diff options
author | Dennis Sweeney <36520290+sweeneyde@users.noreply.github.com> | 2022-06-21 10:19:26 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-06-21 10:19:26 (GMT) |
commit | 5fcfdd87c9b5066a581d3ccb4b2fede938f343ec (patch) | |
tree | 8d333af15ee960d109d32163e005beefb2a16900 /Python/specialize.c | |
parent | c735d545343c3ab002c62596b2fb2cfa4488b0af (diff) | |
download | cpython-5fcfdd87c9b5066a581d3ccb4b2fede938f343ec.zip cpython-5fcfdd87c9b5066a581d3ccb4b2fede938f343ec.tar.gz cpython-5fcfdd87c9b5066a581d3ccb4b2fede938f343ec.tar.bz2 |
GH-91432: Specialize FOR_ITER (GH-91713)
* Adds FOR_ITER_LIST and FOR_ITER_RANGE specializations.
* Adds _PyLong_AssignValue() internal function to avoid temporary boxing of ints.
Diffstat (limited to 'Python/specialize.c')
-rw-r--r-- | Python/specialize.c | 31 |
1 files changed, 31 insertions, 0 deletions
diff --git a/Python/specialize.c b/Python/specialize.c index 3922b1e..c9cf35f 100644 --- a/Python/specialize.c +++ b/Python/specialize.c @@ -28,6 +28,7 @@ uint8_t _PyOpcode_Adaptive[256] = { [BINARY_OP] = BINARY_OP_ADAPTIVE, [COMPARE_OP] = COMPARE_OP_ADAPTIVE, [UNPACK_SEQUENCE] = UNPACK_SEQUENCE_ADAPTIVE, + [FOR_ITER] = FOR_ITER_ADAPTIVE, }; Py_ssize_t _Py_QuickenedCount = 0; @@ -2092,3 +2093,33 @@ int } #endif + +void +_Py_Specialize_ForIter(PyObject *iter, _Py_CODEUNIT *instr) +{ + assert(_PyOpcode_Caches[FOR_ITER] == INLINE_CACHE_ENTRIES_FOR_ITER); + _PyForIterCache *cache = (_PyForIterCache *)(instr + 1); + PyTypeObject *tp = Py_TYPE(iter); + _Py_CODEUNIT next = instr[1+INLINE_CACHE_ENTRIES_FOR_ITER]; + int next_op = _PyOpcode_Deopt[_Py_OPCODE(next)]; + if (tp == &PyListIter_Type) { + _Py_SET_OPCODE(*instr, FOR_ITER_LIST); + goto success; + } + else if (tp == &PyRangeIter_Type && next_op == STORE_FAST) { + _Py_SET_OPCODE(*instr, FOR_ITER_RANGE); + goto success; + } + else { + SPECIALIZATION_FAIL(FOR_ITER, + _PySpecialization_ClassifyIterator(iter)); + goto failure; + } +failure: + STAT_INC(FOR_ITER, failure); + cache->counter = adaptive_counter_backoff(cache->counter); + return; +success: + STAT_INC(FOR_ITER, success); + cache->counter = miss_counter_start(); +} |