[Python-checkins] bpo-46072: Merge dxpairs into py_stats. (GH-31197)
markshannon
webhook-mailer at python.org
Mon Feb 7 11:51:53 EST 2022
https://github.com/python/cpython/commit/9c979d7afd839abbb080028bdfeb73727e5cf633
commit: 9c979d7afd839abbb080028bdfeb73727e5cf633
branch: main
author: Mark Shannon <mark at hotpy.org>
committer: markshannon <mark at hotpy.org>
date: 2022-02-07T16:51:43Z
summary:
bpo-46072: Merge dxpairs into py_stats. (GH-31197)
files:
A Misc/NEWS.d/next/Core and Builtins/2022-02-07-14-38-54.bpo-46072.6ebLyN.rst
M Python/ceval.c
M Python/sysmodule.c
diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-02-07-14-38-54.bpo-46072.6ebLyN.rst b/Misc/NEWS.d/next/Core and Builtins/2022-02-07-14-38-54.bpo-46072.6ebLyN.rst
new file mode 100644
index 0000000000000..288cb56cc205f
--- /dev/null
+++ b/Misc/NEWS.d/next/Core and Builtins/2022-02-07-14-38-54.bpo-46072.6ebLyN.rst
@@ -0,0 +1,2 @@
+Opcode pair stats are now gathered with ``--enable-pystats``. Defining
+``DYNAMIC_EXECUTION_PROFILE`` or ``DXPAIRS`` no longer has any effect.
diff --git a/Python/ceval.c b/Python/ceval.c
index 31b41b848486a..52dbd6e7b0720 100644
--- a/Python/ceval.c
+++ b/Python/ceval.c
@@ -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)
-#else
- #define RECORD_DXPROFILE() \
- do { \
- dxp[opcode]++; \
- } while (0)
-#endif
+/* 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() ((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
diff --git a/Python/sysmodule.c b/Python/sysmodule.c
index 7597ea2ea9e49..acb03781a4f14 100644
--- a/Python/sysmodule.c
+++ b/Python/sysmodule.c
@@ -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
More information about the Python-checkins
mailing list