Skip to content

Commit e61006a

Browse files
committed
Use shape bits to store capacity of object
This commit uses 7 shape bits to store the capacity of the object instead of the heap ID. This allows for slot sizes with up to capacity of 127. This removes the abstraction leak of slot sizes from the GC, which allows more flexibility in the GC. This implementation should currently make no difference for the default GC as it will end up creating the same root shapes. We can see that there is basically no change in benchmarks: -------------- ------------ ------------ ------------ ------------ -------------- ------------- ----------------- bench master (ms) RSS (MiB) branch (ms) RSS (MiB) branch 1st itr master/branch RSS master/branch activerecord 99.6 ± 3.9% 75.5 ± 0.3% 98.9 ± 2.4% 74.0 ± 1.3% 0.919 1.007 1.021 chunky-png 328.2 ± 0.6% 83.0 ± 3.9% 336.4 ± 0.7% 87.0 ± 2.2% 0.979 0.976 0.954 erubi-rails 440.4 ± 1.7% 138.1 ± 0.3% 431.0 ± 0.5% 135.2 ± 0.0% 0.992 1.022 1.022 hexapdf 855.6 ± 0.7% 577.0 ± 0.1% 856.7 ± 0.9% 649.0 ± 2.6% 0.993 0.999 0.889 liquid-c 21.6 ± 8.2% 69.6 ± 14.7% 23.2 ± 8.4% 64.6 ± 15.4% 0.993 0.930 1.077 liquid-compile 19.9 ± 7.9% 47.0 ± 5.7% 20.2 ± 8.7% 46.9 ± 5.1% 0.925 0.987 1.001 liquid-render 54.0 ± 2.7% 55.3 ± 8.6% 55.2 ± 2.7% 55.9 ± 9.0% 0.977 0.978 0.990 lobsters 351.6 ± 0.7% 336.8 ± 0.2% 357.0 ± 0.6% 335.4 ± 0.1% 0.997 0.985 1.004 mail 47.5 ± 3.1% 75.6 ± 2.7% 46.8 ± 1.3% 72.3 ± 0.5% 0.974 1.016 1.045 psych-load 829.1 ± 1.2% 55.0 ± 0.4% 832.9 ± 0.5% 55.3 ± 0.7% 1.006 0.995 0.995 railsbench 713.8 ± 0.4% 134.6 ± 1.1% 717.9 ± 1.0% 138.2 ± 1.2% 0.992 0.994 0.974 rubocop 73.1 ± 6.0% 106.7 ± 1.7% 73.2 ± 6.1% 106.4 ± 1.4% 0.997 0.998 1.003 ruby-lsp 69.0 ± 1.2% 78.3 ± 0.2% 67.8 ± 2.3% 74.2 ± 0.0% 1.043 1.017 1.055 sequel 21.7 ± 6.8% 56.1 ± 1.6% 21.0 ± 4.4% 55.9 ± 1.1% 0.873 1.032 1.003 shipit 608.9 ± 1.4% 160.2 ± 0.5% 619.2 ± 1.4% 157.3 ± 0.2% 1.012 0.983 1.018 -------------- ------------ ------------ ------------ ------------ -------------- ------------- -----------------
1 parent c048ba5 commit e61006a

13 files changed

Lines changed: 137 additions & 180 deletions

File tree

gc.c

Lines changed: 17 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -375,11 +375,11 @@ rb_gc_shutdown_call_finalizer_p(VALUE obj)
375375
}
376376

377377
void
378-
rb_gc_obj_changed_pool(VALUE obj, size_t heap_id)
378+
rb_gc_obj_changed_slot_size(VALUE obj, size_t slot_size)
379379
{
380380
RUBY_ASSERT(RB_TYPE_P(obj, T_OBJECT));
381381

382-
RBASIC_SET_SHAPE_ID(obj, rb_obj_shape_transition_heap(obj, heap_id));
382+
RBASIC_SET_SHAPE_ID_WITH_CAPACITY(obj, rb_obj_shape_transition_capacity(obj, rb_shape_capacity_for_slot_size(slot_size)));
383383
}
384384

385385
void rb_vm_update_references(void *ptr);
@@ -604,7 +604,6 @@ typedef struct gc_function_map {
604604
void *(*ractor_cache_alloc)(void *objspace_ptr, void *ractor);
605605
void (*set_params)(void *objspace_ptr);
606606
void (*init)(void);
607-
size_t *(*heap_sizes)(void *objspace_ptr);
608607
// Shutdown
609608
void (*shutdown_free_objects)(void *objspace_ptr);
610609
void (*objspace_free)(void *objspace_ptr);
@@ -622,9 +621,9 @@ typedef struct gc_function_map {
622621
VALUE (*stress_get)(void *objspace_ptr);
623622
struct rb_gc_vm_context *(*get_vm_context)(void *objspace_ptr);
624623
// Object allocation
625-
VALUE (*new_obj)(void *objspace_ptr, void *cache_ptr, VALUE klass, VALUE flags, bool wb_protected, size_t alloc_size);
624+
VALUE (*new_obj)(void *objspace_ptr, void *cache_ptr, VALUE klass, VALUE flags, bool wb_protected, size_t alloc_size, size_t *actual_alloc_size);
626625
size_t (*obj_slot_size)(VALUE obj);
627-
size_t (*heap_id_for_size)(void *objspace_ptr, size_t size);
626+
size_t (*size_slot_size)(void *objspace_ptr, size_t size);
628627
bool (*size_allocatable_p)(size_t size);
629628
// Malloc
630629
void *(*malloc)(void *objspace_ptr, size_t size, bool gc_allowed);
@@ -783,7 +782,6 @@ ruby_modular_gc_init(void)
783782
load_modular_gc_func(ractor_cache_alloc);
784783
load_modular_gc_func(set_params);
785784
load_modular_gc_func(init);
786-
load_modular_gc_func(heap_sizes);
787785
// Shutdown
788786
load_modular_gc_func(shutdown_free_objects);
789787
load_modular_gc_func(objspace_free);
@@ -803,7 +801,7 @@ ruby_modular_gc_init(void)
803801
// Object allocation
804802
load_modular_gc_func(new_obj);
805803
load_modular_gc_func(obj_slot_size);
806-
load_modular_gc_func(heap_id_for_size);
804+
load_modular_gc_func(size_slot_size);
807805
load_modular_gc_func(size_allocatable_p);
808806
// Malloc
809807
load_modular_gc_func(malloc);
@@ -871,7 +869,6 @@ ruby_modular_gc_init(void)
871869
# define rb_gc_impl_ractor_cache_alloc rb_gc_functions.ractor_cache_alloc
872870
# define rb_gc_impl_set_params rb_gc_functions.set_params
873871
# define rb_gc_impl_init rb_gc_functions.init
874-
# define rb_gc_impl_heap_sizes rb_gc_functions.heap_sizes
875872
// Shutdown
876873
# define rb_gc_impl_shutdown_free_objects rb_gc_functions.shutdown_free_objects
877874
# define rb_gc_impl_objspace_free rb_gc_functions.objspace_free
@@ -891,7 +888,7 @@ ruby_modular_gc_init(void)
891888
// Object allocation
892889
# define rb_gc_impl_new_obj rb_gc_functions.new_obj
893890
# define rb_gc_impl_obj_slot_size rb_gc_functions.obj_slot_size
894-
# define rb_gc_impl_heap_id_for_size rb_gc_functions.heap_id_for_size
891+
# define rb_gc_impl_size_slot_size rb_gc_functions.size_slot_size
895892
# define rb_gc_impl_size_allocatable_p rb_gc_functions.size_allocatable_p
896893
// Malloc
897894
# define rb_gc_impl_malloc rb_gc_functions.malloc
@@ -1033,7 +1030,11 @@ rb_newobj(rb_execution_context_t *ec, VALUE klass, VALUE flags, shape_id_t shape
10331030
{
10341031
GC_ASSERT((flags & FL_WB_PROTECTED) == 0);
10351032
rb_ractor_t *cr = rb_ec_ractor_ptr(ec);
1036-
VALUE obj = rb_gc_impl_new_obj(rb_gc_get_objspace(), cr->newobj_cache, klass, flags, wb_protected, size);
1033+
size_t actual_alloc_size;
1034+
VALUE obj = rb_gc_impl_new_obj(rb_gc_get_objspace(), cr->newobj_cache, klass, flags, wb_protected, size, &actual_alloc_size);
1035+
1036+
GC_ASSERT(actual_alloc_size >= size);
1037+
shape_id = (shape_id & ~SHAPE_ID_CAPACITY_MASK) | rb_shape_id_with_capacity(rb_shape_capacity_for_slot_size(actual_alloc_size));
10371038

10381039
#if RACTOR_CHECK_MODE
10391040
void rb_ractor_setup_belonging(VALUE obj);
@@ -1092,7 +1093,7 @@ rb_newobj_of(VALUE klass, VALUE flags, size_t size)
10921093
static
10931094
VALUE class_allocate_complex_instance(VALUE klass, uint32_t capacity)
10941095
{
1095-
shape_id_t initial_shape_id = rb_shape_id_with_robject_layout(rb_shape_root(rb_gc_heap_id_for_size(sizeof(struct RObject))));
1096+
shape_id_t initial_shape_id = rb_shape_id_with_robject_layout(0);
10961097
VALUE obj = rb_newobj_of_with_shape(klass, T_OBJECT, initial_shape_id, sizeof(struct RObject));
10971098
rb_obj_init_complex(obj, rb_st_init_numtable_with_size(capacity));
10981099
return obj;
@@ -1105,8 +1106,8 @@ rb_class_allocate_instance(VALUE klass)
11051106
VALUE obj;
11061107

11071108
// Directly start as COMPLEX if we know we're over the limit.
1108-
RUBY_ASSERT(rb_shape_tree.max_capacity > 0);
1109-
if (RB_UNLIKELY(index_tbl_num_entries > rb_shape_tree.max_capacity)) {
1109+
RUBY_ASSERT(SHAPE_MAX_CAPACITY > 0);
1110+
if (RB_UNLIKELY(index_tbl_num_entries > SHAPE_MAX_CAPACITY)) {
11101111
obj = class_allocate_complex_instance(klass, index_tbl_num_entries);
11111112
}
11121113
else {
@@ -1117,7 +1118,7 @@ rb_class_allocate_instance(VALUE klass)
11171118

11181119
// There might be a NEWOBJ tracepoint callback, and it may set fields.
11191120
// So the shape must be passed to `NEWOBJ_OF`.
1120-
obj = rb_newobj_of_with_shape(klass, T_OBJECT, rb_shape_id_with_robject_layout(rb_shape_root(rb_gc_heap_id_for_size(size))), size);
1121+
obj = rb_newobj_of_with_shape(klass, T_OBJECT, rb_shape_id_with_robject_layout(0), size);
11211122

11221123
#if RUBY_DEBUG
11231124
VALUE *ptr = ROBJECT_FIELDS(obj);
@@ -2187,7 +2188,6 @@ object_id0(VALUE obj)
21872188
id = generate_next_object_id();
21882189
rb_obj_field_set(obj, object_id_shape_id, 0, id);
21892190

2190-
RUBY_ASSERT(RBASIC_SHAPE_ID(obj) == object_id_shape_id);
21912191
RUBY_ASSERT(rb_obj_shape_has_id(obj));
21922192

21932193
if (RB_UNLIKELY(id2ref_tbl)) {
@@ -3989,9 +3989,9 @@ rb_gc_prepare_heap(void)
39893989
}
39903990

39913991
size_t
3992-
rb_gc_heap_id_for_size(size_t size)
3992+
rb_gc_size_slot_size(size_t size)
39933993
{
3994-
return rb_gc_impl_heap_id_for_size(rb_gc_get_objspace(), size);
3994+
return rb_gc_impl_size_slot_size(rb_gc_get_objspace(), size);
39953995
}
39963996

39973997
bool
@@ -4704,12 +4704,6 @@ rb_gc_initial_stress_set(VALUE flag)
47044704
initial_stress = flag;
47054705
}
47064706

4707-
size_t *
4708-
rb_gc_heap_sizes(void)
4709-
{
4710-
return rb_gc_impl_heap_sizes(rb_gc_get_objspace());
4711-
}
4712-
47134707
VALUE
47144708
rb_gc_enable(void)
47154709
{

gc/default/default.c

Lines changed: 5 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2606,24 +2606,9 @@ heap_idx_for_size(size_t size)
26062606
}
26072607

26082608
size_t
2609-
rb_gc_impl_heap_id_for_size(void *objspace_ptr, size_t size)
2609+
rb_gc_impl_size_slot_size(void *objspace_ptr, size_t size)
26102610
{
2611-
return heap_idx_for_size(size);
2612-
}
2613-
2614-
2615-
static size_t heap_sizes[HEAP_COUNT + 1] = { 0 };
2616-
2617-
size_t *
2618-
rb_gc_impl_heap_sizes(void *objspace_ptr)
2619-
{
2620-
if (heap_sizes[0] == 0) {
2621-
for (unsigned char i = 0; i < HEAP_COUNT; i++) {
2622-
heap_sizes[i] = heap_slot_size(i);
2623-
}
2624-
}
2625-
2626-
return heap_sizes;
2611+
return heap_slot_size((unsigned char)heap_idx_for_size(size));
26272612
}
26282613

26292614
NOINLINE(static VALUE newobj_cache_miss(rb_objspace_t *objspace, rb_ractor_newobj_cache_t *cache, size_t heap_idx, bool vm_locked));
@@ -2736,7 +2721,7 @@ newobj_slowpath_wb_unprotected(VALUE klass, VALUE flags, rb_objspace_t *objspace
27362721
}
27372722

27382723
VALUE
2739-
rb_gc_impl_new_obj(void *objspace_ptr, void *cache_ptr, VALUE klass, VALUE flags, bool wb_protected, size_t alloc_size)
2724+
rb_gc_impl_new_obj(void *objspace_ptr, void *cache_ptr, VALUE klass, VALUE flags, bool wb_protected, size_t alloc_size, size_t *actual_alloc_size)
27402725
{
27412726
VALUE obj;
27422727
rb_objspace_t *objspace = objspace_ptr;
@@ -2751,6 +2736,7 @@ rb_gc_impl_new_obj(void *objspace_ptr, void *cache_ptr, VALUE klass, VALUE flags
27512736
}
27522737

27532738
size_t heap_idx = heap_idx_for_size(alloc_size);
2739+
*actual_alloc_size = heap_slot_size((unsigned char)heap_idx);
27542740

27552741
rb_ractor_newobj_cache_t *cache = (rb_ractor_newobj_cache_t *)cache_ptr;
27562742

@@ -7479,7 +7465,7 @@ gc_move(rb_objspace_t *objspace, VALUE src, VALUE dest, struct heap_page *src_pa
74797465
memcpy((void *)dest, (void *)src, MIN(src_slot_size, slot_size));
74807466

74817467
if (src_slot_size != slot_size && RB_TYPE_P(src, T_OBJECT)) {
7482-
rb_gc_obj_changed_pool(dest, dest_page->heap - heaps);
7468+
rb_gc_obj_changed_slot_size(dest, slot_size - RVALUE_OVERHEAD);
74837469
}
74847470

74857471
if (RVALUE_OVERHEAD > 0) {

gc/gc.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ MODULAR_GC_FN void rb_gc_mark_roots(void *objspace, const char **categoryp);
110110
MODULAR_GC_FN void rb_gc_ractor_newobj_cache_foreach(void (*func)(void *cache, void *data), void *data);
111111
MODULAR_GC_FN bool rb_gc_multi_ractor_p(void);
112112
MODULAR_GC_FN bool rb_gc_shutdown_call_finalizer_p(VALUE obj);
113-
MODULAR_GC_FN void rb_gc_obj_changed_pool(VALUE obj, size_t heap_id);
113+
MODULAR_GC_FN void rb_gc_obj_changed_slot_size(VALUE obj, size_t slot_size);
114114
MODULAR_GC_FN void rb_gc_prepare_heap_process_object(VALUE obj);
115115
MODULAR_GC_FN bool rb_memerror_reentered(void);
116116
MODULAR_GC_FN bool rb_obj_id_p(VALUE);

gc/gc_impl.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@ GC_IMPL_FN void rb_gc_impl_objspace_init(void *objspace_ptr);
3838
GC_IMPL_FN void *rb_gc_impl_ractor_cache_alloc(void *objspace_ptr, void *ractor);
3939
GC_IMPL_FN void rb_gc_impl_set_params(void *objspace_ptr);
4040
GC_IMPL_FN void rb_gc_impl_init(void);
41-
GC_IMPL_FN size_t *rb_gc_impl_heap_sizes(void *objspace_ptr);
4241
// Shutdown
4342
GC_IMPL_FN void rb_gc_impl_shutdown_free_objects(void *objspace_ptr);
4443
GC_IMPL_FN void rb_gc_impl_objspace_free(void *objspace_ptr);
@@ -56,9 +55,9 @@ GC_IMPL_FN VALUE rb_gc_impl_config_get(void *objspace_ptr);
5655
GC_IMPL_FN void rb_gc_impl_config_set(void *objspace_ptr, VALUE hash);
5756
GC_IMPL_FN struct rb_gc_vm_context *rb_gc_impl_get_vm_context(void *objspace_ptr);
5857
// Object allocation
59-
GC_IMPL_FN VALUE rb_gc_impl_new_obj(void *objspace_ptr, void *cache_ptr, VALUE klass, VALUE flags, bool wb_protected, size_t alloc_size);
58+
GC_IMPL_FN VALUE rb_gc_impl_new_obj(void *objspace_ptr, void *cache_ptr, VALUE klass, VALUE flags, bool wb_protected, size_t alloc_size, size_t *actual_alloc_size);
6059
GC_IMPL_FN size_t rb_gc_impl_obj_slot_size(VALUE obj);
61-
GC_IMPL_FN size_t rb_gc_impl_heap_id_for_size(void *objspace_ptr, size_t size);
60+
GC_IMPL_FN size_t rb_gc_impl_size_slot_size(void *objspace_ptr, size_t size);
6261
GC_IMPL_FN bool rb_gc_impl_size_allocatable_p(size_t size);
6362
// Malloc
6463
/*

gc/mmtk/mmtk.c

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -687,12 +687,6 @@ rb_gc_impl_init(void)
687687
rb_define_singleton_method(rb_mGC, "verify_compaction_references", rb_f_notimplement, -1);
688688
}
689689

690-
size_t *
691-
rb_gc_impl_heap_sizes(void *objspace_ptr)
692-
{
693-
return heap_sizes;
694-
}
695-
696690
int
697691
rb_mmtk_obj_free_iter_wrapper(VALUE obj, void *data)
698692
{
@@ -902,7 +896,7 @@ mmtk_post_alloc_fast_immix(struct objspace *objspace, struct MMTk_ractor_cache *
902896
}
903897

904898
VALUE
905-
rb_gc_impl_new_obj(void *objspace_ptr, void *cache_ptr, VALUE klass, VALUE flags, bool wb_protected, size_t alloc_size)
899+
rb_gc_impl_new_obj(void *objspace_ptr, void *cache_ptr, VALUE klass, VALUE flags, bool wb_protected, size_t alloc_size, size_t *actual_alloc_size)
906900
{
907901
#define MMTK_ALLOCATION_SEMANTICS_DEFAULT 0
908902
struct objspace *objspace = objspace_ptr;
@@ -916,6 +910,7 @@ rb_gc_impl_new_obj(void *objspace_ptr, void *cache_ptr, VALUE klass, VALUE flags
916910
break;
917911
}
918912
}
913+
*actual_alloc_size = alloc_size;
919914

920915
if (objspace->gc_stress) {
921916
mmtk_handle_user_collection_request(ractor_cache, false, false);
@@ -962,10 +957,10 @@ rb_gc_impl_obj_slot_size(VALUE obj)
962957
}
963958

964959
size_t
965-
rb_gc_impl_heap_id_for_size(void *objspace_ptr, size_t size)
960+
rb_gc_impl_size_slot_size(void *objspace_ptr, size_t size)
966961
{
967962
for (int i = 0; i < MMTK_HEAP_COUNT; i++) {
968-
if (size <= heap_sizes[i]) return i;
963+
if (size <= heap_sizes[i]) return heap_sizes[i];
969964
}
970965

971966
rb_bug("size too big");

gc/wbcheck/wbcheck.c

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -536,12 +536,6 @@ rb_gc_impl_init(void)
536536
// Stub implementation
537537
}
538538

539-
size_t *
540-
rb_gc_impl_heap_sizes(void *objspace_ptr)
541-
{
542-
return heap_sizes;
543-
}
544-
545539
// Shutdown
546540
void
547541
rb_gc_impl_shutdown_free_objects(void *objspace_ptr)
@@ -1075,7 +1069,7 @@ lock_and_maybe_gc(void *objspace_ptr)
10751069
}
10761070

10771071
VALUE
1078-
rb_gc_impl_new_obj(void *objspace_ptr, void *cache_ptr, VALUE klass, VALUE flags, bool wb_protected, size_t alloc_size)
1072+
rb_gc_impl_new_obj(void *objspace_ptr, void *cache_ptr, VALUE klass, VALUE flags, bool wb_protected, size_t alloc_size, size_t *actual_alloc_size)
10791073
{
10801074
unsigned int lev = RB_GC_VM_LOCK();
10811075
rb_gc_vm_barrier();
@@ -1084,12 +1078,14 @@ rb_gc_impl_new_obj(void *objspace_ptr, void *cache_ptr, VALUE klass, VALUE flags
10841078
maybe_gc(objspace_ptr);
10851079

10861080
// Ensure minimum allocation size of BASE_SLOT_SIZE
1087-
alloc_size = heap_sizes[rb_gc_impl_heap_id_for_size(objspace_ptr, alloc_size)];
1081+
alloc_size = rb_gc_impl_size_slot_size(objspace_ptr, alloc_size);
10881082

10891083
// Allocate memory for the object
10901084
VALUE *mem = malloc(alloc_size);
10911085
if (!mem) rb_bug("FIXME: malloc failed");
10921086

1087+
*actual_alloc_size = alloc_size;
1088+
10931089
// Initialize the object
10941090
VALUE obj = (VALUE)mem;
10951091
RBASIC(obj)->flags = flags;
@@ -1119,10 +1115,10 @@ rb_gc_impl_obj_slot_size(VALUE obj)
11191115
}
11201116

11211117
size_t
1122-
rb_gc_impl_heap_id_for_size(void *objspace_ptr, size_t size)
1118+
rb_gc_impl_size_slot_size(void *objspace_ptr, size_t size)
11231119
{
11241120
for (int i = 0; i < HEAP_COUNT; i++) {
1125-
if (size <= heap_sizes[i]) return i;
1121+
if (size <= heap_sizes[i]) return heap_sizes[i];
11261122
}
11271123
rb_bug("size too big");
11281124
}
@@ -1952,4 +1948,3 @@ rb_gc_impl_copy_attributes(void *objspace_ptr, VALUE dest, VALUE obj)
19521948
}
19531949
rb_gc_impl_copy_finalizer(objspace_ptr, dest, obj);
19541950
}
1955-

imemo.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ rb_imemo_cdhash_new(size_t size, const struct st_hash_type *type)
133133
VALUE
134134
rb_imemo_fields_new(VALUE owner, shape_id_t shape_id, bool shareable)
135135
{
136-
size_t capa = RSHAPE_CAPACITY(shape_id);
136+
size_t capa = RSHAPE_CAPACITY(shape_id & ~SHAPE_ID_CAPACITY_MASK);
137137
size_t embedded_size = offsetof(struct rb_fields, as.embed) + capa * sizeof(VALUE);
138138
RUBY_ASSERT(rb_gc_size_allocatable_p(embedded_size));
139139
VALUE fields = rb_imemo_new(imemo_fields, owner, embedded_size, shareable);

internal/gc.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -205,8 +205,7 @@ void *rb_gc_ractor_cache_alloc(rb_ractor_t *ractor);
205205
void rb_gc_ractor_cache_free(void *cache);
206206

207207
bool rb_gc_size_allocatable_p(size_t size);
208-
size_t *rb_gc_heap_sizes(void);
209-
size_t rb_gc_heap_id_for_size(size_t size);
208+
size_t rb_gc_size_slot_size(size_t size);
210209

211210
void rb_gc_mark_and_move(VALUE *ptr);
212211

0 commit comments

Comments
 (0)