diff options
author | John Hawthorn <john@hawthorn.email> | 2023-08-25 18:52:02 -0700 |
---|---|---|
committer | Alan Wu <XrXr@users.noreply.github.com> | 2023-08-31 10:46:24 -0400 |
commit | 43825fba6eb39980130fd9bf47acb2000cde55d3 (patch) | |
tree | de6ca9d35b3c3eaf244f2654bf0f7a24f4d7d938 /yjit | |
parent | 0270210e4984957427a4cf3824b724b62bfa2eaf (diff) |
YJIT: Handle getblockparamproxy with ifunc
getblockparamproxy for "ifunc" behaves identically to iseq, in just
pushing rb_block_param_proxy.
Notes
Notes:
Merged: https://github.com/ruby/ruby/pull/8300
Diffstat (limited to 'yjit')
-rw-r--r-- | yjit/src/codegen.rs | 24 |
1 files changed, 14 insertions, 10 deletions
diff --git a/yjit/src/codegen.rs b/yjit/src/codegen.rs index c506b4360c..b51704b2c6 100644 --- a/yjit/src/codegen.rs +++ b/yjit/src/codegen.rs @@ -8151,9 +8151,10 @@ fn gen_getblockparamproxy( // Peek at the block handler so we can check whether it's nil let comptime_handler = jit.peek_at_block_handler(level); - // Filter for the 3 cases we currently handle + // Filter for the 4 cases we currently handle if !(comptime_handler.as_u64() == 0 || // no block given comptime_handler.as_u64() & 0x3 == 0x1 || // iseq block (no associated GC managed object) + comptime_handler.as_u64() & 0x3 == 0x3 || // ifunc block (no associated GC managed object) unsafe { rb_obj_is_proc(comptime_handler) }.test() // block is a Proc ) { // Missing the symbol case, where we basically need to call Symbol#to_proc at runtime @@ -8181,7 +8182,7 @@ fn gen_getblockparamproxy( // Use block handler sample to guide specialization... // NOTE: we use jit_chain_guard() in this decision tree, and since - // there are only 3 cases, it should never reach the depth limit use + // there are only a few cases, it should never reach the depth limit use // the exit counter we pass to it. // // No block given @@ -8199,15 +8200,18 @@ fn gen_getblockparamproxy( ); jit_putobject(asm, Qnil); - } else if comptime_handler.as_u64() & 0x3 == 0x1 { - // Block handler is a tagged pointer. Look at the tag. 0x03 is from VM_BH_ISEQ_BLOCK_P(). - let block_handler = asm.and(block_handler, 0x3.into()); - - // Bail unless VM_BH_ISEQ_BLOCK_P(bh). This also checks for null. - asm.cmp(block_handler, 0x1.into()); - + } else if comptime_handler.as_u64() & 0x1 == 0x1 { + // This handles two cases which are nearly identical + // Block handler is a tagged pointer. Look at the tag. + // VM_BH_ISEQ_BLOCK_P(): block_handler & 0x03 == 0x01 + // VM_BH_IFUNC_P(): block_handler & 0x03 == 0x03 + // So to check for either of those cases we can use: val & 0x1 == 0x1 + const _: () = assert!(RUBY_SYMBOL_FLAG & 1 == 0, "guard below rejects symbol block handlers"); + // Procs are aligned heap pointers so testing the bit rejects them too. + + asm.test(block_handler, 0x1.into()); jit_chain_guard( - JCC_JNZ, + JCC_JZ, jit, asm, ocb, |