YJIT: Skip pushing a frame for Hash#empty? (#9875)

This commit is contained in:
Takashi Kokubun 2024-02-08 07:22:07 -08:00 committed by GitHub
parent 01fd262e62
commit b74c8abd11
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 26 additions and 2 deletions

2
hash.c
View File

@ -3015,7 +3015,7 @@ rb_hash_size_num(VALUE hash)
* {foo: 0, bar: 1, baz: 2}.empty? # => false
*/
static VALUE
VALUE
rb_hash_empty_p(VALUE hash)
{
return RBOOL(RHASH_EMPTY_P(hash));

View File

@ -5499,6 +5499,27 @@ fn jit_rb_ary_push(
true
}
// Just a leaf method, but not using `Primitive.attr! :leaf` since BOP methods can't use it.
fn jit_rb_hash_empty_p(
_jit: &mut JITState,
asm: &mut Assembler,
_ocb: &mut OutlinedCb,
_ci: *const rb_callinfo,
_cme: *const rb_callable_method_entry_t,
_block: Option<BlockHandler>,
_argc: i32,
_known_recv_class: *const VALUE,
) -> bool {
asm_comment!(asm, "Hash#empty?");
let hash_opnd = asm.stack_pop(1);
let ret = asm.ccall(rb_hash_empty_p as *const u8, vec![hash_opnd]);
let ret_opnd = asm.stack_push(Type::UnknownImm);
asm.mov(ret_opnd, ret);
true
}
fn jit_obj_respond_to(
jit: &mut JITState,
asm: &mut Assembler,
@ -9360,6 +9381,8 @@ pub fn yjit_reg_method_codegen_fns() {
yjit_reg_method(rb_cArray, "size", jit_rb_ary_length);
yjit_reg_method(rb_cArray, "<<", jit_rb_ary_push);
yjit_reg_method(rb_cHash, "empty?", jit_rb_hash_empty_p);
yjit_reg_method(rb_mKernel, "respond_to?", jit_obj_respond_to);
yjit_reg_method(rb_mKernel, "block_given?", jit_rb_f_block_given_p);

View File

@ -107,11 +107,12 @@ pub use autogened::*;
// TODO: For #defines that affect memory layout, we need to check for them
// on build and fail if they're wrong. e.g. USE_FLONUM *must* be true.
// These are functions we expose from vm_insnhelper.c, not in any header.
// These are functions we expose from C files, not in any header.
// Parsing it would result in a lot of duplicate definitions.
// Use bindgen for functions that are defined in headers or in yjit.c.
#[cfg_attr(test, allow(unused))] // We don't link against C code when testing
extern "C" {
pub fn rb_hash_empty_p(hash: VALUE) -> VALUE;
pub fn rb_vm_splat_array(flag: VALUE, ary: VALUE) -> VALUE;
pub fn rb_vm_concat_array(ary1: VALUE, ary2st: VALUE) -> VALUE;
pub fn rb_vm_concat_to_array(ary1: VALUE, ary2st: VALUE) -> VALUE;