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

ruby-changes:36739

From: normal <ko1@a...>
Date: Sat, 13 Dec 2014 10:28:30 +0900 (JST)
Subject: [ruby-changes:36739] normal:r48820 (trunk): gc.c (define_final0): avoid duplicate blocks

normal	2014-12-13 10:28:18 +0900 (Sat, 13 Dec 2014)

  New Revision: 48820

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

  Log:
    gc.c (define_final0): avoid duplicate blocks
    
    This prevents excessive memory growth when a WeakRef
    is repeatedly created
    
    * gc.c (define_final0): avoid duplicate blocks
      [Bug #10537]
    * test/test_weakref.rb (test_repeated_object_leak): new test

  Modified files:
    trunk/ChangeLog
    trunk/gc.c
    trunk/test/test_weakref.rb
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 48819)
+++ ChangeLog	(revision 48820)
@@ -1,3 +1,9 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1
+Sat Dec 13 09:58:41 2014  Eric Wong  <e@8...>
+
+	* gc.c (define_final0): avoid duplicate blocks
+	  [Bug #10537]
+	* test/test_weakref.rb (test_repeated_object_leak): new test
+
 Sat Dec 13 04:59:20 2014  Nobuyoshi Nakada  <nobu@r...>
 
 	* bin/erb (ERB::Main#run): get rid of shadowing outer local
Index: gc.c
===================================================================
--- gc.c	(revision 48819)
+++ gc.c	(revision 48820)
@@ -2370,6 +2370,20 @@ define_final0(VALUE obj, VALUE block) https://github.com/ruby/ruby/blob/trunk/gc.c#L2370
 
     if (st_lookup(finalizer_table, obj, &data)) {
 	table = (VALUE)data;
+
+	/* avoid duplicate block, table is usually small */
+	{
+	    const VALUE *ptr = RARRAY_CONST_PTR(table);
+	    long len = RARRAY_LEN(table);
+	    long i;
+
+	    for (i = 0; i < len; i++, ptr++) {
+		if (rb_funcall(*ptr, idEq, 1, block)) {
+		    return *ptr;
+		}
+	    }
+	}
+
 	rb_ary_push(table, block);
     }
     else {
Index: test/test_weakref.rb
===================================================================
--- test/test_weakref.rb	(revision 48819)
+++ test/test_weakref.rb	(revision 48820)
@@ -60,4 +60,12 @@ class TestWeakRef < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/test_weakref.rb#L60
       end
     }, bug7304
   end
+
+  def test_repeated_object_leak
+    bug10537 = '[ruby-core:66428]'
+    assert_no_memory_leak(%w(-rweakref), '', <<-'end;', bug10537)
+      a = Object.new
+      150_000.times { WeakRef.new(a) }
+    end;
+  end
 end

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

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