summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTakashi Kokubun <takashikkbn@gmail.com>2024-02-08 07:22:07 -0800
committerGitHub <noreply@github.com>2024-02-08 10:22:07 -0500
commitb74c8abd1132824f95d81309f96645f272c064dc (patch)
tree568718a6e580b4538c65574cbb1f123291e8b12a
parent01fd262e62076277a41af72ea13f20deb1b462a2 (diff)
YJIT: Skip pushing a frame for Hash#empty? (#9875)
-rw-r--r--hash.c2
-rw-r--r--yjit/src/codegen.rs23
-rw-r--r--yjit/src/cruby.rs3
3 files changed, 26 insertions, 2 deletions
diff --git a/hash.c b/hash.c
index 91f1e73a39..201ada4f6e 100644
--- a/hash.c
+++ b/hash.c
@@ -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));
diff --git a/yjit/src/codegen.rs b/yjit/src/codegen.rs
index 4eaeebd503..b7df2b44f8 100644
--- a/yjit/src/codegen.rs
+++ b/yjit/src/codegen.rs
@@ -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);
diff --git a/yjit/src/cruby.rs b/yjit/src/cruby.rs
index 0f3519b820..78cb2d65ea 100644
--- a/yjit/src/cruby.rs
+++ b/yjit/src/cruby.rs
@@ -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;