Author: Maciej Fijalkowski <[email protected]>
Branch: lightweight-finalizers
Changeset: r47886:b8be75dae939
Date: 2011-10-09 11:31 +0200
http://bitbucket.org/pypy/pypy/changeset/b8be75dae939/
Log: change approach - remove the owns_raw_memory_decorator, we'll try to
detect automatically and act accordingly
diff --git a/pypy/jit/metainterp/test/test_ajit.py
b/pypy/jit/metainterp/test/test_ajit.py
--- a/pypy/jit/metainterp/test/test_ajit.py
+++ b/pypy/jit/metainterp/test/test_ajit.py
@@ -3408,30 +3408,6 @@
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
diff --git a/pypy/rlib/rgc.py b/pypy/rlib/rgc.py
--- a/pypy/rlib/rgc.py
+++ b/pypy/rlib/rgc.py
@@ -440,23 +440,3 @@
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
diff --git a/pypy/rlib/rsocket.py b/pypy/rlib/rsocket.py
--- a/pypy/rlib/rsocket.py
+++ b/pypy/rlib/rsocket.py
@@ -15,7 +15,6 @@
# 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
@@ -57,7 +56,6 @@
_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)
@@ -78,6 +76,10 @@
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.
diff --git a/pypy/rlib/test/test_rgc.py b/pypy/rlib/test/test_rgc.py
--- a/pypy/rlib/test/test_rgc.py
+++ b/pypy/rlib/test/test_rgc.py
@@ -171,45 +171,3 @@
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
diff --git a/pypy/rpython/lltypesystem/rclass.py
b/pypy/rpython/lltypesystem/rclass.py
--- a/pypy/rpython/lltypesystem/rclass.py
+++ b/pypy/rpython/lltypesystem/rclass.py
@@ -391,39 +391,26 @@
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)
diff --git a/pypy/rpython/memory/test/test_gc.py
b/pypy/rpython/memory/test/test_gc.py
--- a/pypy/rpython/memory/test/test_gc.py
+++ b/pypy/rpython/memory/test/test_gc.py
@@ -130,37 +130,6 @@
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
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,36 +339,6 @@
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/test/test_rclass.py b/pypy/rpython/test/test_rclass.py
--- a/pypy/rpython/test/test_rclass.py
+++ b/pypy/rpython/test/test_rclass.py
@@ -977,28 +977,6 @@
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:
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit