[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