[pypy-svn] pypy fast-forward: hg merge default

amauryfa commits-noreply at bitbucket.org
Mon Jan 10 20:06:35 CET 2011


Author: Amaury Forgeot d'Arc <amauryfa at gmail.com>
Branch: fast-forward
Changeset: r40566:57875f631aa1
Date: 2011-01-10 20:04 +0100
http://bitbucket.org/pypy/pypy/changeset/57875f631aa1/

Log:	hg merge default

diff --git a/pypy/jit/metainterp/specnode.py b/pypy/jit/metainterp/specnode.py
deleted file mode 100644
--- a/pypy/jit/metainterp/specnode.py
+++ /dev/null
@@ -1,127 +0,0 @@
-from pypy.tool.pairtype import extendabletype
-from pypy.jit.metainterp.history import Const
-
-
-class SpecNode(object):
-    __metaclass__ = extendabletype     # extended in optimizefindnode.py
-    __slots__ = ()
-
-    def equals(self, other, ge):     # 'ge' stands for greater-or-equal;
-        raise NotImplementedError    # if false, the default is 'equal'.
- 
-    def extract_runtime_data(self, cpu, valuebox, resultlist):
-        raise NotImplementedError
-
-
-class NotSpecNode(SpecNode):
-    __slots__ = ()
-
-    def equals(self, other, ge):
-        return isinstance(other, NotSpecNode) or ge
-
-    def extract_runtime_data(self, cpu, valuebox, resultlist):
-        resultlist.append(valuebox)
-
-
-prebuiltNotSpecNode = NotSpecNode()
-
-
-class ConstantSpecNode(SpecNode):
-    def __init__(self, constbox):
-        assert isinstance(constbox, Const)
-        self.constbox = constbox
-
-    def equals(self, other, ge):
-        return isinstance(other, ConstantSpecNode) and \
-               self.constbox.same_constant(other.constbox)
-
-    def extract_runtime_data(self, cpu, valuebox, resultlist):
-        pass
-
-
-class AbstractVirtualStructSpecNode(SpecNode):
-    def __init__(self, fields):
-        self.fields = fields    # list: [(fieldofs, subspecnode)]
-
-    def equal_fields(self, other, ge):
-        if len(self.fields) != len(other.fields):
-            return False
-        for i in range(len(self.fields)):
-            o1, s1 = self.fields[i]
-            o2, s2 = other.fields[i]
-            if not (o1 is o2 and s1.equals(s2, ge)):
-                return False
-        return True
-
-    def extract_runtime_data(self, cpu, valuebox, resultlist):
-        from pypy.jit.metainterp import executor, history, resoperation
-        for ofs, subspecnode in self.fields:
-            assert isinstance(ofs, history.AbstractDescr)
-            fieldbox = executor.execute(cpu, None,
-                                        resoperation.rop.GETFIELD_GC,
-                                        ofs, valuebox)
-            subspecnode.extract_runtime_data(cpu, fieldbox, resultlist)
-
-
-class VirtualInstanceSpecNode(AbstractVirtualStructSpecNode):
-    def __init__(self, known_class, fields):
-        AbstractVirtualStructSpecNode.__init__(self, fields)
-        assert isinstance(known_class, Const)
-        self.known_class = known_class
-
-    def equals(self, other, ge):
-        if not (isinstance(other, VirtualInstanceSpecNode) and
-                self.known_class.same_constant(other.known_class)):
-            return False
-        return self.equal_fields(other, ge)
-
-
-class VirtualArraySpecNode(SpecNode):
-    def __init__(self, arraydescr, items):
-        self.arraydescr = arraydescr
-        self.items = items      # list of subspecnodes
-
-    def equals(self, other, ge):
-        if not (isinstance(other, VirtualArraySpecNode) and
-                len(self.items) == len(other.items)):
-            return False
-        assert self.arraydescr == other.arraydescr
-        for i in range(len(self.items)):
-            s1 = self.items[i]
-            s2 = other.items[i]
-            if not s1.equals(s2, ge):
-                return False
-        return True
-
-    def extract_runtime_data(self, cpu, valuebox, resultlist):
-        from pypy.jit.metainterp import executor, history, resoperation
-        for i in range(len(self.items)):
-            itembox = executor.execute(cpu, None,
-                                       resoperation.rop.GETARRAYITEM_GC,
-                                       self.arraydescr,
-                                       valuebox, history.ConstInt(i))
-            subspecnode = self.items[i]
-            subspecnode.extract_runtime_data(cpu, itembox, resultlist)
-
-
-class VirtualStructSpecNode(AbstractVirtualStructSpecNode):
-    def __init__(self, typedescr, fields):
-        AbstractVirtualStructSpecNode.__init__(self, fields)
-        self.typedescr = typedescr
-
-    def equals(self, other, ge):
-        if not isinstance(other, VirtualStructSpecNode):
-            return False
-        assert self.typedescr == other.typedescr
-        return self.equal_fields(other, ge)
-
-
-def equals_specnodes(specnodes1, specnodes2, ge=False):
-    assert len(specnodes1) == len(specnodes2)
-    for i in range(len(specnodes1)):
-        if not specnodes1[i].equals(specnodes2[i], ge):
-            return False
-    return True
-
-def more_general_specnodes(specnodes1, specnodes2):
-    return equals_specnodes(specnodes1, specnodes2, ge=True)


diff --git a/pypy/annotation/annrpython.py b/pypy/annotation/annrpython.py
--- a/pypy/annotation/annrpython.py
+++ b/pypy/annotation/annrpython.py
@@ -406,31 +406,6 @@
 
     #___ simplification (should be moved elsewhere?) _______
 
-    # it should be!
-    # now simplify_calls is moved to transform.py.
-    # i kept reverse_binding here for future(?) purposes though. --sanxiyn
-
-    def reverse_binding(self, known_variables, cell):
-        """This is a hack."""
-        # In simplify_calls, when we are trying to create the new
-        # SpaceOperation, all we have are SomeValues.  But SpaceOperations take
-        # Variables, not SomeValues.  Trouble is, we don't always have a
-        # Variable that just happens to be bound to the given SomeValue.
-        # A typical example would be if the tuple of arguments was created
-        # from another basic block or even another function.  Well I guess
-        # there is no clean solution, short of making the transformations
-        # more syntactic (e.g. replacing a specific sequence of SpaceOperations
-        # with another one).  This is a real hack because we have to use
-        # the identity of 'cell'.
-        if cell.is_constant():
-            return Constant(cell.const)
-        else:
-            for v in known_variables:
-                if self.bindings[v] is cell:
-                    return v
-            else:
-                raise CannotSimplify
-
     def simplify(self, block_subset=None, extra_passes=None):
         # Generic simplifications
         transform.transform_graph(self, block_subset=block_subset,
@@ -783,10 +758,6 @@
 RPythonAnnotator._registeroperations(annmodel)
 
 
-class CannotSimplify(Exception):
-    pass
-
-
 class BlockedInference(Exception):
     """This exception signals the type inference engine that the situation
     is currently blocked, and that it should try to progress elsewhere."""








diff --git a/pypy/jit/metainterp/test/test_loop_dummy.py b/pypy/jit/metainterp/test/test_loop_dummy.py
deleted file mode 100644
--- a/pypy/jit/metainterp/test/test_loop_dummy.py
+++ /dev/null
@@ -1,28 +0,0 @@
-# xxx mostly pointless
-
-from pypy.jit.metainterp.test import test_loop, test_send
-from pypy.jit.metainterp.warmspot import ll_meta_interp
-from pypy.rlib.jit import OPTIMIZER_SIMPLE
-from pypy.jit.metainterp.test.test_basic import LLJitMixin, OOJitMixin
-
-class LoopDummyTest(test_send.SendTests):
-    def meta_interp(self, func, args, **kwds):
-        return ll_meta_interp(func, args, optimizer=OPTIMIZER_SIMPLE,
-                              CPUClass=self.CPUClass, 
-                              type_system=self.type_system,
-                              **kwds)
-
-    def check_loops(self, *args, **kwds):
-        pass
-
-    def check_loop_count(self, count):
-        pass
-
-    def check_jumps(self, maxcount):
-        pass
-
-class TestLLtype(LoopDummyTest, LLJitMixin):
-    pass
-
-class TestOOtype(LoopDummyTest, OOJitMixin):
-    pass



diff --git a/pypy/jit/metainterp/test/test_optimizefindnode.py b/pypy/jit/metainterp/test/test_optimizefindnode.py
deleted file mode 100644
--- a/pypy/jit/metainterp/test/test_optimizefindnode.py
+++ /dev/null
@@ -1,1199 +0,0 @@
-import py, random
-
-from pypy.rpython.lltypesystem import lltype, llmemory, rclass, rstr
-from pypy.rpython.ootypesystem import ootype
-from pypy.rpython.lltypesystem.rclass import OBJECT, OBJECT_VTABLE
-
-from pypy.jit.backend.llgraph import runner
-from pypy.jit.metainterp.history import (BoxInt, BoxPtr, ConstInt, ConstPtr,
-                                         Const, TreeLoop, BoxObj,
-                                         ConstObj, AbstractDescr)
-from pypy.jit.metainterp.optimizefindnode import PerfectSpecializationFinder
-from pypy.jit.metainterp.optimizefindnode import BridgeSpecializationFinder
-from pypy.jit.metainterp.optimizeutil import sort_descrs, InvalidLoop
-from pypy.jit.metainterp.specnode import NotSpecNode, prebuiltNotSpecNode
-from pypy.jit.metainterp.specnode import VirtualInstanceSpecNode
-from pypy.jit.metainterp.specnode import VirtualArraySpecNode
-from pypy.jit.metainterp.specnode import VirtualStructSpecNode
-from pypy.jit.metainterp.specnode import ConstantSpecNode
-from pypy.jit.codewriter.effectinfo import EffectInfo
-from pypy.jit.codewriter.heaptracker import register_known_gctype, adr2int
-from pypy.jit.tool.oparser import parse
-
-def test_sort_descrs():
-    class PseudoDescr(AbstractDescr):
-        def __init__(self, n):
-            self.n = n
-        def sort_key(self):
-            return self.n
-    for i in range(17):
-        lst = [PseudoDescr(j) for j in range(i)]
-        lst2 = lst[:]
-        random.shuffle(lst2)
-        sort_descrs(lst2)
-        assert lst2 == lst
-
-# ____________________________________________________________
-
-class LLtypeMixin(object):
-    type_system = 'lltype'
-
-    def get_class_of_box(self, box):
-        return box.getref(rclass.OBJECTPTR).typeptr
-
-    node_vtable = lltype.malloc(OBJECT_VTABLE, immortal=True)
-    node_vtable.name = rclass.alloc_array_name('node')
-    node_vtable_adr = llmemory.cast_ptr_to_adr(node_vtable)
-    node_vtable2 = lltype.malloc(OBJECT_VTABLE, immortal=True)
-    node_vtable2.name = rclass.alloc_array_name('node2')
-    node_vtable_adr2 = llmemory.cast_ptr_to_adr(node_vtable2)
-    cpu = runner.LLtypeCPU(None)
-
-    NODE = lltype.GcForwardReference()
-    NODE.become(lltype.GcStruct('NODE', ('parent', OBJECT),
-                                        ('value', lltype.Signed),
-                                        ('floatval', lltype.Float),
-                                        ('next', lltype.Ptr(NODE))))
-    NODE2 = lltype.GcStruct('NODE2', ('parent', NODE),
-                                     ('other', lltype.Ptr(NODE)))
-    node = lltype.malloc(NODE)
-    node.parent.typeptr = node_vtable
-    nodebox = BoxPtr(lltype.cast_opaque_ptr(llmemory.GCREF, node))
-    myptr = nodebox.value
-    myptr2 = lltype.cast_opaque_ptr(llmemory.GCREF, lltype.malloc(NODE))
-    nodebox2 = BoxPtr(lltype.cast_opaque_ptr(llmemory.GCREF, node))
-    nodesize = cpu.sizeof(NODE)
-    nodesize2 = cpu.sizeof(NODE2)
-    valuedescr = cpu.fielddescrof(NODE, 'value')
-    floatdescr = cpu.fielddescrof(NODE, 'floatval')
-    nextdescr = cpu.fielddescrof(NODE, 'next')
-    otherdescr = cpu.fielddescrof(NODE2, 'other')
-
-    NODEOBJ = lltype.GcStruct('NODEOBJ', ('parent', OBJECT),
-                                         ('ref', lltype.Ptr(OBJECT)))
-    nodeobj = lltype.malloc(NODEOBJ)
-    nodeobjvalue = lltype.cast_opaque_ptr(llmemory.GCREF, nodeobj)
-    refdescr = cpu.fielddescrof(NODEOBJ, 'ref')
-
-    arraydescr = cpu.arraydescrof(lltype.GcArray(lltype.Signed))
-    floatarraydescr = cpu.arraydescrof(lltype.GcArray(lltype.Float))
-
-    # a GcStruct not inheriting from OBJECT
-    S = lltype.GcStruct('TUPLE', ('a', lltype.Signed), ('b', lltype.Ptr(NODE)))
-    ssize = cpu.sizeof(S)
-    adescr = cpu.fielddescrof(S, 'a')
-    bdescr = cpu.fielddescrof(S, 'b')
-    sbox = BoxPtr(lltype.cast_opaque_ptr(llmemory.GCREF, lltype.malloc(S)))
-    arraydescr2 = cpu.arraydescrof(lltype.GcArray(lltype.Ptr(S)))
-
-    T = lltype.GcStruct('TUPLE',
-                        ('c', lltype.Signed),
-                        ('d', lltype.Ptr(lltype.GcArray(lltype.Ptr(NODE)))))
-    tsize = cpu.sizeof(T)
-    cdescr = cpu.fielddescrof(T, 'c')
-    ddescr = cpu.fielddescrof(T, 'd')
-    arraydescr3 = cpu.arraydescrof(lltype.GcArray(lltype.Ptr(NODE)))
-
-    U = lltype.GcStruct('U',
-                        ('parent', OBJECT),
-                        ('one', lltype.Ptr(lltype.GcArray(lltype.Ptr(NODE)))))
-    u_vtable = lltype.malloc(OBJECT_VTABLE, immortal=True)
-    u_vtable_adr = llmemory.cast_ptr_to_adr(u_vtable)
-    usize = cpu.sizeof(U)
-    onedescr = cpu.fielddescrof(U, 'one')
-
-    FUNC = lltype.FuncType([lltype.Signed], lltype.Signed)
-    plaincalldescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT)
-    nonwritedescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT,
-                                    EffectInfo([], [], []))
-    writeadescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT,
-                                  EffectInfo([], [adescr], []))
-    writearraydescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT,
-                                      EffectInfo([], [adescr], [arraydescr]))
-    readadescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT,
-                                 EffectInfo([adescr], [], []))
-    mayforcevirtdescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT,
-                 EffectInfo([nextdescr], [], [],
-                            EffectInfo.EF_FORCES_VIRTUAL_OR_VIRTUALIZABLE))
-    arraycopydescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT,
-                 EffectInfo([], [], [], oopspecindex=EffectInfo.OS_ARRAYCOPY))
-
-    for _name, _os in [
-        ('strconcatdescr',               'OS_STR_CONCAT'),
-        ('strslicedescr',                'OS_STR_SLICE'),
-        ('strequaldescr',                'OS_STR_EQUAL'),
-        ('streq_slice_checknull_descr',  'OS_STREQ_SLICE_CHECKNULL'),
-        ('streq_slice_nonnull_descr',    'OS_STREQ_SLICE_NONNULL'),
-        ('streq_slice_char_descr',       'OS_STREQ_SLICE_CHAR'),
-        ('streq_nonnull_descr',          'OS_STREQ_NONNULL'),
-        ('streq_nonnull_char_descr',     'OS_STREQ_NONNULL_CHAR'),
-        ('streq_checknull_char_descr',   'OS_STREQ_CHECKNULL_CHAR'),
-        ('streq_lengthok_descr',         'OS_STREQ_LENGTHOK'),
-        ]:
-        _oopspecindex = getattr(EffectInfo, _os)
-        locals()[_name] = \
-            cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT,
-                EffectInfo([], [], [], oopspecindex=_oopspecindex))
-        #
-        _oopspecindex = getattr(EffectInfo, _os.replace('STR', 'UNI'))
-        locals()[_name.replace('str', 'unicode')] = \
-            cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT,
-                EffectInfo([], [], [], oopspecindex=_oopspecindex))
-
-    s2u_descr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT,
-                EffectInfo([], [], [], oopspecindex=EffectInfo.OS_STR2UNICODE))
-    #
-
-    class LoopToken(AbstractDescr):
-        pass
-    asmdescr = LoopToken() # it can be whatever, it's not a descr though
-
-    from pypy.jit.metainterp.virtualref import VirtualRefInfo
-    class FakeWarmRunnerDesc:
-        pass
-    FakeWarmRunnerDesc.cpu = cpu
-    vrefinfo = VirtualRefInfo(FakeWarmRunnerDesc)
-    virtualtokendescr = vrefinfo.descr_virtual_token
-    virtualrefindexdescr = vrefinfo.descr_virtualref_index
-    virtualforceddescr = vrefinfo.descr_forced
-    jit_virtual_ref_vtable = vrefinfo.jit_virtual_ref_vtable
-    jvr_vtable_adr = llmemory.cast_ptr_to_adr(jit_virtual_ref_vtable)
-
-    register_known_gctype(cpu, node_vtable,  NODE)
-    register_known_gctype(cpu, node_vtable2, NODE2)
-    register_known_gctype(cpu, u_vtable,     U)
-    register_known_gctype(cpu, jit_virtual_ref_vtable,vrefinfo.JIT_VIRTUAL_REF)
-
-    namespace = locals()
-
-class OOtypeMixin_xxx_disabled(object):
-    type_system = 'ootype'
-
-##    def get_class_of_box(self, box):
-##        root = box.getref(ootype.ROOT)
-##        return ootype.classof(root)
-    
-##    cpu = runner.OOtypeCPU(None)
-##    NODE = ootype.Instance('NODE', ootype.ROOT, {})
-##    NODE._add_fields({'value': ootype.Signed,
-##                      'floatval' : ootype.Float,
-##                      'next': NODE})
-##    NODE2 = ootype.Instance('NODE2', NODE, {'other': NODE})
-
-##    node_vtable = ootype.runtimeClass(NODE)
-##    node_vtable_adr = ootype.cast_to_object(node_vtable)
-##    node_vtable2 = ootype.runtimeClass(NODE2)
-##    node_vtable_adr2 = ootype.cast_to_object(node_vtable2)
-
-##    node = ootype.new(NODE)
-##    nodebox = BoxObj(ootype.cast_to_object(node))
-##    myptr = nodebox.value
-##    myptr2 = ootype.cast_to_object(ootype.new(NODE))
-##    nodebox2 = BoxObj(ootype.cast_to_object(node))
-##    valuedescr = cpu.fielddescrof(NODE, 'value')
-##    floatdescr = cpu.fielddescrof(NODE, 'floatval')
-##    nextdescr = cpu.fielddescrof(NODE, 'next')
-##    otherdescr = cpu.fielddescrof(NODE2, 'other')
-##    nodesize = cpu.typedescrof(NODE)
-##    nodesize2 = cpu.typedescrof(NODE2)
-
-##    arraydescr = cpu.arraydescrof(ootype.Array(ootype.Signed))
-##    floatarraydescr = cpu.arraydescrof(ootype.Array(ootype.Float))
-
-##    # a plain Record
-##    S = ootype.Record({'a': ootype.Signed, 'b': NODE})
-##    ssize = cpu.typedescrof(S)
-##    adescr = cpu.fielddescrof(S, 'a')
-##    bdescr = cpu.fielddescrof(S, 'b')
-##    sbox = BoxObj(ootype.cast_to_object(ootype.new(S)))
-##    arraydescr2 = cpu.arraydescrof(ootype.Array(S))
-
-##    T = ootype.Record({'c': ootype.Signed,
-##                       'd': ootype.Array(NODE)})
-##    tsize = cpu.typedescrof(T)
-##    cdescr = cpu.fielddescrof(T, 'c')
-##    ddescr = cpu.fielddescrof(T, 'd')
-##    arraydescr3 = cpu.arraydescrof(ootype.Array(NODE))
-
-##    U = ootype.Instance('U', ootype.ROOT, {'one': ootype.Array(NODE)})
-##    usize = cpu.typedescrof(U)
-##    onedescr = cpu.fielddescrof(U, 'one')
-##    u_vtable = ootype.runtimeClass(U)
-##    u_vtable_adr = ootype.cast_to_object(u_vtable)
-
-##    # force a consistent order
-##    valuedescr.sort_key()
-##    nextdescr.sort_key()
-##    adescr.sort_key()
-##    bdescr.sort_key()
-
-##    FUNC = lltype.FuncType([lltype.Signed], lltype.Signed)
-##    nonwritedescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT) # XXX fix ootype
-
-##    cpu.class_sizes = {node_vtable_adr: cpu.typedescrof(NODE),
-##                       node_vtable_adr2: cpu.typedescrof(NODE2),
-##                       u_vtable_adr: cpu.typedescrof(U)}
-##    namespace = locals()
-
-class BaseTest(object):
-    invent_fail_descr = None
-
-    def parse(self, s, boxkinds=None):
-        return parse(s, self.cpu, self.namespace,
-                     type_system=self.type_system,
-                     boxkinds=boxkinds,
-                     invent_fail_descr=self.invent_fail_descr)
-
-    def unpack_specnodes(self, text):
-        #
-        def constclass(cls_vtable):
-            if self.type_system == 'lltype':
-                return ConstInt(adr2int(llmemory.cast_ptr_to_adr(cls_vtable)))
-            else:
-                return ConstObj(ootype.cast_to_object(cls_vtable))
-        def constant(value):
-            if isinstance(lltype.typeOf(value), lltype.Ptr):
-                return ConstPtr(value)
-            elif isinstance(ootype.typeOf(value), ootype.OOType):
-                return ConstObj(ootype.cast_to_object(value))
-            else:
-                return ConstInt(value)
-
-        def parsefields(kwds_fields):
-            fields = []
-            for key, value in kwds_fields.items():
-                fields.append((self.namespace[key], value))
-            fields.sort(key = lambda (x, _): x.sort_key())
-            return fields
-        def makeConstant(value):
-            return ConstantSpecNode(constant(value))
-        def makeVirtual(cls_vtable, **kwds_fields):
-            fields = parsefields(kwds_fields)
-            return VirtualInstanceSpecNode(constclass(cls_vtable), fields)
-        def makeVirtualArray(arraydescr, *items):
-            return VirtualArraySpecNode(arraydescr, items)
-        def makeVirtualStruct(typedescr, **kwds_fields):
-            fields = parsefields(kwds_fields)
-            return VirtualStructSpecNode(typedescr, fields)
-        #
-        context = {'Not': prebuiltNotSpecNode,
-                   'Constant': makeConstant,
-                   'Virtual': makeVirtual,
-                   'VArray': makeVirtualArray,
-                   'VStruct': makeVirtualStruct}
-        lst = eval('[' + text + ']', self.namespace, context)
-        return lst
-
-    def check_specnodes(self, specnodes, text):
-        lst = self.unpack_specnodes(text)
-        assert len(specnodes) == len(lst)
-        for x, y in zip(specnodes, lst):
-            assert x.equals(y, ge=False)
-        return True
-
-# ____________________________________________________________
-
-class BaseTestOptimizeFindNode(BaseTest):
-
-    def find_nodes(self, ops, spectext, boxkinds=None):
-        assert boxkinds is None or isinstance(boxkinds, dict)
-        loop = self.parse(ops, boxkinds=boxkinds)
-        perfect_specialization_finder = PerfectSpecializationFinder(self.cpu)
-        perfect_specialization_finder.find_nodes_loop(loop)
-        self.check_specnodes(loop.token.specnodes, spectext)
-        return (loop.getboxes(), perfect_specialization_finder.getnode)
-
-    def test_find_nodes_simple(self):
-        ops = """
-        [i]
-        i0 = int_sub(i, 1)
-        guard_value(i0, 0) [i0]
-        jump(i0)
-        """
-        boxes, getnode = self.find_nodes(ops, 'Not')
-        assert getnode(boxes.i).fromstart
-        assert not getnode(boxes.i0).fromstart
-
-    def test_find_nodes_non_escape(self):
-        ops = """
-        [p0]
-        p1 = getfield_gc(p0, descr=nextdescr)
-        i0 = getfield_gc(p1, descr=valuedescr)
-        i1 = int_sub(i0, 1)
-        p2 = getfield_gc(p0, descr=nextdescr)
-        setfield_gc(p2, i1, descr=valuedescr)
-        p3 = new_with_vtable(ConstClass(node_vtable))
-        jump(p3)
-        """
-        boxes, getnode = self.find_nodes(ops,
-                                         'Virtual(node_vtable, nextdescr=Not)')
-        assert not getnode(boxes.p0).escaped
-        assert getnode(boxes.p1).escaped
-        assert getnode(boxes.p2).escaped
-        assert getnode(boxes.p0).fromstart
-        assert getnode(boxes.p1).fromstart
-        assert getnode(boxes.p2).fromstart
-
-    def test_find_nodes_escape(self):
-        ops = """
-        [p0]
-        p1 = getfield_gc(p0, descr=nextdescr)
-        p2 = getfield_gc(p1, descr=nextdescr)
-        i0 = getfield_gc(p2, descr=valuedescr)
-        i1 = int_sub(i0, 1)
-        escape(p1)
-        p3 = getfield_gc(p0, descr=nextdescr)
-        setfield_gc(p3, i1, descr=valuedescr)
-        p4 = getfield_gc(p1, descr=nextdescr)
-        setfield_gc(p4, i1, descr=valuedescr)
-        p5 = new_with_vtable(ConstClass(node_vtable))
-        jump(p5)
-        """
-        boxes, getnode = self.find_nodes(ops,
-                                         'Virtual(node_vtable, nextdescr=Not)')
-        assert not getnode(boxes.p0).escaped
-        assert getnode(boxes.p1).escaped
-        assert getnode(boxes.p2).escaped    # forced by p1
-        assert getnode(boxes.p3).escaped    # forced because p3 == p1
-        assert getnode(boxes.p4).escaped    # forced by p1
-        assert getnode(boxes.p0).fromstart
-        assert getnode(boxes.p1).fromstart
-        assert getnode(boxes.p2).fromstart
-        assert getnode(boxes.p3).fromstart
-        assert not getnode(boxes.p4).fromstart
-
-    def test_find_nodes_new_1(self):
-        ops = """
-        [p1]
-        p2 = new_with_vtable(ConstClass(node_vtable))
-        jump(p2)
-        """
-        boxes, getnode = self.find_nodes(ops, 'Virtual(node_vtable)')
-
-        boxp1 = getnode(boxes.p1)
-        boxp2 = getnode(boxes.p2)
-        assert not boxp1.escaped
-        assert not boxp2.escaped
-
-        assert not boxp1.origfields
-        assert not boxp1.curfields
-        assert not boxp2.origfields
-        assert not boxp2.curfields
-
-        assert boxp1.fromstart
-        assert not boxp2.fromstart
-
-        assert boxp1.knownclsbox is None
-        assert boxp2.knownclsbox.getaddr() == self.node_vtable_adr
-
-    def test_find_nodes_new_2(self):
-        ops = """
-        [i1, p1]
-        p2 = new_with_vtable(ConstClass(node_vtable))
-        p3 = new_with_vtable(ConstClass(node_vtable2))
-        setfield_gc(p2, p3, descr=nextdescr)
-        setfield_gc(p3, i1, descr=valuedescr)
-        jump(i1, p2)
-        """
-        self.find_nodes(ops,
-            '''Not,
-               Virtual(node_vtable,
-                       nextdescr=Virtual(node_vtable2,
-                                         valuedescr=Not))''')
-
-    def test_find_nodes_new_3(self):
-        ops = """
-        [sum, p1]
-        guard_class(p1, ConstClass(node_vtable)) []
-        i1 = getfield_gc(p1, descr=valuedescr)
-        i2 = int_sub(i1, 1)
-        sum2 = int_add(sum, i1)
-        p2 = new_with_vtable(ConstClass(node_vtable))
-        setfield_gc(p2, i2, descr=valuedescr)
-        p3 = new_with_vtable(ConstClass(node_vtable2))
-        setfield_gc(p2, p3, descr=nextdescr)
-        jump(sum2, p2)
-        """
-        boxes, getnode = self.find_nodes(
-            ops,
-            '''Not,
-               Virtual(node_vtable,
-                       valuedescr=Not,
-                       nextdescr=Virtual(node_vtable2))''',
-            boxkinds={'sum': BoxInt, 'sum2': BoxInt})
-        assert getnode(boxes.sum) is not getnode(boxes.sum2)
-        assert getnode(boxes.p1) is not getnode(boxes.p2)
-
-        boxp1 = getnode(boxes.p1)
-        boxp2 = getnode(boxes.p2)
-        boxp3 = getnode(boxes.p3)
-        assert not boxp1.escaped
-        assert not boxp2.escaped
-        assert not boxp3.escaped
-
-        assert not boxp1.curfields
-        assert boxp1.origfields[self.valuedescr] is getnode(boxes.i1)
-        assert not boxp2.origfields
-        assert boxp2.curfields[self.nextdescr] is boxp3
-
-        assert boxp1.fromstart
-        assert not boxp2.fromstart
-        assert not boxp3.fromstart
-
-        assert boxp2.knownclsbox.getaddr() == self.node_vtable_adr
-        assert boxp3.knownclsbox.getaddr() == self.node_vtable_adr2
-
-    def test_find_nodes_new_aliasing_0(self):
-        ops = """
-        [p1, p2]
-        p3 = new_with_vtable(ConstClass(node_vtable))
-        jump(p3, p3)
-        """
-        # both p1 and p2 must be NotSpecNodes; it's not possible to pass
-        # the same Virtual both in p1 and p2 (at least so far).
-        self.find_nodes(ops, 'Not, Not')
-
-    def test_find_nodes_new_aliasing_1(self):
-        ops = """
-        [sum, p1]
-        guard_class(p1, ConstClass(node_vtable)) []
-        p3 = getfield_gc(p1, descr=nextdescr)
-        guard_class(p3, ConstClass(node_vtable)) []
-        i1 = getfield_gc(p1, descr=valuedescr)
-        i2 = int_sub(i1, 1)
-        sum2 = int_add(sum, i1)
-        p2 = new_with_vtable(ConstClass(node_vtable))
-        setfield_gc(p2, i2, descr=valuedescr)
-        setfield_gc(p2, p2, descr=nextdescr)
-        jump(sum2, p2)
-        """
-        # the issue is the cycle "p2->p2", which cannot be represented
-        # with SpecNodes so far
-        self.find_nodes(ops, 'Not, Not',
-                        boxkinds={'sum': BoxInt, 'sum2': BoxInt})
-
-    def test_find_nodes_new_aliasing_2(self):
-        ops = """
-        [p1, p2]
-        escape(p2)
-        p3 = new_with_vtable(ConstClass(node_vtable))
-        jump(p3, p3)
-        """
-        # both p1 and p2 must be NotSpecNodes; it's not possible to pass
-        # in p1 a Virtual and not in p2, as they both come from the same p3.
-        self.find_nodes(ops, 'Not, Not')
-
-    def test_find_nodes_new_mismatch(self):
-        ops = """
-        [p1]
-        guard_class(p1, ConstClass(node_vtable)) []
-        p2 = new_with_vtable(ConstClass(node_vtable2))
-        jump(p2)
-        """
-        # this is not a valid loop at all, because of the mismatch
-        # between the produced and the consumed class.
-        py.test.raises(InvalidLoop, self.find_nodes, ops, None)
-
-    def test_find_nodes_new_aliasing_mismatch(self):
-        ops = """
-        [p0, p1]
-        guard_class(p0, ConstClass(node_vtable)) []
-        guard_class(p1, ConstClass(node_vtable2)) []
-        p2 = new_with_vtable(ConstClass(node_vtable2))
-        jump(p2, p2)
-        """
-        # this is also not really a valid loop, but it's not detected
-        # because p2 is passed more than once in the jump().
-        self.find_nodes(ops, 'Not, Not')
-
-    def test_find_nodes_new_escapes(self):
-        ops = """
-        [p0]
-        escape(p0)
-        p1 = new_with_vtable(ConstClass(node_vtable))
-        jump(p1)
-        """
-        self.find_nodes(ops, 'Not')
-
-    def test_find_nodes_new_unused(self):
-        ops = """
-        [p0]
-        p1 = new_with_vtable(ConstClass(node_vtable))
-        p2 = new_with_vtable(ConstClass(node_vtable))
-        p3 = new_with_vtable(ConstClass(node_vtable))
-        setfield_gc(p1, p2, descr=nextdescr)
-        setfield_gc(p2, p3, descr=nextdescr)
-        jump(p1)
-        """
-        self.find_nodes(ops, '''
-            Virtual(node_vtable,
-                    nextdescr=Virtual(node_vtable,
-                                      nextdescr=Virtual(node_vtable)))''')
-
-    def test_find_nodes_ptr_eq(self):
-        ops = """
-        [p3, p4, p2]
-        p0 = new_with_vtable(ConstClass(node_vtable))
-        p1 = new_with_vtable(ConstClass(node_vtable))
-        guard_nonnull(p0) []
-        i3 = ptr_ne(p0, NULL)
-        guard_true(i3) []
-        i4 = ptr_eq(p0, NULL)
-        guard_false(i4) []
-        i5 = ptr_ne(NULL, p0)
-        guard_true(i5) []
-        i6 = ptr_eq(NULL, p0)
-        guard_false(i6) []
-        i7 = ptr_ne(p0, p1)
-        guard_true(i7) []
-        i8 = ptr_eq(p0, p1)
-        guard_false(i8) []
-        i9 = ptr_ne(p0, p2)
-        guard_true(i9) []
-        i10 = ptr_eq(p0, p2)
-        guard_false(i10) []
-        i11 = ptr_ne(p2, p1)
-        guard_true(i11) []
-        i12 = ptr_eq(p2, p1)
-        guard_false(i12) []
-        jump(p0, p1, p2)
-        """
-        self.find_nodes(ops, '''Virtual(node_vtable),
-                                Virtual(node_vtable),
-                                Not''')
-
-    def test_find_nodes_call(self):
-        ops = """
-        [i0, p2]
-        p0 = new_with_vtable(ConstClass(node_vtable))
-        i1 = call_pure(i0, p0)     # forces p0 to not be virtual
-        jump(i1, p0)
-        """
-        self.find_nodes(ops, 'Not, Not')
-
-    def test_find_nodes_default_field(self):
-        ops = """
-        [p0]
-        i0 = getfield_gc(p0, descr=valuedescr)
-        guard_value(i0, 5) []
-        p1 = new_with_vtable(ConstClass(node_vtable))
-        # the field 'value' has its default value of 0
-        jump(p1)
-        """
-        # The answer must contain the 'value' field, because otherwise
-        # we might get incorrect results: when tracing, i0 was 5.
-        self.find_nodes(ops, 'Virtual(node_vtable, valuedescr=Not)')
-
-    def test_find_nodes_nonvirtual_guard_class(self):
-        ops = """
-        [p1]
-        guard_class(p1, ConstClass(node_vtable)) [p1]
-        jump(p1)
-        """
-        self.find_nodes(ops, 'Not')
-
-    def test_find_nodes_p12_simple(self):
-        ops = """
-        [p1]
-        i3 = getfield_gc(p1, descr=valuedescr)
-        escape(i3)
-        jump(p1)
-        """
-        self.find_nodes(ops, 'Not')
-
-    def test_find_nodes_p123_simple(self):
-        ops = """
-        [i1, p2, p3]
-        i3 = getfield_gc(p3, descr=valuedescr)
-        escape(i3)
-        p1 = new_with_vtable(ConstClass(node_vtable))
-        setfield_gc(p1, i1, descr=valuedescr)
-        jump(i1, p1, p2)
-        """
-        # We cannot track virtuals that survive for more than two iterations.
-        self.find_nodes(ops, 'Not, Not, Not')
-
-    def test_find_nodes_p1234_simple(self):
-        ops = """
-        [i1, p2, p3, p4]
-        i4 = getfield_gc(p4, descr=valuedescr)
-        escape(i4)
-        p1 = new_with_vtable(ConstClass(node_vtable))
-        setfield_gc(p1, i1, descr=valuedescr)
-        jump(i1, p1, p2, p3)
-        """
-        # We cannot track virtuals that survive for more than two iterations.
-        self.find_nodes(ops, 'Not, Not, Not, Not')
-
-    def test_find_nodes_p123_guard_class(self):
-        ops = """
-        [i1, p2, p3]
-        guard_class(p3, ConstClass(node_vtable)) [i1, p2, p3]
-        i3 = getfield_gc(p3, descr=valuedescr)
-        escape(i3)
-        p1 = new_with_vtable(ConstClass(node_vtable))
-        setfield_gc(p1, i1, descr=valuedescr)
-        jump(i1, p1, p2)
-        """
-        # We cannot track virtuals that survive for more than two iterations.
-        self.find_nodes(ops, 'Not, Not, Not')
-
-    def test_find_nodes_p123_rec(self):
-        ops = """
-        [i1, p2, p0d]
-        p3 = getfield_gc(p0d, descr=nextdescr)
-        i3 = getfield_gc(p3, descr=valuedescr)
-        escape(i3)
-        p1 = new_with_vtable(ConstClass(node_vtable))
-        setfield_gc(p1, i1, descr=valuedescr)
-        p0c = new_with_vtable(ConstClass(node_vtable))
-        setfield_gc(p0c, p2, descr=nextdescr)
-        jump(i1, p1, p0c)
-        """
-        # We cannot track virtuals that survive for more than two iterations.
-        self.find_nodes(ops, '''Not,
-                                Not,
-                                Virtual(node_vtable, nextdescr=Not)''')
-
-    def test_find_nodes_setfield_bug(self):
-        ops = """
-        [p1, p2]
-        escape(p1)
-        setfield_gc(p1, p2, descr=nextdescr)
-        p3 = new_with_vtable(ConstClass(node_vtable))
-        jump(p1, p3)
-        """
-        self.find_nodes(ops, 'Not, Not')
-
-    def test_find_nodes_array_virtual_1(self):
-        ops = """
-        [i1, p2]
-        i2 = getarrayitem_gc(p2, 1, descr=arraydescr)
-        escape(i2)
-        p3 = new_array(3, descr=arraydescr)
-        setarrayitem_gc(p3, 1, i1, descr=arraydescr)
-        jump(i1, p3)
-        """
-        self.find_nodes(ops, 'Not, VArray(arraydescr, Not, Not, Not)')
-
-    def test_find_nodes_array_virtual_2(self):
-        ops = """
-        [i1, p2]
-        i2 = arraylen_gc(p2, descr=arraydescr)
-        escape(i2)
-        p3 = new_array(3, descr=arraydescr)
-        setarrayitem_gc(p3, 1, i1, descr=arraydescr)
-        jump(i1, p3)
-        """
-        self.find_nodes(ops, 'Not, VArray(arraydescr, Not, Not, Not)')
-
-    def test_find_nodes_array_virtual_3(self):
-        ops = """
-        [pvalue1, p2]
-        pvalue2 = new_with_vtable(ConstClass(node_vtable2))
-        ps2 = getarrayitem_gc(p2, 1, descr=arraydescr)
-        setfield_gc(ps2, pvalue2, descr=nextdescr)
-        ps3 = getarrayitem_gc(p2, 1, descr=arraydescr)
-        pvalue3 = getfield_gc(ps3, descr=nextdescr)
-        ps1 = new_with_vtable(ConstClass(node_vtable))
-        p3 = new_array(3, descr=arraydescr)
-        setarrayitem_gc(p3, 1, ps1, descr=arraydescr)
-        jump(pvalue3, p3)
-        """
-        self.find_nodes(ops, 'Virtual(node_vtable2), VArray(arraydescr, Not, Virtual(node_vtable), Not)')
-
-    def test_find_nodes_array_virtual_empty(self):
-        ops = """
-        [i1, p2]
-        p3 = new_array(3, descr=arraydescr)
-        jump(i1, p3)
-        """
-        self.find_nodes(ops, 'Not, VArray(arraydescr, Not, Not, Not)')
-
-    def test_find_nodes_array_nonvirtual_1(self):
-        ops = """
-        [i1, p2]
-        i2 = getarrayitem_gc(p2, i1, descr=arraydescr)
-        escape(i2)
-        p3 = new_array(4, descr=arraydescr)
-        setarrayitem_gc(p3, i1, i2, descr=arraydescr)
-        jump(i1, p3)
-        """
-        # Does not work because of the variable index, 'i1'.
-        self.find_nodes(ops, 'Not, Not')
-
-    def test_find_nodes_array_forced_1(self):
-        ops = """
-        [p1, i1]
-        p2 = new_array(1, descr=arraydescr)
-        setarrayitem_gc(p2, 0, p1, descr=arraydescr)
-        p3 = getarrayitem_gc(p2, i1, descr=arraydescr)
-        p4 = new_with_vtable(ConstClass(node_vtable))
-        jump(p4, i1)
-        """
-        # escapes because getarrayitem_gc uses a non-constant index
-        self.find_nodes(ops, 'Not, Not')
-
-    def test_find_nodes_arrayitem_forced(self):
-        ops = """
-        [p1]
-        p2 = new_array(1, descr=arraydescr)
-        escape(p2)
-        p4 = new_with_vtable(ConstClass(node_vtable))
-        setarrayitem_gc(p2, 0, p4, descr=arraydescr)
-        jump(p4)
-        """
-        self.find_nodes(ops, 'Not')
-
-    def test_find_nodes_struct_virtual_1(self):
-        ops = """
-        [i1, p2]
-        i2 = getfield_gc(p2, descr=adescr)
-        escape(i2)
-        p3 = new(descr=ssize)
-        setfield_gc(p3, i1, descr=adescr)
-        jump(i1, p3)
-        """
-        self.find_nodes(ops, 'Not, VStruct(ssize, adescr=Not)')
-
-    def test_find_nodes_struct_nonvirtual_1(self):
-        ops = """
-        [i1, p2]
-        i2 = getfield_gc(p2, descr=adescr)
-        escape(p2)
-        p3 = new(descr=ssize)
-        setfield_gc(p3, i1, descr=adescr)
-        jump(i1, p3)
-        """
-        self.find_nodes(ops, 'Not, Not')
-
-    def test_find_nodes_guard_value_constant(self):
-        ops = """
-        [p1]
-        guard_value(p1, ConstPtr(myptr)) []
-        jump(ConstPtr(myptr))
-        """
-        self.find_nodes(ops, 'Constant(myptr)')
-
-    def test_find_nodes_guard_value_constant_mismatch(self):
-        ops = """
-        [p1]
-        guard_value(p1, ConstPtr(myptr2)) []
-        jump(ConstPtr(myptr))
-        """
-        py.test.raises(InvalidLoop, self.find_nodes, ops, None)
-
-    def test_find_nodes_guard_value_escaping_constant(self):
-        ops = """
-        [p1]
-        escape(p1)
-        guard_value(p1, ConstPtr(myptr)) []
-        jump(ConstPtr(myptr))
-        """
-        self.find_nodes(ops, 'Constant(myptr)')
-
-    def test_find_nodes_guard_value_same_as_constant(self):
-        ops = """
-        [p1]
-        guard_value(p1, ConstPtr(myptr)) []
-        p2 = same_as(ConstPtr(myptr))
-        jump(p2)
-        """
-        self.find_nodes(ops, 'Constant(myptr)')
-
-    def test_find_nodes_store_into_loop_constant_1(self):
-        ops = """
-        [i0, p1, p4]
-        p2 = new_with_vtable(ConstClass(node_vtable))
-        setfield_gc(p1, p2, descr=nextdescr)
-        jump(i0, p1, p2)
-        """
-        self.find_nodes(ops, 'Not, Not, Not')
-
-    def test_find_nodes_store_into_loop_constant_2(self):
-        ops = """
-        [i0, p4, p1]
-        p2 = new_with_vtable(ConstClass(node_vtable))
-        setfield_gc(p1, p2, descr=nextdescr)
-        jump(i0, p2, p1)
-        """
-        self.find_nodes(ops, 'Not, Not, Not')
-
-    def test_find_nodes_store_into_loop_constant_3(self):
-        ops = """
-        [i0, p1]
-        p2 = new_with_vtable(ConstClass(node_vtable))
-        setfield_gc(p1, p2, descr=nextdescr)
-        call(i0)
-        jump(i0, p1)
-        """
-        self.find_nodes(ops, 'Not, Not')
-
-    def test_find_nodes_arithmetic_propagation_bug_0(self):
-        ops = """
-        [p1]
-        i1 = getarrayitem_gc(p1, 0, descr=arraydescr)
-        escape(i1)
-        i2 = int_add(0, 1)
-        p2 = new_array(i2, descr=arraydescr)
-        i3 = escape()
-        setarrayitem_gc(p2, 0, i3, descr=arraydescr)
-        jump(p2)
-        """
-        self.find_nodes(ops, 'VArray(arraydescr, Not)')
-
-    def test_find_nodes_arithmetic_propagation_bug_1(self):
-        ops = """
-        [p1]
-        i1 = getarrayitem_gc(p1, 0, descr=arraydescr)
-        escape(i1)
-        i2 = same_as(1)
-        p2 = new_array(i2, descr=arraydescr)
-        setarrayitem_gc(p2, 0, 5)
-        jump(p2)
-        """
-        self.find_nodes(ops, 'VArray(arraydescr, Not)')
-
-    def test_find_nodes_arithmetic_propagation_bug_2(self):
-        ops = """
-        [p1]
-        i0 = int_sub(17, 17)
-        i1 = getarrayitem_gc(p1, i0, descr=arraydescr)
-        escape(i1)
-        i2 = int_add(0, 1)
-        p2 = new_array(i2, descr=arraydescr)
-        i3 = escape()
-        setarrayitem_gc(p2, i0, i3, descr=arraydescr)
-        jump(p2)
-        """
-        self.find_nodes(ops, 'VArray(arraydescr, Not)')
-
-    def test_find_nodes_arithmetic_propagation_bug_3(self):
-        ops = """
-        [p1]
-        i1 = getarrayitem_gc(p1, 0, descr=arraydescr)
-        escape(i1)
-        p3 = new_array(1, descr=arraydescr)
-        i2 = arraylen_gc(p3, descr=arraydescr)
-        p2 = new_array(i2, descr=arraydescr)
-        i3 = escape()
-        setarrayitem_gc(p2, 0, i3, descr=arraydescr)
-        jump(p2)
-        """
-        self.find_nodes(ops, 'VArray(arraydescr, Not)')
-
-    def test_find_nodes_bug_1(self):
-        ops = """
-        [p12]
-        guard_nonnull(p12) []
-        guard_class(p12, ConstClass(node_vtable)) []
-        guard_class(p12, ConstClass(node_vtable)) []
-        i22 = getfield_gc_pure(p12, descr=valuedescr)
-        escape(i22)
-        guard_nonnull(p12) []
-        guard_class(p12, ConstClass(node_vtable)) []
-        guard_class(p12, ConstClass(node_vtable)) []
-        i29 = getfield_gc_pure(p12, descr=valuedescr)
-        i31 = int_add_ovf(i29, 1)
-        guard_no_overflow() []
-        p33 = new_with_vtable(ConstClass(node_vtable))      # NODE
-        setfield_gc(p33, i31, descr=valuedescr)
-        #
-        p35 = new_array(1, descr=arraydescr3)               # Array(NODE)
-        setarrayitem_gc(p35, 0, p33, descr=arraydescr3)
-        p38 = new_with_vtable(ConstClass(u_vtable))         # U
-        setfield_gc(p38, p35, descr=onedescr)
-        guard_nonnull(p38) []
-        guard_nonnull(p38) []
-        guard_class(p38, ConstClass(u_vtable)) []
-        p42 = getfield_gc(p38, descr=onedescr)              # Array(NODE)
-        i43 = arraylen_gc(p42, descr=arraydescr3)
-        i45 = int_sub(i43, 0)
-        p46 = new(descr=tsize)                              # T
-        setfield_gc(p46, i45, descr=cdescr)
-        p47 = new_array(i45, descr=arraydescr3)             # Array(NODE)
-        setfield_gc(p46, p47, descr=ddescr)
-        i48 = int_lt(0, i43)
-        guard_true(i48) []
-        p49 = getarrayitem_gc(p42, 0, descr=arraydescr3)    # NODE
-        p50 = getfield_gc(p46, descr=ddescr)                # Array(NODE)
-        setarrayitem_gc(p50, 0, p49, descr=arraydescr3)
-        i52 = int_lt(1, i43)
-        guard_false(i52) []
-        i53 = getfield_gc(p46, descr=cdescr)
-        i55 = int_ne(i53, 1)
-        guard_false(i55) []
-        p56 = getfield_gc(p46, descr=ddescr)                # Array(NODE)
-        p58 = getarrayitem_gc(p56, 0, descr=arraydescr3)    # NODE
-        guard_nonnull(p38) []
-        jump(p58)
-        """
-        self.find_nodes(ops, 'Virtual(node_vtable, valuedescr=Not)')
-
-    # ------------------------------
-    # Bridge tests
-
-    def find_bridge(self, ops, inputspectext, outputspectext, boxkinds=None,
-                    mismatch=False):
-        assert boxkinds is None or isinstance(boxkinds, dict)
-        inputspecnodes = self.unpack_specnodes(inputspectext)
-        outputspecnodes = self.unpack_specnodes(outputspectext)
-        bridge = self.parse(ops, boxkinds=boxkinds)
-        bridge_specialization_finder = BridgeSpecializationFinder(self.cpu)
-        bridge_specialization_finder.find_nodes_bridge(bridge, inputspecnodes)
-        matches = bridge_specialization_finder.bridge_matches(outputspecnodes)
-        if mismatch:
-            assert not matches
-        else:
-            assert matches
-
-    def test_bridge_simple(self):
-        ops = """
-        [i0]
-        i1 = int_add(i0, 1)
-        jump(i1)
-        """
-        self.find_bridge(ops, 'Not', 'Not')
-        self.find_bridge(ops, 'Not', 'Virtual(node_vtable)', mismatch=True)
-
-    def test_bridge_simple_known_class(self):
-        ops = """
-        [p0]
-        setfield_gc(p0, 123, descr=valuedescr)
-        jump(p0)
-        """
-        self.find_bridge(ops, 'Not', 'Not')
-
-    def test_bridge_simple_constant(self):
-        ops = """
-        []
-        jump(ConstPtr(myptr))
-        """
-        self.find_bridge(ops, '', 'Not')
-        self.find_bridge(ops, '', 'Constant(myptr)')
-        self.find_bridge(ops, '', 'Constant(myptr2)', mismatch=True)
-
-    def test_bridge_simple_constant_mismatch(self):
-        ops = """
-        [p0]
-        jump(p0)
-        """
-        self.find_bridge(ops, 'Not', 'Not')
-        self.find_bridge(ops, 'Not', 'Constant(myptr)', mismatch=True)
-
-    def test_bridge_simple_virtual_1(self):
-        ops = """
-        [i0]
-        p0 = new_with_vtable(ConstClass(node_vtable))
-        setfield_gc(p0, i0, descr=valuedescr)
-        jump(p0)
-        """
-        self.find_bridge(ops, 'Not', 'Not')
-        self.find_bridge(ops, 'Not', 'Virtual(node_vtable, valuedescr=Not)')
-        self.find_bridge(ops, 'Not',
-                         '''Virtual(node_vtable,
-                                    valuedescr=Not,
-                                    nextdescr=Not)''')
-        #
-        self.find_bridge(ops, 'Not', 'Virtual(node_vtable)',
-                         mismatch=True)   # missing valuedescr
-        self.find_bridge(ops, 'Not', 'Virtual(node_vtable, nextdescr=Not)',
-                         mismatch=True)   # missing valuedescr
-        self.find_bridge(ops, 'Not', 'Virtual(node_vtable2, valuedescr=Not)',
-                         mismatch=True)   # bad class
-
-    def test_bridge_simple_virtual_struct(self):
-        ops = """
-        [i0]
-        p0 = new(descr=ssize)
-        setfield_gc(p0, i0, descr=adescr)
-        jump(p0)
-        """
-        self.find_bridge(ops, 'Not', 'Not')
-        self.find_bridge(ops, 'Not', 'VStruct(ssize, adescr=Not)')
-
-    def test_bridge_simple_virtual_struct_non_unique(self):
-        ops = """
-        [i0]
-        p0 = new(descr=ssize)
-        setfield_gc(p0, i0, descr=adescr)
-        jump(p0, p0)
-        """
-        self.find_bridge(ops, 'Not', 'Not, Not')
-        self.find_bridge(ops, 'Not', 'VStruct(ssize), VStruct(ssize)',
-                         mismatch=True)
-
-
-    def test_bridge_simple_virtual_2(self):
-        ops = """
-        [p0]
-        setfield_gc(p0, 123, descr=valuedescr)
-        jump(p0)
-        """
-        self.find_bridge(ops, 'Virtual(node_vtable)', 'Not')
-        self.find_bridge(ops, 'Virtual(node_vtable)',
-                              'Virtual(node_vtable, valuedescr=Not)')
-        self.find_bridge(ops, 'Virtual(node_vtable, valuedescr=Not)',
-                              'Virtual(node_vtable, valuedescr=Not)')
-        self.find_bridge(ops, 'Virtual(node_vtable, valuedescr=Not)',
-                            '''Virtual(node_vtable,
-                                       valuedescr=Not,
-                                       nextdescr=Not)''')
-        self.find_bridge(ops, '''Virtual(node_vtable,
-                                         valuedescr=Not,
-                                         nextdescr=Not)''',
-                              '''Virtual(node_vtable,
-                                         valuedescr=Not,
-                                         nextdescr=Not)''')
-        #
-        self.find_bridge(ops, 'Virtual(node_vtable)', 'Virtual(node_vtable)',
-                         mismatch=True)    # because of missing valuedescr
-        self.find_bridge(ops, 'Virtual(node_vtable)',
-                         'Virtual(node_vtable2, valuedescr=Not)',
-                         mismatch=True)    # bad class
-
-    def test_bridge_virtual_mismatch_1(self):
-        ops = """
-        [i0]
-        p0 = new_with_vtable(ConstClass(node_vtable))
-        setfield_gc(p0, i0, descr=valuedescr)
-        jump(p0, p0)
-        """
-        self.find_bridge(ops, 'Not', 'Not, Not')
-        #
-        self.find_bridge(ops, 'Not',
-                         '''Virtual(node_vtable, valuedescr=Not),
-                            Virtual(node_vtable, valuedescr=Not)''',
-                         mismatch=True)    # duplicate p0
-
-    def test_bridge_guard_class(self):
-        ops = """
-        [p1]
-        p2 = getfield_gc(p1, descr=nextdescr)
-        guard_class(p2, ConstClass(node_vtable)) []
-        jump(p2)
-        """
-        self.find_bridge(ops, 'Not', 'Not')
-        self.find_bridge(ops, 'Virtual(node_vtable2, nextdescr=Not)', 'Not')
-        self.find_bridge(ops,
-            '''Virtual(node_vtable,
-                       nextdescr=Virtual(node_vtable,
-                                         nextdescr=Not))''',
-            '''Virtual(node_vtable,
-                       nextdescr=Not)''')
-        #
-        self.find_bridge(ops, 'Not', 'Virtual(node_vtable)',
-                         mismatch=True)
-
-    def test_bridge_unused(self):
-        ops = """
-        []
-        p1 = new_with_vtable(ConstClass(node_vtable))
-        p2 = new_with_vtable(ConstClass(node_vtable))
-        p3 = new_with_vtable(ConstClass(node_vtable))
-        setfield_gc(p1, p2, descr=nextdescr)
-        setfield_gc(p2, p3, descr=nextdescr)
-        jump(p1)
-        """
-        self.find_bridge(ops, '',
-            '''Not''')
-        self.find_bridge(ops, '',
-            '''Virtual(node_vtable,
-                       nextdescr=Not)''')
-        self.find_bridge(ops, '',
-            '''Virtual(node_vtable,
-                       nextdescr=Virtual(node_vtable,
-                                         nextdescr=Not))''')
-        self.find_bridge(ops, '',
-            '''Virtual(node_vtable,
-                       nextdescr=Virtual(node_vtable,
-                                         nextdescr=Virtual(node_vtable)))''')
-        self.find_bridge(ops, '',
-            '''Virtual(node_vtable,
-                       nextdescr=Virtual(node_vtable,
-                                         nextdescr=Virtual(node_vtable,
-                                                           nextdescr=Not)))''')
-
-    def test_bridge_to_finish(self):
-        ops = """
-        [i1]
-        i2 = int_add(i1, 5)
-        finish(i2)
-        """
-        self.find_bridge(ops, 'Not', 'Not')
-
-    def test_bridge_virtual_to_finish(self):
-        ops = """
-        [i1]
-        p1 = new_with_vtable(ConstClass(node_vtable))
-        setfield_gc(p1, i1, descr=valuedescr)
-        finish(p1)
-        """
-        self.find_bridge(ops, 'Not', 'Not')
-        self.find_bridge(ops, 'Not',
-                         'Virtual(node_vtable, valuedescr=Not)',
-                         mismatch=True)
-
-    def test_bridge_array_virtual_1(self):
-        ops = """
-        [i1]
-        p1 = new_array(3, descr=arraydescr)
-        setarrayitem_gc(p1, 0, i1, descr=arraydescr)
-        jump(p1)
-        """
-        self.find_bridge(ops, 'Not', 'Not')
-        self.find_bridge(ops, 'Not', 'VArray(arraydescr, Not, Not, Not)')
-
-    def test_bridge_array_virtual_size_mismatch(self):
-        ops = """
-        [i1]
-        p1 = new_array(5, descr=arraydescr)
-        setarrayitem_gc(p1, 0, i1, descr=arraydescr)
-        jump(p1)
-        """
-        self.find_bridge(ops, 'Not', 'Not')
-        self.find_bridge(ops, 'Not', 'VArray(arraydescr, Not, Not, Not)',
-                         mismatch=True)
-
-    def test_bridge_array_virtual_2(self):
-        ops = """
-        [i1]
-        p1 = new_array(3, descr=arraydescr)
-        setarrayitem_gc(p1, 0, i1, descr=arraydescr)
-        escape(p1)
-        jump(p1)
-        """
-        self.find_bridge(ops, 'Not', 'Not')
-        self.find_bridge(ops, 'Not', 'VArray(arraydescr, Not, Not, Not)',
-                         mismatch=True)
-
-    def test_bridge_nested_structs(self):
-        ops = """
-        []
-        p1 = new_with_vtable(ConstClass(node_vtable))
-        p2 = new_with_vtable(ConstClass(node_vtable))
-        setfield_gc(p1, p2, descr=nextdescr)
-        jump(p1)
-        """
-        self.find_bridge(ops, '', 'Not')
-        self.find_bridge(ops, '', 'Virtual(node_vtable, nextdescr=Not)')
-        self.find_bridge(ops, '',
-                   'Virtual(node_vtable, nextdescr=Virtual(node_vtable))')
-        self.find_bridge(ops, '',
-                   'Virtual(node_vtable, nextdescr=Virtual(node_vtable2))',
-                   mismatch=True)
-
-
-class TestLLtype(BaseTestOptimizeFindNode, LLtypeMixin):
-    pass
-
-##class TestOOtype(BaseTestOptimizeFindNode, OOtypeMixin):
-##    def test_find_nodes_instanceof(self):
-##        ops = """
-##        [i0]
-##        p0 = new_with_vtable(ConstClass(node_vtable))
-##        i1 = instanceof(p0, descr=nodesize)
-##        jump(i1)
-##        """
-##        boxes, getnode = self.find_nodes(ops, 'Not')
-##        assert not getnode(boxes.p0).escaped



diff --git a/pypy/jit/backend/llgraph/runner.py b/pypy/jit/backend/llgraph/runner.py
--- a/pypy/jit/backend/llgraph/runner.py
+++ b/pypy/jit/backend/llgraph/runner.py
@@ -202,6 +202,7 @@
                         llimpl.compile_add_fail_arg(c, var2index[box])
                     else:
                         llimpl.compile_add_fail_arg(c, -1)
+                        
             x = op.result
             if x is not None:
                 if isinstance(x, history.BoxInt):





diff --git a/pypy/jit/metainterp/test/test_loop_nopspec.py b/pypy/jit/metainterp/test/test_loop_nopspec.py
deleted file mode 100644
--- a/pypy/jit/metainterp/test/test_loop_nopspec.py
+++ /dev/null
@@ -1,27 +0,0 @@
-
-from pypy.jit.metainterp.test import test_loop, test_send
-from pypy.jit.metainterp.warmspot import ll_meta_interp
-from pypy.rlib.jit import OPTIMIZER_NO_PERFECTSPEC
-from pypy.jit.metainterp.test.test_basic import LLJitMixin, OOJitMixin
-
-class LoopNoPSpecTest(test_send.SendTests):
-    def meta_interp(self, func, args, **kwds):
-        return ll_meta_interp(func, args, optimizer=OPTIMIZER_NO_PERFECTSPEC,
-                              CPUClass=self.CPUClass, 
-                              type_system=self.type_system,
-                              **kwds)
-
-    def check_loops(self, *args, **kwds):
-        pass
-
-    def check_loop_count(self, count):
-        pass
-
-    def check_jumps(self, maxcount):
-        pass
-
-class TestLLtype(LoopNoPSpecTest, LLJitMixin):
-    pass
-
-class TestOOtype(LoopNoPSpecTest, OOJitMixin):
-    pass



diff --git a/pypy/jit/metainterp/viewnode.py b/pypy/jit/metainterp/viewnode.py
deleted file mode 100644
--- a/pypy/jit/metainterp/viewnode.py
+++ /dev/null
@@ -1,124 +0,0 @@
-import py
-from pypy.jit.metainterp import specnode, optimizefindnode
-from pypy.tool.pairtype import extendabletype
-
-class __extend__(specnode.NotSpecNode):
-    def _dot(self, seen):
-        if self in seen:
-            return
-        seen.add(self)
-        yield '%s [label="<Not>"]' % (id(self), )
-
-class __extend__(specnode.ConstantSpecNode):
-    def _dot(self, seen):
-        if self in seen:
-            return
-        seen.add(self)
-        yield '%s [label="<Const: %s>"]' % (id(self), self.constbox)
-
-class __extend__(specnode.AbstractVirtualStructSpecNode):
-    def _dot(self, seen):
-        if self in seen:
-            return
-        seen.add(self)
-        yield '%s [label="<%s>"]' % (
-                id(self),
-                self.__class__.__name__[:-len("SpecNode")])
-        for label, node in self.fields:
-            yield '%s -> %s [label="%s"]' % (id(self), id(node), label.name)
-            for line in node._dot(seen):
-                yield line
-
-class __extend__(specnode.VirtualArraySpecNode):
-    def _dot(self, seen):
-        if self in seen:
-            return
-        seen.add(self)
-        yield '%s [label="<Array: %s>"]' % (
-                id(self),
-                len(self.items))
-        for i, node in enumerate(self.items):
-            yield '%s -> %s [label="%s"]' % (id(self), id(node), i)
-            for line in node._dot(seen):
-                yield line
-
-
-class __extend__(optimizefindnode.InstanceNode):
-    __metaclass__ = extendabletype # evil
-
-    def _dot(self, seen):
-        if self in seen:
-            return
-        seen.add(self)
-        if self.knownclsbox:
-            name = "Virtual "
-            if isinstance(self.knownclsbox.value, int):
-                name += str(self.knownclsbox.value)
-            else:
-                name += str(self.knownclsbox.value.adr.ptr).rpartition("_vtable")[0].rpartition('.')[2]
-        elif self.structdescr:
-            name = "Struct " + str(self.structdescr)
-        elif self.arraydescr:
-            name = "Array"
-        else:
-            name = "Not"
-        if self.escaped:
-            name = "ESC " + name
-        if self.fromstart:
-            name = "START " + name
-        if self.unique == optimizefindnode.UNIQUE_NO:
-            color = "blue"
-        else:
-            color = "black"
-
-        yield 'orig%s [label="in: [%s]", shape=box, color=%s]' % (
-                id(self), name, color)
-        yield '%s [label="out: [%s]", shape=box, color=%s]' % (
-                id(self), name, color)
-        yield 'orig%s -> %s [color=red]' % (id(self), id(self))
-        if self.origfields:
-            for descr, node in self.origfields.iteritems():
-                yield 'orig%s -> orig%s [label="%s"]' % (id(self), id(node), descr.name)
-                for line in node._dot(seen):
-                    yield line
-        if self.curfields:
-            for descr, node in self.curfields.iteritems():
-                yield '%s -> %s [label="%s"]' % (id(self), id(node), descr.name)
-                for line in node._dot(seen):
-                    yield line
-        if self.origitems:
-            for i, node in sorted(self.origitems.iteritems()):
-                yield 'orig%s -> orig%s [label="%s"]' % (id(self), id(node), i)
-                for line in node._dot(seen):
-                    yield line
-        if self.curitems:
-            for i, node in sorted(self.curitems.iteritems()):
-                yield '%s -> %s [label="%s"]' % (id(self), id(node), i)
-                for line in node._dot(seen):
-                    yield line
-
-
-def view(*objects):
-    from dotviewer import graphclient
-    content = ["digraph G{"]
-    seen = set()
-    for obj in objects:
-        content.extend(obj._dot(seen))
-    content.append("}")
-    p = py.test.ensuretemp("specnodes").join("temp.dot")
-    p.write("\n".join(content))
-    graphclient.display_dot_file(str(p))
-
-def viewnodes(l1, l2):
-    from dotviewer import graphclient
-    content = ["digraph G{"]
-    seen = set()
-    for obj in l1 + l2:
-        content.extend(obj._dot(seen))
-    for i, (o1, o2) in enumerate(zip(l1, l2)):
-        content.append("%s -> %s [color=green]" % (id(o1), i))
-        content.append("%s -> orig%s [color=green]" % (i, id(o2)))
-    content.append("}")
-    p = py.test.ensuretemp("specnodes").join("temp.dot")
-    p.write("\n".join(content))
-    graphclient.display_dot_file(str(p))

