@@ -4660,6 +4660,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, InterpreterFrame *frame, int thr
4660
4660
4661
4661
TARGET (CALL_FUNCTION ) {
4662
4662
PREDICTED (CALL_FUNCTION );
4663
+ STAT_INC (CALL_FUNCTION , unquickened );
4663
4664
PyObject * function ;
4664
4665
nargs = oparg ;
4665
4666
kwnames = NULL ;
@@ -4717,6 +4718,151 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, InterpreterFrame *frame, int thr
4717
4718
DISPATCH ();
4718
4719
}
4719
4720
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
+
4720
4866
TARGET (CALL_FUNCTION_EX ) {
4721
4867
PREDICTED (CALL_FUNCTION_EX );
4722
4868
PyObject * func , * callargs , * kwargs = NULL , * result ;
@@ -4985,6 +5131,7 @@ MISS_WITH_CACHE(LOAD_ATTR)
4985
5131
MISS_WITH_CACHE (STORE_ATTR )
4986
5132
MISS_WITH_CACHE (LOAD_GLOBAL )
4987
5133
MISS_WITH_CACHE (LOAD_METHOD )
5134
+ MISS_WITH_CACHE (CALL_FUNCTION )
4988
5135
MISS_WITH_OPARG_COUNTER (BINARY_SUBSCR )
4989
5136
MISS_WITH_OPARG_COUNTER (BINARY_ADD )
4990
5137
MISS_WITH_OPARG_COUNTER (BINARY_MULTIPLY )
0 commit comments