Coverage Report

Created: 2026-02-26 06:53

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/cpython/Python/specialize.c
Line
Count
Source
1
#include "Python.h"
2
3
#include "opcode.h"
4
5
#include "pycore_code.h"
6
#include "pycore_critical_section.h"
7
#include "pycore_descrobject.h"   // _PyMethodWrapper_Type
8
#include "pycore_dict.h"          // DICT_KEYS_UNICODE
9
#include "pycore_function.h"      // _PyFunction_GetVersionForCurrentState()
10
#include "pycore_interpframe.h"   // FRAME_SPECIALS_SIZE
11
#include "pycore_lazyimportobject.h" // PyLazyImport_CheckExact
12
#include "pycore_list.h"          // _PyListIterObject
13
#include "pycore_long.h"          // _PyLong_IsNonNegativeCompact()
14
#include "pycore_moduleobject.h"
15
#include "pycore_object.h"
16
#include "pycore_opcode_metadata.h" // _PyOpcode_Caches
17
#include "pycore_uop_metadata.h"    // _PyOpcode_uop_name
18
#include "pycore_uop_ids.h"       // MAX_UOP_ID
19
#include "pycore_opcode_utils.h"  // RESUME_AT_FUNC_START
20
#include "pycore_pylifecycle.h"   // _PyOS_URandomNonblock()
21
#include "pycore_runtime.h"       // _Py_ID()
22
#include "pycore_unicodeobject.h" // _PyUnicodeASCIIIter_Type
23
24
#include <stdlib.h> // rand()
25
26
/* For guidance on adding or extending families of instructions see
27
 * InternalDocs/interpreter.md `Specialization` section.
28
 */
29
30
#if Py_STATS
31
#define SPECIALIZATION_FAIL(opcode, kind) \
32
do { \
33
    PyStats *s = _PyStats_GET(); \
34
    if (s) { \
35
        int _kind = (kind); \
36
        assert(_kind < SPECIALIZATION_FAILURE_KINDS); \
37
        s->opcode_stats[opcode].specialization.failure_kinds[_kind]++; \
38
    } \
39
} while (0)
40
#else
41
264k
#  define SPECIALIZATION_FAIL(opcode, kind) ((void)0)
42
#endif  // Py_STATS
43
44
// Initialize warmup counters and optimize instructions. This cannot fail.
45
void
46
_PyCode_Quicken(_Py_CODEUNIT *instructions, Py_ssize_t size, int enable_counters)
47
120k
{
48
120k
    #if ENABLE_SPECIALIZATION
49
120k
    _Py_BackoffCounter jump_counter, adaptive_counter;
50
120k
    if (enable_counters) {
51
120k
        PyThreadState *tstate = _PyThreadState_GET();
52
120k
        PyInterpreterState *interp = tstate->interp;
53
120k
        jump_counter = initial_jump_backoff_counter(&interp->opt_config);
54
120k
        adaptive_counter = adaptive_counter_warmup();
55
120k
    }
56
0
    else {
57
0
        jump_counter = initial_unreachable_backoff_counter();
58
0
        adaptive_counter = initial_unreachable_backoff_counter();
59
0
    }
60
120k
    int opcode = 0;
61
120k
    int oparg = 0;
62
    /* The last code unit cannot have a cache, so we don't need to check it */
63
5.33M
    for (Py_ssize_t i = 0; i < size-1; i++) {
64
5.21M
        opcode = instructions[i].op.code;
65
5.21M
        int caches = _PyOpcode_Caches[opcode];
66
5.21M
        oparg = (oparg << 8) | instructions[i].op.arg;
67
5.21M
        if (caches) {
68
            // The initial value depends on the opcode
69
1.53M
            switch (opcode) {
70
47.5k
                case JUMP_BACKWARD:
71
47.5k
                    instructions[i + 1].counter = jump_counter;
72
47.5k
                    break;
73
105k
                case POP_JUMP_IF_FALSE:
74
154k
                case POP_JUMP_IF_TRUE:
75
162k
                case POP_JUMP_IF_NONE:
76
172k
                case POP_JUMP_IF_NOT_NONE:
77
172k
                    instructions[i + 1].cache = 0x5555;  // Alternating 0, 1 bits
78
172k
                    break;
79
1.31M
                default:
80
1.31M
                    instructions[i + 1].counter = adaptive_counter;
81
1.31M
                    break;
82
1.53M
            }
83
1.53M
            i += caches;
84
1.53M
        }
85
5.21M
        if (opcode != EXTENDED_ARG) {
86
5.18M
            oparg = 0;
87
5.18M
        }
88
5.21M
    }
89
120k
    #endif /* ENABLE_SPECIALIZATION */
90
120k
}
91
92
453k
#define SIMPLE_FUNCTION 0
93
94
/* Common */
95
96
#define SPEC_FAIL_OTHER 0
97
#define SPEC_FAIL_NO_DICT 1
98
#define SPEC_FAIL_OVERRIDDEN 2
99
#define SPEC_FAIL_OUT_OF_VERSIONS 3
100
#define SPEC_FAIL_OUT_OF_RANGE 4
101
#define SPEC_FAIL_EXPECTED_ERROR 5
102
#define SPEC_FAIL_WRONG_NUMBER_ARGUMENTS 6
103
1.69k
#define SPEC_FAIL_CODE_COMPLEX_PARAMETERS 7
104
22.5k
#define SPEC_FAIL_CODE_NOT_OPTIMIZED 8
105
106
107
#define SPEC_FAIL_LOAD_GLOBAL_NON_DICT 17
108
#define SPEC_FAIL_LOAD_GLOBAL_NON_STRING_OR_SPLIT 18
109
110
/* Super */
111
112
#define SPEC_FAIL_SUPER_BAD_CLASS 9
113
#define SPEC_FAIL_SUPER_SHADOWED 10
114
115
/* Attributes */
116
117
#define SPEC_FAIL_ATTR_OVERRIDING_DESCRIPTOR 9
118
#define SPEC_FAIL_ATTR_NON_OVERRIDING_DESCRIPTOR 10
119
#define SPEC_FAIL_ATTR_NOT_DESCRIPTOR 11
120
#define SPEC_FAIL_ATTR_METHOD 12
121
#define SPEC_FAIL_ATTR_MUTABLE_CLASS 13
122
#define SPEC_FAIL_ATTR_PROPERTY 14
123
#define SPEC_FAIL_ATTR_NON_OBJECT_SLOT 15
124
#define SPEC_FAIL_ATTR_READ_ONLY 16
125
#define SPEC_FAIL_ATTR_AUDITED_SLOT 17
126
#define SPEC_FAIL_ATTR_NOT_MANAGED_DICT 18
127
#define SPEC_FAIL_ATTR_NON_STRING 19
128
#define SPEC_FAIL_ATTR_MODULE_ATTR_NOT_FOUND 20
129
#define SPEC_FAIL_ATTR_SHADOWED 21
130
#define SPEC_FAIL_ATTR_BUILTIN_CLASS_METHOD 22
131
#define SPEC_FAIL_ATTR_CLASS_METHOD_OBJ 23
132
#define SPEC_FAIL_ATTR_OBJECT_SLOT 24
133
#define SPEC_FAIL_ATTR_MODULE_LAZY_VALUE 25
134
135
#define SPEC_FAIL_ATTR_INSTANCE_ATTRIBUTE 26
136
#define SPEC_FAIL_ATTR_METACLASS_ATTRIBUTE 27
137
#define SPEC_FAIL_ATTR_PROPERTY_NOT_PY_FUNCTION 28
138
#define SPEC_FAIL_ATTR_NOT_IN_KEYS 29
139
#define SPEC_FAIL_ATTR_NOT_IN_DICT 30
140
#define SPEC_FAIL_ATTR_CLASS_ATTR_SIMPLE 31
141
#define SPEC_FAIL_ATTR_CLASS_ATTR_DESCRIPTOR 32
142
#define SPEC_FAIL_ATTR_BUILTIN_CLASS_METHOD_OBJ 33
143
#define SPEC_FAIL_ATTR_METACLASS_OVERRIDDEN 34
144
#define SPEC_FAIL_ATTR_SPLIT_DICT 35
145
#define SPEC_FAIL_ATTR_DESCR_NOT_DEFERRED 36
146
#define SPEC_FAIL_ATTR_SLOT_AFTER_ITEMS 37
147
148
/* Binary subscr and store subscr */
149
150
#define SPEC_FAIL_SUBSCR_ARRAY_INT 9
151
#define SPEC_FAIL_SUBSCR_ARRAY_SLICE 10
152
#define SPEC_FAIL_SUBSCR_LIST_SLICE 11
153
#define SPEC_FAIL_SUBSCR_BUFFER_INT 12
154
#define SPEC_FAIL_SUBSCR_BUFFER_SLICE 13
155
156
/* Store subscr */
157
#define SPEC_FAIL_SUBSCR_BYTEARRAY_INT 18
158
#define SPEC_FAIL_SUBSCR_BYTEARRAY_SLICE 19
159
#define SPEC_FAIL_SUBSCR_PY_SIMPLE 20
160
#define SPEC_FAIL_SUBSCR_PY_OTHER 21
161
#define SPEC_FAIL_SUBSCR_DICT_SUBCLASS_NO_OVERRIDE 22
162
#define SPEC_FAIL_SUBSCR_NOT_HEAP_TYPE 23
163
164
/* Binary op */
165
166
#define SPEC_FAIL_BINARY_OP_ADD_DIFFERENT_TYPES          9
167
#define SPEC_FAIL_BINARY_OP_ADD_OTHER                   10
168
#define SPEC_FAIL_BINARY_OP_AND_DIFFERENT_TYPES         11
169
#define SPEC_FAIL_BINARY_OP_AND_INT                     12
170
#define SPEC_FAIL_BINARY_OP_AND_OTHER                   13
171
#define SPEC_FAIL_BINARY_OP_FLOOR_DIVIDE                14
172
#define SPEC_FAIL_BINARY_OP_LSHIFT                      15
173
#define SPEC_FAIL_BINARY_OP_MATRIX_MULTIPLY             16
174
#define SPEC_FAIL_BINARY_OP_MULTIPLY_DIFFERENT_TYPES    17
175
#define SPEC_FAIL_BINARY_OP_MULTIPLY_OTHER              18
176
#define SPEC_FAIL_BINARY_OP_OR                          19
177
#define SPEC_FAIL_BINARY_OP_POWER                       20
178
#define SPEC_FAIL_BINARY_OP_REMAINDER                   21
179
#define SPEC_FAIL_BINARY_OP_RSHIFT                      22
180
#define SPEC_FAIL_BINARY_OP_SUBTRACT_DIFFERENT_TYPES    23
181
#define SPEC_FAIL_BINARY_OP_SUBTRACT_OTHER              24
182
#define SPEC_FAIL_BINARY_OP_TRUE_DIVIDE_DIFFERENT_TYPES 25
183
#define SPEC_FAIL_BINARY_OP_TRUE_DIVIDE_FLOAT           26
184
#define SPEC_FAIL_BINARY_OP_TRUE_DIVIDE_OTHER           27
185
#define SPEC_FAIL_BINARY_OP_XOR                         28
186
#define SPEC_FAIL_BINARY_OP_OR_INT                      29
187
#define SPEC_FAIL_BINARY_OP_OR_DIFFERENT_TYPES          30
188
#define SPEC_FAIL_BINARY_OP_XOR_INT                     31
189
#define SPEC_FAIL_BINARY_OP_XOR_DIFFERENT_TYPES         32
190
#define SPEC_FAIL_BINARY_OP_SUBSCR                      33
191
#define SPEC_FAIL_BINARY_OP_SUBSCR_LIST_SLICE           34
192
#define SPEC_FAIL_BINARY_OP_SUBSCR_TUPLE_SLICE          35
193
#define SPEC_FAIL_BINARY_OP_SUBSCR_STRING_SLICE         36
194
#define SPEC_FAIL_BINARY_OP_SUBSCR_NOT_HEAP_TYPE        37
195
#define SPEC_FAIL_BINARY_OP_SUBSCR_OTHER_SLICE          38
196
#define SPEC_FAIL_BINARY_OP_SUBSCR_MAPPINGPROXY         39
197
#define SPEC_FAIL_BINARY_OP_SUBSCR_RE_MATCH             40
198
#define SPEC_FAIL_BINARY_OP_SUBSCR_ARRAY                41
199
#define SPEC_FAIL_BINARY_OP_SUBSCR_DEQUE                42
200
#define SPEC_FAIL_BINARY_OP_SUBSCR_ENUMDICT             43
201
#define SPEC_FAIL_BINARY_OP_SUBSCR_STACKSUMMARY         44
202
#define SPEC_FAIL_BINARY_OP_SUBSCR_DEFAULTDICT          45
203
#define SPEC_FAIL_BINARY_OP_SUBSCR_COUNTER              46
204
#define SPEC_FAIL_BINARY_OP_SUBSCR_ORDEREDDICT          47
205
#define SPEC_FAIL_BINARY_OP_SUBSCR_BYTES                48
206
#define SPEC_FAIL_BINARY_OP_SUBSCR_STRUCTTIME           49
207
#define SPEC_FAIL_BINARY_OP_SUBSCR_RANGE                50
208
209
/* Calls */
210
211
#define SPEC_FAIL_CALL_INSTANCE_METHOD 11
212
#define SPEC_FAIL_CALL_CMETHOD 12
213
#define SPEC_FAIL_CALL_CFUNC_VARARGS 13
214
#define SPEC_FAIL_CALL_CFUNC_VARARGS_KEYWORDS 14
215
#define SPEC_FAIL_CALL_CFUNC_NOARGS 15
216
#define SPEC_FAIL_CALL_CFUNC_METHOD_FASTCALL_KEYWORDS 16
217
#define SPEC_FAIL_CALL_METH_DESCR_VARARGS 17
218
#define SPEC_FAIL_CALL_METH_DESCR_VARARGS_KEYWORDS 18
219
#define SPEC_FAIL_CALL_METH_DESCR_METHOD_FASTCALL_KEYWORDS 19
220
#define SPEC_FAIL_CALL_BAD_CALL_FLAGS 20
221
#define SPEC_FAIL_CALL_INIT_NOT_PYTHON 21
222
#define SPEC_FAIL_CALL_PEP_523 22
223
#define SPEC_FAIL_CALL_BOUND_METHOD 23
224
#define SPEC_FAIL_CALL_VECTORCALL 24
225
#define SPEC_FAIL_CALL_CLASS_MUTABLE 26
226
#define SPEC_FAIL_CALL_METHOD_WRAPPER 28
227
#define SPEC_FAIL_CALL_OPERATOR_WRAPPER 29
228
#define SPEC_FAIL_CALL_INIT_NOT_SIMPLE 30
229
#define SPEC_FAIL_CALL_METACLASS 31
230
#define SPEC_FAIL_CALL_INIT_NOT_INLINE_VALUES 32
231
232
/* COMPARE_OP */
233
#define SPEC_FAIL_COMPARE_OP_DIFFERENT_TYPES 12
234
#define SPEC_FAIL_COMPARE_OP_STRING 13
235
#define SPEC_FAIL_COMPARE_OP_BIG_INT 14
236
#define SPEC_FAIL_COMPARE_OP_BYTES 15
237
#define SPEC_FAIL_COMPARE_OP_TUPLE 16
238
#define SPEC_FAIL_COMPARE_OP_LIST 17
239
#define SPEC_FAIL_COMPARE_OP_SET 18
240
#define SPEC_FAIL_COMPARE_OP_BOOL 19
241
#define SPEC_FAIL_COMPARE_OP_BASEOBJECT 20
242
#define SPEC_FAIL_COMPARE_OP_FLOAT_LONG 21
243
#define SPEC_FAIL_COMPARE_OP_LONG_FLOAT 22
244
245
/* FOR_ITER and SEND */
246
#define SPEC_FAIL_ITER_GENERATOR 10
247
#define SPEC_FAIL_ITER_COROUTINE 11
248
#define SPEC_FAIL_ITER_ASYNC_GENERATOR 12
249
#define SPEC_FAIL_ITER_LIST 13
250
#define SPEC_FAIL_ITER_TUPLE 14
251
#define SPEC_FAIL_ITER_SET 15
252
#define SPEC_FAIL_ITER_STRING 16
253
#define SPEC_FAIL_ITER_BYTES 17
254
#define SPEC_FAIL_ITER_RANGE 18
255
#define SPEC_FAIL_ITER_ITERTOOLS 19
256
#define SPEC_FAIL_ITER_DICT_KEYS 20
257
#define SPEC_FAIL_ITER_DICT_ITEMS 21
258
#define SPEC_FAIL_ITER_DICT_VALUES 22
259
#define SPEC_FAIL_ITER_ENUMERATE 23
260
#define SPEC_FAIL_ITER_MAP 24
261
#define SPEC_FAIL_ITER_ZIP 25
262
#define SPEC_FAIL_ITER_SEQ_ITER 26
263
#define SPEC_FAIL_ITER_REVERSED_LIST 27
264
#define SPEC_FAIL_ITER_CALLABLE 28
265
#define SPEC_FAIL_ITER_ASCII_STRING 29
266
#define SPEC_FAIL_ITER_ASYNC_GENERATOR_SEND 30
267
#define SPEC_FAIL_ITER_SELF 31
268
269
// UNPACK_SEQUENCE
270
271
#define SPEC_FAIL_UNPACK_SEQUENCE_ITERATOR 9
272
#define SPEC_FAIL_UNPACK_SEQUENCE_SEQUENCE 10
273
274
// TO_BOOL
275
#define SPEC_FAIL_TO_BOOL_BYTEARRAY    9
276
#define SPEC_FAIL_TO_BOOL_BYTES       10
277
#define SPEC_FAIL_TO_BOOL_DICT        11
278
#define SPEC_FAIL_TO_BOOL_FLOAT       12
279
4.56k
#define SPEC_FAIL_TO_BOOL_MAPPING     13
280
#define SPEC_FAIL_TO_BOOL_MEMORY_VIEW 14
281
47
#define SPEC_FAIL_TO_BOOL_NUMBER      15
282
4.15k
#define SPEC_FAIL_TO_BOOL_SEQUENCE    16
283
#define SPEC_FAIL_TO_BOOL_SET         17
284
#define SPEC_FAIL_TO_BOOL_TUPLE       18
285
286
// CONTAINS_OP
287
#define SPEC_FAIL_CONTAINS_OP_STR        9
288
#define SPEC_FAIL_CONTAINS_OP_TUPLE      10
289
#define SPEC_FAIL_CONTAINS_OP_LIST       11
290
#define SPEC_FAIL_CONTAINS_OP_USER_CLASS 12
291
292
static inline int
293
set_opcode(_Py_CODEUNIT *instr, uint8_t opcode)
294
5.16M
{
295
#ifdef Py_GIL_DISABLED
296
    uint8_t old_op = _Py_atomic_load_uint8_relaxed(&instr->op.code);
297
    if (old_op >= MIN_INSTRUMENTED_OPCODE) {
298
        /* Lost race with instrumentation */
299
        return 0;
300
    }
301
    if (!_Py_atomic_compare_exchange_uint8(&instr->op.code, &old_op, opcode)) {
302
        /* Lost race with instrumentation */
303
        assert(old_op >= MIN_INSTRUMENTED_OPCODE);
304
        return 0;
305
    }
306
    return 1;
307
#else
308
5.16M
    instr->op.code = opcode;
309
5.16M
    return 1;
310
5.16M
#endif
311
5.16M
}
312
313
static inline void
314
set_counter(_Py_BackoffCounter *counter, _Py_BackoffCounter value)
315
6.47M
{
316
6.47M
    FT_ATOMIC_STORE_UINT16_RELAXED(counter->value_and_backoff,
317
6.47M
                                   value.value_and_backoff);
318
6.47M
}
319
320
static inline _Py_BackoffCounter
321
load_counter(_Py_BackoffCounter *counter)
322
264k
{
323
264k
    _Py_BackoffCounter result = {
324
264k
        .value_and_backoff =
325
264k
            FT_ATOMIC_LOAD_UINT16_RELAXED(counter->value_and_backoff)};
326
264k
    return result;
327
264k
}
328
329
static inline void
330
specialize(_Py_CODEUNIT *instr, uint8_t specialized_opcode)
331
4.90M
{
332
4.90M
    assert(!PyErr_Occurred());
333
4.90M
    if (!set_opcode(instr, specialized_opcode)) {
334
0
        STAT_INC(_PyOpcode_Deopt[specialized_opcode], failure);
335
0
        SPECIALIZATION_FAIL(_PyOpcode_Deopt[specialized_opcode],
336
0
                            SPEC_FAIL_OTHER);
337
0
        return;
338
0
    }
339
4.90M
    STAT_INC(_PyOpcode_Deopt[specialized_opcode], success);
340
4.90M
    set_counter((_Py_BackoffCounter *)instr + 1, adaptive_counter_cooldown());
341
4.90M
}
342
343
static inline void
344
unspecialize(_Py_CODEUNIT *instr)
345
264k
{
346
264k
    assert(!PyErr_Occurred());
347
264k
    uint8_t opcode = FT_ATOMIC_LOAD_UINT8_RELAXED(instr->op.code);
348
264k
    uint8_t generic_opcode = _PyOpcode_Deopt[opcode];
349
264k
    STAT_INC(generic_opcode, failure);
350
264k
    if (!set_opcode(instr, generic_opcode)) {
351
0
        SPECIALIZATION_FAIL(generic_opcode, SPEC_FAIL_OTHER);
352
0
        return;
353
0
    }
354
264k
    _Py_BackoffCounter *counter = (_Py_BackoffCounter *)instr + 1;
355
264k
    _Py_BackoffCounter cur = load_counter(counter);
356
264k
    set_counter(counter, adaptive_counter_backoff(cur));
357
264k
}
358
359
static int function_kind(PyCodeObject *code);
360
static bool function_check_args(PyObject *o, int expected_argcount, int opcode);
361
static uint32_t function_get_version(PyObject *o, int opcode);
362
363
#ifdef Py_GIL_DISABLED
364
static void
365
maybe_enable_deferred_ref_count(PyObject *op)
366
{
367
    if (!_Py_IsOwnedByCurrentThread(op) && _PyObject_GC_IS_TRACKED(op)) {
368
        // For module level variables that are heavily used from multiple
369
        // threads, deferred reference counting provides good scaling
370
        // benefits.  The downside is that the object will only be deallocated
371
        // by a GC run.
372
        PyUnstable_Object_EnableDeferredRefcount(op);
373
    }
374
}
375
#endif
376
377
378
static int
379
specialize_module_load_attr_lock_held(PyDictObject *dict, _Py_CODEUNIT *instr, PyObject *name)
380
5.40k
{
381
5.40k
    _PyAttrCache *cache = (_PyAttrCache *)(instr + 1);
382
5.40k
    if (dict->ma_keys->dk_kind != DICT_KEYS_UNICODE) {
383
0
        SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_ATTR_NON_STRING);
384
0
        return -1;
385
0
    }
