From 6074e53703cf22b837c58f010c99651de7ad442f Mon Sep 17 00:00:00 2001 From: Jean Boussier Date: Tue, 5 May 2026 14:26:12 +0200 Subject: [PATCH] Reduce INVALID_SHAPE_ID to only its offset Given we only store the shape offset in ivar caches, and the offset is only 19bits, we should be able to store two shape offsets and an attribute index in a single uint64_t. Which is perfect for `setivar` caches. However when initializing caches we set them to `INVALID_SHAPE_ID` which is a full 32bits. By making `INVALID_SHAPE_ID` only as large as a shape offset we open the door to packing more information in ivar caches. --- shape.c | 2 +- shape.h | 7 ++++--- zjit/src/cruby_bindings.inc.rs | 2 +- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/shape.c b/shape.c index 5b5e2ce4ec5c77..ee1cb5b4cf7567 100644 --- a/shape.c +++ b/shape.c @@ -30,7 +30,7 @@ #define SINGLE_CHILD_P(x) ((uintptr_t)(x) & SINGLE_CHILD_TAG) #define SINGLE_CHILD(x) (rb_shape_t *)((uintptr_t)(x) & SINGLE_CHILD_MASK) #define ANCESTOR_CACHE_THRESHOLD 10 -#define MAX_SHAPE_ID (SHAPE_BUFFER_SIZE - 1) +#define MAX_SHAPE_ID (INVALID_SHAPE_ID - 1) #define ANCESTOR_SEARCH_MAX_DEPTH 2 static ID id_object_id; diff --git a/shape.h b/shape.h index c284cfb3a89945..b066bf3a15e05a 100644 --- a/shape.h +++ b/shape.h @@ -70,7 +70,7 @@ typedef uint32_t redblack_id_t; #define SHAPE_MAX_VARIATIONS 8 -#define INVALID_SHAPE_ID ((shape_id_t)-1) +#define INVALID_SHAPE_ID (SHAPE_BUFFER_SIZE - 1) #define ATTR_INDEX_NOT_SET ((attr_index_t)-1) #define ROOT_SHAPE_ID 0x0 @@ -187,8 +187,9 @@ RSHAPE_OFFSET(shape_id_t shape_id) static inline rb_shape_t * RSHAPE(shape_id_t shape_id) { - RUBY_ASSERT(shape_id != INVALID_SHAPE_ID); - return &rb_shape_tree.shape_list[RSHAPE_OFFSET(shape_id)]; + shape_id_t offset = RSHAPE_OFFSET(shape_id); + RUBY_ASSERT(offset != INVALID_SHAPE_ID); + return &rb_shape_tree.shape_list[offset]; } int32_t rb_shape_id_offset(void); diff --git a/zjit/src/cruby_bindings.inc.rs b/zjit/src/cruby_bindings.inc.rs index bd6a4afa25aa6f..1474551b5d2a41 100644 --- a/zjit/src/cruby_bindings.inc.rs +++ b/zjit/src/cruby_bindings.inc.rs @@ -1934,7 +1934,7 @@ pub const RUBY_OFFSET_EC_INTERRUPT_MASK: jit_bindgen_constants = 36; pub const RUBY_OFFSET_EC_THREAD_PTR: jit_bindgen_constants = 48; pub const RUBY_OFFSET_EC_RACTOR_ID: jit_bindgen_constants = 64; pub type jit_bindgen_constants = u32; -pub const rb_invalid_shape_id: shape_id_t = 4294967295; +pub const rb_invalid_shape_id: shape_id_t = 524287; pub type rb_iseq_param_keyword_struct = rb_iseq_constant_body_rb_iseq_parameters_rb_iseq_param_keyword; #[repr(C)]