summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Bradshaw <robertwb@gmail.com>2021-04-10 00:55:50 -0700
committerRobert Bradshaw <robertwb@gmail.com>2021-04-10 00:55:50 -0700
commitb68f2585ceec37e0be245122a0fb6328f5145e8d (patch)
tree760767afe00b5f01aa7fc119f894ac4960fb203c
parente9aa3db7ba616316319bd31d591be1b715fd8c5a (diff)
downloadcython-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.c29
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