mirror of
https://github.com/python/cpython.git
synced 2025-07-08 03:45:36 +00:00
gh-111178: fix UBSan failures for _PyExecutorObject
(#131610)
This commit is contained in:
parent
aa444bc4af
commit
f65be097ed
1 changed files with 21 additions and 15 deletions
|
@ -28,6 +28,8 @@
|
||||||
|
|
||||||
#define MAX_EXECUTORS_SIZE 256
|
#define MAX_EXECUTORS_SIZE 256
|
||||||
|
|
||||||
|
#define _PyExecutorObject_CAST(op) ((_PyExecutorObject *)(op))
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
has_space_for_executor(PyCodeObject *code, _Py_CODEUNIT *instr)
|
has_space_for_executor(PyCodeObject *code, _Py_CODEUNIT *instr)
|
||||||
{
|
{
|
||||||
|
@ -199,11 +201,12 @@ get_oparg(PyObject *self, PyObject *Py_UNUSED(ignored))
|
||||||
|
|
||||||
///////////////////// Experimental UOp Optimizer /////////////////////
|
///////////////////// Experimental UOp Optimizer /////////////////////
|
||||||
|
|
||||||
static int executor_clear(_PyExecutorObject *executor);
|
static int executor_clear(PyObject *executor);
|
||||||
static void unlink_executor(_PyExecutorObject *executor);
|
static void unlink_executor(_PyExecutorObject *executor);
|
||||||
|
|
||||||
static void
|
static void
|
||||||
uop_dealloc(_PyExecutorObject *self) {
|
uop_dealloc(PyObject *op) {
|
||||||
|
_PyExecutorObject *self = _PyExecutorObject_CAST(op);
|
||||||
_PyObject_GC_UNTRACK(self);
|
_PyObject_GC_UNTRACK(self);
|
||||||
assert(self->vm_data.code == NULL);
|
assert(self->vm_data.code == NULL);
|
||||||
unlink_executor(self);
|
unlink_executor(self);
|
||||||
|
@ -260,15 +263,17 @@ _PyUOpPrint(const _PyUOpInstruction *uop)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static Py_ssize_t
|
static Py_ssize_t
|
||||||
uop_len(_PyExecutorObject *self)
|
uop_len(PyObject *op)
|
||||||
{
|
{
|
||||||
|
_PyExecutorObject *self = _PyExecutorObject_CAST(op);
|
||||||
return self->code_size;
|
return self->code_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
uop_item(_PyExecutorObject *self, Py_ssize_t index)
|
uop_item(PyObject *op, Py_ssize_t index)
|
||||||
{
|
{
|
||||||
Py_ssize_t len = uop_len(self);
|
_PyExecutorObject *self = _PyExecutorObject_CAST(op);
|
||||||
|
Py_ssize_t len = uop_len(op);
|
||||||
if (index < 0 || index >= len) {
|
if (index < 0 || index >= len) {
|
||||||
PyErr_SetNone(PyExc_IndexError);
|
PyErr_SetNone(PyExc_IndexError);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -304,14 +309,14 @@ uop_item(_PyExecutorObject *self, Py_ssize_t index)
|
||||||
}
|
}
|
||||||
|
|
||||||
PySequenceMethods uop_as_sequence = {
|
PySequenceMethods uop_as_sequence = {
|
||||||
.sq_length = (lenfunc)uop_len,
|
.sq_length = uop_len,
|
||||||
.sq_item = (ssizeargfunc)uop_item,
|
.sq_item = uop_item,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int
|
static int
|
||||||
executor_traverse(PyObject *o, visitproc visit, void *arg)
|
executor_traverse(PyObject *o, visitproc visit, void *arg)
|
||||||
{
|
{
|
||||||
_PyExecutorObject *executor = (_PyExecutorObject *)o;
|
_PyExecutorObject *executor = _PyExecutorObject_CAST(o);
|
||||||
for (uint32_t i = 0; i < executor->exit_count; i++) {
|
for (uint32_t i = 0; i < executor->exit_count; i++) {
|
||||||
Py_VISIT(executor->exits[i].executor);
|
Py_VISIT(executor->exits[i].executor);
|
||||||
}
|
}
|
||||||
|
@ -325,7 +330,7 @@ get_jit_code(PyObject *self, PyObject *Py_UNUSED(ignored))
|
||||||
PyErr_SetString(PyExc_RuntimeError, "JIT support not enabled.");
|
PyErr_SetString(PyExc_RuntimeError, "JIT support not enabled.");
|
||||||
return NULL;
|
return NULL;
|
||||||
#else
|
#else
|
||||||
_PyExecutorObject *executor = (_PyExecutorObject *)self;
|
_PyExecutorObject *executor = _PyExecutorObject_CAST(self);
|
||||||
if (executor->jit_code == NULL || executor->jit_size == 0) {
|
if (executor->jit_code == NULL || executor->jit_size == 0) {
|
||||||
Py_RETURN_NONE;
|
Py_RETURN_NONE;
|
||||||
}
|
}
|
||||||
|
@ -353,11 +358,11 @@ PyTypeObject _PyUOpExecutor_Type = {
|
||||||
.tp_basicsize = offsetof(_PyExecutorObject, exits),
|
.tp_basicsize = offsetof(_PyExecutorObject, exits),
|
||||||
.tp_itemsize = 1,
|
.tp_itemsize = 1,
|
||||||
.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION | Py_TPFLAGS_HAVE_GC,
|
.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION | Py_TPFLAGS_HAVE_GC,
|
||||||
.tp_dealloc = (destructor)uop_dealloc,
|
.tp_dealloc = uop_dealloc,
|
||||||
.tp_as_sequence = &uop_as_sequence,
|
.tp_as_sequence = &uop_as_sequence,
|
||||||
.tp_methods = uop_executor_methods,
|
.tp_methods = uop_executor_methods,
|
||||||
.tp_traverse = executor_traverse,
|
.tp_traverse = executor_traverse,
|
||||||
.tp_clear = (inquiry)executor_clear,
|
.tp_clear = executor_clear,
|
||||||
.tp_is_gc = executor_is_gc,
|
.tp_is_gc = executor_is_gc,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1422,8 +1427,9 @@ _Py_ExecutorDetach(_PyExecutorObject *executor)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
executor_clear(_PyExecutorObject *executor)
|
executor_clear(PyObject *op)
|
||||||
{
|
{
|
||||||
|
_PyExecutorObject *executor = _PyExecutorObject_CAST(op);
|
||||||
if (!executor->vm_data.valid) {
|
if (!executor->vm_data.valid) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1479,7 +1485,7 @@ _Py_Executors_InvalidateDependency(PyInterpreterState *interp, void *obj, int is
|
||||||
exec = next;
|
exec = next;
|
||||||
}
|
}
|
||||||
for (Py_ssize_t i = 0; i < PyList_GET_SIZE(invalidate); i++) {
|
for (Py_ssize_t i = 0; i < PyList_GET_SIZE(invalidate); i++) {
|
||||||
_PyExecutorObject *exec = (_PyExecutorObject *)PyList_GET_ITEM(invalidate, i);
|
PyObject *exec = PyList_GET_ITEM(invalidate, i);
|
||||||
executor_clear(exec);
|
executor_clear(exec);
|
||||||
if (is_invalidation) {
|
if (is_invalidation) {
|
||||||
OPT_STAT_INC(executors_invalidated);
|
OPT_STAT_INC(executors_invalidated);
|
||||||
|
@ -1506,7 +1512,7 @@ _Py_Executors_InvalidateAll(PyInterpreterState *interp, int is_invalidation)
|
||||||
_PyCode_Clear_Executors(executor->vm_data.code);
|
_PyCode_Clear_Executors(executor->vm_data.code);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
executor_clear(executor);
|
executor_clear((PyObject *)executor);
|
||||||
}
|
}
|
||||||
if (is_invalidation) {
|
if (is_invalidation) {
|
||||||
OPT_STAT_INC(executors_invalidated);
|
OPT_STAT_INC(executors_invalidated);
|
||||||
|
@ -1540,7 +1546,7 @@ _Py_Executors_InvalidateCold(PyInterpreterState *interp)
|
||||||
exec = next;
|
exec = next;
|
||||||
}
|
}
|
||||||
for (Py_ssize_t i = 0; i < PyList_GET_SIZE(invalidate); i++) {
|
for (Py_ssize_t i = 0; i < PyList_GET_SIZE(invalidate); i++) {
|
||||||
_PyExecutorObject *exec = (_PyExecutorObject *)PyList_GET_ITEM(invalidate, i);
|
PyObject *exec = PyList_GET_ITEM(invalidate, i);
|
||||||
executor_clear(exec);
|
executor_clear(exec);
|
||||||
}
|
}
|
||||||
Py_DECREF(invalidate);
|
Py_DECREF(invalidate);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue