[pypy-commit] pypy optinfo-into-bridges: factor out resumecode decoding into a Reader class instead of passing indexes everywhere
cfbolz
pypy.commits at gmail.com
Sat Oct 15 07:02:22 EDT 2016
Author: Carl Friedrich Bolz <cfbolz at gmx.de>
Branch: optinfo-into-bridges
Changeset: r87804:55bfa972b650
Date: 2016-10-14 15:46 +0200
http://bitbucket.org/pypy/pypy/changeset/55bfa972b650/
Log: factor out resumecode decoding into a Reader class instead of
passing indexes everywhere
diff --git a/rpython/jit/codewriter/jitcode.py b/rpython/jit/codewriter/jitcode.py
--- a/rpython/jit/codewriter/jitcode.py
+++ b/rpython/jit/codewriter/jitcode.py
@@ -141,14 +141,13 @@
def get_register_index_f(self, index):
return ord(self.live_f[index])
- def enumerate_vars(self, callback_i, callback_r, callback_f, spec, index):
+ def enumerate_vars(self, callback_i, callback_r, callback_f, spec):
for i in range(self.get_register_count_i()):
- index = callback_i(index, self.get_register_index_i(i))
+ callback_i(self.get_register_index_i(i))
for i in range(self.get_register_count_r()):
- index = callback_r(index, self.get_register_index_r(i))
+ callback_r(self.get_register_index_r(i))
for i in range(self.get_register_count_f()):
- index = callback_f(index, self.get_register_index_f(i))
- return index
+ callback_f(self.get_register_index_f(i))
enumerate_vars._annspecialcase_ = 'specialize:arg(4)'
_liveness_cache = {}
diff --git a/rpython/jit/metainterp/optimizeopt/bridgeopt.py b/rpython/jit/metainterp/optimizeopt/bridgeopt.py
--- a/rpython/jit/metainterp/optimizeopt/bridgeopt.py
+++ b/rpython/jit/metainterp/optimizeopt/bridgeopt.py
@@ -1,7 +1,7 @@
""" Code to feed information from the optimizer via the resume code into the
optimizer of the bridge attached to a guard. """
-from rpython.jit.metainterp.resumecode import numb_next_item, numb_next_n_items, unpack_numbering
+from rpython.jit.metainterp import resumecode
# XXX at the moment this is all quite ad-hoc. Could be delegated to the
# different optimization passes
@@ -81,6 +81,7 @@
for box1, descr, box2 in triples:
index = metainterp_sd.descrs_dct.get(descr, -1)
if index == -1:
+ # XXX XXX XXX fix length!
continue # just skip it, if the descr is not encodable
numb_state.append_short(tag_box(box1, liveboxes_from_env, memo))
numb_state.append_int(index)
@@ -90,12 +91,13 @@
numb_state.append_int(0)
def deserialize_optimizer_knowledge(optimizer, resumestorage, frontend_boxes, liveboxes):
+ reader = resumecode.Reader(resumestorage.rd_numb)
assert len(frontend_boxes) == len(liveboxes)
- numb = resumestorage.rd_numb
metainterp_sd = optimizer.metainterp_sd
# skip resume section
- index = skip_resume_section(numb, optimizer)
+ startcount = reader.next_item()
+ reader.jump(startcount - 1)
# class knowledge
bitfield = 0
@@ -104,7 +106,7 @@
if box.type != "r":
continue
if not mask:
- bitfield, index = numb_next_item(numb, index)
+ bitfield = reader.next_item()
mask = 0b100000
class_known = bitfield & mask
mask >>= 1
@@ -113,19 +115,15 @@
optimizer.make_constant_class(box, cls)
# heap knowledge
- length, index = numb_next_item(numb, index)
+ length = reader.next_item()
result = []
for i in range(length):
- tagged, index = numb_next_item(numb, index)
+ tagged = reader.next_item()
box1 = decode_box(resumestorage, tagged, liveboxes, metainterp_sd.cpu)
- tagged, index = numb_next_item(numb, index)
+ tagged = reader.next_item()
descr = metainterp_sd.opcode_descrs[tagged]
- tagged, index = numb_next_item(numb, index)
+ tagged = reader.next_item()
box2 = decode_box(resumestorage, tagged, liveboxes, metainterp_sd.cpu)
result.append((box1, descr, box2))
if optimizer.optheap:
optimizer.optheap.deserialize_optheap(result)
-
-def skip_resume_section(numb, optimizer):
- startcount, index = numb_next_item(numb, 0)
- return numb_next_n_items(numb, startcount, 0)
diff --git a/rpython/jit/metainterp/resume.py b/rpython/jit/metainterp/resume.py
--- a/rpython/jit/metainterp/resume.py
+++ b/rpython/jit/metainterp/resume.py
@@ -950,12 +950,9 @@
def _init(self, cpu, storage):
self.cpu = cpu
- self.numb = storage.rd_numb
- count, self.cur_index = resumecode.numb_next_item(
- self.numb, 0)
- # XXX inefficient
- self.size_resume_section = resumecode.numb_next_n_items(
- self.numb, count, 0)
+ self.resumecodereader = resumecode.Reader(storage.rd_numb)
+ count = self.resumecodereader.next_item()
+ self.items_resume_section = count
self.count = storage.rd_count
self.consts = storage.rd_consts
@@ -964,14 +961,12 @@
self._prepare_pendingfields(storage.rd_pendingfields)
def read_jitcode_pos_pc(self):
- jitcode_pos, self.cur_index = resumecode.numb_next_item(self.numb,
- self.cur_index)
- pc, self.cur_index = resumecode.numb_next_item(self.numb,
- self.cur_index)
+ jitcode_pos = self.resumecodereader.next_item()
+ pc = self.resumecodereader.next_item()
return jitcode_pos, pc
def done_reading(self):
- return self.cur_index >= self.size_resume_section
+ return self.resumecodereader.items_read >= self.items_resume_section
def getvirtual_ptr(self, index):
# Returns the index'th virtual, building it lazily if needed.
@@ -1048,29 +1043,25 @@
def _prepare_next_section(self, info):
# Use info.enumerate_vars(), normally dispatching to
# rpython.jit.codewriter.jitcode. Some tests give a different 'info'.
- self.cur_index = info.enumerate_vars(self._callback_i,
- self._callback_r,
- self._callback_f,
- self.unique_id, # <-- annotation hack
- self.cur_index)
+ info.enumerate_vars(self._callback_i,
+ self._callback_r,
+ self._callback_f,
+ self.unique_id) # <-- annotation hack
- def _callback_i(self, index, register_index):
- item, index = resumecode.numb_next_item(self.numb, index)
+ def _callback_i(self, register_index):
+ item = self.resumecodereader.next_item()
value = self.decode_int(item)
self.write_an_int(register_index, value)
- return index
- def _callback_r(self, index, register_index):
- item, index = resumecode.numb_next_item(self.numb, index)
+ def _callback_r(self, register_index):
+ item = self.resumecodereader.next_item()
value = self.decode_ref(item)
self.write_a_ref(register_index, value)
- return index
- def _callback_f(self, index, register_index):
- item, index = resumecode.numb_next_item(self.numb, index)
+ def _callback_f(self, register_index):
+ item = self.resumecodereader.next_item()
value = self.decode_float(item)
self.write_a_float(register_index, value)
- return index
# ---------- when resuming for pyjitpl.py, make boxes ----------
@@ -1109,42 +1100,33 @@
self.boxes_f = boxes_f
self._prepare_next_section(info)
- def consume_virtualizable_boxes(self, vinfo, index):
+ def consume_virtualizable_boxes(self, vinfo):
# we have to ignore the initial part of 'nums' (containing vrefs),
# find the virtualizable from nums[-1], and use it to know how many
# boxes of which type we have to return. This does not write
# anything into the virtualizable.
- numb = self.numb
- item, index = resumecode.numb_next_item(numb, index)
+ item = self.resumecodereader.next_item()
virtualizablebox = self.decode_ref(item)
virtualizable = vinfo.unwrap_virtualizable_box(virtualizablebox)
- return vinfo.load_list_of_boxes(virtualizable, self, virtualizablebox,
- numb, index)
+ return vinfo.load_list_of_boxes(virtualizable, self, virtualizablebox)
- def consume_virtualref_boxes(self, index):
+ def consume_virtualref_boxes(self):
# Returns a list of boxes, assumed to be all BoxPtrs.
# We leave up to the caller to call vrefinfo.continue_tracing().
- size, index = resumecode.numb_next_item(self.numb, index)
- if size == 0:
- return [], index
- lst = []
- for i in range(size * 2):
- item, index = resumecode.numb_next_item(self.numb, index)
- lst.append(self.decode_ref(item))
- return lst, index
+ size = self.resumecodereader.next_item()
+ return [self.decode_ref(self.resumecodereader.next_item())
+ for i in range(size * 2)]
def consume_vref_and_vable_boxes(self, vinfo, ginfo):
- vable_size, index = resumecode.numb_next_item(self.numb, self.cur_index)
+ vable_size = self.resumecodereader.next_item()
if vinfo is not None:
- virtualizable_boxes, index = self.consume_virtualizable_boxes(vinfo,
- index)
+ virtualizable_boxes = self.consume_virtualizable_boxes(vinfo)
elif ginfo is not None:
- item, index = resumecode.numb_next_item(self.numb, index)
+ item = self.resumecodereader.next_item()
virtualizable_boxes = [self.decode_ref(item)]
else:
virtualizable_boxes = None
- virtualref_boxes, index = self.consume_virtualref_boxes(index)
- self.cur_index = index
+ virtualref_boxes = self.consume_virtualref_boxes()
return virtualizable_boxes, virtualref_boxes
def allocate_with_vtable(self, descr=None):
@@ -1421,30 +1403,26 @@
info = blackholeinterp.get_current_position_info()
self._prepare_next_section(info)
- def consume_virtualref_info(self, vrefinfo, index):
+ def consume_virtualref_info(self, vrefinfo):
# we have to decode a list of references containing pairs
# [..., virtual, vref, ...] and returns the index at the end
- size, index = resumecode.numb_next_item(self.numb, index)
+ size = self.resumecodereader.next_item()
if vrefinfo is None or size == 0:
assert size == 0
- return index
+ return
for i in range(size):
- virtual_item, index = resumecode.numb_next_item(
- self.numb, index)
- vref_item, index = resumecode.numb_next_item(
- self.numb, index)
+ virtual_item = self.resumecodereader.next_item()
+ vref_item = self.resumecodereader.next_item()
virtual = self.decode_ref(virtual_item)
vref = self.decode_ref(vref_item)
# For each pair, we store the virtual inside the vref.
vrefinfo.continue_tracing(vref, virtual)
- return index
- def consume_vable_info(self, vinfo, index):
+ def consume_vable_info(self, vinfo):
# we have to ignore the initial part of 'nums' (containing vrefs),
# find the virtualizable from nums[-1], load all other values
# from the CPU stack, and copy them into the virtualizable
- numb = self.numb
- item, index = resumecode.numb_next_item(self.numb, index)
+ item = self.resumecodereader.next_item()
virtualizable = self.decode_ref(item)
# just reset the token, we'll force it later
vinfo.reset_token_gcref(virtualizable)
@@ -1467,18 +1445,17 @@
load_value_of_type._annspecialcase_ = 'specialize:arg(1)'
def consume_vref_and_vable(self, vrefinfo, vinfo, ginfo):
- vable_size, index = resumecode.numb_next_item(self.numb, self.cur_index)
+ vable_size = self.resumecodereader.next_item()
if self.resume_after_guard_not_forced != 2:
if vinfo is not None:
- index = self.consume_vable_info(vinfo, index)
+ self.consume_vable_info(vinfo)
if ginfo is not None:
- _, index = resumecode.numb_next_item(self.numb, index)
- index = self.consume_virtualref_info(vrefinfo, index)
+ _ = self.resumecodereader.next_item()
+ self.consume_virtualref_info(vrefinfo)
else:
- index = resumecode.numb_next_n_items(self.numb, vable_size, index)
- vref_size, index = resumecode.numb_next_item(self.numb, index)
- index = resumecode.numb_next_n_items(self.numb, vref_size * 2, index)
- self.cur_index = index
+ self.resumecodereader.jump(vable_size)
+ vref_size = self.resumecodereader.next_item()
+ self.resumecodereader.jump(vref_size * 2)
def allocate_with_vtable(self, descr=None):
from rpython.jit.metainterp.executor import exec_new_with_vtable
diff --git a/rpython/jit/metainterp/resumecode.py b/rpython/jit/metainterp/resumecode.py
--- a/rpython/jit/metainterp/resumecode.py
+++ b/rpython/jit/metainterp/resumecode.py
@@ -86,3 +86,30 @@
next, i = numb_next_item(numb, i)
l.append(next)
return l
+
+class Reader(object):
+ def __init__(self, code):
+ self.code = code
+ self.cur_pos = 0 # index into the code
+ self.items_read = 0 # number of items read
+
+ def next_item(self):
+ result, self.cur_pos = numb_next_item(self.code, self.cur_pos)
+ self.items_read += 1
+ return result
+
+ def peek(self):
+ result, _ = numb_next_item(self.code, self.cur_pos)
+ return result
+
+ def jump(self, size):
+ """ jump n items forward without returning anything """
+ index = self.cur_pos
+ for i in range(size):
+ _, index = numb_next_item(self.code, index)
+ self.items_read += size
+ self.cur_pos = index
+
+ def unpack(self):
+ # mainly for debugging
+ return unpack_numbering(self.code)
diff --git a/rpython/jit/metainterp/test/test_resume.py b/rpython/jit/metainterp/test/test_resume.py
--- a/rpython/jit/metainterp/test/test_resume.py
+++ b/rpython/jit/metainterp/test/test_resume.py
@@ -254,18 +254,17 @@
def get_current_position_info(self):
class MyInfo:
@staticmethod
- def enumerate_vars(callback_i, callback_r, callback_f, _, index):
+ def enumerate_vars(callback_i, callback_r, callback_f, _):
count_i = count_r = count_f = 0
for ARG in self.ARGS:
if ARG == lltype.Signed:
- index = callback_i(index, count_i); count_i += 1
+ callback_i(count_i); count_i += 1
elif ARG == llmemory.GCREF:
- index = callback_r(index, count_r); count_r += 1
+ callback_r(count_r); count_r += 1
elif ARG == longlong.FLOATSTORAGE:
- index = callback_f(index, count_f); count_f += 1
+ callback_f(count_f); count_f += 1
else:
assert 0
- return index
return MyInfo()
def setarg_i(self, index, value):
@@ -1074,11 +1073,11 @@
cpu = MyCPU([])
reader = ResumeDataDirectReader(MyMetaInterp(cpu), storage, "deadframe")
reader.consume_vref_and_vable(None, None, None)
- reader.cur_index += 2 # framestack
+ reader.resumecodereader.jump(2) # framestack
_next_section(reader, sys.maxint, 1, sys.maxint, 2**16)
- reader.cur_index += 2 # framestack
+ reader.resumecodereader.jump(2) # framestack
_next_section(reader, 2, 3)
- reader.cur_index += 2 # framestack
+ reader.resumecodereader.jump(2) # framestack
_next_section(reader, sys.maxint, 2**16, -65)
def test_virtual_adder_memo_const_sharing():
@@ -1117,9 +1116,10 @@
return True
class MyInfo:
@staticmethod
- def enumerate_vars(callback_i, callback_r, callback_f, _, index):
- while index < max_index:
- tagged, _ = resumecode.numb_next_item(self.numb, index)
+ def enumerate_vars(callback_i, callback_r, callback_f, _):
+ index = 0
+ while not self.done_reading():
+ tagged = self.resumecodereader.peek()
_, tag = untag(tagged)
if tag == TAGVIRTUAL:
kind = REF
@@ -1127,22 +1127,21 @@
kind = Whatever()
box = self.decode_box(tagged, kind)
if box.type == INT:
- index = callback_i(index, index)
+ callback_i(index)
elif box.type == REF:
- index = callback_r(index, index)
+ callback_r(index)
elif box.type == FLOAT:
- index = callback_f(index, index)
+ callback_f(index)
else:
assert 0
+ index += 1
- size_section, self.cur_index = resumecode.numb_next_item(self.numb, 0)
- max_index = resumecode.numb_next_n_items(self.numb, size_section, 0)
- size, self.cur_index = resumecode.numb_next_item(self.numb, self.cur_index)
+ size = self.resumecodereader.next_item()
assert size == 0
- size, self.cur_index = resumecode.numb_next_item(self.numb, self.cur_index)
+ size = self.resumecodereader.next_item()
assert size == 0
- pc, self.cur_index = resumecode.numb_next_item(self.numb, self.cur_index)
- jitcode_pos, self.cur_index = resumecode.numb_next_item(self.numb, self.cur_index)
+ pc = self.resumecodereader.next_item()
+ jitcode_pos = self.resumecodereader.next_item()
self._prepare_next_section(MyInfo())
return self.lst
diff --git a/rpython/jit/metainterp/virtualizable.py b/rpython/jit/metainterp/virtualizable.py
--- a/rpython/jit/metainterp/virtualizable.py
+++ b/rpython/jit/metainterp/virtualizable.py
@@ -144,7 +144,7 @@
setarrayitem(lst, j, x)
return index
- def load_list_of_boxes(virtualizable, reader, vable_box, numb, index):
+ def load_list_of_boxes(virtualizable, reader, vable_box):
virtualizable = cast_gcref_to_vtype(virtualizable)
# Uses 'virtualizable' only to know the length of the arrays;
# does not write anything into it. The returned list is in
@@ -152,13 +152,13 @@
# the virtualizable itself.
boxes = []
for FIELDTYPE, fieldname in unroll_static_fields:
- item, index = numb_next_item(numb, index)
+ item = reader.resumecodereader.next_item()
box = reader.decode_box_of_type(FIELDTYPE, item)
boxes.append(box)
for ARRAYITEMTYPE, fieldname in unroll_array_fields:
lst = getattr(virtualizable, fieldname)
for j in range(getlength(lst)):
- item, index = numb_next_item(numb, index)
+ item = reader.resumecodereader.next_item()
box = reader.decode_box_of_type(ARRAYITEMTYPE, item)
boxes.append(box)
boxes.append(vable_box)
More information about the pypy-commit
mailing list