summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorPeter Zhu <peter@peterzhu.ca>2022-07-11 10:09:39 -0400
committerPeter Zhu <peter@peterzhu.ca>2022-07-15 09:21:07 -0400
commit7424ea184f9d67c1c7f3ee97494ed3bd1aa60833 (patch)
tree822838e39d81cd2785c970cb45a86854823af6fe /include
parent7fda741f6e67b809b08423f0d4e903c078da2eed (diff)
Implement Objects on VWA
This commit implements Objects on Variable Width Allocation. This allows Objects with more ivars to be embedded (i.e. contents directly follow the object header) which improves performance through better cache locality.
Notes
Notes: Merged: https://github.com/ruby/ruby/pull/6117
Diffstat (limited to 'include')
-rw-r--r--include/ruby/internal/abi.h2
-rw-r--r--include/ruby/internal/core/robject.h45
2 files changed, 43 insertions, 4 deletions
diff --git a/include/ruby/internal/abi.h b/include/ruby/internal/abi.h
index ed779f3558..e42a1777ff 100644
--- a/include/ruby/internal/abi.h
+++ b/include/ruby/internal/abi.h
@@ -22,7 +22,7 @@
* In released versions of Ruby, this number should not be changed since teeny
* versions of Ruby should guarantee ABI compatibility.
*/
-#define RUBY_ABI_VERSION 1
+#define RUBY_ABI_VERSION 2
/* Windows does not support weak symbols so ruby_abi_version will not exist
* in the shared library. */
diff --git a/include/ruby/internal/core/robject.h b/include/ruby/internal/core/robject.h
index f2028063a6..7823061d8f 100644
--- a/include/ruby/internal/core/robject.h
+++ b/include/ruby/internal/core/robject.h
@@ -75,6 +75,7 @@ enum ruby_robject_flags {
ROBJECT_EMBED = RUBY_FL_USER1
};
+#if !USE_RVARGC
/**
* This is an enum because GDB wants it (rather than a macro). People need not
* bother.
@@ -83,6 +84,7 @@ enum ruby_robject_consts {
/** Max possible number of instance variables that can be embedded. */
ROBJECT_EMBED_LEN_MAX = RBIMPL_EMBED_LEN_MAX_OF(VALUE)
};
+#endif
struct st_table;
@@ -95,6 +97,14 @@ struct RObject {
/** Basic part, including flags and class. */
struct RBasic basic;
+#if USE_RVARGC
+ /**
+ * Number of instance variables. This is per object; objects might
+ * differ in this field even if they have the identical classes.
+ */
+ uint32_t numiv;
+#endif
+
/** Object's specific fields. */
union {
@@ -103,12 +113,13 @@ struct RObject {
* this pattern.
*/
struct {
-
+#if !USE_RVARGC
/**
* Number of instance variables. This is per object; objects might
* differ in this field even if they have the identical classes.
*/
uint32_t numiv;
+#endif
/** Pointer to a C array that holds instance variables. */
VALUE *ivptr;
@@ -124,14 +135,38 @@ struct RObject {
struct st_table *iv_index_tbl;
} heap;
- /**
- * Embedded instance variables. When an object is small enough, it
+#if USE_RVARGC
+ /* Embedded instance variables. When an object is small enough, it
* uses this area to store the instance variables.
+ *
+ * This is a length 1 array because:
+ * 1. GCC has a bug that does not optimize C flexible array members
+ * (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102452)
+ * 2. Zero length arrays are not supported by all compilers
*/
+ VALUE ary[1];
+#else
+ /**
+ * Embedded instance variables. When an object is small enough, it
+ * uses this area to store the instance variables.
+ */
VALUE ary[ROBJECT_EMBED_LEN_MAX];
+#endif
} as;
};
+/* Offsets for YJIT */
+#ifndef __cplusplus
+# if USE_RVARGC
+static const int32_t ROBJECT_OFFSET_NUMIV = offsetof(struct RObject, numiv);
+# else
+static const int32_t ROBJECT_OFFSET_NUMIV = offsetof(struct RObject, as.heap.numiv);
+# endif
+static const int32_t ROBJECT_OFFSET_AS_HEAP_IVPTR = offsetof(struct RObject, as.heap.ivptr);
+static const int32_t ROBJECT_OFFSET_AS_HEAP_IV_INDEX_TBL = offsetof(struct RObject, as.heap.iv_index_tbl);
+static const int32_t ROBJECT_OFFSET_AS_ARY = offsetof(struct RObject, as.ary);
+#endif
+
RBIMPL_ATTR_PURE_UNLESS_DEBUG()
RBIMPL_ATTR_ARTIFICIAL()
/**
@@ -146,12 +181,16 @@ ROBJECT_NUMIV(VALUE obj)
{
RBIMPL_ASSERT_TYPE(obj, RUBY_T_OBJECT);
+#if USE_RVARGC
+ return ROBJECT(obj)->numiv;
+#else
if (RB_FL_ANY_RAW(obj, ROBJECT_EMBED)) {
return ROBJECT_EMBED_LEN_MAX;
}
else {
return ROBJECT(obj)->as.heap.numiv;
}
+#endif
}
RBIMPL_ATTR_PURE_UNLESS_DEBUG()