[pypy-svn] r66307 - in pypy/branch/pyjitpl5-optimize4/pypy/jit/metainterp: . test
arigo at codespeak.net
arigo at codespeak.net
Fri Jul 17 16:46:33 CEST 2009
Author: arigo
Date: Fri Jul 17 16:46:32 2009
New Revision: 66307
Modified:
pypy/branch/pyjitpl5-optimize4/pypy/jit/metainterp/optimize.py
pypy/branch/pyjitpl5-optimize4/pypy/jit/metainterp/specnode.py
pypy/branch/pyjitpl5-optimize4/pypy/jit/metainterp/test/test_optimize.py
Log:
Start support for the next phase, namely intersect().
Support for tracking which boxes know their class.
Write more tests about that.
Modified: pypy/branch/pyjitpl5-optimize4/pypy/jit/metainterp/optimize.py
==============================================================================
--- pypy/branch/pyjitpl5-optimize4/pypy/jit/metainterp/optimize.py (original)
+++ pypy/branch/pyjitpl5-optimize4/pypy/jit/metainterp/optimize.py Fri Jul 17 16:46:32 2009
@@ -1,6 +1,6 @@
from pypy.rlib.objectmodel import r_dict
from pypy.rlib.unroll import unrolling_iterable
-from pypy.jit.metainterp import resoperation
+from pypy.jit.metainterp import resoperation, specnode
from pypy.jit.metainterp.history import AbstractValue
@@ -31,8 +31,7 @@
origfields = None # optimization; equivalent to an empty dict
curfields = None # optimization; equivalent to an empty dict
dependencies = None
- origclass = False
- curclass = None
+ knownclsbox = None
def __init__(self, escaped, fromstart=False):
self.escaped = escaped
@@ -62,21 +61,21 @@
class PerfectSpecializationFinder(object):
+ node_escaped = InstanceNode(escaped=True)
def __init__(self):
self.nodes = {} # Box -> InstanceNode
- self.node_escaped = InstanceNode(escaped=True)
-
- def clear(self):
- self.nodes.clear()
def getnode(self, box):
return self.nodes.get(box, self.node_escaped)
def find_nodes(self, loop):
- self.clear()
+ inputnodes = []
for box in loop.inputargs:
- self.nodes[box] = InstanceNode(escaped=False, fromstart=True)
+ instnode = InstanceNode(escaped=False, fromstart=True)
+ inputnodes.append(instnode)
+ self.nodes[box] = instnode
+ self.inputnodes = inputnodes
#
for op in loop.operations:
opnum = op.opnum
@@ -95,7 +94,7 @@
def find_nodes_NEW_WITH_VTABLE(self, op):
instnode = InstanceNode(escaped=False)
- instnode.curclass = op.args[0]
+ instnode.knownclsbox = op.args[0]
self.nodes[op.result] = instnode
def find_nodes_SETFIELD_GC(self, op):
@@ -134,22 +133,40 @@
def find_nodes_GUARD_CLASS(self, op):
instbox = op.args[0]
+ clsbox = op.args[1]
try:
instnode = self.nodes[instbox]
except KeyError:
instnode = self.nodes[instbox] = InstanceNode(escaped=True)
- else:
- if instnode.fromstart:
- instnode.origclass = True
- instnode.curclass = op.args[1]
+ assert instnode is not self.node_escaped
+ assert (instnode.knownclsbox is None or
+ instnode.knownclsbox.equals(clsbox))
+ instnode.knownclsbox = clsbox
def find_nodes_JUMP(self, op):
- pass # prevent the default handling
-
- def find_nodes_FAIL(self, op):
- pass # prevent the default handling
+ """Build the list of specnodes based on the result
+ computed by this PerfectSpecializationFinder.
+ """
+ specnodes = []
+ assert len(self.inputnodes) == len(op.args)
+ for i in range(len(op.args)):
+ inputnode = self.inputnodes[i]
+ specnodes.append(self.intersect(inputnode, op.args[i]))
+ self.specnodes = specnodes
+
+ def intersect(self, inputnode, exitbox):
+ assert inputnode.fromstart
+ exitnode = self.getnode(exitbox)
+ if inputnode.escaped or exitnode.escaped or exitnode.fromstart:
+ if (inputnode.knownclsbox is not None and
+ exitnode.knownclsbox is not None and
+ inputnode.knownclsbox.equals(exitnode.knownclsbox)):
+ return specnode.FixedClassSpecNode(inputnode.knownclsbox)
+ else:
+ return specnode.prebuiltNotSpecNode
+ else:
+ xxx #...
find_nodes_ops = _findall(PerfectSpecializationFinder, 'find_nodes_')
-perfect_specialization_finder = PerfectSpecializationFinder()
# ____________________________________________________________
Modified: pypy/branch/pyjitpl5-optimize4/pypy/jit/metainterp/specnode.py
==============================================================================
--- pypy/branch/pyjitpl5-optimize4/pypy/jit/metainterp/specnode.py (original)
+++ pypy/branch/pyjitpl5-optimize4/pypy/jit/metainterp/specnode.py Fri Jul 17 16:46:32 2009
@@ -1,369 +1,25 @@
-from pypy.jit.metainterp.resoperation import ResOperation, rop
-from pypy.jit.metainterp import executor
+
class SpecNode(object):
__slots__ = ()
- def expand_boxlist(self, instnode, newboxlist):
- newboxlist.append(instnode.source)
-
def extract_runtime_data(self, cpu, valuebox, resultlist):
resultlist.append(valuebox)
- def adapt_to(self, instnode, offsets):
- instnode.escaped = True
-
- def mutate_nodes(self, instnode):
- raise NotImplementedError
-
- def equals(self, other):
- raise NotImplementedError
-
- def matches(self, other):
- raise NotImplementedError
-
- def compute_number_of_nodes(self):
- raise NotImplementedError
class NotSpecNode(SpecNode):
__slots__ = ()
- def mutate_nodes(self, instnode):
- instnode.cursize = -1
- def equals(self, other):
- if type(other) is NotSpecNode:
- return True
- return False
-
- def matches(self, other):
- # NotSpecNode matches everything
- return True
-
- def compute_number_of_nodes(self):
- return 1
-
-class MatchEverythingSpecNode(SpecNode):
-
- def compute_number_of_nodes(self):
- return 0
-
-#class SpecNodeWithBox(NotSpecNode):
-# # XXX what is this class used for?
-# def __init__(self, box):
-# self.box = box
-
-# def equals(self, other):
-# if type(other) is SpecNodeWithBox:
-# return True
-# return False
+prebuiltNotSpecNode = NotSpecNode()
+
class FixedClassSpecNode(SpecNode):
def __init__(self, known_class):
self.known_class = known_class
- def mutate_nodes(self, instnode):
- from pypy.jit.metainterp.optimize import InstanceNode
-
- if instnode.cls is None:
- instnode.cls = InstanceNode(self.known_class, const=True)
- else:
- assert instnode.cls.source.equals(self.known_class)
-
- def equals(self, other):
- if type(other) is not FixedClassSpecNode:
- return False
- else:
- assert isinstance(other, FixedClassSpecNode) # make annotator happy
- return self.known_class.equals(other.known_class)
-
- def matches(self, instnode):
- if instnode.cls is None:
- return False
- return instnode.cls.source.equals(self.known_class)
-
- def compute_number_of_nodes(self):
- return 1
-
-##class FixedListSpecNode(FixedClassSpecNode):
-
-## def equals(self, other):
-## if type(other) is not FixedListSpecNode:
-## return False
-## else:
-## assert isinstance(other, FixedListSpecNode) # make annotator happy
-## return self.known_class.equals(other.known_class)
-class SpecNodeWithFields(FixedClassSpecNode):
+class VirtualInstanceSpecNode(FixedClassSpecNode):
def __init__(self, known_class, fields):
FixedClassSpecNode.__init__(self, known_class)
self.fields = fields
-
- def mutate_nodes(self, instnode):
- from pypy.jit.metainterp.optimize import av_eq, av_hash
- from pypy.rlib.objectmodel import r_dict
-
- FixedClassSpecNode.mutate_nodes(self, instnode)
- curfields = r_dict(av_eq, av_hash)
- for ofs, subspecnode in self.fields:
- if not isinstance(subspecnode, MatchEverythingSpecNode):
- subinstnode = instnode.origfields[ofs]
- # should really be there
- subspecnode.mutate_nodes(subinstnode)
- curfields[ofs] = subinstnode
- instnode.curfields = curfields
-
- def equals(self, other):
- if not isinstance(other, SpecNodeWithFields):
- return False
- if not self.known_class.equals(other.known_class):
- return False
- elif len(self.fields) != len(other.fields):
- return False
- else:
- for i in range(len(self.fields)):
- key, value = self.fields[i]
- otherkey, othervalue = other.fields[i]
- if key != otherkey:
- return False
- if not value.equals(othervalue):
- return False
- return True
-
- def matches(self, instnode):
- # XXX think about details of virtual vs virtualizable
- if not FixedClassSpecNode.matches(self, instnode):
- return False
- for key, value in self.fields:
- if key not in instnode.curfields:
- return False
- if value is not None and not value.matches(instnode.curfields[key]):
- return False
- return True
-
- def expand_boxlist(self, instnode, newboxlist):
- for ofs, subspecnode in self.fields:
- if not isinstance(subspecnode, MatchEverythingSpecNode):
- subinstnode = instnode.curfields[ofs] # should really be there
- subspecnode.expand_boxlist(subinstnode, newboxlist)
-
- def extract_runtime_data(self, cpu, valuebox, resultlist):
- for ofs, subspecnode in self.fields:
- from pypy.jit.metainterp.history import AbstractDescr
- assert isinstance(ofs, AbstractDescr)
- if not isinstance(subspecnode, MatchEverythingSpecNode):
- fieldbox = executor.execute(cpu, rop.GETFIELD_GC,
- [valuebox], ofs)
- subspecnode.extract_runtime_data(cpu, fieldbox, resultlist)
-
- def adapt_to(self, instnode, offsets):
- for ofs, subspecnode in self.fields:
- subspecnode.adapt_to(instnode.curfields[ofs], offsets)
-
- def compute_number_of_nodes(self):
- counter = 0
- for ofs, subspecnode in self.fields:
- counter += subspecnode.compute_number_of_nodes()
- return counter
-
-class VirtualizedSpecNode(SpecNodeWithFields):
-
- def equals(self, other):
- if not self.known_class.equals(other.known_class):
- return False
- assert len(self.fields) == len(other.fields)
- for i in range(len(self.fields)):
- if (isinstance(self.fields[i][1], MatchEverythingSpecNode) or
- isinstance(other.fields[i][1], MatchEverythingSpecNode)):
- continue
- assert self.fields[i][0].equals(other.fields[i][0])
- if not self.fields[i][1].equals(other.fields[i][1]):
- return False
- return True
-
- def matches(self, instnode):
- for key, value in self.fields:
- if not isinstance(value, MatchEverythingSpecNode):
- if key not in instnode.curfields:
- return False
- if value is not None and not value.matches(instnode.curfields[key]):
- return False
- return True
-
- def expand_boxlist(self, instnode, newboxlist):
- newboxlist.append(instnode.source)
- SpecNodeWithFields.expand_boxlist(self, instnode, newboxlist)
-
- def extract_runtime_data(self, cpu, valuebox, resultlist):
- resultlist.append(valuebox)
- SpecNodeWithFields.extract_runtime_data(self, cpu, valuebox, resultlist)
-
- def adapt_to(self, instnode, offsets_relative_to):
- instnode.escaped = True
- fields = []
- offsets_so_far = 0
- for ofs, subspecnode in self.fields:
- if isinstance(subspecnode, MatchEverythingSpecNode):
- node = None
- if ofs in instnode.curfields:
- node = instnode.curfields[ofs]
- orignode = instnode.origfields[ofs]
- subspecnode = orignode.intersect(node, {})
- elif ofs in instnode.origfields:
- node = instnode.origfields[ofs]
- subspecnode = node.intersect(node, {})
- orignode = node
- if node is not None:
- subspecnode.mutate_nodes(orignode)
- offsets_relative_to.append((subspecnode, ofs, instnode,
- offsets_so_far, orignode))
- else:
- subspecnode.adapt_to(instnode.curfields[ofs],
- offsets_relative_to)
- offsets_so_far += subspecnode.compute_number_of_nodes()
- fields.append((ofs, subspecnode))
-
- self.fields = fields
-
-# class DelayedSpecNode(VirtualizedSpecNode):
-
-# def expand_boxlist(self, instnode, newboxlist, oplist):
-# from pypy.jit.metainterp.history import AbstractDescr
-# newboxlist.append(instnode.source)
-# for ofs, subspecnode in self.fields:
-# assert isinstance(subspecnode, SpecNodeWithBox)
-# if oplist is None:
-# instnode.cleanfields[ofs] = instnode.origfields[ofs]
-# newboxlist.append(instnode.curfields[ofs].source)
-# else:
-# if ofs in instnode.cleanfields:
-# newboxlist.append(instnode.cleanfields[ofs].source)
-# else:
-# box = subspecnode.box.clonebox()
-# assert isinstance(ofs, AbstractDescr)
-# oplist.append(ResOperation(rop.GETFIELD_GC,
-# [instnode.source], box, ofs))
-# newboxlist.append(box)
-
-# class DelayedFixedListSpecNode(DelayedSpecNode):
-
-# def expand_boxlist(self, instnode, newboxlist, oplist):
-# from pypy.jit.metainterp.history import ResOperation
-# from pypy.jit.metainterp.resoperation import rop
-# from pypy.jit.metainterp.optimize import FixedList
-
-# newboxlist.append(instnode.source)
-# cls = self.known_class
-# assert isinstance(cls, FixedList)
-# arraydescr = cls.arraydescr
-# for ofs, subspecnode in self.fields:
-# assert isinstance(subspecnode, SpecNodeWithBox)
-# if oplist is None:
-# instnode.cleanfields[ofs] = instnode.origfields[ofs]
-# newboxlist.append(instnode.curfields[ofs].source)
-# else:
-# if ofs in instnode.cleanfields:
-# newboxlist.append(instnode.cleanfields[ofs].source)
-# else:
-# box = subspecnode.box.clonebox()
-# oplist.append(ResOperation(rop.GETARRAYITEM_GC,
-# [instnode.source, ofs], box, arraydescr))
-# newboxlist.append(box)
-
-# def extract_runtime_data(self, cpu, valuebox, resultlist):
-# from pypy.jit.metainterp.resoperation import rop
-# from pypy.jit.metainterp.optimize import FixedList
-# from pypy.jit.metainterp.history import check_descr
-
-# resultlist.append(valuebox)
-# cls = self.known_class
-# assert isinstance(cls, FixedList)
-# arraydescr = cls.arraydescr
-# check_descr(arraydescr)
-# for ofs, subspecnode in self.fields:
-# fieldbox = executor.execute(cpu, rop.GETARRAYITEM_GC,
-# [valuebox, ofs], arraydescr)
-# subspecnode.extract_runtime_data(cpu, fieldbox, resultlist)
-
-class VirtualizableSpecNode(VirtualizedSpecNode):
-
- def equals(self, other):
- if not isinstance(other, VirtualizableSpecNode):
- return False
- return VirtualizedSpecNode.equals(self, other)
-
- def adapt_to(self, instnode, offsets):
- instnode.virtualized = True
- VirtualizedSpecNode.adapt_to(self, instnode, offsets)
-
-class VirtualizableListSpecNode(VirtualizedSpecNode):
-
- def equals(self, other):
- if not isinstance(other, VirtualizableListSpecNode):
- return False
- return VirtualizedSpecNode.equals(self, other)
-
- def extract_runtime_data(self, cpu, valuebox, resultlist):
- from pypy.jit.metainterp.resoperation import rop
- from pypy.jit.metainterp.optimize import FixedList
- from pypy.jit.metainterp.history import check_descr
-
- resultlist.append(valuebox)
- cls = self.known_class
- assert isinstance(cls, FixedList)
- arraydescr = cls.arraydescr
- check_descr(arraydescr)
- for ofs, subspecnode in self.fields:
- if not isinstance(subspecnode, MatchEverythingSpecNode):
- fieldbox = executor.execute(cpu, rop.GETARRAYITEM_GC,
- [valuebox, ofs], arraydescr)
- subspecnode.extract_runtime_data(cpu, fieldbox, resultlist)
-
- def adapt_to(self, instnode, offsets):
- instnode.virtualized = True
- VirtualizedSpecNode.adapt_to(self, instnode, offsets)
-
-class VirtualSpecNode(SpecNodeWithFields):
-
- def adapt_to(self, instnode, offsets):
- instnode.virtual = True
- SpecNodeWithFields.adapt_to(self, instnode, offsets)
-
- def mutate_nodes(self, instnode):
- SpecNodeWithFields.mutate_nodes(self, instnode)
- instnode.virtual = True
-
-class VirtualInstanceSpecNode(VirtualSpecNode):
-
- def equals(self, other):
- if not isinstance(other, VirtualInstanceSpecNode):
- return False
- return SpecNodeWithFields.equals(self, other)
-
-class VirtualFixedListSpecNode(VirtualSpecNode):
-
- def __init__(self, known_class, fields, known_length):
- VirtualSpecNode.__init__(self, known_class, fields)
- self.known_length = known_length
-
- def mutate_nodes(self, instnode):
- VirtualSpecNode.mutate_nodes(self, instnode)
- instnode.cursize = self.known_length
-
- def equals(self, other):
- if not isinstance(other, VirtualFixedListSpecNode):
- return False
- return SpecNodeWithFields.equals(self, other)
-
- def extract_runtime_data(self, cpu, valuebox, resultlist):
- from pypy.jit.metainterp.resoperation import rop
- from pypy.jit.metainterp.optimize import FixedList
- from pypy.jit.metainterp.history import check_descr
- cls = self.known_class
- assert isinstance(cls, FixedList)
- arraydescr = cls.arraydescr
- check_descr(arraydescr)
- for ofs, subspecnode in self.fields:
- fieldbox = executor.execute(cpu, rop.GETARRAYITEM_GC,
- [valuebox, ofs], arraydescr)
- subspecnode.extract_runtime_data(cpu, fieldbox, resultlist)
Modified: pypy/branch/pyjitpl5-optimize4/pypy/jit/metainterp/test/test_optimize.py
==============================================================================
--- pypy/branch/pyjitpl5-optimize4/pypy/jit/metainterp/test/test_optimize.py (original)
+++ pypy/branch/pyjitpl5-optimize4/pypy/jit/metainterp/test/test_optimize.py Fri Jul 17 16:46:32 2009
@@ -7,7 +7,9 @@
from pypy.jit.backend.llgraph import runner
from pypy.jit.metainterp.history import (BoxInt, BoxPtr, ConstInt, ConstPtr,
Const, ConstAddr, TreeLoop, BoxObj)
-from pypy.jit.metainterp.optimize import perfect_specialization_finder
+from pypy.jit.metainterp.optimize import PerfectSpecializationFinder
+from pypy.jit.metainterp.specnode import NotSpecNode, FixedClassSpecNode
+from pypy.jit.metainterp.specnode import VirtualInstanceSpecNode
from pypy.jit.metainterp.test.oparser import parse
# ____________________________________________________________
@@ -56,12 +58,16 @@
node_vtable = lltype.malloc(OBJECT_VTABLE, immortal=True)
node_vtable_adr = llmemory.cast_ptr_to_adr(node_vtable)
+ node_vtable2 = lltype.malloc(OBJECT_VTABLE, immortal=True)
+ 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),
('next', lltype.Ptr(NODE))))
+ NODE2 = lltype.GcStruct('NODE2', ('parent', NODE),
+ ('other', lltype.Ptr(NODE)))
node = lltype.malloc(NODE)
nodebox = BoxPtr(lltype.cast_opaque_ptr(llmemory.GCREF, node))
nodebox2 = BoxPtr(lltype.cast_opaque_ptr(llmemory.GCREF, node))
@@ -69,7 +75,8 @@
valuedescr = cpu.fielddescrof(NODE, 'value')
nextdescr = cpu.fielddescrof(NODE, 'next')
- cpu.class_sizes = {cpu.cast_adr_to_int(node_vtable_adr): cpu.sizeof(NODE)}
+ cpu.class_sizes = {cpu.cast_adr_to_int(node_vtable_adr): cpu.sizeof(NODE),
+ cpu.cast_adr_to_int(node_vtable_adr2): cpu.sizeof(NODE2)}
namespace = locals()
class OOtypeMixin(object):
@@ -80,9 +87,12 @@
NODE = ootype.Instance('NODE', ootype.ROOT, {})
NODE._add_fields({'value': ootype.Signed,
'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))
@@ -91,7 +101,8 @@
nextdescr = cpu.fielddescrof(NODE, 'next')
nodesize = cpu.typedescrof(NODE)
- cpu.class_sizes = {node_vtable_adr: cpu.typedescrof(NODE)}
+ cpu.class_sizes = {node_vtable_adr: cpu.typedescrof(NODE),
+ node_vtable_adr2: cpu.typedescrof(NODE2)}
namespace = locals()
# ____________________________________________________________
@@ -109,8 +120,11 @@
def find_nodes(self, ops, boxkinds=None):
loop = self.parse(ops, boxkinds=boxkinds)
+ perfect_specialization_finder = PerfectSpecializationFinder()
perfect_specialization_finder.find_nodes(loop)
- return loop.getboxes(), perfect_specialization_finder.getnode
+ return (loop.getboxes(),
+ perfect_specialization_finder.getnode,
+ perfect_specialization_finder.specnodes)
def test_find_nodes_simple(self):
ops = """
@@ -120,9 +134,10 @@
fail(i0)
jump(i0)
"""
- boxes, getnode = self.find_nodes(ops)
+ boxes, getnode, specnodes = self.find_nodes(ops)
assert getnode(boxes.i).fromstart
assert not getnode(boxes.i0).fromstart
+ assert [sn.__class__ for sn in specnodes] == [NotSpecNode]
def test_find_nodes_non_escape(self):
ops = """
@@ -134,13 +149,14 @@
setfield_gc(p2, i1, descr=valuedescr)
jump(p0)
"""
- boxes, getnode = self.find_nodes(ops)
+ boxes, getnode, specnodes = self.find_nodes(ops)
assert not getnode(boxes.p0).escaped
assert not getnode(boxes.p1).escaped
assert not getnode(boxes.p2).escaped
assert getnode(boxes.p0).fromstart
assert getnode(boxes.p1).fromstart
assert getnode(boxes.p2).fromstart
+ assert [sn.__class__ for sn in specnodes] == [NotSpecNode]
def test_find_nodes_escape(self):
ops = """
@@ -156,7 +172,7 @@
setfield_gc(p4, i1, descr=valuedescr)
jump(p0)
"""
- boxes, getnode = self.find_nodes(ops)
+ boxes, getnode, specnodes = self.find_nodes(ops)
assert not getnode(boxes.p0).escaped
assert getnode(boxes.p1).escaped
assert getnode(boxes.p2).escaped # forced by p1
@@ -167,8 +183,21 @@
assert getnode(boxes.p2).fromstart
assert getnode(boxes.p3).fromstart
assert not getnode(boxes.p4).fromstart
+ assert [sn.__class__ for sn in specnodes] == [NotSpecNode]
- def test_find_nodes_guard_class(self):
+ def test_find_nodes_guard_class_1(self):
+ ops = """
+ [p1]
+ guard_class(p1, ConstClass(node_vtable))
+ fail()
+ jump(p1)
+ """
+ boxes, getnode, specnodes = self.find_nodes(ops)
+ boxp1 = getnode(boxes.p1)
+ assert boxp1.knownclsbox.value == self.node_vtable_adr
+ assert [sn.__class__ for sn in specnodes] == [FixedClassSpecNode]
+
+ def test_find_nodes_guard_class_2(self):
ops = """
[p1]
p2 = getfield_gc(p1, descr=nextdescr)
@@ -176,15 +205,79 @@
fail()
jump(p1)
"""
- boxes, getnode = self.find_nodes(ops)
+ boxes, getnode, specnodes = self.find_nodes(ops)
+ boxp1 = getnode(boxes.p1)
+ boxp2 = getnode(boxes.p2)
+ assert boxp1.knownclsbox is None
+ assert boxp2.knownclsbox.value == self.node_vtable_adr
+ assert [sn.__class__ for sn in specnodes] == [NotSpecNode]
+
+ def test_find_nodes_guard_class_outonly(self):
+ ops = """
+ [p1]
+ p2 = escape()
+ guard_class(p2, ConstClass(node_vtable))
+ fail()
+ jump(p2)
+ """
+ boxes, getnode, specnodes = self.find_nodes(ops)
+ boxp1 = getnode(boxes.p1)
+ boxp2 = getnode(boxes.p2)
+ assert boxp1.knownclsbox is None
+ assert boxp2.knownclsbox.value == self.node_vtable_adr
+ assert [sn.__class__ for sn in specnodes] == [NotSpecNode]
+
+ def test_find_nodes_guard_class_inonly(self):
+ ops = """
+ [p1]
+ guard_class(p1, ConstClass(node_vtable))
+ fail()
+ p2 = escape()
+ jump(p2)
+ """
+ boxes, getnode, specnodes = self.find_nodes(ops)
+ boxp1 = getnode(boxes.p1)
+ boxp2 = getnode(boxes.p2)
+ assert boxp1.knownclsbox.value == self.node_vtable_adr
+ assert boxp2.knownclsbox is None
+ assert [sn.__class__ for sn in specnodes] == [NotSpecNode]
+
+ def test_find_nodes_guard_class_inout(self):
+ ops = """
+ [p1]
+ guard_class(p1, ConstClass(node_vtable))
+ fail()
+ p2 = escape()
+ guard_class(p2, ConstClass(node_vtable))
+ fail()
+ jump(p2)
+ """
+ boxes, getnode, specnodes = self.find_nodes(ops)
boxp1 = getnode(boxes.p1)
boxp2 = getnode(boxes.p2)
- assert not boxp1.origclass
- assert boxp1.curclass is None
- assert boxp2.origclass
- assert boxp2.curclass.value == self.node_vtable_adr
+ assert boxp1.knownclsbox.value == self.node_vtable_adr
+ assert boxp2.knownclsbox.value == self.node_vtable_adr
+ assert [sn.__class__ for sn in specnodes] == [FixedClassSpecNode]
+
+ def test_find_nodes_guard_class_mismatch(self):
+ ops = """
+ [p1]
+ guard_class(p1, ConstClass(node_vtable))
+ fail()
+ p2 = escape()
+ guard_class(p2, ConstClass(node_vtable2))
+ fail()
+ jump(p2)
+ """
+ boxes, getnode, specnodes = self.find_nodes(ops)
+ boxp1 = getnode(boxes.p1)
+ boxp2 = getnode(boxes.p2)
+ assert boxp1.knownclsbox.value == self.node_vtable_adr
+ assert boxp2.knownclsbox.value == self.node_vtable_adr2
+ assert [sn.__class__ for sn in specnodes] == [NotSpecNode]
def test_find_nodes_new(self):
+ py.test.skip("VirtualInstanceSpecNode in-progress")
ops = """
[sum, p1]
guard_class(p1, ConstClass(node_vtable))
@@ -197,8 +290,8 @@
setfield_gc(p2, p2, descr=nextdescr)
jump(sum2, p2)
"""
- boxes, getnode = self.find_nodes(ops, boxkinds={'sum': BoxInt,
- 'sum2': BoxInt})
+ boxes, getnode, specnodes = self.find_nodes(
+ ops, boxkinds={'sum': BoxInt, 'sum2': BoxInt})
assert getnode(boxes.sum) is not getnode(boxes.sum2)
assert getnode(boxes.p1) is not getnode(boxes.p2)
@@ -215,10 +308,11 @@
assert boxp1.fromstart
assert not boxp2.fromstart
- assert boxp1.origclass
- assert boxp1.curclass.value == self.node_vtable_adr
- assert not boxp2.origclass
- assert boxp2.curclass.value == self.node_vtable_adr
+ assert boxp1.knownclsbox.value == self.node_vtable_adr
+ assert boxp2.knownclsbox.value == self.node_vtable_adr
+
+ assert [sn.__class__ for sn in specnodes] == [NotSpecNode,
+ VirtualInstanceSpecNode]
class TestLLtype(BaseTestOptimize, LLtypeMixin):
More information about the Pypy-commit
mailing list