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

This commit is contained in:
Mark Shannon 2022-05-18 14:38:43 +01:00 committed by GitHub
parent 3fa023721b
commit a4460f2eb8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 24 additions and 0 deletions

View File

@ -36,6 +36,8 @@ typedef struct _call_stats {
typedef struct _object_stats { typedef struct _object_stats {
uint64_t increfs; uint64_t increfs;
uint64_t decrefs; uint64_t decrefs;
uint64_t interpreter_increfs;
uint64_t interpreter_decrefs;
uint64_t allocations; uint64_t allocations;
uint64_t allocations512; uint64_t allocations512;
uint64_t allocations4k; uint64_t allocations4k;
@ -60,10 +62,18 @@ PyAPI_DATA(PyStats) _py_stats;
extern void _Py_PrintSpecializationStats(int to_file); 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_INCREF_STAT_INC() _py_stats.object_stats.increfs++
#define _Py_DECREF_STAT_INC() _py_stats.object_stats.decrefs++ #define _Py_DECREF_STAT_INC() _py_stats.object_stats.decrefs++
#endif
#else #else
#define _Py_INCREF_STAT_INC() ((void)0) #define _Py_INCREF_STAT_INC() ((void)0)

View File

@ -1,5 +1,7 @@
/* Generator object implementation */ /* Generator object implementation */
#define _PY_INTERPRETER
#include "Python.h" #include "Python.h"
#include "pycore_call.h" // _PyObject_CallNoArgs() #include "pycore_call.h" // _PyObject_CallNoArgs()
#include "pycore_ceval.h" // _PyEval_EvalFrame() #include "pycore_ceval.h" // _PyEval_EvalFrame()

View File

@ -5,6 +5,8 @@
XXX document it! XXX document it!
*/ */
#define _PY_INTERPRETER
#include "Python.h" #include "Python.h"
#include "pycore_abstract.h" // _PyIndex_Check() #include "pycore_abstract.h" // _PyIndex_Check()
#include "pycore_call.h" // _PyObject_FastCallDictTstate() #include "pycore_call.h" // _PyObject_FastCallDictTstate()

View File

@ -1,4 +1,6 @@
#define _PY_INTERPRETER
#include "Python.h" #include "Python.h"
#include "frameobject.h" #include "frameobject.h"
#include "pycore_code.h" // stats #include "pycore_code.h" // stats

View File

@ -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 allocations over 4 kbytes: %" PRIu64 "\n", stats->allocations_big);
fprintf(out, "Object frees: %" PRIu64 "\n", stats->frees); fprintf(out, "Object frees: %" PRIu64 "\n", stats->frees);
fprintf(out, "Object new values: %" PRIu64 "\n", stats->new_values); 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 increfs: %" PRIu64 "\n", stats->increfs);
fprintf(out, "Object decrefs: %" PRIu64 "\n", stats->decrefs); fprintf(out, "Object decrefs: %" PRIu64 "\n", stats->decrefs);
fprintf(out, "Object materialize dict (on request): %" PRIu64 "\n", stats->dict_materialized_on_request); fprintf(out, "Object materialize dict (on request): %" PRIu64 "\n", stats->dict_materialized_on_request);

View File

@ -272,6 +272,8 @@ def emit_object_stats(stats):
with Section("Object stats", summary="allocations, frees and dict materializatons"): with Section("Object stats", summary="allocations, frees and dict materializatons"):
total_materializations = stats.get("Object new values") total_materializations = stats.get("Object new values")
total_allocations = stats.get("Object allocations") 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 = [] rows = []
for key, value in stats.items(): for key, value in stats.items():
if key.startswith("Object"): if key.startswith("Object"):
@ -279,6 +281,10 @@ def emit_object_stats(stats):
ratio = f"{100*value/total_materializations:0.1f}%" ratio = f"{100*value/total_materializations:0.1f}%"
elif "allocations" in key: elif "allocations" in key:
ratio = f"{100*value/total_allocations:0.1f}%" 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: else:
ratio = "" ratio = ""
label = key[6:].strip() label = key[6:].strip()