summaryrefslogtreecommitdiffstats
path: root/Python
diff options
context:
space:
mode:
authorIrit Katriel <1055913+iritkatriel@users.noreply.github.com>2021-07-29 16:26:53 (GMT)
committerGitHub <noreply@github.com>2021-07-29 16:26:53 (GMT)
commitddd1c418c05da0de978c75dfb3e4a5b8d27e1d9f (patch)
treee43ba73ffc54a4e7a5d96c808592e43d40c45a5b /Python
parent6741794dd420c6b9775a188690dbf265037cd69f (diff)
downloadcpython-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.c78
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)