python: Add performance patches from upstream 2.7 branch
PATCH 1/1 python: Add performance patches from upstream 2.7 branch
These performance patches result in about a 25% speed up of our parsing speed with bitbake. They're already applied in 1.7 upstream and backported from 3.X so worth applying for 2.7 too.
meta/recipes-devtools/python/python/17d3bbde60d2.patch new file +2293 -0
@@ -0,0 +1,2293 @@ + +# HG changeset patch +# User Benjamin Peterson <[email protected]> +# Date 1432835131 18000 +# Node ID 17d3bbde60d215225ddc0cf2135d3acca5398026 +# Parent 581776726b61b80d20e596ceaec6b5852aa29a70 +backport computed gotos (#4753) + +Upstream-Status: Backport +RP 2015/6/17 + +Index: Python-2.7.9/Include/opcode.h +=================================================================== +--- Python-2.7.9.orig/Include/opcode.h ++++ Python-2.7.9/Include/opcode.h +@@ -37,12 +37,21 @@ extern "C" { + + #define SLICE 30 + /* Also uses 31-33 */ ++#define SLICE_1 31 ++#define SLICE_2 32 ++#define SLICE_3 33 + + #define STORE_SLICE 40 + /* Also uses 41-43 */ ++#define STORE_SLICE_1 41 ++#define STORE_SLICE_2 42 ++#define STORE_SLICE_3 43 + + #define DELETE_SLICE 50 + /* Also uses 51-53 */ ++#define DELETE_SLICE_1 51 ++#define DELETE_SLICE_2 52 ++#define DELETE_SLICE_3 53 + + #define STORE_MAP 54 + #define INPLACE_ADD 55 +Index: Python-2.7.9/Makefile.pre.in +=================================================================== +--- Python-2.7.9.orig/Makefile.pre.in ++++ Python-2.7.9/Makefile.pre.in +@@ -302,6 +302,16 @@ ASDLGEN= $(srcdir)/Parser/asdl_c.py + + ########################################################################## + # Python ++ ++OPCODETARGETS_H= \ ++ $(srcdir)/Python/opcode_targets.h ++ ++OPCODETARGETGEN= \ ++ $(srcdir)/Python/makeopcodetargets.py ++ ++OPCODETARGETGEN_FILES= \ ++ $(OPCODETARGETGEN) $(srcdir)/Lib/opcode.py ++ + PYTHON_OBJS= \ + Python/_warnings.o \ + Python/Python-ast.o \ +@@ -672,6 +682,11 @@ Objects/bytearrayobject.o: $(srcdir)/Obj + Objects/stringobject.o: $(srcdir)/Objects/stringobject.c \ + $(STRINGLIB_HEADERS) + ++$(OPCODETARGETS_H): $(OPCODETARGETGEN_FILES) ++ $(OPCODETARGETGEN) $(OPCODETARGETS_H) ++ ++Python/ceval.o: $(OPCODETARGETS_H) ++ + Python/formatter_unicode.o: $(srcdir)/Python/formatter_unicode.c \ + $(STRINGLIB_HEADERS) + +Index: Python-2.7.9/Misc/NEWS +=================================================================== +--- Python-2.7.9.orig/Misc/NEWS ++++ Python-2.7.9/Misc/NEWS +@@ -41,6 +41,10 @@ What's New in Python 2.7.9 release candi + Core and Builtins + ----------------- + ++- Issue #4753: On compilers where it is supported, use "computed gotos" for ++ bytecode dispatch in the interpreter. This improves interpretation ++ performance. ++ + - Issue #21963: backout issue #1856 patch (avoid crashes and lockups when + daemon threads run while the interpreter is shutting down; instead, these + threads are now killed when they try to take the GIL), as it seems to +Index: Python-2.7.9/Python/ceval.c +=================================================================== +--- Python-2.7.9.orig/Python/ceval.c ++++ Python-2.7.9/Python/ceval.c +@@ -686,6 +686,100 @@ PyEval_EvalFrame(PyFrameObject *f) { + PyObject * + PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) + { ++#ifdef DYNAMIC_EXECUTION_PROFILE ++ #undef USE_COMPUTED_GOTOS ++#endif ++#ifdef HAVE_COMPUTED_GOTOS ++ #ifndef USE_COMPUTED_GOTOS ++ #define USE_COMPUTED_GOTOS 1 ++ #endif ++#else ++ #if defined(USE_COMPUTED_GOTOS) && USE_COMPUTED_GOTOS ++ #error "Computed gotos are not supported on this compiler." ++ #endif ++ #undef USE_COMPUTED_GOTOS ++ #define USE_COMPUTED_GOTOS 0 ++#endif ++#if USE_COMPUTED_GOTOS ++/* Import the static jump table */ ++#include "opcode_targets.h" ++ ++ /* This macro is used when several opcodes defer to the same implementation ++ (e.g. SETUP_LOOP, SETUP_FINALLY) */ ++#define TARGET_WITH_IMPL(op, impl) \ ++ TARGET_##op: \ ++ opcode = op; \ ++ oparg = NEXTARG(); \ ++ case op: \ ++ goto impl; \ ++ ++#define TARGET_WITH_IMPL_NOARG(op, impl) \ ++ TARGET_##op: \ ++ opcode = op; \ ++ case op: \ ++ goto impl; \ ++ ++#define TARGET_NOARG(op) \ ++ TARGET_##op: \ ++ opcode = op; \ ++ case op:\ ++ ++#define TARGET(op) \ ++ TARGET_##op: \ ++ opcode = op; \ ++ oparg = NEXTARG(); \ ++ case op:\ ++ ++ ++#define DISPATCH() \ ++ { \ ++ int _tick = _Py_Ticker - 1; \ ++ _Py_Ticker = _tick; \ ++ if (_tick >= 0) { \ ++ FAST_DISPATCH(); \ ++ } \ ++ continue; \ ++ } ++ ++#ifdef LLTRACE ++#define FAST_DISPATCH() \ ++ { \ ++ if (!lltrace && !_Py_TracingPossible) { \ ++ f->f_lasti = INSTR_OFFSET(); \ ++ goto *opcode_targets[*next_instr++]; \ ++ } \ ++ goto fast_next_opcode; \ ++ } ++#else ++#define FAST_DISPATCH() { \ ++ if (!_Py_TracingPossible) { \ ++ f->f_lasti = INSTR_OFFSET(); \ ++ goto *opcode_targets[*next_instr++]; \ ++ } \ ++ goto fast_next_opcode;\ ++} ++#endif ++ ++#else ++#define TARGET(op) \ ++ case op: ++#define TARGET_WITH_IMPL(op, impl) \ ++ /* silence compiler warnings about `impl` unused */ \ ++ if (0) goto impl; \ ++ case op:\ ++ ++#define TARGET_NOARG(op) \ ++ case op:\ ++ ++#define TARGET_WITH_IMPL_NOARG(op, impl) \ ++ if (0) goto impl; \ ++ case op:\ ++ ++#define DISPATCH() continue ++#define FAST_DISPATCH() goto fast_next_opcode ++#endif ++ ++ + #ifdef DXPAIRS + int lastopcode = 0; + #endif +@@ -803,14 +897,23 @@ PyEval_EvalFrameEx(PyFrameObject *f, int + counter updates for both opcodes. + */ + ++ ++// Next opcode prediction is also enabled for Computed Gotos as well. + #ifdef DYNAMIC_EXECUTION_PROFILE +-#define PREDICT(op) if (0) goto PRED_##op ++#define PREDICT(op) //if (0) goto PRED_##op ++#define PREDICTED(op) ++#define PREDICTED_WITH_ARG(op) + #else + #define PREDICT(op) if (*next_instr == op) goto PRED_##op +-#endif +- + #define PREDICTED(op) PRED_##op: next_instr++ ++#ifdef USE_COMPUTED_GOTOS ++#define PREDICTED_WITH_ARG(op) PRED_##op: next_instr++ ++#else + #define PREDICTED_WITH_ARG(op) PRED_##op: oparg = PEEKARG(); next_instr += 3 ++#endif ++#endif ++ ++ + + /* Stack manipulation macros */ + +@@ -1106,55 +1209,70 @@ PyEval_EvalFrameEx(PyFrameObject *f, int + + /* case STOP_CODE: this is an error! */ + +- case NOP: +- goto fast_next_opcode; ++ TARGET_NOARG(NOP) ++ { ++ FAST_DISPATCH(); ++ } + +- case LOAD_FAST: ++ TARGET(LOAD_FAST) ++ { + x = GETLOCAL(oparg); + if (x != NULL) { + Py_INCREF(x); + PUSH(x); +- goto fast_next_opcode; ++ FAST_DISPATCH(); + } + format_exc_check_arg(PyExc_UnboundLocalError, + UNBOUNDLOCAL_ERROR_MSG, + PyTuple_GetItem(co->co_varnames, oparg)); + break; ++ } + +- case LOAD_CONST: ++ TARGET(LOAD_CONST) ++ { + x = GETITEM(consts, oparg); + Py_INCREF(x); + PUSH(x); +- goto fast_next_opcode; ++ FAST_DISPATCH(); ++ } + + PREDICTED_WITH_ARG(STORE_FAST); +- case STORE_FAST: ++ TARGET(STORE_FAST) ++ { + v = POP(); + SETLOCAL(oparg, v); +- goto fast_next_opcode; ++ FAST_DISPATCH(); ++ } + +- case POP_TOP: ++ TARGET_NOARG(POP_TOP) ++ { + v = POP(); + Py_DECREF(v); +- goto fast_next_opcode; ++ FAST_DISPATCH(); ++ } + +- case ROT_TWO: ++ TARGET_NOARG(ROT_TWO) ++ { + v = TOP(); + w = SECOND(); + SET_TOP(w); + SET_SECOND(v); +- goto fast_next_opcode; ++ FAST_DISPATCH(); ++ } + +- case ROT_THREE: ++ TARGET_NOARG(ROT_THREE) ++ { + v = TOP(); + w = SECOND(); + x = THIRD(); + SET_TOP(w); + SET_SECOND(x); + SET_THIRD(v); +- goto fast_next_opcode; ++ FAST_DISPATCH(); ++ } + +- case ROT_FOUR: ++ TARGET_NOARG(ROT_FOUR) ++ { + u = TOP(); + v = SECOND(); + w = THIRD(); +@@ -1163,15 +1281,21 @@ PyEval_EvalFrameEx(PyFrameObject *f, int + SET_SECOND(w); + SET_THIRD(x); + SET_FOURTH(u); +- goto fast_next_opcode; ++ FAST_DISPATCH(); ++ } + +- case DUP_TOP: ++ ++ TARGET_NOARG(DUP_TOP) ++ { + v = TOP(); + Py_INCREF(v); + PUSH(v); +- goto fast_next_opcode; ++ FAST_DISPATCH(); ++ } + +- case DUP_TOPX: ++ ++ TARGET(DUP_TOPX) ++ { + if (oparg == 2) { + x = TOP(); + Py_INCREF(x); +@@ -1180,7 +1304,7 @@ PyEval_EvalFrameEx(PyFrameObject *f, int + STACKADJ(2); + SET_TOP(x); + SET_SECOND(w); +- goto fast_next_opcode; ++ FAST_DISPATCH(); + } else if (oparg == 3) { + x = TOP(); + Py_INCREF(x); +@@ -1192,84 +1316,100 @@ PyEval_EvalFrameEx(PyFrameObject *f, int + SET_TOP(x); + SET_SECOND(w); + SET_THIRD(v); +- goto fast_next_opcode; ++ FAST_DISPATCH(); + } + Py_FatalError("invalid argument to DUP_TOPX" + " (bytecode corruption?)"); + /* Never returns, so don't bother to set why. */ + break; ++ } + +- case UNARY_POSITIVE: ++ TARGET_NOARG(UNARY_POSITIVE) ++ { + v = TOP(); + x = PyNumber_Positive(v); + Py_DECREF(v); + SET_TOP(x); +- if (x != NULL) continue; ++ if (x != NULL) DISPATCH(); + break; ++ } + +- case UNARY_NEGATIVE: ++ TARGET_NOARG( UNARY_NEGATIVE) ++ { + v = TOP(); + x = PyNumber_Negative(v); + Py_DECREF(v); + SET_TOP(x); +- if (x != NULL) continue; ++ if (x != NULL) DISPATCH(); + break; ++ } + +- case UNARY_NOT: ++ TARGET_NOARG(UNARY_NOT) ++ { + v = TOP(); + err = PyObject_IsTrue(v); + Py_DECREF(v); + if (err == 0) { + Py_INCREF(Py_True); + SET_TOP(Py_True); +- continue; ++ DISPATCH(); + } + else if (err > 0) { + Py_INCREF(Py_False); + SET_TOP(Py_False); + err = 0; +- continue; ++ DISPATCH(); + } + STACKADJ(-1); + break; ++ } + +- case UNARY_CONVERT: ++ TARGET_NOARG(UNARY_CONVERT) ++ { + v = TOP(); + x = PyObject_Repr(v); + Py_DECREF(v); + SET_TOP(x); +- if (x != NULL) continue; ++ if (x != NULL) DISPATCH(); + break; ++ } + +- case UNARY_INVERT: ++ TARGET_NOARG(UNARY_INVERT) ++ { + v = TOP(); + x = PyNumber_Invert(v); + Py_DECREF(v); + SET_TOP(x); +- if (x != NULL) continue; ++ if (x != NULL) DISPATCH(); + break; ++ } + +- case BINARY_POWER: ++ TARGET_NOARG(BINARY_POWER) ++ { + w = POP(); + v = TOP(); + x = PyNumber_Power(v, w, Py_None); + Py_DECREF(v); + Py_DECREF(w); + SET_TOP(x); +- if (x != NULL) continue; ++ if (x != NULL) DISPATCH(); + break; ++ } + +- case BINARY_MULTIPLY: ++ TARGET_NOARG(BINARY_MULTIPLY) ++ { + w = POP(); + v = TOP(); + x = PyNumber_Multiply(v, w); + Py_DECREF(v); + Py_DECREF(w); + SET_TOP(x); +- if (x != NULL) continue; ++ if(x!=NULL) DISPATCH(); + break; ++ } + +- case BINARY_DIVIDE: ++ TARGET_NOARG(BINARY_DIVIDE) ++ { + if (!_Py_QnewFlag) { + w = POP(); + v = TOP(); +@@ -1277,32 +1417,37 @@ PyEval_EvalFrameEx(PyFrameObject *f, int + Py_DECREF(v); + Py_DECREF(w); + SET_TOP(x); +- if (x != NULL) continue; ++ if (x != NULL) DISPATCH(); + break; + } +- /* -Qnew is in effect: fall through to +- BINARY_TRUE_DIVIDE */ +- case BINARY_TRUE_DIVIDE: ++ } ++ /* -Qnew is in effect: fall through to BINARY_TRUE_DIVIDE */ ++ TARGET_NOARG(BINARY_TRUE_DIVIDE) ++ { + w = POP(); + v = TOP(); + x = PyNumber_TrueDivide(v, w); + Py_DECREF(v); + Py_DECREF(w); + SET_TOP(x); +- if (x != NULL) continue; ++ if (x != NULL) DISPATCH(); + break; ++ } + +- case BINARY_FLOOR_DIVIDE: ++ TARGET_NOARG(BINARY_FLOOR_DIVIDE) ++ { + w = POP(); + v = TOP(); + x = PyNumber_FloorDivide(v, w); + Py_DECREF(v); + Py_DECREF(w); + SET_TOP(x); +- if (x != NULL) continue; ++ if (x != NULL) DISPATCH(); + break; ++ } + +- case BINARY_MODULO: ++ TARGET_NOARG(BINARY_MODULO) ++ { + w = POP(); + v = TOP(); + if (PyString_CheckExact(v)) +@@ -1312,10 +1457,12 @@ PyEval_EvalFrameEx(PyFrameObject *f, int + Py_DECREF(v); + Py_DECREF(w); + SET_TOP(x); +- if (x != NULL) continue; ++ if (x != NULL) DISPATCH(); + break; ++ } + +- case BINARY_ADD: ++ TARGET_NOARG(BINARY_ADD) ++ { + w = POP(); + v = TOP(); + if (PyInt_CheckExact(v) && PyInt_CheckExact(w)) { +@@ -1344,10 +1491,12 @@ PyEval_EvalFrameEx(PyFrameObject *f, int + skip_decref_vx: + Py_DECREF(w); + SET_TOP(x); +- if (x != NULL) continue; ++ if (x != NULL) DISPATCH(); + break; ++ } + +- case BINARY_SUBTRACT: ++ TARGET_NOARG(BINARY_SUBTRACT) ++ { + w = POP(); + v = TOP(); + if (PyInt_CheckExact(v) && PyInt_CheckExact(w)) { +@@ -1369,10 +1518,12 @@ PyEval_EvalFrameEx(PyFrameObject *f, int + Py_DECREF(v); + Py_DECREF(w); + SET_TOP(x); +- if (x != NULL) continue; ++ if (x != NULL) DISPATCH(); + break; ++ } + +- case BINARY_SUBSCR: ++ TARGET_NOARG(BINARY_SUBSCR) ++ { + w = POP(); + v = TOP(); + if (PyList_CheckExact(v) && PyInt_CheckExact(w)) { +@@ -1393,102 +1544,122 @@ PyEval_EvalFrameEx(PyFrameObject *f, int + Py_DECREF(v); + Py_DECREF(w); + SET_TOP(x); +- if (x != NULL) continue; ++ if (x != NULL) DISPATCH(); + break; ++ } + +- case BINARY_LSHIFT: ++ TARGET_NOARG(BINARY_LSHIFT) ++ { + w = POP(); + v = TOP(); + x = PyNumber_Lshift(v, w); + Py_DECREF(v); + Py_DECREF(w); + SET_TOP(x); +- if (x != NULL) continue; ++ if (x != NULL) DISPATCH(); + break; ++ } + +- case BINARY_RSHIFT: ++ TARGET_NOARG(BINARY_RSHIFT) ++ { + w = POP(); + v = TOP(); + x = PyNumber_Rshift(v, w); + Py_DECREF(v); + Py_DECREF(w); + SET_TOP(x); +- if (x != NULL) continue; ++ if (x != NULL) DISPATCH(); + break; ++ } + +- case BINARY_AND: ++ TARGET_NOARG(BINARY_AND) ++ { + w = POP(); + v = TOP(); + x = PyNumber_And(v, w); + Py_DECREF(v); + Py_DECREF(w); + SET_TOP(x); +- if (x != NULL) continue; ++ if (x != NULL) DISPATCH(); + break; ++ } + +- case BINARY_XOR: ++ TARGET_NOARG(BINARY_XOR) ++ { + w = POP(); + v = TOP(); + x = PyNumber_Xor(v, w); + Py_DECREF(v); + Py_DECREF(w); + SET_TOP(x); +- if (x != NULL) continue; ++ if (x != NULL) DISPATCH(); + break; ++ } + +- case BINARY_OR: ++ TARGET_NOARG(BINARY_OR) ++ { + w = POP(); + v = TOP(); + x = PyNumber_Or(v, w); + Py_DECREF(v); + Py_DECREF(w); + SET_TOP(x); +- if (x != NULL) continue; ++ if (x != NULL) DISPATCH(); + break; ++ } + +- case LIST_APPEND: ++ TARGET(LIST_APPEND) ++ { + w = POP(); + v = PEEK(oparg); + err = PyList_Append(v, w); + Py_DECREF(w); + if (err == 0) { + PREDICT(JUMP_ABSOLUTE); +- continue; ++ DISPATCH(); + } + break; ++ } + +- case SET_ADD: ++ TARGET(SET_ADD) ++ { + w = POP(); + v = stack_pointer[-oparg]; + err = PySet_Add(v, w); + Py_DECREF(w); + if (err == 0) { + PREDICT(JUMP_ABSOLUTE); +- continue; ++ DISPATCH(); + } + break; ++ } + +- case INPLACE_POWER: ++ TARGET_NOARG(INPLACE_POWER) ++ { + w = POP(); + v = TOP(); + x = PyNumber_InPlacePower(v, w, Py_None); + Py_DECREF(v); + Py_DECREF(w); + SET_TOP(x); +- if (x != NULL) continue; ++ if (x != NULL) DISPATCH(); + break; ++ } + +- case INPLACE_MULTIPLY: ++ TARGET_NOARG(INPLACE_MULTIPLY) ++ { + w = POP(); + v = TOP(); + x = PyNumber_InPlaceMultiply(v, w); + Py_DECREF(v); + Py_DECREF(w); + SET_TOP(x); +- if (x != NULL) continue; ++ if (x != NULL) DISPATCH(); + break; ++ } + +- case INPLACE_DIVIDE: ++ TARGET_NOARG(INPLACE_DIVIDE) ++ { + if (!_Py_QnewFlag) { + w = POP(); + v = TOP(); +@@ -1496,42 +1667,50 @@ PyEval_EvalFrameEx(PyFrameObject *f, int + Py_DECREF(v); + Py_DECREF(w); + SET_TOP(x); +- if (x != NULL) continue; ++ if (x != NULL) DISPATCH(); + break; + } ++ } + /* -Qnew is in effect: fall through to + INPLACE_TRUE_DIVIDE */ +- case INPLACE_TRUE_DIVIDE: ++ TARGET_NOARG(INPLACE_TRUE_DIVIDE) ++ { + w = POP(); + v = TOP(); + x = PyNumber_InPlaceTrueDivide(v, w); + Py_DECREF(v); + Py_DECREF(w); + SET_TOP(x); +- if (x != NULL) continue; ++ if (x != NULL) DISPATCH(); + break; ++ } + +- case INPLACE_FLOOR_DIVIDE: ++ TARGET_NOARG(INPLACE_FLOOR_DIVIDE) ++ { + w = POP(); + v = TOP(); + x = PyNumber_InPlaceFloorDivide(v, w); + Py_DECREF(v); + Py_DECREF(w); + SET_TOP(x); +- if (x != NULL) continue; ++ if (x != NULL) DISPATCH(); + break; ++ } + +- case INPLACE_MODULO: ++ TARGET_NOARG(INPLACE_MODULO) ++ { + w = POP(); + v = TOP(); + x = PyNumber_InPlaceRemainder(v, w); + Py_DECREF(v); + Py_DECREF(w); + SET_TOP(x); +- if (x != NULL) continue; ++ if (x != NULL) DISPATCH(); + break; ++ } + +- case INPLACE_ADD: ++ TARGET_NOARG(INPLACE_ADD) ++ { + w = POP(); + v = TOP(); + if (PyInt_CheckExact(v) && PyInt_CheckExact(w)) { +@@ -1558,10 +1737,12 @@ PyEval_EvalFrameEx(PyFrameObject *f, int + skip_decref_v: + Py_DECREF(w); + SET_TOP(x); +- if (x != NULL) continue; ++ if (x != NULL) DISPATCH(); + break; ++ } + +- case INPLACE_SUBTRACT: ++ TARGET_NOARG(INPLACE_SUBTRACT) ++ { + w = POP(); + v = TOP(); + if (PyInt_CheckExact(v) && PyInt_CheckExact(w)) { +@@ -1581,63 +1762,78 @@ PyEval_EvalFrameEx(PyFrameObject *f, int + Py_DECREF(v); + Py_DECREF(w); + SET_TOP(x); +- if (x != NULL) continue; ++ if (x != NULL) DISPATCH(); + break; ++ } + +- case INPLACE_LSHIFT: ++ TARGET_NOARG(INPLACE_LSHIFT) ++ { + w = POP(); + v = TOP(); + x = PyNumber_InPlaceLshift(v, w); + Py_DECREF(v); + Py_DECREF(w); + SET_TOP(x); +- if (x != NULL) continue; ++ if (x != NULL) DISPATCH(); + break; ++ } + +- case INPLACE_RSHIFT: ++ TARGET_NOARG(INPLACE_RSHIFT) ++ { + w = POP(); + v = TOP(); + x = PyNumber_InPlaceRshift(v, w); + Py_DECREF(v); + Py_DECREF(w); + SET_TOP(x); +- if (x != NULL) continue; ++ if (x != NULL) DISPATCH(); + break; ++ } + +- case INPLACE_AND: ++ TARGET_NOARG(INPLACE_AND) ++ { + w = POP(); + v = TOP(); + x = PyNumber_InPlaceAnd(v, w); + Py_DECREF(v); + Py_DECREF(w); + SET_TOP(x); +- if (x != NULL) continue; ++ if (x != NULL) DISPATCH(); + break; ++ } + +- case INPLACE_XOR: ++ TARGET_NOARG(INPLACE_XOR) ++ { + w = POP(); + v = TOP(); + x = PyNumber_InPlaceXor(v, w); + Py_DECREF(v); + Py_DECREF(w); + SET_TOP(x); +- if (x != NULL) continue; ++ if (x != NULL) DISPATCH(); + break; ++ } + +- case INPLACE_OR: ++ TARGET_NOARG(INPLACE_OR) ++ { + w = POP(); + v = TOP(); + x = PyNumber_InPlaceOr(v, w); + Py_DECREF(v); + Py_DECREF(w); + SET_TOP(x); +- if (x != NULL) continue; ++ if (x != NULL) DISPATCH(); + break; ++ } ++ + +- case SLICE+0: +- case SLICE+1: +- case SLICE+2: +- case SLICE+3: ++ ++ TARGET_WITH_IMPL_NOARG(SLICE, _slice) ++ TARGET_WITH_IMPL_NOARG(SLICE_1, _slice) ++ TARGET_WITH_IMPL_NOARG(SLICE_2, _slice) ++ TARGET_WITH_IMPL_NOARG(SLICE_3, _slice) ++ _slice: ++ { + if ((opcode-SLICE) & 2) + w = POP(); + else +@@ -1652,13 +1848,17 @@ PyEval_EvalFrameEx(PyFrameObject *f, int + Py_XDECREF(v); + Py_XDECREF(w); + SET_TOP(x); +- if (x != NULL) continue; ++ if (x != NULL) DISPATCH(); + break; ++ } + +- case STORE_SLICE+0: +- case STORE_SLICE+1: +- case STORE_SLICE+2: +- case STORE_SLICE+3: ++ ++ TARGET_WITH_IMPL_NOARG(STORE_SLICE, _store_slice) ++ TARGET_WITH_IMPL_NOARG(STORE_SLICE_1, _store_slice) ++ TARGET_WITH_IMPL_NOARG(STORE_SLICE_2, _store_slice) ++ TARGET_WITH_IMPL_NOARG(STORE_SLICE_3, _store_slice) ++ _store_slice: ++ { + if ((opcode-STORE_SLICE) & 2) + w = POP(); + else +@@ -1674,13 +1874,17 @@ PyEval_EvalFrameEx(PyFrameObject *f, int + Py_DECREF(u); + Py_XDECREF(v); + Py_XDECREF(w); +- if (err == 0) continue; ++ if (err == 0) DISPATCH(); + break; ++ } + +- case DELETE_SLICE+0: +- case DELETE_SLICE+1: +- case DELETE_SLICE+2: +- case DELETE_SLICE+3: ++ ++ TARGET_WITH_IMPL_NOARG(DELETE_SLICE, _delete_slice) ++ TARGET_WITH_IMPL_NOARG(DELETE_SLICE_1, _delete_slice) ++ TARGET_WITH_IMPL_NOARG(DELETE_SLICE_2, _delete_slice) ++ TARGET_WITH_IMPL_NOARG(DELETE_SLICE_3, _delete_slice) ++ _delete_slice: ++ { + if ((opcode-DELETE_SLICE) & 2) + w = POP(); + else +@@ -1695,10 +1899,12 @@ PyEval_EvalFrameEx(PyFrameObject *f, int + Py_DECREF(u); + Py_XDECREF(v); + Py_XDECREF(w); +- if (err == 0) continue; ++ if (err == 0) DISPATCH(); + break; ++ } + +- case STORE_SUBSCR: ++ TARGET_NOARG(STORE_SUBSCR) ++ { + w = TOP(); + v = SECOND(); + u = THIRD(); +@@ -1708,10 +1914,12 @@ PyEval_EvalFrameEx(PyFrameObject *f, int + Py_DECREF(u); + Py_DECREF(v); + Py_DECREF(w); +- if (err == 0) continue; ++ if (err == 0) DISPATCH(); + break; ++ } + +- case DELETE_SUBSCR: ++ TARGET_NOARG(DELETE_SUBSCR) ++ { + w = TOP(); + v = SECOND(); + STACKADJ(-2); +@@ -1719,10 +1927,12 @@ PyEval_EvalFrameEx(PyFrameObject *f, int + err = PyObject_DelItem(v, w); + Py_DECREF(v); + Py_DECREF(w); +- if (err == 0) continue; ++ if (err == 0) DISPATCH(); + break; ++ } + +- case PRINT_EXPR: ++ TARGET_NOARG(PRINT_EXPR) ++ { + v = POP(); + w = PySys_GetObject("displayhook"); + if (w == NULL) { +@@ -1745,12 +1955,16 @@ PyEval_EvalFrameEx(PyFrameObject *f, int + Py_DECREF(v); + Py_XDECREF(x); + break; ++ } + +- case PRINT_ITEM_TO: ++ TARGET_NOARG(PRINT_ITEM_TO) ++ { + w = stream = POP(); + /* fall through to PRINT_ITEM */ ++ } + +- case PRINT_ITEM: ++ TARGET_NOARG(PRINT_ITEM) ++ { + v = POP(); + if (stream == NULL || stream == Py_None) { + w = PySys_GetObject("stdout"); +@@ -1796,16 +2010,20 @@ PyEval_EvalFrameEx(PyFrameObject *f, int + Py_DECREF(v); + Py_XDECREF(stream); + stream = NULL; +- if (err == 0) +- continue; ++ if (err == 0) DISPATCH(); + break; ++ } + +- case PRINT_NEWLINE_TO: ++ TARGET_NOARG(PRINT_NEWLINE_TO) ++ { + w = stream = POP(); + /* fall through to PRINT_NEWLINE */ ++ } + +- case PRINT_NEWLINE: +- if (stream == NULL || stream == Py_None) { ++ TARGET_NOARG(PRINT_NEWLINE) ++ { ++ if (stream == NULL || stream == Py_None) ++ { + w = PySys_GetObject("stdout"); + if (w == NULL) { + PyErr_SetString(PyExc_RuntimeError, +@@ -1825,12 +2043,14 @@ PyEval_EvalFrameEx(PyFrameObject *f, int + Py_XDECREF(stream); + stream = NULL; + break; +- ++ } + + #ifdef CASE_TOO_BIG + default: switch (opcode) { + #endif +- case RAISE_VARARGS: ++ ++ TARGET(RAISE_VARARGS) ++ { + u = v = w = NULL; + switch (oparg) { + case 3: +@@ -1851,28 +2071,37 @@ PyEval_EvalFrameEx(PyFrameObject *f, int + break; + } + break; ++ } + +- case LOAD_LOCALS: +- if ((x = f->f_locals) != NULL) { ++ TARGET_NOARG(LOAD_LOCALS) ++ { ++ if ((x = f->f_locals) != NULL) ++ { + Py_INCREF(x); + PUSH(x); +- continue; ++ DISPATCH(); + } + PyErr_SetString(PyExc_SystemError, "no locals"); + break; ++ } + +- case RETURN_VALUE: ++ TARGET_NOARG(RETURN_VALUE) ++ { + retval = POP(); + why = WHY_RETURN; + goto fast_block_end; ++ } + +- case YIELD_VALUE: ++ TARGET_NOARG(YIELD_VALUE) ++ { + retval = POP(); + f->f_stacktop = stack_pointer; + why = WHY_YIELD; + goto fast_yield; ++ } + +- case EXEC_STMT: ++ TARGET_NOARG(EXEC_STMT) ++ { + w = TOP(); + v = SECOND(); + u = THIRD(); +@@ -1884,8 +2113,10 @@ PyEval_EvalFrameEx(PyFrameObject *f, int + Py_DECREF(v); + Py_DECREF(w); + break; ++ } + +- case POP_BLOCK: ++ TARGET_NOARG(POP_BLOCK) ++ { + { + PyTryBlock *b = PyFrame_BlockPop(f); + while (STACK_LEVEL() > b->b_level) { +@@ -1893,10 +2124,12 @@ PyEval_EvalFrameEx(PyFrameObject *f, int + Py_DECREF(v); + } + } +- continue; ++ DISPATCH(); ++ } + + PREDICTED(END_FINALLY); +- case END_FINALLY: ++ TARGET_NOARG(END_FINALLY) ++ { + v = POP(); + if (PyInt_Check(v)) { + why = (enum why_code) PyInt_AS_LONG(v); +@@ -1920,8 +2153,10 @@ PyEval_EvalFrameEx(PyFrameObject *f, int + } + Py_DECREF(v); + break; ++ } + +- case BUILD_CLASS: ++ TARGET_NOARG(BUILD_CLASS) ++ { + u = TOP(); + v = SECOND(); + w = THIRD(); +@@ -1932,8 +2167,10 @@ PyEval_EvalFrameEx(PyFrameObject *f, int + Py_DECREF(v); + Py_DECREF(w); + break; ++ } + +- case STORE_NAME: ++ TARGET(STORE_NAME) ++ { + w = GETITEM(names, oparg); + v = POP(); + if ((x = f->f_locals) != NULL) { +@@ -1942,7 +2179,7 @@ PyEval_EvalFrameEx(PyFrameObject *f, int + else + err = PyObject_SetItem(x, w, v); + Py_DECREF(v); +- if (err == 0) continue; ++ if (err == 0) DISPATCH(); + break; + } + t = PyObject_Repr(w); +@@ -1953,8 +2190,10 @@ PyEval_EvalFrameEx(PyFrameObject *f, int + PyString_AS_STRING(t)); + Py_DECREF(t); + break; ++ } + +- case DELETE_NAME: ++ TARGET(DELETE_NAME) ++ { + w = GETITEM(names, oparg); + if ((x = f->f_locals) != NULL) { + if ((err = PyObject_DelItem(x, w)) != 0) +@@ -1971,9 +2210,11 @@ PyEval_EvalFrameEx(PyFrameObject *f, int + PyString_AS_STRING(w)); + Py_DECREF(t); + break; ++ } + + PREDICTED_WITH_ARG(UNPACK_SEQUENCE); +- case UNPACK_SEQUENCE: ++ TARGET(UNPACK_SEQUENCE) ++ { + v = POP(); + if (PyTuple_CheckExact(v) && + PyTuple_GET_SIZE(v) == oparg) { +@@ -1985,7 +2226,7 @@ PyEval_EvalFrameEx(PyFrameObject *f, int + PUSH(w); + } + Py_DECREF(v); +- continue; ++ DISPATCH(); + } else if (PyList_CheckExact(v) && + PyList_GET_SIZE(v) == oparg) { + PyObject **items = \ +@@ -2004,8 +2245,11 @@ PyEval_EvalFrameEx(PyFrameObject *f, int + } + Py_DECREF(v); + break; ++ } + +- case STORE_ATTR: ++ ++ TARGET(STORE_ATTR) ++ { + w = GETITEM(names, oparg); + v = TOP(); + u = SECOND(); +@@ -2013,33 +2257,42 @@ PyEval_EvalFrameEx(PyFrameObject *f, int + err = PyObject_SetAttr(v, w, u); /* v.w = u */ + Py_DECREF(v); + Py_DECREF(u); +- if (err == 0) continue; ++ if (err == 0) DISPATCH(); + break; ++ } + +- case DELETE_ATTR: ++ TARGET(DELETE_ATTR) ++ { + w = GETITEM(names, oparg); + v = POP(); + err = PyObject_SetAttr(v, w, (PyObject *)NULL); + /* del v.w */ + Py_DECREF(v); + break; ++ } ++ + +- case STORE_GLOBAL: ++ TARGET(STORE_GLOBAL) ++ { + w = GETITEM(names, oparg); + v = POP(); + err = PyDict_SetItem(f->f_globals, w, v); + Py_DECREF(v); +- if (err == 0) continue; ++ if (err == 0) DISPATCH(); + break; ++ } + +- case DELETE_GLOBAL: ++ TARGET(DELETE_GLOBAL) ++ { + w = GETITEM(names, oparg); + if ((err = PyDict_DelItem(f->f_globals, w)) != 0) + format_exc_check_arg( + PyExc_NameError, GLOBAL_NAME_ERROR_MSG, w); + break; ++ } + +- case LOAD_NAME: ++ TARGET(LOAD_NAME) ++ { + w = GETITEM(names, oparg); + if ((v = f->f_locals) == NULL) { + why = WHY_EXCEPTION; +@@ -2079,9 +2332,11 @@ PyEval_EvalFrameEx(PyFrameObject *f, int + Py_INCREF(x); + } + PUSH(x); +- continue; ++ DISPATCH(); ++ } + +- case LOAD_GLOBAL: ++ TARGET(LOAD_GLOBAL) ++ { + w = GETITEM(names, oparg); + if (PyString_CheckExact(w)) { + /* Inline the PyDict_GetItem() calls. +@@ -2101,7 +2356,7 @@ PyEval_EvalFrameEx(PyFrameObject *f, int + if (x != NULL) { + Py_INCREF(x); + PUSH(x); +- continue; ++ DISPATCH(); + } + d = (PyDictObject *)(f->f_builtins); + e = d->ma_lookup(d, w, hash); +@@ -2113,7 +2368,7 @@ PyEval_EvalFrameEx(PyFrameObject *f, int + if (x != NULL) { + Py_INCREF(x); + PUSH(x); +- continue; ++ DISPATCH(); + } + goto load_global_error; + } +@@ -2132,13 +2387,15 @@ PyEval_EvalFrameEx(PyFrameObject *f, int + } + Py_INCREF(x); + PUSH(x); +- continue; ++ DISPATCH(); ++ } + +- case DELETE_FAST: ++ TARGET(DELETE_FAST) ++ { + x = GETLOCAL(oparg); + if (x != NULL) { + SETLOCAL(oparg, NULL); +- continue; ++ DISPATCH(); + } + format_exc_check_arg( + PyExc_UnboundLocalError, +@@ -2146,20 +2403,24 @@ PyEval_EvalFrameEx(PyFrameObject *f, int + PyTuple_GetItem(co->co_varnames, oparg) + ); + break; ++ } + +- case LOAD_CLOSURE: ++ TARGET(LOAD_CLOSURE) ++ { + x = freevars[oparg]; + Py_INCREF(x); + PUSH(x); +- if (x != NULL) continue; ++ if (x != NULL) DISPATCH(); + break; ++ } + +- case LOAD_DEREF: ++ TARGET(LOAD_DEREF) ++ { + x = freevars[oparg]; + w = PyCell_Get(x); + if (w != NULL) { + PUSH(w); +- continue; ++ DISPATCH(); + } + err = -1; + /* Don't stomp existing exception */ +@@ -2179,15 +2440,19 @@ PyEval_EvalFrameEx(PyFrameObject *f, int + UNBOUNDFREE_ERROR_MSG, v); + } + break; ++ } + +- case STORE_DEREF: ++ TARGET(STORE_DEREF) ++ { + w = POP(); + x = freevars[oparg]; + PyCell_Set(x, w); + Py_DECREF(w); +- continue; ++ DISPATCH(); ++ } + +- case BUILD_TUPLE: ++ TARGET(BUILD_TUPLE) ++ { + x = PyTuple_New(oparg); + if (x != NULL) { + for (; --oparg >= 0;) { +@@ -2195,11 +2460,13 @@ PyEval_EvalFrameEx(PyFrameObject *f, int + PyTuple_SET_ITEM(x, oparg, w); + } + PUSH(x); +- continue; ++ DISPATCH(); + } + break; ++ } + +- case BUILD_LIST: ++ TARGET(BUILD_LIST) ++ { + x = PyList_New(oparg); + if (x != NULL) { + for (; --oparg >= 0;) { +@@ -2207,11 +2474,13 @@ PyEval_EvalFrameEx(PyFrameObject *f, int + PyList_SET_ITEM(x, oparg, w); + } + PUSH(x); +- continue; ++ DISPATCH(); + } + break; ++ } + +- case BUILD_SET: ++ TARGET(BUILD_SET) ++ { + x = PySet_New(NULL); + if (x != NULL) { + for (; --oparg >= 0;) { +@@ -2225,18 +2494,21 @@ PyEval_EvalFrameEx(PyFrameObject *f, int + break; + } + PUSH(x); +- continue; ++ DISPATCH(); + } + break; ++ } + +- +- case BUILD_MAP: ++ TARGET(BUILD_MAP) ++ { + x = _PyDict_NewPresized((Py_ssize_t)oparg); + PUSH(x); +- if (x != NULL) continue; ++ if (x != NULL) DISPATCH(); + break; ++ } + +- case STORE_MAP: ++ TARGET_NOARG(STORE_MAP) ++ { + w = TOP(); /* key */ + u = SECOND(); /* value */ + v = THIRD(); /* dict */ +@@ -2245,10 +2517,12 @@ PyEval_EvalFrameEx(PyFrameObject *f, int + err = PyDict_SetItem(v, w, u); /* v[w] = u */ + Py_DECREF(u); + Py_DECREF(w); +- if (err == 0) continue; ++ if (err == 0) DISPATCH(); + break; ++ } + +- case MAP_ADD: ++ TARGET(MAP_ADD) ++ { + w = TOP(); /* key */ + u = SECOND(); /* value */ + STACKADJ(-2); +@@ -2259,20 +2533,24 @@ PyEval_EvalFrameEx(PyFrameObject *f, int + Py_DECREF(w); + if (err == 0) { + PREDICT(JUMP_ABSOLUTE); +- continue; ++ DISPATCH(); + } + break; ++ } + +- case LOAD_ATTR: ++ TARGET(LOAD_ATTR) ++ { + w = GETITEM(names, oparg); + v = TOP(); + x = PyObject_GetAttr(v, w); + Py_DECREF(v); + SET_TOP(x); +- if (x != NULL) continue; ++ if (x != NULL) DISPATCH(); + break; ++ } + +- case COMPARE_OP: ++ TARGET(COMPARE_OP) ++ { + w = POP(); + v = TOP(); + if (PyInt_CheckExact(w) && PyInt_CheckExact(v)) { +@@ -2305,9 +2583,11 @@ PyEval_EvalFrameEx(PyFrameObject *f, int + if (x == NULL) break; + PREDICT(POP_JUMP_IF_FALSE); + PREDICT(POP_JUMP_IF_TRUE); +- continue; ++ DISPATCH(); ++ } + +- case IMPORT_NAME: ++ TARGET(IMPORT_NAME) ++ { + w = GETITEM(names, oparg); + x = PyDict_GetItemString(f->f_builtins, "__import__"); + if (x == NULL) { +@@ -2348,10 +2628,12 @@ PyEval_EvalFrameEx(PyFrameObject *f, int + READ_TIMESTAMP(intr1); + Py_DECREF(w); + SET_TOP(x); +- if (x != NULL) continue; ++ if (x != NULL) DISPATCH(); + break; ++ } + +- case IMPORT_STAR: ++ TARGET_NOARG(IMPORT_STAR) ++ { + v = POP(); + PyFrame_FastToLocals(f); + if ((x = f->f_locals) == NULL) { +@@ -2364,34 +2646,40 @@ PyEval_EvalFrameEx(PyFrameObject *f, int + READ_TIMESTAMP(intr1); + PyFrame_LocalsToFast(f, 0); + Py_DECREF(v); +- if (err == 0) continue; ++ if (err == 0) DISPATCH(); + break; ++ } + +- case IMPORT_FROM: ++ TARGET(IMPORT_FROM) ++ { + w = GETITEM(names, oparg); + v = TOP(); + READ_TIMESTAMP(intr0); + x = import_from(v, w); + READ_TIMESTAMP(intr1); + PUSH(x); +- if (x != NULL) continue; ++ if (x != NULL) DISPATCH(); + break; ++ } + +- case JUMP_FORWARD: ++ TARGET(JUMP_FORWARD) ++ { + JUMPBY(oparg); +- goto fast_next_opcode; ++ FAST_DISPATCH(); ++ } + + PREDICTED_WITH_ARG(POP_JUMP_IF_FALSE); +- case POP_JUMP_IF_FALSE: ++ TARGET(POP_JUMP_IF_FALSE) ++ { + w = POP(); + if (w == Py_True) { + Py_DECREF(w); +- goto fast_next_opcode; ++ FAST_DISPATCH(); + } + if (w == Py_False) { + Py_DECREF(w); + JUMPTO(oparg); +- goto fast_next_opcode; ++ FAST_DISPATCH(); + } + err = PyObject_IsTrue(w); + Py_DECREF(w); +@@ -2401,19 +2689,21 @@ PyEval_EvalFrameEx(PyFrameObject *f, int + JUMPTO(oparg); + else + break; +- continue; ++ DISPATCH(); ++ } + + PREDICTED_WITH_ARG(POP_JUMP_IF_TRUE); +- case POP_JUMP_IF_TRUE: ++ TARGET(POP_JUMP_IF_TRUE) ++ { + w = POP(); + if (w == Py_False) { + Py_DECREF(w); +- goto fast_next_opcode; ++ FAST_DISPATCH(); + } + if (w == Py_True) { + Py_DECREF(w); + JUMPTO(oparg); +- goto fast_next_opcode; ++ FAST_DISPATCH(); + } + err = PyObject_IsTrue(w); + Py_DECREF(w); +@@ -2425,18 +2715,20 @@ PyEval_EvalFrameEx(PyFrameObject *f, int + ; + else + break; +- continue; ++ DISPATCH(); ++ } + +- case JUMP_IF_FALSE_OR_POP: ++ TARGET(JUMP_IF_FALSE_OR_POP) ++ { + w = TOP(); + if (w == Py_True) { + STACKADJ(-1); + Py_DECREF(w); +- goto fast_next_opcode; ++ FAST_DISPATCH(); + } + if (w == Py_False) { + JUMPTO(oparg); +- goto fast_next_opcode; ++ FAST_DISPATCH(); + } + err = PyObject_IsTrue(w); + if (err > 0) { +@@ -2448,18 +2740,20 @@ PyEval_EvalFrameEx(PyFrameObject *f, int + JUMPTO(oparg); + else + break; +- continue; ++ DISPATCH(); ++ } + +- case JUMP_IF_TRUE_OR_POP: ++ TARGET(JUMP_IF_TRUE_OR_POP) ++ { + w = TOP(); + if (w == Py_False) { + STACKADJ(-1); + Py_DECREF(w); +- goto fast_next_opcode; ++ FAST_DISPATCH(); + } + if (w == Py_True) { + JUMPTO(oparg); +- goto fast_next_opcode; ++ FAST_DISPATCH(); + } + err = PyObject_IsTrue(w); + if (err > 0) { +@@ -2472,10 +2766,12 @@ PyEval_EvalFrameEx(PyFrameObject *f, int + } + else + break; +- continue; ++ DISPATCH(); ++ } + + PREDICTED_WITH_ARG(JUMP_ABSOLUTE); +- case JUMP_ABSOLUTE: ++ TARGET(JUMP_ABSOLUTE) ++ { + JUMPTO(oparg); + #if FAST_LOOPS + /* Enabling this path speeds-up all while and for-loops by bypassing +@@ -2487,10 +2783,12 @@ PyEval_EvalFrameEx(PyFrameObject *f, int + */ + goto fast_next_opcode; + #else +- continue; ++ DISPATCH(); + #endif ++ } + +- case GET_ITER: ++ TARGET_NOARG(GET_ITER) ++ { + /* before: [obj]; after [getiter(obj)] */ + v = TOP(); + x = PyObject_GetIter(v); +@@ -2498,13 +2796,15 @@ PyEval_EvalFrameEx(PyFrameObject *f, int + if (x != NULL) { + SET_TOP(x); + PREDICT(FOR_ITER); +- continue; ++ DISPATCH(); + } + STACKADJ(-1); + break; ++ } + + PREDICTED_WITH_ARG(FOR_ITER); +- case FOR_ITER: ++ TARGET(FOR_ITER) ++ { + /* before: [iter]; after: [iter, iter()] *or* [] */ + v = TOP(); + x = (*v->ob_type->tp_iternext)(v); +@@ -2512,7 +2812,7 @@ PyEval_EvalFrameEx(PyFrameObject *f, int + PUSH(x); + PREDICT(STORE_FAST); + PREDICT(UNPACK_SEQUENCE); +- continue; ++ DISPATCH(); + } + if (PyErr_Occurred()) { + if (!PyErr_ExceptionMatches( +@@ -2524,13 +2824,17 @@ PyEval_EvalFrameEx(PyFrameObject *f, int + x = v = POP(); + Py_DECREF(v); + JUMPBY(oparg); +- continue; ++ DISPATCH(); ++ } + +- case BREAK_LOOP: ++ TARGET_NOARG(BREAK_LOOP) ++ { + why = WHY_BREAK; + goto fast_block_end; ++ } + +- case CONTINUE_LOOP: ++ TARGET(CONTINUE_LOOP) ++ { + retval = PyInt_FromLong(oparg); + if (!retval) { + x = NULL; +@@ -2538,10 +2842,13 @@ PyEval_EvalFrameEx(PyFrameObject *f, int + } + why = WHY_CONTINUE; + goto fast_block_end; ++ } + +- case SETUP_LOOP: +- case SETUP_EXCEPT: +- case SETUP_FINALLY: ++ TARGET_WITH_IMPL(SETUP_LOOP, _setup_finally) ++ TARGET_WITH_IMPL(SETUP_EXCEPT, _setup_finally) ++ TARGET(SETUP_FINALLY) ++ _setup_finally: ++ { + /* NOTE: If you add any new block-setup opcodes that + are not try/except/finally handlers, you may need + to update the PyGen_NeedsFinalizing() function. +@@ -2549,9 +2856,13 @@ PyEval_EvalFrameEx(PyFrameObject *f, int + + PyFrame_BlockSetup(f, opcode, INSTR_OFFSET() + oparg, + STACK_LEVEL()); +- continue; ++ DISPATCH(); ++ } + +- case SETUP_WITH: ++ ++ ++ TARGET(SETUP_WITH) ++ { + { + static PyObject *exit, *enter; + w = TOP(); +@@ -2577,10 +2888,11 @@ PyEval_EvalFrameEx(PyFrameObject *f, int + STACK_LEVEL()); + + PUSH(x); +- continue; ++ DISPATCH(); ++ } + } + +- case WITH_CLEANUP: ++ TARGET_NOARG(WITH_CLEANUP) + { + /* At the top of the stack are 1-3 values indicating + how/why we entered the finally clause: +@@ -2668,7 +2980,7 @@ PyEval_EvalFrameEx(PyFrameObject *f, int + break; + } + +- case CALL_FUNCTION: ++ TARGET(CALL_FUNCTION) + { + PyObject **sp; + PCALL(PCALL_ALL); +@@ -2680,14 +2992,14 @@ PyEval_EvalFrameEx(PyFrameObject *f, int + #endif + stack_pointer = sp; + PUSH(x); +- if (x != NULL) +- continue; ++ if (x != NULL) DISPATCH(); + break; + } + +- case CALL_FUNCTION_VAR: +- case CALL_FUNCTION_KW: +- case CALL_FUNCTION_VAR_KW: ++ TARGET_WITH_IMPL(CALL_FUNCTION_VAR, _call_function_var_kw) ++ TARGET_WITH_IMPL(CALL_FUNCTION_KW, _call_function_var_kw) ++ TARGET(CALL_FUNCTION_VAR_KW) ++ _call_function_var_kw: + { + int na = oparg & 0xff; + int nk = (oparg>>8) & 0xff; +@@ -2725,12 +3037,13 @@ PyEval_EvalFrameEx(PyFrameObject *f, int + Py_DECREF(w); + } + PUSH(x); +- if (x != NULL) +- continue; ++ if (x != NULL) DISPATCH(); + break; + } + +- case MAKE_FUNCTION: ++ ++ TARGET(MAKE_FUNCTION) ++ { + v = POP(); /* code object */ + x = PyFunction_New(v, f->f_globals); + Py_DECREF(v); +@@ -2751,8 +3064,9 @@ PyEval_EvalFrameEx(PyFrameObject *f, int + } + PUSH(x); + break; ++ } + +- case MAKE_CLOSURE: ++ TARGET(MAKE_CLOSURE) + { + v = POP(); /* code object */ + x = PyFunction_New(v, f->f_globals); +@@ -2787,7 +3101,8 @@ PyEval_EvalFrameEx(PyFrameObject *f, int + break; + } + +- case BUILD_SLICE: ++ TARGET(BUILD_SLICE) ++ { + if (oparg == 3) + w = POP(); + else +@@ -2799,14 +3114,20 @@ PyEval_EvalFrameEx(PyFrameObject *f, int + Py_DECREF(v); + Py_XDECREF(w); + SET_TOP(x); +- if (x != NULL) continue; ++ if (x != NULL) DISPATCH(); + break; ++ } + +- case EXTENDED_ARG: ++ TARGET(EXTENDED_ARG) ++ { + opcode = NEXTOP(); + oparg = oparg<<16 | NEXTARG(); + goto dispatch_opcode; ++ } + ++#if USE_COMPUTED_GOTOS ++ _unknown_opcode: ++#endif + default: + fprintf(stderr, + "XXX lineno: %d, opcode: %d\n", +Index: Python-2.7.9/Python/makeopcodetargets.py +=================================================================== +--- /dev/null ++++ Python-2.7.9/Python/makeopcodetargets.py +@@ -0,0 +1,45 @@ ++#! /usr/bin/env python ++"""Generate C code for the jump table of the threaded code interpreter ++(for compilers supporting computed gotos or "labels-as-values", such as gcc). ++""" ++ ++# This code should stay compatible with Python 2.3, at least while ++# some of the buildbots have Python 2.3 as their system Python. ++ ++import imp ++import os ++ ++ ++def find_module(modname): ++ """Finds and returns a module in the local dist/checkout. ++ """ ++ modpath = os.path.join( ++ os.path.dirname(os.path.dirname(__file__)), "Lib") ++ return imp.load_module(modname, *imp.find_module(modname, [modpath])) ++ ++def write_contents(f): ++ """Write C code contents to the target file object. ++ """ ++ opcode = find_module("opcode") ++ targets = ['_unknown_opcode'] * 256 ++ for opname, op in opcode.opmap.items(): ++ if opname == "STOP_CODE": ++ continue ++ targets[op] = "TARGET_%s" % opname.replace("+0", " ").replace("+", "_") ++ f.write("static void *opcode_targets[256] = {\n") ++ f.write(",\n".join([" &&%s" % s for s in targets])) ++ f.write("\n};\n") ++ ++ ++if __name__ == "__main__": ++ import sys ++ assert len(sys.argv) < 3, "Too many arguments" ++ if len(sys.argv) == 2: ++ target = sys.argv[1] ++ else: ++ target = "Python/opcode_targets.h" ++ f = open(target, "w") ++ try: ++ write_contents(f) ++ finally: ++ f.close() +Index: Python-2.7.9/Python/opcode_targets.h +=================================================================== +--- /dev/null ++++ Python-2.7.9/Python/opcode_targets.h +@@ -0,0 +1,258 @@ ++static void *opcode_targets[256] = { ++ &&_unknown_opcode, ++ &&TARGET_POP_TOP, ++ &&TARGET_ROT_TWO, ++ &&TARGET_ROT_THREE, ++ &&TARGET_DUP_TOP, ++ &&TARGET_ROT_FOUR, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&TARGET_NOP, ++ &&TARGET_UNARY_POSITIVE, ++ &&TARGET_UNARY_NEGATIVE, ++ &&TARGET_UNARY_NOT, ++ &&TARGET_UNARY_CONVERT, ++ &&_unknown_opcode, ++ &&TARGET_UNARY_INVERT, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&TARGET_BINARY_POWER, ++ &&TARGET_BINARY_MULTIPLY, ++ &&TARGET_BINARY_DIVIDE, ++ &&TARGET_BINARY_MODULO, ++ &&TARGET_BINARY_ADD, ++ &&TARGET_BINARY_SUBTRACT, ++ &&TARGET_BINARY_SUBSCR, ++ &&TARGET_BINARY_FLOOR_DIVIDE, ++ &&TARGET_BINARY_TRUE_DIVIDE, ++ &&TARGET_INPLACE_FLOOR_DIVIDE, ++ &&TARGET_INPLACE_TRUE_DIVIDE, ++ &&TARGET_SLICE , ++ &&TARGET_SLICE_1, ++ &&TARGET_SLICE_2, ++ &&TARGET_SLICE_3, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&TARGET_STORE_SLICE , ++ &&TARGET_STORE_SLICE_1, ++ &&TARGET_STORE_SLICE_2, ++ &&TARGET_STORE_SLICE_3, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&TARGET_DELETE_SLICE , ++ &&TARGET_DELETE_SLICE_1, ++ &&TARGET_DELETE_SLICE_2, ++ &&TARGET_DELETE_SLICE_3, ++ &&TARGET_STORE_MAP, ++ &&TARGET_INPLACE_ADD, ++ &&TARGET_INPLACE_SUBTRACT, ++ &&TARGET_INPLACE_MULTIPLY, ++ &&TARGET_INPLACE_DIVIDE, ++ &&TARGET_INPLACE_MODULO, ++ &&TARGET_STORE_SUBSCR, ++ &&TARGET_DELETE_SUBSCR, ++ &&TARGET_BINARY_LSHIFT, ++ &&TARGET_BINARY_RSHIFT, ++ &&TARGET_BINARY_AND, ++ &&TARGET_BINARY_XOR, ++ &&TARGET_BINARY_OR, ++ &&TARGET_INPLACE_POWER, ++ &&TARGET_GET_ITER, ++ &&_unknown_opcode, ++ &&TARGET_PRINT_EXPR, ++ &&TARGET_PRINT_ITEM, ++ &&TARGET_PRINT_NEWLINE, ++ &&TARGET_PRINT_ITEM_TO, ++ &&TARGET_PRINT_NEWLINE_TO, ++ &&TARGET_INPLACE_LSHIFT, ++ &&TARGET_INPLACE_RSHIFT, ++ &&TARGET_INPLACE_AND, ++ &&TARGET_INPLACE_XOR, ++ &&TARGET_INPLACE_OR, ++ &&TARGET_BREAK_LOOP, ++ &&TARGET_WITH_CLEANUP, ++ &&TARGET_LOAD_LOCALS, ++ &&TARGET_RETURN_VALUE, ++ &&TARGET_IMPORT_STAR, ++ &&TARGET_EXEC_STMT, ++ &&TARGET_YIELD_VALUE, ++ &&TARGET_POP_BLOCK, ++ &&TARGET_END_FINALLY, ++ &&TARGET_BUILD_CLASS, ++ &&TARGET_STORE_NAME, ++ &&TARGET_DELETE_NAME, ++ &&TARGET_UNPACK_SEQUENCE, ++ &&TARGET_FOR_ITER, ++ &&TARGET_LIST_APPEND, ++ &&TARGET_STORE_ATTR, ++ &&TARGET_DELETE_ATTR, ++ &&TARGET_STORE_GLOBAL, ++ &&TARGET_DELETE_GLOBAL, ++ &&TARGET_DUP_TOPX, ++ &&TARGET_LOAD_CONST, ++ &&TARGET_LOAD_NAME, ++ &&TARGET_BUILD_TUPLE, ++ &&TARGET_BUILD_LIST, ++ &&TARGET_BUILD_SET, ++ &&TARGET_BUILD_MAP, ++ &&TARGET_LOAD_ATTR, ++ &&TARGET_COMPARE_OP, ++ &&TARGET_IMPORT_NAME, ++ &&TARGET_IMPORT_FROM, ++ &&TARGET_JUMP_FORWARD, ++ &&TARGET_JUMP_IF_FALSE_OR_POP, ++ &&TARGET_JUMP_IF_TRUE_OR_POP, ++ &&TARGET_JUMP_ABSOLUTE, ++ &&TARGET_POP_JUMP_IF_FALSE, ++ &&TARGET_POP_JUMP_IF_TRUE, ++ &&TARGET_LOAD_GLOBAL, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&TARGET_CONTINUE_LOOP, ++ &&TARGET_SETUP_LOOP, ++ &&TARGET_SETUP_EXCEPT, ++ &&TARGET_SETUP_FINALLY, ++ &&_unknown_opcode, ++ &&TARGET_LOAD_FAST, ++ &&TARGET_STORE_FAST, ++ &&TARGET_DELETE_FAST, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&TARGET_RAISE_VARARGS, ++ &&TARGET_CALL_FUNCTION, ++ &&TARGET_MAKE_FUNCTION, ++ &&TARGET_BUILD_SLICE, ++ &&TARGET_MAKE_CLOSURE, ++ &&TARGET_LOAD_CLOSURE, ++ &&TARGET_LOAD_DEREF, ++ &&TARGET_STORE_DEREF, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&TARGET_CALL_FUNCTION_VAR, ++ &&TARGET_CALL_FUNCTION_KW, ++ &&TARGET_CALL_FUNCTION_VAR_KW, ++ &&TARGET_SETUP_WITH, ++ &&_unknown_opcode, ++ &&TARGET_EXTENDED_ARG, ++ &&TARGET_SET_ADD, ++ &&TARGET_MAP_ADD, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode ++}; +Index: Python-2.7.9/configure +=================================================================== +--- Python-2.7.9.orig/configure ++++ Python-2.7.9/configure +@@ -809,6 +809,7 @@ with_libm + with_libc + enable_big_digits + enable_unicode ++with_computed_gotos + with_ensurepip + ' + ac_precious_vars='build_alias +@@ -1489,6 +1490,9 @@ Optional Packages: + --with-fpectl enable SIGFPE catching + --with-libm=STRING math library + --with-libc=STRING C library ++ --with(out)-computed-gotos ++ Use computed gotos in evaluation loop (enabled by ++ default on supported compilers) + --with(out)-ensurepip=[=OPTION] + "install" or "upgrade" using bundled pip, default is + "no" +@@ -14606,6 +14610,85 @@ for dir in $SRCDIRS; do + mkdir $dir + fi + done ++ ++# BEGIN_COMPUTED_GOTO ++# Check for --with-computed-gotos ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for --with-computed-gotos" >&5 ++$as_echo_n "checking for --with-computed-gotos... " >&6; } ++ ++# Check whether --with-computed-gotos was given. ++if test "${with_computed_gotos+set}" = set; then : ++ withval=$with_computed_gotos; ++if test "$withval" = yes ++then ++ ++$as_echo "#define USE_COMPUTED_GOTOS 1" >>confdefs.h ++ ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 ++$as_echo "yes" >&6; } ++fi ++if test "$withval" = no ++then ++ ++$as_echo "#define USE_COMPUTED_GOTOS 0" >>confdefs.h ++ ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++$as_echo "no" >&6; } ++fi ++ ++else ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no value specified" >&5 ++$as_echo "no value specified" >&6; } ++fi ++ ++ ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC supports computed gotos" >&5 ++$as_echo_n "checking whether $CC supports computed gotos... " >&6; } ++if ${ac_cv_computed_gotos+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ if test "$cross_compiling" = yes; then : ++ if test "${with_computed_gotos+set}" = set; then ++ ac_cv_computed_gotos="$with_computed_gotos -- configured --with(out)-computed-gotos" ++ else ++ ac_cv_computed_gotos=no ++ fi ++else ++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++ ++int main(int argc, char **argv) ++{ ++ static void *targets[1] = { &&LABEL1 }; ++ goto LABEL2; ++LABEL1: ++ return 0; ++LABEL2: ++ goto *targets[0]; ++ return 1; ++} ++ ++_ACEOF ++if ac_fn_c_try_run "$LINENO"; then : ++ ac_cv_computed_gotos=yes ++else ++ ac_cv_computed_gotos=no ++fi ++rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ ++ conftest.$ac_objext conftest.beam conftest.$ac_ext ++fi ++ ++fi ++ ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_computed_gotos" >&5 ++$as_echo "$ac_cv_computed_gotos" >&6; } ++case "$ac_cv_computed_gotos" in yes*) ++ ++$as_echo "#define HAVE_COMPUTED_GOTOS 1" >>confdefs.h ++ ++esac ++# END_COMPUTED_GOTO ++ + { $as_echo "$as_me:${as_lineno-$LINENO}: result: done" >&5 + $as_echo "done" >&6; } + +Index: Python-2.7.9/configure.ac +=================================================================== +--- Python-2.7.9.orig/configure.ac ++++ Python-2.7.9/configure.ac +@@ -4554,6 +4554,57 @@ for dir in $SRCDIRS; do + mkdir $dir + fi + done ++ ++# BEGIN_COMPUTED_GOTO ++# Check for --with-computed-gotos ++AC_MSG_CHECKING(for --with-computed-gotos) ++AC_ARG_WITH(computed-gotos, ++ AS_HELP_STRING([--with(out)-computed-gotos], ++ [Use computed gotos in evaluation loop (enabled by default on supported compilers)]), ++[ ++if test "$withval" = yes ++then ++ AC_DEFINE(USE_COMPUTED_GOTOS, 1, ++ [Define if you want to use computed gotos in ceval.c.]) ++ AC_MSG_RESULT(yes) ++fi ++if test "$withval" = no ++then ++ AC_DEFINE(USE_COMPUTED_GOTOS, 0, ++ [Define if you want to use computed gotos in ceval.c.]) ++ AC_MSG_RESULT(no) ++fi ++], ++[AC_MSG_RESULT(no value specified)]) ++ ++AC_MSG_CHECKING(whether $CC supports computed gotos) ++AC_CACHE_VAL(ac_cv_computed_gotos, ++AC_RUN_IFELSE([AC_LANG_SOURCE([[[ ++int main(int argc, char **argv) ++{ ++ static void *targets[1] = { &&LABEL1 }; ++ goto LABEL2; ++LABEL1: ++ return 0; ++LABEL2: ++ goto *targets[0]; ++ return 1; ++} ++]]])], ++[ac_cv_computed_gotos=yes], ++[ac_cv_computed_gotos=no], ++[if test "${with_computed_gotos+set}" = set; then ++ ac_cv_computed_gotos="$with_computed_gotos -- configured --with(out)-computed-gotos" ++ else ++ ac_cv_computed_gotos=no ++ fi])) ++AC_MSG_RESULT($ac_cv_computed_gotos) ++case "$ac_cv_computed_gotos" in yes*) ++ AC_DEFINE(HAVE_COMPUTED_GOTOS, 1, ++ [Define if the C compiler supports computed gotos.]) ++esac ++# END_COMPUTED_GOTO ++ + AC_MSG_RESULT(done) + + # ensurepip option +Index: Python-2.7.9/pyconfig.h.in +=================================================================== +--- Python-2.7.9.orig/pyconfig.h.in ++++ Python-2.7.9/pyconfig.h.in +@@ -118,6 +118,9 @@ + /* Define to 1 if you have the `clock' function. */ + #undef HAVE_CLOCK + ++/* Define if the C compiler supports computed gotos. */ ++#undef HAVE_COMPUTED_GOTOS ++ + /* Define to 1 if you have the `confstr' function. */ + #undef HAVE_CONFSTR + +@@ -1063,6 +1066,9 @@ + /* Define to 1 if your <sys/time.h> declares `struct tm'. */ + #undef TM_IN_SYS_TIME + ++/* Define if you want to use computed gotos in ceval.c. */ ++#undef USE_COMPUTED_GOTOS ++ + /* Enable extensions on AIX 3, Interix. */ + #ifndef _ALL_SOURCE + # undef _ALL_SOURCE
meta/recipes-devtools/python/python/5e8fa1b13516.patch new file +41 -0
41 lines not on this page · raw message
meta/recipes-devtools/python/python_2.7.9.bb +3 -1
@@ -26,13 +26,15 @@ SRC_URI += "\ file://parallel-makeinst-create-bindir.patch \ file://use_sysroot_ncurses_instead_of_host.patch \ file://avoid_parallel_make_races_on_pgen.patch \ + file://17d3bbde60d2.patch \ + file://5e8fa1b13516.patch \ " S = "${WORKDIR}/Python-${PV}" inherit autotools multilib_header python-dir pythonnative -CONFIGUREOPTS += " --with-system-ffi " +CONFIGUREOPTS += " --with-system-ffi --with-computed-gotos " # The 3 lines below are copied from the libffi recipe, ctypes ships its own copy of the libffi sources #Somehow gcc doesn't set __SOFTFP__ when passing -mfloatabi=softp :(
Quoted 3 lines · Richard Purdie
These performance patches result in about a 25% speed up of our parsing speed with bitbake. They're already applied in 1.7 upstream and backported from 3.X so worth applying for 2.7 too.
Sadly, this was too good to be true. I'd messed up the test environment and the 25% is Ubuntu's python verses the one from OE. Ubuntu's uses PGO whereas ours does not which is likely where the speed comes from. The patches in this series do give a small speedup, but its more like 0.5-1%. Shows that PGO is likely worth investigating further though.
Cheers,
Richard
Quoted 8 lines · Richard Purdie
Quoted 3 lines · Richard Purdie
These performance patches result in about a 25% speed up of our parsing speed with bitbake. They're already applied in 1.7 upstream and backported from 3.X so worth applying for 2.7 too.
Quoted 6 lines
Sadly, this was too good to be true. I'd messed up the test environment and the 25% is Ubuntu's python verses the one from OE. Ubuntu's uses PGO whereas ours does not which is likely where the speed comes from. The patches in this series do give a small speedup, but its more like 0.5-1%. Shows that PGO is likely worth investigating further though.
25% is too good to ignore. Have you opened a tracker for this ?
and python has needed workload for generating profile data pybench and pydes benchmarks are there in source tree.
we need to compile twice.
compile with -fprofile-generate
run make run_profile_task
compile with -fprofile-use -fprofile-correction
So it should be straight forwards to try it out, do you still have the environment ?
Quoted 11 lines
Cheers,
Richard
--
_______________________________________________
Openembedded-core mailing list
[email protected]
http://lists.openembedded.org/mailman/listinfo/openembedded-core