diff options
-rw-r--r-- | compile.c | 24 | ||||
-rw-r--r-- | iseq.c | 25 | ||||
-rw-r--r-- | mjit_c.rb | 1 | ||||
-rw-r--r-- | vm_core.h | 1 | ||||
-rw-r--r-- | yjit/src/cruby_bindings.inc.rs | 1 |
5 files changed, 31 insertions, 21 deletions
@@ -2461,7 +2461,17 @@ iseq_set_sequence(rb_iseq_t *iseq, LINK_ANCHOR *const anchor) case TS_IVC: /* inline ivar cache */ { unsigned int ic_index = FIX2UINT(operands[j]); - vm_ic_attr_index_initialize(((IVC)&body->is_entries[ic_index]), INVALID_SHAPE_ID); + + IVC cache = ((IVC)&body->is_entries[ic_index]); + + if (insn == BIN(setinstancevariable)) { + cache->iv_set_name = SYM2ID(operands[j - 1]); + } + else { + cache->iv_set_name = 0; + } + + vm_ic_attr_index_initialize(cache, INVALID_SHAPE_ID); } case TS_ISE: /* inline storage entry: `once` insn */ case TS_ICVARC: /* inline cvar cache */ @@ -11529,7 +11539,17 @@ ibf_load_code(const struct ibf_load *load, rb_iseq_t *iseq, ibf_offset_t bytecod code[code_index] = (VALUE)ic; if (operand_type == TS_IVC) { - vm_ic_attr_index_initialize(((IVC)code[code_index]), INVALID_SHAPE_ID); + IVC cache = (IVC)ic; + + if (insn == BIN(setinstancevariable)) { + ID iv_name = (ID)code[code_index - 1]; + cache->iv_set_name = iv_name; + } + else { + cache->iv_set_name = 0; + } + + vm_ic_attr_index_initialize(cache, INVALID_SHAPE_ID); } } @@ -2509,33 +2509,20 @@ rb_iseq_disasm(const rb_iseq_t *iseq) attr_index_t rb_estimate_iv_count(VALUE klass, const rb_iseq_t * initialize_iseq) { - bool calls_super = false; - struct rb_id_table * iv_names = rb_id_table_create(0); - VALUE * code = ISEQ_BODY(initialize_iseq)->iseq_encoded; - - for (unsigned int i = 0; i < ISEQ_BODY(initialize_iseq)->iseq_size; ) { - VALUE insn = code[i]; - int original_insn = rb_vm_insn_addr2insn((const void *)insn); + for (unsigned int i = 0; i < ISEQ_BODY(initialize_iseq)->ivc_size; i++) { + IVC cache = (IVC)&ISEQ_BODY(initialize_iseq)->is_entries[i]; - if (BIN(setinstancevariable) == original_insn) { - ID name = (ID)code[i + 1]; - rb_id_table_insert(iv_names, name, Qtrue); + if (cache->iv_set_name) { + rb_id_table_insert(iv_names, cache->iv_set_name, Qtrue); } - else if (BIN(invokesuper) == original_insn) { - calls_super = true; - } - - i += insn_len(original_insn); } attr_index_t count = (attr_index_t)rb_id_table_size(iv_names); - if (calls_super) { - VALUE superclass = rb_class_superclass(klass); - count += RCLASS_EXT(superclass)->max_iv_count; - } + VALUE superclass = rb_class_superclass(klass); + count += RCLASS_EXT(superclass)->max_iv_count; rb_id_table_free(iv_names); @@ -310,6 +310,7 @@ module RubyVM::MJIT @iseq_inline_iv_cache_entry ||= CType::Struct.new( "iseq_inline_iv_cache_entry", Primitive.cexpr!("SIZEOF(struct iseq_inline_iv_cache_entry)"), value: [CType::Immediate.parse("uintptr_t"), Primitive.cexpr!("OFFSETOF((*((struct iseq_inline_iv_cache_entry *)NULL)), value)")], + iv_set_name: [self.ID, Primitive.cexpr!("OFFSETOF((*((struct iseq_inline_iv_cache_entry *)NULL)), iv_set_name)")], ) end @@ -275,6 +275,7 @@ struct iseq_inline_constant_cache { struct iseq_inline_iv_cache_entry { uintptr_t value; // attr_index in lower bits, dest_shape_id in upper bits + ID iv_set_name; }; struct iseq_inline_cvar_cache_entry { diff --git a/yjit/src/cruby_bindings.inc.rs b/yjit/src/cruby_bindings.inc.rs index 470b6d0a5b..1555196a06 100644 --- a/yjit/src/cruby_bindings.inc.rs +++ b/yjit/src/cruby_bindings.inc.rs @@ -853,6 +853,7 @@ pub struct iseq_inline_constant_cache { #[derive(Debug, Copy, Clone)] pub struct iseq_inline_iv_cache_entry { pub value: usize, + pub iv_set_name: ID, } #[repr(C)] #[derive(Debug, Copy, Clone)] |