Skip to content

Commit 06356db

Browse files
committed
Fix stack scanning
1 parent cbe1a1a commit 06356db

File tree

6 files changed

+92
-87
lines changed

6 files changed

+92
-87
lines changed

Diff for: gc.c

+27-38
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,12 @@ rb_gc_get_ractor_newobj_cache(void)
196196
return GET_RACTOR()->newobj_cache;
197197
}
198198

199+
void *
200+
rb_gc_get_current_execution_context(void)
201+
{
202+
return GET_EC();
203+
}
204+
199205
void
200206
rb_gc_ractor_newobj_cache_foreach(void (*func)(void *cache, void *data), void *data)
201207
{
@@ -2273,6 +2279,12 @@ rb_mark_locations(void *begin, void *end)
22732279

22742280
# if defined(__EMSCRIPTEN__)
22752281

2282+
void
2283+
rb_gc_save_machine_context(void)
2284+
{
2285+
// no-op
2286+
}
2287+
22762288
static void
22772289
mark_current_machine_context(void *objspace, rb_execution_context_t *ec)
22782290
{
@@ -2300,35 +2312,18 @@ mark_current_machine_context(void *objspace, rb_execution_context_t *ec)
23002312

23012313
#else // !defined(__wasm__)
23022314

2303-
static void
2304-
mark_current_machine_context(void *objspace, rb_execution_context_t *ec)
2315+
void
2316+
rb_gc_save_machine_context(void)
23052317
{
2306-
union {
2307-
rb_jmp_buf j;
2308-
VALUE v[sizeof(rb_jmp_buf) / (sizeof(VALUE))];
2309-
} save_regs_gc_mark;
2310-
VALUE *stack_start, *stack_end;
2318+
rb_thread_t *thread = GET_THREAD();
23112319

2312-
FLUSH_REGISTER_WINDOWS;
2313-
memset(&save_regs_gc_mark, 0, sizeof(save_regs_gc_mark));
2314-
/* This assumes that all registers are saved into the jmp_buf (and stack) */
2315-
rb_setjmp(save_regs_gc_mark.j);
2316-
2317-
/* SET_STACK_END must be called in this function because
2318-
* the stack frame of this function may contain
2319-
* callee save registers and they should be marked. */
2320-
SET_STACK_END;
2321-
GET_STACK_BOUNDS(stack_start, stack_end, 1);
2322-
2323-
struct mark_machine_stack_location_maybe_data data = {
2324-
.objspace = objspace,
2325-
#ifdef RUBY_ASAN_ENABLED
2326-
.ec = ec
2327-
#endif
2328-
};
2320+
RB_VM_SAVE_MACHINE_CONTEXT(thread);
2321+
}
23292322

2330-
each_location((void *)&data, save_regs_gc_mark.v, numberof(save_regs_gc_mark.v), gc_mark_machine_stack_location_maybe);
2331-
each_stack_location((void *)&data, ec, stack_start, stack_end, gc_mark_machine_stack_location_maybe);
2323+
static void
2324+
mark_current_machine_context(void *objspace, const rb_execution_context_t *ec)
2325+
{
2326+
rb_gc_mark_machine_context(ec);
23322327
}
23332328
#endif
23342329

@@ -2460,7 +2455,7 @@ mark_const_table_i(VALUE value, void *objspace)
24602455
}
24612456

24622457
void
2463-
rb_gc_mark_roots(void *objspace, const char **categoryp)
2458+
rb_gc_mark_roots(void *objspace, const void *ec, const char **categoryp)
24642459
{
24652460
rb_vm_t *vm = GET_VM();
24662461

@@ -2487,18 +2482,11 @@ rb_gc_mark_roots(void *objspace, const char **categoryp)
24872482
}
24882483
#endif
24892484

2490-
MARK_CHECKPOINT("finish");
2491-
}
2492-
2493-
void
2494-
rb_gc_mark_thread_roots(void *objspace, void *ractor, const char **categoryp)
2495-
{
2496-
if (ractor == NULL) ractor = GET_RACTOR();
2497-
2498-
rb_execution_context_t *ec = ((rb_ractor_t *)ractor)->threads.running_ec;
2499-
25002485
MARK_CHECKPOINT("machine_context");
25012486
mark_current_machine_context(objspace, ec);
2487+
2488+
MARK_CHECKPOINT("finish");
2489+
25022490
#undef MARK_CHECKPOINT
25032491
}
25042492