386
5.40k
    PyObject *value;
387
5.40k
    Py_ssize_t index = _PyDict_LookupIndexAndValue(dict, name, &value);
388
5.40k
    if (value != NULL && PyLazyImport_CheckExact(value)) {
389
0
        SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_ATTR_MODULE_LAZY_VALUE);
390
0
        return -1;
391
0
    }
392
5.40k
    assert(index != DKIX_ERROR);
393
5.40k
    if (index != (uint16_t)index) {
394
285
        SPECIALIZATION_FAIL(LOAD_ATTR,
395
285
                            index == DKIX_EMPTY ?
396
285
                            SPEC_FAIL_ATTR_MODULE_ATTR_NOT_FOUND :
397
285
                            SPEC_FAIL_OUT_OF_RANGE);
398
285
        return -1;
399
285
    }
400
5.11k
    uint32_t keys_version = _PyDict_GetKeysVersionForCurrentState(
401
5.11k
            _PyInterpreterState_GET(), dict);
402
5.11k
    if (keys_version == 0) {
403
0
        SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_OUT_OF_VERSIONS);
404
0
        return -1;
405
0
    }
406
#ifdef Py_GIL_DISABLED
407
    maybe_enable_deferred_ref_count(value);
408
#endif
409
5.11k
    write_u32(cache->version, keys_version);
410
5.11k
    cache->index = (uint16_t)index;
411
5.11k
    specialize(instr, LOAD_ATTR_MODULE);
412
5.11k
    return 0;
413
5.11k
}
414
415
static int
416
specialize_module_load_attr(
417
    PyObject *owner, _Py_CODEUNIT *instr, PyObject *name)
418
5.40k
{
419
5.40k
    PyModuleObject *m = (PyModuleObject *)owner;
420
5.40k
    assert((Py_TYPE(owner)->tp_flags & Py_TPFLAGS_MANAGED_DICT) == 0);
421
5.40k
    PyDictObject *dict = (PyDictObject *)m->md_dict;
422
5.40k
    if (dict == NULL) {
423
0
        SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_NO_DICT);
424
0
        return -1;
425
0
    }
426
5.40k
    int result;
427
5.40k
    Py_BEGIN_CRITICAL_SECTION(dict);
428
5.40k
    result = specialize_module_load_attr_lock_held(dict, instr, name);
429
5.40k
    Py_END_CRITICAL_SECTION();
430
5.40k
    return result;
431
5.40k
}
432
433
/* Attribute specialization */
434
435
Py_NO_INLINE void
436
417
_Py_Specialize_LoadSuperAttr(_PyStackRef global_super_st, _PyStackRef cls_st, _Py_CODEUNIT *instr, int load_method) {
437
417
    PyObject *global_super = PyStackRef_AsPyObjectBorrow(global_super_st);
438
417
    PyObject *cls = PyStackRef_AsPyObjectBorrow(cls_st);
439
440
417
    assert(ENABLE_SPECIALIZATION);
441
417
    assert(_PyOpcode_Caches[LOAD_SUPER_ATTR] == INLINE_CACHE_ENTRIES_LOAD_SUPER_ATTR);
442
417
    if (global_super != (PyObject *)&PySuper_Type) {
443
0
        SPECIALIZATION_FAIL(LOAD_SUPER_ATTR, SPEC_FAIL_SUPER_SHADOWED);
444
0
        goto fail;
445
0
    }
446
417
    if (!PyType_Check(cls)) {
447
0
        SPECIALIZATION_FAIL(LOAD_SUPER_ATTR, SPEC_FAIL_SUPER_BAD_CLASS);
448
0
        goto fail;
449
0
    }
450
417
    uint8_t load_code = load_method ? LOAD_SUPER_ATTR_METHOD : LOAD_SUPER_ATTR_ATTR;
451
417
    specialize(instr, load_code);
452
417
    return;
453
0
fail:
454
0
    unspecialize(instr);
455
0
}
456
457
typedef enum {
458
    OVERRIDING, /* Is an overriding descriptor, and will remain so. */
459
    METHOD, /* Attribute has Py_TPFLAGS_METHOD_DESCRIPTOR set */
460
    PROPERTY, /* Is a property */
461
    OBJECT_SLOT, /* Is an object slot descriptor */
462
    OTHER_SLOT, /* Is a slot descriptor of another type */
463
    NON_OVERRIDING, /* Is another non-overriding descriptor, and is an instance of an immutable class*/
464
    BUILTIN_CLASSMETHOD, /* Builtin methods with METH_CLASS */
465
    PYTHON_CLASSMETHOD, /* Python classmethod(func) object */
466
    NON_DESCRIPTOR, /* Is not a descriptor, and is an instance of an immutable class */
467
    MUTABLE,   /* Instance of a mutable class; might, or might not, be a descriptor */
468
    ABSENT, /* Attribute is not present on the class */
469
    DUNDER_CLASS, /* __class__ attribute */
470
    GETSET_OVERRIDDEN, /* __getattribute__ or __setattr__ has been overridden */
471
    GETATTRIBUTE_IS_PYTHON_FUNCTION  /* Descriptor requires calling a Python __getattribute__ */
472
} DescriptorClassification;
473
474
475
static DescriptorClassification
476
classify_descriptor(PyObject *descriptor, bool has_getattr)
477
3.70M
{
478
3.70M
    if (descriptor == NULL) {
479
1.71M
        return ABSENT;
480
1.71M
    }
481
1.98M
    PyTypeObject *desc_cls = Py_TYPE(descriptor);
482
1.98M
    if (!(desc_cls->tp_flags & Py_TPFLAGS_IMMUTABLETYPE)) {
483
677
        return MUTABLE;
484
677
    }
485
1.98M
    if (desc_cls->tp_descr_set) {
486
227k
        if (desc_cls == &PyMemberDescr_Type) {
487
19.3k
            PyMemberDescrObject *member = (PyMemberDescrObject *)descriptor;
488
19.3k
            struct PyMemberDef *dmem = member->d_member;
489
19.3k
            if (dmem->type == Py_T_OBJECT_EX || dmem->type == _Py_T_OBJECT) {
490
19.1k
                return OBJECT_SLOT;
491
19.1k
            }
492
177
            return OTHER_SLOT;
493
19.3k
        }
494
208k
        if (desc_cls == &PyProperty_Type) {
495
            /* We can't detect at runtime whether an attribute exists
496
               with property. So that means we may have to call
497
               __getattr__. */
498
204k
            return has_getattr ? GETSET_OVERRIDDEN : PROPERTY;
499
204k
        }
500
3.80k
        return OVERRIDING;
501
208k
    }
502
1.75M
    if (desc_cls->tp_descr_get) {
503
455k
        if (desc_cls->tp_flags & Py_TPFLAGS_METHOD_DESCRIPTOR) {
504
431k
            return METHOD;
505
431k
        }
506
23.4k
        if (Py_IS_TYPE(descriptor, &PyClassMethodDescr_Type)) {
507
279
            return BUILTIN_CLASSMETHOD;
508
279
        }
509
23.2k
        if (Py_IS_TYPE(descriptor, &PyClassMethod_Type)) {
510
2.61k
            return PYTHON_CLASSMETHOD;
511
2.61k
        }
512
20.6k
        return NON_OVERRIDING;
513
23.2k
    }
514
1.30M
    return NON_DESCRIPTOR;
515
1.75M
}
516
517
static bool
518
descriptor_is_class(PyObject *descriptor, PyObject *name)
519
3.69M
{
520
3.69M
    return ((PyUnicode_CompareWithASCIIString(name, "__class__") == 0) &&
521
57.1k
            (descriptor == _PyType_Lookup(&PyBaseObject_Type, name)));
522
3.69M
}
523
524
static DescriptorClassification
525
3.49M
analyze_descriptor_load(PyTypeObject *type, PyObject *name, PyObject **descr, unsigned int *tp_version) {
526
3.49M
    bool has_getattr = false;
527
3.49M
    bool have_ga_version = false;
528
3.49M
    unsigned int ga_version;
529
3.49M
    getattrofunc getattro_slot = type->tp_getattro;
530
3.49M
    if (getattro_slot == PyObject_GenericGetAttr) {
531
        /* Normal attribute lookup; */
532
3.48M
        has_getattr = false;
533
3.48M
    }
534
518
    else if (getattro_slot == _Py_slot_tp_getattr_hook ||
535
286
        getattro_slot == _Py_slot_tp_getattro) {
536
        /* One or both of __getattribute__ or __getattr__ may have been
537
         overridden See typeobject.c for why these functions are special. */
538
232
        PyObject *getattribute = _PyType_LookupRefAndVersion(type,
539
232
                &_Py_ID(__getattribute__), &ga_version);
540
232
        have_ga_version = true;
541
232
        PyInterpreterState *interp = _PyInterpreterState_GET();
542
232
        bool has_custom_getattribute = getattribute != NULL &&
543
232
            getattribute != interp->callable_cache.object__getattribute__;
544
232
        PyObject *getattr = _PyType_Lookup(type, &_Py_ID(__getattr__));
545
232
        has_getattr = getattr != NULL;
546
232
        if (has_custom_getattribute) {
547
0
            if (!has_getattr &&
548
0
                Py_IS_TYPE(getattribute, &PyFunction_Type)) {
549
0
                *descr = getattribute;
550
0
                *tp_version = ga_version;
551
0
                return GETATTRIBUTE_IS_PYTHON_FUNCTION;
552
0
            }
553
            /* Potentially both __getattr__ and __getattribute__ are set.
554
               Too complicated */
555
0
            Py_DECREF(getattribute);
556
0
            *descr = NULL;
557
0
            *tp_version = ga_version;
558
0
            return GETSET_OVERRIDDEN;
559
0
        }
560
        /* Potentially has __getattr__ but no custom __getattribute__.
561
           Fall through to usual descriptor analysis.
562
           Usual attribute lookup should only be allowed at runtime
563
           if we can guarantee that there is no way an exception can be
564
           raised. This means some specializations, e.g. specializing
565
           for property() isn't safe.
566
        */
567
232
        Py_XDECREF(getattribute);
568
232
    }
569
286
    else {
570
286
        *descr = NULL;
571
286
        *tp_version = FT_ATOMIC_LOAD_UINT_RELAXED(type->tp_version_tag);
572
286
        return GETSET_OVERRIDDEN;
573
286
    }
574
3.49M
    unsigned int descr_version;
575
3.49M
    PyObject *descriptor = _PyType_LookupRefAndVersion(type, name, &descr_version);
576
3.49M
    *descr = descriptor;
577
3.49M
    *tp_version = have_ga_version ? ga_version : descr_version;
578
3.49M
    if (descriptor_is_class(descriptor, name)) {
579
57.1k
        return DUNDER_CLASS;
580
57.1k
    }
581
3.43M
    return classify_descriptor(descriptor, has_getattr);
582
3.49M
}
583
584
static DescriptorClassification
585
analyze_descriptor_store(PyTypeObject *type, PyObject *name, PyObject **descr, unsigned int *tp_version)
586
205k
{
587
205k
    if (type->tp_setattro != PyObject_GenericSetAttr) {
588
634
        *descr = NULL;
589
634
        return GETSET_OVERRIDDEN;
590
634
    }
591
204k
    PyObject *descriptor = _PyType_LookupRefAndVersion(type, name, tp_version);
592
204k
    *descr = descriptor;
593
204k
    if (descriptor_is_class(descriptor, name)) {
594
8
        return DUNDER_CLASS;
595
8
    }
596
204k
    return classify_descriptor(descriptor, false);
597
204k
}
598
599
static int
600
specialize_dict_access_inline(
601
    PyObject *owner, _Py_CODEUNIT *instr, PyTypeObject *type,
602
    PyObject *name, unsigned int tp_version,
603
    int base_op, int values_op)
604
767k
{
605
767k
    _PyAttrCache *cache = (_PyAttrCache *)(instr + 1);
606
767k
    PyDictKeysObject *keys = ((PyHeapTypeObject *)type)->ht_cached_keys;
607
767k
    assert(PyUnicode_CheckExact(name));
608
767k
    _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(owner);
609
767k
    Py_ssize_t index = _PyDictKeys_StringLookupSplit(keys, name);
610
767k
    assert (index != DKIX_ERROR);
611
767k
    if (index == DKIX_EMPTY) {
612
219
        SPECIALIZATION_FAIL(base_op, SPEC_FAIL_ATTR_NOT_IN_KEYS);
613
219
        return 0;
614
219
    }
615
767k
    assert(index >= 0);
616
767k
    assert(_PyObject_InlineValues(owner)->valid);
617
767k
    char *value_addr = (char *)&_PyObject_InlineValues(owner)->values[index];
618
767k
    Py_ssize_t offset = value_addr - (char *)owner;
619
767k
    if (offset != (uint16_t)offset) {
620
0
        SPECIALIZATION_FAIL(base_op, SPEC_FAIL_OUT_OF_RANGE);
621
0
        return 0;
622
0
    }
623
767k
    cache->index = (uint16_t)offset;
624
767k
    write_u32(cache->version, tp_version);
625
767k
    specialize(instr, values_op);
626
767k
    return 1;
627
767k
}
628
629
static int
630
specialize_dict_access_hint(
631
    PyDictObject *dict, _Py_CODEUNIT *instr, PyTypeObject *type,
632
    PyObject *name, unsigned int tp_version,
633
    int base_op, int hint_op)
634
14.7k
{
635
14.7k
    _PyAttrCache *cache = (_PyAttrCache *)(instr + 1);
636
637
14.7k
    _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(dict);
638
#ifdef Py_GIL_DISABLED
639
    _PyDict_EnsureSharedOnRead(dict);
640
#endif
641
642
    // We found an instance with a __dict__.
643
14.7k
    if (_PyDict_HasSplitTable(dict)) {
644
472
        SPECIALIZATION_FAIL(base_op, SPEC_FAIL_ATTR_SPLIT_DICT);
645
472
        return 0;
646
472
    }
647
14.2k
    Py_ssize_t index = _PyDict_LookupIndex(dict, name);
648
14.2k
    if (index != (uint16_t)index) {
649
3.37k
        SPECIALIZATION_FAIL(base_op,
650
3.37k
                            index == DKIX_EMPTY ?
651
3.37k
                            SPEC_FAIL_ATTR_NOT_IN_DICT :
652
3.37k
                            SPEC_FAIL_OUT_OF_RANGE);
653
3.37k
        return 0;
654
3.37k
    }
655
10.8k
    cache->index = (uint16_t)index;
656
10.8k
    write_u32(cache->version, tp_version);
657
10.8k
    specialize(instr, hint_op);
658
10.8k
    return 1;
659
14.2k
}
660
661
662
static int
663
specialize_dict_access(
664
    PyObject *owner, _Py_CODEUNIT *instr, PyTypeObject *type,
665
    DescriptorClassification kind, PyObject *name, unsigned int tp_version,
666
    int base_op, int values_op, int hint_op)
667
786k
{
668
786k
    assert(kind == NON_OVERRIDING || kind == NON_DESCRIPTOR || kind == ABSENT ||
669
786k
        kind == BUILTIN_CLASSMETHOD || kind == PYTHON_CLASSMETHOD ||
670
786k
        kind == METHOD);
671
    // No descriptor, or non overriding.
672
786k
    if ((type->tp_flags & Py_TPFLAGS_MANAGED_DICT) == 0) {
673
3.47k
        SPECIALIZATION_FAIL(base_op, SPEC_FAIL_ATTR_NOT_MANAGED_DICT);
674
3.47k
        return 0;
675
3.47k
    }
676
782k
    if (type->tp_flags & Py_TPFLAGS_INLINE_VALUES &&
677
781k
        FT_ATOMIC_LOAD_UINT8(_PyObject_InlineValues(owner)->valid) &&
678
767k
        !(base_op == STORE_ATTR && _PyObject_GetManagedDict(owner) != NULL))
679
767k
    {
680
767k
        int res;
681
767k
        Py_BEGIN_CRITICAL_SECTION(owner);
682
767k
        PyDictObject *dict = _PyObject_GetManagedDict(owner);
683
767k
        if (dict == NULL) {
684
            // managed dict, not materialized, inline values valid
685
767k
            res = specialize_dict_access_inline(owner, instr, type, name,
686
767k
                                                tp_version, base_op, values_op);
687
767k
        }
688
74
        else {
689
            // lost race and dict was created, fail specialization
690
74
            SPECIALIZATION_FAIL(STORE_ATTR, SPEC_FAIL_OTHER);
691
74
            res = 0;
692
74
        }
693
767k
        Py_END_CRITICAL_SECTION();
694
767k
        return res;
695
767k
    }
696
14.9k
    else {
697
14.9k
        PyDictObject *dict = _PyObject_GetManagedDict(owner);
698
14.9k
        if (dict == NULL || !PyDict_CheckExact(dict)) {
699
233
            SPECIALIZATION_FAIL(base_op, SPEC_FAIL_NO_DICT);
700
233
            return 0;
701
233
        }
702
14.7k
        int res;
703
14.7k
        Py_BEGIN_CRITICAL_SECTION(dict);
704
        // materialized managed dict
705
14.7k
        res = specialize_dict_access_hint(dict, instr, type, name,
706
14.7k
                                          tp_version, base_op, hint_op);
707
14.7k
        Py_END_CRITICAL_SECTION();
708
14.7k
        return res;
709
14.9k
    }
710
782k
}
711
712
static int
713
specialize_attr_loadclassattr(PyObject *owner, _Py_CODEUNIT *instr,
714
                              PyObject *name, PyObject *descr,
715
                              unsigned int tp_version,
716
                              DescriptorClassification kind, bool is_method,
717
                              uint32_t shared_keys_version);
718
static int specialize_class_load_attr(PyObject* owner, _Py_CODEUNIT* instr, PyObject* name);
719
720
/* Returns true if instances of obj's class are
721
 * likely to have `name` in their __dict__.
722
 * For objects with inline values, we check in the shared keys.
723
 * For other objects, we check their actual dictionary.
724
 */
725
static bool
726
instance_has_key(PyObject *obj, PyObject *name, uint32_t *shared_keys_version)
727
3.42M
{
728
3.42M
    PyTypeObject *cls = Py_TYPE(obj);
729
3.42M
    if ((cls->tp_flags & Py_TPFLAGS_MANAGED_DICT) == 0) {
730
1.02M
        return false;
731
1.02M
    }
732
2.40M
    if (cls->tp_flags & Py_TPFLAGS_INLINE_VALUES) {
733
2.30M
        PyDictKeysObject *keys = ((PyHeapTypeObject *)cls)->ht_cached_keys;
734
2.30M
        Py_ssize_t index =
735
2.30M
            _PyDictKeys_StringLookupAndVersion(keys, name, shared_keys_version);
736
2.30M
        return index >= 0;
737
2.30M
    }
738
95.8k
    PyDictObject *dict = _PyObject_GetManagedDict(obj);
739
95.8k
    if (dict == NULL || !PyDict_CheckExact(dict)) {
740
14
        return false;
741
14
    }
742
95.8k
    bool result;
743
95.8k
    Py_BEGIN_CRITICAL_SECTION(dict);
744
95.8k
    if (dict->ma_values) {
745
95.8k
        result = false;
746
95.8k
    }
747
0
    else {
748
0
        result = (_PyDict_LookupIndex(dict, name) >= 0);
749
0
    }
750
95.8k
    Py_END_CRITICAL_SECTION();
751
95.8k
    return result;
752
95.8k
}
753
754
static int
755
do_specialize_instance_load_attr(PyObject* owner, _Py_CODEUNIT* instr, PyObject* name,
756
                                 bool shadow, uint32_t shared_keys_version,
757
                                 DescriptorClassification kind, PyObject *descr, unsigned int tp_version)
758
3.42M
{
759
3.42M
    _PyAttrCache *cache = (_PyAttrCache *)(instr + 1);
760
3.42M
    PyTypeObject *type = Py_TYPE(owner);
761
3.42M
    if (tp_version == 0) {
762
3.60k
        SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_OUT_OF_VERSIONS);
763
3.60k
        return -1;
764
3.60k
    }
765
3.42M
    uint8_t oparg = FT_ATOMIC_LOAD_UINT8_RELAXED(instr->op.arg);
766
3.42M
    switch(kind) {
767
574
        case OVERRIDING:
768
574
            SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_ATTR_OVERRIDING_DESCRIPTOR);
769
574
            return -1;
770
409k
        case METHOD:
771
409k
        {
772
409k
            if (shadow) {
773
84
                goto try_instance;
774
84
            }
775
409k
            if (oparg & 1) {
776
371k
                if (specialize_attr_loadclassattr(owner, instr, name, descr,
777
371k
                                                  tp_version, kind, true,
778
371k
                                                  shared_keys_version)) {
779
367k
                    return 0;
780
367k
                }
781
4.75k
                else {
782
4.75k
                    return -1;
783
4.75k
                }
784
371k
            }
785
37.2k
            SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_ATTR_METHOD);
786
37.2k
            return -1;
787
409k
        }
788
204k
        case PROPERTY:
789
204k
        {
790
204k
            _PyLoadMethodCache *lm_cache = (_PyLoadMethodCache *)(instr + 1);
791
204k
            assert(Py_TYPE(descr) == &PyProperty_Type);
792
204k
            PyObject *fget = ((_PyPropertyObject *)descr)->prop_get;
793
204k
            if (fget == NULL) {
794
0
                SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_EXPECTED_ERROR);
795
0
                return -1;
796
0
            }
797
204k
            if (!Py_IS_TYPE(fget, &PyFunction_Type)) {
798
0
                SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_ATTR_PROPERTY_NOT_PY_FUNCTION);
799
0
                return -1;
800
0
            }
801
204k
            if (!function_check_args(fget, 1, LOAD_ATTR)) {
802
0
                return -1;
803
0
            }
804
204k
            if (oparg & 1) {
805
0
                SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_ATTR_METHOD);
806
0
                return -1;
807
0
            }
808
            /* Don't specialize if PEP 523 is active */
809
204k
            if (_PyInterpreterState_GET()->eval_frame) {
810
0
                SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_OTHER);
811
0
                return -1;
812
0
            }
813
            #ifdef Py_GIL_DISABLED
814
            if (!_PyObject_HasDeferredRefcount(fget)) {
815
                SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_ATTR_DESCR_NOT_DEFERRED);
816
                return -1;
817
            }
818
            #endif
819
204k
            assert(tp_version != 0);
820
204k
            write_u32(lm_cache->type_version, tp_version);
821
            /* borrowed */
822
204k
            write_ptr(lm_cache->descr, fget);
823
204k
            specialize(instr, LOAD_ATTR_PROPERTY);
824
204k
            return 0;
825
204k
        }
826
18.4k
        case OBJECT_SLOT:
827
18.4k
        {
828
18.4k
            PyMemberDescrObject *member = (PyMemberDescrObject *)descr;
829
18.4k
            struct PyMemberDef *dmem = member->d_member;
830
18.4k
            Py_ssize_t offset = dmem->offset;
831
18.4k
            if (!PyObject_TypeCheck(owner, member->d_common.d_type)) {
832
0
                SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_EXPECTED_ERROR);
833
0
                return -1;
834
0
            }
835
18.4k
            if (dmem->flags & _Py_AFTER_ITEMS) {
836
0
                SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_ATTR_SLOT_AFTER_ITEMS);
837
0
                return -1;
838
0
            }
839
18.4k
            if (dmem->flags & Py_AUDIT_READ) {
840
0
                SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_ATTR_AUDITED_SLOT);
841
0
                return -1;
842
0
            }
843
18.4k
            if (offset != (uint16_t)offset) {
844
0
                SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_OUT_OF_RANGE);
845
0
                return -1;
846
0
            }
847
18.4k
            assert(dmem->type == Py_T_OBJECT_EX || dmem->type == _Py_T_OBJECT);
848
18.4k
            assert(offset > 0);
849
18.4k
            cache->index = (uint16_t)offset;
850
18.4k
            write_u32(cache->version, tp_version);
851
18.4k
            specialize(instr, LOAD_ATTR_SLOT);
852
18.4k
            return 0;
853
18.4k
        }
854
57.1k
        case DUNDER_CLASS:
855
57.1k
        {
856
57.1k
            Py_ssize_t offset = offsetof(PyObject, ob_type);
857
57.1k
            assert(offset == (uint16_t)offset);
858
57.1k
            cache->index = (uint16_t)offset;
859
57.1k
            write_u32(cache->version, tp_version);
860
57.1k
            specialize(instr, LOAD_ATTR_SLOT);
861
57.1k
            return 0;
862
18.4k
        }
863
177
        case OTHER_SLOT:
864
177
            SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_ATTR_NON_OBJECT_SLOT);
865
177
            return -1;
866
278
        case MUTABLE:
867
278
            SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_ATTR_MUTABLE_CLASS);
868
278
            return -1;
869
34
        case GETSET_OVERRIDDEN:
870
34
            SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_OVERRIDDEN);
871
34
            return -1;
872
0
        case GETATTRIBUTE_IS_PYTHON_FUNCTION:
873
0
        {
874
0
            assert(Py_IS_TYPE(descr, &PyFunction_Type));
875
0
            _PyLoadMethodCache *lm_cache = (_PyLoadMethodCache *)(instr + 1);
876
0
            if (!function_check_args(descr, 2, LOAD_ATTR)) {
877
0
                return -1;
878
0
            }
879
0
            if (oparg & 1) {
880
0
                SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_ATTR_METHOD);
881
0
                return -1;
882
0
            }
883
0
            uint32_t version = function_get_version(descr, LOAD_ATTR);
884
0
            if (version == 0) {
885
0
                return -1;
886
0
            }
887
            /* Don't specialize if PEP 523 is active */
888
0
            if (_PyInterpreterState_GET()->eval_frame) {
889
0
                SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_OTHER);
890
0
                return -1;
891
0
            }
892
            #ifdef Py_GIL_DISABLED
893
            if (!_PyObject_HasDeferredRefcount(descr)) {
894
                SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_ATTR_DESCR_NOT_DEFERRED);
895
                return -1;
896
            }
897
            #endif
898
0
            write_u32(lm_cache->keys_version, version);
899
            /* borrowed */
900
0
            write_ptr(lm_cache->descr, descr);
901
0
            write_u32(lm_cache->type_version, tp_version);
902
0
            specialize(instr, LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN);
903
0
            return 0;
904
0
        }
905
0
        case BUILTIN_CLASSMETHOD:
906
248
        case PYTHON_CLASSMETHOD:
907
375
        case NON_OVERRIDING:
908
375
            if (shadow) {
909
0
                goto try_instance;
910
0
            }
911
375
            return -1;
912
1.25M
        case NON_DESCRIPTOR:
913
1.25M
            if (shadow) {
914
416k
                goto try_instance;
915
416k
            }
916
841k
            if ((oparg & 1) == 0) {
917
841k
                if (specialize_attr_loadclassattr(owner, instr, name, descr,
918
841k
                                                  tp_version, kind, false,
919
841k
                                                  shared_keys_version)) {
920
840k
                    return 0;
921
840k
                }
922
841k
            }
923
498
            return -1;
924
1.47M
        case ABSENT:
925
1.47M
            if (shadow) {
926
170k
                goto try_instance;
927
170k
            }
928
1.30M
            set_counter((_Py_BackoffCounter*)instr + 1, adaptive_counter_cooldown());
929
1.30M
            return 0;
930
3.42M
    }
931
3.42M
    Py_UNREACHABLE();
932
586k
try_instance:
933
586k
    if (specialize_dict_access(owner, instr, type, kind, name, tp_version,
934
586k
                               LOAD_ATTR, LOAD_ATTR_INSTANCE_VALUE, LOAD_ATTR_WITH_HINT))
935
583k
    {
936
583k
        return 0;
937
583k
    }
938
3.19k
    return -1;
939
586k
}
940
941
static int
942
specialize_instance_load_attr(PyObject* owner, _Py_CODEUNIT* instr, PyObject* name)
943
3.42M
{
944
    // 0 is not a valid version
945
3.42M
    uint32_t shared_keys_version = 0;
946
3.42M
    bool shadow = instance_has_key(owner, name, &shared_keys_version);
947
3.42M
    PyObject *descr = NULL;
948
3.42M
    unsigned int tp_version = 0;
949
3.42M
    PyTypeObject *type = Py_TYPE(owner);
950
3.42M
    DescriptorClassification kind = analyze_descriptor_load(type, name, &descr, &tp_version);
951
3.42M
    int result = do_specialize_instance_load_attr(owner, instr, name, shadow, shared_keys_version, kind, descr, tp_version);
952
3.42M
    Py_XDECREF(descr);
953
3.42M
    return result;
954
3.42M
}
955
956
Py_NO_INLINE void
957
_Py_Specialize_LoadAttr(_PyStackRef owner_st, _Py_CODEUNIT *instr, PyObject *name)
958
3.49M
{
959
3.49M
    PyObject *owner = PyStackRef_AsPyObjectBorrow(owner_st);
960
961
3.49M
    assert(ENABLE_SPECIALIZATION);
962
3.49M
    assert(_PyOpcode_Caches[LOAD_ATTR] == INLINE_CACHE_ENTRIES_LOAD_ATTR);
963
3.49M
    PyTypeObject *type = Py_TYPE(owner);
964
3.49M
    bool fail;
965
3.49M
    if (!_PyType_IsReady(type)) {
966
        // We *might* not really need this check, but we inherited it from
967
        // PyObject_GenericGetAttr and friends... and this way we still do the
968
        // right thing if someone forgets to call PyType_Ready(type):
969
0
        SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_OTHER);
970
0
        fail = true;
971
0
    }
972
3.49M
    else if (Py_TYPE(owner)->tp_getattro == PyModule_Type.tp_getattro) {
973
5.40k
        fail = specialize_module_load_attr(owner, instr, name);
974
5.40k
    }
975
3.49M
    else if (PyType_Check(owner)) {
976
68.7k
        fail = specialize_class_load_attr(owner, instr, name);
977
68.7k
    }
978
3.42M
    else {
979
3.42M
        fail = specialize_instance_load_attr(owner, instr, name);
980
3.42M
    }
981
982
3.49M
    if (fail) {
983
57.7k
        unspecialize(instr);
984
57.7k
    }
985
3.49M
}
986
987
Py_NO_INLINE void
988
_Py_Specialize_StoreAttr(_PyStackRef owner_st, _Py_CODEUNIT *instr, PyObject *name)
989
205k
{
990
205k
    PyObject *owner = PyStackRef_AsPyObjectBorrow(owner_st);
991
992
205k
    assert(ENABLE_SPECIALIZATION);
993
205k
    assert(_PyOpcode_Caches[STORE_ATTR] == INLINE_CACHE_ENTRIES_STORE_ATTR);
994
205k
    PyObject *descr = NULL;
995
205k
    _PyAttrCache *cache = (_PyAttrCache *)(instr + 1);
996
205k
    PyTypeObject *type = Py_TYPE(owner);
997
205k
    if (!_PyType_IsReady(type)) {
998
        // We *might* not really need this check, but we inherited it from
999
        // PyObject_GenericSetAttr and friends... and this way we still do the
1000
        // right thing if someone forgets to call PyType_Ready(type):
1001
0
        SPECIALIZATION_FAIL(STORE_ATTR, SPEC_FAIL_OTHER);
1002
0
        goto fail;
1003
0
    }
1004
205k
    if (PyModule_CheckExact(owner)) {
1005
473
        SPECIALIZATION_FAIL(STORE_ATTR, SPEC_FAIL_OVERRIDDEN);
1006
473
        goto fail;
1007
473
    }
1008
205k
    unsigned int tp_version = 0;
1009
205k
    DescriptorClassification kind = analyze_descriptor_store(type, name, &descr, &tp_version);
1010
205k
    if (tp_version == 0) {
1011
669
        goto fail;
1012
669
    }
1013
205k
    assert(descr != NULL || kind == ABSENT || kind == GETSET_OVERRIDDEN);
1014
204k
    switch(kind) {
1015
730
        case OVERRIDING:
1016
730
            SPECIALIZATION_FAIL(STORE_ATTR, SPEC_FAIL_ATTR_OVERRIDING_DESCRIPTOR);
1017
730
            goto fail;
1018
24
        case METHOD:
1019
24
            SPECIALIZATION_FAIL(STORE_ATTR, SPEC_FAIL_ATTR_METHOD);
1020
24
            goto fail;
1021
32
        case PROPERTY:
1022
32
            SPECIALIZATION_FAIL(STORE_ATTR, SPEC_FAIL_ATTR_PROPERTY);
1023
32
            goto fail;
1024
672
        case OBJECT_SLOT:
1025
672
        {
1026
672
            PyMemberDescrObject *member = (PyMemberDescrObject *)descr;
1027
672
            struct PyMemberDef *dmem = member->d_member;
1028
672
            Py_ssize_t offset = dmem->offset;
1029
672
            if (!PyObject_TypeCheck(owner, member->d_common.d_type)) {
1030
0
                SPECIALIZATION_FAIL(STORE_ATTR, SPEC_FAIL_EXPECTED_ERROR);
1031
0
                goto fail;
1032
0
            }
1033
672
            if (dmem->flags & _Py_AFTER_ITEMS) {
1034
0
                SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_ATTR_SLOT_AFTER_ITEMS);
1035
0
                goto fail;
1036
0
            }
1037
672
            if (dmem->flags & Py_READONLY) {
1038
0
                SPECIALIZATION_FAIL(STORE_ATTR, SPEC_FAIL_ATTR_READ_ONLY);
1039
0
                goto fail;
1040
0
            }
1041
672
            if (offset != (uint16_t)offset) {
1042
0
                SPECIALIZATION_FAIL(STORE_ATTR, SPEC_FAIL_OUT_OF_RANGE);
1043
0
                goto fail;
1044
0
            }
1045
672
            assert(dmem->type == Py_T_OBJECT_EX || dmem->type == _Py_T_OBJECT);
1046
672
            assert(offset > 0);
1047
672
            cache->index = (uint16_t)offset;
1048
672
            write_u32(cache->version, tp_version);
1049
672
            specialize(instr, STORE_ATTR_SLOT);
1050
672
            goto success;
1051
672
        }
1052
8
        case DUNDER_CLASS:
1053
8
        case OTHER_SLOT:
1054
8
            SPECIALIZATION_FAIL(STORE_ATTR, SPEC_FAIL_ATTR_NON_OBJECT_SLOT);
1055
8
            goto fail;
1056
2
        case MUTABLE:
1057
2
            SPECIALIZATION_FAIL(STORE_ATTR, SPEC_FAIL_ATTR_MUTABLE_CLASS);
1058
2
            goto fail;
1059
0
        case GETATTRIBUTE_IS_PYTHON_FUNCTION:
1060
0
        case GETSET_OVERRIDDEN:
1061
0
            SPECIALIZATION_FAIL(STORE_ATTR, SPEC_FAIL_OVERRIDDEN);
1062
0
            goto fail;
1063
0
        case BUILTIN_CLASSMETHOD:
1064
0
            SPECIALIZATION_FAIL(STORE_ATTR, SPEC_FAIL_ATTR_BUILTIN_CLASS_METHOD_OBJ);
1065
0
            goto fail;
1066
0
        case PYTHON_CLASSMETHOD:
1067
0
            SPECIALIZATION_FAIL(STORE_ATTR, SPEC_FAIL_ATTR_CLASS_METHOD_OBJ);
1068
0
            goto fail;
1069
0
        case NON_OVERRIDING:
1070
0
            SPECIALIZATION_FAIL(STORE_ATTR, SPEC_FAIL_ATTR_CLASS_ATTR_DESCRIPTOR);
1071
0
            goto fail;
1072
3.67k
        case NON_DESCRIPTOR:
1073
3.67k
            SPECIALIZATION_FAIL(STORE_ATTR, SPEC_FAIL_ATTR_CLASS_ATTR_SIMPLE);
1074
3.67k
            goto fail;
1075
199k
        case ABSENT:
1076
199k
            if (specialize_dict_access(owner, instr, type, kind, name, tp_version,
1077
199k
                                       STORE_ATTR, STORE_ATTR_INSTANCE_VALUE,
1078
199k
                                       STORE_ATTR_WITH_HINT)) {
1079
194k
                goto success;
1080
194k
            }
1081
204k
    }
1082
10.2k
fail:
1083
10.2k
    Py_XDECREF(descr);
1084
10.2k
    unspecialize(instr);
1085
10.2k
    return;
1086
195k
success:
1087
195k
    Py_XDECREF(descr);
1088
195k
    return;
1089
204k
}
1090
1091
#ifdef Py_STATS
1092
static int
1093
load_attr_fail_kind(DescriptorClassification kind)
1094
{
1095
    switch (kind) {
1096
        case OVERRIDING:
1097
            return SPEC_FAIL_ATTR_OVERRIDING_DESCRIPTOR;
1098
        case METHOD:
1099
            return SPEC_FAIL_ATTR_METHOD;
1100
        case PROPERTY:
1101
            return SPEC_FAIL_ATTR_PROPERTY;
1102
        case OBJECT_SLOT:
1103
            return SPEC_FAIL_ATTR_OBJECT_SLOT;
1104
        case OTHER_SLOT:
1105
            return SPEC_FAIL_ATTR_NON_OBJECT_SLOT;
1106
        case DUNDER_CLASS:
1107
            return SPEC_FAIL_OTHER;
1108
        case MUTABLE:
1109
            return SPEC_FAIL_ATTR_MUTABLE_CLASS;
1110
        case GETSET_OVERRIDDEN:
1111
        case GETATTRIBUTE_IS_PYTHON_FUNCTION:
1112
            return SPEC_FAIL_OVERRIDDEN;
1113
        case BUILTIN_CLASSMETHOD:
1114
            return SPEC_FAIL_ATTR_BUILTIN_CLASS_METHOD;
1115
        case PYTHON_CLASSMETHOD:
1116
            return SPEC_FAIL_ATTR_CLASS_METHOD_OBJ;
1117
        case NON_OVERRIDING:
1118
            return SPEC_FAIL_ATTR_NON_OVERRIDING_DESCRIPTOR;
1119
        case NON_DESCRIPTOR:
1120
            return SPEC_FAIL_ATTR_NOT_DESCRIPTOR;
1121
        case ABSENT:
1122
            return SPEC_FAIL_ATTR_INSTANCE_ATTRIBUTE;
1123
    }
1124
    Py_UNREACHABLE();
1125
}
1126
#endif   // Py_STATS
1127
1128
static int
1129
specialize_class_load_attr(PyObject *owner, _Py_CODEUNIT *instr,
1130
                             PyObject *name)
1131
68.7k
{
1132
68.7k
    assert(PyType_Check(owner));
1133
68.7k
    PyTypeObject *cls = (PyTypeObject *)owner;
1134
68.7k
    _PyLoadMethodCache *cache = (_PyLoadMethodCache *)(instr + 1);
1135
68.7k
    if (Py_TYPE(cls)->tp_getattro != _Py_type_getattro) {
1136
0
        SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_ATTR_METACLASS_OVERRIDDEN);
1137
0
        return -1;
1138
0
    }
1139
68.7k
    unsigned int meta_version = 0;
1140
68.7k
    PyObject *metadescriptor = _PyType_LookupRefAndVersion(Py_TYPE(cls), name, &meta_version);
1141
68.7k
    DescriptorClassification metakind = classify_descriptor(metadescriptor, false);
1142
68.7k
    Py_XDECREF(metadescriptor);
1143
68.7k
    switch (metakind) {
1144
747
        case METHOD:
1145
1.60k
        case NON_DESCRIPTOR:
1146
21.5k
        case NON_OVERRIDING:
1147
21.5k
        case BUILTIN_CLASSMETHOD:
1148
21.5k
        case PYTHON_CLASSMETHOD:
1149
66.2k
        case ABSENT:
1150
66.2k
            break;
1151
2.52k
        default:
1152
2.52k
            SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_ATTR_METACLASS_ATTRIBUTE);
1153
2.52k
            return -1;
1154
68.7k
    }
1155
66.2k
    PyObject *descr = NULL;
1156
66.2k
    DescriptorClassification kind = 0;
1157
66.2k
    unsigned int tp_version = 0;
1158
66.2k
    kind = analyze_descriptor_load(cls, name, &descr, &tp_version);
1159
66.2k
    if (tp_version == 0) {
1160
144
        SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_OUT_OF_VERSIONS);
1161
144
        Py_XDECREF(descr);
1162
144
        return -1;
1163
144
    }
1164
66.2k
    bool metaclass_check = false;
1165
66.0k
    if ((Py_TYPE(cls)->tp_flags & Py_TPFLAGS_IMMUTABLETYPE) == 0) {
1166
61.6k
        metaclass_check = true;
1167
61.6k
        if (meta_version == 0) {
1168
0
            SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_OUT_OF_VERSIONS);
1169
0
            Py_XDECREF(descr);
1170
0
            return -1;
1171
0
        }
1172
61.6k
    }
1173
66.0k
    switch (kind) {
1174
20.4k
        case METHOD:
1175
62.0k
        case NON_DESCRIPTOR:
1176
            #ifdef Py_GIL_DISABLED
1177
            if (!_PyObject_HasDeferredRefcount(descr)) {
1178
                SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_ATTR_DESCR_NOT_DEFERRED);
1179
                Py_XDECREF(descr);
1180
                return -1;
1181
            }
1182
            #endif
1183
62.0k
            write_u32(cache->type_version, tp_version);
1184
62.0k
            write_ptr(cache->descr, descr);
1185
62.0k
            if (metaclass_check) {
1186
60.8k
                write_u32(cache->keys_version, meta_version);
1187
60.8k
                specialize(instr, LOAD_ATTR_CLASS_WITH_METACLASS_CHECK);
1188
60.8k
            }
1189
1.20k
            else {
1190
1.20k
                specialize(instr, LOAD_ATTR_CLASS);
1191
1.20k
            }
1192
62.0k
            Py_XDECREF(descr);
1193
62.0k
            return 0;
1194
#ifdef Py_STATS
1195
        case ABSENT:
1196
            SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_EXPECTED_ERROR);
1197
            Py_XDECREF(descr);
1198
            return -1;
1199
#endif
1200
4.00k
        default:
1201
4.00k
            SPECIALIZATION_FAIL(LOAD_ATTR, load_attr_fail_kind(kind));
1202
4.00k
            Py_XDECREF(descr);
1203
4.00k
            return -1;
1204
66.0k
    }
1205
66.0k
}
1206
1207
// Please collect stats carefully before and after modifying. A subtle change
1208
// can cause a significant drop in cache hits. A possible test is
1209
// python.exe -m test_typing test_re test_dis test_zlib.
1210
static int
1211
specialize_attr_loadclassattr(PyObject *owner, _Py_CODEUNIT *instr,
1212
                              PyObject *name, PyObject *descr,
1213
                              unsigned int tp_version,
1214
                              DescriptorClassification kind, bool is_method,
1215
                              uint32_t shared_keys_version)
1216
1.21M
{
1217
1.21M
    _PyLoadMethodCache *cache = (_PyLoadMethodCache *)(instr + 1);
1218
1.21M
    PyTypeObject *owner_cls = Py_TYPE(owner);
1219
1220
1.21M
    assert(descr != NULL);
1221
1.21M
    assert((is_method && kind == METHOD) || (!is_method && kind == NON_DESCRIPTOR));
1222
1223
    #ifdef Py_GIL_DISABLED
1224
    if (!_PyObject_HasDeferredRefcount(descr)) {
1225
        SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_ATTR_DESCR_NOT_DEFERRED);
1226
        return 0;
1227
    }
1228
    #endif
1229
1230
1.21M
    unsigned long tp_flags = PyType_GetFlags(owner_cls);
1231
1.21M
    if (tp_flags & Py_TPFLAGS_INLINE_VALUES) {
1232
1.18M
        #ifndef Py_GIL_DISABLED
1233
1.18M
        assert(_PyDictKeys_StringLookup(
1234
1.18M
                   ((PyHeapTypeObject *)owner_cls)->ht_cached_keys, name) < 0);
1235
1.18M
        #endif
1236
1.18M
        if (shared_keys_version == 0) {
1237
0
            SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_OUT_OF_VERSIONS);
1238
0
            return 0;
1239
0
        }
1240
1.18M
        write_u32(cache->keys_version, shared_keys_version);
1241
1.18M
        specialize(instr, is_method ? LOAD_ATTR_METHOD_WITH_VALUES : LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES);
1242
1.18M
    }
1243
25.7k
    else {
1244
25.7k
        Py_ssize_t dictoffset;
1245
25.7k
        if (tp_flags & Py_TPFLAGS_MANAGED_DICT) {
1246
789
            dictoffset = MANAGED_DICT_OFFSET;
1247
789
        }
1248
24.9k
        else {
1249
24.9k
            dictoffset = owner_cls->tp_dictoffset;
1250
24.9k
            if (dictoffset < 0 || dictoffset > INT16_MAX + MANAGED_DICT_OFFSET) {
1251
0
                SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_OUT_OF_RANGE);
1252
0
                return 0;
1253
0
            }
1254
24.9k
        }
1255
25.7k
        if (dictoffset == 0) {
1256
20.3k
            specialize(instr, is_method ? LOAD_ATTR_METHOD_NO_DICT : LOAD_ATTR_NONDESCRIPTOR_NO_DICT);
1257
20.3k
        }
1258
5.42k
        else if (is_method) {
1259
4.94k
            PyObject **addr = (PyObject **)((char *)owner + dictoffset);
1260
4.94k
            PyObject *dict = FT_ATOMIC_LOAD_PTR_ACQUIRE(*addr);
1261
4.94k
            if (dict) {
1262
4.75k
                SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_ATTR_NOT_MANAGED_DICT);
1263
4.75k
                return 0;
1264
4.75k
            }
1265
            /* Cache entries must be unsigned values, so we offset the
1266
             * dictoffset by MANAGED_DICT_OFFSET.
1267
             * We do the reverse offset in LOAD_ATTR_METHOD_LAZY_DICT */
1268
187
            dictoffset -= MANAGED_DICT_OFFSET;
1269
187
            assert(((uint16_t)dictoffset) == dictoffset);
1270
187
            cache->dict_offset = (uint16_t)dictoffset;
1271
187
            specialize(instr, LOAD_ATTR_METHOD_LAZY_DICT);
1272
187
        }
1273
482
        else {
1274
482
            SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_ATTR_CLASS_ATTR_SIMPLE);
1275
482
            return 0;
1276
482
        }
1277
25.7k
    }
1278
    /* `descr` is borrowed. This is safe for methods (even inherited ones from
1279
    *  super classes!) as long as tp_version_tag is validated for two main reasons:
1280
    *
1281
    *  1. The class will always hold a reference to the method so it will
1282
    *  usually not be GC-ed. Should it be deleted in Python, e.g.
1283
    *  `del obj.meth`, tp_version_tag will be invalidated, because of reason 2.
1284
    *
1285
    *  2. The pre-existing type method cache (MCACHE) uses the same principles
1286
    *  of caching a borrowed descriptor. The MCACHE infrastructure does all the
1287
    *  heavy lifting for us. E.g. it invalidates tp_version_tag on any MRO
1288
    *  modification, on any type object change along said MRO, etc. (see
1289
    *  PyType_Modified usages in typeobject.c). The MCACHE has been
1290
    *  working since Python 2.6 and it's battle-tested.
1291
    */
1292
1.20M
    write_u32(cache->type_version, tp_version);
1293
1.20M
    write_ptr(cache->descr, descr);
1294
1.20M
    return 1;
1295
1.21M
}
1296
1297
static void
1298
specialize_load_global_lock_held(
1299
    PyObject *globals, PyObject *builtins,
1300
    _Py_CODEUNIT *instr, PyObject *name)
1301
31.7k
{
1302
31.7k
    assert(ENABLE_SPECIALIZATION);
1303
31.7k
    assert(_PyOpcode_Caches[LOAD_GLOBAL] == INLINE_CACHE_ENTRIES_LOAD_GLOBAL);
1304
    /* Use inline cache */
1305
31.7k
    _PyLoadGlobalCache *cache = (_PyLoadGlobalCache *)(instr + 1);
1306
31.7k
    assert(PyUnicode_CheckExact(name));
1307
31.7k
    if (!PyDict_CheckExact(globals)) {
1308
0
        SPECIALIZATION_FAIL(LOAD_GLOBAL, SPEC_FAIL_LOAD_GLOBAL_NON_DICT);
1309
0
        goto fail;
1310
0
    }
1311
31.7k
    PyDictKeysObject * globals_keys = ((PyDictObject *)globals)->ma_keys;
1312
31.7k
    if (globals_keys->dk_kind != DICT_KEYS_UNICODE) {
1313
0
        SPECIALIZATION_FAIL(LOAD_GLOBAL, SPEC_FAIL_LOAD_GLOBAL_NON_STRING_OR_SPLIT);
1314
0
        goto fail;
1315
0
    }
1316
31.7k
    PyObject *value;
1317
31.7k
    Py_ssize_t index = _PyDict_LookupIndexAndValue((PyDictObject *)globals, name, &value);
1318
31.7k
    if (index == DKIX_ERROR) {
1319
0
        SPECIALIZATION_FAIL(LOAD_GLOBAL, SPEC_FAIL_EXPECTED_ERROR);
1320
0
        goto fail;
1321
0
    }
1322
31.7k
    if (value != NULL && PyLazyImport_CheckExact(value)) {
1323
0
        SPECIALIZATION_FAIL(LOAD_GLOBAL, SPEC_FAIL_ATTR_MODULE_LAZY_VALUE);
1324
0
        goto fail;
1325
0
    }
1326
31.7k
    PyInterpreterState *interp = _PyInterpreterState_GET();
1327
31.7k
    if (index != DKIX_EMPTY) {
1328
18.6k
        if (index != (uint16_t)index) {
1329
0
            SPECIALIZATION_FAIL(LOAD_GLOBAL, SPEC_FAIL_OUT_OF_RANGE);
1330
0
            goto fail;
1331
0
        }
1332
18.6k
        uint32_t keys_version = _PyDict_GetKeysVersionForCurrentState(
1333
18.6k
                interp, (PyDictObject*) globals);
1334
18.6k
        if (keys_version == 0) {
1335
0
            SPECIALIZATION_FAIL(LOAD_GLOBAL, SPEC_FAIL_OUT_OF_VERSIONS);
1336
0
            goto fail;
1337
0
        }
1338
18.6k
        if (keys_version != (uint16_t)keys_version) {
1339
0
            SPECIALIZATION_FAIL(LOAD_GLOBAL, SPEC_FAIL_OUT_OF_RANGE);
1340
0
            goto fail;
1341
0
        }
1342
#ifdef Py_GIL_DISABLED
1343
        maybe_enable_deferred_ref_count(value);
1344
#endif
1345
18.6k
        cache->index = (uint16_t)index;
1346
18.6k
        cache->module_keys_version = (uint16_t)keys_version;
1347
18.6k
        specialize(instr, LOAD_GLOBAL_MODULE);
1348
18.6k
        return;
1349
18.6k
    }
1350
13.0k
    if (!PyDict_CheckExact(builtins)) {
1351
0
        SPECIALIZATION_FAIL(LOAD_GLOBAL, SPEC_FAIL_LOAD_GLOBAL_NON_DICT);
1352
0
        goto fail;
1353
0
    }
1354
13.0k
    PyDictKeysObject * builtin_keys = ((PyDictObject *)builtins)->ma_keys;
1355
13.0k
    if (builtin_keys->dk_kind != DICT_KEYS_UNICODE) {
1356
0
        SPECIALIZATION_FAIL(LOAD_GLOBAL, SPEC_FAIL_LOAD_GLOBAL_NON_STRING_OR_SPLIT);
1357
0
        goto fail;
1358
0
    }
1359
13.0k
    index = _PyDictKeys_StringLookup(builtin_keys, name);
1360
13.0k
    if (index == DKIX_ERROR) {
1361
0
        SPECIALIZATION_FAIL(LOAD_GLOBAL, SPEC_FAIL_EXPECTED_ERROR);
1362
0
        goto fail;
1363
0
    }
1364
13.0k
    if (index != (uint16_t)index) {
1365
0
        SPECIALIZATION_FAIL(LOAD_GLOBAL, SPEC_FAIL_OUT_OF_RANGE);
1366
0
        goto fail;
1367
0
    }
1368
13.0k
    uint32_t globals_version = _PyDict_GetKeysVersionForCurrentState(
1369
13.0k
            interp, (PyDictObject*) globals);
1370
13.0k
    if (globals_version == 0) {
1371
0
        SPECIALIZATION_FAIL(LOAD_GLOBAL, SPEC_FAIL_OUT_OF_VERSIONS);
1372
0
        goto fail;
1373
0
    }
1374
13.0k
    if (globals_version != (uint16_t)globals_version) {
1375
0
        SPECIALIZATION_FAIL(LOAD_GLOBAL, SPEC_FAIL_OUT_OF_RANGE);
1376
0
        goto fail;
1377
0
    }
1378
13.0k
    uint32_t builtins_version = _PyDict_GetKeysVersionForCurrentState(
1379
13.0k
            interp, (PyDictObject*) builtins);
1380
13.0k
    if (builtins_version == 0) {
1381
0
        SPECIALIZATION_FAIL(LOAD_GLOBAL, SPEC_FAIL_OUT_OF_VERSIONS);
1382
0
        goto fail;
1383
0
    }
1384
13.0k
    if (builtins_version > UINT16_MAX) {
1385
0
        SPECIALIZATION_FAIL(LOAD_GLOBAL, SPEC_FAIL_OUT_OF_RANGE);
1386
0
        goto fail;
1387
0
    }
1388
13.0k
    cache->index = (uint16_t)index;
1389
13.0k
    cache->module_keys_version = (uint16_t)globals_version;
1390
13.0k
    cache->builtin_keys_version = (uint16_t)builtins_version;
1391
13.0k
    specialize(instr, LOAD_GLOBAL_BUILTIN);
1392
13.0k
    return;
1393
0
fail:
1394
0
    unspecialize(instr);
1395
0
}
1396
1397
Py_NO_INLINE void
1398
_Py_Specialize_LoadGlobal(
1399
    PyObject *globals, PyObject *builtins,
1400
    _Py_CODEUNIT *instr, PyObject *name)
1401
31.7k
{
1402
31.7k
    Py_BEGIN_CRITICAL_SECTION2(globals, builtins);
1403
31.7k
    specialize_load_global_lock_held(globals, builtins, instr, name);
1404
31.7k
    Py_END_CRITICAL_SECTION2();
1405
31.7k
}
1406
1407
static int
1408
227k
function_kind(PyCodeObject *code) {
1409
227k
    int flags = code->co_flags;
1410
227k
    if ((flags & (CO_VARKEYWORDS | CO_VARARGS)) || code->co_kwonlyargcount) {
1411
1.69k
        return SPEC_FAIL_CODE_COMPLEX_PARAMETERS;
1412
1.69k
    }
1413
225k
    if ((flags & CO_OPTIMIZED) == 0) {
1414
0
        return SPEC_FAIL_CODE_NOT_OPTIMIZED;
1415
0
    }
1416
225k
    return SIMPLE_FUNCTION;
1417
225k
}
1418
1419
/* Returning false indicates a failure. */
1420
static bool
1421
function_check_args(PyObject *o, int expected_argcount, int opcode)
1422
204k
{
1423
204k
    assert(Py_IS_TYPE(o, &PyFunction_Type));
1424
204k
    PyFunctionObject *func = (PyFunctionObject *)o;
1425
204k
    PyCodeObject *fcode = (PyCodeObject *)func->func_code;
1426
204k
    int kind = function_kind(fcode);
1427
204k
    if (kind != SIMPLE_FUNCTION) {
1428
0
        SPECIALIZATION_FAIL(opcode, kind);
1429
0
        return false;
1430
0
    }
1431
204k
    if (fcode->co_argcount != expected_argcount) {
1432
0
        SPECIALIZATION_FAIL(opcode, SPEC_FAIL_WRONG_NUMBER_ARGUMENTS);
1433
0
        return false;
1434
0
    }
1435
204k
    return true;
1436
204k
}
1437
1438
/* Returning 0 indicates a failure. */
1439
static uint32_t
1440
function_get_version(PyObject *o, int opcode)
1441
0
{
1442
0
    assert(Py_IS_TYPE(o, &PyFunction_Type));
1443
0
    PyFunctionObject *func = (PyFunctionObject *)o;
1444
0
    uint32_t version = _PyFunction_GetVersionForCurrentState(func);
1445
0
    if (!_PyFunction_IsVersionValid(version)) {
1446
0
        SPECIALIZATION_FAIL(opcode, SPEC_FAIL_OUT_OF_VERSIONS);
1447
0
        return 0;
1448
0
    }
1449
0
    return version;
1450
0
}
1451
1452
#ifdef Py_STATS
1453
static int
1454
store_subscr_fail_kind(PyObject *container, PyObject *sub)
1455
{
1456
    PyTypeObject *container_type = Py_TYPE(container);
1457
    PyMappingMethods *as_mapping = container_type->tp_as_mapping;
1458
    if (as_mapping && (as_mapping->mp_ass_subscript
1459
                       == PyDict_Type.tp_as_mapping->mp_ass_subscript)) {
1460
        return SPEC_FAIL_SUBSCR_DICT_SUBCLASS_NO_OVERRIDE;
1461
    }
1462
    if (PyObject_CheckBuffer(container)) {
1463
        if (PyLong_CheckExact(sub) && (!_PyLong_IsNonNegativeCompact((PyLongObject *)sub))) {
1464
            return SPEC_FAIL_OUT_OF_RANGE;
1465
        }
1466
        else if (strcmp(container_type->tp_name, "array.array") == 0) {
1467
            if (PyLong_CheckExact(sub)) {
1468
                return SPEC_FAIL_SUBSCR_ARRAY_INT;
1469
            }
1470
            else if (PySlice_Check(sub)) {
1471
                return SPEC_FAIL_SUBSCR_ARRAY_SLICE;
1472
            }
1473
            else {
1474
                return SPEC_FAIL_OTHER;
1475
            }
1476
        }
1477
        else if (PyByteArray_CheckExact(container)) {
1478
            if (PyLong_CheckExact(sub)) {
1479
                return SPEC_FAIL_SUBSCR_BYTEARRAY_INT;
1480
            }
1481
            else if (PySlice_Check(sub)) {
1482
                return SPEC_FAIL_SUBSCR_BYTEARRAY_SLICE;
1483
            }
1484
            else {
1485
                return SPEC_FAIL_OTHER;
1486
            }
1487
        }
1488
        else {
1489
            if (PyLong_CheckExact(sub)) {
1490
                return SPEC_FAIL_SUBSCR_BUFFER_INT;
1491
            }
1492
            else if (PySlice_Check(sub)) {
1493
                return SPEC_FAIL_SUBSCR_BUFFER_SLICE;
1494
            }
1495
            else {
1496
                return SPEC_FAIL_OTHER;
1497
            }
1498
        }
1499
        return SPEC_FAIL_OTHER;
1500
    }
1501
    PyObject *descriptor = _PyType_Lookup(container_type, &_Py_ID(__setitem__));
1502
    if (descriptor && Py_TYPE(descriptor) == &PyFunction_Type) {
1503
        PyFunctionObject *func = (PyFunctionObject *)descriptor;
1504
        PyCodeObject *code = (PyCodeObject *)func->func_code;
1505
        int kind = function_kind(code);
1506
        if (kind == SIMPLE_FUNCTION) {
1507
            return SPEC_FAIL_SUBSCR_PY_SIMPLE;
1508
        }
1509
        else {
1510
            return SPEC_FAIL_SUBSCR_PY_OTHER;
1511
        }
1512
    }
1513
    return SPEC_FAIL_OTHER;
1514
}
1515
#endif
1516
1517
Py_NO_INLINE void
1518
_Py_Specialize_StoreSubscr(_PyStackRef container_st, _PyStackRef sub_st, _Py_CODEUNIT *instr)
1519
16.4k
{
1520
16.4k
    PyObject *container = PyStackRef_AsPyObjectBorrow(container_st);
1521
16.4k
    PyObject *sub = PyStackRef_AsPyObjectBorrow(sub_st);
1522
1523
16.4k
    assert(ENABLE_SPECIALIZATION);
1524
16.4k
    PyTypeObject *container_type = Py_TYPE(container);
1525
16.4k
    if (container_type == &PyList_Type) {
1526
876
        if (PyLong_CheckExact(sub)) {
1527
851
            if (_PyLong_IsNonNegativeCompact((PyLongObject *)sub)
1528
249
                && ((PyLongObject *)sub)->long_value.ob_digit[0] < (size_t)PyList_GET_SIZE(container))
1529
249
            {
1530
249
                specialize(instr, STORE_SUBSCR_LIST_INT);
1531
249
                return;
1532
249
            }
1533
602
            else {
1534
602
                SPECIALIZATION_FAIL(STORE_SUBSCR, SPEC_FAIL_OUT_OF_RANGE);
1535
602
                unspecialize(instr);
1536
602
                return;
1537
602
            }
1538
851
        }
1539
25
        else if (PySlice_Check(sub)) {
1540
25
            SPECIALIZATION_FAIL(STORE_SUBSCR, SPEC_FAIL_SUBSCR_LIST_SLICE);
1541
25
            unspecialize(instr);
1542
25
            return;
1543
25
        }
1544
0
        else {
1545
0
            SPECIALIZATION_FAIL(STORE_SUBSCR, SPEC_FAIL_OTHER);
1546
0
            unspecialize(instr);
1547
0
            return;
1548
0
        }
1549
876
    }
1550
15.5k
    if (container_type == &PyDict_Type) {
1551
1.84k
        specialize(instr, STORE_SUBSCR_DICT);
1552
1.84k
        return;
1553
1.84k
    }
1554
13.7k
    SPECIALIZATION_FAIL(STORE_SUBSCR, store_subscr_fail_kind(container, sub));
1555
13.7k
    unspecialize(instr);
1556
13.7k
}
1557
1558
/* Returns a strong reference. */
1559
static PyObject *
1560
get_init_for_simple_managed_python_class(PyTypeObject *tp, unsigned int *tp_version)
1561
826
{
1562
826
    assert(tp->tp_new == PyBaseObject_Type.tp_new);
1563
826
    if (tp->tp_alloc != PyType_GenericAlloc) {
1564
0
        SPECIALIZATION_FAIL(CALL, SPEC_FAIL_OVERRIDDEN);
1565
0
        return NULL;
1566
0
    }
1567
826
    unsigned long tp_flags = PyType_GetFlags(tp);
1568
826
    if (!(tp_flags & Py_TPFLAGS_HEAPTYPE)) {
1569
        /* Is this possible? */
1570
0
        SPECIALIZATION_FAIL(CALL, SPEC_FAIL_EXPECTED_ERROR);
1571
0
        return NULL;
1572
0
    }
1573
826
    PyObject *init = _PyType_LookupRefAndVersion(tp, &_Py_ID(__init__), tp_version);
1574
826
    if (init == NULL || !PyFunction_Check(init)) {
1575
284
        SPECIALIZATION_FAIL(CALL, SPEC_FAIL_CALL_INIT_NOT_PYTHON);
1576
284
        Py_XDECREF(init);
1577
284
        return NULL;
1578
284
    }
1579
542
    int kind = function_kind((PyCodeObject *)PyFunction_GET_CODE(init));
1580
542
    if (kind != SIMPLE_FUNCTION) {
1581
50
        SPECIALIZATION_FAIL(CALL, SPEC_FAIL_CALL_INIT_NOT_SIMPLE);
1582
50
        Py_DECREF(init);
1583
50
        return NULL;
1584
50
    }
1585
492
    return init;
1586
542
}
1587
1588
static int
1589
specialize_class_call(PyObject *callable, _Py_CODEUNIT *instr, int nargs)
1590
3.43k
{
1591
3.43k
    assert(PyType_Check(callable));
1592
3.43k
    PyTypeObject *tp = _PyType_CAST(callable);
1593
3.43k
    if (tp->tp_flags & Py_TPFLAGS_IMMUTABLETYPE) {
1594
2.18k
        int oparg = instr->op.arg;
1595
2.18k
        if (nargs == 1 && oparg == 1) {
1596
1.42k
            if (tp == &PyUnicode_Type) {
1597
139
                specialize(instr, CALL_STR_1);
1598
139
                return 0;
1599
139
            }
1600
1.28k
            else if (tp == &PyType_Type) {
1601
315
                specialize(instr, CALL_TYPE_1);
1602
315
                return 0;
1603
315
            }
1604
968
            else if (tp == &PyTuple_Type) {
1605
97
                specialize(instr, CALL_TUPLE_1);
1606
97
                return 0;
1607
97
            }
1608
1.42k
        }
1609
1.63k
        if (tp->tp_vectorcall != NULL) {
1610
1.11k
            specialize(instr, CALL_BUILTIN_CLASS);
1611
1.11k
            return 0;
1612
1.11k
        }
1613
518
        goto generic;
1614
1.63k
    }
1615
1.25k
    if (Py_TYPE(tp) != &PyType_Type) {
1616
73
        goto generic;
1617
73
    }
1618
1.18k
    if (tp->tp_new == PyBaseObject_Type.tp_new) {
1619
826
        unsigned int tp_version = 0;
1620
826
        PyObject *init = get_init_for_simple_managed_python_class(tp, &tp_version);
1621
826
        if (!tp_version) {
1622
7
            SPECIALIZATION_FAIL(CALL, SPEC_FAIL_OUT_OF_VERSIONS);
1623
7
            Py_XDECREF(init);
1624
7
            return -1;
1625
7
        }
1626
819
        if (init != NULL && _PyType_CacheInitForSpecialization(
1627
485
                                (PyHeapTypeObject *)tp, init, tp_version)) {
1628
485
            _PyCallCache *cache = (_PyCallCache *)(instr + 1);
1629
485
            write_u32(cache->func_version, tp_version);
1630
485
            specialize(instr, CALL_ALLOC_AND_ENTER_INIT);
1631
485
            Py_DECREF(init);
1632
485
            return 0;
1633
485
        }
1634
334
        Py_XDECREF(init);
1635
334
    }
1636
1.28k
generic:
1637
1.28k
    specialize(instr, CALL_NON_PY_GENERAL);
1638
1.28k
    return 0;
1639
1.18k
}
1640
1641
static int
1642
specialize_method_descriptor(PyMethodDescrObject *descr, PyObject *self_or_null,
1643
                             _Py_CODEUNIT *instr, int nargs)
1644
509k
{
1645
509k
    switch (descr->d_method->ml_flags &
1646
509k
        (METH_VARARGS | METH_FASTCALL | METH_NOARGS | METH_O |
1647
509k
        METH_KEYWORDS | METH_METHOD)) {
1648
46.4k
        case METH_NOARGS: {
1649
46.4k
            if (nargs != 1) {
1650
0
                SPECIALIZATION_FAIL(CALL, SPEC_FAIL_WRONG_NUMBER_ARGUMENTS);
1651
0
                return -1;
1652
0
            }
1653
46.4k
            specialize(instr, CALL_METHOD_DESCRIPTOR_NOARGS);
1654
46.4k
            return 0;
1655
46.4k
        }
1656
381k
        case METH_O: {
1657
381k
            if (nargs != 2) {
1658
0
                SPECIALIZATION_FAIL(CALL, SPEC_FAIL_WRONG_NUMBER_ARGUMENTS);
1659
0
                return -1;
1660
0
            }
1661
381k
            PyInterpreterState *interp = _PyInterpreterState_GET();
1662
381k
            PyObject *list_append = interp->callable_cache.list_append;
1663
381k
            int oparg = instr->op.arg;
1664
381k
            if ((PyObject *)descr == list_append && oparg == 1) {
1665
374k
                assert(self_or_null != NULL);
1666
374k
                if (PyList_CheckExact(self_or_null)) {
1667
925
                    specialize(instr, CALL_LIST_APPEND);
1668
925
                    return 0;
1669
925
                }
1670
374k
            }
1671
380k
            specialize(instr, CALL_METHOD_DESCRIPTOR_O);
1672
380k
            return 0;
1673
381k
        }
1674
3.06k
        case METH_FASTCALL: {
1675
3.06k
            specialize(instr, CALL_METHOD_DESCRIPTOR_FAST);
1676
3.06k
            return 0;
1677
381k
        }
1678
77.9k
        case METH_FASTCALL | METH_KEYWORDS: {
1679
77.9k
            specialize(instr, CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS);
1680
77.9k
            return 0;
1681
381k
        }
1682
509k
    }
1683
390
    specialize(instr, CALL_NON_PY_GENERAL);
1684
390
    return 0;
1685
509k
}
1686
1687
static int
1688
specialize_py_call(PyFunctionObject *func, _Py_CODEUNIT *instr, int nargs,
1689
                   bool bound_method)
1690
22.0k
{
1691
22.0k
    _PyCallCache *cache = (_PyCallCache *)(instr + 1);
1692
22.0k
    PyCodeObject *code = (PyCodeObject *)func->func_code;
1693
22.0k
    int kind = function_kind(code);
1694
    /* Don't specialize if PEP 523 is active */
1695
22.0k
    if (_PyInterpreterState_GET()->eval_frame) {
1696
0
        SPECIALIZATION_FAIL(CALL, SPEC_FAIL_CALL_PEP_523);
1697
0
        return -1;
1698
0
    }
1699
22.0k
    if (func->vectorcall != _PyFunction_Vectorcall) {
1700
0
        SPECIALIZATION_FAIL(CALL, SPEC_FAIL_CALL_VECTORCALL);
1701
0
        return -1;
1702
0
    }
1703
22.0k
    int argcount = -1;
1704
22.0k
    if (kind == SPEC_FAIL_CODE_NOT_OPTIMIZED) {
1705
0
        SPECIALIZATION_FAIL(CALL, SPEC_FAIL_CODE_NOT_OPTIMIZED);
1706
0
        return -1;
1707
0
    }
1708
22.0k
    if (kind == SIMPLE_FUNCTION) {
1709
20.8k
        argcount = code->co_argcount;
1710
20.8k
    }
1711
22.0k
    int version = _PyFunction_GetVersionForCurrentState(func);
1712
22.0k
    if (!_PyFunction_IsVersionValid(version)) {
1713
6
        SPECIALIZATION_FAIL(CALL, SPEC_FAIL_OUT_OF_VERSIONS);
1714
6
        return -1;
1715
6
    }
1716
22.0k
    write_u32(cache->func_version, version);
1717
22.0k
    uint8_t opcode;
1718
22.0k
    if (argcount == nargs + bound_method) {
1719
20.5k
        opcode =
1720
20.5k
            bound_method ? CALL_BOUND_METHOD_EXACT_ARGS : CALL_PY_EXACT_ARGS;
1721
20.5k
    }
1722
1.58k
    else {
1723
1.58k
        opcode = bound_method ? CALL_BOUND_METHOD_GENERAL : CALL_PY_GENERAL;
1724
1.58k
    }
1725
22.0k
    specialize(instr, opcode);
1726
22.0k
    return 0;
1727
22.0k
}
1728
1729
1730
static int
1731
specialize_py_call_kw(PyFunctionObject *func, _Py_CODEUNIT *instr, int nargs,
1732
                   bool bound_method)
1733
500
{
1734
500
    _PyCallCache *cache = (_PyCallCache *)(instr + 1);
1735
500
    PyCodeObject *code = (PyCodeObject *)func->func_code;
1736
500
    int kind = function_kind(code);
1737
    /* Don't specialize if PEP 523 is active */
1738
500
    if (_PyInterpreterState_GET()->eval_frame) {
1739
0
        SPECIALIZATION_FAIL(CALL, SPEC_FAIL_CALL_PEP_523);
1740
0
        return -1;
1741
0
    }
1742
500
    if (func->vectorcall != _PyFunction_Vectorcall) {
1743
0
        SPECIALIZATION_FAIL(CALL, SPEC_FAIL_CALL_VECTORCALL);
1744
0
        return -1;
1745
0
    }
1746
500
    if (kind == SPEC_FAIL_CODE_NOT_OPTIMIZED) {
1747
0
        SPECIALIZATION_FAIL(CALL, SPEC_FAIL_CODE_NOT_OPTIMIZED);
1748
0
        return -1;
1749
0
    }
1750
500
    int version = _PyFunction_GetVersionForCurrentState(func);
1751
500
    if (!_PyFunction_IsVersionValid(version)) {
1752
0
        SPECIALIZATION_FAIL(CALL, SPEC_FAIL_OUT_OF_VERSIONS);
1753
0
        return -1;
1754
0
    }
1755
500
    write_u32(cache->func_version, version);
1756
500
    specialize(instr, bound_method ? CALL_KW_BOUND_METHOD : CALL_KW_PY);
1757
500
    return 0;
1758
500
}
1759
1760
static int
1761
specialize_c_call(PyObject *callable, _Py_CODEUNIT *instr, int nargs)
1762
436k
{
1763
436k
    if (PyCFunction_GET_FUNCTION(callable) == NULL) {
1764
0
        SPECIALIZATION_FAIL(CALL, SPEC_FAIL_OTHER);
1765
0
        return 1;
1766
0
    }
1767
436k
    switch (PyCFunction_GET_FLAGS(callable) &
1768
436k
        (METH_VARARGS | METH_FASTCALL | METH_NOARGS | METH_O |
1769
436k
        METH_KEYWORDS | METH_METHOD)) {
1770
419k
        case METH_O: {
1771
419k
            if (nargs != 1) {
1772
0
                SPECIALIZATION_FAIL(CALL, SPEC_FAIL_WRONG_NUMBER_ARGUMENTS);
1773
0
                return 1;
1774
0
            }
1775
            /* len(o) */
1776
419k
            PyInterpreterState *interp = _PyInterpreterState_GET();
1777
419k
            if (callable == interp->callable_cache.len && instr->op.arg == 1) {
1778
1.81k
                specialize(instr, CALL_LEN);
1779
1.81k
                return 0;
1780
1.81k
            }
1781
417k
            specialize(instr, CALL_BUILTIN_O);
1782
417k
            return 0;
1783
419k
        }
1784
15.5k
        case METH_FASTCALL: {
1785
15.5k
            if (nargs == 2) {
1786
                /* isinstance(o1, o2) */
1787
3.23k
                PyInterpreterState *interp = _PyInterpreterState_GET();
1788
3.23k
                if (callable == interp->callable_cache.isinstance && instr->op.arg == 2) {
1789
1.75k
                    specialize(instr, CALL_ISINSTANCE);
1790
1.75k
                    return 0;
1791
1.75k
                }
1792
3.23k
            }
1793
13.7k
            specialize(instr, CALL_BUILTIN_FAST);
1794
13.7k
            return 0;
1795
15.5k
        }
1796
1.44k
        case METH_FASTCALL | METH_KEYWORDS: {
1797
1.44k
            specialize(instr, CALL_BUILTIN_FAST_WITH_KEYWORDS);
1798
1.44k
            return 0;
1799
15.5k
        }
1800
503
        default:
1801
503
            specialize(instr, CALL_NON_PY_GENERAL);
1802
503
            return 0;
1803
436k
    }
1804
436k
}
1805
1806
Py_NO_INLINE void
1807
_Py_Specialize_Call(_PyStackRef callable_st, _PyStackRef self_or_null_st, _Py_CODEUNIT *instr, int nargs)
1808
978k
{
1809
978k
    PyObject *callable = PyStackRef_AsPyObjectBorrow(callable_st);
1810
1811
978k
    assert(ENABLE_SPECIALIZATION);
1812
978k
    assert(_PyOpcode_Caches[CALL] == INLINE_CACHE_ENTRIES_CALL);
1813
978k
    assert(_Py_OPCODE(*instr) != INSTRUMENTED_CALL);
1814
978k
    int fail;
1815
978k
    if (PyCFunction_CheckExact(callable)) {
1816
436k
        fail = specialize_c_call(callable, instr, nargs);
1817
436k
    }
1818
541k
    else if (PyFunction_Check(callable)) {
1819
19.2k
        fail = specialize_py_call((PyFunctionObject *)callable, instr, nargs, false);
1820
19.2k
    }
1821
522k
    else if (PyType_Check(callable)) {
1822
3.43k
        fail = specialize_class_call(callable, instr, nargs);
1823
3.43k
    }
1824
518k
    else if (Py_IS_TYPE(callable, &PyMethodDescr_Type)) {
1825
509k
        PyObject *self_or_null = PyStackRef_AsPyObjectBorrow(self_or_null_st);
1826
509k
        fail = specialize_method_descriptor((PyMethodDescrObject *)callable,
1827
509k
                                            self_or_null, instr, nargs);
1828
509k
    }
1829
9.24k
    else if (PyMethod_Check(callable)) {
1830
2.88k
        PyObject *func = ((PyMethodObject *)callable)->im_func;
1831
2.88k
        if (PyFunction_Check(func)) {
1832
2.87k
            fail = specialize_py_call((PyFunctionObject *)func, instr, nargs, true);
1833
2.87k
        }
1834
8
        else {
1835
8
            SPECIALIZATION_FAIL(CALL, SPEC_FAIL_CALL_BOUND_METHOD);
1836
8
            fail = -1;
1837
8
        }
1838
2.88k
    }
1839
6.36k
    else {
1840
6.36k
        specialize(instr, CALL_NON_PY_GENERAL);
1841
6.36k
        fail = 0;
1842
6.36k
    }
1843
978k
    if (fail) {
1844
21
        unspecialize(instr);
1845
21
    }
1846
978k
}
1847
1848
Py_NO_INLINE void
1849
_Py_Specialize_CallKw(_PyStackRef callable_st, _Py_CODEUNIT *instr, int nargs)
1850
1.12k
{
1851
1.12k
    PyObject *callable = PyStackRef_AsPyObjectBorrow(callable_st);
1852
1853
1.12k
    assert(ENABLE_SPECIALIZATION);
1854
1.12k
    assert(_PyOpcode_Caches[CALL_KW] == INLINE_CACHE_ENTRIES_CALL_KW);
1855
1.12k
    assert(_Py_OPCODE(*instr) != INSTRUMENTED_CALL_KW);
1856
1.12k
    int fail;
1857
1.12k
    if (PyFunction_Check(callable)) {
1858
478
        fail = specialize_py_call_kw((PyFunctionObject *)callable, instr, nargs, false);
1859
478
    }
1860
643
    else if (PyMethod_Check(callable)) {
1861
22
        PyObject *func = ((PyMethodObject *)callable)->im_func;
1862
22
        if (PyFunction_Check(func)) {
1863
22
            fail = specialize_py_call_kw((PyFunctionObject *)func, instr, nargs, true);
1864
22
        }
1865
0
        else {
1866
0
            SPECIALIZATION_FAIL(CALL_KW, SPEC_FAIL_CALL_BOUND_METHOD);
1867
0
            fail = -1;
1868
0
        }
1869
22
    }
1870
621
    else {
1871
621
        specialize(instr, CALL_KW_NON_PY);
1872
621
        fail = 0;
1873
621
    }
1874
1.12k
    if (fail) {
1875
0
        unspecialize(instr);
1876
0
    }
1877
1.12k
}
1878
1879
#ifdef Py_STATS
1880
static int
1881
binary_op_fail_kind(int oparg, PyObject *lhs, PyObject *rhs)
1882
{
1883
    switch (oparg) {
1884
        case NB_ADD:
1885
        case NB_INPLACE_ADD:
1886
            if (!Py_IS_TYPE(lhs, Py_TYPE(rhs))) {
1887
                return SPEC_FAIL_BINARY_OP_ADD_DIFFERENT_TYPES;
1888
            }
1889
            return SPEC_FAIL_BINARY_OP_ADD_OTHER;
1890
        case NB_AND:
1891
        case NB_INPLACE_AND:
1892
            if (!Py_IS_TYPE(lhs, Py_TYPE(rhs))) {
1893
                return SPEC_FAIL_BINARY_OP_AND_DIFFERENT_TYPES;
1894
            }
1895
            if (PyLong_CheckExact(lhs)) {
1896
                return SPEC_FAIL_BINARY_OP_AND_INT;
1897
            }
1898
            return SPEC_FAIL_BINARY_OP_AND_OTHER;
1899
        case NB_FLOOR_DIVIDE:
1900
        case NB_INPLACE_FLOOR_DIVIDE:
1901
            return SPEC_FAIL_BINARY_OP_FLOOR_DIVIDE;
1902
        case NB_LSHIFT:
1903
        case NB_INPLACE_LSHIFT:
1904
            return SPEC_FAIL_BINARY_OP_LSHIFT;
1905
        case NB_MATRIX_MULTIPLY:
1906
        case NB_INPLACE_MATRIX_MULTIPLY:
1907
            return SPEC_FAIL_BINARY_OP_MATRIX_MULTIPLY;
1908
        case NB_MULTIPLY:
1909
        case NB_INPLACE_MULTIPLY:
1910
            if (!Py_IS_TYPE(lhs, Py_TYPE(rhs))) {
1911
                return SPEC_FAIL_BINARY_OP_MULTIPLY_DIFFERENT_TYPES;
1912
            }
1913
            return SPEC_FAIL_BINARY_OP_MULTIPLY_OTHER;
1914
        case NB_OR:
1915
        case NB_INPLACE_OR:
1916
            if (!Py_IS_TYPE(lhs, Py_TYPE(rhs))) {
1917
                return SPEC_FAIL_BINARY_OP_OR_DIFFERENT_TYPES;
1918
            }
1919
            if (PyLong_CheckExact(lhs)) {
1920
                return SPEC_FAIL_BINARY_OP_OR_INT;
1921
            }
1922
            return SPEC_FAIL_BINARY_OP_OR;
1923
        case NB_POWER:
1924
        case NB_INPLACE_POWER:
1925
            return SPEC_FAIL_BINARY_OP_POWER;
1926
        case NB_REMAINDER:
1927
        case NB_INPLACE_REMAINDER:
1928
            return SPEC_FAIL_BINARY_OP_REMAINDER;
1929
        case NB_RSHIFT:
1930
        case NB_INPLACE_RSHIFT:
1931
            return SPEC_FAIL_BINARY_OP_RSHIFT;
1932
        case NB_SUBTRACT:
1933
        case NB_INPLACE_SUBTRACT:
1934
            if (!Py_IS_TYPE(lhs, Py_TYPE(rhs))) {
1935
                return SPEC_FAIL_BINARY_OP_SUBTRACT_DIFFERENT_TYPES;
1936
            }
1937
            return SPEC_FAIL_BINARY_OP_SUBTRACT_OTHER;
1938
        case NB_TRUE_DIVIDE:
1939
        case NB_INPLACE_TRUE_DIVIDE:
1940
            if (!Py_IS_TYPE(lhs, Py_TYPE(rhs))) {
1941
                return SPEC_FAIL_BINARY_OP_TRUE_DIVIDE_DIFFERENT_TYPES;
1942
            }
1943
            if (PyFloat_CheckExact(lhs)) {
1944
                return SPEC_FAIL_BINARY_OP_TRUE_DIVIDE_FLOAT;
1945
            }
1946
            return SPEC_FAIL_BINARY_OP_TRUE_DIVIDE_OTHER;
1947
        case NB_XOR:
1948
        case NB_INPLACE_XOR:
1949
            if (!Py_IS_TYPE(lhs, Py_TYPE(rhs))) {
1950
                return SPEC_FAIL_BINARY_OP_XOR_DIFFERENT_TYPES;
1951
            }
1952
            if (PyLong_CheckExact(lhs)) {
1953
                return SPEC_FAIL_BINARY_OP_XOR_INT;
1954
            }
1955
            return SPEC_FAIL_BINARY_OP_XOR;
1956
        case NB_SUBSCR:
1957
            if (PyList_CheckExact(lhs)) {
1958
                if (PyLong_CheckExact(rhs) && !_PyLong_IsNonNegativeCompact((PyLongObject *)rhs)) {
1959
                    return SPEC_FAIL_OUT_OF_RANGE;
1960
                }
1961
                if (PySlice_Check(rhs)) {
1962
                    return SPEC_FAIL_BINARY_OP_SUBSCR_LIST_SLICE;
1963
                }
1964
            }
1965
            if (PyTuple_CheckExact(lhs)) {
1966
                if (PyLong_CheckExact(rhs) && !_PyLong_IsNonNegativeCompact((PyLongObject *)rhs)) {
1967
                    return SPEC_FAIL_OUT_OF_RANGE;
1968
                }
1969
                if (PySlice_Check(rhs)) {
1970
                    return SPEC_FAIL_BINARY_OP_SUBSCR_TUPLE_SLICE;
1971
                }
1972
            }
1973
            if (PyUnicode_CheckExact(lhs)) {
1974
                if (PyLong_CheckExact(rhs) && !_PyLong_IsNonNegativeCompact((PyLongObject *)rhs)) {
1975
                    return SPEC_FAIL_OUT_OF_RANGE;
1976
                }
1977
                if (PySlice_Check(rhs)) {
1978
                    return SPEC_FAIL_BINARY_OP_SUBSCR_STRING_SLICE;
1979
                }
1980
            }
1981
            unsigned int tp_version;
1982
            PyTypeObject *container_type = Py_TYPE(lhs);
1983
            PyObject *descriptor = _PyType_LookupRefAndVersion(container_type, &_Py_ID(__getitem__), &tp_version);
1984
            if (descriptor && Py_TYPE(descriptor) == &PyFunction_Type) {
1985
                if (!(container_type->tp_flags & Py_TPFLAGS_HEAPTYPE)) {
1986
                    Py_DECREF(descriptor);
1987
                    return SPEC_FAIL_BINARY_OP_SUBSCR_NOT_HEAP_TYPE;
1988
                }
1989
                PyFunctionObject *func = (PyFunctionObject *)descriptor;
1990
                PyCodeObject *fcode = (PyCodeObject *)func->func_code;
1991
                int kind = function_kind(fcode);
1992
                if (kind != SIMPLE_FUNCTION) {
1993
                    Py_DECREF(descriptor);
1994
                    return kind;
1995
                }
1996
                if (fcode->co_argcount != 2) {
1997
                    Py_DECREF(descriptor);
1998
                    return SPEC_FAIL_WRONG_NUMBER_ARGUMENTS;
1999
                }
2000
2001
                if (_PyInterpreterState_GET()->eval_frame) {
2002
                    /* Don't specialize if PEP 523 is active */
2003
                    Py_DECREF(descriptor);
2004
                    return SPEC_FAIL_OTHER;
2005
                }
2006
            }
2007
            Py_XDECREF(descriptor);
2008
2009
            if (PyObject_TypeCheck(lhs, &PyDictProxy_Type)) {
2010
                return SPEC_FAIL_BINARY_OP_SUBSCR_MAPPINGPROXY;
2011
            }
2012
2013
            if (PyObject_TypeCheck(lhs, &PyBytes_Type)) {
2014
                return SPEC_FAIL_BINARY_OP_SUBSCR_BYTES;
2015
            }
2016
2017
            if (PyObject_TypeCheck(lhs, &PyRange_Type)) {
2018
                return SPEC_FAIL_BINARY_OP_SUBSCR_RANGE;
2019
            }
2020
2021
            if (strcmp(container_type->tp_name, "array.array") == 0) {
2022
                return SPEC_FAIL_BINARY_OP_SUBSCR_ARRAY;
2023
            }
2024
2025
            if (strcmp(container_type->tp_name, "re.Match") == 0) {
2026
                return SPEC_FAIL_BINARY_OP_SUBSCR_RE_MATCH;
2027
            }
2028
2029
            if (strcmp(container_type->tp_name, "collections.deque") == 0) {
2030
                return SPEC_FAIL_BINARY_OP_SUBSCR_DEQUE;
2031
            }
2032
2033
            if (strcmp(_PyType_Name(container_type), "EnumDict") == 0) {
2034
                return SPEC_FAIL_BINARY_OP_SUBSCR_ENUMDICT;
2035
            }
2036
2037
            if (strcmp(container_type->tp_name, "StackSummary") == 0) {
2038
                return SPEC_FAIL_BINARY_OP_SUBSCR_STACKSUMMARY;
2039
            }
2040
2041
            if (strcmp(container_type->tp_name, "collections.defaultdict") == 0) {
2042
                return SPEC_FAIL_BINARY_OP_SUBSCR_DEFAULTDICT;
2043
            }
2044
2045
            if (strcmp(container_type->tp_name, "Counter") == 0) {
2046
                return SPEC_FAIL_BINARY_OP_SUBSCR_COUNTER;
2047
            }
2048
2049
            if (strcmp(container_type->tp_name, "collections.OrderedDict") == 0) {
2050
                return SPEC_FAIL_BINARY_OP_SUBSCR_ORDEREDDICT;
2051
            }
2052
2053
            if (strcmp(container_type->tp_name, "time.struct_time") == 0) {
2054
                return SPEC_FAIL_BINARY_OP_SUBSCR_STRUCTTIME;
2055
            }
2056
2057
            if (PySlice_Check(rhs)) {
2058
                return SPEC_FAIL_BINARY_OP_SUBSCR_OTHER_SLICE;
2059
            }
2060
            return SPEC_FAIL_BINARY_OP_SUBSCR;
2061
    }
2062
    Py_UNREACHABLE();
2063
}
2064
#endif
2065
2066
/** Binary Op Specialization Extensions */
2067
2068
/* long-long */
2069
2070
static inline int
2071
is_compactlong(PyObject *v)
2072
157M
{
2073
157M
    return PyLong_CheckExact(v) &&
2074
157M
           _PyLong_IsCompact((PyLongObject *)v);
2075
157M
}
2076
2077
static int
2078
compactlongs_guard(PyObject *lhs, PyObject *rhs)
2079
78.7M
{
2080
78.7M
    return (is_compactlong(lhs) && is_compactlong(rhs));
2081
78.7M
}
2082
2083
#define BITWISE_LONGS_ACTION(NAME, OP) \
2084
    static PyObject * \
2085
    (NAME)(PyObject *lhs, PyObject *rhs) \
2086
78.7M
    { \
2087
78.7M
        Py_ssize_t rhs_val = _PyLong_CompactValue((PyLongObject *)rhs); \
2088
78.7M
        Py_ssize_t lhs_val = _PyLong_CompactValue((PyLongObject *)lhs); \
2089
78.7M
        return PyLong_FromSsize_t(lhs_val OP rhs_val); \
2090
78.7M
    }
specialize.c:compactlongs_or
Line
Count
Source
2086
1.24M
    { \
2087
1.24M
        Py_ssize_t rhs_val = _PyLong_CompactValue((PyLongObject *)rhs); \
2088
1.24M
        Py_ssize_t lhs_val = _PyLong_CompactValue((PyLongObject *)lhs); \
2089
1.24M
        return PyLong_FromSsize_t(lhs_val OP rhs_val); \
2090
1.24M
    }
specialize.c:compactlongs_and
Line
Count
Source
2086
77.4M
    { \
2087
77.4M
        Py_ssize_t rhs_val = _PyLong_CompactValue((PyLongObject *)rhs); \
2088
77.4M
        Py_ssize_t lhs_val = _PyLong_CompactValue((PyLongObject *)lhs); \
2089
77.4M
        return PyLong_FromSsize_t(lhs_val OP rhs_val); \
2090
77.4M
    }
specialize.c:compactlongs_xor
Line
Count
Source
2086
56
    { \
2087
56
        Py_ssize_t rhs_val = _PyLong_CompactValue((PyLongObject *)rhs); \
2088
56
        Py_ssize_t lhs_val = _PyLong_CompactValue((PyLongObject *)lhs); \
2089
56
        return PyLong_FromSsize_t(lhs_val OP rhs_val); \
2090
56
    }
2091
BITWISE_LONGS_ACTION(compactlongs_or, |)
2092
BITWISE_LONGS_ACTION(compactlongs_and, &)
2093
BITWISE_LONGS_ACTION(compactlongs_xor, ^)
2094
#undef BITWISE_LONGS_ACTION
2095
2096
/* float-long */
2097
2098
static inline int
2099
float_compactlong_guard(PyObject *lhs, PyObject *rhs)
2100
5.91M
{
2101
5.91M
    return (
2102
5.91M
        PyFloat_CheckExact(lhs) &&
2103
5.90M
        !isnan(PyFloat_AS_DOUBLE(lhs)) &&
2104
5.91M
        PyLong_CheckExact(rhs) &&
2105
5.90M
        _PyLong_IsCompact((PyLongObject *)rhs)
2106
5.91M
    );
2107
5.91M
}
2108
2109
static inline int
2110
nonzero_float_compactlong_guard(PyObject *lhs, PyObject *rhs)
2111
2.95M
{
2112
2.95M
    return (
2113
2.95M
        float_compactlong_guard(lhs, rhs) && !_PyLong_IsZero((PyLongObject*)rhs)
2114
2.95M
    );
2115
2.95M
}
2116
2117
#define FLOAT_LONG_ACTION(NAME, OP) \
2118
    static PyObject * \
2119
    (NAME)(PyObject *lhs, PyObject *rhs) \
2120
5.90M
    { \
2121
5.90M
        double lhs_val = PyFloat_AS_DOUBLE(lhs); \
2122
5.90M
        Py_ssize_t rhs_val = _PyLong_CompactValue((PyLongObject *)rhs); \
2123
5.90M
        return PyFloat_FromDouble(lhs_val OP rhs_val); \
2124
5.90M
    }
Unexecuted instantiation: specialize.c:float_compactlong_add
specialize.c:float_compactlong_subtract
Line
Count
Source
2120
24
    { \
2121
24
        double lhs_val = PyFloat_AS_DOUBLE(lhs); \
2122
24
        Py_ssize_t rhs_val = _PyLong_CompactValue((PyLongObject *)rhs); \
2123
24
        return PyFloat_FromDouble(lhs_val OP rhs_val); \
2124
24
    }
specialize.c:float_compactlong_true_div
Line
Count
Source
2120
2.95M
    { \
2121
2.95M
        double lhs_val = PyFloat_AS_DOUBLE(lhs); \
2122
2.95M
        Py_ssize_t rhs_val = _PyLong_CompactValue((PyLongObject *)rhs); \
2123
2.95M
        return PyFloat_FromDouble(lhs_val OP rhs_val); \
2124
2.95M
    }
specialize.c:float_compactlong_multiply
Line
Count
Source
2120
2.95M
    { \
2121
2.95M
        double lhs_val = PyFloat_AS_DOUBLE(lhs); \
2122
2.95M
        Py_ssize_t rhs_val = _PyLong_CompactValue((PyLongObject *)rhs); \
2123
2.95M
        return PyFloat_FromDouble(lhs_val OP rhs_val); \
2124
2.95M
    }
2125
FLOAT_LONG_ACTION(float_compactlong_add, +)
2126
FLOAT_LONG_ACTION(float_compactlong_subtract, -)
2127
FLOAT_LONG_ACTION(float_compactlong_multiply, *)
2128
FLOAT_LONG_ACTION(float_compactlong_true_div, /)
2129
#undef FLOAT_LONG_ACTION
2130
2131
/*  long-float */
2132
2133
static inline int
2134
compactlong_float_guard(PyObject *lhs, PyObject *rhs)
2135
7.08k
{
2136
7.08k
    return (
2137
7.08k
        PyLong_CheckExact(lhs) &&
2138
5.81k
        _PyLong_IsCompact((PyLongObject *)lhs) &&
2139
7.08k
        PyFloat_CheckExact(rhs) &&
2140
20
        !isnan(PyFloat_AS_DOUBLE(rhs))
2141
7.08k
    );
2142
7.08k
}
2143
2144
static inline int
2145
nonzero_compactlong_float_guard(PyObject *lhs, PyObject *rhs)
2146
19
{
2147
19
    return (
2148
19
        compactlong_float_guard(lhs, rhs) && PyFloat_AS_DOUBLE(rhs) != 0.0
2149
19
    );
2150
19
}
2151
2152
#define LONG_FLOAT_ACTION(NAME, OP) \
2153
    static PyObject * \
2154
    (NAME)(PyObject *lhs, PyObject *rhs) \
2155
14
    { \
2156
14
        double rhs_val = PyFloat_AS_DOUBLE(rhs); \
2157
14
        Py_ssize_t lhs_val = _PyLong_CompactValue((PyLongObject *)lhs); \
2158
14
        return PyFloat_FromDouble(lhs_val OP rhs_val); \
2159
14
    }
specialize.c:compactlong_float_add
Line
Count
Source
2155
2
    { \
2156
2
        double rhs_val = PyFloat_AS_DOUBLE(rhs); \
2157
2
        Py_ssize_t lhs_val = _PyLong_CompactValue((PyLongObject *)lhs); \
2158
2
        return PyFloat_FromDouble(lhs_val OP rhs_val); \
2159
2
    }
specialize.c:compactlong_float_subtract
Line
Count
Source
2155
12
    { \
2156
12
        double rhs_val = PyFloat_AS_DOUBLE(rhs); \
2157
12
        Py_ssize_t lhs_val = _PyLong_CompactValue((PyLongObject *)lhs); \
2158
12
        return PyFloat_FromDouble(lhs_val OP rhs_val); \
2159
12
    }
Unexecuted instantiation: specialize.c:compactlong_float_true_div
Unexecuted instantiation: specialize.c:compactlong_float_multiply
2160
LONG_FLOAT_ACTION(compactlong_float_add, +)
2161
LONG_FLOAT_ACTION(compactlong_float_subtract, -)
2162
LONG_FLOAT_ACTION(compactlong_float_multiply, *)
2163
LONG_FLOAT_ACTION(compactlong_float_true_div, /)
2164
#undef LONG_FLOAT_ACTION
2165
2166
static _PyBinaryOpSpecializationDescr binaryop_extend_descrs[] = {
2167
    /* long-long arithmetic */
2168
    {NB_OR, compactlongs_guard, compactlongs_or},
2169
    {NB_AND, compactlongs_guard, compactlongs_and},
2170
    {NB_XOR, compactlongs_guard, compactlongs_xor},
2171
    {NB_INPLACE_OR, compactlongs_guard, compactlongs_or},
2172
    {NB_INPLACE_AND, compactlongs_guard, compactlongs_and},
2173
    {NB_INPLACE_XOR, compactlongs_guard, compactlongs_xor},
2174
2175
    /* float-long arithemetic */
2176
    {NB_ADD, float_compactlong_guard, float_compactlong_add},
2177
    {NB_SUBTRACT, float_compactlong_guard, float_compactlong_subtract},
2178
    {NB_TRUE_DIVIDE, nonzero_float_compactlong_guard, float_compactlong_true_div},
2179
    {NB_MULTIPLY, float_compactlong_guard, float_compactlong_multiply},
2180
2181
    /* float-float arithmetic */
2182
    {NB_ADD, compactlong_float_guard, compactlong_float_add},
2183
    {NB_SUBTRACT, compactlong_float_guard, compactlong_float_subtract},
2184
    {NB_TRUE_DIVIDE, nonzero_compactlong_float_guard, compactlong_float_true_div},
2185
    {NB_MULTIPLY, compactlong_float_guard, compactlong_float_multiply},
2186
};
2187
2188
static int
2189
binary_op_extended_specialization(PyObject *lhs, PyObject *rhs, int oparg,
2190
                                  _PyBinaryOpSpecializationDescr **descr)
2191
44.9k
{
2192
44.9k
    size_t n = sizeof(binaryop_extend_descrs)/sizeof(_PyBinaryOpSpecializationDescr);
2193
660k
    for (size_t i = 0; i < n; i++) {
2194
616k
        _PyBinaryOpSpecializationDescr *d = &binaryop_extend_descrs[i];
2195
616k
        if (d->oparg == oparg && d->guard(lhs, rhs)) {
2196
1.09k
            *descr = d;
2197
1.09k
            return 1;
2198
1.09k
        }
2199
616k
    }
2200
43.8k
    return 0;
2201
44.9k
}
2202
2203
Py_NO_INLINE void
2204
_Py_Specialize_BinaryOp(_PyStackRef lhs_st, _PyStackRef rhs_st, _Py_CODEUNIT *instr,
2205
                        int oparg, _PyStackRef *locals)
2206
1.39M
{
2207
1.39M
    PyObject *lhs = PyStackRef_AsPyObjectBorrow(lhs_st);
2208
1.39M
    PyObject *rhs = PyStackRef_AsPyObjectBorrow(rhs_st);
2209
1.39M
    assert(ENABLE_SPECIALIZATION);
2210
1.39M
    assert(_PyOpcode_Caches[BINARY_OP] == INLINE_CACHE_ENTRIES_BINARY_OP);
2211
2212
1.39M
    _PyBinaryOpCache *cache = (_PyBinaryOpCache *)(instr + 1);
2213
1.39M
    if (instr->op.code == BINARY_OP_EXTEND) {
2214
1
        write_ptr(cache->external_cache, NULL);
2215
1
    }
2216
2217
1.39M
    switch (oparg) {
2218
8.58k
        case NB_ADD:
2219
23.8k
        case NB_INPLACE_ADD:
2220
23.8k
            if (!Py_IS_TYPE(lhs, Py_TYPE(rhs))) {
2221
108
                break;
2222
108
            }
2223
23.7k
            if (PyUnicode_CheckExact(lhs)) {
2224
642
                _Py_CODEUNIT next = instr[INLINE_CACHE_ENTRIES_BINARY_OP + 1];
2225
642
                bool to_store = (next.op.code == STORE_FAST);
2226
642
                if (to_store && PyStackRef_AsPyObjectBorrow(locals[next.op.arg]) == lhs) {
2227
140
                    specialize(instr, BINARY_OP_INPLACE_ADD_UNICODE);
2228
140
                    return;
2229
140
                }
2230
502
                specialize(instr, BINARY_OP_ADD_UNICODE);
2231
502
                return;
2232
642
            }
2233
23.0k
            if (_PyLong_CheckExactAndCompact(lhs) && _PyLong_CheckExactAndCompact(rhs)) {
2234
4.62k
                specialize(instr, BINARY_OP_ADD_INT);
2235
4.62k
                return;
2236
4.62k
            }
2237
18.4k
            if (PyFloat_CheckExact(lhs)) {
2238
2
                specialize(instr, BINARY_OP_ADD_FLOAT);
2239
2
                return;
2240
2
            }
2241
18.4k
            break;
2242
18.4k
        case NB_MULTIPLY:
2243
1.13k
        case NB_INPLACE_MULTIPLY:
2244
1.13k
            if (!Py_IS_TYPE(lhs, Py_TYPE(rhs))) {
2245
342
                break;
2246
342
            }
2247
795
            if (_PyLong_CheckExactAndCompact(lhs) && _PyLong_CheckExactAndCompact(rhs)) {
2248
270
                specialize(instr, BINARY_OP_MULTIPLY_INT);
2249
270
                return;
2250
270
            }
2251
525
            if (PyFloat_CheckExact(lhs)) {
2252
8
                specialize(instr, BINARY_OP_MULTIPLY_FLOAT);
2253
8
                return;
2254
8
            }
2255
517
            break;
2256
799
        case NB_SUBTRACT:
2257
855
        case NB_INPLACE_SUBTRACT:
2258
855
            if (!Py_IS_TYPE(lhs, Py_TYPE(rhs))) {
2259
8
                break;
2260
8
            }
2261
847
            if (_PyLong_CheckExactAndCompact(lhs) && _PyLong_CheckExactAndCompact(rhs)) {
2262
668
                specialize(instr, BINARY_OP_SUBTRACT_INT);
2263
668
                return;
2264
668
            }
2265
179
            if (PyFloat_CheckExact(lhs)) {
2266
10
                specialize(instr, BINARY_OP_SUBTRACT_FLOAT);
2267
10
                return;
2268
10
            }
2269
169
            break;
2270
1.35M
        case NB_SUBSCR:
2271
1.35M
            if (PyLong_CheckExact(rhs) && _PyLong_IsNonNegativeCompact((PyLongObject *)rhs)) {
2272
1.34M
                if (PyList_CheckExact(lhs)) {
2273
55.7k
                    specialize(instr, BINARY_OP_SUBSCR_LIST_INT);
2274
55.7k
                    return;
2275
55.7k
                }
2276
1.28M
                if (PyTuple_CheckExact(lhs)) {
2277
956
                    specialize(instr, BINARY_OP_SUBSCR_TUPLE_INT);
2278
956
                    return;
2279
956
                }
2280
1.28M
                if (PyUnicode_CheckExact(lhs) && _PyLong_IsNonNegativeCompact((PyLongObject*)rhs)) {
2281
1.28M
                    if (PyUnicode_IS_COMPACT_ASCII(lhs)) {
2282
1.50k
                        specialize(instr, BINARY_OP_SUBSCR_STR_INT);
2283
1.50k
                        return;
2284
1.28M
                    } else {
2285
1.28M
                        specialize(instr, BINARY_OP_SUBSCR_USTR_INT);
2286
1.28M
                        return;
2287
1.28M
                    }
2288
1.28M
                }
2289
1.28M
            }
2290
14.6k
            if (PyAnyDict_CheckExact(lhs)) {
2291
720
                specialize(instr, BINARY_OP_SUBSCR_DICT);
2292
720
                return;
2293
720
            }
2294
13.8k
            if (PyList_CheckExact(lhs) && PySlice_Check(rhs)) {
2295
70
                specialize(instr, BINARY_OP_SUBSCR_LIST_SLICE);
2296
70
                return;
2297
70
            }
2298
13.8k
            unsigned int tp_version;
2299
13.8k
            PyTypeObject *container_type = Py_TYPE(lhs);
2300
13.8k
            PyObject *descriptor = _PyType_LookupRefAndVersion(container_type, &_Py_ID(__getitem__), &tp_version);
2301
13.8k
            if (descriptor && Py_TYPE(descriptor) == &PyFunction_Type &&
2302
218
                container_type->tp_flags & Py_TPFLAGS_HEAPTYPE)
2303
218
            {
2304
218
                PyFunctionObject *func = (PyFunctionObject *)descriptor;
2305
218
                PyCodeObject *fcode = (PyCodeObject *)func->func_code;
2306
218
                int kind = function_kind(fcode);
2307
218
                PyHeapTypeObject *ht = (PyHeapTypeObject *)container_type;
2308
218
                if (kind == SIMPLE_FUNCTION &&
2309
218
                    fcode->co_argcount == 2 &&
2310
218
                    !_PyInterpreterState_GET()->eval_frame && /* Don't specialize if PEP 523 is active */
2311
218
                    _PyType_CacheGetItemForSpecialization(ht, descriptor, (uint32_t)tp_version))
2312
218
                {
2313
218
                    specialize(instr, BINARY_OP_SUBSCR_GETITEM);
2314
218
                    Py_DECREF(descriptor);
2315
218
                    return;
2316
218
                }
2317
218
            }
2318
13.6k
            Py_XDECREF(descriptor);
2319
13.6k
            break;
2320
1.39M
    }
2321
2322
44.9k
    _PyBinaryOpSpecializationDescr *descr;
2323
44.9k
    if (binary_op_extended_specialization(lhs, rhs, oparg, &descr)) {
2324
1.09k
        specialize(instr, BINARY_OP_EXTEND);
2325
1.09k
        write_ptr(cache->external_cache, (void*)descr);
2326
1.09k
        return;
2327
1.09k
    }
2328
2329
43.8k
    SPECIALIZATION_FAIL(BINARY_OP, binary_op_fail_kind(oparg, lhs, rhs));
2330
43.8k
    unspecialize(instr);
2331
43.8k
    return;
2332
44.9k
}
2333
2334
2335
#ifdef Py_STATS
2336
static int
2337
compare_op_fail_kind(PyObject *lhs, PyObject *rhs)
2338
{
2339
    if (Py_TYPE(lhs) != Py_TYPE(rhs)) {
2340
        if (PyFloat_CheckExact(lhs) && PyLong_CheckExact(rhs)) {
2341
            return SPEC_FAIL_COMPARE_OP_FLOAT_LONG;
2342
        }
2343
        if (PyLong_CheckExact(lhs) && PyFloat_CheckExact(rhs)) {
2344
            return SPEC_FAIL_COMPARE_OP_LONG_FLOAT;
2345
        }
2346
        return SPEC_FAIL_COMPARE_OP_DIFFERENT_TYPES;
2347
    }
2348
    if (PyBytes_CheckExact(lhs)) {
2349
        return SPEC_FAIL_COMPARE_OP_BYTES;
2350
    }
2351
    if (PyTuple_CheckExact(lhs)) {
2352
        return SPEC_FAIL_COMPARE_OP_TUPLE;
2353
    }
2354
    if (PyList_CheckExact(lhs)) {
2355
        return SPEC_FAIL_COMPARE_OP_LIST;
2356
    }
2357
    if (PySet_CheckExact(lhs) || PyFrozenSet_CheckExact(lhs)) {
2358
        return SPEC_FAIL_COMPARE_OP_SET;
2359
    }
2360
    if (PyBool_Check(lhs)) {
2361
        return SPEC_FAIL_COMPARE_OP_BOOL;
2362
    }
2363
    if (Py_TYPE(lhs)->tp_richcompare == PyBaseObject_Type.tp_richcompare) {
2364
        return SPEC_FAIL_COMPARE_OP_BASEOBJECT;
2365
    }
2366
    return SPEC_FAIL_OTHER;
2367
}
2368
#endif   // Py_STATS
2369
2370
Py_NO_INLINE void
2371
_Py_Specialize_CompareOp(_PyStackRef lhs_st, _PyStackRef rhs_st, _Py_CODEUNIT *instr,
2372
                         int oparg)
2373
15.4k
{
2374
15.4k
    PyObject *lhs = PyStackRef_AsPyObjectBorrow(lhs_st);
2375
15.4k
    PyObject *rhs = PyStackRef_AsPyObjectBorrow(rhs_st);
2376
15.4k
    uint8_t specialized_op;
2377
2378
15.4k
    assert(ENABLE_SPECIALIZATION);
2379
15.4k
    assert(_PyOpcode_Caches[COMPARE_OP] == INLINE_CACHE_ENTRIES_COMPARE_OP);
2380
    // All of these specializations compute boolean values, so they're all valid
2381
    // regardless of the fifth-lowest oparg bit.
2382
15.4k
    if (Py_TYPE(lhs) != Py_TYPE(rhs)) {
2383
2.86k
        SPECIALIZATION_FAIL(COMPARE_OP, compare_op_fail_kind(lhs, rhs));
2384
2.86k
        goto failure;
2385
2.86k
    }
2386
12.5k
    if (PyFloat_CheckExact(lhs)) {
2387
49
        specialized_op = COMPARE_OP_FLOAT;
2388
49
        goto success;
2389
49
    }
2390
12.4k
    if (PyLong_CheckExact(lhs)) {
2391
5.91k
        if (_PyLong_IsCompact((PyLongObject *)lhs) && _PyLong_IsCompact((PyLongObject *)rhs)) {
2392
3.49k
            specialized_op = COMPARE_OP_INT;
2393
3.49k
            goto success;
2394
3.49k
        }
2395
2.42k
        else {
2396
2.42k
            SPECIALIZATION_FAIL(COMPARE_OP, SPEC_FAIL_COMPARE_OP_BIG_INT);
2397
2.42k
            goto failure;
2398
2.42k
        }
2399
5.91k
    }
2400
6.57k
    if (PyUnicode_CheckExact(lhs)) {
2401
4.26k
        int cmp = oparg >> 5;
2402
4.26k
        if (cmp != Py_EQ && cmp != Py_NE) {
2403
1.90k
            SPECIALIZATION_FAIL(COMPARE_OP, SPEC_FAIL_COMPARE_OP_STRING);
2404
1.90k
            goto failure;
2405
1.90k
        }
2406
2.35k
        else {
2407
2.35k
            specialized_op = COMPARE_OP_STR;
2408
2.35k
            goto success;
2409
2.35k
        }
2410
4.26k
    }
2411
2.31k
    SPECIALIZATION_FAIL(COMPARE_OP, compare_op_fail_kind(lhs, rhs));
2412
9.50k
failure:
2413
9.50k
    unspecialize(instr);
2414
9.50k
    return;
2415
5.90k
success:
2416
5.90k
    specialize(instr, specialized_op);
2417
5.90k
}
2418
2419
#ifdef Py_STATS
2420
static int
2421
unpack_sequence_fail_kind(PyObject *seq)
2422
{
2423
    if (PySequence_Check(seq)) {
2424
        return SPEC_FAIL_UNPACK_SEQUENCE_SEQUENCE;
2425
    }
2426
    if (PyIter_Check(seq)) {
2427
        return SPEC_FAIL_UNPACK_SEQUENCE_ITERATOR;
2428
    }
2429
    return SPEC_FAIL_OTHER;
2430
}
2431
#endif   // Py_STATS
2432
2433
Py_NO_INLINE void
2434
_Py_Specialize_UnpackSequence(_PyStackRef seq_st, _Py_CODEUNIT *instr, int oparg)
2435
5.05k
{
2436
5.05k
    PyObject *seq = PyStackRef_AsPyObjectBorrow(seq_st);
2437
2438
5.05k
    assert(ENABLE_SPECIALIZATION);
2439
5.05k
    assert(_PyOpcode_Caches[UNPACK_SEQUENCE] ==
2440
5.05k
           INLINE_CACHE_ENTRIES_UNPACK_SEQUENCE);
2441
5.05k
    if (PyTuple_CheckExact(seq)) {
2442
1.92k
        if (PyTuple_GET_SIZE(seq) != oparg) {
2443
0
            SPECIALIZATION_FAIL(UNPACK_SEQUENCE, SPEC_FAIL_EXPECTED_ERROR);
2444
0
            unspecialize(instr);
2445
0
            return;
2446
0
        }
2447
1.92k
        if (PyTuple_GET_SIZE(seq) == 2) {
2448
1.24k
            specialize(instr, UNPACK_SEQUENCE_TWO_TUPLE);
2449
1.24k
            return;
2450
1.24k
        }
2451
675
        specialize(instr, UNPACK_SEQUENCE_TUPLE);
2452
675
        return;
2453
1.92k
    }
2454
3.13k
    if (PyList_CheckExact(seq)) {
2455
2.75k
        if (PyList_GET_SIZE(seq) != oparg) {
2456
1.88k
            SPECIALIZATION_FAIL(UNPACK_SEQUENCE, SPEC_FAIL_EXPECTED_ERROR);
2457
1.88k
            unspecialize(instr);
2458
1.88k
            return;
2459
1.88k
        }
2460
870
        specialize(instr, UNPACK_SEQUENCE_LIST);
2461
870
        return;
2462
2.75k
    }
2463
385
    SPECIALIZATION_FAIL(UNPACK_SEQUENCE, unpack_sequence_fail_kind(seq));
2464
385
    unspecialize(instr);
2465
385
}
2466
2467
#ifdef Py_STATS
2468
int
2469
 _PySpecialization_ClassifyIterator(PyObject *iter)
