diff options
author | NARUSE, Yui <naruse@airemix.jp> | 2021-03-02 22:00:45 +0900 |
---|---|---|
committer | NARUSE, Yui <naruse@airemix.jp> | 2021-03-02 22:00:45 +0900 |
commit | b49264ab7aa92f64a806857d7e81b3f1cbba5585 (patch) | |
tree | ae23168bfe59e5e1f5e706ef3503386895b82db7 /gc.c | |
parent | 4328f93f1bf08296115172a279e2d85a0ed80122 (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.c | 30 |
1 files changed, 18 insertions, 12 deletions
@@ -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 |