Commits

Maciej Fijalkowski committed b8be75d

change approach - remove the owns_raw_memory_decorator, we'll try to detect
automatically and act accordingly

  • Participants
  • Parent commits d8f5b33
  • Branches lightweight-finalizers

Comments (0)

Files changed (8)

File pypy/jit/metainterp/test/test_ajit.py

         assert res == main(1, 10)
         self.check_loops(call=0)
 
-    def test_virtual_lightweight_finalizer(self):
-        py.test.skip("raw mallocs unsupported, otherwise this would be a problem")
-        from pypy.rlib import rgc
-        import gc
-
-        S = lltype.Struct('S', ('x', lltype.Signed))
-        
-        @rgc.owns_raw_memory('p')
-        class A(object):
-            def __init__(self):
-                self.p = lltype.malloc(S, flavor='raw')
-
-        driver = JitDriver(greens = [], reds = ['i', 'a'])
-
-        def f(i):
-            a = None
-            while i > 0:
-                driver.jit_merge_point(i=i, a=a)
-                a = A()
-                i -= 1
-            gc.collect()
-
-        self.meta_interp(f, [10])
-
 
 class TestLLtype(BaseLLtypeTests, LLJitMixin):
     pass

File pypy/rlib/rgc.py

     def specialize_call(self, hop):
         hop.exception_is_here()
         return hop.genop('gc_typeids_z', [], resulttype = hop.r_result)
-
-# ----------------------------------------------------------------------
-
-def owns_raw_memory(name):
-    """ Declare class as owning raw memory under the attribute name. When
-    object is freed, it'll automatically free the raw memory residing
-    under this attribute
-    """
-    def wrapper(cls):
-        def remove_raw_mem_attr(self):
-            if getattr(self, name):
-                lltype.free(getattr(self, name), flavor='raw')
-            if orig_del is not None:
-                orig_del(self)
-
-        orig_del = getattr(cls, '__del__', None)
-        cls._raw_mem_ptr_name = name
-        cls.__del__ = remove_raw_mem_attr
-        return cls
-    return wrapper

File pypy/rlib/rsocket.py

 # app-level code for PyPy.
 
 from pypy.rlib.objectmodel import instantiate, keepalive_until_here
-from pypy.rlib.rgc import owns_raw_memory
 from pypy.rlib import _rsocket_rffi as _c
 from pypy.rlib.rarithmetic import intmask
 from pypy.rpython.lltypesystem import lltype, rffi
 
 _FAMILIES = {}
 
