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

ruby-changes:51182

From: normal <ko1@a...>
Date: Thu, 10 May 2018 13:18:32 +0900 (JST)
Subject: [ruby-changes:51182] normal:r63389 (trunk): variable.c: fix autoload object lifetimes and leak

normal	2018-05-10 13:18:28 +0900 (Thu, 10 May 2018)

  New Revision: 63389

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

  Log:
    variable.c: fix autoload object lifetimes and leak
    
    We must not call normal Hash methods inside GC free callback,
    either, however identity hash may be used.
    
    [ruby-core:86935] [Bug #14742]

  Modified files:
    trunk/test/ruby/test_autoload.rb
    trunk/variable.c
Index: test/ruby/test_autoload.rb
===================================================================
--- test/ruby/test_autoload.rb	(revision 63388)
+++ test/ruby/test_autoload.rb	(revision 63389)
@@ -335,6 +335,18 @@ p Foo::Bar https://github.com/ruby/ruby/blob/trunk/test/ruby/test_autoload.rb#L335
     end
   end
 
+  def test_no_leak
+    assert_no_memory_leak([], '', <<~'end;', 'many autoloads', timeout: 30)
+      200000.times do |i|
+        m = Module.new
+        m.instance_eval do
+          autoload :Foo, 'x'
+          autoload :Bar, i.to_s
+        end
+      end
+    end;
+  end
+
   def add_autoload(path)
     (@autoload_paths ||= []) << path
     ::Object.class_eval {autoload(:AutoloadTest, path)}
Index: variable.c
===================================================================
--- variable.c	(revision 63388)
+++ variable.c	(revision 63389)
@@ -1908,6 +1908,7 @@ autoload_c_free(void *ptr) https://github.com/ruby/ruby/blob/trunk/variable.c#L1908
 {
     struct autoload_const *ac = ptr;
     list_del(&ac->cnode);
+    xfree(ac);
 }
 
 static size_t
@@ -1990,7 +1991,7 @@ rb_autoload_str(VALUE mod, ID id, VALUE https://github.com/ruby/ruby/blob/trunk/variable.c#L1991
     }
     file = rb_fstring(file);
     if (!autoload_featuremap) {
-        autoload_featuremap = rb_hash_new();
+        autoload_featuremap = rb_hash_new_compare_by_id();
         rb_obj_hide(autoload_featuremap);
         rb_gc_register_mark_object(autoload_featuremap);
     }
@@ -2036,13 +2037,13 @@ autoload_delete(VALUE mod, ID id) https://github.com/ruby/ruby/blob/trunk/variable.c#L2037
 	ele = get_autoload_data((VALUE)load, &ac);
 	VM_ASSERT(!list_empty(&ele->constants));
 
-	/* list_del_init to make list_del in autoload_c_free idempotent: */
+	/*
+	 * we must delete here to avoid "already initialized" warnings
+	 * with parallel autoload.  list_del_init makes list_del in
+	 * autoload_c_free idempotent
+	 */
 	list_del_init(&ac->cnode);
 
-	if (list_empty(&ele->constants)) {
-	    rb_hash_delete(autoload_featuremap, ele->feature);
-	}
-
 	if (tbl->num_entries == 0) {
 	    n = autoload;
 	    st_delete(RCLASS_IV_TBL(mod), &n, &val);

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

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