Separately allocate class_serial on 32-bit systems

On 32-bit systems, VWA causes class_serial to not be aligned (it only
guarantees 4 byte alignment but class_serial is 8 bytes and requires 8
byte alignment). This commit uses a hack to allocate class_serial
through malloc. Once VWA allocates with 8 byte alignment in the future,
we will revert this commit.
This commit is contained in:
Peter Zhu 2022-01-14 13:59:38 -05:00
parent ca3d405242
commit 6b7eff9086
Notes: git 2022-01-15 04:36:54 +09:00
3 changed files with 16 additions and 2 deletions

View File

@ -208,6 +208,9 @@ class_alloc(VALUE flags, VALUE klass)
#if USE_RVARGC #if USE_RVARGC
memset(RCLASS_EXT(obj), 0, sizeof(rb_classext_t)); memset(RCLASS_EXT(obj), 0, sizeof(rb_classext_t));
# if SIZEOF_SERIAL_T != SIZEOF_VALUE
RCLASS(obj)->class_serial_ptr = ZALLOC(rb_serial_t);
# endif
#else #else
obj->ptr = ZALLOC(rb_classext_t); obj->ptr = ZALLOC(rb_classext_t);
#endif #endif

4
gc.c
View File

@ -3132,6 +3132,10 @@ obj_free(rb_objspace_t *objspace, VALUE obj)
rb_class_remove_subclass_head(obj); rb_class_remove_subclass_head(obj);
rb_class_remove_from_module_subclasses(obj); rb_class_remove_from_module_subclasses(obj);
rb_class_remove_from_super_subclasses(obj); rb_class_remove_from_super_subclasses(obj);
#if SIZEOF_SERIAL_T != SIZEOF_VALUE && USE_RVARGC
xfree(RCLASS(obj)->class_serial_ptr);
#endif
#if !USE_RVARGC #if !USE_RVARGC
if (RCLASS_EXT(obj)) if (RCLASS_EXT(obj))
xfree(RCLASS_EXT(obj)); xfree(RCLASS_EXT(obj));

View File

@ -55,7 +55,7 @@ struct rb_classext_struct {
* included. Hopefully that makes sense. * included. Hopefully that makes sense.
*/ */
struct rb_subclass_entry *module_subclass_entry; struct rb_subclass_entry *module_subclass_entry;
#if SIZEOF_SERIAL_T != SIZEOF_VALUE /* otherwise class_serial is in struct RClass */ #if SIZEOF_SERIAL_T != SIZEOF_VALUE && !USE_RVARGC /* otherwise class_serial is in struct RClass */
rb_serial_t class_serial; rb_serial_t class_serial;
#endif #endif
const VALUE origin_; const VALUE origin_;
@ -76,6 +76,9 @@ struct RClass {
#else #else
/* Class serial does not fit into struct RClass. Place m_tbl instead. */ /* Class serial does not fit into struct RClass. Place m_tbl instead. */
struct rb_id_table *m_tbl; struct rb_id_table *m_tbl;
# if USE_RVARGC
rb_serial_t *class_serial_ptr;
# endif
#endif #endif
}; };
@ -103,7 +106,11 @@ typedef struct rb_classext_struct rb_classext_t;
#if SIZEOF_SERIAL_T == SIZEOF_VALUE #if SIZEOF_SERIAL_T == SIZEOF_VALUE
# define RCLASS_SERIAL(c) (RCLASS(c)->class_serial) # define RCLASS_SERIAL(c) (RCLASS(c)->class_serial)
#else #else
# define RCLASS_SERIAL(c) (RCLASS_EXT(c)->class_serial) # if USE_RVARGC
# define RCLASS_SERIAL(c) (*RCLASS(c)->class_serial_ptr)
# else
# define RCLASS_SERIAL(c) (RCLASS_EXT(c)->class_serial)
# endif
#endif #endif
#define RCLASS_INCLUDER(c) (RCLASS_EXT(c)->includer) #define RCLASS_INCLUDER(c) (RCLASS_EXT(c)->includer)
#define RCLASS_SUBCLASS_ENTRY(c) (RCLASS_EXT(c)->subclass_entry) #define RCLASS_SUBCLASS_ENTRY(c) (RCLASS_EXT(c)->subclass_entry)