mirror of https://github.com/python/cpython
bpo-46072: Merge dxpairs into py_stats. (GH-31197)
This commit is contained in:
parent
a89772c791
commit
9c979d7afd
|
@ -0,0 +1,2 @@
|
|||
Opcode pair stats are now gathered with ``--enable-pystats``. Defining
|
||||
``DYNAMIC_EXECUTION_PROFILE`` or ``DXPAIRS`` no longer has any effect.
|
|
@ -114,16 +114,6 @@ _PyEvalFrameClearAndPop(PyThreadState *tstate, InterpreterFrame *frame);
|
|||
"cannot access free variable '%s' where it is not associated with a" \
|
||||
" value in enclosing scope"
|
||||
|
||||
/* Dynamic execution profile */
|
||||
#ifdef DYNAMIC_EXECUTION_PROFILE
|
||||
#ifdef DXPAIRS
|
||||
static long dxpairs[257][256];
|
||||
#define dxp dxpairs[256]
|
||||
#else
|
||||
static long dxp[256];
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef NDEBUG
|
||||
/* Ensure that tstate is valid: sanity check for PyEval_AcquireThread() and
|
||||
PyEval_RestoreThread(). Detect if tstate memory was freed. It can happen
|
||||
|
@ -1238,10 +1228,6 @@ eval_frame_handle_pending(PyThreadState *tstate)
|
|||
faster than the normal "switch" version, depending on the compiler and the
|
||||
CPU architecture.
|
||||
|
||||
We disable the optimization if DYNAMIC_EXECUTION_PROFILE is defined,
|
||||
because it would render the measurements invalid.
|
||||
|
||||
|
||||
NOTE: care must be taken that the compiler doesn't try to "optimize" the
|
||||
indirect jumps by sharing them between all opcodes. Such optimizations
|
||||
can be disabled on gcc by using the -fno-gcse flag (or possibly
|
||||
|
@ -1253,11 +1239,6 @@ eval_frame_handle_pending(PyThreadState *tstate)
|
|||
* We want to be sure that the compiler knows this before it generates
|
||||
* the CFG.
|
||||
*/
|
||||
#ifdef LLTRACE
|
||||
#define LLTRACE_INSTR() if (lltrace) { lltrace_instruction(frame, opcode, oparg); }
|
||||
#else
|
||||
#define LLTRACE_INSTR() ((void)0)
|
||||
#endif
|
||||
|
||||
#ifdef WITH_DTRACE
|
||||
#define OR_DTRACE_LINE | (PyDTrace_LINE_ENABLED() ? 255 : 0)
|
||||
|
@ -1265,11 +1246,6 @@ eval_frame_handle_pending(PyThreadState *tstate)
|
|||
#define OR_DTRACE_LINE
|
||||
#endif
|
||||
|
||||
#ifdef DYNAMIC_EXECUTION_PROFILE
|
||||
#undef USE_COMPUTED_GOTOS
|
||||
#define USE_COMPUTED_GOTOS 0
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_COMPUTED_GOTOS
|
||||
#ifndef USE_COMPUTED_GOTOS
|
||||
#define USE_COMPUTED_GOTOS 1
|
||||
|
@ -1283,7 +1259,14 @@ eval_frame_handle_pending(PyThreadState *tstate)
|
|||
#endif
|
||||
|
||||
#ifdef Py_STATS
|
||||
#define INSTRUCTION_START(op) frame->f_lasti = INSTR_OFFSET(); next_instr++; OPCODE_EXE_INC(op);
|
||||
#define INSTRUCTION_START(op) \
|
||||
do { \
|
||||
frame->f_lasti = INSTR_OFFSET(); \
|
||||
next_instr++; \
|
||||
OPCODE_EXE_INC(op); \
|
||||
_py_stats.opcode_stats[lastopcode].pair_count[op]++; \
|
||||
lastopcode = op; \
|
||||
} while (0)
|
||||
#else
|
||||
#define INSTRUCTION_START(op) frame->f_lasti = INSTR_OFFSET(); next_instr++
|
||||
#endif
|
||||
|
@ -1296,34 +1279,12 @@ eval_frame_handle_pending(PyThreadState *tstate)
|
|||
#define DISPATCH_GOTO() goto dispatch_opcode
|
||||
#endif
|
||||
|
||||
/* RECORD_DXPROFILE() records the dxprofile information, if enabled. Normally a no-op */
|
||||
#ifdef DYNAMIC_EXECUTION_PROFILE
|
||||
#ifdef DXPAIRS
|
||||
#define RECORD_DXPROFILE() \
|
||||
do { \
|
||||
dxpairs[lastopcode][opcode]++; \
|
||||
lastopcode = opcode; \
|
||||
dxp[opcode]++; \
|
||||
} while (0)
|
||||
/* PRE_DISPATCH_GOTO() does lltrace if enabled. Normally a no-op */
|
||||
#ifdef LLTRACE
|
||||
#define PRE_DISPATCH_GOTO() if (lltrace) { lltrace_instruction(frame, opcode, oparg); }
|
||||
#else
|
||||
#define RECORD_DXPROFILE() \
|
||||
do { \
|
||||
dxp[opcode]++; \
|
||||
} while (0)
|
||||
#endif
|
||||
#else
|
||||
#define RECORD_DXPROFILE() ((void)0)
|
||||
#endif
|
||||
|
||||
/* PRE_DISPATCH_GOTO() does lltrace and dxprofile if either is enabled. Normally a no-op */
|
||||
#ifndef LLTRACE
|
||||
#ifndef DYNAMIC_EXECUTION_PROFILE
|
||||
#define PRE_DISPATCH_GOTO() ((void)0)
|
||||
#endif
|
||||
#endif
|
||||
#ifndef PRE_DISPATCH_GOTO
|
||||
#define PRE_DISPATCH_GOTO() do { LLTRACE_INSTR(); RECORD_DXPROFILE(); } while (0)
|
||||
#endif
|
||||
|
||||
#define NOTRACE_DISPATCH() \
|
||||
{ \
|
||||
|
@ -1403,7 +1364,7 @@ eval_frame_handle_pending(PyThreadState *tstate)
|
|||
|
||||
#define PREDICT_ID(op) PRED_##op
|
||||
|
||||
#if defined(DYNAMIC_EXECUTION_PROFILE) || USE_COMPUTED_GOTOS
|
||||
#if USE_COMPUTED_GOTOS
|
||||
#define PREDICT(op) if (0) goto PREDICT_ID(op)
|
||||
#else
|
||||
#define PREDICT(op) \
|
||||
|
@ -1653,7 +1614,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, InterpreterFrame *frame, int thr
|
|||
#include "opcode_targets.h"
|
||||
#endif
|
||||
|
||||
#ifdef DXPAIRS
|
||||
#ifdef Py_STATS
|
||||
int lastopcode = 0;
|
||||
#endif
|
||||
int opcode; /* Current opcode */
|
||||
|
@ -7489,16 +7450,16 @@ format_awaitable_error(PyThreadState *tstate, PyTypeObject *type, int prevprevpr
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef DYNAMIC_EXECUTION_PROFILE
|
||||
#ifdef Py_STATS
|
||||
|
||||
static PyObject *
|
||||
getarray(long a[256])
|
||||
getarray(uint64_t a[256])
|
||||
{
|
||||
int i;
|
||||
PyObject *l = PyList_New(256);
|
||||
if (l == NULL) return NULL;
|
||||
for (i = 0; i < 256; i++) {
|
||||
PyObject *x = PyLong_FromLong(a[i]);
|
||||
PyObject *x = PyLong_FromUnsignedLongLong(a[i]);
|
||||
if (x == NULL) {
|
||||
Py_DECREF(l);
|
||||
return NULL;
|
||||
|
@ -7513,14 +7474,11 @@ getarray(long a[256])
|
|||
PyObject *
|
||||
_Py_GetDXProfile(PyObject *self, PyObject *args)
|
||||
{
|
||||
#ifndef DXPAIRS
|
||||
return getarray(dxp);
|
||||
#else
|
||||
int i;
|
||||
PyObject *l = PyList_New(257);
|
||||
if (l == NULL) return NULL;
|
||||
for (i = 0; i < 257; i++) {
|
||||
PyObject *x = getarray(dxpairs[i]);
|
||||
PyObject *x = getarray(_py_stats.opcode_stats[i].pair_count);
|
||||
if (x == NULL) {
|
||||
Py_DECREF(l);
|
||||
return NULL;
|
||||
|
@ -7528,7 +7486,6 @@ _Py_GetDXProfile(PyObject *self, PyObject *args)
|
|||
PyList_SET_ITEM(l, i, x);
|
||||
}
|
||||
return l;
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1923,7 +1923,7 @@ sys__debugmallocstats_impl(PyObject *module)
|
|||
extern PyObject *_Py_GetObjects(PyObject *, PyObject *);
|
||||
#endif
|
||||
|
||||
#ifdef DYNAMIC_EXECUTION_PROFILE
|
||||
#ifdef Py_STATS
|
||||
/* Defined in ceval.c because it uses static globals in that file */
|
||||
extern PyObject *_Py_GetDXProfile(PyObject *, PyObject *);
|
||||
#endif
|
||||
|
@ -1992,7 +1992,7 @@ static PyMethodDef sys_methods[] = {
|
|||
SYS_GETDEFAULTENCODING_METHODDEF
|
||||
SYS_GETDLOPENFLAGS_METHODDEF
|
||||
SYS_GETALLOCATEDBLOCKS_METHODDEF
|
||||
#ifdef DYNAMIC_EXECUTION_PROFILE
|
||||
#ifdef Py_STATS
|
||||
{"getdxp", _Py_GetDXProfile, METH_VARARGS},
|
||||
#endif
|
||||
SYS_GETFILESYSTEMENCODING_METHODDEF
|
||||
|
|
Loading…
Reference in New Issue