[pypy-svn] r62577 - in pypy/branch/pyjitpl5/pypy/jit/metainterp: . test

arigo at codespeak.net arigo at codespeak.net
Thu Mar 5 14:04:02 CET 2009


Author: arigo
Date: Thu Mar  5 14:04:00 2009
New Revision: 62577

Modified:
   pypy/branch/pyjitpl5/pypy/jit/metainterp/codewriter.py
   pypy/branch/pyjitpl5/pypy/jit/metainterp/history.py
   pypy/branch/pyjitpl5/pypy/jit/metainterp/optimize.py
   pypy/branch/pyjitpl5/pypy/jit/metainterp/pyjitpl.py
   pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimize.py
Log:
Move the actual execution of an operation out of the class History
and into the class OOMetaInterp.  Note that now execute_and_record()
can be specialized according to the operation it runs.


Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/codewriter.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/metainterp/codewriter.py	(original)
+++ pypy/branch/pyjitpl5/pypy/jit/metainterp/codewriter.py	Thu Mar  5 14:04:00 2009
@@ -709,7 +709,7 @@
 ##                self._eventualy_builtin(op.result, False)
 ##            return
         if oopspec_name.endswith('_foldable'):
-            opname = 'residual_call_pure'
+            opname = 'residual_call_pure'  # XXX not for possibly-raising calls
         else:
             opname = 'residual_call'
         calldescr = self.cpu.calldescrof(argtypes, resulttype)

Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/history.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/metainterp/history.py	(original)
+++ pypy/branch/pyjitpl5/pypy/jit/metainterp/history.py	Thu Mar  5 14:04:00 2009
@@ -324,12 +324,12 @@
         op = operations[0]
         assert op.opnum in (rop.MERGE_POINT, rop.CATCH)
         seen = dict.fromkeys(op.args)
-        for op in operations[1:]:
+        for op in operations:
             for box in op.args:
                 if isinstance(box, Box):
                     assert box in seen
                 elif isinstance(box, Const):
-                    assert op.opnum not in (rop.MERGE_POINT, rop.CATCH), (
+                    assert op.opnum != rop.MERGE_POINT, (
                         "no Constant arguments allowed in: %s" % (op,))
             box = op.result
             if box is not None:
@@ -348,49 +348,21 @@
 class Matcher(object):
     pass
 
-
 class RunningMatcher(Matcher):
-
     def __init__(self, cpu):
         self.cpu = cpu
         self.operations = []
 
-    def execute_and_record(self, opnum, argboxes, result_type):
-        # collect arguments
-        canfold = False
-        if rop._ALWAYS_PURE_FIRST <= opnum <= rop._ALWAYS_PURE_LAST:
-            for box in argboxes:
-                if not isinstance(box, Const):
-                    break
-            else:
-                canfold = True
-        # really run this operation
-        resbox = self.cpu.execute_operation(opnum, argboxes, result_type)
-        # collect the result(s)
-        if canfold:
-            resbox = resbox.constbox()
-        else:
-            self.record(opnum, argboxes, resbox)
-        return resbox
-
+class History(RunningMatcher):
     def record(self, opnum, argboxes, resbox):
         op = ResOperation(opnum, argboxes, resbox)
         self.operations.append(op)
         return op
 
-    def generate_anything_since(self, old_index):
-        return len(self.operations) > old_index
-
-class History(RunningMatcher):
-    pass
-
 class BlackHole(RunningMatcher):
-    def record(self, step, argboxes, resbox):
+    def record(self, opnum, argboxes, resbox):
         return None
 
-    def generate_anything_since(self, old_index):
-        return True
-
 def mp_eq(greenkey1, greenkey2):
     assert len(greenkey1) == len(greenkey2)
     for i in range(len(greenkey1)):

Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/optimize.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/metainterp/optimize.py	(original)
+++ pypy/branch/pyjitpl5/pypy/jit/metainterp/optimize.py	Thu Mar  5 14:04:00 2009
@@ -1013,7 +1013,6 @@
     allocated_boxes = []
     allocated_lists = []
     storage = guard_op.storage_info
-    history = metainterp.history
 
     for vtable in storage.allocations:
         if metainterp.cpu.translate_support_code:
@@ -1022,15 +1021,15 @@
         else:
             sizebox = ConstInt(metainterp.class_sizes[vtable])
         vtablebox = ConstInt(vtable)
-        instbox = history.execute_and_record(rop.NEW_WITH_VTABLE,
-                                             [sizebox, vtablebox],
-                                             'ptr')
+        instbox = metainterp.execute_and_record(rop.NEW_WITH_VTABLE,
+                                                [sizebox, vtablebox],
+                                                'ptr')
         allocated_boxes.append(instbox)
     for ad, lgt in storage.list_allocations:
         sizebox = ConstInt(lgt)
-        listbox = history.execute_and_record(rop.NEW_ARRAY,
-                                               [ad, sizebox],
-                                               'ptr')
+        listbox = metainterp.execute_and_record(rop.NEW_ARRAY,
+                                                [ad, sizebox],
+                                                'ptr')
         allocated_lists.append(listbox)
     for index_in_alloc, ofs, index_in_arglist in storage.setfields:
         fieldbox = box_from_index(allocated_boxes, allocated_lists,
@@ -1038,17 +1037,17 @@
         box = box_from_index(allocated_boxes, allocated_lists,
                              boxes_from_frame,
                              index_in_alloc)
-        history.execute_and_record(rop.SETFIELD_GC,
-                                   [box, ConstInt(ofs), fieldbox],
-                                   'void')
+        metainterp.execute_and_record(rop.SETFIELD_GC,
+                                      [box, ConstInt(ofs), fieldbox],
+                                      'void')
     for index_in_alloc, ad, ofs, index_in_arglist in storage.setitems:
         itembox = box_from_index(allocated_boxes, allocated_lists,
                                  boxes_from_frame, index_in_arglist)
         box = box_from_index(allocated_boxes, allocated_lists,
                              boxes_from_frame, index_in_alloc)
-        history.execute_and_record(rop.SETARRAYITEM_GC,
-                                   [box, ad, ConstInt(ofs), itembox],
-                                   'void')
+        metainterp.execute_and_record(rop.SETARRAYITEM_GC,
+                                      [box, ad, ConstInt(ofs), itembox],
+                                      'void')
 ##    if storage.setitems:
 ##        #history.execute_and_record('guard_no_exception', [], 'void', False)
 ##        # XXX this needs to check for exceptions somehow

Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/pyjitpl.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/metainterp/pyjitpl.py	(original)
+++ pypy/branch/pyjitpl5/pypy/jit/metainterp/pyjitpl.py	Thu Mar  5 14:04:00 2009
@@ -344,14 +344,14 @@
 
     @arguments("orgpc", "box", "constbox", "box")
     def opimpl_check_neg_index(self, pc, arraybox, arraydesc, indexbox):
-        negbox = self.metainterp.history.execute_and_record(
+        negbox = self.metainterp.execute_and_record(
             rop.INT_LT, [indexbox, ConstInt(0)], 'int')
         negbox = self.implement_guard_value(pc, negbox)
         if negbox.getint():
             # the index is < 0; add the array length to it
-            lenbox = self.metainterp.history.execute_and_record(
+            lenbox = self.metainterp.execute_and_record(
                 rop.ARRAYLEN_GC, [arraybox, arraydesc], 'int')
-            indexbox = self.metainterp.history.execute_and_record(
+            indexbox = self.metainterp.execute_and_record(
                 rop.INT_ADD, [indexbox, lenbox], 'int')
         self.make_result_box(indexbox)
 
@@ -414,7 +414,7 @@
     def opimpl_residual_call_pure(self, funcbox, calldescr, varargs):
         tp = self.metainterp.cpu.typefor(calldescr.getint())
         args = [funcbox, calldescr] + varargs
-        return self.execute_with_exc(rop.CALL_PURE, args, tp)
+        self.execute(rop.CALL_PURE, args, tp)
 
 ##    @arguments("fixedlist", "box", "box")
 ##    def opimpl_list_getitem(self, descr, listbox, indexbox):
@@ -654,15 +654,17 @@
         return ConstInt(self.metainterp.cpu.cast_adr_to_int(cls))
 
     def execute(self, opnum, argboxes, result_type):
-        resbox = self.metainterp.history.execute_and_record(opnum, argboxes,
-                                                            result_type)
+        resbox = self.metainterp.execute_and_record(opnum, argboxes,
+                                                    result_type)
         if resbox is not None:
             self.make_result_box(resbox)
+    execute._annspecialcase_ = 'specialize:arg(1)'
 
     def execute_with_exc(self, opnum, argboxes, result_type):
         old_index = len(self.metainterp.history.operations)
         try:
-            self.execute(opnum, argboxes, result_type)
+            resbox = self.metainterp.cpu.execute_operation(opnum, argboxes,
+                                                           result_type)
         except Exception, e:
             if not we_are_translated():
                 if not isinstance(e, LLException):
@@ -672,23 +674,22 @@
                 evalue = cast_instance_to_base_ptr(e)
                 etype = evalue.typeptr
             if result_type == 'void':
-                resultbox = None
+                resbox = None
             else:
                 if result_type == 'ptr':
-                    resultbox = BoxPtr()
+                    resbox = BoxPtr()
                 else:
-                    resultbox = BoxInt()
-                self.make_result_box(resultbox)
-            self.metainterp.history.record(opnum, argboxes, resultbox)
+                    resbox = BoxInt()
         else:
-            if not self.metainterp.history.generate_anything_since(old_index):
-                assert rop._ALWAYS_PURE_FIRST <= opnum <= rop._ALWAYS_PURE_LAST
-                return False
             if not we_are_translated():
                 self.metainterp._debug_history.append(['call',
                                                   argboxes[0], argboxes[1:]])
             etype = lltype.nullptr(rclass.OBJECT_VTABLE)
             evalue = lltype.nullptr(rclass.OBJECT)
+        # record the operation in the history
+        self.metainterp.history.record(opnum, argboxes, resbox)
+        if resbox is not None:
+            self.make_result_box(resbox)
         type_as_int = self.metainterp.cpu.cast_adr_to_int(
             llmemory.cast_ptr_to_adr(etype))
         value_as_gcref = lltype.cast_opaque_ptr(llmemory.GCREF, evalue)
@@ -767,6 +768,30 @@
         self.history = None
         self.framestack = None
 
+    def _all_constants(self, boxes):
+        for box in boxes:
+            if not isinstance(box, Const):
+                return False
+        return True
+
+    def execute_and_record(self, opnum, argboxes, result_type):
+        # execute the operation first
+        resbox = self.cpu.execute_operation(opnum, argboxes, result_type)
+        # check if the operation can be constant-folded away
+        canfold = False
+        if rop._ALWAYS_PURE_FIRST <= opnum <= rop._ALWAYS_PURE_LAST:
+            # this part disappears if execute() is specialized for an
+            # opnum that is not within the range
+            assert resbox is not None
+            canfold = self._all_constants(argboxes)
+            if canfold:
+                resbox = resbox.constbox()
+        # record the operation if not constant-folded away
+        if not canfold:
+            self.history.record(opnum, argboxes, resbox)
+        return resbox
+    execute_and_record._annspecialcase_ = 'specialize:arg(1)'
+
     def interpret(self):
         # Execute the frames forward until we raise a DoneWithThisFrame,
         # a ContinueRunningNormally, or a GenerateMergePoint exception.

Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimize.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimize.py	(original)
+++ pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimize.py	Thu Mar  5 14:04:00 2009
@@ -319,8 +319,12 @@
     assert guard_op.storage_info.setfields == [(0, E.ofs_value, -2)]
 
 def test_E_rebuild_after_failure():
-    class FakeHistory(object):
+    class FakeMetaInterp(object):
         def __init__(self):
+            self.class_sizes = {cpu.cast_adr_to_int(node_vtable_adr):
+                                E.size_of_node}
+            self.cpu = cpu
+            self.cpu.translate_support_code = False
             self.ops = []
         
         def execute_and_record(self, opnum, args, res_type):
@@ -329,14 +333,6 @@
                 return 'allocated'
             else:
                 return None
-
-    class FakeMetaInterp(object):
-        def __init__(self):
-            self.history = FakeHistory()
-            self.class_sizes = {cpu.cast_adr_to_int(node_vtable_adr):
-                                E.size_of_node}
-            self.cpu = cpu
-            self.cpu.translate_support_code = False
     
     spec = PerfectSpecializer(Loop(E.ops))
     spec.find_nodes()
@@ -353,7 +349,7 @@
        (rop.NEW_WITH_VTABLE, [E.sizebox, ConstInt(vt)]),
        (rop.SETFIELD_GC, ['allocated', ConstInt(E.ofs_value), v_v_b])
        ]
-    assert expected == fake_metainterp.history.ops
+    assert expected == fake_metainterp.ops
     assert newboxes == [v_sum_b, 'allocated']
 
 # ____________________________________________________________



More information about the Pypy-commit mailing list