summaryrefslogtreecommitdiff
path: root/gc.c
diff options
context:
space:
mode:
authorPeter Zhu <[email protected]>2024-12-20 16:48:48 -0500
committerPeter Zhu <[email protected]>2024-12-23 09:03:32 -0500
commitf4476f0d07c781c906ed1353d8e1be5a7314d6e7 (patch)
tree092d0330e8d7ebdd300b4d12a61ed24a800c171d /gc.c
parent4e12c2577839bd1696a3b318988be1c4de807d48 (diff)
Disable GC during RUBY_INTERNAL_EVENT_NEWOBJ
We must disable GC when running RUBY_INTERNAL_EVENT_NEWOBJ hooks because the callback could call xmalloc which could potentially trigger a GC, and a lot of code is unsafe to trigger a GC right after an object has been allocated because they perform initialization for the object and assume that the GC does not trigger before then.
Notes
Notes: Merged: https://github.com/ruby/ruby/pull/12419
Diffstat (limited to 'gc.c')
-rw-r--r--gc.c11
1 files changed, 10 insertions, 1 deletions
diff --git a/gc.c b/gc.c
index 67857ed44c..1ec159a2da 100644
--- a/gc.c
+++ b/gc.c
@@ -1031,7 +1031,16 @@ newobj_of(rb_ractor_t *cr, VALUE klass, VALUE flags, VALUE v1, VALUE v2, VALUE v
{
memset((char *)obj + RVALUE_SIZE, 0, rb_gc_obj_slot_size(obj) - RVALUE_SIZE);
- rb_gc_event_hook(obj, RUBY_INTERNAL_EVENT_NEWOBJ);
+ /* We must disable GC here because the callback could call xmalloc
+ * which could potentially trigger a GC, and a lot of code is unsafe
+ * to trigger a GC right after an object has been allocated because
+ * they perform initialization for the object and assume that the
+ * GC does not trigger before then. */
+ bool gc_disabled = RTEST(rb_gc_disable_no_rest());
+ {
+ rb_gc_event_hook(obj, RUBY_INTERNAL_EVENT_NEWOBJ);
+ }
+ if (!gc_disabled) rb_gc_enable();
}
RB_VM_LOCK_LEAVE_CR_LEV(cr, &lev);
}