diff options
author | Satoshi Tagomori <[email protected]> | 2025-04-30 13:48:02 +0900 |
---|---|---|
committer | Satoshi Tagomori <[email protected]> | 2025-05-11 23:32:50 +0900 |
commit | 382645d440d5da66a0c04557f3ff2ca226de3a27 () | |
tree | b7453449930197237e739d0985561b664f51b0f3 /vm_method.c | |
parent | 49742414f6444960838bb968bab43db27f5872c1 (diff) |
namespace on read
-rw-r--r-- | vm_method.c | 197 |
1 files changed, 152 insertions, 45 deletions
@@ -39,7 +39,7 @@ vm_ccs_dump_i(ID mid, VALUE val, void *data) static void vm_ccs_dump(VALUE klass, ID target_mid) { - struct rb_id_table *cc_tbl = RCLASS_CC_TBL(klass); if (cc_tbl) { VALUE ccs; if (target_mid) { @@ -87,18 +87,18 @@ vm_mtbl_dump(VALUE klass, ID target_mid) else { fprintf(stderr, " MTBL: NULL\n"); } - if (RCLASS_CALLABLE_M_TBL(klass)) { if (target_mid != 0) { - if (rb_id_table_lookup(RCLASS_CALLABLE_M_TBL(klass), target_mid, &me)) { rp_m(" [CM**] ", me); } } else { fprintf(stderr, " ## RCLASS_CALLABLE_M_TBL\n"); - rb_id_table_foreach(RCLASS_CALLABLE_M_TBL(klass), vm_cme_dump_i, NULL); } } - if (RCLASS_CC_TBL(klass)) { vm_ccs_dump(klass, target_mid); } klass = RCLASS_SUPER(klass); @@ -166,6 +166,78 @@ const rb_method_entry_t * rb_method_entry_clone(const rb_method_entry_t *src_me) static const rb_callable_method_entry_t *complemented_callable_method_entry(VALUE klass, ID id); static const rb_callable_method_entry_t *lookup_overloaded_cme(const rb_callable_method_entry_t *cme); static void clear_method_cache_by_id_in_class(VALUE klass, ID mid) @@ -174,33 +246,24 @@ clear_method_cache_by_id_in_class(VALUE klass, ID mid) if (rb_objspace_garbage_object_p(klass)) return; RB_VM_LOCK_ENTER(); - if (LIKELY(RCLASS_SUBCLASSES(klass) == NULL)) { // no subclasses // check only current class - struct rb_id_table *cc_tbl = RCLASS_CC_TBL(klass); - VALUE ccs_data; - // invalidate CCs - if (cc_tbl && rb_id_table_lookup(cc_tbl, mid, &ccs_data)) { - struct rb_class_cc_entries *ccs = (struct rb_class_cc_entries *)ccs_data; - rb_yjit_cme_invalidate((rb_callable_method_entry_t *)ccs->cme); - if (NIL_P(ccs->cme->owner)) invalidate_negative_cache(mid); - rb_vm_ccs_free(ccs); - rb_id_table_delete(cc_tbl, mid); - RB_DEBUG_COUNTER_INC(cc_invalidate_leaf_ccs); } // remove from callable_m_tbl, if exists - struct rb_id_table *cm_tbl; - if ((cm_tbl = RCLASS_CALLABLE_M_TBL(klass)) != NULL) { - VALUE cme; - if (rb_yjit_enabled_p && rb_id_table_lookup(cm_tbl, mid, &cme)) { - rb_yjit_cme_invalidate((rb_callable_method_entry_t *)cme); - } - rb_id_table_delete(cm_tbl, mid); - RB_DEBUG_COUNTER_INC(cc_invalidate_leaf_callable); } RB_DEBUG_COUNTER_INC(cc_invalidate_leaf); } else { @@ -223,10 +286,9 @@ clear_method_cache_by_id_in_class(VALUE klass, ID mid) else { klass_housing_cme = RCLASS_ORIGIN(owner); } - // replace the cme that will be invalid - VM_ASSERT(lookup_method_table(klass_housing_cme, mid) == (const rb_method_entry_t *)cme); - const rb_method_entry_t *new_cme = rb_method_entry_clone((const rb_method_entry_t *)cme); - rb_method_table_insert(klass_housing_cme, RCLASS_M_TBL(klass_housing_cme), mid, new_cme); } vm_cme_invalidate((rb_callable_method_entry_t *)cme); @@ -234,7 +296,7 @@ clear_method_cache_by_id_in_class(VALUE klass, ID mid) // In case of refinement ME, also invalidate the wrapped ME that // could be cached at some callsite and is unreachable from any - // RCLASS_CC_TBL. if (cme->def->type == VM_METHOD_TYPE_REFINED && cme->def->body.refined.orig_me) { vm_cme_invalidate((rb_callable_method_entry_t *)cme->def->body.refined.orig_me); } @@ -250,11 +312,12 @@ clear_method_cache_by_id_in_class(VALUE klass, ID mid) // invalidate complement tbl if (METHOD_ENTRY_COMPLEMENTED(cme)) { VALUE defined_class = cme->defined_class; - struct rb_id_table *cm_tbl = RCLASS_CALLABLE_M_TBL(defined_class); - VM_ASSERT(cm_tbl != NULL); - int r = rb_id_table_delete(cm_tbl, mid); - VM_ASSERT(r == TRUE); (void)r; - RB_DEBUG_COUNTER_INC(cc_invalidate_tree_callable); } RB_DEBUG_COUNTER_INC(cc_invalidate_tree); @@ -263,6 +326,9 @@ clear_method_cache_by_id_in_class(VALUE klass, ID mid) invalidate_negative_cache(mid); } } RB_VM_LOCK_LEAVE(); } @@ -302,6 +368,32 @@ rb_clear_method_cache(VALUE klass_or_module, ID mid) } } static int invalidate_all_refinement_cc(void *vstart, void *vend, size_t stride, void *data) { @@ -447,12 +539,17 @@ rb_clear_all_refinement_method_cache(void) void rb_method_table_insert(VALUE klass, struct rb_id_table *table, ID method_id, const rb_method_entry_t *me) { VALUE table_owner = klass; - if (RB_TYPE_P(klass, T_ICLASS) && !RICLASS_OWNS_M_TBL_P(klass)) { table_owner = RBASIC(table_owner)->klass; } VM_ASSERT_TYPE3(table_owner, T_CLASS, T_ICLASS, T_MODULE); - VM_ASSERT(table == RCLASS_M_TBL(table_owner)); rb_id_table_insert(table, method_id, (VALUE)me); RB_OBJ_WRITTEN(table_owner, Qundef, (VALUE)me); } @@ -760,6 +857,7 @@ rb_method_definition_create(rb_method_type_t type, ID mid) def->original_id = mid; static uintptr_t method_serial = 1; def->method_serial = method_serial++; return def; } @@ -1003,7 +1101,7 @@ rb_method_entry_make(VALUE klass, ID mid, VALUE defined_class, rb_method_visibil rb_clear_method_cache(orig_klass, mid); } } - mtbl = RCLASS_M_TBL(klass); /* check re-definition */ if (rb_id_table_lookup(mtbl, mid, &data)) { @@ -1331,7 +1429,11 @@ search_method0(VALUE klass, ID id, VALUE *defined_class_ptr, bool skip_refined) if (me == NULL) RB_DEBUG_COUNTER_INC(mc_search_notfound); - VM_ASSERT(me == NULL || !METHOD_ENTRY_INVALIDATED(me)); return me; } @@ -1366,23 +1468,27 @@ prepare_callable_method_entry(VALUE defined_class, ID id, const rb_method_entry_ struct rb_id_table *mtbl; const rb_callable_method_entry_t *cme; VALUE cme_data; if (me) { if (me->defined_class == 0) { RB_DEBUG_COUNTER_INC(mc_cme_complement); VM_ASSERT_TYPE2(defined_class, T_ICLASS, T_MODULE); - mtbl = RCLASS_CALLABLE_M_TBL(defined_class); - if (mtbl && rb_id_table_lookup(mtbl, id, &cme_data)) { cme = (rb_callable_method_entry_t *)cme_data; RB_DEBUG_COUNTER_INC(mc_cme_complement_hit); VM_ASSERT(callable_method_entry_p(cme)); VM_ASSERT(!METHOD_ENTRY_INVALIDATED(cme)); } else if (create) { if (!mtbl) { - mtbl = RCLASS_EXT(defined_class)->callable_m_tbl = rb_id_table_create(0); } cme = rb_method_entry_complement_defined_class(me, me->called_id, defined_class); rb_id_table_insert(mtbl, id, (VALUE)cme); @@ -1418,7 +1524,7 @@ cached_callable_method_entry(VALUE klass, ID mid) { ASSERT_vm_locking(); - struct rb_id_table *cc_tbl = RCLASS_CC_TBL(klass); VALUE ccs_data; if (cc_tbl && rb_id_table_lookup(cc_tbl, mid, &ccs_data)) { @@ -1446,11 +1552,12 @@ cache_callable_method_entry(VALUE klass, ID mid, const rb_callable_method_entry_ ASSERT_vm_locking(); VM_ASSERT(cme != NULL); - struct rb_id_table *cc_tbl = RCLASS_CC_TBL(klass); VALUE ccs_data; if (!cc_tbl) { - cc_tbl = RCLASS_CC_TBL(klass) = rb_id_table_create(2); } if (rb_id_table_lookup(cc_tbl, mid, &ccs_data)) { @@ -1694,7 +1801,7 @@ remove_method(VALUE klass, ID mid) rb_clear_method_cache(self, mid); } rb_clear_method_cache(klass, mid); - rb_id_table_delete(RCLASS_M_TBL(klass), mid); rb_vm_check_redefinition_opt_method(me, klass); |