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

ruby-changes:56139

From: Nobuyoshi <ko1@a...>
Date: Wed, 19 Jun 2019 14:39:49 +0900 (JST)
Subject: [ruby-changes:56139] Nobuyoshi Nakada: 8797f48373 (trunk): New buffer for shared string

https://git.ruby-lang.org/ruby.git/commit/?id=8797f48373

From 8797f48373dcfa3ff8e748667732dea8aea4347e Mon Sep 17 00:00:00 2001
From: Nobuyoshi Nakada <nobu@r...>
Date: Wed, 19 Jun 2019 14:03:02 +0900
Subject: New buffer for shared string

* string.c (rb_str_init): allocate new buffer if the string is
  shared.  [Bug #15937]

diff --git a/string.c b/string.c
index e402a5a..3feeb8c 100644
--- a/string.c
+++ b/string.c
@@ -1615,6 +1615,15 @@ rb_str_init(int argc, VALUE *argv, VALUE str) https://github.com/ruby/ruby/blob/trunk/string.c#L1615
                 char *new_ptr = ALLOC_N(char, (size_t)capa + termlen);
                 memcpy(new_ptr, RSTRING(str)->as.ary, RSTRING_EMBED_LEN_MAX + 1);
                 RSTRING(str)->as.heap.ptr = new_ptr;
+            }
+            else if (FL_TEST(str, STR_SHARED|STR_NOFREE)) {
+                const size_t size = (size_t)capa + termlen;
+                const char *const old_ptr = RSTRING_PTR(str);
+                const size_t osize = RSTRING(str)->as.heap.len + TERM_LEN(str);
+                char *new_ptr = ALLOC_N(char, (size_t)capa + termlen);
+                memcpy(new_ptr, old_ptr, osize < size ? osize : size);
+                FL_UNSET_RAW(str, STR_SHARED);
+                RSTRING(str)->as.heap.ptr = new_ptr;
 	    }
 	    else if (STR_HEAP_SIZE(str) != (size_t)capa + termlen) {
 		SIZED_REALLOC_N(RSTRING(str)->as.heap.ptr, char,
diff --git a/test/ruby/test_string.rb b/test/ruby/test_string.rb
index 1d81d24..afa3803 100644
--- a/test/ruby/test_string.rb
+++ b/test/ruby/test_string.rb
@@ -79,6 +79,11 @@ class TestString < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_string.rb#L79
     assert_equal("mystring", str.__send__(:initialize, str, capacity: 1000))
   end
 
+  def test_initialize_shared
+    String.new(str = "mystring" * 10).__send__(:initialize, capacity: str.bytesize)
+    assert_equal("mystring", str[0, 8])
+  end
+
   def test_initialize_nonstring
     assert_raise(TypeError) {
       S(1)
-- 
cgit v0.10.2


--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

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