diff options
-rw-r--r-- | Include/cpython/code.h | 1 | ||||
-rw-r--r-- | Include/internal/pycore_code.h | 32 | ||||
-rw-r--r-- | Include/internal/pycore_opcode.h | 30 | ||||
-rw-r--r-- | Include/opcode.h | 64 | ||||
-rw-r--r-- | Lib/opcode.py | 6 | ||||
-rw-r--r-- | Lib/test/libregrtest/refleak.py | 3 | ||||
-rw-r--r-- | Lib/test/test_call.py | 10 | ||||
-rw-r--r-- | Lib/test/test_dis.py | 23 | ||||
-rw-r--r-- | Lib/test/test_embed.py | 46 | ||||
-rw-r--r-- | Lib/test/test_lltrace.py | 4 | ||||
-rw-r--r-- | Misc/NEWS.d/next/Core and Builtins/2022-10-16-13-26-46.gh-issue-98686.D9Gu_Q.rst | 2 | ||||
-rw-r--r-- | Objects/codeobject.c | 16 | ||||
-rw-r--r-- | Objects/frameobject.c | 2 | ||||
-rw-r--r-- | Objects/genobject.c | 3 | ||||
-rw-r--r-- | Python/ceval.c | 30 | ||||
-rw-r--r-- | Python/clinic/sysmodule.c.h | 29 | ||||
-rw-r--r-- | Python/opcode_targets.h | 26 | ||||
-rw-r--r-- | Python/specialize.c | 13 | ||||
-rw-r--r-- | Python/sysmodule.c | 13 | ||||
-rw-r--r-- | Tools/build/deepfreeze.py | 29 | ||||
-rw-r--r-- | Tools/c-analyzer/cpython/globals-to-fix.tsv | 1 |
21 files changed, 144 insertions, 239 deletions
diff --git a/Include/cpython/code.h b/Include/cpython/code.h index 893ff93..ebac0b1 100644 --- a/Include/cpython/code.h +++ b/Include/cpython/code.h @@ -70,7 +70,6 @@ typedef struct { PyObject *co_exceptiontable; /* Byte string encoding exception handling \ table */ \ int co_flags; /* CO_..., see below */ \ - short co_warmup; /* Warmup counter for quickening */ \ short _co_linearray_entry_size; /* Size of each entry in _co_linearray */ \ \ /* The rest are not so impactful on performance. */ \ diff --git a/Include/internal/pycore_code.h b/Include/internal/pycore_code.h index bf59454..cf8573a 100644 --- a/Include/internal/pycore_code.h +++ b/Include/internal/pycore_code.h @@ -91,28 +91,8 @@ typedef struct { #define INLINE_CACHE_ENTRIES_FOR_ITER CACHE_ENTRIES(_PyForIterCache) -#define QUICKENING_WARMUP_DELAY 8 - -/* We want to compare to zero for efficiency, so we offset values accordingly */ -#define QUICKENING_INITIAL_WARMUP_VALUE (-QUICKENING_WARMUP_DELAY) - -void _PyCode_Quicken(PyCodeObject *code); - -static inline void -_PyCode_Warmup(PyCodeObject *code) -{ - if (code->co_warmup != 0) { - code->co_warmup++; - if (code->co_warmup == 0) { - _PyCode_Quicken(code); - } - } -} - extern uint8_t _PyOpcode_Adaptive[256]; -extern Py_ssize_t _Py_QuickenedCount; - // Borrowed references to common callables: struct callable_cache { PyObject *isinstance; @@ -252,10 +232,10 @@ extern void _Py_Specialize_UnpackSequence(PyObject *seq, _Py_CODEUNIT *instr, int oparg); extern void _Py_Specialize_ForIter(PyObject *iter, _Py_CODEUNIT *instr); -/* Deallocator function for static codeobjects used in deepfreeze.py */ -extern void _PyStaticCode_Dealloc(PyCodeObject *co); -/* Function to intern strings of codeobjects */ -extern int _PyStaticCode_InternStrings(PyCodeObject *co); +/* Finalizer function for static codeobjects used in deepfreeze.py */ +extern void _PyStaticCode_Fini(PyCodeObject *co); +/* Function to intern strings of codeobjects and quicken the bytecode */ +extern int _PyStaticCode_Init(PyCodeObject *co); #ifdef Py_STATS @@ -397,8 +377,8 @@ write_location_entry_start(uint8_t *ptr, int code, int length) /* With a 16-bit counter, we have 12 bits for the counter value, and 4 bits for the backoff */ #define ADAPTIVE_BACKOFF_BITS 4 -/* The initial counter value is 31 == 2**ADAPTIVE_BACKOFF_START - 1 */ -#define ADAPTIVE_BACKOFF_START 5 +/* The initial counter value is 1 == 2**ADAPTIVE_BACKOFF_START - 1 */ +#define ADAPTIVE_BACKOFF_START 1 #define MAX_BACKOFF_VALUE (16 - ADAPTIVE_BACKOFF_BITS) diff --git a/Include/internal/pycore_opcode.h b/Include/internal/pycore_opcode.h index 33617b4..0ef677f 100644 --- a/Include/internal/pycore_opcode.h +++ b/Include/internal/pycore_opcode.h @@ -142,7 +142,6 @@ const uint8_t _PyOpcode_Deopt[256] = { [IS_OP] = IS_OP, [JUMP_BACKWARD] = JUMP_BACKWARD, [JUMP_BACKWARD_NO_INTERRUPT] = JUMP_BACKWARD_NO_INTERRUPT, - [JUMP_BACKWARD_QUICK] = JUMP_BACKWARD, [JUMP_FORWARD] = JUMP_FORWARD, [JUMP_IF_FALSE_OR_POP] = JUMP_IF_FALSE_OR_POP, [JUMP_IF_TRUE_OR_POP] = JUMP_IF_TRUE_OR_POP, @@ -200,7 +199,6 @@ const uint8_t _PyOpcode_Deopt[256] = { [RAISE_VARARGS] = RAISE_VARARGS, [RERAISE] = RERAISE, [RESUME] = RESUME, - [RESUME_QUICK] = RESUME, [RETURN_GENERATOR] = RETURN_GENERATOR, [RETURN_VALUE] = RETURN_VALUE, [SEND] = SEND, @@ -313,21 +311,21 @@ static const char *const _PyOpcode_OpName[263] = { [GET_YIELD_FROM_ITER] = "GET_YIELD_FROM_ITER", [PRINT_EXPR] = "PRINT_EXPR", [LOAD_BUILD_CLASS] = "LOAD_BUILD_CLASS", - [JUMP_BACKWARD_QUICK] = "JUMP_BACKWARD_QUICK", [LOAD_ATTR_ADAPTIVE] = "LOAD_ATTR_ADAPTIVE", + [LOAD_ATTR_CLASS] = "LOAD_ATTR_CLASS", [LOAD_ASSERTION_ERROR] = "LOAD_ASSERTION_ERROR", [RETURN_GENERATOR] = "RETURN_GENERATOR", - [LOAD_ATTR_CLASS] = "LOAD_ATTR_CLASS", [LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN] = "LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN", [LOAD_ATTR_INSTANCE_VALUE] = "LOAD_ATTR_INSTANCE_VALUE", [LOAD_ATTR_MODULE] = "LOAD_ATTR_MODULE", [LOAD_ATTR_PROPERTY] = "LOAD_ATTR_PROPERTY", [LOAD_ATTR_SLOT] = "LOAD_ATTR_SLOT", + [LOAD_ATTR_WITH_HINT] = "LOAD_ATTR_WITH_HINT", [LIST_TO_TUPLE] = "LIST_TO_TUPLE", [RETURN_VALUE] = "RETURN_VALUE", [IMPORT_STAR] = "IMPORT_STAR", [SETUP_ANNOTATIONS] = "SETUP_ANNOTATIONS", - [LOAD_ATTR_WITH_HINT] = "LOAD_ATTR_WITH_HINT", + [LOAD_ATTR_METHOD_LAZY_DICT] = "LOAD_ATTR_METHOD_LAZY_DICT", [ASYNC_GEN_WRAP] = "ASYNC_GEN_WRAP", [PREP_RERAISE_STAR] = "PREP_RERAISE_STAR", [POP_EXCEPT] = "POP_EXCEPT", @@ -354,7 +352,7 @@ static const char *const _PyOpcode_OpName[263] = { [JUMP_FORWARD] = "JUMP_FORWARD", [JUMP_IF_FALSE_OR_POP] = "JUMP_IF_FALSE_OR_POP", [JUMP_IF_TRUE_OR_POP] = "JUMP_IF_TRUE_OR_POP", - [LOAD_ATTR_METHOD_LAZY_DICT] = "LOAD_ATTR_METHOD_LAZY_DICT", + [LOAD_ATTR_METHOD_NO_DICT] = "LOAD_ATTR_METHOD_NO_DICT", [POP_JUMP_IF_FALSE] = "POP_JUMP_IF_FALSE", [POP_JUMP_IF_TRUE] = "POP_JUMP_IF_TRUE", [LOAD_GLOBAL] = "LOAD_GLOBAL", @@ -362,7 +360,7 @@ static const char *const _PyOpcode_OpName[263] = { [CONTAINS_OP] = "CONTAINS_OP", [RERAISE] = "RERAISE", [COPY] = "COPY", - [LOAD_ATTR_METHOD_NO_DICT] = "LOAD_ATTR_METHOD_NO_DICT", + [LOAD_ATTR_METHOD_WITH_DICT] = "LOAD_ATTR_METHOD_WITH_DICT", [BINARY_OP] = "BINARY_OP", [SEND] = "SEND", [LOAD_FAST] = "LOAD_FAST", @@ -382,9 +380,9 @@ static const char *const _PyOpcode_OpName[263] = { [STORE_DEREF] = "STORE_DEREF", [DELETE_DEREF] = "DELETE_DEREF", [JUMP_BACKWARD] = "JUMP_BACKWARD", - [LOAD_ATTR_METHOD_WITH_DICT] = "LOAD_ATTR_METHOD_WITH_DICT", - [CALL_FUNCTION_EX] = "CALL_FUNCTION_EX", [LOAD_ATTR_METHOD_WITH_VALUES] = "LOAD_ATTR_METHOD_WITH_VALUES", + [CALL_FUNCTION_EX] = "CALL_FUNCTION_EX", + [LOAD_CONST__LOAD_FAST] = "LOAD_CONST__LOAD_FAST", [EXTENDED_ARG] = "EXTENDED_ARG", [LIST_APPEND] = "LIST_APPEND", [SET_ADD] = "SET_ADD", @@ -394,28 +392,26 @@ static const char *const _PyOpcode_OpName[263] = { [YIELD_VALUE] = "YIELD_VALUE", [RESUME] = "RESUME", [MATCH_CLASS] = "MATCH_CLASS", - [LOAD_CONST__LOAD_FAST] = "LOAD_CONST__LOAD_FAST", [LOAD_FAST__LOAD_CONST] = "LOAD_FAST__LOAD_CONST", + [LOAD_FAST__LOAD_FAST] = "LOAD_FAST__LOAD_FAST", [FORMAT_VALUE] = "FORMAT_VALUE", [BUILD_CONST_KEY_MAP] = "BUILD_CONST_KEY_MAP", [BUILD_STRING] = "BUILD_STRING", - [LOAD_FAST__LOAD_FAST] = "LOAD_FAST__LOAD_FAST", [LOAD_GLOBAL_ADAPTIVE] = "LOAD_GLOBAL_ADAPTIVE", [LOAD_GLOBAL_BUILTIN] = "LOAD_GLOBAL_BUILTIN", [LOAD_GLOBAL_MODULE] = "LOAD_GLOBAL_MODULE", + [STORE_ATTR_ADAPTIVE] = "STORE_ATTR_ADAPTIVE", [LIST_EXTEND] = "LIST_EXTEND", [SET_UPDATE] = "SET_UPDATE", [DICT_MERGE] = "DICT_MERGE", [DICT_UPDATE] = "DICT_UPDATE", - [RESUME_QUICK] = "RESUME_QUICK", - [STORE_ATTR_ADAPTIVE] = "STORE_ATTR_ADAPTIVE", [STORE_ATTR_INSTANCE_VALUE] = "STORE_ATTR_INSTANCE_VALUE", [STORE_ATTR_SLOT] = "STORE_ATTR_SLOT", [STORE_ATTR_WITH_HINT] = "STORE_ATTR_WITH_HINT", - [CALL] = "CALL", - [KW_NAMES] = "KW_NAMES", [STORE_FAST__LOAD_FAST] = "STORE_FAST__LOAD_FAST", [STORE_FAST__STORE_FAST] = "STORE_FAST__STORE_FAST", + [CALL] = "CALL", + [KW_NAMES] = "KW_NAMES", [STORE_SUBSCR_ADAPTIVE] = "STORE_SUBSCR_ADAPTIVE", [STORE_SUBSCR_DICT] = "STORE_SUBSCR_DICT", [STORE_SUBSCR_LIST_INT] = "STORE_SUBSCR_LIST_INT", @@ -423,6 +419,8 @@ static const char *const _PyOpcode_OpName[263] = { [UNPACK_SEQUENCE_LIST] = "UNPACK_SEQUENCE_LIST", [UNPACK_SEQUENCE_TUPLE] = "UNPACK_SEQUENCE_TUPLE", [UNPACK_SEQUENCE_TWO_TUPLE] = "UNPACK_SEQUENCE_TWO_TUPLE", + [180] = "<180>", + [181] = "<181>", [182] = "<182>", [183] = "<183>", [184] = "<184>", @@ -508,6 +506,8 @@ static const char *const _PyOpcode_OpName[263] = { #endif #define EXTRA_CASES \ + case 180: \ + case 181: \ case 182: \ case 183: \ case 184: \ diff --git a/Include/opcode.h b/Include/opcode.h index 9b9414c..661b587 100644 --- a/Include/opcode.h +++ b/Include/opcode.h @@ -167,39 +167,37 @@ extern "C" { #define FOR_ITER_ADAPTIVE 65 #define FOR_ITER_LIST 66 #define FOR_ITER_RANGE 67 -#define JUMP_BACKWARD_QUICK 72 -#define LOAD_ATTR_ADAPTIVE 73 -#define LOAD_ATTR_CLASS 76 -#define LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN 77 -#define LOAD_ATTR_INSTANCE_VALUE 78 -#define LOAD_ATTR_MODULE 79 -#define LOAD_ATTR_PROPERTY 80 -#define LOAD_ATTR_SLOT 81 -#define LOAD_ATTR_WITH_HINT 86 -#define LOAD_ATTR_METHOD_LAZY_DICT 113 -#define LOAD_ATTR_METHOD_NO_DICT 121 -#define LOAD_ATTR_METHOD_WITH_DICT 141 -#define LOAD_ATTR_METHOD_WITH_VALUES 143 -#define LOAD_CONST__LOAD_FAST 153 -#define LOAD_FAST__LOAD_CONST 154 -#define LOAD_FAST__LOAD_FAST 158 -#define LOAD_GLOBAL_ADAPTIVE 159 -#define LOAD_GLOBAL_BUILTIN 160 -#define LOAD_GLOBAL_MODULE 161 -#define RESUME_QUICK 166 -#define STORE_ATTR_ADAPTIVE 167 -#define STORE_ATTR_INSTANCE_VALUE 168 -#define STORE_ATTR_SLOT 169 -#define STORE_ATTR_WITH_HINT 170 -#define STORE_FAST__LOAD_FAST 173 -#define STORE_FAST__STORE_FAST 174 -#define STORE_SUBSCR_ADAPTIVE 175 -#define STORE_SUBSCR_DICT 176 -#define STORE_SUBSCR_LIST_INT 177 -#define UNPACK_SEQUENCE_ADAPTIVE 178 -#define UNPACK_SEQUENCE_LIST 179 -#define UNPACK_SEQUENCE_TUPLE 180 -#define UNPACK_SEQUENCE_TWO_TUPLE 181 +#define LOAD_ATTR_ADAPTIVE 72 +#define LOAD_ATTR_CLASS 73 +#define LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN 76 +#define LOAD_ATTR_INSTANCE_VALUE 77 +#define LOAD_ATTR_MODULE 78 +#define LOAD_ATTR_PROPERTY 79 +#define LOAD_ATTR_SLOT 80 +#define LOAD_ATTR_WITH_HINT 81 +#define LOAD_ATTR_METHOD_LAZY_DICT 86 +#define LOAD_ATTR_METHOD_NO_DICT 113 +#define LOAD_ATTR_METHOD_WITH_DICT 121 +#define LOAD_ATTR_METHOD_WITH_VALUES 141 +#define LOAD_CONST__LOAD_FAST 143 +#define LOAD_FAST__LOAD_CONST 153 +#define LOAD_FAST__LOAD_FAST 154 +#define LOAD_GLOBAL_ADAPTIVE 158 +#define LOAD_GLOBAL_BUILTIN 159 +#define LOAD_GLOBAL_MODULE 160 +#define STORE_ATTR_ADAPTIVE 161 +#define STORE_ATTR_INSTANCE_VALUE 166 +#define STORE_ATTR_SLOT 167 +#define STORE_ATTR_WITH_HINT 168 +#define STORE_FAST__LOAD_FAST 169 +#define STORE_FAST__STORE_FAST 170 +#define STORE_SUBSCR_ADAPTIVE 173 +#define STORE_SUBSCR_DICT 174 +#define STORE_SUBSCR_LIST_INT 175 +#define UNPACK_SEQUENCE_ADAPTIVE 176 +#define UNPACK_SEQUENCE_LIST 177 +#define UNPACK_SEQUENCE_TUPLE 178 +#define UNPACK_SEQUENCE_TWO_TUPLE 179 #define DO_TRACING 255 #define HAS_ARG(op) ((((op) >= HAVE_ARGUMENT) && (!IS_PSEUDO_OPCODE(op)))\ diff --git a/Lib/opcode.py b/Lib/opcode.py index d655b0e..92921fe 100644 --- a/Lib/opcode.py +++ b/Lib/opcode.py @@ -327,9 +327,6 @@ _specializations = { "FOR_ITER_LIST", "FOR_ITER_RANGE", ], - "JUMP_BACKWARD": [ - "JUMP_BACKWARD_QUICK", - ], "LOAD_ATTR": [ "LOAD_ATTR_ADAPTIVE", # These potentially push [NULL, bound method] onto the stack. @@ -358,9 +355,6 @@ _specializations = { "LOAD_GLOBAL_BUILTIN", "LOAD_GLOBAL_MODULE", ], - "RESUME": [ - "RESUME_QUICK", - ], "STORE_ATTR": [ "STORE_ATTR_ADAPTIVE", "STORE_ATTR_INSTANCE_VALUE", diff --git a/Lib/test/libregrtest/refleak.py b/Lib/test/libregrtest/refleak.py index a0538cb..4298fa8 100644 --- a/Lib/test/libregrtest/refleak.py +++ b/Lib/test/libregrtest/refleak.py @@ -73,7 +73,6 @@ def dash_R(ns, test_name, test_func): fd_deltas = [0] * repcount getallocatedblocks = sys.getallocatedblocks gettotalrefcount = sys.gettotalrefcount - _getquickenedcount = sys._getquickenedcount fd_count = os_helper.fd_count # initialize variables to make pyflakes quiet rc_before = alloc_before = fd_before = 0 @@ -93,7 +92,7 @@ def dash_R(ns, test_name, test_func): support.gc_collect() # Read memory statistics immediately after the garbage collection - alloc_after = getallocatedblocks() - _getquickenedcount() + alloc_after = getallocatedblocks() rc_after = gettotalrefcount() fd_after = fd_count() diff --git a/Lib/test/test_call.py b/Lib/test/test_call.py index d4ddb79..f148b5e 100644 --- a/Lib/test/test_call.py +++ b/Lib/test/test_call.py @@ -580,7 +580,7 @@ def testfunction_kw(self, *, kw): return self -QUICKENING_WARMUP_DELAY = 8 +ADAPTIVE_WARMUP_DELAY = 2 class TestPEP590(unittest.TestCase): @@ -771,7 +771,7 @@ class TestPEP590(unittest.TestCase): assert_equal(11, f(num)) function_setvectorcall(f) # make sure specializer is triggered by running > 50 times - for _ in range(10 * QUICKENING_WARMUP_DELAY): + for _ in range(10 * ADAPTIVE_WARMUP_DELAY): assert_equal("overridden", f(num)) def test_setvectorcall_load_attr_specialization_skip(self): @@ -787,7 +787,7 @@ class TestPEP590(unittest.TestCase): function_setvectorcall(X.__getattribute__) # make sure specialization doesn't trigger # when vectorcall is overridden - for _ in range(QUICKENING_WARMUP_DELAY): + for _ in range(ADAPTIVE_WARMUP_DELAY): assert_equal("overridden", x.a) def test_setvectorcall_load_attr_specialization_deopt(self): @@ -803,12 +803,12 @@ class TestPEP590(unittest.TestCase): assert_equal = self.assertEqual x = X() # trigger LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN specialization - for _ in range(QUICKENING_WARMUP_DELAY): + for _ in range(ADAPTIVE_WARMUP_DELAY): assert_equal("a", get_a(x)) function_setvectorcall(X.__getattribute__) # make sure specialized LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN # gets deopted due to overridden vectorcall - for _ in range(QUICKENING_WARMUP_DELAY): + for _ in range(ADAPTIVE_WARMUP_DELAY): assert_equal("overridden", get_a(x)) @requires_limited_api diff --git a/Lib/test/test_dis.py b/Lib/test/test_dis.py index c986a6b..0897d23 100644 --- a/Lib/test/test_dis.py +++ b/Lib/test/test_dis.py @@ -713,7 +713,7 @@ def load_test(x, y=0): return a, b dis_load_test_quickened_code = """\ -%3d 0 RESUME_QUICK 0 +%3d 0 RESUME 0 %3d 2 LOAD_FAST__LOAD_FAST 0 (x) 4 LOAD_FAST 1 (y) @@ -733,7 +733,7 @@ def loop_test(): load_test(i) dis_loop_test_quickened_code = """\ -%3d RESUME_QUICK 0 +%3d RESUME 0 %3d BUILD_LIST 0 LOAD_CONST 1 ((1, 2, 3)) @@ -748,7 +748,7 @@ dis_loop_test_quickened_code = """\ LOAD_FAST 0 (i) CALL_PY_WITH_DEFAULTS 1 POP_TOP - JUMP_BACKWARD_QUICK 17 (to 16) + JUMP_BACKWARD 17 (to 16) %3d >> END_FOR LOAD_CONST 0 (None) @@ -774,7 +774,7 @@ dis_extended_arg_quick_code = """\ """% (extended_arg_quick.__code__.co_firstlineno, extended_arg_quick.__code__.co_firstlineno + 1,) -QUICKENING_WARMUP_DELAY = 8 +ADAPTIVE_WARMUP_DELAY = 2 class DisTestBase(unittest.TestCase): "Common utilities for DisTests and TestDisTraceback" @@ -1079,7 +1079,7 @@ class DisTests(DisTestBase): check(dis_nested_2) @staticmethod - def code_quicken(f, times=QUICKENING_WARMUP_DELAY): + def code_quicken(f, times=ADAPTIVE_WARMUP_DELAY): for _ in range(times): f() @@ -1092,7 +1092,7 @@ class DisTests(DisTestBase): @cpython_only def test_binary_specialize(self): binary_op_quicken = """\ - 0 0 RESUME_QUICK 0 + 0 0 RESUME 0 1 2 LOAD_NAME 0 (a) 4 LOAD_NAME 1 (b) @@ -1110,7 +1110,7 @@ class DisTests(DisTestBase): self.do_disassembly_compare(got, binary_op_quicken % "BINARY_OP_ADD_UNICODE 0 (+)", True) binary_subscr_quicken = """\ - 0 0 RESUME_QUICK 0 + 0 0 RESUME 0 1 2 LOAD_NAME 0 (a) 4 LOAD_CONST 0 (0) @@ -1130,7 +1130,7 @@ class DisTests(DisTestBase): @cpython_only def test_load_attr_specialize(self): load_attr_quicken = """\ - 0 0 RESUME_QUICK 0 + 0 0 RESUME 0 1 2 LOAD_CONST 0 ('a') 4 LOAD_ATTR_SLOT 0 (__class__) @@ -1144,7 +1144,7 @@ class DisTests(DisTestBase): @cpython_only def test_call_specialize(self): call_quicken = """\ - 0 RESUME_QUICK 0 + 0 RESUME 0 1 PUSH_NULL LOAD_NAME 0 (str) @@ -1190,7 +1190,7 @@ class DisTests(DisTestBase): for quickened in (False, True): for adaptive in (False, True): with self.subTest(f"{quickened=}, {adaptive=}"): - if quickened and adaptive: + if adaptive: pattern = r"^(\w+: \d+)?$" else: pattern = r"^(\w+: 0)?$" @@ -1198,11 +1198,10 @@ class DisTests(DisTestBase): for cache in caches: self.assertRegex(cache, pattern) total_caches = 23 - empty_caches = 8 if adaptive and quickened else total_caches + empty_caches = 8 if adaptive else total_caches self.assertEqual(caches.count(""), empty_caches) self.assertEqual(len(caches), total_caches) - class DisWithFileTests(DisTests): # Run the tests again, using the file arg instead of print diff --git a/Lib/test/test_embed.py b/Lib/test/test_embed.py index fa9815c..f5cda15 100644 --- a/Lib/test/test_embed.py +++ b/Lib/test/test_embed.py @@ -346,33 +346,41 @@ class EmbeddingTests(EmbeddingTestsMixin, unittest.TestCase): out, err = self.run_embedded_interpreter("test_repeated_simple_init") self.assertEqual(out, 'Finalized\n' * INIT_LOOPS) - def test_quickened_static_code_gets_unquickened_at_Py_FINALIZE(self): + def test_specialized_static_code_gets_unspecialized_at_Py_FINALIZE(self): # https://github.com/python/cpython/issues/92031 - # Do these imports outside of the code string to avoid using - # importlib too much from within the code string, so that - # _handle_fromlist doesn't get quickened until we intend it to. - from dis import _all_opmap - resume = _all_opmap["RESUME"] - resume_quick = _all_opmap["RESUME_QUICK"] - from test.test_dis import QUICKENING_WARMUP_DELAY - - code = textwrap.dedent(f"""\ + code = textwrap.dedent("""\ + import dis import importlib._bootstrap + import opcode + import test.test_dis + + def is_specialized(f): + for instruction in dis.get_instructions(f, adaptive=True): + opname = instruction.opname + if ( + opname in opcode._specialized_instructions + # Exclude superinstructions: + and "__" not in opname + # Exclude adaptive instructions: + and not opname.endswith("_ADAPTIVE") + # Exclude "quick" instructions: + and not opname.endswith("_QUICK") + ): + return True + return False + func = importlib._bootstrap._handle_fromlist - code = func.__code__ - # Assert initially unquickened. - # Use sets to account for byte order. - if set(code._co_code_adaptive[:2]) != set([{resume}, 0]): - raise AssertionError() + # "copy" the code to un-specialize it: + func.__code__ = func.__code__.replace() + + assert not is_specialized(func), "specialized instructions found" - for i in range({QUICKENING_WARMUP_DELAY}): + for i in range(test.test_dis.ADAPTIVE_WARMUP_DELAY): func(importlib._bootstrap, ["x"], lambda *args: None) - # Assert quickening worked - if set(code._co_code_adaptive[:2]) != set([{resume_quick}, 0]): - raise AssertionError() + assert is_specialized(func), "no specialized instructions found" print("Tests passed") """) diff --git a/Lib/test/test_lltrace.py b/Lib/test/test_lltrace.py index 7cf8984..747666e 100644 --- a/Lib/test/test_lltrace.py +++ b/Lib/test/test_lltrace.py @@ -8,7 +8,7 @@ from test.support.script_helper import assert_python_ok def example(): x = [] - for i in range(1): + for i in range(0): x.append(i) x = "this is" y = "an example" @@ -75,7 +75,7 @@ class TestLLTrace(unittest.TestCase): self.assertIn('this is an example', stdout) # check that offsets match the output of dis.dis() - instr_map = {i.offset: i for i in dis.get_instructions(example)} + instr_map = {i.offset: i for i in dis.get_instructions(example, adaptive=True)} for line in stdout.splitlines(): offset, colon, opname_oparg = line.partition(":") if not colon: diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-10-16-13-26-46.gh-issue-98686.D9Gu_Q.rst b/Misc/NEWS.d/next/Core and Builtins/2022-10-16-13-26-46.gh-issue-98686.D9Gu_Q.rst new file mode 100644 index 0000000..b97c1f9 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2022-10-16-13-26-46.gh-issue-98686.D9Gu_Q.rst @@ -0,0 +1,2 @@ +Quicken all code objects, and specialize adaptive bytecode instructions more +aggressively. diff --git a/Objects/codeobject.c b/Objects/codeobject.c index 8920b1d..854611f 100644 --- a/Objects/codeobject.c +++ b/Objects/codeobject.c @@ -301,6 +301,8 @@ _PyCode_Validate(struct _PyCodeConstructor *con) return 0; } +extern void _PyCode_Quicken(PyCodeObject *code); + static void init_code(PyCodeObject *co, struct _PyCodeConstructor *con) { @@ -353,7 +355,6 @@ init_code(PyCodeObject *co, struct _PyCodeConstructor *con) co->co_extra = NULL; co->_co_cached = NULL; - co->co_warmup = QUICKENING_INITIAL_WARMUP_VALUE; co->_co_linearray_entry_size = 0; co->_co_linearray = NULL; memcpy(_PyCode_CODE(co), PyBytes_AS_STRING(con->code), @@ -364,6 +365,7 @@ init_code(PyCodeObject *co, struct _PyCodeConstructor *con) entry_point++; } co->_co_firsttraceable = entry_point; + _PyCode_Quicken(co); } static int @@ -1664,9 +1666,6 @@ code_dealloc(PyCodeObject *co) if (co->_co_linearray) { PyMem_Free(co->_co_linearray); } - if (co->co_warmup == 0) { - _Py_QuickenedCount--; - } PyObject_Free(co); } @@ -2224,13 +2223,9 @@ _PyCode_ConstantKey(PyObject *op) } void -_PyStaticCode_Dealloc(PyCodeObject *co) +_PyStaticCode_Fini(PyCodeObject *co) { - if (co->co_warmup == 0) { - _Py_QuickenedCount--; - } deopt_code(_PyCode_CODE(co), Py_SIZE(co)); - co->co_warmup = QUICKENING_INITIAL_WARMUP_VALUE; PyMem_Free(co->co_extra); if (co->_co_cached != NULL) { Py_CLEAR(co->_co_cached->_co_code); @@ -2252,7 +2247,7 @@ _PyStaticCode_Dealloc(PyCodeObject *co) } int -_PyStaticCode_InternStrings(PyCodeObject *co) +_PyStaticCode_Init(PyCodeObject *co) { int res = intern_strings(co->co_names); if (res < 0) { @@ -2266,5 +2261,6 @@ _PyStaticCode_InternStrings(PyCodeObject *co) if (res < 0) { return -1; } + _PyCode_Quicken(co); return 0; } diff --git a/Objects/frameobject.c b/Objects/frameobject.c index dd69207..1f1228b 100644 --- a/Objects/frameobject.c +++ b/Objects/frameobject.c @@ -603,7 +603,7 @@ _PyFrame_GetState(PyFrameObject *frame) if (_PyInterpreterFrame_LASTI(frame->f_frame) < 0) { return FRAME_CREATED; } - switch (_PyOpcode_Deopt[_Py_OPCODE(*frame->f_frame->prev_instr)]) + switch (_Py_OPCODE(*frame->f_frame->prev_instr)) { case COPY_FREE_VARS: case MAKE_CELL: diff --git a/Objects/genobject.c b/Objects/genobject.c index ad4fbed..c62fb62 100644 --- a/Objects/genobject.c +++ b/Objects/genobject.c @@ -8,7 +8,6 @@ #include "pycore_frame.h" // _PyInterpreterFrame #include "pycore_genobject.h" // struct _Py_async_gen_state #include "pycore_object.h" // _PyObject_GC_UNTRACK() -#include "pycore_opcode.h" // _PyOpcode_Deopt #include "pycore_pyerrors.h" // _PyErr_ClearExcState() #include "pycore_pystate.h" // _PyThreadState_GET() #include "structmember.h" // PyMemberDef @@ -364,7 +363,7 @@ _PyGen_yf(PyGenObject *gen) return NULL; } _Py_CODEUNIT next = frame->prev_instr[1]; - if (_PyOpcode_Deopt[_Py_OPCODE(next)] != RESUME || _Py_OPARG(next) < 2) + if (_Py_OPCODE(next) != RESUME || _Py_OPARG(next) < 2) { /* Not in a yield from */ return NULL; diff --git a/Python/ceval.c b/Python/ceval.c index 100aa3d..2b42c68 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -143,7 +143,7 @@ lltrace_instruction(_PyInterpreterFrame *frame, const char *opname = _PyOpcode_OpName[opcode]; assert(opname != NULL); int offset = (int)(next_instr - _PyCode_CODE(frame->f_code)); - if (HAS_ARG(opcode)) { + if (HAS_ARG(_PyOpcode_Deopt[opcode])) { printf("%d: %s %d\n", offset * 2, opname, oparg); } else { @@ -1165,14 +1165,7 @@ handle_eval_breaker: TARGET(NOP) { DISPATCH(); } - TARGET(RESUME) { - _PyCode_Warmup(frame->f_code); - GO_TO_INSTRUCTION(RESUME_QUICK); - } - - TARGET(RESUME_QUICK) { - PREDICTED(RESUME_QUICK); assert(tstate->cframe == &cframe); assert(frame == cframe.current_frame); if (_Py_atomic_load_relaxed_int32(eval_breaker) && oparg < 2) { @@ -1710,7 +1703,7 @@ handle_eval_breaker: PyObject *list = PEEK(oparg); if (_PyList_AppendTakeRef((PyListObject *)list, v) < 0) goto error; - PREDICT(JUMP_BACKWARD_QUICK); + PREDICT(JUMP_BACKWARD); DISPATCH(); } @@ -1722,7 +1715,7 @@ handle_eval_breaker: Py_DECREF(v); if (err != 0) goto error; - PREDICT(JUMP_BACKWARD_QUICK); + PREDICT(JUMP_BACKWARD); DISPATCH(); } @@ -2908,7 +2901,7 @@ handle_eval_breaker: if (_PyDict_SetItem_Take2((PyDictObject *)map, key, value) != 0) { goto error; } - PREDICT(JUMP_BACKWARD_QUICK); + PREDICT(JUMP_BACKWARD); DISPATCH(); } @@ -3576,8 +3569,11 @@ handle_eval_breaker: } TARGET(JUMP_BACKWARD) { - _PyCode_Warmup(frame->f_code); - GO_TO_INSTRUCTION(JUMP_BACKWARD_QUICK); + PREDICTED(JUMP_BACKWARD); + assert(oparg < INSTR_OFFSET()); + JUMPBY(-oparg); + CHECK_EVAL_BREAKER(); + DISPATCH(); } TARGET(POP_JUMP_IF_FALSE) { @@ -3707,14 +3703,6 @@ handle_eval_breaker: DISPATCH(); } - TARGET(JUMP_BACKWARD_QUICK) { - PREDICTED(JUMP_BACKWARD_QUICK); - assert(oparg < INSTR_OFFSET()); - JUMPBY(-oparg); - CHECK_EVAL_BREAKER(); - DISPATCH(); - } - TARGET(GET_LEN) { // PUSH(len(TOS)) Py_ssize_t len_i = PyObject_Length(TOP()); diff --git a/Python/clinic/sysmodule.c.h b/Python/clinic/sysmodule.c.h index 3dc7aa8..5678d0a 100644 --- a/Python/clinic/sysmodule.c.h +++ b/Python/clinic/sysmodule.c.h @@ -884,33 +884,6 @@ exit: #endif /* defined(Py_REF_DEBUG) */ -PyDoc_STRVAR(sys__getquickenedcount__doc__, -"_getquickenedcount($module, /)\n" -"--\n" -"\n"); - -#define SYS__GETQUICKENEDCOUNT_METHODDEF \ - {"_getquickenedcount", (PyCFunction)sys__getquickenedcount, METH_NOARGS, sys__getquickenedcount__doc__}, - -static Py_ssize_t -sys__getquickenedcount_impl(PyObject *module); - -static PyObject * -sys__getquickenedcount(PyObject *module, PyObject *Py_UNUSED(ignored)) -{ - PyObject *return_value = NULL; - Py_ssize_t _return_value; - - _return_value = sys__getquickenedcount_impl(module); - if ((_return_value == -1) && PyErr_Occurred()) { - goto exit; - } - return_value = PyLong_FromSsize_t(_return_value); - -exit: - return return_value; -} - PyDoc_STRVAR(sys_getallocatedblocks__doc__, "getallocatedblocks($module, /)\n" "--\n" @@ -1345,4 +1318,4 @@ sys_is_stack_trampoline_active(PyObject *module, PyObject *Py_UNUSED(ignored)) #ifndef SYS_GETANDROIDAPILEVEL_METHODDEF #define SYS_GETANDROIDAPILEVEL_METHODDEF #endif /* !defined(SYS_GETANDROIDAPILEVEL_METHODDEF) */ -/*[clinic end generated code: output=2b5e1bc24a3348bd input=a9049054013a1b77]*/ +/*[clinic end generated code: output=79228e569529129c input=a9049054013a1b77]*/ diff --git a/Python/opcode_targets.h b/Python/opcode_targets.h index 53b2770..9004bba 100644 --- a/Python/opcode_targets.h +++ b/Python/opcode_targets.h @@ -71,21 +71,21 @@ static void *opcode_targets[256] = { &&TARGET_GET_YIELD_FROM_ITER, &&TARGET_PRINT_EXPR, &&TARGET_LOAD_BUILD_CLASS, - &&TARGET_JUMP_BACKWARD_QUICK, &&TARGET_LOAD_ATTR_ADAPTIVE, + &&TARGET_LOAD_ATTR_CLASS, &&TARGET_LOAD_ASSERTION_ERROR, &&TARGET_RETURN_GENERATOR, - &&TARGET_LOAD_ATTR_CLASS, &&TARGET_LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN, &&TARGET_LOAD_ATTR_INSTANCE_VALUE, &&TARGET_LOAD_ATTR_MODULE, &&TARGET_LOAD_ATTR_PROPERTY, &&TARGET_LOAD_ATTR_SLOT, + &&TARGET_LOAD_ATTR_WITH_HINT, &&TARGET_LIST_TO_TUPLE, &&TARGET_RETURN_VALUE, &&TARGET_IMPORT_STAR, &&TARGET_SETUP_ANNOTATIONS, - &&TARGET_LOAD_ATTR_WITH_HINT, + &&TARGET_LOAD_ATTR_METHOD_LAZY_DICT, &&TARGET_ASYNC_GEN_WRAP, &&TARGET_PREP_RERAISE_STAR, &&TARGET_POP_EXCEPT, @@ -112,7 +112,7 @@ static void *opcode_targets[256] = { &&TARGET_JUMP_FORWARD, &&TARGET_JUMP_IF_FALSE_OR_POP, &&TARGET_JUMP_IF_TRUE_OR_POP, - &&TARGET_LOAD_ATTR_METHOD_LAZY_DICT, + &&TARGET_LOAD_ATTR_METHOD_NO_DICT, &&TARGET_POP_JUMP_IF_FALSE, &&TARGET_POP_JUMP_IF_TRUE, &&TARGET_LOAD_GLOBAL, @@ -120,7 +120,7 @@ static void *opcode_targets[256] = { &&TARGET_CONTAINS_OP, &&TARGET_RERAISE, &&TARGET_COPY, - &&TARGET_LOAD_ATTR_METHOD_NO_DICT, + &&TARGET_LOAD_ATTR_METHOD_WITH_DICT, &&TARGET_BINARY_OP, &&TARGET_SEND, &&TARGET_LOAD_FAST, @@ -140,9 +140,9 @@ static void *opcode_targets[256] = { &&TARGET_STORE_DEREF, &&TARGET_DELETE_DEREF, &&TARGET_JUMP_BACKWARD, - &&TARGET_LOAD_ATTR_METHOD_WITH_DICT, - &&TARGET_CALL_FUNCTION_EX, &&TARGET_LOAD_ATTR_METHOD_WITH_VALUES, + &&TARGET_CALL_FUNCTION_EX, + &&TARGET_LOAD_CONST__LOAD_FAST, &&TARGET_EXTENDED_ARG, &&TARGET_LIST_APPEND, &&TARGET_SET_ADD, @@ -152,28 +152,26 @@ static void *opcode_targets[256] = { &&TARGET_YIELD_VALUE, &&TARGET_RESUME, &&TARGET_MATCH_CLASS, - &&TARGET_LOAD_CONST__LOAD_FAST, &&TARGET_LOAD_FAST__LOAD_CONST, + &&TARGET_LOAD_FAST__LOAD_FAST, &&TARGET_FORMAT_VALUE, &&TARGET_BUILD_CONST_KEY_MAP, &&TARGET_BUILD_STRING, - &&TARGET_LOAD_FAST__LOAD_FAST, &&TARGET_LOAD_GLOBAL_ADAPTIVE, &&TARGET_LOAD_GLOBAL_BUILTIN, &&TARGET_LOAD_GLOBAL_MODULE, + &&TARGET_STORE_ATTR_ADAPTIVE, &&TARGET_LIST_EXTEND, &&TARGET_SET_UPDATE, &&TARGET_DICT_MERGE, &&TARGET_DICT_UPDATE, - &&TARGET_RESUME_QUICK, - &&TARGET_STORE_ATTR_ADAPTIVE, &&TARGET_STORE_ATTR_INSTANCE_VALUE, &&TARGET_STORE_ATTR_SLOT, &&TARGET_STORE_ATTR_WITH_HINT, - &&TARGET_CALL, - &&TARGET_KW_NAMES, &&TARGET_STORE_FAST__LOAD_FAST, &&TARGET_STORE_FAST__STORE_FAST, + &&TARGET_CALL, + &&TARGET_KW_NAMES, &&TARGET_STORE_SUBSCR_ADAPTIVE, &&TARGET_STORE_SUBSCR_DICT, &&TARGET_STORE_SUBSCR_LIST_INT, @@ -254,5 +252,7 @@ static void *opcode_targets[256] = { &&_unknown_opcode, &&_unknown_opcode, &&_unknown_opcode, + &&_unknown_opcode, + &&_unknown_opcode, &&TARGET_DO_TRACING }; diff --git a/Python/specialize.c b/Python/specialize.c index 6e2fa4e..70a456c 100644 --- a/Python/specialize.c +++ b/Python/specialize.c @@ -31,7 +31,6 @@ uint8_t _PyOpcode_Adaptive[256] = { [FOR_ITER] = FOR_ITER_ADAPTIVE, }; -Py_ssize_t _Py_QuickenedCount = 0; #ifdef Py_STATS PyStats _py_stats_struct = { 0 }; PyStats *_py_stats = &_py_stats_struct; @@ -280,16 +279,14 @@ do { \ void _PyCode_Quicken(PyCodeObject *code) { - _Py_QuickenedCount++; int previous_opcode = -1; _Py_CODEUNIT *instructions = _PyCode_CODE(code); for (int i = 0; i < Py_SIZE(code); i++) { - int opcode = _Py_OPCODE(instructions[i]); + int opcode = _PyOpcode_Deopt[_Py_OPCODE(instructions[i])]; uint8_t adaptive_opcode = _PyOpcode_Adaptive[opcode]; if (adaptive_opcode) { _Py_SET_OPCODE(instructions[i], adaptive_opcode); - // Make sure the adaptive counter is zero: - assert(instructions[i + 1] == 0); + instructions[i + 1] = adaptive_counter_start(); previous_opcode = -1; i += _PyOpcode_Caches[opcode]; } @@ -299,12 +296,6 @@ _PyCode_Quicken(PyCodeObject *code) case EXTENDED_ARG: _Py_SET_OPCODE(instructions[i], EXTENDED_ARG_QUICK); break; - case JUMP_BACKWARD: - _Py_SET_OPCODE(instructions[i], JUMP_BACKWARD_QUICK); - break; - case RESUME: - _Py_SET_OPCODE(instructions[i], RESUME_QUICK); - break; case LOAD_FAST: switch(previous_opcode) { case LOAD_FAST: diff --git a/Python/sysmodule.c b/Python/sysmodule.c index f73d332..55cd059 100644 --- a/Python/sysmodule.c +++ b/Python/sysmodule.c @@ -17,7 +17,6 @@ Data members: #include "Python.h" #include "pycore_call.h" // _PyObject_CallNoArgs() #include "pycore_ceval.h" // _PyEval_SetAsyncGenFinalizer() -#include "pycore_code.h" // _Py_QuickenedCount #include "pycore_frame.h" // _PyInterpreterFrame #include "pycore_initconfig.h" // _PyStatus_EXCEPTION() #include "pycore_long.h" // _PY_LONG_MAX_STR_DIGITS_THRESHOLD @@ -1856,17 +1855,6 @@ sys_gettotalrefcount_impl(PyObject *module) #endif /* Py_REF_DEBUG */ /*[clinic input] -sys._getquickenedcount -> Py_ssize_t -[clinic start generated code]*/ - -static Py_ssize_t -sys__getquickenedcount_impl(PyObject *module) -/*[clinic end generated code: output=1ab259e7f91248a2 input=249d448159eca912]*/ -{ - return _Py_QuickenedCount; -} - -/*[clinic input] sys.getallocatedblocks -> Py_ssize_t Return the number of memory blocks currently allocated. @@ -2216,7 +2204,6 @@ static PyMethodDef sys_methods[] = { SYS_GETALLOCATEDBLOCKS_METHODDEF SYS_GETFILESYSTEMENCODING_METHODDEF SYS_GETFILESYSTEMENCODEERRORS_METHODDEF - SYS__GETQUICKENEDCOUNT_METHODDEF #ifdef Py_TRACE_REFS {"getobjects", _Py_GetObjects, METH_VARARGS}, #endif diff --git a/Tools/build/deepfreeze.py b/Tools/build/deepfreeze.py index 28ac2b1..2eef649 100644 --- a/Tools/build/deepfreeze.py +++ b/Tools/build/deepfreeze.py @@ -114,9 +114,8 @@ class Printer: self.file = file self.cache: Dict[tuple[type, object, str], str] = {} self.hits, self.misses = 0, 0 - self.patchups: list[str] = [] - self.deallocs: list[str] = [] - self.interns: list[str] = [] + self.finis: list[str] = [] + self.inits: list[str] = [] self.write('#include "Python.h"') self.write('#include "internal/pycore_gc.h"') self.write('#include "internal/pycore_code.h"') @@ -257,7 +256,6 @@ class Printer: self.write(f".co_names = {co_names},") self.write(f".co_exceptiontable = {co_exceptiontable},") self.field(code, "co_flags") - self.write(".co_warmup = QUICKENING_INITIAL_WARMUP_VALUE,") self.write("._co_linearray_entry_size = 0,") self.field(code, "co_argcount") self.field(code, "co_posonlyargcount") @@ -284,8 +282,8 @@ class Printer: self.write(f"._co_firsttraceable = {i},") break name_as_code = f"(PyCodeObject *)&{name}" - self.deallocs.append(f"_PyStaticCode_Dealloc({name_as_code});") - self.interns.append(f"_PyStaticCode_InternStrings({name_as_code})") + self.finis.append(f"_PyStaticCode_Fini({name_as_code});") + self.inits.append(f"_PyStaticCode_Init({name_as_code})") return f"& {name}.ob_base.ob_base" def generate_tuple(self, name: str, t: Tuple[object, ...]) -> str: @@ -373,11 +371,7 @@ class Printer: def generate_file(self, module: str, code: object)-> None: module = module.replace(".", "_") self.generate(f"{module}_toplevel", code) - with self.block(f"static void {module}_do_patchups(void)"): - for p in self.patchups: - self.write(p) - self.patchups.clear() - self.write(EPILOGUE.replace("%%NAME%%", module)) + self.write(EPILOGUE.format(name=module)) def generate(self, name: str, obj: object) -> str: # Use repr() in the key to distinguish -0.0 from +0.0 @@ -421,11 +415,10 @@ class Printer: EPILOGUE = """ PyObject * -_Py_get_%%NAME%%_toplevel(void) -{ - %%NAME%%_do_patchups(); - return Py_NewRef((PyObject *) &%%NAME%%_toplevel); -} +_Py_get_{name}_toplevel(void) +{{ + return Py_NewRef((PyObject *) &{name}_toplevel); +}} """ FROZEN_COMMENT_C = "/* Auto-generated by Programs/_freeze_module.c */" @@ -461,10 +454,10 @@ def generate(args: list[str], output: TextIO) -> None: code = compile(fd.read(), f"<frozen {modname}>", "exec") printer.generate_file(modname, code) with printer.block(f"void\n_Py_Deepfreeze_Fini(void)"): - for p in printer.deallocs: + for p in printer.finis: printer.write(p) with printer.block(f"int\n_Py_Deepfreeze_Init(void)"): - for p in printer.interns: + for p in printer.inits: with printer.block(f"if ({p} < 0)"): printer.write("return -1;") printer.write("return 0;") diff --git a/Tools/c-analyzer/cpython/globals-to-fix.tsv b/Tools/c-analyzer/cpython/globals-to-fix.tsv index e327f0a..56e499d 100644 --- a/Tools/c-analyzer/cpython/globals-to-fix.tsv +++ b/Tools/c-analyzer/cpython/globals-to-fix.tsv @@ -477,7 +477,6 @@ Python/pyfpe.c - PyFPE_counter - Python/pylifecycle.c _Py_FatalErrorFormat reentrant - Python/pylifecycle.c - _Py_UnhandledKeyboardInterrupt - Python/pylifecycle.c fatal_error reentrant - -Python/specialize.c - _Py_QuickenedCount - ################################## |