Coverage Report

Created: 2026-04-20 06:11

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