[pypy-svn] r61857 - pypy/branch/pyjitpl5/pypy/jit/metainterp
fijal at codespeak.net
fijal at codespeak.net
Fri Feb 13 22:48:05 CET 2009
Author: fijal
Date: Fri Feb 13 22:48:03 2009
New Revision: 61857
Modified:
pypy/branch/pyjitpl5/pypy/jit/metainterp/codewriter.py
pypy/branch/pyjitpl5/pypy/jit/metainterp/optimize.py
pypy/branch/pyjitpl5/pypy/jit/metainterp/pyjitpl.py
pypy/branch/pyjitpl5/pypy/jit/metainterp/specnode.py
pypy/branch/pyjitpl5/pypy/jit/metainterp/support.py
Log:
Do it correctly (at least a bit more). Now delayed list comes with it's own
specnode, which makes things vastly easier. Next step - recover from
guard failure
Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/codewriter.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/metainterp/codewriter.py (original)
+++ pypy/branch/pyjitpl5/pypy/jit/metainterp/codewriter.py Fri Feb 13 22:48:03 2009
@@ -1,5 +1,4 @@
from pypy.annotation import model as annmodel
-from pypy.rpython.annlowlevel import MixLevelHelperAnnotator
from pypy.rpython.lltypesystem import lltype, llmemory, rstr
from pypy.objspace.flow.model import Variable, Constant, Link, c_last_exception
from pypy.rlib import objectmodel
@@ -15,6 +14,20 @@
MAX_MAKE_NEW_VARS = 16
+class BuiltinDescr(history.AbstractValue):
+ pass
+
+class ListDescr(BuiltinDescr):
+ def __init__(self, getfunc, setfunc, tp):
+ self.setfunc = setfunc
+ self.getfunc = getfunc
+ self.tp = tp
+
+ def equals(self, other):
+ if isinstance(other, ListDescr):
+ return True
+ return False
+
class JitCode(history.AbstractValue):
def __init__(self, name):
self.name = name
@@ -74,6 +87,7 @@
self.rtyper = metainterp.cpu.rtyper
self.cpu = metainterp.cpu
self.policy = policy
+ self.list_cache = {}
def make_portal_bytecode(self, graph):
log.info("making JitCodes...")
@@ -125,6 +139,29 @@
metainterp.builtins_keys.append(key)
metainterp.builtins_values.append(value)
+
+ def list_descr_for_tp(self, TP):
+ try:
+ return self.list_cache[TP.TO]
+ except KeyError:
+ rtyper = self.rtyper
+ args = [TP, lltype.Signed, TP.TO.OF]
+ setfunc = support.builtin_func_for_spec(rtyper, 'list.setitem',
+ args, lltype.Void)
+ getfunc = support.builtin_func_for_spec(rtyper, 'list.getitem',
+ args[:-1], TP.TO.OF)
+ if isinstance(TP.TO.OF, lltype.Number):
+ tp = "int"
+ else:
+ tp = "ptr"
+ ld = ListDescr(history.ConstAddr(getfunc.value, self.cpu),
+ history.ConstAddr(setfunc.value, self.cpu),
+ tp)
+ self.list_cache[TP.TO] = ld
+ return ld
+
+
+
class BytecodeMaker(object):
debug = True
@@ -515,10 +552,11 @@
if isinstance(arg.concretetype, lltype.Ptr):
# XXX very complex logic for getting all things
# that are pointers, but not objects
- if not (isinstance(arg.concretetype.TO, lltype.GcStruct) and
- (heaptracker.get_vtable_for_gcstruct(self.cpu,
- arg.concretetype.TO))):
- self.emit('guard_builtin', self.var_position(arg))
+ if isinstance(arg.concretetype.TO, lltype.GcArray):
+ descr = self.codewriter.list_descr_for_tp(
+ arg.concretetype)
+ self.emit('guard_builtin', self.var_position(arg),
+ self.get_position(descr))
elif op.args[0].value == 'can_enter_jit':
self.emit('can_enter_jit')
@@ -559,21 +597,10 @@
def handle_builtin_call(self, op):
oopspec_name, args = support.decode_builtin_call(op)
- args_s = [annmodel.lltype_to_annotation(v.concretetype)
- for v in args]
- if '.' not in oopspec_name: # 'newxxx' operations
- LIST_OR_DICT = op.result.concretetype
- bk = self.codewriter.rtyper.annotator.bookkeeper
- args_s.insert(0, annmodel.SomePBC([bk.getdesc(LIST_OR_DICT.TO)]))
- else:
- LIST_OR_DICT = args[0].concretetype
- s_result = annmodel.lltype_to_annotation(op.result.concretetype)
- impl = support.setup_extra_builtin(oopspec_name, len(args_s))
- #
- mixlevelann = MixLevelHelperAnnotator(self.codewriter.rtyper)
- c_func = mixlevelann.constfunc(impl, args_s, s_result)
- mixlevelann.finish()
- #
+ ll_args = [v.concretetype for v in args]
+ c_func = support.builtin_func_for_spec(self.codewriter.rtyper,
+ oopspec_name, ll_args,
+ op.result.concretetype)
if oopspec_name.endswith('_foldable'):
opname = 'green_call_%s'
else:
Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/optimize.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/metainterp/optimize.py (original)
+++ pypy/branch/pyjitpl5/pypy/jit/metainterp/optimize.py Fri Feb 13 22:48:03 2009
@@ -7,8 +7,10 @@
VirtualizableSpecNode,
NotSpecNode,
DelayedSpecNode,
- SpecNodeWithBox)
+ SpecNodeWithBox,
+ DelayedListSpecNode)
from pypy.rlib.objectmodel import we_are_translated
+from pypy.jit.metainterp.codewriter import ListDescr
class CancelInefficientLoop(Exception):
pass
@@ -110,6 +112,8 @@
return NotSpecNode()
return FixedClassSpecNode(known_class)
if not other.escaped:
+ # XXX write a spec node
+ assert not isinstance(known_class, ListDescr)
fields = []
lst = other.curfields.items()
lst.sort()
@@ -128,6 +132,8 @@
for ofs in lst:
specnode = SpecNodeWithBox(self.origfields[ofs].source)
fields.append((ofs, specnode))
+ if isinstance(known_class, ListDescr):
+ return DelayedListSpecNode(known_class, fields)
return DelayedSpecNode(known_class, fields)
else:
assert self is other
@@ -243,7 +249,7 @@
elif opname == 'guard_builtin':
instnode = self.nodes[op.args[0]]
# all builtins have equal classes
- instnode.cls = InstanceNode(ConstInt(0))
+ instnode.cls = InstanceNode(op.args[1])
continue
elif opname == 'setfield_gc':
instnode = self.getnode(op.args[0])
@@ -543,8 +549,14 @@
# we need to invalidate everything
for node in self.nodes.values():
for ofs, valuenode in node.dirtyfields.items():
- newoperations.append(ResOperation('setfield_gc',
- [node.source, ConstInt(ofs), valuenode.source], []))
+ # XXX move to IntanceNode eventually
+ if isinstance(node.cls.source, ListDescr):
+ newoperations.append(ResOperation('setitem',
+ [node.cls.source.setfunc, node.source,
+ ConstInt(ofs), valuenode.source], []))
+ else:
+ newoperations.append(ResOperation('setfield_gc',
+ [node.source, ConstInt(ofs), valuenode.source], []))
node.dirtyfields = {}
node.cleanfields = {}
Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/pyjitpl.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/metainterp/pyjitpl.py (original)
+++ pypy/branch/pyjitpl5/pypy/jit/metainterp/pyjitpl.py Fri Feb 13 22:48:03 2009
@@ -74,7 +74,7 @@
args += (indirectcallset, )
elif argspec == "builtin":
builtin = self.load_const_arg()
- assert isinstance(builtin, codewriter.BuiltinCall)
+ assert isinstance(builtin, codewriter.BuiltinDescr)
args += (builtin, )
elif argspec == "virtualizabledesc":
from virtualizable import VirtualizableDesc
@@ -419,9 +419,9 @@
self.generate_guard(pc, 'guard_class', box, [clsbox])
return clsbox
- @arguments("orgpc", "box")
- def opimpl_guard_builtin(self, pc, box):
- self.generate_guard(pc, "guard_builtin", box)
+ @arguments("orgpc", "box", "builtin")
+ def opimpl_guard_builtin(self, pc, box, builtin):
+ self.generate_guard(pc, "guard_builtin", box, [builtin])
@arguments("orgpc", "box", "virtualizabledesc", "int")
def opimpl_guard_nonvirtualized(self, pc, box, vdesc, guard_field):
Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/specnode.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/metainterp/specnode.py (original)
+++ pypy/branch/pyjitpl5/pypy/jit/metainterp/specnode.py Fri Feb 13 22:48:03 2009
@@ -151,6 +151,39 @@
[instnode.source, ConstInt(ofs)], [box]))
newboxlist.append(box)
+class DelayedListSpecNode(DelayedSpecNode):
+
+ def expand_boxlist(self, instnode, newboxlist, oplist):
+ from pypy.jit.metainterp.history import ResOperation, ConstInt
+
+ 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:
+ xxx
+ box = subspecnode.box.clonebox()
+ oplist.append(ResOperation('setitem',
+ [instnode.source, ConstInt(ofs)], [box]))
+ newboxlist.append(box)
+
+ def extract_runtime_data(self, cpu, valuebox, resultlist):
+ from pypy.jit.metainterp.codewriter import ListDescr
+
+ resultlist.append(valuebox)
+ ld = self.known_class
+ assert isinstance(ld, ListDescr)
+ for ofs, subspecnode in self.fields:
+ fieldbox = cpu.execute_operation('getitem',
+ [ld.getfunc, valuebox, ConstInt(ofs)],
+ ld.tp)
+ subspecnode.extract_runtime_data(cpu, fieldbox, resultlist)
+
class VirtualizableSpecNode(VirtualizedSpecNode):
def equals(self, other):
Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/support.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/metainterp/support.py (original)
+++ pypy/branch/pyjitpl5/pypy/jit/metainterp/support.py Fri Feb 13 22:48:03 2009
@@ -10,6 +10,7 @@
from pypy.translator.translator import TranslationContext
from pypy.annotation.policy import AnnotatorPolicy
from pypy.annotation import model as annmodel
+from pypy.rpython.annlowlevel import MixLevelHelperAnnotator
def getargtypes(annotator, values):
if values is None: # for backend tests producing stand-alone exe's
@@ -178,3 +179,20 @@
return get_call_oopspec_opargs(fnobj, opargs)
else:
raise ValueError(op.opname)
+
+def builtin_func_for_spec(rtyper, oopspec_name, ll_args, ll_res):
+ args_s = [annmodel.lltype_to_annotation(v) for v in ll_args]
+ if '.' not in oopspec_name: # 'newxxx' operations
+ LIST_OR_DICT = op.result.concretetype
+ bk = self.codewriter.rtyper.annotator.bookkeeper
+ args_s.insert(0, annmodel.SomePBC([bk.getdesc(LIST_OR_DICT.TO)]))
+ else:
+ LIST_OR_DICT = ll_args[0]
+ s_result = annmodel.lltype_to_annotation(ll_res)
+ impl = setup_extra_builtin(oopspec_name, len(args_s))
+ #
+ mixlevelann = MixLevelHelperAnnotator(rtyper)
+ c_func = mixlevelann.constfunc(impl, args_s, s_result)
+ mixlevelann.finish()
+ #
+ return c_func
More information about the Pypy-commit
mailing list