diff options
author | Brandt Bucher <brandtbucher@microsoft.com> | 2022-02-16 16:48:16 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-02-16 16:48:16 (GMT) |
commit | a9da085015db8cbb81f660158864ac94fe6c67a2 (patch) | |
tree | c24578d6baf4b19b1e57598c32797ec9b17aaf99 /Python/ceval.c | |
parent | e8a19b092fc0551581e10d6f310dd5feabac7609 (diff) | |
download | cpython-a9da085015db8cbb81f660158864ac94fe6c67a2.zip cpython-a9da085015db8cbb81f660158864ac94fe6c67a2.tar.gz cpython-a9da085015db8cbb81f660158864ac94fe6c67a2.tar.bz2 |
bpo-46702: Specialize UNPACK_SEQUENCE (GH-31240)
Diffstat (limited to 'Python/ceval.c')
-rw-r--r-- | Python/ceval.c | 99 |
1 files changed, 66 insertions, 33 deletions
diff --git a/Python/ceval.c b/Python/ceval.c index ad8b054..b900de5 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -2738,52 +2738,84 @@ handle_eval_breaker: TARGET(UNPACK_SEQUENCE) { PREDICTED(UNPACK_SEQUENCE); - PyObject *seq = POP(), *item, **items; -#ifdef Py_STATS - extern int _PySpecialization_ClassifySequence(PyObject *, int); - _py_stats.opcode_stats[UNPACK_SEQUENCE].specialization.failure++; - _py_stats.opcode_stats[UNPACK_SEQUENCE].specialization. - failure_kinds[_PySpecialization_ClassifySequence(seq, oparg)]++; -#endif - if (PyTuple_CheckExact(seq) && - PyTuple_GET_SIZE(seq) == oparg) { - items = ((PyTupleObject *)seq)->ob_item; - while (oparg--) { - item = items[oparg]; - Py_INCREF(item); - PUSH(item); - } - } else if (PyList_CheckExact(seq) && - PyList_GET_SIZE(seq) == oparg) { - items = ((PyListObject *)seq)->ob_item; - while (oparg--) { - item = items[oparg]; - Py_INCREF(item); - PUSH(item); - } - } else if (unpack_iterable(tstate, seq, oparg, -1, - stack_pointer + oparg)) { - STACK_GROW(oparg); - } else { - /* unpack_iterable() raised an exception */ + PyObject *seq = POP(); + PyObject **top = stack_pointer + oparg; + if (!unpack_iterable(tstate, seq, oparg, -1, top)) { Py_DECREF(seq); goto error; } + STACK_GROW(oparg); Py_DECREF(seq); DISPATCH(); } + TARGET(UNPACK_SEQUENCE_ADAPTIVE) { + assert(cframe.use_tracing == 0); + SpecializedCacheEntry *cache = GET_CACHE(); + if (cache->adaptive.counter == 0) { + PyObject *seq = TOP(); + next_instr--; + _Py_Specialize_UnpackSequence(seq, next_instr, cache); + DISPATCH(); + } + else { + STAT_INC(UNPACK_SEQUENCE, deferred); + cache->adaptive.counter--; + oparg = cache->adaptive.original_oparg; + JUMP_TO_INSTRUCTION(UNPACK_SEQUENCE); + } + } + + TARGET(UNPACK_SEQUENCE_TWO_TUPLE) { + PyObject *seq = TOP(); + DEOPT_IF(!PyTuple_CheckExact(seq), UNPACK_SEQUENCE); + DEOPT_IF(PyTuple_GET_SIZE(seq) != 2, UNPACK_SEQUENCE); + STAT_INC(UNPACK_SEQUENCE, hit); + SET_TOP(Py_NewRef(PyTuple_GET_ITEM(seq, 1))); + PUSH(Py_NewRef(PyTuple_GET_ITEM(seq, 0))); + Py_DECREF(seq); + NOTRACE_DISPATCH(); + } + + TARGET(UNPACK_SEQUENCE_TUPLE) { + PyObject *seq = TOP(); + int len = GET_CACHE()->adaptive.original_oparg; + DEOPT_IF(!PyTuple_CheckExact(seq), UNPACK_SEQUENCE); + DEOPT_IF(PyTuple_GET_SIZE(seq) != len, UNPACK_SEQUENCE); + STAT_INC(UNPACK_SEQUENCE, hit); + STACK_SHRINK(1); + PyObject **items = _PyTuple_ITEMS(seq); + while (len--) { + PUSH(Py_NewRef(items[len])); + } + Py_DECREF(seq); + NOTRACE_DISPATCH(); + } + + TARGET(UNPACK_SEQUENCE_LIST) { + PyObject *seq = TOP(); + int len = GET_CACHE()->adaptive.original_oparg; + DEOPT_IF(!PyList_CheckExact(seq), UNPACK_SEQUENCE); + DEOPT_IF(PyList_GET_SIZE(seq) != len, UNPACK_SEQUENCE); + STAT_INC(UNPACK_SEQUENCE, hit); + STACK_SHRINK(1); + PyObject **items = _PyList_ITEMS(seq); + while (len--) { + PUSH(Py_NewRef(items[len])); + } + Py_DECREF(seq); + NOTRACE_DISPATCH(); + } + TARGET(UNPACK_EX) { int totalargs = 1 + (oparg & 0xFF) + (oparg >> 8); PyObject *seq = POP(); - - if (unpack_iterable(tstate, seq, oparg & 0xFF, oparg >> 8, - stack_pointer + totalargs)) { - stack_pointer += totalargs; - } else { + PyObject **top = stack_pointer + totalargs; + if (!unpack_iterable(tstate, seq, oparg & 0xFF, oparg >> 8, top)) { Py_DECREF(seq); goto error; } + STACK_GROW(totalargs); Py_DECREF(seq); DISPATCH(); } @@ -5396,6 +5428,7 @@ MISS_WITH_CACHE(CALL) MISS_WITH_CACHE(BINARY_OP) MISS_WITH_CACHE(COMPARE_OP) MISS_WITH_CACHE(BINARY_SUBSCR) +MISS_WITH_CACHE(UNPACK_SEQUENCE) MISS_WITH_OPARG_COUNTER(STORE_SUBSCR) binary_subscr_dict_error: |