GH-126599: Remove the "counter" optimizer/executor (GH-126853)

This commit is contained in:
Xuanteng Huang 2025-01-17 07:57:04 +08:00 committed by GitHub
parent 27494dd9ad
commit b44ff6d0df
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
13 changed files with 97 additions and 353 deletions

View File

@ -98,11 +98,6 @@ struct _PyOptimizerObject {
};
/** Test support **/
typedef struct {
_PyOptimizerObject base;
int64_t count;
} _PyCounterOptimizerObject;
_PyOptimizerObject *_Py_SetOptimizer(PyInterpreterState *interp, _PyOptimizerObject* optimizer);
@ -119,7 +114,6 @@ PyAPI_FUNC(void) _Py_Executor_DependsOn(_PyExecutorObject *executor, void *obj);
// Export for '_testinternalcapi' shared extension.
PyAPI_FUNC(_PyOptimizerObject *) _Py_GetOptimizer(void);
PyAPI_FUNC(int) _Py_SetTier2Optimizer(_PyOptimizerObject* optimizer);
PyAPI_FUNC(PyObject *) _PyOptimizer_NewCounter(void);
PyAPI_FUNC(PyObject *) _PyOptimizer_NewUOpOptimizer(void);
#define _Py_MAX_ALLOWED_BUILTINS_MODIFICATIONS 3
@ -150,8 +144,6 @@ int _Py_uop_analyze_and_optimize(struct _PyInterpreterFrame *frame,
_PyUOpInstruction *trace, int trace_len, int curr_stackentries,
_PyBloomFilter *dependencies);
extern PyTypeObject _PyCounterExecutor_Type;
extern PyTypeObject _PyCounterOptimizer_Type;
extern PyTypeObject _PyDefaultOptimizer_Type;
extern PyTypeObject _PyUOpExecutor_Type;
extern PyTypeObject _PyUOpOptimizer_Type;

View File

