[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