From 54aad59bee9fb6dc367e55d7f3484bb74c1a7938 Mon Sep 17 00:00:00 2001 From: Irit Katriel Date: Wed, 14 Jun 2023 16:34:07 +0100 Subject: [PATCH] gh-105481: add HAS_JUMP flag to opcode metadata --- Include/internal/pycore_opcode_utils.h | 4 +- Python/bytecodes.c | 34 +-- Python/ceval_macros.h | 6 + Python/compile.c | 3 +- Python/flowgraph.c | 3 +- Python/generated_cases.c.h | 264 ++++++++++++------------ Python/opcode_metadata.h | 30 +-- Tools/cases_generator/generate_cases.py | 3 +- 8 files changed, 183 insertions(+), 164 deletions(-) diff --git a/Include/internal/pycore_opcode_utils.h b/Include/internal/pycore_opcode_utils.h index 5ab31e6588536d..d80b3c1c20b149 100644 --- a/Include/internal/pycore_opcode_utils.h +++ b/Include/internal/pycore_opcode_utils.h @@ -26,11 +26,11 @@ extern "C" { (opcode) == SETUP_CLEANUP) #define HAS_TARGET(opcode) \ - (IS_JUMP_OPCODE(opcode) || IS_BLOCK_PUSH_OPCODE(opcode)) + (OPCODE_HAS_JUMP(opcode) || IS_BLOCK_PUSH_OPCODE(opcode)) /* opcodes that must be last in the basicblock */ #define IS_TERMINATOR_OPCODE(opcode) \ - (IS_JUMP_OPCODE(opcode) || IS_SCOPE_EXIT_OPCODE(opcode)) + (OPCODE_HAS_JUMP(opcode) || IS_SCOPE_EXIT_OPCODE(opcode)) /* opcodes which are not emitted in codegen stage, only by the assembler */ #define IS_ASSEMBLER_OPCODE(opcode) \ diff --git a/Python/bytecodes.c b/Python/bytecodes.c index 78e276bfad20e7..d324261667a351 100644 --- a/Python/bytecodes.c +++ b/Python/bytecodes.c @@ -428,7 +428,7 @@ dummy_func( _Py_DECREF_SPECIALIZED(right, _PyUnicode_ExactDealloc); ERROR_IF(*target_local == NULL, error); // The STORE_FAST is already done. - JUMPBY(INLINE_CACHE_ENTRIES_BINARY_OP + 1); + SKIP_OVER(INLINE_CACHE_ENTRIES_BINARY_OP + 1); } macro(BINARY_OP_INPLACE_ADD_UNICODE) = @@ -555,7 +555,7 @@ dummy_func( STACK_SHRINK(2); new_frame->localsplus[0] = container; new_frame->localsplus[1] = sub; - JUMPBY(INLINE_CACHE_ENTRIES_BINARY_SUBSCR); + SKIP_OVER(INLINE_CACHE_ENTRIES_BINARY_SUBSCR); frame->return_offset = 0; DISPATCH_INLINED(new_frame); } @@ -877,7 +877,7 @@ dummy_func( gen->gi_frame_state = FRAME_EXECUTING; gen->gi_exc_state.previous_item = tstate->exc_info; tstate->exc_info = &gen->gi_exc_state; - JUMPBY(INLINE_CACHE_ENTRIES_SEND); + SKIP_OVER(INLINE_CACHE_ENTRIES_SEND); DISPATCH_INLINED(gen_frame); } if (Py_IsNone(v) && PyIter_Check(receiver)) { @@ -916,7 +916,7 @@ dummy_func( gen->gi_frame_state = FRAME_EXECUTING; gen->gi_exc_state.previous_item = tstate->exc_info; tstate->exc_info = &gen->gi_exc_state; - JUMPBY(INLINE_CACHE_ENTRIES_SEND); + SKIP_OVER(INLINE_CACHE_ENTRIES_SEND); DISPATCH_INLINED(gen_frame); } @@ -1903,7 +1903,7 @@ dummy_func( int shrink_stack = !(oparg & 1); STACK_SHRINK(shrink_stack); new_frame->localsplus[0] = owner; - JUMPBY(INLINE_CACHE_ENTRIES_LOAD_ATTR); + SKIP_OVER(INLINE_CACHE_ENTRIES_LOAD_ATTR); frame->return_offset = 0; DISPATCH_INLINED(new_frame); } @@ -1931,7 +1931,7 @@ dummy_func( STACK_SHRINK(shrink_stack); new_frame->localsplus[0] = owner; new_frame->localsplus[1] = Py_NewRef(name); - JUMPBY(INLINE_CACHE_ENTRIES_LOAD_ATTR); + SKIP_OVER(INLINE_CACHE_ENTRIES_LOAD_ATTR); frame->return_offset = 0; DISPATCH_INLINED(new_frame); } @@ -2354,8 +2354,9 @@ dummy_func( next_instr[INLINE_CACHE_ENTRIES_FOR_ITER + oparg].op.code == INSTRUMENTED_END_FOR); Py_DECREF(iter); STACK_SHRINK(1); + SKIP_OVER(INLINE_CACHE_ENTRIES_FOR_ITER); /* Jump forward oparg, then skip following END_FOR instruction */ - JUMPBY(INLINE_CACHE_ENTRIES_FOR_ITER + oparg + 1); + JUMPBY(oparg + 1); DISPATCH(); } // Common case: no jump, leave it to the code generator @@ -2404,8 +2405,9 @@ dummy_func( } Py_DECREF(iter); STACK_SHRINK(1); + SKIP_OVER(INLINE_CACHE_ENTRIES_FOR_ITER); /* Jump forward oparg, then skip following END_FOR instruction */ - JUMPBY(INLINE_CACHE_ENTRIES_FOR_ITER + oparg + 1); + JUMPBY(oparg + 1); DISPATCH(); end_for_iter_list: // Common case: no jump, leave it to the code generator @@ -2426,8 +2428,9 @@ dummy_func( } Py_DECREF(iter); STACK_SHRINK(1); + SKIP_OVER(INLINE_CACHE_ENTRIES_FOR_ITER); /* Jump forward oparg, then skip following END_FOR instruction */ - JUMPBY(INLINE_CACHE_ENTRIES_FOR_ITER + oparg + 1); + JUMPBY(oparg + 1); DISPATCH(); end_for_iter_tuple: // Common case: no jump, leave it to the code generator @@ -2440,8 +2443,9 @@ dummy_func( if (r->len <= 0) { STACK_SHRINK(1); Py_DECREF(r); + SKIP_OVER(INLINE_CACHE_ENTRIES_FOR_ITER); // Jump over END_FOR instruction. - JUMPBY(INLINE_CACHE_ENTRIES_FOR_ITER + oparg + 1); + JUMPBY(oparg + 1); DISPATCH(); } long value = r->start; @@ -2465,7 +2469,7 @@ dummy_func( gen->gi_frame_state = FRAME_EXECUTING; gen->gi_exc_state.previous_item = tstate->exc_info; tstate->exc_info = &gen->gi_exc_state; - JUMPBY(INLINE_CACHE_ENTRIES_FOR_ITER); + SKIP_OVER(INLINE_CACHE_ENTRIES_FOR_ITER); assert(next_instr[oparg].op.code == END_FOR || next_instr[oparg].op.code == INSTRUMENTED_END_FOR); DISPATCH_INLINED(gen_frame); @@ -2736,7 +2740,7 @@ dummy_func( if (new_frame == NULL) { goto error; } - JUMPBY(INLINE_CACHE_ENTRIES_CALL); + SKIP_OVER(INLINE_CACHE_ENTRIES_CALL); frame->return_offset = 0; DISPATCH_INLINED(new_frame); } @@ -2810,7 +2814,7 @@ dummy_func( } // Manipulate stack directly since we leave using DISPATCH_INLINED(). STACK_SHRINK(oparg + 2); - JUMPBY(INLINE_CACHE_ENTRIES_CALL); + SKIP_OVER(INLINE_CACHE_ENTRIES_CALL); frame->return_offset = 0; DISPATCH_INLINED(new_frame); } @@ -2848,7 +2852,7 @@ dummy_func( } // Manipulate stack and cache directly since we leave using DISPATCH_INLINED(). STACK_SHRINK(oparg + 2); - JUMPBY(INLINE_CACHE_ENTRIES_CALL); + SKIP_OVER(INLINE_CACHE_ENTRIES_CALL); frame->return_offset = 0; DISPATCH_INLINED(new_frame); } @@ -3091,7 +3095,7 @@ dummy_func( Py_DECREF(method); STACK_SHRINK(3); // CALL + POP_TOP - JUMPBY(INLINE_CACHE_ENTRIES_CALL + 1); + SKIP_OVER(INLINE_CACHE_ENTRIES_CALL + 1); assert(next_instr[-1].op.code == POP_TOP); DISPATCH(); } diff --git a/Python/ceval_macros.h b/Python/ceval_macros.h index 1130b10ef7638b..80e7b36e981326 100644 --- a/Python/ceval_macros.h +++ b/Python/ceval_macros.h @@ -145,7 +145,13 @@ GETITEM(PyObject *v, Py_ssize_t i) { oparg = word.op.arg; \ } while (0) #define JUMPTO(x) (next_instr = _PyCode_CODE(_PyFrame_GetCode(frame)) + (x)) + +/* JUMPBY makes the generator identify the instruction as a jump. SKIP_OVER is for + * advancing to the next instruction, taking into account cache entries and skipped + * instructions into account. + */ #define JUMPBY(x) (next_instr += (x)) +#define SKIP_OVER(x) (next_instr += (x)) /* OpCode prediction macros Some opcodes tend to come in pairs thus making it possible to diff --git a/Python/compile.c b/Python/compile.c index 399a702ac1d7eb..de9c62ed5abdfd 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -250,6 +250,7 @@ instr_sequence_addop(instr_sequence *seq, int opcode, int oparg, location loc) { assert(!HAS_ARG(opcode) == !OPCODE_HAS_ARG(opcode)); assert(!HAS_CONST(opcode) == !OPCODE_HAS_CONST(opcode)); + assert(!OPCODE_HAS_JUMP(opcode) == !OPCODE_HAS_JUMP(opcode)); assert(0 <= opcode && opcode <= MAX_OPCODE); assert(IS_PSEUDO_OPCODE(opcode) == IS_PSEUDO_INSTR(opcode)); assert(IS_WITHIN_OPCODE_RANGE(opcode)); @@ -1114,7 +1115,7 @@ codegen_addop_j(instr_sequence *seq, location loc, int opcode, jump_target_label target) { assert(IS_LABEL(target)); - assert(IS_JUMP_OPCODE(opcode) || IS_BLOCK_PUSH_OPCODE(opcode)); + assert(OPCODE_HAS_JUMP(opcode) || IS_BLOCK_PUSH_OPCODE(opcode)); assert(!IS_ASSEMBLER_OPCODE(opcode)); return instr_sequence_addop(seq, opcode, target.id, loc); } diff --git a/Python/flowgraph.c b/Python/flowgraph.c index 889eba40b14a2e..de5c5e7ecc38d6 100644 --- a/Python/flowgraph.c +++ b/Python/flowgraph.c @@ -45,7 +45,8 @@ is_block_push(cfg_instr *i) static inline int is_jump(cfg_instr *i) { - return IS_JUMP_OPCODE(i->i_opcode); + assert(!OPCODE_HAS_JUMP(i->i_opcode) == !IS_JUMP_OPCODE(i->i_opcode)); + return OPCODE_HAS_JUMP(i->i_opcode); } /* One arg*/ diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h index 008524ac95b69b..4800a87ba36770 100644 --- a/Python/generated_cases.c.h +++ b/Python/generated_cases.c.h @@ -566,7 +566,7 @@ _Py_DECREF_SPECIALIZED(right, _PyUnicode_ExactDealloc); if (*target_local == NULL) goto pop_2_error; // The STORE_FAST is already done. - JUMPBY(INLINE_CACHE_ENTRIES_BINARY_OP + 1); + SKIP_OVER(INLINE_CACHE_ENTRIES_BINARY_OP + 1); #line 571 "Python/generated_cases.c.h" } STACK_SHRINK(2); @@ -751,7 +751,7 @@ STACK_SHRINK(2); new_frame->localsplus[0] = container; new_frame->localsplus[1] = sub; - JUMPBY(INLINE_CACHE_ENTRIES_BINARY_SUBSCR); + SKIP_OVER(INLINE_CACHE_ENTRIES_BINARY_SUBSCR); frame->return_offset = 0; DISPATCH_INLINED(new_frame); #line 758 "Python/generated_cases.c.h" @@ -1183,7 +1183,7 @@ gen->gi_frame_state = FRAME_EXECUTING; gen->gi_exc_state.previous_item = tstate->exc_info; tstate->exc_info = &gen->gi_exc_state; - JUMPBY(INLINE_CACHE_ENTRIES_SEND); + SKIP_OVER(INLINE_CACHE_ENTRIES_SEND); DISPATCH_INLINED(gen_frame); } if (Py_IsNone(v) && PyIter_Check(receiver)) { @@ -1229,7 +1229,7 @@ gen->gi_frame_state = FRAME_EXECUTING; gen->gi_exc_state.previous_item = tstate->exc_info; tstate->exc_info = &gen->gi_exc_state; - JUMPBY(INLINE_CACHE_ENTRIES_SEND); + SKIP_OVER(INLINE_CACHE_ENTRIES_SEND); DISPATCH_INLINED(gen_frame); #line 1235 "Python/generated_cases.c.h" } @@ -2689,7 +2689,7 @@ int shrink_stack = !(oparg & 1); STACK_SHRINK(shrink_stack); new_frame->localsplus[0] = owner; - JUMPBY(INLINE_CACHE_ENTRIES_LOAD_ATTR); + SKIP_OVER(INLINE_CACHE_ENTRIES_LOAD_ATTR); frame->return_offset = 0; DISPATCH_INLINED(new_frame); #line 2696 "Python/generated_cases.c.h" @@ -2723,7 +2723,7 @@ STACK_SHRINK(shrink_stack); new_frame->localsplus[0] = owner; new_frame->localsplus[1] = Py_NewRef(name); - JUMPBY(INLINE_CACHE_ENTRIES_LOAD_ATTR); + SKIP_OVER(INLINE_CACHE_ENTRIES_LOAD_ATTR); frame->return_offset = 0; DISPATCH_INLINED(new_frame); #line 2730 "Python/generated_cases.c.h" @@ -3350,12 +3350,13 @@ next_instr[INLINE_CACHE_ENTRIES_FOR_ITER + oparg].op.code == INSTRUMENTED_END_FOR); Py_DECREF(iter); STACK_SHRINK(1); + SKIP_OVER(INLINE_CACHE_ENTRIES_FOR_ITER); /* Jump forward oparg, then skip following END_FOR instruction */ - JUMPBY(INLINE_CACHE_ENTRIES_FOR_ITER + oparg + 1); + JUMPBY(oparg + 1); DISPATCH(); } // Common case: no jump, leave it to the code generator - #line 3359 "Python/generated_cases.c.h" + #line 3360 "Python/generated_cases.c.h" STACK_GROW(1); stack_pointer[-1] = next; next_instr += 1; @@ -3363,7 +3364,7 @@ } TARGET(INSTRUMENTED_FOR_ITER) { - #line 2365 "Python/bytecodes.c" + #line 2366 "Python/bytecodes.c" _Py_CODEUNIT *here = next_instr-1; _Py_CODEUNIT *target; PyObject *iter = TOP(); @@ -3389,14 +3390,14 @@ target = next_instr + INLINE_CACHE_ENTRIES_FOR_ITER + oparg + 1; } INSTRUMENTED_JUMP(here, target, PY_MONITORING_EVENT_BRANCH); - #line 3393 "Python/generated_cases.c.h" + #line 3394 "Python/generated_cases.c.h" DISPATCH(); } TARGET(FOR_ITER_LIST) { PyObject *iter = stack_pointer[-1]; PyObject *next; - #line 2393 "Python/bytecodes.c" + #line 2394 "Python/bytecodes.c" DEOPT_IF(Py_TYPE(iter) != &PyListIter_Type, FOR_ITER); _PyListIterObject *it = (_PyListIterObject *)iter; STAT_INC(FOR_ITER, hit); @@ -3411,12 +3412,13 @@ } Py_DECREF(iter); STACK_SHRINK(1); + SKIP_OVER(INLINE_CACHE_ENTRIES_FOR_ITER); /* Jump forward oparg, then skip following END_FOR instruction */ - JUMPBY(INLINE_CACHE_ENTRIES_FOR_ITER + oparg + 1); + JUMPBY(oparg + 1); DISPATCH(); end_for_iter_list: // Common case: no jump, leave it to the code generator - #line 3420 "Python/generated_cases.c.h" + #line 3422 "Python/generated_cases.c.h" STACK_GROW(1); stack_pointer[-1] = next; next_instr += 1; @@ -3426,7 +3428,7 @@ TARGET(FOR_ITER_TUPLE) { PyObject *iter = stack_pointer[-1]; PyObject *next; - #line 2415 "Python/bytecodes.c" + #line 2417 "Python/bytecodes.c" _PyTupleIterObject *it = (_PyTupleIterObject *)iter; DEOPT_IF(Py_TYPE(it) != &PyTupleIter_Type, FOR_ITER); STAT_INC(FOR_ITER, hit); @@ -3441,12 +3443,13 @@ } Py_DECREF(iter); STACK_SHRINK(1); + SKIP_OVER(INLINE_CACHE_ENTRIES_FOR_ITER); /* Jump forward oparg, then skip following END_FOR instruction */ - JUMPBY(INLINE_CACHE_ENTRIES_FOR_ITER + oparg + 1); + JUMPBY(oparg + 1); DISPATCH(); end_for_iter_tuple: // Common case: no jump, leave it to the code generator - #line 3450 "Python/generated_cases.c.h" + #line 3453 "Python/generated_cases.c.h" STACK_GROW(1); stack_pointer[-1] = next; next_instr += 1; @@ -3456,15 +3459,16 @@ TARGET(FOR_ITER_RANGE) { PyObject *iter = stack_pointer[-1]; PyObject *next; - #line 2437 "Python/bytecodes.c" + #line 2440 "Python/bytecodes.c" _PyRangeIterObject *r = (_PyRangeIterObject *)iter; DEOPT_IF(Py_TYPE(r) != &PyRangeIter_Type, FOR_ITER); STAT_INC(FOR_ITER, hit); if (r->len <= 0) { STACK_SHRINK(1); Py_DECREF(r); + SKIP_OVER(INLINE_CACHE_ENTRIES_FOR_ITER); // Jump over END_FOR instruction. - JUMPBY(INLINE_CACHE_ENTRIES_FOR_ITER + oparg + 1); + JUMPBY(oparg + 1); DISPATCH(); } long value = r->start; @@ -3474,7 +3478,7 @@ if (next == NULL) { goto error; } - #line 3478 "Python/generated_cases.c.h" + #line 3482 "Python/generated_cases.c.h" STACK_GROW(1); stack_pointer[-1] = next; next_instr += 1; @@ -3483,7 +3487,7 @@ TARGET(FOR_ITER_GEN) { PyObject *iter = stack_pointer[-1]; - #line 2457 "Python/bytecodes.c" + #line 2461 "Python/bytecodes.c" DEOPT_IF(tstate->interp->eval_frame, FOR_ITER); PyGenObject *gen = (PyGenObject *)iter; DEOPT_IF(Py_TYPE(gen) != &PyGen_Type, FOR_ITER); @@ -3495,18 +3499,18 @@ gen->gi_frame_state = FRAME_EXECUTING; gen->gi_exc_state.previous_item = tstate->exc_info; tstate->exc_info = &gen->gi_exc_state; - JUMPBY(INLINE_CACHE_ENTRIES_FOR_ITER); + SKIP_OVER(INLINE_CACHE_ENTRIES_FOR_ITER); assert(next_instr[oparg].op.code == END_FOR || next_instr[oparg].op.code == INSTRUMENTED_END_FOR); DISPATCH_INLINED(gen_frame); - #line 3503 "Python/generated_cases.c.h" + #line 3507 "Python/generated_cases.c.h" } TARGET(BEFORE_ASYNC_WITH) { PyObject *mgr = stack_pointer[-1]; PyObject *exit; PyObject *res; - #line 2475 "Python/bytecodes.c" + #line 2479 "Python/bytecodes.c" PyObject *enter = _PyObject_LookupSpecial(mgr, &_Py_ID(__aenter__)); if (enter == NULL) { if (!_PyErr_Occurred(tstate)) { @@ -3529,16 +3533,16 @@ Py_DECREF(enter); goto error; } - #line 3533 "Python/generated_cases.c.h" + #line 3537 "Python/generated_cases.c.h" Py_DECREF(mgr); - #line 2498 "Python/bytecodes.c" + #line 2502 "Python/bytecodes.c" res = _PyObject_CallNoArgs(enter); Py_DECREF(enter); if (res == NULL) { Py_DECREF(exit); if (true) goto pop_1_error; } - #line 3542 "Python/generated_cases.c.h" + #line 3546 "Python/generated_cases.c.h" STACK_GROW(1); stack_pointer[-1] = res; stack_pointer[-2] = exit; @@ -3549,7 +3553,7 @@ PyObject *mgr = stack_pointer[-1]; PyObject *exit; PyObject *res; - #line 2507 "Python/bytecodes.c" + #line 2511 "Python/bytecodes.c" /* pop the context manager, push its __exit__ and the * value returned from calling its __enter__ */ @@ -3575,16 +3579,16 @@ Py_DECREF(enter); goto error; } - #line 3579 "Python/generated_cases.c.h" + #line 3583 "Python/generated_cases.c.h" Py_DECREF(mgr); - #line 2533 "Python/bytecodes.c" + #line 2537 "Python/bytecodes.c" res = _PyObject_CallNoArgs(enter); Py_DECREF(enter); if (res == NULL) { Py_DECREF(exit); if (true) goto pop_1_error; } - #line 3588 "Python/generated_cases.c.h" + #line 3592 "Python/generated_cases.c.h" STACK_GROW(1); stack_pointer[-1] = res; stack_pointer[-2] = exit; @@ -3596,7 +3600,7 @@ PyObject *lasti = stack_pointer[-3]; PyObject *exit_func = stack_pointer[-4]; PyObject *res; - #line 2542 "Python/bytecodes.c" + #line 2546 "Python/bytecodes.c" /* At the top of the stack are 4 values: - val: TOP = exc_info() - unused: SECOND = previous exception @@ -3617,7 +3621,7 @@ res = PyObject_Vectorcall(exit_func, stack + 1, 3 | PY_VECTORCALL_ARGUMENTS_OFFSET, NULL); if (res == NULL) goto error; - #line 3621 "Python/generated_cases.c.h" + #line 3625 "Python/generated_cases.c.h" STACK_GROW(1); stack_pointer[-1] = res; DISPATCH(); @@ -3626,7 +3630,7 @@ TARGET(PUSH_EXC_INFO) { PyObject *new_exc = stack_pointer[-1]; PyObject *prev_exc; - #line 2581 "Python/bytecodes.c" + #line 2585 "Python/bytecodes.c" _PyErr_StackItem *exc_info = tstate->exc_info; if (exc_info->exc_value != NULL) { prev_exc = exc_info->exc_value; @@ -3636,7 +3640,7 @@ } assert(PyExceptionInstance_Check(new_exc)); exc_info->exc_value = Py_NewRef(new_exc); - #line 3640 "Python/generated_cases.c.h" + #line 3644 "Python/generated_cases.c.h" STACK_GROW(1); stack_pointer[-1] = new_exc; stack_pointer[-2] = prev_exc; @@ -3650,7 +3654,7 @@ uint32_t type_version = read_u32(&next_instr[1].cache); uint32_t keys_version = read_u32(&next_instr[3].cache); PyObject *descr = read_obj(&next_instr[5].cache); - #line 2593 "Python/bytecodes.c" + #line 2597 "Python/bytecodes.c" /* Cached method object */ PyTypeObject *self_cls = Py_TYPE(self); assert(type_version != 0); @@ -3667,7 +3671,7 @@ assert(_PyType_HasFeature(Py_TYPE(res2), Py_TPFLAGS_METHOD_DESCRIPTOR)); res = self; assert(oparg & 1); - #line 3671 "Python/generated_cases.c.h" + #line 3675 "Python/generated_cases.c.h" STACK_GROW(((oparg & 1) ? 1 : 0)); stack_pointer[-1] = res; if (oparg & 1) { stack_pointer[-(1 + ((oparg & 1) ? 1 : 0))] = res2; } @@ -3681,7 +3685,7 @@ PyObject *res; uint32_t type_version = read_u32(&next_instr[1].cache); PyObject *descr = read_obj(&next_instr[5].cache); - #line 2612 "Python/bytecodes.c" + #line 2616 "Python/bytecodes.c" PyTypeObject *self_cls = Py_TYPE(self); DEOPT_IF(self_cls->tp_version_tag != type_version, LOAD_ATTR); assert(self_cls->tp_dictoffset == 0); @@ -3691,7 +3695,7 @@ res2 = Py_NewRef(descr); res = self; assert(oparg & 1); - #line 3695 "Python/generated_cases.c.h" + #line 3699 "Python/generated_cases.c.h" STACK_GROW(((oparg & 1) ? 1 : 0)); stack_pointer[-1] = res; if (oparg & 1) { stack_pointer[-(1 + ((oparg & 1) ? 1 : 0))] = res2; } @@ -3705,7 +3709,7 @@ PyObject *res; uint32_t type_version = read_u32(&next_instr[1].cache); PyObject *descr = read_obj(&next_instr[5].cache); - #line 2624 "Python/bytecodes.c" + #line 2628 "Python/bytecodes.c" PyTypeObject *self_cls = Py_TYPE(self); DEOPT_IF(self_cls->tp_version_tag != type_version, LOAD_ATTR); Py_ssize_t dictoffset = self_cls->tp_dictoffset; @@ -3719,7 +3723,7 @@ res2 = Py_NewRef(descr); res = self; assert(oparg & 1); - #line 3723 "Python/generated_cases.c.h" + #line 3727 "Python/generated_cases.c.h" STACK_GROW(((oparg & 1) ? 1 : 0)); stack_pointer[-1] = res; if (oparg & 1) { stack_pointer[-(1 + ((oparg & 1) ? 1 : 0))] = res2; } @@ -3728,16 +3732,16 @@ } TARGET(KW_NAMES) { - #line 2640 "Python/bytecodes.c" + #line 2644 "Python/bytecodes.c" assert(kwnames == NULL); assert(oparg < PyTuple_GET_SIZE(FRAME_CO_CONSTS)); kwnames = GETITEM(FRAME_CO_CONSTS, oparg); - #line 3736 "Python/generated_cases.c.h" + #line 3740 "Python/generated_cases.c.h" DISPATCH(); } TARGET(INSTRUMENTED_CALL) { - #line 2646 "Python/bytecodes.c" + #line 2650 "Python/bytecodes.c" int is_meth = PEEK(oparg+2) != NULL; int total_args = oparg + is_meth; PyObject *function = PEEK(total_args + 1); @@ -3750,7 +3754,7 @@ _PyCallCache *cache = (_PyCallCache *)next_instr; INCREMENT_ADAPTIVE_COUNTER(cache->counter); GO_TO_INSTRUCTION(CALL); - #line 3754 "Python/generated_cases.c.h" + #line 3758 "Python/generated_cases.c.h" } TARGET(CALL) { @@ -3760,7 +3764,7 @@ PyObject *callable = stack_pointer[-(1 + oparg)]; PyObject *method = stack_pointer[-(2 + oparg)]; PyObject *res; - #line 2691 "Python/bytecodes.c" + #line 2695 "Python/bytecodes.c" int is_meth = method != NULL; int total_args = oparg; if (is_meth) { @@ -3809,7 +3813,7 @@ if (new_frame == NULL) { goto error; } - JUMPBY(INLINE_CACHE_ENTRIES_CALL); + SKIP_OVER(INLINE_CACHE_ENTRIES_CALL); frame->return_offset = 0; DISPATCH_INLINED(new_frame); } @@ -3842,7 +3846,7 @@ Py_DECREF(args[i]); } if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; } - #line 3846 "Python/generated_cases.c.h" + #line 3850 "Python/generated_cases.c.h" STACK_SHRINK(oparg); STACK_SHRINK(1); stack_pointer[-1] = res; @@ -3854,7 +3858,7 @@ TARGET(CALL_BOUND_METHOD_EXACT_ARGS) { PyObject *callable = stack_pointer[-(1 + oparg)]; PyObject *method = stack_pointer[-(2 + oparg)]; - #line 2779 "Python/bytecodes.c" + #line 2783 "Python/bytecodes.c" DEOPT_IF(method != NULL, CALL); DEOPT_IF(Py_TYPE(callable) != &PyMethod_Type, CALL); STAT_INC(CALL, hit); @@ -3864,7 +3868,7 @@ PEEK(oparg + 2) = Py_NewRef(meth); // method Py_DECREF(callable); GO_TO_INSTRUCTION(CALL_PY_EXACT_ARGS); - #line 3868 "Python/generated_cases.c.h" + #line 3872 "Python/generated_cases.c.h" } TARGET(CALL_PY_EXACT_ARGS) { @@ -3873,7 +3877,7 @@ PyObject *callable = stack_pointer[-(1 + oparg)]; PyObject *method = stack_pointer[-(2 + oparg)]; uint32_t func_version = read_u32(&next_instr[1].cache); - #line 2791 "Python/bytecodes.c" + #line 2795 "Python/bytecodes.c" assert(kwnames == NULL); DEOPT_IF(tstate->interp->eval_frame, CALL); int is_meth = method != NULL; @@ -3896,10 +3900,10 @@ } // Manipulate stack directly since we leave using DISPATCH_INLINED(). STACK_SHRINK(oparg + 2); - JUMPBY(INLINE_CACHE_ENTRIES_CALL); + SKIP_OVER(INLINE_CACHE_ENTRIES_CALL); frame->return_offset = 0; DISPATCH_INLINED(new_frame); - #line 3903 "Python/generated_cases.c.h" + #line 3907 "Python/generated_cases.c.h" } TARGET(CALL_PY_WITH_DEFAULTS) { @@ -3907,7 +3911,7 @@ PyObject *callable = stack_pointer[-(1 + oparg)]; PyObject *method = stack_pointer[-(2 + oparg)]; uint32_t func_version = read_u32(&next_instr[1].cache); - #line 2819 "Python/bytecodes.c" + #line 2823 "Python/bytecodes.c" assert(kwnames == NULL); DEOPT_IF(tstate->interp->eval_frame, CALL); int is_meth = method != NULL; @@ -3940,10 +3944,10 @@ } // Manipulate stack and cache directly since we leave using DISPATCH_INLINED(). STACK_SHRINK(oparg + 2); - JUMPBY(INLINE_CACHE_ENTRIES_CALL); + SKIP_OVER(INLINE_CACHE_ENTRIES_CALL); frame->return_offset = 0; DISPATCH_INLINED(new_frame); - #line 3947 "Python/generated_cases.c.h" + #line 3951 "Python/generated_cases.c.h" } TARGET(CALL_NO_KW_TYPE_1) { @@ -3951,7 +3955,7 @@ PyObject *callable = stack_pointer[-(1 + oparg)]; PyObject *null = stack_pointer[-(2 + oparg)]; PyObject *res; - #line 2857 "Python/bytecodes.c" + #line 2861 "Python/bytecodes.c" assert(kwnames == NULL); assert(oparg == 1); DEOPT_IF(null != NULL, CALL); @@ -3961,7 +3965,7 @@ res = Py_NewRef(Py_TYPE(obj)); Py_DECREF(obj); Py_DECREF(&PyType_Type); // I.e., callable - #line 3965 "Python/generated_cases.c.h" + #line 3969 "Python/generated_cases.c.h" STACK_SHRINK(oparg); STACK_SHRINK(1); stack_pointer[-1] = res; @@ -3974,7 +3978,7 @@ PyObject *callable = stack_pointer[-(1 + oparg)]; PyObject *null = stack_pointer[-(2 + oparg)]; PyObject *res; - #line 2869 "Python/bytecodes.c" + #line 2873 "Python/bytecodes.c" assert(kwnames == NULL); assert(oparg == 1); DEOPT_IF(null != NULL, CALL); @@ -3985,7 +3989,7 @@ Py_DECREF(arg); Py_DECREF(&PyUnicode_Type); // I.e., callable if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; } - #line 3989 "Python/generated_cases.c.h" + #line 3993 "Python/generated_cases.c.h" STACK_SHRINK(oparg); STACK_SHRINK(1); stack_pointer[-1] = res; @@ -3999,7 +4003,7 @@ PyObject *callable = stack_pointer[-(1 + oparg)]; PyObject *null = stack_pointer[-(2 + oparg)]; PyObject *res; - #line 2883 "Python/bytecodes.c" + #line 2887 "Python/bytecodes.c" assert(kwnames == NULL); assert(oparg == 1); DEOPT_IF(null != NULL, CALL); @@ -4010,7 +4014,7 @@ Py_DECREF(arg); Py_DECREF(&PyTuple_Type); // I.e., tuple if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; } - #line 4014 "Python/generated_cases.c.h" + #line 4018 "Python/generated_cases.c.h" STACK_SHRINK(oparg); STACK_SHRINK(1); stack_pointer[-1] = res; @@ -4024,7 +4028,7 @@ PyObject *callable = stack_pointer[-(1 + oparg)]; PyObject *method = stack_pointer[-(2 + oparg)]; PyObject *res; - #line 2897 "Python/bytecodes.c" + #line 2901 "Python/bytecodes.c" int is_meth = method != NULL; int total_args = oparg; if (is_meth) { @@ -4046,7 +4050,7 @@ } Py_DECREF(tp); if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; } - #line 4050 "Python/generated_cases.c.h" + #line 4054 "Python/generated_cases.c.h" STACK_SHRINK(oparg); STACK_SHRINK(1); stack_pointer[-1] = res; @@ -4060,7 +4064,7 @@ PyObject *callable = stack_pointer[-(1 + oparg)]; PyObject *method = stack_pointer[-(2 + oparg)]; PyObject *res; - #line 2922 "Python/bytecodes.c" + #line 2926 "Python/bytecodes.c" /* Builtin METH_O functions */ assert(kwnames == NULL); int is_meth = method != NULL; @@ -4088,7 +4092,7 @@ Py_DECREF(arg); Py_DECREF(callable); if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; } - #line 4092 "Python/generated_cases.c.h" + #line 4096 "Python/generated_cases.c.h" STACK_SHRINK(oparg); STACK_SHRINK(1); stack_pointer[-1] = res; @@ -4102,7 +4106,7 @@ PyObject *callable = stack_pointer[-(1 + oparg)]; PyObject *method = stack_pointer[-(2 + oparg)]; PyObject *res; - #line 2953 "Python/bytecodes.c" + #line 2957 "Python/bytecodes.c" /* Builtin METH_FASTCALL functions, without keywords */ assert(kwnames == NULL); int is_meth = method != NULL; @@ -4134,7 +4138,7 @@ 'invalid'). In those cases an exception is set, so we must handle it. */ - #line 4138 "Python/generated_cases.c.h" + #line 4142 "Python/generated_cases.c.h" STACK_SHRINK(oparg); STACK_SHRINK(1); stack_pointer[-1] = res; @@ -4148,7 +4152,7 @@ PyObject *callable = stack_pointer[-(1 + oparg)]; PyObject *method = stack_pointer[-(2 + oparg)]; PyObject *res; - #line 2988 "Python/bytecodes.c" + #line 2992 "Python/bytecodes.c" /* Builtin METH_FASTCALL | METH_KEYWORDS functions */ int is_meth = method != NULL; int total_args = oparg; @@ -4180,7 +4184,7 @@ } Py_DECREF(callable); if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; } - #line 4184 "Python/generated_cases.c.h" + #line 4188 "Python/generated_cases.c.h" STACK_SHRINK(oparg); STACK_SHRINK(1); stack_pointer[-1] = res; @@ -4194,7 +4198,7 @@ PyObject *callable = stack_pointer[-(1 + oparg)]; PyObject *method = stack_pointer[-(2 + oparg)]; PyObject *res; - #line 3023 "Python/bytecodes.c" + #line 3027 "Python/bytecodes.c" assert(kwnames == NULL); /* len(o) */ int is_meth = method != NULL; @@ -4219,7 +4223,7 @@ Py_DECREF(callable); Py_DECREF(arg); if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; } - #line 4223 "Python/generated_cases.c.h" + #line 4227 "Python/generated_cases.c.h" STACK_SHRINK(oparg); STACK_SHRINK(1); stack_pointer[-1] = res; @@ -4232,7 +4236,7 @@ PyObject *callable = stack_pointer[-(1 + oparg)]; PyObject *method = stack_pointer[-(2 + oparg)]; PyObject *res; - #line 3050 "Python/bytecodes.c" + #line 3054 "Python/bytecodes.c" assert(kwnames == NULL); /* isinstance(o, o2) */ int is_meth = method != NULL; @@ -4259,7 +4263,7 @@ Py_DECREF(cls); Py_DECREF(callable); if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; } - #line 4263 "Python/generated_cases.c.h" + #line 4267 "Python/generated_cases.c.h" STACK_SHRINK(oparg); STACK_SHRINK(1); stack_pointer[-1] = res; @@ -4271,7 +4275,7 @@ PyObject **args = (stack_pointer - oparg); PyObject *self = stack_pointer[-(1 + oparg)]; PyObject *method = stack_pointer[-(2 + oparg)]; - #line 3080 "Python/bytecodes.c" + #line 3084 "Python/bytecodes.c" assert(kwnames == NULL); assert(oparg == 1); assert(method != NULL); @@ -4286,17 +4290,17 @@ Py_DECREF(method); STACK_SHRINK(3); // CALL + POP_TOP - JUMPBY(INLINE_CACHE_ENTRIES_CALL + 1); + SKIP_OVER(INLINE_CACHE_ENTRIES_CALL + 1); assert(next_instr[-1].op.code == POP_TOP); DISPATCH(); - #line 4293 "Python/generated_cases.c.h" + #line 4297 "Python/generated_cases.c.h" } TARGET(CALL_NO_KW_METHOD_DESCRIPTOR_O) { PyObject **args = (stack_pointer - oparg); PyObject *method = stack_pointer[-(2 + oparg)]; PyObject *res; - #line 3100 "Python/bytecodes.c" + #line 3104 "Python/bytecodes.c" assert(kwnames == NULL); int is_meth = method != NULL; int total_args = oparg; @@ -4327,7 +4331,7 @@ Py_DECREF(arg); Py_DECREF(callable); if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; } - #line 4331 "Python/generated_cases.c.h" + #line 4335 "Python/generated_cases.c.h" STACK_SHRINK(oparg); STACK_SHRINK(1); stack_pointer[-1] = res; @@ -4340,7 +4344,7 @@ PyObject **args = (stack_pointer - oparg); PyObject *method = stack_pointer[-(2 + oparg)]; PyObject *res; - #line 3134 "Python/bytecodes.c" + #line 3138 "Python/bytecodes.c" int is_meth = method != NULL; int total_args = oparg; if (is_meth) { @@ -4369,7 +4373,7 @@ } Py_DECREF(callable); if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; } - #line 4373 "Python/generated_cases.c.h" + #line 4377 "Python/generated_cases.c.h" STACK_SHRINK(oparg); STACK_SHRINK(1); stack_pointer[-1] = res; @@ -4382,7 +4386,7 @@ PyObject **args = (stack_pointer - oparg); PyObject *method = stack_pointer[-(2 + oparg)]; PyObject *res; - #line 3166 "Python/bytecodes.c" + #line 3170 "Python/bytecodes.c" assert(kwnames == NULL); assert(oparg == 0 || oparg == 1); int is_meth = method != NULL; @@ -4411,7 +4415,7 @@ Py_DECREF(self); Py_DECREF(callable); if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; } - #line 4415 "Python/generated_cases.c.h" + #line 4419 "Python/generated_cases.c.h" STACK_SHRINK(oparg); STACK_SHRINK(1); stack_pointer[-1] = res; @@ -4424,7 +4428,7 @@ PyObject **args = (stack_pointer - oparg); PyObject *method = stack_pointer[-(2 + oparg)]; PyObject *res; - #line 3198 "Python/bytecodes.c" + #line 3202 "Python/bytecodes.c" assert(kwnames == NULL); int is_meth = method != NULL; int total_args = oparg; @@ -4452,7 +4456,7 @@ } Py_DECREF(callable); if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; } - #line 4456 "Python/generated_cases.c.h" + #line 4460 "Python/generated_cases.c.h" STACK_SHRINK(oparg); STACK_SHRINK(1); stack_pointer[-1] = res; @@ -4462,9 +4466,9 @@ } TARGET(INSTRUMENTED_CALL_FUNCTION_EX) { - #line 3229 "Python/bytecodes.c" + #line 3233 "Python/bytecodes.c" GO_TO_INSTRUCTION(CALL_FUNCTION_EX); - #line 4468 "Python/generated_cases.c.h" + #line 4472 "Python/generated_cases.c.h" } TARGET(CALL_FUNCTION_EX) { @@ -4473,7 +4477,7 @@ PyObject *callargs = stack_pointer[-(1 + ((oparg & 1) ? 1 : 0))]; PyObject *func = stack_pointer[-(2 + ((oparg & 1) ? 1 : 0))]; PyObject *result; - #line 3233 "Python/bytecodes.c" + #line 3237 "Python/bytecodes.c" // DICT_MERGE is called before this opcode if there are kwargs. // It converts all dict subtypes in kwargs into regular dicts. assert(kwargs == NULL || PyDict_CheckExact(kwargs)); @@ -4535,14 +4539,14 @@ } result = PyObject_Call(func, callargs, kwargs); } - #line 4539 "Python/generated_cases.c.h" + #line 4543 "Python/generated_cases.c.h" Py_DECREF(func); Py_DECREF(callargs); Py_XDECREF(kwargs); - #line 3295 "Python/bytecodes.c" + #line 3299 "Python/bytecodes.c" assert(PEEK(3 + (oparg & 1)) == NULL); if (result == NULL) { STACK_SHRINK(((oparg & 1) ? 1 : 0)); goto pop_3_error; } - #line 4546 "Python/generated_cases.c.h" + #line 4550 "Python/generated_cases.c.h" STACK_SHRINK(((oparg & 1) ? 1 : 0)); STACK_SHRINK(2); stack_pointer[-1] = result; @@ -4553,7 +4557,7 @@ TARGET(MAKE_FUNCTION) { PyObject *codeobj = stack_pointer[-1]; PyObject *func; - #line 3301 "Python/bytecodes.c" + #line 3305 "Python/bytecodes.c" PyFunctionObject *func_obj = (PyFunctionObject *) PyFunction_New(codeobj, GLOBALS()); @@ -4565,7 +4569,7 @@ func_obj->func_version = ((PyCodeObject *)codeobj)->co_version; func = (PyObject *)func_obj; - #line 4569 "Python/generated_cases.c.h" + #line 4573 "Python/generated_cases.c.h" stack_pointer[-1] = func; DISPATCH(); } @@ -4573,7 +4577,7 @@ TARGET(SET_FUNCTION_ATTRIBUTE) { PyObject *func = stack_pointer[-1]; PyObject *attr = stack_pointer[-2]; - #line 3315 "Python/bytecodes.c" + #line 3319 "Python/bytecodes.c" assert(PyFunction_Check(func)); PyFunctionObject *func_obj = (PyFunctionObject *)func; switch(oparg) { @@ -4598,14 +4602,14 @@ default: Py_UNREACHABLE(); } - #line 4602 "Python/generated_cases.c.h" + #line 4606 "Python/generated_cases.c.h" STACK_SHRINK(1); stack_pointer[-1] = func; DISPATCH(); } TARGET(RETURN_GENERATOR) { - #line 3342 "Python/bytecodes.c" + #line 3346 "Python/bytecodes.c" assert(PyFunction_Check(frame->f_funcobj)); PyFunctionObject *func = (PyFunctionObject *)frame->f_funcobj; PyGenObject *gen = (PyGenObject *)_Py_MakeCoro(func); @@ -4626,7 +4630,7 @@ frame = cframe.current_frame = prev; _PyFrame_StackPush(frame, (PyObject *)gen); goto resume_frame; - #line 4630 "Python/generated_cases.c.h" + #line 4634 "Python/generated_cases.c.h" } TARGET(BUILD_SLICE) { @@ -4634,15 +4638,15 @@ PyObject *stop = stack_pointer[-(1 + ((oparg == 3) ? 1 : 0))]; PyObject *start = stack_pointer[-(2 + ((oparg == 3) ? 1 : 0))]; PyObject *slice; - #line 3365 "Python/bytecodes.c" + #line 3369 "Python/bytecodes.c" slice = PySlice_New(start, stop, step); - #line 4640 "Python/generated_cases.c.h" + #line 4644 "Python/generated_cases.c.h" Py_DECREF(start); Py_DECREF(stop); Py_XDECREF(step); - #line 3367 "Python/bytecodes.c" + #line 3371 "Python/bytecodes.c" if (slice == NULL) { STACK_SHRINK(((oparg == 3) ? 1 : 0)); goto pop_2_error; } - #line 4646 "Python/generated_cases.c.h" + #line 4650 "Python/generated_cases.c.h" STACK_SHRINK(((oparg == 3) ? 1 : 0)); STACK_SHRINK(1); stack_pointer[-1] = slice; @@ -4653,7 +4657,7 @@ PyObject *fmt_spec = ((oparg & FVS_MASK) == FVS_HAVE_SPEC) ? stack_pointer[-((((oparg & FVS_MASK) == FVS_HAVE_SPEC) ? 1 : 0))] : NULL; PyObject *value = stack_pointer[-(1 + (((oparg & FVS_MASK) == FVS_HAVE_SPEC) ? 1 : 0))]; PyObject *result; - #line 3371 "Python/bytecodes.c" + #line 3375 "Python/bytecodes.c" /* Handles f-string value formatting. */ PyObject *(*conv_fn)(PyObject *); int which_conversion = oparg & FVC_MASK; @@ -4688,7 +4692,7 @@ Py_DECREF(value); Py_XDECREF(fmt_spec); if (result == NULL) { STACK_SHRINK((((oparg & FVS_MASK) == FVS_HAVE_SPEC) ? 1 : 0)); goto pop_1_error; } - #line 4692 "Python/generated_cases.c.h" + #line 4696 "Python/generated_cases.c.h" STACK_SHRINK((((oparg & FVS_MASK) == FVS_HAVE_SPEC) ? 1 : 0)); stack_pointer[-1] = result; DISPATCH(); @@ -4697,10 +4701,10 @@ TARGET(COPY) { PyObject *bottom = stack_pointer[-(1 + (oparg-1))]; PyObject *top; - #line 3408 "Python/bytecodes.c" + #line 3412 "Python/bytecodes.c" assert(oparg > 0); top = Py_NewRef(bottom); - #line 4704 "Python/generated_cases.c.h" + #line 4708 "Python/generated_cases.c.h" STACK_GROW(1); stack_pointer[-1] = top; DISPATCH(); @@ -4712,7 +4716,7 @@ PyObject *rhs = stack_pointer[-1]; PyObject *lhs = stack_pointer[-2]; PyObject *res; - #line 3413 "Python/bytecodes.c" + #line 3417 "Python/bytecodes.c" #if ENABLE_SPECIALIZATION _PyBinaryOpCache *cache = (_PyBinaryOpCache *)next_instr; if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) { @@ -4727,12 +4731,12 @@ assert((unsigned)oparg < Py_ARRAY_LENGTH(binary_ops)); assert(binary_ops[oparg]); res = binary_ops[oparg](lhs, rhs); - #line 4731 "Python/generated_cases.c.h" + #line 4735 "Python/generated_cases.c.h" Py_DECREF(lhs); Py_DECREF(rhs); - #line 3428 "Python/bytecodes.c" + #line 3432 "Python/bytecodes.c" if (res == NULL) goto pop_2_error; - #line 4736 "Python/generated_cases.c.h" + #line 4740 "Python/generated_cases.c.h" STACK_SHRINK(1); stack_pointer[-1] = res; next_instr += 1; @@ -4742,16 +4746,16 @@ TARGET(SWAP) { PyObject *top = stack_pointer[-1]; PyObject *bottom = stack_pointer[-(2 + (oparg-2))]; - #line 3433 "Python/bytecodes.c" + #line 3437 "Python/bytecodes.c" assert(oparg >= 2); - #line 4748 "Python/generated_cases.c.h" + #line 4752 "Python/generated_cases.c.h" stack_pointer[-1] = bottom; stack_pointer[-(2 + (oparg-2))] = top; DISPATCH(); } TARGET(INSTRUMENTED_INSTRUCTION) { - #line 3437 "Python/bytecodes.c" + #line 3441 "Python/bytecodes.c" int next_opcode = _Py_call_instrumentation_instruction( tstate, frame, next_instr-1); if (next_opcode < 0) goto error; @@ -4763,26 +4767,26 @@ assert(next_opcode > 0 && next_opcode < 256); opcode = next_opcode; DISPATCH_GOTO(); - #line 4767 "Python/generated_cases.c.h" + #line 4771 "Python/generated_cases.c.h" } TARGET(INSTRUMENTED_JUMP_FORWARD) { - #line 3451 "Python/bytecodes.c" + #line 3455 "Python/bytecodes.c" INSTRUMENTED_JUMP(next_instr-1, next_instr+oparg, PY_MONITORING_EVENT_JUMP); - #line 4773 "Python/generated_cases.c.h" + #line 4777 "Python/generated_cases.c.h" DISPATCH(); } TARGET(INSTRUMENTED_JUMP_BACKWARD) { - #line 3455 "Python/bytecodes.c" + #line 3459 "Python/bytecodes.c" INSTRUMENTED_JUMP(next_instr-1, next_instr+1-oparg, PY_MONITORING_EVENT_JUMP); - #line 4780 "Python/generated_cases.c.h" + #line 4784 "Python/generated_cases.c.h" CHECK_EVAL_BREAKER(); DISPATCH(); } TARGET(INSTRUMENTED_POP_JUMP_IF_TRUE) { - #line 3460 "Python/bytecodes.c" + #line 3464 "Python/bytecodes.c" PyObject *cond = POP(); int err = PyObject_IsTrue(cond); Py_DECREF(cond); @@ -4791,12 +4795,12 @@ assert(err == 0 || err == 1); int offset = err*oparg; INSTRUMENTED_JUMP(here, next_instr + offset, PY_MONITORING_EVENT_BRANCH); - #line 4795 "Python/generated_cases.c.h" + #line 4799 "Python/generated_cases.c.h" DISPATCH(); } TARGET(INSTRUMENTED_POP_JUMP_IF_FALSE) { - #line 3471 "Python/bytecodes.c" + #line 3475 "Python/bytecodes.c" PyObject *cond = POP(); int err = PyObject_IsTrue(cond); Py_DECREF(cond); @@ -4805,12 +4809,12 @@ assert(err == 0 || err == 1); int offset = (1-err)*oparg; INSTRUMENTED_JUMP(here, next_instr + offset, PY_MONITORING_EVENT_BRANCH); - #line 4809 "Python/generated_cases.c.h" + #line 4813 "Python/generated_cases.c.h" DISPATCH(); } TARGET(INSTRUMENTED_POP_JUMP_IF_NONE) { - #line 3482 "Python/bytecodes.c" + #line 3486 "Python/bytecodes.c" PyObject *value = POP(); _Py_CODEUNIT *here = next_instr-1; int offset; @@ -4822,12 +4826,12 @@ offset = 0; } INSTRUMENTED_JUMP(here, next_instr + offset, PY_MONITORING_EVENT_BRANCH); - #line 4826 "Python/generated_cases.c.h" + #line 4830 "Python/generated_cases.c.h" DISPATCH(); } TARGET(INSTRUMENTED_POP_JUMP_IF_NOT_NONE) { - #line 3496 "Python/bytecodes.c" + #line 3500 "Python/bytecodes.c" PyObject *value = POP(); _Py_CODEUNIT *here = next_instr-1; int offset; @@ -4839,30 +4843,30 @@ offset = oparg; } INSTRUMENTED_JUMP(here, next_instr + offset, PY_MONITORING_EVENT_BRANCH); - #line 4843 "Python/generated_cases.c.h" + #line 4847 "Python/generated_cases.c.h" DISPATCH(); } TARGET(EXTENDED_ARG) { - #line 3510 "Python/bytecodes.c" + #line 3514 "Python/bytecodes.c" assert(oparg); opcode = next_instr->op.code; oparg = oparg << 8 | next_instr->op.arg; PRE_DISPATCH_GOTO(); DISPATCH_GOTO(); - #line 4854 "Python/generated_cases.c.h" + #line 4858 "Python/generated_cases.c.h" } TARGET(CACHE) { - #line 3518 "Python/bytecodes.c" + #line 3522 "Python/bytecodes.c" assert(0 && "Executing a cache."); Py_UNREACHABLE(); - #line 4861 "Python/generated_cases.c.h" + #line 4865 "Python/generated_cases.c.h" } TARGET(RESERVED) { - #line 3523 "Python/bytecodes.c" + #line 3527 "Python/bytecodes.c" assert(0 && "Executing RESERVED instruction."); Py_UNREACHABLE(); - #line 4868 "Python/generated_cases.c.h" + #line 4872 "Python/generated_cases.c.h" } diff --git a/Python/opcode_metadata.h b/Python/opcode_metadata.h index faa5087adebf92..b946f7b227d9ae 100644 --- a/Python/opcode_metadata.h +++ b/Python/opcode_metadata.h @@ -858,9 +858,11 @@ enum InstructionFormat { INSTR_FMT_IB, INSTR_FMT_IBC, INSTR_FMT_IBC00, INSTR_FMT #define HAS_ARG_FLAG (1) #define HAS_CONST_FLAG (2) #define HAS_NAME_FLAG (4) +#define HAS_JUMP_FLAG (8) #define OPCODE_HAS_ARG(OP) (_PyOpcode_opcode_metadata[(OP)].flags & (HAS_ARG_FLAG)) #define OPCODE_HAS_CONST(OP) (_PyOpcode_opcode_metadata[(OP)].flags & (HAS_CONST_FLAG)) #define OPCODE_HAS_NAME(OP) (_PyOpcode_opcode_metadata[(OP)].flags & (HAS_NAME_FLAG)) +#define OPCODE_HAS_JUMP(OP) (_PyOpcode_opcode_metadata[(OP)].flags & (HAS_JUMP_FLAG)) struct opcode_metadata { bool valid_entry; enum InstructionFormat instr_format; @@ -929,7 +931,7 @@ const struct opcode_metadata _PyOpcode_opcode_metadata[512] = { [GET_AITER] = { true, INSTR_FMT_IX, 0 }, [GET_ANEXT] = { true, INSTR_FMT_IX, 0 }, [GET_AWAITABLE] = { true, INSTR_FMT_IB, HAS_ARG_FLAG }, - [SEND] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG }, + [SEND] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_JUMP_FLAG }, [SEND_GEN] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG }, [INSTRUMENTED_YIELD_VALUE] = { true, INSTR_FMT_IB, HAS_ARG_FLAG }, [YIELD_VALUE] = { true, INSTR_FMT_IB, HAS_ARG_FLAG }, @@ -1004,16 +1006,16 @@ const struct opcode_metadata _PyOpcode_opcode_metadata[512] = { [CHECK_EXC_MATCH] = { true, INSTR_FMT_IX, 0 }, [IMPORT_NAME] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_NAME_FLAG }, [IMPORT_FROM] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_NAME_FLAG }, - [JUMP_FORWARD] = { true, INSTR_FMT_IB, HAS_ARG_FLAG }, - [JUMP_BACKWARD] = { true, INSTR_FMT_IB, HAS_ARG_FLAG }, - [JUMP] = { true, INSTR_FMT_IB, HAS_ARG_FLAG }, - [JUMP_NO_INTERRUPT] = { true, INSTR_FMT_IB, HAS_ARG_FLAG }, + [JUMP_FORWARD] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_JUMP_FLAG }, + [JUMP_BACKWARD] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_JUMP_FLAG }, + [JUMP] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_JUMP_FLAG }, + [JUMP_NO_INTERRUPT] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_JUMP_FLAG }, [ENTER_EXECUTOR] = { true, INSTR_FMT_IB, HAS_ARG_FLAG }, - [POP_JUMP_IF_FALSE] = { true, INSTR_FMT_IB, HAS_ARG_FLAG }, - [POP_JUMP_IF_TRUE] = { true, INSTR_FMT_IB, HAS_ARG_FLAG }, - [POP_JUMP_IF_NOT_NONE] = { true, INSTR_FMT_IB, HAS_ARG_FLAG }, - [POP_JUMP_IF_NONE] = { true, INSTR_FMT_IB, HAS_ARG_FLAG }, - [JUMP_BACKWARD_NO_INTERRUPT] = { true, INSTR_FMT_IB, HAS_ARG_FLAG }, + [POP_JUMP_IF_FALSE] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_JUMP_FLAG }, + [POP_JUMP_IF_TRUE] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_JUMP_FLAG }, + [POP_JUMP_IF_NOT_NONE] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_JUMP_FLAG }, + [POP_JUMP_IF_NONE] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_JUMP_FLAG }, + [JUMP_BACKWARD_NO_INTERRUPT] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_JUMP_FLAG }, [GET_LEN] = { true, INSTR_FMT_IX, 0 }, [MATCH_CLASS] = { true, INSTR_FMT_IB, HAS_ARG_FLAG }, [MATCH_MAPPING] = { true, INSTR_FMT_IX, 0 }, @@ -1021,11 +1023,11 @@ const struct opcode_metadata _PyOpcode_opcode_metadata[512] = { [MATCH_KEYS] = { true, INSTR_FMT_IX, 0 }, [GET_ITER] = { true, INSTR_FMT_IX, 0 }, [GET_YIELD_FROM_ITER] = { true, INSTR_FMT_IX, 0 }, - [FOR_ITER] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG }, + [FOR_ITER] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_JUMP_FLAG }, [INSTRUMENTED_FOR_ITER] = { true, INSTR_FMT_IB, HAS_ARG_FLAG }, - [FOR_ITER_LIST] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG }, - [FOR_ITER_TUPLE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG }, - [FOR_ITER_RANGE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG }, + [FOR_ITER_LIST] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_JUMP_FLAG }, + [FOR_ITER_TUPLE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_JUMP_FLAG }, + [FOR_ITER_RANGE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_JUMP_FLAG }, [FOR_ITER_GEN] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG }, [BEFORE_ASYNC_WITH] = { true, INSTR_FMT_IX, 0 }, [BEFORE_WITH] = { true, INSTR_FMT_IX, 0 }, diff --git a/Tools/cases_generator/generate_cases.py b/Tools/cases_generator/generate_cases.py index 8aa500e9e7412a..23e7c01de08af4 100644 --- a/Tools/cases_generator/generate_cases.py +++ b/Tools/cases_generator/generate_cases.py @@ -228,7 +228,7 @@ def assign(self, dst: StackEffect, src: StackEffect): def cast(self, dst: StackEffect, src: StackEffect) -> str: return f"({dst.type or 'PyObject *'})" if src.type != dst.type else "" -INSTRUCTION_FLAGS = ['HAS_ARG', 'HAS_CONST', 'HAS_NAME'] +INSTRUCTION_FLAGS = ['HAS_ARG', 'HAS_CONST', 'HAS_NAME', 'HAS_JUMP'] @dataclasses.dataclass class Instruction: @@ -283,6 +283,7 @@ def __init__(self, inst: parser.InstDef): 'HAS_ARG' : variable_used(inst, "oparg"), 'HAS_CONST': variable_used(inst, "FRAME_CO_CONSTS"), 'HAS_NAME' : variable_used(inst, "FRAME_CO_NAMES"), + 'HAS_JUMP' : variable_used(inst, "JUMPBY"), } assert set(flag_data.keys()) == set(INSTRUCTION_FLAGS) self.flags = 0