Where Online Learning is simpler!
The C and C++ Include Header Files
cat -n /usr/include/python3.14/cpython/pystats.h
1 // Statistics on Python performance. 2 // 3 // API: 4 // 5 // - _Py_INCREF_STAT_INC() and _Py_DECREF_STAT_INC() used by Py_INCREF() 6 // and Py_DECREF(). 7 // - _Py_stats variable 8 // 9 // Functions of the sys module: 10 // 11 // - sys._stats_on() 12 // - sys._stats_off() 13 // - sys._stats_clear() 14 // - sys._stats_dump() 15 // 16 // Python must be built with ./configure --enable-pystats to define the 17 // Py_STATS macro. 18 // 19 // Define _PY_INTERPRETER macro to increment interpreter_increfs and 20 // interpreter_decrefs. Otherwise, increment increfs and decrefs. 21 // 22 // The number of incref operations counted by `incref` and 23 // `interpreter_incref` is the number of increment operations, which is 24 // not equal to the total of all reference counts. A single increment 25 // operation may increase the reference count of an object by more than 26 // one. For example, see `_Py_RefcntAdd`. 27 28 #ifndef Py_CPYTHON_PYSTATS_H 29 # error "this header file must not be included directly" 30 #endif 31 32 #define PYSTATS_MAX_UOP_ID 1024 33 34 #define SPECIALIZATION_FAILURE_KINDS 60 35 36 /* Stats for determining who is calling PyEval_EvalFrame */ 37 #define EVAL_CALL_TOTAL 0 38 #define EVAL_CALL_VECTOR 1 39 #define EVAL_CALL_GENERATOR 2 40 #define EVAL_CALL_LEGACY 3 41 #define EVAL_CALL_FUNCTION_VECTORCALL 4 42 #define EVAL_CALL_BUILD_CLASS 5 43 #define EVAL_CALL_SLOT 6 44 #define EVAL_CALL_FUNCTION_EX 7 45 #define EVAL_CALL_API 8 46 #define EVAL_CALL_METHOD 9 47 48 #define EVAL_CALL_KINDS 10 49 50 typedef struct _specialization_stats { 51 uint64_t success; 52 uint64_t failure; 53 uint64_t hit; 54 uint64_t deferred; 55 uint64_t miss; 56 uint64_t deopt; 57 uint64_t failure_kinds[SPECIALIZATION_FAILURE_KINDS]; 58 } SpecializationStats; 59 60 typedef struct _opcode_stats { 61 SpecializationStats specialization; 62 uint64_t execution_count; 63 uint64_t pair_count[256]; 64 } OpcodeStats; 65 66 typedef struct _call_stats { 67 uint64_t inlined_py_calls; 68 uint64_t pyeval_calls; 69 uint64_t frames_pushed; 70 uint64_t frame_objects_created; 71 uint64_t eval_calls[EVAL_CALL_KINDS]; 72 } CallStats; 73 74 typedef struct _object_stats { 75 uint64_t increfs; 76 uint64_t decrefs; 77 uint64_t interpreter_increfs; 78 uint64_t interpreter_decrefs; 79 uint64_t immortal_increfs; 80 uint64_t immortal_decrefs; 81 uint64_t interpreter_immortal_increfs; 82 uint64_t interpreter_immortal_decrefs; 83 uint64_t allocations; 84 uint64_t allocations512; 85 uint64_t allocations4k; 86 uint64_t allocations_big; 87 uint64_t frees; 88 uint64_t to_freelist; 89 uint64_t from_freelist; 90 uint64_t inline_values; 91 uint64_t dict_materialized_on_request; 92 uint64_t dict_materialized_new_key; 93 uint64_t dict_materialized_too_big; 94 uint64_t dict_materialized_str_subclass; 95 uint64_t type_cache_hits; 96 uint64_t type_cache_misses; 97 uint64_t type_cache_dunder_hits; 98 uint64_t type_cache_dunder_misses; 99 uint64_t type_cache_collisions; 100 /* Temporary value used during GC */ 101 uint64_t object_visits; 102 } ObjectStats; 103 104 typedef struct _gc_stats { 105 uint64_t collections; 106 uint64_t object_visits; 107 uint64_t objects_collected; 108 uint64_t objects_transitively_reachable; 109 uint64_t objects_not_transitively_reachable; 110 } GCStats; 111 112 typedef struct _uop_stats { 113 uint64_t execution_count; 114 uint64_t miss; 115 uint64_t pair_count[PYSTATS_MAX_UOP_ID + 1]; 116 } UOpStats; 117 118 #define _Py_UOP_HIST_SIZE 32 119 120 typedef struct _optimization_stats { 121 uint64_t attempts; 122 uint64_t traces_created; 123 uint64_t traces_executed; 124 uint64_t uops_executed; 125 uint64_t trace_stack_overflow; 126 uint64_t trace_stack_underflow; 127 uint64_t trace_too_long; 128 uint64_t trace_too_short; 129 uint64_t inner_loop; 130 uint64_t recursive_call; 131 uint64_t low_confidence; 132 uint64_t unknown_callee; 133 uint64_t executors_invalidated; 134 UOpStats opcode[PYSTATS_MAX_UOP_ID + 1]; 135 uint64_t unsupported_opcode[256]; 136 uint64_t trace_length_hist[_Py_UOP_HIST_SIZE]; 137 uint64_t trace_run_length_hist[_Py_UOP_HIST_SIZE]; 138 uint64_t optimized_trace_length_hist[_Py_UOP_HIST_SIZE]; 139 uint64_t optimizer_attempts; 140 uint64_t optimizer_successes; 141 uint64_t optimizer_failure_reason_no_memory; 142 uint64_t remove_globals_builtins_changed; 143 uint64_t remove_globals_incorrect_keys; 144 uint64_t error_in_opcode[PYSTATS_MAX_UOP_ID + 1]; 145 // JIT memory stats 146 uint64_t jit_total_memory_size; 147 uint64_t jit_code_size; 148 uint64_t jit_trampoline_size; 149 uint64_t jit_data_size; 150 uint64_t jit_padding_size; 151 uint64_t jit_freed_memory_size; 152 uint64_t trace_total_memory_hist[_Py_UOP_HIST_SIZE]; 153 } OptimizationStats; 154 155 typedef struct _rare_event_stats { 156 /* Setting an object's class, obj.__class__ = ... */ 157 uint64_t set_class; 158 /* Setting the bases of a class, cls.__bases__ = ... */ 159 uint64_t set_bases; 160 /* Setting the PEP 523 frame eval function, _PyInterpreterState_SetFrameEvalFunc() */ 161 uint64_t set_eval_frame_func; 162 /* Modifying the builtins, __builtins__.__dict__[var] = ... */ 163 uint64_t builtin_dict; 164 /* Modifying a function, e.g. func.__defaults__ = ..., etc. */ 165 uint64_t func_modification; 166 /* Modifying a dict that is being watched */ 167 uint64_t watched_dict_modification; 168 uint64_t watched_globals_modification; 169 } RareEventStats; 170 171 typedef struct _stats { 172 OpcodeStats opcode_stats[256]; 173 CallStats call_stats; 174 ObjectStats object_stats; 175 OptimizationStats optimization_stats; 176 RareEventStats rare_event_stats; 177 GCStats *gc_stats; 178 } PyStats; 179 180 181 // Export for shared extensions like 'math' 182 PyAPI_DATA(PyStats*) _Py_stats; 183 184 #ifdef _PY_INTERPRETER 185 # define _Py_INCREF_STAT_INC() do { if (_Py_stats) _Py_stats->object_stats.interpreter_increfs++; } while (0) 186 # define _Py_DECREF_STAT_INC() do { if (_Py_stats) _Py_stats->object_stats.interpreter_decrefs++; } while (0) 187 # define _Py_INCREF_IMMORTAL_STAT_INC() do { if (_Py_stats) _Py_stats->object_stats.interpreter_immortal_increfs++; } while (0) 188 # define _Py_DECREF_IMMORTAL_STAT_INC() do { if (_Py_stats) _Py_stats->object_stats.interpreter_immortal_decrefs++; } while (0) 189 #else 190 # define _Py_INCREF_STAT_INC() do { if (_Py_stats) _Py_stats->object_stats.increfs++; } while (0) 191 # define _Py_DECREF_STAT_INC() do { if (_Py_stats) _Py_stats->object_stats.decrefs++; } while (0) 192 # define _Py_INCREF_IMMORTAL_STAT_INC() do { if (_Py_stats) _Py_stats->object_stats.immortal_increfs++; } while (0) 193 # define _Py_DECREF_IMMORTAL_STAT_INC() do { if (_Py_stats) _Py_stats->object_stats.immortal_decrefs++; } while (0) 194 #endif