variable.c: add object shapes for MRB_TT_OBJECT IV storage

Introduce "object shapes" (hidden classes) that share IV key
layouts across objects with the same instance variable assignment
order. This eliminates per-object key storage overhead.

Memory savings: ~22% heap reduction for object-heavy workloads
(e.g., 150k objects with 2-6 IVs). Per-object: 40->24 bytes
for 2 IVs. Objects exceeding 16 IVs or using
remove_instance_variable fall back to traditional iv_tbl.

Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
Yukihiro "Matz" Matsumoto
2026-02-27 08:29:46 +09:00
parent b4d2524fb4
commit 8d10056aff
6 changed files with 404 additions and 13 deletions
+4
View File
@@ -199,6 +199,10 @@ void mrb_gc_free_gv(mrb_state*);
size_t mrb_gc_mark_iv(mrb_state*, struct RObject*);
void mrb_gc_free_iv(mrb_state*, struct RObject*);
/* IV shape tree */
void mrb_init_shape(mrb_state*);
void mrb_free_shape(mrb_state*);
/* VM */
#define MRB_CI_VISIBILITY(ci) MRB_FLAGS_GET((ci)->vis, 0, 2)
#define MRB_CI_SET_VISIBILITY(ci, visi) MRB_FLAGS_SET((ci)->vis, 0, 2, visi)
+5
View File
@@ -24,6 +24,11 @@ struct RBasic {
#define MRB_OBJ_IS_FROZEN 1
#define mrb_frozen_p(o) ((o)->frozen)
/* Object shape flag -- when set, obj->iv is shaped, not iv_tbl* */
/* Bit 5: avoids conflict with MRB_INSTANCE_TT_MASK (bits 0-4) */
#define MRB_FL_OBJ_SHAPED (1 << 5)
#define MRB_OBJ_SHAPED_P(o) ((o)->flags & MRB_FL_OBJ_SHAPED)
struct RObject {
MRB_OBJECT_HEADER;
struct iv_tbl *iv;