@@ -4733,29 +4733,22 @@ dummy_func(
47334733 res = PyStackRef_FromPyObjectSteal (res_o );
47344734 }
47354735
4736- // The optimizer folds self_or_null into args by emitting with
4737- // oparg = original_oparg + 1. Total args is always 2 for METH_O,
4738- // so arguments = args + oparg - 2.
47394736 tier2 op (_CALL_METHOD_DESCRIPTOR_O_INLINE , (callable , args [oparg ], cfunc /4 -- res , c , s , a )) {
4740- assert (oparg >= 2 );
4741- _PyStackRef * arguments = args + oparg - 2 ;
4742- // CPython promises to check all non-vectorcall function calls.
4737+ assert (oparg == 2 );
47434738 EXIT_IF (_Py_ReachedRecursionLimit (tstate ));
4744- _PyStackRef self_stackref = arguments [0 ];
4745- _PyStackRef arg_stackref = arguments [1 ];
47464739 STAT_INC (CALL , hit );
4747- PyCFunction volatile cfunc_fn = ( PyCFunction ) cfunc ;
4748- PyObject * res_o = cfunc_fn (
4749- PyStackRef_AsPyObjectBorrow (self_stackref ),
4750- PyStackRef_AsPyObjectBorrow (arg_stackref ));
4740+ PyObject * res_o = _PyCFunction_TrampolineCall (
4741+ ( PyCFunction ) cfunc ,
4742+ PyStackRef_AsPyObjectBorrow (args [ 0 ] ),
4743+ PyStackRef_AsPyObjectBorrow (args [ 1 ] ));
47514744 _Py_LeaveRecursiveCallTstate (tstate );
47524745 assert ((res_o != NULL ) ^ (_PyErr_Occurred (tstate ) != NULL ));
47534746 if (res_o == NULL ) {
47544747 ERROR_NO_POP ();
47554748 }
47564749 c = callable ;
4757- s = arguments [0 ];
4758- a = arguments [1 ];
4750+ s = args [0 ];
4751+ a = args [1 ];
47594752 INPUTS_DEAD ();
47604753 res = PyStackRef_FromPyObjectSteal (res_o );
47614754 }
@@ -4800,7 +4793,7 @@ dummy_func(
48004793 PyObject * self = PyStackRef_AsPyObjectBorrow (arguments [0 ]);
48014794 assert (self != NULL );
48024795 STAT_INC (CALL , hit );
4803- PyCFunction cfunc = method -> d_method -> ml_meth ;
4796+ PyCFunctionFastWithKeywords cfunc = ( PyCFunctionFastWithKeywords ) method -> d_method -> ml_meth ;
48044797 PyObject * res_o = _PyCallMethodDescriptorFastWithKeywords_StackRefSteal (
48054798 callable ,
48064799 cfunc ,
@@ -4815,19 +4808,16 @@ dummy_func(
48154808 res = PyStackRef_FromPyObjectSteal (res_o );
48164809 }
48174810
4818- // The optimizer folds self_or_null into args (oparg = original + 1)
4819- // and encodes total_args in operand1 to avoid runtime null checks.
4820- tier2 op (_CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS_INLINE , (callable , args [oparg ], cfunc /4 , total_args /2 -- res )) {
4821- _PyStackRef * arguments = args + oparg - total_args ;
4822- PyObject * self = PyStackRef_AsPyObjectBorrow (arguments [0 ]);
4811+ tier2 op (_CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS_INLINE , (callable , args [oparg ], cfunc /4 -- res )) {
4812+ PyObject * self = PyStackRef_AsPyObjectBorrow (args [0 ]);
48234813 assert (self != NULL );
48244814 STAT_INC (CALL , hit );
48254815 PyObject * res_o = _PyCallMethodDescriptorFastWithKeywords_StackRefSteal (
48264816 callable ,
4827- (PyCFunction )cfunc ,
4817+ (PyCFunctionFastWithKeywords )cfunc ,
48284818 self ,
4829- arguments ,
4830- total_args
4819+ args ,
4820+ oparg
48314821 );
48324822 DEAD (args );
48334823 DEAD (callable );
@@ -4883,21 +4873,13 @@ dummy_func(
48834873 res = PyStackRef_FromPyObjectSteal (res_o );
48844874 }
48854875
4886- // The optimizer folds self_or_null into args by emitting with
4887- // oparg = original_oparg + 1, so args always includes self.
4888- // Self is always the last element: args[oparg - 1].
48894876 tier2 op (_CALL_METHOD_DESCRIPTOR_NOARGS_INLINE , (callable , args [oparg ], cfunc /4 -- res )) {
4890- assert (oparg > = 1 );
4891- _PyStackRef self_stackref = args [oparg - 1 ];
4877+ assert (oparg = = 1 );
4878+ _PyStackRef self_stackref = args [0 ];
48924879 PyObject * self = PyStackRef_AsPyObjectBorrow (self_stackref );
4893- // CPython promises to check all non-vectorcall function calls.
48944880 EXIT_IF (_Py_ReachedRecursionLimit (tstate ));
48954881 STAT_INC (CALL , hit );
4896- // Use volatile to prevent the JIT compiler from generating a
4897- // direct BL to the cfunc symbol; we need an indirect BLR since
4898- // the cfunc address may be out of range for relative branches.
4899- PyCFunction volatile cfunc_fn = (PyCFunction )cfunc ;
4900- PyObject * res_o = cfunc_fn (self , NULL );
4882+ PyObject * res_o = _PyCFunction_TrampolineCall ((PyCFunction )cfunc , self , NULL );
49014883 _Py_LeaveRecursiveCallTstate (tstate );
49024884 assert ((res_o != NULL ) ^ (_PyErr_Occurred (tstate ) != NULL ));
49034885 PyStackRef_CLOSE (self_stackref );
@@ -4944,7 +4926,7 @@ dummy_func(
49444926 PyObject * self = PyStackRef_AsPyObjectBorrow (arguments [0 ]);
49454927 assert (self != NULL );
49464928 STAT_INC (CALL , hit );
4947- PyCFunction cfunc = method -> d_method -> ml_meth ;
4929+ PyCFunctionFast cfunc = ( PyCFunctionFast ) method -> d_method -> ml_meth ;
49484930 PyObject * res_o = _PyCallMethodDescriptorFast_StackRefSteal (
49494931 callable ,
49504932 cfunc ,
@@ -4959,19 +4941,16 @@ dummy_func(
49594941 res = PyStackRef_FromPyObjectSteal (res_o );
49604942 }
49614943
4962- // The optimizer folds self_or_null into args (oparg = original + 1)
4963- // and encodes total_args in operand1 to avoid runtime null checks.
4964- tier2 op (_CALL_METHOD_DESCRIPTOR_FAST_INLINE , (callable , args [oparg ], cfunc /4 , total_args /2 -- res )) {
4965- _PyStackRef * arguments = args + oparg - total_args ;
4966- PyObject * self = PyStackRef_AsPyObjectBorrow (arguments [0 ]);
4944+ tier2 op (_CALL_METHOD_DESCRIPTOR_FAST_INLINE , (callable , args [oparg ], cfunc /4 -- res )) {
4945+ PyObject * self = PyStackRef_AsPyObjectBorrow (args [0 ]);
49674946 assert (self != NULL );
49684947 STAT_INC (CALL , hit );
49694948 PyObject * res_o = _PyCallMethodDescriptorFast_StackRefSteal (
49704949 callable ,
4971- (PyCFunction )cfunc ,
4950+ (PyCFunctionFast )cfunc ,
49724951 self ,
4973- arguments ,
4974- total_args
4952+ args ,
4953+ oparg
49754954 );
49764955 DEAD (args );
49774956 DEAD (callable );
0 commit comments