mirror of
https://github.com/python/cpython.git
synced 2025-07-08 03:45:36 +00:00
GH-113860: All executors are now defined in terms of micro ops. Convert counter executor to use uops. (GH-113864)
This commit is contained in:
parent
93930eaf0a
commit
a0c9cf9456
9 changed files with 125 additions and 139 deletions
|
@ -212,27 +212,6 @@ PyUnstable_GetExecutor(PyCodeObject *code, int offset)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/** Test support **/
|
||||
|
||||
|
||||
typedef struct {
|
||||
_PyOptimizerObject base;
|
||||
int64_t count;
|
||||
} _PyCounterOptimizerObject;
|
||||
|
||||
typedef struct {
|
||||
_PyExecutorObject executor;
|
||||
_PyCounterOptimizerObject *optimizer;
|
||||
_Py_CODEUNIT *next_instr;
|
||||
} _PyCounterExecutorObject;
|
||||
|
||||
static void
|
||||
counter_dealloc(_PyCounterExecutorObject *self) {
|
||||
_Py_ExecutorClear((_PyExecutorObject *)self);
|
||||
Py_DECREF(self->optimizer);
|
||||
PyObject_Free(self);
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
is_valid(PyObject *self, PyObject *Py_UNUSED(ignored))
|
||||
{
|
||||
|
@ -244,84 +223,6 @@ static PyMethodDef executor_methods[] = {
|
|||
{ NULL, NULL },
|
||||
};
|
||||
|
||||
PyTypeObject _PyCounterExecutor_Type = {
|
||||
PyVarObject_HEAD_INIT(&PyType_Type, 0)
|
||||
.tp_name = "counting_executor",
|
||||
.tp_basicsize = sizeof(_PyCounterExecutorObject),
|
||||
.tp_itemsize = 0,
|
||||
.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION,
|
||||
.tp_dealloc = (destructor)counter_dealloc,
|
||||
.tp_methods = executor_methods,
|
||||
};
|
||||
|
||||
static _Py_CODEUNIT *
|
||||
counter_execute(_PyExecutorObject *self, _PyInterpreterFrame *frame, PyObject **stack_pointer)
|
||||
{
|
||||
((_PyCounterExecutorObject *)self)->optimizer->count++;
|
||||
_PyFrame_SetStackPointer(frame, stack_pointer);
|
||||
Py_DECREF(self);
|
||||
return ((_PyCounterExecutorObject *)self)->next_instr;
|
||||
}
|
||||
|
||||
static int
|
||||
counter_optimize(
|
||||
_PyOptimizerObject* self,
|
||||
PyCodeObject *code,
|
||||
_Py_CODEUNIT *instr,
|
||||
_PyExecutorObject **exec_ptr,
|
||||
int Py_UNUSED(curr_stackentries)
|
||||
)
|
||||
{
|
||||
_PyCounterExecutorObject *executor = (_PyCounterExecutorObject *)_PyObject_New(&_PyCounterExecutor_Type);
|
||||
if (executor == NULL) {
|
||||
return -1;
|
||||
}
|
||||
executor->executor.execute = counter_execute;
|
||||
Py_INCREF(self);
|
||||
executor->optimizer = (_PyCounterOptimizerObject *)self;
|
||||
executor->next_instr = instr;
|
||||
*exec_ptr = (_PyExecutorObject *)executor;
|
||||
_PyBloomFilter empty;
|
||||
_Py_BloomFilter_Init(&empty);
|
||||
_Py_ExecutorInit((_PyExecutorObject *)executor, &empty);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
counter_get_counter(PyObject *self, PyObject *args)
|
||||
{
|
||||
return PyLong_FromLongLong(((_PyCounterOptimizerObject *)self)->count);
|
||||
}
|
||||
|
||||
static PyMethodDef counter_optimizer_methods[] = {
|
||||
{ "get_count", counter_get_counter, METH_NOARGS, NULL },
|
||||
{ NULL, NULL },
|
||||
};
|
||||
|
||||
PyTypeObject _PyCounterOptimizer_Type = {
|
||||
PyVarObject_HEAD_INIT(&PyType_Type, 0)
|
||||
.tp_name = "Counter optimizer",
|
||||
.tp_basicsize = sizeof(_PyCounterOptimizerObject),
|
||||
.tp_itemsize = 0,
|
||||
.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION,
|
||||
.tp_methods = counter_optimizer_methods,
|
||||
.tp_dealloc = (destructor)PyObject_Del,
|
||||
};
|
||||
|
||||
PyObject *
|
||||
PyUnstable_Optimizer_NewCounter(void)
|
||||
{
|
||||
_PyCounterOptimizerObject *opt = (_PyCounterOptimizerObject *)_PyObject_New(&_PyCounterOptimizer_Type);
|
||||
if (opt == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
opt->base.optimize = counter_optimize;
|
||||
opt->base.resume_threshold = INT16_MAX;
|
||||
opt->base.backedge_threshold = 0;
|
||||
opt->count = 0;
|
||||
return (PyObject *)opt;
|
||||
}
|
||||
|
||||
///////////////////// Experimental UOp Optimizer /////////////////////
|
||||
|
||||
static void
|
||||
|
@ -381,7 +282,7 @@ PySequenceMethods uop_as_sequence = {
|
|||
PyTypeObject _PyUOpExecutor_Type = {
|
||||
PyVarObject_HEAD_INIT(&PyType_Type, 0)
|
||||
.tp_name = "uop_executor",
|
||||
.tp_basicsize = sizeof(_PyUOpExecutorObject) - sizeof(_PyUOpInstruction),
|
||||
.tp_basicsize = offsetof(_PyUOpExecutorObject, trace),
|
||||
.tp_itemsize = sizeof(_PyUOpInstruction),
|
||||
.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION,
|
||||
.tp_dealloc = (destructor)uop_dealloc,
|
||||
|
@ -843,7 +744,6 @@ make_executor_from_uops(_PyUOpInstruction *buffer, _PyBloomFilter *dependencies)
|
|||
dest--;
|
||||
}
|
||||
assert(dest == -1);
|
||||
executor->base.execute = _PyUOpExecute;
|
||||
_Py_ExecutorInit((_PyExecutorObject *)executor, dependencies);
|
||||
#ifdef Py_DEBUG
|
||||
char *python_lltrace = Py_GETENV("PYTHON_LLTRACE");
|
||||
|
@ -899,15 +799,6 @@ uop_optimize(
|
|||
return 1;
|
||||
}
|
||||
|
||||
/* Dummy execute() function for UOp Executor.
|
||||
* The actual implementation is inlined in ceval.c,
|
||||
* in _PyEval_EvalFrameDefault(). */
|
||||
_Py_CODEUNIT *
|
||||
_PyUOpExecute(_PyExecutorObject *executor, _PyInterpreterFrame *frame, PyObject **stack_pointer)
|
||||
{
|
||||
Py_FatalError("Tier 2 is now inlined into Tier 1");
|
||||
}
|
||||
|
||||
static void
|
||||
uop_opt_dealloc(PyObject *self) {
|
||||
PyObject_Free(self);
|
||||
|
@ -937,6 +828,84 @@ PyUnstable_Optimizer_NewUOpOptimizer(void)
|
|||
return (PyObject *)opt;
|
||||
}
|
||||
|
||||
static void
|
||||
counter_dealloc(_PyUOpExecutorObject *self) {
|
||||
PyObject *opt = (PyObject *)self->trace[0].operand;
|
||||
Py_DECREF(opt);
|
||||
uop_dealloc(self);
|
||||
}
|
||||
|
||||
PyTypeObject _PyCounterExecutor_Type = {
|
||||
PyVarObject_HEAD_INIT(&PyType_Type, 0)
|
||||
.tp_name = "counting_executor",
|
||||
.tp_basicsize = offsetof(_PyUOpExecutorObject, trace),
|
||||
.tp_itemsize = sizeof(_PyUOpInstruction),
|
||||
.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION,
|
||||
.tp_dealloc = (destructor)counter_dealloc,
|
||||
.tp_methods = executor_methods,
|
||||
};
|
||||
|
||||
static int
|
||||
counter_optimize(
|
||||
_PyOptimizerObject* self,
|
||||
PyCodeObject *code,
|
||||
_Py_CODEUNIT *instr,
|
||||
_PyExecutorObject **exec_ptr,
|
||||
int Py_UNUSED(curr_stackentries)
|
||||
)
|
||||
{
|
||||
_PyUOpInstruction buffer[3] = {
|
||||
{ .opcode = _LOAD_CONST_INLINE_BORROW, .operand = (uintptr_t)self },
|
||||
{ .opcode = _INTERNAL_INCREMENT_OPT_COUNTER },
|
||||
{ .opcode = _EXIT_TRACE, .target = (uint32_t)(instr - _PyCode_CODE(code)) }
|
||||
};
|
||||
_PyBloomFilter empty;
|
||||
_Py_BloomFilter_Init(&empty);
|
||||
_PyExecutorObject *executor = make_executor_from_uops(buffer, &empty);
|
||||
if (executor == NULL) {
|
||||
return -1;
|
||||
}
|
||||
Py_INCREF(self);
|
||||
Py_SET_TYPE(executor, &_PyCounterExecutor_Type);
|
||||
*exec_ptr = executor;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
counter_get_counter(PyObject *self, PyObject *args)
|
||||
{
|
||||
return PyLong_FromLongLong(((_PyCounterOptimizerObject *)self)->count);
|
||||
}
|
||||
|
||||
static PyMethodDef counter_optimizer_methods[] = {
|
||||
{ "get_count", counter_get_counter, METH_NOARGS, NULL },
|
||||
{ NULL, NULL },
|
||||
};
|
||||
|
||||
PyTypeObject _PyCounterOptimizer_Type = {
|
||||
PyVarObject_HEAD_INIT(&PyType_Type, 0)
|
||||
.tp_name = "Counter optimizer",
|
||||
.tp_basicsize = sizeof(_PyCounterOptimizerObject),
|
||||
.tp_itemsize = 0,
|
||||
.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION,
|
||||
.tp_methods = counter_optimizer_methods,
|
||||
.tp_dealloc = (destructor)PyObject_Del,
|
||||
};
|
||||
|
||||
PyObject *
|
||||
PyUnstable_Optimizer_NewCounter(void)
|
||||
{
|
||||
_PyCounterOptimizerObject *opt = (_PyCounterOptimizerObject *)_PyObject_New(&_PyCounterOptimizer_Type);
|
||||
if (opt == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
opt->base.optimize = counter_optimize;
|
||||
opt->base.resume_threshold = INT16_MAX;
|
||||
opt->base.backedge_threshold = 0;
|
||||
opt->count = 0;
|
||||
return (PyObject *)opt;
|
||||
}
|
||||
|
||||
|
||||
/*****************************************
|
||||
* Executor management
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue