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