diff options
author | Sam Gross <colesbury@gmail.com> | 2024-08-07 13:23:53 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-08-07 13:23:53 -0400 |
commit | 3e753c689a802d2e6d909cce3e22173977b2edbf (patch) | |
tree | 7330f998c15e42dbf12622dffccd773e5c5520dd /Python/generated_cases.c.h | |
parent | 967a4f1d180d4cd669d5c6e3ac5ba99af4e72d4e (diff) | |
download | cpython-3e753c689a802d2e6d909cce3e22173977b2edbf.tar.gz cpython-3e753c689a802d2e6d909cce3e22173977b2edbf.zip |
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>
Diffstat (limited to 'Python/generated_cases.c.h')
-rw-r--r-- | Python/generated_cases.c.h | 40 |
1 files changed, 23 insertions, 17 deletions
diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h index 5890fcea8e6..31f95eb4686 100644 --- a/Python/generated_cases.c.h +++ b/Python/generated_cases.c.h @@ -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)); + stack_pointer[0] = val0; val1 = PyStackRef_FromPyObjectNew(PyTuple_GET_ITEM(seq_o, 1)); - PyStackRef_CLOSE(seq); stack_pointer[-1] = val1; - stack_pointer[0] = val0; + PyStackRef_CLOSE(seq); stack_pointer += 1; assert(WITHIN_STACK_BOUNDS()); DISPATCH(); |