diff options
author | Peter Zhu <peter@peterzhu.ca> | 2021-05-04 13:37:02 +0000 |
---|---|---|
committer | Peter Zhu <peter@peterzhu.ca> | 2021-05-04 11:46:23 -0400 |
commit | 3ca291c9ae1b6de09cce76e17aa3f08e92e1a2bf (patch) | |
tree | 7bb2c625a07cd9b87a04c52b174626b7fcc9de02 /array.c | |
parent | d09988502ed75cae65b787865465361b675cf1ee (diff) |
Correctly update array capacity after realloc
Reallocating to a smaller size in the transient heap may result in no
change in the actual capacity but the capacity of the array is still
updated to the smaller value.
This commit changes `ary_heap_realloc` to return the new capacity which
can be used by the caller to correctly update the capacity.
Notes
Notes:
Merged: https://github.com/ruby/ruby/pull/4448
Diffstat (limited to 'array.c')
-rw-r--r-- | array.c | 15 |
1 files changed, 10 insertions, 5 deletions
@@ -354,14 +354,16 @@ ary_heap_free(VALUE ary) } } -static void +static size_t ary_heap_realloc(VALUE ary, size_t new_capa) { + size_t alloc_capa = new_capa; size_t old_capa = ARY_HEAP_CAPA(ary); if (RARRAY_TRANSIENT_P(ary)) { if (new_capa <= old_capa) { /* do nothing */ + alloc_capa = old_capa; } else { VALUE *new_ptr = rb_transient_heap_alloc(ary, sizeof(VALUE) * new_capa); @@ -379,6 +381,8 @@ ary_heap_realloc(VALUE ary, size_t new_capa) SIZED_REALLOC_N(RARRAY(ary)->as.heap.ptr, VALUE, new_capa, old_capa); } ary_verify(ary); + + return alloc_capa; } #if USE_TRANSIENT_HEAP @@ -443,6 +447,7 @@ ary_resize_capa(VALUE ary, long capacity) assert(!ARY_SHARED_P(ary)); if (capacity > RARRAY_EMBED_LEN_MAX) { + size_t new_capa = capacity; if (ARY_EMBED_P(ary)) { long len = ARY_EMBED_LEN(ary); VALUE *ptr = ary_heap_alloc(ary, capacity); @@ -453,9 +458,9 @@ ary_resize_capa(VALUE ary, long capacity) ARY_SET_HEAP_LEN(ary, len); } else { - ary_heap_realloc(ary, capacity); + new_capa = ary_heap_realloc(ary, capacity); } - ARY_SET_CAPA(ary, capacity); + ARY_SET_CAPA(ary, new_capa); } else { if (!ARY_EMBED_P(ary)) { @@ -2267,8 +2272,8 @@ rb_ary_resize(VALUE ary, long len) } else { if (olen > len + ARY_DEFAULT_SIZE) { - ary_heap_realloc(ary, len); - ARY_SET_CAPA(ary, len); + size_t new_capa = ary_heap_realloc(ary, len); + ARY_SET_CAPA(ary, new_capa); } ARY_SET_HEAP_LEN(ary, len); } |