diff options
-rw-r--r-- | class.c | 33 | ||||
-rw-r--r-- | gc.c | 14 | ||||
-rw-r--r-- | internal/class.h | 3 |
3 files changed, 26 insertions, 24 deletions
@@ -259,17 +259,21 @@ rb_class_boot(VALUE super) return (VALUE)klass; } -void -rb_class_remove_superclasses(VALUE klass) +static VALUE * +class_superclasses_including_self(VALUE klass) { - if (!RB_TYPE_P(klass, T_CLASS)) - return; + if (FL_TEST_RAW(klass, RCLASS_SUPERCLASSES_INCLUDE_SELF)) + return RCLASS_SUPERCLASSES(klass); - if (RCLASS_SUPERCLASSES(klass)) - xfree(RCLASS_SUPERCLASSES(klass)); + size_t depth = RCLASS_SUPERCLASS_DEPTH(klass); + VALUE *superclasses = xmalloc(sizeof(VALUE) * (depth + 1)); + if (depth > 0) + memcpy(superclasses, RCLASS_SUPERCLASSES(klass), sizeof(VALUE) * depth); + superclasses[depth] = klass; - RCLASS_SUPERCLASSES(klass) = NULL; - RCLASS_SUPERCLASS_DEPTH(klass) = 0; + RCLASS_SUPERCLASSES(klass) = superclasses; + FL_SET_RAW(klass, RCLASS_SUPERCLASSES_INCLUDE_SELF); + return superclasses; } void @@ -303,17 +307,8 @@ rb_class_update_superclasses(VALUE klass) return; } - size_t parent_num = RCLASS_SUPERCLASS_DEPTH(super); - size_t num = parent_num + 1; - - VALUE *superclasses = xmalloc(sizeof(VALUE) * num); - superclasses[parent_num] = super; - if (parent_num > 0) { - memcpy(superclasses, RCLASS_SUPERCLASSES(super), sizeof(VALUE) * parent_num); - } - - RCLASS_SUPERCLASSES(klass) = superclasses; - RCLASS_SUPERCLASS_DEPTH(klass) = num; + RCLASS_SUPERCLASSES(klass) = class_superclasses_including_self(super); + RCLASS_SUPERCLASS_DEPTH(klass) = RCLASS_SUPERCLASS_DEPTH(super) + 1; } void @@ -3187,7 +3187,9 @@ obj_free(rb_objspace_t *objspace, VALUE obj) rb_class_remove_subclass_head(obj); rb_class_remove_from_module_subclasses(obj); rb_class_remove_from_super_subclasses(obj); - rb_class_remove_superclasses(obj); + if (FL_TEST_RAW(obj, RCLASS_SUPERCLASSES_INCLUDE_SELF)) { + xfree(RCLASS_SUPERCLASSES(obj)); + } #if SIZEOF_SERIAL_T != SIZEOF_VALUE && USE_RVARGC xfree(RCLASS(obj)->class_serial_ptr); #endif @@ -4620,7 +4622,9 @@ obj_memsize_of(VALUE obj, int use_all_types) if (RCLASS_CC_TBL(obj)) { size += cc_table_memsize(RCLASS_CC_TBL(obj)); } - size += RCLASS_SUPERCLASS_DEPTH(obj) * sizeof(VALUE); + if (FL_TEST_RAW(obj, RCLASS_SUPERCLASSES_INCLUDE_SELF)) { + size += (RCLASS_SUPERCLASS_DEPTH(obj) + 1) * sizeof(VALUE); + } #if !USE_RVARGC size += sizeof(rb_classext_t); #endif @@ -10037,8 +10041,10 @@ update_class_ext(rb_objspace_t *objspace, rb_classext_t *ext) static void update_superclasses(rb_objspace_t *objspace, VALUE obj) { - for (size_t i = 0; i < RCLASS_SUPERCLASS_DEPTH(obj); i++) { - UPDATE_IF_MOVED(objspace, RCLASS_SUPERCLASSES(obj)[i]); + if (FL_TEST_RAW(obj, RCLASS_SUPERCLASSES_INCLUDE_SELF)) { + for (size_t i = 0; i < RCLASS_SUPERCLASS_DEPTH(obj) + 1; i++) { + UPDATE_IF_MOVED(objspace, RCLASS_SUPERCLASSES(obj)[i]); + } } } diff --git a/internal/class.h b/internal/class.h index c6151299c7..be2f703fc8 100644 --- a/internal/class.h +++ b/internal/class.h @@ -124,13 +124,14 @@ typedef struct rb_classext_struct rb_classext_t; #define RICLASS_IS_ORIGIN FL_USER5 #define RCLASS_CLONED FL_USER6 +#define RCLASS_SUPERCLASSES_INCLUDE_SELF FL_USER7 #define RICLASS_ORIGIN_SHARED_MTBL FL_USER8 /* class.c */ void rb_class_subclass_add(VALUE super, VALUE klass); void rb_class_remove_from_super_subclasses(VALUE); void rb_class_update_superclasses(VALUE); -void rb_class_remove_superclasses(VALUE); +size_t rb_class_superclasses_memsize(VALUE); void rb_class_remove_subclass_head(VALUE); int rb_singleton_class_internal_p(VALUE sklass); VALUE rb_class_boot(VALUE); |