Author: fijal
Branch: jit-leaner-frontend
Changeset: r82935:ca0177a1db3a
Date: 2016-03-10 13:28 +0200
http://bitbucket.org/pypy/pypy/changeset/ca0177a1db3a/

Log:    lots of random progress + implement virtualref and virtualizable
        support

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
@@ -431,13 +431,13 @@
         box = inputargs[i]
         opnum = OpHelpers.getfield_for_descr(descr)
         emit_op(extra_ops,
-                ResOperation(opnum, [vable_box], descr))
+                ResOperation(opnum, [vable_box], descr=descr))
         box.set_forwarded(extra_ops[-1])
         i += 1
     arrayindex = 0
     for descr in vinfo.array_field_descrs:
         arraylen = vinfo.get_array_length(vable, arrayindex)
-        arrayop = ResOperation(rop.GETFIELD_GC_R, [vable_box], descr)
+        arrayop = ResOperation(rop.GETFIELD_GC_R, [vable_box], descr=descr)
         emit_op(extra_ops, arrayop)
         arraydescr = vinfo.array_descrs[arrayindex]
         assert i + arraylen <= len(inputargs)
@@ -1005,7 +1005,7 @@
 
 def compile_trace(metainterp, resumekey, runtime_boxes):
     """Try to compile a new bridge leading from the beginning of the history
-    to some existing place.
+    to some existging place.
     """
 
     from rpython.jit.metainterp.optimizeopt import optimize_trace
diff --git a/rpython/jit/metainterp/logger.py b/rpython/jit/metainterp/logger.py
--- a/rpython/jit/metainterp/logger.py
+++ b/rpython/jit/metainterp/logger.py
@@ -15,11 +15,15 @@
     def log_loop_from_trace(self, trace, memo):
         if not have_debug_prints():
             return
+        inputargs, ops = self._unpack_trace(trace)
+        self.log_loop(inputargs, ops, memo=memo)
+
+    def _unpack_trace(self, trace):
         ops = []
         i = trace.get_iter()
         while not i.done():
             ops.append(i.next())
-        self.log_loop(i.inputargs, ops, memo=memo)
+        return i.inputargs, ops
 
     def log_loop(self, inputargs, operations, number=0, type=None,
                  ops_offset=None, name='', memo=None):
@@ -91,8 +95,11 @@
         debug_stop("jit-log-short-preamble")
         return logops
 
-    def log_abort_loop(self, inputargs, operations, memo=None):
+    def log_abort_loop(self, trace, memo=None):
         debug_start("jit-abort-log")
+        if not have_debug_prints():
+            return
+        inputargs, operations = self._unpack_trace(trace)
         logops = self._log_operations(inputargs, operations, ops_offset=None,
                                       memo=memo)
         debug_stop("jit-abort-log")
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
@@ -1,5 +1,10 @@
 
 """ Storage format:
+for each operation (inputargs numbered with negative numbers)
+<opnum> [size-if-unknown-arity] [<arg0> <arg1> ...] [descr] [potential 
snapshot]
+snapshot is as follows
+<total size of snapshot> <virtualizable size> <virtualizable boxes>
+<virtualref size> <virtualref boxes> [<size> <jitcode> <pc> <boxes...> ...]
 """
 
 from rpython.jit.metainterp.history import ConstInt, Const
@@ -57,6 +62,13 @@
             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
+
 class TraceIterator(object):
     def __init__(self, trace, start, end, force_inputargs=None):
         self.trace = trace
@@ -251,6 +263,11 @@
             self._ops.append(self._encode(box)) # not tagged, as it must be 
boxes
         return pos
 
+    def record_list_of_boxes(self, boxes):
+        self._ops.append(len(boxes))
+        for box in boxes:
+            self._ops.append(self._encode(box))
+
     def get_patchable_position(self):
         p = len(self._ops)
         if not we_are_translated():
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
@@ -1619,8 +1619,8 @@
             self.metainterp.vrefs_after_residual_call()
             vablebox = None
             if assembler_call:
-                vablebox, resbox = 
self.metainterp.direct_assembler_call(resbox,
-                    assembler_call_jd, cut_pos)
+                vablebox, resbox = self.metainterp.direct_assembler_call(
+                    self.metainterp._last_op, assembler_call_jd, cut_pos)
             if resbox and resbox.type != 'v':
                 self.make_result_of_lastop(resbox)
             self.metainterp.vable_after_residual_call(funcbox)
@@ -1893,6 +1893,7 @@
     cancel_count = 0
     exported_state = None
     last_exc_box = None
+    _last_op = None
 
     def __init__(self, staticdata, jitdriver_sd):
         self.staticdata = staticdata
@@ -1949,7 +1950,7 @@
             self.current_call_id += 1
         if greenkey is not None and self.is_main_jitcode(jitcode):
             self.portal_trace_positions.append(
-                    (jitcode.jitdriver_sd, greenkey, 
len(self.history.operations)))
+                    (jitcode.jitdriver_sd, greenkey, 
self.history.get_trace_position()))
         if len(self.free_frames_list) > 0:
             f = self.free_frames_list.pop()
         else:
@@ -1976,7 +1977,7 @@
             self.call_ids.pop()
         if frame.greenkey is not None and self.is_main_jitcode(jitcode):
             self.portal_trace_positions.append(
-                    (jitcode.jitdriver_sd, None, len(self.history.operations)))
+                    (jitcode.jitdriver_sd, None, 
self.history.get_trace_position()))
         # we save the freed MIFrames to avoid needing to re-create new
         # MIFrame objects all the time; they are a bit big, with their
         # 3*256 register entries.
@@ -2162,6 +2163,7 @@
         profiler.count_ops(opnum, Counters.RECORDED_OPS)
         self.heapcache.invalidate_caches(opnum, descr, argboxes)
         op = self.history.record(opnum, argboxes, resvalue, descr)
+        self._last_op = op
         self.attach_debug_info(op)
         if op.type != 'v':
             return op
@@ -2962,7 +2964,7 @@
             else:
                 jitdriver_sd, greenkey, startpos = start_stack.pop()
                 warmstate = jitdriver_sd.warmstate
-                size = pos - startpos
+                size = pos[0] - startpos[0]
                 if size > max_size:
                     if warmstate is not None:
                         r = warmstate.get_location_str(greenkey)
@@ -2982,8 +2984,7 @@
                 max_jdsd = jitdriver_sd
                 max_key = key
         if self.portal_trace_positions: # tests
-            self.staticdata.logger_ops.log_abort_loop(self.history.inputargs,
-                                       self.history.operations,
+            self.staticdata.logger_ops.log_abort_loop(self.history.trace,
                                        self.box_names_memo)
         debug_stop("jit-abort-longest-function")
         return max_jdsd, max_key
@@ -3028,9 +3029,10 @@
         opnum = OpHelpers.call_assembler_for_descr(op.getdescr())
         oldop = op
         op = self.history.record_nospec(opnum, args, descr=token)
-        op.copy_value_from(oldop)
         if opnum == rop.CALL_ASSEMBLER_N:
             op = None
+        else:
+            op.copy_value_from(oldop)
         #
         # To fix an obscure issue, make sure the vable stays alive
         # longer than the CALL_ASSEMBLER operation.  We do it by
diff --git a/rpython/jit/metainterp/resoperation.py 
b/rpython/jit/metainterp/resoperation.py
--- a/rpython/jit/metainterp/resoperation.py
+++ b/rpython/jit/metainterp/resoperation.py
@@ -110,7 +110,7 @@
     return VecOperationNew(opnum, args, datatype, bytesize, signed, count, 
descr)
 
 def VecOperationNew(opnum, args, datatype, bytesize, signed, count, 
descr=None):
-    op = ResOperation(opnum, args, descr)
+    op = ResOperation(opnum, args, descr=descr)
     vecinfo = VectorizationInfo(None)
     vecinfo.setinfo(datatype, bytesize, signed)
     vecinfo.count = count
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
@@ -136,18 +136,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]
-        pos = t.get_patchable_position()
         _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)
