Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork 35.2k
gh-106581: Split CALL_PY_EXACT_ARGS into uops#107760
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Uh oh!
There was an error while loading. Please reload this page.
Changes from all commits
56133bb907ff952c6be6d6d78ff20d8e66cb75f30e61c2822f73ea9012910fc2fafa2c2717b07e4879081d549aff40fb1f4f6f8f86facc8d94630d4cf8e2c01e6287605af848File filter
Filter by extension
Conversations
Uh oh!
There was an error while loading. Please reload this page.
Jump to
Uh oh!
There was an error while loading. Please reload this page.
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Uh oh!
There was an error while loading. Please reload this page.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Uh oh!
There was an error while loading. Please reload this page.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -957,13 +957,13 @@ dummy_func( | ||
| { | ||
| PyGenObject *gen = (PyGenObject *)receiver; | ||
| _PyInterpreterFrame *gen_frame = (_PyInterpreterFrame *)gen->gi_iframe; | ||
| frame->return_offset = oparg; | ||
| STACK_SHRINK(1); | ||
| _PyFrame_StackPush(gen_frame, v); | ||
| gen->gi_frame_state = FRAME_EXECUTING; | ||
| gen->gi_exc_state.previous_item = tstate->exc_info; | ||
| tstate->exc_info = &gen->gi_exc_state; | ||
| SKIP_OVER(INLINE_CACHE_ENTRIES_SEND); | ||
| frame->return_offset = oparg; | ||
| DISPATCH_INLINED(gen_frame); | ||
| } | ||
| if (Py_IsNone(v) && PyIter_Check(receiver)) { | ||
| @@ -996,13 +996,13 @@ dummy_func( | ||
| DEOPT_IF(gen->gi_frame_state >= FRAME_EXECUTING, SEND); | ||
| STAT_INC(SEND, hit); | ||
| _PyInterpreterFrame *gen_frame = (_PyInterpreterFrame *)gen->gi_iframe; | ||
| frame->return_offset = oparg; | ||
| STACK_SHRINK(1); | ||
| _PyFrame_StackPush(gen_frame, v); | ||
| gen->gi_frame_state = FRAME_EXECUTING; | ||
| gen->gi_exc_state.previous_item = tstate->exc_info; | ||
| tstate->exc_info = &gen->gi_exc_state; | ||
| SKIP_OVER(INLINE_CACHE_ENTRIES_SEND); | ||
| frame->return_offset = oparg; | ||
| DISPATCH_INLINED(gen_frame); | ||
| } | ||
| @@ -2588,14 +2588,14 @@ dummy_func( | ||
| DEOPT_IF(gen->gi_frame_state >= FRAME_EXECUTING, FOR_ITER); | ||
| STAT_INC(FOR_ITER, hit); | ||
| _PyInterpreterFrame *gen_frame = (_PyInterpreterFrame *)gen->gi_iframe; | ||
| frame->return_offset = oparg; | ||
| _PyFrame_StackPush(gen_frame, Py_None); | ||
| gen->gi_frame_state = FRAME_EXECUTING; | ||
| gen->gi_exc_state.previous_item = tstate->exc_info; | ||
| tstate->exc_info = &gen->gi_exc_state; | ||
| SKIP_OVER(INLINE_CACHE_ENTRIES_FOR_ITER); | ||
| assert(next_instr[oparg].op.code == END_FOR || | ||
| next_instr[oparg].op.code == INSTRUMENTED_END_FOR); | ||
| frame->return_offset = oparg; | ||
| DISPATCH_INLINED(gen_frame); | ||
| } | ||
| @@ -2950,32 +2950,72 @@ dummy_func( | ||
| GO_TO_INSTRUCTION(CALL_PY_EXACT_ARGS); | ||
| } | ||
| inst(CALL_PY_EXACT_ARGS, (unused/1, func_version/2, callable, self_or_null, args[oparg] -- unused)) { | ||
| ASSERT_KWNAMES_IS_NULL(); | ||
| op(_CHECK_PEP_523, (--)) { | ||
| DEOPT_IF(tstate->interp->eval_frame, CALL); | ||
| int argcount = oparg; | ||
| if (self_or_null != NULL) { | ||
| args--; | ||
| argcount++; | ||
| } | ||
| } | ||
| op(_CHECK_FUNCTION_EXACT_ARGS, (func_version/2, callable, self_or_null, unused[oparg] -- callable, self_or_null, unused[oparg])) { | ||
| ASSERT_KWNAMES_IS_NULL(); | ||
| DEOPT_IF(!PyFunction_Check(callable), CALL); | ||
| PyFunctionObject *func = (PyFunctionObject *)callable; | ||
| DEOPT_IF(func->func_version != func_version, CALL); | ||
| PyCodeObject *code = (PyCodeObject *)func->func_code; | ||
| DEOPT_IF(code->co_argcount != argcount, CALL); | ||
| DEOPT_IF(code->co_argcount != oparg + (self_or_null != NULL), CALL); | ||
| } | ||
| op(_CHECK_STACK_SPACE, (callable, unused, unused[oparg] -- callable, unused, unused[oparg])) { | ||
| PyFunctionObject *func = (PyFunctionObject *)callable; | ||
| PyCodeObject *code = (PyCodeObject *)func->func_code; | ||
| DEOPT_IF(!_PyThreadState_HasStackSpace(tstate, code->co_framesize), CALL); | ||
| } | ||
| op(_INIT_CALL_PY_EXACT_ARGS, (callable, self_or_null, args[oparg] -- new_frame: _PyInterpreterFrame*)) { | ||
| int argcount = oparg; | ||
| if (self_or_null != NULL) { | ||
| args--; | ||
| argcount++; | ||
| } | ||
| STAT_INC(CALL, hit); | ||
gvanrossum marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| _PyInterpreterFrame *new_frame = _PyFrame_PushUnchecked(tstate, func, argcount); | ||
| PyFunctionObject *func = (PyFunctionObject *)callable; | ||
| new_frame = _PyFrame_PushUnchecked(tstate, func, argcount); | ||
| for (int i = 0; i < argcount; i++) { | ||
| new_frame->localsplus[i] = args[i]; | ||
| } | ||
| // Manipulate stack directly since we leave using DISPATCH_INLINED(). | ||
| STACK_SHRINK(oparg + 2); | ||
| SKIP_OVER(INLINE_CACHE_ENTRIES_CALL); | ||
| } | ||
| // The 'unused' output effect represents the return value | ||
| // (which will be pushed when the frame returns). | ||
| // It is needed so CALL_PY_EXACT_ARGS matches its family. | ||
| op(_PUSH_FRAME, (new_frame: _PyInterpreterFrame* -- unused)) { | ||
| ||
| // Write it out explicitly because it's subtly different. | ||
| // Eventually this should be the only occurrence of this code. | ||
| frame->return_offset = 0; | ||
| DISPATCH_INLINED(new_frame); | ||
| assert(tstate->interp->eval_frame == NULL); | ||
| _PyFrame_SetStackPointer(frame, stack_pointer); | ||
| new_frame->previous = frame; | ||
| CALL_STAT_INC(inlined_py_calls); | ||
| #if TIER_ONE | ||
| frame = cframe.current_frame = new_frame; | ||
| goto start_frame; | ||
| #endif | ||
| #if TIER_TWO | ||
| frame = tstate->cframe->current_frame = new_frame; | ||
| ERROR_IF(_Py_EnterRecursivePy(tstate), exit_unwind); | ||
| stack_pointer = _PyFrame_GetStackPointer(frame); | ||
| ip_offset = (_Py_CODEUNIT *)_PyFrame_GetCode(frame)->co_code_adaptive; | ||
| #endif | ||
| } | ||
| macro(CALL_PY_EXACT_ARGS) = | ||
| unused/1 + // Skip over the counter | ||
| _CHECK_PEP_523 + | ||
| _CHECK_FUNCTION_EXACT_ARGS + | ||
| _CHECK_STACK_SPACE + | ||
| _INIT_CALL_PY_EXACT_ARGS + | ||
| SAVE_IP + // Tier 2 only; special-cased oparg | ||
| SAVE_CURRENT_IP + // Sets frame->prev_instr | ||
| _PUSH_FRAME; | ||
| inst(CALL_PY_WITH_DEFAULTS, (unused/1, func_version/2, callable, self_or_null, args[oparg] -- unused)) { | ||
| ASSERT_KWNAMES_IS_NULL(); | ||
| DEOPT_IF(tstate->interp->eval_frame, CALL); | ||
| @@ -3736,6 +3776,16 @@ dummy_func( | ||
| frame->prev_instr = ip_offset + oparg; | ||
| } | ||
| op(SAVE_CURRENT_IP, (--)) { | ||
| #if TIER_ONE | ||
| frame->prev_instr = next_instr - 1; | ||
| #endif | ||
| #if TIER_TWO | ||
| // Relies on a preceding SAVE_IP | ||
| frame->prev_instr--; | ||
| #endif | ||
| } | ||
| op(EXIT_TRACE, (--)) { | ||
| frame->prev_instr--; // Back up to just before destination | ||
| _PyFrame_SetStackPointer(frame, stack_pointer); | ||
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.