diff options
author | Irit Katriel <1055913+iritkatriel@users.noreply.github.com> | 2021-07-29 16:26:53 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-07-29 16:26:53 (GMT) |
commit | ddd1c418c05da0de978c75dfb3e4a5b8d27e1d9f (patch) | |
tree | e43ba73ffc54a4e7a5d96c808592e43d40c45a5b /Python | |
parent | 6741794dd420c6b9775a188690dbf265037cd69f (diff) | |
download | cpython-ddd1c418c05da0de978c75dfb3e4a5b8d27e1d9f.zip cpython-ddd1c418c05da0de978c75dfb3e4a5b8d27e1d9f.tar.gz cpython-ddd1c418c05da0de978c75dfb3e4a5b8d27e1d9f.tar.bz2 |
bpo-44725 : expose specialization stats in python (GH-27192)
Diffstat (limited to 'Python')
-rw-r--r-- | Python/specialize.c | 78 |
1 files changed, 78 insertions, 0 deletions
diff --git a/Python/specialize.c b/Python/specialize.c index 5ebe596..f699065 100644 --- a/Python/specialize.c +++ b/Python/specialize.c @@ -40,6 +40,83 @@ Py_ssize_t _Py_QuickenedCount = 0; #if SPECIALIZATION_STATS SpecializationStats _specialization_stats[256] = { 0 }; +#define ADD_STAT_TO_DICT(res, field) \ + do { \ + PyObject *val = PyLong_FromUnsignedLongLong(stats->field); \ + if (val == NULL) { \ + Py_DECREF(res); \ + return NULL; \ + } \ + if (PyDict_SetItemString(res, #field, val) == -1) { \ + Py_DECREF(res); \ + Py_DECREF(val); \ + return NULL; \ + } \ + Py_DECREF(val); \ + } while(0); + +static PyObject* +stats_to_dict(SpecializationStats *stats) +{ + PyObject *res = PyDict_New(); + if (res == NULL) { + return NULL; + } + ADD_STAT_TO_DICT(res, specialization_success); + ADD_STAT_TO_DICT(res, specialization_failure); + ADD_STAT_TO_DICT(res, hit); + ADD_STAT_TO_DICT(res, deferred); + ADD_STAT_TO_DICT(res, miss); + ADD_STAT_TO_DICT(res, deopt); + ADD_STAT_TO_DICT(res, unquickened); +#if SPECIALIZATION_STATS_DETAILED + if (stats->miss_types != NULL) { + if (PyDict_SetItemString(res, "fails", stats->miss_types) == -1) { + Py_DECREF(res); + return NULL; + } + } +#endif + return res; +} +#undef ADD_STAT_TO_DICT + +static int +add_stat_dict( + PyObject *res, + int opcode, + const char *name) { + + SpecializationStats *stats = &_specialization_stats[opcode]; + PyObject *d = stats_to_dict(stats); + if (d == NULL) { + return -1; + } + int err = PyDict_SetItemString(res, name, d); + Py_DECREF(d); + return err; +} + +#if SPECIALIZATION_STATS +PyObject* +_Py_GetSpecializationStats(void) { + PyObject *stats = PyDict_New(); + if (stats == NULL) { + return NULL; + } + int err = 0; + err += add_stat_dict(stats, LOAD_ATTR, "load_attr"); + err += add_stat_dict(stats, LOAD_GLOBAL, "load_global"); + err += add_stat_dict(stats, BINARY_SUBSCR, "binary_subscr"); + if (err < 0) { + Py_DECREF(stats); + return NULL; + } + return stats; +} +#endif + + #define PRINT_STAT(name, field) fprintf(stderr, " %s." #field " : %" PRIu64 "\n", name, stats->field); static void @@ -71,6 +148,7 @@ print_stats(SpecializationStats *stats, const char *name) } #endif } +#undef PRINT_STAT void _Py_PrintSpecializationStats(void) |