summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--yjit_codegen.c125
-rw-r--r--yjit_iface.h1
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
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(
getivar_se_self_not_heap,
getivar_idx_out_of_range,
- getivar_name_not_mapped,
setivar_se_self_not_heap,
setivar_idx_out_of_range,