diff --git a/Lib/test/test_capi/test_misc.py b/Lib/test/test_capi/test_misc.py index fd27bd06097f6a..9cbd5506bf6dea 100644 --- a/Lib/test/test_capi/test_misc.py +++ b/Lib/test/test_capi/test_misc.py @@ -2525,7 +2525,6 @@ def testfunc(n): i += 1 opt = _testinternalcapi.get_uop_optimizer() - with temporary_optimizer(opt): testfunc(10) @@ -2541,7 +2540,6 @@ def testfunc(n): i += 1 opt = _testinternalcapi.get_uop_optimizer() - with temporary_optimizer(opt): testfunc(10) @@ -2550,6 +2548,20 @@ def testfunc(n): uops = {opname for opname, _ in ex} self.assertIn("_POP_JUMP_IF_TRUE", uops) + def test_jump_backward(self): + def testfunc(n): + i = 0 + while i < n: + i += 1 + opt = _testinternalcapi.get_uop_optimizer() + with temporary_optimizer(opt): + testfunc(10) + + ex = get_first_executor(testfunc) + self.assertIsNotNone(ex) + uops = {opname for opname, _ in ex} + self.assertIn("JUMP_TO_TOP", uops) + if __name__ == "__main__": unittest.main() diff --git a/Python/ceval.c b/Python/ceval.c index 866acd2dd69c7e..57e478c1313f64 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -2783,6 +2783,13 @@ _PyUopExecute(_PyExecutorObject *executor, _PyInterpreterFrame *frame, PyObject break; } + case JUMP_TO_TOP: + { + pc = 0; + CHECK_EVAL_BREAKER(); + break; + } + case SAVE_IP: { frame->prev_instr = ip_offset + oparg; diff --git a/Python/opcode_metadata.h b/Python/opcode_metadata.h index 34ac85d6517a88..4a41cd86a4287b 100644 --- a/Python/opcode_metadata.h +++ b/Python/opcode_metadata.h @@ -23,19 +23,20 @@ #define SAVE_IP 301 #define _POP_JUMP_IF_FALSE 302 #define _POP_JUMP_IF_TRUE 303 -#define _GUARD_BOTH_INT 304 -#define _BINARY_OP_MULTIPLY_INT 305 -#define _BINARY_OP_ADD_INT 306 -#define _BINARY_OP_SUBTRACT_INT 307 -#define _GUARD_BOTH_FLOAT 308 -#define _BINARY_OP_MULTIPLY_FLOAT 309 -#define _BINARY_OP_ADD_FLOAT 310 -#define _BINARY_OP_SUBTRACT_FLOAT 311 -#define _GUARD_BOTH_UNICODE 312 -#define _BINARY_OP_ADD_UNICODE 313 -#define _LOAD_LOCALS 314 -#define _LOAD_FROM_DICT_OR_GLOBALS 315 -#define IS_NONE 316 +#define JUMP_TO_TOP 304 +#define _GUARD_BOTH_INT 305 +#define _BINARY_OP_MULTIPLY_INT 306 +#define _BINARY_OP_ADD_INT 307 +#define _BINARY_OP_SUBTRACT_INT 308 +#define _GUARD_BOTH_FLOAT 309 +#define _BINARY_OP_MULTIPLY_FLOAT 310 +#define _BINARY_OP_ADD_FLOAT 311 +#define _BINARY_OP_SUBTRACT_FLOAT 312 +#define _GUARD_BOTH_UNICODE 313 +#define _BINARY_OP_ADD_UNICODE 314 +#define _LOAD_LOCALS 315 +#define _LOAD_FROM_DICT_OR_GLOBALS 316 +#define IS_NONE 317 #ifndef NEED_OPCODE_METADATA extern int _PyOpcode_num_popped(int opcode, int oparg, bool jump); @@ -1298,18 +1299,19 @@ const char * const _PyOpcode_uop_name[512] = { [301] = "SAVE_IP", [302] = "_POP_JUMP_IF_FALSE", [303] = "_POP_JUMP_IF_TRUE", - [304] = "_GUARD_BOTH_INT", - [305] = "_BINARY_OP_MULTIPLY_INT", - [306] = "_BINARY_OP_ADD_INT", - [307] = "_BINARY_OP_SUBTRACT_INT", - [308] = "_GUARD_BOTH_FLOAT", - [309] = "_BINARY_OP_MULTIPLY_FLOAT", - [310] = "_BINARY_OP_ADD_FLOAT", - [311] = "_BINARY_OP_SUBTRACT_FLOAT", - [312] = "_GUARD_BOTH_UNICODE", - [313] = "_BINARY_OP_ADD_UNICODE", - [314] = "_LOAD_LOCALS", - [315] = "_LOAD_FROM_DICT_OR_GLOBALS", - [316] = "IS_NONE", + [304] = "JUMP_TO_TOP", + [305] = "_GUARD_BOTH_INT", + [306] = "_BINARY_OP_MULTIPLY_INT", + [307] = "_BINARY_OP_ADD_INT", + [308] = "_BINARY_OP_SUBTRACT_INT", + [309] = "_GUARD_BOTH_FLOAT", + [310] = "_BINARY_OP_MULTIPLY_FLOAT", + [311] = "_BINARY_OP_ADD_FLOAT", + [312] = "_BINARY_OP_SUBTRACT_FLOAT", + [313] = "_GUARD_BOTH_UNICODE", + [314] = "_BINARY_OP_ADD_UNICODE", + [315] = "_LOAD_LOCALS", + [316] = "_LOAD_FROM_DICT_OR_GLOBALS", + [317] = "IS_NONE", }; #endif // NEED_OPCODE_METADATA diff --git a/Python/optimizer.c b/Python/optimizer.c index 08073193c0228f..8d4162b44c2f35 100644 --- a/Python/optimizer.c +++ b/Python/optimizer.c @@ -372,9 +372,7 @@ translate_bytecode_to_trace( _PyUOpInstruction *trace, int buffer_size) { -#ifdef Py_DEBUG _Py_CODEUNIT *initial_instr = instr; -#endif int trace_length = 0; int max_length = buffer_size; @@ -456,6 +454,19 @@ translate_bytecode_to_trace( break; } + case JUMP_BACKWARD: + { + if (instr + 2 - oparg == initial_instr + && trace_length + 3 <= max_length) + { + ADD_TO_TRACE(JUMP_TO_TOP, 0); + } + else { + DPRINTF(2, "JUMP_BACKWARD not to top ends trace\n"); + } + goto done; + } + default: { const struct opcode_macro_expansion *expansion = &_PyOpcode_macro_expansion[opcode]; diff --git a/Tools/cases_generator/generate_cases.py b/Tools/cases_generator/generate_cases.py index 641a327b06aa22..8c77c1f08335df 100644 --- a/Tools/cases_generator/generate_cases.py +++ b/Tools/cases_generator/generate_cases.py @@ -1346,6 +1346,7 @@ def add(name: str) -> None: add("SAVE_IP") add("_POP_JUMP_IF_FALSE") add("_POP_JUMP_IF_TRUE") + add("JUMP_TO_TOP") for instr in self.instrs.values(): if instr.kind == "op" and instr.is_viable_uop(): pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy