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