From 7424ea184f9d67c1c7f3ee97494ed3bd1aa60833 Mon Sep 17 00:00:00 2001 From: Peter Zhu Date: Mon, 11 Jul 2022 10:09:39 -0400 Subject: 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. --- include/ruby/internal/core/robject.h | 45 +++++++++++++++++++++++++++++++++--- 1 file changed, 42 insertions(+), 3 deletions(-) (limited to 'include/ruby/internal/core/robject.h') 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() -- cgit v1.2.3