-    else:
-        yyy
-        snapshot_storage.rd_frame_info_list = None
-        snapshot_storage.rd_snapshot = TopSnapshot(None, virtualref_boxes,
-                                                   virtualizable_boxes)
+    t.patch_position_to_current(pos)
     return result
 
 PENDINGFIELDSTRUCT = lltype.Struct('PendingField',
@@ -295,25 +292,16 @@
         snapshot_iter = trace.get_snapshot_iter(position)
         state = NumberingState(snapshot_iter.length())
 
-        state.append(rffi.cast(rffi.SHORT, 0))
-        n = 0 # len(topsnapshot.boxes)
+        virtualizable_length = snapshot_iter._next()
+
+        state.append(rffi.cast(rffi.SHORT, virtualizable_length))
+        self._number_boxes(snapshot_iter, virtualizable_length, optimizer, 
state)
+
+        n = snapshot_iter._next()
         assert not (n & 1)
         state.append(rffi.cast(rffi.SHORT, n >> 1))
-        #
-        # XXX ignore vables and virtualrefs for now
-        #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
+        self._number_boxes(snapshot_iter, n, optimizer, state)
 
         while not snapshot_iter.done():
             size, jitcode_index, pc = snapshot_iter.get_size_jitcode_pc()
diff --git a/rpython/jit/metainterp/test/test_compile.py 
b/rpython/jit/metainterp/test/test_compile.py
--- a/rpython/jit/metainterp/test/test_compile.py
+++ b/rpython/jit/metainterp/test/test_compile.py
@@ -31,6 +31,9 @@
     def log_loop(self, inputargs, operations, number=0, type=None, 
ops_offset=None, name='', memo=None):
         pass
 
+    def log_loop_from_trace(self, *args, **kwds):
+        pass
+
     def repr_of_resop(self, op):
         return repr(op)
 
@@ -91,11 +94,13 @@
     metainterp.staticdata = staticdata
     metainterp.cpu = cpu
     metainterp.history = History()
-    metainterp.history.operations = loop.operations[:-1]
-    metainterp.history.inputargs = loop.inputargs[:]
+    metainterp.history.set_inputargs(loop.inputargs[:])
+    for op in loop.operations:
+        newop = metainterp.history.record_nospec(op.getopnum(), 
op.getarglist(), op.getdescr())
+        op.position = newop.position
     #
     greenkey = 'faked'
-    target_token = compile_loop(metainterp, greenkey, 0,
+    target_token = compile_loop(metainterp, greenkey, (0, 0),
                                 loop.inputargs,
                                 loop.operations[-1].getarglist(),
                                 None)
diff --git a/rpython/jit/metainterp/test/test_history.py 
b/rpython/jit/metainterp/test/test_history.py
--- a/rpython/jit/metainterp/test/test_history.py
+++ b/rpython/jit/metainterp/test/test_history.py
@@ -62,17 +62,6 @@
     assert c5.nonnull()
     assert c6.nonnull()
 
-class TestHistoryEncoding(object):
-    def test_encode_basic(self):
-        history = History()
-        i0 = InputArgInt()
-        i1 = InputArgInt()
-        history.set_inputargs([i0, i1])
-        history.record(rop.INT_ADD, [i0, i1], 13)
-        rh = history.get_recorded_history()
-        op = rh.get_next_op()
-        assert op.getopnum() == rop.INT_ADD
-
 class TestZTranslated(StandaloneTests):
     def test_ztranslated_same_constant_float(self):
         def fn(args):
diff --git a/rpython/jit/metainterp/test/test_jitiface.py 
b/rpython/jit/metainterp/test/test_jitiface.py
--- a/rpython/jit/metainterp/test/test_jitiface.py
+++ b/rpython/jit/metainterp/test/test_jitiface.py
@@ -18,12 +18,12 @@
         reasons = []
 
         class MyJitIface(JitHookInterface):
-            def on_abort(self, reason, jitdriver, greenkey, greenkey_repr, 
logops, operations):
+            def on_abort(self, reason, jitdriver, greenkey, greenkey_repr, 
logops, trace):
                 assert jitdriver is myjitdriver
                 assert len(greenkey) == 1
                 reasons.append(reason)
                 assert greenkey_repr == 'blah'
-                assert len(operations) > 1
+                assert trace.length() > 1
 
         iface = MyJitIface()
 
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
@@ -6,7 +6,7 @@
 from rpython.jit.metainterp import resume
 from rpython.jit.metainterp.test.strategies import lists_of_operations
 from rpython.jit.metainterp.optimizeopt.test.test_util import BaseTest
-from rpython.jit.metainterp.history import TreeLoop
+from rpython.jit.metainterp.history import TreeLoop, AbstractDescr
 from hypothesis import given
 
 class JitCode(object):
@@ -24,19 +24,19 @@
     def get_list_of_active_boxes(self, flag):
         return self.boxes
 
-def unpack_snapshot(t, pos):
-    trace = t.trace
-    first = trace._ops[pos] # this is the size
-    pos += 1
-    boxes = []
-    while first > pos + 1:
-        snapshot_size = trace._ops[pos]
-        # 2 for jitcode and pc
-        pos += 1 + 2
-        boxes += [t._untag(trace._ops[i + pos]) for i in range(snapshot_size)]
-        pos += len(boxes)
-    return boxes
-
+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()
+    while not si.done():
+        size, jitcode, pc = si.get_size_jitcode_pc()
+        boxes = []
+        for i in range(size):
+            boxes.append(si.next())
+        op.framestack.append(FakeFrame(JitCode(jitcode), pc, boxes))
+    op.virtualizables = virtualizables
+    op.vref_boxes = vref_boxes
 
 class TestOpencoder(object):
     def unpack(self, t):
@@ -45,14 +45,7 @@
         while not iter.done():
             op = iter.next()
             if op.is_guard():
-                op.framestack = []
-                si = iter.get_snapshot_iter(op.rd_resume_position)
-                while not si.done():
-                    size, jitcode, pc = si.get_size_jitcode_pc()
-                    boxes = []
-                    for i in range(size):
-                        boxes.append(si.next())
-                    op.framestack.append(FakeFrame(JitCode(jitcode), pc, 
boxes))
+                unpack_snapshot(iter, op, op.rd_resume_position)
             l.append(op)
         return iter.inputargs, l, iter
 
@@ -82,18 +75,17 @@
         resume.capture_resumedata(framestack, None, [], t)
         (i0, i1), l, iter = self.unpack(t)
         assert l[1].opnum == rop.GUARD_FALSE
-        boxes = unpack_snapshot(iter, l[1].rd_resume_position)
-        assert boxes == [i0, i1]
+        assert l[1].framestack[0].boxes == [i0, i1]
         t.record_op(rop.GUARD_FALSE, [add])
         resume.capture_resumedata([frame0, frame1], None, [], t)
         t.record_op(rop.INT_ADD, [add, add])
         (i0, i1), l, iter = self.unpack(t)
         assert l[1].opnum == rop.GUARD_FALSE
-        boxes = unpack_snapshot(iter, l[1].rd_resume_position)
-        assert boxes == [i0, i1]
+        assert l[1].framestack[0].boxes == [i0, i1]
         assert l[2].opnum == rop.GUARD_FALSE
-        boxes = unpack_snapshot(iter, l[2].rd_resume_position)
-        assert boxes == [i0, i1, i0, i0, l[0]]
+        fstack = l[2].framestack
+        assert fstack[0].boxes == [i0, i1]
+        assert fstack[1].boxes == [i0, i0, l[0]]
 
     def test_read_snapshot_interface(self):
         i0, i1, i2 = InputArgInt(), InputArgInt(), InputArgInt()
@@ -107,6 +99,8 @@
         (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() == []
         size, jc_index, pc = snapshot_iter.get_size_jitcode_pc()
         assert size == 2
         assert jc_index == 2
@@ -119,6 +113,8 @@
         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
@@ -158,4 +154,18 @@
         t2 = t.cut_trace_from(cut_point, [add1, i1])
         (i0, i1), l, iter = self.unpack(t2)
         assert len(l) == 3
-        assert l[0].getarglist() == [i0, i1]
\ No newline at end of file
+        assert l[0].getarglist() == [i0, i1]
+
+    def test_virtualizable_virtualref(self):
+        class SomeDescr(AbstractDescr):
+            pass
+
+        i0, i1, i2 = InputArgInt(), InputArgInt(), InputArgInt()
+        t = Trace([i0, i1, i2])
+        p0 = t.record_op(rop.NEW_WITH_VTABLE, [], descr=SomeDescr())
+        t.record_op(rop.GUARD_TRUE, [i0])
+        resume.capture_resumedata([], [i1, i2, p0], [p0, i1], t)
+        (i0, i1, i2), l, iter = self.unpack(t)
+        assert not l[1].framestack
+        assert l[1].virtualizables == [l[0], i1, i2]
+        assert l[1].vref_boxes == [l[0], i1]
\ No newline at end of file
diff --git a/rpython/jit/metainterp/test/test_pyjitpl.py 
b/rpython/jit/metainterp/test/test_pyjitpl.py
--- a/rpython/jit/metainterp/test/test_pyjitpl.py
+++ b/rpython/jit/metainterp/test/test_pyjitpl.py
@@ -87,6 +87,7 @@
     c3 = ConstInt(3)
     boxes = [b1, b2, b1, c3]
     dup = {}
+    metainterp.history.set_inputargs([b1, b2])
     metainterp.remove_consts_and_duplicates(boxes, 4, dup)
     assert boxes[0] is b1
     assert boxes[1] is b2
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to