[Python-checkins] Split refcount stats into 'interpreter' and 'non-interpreter' (GH-92919)

markshannon webhook-mailer at python.org
Wed May 18 09:38:53 EDT 2022


https://github.com/python/cpython/commit/a4460f2eb8b9db46a9bce3c450c8b038038a7c93
commit: a4460f2eb8b9db46a9bce3c450c8b038038a7c93
branch: main
author: Mark Shannon <mark at hotpy.org>
committer: markshannon <mark at hotpy.org>
date: 2022-05-18T14:38:43+01:00
summary:

Split refcount stats into 'interpreter' and 'non-interpreter' (GH-92919)

files:
M Include/pystats.h
M Objects/genobject.c
M Python/ceval.c
M Python/frame.c
M Python/specialize.c
M Tools/scripts/summarize_stats.py

diff --git a/Include/pystats.h b/Include/pystats.h
index bc05dd864c63a..4375614b05e48 100644
--- a/Include/pystats.h
+++ b/Include/pystats.h
@@ -36,6 +36,8 @@ typedef struct _call_stats {
 typedef struct _object_stats {
     uint64_t increfs;
     uint64_t decrefs;
+    uint64_t interpreter_increfs;
+    uint64_t interpreter_decrefs;
     uint64_t allocations;
     uint64_t allocations512;
     uint64_t allocations4k;
@@ -60,10 +62,18 @@ PyAPI_DATA(PyStats) _py_stats;
 
 extern void _Py_PrintSpecializationStats(int to_file);
 
+#ifdef _PY_INTERPRETER
+
+#define _Py_INCREF_STAT_INC() _py_stats.object_stats.interpreter_increfs++
+#define _Py_DECREF_STAT_INC()  _py_stats.object_stats.interpreter_decrefs++
+
+#else
 
 #define _Py_INCREF_STAT_INC() _py_stats.object_stats.increfs++
 #define _Py_DECREF_STAT_INC()  _py_stats.object_stats.decrefs++
 
+#endif
+
 #else
 
 #define _Py_INCREF_STAT_INC() ((void)0)
diff --git a/Objects/genobject.c b/Objects/genobject.c
index b9a0c30c411a0..a88522abf414c 100644
--- a/Objects/genobject.c
+++ b/Objects/genobject.c
@@ -1,5 +1,7 @@
 /* Generator object implementation */
 
+#define _PY_INTERPRETER
+
 #include "Python.h"
 #include "pycore_call.h"          // _PyObject_CallNoArgs()
 #include "pycore_ceval.h"         // _PyEval_EvalFrame()
diff --git a/Python/ceval.c b/Python/ceval.c
index c81d0efff9b9b..e4c47498c0cba 100644
--- a/Python/ceval.c
+++ b/Python/ceval.c
@@ -5,6 +5,8 @@
    XXX document it!
    */
 
+#define _PY_INTERPRETER
+
 #include "Python.h"
 #include "pycore_abstract.h"      // _PyIndex_Check()
 #include "pycore_call.h"          // _PyObject_FastCallDictTstate()
diff --git a/Python/frame.c b/Python/frame.c
index c2da123a2bbc1..3573f54ad63e9 100644
--- a/Python/frame.c
+++ b/Python/frame.c
@@ -1,4 +1,6 @@
 
+#define _PY_INTERPRETER
+
 #include "Python.h"
 #include "frameobject.h"
 #include "pycore_code.h"           // stats
diff --git a/Python/specialize.c b/Python/specialize.c
index 6a91389f85610..5469285e16c4d 100644
--- a/Python/specialize.c
+++ b/Python/specialize.c
@@ -191,6 +191,8 @@ print_object_stats(FILE *out, ObjectStats *stats)
     fprintf(out, "Object allocations over 4 kbytes: %" PRIu64 "\n", stats->allocations_big);
     fprintf(out, "Object frees: %" PRIu64 "\n", stats->frees);
     fprintf(out, "Object new values: %" PRIu64 "\n", stats->new_values);
+    fprintf(out, "Object interpreter increfs: %" PRIu64 "\n", stats->interpreter_increfs);
+    fprintf(out, "Object interpreter decrefs: %" PRIu64 "\n", stats->interpreter_decrefs);
     fprintf(out, "Object increfs: %" PRIu64 "\n", stats->increfs);
     fprintf(out, "Object decrefs: %" PRIu64 "\n", stats->decrefs);
     fprintf(out, "Object materialize dict (on request): %" PRIu64 "\n", stats->dict_materialized_on_request);
diff --git a/Tools/scripts/summarize_stats.py b/Tools/scripts/summarize_stats.py
index f66fc7b684594..3d7479f261b4a 100644
--- a/Tools/scripts/summarize_stats.py
+++ b/Tools/scripts/summarize_stats.py
@@ -272,6 +272,8 @@ def emit_object_stats(stats):
     with Section("Object stats", summary="allocations, frees and dict materializatons"):
         total_materializations = stats.get("Object new values")
         total_allocations = stats.get("Object allocations")
+        total_increfs = stats.get("Object interpreter increfs") + stats.get("Object increfs")
+        total_decrefs = stats.get("Object interpreter decrefs") + stats.get("Object decrefs")
         rows = []
         for key, value in stats.items():
             if key.startswith("Object"):
@@ -279,6 +281,10 @@ def emit_object_stats(stats):
                     ratio = f"{100*value/total_materializations:0.1f}%"
                 elif "allocations" in key:
                     ratio = f"{100*value/total_allocations:0.1f}%"
+                elif "increfs"     in key:
+                    ratio = f"{100*value/total_increfs:0.1f}%"
+                elif "decrefs"     in key:
+                    ratio = f"{100*value/total_decrefs:0.1f}%"
                 else:
                     ratio = ""
                 label = key[6:].strip()



More information about the Python-checkins mailing list