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/