[pypy-svn] r74871 - in pypy/branch/blackhole-improvement/pypy: jit/backend/llsupport jit/backend/llsupport/test rpython/lltypesystem

arigo at codespeak.net arigo at codespeak.net
Fri May 28 20:46:52 CEST 2010


Author: arigo
Date: Fri May 28 20:46:50 2010
New Revision: 74871

Modified:
   pypy/branch/blackhole-improvement/pypy/jit/backend/llsupport/descr.py
   pypy/branch/blackhole-improvement/pypy/jit/backend/llsupport/gc.py
   pypy/branch/blackhole-improvement/pypy/jit/backend/llsupport/llmodel.py
   pypy/branch/blackhole-improvement/pypy/jit/backend/llsupport/test/test_descr.py
   pypy/branch/blackhole-improvement/pypy/jit/backend/llsupport/test/test_gc.py
   pypy/branch/blackhole-improvement/pypy/rpython/lltypesystem/ll2ctypes.py
Log:
Start implementing bh_call_x.


Modified: pypy/branch/blackhole-improvement/pypy/jit/backend/llsupport/descr.py
==============================================================================
--- pypy/branch/blackhole-improvement/pypy/jit/backend/llsupport/descr.py	(original)
+++ pypy/branch/blackhole-improvement/pypy/jit/backend/llsupport/descr.py	Fri May 28 20:46:50 2010
@@ -179,7 +179,6 @@
 # CallDescrs
 
 class BaseCallDescr(AbstractDescr):
-    empty_box = BoxInt(0)
     _clsname = ''
     loop_token = None
     arg_classes = ''     # <-- annotation hack
@@ -207,19 +206,11 @@
     def get_result_size(self, translate_support_code):
         raise NotImplementedError
 
-    def get_call_stub(self):
-        return self.call_stub
-
     def create_call_stub(self, rtyper, RESULT):
-        def process(no, c):
-            if c == 'i':
-                return 'args[%d].getint()' % (no,)
-            elif c == 'f':
-                return 'args[%d].getfloat()' % (no,)
-            elif c == 'r':
-                return 'args[%d].getref_base()' % (no,)
-            else:
-                raise Exception("Unknown type %s for type %s" % (c, TP))
+        def process(c):
+            arg = 'args_%s[%d]' % (c, seen[c])
+            seen[c] += 1
+            return arg
 
         def TYPE(arg):
             if arg == 'i':
@@ -230,21 +221,21 @@
                 return llmemory.GCREF
             elif arg == 'v':
                 return lltype.Void
-            
-        args = ", ".join([process(i + 1, c) for i, c in
-                          enumerate(self.arg_classes)])
+
+        seen = {'i': 0, 'r': 0, 'f': 0}
+        args = ", ".join([process(c) for c in self.arg_classes])
 
         if self.returns_a_pointer():
-            result = 'history.BoxPtr(lltype.cast_opaque_ptr(llmemory.GCREF, res))'
+            result = 'lltype.cast_opaque_ptr(llmemory.GCREF, res)'
         elif self.returns_a_float():
-            result = 'history.BoxFloat(res)'
+            result = 'res'
         elif self.returns_a_void():
             result = 'None'
         else:
-            result = 'history.BoxInt(rffi.cast(lltype.Signed, res))'
+            result = 'rffi.cast(lltype.Signed, res)'
         source = py.code.Source("""
-        def call_stub(args):
-            fnptr = rffi.cast(lltype.Ptr(FUNC), args[0].getint())
+        def call_stub(func, args_i, args_r, args_f):
+            fnptr = rffi.cast(lltype.Ptr(FUNC), func)
             res = support.maybe_on_top_of_llinterp(rtyper, fnptr)(%(args)s)
             return %(result)s
         """ % locals())
@@ -255,35 +246,61 @@
         exec source.compile() in d
         self.call_stub = d['call_stub']
 
+    def verify_types(self, args_i, args_r, args_f, return_type):
+        assert self._returns_a_pointer == (return_type == 'ref')
+        assert self._returns_a_float   == (return_type == 'float')
+        assert self._returns_a_void    == (return_type == 'void')
+        assert self.arg_classes.count('i') == len(args_i or ())
+        assert self.arg_classes.count('r') == len(args_r or ())
+        assert self.arg_classes.count('f') == len(args_f or ())
+
     def repr_of_descr(self):
         return '<%s>' % self._clsname
 
 
