Exemplo n.º 1
0
static void
Stop(ProfilerObject *pObj, ProfilerContext *self, ProfilerEntry *entry)
{
	PY_LONG_LONG tt = CALL_TIMER(pObj) - self->t0;
	PY_LONG_LONG it = tt - self->subt;
	if (self->previous)
		self->previous->subt += tt;
	pObj->currentProfilerContext = self->previous;
	if (--entry->recursionLevel == 0)
		entry->tt += tt;
	else
		++entry->recursivecallcount;
	entry->it += it;
	entry->callcount++;
	if ((pObj->flags & POF_SUBCALLS) && self->previous) {
		/* find or create an entry for me in my caller's entry */
		ProfilerEntry *caller = self->previous->ctxEntry;
		ProfilerSubEntry *subentry = getSubEntry(pObj, caller, entry);
		if (subentry) {
			if (--subentry->recursionLevel == 0)
				subentry->tt += tt;
			else
				++subentry->recursivecallcount;
			subentry->it += it;
			++subentry->callcount;
		}
	}
}
Exemplo n.º 2
0
static void
initContext(ProfilerObject *pObj, ProfilerContext *self, ProfilerEntry *entry)
{
	self->ctxEntry = entry;
	self->subt = 0;
	self->previous = pObj->currentProfilerContext;
	pObj->currentProfilerContext = self;
	++entry->recursionLevel;
	if ((pObj->flags & POF_SUBCALLS) && self->previous) {
		/* find or create an entry for me in my caller's entry */
		ProfilerEntry *caller = self->previous->ctxEntry;
		ProfilerSubEntry *subentry = getSubEntry(pObj, caller, entry);
		if (subentry == NULL)
			subentry = newSubEntry(pObj, caller, entry);
		if (subentry)
			++subentry->recursionLevel;
	}
	self->t0 = CALL_TIMER(pObj);
}
Exemplo n.º 3
0
static int
profiler_callback(PyObject *self, PyFrameObject *frame, int what,
                  PyObject *arg)
{
    ProfilerObject *pObj = (ProfilerObject*)self;
    {
        /* keep error state, see ptrace_enter_call above.
         * We could keep this more focused, only really needed
         * when calling a user time function, and initializing
         * a user object
         */
        PyObject *et, *ev, *tb;
        PyErr_Fetch(&et, &ev, &tb);
        pObj->currentTime = CALL_TIMER(pObj);
        SelectStack(pObj);
        PyErr_Restore(et, ev, tb);
    }
    if (pObj->currentProfilerStack == NULL)
        return 0;

    switch (what) {

    /* the 'frame' of a called function is about to start its execution */
    case PyTrace_CALL:
        ptrace_enter_call(self, (void *)frame->f_code,
                                (PyObject *)frame->f_code);
        break;

    /* the 'frame' of a called function is about to finish
       (either normally or with an exception) */
    case PyTrace_RETURN:
        ptrace_leave_call(self, (void *)frame->f_code);
        break;

    /* case PyTrace_EXCEPTION:
        If the exception results in the function exiting, a
        PyTrace_RETURN event will be generated, so we don't need to
        handle it. */

#ifdef PyTrace_C_CALL   /* not defined in Python <= 2.3 */
    /* the Python function 'frame' is issuing a call to the built-in
       function 'arg' */
    case PyTrace_C_CALL:
        if ((((ProfilerObject *)self)->flags & POF_BUILTINS)
            && PyCFunction_Check(arg)) {
            ptrace_enter_call(self,
                              ((PyCFunctionObject *)arg)->m_ml,
                              arg);
        }
        break;

    /* the call to the built-in function 'arg' is returning into its
       caller 'frame' */
    case PyTrace_C_RETURN:              /* ...normally */
    case PyTrace_C_EXCEPTION:           /* ...with an exception set */
        if ((((ProfilerObject *)self)->flags & POF_BUILTINS)
            && PyCFunction_Check(arg)) {
            ptrace_leave_call(self,
                              ((PyCFunctionObject *)arg)->m_ml);
        }
        break;
#endif

    default:
        break;
    }
    return 0;
}