diff options
author | Matt Valentine-House <matt@eightbitraptor.com> | 2022-06-09 15:59:08 +0100 |
---|---|---|
committer | Peter Zhu <peter@peterzhu.ca> | 2022-07-12 08:50:33 -0400 |
commit | 214ed4cbc6f33675230602dd09268b436da96f7d (patch) | |
tree | 0c1cd73729447e53136643b7975b39385ee7a711 /gc.c | |
parent | 0f8a0c5f371b0886e8e31e35a9095bc9843de27c (diff) |
[Feature #18901] Support size pool movement for Arrays
This commit enables Arrays to move between size pools during compaction.
This can occur if the array is mutated such that it would fit in a
different size pool when embedded.
The move is carried out in two stages:
1. The RVALUE is moved to a destination heap during object movement
phase of compaction
2. The array data is re-embedded and the original buffer free'd if
required. This happens during the update references step
Notes
Notes:
Merged: https://github.com/ruby/ruby/pull/6099
Diffstat (limited to 'gc.c')
-rw-r--r-- | gc.c | 25 |
1 files changed, 18 insertions, 7 deletions
@@ -8324,16 +8324,20 @@ gc_compact_destination_pool(rb_objspace_t *objspace, rb_size_pool_t *src_pool, V switch (BUILTIN_TYPE(src)) { case T_STRING: obj_size = rb_str_size_as_embedded(src); - if (rb_gc_size_allocatable_p(obj_size)){ - return &size_pools[size_pool_idx_for_size(obj_size)]; - } - else { - GC_ASSERT(!STR_EMBED_P(src)); - return &size_pools[0]; - } + break; + case T_ARRAY: + obj_size = rb_ary_size_as_embedded(src); + break; default: return src_pool; } + + if (rb_gc_size_allocatable_p(obj_size)) { + return &size_pools[size_pool_idx_for_size(obj_size)]; + } + else { + return &size_pools[0]; + } } static bool @@ -10368,6 +10372,13 @@ gc_update_object_references(rb_objspace_t *objspace, VALUE obj) else { gc_ref_update_array(objspace, obj); } +#if USE_RVARGC + if ((size_t)GET_HEAP_PAGE(obj)->slot_size >= rb_ary_size_as_embedded(obj)) { + if (rb_ary_embeddable_p(obj)) { + rb_ary_make_embedded(obj); + } + } +#endif break; case T_HASH: |