-class NonGcPtrCallDescr(BaseCallDescr):
+class BaseIntCallDescr(BaseCallDescr):
+    # Base class of the various subclasses of descrs corresponding to
+    # calls having a return kind of 'int' (including non-gc pointers).
+    # The inheritance hierarchy is a bit different than with other Descr
+    # classes because of the 'call_stub' attribute, which is of type
+    #
+    #     lambda args_i, args_r, args_f --> int/ref/float/void
+    #
+    # The purpose of BaseIntCallDescr is to be the parent of all classes
+    # in which 'call_stub' has a return kind of 'int'.
+    pass
+
+class NonGcPtrCallDescr(BaseIntCallDescr):
     _clsname = 'NonGcPtrCallDescr'
-    
     def get_result_size(self, translate_support_code):
         return symbolic.get_size_of_ptr(translate_support_code)
 
-class GcPtrCallDescr(NonGcPtrCallDescr):
-    empty_box = BoxPtr(lltype.nullptr(llmemory.GCREF.TO))
+class GcPtrCallDescr(BaseCallDescr):
     _clsname = 'GcPtrCallDescr'
     _returns_a_pointer = True
+    def get_result_size(self, translate_support_code):
+        return symbolic.get_size_of_ptr(translate_support_code)
+
+class FloatCallDescr(BaseCallDescr):
+    _clsname = 'FloatCallDescr'
+    _returns_a_float = True
+    def get_result_size(self, translate_support_code):
+        return symbolic.get_size(lltype.Float, translate_support_code)
 
-class VoidCallDescr(NonGcPtrCallDescr):
-    empty_box = None
+class VoidCallDescr(BaseCallDescr):
     _clsname = 'VoidCallDescr'
     _returns_a_void = True
-    
     def get_result_size(self, translate_support_code):
         return 0
 
 def getCallDescrClass(RESULT):
     if RESULT is lltype.Void:
         return VoidCallDescr
-    return getDescrClass(RESULT, BaseCallDescr, GcPtrCallDescr,
+    if RESULT is lltype.Float:
+        return FloatCallDescr
+    return getDescrClass(RESULT, BaseIntCallDescr, GcPtrCallDescr,
                          NonGcPtrCallDescr, 'Call', 'get_result_size',
-                         '_returns_a_float')
+                         Ellipsis)  # <= floatattrname should not be used here
 
 def get_call_descr(gccache, ARGS, RESULT, extrainfo=None):
     arg_classes = []
@@ -330,7 +347,6 @@
         #
         if TYPE is lltype.Float:
             setattr(Descr, floatattrname, True)
-            Descr.empty_box = BoxFloat(0.0)
         #
         _cache[nameprefix, TYPE] = Descr
         return Descr

Modified: pypy/branch/blackhole-improvement/pypy/jit/backend/llsupport/gc.py
==============================================================================
--- pypy/branch/blackhole-improvement/pypy/jit/backend/llsupport/gc.py	(original)
+++ pypy/branch/blackhole-improvement/pypy/jit/backend/llsupport/gc.py	Fri May 28 20:46:50 2010
@@ -171,6 +171,7 @@
         # the object moves)
         addr = llmemory.cast_ptr_to_adr(gcref)
         hash = llmemory.cast_adr_to_int(addr)
+        hash = llmemory.get_inthash_from_int(hash)
         hash -= hash >> self.HASHTABLE_BITS
         hash &= self.HASHTABLE_SIZE - 1
         addr_ref = self.hashtable[hash]

Modified: pypy/branch/blackhole-improvement/pypy/jit/backend/llsupport/llmodel.py
==============================================================================
--- pypy/branch/blackhole-improvement/pypy/jit/backend/llsupport/llmodel.py	(original)
+++ pypy/branch/blackhole-improvement/pypy/jit/backend/llsupport/llmodel.py	Fri May 28 20:46:50 2010
@@ -12,7 +12,9 @@
 from pypy.jit.backend.llsupport.descr import get_size_descr,  BaseSizeDescr
 from pypy.jit.backend.llsupport.descr import get_field_descr, BaseFieldDescr
 from pypy.jit.backend.llsupport.descr import get_array_descr, BaseArrayDescr
-from pypy.jit.backend.llsupport.descr import get_call_descr,  BaseCallDescr
+from pypy.jit.backend.llsupport.descr import get_call_descr
+from pypy.jit.backend.llsupport.descr import BaseIntCallDescr, GcPtrCallDescr
+from pypy.jit.backend.llsupport.descr import FloatCallDescr, VoidCallDescr
 from pypy.rpython.annlowlevel import cast_instance_to_base_ptr
 
 empty_int_box = BoxInt(0)
@@ -471,32 +473,29 @@
         basesize = basesize // itemsize
         rffi.cast(rffi.CArrayPtr(lltype.UniChar), a)[index + basesize] = unichr(v)
 
-    def do_call(self, args, calldescr):
-        assert isinstance(calldescr, BaseCallDescr)
-        assert len(args) == 1 + len(calldescr.arg_classes)
+    def bh_call_i(self, func, calldescr, args_i, args_r, args_f):
+        assert isinstance(calldescr, BaseIntCallDescr)
         if not we_are_translated():
-            assert (list(calldescr.arg_classes) ==
-                    [arg.type for arg in args[1:]])
-        callstub = calldescr.get_call_stub()
-        try:
-            return callstub(args)
-        except Exception, e:
-            if not we_are_translated():
-                if not type(e) is LLException:
-                    raise
-                self.saved_exc_value = lltype.cast_opaque_ptr(llmemory.GCREF,
-                                                              e.args[1])
-                self.saved_exception = rffi.cast(lltype.Signed, e.args[0])
-            else:
-                ptr = cast_instance_to_base_ptr(e)
-                self.saved_exc_value = lltype.cast_opaque_ptr(llmemory.GCREF,
-                                                              ptr)
-                self.saved_exception = rffi.cast(lltype.Signed, ptr.typeptr)
-            return calldescr.empty_box
-            
-    def do_cast_ptr_to_int(self, ptrbox):
-        return BoxInt(self.cast_gcref_to_int(ptrbox.getref_base()))
+            calldescr.verify_types(args_i, args_r, args_f, 'int')
+        return calldescr.call_stub(func, args_i, args_r, args_f)
 
+    def bh_call_r(self, func, calldescr, args_i, args_r, args_f):
+        assert isinstance(calldescr, GcPtrCallDescr)
+        if not we_are_translated():
+            calldescr.verify_types(args_i, args_r, args_f, 'ref')
+        return calldescr.call_stub(func, args_i, args_r, args_f)
+
+    def bh_call_f(self, func, calldescr, args_i, args_r, args_f):
+        assert isinstance(calldescr, FloatCallDescr)
+        if not we_are_translated():
+            calldescr.verify_types(args_i, args_r, args_f, 'float')
+        return calldescr.call_stub(func, args_i, args_r, args_f)
 
-import pypy.jit.metainterp.executor
-pypy.jit.metainterp.executor.make_execute_list(AbstractLLCPU)
+    def bh_call_v(self, func, calldescr, args_i, args_r, args_f):
+        assert isinstance(calldescr, VoidCallDescr)
+        if not we_are_translated():
+            calldescr.verify_types(args_i, args_r, args_f, 'void')
+        return calldescr.call_stub(func, args_i, args_r, args_f)
+
+    def do_cast_ptr_to_int(self, ptrbox):
+        return BoxInt(self.cast_gcref_to_int(ptrbox.getref_base()))

Modified: pypy/branch/blackhole-improvement/pypy/jit/backend/llsupport/test/test_descr.py
==============================================================================
--- pypy/branch/blackhole-improvement/pypy/jit/backend/llsupport/test/test_descr.py	(original)
+++ pypy/branch/blackhole-improvement/pypy/jit/backend/llsupport/test/test_descr.py	Fri May 28 20:46:50 2010
@@ -148,30 +148,29 @@
     assert not descr1.returns_a_pointer()
     assert not descr1.returns_a_float()
     assert descr1.arg_classes == "ii"
-    assert isinstance(descr1.empty_box, BoxInt)
     #
     T = lltype.GcStruct('T')
     descr2 = get_call_descr(c0, [lltype.Ptr(T)], lltype.Ptr(T))
     assert descr2.get_result_size(False) == rffi.sizeof(lltype.Ptr(T))
     assert descr2.returns_a_pointer()
     assert not descr2.returns_a_float()
+    assert not descr2.returns_a_void()
     assert descr2.arg_classes == "r"
-    assert isinstance(descr2.empty_box, BoxPtr)
     #
     U = lltype.GcStruct('U', ('x', lltype.Signed))
     assert descr2 == get_call_descr(c0, [lltype.Ptr(U)], lltype.Ptr(U))
     #
     V = lltype.Struct('V', ('x', lltype.Signed))
-    assert isinstance(get_call_descr(c0, [], lltype.Ptr(V)).empty_box, BoxInt)
+    assert not get_call_descr(c0, [], lltype.Ptr(V)).returns_a_pointer()
     #
-    assert get_call_descr(c0, [], lltype.Void).empty_box is None
+    assert get_call_descr(c0, [], lltype.Void).returns_a_void()
     #
     descr4 = get_call_descr(c0, [lltype.Float, lltype.Float], lltype.Float)
     assert descr4.get_result_size(False) == rffi.sizeof(lltype.Float)
     assert not descr4.returns_a_pointer()
     assert descr4.returns_a_float()
+    assert not descr4.returns_a_void()
     assert descr4.arg_classes == "ff"
-    assert isinstance(descr4.empty_box, BoxFloat)
 
 def test_get_call_descr_translated():
     c1 = GcCache(True)
@@ -245,12 +244,11 @@
     def f(a, b):
         return 'c'
 
-    call_stub = descr1.get_call_stub()
+    call_stub = descr1.call_stub
     fnptr = llhelper(lltype.Ptr(lltype.FuncType(ARGS, RES)), f)
 
-    res = call_stub([BoxInt(rffi.cast(lltype.Signed, fnptr)),
-                     BoxInt(1), BoxInt(2)])
-    assert res.getint() == ord('c')
+    res = call_stub(rffi.cast(lltype.Signed, fnptr), [1, 2], None, None)
+    assert res == ord('c')
 
     ARRAY = lltype.GcArray(lltype.Signed)
     ARGS = [lltype.Float, lltype.Ptr(ARRAY)]
@@ -264,6 +262,6 @@
     a = lltype.malloc(ARRAY, 3)
     opaquea = lltype.cast_opaque_ptr(llmemory.GCREF, a)
     a[0] = 1
-    res = descr2.get_call_stub()([BoxInt(rffi.cast(lltype.Signed, fnptr)),
-                                  BoxFloat(3.5), BoxPtr(opaquea)])
-    assert res.getfloat() == 4.5
+    res = descr2.call_stub(rffi.cast(lltype.Signed, fnptr),
+                           [], [opaquea], [3.5])
+    assert res == 4.5

Modified: pypy/branch/blackhole-improvement/pypy/jit/backend/llsupport/test/test_gc.py
==============================================================================
--- pypy/branch/blackhole-improvement/pypy/jit/backend/llsupport/test/test_gc.py	(original)
+++ pypy/branch/blackhole-improvement/pypy/jit/backend/llsupport/test/test_gc.py	Fri May 28 20:46:50 2010
@@ -291,7 +291,7 @@
         v_random_box = BoxPtr()
         v_result = BoxInt()
         operations = [
-            ResOperation(rop.OOIS, [v_random_box, ConstPtr(s_gcref)],
+            ResOperation(rop.PTR_EQ, [v_random_box, ConstPtr(s_gcref)],
                          v_result),
             ]
         gc_ll_descr = self.gc_ll_descr
@@ -303,7 +303,7 @@
         assert operations[0].descr == gc_ll_descr.single_gcref_descr
         v_box = operations[0].result
         assert isinstance(v_box, BoxPtr)
-        assert operations[1].opnum == rop.OOIS
+        assert operations[1].opnum == rop.PTR_EQ
         assert operations[1].args == [v_random_box, v_box]
         assert operations[1].result == v_result
 
@@ -324,7 +324,7 @@
         v_random_box = BoxPtr()
         v_result = BoxInt()
         operations = [
-            ResOperation(rop.OOIS, [v_random_box, ConstPtr(s_gcref)],
+            ResOperation(rop.PTR_EQ, [v_random_box, ConstPtr(s_gcref)],
                          v_result),
             ]
         gc_ll_descr = self.gc_ll_descr
@@ -336,7 +336,7 @@
         finally:
             rgc.can_move = old_can_move
         assert len(operations) == 1
-        assert operations[0].opnum == rop.OOIS
+        assert operations[0].opnum == rop.PTR_EQ
         assert operations[0].args == [v_random_box, ConstPtr(s_gcref)]
         assert operations[0].result == v_result
         # check that s_gcref gets added to the list anyway, to make sure

Modified: pypy/branch/blackhole-improvement/pypy/rpython/lltypesystem/ll2ctypes.py
==============================================================================
--- pypy/branch/blackhole-improvement/pypy/rpython/lltypesystem/ll2ctypes.py	(original)
+++ pypy/branch/blackhole-improvement/pypy/rpython/lltypesystem/ll2ctypes.py	Fri May 28 20:46:50 2010
@@ -511,6 +511,10 @@
     """
     if isinstance(llobj, lltype._uninitialized):
         return uninitialized2ctypes(llobj.TYPE)
+    if isinstance(llobj, llmemory.AddressAsInt):
+        llobj = llobj.adr
+    if isinstance(llobj, llmemory.fakeaddress):
+        llobj = llobj.ptr or 0
 
     T = lltype.typeOf(llobj)
 
@@ -975,6 +979,8 @@
     """Cast a value to a result type, trying to use the same rules as C."""
     if not isinstance(RESTYPE, lltype.LowLevelType):
         raise TypeError("rffi.cast() first arg should be a TYPE")
+    if isinstance(value, llmemory.AddressAsInt):
+        value = value.adr
     if isinstance(value, llmemory.fakeaddress):
         value = value.ptr or 0
     TYPE1 = lltype.typeOf(value)



More information about the Pypy-commit mailing list