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
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit