summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Zhu <peter@peterzhu.ca>2022-01-14 13:59:38 -0500
committerPeter Zhu <peter@peterzhu.ca>2022-01-14 14:36:33 -0500
commit6b7eff90860d4fb4db01ec4d1f522afa6d809632 (patch)
treec545242eaf1dfeb27a1ec59d0cb181429584af88
parentca3d405242c722c8140944bda7278c2a9e5a7139 (diff)
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.
Notes
Notes: Merged: https://github.com/ruby/ruby/pull/5442
-rw-r--r--class.c3
-rw-r--r--gc.c4
-rw-r--r--internal/class.h11
3 files changed, 16 insertions, 2 deletions
diff --git a/class.c b/class.c
index 1281a243ab..9739aadc73 100644
--- a/class.c
+++ b/class.c
@@ -208,6 +208,9 @@ class_alloc(VALUE flags, VALUE klass)
#if USE_RVARGC
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
obj->ptr = ZALLOC(rb_classext_t);
#endif
diff --git a/gc.c b/gc.c
index 02f3e0bbb4..aca15ad426 100644
--- a/gc.c
+++ b/gc.c
@@ -3132,6 +3132,10 @@ 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);
+#if SIZEOF_SERIAL_T != SIZEOF_VALUE && USE_RVARGC
+ xfree(RCLASS(obj)->class_serial_ptr);
+#endif
+
#if !USE_RVARGC
if (RCLASS_EXT(obj))
xfree(RCLASS_EXT(obj));
diff --git a/internal/class.h b/internal/class.h
index 9edc821701..8942f80c9b 100644
--- a/internal/class.h
+++ b/internal/class.h
@@ -55,7 +55,7 @@ struct rb_classext_struct {
* included. Hopefully that makes sense.
*/
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;
#endif
const VALUE origin_;
@@ -76,6 +76,9 @@ struct RClass {
#else
/* Class serial does not fit into struct RClass. Place m_tbl instead. */
struct rb_id_table *m_tbl;
+# if USE_RVARGC
+ rb_serial_t *class_serial_ptr;
+# endif
#endif
};
@@ -103,7 +106,11 @@ typedef struct rb_classext_struct rb_classext_t;
#if SIZEOF_SERIAL_T == SIZEOF_VALUE
# define RCLASS_SERIAL(c) (RCLASS(c)->class_serial)
#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
#define RCLASS_INCLUDER(c) (RCLASS_EXT(c)->includer)
#define RCLASS_SUBCLASS_ENTRY(c) (RCLASS_EXT(c)->subclass_entry)