[pypy-svn] r22782 - in pypy/dist/pypy/rpython/memory: . test
mwh at codespeak.net
mwh at codespeak.net
Sat Jan 28 14:08:13 CET 2006
Author: mwh
Date: Sat Jan 28 14:08:11 2006
New Revision: 22782
Modified:
pypy/dist/pypy/rpython/memory/gctransform.py
pypy/dist/pypy/rpython/memory/test/test_gctransform.py
Log:
(cfbolz,mwh)
Test that we handle variables without concretetypes correctly.
When looking at the graph, we realised that we need to handle return values
of type PyObject differently -- they never need to be push_alived as we are always
given a new reference to a PyObject. So we fixed that and tested for it too.
Modified: pypy/dist/pypy/rpython/memory/gctransform.py
==============================================================================
--- pypy/dist/pypy/rpython/memory/gctransform.py (original)
+++ pypy/dist/pypy/rpython/memory/gctransform.py Sat Jan 28 14:08:11 2006
@@ -24,8 +24,23 @@
EXCEPTION_RAISING_OPS = ['direct_call', 'indirect_call']
def var_needsgc(var):
- vartype = var.concretetype
- return isinstance(vartype, lltype.Ptr) and vartype._needsgc()
+ if hasattr(var, 'concretetype'):
+ vartype = var.concretetype
+ return isinstance(vartype, lltype.Ptr) and vartype._needsgc()
+ else:
+ # assume PyObjPtr
+ return True
+
+def var_ispyobj(var):
+ if hasattr(var, 'concretetype'):
+ if isinstance(var.concretetype, lltype.Ptr):
+ return var.concretetype.TO is lltype.PyObject
+ else:
+ return False
+ else:
+ # assume PyObjPtr
+ return True
+
class GCTransformer:
def __init__(self):
@@ -73,7 +88,7 @@
cleanup_on_exception.extend(self.pop_alive(var))
op.cleanup = cleanup_on_exception
if var_needsgc(op.result):
- if op.opname not in ('direct_call', 'indirect_call'):
+ if op.opname not in ('direct_call', 'indirect_call') and not var_ispyobj(op.result):
newops.extend(self.push_alive(op.result))
livevars.append(op.result)
if len(block.exits) == 0:
@@ -102,7 +117,7 @@
return [op]
def push_alive(self, var):
- if var.concretetype.TO is lltype.PyObject:
+ if var_ispyobj(var):
return self.push_alive_pyobj(var)
else:
return self.push_alive_nopyobj(var)
@@ -118,7 +133,7 @@
return [SpaceOperation("gc_push_alive_pyobj", [var], result)]
def pop_alive(self, var):
- if var.concretetype.TO is lltype.PyObject:
+ if var_ispyobj(var):
return self.pop_alive_pyobj(var)
else:
return self.pop_alive_nopyobj(var)
Modified: pypy/dist/pypy/rpython/memory/test/test_gctransform.py
==============================================================================
--- pypy/dist/pypy/rpython/memory/test/test_gctransform.py (original)
+++ pypy/dist/pypy/rpython/memory/test/test_gctransform.py Sat Jan 28 14:08:11 2006
@@ -1,5 +1,5 @@
from pypy.rpython.memory import gctransform
-from pypy.rpython.memory.gctransform import var_needsgc
+from pypy.rpython.memory.gctransform import var_needsgc, var_ispyobj
from pypy.translator.translator import TranslationContext, graphof
from pypy.rpython.lltypesystem import lltype
from pypy.objspace.flow.model import Variable
@@ -14,7 +14,10 @@
else:
refs_in = len([v for v in block.inputargs if var_needsgc(v)])
push_alives = len([op for op in block.operations
- if op.opname.startswith('gc_push_alive')])
+ if op.opname.startswith('gc_push_alive')]) + \
+ len([op for op in block.operations
+ if var_ispyobj(op.result) and 'direct_call' not in op.opname])
+
pop_alives = len([op for op in block.operations
if op.opname.startswith('gc_pop_alive')])
calls = len([op for op in block.operations
@@ -28,10 +31,11 @@
assert refs_in + push_alives + calls == pop_alives + refs_out
-def rtype_and_transform(func, inputtypes, transformcls):
+def rtype_and_transform(func, inputtypes, transformcls, specialize=True):
t = TranslationContext()
t.buildannotator().build_types(func, inputtypes)
- t.buildrtyper().specialize(t)
+ if specialize:
+ t.buildrtyper().specialize(t)
transformer = transformcls()
transformer.transform(t.graphs)
t.checkgraphs()
@@ -173,5 +177,18 @@
f(s)
return s.x
t = rtype_and_transform(g, [], gctransform.GCTransformer)
- ggraph = graphof(t, g)
+def test_noconcretetype():
+ def f():
+ return [1][0]
+ t = rtype_and_transform(f, [], gctransform.GCTransformer, specialize=False)
+ fgraph = graphof(t, f)
+ push_count = 0
+ pop_count = 0
+ for op in fgraph.startblock.operations:
+ if op.opname == 'gc_push_alive_pyobj':
+ push_count += 1
+ elif op.opname == 'gc_pop_alive_pyobj':
+ pop_count += 1
+ assert push_count == 0 and pop_count == 1
+
More information about the Pypy-commit
mailing list