diff --git a/compile.c b/compile.c index e6748d38b309da..ac1bdfe0f9278b 100644 --- a/compile.c +++ b/compile.c @@ -12167,7 +12167,7 @@ iseq_build_from_ary_body(rb_iseq_t *iseq, LINK_ANCHOR *const anchor, case TS_CDHASH: { int i; - VALUE map = rb_hash_alloc_fixed_size(Qfalse, RARRAY_LEN(op)/2); + VALUE map = rb_hash_new_with_size(RARRAY_LEN(op)/2); RHASH_TBL_RAW(map)->type = &cdhash_type; op = rb_to_array_type(op); @@ -12179,7 +12179,7 @@ iseq_build_from_ary_body(rb_iseq_t *iseq, LINK_ANCHOR *const anchor, rb_hash_aset(map, key, (VALUE)label | 1); } RB_GC_GUARD(op); - RB_OBJ_SET_SHAREABLE(map); // allow mutation while compiling + RB_OBJ_SET_SHAREABLE(rb_obj_hide(map)); // allow mutation while compiling argv[j] = map; RB_OBJ_WRITTEN(iseq, Qundef, map); } diff --git a/hash.c b/hash.c index 700c429d2aeb49..8507c9c8f5328d 100644 --- a/hash.c +++ b/hash.c @@ -604,6 +604,7 @@ RHASH_AR_TABLE_SIZE_DEC(VALUE h) static inline void RHASH_AR_TABLE_CLEAR(VALUE h) { + RUBY_ASSERT(rb_gc_obj_slot_size(h) >= sizeof(struct RHash) + sizeof(ar_table)); RBASIC(h)->flags &= ~RHASH_AR_TABLE_SIZE_MASK; RBASIC(h)->flags &= ~RHASH_AR_TABLE_BOUND_MASK; @@ -719,6 +720,8 @@ ar_force_convert_table(VALUE hash, const char *file, int line) st_hash_t hashes[RHASH_AR_TABLE_MAX_SIZE]; unsigned int bound, size; + RUBY_ASSERT(rb_gc_obj_slot_size(hash) >= sizeof(struct RHash) + sizeof(ar_table)); + // prepare hash values do { st_data_t keys[RHASH_AR_TABLE_MAX_SIZE]; diff --git a/internal/object.h b/internal/object.h index 3cf58d55d940e3..99aa1f524bab5d 100644 --- a/internal/object.h +++ b/internal/object.h @@ -64,9 +64,9 @@ RBASIC_SET_CLASS(VALUE obj, VALUE klass) static inline size_t rb_obj_embedded_size(uint32_t fields_count) { -#if (defined(RACTOR_CHECK_MODE) && RACTOR_CHECK_MODE) || (defined(GC_DEBUG) && GC_DEBUG) - if (fields_count < 1) fields_count = 1; -#endif - return offsetof(struct RObject, as.ary) + (sizeof(VALUE) * fields_count); + size_t size = offsetof(struct RObject, as.ary) + (sizeof(VALUE) * fields_count); + // Ensure enough room for the heap pointer if this expands + if (size < sizeof(struct RObject)) size = sizeof(struct RObject); + return size; } #endif /* INTERNAL_OBJECT_H */ diff --git a/zjit/src/hir_type/gen_hir_type.rb b/zjit/src/hir_type/gen_hir_type.rb index 37919425cee51f..aca8e574d61457 100644 --- a/zjit/src/hir_type/gen_hir_type.rb +++ b/zjit/src/hir_type/gen_hir_type.rb @@ -89,7 +89,7 @@ def base_type name, c_name: nil [type, exact] end -# Define a new type that cannot be subclassed. +# Define a new type that has no subclasses and cannot be subclassed. # If c_name is given, mark the rb_cXYZ object as equivalent to this type. def final_type name, base: $object, c_name: nil if c_name @@ -109,7 +109,9 @@ def final_type name, base: $object, c_name: nil base_type "Set", c_name: "rb_cSet" base_type "Regexp", c_name: "rb_cRegexp" module_class, _ = base_type "Module", c_name: "rb_cModule" -class_ = final_type "Class", base: module_class, c_name: "rb_cClass" +# Class cannot be subclassed by doing `class Sub < Class`, +# but every metaclass is a subclass of `Class`. It's not final. +module_class.subtype "Class" numeric, _ = base_type "Numeric", c_name: "rb_cNumeric" diff --git a/zjit/src/hir_type/hir_type.inc.rs b/zjit/src/hir_type/hir_type.inc.rs index f37cd57b319445..46c45f17f39e07 100644 --- a/zjit/src/hir_type/hir_type.inc.rs +++ b/zjit/src/hir_type/hir_type.inc.rs @@ -9,7 +9,7 @@ mod bits { pub const BasicObjectSubclass: u64 = 1u64 << 3; pub const Bignum: u64 = 1u64 << 4; pub const BoolExact: u64 = FalseClass | TrueClass; - pub const BuiltinExact: u64 = ArrayExact | BasicObjectExact | Class | FalseClass | Float | HashExact | Integer | ModuleExact | NilClass | NumericExact | ObjectExact | RangeExact | RegexpExact | SetExact | StringExact | Symbol | TrueClass; + pub const BuiltinExact: u64 = ArrayExact | BasicObjectExact | FalseClass | Float | HashExact | Integer | ModuleExact | NilClass | NumericExact | ObjectExact | RangeExact | RegexpExact | SetExact | StringExact | Symbol | TrueClass; pub const CBool: u64 = 1u64 << 5; pub const CDouble: u64 = 1u64 << 6; pub const CInt: u64 = CSigned | CUnsigned; @@ -231,7 +231,7 @@ pub mod types { pub const Truthy: Type = Type::from_bits(bits::Truthy); pub const TypedTData: Type = Type::from_bits(bits::TypedTData); pub const Undef: Type = Type::from_bits(bits::Undef); - pub const ExactBitsAndClass: [(u64, *const VALUE); 17] = [ + pub const ExactBitsAndClass: [(u64, *const VALUE); 16] = [ (bits::ObjectExact, &raw const crate::cruby::rb_cObject), (bits::BasicObjectExact, &raw const crate::cruby::rb_cBasicObject), (bits::StringExact, &raw const crate::cruby::rb_cString), @@ -241,7 +241,6 @@ pub mod types { (bits::SetExact, &raw const crate::cruby::rb_cSet), (bits::RegexpExact, &raw const crate::cruby::rb_cRegexp), (bits::ModuleExact, &raw const crate::cruby::rb_cModule), - (bits::Class, &raw const crate::cruby::rb_cClass), (bits::NumericExact, &raw const crate::cruby::rb_cNumeric), (bits::Integer, &raw const crate::cruby::rb_cInteger), (bits::Float, &raw const crate::cruby::rb_cFloat), @@ -250,9 +249,8 @@ pub mod types { (bits::TrueClass, &raw const crate::cruby::rb_cTrueClass), (bits::FalseClass, &raw const crate::cruby::rb_cFalseClass), ]; - pub const SubclassBitsAndClass: [(u64, *const VALUE); 17] = [ + pub const SubclassBitsAndClass: [(u64, *const VALUE); 16] = [ (bits::ArraySubclass, &raw const crate::cruby::rb_cArray), - (bits::Class, &raw const crate::cruby::rb_cClass), (bits::FalseClass, &raw const crate::cruby::rb_cFalseClass), (bits::Integer, &raw const crate::cruby::rb_cInteger), (bits::HashSubclass, &raw const crate::cruby::rb_cHash), @@ -269,9 +267,8 @@ pub mod types { (bits::ObjectSubclass, &raw const crate::cruby::rb_cObject), (bits::BasicObjectSubclass, &raw const crate::cruby::rb_cBasicObject), ]; - pub const InexactBitsAndClass: [(u64, *const VALUE); 17] = [ + pub const InexactBitsAndClass: [(u64, *const VALUE); 16] = [ (bits::Array, &raw const crate::cruby::rb_cArray), - (bits::Class, &raw const crate::cruby::rb_cClass), (bits::FalseClass, &raw const crate::cruby::rb_cFalseClass), (bits::Integer, &raw const crate::cruby::rb_cInteger), (bits::Hash, &raw const crate::cruby::rb_cHash),