@@ -3617,7 +3605,8 @@ rb_objspace_reachable_objects_from_root(void (func)(const char *category, VALUE,
36173605
}, *prev_mfd = cr->mfd;
36183606

36193607
cr->mfd = &mfd;
3620-
rb_gc_mark_roots(rb_gc_get_objspace(), &data.category);
3608+
rb_gc_save_machine_context();
3609+
rb_gc_mark_roots(rb_gc_get_objspace(), rb_gc_get_current_execution_context(), &data.category);
36213610
cr->mfd = prev_mfd;
36223611
}
36233612

Diff for: gc/default.c

+2-3
Original file line numberDiff line numberDiff line change
@@ -4838,9 +4838,8 @@ mark_roots(rb_objspace_t *objspace, const char **categoryp)
48384838

48394839
if (stress_to_class) rb_gc_mark(stress_to_class);
48404840

4841-
rb_gc_mark_roots(objspace, categoryp);
4842-
4843-
rb_gc_mark_thread_roots(objspace, NULL, categoryp);
4841+
rb_gc_save_machine_context();
4842+
rb_gc_mark_roots(objspace, rb_gc_get_current_execution_context(), categoryp);
48444843
}
48454844

48464845
static inline void

Diff for: gc/gc.h

+3-2
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,14 @@ void rb_gc_reachable_objects_from_callback(VALUE obj);
2727
void rb_gc_event_hook(VALUE obj, rb_event_flag_t event);
2828
void *rb_gc_get_objspace(void);
2929
void *rb_gc_get_ractor_newobj_cache(void);
30+
void *rb_gc_get_current_execution_context(void);
3031
size_t rb_size_mul_or_raise(size_t x, size_t y, VALUE exc);
3132
void rb_gc_run_obj_finalizer(VALUE objid, long count, VALUE (*callback)(long i, void *data), void *data);
3233
void rb_gc_set_pending_interrupt(void);
3334
void rb_gc_unset_pending_interrupt(void);
3435
bool rb_gc_obj_free(void *objspace, VALUE obj);
35-
void rb_gc_mark_roots(void *objspace, const char **categoryp);
36-
void rb_gc_mark_thread_roots(void *objspace, void *ractor, const char **categoryp);
36+
void rb_gc_save_machine_context(void);
37+
void rb_gc_mark_roots(void *objspace, const void *ec, const char **categoryp);
3738
void rb_gc_ractor_newobj_cache_foreach(void (*func)(void *cache, void *data), void *data);
3839
bool rb_gc_multi_ractor_p(void);
3940
void rb_objspace_reachable_objects_from_root(void (func)(const char *category, VALUE, void *), void *passing_data);

Diff for: gc/mmtk.c

+56-36
Original file line numberDiff line numberDiff line change
@@ -11,24 +11,6 @@
1111
#include "gc/gc_impl.h"
1212
#include "gc/mmtk.h"
1313

14-
struct MMTk_final_job {
15-
struct MMTk_final_job *next;
16-
enum {
17-
MMTK_FINAL_JOB_DFREE,
18-
MMTK_FINAL_JOB_FINALIZE,
19-
} kind;
20-
union {
21-
struct {
22-
void (*dfree)(void *);
23-
void *data;
24-
} dfree;
25-
struct {
26-
VALUE object_id;
27-
VALUE finalizer_array;
28-
} finalize;
29-
} as;
30-
};
31-
3214
struct objspace {
3315
st_table *id_to_obj_tbl;
3416
st_table *obj_to_id_tbl;
@@ -38,6 +20,7 @@ struct objspace {
3820
struct MMTk_final_job *finalizer_jobs;
3921
rb_postponed_job_handle_t finalizer_postponed_job;
4022

23+
struct MMTk_ractor_cache *ractor_caches;
4124
unsigned long live_ractor_cache_count;
4225

4326
int lock_lev;
@@ -49,6 +32,31 @@ struct objspace {
4932
size_t start_the_world_count;
5033
};
5134

35+
struct MMTk_ractor_cache {
36+
struct MMTk_ractor_cache *next_ractor_cache;
37+
38+
MMTk_Mutator *mutator;
39+
void *execution_context;
40+
};
41+
42+
struct MMTk_final_job {
43+
struct MMTk_final_job *next;
44+
enum {
45+
MMTK_FINAL_JOB_DFREE,
46+
MMTK_FINAL_JOB_FINALIZE,
47+
} kind;
48+
union {
49+
struct {
50+
void (*dfree)(void *);
51+
void *data;
52+
} dfree;
53+
struct {
54+
VALUE object_id;
55+
VALUE finalizer_array;
56+
} finalize;
57+
} as;
58+
};
59+
5260
#ifdef RB_THREAD_LOCAL_SPECIFIER
5361
RB_THREAD_LOCAL_SPECIFIER struct MMTk_GCThreadTLS *rb_mmtk_gc_thread_tls;
5462
#else
@@ -113,7 +121,7 @@ rb_mmtk_resume_mutators(void)
113121
}
114122

115123
static void
116-
rb_mmtk_block_for_gc(MMTk_VMMutatorThread tls)
124+
rb_mmtk_block_for_gc(MMTk_VMMutatorThread mutator)
117125
{
118126
struct objspace *objspace = rb_gc_get_objspace();
119127

@@ -125,6 +133,8 @@ rb_mmtk_block_for_gc(MMTk_VMMutatorThread tls)
125133
// Increment the stopped ractor count
126134
objspace->stopped_ractors++;
127135
if (objspace->stopped_ractors == 1) {
136+
rb_gc_save_machine_context();
137+
mutator->execution_context = rb_gc_get_current_execution_context();
128138
pthread_cond_broadcast(&objspace->cond_world_stopped);
129139
}
130140

@@ -146,23 +156,28 @@ rb_mmtk_block_for_gc(MMTk_VMMutatorThread tls)
146156
static size_t
147157
rb_mmtk_number_of_mutators(void)
148158
{
149-
// TODO
150-
return 1;
159+
struct objspace *objspace = rb_gc_get_objspace();
160+
return objspace->live_ractor_cache_count;
151161
}
152162

153-
static void *mutator;
154-
155163
static void
156164
rb_mmtk_get_mutators(void (*visit_mutator)(MMTk_Mutator *mutator, void *data), void *data)
157165
{
158-
// TODO
159-
visit_mutator(mutator, data);
166+
struct objspace *objspace = rb_gc_get_objspace();
167+
168+
struct MMTk_ractor_cache *ractor_cache = objspace->ractor_caches;
169+
RUBY_ASSERT(ractor_cache != NULL);
170+
171+
while (ractor_cache != NULL) {
172+
visit_mutator(ractor_cache->mutator, data);
173+
ractor_cache = ractor_cache->next_ractor_cache;
174+
}
160175
}
161176

162177
static void
163178
rb_mmtk_scan_gc_roots(void)
164179
{
165-
rb_gc_mark_roots(rb_gc_get_objspace(), NULL);
180+
// rb_gc_mark_roots(rb_gc_get_objspace(), NULL);
166181
}
167182

168183
static int
@@ -188,9 +203,7 @@ rb_mmtk_scan_objspace(void)
188203
static void
189204
rb_mmtk_scan_roots_in_mutator_thread(MMTk_VMMutatorThread mutator, MMTk_VMWorkerThread worker)
190205
{
191-
void *ractor = mutator;
192-
193-
rb_gc_mark_thread_roots(rb_gc_get_objspace(), ractor, NULL);
206+
rb_gc_mark_roots(rb_gc_get_objspace(), mutator->execution_context, NULL);
194207
}
195208

196209
static void
@@ -457,10 +470,13 @@ rb_gc_impl_ractor_cache_alloc(void *objspace_ptr, void *ractor)
457470
}
458471
objspace->live_ractor_cache_count++;
459472

460-
mutator = mmtk_bind_mutator(ractor);
461-
return mutator;
473+
struct MMTk_ractor_cache *cache = malloc(sizeof(struct MMTk_ractor_cache));
474+
cache->next_ractor_cache = objspace->ractor_caches;
475+
objspace->ractor_caches = cache;
462476

463-
// return mmtk_bind_mutator(ractor);
477+
cache->mutator = mmtk_bind_mutator(cache);
478+
479+
return cache;
464480
}
465481

466482
void
@@ -572,7 +588,9 @@ rb_gc_impl_new_obj(void *objspace_ptr, void *cache_ptr, VALUE klass, VALUE flags
572588
}
573589
}
574590

