[前][次][番号順一覧][スレッド一覧]

ruby-changes:69133

From: Maxime <ko1@a...>
Date: Thu, 21 Oct 2021 08:20:57 +0900 (JST)
Subject: [ruby-changes:69133] b3e993a64b (master): Make sure that there is always an index table entry for getivars

https://git.ruby-lang.org/ruby.git/commit/?id=b3e993a64b

From b3e993a64bb10e20280a7a5c604f9f0fe3939a4b Mon Sep 17 00:00:00 2001
From: Maxime Chevalier-Boisvert <maxime.chevalierboisvert@s...>
Date: Wed, 25 Aug 2021 16:10:05 -0400
Subject: Make sure that there is always an index table entry for getivars

---
 yjit_codegen.c | 125 +++++++++++++++++++++++++++++----------------------------
 yjit_iface.h   |   1 -
 2 files changed, 63 insertions(+), 63 deletions(-)

diff --git a/yjit_codegen.c b/yjit_codegen.c
index a5f39d273b..aaac15b1cb 100644
--- a/yjit_codegen.c
+++ b/yjit_codegen.c
@@ -1442,82 +1442,83 @@ gen_get_ivar(jitstate_t *jit, ctx_t *ctx, const int max_chain_depth, VALUE compt https://github.com/ruby/ruby/blob/trunk/yjit_codegen.c#L1442
     struct rb_iv_index_tbl_entry *ent;
     struct st_table *iv_index_tbl = ROBJECT_IV_INDEX_TBL(comptime_receiver);
 
-    // Lookup index for the ivar the instruction loads
-    if (iv_index_tbl && rb_iv_index_tbl_lookup(iv_index_tbl, id, &ent)) {
-        uint32_t ivar_index = ent->index;
+    // Make sure there is a mapping for this ivar in the index table
+    if (!iv_index_tbl || !rb_iv_index_tbl_lookup(iv_index_tbl, id, &ent)) {
+        rb_ivar_set(comptime_receiver, id, Qundef);
+        iv_index_tbl = ROBJECT_IV_INDEX_TBL(comptime_receiver);
+        RUBY_ASSERT(iv_index_tbl && rb_iv_index_tbl_lookup(iv_index_tbl, id, &ent));
+    }
 
-        // Pop receiver if it's on the temp stack
-        if (!reg0_opnd.is_self) {
-            (void)ctx_stack_pop(ctx, 1);
-        }
+    uint32_t ivar_index = ent->index;
 
-        // Compile time self is embedded and the ivar index lands within the object
-        if (RB_FL_TEST_RAW(comptime_receiver, ROBJECT_EMBED) && ivar_index < ROBJECT_EMBED_LEN_MAX) {
-            // See ROBJECT_IVPTR() from include/ruby/internal/core/robject.h
+    // Pop receiver if it's on the temp stack
+    if (!reg0_opnd.is_self) {
+        (void)ctx_stack_pop(ctx, 1);
+    }
 
-            // Guard that self is embedded
-            // TODO: BT and JC is shorter
-            ADD_COMMENT(cb, "guard embedded getivar");
-            x86opnd_t flags_opnd = member_opnd(REG0, struct RBasic, flags);
-            test(cb, flags_opnd, imm_opnd(ROBJECT_EMBED));
-            jit_chain_guard(JCC_JZ, jit, &starting_context, max_chain_depth, side_exit);
+    // Compile time self is embedded and the ivar index lands within the object
+    if (RB_FL_TEST_RAW(comptime_receiver, ROBJECT_EMBED) && ivar_index < ROBJECT_EMBED_LEN_MAX) {
+        // See ROBJECT_IVPTR() from include/ruby/internal/core/robject.h
 
-            // Load the variable
-            x86opnd_t ivar_opnd = mem_opnd(64, REG0, offsetof(struct RObject, as.ary) + ivar_index * SIZEOF_VALUE);
-            mov(cb, REG1, ivar_opnd);
+        // Guard that self is embedded
+        // TODO: BT and JC is shorter
+        ADD_COMMENT(cb, "guard embedded getivar");
+        x86opnd_t flags_opnd = member_opnd(REG0, struct RBasic, flags);
+        test(cb, flags_opnd, imm_opnd(ROBJECT_EMBED));
+        jit_chain_guard(JCC_JZ, jit, &starting_context, max_chain_depth, side_exit);
 
-            // Guard that the variable is not Qundef
-            cmp(cb, REG1, imm_opnd(Qundef));
-            mov(cb, REG0, imm_opnd(Qnil));
-            cmove(cb, REG1, REG0);
+        // Load the variable
+        x86opnd_t ivar_opnd = mem_opnd(64, REG0, offsetof(struct RObject, as.ary) + ivar_index * SIZEOF_VALUE);
+        mov(cb, REG1, ivar_opnd);
 
-            // Push the ivar on the stack
-            x86opnd_t out_opnd = ctx_stack_push(ctx, TYPE_UNKNOWN);
-            mov(cb, out_opnd, REG1);
-        }
-        else {
-            // Compile time value is *not* embeded.
+        // Guard that the variable is not Qundef
+        cmp(cb, REG1, imm_opnd(Qundef));
+        mov(cb, REG0, imm_opnd(Qnil));
+        cmove(cb, REG1, REG0);
 
-            // Guard that value is *not* embedded
-            // See ROBJECT_IVPTR() from include/ruby/internal/core/robject.h
-            ADD_COMMENT(cb, "guard extended getivar");
-            x86opnd_t flags_opnd = member_opnd(REG0, struct RBasic, flags);
-            test(cb, flags_opnd, imm_opnd(ROBJECT_EMBED));
-            jit_chain_guard(JCC_JNZ, jit, &starting_context, max_chain_depth, side_exit);
-
-            // check that the extended table is big enough
-            if (ivar_index >= ROBJECT_EMBED_LEN_MAX + 1) {
-                // Check that the slot is inside the extended table (num_slots > index)
-                x86opnd_t num_slots = mem_opnd(32, REG0, offsetof(struct RObject, as.heap.numiv));
-                cmp(cb, num_slots, imm_opnd(ivar_index));
-                jle_ptr(cb, COUNTED_EXIT(side_exit, getivar_idx_out_of_range));
-            }
+        // Push the ivar on the stack
+        x86opnd_t out_opnd = ctx_stack_push(ctx, TYPE_UNKNOWN);
+        mov(cb, out_opnd, REG1);
+    }
+    else {
+        // Compile time value is *not* embeded.
 
-            // Get a pointer to the extended table
-            x86opnd_t tbl_opnd = mem_opnd(64, REG0, offsetof(struct RObject, as.heap.ivptr));
-            mov(cb, REG0, tbl_opnd);
+        // Guard that value is *not* embedded
+        // See ROBJECT_IVPTR() from include/ruby/internal/core/robject.h
+        ADD_COMMENT(cb, "guard extended getivar");
+        x86opnd_t flags_opnd = member_opnd(REG0, struct RBasic, flags);
+        test(cb, flags_opnd, imm_opnd(ROBJECT_EMBED));
+        jit_chain_guard(JCC_JNZ, jit, &starting_context, max_chain_depth, side_exit);
+
+        // check that the extended table is big enough
+        if (ivar_index >= ROBJECT_EMBED_LEN_MAX + 1) {
+            // Check that the slot is inside the extended table (num_slots > index)
+            x86opnd_t num_slots = mem_opnd(32, REG0, offsetof(struct RObject, as.heap.numiv));
+            cmp(cb, num_slots, imm_opnd(ivar_index));
+            jle_ptr(cb, COUNTED_EXIT(side_exit, getivar_idx_out_of_range));
+        }
 
-            // Read the ivar from the extended table
-            x86opnd_t ivar_opnd = mem_opnd(64, REG0, sizeof(VALUE) * ivar_index);
-            mov(cb, REG0, ivar_opnd);
+        // Get a pointer to the extended table
+        x86opnd_t tbl_opnd = mem_opnd(64, REG0, offsetof(struct RObject, as.heap.ivptr));
+        mov(cb, REG0, tbl_opnd);
 
-            // Check that the ivar is not Qundef
-            cmp(cb, REG0, imm_opnd(Qundef));
-            mov(cb, REG1, imm_opnd(Qnil));
-            cmove(cb, REG0, REG1);
+        // Read the ivar from the extended table
+        x86opnd_t ivar_opnd = mem_opnd(64, REG0, sizeof(VALUE) * ivar_index);
+        mov(cb, REG0, ivar_opnd);
 
-            // Push the ivar on the stack
-            x86opnd_t out_opnd = ctx_stack_push(ctx, TYPE_UNKNOWN);
-            mov(cb, out_opnd, REG0);
-        }
+        // Check that the ivar is not Qundef
+        cmp(cb, REG0, imm_opnd(Qundef));
+        mov(cb, REG1, imm_opnd(Qnil));
+        cmove(cb, REG0, REG1);
 
-        // Jump to next instruction. This allows guard chains to share the same successor.
-        jit_jump_to_next_insn(jit, ctx);
-        return YJIT_END_BLOCK;
+        // Push the ivar on the stack
+        x86opnd_t out_opnd = ctx_stack_push(ctx, TYPE_UNKNOWN);
+        mov(cb, out_opnd, REG0);
     }
 
-    GEN_COUNTER_INC(cb, getivar_name_not_mapped);
-    return YJIT_CANT_COMPILE;
+    // Jump to next instruction. This allows guard chains to share the same successor.
+    jit_jump_to_next_insn(jit, ctx);
+    return YJIT_END_BLOCK;
 }
 
 static codegen_status_t
diff --git a/yjit_iface.h b/yjit_iface.h
index 6f7aa69cea..c253153321 100644
--- a/yjit_iface.h
+++ b/yjit_iface.h
@@ -69,7 +69,6 @@ YJIT_DECLARE_COUNTERS( https://github.com/ruby/ruby/blob/trunk/yjit_iface.h#L69
 
     getivar_se_self_not_heap,
     getivar_idx_out_of_range,
-    getivar_name_not_mapped,
 
     setivar_se_self_not_heap,
     setivar_idx_out_of_range,
-- 
cgit v1.2.1


--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]