[Python-checkins] CVS: python/dist/src/Python ceval.c,2.259,2.260 pystate.c,2.17,2.18
Fred L. Drake
fdrake@users.sourceforge.net
Tue, 03 Jul 2001 16:39:54 -0700
Update of /cvsroot/python/python/dist/src/Python
In directory usw-pr-cvs1:/tmp/cvs-serv21594/Python
Modified Files:
ceval.c pystate.c
Log Message:
This change adjusts the profiling/tracing support so that the common
path (with no profile/trace function) through eval_code2() and
eval_frame() avoids several checks.
In the common cases of calls, returns, and exception propogation,
eval_code2() and eval_frame() used to test two values in the
thread-state: the profiling function and the tracing function. With
this change, a flag is set in the thread-state if either of these is
active, allowing a single check to suffice when both are NULL. This
also simplifies the code needed when either function is in use but is
already active (to avoid profiling/tracing the profiler/tracer); the
flag is set to 0 when the profile/trace code is entered, allowing the
same check to suffice for "already in the tracer" for call/return/
exception events.
Index: ceval.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Python/ceval.c,v
retrieving revision 2.259
retrieving revision 2.260
diff -C2 -r2.259 -r2.260
*** ceval.c 2001/06/27 19:19:46 2.259
--- ceval.c 2001/07/03 23:39:52 2.260
***************
*** 1891,1896 ****
--- 1891,1899 ----
/* Inline call_trace() for performance: */
tstate->tracing++;
+ tstate->use_tracing = 0;
err = (tstate->c_tracefunc)(tstate->c_traceobj, f,
PyTrace_LINE, Py_None);
+ tstate->use_tracing = (tstate->c_tracefunc
+ || tstate->c_profilefunc);
tstate->tracing--;
break;
***************
*** 2143,2152 ****
PyTraceBack_Here(f);
! if (tstate->c_tracefunc)
! call_exc_trace(tstate->c_tracefunc,
! tstate->c_traceobj, f);
! if (tstate->c_profilefunc)
! call_exc_trace(tstate->c_profilefunc,
! tstate->c_profileobj, f);
}
--- 2146,2157 ----
PyTraceBack_Here(f);
! if (tstate->use_tracing) {
! if (tstate->c_tracefunc)
! call_exc_trace(tstate->c_tracefunc,
! tstate->c_traceobj, f);
! if (tstate->c_profilefunc)
! call_exc_trace(tstate->c_profilefunc,
! tstate->c_profileobj,f);
! }
}
***************
*** 2229,2236 ****
retval = NULL;
! if (tstate->c_tracefunc && !tstate->tracing) {
! if (why == WHY_RETURN || why == WHY_YIELD) {
! if (call_trace(tstate->c_tracefunc, tstate->c_traceobj,
! f, PyTrace_RETURN, retval)) {
Py_XDECREF(retval);
retval = NULL;
--- 2234,2243 ----
retval = NULL;
! if (tstate->use_tracing) {
! if (tstate->c_tracefunc
! && (why == WHY_RETURN || why == WHY_YIELD)) {
! if (call_trace(tstate->c_tracefunc,
! tstate->c_traceobj, f,
! PyTrace_RETURN, retval)) {
Py_XDECREF(retval);
retval = NULL;
***************
*** 2238,2250 ****
}
}
! }
!
! if (tstate->c_profilefunc && !tstate->tracing
! && (why == WHY_RETURN || why == WHY_YIELD)) {
! if (call_trace(tstate->c_profilefunc, tstate->c_profileobj,
! f, PyTrace_RETURN, retval)) {
! Py_XDECREF(retval);
! retval = NULL;
! why = WHY_EXCEPTION;
}
}
--- 2245,2257 ----
}
}
! if (tstate->c_profilefunc
! && (why == WHY_RETURN || why == WHY_YIELD)) {
! if (call_trace(tstate->c_profilefunc,
! tstate->c_profileobj, f,
! PyTrace_RETURN, retval)) {
! Py_XDECREF(retval);
! retval = NULL;
! why = WHY_EXCEPTION;
! }
}
}
***************
*** 2472,2504 ****
}
! if (tstate->c_tracefunc != NULL && !tstate->tracing) {
! /* tstate->sys_tracefunc, if defined, is a function that
! will be called on *every* entry to a code block.
! Its return value, if not None, is a function that
! will be called at the start of each executed line
! of code. (Actually, the function must return
! itself in order to continue tracing.)
! The trace functions are called with three arguments:
! a pointer to the current frame, a string indicating
! why the function is called, and an argument which
! depends on the situation. The global trace function
! (sys.trace) is also called whenever an exception
! is detected. */
! if (call_trace(tstate->c_tracefunc, tstate->c_traceobj,
! f, PyTrace_CALL, Py_None)) {
! /* XXX Need way to compute arguments?? */
! /* Trace function raised an error */
! goto fail;
}
! }
!
! if (tstate->c_profilefunc != NULL) {
! /* Similar for sys_profilefunc, except it needn't return
! itself and isn't called for "line" events */
! if (call_trace(tstate->c_profilefunc, tstate->c_profileobj,
! f, PyTrace_CALL, Py_None)) {
! /* XXX Need way to compute arguments?? */
! /* Profile function raised an error */
! goto fail;
}
}
--- 2479,2514 ----
}
! if (tstate->use_tracing) {
! if (tstate->c_tracefunc != NULL) {
! /* tstate->c_tracefunc, if defined, is a
! function that will be called on *every* entry
! to a code block. Its return value, if not
! None, is a function that will be called at
! the start of each executed line of code.
! (Actually, the function must return itself
! in order to continue tracing.) The trace
! functions are called with three arguments:
! a pointer to the current frame, a string
! indicating why the function is called, and
! an argument which depends on the situation.
! The global trace function is also called
! whenever an exception is detected. */
! if (call_trace(tstate->c_tracefunc, tstate->c_traceobj,
! f, PyTrace_CALL, Py_None)) {
! /* XXX Need way to compute arguments?? */
! /* Trace function raised an error */
! goto fail;
! }
}
! if (tstate->c_profilefunc != NULL) {
! /* Similar for c_profilefunc, except it needn't
! return itself and isn't called for "line" events */
! if (call_trace(tstate->c_profilefunc,
! tstate->c_profileobj,
! f, PyTrace_CALL, Py_None)) {
! /* XXX Need way to compute arguments?? */
! /* Profile function raised an error */
! goto fail;
! }
}
}
***************
*** 2804,2808 ****
--- 2814,2821 ----
return 0;
tstate->tracing++;
+ tstate->use_tracing = 0;
result = func(obj, frame, what, arg);
+ tstate->use_tracing = ((tstate->c_tracefunc != NULL)
+ || (tstate->c_profilefunc != NULL));
tstate->tracing--;
return result;
***************
*** 2817,2823 ****
--- 2830,2838 ----
tstate->c_profilefunc = NULL;
tstate->c_profileobj = NULL;
+ tstate->use_tracing = tstate->c_tracefunc != NULL;
Py_XDECREF(temp);
tstate->c_profilefunc = func;
tstate->c_profileobj = arg;
+ tstate->use_tracing = (func != NULL) || (tstate->c_tracefunc != NULL);
}
***************
*** 2830,2836 ****
--- 2845,2854 ----
tstate->c_tracefunc = NULL;
tstate->c_traceobj = NULL;
+ tstate->use_tracing = tstate->c_profilefunc != NULL;
Py_XDECREF(temp);
tstate->c_tracefunc = func;
tstate->c_traceobj = arg;
+ tstate->use_tracing = ((func != NULL)
+ || (tstate->c_profilefunc != NULL));
}
Index: pystate.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Python/pystate.c,v
retrieving revision 2.17
retrieving revision 2.18
diff -C2 -r2.17 -r2.18
*** pystate.c 2001/06/27 19:19:46 2.17
--- pystate.c 2001/07/03 23:39:52 2.18
***************
*** 110,113 ****
--- 110,114 ----
tstate->ticker = 0;
tstate->tracing = 0;
+ tstate->use_tracing = 0;
tstate->dict = NULL;