[pypy-commit] pypy gc-incminimark-pinning: (arigo, fijal) Cannot pin objects with finalizers or light finalizers

arigo noreply at buildbot.pypy.org
Wed Oct 22 11:24:10 CEST 2014


Author: Armin Rigo <arigo at tunes.org>
Branch: gc-incminimark-pinning
Changeset: r74066:db5a5627d048
Date: 2014-10-22 11:23 +0200
http://bitbucket.org/pypy/pypy/changeset/db5a5627d048/

Log:	(arigo, fijal) Cannot pin objects with finalizers or light
	finalizers

diff --git a/rpython/memory/gc/base.py b/rpython/memory/gc/base.py
--- a/rpython/memory/gc/base.py
+++ b/rpython/memory/gc/base.py
@@ -73,7 +73,8 @@
                             has_custom_trace,
                             get_custom_trace,
                             fast_path_tracing,
-                            has_gcptr):
+                            has_gcptr,
+                            cannot_pin):
         self.getfinalizer = getfinalizer
         self.getlightfinalizer = getlightfinalizer
         self.is_varsize = is_varsize
@@ -92,6 +93,7 @@
         self.get_custom_trace = get_custom_trace
         self.fast_path_tracing = fast_path_tracing
         self.has_gcptr = has_gcptr
+        self.cannot_pin = cannot_pin
 
     def get_member_index(self, type_id):
         return self.member_index(type_id)
diff --git a/rpython/memory/gc/incminimark.py b/rpython/memory/gc/incminimark.py
--- a/rpython/memory/gc/incminimark.py
+++ b/rpython/memory/gc/incminimark.py
@@ -915,14 +915,13 @@
             return False
         #
         obj_type_id = self.get_type_id(obj)
-        if self.has_gcptr(obj_type_id):
+        if self.cannot_pin(obj_type_id):
             # objects containing GC pointers can't be pinned. If we would add
             # it, we would have to track all pinned objects and trace them
             # every minor collection to make sure the referenced object are
             # kept alive. Right now this is not a use case that's needed.
-            return False
-        if self.weakpointer_offset(obj_type_id) >= 0:
-            # for now we don't support pinning objects with weak pointers.
+            # The check above also tests for being a less common kind of
+            # object: a weakref, or one with any kind of finalizer.
             return False
         #
         self.header(obj).tid |= GCFLAG_PINNED
diff --git a/rpython/memory/gctypelayout.py b/rpython/memory/gctypelayout.py
--- a/rpython/memory/gctypelayout.py
+++ b/rpython/memory/gctypelayout.py
@@ -83,6 +83,14 @@
         infobits = self.get(typeid).infobits
         return (infobits & T_IS_GCARRAY_OF_GCPTR) != 0
 
+    def q_cannot_pin(self, typeid):
+        infobits = self.get(typeid).infobits
+        ANY = (T_HAS_GCPTR |
+               T_IS_WEAKREF |
+               T_HAS_FINALIZER |
+               T_HAS_LIGHTWEIGHT_FINALIZER)
+        return (infobits & ANY) != 0
+
     def q_finalizer(self, typeid):
         typeinfo = self.get(typeid)
         if typeinfo.infobits & T_HAS_FINALIZER:
@@ -167,7 +175,8 @@
             self.q_has_custom_trace,
             self.q_get_custom_trace,
             self.q_fast_path_tracing,
-            self.q_has_gcptr)
+            self.q_has_gcptr,
+            self.q_cannot_pin)
 
 
 # the lowest 16bits are used to store group member index
diff --git a/rpython/memory/test/test_incminimark_gc.py b/rpython/memory/test/test_incminimark_gc.py
--- a/rpython/memory/test/test_incminimark_gc.py
+++ b/rpython/memory/test/test_incminimark_gc.py
@@ -48,6 +48,24 @@
             assert not rgc.pin(ref)
         self.interpret(f, [])
 
+    def test_pin_finalizer_not_implemented(self):
+        import weakref
+        class A:
+            def __del__(self):
+                pass
+        class B:
+            def __del__(self):
+                foo.bar += 1
+        class Foo:
+            bar = 0
+        foo = Foo()
+        def f():
+            a = A()
+            b = B()
+            assert not rgc.pin(a)
+            assert not rgc.pin(b)
+        self.interpret(f, [])
+
     def test_weakref_to_pinned(self):
         import weakref
         from rpython.rlib import rgc


More information about the pypy-commit mailing list