[pypy-svn] r28588 - in pypy/dist/pypy: rpython rpython/lltypesystem rpython/lltypesystem/test rpython/memory translator/c translator/c/src
arigo at codespeak.net
arigo at codespeak.net
Fri Jun 9 15:55:08 CEST 2006
Author: arigo
Date: Fri Jun 9 15:55:04 2006
New Revision: 28588
Modified:
pypy/dist/pypy/rpython/llinterp.py
pypy/dist/pypy/rpython/lltypesystem/lloperation.py
pypy/dist/pypy/rpython/lltypesystem/lltype.py
pypy/dist/pypy/rpython/lltypesystem/rclass.py
pypy/dist/pypy/rpython/lltypesystem/test/test_rcpyclass.py
pypy/dist/pypy/rpython/memory/gctransform.py
pypy/dist/pypy/rpython/rcpy.py
pypy/dist/pypy/translator/c/funcgen.py
pypy/dist/pypy/translator/c/gc.py
pypy/dist/pypy/translator/c/node.py
pypy/dist/pypy/translator/c/src/mem.h
Log:
(arre, arigo)
Support deallocation "properly" for PyStruct and rcpy.py.
Modified: pypy/dist/pypy/rpython/llinterp.py
==============================================================================
--- pypy/dist/pypy/rpython/llinterp.py (original)
+++ pypy/dist/pypy/rpython/llinterp.py Fri Jun 9 15:55:04 2006
@@ -751,6 +751,9 @@
def op_gc_call_rtti_destructor(self, rtti, addr):
raise NotImplementedError("gc_call_rtti_destructor")
+ def op_gc_deallocate(self, TYPE, addr):
+ raise NotImplementedError("gc_deallocate")
+
def op_gc_push_alive_pyobj(self, pyobj):
raise NotImplementedError("gc_push_alive_pyobj")
Modified: pypy/dist/pypy/rpython/lltypesystem/lloperation.py
==============================================================================
--- pypy/dist/pypy/rpython/lltypesystem/lloperation.py (original)
+++ pypy/dist/pypy/rpython/lltypesystem/lloperation.py Fri Jun 9 15:55:04 2006
@@ -321,6 +321,7 @@
'gc_fetch_exception': LLOp(),
'gc_restore_exception': LLOp(),
'gc_call_rtti_destructor': LLOp(),
+ 'gc_deallocate': LLOp(),
'gc_push_alive_pyobj': LLOp(),
'gc_pop_alive_pyobj': LLOp(),
'gc_protect': LLOp(),
Modified: pypy/dist/pypy/rpython/lltypesystem/lltype.py
==============================================================================
--- pypy/dist/pypy/rpython/lltypesystem/lltype.py (original)
+++ pypy/dist/pypy/rpython/lltypesystem/lltype.py Fri Jun 9 15:55:04 2006
@@ -262,8 +262,7 @@
n = 1
return _struct(self, n)
-class GcStruct(Struct):
- _gckind = 'gc'
+class RttiStruct(Struct):
_runtime_type_info = None
def _attach_runtime_type_info_funcptr(self, funcptr, destrptr):
@@ -290,11 +289,14 @@
"implementation, got: %s" % destrptr)
self._runtime_type_info.destructor_funcptr = destrptr
-class PyStruct(Struct):
+class GcStruct(RttiStruct):
+ _gckind = 'gc'
+
+class PyStruct(RttiStruct):
_gckind = 'cpy'
def __init__(self, name, *fields, **kwds):
- Struct.__init__(self, name, *fields, **kwds)
+ RttiStruct.__init__(self, name, *fields, **kwds)
if self._first_struct() == (None, None):
raise TypeError("a PyStruct must have another PyStruct or "
"PyObject as first field")
@@ -457,6 +459,8 @@
def _inline_is_varsize(self, last):
raise TypeError, "%r cannot be inlined in structure" % self
+FOR_TESTING_ONLY = "for testing only"
+
class PyObjectType(ContainerType):
_gckind = 'cpy'
__name__ = 'PyObject'
@@ -466,10 +470,10 @@
return False
def _defl(self, parent=None, parentindex=None, extra_args=()):
if not extra_args:
- raise NotImplementedError("PyObjectType._defl()")
+ ob_type = FOR_TESTING_ONLY
else:
ob_type = extra_args[0]
- return _pyobjheader(ob_type, parent, parentindex)
+ return _pyobjheader(ob_type, parent, parentindex)
PyObject = PyObjectType()
@@ -1478,7 +1482,8 @@
def __init__(self, ob_type, parent=None, parentindex=None):
_parentable.__init__(self, PyObject)
- assert typeOf(ob_type) == Ptr(PyObject)
+ assert (ob_type is FOR_TESTING_ONLY or
+ typeOf(ob_type) == Ptr(PyObject))
self.ob_type = ob_type
if parent is not None:
self._setparentstructure(parent, parentindex)
@@ -1540,22 +1545,22 @@
return _ptr(PTRTYPE, oddint, solid=True)
def attachRuntimeTypeInfo(GCSTRUCT, funcptr=None, destrptr=None):
- if not isinstance(GCSTRUCT, GcStruct):
- raise TypeError, "expected a GcStruct: %s" % GCSTRUCT
+ if not isinstance(GCSTRUCT, RttiStruct):
+ raise TypeError, "expected a RttiStruct: %s" % GCSTRUCT
GCSTRUCT._attach_runtime_type_info_funcptr(funcptr, destrptr)
return _ptr(Ptr(RuntimeTypeInfo), GCSTRUCT._runtime_type_info)
def getRuntimeTypeInfo(GCSTRUCT):
- if not isinstance(GCSTRUCT, GcStruct):
- raise TypeError, "expected a GcStruct: %s" % GCSTRUCT
+ if not isinstance(GCSTRUCT, RttiStruct):
+ raise TypeError, "expected a RttiStruct: %s" % GCSTRUCT
if GCSTRUCT._runtime_type_info is None:
raise ValueError, "no attached runtime type info for %s" % GCSTRUCT
return _ptr(Ptr(RuntimeTypeInfo), GCSTRUCT._runtime_type_info)
def runtime_type_info(p):
T = typeOf(p)
- if not isinstance(T, Ptr) or not isinstance(T.TO, GcStruct):
- raise TypeError, "runtime_type_info on non-GcStruct pointer: %s" % p
+ if not isinstance(T, Ptr) or not isinstance(T.TO, RttiStruct):
+ raise TypeError, "runtime_type_info on non-RttiStruct pointer: %s" % p
struct = p._obj
top_parent = top_container(struct)
result = getRuntimeTypeInfo(top_parent._TYPE)
Modified: pypy/dist/pypy/rpython/lltypesystem/rclass.py
==============================================================================
--- pypy/dist/pypy/rpython/lltypesystem/rclass.py (original)
+++ pypy/dist/pypy/rpython/lltypesystem/rclass.py Fri Jun 9 15:55:04 2006
@@ -85,6 +85,7 @@
'cpy' : 'cpy',
'stack': 'raw',
}
+RTTIFLAVORS = ('gc', 'cpy')
def cast_vtable_to_typeptr(vtable):
while typeOf(vtable).TO != OBJECT_VTABLE:
@@ -188,7 +189,7 @@
vtable.subclassrange_max = sys.maxint
rinstance = getinstancerepr(self.rtyper, rsubcls.classdef)
rinstance.setup()
- if rinstance.gcflavor == 'gc': # only gc-case
+ if rinstance.gcflavor in RTTIFLAVORS:
vtable.rtti = getRuntimeTypeInfo(rinstance.object_type)
if rsubcls.classdef is None:
name = 'object'
@@ -358,11 +359,11 @@
allinstancefields.update(fields)
self.fields = fields
self.allinstancefields = allinstancefields
- if self.gcflavor == 'gc': # only gc-case
+ if self.gcflavor in RTTIFLAVORS:
attachRuntimeTypeInfo(self.object_type)
def _setup_repr_final(self):
- if self.gcflavor == 'gc': # only gc-case
+ if self.gcflavor in RTTIFLAVORS:
if (self.classdef is not None and
self.classdef.classdesc.lookup('__del__') is not None):
s_func = self.classdef.classdesc.s_read_attribute('__del__')
@@ -378,6 +379,7 @@
_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)
Modified: pypy/dist/pypy/rpython/lltypesystem/test/test_rcpyclass.py
==============================================================================
--- pypy/dist/pypy/rpython/lltypesystem/test/test_rcpyclass.py (original)
+++ pypy/dist/pypy/rpython/lltypesystem/test/test_rcpyclass.py Fri Jun 9 15:55:04 2006
@@ -43,7 +43,6 @@
def test_tp_dealloc():
- import py; py.test.skip("in-progress")
class mytest(object):
pass
Modified: pypy/dist/pypy/rpython/memory/gctransform.py
==============================================================================
--- pypy/dist/pypy/rpython/memory/gctransform.py (original)
+++ pypy/dist/pypy/rpython/memory/gctransform.py Fri Jun 9 15:55:04 2006
@@ -410,7 +410,7 @@
ADDRESS_VOID_FUNC = lltype.FuncType([llmemory.Address], lltype.Void)
def get_rtti(TYPE):
- if isinstance(TYPE, lltype.GcStruct):
+ if isinstance(TYPE, lltype.RttiStruct):
try:
return lltype.getRuntimeTypeInfo(TYPE)
except ValueError:
@@ -636,6 +636,16 @@
self.queryptr2dynamic_deallocator_funcptr[queryptr._obj] = fptr
return fptr
+ def replace_gc_deallocate(self, op, livevars, block):
+ TYPE = op.args[0].value
+ v_addr = op.args[1]
+ dealloc_fptr = self.dynamic_deallocation_funcptr_for_type(TYPE)
+ cdealloc_fptr = rmodel.inputconst(
+ lltype.typeOf(dealloc_fptr), dealloc_fptr)
+ return [SpaceOperation("direct_call", [cdealloc_fptr,
+ v_addr],
+ varoftype(lltype.Void))]
+
def varoftype(concretetype):
var = Variable()
var.concretetype = concretetype
Modified: pypy/dist/pypy/rpython/rcpy.py
==============================================================================
--- pypy/dist/pypy/rpython/rcpy.py (original)
+++ pypy/dist/pypy/rpython/rcpy.py Fri Jun 9 15:55:04 2006
@@ -1,6 +1,8 @@
from pypy.rpython.extregistry import ExtRegistryEntry
from pypy.rpython.lltypesystem import lltype, llmemory
+from pypy.rpython.lltypesystem.lloperation import llop
from pypy.rpython.objectmodel import CDefinedIntSymbolic
+from pypy.objspace.flow.model import Constant
def cpy_export(cpytype, obj):
@@ -72,7 +74,8 @@
('c_tp_name', lltype.Ptr(lltype.FixedSizeArray(lltype.Char, 1))),
('c_tp_basicsize', lltype.Signed),
('c_tp_itemsize', lltype.Signed),
- ('c_tp_dealloc', lltype.Signed),
+ ('c_tp_dealloc', lltype.Ptr(lltype.FuncType([PyObjPtr],
+ lltype.Void))),
('c_tp_print', lltype.Signed),
('c_tp_getattr', lltype.Signed),
('c_tp_setattr', lltype.Signed), # in
@@ -104,24 +107,31 @@
('c_tp_descr_set', lltype.Signed),
('c_tp_dictoffset',lltype.Signed),
('c_tp_init', lltype.Signed),
- ('c_tp_alloc', lltype.Ptr(lltype.FuncType([lltype.Ptr(PY_TYPE_OBJECT),
- lltype.Signed],
+ ('c_tp_alloc', lltype.Signed),
+ #lltype.Ptr(lltype.FuncType([lltype.Ptr(PY_TYPE_OBJECT),
+ # lltype.Signed],
+ # PyObjPtr))),
+ ('c_tp_new', lltype.Ptr(lltype.FuncType([lltype.Ptr(PY_TYPE_OBJECT),
+ PyObjPtr,
+ PyObjPtr],
PyObjPtr))),
- ('c_tp_new', lltype.Signed),
- ('c_tp_free', lltype.Ptr(lltype.FuncType([llmemory.Address],
- lltype.Void))),
+ ('c_tp_free', lltype.Signed),
+ #lltype.Ptr(lltype.FuncType([llmemory.Address],
+ # lltype.Void))),
hints={'c_name': '_typeobject', 'external': True, 'inline_head': True}))
# XXX should be PyTypeObject but genc inserts 'struct' :-(
-def ll_tp_alloc(tp, itemcount):
- # XXX pass itemcount too
+def ll_tp_new(tp, args, kwds):
return lltype.malloc(lltype.PyObject, flavor='cpy', extra_args=(tp,))
-def ll_tp_free(addr):
- # hack: don't cast addr to PyObjPtr, otherwise there is an incref/decref
- # added around the free!
- lltype.free(addr, flavor='cpy')
+def ll_tp_dealloc(p):
+ addr = llmemory.cast_ptr_to_adr(p)
+ # Warning: this relies on an optimization in gctransformer, which will
+ # not insert any incref/decref for 'p'. That would lead to infinite
+ # recursion, as the refcnt of 'p' is already zero!
+ from pypy.rpython.lltypesystem.rclass import CPYOBJECT
+ llop.gc_deallocate(lltype.Void, CPYOBJECT, addr)
def build_pytypeobject(r_inst):
typetype = lltype.pyobjectptr(type)
@@ -136,10 +146,10 @@
pytypeobj.c_tp_name = lltype.direct_arrayitems(p)
pytypeobj.c_tp_basicsize = llmemory.sizeof(r_inst.lowleveltype.TO)
pytypeobj.c_tp_flags = CDefinedIntSymbolic('Py_TPFLAGS_DEFAULT')
- pytypeobj.c_tp_alloc = r_inst.rtyper.annotate_helper_fn(
- ll_tp_alloc,
- [lltype.Ptr(PY_TYPE_OBJECT), lltype.Signed])
- pytypeobj.c_tp_free = r_inst.rtyper.annotate_helper_fn(
- ll_tp_free,
- [llmemory.Address])
+ pytypeobj.c_tp_new = r_inst.rtyper.annotate_helper_fn(
+ ll_tp_new,
+ [lltype.Ptr(PY_TYPE_OBJECT), PyObjPtr, PyObjPtr])
+ pytypeobj.c_tp_dealloc = r_inst.rtyper.annotate_helper_fn(
+ ll_tp_dealloc,
+ [PyObjPtr])
return lltype.cast_pointer(PyObjPtr, pytypeobj)
Modified: pypy/dist/pypy/translator/c/funcgen.py
==============================================================================
--- pypy/dist/pypy/translator/c/funcgen.py (original)
+++ pypy/dist/pypy/translator/c/funcgen.py Fri Jun 9 15:55:04 2006
@@ -569,7 +569,8 @@
def OP_FLAVORED_FREE(self, op):
flavor = op.args[0].value
if flavor == "raw":
- return "OP_RAW_FREE(%s)" % (self.expr(op.args[1]),)
+ return "OP_RAW_FREE(%s, %s)" % (self.expr(op.args[1]),
+ self.expr(op.result))
elif flavor == "cpy":
return "OP_CPY_FREE(%s)" % (self.expr(op.args[1]),)
else:
Modified: pypy/dist/pypy/translator/c/gc.py
==============================================================================
--- pypy/dist/pypy/translator/c/gc.py (original)
+++ pypy/dist/pypy/translator/c/gc.py Fri Jun 9 15:55:04 2006
@@ -2,7 +2,7 @@
from pypy.translator.c.support import cdecl
from pypy.translator.c.node import ContainerNode
from pypy.rpython.lltypesystem.lltype import \
- typeOf, Ptr, ContainerType, GcArray, GcStruct, \
+ typeOf, Ptr, ContainerType, RttiStruct, \
RuntimeTypeInfo, getRuntimeTypeInfo, top_container
from pypy.rpython.memory import gctransform
from pypy.rpython.lltypesystem import lltype, llmemory
@@ -131,7 +131,7 @@
def __init__(self, db, T, obj):
assert T == RuntimeTypeInfo
- assert isinstance(obj.about, GcStruct)
+ assert isinstance(obj.about, RttiStruct)
self.db = db
self.T = T
self.obj = obj
@@ -238,7 +238,7 @@
def __init__(self, db, T, obj):
assert T == RuntimeTypeInfo
- assert isinstance(obj.about, GcStruct)
+ assert isinstance(obj.about, RttiStruct)
self.db = db
self.T = T
self.obj = obj
Modified: pypy/dist/pypy/translator/c/node.py
==============================================================================
--- pypy/dist/pypy/translator/c/node.py (original)
+++ pypy/dist/pypy/translator/c/node.py Fri Jun 9 15:55:04 2006
@@ -1,7 +1,7 @@
from __future__ import generators
from pypy.rpython.lltypesystem.lltype import \
Struct, Array, FixedSizeArray, FuncType, PyObjectType, typeOf, \
- GcStruct, GcArray, PyStruct, ContainerType, \
+ GcStruct, GcArray, RttiStruct, PyStruct, ContainerType, \
parentlink, Ptr, PyObject, Void, OpaqueType, Float, \
RuntimeTypeInfo, getRuntimeTypeInfo, Char, _subarray, _pyobjheader
from pypy.rpython.lltypesystem.llmemory import WeakGcAddress
@@ -85,7 +85,7 @@
self.gcinfo = None # unless overwritten below
rtti = None
STRUCT = self.STRUCT
- if isinstance(STRUCT, GcStruct):
+ if isinstance(STRUCT, RttiStruct):
try:
rtti = getRuntimeTypeInfo(STRUCT)
except ValueError:
Modified: pypy/dist/pypy/translator/c/src/mem.h
==============================================================================
--- pypy/dist/pypy/translator/c/src/mem.h (original)
+++ pypy/dist/pypy/translator/c/src/mem.h Fri Jun 9 15:55:04 2006
@@ -14,7 +14,7 @@
r = (void*) alloca(size); \
if (r == NULL) FAIL_EXCEPTION(PyExc_MemoryError, "out of memory");\
-#define OP_RAW_FREE(x) OP_FREE(x)
+#define OP_RAW_FREE(x,r) OP_FREE(x)
#define OP_RAW_MEMCOPY(x,y,size,r) memcpy(y,x,size);
/************************************************************/
@@ -130,4 +130,4 @@
PyObject_Init((PyObject *)r, (PyTypeObject *)cpytype); \
} \
}
-#define OP_CPY_FREE(x) OP_RAW_FREE(x)
+#define OP_CPY_FREE(x) OP_RAW_FREE(x, /*nothing*/)
More information about the Pypy-commit
mailing list