diff --git a/pypy/jit/backend/llgraph/llimpl.py b/pypy/jit/backend/llgraph/llimpl.py
--- a/pypy/jit/backend/llgraph/llimpl.py
+++ b/pypy/jit/backend/llgraph/llimpl.py
@@ -373,6 +373,13 @@
     else:
         log.info("compiling new bridge")
 
+def compile_add_guard_jump_target(loop, loop_target):
+    loop = _from_opaque(loop)
+    loop_target = _from_opaque(loop_target)
+    op = loop.operations[-1]
+    assert op.is_guard()
+    op.jump_target = loop_target
+
 def compile_add_fail(loop, fail_index):
     loop = _from_opaque(loop)
     index = len(loop.operations)-1
@@ -1634,6 +1641,7 @@
 setannotation(compile_add_ref_result, annmodel.SomeInteger())
 setannotation(compile_add_float_result, annmodel.SomeInteger())
 setannotation(compile_add_jump_target, annmodel.s_None)
+setannotation(compile_add_guard_jump_target, annmodel.s_None)
 setannotation(compile_add_fail, annmodel.SomeInteger())
 setannotation(compile_add_fail_arg, annmodel.s_None)
 setannotation(compile_redirect_fail, annmodel.s_None)




diff --git a/pypy/jit/metainterp/test/test_specnode.py b/pypy/jit/metainterp/test/test_specnode.py
deleted file mode 100644
--- a/pypy/jit/metainterp/test/test_specnode.py
+++ /dev/null
@@ -1,132 +0,0 @@
-from pypy.rpython.lltypesystem import lltype, llmemory
-from pypy.jit.metainterp.history import AbstractDescr, BoxPtr, ConstInt, ConstPtr
-from pypy.jit.metainterp.specnode import prebuiltNotSpecNode
-from pypy.jit.metainterp.specnode import VirtualInstanceSpecNode
-from pypy.jit.metainterp.specnode import VirtualArraySpecNode
-from pypy.jit.metainterp.specnode import VirtualStructSpecNode
-from pypy.jit.metainterp.specnode import ConstantSpecNode
-from pypy.jit.metainterp.specnode import equals_specnodes
-from pypy.jit.metainterp.specnode import more_general_specnodes
-from pypy.jit.metainterp.test.test_optimizefindnode import LLtypeMixin
-
-def _get_vspecnode(classnum=123):
-    return VirtualInstanceSpecNode(ConstInt(classnum),
-                         [(LLtypeMixin.valuedescr, prebuiltNotSpecNode),
-                          (LLtypeMixin.nextdescr,  prebuiltNotSpecNode)])
-
-def _get_aspecnode(length=2):
-    return VirtualArraySpecNode(LLtypeMixin.arraydescr,
-                                [prebuiltNotSpecNode] * length)
-
-def _get_sspecnode():
-    return VirtualStructSpecNode(LLtypeMixin.ssize,
-                                 [(LLtypeMixin.adescr, prebuiltNotSpecNode),
-                                  (LLtypeMixin.bdescr, prebuiltNotSpecNode)])
-
-def _get_cspecnode(s):
-    from pypy.rpython.module.support import LLSupport        
-    llstr = lltype.cast_opaque_ptr(llmemory.GCREF, LLSupport.to_rstr(s))
-    box = ConstPtr(llstr)
-    return ConstantSpecNode(box)
-
-def test_equals_specnodes():
-    assert equals_specnodes([prebuiltNotSpecNode, prebuiltNotSpecNode],
-                            [prebuiltNotSpecNode, prebuiltNotSpecNode])
-    vspecnode1 = _get_vspecnode(1)
-    vspecnode2 = _get_vspecnode(2)
-    assert equals_specnodes([vspecnode1], [vspecnode1])
-    assert not equals_specnodes([vspecnode1], [vspecnode2])
-    assert not equals_specnodes([vspecnode1], [prebuiltNotSpecNode])
-    assert not equals_specnodes([prebuiltNotSpecNode], [vspecnode2])
-    aspecnode1 = _get_aspecnode(1)
-    aspecnode2 = _get_aspecnode(2)
-    assert equals_specnodes([aspecnode2], [aspecnode2])
-    assert not equals_specnodes([aspecnode1], [aspecnode2])
-    assert not equals_specnodes([aspecnode1], [prebuiltNotSpecNode])
-    assert not equals_specnodes([prebuiltNotSpecNode], [aspecnode2])
-    sspecnode1 = _get_sspecnode()
-    assert equals_specnodes([sspecnode1], [sspecnode1])
-    assert not equals_specnodes([sspecnode1], [prebuiltNotSpecNode])
-    assert not equals_specnodes([prebuiltNotSpecNode], [sspecnode1])
-    #
-    foonode = _get_cspecnode('foo')
-    barnode = _get_cspecnode('bar')
-    assert equals_specnodes([foonode], [foonode])
-    assert not equals_specnodes([foonode], [barnode])
-    assert not equals_specnodes([foonode], [prebuiltNotSpecNode])
-
-def test_more_general_specnodes():
-    assert more_general_specnodes([prebuiltNotSpecNode, prebuiltNotSpecNode],
-                                  [prebuiltNotSpecNode, prebuiltNotSpecNode])
-    vspecnode1 = _get_vspecnode(1)
-    vspecnode2 = _get_vspecnode(2)
-    assert more_general_specnodes([vspecnode1], [vspecnode1])
-    assert not more_general_specnodes([vspecnode1], [vspecnode2])
-    assert not more_general_specnodes([vspecnode1], [prebuiltNotSpecNode])
-    assert more_general_specnodes([prebuiltNotSpecNode], [vspecnode2])
-    aspecnode1 = _get_aspecnode(1)
-    aspecnode2 = _get_aspecnode(2)
-    assert more_general_specnodes([aspecnode2], [aspecnode2])
-    assert not more_general_specnodes([aspecnode1], [aspecnode2])
-    assert not more_general_specnodes([aspecnode1], [prebuiltNotSpecNode])
-    assert more_general_specnodes([prebuiltNotSpecNode], [aspecnode2])
-    sspecnode1 = _get_sspecnode()
-    assert more_general_specnodes([sspecnode1], [sspecnode1])
-    assert not more_general_specnodes([sspecnode1], [prebuiltNotSpecNode])
-    assert more_general_specnodes([prebuiltNotSpecNode], [sspecnode1])
-    #
-    foonode = _get_cspecnode('foo')
-    barnode = _get_cspecnode('bar')
-    assert more_general_specnodes([foonode], [foonode])
-    assert not more_general_specnodes([foonode], [barnode])
-    assert not more_general_specnodes([foonode], [prebuiltNotSpecNode])
-    assert more_general_specnodes([prebuiltNotSpecNode], [foonode])
-
-def test_extract_runtime_data_0():
-    res = []
-    node = _get_cspecnode('foo')
-    node.extract_runtime_data("cpu", "box1", res)
-    assert res == []
-
-def test_extract_runtime_data_1():
-    res = []
-    prebuiltNotSpecNode.extract_runtime_data("cpu", "box1", res)
-    prebuiltNotSpecNode.extract_runtime_data("cpu", "box2", res)
-    assert res == ["box1", "box2"]
-
-def test_extract_runtime_data_2():
-    structure = lltype.malloc(LLtypeMixin.NODE)
-    structure.value = 515
-    structure.next = lltype.malloc(LLtypeMixin.NODE)
-    structbox = BoxPtr(lltype.cast_opaque_ptr(llmemory.GCREF, structure))
-    vspecnode = _get_vspecnode()
-    res = []
-    vspecnode.extract_runtime_data(LLtypeMixin.cpu, structbox, res)
-    assert len(res) == 2
-    assert res[0].value == structure.value
-    assert res[1].value._obj.container._as_ptr() == structure.next
-
-def test_extract_runtime_data_3():
-    array = lltype.malloc(lltype.GcArray(lltype.Signed), 2)
-    array[0] = 123
-    array[1] = 456
-    arraybox = BoxPtr(lltype.cast_opaque_ptr(llmemory.GCREF, array))
-    aspecnode = _get_aspecnode()
-    res = []
-    aspecnode.extract_runtime_data(LLtypeMixin.cpu, arraybox, res)
-    assert len(res) == 2
-    assert res[0].value == 123
-    assert res[1].value == 456
-
-def test_extract_runtime_data_4():
-    struct = lltype.malloc(LLtypeMixin.S)
-    struct.a = 123
-    struct.b = lltype.malloc(LLtypeMixin.NODE)
-    structbox = BoxPtr(lltype.cast_opaque_ptr(llmemory.GCREF, struct))
-    sspecnode = _get_sspecnode()
-    res = []
-    sspecnode.extract_runtime_data(LLtypeMixin.cpu, structbox, res)
-    assert len(res) == 2
-    assert res[0].value == 123
-    assert (lltype.cast_opaque_ptr(lltype.Ptr(LLtypeMixin.NODE), res[1].value)
-            == struct.b)

