Author: fijal
Branch: jit-leaner-frontend
Changeset: r82993:065b7dae64ce
Date: 2016-03-12 18:36 +0200
http://bitbucket.org/pypy/pypy/changeset/065b7dae64ce/

Log:    hack differently

diff --git a/rpython/jit/metainterp/opencoder.py 
b/rpython/jit/metainterp/opencoder.py
--- a/rpython/jit/metainterp/opencoder.py
+++ b/rpython/jit/metainterp/opencoder.py
@@ -27,52 +27,32 @@
     pass
 
 class SnapshotIterator(object):
-    def __init__(self, main_iter, pos, end_pos):
-        self.trace = main_iter.trace
+    def __init__(self, main_iter, snapshot):
         self.main_iter = main_iter
-        self.end = end_pos
-        self.start = pos
-        self.pos = pos
-        self.save_pos = -1
+        # reverse the snapshots and store the vable, vref lists
+        assert isinstance(snapshot, TopSnapshot)
+        self.vable_array = snapshot.vable_array
+        self.vref_array = snapshot.vref_array
+        self.size = len(self.vable_array) + len(self.vref_array) + 2
+        jc_index, pc = unpack_uint(snapshot.packed_jitcode_pc)
+        self.framestack = []
+        if jc_index == 2**16-1:
+            return
+        while snapshot:
+            self.framestack.append(snapshot)
+            self.size += len(snapshot.box_array) + 2
+            snapshot = snapshot.prev
+        self.framestack.reverse()
 
-    def length(self):
-        return self.end - self.start
+    def get(self, index):
+        return self.main_iter._untag(index)
 
-    def done(self):
-        return self.pos >= self.end
+    def unpack_jitcode_pc(self, snapshot):
+        return unpack_uint(snapshot.packed_jitcode_pc)
 
-    def _next(self):
-        res = rffi.cast(lltype.Signed, self.trace._ops[self.pos])
-        self.pos += 1
-        return res
-
-    def next(self):
-        r = self.main_iter._untag(self._next())
-        assert r
-        return r
-
-    def read_boxes(self, size):
-        return [self.next() for i in range(size)]
-
-    def get_size_jitcode_pc(self):
-        if self.save_pos >= 0:
-            self.pos = self.save_pos
-            self.save_pos = -1
-        size = self._next()
-        if size < 0:
-            self.save_pos = self.pos + 1
-            self.pos = ((-size - 1) << 15) | (self._next())
-            assert self.pos >= 0
-            size = self._next()
-            assert size >= 0
-        return size, self._next(), self._next()
-
-    def get_list_of_boxes(self):
-        size = self._next()
-        l = []
-        for i in range(size):
-            l.append(self.next())
-        return l
+    def unpack_array(self, arr):
+        # NOT_RPYTHON
+        return [self.get(i) for i in arr]
 
 class TraceIterator(BaseTrace):
     def __init__(self, trace, start, end, force_inputargs=None):
@@ -127,14 +107,8 @@
         else:
             assert False
 
-    def skip_resume_data(self):
-        pos = self.pos
-        self.pos += self._next()
-        return pos
-
-    def get_snapshot_iter(self, pos):
-        end = rffi.cast(lltype.Signed, self.trace._ops[pos]) + pos
-        return SnapshotIterator(self, pos + 1, end)
+    def get_snapshot_iter(self, index):
+        return SnapshotIterator(self, self.trace._snapshots[index])
 
     def next(self):
         opnum = self._next()
@@ -147,7 +121,7 @@
             args.append(self._untag(self._next()))
         if opwithdescr[opnum]:
             descr_index = self._next()
-            if descr_index == -1:
+            if descr_index == -1 or rop.is_guard(opnum):
                 descr = None
             else:
                 descr = self.trace._descrs[descr_index]
@@ -156,7 +130,7 @@
         res = ResOperation(opnum, args, -1, descr=descr)
         if rop.is_guard(opnum):
             assert isinstance(res, GuardResOp)
-            res.rd_resume_position = self.skip_resume_data()
+            res.rd_resume_position = descr_index
         self._cache[self._count] = res
         self._count += 1
         return res
@@ -174,6 +148,30 @@
         iter._count = self.count
         return iter
 
+def combine_uint(index1, index2):
+    assert 0 <= index1 < 65536
+    assert 0 <= index2 < 65536
+    return index1 << 16 | index2 # it's ok to return signed here,
+    # we need only 32bit, but 64 is ok for now
+
+def unpack_uint(packed):
+    return (packed >> 16) & 0xffff, packed & 0xffff
+
+class Snapshot(object):
+    _attrs_ = ('packed_jitcode_pc', 'box_array', 'prev')
+
+    prev = None
+
+    def __init__(self, packed_jitcode_pc, box_array):
+        self.packed_jitcode_pc = packed_jitcode_pc
+        self.box_array = box_array
+
+class TopSnapshot(Snapshot):
+    def __init__(self, packed_jitcode_pc, box_array, vable_array, vref_array):
+        Snapshot.__init__(self, packed_jitcode_pc, box_array)
+        self.vable_array = vable_array
+        self.vref_array = vref_array
+
 class Trace(BaseTrace):
     def __init__(self, inputargs):
         self._ops = [rffi.cast(rffi.SHORT, -15)] * 30000
@@ -191,6 +189,7 @@
         self._bigints_dict = {}
         self._floats = []
         self._floats_dict = {}
+        self._snapshots = []
         for i, inparg in enumerate(inputargs):
             assert isinstance(inparg, AbstractInputArg)
             inparg.position = -i - 1
@@ -301,32 +300,12 @@
         self._count += 1
         return pos
 
-    def _record_raw(self, opnum, tagged_args, tagged_descr=-1):
-        NOT_USED
-        operations = self._ops
-        pos = self._count
-        operations.append(opnum)
-        expected_arity = oparity[opnum]
-        if expected_arity == -1:
-            operations.append(len(tagged_args))
-        else:
-            assert len(argboxes) == expected_arity
-        operations.extend(tagged_args)
-        if tagged_descr != -1:
-            operations.append(tagged_descr)
-        self._count += 1
-        return pos        
-
     def _encode_descr(self, descr):
         # XXX provide a global cache for prebuilt descrs so we don't
         #     have to repeat them here        
         self._descrs.append(descr)
         return len(self._descrs) - 1
 
-#    def record_forwarding(self, op, newtag):
-#        index = op._pos
-#        self._ops[index] = -newtag - 1
-
     def record_snapshot_link(self, pos):
         self._sharings += 1
         lower = pos & 0x7fff
@@ -340,40 +319,35 @@
         assert opnum >= 0
         return ResOperation(opnum, argboxes, pos, descr)
 
-    def record_op_tag(self, opnum, tagged_args, descr=None):
-        NOT_USED
-        return tag(TAGBOX, self._record_raw(opnum, tagged_args, descr))
+    def _list_of_boxes(self, boxes):
+        return [rffi.cast(rffi.SHORT, self._encode(box)) for box in boxes]
 
-    def record_snapshot(self, jitcode, pc, active_boxes):
-        self._total_snapshots += 1
-        pos = self._pos
-        self.append(len(active_boxes)) # unnecessary, can be read from
-        self.append(jitcode.index)
-        self.append(pc)
-        for box in active_boxes:
-            self.append(self._encode(box)) # not tagged, as it must be boxes
-        return pos
+    def create_top_snapshot(self, jitcode, pc, boxes, vable_boxes, vref_boxes):
+        array = self._list_of_boxes(boxes)
+        vable_array = self._list_of_boxes(vable_boxes)
+        vref_array = self._list_of_boxes(vref_boxes)
+        s = TopSnapshot(combine_uint(jitcode.index, pc), array, vable_array,
+                        vref_array)
+        assert rffi.cast(lltype.Signed, self._ops[self._pos - 1]) == -1
+        # guards have no descr
+        self._snapshots.append(s)
+        self._ops[self._pos - 1] = rffi.cast(rffi.SHORT, len(self._snapshots) 
- 1)
+        return s
 
-    def record_list_of_boxes(self, boxes):
-        self.append(len(boxes))
-        for box in boxes:
-            self.append(self._encode(box))
+    def create_empty_top_snapshot(self, vable_boxes, vref_boxes):
+        vable_array = self._list_of_boxes(vable_boxes)
+        vref_array = self._list_of_boxes(vref_boxes)
+        s = TopSnapshot(combine_uint(2**16 - 1, 0), [], vable_array,
+                        vref_array)
+        assert rffi.cast(lltype.Signed, self._ops[self._pos - 1]) == -1
+        # guards have no descr
+        self._snapshots.append(s)
+        self._ops[self._pos - 1] = rffi.cast(rffi.SHORT, len(self._snapshots) 
- 1)
+        return s
 
-    def get_patchable_position(self):
-        p = self._pos
-        self.append(-1)
-        return p
-
-    def patch_position_to_current(self, p):
-        prev = self._ops[p]
-        assert rffi.cast(lltype.Signed, prev) == -1
-        self._snapshot_lgt += self._pos - p
-        self._ops[p] = rffi.cast(rffi.SHORT, self._pos - p)
-
-    def check_snapshot_jitcode_pc(self, jitcode, pc, resumedata_pos):
-        # XXX expensive?
-        assert self._ops[resumedata_pos + 1] == rffi.cast(rffi.SHORT, 
jitcode.index)
-        assert self._ops[resumedata_pos + 2] == rffi.cast(rffi.SHORT, pc)
+    def create_snapshot(self, jitcode, pc, boxes):
+        array = self._list_of_boxes(boxes)
+        return Snapshot(combine_uint(jitcode.index, pc), array)
 
     def get_iter(self):
         return TraceIterator(self, 0, self._pos)
diff --git a/rpython/jit/metainterp/pyjitpl.py 
b/rpython/jit/metainterp/pyjitpl.py
--- a/rpython/jit/metainterp/pyjitpl.py
+++ b/rpython/jit/metainterp/pyjitpl.py
@@ -70,7 +70,7 @@
         self.copy_constants(self.registers_f, jitcode.constants_f, ConstFloat)
         self._result_argcode = 'v'
         # for resume.py operation
-        self.parent_resumedata_position = -1
+        self.parent_snapshot = None
         # counter for unrolling inlined loops
         self.unroll_iterations = 1
 
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
@@ -20,36 +20,6 @@
 # because it needs to support optimize.py which encodes virtuals with
 # arbitrary cycles and also to compress the information
 
