From 2b057859414d1ccfa4d88a898d27defc8c74dc1c Mon Sep 17 00:00:00 2001 From: Keenan Brock Date: Thu, 26 Sep 2024 16:34:39 -0400 Subject: [PATCH 01/24] Allow rb_thread_call_with_gvl() to work when thread already has GVL [Feature #20750] Co-authored-by: Benoit Daloze --- NEWS.md | 7 +++++++ gc.c | 6 +----- thread.c | 6 +++++- 3 files changed, 13 insertions(+), 6 deletions(-) diff --git a/NEWS.md b/NEWS.md index 53ed47cb8c3265..b44df19ca2b9b2 100644 --- a/NEWS.md +++ b/NEWS.md @@ -342,6 +342,12 @@ The following bundled gems are updated. `IO` objects share the same file descriptor, closing one does not affect the other. [[Feature #18455]] +* GVL + + * `rb_thread_call_with_gvl` now works with or without the GVL. + This allows gems to avoid checking `ruby_thread_has_gvl_p`. + Please still be diligent about the GVL. [[Feature #20750]] + * Set * A C API for `Set` has been added. The following methods are supported: @@ -402,6 +408,7 @@ A lot of work has gone into making Ractors more stable, performant, and usable. [Feature #19908]: https://bugs.ruby-lang.org/issues/19908 [Feature #20610]: https://bugs.ruby-lang.org/issues/20610 [Feature #20724]: https://bugs.ruby-lang.org/issues/20724 +[Feature #20750]: https://bugs.ruby-lang.org/issues/20750 [Feature #20884]: https://bugs.ruby-lang.org/issues/20884 [Feature #20925]: https://bugs.ruby-lang.org/issues/20925 [Feature #20971]: https://bugs.ruby-lang.org/issues/20971 diff --git a/gc.c b/gc.c index 7b4547e2ea0bca..18badba00581d8 100644 --- a/gc.c +++ b/gc.c @@ -5063,11 +5063,7 @@ gc_raise(VALUE exc, const char *fmt, ...) exc, fmt, &ap, }; - if (ruby_thread_has_gvl_p()) { - gc_vraise(&argv); - UNREACHABLE; - } - else if (ruby_native_thread_p()) { + if (ruby_native_thread_p()) { rb_thread_call_with_gvl(gc_vraise, &argv); UNREACHABLE; } diff --git a/thread.c b/thread.c index 5f592a42562adf..7c88c979029a10 100644 --- a/thread.c +++ b/thread.c @@ -2042,6 +2042,9 @@ rb_thread_io_blocking_region(struct rb_io *io, rb_blocking_function_t *func, voi * created as Ruby thread (created by Thread.new or so). In other * words, this function *DOES NOT* associate or convert a NON-Ruby * thread to a Ruby thread. + * + * NOTE: If this thread has already acquired the GVL, then the method call + * is performed without acquiring or releasing the GVL (from Ruby 4.0). */ void * rb_thread_call_with_gvl(void *(*func)(void *), void *data1) @@ -2065,7 +2068,8 @@ rb_thread_call_with_gvl(void *(*func)(void *), void *data1) prev_unblock = th->unblock; if (brb == 0) { - rb_bug("rb_thread_call_with_gvl: called by a thread which has GVL."); + /* the GVL is already acquired, call method directly */ + return (*func)(data1); } blocking_region_end(th, brb); From 834adc358ae967dfa52890a9abba551a070ab75e Mon Sep 17 00:00:00 2001 From: Steven Johnstone Date: Fri, 5 Dec 2025 16:07:33 +0000 Subject: [PATCH 02/24] [ruby/prism] Avoid out-of-bounds reads Fixes https://github.com/ruby/prism/pull/3784. https://github.com/ruby/prism/commit/3fe862534b --- prism/encoding.c | 84 +++++++++++++++++++++++++++++++++--------------- 1 file changed, 58 insertions(+), 26 deletions(-) diff --git a/prism/encoding.c b/prism/encoding.c index 424f149b8f833f..d7e5616840483f 100644 --- a/prism/encoding.c +++ b/prism/encoding.c @@ -2377,6 +2377,10 @@ pm_encoding_utf_8_char_width(const uint8_t *b, ptrdiff_t n) { */ size_t pm_encoding_utf_8_alpha_char(const uint8_t *b, ptrdiff_t n) { + if (n == 0) { + return 0; + } + if (*b < 0x80) { return (pm_encoding_unicode_table[*b] & PRISM_ENCODING_ALPHABETIC_BIT) ? 1 : 0; } @@ -2397,6 +2401,10 @@ pm_encoding_utf_8_alpha_char(const uint8_t *b, ptrdiff_t n) { */ size_t pm_encoding_utf_8_alnum_char(const uint8_t *b, ptrdiff_t n) { + if (n == 0) { + return 0; + } + if (*b < 0x80) { return (pm_encoding_unicode_table[*b] & (PRISM_ENCODING_ALPHANUMERIC_BIT)) ? 1 : 0; } @@ -2417,6 +2425,10 @@ pm_encoding_utf_8_alnum_char(const uint8_t *b, ptrdiff_t n) { */ bool pm_encoding_utf_8_isupper_char(const uint8_t *b, ptrdiff_t n) { + if (n == 0) { + return 0; + } + if (*b < 0x80) { return (pm_encoding_unicode_table[*b] & PRISM_ENCODING_UPPERCASE_BIT) ? true : false; } @@ -2435,7 +2447,8 @@ pm_encoding_utf_8_isupper_char(const uint8_t *b, ptrdiff_t n) { static pm_unicode_codepoint_t pm_cesu_8_codepoint(const uint8_t *b, ptrdiff_t n, size_t *width) { - if (b[0] < 0x80) { + + if ((n > 0) && (b[0] < 0x80)) { *width = 1; return (pm_unicode_codepoint_t) b[0]; } @@ -2474,6 +2487,10 @@ pm_cesu_8_codepoint(const uint8_t *b, ptrdiff_t n, size_t *width) { static size_t pm_encoding_cesu_8_char_width(const uint8_t *b, ptrdiff_t n) { + if (n == 0) { + return 0; + } + size_t width; pm_cesu_8_codepoint(b, n, &width); return width; @@ -2481,6 +2498,10 @@ pm_encoding_cesu_8_char_width(const uint8_t *b, ptrdiff_t n) { static size_t pm_encoding_cesu_8_alpha_char(const uint8_t *b, ptrdiff_t n) { + if (n == 0) { + return 0; + } + if (*b < 0x80) { return (pm_encoding_unicode_table[*b] & PRISM_ENCODING_ALPHABETIC_BIT) ? 1 : 0; } @@ -2497,6 +2518,10 @@ pm_encoding_cesu_8_alpha_char(const uint8_t *b, ptrdiff_t n) { static size_t pm_encoding_cesu_8_alnum_char(const uint8_t *b, ptrdiff_t n) { + if (n == 0) { + return 0; + } + if (*b < 0x80) { return (pm_encoding_unicode_table[*b] & (PRISM_ENCODING_ALPHANUMERIC_BIT)) ? 1 : 0; } @@ -2513,6 +2538,10 @@ pm_encoding_cesu_8_alnum_char(const uint8_t *b, ptrdiff_t n) { static bool pm_encoding_cesu_8_isupper_char(const uint8_t *b, ptrdiff_t n) { + if (n == 0) { + return 0; + } + if (*b < 0x80) { return (pm_encoding_unicode_table[*b] & PRISM_ENCODING_UPPERCASE_BIT) ? true : false; } @@ -3928,14 +3957,14 @@ static const uint8_t pm_encoding_windows_874_table[256] = { }; #define PRISM_ENCODING_TABLE(name) \ - static size_t pm_encoding_ ##name ## _alpha_char(const uint8_t *b, PRISM_ATTRIBUTE_UNUSED ptrdiff_t n) { \ - return (pm_encoding_ ##name ## _table[*b] & PRISM_ENCODING_ALPHABETIC_BIT); \ + static size_t pm_encoding_ ##name ## _alpha_char(const uint8_t *b, ptrdiff_t n) { \ + return ((n > 0) && (pm_encoding_ ##name ## _table[*b] & PRISM_ENCODING_ALPHABETIC_BIT)); \ } \ - static size_t pm_encoding_ ##name ## _alnum_char(const uint8_t *b, PRISM_ATTRIBUTE_UNUSED ptrdiff_t n) { \ - return (pm_encoding_ ##name ## _table[*b] & PRISM_ENCODING_ALPHANUMERIC_BIT) ? 1 : 0; \ + static size_t pm_encoding_ ##name ## _alnum_char(const uint8_t *b, ptrdiff_t n) { \ + return ((n > 0) && (pm_encoding_ ##name ## _table[*b] & PRISM_ENCODING_ALPHANUMERIC_BIT)) ? 1 : 0; \ } \ - static bool pm_encoding_ ##name ## _isupper_char(const uint8_t *b, PRISM_ATTRIBUTE_UNUSED ptrdiff_t n) { \ - return (pm_encoding_ ##name ## _table[*b] & PRISM_ENCODING_UPPERCASE_BIT); \ + static bool pm_encoding_ ##name ## _isupper_char(const uint8_t *b, ptrdiff_t n) { \ + return ((n > 0) && (pm_encoding_ ##name ## _table[*b] & PRISM_ENCODING_UPPERCASE_BIT)); \ } PRISM_ENCODING_TABLE(cp850) @@ -4004,8 +4033,8 @@ PRISM_ENCODING_TABLE(windows_874) * means that if the top bit is not set, the character is 1 byte long. */ static size_t -pm_encoding_ascii_char_width(const uint8_t *b, PRISM_ATTRIBUTE_UNUSED ptrdiff_t n) { - return *b < 0x80 ? 1 : 0; +pm_encoding_ascii_char_width(const uint8_t *b, ptrdiff_t n) { + return ((n > 0) && (*b < 0x80)) ? 1 : 0; } /** @@ -4013,8 +4042,8 @@ pm_encoding_ascii_char_width(const uint8_t *b, PRISM_ATTRIBUTE_UNUSED ptrdiff_t * alphabetical character. */ static size_t -pm_encoding_ascii_alpha_char(const uint8_t *b, PRISM_ATTRIBUTE_UNUSED ptrdiff_t n) { - return (pm_encoding_ascii_table[*b] & PRISM_ENCODING_ALPHABETIC_BIT); +pm_encoding_ascii_alpha_char(const uint8_t *b, ptrdiff_t n) { + return (n > 0) ? (pm_encoding_ascii_table[*b] & PRISM_ENCODING_ALPHABETIC_BIT) : 0; } /** @@ -4024,7 +4053,7 @@ pm_encoding_ascii_alpha_char(const uint8_t *b, PRISM_ATTRIBUTE_UNUSED ptrdiff_t */ static size_t pm_encoding_ascii_alpha_char_7bit(const uint8_t *b, ptrdiff_t n) { - return (*b < 0x80) ? pm_encoding_ascii_alpha_char(b, n) : 0; + return ((n > 0) && (*b < 0x80)) ? pm_encoding_ascii_alpha_char(b, n) : 0; } /** @@ -4032,8 +4061,8 @@ pm_encoding_ascii_alpha_char_7bit(const uint8_t *b, ptrdiff_t n) { * alphanumeric character. */ static size_t -pm_encoding_ascii_alnum_char(const uint8_t *b, PRISM_ATTRIBUTE_UNUSED ptrdiff_t n) { - return (pm_encoding_ascii_table[*b] & PRISM_ENCODING_ALPHANUMERIC_BIT) ? 1 : 0; +pm_encoding_ascii_alnum_char(const uint8_t *b, ptrdiff_t n) { + return ((n > 0) && (pm_encoding_ascii_table[*b] & PRISM_ENCODING_ALPHANUMERIC_BIT)) ? 1 : 0; } /** @@ -4043,7 +4072,7 @@ pm_encoding_ascii_alnum_char(const uint8_t *b, PRISM_ATTRIBUTE_UNUSED ptrdiff_t */ static size_t pm_encoding_ascii_alnum_char_7bit(const uint8_t *b, ptrdiff_t n) { - return (*b < 0x80) ? pm_encoding_ascii_alnum_char(b, n) : 0; + return ((n > 0) && (*b < 0x80)) ? pm_encoding_ascii_alnum_char(b, n) : 0; } /** @@ -4051,8 +4080,8 @@ pm_encoding_ascii_alnum_char_7bit(const uint8_t *b, ptrdiff_t n) { * character. */ static bool -pm_encoding_ascii_isupper_char(const uint8_t *b, PRISM_ATTRIBUTE_UNUSED ptrdiff_t n) { - return (pm_encoding_ascii_table[*b] & PRISM_ENCODING_UPPERCASE_BIT); +pm_encoding_ascii_isupper_char(const uint8_t *b, ptrdiff_t n) { + return (n > 0) && (pm_encoding_ascii_table[*b] & PRISM_ENCODING_UPPERCASE_BIT); } /** @@ -4071,7 +4100,7 @@ pm_encoding_single_char_width(PRISM_ATTRIBUTE_UNUSED const uint8_t *b, PRISM_ATT static size_t pm_encoding_euc_jp_char_width(const uint8_t *b, ptrdiff_t n) { // These are the single byte characters. - if (*b < 0x80) { + if ((n > 0) && (*b < 0x80)) { return 1; } @@ -4115,6 +4144,9 @@ pm_encoding_euc_jp_isupper_char(const uint8_t *b, ptrdiff_t n) { */ static size_t pm_encoding_shift_jis_char_width(const uint8_t *b, ptrdiff_t n) { + if (n == 0) { + return 0; + } // These are the single byte characters. if (b[0] < 0x80 || (b[0] >= 0xA1 && b[0] <= 0xDF)) { return 1; @@ -4178,7 +4210,7 @@ pm_encoding_shift_jis_isupper_char(const uint8_t *b, ptrdiff_t n) { */ static bool pm_encoding_ascii_isupper_char_7bit(const uint8_t *b, ptrdiff_t n) { - return (*b < 0x80) && pm_encoding_ascii_isupper_char(b, n); + return (n > 0) && (*b < 0x80) && pm_encoding_ascii_isupper_char(b, n); } /** @@ -4188,7 +4220,7 @@ pm_encoding_ascii_isupper_char_7bit(const uint8_t *b, ptrdiff_t n) { static size_t pm_encoding_big5_char_width(const uint8_t *b, ptrdiff_t n) { // These are the single byte characters. - if (*b < 0x80) { + if ((n > 0) && (*b < 0x80)) { return 1; } @@ -4207,7 +4239,7 @@ pm_encoding_big5_char_width(const uint8_t *b, ptrdiff_t n) { static size_t pm_encoding_cp949_char_width(const uint8_t *b, ptrdiff_t n) { // These are the single byte characters - if (*b <= 0x80) { + if ((n > 0) && (*b <= 0x80)) { return 1; } @@ -4226,7 +4258,7 @@ pm_encoding_cp949_char_width(const uint8_t *b, ptrdiff_t n) { static size_t pm_encoding_emacs_mule_char_width(const uint8_t *b, ptrdiff_t n) { // These are the 1 byte characters. - if (*b < 0x80) { + if ((n > 0) && (*b < 0x80)) { return 1; } @@ -4269,7 +4301,7 @@ pm_encoding_emacs_mule_char_width(const uint8_t *b, ptrdiff_t n) { static size_t pm_encoding_euc_kr_char_width(const uint8_t *b, ptrdiff_t n) { // These are the single byte characters. - if (*b < 0x80) { + if ((n > 0) && (*b < 0x80)) { return 1; } @@ -4288,7 +4320,7 @@ pm_encoding_euc_kr_char_width(const uint8_t *b, ptrdiff_t n) { static size_t pm_encoding_euc_tw_char_width(const uint8_t *b, ptrdiff_t n) { // These are the single byte characters. - if (*b < 0x80) { + if ((n > 0) && (*b < 0x80)) { return 1; } @@ -4312,7 +4344,7 @@ pm_encoding_euc_tw_char_width(const uint8_t *b, ptrdiff_t n) { static size_t pm_encoding_gb18030_char_width(const uint8_t *b, ptrdiff_t n) { // These are the 1 byte characters. - if (*b < 0x80) { + if ((n > 0) && (*b < 0x80)) { return 1; } @@ -4336,7 +4368,7 @@ pm_encoding_gb18030_char_width(const uint8_t *b, ptrdiff_t n) { static size_t pm_encoding_gbk_char_width(const uint8_t *b, ptrdiff_t n) { // These are the single byte characters. - if (*b <= 0x80) { + if ((n > 0) && (*b <= 0x80)) { return 1; } From be12e19856c95ac722efa944af74122a9b2a6bef Mon Sep 17 00:00:00 2001 From: Steven Johnstone Date: Fri, 5 Dec 2025 17:44:00 +0000 Subject: [PATCH 03/24] [ruby/prism] Avoid undefined int overflow behaviour Fixes https://github.com/ruby/prism/pull/3786. https://github.com/ruby/prism/commit/b72b664675 --- prism/templates/src/serialize.c.erb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/prism/templates/src/serialize.c.erb b/prism/templates/src/serialize.c.erb index 3e15a11039ef94..0f0aace445a680 100644 --- a/prism/templates/src/serialize.c.erb +++ b/prism/templates/src/serialize.c.erb @@ -315,7 +315,7 @@ pm_serialize_content(pm_parser_t *parser, pm_node_t *node, pm_buffer_t *buffer) // buffer offset. We will add a leading 1 to indicate that this // is a buffer offset. uint32_t content_offset = pm_sizet_to_u32(buffer->length); - uint32_t owned_mask = (uint32_t) (1 << 31); + uint32_t owned_mask = 1U << 31; assert(content_offset < owned_mask); content_offset |= owned_mask; From 786f67393875b0a5089da73504ac57179e8ef829 Mon Sep 17 00:00:00 2001 From: Kevin Newton Date: Fri, 5 Dec 2025 15:17:09 -0500 Subject: [PATCH 04/24] [ruby/prism] Correct constant pool bucket type logic When replacing an owned constant by a different type (constant or shared) replace with the correct type instead of defaulting to shared. https://github.com/ruby/prism/commit/fbe9b131a1 --- prism/util/pm_constant_pool.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/prism/util/pm_constant_pool.c b/prism/util/pm_constant_pool.c index 38ea01a2289d65..922ce6a18cfaff 100644 --- a/prism/util/pm_constant_pool.c +++ b/prism/util/pm_constant_pool.c @@ -264,7 +264,7 @@ pm_constant_pool_insert(pm_constant_pool_t *pool, const uint8_t *start, size_t l // constant and replace it with the shared constant. xfree((void *) constant->start); constant->start = start; - bucket->type = (unsigned int) (PM_CONSTANT_POOL_BUCKET_DEFAULT & 0x3); + bucket->type = (unsigned int) (type & 0x3); } return bucket->id; From ee7923288fd4915199954f615980e516750cb8bb Mon Sep 17 00:00:00 2001 From: Alan Wu Date: Tue, 2 Dec 2025 21:50:06 -0500 Subject: [PATCH 05/24] ZJIT: Skip GC.auto_compact test when unsupported --- test/ruby/test_zjit.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/test/ruby/test_zjit.rb b/test/ruby/test_zjit.rb index 00550bbe2058e2..45ee42e6a29162 100644 --- a/test/ruby/test_zjit.rb +++ b/test/ruby/test_zjit.rb @@ -2421,6 +2421,7 @@ def test_require_rubygems end def test_require_rubygems_with_auto_compact + omit("GC.auto_compact= support is required for this test") unless GC.respond_to?(:auto_compact=) assert_runs 'true', %q{ GC.auto_compact = true require 'rubygems' From 3269ae1b0d1aaa78d12b1527a2f6b095e148c5d3 Mon Sep 17 00:00:00 2001 From: Alan Wu Date: Tue, 2 Dec 2025 22:11:20 -0500 Subject: [PATCH 06/24] ZJIT: Fix -Wpedantic warning in C99 mode when built with YJIT > insns.def:857:5: error: assigning to 'rb_zjit_func_t' (aka 'unsigned > long (*)(struct rb_execution_context_struct *, struct > rb_control_frame_struct *, unsigned long (*)(struct > rb_execution_context_struct *, struct rb_control_frame_struct *))') from > 'void *' converts between void pointer and function pointer > [-Werror,-Wpedantic] --- vm_exec.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vm_exec.h b/vm_exec.h index 033a48f1e7683c..641ace4eaf29b9 100644 --- a/vm_exec.h +++ b/vm_exec.h @@ -185,7 +185,7 @@ default: \ if (ec->tag->state) THROW_EXCEPTION(val); \ } \ } \ - else if ((zjit_entry = rb_zjit_entry)) { \ + else if ((zjit_entry = (rb_zjit_func_t)rb_zjit_entry)) { \ rb_jit_func_t func = zjit_compile(ec); \ if (func) { \ val = zjit_entry(ec, ec->cfp, func); \ From 7ecd369a87d65879f98d95d726772238c1dabc16 Mon Sep 17 00:00:00 2001 From: Alan Wu Date: Wed, 3 Dec 2025 14:31:48 -0500 Subject: [PATCH 07/24] ZJIT: Account for when YJIT is on by default in test_zjit_enable --- test/ruby/test_zjit.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/test/ruby/test_zjit.rb b/test/ruby/test_zjit.rb index 45ee42e6a29162..03d2461fa0a0af 100644 --- a/test/ruby/test_zjit.rb +++ b/test/ruby/test_zjit.rb @@ -60,7 +60,9 @@ def test_enable_through_env end def test_zjit_enable - assert_separately([], <<~'RUBY') + # --disable-all is important in case the build/environment has YJIT enabled by + # default through e.g. -DYJIT_FORCE_ENABLE. Can't enable ZJIT when YJIT is on. + assert_separately(["--disable-all"], <<~'RUBY') refute_predicate RubyVM::ZJIT, :enabled? refute_predicate RubyVM::ZJIT, :stats_enabled? refute_includes RUBY_DESCRIPTION, "+ZJIT" From 02ca507aa3fe45640ace494e5440d9e8bfd5a517 Mon Sep 17 00:00:00 2001 From: Alan Wu Date: Wed, 3 Dec 2025 15:05:01 -0500 Subject: [PATCH 08/24] JITs: rb_iseq_opcode_at_pc(): Accommodate switch-case interpreter --- jit.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/jit.c b/jit.c index a886b66278c2aa..ae592b2205c0be 100644 --- a/jit.c +++ b/jit.c @@ -52,8 +52,11 @@ rb_iseq_pc_at_idx(const rb_iseq_t *iseq, uint32_t insn_idx) int rb_iseq_opcode_at_pc(const rb_iseq_t *iseq, const VALUE *pc) { - // YJIT should only use iseqs after AST to bytecode compilation - RUBY_ASSERT_ALWAYS(FL_TEST_RAW((VALUE)iseq, ISEQ_TRANSLATED)); + // YJIT should only use iseqs after AST to bytecode compilation. + // (Certain non-default interpreter configurations never set ISEQ_TRANSLATED) + if (OPT_DIRECT_THREADED_CODE || OPT_CALL_THREADED_CODE) { + RUBY_ASSERT_ALWAYS(FL_TEST_RAW((VALUE)iseq, ISEQ_TRANSLATED)); + } const VALUE at_pc = *pc; return rb_vm_insn_addr2opcode((const void *)at_pc); From f01fd2bde2c79dd4f3e23154c953baca623b6460 Mon Sep 17 00:00:00 2001 From: Alan Wu Date: Wed, 3 Dec 2025 15:41:21 -0500 Subject: [PATCH 09/24] JITs: Update bindings to include interpreter zjit_ opcodes Mostly YJIT. ZJIT already has the right bindings and this just tweaks the CI configuration. --- .github/workflows/yjit-ubuntu.yml | 3 ++- .github/workflows/zjit-ubuntu.yml | 3 ++- yjit/src/cruby_bindings.inc.rs | 32 ++++++++++++++++++++++++++++++- 3 files changed, 35 insertions(+), 3 deletions(-) diff --git a/.github/workflows/yjit-ubuntu.yml b/.github/workflows/yjit-ubuntu.yml index 00214709b93e65..7dce69cda4ea78 100644 --- a/.github/workflows/yjit-ubuntu.yml +++ b/.github/workflows/yjit-ubuntu.yml @@ -81,7 +81,8 @@ jobs: include: - test_task: 'yjit-bindgen' hint: 'To fix: use patch in logs' - configure: '--with-gcc=clang-14 --enable-yjit=dev' + # Build with YJIT+ZJIT for output that works in the most number of configurations + configure: '--with-gcc=clang-14 --enable-yjit=dev --enable-zjit' libclang_path: '/usr/lib/llvm-14/lib/libclang.so.1' - test_task: 'check' diff --git a/.github/workflows/zjit-ubuntu.yml b/.github/workflows/zjit-ubuntu.yml index 5d281eab0b9947..37a9000d704c5a 100644 --- a/.github/workflows/zjit-ubuntu.yml +++ b/.github/workflows/zjit-ubuntu.yml @@ -73,7 +73,8 @@ jobs: - test_task: 'zjit-bindgen' hint: 'To fix: use patch in logs' - configure: '--enable-zjit=dev --with-gcc=clang-16' + # Build with YJIT+ZJIT for output that works in the most number of configurations + configure: '--enable-zjit=dev --enable-yjit --with-gcc=clang-16' clang_path: '/usr/bin/clang-16' runs-on: 'ubuntu-24.04' # for clang-16 diff --git a/yjit/src/cruby_bindings.inc.rs b/yjit/src/cruby_bindings.inc.rs index b9a8197184a21a..0bd2cefc08acf2 100644 --- a/yjit/src/cruby_bindings.inc.rs +++ b/yjit/src/cruby_bindings.inc.rs @@ -919,7 +919,37 @@ pub const YARVINSN_trace_setlocal_WC_0: ruby_vminsn_type = 214; pub const YARVINSN_trace_setlocal_WC_1: ruby_vminsn_type = 215; pub const YARVINSN_trace_putobject_INT2FIX_0_: ruby_vminsn_type = 216; pub const YARVINSN_trace_putobject_INT2FIX_1_: ruby_vminsn_type = 217; -pub const VM_INSTRUCTION_SIZE: ruby_vminsn_type = 218; +pub const YARVINSN_zjit_getinstancevariable: ruby_vminsn_type = 218; +pub const YARVINSN_zjit_setinstancevariable: ruby_vminsn_type = 219; +pub const YARVINSN_zjit_definedivar: ruby_vminsn_type = 220; +pub const YARVINSN_zjit_send: ruby_vminsn_type = 221; +pub const YARVINSN_zjit_opt_send_without_block: ruby_vminsn_type = 222; +pub const YARVINSN_zjit_objtostring: ruby_vminsn_type = 223; +pub const YARVINSN_zjit_opt_nil_p: ruby_vminsn_type = 224; +pub const YARVINSN_zjit_invokeblock: ruby_vminsn_type = 225; +pub const YARVINSN_zjit_opt_plus: ruby_vminsn_type = 226; +pub const YARVINSN_zjit_opt_minus: ruby_vminsn_type = 227; +pub const YARVINSN_zjit_opt_mult: ruby_vminsn_type = 228; +pub const YARVINSN_zjit_opt_div: ruby_vminsn_type = 229; +pub const YARVINSN_zjit_opt_mod: ruby_vminsn_type = 230; +pub const YARVINSN_zjit_opt_eq: ruby_vminsn_type = 231; +pub const YARVINSN_zjit_opt_neq: ruby_vminsn_type = 232; +pub const YARVINSN_zjit_opt_lt: ruby_vminsn_type = 233; +pub const YARVINSN_zjit_opt_le: ruby_vminsn_type = 234; +pub const YARVINSN_zjit_opt_gt: ruby_vminsn_type = 235; +pub const YARVINSN_zjit_opt_ge: ruby_vminsn_type = 236; +pub const YARVINSN_zjit_opt_ltlt: ruby_vminsn_type = 237; +pub const YARVINSN_zjit_opt_and: ruby_vminsn_type = 238; +pub const YARVINSN_zjit_opt_or: ruby_vminsn_type = 239; +pub const YARVINSN_zjit_opt_aref: ruby_vminsn_type = 240; +pub const YARVINSN_zjit_opt_aset: ruby_vminsn_type = 241; +pub const YARVINSN_zjit_opt_length: ruby_vminsn_type = 242; +pub const YARVINSN_zjit_opt_size: ruby_vminsn_type = 243; +pub const YARVINSN_zjit_opt_empty_p: ruby_vminsn_type = 244; +pub const YARVINSN_zjit_opt_succ: ruby_vminsn_type = 245; +pub const YARVINSN_zjit_opt_not: ruby_vminsn_type = 246; +pub const YARVINSN_zjit_opt_regexpmatch2: ruby_vminsn_type = 247; +pub const VM_INSTRUCTION_SIZE: ruby_vminsn_type = 248; pub type ruby_vminsn_type = u32; pub type rb_iseq_callback = ::std::option::Option< unsafe extern "C" fn(arg1: *const rb_iseq_t, arg2: *mut ::std::os::raw::c_void), From 8132b3d1d8abbe38810a1e268c59b6d49e46d9a1 Mon Sep 17 00:00:00 2001 From: Alan Wu Date: Wed, 3 Dec 2025 21:15:04 -0500 Subject: [PATCH 10/24] YJIT: Fix including stats for ZJIT instructions when ZJIT not in build --- yjit.c | 9 +++++++++ yjit/bindgen/src/main.rs | 1 + yjit/src/cruby_bindings.inc.rs | 1 + yjit/src/stats.rs | 7 +++++-- 4 files changed, 16 insertions(+), 2 deletions(-) diff --git a/yjit.c b/yjit.c index 4b78cfbae25a25..16debf6eca5555 100644 --- a/yjit.c +++ b/yjit.c @@ -521,6 +521,15 @@ rb_yjit_set_exception_return(rb_control_frame_t *cfp, void *leave_exit, void *le } } +// VM_INSTRUCTION_SIZE changes depending on if ZJIT is in the build. Since +// bindgen can only grab one version of the constant and copy that to rust, +// we make that the upper bound and this the accurate value. +uint32_t +rb_vm_instruction_size(void) +{ + return VM_INSTRUCTION_SIZE; +} + // Primitives used by yjit.rb VALUE rb_yjit_stats_enabled_p(rb_execution_context_t *ec, VALUE self); VALUE rb_yjit_print_stats_p(rb_execution_context_t *ec, VALUE self); diff --git a/yjit/bindgen/src/main.rs b/yjit/bindgen/src/main.rs index 9c28177a6054b2..8d11b4216ef0b0 100644 --- a/yjit/bindgen/src/main.rs +++ b/yjit/bindgen/src/main.rs @@ -304,6 +304,7 @@ fn main() { .allowlist_function("rb_mod_name") .allowlist_function("rb_const_get") .allowlist_var("rb_vm_insn_count") + .allowlist_function("rb_vm_instruction_size") .allowlist_function("rb_get_alloc_func") .allowlist_function("rb_class_allocate_instance") .allowlist_function("rb_obj_equal") diff --git a/yjit/src/cruby_bindings.inc.rs b/yjit/src/cruby_bindings.inc.rs index 0bd2cefc08acf2..b9e5fb3ab12843 100644 --- a/yjit/src/cruby_bindings.inc.rs +++ b/yjit/src/cruby_bindings.inc.rs @@ -1204,6 +1204,7 @@ extern "C" { leave_exit: *mut ::std::os::raw::c_void, leave_exception: *mut ::std::os::raw::c_void, ); + pub fn rb_vm_instruction_size() -> u32; pub fn rb_iseq_encoded_size(iseq: *const rb_iseq_t) -> ::std::os::raw::c_uint; pub fn rb_iseq_pc_at_idx(iseq: *const rb_iseq_t, insn_idx: u32) -> *mut VALUE; pub fn rb_iseq_opcode_at_pc(iseq: *const rb_iseq_t, pc: *const VALUE) -> ::std::os::raw::c_int; diff --git a/yjit/src/stats.rs b/yjit/src/stats.rs index e8ce7b8b353d63..4f23d97bce7360 100644 --- a/yjit/src/stats.rs +++ b/yjit/src/stats.rs @@ -90,7 +90,9 @@ pub extern "C" fn incr_iseq_counter(idx: usize) { iseq_call_count[idx] += 1; } -// YJIT exit counts for each instruction type +/// YJIT exit counts for each instruction type. +/// Note that `VM_INSTRUCTION_SIZE` is an upper bound and the actual number +/// of VM opcodes may be different in the build. See [`rb_vm_instruction_size()`] const VM_INSTRUCTION_SIZE_USIZE: usize = VM_INSTRUCTION_SIZE as usize; static mut EXIT_OP_COUNT: [u64; VM_INSTRUCTION_SIZE_USIZE] = [0; VM_INSTRUCTION_SIZE_USIZE]; @@ -804,7 +806,8 @@ fn rb_yjit_gen_stats_dict(key: VALUE) -> VALUE { // For each entry in exit_op_count, add a stats entry with key "exit_INSTRUCTION_NAME" // and the value is the count of side exits for that instruction. - for op_idx in 0..VM_INSTRUCTION_SIZE_USIZE { + use crate::utils::IntoUsize; + for op_idx in 0..rb_vm_instruction_size().as_usize() { let op_name = insn_name(op_idx); let key_string = "exit_".to_owned() + &op_name; let count = EXIT_OP_COUNT[op_idx]; From 109ddd291ebc4f07f786e7b4ed277b20e3faaa8a Mon Sep 17 00:00:00 2001 From: Alan Wu Date: Wed, 3 Dec 2025 16:03:23 -0500 Subject: [PATCH 11/24] ZJIT: Avoid binding to `rb_iseq_constant_body` Its definition changes depending on e.g. whether there is YJIT in the build. --- zjit.c | 4 ++++ zjit/bindgen/src/main.rs | 2 ++ zjit/src/cruby.rs | 13 +++++++++++- zjit/src/cruby_bindings.inc.rs | 36 ++-------------------------------- 4 files changed, 20 insertions(+), 35 deletions(-) diff --git a/zjit.c b/zjit.c index b8a89aad1a8498..d62c5c58c6334c 100644 --- a/zjit.c +++ b/zjit.c @@ -31,6 +31,10 @@ #include +enum zjit_struct_offsets { + ISEQ_BODY_OFFSET_PARAM = offsetof(struct rb_iseq_constant_body, param) +}; + #define PTR2NUM(x) (rb_int2inum((intptr_t)(void *)(x))) // For a given raw_sample (frame), set the hash with the caller's diff --git a/zjit/bindgen/src/main.rs b/zjit/bindgen/src/main.rs index e07953ffd5df08..30e85149744e22 100644 --- a/zjit/bindgen/src/main.rs +++ b/zjit/bindgen/src/main.rs @@ -301,6 +301,7 @@ fn main() { .allowlist_function("rb_zjit_defined_ivar") .allowlist_function("rb_zjit_insn_leaf") .allowlist_type("jit_bindgen_constants") + .allowlist_type("zjit_struct_offsets") .allowlist_function("rb_assert_holding_vm_lock") .allowlist_function("rb_jit_shape_too_complex_p") .allowlist_function("rb_jit_multi_ractor_p") @@ -428,6 +429,7 @@ fn main() { // We define these manually, don't import them .blocklist_type("VALUE") .blocklist_type("ID") + .blocklist_type("rb_iseq_constant_body") // Avoid binding to stuff we don't use .blocklist_item("rb_thread_struct.*") diff --git a/zjit/src/cruby.rs b/zjit/src/cruby.rs index b255c28e52cd17..e653602874df77 100644 --- a/zjit/src/cruby.rs +++ b/zjit/src/cruby.rs @@ -231,6 +231,16 @@ pub fn insn_len(opcode: usize) -> u32 { } } +/// We avoid using bindgen for `rb_iseq_constant_body` since its definition changes depending +/// on build configuration while we need one bindgen file that works for all configurations. +/// Use an opaque type for it instead. +/// See: +#[repr(C)] +pub struct rb_iseq_constant_body { + _data: [u8; 0], + _marker: core::marker::PhantomData<(*mut u8, core::marker::PhantomPinned)>, +} + /// An object handle similar to VALUE in the C code. Our methods assume /// that this is a handle. Sometimes the C code briefly uses VALUE as /// an unsigned integer type and don't necessarily store valid handles but @@ -683,7 +693,8 @@ pub trait IseqAccess { impl IseqAccess for IseqPtr { /// Get a description of the ISEQ's signature. Analogous to `ISEQ_BODY(iseq)->param` in C. unsafe fn params<'a>(self) -> &'a IseqParameters { - unsafe { &(*(*self).body).param } + use crate::cast::IntoUsize; + unsafe { &*((*self).body.byte_add(ISEQ_BODY_OFFSET_PARAM.to_usize()) as *const IseqParameters) } } } diff --git a/zjit/src/cruby_bindings.inc.rs b/zjit/src/cruby_bindings.inc.rs index a80f3d83c5f414..aed35c3c636846 100644 --- a/zjit/src/cruby_bindings.inc.rs +++ b/zjit/src/cruby_bindings.inc.rs @@ -595,40 +595,6 @@ pub type rb_jit_func_t = ::std::option::Option< ) -> VALUE, >; #[repr(C)] -pub struct rb_iseq_constant_body { - pub type_: rb_iseq_type, - pub iseq_size: ::std::os::raw::c_uint, - pub iseq_encoded: *mut VALUE, - pub param: rb_iseq_constant_body_rb_iseq_parameters, - pub location: rb_iseq_location_t, - pub insns_info: rb_iseq_constant_body_iseq_insn_info, - pub local_table: *const ID, - pub lvar_states: *mut rb_iseq_constant_body_lvar_state, - pub catch_table: *mut iseq_catch_table, - pub parent_iseq: *const rb_iseq_struct, - pub local_iseq: *mut rb_iseq_struct, - pub is_entries: *mut iseq_inline_storage_entry, - pub call_data: *mut rb_call_data, - pub variable: rb_iseq_constant_body__bindgen_ty_1, - pub local_table_size: ::std::os::raw::c_uint, - pub ic_size: ::std::os::raw::c_uint, - pub ise_size: ::std::os::raw::c_uint, - pub ivc_size: ::std::os::raw::c_uint, - pub icvarc_size: ::std::os::raw::c_uint, - pub ci_size: ::std::os::raw::c_uint, - pub stack_max: ::std::os::raw::c_uint, - pub builtin_attrs: ::std::os::raw::c_uint, - pub prism: bool, - pub mark_bits: rb_iseq_constant_body__bindgen_ty_2, - pub outer_variables: *mut rb_id_table, - pub mandatory_only_iseq: *const rb_iseq_t, - pub jit_entry: rb_jit_func_t, - pub jit_entry_calls: ::std::os::raw::c_ulong, - pub jit_exception: rb_jit_func_t, - pub jit_exception_calls: ::std::os::raw::c_ulong, - pub zjit_payload: *mut ::std::os::raw::c_void, -} -#[repr(C)] #[derive(Debug, Copy, Clone)] pub struct rb_iseq_constant_body_rb_iseq_parameters { pub flags: rb_iseq_constant_body_rb_iseq_parameters__bindgen_ty_1, @@ -1866,6 +1832,8 @@ pub const DEFINED_REF: defined_type = 15; pub const DEFINED_FUNC: defined_type = 16; pub const DEFINED_CONST_FROM: defined_type = 17; pub type defined_type = u32; +pub const ISEQ_BODY_OFFSET_PARAM: zjit_struct_offsets = 16; +pub type zjit_struct_offsets = u32; pub const ROBJECT_OFFSET_AS_HEAP_FIELDS: jit_bindgen_constants = 16; pub const ROBJECT_OFFSET_AS_ARY: jit_bindgen_constants = 16; pub const RUBY_OFFSET_RSTRING_LEN: jit_bindgen_constants = 16; From fb72ff7be0b927cdad518da4eca041c191a91404 Mon Sep 17 00:00:00 2001 From: Alan Wu Date: Wed, 3 Dec 2025 16:14:40 -0500 Subject: [PATCH 12/24] CI: Avoid building ZJIT when LLVM is too old --- .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 97a698613a2f10..5e54d39e9fa6b9 100644 --- a/.github/workflows/compilers.yml +++ b/.github/workflows/compilers.yml @@ -132,11 +132,11 @@ jobs: - { uses: './.github/actions/compilers', name: 'clang 12', with: { tag: 'clang-12' }, timeout-minutes: 5 } - { uses: './.github/actions/compilers', name: 'clang 11', with: { tag: 'clang-11' }, timeout-minutes: 5 } - { uses: './.github/actions/compilers', name: 'clang 10', with: { tag: 'clang-10' }, timeout-minutes: 5 } - # llvm-objcopy<=9 doesn't have --wildcard. It compiles, but leaves Rust symbols in libyjit.o. - - { uses: './.github/actions/compilers', name: 'clang 9', with: { tag: 'clang-9', append_configure: '--disable-yjit' }, timeout-minutes: 5 } - - { uses: './.github/actions/compilers', name: 'clang 8', with: { tag: 'clang-8', append_configure: '--disable-yjit' }, timeout-minutes: 5 } - - { uses: './.github/actions/compilers', name: 'clang 7', with: { tag: 'clang-7', append_configure: '--disable-yjit' }, timeout-minutes: 5 } - - { uses: './.github/actions/compilers', name: 'clang 6', with: { tag: 'clang-6.0', append_configure: '--disable-yjit' }, timeout-minutes: 5 } + # llvm-objcopy<=9 doesn't have --wildcard. It compiles, but leaves Rust symbols in libyjit.o and fail `make test-leaked-globals`. + - { uses: './.github/actions/compilers', name: 'clang 9', with: { tag: 'clang-9', append_configure: '--disable-yjit --disable-zjit' }, timeout-minutes: 5 } + - { uses: './.github/actions/compilers', name: 'clang 8', with: { tag: 'clang-8', append_configure: '--disable-yjit --disable-zjit' }, timeout-minutes: 5 } + - { uses: './.github/actions/compilers', name: 'clang 7', with: { tag: 'clang-7', append_configure: '--disable-yjit --disable-zjit' }, timeout-minutes: 5 } + - { uses: './.github/actions/compilers', name: 'clang 6', with: { tag: 'clang-6.0', append_configure: '--disable-yjit --disable-zjit' }, timeout-minutes: 5 } compile5: name: 'omnibus compilations, #5' From 2bc9b5a85454d2536d18be32e0302842bde18a3f Mon Sep 17 00:00:00 2001 From: Alan Wu Date: Wed, 3 Dec 2025 16:55:26 -0500 Subject: [PATCH 13/24] tool/update-deps: Skip ZJIT and YJIT+ZJIT build objects --- tool/update-deps | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tool/update-deps b/tool/update-deps index c927d2483e9a7a..2d4a5674be72a7 100755 --- a/tool/update-deps +++ b/tool/update-deps @@ -326,6 +326,8 @@ def read_make_deps(cwd) deps.delete_if {|dep| /\.time\z/ =~ dep} # skip timestamp next if /\.o\z/ !~ target.to_s next if /libyjit.o\z/ =~ target.to_s # skip YJIT Rust object (no corresponding C source) + next if /libzjit.o\z/ =~ target.to_s # skip ZJIT Rust object (no corresponding C source) + next if /target\/release\/libruby.o\z/ =~ target.to_s # skip YJIT+ZJIT Rust object (no corresponding C source) next if /\.bundle\// =~ target.to_s next if /\A\./ =~ target.to_s # skip rules such as ".c.o" #p [curdir, target, deps] From 8296524fd6cf2fb9ae1eca4be722fe9ee2c26f37 Mon Sep 17 00:00:00 2001 From: Alan Wu Date: Wed, 3 Dec 2025 17:16:27 -0500 Subject: [PATCH 14/24] ZJIT: Fix duplicate make rule warning in combo build ~/zjit/zjit.mk:30: warning: overriding commands for target `~/build-default/' ~/yjit/yjit.mk:26: warning: ignoring old commands for target `~/build-default/' ~/zjit/zjit.mk:30: warning: overriding commands for target `~/build-default/' ~/yjit/yjit.mk:26: warning: ignoring old commands for target `~/build-default/' --- zjit/zjit.mk | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/zjit/zjit.mk b/zjit/zjit.mk index f31b948845678a..01274dc3073642 100644 --- a/zjit/zjit.mk +++ b/zjit/zjit.mk @@ -24,8 +24,8 @@ ZJIT_LIB_TOUCH = touch $@ # the "target" dir in the source directory through VPATH. BUILD_ZJIT_LIBS = $(TOP_BUILD_DIR)/$(ZJIT_LIBS) -# ZJIT_SUPPORT=yes when `configure` gets `--enable-zjit` -ifeq ($(ZJIT_SUPPORT),yes) +# In a ZJIT-only build (no YJIT) +ifneq ($(strip $(ZJIT_LIBS)),) $(BUILD_ZJIT_LIBS): $(ZJIT_SRC_FILES) $(ECHO) 'building Rust ZJIT (release mode)' +$(Q) $(RUSTC) $(ZJIT_RUSTC_ARGS) From addeafdd5b9e2404eef555f523bc92a6c373d294 Mon Sep 17 00:00:00 2001 From: Alan Wu Date: Wed, 3 Dec 2025 17:20:44 -0500 Subject: [PATCH 15/24] YJIT: Fix duplicate make rule warning in combo build --- yjit/yjit.mk | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/yjit/yjit.mk b/yjit/yjit.mk index cf68edb29770b8..e019e4a08cf7b8 100644 --- a/yjit/yjit.mk +++ b/yjit/yjit.mk @@ -19,8 +19,8 @@ YJIT_LIB_TOUCH = touch $@ # the "target" dir in the source directory through VPATH. BUILD_YJIT_LIBS = $(TOP_BUILD_DIR)/$(YJIT_LIBS) -# YJIT_SUPPORT=yes when `configure` gets `--enable-yjit` -ifeq ($(YJIT_SUPPORT),yes) +# In a YJIT-only build (no ZJIT) +ifneq ($(strip $(YJIT_LIBS)),) yjit-libs: $(BUILD_YJIT_LIBS) $(BUILD_YJIT_LIBS): $(YJIT_SRC_FILES) $(ECHO) 'building Rust YJIT (release mode)' From dce716e25b5101cc57ab0699db9265d961d59d82 Mon Sep 17 00:00:00 2001 From: Alan Wu Date: Wed, 3 Dec 2025 20:26:51 -0500 Subject: [PATCH 16/24] ZJIT: Update `depend` for zjit.o --- depend | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/depend b/depend index 569f14a04da5bf..81ab8274710947 100644 --- a/depend +++ b/depend @@ -20241,6 +20241,7 @@ zjit.$(OBJEXT): $(top_srcdir)/internal/array.h zjit.$(OBJEXT): $(top_srcdir)/internal/basic_operators.h zjit.$(OBJEXT): $(top_srcdir)/internal/bignum.h zjit.$(OBJEXT): $(top_srcdir)/internal/bits.h +zjit.$(OBJEXT): $(top_srcdir)/internal/box.h zjit.$(OBJEXT): $(top_srcdir)/internal/class.h zjit.$(OBJEXT): $(top_srcdir)/internal/compile.h zjit.$(OBJEXT): $(top_srcdir)/internal/compilers.h @@ -20252,6 +20253,7 @@ zjit.$(OBJEXT): $(top_srcdir)/internal/imemo.h zjit.$(OBJEXT): $(top_srcdir)/internal/numeric.h zjit.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h zjit.$(OBJEXT): $(top_srcdir)/internal/serial.h +zjit.$(OBJEXT): $(top_srcdir)/internal/set_table.h zjit.$(OBJEXT): $(top_srcdir)/internal/static_assert.h zjit.$(OBJEXT): $(top_srcdir)/internal/string.h zjit.$(OBJEXT): $(top_srcdir)/internal/variable.h @@ -20428,6 +20430,7 @@ zjit.$(OBJEXT): {$(VPATH)}internal/intern/re.h zjit.$(OBJEXT): {$(VPATH)}internal/intern/ruby.h zjit.$(OBJEXT): {$(VPATH)}internal/intern/select.h zjit.$(OBJEXT): {$(VPATH)}internal/intern/select/largesize.h +zjit.$(OBJEXT): {$(VPATH)}internal/intern/set.h zjit.$(OBJEXT): {$(VPATH)}internal/intern/signal.h zjit.$(OBJEXT): {$(VPATH)}internal/intern/sprintf.h zjit.$(OBJEXT): {$(VPATH)}internal/intern/string.h @@ -20479,6 +20482,7 @@ zjit.$(OBJEXT): {$(VPATH)}vm_debug.h zjit.$(OBJEXT): {$(VPATH)}vm_insnhelper.h zjit.$(OBJEXT): {$(VPATH)}vm_opts.h zjit.$(OBJEXT): {$(VPATH)}vm_sync.h +zjit.$(OBJEXT): {$(VPATH)}yjit.h zjit.$(OBJEXT): {$(VPATH)}zjit.c zjit.$(OBJEXT): {$(VPATH)}zjit.h zjit.$(OBJEXT): {$(VPATH)}zjit.rbinc From 9a2710013c52d81174fa289b9002df1be379d39d Mon Sep 17 00:00:00 2001 From: Alan Wu Date: Wed, 3 Dec 2025 21:16:23 -0500 Subject: [PATCH 17/24] YJIT: Fix unused_unsafe warning in `StatsAlloc` --- jit/src/lib.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/jit/src/lib.rs b/jit/src/lib.rs index 6079d00f2fd886..c0f043131e0d74 100644 --- a/jit/src/lib.rs +++ b/jit/src/lib.rs @@ -1,4 +1,5 @@ //! Shared code between YJIT and ZJIT. +#![warn(unsafe_op_in_unsafe_fn)] // Adopt 2024 edition default when targeting 2021 editions use std::sync::atomic::{AtomicUsize, Ordering}; use std::alloc::{GlobalAlloc, Layout, System}; From ffe99a56de887bbc24e6ff63cd93f6a88fdd1cf4 Mon Sep 17 00:00:00 2001 From: Alan Wu Date: Mon, 1 Dec 2025 22:57:04 -0500 Subject: [PATCH 18/24] ZJIT: configure.ac logic to detect suitable build environment This runs the detection, but does nothing with the result. * Fixed version requirement in messages -- ZJIT requires >= 1.85 unlike YJIT. * New: Detect when rust 1.85 is available, and neither --enable-yjit nor --enable-zjit is passed to ./configure, include both YJIT and ZJIT in the build --- configure.ac | 55 ++++++++++++++++++++++++++++++++-------------------- 1 file changed, 34 insertions(+), 21 deletions(-) diff --git a/configure.ac b/configure.ac index 21f2e5a466e382..ffdf86e1da21ef 100644 --- a/configure.ac +++ b/configure.ac @@ -3875,12 +3875,13 @@ AC_SUBST(INSTALL_STATIC_LIBRARY) [begin]_group "JIT section" && { AC_CHECK_PROG(RUSTC, [rustc], [rustc], [no]) dnl no ac_tool_prefix +AC_CHECK_TOOL(CARGO, [cargo], [no]) -dnl check if rustc is recent enough to build YJIT/ZJIT (rustc >= 1.58.0) +dnl check if rustc is recent enough to build YJIT (rustc >= 1.58.0) JIT_RUSTC_OK=no +JIT_TARGET_ARCH= AS_IF([test "$RUSTC" != "no"], - AC_MSG_CHECKING([whether ${RUSTC} works for YJIT/ZJIT]) - JIT_TARGET_ARCH= + AC_MSG_CHECKING([whether ${RUSTC} works for YJIT]) AS_CASE(["$target_cpu"], [arm64|aarch64], [JIT_TARGET_ARCH=aarch64], [x86_64], [JIT_TARGET_ARCH=x86_64], @@ -3914,33 +3915,46 @@ AS_IF([test "$cross_compiling" = no], ) ) -dnl build ZJIT in release mode if rustc >= 1.58.0 is present and we are on a supported platform -AC_ARG_ENABLE(zjit, - AS_HELP_STRING([--enable-zjit], - [enable in-process JIT compiler that requires Rust build tools. enabled by default on supported platforms if rustc 1.58.0+ is available]), - [ZJIT_SUPPORT=$enableval], - [AS_CASE(["$JIT_TARGET_OK:$JIT_RUSTC_OK:$YJIT_SUPPORT"], - [yes:yes:no], [ - ZJIT_SUPPORT=yes - ], - [ZJIT_SUPPORT=no] - )] -) - dnl build YJIT in release mode if rustc >= 1.58.0 is present and we are on a supported platform AC_ARG_ENABLE(yjit, AS_HELP_STRING([--enable-yjit], [enable in-process JIT compiler that requires Rust build tools. enabled by default on supported platforms if rustc 1.58.0+ is available]), [YJIT_SUPPORT=$enableval], - [AS_CASE(["$JIT_TARGET_OK:$JIT_RUSTC_OK:$ZJIT_SUPPORT"], - [yes:yes:no], [ + [AS_CASE(["$JIT_TARGET_OK:$JIT_RUSTC_OK"], + [yes:yes], [ YJIT_SUPPORT=yes ], [YJIT_SUPPORT=no] )] ) -CARGO= +dnl build ZJIT in release mode if rustc >= 1.85.0 is present and we are on a supported platform +ZJIT_SUPPORT=no +AC_ARG_ENABLE(zjit, + AS_HELP_STRING([--enable-zjit], + [enable experimental JIT compiler that requires Rust build tools. enabled by default on supported platforms if rustc 1.85.0+ is available]), + [ZJIT_SUPPORT=$enableval], + [AS_CASE(["$JIT_TARGET_OK"], + [yes], [ + rb_zjit_build_possible=no + AC_MSG_CHECKING([possible to build ZJIT])dnl only checked when --enable-zjit is not specified + # Fails in case rustc target doesn't match ruby target. Can happen on Rosetta, for example. + # 1.85.0 is the first stable version that supports the 2024 edition. + AS_IF([test "$RUSTC" != "no" && echo "#[cfg(target_arch = \"$JIT_TARGET_ARCH\")] fn main() {}" | + $RUSTC - --edition=2024 --emit asm=/dev/null 2>/dev/null], + AS_IF([test "$YJIT_SUPPORT" = "no" -o "$CARGO" != "no"], [ + # When only building ZJIT, we don't need cargo; it's required for YJIT+ZJIT build. + # Assume that if rustc is new enough, then cargo is also. + # TODO(alan): Get rid of dependency on cargo in YJIT+ZJIT build. Cargo's offline mode + # still too unreliable: https://github.com/rust-lang/cargo/issues/10352 + rb_zjit_build_possible=yes + ]) + ) + AC_MSG_RESULT($rb_zjit_build_possible) + ] + )] +) + CARGO_BUILD_ARGS= YJIT_LIBS= JIT_CARGO_SUPPORT=no @@ -4019,9 +4033,8 @@ AS_CASE(["${ZJIT_SUPPORT}"], # if YJIT+ZJIT release build, or any build that requires Cargo AS_IF([test x"$JIT_CARGO_SUPPORT" != "xno" -o \( x"$YJIT_SUPPORT" != "xno" -a x"$ZJIT_SUPPORT" != "xno" \)], [ - AC_CHECK_TOOL(CARGO, [cargo], [no]) AS_IF([test x"$CARGO" = "xno"], - AC_MSG_ERROR([cargo is required. Installation instructions available at https://www.rust-lang.org/tools/install])) + AC_MSG_ERROR([this build configuration requires cargo. Installation instructions available at https://www.rust-lang.org/tools/install])) YJIT_LIBS= ZJIT_LIBS= From f559a9106c703c3ecadefa2f2eb26290b9ffa7fe Mon Sep 17 00:00:00 2001 From: Alan Wu Date: Wed, 3 Dec 2025 16:55:55 -0500 Subject: [PATCH 19/24] ZJIT: configure.ac: Look for GNU make when detecting build environment Building ZJIT requires GNU make at the moment. To get access to `$gnumake`, lift the `make` flavour detection up to the environment section, before the JIT section runs. --- configure.ac | 42 +++++++++++++++++++++++------------------- 1 file changed, 23 insertions(+), 19 deletions(-) diff --git a/configure.ac b/configure.ac index ffdf86e1da21ef..9a35917cac88d3 100644 --- a/configure.ac +++ b/configure.ac @@ -296,6 +296,8 @@ AC_CHECK_TOOLS([OBJCOPY], [gobjcopy objcopy], [:]) AC_CHECK_TOOLS([OBJDUMP], [gobjdump objdump]) AC_CHECK_TOOLS([STRIP], [gstrip strip], [:]) +FIRSTMAKEFILE="" + # nm errors with Rust's LLVM bitcode when Rust uses a newer LLVM version than nm. # In case we're working with llvm-nm, tell it to not worry about the bitcode. AS_IF([${NM} --help 2>&1 | grep -q 'llvm-bc'], [NM="$NM --no-llvm-bc"]) @@ -470,6 +472,8 @@ AS_CASE(["$target_os"], # so wrap clang to insert our fake wasm-opt, which does nothing, in PATH. CC_WRAPPER=`cd -P "${tooldir}" && pwd`/wasm-clangw CC="$CC_WRAPPER $CC" + + FIRSTMAKEFILE=GNUmakefile:wasm/GNUmakefile.in ]) cc_version= @@ -511,6 +515,8 @@ AS_CASE(["$target_os"], target_cpu=`echo $target_cpu | sed s/i.86/i386/` AS_CASE(["$target"], [-*], [ target="$target_cpu${target}"]) AS_CASE(["$target_alias"], [-*], [ target_alias="$target_cpu${target_alias}"]) + # cygwin/GNUmakefile.in is not exclusively for cygwin. + FIRSTMAKEFILE=GNUmakefile:cygwin/GNUmakefile.in AS_CASE(["$target_os"], [mingw*], [ test "$rb_cv_msvcrt" = "" && unset rb_cv_msvcrt @@ -613,6 +619,22 @@ AS_IF([test -f conf$$.dir/src/cdcmd], [ rm -fr conf$$.dir AC_MSG_RESULT([$CHDIR]) AC_SUBST(CHDIR) + +AS_CASE(["$FIRSTMAKEFILE"], [*GNUmakefile:*], [gnumake=yes], [ + AC_MSG_CHECKING([if ${MAKE-make} is GNU make]) + mkdir conftest.dir + echo "all:; @echo yes" > conftest.dir/GNUmakefile + echo "all:; @echo no" > conftest.dir/Makefile + gnumake=`(cd conftest.dir; ${MAKE-make})` + rm -fr conftest.dir + AS_CASE(["$gnumake"], + [*yes*], [ + FIRSTMAKEFILE=GNUmakefile:template/GNUmakefile.in + gnumake=yes], + [ + gnumake=no]) + AC_MSG_RESULT($gnumake) +]) } [begin]_group "compiler section" && { @@ -3512,7 +3534,6 @@ AC_SUBST(RUNRUBY) AC_SUBST(XRUBY) AC_SUBST(EXTOUT, [${EXTOUT=.ext}]) -FIRSTMAKEFILE="" LIBRUBY_A='lib$(RUBY_SO_NAME)-static.a' LIBRUBY='$(LIBRUBY_A)' LIBRUBYARG_STATIC='-l$(RUBY_SO_NAME)-static' @@ -3942,7 +3963,7 @@ AC_ARG_ENABLE(zjit, # 1.85.0 is the first stable version that supports the 2024 edition. AS_IF([test "$RUSTC" != "no" && echo "#[cfg(target_arch = \"$JIT_TARGET_ARCH\")] fn main() {}" | $RUSTC - --edition=2024 --emit asm=/dev/null 2>/dev/null], - AS_IF([test "$YJIT_SUPPORT" = "no" -o "$CARGO" != "no"], [ + AS_IF([test "$gnumake" = "yes" -a \( "$YJIT_SUPPORT" = "no" -o "$CARGO" != "no" \)], [ # When only building ZJIT, we don't need cargo; it's required for YJIT+ZJIT build. # Assume that if rustc is new enough, then cargo is also. # TODO(alan): Get rid of dependency on cargo in YJIT+ZJIT build. Cargo's offline mode @@ -4200,7 +4221,6 @@ enum { PLATFORM_DIR=win32 ]) LIBRUBY_ALIASES='' - FIRSTMAKEFILE=GNUmakefile:cygwin/GNUmakefile.in AS_IF([test x"$enable_shared" = xyes], [ LIBRUBY='lib$(RUBY_SO_NAME).dll.a' ], [ @@ -4210,7 +4230,6 @@ enum { ]) ], [wasi*], [ - FIRSTMAKEFILE=GNUmakefile:wasm/GNUmakefile.in AC_LIBOBJ([wasm/missing]) AC_LIBOBJ([wasm/runtime]) AC_LIBOBJ([wasm/fiber]) @@ -4227,21 +4246,6 @@ AC_ARG_ENABLE(debug-env, AS_HELP_STRING([--enable-debug-env], [enable RUBY_DEBUG environment variable]), [AC_SUBST(ENABLE_DEBUG_ENV, yes)]) -AS_CASE(["$FIRSTMAKEFILE"], [*GNUmakefile:*], [gnumake=yes], [ - AC_MSG_CHECKING([if ${MAKE-make} is GNU make]) - mkdir conftest.dir - echo "all:; @echo yes" > conftest.dir/GNUmakefile - echo "all:; @echo no" > conftest.dir/Makefile - gnumake=`(cd conftest.dir; ${MAKE-make})` - rm -fr conftest.dir - AS_CASE(["$gnumake"], - [*yes*], [ - FIRSTMAKEFILE=GNUmakefile:template/GNUmakefile.in - gnumake=yes], - [ - gnumake=no]) - AC_MSG_RESULT($gnumake) -]) AS_IF([test "$gnumake" = yes], [ NULLCMD=: ], [ AC_MSG_CHECKING([for safe null command for ${MAKE-make}]) mkdir conftest.dir From d396a66a82992d4ff3f4d52a6e7c493b560ae9b2 Mon Sep 17 00:00:00 2001 From: Alan Wu Date: Thu, 4 Dec 2025 22:43:28 -0500 Subject: [PATCH 20/24] ZJIT: Build by default when build environment allows "Default" means when `--enable-zjit` is absent from `./configure` arguments. --- configure.ac | 1 + 1 file changed, 1 insertion(+) diff --git a/configure.ac b/configure.ac index 9a35917cac88d3..14b0234ef0f9aa 100644 --- a/configure.ac +++ b/configure.ac @@ -3972,6 +3972,7 @@ AC_ARG_ENABLE(zjit, ]) ) AC_MSG_RESULT($rb_zjit_build_possible) + ZJIT_SUPPORT=$rb_zjit_build_possible ] )] ) From c4c909b538a2114491be0785ec4aa3d26d2916c4 Mon Sep 17 00:00:00 2001 From: Stan Lo Date: Fri, 5 Dec 2025 22:00:24 +0000 Subject: [PATCH 21/24] ZJIT: Include local variable names in `Get|SetLocal` insn's print value (#15423) ZJIT: Print local variable names GetLocal and SetLocal instructions --- zjit/src/hir.rs | 57 ++++- zjit/src/hir/opt_tests.rs | 452 +++++++++++++++++++------------------- zjit/src/hir/tests.rs | 324 +++++++++++++-------------- 3 files changed, 433 insertions(+), 400 deletions(-) diff --git a/zjit/src/hir.rs b/zjit/src/hir.rs index 32d6f63b9ed74c..4323b145feb1b6 100644 --- a/zjit/src/hir.rs +++ b/zjit/src/hir.rs @@ -956,8 +956,8 @@ impl Insn { } } - pub fn print<'a>(&self, ptr_map: &'a PtrPrintMap) -> InsnPrinter<'a> { - InsnPrinter { inner: self.clone(), ptr_map } + pub fn print<'a>(&self, ptr_map: &'a PtrPrintMap, iseq: Option) -> InsnPrinter<'a> { + InsnPrinter { inner: self.clone(), ptr_map, iseq } } /// Return true if the instruction needs to be kept around. For example, if the instruction @@ -1020,6 +1020,30 @@ impl Insn { pub struct InsnPrinter<'a> { inner: Insn, ptr_map: &'a PtrPrintMap, + iseq: Option, +} + +/// Get the name of a local variable given iseq, level, and ep_offset. +/// Returns +/// - `":name"` if iseq is available and name is a real identifier, +/// - `""` for anonymous locals. +/// - `None` if iseq is not available. +/// (When `Insn` is printed in a panic/debug message the `Display::fmt` method is called, which can't access an iseq.) +/// +/// This mimics local_var_name() from iseq.c. +fn get_local_var_name_for_printer(iseq: Option, level: u32, ep_offset: u32) -> Option { + let mut current_iseq = iseq?; + for _ in 0..level { + current_iseq = unsafe { rb_get_iseq_body_parent_iseq(current_iseq) }; + } + let local_idx = ep_offset_to_local_idx(current_iseq, ep_offset); + let id: ID = unsafe { rb_zjit_local_id(current_iseq, local_idx.try_into().unwrap()) }; + + if id.0 == 0 || unsafe { rb_id2str(id) } == Qfalse { + return Some(String::from("")); + } + + Some(format!(":{}", id.contents_lossy())) } static REGEXP_FLAGS: &[(u32, &str)] = &[ @@ -1302,9 +1326,18 @@ impl<'a> std::fmt::Display for InsnPrinter<'a> { Insn::SetIvar { self_val, id, val, .. } => write!(f, "SetIvar {self_val}, :{}, {val}", id.contents_lossy()), Insn::GetGlobal { id, .. } => write!(f, "GetGlobal :{}", id.contents_lossy()), Insn::SetGlobal { id, val, .. } => write!(f, "SetGlobal :{}, {val}", id.contents_lossy()), - &Insn::GetLocal { level, ep_offset, use_sp: true, rest_param } => write!(f, "GetLocal l{level}, SP@{}{}", ep_offset + 1, if rest_param { ", *" } else { "" }), - &Insn::GetLocal { level, ep_offset, use_sp: false, rest_param } => write!(f, "GetLocal l{level}, EP@{ep_offset}{}", if rest_param { ", *" } else { "" }), - Insn::SetLocal { val, level, ep_offset } => write!(f, "SetLocal l{level}, EP@{ep_offset}, {val}"), + &Insn::GetLocal { level, ep_offset, use_sp: true, rest_param } => { + let name = get_local_var_name_for_printer(self.iseq, level, ep_offset).map_or(String::new(), |x| format!("{x}, ")); + write!(f, "GetLocal {name}l{level}, SP@{}{}", ep_offset + 1, if rest_param { ", *" } else { "" }) + }, + &Insn::GetLocal { level, ep_offset, use_sp: false, rest_param } => { + let name = get_local_var_name_for_printer(self.iseq, level, ep_offset).map_or(String::new(), |x| format!("{x}, ")); + write!(f, "GetLocal {name}l{level}, EP@{ep_offset}{}", if rest_param { ", *" } else { "" }) + }, + &Insn::SetLocal { val, level, ep_offset } => { + let name = get_local_var_name_for_printer(self.iseq, level, ep_offset).map_or(String::new(), |x| format!("{x}, ")); + write!(f, "SetLocal {name}l{level}, EP@{ep_offset}, {val}") + }, Insn::GetSpecialSymbol { symbol_type, .. } => write!(f, "GetSpecialSymbol {symbol_type:?}"), Insn::GetSpecialNumber { nth, .. } => write!(f, "GetSpecialNumber {nth}"), Insn::GetClassVar { id, .. } => write!(f, "GetClassVar :{}", id.contents_lossy()), @@ -1346,7 +1379,7 @@ impl<'a> std::fmt::Display for InsnPrinter<'a> { impl std::fmt::Display for Insn { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { - self.print(&PtrPrintMap::identity()).fmt(f) + self.print(&PtrPrintMap::identity(), None).fmt(f) } } @@ -4052,7 +4085,7 @@ impl Function { }; - let opcode = insn.print(&ptr_map).to_string(); + let opcode = insn.print(&ptr_map, Some(self.iseq)).to_string(); // Traverse the worklist to get inputs for a given instruction. let mut inputs = VecDeque::new(); @@ -4606,7 +4639,7 @@ impl<'a> std::fmt::Display for FunctionPrinter<'a> { write!(f, "{insn_id}:{} = ", insn_type.print(&self.ptr_map))?; } } - writeln!(f, "{}", insn.print(&self.ptr_map))?; + writeln!(f, "{}", insn.print(&self.ptr_map, Some(fun.iseq)))?; } } Ok(()) @@ -4682,7 +4715,7 @@ impl<'a> std::fmt::Display for FunctionGraphvizPrinter<'a> { if let Insn::Jump(ref target) | Insn::IfTrue { ref target, .. } | Insn::IfFalse { ref target, .. } = insn { edges.push((insn_id, target.target)); } - write_encoded!(f, "{}", insn.print(&self.ptr_map))?; + write_encoded!(f, "{}", insn.print(&self.ptr_map, Some(fun.iseq)))?; writeln!(f, " ")?; } writeln!(f, ">];")?; @@ -6723,8 +6756,8 @@ mod graphviz_tests { bb0()  EntryPoint interpreter  v1:BasicObject = LoadSelf  - v2:BasicObject = GetLocal l0, SP@5  - v3:BasicObject = GetLocal l0, SP@4  + v2:BasicObject = GetLocal :x, l0, SP@5  + v3:BasicObject = GetLocal :y, l0, SP@4  Jump bb2(v1, v2, v3)  >]; bb0:v4 -> bb2:params:n; @@ -6774,7 +6807,7 @@ mod graphviz_tests { bb0()  EntryPoint interpreter  v1:BasicObject = LoadSelf  - v2:BasicObject = GetLocal l0, SP@4  + v2:BasicObject = GetLocal :c, l0, SP@4  Jump bb2(v1, v2)  >]; bb0:v3 -> bb2:params:n; diff --git a/zjit/src/hir/opt_tests.rs b/zjit/src/hir/opt_tests.rs index a174ac1b69280e..5646af804a2d0f 100644 --- a/zjit/src/hir/opt_tests.rs +++ b/zjit/src/hir/opt_tests.rs @@ -219,7 +219,7 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :n, l0, SP@4 Jump bb2(v1, v2) bb1(v5:BasicObject, v6:BasicObject): EntryPoint JIT(0) @@ -551,7 +551,7 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :object, l0, SP@4 Jump bb2(v1, v2) bb1(v5:BasicObject, v6:BasicObject): EntryPoint JIT(0) @@ -580,7 +580,7 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :a, l0, SP@4 Jump bb2(v1, v2) bb1(v5:BasicObject, v6:BasicObject): EntryPoint JIT(0) @@ -610,7 +610,7 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:ArrayExact = GetLocal l0, SP@4, * + v2:ArrayExact = GetLocal :array, l0, SP@4, * Jump bb2(v1, v2) bb1(v5:BasicObject, v6:ArrayExact): EntryPoint JIT(0) @@ -623,8 +623,8 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@5 - v3:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :k, l0, SP@5 + v3:BasicObject = GetLocal , l0, SP@4 Jump bb2(v1, v2, v3) bb1(v6:BasicObject, v7:BasicObject, v8:BasicObject): EntryPoint JIT(0) @@ -637,7 +637,7 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :k, l0, SP@4 Jump bb2(v1, v2) bb1(v5:BasicObject, v6:BasicObject): EntryPoint JIT(0) @@ -650,7 +650,7 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :b, l0, SP@4 Jump bb2(v1, v2) bb1(v5:BasicObject, v6:BasicObject): EntryPoint JIT(0) @@ -664,8 +664,8 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:ArrayExact = GetLocal l0, SP@5, * - v3:BasicObject = GetLocal l0, SP@4 + v2:ArrayExact = GetLocal :rest, l0, SP@5, * + v3:BasicObject = GetLocal :post, l0, SP@4 Jump bb2(v1, v2, v3) bb1(v6:BasicObject, v7:ArrayExact, v8:BasicObject): EntryPoint JIT(0) @@ -774,7 +774,7 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :o, l0, SP@4 Jump bb2(v1, v2) bb1(v5:BasicObject, v6:BasicObject): EntryPoint JIT(0) @@ -784,7 +784,7 @@ mod hir_opt_tests { PatchPoint NoSingletonClass(C@0x1000) v23:ArraySubclass[class_exact:C] = GuardType v9, ArraySubclass[class_exact:C] v24:BasicObject = CCallWithFrame v23, :C#fun_new_map@0x1038, block=0x1040 - v15:BasicObject = GetLocal l0, EP@3 + v15:BasicObject = GetLocal :o, l0, EP@3 CheckInterrupts Return v24 "); @@ -1064,8 +1064,8 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@5 - v3:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :a, l0, SP@5 + v3:BasicObject = GetLocal :b, l0, SP@4 Jump bb2(v1, v2, v3) bb1(v6:BasicObject, v7:BasicObject, v8:BasicObject): EntryPoint JIT(0) @@ -1091,8 +1091,8 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@5 - v3:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :a, l0, SP@5 + v3:BasicObject = GetLocal :b, l0, SP@4 Jump bb2(v1, v2, v3) bb1(v6:BasicObject, v7:BasicObject, v8:BasicObject): EntryPoint JIT(0) @@ -1119,7 +1119,7 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :a, l0, SP@4 Jump bb2(v1, v2) bb1(v5:BasicObject, v6:BasicObject): EntryPoint JIT(0) @@ -1146,7 +1146,7 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :a, l0, SP@4 Jump bb2(v1, v2) bb1(v5:BasicObject, v6:BasicObject): EntryPoint JIT(0) @@ -1173,8 +1173,8 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@5 - v3:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :a, l0, SP@5 + v3:BasicObject = GetLocal :b, l0, SP@4 Jump bb2(v1, v2, v3) bb1(v6:BasicObject, v7:BasicObject, v8:BasicObject): EntryPoint JIT(0) @@ -1201,7 +1201,7 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :a, l0, SP@4 Jump bb2(v1, v2) bb1(v5:BasicObject, v6:BasicObject): EntryPoint JIT(0) @@ -1228,7 +1228,7 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :a, l0, SP@4 Jump bb2(v1, v2) bb1(v5:BasicObject, v6:BasicObject): EntryPoint JIT(0) @@ -1316,7 +1316,7 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :a, l0, SP@4 Jump bb2(v1, v2) bb1(v5:BasicObject, v6:BasicObject): EntryPoint JIT(0) @@ -1343,7 +1343,7 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :a, l0, SP@4 Jump bb2(v1, v2) bb1(v5:BasicObject, v6:BasicObject): EntryPoint JIT(0) @@ -1370,7 +1370,7 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :a, l0, SP@4 Jump bb2(v1, v2) bb1(v5:BasicObject, v6:BasicObject): EntryPoint JIT(0) @@ -1397,7 +1397,7 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :a, l0, SP@4 Jump bb2(v1, v2) bb1(v5:BasicObject, v6:BasicObject): EntryPoint JIT(0) @@ -1451,7 +1451,7 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :arr, l0, SP@4 Jump bb2(v1, v2) bb1(v5:BasicObject, v6:BasicObject): EntryPoint JIT(0) @@ -1481,7 +1481,7 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :arr, l0, SP@4 Jump bb2(v1, v2) bb1(v5:BasicObject, v6:BasicObject): EntryPoint JIT(0) @@ -1574,7 +1574,7 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@5 + v2:BasicObject = GetLocal :a, l0, SP@5 v3:NilClass = Const Value(nil) Jump bb2(v1, v2, v3) bb1(v6:BasicObject, v7:BasicObject): @@ -1630,8 +1630,8 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@6 - v3:BasicObject = GetLocal l0, SP@5 + v2:BasicObject = GetLocal :aval, l0, SP@6 + v3:BasicObject = GetLocal :bval, l0, SP@5 v4:NilClass = Const Value(nil) Jump bb2(v1, v2, v3, v4) bb1(v7:BasicObject, v8:BasicObject, v9:BasicObject): @@ -1776,8 +1776,8 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@5 - v3:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :a, l0, SP@5 + v3:BasicObject = GetLocal :b, l0, SP@4 Jump bb2(v1, v2, v3) bb1(v6:BasicObject, v7:BasicObject, v8:BasicObject): EntryPoint JIT(0) @@ -1807,8 +1807,8 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@5 - v3:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :a, l0, SP@5 + v3:BasicObject = GetLocal :b, l0, SP@4 Jump bb2(v1, v2, v3) bb1(v6:BasicObject, v7:BasicObject, v8:BasicObject): EntryPoint JIT(0) @@ -1838,8 +1838,8 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@5 - v3:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :a, l0, SP@5 + v3:BasicObject = GetLocal :b, l0, SP@4 Jump bb2(v1, v2, v3) bb1(v6:BasicObject, v7:BasicObject, v8:BasicObject): EntryPoint JIT(0) @@ -1869,8 +1869,8 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@5 - v3:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :a, l0, SP@5 + v3:BasicObject = GetLocal :b, l0, SP@4 Jump bb2(v1, v2, v3) bb1(v6:BasicObject, v7:BasicObject, v8:BasicObject): EntryPoint JIT(0) @@ -1901,8 +1901,8 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@5 - v3:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :a, l0, SP@5 + v3:BasicObject = GetLocal :b, l0, SP@4 Jump bb2(v1, v2, v3) bb1(v6:BasicObject, v7:BasicObject, v8:BasicObject): EntryPoint JIT(0) @@ -1933,8 +1933,8 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@5 - v3:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :a, l0, SP@5 + v3:BasicObject = GetLocal :b, l0, SP@4 Jump bb2(v1, v2, v3) bb1(v6:BasicObject, v7:BasicObject, v8:BasicObject): EntryPoint JIT(0) @@ -1964,8 +1964,8 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@5 - v3:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :a, l0, SP@5 + v3:BasicObject = GetLocal :b, l0, SP@4 Jump bb2(v1, v2, v3) bb1(v6:BasicObject, v7:BasicObject, v8:BasicObject): EntryPoint JIT(0) @@ -1995,8 +1995,8 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@5 - v3:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :a, l0, SP@5 + v3:BasicObject = GetLocal :b, l0, SP@4 Jump bb2(v1, v2, v3) bb1(v6:BasicObject, v7:BasicObject, v8:BasicObject): EntryPoint JIT(0) @@ -2026,8 +2026,8 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@5 - v3:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :a, l0, SP@5 + v3:BasicObject = GetLocal :b, l0, SP@4 Jump bb2(v1, v2, v3) bb1(v6:BasicObject, v7:BasicObject, v8:BasicObject): EntryPoint JIT(0) @@ -2057,8 +2057,8 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@5 - v3:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :a, l0, SP@5 + v3:BasicObject = GetLocal :b, l0, SP@4 Jump bb2(v1, v2, v3) bb1(v6:BasicObject, v7:BasicObject, v8:BasicObject): EntryPoint JIT(0) @@ -2088,8 +2088,8 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@5 - v3:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :a, l0, SP@5 + v3:BasicObject = GetLocal :b, l0, SP@4 Jump bb2(v1, v2, v3) bb1(v6:BasicObject, v7:BasicObject, v8:BasicObject): EntryPoint JIT(0) @@ -2143,7 +2143,7 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :x, l0, SP@4 Jump bb2(v1, v2) bb1(v5:BasicObject, v6:BasicObject): EntryPoint JIT(0) @@ -2540,7 +2540,7 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :x, l0, SP@4 Jump bb2(v1, v2) bb1(v5:BasicObject, v6:BasicObject): EntryPoint JIT(0) @@ -2568,7 +2568,7 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@5 + v2:BasicObject = GetLocal :x, l0, SP@5 v3:NilClass = Const Value(nil) Jump bb2(v1, v2, v3) bb1(v6:BasicObject, v7:BasicObject): @@ -2636,7 +2636,7 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :c, l0, SP@4 Jump bb2(v1, v2) bb1(v5:BasicObject, v6:BasicObject): EntryPoint JIT(0) @@ -2700,10 +2700,10 @@ mod hir_opt_tests { Jump bb2(v5, v6) bb2(v8:BasicObject, v9:NilClass): v13:Fixnum[1] = Const Value(1) - SetLocal l0, EP@3, v13 + SetLocal :a, l0, EP@3, v13 v19:BasicObject = Send v8, 0x1000, :foo - v20:BasicObject = GetLocal l0, EP@3 - v24:BasicObject = GetLocal l0, EP@3 + v20:BasicObject = GetLocal :a, l0, EP@3 + v24:BasicObject = GetLocal :a, l0, EP@3 CheckInterrupts Return v24 "); @@ -3260,8 +3260,8 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@5 - v3:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :a, l0, SP@5 + v3:BasicObject = GetLocal :b, l0, SP@4 Jump bb2(v1, v2, v3) bb1(v6:BasicObject, v7:BasicObject, v8:BasicObject): EntryPoint JIT(0) @@ -3287,8 +3287,8 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@5 - v3:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :a, l0, SP@5 + v3:BasicObject = GetLocal :b, l0, SP@4 Jump bb2(v1, v2, v3) bb1(v6:BasicObject, v7:BasicObject, v8:BasicObject): EntryPoint JIT(0) @@ -3314,7 +3314,7 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :block, l0, SP@4 Jump bb2(v1, v2) bb1(v5:BasicObject, v6:BasicObject): EntryPoint JIT(0) @@ -4150,7 +4150,7 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :a, l0, SP@4 Jump bb2(v1, v2) bb1(v5:BasicObject, v6:BasicObject): EntryPoint JIT(0) @@ -4182,7 +4182,7 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :a, l0, SP@4 Jump bb2(v1, v2) bb1(v5:BasicObject, v6:BasicObject): EntryPoint JIT(0) @@ -4211,7 +4211,7 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :a, l0, SP@4 Jump bb2(v1, v2) bb1(v5:BasicObject, v6:BasicObject): EntryPoint JIT(0) @@ -4762,7 +4762,7 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :val, l0, SP@4 Jump bb2(v1, v2) bb1(v5:BasicObject, v6:BasicObject): EntryPoint JIT(0) @@ -4789,7 +4789,7 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :val, l0, SP@4 Jump bb2(v1, v2) bb1(v5:BasicObject, v6:BasicObject): EntryPoint JIT(0) @@ -4816,7 +4816,7 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :val, l0, SP@4 Jump bb2(v1, v2) bb1(v5:BasicObject, v6:BasicObject): EntryPoint JIT(0) @@ -4843,7 +4843,7 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :val, l0, SP@4 Jump bb2(v1, v2) bb1(v5:BasicObject, v6:BasicObject): EntryPoint JIT(0) @@ -4870,7 +4870,7 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :val, l0, SP@4 Jump bb2(v1, v2) bb1(v5:BasicObject, v6:BasicObject): EntryPoint JIT(0) @@ -4897,7 +4897,7 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :val, l0, SP@4 Jump bb2(v1, v2) bb1(v5:BasicObject, v6:BasicObject): EntryPoint JIT(0) @@ -4924,7 +4924,7 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :val, l0, SP@4 Jump bb2(v1, v2) bb1(v5:BasicObject, v6:BasicObject): EntryPoint JIT(0) @@ -4952,7 +4952,7 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :a, l0, SP@4 Jump bb2(v1, v2) bb1(v5:BasicObject, v6:BasicObject): EntryPoint JIT(0) @@ -4980,7 +4980,7 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :a, l0, SP@4 Jump bb2(v1, v2) bb1(v5:BasicObject, v6:BasicObject): EntryPoint JIT(0) @@ -5007,7 +5007,7 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :a, l0, SP@4 Jump bb2(v1, v2) bb1(v5:BasicObject, v6:BasicObject): EntryPoint JIT(0) @@ -5037,7 +5037,7 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :a, l0, SP@4 Jump bb2(v1, v2) bb1(v5:BasicObject, v6:BasicObject): EntryPoint JIT(0) @@ -5074,7 +5074,7 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :a, l0, SP@4 Jump bb2(v1, v2) bb1(v5:BasicObject, v6:BasicObject): EntryPoint JIT(0) @@ -5102,7 +5102,7 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :a, l0, SP@4 Jump bb2(v1, v2) bb1(v5:BasicObject, v6:BasicObject): EntryPoint JIT(0) @@ -5131,8 +5131,8 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@5 - v3:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :a, l0, SP@5 + v3:BasicObject = GetLocal :b, l0, SP@4 Jump bb2(v1, v2, v3) bb1(v6:BasicObject, v7:BasicObject, v8:BasicObject): EntryPoint JIT(0) @@ -5161,8 +5161,8 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@5 - v3:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :x, l0, SP@5 + v3:BasicObject = GetLocal :y, l0, SP@4 Jump bb2(v1, v2, v3) bb1(v6:BasicObject, v7:BasicObject, v8:BasicObject): EntryPoint JIT(0) @@ -5190,8 +5190,8 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@5 - v3:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :x, l0, SP@5 + v3:BasicObject = GetLocal :y, l0, SP@4 Jump bb2(v1, v2, v3) bb1(v6:BasicObject, v7:BasicObject, v8:BasicObject): EntryPoint JIT(0) @@ -5256,7 +5256,7 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :o, l0, SP@4 Jump bb2(v1, v2) bb1(v5:BasicObject, v6:BasicObject): EntryPoint JIT(0) @@ -5295,7 +5295,7 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :o, l0, SP@4 Jump bb2(v1, v2) bb1(v5:BasicObject, v6:BasicObject): EntryPoint JIT(0) @@ -5485,7 +5485,7 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :o, l0, SP@4 Jump bb2(v1, v2) bb1(v5:BasicObject, v6:BasicObject): EntryPoint JIT(0) @@ -5518,7 +5518,7 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :o, l0, SP@4 Jump bb2(v1, v2) bb1(v5:BasicObject, v6:BasicObject): EntryPoint JIT(0) @@ -5587,7 +5587,7 @@ mod hir_opt_tests { Jump bb2(v5, v6) bb2(v8:BasicObject, v9:NilClass): v13:ArrayExact = NewArray - SetLocal l0, EP@3, v13 + SetLocal :result, l0, EP@3, v13 PatchPoint SingleRactorMode PatchPoint StableConstantNames(0x1000, A) v36:ArrayExact[VALUE(0x1008)] = Const Value(VALUE(0x1008)) @@ -5597,8 +5597,8 @@ mod hir_opt_tests { PatchPoint MethodRedefined(Array@0x1020, zip@0x1028, cme:0x1030) PatchPoint NoSingletonClass(Array@0x1020) v43:BasicObject = CCallVariadic v36, :zip@0x1058, v39 - v25:BasicObject = GetLocal l0, EP@3 - v29:BasicObject = GetLocal l0, EP@3 + v25:BasicObject = GetLocal :result, l0, EP@3 + v29:BasicObject = GetLocal :result, l0, EP@3 CheckInterrupts Return v29 "); @@ -5615,7 +5615,7 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :block, l0, SP@4 Jump bb2(v1, v2) bb1(v5:BasicObject, v6:BasicObject): EntryPoint JIT(0) @@ -5741,7 +5741,7 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :o, l0, SP@4 Jump bb2(v1, v2) bb1(v5:BasicObject, v6:BasicObject): EntryPoint JIT(0) @@ -5773,7 +5773,7 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :o, l0, SP@4 Jump bb2(v1, v2) bb1(v5:BasicObject, v6:BasicObject): EntryPoint JIT(0) @@ -5805,7 +5805,7 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :o, l0, SP@4 Jump bb2(v1, v2) bb1(v5:BasicObject, v6:BasicObject): EntryPoint JIT(0) @@ -5840,7 +5840,7 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :o, l0, SP@4 Jump bb2(v1, v2) bb1(v5:BasicObject, v6:BasicObject): EntryPoint JIT(0) @@ -5872,7 +5872,7 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :o, l0, SP@4 Jump bb2(v1, v2) bb1(v5:BasicObject, v6:BasicObject): EntryPoint JIT(0) @@ -5900,7 +5900,7 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :o, l0, SP@4 Jump bb2(v1, v2) bb1(v5:BasicObject, v6:BasicObject): EntryPoint JIT(0) @@ -5932,7 +5932,7 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :o, l0, SP@4 Jump bb2(v1, v2) bb1(v5:BasicObject, v6:BasicObject): EntryPoint JIT(0) @@ -5961,8 +5961,8 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@5 - v3:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :o, l0, SP@5 + v3:BasicObject = GetLocal :v, l0, SP@4 Jump bb2(v1, v2, v3) bb1(v6:BasicObject, v7:BasicObject, v8:BasicObject): EntryPoint JIT(0) @@ -5993,8 +5993,8 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@5 - v3:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :o, l0, SP@5 + v3:BasicObject = GetLocal :v, l0, SP@4 Jump bb2(v1, v2, v3) bb1(v6:BasicObject, v7:BasicObject, v8:BasicObject): EntryPoint JIT(0) @@ -6150,7 +6150,7 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :o, l0, SP@4 Jump bb2(v1, v2) bb1(v5:BasicObject, v6:BasicObject): EntryPoint JIT(0) @@ -6176,7 +6176,7 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :x, l0, SP@4 Jump bb2(v1, v2) bb1(v5:BasicObject, v6:BasicObject): EntryPoint JIT(0) @@ -6201,7 +6201,7 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :x, l0, SP@4 Jump bb2(v1, v2) bb1(v5:BasicObject, v6:BasicObject): EntryPoint JIT(0) @@ -6226,7 +6226,7 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :x, l0, SP@4 Jump bb2(v1, v2) bb1(v5:BasicObject, v6:BasicObject): EntryPoint JIT(0) @@ -6287,8 +6287,8 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@5 - v3:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :arr, l0, SP@5 + v3:BasicObject = GetLocal :idx, l0, SP@4 Jump bb2(v1, v2, v3) bb1(v6:BasicObject, v7:BasicObject, v8:BasicObject): EntryPoint JIT(0) @@ -6319,8 +6319,8 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@5 - v3:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :arr, l0, SP@5 + v3:BasicObject = GetLocal :idx, l0, SP@4 Jump bb2(v1, v2, v3) bb1(v6:BasicObject, v7:BasicObject, v8:BasicObject): EntryPoint JIT(0) @@ -6382,8 +6382,8 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@5 - v3:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :hash, l0, SP@5 + v3:BasicObject = GetLocal :key, l0, SP@4 Jump bb2(v1, v2, v3) bb1(v6:BasicObject, v7:BasicObject, v8:BasicObject): EntryPoint JIT(0) @@ -6413,8 +6413,8 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@5 - v3:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :hash, l0, SP@5 + v3:BasicObject = GetLocal :key, l0, SP@4 Jump bb2(v1, v2, v3) bb1(v6:BasicObject, v7:BasicObject, v8:BasicObject): EntryPoint JIT(0) @@ -6503,7 +6503,7 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :arr, l0, SP@4 Jump bb2(v1, v2) bb1(v5:BasicObject, v6:BasicObject): EntryPoint JIT(0) @@ -6533,7 +6533,7 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :arr, l0, SP@4 Jump bb2(v1, v2) bb1(v5:BasicObject, v6:BasicObject): EntryPoint JIT(0) @@ -6563,7 +6563,7 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :arr, l0, SP@4 Jump bb2(v1, v2) bb1(v5:BasicObject, v6:BasicObject): EntryPoint JIT(0) @@ -6593,7 +6593,7 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :arr, l0, SP@4 Jump bb2(v1, v2) bb1(v5:BasicObject, v6:BasicObject): EntryPoint JIT(0) @@ -6623,7 +6623,7 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :arr, l0, SP@4 Jump bb2(v1, v2) bb1(v5:BasicObject, v6:BasicObject): EntryPoint JIT(0) @@ -6651,7 +6651,7 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :arr, l0, SP@4 Jump bb2(v1, v2) bb1(v5:BasicObject, v6:BasicObject): EntryPoint JIT(0) @@ -6679,7 +6679,7 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :s, l0, SP@4 Jump bb2(v1, v2) bb1(v5:BasicObject, v6:BasicObject): EntryPoint JIT(0) @@ -6706,8 +6706,8 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@5 - v3:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :s, l0, SP@5 + v3:BasicObject = GetLocal :i, l0, SP@4 Jump bb2(v1, v2, v3) bb1(v6:BasicObject, v7:BasicObject, v8:BasicObject): EntryPoint JIT(0) @@ -6743,8 +6743,8 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@5 - v3:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :s, l0, SP@5 + v3:BasicObject = GetLocal :i, l0, SP@4 Jump bb2(v1, v2, v3) bb1(v6:BasicObject, v7:BasicObject, v8:BasicObject): EntryPoint JIT(0) @@ -6779,9 +6779,9 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@6 - v3:BasicObject = GetLocal l0, SP@5 - v4:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :s, l0, SP@6 + v3:BasicObject = GetLocal :idx, l0, SP@5 + v4:BasicObject = GetLocal :val, l0, SP@4 Jump bb2(v1, v2, v3, v4) bb1(v7:BasicObject, v8:BasicObject, v9:BasicObject, v10:BasicObject): EntryPoint JIT(0) @@ -6820,9 +6820,9 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@6 - v3:BasicObject = GetLocal l0, SP@5 - v4:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :s, l0, SP@6 + v3:BasicObject = GetLocal :idx, l0, SP@5 + v4:BasicObject = GetLocal :val, l0, SP@4 Jump bb2(v1, v2, v3, v4) bb1(v7:BasicObject, v8:BasicObject, v9:BasicObject, v10:BasicObject): EntryPoint JIT(0) @@ -6859,9 +6859,9 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@6 - v3:BasicObject = GetLocal l0, SP@5 - v4:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :s, l0, SP@6 + v3:BasicObject = GetLocal :idx, l0, SP@5 + v4:BasicObject = GetLocal :val, l0, SP@4 Jump bb2(v1, v2, v3, v4) bb1(v7:BasicObject, v8:BasicObject, v9:BasicObject, v10:BasicObject): EntryPoint JIT(0) @@ -6889,7 +6889,7 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :s, l0, SP@4 Jump bb2(v1, v2) bb1(v5:BasicObject, v6:BasicObject): EntryPoint JIT(0) @@ -6922,7 +6922,7 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :s, l0, SP@4 Jump bb2(v1, v2) bb1(v5:BasicObject, v6:BasicObject): EntryPoint JIT(0) @@ -6950,7 +6950,7 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :x, l0, SP@4 Jump bb2(v1, v2) bb1(v5:BasicObject, v6:BasicObject): EntryPoint JIT(0) @@ -6978,7 +6978,7 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :x, l0, SP@4 Jump bb2(v1, v2) bb1(v5:BasicObject, v6:BasicObject): EntryPoint JIT(0) @@ -7004,7 +7004,7 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :x, l0, SP@4 Jump bb2(v1, v2) bb1(v5:BasicObject, v6:BasicObject): EntryPoint JIT(0) @@ -7032,7 +7032,7 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :x, l0, SP@4 Jump bb2(v1, v2) bb1(v5:BasicObject, v6:BasicObject): EntryPoint JIT(0) @@ -7059,7 +7059,7 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :x, l0, SP@4 Jump bb2(v1, v2) bb1(v5:BasicObject, v6:BasicObject): EntryPoint JIT(0) @@ -7086,8 +7086,8 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@5 - v3:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :x, l0, SP@5 + v3:BasicObject = GetLocal :y, l0, SP@4 Jump bb2(v1, v2, v3) bb1(v6:BasicObject, v7:BasicObject, v8:BasicObject): EntryPoint JIT(0) @@ -7112,7 +7112,7 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :x, l0, SP@4 Jump bb2(v1, v2) bb1(v5:BasicObject, v6:BasicObject): EntryPoint JIT(0) @@ -7139,7 +7139,7 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :x, l0, SP@4 Jump bb2(v1, v2) bb1(v5:BasicObject, v6:BasicObject): EntryPoint JIT(0) @@ -7165,7 +7165,7 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :x, l0, SP@4 Jump bb2(v1, v2) bb1(v5:BasicObject, v6:BasicObject): EntryPoint JIT(0) @@ -7191,8 +7191,8 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@5 - v3:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :x, l0, SP@5 + v3:BasicObject = GetLocal :y, l0, SP@4 Jump bb2(v1, v2, v3) bb1(v6:BasicObject, v7:BasicObject, v8:BasicObject): EntryPoint JIT(0) @@ -7217,8 +7217,8 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@5 - v3:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :x, l0, SP@5 + v3:BasicObject = GetLocal :y, l0, SP@4 Jump bb2(v1, v2, v3) bb1(v6:BasicObject, v7:BasicObject, v8:BasicObject): EntryPoint JIT(0) @@ -7246,8 +7246,8 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@5 - v3:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :x, l0, SP@5 + v3:BasicObject = GetLocal :y, l0, SP@4 Jump bb2(v1, v2, v3) bb1(v6:BasicObject, v7:BasicObject, v8:BasicObject): EntryPoint JIT(0) @@ -7277,8 +7277,8 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@5 - v3:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :x, l0, SP@5 + v3:BasicObject = GetLocal :y, l0, SP@4 Jump bb2(v1, v2, v3) bb1(v6:BasicObject, v7:BasicObject, v8:BasicObject): EntryPoint JIT(0) @@ -7308,8 +7308,8 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@5 - v3:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :x, l0, SP@5 + v3:BasicObject = GetLocal :y, l0, SP@4 Jump bb2(v1, v2, v3) bb1(v6:BasicObject, v7:BasicObject, v8:BasicObject): EntryPoint JIT(0) @@ -7387,7 +7387,7 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :x, l0, SP@4 Jump bb2(v1, v2) bb1(v5:BasicObject, v6:BasicObject): EntryPoint JIT(0) @@ -7460,8 +7460,8 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@5 - v3:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :x, l0, SP@5 + v3:BasicObject = GetLocal :y, l0, SP@4 Jump bb2(v1, v2, v3) bb1(v6:BasicObject, v7:BasicObject, v8:BasicObject): EntryPoint JIT(0) @@ -7491,8 +7491,8 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@5 - v3:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :x, l0, SP@5 + v3:BasicObject = GetLocal :y, l0, SP@4 Jump bb2(v1, v2, v3) bb1(v6:BasicObject, v7:BasicObject, v8:BasicObject): EntryPoint JIT(0) @@ -7519,8 +7519,8 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@5 - v3:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :x, l0, SP@5 + v3:BasicObject = GetLocal :y, l0, SP@4 Jump bb2(v1, v2, v3) bb1(v6:BasicObject, v7:BasicObject, v8:BasicObject): EntryPoint JIT(0) @@ -7542,8 +7542,8 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@5 - v3:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :x, l0, SP@5 + v3:BasicObject = GetLocal :y, l0, SP@4 Jump bb2(v1, v2, v3) bb1(v6:BasicObject, v7:BasicObject, v8:BasicObject): EntryPoint JIT(0) @@ -7565,8 +7565,8 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@5 - v3:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :x, l0, SP@5 + v3:BasicObject = GetLocal :y, l0, SP@4 Jump bb2(v1, v2, v3) bb1(v6:BasicObject, v7:BasicObject, v8:BasicObject): EntryPoint JIT(0) @@ -7590,8 +7590,8 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@5 - v3:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :x, l0, SP@5 + v3:BasicObject = GetLocal :y, l0, SP@4 Jump bb2(v1, v2, v3) bb1(v6:BasicObject, v7:BasicObject, v8:BasicObject): EntryPoint JIT(0) @@ -7614,7 +7614,7 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :hash, l0, SP@4 Jump bb2(v1, v2) bb1(v5:BasicObject, v6:BasicObject): EntryPoint JIT(0) @@ -7644,7 +7644,7 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :hash, l0, SP@4 Jump bb2(v1, v2) bb1(v5:BasicObject, v6:BasicObject): EntryPoint JIT(0) @@ -7674,7 +7674,7 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :o, l0, SP@4 Jump bb2(v1, v2) bb1(v5:BasicObject, v6:BasicObject): EntryPoint JIT(0) @@ -7706,7 +7706,7 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :o, l0, SP@4 Jump bb2(v1, v2) bb1(v5:BasicObject, v6:BasicObject): EntryPoint JIT(0) @@ -7741,7 +7741,7 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :o, l0, SP@4 Jump bb2(v1, v2) bb1(v5:BasicObject, v6:BasicObject): EntryPoint JIT(0) @@ -7775,7 +7775,7 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :o, l0, SP@4 Jump bb2(v1, v2) bb1(v5:BasicObject, v6:BasicObject): EntryPoint JIT(0) @@ -7810,7 +7810,7 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :o, l0, SP@4 Jump bb2(v1, v2) bb1(v5:BasicObject, v6:BasicObject): EntryPoint JIT(0) @@ -7845,7 +7845,7 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :o, l0, SP@4 Jump bb2(v1, v2) bb1(v5:BasicObject, v6:BasicObject): EntryPoint JIT(0) @@ -7879,7 +7879,7 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :o, l0, SP@4 Jump bb2(v1, v2) bb1(v5:BasicObject, v6:BasicObject): EntryPoint JIT(0) @@ -7913,7 +7913,7 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :o, l0, SP@4 Jump bb2(v1, v2) bb1(v5:BasicObject, v6:BasicObject): EntryPoint JIT(0) @@ -7946,7 +7946,7 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :o, l0, SP@4 Jump bb2(v1, v2) bb1(v5:BasicObject, v6:BasicObject): EntryPoint JIT(0) @@ -7982,7 +7982,7 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :o, l0, SP@4 Jump bb2(v1, v2) bb1(v5:BasicObject, v6:BasicObject): EntryPoint JIT(0) @@ -8299,7 +8299,7 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :o, l0, SP@4 Jump bb2(v1, v2) bb1(v5:BasicObject, v6:BasicObject): EntryPoint JIT(0) @@ -8324,7 +8324,7 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :o, l0, SP@4 Jump bb2(v1, v2) bb1(v5:BasicObject, v6:BasicObject): EntryPoint JIT(0) @@ -8349,8 +8349,8 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@5 - v3:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :l, l0, SP@5 + v3:BasicObject = GetLocal :r, l0, SP@4 Jump bb2(v1, v2, v3) bb1(v6:BasicObject, v7:BasicObject, v8:BasicObject): EntryPoint JIT(0) @@ -8380,8 +8380,8 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@5 - v3:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :l, l0, SP@5 + v3:BasicObject = GetLocal :r, l0, SP@4 Jump bb2(v1, v2, v3) bb1(v6:BasicObject, v7:BasicObject, v8:BasicObject): EntryPoint JIT(0) @@ -8411,8 +8411,8 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@5 - v3:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :l, l0, SP@5 + v3:BasicObject = GetLocal :r, l0, SP@4 Jump bb2(v1, v2, v3) bb1(v6:BasicObject, v7:BasicObject, v8:BasicObject): EntryPoint JIT(0) @@ -8440,8 +8440,8 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@5 - v3:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :l, l0, SP@5 + v3:BasicObject = GetLocal :r, l0, SP@4 Jump bb2(v1, v2, v3) bb1(v6:BasicObject, v7:BasicObject, v8:BasicObject): EntryPoint JIT(0) @@ -8471,8 +8471,8 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@5 - v3:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :l, l0, SP@5 + v3:BasicObject = GetLocal :r, l0, SP@4 Jump bb2(v1, v2, v3) bb1(v6:BasicObject, v7:BasicObject, v8:BasicObject): EntryPoint JIT(0) @@ -8502,8 +8502,8 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@5 - v3:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :l, l0, SP@5 + v3:BasicObject = GetLocal :r, l0, SP@4 Jump bb2(v1, v2, v3) bb1(v6:BasicObject, v7:BasicObject, v8:BasicObject): EntryPoint JIT(0) @@ -8533,7 +8533,7 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :s, l0, SP@4 Jump bb2(v1, v2) bb1(v5:BasicObject, v6:BasicObject): EntryPoint JIT(0) @@ -8563,7 +8563,7 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :s, l0, SP@4 Jump bb2(v1, v2) bb1(v5:BasicObject, v6:BasicObject): EntryPoint JIT(0) @@ -8592,7 +8592,7 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :s, l0, SP@4 Jump bb2(v1, v2) bb1(v5:BasicObject, v6:BasicObject): EntryPoint JIT(0) @@ -8623,7 +8623,7 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :s, l0, SP@4 Jump bb2(v1, v2) bb1(v5:BasicObject, v6:BasicObject): EntryPoint JIT(0) @@ -8652,7 +8652,7 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :s, l0, SP@4 Jump bb2(v1, v2) bb1(v5:BasicObject, v6:BasicObject): EntryPoint JIT(0) @@ -8679,7 +8679,7 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :o, l0, SP@4 Jump bb2(v1, v2) bb1(v5:BasicObject, v6:BasicObject): EntryPoint JIT(0) @@ -8709,7 +8709,7 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :o, l0, SP@4 Jump bb2(v1, v2) bb1(v5:BasicObject, v6:BasicObject): EntryPoint JIT(0) @@ -8739,7 +8739,7 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :o, l0, SP@4 Jump bb2(v1, v2) bb1(v5:BasicObject, v6:BasicObject): EntryPoint JIT(0) @@ -8769,7 +8769,7 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :o, l0, SP@4 Jump bb2(v1, v2) bb1(v5:BasicObject, v6:BasicObject): EntryPoint JIT(0) @@ -8801,7 +8801,7 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :o, l0, SP@4 Jump bb2(v1, v2) bb1(v5:BasicObject, v6:BasicObject): EntryPoint JIT(0) @@ -8834,7 +8834,7 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :o, l0, SP@4 Jump bb2(v1, v2) bb1(v5:BasicObject, v6:BasicObject): EntryPoint JIT(0) @@ -8864,7 +8864,7 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :o, l0, SP@4 Jump bb2(v1, v2) bb1(v5:BasicObject, v6:BasicObject): EntryPoint JIT(0) @@ -8894,7 +8894,7 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :o, l0, SP@4 Jump bb2(v1, v2) bb1(v5:BasicObject, v6:BasicObject): EntryPoint JIT(0) @@ -8926,7 +8926,7 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :o, l0, SP@4 Jump bb2(v1, v2) bb1(v5:BasicObject, v6:BasicObject): EntryPoint JIT(0) @@ -9011,7 +9011,7 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :s, l0, SP@4 Jump bb2(v1, v2) bb1(v5:BasicObject, v6:BasicObject): EntryPoint JIT(0) @@ -9090,7 +9090,7 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :o, l0, SP@4 Jump bb2(v1, v2) bb1(v5:BasicObject, v6:BasicObject): EntryPoint JIT(0) @@ -9123,7 +9123,7 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :o, l0, SP@4 Jump bb2(v1, v2) bb1(v5:BasicObject, v6:BasicObject): EntryPoint JIT(0) @@ -9217,9 +9217,9 @@ mod hir_opt_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@7 - v3:BasicObject = GetLocal l0, SP@6 - v4:BasicObject = GetLocal l0, SP@5 + v2:BasicObject = GetLocal :a, l0, SP@7 + v3:BasicObject = GetLocal :_b, l0, SP@6 + v4:BasicObject = GetLocal :_c, l0, SP@5 v5:NilClass = Const Value(nil) Jump bb2(v1, v2, v3, v4, v5) bb1(v8:BasicObject, v9:BasicObject, v10:BasicObject, v11:BasicObject): @@ -9228,9 +9228,9 @@ mod hir_opt_tests { Jump bb2(v8, v9, v10, v11, v12) bb2(v14:BasicObject, v15:BasicObject, v16:BasicObject, v17:BasicObject, v18:NilClass): CheckInterrupts - v27:BasicObject = GetLocal l0, EP@6 - SetLocal l0, EP@3, v27 - v39:BasicObject = GetLocal l0, EP@3 + v27:BasicObject = GetLocal :a, l0, EP@6 + SetLocal :formatted, l0, EP@3, v27 + v39:BasicObject = GetLocal :formatted, l0, EP@3 PatchPoint SingleRactorMode v56:HeapBasicObject = GuardType v14, HeapBasicObject v57:HeapBasicObject = GuardShape v56, 0x1000 @@ -9242,10 +9242,10 @@ mod hir_opt_tests { PatchPoint MethodRedefined(Class@0x1010, lambda@0x1018, cme:0x1020) PatchPoint NoSingletonClass(Class@0x1010) v65:BasicObject = CCallWithFrame v45, :RubyVM::FrozenCore.lambda@0x1048, block=0x1050 - v48:BasicObject = GetLocal l0, EP@6 - v49:BasicObject = GetLocal l0, EP@5 - v50:BasicObject = GetLocal l0, EP@4 - v51:BasicObject = GetLocal l0, EP@3 + v48:BasicObject = GetLocal :a, l0, EP@6 + v49:BasicObject = GetLocal :_b, l0, EP@5 + v50:BasicObject = GetLocal :_c, l0, EP@4 + v51:BasicObject = GetLocal :formatted, l0, EP@3 CheckInterrupts Return v65 "); diff --git a/zjit/src/hir/tests.rs b/zjit/src/hir/tests.rs index 79ba1d30c53443..76be941fe529f9 100644 --- a/zjit/src/hir/tests.rs +++ b/zjit/src/hir/tests.rs @@ -22,8 +22,8 @@ mod snapshot_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@5 - v3:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :a, l0, SP@5 + v3:BasicObject = GetLocal :b, l0, SP@4 Jump bb2(v1, v2, v3) bb1(v6:BasicObject, v7:BasicObject, v8:BasicObject): EntryPoint JIT(0) @@ -127,7 +127,7 @@ pub mod hir_build_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :x, l0, SP@4 v3:CPtr = LoadPC v4:CPtr[CPtr(0x1000)] = Const CPtr(0x1008) v5:CBool = IsBitEqual v3, v4 @@ -199,7 +199,7 @@ pub mod hir_build_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :a, l0, SP@4 Jump bb2(v1, v2) bb1(v5:BasicObject, v6:BasicObject): EntryPoint JIT(0) @@ -220,8 +220,8 @@ pub mod hir_build_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@5 - v3:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :a, l0, SP@5 + v3:BasicObject = GetLocal :b, l0, SP@4 Jump bb2(v1, v2, v3) bb1(v6:BasicObject, v7:BasicObject, v8:BasicObject): EntryPoint JIT(0) @@ -242,7 +242,7 @@ pub mod hir_build_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :a, l0, SP@4 Jump bb2(v1, v2) bb1(v5:BasicObject, v6:BasicObject): EntryPoint JIT(0) @@ -264,8 +264,8 @@ pub mod hir_build_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@5 - v3:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :a, l0, SP@5 + v3:BasicObject = GetLocal :b, l0, SP@4 Jump bb2(v1, v2, v3) bb1(v6:BasicObject, v7:BasicObject, v8:BasicObject): EntryPoint JIT(0) @@ -286,7 +286,7 @@ pub mod hir_build_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :a, l0, SP@4 Jump bb2(v1, v2) bb1(v5:BasicObject, v6:BasicObject): EntryPoint JIT(0) @@ -308,8 +308,8 @@ pub mod hir_build_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@5 - v3:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :a, l0, SP@5 + v3:BasicObject = GetLocal :b, l0, SP@4 Jump bb2(v1, v2, v3) bb1(v6:BasicObject, v7:BasicObject, v8:BasicObject): EntryPoint JIT(0) @@ -392,8 +392,8 @@ pub mod hir_build_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@5 - v3:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :aval, l0, SP@5 + v3:BasicObject = GetLocal :bval, l0, SP@4 Jump bb2(v1, v2, v3) bb1(v6:BasicObject, v7:BasicObject, v8:BasicObject): EntryPoint JIT(0) @@ -773,16 +773,16 @@ pub mod hir_build_tests { EntryPoint JIT(0) Jump bb2(v4) bb2(v6:BasicObject): - v10:BasicObject = GetLocal l2, EP@4 - SetLocal l1, EP@3, v10 - v15:BasicObject = GetLocal l1, EP@3 - v17:BasicObject = GetLocal l2, EP@4 + v10:BasicObject = GetLocal :l2, l2, EP@4 + SetLocal :l1, l1, EP@3, v10 + v15:BasicObject = GetLocal :l1, l1, EP@3 + v17:BasicObject = GetLocal :l2, l2, EP@4 v20:BasicObject = SendWithoutBlock v15, :+, v17 - SetLocal l2, EP@4, v20 - v25:BasicObject = GetLocal l2, EP@4 - v27:BasicObject = GetLocal l3, EP@5 + SetLocal :l2, l2, EP@4, v20 + v25:BasicObject = GetLocal :l2, l2, EP@4 + v27:BasicObject = GetLocal :l3, l3, EP@5 v30:BasicObject = SendWithoutBlock v25, :+, v27 - SetLocal l3, EP@5, v30 + SetLocal :l3, l3, EP@5, v30 CheckInterrupts Return v30 " @@ -800,7 +800,7 @@ pub mod hir_build_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@5 + v2:BasicObject = GetLocal :a, l0, SP@5 v3:NilClass = Const Value(nil) v4:CPtr = LoadPC v5:CPtr[CPtr(0x1000)] = Const CPtr(0x1008) @@ -838,7 +838,7 @@ pub mod hir_build_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@5 + v2:BasicObject = GetLocal :a, l0, SP@5 v3:NilClass = Const Value(nil) v4:CPtr = LoadPC v5:CPtr[CPtr(0x1000)] = Const CPtr(0x1008) @@ -873,7 +873,7 @@ pub mod hir_build_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :a, l0, SP@4 v3:CPtr = LoadPC v4:CPtr[CPtr(0x1000)] = Const CPtr(0x1008) v5:CBool = IsBitEqual v3, v4 @@ -904,7 +904,7 @@ pub mod hir_build_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :a, l0, SP@4 Jump bb2(v1, v2) bb1(v5:BasicObject): EntryPoint JIT(0) @@ -1021,7 +1021,7 @@ pub mod hir_build_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :cond, l0, SP@4 Jump bb2(v1, v2) bb1(v5:BasicObject, v6:BasicObject): EntryPoint JIT(0) @@ -1057,7 +1057,7 @@ pub mod hir_build_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@5 + v2:BasicObject = GetLocal :cond, l0, SP@5 v3:NilClass = Const Value(nil) Jump bb2(v1, v2, v3) bb1(v6:BasicObject, v7:BasicObject): @@ -1095,8 +1095,8 @@ pub mod hir_build_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@5 - v3:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :a, l0, SP@5 + v3:BasicObject = GetLocal :b, l0, SP@4 Jump bb2(v1, v2, v3) bb1(v6:BasicObject, v7:BasicObject, v8:BasicObject): EntryPoint JIT(0) @@ -1120,8 +1120,8 @@ pub mod hir_build_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@5 - v3:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :a, l0, SP@5 + v3:BasicObject = GetLocal :b, l0, SP@4 Jump bb2(v1, v2, v3) bb1(v6:BasicObject, v7:BasicObject, v8:BasicObject): EntryPoint JIT(0) @@ -1145,8 +1145,8 @@ pub mod hir_build_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@5 - v3:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :a, l0, SP@5 + v3:BasicObject = GetLocal :b, l0, SP@4 Jump bb2(v1, v2, v3) bb1(v6:BasicObject, v7:BasicObject, v8:BasicObject): EntryPoint JIT(0) @@ -1170,8 +1170,8 @@ pub mod hir_build_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@5 - v3:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :a, l0, SP@5 + v3:BasicObject = GetLocal :b, l0, SP@4 Jump bb2(v1, v2, v3) bb1(v6:BasicObject, v7:BasicObject, v8:BasicObject): EntryPoint JIT(0) @@ -1195,8 +1195,8 @@ pub mod hir_build_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@5 - v3:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :a, l0, SP@5 + v3:BasicObject = GetLocal :b, l0, SP@4 Jump bb2(v1, v2, v3) bb1(v6:BasicObject, v7:BasicObject, v8:BasicObject): EntryPoint JIT(0) @@ -1220,8 +1220,8 @@ pub mod hir_build_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@5 - v3:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :a, l0, SP@5 + v3:BasicObject = GetLocal :b, l0, SP@4 Jump bb2(v1, v2, v3) bb1(v6:BasicObject, v7:BasicObject, v8:BasicObject): EntryPoint JIT(0) @@ -1245,8 +1245,8 @@ pub mod hir_build_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@5 - v3:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :a, l0, SP@5 + v3:BasicObject = GetLocal :b, l0, SP@4 Jump bb2(v1, v2, v3) bb1(v6:BasicObject, v7:BasicObject, v8:BasicObject): EntryPoint JIT(0) @@ -1270,8 +1270,8 @@ pub mod hir_build_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@5 - v3:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :a, l0, SP@5 + v3:BasicObject = GetLocal :b, l0, SP@4 Jump bb2(v1, v2, v3) bb1(v6:BasicObject, v7:BasicObject, v8:BasicObject): EntryPoint JIT(0) @@ -1295,8 +1295,8 @@ pub mod hir_build_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@5 - v3:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :a, l0, SP@5 + v3:BasicObject = GetLocal :b, l0, SP@4 Jump bb2(v1, v2, v3) bb1(v6:BasicObject, v7:BasicObject, v8:BasicObject): EntryPoint JIT(0) @@ -1320,8 +1320,8 @@ pub mod hir_build_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@5 - v3:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :a, l0, SP@5 + v3:BasicObject = GetLocal :b, l0, SP@4 Jump bb2(v1, v2, v3) bb1(v6:BasicObject, v7:BasicObject, v8:BasicObject): EntryPoint JIT(0) @@ -1398,8 +1398,8 @@ pub mod hir_build_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@5 - v3:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :a, l0, SP@5 + v3:BasicObject = GetLocal :b, l0, SP@4 Jump bb2(v1, v2, v3) bb1(v6:BasicObject, v7:BasicObject, v8:BasicObject): EntryPoint JIT(0) @@ -1494,14 +1494,14 @@ pub mod hir_build_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :a, l0, SP@4 Jump bb2(v1, v2) bb1(v5:BasicObject, v6:BasicObject): EntryPoint JIT(0) Jump bb2(v5, v6) bb2(v8:BasicObject, v9:BasicObject): v14:BasicObject = Send v9, 0x1000, :each - v15:BasicObject = GetLocal l0, EP@3 + v15:BasicObject = GetLocal :a, l0, EP@3 CheckInterrupts Return v14 "); @@ -1575,7 +1575,7 @@ pub mod hir_build_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :a, l0, SP@4 Jump bb2(v1, v2) bb1(v5:BasicObject, v6:BasicObject): EntryPoint JIT(0) @@ -1598,7 +1598,7 @@ pub mod hir_build_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :a, l0, SP@4 Jump bb2(v1, v2) bb1(v5:BasicObject, v6:BasicObject): EntryPoint JIT(0) @@ -1620,7 +1620,7 @@ pub mod hir_build_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :a, l0, SP@4 Jump bb2(v1, v2) bb1(v5:BasicObject, v6:BasicObject): EntryPoint JIT(0) @@ -1643,7 +1643,7 @@ pub mod hir_build_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :a, l0, SP@4 Jump bb2(v1, v2) bb1(v5:BasicObject, v6:BasicObject): EntryPoint JIT(0) @@ -1731,7 +1731,7 @@ pub mod hir_build_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :..., l0, SP@4 Jump bb2(v1, v2) bb1(v5:BasicObject, v6:BasicObject): EntryPoint JIT(0) @@ -1749,7 +1749,7 @@ pub mod hir_build_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :..., l0, SP@4 Jump bb2(v1, v2) bb1(v5:BasicObject, v6:BasicObject): EntryPoint JIT(0) @@ -1773,7 +1773,7 @@ pub mod hir_build_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :a, l0, SP@4 Jump bb2(v1, v2) bb1(v5:BasicObject, v6:BasicObject): EntryPoint JIT(0) @@ -1803,7 +1803,7 @@ pub mod hir_build_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:ArrayExact = GetLocal l0, SP@4, * + v2:ArrayExact = GetLocal :*, l0, SP@4, * Jump bb2(v1, v2) bb1(v5:BasicObject, v6:ArrayExact): EntryPoint JIT(0) @@ -1828,7 +1828,7 @@ pub mod hir_build_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :..., l0, SP@4 Jump bb2(v1, v2) bb1(v5:BasicObject, v6:BasicObject): EntryPoint JIT(0) @@ -1850,10 +1850,10 @@ pub mod hir_build_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@8 - v3:ArrayExact = GetLocal l0, SP@7, * - v4:BasicObject = GetLocal l0, SP@6 - v5:BasicObject = GetLocal l0, SP@5 + v2:BasicObject = GetLocal :a, l0, SP@8 + v3:ArrayExact = GetLocal :*, l0, SP@7, * + v4:BasicObject = GetLocal :**, l0, SP@6 + v5:BasicObject = GetLocal :&, l0, SP@5 v6:NilClass = Const Value(nil) Jump bb2(v1, v2, v3, v4, v5, v6) bb1(v9:BasicObject, v10:BasicObject, v11:ArrayExact, v12:BasicObject, v13:BasicObject): @@ -1938,8 +1938,8 @@ pub mod hir_build_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@5 - v3:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :a, l0, SP@5 + v3:BasicObject = GetLocal :b, l0, SP@4 Jump bb2(v1, v2, v3) bb1(v6:BasicObject, v7:BasicObject, v8:BasicObject): EntryPoint JIT(0) @@ -1970,8 +1970,8 @@ pub mod hir_build_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@5 - v3:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :a, l0, SP@5 + v3:BasicObject = GetLocal :b, l0, SP@4 Jump bb2(v1, v2, v3) bb1(v6:BasicObject, v7:BasicObject, v8:BasicObject): EntryPoint JIT(0) @@ -1997,8 +1997,8 @@ pub mod hir_build_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@7 - v3:BasicObject = GetLocal l0, SP@6 + v2:BasicObject = GetLocal :a, l0, SP@7 + v3:BasicObject = GetLocal :b, l0, SP@6 v4:NilClass = Const Value(nil) v5:NilClass = Const Value(nil) Jump bb2(v1, v2, v3, v4, v5) @@ -2029,8 +2029,8 @@ pub mod hir_build_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@7 - v3:BasicObject = GetLocal l0, SP@6 + v2:BasicObject = GetLocal :a, l0, SP@7 + v3:BasicObject = GetLocal :b, l0, SP@6 v4:NilClass = Const Value(nil) v5:NilClass = Const Value(nil) Jump bb2(v1, v2, v3, v4, v5) @@ -2071,8 +2071,8 @@ pub mod hir_build_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@7 - v3:BasicObject = GetLocal l0, SP@6 + v2:BasicObject = GetLocal :a, l0, SP@7 + v3:BasicObject = GetLocal :b, l0, SP@6 v4:NilClass = Const Value(nil) v5:NilClass = Const Value(nil) Jump bb2(v1, v2, v3, v4, v5) @@ -2103,8 +2103,8 @@ pub mod hir_build_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@7 - v3:BasicObject = GetLocal l0, SP@6 + v2:BasicObject = GetLocal :a, l0, SP@7 + v3:BasicObject = GetLocal :b, l0, SP@6 v4:NilClass = Const Value(nil) v5:NilClass = Const Value(nil) Jump bb2(v1, v2, v3, v4, v5) @@ -2137,8 +2137,8 @@ pub mod hir_build_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@7 - v3:BasicObject = GetLocal l0, SP@6 + v2:BasicObject = GetLocal :a, l0, SP@7 + v3:BasicObject = GetLocal :b, l0, SP@6 v4:NilClass = Const Value(nil) v5:NilClass = Const Value(nil) Jump bb2(v1, v2, v3, v4, v5) @@ -2153,7 +2153,7 @@ pub mod hir_build_tests { v30:StringExact = StringCopy v29 v36:StringExact[VALUE(0x1008)] = Const Value(VALUE(0x1008)) v37:StringExact = StringCopy v36 - v39:BasicObject = GetLocal l0, EP@3 + v39:BasicObject = GetLocal :buf, l0, EP@3 SideExit UnhandledNewarraySend(PACK_BUFFER) "); } @@ -2174,8 +2174,8 @@ pub mod hir_build_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@7 - v3:BasicObject = GetLocal l0, SP@6 + v2:BasicObject = GetLocal :a, l0, SP@7 + v3:BasicObject = GetLocal :b, l0, SP@6 v4:NilClass = Const Value(nil) v5:NilClass = Const Value(nil) Jump bb2(v1, v2, v3, v4, v5) @@ -2221,8 +2221,8 @@ pub mod hir_build_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@7 - v3:BasicObject = GetLocal l0, SP@6 + v2:BasicObject = GetLocal :a, l0, SP@7 + v3:BasicObject = GetLocal :b, l0, SP@6 v4:NilClass = Const Value(nil) v5:NilClass = Const Value(nil) Jump bb2(v1, v2, v3, v4, v5) @@ -2250,7 +2250,7 @@ pub mod hir_build_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :x, l0, SP@4 Jump bb2(v1, v2) bb1(v5:BasicObject, v6:BasicObject): EntryPoint JIT(0) @@ -2282,7 +2282,7 @@ pub mod hir_build_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :x, l0, SP@4 Jump bb2(v1, v2) bb1(v5:BasicObject, v6:BasicObject): EntryPoint JIT(0) @@ -2303,8 +2303,8 @@ pub mod hir_build_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@5 - v3:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :a, l0, SP@5 + v3:BasicObject = GetLocal :b, l0, SP@4 Jump bb2(v1, v2, v3) bb1(v6:BasicObject, v7:BasicObject, v8:BasicObject): EntryPoint JIT(0) @@ -2328,8 +2328,8 @@ pub mod hir_build_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@5 - v3:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :a, l0, SP@5 + v3:BasicObject = GetLocal :b, l0, SP@4 Jump bb2(v1, v2, v3) bb1(v6:BasicObject, v7:BasicObject, v8:BasicObject): EntryPoint JIT(0) @@ -2529,7 +2529,7 @@ pub mod hir_build_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :a, l0, SP@4 Jump bb2(v1, v2) bb1(v5:BasicObject, v6:BasicObject): EntryPoint JIT(0) @@ -2552,7 +2552,7 @@ pub mod hir_build_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :a, l0, SP@4 Jump bb2(v1, v2) bb1(v5:BasicObject, v6:BasicObject): EntryPoint JIT(0) @@ -2578,7 +2578,7 @@ pub mod hir_build_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :a, l0, SP@4 Jump bb2(v1, v2) bb1(v5:BasicObject, v6:BasicObject): EntryPoint JIT(0) @@ -2603,7 +2603,7 @@ pub mod hir_build_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :a, l0, SP@4 Jump bb2(v1, v2) bb1(v5:BasicObject, v6:BasicObject): EntryPoint JIT(0) @@ -2632,8 +2632,8 @@ pub mod hir_build_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@5 - v3:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :a, l0, SP@5 + v3:BasicObject = GetLocal :b, l0, SP@4 Jump bb2(v1, v2, v3) bb1(v6:BasicObject, v7:BasicObject, v8:BasicObject): EntryPoint JIT(0) @@ -2658,8 +2658,8 @@ pub mod hir_build_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@5 - v3:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :a, l0, SP@5 + v3:BasicObject = GetLocal :b, l0, SP@4 Jump bb2(v1, v2, v3) bb1(v6:BasicObject, v7:BasicObject, v8:BasicObject): EntryPoint JIT(0) @@ -2682,7 +2682,7 @@ pub mod hir_build_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :x, l0, SP@4 Jump bb2(v1, v2) bb1(v5:BasicObject, v6:BasicObject): EntryPoint JIT(0) @@ -2705,7 +2705,7 @@ pub mod hir_build_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :x, l0, SP@4 Jump bb2(v1, v2) bb1(v5:BasicObject, v6:BasicObject): EntryPoint JIT(0) @@ -2728,8 +2728,8 @@ pub mod hir_build_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@5 - v3:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :x, l0, SP@5 + v3:BasicObject = GetLocal :y, l0, SP@4 Jump bb2(v1, v2, v3) bb1(v6:BasicObject, v7:BasicObject, v8:BasicObject): EntryPoint JIT(0) @@ -2752,8 +2752,8 @@ pub mod hir_build_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@5 - v3:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :x, l0, SP@5 + v3:BasicObject = GetLocal :y, l0, SP@4 Jump bb2(v1, v2, v3) bb1(v6:BasicObject, v7:BasicObject, v8:BasicObject): EntryPoint JIT(0) @@ -2776,7 +2776,7 @@ pub mod hir_build_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :x, l0, SP@4 Jump bb2(v1, v2) bb1(v5:BasicObject, v6:BasicObject): EntryPoint JIT(0) @@ -2799,8 +2799,8 @@ pub mod hir_build_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@5 - v3:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :regexp, l0, SP@5 + v3:BasicObject = GetLocal :matchee, l0, SP@4 Jump bb2(v1, v2, v3) bb1(v6:BasicObject, v7:BasicObject, v8:BasicObject): EntryPoint JIT(0) @@ -2927,7 +2927,7 @@ pub mod hir_build_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :x, l0, SP@4 Jump bb2(v1, v2) bb1(v5:BasicObject, v6:BasicObject): EntryPoint JIT(0) @@ -2952,9 +2952,9 @@ pub mod hir_build_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@6 - v3:BasicObject = GetLocal l0, SP@5 - v4:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :arg, l0, SP@6 + v3:BasicObject = GetLocal :exception, l0, SP@5 + v4:BasicObject = GetLocal , l0, SP@4 Jump bb2(v1, v2, v3, v4) bb1(v7:BasicObject, v8:BasicObject, v9:BasicObject, v10:BasicObject): EntryPoint JIT(0) @@ -3000,10 +3000,10 @@ pub mod hir_build_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@8 - v3:BasicObject = GetLocal l0, SP@7 - v4:BasicObject = GetLocal l0, SP@6 - v5:BasicObject = GetLocal l0, SP@5 + v2:BasicObject = GetLocal :name, l0, SP@8 + v3:BasicObject = GetLocal :encoding, l0, SP@7 + v4:BasicObject = GetLocal , l0, SP@6 + v5:BasicObject = GetLocal :block, l0, SP@5 v6:NilClass = Const Value(nil) Jump bb2(v1, v2, v3, v4, v5, v6) bb1(v9:BasicObject, v10:BasicObject, v11:BasicObject, v12:BasicObject, v13:BasicObject): @@ -3063,10 +3063,10 @@ pub mod hir_build_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@7 - v3:BasicObject = GetLocal l0, SP@6 - v4:BasicObject = GetLocal l0, SP@5 - v5:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :full_mark, l0, SP@7 + v3:BasicObject = GetLocal :immediate_mark, l0, SP@6 + v4:BasicObject = GetLocal :immediate_sweep, l0, SP@5 + v5:BasicObject = GetLocal , l0, SP@4 Jump bb2(v1, v2, v3, v4, v5) bb1(v8:BasicObject, v9:BasicObject, v10:BasicObject, v11:BasicObject, v12:BasicObject): EntryPoint JIT(0) @@ -3134,7 +3134,7 @@ pub mod hir_build_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :x, l0, SP@4 Jump bb2(v1, v2) bb1(v5:BasicObject, v6:BasicObject): EntryPoint JIT(0) @@ -3369,8 +3369,8 @@ pub mod hir_build_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@5 - v3:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :x, l0, SP@5 + v3:BasicObject = GetLocal :y, l0, SP@4 Jump bb2(v1, v2, v3) bb1(v6:BasicObject, v7:BasicObject, v8:BasicObject): EntryPoint JIT(0) @@ -3395,7 +3395,7 @@ pub mod hir_build_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@6 + v2:BasicObject = GetLocal :o, l0, SP@6 v3:NilClass = Const Value(nil) v4:NilClass = Const Value(nil) Jump bb2(v1, v2, v3, v4) @@ -3431,7 +3431,7 @@ pub mod hir_build_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@6 + v2:BasicObject = GetLocal :o, l0, SP@6 v3:NilClass = Const Value(nil) v4:NilClass = Const Value(nil) Jump bb2(v1, v2, v3, v4) @@ -3458,7 +3458,7 @@ pub mod hir_build_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@7 + v2:BasicObject = GetLocal :o, l0, SP@7 v3:NilClass = Const Value(nil) v4:NilClass = Const Value(nil) v5:NilClass = Const Value(nil) @@ -3485,14 +3485,14 @@ pub mod hir_build_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@5 - v3:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :kw, l0, SP@5 + v3:BasicObject = GetLocal , l0, SP@4 Jump bb2(v1, v2, v3) bb1(v6:BasicObject, v7:BasicObject, v8:BasicObject): EntryPoint JIT(0) Jump bb2(v6, v7, v8) bb2(v10:BasicObject, v11:BasicObject, v12:BasicObject): - v15:BasicObject = GetLocal l0, EP@3 + v15:BasicObject = GetLocal , l0, EP@3 v16:BoolExact = FixnumBitCheck v15, 0 CheckInterrupts v19:CBool = Test v16 @@ -3526,40 +3526,40 @@ pub mod hir_build_tests { bb0(): EntryPoint interpreter v1:BasicObject = LoadSelf - v2:BasicObject = GetLocal l0, SP@37 - v3:BasicObject = GetLocal l0, SP@36 - v4:BasicObject = GetLocal l0, SP@35 - v5:BasicObject = GetLocal l0, SP@34 - v6:BasicObject = GetLocal l0, SP@33 - v7:BasicObject = GetLocal l0, SP@32 - v8:BasicObject = GetLocal l0, SP@31 - v9:BasicObject = GetLocal l0, SP@30 - v10:BasicObject = GetLocal l0, SP@29 - v11:BasicObject = GetLocal l0, SP@28 - v12:BasicObject = GetLocal l0, SP@27 - v13:BasicObject = GetLocal l0, SP@26 - v14:BasicObject = GetLocal l0, SP@25 - v15:BasicObject = GetLocal l0, SP@24 - v16:BasicObject = GetLocal l0, SP@23 - v17:BasicObject = GetLocal l0, SP@22 - v18:BasicObject = GetLocal l0, SP@21 - v19:BasicObject = GetLocal l0, SP@20 - v20:BasicObject = GetLocal l0, SP@19 - v21:BasicObject = GetLocal l0, SP@18 - v22:BasicObject = GetLocal l0, SP@17 - v23:BasicObject = GetLocal l0, SP@16 - v24:BasicObject = GetLocal l0, SP@15 - v25:BasicObject = GetLocal l0, SP@14 - v26:BasicObject = GetLocal l0, SP@13 - v27:BasicObject = GetLocal l0, SP@12 - v28:BasicObject = GetLocal l0, SP@11 - v29:BasicObject = GetLocal l0, SP@10 - v30:BasicObject = GetLocal l0, SP@9 - v31:BasicObject = GetLocal l0, SP@8 - v32:BasicObject = GetLocal l0, SP@7 - v33:BasicObject = GetLocal l0, SP@6 - v34:BasicObject = GetLocal l0, SP@5 - v35:BasicObject = GetLocal l0, SP@4 + v2:BasicObject = GetLocal :k1, l0, SP@37 + v3:BasicObject = GetLocal :k2, l0, SP@36 + v4:BasicObject = GetLocal :k3, l0, SP@35 + v5:BasicObject = GetLocal :k4, l0, SP@34 + v6:BasicObject = GetLocal :k5, l0, SP@33 + v7:BasicObject = GetLocal :k6, l0, SP@32 + v8:BasicObject = GetLocal :k7, l0, SP@31 + v9:BasicObject = GetLocal :k8, l0, SP@30 + v10:BasicObject = GetLocal :k9, l0, SP@29 + v11:BasicObject = GetLocal :k10, l0, SP@28 + v12:BasicObject = GetLocal :k11, l0, SP@27 + v13:BasicObject = GetLocal :k12, l0, SP@26 + v14:BasicObject = GetLocal :k13, l0, SP@25 + v15:BasicObject = GetLocal :k14, l0, SP@24 + v16:BasicObject = GetLocal :k15, l0, SP@23 + v17:BasicObject = GetLocal :k16, l0, SP@22 + v18:BasicObject = GetLocal :k17, l0, SP@21 + v19:BasicObject = GetLocal :k18, l0, SP@20 + v20:BasicObject = GetLocal :k19, l0, SP@19 + v21:BasicObject = GetLocal :k20, l0, SP@18 + v22:BasicObject = GetLocal :k21, l0, SP@17 + v23:BasicObject = GetLocal :k22, l0, SP@16 + v24:BasicObject = GetLocal :k23, l0, SP@15 + v25:BasicObject = GetLocal :k24, l0, SP@14 + v26:BasicObject = GetLocal :k25, l0, SP@13 + v27:BasicObject = GetLocal :k26, l0, SP@12 + v28:BasicObject = GetLocal :k27, l0, SP@11 + v29:BasicObject = GetLocal :k28, l0, SP@10 + v30:BasicObject = GetLocal :k29, l0, SP@9 + v31:BasicObject = GetLocal :k30, l0, SP@8 + v32:BasicObject = GetLocal :k31, l0, SP@7 + v33:BasicObject = GetLocal :k32, l0, SP@6 + v34:BasicObject = GetLocal :k33, l0, SP@5 + v35:BasicObject = GetLocal , l0, SP@4 Jump bb2(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35) bb1(v38:BasicObject, v39:BasicObject, v40:BasicObject, v41:BasicObject, v42:BasicObject, v43:BasicObject, v44:BasicObject, v45:BasicObject, v46:BasicObject, v47:BasicObject, v48:BasicObject, v49:BasicObject, v50:BasicObject, v51:BasicObject, v52:BasicObject, v53:BasicObject, v54:BasicObject, v55:BasicObject, v56:BasicObject, v57:BasicObject, v58:BasicObject, v59:BasicObject, v60:BasicObject, v61:BasicObject, v62:BasicObject, v63:BasicObject, v64:BasicObject, v65:BasicObject, v66:BasicObject, v67:BasicObject, v68:BasicObject, v69:BasicObject, v70:BasicObject, v71:BasicObject, v72:BasicObject): EntryPoint JIT(0) From 65995c22f892e103fdf2601fdccd0202483a4fca Mon Sep 17 00:00:00 2001 From: Benoit Daloze Date: Fri, 5 Dec 2025 23:08:48 +0100 Subject: [PATCH 22/24] [ruby/timeout] Exclude constantly-failing test on x86_64-darwin * https://github.com/ruby/ruby-dev-builder/actions/runs/19973218359/job/57293388626 https://github.com/ruby/timeout/commit/45816b1b26 --- test/test_timeout.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/test_timeout.rb b/test/test_timeout.rb index 3f94134fb04d9c..d6ae0c9b50b0ec 100644 --- a/test/test_timeout.rb +++ b/test/test_timeout.rb @@ -299,5 +299,6 @@ def test_ractor assert_equal :ok, r end; - end if defined?(::Ractor) && RUBY_VERSION >= '4.0' + end if defined?(::Ractor) && RUBY_VERSION >= '4.0' && !RUBY_PLATFORM.include?('x86_64-darwin') + # Exclude on x86_64-darwin as it failed 4 times out of 4 tries in the CI of ruby/ruby-dev-builder end From 791acc5697afc8f256e652169f7c85a3d90b3f06 Mon Sep 17 00:00:00 2001 From: Peter Zhu Date: Fri, 5 Dec 2025 17:08:20 -0500 Subject: [PATCH 23/24] Revert "gc.c: Pass shape_id to `newobj_init`" This reverts commit 228d13f6ed914d1e7f6bd2416e3f5be8283be865. This commit makes default.c and mmtk.c depend on shape.h, which prevents them from building independently. --- gc.c | 5 +++-- gc/default/default.c | 33 +++++++++++++++++---------------- gc/gc_impl.h | 2 +- gc/mmtk/mmtk.c | 5 ++--- shape.h | 9 ++------- 5 files changed, 25 insertions(+), 29 deletions(-) diff --git a/gc.c b/gc.c index 18badba00581d8..4f5f041fb348fb 100644 --- a/gc.c +++ b/gc.c @@ -622,7 +622,7 @@ typedef struct gc_function_map { void (*stress_set)(void *objspace_ptr, VALUE flag); VALUE (*stress_get)(void *objspace_ptr); // Object allocation - VALUE (*new_obj)(void *objspace_ptr, void *cache_ptr, VALUE klass, VALUE flags, shape_id_t shape_id, bool wb_protected, size_t alloc_size); + VALUE (*new_obj)(void *objspace_ptr, void *cache_ptr, VALUE klass, VALUE flags, bool wb_protected, size_t alloc_size); size_t (*obj_slot_size)(VALUE obj); size_t (*heap_id_for_size)(void *objspace_ptr, size_t size); bool (*size_allocatable_p)(size_t size); @@ -993,7 +993,8 @@ gc_validate_pc(VALUE obj) static inline VALUE newobj_of(rb_ractor_t *cr, VALUE klass, VALUE flags, shape_id_t shape_id, bool wb_protected, size_t size) { - VALUE obj = rb_gc_impl_new_obj(rb_gc_get_objspace(), cr->newobj_cache, klass, flags, shape_id, wb_protected, size); + VALUE obj = rb_gc_impl_new_obj(rb_gc_get_objspace(), cr->newobj_cache, klass, flags, wb_protected, size); + RBASIC_SET_SHAPE_ID_NO_CHECKS(obj, shape_id); gc_validate_pc(obj); diff --git a/gc/default/default.c b/gc/default/default.c index f8fd40b44fd8b4..a03fda859cf4ca 100644 --- a/gc/default/default.c +++ b/gc/default/default.c @@ -32,7 +32,6 @@ #include "darray.h" #include "gc/gc.h" #include "gc/gc_impl.h" -#include "shape.h" #ifndef BUILDING_MODULAR_GC # include "probes.h" @@ -2148,13 +2147,15 @@ rb_gc_impl_source_location_cstr(int *ptr) #endif static inline VALUE -newobj_init(VALUE klass, VALUE flags, shape_id_t shape_id, int wb_protected, rb_objspace_t *objspace, VALUE obj) +newobj_init(VALUE klass, VALUE flags, int wb_protected, rb_objspace_t *objspace, VALUE obj) { GC_ASSERT(BUILTIN_TYPE(obj) == T_NONE); GC_ASSERT((flags & FL_WB_PROTECTED) == 0); RBASIC(obj)->flags = flags; *((VALUE *)&RBASIC(obj)->klass) = klass; - RBASIC_SET_SHAPE_ID_NO_CHECKS(obj, shape_id); +#if RBASIC_SHAPE_ID_FIELD + RBASIC(obj)->shape_id = 0; +#endif int t = flags & RUBY_T_MASK; if (t == T_CLASS || t == T_MODULE || t == T_ICLASS) { @@ -2438,10 +2439,10 @@ newobj_alloc(rb_objspace_t *objspace, rb_ractor_newobj_cache_t *cache, size_t he return obj; } -ALWAYS_INLINE(static VALUE newobj_slowpath(VALUE klass, VALUE flags, shape_id_t shape_id, rb_objspace_t *objspace, rb_ractor_newobj_cache_t *cache, int wb_protected, size_t heap_idx)); +ALWAYS_INLINE(static VALUE newobj_slowpath(VALUE klass, VALUE flags, rb_objspace_t *objspace, rb_ractor_newobj_cache_t *cache, int wb_protected, size_t heap_idx)); static inline VALUE -newobj_slowpath(VALUE klass, VALUE flags, shape_id_t shape_id, rb_objspace_t *objspace, rb_ractor_newobj_cache_t *cache, int wb_protected, size_t heap_idx) +newobj_slowpath(VALUE klass, VALUE flags, rb_objspace_t *objspace, rb_ractor_newobj_cache_t *cache, int wb_protected, size_t heap_idx) { VALUE obj; unsigned int lev; @@ -2466,32 +2467,32 @@ newobj_slowpath(VALUE klass, VALUE flags, shape_id_t shape_id, rb_objspace_t *ob } obj = newobj_alloc(objspace, cache, heap_idx, true); - newobj_init(klass, flags, shape_id, wb_protected, objspace, obj); + newobj_init(klass, flags, wb_protected, objspace, obj); } RB_GC_CR_UNLOCK(lev); return obj; } -NOINLINE(static VALUE newobj_slowpath_wb_protected(VALUE klass, VALUE flags, shape_id_t shape_id, +NOINLINE(static VALUE newobj_slowpath_wb_protected(VALUE klass, VALUE flags, rb_objspace_t *objspace, rb_ractor_newobj_cache_t *cache, size_t heap_idx)); -NOINLINE(static VALUE newobj_slowpath_wb_unprotected(VALUE klass, VALUE flags, shape_id_t shape_id, +NOINLINE(static VALUE newobj_slowpath_wb_unprotected(VALUE klass, VALUE flags, rb_objspace_t *objspace, rb_ractor_newobj_cache_t *cache, size_t heap_idx)); static VALUE -newobj_slowpath_wb_protected(VALUE klass, VALUE flags, shape_id_t shape_id, rb_objspace_t *objspace, rb_ractor_newobj_cache_t *cache, size_t heap_idx) +newobj_slowpath_wb_protected(VALUE klass, VALUE flags, rb_objspace_t *objspace, rb_ractor_newobj_cache_t *cache, size_t heap_idx) { - return newobj_slowpath(klass, flags, shape_id, objspace, cache, TRUE, heap_idx); + return newobj_slowpath(klass, flags, objspace, cache, TRUE, heap_idx); } static VALUE -newobj_slowpath_wb_unprotected(VALUE klass, VALUE flags, shape_id_t shape_id, rb_objspace_t *objspace, rb_ractor_newobj_cache_t *cache, size_t heap_idx) +newobj_slowpath_wb_unprotected(VALUE klass, VALUE flags, rb_objspace_t *objspace, rb_ractor_newobj_cache_t *cache, size_t heap_idx) { - return newobj_slowpath(klass, flags, shape_id, objspace, cache, FALSE, heap_idx); + return newobj_slowpath(klass, flags, objspace, cache, FALSE, heap_idx); } VALUE -rb_gc_impl_new_obj(void *objspace_ptr, void *cache_ptr, VALUE klass, VALUE flags, shape_id_t shape_id, bool wb_protected, size_t alloc_size) +rb_gc_impl_new_obj(void *objspace_ptr, void *cache_ptr, VALUE klass, VALUE flags, bool wb_protected, size_t alloc_size) { VALUE obj; rb_objspace_t *objspace = objspace_ptr; @@ -2512,14 +2513,14 @@ rb_gc_impl_new_obj(void *objspace_ptr, void *cache_ptr, VALUE klass, VALUE flags if (!RB_UNLIKELY(during_gc || ruby_gc_stressful) && wb_protected) { obj = newobj_alloc(objspace, cache, heap_idx, false); - newobj_init(klass, flags, shape_id, wb_protected, objspace, obj); + newobj_init(klass, flags, wb_protected, objspace, obj); } else { RB_DEBUG_COUNTER_INC(obj_newobj_slowpath); obj = wb_protected ? - newobj_slowpath_wb_protected(klass, flags, shape_id, objspace, cache, heap_idx) : - newobj_slowpath_wb_unprotected(klass, flags, shape_id, objspace, cache, heap_idx); + newobj_slowpath_wb_protected(klass, flags, objspace, cache, heap_idx) : + newobj_slowpath_wb_unprotected(klass, flags, objspace, cache, heap_idx); } return obj; diff --git a/gc/gc_impl.h b/gc/gc_impl.h index 65c0586d46bfad..3250483639e775 100644 --- a/gc/gc_impl.h +++ b/gc/gc_impl.h @@ -55,7 +55,7 @@ GC_IMPL_FN VALUE rb_gc_impl_stress_get(void *objspace_ptr); GC_IMPL_FN VALUE rb_gc_impl_config_get(void *objspace_ptr); GC_IMPL_FN void rb_gc_impl_config_set(void *objspace_ptr, VALUE hash); // Object allocation -GC_IMPL_FN VALUE rb_gc_impl_new_obj(void *objspace_ptr, void *cache_ptr, VALUE klass, VALUE flags, uint32_t /* shape_id_t */ shape_id, bool wb_protected, size_t alloc_size); +GC_IMPL_FN VALUE rb_gc_impl_new_obj(void *objspace_ptr, void *cache_ptr, VALUE klass, VALUE flags, bool wb_protected, size_t alloc_size); GC_IMPL_FN size_t rb_gc_impl_obj_slot_size(VALUE obj); GC_IMPL_FN size_t rb_gc_impl_heap_id_for_size(void *objspace_ptr, size_t size); GC_IMPL_FN bool rb_gc_impl_size_allocatable_p(size_t size); diff --git a/gc/mmtk/mmtk.c b/gc/mmtk/mmtk.c index a3bdf1cd4a9a42..e1678dcf6ab0b4 100644 --- a/gc/mmtk/mmtk.c +++ b/gc/mmtk/mmtk.c @@ -7,7 +7,6 @@ #include "gc/gc.h" #include "gc/gc_impl.h" -#include "shape.h" #include "gc/mmtk/mmtk.h" #include "ccan/list/list.h" @@ -604,7 +603,7 @@ rb_gc_impl_config_set(void *objspace_ptr, VALUE hash) // Object allocation VALUE -rb_gc_impl_new_obj(void *objspace_ptr, void *cache_ptr, VALUE klass, VALUE flags, shape_id_t shape_id, bool wb_protected, size_t alloc_size) +rb_gc_impl_new_obj(void *objspace_ptr, void *cache_ptr, VALUE klass, VALUE flags, bool wb_protected, size_t alloc_size) { #define MMTK_ALLOCATION_SEMANTICS_DEFAULT 0 struct objspace *objspace = objspace_ptr; @@ -626,7 +625,7 @@ rb_gc_impl_new_obj(void *objspace_ptr, void *cache_ptr, VALUE klass, VALUE flags VALUE *alloc_obj = mmtk_alloc(ractor_cache->mutator, alloc_size + 8, MMTk_MIN_OBJ_ALIGN, 0, MMTK_ALLOCATION_SEMANTICS_DEFAULT); alloc_obj++; alloc_obj[-1] = alloc_size; - alloc_obj[0] = RSHAPE_COMBINE_IN_FLAGS(flags, shape_id);; + alloc_obj[0] = flags; alloc_obj[1] = klass; mmtk_post_alloc(ractor_cache->mutator, (void*)alloc_obj, alloc_size + 8, MMTK_ALLOCATION_SEMANTICS_DEFAULT); diff --git a/shape.h b/shape.h index bebfaba608c7fa..af6add9e08158a 100644 --- a/shape.h +++ b/shape.h @@ -162,12 +162,6 @@ RBASIC_SHAPE_ID_FOR_READ(VALUE obj) bool rb_shape_verify_consistency(VALUE obj, shape_id_t shape_id); #endif -static inline VALUE -RSHAPE_COMBINE_IN_FLAGS(VALUE flags, shape_id_t shape_id) -{ - return (flags &SHAPE_FLAG_MASK) | (((VALUE)shape_id) << SHAPE_FLAG_SHIFT); -} - static inline void RBASIC_SET_SHAPE_ID_NO_CHECKS(VALUE obj, shape_id_t shape_id) { @@ -175,7 +169,8 @@ RBASIC_SET_SHAPE_ID_NO_CHECKS(VALUE obj, shape_id_t shape_id) RBASIC(obj)->shape_id = (VALUE)shape_id; #else // Object shapes are occupying top bits - RBASIC(obj)->flags = RSHAPE_COMBINE_IN_FLAGS(RBASIC(obj)->flags, shape_id); + RBASIC(obj)->flags &= SHAPE_FLAG_MASK; + RBASIC(obj)->flags |= ((VALUE)(shape_id) << SHAPE_FLAG_SHIFT); #endif } From 8f9838476dc8cc857859a0a93da285d792be7d3b Mon Sep 17 00:00:00 2001 From: Peter Zhu Date: Fri, 5 Dec 2025 17:58:11 -0500 Subject: [PATCH 24/24] Fix fields object in embedded struct We don't set RSTRUCT_GEN_FIELDS when RCLASS_MAX_IV_COUNT(klass) != 0, so we need to set RSTRUCT_SET_FIELDS_OBJ to 0 otherwise it may have an invalid value and crash. --- struct.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/struct.c b/struct.c index a6155d4684249f..667d35424fb8d1 100644 --- a/struct.c +++ b/struct.c @@ -826,12 +826,17 @@ struct_alloc(VALUE klass) } NEWOBJ_OF(st, struct RStruct, klass, flags, embedded_size, 0); - if (RCLASS_MAX_IV_COUNT(klass) == 0 - && !rb_shape_obj_has_fields((VALUE)st) - && embedded_size < rb_gc_obj_slot_size((VALUE)st)) { - FL_UNSET_RAW((VALUE)st, RSTRUCT_GEN_FIELDS); + if (RCLASS_MAX_IV_COUNT(klass) == 0) { + if (!rb_shape_obj_has_fields((VALUE)st) + && embedded_size < rb_gc_obj_slot_size((VALUE)st)) { + FL_UNSET_RAW((VALUE)st, RSTRUCT_GEN_FIELDS); + RSTRUCT_SET_FIELDS_OBJ((VALUE)st, 0); + } + } + else { RSTRUCT_SET_FIELDS_OBJ((VALUE)st, 0); } + rb_mem_clear((VALUE *)st->as.ary, n); return (VALUE)st;