dumping ground for random patches and texts
 help / color / mirror / Atom feed
* [PATCH] string.c (rb_str_tmp_frozen_release): release embedded strings
@ 2017-01-30 21:52 Eric Wong
  0 siblings, 0 replies; only message in thread
From: Eric Wong @ 2017-01-30 21:52 UTC (permalink / raw)
  To: spew

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]
---
 string.c             | 10 +++++-----
 test/ruby/test_io.rb | 16 ++++++++++++++++
 2 files changed, 21 insertions(+), 5 deletions(-)

diff --git a/string.c b/string.c
index a65a423b8f..3a7113dcc0 100644
--- a/string.c
+++ b/string.c
@@ -1150,7 +1150,11 @@ rb_str_tmp_frozen_release(VALUE orig, VALUE tmp)
     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, VALUE tmp)
 	    rb_gc_force_recycle(tmp);
 	}
     }
-    else if (STR_EMBED_P(tmp)) {
-	assert(OBJ_FROZEN_RAW(tmp));
-	rb_gc_force_recycle(tmp);
-    }
 }
 
 static VALUE
diff --git a/test/ruby/test_io.rb b/test/ruby/test_io.rb
index b146e8e321..c501edd0ab 100644
--- a/test/ruby/test_io.rb
+++ b/test/ruby/test_io.rb
@@ -3504,5 +3504,21 @@ def test_closed_stream_in_rescue
         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
-- 
EW


^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2017-01-30 21:53 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-01-30 21:52 [PATCH] string.c (rb_str_tmp_frozen_release): release embedded strings Eric Wong

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).