summaryrefslogtreecommitdiff
path: root/vm_method.c
diff options
context:
space:
mode:
authorNobuyoshi Nakada <nobu@ruby-lang.org>2025-05-23 20:14:20 +0900
committerNobuyoshi Nakada <nobu@ruby-lang.org>2025-05-25 15:22:43 +0900
commitaad9fa285398d48b5647f8a36922b8d817a24156 (patch)
treeb789aa228c8cfe1f3e006cc9156970587aa19514 /vm_method.c
parentfc518fe1ff0410f836b01577b8c4f3940404a24b (diff)
Use RB_VM_LOCKING
Notes
Notes: Merged: https://github.com/ruby/ruby/pull/13439
Diffstat (limited to 'vm_method.c')
-rw-r--r--vm_method.c157
1 files changed, 76 insertions, 81 deletions
diff --git a/vm_method.c b/vm_method.c
index 62aae93234..bfb567414a 100644
--- a/vm_method.c
+++ b/vm_method.c
@@ -245,91 +245,89 @@ clear_method_cache_by_id_in_class(VALUE klass, ID mid)
VM_ASSERT_TYPE2(klass, T_CLASS, T_ICLASS);
if (rb_objspace_garbage_object_p(klass)) return;
- RB_VM_LOCK_ENTER();
- if (LIKELY(RCLASS_SUBCLASSES_FIRST(klass) == NULL)) {
- // no subclasses
- // check only current class
-
- // invalidate CCs
- struct rb_id_table *cc_tbl = RCLASS_WRITABLE_CC_TBL(klass);
- invalidate_method_cache_in_cc_table(cc_tbl, mid);
- if (RCLASS_CC_TBL_NOT_PRIME_P(klass, cc_tbl)) {
- invalidate_method_cache_in_cc_table(RCLASS_PRIME_CC_TBL(klass), mid);
- }
-
- // remove from callable_m_tbl, if exists
- struct rb_id_table *cm_tbl = RCLASS_WRITABLE_CALLABLE_M_TBL(klass);
- invalidate_callable_method_entry_in_callable_m_table(cm_tbl, mid);
- if (RCLASS_CALLABLE_M_TBL_NOT_PRIME_P(klass, cm_tbl)) {
- invalidate_callable_method_entry_in_callable_m_table(RCLASS_PRIME_CALLABLE_M_TBL(klass), mid);
+ RB_VM_LOCKING() { if (LIKELY(RCLASS_SUBCLASSES_FIRST(klass) == NULL)) {
+ // no subclasses
+ // check only current class
+
+ // invalidate CCs
+ struct rb_id_table *cc_tbl = RCLASS_WRITABLE_CC_TBL(klass);
+ invalidate_method_cache_in_cc_table(cc_tbl, mid);
+ if (RCLASS_CC_TBL_NOT_PRIME_P(klass, cc_tbl)) {
+ invalidate_method_cache_in_cc_table(RCLASS_PRIME_CC_TBL(klass), mid);
+ }
+
+ // remove from callable_m_tbl, if exists
+ struct rb_id_table *cm_tbl = RCLASS_WRITABLE_CALLABLE_M_TBL(klass);
+ invalidate_callable_method_entry_in_callable_m_table(cm_tbl, mid);
+ if (RCLASS_CALLABLE_M_TBL_NOT_PRIME_P(klass, cm_tbl)) {
+ invalidate_callable_method_entry_in_callable_m_table(RCLASS_PRIME_CALLABLE_M_TBL(klass), mid);
+ }
+
+ RB_DEBUG_COUNTER_INC(cc_invalidate_leaf);
}
-
- RB_DEBUG_COUNTER_INC(cc_invalidate_leaf);
- }
- else {
- const rb_callable_method_entry_t *cme = complemented_callable_method_entry(klass, mid);
-
- if (cme) {
- // invalidate cme if found to invalidate the inline method cache.
- if (METHOD_ENTRY_CACHED(cme)) {
- if (METHOD_ENTRY_COMPLEMENTED(cme)) {
- // do nothing
- }
- else {
- // invalidate cc by invalidating cc->cme
- VALUE owner = cme->owner;
- VM_ASSERT_TYPE(owner, T_CLASS);
- VALUE klass_housing_cme;
- if (cme->def->type == VM_METHOD_TYPE_REFINED && !cme->def->body.refined.orig_me) {
- klass_housing_cme = owner;
+ else {
+ const rb_callable_method_entry_t *cme = complemented_callable_method_entry(klass, mid);
+
+ if (cme) {
+ // invalidate cme if found to invalidate the inline method cache.
+ if (METHOD_ENTRY_CACHED(cme)) {
+ if (METHOD_ENTRY_COMPLEMENTED(cme)) {
+ // do nothing
}
else {
- klass_housing_cme = RCLASS_ORIGIN(owner);
+ // invalidate cc by invalidating cc->cme
+ VALUE owner = cme->owner;
+ VM_ASSERT_TYPE(owner, T_CLASS);
+ VALUE klass_housing_cme;
+ if (cme->def->type == VM_METHOD_TYPE_REFINED && !cme->def->body.refined.orig_me) {
+ klass_housing_cme = owner;
+ }
+ else {
+ klass_housing_cme = RCLASS_ORIGIN(owner);
+ }
+
+ // replace the cme that will be invalid in the all classexts
+ invalidate_callable_method_entry_in_every_m_table(klass_housing_cme, mid, cme);
+ }
+
+ vm_cme_invalidate((rb_callable_method_entry_t *)cme);
+ RB_DEBUG_COUNTER_INC(cc_invalidate_tree_cme);
+
+ // In case of refinement ME, also invalidate the wrapped ME that
+ // could be cached at some callsite and is unreachable from any
+ // RCLASS_WRITABLE_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);
+ }
+
+ if (cme->def->iseq_overload) {
+ rb_callable_method_entry_t *monly_cme = (rb_callable_method_entry_t *)lookup_overloaded_cme(cme);
+ if (monly_cme) {
+ vm_cme_invalidate(monly_cme);
+ }
}
-
- // replace the cme that will be invalid in the all classexts
- invalidate_callable_method_entry_in_every_m_table(klass_housing_cme, mid, cme);
- }
-
- vm_cme_invalidate((rb_callable_method_entry_t *)cme);
- RB_DEBUG_COUNTER_INC(cc_invalidate_tree_cme);
-
- // In case of refinement ME, also invalidate the wrapped ME that
- // could be cached at some callsite and is unreachable from any
- // RCLASS_WRITABLE_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);
}
-
- if (cme->def->iseq_overload) {
- rb_callable_method_entry_t *monly_cme = (rb_callable_method_entry_t *)lookup_overloaded_cme(cme);
- if (monly_cme) {
- vm_cme_invalidate(monly_cme);
+
+ // invalidate complement tbl
+ if (METHOD_ENTRY_COMPLEMENTED(cme)) {
+ VALUE defined_class = cme->defined_class;
+ struct rb_id_table *cm_tbl = RCLASS_WRITABLE_CALLABLE_M_TBL(defined_class);
+ invalidate_complemented_method_entry_in_callable_m_table(cm_tbl, mid);
+ if (RCLASS_CALLABLE_M_TBL_NOT_PRIME_P(defined_class, cm_tbl)) {
+ struct rb_id_table *prime_cm_table = RCLASS_PRIME_CALLABLE_M_TBL(defined_class);
+ invalidate_complemented_method_entry_in_callable_m_table(prime_cm_table, mid);
}
}
+
+ RB_DEBUG_COUNTER_INC(cc_invalidate_tree);
}
-
- // invalidate complement tbl
- if (METHOD_ENTRY_COMPLEMENTED(cme)) {
- VALUE defined_class = cme->defined_class;
- struct rb_id_table *cm_tbl = RCLASS_WRITABLE_CALLABLE_M_TBL(defined_class);
- invalidate_complemented_method_entry_in_callable_m_table(cm_tbl, mid);
- if (RCLASS_CALLABLE_M_TBL_NOT_PRIME_P(defined_class, cm_tbl)) {
- struct rb_id_table *prime_cm_table = RCLASS_PRIME_CALLABLE_M_TBL(defined_class);
- invalidate_complemented_method_entry_in_callable_m_table(prime_cm_table, mid);
- }
+ else {
+ invalidate_negative_cache(mid);
}
-
- RB_DEBUG_COUNTER_INC(cc_invalidate_tree);
}
- else {
- invalidate_negative_cache(mid);
- }
- }
-
- rb_gccct_clear_table(Qnil);
-
- RB_VM_LOCK_LEAVE();
+
+ rb_gccct_clear_table(Qnil);
+}
}
static void
@@ -502,8 +500,7 @@ rb_vm_ci_lookup(ID mid, unsigned int flag, unsigned int argc, const struct rb_ca
new_ci->flag = flag;
new_ci->argc = argc;
- RB_VM_LOCK_ENTER();
- {
+ RB_VM_LOCKING() {
st_table *ci_table = vm->ci_table;
VM_ASSERT(ci_table);
@@ -511,7 +508,6 @@ rb_vm_ci_lookup(ID mid, unsigned int flag, unsigned int argc, const struct rb_ca
st_update(ci_table, (st_data_t)new_ci, ci_lookup_i, (st_data_t)&ci);
} while (ci == NULL);
}
- RB_VM_LOCK_LEAVE();
VM_ASSERT(ci);
@@ -1596,8 +1592,7 @@ callable_method_entry_or_negative(VALUE klass, ID mid, VALUE *defined_class_ptr)
const rb_callable_method_entry_t *cme;
VM_ASSERT_TYPE2(klass, T_CLASS, T_ICLASS);
- RB_VM_LOCK_ENTER();
- {
+ RB_VM_LOCKING() {
cme = cached_callable_method_entry(klass, mid);
if (cme) {
@@ -1618,7 +1613,6 @@ callable_method_entry_or_negative(VALUE klass, ID mid, VALUE *defined_class_ptr)
cache_callable_method_entry(klass, mid, cme);
}
}
- RB_VM_LOCK_LEAVE();
return cme;
}
@@ -3165,3 +3159,4 @@ Init_eval_method(void)
REPLICATE_METHOD(rb_eException, idRespond_to_missing);
}
}
+