@@ -31,7 +31,7 @@ extern "C" {
31
31
#define CACHE_ENTRIES (cache ) (sizeof(cache)/sizeof(_Py_CODEUNIT))
32
32
33
33
typedef struct {
34
- uint16_t counter ;
34
+ _Py_BackoffCounter counter ;
35
35
uint16_t module_keys_version ;
36
36
uint16_t builtin_keys_version ;
37
37
uint16_t index ;
@@ -40,44 +40,44 @@ typedef struct {
40
40
#define INLINE_CACHE_ENTRIES_LOAD_GLOBAL CACHE_ENTRIES(_PyLoadGlobalCache)
41
41
42
42
typedef struct {
43
- uint16_t counter ;
43
+ _Py_BackoffCounter counter ;
44
44
} _PyBinaryOpCache ;
45
45
46
46
#define INLINE_CACHE_ENTRIES_BINARY_OP CACHE_ENTRIES(_PyBinaryOpCache)
47
47
48
48
typedef struct {
49
- uint16_t counter ;
49
+ _Py_BackoffCounter counter ;
50
50
} _PyUnpackSequenceCache ;
51
51
52
52
#define INLINE_CACHE_ENTRIES_UNPACK_SEQUENCE \
53
53
CACHE_ENTRIES(_PyUnpackSequenceCache)
54
54
55
55
typedef struct {
56
- uint16_t counter ;
56
+ _Py_BackoffCounter counter ;
57
57
} _PyCompareOpCache ;
58
58
59
59
#define INLINE_CACHE_ENTRIES_COMPARE_OP CACHE_ENTRIES(_PyCompareOpCache)
60
60
61
61
typedef struct {
62
- uint16_t counter ;
62
+ _Py_BackoffCounter counter ;
63
63
} _PyBinarySubscrCache ;
64
64
65
65
#define INLINE_CACHE_ENTRIES_BINARY_SUBSCR CACHE_ENTRIES(_PyBinarySubscrCache)
66
66
67
67
typedef struct {
68
- uint16_t counter ;
68
+ _Py_BackoffCounter counter ;
69
69
} _PySuperAttrCache ;
70
70
71
71
#define INLINE_CACHE_ENTRIES_LOAD_SUPER_ATTR CACHE_ENTRIES(_PySuperAttrCache)
72
72
73
73
typedef struct {
74
- uint16_t counter ;
74
+ _Py_BackoffCounter counter ;
75
75
uint16_t version [2 ];
76
76
uint16_t index ;
77
77
} _PyAttrCache ;
78
78
79
79
typedef struct {
80
- uint16_t counter ;
80
+ _Py_BackoffCounter counter ;
81
81
uint16_t type_version [2 ];
82
82
union {
83
83
uint16_t keys_version [2 ];
@@ -93,39 +93,39 @@ typedef struct {
93
93
#define INLINE_CACHE_ENTRIES_STORE_ATTR CACHE_ENTRIES(_PyAttrCache)
94
94
95
95
typedef struct {
96
- uint16_t counter ;
96
+ _Py_BackoffCounter counter ;
97
97
uint16_t func_version [2 ];
98
98
} _PyCallCache ;
99
99
100
100
#define INLINE_CACHE_ENTRIES_CALL CACHE_ENTRIES(_PyCallCache)
101
101
102
102
typedef struct {
103
- uint16_t counter ;
103
+ _Py_BackoffCounter counter ;
104
104
} _PyStoreSubscrCache ;
105
105
106
106
#define INLINE_CACHE_ENTRIES_STORE_SUBSCR CACHE_ENTRIES(_PyStoreSubscrCache)
107
107
108
108
typedef struct {
109
- uint16_t counter ;
109
+ _Py_BackoffCounter counter ;
110
110
} _PyForIterCache ;
111
111
112
112
#define INLINE_CACHE_ENTRIES_FOR_ITER CACHE_ENTRIES(_PyForIterCache)
113
113
114
114
typedef struct {
115
- uint16_t counter ;
115
+ _Py_BackoffCounter counter ;
116
116
} _PySendCache ;
117
117
118
118
#define INLINE_CACHE_ENTRIES_SEND CACHE_ENTRIES(_PySendCache)
119
119
120
120
typedef struct {
121
- uint16_t counter ;
121
+ _Py_BackoffCounter counter ;
122
122
uint16_t version [2 ];
123
123
} _PyToBoolCache ;
124
124
125
125
#define INLINE_CACHE_ENTRIES_TO_BOOL CACHE_ENTRIES(_PyToBoolCache)
126
126
127
127
typedef struct {
128
- uint16_t counter ;
128
+ _Py_BackoffCounter counter ;
129
129
} _PyContainsOpCache ;
130
130
131
131
#define INLINE_CACHE_ENTRIES_CONTAINS_OP CACHE_ENTRIES(_PyContainsOpCache)
@@ -451,18 +451,14 @@ write_location_entry_start(uint8_t *ptr, int code, int length)
451
451
452
452
/** Counters
453
453
* The first 16-bit value in each inline cache is a counter.
454
- * When counting misses, the counter is treated as a simple unsigned value.
455
454
*
456
455
* When counting executions until the next specialization attempt,
457
456
* exponential backoff is used to reduce the number of specialization failures.
458
- * The high 12 bits store the counter, the low 4 bits store the backoff exponent.
459
- * On a specialization failure, the backoff exponent is incremented and the
460
- * counter set to (2**backoff - 1).
461
- * Backoff == 6 -> starting counter == 63, backoff == 10 -> starting counter == 1023.
457
+ * See pycore_backoff.h for more details.
458
+ * On a specialization failure, the backoff counter is restarted.
462
459
*/
463
460
464
- /* With a 16-bit counter, we have 12 bits for the counter value, and 4 bits for the backoff */
465
- #define ADAPTIVE_BACKOFF_BITS 4
461
+ #include "pycore_backoff.h"
466
462
467
463
// A value of 1 means that we attempt to specialize the *second* time each
468
464
// instruction is executed. Executing twice is a much better indicator of
@@ -480,36 +476,30 @@ write_location_entry_start(uint8_t *ptr, int code, int length)
480
476
#define ADAPTIVE_COOLDOWN_VALUE 52
481
477
#define ADAPTIVE_COOLDOWN_BACKOFF 0
482
478
483
- #define MAX_BACKOFF_VALUE (16 - ADAPTIVE_BACKOFF_BITS)
479
+ // Can't assert this in pycore_backoff.h because of header order dependencies
480
+ static_assert (COLD_EXIT_INITIAL_VALUE > ADAPTIVE_COOLDOWN_VALUE ,
481
+ "Cold exit value should be larger than adaptive cooldown value" );
484
482
485
-
486
- static inline uint16_t
483
+ static inline _Py_BackoffCounter
487
484
adaptive_counter_bits (uint16_t value , uint16_t backoff ) {
488
- return ((value << ADAPTIVE_BACKOFF_BITS )
489
- | (backoff & ((1 << ADAPTIVE_BACKOFF_BITS ) - 1 )));
485
+ return make_backoff_counter (value , backoff );
490
486
}
491
487
492
- static inline uint16_t
488
+ static inline _Py_BackoffCounter
493
489
adaptive_counter_warmup (void ) {
494
490
return adaptive_counter_bits (ADAPTIVE_WARMUP_VALUE ,
495
491
ADAPTIVE_WARMUP_BACKOFF );
496
492
}
497
493
498
- static inline uint16_t
494
+ static inline _Py_BackoffCounter
499
495
adaptive_counter_cooldown (void ) {
500
496
return adaptive_counter_bits (ADAPTIVE_COOLDOWN_VALUE ,
501
497
ADAPTIVE_COOLDOWN_BACKOFF );
502
498
}
503
499
504
- static inline uint16_t
505
- adaptive_counter_backoff (uint16_t counter ) {
506
- uint16_t backoff = counter & ((1 << ADAPTIVE_BACKOFF_BITS ) - 1 );
507
- backoff ++ ;
508
- if (backoff > MAX_BACKOFF_VALUE ) {
509
- backoff = MAX_BACKOFF_VALUE ;
510
- }
511
- uint16_t value = (uint16_t )(1 << backoff ) - 1 ;
512
- return adaptive_counter_bits (value , backoff );
500
+ static inline _Py_BackoffCounter
501
+ adaptive_counter_backoff (_Py_BackoffCounter counter ) {
502
+ return restart_backoff_counter (counter );
513
503
}
514
504
515
505
0 commit comments