[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