Skip to content

Commit 1271067

Browse files
Generic global table iterator
Instead of special casing all the global tables with weak references, provide a generic interface to update all of them with a single function callback.
1 parent b0d0e6f commit 1271067

File tree

8 files changed

+103
-199
lines changed

8 files changed

+103
-199
lines changed

Diff for: gc.c

+84
Original file line numberDiff line numberDiff line change
@@ -3229,6 +3229,90 @@ update_superclasses(void *objspace, VALUE obj)
32293229
extern rb_symbols_t ruby_global_symbols;
32303230
#define global_symbols ruby_global_symbols
32313231

3232+
struct global_vm_tbl_iter_data {
3233+
vm_tbl_iter_callback_func callback;
3234+
vm_tbl_update_callback_func update_callback;
3235+
void *data;
3236+
};
3237+
3238+
static int
3239+
vm_table_iter_wrapper(st_data_t key, st_data_t value, st_data_t data, int error)
3240+
{
3241+
struct global_vm_tbl_iter_data *iter_data = (struct global_vm_tbl_iter_data *)data;
3242+
vm_tbl_iter_callback_func callback = iter_data->callback;
3243+
3244+
return (*callback)((VALUE)key, iter_data->data);
3245+
}
3246+
3247+
static int
3248+
vm_table_update_wrapper(st_data_t *key, st_data_t *value, st_data_t data, int existing)
3249+
{
3250+
struct global_vm_tbl_iter_data *iter_data = (struct global_vm_tbl_iter_data *)data;
3251+
vm_tbl_update_callback_func callback = iter_data->update_callback;
3252+
3253+
return (*callback)((VALUE *)key, iter_data->data);
3254+
}
3255+
3256+
static int
3257+
vm_frozen_strings_iter_wrapper(st_data_t key, st_data_t value, st_data_t data, int error)
3258+
{
3259+
GC_ASSERT(RB_TYPE_P((VALUE)key, T_STRING));
3260+
3261+
int retval = vm_table_iter_wrapper(key, value, data, error);
3262+
if( retval == ST_DELETE) {
3263+
FL_UNSET((VALUE)key, RSTRING_FSTR);
3264+
}
3265+
return retval;
3266+
}
3267+
3268+
static int
3269+
vm_gen_ivar_iter_wrapper(st_data_t key, st_data_t value, st_data_t data, int error)
3270+
{
3271+
int retval = vm_table_iter_wrapper(key, value, data, error);
3272+
if( retval == ST_DELETE) {
3273+
FL_UNSET((VALUE)key, FL_EXIVAR);
3274+
}
3275+
return retval;
3276+
}
3277+
3278+
3279+
void
3280+
rb_gc_vm_weak_tbl_iter(vm_tbl_iter_callback_func cb, vm_tbl_update_callback_func ucb, void *data)
3281+
{
3282+
rb_vm_t *vm = GET_VM();
3283+
3284+
struct global_vm_tbl_iter_data iter_data = {
3285+
.callback = cb,
3286+
.update_callback = ucb,
3287+
.data = data
3288+
};
3289+
3290+
#define ITER_TABLE_WITH_CB(tbl) do { \
3291+
if (tbl->num_entries > 0) { \
3292+
st_foreach_with_replace( \
3293+
tbl, \
3294+
vm_table_iter_wrapper, \
3295+
vm_table_update_wrapper, \
3296+
(st_data_t)&iter_data \
3297+
); \
3298+
} \
3299+
} while (0)
3300+
3301+
ITER_TABLE_WITH_CB(vm->ci_table);
3302+
ITER_TABLE_WITH_CB(vm->overloaded_cme_table);
3303+
ITER_TABLE_WITH_CB(global_symbols.str_sym);
3304+
3305+
st_table *generic_iv_tbl = rb_generic_ivtbl_get();
3306+
if (generic_iv_tbl->num_entries > 0) {
3307+
st_foreach_with_replace(generic_iv_tbl, vm_gen_ivar_iter_wrapper, vm_table_update_wrapper, (st_data_t)&iter_data);
3308+
}
3309+
3310+
st_table *frozen_strings = GET_VM()->frozen_strings;
3311+
if (frozen_strings->num_entries > 0) {
3312+
st_foreach_with_replace(frozen_strings, vm_frozen_strings_iter_wrapper, vm_table_update_wrapper, (st_data_t)&iter_data);
3313+
}
3314+
}
3315+
32323316
void
32333317
rb_gc_update_vm_references(void *objspace)
32343318
{

Diff for: gc/gc.h

+5-5
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ struct rb_gc_vm_context {
1818
struct rb_execution_context_struct *ec;
1919
};
2020

21+
typedef int (*vm_tbl_iter_callback_func)(VALUE value, void *data);
22+
typedef int (*vm_tbl_update_callback_func)(VALUE *value, void *data);
23+
2124
RUBY_SYMBOL_EXPORT_BEGIN
2225
unsigned int rb_gc_vm_lock(void);
2326
void rb_gc_vm_unlock(unsigned int lev);
@@ -55,13 +58,10 @@ uint32_t rb_gc_get_shape(VALUE obj);
5558
void rb_gc_set_shape(VALUE obj, uint32_t shape_id);
5659
uint32_t rb_gc_rebuild_shape(VALUE obj, size_t size_pool_id);
5760
size_t rb_obj_memsize_of(VALUE obj);
58-
struct st_table *rb_gc_get_generic_ivar_table(void);
59-
struct st_table *rb_gc_get_frozen_strings_table(void);
60-
struct st_table *rb_gc_get_global_symbols_table(void);
61-
struct st_table *rb_gc_get_overloaded_cme_table(void);
62-
struct st_table *rb_gc_get_ci_table(void);
61+
void rb_gc_vm_weak_tbl_iter(vm_tbl_iter_callback_func cb, vm_tbl_update_callback_func ucb, void *data);
6362
RUBY_SYMBOL_EXPORT_END
6463

64+
6565
void rb_ractor_finish_marking(void);
6666

6767
// -------------------Private section begin------------------------

Diff for: gc/mmtk.c

+8-118
Original file line numberDiff line numberDiff line change
@@ -266,56 +266,12 @@ rb_mmtk_call_obj_free(MMTk_ObjectReference object)
266266
rb_gc_obj_free(objspace, obj);
267267
}
268268

269-
static int
270-
rb_mmtk_cleanup_generic_iv_tbl_i(st_data_t key, st_data_t val, st_data_t data)
271-
{
272-
// TODO: make this more performant. We should just free val and return ST_DELETE.
273-
MMTk_ObjectReference key_objref = (MMTk_ObjectReference)key;
274-
if (!mmtk_is_live_object(key_objref)) {
275-
rb_free_generic_ivar((VALUE)key);
276-
277-
RB_FL_UNSET((VALUE)key, FL_EXIVAR);
278-
}
279-
280-
return ST_CONTINUE;
281-
}
282-
283-
static void
284-
rb_mmtk_cleanup_generic_iv_tbl(void)
285-
{
286-
struct st_table *table = rb_gc_get_generic_ivar_table();
287-
288-
st_foreach(table, rb_mmtk_cleanup_generic_iv_tbl_i, (st_data_t)0);
289-
}
290-
291269
static size_t
292270
rb_mmtk_vm_live_bytes(void)
293271
{
294272
return 0;
295273
}
296274

297-
static int
298-
rb_mmtk_update_frozen_strings_table_i(st_data_t key, st_data_t val, st_data_t data)
299-
{
300-
RUBY_ASSERT(key == val);
301-
RUBY_ASSERT(RB_BUILTIN_TYPE(key) == T_STRING);
302-
RUBY_ASSERT(RB_FL_TEST(key, RSTRING_FSTR));
303-
304-
if (!mmtk_is_reachable((MMTk_ObjectReference)key)) {
305-
RB_FL_UNSET(key, RSTRING_FSTR);
306-
return ST_DELETE;
307-
}
308-
309-
return ST_CONTINUE;
310-
}
311-
312-
static void
313-
rb_mmtk_update_frozen_strings_table(void)
314-
{
315-
// TODO: replace with st_foreach_with_replace when GC is moving
316-
st_foreach(rb_gc_get_frozen_strings_table(), rb_mmtk_update_frozen_strings_table_i, 0);
317-
}
318-
319275
static int
320276
rb_mmtk_update_finalizer_table_i(st_data_t key, st_data_t value, st_data_t data)
321277
{
@@ -355,82 +311,21 @@ rb_mmtk_update_finalizer_table(void)
355311
}
356312

357313
static int
358-
rb_mmtk_update_obj_id_tables_i(st_data_t key, st_data_t val, st_data_t data)
359-
{
360-
RUBY_ASSERT(RB_FL_TEST(key, FL_SEEN_OBJ_ID));
361-
362-
if (!mmtk_is_reachable((MMTk_ObjectReference)key)) {
363-
RB_FL_UNSET(key, FL_SEEN_OBJ_ID);
364-
return ST_DELETE;
365-
}
366-
367-
return ST_CONTINUE;
368-
}
369-
370-
static void
371-
rb_mmtk_update_obj_id_tables(void)
372-
{
373-
struct objspace *objspace = rb_gc_get_objspace();
374-
375-
st_foreach(objspace->obj_to_id_tbl, rb_mmtk_update_obj_id_tables_i, 0);
376-
}
377-
378-
static int
379-
rb_mmtk_update_global_symbols_table_i(st_data_t key, st_data_t val, st_data_t data)
380-
{
381-
RUBY_ASSERT(RB_BUILTIN_TYPE(key) == T_SYMBOL);
382-
383-
if (!mmtk_is_reachable((MMTk_ObjectReference)key)) {
384-
return ST_DELETE;
385-
}
386-
387-
return ST_CONTINUE;
388-
}
389-
390-
static void
391-
rb_mmtk_update_global_symbols_table(void)
392-
{
393-
struct objspace *objspace = rb_gc_get_objspace();
394-
395-
// st_foreach(rb_gc_get_global_symbols_table(), rb_mmtk_update_global_symbols_table_i, 0);
396-
}
397-
398-
static int
399-
rb_mmtk_update_overloaded_cme_table_i(st_data_t key, st_data_t val, st_data_t data)
314+
rb_mmtk_update_table_i(VALUE val, void *data)
400315
{
401-
RUBY_ASSERT(RB_BUILTIN_TYPE(key) == T_SYMBOL);
402-
403-
if (!mmtk_is_reachable((MMTk_ObjectReference)key)) {
404-
return ST_DELETE;
405-
}
406-
407-
return ST_CONTINUE;
408-
}
409-
410-
static void
411-
rb_mmtk_update_overloaded_cme_table(void)
412-
{
413-
struct objspace *objspace = rb_gc_get_objspace();
414-
415-
st_foreach(rb_gc_get_overloaded_cme_table(), rb_mmtk_update_overloaded_cme_table_i, 0);
416-
}
417-
418-
static int
419-
rb_mmtk_update_ci_table_i(st_data_t key, st_data_t val, st_data_t data)
420-
{
421-
if (!mmtk_is_reachable((MMTk_ObjectReference)key)) {
316+
if (!mmtk_is_reachable((MMTk_ObjectReference)val)) {
422317
return ST_DELETE;
423318
}
424319

425320
return ST_CONTINUE;
426321
}
427322

428323
static void
429-
rb_mmtk_update_ci_table(void)
324+
rb_mmtk_update_global_tables(void)
430325
{
431-
struct objspace *objspace = rb_gc_get_objspace();
432-
433-
st_foreach(rb_gc_get_ci_table(), rb_mmtk_update_ci_table_i, 0);
326+
fprintf(stderr, "Hi Mom");
327+
rb_mmtk_update_finalizer_table();
328+
rb_gc_vm_weak_tbl_iter(rb_mmtk_update_table_i, NULL, NULL);
434329
}
435330

436331
// Bootup
@@ -449,16 +344,11 @@ MMTk_RubyUpcalls ruby_upcalls = {
449344
rb_mmtk_scan_object_ruby_style,
450345
rb_mmtk_call_gc_mark_children,
451346
rb_mmtk_call_obj_free,
452-
rb_mmtk_cleanup_generic_iv_tbl,
347+
NULL,
453348
NULL,
454349
NULL,
455350
rb_mmtk_vm_live_bytes,
456-
rb_mmtk_update_frozen_strings_table,
457-
rb_mmtk_update_finalizer_table,
458-
rb_mmtk_update_obj_id_tables,
459-
rb_mmtk_update_global_symbols_table,
460-
rb_mmtk_update_overloaded_cme_table,
461-
rb_mmtk_update_ci_table,
351+
rb_mmtk_update_global_tables,
462352
NULL,
463353
NULL,
464354
NULL,

Diff for: gc/mmtk.h

+1-8
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,6 @@ typedef uint32_t MMTk_AllocationSemantics;
2727

2828
#define MMTk_GC_THREAD_KIND_WORKER 1
2929

30-
typedef struct MMTk_st_table MMTk_st_table;
31-
3230
typedef struct MMTk_RubyBindingOptions {
3331
bool ractor_check_mode;
3432
size_t suffix_size;
@@ -73,18 +71,13 @@ typedef struct MMTk_RubyUpcalls {
7371
void *(*get_original_givtbl)(MMTk_ObjectReference object);
7472
void (*move_givtbl)(MMTk_ObjectReference old_objref, MMTk_ObjectReference new_objref);
7573
size_t (*vm_live_bytes)(void);
74+
void (*update_global_tables)(void);
7675
void (*update_frozen_strings_table)(void);
7776
void (*update_finalizer_table)(void);
7877
void (*update_obj_id_tables)(void);
7978
void (*update_global_symbols_table)(void);
8079
void (*update_overloaded_cme_table)(void);
8180
void (*update_ci_table)(void);
82-
struct MMTk_st_table *(*get_frozen_strings_table)(void);
83-
struct MMTk_st_table *(*get_finalizer_table)(void);
84-
struct MMTk_st_table *(*get_obj_id_tables)(void);
85-
struct MMTk_st_table *(*get_global_symbols_table)(void);
86-
struct MMTk_st_table *(*get_overloaded_cme_table)(void);
87-
struct MMTk_st_table *(*get_ci_table)(void);
8881
} MMTk_RubyUpcalls;
8982

9083
typedef struct MMTk_RawVecOfObjRef {

Diff for: gc/mmtk/src/abi.rs

+1-6
Original file line numberDiff line numberDiff line change
@@ -366,18 +366,13 @@ pub struct RubyUpcalls {
366366
pub get_original_givtbl: extern "C" fn(object: ObjectReference) -> *mut libc::c_void,
367367
pub move_givtbl: extern "C" fn(old_objref: ObjectReference, new_objref: ObjectReference),
368368
pub vm_live_bytes: extern "C" fn() -> usize,
369+
pub update_global_tables: extern "C" fn(),
369370
pub update_frozen_strings_table: extern "C" fn(),
370371
pub update_finalizer_table: extern "C" fn(),
371372
pub update_obj_id_tables: extern "C" fn(),
372373
pub update_global_symbols_table: extern "C" fn(),
373374
pub update_overloaded_cme_table: extern "C" fn(),
374375
pub update_ci_table: extern "C" fn(),
375-
pub get_frozen_strings_table: extern "C" fn() -> *mut st_table,
376-
pub get_finalizer_table: extern "C" fn() -> *mut st_table,
377-
pub get_obj_id_tables: extern "C" fn() -> *mut st_table,
378-
pub get_global_symbols_table: extern "C" fn() -> *mut st_table,
379-
pub get_overloaded_cme_table: extern "C" fn() -> *mut st_table,
380-
pub get_ci_table: extern "C" fn() -> *mut st_table,
381376

382377
// pub st_get_size_info: extern "C" fn(
383378
// table: *const st_table,

Diff for: gc/mmtk/src/binding.rs

-1
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,6 @@ impl RubyConfiguration {
5151
}
5252

5353
pub(crate) struct MovedGIVTblEntry {
54-
pub old_objref: ObjectReference,
5554
pub gen_ivtbl: *mut c_void,
5655
}
5756

Diff for: gc/mmtk/src/object_model.rs

-1
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,6 @@ impl ObjectModel<Ruby> for VMObjectModel {
8080
moved_givtbl.insert(
8181
to_obj,
8282
crate::binding::MovedGIVTblEntry {
83-
old_objref: from,
8483
gen_ivtbl: givtbl,
8584
},
8685
);

0 commit comments

Comments
 (0)