diff options
| author | Peter Zhu <peter@peterzhu.ca> | 2026-05-09 15:56:17 -0400 |
|---|---|---|
| committer | Peter Zhu <peter@peterzhu.ca> | 2026-05-11 19:16:45 -0400 |
| commit | 24a1b097ce92ddb2b5dce59435c557cd19223c43 (patch) | |
| tree | 77d4efda4df21716bf1c34d501db50468e00d244 | |
| parent | da9e38460a776dd8b10d7f42d4630a1e5f3dc455 (diff) | |
Don't use obj_id in Box classext_cow_classes
Using obj_id in classext_cow_classes is slow and also is a problem when
freeing classes because the lookup requires the EC, which is not available
if it is running on a GC thread. This will cause it to crash on MMTk.
We don't need to use the obj_id as the key in the classext_cow_classes
st_table because the class itself is pinned and won't move so we can use
it as the key instead.
| -rw-r--r-- | box.c | 6 | ||||
| -rw-r--r-- | class.c | 5 |
2 files changed, 5 insertions, 6 deletions
@@ -234,7 +234,7 @@ rb_box_entry_mark(void *ptr) rb_gc_mark(box->ruby_dln_libmap); rb_gc_mark(box->gvar_tbl); if (box->classext_cow_classes) { - rb_mark_tbl(box->classext_cow_classes); + rb_mark_set(box->classext_cow_classes); } } @@ -271,10 +271,10 @@ free_box_st_tables(void *ptr) } static int -free_classext_for_box(st_data_t _key, st_data_t obj_value, st_data_t box_arg) +free_classext_for_box(st_data_t key, st_data_t _value, st_data_t box_arg) { rb_classext_t *ext; - VALUE obj = (VALUE)obj_value; + VALUE obj = (VALUE)key; const rb_box_t *box = (const rb_box_t *)box_arg; if (RB_TYPE_P(obj, T_CLASS) || RB_TYPE_P(obj, T_MODULE)) { @@ -89,8 +89,7 @@ rb_class_unlink_classext(VALUE klass, const rb_box_t *box) { st_data_t ext; st_data_t key = (st_data_t)box->box_object; - VALUE obj_id = rb_obj_id(klass); - st_delete(box->classext_cow_classes, &obj_id, 0); + st_delete(box->classext_cow_classes, &klass, 0); st_delete(RCLASS_CLASSEXT_TBL(klass), &key, &ext); return (rb_classext_t *)ext; } @@ -203,7 +202,7 @@ rb_class_set_box_classext(VALUE obj, const rb_box_t *box, rb_classext_t *ext) // (e.g. st_insert below) that could trigger GC. rb_gc_writebarrier_remember(obj); - st_insert(box->classext_cow_classes, (st_data_t)rb_obj_id(obj), obj); + st_insert(box->classext_cow_classes, (st_data_t)obj, 0); } RUBY_EXTERN rb_serial_t ruby_vm_global_cvar_state; |
