summaryrefslogtreecommitdiff
path: root/vm_method.c
diff options
context:
space:
mode:
authorLuke Gruber <luke.gruber@shopify.com>2025-12-16 14:06:55 -0500
committerGitHub <noreply@github.com>2025-12-16 14:06:55 -0500
commit4fb537b1ee28bb37dbe551ac65c279d436c756bc (patch)
tree03a8f339cb53f6b9b0b359af0d50bdcbc5eefcc9 /vm_method.c
parentd209e6f1c0a93ad3ce1cc64dd165a6b67672614d (diff)
Make tracepoints with set_trace_func or TracePoint.new ractor local (#15468)
Before this change, GC'ing any Ractor object caused you to lose all enabled tracepoints across all ractors (even main). Now tracepoints are ractor-local and this doesn't happen. Internal events are still global. Fixes [Bug #19112]
Diffstat (limited to 'vm_method.c')
-rw-r--r--vm_method.c26
1 files changed, 17 insertions, 9 deletions
diff --git a/vm_method.c b/vm_method.c
index 17f68fc258..9f569df7fa 100644
--- a/vm_method.c
+++ b/vm_method.c
@@ -826,7 +826,7 @@ rb_add_method_optimized(VALUE klass, ID mid, enum method_optimized_type opt_type
}
static void
-rb_method_definition_release(rb_method_definition_t *def)
+method_definition_release(rb_method_definition_t *def)
{
if (def != NULL) {
const unsigned int reference_count_was = RUBY_ATOMIC_FETCH_SUB(def->reference_count, 1);
@@ -836,9 +836,6 @@ rb_method_definition_release(rb_method_definition_t *def)
if (reference_count_was == 1) {
if (METHOD_DEBUG) fprintf(stderr, "-%p-%s:1->0 (remove)\n", (void *)def,
rb_id2name(def->original_id));
- if (def->type == VM_METHOD_TYPE_BMETHOD && def->body.bmethod.hooks) {
- xfree(def->body.bmethod.hooks);
- }
xfree(def);
}
else {
@@ -848,6 +845,12 @@ rb_method_definition_release(rb_method_definition_t *def)
}
}
+void
+rb_method_definition_release(rb_method_definition_t *def)
+{
+ method_definition_release(def);
+}
+
static void delete_overloaded_cme(const rb_callable_method_entry_t *cme);
void
@@ -872,7 +875,7 @@ rb_free_method_entry(const rb_method_entry_t *me)
// to remove from `Invariants` here.
#endif
- rb_method_definition_release(me->def);
+ method_definition_release(me->def);
}
static inline rb_method_entry_t *search_method(VALUE klass, ID id, VALUE *defined_class_ptr);
@@ -939,6 +942,7 @@ setup_method_cfunc_struct(rb_method_cfunc_t *cfunc, VALUE (*func)(ANYARGS), int
cfunc->invoker = call_cfunc_invoker_func(argc);
}
+
static rb_method_definition_t *
method_definition_addref(rb_method_definition_t *def, bool complemented)
{
@@ -953,9 +957,15 @@ method_definition_addref(rb_method_definition_t *def, bool complemented)
}
void
+rb_method_definition_addref(rb_method_definition_t *def)
+{
+ method_definition_addref(def, false);
+}
+
+void
rb_method_definition_set(const rb_method_entry_t *me, rb_method_definition_t *def, void *opts)
{
- rb_method_definition_release(me->def);
+ method_definition_release(me->def);
*(rb_method_definition_t **)&me->def = method_definition_addref(def, METHOD_ENTRY_COMPLEMENTED(me));
if (!ruby_running) add_opt_method_entry(me);
@@ -1060,8 +1070,6 @@ method_definition_reset(const rb_method_entry_t *me)
break;
case VM_METHOD_TYPE_BMETHOD:
RB_OBJ_WRITTEN(me, Qundef, def->body.bmethod.proc);
- /* give up to check all in a list */
- if (def->body.bmethod.hooks) rb_gc_writebarrier_remember((VALUE)me);
break;
case VM_METHOD_TYPE_REFINED:
RB_OBJ_WRITTEN(me, Qundef, def->body.refined.orig_me);
@@ -1195,7 +1203,7 @@ rb_method_entry_complement_defined_class(const rb_method_entry_t *src_me, ID cal
void
rb_method_entry_copy(rb_method_entry_t *dst, const rb_method_entry_t *src)
{
- rb_method_definition_release(dst->def);
+ method_definition_release(dst->def);
*(rb_method_definition_t **)&dst->def = method_definition_addref(src->def, METHOD_ENTRY_COMPLEMENTED(src));
method_definition_reset(dst);
dst->called_id = src->called_id;