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

ruby-changes:45398

From: normal <ko1@a...>
Date: Tue, 31 Jan 2017 06:54:52 +0900 (JST)
Subject: [ruby-changes:45398] normal:r57471 (trunk): string.c (rb_str_tmp_frozen_release): release embedded strings

normal	2017-01-31 06:54:32 +0900 (Tue, 31 Jan 2017)

  New Revision: 57471

  https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=57471

  Log:
    string.c (rb_str_tmp_frozen_release): release embedded strings
    
    Handle the embedded case first, since we may have an embedded
    duplicate and non-embedded original string.
    
    * string.c (rb_str_tmp_frozen_release): handled embedded strings
    * test/ruby/test_io.rb (test_write_no_garbage): new test
      [ruby-core:78898] [Bug #13085]

  Modified files:
    trunk/string.c
    trunk/test/ruby/test_io.rb
Index: test/ruby/test_io.rb
===================================================================
--- test/ruby/test_io.rb	(revision 57470)
+++ test/ruby/test_io.rb	(revision 57471)
@@ -3504,5 +3504,21 @@ __END__ https://github.com/ruby/ruby/blob/trunk/test/ruby/test_io.rb#L3504
         end
       end
     end
+
+    def test_write_no_garbage
+      res = {}
+      ObjectSpace.count_objects(res) # creates strings on first call
+      [ 'foo'.b, '*' * 24 ].each do |buf|
+        with_pipe do |r, w|
+          before = ObjectSpace.count_objects(res)[:T_STRING]
+          n = w.write(buf)
+          after = ObjectSpace.count_objects(res)[:T_STRING]
+          assert_equal before, after,
+            'no strings left over after write [ruby-core:78898] [Bug #13085]'
+          assert_not_predicate buf, :frozen?, 'no inadvertant freeze'
+          assert_equal buf.bytesize, n, 'wrote expected size'
+        end
+      end
+    end
   end
 end
Index: string.c
===================================================================
--- string.c	(revision 57470)
+++ string.c	(revision 57471)
@@ -1150,7 +1150,11 @@ rb_str_tmp_frozen_release(VALUE orig, VA https://github.com/ruby/ruby/blob/trunk/string.c#L1150
     if (RBASIC_CLASS(tmp) != 0)
 	return;
 
-    if (FL_TEST_RAW(orig, STR_SHARED) &&
+    if (STR_EMBED_P(tmp)) {
+	assert(OBJ_FROZEN_RAW(tmp));
+	rb_gc_force_recycle(tmp);
+    }
+    else if (FL_TEST_RAW(orig, STR_SHARED) &&
 	    !FL_TEST_RAW(orig, STR_TMPLOCK|RUBY_FL_FREEZE)) {
 	VALUE shared = RSTRING(orig)->as.heap.aux.shared;
 
@@ -1164,10 +1168,6 @@ rb_str_tmp_frozen_release(VALUE orig, VA https://github.com/ruby/ruby/blob/trunk/string.c#L1168
 	    rb_gc_force_recycle(tmp);
 	}
     }
-    else if (STR_EMBED_P(tmp)) {
-	assert(OBJ_FROZEN_RAW(tmp));
-	rb_gc_force_recycle(tmp);
-    }
 }
 
 static VALUE

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

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