Author: fijal
Branch:
Changeset: r82406:9cc15a57d1c2
Date: 2016-02-22 18:35 +0100
http://bitbucket.org/pypy/pypy/changeset/9cc15a57d1c2/
Log: (fijal, arigo, cfbolz) Merge vlen-resume which compresses the
numberings by about 20% by using a variable-size encoding
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
@@ -27,6 +27,13 @@
self.prev = prev
self.boxes = boxes
+class TopSnapshot(Snapshot):
+ __slots__ = ('vable_boxes',)
+
+ def __init__(self, prev, boxes, vable_boxes):
+ Snapshot.__init__(self, prev, boxes)
+ self.vable_boxes = vable_boxes
+
def combine_uint(index1, index2):
assert 0 <= index1 < 65536
assert 0 <= index2 < 65536
@@ -127,9 +134,11 @@
snapshot_storage):
n = len(framestack) - 1
if virtualizable_boxes is not None:
- boxes = virtualref_boxes + virtualizable_boxes
+ virtualizable_boxes = ([virtualizable_boxes[-1]] +
+ virtualizable_boxes[:-1])
else:
- boxes = virtualref_boxes[:]
+ virtualizable_boxes = []
+ virtualref_boxes = virtualref_boxes[:]
if n >= 0:
top = framestack[n]
_ensure_parent_resumedata(framestack, n)
@@ -138,11 +147,12 @@
snapshot_storage.rd_frame_info_list = frame_info_list
snapshot = Snapshot(top.parent_resumedata_snapshot,
top.get_list_of_active_boxes(False))
- snapshot = Snapshot(snapshot, boxes)
+ snapshot = TopSnapshot(snapshot, virtualref_boxes, virtualizable_boxes)
snapshot_storage.rd_snapshot = snapshot
else:
snapshot_storage.rd_frame_info_list = None
- snapshot_storage.rd_snapshot = Snapshot(None, boxes)
+ snapshot_storage.rd_snapshot = TopSnapshot(None, virtualref_boxes,
+ virtualizable_boxes)
PENDINGFIELDSTRUCT = lltype.Struct('PendingField',
('lldescr', OBJECTPTR),
@@ -200,10 +210,12 @@
self.v = 0
def count_boxes(self, lst):
- c = 0
+ snapshot = lst[0]
+ assert isinstance(snapshot, TopSnapshot)
+ c = len(snapshot.vable_boxes)
for snapshot in lst:
c += len(snapshot.boxes)
- c += 2 * (len(lst) - 1)
+ c += 2 * (len(lst) - 1) + 1 + 1
return c
def append(self, item):
@@ -294,13 +306,11 @@
state.append(tagged)
state.n = n
state.v = v
- state.position -= length + 2
- def number(self, optimizer, snapshot, frameinfo):
+ def number(self, optimizer, topsnapshot, frameinfo):
# flatten the list
- vref_snapshot = snapshot
- cur = snapshot.prev
- snapshot_list = [vref_snapshot]
+ cur = topsnapshot.prev
+ snapshot_list = [topsnapshot]
framestack_list = []
while cur:
framestack_list.append(frameinfo)
@@ -311,19 +321,30 @@
# we want to number snapshots starting from the back, but ending
# with a forward list
- for i in range(len(snapshot_list) - 1, -1, -1):
- state.position -= len(snapshot_list[i].boxes)
- if i != 0:
- frameinfo = framestack_list[i - 1]
- jitcode_pos, pc = unpack_uint(frameinfo.packed_jitcode_pc)
- state.position -= 2
- state.append(rffi.cast(rffi.SHORT, jitcode_pos))
- state.append(rffi.cast(rffi.SHORT, pc))
+ for i in range(len(snapshot_list) - 1, 0, -1):
+ state.position -= len(snapshot_list[i].boxes) + 2
+ frameinfo = framestack_list[i - 1]
+ jitcode_pos, pc = unpack_uint(frameinfo.packed_jitcode_pc)
+ state.append(rffi.cast(rffi.SHORT, jitcode_pos))
+ state.append(rffi.cast(rffi.SHORT, pc))
self._number_boxes(snapshot_list[i].boxes, optimizer, state)
+ state.position -= len(snapshot_list[i].boxes) + 2
- numb = resumecode.create_numbering(state.current,
- len(vref_snapshot.boxes))
+ assert isinstance(topsnapshot, TopSnapshot)
+ special_boxes_size = (1 + len(topsnapshot.vable_boxes) +
+ 1 + len(topsnapshot.boxes))
+ assert state.position == special_boxes_size
+ state.position = 0
+ state.append(rffi.cast(rffi.SHORT, len(topsnapshot.vable_boxes)))
+ self._number_boxes(topsnapshot.vable_boxes, optimizer, state)
+ n = len(topsnapshot.boxes)
+ assert not (n & 1)
+ state.append(rffi.cast(rffi.SHORT, n >> 1))
+ self._number_boxes(topsnapshot.boxes, optimizer, state)
+ assert state.position == special_boxes_size
+
+ numb = resumecode.create_numbering(state.current)
return numb, state.liveboxes, state.v
def forget_numberings(self):
@@ -1113,48 +1134,42 @@
self.boxes_f = boxes_f
self._prepare_next_section(info)
- def consume_virtualizable_boxes(self, vinfo):
+ def consume_virtualizable_boxes(self, vinfo, index):
# 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
- first_snapshot_size = rffi.cast(lltype.Signed,
numb.first_snapshot_size)
- item, _ = resumecode.numb_next_item(numb, first_snapshot_size - 1)
+ item, index = resumecode.numb_next_item(numb, index)
virtualizablebox = self.decode_ref(item)
- index = first_snapshot_size -
vinfo.get_total_size(virtualizablebox.getref_base()) - 1
virtualizable = vinfo.unwrap_virtualizable_box(virtualizablebox)
return vinfo.load_list_of_boxes(virtualizable, self, virtualizablebox,
numb, index)
- def consume_virtualref_boxes(self, end):
+ def consume_virtualref_boxes(self, index):
# Returns a list of boxes, assumed to be all BoxPtrs.
# We leave up to the caller to call vrefinfo.continue_tracing().
- assert (end & 1) == 0
+ size, index = resumecode.numb_next_item(self.numb, index)
+ if size == 0:
+ return [], index
lst = []
- self.cur_index = 0
- for i in range(end):
- item, self.cur_index = resumecode.numb_next_item(self.numb,
- self.cur_index)
+ for i in range(size * 2):
+ item, index = resumecode.numb_next_item(self.numb, index)
lst.append(self.decode_ref(item))
- return lst
+ return lst, index
def consume_vref_and_vable_boxes(self, vinfo, ginfo):
- first_snapshot_size = rffi.cast(lltype.Signed,
- self.numb.first_snapshot_size)
+ vable_size, index = resumecode.numb_next_item(self.numb, 0)
if vinfo is not None:
- virtualizable_boxes = self.consume_virtualizable_boxes(vinfo)
- end = first_snapshot_size - len(virtualizable_boxes)
+ virtualizable_boxes, index =
self.consume_virtualizable_boxes(vinfo,
+
index)
elif ginfo is not None:
- item, self.cur_index = resumecode.numb_next_item(self.numb,
- first_snapshot_size - 1)
+ item, index = resumecode.numb_next_item(self.numb, index)
virtualizable_boxes = [self.decode_ref(item)]
- end = first_snapshot_size - 1
else:
- end = first_snapshot_size
virtualizable_boxes = None
- virtualref_boxes = self.consume_virtualref_boxes(end)
- self.cur_index = rffi.cast(lltype.Signed,
self.numb.first_snapshot_size)
+ virtualref_boxes, index = self.consume_virtualref_boxes(index)
+ self.cur_index = index
return virtualizable_boxes, virtualref_boxes
def allocate_with_vtable(self, descr=None):
@@ -1429,39 +1444,36 @@
info = blackholeinterp.get_current_position_info()
self._prepare_next_section(info)
- def consume_virtualref_info(self, vrefinfo, end):
+ def consume_virtualref_info(self, vrefinfo, index):
# we have to decode a list of references containing pairs
- # [..., virtual, vref, ...] stopping at 'end'
- if vrefinfo is None:
- assert end == 0
- return
- assert (end & 1) == 0
- self.cur_index = 0
- for i in range(0, end, 2):
- virtual_item, self.cur_index = resumecode.numb_next_item(
- self.numb, self.cur_index)
- vref_item, self.cur_index = resumecode.numb_next_item(
- self.numb, self.cur_index)
+ # [..., virtual, vref, ...] and returns the index at the end
+ size, index = resumecode.numb_next_item(self.numb, index)
+ if vrefinfo is None or size == 0:
+ assert size == 0
+ return index
+ 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 = 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):
+ def consume_vable_info(self, vinfo, index):
# 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
- first_snapshot_size = rffi.cast(lltype.Signed,
numb.first_snapshot_size)
- item, _ = resumecode.numb_next_item(self.numb,
- first_snapshot_size - 1)
+ item, index = resumecode.numb_next_item(self.numb, index)
virtualizable = self.decode_ref(item)
- start_index = first_snapshot_size - 1 -
vinfo.get_total_size(virtualizable)
# just reset the token, we'll force it later
vinfo.reset_token_gcref(virtualizable)
- vinfo.write_from_resume_data_partial(virtualizable, self, start_index,
- numb)
- return start_index
+ index = vinfo.write_from_resume_data_partial(virtualizable, self,
+ index, numb)
+ return index
def load_value_of_type(self, TYPE, tagged):
from rpython.jit.metainterp.warmstate import specialize_value
@@ -1478,14 +1490,18 @@
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, 0)
if self.resume_after_guard_not_forced != 2:
- end_vref = rffi.cast(lltype.Signed, self.numb.first_snapshot_size)
if vinfo is not None:
- end_vref = self.consume_vable_info(vinfo)
+ index = self.consume_vable_info(vinfo, index)
if ginfo is not None:
- end_vref -= 1
- self.consume_virtualref_info(vrefinfo, end_vref)
- self.cur_index = rffi.cast(lltype.Signed,
self.numb.first_snapshot_size)
+ _, index = resumecode.numb_next_item(self.numb, index)
+ index = self.consume_virtualref_info(vrefinfo, index)
+ 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
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
@@ -1,96 +1,74 @@
""" Resume bytecode. It goes as following:
-<numb> <numb> <pc> <jitcode> <numb> <numb> <numb> <pc> <jitcode>
+ [<length> <virtualizable object> <numb> <numb> <numb>] if vinfo is not
None
+ -OR-
+ [1 <ginfo object>] if ginfo is not
None
+ -OR-
+ [0] if both are None
-until the length of the array.
+ [<length> <virtual> <vref> <virtual> <vref>] for virtualrefs
-The interface is only create_numbering/numb_next_item, but! there is a trick
-that uses first_snapshot_size + some knowledge about inside to decode
-virtualref/virtualizable_fields/virtualizable in that order in resume.py.
+ [<pc> <jitcode> <numb> <numb> <numb>] the frames
+ [<pc> <jitcode> <numb> <numb>]
+ ...
-If the algorithm changes, the part about how to find where virtualizable
-and virtualrefs are to be found
+ until the length of the array.
"""
from rpython.rtyper.lltypesystem import rffi, lltype
NUMBERINGP = lltype.Ptr(lltype.GcForwardReference())
NUMBERING = lltype.GcStruct('Numbering',
-# ('prev', NUMBERINGP),
-# ('prev_index', rffi.USHORT),
- ('first_snapshot_size', rffi.USHORT), # ugh, ugly
- ('code', lltype.Array(rffi.SHORT)))
+ ('code', lltype.Array(rffi.UCHAR)))
NUMBERINGP.TO.become(NUMBERING)
NULL_NUMBER = lltype.nullptr(NUMBERING)
-# this is the actually used version
+def create_numbering(lst):
+ result = []
+ for item in lst:
+ item = rffi.cast(lltype.Signed, item)
+ item *= 2
+ if item < 0:
+ item = -1 - item
-def create_numbering(lst, first_snapshot_size):
- numb = lltype.malloc(NUMBERING, len(lst))
- for i in range(len(lst)):
- numb.code[i] = rffi.cast(rffi.SHORT, lst[i])
- numb.first_snapshot_size = rffi.cast(rffi.USHORT, first_snapshot_size)
+ assert item >= 0
+ if item < 2**7:
+ result.append(rffi.cast(rffi.UCHAR, item))
+ elif item < 2**14:
+ result.append(rffi.cast(rffi.UCHAR, item | 0x80))
+ result.append(rffi.cast(rffi.UCHAR, item >> 7))
+ else:
+ assert item < 2**16
+ result.append(rffi.cast(rffi.UCHAR, item | 0x80))
+ result.append(rffi.cast(rffi.UCHAR, (item >> 7) | 0x80))
+ result.append(rffi.cast(rffi.UCHAR, item >> 14))
+
+ numb = lltype.malloc(NUMBERING, len(result))
+ for i in range(len(result)):
+ numb.code[i] = result[i]
return numb
def numb_next_item(numb, index):
- return rffi.cast(lltype.Signed, numb.code[index]), index + 1
+ value = rffi.cast(lltype.Signed, numb.code[index])
+ index += 1
+ if value & (2**7):
+ value &= 2**7 - 1
+ value |= rffi.cast(lltype.Signed, numb.code[index]) << 7
+ index += 1
+ if value & (2**14):
+ value &= 2**14 - 1
+ value |= rffi.cast(lltype.Signed, numb.code[index]) << 14
+ index += 1
+ if value & 1:
+ value = -1 - value
+ value >>= 1
+ return value, index
-# this is the version that can be potentially used
-
-def _create_numbering(lst, prev, prev_index, first_snapshot_size):
- count = 0
- for item in lst:
- if item < 0:
- if item < -63:
- count += 1
- if item > 127:
- count += 1
- count += 1
- numb = lltype.malloc(NUMBERING, count)
- numb.prev = prev
- numb.prev_index = rffi.cast(rffi.USHORT, prev_index)
- numb.first_snapshot_size = rffi.cast(rffi.USHORT, first_snapshot_size)
- index = 0
- for item in lst:
- if 0 <= item <= 128:
- numb.code[index] = rffi.cast(rffi.UCHAR, item)
- index += 1
- else:
- assert (item >> 8) <= 63
- if item < 0:
- item = -item
- if item <= 63:
- numb.code[index] = rffi.cast(rffi.UCHAR, item | 0x40)
- index += 1
- else:
- numb.code[index] = rffi.cast(rffi.UCHAR, (item >> 8) |
0x80 | 0x40)
- numb.code[index + 1] = rffi.cast(rffi.UCHAR, item & 0xff)
- index += 2
- else:
- numb.code[index] = rffi.cast(rffi.UCHAR, (item >> 8) | 0x80)
- numb.code[index + 1] = rffi.cast(rffi.UCHAR, item & 0xff)
- index += 2
- return numb
-
-def copy_from_list_to_numb(lst, numb, index):
- i = 0
- while i < len(lst):
- numb.code[i + index] = lst[i]
- i += 1
-
-def _numb_next_item(numb, index):
- one = rffi.cast(lltype.Signed, numb.code[index])
- if one & 0x40:
- if one & 0x80:
- two = rffi.cast(lltype.Signed, numb.code[index + 1])
- return -(((one & ~(0x80 | 0x40)) << 8) | two), index + 2
- else:
- return -(one & (~0x40)), index + 1
- if one & 0x80:
- two = rffi.cast(lltype.Signed, numb.code[index + 1])
- return ((one & 0x7f) << 8) | two, index + 2
- return one, index + 1
+def numb_next_n_items(numb, size, index):
+ for i in range(size):
+ _, index = numb_next_item(numb, index)
+ return index
def unpack_numbering(numb):
l = []
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
@@ -10,7 +10,7 @@
VArrayInfoNotClear, VStrPlainInfo, VStrConcatInfo, VStrSliceInfo,\
VUniPlainInfo, VUniConcatInfo, VUniSliceInfo, Snapshot, FrameInfo,\
capture_resumedata, ResumeDataLoopMemo, UNASSIGNEDVIRTUAL, INT,\
- annlowlevel, PENDINGFIELDSP, unpack_uint, TAG_CONST_OFFSET
+ annlowlevel, PENDINGFIELDSP, unpack_uint, TAG_CONST_OFFSET, TopSnapshot
from rpython.jit.metainterp.resumecode import unpack_numbering,\
create_numbering, NULL_NUMBER
@@ -22,9 +22,12 @@
from rpython.jit.codewriter import heaptracker, longlong
from rpython.jit.metainterp.resoperation import ResOperation, InputArgInt,\
InputArgRef, rop
+from rpython.jit.metainterp.test.strategies import boxlists
from rpython.rlib.debug import debug_start, debug_stop, debug_print,\
have_debug_prints
+from hypothesis import given
+
class Storage:
rd_frame_info_list = None
rd_numb = None
@@ -278,9 +281,7 @@
assert bh.written_f == expected_f
-def Numbering(nums):
- numb = create_numbering(nums, 0)
- return numb
+Numbering = create_numbering
def tagconst(i):
return tag(i + TAG_CONST_OFFSET, TAGCONST)
@@ -610,7 +611,8 @@
assert unpack_uint(frame_info_list.packed_jitcode_pc) == (2, 15)
snapshot = storage.rd_snapshot
- assert snapshot.boxes == vrs + vbs # in the same list
+ assert snapshot.boxes == vrs
+ assert snapshot.vable_boxes == [b2, b1]
snapshot = snapshot.prev
assert snapshot.prev is fs[2].parent_resumedata_snapshot
@@ -904,9 +906,9 @@
env = [b1, c1, b2, b1, c2]
snap = Snapshot(None, env)
env1 = [c3, b3, b1, c1]
- snap1 = Snapshot(snap, env1)
+ snap1 = TopSnapshot(snap, env1, [])
env2 = [c3, b3, b1, c3]
- snap2 = Snapshot(snap, env2)
+ snap2 = TopSnapshot(snap, env2, [])
memo = ResumeDataLoopMemo(FakeMetaInterpStaticData())
frameinfo = FrameInfo(None, FakeJitCode("jitcode", 0), 0)
@@ -916,10 +918,11 @@
assert liveboxes == {b1: tag(0, TAGBOX), b2: tag(1, TAGBOX),
b3: tag(2, TAGBOX)}
- base = [tag(0, TAGBOX), tag(1, TAGINT), tag(1, TAGBOX), tag(0, TAGBOX),
tag(2, TAGINT)]
+ base = [0, 0, tag(0, TAGBOX), tag(1, TAGINT),
+ tag(1, TAGBOX), tag(0, TAGBOX), tag(2, TAGINT)]
- assert unpack_numbering(numb) == [
- tag(3, TAGINT), tag(2, TAGBOX), tag(0, TAGBOX), tag(1, TAGINT), 0,
0] + base
+ assert unpack_numbering(numb) == [0, 2, tag(3, TAGINT), tag(2, TAGBOX),
+ tag(0, TAGBOX), tag(1, TAGINT)] + base
numb2, liveboxes2, v = memo.number(FakeOptimizer(), snap2, frameinfo)
assert v == 0
@@ -927,11 +930,11 @@
assert liveboxes2 == {b1: tag(0, TAGBOX), b2: tag(1, TAGBOX),
b3: tag(2, TAGBOX)}
assert liveboxes2 is not liveboxes
- assert unpack_numbering(numb2) == [
- tag(3, TAGINT), tag(2, TAGBOX), tag(0, TAGBOX), tag(3, TAGINT), 0, 0]
+ base
+ assert unpack_numbering(numb2) == [0, 2, tag(3, TAGINT), tag(2, TAGBOX),
+ tag(0, TAGBOX), tag(3, TAGINT)] + base
env3 = [c3, b3, b1, c3]
- snap3 = Snapshot(snap, env3)
+ snap3 = TopSnapshot(snap, env3, [])
class FakeVirtualInfo(info.AbstractInfo):
def __init__(self, virt):
@@ -946,13 +949,12 @@
assert v == 0
assert liveboxes3 == {b1: tag(0, TAGBOX), b2: tag(1, TAGBOX)}
- assert unpack_numbering(numb3) == [tag(3, TAGINT), tag(4, TAGINT),
- tag(0, TAGBOX),
- tag(3, TAGINT), 0, 0] + base
+ assert unpack_numbering(numb3) == [0, 2, tag(3, TAGINT), tag(4, TAGINT),
+ tag(0, TAGBOX), tag(3, TAGINT)] + base
# virtual
env4 = [c3, b4, b1, c3]
- snap4 = Snapshot(snap, env4)
+ snap4 = TopSnapshot(snap, env4, [])
b4.set_forwarded(FakeVirtualInfo(True))
numb4, liveboxes4, v = memo.number(FakeOptimizer(), snap4, frameinfo)
@@ -960,11 +962,11 @@
assert liveboxes4 == {b1: tag(0, TAGBOX), b2: tag(1, TAGBOX),
b4: tag(0, TAGVIRTUAL)}
- assert unpack_numbering(numb4) == [tag(3, TAGINT), tag(0, TAGVIRTUAL),
- tag(0, TAGBOX), tag(3, TAGINT), 0, 0] + base
+ assert unpack_numbering(numb4) == [0, 2, tag(3, TAGINT), tag(0,
TAGVIRTUAL),
+ tag(0, TAGBOX), tag(3, TAGINT)] + base
env5 = [b1, b4, b5]
- snap5 = Snapshot(snap4, env5)
+ snap5 = TopSnapshot(snap4, [], env5)
b4.set_forwarded(FakeVirtualInfo(True))
b5.set_forwarded(FakeVirtualInfo(True))
@@ -974,9 +976,30 @@
assert liveboxes5 == {b1: tag(0, TAGBOX), b2: tag(1, TAGBOX),
b4: tag(0, TAGVIRTUAL), b5: tag(1, TAGVIRTUAL)}
- assert unpack_numbering(numb5) == [tag(0, TAGBOX), tag(0, TAGVIRTUAL),
- tag(1, TAGVIRTUAL), 2, 1] + unpack_numbering(numb4)
+ assert unpack_numbering(numb5) == [
+ 3, tag(0, TAGBOX), tag(0, TAGVIRTUAL), tag(1, TAGVIRTUAL),
+ 0,
+ 2, 1, tag(3, TAGINT), tag(0, TAGVIRTUAL), tag(0, TAGBOX), tag(3,
TAGINT)
+ ] + base
+@given(boxlists)
+def test_ResumeDataLoopMemo_random(lst):
+ s = TopSnapshot(None, [], lst)
+ frameinfo = FrameInfo(None, FakeJitCode("foo", 0), 0)
+ memo = ResumeDataLoopMemo(FakeMetaInterpStaticData())
+ num, liveboxes, v = memo.number(FakeOptimizer(), s, frameinfo)
+ l = unpack_numbering(num)
+ assert l[-1] == 0
+ assert l[0] == len(lst)
+ for i, item in enumerate(lst):
+ v, tag = untag(l[i + 1])
+ if tag == TAGBOX:
+ assert l[i + 1] == liveboxes[item]
+ elif tag == TAGCONST:
+ assert memo.consts[v].getint() == item.getint()
+ elif tag == TAGINT:
+ assert v == item.getint()
+
def test_ResumeDataLoopMemo_number_boxes():
memo = ResumeDataLoopMemo(FakeMetaInterpStaticData())
b1, b2 = [InputArgInt(), InputArgInt()]
@@ -1060,10 +1083,11 @@
storage = Storage()
snapshot = Snapshot(None, [b1, ConstInt(1), b1, b2])
snapshot = Snapshot(snapshot, [ConstInt(2), ConstInt(3)])
- snapshot = Snapshot(snapshot, [b1, b2, b3])
- frameinfo = FrameInfo(FrameInfo(None, FakeJitCode("code1", 21), 22),
- FakeJitCode("code2", 31), 32)
- storage.rd_snapshot = snapshot
+ snapshot = Snapshot(snapshot, [b1, b2, b3])
+ top_snapshot = TopSnapshot(snapshot, [], [])
+ frameinfo = FrameInfo(FrameInfo(FrameInfo(None, FakeJitCode("code1", 21),
22),
+ FakeJitCode("code2", 31), 32), FakeJitCode("code3", 41), 42)
+ storage.rd_snapshot = top_snapshot
storage.rd_frame_info_list = frameinfo
return storage
@@ -1076,6 +1100,8 @@
assert storage.rd_snapshot is None
cpu = MyCPU([])
reader = ResumeDataDirectReader(MyMetaInterp(cpu), storage, "deadframe")
+ reader.consume_vref_and_vable(None, None, None)
+ reader.cur_index += 2 # framestack
_next_section(reader, sys.maxint, 2**16, -65)
reader.cur_index += 2 # framestack
_next_section(reader, 2, 3)
diff --git a/rpython/jit/metainterp/test/test_resumecode.py
b/rpython/jit/metainterp/test/test_resumecode.py
--- a/rpython/jit/metainterp/test/test_resumecode.py
+++ b/rpython/jit/metainterp/test/test_resumecode.py
@@ -1,9 +1,12 @@
from rpython.jit.metainterp.resumecode import NUMBERING, NULL_NUMBER
from rpython.jit.metainterp.resumecode import create_numbering,\
- unpack_numbering, copy_from_list_to_numb
+ unpack_numbering
from rpython.rtyper.lltypesystem import lltype
+from hypothesis import strategies, given
+
+
def test_pack_unpack():
examples = [
[1, 2, 3, 4, 257, 10000, 13, 15],
@@ -12,5 +15,15 @@
[13000, 12000, 10000, 256, 255, 254, 257, -3, -1000]
]
for l in examples:
- n = create_numbering(l, 0)
+ n = create_numbering(l)
assert unpack_numbering(n) == l
+
+@given(strategies.lists(strategies.integers(-2**15, 2**15-1)))
+def test_roundtrip(l):
+ n = create_numbering(l)
+ assert unpack_numbering(n) == l
+
+@given(strategies.lists(strategies.integers(-2**15, 2**15-1)))
+def test_compressing(l):
+ n = create_numbering(l)
+ assert len(n.code) <= len(l) * 3
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
@@ -142,6 +142,7 @@
item, index = numb_next_item(numb, index)
x = reader.load_value_of_type(ARRAYITEMTYPE, item)
setarrayitem(lst, j, x)
+ return index
def load_list_of_boxes(virtualizable, reader, vable_box, numb, index):
virtualizable = cast_gcref_to_vtype(virtualizable)
@@ -161,7 +162,7 @@
box = reader.decode_box_of_type(ARRAYITEMTYPE, item)
boxes.append(box)
boxes.append(vable_box)
- return boxes
+ return boxes, index
def check_boxes(virtualizable, boxes):
virtualizable = cast_gcref_to_vtype(virtualizable)
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit