]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
GH-126599: Remove the "counter" optimizer/executor (GH-126853)
authorXuanteng Huang <44627253+xuantengh@users.noreply.github.com>
Thu, 16 Jan 2025 23:57:04 +0000 (07:57 +0800)
committerGitHub <noreply@github.com>
Thu, 16 Jan 2025 23:57:04 +0000 (15:57 -0800)
13 files changed:
Include/internal/pycore_optimizer.h
Include/internal/pycore_uop_ids.h
Include/internal/pycore_uop_metadata.h
Lib/test/test_capi/test_opt.py
Lib/test/test_monitoring.py
Misc/NEWS.d/next/C_API/2025-01-01-03-25-38.gh-issue-126599.MRCYlH.rst [new file with mode: 0644]
Modules/_testinternalcapi.c
Objects/object.c
Python/bytecodes.c
Python/executor_cases.c.h
Python/optimizer.c
Python/optimizer_cases.c.h
Tools/c-analyzer/cpython/ignored.tsv

index bc7cfcde613d656806f92e1a2648169b24fbed27..a02b9ab4291bfc59f69a0de9da9412871b8350c2 100644 (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;
index f95defbc364aedde24e5ade389f2080af71af342..066165a2c810d5f618550f5944ab3c95a5707b30 100644 (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
 }
index 298e918b872c6227c950b6259f6722d20936a5d2..7b28667a26e94d41fa348449cd7184ebe2a8568a 100644 (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:
index 12542d8b7fa62ee40ff480f4650103f0035f60cc..a74b8fdd3923b7c2308655b913e9f07bd5e0bdab 100644 (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 @@ class TestExecutorInvalidation(unittest.TestCase):
         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.
index bea0e48883bf9a52d822a42000ab6374665b24af..364381e7dce00a414a21da76c2c982a23e8b0128 100644 (file)
@@ -12,7 +12,6 @@ import unittest
 
 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 @@ class TestRegressions(MonitoringTestBase, unittest.TestCase):
 
 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
diff --git a/Misc/NEWS.d/next/C_API/2025-01-01-03-25-38.gh-issue-126599.MRCYlH.rst b/Misc/NEWS.d/next/C_API/2025-01-01-03-25-38.gh-issue-126599.MRCYlH.rst
new file mode 100644 (file)
index 0000000..8362ee3
--- /dev/null
@@ -0,0 +1 @@
+Remove some internal test APIs for the experimental JIT compiler.
index 150d34d168f5e47ac0bfdbb8dcc4a9914f12b240..98aea5b596e9208f0db5d1bb49e87f9f5052dc63 100644 (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},
index 9befd92e3231c8efc7880a426295ab3f29f84e88..4e900d8e79d91a97d3c0fcd5429c18cbfd7ccd21 100644 (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,
index b1d61a8707bd4cb0d53d5820186d1498a50d38e9..c0ef767a9dd68b5613eba07e0a9c4ff7d9ce10f0 100644 (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;
index ad825881c8228c8e337b9b4370c19a84272273d3..e2eaca2c90fa7639b9f3fe99f1c54869ce1cd142 100644 (file)
             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;
index 52b3f0a84afedf54a648b3b7a22ccae40acc6041..9beb47246eb3d6d51f821825c773dc00f3cc120c 100644 (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
index 90838d274a5e873a454ee616adaa59321c73299c..1f2b29c947434f8d18bfd15634e9605adc8c52fa 100644 (file)
             break;
         }
 
-        case _INTERNAL_INCREMENT_OPT_COUNTER: {
-            stack_pointer += -1;
-            assert(WITHIN_STACK_BOUNDS());
-            break;
-        }
-
         case _DYNAMIC_EXIT: {
             break;
         }
index 213165b06866b5c105c6c5b1a450b4be25b5ba19..da2cfedfd802c8dbbe20062e967284d7fc0cf5ba 100644 (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    -