From da9e38460a776dd8b10d7f42d4630a1e5f3dc455 Mon Sep 17 00:00:00 2001 From: Takashi Kokubun Date: Mon, 11 May 2026 14:20:56 -0700 Subject: [PATCH 1/2] publish.yml: Bump an example version a little 3.x is getting old. I wanted to at least see 4.x. --- .github/workflows/publish.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 6b045afea7f912..1b3df3a6eabd3e 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -9,7 +9,7 @@ on: version: description: 'Version of the Ruby package to release' required: true - default: '3.3.4' + default: '4.0.0' permissions: contents: read From 24a1b097ce92ddb2b5dce59435c557cd19223c43 Mon Sep 17 00:00:00 2001 From: Peter Zhu Date: Sat, 9 May 2026 15:56:17 -0400 Subject: [PATCH 2/2] 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. --- box.c | 6 +++--- class.c | 5 ++--- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/box.c b/box.c index 9c85426b8c51b8..b55e8bb137a576 100644 --- a/box.c +++ b/box.c @@ -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)) { diff --git a/class.c b/class.c index 91bea44cd93069..11cdd9a81ddc12 100644 --- a/class.c +++ b/class.c @@ -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;