Calling function is up to 5% faster.
#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 */
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.
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;
}
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;
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
/* 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;
}
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;
}
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;
}
}
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;
}