Skip to content

Commit ce53b0b

Browse files
committed
Split global roots
Split gc_mark_roots into multiple functions so that they can be called from different work packets.
1 parent e37fb27 commit ce53b0b

File tree

4 files changed

+86
-48
lines changed

4 files changed

+86
-48
lines changed

gc.c

+64-35
Original file line numberDiff line numberDiff line change
@@ -7315,6 +7315,11 @@ rb_gc_remove_weak(VALUE parent_obj, VALUE *ptr)
73157315
static inline void
73167316
gc_mark_set_parent(rb_objspace_t *objspace, VALUE obj)
73177317
{
7318+
WHEN_USING_MMTK({
7319+
// MMTk scans object concurrently. This function only adds one more source of data race.
7320+
return;
7321+
})
7322+
73187323
if (RVALUE_OLD_P(obj)) {
73197324
objspace->rgengc.parent_object = obj;
73207325
}
@@ -7664,21 +7669,14 @@ show_mark_ticks(void)
76647669
static void
76657670
gc_mark_roots(rb_objspace_t *objspace, const char **categoryp)
76667671
{
7667-
rb_execution_context_t *ec;
7668-
rb_vm_t *vm;
7672+
WHEN_USING_MMTK({
7673+
// When using MMTk, we parallelize root scanning by splitting this function into multiple
7674+
// functions, and call each one in a separate work packet.
7675+
rb_bug("gc_mark_roots should not be called when using MMTk.");
7676+
})
76697677

7670-
#if USE_MMTK
7671-
const bool mmtk_enabled_local = rb_mmtk_enabled_p(); // Allows control-flow sensitive analysis of ec etc
7672-
if (mmtk_enabled_local) {
7673-
rb_mmtk_assert_mmtk_worker();
7674-
vm = GET_VM();
7675-
} else {
7676-
#endif
7677-
ec = GET_EC();
7678-
vm = rb_ec_vm_ptr(ec);
7679-
#if USE_MMTK
7680-
}
7681-
#endif
7678+
rb_execution_context_t *ec = GET_EC();
7679+
rb_vm_t *vm = rb_ec_vm_ptr(ec);
76827680

76837681
#if PRINT_ROOT_TICKS
76847682
tick_t start_tick = tick();
@@ -7715,32 +7713,15 @@ gc_mark_roots(rb_objspace_t *objspace, const char **categoryp)
77157713
} while (0)
77167714

77177715
MARK_CHECKPOINT("vm");
7718-
7719-
#if USE_MMTK
7720-
// Note that when using MMTk, this function is executed by a GC worker thread, not a mutator.
7721-
// Therefore we don't set stack end or scan the current stack.
7722-
if (!mmtk_enabled_local) {
7723-
#endif
77247716
SET_STACK_END;
7725-
#if USE_MMTK
7726-
}
7727-
#endif
7728-
77297717
rb_vm_mark(vm);
77307718
if (vm->self) gc_mark(objspace, vm->self);
77317719

77327720
MARK_CHECKPOINT("finalizers");
77337721
mark_finalizer_tbl(objspace, finalizer_table);
77347722

7735-
#if USE_MMTK
7736-
if (!mmtk_enabled_local) {
7737-
#endif
7738-
// When using MMTk, the current thread is a GC worker. Mutators are scanned separately.
77397723
MARK_CHECKPOINT("machine_context");
77407724
mark_current_machine_context(objspace, ec);
7741-
#if USE_MMTK
7742-
}
7743-
#endif
77447725

77457726
/* mark protected global variables */
77467727

@@ -7759,6 +7740,57 @@ gc_mark_roots(rb_objspace_t *objspace, const char **categoryp)
77597740
#undef MARK_CHECKPOINT
77607741
}
77617742

7743+
#if USE_MMTK
7744+
void
7745+
rb_mmtk_scan_vm_roots(void)
7746+
{
7747+
rb_vm_t *vm = GET_VM();
7748+
rb_objspace_t *objspace = vm->objspace;
7749+
7750+
rb_vm_mark(vm);
7751+
if (vm->self) gc_mark(objspace, vm->self);
7752+
}
7753+
7754+
void
7755+
rb_mmtk_scan_finalizer_tbl_roots(void)
7756+
{
7757+
rb_vm_t *vm = GET_VM();
7758+
rb_objspace_t *objspace = vm->objspace;
7759+
7760+
mark_finalizer_tbl(objspace, finalizer_table);
7761+
}
7762+
7763+
void
7764+
rb_mmtk_scan_end_proc_roots(void)
7765+
{
7766+
rb_mark_end_proc();
7767+
}
7768+
7769+
void
7770+
rb_mmtk_scan_global_tbl_roots(void)
7771+
{
7772+
rb_gc_mark_global_tbl();
7773+
}
7774+
7775+
void
7776+
rb_mmtk_scan_obj_to_id_tbl_roots(void)
7777+
{
7778+
rb_vm_t *vm = GET_VM();
7779+
rb_objspace_t *objspace = vm->objspace;
7780+
7781+
mark_tbl_no_pin(objspace, objspace->obj_to_id_tbl); /* Only mark ids */
7782+
}
7783+
7784+
void
7785+
rb_mmtk_scan_misc_roots(void)
7786+
{
7787+
rb_vm_t *vm = GET_VM();
7788+
rb_objspace_t *objspace = vm->objspace;
7789+
7790+
if (stress_to_class) rb_gc_mark(stress_to_class);
7791+
}
7792+
#endif
7793+
77627794
#if RGENGC_CHECK_MODE >= 4
77637795

77647796
#define MAKE_ROOTSIG(obj) (((VALUE)(obj) << 1) | 0x01)
@@ -14778,11 +14810,8 @@ rb_mmtk_update_ci_table(void)
1477814810

1477914811
// Workaround private functions
1478014812
void
14781-
rb_mmtk_mark_roots(void)
14813+
rb_mmtk_scan_final_jobs_roots(void)
1478214814
{
14783-
rb_vm_t *vm = GET_VM();
14784-
const char *phase;
14785-
gc_mark_roots(vm->objspace, &phase);
1478614815
rb_mmtk_mark_final_jobs();
1478714816
}
1478814817

internal/gc.h

+8-1
Original file line numberDiff line numberDiff line change
@@ -235,7 +235,14 @@ void rb_gc_initial_stress_set(VALUE flag);
235235
} while (0)
236236

237237
#if USE_MMTK
238-
void rb_mmtk_mark_roots(void);
238+
void rb_mmtk_scan_vm_roots(void);
239+
void rb_mmtk_scan_finalizer_tbl_roots(void);
240+
void rb_mmtk_scan_end_proc_roots(void);
241+
void rb_mmtk_scan_global_tbl_roots(void);
242+
void rb_mmtk_scan_obj_to_id_tbl_roots(void);
243+
void rb_mmtk_scan_misc_roots(void);
244+
void rb_mmtk_scan_final_jobs_roots(void);
245+
239246
void rb_mmtk_mark_children(VALUE obj);
240247
void rb_mmtk_update_object_references(VALUE obj);
241248
void rb_mmtk_obj_free(VALUE obj);

internal/mmtk.h

+7-1
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,13 @@ typedef struct MMTk_RubyUpcalls {
6262
void (*block_for_gc)(MMTk_VMMutatorThread tls);
6363
size_t (*number_of_mutators)(void);
6464
void (*get_mutators)(void (*visit_mutator)(MMTk_Mutator*, void*), void *data);
65-
void (*scan_vm_specific_roots)(void);
65+
void (*scan_vm_roots)(void);
66+
void (*scan_finalizer_tbl_roots)(void);
67+
void (*scan_end_proc_roots)(void);
68+
void (*scan_global_tbl_roots)(void);
69+
void (*scan_obj_to_id_tbl_roots)(void);
70+
void (*scan_misc_roots)(void);
71+
void (*scan_final_jobs_roots)(void);
6672
void (*scan_roots_in_mutator_thread)(MMTk_VMMutatorThread mutator_tls,
6773
MMTk_VMWorkerThread worker_tls);
6874
void (*scan_object_ruby_style)(MMTk_ObjectReference object);

mmtk_support.c

+7-11
Original file line numberDiff line numberDiff line change
@@ -1556,16 +1556,6 @@ rb_mmtk_get_mutators(void (*visit_mutator)(MMTk_Mutator *mutator, void *data), v
15561556
}
15571557
}
15581558

1559-
static void
1560-
rb_mmtk_scan_vm_specific_roots(void)
1561-
{
1562-
rb_mmtk_assert_mmtk_worker();
1563-
1564-
RUBY_DEBUG_LOG("Scanning VM-specific roots...");
1565-
1566-
rb_mmtk_mark_roots();
1567-
}
1568-
15691559
static void
15701560
rb_mmtk_scan_roots_in_mutator_thread(MMTk_VMMutatorThread mutator, MMTk_VMWorkerThread worker)
15711561
{
@@ -1616,7 +1606,13 @@ MMTk_RubyUpcalls ruby_upcalls = {
16161606
rb_mmtk_block_for_gc,
16171607
rb_mmtk_number_of_mutators,
16181608
rb_mmtk_get_mutators,
1619-
rb_mmtk_scan_vm_specific_roots,
1609+
rb_mmtk_scan_vm_roots,
1610+
rb_mmtk_scan_finalizer_tbl_roots,
1611+
rb_mmtk_scan_end_proc_roots,
1612+
rb_mmtk_scan_global_tbl_roots,
1613+
rb_mmtk_scan_obj_to_id_tbl_roots,
1614+
rb_mmtk_scan_misc_roots,
1615+
rb_mmtk_scan_final_jobs_roots,
16201616
rb_mmtk_scan_roots_in_mutator_thread,
16211617
rb_mmtk_scan_object_ruby_style,
16221618
rb_mmtk_call_gc_mark_children,

0 commit comments

Comments
 (0)