[pypy-svn] r62048 - in pypy/branch/pyjitpl5/pypy/jit/metainterp: . test
fijal at codespeak.net
fijal at codespeak.net
Fri Feb 20 13:54:38 CET 2009
Author: fijal
Date: Fri Feb 20 13:54:36 2009
New Revision: 62048
Modified:
pypy/branch/pyjitpl5/pypy/jit/metainterp/graphpage.py
pypy/branch/pyjitpl5/pypy/jit/metainterp/heaptracker.py
pypy/branch/pyjitpl5/pypy/jit/metainterp/optimize.py
pypy/branch/pyjitpl5/pypy/jit/metainterp/pyjitpl.py
pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_basic.py
pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_dlist.py
pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimize.py
pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_slist.py
pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_vable_optimize.py
pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_virtualizable.py
pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_warmspot.py
pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_zrpy_basic.py
pypy/branch/pyjitpl5/pypy/jit/metainterp/warmspot.py
Log:
A bit of progress, more specific:
* Fix virtual lists to work
* Disable lazy lists, for various reasons
* Progress towards rpythonization
Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/graphpage.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/metainterp/graphpage.py (original)
+++ pypy/branch/pyjitpl5/pypy/jit/metainterp/graphpage.py Fri Feb 20 13:54:36 2009
@@ -68,10 +68,10 @@
_prev = Box._extended_display
try:
Box._extended_display = False
- if len(self.graphs) > 1:
- graphs = self.graphs[1:]
- else:
- graphs = self.graphs
+ #if len(self.graphs) > 1:
+ # graphs = self.graphs[1:]
+ #else:
+ graphs = self.graphs
for i, graph in enumerate(graphs):
self.gengraph(graph, i)
finally:
Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/heaptracker.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/metainterp/heaptracker.py (original)
+++ pypy/branch/pyjitpl5/pypy/jit/metainterp/heaptracker.py Fri Feb 20 13:54:36 2009
@@ -63,6 +63,21 @@
# structures in case they are GcStruct inheriting from OBJECT.
testing_gcstruct2vtable[GCSTRUCT] = vtable
+def populate_type_cache(graphs, cpu):
+ cache = {}
+ for graph in graphs:
+ for block in graph.iterblocks():
+ for op in block.operations:
+ if op.opname == 'malloc':
+ STRUCT = op.args[0].value
+ if isinstance(STRUCT, lltype.GcStruct):
+ vtable = get_vtable_for_gcstruct(cpu, STRUCT)
+ if vtable:
+ vt = cpu.cast_adr_to_int(
+ llmemory.cast_ptr_to_adr(vtable))
+ cache[vt] = cpu.sizeof(STRUCT)
+ return cache
+
testing_gcstruct2vtable = {}
# ____________________________________________________________
@@ -86,7 +101,7 @@
for guard in ['guard_no_exception', 'guard_true',
'guard_false', 'guard_value', 'guard_class']:
- always_pure_operations[guard] = True
- operation_never_raises[guard] = True
+ always_pure_operations[guard] = None
+ operation_never_raises[guard] = None
setup()
Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/optimize.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/metainterp/optimize.py (original)
+++ pypy/branch/pyjitpl5/pypy/jit/metainterp/optimize.py Fri Feb 20 13:54:36 2009
@@ -54,9 +54,9 @@
assert isinstance(ld, ListDescr)
alloc_offset = len(self.list_allocations)
malloc_func = ld.malloc_func
- assert instnode.known_length != -1
+ assert instnode.cursize != -1
self.list_allocations.append((malloc_func,
- instnode.known_length))
+ instnode.cursize))
res = (alloc_offset + 1) << 16
else:
alloc_offset = len(self.allocations)
@@ -69,7 +69,7 @@
if isinstance(instnode.cls.source, ListDescr):
ld = instnode.cls.source
x = (alloc_offset + 1) << 16
- assert ofs < instnode.known_length
+ assert ofs < instnode.cursize
self.setitems.append((ld.setfunc, x, ofs, num))
else:
self.setfields.append((alloc_offset, ofs, num))
@@ -87,11 +87,6 @@
liveboxes.append(box)
return res
-class TypeCache(object):
- pass
-type_cache = TypeCache() # XXX remove me later
-type_cache.class_size = {}
-
class InstanceNode(object):
def __init__(self, source, escaped=True, startbox=False, const=False):
if isinstance(source, Const):
@@ -108,18 +103,8 @@
self.cleanfields = {}
self.dirtyfields = {}
self.expanded_fields = {}
- self.known_length = -1
-
- def set_known_length(self, val):
- if val != -1:
- print "Setting: %r to %d" % (self, val)
- assert val >= -1
- self._kl = val
-
- def get_known_length(self):
- return self._kl
-
- known_length = property(get_known_length, set_known_length)
+ self.origsize = -1
+ self.cursize = -1
def escape_if_startbox(self, memo):
if self in memo:
@@ -155,8 +140,11 @@
return FixedClassSpecNode(known_class)
if not other.escaped:
if (isinstance(known_class, ListDescr)
- and self.known_length != other.known_length):
- XXX # XXX think
+ and self.cursize != other.origsize):
+ # or DelayedListSpecNode, later on
+ self.escaped = True
+ other.escaped = True
+ return FixedListSpecNode(known_class)
fields = []
if self is other:
d = other.curfields.copy()
@@ -174,7 +162,7 @@
fields.append((ofs, specnode))
if isinstance(known_class, ListDescr):
return VirtualListSpecNode(known_class, fields,
- other.known_length)
+ other.cursize)
return VirtualInstanceSpecNode(known_class, fields)
if not other.virtualized and self.expanded_fields:
fields = []
@@ -285,15 +273,17 @@
self.dependency_graph.append((instnode, fieldnode))
instnode.origfields[field] = fieldnode
self.nodes[box] = fieldnode
- #if self.first_escaping_op:
- # instnode.expanded_fields[field] = None
+ if (self.first_escaping_op and
+ instnode.cls and
+ not isinstance(instnode.cls.source, ListDescr)):
+ instnode.expanded_fields[field] = None
def find_nodes_insert(self, instnode, field, fieldnode):
for ofs, node in instnode.curfields.items():
if ofs >= field:
instnode.curfields[ofs + 1] = node
instnode.curfields[field] = fieldnode
- instnode.known_length = instnode.known_length + 1
+ instnode.cursize += 1
self.dependency_graph.append((instnode, fieldnode))
def find_nodes(self):
@@ -319,7 +309,9 @@
self.first_escaping_op = False
if (isinstance(op.args[1], ConstInt) or
self.nodes[op.args[1]].const):
- instnode.known_length = self.getsource(op.args[1]).getint()
+ size = self.getsource(op.args[1]).getint()
+ instnode.cursize = size
+ instnode.origsize = size
# XXX following guard_builtin will set the
# correct class, otherwise it's a mess
continue
@@ -329,9 +321,12 @@
instnode.cls = InstanceNode(op.args[1])
continue
elif opname == 'guard_len':
- if instnode.known_length == -1:
+ instnode = self.nodes[op.args[0]]
+ if instnode.cursize == -1:
instnode = self.nodes[op.args[0]]
- instnode.known_length = op.args[1].getint()
+ size = op.args[1].getint()
+ instnode.cursize = size
+ instnode.origsize = size
continue
elif opname == 'setfield_gc':
instnode = self.getnode(op.args[0])
@@ -356,10 +351,9 @@
self.nodes[op.args[2]].const):
field = self.getsource(fieldbox).getint()
if field < 0:
- field = instnode.known_length + field
+ field = instnode.cursize + field
box = op.results[0]
self.find_nodes_getfield(instnode, field, box)
- print instnode, instnode.curfields, instnode.known_length
continue
else:
instnode.escaped = True
@@ -369,36 +363,33 @@
elif opname == 'append':
instnode = self.getnode(op.args[1])
assert isinstance(instnode.cls.source, ListDescr)
- if instnode.known_length != -1:
- field = instnode.known_length
- instnode.known_length = instnode.known_length + 1
+ if instnode.cursize != -1:
+ field = instnode.cursize
+ instnode.cursize += 1
self.find_nodes_setfield(instnode, field,
self.getnode(op.args[2]))
- print instnode, instnode.curfields, instnode.known_length
continue
elif opname == 'insert':
instnode = self.getnode(op.args[1])
assert isinstance(instnode.cls.source, ListDescr)
- if instnode.known_length != -1:
+ if instnode.cursize != -1:
fieldbox = self.getsource(op.args[2])
assert isinstance(fieldbox, Const) or fieldbox.const
field = fieldbox.getint()
if field < 0:
- field = instnode.known_length + field
+ field = instnode.cursize + field
self.find_nodes_insert(instnode, field,
self.getnode(op.args[3]))
- print instnode, instnode.curfields, instnode.known_length
continue
elif opname == 'pop':
instnode = self.getnode(op.args[1])
assert isinstance(instnode.cls.source, ListDescr)
- if instnode.known_length != -1:
- instnode.known_length = instnode.known_length - 1
- field = instnode.known_length
+ if instnode.cursize != -1:
+ instnode.cursize -= 1
+ field = instnode.cursize
self.find_nodes_getfield(instnode, field, op.results[0])
if field in instnode.curfields:
del instnode.curfields[field]
- print instnode, instnode.curfields, instnode.known_length
continue
self.nodes[op.results[0]] = InstanceNode(op.results[0],
escaped=True)
@@ -408,7 +399,7 @@
elif opname == 'len' or opname == 'listnonzero':
instnode = self.getnode(op.args[1])
if not instnode.escaped:
- assert instnode.known_length != -1
+ assert instnode.cursize != -1
lgtbox = op.results[0].constbox()
self.nodes[op.results[0]] = InstanceNode(lgtbox, const=True)
continue
@@ -419,11 +410,10 @@
or self.nodes[op.args[2]].const):
field = self.getsource(fieldbox).getint()
if field < 0:
- field = instnode.known_length + field
- assert field < instnode.known_length
+ field = instnode.cursize + field
+ assert field < instnode.cursize
self.find_nodes_setfield(instnode, field,
self.getnode(op.args[3]))
- print "XXX", instnode, " <- ", self.getnode(fieldbox)
continue
else:
self.dependency_graph.append((instnode,
@@ -571,7 +561,7 @@
def optimize_getfield(self, instnode, ofs, box):
if instnode.virtual or instnode.virtualized:
if ofs < 0:
- ofs = instnode.known_length + ofs
+ ofs = instnode.cursize + ofs
assert ofs in instnode.curfields
return True # this means field is never actually
elif ofs in instnode.cleanfields:
@@ -584,7 +574,7 @@
def optimize_setfield(self, instnode, ofs, valuenode, valuebox):
if instnode.virtual or instnode.virtualized:
if ofs < 0:
- ofs = instnode.known_length + ofs
+ ofs = instnode.cursize + ofs
instnode.curfields[ofs] = valuenode
else:
assert not valuenode.virtual
@@ -598,7 +588,7 @@
if ofs >= field:
instnode.curfields[ofs + 1] = node
instnode.curfields[field] = valuenode
- instnode.known_length = instnode.known_length + 1
+ instnode.cursize += 1
def optimize_loop(self):
self.ready_results = {}
@@ -655,9 +645,10 @@
elif opname == 'guard_len':
# it should be completely gone, because if it escapes
# we don't virtualize it anymore
- if not instnode.escaped and instnode.known_length == -1:
+ instnode = self.nodes[op.args[0]]
+ if not instnode.escaped and instnode.cursize == -1:
instnode = self.nodes[op.args[0]]
- instnode.known_length = op.args[1].getint()
+ instnode.cursize = op.args[1].getint()
continue
elif opname == 'guard_nonvirtualized':
instnode = self.nodes[op.args[0]]
@@ -702,9 +693,6 @@
if not instnode.escaped:
instnode.virtual = True
assert instnode.cls is not None
- size = op.args[0].getint()
- key = instnode.cls.source.getint()
- type_cache.class_size[key] = size
continue
elif opname == 'newlist':
instnode = self.nodes[op.results[0]]
@@ -712,9 +700,9 @@
if not instnode.escaped:
instnode.virtual = True
valuesource = self.getsource(op.args[2])
- instnode.known_length = op.args[1].getint()
+ instnode.cursize = op.args[1].getint()
curfields = {}
- for i in range(instnode.known_length):
+ for i in range(instnode.cursize):
curfields[i] = InstanceNode(valuesource,
const=True)
instnode.curfields = curfields
@@ -723,8 +711,8 @@
instnode = self.nodes[op.args[1]]
valuenode = self.getnode(op.args[2])
if not instnode.escaped:
- ofs = instnode.known_length
- instnode.known_length = instnode.known_length + 1
+ ofs = instnode.cursize
+ instnode.cursize += 1
self.optimize_setfield(instnode, ofs, valuenode, op.args[2])
continue
elif opname == 'insert':
@@ -737,8 +725,8 @@
elif opname == 'pop':
instnode = self.nodes[op.args[1]]
if not instnode.escaped:
- instnode.known_length = instnode.known_length - 1
- ofs = instnode.known_length
+ instnode.cursize -= 1
+ ofs = instnode.cursize
if self.optimize_getfield(instnode, ofs, op.results[0]):
del instnode.curfields[ofs]
continue
@@ -859,16 +847,14 @@
return allocated_lists[(index - 1) >> 16]
return allocated_boxes[index]
-def rebuild_boxes_from_guard_failure(guard_op, history, boxes_from_frame):
+def rebuild_boxes_from_guard_failure(guard_op, metainterp, boxes_from_frame):
allocated_boxes = []
allocated_lists = []
storage = guard_op.storage_info
+ history = metainterp.history
for vtable in storage.allocations:
- # XXX virtual object that came from the outside (stored on
- # a virtualizable) has no entry in type_cache, probably
- # we need to attach some info to guard_class
- sizebox = ConstInt(type_cache.class_size[vtable])
+ sizebox = ConstInt(metainterp.class_sizes[vtable])
vtablebox = ConstInt(vtable)
[instbox] = history.execute_and_record('new_with_vtable',
[sizebox, vtablebox],
Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/pyjitpl.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/metainterp/pyjitpl.py (original)
+++ pypy/branch/pyjitpl5/pypy/jit/metainterp/pyjitpl.py Fri Feb 20 13:54:36 2009
@@ -10,7 +10,8 @@
from pypy.jit.metainterp.history import (Const, ConstInt, ConstPtr, Box,
BoxInt, BoxPtr, GuardOp)
from pypy.jit.metainterp.compile import compile_new_loop, compile_new_bridge
-from pypy.jit.metainterp.heaptracker import get_vtable_for_gcstruct
+from pypy.jit.metainterp.heaptracker import (get_vtable_for_gcstruct,
+ populate_type_cache)
from pypy.jit.metainterp import codewriter, optimize
# ____________________________________________________________
@@ -492,7 +493,7 @@
def generate_merge_point(self, pc, varargs):
if isinstance(self.metainterp.history, history.BlackHole):
raise self.metainterp.ContinueRunningNormally(varargs)
- num_green_args = self.metainterp.warmrunnerdesc.num_green_args
+ num_green_args = self.metainterp.num_green_args
for i in range(num_green_args):
varargs[i] = self.implement_guard_value(pc, varargs[i])
@@ -659,8 +660,9 @@
class OOMetaInterp(object):
+ num_green_args = 0
- def __init__(self, portal_graph, cpu, stats, specialize):
+ def __init__(self, portal_graph, graphs, cpu, stats, specialize):
self.portal_graph = portal_graph
self.cpu = cpu
self.stats = stats
@@ -675,7 +677,9 @@
self.builtins_keys = []
self.builtins_values = []
self.builtins_seen = {}
-
+
+ self.class_sizes = populate_type_cache(graphs, self.cpu)
+
self._virtualizabledescs = {}
def generate_bytecode(self, policy):
@@ -772,7 +776,7 @@
self.jump_after_guard_failure(guard_failure, loop, resargs)
def designate_target_loop(self, gmp, loop):
- num_green_args = self.warmrunnerdesc.num_green_args
+ num_green_args = self.num_green_args
residual_args = self.get_residual_args(loop,
gmp.argboxes[num_green_args:])
return (loop, residual_args)
@@ -784,7 +788,7 @@
i, residual_args[i])
def compile(self, original_boxes, live_arg_boxes):
- num_green_args = self.warmrunnerdesc.num_green_args
+ num_green_args = self.num_green_args
for i in range(num_green_args):
box1 = original_boxes[i]
box2 = live_arg_boxes[i]
@@ -803,7 +807,7 @@
return loop
def compile_bridge(self, guard_failure, original_boxes, live_arg_boxes):
- num_green_args = self.warmrunnerdesc.num_green_args
+ num_green_args = self.num_green_args
mp = history.ResOperation('catch', original_boxes, [])
mp.coming_from = guard_failure.guard_op
self.history.operations.insert(0, mp)
@@ -833,7 +837,7 @@
def initialize_state_from_start(self, args):
self.create_empty_history()
- num_green_args = self.warmrunnerdesc.num_green_args
+ num_green_args = self.num_green_args
original_boxes = []
for i in range(len(args)):
value = args[i]
@@ -851,7 +855,7 @@
def initialize_state_from_guard_failure(self, guard_failure):
# guard failure: rebuild a complete MIFrame stack
- if self.warmrunnerdesc.state.must_compile_from_failure(guard_failure):
+ if self.state.must_compile_from_failure(guard_failure):
self.history = history.History(self.cpu)
else:
self.history = history.BlackHole(self.cpu)
@@ -869,7 +873,7 @@
boxes_from_frame.append(newbox)
if guard_op.storage_info is not None:
newboxes = optimize.rebuild_boxes_from_guard_failure(
- guard_op, self.history, boxes_from_frame)
+ guard_op, self, boxes_from_frame)
else:
# xxx for tests only
newboxes = boxes_from_frame
Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_basic.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_basic.py (original)
+++ pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_basic.py Fri Feb 20 13:54:36 2009
@@ -16,7 +16,9 @@
stats = history.Stats()
cpu = CPUClass(rtyper, stats, False)
graph = rtyper.annotator.translator.graphs[0]
- return pyjitpl.OOMetaInterp(graph, cpu, stats, False), rtyper
+ metainterp = pyjitpl.OOMetaInterp(graph, [], cpu, stats, False)
+ metainterp.num_green_args = 0
+ return metainterp, rtyper
class JitMixin:
basic = True
Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_dlist.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_dlist.py (original)
+++ pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_dlist.py Fri Feb 20 13:54:36 2009
@@ -1,5 +1,6 @@
import py
+py.test.skip("turned off for now")
from pypy.rlib.jit import JitDriver
from pypy.jit.metainterp.test.test_basic import LLJitMixin, OOJitMixin
@@ -19,7 +20,7 @@
res = self.meta_interp(f, [10])
assert res == f(10)
self.check_loops(getitem=0, setitem=1, guard_exception=0,
- guard_no_exception=0)
+ guard_no_exception=1)
def test_list_escapes(self):
myjitdriver = JitDriver(greens = [], reds = ['n', 'l'])
Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimize.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimize.py (original)
+++ pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimize.py Fri Feb 20 13:54:36 2009
@@ -10,7 +10,7 @@
Jump, GuardOp)
from pypy.jit.metainterp.optimize import (PerfectSpecializer,
CancelInefficientLoop, VirtualInstanceSpecNode, FixedClassSpecNode,
- rebuild_boxes_from_guard_failure, type_cache, AllocationStorage,
+ rebuild_boxes_from_guard_failure, AllocationStorage,
NotSpecNode)
cpu = runner.CPU(None)
@@ -74,6 +74,7 @@
ofs_next = runner.CPU.fielddescrof(NODE, 'next')
ofs_value = runner.CPU.fielddescrof(NODE, 'value')
size_of_node = runner.CPU.sizeof(NODE)
+ sizebox = ConstInt(size_of_node)
#
startnode = lltype.malloc(NODE)
startnode.value = 20
@@ -88,11 +89,12 @@
sum2 = BoxInt(0 + startnode.value)
ops = [
MergePoint('merge_point', [sum, n1], []),
- ResOperation('guard_class', [n1, ConstAddr(node_vtable, cpu)], []),
+ ResOperation('guard_class', [n1, ConstAddr(node_vtable, cpu),
+ sizebox], []),
ResOperation('getfield_gc', [n1, ConstInt(ofs_value)], [v]),
ResOperation('int_sub', [v, ConstInt(1)], [v2]),
ResOperation('int_add', [sum, v], [sum2]),
- ResOperation('new_with_vtable', [ConstInt(size_of_node),
+ ResOperation('new_with_vtable', [sizebox,
ConstAddr(node_vtable, cpu)], [n2]),
ResOperation('setfield_gc', [n2, ConstInt(ofs_value), v2], []),
Jump('jump', [sum2, n2], []),
@@ -138,7 +140,8 @@
locals().update(A.__dict__) # :-)
ops = [
MergePoint('merge_point', [sum, n1], []),
- ResOperation('guard_class', [n1, ConstAddr(node_vtable, cpu)], []),
+ ResOperation('guard_class', [n1, ConstAddr(node_vtable, cpu),
+ sizebox], []),
ResOperation('escape', [n1], []),
ResOperation('getfield_gc', [n1, ConstInt(ofs_value)], [v]),
ResOperation('int_sub', [v, ConstInt(1)], [v2]),
@@ -194,7 +197,8 @@
locals().update(A.__dict__) # :-)
ops = [
MergePoint('merge_point', [sum, n1], []),
- ResOperation('guard_class', [n1, ConstAddr(node_vtable, cpu)], []),
+ ResOperation('guard_class', [n1, ConstAddr(node_vtable, cpu),
+ sizebox], []),
ResOperation('some_escaping_operation', [n1], []), # <== escaping
ResOperation('getfield_gc', [n1, ConstInt(ofs_value)], [v]),
ResOperation('int_sub', [v, ConstInt(1)], [v2]),
@@ -250,7 +254,8 @@
locals().update(A.__dict__) # :-)
ops = [
MergePoint('merge_point', [sum, n1], []),
- ResOperation('guard_class', [n1, ConstAddr(node2_vtable, cpu)], []),
+ ResOperation('guard_class', [n1, ConstAddr(node2_vtable, cpu),
+ sizebox], []),
# the only difference is different vtable ^^^^^^^^^^^^
ResOperation('getfield', [n1, ConstInt(ofs_value)], [v]),
ResOperation('int_sub', [v, ConstInt(1)], [v2]),
@@ -272,7 +277,8 @@
locals().update(A.__dict__) # :-)
ops = [
MergePoint('merge_point', [sum, n1], []),
- ResOperation('guard_class', [n1, ConstAddr(node_vtable, cpu)], []),
+ ResOperation('guard_class', [n1, ConstAddr(node_vtable, cpu),
+ sizebox], []),
ResOperation('getfield_gc', [n1, ConstInt(ofs_value)], [v]),
ResOperation('int_sub', [v, ConstInt(1)], [v2]),
ResOperation('int_add', [sum, v], [sum2]),
@@ -315,22 +321,29 @@
return ['allocated']
else:
return []
+
+ class FakeMetaInterp(object):
+ def __init__(self):
+ self.history = FakeHistory()
+ self.class_sizes = {cpu.cast_adr_to_int(node_vtable_adr):
+ E.size_of_node}
spec = PerfectSpecializer(Loop(E.ops))
spec.find_nodes()
spec.intersect_input_and_output()
spec.optimize_loop()
guard_op = spec.loop.operations[-2]
- fake_history = FakeHistory()
v_sum_b = BoxInt(13)
v_v_b = BoxInt(14)
- newboxes = rebuild_boxes_from_guard_failure(guard_op, fake_history,
- [v_sum_b, v_v_b])
vt = cpu.cast_adr_to_int(node_vtable_adr)
- assert fake_history.ops == [
- ('new_with_vtable', [ConstInt(type_cache.class_size[vt]), ConstInt(vt)]),
+ fake_metainterp = FakeMetaInterp()
+ newboxes = rebuild_boxes_from_guard_failure(guard_op, fake_metainterp,
+ [v_sum_b, v_v_b])
+ expected = [
+ ('new_with_vtable', [E.sizebox, ConstInt(vt)]),
('setfield_gc', ['allocated', ConstInt(E.ofs_value), v_v_b])
]
+ assert expected == fake_metainterp.history.ops
assert newboxes == [v_sum_b, 'allocated']
# ____________________________________________________________
@@ -345,7 +358,8 @@
vbool3 = BoxInt(1)
ops = [
MergePoint('merge_point', [sum, n1, n3], []),
- ResOperation('guard_class', [n1, ConstAddr(node_vtable, cpu)], []),
+ ResOperation('guard_class', [n1, ConstAddr(node_vtable, cpu),
+ sizebox], []),
ResOperation('getfield_gc', [n1, ConstInt(ofs_value)], [v]),
ResOperation('int_sub', [v, ConstInt(1)], [v2]),
ResOperation('int_add', [sum, v], [sum2]),
@@ -394,7 +408,8 @@
v4 = BoxInt(124)
ops = [
MergePoint('merge_point', [sum, n1], []),
- ResOperation('guard_class', [n1, ConstAddr(node_vtable, cpu)], []),
+ ResOperation('guard_class', [n1, ConstAddr(node_vtable, cpu),
+ sizebox], []),
ResOperation('getfield_gc', [n1, ConstInt(ofs_value)], [v]),
ResOperation('int_sub', [v, ConstInt(1)], [v2]),
ResOperation('int_add', [sum, v], [sum2]),
@@ -531,7 +546,8 @@
v3 = BoxInt(4)
ops = [
MergePoint('merge_point', [sum, n1], []),
- ResOperation('guard_class', [n1, ConstAddr(node_vtable, cpu)], []),
+ ResOperation('guard_class', [n1, ConstAddr(node_vtable, cpu),
+ sizebox], []),
ResOperation('getfield_gc', [n1, ConstInt(ofs_value)], [v]),
ResOperation('int_sub', [v, ConstInt(1)], [v2]),
ResOperation('int_add', [sum, v], [sum2]),
@@ -563,7 +579,8 @@
v3 = BoxInt(4)
ops = [
MergePoint('merge_point', [sum, n1], []),
- ResOperation('guard_class', [n1, ConstAddr(node_vtable, cpu)], []),
+ ResOperation('guard_class', [n1, ConstAddr(node_vtable, cpu),
+ sizebox], []),
ResOperation('getfield_gc', [n1, ConstInt(ofs_value)], [v]),
ResOperation('int_sub', [v, ConstInt(1)], [v2]),
ResOperation('int_add', [sum, v], [sum2]),
@@ -598,7 +615,8 @@
v3 = BoxInt(4)
ops = [
MergePoint('merge_point', [sum, n1], []),
- ResOperation('guard_class', [n1, ConstAddr(node_vtable, cpu)], []),
+ ResOperation('guard_class', [n1, ConstAddr(node_vtable, cpu),
+ sizebox], []),
ResOperation('getfield_gc', [n1, ConstInt(ofs_value)], [v]),
ResOperation('int_sub', [v, ConstInt(1)], [v2]),
ResOperation('int_add', [sum, v], [sum2]),
@@ -628,7 +646,8 @@
v3 = BoxInt(4)
ops = [
MergePoint('merge_point', [sum, n1], []),
- ResOperation('guard_class', [n1, ConstAddr(node_vtable, cpu)], []),
+ ResOperation('guard_class', [n1, ConstAddr(node_vtable, cpu),
+ sizebox], []),
ResOperation('getfield_gc', [n1, ConstInt(ofs_value)], [v]),
ResOperation('int_sub', [v, ConstInt(1)], [v2]),
ResOperation('int_add', [sum, v], [sum2]),
@@ -661,7 +680,8 @@
v3 = BoxInt(4)
ops = [
MergePoint('merge_point', [sum, n1], []),
- ResOperation('guard_class', [n1, ConstAddr(node_vtable, cpu)], []),
+ ResOperation('guard_class', [n1, ConstAddr(node_vtable, cpu),
+ sizebox], []),
ResOperation('getfield_gc', [n1, ConstInt(ofs_value)], [v]),
ResOperation('int_sub', [v, ConstInt(1)], [v2]),
ResOperation('int_add', [sum, v], [sum2]),
@@ -692,7 +712,8 @@
v3 = BoxInt(4)
ops = [
MergePoint('merge_point', [sum, n1], []),
- ResOperation('guard_class', [n1, ConstAddr(node_vtable, cpu)], []),
+ ResOperation('guard_class', [n1, ConstAddr(node_vtable, cpu),
+ sizebox], []),
ResOperation('getfield_gc', [n1, ConstInt(ofs_value)], [v]),
ResOperation('int_sub', [v, ConstInt(1)], [v2]),
ResOperation('int_add', [sum, v], [sum2]),
Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_slist.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_slist.py (original)
+++ pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_slist.py Fri Feb 20 13:54:36 2009
@@ -1,5 +1,4 @@
import py
-py.test.skip("unsupported list ops")
from pypy.jit.metainterp.policy import StopAtXPolicy
from pypy.jit.metainterp.test.test_basic import LLJitMixin, OOJitMixin
from pypy.rlib.jit import JitDriver, hint
@@ -20,6 +19,7 @@
assert res == 9
def test_list_operations(self):
+ py.test.skip("pop(int) not supported")
class FooBar:
def __init__(self, z):
self.z = z
Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_vable_optimize.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_vable_optimize.py (original)
+++ pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_vable_optimize.py Fri Feb 20 13:54:36 2009
@@ -166,13 +166,15 @@
locals().update(B.__dict__)
n2 = BoxPtr(lltype.cast_opaque_ptr(llmemory.GCREF, frame.node))
v2 = BoxInt(13)
+ sizebox = ConstInt(cpu.sizeof(NODE))
ops = [
MergePoint('merge_point', [fr], []),
ResOperation('guard_nonvirtualized', [fr, ConstAddr(xy_vtable, cpu),
ConstInt(ofs_node)], []),
#
ResOperation('getfield_gc', [fr, ConstInt(ofs_node)], [n1]),
- ResOperation('guard_class', [n1, ConstAddr(node_vtable, cpu)], []),
+ ResOperation('guard_class', [n1, ConstAddr(node_vtable, cpu),
+ sizebox], []),
ResOperation('getfield_gc', [n1, ConstInt(ofs_value)], [v]),
#
ResOperation('getfield_gc', [fr, ConstInt(ofs_node)], [n2]),
Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_virtualizable.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_virtualizable.py (original)
+++ pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_virtualizable.py Fri Feb 20 13:54:36 2009
@@ -145,6 +145,59 @@
res = self.meta_interp(f, [10])
assert res == f(10)
+ def test_virtual_on_virtualizable(self):
+ myjitdriver = JitDriver(greens = [], reds = ['frame', 'n'],
+ virtualizables = ['frame'])
+
+ class Stuff(object):
+ def __init__(self, x):
+ self.x = x
+
+ class Stuff2(Stuff):
+ pass
+
+ class Frame(object):
+ _virtualizable2_ = True
+ def __init__(self, x):
+ self.stuff = Stuff(x)
+
+ def f(n):
+ frame = Frame(3)
+ while n > 0:
+ myjitdriver.can_enter_jit(frame=frame, n=n)
+ myjitdriver.jit_merge_point(frame=frame, n=n)
+ if isinstance(frame.stuff, Stuff2):
+ return 2
+ n -= frame.stuff.x
+ return n
+
+ res = self.meta_interp(f, [30])
+ assert res == f(30)
+
+ def test_unequal_list_lengths_cannot_be_virtual(self):
+ jitdriver = JitDriver(greens = [], reds = ['frame', 'n'],
+ virtualizables = ['frame'])
+
+ class Frame(object):
+ _virtualizable2_ = True
+ def __init__(self):
+ self.l = []
+
+ def f(n):
+ frame = Frame()
+ while n > 0:
+ jitdriver.can_enter_jit(n=n, frame=frame)
+ jitdriver.jit_merge_point(n=n, frame=frame)
+ frame.l.append(n)
+ n -= 1
+ sum = 0
+ for i in range(len(frame.l)):
+ sum += frame.l[i]
+ return sum
+
+ res = self.meta_interp(f, [20])
+ assert res == f(20)
+
def test_external_read(self):
py.test.skip("Fails")
class Frame(object):
Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_warmspot.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_warmspot.py (original)
+++ pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_warmspot.py Fri Feb 20 13:54:36 2009
@@ -42,8 +42,23 @@
except Exit, e:
return e.result
- res = self.meta_interp(main, [1], interpreter_loop)
+ res = self.meta_interp(main, [1])
assert res == 21
+ def test_reentry(self):
+ mydriver = JitDriver(reds = ['n'], greens = [])
+
+ def f(n):
+ while n > 0:
+ mydriver.can_enter_jit(n=n)
+ mydriver.jit_merge_point(n=n)
+ if n % 20 == 0:
+ n -= 2
+ n -= 1
+
+ res = self.meta_interp(f, [60])
+ assert res == f(30)
+
+
class TestLLWarmspot(WarmspotTests):
pass
Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_zrpy_basic.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_zrpy_basic.py (original)
+++ pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_zrpy_basic.py Fri Feb 20 13:54:36 2009
@@ -1,47 +1,18 @@
import py
-py.test.skip("XXX")
-from pyjitpl import ll_meta_interp, get_stats
-from rpyjitpl import rpython_ll_meta_interp
-from test import test_basic
-
+py.test.skip("XXX WiP")
+from pypy.jit.metainterp.warmspot import rpython_ll_meta_interp, ll_meta_interp
+from pypy.jit.metainterp.test import test_basic
+from pypy.rlib.jit import JitDriver
class TestBasic:
- def test_dummy(self):
- def f(x):
- return x
- res = ll_meta_interp(f, [42])
- assert res == 42
- res = rpython_ll_meta_interp(f, [42], loops=0)
- assert res == 42
-
- def test_basic(self):
- def f(x, y):
- return x + y
- res = ll_meta_interp(f, [40, 2])
- assert res == 42
- res = rpython_ll_meta_interp(f, [40, 2], loops=0)
- assert res == 42
-
- def test_if(self):
- def f(x, y, z):
- if x:
- return y
- else:
- return z
- res = ll_meta_interp(f, [1, 40, 2])
- assert res == 40
- res = ll_meta_interp(f, [1, 40, 2])
- assert res == 40
- res = rpython_ll_meta_interp(f, [1, 40, 2], loops=0)
- assert res == 40
- res = rpython_ll_meta_interp(f, [0, 40, 2], loops=0)
- assert res == 2
-
def test_loop_1(self):
+ jitdriver = JitDriver(greens = [], reds = ['i', 'total'])
def f(i):
total = 0
while i > 3:
+ jitdriver.can_enter_jit(i=i, total=total)
+ jitdriver.jit_merge_point(i=i, total=total)
total += i
i -= 1
return total * 10
@@ -64,31 +35,6 @@
res = rpython_ll_meta_interp(f, [17], loops=2)
assert res == (17+14+11+8+7+6+5+4) * 10
- def test_ptr_very_simple(self):
- class A:
- pass
- a = A()
- def f(i):
- a.i = i
- return a.i + 2
- res = ll_meta_interp(f, [17])
- assert res == 19
- res = rpython_ll_meta_interp(f, [17])
- assert res == 19
-
- def test_ptr_simple(self):
- class A:
- pass
- def f(i):
- a = A()
- a.i = i
- return a.i + 2
- res = ll_meta_interp(f, [17])
- assert res == 19
- res = rpython_ll_meta_interp(f, [17], loops=0)
- assert res == 19
-
-
class LLInterpJitMixin:
type_system = 'lltype'
meta_interp = staticmethod(rpython_ll_meta_interp)
Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/warmspot.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/metainterp/warmspot.py (original)
+++ pypy/branch/pyjitpl5/pypy/jit/metainterp/warmspot.py Fri Feb 20 13:54:36 2009
@@ -1,6 +1,7 @@
import sys
from pypy.rpython.lltypesystem import lltype, llmemory, rclass
-from pypy.rpython.annlowlevel import llhelper
+from pypy.rpython.annlowlevel import llhelper, MixLevelHelperAnnotator
+from pypy.annotation import model as annmodel
from pypy.rpython.llinterp import LLException
from pypy.rpython.test.test_llinterp import get_interpreter, clear_tcache
from pypy.objspace.flow.model import SpaceOperation, Variable, Constant
@@ -28,6 +29,18 @@
warmrunnerdesc.state.set_param_trace_eagerness(2) # for tests
return interp.eval_graph(graph, args)
+def rpython_ll_meta_interp(function, args, loops=None, **kwds):
+ kwds['translate_support_code'] = True
+ interp, graph = get_interpreter(function, args, backendopt=True,
+ inline_threshold=0)
+ clear_tcache()
+ translator = interp.typer.annotator.translator
+ warmrunnerdesc = WarmRunnerDesc(translator, **kwds)
+ warmrunnerdesc.state.set_param_threshold(3) # for tests
+ warmrunnerdesc.state.set_param_trace_eagerness(2) # for tests
+ xxx
+ interp.eval_graph(boot, args)
+
def find_can_enter_jit(graphs):
results = []
for graph in graphs:
@@ -78,7 +91,8 @@
self.make_enter_function()
self.rewrite_can_enter_jit()
self.rewrite_jit_merge_point()
- self.metainterp.warmrunnerdesc = self # allows call-backs
+ self.metainterp.num_green_args = self.num_green_args
+ self.metainterp.state = self.state
def _freeze_(self):
return True
@@ -90,6 +104,8 @@
cpu = CPUClass(self.translator.rtyper, self.stats,
translate_support_code)
self.cpu = cpu
+ if translate_support_code:
+ self.annhelper = MixLevelHelperAnnotator(self.translator.rtyper)
graphs = self.translator.graphs
self.jit_merge_point_pos = find_jit_merge_point(graphs)
graph, block, pos = self.jit_merge_point_pos
@@ -102,7 +118,8 @@
self.translator.graphs.append(graph)
self.portal_graph = graph
self.jitdriver = block.operations[pos].args[1].value
- self.metainterp = OOMetaInterp(graph, cpu, self.stats, specialize)
+ self.metainterp = OOMetaInterp(graph, graphs, cpu, self.stats,
+ specialize)
def make_enter_function(self):
WarmEnterState = make_state_class(self)
@@ -131,10 +148,9 @@
self.PORTAL_FUNCTYPE = lltype.FuncType(ALLARGS, RESTYPE)
def rewrite_can_enter_jit(self):
- assert not self.cpu.translate_support_code, "XXX for now"
FUNC = self.JIT_ENTER_FUNCTYPE
FUNCPTR = lltype.Ptr(FUNC)
- jit_enter_fnptr = llhelper(FUNCPTR, self.maybe_enter_jit_fn)
+ jit_enter_fnptr = self.helper_func(FUNCPTR, self.maybe_enter_jit_fn)
graphs = self.translator.graphs
can_enter_jits = find_can_enter_jit(graphs)
@@ -153,6 +169,14 @@
newop = SpaceOperation('direct_call', vlist, v_result)
block.operations[index] = newop
+ def helper_func(self, FUNCPTR, func):
+ if not self.cpu.translate_support_code:
+ return llhelper(FUNCPTR, func)
+ FUNC = FUNCPTR.TO
+ args_s = [annmodel.lltype_to_annotation(ARG) for ARG in FUNC.ARGS]
+ s_result = annmodel.lltype_to_annotation(FUNC.RESULT)
+ return self.annhelper.delayedfunction(func, args_s, s_result)
+
def rewrite_jit_merge_point(self):
#
# Mutate the original portal graph from this:
@@ -228,34 +252,39 @@
self.metainterp.ContinueRunningNormally = ContinueRunningNormally
rtyper = self.translator.rtyper
- def ll_portal_runner(*args):
- while 1:
- try:
- return support.maybe_on_top_of_llinterp(rtyper,
- portal_ptr)(*args)
- except ContinueRunningNormally, e:
- # XXX NOT RPYTHON
- args = []
- for i, arg in enumerate(e.args):
- v = arg.value
- if lltype.typeOf(v) == llmemory.GCREF:
- v = lltype.cast_opaque_ptr(PORTALFUNC.ARGS[i], v)
- args.append(v)
- except DoneWithThisFrame, e:
- if e.resultbox is not None:
- return e.resultbox.value
- return
- except ExitFrameWithException, e:
- type = e.typebox.getaddr(self.metainterp.cpu)
- type = llmemory.cast_adr_to_ptr(type, rclass.CLASSTYPE)
- value = e.valuebox.getptr(lltype.Ptr(rclass.OBJECT))
- raise LLException(type, value)
-
if not self.cpu.translate_support_code:
- portal_runner_ptr = llhelper(lltype.Ptr(PORTALFUNC),
- ll_portal_runner)
+ def ll_portal_runner(*args):
+ while 1:
+ try:
+ return support.maybe_on_top_of_llinterp(rtyper,
+ portal_ptr)(*args)
+ except ContinueRunningNormally, e:
+ args = []
+ for i, arg in enumerate(e.args):
+ v = arg.value
+ if lltype.typeOf(v) == llmemory.GCREF:
+ v = lltype.cast_opaque_ptr(PORTALFUNC.ARGS[i],
+ v)
+ args.append(v)
+ except DoneWithThisFrame, e:
+ if e.resultbox is not None:
+ return e.resultbox.value
+ return
+ except ExitFrameWithException, e:
+ type = e.typebox.getaddr(self.metainterp.cpu)
+ type = llmemory.cast_adr_to_ptr(type, rclass.CLASSTYPE)
+ value = e.valuebox.getptr(lltype.Ptr(rclass.OBJECT))
+ raise LLException(type, value)
+
else:
- xxx
+ def ll_portal_runner(*args):
+ while 1:
+ #try:
+ portal_ptr(*args)
+ #xexcept DoneWi
+
+ portal_runner_ptr = self.helper_func(lltype.Ptr(PORTALFUNC),
+ ll_portal_runner)
# ____________________________________________________________
# Now mutate origportalgraph to end with a call to portal_runner_ptr
@@ -276,6 +305,8 @@
origblock.exitswitch = None
origblock.recloseblock(Link([v_result], origportalgraph.returnblock))
checkgraph(origportalgraph)
+ if self.cpu.translate_support_code:
+ self.annhelper.finish()
def decode_hp_hint_args(op):
@@ -318,8 +349,8 @@
__slots__ = 'counter'
class MachineCodeEntryPoint(StateCell):
- def __init__(self, mc, *greenargs):
- self.mc = mc
+ def __init__(self, mp, *greenargs):
+ self.mp = mp
self.next = Counter(0)
i = 0
for name in green_args_names:
@@ -378,16 +409,17 @@
self.cells[argshash] = Counter(n)
return
#interp.debug_trace("jit_compile", *greenargs)
- return self.compile_and_run(argshash, *args)
+ self.compile_and_run(argshash, *args)
else:
+ raise NotImplementedError("bridges to compiled code")
# machine code was already compiled for these greenargs
# (or we have a hash collision)
- XXX
assert isinstance(cell, MachineCodeEntryPoint)
if cell.equalkey(*greenargs):
- return cell.mc
+ self.run(cell, *args)
else:
- return self.handle_hash_collision(cell, argshash, *args)
+ xxx
+ self.handle_hash_collision(cell, argshash, *args)
maybe_compile_and_run._dont_inline_ = True
def handle_hash_collision(self, cell, argshash, *args):
More information about the Pypy-commit
mailing list