uint64_t pair_count[256];
} OpcodeStats;
+typedef struct _call_stats {
+ uint64_t inlined_py_calls;
+ uint64_t pyeval_calls;
+} CallStats;
+
typedef struct _stats {
OpcodeStats opcode_stats[256];
+ CallStats call_stats;
} PyStats;
extern PyStats _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++
void _Py_PrintSpecializationStats(int to_file);
#define STAT_INC(opname, name) ((void)0)
#define STAT_DEC(opname, name) ((void)0)
#define OPCODE_EXE_INC(opname) ((void)0)
+#define CALL_STAT_INC(name) ((void)0)
#endif
_PyEval_EvalFrameDefault(PyThreadState *tstate, InterpreterFrame *frame, int throwflag)
{
_Py_EnsureTstateNotNULL(tstate);
+ CALL_STAT_INC(pyeval_calls);
#if USE_COMPUTED_GOTOS
/* Import the static jump table */
_PyFrame_SetStackPointer(frame, stack_pointer);
new_frame->previous = frame;
frame = cframe.current_frame = new_frame;
+ CALL_STAT_INC(inlined_py_calls);
goto start_frame;
}
_PyFrame_SetStackPointer(frame, stack_pointer);
new_frame->previous = frame;
cframe.current_frame = frame = new_frame;
+ CALL_STAT_INC(inlined_py_calls);
goto start_frame;
}
/* Callable is not a normal Python function */
_PyFrame_SetStackPointer(frame, stack_pointer);
new_frame->previous = frame;
frame = cframe.current_frame = new_frame;
+ CALL_STAT_INC(inlined_py_calls);
goto start_frame;
}
}
#undef PRINT_STAT
+
+static void
+print_call_stats(FILE *out, CallStats *stats)
+{
+ fprintf(out, "Calls to PyEval_EvalDefault: %" PRIu64 "\n", stats->pyeval_calls);
+ fprintf(out, "Calls to Python functions inlined: %" PRIu64 "\n", stats->inlined_py_calls);
+}
+
static void
print_stats(FILE *out, PyStats *stats) {
print_spec_stats(out, stats->opcode_stats);
+ print_call_stats(out, &stats->call_stats);
}
void
for i, opcode_stat in enumerate(opcode_stats):
name = opname[i]
print_specialization_stats(name, opcode_stat)
+ print("Call stats:")
+ total = 0
+ for key, value in stats.items():
+ if "Calls to" in key:
+ total += value
+ for key, value in stats.items():
+ if "Calls to" in key:
+ print(f"{key}: {value} {100*value/total:0.1f}%")
if __name__ == "__main__":
main()