[pypy-svn] r48337 - in pypy/dist/pypy/translator/backendopt: . test
cfbolz at codespeak.net
cfbolz at codespeak.net
Tue Nov 6 14:20:28 CET 2007
Author: cfbolz
Date: Tue Nov 6 14:20:27 2007
New Revision: 48337
Modified:
pypy/dist/pypy/translator/backendopt/coalloc.py
pypy/dist/pypy/translator/backendopt/test/test_coalloc.py
Log:
don't coallocate things with a __del__
Modified: pypy/dist/pypy/translator/backendopt/coalloc.py
==============================================================================
--- pypy/dist/pypy/translator/backendopt/coalloc.py (original)
+++ pypy/dist/pypy/translator/backendopt/coalloc.py Tue Nov 6 14:20:27 2007
@@ -8,6 +8,7 @@
class CreationPoint(object):
constant = None
+ coallocator = None
def __init__(self, creation_method, TYPE):
self.creation_method = creation_method
self.TYPE = TYPE
@@ -39,6 +40,12 @@
crepsrepr = (", ".join([repr(crep) for crep in self.creation_points]), )
return "VarState({%s})" % crepsrepr
+ def get_crep(self, checksingle=False):
+ if checksingle:
+ assert len(self.creation_points) == 1
+ for crep in self.creation_points.iterkeys():
+ return crep
+
class GraphState(object):
def __init__(self, graph):
self.graph = graph
@@ -319,7 +326,7 @@
if len(tovarstate.creation_points) != 1:
continue
fromcreps = set(fromvarstate.creation_points.keys())
- tocrep = tovarstate.creation_points.keys()[0]
+ tocrep = tovarstate.get_crep()
if not tocrep.creation_method.startswith("malloc"):
continue
for fromcrep in fromcreps:
@@ -327,7 +334,7 @@
break # also recently malloced
else:
#import pdb; pdb.set_trace()
- num = do_coalloc(adi, graph, op.args[0], block,
+ num = do_coalloc(adi, graph, block, op,
fromcreps, tocrep)
if num:
@@ -338,9 +345,9 @@
return total
-def do_coalloc(adi, graph, fromvar, setblock, fromcreps, tocrep):
+def do_coalloc(adi, graph, setblock, setop, fromcreps, tocrep):
def find_coalloc_var():
- if block is setblock:
+ if block is setblock and seen_setvar:
return fromvar
for fromcrep in fromcreps:
if fromcrep.creation_method == "constant":
@@ -348,16 +355,24 @@
for fromcrep in fromcreps:
for var in block.inputargs:
varstate = adi.getstate(var)
- assert len(varstate.creation_points) == 1
- crep = varstate.creation_points.keys()[0]
+ if varstate is None:
+ continue
+ crep = varstate.get_crep(checksingle=True)
if crep is fromcrep:
return var
return None
result = 0
+ seen_setvar = False
for block, op in graph.iterblockops():
+ if op.result is setop.args[0]:
+ seen_setvar = True
if not op.opname.startswith("malloc"):
continue
- if adi.getstate(op.result).creation_points.keys()[0] is not tocrep:
+ if adi.getstate(op.result).get_crep(checksingle=True) is not tocrep:
+ continue
+ TYPE = op.result.concretetype.TO
+ # must not remove mallocs of structures that a destructor
+ if hasdestructor(TYPE):
continue
coallocvar = find_coalloc_var()
if coallocvar is None:
@@ -365,8 +380,18 @@
op.opname = "coalloc" + op.opname[len("malloc"):]
op.args.insert(1, coallocvar)
mallocvarstate = adi.getstate(op.result)
- assert len(mallocvarstate.creation_points) == 1
- malloccrep = mallocvarstate.creation_points.keys()[0]
+ malloccrep = mallocvarstate.get_crep(checksingle=True)
malloccrep.creation_method = "coalloc"
result += 1
return result
+
+def hasdestructor(STRUCT):
+ if not isinstance(STRUCT, lltype.Struct):
+ return False
+ try:
+ destr_ptr = lltype.getRuntimeTypeInfo(STRUCT)._obj.destructor_funcptr
+ if destr_ptr:
+ return True
+ except (ValueError, AttributeError), e:
+ pass
+ return False
Modified: pypy/dist/pypy/translator/backendopt/test/test_coalloc.py
==============================================================================
--- pypy/dist/pypy/translator/backendopt/test/test_coalloc.py (original)
+++ pypy/dist/pypy/translator/backendopt/test/test_coalloc.py Tue Nov 6 14:20:27 2007
@@ -240,3 +240,27 @@
g(a)
return a.length
t = check_malloc_to_coalloc(f, [int], [8], 8, must_remove=1)
+
+def test_coalloc_in_setblock():
+ class A(object):
+ pass
+ a3 = A()
+ def f():
+ a1 = A()
+ a2 = A()
+ a2.a = a1
+ a3.a = a2
+ return 1
+ # this should really be mustremove=2, but for now I am happy
+ t = check_malloc_to_coalloc(f, [], [], 1, must_remove=1)
+
+def test_nocoalloc_finalizer():
+ class A(object):
+ def __del__(self):
+ pass
+ a = A()
+ def f():
+ n = A()
+ a.next = n
+ return 1
+ check_malloc_to_coalloc(f, [], [], 1, must_remove=0)
More information about the Pypy-commit
mailing list