gh-114312: Collect stats for unlikely events (GH-114493)

This commit is contained in:
Michael Droettboom 2024-01-25 06:10:51 -05:00 committed by GitHub
parent c63c6142f9
commit ea3cd0498c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
11 changed files with 199 additions and 1 deletions

View file

@ -295,6 +295,7 @@ extern int _PyStaticCode_Init(PyCodeObject *co);
_Py_stats->optimization_stats.name[bucket]++; \
} \
} while (0)
#define RARE_EVENT_STAT_INC(name) do { if (_Py_stats) _Py_stats->rare_event_stats.name++; } while (0)
// Export for '_opcode' shared extension
PyAPI_FUNC(PyObject*) _Py_GetSpecializationStats(void);
@ -313,6 +314,7 @@ PyAPI_FUNC(PyObject*) _Py_GetSpecializationStats(void);
#define UOP_STAT_INC(opname, name) ((void)0)
#define OPT_UNSUPPORTED_OPCODE(opname) ((void)0)
#define OPT_HIST(length, name) ((void)0)
#define RARE_EVENT_STAT_INC(name) ((void)0)
#endif // !Py_STATS
// Utility functions for reading/writing 32/64-bit values in the inline caches.

View file

@ -60,6 +60,21 @@ struct _stoptheworld_state {
/* cross-interpreter data registry */
/* Tracks some rare events per-interpreter, used by the optimizer to turn on/off
specific optimizations. */
typedef struct _rare_events {
/* Setting an object's class, obj.__class__ = ... */
uint8_t set_class;
/* Setting the bases of a class, cls.__bases__ = ... */
uint8_t set_bases;
/* Setting the PEP 523 frame eval function, _PyInterpreterState_SetFrameEvalFunc() */
uint8_t set_eval_frame_func;
/* Modifying the builtins, __builtins__.__dict__[var] = ... */
uint8_t builtin_dict;
int builtins_dict_watcher_id;
/* Modifying a function, e.g. func.__defaults__ = ..., etc. */
uint8_t func_modification;
} _rare_events;
/* interpreter state */
@ -217,6 +232,7 @@ struct _is {
uint16_t optimizer_resume_threshold;
uint16_t optimizer_backedge_threshold;
uint32_t next_func_version;
_rare_events rare_events;
_Py_GlobalMonitors monitors;
bool sys_profile_initialized;
@ -347,6 +363,19 @@ PyAPI_FUNC(PyStatus) _PyInterpreterState_New(
PyInterpreterState **pinterp);
#define RARE_EVENT_INTERP_INC(interp, name) \
do { \
/* saturating add */ \
if (interp->rare_events.name < UINT8_MAX) interp->rare_events.name++; \
RARE_EVENT_STAT_INC(name); \
} while (0); \
#define RARE_EVENT_INC(name) \
do { \
PyInterpreterState *interp = PyInterpreterState_Get(); \
RARE_EVENT_INTERP_INC(interp, name); \
} while (0); \
#ifdef __cplusplus
}
#endif