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:
Sam Gross 2024-08-07 13:23:53 -04:00 committed by GitHub
parent 967a4f1d18
commit 3e753c689a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 176 additions and 63 deletions

View file

@ -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());