diff options
author | Stefan Behnel <stefan_ml@behnel.de> | 2019-02-08 16:07:07 +0100 |
---|---|---|
committer | Stefan Behnel <stefan_ml@behnel.de> | 2019-02-08 16:07:07 +0100 |
commit | 1ce9a633e3671f2339b4fc6202c52a5743abdcef (patch) | |
tree | 08f4f8412aa698021ace8de4665ee8a83be9ac3b | |
parent | 253c25a902aef2c54de31baa22af73d0dbad2a06 (diff) | |
download | cython-1ce9a633e3671f2339b4fc6202c52a5743abdcef.tar.gz |
Move dict version checking code into a separate utility code section since it's getting lengthy.
-rw-r--r-- | Cython/Compiler/Nodes.py | 2 | ||||
-rw-r--r-- | Cython/Utility/Exceptions.c | 1 | ||||
-rw-r--r-- | Cython/Utility/ModuleSetupCode.c | 47 | ||||
-rw-r--r-- | Cython/Utility/ObjectHandling.c | 57 |
4 files changed, 60 insertions, 47 deletions
diff --git a/Cython/Compiler/Nodes.py b/Cython/Compiler/Nodes.py index e880e6972..be4683e0d 100644 --- a/Cython/Compiler/Nodes.py +++ b/Cython/Compiler/Nodes.py @@ -4355,6 +4355,8 @@ class OverrideCheckNode(StatNode): self_arg, self_arg)) code.putln("#if CYTHON_USE_DICT_VERSIONS && CYTHON_USE_PYTYPE_LOOKUP") + code.globalstate.use_utility_code( + UtilityCode.load_cached("PyDictVersioning", "ObjectHandling.c")) # TODO: remove the object dict version check by 'inlining' the getattr implementation for methods. # This would allow checking the dict versions around _PyType_Lookup() if it returns a descriptor, # and would (tada!) make this check a pure type based thing instead of supporting only a single diff --git a/Cython/Utility/Exceptions.c b/Cython/Utility/Exceptions.c index 29a2ae4c7..df47424a7 100644 --- a/Cython/Utility/Exceptions.c +++ b/Cython/Utility/Exceptions.c @@ -642,6 +642,7 @@ static int __Pyx_CLineForTraceback(PyThreadState *tstate, int c_line);/*proto*/ /////////////// CLineInTraceback /////////////// //@requires: ObjectHandling.c::PyObjectGetAttrStr +//@requires: ObjectHandling.c::PyDictVersioning //@requires: PyErrFetchRestore //@substitute: naming diff --git a/Cython/Utility/ModuleSetupCode.c b/Cython/Utility/ModuleSetupCode.c index 540e1d6e6..72043ca4a 100644 --- a/Cython/Utility/ModuleSetupCode.c +++ b/Cython/Utility/ModuleSetupCode.c @@ -428,53 +428,6 @@ class __Pyx_FakeReference { #define __Pyx_PyFastCFunction_Check(func) 0 #endif -#if CYTHON_USE_DICT_VERSIONS - -#define __PYX_DICT_VERSION_INIT ((PY_UINT64_T) -1) -#define __PYX_GET_DICT_VERSION(dict) (((PyDictObject*)(dict))->ma_version_tag) -#define __PYX_UPDATE_DICT_CACHE(dict, value, cache_var, version_var) \ - (version_var) = __PYX_GET_DICT_VERSION(dict); \ - (cache_var) = (value); - -static CYTHON_INLINE PY_UINT64_T __Pyx_get_tp_dict_version(PyObject *obj) { - PyObject *dict = Py_TYPE(obj)->tp_dict; - return dict ? __PYX_GET_DICT_VERSION(dict) : 0; -} - -static CYTHON_INLINE PY_UINT64_T __Pyx_get_object_dict_version(PyObject *obj) { - PyObject **dictptr = NULL; - Py_ssize_t offset = Py_TYPE(obj)->tp_dictoffset; - if (offset) { - dictptr = (offset > 0) ? (PyObject **) ((char *)obj + offset) : _PyObject_GetDictPtr(obj); - } - return (dictptr && *dictptr) ? __PYX_GET_DICT_VERSION(*dictptr) : 0; -} - -#define __PYX_PY_DICT_LOOKUP_IF_MODIFIED(VAR, DICT, LOOKUP) { \ - static PY_UINT64_T __pyx_dict_version = 0; \ - static PyObject *__pyx_dict_cached_value = NULL; \ - if (likely(__PYX_GET_DICT_VERSION(DICT) == __pyx_dict_version)) { \ - (VAR) = __pyx_dict_cached_value; \ - } else { \ - (VAR) = __pyx_dict_cached_value = (LOOKUP); \ - __pyx_dict_version = __PYX_GET_DICT_VERSION(DICT); \ - } \ -} - -static CYTHON_INLINE int __Pyx_object_dict_version_matches(PyObject* obj, PY_UINT64_T tp_dict_version, PY_UINT64_T obj_dict_version) { - PyObject *dict = Py_TYPE(obj)->tp_dict; - if (!dict || tp_dict_version != __PYX_GET_DICT_VERSION(dict)) - return 0; - return obj_dict_version == __Pyx_get_object_dict_version(obj); -} - -#else -#define __PYX_GET_DICT_VERSION(dict) (0) -#define __PYX_UPDATE_DICT_CACHE(dict, value, cache_var, version_var) -#define __PYX_PY_DICT_LOOKUP_IF_MODIFIED(VAR, DICT, LOOKUP) (VAR) = (LOOKUP); -#endif -// endif: CYTHON_USE_DICT_VERSIONS - #if CYTHON_COMPILING_IN_PYPY && !defined(PyObject_Malloc) #define PyObject_Malloc(s) PyMem_Malloc(s) #define PyObject_Free(p) PyMem_Free(p) diff --git a/Cython/Utility/ObjectHandling.c b/Cython/Utility/ObjectHandling.c index a325d4570..d58fd42d4 100644 --- a/Cython/Utility/ObjectHandling.c +++ b/Cython/Utility/ObjectHandling.c @@ -1165,6 +1165,7 @@ static PyObject *__Pyx__GetNameInClass(PyObject *nmspace, PyObject *name) { /////////////// GetModuleGlobalName.proto /////////////// +//@requires: PyDictVersioning //@substitute: naming #if CYTHON_USE_DICT_VERSIONS @@ -2397,3 +2398,59 @@ static PyObject* __Pyx_PyNumber_InPlaceMatrixMultiply(PyObject* x, PyObject* y) #undef __Pyx_TryMatrixMethod #endif + + +/////////////// PyDictVersioning.proto /////////////// + +#if CYTHON_USE_DICT_VERSIONS +#define __PYX_DICT_VERSION_INIT ((PY_UINT64_T) -1) +#define __PYX_GET_DICT_VERSION(dict) (((PyDictObject*)(dict))->ma_version_tag) +#define __PYX_UPDATE_DICT_CACHE(dict, value, cache_var, version_var) \ + (version_var) = __PYX_GET_DICT_VERSION(dict); \ + (cache_var) = (value); + +#define __PYX_PY_DICT_LOOKUP_IF_MODIFIED(VAR, DICT, LOOKUP) { \ + static PY_UINT64_T __pyx_dict_version = 0; \ + static PyObject *__pyx_dict_cached_value = NULL; \ + if (likely(__PYX_GET_DICT_VERSION(DICT) == __pyx_dict_version)) { \ + (VAR) = __pyx_dict_cached_value; \ + } else { \ + (VAR) = __pyx_dict_cached_value = (LOOKUP); \ + __pyx_dict_version = __PYX_GET_DICT_VERSION(DICT); \ + } \ +} + +static CYTHON_INLINE PY_UINT64_T __Pyx_get_tp_dict_version(PyObject *obj); /*proto*/ +static CYTHON_INLINE PY_UINT64_T __Pyx_get_object_dict_version(PyObject *obj); /*proto*/ +static CYTHON_INLINE int __Pyx_object_dict_version_matches(PyObject* obj, PY_UINT64_T tp_dict_version, PY_UINT64_T obj_dict_version); /*proto*/ + +#else +#define __PYX_GET_DICT_VERSION(dict) (0) +#define __PYX_UPDATE_DICT_CACHE(dict, value, cache_var, version_var) +#define __PYX_PY_DICT_LOOKUP_IF_MODIFIED(VAR, DICT, LOOKUP) (VAR) = (LOOKUP); +#endif + +/////////////// PyDictVersioning /////////////// + +#if CYTHON_USE_DICT_VERSIONS +static CYTHON_INLINE PY_UINT64_T __Pyx_get_tp_dict_version(PyObject *obj) { + PyObject *dict = Py_TYPE(obj)->tp_dict; + return dict ? __PYX_GET_DICT_VERSION(dict) : 0; +} + +static CYTHON_INLINE PY_UINT64_T __Pyx_get_object_dict_version(PyObject *obj) { + PyObject **dictptr = NULL; + Py_ssize_t offset = Py_TYPE(obj)->tp_dictoffset; + if (offset) { + dictptr = (offset > 0) ? (PyObject **) ((char *)obj + offset) : _PyObject_GetDictPtr(obj); + } + return (dictptr && *dictptr) ? __PYX_GET_DICT_VERSION(*dictptr) : 0; +} + +static CYTHON_INLINE int __Pyx_object_dict_version_matches(PyObject* obj, PY_UINT64_T tp_dict_version, PY_UINT64_T obj_dict_version) { + PyObject *dict = Py_TYPE(obj)->tp_dict; + if (!dict || tp_dict_version != __PYX_GET_DICT_VERSION(dict)) + return 0; + return obj_dict_version == __Pyx_get_object_dict_version(obj); +} +#endif |