summaryrefslogtreecommitdiff
path: root/gc.c
diff options
context:
space:
mode:
authorNARUSE, Yui <naruse@airemix.jp>2021-03-02 22:00:45 +0900
committerNARUSE, Yui <naruse@airemix.jp>2021-03-02 22:00:45 +0900
commitb49264ab7aa92f64a806857d7e81b3f1cbba5585 (patch)
treeae23168bfe59e5e1f5e706ef3503386895b82db7 /gc.c
parent4328f93f1bf08296115172a279e2d85a0ed80122 (diff)
merge revision(s) 969b824a0c7605e0e570631d967ad0de0c37d0bf,100e464bee46ae71ef048ed85a9bdd012935a3f7: [Backport #17599]
sync GC rest if needed marking requires a barrier (stop all Ractors) and gc_enter() does it. However, it doesn't check rest event which can start marking. [Bug #17599] --- gc.c | 3 +++ 1 file changed, 3 insertions(+) clear RVALUE on NEWOBJ event. NEWOBJ event is called without clearing RVALUE values (v1, v2, v3). This patch clear them before NEWOBJ tracepoint internal hook. [Bug #17599] --- gc.c | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-)
Diffstat (limited to 'gc.c')
-rw-r--r--gc.c30
1 files changed, 18 insertions, 12 deletions
diff --git a/gc.c b/gc.c
index e363dc158a..0ee444e026 100644
--- a/gc.c
+++ b/gc.c
@@ -2071,12 +2071,15 @@ gc_event_hook_body(rb_execution_context_t *ec, rb_objspace_t *objspace, const rb
#define gc_event_hook_available_p(objspace) ((objspace)->flags.has_hook)
#define gc_event_hook_needed_p(objspace, event) ((objspace)->hook_events & (event))
-#define gc_event_hook(objspace, event, data) do { \
+#define gc_event_hook_prep(objspace, event, data, prep) do { \
if (UNLIKELY(gc_event_hook_needed_p(objspace, event))) { \
+ prep; \
gc_event_hook_body(GET_EC(), (objspace), (event), (data)); \
} \
} while (0)
+#define gc_event_hook(objspace, event, data) gc_event_hook_prep(objspace, event, data, (void)0)
+
static inline VALUE
newobj_init(VALUE klass, VALUE flags, int wb_protected, rb_objspace_t *objspace, VALUE obj)
{
@@ -2220,6 +2223,16 @@ ractor_cache_slots(rb_objspace_t *objspace, rb_ractor_t *cr)
GC_ASSERT(RB_TYPE_P((VALUE)cr->newobj_cache.freelist, T_NONE));
}
+static inline VALUE
+newobj_fill(VALUE obj, VALUE v1, VALUE v2, VALUE v3)
+{
+ RVALUE *p = (RVALUE *)obj;
+ p->as.values.v1 = v1;
+ p->as.values.v2 = v2;
+ p->as.values.v3 = v3;
+ return obj;
+}
+
ALWAYS_INLINE(static VALUE newobj_slowpath(VALUE klass, VALUE flags, rb_objspace_t *objspace, rb_ractor_t *cr, int wb_protected));
static inline VALUE
@@ -2250,7 +2263,7 @@ newobj_slowpath(VALUE klass, VALUE flags, rb_objspace_t *objspace, rb_ractor_t *
}
GC_ASSERT(obj != 0);
newobj_init(klass, flags, wb_protected, objspace, obj);
- gc_event_hook(objspace, RUBY_INTERNAL_EVENT_NEWOBJ, obj);
+ gc_event_hook_prep(objspace, RUBY_INTERNAL_EVENT_NEWOBJ, obj, newobj_fill(obj, 0, 0, 0));
}
RB_VM_LOCK_LEAVE_CR_LEV(cr, &lev);
@@ -2312,16 +2325,6 @@ newobj_of0(VALUE klass, VALUE flags, int wb_protected, rb_ractor_t *cr)
}
static inline VALUE
-newobj_fill(VALUE obj, VALUE v1, VALUE v2, VALUE v3)
-{
- RVALUE *p = (RVALUE *)obj;
- p->as.values.v1 = v1;
- p->as.values.v2 = v2;
- p->as.values.v3 = v3;
- return obj;
-}
-
-static inline VALUE
newobj_of(VALUE klass, VALUE flags, VALUE v1, VALUE v2, VALUE v3, int wb_protected)
{
VALUE obj = newobj_of0(klass, flags, wb_protected, GET_RACTOR());
@@ -8457,6 +8460,9 @@ gc_enter(rb_objspace_t *objspace, enum gc_enter_event event, unsigned int *lock_
RB_VM_LOCK_ENTER_LEV(lock_lev);
switch (event) {
+ case gc_enter_event_rest:
+ if (!is_marking(objspace)) break;
+ // fall through
case gc_enter_event_start:
case gc_enter_event_mark_continue:
// stop other ractors