Skip to content

Commit a269e69

Browse files
gh-139109: Dynamic opcode targets (GH-139111)
Make opcode targets table dynamic
1 parent 243d599 commit a269e69

File tree

5 files changed

+19
-17
lines changed

5 files changed

+19
-17
lines changed

Python/ceval.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1022,6 +1022,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int
10221022
#if USE_COMPUTED_GOTOS && !_Py_TAIL_CALL_INTERP
10231023
/* Import the static jump table */
10241024
#include "opcode_targets.h"
1025+
void **opcode_targets = opcode_targets_table;
10251026
#endif
10261027

10271028
#ifdef Py_STATS
@@ -1101,9 +1102,9 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int
11011102
stack_pointer = _PyFrame_GetStackPointer(frame);
11021103
#if _Py_TAIL_CALL_INTERP
11031104
# if Py_STATS
1104-
return _TAIL_CALL_error(frame, stack_pointer, tstate, next_instr, 0, lastopcode);
1105+
return _TAIL_CALL_error(frame, stack_pointer, tstate, next_instr, instruction_funcptr_table, 0, lastopcode);
11051106
# else
1106-
return _TAIL_CALL_error(frame, stack_pointer, tstate, next_instr, 0);
1107+
return _TAIL_CALL_error(frame, stack_pointer, tstate, next_instr, instruction_funcptr_table, 0);
11071108
# endif
11081109
#else
11091110
goto error;
@@ -1112,9 +1113,9 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int
11121113

11131114
#if _Py_TAIL_CALL_INTERP
11141115
# if Py_STATS
1115-
return _TAIL_CALL_start_frame(frame, NULL, tstate, NULL, 0, lastopcode);
1116+
return _TAIL_CALL_start_frame(frame, NULL, tstate, NULL, instruction_funcptr_table, 0, lastopcode);
11161117
# else
1117-
return _TAIL_CALL_start_frame(frame, NULL, tstate, NULL, 0);
1118+
return _TAIL_CALL_start_frame(frame, NULL, tstate, NULL, instruction_funcptr_table, 0);
11181119
# endif
11191120
#else
11201121
goto start_frame;

Python/ceval_macros.h

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -71,11 +71,11 @@
7171
#endif
7272

7373
#ifdef Py_STATS
74-
# define TAIL_CALL_PARAMS _PyInterpreterFrame *frame, _PyStackRef *stack_pointer, PyThreadState *tstate, _Py_CODEUNIT *next_instr, int oparg, int lastopcode
75-
# define TAIL_CALL_ARGS frame, stack_pointer, tstate, next_instr, oparg, lastopcode
74+
# define TAIL_CALL_PARAMS _PyInterpreterFrame *frame, _PyStackRef *stack_pointer, PyThreadState *tstate, _Py_CODEUNIT *next_instr, const void *instruction_funcptr_table, int oparg, int lastopcode
75+
# define TAIL_CALL_ARGS frame, stack_pointer, tstate, next_instr, instruction_funcptr_table, oparg, lastopcode
7676
#else
77-
# define TAIL_CALL_PARAMS _PyInterpreterFrame *frame, _PyStackRef *stack_pointer, PyThreadState *tstate, _Py_CODEUNIT *next_instr, int oparg
78-
# define TAIL_CALL_ARGS frame, stack_pointer, tstate, next_instr, oparg
77+
# define TAIL_CALL_PARAMS _PyInterpreterFrame *frame, _PyStackRef *stack_pointer, PyThreadState *tstate, _Py_CODEUNIT *next_instr, const void *instruction_funcptr_table, int oparg
78+
# define TAIL_CALL_ARGS frame, stack_pointer, tstate, next_instr, instruction_funcptr_table, oparg
7979
#endif
8080

8181
#if _Py_TAIL_CALL_INTERP
@@ -87,7 +87,7 @@
8787
# define TARGET(op) Py_PRESERVE_NONE_CC PyObject *_TAIL_CALL_##op(TAIL_CALL_PARAMS)
8888
# define DISPATCH_GOTO() \
8989
do { \
90-
Py_MUSTTAIL return (INSTRUCTION_TABLE[opcode])(TAIL_CALL_ARGS); \
90+
Py_MUSTTAIL return (((py_tail_call_funcptr *)instruction_funcptr_table)[opcode])(TAIL_CALL_ARGS); \
9191
} while (0)
9292
# define JUMP_TO_LABEL(name) \
9393
do { \
@@ -96,12 +96,12 @@
9696
# ifdef Py_STATS
9797
# define JUMP_TO_PREDICTED(name) \
9898
do { \
99-
Py_MUSTTAIL return (_TAIL_CALL_##name)(frame, stack_pointer, tstate, this_instr, oparg, lastopcode); \
99+
Py_MUSTTAIL return (_TAIL_CALL_##name)(frame, stack_pointer, tstate, this_instr, instruction_funcptr_table, oparg, lastopcode); \
100100
} while (0)
101101
# else
102102
# define JUMP_TO_PREDICTED(name) \
103103
do { \
104-
Py_MUSTTAIL return (_TAIL_CALL_##name)(frame, stack_pointer, tstate, this_instr, oparg); \
104+
Py_MUSTTAIL return (_TAIL_CALL_##name)(frame, stack_pointer, tstate, this_instr, instruction_funcptr_table, oparg); \
105105
} while (0)
106106
# endif
107107
# define LABEL(name) TARGET(name)

Python/opcode_targets.h

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Tools/c-analyzer/cpython/_parser.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ def format_tsv_lines(lines):
8080
'Python/generated_cases.c.h',
8181
'Python/executor_cases.c.h',
8282
'Python/optimizer_cases.c.h',
83+
'Python/opcode_targets.h',
8384
# XXX: Throws errors if PY_VERSION_HEX is not mocked out
8485
'Modules/clinic/_testclinic_depr.c.h',
8586

Tools/cases_generator/target_generator.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ def write_opcode_targets(analysis: Analysis, out: CWriter) -> None:
2727
if op < 256:
2828
targets[op] = f"&&TARGET_{name},\n"
2929
out.emit("#if !_Py_TAIL_CALL_INTERP\n")
30-
out.emit("static void *opcode_targets[256] = {\n")
30+
out.emit("static void *opcode_targets_table[256] = {\n")
3131
for target in targets:
3232
out.emit(target)
3333
out.emit("};\n")
@@ -38,7 +38,7 @@ def function_proto(name: str) -> str:
3838

3939

4040
def write_tailcall_dispatch_table(analysis: Analysis, out: CWriter) -> None:
41-
out.emit("static py_tail_call_funcptr INSTRUCTION_TABLE[256];\n")
41+
out.emit("static py_tail_call_funcptr instruction_funcptr_table[256];\n")
4242
out.emit("\n")
4343

4444
# Emit function prototypes for labels.
@@ -60,7 +60,7 @@ def write_tailcall_dispatch_table(analysis: Analysis, out: CWriter) -> None:
6060
out.emit("\n")
6161

6262
# Emit the dispatch table.
63-
out.emit("static py_tail_call_funcptr INSTRUCTION_TABLE[256] = {\n")
63+
out.emit("static py_tail_call_funcptr instruction_funcptr_table[256] = {\n")
6464
for name in sorted(analysis.instructions.keys()):
6565
out.emit(f"[{name}] = _TAIL_CALL_{name},\n")
6666
named_values = analysis.opmap.values()

0 commit comments

Comments
 (0)