[pypy-commit] pypy dynamic-specialized-tuple: (fijal, alex): start on JIT support for untyped memory stuff

alex_gaynor noreply at buildbot.pypy.org
Wed Mar 14 06:02:19 CET 2012


Author: Alex Gaynor <alex.gaynor at gmail.com>
Branch: dynamic-specialized-tuple
Changeset: r53529:eddc1d03cf37
Date: 2012-03-13 22:01 -0700
http://bitbucket.org/pypy/pypy/changeset/eddc1d03cf37/

Log:	(fijal, alex): start on JIT support for untyped memory stuff

diff --git a/pypy/jit/backend/llgraph/runner.py b/pypy/jit/backend/llgraph/runner.py
--- a/pypy/jit/backend/llgraph/runner.py
+++ b/pypy/jit/backend/llgraph/runner.py
@@ -335,10 +335,14 @@
         return self.getdescr(ofs, token[0], name=fieldname)
 
     def interiorfielddescrof(self, A, fieldname):
-        S = A.OF
         width = symbolic.get_size(A)
-        ofs, size = symbolic.get_field_token(S, fieldname)
-        token = history.getkind(getattr(S, fieldname))
+        if isinstance(A, lltype.GcArray):
+            S = A.OF
+            ofs, size = symbolic.get_field_token(S, fieldname)
+            token = history.getkind(getattr(S, fieldname))
+        else:
+            ofs, size = symbolic.get_field_token(A, fieldname)
+            token = history.getkind(getattr(A, fieldname).OF)
         return self.getdescr(ofs, token[0], name=fieldname, width=width)
 
     def interiorfielddescrof_dynamic(self, offset, width, fieldsize,
diff --git a/pypy/jit/codewriter/jtransform.py b/pypy/jit/codewriter/jtransform.py
--- a/pypy/jit/codewriter/jtransform.py
+++ b/pypy/jit/codewriter/jtransform.py
@@ -462,6 +462,7 @@
     rewrite_op_ullong_mod_zer      = _do_builtin_call
     rewrite_op_gc_identityhash = _do_builtin_call
     rewrite_op_gc_id           = _do_builtin_call
+    rewrite_op_gc_writebarrier = _do_builtin_call
     rewrite_op_uint_mod        = _do_builtin_call
     rewrite_op_cast_float_to_uint = _do_builtin_call
     rewrite_op_cast_uint_to_float = _do_builtin_call
@@ -820,13 +821,14 @@
             return SpaceOperation(opname, [op.args[0], op.args[2], op.args[3]],
                                   op.result)
         else:
-            v_inst, v_index, c_field, v_value = op.args
+            v_inst = op.args[0]
+            v_value = op.args[3]
             if v_value.concretetype is lltype.Void:
                 return
-            # only GcArray of Struct supported
-            assert isinstance(v_inst.concretetype.TO, lltype.GcArray)
-            STRUCT = v_inst.concretetype.TO.OF
-            assert isinstance(STRUCT, lltype.Struct)
+            if isinstance(v_inst.concretetype.TO, lltype.GcArray):
+                v_inst, v_index, c_field, v_value = op.args
+            else:
+                v_inst, c_field, v_index, v_value = op.args
             descr = self.cpu.interiorfielddescrof(v_inst.concretetype.TO,
                                                   c_field.value)
             kind = getkind(v_value.concretetype)[0]
diff --git a/pypy/jit/codewriter/support.py b/pypy/jit/codewriter/support.py
--- a/pypy/jit/codewriter/support.py
+++ b/pypy/jit/codewriter/support.py
@@ -177,6 +177,9 @@
 def _ll_1_gc_identityhash(x):
     return lltype.identityhash(x)
 
+def _ll_2_gc_writebarrier(x, y):
+    llop.gc_writebarrier(lltype.Void, x, y)
+
 # the following function should not be "@elidable": I can think of
 # a corner case in which id(const) is constant-folded, and then 'const'
 # disappears and is collected too early (possibly causing another object
diff --git a/pypy/jit/codewriter/test/test_jtransform.py b/pypy/jit/codewriter/test/test_jtransform.py
--- a/pypy/jit/codewriter/test/test_jtransform.py
+++ b/pypy/jit/codewriter/test/test_jtransform.py
@@ -1218,3 +1218,17 @@
         tr.rewrite_operation(op)
     except Exception, e:
         assert 'foobar' in str(e)
+
+def test_interiorfield_struct():
+    S = lltype.GcStruct("S",
+        ("x", lltype.Signed),
+        ("data", lltype.Array(lltype.Signed)),
+    )
+    v = varoftype(lltype.Ptr(S))
+    c_data = Constant("data", lltype.Void)
+    op = SpaceOperation("setinteriorfield",
+        [v, c_data, const(0), const(1)], varoftype(lltype.Void)
+    )
+    op1 = Transformer(FakeCPU()).rewrite_operation(op)
+    assert op1.opname == "setinteriorfield_gc_i"
+    assert op1.args == [v, const(0), const(1), ('interiorfielddescr', S, "data")]
diff --git a/pypy/jit/metainterp/test/test_ajit.py b/pypy/jit/metainterp/test/test_ajit.py
--- a/pypy/jit/metainterp/test/test_ajit.py
+++ b/pypy/jit/metainterp/test/test_ajit.py
@@ -9,7 +9,7 @@
 from pypy.jit.metainterp.test.support import LLJitMixin, OOJitMixin, noConst
 from pypy.jit.metainterp.typesystem import LLTypeHelper, OOTypeHelper
 from pypy.jit.metainterp.warmspot import get_stats
-from pypy.rlib import rerased
+from pypy.rlib import rerased, rerased_raw
 from pypy.rlib.jit import (JitDriver, we_are_jitted, hint, dont_look_inside,
     loop_invariant, elidable, promote, jit_debug, assert_green,
     AssertGreenFailed, unroll_safe, current_trace_length, look_inside_iff,
@@ -292,7 +292,7 @@
         assert res == f(6, sys.maxint, 32, 48)
         res = self.meta_interp(f, [sys.maxint, 6, 32, 48])
         assert res == f(sys.maxint, 6, 32, 48)
-        
+
 
     def test_loop_invariant_intbox(self):
         myjitdriver = JitDriver(greens = [], reds = ['y', 'res', 'x'])
@@ -953,7 +953,7 @@
         self.meta_interp(f, [20], repeat=7)
         # the loop and the entry path as a single trace
         self.check_jitcell_token_count(1)
-        
+
         # we get:
         #    ENTER             - compile the new loop and the entry bridge
         #    ENTER             - compile the leaving path
@@ -1470,7 +1470,7 @@
         assert res == f(299)
         self.check_resops(guard_class=0, guard_nonnull=4,
                           guard_nonnull_class=4, guard_isnull=2)
-        
+
 
     def test_merge_guardnonnull_guardvalue(self):
         from pypy.rlib.objectmodel import instantiate
@@ -1499,7 +1499,7 @@
         assert res == f(299)
         self.check_resops(guard_value=4, guard_class=0, guard_nonnull=4,
                           guard_nonnull_class=0, guard_isnull=2)
-        
+
 
     def test_merge_guardnonnull_guardvalue_2(self):
         from pypy.rlib.objectmodel import instantiate
@@ -1528,7 +1528,7 @@
         assert res == f(299)
         self.check_resops(guard_value=4, guard_class=0, guard_nonnull=4,
                           guard_nonnull_class=0, guard_isnull=2)
-        
+
 
     def test_merge_guardnonnull_guardclass_guardvalue(self):
         from pypy.rlib.objectmodel import instantiate
@@ -2636,7 +2636,7 @@
             return sa
         assert self.meta_interp(f, [20]) == f(20)
         self.check_resops(int_lt=6, int_le=2, int_ge=4, int_gt=3)
-        
+
 
     def test_intbounds_not_generalized2(self):
         myjitdriver = JitDriver(greens = [], reds = ['n', 'i', 'sa', 'node'])
@@ -2677,7 +2677,7 @@
         assert self.meta_interp(f, [20, 3]) == f(20, 3)
         self.check_jitcell_token_count(1)
         self.check_target_token_count(5)
-        
+
     def test_max_retrace_guards(self):
         myjitdriver = JitDriver(greens = [], reds = ['n', 'i', 'sa', 'a'])
 
@@ -2815,7 +2815,7 @@
         for cell in get_stats().get_all_jitcell_tokens():
             # Initialal trace with two labels and 5 retraces
             assert len(cell.target_tokens) <= 7
-            
+
     def test_nested_retrace(self):
 
         myjitdriver = JitDriver(greens = ['pc'], reds = ['n', 'a', 'i', 'j', 'sa'])
@@ -3910,3 +3910,15 @@
             return 42
         self.interp_operations(f, [1, 2, 3])
         self.check_operations_history(call=1, guard_no_exception=0)
+
+    def test_untyped_storage(self):
+        class A(object):
+            def __init__(self, v):
+                self.v = v
+        def f(x):
+            storage = rerased_raw.UntypedStorage("io")
+            storage.setint(0, x)
+            storage.setinstance(1, A(x * 10))
+            return storage.getint(0) + storage.getinstance(1, A).v
+        res = self.interp_operations(f, [5])
+        assert res == 55
\ No newline at end of file


More information about the pypy-commit mailing list