From cd9f447be247478d2eb3da985295735cce20cb23 Mon Sep 17 00:00:00 2001 From: Jean Boussier Date: Mon, 16 Jun 2025 11:19:12 +0200 Subject: Refactor generic fields to use `T_IMEMO/fields` objects. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Followup: https://github.com/ruby/ruby/pull/13589 This simplify a lot of things, as we no longer need to manually manage the memory, we can use the Read-Copy-Update pattern and avoid numerous race conditions. Co-Authored-By: Étienne Barrié --- imemo.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) (limited to 'imemo.c') diff --git a/imemo.c b/imemo.c index f465c0098b..a4393ffe79 100644 --- a/imemo.c +++ b/imemo.c @@ -147,6 +147,23 @@ rb_imemo_fields_new_complex(VALUE klass, size_t capa) return imemo_fields_new_complex(klass, capa); } +static int +imemo_fields_trigger_wb_i(st_data_t key, st_data_t value, st_data_t arg) +{ + VALUE field_obj = (VALUE)arg; + RB_OBJ_WRITTEN(field_obj, Qundef, (VALUE)value); + return ST_CONTINUE; +} + +VALUE +rb_imemo_fields_new_complex_tbl(VALUE klass, st_table *tbl) +{ + VALUE fields = imemo_fields_new(klass, sizeof(struct rb_fields)); + IMEMO_OBJ_FIELDS(fields)->as.complex.table = tbl; + st_foreach(tbl, imemo_fields_trigger_wb_i, (st_data_t)fields); + return fields; +} + VALUE rb_imemo_fields_clone(VALUE fields_obj) { @@ -168,6 +185,19 @@ rb_imemo_fields_clone(VALUE fields_obj) return clone; } +void +rb_imemo_fields_clear(VALUE fields_obj) +{ + // When replacing an imemo/fields by another one, we must clear + // its shape so that gc.c:obj_free_object_id won't be called. + if (rb_shape_obj_too_complex_p(fields_obj)) { + RBASIC_SET_SHAPE_ID(fields_obj, ROOT_TOO_COMPLEX_SHAPE_ID); + } + else { + RBASIC_SET_SHAPE_ID(fields_obj, ROOT_SHAPE_ID); + } +} + /* ========================================================================= * memsize * ========================================================================= */ -- cgit v1.2.3