Skip to content

Commit

Permalink
Generic global table iterator
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
eightbitraptor committed Oct 2, 2024
1 parent b0d0e6f commit 1271067
Show file tree
Hide file tree
Showing 8 changed files with 103 additions and 199 deletions.
84 changes: 84 additions & 0 deletions gc.c
Original file line number Diff line number Diff line change
Expand Up @@ -3229,6 +3229,90 @@ update_superclasses(void *objspace, VALUE obj)
extern rb_symbols_t ruby_global_symbols;
#define global_symbols ruby_global_symbols

struct global_vm_tbl_iter_data {
vm_tbl_iter_callback_func callback;
vm_tbl_update_callback_func update_callback;
void *data;
};

static int
vm_table_iter_wrapper(st_data_t key, st_data_t value, st_data_t data, int error)
{
struct global_vm_tbl_iter_data *iter_data = (struct global_vm_tbl_iter_data *)data;
vm_tbl_iter_callback_func callback = iter_data->callback;

return (*callback)((VALUE)key, iter_data->data);
}

static int
vm_table_update_wrapper(st_data_t *key, st_data_t *value, st_data_t data, int existing)
{
struct global_vm_tbl_iter_data *iter_data = (struct global_vm_tbl_iter_data *)data;
vm_tbl_update_callback_func callback = iter_data->update_callback;

return (*callback)((VALUE *)key, iter_data->data);
}

static int
vm_frozen_strings_iter_wrapper(st_data_t key, st_data_t value, st_data_t data, int error)
{
GC_ASSERT(RB_TYPE_P((VALUE)key, T_STRING));

int retval = vm_table_iter_wrapper(key, value, data, error);
if( retval == ST_DELETE) {
FL_UNSET((VALUE)key, RSTRING_FSTR);
}
return retval;
}

static int
vm_gen_ivar_iter_wrapper(st_data_t key, st_data_t value, st_data_t data, int error)
{
int retval = vm_table_iter_wrapper(key, value, data, error);
if( retval == ST_DELETE) {
FL_UNSET((VALUE)key, FL_EXIVAR);
}
return retval;
}


void
rb_gc_vm_weak_tbl_iter(vm_tbl_iter_callback_func cb, vm_tbl_update_callback_func ucb, void *data)
{
rb_vm_t *vm = GET_VM();

struct global_vm_tbl_iter_data iter_data = {
.callback = cb,
.update_callback = ucb,
.data = data
};

#define ITER_TABLE_WITH_CB(tbl) do { \
if (tbl->num_entries > 0) { \
st_foreach_with_replace( \
tbl, \
vm_table_iter_wrapper, \
vm_table_update_wrapper, \
(st_data_t)&iter_data \
); \
} \
} while (0)

ITER_TABLE_WITH_CB(vm->ci_table);
ITER_TABLE_WITH_CB(vm->overloaded_cme_table);
ITER_TABLE_WITH_CB(global_symbols.str_sym);

st_table *generic_iv_tbl = rb_generic_ivtbl_get();
if (generic_iv_tbl->num_entries > 0) {
st_foreach_with_replace(generic_iv_tbl, vm_gen_ivar_iter_wrapper, vm_table_update_wrapper, (st_data_t)&iter_data);
}

st_table *frozen_strings = GET_VM()->frozen_strings;
if (frozen_strings->num_entries > 0) {
st_foreach_with_replace(frozen_strings, vm_frozen_strings_iter_wrapper, vm_table_update_wrapper, (st_data_t)&iter_data);
}
}

void
rb_gc_update_vm_references(void *objspace)
{
Expand Down
10 changes: 5 additions & 5 deletions gc/gc.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ struct rb_gc_vm_context {
struct rb_execution_context_struct *ec;
};

typedef int (*vm_tbl_iter_callback_func)(VALUE value, void *data);
typedef int (*vm_tbl_update_callback_func)(VALUE *value, void *data);

RUBY_SYMBOL_EXPORT_BEGIN
unsigned int rb_gc_vm_lock(void);
void rb_gc_vm_unlock(unsigned int lev);
Expand Down Expand Up @@ -55,13 +58,10 @@ uint32_t rb_gc_get_shape(VALUE obj);
void rb_gc_set_shape(VALUE obj, uint32_t shape_id);
uint32_t rb_gc_rebuild_shape(VALUE obj, size_t size_pool_id);
size_t rb_obj_memsize_of(VALUE obj);
struct st_table *rb_gc_get_generic_ivar_table(void);
struct st_table *rb_gc_get_frozen_strings_table(void);
struct st_table *rb_gc_get_global_symbols_table(void);
struct st_table *rb_gc_get_overloaded_cme_table(void);
struct st_table *rb_gc_get_ci_table(void);
void rb_gc_vm_weak_tbl_iter(vm_tbl_iter_callback_func cb, vm_tbl_update_callback_func ucb, void *data);
RUBY_SYMBOL_EXPORT_END


void rb_ractor_finish_marking(void);

// -------------------Private section begin------------------------
Expand Down
126 changes: 8 additions & 118 deletions gc/mmtk.c
Original file line number Diff line number Diff line change
Expand Up @@ -266,56 +266,12 @@ rb_mmtk_call_obj_free(MMTk_ObjectReference object)
rb_gc_obj_free(objspace, obj);
}

