Branch data Line data Source code
1 : : #ifndef Py_INTERNAL_CODE_H
2 : : #define Py_INTERNAL_CODE_H
3 : : #ifdef __cplusplus
4 : : extern "C" {
5 : : #endif
6 : :
7 : : #define CODE_MAX_WATCHERS 8
8 : :
9 : : /* PEP 659
10 : : * Specialization and quickening structs and helper functions
11 : : */
12 : :
13 : :
14 : : // Inline caches. If you change the number of cache entries for an instruction,
15 : : // you must *also* update the number of cache entries in Lib/opcode.py and bump
16 : : // the magic number in Lib/importlib/_bootstrap_external.py!
17 : :
18 : : #define CACHE_ENTRIES(cache) (sizeof(cache)/sizeof(_Py_CODEUNIT))
19 : :
20 : : typedef struct {
21 : : uint16_t counter;
22 : : uint16_t index;
23 : : uint16_t module_keys_version;
24 : : uint16_t builtin_keys_version;
25 : : } _PyLoadGlobalCache;
26 : :
27 : : #define INLINE_CACHE_ENTRIES_LOAD_GLOBAL CACHE_ENTRIES(_PyLoadGlobalCache)
28 : :
29 : : typedef struct {
30 : : uint16_t counter;
31 : : } _PyBinaryOpCache;
32 : :
33 : : #define INLINE_CACHE_ENTRIES_BINARY_OP CACHE_ENTRIES(_PyBinaryOpCache)
34 : :
35 : : typedef struct {
36 : : uint16_t counter;
37 : : } _PyUnpackSequenceCache;
38 : :
39 : : #define INLINE_CACHE_ENTRIES_UNPACK_SEQUENCE \
40 : : CACHE_ENTRIES(_PyUnpackSequenceCache)
41 : :
42 : : typedef struct {
43 : : uint16_t counter;
44 : : } _PyCompareOpCache;
45 : :
46 : : #define INLINE_CACHE_ENTRIES_COMPARE_OP CACHE_ENTRIES(_PyCompareOpCache)
47 : :
48 : : typedef struct {
49 : : uint16_t counter;
50 : : uint16_t type_version[2];
51 : : uint16_t func_version;
52 : : } _PyBinarySubscrCache;
53 : :
54 : : #define INLINE_CACHE_ENTRIES_BINARY_SUBSCR CACHE_ENTRIES(_PyBinarySubscrCache)
55 : :
56 : : typedef struct {
57 : : uint16_t counter;
58 : : uint16_t version[2];
59 : : uint16_t index;
60 : : } _PyAttrCache;
61 : :
62 : : typedef struct {
63 : : uint16_t counter;
64 : : uint16_t type_version[2];
65 : : uint16_t keys_version[2];
66 : : uint16_t descr[4];
67 : : } _PyLoadMethodCache;
68 : :
69 : :
70 : : // MUST be the max(_PyAttrCache, _PyLoadMethodCache)
71 : : #define INLINE_CACHE_ENTRIES_LOAD_ATTR CACHE_ENTRIES(_PyLoadMethodCache)
72 : :
73 : : #define INLINE_CACHE_ENTRIES_STORE_ATTR CACHE_ENTRIES(_PyAttrCache)
74 : :
75 : : typedef struct {
76 : : uint16_t counter;
77 : : uint16_t func_version[2];
78 : : uint16_t min_args;
79 : : } _PyCallCache;
80 : :
81 : : #define INLINE_CACHE_ENTRIES_CALL CACHE_ENTRIES(_PyCallCache)
82 : :
83 : : typedef struct {
84 : : uint16_t counter;
85 : : } _PyStoreSubscrCache;
86 : :
87 : : #define INLINE_CACHE_ENTRIES_STORE_SUBSCR CACHE_ENTRIES(_PyStoreSubscrCache)
88 : :
89 : : typedef struct {
90 : : uint16_t counter;
91 : : } _PyForIterCache;
92 : :
93 : : #define INLINE_CACHE_ENTRIES_FOR_ITER CACHE_ENTRIES(_PyForIterCache)
94 : :
95 : : typedef struct {
96 : : uint16_t counter;
97 : : } _PySendCache;
98 : :
99 : : #define INLINE_CACHE_ENTRIES_SEND CACHE_ENTRIES(_PySendCache)
100 : :
101 : : // Borrowed references to common callables:
102 : : struct callable_cache {
103 : : PyObject *isinstance;
104 : : PyObject *len;
105 : : PyObject *list_append;
106 : : PyObject *object__getattribute__;
107 : : };
108 : :
109 : : /* "Locals plus" for a code object is the set of locals + cell vars +
110 : : * free vars. This relates to variable names as well as offsets into
111 : : * the "fast locals" storage array of execution frames. The compiler
112 : : * builds the list of names, their offsets, and the corresponding
113 : : * kind of local.
114 : : *
115 : : * Those kinds represent the source of the initial value and the
116 : : * variable's scope (as related to closures). A "local" is an
117 : : * argument or other variable defined in the current scope. A "free"
118 : : * variable is one that is defined in an outer scope and comes from
119 : : * the function's closure. A "cell" variable is a local that escapes
120 : : * into an inner function as part of a closure, and thus must be
121 : : * wrapped in a cell. Any "local" can also be a "cell", but the
122 : : * "free" kind is mutually exclusive with both.
123 : : */
124 : :
125 : : // Note that these all fit within a byte, as do combinations.
126 : : // Later, we will use the smaller numbers to differentiate the different
127 : : // kinds of locals (e.g. pos-only arg, varkwargs, local-only).
128 : : #define CO_FAST_LOCAL 0x20
129 : : #define CO_FAST_CELL 0x40
130 : : #define CO_FAST_FREE 0x80
131 : :
132 : : typedef unsigned char _PyLocals_Kind;
133 : :
134 : : static inline _PyLocals_Kind
135 : 190727 : _PyLocals_GetKind(PyObject *kinds, int i)
136 : : {
137 : : assert(PyBytes_Check(kinds));
138 : : assert(0 <= i && i < PyBytes_GET_SIZE(kinds));
139 : 190727 : char *ptr = PyBytes_AS_STRING(kinds);
140 : 190727 : return (_PyLocals_Kind)(ptr[i]);
141 : : }
142 : :
143 : : static inline void
144 : 25043 : _PyLocals_SetKind(PyObject *kinds, int i, _PyLocals_Kind kind)
145 : : {
146 : : assert(PyBytes_Check(kinds));
147 : : assert(0 <= i && i < PyBytes_GET_SIZE(kinds));
148 : 25043 : char *ptr = PyBytes_AS_STRING(kinds);
149 : 25043 : ptr[i] = (char) kind;
150 : 25043 : }
151 : :
152 : :
153 : : struct _PyCodeConstructor {
154 : : /* metadata */
155 : : PyObject *filename;
156 : : PyObject *name;
157 : : PyObject *qualname;
158 : : int flags;
159 : :
160 : : /* the code */
161 : : PyObject *code;
162 : : int firstlineno;
163 : : PyObject *linetable;
164 : :
165 : : /* used by the code */
166 : : PyObject *consts;
167 : : PyObject *names;
168 : :
169 : : /* mapping frame offsets to information */
170 : : PyObject *localsplusnames; // Tuple of strings
171 : : PyObject *localspluskinds; // Bytes object, one byte per variable
172 : :
173 : : /* args (within varnames) */
174 : : int argcount;
175 : : int posonlyargcount;
176 : : // XXX Replace argcount with posorkwargcount (argcount - posonlyargcount).
177 : : int kwonlyargcount;
178 : :
179 : : /* needed to create the frame */
180 : : int stacksize;
181 : :
182 : : /* used by the eval loop */
183 : : PyObject *exceptiontable;
184 : : };
185 : :
186 : : // Using an "arguments struct" like this is helpful for maintainability
187 : : // in a case such as this with many parameters. It does bear a risk:
188 : : // if the struct changes and callers are not updated properly then the
189 : : // compiler will not catch problems (like a missing argument). This can
190 : : // cause hard-to-debug problems. The risk is mitigated by the use of
191 : : // check_code() in codeobject.c. However, we may decide to switch
192 : : // back to a regular function signature. Regardless, this approach
193 : : // wouldn't be appropriate if this weren't a strictly internal API.
194 : : // (See the comments in https://github.com/python/cpython/pull/26258.)
195 : : PyAPI_FUNC(int) _PyCode_Validate(struct _PyCodeConstructor *);
196 : : PyAPI_FUNC(PyCodeObject *) _PyCode_New(struct _PyCodeConstructor *);
197 : :
198 : :
199 : : /* Private API */
200 : :
201 : : /* Getters for internal PyCodeObject data. */
202 : : extern PyObject* _PyCode_GetVarnames(PyCodeObject *);
203 : : extern PyObject* _PyCode_GetCellvars(PyCodeObject *);
204 : : extern PyObject* _PyCode_GetFreevars(PyCodeObject *);
205 : : extern PyObject* _PyCode_GetCode(PyCodeObject *);
206 : :
207 : : /** API for initializing the line number tables. */
208 : : extern int _PyCode_InitAddressRange(PyCodeObject* co, PyCodeAddressRange *bounds);
209 : :
210 : : /** Out of process API for initializing the location table. */
211 : : extern void _PyLineTable_InitAddressRange(
212 : : const char *linetable,
213 : : Py_ssize_t length,
214 : : int firstlineno,
215 : : PyCodeAddressRange *range);
216 : :
217 : : /** API for traversing the line number table. */
218 : : extern int _PyLineTable_NextAddressRange(PyCodeAddressRange *range);
219 : : extern int _PyLineTable_PreviousAddressRange(PyCodeAddressRange *range);
220 : :
221 : : /* Specialization functions */
222 : :
223 : : extern void _Py_Specialize_LoadAttr(PyObject *owner, _Py_CODEUNIT *instr,
224 : : PyObject *name);
225 : : extern void _Py_Specialize_StoreAttr(PyObject *owner, _Py_CODEUNIT *instr,
226 : : PyObject *name);
227 : : extern void _Py_Specialize_LoadGlobal(PyObject *globals, PyObject *builtins,
228 : : _Py_CODEUNIT *instr, PyObject *name);
229 : : extern void _Py_Specialize_BinarySubscr(PyObject *sub, PyObject *container,
230 : : _Py_CODEUNIT *instr);
231 : : extern void _Py_Specialize_StoreSubscr(PyObject *container, PyObject *sub,
232 : : _Py_CODEUNIT *instr);
233 : : extern void _Py_Specialize_Call(PyObject *callable, _Py_CODEUNIT *instr,
234 : : int nargs, PyObject *kwnames);
235 : : extern void _Py_Specialize_BinaryOp(PyObject *lhs, PyObject *rhs, _Py_CODEUNIT *instr,
236 : : int oparg, PyObject **locals);
237 : : extern void _Py_Specialize_CompareAndBranch(PyObject *lhs, PyObject *rhs,
238 : : _Py_CODEUNIT *instr, int oparg);
239 : : extern void _Py_Specialize_UnpackSequence(PyObject *seq, _Py_CODEUNIT *instr,
240 : : int oparg);
241 : : extern void _Py_Specialize_ForIter(PyObject *iter, _Py_CODEUNIT *instr, int oparg);
242 : : extern void _Py_Specialize_Send(PyObject *receiver, _Py_CODEUNIT *instr);
243 : :
244 : : /* Finalizer function for static codeobjects used in deepfreeze.py */
245 : : extern void _PyStaticCode_Fini(PyCodeObject *co);
246 : : /* Function to intern strings of codeobjects and quicken the bytecode */
247 : : extern int _PyStaticCode_Init(PyCodeObject *co);
248 : :
249 : : #ifdef Py_STATS
250 : :
251 : :
252 : : #define STAT_INC(opname, name) do { if (_py_stats) _py_stats->opcode_stats[opname].specialization.name++; } while (0)
253 : : #define STAT_DEC(opname, name) do { if (_py_stats) _py_stats->opcode_stats[opname].specialization.name--; } while (0)
254 : : #define OPCODE_EXE_INC(opname) do { if (_py_stats) _py_stats->opcode_stats[opname].execution_count++; } while (0)
255 : : #define CALL_STAT_INC(name) do { if (_py_stats) _py_stats->call_stats.name++; } while (0)
256 : : #define OBJECT_STAT_INC(name) do { if (_py_stats) _py_stats->object_stats.name++; } while (0)
257 : : #define OBJECT_STAT_INC_COND(name, cond) \
258 : : do { if (_py_stats && cond) _py_stats->object_stats.name++; } while (0)
259 : : #define EVAL_CALL_STAT_INC(name) do { if (_py_stats) _py_stats->call_stats.eval_calls[name]++; } while (0)
260 : : #define EVAL_CALL_STAT_INC_IF_FUNCTION(name, callable) \
261 : : do { if (_py_stats && PyFunction_Check(callable)) _py_stats->call_stats.eval_calls[name]++; } while (0)
262 : :
263 : : // Used by the _opcode extension which is built as a shared library
264 : : PyAPI_FUNC(PyObject*) _Py_GetSpecializationStats(void);
265 : :
266 : : #else
267 : : #define STAT_INC(opname, name) ((void)0)
268 : : #define STAT_DEC(opname, name) ((void)0)
269 : : #define OPCODE_EXE_INC(opname) ((void)0)
270 : : #define CALL_STAT_INC(name) ((void)0)
271 : : #define OBJECT_STAT_INC(name) ((void)0)
272 : : #define OBJECT_STAT_INC_COND(name, cond) ((void)0)
273 : : #define EVAL_CALL_STAT_INC(name) ((void)0)
274 : : #define EVAL_CALL_STAT_INC_IF_FUNCTION(name, callable) ((void)0)
275 : : #endif // !Py_STATS
276 : :
277 : : // Utility functions for reading/writing 32/64-bit values in the inline caches.
278 : : // Great care should be taken to ensure that these functions remain correct and
279 : : // performant! They should compile to just "move" instructions on all supported
280 : : // compilers and platforms.
281 : :
282 : : // We use memcpy to let the C compiler handle unaligned accesses and endianness
283 : : // issues for us. It also seems to produce better code than manual copying for
284 : : // most compilers (see https://blog.regehr.org/archives/959 for more info).
285 : :
286 : : static inline void
287 : 26870 : write_u32(uint16_t *p, uint32_t val)
288 : : {
289 : 26870 : memcpy(p, &val, sizeof(val));
290 : 26870 : }
291 : :
292 : : static inline void
293 : : write_u64(uint16_t *p, uint64_t val)
294 : : {
295 : : memcpy(p, &val, sizeof(val));
296 : : }
297 : :
298 : : static inline void
299 : 3060 : write_obj(uint16_t *p, PyObject *val)
300 : : {
301 : 3060 : memcpy(p, &val, sizeof(val));
302 : 3060 : }
303 : :
304 : : static inline uint16_t
305 : 24693037 : read_u16(uint16_t *p)
306 : : {
307 : 24693037 : return *p;
308 : : }
309 : :
310 : : static inline uint32_t
311 : 11900004 : read_u32(uint16_t *p)
312 : : {
313 : : uint32_t val;
314 : 11900004 : memcpy(&val, p, sizeof(val));
315 : 11900004 : return val;
316 : : }
317 : :
318 : : static inline uint64_t
319 : : read_u64(uint16_t *p)
320 : : {
321 : : uint64_t val;
322 : : memcpy(&val, p, sizeof(val));
323 : : return val;
324 : : }
325 : :
326 : : static inline PyObject *
327 : 3820716 : read_obj(uint16_t *p)
328 : : {
329 : : PyObject *val;
330 : 3820716 : memcpy(&val, p, sizeof(val));
331 : 3820716 : return val;
332 : : }
333 : :
334 : : /* See Objects/exception_handling_notes.txt for details.
335 : : */
336 : : static inline unsigned char *
337 : 632007 : parse_varint(unsigned char *p, int *result) {
338 : 632007 : int val = p[0] & 63;
339 [ + + ]: 840162 : while (p[0] & 64) {
340 : 208155 : p++;
341 : 208155 : val = (val << 6) | (p[0] & 63);
342 : : }
343 : 632007 : *result = val;
344 : 632007 : return p+1;
345 : : }
346 : :
347 : : static inline int
348 : 159368 : write_varint(uint8_t *ptr, unsigned int val)
349 : : {
350 : 159368 : int written = 1;
351 [ + + ]: 170950 : while (val >= 64) {
352 : 11582 : *ptr++ = 64 | (val & 63);
353 : 11582 : val >>= 6;
354 : 11582 : written++;
355 : : }
356 : 159368 : *ptr = val;
357 : 159368 : return written;
358 : : }
359 : :
360 : : static inline int
361 : 40241 : write_signed_varint(uint8_t *ptr, int val)
362 : : {
363 [ + + ]: 40241 : if (val < 0) {
364 : 10839 : val = ((-val)<<1) | 1;
365 : : }
366 : : else {
367 : 29402 : val = val << 1;
368 : : }
369 : 40241 : return write_varint(ptr, val);
370 : : }
371 : :
372 : : static inline int
373 : 286095 : write_location_entry_start(uint8_t *ptr, int code, int length)
374 : : {
375 : : assert((code & 15) == code);
376 : 286095 : *ptr = 128 | (code << 3) | (length - 1);
377 : 286095 : return 1;
378 : : }
379 : :
380 : :
381 : : /** Counters
382 : : * The first 16-bit value in each inline cache is a counter.
383 : : * When counting misses, the counter is treated as a simple unsigned value.
384 : : *
385 : : * When counting executions until the next specialization attempt,
386 : : * exponential backoff is used to reduce the number of specialization failures.
387 : : * The high 12 bits store the counter, the low 4 bits store the backoff exponent.
388 : : * On a specialization failure, the backoff exponent is incremented and the
389 : : * counter set to (2**backoff - 1).
390 : : * Backoff == 6 -> starting counter == 63, backoff == 10 -> starting counter == 1023.
391 : : */
392 : :
393 : : /* With a 16-bit counter, we have 12 bits for the counter value, and 4 bits for the backoff */
394 : : #define ADAPTIVE_BACKOFF_BITS 4
395 : :
396 : : // A value of 1 means that we attempt to specialize the *second* time each
397 : : // instruction is executed. Executing twice is a much better indicator of
398 : : // "hotness" than executing once, but additional warmup delays only prevent
399 : : // specialization. Most types stabilize by the second execution, too:
400 : : #define ADAPTIVE_WARMUP_VALUE 1
401 : : #define ADAPTIVE_WARMUP_BACKOFF 1
402 : :
403 : : // A value of 52 means that we attempt to re-specialize after 53 misses (a prime
404 : : // number, useful for avoiding artifacts if every nth value is a different type
405 : : // or something). Setting the backoff to 0 means that the counter is reset to
406 : : // the same state as a warming-up instruction (value == 1, backoff == 1) after
407 : : // deoptimization. This isn't strictly necessary, but it is bit easier to reason
408 : : // about when thinking about the opcode transitions as a state machine:
409 : : #define ADAPTIVE_COOLDOWN_VALUE 52
410 : : #define ADAPTIVE_COOLDOWN_BACKOFF 0
411 : :
412 : : #define MAX_BACKOFF_VALUE (16 - ADAPTIVE_BACKOFF_BITS)
413 : :
414 : :
415 : : static inline uint16_t
416 : 405661 : adaptive_counter_bits(int value, int backoff) {
417 : 811322 : return (value << ADAPTIVE_BACKOFF_BITS) |
418 : 405661 : (backoff & ((1<<ADAPTIVE_BACKOFF_BITS)-1));
419 : : }
420 : :
421 : : static inline uint16_t
422 : 332738 : adaptive_counter_warmup(void) {
423 : 332738 : return adaptive_counter_bits(ADAPTIVE_WARMUP_VALUE,
424 : : ADAPTIVE_WARMUP_BACKOFF);
425 : : }
426 : :
427 : : static inline uint16_t
428 : 50003 : adaptive_counter_cooldown(void) {
429 : 50003 : return adaptive_counter_bits(ADAPTIVE_COOLDOWN_VALUE,
430 : : ADAPTIVE_COOLDOWN_BACKOFF);
431 : : }
432 : :
433 : : static inline uint16_t
434 : 22920 : adaptive_counter_backoff(uint16_t counter) {
435 : 22920 : unsigned int backoff = counter & ((1<<ADAPTIVE_BACKOFF_BITS)-1);
436 : 22920 : backoff++;
437 [ + + ]: 22920 : if (backoff > MAX_BACKOFF_VALUE) {
438 : 2422 : backoff = MAX_BACKOFF_VALUE;
439 : : }
440 : 22920 : unsigned int value = (1 << backoff) - 1;
441 : 22920 : return adaptive_counter_bits(value, backoff);
442 : : }
443 : :
444 : :
445 : : /* Line array cache for tracing */
446 : :
447 : : extern int _PyCode_CreateLineArray(PyCodeObject *co);
448 : :
449 : : static inline int
450 : 0 : _PyCode_InitLineArray(PyCodeObject *co)
451 : : {
452 [ # # ]: 0 : if (co->_co_linearray) {
453 : 0 : return 0;
454 : : }
455 : 0 : return _PyCode_CreateLineArray(co);
456 : : }
457 : :
458 : : static inline int
459 : 0 : _PyCode_LineNumberFromArray(PyCodeObject *co, int index)
460 : : {
461 : : assert(co->_co_linearray != NULL);
462 : : assert(index >= 0);
463 : : assert(index < Py_SIZE(co));
464 [ # # ]: 0 : if (co->_co_linearray_entry_size == 2) {
465 : 0 : return ((int16_t *)co->_co_linearray)[index];
466 : : }
467 : : else {
468 : : assert(co->_co_linearray_entry_size == 4);
469 : 0 : return ((int32_t *)co->_co_linearray)[index];
470 : : }
471 : : }
472 : :
473 : : typedef struct _PyShimCodeDef {
474 : : const uint8_t *code;
475 : : int codelen;
476 : : int stacksize;
477 : : const char *cname;
478 : : } _PyShimCodeDef;
479 : :
480 : : extern PyCodeObject *
481 : : _Py_MakeShimCode(const _PyShimCodeDef *code);
482 : :
483 : : extern uint32_t _Py_next_func_version;
484 : :
485 : :
486 : : /* Comparison bit masks. */
487 : :
488 : : /* Note this evaluates its arguments twice each */
489 : : #define COMPARISON_BIT(x, y) (1 << (2 * ((x) >= (y)) + ((x) <= (y))))
490 : :
491 : : /*
492 : : * The following bits are chosen so that the value of
493 : : * COMPARSION_BIT(left, right)
494 : : * masked by the values below will be non-zero if the
495 : : * comparison is true, and zero if it is false */
496 : :
497 : : /* This is for values that are unordered, ie. NaN, not types that are unordered, e.g. sets */
498 : : #define COMPARISON_UNORDERED 1
499 : :
500 : : #define COMPARISON_LESS_THAN 2
501 : : #define COMPARISON_GREATER_THAN 4
502 : : #define COMPARISON_EQUALS 8
503 : :
504 : : #define COMPARISON_NOT_EQUALS (COMPARISON_UNORDERED | COMPARISON_LESS_THAN | COMPARISON_GREATER_THAN)
505 : :
506 : :
507 : : #ifdef __cplusplus
508 : : }
509 : : #endif
510 : : #endif /* !Py_INTERNAL_CODE_H */
|