Author: Armin Rigo <[email protected]>
Branch: gc-del-3
Changeset: r84175:270bb3186930
Date: 2016-05-03 21:18 +0200
http://bitbucket.org/pypy/pypy/changeset/270bb3186930/

Log:    Pass test_incminimark_gc -k test_finalizer

diff --git a/rpython/memory/test/gc_test_base.py 
b/rpython/memory/test/gc_test_base.py
--- a/rpython/memory/test/gc_test_base.py
+++ b/rpython/memory/test/gc_test_base.py
@@ -192,18 +192,27 @@
             def __init__(self):
                 self.id = b.nextid
                 b.nextid += 1
-            def __del__(self):
-                b.num_deleted += 1
-                C()
+                fq.register_finalizer(self)
         class C(A):
-            def __del__(self):
-                b.num_deleted += 1
+            pass
+        class FQ(rgc.FinalizerQueue):
+            Class = A
+            def finalizer_trigger(self):
+                while True:
+                    a = self.next_dead()
+                    if a is None:
+                        break
+                    b.num_deleted += 1
+                    if not isinstance(a, C):
+                        C()
+        fq = FQ()
         def f(x):
             a = A()
             i = 0
             while i < x:
                 i += 1
                 a = A()
+            a = None
             llop.gc__collect(lltype.Void)
             llop.gc__collect(lltype.Void)
             return b.num_deleted
@@ -220,15 +229,21 @@
             def __init__(self):
                 self.id = b.nextid
                 b.nextid += 1
-            def __del__(self):
-                b.num_deleted += 1
-                llop.gc__collect(lltype.Void)
+                fq.register_finalizer(self)
+        class FQ(rgc.FinalizerQueue):
+            Class = A
+            def finalizer_trigger(self):
+                while self.next_dead() is not None:
+                    b.num_deleted += 1
+                    llop.gc__collect(lltype.Void)
+        fq = FQ()
         def f(x):
             a = A()
             i = 0
             while i < x:
                 i += 1
                 a = A()
+            a = None
             llop.gc__collect(lltype.Void)
             llop.gc__collect(lltype.Void)
             return b.num_deleted
@@ -245,15 +260,24 @@
             def __init__(self):
                 self.id = b.nextid
                 b.nextid += 1
-            def __del__(self):
-                b.num_deleted += 1
-                b.a = self
+                fq.register_finalizer(self)
+        class FQ(rgc.FinalizerQueue):
+            Class = A
+            def finalizer_trigger(self):
+                while True:
+                    a = self.next_dead()
+                    if a is None:
+                        break
+                    b.num_deleted += 1
+                    b.a = a
+        fq = FQ()
         def f(x):
             a = A()
             i = 0
             while i < x:
                 i += 1
                 a = A()
+            a = None
             llop.gc__collect(lltype.Void)
             llop.gc__collect(lltype.Void)
             aid = b.a.id
@@ -320,7 +344,7 @@
         res = self.interpret(f, [])
         assert res
 
-    def test_weakref_to_object_with_finalizer(self):
+    def test_weakref_to_object_with_destructor(self):
         import weakref
         class A(object):
             count = 0
@@ -340,6 +364,32 @@
         res = self.interpret(f, [])
         assert res
 
+    def test_weakref_to_object_with_finalizer(self):
+        import weakref
+        class A(object):
+            count = 0
+        a = A()
+        class B(object):
+            pass
+        class FQ(rgc.FinalizerQueue):
+            Class = B
+            def finalizer_trigger(self):
+                while self.next_dead() is not None:
+                    a.count += 1
+        fq = FQ()
+        def g():
+            b = B()
+            fq.register_finalizer(b)
+            return weakref.ref(b)
+        def f():
+            ref = g()
+            llop.gc__collect(lltype.Void)
+            llop.gc__collect(lltype.Void)
+            result = a.count == 1 and (ref() is None)
+            return result
+        res = self.interpret(f, [])
+        assert res
+
     def test_bug_1(self):
         import weakref
         class B(object):
@@ -478,9 +528,14 @@
             def __init__(self):
                 self.id = b.nextid
                 b.nextid += 1
-            def __del__(self):
-                b.num_deleted += 1
-                b.all.append(D(b.num_deleted))
+                fq.register_finalizer(self)
+        class FQ(rgc.FinalizerQueue):
+            Class = A
+            def finalizer_trigger(self):
+                while self.next_dead() is not None:
+                    b.num_deleted += 1
+                    b.all.append(D(b.num_deleted))
+        fq = FQ()
         class D(object):
             # make a big object that does not use malloc_varsize
             def __init__(self, x):
@@ -491,6 +546,7 @@
             i = 0
             all = [None] * x
             a = A()
+            del a
             while i < x:
                 d = D(i)
                 all[i] = d
diff --git a/rpython/memory/test/snippet.py b/rpython/memory/test/snippet.py
--- a/rpython/memory/test/snippet.py
+++ b/rpython/memory/test/snippet.py
@@ -1,5 +1,6 @@
 import os, py
 from rpython.tool.udir import udir
+from rpython.rlib import rgc
 from rpython.rtyper.lltypesystem import lltype
 from rpython.rtyper.lltypesystem.lloperation import llop
 
@@ -61,12 +62,21 @@
             def __init__(self, key):
                 self.key = key
                 self.refs = []
-            def __del__(self):
+                fq.register_finalizer(self)
+
+        class FQ(rgc.FinalizerQueue):
+            Class = A
+            def finalizer_trigger(self):
                 from rpython.rlib.debug import debug_print
-                debug_print("DEL:", self.key)
-                assert age_of(self.key) == -1
-                set_age_of(self.key, state.time)
-                state.progress = True
+                while True:
+                    a = self.next_dead()
+                    if a is None:
+                        break
+                    debug_print("DEL:", a.key)
+                    assert age_of(a.key) == -1
+                    set_age_of(a.key, state.time)
+                    state.progress = True
+        fq = FQ()
 
         def build_example(input):
             state.time = 0
diff --git a/rpython/translator/backendopt/finalizer.py 
b/rpython/translator/backendopt/finalizer.py
--- a/rpython/translator/backendopt/finalizer.py
+++ b/rpython/translator/backendopt/finalizer.py
@@ -20,7 +20,8 @@
     """
     ok_operations = ['ptr_nonzero', 'ptr_eq', 'ptr_ne', 'free', 'same_as',
                      'direct_ptradd', 'force_cast', 'track_alloc_stop',
-                     'raw_free', 'adr_eq', 'adr_ne']
+                     'raw_free', 'adr_eq', 'adr_ne',
+                     'debug_print']
 
     def check_light_finalizer(self, graph):
         self._origin = graph
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to