summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Behnel <stefan_ml@behnel.de>2020-04-12 18:51:03 +0200
committerStefan Behnel <stefan_ml@behnel.de>2020-04-12 18:51:03 +0200
commit059e53c1d3b07b6f30b6fbc5e0db1164163f1c0a (patch)
tree33dc11203bcb7d9fa98c7771022b3af473d36a61
parent791605d25c6798c125ec213ac62ffd5360442912 (diff)
downloadcython-059e53c1d3b07b6f30b6fbc5e0db1164163f1c0a.tar.gz
Sprinkle lots of branch prediction hints in places where exceptions are being handled or otherwise exceptional cases occur.
-rw-r--r--Cython/Utility/AsyncGen.c4
-rw-r--r--Cython/Utility/Builtins.c16
-rw-r--r--Cython/Utility/Coroutine.c16
-rw-r--r--Cython/Utility/CythonFunction.c41
-rw-r--r--Cython/Utility/FunctionArguments.c2
5 files changed, 40 insertions, 39 deletions
diff --git a/Cython/Utility/AsyncGen.c b/Cython/Utility/AsyncGen.c
index 11b12e65d..f045f04ff 100644
--- a/Cython/Utility/AsyncGen.c
+++ b/Cython/Utility/AsyncGen.c
@@ -929,7 +929,7 @@ __Pyx_async_gen_athrow_send(__pyx_PyAsyncGenAThrow *o, PyObject *arg)
} else {
/* aclose() mode */
if (retval) {
- if (__pyx__PyAsyncGenWrappedValue_CheckExact(retval)) {
+ if (unlikely(__pyx__PyAsyncGenWrappedValue_CheckExact(retval))) {
Py_DECREF(retval);
goto yield_close;
}
@@ -983,7 +983,7 @@ __Pyx_async_gen_athrow_throw(__pyx_PyAsyncGenAThrow *o, PyObject *args)
} else {
// aclose() mode
PyObject *exc_type;
- if (retval && __pyx__PyAsyncGenWrappedValue_CheckExact(retval)) {
+ if (unlikely(retval && __pyx__PyAsyncGenWrappedValue_CheckExact(retval))) {
o->agt_gen->ag_running_async = 0;
o->agt_state = __PYX_AWAITABLE_STATE_CLOSED;
Py_DECREF(retval);
diff --git a/Cython/Utility/Builtins.c b/Cython/Utility/Builtins.c
index df5b0d86f..a8e8f0a08 100644
--- a/Cython/Utility/Builtins.c
+++ b/Cython/Utility/Builtins.c
@@ -68,7 +68,7 @@ static PyObject* __Pyx_PyExec3(PyObject* o, PyObject* globals, PyObject* locals)
if (!globals || globals == Py_None) {
globals = $moddict_cname;
- } else if (!PyDict_Check(globals)) {
+ } else if (unlikely(!PyDict_Check(globals))) {
PyErr_Format(PyExc_TypeError, "exec() arg 2 must be a dict, not %.200s",
Py_TYPE(globals)->tp_name);
goto bad;
@@ -78,12 +78,12 @@ static PyObject* __Pyx_PyExec3(PyObject* o, PyObject* globals, PyObject* locals)
}
if (__Pyx_PyDict_GetItemStr(globals, PYIDENT("__builtins__")) == NULL) {
- if (PyDict_SetItem(globals, PYIDENT("__builtins__"), PyEval_GetBuiltins()) < 0)
+ if (unlikely(PyDict_SetItem(globals, PYIDENT("__builtins__"), PyEval_GetBuiltins()) < 0))
goto bad;
}
if (PyCode_Check(o)) {
- if (__Pyx_PyCode_HasFreeVars((PyCodeObject *)o)) {
+ if (unlikely(__Pyx_PyCode_HasFreeVars((PyCodeObject *)o))) {
PyErr_SetString(PyExc_TypeError,
"code object passed to exec() may not contain free variables");
goto bad;
@@ -99,12 +99,12 @@ static PyObject* __Pyx_PyExec3(PyObject* o, PyObject* globals, PyObject* locals)
if (PyUnicode_Check(o)) {
cf.cf_flags = PyCF_SOURCE_IS_UTF8;
s = PyUnicode_AsUTF8String(o);
- if (!s) goto bad;
+ if (unlikely(!s)) goto bad;
o = s;
#if PY_MAJOR_VERSION >= 3
- } else if (!PyBytes_Check(o)) {
+ } else if (unlikely(!PyBytes_Check(o))) {
#else
- } else if (!PyString_Check(o)) {
+ } else if (unlikely(!PyString_Check(o))) {
#endif
PyErr_Format(PyExc_TypeError,
"exec: arg 1 must be string, bytes or code object, got %.200s",
@@ -180,7 +180,7 @@ static CYTHON_INLINE int __Pyx_HasAttr(PyObject *o, PyObject *n) {
return -1;
}
r = __Pyx_GetAttr(o, n);
- if (unlikely(!r)) {
+ if (!r) {
PyErr_Clear();
return 0;
} else {
@@ -196,7 +196,7 @@ static PyObject* __Pyx_Intern(PyObject* s); /* proto */
//////////////////// Intern ////////////////////
static PyObject* __Pyx_Intern(PyObject* s) {
- if (!(likely(PyString_CheckExact(s)))) {
+ if (unlikely(!PyString_CheckExact(s))) {
PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "str", Py_TYPE(s)->tp_name);
return 0;
}
diff --git a/Cython/Utility/Coroutine.c b/Cython/Utility/Coroutine.c
index add9455f6..f3283497d 100644
--- a/Cython/Utility/Coroutine.c
+++ b/Cython/Utility/Coroutine.c
@@ -522,7 +522,7 @@ static int __Pyx_PyGen__FetchStopIterationValue(CYTHON_UNUSED PyThreadState *$lo
value = Py_None;
}
#if PY_VERSION_HEX >= 0x030300A0
- else if (__Pyx_IS_TYPE(ev, (PyTypeObject*)PyExc_StopIteration)) {
+ else if (likely(__Pyx_IS_TYPE(ev, (PyTypeObject*)PyExc_StopIteration))) {
value = ((PyStopIterationObject *)ev)->value;
Py_INCREF(value);
Py_DECREF(ev);
@@ -905,7 +905,7 @@ static int __Pyx_Coroutine_CloseIter(__pyx_CoroutineObject *gen, PyObject *yf) {
} else {
retval = PyObject_CallFunction(meth, NULL);
Py_DECREF(meth);
- if (!retval)
+ if (unlikely(!retval))
err = -1;
}
gen->is_running = 0;
@@ -1079,7 +1079,7 @@ static PyObject *__Pyx_Coroutine_Throw(PyObject *self, PyObject *args) {
PyObject *val = NULL;
PyObject *tb = NULL;
- if (!PyArg_UnpackTuple(args, (char *)"throw", 1, 3, &typ, &val, &tb))
+ if (unlikely(!PyArg_UnpackTuple(args, (char *)"throw", 1, 3, &typ, &val, &tb)))
return NULL;
return __Pyx__Coroutine_Throw(self, typ, val, tb, args, 1);
@@ -1130,10 +1130,10 @@ static void __Pyx_Coroutine_dealloc(PyObject *self) {
// Generator is paused or unstarted, so we need to close
PyObject_GC_Track(self);
#if PY_VERSION_HEX >= 0x030400a1 && CYTHON_USE_TP_FINALIZE
- if (PyObject_CallFinalizerFromDealloc(self))
+ if (unlikely(PyObject_CallFinalizerFromDealloc(self)))
#else
Py_TYPE(gen)->tp_del(self);
- if (self->ob_refcnt > 0)
+ if (unlikely(self->ob_refcnt > 0))
#endif
{
// resurrected. :(
@@ -1249,7 +1249,7 @@ static void __Pyx_Coroutine_del(PyObject *self) {
// Undo the temporary resurrection; can't use DECREF here, it would
// cause a recursive call.
assert(self->ob_refcnt > 0);
- if (--self->ob_refcnt == 0) {
+ if (likely(--self->ob_refcnt == 0)) {
// this is the normal path out
return;
}
@@ -2061,7 +2061,7 @@ static int __Pyx_patch_abc(void) {
if (CYTHON_REGISTER_ABCS && !abc_patched) {
PyObject *module;
module = PyImport_ImportModule((PY_MAJOR_VERSION >= 3) ? "collections.abc" : "collections");
- if (!module) {
+ if (unlikely(!module)) {
PyErr_WriteUnraisable(NULL);
if (unlikely(PyErr_WarnEx(PyExc_RuntimeWarning,
((PY_MAJOR_VERSION >= 3) ?
@@ -2319,7 +2319,7 @@ static int __pyx_StopAsyncIteration_init(void) {
__Pyx_PyExc_StopAsyncIteration = (PyObject*) __Pyx_FetchCommonType(&__Pyx__PyExc_StopAsyncIteration_type);
if (unlikely(!__Pyx_PyExc_StopAsyncIteration))
return -1;
- if (builtins && unlikely(PyMapping_SetItemString(builtins, (char*) "StopAsyncIteration", __Pyx_PyExc_StopAsyncIteration) < 0))
+ if (likely(builtins) && unlikely(PyMapping_SetItemString(builtins, (char*) "StopAsyncIteration", __Pyx_PyExc_StopAsyncIteration) < 0))
return -1;
#endif
return 0;
diff --git a/Cython/Utility/CythonFunction.c b/Cython/Utility/CythonFunction.c
index 0a6bfd9cf..76cd682f6 100644
--- a/Cython/Utility/CythonFunction.c
+++ b/Cython/Utility/CythonFunction.c
@@ -279,7 +279,7 @@ __Pyx_CyFunction_set_defaults(__pyx_CyFunctionObject *op, PyObject* value, CYTHO
if (!value) {
// del => explicit None to prevent rebuilding
value = Py_None;
- } else if (value != Py_None && !PyTuple_Check(value)) {
+ } else if (unlikely(value != Py_None && !PyTuple_Check(value))) {
PyErr_SetString(PyExc_TypeError,
"__defaults__ must be set to a tuple object");
return -1;
@@ -294,7 +294,7 @@ __Pyx_CyFunction_get_defaults(__pyx_CyFunctionObject *op, CYTHON_UNUSED void *co
PyObject* result = op->defaults_tuple;
if (unlikely(!result)) {
if (op->defaults_getter) {
- if (__Pyx_CyFunction_init_defaults(op) < 0) return NULL;
+ if (unlikely(__Pyx_CyFunction_init_defaults(op) < 0)) return NULL;
result = op->defaults_tuple;
} else {
result = Py_None;
@@ -309,7 +309,7 @@ __Pyx_CyFunction_set_kwdefaults(__pyx_CyFunctionObject *op, PyObject* value, CYT
if (!value) {
// del => explicit None to prevent rebuilding
value = Py_None;
- } else if (value != Py_None && !PyDict_Check(value)) {
+ } else if (unlikely(value != Py_None && !PyDict_Check(value))) {
PyErr_SetString(PyExc_TypeError,
"__kwdefaults__ must be set to a dict object");
return -1;
@@ -324,7 +324,7 @@ __Pyx_CyFunction_get_kwdefaults(__pyx_CyFunctionObject *op, CYTHON_UNUSED void *
PyObject* result = op->defaults_kwdict;
if (unlikely(!result)) {
if (op->defaults_getter) {
- if (__Pyx_CyFunction_init_defaults(op) < 0) return NULL;
+ if (unlikely(__Pyx_CyFunction_init_defaults(op) < 0)) return NULL;
result = op->defaults_kwdict;
} else {
result = Py_None;
@@ -338,7 +338,7 @@ static int
__Pyx_CyFunction_set_annotations(__pyx_CyFunctionObject *op, PyObject* value, CYTHON_UNUSED void *context) {
if (!value || value == Py_None) {
value = NULL;
- } else if (!PyDict_Check(value)) {
+ } else if (unlikely(!PyDict_Check(value))) {
PyErr_SetString(PyExc_TypeError,
"__annotations__ must be set to a dict object");
return -1;
@@ -696,7 +696,7 @@ static CYTHON_INLINE int __Pyx_CyFunction_Vectorcall_CheckArgs(__pyx_CyFunctionO
}
ret = 1;
}
- if (unlikely(kwnames) && PyTuple_GET_SIZE(kwnames)) {
+ if (unlikely(kwnames) && unlikely(PyTuple_GET_SIZE(kwnames))) {
PyErr_Format(PyExc_TypeError,
"%.200s() takes no keyword arguments", cyfunc->func.m_ml->ml_name);
return -1;
@@ -1090,7 +1090,7 @@ __pyx_FusedFunction_descr_get(PyObject *self, PyObject *obj, PyObject *type)
((PyCFunctionObject *) func)->m_module,
((__pyx_CyFunctionObject *) func)->func_globals,
((__pyx_CyFunctionObject *) func)->func_code);
- if (!meth)
+ if (unlikely(!meth))
return NULL;
// defaults needs copying fully rather than just copying the pointer
@@ -1100,9 +1100,10 @@ __pyx_FusedFunction_descr_get(PyObject *self, PyObject *obj, PyObject *type)
PyObject **pydefaults;
int i;
- if (!__Pyx_CyFunction_InitDefaults((PyObject*)meth,
- func->func.defaults_size,
- func->func.defaults_pyobjects)) {
+ if (unlikely(!__Pyx_CyFunction_InitDefaults(
+ (PyObject*)meth,
+ func->func.defaults_size,
+ func->func.defaults_pyobjects))) {
Py_XDECREF((PyObject*)meth);
return NULL;
}
@@ -1147,7 +1148,7 @@ __pyx_FusedFunction_getitem(__pyx_FusedFunctionObject *self, PyObject *idx)
PyObject *unbound_result_func;
PyObject *result_func = NULL;
- if (self->__signatures__ == NULL) {
+ if (unlikely(self->__signatures__ == NULL)) {
PyErr_SetString(PyExc_TypeError, "Function is not fused");
return NULL;
}
@@ -1159,7 +1160,7 @@ __pyx_FusedFunction_getitem(__pyx_FusedFunctionObject *self, PyObject *idx)
PyObject *sep = NULL;
int i;
- if (!list)
+ if (unlikely(!list))
return NULL;
for (i = 0; i < n; i++) {
@@ -1172,14 +1173,14 @@ __pyx_FusedFunction_getitem(__pyx_FusedFunctionObject *self, PyObject *idx)
#if !(CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS)
Py_DECREF(item);
#endif
- if (!string || PyList_Append(list, string) < 0)
+ if (unlikely(!string) || unlikely(PyList_Append(list, string) < 0))
goto __pyx_err;
Py_DECREF(string);
}
sep = PyUnicode_FromString("|");
- if (sep)
+ if (likely(sep))
signature = PyUnicode_Join(sep, list);
__pyx_err:
;
@@ -1189,12 +1190,12 @@ __pyx_err:
signature = _obj_to_str(idx);
}
- if (!signature)
+ if (unlikely(!signature))
return NULL;
unbound_result_func = PyObject_GetItem(self->__signatures__, signature);
- if (unbound_result_func) {
+ if (likely(unbound_result_func)) {
if (self->self) {
__pyx_FusedFunctionObject *unbound = (__pyx_FusedFunctionObject *) unbound_result_func;
@@ -1251,7 +1252,7 @@ __pyx_FusedFunction_call(PyObject *func, PyObject *args, PyObject *kw)
PyObject *self;
Py_ssize_t i;
new_args = PyTuple_New(argc + 1);
- if (!new_args)
+ if (unlikely(!new_args))
return NULL;
self = binding_func->self;
@@ -1426,7 +1427,7 @@ static int __pyx_FusedFunction_init(void) {
__pyx_FusedFunctionType_type.tp_base = __pyx_CyFunctionType;
__pyx_FusedFunctionType = __Pyx_FetchCommonType(&__pyx_FusedFunctionType_type);
#endif
- if (__pyx_FusedFunctionType == NULL) {
+ if (unlikely(__pyx_FusedFunctionType == NULL)) {
return -1;
}
return 0;
@@ -1452,9 +1453,9 @@ static PyObject* __Pyx_Method_ClassMethod(PyObject *method) {
#else
// It appears that PyMethodDescr_Type is not exposed anywhere in the CPython C-API
static PyTypeObject *methoddescr_type = NULL;
- if (methoddescr_type == NULL) {
+ if (unlikely(methoddescr_type == NULL)) {
PyObject *meth = PyObject_GetAttrString((PyObject*)&PyList_Type, "append");
- if (!meth) return NULL;
+ if (unlikely(!meth)) return NULL;
methoddescr_type = Py_TYPE(meth);
Py_DECREF(meth);
}
diff --git a/Cython/Utility/FunctionArguments.c b/Cython/Utility/FunctionArguments.c
index 112ab89b6..77a1756e9 100644
--- a/Cython/Utility/FunctionArguments.c
+++ b/Cython/Utility/FunctionArguments.c
@@ -355,7 +355,7 @@ static int __Pyx_MergeKeywords(PyObject *kwdict, PyObject *source_mapping) {
if (unlikely(!iter)) {
// slow fallback: try converting to dict, then iterate
PyObject *args;
- if (!PyErr_ExceptionMatches(PyExc_AttributeError)) goto bad;
+ if (unlikely(!PyErr_ExceptionMatches(PyExc_AttributeError))) goto bad;
PyErr_Clear();
args = PyTuple_Pack(1, source_mapping);
if (likely(args)) {