[pypy-svn] r53870 - in pypy/branch/jit-hotpath/pypy: jit/rainbow jit/rainbow/test jit/timeshifter rpython/ootypesystem

antocuni at codespeak.net antocuni at codespeak.net
Sat Apr 19 15:43:08 CEST 2008


Author: antocuni
Date: Sat Apr 19 15:43:06 2008
New Revision: 53870

Modified:
   pypy/branch/jit-hotpath/pypy/jit/rainbow/codewriter.py
   pypy/branch/jit-hotpath/pypy/jit/rainbow/test/test_vdict.py
   pypy/branch/jit-hotpath/pypy/jit/timeshifter/oop.py
   pypy/branch/jit-hotpath/pypy/jit/timeshifter/vdict.py
   pypy/branch/jit-hotpath/pypy/rpython/ootypesystem/ootype.py
Log:
add support for vdicts to ootype. test_vdict passes



Modified: pypy/branch/jit-hotpath/pypy/jit/rainbow/codewriter.py
==============================================================================
--- pypy/branch/jit-hotpath/pypy/jit/rainbow/codewriter.py	(original)
+++ pypy/branch/jit-hotpath/pypy/jit/rainbow/codewriter.py	Sat Apr 19 15:43:06 2008
@@ -1085,23 +1085,25 @@
 
             self.emit(label(("after indirect call", op)))
 
-
-    def handle_oopspec_call(self, op, withexc):
+    def serialize_argtuple(self, opargs, argtuple):
         from pypy.jit.timeshifter.oop import Index
-        fnobj = get_funcobj(op.args[0].value)
-        oopspecdescindex = self.oopspecdesc_position('call', fnobj, withexc)
-        oopspecdesc = self.oopspecdescs[oopspecdescindex]
-        opargs = op.args[1:]
         args_v = []
         args = []
-        for obj in oopspecdesc.argtuple:
+        for obj in argtuple:
             if isinstance(obj, Index):
                 v = opargs[obj.n]
             else:
                 v = flowmodel.Constant(obj, lltype.typeOf(obj))
             args_v.append(v)
             args.append(self.serialize_oparg("red", v))
+        return args, args_v
 
+    def handle_oopspec_call(self, op, withexc):
+        fnobj = get_funcobj(op.args[0].value)
+        oopspecdescindex = self.oopspecdesc_position('call', fnobj, withexc)
+        oopspecdesc = self.oopspecdescs[oopspecdescindex]
+        opargs = op.args[1:]
+        args, args_v = self.serialize_argtuple(opargs, oopspecdesc.argtuple)
         if oopspecdesc.is_method:
             hs_self = self.hannotator.binding(
                 opargs[oopspecdesc.argtuple[0].n])
@@ -1650,12 +1652,12 @@
             # XXX: works only for List
             oopspecdescindex = self.oopspecdesc_position('new', TYPE, False)
             oopspecdesc = self.oopspecdescs[oopspecdescindex]
+            args, args_v = self.serialize_argtuple([], oopspecdesc.argtuple)
             deepfrozen = False
-            index = self.serialize_oparg("red", flowmodel.Constant(0, lltype.Signed))
-            self.emit('red_oopspec_call_1')
+            self.emit('red_oopspec_call_%s' % len(args))
             self.emit(oopspecdescindex)
             self.emit(deepfrozen)
-            self.emit(index)
+            self.emit(*args)
             self.register_redvar(op.result)
             return
 
@@ -1693,6 +1695,8 @@
             self.emit(oopspecdescindex)
             self.emit(deepfrozen)
             self.emit(*args)
+            if has_result:
+                self.register_redvar(op.result)
             return
 
         # real oosend, either red or const

Modified: pypy/branch/jit-hotpath/pypy/jit/rainbow/test/test_vdict.py
==============================================================================
--- pypy/branch/jit-hotpath/pypy/jit/rainbow/test/test_vdict.py	(original)
+++ pypy/branch/jit-hotpath/pypy/jit/rainbow/test/test_vdict.py	Sat Apr 19 15:43:06 2008
@@ -4,7 +4,7 @@
 from pypy.rlib.jit import hint
 
 
-class TestVDict(InterpretationTest):
+class VDictTest(InterpretationTest):
     type_system = "lltype"
 
     def test_vdict(self):
@@ -73,3 +73,10 @@
         res = self.interpret(ll_function, [3, 2], [0, 1], policy=P_OOPSPEC)
         assert res == 54
         self.check_insns({})
+
+
+class TestOOType(VDictTest):
+    type_system = "ootype"
+
+class TestLLType(VDictTest):
+    type_system = "lltype"

