backport computed gotos (#4753)

This commit is contained in:
Benjamin Peterson 2015-05-28 12:45:31 -05:00
parent 78ba242403
commit 2c992a0788
9 changed files with 1021 additions and 229 deletions

View File

@ -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

View File

@ -300,6 +300,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 \
@ -671,6 +681,11 @@ Objects/bytearrayobject.o: $(srcdir)/Objects/bytearrayobject.c \
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)

View File

@ -10,6 +10,10 @@ What's New in Python 2.7.11?
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 #22939: Fixed integer overflow in iterator object. Original patch by
Clement Rouault.

File diff suppressed because it is too large Load Diff

45
Python/makeopcodetargets.py Executable file
View File

@ -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()

258
Python/opcode_targets.h Normal file
View File

@ -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
};

83
configure vendored
View File

@ -811,6 +811,7 @@ with_libm
with_libc
enable_big_digits
enable_unicode
with_computed_gotos
with_ensurepip
'
ac_precious_vars='build_alias
@ -1494,6 +1495,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"
@ -14685,6 +14689,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; }

View File

@ -4557,6 +4557,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

View File

@ -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
@ -1069,6 +1072,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