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] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@63389 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
23c74845ed
commit
6726038d76
@ -335,6 +335,18 @@ p Foo::Bar
|
||||
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)}
|
||||
|
13
variable.c
13
variable.c
@ -1908,6 +1908,7 @@ autoload_c_free(void *ptr)
|
||||
{
|
||||
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 file)
|
||||
}
|
||||
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)
|
||||
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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user