[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