diff options
author | normal <normal@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2014-12-13 01:28:18 +0000 |
---|---|---|
committer | normal <normal@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2014-12-13 01:28:18 +0000 |
commit | 856903850bf86932f7994da799479eb9c1550041 (patch) | |
tree | fb5a01ba0580aadd2a4c2aee1ba0ba62059ef8e0 /gc.c | |
parent | 58d992ec44ea676e40b878fc663b543459243dcf (diff) | |
download | ruby-856903850bf86932f7994da799479eb9c1550041.tar.gz |
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
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@48820 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'gc.c')
-rw-r--r-- | gc.c | 14 |
1 files changed, 14 insertions, 0 deletions
@@ -2370,6 +2370,20 @@ define_final0(VALUE obj, VALUE block) 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 { |