summaryrefslogtreecommitdiff
path: root/shape.h
diff options
context:
space:
mode:
authorJean Boussier <jean.boussier@gmail.com>2025-05-28 09:34:37 +0200
committerJean Boussier <jean.boussier@gmail.com>2025-06-04 07:59:20 +0200
commitbbd5a5a81d8bf3c7368d308c10f5752be25af6d1 (patch)
tree5e9ec252371ab832175c44af0f1ca419317137e2 /shape.h
parent625d6a9cbb0ed617b28115e4e3cb063e52481635 (diff)
vm_getivar: normalize shape_id to ignore frozen state
Freezing an object changes its `shape_id` This is necessary so that `setivar` routines can use the `shape_id` as a cache key and save on checking the frozen status every time. However for `getivar` routines, this causes needless cache misses. By clearing that bit we increase hit rate in codepaths that see both frozen and mutable objects.
Notes
Notes: Merged: https://github.com/ruby/ruby/pull/13289
Diffstat (limited to 'shape.h')
-rw-r--r--shape.h9
1 files changed, 9 insertions, 0 deletions
diff --git a/shape.h b/shape.h
index 4508646de2..ea736c385c 100644
--- a/shape.h
+++ b/shape.h
@@ -14,6 +14,7 @@ STATIC_ASSERT(shape_id_num_bits, SHAPE_ID_NUM_BITS == sizeof(shape_id_t) * CHAR_
#define SHAPE_ID_OFFSET_MASK (SHAPE_BUFFER_SIZE - 1)
#define SHAPE_ID_FLAGS_MASK (shape_id_t)(((1 << (SHAPE_ID_NUM_BITS - SHAPE_ID_OFFSET_NUM_BITS)) - 1) << SHAPE_ID_OFFSET_NUM_BITS)
#define SHAPE_ID_FL_FROZEN (SHAPE_FL_FROZEN << SHAPE_ID_OFFSET_NUM_BITS)
+#define SHAPE_ID_READ_ONLY_MASK (~SHAPE_ID_FL_FROZEN)
typedef uint32_t redblack_id_t;
@@ -110,6 +111,14 @@ RBASIC_SHAPE_ID(VALUE obj)
#endif
}
+// Same as RBASIC_SHAPE_ID but with flags that have no impact
+// on reads removed. e.g. Remove FL_FROZEN.
+static inline shape_id_t
+RBASIC_SHAPE_ID_FOR_READ(VALUE obj)
+{
+ return RBASIC_SHAPE_ID(obj) & SHAPE_ID_READ_ONLY_MASK;
+}
+
static inline void
RBASIC_SET_SHAPE_ID(VALUE obj, shape_id_t shape_id)
{