2020
2121#include <ctype.h>
2222
23- #ifndef WITH_TSC
24-
25- #define READ_TIMESTAMP (var )
26-
27- #else
28-
29- typedef unsigned long long uint64 ;
30-
31- /* PowerPC support.
32- "__ppc__" appears to be the preprocessor definition to detect on OS X, whereas
33- "__powerpc__" appears to be the correct one for Linux with GCC
34- */
35- #if defined(__ppc__ ) || defined (__powerpc__ )
36-
37- #define READ_TIMESTAMP (var ) ppc_getcounter(&var)
38-
39- static void
40- ppc_getcounter (uint64 * v )
41- {
42- unsigned long tbu , tb , tbu2 ;
43-
44- loop :
45- asm volatile ("mftbu %0" : "=r" (tbu ) );
46- asm volatile ("mftb %0" : "=r" (tb ) );
47- asm volatile ("mftbu %0" : "=r" (tbu2 ));
48- if (__builtin_expect (tbu != tbu2 , 0 )) goto loop ;
49-
50- /* The slightly peculiar way of writing the next lines is
51- compiled better by GCC than any other way I tried. */
52- ((long * )(v ))[0 ] = tbu ;
53- ((long * )(v ))[1 ] = tb ;
54- }
55-
56- #elif defined(__i386__ )
57-
58- /* this is for linux/x86 (and probably any other GCC/x86 combo) */
59-
60- #define READ_TIMESTAMP (val ) \
61- __asm__ __volatile__("rdtsc" : "=A" (val))
62-
63- #elif defined(__x86_64__ )
64-
65- /* for gcc/x86_64, the "A" constraint in DI mode means *either* rax *or* rdx;
66- not edx:eax as it does for i386. Since rdtsc puts its result in edx:eax
67- even in 64-bit mode, we need to use "a" and "d" for the lower and upper
68- 32-bit pieces of the result. */
69-
70- #define READ_TIMESTAMP (val ) do { \
71- unsigned int h, l; \
72- __asm__ __volatile__("rdtsc" : "=a" (l), "=d" (h)); \
73- (val) = ((uint64)l) | (((uint64)h) << 32); \
74- } while(0)
75-
76-
77- #else
78-
79- #error "Don't know how to implement timestamp counter for this architecture"
80-
81- #endif
82-
83- void dump_tsc (int opcode , int ticked , uint64 inst0 , uint64 inst1 ,
84- uint64 loop0 , uint64 loop1 , uint64 intr0 , uint64 intr1 )
85- {
86- uint64 intr , inst , loop ;
87- PyThreadState * tstate = PyThreadState_Get ();
88- if (!tstate -> interp -> tscdump )
89- return ;
90- intr = intr1 - intr0 ;
91- inst = inst1 - inst0 - intr ;
92- loop = loop1 - loop0 - intr ;
93- fprintf (stderr , "opcode=%03d t=%d inst=%06lld loop=%06lld\n" ,
94- opcode , ticked , inst , loop );
95- }
96-
97- #endif
98-
9923/* Turn this on if your compiler chokes on the big switch: */
10024/* #define CASE_TOO_BIG 1 */
10125
@@ -108,11 +32,7 @@ void dump_tsc(int opcode, int ticked, uint64 inst0, uint64 inst1,
10832typedef PyObject * (* callproc )(PyObject * , PyObject * , PyObject * );
10933
11034/* Forward declarations */
111- #ifdef WITH_TSC
112- static PyObject * call_function (PyObject * * * , Py_ssize_t , PyObject * , uint64 * , uint64 * );
113- #else
11435static PyObject * call_function (PyObject * * * , Py_ssize_t , PyObject * );
115- #endif
11636static PyObject * fast_function (PyObject * , PyObject * * , Py_ssize_t , PyObject * );
11737static PyObject * do_call_core (PyObject * , PyObject * , PyObject * );
11838
@@ -938,46 +858,6 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag)
938858#define GETITEM (v , i ) PyTuple_GetItem((v), (i))
939859#endif
940860
941- #ifdef WITH_TSC
942- /* Use Pentium timestamp counter to mark certain events:
943- inst0 -- beginning of switch statement for opcode dispatch
944- inst1 -- end of switch statement (may be skipped)
945- loop0 -- the top of the mainloop
946- loop1 -- place where control returns again to top of mainloop
947- (may be skipped)
948- intr1 -- beginning of long interruption
949- intr2 -- end of long interruption
950-
951- Many opcodes call out to helper C functions. In some cases, the
952- time in those functions should be counted towards the time for the
953- opcode, but not in all cases. For example, a CALL_FUNCTION opcode
954- calls another Python function; there's no point in charge all the
955- bytecode executed by the called function to the caller.
956-
957- It's hard to make a useful judgement statically. In the presence
958- of operator overloading, it's impossible to tell if a call will
959- execute new Python code or not.
960-
961- It's a case-by-case judgement. I'll use intr1 for the following
962- cases:
963-
964- IMPORT_STAR
965- IMPORT_FROM
966- CALL_FUNCTION (and friends)
967-
968- */
969- uint64 inst0 , inst1 , loop0 , loop1 , intr0 = 0 , intr1 = 0 ;
970- int ticked = 0 ;
971-
972- READ_TIMESTAMP (inst0 );
973- READ_TIMESTAMP (inst1 );
974- READ_TIMESTAMP (loop0 );
975- READ_TIMESTAMP (loop1 );
976-
977- /* shut up the compiler */
978- opcode = 0 ;
979- #endif
980-
981861/* Code access macros */
982862
983863#ifdef WORDS_BIGENDIAN
@@ -1225,23 +1105,6 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag)
12251105#endif
12261106
12271107 for (;;) {
1228- #ifdef WITH_TSC
1229- if (inst1 == 0 ) {
1230- /* Almost surely, the opcode executed a break
1231- or a continue, preventing inst1 from being set
1232- on the way out of the loop.
1233- */
1234- READ_TIMESTAMP (inst1 );
1235- loop1 = inst1 ;
1236- }
1237- dump_tsc (opcode , ticked , inst0 , inst1 , loop0 , loop1 ,
1238- intr0 , intr1 );
1239- ticked = 0 ;
1240- inst1 = 0 ;
1241- intr0 = 0 ;
1242- intr1 = 0 ;
1243- READ_TIMESTAMP (loop0 );
1244- #endif
12451108 assert (stack_pointer >= f -> f_valuestack ); /* else underflow */
12461109 assert (STACK_LEVEL () <= co -> co_stacksize ); /* else overflow */
12471110 assert (!PyErr_Occurred ());
@@ -1260,9 +1123,6 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag)
12601123 a try: finally: block uninterruptible. */
12611124 goto fast_next_opcode ;
12621125 }
1263- #ifdef WITH_TSC
1264- ticked = 1 ;
1265- #endif
12661126 if (_Py_atomic_load_relaxed (& pendingcalls_to_do )) {
12671127 if (Py_MakePendingCalls () < 0 )
12681128 goto error ;
@@ -3403,11 +3263,7 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag)
34033263 PyObject * * sp , * res ;
34043264 PCALL (PCALL_ALL );
34053265 sp = stack_pointer ;
3406- #ifdef WITH_TSC
3407- res = call_function (& sp , oparg , NULL , & intr0 , & intr1 );
3408- #else
34093266 res = call_function (& sp , oparg , NULL );
3410- #endif
34113267 stack_pointer = sp ;
34123268 PUSH (res );
34133269 if (res == NULL ) {
@@ -3423,11 +3279,7 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag)
34233279 assert (PyTuple_CheckExact (names ) && PyTuple_GET_SIZE (names ) <= oparg );
34243280 PCALL (PCALL_ALL );
34253281 sp = stack_pointer ;
3426- #ifdef WITH_TSC
3427- res = call_function (& sp , oparg , names , & intr0 , & intr1 );
3428- #else
34293282 res = call_function (& sp , oparg , names );
3430- #endif
34313283 stack_pointer = sp ;
34323284 PUSH (res );
34333285 Py_DECREF (names );
@@ -4922,11 +4774,7 @@ if (tstate->use_tracing && tstate->c_profilefunc) { \
49224774 }
49234775
49244776static PyObject *
4925- call_function (PyObject * * * pp_stack , Py_ssize_t oparg , PyObject * kwnames
4926- #ifdef WITH_TSC
4927- , uint64 * pintr0 , uint64 * pintr1
4928- #endif
4929- )
4777+ call_function (PyObject * * * pp_stack , Py_ssize_t oparg , PyObject * kwnames )
49304778{
49314779 PyObject * * pfunc = (* pp_stack ) - oparg - 1 ;
49324780 PyObject * func = * pfunc ;
0 commit comments