[pypy-svn] r79311 - in pypy/trunk/pypy/jit: codewriter metainterp metainterp/test

arigo at codespeak.net arigo at codespeak.net
Sun Nov 21 16:45:31 CET 2010


Author: arigo
Date: Sun Nov 21 16:45:29 2010
New Revision: 79311

Modified:
   pypy/trunk/pypy/jit/codewriter/jtransform.py
   pypy/trunk/pypy/jit/metainterp/pyjitpl.py
   pypy/trunk/pypy/jit/metainterp/test/test_recursive.py
Log:
Minor bug and fix.


Modified: pypy/trunk/pypy/jit/codewriter/jtransform.py
==============================================================================
--- pypy/trunk/pypy/jit/codewriter/jtransform.py	(original)
+++ pypy/trunk/pypy/jit/codewriter/jtransform.py	Sun Nov 21 16:45:29 2010
@@ -843,9 +843,16 @@
             "general mix-up of jitdrivers?")
         ops = self.promote_greens(op.args[2:], jitdriver)
         num_green_args = len(jitdriver.greens)
+        redlists = self.make_three_lists(op.args[2+num_green_args:])
+        for redlist in redlists:
+            for v in redlist:
+                assert isinstance(v, Variable), (
+                    "Constant specified red in jit_merge_point()")
+            assert len(dict.fromkeys(redlist)) == len(list(redlist)), (
+                "duplicate red variable on jit_merge_point()")
         args = ([Constant(self.portal_jd.index, lltype.Signed)] +
                 self.make_three_lists(op.args[2:2+num_green_args]) +
-                self.make_three_lists(op.args[2+num_green_args:]))
+                redlists)
         op1 = SpaceOperation('jit_merge_point', args, None)
         op2 = SpaceOperation('-live-', [], None)
         # ^^^ we need a -live- for the case of do_recursive_call()

Modified: pypy/trunk/pypy/jit/metainterp/pyjitpl.py
==============================================================================
--- pypy/trunk/pypy/jit/metainterp/pyjitpl.py	(original)
+++ pypy/trunk/pypy/jit/metainterp/pyjitpl.py	Sun Nov 21 16:45:29 2010
@@ -94,6 +94,18 @@
             else: raise AssertionError(argcode)
             outvalue[startindex+i] = reg
 
+    def _put_back_list_of_boxes(self, outvalue, startindex, position):
+        code = self.bytecode
+        length = ord(code[position])
+        position += 1
+        for i in range(length):
+            index = ord(code[position+i])
+            box = outvalue[startindex+i]
+            if   box.type == history.INT:   self.registers_i[index] = box
+            elif box.type == history.REF:   self.registers_r[index] = box
+            elif box.type == history.FLOAT: self.registers_f[index] = box
+            else: raise AssertionError(box.type)
+
     def get_current_position_info(self):
         return self.jitcode.get_live_vars_info(self.pc)
 
@@ -814,8 +826,9 @@
         for i in range(num_green_args):
             assert isinstance(varargs[i], Const)
 
-    @arguments("orgpc", "int", "boxes3", "boxes3")
-    def opimpl_jit_merge_point(self, orgpc, jdindex, greenboxes, redboxes):
+    @arguments("orgpc", "int", "boxes3", "jitcode_position", "boxes3")
+    def opimpl_jit_merge_point(self, orgpc, jdindex, greenboxes,
+                               jcposition, redboxes):
         any_operation = len(self.metainterp.history.operations) > 0
         jitdriver_sd = self.metainterp.staticdata.jitdrivers_sd[jdindex]
         self.verify_green_args(jitdriver_sd, greenboxes)
@@ -843,6 +856,10 @@
             self.pc = orgpc
             self.metainterp.reached_loop_header(greenboxes, redboxes)
             self.pc = saved_pc
+            # no exception, which means that the jit_merge_point did not
+            # close the loop.  We have to put the possibly-modified list
+            # 'redboxes' back into the registers where it comes from.
+            put_back_list_of_boxes3(self, jcposition, redboxes)
         else:
             # warning! careful here.  We have to return from the current
             # frame containing the jit_merge_point, and then use
@@ -2293,6 +2310,8 @@
                 else:
                     raise AssertionError("bad argcode")
                 position += 1
+            elif argtype == "jitcode_position":
+                value = position
             else:
                 raise AssertionError("bad argtype: %r" % (argtype,))
             args += (value,)
@@ -2337,3 +2356,15 @@
     argtypes = unrolling_iterable(unboundmethod.argtypes)
     handler.func_name = 'handler_' + name
     return handler
+
+def put_back_list_of_boxes3(frame, position, newvalue):
+    code = frame.bytecode
+    length1 = ord(code[position])
+    position2 = position + 1 + length1
+    length2 = ord(code[position2])
+    position3 = position2 + 1 + length2
+    length3 = ord(code[position3])
+    assert len(newvalue) == length1 + length2 + length3
+    frame._put_back_list_of_boxes(newvalue, 0, position)
+    frame._put_back_list_of_boxes(newvalue, length1, position2)
+    frame._put_back_list_of_boxes(newvalue, length1 + length2, position3)

Modified: pypy/trunk/pypy/jit/metainterp/test/test_recursive.py
==============================================================================
--- pypy/trunk/pypy/jit/metainterp/test/test_recursive.py	(original)
+++ pypy/trunk/pypy/jit/metainterp/test/test_recursive.py	Sun Nov 21 16:45:29 2010
@@ -1142,6 +1142,19 @@
             res = self.meta_interp(main, [], inline=True, trace_limit=tlimit)
             assert ''.join(res.chars) == 'ABCDEFGHIabcdefghijJ' * 5
 
+    def test_no_duplicates_bug(self):
+        driver = JitDriver(greens = ['codeno'], reds = ['i'],
+                           get_printable_location = lambda codeno: str(codeno))
+        def portal(codeno, i):
+            while i > 0:
+                driver.can_enter_jit(codeno=codeno, i=i)
+                driver.jit_merge_point(codeno=codeno, i=i)
+                if codeno > 0:
+                    break
+                portal(i, i)
+                i -= 1
+        self.meta_interp(portal, [0, 10], inline=True)
+
 
 class TestLLtype(RecursiveTests, LLJitMixin):
     pass



More information about the Pypy-commit mailing list