[pypy-svn] r63032 - in pypy/branch/virtualizable-specnodes/pypy/jit: backend/llgraph metainterp metainterp/test
fijal at codespeak.net
fijal at codespeak.net
Wed Mar 18 14:16:21 CET 2009
Author: fijal
Date: Wed Mar 18 14:16:20 2009
New Revision: 63032
Modified:
pypy/branch/virtualizable-specnodes/pypy/jit/backend/llgraph/runner.py
pypy/branch/virtualizable-specnodes/pypy/jit/metainterp/compile.py
pypy/branch/virtualizable-specnodes/pypy/jit/metainterp/optimize.py
pypy/branch/virtualizable-specnodes/pypy/jit/metainterp/pyjitpl.py
pypy/branch/virtualizable-specnodes/pypy/jit/metainterp/specnode.py
pypy/branch/virtualizable-specnodes/pypy/jit/metainterp/test/test_virtualizable.py
pypy/branch/virtualizable-specnodes/pypy/jit/metainterp/virtualizable.py
Log:
in-progress checkin of dealing with virtualizable specnodes in a correct way
Modified: pypy/branch/virtualizable-specnodes/pypy/jit/backend/llgraph/runner.py
==============================================================================
--- pypy/branch/virtualizable-specnodes/pypy/jit/backend/llgraph/runner.py (original)
+++ pypy/branch/virtualizable-specnodes/pypy/jit/backend/llgraph/runner.py Wed Mar 18 14:16:20 2009
@@ -37,6 +37,11 @@
def sort_key(self):
return self.ofs
+ def equals(self, other):
+ if not isinstance(other, Descr):
+ return False
+ return self.sort_key() == other.sort_key()
+
def __lt__(self, other):
raise TypeError("cannot use comparison on Descrs")
def __le__(self, other):
@@ -74,6 +79,19 @@
def set_meta_interp(self, metainterp):
self.metainterp = metainterp # to handle guard failures
+ def compile_arg(self, x, c, op, var2index):
+ if isinstance(x, history.Box):
+ llimpl.compile_add_var(c, var2index[x])
+ elif isinstance(x, history.ConstInt):
+ llimpl.compile_add_int_const(c, x.value)
+ elif isinstance(x, history.ConstPtr):
+ llimpl.compile_add_ptr_const(c, x.value)
+ elif isinstance(x, history.ConstAddr):
+ llimpl.compile_add_int_const(c, x.getint())
+ else:
+ raise Exception("%s args contain: %r" % (op.getopname(),
+ x))
+
def compile_operations(self, operations, from_guard=None):
"""In a real assembler backend, this should assemble the given
list of operations. Here we just generate a similar LoopOrBridge
@@ -105,17 +123,7 @@
if op.descr is not None:
llimpl.compile_add_descr(c, op.descr.ofs, op.descr.type)
for x in op.args:
- if isinstance(x, history.Box):
- llimpl.compile_add_var(c, var2index[x])
- elif isinstance(x, history.ConstInt):
- llimpl.compile_add_int_const(c, x.value)
- elif isinstance(x, history.ConstPtr):
- llimpl.compile_add_ptr_const(c, x.value)
- elif isinstance(x, history.ConstAddr):
- llimpl.compile_add_int_const(c, x.getint())
- else:
- raise Exception("%s args contain: %r" % (op.getopname(),
- x))
+ self.compile_arg(x, c, op, var2index)
x = op.result
if x is not None:
if isinstance(x, history.BoxInt):
@@ -142,6 +150,9 @@
llimpl.compile_from_guard(c, from_guard._compiled,
from_guard._opindex)
+ def update_loop(self, loop, mp, guard_op, newboxlist):
+ self.compile_operations(loop.operations)
+
def execute_operations_in_new_frame(self, name, operations, valueboxes):
"""Perform a 'call' to the given merge point, i.e. create
a new CPU frame and use it to execute the operations that
Modified: pypy/branch/virtualizable-specnodes/pypy/jit/metainterp/compile.py
==============================================================================
--- pypy/branch/virtualizable-specnodes/pypy/jit/metainterp/compile.py (original)
+++ pypy/branch/virtualizable-specnodes/pypy/jit/metainterp/compile.py Wed Mar 18 14:16:20 2009
@@ -112,6 +112,7 @@
else:
name = 'Loop #%d' % len(metainterp.stats.loops)
graph = Graph(name, '#f084c2')
+ graph.extensions = [None]
return graph
def create_empty_bridge(metainterp):
@@ -120,6 +121,7 @@
else:
name = 'Bridge #%d' % len(metainterp.stats.loops)
graph = Graph(name, '#84f0c2')
+ graph.extensions = [None]
return graph
# ____________________________________________________________
@@ -149,6 +151,15 @@
metainterp.cpu.compile_operations(loop.operations, guard_op)
metainterp.stats.loops.append(loop)
+def update_loop(metainterp, loop, guard_op, newboxlist):
+ mp = loop.operations[0]
+ mp.args += newboxlist
+ jump = loop.operations[-1]
+ jump.args += newboxlist
+ guard_op.liveboxes += newboxlist
+ guard_op.storage = None
+ metainterp.cpu.update_loop(loop, mp, guard_op, newboxlist)
+
# ____________________________________________________________
def matching_merge_point(metainterp, targetmp, endliveboxes):
@@ -165,10 +176,14 @@
op = ResOperation(rop.JUMP, endliveboxes, None)
operations.append(op)
#
- old_loop = optimize.optimize_bridge(metainterp.options, old_loops, bridge,
- metainterp.cpu)
+ old_loop, newboxlist = optimize.optimize_bridge(metainterp.options,
+ old_loops, bridge,
+ metainterp.cpu)
if old_loop is None:
return None
bridge.jump_to = old_loop
+ if newboxlist:
+ # recompile loop
+ update_loop(metainterp, old_loop, guard_op, newboxlist)
finish_loop_or_bridge(metainterp, bridge, old_loop.operations[0], guard_op)
return bridge
Modified: pypy/branch/virtualizable-specnodes/pypy/jit/metainterp/optimize.py
==============================================================================
--- pypy/branch/virtualizable-specnodes/pypy/jit/metainterp/optimize.py (original)
+++ pypy/branch/virtualizable-specnodes/pypy/jit/metainterp/optimize.py Wed Mar 18 14:16:20 2009
@@ -3,15 +3,10 @@
ResOperation, AbstractDescr,
Options, AbstractValue, ConstPtr)
from pypy.jit.metainterp.specnode import (FixedClassSpecNode,
- VirtualInstanceSpecNode,
- VirtualizableSpecNode,
- NotSpecNode,
- DelayedSpecNode,
- SpecNodeWithBox,
- DelayedFixedListSpecNode,
- VirtualFixedListSpecNode,
- VirtualizableListSpecNode,
- )
+ VirtualInstanceSpecNode, VirtualizableSpecNode, NotSpecNode,
+ DelayedSpecNode, SpecNodeWithBox, DelayedFixedListSpecNode,
+ VirtualFixedListSpecNode, MatchEverythingSpecNode,
+ VirtualizableListSpecNode, av_eq, av_hash)
from pypy.jit.metainterp import executor
from pypy.rlib.objectmodel import we_are_translated
from pypy.rpython.lltypesystem import lltype, llmemory
@@ -106,12 +101,6 @@
liveboxes.append(box)
return res
-def av_eq(self, other):
- return self.sort_key() == other.sort_key()
-
-def av_hash(self):
- return self.sort_key()
-
def av_list_in(lst, key):
# lst is a list of about 2 elements in the typical case, so no
# point in making a dict lookup
@@ -139,6 +128,7 @@
self.expanded_fields = r_dict(av_eq, av_hash)
self.cursize = -1
self.vdesc = None # for virtualizables
+ self.allfields = None
def is_nonzero(self):
return self.cls is not None or self.nonzero
@@ -146,7 +136,7 @@
def is_zero(self):
return self.const and not self.source.getptr_base()
- def escape_if_startbox(self, memo):
+ def escape_if_startbox(self, memo, cpu):
if self in memo:
return
memo[self] = None
@@ -154,23 +144,29 @@
self.escaped = True
if not self.virtualized:
for node in self.curfields.values():
- node.escape_if_startbox(memo)
+ node.escape_if_startbox(memo, cpu)
else:
for key, node in self.curfields.items():
if self.vdesc is not None and av_list_in(self.vdesc, key):
- node.virtualized = True
- if node.cls is None:
- node.cls = InstanceNode(FixedClass(), const=True)
- node.escape_if_startbox(memo)
+ node.initialize_virtualizable(cpu)
+ node.escape_if_startbox(memo, cpu)
# we also need to escape fields that are only read, never written,
# if they're not marked specifically as ones that does not escape
for key, node in self.origfields.items():
if key not in self.curfields:
if self.vdesc is not None and av_list_in(self.vdesc, key):
- node.virtualized = True
- if node.cls is None:
- node.cls = InstanceNode(FixedClass(), const=True)
- node.escape_if_startbox(memo)
+ node.initialize_virtualizable(cpu)
+ node.escape_if_startbox(memo, cpu)
+
+ def initialize_virtualizable(self, cpu):
+ self.virtualized = True
+ if self.cls is None:
+ self.cls = InstanceNode(FixedClass(), const=True)
+ self.allfields = xxx
+ else:
+ ad = self.cls.source.arraydescr
+ lgtbox = cpu.do_arraylen_gc([self.source], ad)
+ self.allfields = [ConstInt(i) for i in range(lgtbox.getint())]
def add_to_dependency_graph(self, other, dep_graph):
dep_graph.append((self, other))
@@ -228,9 +224,7 @@
return DelayedSpecNode(known_class, fields)
else:
assert self is other
- d = self.origfields.copy()
- d.update(other.curfields)
- offsets = d.keys()
+ offsets = self.allfields
sort_descrs(offsets)
fields = []
for ofs in offsets:
@@ -242,10 +236,11 @@
self.origfields[ofs].cls = node.cls
nodes[box] = self.origfields[ofs]
specnode = self.origfields[ofs].intersect(node, nodes)
- else:
- # ofs in self.origfields:
+ elif ofs in self.origfields:
node = self.origfields[ofs]
specnode = node.intersect(node, nodes)
+ else:
+ specnode = MatchEverythingSpecNode()
fields.append((ofs, specnode))
if isinstance(known_class, FixedList):
return VirtualizableListSpecNode(known_class, fields)
@@ -285,9 +280,14 @@
perfect_specializer.find_nodes()
for old_loop in old_loops:
if perfect_specializer.match(old_loop.operations):
- perfect_specializer.adapt_for_match(old_loop.operations)
+ num = len(old_loop.extensions)
+ newlist, newspecnodes = perfect_specializer.adapt_for_match(
+ old_loop.operations, num)
+ if newlist:
+ old_loop.extensions.append(newspecnodes)
+ perfect_specializer.loop.operations[0].args.extend(newlist)
perfect_specializer.optimize_loop()
- return old_loop
+ return old_loop, newlist
return None # no loop matches
class PerfectSpecializer(object):
@@ -439,7 +439,8 @@
if instnode.cls is None:
instnode.cls = InstanceNode(op.args[1], const=True)
if op.vdesc:
- instnode.vdesc = op.vdesc.virtuals
+ instnode.vdesc = op.vdesc.virtuals
+ instnode.allfields = op.vdesc.fields
continue
elif op.is_always_pure():
for arg in op.args:
@@ -469,7 +470,7 @@
for i in range(len(end_args)):
end_box = end_args[i]
if isinstance(end_box, Box):
- self.nodes[end_box].escape_if_startbox(memo)
+ self.nodes[end_box].escape_if_startbox(memo, self.cpu)
for i in range(len(end_args)):
box = self.loop.operations[0].args[i]
other_box = end_args[i]
@@ -508,18 +509,28 @@
box = boxlist[i]
specnode = self.specnodes[i]
specnode.expand_boxlist(self.nodes[box], newboxlist, oplist)
+ l = []
+ for i, (group, arg) in enumerate(newboxlist):
+ l.append((group, i, arg))
+ l.sort()
+ return [e[2] for e in l]
+
return newboxlist
- def optimize_guard(self, op):
- liveboxes = []
+ def deal_with_boxes(self, boxes):
storage = AllocationStorage()
- memo = {}
+ newboxes = []
indices = []
+ memo = {}
+ for box in boxes:
+ indices.append(storage.deal_with_box(box, self.nodes, newboxes,
+ memo))
+ return storage, newboxes, indices
+
+ def optimize_guard(self, op):
old_boxes = op.liveboxes
op = op.clone()
- for box in old_boxes:
- indices.append(storage.deal_with_box(box, self.nodes,
- liveboxes, memo))
+ storage, liveboxes, indices = self.deal_with_boxes(old_boxes)
rev_boxes = {}
for i in range(len(liveboxes)):
box = liveboxes[i]
@@ -821,14 +832,18 @@
return False
return True
- def adapt_for_match(self, old_operations):
+ def adapt_for_match(self, old_operations, num):
old_mp = old_operations[0]
jump_op = self.loop.operations[-1]
self.specnodes = old_mp.specnodes
+ newboxlist = []
+ extensions = []
for i in range(len(old_mp.specnodes)):
old_specnode = old_mp.specnodes[i]
new_instnode = self.nodes[jump_op.args[i]]
- old_specnode.adapt_to(new_instnode)
+ old_specnode.adapt_to(new_instnode, newboxlist, extensions, num)
+ newboxlist = [i for _, i in newboxlist]
+ return newboxlist, extensions
class Chooser(object):
def __init__(self, boxes_from_frame, allocated_boxes, allocated_lists):
Modified: pypy/branch/virtualizable-specnodes/pypy/jit/metainterp/pyjitpl.py
==============================================================================
--- pypy/branch/virtualizable-specnodes/pypy/jit/metainterp/pyjitpl.py (original)
+++ pypy/branch/virtualizable-specnodes/pypy/jit/metainterp/pyjitpl.py Wed Mar 18 14:16:20 2009
@@ -898,7 +898,11 @@
for i in range(len(mp.specnodes)):
specnode = mp.specnodes[i]
specnode.extract_runtime_data(self.cpu, args[i], expanded_args)
- return expanded_args
+ l = []
+ for i, (group, arg) in enumerate(expanded_args):
+ l.append((group, i, arg))
+ l.sort()
+ return [e[2] for e in l]
def _initialize_from_start(self, original_boxes, num_green_args, *args):
if args:
Modified: pypy/branch/virtualizable-specnodes/pypy/jit/metainterp/specnode.py
==============================================================================
--- pypy/branch/virtualizable-specnodes/pypy/jit/metainterp/specnode.py (original)
+++ pypy/branch/virtualizable-specnodes/pypy/jit/metainterp/specnode.py Wed Mar 18 14:16:20 2009
@@ -1,15 +1,22 @@
from pypy.jit.metainterp.resoperation import ResOperation, rop
from pypy.jit.metainterp import executor
+from pypy.rlib.objectmodel import r_dict
+
+def av_eq(self, other):
+ return self.sort_key() == other.sort_key()
+
+def av_hash(self):
+ return self.sort_key()
class SpecNode(object):
def expand_boxlist(self, instnode, newboxlist, start):
- newboxlist.append(instnode.source)
+ newboxlist.append((0, instnode.source))
def extract_runtime_data(self, cpu, valuebox, resultlist):
- resultlist.append(valuebox)
+ resultlist.append((0, valuebox))
- def adapt_to(self, instnode):
+ def adapt_to(self, instnode, newboxlist, newspecnodes, num):
instnode.escaped = True
def mutate_nodes(self, instnode):
@@ -21,6 +28,33 @@
def matches(self, other):
raise NotImplementedError
+class RedirectingSpecNode(SpecNode):
+ def __init__(self, specnode, group):
+ self.redirect_to = specnode
+ self.group = group
+
+ def expand_boxlist(self, instnode, newboxlist, start):
+ l = []
+ self.redirect_to.expand_boxlist(instnode, l, start)
+ newboxlist.extend([(self.group, e) for _, e in l])
+
+ def extract_runtime_data(self, cpu, valuebox, resultlist):
+ l = []
+ self.redirect_to.extract_runtime_data(cpu, valuebox, l)
+ resultlist.extend([(self.group, e) for _, e in l])
+
+ def adapt_to(self, *args):
+ self.redirect_to.adapt_to(*args)
+
+ def equals(self, other):
+ return self.redirect_to.equals(other)
+
+ def matches(self, other):
+ return self.redirect_to.matches(other)
+
+class MatchEverythingSpecNode(SpecNode):
+ pass
+
class NotSpecNode(SpecNode):
def mutate_nodes(self, instnode):
instnode.cursize = -1
@@ -68,31 +102,20 @@
return False
return instnode.cls.source.equals(self.known_class)
-##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):
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:
- subinstnode = instnode.origfields[ofs]
- # should really be there
- subspecnode.mutate_nodes(subinstnode)
- curfields[ofs] = subinstnode
+ 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):
@@ -111,66 +134,70 @@
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
+ 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, start):
for ofs, subspecnode in self.fields:
- subinstnode = instnode.curfields[ofs] # should really be there
- subspecnode.expand_boxlist(subinstnode, newboxlist, start)
+ if not isinstance(subspecnode, MatchEverythingSpecNode):
+ subinstnode = instnode.curfields[ofs] # should really be there
+ subspecnode.expand_boxlist(subinstnode, newboxlist, start)
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)
- fieldbox = executor.execute(cpu, rop.GETFIELD_GC,
- [valuebox], ofs)
- subspecnode.extract_runtime_data(cpu, fieldbox, resultlist)
+ 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):
+ def adapt_to(self, instnode, newboxlist, newspecnodes, num):
for ofs, subspecnode in self.fields:
- subspecnode.adapt_to(instnode.curfields[ofs])
+ subspecnode.adapt_to(instnode.curfields[ofs], newboxlist,
+ newspecnodes, num)
-class VirtualizedSpecNode(SpecNodeWithFields):
+class VirtualizedOrDelayedSpecNode(SpecNodeWithFields):
def expand_boxlist(self, instnode, newboxlist, start):
- newboxlist.append(instnode.source)
+ newboxlist.append((0, instnode.source))
SpecNodeWithFields.expand_boxlist(self, instnode, newboxlist, start)
def extract_runtime_data(self, cpu, valuebox, resultlist):
- resultlist.append(valuebox)
+ resultlist.append((0, valuebox))
SpecNodeWithFields.extract_runtime_data(self, cpu, valuebox, resultlist)
- def adapt_to(self, instnode):
+ def adapt_to(self, instnode, newboxlist, newspecnodes, num):
instnode.escaped = True
- SpecNodeWithFields.adapt_to(self, instnode)
+ SpecNodeWithFields.adapt_to(self, instnode, newboxlist, newspecnodes,
+ num)
-class DelayedSpecNode(VirtualizedSpecNode):
+class DelayedSpecNode(VirtualizedOrDelayedSpecNode):
def expand_boxlist(self, instnode, newboxlist, oplist):
from pypy.jit.metainterp.history import AbstractDescr
- newboxlist.append(instnode.source)
+ newboxlist.append((0, 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)
+ newboxlist.append((0, instnode.curfields[ofs].source))
else:
if ofs in instnode.cleanfields:
- newboxlist.append(instnode.cleanfields[ofs].source)
+ newboxlist.append((0, 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)
+ newboxlist.append((0, box))
class DelayedFixedListSpecNode(DelayedSpecNode):
@@ -179,7 +206,7 @@
from pypy.jit.metainterp.resoperation import rop
from pypy.jit.metainterp.optimize import FixedList
- newboxlist.append(instnode.source)
+ newboxlist.append((0, instnode.source))
cls = self.known_class
assert isinstance(cls, FixedList)
arraydescr = cls.arraydescr
@@ -187,22 +214,22 @@
assert isinstance(subspecnode, SpecNodeWithBox)
if oplist is None:
instnode.cleanfields[ofs] = instnode.origfields[ofs]
- newboxlist.append(instnode.curfields[ofs].source)
+ newboxlist.append((0, instnode.curfields[ofs].source))
else:
if ofs in instnode.cleanfields:
- newboxlist.append(instnode.cleanfields[ofs].source)
+ newboxlist.append((0, instnode.cleanfields[ofs].source))
else:
box = subspecnode.box.clonebox()
oplist.append(ResOperation(rop.GETARRAYITEM_GC,
[instnode.source, ofs], box, arraydescr))
- newboxlist.append(box)
+ newboxlist.append((0, 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)
+ resultlist.append((0, valuebox))
cls = self.known_class
assert isinstance(cls, FixedList)
arraydescr = cls.arraydescr
@@ -212,48 +239,77 @@
[valuebox, ofs], arraydescr)
subspecnode.extract_runtime_data(cpu, fieldbox, resultlist)
-class VirtualizableSpecNode(VirtualizedSpecNode):
+class VirtualizedSpecNode(VirtualizedOrDelayedSpecNode):
def equals(self, other):
- if not isinstance(other, VirtualizableSpecNode):
+ if not self.known_class.equals(other.known_class):
return False
- return SpecNodeWithFields.equals(self, other)
+ 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 adapt_to(self, instnode):
+ def adapt_to(self, instnode, newboxlist, newspecnodes, num):
instnode.virtualized = True
- VirtualizedSpecNode.adapt_to(self, instnode)
+ fields = []
+ for ofs, subspecnode in self.fields:
+ if isinstance(subspecnode, MatchEverythingSpecNode):
+ if ofs in instnode.curfields:
+ orignode = instnode.origfields[ofs]
+ node = instnode.curfields[ofs]
+ subspecnode = orignode.intersect(node, {})
+ subspecnode.mutate_nodes(orignode)
+ subspecnode = RedirectingSpecNode(subspecnode, num)
+ subspecnode.expand_boxlist(orignode, newboxlist, None)
+ newspecnodes.append(subspecnode)
+ # otherwise we simply ignore unused field
+ else:
+ subspecnode.adapt_to(instnode.curfields[ofs], newboxlist,
+ newspecnodes, num)
+ fields.append((ofs, subspecnode))
+ self.fields = fields
+
+class VirtualizableSpecNode(VirtualizedSpecNode):
+
+ def equals(self, other):
+ if not isinstance(other, VirtualizableSpecNode):
+ return False
+ return VirtualizedSpecNode.equals(self, other)
class VirtualizableListSpecNode(VirtualizedSpecNode):
def equals(self, other):
if not isinstance(other, VirtualizableListSpecNode):
return False
- return SpecNodeWithFields.equals(self, other)
+ 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)
+ resultlist.append((0, 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)
-
- def adapt_to(self, instnode):
- instnode.virtualized = True
- VirtualizedSpecNode.adapt_to(self, instnode)
+ if not isinstance(subspecnode, MatchEverythingSpecNode):
+ fieldbox = executor.execute(cpu, rop.GETARRAYITEM_GC,
+ [valuebox, ofs], arraydescr)
+ subspecnode.extract_runtime_data(cpu, fieldbox, resultlist)
class VirtualSpecNode(SpecNodeWithFields):
- def adapt_to(self, instnode):
+ def adapt_to(self, instnode, newboxlist, newspecnodes, num):
instnode.virtual = True
- SpecNodeWithFields.adapt_to(self, instnode)
+ return SpecNodeWithFields.adapt_to(self, instnode, newboxlist,
+ newspecnodes, num)
def mutate_nodes(self, instnode):
SpecNodeWithFields.mutate_nodes(self, instnode)
Modified: pypy/branch/virtualizable-specnodes/pypy/jit/metainterp/test/test_virtualizable.py
==============================================================================
--- pypy/branch/virtualizable-specnodes/pypy/jit/metainterp/test/test_virtualizable.py (original)
+++ pypy/branch/virtualizable-specnodes/pypy/jit/metainterp/test/test_virtualizable.py Wed Mar 18 14:16:20 2009
@@ -394,7 +394,6 @@
assert res == 2
def test_pass_always_virtual_to_bridge(self):
- py.test.skip("in-progress")
jitdriver = JitDriver(greens = [], reds = ['frame', 'n'],
virtualizables = ['frame'])
@@ -423,7 +422,6 @@
assert res == 3
def test_virtual_obj_on_always_virtual(self):
- py.test.skip("in-progress")
jitdriver = JitDriver(greens = [], reds = ['frame', 'n', 's'],
virtualizables = ['frame'])
@@ -452,7 +450,7 @@
s += frame.l[1].elem
frame.l[1] = Stuff(n)
n -= 1
- return s
+ return (frame.l[0].elem << 16) + frame.l[1].elem
res = self.meta_interp(f, [30], listops=True)
self.check_loops(getfield_gc=0)
Modified: pypy/branch/virtualizable-specnodes/pypy/jit/metainterp/virtualizable.py
==============================================================================
--- pypy/branch/virtualizable-specnodes/pypy/jit/metainterp/virtualizable.py (original)
+++ pypy/branch/virtualizable-specnodes/pypy/jit/metainterp/virtualizable.py Wed Mar 18 14:16:20 2009
@@ -10,5 +10,18 @@
def __init__(self, cpu, TOPSTRUCT, STRUCTTYPE):
"NOT_RPYTHON"
- self.virtuals = [cpu.fielddescrof(STRUCTTYPE, 'inst_' + name) for
- name in TOPSTRUCT._hints['virtuals']]
+ self.virtuals = [cpu.fielddescrof(STRUCTTYPE, 'inst_' + name) for
+ name in TOPSTRUCT._hints['virtuals']]
+ self.fields = self.catch_all_fields(cpu, STRUCTTYPE)
+
+ def catch_all_fields(self, cpu, S):
+ lst = []
+ p = S
+ while True:
+ lst.extend(p._names)
+ if getattr(p, 'super', None) is not None:
+ p = p.super
+ else:
+ break
+ return [cpu.fielddescrof(S, name) for name in lst if
+ name.startswith('inst_')]
More information about the Pypy-commit
mailing list