Mercurial > cpython-lru_cache-weakref
diff Python/ceval.c @ 51920:ef8fe9088696 legacy-trunk
Backport r69961 to trunk, replacing JUMP_IF_{TRUE,FALSE} with
POP_JUMP_IF_{TRUE,FALSE} and JUMP_IF_{TRUE,FALSE}_OR_POP. This avoids executing
a POP_TOP on each conditional and sometimes allows the peephole optimizer to
skip a JUMP_ABSOLUTE entirely. It speeds up list comprehensions significantly.
| author | Jeffrey Yasskin <jyasskin@gmail.com> |
|---|---|
| date | Sat, 28 Feb 2009 19:03:21 +0000 |
| parents | 0848ebb8f9c8 |
| children | 9ef683d41c9b |
line wrap: on
line diff
--- a/Python/ceval.c Sat Feb 28 15:50:40 2009 +0000 +++ b/Python/ceval.c Sat Feb 28 19:03:21 2009 +0000 @@ -764,8 +764,8 @@ /* OpCode prediction macros Some opcodes tend to come in pairs thus making it possible to predict the second code when the first is run. For example, - COMPARE_OP is often followed by JUMP_IF_FALSE or JUMP_IF_TRUE. And, - those opcodes are often followed by a POP_TOP. + GET_ITER is often followed by FOR_ITER. And FOR_ITER is often + followed by STORE_FAST or UNPACK_SEQUENCE. Verifying the prediction costs a single high-speed test of a register variable against a constant. If the pairing was good, then the @@ -1110,7 +1110,6 @@ SETLOCAL(oparg, v); goto fast_next_opcode; - PREDICTED(POP_TOP); case POP_TOP: v = POP(); Py_DECREF(v); @@ -2220,8 +2219,8 @@ Py_DECREF(w); SET_TOP(x); if (x == NULL) break; - PREDICT(JUMP_IF_FALSE); - PREDICT(JUMP_IF_TRUE); + PREDICT(POP_JUMP_IF_FALSE); + PREDICT(POP_JUMP_IF_TRUE); continue; case IMPORT_NAME: @@ -2298,44 +2297,95 @@ JUMPBY(oparg); goto fast_next_opcode; - PREDICTED_WITH_ARG(JUMP_IF_FALSE); - case JUMP_IF_FALSE: - w = TOP(); + PREDICTED_WITH_ARG(POP_JUMP_IF_FALSE); + case POP_JUMP_IF_FALSE: + w = POP(); if (w == Py_True) { - PREDICT(POP_TOP); + Py_DECREF(w); goto fast_next_opcode; } if (w == Py_False) { - JUMPBY(oparg); + Py_DECREF(w); + JUMPTO(oparg); goto fast_next_opcode; } err = PyObject_IsTrue(w); + Py_DECREF(w); if (err > 0) err = 0; else if (err == 0) - JUMPBY(oparg); + JUMPTO(oparg); + else + break; + continue; + + PREDICTED_WITH_ARG(POP_JUMP_IF_TRUE); + case POP_JUMP_IF_TRUE: + w = POP(); + if (w == Py_False) { + Py_DECREF(w); + goto fast_next_opcode; + } + if (w == Py_True) { + Py_DECREF(w); + JUMPTO(oparg); + goto fast_next_opcode; + } + err = PyObject_IsTrue(w); + Py_DECREF(w); + if (err > 0) { + err = 0; + JUMPTO(oparg); + } + else if (err == 0) + ; else break; continue; - PREDICTED_WITH_ARG(JUMP_IF_TRUE); - case JUMP_IF_TRUE: + case JUMP_IF_FALSE_OR_POP: + w = TOP(); + if (w == Py_True) { + STACKADJ(-1); + Py_DECREF(w); + goto fast_next_opcode; + } + if (w == Py_False) { + JUMPTO(oparg); + goto fast_next_opcode; + } + err = PyObject_IsTrue(w); + if (err > 0) { + STACKADJ(-1); + Py_DECREF(w); + err = 0; + } + else if (err == 0) + JUMPTO(oparg); + else + break; + continue; + + case JUMP_IF_TRUE_OR_POP: w = TOP(); if (w == Py_False) { - PREDICT(POP_TOP); + STACKADJ(-1); + Py_DECREF(w); goto fast_next_opcode; } if (w == Py_True) { - JUMPBY(oparg); + JUMPTO(oparg); goto fast_next_opcode; } err = PyObject_IsTrue(w); if (err > 0) { err = 0; - JUMPBY(oparg); + JUMPTO(oparg); } - else if (err == 0) - ; + else if (err == 0) { + STACKADJ(-1); + Py_DECREF(w); + } else break; continue;
