@@ -4660,6 +4660,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, InterpreterFrame *frame, int thr
46604660
46614661 TARGET (CALL_FUNCTION ) {
46624662 PREDICTED (CALL_FUNCTION );
4663+ STAT_INC (CALL_FUNCTION , unquickened );
46634664 PyObject * function ;
46644665 nargs = oparg ;
46654666 kwnames = NULL ;
@@ -4717,6 +4718,151 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, InterpreterFrame *frame, int thr
47174718 DISPATCH ();
47184719 }
47194720
4721+ TARGET (CALL_FUNCTION_ADAPTIVE ) {
4722+ SpecializedCacheEntry * cache = GET_CACHE ();
4723+ if (cache -> adaptive .counter == 0 ) {
4724+ next_instr -- ;
4725+ int nargs = cache -> adaptive .original_oparg ;
4726+ if (_Py_Specialize_CallFunction (
4727+ PEEK (nargs + 1 ), next_instr , nargs , cache , BUILTINS ()) < 0 ) {
4728+ goto error ;
4729+ }
4730+ DISPATCH ();
4731+ }
4732+ else {
4733+ STAT_INC (CALL_FUNCTION , deferred );
4734+ cache -> adaptive .counter -- ;
4735+ oparg = cache -> adaptive .original_oparg ;
4736+ JUMP_TO_INSTRUCTION (CALL_FUNCTION );
4737+ }
4738+ }
4739+
4740+ TARGET (CALL_FUNCTION_BUILTIN_O ) {
4741+ assert (cframe .use_tracing == 0 );
4742+ /* Builtin METH_O functions */
4743+
4744+ PyObject * callable = SECOND ();
4745+ DEOPT_IF (!PyCFunction_CheckExact (callable ), CALL_FUNCTION );
4746+ DEOPT_IF (PyCFunction_GET_FLAGS (callable ) != METH_O , CALL_FUNCTION );
4747+ _PyAdaptiveEntry * cache0 = & GET_CACHE ()[0 ].adaptive ;
4748+ record_cache_hit (cache0 );
4749+ STAT_INC (CALL_FUNCTION , hit );
4750+
4751+ PyCFunction cfunc = PyCFunction_GET_FUNCTION (callable );
4752+ PyObject * arg = POP ();
4753+ PyObject * res = cfunc (PyCFunction_GET_SELF (callable ), arg );
4754+ assert ((res != NULL ) ^ (_PyErr_Occurred (tstate ) != NULL ));
4755+
4756+ /* Clear the stack of the function object. */
4757+ Py_DECREF (arg );
4758+ Py_DECREF (callable );
4759+ SET_TOP (res );
4760+ if (res == NULL ) {
4761+ goto error ;
4762+ }
4763+ DISPATCH ();
4764+ }
4765+
4766+ TARGET (CALL_FUNCTION_BUILTIN_FAST ) {
4767+ assert (cframe .use_tracing == 0 );
4768+ /* Builtin METH_FASTCALL functions, without keywords */
4769+ SpecializedCacheEntry * caches = GET_CACHE ();
4770+ _PyAdaptiveEntry * cache0 = & caches [0 ].adaptive ;
4771+ int nargs = cache0 -> original_oparg ;
4772+ PyObject * * pfunc = & PEEK (nargs + 1 );
4773+ PyObject * callable = * pfunc ;
4774+ DEOPT_IF (!PyCFunction_CheckExact (callable ), CALL_FUNCTION );
4775+ DEOPT_IF (PyCFunction_GET_FLAGS (callable ) != METH_FASTCALL ,
4776+ CALL_FUNCTION );
4777+ record_cache_hit (cache0 );
4778+ STAT_INC (CALL_FUNCTION , hit );
4779+
4780+ PyCFunction cfunc = PyCFunction_GET_FUNCTION (callable );
4781+ /* res = func(self, args, nargs) */
4782+ PyObject * res = ((_PyCFunctionFast )(void (* )(void ))cfunc )(
4783+ PyCFunction_GET_SELF (callable ),
4784+ & PEEK (nargs ),
4785+ nargs );
4786+ assert ((res != NULL ) ^ (_PyErr_Occurred (tstate ) != NULL ));
4787+
4788+ /* Clear the stack of the function object. */
4789+ while (stack_pointer > pfunc ) {
4790+ PyObject * x = POP ();
4791+ Py_DECREF (x );
4792+ }
4793+ PUSH (res );
4794+ if (res == NULL ) {
4795+ /* Not deopting because this doesn't mean our optimization was
4796+ wrong. `res` can be NULL for valid reasons. Eg. getattr(x,
4797+ 'invalid'). In those cases an exception is set, so we must
4798+ handle it.
4799+ */
4800+ goto error ;
4801+ }
4802+ DISPATCH ();
4803+ }
4804+
4805+ TARGET (CALL_FUNCTION_LEN ) {
4806+ assert (cframe .use_tracing == 0 );
4807+ /* len(o) */
4808+ SpecializedCacheEntry * caches = GET_CACHE ();
4809+ _PyAdaptiveEntry * cache0 = & caches [0 ].adaptive ;
4810+ _PyObjectCache * cache1 = & caches [-1 ].obj ;
4811+ assert (cache0 -> original_oparg == 1 );
4812+
4813+ PyObject * callable = SECOND ();
4814+ DEOPT_IF (callable != cache1 -> obj , CALL_FUNCTION );
4815+ record_cache_hit (cache0 );
4816+ STAT_INC (CALL_FUNCTION , hit );
4817+
4818+ Py_ssize_t len_i = PyObject_Length (TOP ());
4819+ if (len_i < 0 ) {
4820+ goto error ;
4821+ }
4822+ PyObject * res = PyLong_FromSsize_t (len_i );
4823+ assert ((res != NULL ) ^ (_PyErr_Occurred (tstate ) != NULL ));
4824+
4825+ /* Clear the stack of the function object. */
4826+ Py_DECREF (POP ());
4827+ Py_DECREF (callable );
4828+ SET_TOP (res );
4829+ if (res == NULL ) {
4830+ goto error ;
4831+ }
4832+ DISPATCH ();
4833+ }
4834+
4835+ TARGET (CALL_FUNCTION_ISINSTANCE ) {
4836+ assert (cframe .use_tracing == 0 );
4837+ /* isinstance(o, o2) */
4838+ SpecializedCacheEntry * caches = GET_CACHE ();
4839+ _PyAdaptiveEntry * cache0 = & caches [0 ].adaptive ;
4840+ _PyObjectCache * cache1 = & caches [-1 ].obj ;
4841+ assert (cache0 -> original_oparg == 2 );
4842+
4843+ PyObject * callable = THIRD ();
4844+ DEOPT_IF (callable != cache1 -> obj , CALL_FUNCTION );
4845+ record_cache_hit (cache0 );
4846+ STAT_INC (CALL_FUNCTION , hit );
4847+
4848+ int retval = PyObject_IsInstance (SECOND (), TOP ());
4849+ if (retval < 0 ) {
4850+ goto error ;
4851+ }
4852+ PyObject * res = PyBool_FromLong (retval );
4853+ assert ((res != NULL ) ^ (_PyErr_Occurred (tstate ) != NULL ));
4854+
4855+ /* Clear the stack of the function object. */
4856+ Py_DECREF (POP ());
4857+ Py_DECREF (POP ());
4858+ Py_DECREF (callable );
4859+ SET_TOP (res );
4860+ if (res == NULL ) {
4861+ goto error ;
4862+ }
4863+ DISPATCH ();
4864+ }
4865+
47204866 TARGET (CALL_FUNCTION_EX ) {
47214867 PREDICTED (CALL_FUNCTION_EX );
47224868 PyObject * func , * callargs , * kwargs = NULL , * result ;
@@ -4985,6 +5131,7 @@ MISS_WITH_CACHE(LOAD_ATTR)
49855131MISS_WITH_CACHE (STORE_ATTR )
49865132MISS_WITH_CACHE (LOAD_GLOBAL )
49875133MISS_WITH_CACHE (LOAD_METHOD )
5134+ MISS_WITH_CACHE (CALL_FUNCTION )
49885135MISS_WITH_OPARG_COUNTER (BINARY_SUBSCR )
49895136MISS_WITH_OPARG_COUNTER (BINARY_ADD )
49905137MISS_WITH_OPARG_COUNTER (BINARY_MULTIPLY )
0 commit comments