summaryrefslogtreecommitdiffstats
path: root/Python/ceval.c
diff options
context:
space:
mode:
authorINADA Naoki <songofacandy@gmail.com>2016-12-24 11:19:08 (GMT)
committerINADA Naoki <songofacandy@gmail.com>2016-12-24 11:19:08 (GMT)
commit5a625d0aa6a6d9ec6574ee8344b41d63dcb9897e (patch)
tree10b9bb211b5cfdd80e1f42757f2773acd3d7f3cd /Python/ceval.c
parent2585443b6fc83dade775d2c18bfc2fd70dfde369 (diff)
downloadcpython-5a625d0aa6a6d9ec6574ee8344b41d63dcb9897e.zip
cpython-5a625d0aa6a6d9ec6574ee8344b41d63dcb9897e.tar.gz
cpython-5a625d0aa6a6d9ec6574ee8344b41d63dcb9897e.tar.bz2
Issue #29049: Call _PyObject_GC_TRACK() lazily when calling Python function.
Calling function is up to 5% faster.
Diffstat (limited to 'Python/ceval.c')
-rw-r--r--Python/ceval.c31
1 files changed, 21 insertions, 10 deletions
diff --git a/Python/ceval.c b/Python/ceval.c
index f7ee041..e48586d 100644
--- a/Python/ceval.c
+++ b/Python/ceval.c
@@ -3931,7 +3931,7 @@ _PyEval_EvalCodeWithName(PyObject *_co, PyObject *globals, PyObject *locals,
/* Create the frame */
tstate = PyThreadState_GET();
assert(tstate != NULL);
- f = PyFrame_New(tstate, co, globals, locals);
+ f = _PyFrame_New_NoTrack(tstate, co, globals, locals);
if (f == NULL) {
return NULL;
}
@@ -4176,9 +4176,15 @@ fail: /* Jump here from prelude on failure */
so recursion_depth must be boosted for the duration.
*/
assert(tstate != NULL);
- ++tstate->recursion_depth;
- Py_DECREF(f);
- --tstate->recursion_depth;
+ if (Py_REFCNT(f) > 1) {
+ Py_DECREF(f);
+ _PyObject_GC_TRACK(f);
+ }
+ else {
+ ++tstate->recursion_depth;
+ Py_DECREF(f);
+ --tstate->recursion_depth;
+ }
return retval;
}
@@ -4904,11 +4910,11 @@ _PyFunction_FastCall(PyCodeObject *co, PyObject **args, Py_ssize_t nargs,
assert(globals != NULL);
/* XXX Perhaps we should create a specialized
- PyFrame_New() that doesn't take locals, but does
+ _PyFrame_New_NoTrack() that doesn't take locals, but does
take builtins without sanity checking them.
*/
assert(tstate != NULL);
- f = PyFrame_New(tstate, co, globals, NULL);
+ f = _PyFrame_New_NoTrack(tstate, co, globals, NULL);
if (f == NULL) {
return NULL;
}
@@ -4921,10 +4927,15 @@ _PyFunction_FastCall(PyCodeObject *co, PyObject **args, Py_ssize_t nargs,
}
result = PyEval_EvalFrameEx(f,0);
- ++tstate->recursion_depth;
- Py_DECREF(f);
- --tstate->recursion_depth;
-
+ if (Py_REFCNT(f) > 1) {
+ Py_DECREF(f);
+ _PyObject_GC_TRACK(f);
+ }
+ else {
+ ++tstate->recursion_depth;
+ Py_DECREF(f);
+ --tstate->recursion_depth;
+ }
return result;
}