From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from dan.rpsys.net (5751f4a1.skybroadband.com [87.81.244.161]) by mail.openembedded.org (Postfix) with ESMTP id 0738C65C63 for ; Wed, 17 Jun 2015 13:11:03 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by dan.rpsys.net (8.14.4/8.14.4/Debian-4.1ubuntu1) with ESMTP id t5HDB3n4014710 for ; Wed, 17 Jun 2015 14:11:03 +0100 Received: from dan.rpsys.net ([127.0.0.1]) by localhost (dan.rpsys.net [127.0.0.1]) (amavisd-new, port 10024) with LMTP id r86eOeCH7f5i for ; Wed, 17 Jun 2015 14:11:03 +0100 (BST) Received: from [192.168.3.10] ([192.168.3.10]) (authenticated bits=0) by dan.rpsys.net (8.14.4/8.14.4/Debian-4.1ubuntu1) with ESMTP id t5HDAmAT014694 (version=TLSv1/SSLv3 cipher=AES128-GCM-SHA256 bits=128 verify=NOT) for ; Wed, 17 Jun 2015 14:10:59 +0100 Message-ID: <1434546648.14710.25.camel@linuxfoundation.org> From: Richard Purdie To: openembedded-core Date: Wed, 17 Jun 2015 14:10:48 +0100 X-Mailer: Evolution 3.12.10-0ubuntu1~14.10.1 Mime-Version: 1.0 Subject: [PATCH] python: Add performance patches from upstream 2.7 branch X-BeenThere: openembedded-core@lists.openembedded.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: Patches and discussions about the oe-core layer List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 17 Jun 2015 13:11:06 -0000 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: 7bit 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. Signed-off-by: Richard Purdie diff --git a/meta/recipes-devtools/python/python/17d3bbde60d2.patch b/meta/recipes-devtools/python/python/17d3bbde60d2.patch new file mode 100644 index 0000000..9da8f2a --- /dev/null +++ b/meta/recipes-devtools/python/python/17d3bbde60d2.patch @@ -0,0 +1,2293 @@ + +# HG changeset patch +# User Benjamin Peterson +# 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 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 diff --git a/meta/recipes-devtools/python/python/5e8fa1b13516.patch b/meta/recipes-devtools/python/python/5e8fa1b13516.patch new file mode 100644 index 0000000..e27fd4c --- /dev/null +++ b/meta/recipes-devtools/python/python/5e8fa1b13516.patch @@ -0,0 +1,41 @@ + +# HG changeset patch +# User Benjamin Peterson +# Date 1433201071 18000 +# Node ID 5e8fa1b13516ae3c809e95264387b90aa2c2e89d +# Parent cf6e782a7f94bb12645b9c704afabbc55ad13803 +sync opcode prediction code with python 3 + +Upstream-Status: Backport +RP 2015/6/17 + +Index: Python-2.7.9/Python/ceval.c +=================================================================== +--- Python-2.7.9.orig/Python/ceval.c ++++ Python-2.7.9/Python/ceval.c +@@ -898,21 +898,15 @@ PyEval_EvalFrameEx(PyFrameObject *f, int + */ + + +-// Next opcode prediction is also enabled for Computed Gotos as well. +-#ifdef DYNAMIC_EXECUTION_PROFILE +-#define PREDICT(op) //if (0) goto PRED_##op +-#define PREDICTED(op) +-#define PREDICTED_WITH_ARG(op) ++#if defined(DYNAMIC_EXECUTION_PROFILE) || USE_COMPUTED_GOTOS ++#define PREDICT(op) if (0) goto PRED_##op ++#define PREDICTED(op) PRED_##op: ++#define PREDICTED_WITH_ARG(op) PRED_##op: + #else + #define PREDICT(op) if (*next_instr == op) goto PRED_##op + #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 */ diff --git a/meta/recipes-devtools/python/python_2.7.9.bb b/meta/recipes-devtools/python/python_2.7.9.bb index 7918550..4277a89 100644 --- a/meta/recipes-devtools/python/python_2.7.9.bb +++ b/meta/recipes-devtools/python/python_2.7.9.bb @@ -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 :(