[pypy-svn] r66502 - pypy/branch/pyjitpl5-optimize4/pypy/jit/metainterp

arigo at codespeak.net arigo at codespeak.net
Wed Jul 22 11:33:33 CEST 2009


Author: arigo
Date: Wed Jul 22 11:33:31 2009
New Revision: 66502

Added:
   pypy/branch/pyjitpl5-optimize4/pypy/jit/metainterp/resume.py   (contents, props changed)
Modified:
   pypy/branch/pyjitpl5-optimize4/pypy/jit/metainterp/compile.py
   pypy/branch/pyjitpl5-optimize4/pypy/jit/metainterp/pyjitpl.py
Log:
Move encoding and decoding of the frames and boxes at a FAIL in its own
file.  Will then add tests and direct support for virtuals.


Modified: pypy/branch/pyjitpl5-optimize4/pypy/jit/metainterp/compile.py
==============================================================================
--- pypy/branch/pyjitpl5-optimize4/pypy/jit/metainterp/compile.py	(original)
+++ pypy/branch/pyjitpl5-optimize4/pypy/jit/metainterp/compile.py	Wed Jul 22 11:33:31 2009
@@ -242,15 +242,13 @@
 
 
 class ResumeGuardDescr(AbstractDescr):
-    def __init__(self, resume_info, vable_nums, consts,
-                 history, history_guard_index):
-        self.resume_info = resume_info
-        self.vable_nums = vable_nums      # None if no virtualizable
-        self.counter = 0
+    counter = 0
+
+    def __init__(self, history, history_guard_index):
         self.history = history
         assert history_guard_index >= 0
         self.history_guard_index = history_guard_index
-        self.consts = consts
+        # this class also gets attributes stored by ResumeDataBuilder.finish()
 
     def handle_fail_op(self, metainterp_sd, fail_op):
         from pypy.jit.metainterp.pyjitpl import MetaInterp

Modified: pypy/branch/pyjitpl5-optimize4/pypy/jit/metainterp/pyjitpl.py
==============================================================================
--- pypy/branch/pyjitpl5-optimize4/pypy/jit/metainterp/pyjitpl.py	(original)
+++ pypy/branch/pyjitpl5-optimize4/pypy/jit/metainterp/pyjitpl.py	Wed Jul 22 11:33:31 2009
@@ -4,7 +4,7 @@
 from pypy.rlib.unroll import unrolling_iterable
 from pypy.rlib.debug import debug_print
 
-from pypy.jit.metainterp import history, compile
+from pypy.jit.metainterp import history, compile, resume
 from pypy.jit.metainterp.history import Const, ConstInt, Box
 from pypy.jit.metainterp.resoperation import rop
 from pypy.jit.metainterp.heaptracker import populate_type_cache
@@ -832,13 +832,12 @@
         if not we_are_translated():
             self.metainterp._debug_history[-1][-1] = argboxes
 
-    def setup_resume_at_op(self, pc, nums, consts, liveboxes,
-                           exception_target):
+    def setup_resume_at_op(self, pc, exception_target, env):
         if not we_are_translated():
-            check_args(*liveboxes)
+            check_args(*env)
         self.pc = pc
         self.exception_target = exception_target
-        self.env = _consume_nums(nums, liveboxes, consts)
+        self.env = env
         if DEBUG >= 2:
             values = ' '.join([box.repr_rpython() for box in self.env])
             log('setup_resume_at_op  %s:%d [%s] %d' % (self.jitcode.name,
@@ -869,28 +868,21 @@
             return
         saved_pc = self.pc
         self.pc = pc
-        # XXX 'resume_info' should be shared, either partially or
-        #     if possible totally
-        resume_info = []
-        liveboxes = []
-        consts = []
-        memo = {}
-        if metainterp.staticdata.virtualizable_info is None:
-            vable_nums = None
-        else:
-            vable_nums = _generate_nums(metainterp.virtualizable_boxes,
-                                        memo, liveboxes, consts)
+        resumebuilder = resume.ResumeDataBuilder()
+        if metainterp.staticdata.virtualizable_info is not None:
+            resumebuilder.generate_boxes(metainterp.virtualizable_boxes)
         for frame in metainterp.framestack:
-            nums = _generate_nums(frame.env, memo, liveboxes, consts)
-            resume_info.append((frame.jitcode, frame.pc, nums,
-                                frame.exception_target))
+            resumebuilder.generate_frame_info(frame.jitcode, frame.pc,
+                                              frame.exception_target)
+            resumebuilder.generate_boxes(frame.env)
         if box is not None:
             moreargs = [box] + extraargs
         else:
             moreargs = list(extraargs)
         guard_op = metainterp.history.record(opnum, moreargs, None)
-        resumedescr = compile.ResumeGuardDescr(resume_info, vable_nums, consts,
+        resumedescr = compile.ResumeGuardDescr(
             metainterp.history, len(metainterp.history.operations)-1)
+        liveboxes = resumebuilder.finish(resumedescr)
         op = history.ResOperation(rop.FAIL, liveboxes, None, descr=resumedescr)
         guard_op.suboperations = [op]
         self.pc = saved_pc
@@ -924,35 +916,6 @@
 
 # ____________________________________________________________
 
-def _generate_nums(frameboxes, memo, liveboxes, consts):
-    nums = []
-    for framebox in frameboxes:
-        assert framebox is not None
-        if isinstance(framebox, Box):
-            try:
-                num = memo[framebox]
-            except KeyError:
-                num = len(liveboxes)
-                memo[framebox] = num
-                liveboxes.append(framebox)
-        else:
-            num = ~len(consts)
-            consts.append(framebox)
-        nums.append(num)
-    return nums
-
-def _consume_nums(nums, liveboxes, consts):
-    env = []
-    for num in nums:
-        if num >= 0:
-            box = liveboxes[num]
-        else:
-            box = consts[~num]
-        env.append(box)
-    return env
-
-# ____________________________________________________________
-
 class MetaInterpStaticData(object):
     virtualizable_info = None
 
@@ -1476,10 +1439,7 @@
             self.history = history.BlackHole(self.cpu)
             # the BlackHole is invalid because it doesn't start with
             # guard_failure.key.guard_op.suboperations, but that's fine
-        self.rebuild_state_after_failure(resumedescr.resume_info,
-                                         resumedescr.vable_nums,
-                                         resumedescr.consts,
-                                         guard_failure.args)
+        self.rebuild_state_after_failure(resumedescr, guard_failure.args)
 
     def initialize_virtualizable(self, original_boxes):
         vinfo = self.staticdata.virtualizable_info
@@ -1548,14 +1508,13 @@
             frame.generate_guard(frame.pc, rop.GUARD_NO_EXCEPTION, None, [])
             return False
 
-    def rebuild_state_after_failure(self, resume_info, vable_nums, consts,
-                                    newboxes):
+    def rebuild_state_after_failure(self, resumedescr, newboxes):
         if not we_are_translated():
             self._debug_history.append(['guard_failure', None, None])
         vinfo = self.staticdata.virtualizable_info
+        resumereader = resume.ResumeDataReader(resumedescr, newboxes)
         if vinfo is not None:
-            self.virtualizable_boxes = _consume_nums(vable_nums,
-                                                     newboxes, consts)
+            self.virtualizable_boxes = resumereader.consume_boxes()
             # just jumped away from assembler (case 4 in the comment in
             # virtualizable.py) into tracing (case 2); check that vable_rti
             # is and stays NULL.
@@ -1565,10 +1524,11 @@
             self.synchronize_virtualizable()
             #
         self.framestack = []
-        for jitcode, pc, nums, exception_target in resume_info:
+        while resumereader.has_more_frame_infos():
+            jitcode, pc, exception_target = resumereader.consume_frame_info()
+            env = resumereader.consume_boxes()
             f = self.newframe(jitcode)
-            f.setup_resume_at_op(pc, nums, consts, newboxes,
-                                           exception_target)
+            f.setup_resume_at_op(pc, exception_target, env)
 
     def check_synchronized_virtualizable(self):
         if not we_are_translated():

Added: pypy/branch/pyjitpl5-optimize4/pypy/jit/metainterp/resume.py
==============================================================================
--- (empty file)
+++ pypy/branch/pyjitpl5-optimize4/pypy/jit/metainterp/resume.py	Wed Jul 22 11:33:31 2009
@@ -0,0 +1,77 @@
+from pypy.jit.metainterp.history import Box
+
+# Logic to encode the chain of frames and the state of the boxes at a
+# FAIL operation, and to decode it again.  This is a bit advanced,
+# because it needs to support optimize.py which encodes virtuals with
+# arbitrary cycles.
+
+# XXX I guess that building the data so that it is compact as possible
+# would be a big win.
+
+
+class ResumeDataBuilder(object):
+
+    def __init__(self):
+        self.memo = {}
+        self.liveboxes = []
+        self.consts = []
+        self.nums = []
+        self.frame_infos = []
+
+    def generate_boxes(self, boxes):
+        for box in boxes:
+            assert box is not None
+            if isinstance(box, Box):
+                try:
+                    num = self.memo[box]
+                except KeyError:
+                    num = len(self.liveboxes)
+                    self.liveboxes.append(box)
+                    self.memo[box] = num
+            else:
+                num = -2 - len(self.consts)
+                self.consts.append(box)
+            self.nums.append(num)
+        self.nums.append(-1)
+
+    def generate_frame_info(self, *frame_info):
+        self.frame_infos.append(frame_info)
+
+    def finish(self, storage):
+        storage.rd_frame_infos = self.frame_infos[:]
+        storage.rd_nums = self.nums[:]
+        storage.rd_consts = self.consts[:]
+        return self.liveboxes
+
+
+class ResumeDataReader(object):
+    i_frame_infos = 0
+    i_boxes = 0
+
+    def __init__(self, storage, liveboxes):
+        self.frame_infos = storage.rd_frame_infos
+        self.nums = storage.rd_nums
+        self.consts = storage.rd_consts
+        self.liveboxes = liveboxes
+
+    def consume_boxes(self):
+        boxes = []
+        while True:
+            num = self.nums[self.i_boxes]
+            self.i_boxes += 1
+            if num >= 0:
+                box = self.liveboxes[num]
+            elif num != -1:
+                box = self.consts[-2 - num]
+            else:
+                break
+            boxes.append(box)
+        return boxes
+
+    def has_more_frame_infos(self):
+        return self.i_frame_infos < len(self.frame_infos)
+
+    def consume_frame_info(self):
+        frame_info = self.frame_infos[self.i_frame_infos]
+        self.i_frame_infos += 1
+        return frame_info



More information about the Pypy-commit mailing list