@ -164,144 +164,143 @@ extern "C" {
#define _INSTRUMENTED_POP_JUMP_IF_NONE INSTRUMENTED_POP_JUMP_IF_NONE
#define _INSTRUMENTED_POP_JUMP_IF_NOT_NONE INSTRUMENTED_POP_JUMP_IF_NOT_NONE
#define _INSTRUMENTED_POP_JUMP_IF_TRUE INSTRUMENTED_POP_JUMP_IF_TRUE
#define _INTERNAL_INCREMENT_OPT_COUNTER 399
#define _IS_NONE 400
#define _IS_NONE 399
#define _IS_OP IS_OP
#define _ITER_CHECK_LIST 401
#define _ITER_CHECK_RANGE 402
#define _ITER_CHECK_TUPLE 403
#define _ITER_JUMP_LIST 404
#define _ITER_JUMP_RANGE 405
#define _ITER_JUMP_TUPLE 406
#define _ITER_NEXT_LIST 407
#define _ITER_NEXT_RANGE 408
#define _ITER_NEXT_TUPLE 409
#define _JUMP_TO_TOP 410
#define _ITER_CHECK_LIST 400
#define _ITER_CHECK_RANGE 401
#define _ITER_CHECK_TUPLE 402
#define _ITER_JUMP_LIST 403
#define _ITER_JUMP_RANGE 404
#define _ITER_JUMP_TUPLE 405
#define _ITER_NEXT_LIST 406
#define _ITER_NEXT_RANGE 407
#define _ITER_NEXT_TUPLE 408
#define _JUMP_TO_TOP 409
#define _LIST_APPEND LIST_APPEND
#define _LIST_EXTEND LIST_EXTEND
#define _LOAD_ATTR 411
#define _LOAD_ATTR_CLASS 412
#define _LOAD_ATTR_CLASS_0 413
#define _LOAD_ATTR_CLASS_1 414
#define _LOAD_ATTR 410
#define _LOAD_ATTR_CLASS 411
#define _LOAD_ATTR_CLASS_0 412
#define _LOAD_ATTR_CLASS_1 413
#define _LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN
#define _LOAD_ATTR_INSTANCE_VALUE 415
#define _LOAD_ATTR_INSTANCE_VALUE_0 416
#define _LOAD_ATTR_INSTANCE_VALUE_1 417
#define _LOAD_ATTR_METHOD_LAZY_DICT 418
#define _LOAD_ATTR_METHOD_NO_DICT 419
#define _LOAD_ATTR_METHOD_WITH_VALUES 420
#define _LOAD_ATTR_MODULE 421
#define _LOAD_ATTR_MODULE_FROM_KEYS 422
#define _LOAD_ATTR_NONDESCRIPTOR_NO_DICT 423
#define _LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES 424
#define _LOAD_ATTR_PROPERTY_FRAME 425
#define _LOAD_ATTR_SLOT 426
#define _LOAD_ATTR_SLOT_0 427
#define _LOAD_ATTR_SLOT_1 428
#define _LOAD_ATTR_WITH_HINT 429
#define _LOAD_ATTR_INSTANCE_VALUE 414
#define _LOAD_ATTR_INSTANCE_VALUE_0 415
#define _LOAD_ATTR_INSTANCE_VALUE_1 416
#define _LOAD_ATTR_METHOD_LAZY_DICT 417
#define _LOAD_ATTR_METHOD_NO_DICT 418
#define _LOAD_ATTR_METHOD_WITH_VALUES 419
#define _LOAD_ATTR_MODULE 420
#define _LOAD_ATTR_MODULE_FROM_KEYS 421
#define _LOAD_ATTR_NONDESCRIPTOR_NO_DICT 422
#define _LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES 423
#define _LOAD_ATTR_PROPERTY_FRAME 424
#define _LOAD_ATTR_SLOT 425
#define _LOAD_ATTR_SLOT_0 426
#define _LOAD_ATTR_SLOT_1 427
#define _LOAD_ATTR_WITH_HINT 428
#define _LOAD_BUILD_CLASS LOAD_BUILD_CLASS
#define _LOAD_BYTECODE 430
#define _LOAD_BYTECODE 429
#define _LOAD_COMMON_CONSTANT LOAD_COMMON_CONSTANT
#define _LOAD_CONST LOAD_CONST
#define _LOAD_CONST_IMMORTAL LOAD_CONST_IMMORTAL
#define _LOAD_CONST_INLINE 431
#define _LOAD_CONST_INLINE_BORROW 432
#define _LOAD_CONST_INLINE_BORROW_WITH_NULL 433
#define _LOAD_CONST_INLINE_WITH_NULL 434
#define _LOAD_CONST_INLINE 430
#define _LOAD_CONST_INLINE_BORROW 431
#define _LOAD_CONST_INLINE_BORROW_WITH_NULL 432
#define _LOAD_CONST_INLINE_WITH_NULL 433
#define _LOAD_CONST_MORTAL LOAD_CONST_MORTAL
#define _LOAD_DEREF LOAD_DEREF
#define _LOAD_FAST 435
#define _LOAD_FAST_0 436
#define _LOAD_FAST_1 437
#define _LOAD_FAST_2 438
#define _LOAD_FAST_3 439
#define _LOAD_FAST_4 440
#define _LOAD_FAST_5 441
#define _LOAD_FAST_6 442
#define _LOAD_FAST_7 443
#define _LOAD_FAST 434
#define _LOAD_FAST_0 435
#define _LOAD_FAST_1 436
#define _LOAD_FAST_2 437
#define _LOAD_FAST_3 438
#define _LOAD_FAST_4 439
#define _LOAD_FAST_5 440
#define _LOAD_FAST_6 441
#define _LOAD_FAST_7 442
#define _LOAD_FAST_AND_CLEAR LOAD_FAST_AND_CLEAR
#define _LOAD_FAST_CHECK LOAD_FAST_CHECK
#define _LOAD_FAST_LOAD_FAST LOAD_FAST_LOAD_FAST
#define _LOAD_FROM_DICT_OR_DEREF LOAD_FROM_DICT_OR_DEREF
#define _LOAD_FROM_DICT_OR_GLOBALS LOAD_FROM_DICT_OR_GLOBALS
#define _LOAD_GLOBAL 444
#define _LOAD_GLOBAL_BUILTINS 445
#define _LOAD_GLOBAL_BUILTINS_FROM_KEYS 446
#define _LOAD_GLOBAL_MODULE 447
#define _LOAD_GLOBAL_MODULE_FROM_KEYS 448
#define _LOAD_GLOBAL 443
#define _LOAD_GLOBAL_BUILTINS 444
#define _LOAD_GLOBAL_BUILTINS_FROM_KEYS 445
#define _LOAD_GLOBAL_MODULE 446
#define _LOAD_GLOBAL_MODULE_FROM_KEYS 447
#define _LOAD_LOCALS LOAD_LOCALS
#define _LOAD_NAME LOAD_NAME
#define _LOAD_SMALL_INT 449
#define _LOAD_SMALL_INT_0 450
#define _LOAD_SMALL_INT_1 451
#define _LOAD_SMALL_INT_2 452
#define _LOAD_SMALL_INT_3 453
#define _LOAD_SMALL_INT 448
#define _LOAD_SMALL_INT_0 449
#define _LOAD_SMALL_INT_1 450
#define _LOAD_SMALL_INT_2 451
#define _LOAD_SMALL_INT_3 452
#define _LOAD_SPECIAL LOAD_SPECIAL
#define _LOAD_SUPER_ATTR_ATTR LOAD_SUPER_ATTR_ATTR
#define _LOAD_SUPER_ATTR_METHOD LOAD_SUPER_ATTR_METHOD
#define _MAKE_CALLARGS_A_TUPLE 454
#define _MAKE_CALLARGS_A_TUPLE 453
#define _MAKE_CELL MAKE_CELL
#define _MAKE_FUNCTION MAKE_FUNCTION
#define _MAKE_WARM 455
#define _MAKE_WARM 454
#define _MAP_ADD MAP_ADD
#define _MATCH_CLASS MATCH_CLASS
#define _MATCH_KEYS MATCH_KEYS
#define _MATCH_MAPPING MATCH_MAPPING
#define _MATCH_SEQUENCE MATCH_SEQUENCE
#define _MAYBE_EXPAND_METHOD 456
#define _MAYBE_EXPAND_METHOD_KW 457
#define _MONITOR_CALL 458
#define _MONITOR_JUMP_BACKWARD 459
#define _MONITOR_RESUME 460
#define _MAYBE_EXPAND_METHOD 455
#define _MAYBE_EXPAND_METHOD_KW 456
#define _MONITOR_CALL 457
#define _MONITOR_JUMP_BACKWARD 458
#define _MONITOR_RESUME 459
#define _NOP NOP
#define _POP_EXCEPT POP_EXCEPT
#define _POP_JUMP_IF_FALSE 461
#define _POP_JUMP_IF_TRUE 462
#define _POP_JUMP_IF_FALSE 460
#define _POP_JUMP_IF_TRUE 461
#define _POP_TOP POP_TOP
#define _POP_TOP_LOAD_CONST_INLINE_BORROW 463
#define _POP_TOP_LOAD_CONST_INLINE_BORROW 462
#define _PUSH_EXC_INFO PUSH_EXC_INFO
#define _PUSH_FRAME 464
#define _PUSH_FRAME 463
#define _PUSH_NULL PUSH_NULL
#define _PY_FRAME_GENERAL 465
#define _PY_FRAME_KW 466
#define _QUICKEN_RESUME 467
#define _REPLACE_WITH_TRUE 468
#define _PY_FRAME_GENERAL 464
#define _PY_FRAME_KW 465
#define _QUICKEN_RESUME 466
#define _REPLACE_WITH_TRUE 467
#define _RESUME_CHECK RESUME_CHECK
#define _RETURN_GENERATOR RETURN_GENERATOR
#define _RETURN_VALUE RETURN_VALUE
#define _SAVE_RETURN_OFFSET 469
#define _SEND 470
#define _SEND_GEN_FRAME 471
#define _SAVE_RETURN_OFFSET 468
#define _SEND 469
#define _SEND_GEN_FRAME 470
#define _SETUP_ANNOTATIONS SETUP_ANNOTATIONS
#define _SET_ADD SET_ADD
#define _SET_FUNCTION_ATTRIBUTE SET_FUNCTION_ATTRIBUTE
#define _SET_UPDATE SET_UPDATE
#define _START_EXECUTOR 472
#define _STORE_ATTR 473
#define _STORE_ATTR_INSTANCE_VALUE 474
#define _STORE_ATTR_SLOT 475
#define _STORE_ATTR_WITH_HINT 476
#define _START_EXECUTOR 471
#define _STORE_ATTR 472
#define _STORE_ATTR_INSTANCE_VALUE 473
#define _STORE_ATTR_SLOT 474
#define _STORE_ATTR_WITH_HINT 475
#define _STORE_DEREF STORE_DEREF
#define _STORE_FAST 477
#define _STORE_FAST_0 478
#define _STORE_FAST_1 479
#define _STORE_FAST_2 480
#define _STORE_FAST_3 481
#define _STORE_FAST_4 482
#define _STORE_FAST_5 483
#define _STORE_FAST_6 484
#define _STORE_FAST_7 485
#define _STORE_FAST 476
#define _STORE_FAST_0 477
#define _STORE_FAST_1 478
#define _STORE_FAST_2 479
#define _STORE_FAST_3 480
#define _STORE_FAST_4 481
#define _STORE_FAST_5 482
#define _STORE_FAST_6 483
#define _STORE_FAST_7 484
#define _STORE_FAST_LOAD_FAST STORE_FAST_LOAD_FAST
#define _STORE_FAST_STORE_FAST STORE_FAST_STORE_FAST
#define _STORE_GLOBAL STORE_GLOBAL
#define _STORE_NAME STORE_NAME
#define _STORE_SLICE 486
#define _STORE_SUBSCR 487
#define _STORE_SLICE 485
#define _STORE_SUBSCR 486
#define _STORE_SUBSCR_DICT STORE_SUBSCR_DICT
#define _STORE_SUBSCR_LIST_INT STORE_SUBSCR_LIST_INT
#define _SWAP SWAP
#define _TIER2_RESUME_CHECK 488
#define _TO_BOOL 489
#define _TIER2_RESUME_CHECK 487
#define _TO_BOOL 488
#define _TO_BOOL_BOOL TO_BOOL_BOOL
#define _TO_BOOL_INT TO_BOOL_INT
#define _TO_BOOL_LIST TO_BOOL_LIST
@ -311,13 +310,13 @@ extern "C" {
#define _UNARY_NEGATIVE UNARY_NEGATIVE
#define _UNARY_NOT UNARY_NOT
#define _UNPACK_EX UNPACK_EX
#define _UNPACK_SEQUENCE 490
#define _UNPACK_SEQUENCE 489
#define _UNPACK_SEQUENCE_LIST UNPACK_SEQUENCE_LIST
#define _UNPACK_SEQUENCE_TUPLE UNPACK_SEQUENCE_TUPLE
#define _UNPACK_SEQUENCE_TWO_TUPLE UNPACK_SEQUENCE_TWO_TUPLE
#define _WITH_EXCEPT_START WITH_EXCEPT_START
#define _YIELD_VALUE YIELD_VALUE
#define MAX_UOP_ID 490
#define MAX_UOP_ID 489
#ifdef __cplusplus
}

View File

@ -288,7 +288,6 @@ const uint16_t _PyUop_Flags[MAX_UOP_ID+1] = {
[_LOAD_GLOBAL_MODULE] = HAS_ARG_FLAG | HAS_DEOPT_FLAG,
[_LOAD_GLOBAL_BUILTINS] = HAS_ARG_FLAG | HAS_DEOPT_FLAG,
[_LOAD_ATTR_MODULE] = HAS_ARG_FLAG | HAS_DEOPT_FLAG,
[_INTERNAL_INCREMENT_OPT_COUNTER] = 0,
[_DYNAMIC_EXIT] = HAS_ESCAPES_FLAG,
[_START_EXECUTOR] = HAS_ESCAPES_FLAG,
[_MAKE_WARM] = 0,
@ -445,7 +444,6 @@ const char *const _PyOpcode_uop_name[MAX_UOP_ID+1] = {
[_INIT_CALL_PY_EXACT_ARGS_2] = "_INIT_CALL_PY_EXACT_ARGS_2",
[_INIT_CALL_PY_EXACT_ARGS_3] = "_INIT_CALL_PY_EXACT_ARGS_3",
[_INIT_CALL_PY_EXACT_ARGS_4] = "_INIT_CALL_PY_EXACT_ARGS_4",
[_INTERNAL_INCREMENT_OPT_COUNTER] = "_INTERNAL_INCREMENT_OPT_COUNTER",
[_IS_NONE] = "_IS_NONE",
[_IS_OP] = "_IS_OP",
[_ITER_CHECK_LIST] = "_ITER_CHECK_LIST",
@ -1127,8 +1125,6 @@ int _PyUop_num_popped(int opcode, int oparg)
return 0;
case _LOAD_ATTR_MODULE:
return 1;
case _INTERNAL_INCREMENT_OPT_COUNTER:
return 1;
case _DYNAMIC_EXIT:
return 0;
case _START_EXECUTOR:

View File

@ -35,90 +35,6 @@ def clear_executors(func):
func.__code__ = func.__code__.replace()
@requires_specialization
@unittest.skipIf(Py_GIL_DISABLED, "optimizer not yet supported in free-threaded builds")
@unittest.skipUnless(hasattr(_testinternalcapi, "get_optimizer"),
"Requires optimizer infrastructure")
class TestOptimizerAPI(unittest.TestCase):
def test_new_counter_optimizer_dealloc(self):
# See gh-108727
def f():
_testinternalcapi.new_counter_optimizer()
f()
def test_get_set_optimizer(self):
old = _testinternalcapi.get_optimizer()
opt = _testinternalcapi.new_counter_optimizer()
try:
_testinternalcapi.set_optimizer(opt)
self.assertEqual(_testinternalcapi.get_optimizer(), opt)
_testinternalcapi.set_optimizer(None)
self.assertEqual(_testinternalcapi.get_optimizer(), None)
finally:
_testinternalcapi.set_optimizer(old)
def test_counter_optimizer(self):
# Generate a new function at each call
ns = {}
exec(textwrap.dedent(f"""
def loop():
for _ in range({TIER2_THRESHOLD + 1000}):
pass
"""), ns, ns)
loop = ns['loop']
for repeat in range(5):
opt = _testinternalcapi.new_counter_optimizer()
with temporary_optimizer(opt):
self.assertEqual(opt.get_count(), 0)
with clear_executors(loop):
loop()
self.assertEqual(opt.get_count(), 1001)
def test_long_loop(self):
"Check that we aren't confused by EXTENDED_ARG"
# Generate a new function at each call
ns = {}
exec(textwrap.dedent(f"""
def nop():
pass
def long_loop():
for _ in range({TIER2_THRESHOLD + 20}):
nop(); nop(); nop(); nop(); nop(); nop(); nop(); nop();
nop(); nop(); nop(); nop(); nop(); nop(); nop(); nop();
nop(); nop(); nop(); nop(); nop(); nop(); nop(); nop();
nop(); nop(); nop(); nop(); nop(); nop(); nop(); nop();
nop(); nop(); nop(); nop(); nop(); nop(); nop(); nop();
nop(); nop(); nop(); nop(); nop(); nop(); nop(); nop();
nop(); nop(); nop(); nop(); nop(); nop(); nop(); nop();
"""), ns, ns)
long_loop = ns['long_loop']
opt = _testinternalcapi.new_counter_optimizer()
with temporary_optimizer(opt):
self.assertEqual(opt.get_count(), 0)
long_loop()
self.assertEqual(opt.get_count(), 21) # Need iterations to warm up
def test_code_restore_for_ENTER_EXECUTOR(self):
def testfunc(x):
i = 0
while i < x:
i += 1
opt = _testinternalcapi.new_counter_optimizer()
with temporary_optimizer(opt):
testfunc(1000)
code, replace_code = testfunc.__code__, testfunc.__code__.replace()
self.assertEqual(code, replace_code)
self.assertEqual(hash(code), hash(replace_code))
def get_first_executor(func):
code = func.__code__
co_code = code.co_code
@ -145,14 +61,6 @@ def get_opnames(ex):
"Requires optimizer infrastructure")
class TestExecutorInvalidation(unittest.TestCase):
def setUp(self):
self.old = _testinternalcapi.get_optimizer()
self.opt = _testinternalcapi.new_counter_optimizer()
_testinternalcapi.set_optimizer(self.opt)
def tearDown(self):
_testinternalcapi.set_optimizer(self.old)
def test_invalidate_object(self):
# Generate a new set of functions at each call
ns = {}
@ -167,8 +75,10 @@ def f{n}():
funcs = [ ns[f'f{n}'] for n in range(5)]
objects = [object() for _ in range(5)]
for f in funcs:
f()
opt = _testinternalcapi.new_uop_optimizer()
with temporary_optimizer(opt):
for f in funcs:
f()
executors = [get_first_executor(f) for f in funcs]
# Set things up so each executor depends on the objects
# with an equal or lower index.

View File

@ -12,7 +12,6 @@
import test.support
from test.support import requires_specialization_ft, script_helper
from test.support.import_helper import import_module
_testcapi = test.support.import_helper.import_module("_testcapi")
@ -2087,20 +2086,6 @@ def callback(code, instruction_offset):
class TestOptimizer(MonitoringTestBase, unittest.TestCase):
def setUp(self):
_testinternalcapi = import_module("_testinternalcapi")
if hasattr(_testinternalcapi, "get_optimizer"):
self.old_opt = _testinternalcapi.get_optimizer()
opt = _testinternalcapi.new_counter_optimizer()
_testinternalcapi.set_optimizer(opt)
super(TestOptimizer, self).setUp()
def tearDown(self):
super(TestOptimizer, self).tearDown()
import _testinternalcapi
if hasattr(_testinternalcapi, "get_optimizer"):
_testinternalcapi.set_optimizer(self.old_opt)
def test_for_loop(self):
def test_func(x):
i = 0

View File

@ -0,0 +1 @@
Remove some internal test APIs for the experimental JIT compiler.

View File

@ -989,12 +989,6 @@ get_co_framesize(PyObject *self, PyObject *arg)
#ifdef _Py_TIER2
static PyObject *
new_counter_optimizer(PyObject *self, PyObject *arg)
{
return _PyOptimizer_NewCounter();
}
static PyObject *
new_uop_optimizer(PyObject *self, PyObject *arg)
{
@ -1034,12 +1028,6 @@ add_executor_dependency(PyObject *self, PyObject *args)
if (!PyArg_ParseTuple(args, "OO", &exec, &obj)) {
return NULL;
}
/* No way to tell in general if exec is an executor, so we only accept
* counting_executor */
if (strcmp(Py_TYPE(exec)->tp_name, "counting_executor")) {
PyErr_SetString(PyExc_TypeError, "argument must be a counting_executor");
return NULL;
}
_Py_Executor_DependsOn((_PyExecutorObject *)exec, obj);
Py_RETURN_NONE;
}
@ -2101,7 +2089,6 @@ static PyMethodDef module_functions[] = {
#ifdef _Py_TIER2
{"get_optimizer", get_optimizer, METH_NOARGS, NULL},
{"set_optimizer", set_optimizer, METH_O, NULL},
{"new_counter_optimizer", new_counter_optimizer, METH_NOARGS, NULL},
{"new_uop_optimizer", new_uop_optimizer, METH_NOARGS, NULL},
{"add_executor_dependency", add_executor_dependency, METH_VARARGS, NULL},
{"invalidate_executors", invalidate_executors, METH_O, NULL},

View File

@ -2380,8 +2380,6 @@ static PyTypeObject* static_types[] = {
&_PyContextTokenMissing_Type,
&_PyCoroWrapper_Type,
#ifdef _Py_TIER2
&_PyCounterExecutor_Type,
&_PyCounterOptimizer_Type,
&_PyDefaultOptimizer_Type,
#endif
&_Py_GenericAliasIterType,

View File

@ -5076,13 +5076,6 @@ dummy_func(
DECREF_INPUTS();
}
/* Internal -- for testing executors */
op(_INTERNAL_INCREMENT_OPT_COUNTER, (opt --)) {
_PyCounterOptimizerObject *exe = (_PyCounterOptimizerObject *)PyStackRef_AsPyObjectBorrow(opt);
exe->count++;
DEAD(opt);
}
tier2 op(_DYNAMIC_EXIT, (exit_p/4 --)) {
tstate->previous_executor = (PyObject *)current_executor;
_PyExitData *exit = (_PyExitData *)exit_p;

View File

@ -6209,16 +6209,6 @@
break;
}
case _INTERNAL_INCREMENT_OPT_COUNTER: {
_PyStackRef opt;
opt = stack_pointer[-1];
_PyCounterOptimizerObject *exe = (_PyCounterOptimizerObject *)PyStackRef_AsPyObjectBorrow(opt);
exe->count++;
stack_pointer += -1;
assert(WITHIN_STACK_BOUNDS());
break;
}
case _DYNAMIC_EXIT: {
PyObject *exit_p = (PyObject *)CURRENT_OPERAND0();
tstate->previous_executor = (PyObject *)current_executor;

View File

@ -132,8 +132,6 @@ _Py_GetOptimizer(void)
static _PyExecutorObject *
make_executor_from_uops(_PyUOpInstruction *buffer, int length, const _PyBloomFilter *dependencies);
static const _PyBloomFilter EMPTY_FILTER = { 0 };
_PyOptimizerObject *
_Py_SetOptimizer(PyInterpreterState *interp, _PyOptimizerObject *optimizer)
{
@ -251,13 +249,6 @@ get_oparg(PyObject *self, PyObject *Py_UNUSED(ignored))
return PyLong_FromUnsignedLong(((_PyExecutorObject *)self)->vm_data.oparg);
}
static PyMethodDef executor_methods[] = {
{ "is_valid", is_valid, METH_NOARGS, NULL },
{ "get_opcode", get_opcode, METH_NOARGS, NULL },
{ "get_oparg", get_oparg, METH_NOARGS, NULL },
{ NULL, NULL },
};
///////////////////// Experimental UOp Optimizer /////////////////////
static int executor_clear(_PyExecutorObject *executor);
@ -1332,96 +1323,6 @@ _PyOptimizer_NewUOpOptimizer(void)
return (PyObject *)opt;
}
static void
counter_dealloc(_PyExecutorObject *self) {
/* The optimizer is the operand of the second uop. */
PyObject *opt = (PyObject *)self->trace[1].operand0;
Py_DECREF(opt);
uop_dealloc(self);
}
PyTypeObject _PyCounterExecutor_Type = {
PyVarObject_HEAD_INIT(&PyType_Type, 0)
.tp_name = "counting_executor",
.tp_basicsize = offsetof(_PyExecutorObject, exits),
.tp_itemsize = 1,
.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION | Py_TPFLAGS_HAVE_GC,
.tp_dealloc = (destructor)counter_dealloc,
.tp_methods = executor_methods,
.tp_traverse = executor_traverse,
.tp_clear = (inquiry)executor_clear,
};
static int
counter_optimize(
_PyOptimizerObject* self,
_PyInterpreterFrame *frame,
_Py_CODEUNIT *instr,
_PyExecutorObject **exec_ptr,
int Py_UNUSED(curr_stackentries),
bool Py_UNUSED(progress_needed)
)
{
PyCodeObject *code = _PyFrame_GetCode(frame);
int oparg = instr->op.arg;
while (instr->op.code == EXTENDED_ARG) {
instr++;
oparg = (oparg << 8) | instr->op.arg;
}
if (instr->op.code != JUMP_BACKWARD) {
/* Counter optimizer can only handle backward edges */
return 0;
}
_Py_CODEUNIT *target = instr + 1 + _PyOpcode_Caches[JUMP_BACKWARD] - oparg;
_PyUOpInstruction buffer[4] = {
{ .opcode = _START_EXECUTOR, .jump_target = 3, .format=UOP_FORMAT_JUMP },
{ .opcode = _LOAD_CONST_INLINE, .operand0 = (uintptr_t)self },
{ .opcode = _INTERNAL_INCREMENT_OPT_COUNTER },
{ .opcode = _EXIT_TRACE, .target = (uint32_t)(target - _PyCode_CODE(code)), .format=UOP_FORMAT_TARGET }
};
_PyExecutorObject *executor = make_executor_from_uops(buffer, 4, &EMPTY_FILTER);
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_Free,
};
PyObject *
_PyOptimizer_NewCounter(void)
{
_PyCounterOptimizerObject *opt = (_PyCounterOptimizerObject *)_PyObject_New(&_PyCounterOptimizer_Type);
if (opt == NULL) {
return NULL;
}
opt->base.optimize = counter_optimize;
opt->count = 0;
return (PyObject *)opt;
}
/*****************************************
* Executor management

View File

@ -2667,12 +2667,6 @@
break;
}
case _INTERNAL_INCREMENT_OPT_COUNTER: {
stack_pointer += -1;
assert(WITHIN_STACK_BOUNDS());
break;
}
case _DYNAMIC_EXIT: {
break;
}

View File

@ -386,8 +386,6 @@ Python/sysmodule.c - _PySys_ImplCacheTag -
Python/sysmodule.c - _PySys_ImplName -
Python/sysmodule.c - whatstrings -
Python/optimizer.c - _PyDefaultOptimizer_Type -
Python/optimizer.c - _PyCounterExecutor_Type -
Python/optimizer.c - _PyCounterOptimizer_Type -
Python/optimizer.c - _PyUOpExecutor_Type -
Python/optimizer.c - _PyUOpOptimizer_Type -
Python/optimizer.c - _PyOptimizer_Default -

Can't render this file because it has a wrong number of fields in line 4.