[pypy-commit] pypy jit-simplify-backendintf: Fixed virtualizables.

arigo noreply at buildbot.pypy.org
Sun Dec 11 21:57:57 CET 2011


Author: Armin Rigo <arigo at tunes.org>
Branch: jit-simplify-backendintf
Changeset: r50391:ab500e92817c
Date: 2011-12-11 21:05 +0100
http://bitbucket.org/pypy/pypy/changeset/ab500e92817c/

Log:	Fixed virtualizables.

diff --git a/pypy/jit/metainterp/compile.py b/pypy/jit/metainterp/compile.py
--- a/pypy/jit/metainterp/compile.py
+++ b/pypy/jit/metainterp/compile.py
@@ -11,7 +11,7 @@
 from pypy.jit.metainterp.resoperation import ResOperation, rop, get_deep_immutable_oplist
 from pypy.jit.metainterp.history import TreeLoop, Box, History, JitCellToken, TargetToken
 from pypy.jit.metainterp.history import AbstractFailDescr, BoxInt
-from pypy.jit.metainterp.history import BoxPtr, BoxObj, BoxFloat, Const
+from pypy.jit.metainterp.history import BoxPtr, BoxObj, BoxFloat, Const, ConstInt
 from pypy.jit.metainterp import history
 from pypy.jit.metainterp.typesystem import llhelper, oohelper
 from pypy.jit.metainterp.optimize import InvalidLoop
@@ -252,7 +252,44 @@
     record_loop_or_bridge(metainterp_sd, loop)
     return target_token
 
+def patch_new_loop_to_load_virtualizable_fields(loop, jitdriver_sd):
+    vinfo = jitdriver_sd.virtualizable_info
+    extra_ops = []
+    inputargs = loop.inputargs
+    vable_box = inputargs[jitdriver_sd.index_of_virtualizable]
+    i = jitdriver_sd.num_red_args
+    loop.inputargs = inputargs[:i]
+    for descr in vinfo.static_field_descrs:
+        assert i < len(inputargs)
+        box = inputargs[i]
+        extra_ops.append(
+            ResOperation(rop.GETFIELD_GC, [vable_box], box, descr))
+        i += 1
+    arrayindex = 0
+    for descr in vinfo.array_field_descrs:
+        vable = vable_box.getref_base()
+        arraylen = vinfo.get_array_length(vable, arrayindex)
+        arraybox = BoxPtr()
+        extra_ops.append(
+            ResOperation(rop.GETFIELD_GC, [vable_box], arraybox, descr))
+        arraydescr = vinfo.array_descrs[arrayindex]
+        assert i + arraylen <= len(inputargs)
+        for index in range(arraylen):
+            box = inputargs[i]
+            extra_ops.append(
+                ResOperation(rop.GETARRAYITEM_GC,
+                             [arraybox, ConstInt(index)],
+                             box, descr=arraydescr))
+            i += 1
+        arrayindex += 1
+    assert i == len(inputargs)
+    loop.operations = extra_ops + loop.operations
+
 def send_loop_to_backend(greenkey, jitdriver_sd, metainterp_sd, loop, type):
+    vinfo = jitdriver_sd.virtualizable_info
+    if vinfo is not None:
+        patch_new_loop_to_load_virtualizable_fields(loop, jitdriver_sd)
+
     original_jitcell_token = loop.original_jitcell_token
     jitdriver_sd.on_compile(metainterp_sd.logger_ops, original_jitcell_token,
                             loop.operations, type, greenkey)
@@ -776,6 +813,7 @@
     jitcell_token = make_jitcell_token(jitdriver_sd)
     # 'nb_red_args' might be smaller than len(redboxes),
     # because it doesn't include the virtualizable boxes.
+    XXX   # review and fix me :-)
     nb_red_args = jitdriver_sd.num_red_args
     k = jitdriver_sd.portal_runner_adr
     funcbox = history.ConstInt(heaptracker.adr2int(k))
diff --git a/pypy/jit/metainterp/pyjitpl.py b/pypy/jit/metainterp/pyjitpl.py
--- a/pypy/jit/metainterp/pyjitpl.py
+++ b/pypy/jit/metainterp/pyjitpl.py
@@ -2011,7 +2011,8 @@
         "NOT_RPYTHON"
         args = []
         num_green_args = self.jitdriver_sd.num_green_args
-        for box in live_arg_boxes[num_green_args:]:
+        num_red_args = self.jitdriver_sd.num_red_args
+        for box in live_arg_boxes[num_green_args:num_green_args+num_red_args]:
             if   box.type == history.INT: args.append(box.getint())
             elif box.type == history.REF: args.append(box.getref_base())
             elif box.type == history.FLOAT: args.append(box.getfloatstorage())
diff --git a/pypy/jit/metainterp/test/test_virtualizable.py b/pypy/jit/metainterp/test/test_virtualizable.py
--- a/pypy/jit/metainterp/test/test_virtualizable.py
+++ b/pypy/jit/metainterp/test/test_virtualizable.py
@@ -77,7 +77,7 @@
             return xy.inst_x
         res = self.meta_interp(f, [20])
         assert res == 30
-        self.check_resops(setfield_gc=0, getfield_gc=0)
+        self.check_simple_loop(setfield_gc=0, getfield_gc=0)
 
     def test_preexisting_access_2(self):
         myjitdriver = JitDriver(greens = [], reds = ['n', 'xy'],
@@ -102,7 +102,8 @@
         assert f(5) == 185
         res = self.meta_interp(f, [5])
         assert res == 185
-        self.check_resops(setfield_gc=0, getfield_gc=0)
+        self.check_resops(setfield_gc=0,
+                          getfield_gc=2)  # <= at the header of the loop
 
     def test_two_paths_access(self):
         myjitdriver = JitDriver(greens = [], reds = ['n', 'xy'],
@@ -124,7 +125,7 @@
             return xy.inst_x
         res = self.meta_interp(f, [18])
         assert res == 10118
-        self.check_resops(setfield_gc=0, getfield_gc=0)
+        self.check_resops(setfield_gc=0, getfield_gc=2)
 
     def test_synchronize_in_return(self):
         myjitdriver = JitDriver(greens = [], reds = ['n', 'xy'],
@@ -146,7 +147,7 @@
             return xy.inst_x
         res = self.meta_interp(f, [18])
         assert res == 10180
-        self.check_resops(setfield_gc=0, getfield_gc=0)
+        self.check_resops(setfield_gc=0, getfield_gc=2)
 
     def test_virtualizable_and_greens(self):
         myjitdriver = JitDriver(greens = ['m'], reds = ['n', 'xy'],
@@ -174,7 +175,7 @@
             return res
         res = self.meta_interp(f, [40])
         assert res == 50 * 4
-        self.check_resops(setfield_gc=0, getfield_gc=0)
+        self.check_resops(setfield_gc=0, getfield_gc=4)
 
     def test_double_frame(self):
         myjitdriver = JitDriver(greens = [], reds = ['n', 'xy', 'other'],
@@ -197,7 +198,8 @@
             return xy.inst_x
         res = self.meta_interp(f, [20])
         assert res == 134
-        self.check_resops(setfield_gc=2, getfield_gc=1)
+        self.check_simple_loop(setfield_gc=1, getfield_gc=0)
+        self.check_resops(setfield_gc=2, getfield_gc=3)
 
     # ------------------------------
 
@@ -247,8 +249,8 @@
             return xy2.inst_l1[2]
         res = self.meta_interp(f, [16])
         assert res == 3001 + 16 * 80
-        self.check_resops(setarrayitem_gc=0, setfield_gc=0,
-                          getarrayitem_gc=0, getfield_gc=0)
+        self.check_simple_loop(setarrayitem_gc=0, setfield_gc=0,
+                               getarrayitem_gc=0, getfield_gc=0)
 
     def test_synchronize_arrays_in_return(self):
         myjitdriver = JitDriver(greens = [], reds = ['n', 'xy2'],
@@ -278,7 +280,8 @@
         assert f(18) == 10360
         res = self.meta_interp(f, [18])
         assert res == 10360
-        self.check_resops(setfield_gc=0, getarrayitem_gc=0, getfield_gc=0)
+        self.check_simple_loop(setfield_gc=0, getarrayitem_gc=0,
+                               getfield_gc=0, setarrayitem_gc=0)
 
     def test_array_length(self):
         myjitdriver = JitDriver(greens = [], reds = ['n', 'xy2'],
@@ -304,8 +307,8 @@
             return xy2.inst_l1[1]
         res = self.meta_interp(f, [18])
         assert res == 2941309 + 18
-        self.check_resops(setfield_gc=0, getarrayitem_gc=0,
-                          arraylen_gc=0, getfield_gc=0)
+        self.check_simple_loop(setfield_gc=0, getarrayitem_gc=0,
+                               arraylen_gc=0, getfield_gc=0)
 
     def test_residual_function(self):
         myjitdriver = JitDriver(greens = [], reds = ['n', 'xy2'],
@@ -338,8 +341,8 @@
             return xy2.inst_l1[1]
         res = self.meta_interp(f, [18])
         assert res == 2941309 + 18
-        self.check_resops(call=2, setfield_gc=0, getarrayitem_gc=0,
-                          arraylen_gc=2, getfield_gc=0)
+        self.check_simple_loop(call=1, setfield_gc=0, getarrayitem_gc=0,
+                               arraylen_gc=1, getfield_gc=0)
 
     def test_double_frame_array(self):
         myjitdriver = JitDriver(greens = [], reds = ['n', 'xy2', 'other'],
@@ -375,8 +378,8 @@
         expected = f(20)
         res = self.meta_interp(f, [20], enable_opts='')
         assert res == expected
-        self.check_resops(setarrayitem_gc=1, setfield_gc=0,
-                          getarrayitem_gc=1, arraylen_gc=1, getfield_gc=1)
+        self.check_simple_loop(setarrayitem_gc=1, setfield_gc=0,
+                               getarrayitem_gc=1, arraylen_gc=1, getfield_gc=1)
 
     # ------------------------------
 
@@ -423,7 +426,8 @@
         assert f(18) == 10360
         res = self.meta_interp(f, [18])
         assert res == 10360
-        self.check_resops(setfield_gc=0, getarrayitem_gc=0, getfield_gc=0)
+        self.check_simple_loop(getfield_gc=0, getarrayitem_gc=0,
+                               setfield_gc=0, setarrayitem_gc=0)
 
     # ------------------------------
 
@@ -457,7 +461,7 @@
 
         res = self.meta_interp(f, [10])
         assert res == 55
-        self.check_resops(setfield_gc=0, getfield_gc=0)
+        self.check_simple_loop(setfield_gc=0, getfield_gc=0)
 
     def test_virtualizable_with_array(self):
         myjitdriver = JitDriver(greens = [], reds = ['n', 'x', 'frame'],
@@ -491,7 +495,8 @@
 
         res = self.meta_interp(f, [10, 1], listops=True)
         assert res == f(10, 1)
-        self.check_resops(getarrayitem_gc=0)
+        self.check_simple_loop(getfield_gc=0, getarrayitem_gc=0)
+        self.check_resops(getfield_gc=2, getarrayitem_gc=4)
 
     def test_subclass_of_virtualizable(self):
         myjitdriver = JitDriver(greens = [], reds = ['frame'],
@@ -519,7 +524,7 @@
 
         res = self.meta_interp(f, [10])
         assert res == 55
-        self.check_resops(setfield_gc=0, getfield_gc=0)
+        self.check_simple_loop(setfield_gc=0, getfield_gc=0)
 
     def test_external_pass(self):
         jitdriver = JitDriver(greens = [], reds = ['n', 'z', 'frame'],
@@ -1037,7 +1042,7 @@
 
         res = self.meta_interp(f, [10])
         assert res == 55
-        self.check_resops(setfield_gc=0, getfield_gc=0)
+        self.check_simple_loop(setfield_gc=0, getfield_gc=0)
 
         from pypy.jit.backend.test.support import BaseCompiledMixin
         if isinstance(self, BaseCompiledMixin):
@@ -1197,7 +1202,8 @@
 
         res = self.meta_interp(f, [10])
         assert res == 155
-        self.check_resops(setfield_gc=0, getfield_gc=0)
+        self.check_simple_loop(setfield_gc=0, getfield_gc=0)
+        self.check_resops(setfield_gc=0, getfield_gc=2)
 
     def test_blackhole_should_synchronize(self):
         myjitdriver = JitDriver(greens = [], reds = ['frame'],
@@ -1233,7 +1239,8 @@
 
         res = self.meta_interp(f, [10])
         assert res == 155
-        self.check_resops(setfield_gc=0, getfield_gc=0)
+        self.check_simple_loop(setfield_gc=0, getfield_gc=0)
+        self.check_resops(setfield_gc=0, getfield_gc=2)
 
     def test_blackhole_should_not_reenter(self):
         if not self.basic:
diff --git a/pypy/jit/metainterp/warmstate.py b/pypy/jit/metainterp/warmstate.py
--- a/pypy/jit/metainterp/warmstate.py
+++ b/pypy/jit/metainterp/warmstate.py
@@ -296,7 +296,7 @@
             # 'vable_token' field afterwards
             if vinfo is not None:
                 virtualizable = args[index_of_virtualizable]
-                virtualizable = vinfo.cast_to_vtype(virtualizable)
+                virtualizable = vinfo.cast_gcref_to_vtype(virtualizable)
                 vinfo.reset_vable_token(virtualizable)
             #
             # Record in the memmgr that we just ran this loop,


More information about the pypy-commit mailing list