diff options
author | Robert Bradshaw <robertwb@gmail.com> | 2021-04-10 00:55:50 -0700 |
---|---|---|
committer | Robert Bradshaw <robertwb@gmail.com> | 2021-04-10 00:55:50 -0700 |
commit | b68f2585ceec37e0be245122a0fb6328f5145e8d (patch) | |
tree | 760767afe00b5f01aa7fc119f894ac4960fb203c | |
parent | e9aa3db7ba616316319bd31d591be1b715fd8c5a (diff) | |
download | cython-b68f2585ceec37e0be245122a0fb6328f5145e8d.tar.gz |
Efficiency improvements for enabling/disabling gc in __Pyx_PyType_Ready().
These are more important in light of it being used ubiquitously.
-rw-r--r-- | Cython/Utility/ExtensionTypes.c | 29 |
1 files changed, 20 insertions, 9 deletions
diff --git a/Cython/Utility/ExtensionTypes.c b/Cython/Utility/ExtensionTypes.c index d8b8353cb..26bc2d9d9 100644 --- a/Cython/Utility/ExtensionTypes.c +++ b/Cython/Utility/ExtensionTypes.c @@ -3,6 +3,7 @@ static int __Pyx_PyType_Ready(PyTypeObject *t); /////////////// PyType_Ready /////////////// +//@requires: ObjectHandling.c::PyObjectCallNoArg // Wrapper around PyType_Ready() with some runtime checks and fixes // to deal with multiple inheritance. @@ -67,24 +68,35 @@ static int __Pyx_PyType_Ready(PyTypeObject *t) { // For details, see https://github.com/cython/cython/issues/3603 PyObject *ret, *py_status; int gc_was_enabled; - PyObject *gc = PyImport_Import(PYUNICODE("gc")); - if (unlikely(!gc)) return -1; - py_status = PyObject_CallMethodObjArgs(gc, PYUNICODE("isenabled"), NULL); + static PyObject *gc = NULL; + static PyObject *gc_isenabled = NULL, *gc_enable = NULL, *gc_disable = NULL; + if (unlikely(!gc)) { + gc = PyImport_Import(PYUNICODE("gc")); + if (unlikely(!gc)) return -1; + gc_isenabled = PyObject_GetAttr(gc, PYUNICODE("isenabled")); + gc_enable = PyObject_GetAttr(gc, PYUNICODE("enable")); + gc_disable = PyObject_GetAttr(gc, PYUNICODE("disable")); + if (unlikely(!gc_isenabled || !gc_enable || !gc_disable)) { + Py_XDECREF(gc_isenabled); gc_isenabled = NULL; + Py_XDECREF(gc_enable); gc_enable = NULL; + Py_XDECREF(gc_disable); gc_disable = NULL; + Py_XDECREF(gc); gc = NULL; + return -1; + } + } + py_status = __Pyx_PyObject_CallNoArg(gc_isenabled); if (unlikely(!py_status)) { - Py_DECREF(gc); return -1; } gc_was_enabled = __Pyx_PyObject_IsTrue(py_status); Py_DECREF(py_status); if (gc_was_enabled > 0) { - ret = PyObject_CallMethodObjArgs(gc, PYUNICODE("disable"), NULL); + ret = __Pyx_PyObject_CallNoArg(gc_disable); if (unlikely(!ret)) { - Py_DECREF(gc); return -1; } Py_DECREF(ret); } else if (unlikely(gc_was_enabled == -1)) { - Py_DECREF(gc); return -1; } @@ -106,7 +118,7 @@ static int __Pyx_PyType_Ready(PyTypeObject *t) { if (gc_was_enabled) { PyObject *t, *v, *tb; PyErr_Fetch(&t, &v, &tb); - ret = PyObject_CallMethodObjArgs(gc, PYUNICODE("enable"), NULL); + ret = __Pyx_PyObject_CallNoArg(gc_enable); if (likely(ret || r == -1)) { Py_XDECREF(ret); // do not overwrite exceptions raised by PyType_Ready() above @@ -119,7 +131,6 @@ static int __Pyx_PyType_Ready(PyTypeObject *t) { r = -1; } } - Py_DECREF(gc); } #endif |