static void _call_enter(PyObject *self, PyFrameObject *frame, PyObject *arg, int ccall) { _pit *cp,*pp; _cstackitem *ci; _pit_children_info *pci; if (ccall) { cp = _ccode2pit((PyCFunctionObject *)arg); } else { cp = _code2pit(frame); } // something went wrong. No mem, or another error. we cannot find // a corresponding pit. just run away:) if (!cp) { _log_err(4); return; } // create/update children info if we have a valid parent pp = _get_frame(); if (pp) { pci = _get_child_info(pp, cp); if(!pci) { pci = _add_child_info(pp, cp); } pci->callcount++; incr_rec_level((uintptr_t)pci); } ci = _push_frame(cp); if (!ci) { // runaway! (defensive) _log_err(5); return; } ci->t0 = tickcount(); cp->callcount++; incr_rec_level((uintptr_t)cp); }
static void _call_leave(PyObject *self, PyFrameObject *frame, PyObject *arg, int ccall) { long long elapsed; _pit *cp, *pp, *ppp; _pit_children_info *pci,*ppci; elapsed = _get_frame_elapsed(); // leaving a frame while callstack is empty? cp = _pop_frame(); if (!cp) { return; } // is this the last function in the callstack? pp = _pop_frame(); if (!pp) { cp->ttotal += elapsed; cp->tsubtotal += elapsed; cp->nonrecursive_callcount++; decr_rec_level((uintptr_t)cp); return; } // get children info pci = _get_child_info(pp, cp); if(!pci) { _log_err(6); return; // defensive } // a calls b. b's elapsed time is subtracted from a's tsub and a adds its own elapsed it is leaving. pp->tsubtotal -= elapsed; cp->tsubtotal += elapsed; // a calls b calls c. child c's elapsed time is subtracted from child b's tsub and child b adds its // own elapsed when it is leaving ppp = _get_frame(); if (ppp) { ppci = _get_child_info(ppp, pp); if(!ppci) { _log_err(7); return; } ppci->tsubtotal -= elapsed; } pci->tsubtotal += elapsed; // wait for the top-level function/parent/child to update timing values accordingly. if (get_rec_level((uintptr_t)cp) == 1) { cp->ttotal += elapsed; cp->nonrecursive_callcount++; pci->nonrecursive_callcount++; } if (get_rec_level((uintptr_t)pci) == 1) { pci->ttotal += elapsed; } decr_rec_level((uintptr_t)pci); decr_rec_level((uintptr_t)cp); if (!_push_frame(pp)) { _log_err(8); return; //defensive } }
// create a new handler, put it on the stack, and return it so its // jmp_buf can be filled in by the caller void _push_handler(struct _handler_cons * new_handler) { //errprintf("pushing handler %x\n",(unsigned int)new_handler); new_handler->s.tag = 0; new_handler->s.cleanup = NULL; _push_frame((struct _RuntimeStack *)new_handler); }