From 5e0d8753f3272b8f1ff23f1677a42e3292a8e59d Mon Sep 17 00:00:00 2001 From: Kirill Podoprigora Date: Fri, 8 Nov 2024 15:52:47 +0200 Subject: [PATCH 1/6] Add FT specialization --- Python/bytecodes.c | 2 +- Python/generated_cases.c.h | 2 +- Python/specialize.c | 35 ++++++++++++----------------------- 3 files changed, 14 insertions(+), 25 deletions(-) diff --git a/Python/bytecodes.c b/Python/bytecodes.c index 7ae0f20369641a..3b7c0f5c1dfe4e 100644 --- a/Python/bytecodes.c +++ b/Python/bytecodes.c @@ -1381,7 +1381,7 @@ dummy_func( }; specializing op(_SPECIALIZE_UNPACK_SEQUENCE, (counter/1, seq -- seq)) { - #if ENABLE_SPECIALIZATION + #if ENABLE_SPECIALIZATION_FT if (ADAPTIVE_COUNTER_TRIGGERS(counter)) { next_instr = this_instr; _Py_Specialize_UnpackSequence(seq, next_instr, oparg); diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h index 03b4d2224922f0..c44d6d9e3e509e 100644 --- a/Python/generated_cases.c.h +++ b/Python/generated_cases.c.h @@ -7982,7 +7982,7 @@ seq = stack_pointer[-1]; uint16_t counter = read_u16(&this_instr[1].cache); (void)counter; - #if ENABLE_SPECIALIZATION + #if ENABLE_SPECIALIZATION_FT if (ADAPTIVE_COUNTER_TRIGGERS(counter)) { next_instr = this_instr; _PyFrame_SetStackPointer(frame, stack_pointer); diff --git a/Python/specialize.c b/Python/specialize.c index 0699e7be5e6b9c..86a91b178b22f1 100644 --- a/Python/specialize.c +++ b/Python/specialize.c @@ -2464,7 +2464,6 @@ _Py_Specialize_CompareOp(_PyStackRef lhs_st, _PyStackRef rhs_st, _Py_CODEUNIT *i cache->counter = adaptive_counter_cooldown(); } -#ifdef Py_STATS static int unpack_sequence_fail_kind(PyObject *seq) { @@ -2476,46 +2475,36 @@ unpack_sequence_fail_kind(PyObject *seq) } return SPEC_FAIL_OTHER; } -#endif // Py_STATS void _Py_Specialize_UnpackSequence(_PyStackRef seq_st, _Py_CODEUNIT *instr, int oparg) { PyObject *seq = PyStackRef_AsPyObjectBorrow(seq_st); - assert(ENABLE_SPECIALIZATION); + assert(ENABLE_SPECIALIZATION_FT); assert(_PyOpcode_Caches[UNPACK_SEQUENCE] == INLINE_CACHE_ENTRIES_UNPACK_SEQUENCE); - _PyUnpackSequenceCache *cache = (_PyUnpackSequenceCache *)(instr + 1); if (PyTuple_CheckExact(seq)) { if (PyTuple_GET_SIZE(seq) != oparg) { - SPECIALIZATION_FAIL(UNPACK_SEQUENCE, SPEC_FAIL_EXPECTED_ERROR); - goto failure; + unspecialize(instr, SPEC_FAIL_EXPECTED_ERROR); + return; } if (PyTuple_GET_SIZE(seq) == 2) { - instr->op.code = UNPACK_SEQUENCE_TWO_TUPLE; - goto success; + specialize(instr, UNPACK_SEQUENCE_TWO_TUPLE); + return; } - instr->op.code = UNPACK_SEQUENCE_TUPLE; - goto success; + specialize(instr, UNPACK_SEQUENCE_TUPLE); + return; } if (PyList_CheckExact(seq)) { if (PyList_GET_SIZE(seq) != oparg) { - SPECIALIZATION_FAIL(UNPACK_SEQUENCE, SPEC_FAIL_EXPECTED_ERROR); - goto failure; + unspecialize(instr, SPEC_FAIL_EXPECTED_ERROR); + return; } - instr->op.code = UNPACK_SEQUENCE_LIST; - goto success; + specialize(instr, UNPACK_SEQUENCE_LIST); + return; } - SPECIALIZATION_FAIL(UNPACK_SEQUENCE, unpack_sequence_fail_kind(seq)); -failure: - STAT_INC(UNPACK_SEQUENCE, failure); - instr->op.code = UNPACK_SEQUENCE; - cache->counter = adaptive_counter_backoff(cache->counter); - return; -success: - STAT_INC(UNPACK_SEQUENCE, success); - cache->counter = adaptive_counter_cooldown(); + unspecialize(instr, unpack_sequence_fail_kind(seq)); } #ifdef Py_STATS From fa8ff2f97cd28d2c7b4cbab4fc4823b40b892177 Mon Sep 17 00:00:00 2001 From: Kirill Podoprigora Date: Fri, 8 Nov 2024 22:13:28 +0200 Subject: [PATCH 2/6] Add test case --- Lib/test/test_opcache.py | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/Lib/test/test_opcache.py b/Lib/test/test_opcache.py index 78e4bf44f7ea0c..bea8235f1db9ab 100644 --- a/Lib/test/test_opcache.py +++ b/Lib/test/test_opcache.py @@ -1256,6 +1256,37 @@ def g(): self.assert_no_opcode(g, "CONTAINS_OP") + @cpython_only + @requires_specialization_ft + def test_unpack_sequence(self): + def f(): + for _ in range(100): + a, b = 1, 2 + self.assertEqual(a, 1) + self.assertEqual(b, 2) + + f() + self.assert_specialized(f, "UNPACK_SEQUENCE_TWO_TUPLE") + self.assert_no_opcode(f, "UNPACK_SEQUENCE") + + def g(): + for _ in range(100): + a, = 1, + self.assertEqual(a, 1) + + g() + self.assert_specialized(g, "UNPACK_SEQUENCE_TUPLE") + self.assert_no_opcode(g, "UNPACK_SEQUENCE") + + def x(): + for _ in range(100): + a, b = [1, 2] + self.assertEqual(a, 1) + self.assertEqual(b, 2) + + x() + self.assert_specialized(x, "UNPACK_SEQUENCE_LIST") + self.assert_no_opcode(x, "UNPACK_SEQUENCE") if __name__ == "__main__": unittest.main() From d49e9e637bf68c743af41bccb1e161ddf8529ebf Mon Sep 17 00:00:00 2001 From: Kirill Podoprigora Date: Fri, 8 Nov 2024 23:57:27 +0200 Subject: [PATCH 3/6] Address Matt's review --- Include/internal/pycore_opcode_metadata.h | 2 +- Include/internal/pycore_uop_metadata.h | 2 +- Python/bytecodes.c | 20 ++++++++++++------- Python/executor_cases.c.h | 22 +++++++++++++++------ Python/generated_cases.c.h | 24 ++++++++++++++++------- 5 files changed, 48 insertions(+), 22 deletions(-) diff --git a/Include/internal/pycore_opcode_metadata.h b/Include/internal/pycore_opcode_metadata.h index 58e583eabbcc46..53280875f10429 100644 --- a/Include/internal/pycore_opcode_metadata.h +++ b/Include/internal/pycore_opcode_metadata.h @@ -1223,7 +1223,7 @@ const struct opcode_metadata _PyOpcode_opcode_metadata[266] = { [UNARY_NOT] = { true, INSTR_FMT_IX, HAS_PURE_FLAG }, [UNPACK_EX] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, [UNPACK_SEQUENCE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, - [UNPACK_SEQUENCE_LIST] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_DEOPT_FLAG }, + [UNPACK_SEQUENCE_LIST] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_ESCAPES_FLAG }, [UNPACK_SEQUENCE_TUPLE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_DEOPT_FLAG }, [UNPACK_SEQUENCE_TWO_TUPLE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_DEOPT_FLAG }, [WITH_EXCEPT_START] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, diff --git a/Include/internal/pycore_uop_metadata.h b/Include/internal/pycore_uop_metadata.h index 98a41d1f23f569..a07e4e6ff962b7 100644 --- a/Include/internal/pycore_uop_metadata.h +++ b/Include/internal/pycore_uop_metadata.h @@ -112,7 +112,7 @@ const uint16_t _PyUop_Flags[MAX_UOP_ID+1] = { [_UNPACK_SEQUENCE] = HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG, [_UNPACK_SEQUENCE_TWO_TUPLE] = HAS_ARG_FLAG | HAS_DEOPT_FLAG, [_UNPACK_SEQUENCE_TUPLE] = HAS_ARG_FLAG | HAS_DEOPT_FLAG, - [_UNPACK_SEQUENCE_LIST] = HAS_ARG_FLAG | HAS_DEOPT_FLAG, + [_UNPACK_SEQUENCE_LIST] = HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_ESCAPES_FLAG, [_UNPACK_EX] = HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG, [_STORE_ATTR] = HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG, [_DELETE_ATTR] = HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG, diff --git a/Python/bytecodes.c b/Python/bytecodes.c index 3b7c0f5c1dfe4e..91862815c7b193 100644 --- a/Python/bytecodes.c +++ b/Python/bytecodes.c @@ -1389,7 +1389,7 @@ dummy_func( } OPCODE_DEFERRED_INC(UNPACK_SEQUENCE); ADVANCE_ADAPTIVE_COUNTER(this_instr[1].counter); - #endif /* ENABLE_SPECIALIZATION */ + #endif /* ENABLE_SPECIALIZATION_FT */ (void)seq; (void)counter; } @@ -1429,12 +1429,18 @@ dummy_func( inst(UNPACK_SEQUENCE_LIST, (unused/1, seq -- values[oparg])) { PyObject *seq_o = PyStackRef_AsPyObjectBorrow(seq); DEOPT_IF(!PyList_CheckExact(seq_o)); - DEOPT_IF(PyList_GET_SIZE(seq_o) != oparg); - STAT_INC(UNPACK_SEQUENCE, hit); - PyObject **items = _PyList_ITEMS(seq_o); - for (int i = oparg; --i >= 0; ) { - *values++ = PyStackRef_FromPyObjectNew(items[i]); + int should_deopt = 0; + Py_BEGIN_CRITICAL_SECTION(seq_o); + should_deopt = PyList_GET_SIZE(seq_o) != oparg; + if (!should_deopt) { + STAT_INC(UNPACK_SEQUENCE, hit); + PyObject **items = _PyList_ITEMS(seq_o); + for (int i = oparg; --i >= 0; ) { + *values++ = PyStackRef_FromPyObjectNew(items[i]); + } } + Py_END_CRITICAL_SECTION(); + DEOPT_IF(should_deopt); DECREF_INPUTS(); } @@ -2516,7 +2522,7 @@ dummy_func( } OPCODE_DEFERRED_INC(CONTAINS_OP); ADVANCE_ADAPTIVE_COUNTER(this_instr[1].counter); - #endif /* ENABLE_SPECIALIZATION */ + #endif /* ENABLE_SPECIALIZATION_FT */ } macro(CONTAINS_OP) = _SPECIALIZE_CONTAINS_OP + _CONTAINS_OP; diff --git a/Python/executor_cases.c.h b/Python/executor_cases.c.h index 1d63402214db5d..ac88c650609508 100644 --- a/Python/executor_cases.c.h +++ b/Python/executor_cases.c.h @@ -1711,15 +1711,25 @@ UOP_STAT_INC(uopcode, miss); JUMP_TO_JUMP_TARGET(); } - if (PyList_GET_SIZE(seq_o) != oparg) { + int should_deopt = 0; + _PyFrame_SetStackPointer(frame, stack_pointer); + Py_BEGIN_CRITICAL_SECTION(seq_o); + stack_pointer = _PyFrame_GetStackPointer(frame); + should_deopt = PyList_GET_SIZE(seq_o) != oparg; + if (!should_deopt) { + STAT_INC(UNPACK_SEQUENCE, hit); + PyObject **items = _PyList_ITEMS(seq_o); + for (int i = oparg; --i >= 0; ) { + *values++ = PyStackRef_FromPyObjectNew(items[i]); + } + } + _PyFrame_SetStackPointer(frame, stack_pointer); + Py_END_CRITICAL_SECTION(); + stack_pointer = _PyFrame_GetStackPointer(frame); + if (should_deopt) { UOP_STAT_INC(uopcode, miss); JUMP_TO_JUMP_TARGET(); } - STAT_INC(UNPACK_SEQUENCE, hit); - PyObject **items = _PyList_ITEMS(seq_o); - for (int i = oparg; --i >= 0; ) { - *values++ = PyStackRef_FromPyObjectNew(items[i]); - } PyStackRef_CLOSE(seq); stack_pointer += -1 + oparg; assert(WITHIN_STACK_BOUNDS()); diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h index c44d6d9e3e509e..cfc180d0141ec4 100644 --- a/Python/generated_cases.c.h +++ b/Python/generated_cases.c.h @@ -3405,7 +3405,7 @@ } OPCODE_DEFERRED_INC(CONTAINS_OP); ADVANCE_ADAPTIVE_COUNTER(this_instr[1].counter); - #endif /* ENABLE_SPECIALIZATION */ + #endif /* ENABLE_SPECIALIZATION_FT */ } // _CONTAINS_OP { @@ -7992,7 +7992,7 @@ } OPCODE_DEFERRED_INC(UNPACK_SEQUENCE); ADVANCE_ADAPTIVE_COUNTER(this_instr[1].counter); - #endif /* ENABLE_SPECIALIZATION */ + #endif /* ENABLE_SPECIALIZATION_FT */ (void)seq; (void)counter; } @@ -8023,12 +8023,22 @@ values = &stack_pointer[-1]; PyObject *seq_o = PyStackRef_AsPyObjectBorrow(seq); DEOPT_IF(!PyList_CheckExact(seq_o), UNPACK_SEQUENCE); - DEOPT_IF(PyList_GET_SIZE(seq_o) != oparg, UNPACK_SEQUENCE); - STAT_INC(UNPACK_SEQUENCE, hit); - PyObject **items = _PyList_ITEMS(seq_o); - for (int i = oparg; --i >= 0; ) { - *values++ = PyStackRef_FromPyObjectNew(items[i]); + int should_deopt = 0; + _PyFrame_SetStackPointer(frame, stack_pointer); + Py_BEGIN_CRITICAL_SECTION(seq_o); + stack_pointer = _PyFrame_GetStackPointer(frame); + should_deopt = PyList_GET_SIZE(seq_o) != oparg; + if (!should_deopt) { + STAT_INC(UNPACK_SEQUENCE, hit); + PyObject **items = _PyList_ITEMS(seq_o); + for (int i = oparg; --i >= 0; ) { + *values++ = PyStackRef_FromPyObjectNew(items[i]); + } } + _PyFrame_SetStackPointer(frame, stack_pointer); + Py_END_CRITICAL_SECTION(); + stack_pointer = _PyFrame_GetStackPointer(frame); + DEOPT_IF(should_deopt, UNPACK_SEQUENCE); PyStackRef_CLOSE(seq); stack_pointer += -1 + oparg; assert(WITHIN_STACK_BOUNDS()); From ea1abf37f02a400ca96bf95feb9df3f7b204c95b Mon Sep 17 00:00:00 2001 From: Matt Page Date: Fri, 15 Nov 2024 14:54:43 -0800 Subject: [PATCH 4/6] Refactor UNPACK_SEQUENCE_LIST --- Python/bytecodes.c | 28 +++++++++++++++++----------- Python/executor_cases.c.h | 34 +++++++++++++++++++++------------- Python/generated_cases.c.h | 30 +++++++++++++++++++----------- 3 files changed, 57 insertions(+), 35 deletions(-) diff --git a/Python/bytecodes.c b/Python/bytecodes.c index 91862815c7b193..30f220c9b4215d 100644 --- a/Python/bytecodes.c +++ b/Python/bytecodes.c @@ -1429,18 +1429,24 @@ dummy_func( inst(UNPACK_SEQUENCE_LIST, (unused/1, seq -- values[oparg])) { PyObject *seq_o = PyStackRef_AsPyObjectBorrow(seq); DEOPT_IF(!PyList_CheckExact(seq_o)); - int should_deopt = 0; - Py_BEGIN_CRITICAL_SECTION(seq_o); - should_deopt = PyList_GET_SIZE(seq_o) != oparg; - if (!should_deopt) { - STAT_INC(UNPACK_SEQUENCE, hit); - PyObject **items = _PyList_ITEMS(seq_o); - for (int i = oparg; --i >= 0; ) { - *values++ = PyStackRef_FromPyObjectNew(items[i]); - } + #ifdef Py_GIL_DISABLED + PyCriticalSection cs; + PyCriticalSection_Begin(&cs, seq_o); + #endif + if (PyList_GET_SIZE(seq_o) != oparg) { + #ifdef Py_GIL_DISABLED + PyCriticalSection_End(&cs); + #endif + DEOPT_IF(true); + } + STAT_INC(UNPACK_SEQUENCE, hit); + PyObject **items = _PyList_ITEMS(seq_o); + for (int i = oparg; --i >= 0; ) { + *values++ = PyStackRef_FromPyObjectNew(items[i]); } - Py_END_CRITICAL_SECTION(); - DEOPT_IF(should_deopt); + #ifdef Py_GIL_DISABLED + PyCriticalSection_End(&cs); + #endif DECREF_INPUTS(); } diff --git a/Python/executor_cases.c.h b/Python/executor_cases.c.h index ac88c650609508..02257dfc16c36b 100644 --- a/Python/executor_cases.c.h +++ b/Python/executor_cases.c.h @@ -1711,25 +1711,33 @@ UOP_STAT_INC(uopcode, miss); JUMP_TO_JUMP_TARGET(); } - int should_deopt = 0; + #ifdef Py_GIL_DISABLED + PyCriticalSection cs; _PyFrame_SetStackPointer(frame, stack_pointer); - Py_BEGIN_CRITICAL_SECTION(seq_o); + PyCriticalSection_Begin(&cs, seq_o); stack_pointer = _PyFrame_GetStackPointer(frame); - should_deopt = PyList_GET_SIZE(seq_o) != oparg; - if (!should_deopt) { - STAT_INC(UNPACK_SEQUENCE, hit); - PyObject **items = _PyList_ITEMS(seq_o); - for (int i = oparg; --i >= 0; ) { - *values++ = PyStackRef_FromPyObjectNew(items[i]); + #endif + if (PyList_GET_SIZE(seq_o) != oparg) { + #ifdef Py_GIL_DISABLED + _PyFrame_SetStackPointer(frame, stack_pointer); + PyCriticalSection_End(&cs); + stack_pointer = _PyFrame_GetStackPointer(frame); + #endif + if (true) { + UOP_STAT_INC(uopcode, miss); + JUMP_TO_JUMP_TARGET(); } } + STAT_INC(UNPACK_SEQUENCE, hit); + PyObject **items = _PyList_ITEMS(seq_o); + for (int i = oparg; --i >= 0; ) { + *values++ = PyStackRef_FromPyObjectNew(items[i]); + } + #ifdef Py_GIL_DISABLED _PyFrame_SetStackPointer(frame, stack_pointer); - Py_END_CRITICAL_SECTION(); + PyCriticalSection_End(&cs); stack_pointer = _PyFrame_GetStackPointer(frame); - if (should_deopt) { - UOP_STAT_INC(uopcode, miss); - JUMP_TO_JUMP_TARGET(); - } + #endif PyStackRef_CLOSE(seq); stack_pointer += -1 + oparg; assert(WITHIN_STACK_BOUNDS()); diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h index cfc180d0141ec4..40fc459d8df2ae 100644 --- a/Python/generated_cases.c.h +++ b/Python/generated_cases.c.h @@ -8023,22 +8023,30 @@ values = &stack_pointer[-1]; PyObject *seq_o = PyStackRef_AsPyObjectBorrow(seq); DEOPT_IF(!PyList_CheckExact(seq_o), UNPACK_SEQUENCE); - int should_deopt = 0; + #ifdef Py_GIL_DISABLED + PyCriticalSection cs; _PyFrame_SetStackPointer(frame, stack_pointer); - Py_BEGIN_CRITICAL_SECTION(seq_o); + PyCriticalSection_Begin(&cs, seq_o); stack_pointer = _PyFrame_GetStackPointer(frame); - should_deopt = PyList_GET_SIZE(seq_o) != oparg; - if (!should_deopt) { - STAT_INC(UNPACK_SEQUENCE, hit); - PyObject **items = _PyList_ITEMS(seq_o); - for (int i = oparg; --i >= 0; ) { - *values++ = PyStackRef_FromPyObjectNew(items[i]); - } + #endif + if (PyList_GET_SIZE(seq_o) != oparg) { + #ifdef Py_GIL_DISABLED + _PyFrame_SetStackPointer(frame, stack_pointer); + PyCriticalSection_End(&cs); + stack_pointer = _PyFrame_GetStackPointer(frame); + #endif + DEOPT_IF(true, UNPACK_SEQUENCE); } + STAT_INC(UNPACK_SEQUENCE, hit); + PyObject **items = _PyList_ITEMS(seq_o); + for (int i = oparg; --i >= 0; ) { + *values++ = PyStackRef_FromPyObjectNew(items[i]); + } + #ifdef Py_GIL_DISABLED _PyFrame_SetStackPointer(frame, stack_pointer); - Py_END_CRITICAL_SECTION(); + PyCriticalSection_End(&cs); stack_pointer = _PyFrame_GetStackPointer(frame); - DEOPT_IF(should_deopt, UNPACK_SEQUENCE); + #endif PyStackRef_CLOSE(seq); stack_pointer += -1 + oparg; assert(WITHIN_STACK_BOUNDS()); From 66a2d675764763ba30a35ec195fcde0d4769269f Mon Sep 17 00:00:00 2001 From: Kirill Podoprigora Date: Thu, 21 Nov 2024 14:01:02 +0200 Subject: [PATCH 5/6] Align PR with recent changes --- Python/specialize.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/Python/specialize.c b/Python/specialize.c index 8ec9b49746c58e..493b37b772c682 100644 --- a/Python/specialize.c +++ b/Python/specialize.c @@ -2466,6 +2466,7 @@ _Py_Specialize_CompareOp(_PyStackRef lhs_st, _PyStackRef rhs_st, _Py_CODEUNIT *i cache->counter = adaptive_counter_cooldown(); } +#ifdef Py_STATS static int unpack_sequence_fail_kind(PyObject *seq) { @@ -2477,6 +2478,7 @@ unpack_sequence_fail_kind(PyObject *seq) } return SPEC_FAIL_OTHER; } +#endif void _Py_Specialize_UnpackSequence(_PyStackRef seq_st, _Py_CODEUNIT *instr, int oparg) @@ -2488,7 +2490,8 @@ _Py_Specialize_UnpackSequence(_PyStackRef seq_st, _Py_CODEUNIT *instr, int oparg INLINE_CACHE_ENTRIES_UNPACK_SEQUENCE); if (PyTuple_CheckExact(seq)) { if (PyTuple_GET_SIZE(seq) != oparg) { - unspecialize(instr, SPEC_FAIL_EXPECTED_ERROR); + SPECIALIZATION_FAIL(UNPACK_SEQUENCE, SPEC_FAIL_EXPECTED_ERROR); + unspecialize(instr); return; } if (PyTuple_GET_SIZE(seq) == 2) { @@ -2500,13 +2503,15 @@ _Py_Specialize_UnpackSequence(_PyStackRef seq_st, _Py_CODEUNIT *instr, int oparg } if (PyList_CheckExact(seq)) { if (PyList_GET_SIZE(seq) != oparg) { - unspecialize(instr, SPEC_FAIL_EXPECTED_ERROR); + SPECIALIZATION_FAIL(UNPACK_SEQUENCE, SPEC_FAIL_EXPECTED_ERROR); + unspecialize(instr); return; } specialize(instr, UNPACK_SEQUENCE_LIST); return; } - unspecialize(instr, unpack_sequence_fail_kind(seq)); + SPECIALIZATION_FAIL(UNPACK_SEQUENCE, unpack_sequence_fail_kind(seq)); + unspecialize(instr); } #ifdef Py_STATS From 16093d6dfc4367e10839f037937f4af264574a7b Mon Sep 17 00:00:00 2001 From: Kirill Podoprigora Date: Thu, 21 Nov 2024 19:15:58 +0200 Subject: [PATCH 6/6] Update Python/specialize.c Co-authored-by: mpage --- Python/specialize.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Python/specialize.c b/Python/specialize.c index 493b37b772c682..43250ff778a407 100644 --- a/Python/specialize.c +++ b/Python/specialize.c @@ -2478,7 +2478,7 @@ unpack_sequence_fail_kind(PyObject *seq) } return SPEC_FAIL_OTHER; } -#endif +#endif // Py_STATS void _Py_Specialize_UnpackSequence(_PyStackRef seq_st, _Py_CODEUNIT *instr, int oparg)