mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
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.
This commit is contained in:
parent
d09988502e
commit
3ca291c9ae
Notes:
git
2021-05-05 00:46:51 +09:00
1 changed files with 10 additions and 5 deletions
15
array.c
15
array.c
|
@ -354,14 +354,16 @@ ary_heap_free(VALUE ary)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static size_t
|
||||||
ary_heap_realloc(VALUE ary, size_t new_capa)
|
ary_heap_realloc(VALUE ary, size_t new_capa)
|
||||||
{
|
{
|
||||||
|
size_t alloc_capa = new_capa;
|
||||||
size_t old_capa = ARY_HEAP_CAPA(ary);
|
size_t old_capa = ARY_HEAP_CAPA(ary);
|
||||||
|
|
||||||
if (RARRAY_TRANSIENT_P(ary)) {
|
if (RARRAY_TRANSIENT_P(ary)) {
|
||||||
if (new_capa <= old_capa) {
|
if (new_capa <= old_capa) {
|
||||||
/* do nothing */
|
/* do nothing */
|
||||||
|
alloc_capa = old_capa;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
VALUE *new_ptr = rb_transient_heap_alloc(ary, sizeof(VALUE) * new_capa);
|
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);
|
SIZED_REALLOC_N(RARRAY(ary)->as.heap.ptr, VALUE, new_capa, old_capa);
|
||||||
}
|
}
|
||||||
ary_verify(ary);
|
ary_verify(ary);
|
||||||
|
|
||||||
|
return alloc_capa;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if USE_TRANSIENT_HEAP
|
#if USE_TRANSIENT_HEAP
|
||||||
|
@ -443,6 +447,7 @@ ary_resize_capa(VALUE ary, long capacity)
|
||||||
assert(!ARY_SHARED_P(ary));
|
assert(!ARY_SHARED_P(ary));
|
||||||
|
|
||||||
if (capacity > RARRAY_EMBED_LEN_MAX) {
|
if (capacity > RARRAY_EMBED_LEN_MAX) {
|
||||||
|
size_t new_capa = capacity;
|
||||||
if (ARY_EMBED_P(ary)) {
|
if (ARY_EMBED_P(ary)) {
|
||||||
long len = ARY_EMBED_LEN(ary);
|
long len = ARY_EMBED_LEN(ary);
|
||||||
VALUE *ptr = ary_heap_alloc(ary, capacity);
|
VALUE *ptr = ary_heap_alloc(ary, capacity);
|
||||||
|
@ -453,9 +458,9 @@ ary_resize_capa(VALUE ary, long capacity)
|
||||||
ARY_SET_HEAP_LEN(ary, len);
|
ARY_SET_HEAP_LEN(ary, len);
|
||||||
}
|
}
|
||||||
else {
|
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 {
|
else {
|
||||||
if (!ARY_EMBED_P(ary)) {
|
if (!ARY_EMBED_P(ary)) {
|
||||||
|
@ -2267,8 +2272,8 @@ rb_ary_resize(VALUE ary, long len)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (olen > len + ARY_DEFAULT_SIZE) {
|
if (olen > len + ARY_DEFAULT_SIZE) {
|
||||||
ary_heap_realloc(ary, len);
|
size_t new_capa = ary_heap_realloc(ary, len);
|
||||||
ARY_SET_CAPA(ary, len);
|
ARY_SET_CAPA(ary, new_capa);
|
||||||
}
|
}
|
||||||
ARY_SET_HEAP_LEN(ary, len);
|
ARY_SET_HEAP_LEN(ary, len);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue