[OE-core] [PATCH] python: Add performance patches from upstream 2.7 branch

Richard Purdie richard.purdie at linuxfoundation.org
Wed Jun 17 13:10:48 UTC 2015


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 <richard.purdie at linuxfoundation.org>

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 <benjamin at python.org>
+# 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
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 <benjamin at python.org>
+# 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 :(





More information about the Openembedded-core mailing list