Modified: pypy/branch/jit-hotpath/pypy/jit/timeshifter/oop.py
==============================================================================
--- pypy/branch/jit-hotpath/pypy/jit/timeshifter/oop.py	(original)
+++ pypy/branch/jit-hotpath/pypy/jit/timeshifter/oop.py	Sat Apr 19 15:43:06 2008
@@ -163,6 +163,18 @@
     def __repr__(self):
         return '<%s(%s)>' % (self.__class__.__name__, self.method)
 
+def parse_oopspec(oopspec, argnames):
+    # parse the oopspec and fill in the arguments
+    operation_name, args = oopspec.split('(', 1)
+    assert args.endswith(')')
+    args = args[:-1] + ','     # trailing comma to force tuple syntax
+    if args.strip() == ',':
+        args = '()'
+    nb_args = len(argnames)
+    argname2index = dict(zip(argnames, [Index(n) for n in range(nb_args)]))
+    argtuple = eval(args, argname2index)
+    return operation_name, argtuple
+
 class CallOopSpecDesc(AbstractOopSpecDesc):
 
     def _setup_oopdesc(self, RGenOp, fnobj):
@@ -172,16 +184,9 @@
         ll_func = fnobj._callable
         nb_args = len(FUNCTYPE.ARGS)
 
-        # parse the oopspec and fill in the arguments
-        operation_name, args = ll_func.oopspec.split('(', 1)
-        assert args.endswith(')')
-        args = args[:-1] + ','     # trailing comma to force tuple syntax
-        if args.strip() == ',':
-            args = '()'
         argnames = ll_func.func_code.co_varnames[:nb_args]
-        argname2index = dict(zip(argnames, [Index(n) for n in range(nb_args)]))
-        self.argtuple = eval(args, argname2index)
-        # end of rather XXX'edly hackish parsing
+        operation_name, argtuple = parse_oopspec(ll_func.oopspec, argnames)
+        self.argtuple = argtuple
 
         self.OOPARGTYPES = []
         arg_llsig_to_oopsig = {}
@@ -245,6 +250,9 @@
         self.typename = TYPE.oopspec_name
         self.method = 'oop_new%s' % self.typename
         self.is_method = False
+        opname, argtuple = parse_oopspec(TYPE.oopspec_new, [])
+        assert opname == 'new'
+        self.argtuple = argtuple
 
         def allocate():
             return ootype.new(TYPE)
@@ -262,7 +270,7 @@
         METH = ootype.typeOf(meth)
         assert METH.SELFTYPE is not None, 'fix ootype'
         self.SELFTYPE = METH.SELFTYPE
-        self.ARGS = METH.ARGS
+        self.ARGS = [METH.SELFTYPE] + list(METH.ARGS)
         self.RESULT = METH.RESULT
 
         # we assume the number and position of the arguments are the
@@ -312,8 +320,15 @@
     exc_data_ptr = exceptiondesc.exc_data_ptr
     assert exceptiondesc.rtyper is not None
     llinterp = LLInterpreter(exceptiondesc.rtyper, exc_data_ptr=exc_data_ptr)
-    def on_top_of_llinterp(*args):
-        return llinterp.eval_graph(get_funcobj(fnptr).graph, list(args))
+    funcobj = get_funcobj(fnptr)
+    if hasattr(funcobj, 'graph'):
+        def on_top_of_llinterp(*args):
+            return llinterp.eval_graph(funcobj.graph, list(args))
+    else:
+        assert isinstance(fnptr, ootype._meth)
+        assert hasattr(fnptr, '_callable')
+        def on_top_of_llinterp(*args):
+            return fnptr._callable(*args)
     return on_top_of_llinterp
 
 class Entry(ExtRegistryEntry):

Modified: pypy/branch/jit-hotpath/pypy/jit/timeshifter/vdict.py
==============================================================================
--- pypy/branch/jit-hotpath/pypy/jit/timeshifter/vdict.py	(original)
+++ pypy/branch/jit-hotpath/pypy/jit/timeshifter/vdict.py	Sat Apr 19 15:43:06 2008
@@ -1,6 +1,7 @@
 import operator
 from pypy.rpython.lltypesystem import lltype
 from pypy.rpython.lltypesystem import rdict
+from pypy.rpython.ootypesystem import ootype
 from pypy.jit.timeshifter.rcontainer import VirtualContainer, FrozenContainer
 from pypy.jit.timeshifter.rcontainer import cachedtype
 from pypy.jit.timeshifter import rvalue, oop
@@ -8,10 +9,16 @@
 
 HASH = lltype.Signed
 
+def TypeDesc(RGenOp, rtyper, exceptiondesc, DICT):
+    if rtyper.type_system.name == 'lltypesystem':
+        return LLTypeDictTypeDesc(RGenOp, rtyper, exceptiondesc, DICT)
+    else:
+        return OOTypeDictTypeDesc(RGenOp, rtyper, exceptiondesc, DICT)
+
+
 # XXXXXXXXXX! ARGH.
 # cannot use a dictionary as the item_boxes at all, because of order issues
 
-
 class LLEqDesc(object):
     __metaclass__ = cachedtype
 
@@ -101,37 +108,17 @@
         VirtualDict.FrozenVirtualDict = FrozenVirtualDict
 
 
-class DictTypeDesc(object):
+class AbstractDictTypeDesc(object):
     __metaclass__ = cachedtype
 
     def __init__(self, RGenOp, rtyper, exceptiondesc, DICT):
-        bk = rtyper.annotator.bookkeeper
         self.DICT = DICT
-        self.DICTPTR = lltype.Ptr(DICT)
+        self.DICTPTR = self.Ptr(DICT)
         self.ptrkind = RGenOp.kindToken(self.DICTPTR)
 
-        argtypes = [bk.immutablevalue(DICT)]
-        ll_newdict_ptr = rtyper.annotate_helper_fn(rdict.ll_newdict,
-                                                   argtypes)
-        self.gv_ll_newdict = RGenOp.constPrebuiltGlobal(ll_newdict_ptr)
-        self.tok_ll_newdict = RGenOp.sigToken(lltype.typeOf(ll_newdict_ptr).TO)
+        self._setup(RGenOp, rtyper, DICT)
 
-        argtypes = [self.DICTPTR, DICT.KEY, DICT.VALUE, HASH]
-        ll_insertclean = rtyper.annotate_helper_fn(rdict.ll_dict_insertclean,
-                                                    argtypes)
-        self.gv_ll_insertclean = RGenOp.constPrebuiltGlobal(ll_insertclean)
-        self.tok_ll_insertclean = RGenOp.sigToken(
-            lltype.typeOf(ll_insertclean).TO)
-
-        # XXX some fishing that only works if the DICT does not come from
-        # an r_dict
-        if DICT.keyeq is None:
-            keyeq = operator.eq
-        else:
-            assert isinstance(DICT.keyeq, lltype.staticAdtMethod)
-            keyeq = DICT.keyeq.__get__(42)
-        assert isinstance(DICT.keyhash, lltype.staticAdtMethod)
-        keyhash = DICT.keyhash.__get__(42)
+        keyeq, keyhash = self._get_eq_hash(DICT)
         keydesc = LLEqDesc(DICT.KEY, keyeq, keyhash)
         self.VirtualDict = keydesc.VirtualDict
 
@@ -142,7 +129,7 @@
 
     def factory(self):
         vdict = self.VirtualDict(self)
-        box = rvalue.PtrRedBox(known_nonzero=True)
+        box = self.PtrRedBox(known_nonzero=True)
         box.content = vdict
         vdict.ownbox = box
         return box
@@ -165,9 +152,70 @@
         self.allocate = allocate
         self.perform_setitem = perform_setitem
 
-TypeDesc = DictTypeDesc
+
+class LLTypeDictTypeDesc(AbstractDictTypeDesc):
+
+    Ptr = staticmethod(lltype.Ptr)
+    PtrRedBox = rvalue.PtrRedBox
+
+    def _setup(self, RGenOp, rtyper, DICT):
+        bk = rtyper.annotator.bookkeeper
+        argtypes = [bk.immutablevalue(DICT)]
+        ll_newdict_ptr = rtyper.annotate_helper_fn(rdict.ll_newdict,
+                                                   argtypes)
+        self.gv_ll_newdict = RGenOp.constPrebuiltGlobal(ll_newdict_ptr)
+        self.tok_ll_newdict = RGenOp.sigToken(lltype.typeOf(ll_newdict_ptr).TO)
+
+        argtypes = [self.DICTPTR, DICT.KEY, DICT.VALUE, HASH]
+        ll_insertclean = rtyper.annotate_helper_fn(rdict.ll_dict_insertclean,
+                                                    argtypes)
+        self.gv_ll_insertclean = RGenOp.constPrebuiltGlobal(ll_insertclean)
+        self.tok_ll_insertclean = RGenOp.sigToken(
+            lltype.typeOf(ll_insertclean).TO)
+
+    def _get_eq_hash(self, DICT):
+        # XXX some fishing that only works if the DICT does not come from
+        # an r_dict
+        if DICT.keyeq is None:
+            keyeq = operator.eq
+        else:
+            assert isinstance(DICT.keyeq, lltype.staticAdtMethod)
+            keyeq = DICT.keyeq.__get__(42)
+        assert isinstance(DICT.keyhash, lltype.staticAdtMethod)
+        keyhash = DICT.keyhash.__get__(42)
+        return keyeq, keyhash
+
+    def gen_newdict(self, builder, args_gv):
+        return builder.genop_call(self.tok_ll_newdict,
+                                  self.gv_ll_newdict,
+                                  args_gv)
+
+    def gen_insertclean(self, builder, args_gv):
+        return builder.genop_call(typedesc.tok_ll_insertclean,
+                                  typedesc.gv_ll_insertclean,
+                                  args_gv)
+
 
 
+class OOTypeDictTypeDesc(AbstractDictTypeDesc):
+
+    Ptr = staticmethod(lambda T: T)
+    PtrRedBox = rvalue.InstanceRedBox
+
+    def _setup(self, RGenOp, rtyper, DICT):
+        assert not isinstance(DICT, ootype.CustomDict), 'TODO'
+        self.alloctoken = RGenOp.allocToken(DICT)
+        self.tok_ll_set = RGenOp.methToken(DICT, 'll_set')
+
+    def _get_eq_hash(self, DICT):
+        return operator.eq, hash
+
+    def gen_newdict(self, builder, args_gv):
+        XXX
+
+    def gen_insertclean(self, builder, args_gv):
+        XXX
+
 class AbstractFrozenVirtualDict(FrozenContainer):
     _attrs_ = ('typedesc',)
 
@@ -232,18 +280,14 @@
         items = self.getitems_and_makeempty(builder.rgenop)
 
         args_gv = []
-        gv_dict = builder.genop_call(typedesc.tok_ll_newdict,
-                                     typedesc.gv_ll_newdict,
-                                     args_gv)
+        gv_dict = typedesc.gen_newdict(builder, args_gv)
         self.ownbox.setgenvar_hint(gv_dict, known_nonzero=True)
         self.ownbox.content = None
         for gv_key, valuebox, hash in items:
             gv_hash = builder.rgenop.genconst(hash)
             gv_value = valuebox.getgenvar(jitstate)
             args_gv = [gv_dict, gv_key, gv_value, gv_hash]
-            builder.genop_call(typedesc.tok_ll_insertclean,
-                               typedesc.gv_ll_insertclean,
-                               args_gv)
+            typedesc.gen_insertclean(builder, args_gv)
 
     def freeze(self, memo):
         contmemo = memo.containers
@@ -333,3 +377,7 @@
         return oopspecdesc.residual_call(jitstate, [selfbox, keybox],
                                          deepfrozen=deepfrozen)
 oop_dict_contains.couldfold = True
+
+oop_dict_method_set = oop_dict_setitem
+oop_dict_method_get = oop_dict_getitem
+oop_dict_method_contains = oop_dict_contains

Modified: pypy/branch/jit-hotpath/pypy/rpython/ootypesystem/ootype.py
==============================================================================
--- pypy/branch/jit-hotpath/pypy/rpython/ootypesystem/ootype.py	(original)
+++ pypy/branch/jit-hotpath/pypy/rpython/ootypesystem/ootype.py	Sat Apr 19 15:43:06 2008
@@ -489,6 +489,7 @@
     SELFTYPE_T = object()
     ITEMTYPE_T = object()
     oopspec_name = 'list'
+    oopspec_new = 'new(0)'
 
     def __init__(self, ITEMTYPE=None):
         self._ITEMTYPE = ITEMTYPE
@@ -578,6 +579,7 @@
     KEYTYPE_T = object()
     VALUETYPE_T = object()
     oopspec_name = 'dict'
+    oopspec_new = 'new()'
 
     def __init__(self, KEYTYPE=None, VALUETYPE=None):
         self._KEYTYPE = KEYTYPE
@@ -1446,6 +1448,7 @@
         assert key in self._dict
         assert key == self._last_key
         return self._dict[key]
+    ll_get.oopargcheck = lambda d, key: bool(d)
 
     def ll_set(self, key, value):
         # NOT_RPYTHON
@@ -1469,6 +1472,7 @@
         assert typeOf(key) == self._TYPE._KEYTYPE
         self._last_key = key
         return key in self._dict
+    ll_contains.oopargcheck = lambda d, key: bool(d)
 
     def ll_clear(self):
         self._dict.clear()


More information about the pypy-svn mailing list