-class Snapshot(object):
-    __slots__ = ('prev', 'boxes')
-
-    def __init__(self, prev, boxes):
-        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
-    return index1 << 16 | index2 # it's ok to return signed here,
-    # we need only 32bit, but 64 is ok for now
-
-def unpack_uint(packed):
-    return (packed >> 16) & 0xffff, packed & 0xffff
-
-class FrameInfo(object):
-    __slots__ = ('prev', 'packed_jitcode_pc')
-
-    def __init__(self, prev, jitcode_index, pc):
-        self.prev = prev
-        self.packed_jitcode_pc = combine_uint(jitcode_index, pc)
-
 class VectorInfo(object):
     """
         prev: the previous VectorInfo or None
@@ -112,21 +82,19 @@
                                               self.variable,
                                               self.location)
 
-def _ensure_parent_resumedata(framestack, n, t):
+def _ensure_parent_resumedata(framestack, n, t, snapshot):
     if n == 0:
         return
-    _ensure_parent_resumedata(framestack, n - 1, t)
     target = framestack[n]
     back = framestack[n - 1]
-    if target.parent_resumedata_position != -1:
-        if not we_are_translated():
-            t.check_snapshot_jitcode_pc(back.jitcode, back.pc,
-                target.parent_resumedata_position)
-        t.record_snapshot_link(target.parent_resumedata_position)
+    if target.parent_snapshot:
+        snapshot.prev = target.parent_snapshot
         return
-    pos = t.record_snapshot(back.jitcode, back.pc,
-                            back.get_list_of_active_boxes(True))
-    target.parent_resumedata_position = pos
+    s = t.create_snapshot(back.jitcode, back.pc,
+                          back.get_list_of_active_boxes(True))
+    snapshot.prev = s
+    _ensure_parent_resumedata(framestack, n - 1, t, s)
+    target.parent_snapshot = s
 
 def capture_resumedata(framestack, virtualizable_boxes, virtualref_boxes, t):
     n = len(framestack) - 1
@@ -137,15 +105,15 @@
     else:
         virtualizable_boxes = []
     virtualref_boxes = virtualref_boxes[:]
-    pos = t.get_patchable_position()
-    t.record_list_of_boxes(virtualizable_boxes)
-    t.record_list_of_boxes(virtualref_boxes)
     if n >= 0:
         top = framestack[n]
-        _ensure_parent_resumedata(framestack, n, t)
-        t.record_snapshot(top.jitcode, top.pc,
-                          top.get_list_of_active_boxes(False))
-    t.patch_position_to_current(pos)
+        snapshot = t.create_top_snapshot(top.jitcode, top.pc,
+                    top.get_list_of_active_boxes(False), virtualizable_boxes,
+                    virtualref_boxes)
+        _ensure_parent_resumedata(framestack, n, t,snapshot)
+    else:
+        snapshot = t.create_empty_top_snapshot(
+            virtualizable_boxes, virtualref_boxes)
     return result
 
 PENDINGFIELDSTRUCT = lltype.Struct('PendingField',
@@ -198,12 +166,14 @@
 class NumberingState(object):
     def __init__(self, size):
         self.liveboxes = {}
-        self.current = []
+        self.current = [0] * size
+        self._pos = 0
         self.n = 0
         self.v = 0
 
     def append(self, item):
-        self.current.append(item)
+        self.current[self._pos] = item
+        self._pos += 1
 
 class ResumeDataLoopMemo(object):
 
@@ -256,14 +226,14 @@
 
     # env numbering
 
-    def _number_boxes(self, iter, length, optimizer, state):
+    def _number_boxes(self, iter, arr, optimizer, state):
         """ Number boxes from one snapshot
         """
         n = state.n
         v = state.v
         liveboxes = state.liveboxes
-        for i in range(length):
-            box = iter.next()
+        for item in arr:
+            box = iter.get(item)
             box = optimizer.get_box_replacement(box)
 
             if isinstance(box, Const):
@@ -291,24 +261,25 @@
 
     def number(self, optimizer, position, trace):
         snapshot_iter = trace.get_snapshot_iter(position)
-        state = NumberingState(snapshot_iter.length())
+        state = NumberingState(snapshot_iter.size)
 
-        virtualizable_length = snapshot_iter._next()
+        arr = snapshot_iter.vable_array
 
-        state.append(rffi.cast(rffi.SHORT, virtualizable_length))
-        self._number_boxes(snapshot_iter, virtualizable_length, optimizer, 
state)
+        state.append(rffi.cast(rffi.SHORT, len(arr)))
+        self._number_boxes(snapshot_iter, arr, optimizer, state)
 
-        n = snapshot_iter._next()
+        arr = snapshot_iter.vref_array
+        n = len(arr)
         assert not (n & 1)
         state.append(rffi.cast(rffi.SHORT, n >> 1))
 
-        self._number_boxes(snapshot_iter, n, optimizer, state)
+        self._number_boxes(snapshot_iter, arr, optimizer, state)
 
-        while not snapshot_iter.done():
-            size, jitcode_index, pc = snapshot_iter.get_size_jitcode_pc()
+        for snapshot in snapshot_iter.framestack:
+            jitcode_index, pc = snapshot_iter.unpack_jitcode_pc(snapshot)
             state.append(rffi.cast(rffi.SHORT, jitcode_index))
             state.append(rffi.cast(rffi.SHORT, pc))
-            self._number_boxes(snapshot_iter, size, optimizer, state)
+            self._number_boxes(snapshot_iter, snapshot.box_array, optimizer, 
state)
 
         numb = resumecode.create_numbering(state.current)
         return numb, state.liveboxes, state.v
@@ -454,7 +425,7 @@
         # make sure that nobody attached resume data to this guard yet
         assert not storage.rd_numb
         resume_position = self.guard_op.rd_resume_position
-        assert resume_position > 0
+        assert resume_position >= 0
         # count stack depth
         numb, liveboxes_from_env, v = self.memo.number(optimizer,
             resume_position, self.optimizer.trace)
diff --git a/rpython/jit/metainterp/test/strategies.py 
b/rpython/jit/metainterp/test/strategies.py
--- a/rpython/jit/metainterp/test/strategies.py
+++ b/rpython/jit/metainterp/test/strategies.py
@@ -19,7 +19,7 @@
         self.index = index
 
 class Frame(object):
-    parent_resumedata_position = -1
+    parent_snapshot = None
 
     def __init__(self, jitcode, pc, boxes):
         self.jitcode = jitcode
diff --git a/rpython/jit/metainterp/test/test_opencoder.py 
b/rpython/jit/metainterp/test/test_opencoder.py
--- a/rpython/jit/metainterp/test/test_opencoder.py
+++ b/rpython/jit/metainterp/test/test_opencoder.py
@@ -14,7 +14,7 @@
         self.index = index
 
 class FakeFrame(object):
-    parent_resumedata_position = -1
+    parent_snapshot = None
 
     def __init__(self, pc, jitcode, boxes):
         self.pc = pc
@@ -27,14 +27,17 @@
 def unpack_snapshot(t, op, pos):
     op.framestack = []
     si = t.get_snapshot_iter(op.rd_resume_position)
-    virtualizables = si.get_list_of_boxes()
-    vref_boxes = si.get_list_of_boxes()
+    virtualizables = si.get_virtualizables()
+    vref_boxes = si.get_vref_boxes()
     while not si.done():
         size, jitcode, pc = si.get_size_jitcode_pc()
+        if jitcode == 2**16 - 1:
+            break
         boxes = []
         for i in range(size):
             boxes.append(si.next())
         op.framestack.append(FakeFrame(JitCode(jitcode), pc, boxes))
+    op.framestack.reverse()
     op.virtualizables = virtualizables
     op.vref_boxes = vref_boxes
 
@@ -99,27 +102,27 @@
         (i0, i1, i2), l, iter = self.unpack(t)
         pos = l[0].rd_resume_position
         snapshot_iter = iter.get_snapshot_iter(pos)
-        assert snapshot_iter.get_list_of_boxes() == []
-        assert snapshot_iter.get_list_of_boxes() == []
+        assert snapshot_iter.get_virtualizables() == []
+        assert snapshot_iter.get_vref_boxes() == []
+        size, jc_index, pc = snapshot_iter.get_size_jitcode_pc()
+        assert size == 2
+        assert jc_index == 4
+        assert pc == 3
+        assert [snapshot_iter.next() for i in range(2)] == [i2, i2]
         size, jc_index, pc = snapshot_iter.get_size_jitcode_pc()
         assert size == 2
         assert jc_index == 2
         assert pc == 1
         assert [snapshot_iter.next() for i in range(2)] == [i0, i1]
+        pos = l[1].rd_resume_position
+        snapshot_iter = iter.get_snapshot_iter(pos)
+        assert snapshot_iter.get_virtualizables() == []
+        assert snapshot_iter.get_vref_boxes() == []
         size, jc_index, pc = snapshot_iter.get_size_jitcode_pc()
         assert size == 2
         assert jc_index == 4
         assert pc == 3
         assert [snapshot_iter.next() for i in range(2)] == [i2, i2]
-        pos = l[1].rd_resume_position
-        snapshot_iter = iter.get_snapshot_iter(pos)
-        assert snapshot_iter.get_list_of_boxes() == []
-        assert snapshot_iter.get_list_of_boxes() == []
-        size, jc_index, pc = snapshot_iter.get_size_jitcode_pc()
-        assert size == 2
-        assert jc_index == 2
-        assert pc == 1
-        assert [snapshot_iter.next() for i in range(2)] == [i0, i1]
 
     @given(lists_of_operations())
     def test_random_snapshot(self, lst):
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to