Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Next Next commit
Allow stats recording to be turned on or off. WIP.
  • Loading branch information
markshannon committed Jun 14, 2022
commit 4b142e67a4b2110722b9e82df5eee35d104799fb
16 changes: 8 additions & 8 deletions Include/internal/pycore_code.h
Original file line number Diff line number Diff line change
Expand Up @@ -254,16 +254,16 @@ extern int _PyStaticCode_InternStrings(PyCodeObject *co);
#ifdef Py_STATS


#define STAT_INC(opname, name) _py_stats.opcode_stats[opname].specialization.name++
#define STAT_DEC(opname, name) _py_stats.opcode_stats[opname].specialization.name--
#define OPCODE_EXE_INC(opname) _py_stats.opcode_stats[opname].execution_count++
#define CALL_STAT_INC(name) _py_stats.call_stats.name++
#define OBJECT_STAT_INC(name) _py_stats.object_stats.name++
#define STAT_INC(opname, name) do { if (_py_stats) _py_stats->opcode_stats[opname].specialization.name++; } while (0)
#define STAT_DEC(opname, name) do { if (_py_stats) _py_stats->opcode_stats[opname].specialization.name--; } while (0)
#define OPCODE_EXE_INC(opname) do { if (_py_stats) _py_stats->opcode_stats[opname].execution_count++; } while (0)
#define CALL_STAT_INC(name) do { if (_py_stats) _py_stats->call_stats.name++; } while (0)
#define OBJECT_STAT_INC(name) do { if (_py_stats) _py_stats->object_stats.name++; } while (0)
#define OBJECT_STAT_INC_COND(name, cond) \
do { if (cond) _py_stats.object_stats.name++; } while (0)
#define EVAL_CALL_STAT_INC(name) _py_stats.call_stats.eval_calls[name]++
do { if (_py_stats && cond) _py_stats->object_stats.name++; } while (0)
#define EVAL_CALL_STAT_INC(name) do { if (_py_stats) _py_stats->call_stats.eval_calls[name]++; } while (0)
#define EVAL_CALL_STAT_INC_IF_FUNCTION(name, callable) \
do { if (PyFunction_Check(callable)) _py_stats.call_stats.eval_calls[name]++; } while (0)
do { if (_py_stats && PyFunction_Check(callable)) _py_stats->call_stats.eval_calls[name]++; } while (0)

// Used by the _opcode extension which is built as a shared library
PyAPI_FUNC(PyObject*) _Py_GetSpecializationStats(void);
Expand Down
12 changes: 7 additions & 5 deletions Include/pystats.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,19 +73,21 @@ typedef struct _stats {
ObjectStats object_stats;
} PyStats;

PyAPI_DATA(PyStats) _py_stats;

PyAPI_DATA(PyStats) _py_stats_struct;
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++
#define _Py_INCREF_STAT_INC() do { if (_py_stats) _py_stats->object_stats.interpreter_increfs++; } while (0)
#define _Py_DECREF_STAT_INC() do { if (_py_stats) _py_stats->object_stats.interpreter_decrefs++; } while (0)

#else

#define _Py_INCREF_STAT_INC() _py_stats.object_stats.increfs++
#define _Py_DECREF_STAT_INC() _py_stats.object_stats.decrefs++
#define _Py_INCREF_STAT_INC() do { if (_py_stats) _py_stats->object_stats.increfs++; } while (0)
#define _Py_DECREF_STAT_INC() do { if (_py_stats) _py_stats->object_stats.decrefs++; } while (0)

#endif

Expand Down
10 changes: 5 additions & 5 deletions Python/ceval.c
Original file line number Diff line number Diff line change
Expand Up @@ -1310,7 +1310,7 @@ eval_frame_handle_pending(PyThreadState *tstate)
do { \
frame->prev_instr = next_instr++; \
OPCODE_EXE_INC(op); \
_py_stats.opcode_stats[lastopcode].pair_count[op]++; \
if (_py_stats) _py_stats->opcode_stats[lastopcode].pair_count[op]++; \
lastopcode = op; \
} while (0)
#else
Expand Down Expand Up @@ -4339,8 +4339,8 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int
PyObject *iter = TOP();
#ifdef Py_STATS
extern int _PySpecialization_ClassifyIterator(PyObject *);
_py_stats.opcode_stats[FOR_ITER].specialization.failure++;
_py_stats.opcode_stats[FOR_ITER].specialization.failure_kinds[_PySpecialization_ClassifyIterator(iter)]++;
if (_py_stats) _py_stats->opcode_stats[FOR_ITER].specialization.failure++;
if (_py_stats) _py_stats->opcode_stats[FOR_ITER].specialization.failure_kinds[_PySpecialization_ClassifyIterator(iter)]++;
#endif
PyObject *next = (*Py_TYPE(iter)->tp_iternext)(iter);
if (next != NULL) {
Expand Down Expand Up @@ -7744,7 +7744,7 @@ _Py_GetDXProfile(PyObject *self, PyObject *args)
PyObject *l = PyList_New(257);
if (l == NULL) return NULL;
for (i = 0; i < 256; i++) {
PyObject *x = getarray(_py_stats.opcode_stats[i].pair_count);
PyObject *x = getarray(_py_stats_struct.opcode_stats[i].pair_count);
if (x == NULL) {
Py_DECREF(l);
return NULL;
Expand All @@ -7758,7 +7758,7 @@ _Py_GetDXProfile(PyObject *self, PyObject *args)
}
for (i = 0; i < 256; i++) {
PyObject *x = PyLong_FromUnsignedLongLong(
_py_stats.opcode_stats[i].execution_count);
_py_stats_struct.opcode_stats[i].execution_count);
if (x == NULL) {
Py_DECREF(counts);
Py_DECREF(l);
Expand Down
13 changes: 9 additions & 4 deletions Python/specialize.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ uint8_t _PyOpcode_Adaptive[256] = {

Py_ssize_t _Py_QuickenedCount = 0;
#ifdef Py_STATS
PyStats _py_stats = { 0 };
PyStats _py_stats_struct = { 0 };
PyStats *_py_stats = &_py_stats_struct;

#define ADD_STAT_TO_DICT(res, field) \
do { \
Expand Down Expand Up @@ -92,7 +93,7 @@ add_stat_dict(
int opcode,
const char *name) {

SpecializationStats *stats = &_py_stats.opcode_stats[opcode].specialization;
SpecializationStats *stats = &_py_stats_struct.opcode_stats[opcode].specialization;
PyObject *d = stats_to_dict(stats);
if (d == NULL) {
return -1;
Expand Down Expand Up @@ -250,8 +251,12 @@ _Py_PrintSpecializationStats(int to_file)

#ifdef Py_STATS

#define SPECIALIZATION_FAIL(opcode, kind) _py_stats.opcode_stats[opcode].specialization.failure_kinds[kind]++

#define SPECIALIZATION_FAIL(opcode, kind) \
do { \
if (_py_stats) { \
_py_stats->opcode_stats[opcode].specialization.failure_kinds[kind]++; \
} \
} while (0)

#endif
#endif
Expand Down