[pypy-commit] pypy reflex-support: more JIT friendly capi

wlav noreply at buildbot.pypy.org
Thu Aug 25 05:30:49 CEST 2011


Author: Wim Lavrijsen <WLavrijsen at lbl.gov>
Branch: reflex-support
Changeset: r46764:387ae26ca238
Date: 2011-08-24 20:36 -0700
http://bitbucket.org/pypy/pypy/changeset/387ae26ca238/

Log:	more JIT friendly capi

diff --git a/pypy/module/cppyy/capi/reflex_capi.py b/pypy/module/cppyy/capi/reflex_capi.py
--- a/pypy/module/cppyy/capi/reflex_capi.py
+++ b/pypy/module/cppyy/capi/reflex_capi.py
@@ -2,7 +2,7 @@
 
 from pypy.translator.tool.cbuild import ExternalCompilationInfo
 from pypy.rpython.lltypesystem import rffi, lltype
-from pypy.rlib import libffi
+from pypy.rlib import libffi, jit
 
 pkgpath = py.path.local(__file__).dirpath().join(os.pardir)
 srcpath = pkgpath.join("src")
@@ -76,17 +76,30 @@
     [C_TYPEHANDLE, rffi.INT], rffi.CCHARP,
     compilation_info=eci)
 
-c_is_subtype = rffi.llexternal(
+_c_is_subtype = rffi.llexternal(
     "cppyy_is_subtype",
     [C_TYPEHANDLE, C_TYPEHANDLE], rffi.INT,
     compilation_info=eci,
     elidable_function=True)
-c_base_offset = rffi.llexternal(
+
+ at jit.elidable_promote()
+def c_is_subtype(td, tb):
+    if td == tb:
+        return 1
+    return _c_is_subtype(td, tb)
+
+_c_base_offset = rffi.llexternal(
     "cppyy_base_offset",
     [C_TYPEHANDLE, C_TYPEHANDLE, C_OBJECT], rffi.SIZE_T,
     compilation_info=eci,
     elidable_function=True)
 
+ at jit.elidable_promote()
+def c_base_offset(td, tb, address):
+    if td == tb:
+        return 0
+    return _c_base_offset(td, tb, address)
+
 
 c_call_v = rffi.llexternal(
     "cppyy_call_v",
diff --git a/pypy/module/cppyy/interp_cppyy.py b/pypy/module/cppyy/interp_cppyy.py
--- a/pypy/module/cppyy/interp_cppyy.py
+++ b/pypy/module/cppyy/interp_cppyy.py
@@ -245,9 +245,8 @@
     def get_returntype(self):
         return self.space.wrap(self.functions[0].executor.name)
 
-    @jit.unroll_safe
-    def call(self, w_cppinstance, w_type, args_w):
-        cppinstance = self.space.interp_w(W_CPPInstance, w_cppinstance, can_be_None=True)
+    @jit.elidable_promote()
+    def _get_cppthis(self, cppinstance):
         if cppinstance is not None:
             cppinstance._nullcheck()
             offset = capi.c_base_offset(
@@ -255,6 +254,12 @@
             cppthis = _direct_ptradd(cppinstance.rawobject, offset)
         else:
             cppthis = NULL_VOIDP
+        return cppthis
+
+    @jit.unroll_safe
+    def call(self, w_cppinstance, w_type, args_w):
+        cppinstance = self.space.interp_w(W_CPPInstance, w_cppinstance, can_be_None=True)
+        cppthis = self._get_cppthis(cppinstance)
         assert lltype.typeOf(cppthis) == rffi.VOIDP
 
         space = self.space
diff --git a/pypy/module/cppyy/src/reflexcwrapper.cxx b/pypy/module/cppyy/src/reflexcwrapper.cxx
--- a/pypy/module/cppyy/src/reflexcwrapper.cxx
+++ b/pypy/module/cppyy/src/reflexcwrapper.cxx
@@ -55,14 +55,8 @@
         getbases.Invoke(&bases_holder);
 
         for (Bases_t::iterator ibase = bases->begin(); ibase != bases->end(); ++ibase) {
-            if (ibase->first.ToType() == tb) {
-                if (ibase->first.IsVirtual() && address != NULL) {
-                    Reflex::Object o(td, address);
-                    size_t offset = ibase->first.Offset(o.Address());
-                    return offset;
-                } else
-                    return ibase->first.Offset(address);
-            }
+            if (ibase->first.ToType() == tb)
+                return ibase->first.Offset(address);
         }
 
         // contrary to typical invoke()s, the result of the internal getbases function
diff --git a/pypy/module/cppyy/test/test_zjit.py b/pypy/module/cppyy/test/test_zjit.py
--- a/pypy/module/cppyy/test/test_zjit.py
+++ b/pypy/module/cppyy/test/test_zjit.py
@@ -147,10 +147,6 @@
             return 7
         f()
         space = FakeSpace()
-        # This test is not that constrained anymore, now that there are left-over
-        # calls (to opaque ptr add (above) and to capi offset (the latter could be
-        # eaten by the JIT, since it is elidable ... )), but it's the best that
-        # can be done for now.
         result = self.meta_interp(f, [], listops=True, backendopt=True, listcomp=True)
-        self.check_loops(call=2, call_release_gil=1)
+        self.check_loops(call=0, call_release_gil=1)
         self.check_loops(getarrayitem_gc_pure=0, everywhere=True)


More information about the pypy-commit mailing list