-@owns_raw_memory('addr_p')
 class Address(object):
     """The base class for RPython-level objects representing addresses.
     Fields:  addr    - a _c.sockaddr_ptr (memory owned by the Address instance)
         self.addr_p = addr
         self.addrlen = addrlen
 
+    def __del__(self):
+        if self.addr_p:
+            lltype.free(self.addr_p, flavor='raw')
+
     def setdata(self, addr, addrlen):
         # initialize self.addr and self.addrlen.  'addr' can be a different
         # pointer type than exactly sockaddr_ptr, and we cast it for you.

File pypy/rlib/test/test_rgc.py

     x1 = X()
     n = rgc.get_rpy_memory_usage(rgc.cast_instance_to_gcref(x1))
     assert n >= 8 and n <= 64
-
-def test_raw_memory_owner():
-    T = lltype.Struct('X', ('x', lltype.Signed))
-
-    @rgc.owns_raw_memory('p')
-    class X(object):
-        p = lltype.nullptr(T)
-        
-        def __init__(self, arg):
-            if arg:
-                self.p = lltype.malloc(T, flavor='raw')
-    
-    a = X(3)
-    b = X(0)
-    ptr2 = b.p
-    ptr = a.p
-    del a, b
-    gc.collect()
-    assert ptr._was_freed()
-    assert not ptr2
-
-def test_raw_memory_owner_with_del():
-    T = lltype.Struct('X', ('x', lltype.Signed))
-    collected = []
-
-    @rgc.owns_raw_memory('p')
-    class X(object):
-        p = lltype.nullptr(T)
-        
-        def __init__(self, arg):
-            if arg:
-                self.p = lltype.malloc(T, flavor='raw')
-
-        def __del__(self):
-            collected.append(None)
-    
-    a = X(3)
-    ptr = a.p
-    del a
-    gc.collect()
-    assert ptr._was_freed()
-    assert collected

File pypy/rpython/lltypesystem/rclass.py

     def _setup_repr_final(self):
         AbstractInstanceRepr._setup_repr_final(self)
         if self.gcflavor == 'gc':
-            destrptr = None
-            raw_mem_attr_name = None
-            if self.classdef is not None:
-                classdesc = self.classdef.classdesc
-                if classdesc.lookup('__del__') is not None:
-                    s_func = classdesc.s_read_attribute('__del__')
-                    if classdesc.lookup('_raw_mem_ptr_name'):
-                        # this object has a __del__, but it actually does not
-                        # do much
-                        assert s_func.const.func_name == 'remove_raw_mem_attr',(
-                            "You overloaded __del__ on an object that owns"
-                            " a reference to a low level pointer")
-                        raw_mem_attr_name = classdesc.s_read_attribute(
-                            '_raw_mem_ptr_name').const
-                    else:
-                        source_desc = classdesc.lookup('__del__')
-                        source_classdef = source_desc.getclassdef(None)
-                        source_repr = getinstancerepr(self.rtyper,
-                                                      source_classdef)
-                        assert len(s_func.descriptions) == 1
-                        funcdesc, = s_func.descriptions
-                        graph = funcdesc.getuniquegraph()
-                        self.check_graph_of_del_does_not_call_too_much(graph)
-                        FUNCTYPE = FuncType([Ptr(source_repr.object_type)],
-                                            Void)
-                        destrptr = functionptr(FUNCTYPE, graph.name,
-                                               graph=graph,
-                                               _callable=graph.func)
+            if (self.classdef is not None and
+                self.classdef.classdesc.lookup('__del__') is not None):
+                s_func = self.classdef.classdesc.s_read_attribute('__del__')
+                source_desc = self.classdef.classdesc.lookup('__del__')
+                source_classdef = source_desc.getclassdef(None)
+                source_repr = getinstancerepr(self.rtyper, source_classdef)
+                assert len(s_func.descriptions) == 1
+                funcdesc, = s_func.descriptions
+                graph = funcdesc.getuniquegraph()
+                self.check_graph_of_del_does_not_call_too_much(graph)
+                FUNCTYPE = FuncType([Ptr(source_repr.object_type)], Void)
+                destrptr = functionptr(FUNCTYPE, graph.name,
+                                       graph=graph,
+                                       _callable=graph.func)
+            else:
+                destrptr = None
             OBJECT = OBJECT_BY_FLAVOR[LLFLAVOR[self.gcflavor]]
             self.rtyper.attachRuntimeTypeInfoFunc(self.object_type,
                                                   ll_runtime_type_info,
-                                                  OBJECT, destrptr,
-                                                  raw_mem_attr_name)
+                                                  OBJECT, destrptr)
             vtable = self.rclass.getvtable()
             self.rtyper.set_type_for_typeptr(vtable, self.lowleveltype.TO)
 

File pypy/rpython/memory/test/test_gc.py

         assert res == concat(100)
         #assert simulator.current_size - curr < 16000 * INT_SIZE / 4
 
-    def test_lightweight_finalizer(self):
-        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')
-
-        class B(AClass):
-            pass
-
-        def f():
-            a = AClass(0)
-            for i in range(30):
-                if i % 2:
-                    a = B(3)
-                else:
-                    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
-
-        self.interpret(f, [])
-
     def test_finalizer(self):
         class B(object):
             pass

File pypy/rpython/memory/test/test_transformed_gc.py

         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

File pypy/rpython/test/test_rclass.py

         destrptr = RTTI._obj.destructor_funcptr
         assert destrptr is not None
 
-    def test_lightweight_del(self):
-        T = Struct('T', ('x', Signed))
-        
-        @rgc.owns_raw_memory('p')
-        class A(object):
-            p = nullptr(T)
-
-            def __init__(self, arg):
-                self.p = malloc(T, flavor='raw')
-
-        def f():
-            A(3)
-
-        t = TranslationContext()
-        t.buildannotator().build_types(f, [])
-        t.buildrtyper().specialize()
-        graph = graphof(t, f)
-        TYPE = graph.startblock.operations[0].args[0].value
-        RTTI = getRuntimeTypeInfo(TYPE)
-        RTTI._obj.query_funcptr # should not raise
-        assert RTTI._obj.raw_mem_attr_name == 'p'
-
     def test_del_inheritance(self):
         from pypy.rlib import rgc
         class State: