summaryrefslogtreecommitdiff
path: root/include/ruby/internal/core/robject.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/ruby/internal/core/robject.h')
-rw-r--r--include/ruby/internal/core/robject.h45
1 files changed, 42 insertions, 3 deletions
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()