[前][次][番号順一覧][スレッド一覧]

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/

[前][次][番号順一覧][スレッド一覧]