@@ -2140,21 +2140,21 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, InterpreterFrame *frame, int thr
21402140 }
21412141
21422142 TARGET (BINARY_SUBSCR_ADAPTIVE ) {
2143- if (oparg == 0 ) {
2143+ SpecializedCacheEntry * cache = GET_CACHE ();
2144+ if (cache -> adaptive .counter == 0 ) {
21442145 PyObject * sub = TOP ();
21452146 PyObject * container = SECOND ();
21462147 next_instr -- ;
2147- if (_Py_Specialize_BinarySubscr (container , sub , next_instr ) < 0 ) {
2148+ if (_Py_Specialize_BinarySubscr (container , sub , next_instr , cache ) < 0 ) {
21482149 goto error ;
21492150 }
21502151 DISPATCH ();
21512152 }
21522153 else {
21532154 STAT_INC (BINARY_SUBSCR , deferred );
2154- // oparg is the adaptive cache counter
2155- UPDATE_PREV_INSTR_OPARG (next_instr , oparg - 1 );
2156- assert (_Py_OPCODE (next_instr [-1 ]) == BINARY_SUBSCR_ADAPTIVE );
2157- assert (_Py_OPARG (next_instr [-1 ]) == oparg - 1 );
2155+ cache -> adaptive .counter -- ;
2156+ assert (cache -> adaptive .original_oparg == 0 );
2157+ /* No need to set oparg here; it isn't used by BINARY_SUBSCR */
21582158 STAT_DEC (BINARY_SUBSCR , unquickened );
21592159 JUMP_TO_INSTRUCTION (BINARY_SUBSCR );
21602160 }
@@ -2223,6 +2223,37 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, InterpreterFrame *frame, int thr
22232223 DISPATCH ();
22242224 }
22252225
2226+ TARGET (BINARY_SUBSCR_GETITEM ) {
2227+ PyObject * sub = TOP ();
2228+ PyObject * container = SECOND ();
2229+ SpecializedCacheEntry * caches = GET_CACHE ();
2230+ _PyAdaptiveEntry * cache0 = & caches [0 ].adaptive ;
2231+ _PyObjectCache * cache1 = & caches [-1 ].obj ;
2232+ PyFunctionObject * getitem = (PyFunctionObject * )cache1 -> obj ;
2233+ DEOPT_IF (Py_TYPE (container )-> tp_version_tag != cache0 -> version , BINARY_SUBSCR );
2234+ DEOPT_IF (getitem -> func_version != cache0 -> index , BINARY_SUBSCR );
2235+ PyCodeObject * code = (PyCodeObject * )getitem -> func_code ;
2236+ size_t size = code -> co_nlocalsplus + code -> co_stacksize + FRAME_SPECIALS_SIZE ;
2237+ assert (code -> co_argcount == 2 );
2238+ InterpreterFrame * new_frame = _PyThreadState_BumpFramePointer (tstate , size );
2239+ if (new_frame == NULL ) {
2240+ goto error ;
2241+ }
2242+ _PyFrame_InitializeSpecials (new_frame , PyFunction_AS_FRAME_CONSTRUCTOR (getitem ),
2243+ NULL , code -> co_nlocalsplus );
2244+ STACK_SHRINK (2 );
2245+ new_frame -> localsplus [0 ] = container ;
2246+ new_frame -> localsplus [1 ] = sub ;
2247+ for (int i = 2 ; i < code -> co_nlocalsplus ; i ++ ) {
2248+ new_frame -> localsplus [i ] = NULL ;
2249+ }
2250+ _PyFrame_SetStackPointer (frame , stack_pointer );
2251+ new_frame -> previous = frame ;
2252+ frame = cframe .current_frame = new_frame ;
2253+ new_frame -> depth = frame -> depth + 1 ;
2254+ goto start_frame ;
2255+ }
2256+
22262257 TARGET (LIST_APPEND ) {
22272258 PyObject * v = POP ();
22282259 PyObject * list = PEEK (oparg );
@@ -4878,29 +4909,13 @@ opname ## _miss: \
48784909 JUMP_TO_INSTRUCTION(opname); \
48794910 }
48804911
4881- #define MISS_WITH_OPARG_COUNTER (opname ) \
4882- opname ## _miss: \
4883- { \
4884- STAT_INC(opname, miss); \
4885- uint8_t oparg = _Py_OPARG(next_instr[-1])-1; \
4886- UPDATE_PREV_INSTR_OPARG(next_instr, oparg); \
4887- assert(_Py_OPARG(next_instr[-1]) == oparg); \
4888- if (oparg == 0) /* too many cache misses */ { \
4889- oparg = ADAPTIVE_CACHE_BACKOFF ; \
4890- next_instr [-1 ] = _Py_MAKECODEUNIT (opname ## _ADAPTIVE , oparg ); \
4891- STAT_INC (opname , deopt ); \
4892- } \
4893- STAT_DEC (opname , unquickened ); \
4894- JUMP_TO_INSTRUCTION (opname ); \
4895- }
4896-
48974912MISS_WITH_CACHE (LOAD_ATTR )
48984913MISS_WITH_CACHE (STORE_ATTR )
48994914MISS_WITH_CACHE (LOAD_GLOBAL )
49004915MISS_WITH_CACHE (LOAD_METHOD )
49014916MISS_WITH_CACHE (CALL_FUNCTION )
49024917MISS_WITH_CACHE (BINARY_OP )
4903- MISS_WITH_OPARG_COUNTER (BINARY_SUBSCR )
4918+ MISS_WITH_CACHE (BINARY_SUBSCR )
49044919
49054920binary_subscr_dict_error :
49064921 {
0 commit comments