From 3abdd4241fd5231a5711ce1b087d660c667ef30d Mon Sep 17 00:00:00 2001 From: Jean Boussier Date: Thu, 22 May 2025 14:01:46 +0200 Subject: Turn `rb_classext_t.fields` into a T_IMEMO/class_fields This behave almost exactly as a T_OBJECT, the layout is entirely compatible. This aims to solve two problems. First, it solves the problem of namspaced classes having a single `shape_id`. Now each namespaced classext has an object that can hold the namespace specific shape. Second, it open the door to later make class instance variable writes atomics, hence be able to read class variables without locking the VM. In the future, in multi-ractor mode, we can do the write on a copy of the `fields_obj` and then atomically swap it. Considerations: - Right now the `RClass` shape_id is always synchronized, but with namespace we should likely mark classes that have multiple namespace with a specific shape flag. --- shape.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) (limited to 'shape.c') diff --git a/shape.c b/shape.c index 021ecb1a9e..6f187552de 100644 --- a/shape.c +++ b/shape.c @@ -396,6 +396,13 @@ rb_obj_shape_id(VALUE obj) return SPECIAL_CONST_SHAPE_ID; } + if (BUILTIN_TYPE(obj) == T_CLASS || BUILTIN_TYPE(obj) == T_MODULE) { + VALUE fields_obj = RCLASS_FIELDS_OBJ(obj); + if (fields_obj) { + return RBASIC_SHAPE_ID(fields_obj); + } + return ROOT_SHAPE_ID; + } return RBASIC_SHAPE_ID(obj); } @@ -881,14 +888,11 @@ shape_get_next(rb_shape_t *shape, VALUE obj, ID id, bool emit_warnings) #endif VALUE klass; - switch (BUILTIN_TYPE(obj)) { - case T_CLASS: - case T_MODULE: - klass = rb_singleton_class(obj); - break; - default: + if (IMEMO_TYPE_P(obj, imemo_class_fields)) { // HACK + klass = CLASS_OF(obj); + } + else { klass = rb_obj_class(obj); - break; } bool allow_new_shape = RCLASS_VARIATION_COUNT(klass) < SHAPE_MAX_VARIATIONS; -- cgit v1.2.3