2470
{
2471
    if (PyGen_CheckExact(iter)) {
2472
        return SPEC_FAIL_ITER_GENERATOR;
2473
    }
2474
    if (PyCoro_CheckExact(iter)) {
2475
        return SPEC_FAIL_ITER_COROUTINE;
2476
    }
2477
    if (PyAsyncGen_CheckExact(iter)) {
2478
        return SPEC_FAIL_ITER_ASYNC_GENERATOR;
2479
    }
2480
    if (PyAsyncGenASend_CheckExact(iter)) {
2481
        return SPEC_FAIL_ITER_ASYNC_GENERATOR_SEND;
2482
    }
2483
    PyTypeObject *t = Py_TYPE(iter);
2484
    if (t == &PyListIter_Type) {
2485
        return SPEC_FAIL_ITER_LIST;
2486
    }
2487
    if (t == &PyTupleIter_Type) {
2488
        return SPEC_FAIL_ITER_TUPLE;
2489
    }
2490
    if (t == &PyDictIterKey_Type) {
2491
        return SPEC_FAIL_ITER_DICT_KEYS;
2492
    }
2493
    if (t == &PyDictIterValue_Type) {
2494
        return SPEC_FAIL_ITER_DICT_VALUES;
2495
    }
2496
    if (t == &PyDictIterItem_Type) {
2497
        return SPEC_FAIL_ITER_DICT_ITEMS;
2498
    }
2499
    if (t == &PySetIter_Type) {
2500
        return SPEC_FAIL_ITER_SET;
2501
    }
2502
    if (t == &PyUnicodeIter_Type) {
2503
        return SPEC_FAIL_ITER_STRING;
2504
    }
2505
    if (t == &PyBytesIter_Type) {
2506
        return SPEC_FAIL_ITER_BYTES;
2507
    }
2508
    if (t == &PyRangeIter_Type) {
2509
        return SPEC_FAIL_ITER_RANGE;
2510
    }
2511
    if (t == &PyEnum_Type) {
2512
        return SPEC_FAIL_ITER_ENUMERATE;
2513
    }
2514
    if (t == &PyMap_Type) {
2515
        return SPEC_FAIL_ITER_MAP;
2516
    }
2517
    if (t == &PyZip_Type) {
2518
        return SPEC_FAIL_ITER_ZIP;
2519
    }
2520
    if (t == &PySeqIter_Type) {
2521
        return SPEC_FAIL_ITER_SEQ_ITER;
2522
    }
2523
    if (t == &PyListRevIter_Type) {
2524
        return SPEC_FAIL_ITER_REVERSED_LIST;
2525
    }
2526
    if (t == &_PyUnicodeASCIIIter_Type) {
2527
        return SPEC_FAIL_ITER_ASCII_STRING;
2528
    }
2529
    const char *name = t->tp_name;
2530
    if (strncmp(name, "itertools", 9) == 0) {
2531
        return SPEC_FAIL_ITER_ITERTOOLS;
2532
    }
2533
    if (strncmp(name, "callable_iterator", 17) == 0) {
2534
        return SPEC_FAIL_ITER_CALLABLE;
2535
    }
2536
    return SPEC_FAIL_OTHER;
2537
}
2538
#endif   // Py_STATS
2539
2540
Py_NO_INLINE void
2541
_Py_Specialize_ForIter(_PyStackRef iter, _PyStackRef null_or_index, _Py_CODEUNIT *instr, int oparg)
2542
82.8k
{
2543
82.8k
    assert(ENABLE_SPECIALIZATION);
2544
82.8k
    assert(_PyOpcode_Caches[FOR_ITER] == INLINE_CACHE_ENTRIES_FOR_ITER);
2545
82.8k
    PyObject *iter_o = PyStackRef_AsPyObjectBorrow(iter);
2546
82.8k
    PyTypeObject *tp = Py_TYPE(iter_o);
2547
2548
82.8k
    if (PyStackRef_IsNull(null_or_index)) {
2549
76.3k
        if (tp == &PyRangeIter_Type) {
2550
#ifdef Py_GIL_DISABLED
2551
            // Only specialize for uniquely referenced iterators, so that we know
2552
            // they're only referenced by this one thread. This is more limiting
2553
            // than we need (even `it = iter(mylist); for item in it:` won't get
2554
            // specialized) but we don't have a way to check whether we're the only
2555
            // _thread_ who has access to the object.
2556
            if (!_PyObject_IsUniquelyReferenced(iter_o)) {
2557
                goto failure;
2558
            }
2559
#endif
2560
189
            specialize(instr, FOR_ITER_RANGE);
2561
189
            return;
2562
189
        }
2563
76.1k
        else if (tp == &PyGen_Type && oparg <= SHRT_MAX) {
2564
489
            assert(instr[oparg + INLINE_CACHE_ENTRIES_FOR_ITER + 1].op.code == END_FOR  ||
2565
489
                instr[oparg + INLINE_CACHE_ENTRIES_FOR_ITER + 1].op.code == INSTRUMENTED_END_FOR
2566
489
            );
2567
            /* Don't specialize if PEP 523 is active */
2568
489
            if (_PyInterpreterState_GET()->eval_frame) {
2569
0
                goto failure;
2570
0
            }
2571
489
            specialize(instr, FOR_ITER_GEN);
2572
489
            return;
2573
489
        }
2574
76.3k
    }
2575
6.50k
    else {
2576
6.50k
        if (tp == &PyList_Type) {
2577
#ifdef Py_GIL_DISABLED
2578
            // Only specialize for lists owned by this thread or shared
2579
            if (!_Py_IsOwnedByCurrentThread(iter_o) && !_PyObject_GC_IS_SHARED(iter_o)) {
2580
                goto failure;
2581
            }
2582
#endif
2583
5.18k
            specialize(instr, FOR_ITER_LIST);
2584
5.18k
            return;
2585
5.18k
        }
2586
1.31k
        else if (tp == &PyTuple_Type) {
2587
1.31k
            specialize(instr, FOR_ITER_TUPLE);
2588
1.31k
            return;
2589
1.31k
        }
2590
6.50k
    }
2591
75.6k
failure:
2592
75.6k
    SPECIALIZATION_FAIL(FOR_ITER,
2593
75.6k
                        _PySpecialization_ClassifyIterator(iter_o));
2594
75.6k
    unspecialize(instr);
2595
75.6k
}
2596
2597
Py_NO_INLINE void
2598
_Py_Specialize_Send(_PyStackRef receiver_st, _Py_CODEUNIT *instr)
2599
3.16k
{
2600
3.16k
    PyObject *receiver = PyStackRef_AsPyObjectBorrow(receiver_st);
2601
2602
3.16k
    assert(ENABLE_SPECIALIZATION);
2603
3.16k
    assert(_PyOpcode_Caches[SEND] == INLINE_CACHE_ENTRIES_SEND);
2604
3.16k
    PyTypeObject *tp = Py_TYPE(receiver);
2605
3.16k
    if (tp == &PyGen_Type || tp == &PyCoro_Type) {
2606
        /* Don't specialize if PEP 523 is active */
2607
791
        if (_PyInterpreterState_GET()->eval_frame) {
2608
0
            SPECIALIZATION_FAIL(SEND, SPEC_FAIL_OTHER);
2609
0
            goto failure;
2610
0
        }
2611
791
        specialize(instr, SEND_GEN);
2612
791
        return;
2613
791
    }
2614
2.36k
    SPECIALIZATION_FAIL(SEND,
2615
2.36k
                        _PySpecialization_ClassifyIterator(receiver));
2616
2.36k
failure:
2617
2.36k
    unspecialize(instr);
2618
2.36k
}
2619
2620
Py_NO_INLINE void
2621
_Py_Specialize_CallFunctionEx(_PyStackRef func_st, _Py_CODEUNIT *instr)
2622
537
{
2623
537
    PyObject *func = PyStackRef_AsPyObjectBorrow(func_st);
2624
2625
537
    assert(ENABLE_SPECIALIZATION);
2626
537
    assert(_PyOpcode_Caches[CALL_FUNCTION_EX] == INLINE_CACHE_ENTRIES_CALL_FUNCTION_EX);
2627
2628
537
    if (Py_TYPE(func) == &PyFunction_Type &&
2629
142
        ((PyFunctionObject *)func)->vectorcall == _PyFunction_Vectorcall) {
2630
142
        if (_PyInterpreterState_GET()->eval_frame) {
2631
0
            goto failure;
2632
0
        }
2633
142
        specialize(instr, CALL_EX_PY);
2634
142
        return;
2635
142
    }
2636
395
    specialize(instr, CALL_EX_NON_PY_GENERAL);
2637
395
    return;
2638
0
failure:
2639
0
    unspecialize(instr);
2640
0
}
2641
2642
#ifdef Py_STATS
2643
static int
2644
to_bool_fail_kind(PyObject *value)
2645
{
2646
    if (PyByteArray_CheckExact(value)) {
2647
        return SPEC_FAIL_TO_BOOL_BYTEARRAY;
2648
    }
2649
    if (PyBytes_CheckExact(value)) {
2650
        return SPEC_FAIL_TO_BOOL_BYTES;
2651
    }
2652
    if (PyDict_CheckExact(value)) {
2653
        return SPEC_FAIL_TO_BOOL_DICT;
2654
    }
2655
    if (PyFloat_CheckExact(value)) {
2656
        return SPEC_FAIL_TO_BOOL_FLOAT;
2657
    }
2658
    if (PyMemoryView_Check(value)) {
2659
        return SPEC_FAIL_TO_BOOL_MEMORY_VIEW;
2660
    }
2661
    if (PyAnySet_CheckExact(value)) {
2662
        return SPEC_FAIL_TO_BOOL_SET;
2663
    }
2664
    if (PyTuple_CheckExact(value)) {
2665
        return SPEC_FAIL_TO_BOOL_TUPLE;
2666
    }
2667
    return SPEC_FAIL_OTHER;
2668
}
2669
#endif  // Py_STATS
2670
2671
static int
2672
check_type_always_true(PyTypeObject *ty)
2673
62.8k
{
2674
62.8k
    PyNumberMethods *nb = ty->tp_as_number;
2675
62.8k
    if (nb && nb->nb_bool) {
2676
47
        return SPEC_FAIL_TO_BOOL_NUMBER;
2677
47
    }
2678
62.7k
    PyMappingMethods *mp = ty->tp_as_mapping;
2679
62.7k
    if (mp && mp->mp_length) {
2680
4.56k
        return SPEC_FAIL_TO_BOOL_MAPPING;
2681
4.56k
    }
2682
58.1k
    PySequenceMethods *sq = ty->tp_as_sequence;
2683
58.1k
    if (sq && sq->sq_length) {
2684
4.15k
      return SPEC_FAIL_TO_BOOL_SEQUENCE;
2685
4.15k
    }
2686
54.0k
    return 0;
2687
58.1k
}
2688
2689
Py_NO_INLINE void
2690
_Py_Specialize_ToBool(_PyStackRef value_o, _Py_CODEUNIT *instr)
2691
206k
{
2692
206k
    assert(ENABLE_SPECIALIZATION);
2693
206k
    assert(_PyOpcode_Caches[TO_BOOL] == INLINE_CACHE_ENTRIES_TO_BOOL);
2694
206k
    _PyToBoolCache *cache = (_PyToBoolCache *)(instr + 1);
2695
206k
    PyObject *value = PyStackRef_AsPyObjectBorrow(value_o);
2696
206k
    uint8_t specialized_op;
2697
206k
    if (PyBool_Check(value)) {
2698
17.9k
        specialized_op = TO_BOOL_BOOL;
2699
17.9k
        goto success;
2700
17.9k
    }
2701
188k
    if (PyLong_CheckExact(value)) {
2702
4.53k
        specialized_op = TO_BOOL_INT;
2703
4.53k
        goto success;
2704
4.53k
    }
2705
183k
    if (PyList_CheckExact(value)) {
2706
514
        specialized_op = TO_BOOL_LIST;
2707
514
        goto success;
2708
514
    }
2709
183k
    if (Py_IsNone(value)) {
2710
82.6k
        specialized_op = TO_BOOL_NONE;
2711
82.6k
        goto success;
2712
82.6k
    }
2713
100k
    if (PyUnicode_CheckExact(value)) {
2714
32.1k
        specialized_op = TO_BOOL_STR;
2715
32.1k
        goto success;
2716
32.1k
    }
2717
68.5k
    if (PyType_HasFeature(Py_TYPE(value), Py_TPFLAGS_HEAPTYPE)) {
2718
62.8k
        unsigned int version = 0;
2719
62.8k
        int err = _PyType_Validate(Py_TYPE(value), check_type_always_true, &version);
2720
62.8k
        if (err < 0) {
2721
0
            SPECIALIZATION_FAIL(TO_BOOL, SPEC_FAIL_OUT_OF_VERSIONS);
2722
0
            goto failure;
2723
0
        }
2724
62.8k
        else if (err > 0) {
2725
8.77k
            SPECIALIZATION_FAIL(TO_BOOL, err);
2726
8.77k
            goto failure;
2727
8.77k
        }
2728
2729
62.8k
        assert(err == 0);
2730
54.0k
        assert(version);
2731
54.0k
        write_u32(cache->version, version);
2732
54.0k
        specialized_op = TO_BOOL_ALWAYS_TRUE;
2733
54.0k
        goto success;
2734
62.8k
    }
2735
2736
5.69k
    SPECIALIZATION_FAIL(TO_BOOL, to_bool_fail_kind(value));
2737
14.4k
failure:
2738
14.4k
    unspecialize(instr);
2739
14.4k
    return;
2740
191k
success:
2741
191k
    specialize(instr, specialized_op);
2742
191k
}
2743
2744
#ifdef Py_STATS
2745
static int
2746
containsop_fail_kind(PyObject *value) {
2747
    if (PyUnicode_CheckExact(value)) {
2748
        return SPEC_FAIL_CONTAINS_OP_STR;
2749
    }
2750
    if (PyList_CheckExact(value)) {
2751
        return SPEC_FAIL_CONTAINS_OP_LIST;
2752
    }
2753
    if (PyTuple_CheckExact(value)) {
2754
        return SPEC_FAIL_CONTAINS_OP_TUPLE;
2755
    }
2756
    if (PyType_Check(value)) {
2757
        return SPEC_FAIL_CONTAINS_OP_USER_CLASS;
2758
    }
2759
    return SPEC_FAIL_OTHER;
2760
}
2761
#endif
2762
2763
Py_NO_INLINE void
2764
_Py_Specialize_ContainsOp(_PyStackRef value_st, _Py_CODEUNIT *instr)
2765
35.4k
{
2766
35.4k
    PyObject *value = PyStackRef_AsPyObjectBorrow(value_st);
2767
2768
35.4k
    assert(ENABLE_SPECIALIZATION);
2769
35.4k
    assert(_PyOpcode_Caches[CONTAINS_OP] == INLINE_CACHE_ENTRIES_COMPARE_OP);
2770
35.4k
    if (PyAnyDict_CheckExact(value)) {
2771
614
        specialize(instr, CONTAINS_OP_DICT);
2772
614
        return;
2773
614
    }
2774
34.8k
    if (PySet_CheckExact(value) || PyFrozenSet_CheckExact(value)) {
2775
598
        specialize(instr, CONTAINS_OP_SET);
2776
598
        return;
2777
598
    }
2778
2779
34.2k
    SPECIALIZATION_FAIL(CONTAINS_OP, containsop_fail_kind(value));
2780
34.2k
    unspecialize(instr);
2781
34.2k
    return;
2782
34.8k
}
2783
2784
#ifdef Py_STATS
2785
void
2786
_Py_GatherStats_GetIter(_PyStackRef iterable)
2787
{
2788
    PyTypeObject *tp = PyStackRef_TYPE(iterable);
2789
    int kind = SPEC_FAIL_OTHER;
2790
    if (tp == &PyTuple_Type) {
2791
        kind = SPEC_FAIL_ITER_TUPLE;
2792
    }
2793
    else if (tp == &PyList_Type) {
2794
        kind = SPEC_FAIL_ITER_LIST;
2795
    }
2796
    else if (tp == &PyDict_Type) {
2797
        kind = SPEC_FAIL_ITER_DICT_KEYS;
2798
    }
2799
    else if (tp == &PySet_Type) {
2800
        kind = SPEC_FAIL_ITER_SET;
2801
    }
2802
    else if (tp == &PyBytes_Type) {
2803
        kind = SPEC_FAIL_ITER_BYTES;
2804
    }
2805
    else if (tp == &PyEnum_Type) {
2806
        kind = SPEC_FAIL_ITER_ENUMERATE;
2807
    }
2808
    else if (tp == &PyUnicode_Type) {
2809
        kind = SPEC_FAIL_ITER_STRING;
2810
    }
2811
    else if (tp == &PyGen_Type) {
2812
        kind = SPEC_FAIL_ITER_GENERATOR;
2813
    }
2814
    else if (tp == &PyCoro_Type) {
2815
        kind = SPEC_FAIL_ITER_COROUTINE;
2816
    }
2817
    else if (tp == &PyAsyncGen_Type) {
2818
        kind = SPEC_FAIL_ITER_ASYNC_GENERATOR;
2819
    }
2820
    else if (tp == &_PyAsyncGenASend_Type) {
2821
        kind = SPEC_FAIL_ITER_ASYNC_GENERATOR_SEND;
2822
    }
2823
    else if (tp->tp_iter == PyObject_SelfIter) {
2824
        kind = SPEC_FAIL_ITER_SELF;
2825
    }
2826
    SPECIALIZATION_FAIL(GET_ITER, kind);
2827
}
2828
#endif
2829
2830
2831
/* Code init cleanup.
2832
 * CALL_ALLOC_AND_ENTER_INIT will set up
2833
 * the frame to execute the EXIT_INIT_CHECK
2834
 * instruction.
2835
 * Ends with a RESUME so that it is not traced.
2836
 * This is used as a plain code object, not a function,
2837
 * so must not access globals or builtins.
2838
 * There are a few other constraints imposed on the code
2839
 * by the free-threaded build:
2840
 *
2841
 * 1. The RESUME instruction must not be executed. Otherwise we may attempt to
2842
 *    free the statically allocated TLBC array.
2843
 * 2. It must contain no specializable instructions. Specializing multiple
2844
 *    copies of the same bytecode is not thread-safe in free-threaded builds.
2845
 *
2846
 * This should be dynamically allocated if either of those restrictions need to
2847
 * be lifted.
2848
 */
2849
2850
#define NO_LOC_4 (128 | (PY_CODE_LOCATION_INFO_NONE << 3) | 3)
2851
2852
static const PyBytesObject no_location = {
2853
    PyVarObject_HEAD_INIT(&PyBytes_Type, 1)
2854
    .ob_sval = { NO_LOC_4 }
2855
};
2856
2857
#ifdef Py_GIL_DISABLED
2858
static _PyCodeArray init_cleanup_tlbc = {
2859
    .size = 1,
2860
    .entries = {(char*) &_Py_InitCleanup.co_code_adaptive},
2861
};
2862
#endif
2863
2864
const struct _PyCode8 _Py_InitCleanup = {
2865
    _PyVarObject_HEAD_INIT(&PyCode_Type, 3),
2866
    .co_consts = (PyObject *)&_Py_SINGLETON(tuple_empty),
2867
    .co_names = (PyObject *)&_Py_SINGLETON(tuple_empty),
2868
    .co_exceptiontable = (PyObject *)&_Py_SINGLETON(bytes_empty),
2869
    .co_flags = CO_OPTIMIZED | CO_NO_MONITORING_EVENTS,
2870
    .co_localsplusnames = (PyObject *)&_Py_SINGLETON(tuple_empty),
2871
    .co_localspluskinds = (PyObject *)&_Py_SINGLETON(bytes_empty),
2872
    .co_filename = &_Py_ID(__init__),
2873
    .co_name = &_Py_ID(__init__),
2874
    .co_qualname = &_Py_ID(__init__),
2875
    .co_linetable = (PyObject *)&no_location,
2876
    ._co_firsttraceable = 4,
2877
    .co_stacksize = 2,
2878
    .co_framesize = 2 + FRAME_SPECIALS_SIZE,
2879
#ifdef Py_GIL_DISABLED
2880
    .co_tlbc = &init_cleanup_tlbc,
2881
#endif
2882
    .co_code_adaptive = {
2883
        EXIT_INIT_CHECK, 0,
2884
        RETURN_VALUE, 0,
2885
        RESUME, RESUME_AT_FUNC_START,
2886
    }
2887
};