aboutsummaryrefslogtreecommitdiffstats
path: root/gc.c
diff options
context:
space:
mode:
authornormal <normal@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2014-12-13 01:28:18 +0000
committernormal <normal@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2014-12-13 01:28:18 +0000
commit856903850bf86932f7994da799479eb9c1550041 (patch)
treefb5a01ba0580aadd2a4c2aee1ba0ba62059ef8e0 /gc.c
parent58d992ec44ea676e40b878fc663b543459243dcf (diff)
downloadruby-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.c14
1 files changed, 14 insertions, 0 deletions
diff --git a/gc.c b/gc.c
index feb9c08059..1caa790202 100644
--- a/gc.c
+++ b/gc.c
@@ -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 {