Kaydet (Commit) 5a625d0a authored tarafından INADA Naoki's avatar INADA Naoki

Issue #29049: Call _PyObject_GC_TRACK() lazily when calling Python function.

Calling function is up to 5% faster.
üst 2585443b
...@@ -60,7 +60,11 @@ PyAPI_DATA(PyTypeObject) PyFrame_Type; ...@@ -60,7 +60,11 @@ PyAPI_DATA(PyTypeObject) PyFrame_Type;
#define PyFrame_Check(op) (Py_TYPE(op) == &PyFrame_Type) #define PyFrame_Check(op) (Py_TYPE(op) == &PyFrame_Type)
PyAPI_FUNC(PyFrameObject *) PyFrame_New(PyThreadState *, PyCodeObject *, 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 */ /* The rest of the interface is specific for frame objects */
......
...@@ -10,6 +10,9 @@ What's New in Python 3.7.0 alpha 1? ...@@ -10,6 +10,9 @@ What's New in Python 3.7.0 alpha 1?
Core and Builtins 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 - Issue #28927: bytes.fromhex() and bytearray.fromhex() now ignore all ASCII
whitespace, not only spaces. Patch by Robert Xiao. whitespace, not only spaces. Patch by Robert Xiao.
......
...@@ -415,7 +415,9 @@ frame_dealloc(PyFrameObject *f) ...@@ -415,7 +415,9 @@ frame_dealloc(PyFrameObject *f)
PyObject **p, **valuestack; PyObject **p, **valuestack;
PyCodeObject *co; PyCodeObject *co;
PyObject_GC_UnTrack(f); if (_PyObject_GC_IS_TRACKED(f))
_PyObject_GC_UNTRACK(f);
Py_TRASHCAN_SAFE_BEGIN(f) Py_TRASHCAN_SAFE_BEGIN(f)
/* Kill all local variables */ /* Kill all local variables */
valuestack = f->f_valuestack; valuestack = f->f_valuestack;
...@@ -606,8 +608,8 @@ int _PyFrame_Init() ...@@ -606,8 +608,8 @@ int _PyFrame_Init()
} }
PyFrameObject* _Py_HOT_FUNCTION PyFrameObject* _Py_HOT_FUNCTION
PyFrame_New(PyThreadState *tstate, PyCodeObject *code, PyObject *globals, _PyFrame_New_NoTrack(PyThreadState *tstate, PyCodeObject *code,
PyObject *locals) PyObject *globals, PyObject *locals)
{ {
PyFrameObject *back = tstate->frame; PyFrameObject *back = tstate->frame;
PyFrameObject *f; PyFrameObject *f;
...@@ -727,10 +729,20 @@ PyFrame_New(PyThreadState *tstate, PyCodeObject *code, PyObject *globals, ...@@ -727,10 +729,20 @@ PyFrame_New(PyThreadState *tstate, PyCodeObject *code, PyObject *globals,
f->f_executing = 0; f->f_executing = 0;
f->f_gen = NULL; f->f_gen = NULL;
_PyObject_GC_TRACK(f);
return 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 */ /* Block management */
void void
......
...@@ -3931,7 +3931,7 @@ _PyEval_EvalCodeWithName(PyObject *_co, PyObject *globals, PyObject *locals, ...@@ -3931,7 +3931,7 @@ _PyEval_EvalCodeWithName(PyObject *_co, PyObject *globals, PyObject *locals,
/* Create the frame */ /* Create the frame */
tstate = PyThreadState_GET(); tstate = PyThreadState_GET();
assert(tstate != NULL); assert(tstate != NULL);
f = PyFrame_New(tstate, co, globals, locals); f = _PyFrame_New_NoTrack(tstate, co, globals, locals);
if (f == NULL) { if (f == NULL) {
return NULL; return NULL;
} }
...@@ -4176,9 +4176,15 @@ fail: /* Jump here from prelude on failure */ ...@@ -4176,9 +4176,15 @@ fail: /* Jump here from prelude on failure */
so recursion_depth must be boosted for the duration. so recursion_depth must be boosted for the duration.
*/ */
assert(tstate != NULL); assert(tstate != NULL);
++tstate->recursion_depth; if (Py_REFCNT(f) > 1) {
Py_DECREF(f); Py_DECREF(f);
--tstate->recursion_depth; _PyObject_GC_TRACK(f);
}
else {
++tstate->recursion_depth;
Py_DECREF(f);
--tstate->recursion_depth;
}
return retval; return retval;
} }
...@@ -4904,11 +4910,11 @@ _PyFunction_FastCall(PyCodeObject *co, PyObject **args, Py_ssize_t nargs, ...@@ -4904,11 +4910,11 @@ _PyFunction_FastCall(PyCodeObject *co, PyObject **args, Py_ssize_t nargs,
assert(globals != NULL); assert(globals != NULL);
/* XXX Perhaps we should create a specialized /* 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. take builtins without sanity checking them.
*/ */
assert(tstate != NULL); assert(tstate != NULL);
f = PyFrame_New(tstate, co, globals, NULL); f = _PyFrame_New_NoTrack(tstate, co, globals, NULL);
if (f == NULL) { if (f == NULL) {
return NULL; return NULL;
} }
...@@ -4921,10 +4927,15 @@ _PyFunction_FastCall(PyCodeObject *co, PyObject **args, Py_ssize_t nargs, ...@@ -4921,10 +4927,15 @@ _PyFunction_FastCall(PyCodeObject *co, PyObject **args, Py_ssize_t nargs,
} }
result = PyEval_EvalFrameEx(f,0); result = PyEval_EvalFrameEx(f,0);
++tstate->recursion_depth; if (Py_REFCNT(f) > 1) {
Py_DECREF(f); Py_DECREF(f);
--tstate->recursion_depth; _PyObject_GC_TRACK(f);
}
else {
++tstate->recursion_depth;
Py_DECREF(f);
--tstate->recursion_depth;
}
return result; return result;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment