Author: fijal
Branch: compress-numbering
Changeset: r80049:2255631c47aa
Date: 2015-10-08 17:19 +0200
http://bitbucket.org/pypy/pypy/changeset/2255631c47aa/
Log: break everything - encode resume data in a more compact way (but
reading is not there just yet)
diff --git a/rpython/jit/metainterp/compile.py
b/rpython/jit/metainterp/compile.py
--- a/rpython/jit/metainterp/compile.py
+++ b/rpython/jit/metainterp/compile.py
@@ -823,12 +823,13 @@
class ResumeGuardDescr(AbstractResumeGuardDescr):
_attrs_ = ('rd_numb', 'rd_count', 'rd_consts', 'rd_virtuals',
- 'rd_pendingfields', 'status')
+ 'rd_pendingfields', 'rd_stackdepth', 'status')
rd_numb = lltype.nullptr(NUMBERING)
rd_count = 0
rd_consts = None
rd_virtuals = None
+ rd_stackdepth = 0
rd_pendingfields = lltype.nullptr(PENDINGFIELDSP.TO)
def copy_all_attributes_from(self, other):
@@ -839,6 +840,7 @@
self.rd_consts = other.rd_consts
self.rd_pendingfields = other.rd_pendingfields
self.rd_virtuals = other.rd_virtuals
+ self.rd_stackdepth = other.rd_stackdepth
self.rd_numb = other.rd_numb
# we don't copy status
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
@@ -12,6 +12,7 @@
from rpython.rtyper.lltypesystem import lltype, llmemory, rffi, rstr
from rpython.rtyper.rclass import OBJECTPTR
from rpython.jit.metainterp.walkvirtual import VirtualVisitor
+from rpython.jit.metainterp import resumecode
# Logic to encode the chain of frames and the state of the boxes at a
@@ -196,25 +197,9 @@
# env numbering
- def number(self, optimizer, snapshot, frameinfo, first_iteration=False):
- if snapshot is None:
- return lltype.nullptr(NUMBERING), {}, 0
- if snapshot in self.numberings:
- numb, liveboxes, v = self.numberings[snapshot]
- return numb, liveboxes.copy(), v
-
- if first_iteration:
- numb1, liveboxes, v = self.number(optimizer, snapshot.prev,
frameinfo)
- else:
- numb1, liveboxes, v = self.number(optimizer, snapshot.prev,
frameinfo.prev)
- n = len(liveboxes) - v
- boxes = snapshot.boxes
+ def _number_boxes(self, boxes, liveboxes, optimizer, v, n):
length = len(boxes)
- numb = lltype.malloc(NUMBERING, length)
- if first_iteration:
- numb.packed_jitcode_pc = -1
- else:
- numb.packed_jitcode_pc = frameinfo.packed_jitcode_pc
+ current = []
for i in range(length):
box = boxes[i]
box = optimizer.get_box_replacement(box)
@@ -238,12 +223,58 @@
tagged = tag(n, TAGBOX)
n += 1
liveboxes[box] = tagged
- numb.nums[i] = tagged
- #
- numb.prev = numb1
- self.numberings[snapshot] = numb, liveboxes, v
- return numb, liveboxes.copy(), v
+ current.append(tagged)
+ return v, n, current
+ def _get_prev_snapshot(self, snapshot):
+ cur_snapshot = snapshot
+ while True:
+ try:
+ return self.numberings[cur_snapshot], cur_snapshot
+ except KeyError:
+ pass
+ cur_snapshot = cur_snapshot.prev
+ if not cur_snapshot:
+ return (lltype.nullptr(resumecode.NUMBERING), 0, {}, 0), None
+
+ def number(self, optimizer, snapshot, frameinfo):
+ # find the parent
+
+ p = self._get_prev_snapshot(snapshot)
+ (prev_numb, prev_numb_index, liveboxes, v), s = p
+ n = len(liveboxes) - v
+ first = True
+ all_lists = []
+ total_lgt = 0
+ cur_snapshot = snapshot
+ liveboxes_to_save = []
+ while cur_snapshot != s:
+ liveboxes_to_save.append((liveboxes.copy(), v))
+ v, n, current = self._number_boxes(cur_snapshot.boxes, liveboxes,
optimizer,
+ v, n)
+ cur_snapshot = cur_snapshot.prev
+ if first:
+ first = False
+ else:
+ jitcode_pos, pc = unpack_uint(frameinfo.packed_jitcode_pc)
+ current.append(rffi.cast(rffi.USHORT, jitcode_pos))
+ current.append(rffi.cast(rffi.USHORT, pc))
+ lst = resumecode.create_numbering(current)
+ total_lgt += len(lst)
+ all_lists.append(lst)
+ numb = lltype.malloc(resumecode.NUMBERING, total_lgt)
+ numb.prev = prev_numb
+ numb.prev_index = rffi.cast(rffi.USHORT, prev_numb_index)
+ index = 0
+ for i in range(len(all_lists)):
+ lst = all_lists[i]
+ liveboxes_snapshot, v = liveboxes_to_save[i]
+ self.numberings[snapshot] = (numb, index, liveboxes_snapshot, v)
+ resumecode.copy_from_list_to_numb(lst, numb, index)
+ index += len(lst)
+ snapshot = snapshot.prev
+ return numb, liveboxes, v
+
def forget_numberings(self):
# XXX ideally clear only the affected numberings
self.numberings.clear()
@@ -385,8 +416,15 @@
assert not storage.rd_numb
snapshot = self.snapshot_storage.rd_snapshot
assert snapshot is not None # is that true?
+ # count stack depth
+ frame_info_list = self.snapshot_storage.rd_frame_info_list
+ stack_depth = 1
+ while frame_info_list.prev is not None:
+ frame_info_list = frame_info_list.prev
+ stack_depth += 1
+ storage.rd_stack_depth = stack_depth
numb, liveboxes_from_env, v = self.memo.number(optimizer, snapshot,
- self.snapshot_storage.rd_frame_info_list, first_iteration=True)
+ self.snapshot_storage.rd_frame_info_list)
self.liveboxes_from_env = liveboxes_from_env
self.liveboxes = {}
storage.rd_numb = numb
diff --git a/rpython/jit/metainterp/resumecode.py
b/rpython/jit/metainterp/resumecode.py
new file mode 100644
--- /dev/null
+++ b/rpython/jit/metainterp/resumecode.py
@@ -0,0 +1,59 @@
+
+""" Resume bytecode. It goes as following:
+
+<numb> <numb> <pc> <jitcode> <numb> <numb> <numb> <pc> <jitcode>
+
+until the length of the array, then to the parent at the convinient index.
+numb are encoded in the variable length byte encoding as follows:
+if the first bit is set, then it's the first
+7 bits then the next byte, otherwise it's the next 7 bit.
+"""
+
+from rpython.rtyper.lltypesystem import rffi, lltype
+
+NUMBERINGP = lltype.Ptr(lltype.GcForwardReference())
+NUMBERING = lltype.GcStruct('Numbering',
+ ('prev', NUMBERINGP),
+ ('prev_index', rffi.USHORT),
+ ('code', lltype.Array(rffi.UCHAR)))
+NUMBERINGP.TO.become(NUMBERING)
+
+def create_numbering(lst):
+ count = 0
+ for item in lst:
+ if item > 127:
+ count += 1
+ count += 1
+ numb = [rffi.cast(rffi.UCHAR, 0)] * count
+ index = 0
+ for item in lst:
+ if item <= 128:
+ numb[index] = rffi.cast(rffi.UCHAR, item)
+ index += 1
+ else:
+ assert (item >> 8) <= 127
+ numb[index] = rffi.cast(rffi.UCHAR, (item >> 8) | 0x80)
+ numb[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 & 0x80:
+ two = rffi.cast(lltype.Signed, numb.code[index + 1])
+ return ((one & 0x7f) << 8) | two, index + 2
+ return one, index + 1
+
+def unpack_numbering(numb):
+ l = []
+ i = 0
+ while i < len(numb.code):
+ next, i = numb_next_item(numb, i)
+ l.append(next)
+ return l
diff --git a/rpython/jit/metainterp/test/test_resumecode.py
b/rpython/jit/metainterp/test/test_resumecode.py
new file mode 100644
--- /dev/null
+++ b/rpython/jit/metainterp/test/test_resumecode.py
@@ -0,0 +1,18 @@
+
+from rpython.jit.metainterp.resumecode import NUMBERING
+from rpython.jit.metainterp.resumecode import create_numbering,\
+ unpack_numbering, copy_from_list_to_numb
+from rpython.rtyper.lltypesystem import lltype
+
+def test_pack_unpack():
+ examples = [
+ [1, 2, 3, 4, 257, 10000, 13, 15],
+ [1, 2, 3, 4],
+ range(1, 10, 2),
+ [13000, 12000, 10000, 256, 255, 254, 257]
+ ]
+ for l in examples:
+ lst = create_numbering(l)
+ n = lltype.malloc(NUMBERING, len(lst))
+ copy_from_list_to_numb(lst, n, 0)
+ assert unpack_numbering(n) == l
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit