Author: Armin Rigo <ar...@tunes.org>
Branch: 
Changeset: r80914:9bbd8daa83aa
Date: 2015-11-24 22:00 +0100
http://bitbucket.org/pypy/pypy/changeset/9bbd8daa83aa/

Log:    A fast-path for the JIT: in the common case, ffi.init_once() is
        known during tracing to have been done already, and turns into no
        code at all

diff --git a/pypy/module/_cffi_backend/ffi_obj.py 
b/pypy/module/_cffi_backend/ffi_obj.py
--- a/pypy/module/_cffi_backend/ffi_obj.py
+++ b/pypy/module/_cffi_backend/ffi_obj.py
@@ -50,6 +50,7 @@
 
     w_gc_wref_remove = None
     w_init_once_cache = None
+    jit_init_once_cache = None
 
     @jit.dont_look_inside
     def __init__(self, space, src_ctx):
@@ -589,11 +590,30 @@
     def descr_init_once(self, w_func, w_tag):
         """XXX document me"""
         #
-        # atomically get or create a new dict (no GIL release)
+        # first, a fast-path for the JIT which only works if the very
+        # same w_tag object is passed; then it turns into no code at all
+        try:
+            return self._init_once_elidable(w_tag)
+        except KeyError:
+            return self._init_once_slowpath(w_func, w_tag)
+
+    @jit.elidable
+    def _init_once_elidable(self, w_tag):
+        jit_cache = self.jit_init_once_cache
+        if jit_cache is not None:
+            return jit_cache[w_tag]
+        else:
+            raise KeyError
+
+    @jit.dont_look_inside
+    def _init_once_slowpath(self, w_func, w_tag):
         space = self.space
         w_cache = self.w_init_once_cache
         if w_cache is None:
-            w_cache = self.w_init_once_cache = space.newdict()
+            w_cache = self.space.newdict()
+            jit_cache = {}
+            self.w_init_once_cache = w_cache
+            self.jit_init_once_cache = jit_cache
         #
         # get the lock or result from cache[tag]
         w_res = space.finditem(w_cache, w_tag)
@@ -606,6 +626,7 @@
             w_res = space.finditem(w_cache, w_tag)
             if w_res is None or isinstance(w_res, W_InitOnceLock):
                 w_res = space.call_function(w_func)
+                self.jit_init_once_cache[w_tag] = w_res
                 space.setitem(w_cache, w_tag, w_res)
             else:
                 # the real result was put in the dict while we were
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to