[pypy-svn] r44977 - in pypy/branch/emptying-the-malloc-zoo-2/pypy: rpython/lltypesystem rpython/memory/gctransform translator/c translator/c/src translator/c/test
mwh at codespeak.net
mwh at codespeak.net
Thu Jul 12 17:33:47 CEST 2007
Author: mwh
Date: Thu Jul 12 17:33:45 2007
New Revision: 44977
Modified:
pypy/branch/emptying-the-malloc-zoo-2/pypy/rpython/lltypesystem/lloperation.py
pypy/branch/emptying-the-malloc-zoo-2/pypy/rpython/memory/gctransform/boehm.py
pypy/branch/emptying-the-malloc-zoo-2/pypy/rpython/memory/gctransform/refcounting.py
pypy/branch/emptying-the-malloc-zoo-2/pypy/translator/c/funcgen.py
pypy/branch/emptying-the-malloc-zoo-2/pypy/translator/c/gc.py
pypy/branch/emptying-the-malloc-zoo-2/pypy/translator/c/src/mem.h
pypy/branch/emptying-the-malloc-zoo-2/pypy/translator/c/support.py
pypy/branch/emptying-the-malloc-zoo-2/pypy/translator/c/test/test_boehm.py
Log:
(mwh, pedronis)
make the boehm gc transformer do way more and the boehm gcpolicy in genc do way
less
Modified: pypy/branch/emptying-the-malloc-zoo-2/pypy/rpython/lltypesystem/lloperation.py
==============================================================================
--- pypy/branch/emptying-the-malloc-zoo-2/pypy/rpython/lltypesystem/lloperation.py (original)
+++ pypy/branch/emptying-the-malloc-zoo-2/pypy/rpython/lltypesystem/lloperation.py Thu Jul 12 17:33:45 2007
@@ -341,6 +341,7 @@
'boehm_malloc': LLOp(),
'boehm_malloc_atomic': LLOp(),
+ 'boehm_register_finalizer': LLOp(),
'raw_malloc': LLOp(),
'raw_malloc_usage': LLOp(sideeffects=False),
'raw_free': LLOp(),
Modified: pypy/branch/emptying-the-malloc-zoo-2/pypy/rpython/memory/gctransform/boehm.py
==============================================================================
--- pypy/branch/emptying-the-malloc-zoo-2/pypy/rpython/memory/gctransform/boehm.py (original)
+++ pypy/branch/emptying-the-malloc-zoo-2/pypy/rpython/memory/gctransform/boehm.py Thu Jul 12 17:33:45 2007
@@ -5,22 +5,29 @@
from pypy.rpython.lltypesystem.lloperation import llop
from pypy.rpython import rmodel
from pypy.rlib.rarithmetic import ovfcheck
+from pypy.objspace.flow.model import Constant
class BoehmGCTransformer(GCTransformer):
+ FINALIZER_PTR = lltype.Ptr(lltype.FuncType([llmemory.Address], lltype.Void))
+
def __init__(self, translator, inline=False):
super(BoehmGCTransformer, self).__init__(translator, inline=inline)
self.finalizer_funcptrs = {}
memoryError = MemoryError()
- def ll_malloc_fixedsize(size):
+ def ll_malloc_fixedsize(size, finalizer):
result = llop.boehm_malloc(llmemory.Address, size)
if not result:
raise memoryError
+ if finalizer: # XXX runtime check here is bad?
+ llop.boehm_register_finalizer(lltype.Void, result, finalizer)
return result
- def ll_malloc_fixedsize_atomic(size):
+ def ll_malloc_fixedsize_atomic(size, finalizer):
result = llop.boehm_malloc_atomic(llmemory.Address, size)
if not result:
raise memoryError
+ if finalizer: # XXX runtime check here is bad?
+ llop.boehm_register_finalizer(lltype.Void, result, finalizer)
return result
# XXX, do we need/want an atomic version of this function?
def ll_malloc_varsize_no_length(length, size, itemsize):
@@ -40,9 +47,9 @@
if self.translator:
self.malloc_fixedsize_ptr = self.inittime_helper(
- ll_malloc_fixedsize, [lltype.Signed], llmemory.Address)
+ ll_malloc_fixedsize, [lltype.Signed, self.FINALIZER_PTR], llmemory.Address)
self.malloc_fixedsize_atomic_ptr = self.inittime_helper(
- ll_malloc_fixedsize_atomic, [lltype.Signed], llmemory.Address)
+ ll_malloc_fixedsize_atomic, [lltype.Signed, self.FINALIZER_PTR], llmemory.Address)
self.malloc_varsize_no_length_ptr = self.inittime_helper(
ll_malloc_varsize_no_length, [lltype.Signed]*3, llmemory.Address, inline=False)
self.malloc_varsize_ptr = self.inittime_helper(
@@ -71,10 +78,15 @@
funcptr = self.malloc_fixedsize_atomic_ptr
else:
funcptr = self.malloc_fixedsize_ptr
- v_raw = hop.genop("direct_call", [funcptr, c_size],
+ c_finalizer_ptr = Constant(self.finalizer_funcptr_for_type(TYPE), self.FINALIZER_PTR)
+ v_raw = hop.genop("direct_call",
+ [funcptr, c_size, c_finalizer_ptr],
resulttype=llmemory.Address)
hop.cast_result(v_raw)
+ # XXX In theory this is wrong:
+ gct_zero_malloc = gct_malloc
+
def gct_malloc_varsize(self, hop):
def intconst(c): return rmodel.inputconst(lltype.Signed, c)
@@ -82,6 +94,8 @@
TYPE = op.result.concretetype.TO
assert TYPE._is_varsize()
+ assert not self.finalizer_funcptr_for_type(TYPE)
+
if isinstance(TYPE, lltype.Struct):
ARRAY = TYPE._flds[TYPE._arrayfld]
else:
@@ -110,6 +124,8 @@
resulttype=llmemory.Address)
hop.cast_result(v_raw)
+ gct_zero_malloc_varsize = gct_malloc_varsize
+
def finalizer_funcptr_for_type(self, TYPE):
if TYPE in self.finalizer_funcptrs:
return self.finalizer_funcptrs[TYPE]
@@ -144,7 +160,7 @@
llop.gc_restore_exception(lltype.Void, exc_instance)
fptr = self.annotate_helper(ll_finalizer, [llmemory.Address], lltype.Void)
else:
- fptr = None
+ fptr = lltype.nullptr(self.FINALIZER_PTR.TO)
self.finalizer_funcptrs[TYPE] = fptr
return fptr
Modified: pypy/branch/emptying-the-malloc-zoo-2/pypy/rpython/memory/gctransform/refcounting.py
==============================================================================
--- pypy/branch/emptying-the-malloc-zoo-2/pypy/rpython/memory/gctransform/refcounting.py (original)
+++ pypy/branch/emptying-the-malloc-zoo-2/pypy/rpython/memory/gctransform/refcounting.py Thu Jul 12 17:33:45 2007
@@ -155,6 +155,8 @@
resulttype=llmemory.Address)
hop.cast_result(v_raw)
+ gct_zero_malloc = gct_malloc
+
def gct_malloc_varsize(self, hop):
def intconst(c): return rmodel.inputconst(lltype.Signed, c)
@@ -190,6 +192,8 @@
resulttype=llmemory.Address)
hop.cast_result(v_raw)
+ gct_zero_malloc_varsize = gct_malloc_varsize
+
def gct_gc_deallocate(self, hop):
TYPE = hop.spaceop.args[0].value
v_addr = hop.spaceop.args[1]
Modified: pypy/branch/emptying-the-malloc-zoo-2/pypy/translator/c/funcgen.py
==============================================================================
--- pypy/branch/emptying-the-malloc-zoo-2/pypy/translator/c/funcgen.py (original)
+++ pypy/branch/emptying-the-malloc-zoo-2/pypy/translator/c/funcgen.py Thu Jul 12 17:33:45 2007
@@ -510,62 +510,17 @@
self.expr(op.args[0]),
self.expr(op.args[1]))
- def OP_ZERO_MALLOC(self, op):
- TYPE = self.lltypemap(op.result).TO
- typename = self.db.gettype(TYPE)
- eresult = self.expr(op.result)
- esize = 'sizeof(%s)' % cdecl(typename, '')
-
- return self.gcpolicy.zero_malloc(TYPE, esize, eresult)
-
- def OP_MALLOC(self, op):
- TYPE = self.lltypemap(op.result).TO
- typename = self.db.gettype(TYPE)
- eresult = self.expr(op.result)
- esize = 'sizeof(%s)' % cdecl(typename, '')
-
- return self.gcpolicy.malloc(TYPE, esize, eresult)
-
- OP_ZERO_MALLOC = OP_MALLOC
-
- def OP_MALLOC_VARSIZE(self, op):
- TYPE = self.lltypemap(op.result).TO
- typename = self.db.gettype(TYPE)
- lenfld = 'length'
- nodedef = self.db.gettypedefnode(TYPE)
- if isinstance(TYPE, Struct):
- arfld = TYPE._arrayfld
- lenfld = "%s.length" % nodedef.c_struct_field_name(arfld)
- VARPART = TYPE._flds[TYPE._arrayfld]
- else:
- VARPART = TYPE
- assert isinstance(VARPART, Array)
- itemtypename = self.db.gettype(VARPART.OF)
- elength = self.expr(op.args[1])
- eresult = self.expr(op.result)
- if VARPART.OF is Void: # strange
- esize = 'sizeof(%s)' % (cdecl(typename, ''),)
- result = '{\n'
- else:
- itemtype = cdecl(itemtypename, '')
- result = 'IF_VARSIZE_OVERFLOW(%s, %s, %s)\nelse {\n' % (
- elength,
- itemtype,
- eresult)
- esize = 'sizeof(%s)-sizeof(%s)+%s*sizeof(%s)' % (
- cdecl(typename, ''),
- itemtype,
- elength,
- itemtype)
- result += self.gcpolicy.zero_malloc(TYPE, esize, eresult)
-
- # ctypes Arrays have no length field
- if not VARPART._hints.get('nolength', False):
- result += '\nif(%s) %s->%s = %s;' % (eresult, eresult, lenfld, elength)
- result += '\n}'
- return result
-
- OP_ZERO_MALLOC_VARSIZE = OP_MALLOC_VARSIZE
+ def OP_BOEHM_MALLOC(self, op):
+ return 'OP_BOEHM_ZERO_MALLOC(%s, %s, void*, 0, 0);' % (self.expr(op.args[0]),
+ self.expr(op.result))
+
+ def OP_BOEHM_MALLOC_ATOMIC(self, op):
+ return 'OP_BOEHM_ZERO_MALLOC(%s, %s, void*, 1, 0);' % (self.expr(op.args[0]),
+ self.expr(op.result))
+
+ def OP_BOEHM_REGISTER_FINALIZER(self, op):
+ return 'GC_REGISTER_FINALIZER(%s, (GC_finalization_proc)%s, NULL, NULL, NULL);' \
+ % (self.expr(op.args[0]), self.expr(op.args[1]))
def OP_RAW_MALLOC(self, op):
eresult = self.expr(op.result)
@@ -573,6 +528,7 @@
return "OP_RAW_MALLOC(%s, %s, void *);" % (esize, eresult)
def OP_FLAVORED_MALLOC(self, op):
+ # XXX this function should DIE!
TYPE = self.lltypemap(op.result).TO
typename = self.db.gettype(TYPE)
eresult = self.expr(op.result)
@@ -590,6 +546,7 @@
raise NotImplementedError
def OP_FLAVORED_MALLOC_VARSIZE(self, op):
+ # XXX this function should DIE!, at least twice over
# XXX I know this working in just one case, probably makes
# sense to assert it here, rest is just copied
flavor = op.args[0].value
Modified: pypy/branch/emptying-the-malloc-zoo-2/pypy/translator/c/gc.py
==============================================================================
--- pypy/branch/emptying-the-malloc-zoo-2/pypy/translator/c/gc.py (original)
+++ pypy/branch/emptying-the-malloc-zoo-2/pypy/translator/c/gc.py Thu Jul 12 17:33:45 2007
@@ -117,14 +117,6 @@
# zero malloc impl
- def zero_malloc(self, TYPE, esize, eresult):
- assert TYPE._gckind == 'gc' # we don't really support this
- typename = self.db.gettype(TYPE)
- erestype = cdecl(typename, '*')
- return 'OP_ZERO_MALLOC(%s, %s, %s);' % (esize, eresult, erestype)
-
- malloc = zero_malloc
-
def OP_GC_CALL_RTTI_DESTRUCTOR(self, funcgen, op):
args = [funcgen.expr(v) for v in op.args]
line = '%s(%s);' % (args[0], ', '.join(args[1:]))
@@ -180,18 +172,11 @@
class BoehmGcPolicy(BasicGcPolicy):
transformerclass = boehm.BoehmGCTransformer
- def setup_gcinfo(self, defnode):
- transformer = defnode.db.gctransformer
- fptr = transformer.finalizer_funcptr_for_type(defnode.LLTYPE)
- if fptr:
- defnode.gcinfo = BoehmInfo()
- defnode.gcinfo.finalizer = defnode.db.get(fptr)
-
def array_setup(self, arraydefnode):
- self.setup_gcinfo(arraydefnode)
+ pass
def struct_setup(self, structdefnode, rtti):
- self.setup_gcinfo(structdefnode)
+ pass
def rtti_type(self):
return BoehmGcRuntimeTypeInfo_OpaqueNode.typename
@@ -199,25 +184,6 @@
def rtti_node_factory(self):
return BoehmGcRuntimeTypeInfo_OpaqueNode
- def zero_malloc(self, TYPE, esize, eresult):
- gcinfo = self.db.gettypedefnode(TYPE).gcinfo
- assert TYPE._gckind == 'gc' # _is_atomic() depends on this!
- is_atomic = TYPE._is_atomic()
- is_varsize = TYPE._is_varsize()
- typename = self.db.gettype(TYPE)
- erestype = cdecl(typename, '*')
- result = 'OP_BOEHM_ZERO_MALLOC(%s, %s, %s, %d, %d);' % (esize,
- eresult,
- erestype,
- is_atomic,
- is_varsize)
- if gcinfo and gcinfo.finalizer:
- result += ('\nGC_REGISTER_FINALIZER(%s, (GC_finalization_proc)%s, NULL, NULL, NULL);'
- % (eresult, gcinfo.finalizer))
- return result
-
- malloc = zero_malloc
-
def gc_libraries(self):
if sys.platform == 'win32':
return ['gc_pypy']
@@ -301,7 +267,6 @@
yield "#include <gc/gc_typed.h>"
def struct_setup(self, structdefnode, rtti):
- self.setup_gcinfo(structdefnode)
T = structdefnode.STRUCT
if T._is_atomic():
malloc_exact = False
@@ -336,37 +301,11 @@
self.get_descr_name(defnode), T)
yield "}"
- def zero_malloc(self, TYPE, esize, eresult):
- defnode = self.db.gettypedefnode(TYPE)
- gcinfo = defnode.gcinfo
- if gcinfo:
- if not gcinfo.malloc_exact:
- assert TYPE._gckind == 'gc' # _is_atomic() depends on this!
- is_atomic = TYPE._is_atomic()
- is_varsize = TYPE._is_varsize()
- typename = self.db.gettype(TYPE)
- erestype = cdecl(typename, '*')
- result = 'OP_BOEHM_ZERO_MALLOC(%s, %s, %s, %d, %d);' % (
- esize, eresult, erestype, is_atomic, is_varsize)
- else:
- result = '%s = GC_MALLOC_EXPLICITLY_TYPED(%s, %s);' % (
- eresult, esize, self.get_descr_name(defnode))
- if gcinfo.finalizer:
- result += ('\nGC_REGISTER_FINALIZER(%s, (GC_finalization_proc)%s, NULL, NULL, NULL);'
- % (eresult, gcinfo.finalizer))
- else:
- return super(MoreExactBoehmGcPolicy, self).zero_malloc(
- TYPE, esize, eresult)
- return result
-
- malloc = zero_malloc
# to get an idea how it looks like with no refcount/gc at all
class NoneGcPolicy(BoehmGcPolicy):
- zero_malloc = RefcountingGcPolicy.zero_malloc.im_func
- malloc = RefcountingGcPolicy.malloc.im_func
gc_libraries = RefcountingGcPolicy.gc_libraries.im_func
gc_startup_code = RefcountingGcPolicy.gc_startup_code.im_func
@@ -421,11 +360,6 @@
o = top_container(defnode.obj)
return defnode.db.gctransformer.gc_field_values_for(o)
- def zero_malloc(self, TYPE, esize, eresult):
- assert False, "a malloc operation in a framework build??"
-
- malloc = zero_malloc
-
class StacklessFrameworkGcPolicy(FrameworkGcPolicy):
transformerclass = stacklessframework.StacklessFrameworkGCTransformer
requires_stackless = True
Modified: pypy/branch/emptying-the-malloc-zoo-2/pypy/translator/c/src/mem.h
==============================================================================
--- pypy/branch/emptying-the-malloc-zoo-2/pypy/translator/c/src/mem.h (original)
+++ pypy/branch/emptying-the-malloc-zoo-2/pypy/translator/c/src/mem.h Thu Jul 12 17:33:45 2007
@@ -116,7 +116,6 @@
#define OP_BOEHM_ZERO_MALLOC(size, r, restype, is_atomic, is_varsize) { \
r = (restype) BOEHM_MALLOC_ ## is_atomic ## _ ## is_varsize (size); \
- if (r == NULL) {FAIL_EXCEPTION(PyExc_MemoryError, "out of memory");} \
else { \
if (is_atomic) /* the non-atomic versions return cleared memory */ \
memset((void*) r, 0, size); \
Modified: pypy/branch/emptying-the-malloc-zoo-2/pypy/translator/c/support.py
==============================================================================
--- pypy/branch/emptying-the-malloc-zoo-2/pypy/translator/c/support.py (original)
+++ pypy/branch/emptying-the-malloc-zoo-2/pypy/translator/c/support.py Thu Jul 12 17:33:45 2007
@@ -52,6 +52,10 @@
else:
return s[:2].lower()
+def is_pointer_to_forward_ref(T):
+ if not isinstance(T, lltype.Ptr):
+ return False
+ return isinstance(T.TO, lltype.ForwardReference)
def llvalue_from_constant(c):
try:
@@ -64,7 +68,12 @@
if T == lltype.Void:
return None
else:
- assert lltype.typeOf(c.value) == T
+ ACTUAL_TYPE = lltype.typeOf(c.value)
+ # If the type is still uncomputed, we can't make this
+ # check. Something else will blow up instead, probably
+ # very confusingly.
+ if not is_pointer_to_forward_ref(ACTUAL_TYPE):
+ assert ACTUAL_TYPE == T
return c.value
Modified: pypy/branch/emptying-the-malloc-zoo-2/pypy/translator/c/test/test_boehm.py
==============================================================================
--- pypy/branch/emptying-the-malloc-zoo-2/pypy/translator/c/test/test_boehm.py (original)
+++ pypy/branch/emptying-the-malloc-zoo-2/pypy/translator/c/test/test_boehm.py Thu Jul 12 17:33:45 2007
@@ -1,6 +1,6 @@
import py
from pypy.translator.translator import TranslationContext
-from pypy.rpython.lltypesystem.lltype import Void
+from pypy.rpython.lltypesystem import lltype
from pypy.translator.tool.cbuild import check_boehm_presence
from pypy.translator.c.genc import CExtModuleBuilder
from pypy import conftest
@@ -62,7 +62,6 @@
def test__del__(self):
from pypy.rpython.lltypesystem.lloperation import llop
- from pypy.rpython.lltypesystem import lltype
class State:
pass
s = State()
@@ -98,7 +97,6 @@
def test_weakgcaddress_is_weak(self):
from pypy.rpython.lltypesystem.lloperation import llop
- from pypy.rpython.lltypesystem import lltype
from pypy.rlib.objectmodel import cast_object_to_weakgcaddress
class State:
pass
@@ -130,7 +128,6 @@
def test_del_raises(self):
from pypy.rpython.lltypesystem.lloperation import llop
- from pypy.rpython.lltypesystem import lltype
import os
class A(object):
def __del__(self):
@@ -160,7 +157,6 @@
assert res > 0
def test_memory_error_varsize(self):
- from pypy.rpython.lltypesystem import lltype
N = int(2**31-1)
A = lltype.GcArray(lltype.Char)
def alloc(n):
@@ -183,7 +179,7 @@
def prob_with_pyobj(b):
return 3, b
def collect():
- llop.gc__collect(Void)
+ llop.gc__collect(lltype.Void)
f = self.getcompiled(prob_with_pyobj, [object])
c = self.getcompiled(collect, [])
from sys import getrefcount as g
@@ -202,6 +198,23 @@
after = g(obj)
assert abs(before - after) < 5
+ def test_zero_malloc(self):
+ T = lltype.GcStruct("C", ('x', lltype.Signed))
+ def fixed_size():
+ t = lltype.malloc(T, zero=True)
+ return t.x
+ c_fixed_size = self.getcompiled(fixed_size, [])
+ res = c_fixed_size()
+ assert res == 0
+ A = lltype.GcArray(lltype.Signed)
+ def var_size():
+ a = lltype.malloc(A, 1, zero=True)
+ return a[0]
+ c_var_size = self.getcompiled(var_size, [])
+ res = c_var_size()
+ assert res == 0
+
+
class TestUsingExactBoehm(TestUsingBoehm):
gcpolicy = "exact_boehm"
More information about the Pypy-commit
mailing list