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

Reply via email to