[pypy-commit] pypy gc-minimark-pinning: Fix(?) the issue of objects that are not found any more in

arigo noreply at buildbot.pypy.org
Mon Apr 23 13:29:05 CEST 2012


Author: Armin Rigo <arigo at tunes.org>
Branch: gc-minimark-pinning
Changeset: r54674:27dcf8e6a03f
Date: 2012-04-23 13:28 +0200
http://bitbucket.org/pypy/pypy/changeset/27dcf8e6a03f/

Log:	Fix(?) the issue of objects that are not found any more in
	dictionaries when they are converted to ll2ctypes-style storage. The
	fix is to not use dictionaries any more.

diff --git a/pypy/rpython/lltypesystem/llarena.py b/pypy/rpython/lltypesystem/llarena.py
--- a/pypy/rpython/lltypesystem/llarena.py
+++ b/pypy/rpython/lltypesystem/llarena.py
@@ -1,4 +1,4 @@
-import array, weakref
+import array
 from pypy.rpython.lltypesystem import llmemory
 from pypy.rlib.rarithmetic import is_valid_int
 
@@ -16,8 +16,6 @@
     pass
 
 class Arena(object):
-    object_arena_location = {}     # {container: (arena, offset)}
-    old_object_arena_location = weakref.WeakKeyDictionary()
     _count_arenas = 0
 
     def __init__(self, nbytes, zero):
@@ -49,7 +47,7 @@
                 assert offset >= stop, "object overlaps cleared area"
             else:
                 obj = ptr._obj
-                _dictdel(Arena.object_arena_location, obj)
+                obj.__arena_location__[0] = False   # no longer valid
                 del self.objectptrs[offset]
                 del self.objectsizes[offset]
                 obj._free()
@@ -111,8 +109,7 @@
         self.objectptrs[offset] = objaddr.ptr
         self.objectsizes[offset] = bytes
         container = objaddr.ptr._obj
-        Arena.object_arena_location[container] = self, offset
-        Arena.old_object_arena_location[container] = self, offset
+        container.__arena_location__ = [True, self, offset]
 
     def shrink_obj(self, offset, newsize):
         oldbytes = self.objectsizes[offset]
@@ -203,12 +200,12 @@
             return None, None
         obj = other.ptr._obj
         innerobject = False
-        while obj not in Arena.object_arena_location:
+        while not getattr(obj, '__arena_location__', (False,))[0]:
             obj = obj._parentstructure()
             if obj is None:
                 return None, None     # not found in the arena
             innerobject = True
-        arena, offset = Arena.object_arena_location[obj]
+        _, arena, offset = obj.__arena_location__
         if innerobject:
             # 'obj' is really inside the object allocated from the arena,
             # so it's likely that its address "should be" a bit larger than
@@ -272,8 +269,8 @@
 def _oldobj_to_address(obj):
     obj = obj._normalizedcontainer(check=False)
     try:
-        arena, offset = Arena.old_object_arena_location[obj]
-    except KeyError:
+        _, arena, offset = obj.__arena_location__
+    except AttributeError:
         if obj._was_freed():
             msg = "taking address of %r, but it was freed"
         else:
@@ -281,16 +278,6 @@
         raise RuntimeError(msg % (obj,))
     return arena.getaddr(offset)
 
-def _dictdel(d, key):
-    # hack
-    try:
-        del d[key]
-    except KeyError:
-        items = d.items()
-        d.clear()
-        d.update(items)
-        del d[key]
-
 class RoundedUpForAllocation(llmemory.AddressOffset):
     """A size that is rounded up in order to preserve alignment of objects
     following it.  For arenas containing heterogenous objects.
diff --git a/pypy/rpython/lltypesystem/lltype.py b/pypy/rpython/lltypesystem/lltype.py
--- a/pypy/rpython/lltypesystem/lltype.py
+++ b/pypy/rpython/lltypesystem/lltype.py
@@ -1570,7 +1570,7 @@
         return cache[tag]
     except KeyError:
         class _struct1(_struct):
-            __slots__ = flds
+            __slots__ = tag + ('__arena_location__',)
         cache[tag] = _struct1
         return _struct1
  


More information about the pypy-commit mailing list