ruby-changes:66046
From: Peter <ko1@a...>
Date: Wed, 5 May 2021 00:46:41 +0900 (JST)
Subject: [ruby-changes:66046] 3ca291c9ae (master): Correctly update array capacity after realloc
https://git.ruby-lang.org/ruby.git/commit/?id=3ca291c9ae From 3ca291c9ae1b6de09cce76e17aa3f08e92e1a2bf Mon Sep 17 00:00:00 2001 From: Peter Zhu <peter@p...> Date: Tue, 4 May 2021 13:37:02 +0000 Subject: 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. --- array.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/array.c b/array.c index 76f1158..50e2418 100644 --- a/array.c +++ b/array.c @@ -354,14 +354,16 @@ ary_heap_free(VALUE ary) https://github.com/ruby/ruby/blob/trunk/array.c#L354 } } -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) https://github.com/ruby/ruby/blob/trunk/array.c#L381 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) https://github.com/ruby/ruby/blob/trunk/array.c#L447 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) https://github.com/ruby/ruby/blob/trunk/array.c#L458 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) https://github.com/ruby/ruby/blob/trunk/array.c#L2272 } 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); } -- cgit v1.1 -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/