@@ -2140,21 +2140,21 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, InterpreterFrame *frame, int thr
2140
2140
}
2141
2141
2142
2142
TARGET (BINARY_SUBSCR_ADAPTIVE ) {
2143
- if (oparg == 0 ) {
2143
+ SpecializedCacheEntry * cache = GET_CACHE ();
2144
+ if (cache -> adaptive .counter == 0 ) {
2144
2145
PyObject * sub = TOP ();
2145
2146
PyObject * container = SECOND ();
2146
2147
next_instr -- ;
2147
- if (_Py_Specialize_BinarySubscr (container , sub , next_instr ) < 0 ) {
2148
+ if (_Py_Specialize_BinarySubscr (container , sub , next_instr , cache ) < 0 ) {
2148
2149
goto error ;
2149
2150
}
2150
2151
DISPATCH ();
2151
2152
}
2152
2153
else {
2153
2154
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 */
2158
2158
STAT_DEC (BINARY_SUBSCR , unquickened );
2159
2159
JUMP_TO_INSTRUCTION (BINARY_SUBSCR );
2160
2160
}
@@ -2223,6 +2223,37 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, InterpreterFrame *frame, int thr
2223
2223
DISPATCH ();
2224
2224
}
2225
2225
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
+
2226
2257
TARGET (LIST_APPEND ) {
2227
2258
PyObject * v = POP ();
2228
2259
PyObject * list = PEEK (oparg );
@@ -4878,29 +4909,13 @@ opname ## _miss: \
4878
4909
JUMP_TO_INSTRUCTION(opname); \
4879
4910
}
4880
4911
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
-
4897
4912
MISS_WITH_CACHE (LOAD_ATTR )
4898
4913
MISS_WITH_CACHE (STORE_ATTR )
4899
4914
MISS_WITH_CACHE (LOAD_GLOBAL )
4900
4915
MISS_WITH_CACHE (LOAD_METHOD )
4901
4916
MISS_WITH_CACHE (CALL_FUNCTION )
4902
4917
MISS_WITH_CACHE (BINARY_OP )
4903
- MISS_WITH_OPARG_COUNTER (BINARY_SUBSCR )
4918
+ MISS_WITH_CACHE (BINARY_SUBSCR )
4904
4919
4905
4920
binary_subscr_dict_error :
4906
4921
{
0 commit comments