Skip to content

Commit ddf66b5

Browse files
authored
gh-106581: Split CALL_BOUND_METHOD_EXACT_ARGS into uops (#108462)
Instead of using `GO_TO_INSTRUCTION(CALL_PY_EXACT_ARGS)` we just add the macro elements of the latter to the macro for the former. This requires lengthening the uops array in struct opcode_macro_expansion. (It also required changes to stacking.py that were merged already.)
1 parent 546cab8 commit ddf66b5

File tree

6 files changed

+171
-35
lines changed

6 files changed

+171
-35
lines changed

Include/internal/pycore_opcode_metadata.h

+27-14
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Python/abstract_interp_cases.c.h

+10
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Python/bytecodes.c

+20-9
Original file line numberDiff line numberDiff line change
@@ -2940,19 +2940,18 @@ dummy_func(
29402940
CHECK_EVAL_BREAKER();
29412941
}
29422942

2943-
// Start out with [NULL, bound_method, arg1, arg2, ...]
2944-
// Transform to [callable, self, arg1, arg2, ...]
2945-
// Then fall through to CALL_PY_EXACT_ARGS
2946-
inst(CALL_BOUND_METHOD_EXACT_ARGS, (unused/1, unused/2, callable, null, unused[oparg] -- unused)) {
2943+
op(_CHECK_CALL_BOUND_METHOD_EXACT_ARGS, (callable, null, unused[oparg] -- callable, null, unused[oparg])) {
29472944
DEOPT_IF(null != NULL, CALL);
29482945
DEOPT_IF(Py_TYPE(callable) != &PyMethod_Type, CALL);
2946+
}
2947+
2948+
op(_INIT_CALL_BOUND_METHOD_EXACT_ARGS, (callable, unused, unused[oparg] -- func, self, unused[oparg])) {
29492949
STAT_INC(CALL, hit);
2950-
PyObject *self = ((PyMethodObject *)callable)->im_self;
2951-
PEEK(oparg + 1) = Py_NewRef(self); // self_or_null
2952-
PyObject *meth = ((PyMethodObject *)callable)->im_func;
2953-
PEEK(oparg + 2) = Py_NewRef(meth); // callable
2950+
self = Py_NewRef(((PyMethodObject *)callable)->im_self);
2951+
stack_pointer[-1 - oparg] = self; // Patch stack as it is used by _INIT_CALL_PY_EXACT_ARGS
2952+
func = Py_NewRef(((PyMethodObject *)callable)->im_func);
2953+
stack_pointer[-2 - oparg] = func; // This is used by CALL, upon deoptimization
29542954
Py_DECREF(callable);
2955-
GO_TO_INSTRUCTION(CALL_PY_EXACT_ARGS);
29562955
}
29572956

29582957
op(_CHECK_PEP_523, (--)) {
@@ -3010,6 +3009,18 @@ dummy_func(
30103009
#endif
30113010
}
30123011

3012+
macro(CALL_BOUND_METHOD_EXACT_ARGS) =
3013+
unused/1 + // Skip over the counter
3014+
_CHECK_PEP_523 +
3015+
_CHECK_CALL_BOUND_METHOD_EXACT_ARGS +
3016+
_INIT_CALL_BOUND_METHOD_EXACT_ARGS +
3017+
_CHECK_FUNCTION_EXACT_ARGS +
3018+
_CHECK_STACK_SPACE +
3019+
_INIT_CALL_PY_EXACT_ARGS +
3020+
SAVE_IP + // Tier 2 only; special-cased oparg
3021+
SAVE_CURRENT_IP + // Sets frame->prev_instr
3022+
_PUSH_FRAME;
3023+
30133024
macro(CALL_PY_EXACT_ARGS) =
30143025
unused/1 + // Skip over the counter
30153026
_CHECK_PEP_523 +

Python/executor_cases.c.h

+26
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Python/generated_cases.c.h

+87-11
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Tools/cases_generator/generate_cases.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -444,7 +444,7 @@ def write_metadata(self, metadata_filename: str, pymetadata_filename: str) -> No
444444
with self.out.block("struct opcode_macro_expansion", ";"):
445445
self.out.emit("int nuops;")
446446
self.out.emit(
447-
"struct { int16_t uop; int8_t size; int8_t offset; } uops[8];"
447+
"struct { int16_t uop; int8_t size; int8_t offset; } uops[12];"
448448
)
449449
self.out.emit("")
450450

0 commit comments

Comments
 (0)