[pypy-commit] pypy lightweight-finalizers: make test_translated_gc happy

fijal noreply at buildbot.pypy.org
Fri Sep 30 23:50:11 CEST 2011


Author: Maciej Fijalkowski <fijall at gmail.com>
Branch: lightweight-finalizers
Changeset: r47734:e1db6077ba7e
Date: 2011-09-30 18:49 -0300
http://bitbucket.org/pypy/pypy/changeset/e1db6077ba7e/

Log:	make test_translated_gc happy

diff --git a/pypy/annotation/builtin.py b/pypy/annotation/builtin.py
--- a/pypy/annotation/builtin.py
+++ b/pypy/annotation/builtin.py
@@ -691,7 +691,7 @@
     assert isinstance(s_size, SomeInteger) #XXX add noneg...?
     return SomeInteger(nonneg=True)
 
-def raw_free(s_addr):
+def raw_free(s_addr, s_track_free=None):
     assert isinstance(s_addr, SomeAddress)
 
 def raw_memclear(s_addr, s_int):
diff --git a/pypy/rpython/lltypesystem/llmemory.py b/pypy/rpython/lltypesystem/llmemory.py
--- a/pypy/rpython/lltypesystem/llmemory.py
+++ b/pypy/rpython/lltypesystem/llmemory.py
@@ -8,6 +8,7 @@
 from pypy.rlib.objectmodel import Symbolic
 from pypy.rpython.lltypesystem import lltype
 from pypy.tool.uid import uid
+from pypy.tool import leakfinder
 
 class AddressOffset(Symbolic):
 
@@ -780,7 +781,7 @@
         raise NotImplementedError(size)
     return size._raw_malloc([], zero=False)
 
-def raw_free(adr):
+def raw_free(adr, track_free=False):
     # try to free the whole object if 'adr' is the address of the header
     from pypy.rpython.memory.gcheader import GCHeaderBuilder
     try:
@@ -790,6 +791,8 @@
     else:
         raw_free(cast_ptr_to_adr(objectptr))
     assert isinstance(adr.ref()._obj, lltype._parentable)
+    if track_free:
+        leakfinder.remember_free(adr.ptr._as_obj())
     adr.ptr._as_obj()._free()
 
 def raw_malloc_usage(size):
diff --git a/pypy/rpython/memory/gc/base.py b/pypy/rpython/memory/gc/base.py
--- a/pypy/rpython/memory/gc/base.py
+++ b/pypy/rpython/memory/gc/base.py
@@ -1,4 +1,4 @@
-from pypy.rpython.lltypesystem import lltype, llmemory, llarena
+from pypy.rpython.lltypesystem import lltype, llmemory, llarena, rffi
 from pypy.rlib.debug import ll_assert
 from pypy.rpython.memory.gcheader import GCHeaderBuilder
 from pypy.rpython.memory.support import DEFAULT_CHUNK_SIZE
@@ -355,9 +355,9 @@
 
     def _free_raw_mem_from(self, addr):
         typeid = self.get_type_id(addr)
-        p = (addr + self.ofs_to_raw_mem_ptr(typeid)).ptr[0]
-        if p:
-            lltype.free(p, flavor='raw')
+        raw_adr = (addr + self.ofs_to_raw_mem_ptr(typeid)).address[0]
+        if raw_adr:
+            llmemory.raw_free(raw_adr, track_free=True)
 
 
 class MovingGCBase(GCBase):
diff --git a/pypy/rpython/memory/gctypelayout.py b/pypy/rpython/memory/gctypelayout.py
--- a/pypy/rpython/memory/gctypelayout.py
+++ b/pypy/rpython/memory/gctypelayout.py
@@ -247,8 +247,8 @@
         infobits |= T_IS_WEAKREF
     if is_subclass_of_object(TYPE):
         infobits |= T_IS_RPYTHON_INSTANCE
-    if getattr(TYPE._runtime_type_info, 'raw_mem_attr_name', None):
-        name = TYPE._runtime_type_info.raw_mem_attr_name
+    if builder.get_raw_mem_attr_name(TYPE):
+        name = builder.get_raw_mem_attr_name(TYPE)
         infobits |= T_HAS_RAW_MEM_PTR
         info.ofstorawptr = llmemory.offsetof(TYPE, 'inst_' + name)
     info.infobits = infobits | T_KEY_VALUE
@@ -348,6 +348,13 @@
     def is_weakref_type(self, TYPE):
         return TYPE == WEAKREF
 
+    def get_raw_mem_attr_name(self, TYPE):
+        from pypy.rpython.memory.gctransform.support import get_rtti
+        
+        rtti = get_rtti(TYPE)
+        return rtti is not None and getattr(rtti._obj, 'raw_mem_attr_name',
+                                            None)
+
     def encode_type_shapes_now(self):
         if not self.can_encode_type_shape:
             self.can_encode_type_shape = True
diff --git a/pypy/rpython/memory/test/test_transformed_gc.py b/pypy/rpython/memory/test/test_transformed_gc.py
--- a/pypy/rpython/memory/test/test_transformed_gc.py
+++ b/pypy/rpython/memory/test/test_transformed_gc.py
@@ -339,6 +339,36 @@
         res = run([5, 42]) #XXX pure lazyness here too
         assert res == 6
 
+    def define_lightweight_finalizer(cls):
+        T = lltype.Struct('T', ('x', lltype.Signed))
+        
+        @rgc.owns_raw_memory('p')
+        class AClass(object):
+            p = lltype.nullptr(T)
+
+            def __init__(self, arg):
+                if arg:
+                    self.p = lltype.malloc(T, flavor='raw')
+
+        def f():
+            a = AClass(0)
+            for i in range(30):
+                a = AClass(3)
+                AClass(0)
+            llop.gc__collect(lltype.Void)
+            assert a.p
+            del a
+            llop.gc__collect(lltype.Void)
+            # assert did not crash with malloc mismatch, ie those things
+            # has been freed
+            return 3
+
+        return f
+
+    def test_lightweight_finalizer(self):
+        run = self.runner("lightweight_finalizer")
+        run([])
+
     def define_finalizer_calls_malloc(cls):
         class B(object):
             pass
diff --git a/pypy/rpython/rbuiltin.py b/pypy/rpython/rbuiltin.py
--- a/pypy/rpython/rbuiltin.py
+++ b/pypy/rpython/rbuiltin.py
@@ -565,11 +565,11 @@
     hop.exception_cannot_occur()
     return hop.genop('raw_malloc_usage', [v_size], resulttype=lltype.Signed)
 
-def rtype_raw_free(hop):
+def rtype_raw_free(hop, i_track_free=None):
     s_addr = hop.args_s[0]
     if s_addr.is_null_address():
         raise TyperError("raw_free(x) where x is the constant NULL")
-    v_addr, = hop.inputargs(llmemory.Address)
+    v_addr = hop.inputarg(llmemory.Address, 0)
     hop.exception_cannot_occur()
     return hop.genop('raw_free', [v_addr])
 


More information about the pypy-commit mailing list