mirror of
https://github.com/python/cpython.git
synced 2025-08-31 05:58:33 +00:00
gh-118926: Spill deferred references to stack in cases generator (#122748)
This automatically spills the results from `_PyStackRef_FromPyObjectNew` to the in-memory stack so that the deferred references are visible to the GC before we make any possibly escaping call. Co-authored-by: Ken Jin <kenjin@python.org>
This commit is contained in:
parent
967a4f1d18
commit
3e753c689a
9 changed files with 176 additions and 63 deletions
|
@ -1424,7 +1424,7 @@ dummy_func(
|
|||
"no locals found");
|
||||
ERROR_IF(true, error);
|
||||
}
|
||||
locals = PyStackRef_FromPyObjectNew(l);;
|
||||
locals = PyStackRef_FromPyObjectNew(l);
|
||||
}
|
||||
|
||||
inst(LOAD_FROM_DICT_OR_GLOBALS, (mod_or_class_dict -- v)) {
|
||||
|
|
38
Python/executor_cases.c.h
generated
38
Python/executor_cases.c.h
generated
|
@ -1469,10 +1469,10 @@
|
|||
}
|
||||
STAT_INC(UNPACK_SEQUENCE, hit);
|
||||
val0 = PyStackRef_FromPyObjectNew(PyTuple_GET_ITEM(seq_o, 0));
|
||||
val1 = PyStackRef_FromPyObjectNew(PyTuple_GET_ITEM(seq_o, 1));
|
||||
PyStackRef_CLOSE(seq);
|
||||
stack_pointer[-1] = val1;
|
||||
stack_pointer[0] = val0;
|
||||
val1 = PyStackRef_FromPyObjectNew(PyTuple_GET_ITEM(seq_o, 1));
|
||||
stack_pointer[-1] = val1;
|
||||
PyStackRef_CLOSE(seq);
|
||||
stack_pointer += 1;
|
||||
assert(WITHIN_STACK_BOUNDS());
|
||||
break;
|
||||
|
@ -1612,7 +1612,7 @@
|
|||
"no locals found");
|
||||
if (true) JUMP_TO_ERROR();
|
||||
}
|
||||
locals = PyStackRef_FromPyObjectNew(l);;
|
||||
locals = PyStackRef_FromPyObjectNew(l);
|
||||
stack_pointer[0] = locals;
|
||||
stack_pointer += 1;
|
||||
assert(WITHIN_STACK_BOUNDS());
|
||||
|
@ -2422,8 +2422,8 @@
|
|||
STAT_INC(LOAD_ATTR, hit);
|
||||
null = PyStackRef_NULL;
|
||||
attr = PyStackRef_FromPyObjectNew(attr_o);
|
||||
PyStackRef_CLOSE(owner);
|
||||
stack_pointer[-1] = attr;
|
||||
PyStackRef_CLOSE(owner);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -2444,8 +2444,8 @@
|
|||
STAT_INC(LOAD_ATTR, hit);
|
||||
null = PyStackRef_NULL;
|
||||
attr = PyStackRef_FromPyObjectNew(attr_o);
|
||||
PyStackRef_CLOSE(owner);
|
||||
stack_pointer[-1] = attr;
|
||||
PyStackRef_CLOSE(owner);
|
||||
stack_pointer[0] = null;
|
||||
stack_pointer += 1;
|
||||
assert(WITHIN_STACK_BOUNDS());
|
||||
|
@ -2481,9 +2481,9 @@
|
|||
STAT_INC(LOAD_ATTR, hit);
|
||||
assert(descr != NULL);
|
||||
attr = PyStackRef_FromPyObjectNew(descr);
|
||||
stack_pointer[-1] = attr;
|
||||
null = PyStackRef_NULL;
|
||||
PyStackRef_CLOSE(owner);
|
||||
stack_pointer[-1] = attr;
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -2497,9 +2497,9 @@
|
|||
STAT_INC(LOAD_ATTR, hit);
|
||||
assert(descr != NULL);
|
||||
attr = PyStackRef_FromPyObjectNew(descr);
|
||||
stack_pointer[-1] = attr;
|
||||
null = PyStackRef_NULL;
|
||||
PyStackRef_CLOSE(owner);
|
||||
stack_pointer[-1] = attr;
|
||||
stack_pointer[0] = null;
|
||||
stack_pointer += 1;
|
||||
assert(WITHIN_STACK_BOUNDS());
|
||||
|
@ -3437,8 +3437,8 @@
|
|||
assert(descr != NULL);
|
||||
assert(_PyType_HasFeature(Py_TYPE(descr), Py_TPFLAGS_METHOD_DESCRIPTOR));
|
||||
attr = PyStackRef_FromPyObjectNew(descr);
|
||||
self = owner;
|
||||
stack_pointer[-1] = attr;
|
||||
self = owner;
|
||||
stack_pointer[0] = self;
|
||||
stack_pointer += 1;
|
||||
assert(WITHIN_STACK_BOUNDS());
|
||||
|
@ -3458,8 +3458,8 @@
|
|||
assert(descr != NULL);
|
||||
assert(_PyType_HasFeature(Py_TYPE(descr), Py_TPFLAGS_METHOD_DESCRIPTOR));
|
||||
attr = PyStackRef_FromPyObjectNew(descr);
|
||||
self = owner;
|
||||
stack_pointer[-1] = attr;
|
||||
self = owner;
|
||||
stack_pointer[0] = self;
|
||||
stack_pointer += 1;
|
||||
assert(WITHIN_STACK_BOUNDS());
|
||||
|
@ -3523,8 +3523,8 @@
|
|||
assert(descr != NULL);
|
||||
assert(_PyType_HasFeature(Py_TYPE(descr), Py_TPFLAGS_METHOD_DESCRIPTOR));
|
||||
attr = PyStackRef_FromPyObjectNew(descr);
|
||||
self = owner;
|
||||
stack_pointer[-1] = attr;
|
||||
self = owner;
|
||||
stack_pointer[0] = self;
|
||||
stack_pointer += 1;
|
||||
assert(WITHIN_STACK_BOUNDS());
|
||||
|
@ -3546,8 +3546,10 @@
|
|||
PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable);
|
||||
PyObject *self = ((PyMethodObject *)callable_o)->im_self;
|
||||
maybe_self = PyStackRef_FromPyObjectNew(self);
|
||||
stack_pointer[-1 - oparg] = maybe_self;
|
||||
PyObject *method = ((PyMethodObject *)callable_o)->im_func;
|
||||
func = PyStackRef_FromPyObjectNew(method);
|
||||
stack_pointer[-2 - oparg] = func;
|
||||
/* Make sure that callable and all args are in memory */
|
||||
args[-2] = func;
|
||||
args[-1] = maybe_self;
|
||||
|
@ -3557,8 +3559,6 @@
|
|||
func = callable;
|
||||
maybe_self = self_or_null;
|
||||
}
|
||||
stack_pointer[-2 - oparg] = func;
|
||||
stack_pointer[-1 - oparg] = maybe_self;
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -3666,11 +3666,11 @@
|
|||
assert(PyStackRef_IsNull(null));
|
||||
assert(Py_TYPE(callable_o) == &PyMethod_Type);
|
||||
self = PyStackRef_FromPyObjectNew(((PyMethodObject *)callable_o)->im_self);
|
||||
stack_pointer[-1 - oparg] = self;
|
||||
method = PyStackRef_FromPyObjectNew(((PyMethodObject *)callable_o)->im_func);
|
||||
stack_pointer[-2 - oparg] = method;
|
||||
assert(PyStackRef_FunctionCheck(method));
|
||||
PyStackRef_CLOSE(callable);
|
||||
stack_pointer[-2 - oparg] = method;
|
||||
stack_pointer[-1 - oparg] = self;
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -3763,10 +3763,10 @@
|
|||
PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable);
|
||||
STAT_INC(CALL, hit);
|
||||
self = PyStackRef_FromPyObjectNew(((PyMethodObject *)callable_o)->im_self);
|
||||
func = PyStackRef_FromPyObjectNew(((PyMethodObject *)callable_o)->im_func);
|
||||
PyStackRef_CLOSE(callable);
|
||||
stack_pointer[-2 - oparg] = func;
|
||||
stack_pointer[-1 - oparg] = self;
|
||||
func = PyStackRef_FromPyObjectNew(((PyMethodObject *)callable_o)->im_func);
|
||||
stack_pointer[-2 - oparg] = func;
|
||||
PyStackRef_CLOSE(callable);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -5088,8 +5088,8 @@
|
|||
_PyStackRef null;
|
||||
PyObject *ptr = (PyObject *)CURRENT_OPERAND();
|
||||
value = PyStackRef_FromPyObjectNew(ptr);
|
||||
null = PyStackRef_NULL;
|
||||
stack_pointer[0] = value;
|
||||
null = PyStackRef_NULL;
|
||||
stack_pointer[1] = null;
|
||||
stack_pointer += 2;
|
||||
assert(WITHIN_STACK_BOUNDS());
|
||||
|
|
42
Python/generated_cases.c.h
generated
42
Python/generated_cases.c.h
generated
|
@ -867,8 +867,10 @@
|
|||
PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable);
|
||||
PyObject *self = ((PyMethodObject *)callable_o)->im_self;
|
||||
maybe_self = PyStackRef_FromPyObjectNew(self);
|
||||
stack_pointer[-1 - oparg] = maybe_self;
|
||||
PyObject *method = ((PyMethodObject *)callable_o)->im_func;
|
||||
func = PyStackRef_FromPyObjectNew(method);
|
||||
stack_pointer[-2 - oparg] = func;
|
||||
/* Make sure that callable and all args are in memory */
|
||||
args[-2] = func;
|
||||
args[-1] = maybe_self;
|
||||
|
@ -1063,12 +1065,12 @@
|
|||
PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable);
|
||||
STAT_INC(CALL, hit);
|
||||
self = PyStackRef_FromPyObjectNew(((PyMethodObject *)callable_o)->im_self);
|
||||
stack_pointer[-1 - oparg] = self;
|
||||
func = PyStackRef_FromPyObjectNew(((PyMethodObject *)callable_o)->im_func);
|
||||
stack_pointer[-2 - oparg] = func;
|
||||
PyStackRef_CLOSE(callable);
|
||||
}
|
||||
// flush
|
||||
stack_pointer[-2 - oparg] = func;
|
||||
stack_pointer[-1 - oparg] = self;
|
||||
// _CHECK_FUNCTION_VERSION
|
||||
callable = stack_pointer[-2 - oparg];
|
||||
{
|
||||
|
@ -1172,13 +1174,13 @@
|
|||
assert(PyStackRef_IsNull(null));
|
||||
assert(Py_TYPE(callable_o) == &PyMethod_Type);
|
||||
self = PyStackRef_FromPyObjectNew(((PyMethodObject *)callable_o)->im_self);
|
||||
stack_pointer[-1 - oparg] = self;
|
||||
method = PyStackRef_FromPyObjectNew(((PyMethodObject *)callable_o)->im_func);
|
||||
stack_pointer[-2 - oparg] = method;
|
||||
assert(PyStackRef_FunctionCheck(method));
|
||||
PyStackRef_CLOSE(callable);
|
||||
}
|
||||
// flush
|
||||
stack_pointer[-2 - oparg] = method;
|
||||
stack_pointer[-1 - oparg] = self;
|
||||
// _PY_FRAME_GENERAL
|
||||
args = &stack_pointer[-oparg];
|
||||
self_or_null = stack_pointer[-1 - oparg];
|
||||
|
@ -2534,6 +2536,7 @@
|
|||
int matches = PyErr_GivenExceptionMatches(exc_value, PyExc_StopIteration);
|
||||
if (matches) {
|
||||
value = PyStackRef_FromPyObjectNew(((PyStopIterationObject *)exc_value)->value);
|
||||
stack_pointer[-2] = value;
|
||||
PyStackRef_CLOSE(sub_iter_st);
|
||||
PyStackRef_CLOSE(last_sent_val_st);
|
||||
PyStackRef_CLOSE(exc_value_st);
|
||||
|
@ -2545,7 +2548,6 @@
|
|||
goto exception_unwind;
|
||||
}
|
||||
stack_pointer[-3] = none;
|
||||
stack_pointer[-2] = value;
|
||||
stack_pointer += -1;
|
||||
assert(WITHIN_STACK_BOUNDS());
|
||||
DISPATCH();
|
||||
|
@ -3330,8 +3332,8 @@
|
|||
assert(seq);
|
||||
assert(it->it_index < PyList_GET_SIZE(seq));
|
||||
next = PyStackRef_FromPyObjectNew(PyList_GET_ITEM(seq, it->it_index++));
|
||||
stack_pointer[0] = next;
|
||||
}
|
||||
stack_pointer[0] = next;
|
||||
stack_pointer += 1;
|
||||
assert(WITHIN_STACK_BOUNDS());
|
||||
DISPATCH();
|
||||
|
@ -3423,8 +3425,8 @@
|
|||
assert(seq);
|
||||
assert(it->it_index < PyTuple_GET_SIZE(seq));
|
||||
next = PyStackRef_FromPyObjectNew(PyTuple_GET_ITEM(seq, it->it_index++));
|
||||
stack_pointer[0] = next;
|
||||
}
|
||||
stack_pointer[0] = next;
|
||||
stack_pointer += 1;
|
||||
assert(WITHIN_STACK_BOUNDS());
|
||||
DISPATCH();
|
||||
|
@ -3634,8 +3636,10 @@
|
|||
PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable);
|
||||
PyObject *self = ((PyMethodObject *)callable_o)->im_self;
|
||||
maybe_self = PyStackRef_FromPyObjectNew(self);
|
||||
stack_pointer[-1 - oparg] = maybe_self;
|
||||
PyObject *method = ((PyMethodObject *)callable_o)->im_func;
|
||||
func = PyStackRef_FromPyObjectNew(method);
|
||||
stack_pointer[-2 - oparg] = func;
|
||||
/* Make sure that callable and all args are in memory */
|
||||
args[-2] = func;
|
||||
args[-1] = maybe_self;
|
||||
|
@ -4071,6 +4075,7 @@
|
|||
// _LOAD_CONST
|
||||
{
|
||||
value = PyStackRef_FromPyObjectNew(GETITEM(FRAME_CO_CONSTS, oparg));
|
||||
stack_pointer[0] = value;
|
||||
}
|
||||
// _RETURN_VALUE_EVENT
|
||||
val = value;
|
||||
|
@ -4453,10 +4458,10 @@
|
|||
STAT_INC(LOAD_ATTR, hit);
|
||||
assert(descr != NULL);
|
||||
attr = PyStackRef_FromPyObjectNew(descr);
|
||||
stack_pointer[-1] = attr;
|
||||
null = PyStackRef_NULL;
|
||||
PyStackRef_CLOSE(owner);
|
||||
}
|
||||
stack_pointer[-1] = attr;
|
||||
if (oparg & 1) stack_pointer[0] = null;
|
||||
stack_pointer += (oparg & 1);
|
||||
assert(WITHIN_STACK_BOUNDS());
|
||||
|
@ -4577,9 +4582,9 @@
|
|||
assert(descr != NULL);
|
||||
assert(_PyType_HasFeature(Py_TYPE(descr), Py_TPFLAGS_METHOD_DESCRIPTOR));
|
||||
attr = PyStackRef_FromPyObjectNew(descr);
|
||||
stack_pointer[-1] = attr;
|
||||
self = owner;
|
||||
}
|
||||
stack_pointer[-1] = attr;
|
||||
stack_pointer[0] = self;
|
||||
stack_pointer += 1;
|
||||
assert(WITHIN_STACK_BOUNDS());
|
||||
|
@ -4613,9 +4618,9 @@
|
|||
assert(descr != NULL);
|
||||
assert(_PyType_HasFeature(Py_TYPE(descr), Py_TPFLAGS_METHOD_DESCRIPTOR));
|
||||
attr = PyStackRef_FromPyObjectNew(descr);
|
||||
stack_pointer[-1] = attr;
|
||||
self = owner;
|
||||
}
|
||||
stack_pointer[-1] = attr;
|
||||
stack_pointer[0] = self;
|
||||
stack_pointer += 1;
|
||||
assert(WITHIN_STACK_BOUNDS());
|
||||
|
@ -4661,9 +4666,9 @@
|
|||
assert(descr != NULL);
|
||||
assert(_PyType_HasFeature(Py_TYPE(descr), Py_TPFLAGS_METHOD_DESCRIPTOR));
|
||||
attr = PyStackRef_FromPyObjectNew(descr);
|
||||
stack_pointer[-1] = attr;
|
||||
self = owner;
|
||||
}
|
||||
stack_pointer[-1] = attr;
|
||||
stack_pointer[0] = self;
|
||||
stack_pointer += 1;
|
||||
assert(WITHIN_STACK_BOUNDS());
|
||||
|
@ -4739,8 +4744,8 @@
|
|||
assert(descr != NULL);
|
||||
PyStackRef_CLOSE(owner);
|
||||
attr = PyStackRef_FromPyObjectNew(descr);
|
||||
stack_pointer[-1] = attr;
|
||||
}
|
||||
stack_pointer[-1] = attr;
|
||||
DISPATCH();
|
||||
}
|
||||
|
||||
|
@ -4781,8 +4786,8 @@
|
|||
assert(descr != NULL);
|
||||
PyStackRef_CLOSE(owner);
|
||||
attr = PyStackRef_FromPyObjectNew(descr);
|
||||
stack_pointer[-1] = attr;
|
||||
}
|
||||
stack_pointer[-1] = attr;
|
||||
DISPATCH();
|
||||
}
|
||||
|
||||
|
@ -4878,10 +4883,10 @@
|
|||
STAT_INC(LOAD_ATTR, hit);
|
||||
null = PyStackRef_NULL;
|
||||
attr = PyStackRef_FromPyObjectNew(attr_o);
|
||||
stack_pointer[-1] = attr;
|
||||
PyStackRef_CLOSE(owner);
|
||||
}
|
||||
/* Skip 5 cache entries */
|
||||
stack_pointer[-1] = attr;
|
||||
if (oparg & 1) stack_pointer[0] = null;
|
||||
stack_pointer += (oparg & 1);
|
||||
assert(WITHIN_STACK_BOUNDS());
|
||||
|
@ -5290,7 +5295,7 @@
|
|||
"no locals found");
|
||||
if (true) goto error;
|
||||
}
|
||||
locals = PyStackRef_FromPyObjectNew(l);;
|
||||
locals = PyStackRef_FromPyObjectNew(l);
|
||||
stack_pointer[0] = locals;
|
||||
stack_pointer += 1;
|
||||
assert(WITHIN_STACK_BOUNDS());
|
||||
|
@ -5958,6 +5963,7 @@
|
|||
// _LOAD_CONST
|
||||
{
|
||||
value = PyStackRef_FromPyObjectNew(GETITEM(FRAME_CO_CONSTS, oparg));
|
||||
stack_pointer[0] = value;
|
||||
}
|
||||
// _RETURN_VALUE
|
||||
retval = value;
|
||||
|
@ -7018,10 +7024,10 @@
|
|||
DEOPT_IF(PyTuple_GET_SIZE(seq_o) != 2, UNPACK_SEQUENCE);
|
||||
STAT_INC(UNPACK_SEQUENCE, hit);
|
||||
val0 = PyStackRef_FromPyObjectNew(PyTuple_GET_ITEM(seq_o, 0));
|
||||
val1 = PyStackRef_FromPyObjectNew(PyTuple_GET_ITEM(seq_o, 1));
|
||||
PyStackRef_CLOSE(seq);
|
||||
stack_pointer[-1] = val1;
|
||||
stack_pointer[0] = val0;
|
||||
val1 = PyStackRef_FromPyObjectNew(PyTuple_GET_ITEM(seq_o, 1));
|
||||
stack_pointer[-1] = val1;
|
||||
PyStackRef_CLOSE(seq);
|
||||
stack_pointer += 1;
|
||||
assert(WITHIN_STACK_BOUNDS());
|
||||
DISPATCH();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue