From bb593378603ef43479a78cbafecd79261b041bf0 Mon Sep 17 00:00:00 2001 From: Jean Boussier Date: Wed, 29 Jul 2026 09:48:05 +0200 Subject: [PATCH 01/17] [ruby/json] Improve max_nesting documentation https://github.com/ruby/json/commit/5499aa54a4 --- ext/json/lib/json.rb | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/ext/json/lib/json.rb b/ext/json/lib/json.rb index d1e94147dc1788..74e258424986a5 100644 --- a/ext/json/lib/json.rb +++ b/ext/json/lib/json.rb @@ -121,9 +121,11 @@ # ====== Input Options # # Option +max_nesting+ (\Integer) specifies the maximum nesting depth allowed; -# defaults to +100+; specify +false+ to disable depth checking. +# defaults to +100+; +# You can set it to +false+ to disable depth checking entirely, but that is dangerous +# when parsing untrusted input. # -# With the default, +false+: +# With the default, +100+: # source = '[0, [1, [2, [3]]]]' # ruby = JSON.parse(source) # ruby # => [0, [1, [2, [3]]]] @@ -384,6 +386,15 @@ # # Raises JSON::NestingError (nesting of 2 is too deep): # JSON.generate(obj, max_nesting: 2) # +# With +false+: +# obj = [] +# obj[0] = obj +# # Raises SystemStackError: stack level too deep +# JSON.generate(obj, max_nesting: false) +# +# Setting +max_nesting+ to +false+ can lead to a stackoverflow and may leave the program +# in an unrecoverable state. It is discouraged. +# # ====== Escaping Options # # Options +script_safe+ (boolean) specifies wether '\u2028', '\u2029' From 6c2b11747a00d180e49c75e3b1802d728a667e3b Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Wed, 29 Jul 2026 19:52:19 +0900 Subject: [PATCH 02/17] Clarify strict-prototypes workaround [ci skip] Document the affected Clang and Autoconf versions. --- .github/workflows/compilers.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/compilers.yml b/.github/workflows/compilers.yml index 51f16b09be730a..99b8f08c29fdc5 100644 --- a/.github/workflows/compilers.yml +++ b/.github/workflows/compilers.yml @@ -150,11 +150,11 @@ jobs: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: { sparse-checkout-cone-mode: false, sparse-checkout: /.github, persist-credentials: false } - { uses: './.github/actions/setup/directories', with: { srcdir: 'src', builddir: 'build', makeup: true, fetch-depth: 10 } } - # -Wno-strict-prototypes is necessary with current clang-15 since - # older autoconf generate functions without prototype and -pedantic - # now implies strict-prototypes. Disabling the error but leaving the - # warning generates a lot of noise from use of ANYARGS in - # rb_define_method() and friends. + # -Wno-strict-prototypes is necessary with clang-15 or newer, since + # older autoconf prior to 2.72 generate functions without prototype + # and -pedantic now implies strict-prototypes. Disabling the error + # but leaving the warning generates a lot of noise from use of + # ANYARGS in rb_define_method() and friends. # See: https://github.com/llvm/llvm-project/commit/11da1b53d8cd3507959022cd790d5a7ad4573d94 - { uses: './.github/actions/compilers', name: 'C99', with: { CFLAGS: '-std=c99 -Werror=pedantic -pedantic-errors -Wno-strict-prototypes' }, timeout-minutes: 8 } - { uses: './.github/actions/compilers', name: 'C11', with: { CFLAGS: '-std=c11 -Werror=pedantic -pedantic-errors -Wno-strict-prototypes' }, timeout-minutes: 8 } From a32dded07da3193c90623c63aa157c87d2b2147a Mon Sep 17 00:00:00 2001 From: Max Bernstein Date: Wed, 29 Jul 2026 10:09:51 -0400 Subject: [PATCH 03/17] ZJIT: Iterate over state in SetLocal (#18102) We added state to `SetLocal` but didn't change `for_each_operand_impl`. --- zjit/src/hir.rs | 2 +- zjit/src/hir/opt_tests.rs | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/zjit/src/hir.rs b/zjit/src/hir.rs index 6d3fa90f10599e..2b5077afcf1e03 100644 --- a/zjit/src/hir.rs +++ b/zjit/src/hir.rs @@ -1350,7 +1350,6 @@ macro_rules! for_each_operand_impl { | Insn::HasType { val, .. } | Insn::Return { val } | Insn::Test { val } - | Insn::SetLocal { val, .. } | Insn::BoxBool { val } => { $visit_one!(*val); } @@ -1366,6 +1365,7 @@ macro_rules! for_each_operand_impl { | Insn::ToArray { val, state } | Insn::IsMethodCfunc { val, state, .. } | Insn::ToNewArray { val, state } + | Insn::SetLocal { val, state, .. } | Insn::BoxFixnum { val, state } => { $visit_one!(*val); $visit_one!(*state); diff --git a/zjit/src/hir/opt_tests.rs b/zjit/src/hir/opt_tests.rs index 4d50dc51772d97..67d6e03c11a29d 100644 --- a/zjit/src/hir/opt_tests.rs +++ b/zjit/src/hir/opt_tests.rs @@ -16652,6 +16652,7 @@ mod hir_opt_tests { v43:BasicObject = CCallWithFrame v42, :Kernel#proc@0x1040, block=0x1048 v22:CPtr = GetEP 0 v23:BasicObject = LoadField v22, :blk@0x1001 + v24:BasicObject = LoadField v22, :other_block@0x1002 SetLocal :other_block, l0, EP@3, v43 v30:CPtr = GetEP 0 v31:BasicObject = LoadField v30, :other_block@0x1002 @@ -17295,6 +17296,7 @@ mod hir_opt_tests { v132:BasicObject = CCallWithFrame v131, :Kernel#lambda@0x1048, block=0x1050 v89:CPtr = GetEP 0 v90:BasicObject = LoadField v89, :list@0x1001 + v91:BasicObject = LoadField v89, :sep@0x1002 v92:BasicObject = LoadField v89, :iter_method@0x1005 v93:BasicObject = LoadField v89, :kwsplat@0x1006 SetLocal :sep, l0, EP@5, v132 From 72cf6fff923841cef0e760984e801ff17a4def7c Mon Sep 17 00:00:00 2001 From: Max Bernstein Date: Wed, 29 Jul 2026 10:42:03 -0400 Subject: [PATCH 04/17] ZJIT: Make UnboxFixnum effectless (#18103) It's just an integer right shift. --- zjit/src/hir.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zjit/src/hir.rs b/zjit/src/hir.rs index 2b5077afcf1e03..a793c7f41c4dbf 100644 --- a/zjit/src/hir.rs +++ b/zjit/src/hir.rs @@ -1694,7 +1694,7 @@ impl Insn { Insn::IsBitNotEqual { .. } => effects::Empty, Insn::BoxBool { .. } => effects::Empty, Insn::BoxFixnum { .. } => effects::Empty, - Insn::UnboxFixnum { .. } => effects::Any, + Insn::UnboxFixnum { .. } => effects::Empty, Insn::FixnumAref { .. } => effects::Empty, Insn::Defined { .. } => effects::Any, Insn::GetConstant { .. } => effects::Any, From d6e2feea477ae386ca3cef8f4dec455b4b535835 Mon Sep 17 00:00:00 2001 From: himura467 Date: Wed, 29 Jul 2026 05:49:33 +0900 Subject: [PATCH 05/17] Return a byte count from ractor_sync_memsize() st_table_size() is the number of entries, but ractor_memsize() adds the result to sizeof(rb_ractor_t) as a byte count, so a Ractor was reported as costing one byte per open port. Use st_memsize(), as ractor_selector_memsize() in this file already does for its own ports table. --- ractor_sync.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ractor_sync.c b/ractor_sync.c index 6ac0c11f632bce..b48aad9f756bd0 100644 --- a/ractor_sync.c +++ b/ractor_sync.c @@ -716,7 +716,7 @@ static size_t ractor_sync_memsize(const rb_ractor_t *r) { if (r->sync.ports) { - return st_table_size(r->sync.ports); + return st_memsize(r->sync.ports); } else { return 0; From 3ca77abb61c13d10350167e0f3a1919f91ce105d Mon Sep 17 00:00:00 2001 From: Peter Zhu Date: Wed, 29 Jul 2026 10:24:07 -0400 Subject: [PATCH 06/17] Drop MMTK_HEAP_MAX in test_oom Sync ruby/mmtk@11ea3a437f788fb085a61d1c7d931a9527dc13ba. --- test/mmtk/test_oom.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/mmtk/test_oom.rb b/test/mmtk/test_oom.rb index d51471eb54b83e..bd466881419688 100644 --- a/test/mmtk/test_oom.rb +++ b/test/mmtk/test_oom.rb @@ -5,7 +5,7 @@ module MMTk class TestOOM < TestCase def test_oom - assert_in_out_err([{ "MMTK_HEAP_MAX" => "64MiB" }], <<~RUBY, [], /failed to allocate memory/) + assert_in_out_err([{ "MMTK_HEAP_MAX" => "4MiB" }], <<~RUBY, [], /failed to allocate memory/) 10_000_000.times.map do Object.new end From a2cc692d7707c1bbddac1e6f35d4e6e6e47f5694 Mon Sep 17 00:00:00 2001 From: Koichi Sasada Date: Wed, 29 Jul 2026 15:23:07 +0000 Subject: [PATCH 07/17] Make Proc#refined's memoized iseq copy and memo shareable Proc#refined memoizes {copied_iseq, cref} per source iseq in a process-global map so the copy can be reused from any Ractor. The cref's refinements table is already frozen and marked shareable for that reason, but the copied iseq and the memo array holding it are left unshareable, so the shared payload is not actually a shareable object graph. Complete that intent: mark the copied iseq subtree shareable (it is self-contained -- nested block iseqs are copied too) and mark the frozen memo array shareable. A copy's local_iseq/parent_iseq point at already-shareable iseqs (other copies in the subtree, or the shareable enclosing iseq), so the shareable check needs no special casing. --- compile.c | 4 ++++ proc.c | 3 +++ 2 files changed, 7 insertions(+) diff --git a/compile.c b/compile.c index 09a3ff946a4733..0d4d6ee2002bdc 100644 --- a/compile.c +++ b/compile.c @@ -15227,6 +15227,10 @@ rb_iseq_dup_with_independent_caches(const rb_iseq_t *src_root) RB_OBJ_WRITE(copy, &cb->parent_iseq, sb->parent_iseq); result = copy; } + + /* Shared across Ractors through the Proc#refined memo; the duplicated + * subtree is self-contained, so mark each copy shareable. */ + RB_OBJ_SET_SHAREABLE((VALUE)copy); } if (ISEQ_PC2BRANCHINDEX(src_root) != Qnil) { diff --git a/proc.c b/proc.c index 1fc78e4799ac84..f57196fff157f9 100644 --- a/proc.c +++ b/proc.c @@ -436,6 +436,9 @@ refinement_memo_store(const rb_iseq_t *src_iseq, const rb_cref_t *base_cref, rb_ary_push(memo, mods[i]); } OBJ_FREEZE(memo); + /* Every element is shareable, so mark the memo array shareable too for + * reuse from any Ractor. */ + RB_OBJ_SET_SHAREABLE(memo); /* create the map outside the lock; losing the race just discards it */ VALUE new_map = 0; From 5845220c376b383c106b1b6cae93d660a78406b8 Mon Sep 17 00:00:00 2001 From: Peter Zhu Date: Wed, 29 Jul 2026 10:22:31 -0400 Subject: [PATCH 08/17] Fix directory mappings for MMTk in sync_default_gems.rb --- tool/sync_default_gems.rb | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tool/sync_default_gems.rb b/tool/sync_default_gems.rb index d9c23cf127ec7f..f07d1b3840e5da 100755 --- a/tool/sync_default_gems.rb +++ b/tool/sync_default_gems.rb @@ -177,8 +177,9 @@ def lib((upstream, branch), gemspec_in_subdir: false) "ext/json/extconf.rb", ]), mmtk: repo(["ruby/mmtk", "main"], [ - ["gc/mmtk", "gc/mmtk", - "test/.excludes-mmtk", "test/mmtk"], + ["gc/mmtk", "gc/mmtk"], + ["test/.excludes-mmtk", "test/.excludes-mmtk"], + ["test/mmtk", "test/mmtk"], ]), open3: lib("ruby/open3", gemspec_in_subdir: true).tap { it.exclude << "lib/open3/jruby_windows.rb" From 4a6e60e641968171e21a3b05fc3b948408c068d5 Mon Sep 17 00:00:00 2001 From: Max Bernstein Date: Tue, 28 Jul 2026 11:06:33 -0400 Subject: [PATCH 09/17] ZJIT: Rewrite LIR successors function to avoid cloning edges We only need the target blocks, not the argument vectors. --- zjit/src/backend/lir.rs | 48 +++++++++++++++++++++++++---------------- 1 file changed, 29 insertions(+), 19 deletions(-) diff --git a/zjit/src/backend/lir.rs b/zjit/src/backend/lir.rs index 3012d602b1e55c..522931f6feaab2 100644 --- a/zjit/src/backend/lir.rs +++ b/zjit/src/backend/lir.rs @@ -188,23 +188,37 @@ impl BasicBlock { } } + pub fn successors(&self) -> impl DoubleEndedIterator + '_ { + // Stub blocks (from new_block_without_id) have no real CFG structure. + if self.rpo_index == DUMMY_RPO_INDEX { + return None.into_iter().chain(None.into_iter()); + } + assert!(self.insns.last().unwrap().is_terminator()); + let extract_target = |insn: &Insn| -> Option { + if let Some(Target::Block(edge)) = insn.target() { + Some(edge.target) + } else { + None + } + }; + + let (succ1, succ2) = match self.insns.as_slice() { + [] => panic!("empty block"), + [.., second_last, last] => { + (extract_target(second_last), extract_target(last)) + }, + [.., last] => { + (extract_target(last), None) + } + }; + succ1.into_iter().chain(succ2.into_iter()) + } + /// Sort key for scheduling blocks in code layout order pub fn sort_key(&self) -> (usize, usize) { (self.rpo_index, self.id.0) } - pub fn successors(&self) -> Vec { - let EdgePair(edge1, edge2) = self.edges(); - let mut succs = Vec::new(); - if let Some(edge) = edge1 { - succs.push(edge.target); - } - if let Some(edge) = edge2 { - succs.push(edge.target); - } - succs - } - /// Get the output VRegs for this block. /// These are VRegs referenced by operands passed to successor blocks via block edges. /// This function is used for live range calculations and should _not_ @@ -3067,14 +3081,10 @@ impl Assembler } if !seen.insert(block) { continue; } stack.push((block, Action::VisitSelf)); - let EdgePair(edge1, edge2) = self.basic_blocks[block.0].edges(); - // Push edge2 before edge1 so that edge1 is popped first from the + // Push block2 before block1 so that block1 is popped first from the // LIFO stack, matching the visit order of a recursive DFS. - if let Some(edge) = edge2 { - stack.push((edge.target, Action::VisitEdges)); - } - if let Some(edge) = edge1 { - stack.push((edge.target, Action::VisitEdges)); + for block in self.basic_blocks[block.0].successors().rev() { + stack.push((block, Action::VisitEdges)); } } result From 9f6753e683ad7a4874e8d442a09fd2d21d79fdd9 Mon Sep 17 00:00:00 2001 From: Max Bernstein Date: Tue, 28 Jul 2026 17:22:28 -0400 Subject: [PATCH 10/17] ZJIT: Use BitSet, not HashSet, for LIR block sets No need for hashing in LIR RPO. --- zjit/src/backend/lir.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/zjit/src/backend/lir.rs b/zjit/src/backend/lir.rs index 522931f6feaab2..2f3622b0838db7 100644 --- a/zjit/src/backend/lir.rs +++ b/zjit/src/backend/lir.rs @@ -21,6 +21,8 @@ use crate::cast::IntoUsize; #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug, PartialOrd, Ord)] pub struct BlockId(pub usize); +type BlockSet = BitSet; + /// Underlying integer width of a virtual-register id. Narrow to keep `Opnd`/`Mem` small. pub type VRegIdBase = u32; /// Width of a stack-slot index inside `MemBase`. Separate id space from `VRegId`. @@ -3072,7 +3074,7 @@ impl Assembler VisitSelf, } let mut result = vec![]; - let mut seen = HashSet::with_capacity(self.basic_blocks.len()); + let mut seen = BlockSet::with_capacity(self.basic_blocks.len()); let mut stack: Vec<_> = starts.iter().map(|&start| (start, Action::VisitEdges)).collect(); while let Some((block, action)) = stack.pop() { if action == Action::VisitSelf { From 821af045b62ffb123ec0d35fa604bf8d39b51e71 Mon Sep 17 00:00:00 2001 From: Takashi Kokubun Date: Tue, 28 Jul 2026 14:02:39 -0700 Subject: [PATCH 11/17] ZJIT: Map pointer values instead of temporary addresses in HIR dump --- zjit/src/hir.rs | 17 +-- zjit/src/hir/opt_tests.rs | 290 +++++++++++++++++++------------------- zjit/src/hir/tests.rs | 10 +- 3 files changed, 159 insertions(+), 158 deletions(-) diff --git a/zjit/src/hir.rs b/zjit/src/hir.rs index a793c7f41c4dbf..980b0147c6a12a 100644 --- a/zjit/src/hir.rs +++ b/zjit/src/hir.rs @@ -2086,8 +2086,9 @@ impl<'a> std::fmt::Display for InsnPrinter<'a> { Insn::SendDirect(insn) => { let SendDirectData { recv, cme, iseq, args, block, jit_entry_idx, .. } = &**insn; let blockiseq = block.map(|bh| match bh { BlockHandler::BlockIseq(iseq) => iseq, BlockHandler::BlockArg => unreachable!() }); + let blockiseq_ptr = blockiseq.map_or(ptr::null(), |iseq| self.ptr_map.map_ptr(iseq)); let method_name = unsafe { (**cme).called_id }; - write!(f, "SendDirect {recv}, {:p}, :{} ({:?})", self.ptr_map.map_ptr(&blockiseq), method_name, self.ptr_map.map_ptr(iseq))?; + write!(f, "SendDirect {recv}, {blockiseq_ptr:p}, :{method_name} ({:?})", self.ptr_map.map_ptr(*iseq))?; if *jit_entry_idx != 0 { write!(f, ", jit_entry_idx={jit_entry_idx}")?; } @@ -2095,7 +2096,7 @@ impl<'a> std::fmt::Display for InsnPrinter<'a> { Ok(()) } Insn::PushInlineFrame { recv, iseq, args, .. } => { - write!(f, "PushInlineFrame {recv} ({:?})", self.ptr_map.map_ptr(iseq))?; + write!(f, "PushInlineFrame {recv} ({:?})", self.ptr_map.map_ptr(*iseq))?; write_separated!(f, ", ", ", ", args); Ok(()) } @@ -2119,19 +2120,19 @@ impl<'a> std::fmt::Display for InsnPrinter<'a> { Ok(()) } Insn::SendForward { recv, cd, args, blockiseq, reason, .. } => { - write!(f, "SendForward {recv}, {:p}, :{}", self.ptr_map.map_ptr(blockiseq), ruby_call_method_name(*cd))?; + write!(f, "SendForward {recv}, {:p}, :{}", self.ptr_map.map_ptr(*blockiseq), ruby_call_method_name(*cd))?; write_separated!(f, ", ", ", ", args); write!(f, " # SendFallbackReason: {reason}")?; Ok(()) } Insn::InvokeSuper { recv, blockiseq, args, reason, .. } => { - write!(f, "InvokeSuper {recv}, {:p}", self.ptr_map.map_ptr(blockiseq))?; + write!(f, "InvokeSuper {recv}, {:p}", self.ptr_map.map_ptr(*blockiseq))?; write_separated!(f, ", ", ", ", args); write!(f, " # SendFallbackReason: {reason}")?; Ok(()) } Insn::InvokeSuperForward { recv, blockiseq, args, reason, .. } => { - write!(f, "InvokeSuperForward {recv}, {:p}", self.ptr_map.map_ptr(blockiseq))?; + write!(f, "InvokeSuperForward {recv}, {:p}", self.ptr_map.map_ptr(*blockiseq))?; write_separated!(f, ", ", ", ", args); write!(f, " # SendFallbackReason: {reason}")?; Ok(()) @@ -2156,7 +2157,7 @@ impl<'a> std::fmt::Display for InsnPrinter<'a> { Ok(()) } Insn::InvokeBlockIseqDirect { iseq, captured, args, .. } => { - write!(f, "InvokeBlockIseqDirect ({:?}), {captured}", self.ptr_map.map_ptr(iseq))?; + write!(f, "InvokeBlockIseqDirect ({:?}), {captured}", self.ptr_map.map_ptr(*iseq))?; write_separated!(f, ", ", ", ", args); Ok(()) } @@ -2234,7 +2235,7 @@ impl<'a> std::fmt::Display for InsnPrinter<'a> { Insn::GetConstant { klass, id, allow_nil, .. } => { write!(f, "GetConstant {klass}, :{}, {allow_nil}", id.contents_lossy()) } - Insn::GetConstantPath { ic, .. } => { write!(f, "GetConstantPath {:p}", self.ptr_map.map_ptr(ic)) }, + Insn::GetConstantPath { ic, .. } => { write!(f, "GetConstantPath {:p}", self.ptr_map.map_ptr(*ic)) }, Insn::IsBlockGiven { block_handler } => { write!(f, "IsBlockGiven {block_handler}") }, Insn::FixnumBitCheck {val, index} => { write!(f, "FixnumBitCheck {val}, {index}") }, Insn::CCall { cfunc, recv, args, name, owner, return_type: _, elidable: _ } => { @@ -2249,7 +2250,7 @@ impl<'a> std::fmt::Display for InsnPrinter<'a> { write_separated!(f, ", ", ", ", args); match block { Some(BlockHandler::BlockIseq(blockiseq)) => - write!(f, ", block={:p}", self.ptr_map.map_ptr(blockiseq))?, + write!(f, ", block={:p}", self.ptr_map.map_ptr(*blockiseq))?, Some(BlockHandler::BlockArg) => write!(f, ", block=&block")?, None => {} diff --git a/zjit/src/hir/opt_tests.rs b/zjit/src/hir/opt_tests.rs index 67d6e03c11a29d..503b7d7e46d55c 100644 --- a/zjit/src/hir/opt_tests.rs +++ b/zjit/src/hir/opt_tests.rs @@ -1572,7 +1572,7 @@ mod hir_opt_tests { PatchPoint NoSingletonClass(C@0x1008) PatchPoint MethodRedefined(C@0x1008, fun_new_map@0x1010, cme:0x1018) v25:ArraySubclass[class_exact:C] = GuardType v10, ArraySubclass[class_exact:C] recompile - v26:BasicObject = SendDirect v25, 0x1040, :fun_new_map (0x1050) + v26:BasicObject = SendDirect v25, 0x1040, :fun_new_map (0x1068) PatchPoint NoEPEscape(test) CheckInterrupts Return v26 @@ -1762,7 +1762,7 @@ mod hir_opt_tests { PushInlineFrame v18 (0x1038) v26:Fixnum[1] = Const Value(1) v34:Fixnum[2] = Const Value(2) - PatchPoint MethodRedefined(Integer@0x1040, +@0x1048, cme:0x1050) + PatchPoint MethodRedefined(Integer@0x1060, +@0x1068, cme:0x1070) v61:Fixnum[3] = Const Value(3) CheckInterrupts PopInlineFrame @@ -1793,7 +1793,7 @@ mod hir_opt_tests { v20:ObjectSubclass[class_exact*:Object@VALUE(0x1000)] = GuardType v6, ObjectSubclass[class_exact*:Object@VALUE(0x1000)] recompile PushInlineFrame v20 (0x1038), v11 v28:Fixnum[2] = Const Value(2) - PatchPoint MethodRedefined(Integer@0x1040, +@0x1048, cme:0x1050) + PatchPoint MethodRedefined(Integer@0x1060, +@0x1068, cme:0x1070) v54:Fixnum[5] = Const Value(5) CheckInterrupts PopInlineFrame @@ -1824,7 +1824,7 @@ mod hir_opt_tests { PatchPoint MethodRedefined(Object@0x1000, foo@0x1008, cme:0x1010) v22:ObjectSubclass[class_exact*:Object@VALUE(0x1000)] = GuardType v6, ObjectSubclass[class_exact*:Object@VALUE(0x1000)] recompile PushInlineFrame v22 (0x1038), v11, v13 - PatchPoint MethodRedefined(Integer@0x1040, +@0x1048, cme:0x1050) + PatchPoint MethodRedefined(Integer@0x1060, +@0x1068, cme:0x1070) v47:Fixnum[7] = Const Value(7) CheckInterrupts PopInlineFrame @@ -3850,16 +3850,16 @@ mod hir_opt_tests { v52:NilClass = Const Value(nil) PushInlineFrame v22 (0x1038), v11, v13 v34:CPtr = GetEP 0 - v35:CUInt64 = LoadField v34, :VM_ENV_DATA_INDEX_FLAGS@0x1040 + v35:CUInt64 = LoadField v34, :VM_ENV_DATA_INDEX_FLAGS@0x1060 v36:CBool = IsBlockParamModified v35 CondBranch v36, bb6(), bb7() bb6(): - v38:BasicObject = LoadField v34, :block@0x1041 + v38:BasicObject = LoadField v34, :block@0x1061 Jump bb8(v38, v38) bb7(): - v40:CInt64 = LoadField v34, :VM_ENV_DATA_INDEX_SPECVAL@0x1042 + v40:CInt64 = LoadField v34, :VM_ENV_DATA_INDEX_SPECVAL@0x1062 v41:CInt64 = GuardAnyBitSet v40, CUInt64(1) recompile - v42:ObjectSubclass[BlockParamProxy] = Const Value(VALUE(0x1048)) + v42:ObjectSubclass[BlockParamProxy] = Const Value(VALUE(0x1068)) Jump bb8(v42, v52) bb8(v32:BasicObject, v33:BasicObject): v47:BasicObject = Send v32, :call, v11, v13 # SendFallbackReason: Send: unsupported optimized method type BlockCall @@ -3897,10 +3897,10 @@ mod hir_opt_tests { v18:ObjectSubclass[class_exact*:Object@VALUE(0x1000)] = GuardType v6, ObjectSubclass[class_exact*:Object@VALUE(0x1000)] recompile PushInlineFrame v18 (0x1038) v25:CPtr = GetEP 0 - v26:CInt64 = LoadField v25, :VM_ENV_DATA_INDEX_SPECVAL@0x1040 + v26:CInt64 = LoadField v25, :VM_ENV_DATA_INDEX_SPECVAL@0x1060 v27:CInt64[-4] = Const CInt64(-4) v28:CInt64 = IntAnd v26, v27 - v29:BasicObject = InvokeBlockIseqDirect (0x1048), v28 + v29:BasicObject = InvokeBlockIseqDirect (0x1068), v28 CheckInterrupts PopInlineFrame Return v29 @@ -3936,11 +3936,11 @@ mod hir_opt_tests { v29:Fixnum[1] = Const Value(1) v31:Fixnum[2] = Const Value(2) v33:CPtr = GetEP 0 - v34:CInt64 = LoadField v33, :VM_ENV_DATA_INDEX_SPECVAL@0x1040 + v34:CInt64 = LoadField v33, :VM_ENV_DATA_INDEX_SPECVAL@0x1060 v35:CInt64[-4] = Const CInt64(-4) v36:CInt64 = IntAnd v34, v35 - v37:BasicObject = InvokeBlockIseqDirect (0x1048), v36, v29, v31 - PatchPoint MethodRedefined(Integer@0x1050, +@0x1058, cme:0x1060) + v37:BasicObject = InvokeBlockIseqDirect (0x1068), v36, v29, v31 + PatchPoint MethodRedefined(Integer@0x1090, +@0x1098, cme:0x10a0) v52:Fixnum = GuardType v37, Fixnum v53:Fixnum = FixnumAdd v11, v52 CheckInterrupts @@ -4053,7 +4053,7 @@ mod hir_opt_tests { v44:BasicObject = CCallWithFrame v43, :Kernel#lambda@0x1040, block=0x1048 v22:CPtr = GetEP 0 v23:BasicObject = LoadField v22, :a@0x1000 - PatchPoint MethodRedefined(Object@0x1008, foo@0x1050, cme:0x1058) + PatchPoint MethodRedefined(Object@0x1008, foo@0x1070, cme:0x1078) v34:CPtr = GetEP 0 v35:BasicObject = LoadField v34, :a@0x1000 CheckInterrupts @@ -4087,8 +4087,8 @@ mod hir_opt_tests { PatchPoint MethodRedefined(Object@0x1000, foo@0x1008, cme:0x1010) v26:ObjectSubclass[class_exact*:Object@VALUE(0x1000)] = GuardType v6, ObjectSubclass[class_exact*:Object@VALUE(0x1000)] recompile PushInlineFrame v26 (0x1038), v23 - PatchPoint NoSingletonClass(Array@0x1040) - PatchPoint MethodRedefined(Array@0x1040, length@0x1048, cme:0x1050) + PatchPoint NoSingletonClass(Array@0x1060) + PatchPoint MethodRedefined(Array@0x1060, length@0x1068, cme:0x1070) v49:CInt64 = ArrayLength v23 v50:Fixnum = BoxFixnum v49 CheckInterrupts @@ -4127,8 +4127,8 @@ mod hir_opt_tests { PatchPoint MethodRedefined(Object@0x1000, foo@0x1008, cme:0x1010) v34:ObjectSubclass[class_exact*:Object@VALUE(0x1000)] = GuardType v6, ObjectSubclass[class_exact*:Object@VALUE(0x1000)] recompile PushInlineFrame v34 (0x1038), v31 - PatchPoint NoSingletonClass(Array@0x1040) - PatchPoint MethodRedefined(Array@0x1040, length@0x1048, cme:0x1050) + PatchPoint NoSingletonClass(Array@0x1060) + PatchPoint MethodRedefined(Array@0x1060, length@0x1068, cme:0x1070) v57:CInt64 = ArrayLength v31 v58:Fixnum = BoxFixnum v57 CheckInterrupts @@ -4163,15 +4163,15 @@ mod hir_opt_tests { PatchPoint MethodRedefined(Object@0x1000, foo@0x1008, cme:0x1010) v26:ObjectSubclass[class_exact*:Object@VALUE(0x1000)] = GuardType v6, ObjectSubclass[class_exact*:Object@VALUE(0x1000)] recompile PushInlineFrame v26 (0x1038), v23 - PatchPoint NoSingletonClass(Array@0x1040) - PatchPoint MethodRedefined(Array@0x1040, length@0x1048, cme:0x1050) + PatchPoint NoSingletonClass(Array@0x1060) + PatchPoint MethodRedefined(Array@0x1060, length@0x1068, cme:0x1070) v55:CInt64 = ArrayLength v23 v56:Fixnum = BoxFixnum v55 v38:CPtr = GetEP 0 - v39:CInt64 = LoadField v38, :VM_ENV_DATA_INDEX_SPECVAL@0x1078 + v39:CInt64 = LoadField v38, :VM_ENV_DATA_INDEX_SPECVAL@0x1098 v40:CInt64[-4] = Const CInt64(-4) v41:CInt64 = IntAnd v39, v40 - v42:BasicObject = InvokeBlockIseqDirect (0x1080), v41, v56 + v42:BasicObject = InvokeBlockIseqDirect (0x10a0), v41, v56 CheckInterrupts PopInlineFrame Return v42 @@ -4206,20 +4206,20 @@ mod hir_opt_tests { v57:NilClass = Const Value(nil) PushInlineFrame v26 (0x1038), v23 v37:CPtr = GetEP 0 - v38:CUInt64 = LoadField v37, :VM_ENV_DATA_INDEX_FLAGS@0x1040 + v38:CUInt64 = LoadField v37, :VM_ENV_DATA_INDEX_FLAGS@0x1060 v39:CBool = IsBlockParamModified v38 CondBranch v39, bb6(), bb7() bb6(): - v41:BasicObject = LoadField v37, :block@0x1041 + v41:BasicObject = LoadField v37, :block@0x1061 Jump bb8(v41, v41) bb7(): - v43:CInt64 = LoadField v37, :VM_ENV_DATA_INDEX_SPECVAL@0x1042 + v43:CInt64 = LoadField v37, :VM_ENV_DATA_INDEX_SPECVAL@0x1062 v44:CInt64 = GuardAnyBitSet v43, CUInt64(1) recompile - v45:ObjectSubclass[BlockParamProxy] = Const Value(VALUE(0x1048)) + v45:ObjectSubclass[BlockParamProxy] = Const Value(VALUE(0x1068)) Jump bb8(v45, v57) bb8(v35:BasicObject, v36:BasicObject): - PatchPoint NoSingletonClass(Array@0x1050) - PatchPoint MethodRedefined(Array@0x1050, length@0x1058, cme:0x1060) + PatchPoint NoSingletonClass(Array@0x1070) + PatchPoint MethodRedefined(Array@0x1070, length@0x1078, cme:0x1080) v66:CInt64 = ArrayLength v23 v67:Fixnum = BoxFixnum v66 v52:BasicObject = Send v35, :call, v67 # SendFallbackReason: Send: unsupported optimized method type BlockCall @@ -4256,11 +4256,11 @@ mod hir_opt_tests { PatchPoint MethodRedefined(Object@0x1000, foo@0x1008, cme:0x1010) v28:ObjectSubclass[class_exact*:Object@VALUE(0x1000)] = GuardType v6, ObjectSubclass[class_exact*:Object@VALUE(0x1000)] recompile PushInlineFrame v28 (0x1038), v11, v25, v17 - PatchPoint NoSingletonClass(Array@0x1040) - PatchPoint MethodRedefined(Array@0x1040, length@0x1048, cme:0x1050) + PatchPoint NoSingletonClass(Array@0x1060) + PatchPoint MethodRedefined(Array@0x1060, length@0x1068, cme:0x1070) v61:CInt64 = ArrayLength v25 v62:Fixnum = BoxFixnum v61 - PatchPoint MethodRedefined(Integer@0x1078, +@0x1080, cme:0x1088) + PatchPoint MethodRedefined(Integer@0x1098, +@0x10a0, cme:0x10a8) v66:Fixnum = FixnumAdd v62, v11 v70:Fixnum = FixnumAdd v66, v17 CheckInterrupts @@ -4296,11 +4296,11 @@ mod hir_opt_tests { v26:ObjectSubclass[class_exact*:Object@VALUE(0x1000)] = GuardType v6, ObjectSubclass[class_exact*:Object@VALUE(0x1000)] recompile v47:Fixnum[0] = Const Value(0) PushInlineFrame v26 (0x1038), v23, v15 - PatchPoint NoSingletonClass(Array@0x1040) - PatchPoint MethodRedefined(Array@0x1040, length@0x1048, cme:0x1050) + PatchPoint NoSingletonClass(Array@0x1060) + PatchPoint MethodRedefined(Array@0x1060, length@0x1068, cme:0x1070) v56:CInt64 = ArrayLength v23 v57:Fixnum = BoxFixnum v56 - PatchPoint MethodRedefined(Integer@0x1078, +@0x1080, cme:0x1088) + PatchPoint MethodRedefined(Integer@0x1098, +@0x10a0, cme:0x10a8) v61:Fixnum = FixnumAdd v57, v15 CheckInterrupts PopInlineFrame @@ -4335,11 +4335,11 @@ mod hir_opt_tests { v25:ObjectSubclass[class_exact*:Object@VALUE(0x1000)] = GuardType v6, ObjectSubclass[class_exact*:Object@VALUE(0x1000)] recompile v46:Fixnum[0] = Const Value(0) PushInlineFrame v25 (0x1038), v22, v21 - PatchPoint NoSingletonClass(Array@0x1040) - PatchPoint MethodRedefined(Array@0x1040, length@0x1048, cme:0x1050) + PatchPoint NoSingletonClass(Array@0x1060) + PatchPoint MethodRedefined(Array@0x1060, length@0x1068, cme:0x1070) v55:CInt64 = ArrayLength v22 v56:Fixnum = BoxFixnum v55 - PatchPoint MethodRedefined(Integer@0x1078, +@0x1080, cme:0x1088) + PatchPoint MethodRedefined(Integer@0x1098, +@0x10a0, cme:0x10a8) v60:Fixnum = FixnumAdd v56, v21 CheckInterrupts PopInlineFrame @@ -4437,7 +4437,7 @@ mod hir_opt_tests { v22:ObjectSubclass[class_exact*:Object@VALUE(0x1000)] = GuardType v6, ObjectSubclass[class_exact*:Object@VALUE(0x1000)] recompile PushInlineFrame v22 (0x1038), v11, v13 v31:Fixnum[80] = Const Value(80) - PatchPoint MethodRedefined(Integer@0x1040, +@0x1048, cme:0x1050) + PatchPoint MethodRedefined(Integer@0x1060, +@0x1068, cme:0x1070) v67:Fixnum[110] = Const Value(110) CheckInterrupts PopInlineFrame @@ -4683,13 +4683,13 @@ mod hir_opt_tests { v11:Fixnum[6] = Const Value(6) PatchPoint MethodRedefined(Object@0x1000, target@0x1008, cme:0x1010) v48:ObjectSubclass[class_exact*:Object@VALUE(0x1000)] = GuardType v6, ObjectSubclass[class_exact*:Object@VALUE(0x1000)] recompile - v49:BasicObject = SendDirect v48, 0x1038, :target (0x1048), v11 + v49:BasicObject = SendDirect v48, 0x0, :target (0x1038), v11 v16:Fixnum[10] = Const Value(10) v18:Fixnum[20] = Const Value(20) v20:Fixnum[30] = Const Value(30) v22:Fixnum[6] = Const Value(6) PatchPoint MethodRedefined(Object@0x1000, target@0x1008, cme:0x1010) - v52:BasicObject = SendDirect v48, 0x1038, :target (0x1048), jit_entry_idx=3, v16, v18, v20, v22 + v52:BasicObject = SendDirect v48, 0x0, :target (0x1038), jit_entry_idx=3, v16, v18, v20, v22 v27:Fixnum[10] = Const Value(10) v29:Fixnum[20] = Const Value(20) v31:Fixnum[30] = Const Value(30) @@ -4904,7 +4904,7 @@ mod hir_opt_tests { v38:Fixnum[0] = Const Value(0) PushInlineFrame v20 (0x1038), v17 v30:Fixnum[1] = Const Value(1) - PatchPoint MethodRedefined(Integer@0x1040, +@0x1048, cme:0x1050) + PatchPoint MethodRedefined(Integer@0x1060, +@0x1068, cme:0x1070) v47:Fixnum[2] = Const Value(2) CheckInterrupts PopInlineFrame @@ -5205,12 +5205,12 @@ mod hir_opt_tests { PatchPoint NoSingletonClass(C@0x1008) PatchPoint MethodRedefined(C@0x1008, initialize@0x1038, cme:0x1040) PushInlineFrame v47 (0x1068), v17 - v65:CShape = LoadField v47, :shape_id@0x1070 - v66:CShape[0x1071] = GuardBitEquals v65, CShape(0x1071) recompile - StoreField v47, :@x@0x1072, v17 + v65:CShape = LoadField v47, :shape_id@0x1090 + v66:CShape[0x1091] = GuardBitEquals v65, CShape(0x1091) recompile + StoreField v47, :@x@0x1092, v17 WriteBarrier v47, v17 - v69:CShape[0x1073] = Const CShape(0x1073) - StoreField v47, :shape_id@0x1070, v69 + v69:CShape[0x1093] = Const CShape(0x1093) + StoreField v47, :shape_id@0x1090, v69 CheckInterrupts PopInlineFrame Return v47 @@ -5308,11 +5308,11 @@ mod hir_opt_tests { PushInlineFrame v44 (0x1068), v45 v64:TrueClass = Const Value(true) v82:CPtr = GetEP 0 - v83:CUInt64 = LoadField v82, :VM_ENV_DATA_INDEX_FLAGS@0x1070 + v83:CUInt64 = LoadField v82, :VM_ENV_DATA_INDEX_FLAGS@0x1090 v84:CBool = IsBlockParamModified v83 CondBranch v84, bb11(), bb12() bb11(): - v86:BasicObject = LoadField v82, :block@0x1071 + v86:BasicObject = LoadField v82, :block@0x1091 Jump bb13(v86) bb12(): v88:BasicObject = GetBlockParam :block, l0, EP@4 @@ -5737,7 +5737,7 @@ mod hir_opt_tests { PopInlineFrame Return v76 bb4(v44:BasicObject, v45:Falsy, v46:BasicObject): - v50:StaticSymbol[:skip] = Const Value(VALUE(0x1048)) + v50:StaticSymbol[:skip] = Const Value(VALUE(0x1068)) CheckInterrupts Return v50 "); @@ -9965,7 +9965,7 @@ mod hir_opt_tests { v11:ArrayExact = ArrayDup v10 PatchPoint NoSingletonClass(Array@0x1008) PatchPoint MethodRedefined(Array@0x1008, map@0x1010, cme:0x1018) - v22:BasicObject = SendDirect v11, 0x1040, :map (0x1050) + v22:BasicObject = SendDirect v11, 0x1040, :map (0x1068) CheckInterrupts Return v22 "); @@ -10090,7 +10090,7 @@ mod hir_opt_tests { v35:NilClass = GuardBitEquals v16, Value(nil) recompile PatchPoint NoSingletonClass(Array@0x1008) PatchPoint MethodRedefined(Array@0x1008, map@0x1010, cme:0x1018) - v40:BasicObject = SendDirect v14, 0x1040, :map (0x1050) + v40:BasicObject = SendDirect v14, 0x0, :map (0x1040) CheckInterrupts Return v40 "); @@ -10164,10 +10164,10 @@ mod hir_opt_tests { PushInlineFrame v18 (0x1038) v25:Fixnum[1] = Const Value(1) v27:CPtr = GetEP 0 - v28:CInt64 = LoadField v27, :VM_ENV_DATA_INDEX_SPECVAL@0x1040 + v28:CInt64 = LoadField v27, :VM_ENV_DATA_INDEX_SPECVAL@0x1060 v29:CInt64[-4] = Const CInt64(-4) v30:CInt64 = IntAnd v28, v29 - v31:BasicObject = InvokeBlockIseqDirect (0x1048), v30, v25 + v31:BasicObject = InvokeBlockIseqDirect (0x1068), v30, v25 CheckInterrupts PopInlineFrame Return v31 @@ -10202,14 +10202,14 @@ mod hir_opt_tests { v71:NilClass = Const Value(nil) PushInlineFrame v18 (0x1038) v28:CPtr = GetEP 0 - v29:CUInt64 = LoadField v28, :VM_ENV_DATA_INDEX_FLAGS@0x1040 + v29:CUInt64 = LoadField v28, :VM_ENV_DATA_INDEX_FLAGS@0x1060 v30:CBool = IsBlockParamModified v29 CondBranch v30, bb7(), bb8() bb7(): - v32:BasicObject = LoadField v28, :blk@0x1041 + v32:BasicObject = LoadField v28, :blk@0x1061 Jump bb9(v32, v32) bb8(): - v34:CInt64 = LoadField v28, :VM_ENV_DATA_INDEX_SPECVAL@0x1042 + v34:CInt64 = LoadField v28, :VM_ENV_DATA_INDEX_SPECVAL@0x1062 v35:CInt64[0] = GuardBitEquals v34, CInt64(0) recompile v36:NilClass = Const Value(nil) Jump bb9(v36, v71) @@ -10218,16 +10218,16 @@ mod hir_opt_tests { CondBranch v39, bb10(), bb6(v18, v27) bb10(): v46:CPtr = GetEP 0 - v47:CUInt64 = LoadField v46, :VM_ENV_DATA_INDEX_FLAGS@0x1040 + v47:CUInt64 = LoadField v46, :VM_ENV_DATA_INDEX_FLAGS@0x1060 v48:CBool = IsBlockParamModified v47 CondBranch v48, bb11(), bb12() bb11(): - v50:BasicObject = LoadField v46, :blk@0x1041 + v50:BasicObject = LoadField v46, :blk@0x1061 Jump bb13(v50, v50) bb12(): - v52:CInt64 = LoadField v46, :VM_ENV_DATA_INDEX_SPECVAL@0x1042 + v52:CInt64 = LoadField v46, :VM_ENV_DATA_INDEX_SPECVAL@0x1062 v53:CInt64 = GuardAnyBitSet v52, CUInt64(1) recompile - v54:ObjectSubclass[BlockParamProxy] = Const Value(VALUE(0x1048)) + v54:ObjectSubclass[BlockParamProxy] = Const Value(VALUE(0x1068)) Jump bb13(v54, v27) bb13(v44:BasicObject, v45:BasicObject): v57:BasicObject = Send v44, :call # SendFallbackReason: Send: no profile data available @@ -16175,7 +16175,7 @@ mod hir_opt_tests { v21:RubyValue = LoadField v18, :VM_ENV_DATA_INDEX_SPECVAL@0x1048 v22:FalseClass = GuardBitEquals v21, Value(false) PushInlineFrame v6 (0x1050) - v29:StringExact[VALUE(0x1058)] = Const Value(VALUE(0x1058)) + v29:StringExact[VALUE(0x1078)] = Const Value(VALUE(0x1078)) v30:StringExact = StringCopy v29 CheckInterrupts PopInlineFrame @@ -16250,13 +16250,13 @@ mod hir_opt_tests { v32:FalseClass = GuardBitEquals v31, Value(false) PushInlineFrame v9 (0x1058), v10 v45:Fixnum[2] = Const Value(2) - PatchPoint MethodRedefined(Integer@0x1060, *@0x1068, cme:0x1070) + PatchPoint MethodRedefined(Integer@0x1080, *@0x1088, cme:0x1090) v59:Fixnum = GuardType v10, Fixnum recompile v60:Fixnum = FixnumMult v59, v45 CheckInterrupts PopInlineFrame v18:Fixnum[1] = Const Value(1) - PatchPoint MethodRedefined(Integer@0x1060, +@0x1098, cme:0x10a0) + PatchPoint MethodRedefined(Integer@0x1080, +@0x10b8, cme:0x10c0) v37:Fixnum = FixnumAdd v60, v18 Return v37 "); @@ -16656,7 +16656,7 @@ mod hir_opt_tests { SetLocal :other_block, l0, EP@3, v43 v30:CPtr = GetEP 0 v31:BasicObject = LoadField v30, :other_block@0x1002 - v33:BasicObject = InvokeSuper v42, 0x1050, v31 # SendFallbackReason: super: complex argument passing to `super` call + v33:BasicObject = InvokeSuper v42, 0x1070, v31 # SendFallbackReason: super: complex argument passing to `super` call CheckInterrupts Return v33 "); @@ -17303,14 +17303,14 @@ mod hir_opt_tests { Jump bb8(v131, v90, v132, v92, v93) bb8(v97:BasicObject, v98:BasicObject, v99:BasicObject, v100:BasicObject, v101:BasicObject): PatchPoint SingleRactorMode - PatchPoint StableConstantNames(0x1058, CONST) - v107:HashExact[VALUE(0x1060)] = Const Value(VALUE(0x1060)) + PatchPoint StableConstantNames(0x1078, CONST) + v107:HashExact[VALUE(0x1080)] = Const Value(VALUE(0x1080)) SetLocal :kwsplat, l0, EP@3, v107 v112:CPtr = GetEP 0 v113:BasicObject = LoadField v112, :list@0x1001 v115:CPtr = GetEP 0 v116:BasicObject = LoadField v115, :iter_method@0x1005 - v118:BasicObject = Send v113, 0x1068, :__send__, v116 # SendFallbackReason: Send: unsupported method type Optimized + v118:BasicObject = Send v113, 0x1088, :__send__, v116 # SendFallbackReason: Send: unsupported method type Optimized v119:CPtr = GetEP 0 v120:BasicObject = LoadField v119, :list@0x1001 v121:BasicObject = LoadField v119, :sep@0x1002 @@ -17367,7 +17367,7 @@ mod hir_opt_tests { v85:CInt64 = IntAnd v80, v84 v86:CPtr = LoadField v85, :code_iseq@0x1001 v87:CPtr[CPtr(0x1002)] = GuardBitEquals v86, CPtr(0x1002) recompile - v88:BasicObject = InvokeBlockIseqDirect (0x1008), v85, v77 + v88:BasicObject = InvokeBlockIseqDirect (0x1002), v85, v77 v92:Fixnum[1] = Const Value(1) v93:Fixnum = FixnumAdd v71, v92 PatchPoint NoEPEscape(each) @@ -17400,7 +17400,7 @@ mod hir_opt_tests { PatchPoint MethodRedefined(Object@0x1000, foo@0x1008, cme:0x1010) v18:ObjectSubclass[class_exact*:Object@VALUE(0x1000)] = GuardType v6, ObjectSubclass[class_exact*:Object@VALUE(0x1000)] recompile PushInlineFrame v18 (0x1038) - v27:StringExact[VALUE(0x1040)] = Const Value(VALUE(0x1040)) + v27:StringExact[VALUE(0x1060)] = Const Value(VALUE(0x1060)) CheckInterrupts PopInlineFrame Return v27 @@ -17474,10 +17474,10 @@ mod hir_opt_tests { v92:CInt64 = UnboxFixnum v87 v93:BasicObject = ArrayAref v86, v92 v95:CPtr = GetEP 0 - v96:CInt64 = LoadField v95, :VM_ENV_DATA_INDEX_SPECVAL@0x1048 + v96:CInt64 = LoadField v95, :VM_ENV_DATA_INDEX_SPECVAL@0x1068 v97:CInt64[-4] = Const CInt64(-4) v98:CInt64 = IntAnd v96, v97 - v99:BasicObject = InvokeBlockIseqDirect (0x1050), v98, v93 + v99:BasicObject = InvokeBlockIseqDirect (0x1070), v98, v93 v103:Fixnum[1] = Const Value(1) v104:Fixnum = FixnumAdd v87, v103 PatchPoint NoEPEscape(each) @@ -17718,13 +17718,13 @@ mod hir_opt_tests { PatchPoint MethodRedefined(Object@0x1008, greet_recompile@0x1010, cme:0x1018) v42:ObjectSubclass[class_exact*:Object@VALUE(0x1008)] = GuardType v9, ObjectSubclass[class_exact*:Object@VALUE(0x1008)] recompile PushInlineFrame v42 (0x1040), v22 - PatchPoint MethodRedefined(Integer@0x1048, to_s@0x1050, cme:0x1058) - v63:StringExact = CCallVariadic v22, :Integer#to_s@0x1080 + PatchPoint MethodRedefined(Integer@0x1068, to_s@0x1070, cme:0x1078) + v63:StringExact = CCallVariadic v22, :Integer#to_s@0x10a0 CheckInterrupts PopInlineFrame Return v63 bb4(v29:BasicObject, v30:Falsy): - v34:StringExact[VALUE(0x1088)] = Const Value(VALUE(0x1088)) + v34:StringExact[VALUE(0x10a8)] = Const Value(VALUE(0x10a8)) v35:StringExact = StringCopy v34 CheckInterrupts Return v35 @@ -19054,7 +19054,7 @@ mod hir_opt_tests { PatchPoint MethodRedefined(Object@0x1008, double@0x1010, cme:0x1018) v23:ObjectSubclass[class_exact*:Object@VALUE(0x1008)] = GuardType v9, ObjectSubclass[class_exact*:Object@VALUE(0x1008)] recompile PushInlineFrame v23 (0x1040), v10 - PatchPoint MethodRedefined(Integer@0x1048, +@0x1050, cme:0x1058) + PatchPoint MethodRedefined(Integer@0x1068, +@0x1070, cme:0x1078) v45:Fixnum = GuardType v10, Fixnum recompile v47:Fixnum = FixnumAdd v45, v45 CheckInterrupts @@ -19097,7 +19097,7 @@ mod hir_opt_tests { v23:ObjectSubclass[class_exact*:Object@VALUE(0x1008)] = GuardType v9, ObjectSubclass[class_exact*:Object@VALUE(0x1008)] recompile PushInlineFrame v23 (0x1040), v10 v32:Fixnum[0] = Const Value(0) - PatchPoint MethodRedefined(Integer@0x1048, <@0x1050, cme:0x1058) + PatchPoint MethodRedefined(Integer@0x1068, <@0x1070, cme:0x1078) v62:Fixnum = GuardType v10, Fixnum recompile v63:BoolExact = FixnumLt v62, v32 v37:CBool = Test v63 @@ -19146,7 +19146,7 @@ mod hir_opt_tests { v23:ObjectSubclass[class_exact*:Object@VALUE(0x1008)] = GuardType v9, ObjectSubclass[class_exact*:Object@VALUE(0x1008)] recompile PushInlineFrame v23 (0x1040), v10 v32:Fixnum[1] = Const Value(1) - PatchPoint MethodRedefined(Integer@0x1048, +@0x1050, cme:0x1058) + PatchPoint MethodRedefined(Integer@0x1068, +@0x1070, cme:0x1078) v46:Fixnum = GuardType v10, Fixnum recompile v47:Fixnum = FixnumAdd v46, v32 CheckInterrupts @@ -19207,8 +19207,8 @@ mod hir_opt_tests { PatchPoint MethodRedefined(Object@0x1008, outer@0x1010, cme:0x1018) v23:ObjectSubclass[class_exact*:Object@VALUE(0x1008)] = GuardType v9, ObjectSubclass[class_exact*:Object@VALUE(0x1008)] recompile PushInlineFrame v23 (0x1040), v10 - PatchPoint MethodRedefined(Object@0x1008, inner@0x1048, cme:0x1050) - v44:BasicObject = SendDirect v23, 0x1078, :inner (0x1088), v10 + PatchPoint MethodRedefined(Object@0x1008, inner@0x1068, cme:0x1070) + v44:BasicObject = SendDirect v23, 0x0, :inner (0x1098), v10 CheckInterrupts PopInlineFrame Return v44 @@ -19311,7 +19311,7 @@ mod hir_opt_tests { PushInlineFrame v23 (0x1040), v10 v32:Fixnum[10] = Const Value(10) v41:Fixnum[100] = Const Value(100) - PatchPoint MethodRedefined(Integer@0x1048, +@0x1050, cme:0x1058) + PatchPoint MethodRedefined(Integer@0x1068, +@0x1070, cme:0x1078) v71:Fixnum = GuardType v10, Fixnum recompile v72:Fixnum = FixnumAdd v71, v32 v76:Fixnum = FixnumAdd v72, v41 @@ -19367,7 +19367,7 @@ mod hir_opt_tests { v25:ObjectSubclass[class_exact*:Object@VALUE(0x1008)] = GuardType v9, ObjectSubclass[class_exact*:Object@VALUE(0x1008)] recompile PushInlineFrame v25 (0x1040), v10, v16 v34:Fixnum[100] = Const Value(100) - PatchPoint MethodRedefined(Integer@0x1048, +@0x1050, cme:0x1058) + PatchPoint MethodRedefined(Integer@0x1068, +@0x1070, cme:0x1078) v63:Fixnum = GuardType v10, Fixnum recompile v64:Fixnum = FixnumAdd v63, v16 v68:Fixnum = FixnumAdd v64, v34 @@ -19404,7 +19404,7 @@ mod hir_opt_tests { v18:ObjectSubclass[class_exact*:Object@VALUE(0x1000)] = GuardType v6, ObjectSubclass[class_exact*:Object@VALUE(0x1000)] recompile v40:NilClass = Const Value(nil) PushInlineFrame v18 (0x1038) - v26:StaticSymbol[:default] = Const Value(VALUE(0x1040)) + v26:StaticSymbol[:default] = Const Value(VALUE(0x1060)) CheckInterrupts PopInlineFrame Return v26 @@ -19491,7 +19491,7 @@ mod hir_opt_tests { v23:ObjectSubclass[class_exact*:Object@VALUE(0x1008)] = GuardType v9, ObjectSubclass[class_exact*:Object@VALUE(0x1008)] recompile PushInlineFrame v23 (0x1040), v10 v32:Fixnum[1] = Const Value(1) - PatchPoint MethodRedefined(Integer@0x1048, +@0x1050, cme:0x1058) + PatchPoint MethodRedefined(Integer@0x1068, +@0x1070, cme:0x1078) v47:Fixnum = GuardType v10, Fixnum recompile v48:Fixnum = FixnumAdd v47, v32 CheckInterrupts @@ -19588,22 +19588,22 @@ mod hir_opt_tests { PatchPoint MethodRedefined(Child@0x1008, greet@0x1010, cme:0x1018) v23:ObjectSubclass[class_exact:Child] = GuardType v10, ObjectSubclass[class_exact:Child] recompile PushInlineFrame v23 (0x1040) - PatchPoint MethodRedefined(Parent@0x1048, greet@0x1010, cme:0x1050) + PatchPoint MethodRedefined(Parent@0x1068, greet@0x1010, cme:0x1070) v47:CPtr = GetEP 0 - v48:RubyValue = LoadField v47, :VM_ENV_DATA_INDEX_ME_CREF@0x1078 + v48:RubyValue = LoadField v47, :VM_ENV_DATA_INDEX_ME_CREF@0x1098 v49:CallableMethodEntry[VALUE(0x1018)] = GuardBitEquals v48, Value(VALUE(0x1018)) - v50:RubyValue = LoadField v47, :VM_ENV_DATA_INDEX_SPECVAL@0x1079 + v50:RubyValue = LoadField v47, :VM_ENV_DATA_INDEX_SPECVAL@0x1099 v51:FalseClass = GuardBitEquals v50, Value(false) - PushInlineFrame v23 (0x1040) - v63:StringExact[VALUE(0x1080)] = Const Value(VALUE(0x1080)) + PushInlineFrame v23 (0x10a0) + v63:StringExact[VALUE(0x10c8)] = Const Value(VALUE(0x10c8)) v64:StringExact = StringCopy v63 CheckInterrupts PopInlineFrame - v33:StringExact[VALUE(0x1088)] = Const Value(VALUE(0x1088)) + v33:StringExact[VALUE(0x10d0)] = Const Value(VALUE(0x10d0)) v34:StringExact = StringCopy v33 - PatchPoint NoSingletonClass(String@0x1090) - PatchPoint MethodRedefined(String@0x1090, +@0x1098, cme:0x10a0) - v57:BasicObject = CCallWithFrame v64, :String#+@0x10c8, v34 + PatchPoint NoSingletonClass(String@0x10d8) + PatchPoint MethodRedefined(String@0x10d8, +@0x10e0, cme:0x10e8) + v57:BasicObject = CCallWithFrame v64, :String#+@0x1110, v34 CheckInterrupts PopInlineFrame Return v57 @@ -19655,7 +19655,7 @@ mod hir_opt_tests { PatchPoint MethodRedefined(Object@0x1008, add_opts@0x1010, cme:0x1018) v27:ObjectSubclass[class_exact*:Object@VALUE(0x1008)] = GuardType v9, ObjectSubclass[class_exact*:Object@VALUE(0x1008)] recompile PushInlineFrame v27 (0x1040), v10, v16, v18 - PatchPoint MethodRedefined(Integer@0x1048, +@0x1050, cme:0x1058) + PatchPoint MethodRedefined(Integer@0x1068, +@0x1070, cme:0x1078) v55:Fixnum = GuardType v10, Fixnum recompile v56:Fixnum = FixnumAdd v55, v16 v60:Fixnum = FixnumAdd v56, v18 @@ -19711,7 +19711,7 @@ mod hir_opt_tests { v23:ObjectSubclass[class_exact*:Object@VALUE(0x1008)] = GuardType v9, ObjectSubclass[class_exact*:Object@VALUE(0x1008)] recompile PushInlineFrame v23 (0x1040), v10 v31:Fixnum[10] = Const Value(10) - PatchPoint MethodRedefined(Integer@0x1048, +@0x1050, cme:0x1058) + PatchPoint MethodRedefined(Integer@0x1068, +@0x1070, cme:0x1078) v56:Fixnum = GuardType v10, Fixnum v57:Fixnum = FixnumAdd v31, v56 CheckInterrupts @@ -19767,7 +19767,7 @@ mod hir_opt_tests { v25:ObjectSubclass[class_exact*:Object@VALUE(0x1008)] = GuardType v9, ObjectSubclass[class_exact*:Object@VALUE(0x1008)] recompile PushInlineFrame v25 (0x1040), v10, v16 v34:Fixnum[10] = Const Value(10) - PatchPoint MethodRedefined(Integer@0x1048, +@0x1050, cme:0x1058) + PatchPoint MethodRedefined(Integer@0x1068, +@0x1070, cme:0x1078) v63:Fixnum = GuardType v10, Fixnum recompile v64:Fixnum = FixnumAdd v63, v34 v68:Fixnum = FixnumAdd v64, v16 @@ -19820,7 +19820,7 @@ mod hir_opt_tests { v25:ObjectSubclass[class_exact*:Object@VALUE(0x1008)] = GuardType v9, ObjectSubclass[class_exact*:Object@VALUE(0x1008)] recompile v43:Fixnum[0] = Const Value(0) PushInlineFrame v25 (0x1040), v10, v16 - PatchPoint MethodRedefined(Integer@0x1048, +@0x1050, cme:0x1058) + PatchPoint MethodRedefined(Integer@0x1068, +@0x1070, cme:0x1078) v50:Fixnum = GuardType v10, Fixnum recompile v51:Fixnum = FixnumAdd v50, v16 CheckInterrupts @@ -19872,7 +19872,7 @@ mod hir_opt_tests { v25:ObjectSubclass[class_exact*:Object@VALUE(0x1008)] = GuardType v9, ObjectSubclass[class_exact*:Object@VALUE(0x1008)] recompile v43:Fixnum[0] = Const Value(0) PushInlineFrame v25 (0x1040), v10, v16 - PatchPoint MethodRedefined(Integer@0x1048, +@0x1050, cme:0x1058) + PatchPoint MethodRedefined(Integer@0x1068, +@0x1070, cme:0x1078) v50:Fixnum = GuardType v10, Fixnum recompile v51:Fixnum = FixnumAdd v50, v16 CheckInterrupts @@ -19924,7 +19924,7 @@ mod hir_opt_tests { v25:ObjectSubclass[class_exact*:Object@VALUE(0x1008)] = GuardType v9, ObjectSubclass[class_exact*:Object@VALUE(0x1008)] recompile v43:Fixnum[0] = Const Value(0) PushInlineFrame v25 (0x1040), v10, v22 - PatchPoint MethodRedefined(Integer@0x1048, +@0x1050, cme:0x1058) + PatchPoint MethodRedefined(Integer@0x1068, +@0x1070, cme:0x1078) v50:Fixnum = GuardType v10, Fixnum recompile v51:Fixnum = FixnumAdd v50, v22 CheckInterrupts @@ -19979,11 +19979,11 @@ mod hir_opt_tests { v61:Fixnum[0] = Const Value(0) PushInlineFrame v28 (0x1040), v10, v18, v16 v40:Fixnum[100] = Const Value(100) - PatchPoint MethodRedefined(Integer@0x1048, *@0x1050, cme:0x1058) + PatchPoint MethodRedefined(Integer@0x1068, *@0x1070, cme:0x1078) v68:Fixnum = GuardType v10, Fixnum recompile v69:Fixnum = FixnumMult v68, v40 v82:Fixnum[20] = Const Value(20) - PatchPoint MethodRedefined(Integer@0x1048, +@0x1080, cme:0x1088) + PatchPoint MethodRedefined(Integer@0x1068, +@0x10a0, cme:0x10a8) v77:Fixnum = FixnumAdd v69, v82 v81:Fixnum = FixnumAdd v77, v16 CheckInterrupts @@ -20041,12 +20041,12 @@ mod hir_opt_tests { CondBranch v36, bb6(v25, v10, v22, v63), bb7() bb7(): v42:Fixnum[2] = Const Value(2) - PatchPoint MethodRedefined(Integer@0x1048, *@0x1050, cme:0x1058) + PatchPoint MethodRedefined(Integer@0x1068, *@0x1070, cme:0x1078) v70:Fixnum = GuardType v10, Fixnum recompile v71:Fixnum = FixnumMult v70, v42 Jump bb6(v25, v70, v71, v63) bb6(v48:ObjectSubclass[class_exact*:Object@VALUE(0x1008)], v49:BasicObject, v50:NilClass|Fixnum, v51:Fixnum[1]): - PatchPoint MethodRedefined(Integer@0x1048, +@0x1080, cme:0x1088) + PatchPoint MethodRedefined(Integer@0x1068, +@0x10a0, cme:0x10a8) v74:Fixnum = GuardType v49, Fixnum recompile v75:Fixnum = GuardType v50, Fixnum v76:Fixnum = FixnumAdd v74, v75 @@ -20102,7 +20102,7 @@ mod hir_opt_tests { PatchPoint MethodRedefined(Object@0x1008, add_lead_opt_post@0x1010, cme:0x1018) v27:ObjectSubclass[class_exact*:Object@VALUE(0x1008)] = GuardType v9, ObjectSubclass[class_exact*:Object@VALUE(0x1008)] recompile PushInlineFrame v27 (0x1040), v10, v16, v18 - PatchPoint MethodRedefined(Integer@0x1048, +@0x1050, cme:0x1058) + PatchPoint MethodRedefined(Integer@0x1068, +@0x1070, cme:0x1078) v55:Fixnum = GuardType v10, Fixnum recompile v56:Fixnum = FixnumAdd v55, v16 v60:Fixnum = FixnumAdd v56, v18 @@ -20158,10 +20158,10 @@ mod hir_opt_tests { v25:ObjectSubclass[class_exact*:Object@VALUE(0x1008)] = GuardType v9, ObjectSubclass[class_exact*:Object@VALUE(0x1008)] recompile PushInlineFrame v25 (0x1040), v10 v34:CPtr = GetEP 0 - v35:CInt64 = LoadField v34, :VM_ENV_DATA_INDEX_SPECVAL@0x1048 + v35:CInt64 = LoadField v34, :VM_ENV_DATA_INDEX_SPECVAL@0x1068 v36:CInt64[-4] = Const CInt64(-4) v37:CInt64 = IntAnd v35, v36 - v38:BasicObject = InvokeBlockIseqDirect (0x1050), v37, v10 + v38:BasicObject = InvokeBlockIseqDirect (0x1070), v37, v10 CheckInterrupts PopInlineFrame PatchPoint NoEPEscape(test) @@ -20215,16 +20215,16 @@ mod hir_opt_tests { v53:NilClass = Const Value(nil) PushInlineFrame v25 (0x1040), v10 v36:CPtr = GetEP 0 - v37:CUInt64 = LoadField v36, :VM_ENV_DATA_INDEX_FLAGS@0x1048 + v37:CUInt64 = LoadField v36, :VM_ENV_DATA_INDEX_FLAGS@0x1068 v38:CBool = IsBlockParamModified v37 CondBranch v38, bb6(), bb7() bb6(): - v40:BasicObject = LoadField v36, :block@0x1049 + v40:BasicObject = LoadField v36, :block@0x1069 Jump bb8(v40, v40) bb7(): - v42:CInt64 = LoadField v36, :VM_ENV_DATA_INDEX_SPECVAL@0x104a + v42:CInt64 = LoadField v36, :VM_ENV_DATA_INDEX_SPECVAL@0x106a v43:CInt64 = GuardAnyBitSet v42, CUInt64(1) recompile - v44:ObjectSubclass[BlockParamProxy] = Const Value(VALUE(0x1050)) + v44:ObjectSubclass[BlockParamProxy] = Const Value(VALUE(0x1070)) Jump bb8(v44, v53) bb8(v34:BasicObject, v35:BasicObject): v48:BasicObject = Send v34, :call, v10 # SendFallbackReason: Send: unsupported optimized method type BlockCall @@ -20279,16 +20279,16 @@ mod hir_opt_tests { v54:NilClass = Const Value(nil) PushInlineFrame v25 (0x1040), v10 v38:CPtr = GetEP 0 - v39:CUInt64 = LoadField v38, :VM_ENV_DATA_INDEX_FLAGS@0x1048 + v39:CUInt64 = LoadField v38, :VM_ENV_DATA_INDEX_FLAGS@0x1068 v40:CBool = IsBlockParamModified v39 CondBranch v40, bb6(), bb7() bb6(): - v42:BasicObject = LoadField v38, :block@0x1049 + v42:BasicObject = LoadField v38, :block@0x1069 Jump bb8(v42, v42) bb7(): - v44:CInt64 = LoadField v38, :VM_ENV_DATA_INDEX_SPECVAL@0x104a + v44:CInt64 = LoadField v38, :VM_ENV_DATA_INDEX_SPECVAL@0x106a v45:CInt64 = GuardAnyBitSet v44, CUInt64(1) recompile - v46:ObjectSubclass[BlockParamProxy] = Const Value(VALUE(0x1050)) + v46:ObjectSubclass[BlockParamProxy] = Const Value(VALUE(0x1070)) Jump bb8(v46, v54) bb8(v36:BasicObject, v37:BasicObject): v49:BasicObject = Send v25, &block, :inner, v10, v36 # SendFallbackReason: Send: block argument is not nil @@ -20355,22 +20355,22 @@ mod hir_opt_tests { PatchPoint NoSingletonClass(Point@0x1008) PatchPoint MethodRedefined(Point@0x1008, initialize@0x1038, cme:0x1040) PushInlineFrame v89 (0x1068), v17, v19 - v121:CShape = LoadField v89, :shape_id@0x1070 - v122:CShape[0x1071] = GuardBitEquals v121, CShape(0x1071) recompile - StoreField v89, :@x@0x1072, v17 + v121:CShape = LoadField v89, :shape_id@0x1090 + v122:CShape[0x1091] = GuardBitEquals v121, CShape(0x1091) recompile + StoreField v89, :@x@0x1092, v17 WriteBarrier v89, v17 - v125:CShape[0x1073] = Const CShape(0x1073) - StoreField v89, :shape_id@0x1070, v125 + v125:CShape[0x1093] = Const CShape(0x1093) + StoreField v89, :shape_id@0x1090, v125 PatchPoint NoEPEscape(initialize) PatchPoint SingleRactorMode - StoreField v89, :@y@0x1074, v19 + StoreField v89, :@y@0x1094, v19 WriteBarrier v89, v19 - v140:CShape[0x1075] = Const CShape(0x1075) - StoreField v89, :shape_id@0x1070, v140 + v140:CShape[0x1095] = Const CShape(0x1095) + StoreField v89, :shape_id@0x1090, v140 CheckInterrupts PopInlineFrame PatchPoint SingleRactorMode - PatchPoint StableConstantNames(0x1078, Point) + PatchPoint StableConstantNames(0x1098, Point) v46:ClassSubclass[Point@0x1008] = Const Value(VALUE(0x1008)) v48:NilClass = Const Value(nil) v51:Fixnum[1] = Const Value(1) @@ -20380,30 +20380,30 @@ mod hir_opt_tests { PatchPoint NoSingletonClass(Point@0x1008) PatchPoint MethodRedefined(Point@0x1008, initialize@0x1038, cme:0x1040) PushInlineFrame v99 (0x1068), v51, v53 - v161:CShape = LoadField v99, :shape_id@0x1070 - v162:CShape[0x1071] = GuardBitEquals v161, CShape(0x1071) recompile - StoreField v99, :@x@0x1072, v51 + v161:CShape = LoadField v99, :shape_id@0x1090 + v162:CShape[0x1091] = GuardBitEquals v161, CShape(0x1091) recompile + StoreField v99, :@x@0x1092, v51 WriteBarrier v99, v51 - v165:CShape[0x1073] = Const CShape(0x1073) - StoreField v99, :shape_id@0x1070, v165 + v165:CShape[0x1093] = Const CShape(0x1093) + StoreField v99, :shape_id@0x1090, v165 PatchPoint NoEPEscape(initialize) PatchPoint SingleRactorMode - StoreField v99, :@y@0x1074, v53 + StoreField v99, :@y@0x1094, v53 WriteBarrier v99, v53 - v180:CShape[0x1075] = Const CShape(0x1075) - StoreField v99, :shape_id@0x1070, v180 + v180:CShape[0x1095] = Const CShape(0x1095) + StoreField v99, :shape_id@0x1090, v180 CheckInterrupts PopInlineFrame PatchPoint NoSingletonClass(Point@0x1008) - PatchPoint MethodRedefined(Point@0x1008, ==@0x1080, cme:0x1088) - PushInlineFrame v89 (0x1068), v99 + PatchPoint MethodRedefined(Point@0x1008, ==@0x10a0, cme:0x10a8) + PushInlineFrame v89 (0x10d0), v99 PatchPoint SingleRactorMode - v199:CShape = LoadField v89, :shape_id@0x1070 - v200:CShape[0x1075] = GuardBitEquals v199, CShape(0x1075) recompile - v201:BasicObject = LoadField v89, :@x@0x1072 + v199:CShape = LoadField v89, :shape_id@0x1090 + v200:CShape[0x1095] = GuardBitEquals v199, CShape(0x1095) recompile + v201:BasicObject = LoadField v89, :@x@0x1092 PatchPoint NoEPEscape(==) - PatchPoint MethodRedefined(Point@0x1008, x@0x10b0, cme:0x10b8) - PatchPoint MethodRedefined(Integer@0x10e0, ==@0x1080, cme:0x10e8) + PatchPoint MethodRedefined(Point@0x1008, x@0x10f8, cme:0x1100) + PatchPoint MethodRedefined(Integer@0x1128, ==@0x10a0, cme:0x1130) v255:Fixnum = GuardType v201, Fixnum recompile v257:BoolExact = FixnumEq v255, v51 v212:CBool = Test v257 @@ -20411,16 +20411,16 @@ mod hir_opt_tests { CondBranch v212, bb19(), bb18(v89, v99, v213) bb19(): PatchPoint SingleRactorMode - v220:CShape = LoadField v89, :shape_id@0x1070 - v221:CShape[0x1075] = GuardBitEquals v220, CShape(0x1075) recompile - v222:BasicObject = LoadField v89, :@y@0x1074 + v220:CShape = LoadField v89, :shape_id@0x1090 + v221:CShape[0x1095] = GuardBitEquals v220, CShape(0x1095) recompile + v222:BasicObject = LoadField v89, :@y@0x1094 PatchPoint NoEPEscape(==) PatchPoint NoSingletonClass(Point@0x1008) - PatchPoint MethodRedefined(Point@0x1008, y@0x1110, cme:0x1118) - v262:CShape = LoadField v99, :shape_id@0x1070 - v263:CShape[0x1075] = GuardBitEquals v262, CShape(0x1075) recompile - v264:BasicObject = LoadField v99, :@y@0x1074 - PatchPoint MethodRedefined(Integer@0x10e0, ==@0x1080, cme:0x10e8) + PatchPoint MethodRedefined(Point@0x1008, y@0x1158, cme:0x1160) + v262:CShape = LoadField v99, :shape_id@0x1090 + v263:CShape[0x1095] = GuardBitEquals v262, CShape(0x1095) recompile + v264:BasicObject = LoadField v99, :@y@0x1094 + PatchPoint MethodRedefined(Integer@0x1128, ==@0x10a0, cme:0x1130) v267:Fixnum = GuardType v222, Fixnum recompile v268:Fixnum = GuardType v264, Fixnum v269:BoolExact = FixnumEq v267, v268 diff --git a/zjit/src/hir/tests.rs b/zjit/src/hir/tests.rs index 22a6a6440d2058..705a55b26ebd63 100644 --- a/zjit/src/hir/tests.rs +++ b/zjit/src/hir/tests.rs @@ -206,9 +206,9 @@ mod snapshot_tests { v25:ObjectSubclass[class_exact*:Object@VALUE(0x1010)] = GuardType v6, ObjectSubclass[class_exact*:Object@VALUE(0x1010)] recompile v44:Fixnum[0] = Const Value(0) PushInlineFrame v25 (0x1048), v13, v15, v11 - v38:Any = Snapshot FrameState { pc: 0x1050, stack: [v13, v15, v11], locals: [a=v13, b=v15, c=v11, ID(0)=v44], caller: v27 } + v38:Any = Snapshot FrameState { pc: 0x1070, stack: [v13, v15, v11], locals: [a=v13, b=v15, c=v11, ID(0)=v44], caller: v27 } v39:ArrayExact = NewArray v13, v15, v11 - v40:Any = Snapshot FrameState { pc: 0x1058, stack: [v39], locals: [a=v13, b=v15, c=v11, ID(0)=v44], caller: v27 } + v40:Any = Snapshot FrameState { pc: 0x1078, stack: [v39], locals: [a=v13, b=v15, c=v11, ID(0)=v44], caller: v27 } CheckInterrupts PopInlineFrame Return v39 @@ -245,9 +245,9 @@ mod snapshot_tests { v22:ObjectSubclass[class_exact*:Object@VALUE(0x1010)] = GuardType v6, ObjectSubclass[class_exact*:Object@VALUE(0x1010)] recompile v39:Fixnum[0] = Const Value(0) PushInlineFrame v22 (0x1048), v11, v13 - v33:Any = Snapshot FrameState { pc: 0x1050, stack: [v11, v13], locals: [a=v11, b=v13, ID(0)=v39], caller: v24 } + v33:Any = Snapshot FrameState { pc: 0x1070, stack: [v11, v13], locals: [a=v11, b=v13, ID(0)=v39], caller: v24 } v34:ArrayExact = NewArray v11, v13 - v35:Any = Snapshot FrameState { pc: 0x1058, stack: [v34], locals: [a=v11, b=v13, ID(0)=v39], caller: v24 } + v35:Any = Snapshot FrameState { pc: 0x1078, stack: [v34], locals: [a=v11, b=v13, ID(0)=v39], caller: v24 } CheckInterrupts PopInlineFrame Return v34 @@ -6087,7 +6087,7 @@ pub(crate) mod hir_build_tests { bb3(v6:BasicObject): v10:BasicObject = GetConstantPath 0x1000 v12:BasicObject = Send v10, :induce_side_exit! # SendFallbackReason: Uncategorized(opt_send_without_block) - v16:BasicObject = GetConstantPath 0x1000 + v16:BasicObject = GetConstantPath 0x1010 SideExit DirectiveInduced "); } From ab191be2f5b56b605b48dbfc180ba210468c08df Mon Sep 17 00:00:00 2001 From: Takashi Kokubun Date: Wed, 29 Jul 2026 09:10:53 -0700 Subject: [PATCH 12/17] ZJIT: Only accept raw pointers in PtrPrintMap::map_ptr Previously map_ptr() took *const T, so a reference like &IseqPtr silently coerced to *const IseqPtr and mapped the address of the reference itself instead of the pointer value, which is how the bug fixed by the previous commit slipped in. Constrain the parameter with an ActualPtr trait implemented only for *const T and *mut T, so passing a reference no longer compiles. Co-authored-by: Max Bernstein --- zjit/src/hir.rs | 43 +++++++++++++++++++++++++++++++++++-------- 1 file changed, 35 insertions(+), 8 deletions(-) diff --git a/zjit/src/hir.rs b/zjit/src/hir.rs index 980b0147c6a12a..32fee1c1ac4aaa 100644 --- a/zjit/src/hir.rs +++ b/zjit/src/hir.rs @@ -478,9 +478,35 @@ impl std::fmt::LowerHex for Offset { } } +/// Raw pointer types accepted by [`PtrPrintMap::map_ptr`]. Only implemented for +/// raw pointers so that accidentally passing a reference (e.g. `&IseqPtr`), which +/// would map the address of the reference itself, is a compile error. +pub trait ActualPtr: Copy { + fn to_void(self) -> *const c_void; + fn from_void(ptr: *const c_void) -> Self; + /// Alignment of the pointee, used to pick a suitably aligned fake address + fn pointee_align() -> usize; + /// Size of the pointee, used to bump the fake address allocator + fn pointee_size() -> usize; +} + +impl ActualPtr for *const T { + fn to_void(self) -> *const c_void { self.cast() } + fn from_void(ptr: *const c_void) -> Self { ptr.cast() } + fn pointee_align() -> usize { align_of::() } + fn pointee_size() -> usize { size_of::() } +} + +impl ActualPtr for *mut T { + fn to_void(self) -> *const c_void { self.cast_const().cast() } + fn from_void(ptr: *const c_void) -> Self { ptr.cast::().cast_mut() } + fn pointee_align() -> usize { align_of::() } + fn pointee_size() -> usize { size_of::() } +} + impl PtrPrintMap { /// Map a pointer for printing - pub fn map_ptr(&self, ptr: *const T) -> *const T { + pub fn map_ptr(&self, ptr: P) -> P { // When testing, address stability is not a concern so print real address to enable code // reuse if !self.map_ptrs { @@ -488,18 +514,19 @@ impl PtrPrintMap { } use std::collections::hash_map::Entry::*; - let ptr = ptr.cast(); + let raw = ptr.to_void(); let inner = &mut *self.inner.borrow_mut(); - match inner.map.entry(ptr) { - Occupied(entry) => entry.get().cast(), + match inner.map.entry(raw) { + Occupied(entry) => P::from_void(*entry.get()), Vacant(entry) => { - // Pick a fake address that is suitably aligns for T and remember it in the map - let mapped = inner.next_ptr.wrapping_add(inner.next_ptr.align_offset(align_of::())); + // Pick a fake address that is suitably aligned for the pointee and + // remember it in the map + let mapped = inner.next_ptr.wrapping_add(inner.next_ptr.align_offset(P::pointee_align())); entry.insert(mapped); // Bump for the next pointer - inner.next_ptr = mapped.wrapping_add(size_of::()); - mapped.cast() + inner.next_ptr = mapped.wrapping_add(P::pointee_size()); + P::from_void(mapped) } } } From 72749d7df3e370282405c15cba28882f3e102080 Mon Sep 17 00:00:00 2001 From: Takashi Kokubun Date: Wed, 29 Jul 2026 09:46:12 -0700 Subject: [PATCH 13/17] ZJIT: Allowlist pointee types in PtrPrintMap::map_ptr Co-authored-by: Alan Wu --- zjit/src/hir.rs | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/zjit/src/hir.rs b/zjit/src/hir.rs index 32fee1c1ac4aaa..ca93780ba83043 100644 --- a/zjit/src/hir.rs +++ b/zjit/src/hir.rs @@ -478,9 +478,23 @@ impl std::fmt::LowerHex for Offset { } } +/// Marker trait that allowlists the pointee types [`PtrPrintMap::map_ptr`] accepts. +/// Without it, a multi-level pointer like `*const IseqPtr`, usually the result of +/// casting a reference created by matching on an [`Insn`], would map the address +/// of the temporary holding the pointer instead of the pointer value itself. +pub trait HIRPointee {} +impl HIRPointee for VALUE {} +impl HIRPointee for ID {} +impl HIRPointee for c_void {} +impl HIRPointee for u8 {} +impl HIRPointee for rb_iseq_t {} +impl HIRPointee for rb_callable_method_entry_t {} +impl HIRPointee for iseq_inline_constant_cache {} + /// Raw pointer types accepted by [`PtrPrintMap::map_ptr`]. Only implemented for -/// raw pointers so that accidentally passing a reference (e.g. `&IseqPtr`), which -/// would map the address of the reference itself, is a compile error. +/// raw pointers to [`HIRPointee`] types so that accidentally passing a reference +/// (e.g. `&IseqPtr`), which would map the address of the reference itself, is a +/// compile error. pub trait ActualPtr: Copy { fn to_void(self) -> *const c_void; fn from_void(ptr: *const c_void) -> Self; @@ -490,14 +504,14 @@ pub trait ActualPtr: Copy { fn pointee_size() -> usize; } -impl ActualPtr for *const T { +impl ActualPtr for *const T { fn to_void(self) -> *const c_void { self.cast() } fn from_void(ptr: *const c_void) -> Self { ptr.cast() } fn pointee_align() -> usize { align_of::() } fn pointee_size() -> usize { size_of::() } } -impl ActualPtr for *mut T { +impl ActualPtr for *mut T { fn to_void(self) -> *const c_void { self.cast_const().cast() } fn from_void(ptr: *const c_void) -> Self { ptr.cast::().cast_mut() } fn pointee_align() -> usize { align_of::() } From 3731d6659f8458690cbb65f73edd569b515045fd Mon Sep 17 00:00:00 2001 From: Takashi Kokubun Date: Tue, 28 Jul 2026 12:12:49 -0700 Subject: [PATCH 14/17] ZJIT: Reject direct block calls with too many args for LIR The invokeblock fast path (InvokeBlockIseqDirect) passes captured self plus each block argument in C argument registers, but block_call_inlinable_iseq never bounded the argument count. Yielding 6+ arguments to a matching-arity block made gen_invoke_block_iseq_direct emit a CCall with more operands than C_ARG_OPNDS, which aborts the process in the backend: assertion failed: data.opnds.len() <= C_ARG_OPNDS.len() at zjit/src/backend/x86_64/mod.rs:302 Reject such blocks in block_call_inlinable_iseq so both the guarded and the inlined-caller yield paths fall back to VM dispatch. --- zjit/src/codegen_tests.rs | 14 ++++++++++++++ zjit/src/hir.rs | 6 ++++++ 2 files changed, 20 insertions(+) diff --git a/zjit/src/codegen_tests.rs b/zjit/src/codegen_tests.rs index a943f06d572400..8e9308b43294c8 100644 --- a/zjit/src/codegen_tests.rs +++ b/zjit/src/codegen_tests.rs @@ -608,6 +608,20 @@ fn test_yield_inline_invocation_with_args() { assert_snapshot!(assert_compiles("test"), @"7"); } +#[test] +fn test_yield_with_too_many_args_for_lir() { + // Self plus six yield args don't fit in C argument registers, so the direct + // block invocation must be rejected instead of emitting an uncompilable CCall. + set_call_threshold(2); + eval(" + def foo = yield(1, 2, 3, 4, 5, 6) + def test = foo { |a, b, c, d, e, f| a + b + c + d + e + f } + test + test + "); + assert_snapshot!(assert_compiles("test"), @"21"); +} + #[test] fn test_yield_inline_invocation_live_stack_below_args() { // A live value sits on the stack below the yield args; the no-receiver-slot SP math diff --git a/zjit/src/hir.rs b/zjit/src/hir.rs index ca93780ba83043..94aa83ca9bae64 100644 --- a/zjit/src/hir.rs +++ b/zjit/src/hir.rs @@ -2875,6 +2875,12 @@ fn block_call_inlinable_iseq(iseq: IseqPtr, argc: usize) -> bool { if argc == 1 && !unsafe { rb_get_iseq_flags_ambiguous_param0(iseq) } { return false; } + // The JIT-to-JIT call in gen_invoke_block_iseq_direct passes captured self plus + // each argument in C argument registers. + // TODO: Support passing arguments on the stack in C calls + if 1 + argc > C_ARG_OPNDS.len() { + return false; + } !crate::codegen::block_iseq_may_throw(iseq) } From 8b2bd6a5009dae5a448ff7726bfbcc51accca9ca Mon Sep 17 00:00:00 2001 From: Takashi Kokubun Date: Wed, 29 Jul 2026 09:12:19 -0700 Subject: [PATCH 15/17] ZJIT: Add HIR opt tests for oversized direct block calls --- zjit/src/hir/opt_tests.rs | 72 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) diff --git a/zjit/src/hir/opt_tests.rs b/zjit/src/hir/opt_tests.rs index 503b7d7e46d55c..3e4137480b5ecf 100644 --- a/zjit/src/hir/opt_tests.rs +++ b/zjit/src/hir/opt_tests.rs @@ -3949,6 +3949,78 @@ mod hir_opt_tests { "); } + #[test] + fn test_yield_with_too_many_args_for_lir_falls_back() { + // Captured self plus six args don't fit in C argument registers, so the profiled + // invokeblock specialization must not emit InvokeBlockIseqDirect. + let result = eval(" + def foo = yield(1, 2, 3, 4, 5, 6) + def test = foo { |a, b, c, d, e, f| a + b + c + d + e + f } + test + test + "); + assert_eq!(VALUE::fixnum_from_usize(21), result); + assert_snapshot!(hir_string("foo"), @" + fn foo@:2: + bb1(): + EntryPoint interpreter + v1:BasicObject = LoadSelf + Jump bb3(v1) + bb2(): + EntryPoint JIT(0) + v4:BasicObject = LoadArg :self@0 + Jump bb3(v4) + bb3(v6:BasicObject): + v10:Fixnum[1] = Const Value(1) + v12:Fixnum[2] = Const Value(2) + v14:Fixnum[3] = Const Value(3) + v16:Fixnum[4] = Const Value(4) + v18:Fixnum[5] = Const Value(5) + v20:Fixnum[6] = Const Value(6) + v22:BasicObject = InvokeBlock v10, v12, v14, v16, v18, v20 # SendFallbackReason: InvokeBlock: not yet specialized + CheckInterrupts + Return v22 + "); + } + + #[test] + fn test_inlined_yield_with_too_many_args_for_lir_falls_back() { + // Same as test_yield_with_too_many_args_for_lir_falls_back, but for the guard-free + // yield dispatch inside an inlined callee whose caller passes a literal block. + let result = eval(" + def foo = yield(1, 2, 3, 4, 5, 6) + def test = foo { |a, b, c, d, e, f| a + b + c + d + e + f } + test + test + "); + assert_eq!(VALUE::fixnum_from_usize(21), result); + assert_snapshot!(hir_string("test"), @" + fn test@:3: + bb1(): + EntryPoint interpreter + v1:BasicObject = LoadSelf + Jump bb3(v1) + bb2(): + EntryPoint JIT(0) + v4:BasicObject = LoadArg :self@0 + Jump bb3(v4) + bb3(v6:BasicObject): + PatchPoint MethodRedefined(Object@0x1000, foo@0x1008, cme:0x1010) + v18:ObjectSubclass[class_exact*:Object@VALUE(0x1000)] = GuardType v6, ObjectSubclass[class_exact*:Object@VALUE(0x1000)] recompile + PushInlineFrame v18 (0x1038) + v25:Fixnum[1] = Const Value(1) + v27:Fixnum[2] = Const Value(2) + v29:Fixnum[3] = Const Value(3) + v31:Fixnum[4] = Const Value(4) + v33:Fixnum[5] = Const Value(5) + v35:Fixnum[6] = Const Value(6) + v37:BasicObject = InvokeBlock v25, v27, v29, v31, v33, v35 # SendFallbackReason: InvokeBlock: not yet specialized + CheckInterrupts + PopInlineFrame + Return v37 + "); + } + #[test] fn test_yield_lambda_falls_back() { // A lambda passed via &l becomes a proc block handler (not imemo_iseq), so it never inlines invocation. From 6ea07a482452e2c6c22712e633b3200c4b351ba6 Mon Sep 17 00:00:00 2001 From: Takashi Kokubun Date: Wed, 29 Jul 2026 09:44:19 -0700 Subject: [PATCH 16/17] Fix a comment about too many args Co-authored-by: Kevin Menard --- zjit/src/codegen_tests.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zjit/src/codegen_tests.rs b/zjit/src/codegen_tests.rs index 8e9308b43294c8..a2d730dfb7e5b1 100644 --- a/zjit/src/codegen_tests.rs +++ b/zjit/src/codegen_tests.rs @@ -610,7 +610,7 @@ fn test_yield_inline_invocation_with_args() { #[test] fn test_yield_with_too_many_args_for_lir() { - // Self plus six yield args don't fit in C argument registers, so the direct + // `self` + six yield args don't fit in C argument registers, so the direct // block invocation must be rejected instead of emitting an uncompilable CCall. set_call_threshold(2); eval(" From 20449aa1785aaed03e199fbdba3f550e76de9bfb Mon Sep 17 00:00:00 2001 From: Takashi Kokubun Date: Wed, 29 Jul 2026 09:48:34 -0700 Subject: [PATCH 17/17] ZJIT: Use TooManyArgsForLir reason for oversized direct block calls --- zjit/src/hir.rs | 39 ++++++++++++++++++++++++++------------- zjit/src/hir/opt_tests.rs | 4 ++-- 2 files changed, 28 insertions(+), 15 deletions(-) diff --git a/zjit/src/hir.rs b/zjit/src/hir.rs index 94aa83ca9bae64..e849f83e9da33e 100644 --- a/zjit/src/hir.rs +++ b/zjit/src/hir.rs @@ -2860,28 +2860,32 @@ fn block_call_inlinable(flags: u32) -> bool { (flags & (VM_CALL_ARGS_SPLAT | VM_CALL_KW_SPLAT | VM_CALL_KWARG | VM_CALL_ARGS_BLOCKARG)) == 0 } -/// True if `yield` with `argc` positional args can dispatch by inlining the block ISEQ +/// Ok if `yield` with `argc` positional args can dispatch by inlining the block ISEQ /// frame. The block must take the simple callee-setup path (`rb_simple_iseq_p`) /// with an exact arity match, avoid arg0 auto-splat, and contain no `throw` (break / -/// non-local return). Anything else falls back to the generic `invokeblock` dispatch. -fn block_call_inlinable_iseq(iseq: IseqPtr, argc: usize) -> bool { +/// non-local return). Anything else falls back to the generic `invokeblock` dispatch, +/// with the returned reason attached to the fallback instruction. +fn block_call_inlinable_iseq(iseq: IseqPtr, argc: usize) -> Result<(), SendFallbackReason> { if !unsafe { rb_simple_iseq_p(iseq) } { - return false; + return Err(InvokeBlockNotSpecialized); } let lead_num = unsafe { rb_get_iseq_body_param_lead_num(iseq) } as usize; if argc != lead_num { - return false; + return Err(InvokeBlockNotSpecialized); } if argc == 1 && !unsafe { rb_get_iseq_flags_ambiguous_param0(iseq) } { - return false; + return Err(InvokeBlockNotSpecialized); } // The JIT-to-JIT call in gen_invoke_block_iseq_direct passes captured self plus // each argument in C argument registers. // TODO: Support passing arguments on the stack in C calls if 1 + argc > C_ARG_OPNDS.len() { - return false; + return Err(TooManyArgsForLir); + } + if crate::codegen::block_iseq_may_throw(iseq) { + return Err(InvokeBlockNotSpecialized); } - !crate::codegen::block_iseq_may_throw(iseq) + Ok(()) } impl Function { @@ -9379,11 +9383,15 @@ fn add_iseq_to_hir( // If the block handler is a known simple ISEQ block with exact arity and no // non-local exit, push its frame inline instead of calling rb_vm_invokeblock. + let mut fallback_reason = InvokeBlockNotSpecialized; let inline_iseq = if block_call_inlinable(flags) { block_handler_class.and_then(|obj| { if unsafe { rb_IMEMO_TYPE_P(obj, imemo_iseq) == 1 } { let iseq = obj.as_iseq(); - if block_call_inlinable_iseq(iseq, args.len()) { return Some(iseq); } + match block_call_inlinable_iseq(iseq, args.len()) { + Ok(()) => return Some(iseq), + Err(reason) => fallback_reason = reason, + } } None }) @@ -9397,9 +9405,14 @@ fn add_iseq_to_hir( // TODO: if block iseqs become inlinable, a yield here could resolve to an ancestor frame // (level > 0). To stay guard-free we'd bake in get_lvar_level(...) as the level and fetch // that ancestor's blockiseq from the inline caller chain instead of bi. - && get_lvar_level(exit_state.iseq) == 0 - && block_call_inlinable_iseq(bi, args.len()) { - Some(bi) + && get_lvar_level(exit_state.iseq) == 0 { + match block_call_inlinable_iseq(bi, args.len()) { + Ok(()) => Some(bi), + Err(reason) => { + fallback_reason = reason; + None + } + } } else { None } } else { None }; @@ -9454,7 +9467,7 @@ fn add_iseq_to_hir( block = join_block; join_param } else { - fun.push_insn(block, Insn::InvokeBlock { cd, args, state: exit_id, reason: InvokeBlockNotSpecialized }) + fun.push_insn(block, Insn::InvokeBlock { cd, args, state: exit_id, reason: fallback_reason }) }; state.stack_push(result); } diff --git a/zjit/src/hir/opt_tests.rs b/zjit/src/hir/opt_tests.rs index 3e4137480b5ecf..ae4322702c02f1 100644 --- a/zjit/src/hir/opt_tests.rs +++ b/zjit/src/hir/opt_tests.rs @@ -3977,7 +3977,7 @@ mod hir_opt_tests { v16:Fixnum[4] = Const Value(4) v18:Fixnum[5] = Const Value(5) v20:Fixnum[6] = Const Value(6) - v22:BasicObject = InvokeBlock v10, v12, v14, v16, v18, v20 # SendFallbackReason: InvokeBlock: not yet specialized + v22:BasicObject = InvokeBlock v10, v12, v14, v16, v18, v20 # SendFallbackReason: Too many arguments for LIR CheckInterrupts Return v22 "); @@ -4014,7 +4014,7 @@ mod hir_opt_tests { v31:Fixnum[4] = Const Value(4) v33:Fixnum[5] = Const Value(5) v35:Fixnum[6] = Const Value(6) - v37:BasicObject = InvokeBlock v25, v27, v29, v31, v33, v35 # SendFallbackReason: InvokeBlock: not yet specialized + v37:BasicObject = InvokeBlock v25, v27, v29, v31, v33, v35 # SendFallbackReason: Too many arguments for LIR CheckInterrupts PopInlineFrame Return v37