mirror of
https://github.com/python/cpython.git
synced 2025-11-24 20:30:18 +00:00
gh-139109: Dynamic opcode targets (GH-139111)
Make opcode targets table dynamic
This commit is contained in:
parent
243d599a05
commit
a269e691de
5 changed files with 19 additions and 17 deletions
|
|
@ -1022,6 +1022,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int
|
||||||
#if USE_COMPUTED_GOTOS && !_Py_TAIL_CALL_INTERP
|
#if USE_COMPUTED_GOTOS && !_Py_TAIL_CALL_INTERP
|
||||||
/* Import the static jump table */
|
/* Import the static jump table */
|
||||||
#include "opcode_targets.h"
|
#include "opcode_targets.h"
|
||||||
|
void **opcode_targets = opcode_targets_table;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef Py_STATS
|
#ifdef Py_STATS
|
||||||
|
|
@ -1101,9 +1102,9 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int
|
||||||
stack_pointer = _PyFrame_GetStackPointer(frame);
|
stack_pointer = _PyFrame_GetStackPointer(frame);
|
||||||
#if _Py_TAIL_CALL_INTERP
|
#if _Py_TAIL_CALL_INTERP
|
||||||
# if Py_STATS
|
# if Py_STATS
|
||||||
return _TAIL_CALL_error(frame, stack_pointer, tstate, next_instr, 0, lastopcode);
|
return _TAIL_CALL_error(frame, stack_pointer, tstate, next_instr, instruction_funcptr_table, 0, lastopcode);
|
||||||
# else
|
# else
|
||||||
return _TAIL_CALL_error(frame, stack_pointer, tstate, next_instr, 0);
|
return _TAIL_CALL_error(frame, stack_pointer, tstate, next_instr, instruction_funcptr_table, 0);
|
||||||
# endif
|
# endif
|
||||||
#else
|
#else
|
||||||
goto error;
|
goto error;
|
||||||
|
|
@ -1112,9 +1113,9 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int
|
||||||
|
|
||||||
#if _Py_TAIL_CALL_INTERP
|
#if _Py_TAIL_CALL_INTERP
|
||||||
# if Py_STATS
|
# if Py_STATS
|
||||||
return _TAIL_CALL_start_frame(frame, NULL, tstate, NULL, 0, lastopcode);
|
return _TAIL_CALL_start_frame(frame, NULL, tstate, NULL, instruction_funcptr_table, 0, lastopcode);
|
||||||
# else
|
# else
|
||||||
return _TAIL_CALL_start_frame(frame, NULL, tstate, NULL, 0);
|
return _TAIL_CALL_start_frame(frame, NULL, tstate, NULL, instruction_funcptr_table, 0);
|
||||||
# endif
|
# endif
|
||||||
#else
|
#else
|
||||||
goto start_frame;
|
goto start_frame;
|
||||||
|
|
|
||||||
|
|
@ -71,11 +71,11 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef Py_STATS
|
#ifdef Py_STATS
|
||||||
# define TAIL_CALL_PARAMS _PyInterpreterFrame *frame, _PyStackRef *stack_pointer, PyThreadState *tstate, _Py_CODEUNIT *next_instr, int oparg, int lastopcode
|
# define TAIL_CALL_PARAMS _PyInterpreterFrame *frame, _PyStackRef *stack_pointer, PyThreadState *tstate, _Py_CODEUNIT *next_instr, const void *instruction_funcptr_table, int oparg, int lastopcode
|
||||||
# define TAIL_CALL_ARGS frame, stack_pointer, tstate, next_instr, oparg, lastopcode
|
# define TAIL_CALL_ARGS frame, stack_pointer, tstate, next_instr, instruction_funcptr_table, oparg, lastopcode
|
||||||
#else
|
#else
|
||||||
# define TAIL_CALL_PARAMS _PyInterpreterFrame *frame, _PyStackRef *stack_pointer, PyThreadState *tstate, _Py_CODEUNIT *next_instr, int oparg
|
# define TAIL_CALL_PARAMS _PyInterpreterFrame *frame, _PyStackRef *stack_pointer, PyThreadState *tstate, _Py_CODEUNIT *next_instr, const void *instruction_funcptr_table, int oparg
|
||||||
# define TAIL_CALL_ARGS frame, stack_pointer, tstate, next_instr, oparg
|
# define TAIL_CALL_ARGS frame, stack_pointer, tstate, next_instr, instruction_funcptr_table, oparg
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if _Py_TAIL_CALL_INTERP
|
#if _Py_TAIL_CALL_INTERP
|
||||||
|
|
@ -87,7 +87,7 @@
|
||||||
# define TARGET(op) Py_PRESERVE_NONE_CC PyObject *_TAIL_CALL_##op(TAIL_CALL_PARAMS)
|
# define TARGET(op) Py_PRESERVE_NONE_CC PyObject *_TAIL_CALL_##op(TAIL_CALL_PARAMS)
|
||||||
# define DISPATCH_GOTO() \
|
# define DISPATCH_GOTO() \
|
||||||
do { \
|
do { \
|
||||||
Py_MUSTTAIL return (INSTRUCTION_TABLE[opcode])(TAIL_CALL_ARGS); \
|
Py_MUSTTAIL return (((py_tail_call_funcptr *)instruction_funcptr_table)[opcode])(TAIL_CALL_ARGS); \
|
||||||
} while (0)
|
} while (0)
|
||||||
# define JUMP_TO_LABEL(name) \
|
# define JUMP_TO_LABEL(name) \
|
||||||
do { \
|
do { \
|
||||||
|
|
@ -96,12 +96,12 @@
|
||||||
# ifdef Py_STATS
|
# ifdef Py_STATS
|
||||||
# define JUMP_TO_PREDICTED(name) \
|
# define JUMP_TO_PREDICTED(name) \
|
||||||
do { \
|
do { \
|
||||||
Py_MUSTTAIL return (_TAIL_CALL_##name)(frame, stack_pointer, tstate, this_instr, oparg, lastopcode); \
|
Py_MUSTTAIL return (_TAIL_CALL_##name)(frame, stack_pointer, tstate, this_instr, instruction_funcptr_table, oparg, lastopcode); \
|
||||||
} while (0)
|
} while (0)
|
||||||
# else
|
# else
|
||||||
# define JUMP_TO_PREDICTED(name) \
|
# define JUMP_TO_PREDICTED(name) \
|
||||||
do { \
|
do { \
|
||||||
Py_MUSTTAIL return (_TAIL_CALL_##name)(frame, stack_pointer, tstate, this_instr, oparg); \
|
Py_MUSTTAIL return (_TAIL_CALL_##name)(frame, stack_pointer, tstate, this_instr, instruction_funcptr_table, oparg); \
|
||||||
} while (0)
|
} while (0)
|
||||||
# endif
|
# endif
|
||||||
# define LABEL(name) TARGET(name)
|
# define LABEL(name) TARGET(name)
|
||||||
|
|
|
||||||
6
Python/opcode_targets.h
generated
6
Python/opcode_targets.h
generated
|
|
@ -1,5 +1,5 @@
|
||||||
#if !_Py_TAIL_CALL_INTERP
|
#if !_Py_TAIL_CALL_INTERP
|
||||||
static void *opcode_targets[256] = {
|
static void *opcode_targets_table[256] = {
|
||||||
&&TARGET_CACHE,
|
&&TARGET_CACHE,
|
||||||
&&TARGET_BINARY_SLICE,
|
&&TARGET_BINARY_SLICE,
|
||||||
&&TARGET_BUILD_TEMPLATE,
|
&&TARGET_BUILD_TEMPLATE,
|
||||||
|
|
@ -258,7 +258,7 @@ static void *opcode_targets[256] = {
|
||||||
&&TARGET_ENTER_EXECUTOR,
|
&&TARGET_ENTER_EXECUTOR,
|
||||||
};
|
};
|
||||||
#else /* _Py_TAIL_CALL_INTERP */
|
#else /* _Py_TAIL_CALL_INTERP */
|
||||||
static py_tail_call_funcptr INSTRUCTION_TABLE[256];
|
static py_tail_call_funcptr instruction_funcptr_table[256];
|
||||||
|
|
||||||
Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_pop_2_error(TAIL_CALL_PARAMS);
|
Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_pop_2_error(TAIL_CALL_PARAMS);
|
||||||
Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_pop_1_error(TAIL_CALL_PARAMS);
|
Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_pop_1_error(TAIL_CALL_PARAMS);
|
||||||
|
|
@ -503,7 +503,7 @@ Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_UNKNOWN_OPCODE(TAIL_CALL_PARAMS)
|
||||||
JUMP_TO_LABEL(error);
|
JUMP_TO_LABEL(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
static py_tail_call_funcptr INSTRUCTION_TABLE[256] = {
|
static py_tail_call_funcptr instruction_funcptr_table[256] = {
|
||||||
[BINARY_OP] = _TAIL_CALL_BINARY_OP,
|
[BINARY_OP] = _TAIL_CALL_BINARY_OP,
|
||||||
[BINARY_OP_ADD_FLOAT] = _TAIL_CALL_BINARY_OP_ADD_FLOAT,
|
[BINARY_OP_ADD_FLOAT] = _TAIL_CALL_BINARY_OP_ADD_FLOAT,
|
||||||
[BINARY_OP_ADD_INT] = _TAIL_CALL_BINARY_OP_ADD_INT,
|
[BINARY_OP_ADD_INT] = _TAIL_CALL_BINARY_OP_ADD_INT,
|
||||||
|
|
|
||||||
|
|
@ -80,6 +80,7 @@ EXCLUDED = format_conf_lines([
|
||||||
'Python/generated_cases.c.h',
|
'Python/generated_cases.c.h',
|
||||||
'Python/executor_cases.c.h',
|
'Python/executor_cases.c.h',
|
||||||
'Python/optimizer_cases.c.h',
|
'Python/optimizer_cases.c.h',
|
||||||
|
'Python/opcode_targets.h',
|
||||||
# XXX: Throws errors if PY_VERSION_HEX is not mocked out
|
# XXX: Throws errors if PY_VERSION_HEX is not mocked out
|
||||||
'Modules/clinic/_testclinic_depr.c.h',
|
'Modules/clinic/_testclinic_depr.c.h',
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@ def write_opcode_targets(analysis: Analysis, out: CWriter) -> None:
|
||||||
if op < 256:
|
if op < 256:
|
||||||
targets[op] = f"&&TARGET_{name},\n"
|
targets[op] = f"&&TARGET_{name},\n"
|
||||||
out.emit("#if !_Py_TAIL_CALL_INTERP\n")
|
out.emit("#if !_Py_TAIL_CALL_INTERP\n")
|
||||||
out.emit("static void *opcode_targets[256] = {\n")
|
out.emit("static void *opcode_targets_table[256] = {\n")
|
||||||
for target in targets:
|
for target in targets:
|
||||||
out.emit(target)
|
out.emit(target)
|
||||||
out.emit("};\n")
|
out.emit("};\n")
|
||||||
|
|
@ -38,7 +38,7 @@ def function_proto(name: str) -> str:
|
||||||
|
|
||||||
|
|
||||||
def write_tailcall_dispatch_table(analysis: Analysis, out: CWriter) -> None:
|
def write_tailcall_dispatch_table(analysis: Analysis, out: CWriter) -> None:
|
||||||
out.emit("static py_tail_call_funcptr INSTRUCTION_TABLE[256];\n")
|
out.emit("static py_tail_call_funcptr instruction_funcptr_table[256];\n")
|
||||||
out.emit("\n")
|
out.emit("\n")
|
||||||
|
|
||||||
# Emit function prototypes for labels.
|
# Emit function prototypes for labels.
|
||||||
|
|
@ -60,7 +60,7 @@ def write_tailcall_dispatch_table(analysis: Analysis, out: CWriter) -> None:
|
||||||
out.emit("\n")
|
out.emit("\n")
|
||||||
|
|
||||||
# Emit the dispatch table.
|
# Emit the dispatch table.
|
||||||
out.emit("static py_tail_call_funcptr INSTRUCTION_TABLE[256] = {\n")
|
out.emit("static py_tail_call_funcptr instruction_funcptr_table[256] = {\n")
|
||||||
for name in sorted(analysis.instructions.keys()):
|
for name in sorted(analysis.instructions.keys()):
|
||||||
out.emit(f"[{name}] = _TAIL_CALL_{name},\n")
|
out.emit(f"[{name}] = _TAIL_CALL_{name},\n")
|
||||||
named_values = analysis.opmap.values()
|
named_values = analysis.opmap.values()
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue