[pypy-svn] r69050 - in pypy/trunk/pypy/jit: backend/test metainterp metainterp/test

arigo at codespeak.net arigo at codespeak.net
Sat Nov 7 17:12:58 CET 2009


Author: arigo
Date: Sat Nov  7 17:12:57 2009
New Revision: 69050

Modified:
   pypy/trunk/pypy/jit/backend/test/runner_test.py
   pypy/trunk/pypy/jit/backend/test/test_random.py
   pypy/trunk/pypy/jit/metainterp/pyjitpl.py
   pypy/trunk/pypy/jit/metainterp/resoperation.py
   pypy/trunk/pypy/jit/metainterp/test/test_pyjitpl.py
Log:
Fix for reached_can_enter_jit: check for duplicate boxes
and remove them.  Fixes a rare crash in the nightly run
of pypy-c-jit.


Modified: pypy/trunk/pypy/jit/backend/test/runner_test.py
==============================================================================
--- pypy/trunk/pypy/jit/backend/test/runner_test.py	(original)
+++ pypy/trunk/pypy/jit/backend/test/runner_test.py	Sat Nov  7 17:12:57 2009
@@ -673,13 +673,19 @@
     def test_same_as(self):
         r = self.execute_operation(rop.SAME_AS, [ConstInt(5)], 'int')
         assert r.value == 5
+        r = self.execute_operation(rop.SAME_AS, [BoxInt(5)], 'int')
+        assert r.value == 5
         u_box = self.alloc_unicode(u"hello\u1234")
         r = self.execute_operation(rop.SAME_AS, [u_box.constbox()], 'ref')
         assert r.value == u_box.value
+        r = self.execute_operation(rop.SAME_AS, [u_box], 'ref')
+        assert r.value == u_box.value
 
         if self.cpu.supports_floats:
             r = self.execute_operation(rop.SAME_AS, [ConstFloat(5.5)], 'float')
             assert r.value == 5.5
+            r = self.execute_operation(rop.SAME_AS, [BoxFloat(5.5)], 'float')
+            assert r.value == 5.5
 
     def test_jump(self):
         # this test generates small loops where the JUMP passes many

Modified: pypy/trunk/pypy/jit/backend/test/test_random.py
==============================================================================
--- pypy/trunk/pypy/jit/backend/test/test_random.py	(original)
+++ pypy/trunk/pypy/jit/backend/test/test_random.py	Sat Nov  7 17:12:57 2009
@@ -246,7 +246,9 @@
 
 class ConstUnaryOperation(UnaryOperation):
     def produce_into(self, builder, r):
-        if r.random() < 0.75 or not builder.cpu.supports_floats:
+        if r.random() < 0.4:
+            UnaryOperation.produce_into(self, builder, r)
+        elif r.random() < 0.75 or not builder.cpu.supports_floats:
             self.put(builder, [ConstInt(r.random_integer())])
         else:
             self.put(builder, [ConstFloat(r.random_float())])

Modified: pypy/trunk/pypy/jit/metainterp/pyjitpl.py
==============================================================================
--- pypy/trunk/pypy/jit/metainterp/pyjitpl.py	(original)
+++ pypy/trunk/pypy/jit/metainterp/pyjitpl.py	Sat Nov  7 17:12:57 2009
@@ -1442,22 +1442,33 @@
                 warmrunnerstate.reset_counter_from_failure(key, self)
             raise
 
-    def forget_consts(self, boxes, startindex=0):
-        for i in range(startindex, len(boxes)):
+    def remove_consts_and_duplicates(self, boxes, startindex, endindex,
+                                     duplicates):
+        for i in range(startindex, endindex):
             box = boxes[i]
-            if isinstance(box, Const):
-                constbox = box
-                box = constbox.clonebox()
+            if isinstance(box, Const) or box in duplicates:
+                oldbox = box
+                box = oldbox.clonebox()
                 boxes[i] = box
-                self.history.record(rop.SAME_AS, [constbox], box)
+                self.history.record(rop.SAME_AS, [oldbox], box)
+            else:
+                duplicates[box] = None
 
     def reached_can_enter_jit(self, live_arg_boxes):
-        self.forget_consts(live_arg_boxes, self.staticdata.num_green_args)
+        num_green_args = self.staticdata.num_green_args
+        duplicates = {}
+        self.remove_consts_and_duplicates(live_arg_boxes,
+                                          num_green_args,
+                                          len(live_arg_boxes),
+                                          duplicates)
         live_arg_boxes = live_arg_boxes[:]
         if self.staticdata.virtualizable_info is not None:
             # we use ':-1' to remove the last item, which is the virtualizable
             # itself
-            self.forget_consts(self.virtualizable_boxes)
+            self.remove_consts_and_duplicates(self.virtualizable_boxes,
+                                              0,
+                                              len(self.virtualizable_boxes)-1,
+                                              duplicates)
             live_arg_boxes += self.virtualizable_boxes[:-1]
         # Called whenever we reach the 'can_enter_jit' hint.
         # First, attempt to make a bridge:

Modified: pypy/trunk/pypy/jit/metainterp/resoperation.py
==============================================================================
--- pypy/trunk/pypy/jit/metainterp/resoperation.py	(original)
+++ pypy/trunk/pypy/jit/metainterp/resoperation.py	Sat Nov  7 17:12:57 2009
@@ -165,7 +165,7 @@
     'INT_INVERT/1',
     'BOOL_NOT/1',
     #
-    'SAME_AS/1',      # gets a Const, turns it into a Box
+    'SAME_AS/1',      # gets a Const or a Box, turns it into another Box
     #
     'OONONNULL/1',
     'OOISNULL/1',

Modified: pypy/trunk/pypy/jit/metainterp/test/test_pyjitpl.py
==============================================================================
--- pypy/trunk/pypy/jit/metainterp/test/test_pyjitpl.py	(original)
+++ pypy/trunk/pypy/jit/metainterp/test/test_pyjitpl.py	Sat Nov  7 17:12:57 2009
@@ -2,7 +2,10 @@
 # some unit tests for the bytecode decoding
 
 from pypy.jit.metainterp import pyjitpl, codewriter, resoperation
-from pypy.jit.metainterp.history import AbstractFailDescr
+from pypy.jit.metainterp.history import AbstractFailDescr, BoxInt, ConstInt
+from pypy.jit.metainterp.history import History
+from pypy.jit.metainterp.resoperation import ResOperation, rop
+from pypy.jit.metainterp.test.test_optimizeopt import equaloplists
 
 def make_frame(code):
     bytecode = codewriter.JitCode("hello")
@@ -103,3 +106,39 @@
 
     history.operations.extend([9, 10, 11, 12])
     assert metainterp.find_biggest_function() == "green3"
+
+def test_remove_consts_and_duplicates():
+    class FakeStaticData:
+        cpu = None
+    def is_another_box_like(box, referencebox):
+        assert box is not referencebox
+        assert isinstance(box, referencebox.clonebox().__class__)
+        assert box.value == referencebox.value
+        return True
+    metainterp = pyjitpl.MetaInterp(FakeStaticData())
+    metainterp.history = History(None)
+    b1 = BoxInt(1)
+    b2 = BoxInt(2)
+    c3 = ConstInt(3)
+    boxes = [b1, b2, b1, c3]
+    dup = {}
+    metainterp.remove_consts_and_duplicates(boxes, 0, 4, dup)
+    assert boxes[0] is b1
+    assert boxes[1] is b2
+    assert is_another_box_like(boxes[2], b1)
+    assert is_another_box_like(boxes[3], c3)
+    assert equaloplists(metainterp.history.operations, [
+        ResOperation(rop.SAME_AS, [b1], boxes[2]),
+        ResOperation(rop.SAME_AS, [c3], boxes[3]),
+        ])
+    assert dup == {b1: None, b2: None}
+    #
+    del metainterp.history.operations[:]
+    b4 = BoxInt(4)
+    boxes = ["something random", b2, b4, "something else"]
+    metainterp.remove_consts_and_duplicates(boxes, 1, 3, dup)
+    assert is_another_box_like(boxes[1], b2)
+    assert boxes[2] is b4
+    assert equaloplists(metainterp.history.operations, [
+        ResOperation(rop.SAME_AS, [b2], boxes[1]),
+        ])



More information about the Pypy-commit mailing list