[pypy-svn] r18177 - in pypy/dist/pypy: annotation rpython rpython/test translator translator/backendopt translator/backendopt/test translator/c translator/c/test
pedronis at codespeak.net
pedronis at codespeak.net
Tue Oct 4 23:53:13 CEST 2005
Author: pedronis
Date: Tue Oct 4 23:53:06 2005
New Revision: 18177
Modified:
pypy/dist/pypy/annotation/builtin.py
pypy/dist/pypy/rpython/llinterp.py
pypy/dist/pypy/rpython/objectmodel.py
pypy/dist/pypy/rpython/rbuiltin.py
pypy/dist/pypy/rpython/test/test_objectmodel.py
pypy/dist/pypy/translator/backendopt/malloc.py
pypy/dist/pypy/translator/backendopt/test/test_malloc.py
pypy/dist/pypy/translator/c/funcgen.py
pypy/dist/pypy/translator/c/test/test_genc.py
pypy/dist/pypy/translator/simplify.py
Log:
introduced a keepalive objectmodel function and ll operation to have lifetime control and to be used to avoud premature garbage collection (for example with inlining,
which is next to fix using this)
Modified: pypy/dist/pypy/annotation/builtin.py
==============================================================================
--- pypy/dist/pypy/annotation/builtin.py (original)
+++ pypy/dist/pypy/annotation/builtin.py Tue Oct 4 23:53:06 2005
@@ -254,6 +254,10 @@
f, rinputs, rresult = r_func.get_signature()
return lltype_to_annotation(rresult.lowleveltype)
+def robjmodel_keepalive(*args_s):
+ return immutablevalue(None)
+
+
##def rarith_ovfcheck(s_obj):
## if isinstance(s_obj, SomeInteger) and s_obj.unsigned:
## getbookkeeper().warning("ovfcheck on unsigned")
@@ -294,6 +298,7 @@
robjmodel_we_are_translated)
BUILTIN_ANALYZERS[pypy.rpython.objectmodel.r_dict] = robjmodel_r_dict
BUILTIN_ANALYZERS[pypy.rpython.objectmodel.hlinvoke] = robjmodel_hlinvoke
+BUILTIN_ANALYZERS[pypy.rpython.objectmodel.keepalive] = robjmodel_keepalive
BUILTIN_ANALYZERS[Exception.__init__.im_func] = exception_init
BUILTIN_ANALYZERS[OSError.__init__.im_func] = exception_init
Modified: pypy/dist/pypy/rpython/llinterp.py
==============================================================================
--- pypy/dist/pypy/rpython/llinterp.py (original)
+++ pypy/dist/pypy/rpython/llinterp.py Tue Oct 4 23:53:06 2005
@@ -259,6 +259,9 @@
# __________________________________________________________
# misc LL operation implementations
+ def op_keepalive(self, *values):
+ pass
+
def op_same_as(self, x):
return x
Modified: pypy/dist/pypy/rpython/objectmodel.py
==============================================================================
--- pypy/dist/pypy/rpython/objectmodel.py (original)
+++ pypy/dist/pypy/rpython/objectmodel.py Tue Oct 4 23:53:06 2005
@@ -17,6 +17,9 @@
return False
# annotation -> True
+def keepalive(*values):
+ pass
+
class FREED_OBJECT(object):
def __getattribute__(self, attr):
Modified: pypy/dist/pypy/rpython/rbuiltin.py
==============================================================================
--- pypy/dist/pypy/rpython/rbuiltin.py (original)
+++ pypy/dist/pypy/rpython/rbuiltin.py Tue Oct 4 23:53:06 2005
@@ -394,3 +394,10 @@
return hop.genop('flavored_free', [cflavor, vinst])
BUILTIN_TYPER[objectmodel.free_non_gc_object] = rtype_free_non_gc_object
+
+# keepalive
+
+def rtype_keepalive(hop):
+ return hop.genop('keepalive', hop.args_v, resulttype=lltype.Void)
+
+BUILTIN_TYPER[objectmodel.keepalive] = rtype_keepalive
Modified: pypy/dist/pypy/rpython/test/test_objectmodel.py
==============================================================================
--- pypy/dist/pypy/rpython/test/test_objectmodel.py (original)
+++ pypy/dist/pypy/rpython/test/test_objectmodel.py Tue Oct 4 23:53:06 2005
@@ -141,3 +141,14 @@
assert res == 1
res = interpret(fn, [2])
assert res == 2
+
+def test_rtype_keepalive():
+ from pypy.rpython import objectmodel
+ def f():
+ x = [1]
+ y = ['b']
+ objectmodel.keepalive(x,y)
+ return 1
+
+ res = interpret(f, [])
+ assert res == 1
Modified: pypy/dist/pypy/translator/backendopt/malloc.py
==============================================================================
--- pypy/dist/pypy/translator/backendopt/malloc.py (original)
+++ pypy/dist/pypy/translator/backendopt/malloc.py Tue Oct 4 23:53:06 2005
@@ -108,12 +108,16 @@
STRUCT = lltypes.keys()[0].TO
assert isinstance(STRUCT, lltype.GcStruct)
- # must be only ever accessed via getfield/setfield
+ # must be only ever accessed via getfield/setfield or touched by keepalive
for up in info.usepoints:
if up[0] != "op":
return False
- if (up[2].opname, up[3]) not in [("getfield", 0), ("setfield", 0)]:
- return False
+ kind, node, op, index = up
+ if op.opname == 'keepalive':
+ continue
+ if (op.opname, index) in [("getfield", 0), ("setfield", 0)]:
+ continue
+ return False
# success: replace each variable with a family of variables (one per field)
example = STRUCT._container_example()
@@ -172,6 +176,8 @@
# equivalent. We can, and indeed must, use the same
# flattened list of variables for both, as a "setfield"
# via one pointer must be reflected in the other.
+ elif op.opname == 'keepalive':
+ pass
else:
raise AssertionError, op.opname
elif op.result in vars:
Modified: pypy/dist/pypy/translator/backendopt/test/test_malloc.py
==============================================================================
--- pypy/dist/pypy/translator/backendopt/test/test_malloc.py (original)
+++ pypy/dist/pypy/translator/backendopt/test/test_malloc.py Tue Oct 4 23:53:06 2005
@@ -97,3 +97,15 @@
a.x = 12
return a1.x
check(fn6, [int], [1], 12, must_be_removed=False)
+
+def test_with_keepalive():
+ from pypy.rpython.objectmodel import keepalive
+ def fn1(x, y):
+ if x > 0:
+ t = x+y, x-y
+ else:
+ t = x-y, x+y
+ s, d = t
+ keepalive(t)
+ return s*d
+ check(fn1, [int, int], [15, 10], 125)
Modified: pypy/dist/pypy/translator/c/funcgen.py
==============================================================================
--- pypy/dist/pypy/translator/c/funcgen.py (original)
+++ pypy/dist/pypy/translator/c/funcgen.py Tue Oct 4 23:53:06 2005
@@ -538,6 +538,9 @@
result.append(self.pyobj_incref(op.result))
return '\t'.join(result)
+ def OP_KEEPALIVE(self, op, err): # xxx what should be the sematics consequences of this
+ return "/* kept alive: %s */ ;" % ''.join([self.expr(v, special_case_void=False) for v in op.args])
+
def pyobj_incref(self, v):
T = self.lltypemap(v)
return self.pyobj_incref_expr(LOCALVAR % v.name, T)
Modified: pypy/dist/pypy/translator/c/test/test_genc.py
==============================================================================
--- pypy/dist/pypy/translator/c/test/test_genc.py (original)
+++ pypy/dist/pypy/translator/c/test/test_genc.py Tue Oct 4 23:53:06 2005
@@ -237,3 +237,15 @@
for i, s in enumerate(choices):
for j, c in enumerate(s):
assert f1(i, j) == c
+
+
+def test_keepalive():
+ from pypy.rpython import objectmodel
+ def f():
+ x = [1]
+ y = ['b']
+ objectmodel.keepalive(x,y)
+ return 1
+
+ f1 = compile(f, [])
+ assert f1() == 1
Modified: pypy/dist/pypy/translator/simplify.py
==============================================================================
--- pypy/dist/pypy/translator/simplify.py (original)
+++ pypy/dist/pypy/translator/simplify.py Tue Oct 4 23:53:06 2005
@@ -349,6 +349,7 @@
# decide whether a function has side effects
lloperations_with_side_effects = {"setfield": True,
"setarrayitem": True,
+ "keepalive": True,
}
class HasSideEffects(Exception):
More information about the Pypy-commit
mailing list