static int
rb_mmtk_cleanup_generic_iv_tbl_i(st_data_t key, st_data_t val, st_data_t data)
{
// TODO: make this more performant. We should just free val and return ST_DELETE.
MMTk_ObjectReference key_objref = (MMTk_ObjectReference)key;
if (!mmtk_is_live_object(key_objref)) {
rb_free_generic_ivar((VALUE)key);

RB_FL_UNSET((VALUE)key, FL_EXIVAR);
}

return ST_CONTINUE;
}

static void
rb_mmtk_cleanup_generic_iv_tbl(void)
{
struct st_table *table = rb_gc_get_generic_ivar_table();

st_foreach(table, rb_mmtk_cleanup_generic_iv_tbl_i, (st_data_t)0);
}

static size_t
rb_mmtk_vm_live_bytes(void)
{
return 0;
}

static int
rb_mmtk_update_frozen_strings_table_i(st_data_t key, st_data_t val, st_data_t data)
{
RUBY_ASSERT(key == val);
RUBY_ASSERT(RB_BUILTIN_TYPE(key) == T_STRING);
RUBY_ASSERT(RB_FL_TEST(key, RSTRING_FSTR));

if (!mmtk_is_reachable((MMTk_ObjectReference)key)) {
RB_FL_UNSET(key, RSTRING_FSTR);
return ST_DELETE;
}

return ST_CONTINUE;
}

static void
rb_mmtk_update_frozen_strings_table(void)
{
// TODO: replace with st_foreach_with_replace when GC is moving
st_foreach(rb_gc_get_frozen_strings_table(), rb_mmtk_update_frozen_strings_table_i, 0);
}

static int
rb_mmtk_update_finalizer_table_i(st_data_t key, st_data_t value, st_data_t data)
{
Expand Down Expand Up @@ -355,82 +311,21 @@ rb_mmtk_update_finalizer_table(void)
}

static int
rb_mmtk_update_obj_id_tables_i(st_data_t key, st_data_t val, st_data_t data)
{
RUBY_ASSERT(RB_FL_TEST(key, FL_SEEN_OBJ_ID));

if (!mmtk_is_reachable((MMTk_ObjectReference)key)) {
RB_FL_UNSET(key, FL_SEEN_OBJ_ID);
return ST_DELETE;
}

return ST_CONTINUE;
}

static void
rb_mmtk_update_obj_id_tables(void)
{
struct objspace *objspace = rb_gc_get_objspace();

st_foreach(objspace->obj_to_id_tbl, rb_mmtk_update_obj_id_tables_i, 0);
}

static int
rb_mmtk_update_global_symbols_table_i(st_data_t key, st_data_t val, st_data_t data)
{
RUBY_ASSERT(RB_BUILTIN_TYPE(key) == T_SYMBOL);

if (!mmtk_is_reachable((MMTk_ObjectReference)key)) {
return ST_DELETE;
}

return ST_CONTINUE;
}

static void
rb_mmtk_update_global_symbols_table(void)
{
struct objspace *objspace = rb_gc_get_objspace();

// st_foreach(rb_gc_get_global_symbols_table(), rb_mmtk_update_global_symbols_table_i, 0);
}

static int
rb_mmtk_update_overloaded_cme_table_i(st_data_t key, st_data_t val, st_data_t data)
rb_mmtk_update_table_i(VALUE val, void *data)
{
RUBY_ASSERT(RB_BUILTIN_TYPE(key) == T_SYMBOL);

if (!mmtk_is_reachable((MMTk_ObjectReference)key)) {
return ST_DELETE;
}

return ST_CONTINUE;
}

static void
rb_mmtk_update_overloaded_cme_table(void)
{
struct objspace *objspace = rb_gc_get_objspace();

st_foreach(rb_gc_get_overloaded_cme_table(), rb_mmtk_update_overloaded_cme_table_i, 0);
}

static int
rb_mmtk_update_ci_table_i(st_data_t key, st_data_t val, st_data_t data)
{
if (!mmtk_is_reachable((MMTk_ObjectReference)key)) {
if (!mmtk_is_reachable((MMTk_ObjectReference)val)) {
return ST_DELETE;
}

return ST_CONTINUE;
}

static void
rb_mmtk_update_ci_table(void)
rb_mmtk_update_global_tables(void)
{
struct objspace *objspace = rb_gc_get_objspace();

st_foreach(rb_gc_get_ci_table(), rb_mmtk_update_ci_table_i, 0);
fprintf(stderr, "Hi Mom");
rb_mmtk_update_finalizer_table();
rb_gc_vm_weak_tbl_iter(rb_mmtk_update_table_i, NULL, NULL);
}

// Bootup
Expand All @@ -449,16 +344,11 @@ MMTk_RubyUpcalls ruby_upcalls = {
rb_mmtk_scan_object_ruby_style,
rb_mmtk_call_gc_mark_children,
rb_mmtk_call_obj_free,
rb_mmtk_cleanup_generic_iv_tbl,
NULL,
NULL,
NULL,
rb_mmtk_vm_live_bytes,
rb_mmtk_update_frozen_strings_table,
rb_mmtk_update_finalizer_table,
rb_mmtk_update_obj_id_tables,
rb_mmtk_update_global_symbols_table,
rb_mmtk_update_overloaded_cme_table,
rb_mmtk_update_ci_table,
rb_mmtk_update_global_tables,
NULL,
NULL,
NULL,
Expand Down
9 changes: 1 addition & 8 deletions gc/mmtk.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,6 @@ typedef uint32_t MMTk_AllocationSemantics;

#define MMTk_GC_THREAD_KIND_WORKER 1

typedef struct MMTk_st_table MMTk_st_table;

typedef struct MMTk_RubyBindingOptions {
bool ractor_check_mode;
size_t suffix_size;
Expand Down Expand Up @@ -73,18 +71,13 @@ typedef struct MMTk_RubyUpcalls {
void *(*get_original_givtbl)(MMTk_ObjectReference object);
void (*move_givtbl)(MMTk_ObjectReference old_objref, MMTk_ObjectReference new_objref);
size_t (*vm_live_bytes)(void);
void (*update_global_tables)(void);
void (*update_frozen_strings_table)(void);
void (*update_finalizer_table)(void);
void (*update_obj_id_tables)(void);
void (*update_global_symbols_table)(void);
void (*update_overloaded_cme_table)(void);
void (*update_ci_table)(void);
struct MMTk_st_table *(*get_frozen_strings_table)(void);
struct MMTk_st_table *(*get_finalizer_table)(void);
struct MMTk_st_table *(*get_obj_id_tables)(void);
struct MMTk_st_table *(*get_global_symbols_table)(void);
struct MMTk_st_table *(*get_overloaded_cme_table)(void);
struct MMTk_st_table *(*get_ci_table)(void);
} MMTk_RubyUpcalls;

typedef struct MMTk_RawVecOfObjRef {
Expand Down
7 changes: 1 addition & 6 deletions gc/mmtk/src/abi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -366,18 +366,13 @@ pub struct RubyUpcalls {
pub get_original_givtbl: extern "C" fn(object: ObjectReference) -> *mut libc::c_void,
pub move_givtbl: extern "C" fn(old_objref: ObjectReference, new_objref: ObjectReference),
pub vm_live_bytes: extern "C" fn() -> usize,
pub update_global_tables: extern "C" fn(),
pub update_frozen_strings_table: extern "C" fn(),
pub update_finalizer_table: extern "C" fn(),
pub update_obj_id_tables: extern "C" fn(),
pub update_global_symbols_table: extern "C" fn(),
pub update_overloaded_cme_table: extern "C" fn(),
pub update_ci_table: extern "C" fn(),
pub get_frozen_strings_table: extern "C" fn() -> *mut st_table,
pub get_finalizer_table: extern "C" fn() -> *mut st_table,
pub get_obj_id_tables: extern "C" fn() -> *mut st_table,
pub get_global_symbols_table: extern "C" fn() -> *mut st_table,
pub get_overloaded_cme_table: extern "C" fn() -> *mut st_table,
pub get_ci_table: extern "C" fn() -> *mut st_table,

// pub st_get_size_info: extern "C" fn(
// table: *const st_table,
Expand Down
1 change: 0 additions & 1 deletion gc/mmtk/src/binding.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@ impl RubyConfiguration {
}

pub(crate) struct MovedGIVTblEntry {
pub old_objref: ObjectReference,
pub gen_ivtbl: *mut c_void,
}

Expand Down
1 change: 0 additions & 1 deletion gc/mmtk/src/object_model.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,6 @@ impl ObjectModel<Ruby> for VMObjectModel {
moved_givtbl.insert(
to_obj,
crate::binding::MovedGIVTblEntry {
old_objref: from,
gen_ivtbl: givtbl,
},
);
Expand Down
Loading

0 comments on commit 1271067

Please sign in to comment.