diff --git a/pypy/config/test/test_support.py b/pypy/config/test/test_support.py
--- a/pypy/config/test/test_support.py
+++ b/pypy/config/test/test_support.py
@@ -45,7 +45,7 @@
     saved = os.environ
     try:
         os.environ = FakeEnviron(None)
-        assert detect_number_of_processors(StringIO(cpuinfo)) == 4
+        assert detect_number_of_processors(StringIO(cpuinfo)) == 3
         assert detect_number_of_processors('random crap that does not exist') == 1
         os.environ = FakeEnviron('-j2')
         assert detect_number_of_processors(StringIO(cpuinfo)) == 1


diff --git a/pypy/jit/metainterp/optimizefindnode.py b/pypy/jit/metainterp/optimizefindnode.py
deleted file mode 100644
--- a/pypy/jit/metainterp/optimizefindnode.py
+++ /dev/null
@@ -1,576 +0,0 @@
-from pypy.jit.metainterp.specnode import SpecNode
-from pypy.jit.metainterp.specnode import NotSpecNode, prebuiltNotSpecNode
-from pypy.jit.metainterp.specnode import ConstantSpecNode
-from pypy.jit.metainterp.specnode import VirtualInstanceSpecNode
-from pypy.jit.metainterp.specnode import VirtualArraySpecNode
-from pypy.jit.metainterp.specnode import VirtualStructSpecNode
-from pypy.jit.metainterp.history import AbstractValue, ConstInt, Const
-from pypy.jit.metainterp.resoperation import rop
-from pypy.jit.metainterp.executor import execute_nonspec
-from pypy.jit.metainterp.optimizeutil import _findall, sort_descrs
-from pypy.jit.metainterp.optimizeutil import InvalidLoop
-
-# ____________________________________________________________
-
-UNIQUE_UNKNOWN = '\x00'
-UNIQUE_NO      = '\x01'
-UNIQUE_INST    = '\x02'
-UNIQUE_ARRAY   = '\x03'
-UNIQUE_STRUCT  = '\x04'
-
-class InstanceNode(object):
-    """An instance of this class is used to match the start and
-    the end of the loop, so it contains both 'origfields' that represents
-    the field's status at the start and 'curfields' that represents it
-    at the current point (== the end when optimizefindnode is complete).
-    """
-    escaped = False     # if True, then all the rest of the info is pointless
-    unique = UNIQUE_UNKNOWN   # for find_unique_nodes()
-
-    # fields used to store the shape of the potential VirtualInstance
-    knownclsbox = None  # set only on freshly-allocated or fromstart structures
-    origfields = None   # optimization; equivalent to an empty dict
-    curfields = None    # optimization; equivalent to an empty dict
-
-    knownvaluebox = None # a Const with the value of this box, if constant
-
-    # fields used to store the shape of the potential VirtualList
-    arraydescr = None   # set only on freshly-allocated or fromstart arrays
-    #arraysize = ..     # valid if and only if arraydescr is not None
-    origitems = None    # optimization; equivalent to an empty dict
-    curitems = None     # optimization; equivalent to an empty dict
-
-    # fields used to store the shape of the potential VirtualStruct
-    structdescr = None  # set only on freshly-allocated or fromstart structs
-    #origfields = ..    # same as above
-    #curfields = ..     # same as above
-
-    dependencies = None
-
-    def __init__(self, fromstart=False):
-        self.fromstart = fromstart    # for loops only: present since the start
-
-    def is_constant(self):
-        return self.knownvaluebox is not None
-
-    def add_escape_dependency(self, other):
-        assert not self.escaped
-        if self.dependencies is None:
-            self.dependencies = []
-        self.dependencies.append(other)
-
-    def mark_escaped(self):
-        # invariant: if escaped=True, then dependencies is None
-        if not self.escaped:
-            self.escaped = True
-            self.unique = UNIQUE_NO
-            # ^^^ always set unique to UNIQUE_NO when we set escaped to True.
-            # See for example test_find_nodes_store_into_loop_constant_2.
-            if self.dependencies is not None:
-                deps = self.dependencies
-                self.dependencies = None
-                for box in deps:
-                    box.mark_escaped()
-
-    def set_unique_nodes(self):
-        if self.fromstart:
-            self.mark_escaped()
-        if self.escaped or self.unique != UNIQUE_UNKNOWN:
-            # this node is not suitable for being a virtual, or we
-            # encounter it more than once when doing the recursion
-            self.unique = UNIQUE_NO
-        elif self.knownclsbox is not None:
-            self.unique = UNIQUE_INST
-            if self.curfields is not None:
-                for subnode in self.curfields.itervalues():
-                    subnode.set_unique_nodes()
-        elif self.arraydescr is not None:
-            self.unique = UNIQUE_ARRAY
-            if self.curitems is not None:
-                for subnode in self.curitems.itervalues():
-                    subnode.set_unique_nodes()
-        elif self.structdescr is not None:
-            self.unique = UNIQUE_STRUCT
-            if self.curfields is not None:
-                for subnode in self.curfields.itervalues():
-                    subnode.set_unique_nodes()
-        else:
-            assert 0, "most probably unreachable"
-
-    def __repr__(self):
-        flags = ''
-        if self.escaped:     flags += 'e'
-        if self.fromstart:   flags += 's'
-        if self.knownclsbox: flags += 'c'
-        if self.arraydescr:  flags += str(self.arraysize)
-        if self.structdescr: flags += 'S'
-        return "<InstanceNode (%s)>" % (flags,)
-
-# ____________________________________________________________
-# General find_nodes_xxx() interface, for both loops and bridges
-
-class NodeFinder(object):
-    """Abstract base class."""
-    node_escaped = InstanceNode()
-    node_escaped.unique = UNIQUE_NO
-    node_escaped.escaped = True
-
-    def __init__(self, cpu):
-        self.cpu = cpu
-        self.nodes = {}     # Box -> InstanceNode
-
-    def getnode(self, box):
-        if isinstance(box, Const):
-            return self.set_constant_node(box, box)
-        return self.nodes.get(box, self.node_escaped)
-
-    def set_constant_node(self, box, constbox):
-        assert isinstance(constbox, Const)
-        node = InstanceNode()
-        node.unique = UNIQUE_NO
-        node.escaped = True
-        node.knownvaluebox = constbox
-        self.nodes[box] = node
-        return node
-
-    def get_constant_box(self, box):
-        if isinstance(box, Const):
-            return box
-        try:
-            node = self.nodes[box]
-        except KeyError:
-            return None
-        else:
-            return node.knownvaluebox
-
-    def find_nodes(self, operations):
-        for op in operations:
-            opnum = op.getopnum()
-            for value, func in find_nodes_ops:
-                if opnum == value:
-                    func(self, op)
-                    break
-            else:
-                self.find_nodes_default(op)
-
-    def find_nodes_default(self, op):
-        if op.is_always_pure():
-            for i in range(op.numargs()):
-                arg = op.getarg(i)
-                if self.get_constant_box(arg) is None:
-                    break
-            else:
-                # all constant arguments: we can constant-fold
-                argboxes = [self.get_constant_box(op.getarg(i))
-                            for i in range(op.numargs())]
-                resbox = execute_nonspec(self.cpu, None,
-                                         op.getopnum(), argboxes, op.getdescr())
-                self.set_constant_node(op.result, resbox.constbox())
-        # default case: mark the arguments as escaping
-        for i in range(op.numargs()):
-            self.getnode(op.getarg(i)).mark_escaped()
-
-    def find_nodes_no_escape(self, op):
-        pass    # for operations that don't escape their arguments
-
-    find_nodes_PTR_EQ        = find_nodes_no_escape
-    find_nodes_PTR_NE        = find_nodes_no_escape
-    ##find_nodes_INSTANCEOF    = find_nodes_no_escape
-    find_nodes_GUARD_NONNULL = find_nodes_no_escape
-    find_nodes_GUARD_ISNULL  = find_nodes_no_escape
-
-    def find_nodes_NEW_WITH_VTABLE(self, op):
-        instnode = InstanceNode()
-        box = op.getarg(0)
-        assert isinstance(box, Const)
-        instnode.knownclsbox = box
-        self.nodes[op.result] = instnode
-
-    def find_nodes_NEW(self, op):
-        instnode = InstanceNode()
-        instnode.structdescr = op.getdescr()
-        self.nodes[op.result] = instnode
-
-    def find_nodes_NEW_ARRAY(self, op):
-        lengthbox = op.getarg(0)
-        lengthbox = self.get_constant_box(lengthbox)
-        if lengthbox is None:
-            return     # var-sized arrays are not virtual
-        arraynode = InstanceNode()
-        arraynode.arraysize = lengthbox.getint()
-        arraynode.arraydescr = op.getdescr()
-        self.nodes[op.result] = arraynode
-
-    def find_nodes_ARRAYLEN_GC(self, op):
-        arraynode = self.getnode(op.getarg(0))
-        if arraynode.arraydescr is not None:
-            resbox = ConstInt(arraynode.arraysize)
-            self.set_constant_node(op.result, resbox)
-
-    def find_nodes_GUARD_CLASS(self, op):
-        instnode = self.getnode(op.getarg(0))
-        if instnode.fromstart:    # only useful (and safe) in this case
-            box = op.getarg(1)
-            assert isinstance(box, Const)
-            instnode.knownclsbox = box
-
-    def find_nodes_GUARD_VALUE(self, op):
-        instnode = self.getnode(op.getarg(0))
-        if instnode.fromstart:    # only useful (and safe) in this case
-            box = op.getarg(1)
-            assert isinstance(box, Const)
-            instnode.knownvaluebox = box
-
-    def find_nodes_SETFIELD_GC(self, op):
-        instnode = self.getnode(op.getarg(0))
-        fieldnode = self.getnode(op.getarg(1))
-        if instnode.escaped:
-            fieldnode.mark_escaped()
-            return     # nothing to be gained from tracking the field
-        field = op.getdescr()
-        assert isinstance(field, AbstractValue)
-        if instnode.curfields is None:
-            instnode.curfields = {}
-        instnode.curfields[field] = fieldnode
-        instnode.add_escape_dependency(fieldnode)
-
-    def find_nodes_GETFIELD_GC(self, op):
-        instnode = self.getnode(op.getarg(0))
-        if instnode.escaped:
-            return     # nothing to be gained from tracking the field
-        field = op.getdescr()
-        assert isinstance(field, AbstractValue)
-        if instnode.curfields is not None and field in instnode.curfields:
-            fieldnode = instnode.curfields[field]
-        elif instnode.origfields is not None and field in instnode.origfields:
-            fieldnode = instnode.origfields[field]
-        elif instnode.fromstart:
-            fieldnode = InstanceNode(fromstart=True)
-            instnode.add_escape_dependency(fieldnode)
-            if instnode.origfields is None:
-                instnode.origfields = {}
-            instnode.origfields[field] = fieldnode
-        else:
-            return    # nothing to be gained from tracking the field
-        self.nodes[op.result] = fieldnode
-
-    find_nodes_GETFIELD_GC_PURE = find_nodes_GETFIELD_GC
-
-    def find_nodes_SETARRAYITEM_GC(self, op):
-        indexbox = op.getarg(1)
-        indexbox = self.get_constant_box(indexbox)
-        if indexbox is None:
-            self.find_nodes_default(op)            # not a Const index
-            return
-        arraynode = self.getnode(op.getarg(0))
-        itemnode = self.getnode(op.getarg(2))
-        if arraynode.escaped:
-            itemnode.mark_escaped()
-            return     # nothing to be gained from tracking the item
-        if arraynode.curitems is None:
-            arraynode.curitems = {}
-        arraynode.curitems[indexbox.getint()] = itemnode
-        arraynode.add_escape_dependency(itemnode)
-
-    def find_nodes_GETARRAYITEM_GC(self, op):
-        indexbox = op.getarg(1)
-        indexbox = self.get_constant_box(indexbox)
-        if indexbox is None:
-            self.find_nodes_default(op)            # not a Const index
-            return
-        arraynode = self.getnode(op.getarg(0))
-        if arraynode.escaped:
-            return     # nothing to be gained from tracking the item
-        index = indexbox.getint()
-        if arraynode.curitems is not None and index in arraynode.curitems:
-            itemnode = arraynode.curitems[index]
-        elif arraynode.origitems is not None and index in arraynode.origitems:
-            itemnode = arraynode.origitems[index]
-        elif arraynode.fromstart:
-            itemnode = InstanceNode(fromstart=True)
-            arraynode.add_escape_dependency(itemnode)
-            if arraynode.origitems is None:
-                arraynode.origitems = {}
-            arraynode.origitems[index] = itemnode
-        else:
-            return    # nothing to be gained from tracking the item
-        self.nodes[op.result] = itemnode
-
-    find_nodes_GETARRAYITEM_GC_PURE = find_nodes_GETARRAYITEM_GC
-
-    def find_nodes_JUMP(self, op):
-        # only set up the 'unique' field of the InstanceNodes;
-        # real handling comes later (build_result_specnodes() for loops).
-        for i in range(op.numargs()):
-            box = op.getarg(i)
-            self.getnode(box).set_unique_nodes()
-
-    def find_nodes_FINISH(self, op):
-        # only for bridges, and only for the ones that end in a 'return'
-        # or 'raise'; all other cases end with a JUMP.
-        for i in range(op.numargs()):
-            box = op.getarg(i)
-            self.getnode(box).unique = UNIQUE_NO
-
-find_nodes_ops = _findall(NodeFinder, 'find_nodes_')
-
-# ____________________________________________________________
-# Perfect specialization -- for loops only
-
-class PerfectSpecializationFinder(NodeFinder):
-    node_fromstart = InstanceNode(fromstart=True)
-
-    def find_nodes_loop(self, loop, build_specnodes=True):
-        self._loop = loop
-        self.setup_input_nodes(loop.inputargs)
-        self.find_nodes(loop.operations)
-        if build_specnodes:
-            self.build_result_specnodes(loop)
-
-    def show(self):
-        from pypy.jit.metainterp.viewnode import viewnodes, view
-        op = self._loop.operations[-1]
-        assert op.getopnum() == rop.JUMP
-        exitnodes = [self.getnode(arg) for arg in op.args]
-        viewnodes(self.inputnodes, exitnodes)
-        if hasattr(self._loop.token, "specnodes"):
-            view(*self._loop.token.specnodes)
-
-
-    def setup_input_nodes(self, inputargs):
-        inputnodes = []
-        for box in inputargs:
-            instnode = InstanceNode(fromstart=True)
-            inputnodes.append(instnode)
-            self.nodes[box] = instnode
-        self.inputnodes = inputnodes
-
-    def build_result_specnodes(self, loop):
-        # Build the list of specnodes based on the result
-        # computed by NodeFinder.find_nodes().
-        op = loop.operations[-1]
-        assert op.getopnum() == rop.JUMP
-        assert len(self.inputnodes) == op.numargs()
-        while True:
-            self.restart_needed = False
-            specnodes = []
-            for i in range(op.numargs()):
-                inputnode = self.inputnodes[i]
-                exitnode = self.getnode(op.getarg(i))
-                specnodes.append(self.intersect(inputnode, exitnode))
-            if not self.restart_needed:
-                break
-        loop.token.specnodes = specnodes
-
-    def intersect(self, inputnode, exitnode):
-        assert inputnode.fromstart
-        if inputnode.is_constant() and \
-           exitnode.is_constant():
-            if inputnode.knownvaluebox.same_constant(exitnode.knownvaluebox):
-                return ConstantSpecNode(inputnode.knownvaluebox)
-            else:
-                raise InvalidLoop
-        if inputnode.escaped:
-            return prebuiltNotSpecNode
-        unique = exitnode.unique
-        if unique == UNIQUE_NO:
-            if inputnode is not self.node_fromstart:
-                # Mark the input node as escaped, and schedule a complete
-                # restart of intersect().  This is needed because there is
-                # an order dependency: calling inputnode.mark_escaped()
-                # might set the field exitnode.unique to UNIQUE_NO in some
-                # other node.  If inputnode is node_fromstart, there is no
-                # problem (and it must not be mutated by mark_escaped() then).
-                inputnode.mark_escaped()
-                self.restart_needed = True
-            return prebuiltNotSpecNode
-        if unique == UNIQUE_INST:
-            return self.intersect_instance(inputnode, exitnode)
-        if unique == UNIQUE_ARRAY:
-            return self.intersect_array(inputnode, exitnode)
-        if unique == UNIQUE_STRUCT:
-            return self.intersect_struct(inputnode, exitnode)
-        assert 0, "unknown value for exitnode.unique: %d" % ord(unique)
-
-    def compute_common_fields(self, orig, d):
-        fields = []
-        if orig is not None:
-            if d is not None:
-                d = d.copy()
-            else:
-                d = {}
-            for ofs in orig:
-                d.setdefault(ofs, self.node_escaped)
-        if d is not None:
-            lst = d.keys()
-            # we always use the "standardized" order of fields
-            sort_descrs(lst)
-            for ofs in lst:
-                try:
-                    if orig is None:
-                        raise KeyError
-                    node = orig[ofs]
-                except KeyError:
-                    # field stored at exit, but not read at input.  Must
-                    # still be allocated, otherwise it will be incorrectly
-                    # uninitialized after a guard failure.
-                    node = self.node_fromstart
-                specnode = self.intersect(node, d[ofs])
-                fields.append((ofs, specnode))
-        return fields
-
-    def intersect_instance(self, inputnode, exitnode):
-        if (inputnode.knownclsbox is not None and
-            not inputnode.knownclsbox.same_constant(exitnode.knownclsbox)):
-            # unique match, but the class is known to be a mismatch
-            raise InvalidLoop
-        #
-        fields = self.compute_common_fields(inputnode.origfields,
-                                            exitnode.curfields)
-        return VirtualInstanceSpecNode(exitnode.knownclsbox, fields)
-
-    def intersect_array(self, inputnode, exitnode):
-        assert inputnode.arraydescr is None
-        #
-        items = []
-        for i in range(exitnode.arraysize):
-            if exitnode.curitems is None:
-                exitsubnode = self.node_escaped
-            else:
-                exitsubnode = exitnode.curitems.get(i, self.node_escaped)
-            if inputnode.origitems is None:
-                node = self.node_fromstart
-            else:
-                node = inputnode.origitems.get(i, self.node_fromstart)
-            specnode = self.intersect(node, exitsubnode)
-            items.append(specnode)
-        return VirtualArraySpecNode(exitnode.arraydescr, items)
-
-    def intersect_struct(self, inputnode, exitnode):
-        assert inputnode.structdescr is None
-        #
-        fields = self.compute_common_fields(inputnode.origfields,
-                                            exitnode.curfields)
-        return VirtualStructSpecNode(exitnode.structdescr, fields)
-
-# ____________________________________________________________
-# A subclass of NodeFinder for bridges only
-
-class __extend__(SpecNode):
-    def make_instance_node(self):
-        raise NotImplementedError
-    def matches_instance_node(self, exitnode):
-        raise NotImplementedError
-
-class __extend__(NotSpecNode):
-    def make_instance_node(self):
-        return NodeFinder.node_escaped
-    def matches_instance_node(self, exitnode):
-        return True
-
-class __extend__(ConstantSpecNode):
-    def make_instance_node(self):
-        raise AssertionError, "not implemented (but not used actually)"
-    def matches_instance_node(self, exitnode):
-        if exitnode.knownvaluebox is None:
-            return False
-        return self.constbox.same_constant(exitnode.knownvaluebox)
-
-class __extend__(VirtualInstanceSpecNode):
-    def make_instance_node(self):
-        instnode = InstanceNode()
-        instnode.knownclsbox = self.known_class
-        instnode.curfields = {}
-        for ofs, subspecnode in self.fields:
-            instnode.curfields[ofs] = subspecnode.make_instance_node()
-        return instnode
-
-    def matches_instance_node(self, exitnode):
-        if exitnode.unique == UNIQUE_NO:
-            return False
-        #
-        assert exitnode.unique == UNIQUE_INST
-        if not self.known_class.same_constant(exitnode.knownclsbox):
-            # unique match, but the class is known to be a mismatch
-            return False
-        #
-        return matches_fields(self.fields, exitnode.curfields)
-
-def matches_fields(fields, d):
-    seen = 0
-    for ofs, subspecnode in fields:
-        try:
-            if d is None:
-                raise KeyError
-            instnode = d[ofs]
-            seen += 1
-        except KeyError:
-            instnode = NodeFinder.node_escaped
-        if not subspecnode.matches_instance_node(instnode):
-            return False
-    if d is not None and len(d) > seen:
-        return False          # some key is in d but not in fields
-    return True
-
-class __extend__(VirtualArraySpecNode):
-    def make_instance_node(self):
-        raise AssertionError, "not implemented (but not used actually)"
-    def matches_instance_node(self, exitnode):
-        if exitnode.unique == UNIQUE_NO:
-            return False
-        #
-        assert exitnode.unique == UNIQUE_ARRAY
-        assert self.arraydescr == exitnode.arraydescr
-        if len(self.items) != exitnode.arraysize:
-            # the size is known to be a mismatch
-            return False
-        #
-        d = exitnode.curitems
-        for i in range(exitnode.arraysize):
-            try:
-                if d is None:
-                    raise KeyError
-                itemnode = d[i]
-            except KeyError:
-                itemnode = NodeFinder.node_escaped
-            subspecnode = self.items[i]
-            if not subspecnode.matches_instance_node(itemnode):
-                return False
-        return True
-
-class __extend__(VirtualStructSpecNode):
-    def make_instance_node(self):
-        raise AssertionError, "not implemented (but not used actually)"
-    def matches_instance_node(self, exitnode):
-        if exitnode.unique == UNIQUE_NO:
-            return False
-        #
-        assert exitnode.unique == UNIQUE_STRUCT
-        assert self.typedescr == exitnode.structdescr
-        #
-        return matches_fields(self.fields, exitnode.curfields)
-
-
-class BridgeSpecializationFinder(NodeFinder):
-
-    def find_nodes_bridge(self, bridge, specnodes=None):
-        if specnodes is not None:      # not used actually
-            self.setup_bridge_input_nodes(specnodes, bridge.inputargs)
-        self.find_nodes(bridge.operations)
-        self.jump_op = bridge.operations[-1]
-
-    def setup_bridge_input_nodes(self, specnodes, inputargs):
-        assert len(specnodes) == len(inputargs)
-        for i in range(len(inputargs)):
-            instnode = specnodes[i].make_instance_node()
-            box = inputargs[i]
-            self.nodes[box] = instnode
-
-    def bridge_matches(self, nextloop_specnodes):
-        jump_op = self.jump_op
-        assert jump_op.numargs() == len(nextloop_specnodes)
-        for i in range(len(nextloop_specnodes)):
-            exitnode = self.getnode(jump_op.getarg(i))
-            if not nextloop_specnodes[i].matches_instance_node(exitnode):
-                return False
-        return True


diff --git a/pypy/jit/metainterp/test/test_loop_spec.py b/pypy/jit/metainterp/test/test_loop_spec.py
deleted file mode 100644
--- a/pypy/jit/metainterp/test/test_loop_spec.py
+++ /dev/null
@@ -1,19 +0,0 @@
-import py
-from pypy.rlib.jit import OPTIMIZER_FULL
-from pypy.jit.metainterp.test import test_loop
-from pypy.jit.metainterp.test.test_basic import LLJitMixin, OOJitMixin
-
-class LoopSpecTest(test_loop.LoopTest):
-    optimizer = OPTIMIZER_FULL
-    automatic_promotion_result = {
-        'int_add' : 3, 'int_gt' : 1, 'guard_false' : 1, 'jump' : 1, 
-        'guard_value' : 1
-    }
-
-    # ====> test_loop.py
-
-class TestLLtype(LoopSpecTest, LLJitMixin):
-    pass
-
-class TestOOtype(LoopSpecTest, OOJitMixin):
-    pass

















diff --git a/pypy/jit/backend/x86/test/test_loop_spec.py b/pypy/jit/backend/x86/test/test_loop_spec.py
deleted file mode 100644
--- a/pypy/jit/backend/x86/test/test_loop_spec.py
+++ /dev/null
@@ -1,8 +0,0 @@
-import py
-from pypy.jit.backend.x86.test.test_basic import Jit386Mixin
-from pypy.jit.metainterp.test import test_loop_spec
-
-class TestLoopSpec(Jit386Mixin, test_loop_spec.LoopSpecTest):
-    # for the individual tests see
-    # ====> ../../../metainterp/test/test_loop.py
-    pass


diff --git a/pypy/jit/metainterp/optimize_nopspec.py b/pypy/jit/metainterp/optimize_nopspec.py
deleted file mode 100644
--- a/pypy/jit/metainterp/optimize_nopspec.py
+++ /dev/null
@@ -1,45 +0,0 @@
-
-from pypy.rlib.debug import debug_start, debug_stop
-from pypy.jit.metainterp.optimizeopt import optimize_loop_1, optimize_bridge_1
-from pypy.jit.metainterp.optimizefindnode import PerfectSpecializationFinder
-from pypy.jit.metainterp.optimizefindnode import BridgeSpecializationFinder
-
-def optimize_loop(metainterp_sd, old_loop_tokens, loop):
-    debug_start("jit-optimize")
-    try:
-        return _optimize_loop(metainterp_sd, old_loop_tokens, loop)
-    finally:
-        debug_stop("jit-optimize")
-
-def _optimize_loop(metainterp_sd, old_loop_tokens, loop):
-    cpu = metainterp_sd.cpu
-    metainterp_sd.logger_noopt.log_loop(loop.inputargs, loop.operations)
-    # XXX the following lines are probably still needed, to discard invalid
-    # loops. bit silly to run a full perfect specialization and throw the
-    # result away.
-    finder = PerfectSpecializationFinder(cpu)
-    finder.find_nodes_loop(loop, False)
-    if old_loop_tokens:
-        return old_loop_tokens[0]
-    optimize_loop_1(metainterp_sd, loop)
-    return None
-
-def optimize_bridge(metainterp_sd, old_loop_tokens, bridge):
-    debug_start("jit-optimize")
-    try:
-        return _optimize_bridge(metainterp_sd, old_loop_tokens, bridge)
-    finally:
-        debug_stop("jit-optimize")
-
-def _optimize_bridge(metainterp_sd, old_loop_tokens, bridge):
-    cpu = metainterp_sd.cpu    
-    metainterp_sd.logger_noopt.log_loop(bridge.inputargs, bridge.operations)
-    # XXX same comment as above applies
-    finder = BridgeSpecializationFinder(cpu)
-    finder.find_nodes_bridge(bridge)
-    if old_loop_tokens:
-        old_loop_token = old_loop_tokens[0]
-        bridge.operations[-1].setdescr(old_loop_token)   # patch jump target
-        optimize_bridge_1(metainterp_sd, bridge)
-        return old_loop_token
-    return None




diff --git a/pypy/module/array/benchmark/loop.py b/pypy/module/array/benchmark/loop.py
deleted file mode 100644
--- a/pypy/module/array/benchmark/loop.py
+++ /dev/null
@@ -1,7 +0,0 @@
-def h():
-    s=0
-    i=0
-    while i<100000:
-        s+=i
-        i+=1
-    return s

diff --git a/pypy/conftest.py b/pypy/conftest.py
--- a/pypy/conftest.py
+++ b/pypy/conftest.py
@@ -1,6 +1,7 @@
-import py, sys, os
+import py, sys, os, textwrap, types
 from pypy.interpreter.gateway import app2interp_temp
 from pypy.interpreter.error import OperationError
+from pypy.interpreter.function import Method
 from pypy.tool.pytest import appsupport
 from pypy.tool.option import make_config, make_objspace
 from pypy.config.config import ConflictConfigError
@@ -14,8 +15,8 @@
 rsyncdirs = ['.', '../lib-python', '../lib_pypy', '../demo']
 rsyncignore = ['_cache']
 
-# PyPy's command line extra options (these are added 
-# to py.test's standard options) 
+# PyPy's command line extra options (these are added
+# to py.test's standard options)
 #
 
 def _set_platform(opt, opt_str, value, parser):
@@ -54,8 +55,8 @@
 
 _SPACECACHE={}
 def gettestobjspace(name=None, **kwds):
-    """ helper for instantiating and caching space's for testing. 
-    """ 
+    """ helper for instantiating and caching space's for testing.
+    """
     try:
         config = make_config(option, objspace=name, **kwds)
     except ConflictConfigError, e:
@@ -202,30 +203,30 @@
     except AttributeError:
         pass
 
-# 
-# Interfacing/Integrating with py.test's collection process 
+#
+# Interfacing/Integrating with py.test's collection process
 #
 #
 
 def ensure_pytest_builtin_helpers(helpers='skip raises'.split()):
     """ hack (py.test.) raises and skip into builtins, needed
-        for applevel tests to run directly on cpython but 
+        for applevel tests to run directly on cpython but
         apparently earlier on "raises" was already added
-        to module's globals. 
-    """ 
+        to module's globals.
+    """
     import __builtin__
-    for helper in helpers: 
+    for helper in helpers:
         if not hasattr(__builtin__, helper):
             setattr(__builtin__, helper, getattr(py.test, helper))
 
 def pytest_pycollect_makemodule(path, parent):
     return PyPyModule(path, parent)
 
-class PyPyModule(py.test.collect.Module): 
-    """ we take care of collecting classes both at app level 
-        and at interp-level (because we need to stick a space 
-        at the class) ourselves. 
-    """    
+class PyPyModule(py.test.collect.Module):
+    """ we take care of collecting classes both at app level
+        and at interp-level (because we need to stick a space
+        at the class) ourselves.
+    """
     def __init__(self, *args, **kwargs):
         if hasattr(sys, 'pypy_objspaceclass'):
             option.conf_iocapture = "sys" # pypy cannot do FD-based
@@ -259,16 +260,16 @@
         #    return True
         return False
 
-    def setup(self): 
+    def setup(self):
         # stick py.test raise in module globals -- carefully
-        ensure_pytest_builtin_helpers() 
-        super(PyPyModule, self).setup() 
-        #    if hasattr(mod, 'objspacename'): 
+        ensure_pytest_builtin_helpers()
+        super(PyPyModule, self).setup()
+        #    if hasattr(mod, 'objspacename'):
         #        mod.space = getttestobjspace(mod.objspacename)
 
-    def makeitem(self, name, obj): 
-        if isclass(obj) and self.classnamefilter(name): 
-            if name.startswith('AppTest'): 
+    def makeitem(self, name, obj):
+        if isclass(obj) and self.classnamefilter(name):
+            if name.startswith('AppTest'):
                 return AppClassCollector(name, parent=self)
             elif name.startswith('ExpectTest'):
                 if option.rundirect:
@@ -281,18 +282,18 @@
             #    return AppExpectClassCollector(name, parent=self)
             else:
                 return IntClassCollector(name, parent=self)
-            
-        elif hasattr(obj, 'func_code') and self.funcnamefilter(name): 
-            if name.startswith('app_test_'): 
+
+        elif hasattr(obj, 'func_code') and self.funcnamefilter(name):
+            if name.startswith('app_test_'):
                 assert not obj.func_code.co_flags & 32, \
-                    "generator app level functions? you must be joking" 
-                return AppTestFunction(name, parent=self) 
-            elif obj.func_code.co_flags & 32: # generator function 
-                return self.Generator(name, parent=self) 
-            else: 
-                return IntTestFunction(name, parent=self) 
+                    "generator app level functions? you must be joking"
+                return AppTestFunction(name, parent=self)
+            elif obj.func_code.co_flags & 32: # generator function
+                return self.Generator(name, parent=self)
+            else:
+                return IntTestFunction(name, parent=self)
 
-def skip_on_missing_buildoption(**ropts): 
+def skip_on_missing_buildoption(**ropts):
     __tracebackhide__ = True
     import sys
     options = getattr(sys, 'pypy_translation_info', None)
@@ -300,12 +301,12 @@
         py.test.skip("not running on translated pypy "
                      "(btw, i would need options: %s)" %
                      (ropts,))
-    for opt in ropts: 
-        if not options.has_key(opt) or options[opt] != ropts[opt]: 
+    for opt in ropts:
+        if not options.has_key(opt) or options[opt] != ropts[opt]:
             break
     else:
         return
-    py.test.skip("need translated pypy with: %s, got %s" 
+    py.test.skip("need translated pypy with: %s, got %s"
                  %(ropts,options))
 
 def getwithoutbinding(x, name):
@@ -368,8 +369,8 @@
             tb = sys.exc_info()[2]
             if e.match(space, space.w_KeyboardInterrupt):
                 raise OpErrKeyboardInterrupt, OpErrKeyboardInterrupt(), tb
-            appexcinfo = appsupport.AppExceptionInfo(space, e) 
-            if appexcinfo.traceback: 
+            appexcinfo = appsupport.AppExceptionInfo(space, e)
+            if appexcinfo.traceback:
                 raise AppError, AppError(appexcinfo), tb
             raise
 
@@ -427,7 +428,7 @@
         target = self.obj
         if option.runappdirect:
             return target()
-        space = gettestobjspace() 
+        space = gettestobjspace()
         filename = self._getdynfilename(target)
         func = app2interp_temp(target, filename=filename)
         print "executing", func
@@ -437,47 +438,56 @@
         code = getattr(func, 'im_func', func).func_code
         return "[%s:%s]" % (code.co_filename, code.co_firstlineno)
 
-class AppTestMethod(AppTestFunction): 
-
-    def setup(self): 
-        super(AppTestMethod, self).setup() 
-        instance = self.parent.obj 
-        w_instance = self.parent.w_instance 
-        space = instance.space  
-        for name in dir(instance): 
-            if name.startswith('w_'): 
+class AppTestMethod(AppTestFunction):
+    def setup(self):
+        super(AppTestMethod, self).setup()
+        instance = self.parent.obj
+        w_instance = self.parent.w_instance
+        space = instance.space
+        for name in dir(instance):
+            if name.startswith('w_'):
                 if option.runappdirect:
                     # if the value is a function living on the class,
                     # don't turn it into a bound method here
                     obj = getwithoutbinding(instance, name)
                     setattr(instance, name[2:], obj)
                 else:
-                    space.setattr(w_instance, space.wrap(name[2:]), 
-                                  getattr(instance, name)) 
+                    obj = getattr(instance, name)
+                    if isinstance(obj, types.MethodType):
+                        source = py.std.inspect.getsource(obj).lstrip()
+                        w_func = space.appexec([], textwrap.dedent("""
+                        ():
+                            %s
+                            return %s
+                        """) % (source, name))
+                        w_obj = Method(space, w_func, w_instance, space.w_None)
+                    else:
+                        w_obj = obj
+                    space.setattr(w_instance, space.wrap(name[2:]), w_obj)
 
     def runtest_perform(self):
         target = self.obj
         if option.runappdirect:
             return target()
-        space = target.im_self.space 
+        space = target.im_self.space
         filename = self._getdynfilename(target)
-        func = app2interp_temp(target.im_func, filename=filename) 
-        w_instance = self.parent.w_instance 
-        self.execute_appex(space, func, space, w_instance) 
+        func = app2interp_temp(target.im_func, filename=filename)
+        w_instance = self.parent.w_instance
+        self.execute_appex(space, func, space, w_instance)
 
 class PyPyClassCollector(py.test.collect.Class):
     def setup(self):
-        cls = self.obj 
+        cls = self.obj
         if not hasattr(cls, 'spaceconfig'):
-            cls.space = LazyObjSpaceGetter() 
+            cls.space = LazyObjSpaceGetter()
         else:
             assert hasattr(cls, 'space') # set by pytest_runtest_setup
-        super(PyPyClassCollector, self).setup() 
+        super(PyPyClassCollector, self).setup()
 
 class IntInstanceCollector(py.test.collect.Instance):
-    Function = IntTestFunction 
-    
-class IntClassCollector(PyPyClassCollector): 
+    Function = IntTestFunction
+
+class IntClassCollector(PyPyClassCollector):
     Instance = IntInstanceCollector
 
     def _haskeyword(self, keyword):
@@ -487,21 +497,21 @@
     def _keywords(self):
         return super(IntClassCollector, self)._keywords() + ['interplevel']
 
-class AppClassInstance(py.test.collect.Instance): 
-    Function = AppTestMethod 
+class AppClassInstance(py.test.collect.Instance):
+    Function = AppTestMethod
 
-    def setup(self): 
-        super(AppClassInstance, self).setup()         
-        instance = self.obj 
-        space = instance.space 
-        w_class = self.parent.w_class 
+    def setup(self):
+        super(AppClassInstance, self).setup()
+        instance = self.obj
+        space = instance.space
+        w_class = self.parent.w_class
         if option.runappdirect:
             self.w_instance = instance
         else:
             self.w_instance = space.call_function(w_class)
 
-class AppClassCollector(PyPyClassCollector): 
-    Instance = AppClassInstance 
+class AppClassCollector(PyPyClassCollector):
+    Instance = AppClassInstance
 
     def _haskeyword(self, keyword):
         return keyword == 'applevel' or \
@@ -510,11 +520,11 @@
     def _keywords(self):
         return super(AppClassCollector, self)._keywords() + ['applevel']
 
-    def setup(self): 
-        super(AppClassCollector, self).setup()        
-        cls = self.obj 
-        space = cls.space 
-        clsname = cls.__name__ 
+    def setup(self):
+        super(AppClassCollector, self).setup()
+        cls = self.obj
+        space = cls.space
+        clsname = cls.__name__
         if option.runappdirect:
             w_class = cls
         else:
@@ -522,7 +532,7 @@
                                           space.wrap(clsname),
                                           space.newtuple([]),
                                           space.newdict())
-        self.w_class = w_class 
+        self.w_class = w_class
 
 class ExpectTestMethod(py.test.collect.Function):
     def safe_name(target):




More information about the Pypy-commit mailing list