Issue #29049: Call _PyObject_GC_TRACK() lazily when calling Python function.
Calling function is up to 5% faster.
This commit is contained in:
parent
2585443b6f
commit
5a625d0aa6
|
@ -60,7 +60,11 @@ PyAPI_DATA(PyTypeObject) PyFrame_Type;
|
|||
#define PyFrame_Check(op) (Py_TYPE(op) == &PyFrame_Type)
|
||||
|
||||
PyAPI_FUNC(PyFrameObject *) PyFrame_New(PyThreadState *, PyCodeObject *,
|
||||
PyObject *, PyObject *);
|
||||
PyObject *, PyObject *);
|
||||
|
||||
/* only internal use */
|
||||
PyFrameObject* _PyFrame_New_NoTrack(PyThreadState *, PyCodeObject *,
|
||||
PyObject *, PyObject *);
|
||||
|
||||
|
||||
/* The rest of the interface is specific for frame objects */
|
||||
|
|
|
@ -10,6 +10,9 @@ What's New in Python 3.7.0 alpha 1?
|
|||
Core and Builtins
|
||||
-----------------
|
||||
|
||||
- Issue #29049: Call _PyObject_GC_TRACK() lazily when calling Python function.
|
||||
Calling function is up to 5% faster.
|
||||
|
||||
- Issue #28927: bytes.fromhex() and bytearray.fromhex() now ignore all ASCII
|
||||
whitespace, not only spaces. Patch by Robert Xiao.
|
||||
|
||||
|
|
|
@ -415,7 +415,9 @@ frame_dealloc(PyFrameObject *f)
|
|||
PyObject **p, **valuestack;
|
||||
PyCodeObject *co;
|
||||
|
||||
PyObject_GC_UnTrack(f);
|
||||
if (_PyObject_GC_IS_TRACKED(f))
|
||||
_PyObject_GC_UNTRACK(f);
|
||||
|
||||
Py_TRASHCAN_SAFE_BEGIN(f)
|
||||
/* Kill all local variables */
|
||||
valuestack = f->f_valuestack;
|
||||
|
@ -606,8 +608,8 @@ int _PyFrame_Init()
|
|||
}
|
||||
|
||||
PyFrameObject* _Py_HOT_FUNCTION
|
||||
PyFrame_New(PyThreadState *tstate, PyCodeObject *code, PyObject *globals,
|
||||
PyObject *locals)
|
||||
_PyFrame_New_NoTrack(PyThreadState *tstate, PyCodeObject *code,
|
||||
PyObject *globals, PyObject *locals)
|
||||
{
|
||||
PyFrameObject *back = tstate->frame;
|
||||
PyFrameObject *f;
|
||||
|
@ -727,10 +729,20 @@ PyFrame_New(PyThreadState *tstate, PyCodeObject *code, PyObject *globals,
|
|||
f->f_executing = 0;
|
||||
f->f_gen = NULL;
|
||||
|
||||
_PyObject_GC_TRACK(f);
|
||||
return f;
|
||||
}
|
||||
|
||||
PyFrameObject*
|
||||
PyFrame_New(PyThreadState *tstate, PyCodeObject *code,
|
||||
PyObject *globals, PyObject *locals)
|
||||
{
|
||||
PyFrameObject *f = _PyFrame_New_NoTrack(tstate, code, globals, locals);
|
||||
if (f)
|
||||
_PyObject_GC_TRACK(f);
|
||||
return f;
|
||||
}
|
||||
|
||||
|
||||
/* Block management */
|
||||
|
||||
void
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue