[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