From 3c28bb53a7447c1e8b88da1ccbae76801d5b643a Mon Sep 17 00:00:00 2001 From: Matt Valentine-House Date: Mon, 6 Apr 2026 22:24:12 +0100 Subject: Make it obvious that field count guard is for debug This is because when `RVALUE_OVERHEAD` is positive, ie. when `RACTOR_CHECK_MODE` is enabled and we need to store the pointer to the owning ractor, we need to make sure there is enough space to store it. With the previous size pools the smallest size pool was 40 bytes, this gets expanded to 48 bytes when debug mode is on in order to make space for this extra pointer. because rb_obj_embedded_size(0) returns just the header with no field space it wants to be allocated in the 40 byte slot, this gives 16 bytes which is enough for RBasic only, but because this slot is 48 bytes in debug mode, we get the extra space for the pointer. When the smallest slot is 32 bytes it becomes 40 bytes in debug mode, this causes objects with no ivars to to get allocated in this pool because according to this calc it fits. but this doesn't leave the extra word for the ractor pointer. So in debug mode, we'll clamp this to 1 so that there's always enough space for 1 extra field to force allocation into the 40/48 byte pool. --- internal/object.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/internal/object.h b/internal/object.h index a6ff4e7476..3cf58d55d9 100644 --- a/internal/object.h +++ b/internal/object.h @@ -64,7 +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); } #endif /* INTERNAL_OBJECT_H */ -- cgit v1.2.3