575-
VALUE *alloc_obj = mmtk_alloc(cache_ptr, alloc_size + 8, MMTk_MIN_OBJ_ALIGN, 0, MMTK_ALLOCATION_SEMANTICS_DEFAULT);
591+
struct MMTk_ractor_cache *ractor_cache = cache_ptr;
592+
593+
VALUE *alloc_obj = mmtk_alloc(ractor_cache->mutator, alloc_size + 8, MMTk_MIN_OBJ_ALIGN, 0, MMTK_ALLOCATION_SEMANTICS_DEFAULT);
576594
alloc_obj++;
577595
alloc_obj[-1] = alloc_size;
578596
alloc_obj[0] = flags;
@@ -581,7 +599,7 @@ rb_gc_impl_new_obj(void *objspace_ptr, void *cache_ptr, VALUE klass, VALUE flags
581599
if (alloc_size > 24) alloc_obj[3] = v2;
582600
if (alloc_size > 32) alloc_obj[4] = v3;
583601

584-
mmtk_post_alloc(cache_ptr, (void*)alloc_obj, alloc_size + 8, MMTK_ALLOCATION_SEMANTICS_DEFAULT);
602+
mmtk_post_alloc(ractor_cache->mutator, (void*)alloc_obj, alloc_size + 8, MMTK_ALLOCATION_SEMANTICS_DEFAULT);
585603

586604
// TODO: only add when object needs obj_free to be called
587605
mmtk_add_obj_free_candidate(alloc_obj);
@@ -708,7 +726,9 @@ rb_gc_impl_location(void *objspace_ptr, VALUE value)
708726
void
709727
rb_gc_impl_writebarrier(void *objspace_ptr, VALUE a, VALUE b)
710728
{
711-
mmtk_object_reference_write_post(rb_gc_get_ractor_newobj_cache(), (MMTk_ObjectReference)a);
729+
struct MMTk_ractor_cache *cache = rb_gc_get_ractor_newobj_cache();
730+
731+
mmtk_object_reference_write_post(cache->mutator, (MMTk_ObjectReference)a);
712732
}
713733

714734
void
@@ -720,7 +740,7 @@ rb_gc_impl_writebarrier_unprotect(void *objspace_ptr, VALUE obj)
720740
void
721741
rb_gc_impl_writebarrier_remember(void *objspace_ptr, VALUE obj)
722742
{
723-
mmtk_object_reference_write_post(rb_gc_get_ractor_newobj_cache(), (MMTk_ObjectReference)obj);
743+
rb_gc_impl_writebarrier(objspace_ptr, obj, Qundef);
724744
}
725745

726746
// Heap walking

Diff for: gc/mmtk.h

+2-4
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,8 @@
1212
typedef struct MMTk_Builder MMTk_Builder;
1313
typedef struct MMTk_Mutator MMTk_Mutator;
1414

15-
struct rb_thread_struct;
16-
typedef struct rb_thread_struct rb_thread_t;
17-
typedef rb_thread_t *MMTk_VMThread;
18-
typedef rb_thread_t *MMTk_VMMutatorThread;
15+
typedef struct MMTk_ractor_cache *MMTk_VMThread;
16+
typedef struct MMTk_ractor_cache *MMTk_VMMutatorThread;
1917
typedef struct MMTk_GCThreadTLS *MMTk_VMWorkerThread;
2018
typedef void *MMTk_Address;
2119
typedef void *MMTk_ObjectReference;

Diff for: gc/mmtk/cbindgen.toml

+2-4
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,8 @@ after_includes = """
1313
typedef struct MMTk_Builder MMTk_Builder;
1414
typedef struct MMTk_Mutator MMTk_Mutator;
1515
16-
struct rb_thread_struct;
17-
typedef struct rb_thread_struct rb_thread_t;
18-
typedef rb_thread_t *MMTk_VMThread;
19-
typedef rb_thread_t *MMTk_VMMutatorThread;
16+
typedef struct MMTk_ractor_cache *MMTk_VMThread;
17+
typedef struct MMTk_ractor_cache *MMTk_VMMutatorThread;
2018
typedef struct MMTk_GCThreadTLS *MMTk_VMWorkerThread;
2119
typedef void *MMTk_Address;
2220
typedef void *MMTk_ObjectReference;

0 commit comments

Comments
 (0)