Skip to content

Split refcount stats into 'interpreter' and 'non-interpreter' #92919

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 18, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions Include/pystats.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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)
Expand Down
2 changes: 2 additions & 0 deletions Objects/genobject.c
Original file line number Diff line number Diff line change
@@ -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()
Expand Down
2 changes: 2 additions & 0 deletions Python/ceval.c
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down
2 changes: 2 additions & 0 deletions Python/frame.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@

#define _PY_INTERPRETER

#include "Python.h"
#include "frameobject.h"
#include "pycore_code.h" // stats
Expand Down
2 changes: 2 additions & 0 deletions Python/specialize.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
6 changes: 6 additions & 0 deletions Tools/scripts/summarize_stats.py
Original file line number Diff line number Diff line change
Expand Up @@ -272,13 +272,19 @@ 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"):
if "materialize" in key:
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()
Expand Down