diff options
Diffstat (limited to 'Modules/_lsprof.c')
-rw-r--r-- | Modules/_lsprof.c | 1170 |
1 files changed, 585 insertions, 585 deletions
diff --git a/Modules/_lsprof.c b/Modules/_lsprof.c index a4951c0..1fd660b 100644 --- a/Modules/_lsprof.c +++ b/Modules/_lsprof.c @@ -17,19 +17,19 @@ static PY_LONG_LONG hpTimer(void) { - LARGE_INTEGER li; - QueryPerformanceCounter(&li); - return li.QuadPart; + LARGE_INTEGER li; + QueryPerformanceCounter(&li); + return li.QuadPart; } static double hpTimerUnit(void) { - LARGE_INTEGER li; - if (QueryPerformanceFrequency(&li)) - return 1.0 / li.QuadPart; - else - return 0.000001; /* unlikely */ + LARGE_INTEGER li; + if (QueryPerformanceFrequency(&li)) + return 1.0 / li.QuadPart; + else + return 0.000001; /* unlikely */ } #else /* !MS_WINDOWS */ @@ -48,22 +48,22 @@ hpTimerUnit(void) static PY_LONG_LONG hpTimer(void) { - struct timeval tv; - PY_LONG_LONG ret; + struct timeval tv; + PY_LONG_LONG ret; #ifdef GETTIMEOFDAY_NO_TZ - gettimeofday(&tv); + gettimeofday(&tv); #else - gettimeofday(&tv, (struct timezone *)NULL); + gettimeofday(&tv, (struct timezone *)NULL); #endif - ret = tv.tv_sec; - ret = ret * 1000000 + tv.tv_usec; - return ret; + ret = tv.tv_sec; + ret = ret * 1000000 + tv.tv_usec; + return ret; } static double hpTimerUnit(void) { - return 0.000001; + return 0.000001; } #endif /* MS_WINDOWS */ @@ -75,41 +75,41 @@ struct _ProfilerEntry; /* represents a function called from another function */ typedef struct _ProfilerSubEntry { - rotating_node_t header; - PY_LONG_LONG tt; - PY_LONG_LONG it; - long callcount; - long recursivecallcount; - long recursionLevel; + rotating_node_t header; + PY_LONG_LONG tt; + PY_LONG_LONG it; + long callcount; + long recursivecallcount; + long recursionLevel; } ProfilerSubEntry; /* represents a function or user defined block */ typedef struct _ProfilerEntry { - rotating_node_t header; - PyObject *userObj; /* PyCodeObject, or a descriptive str for builtins */ - PY_LONG_LONG tt; /* total time in this entry */ - PY_LONG_LONG it; /* inline time in this entry (not in subcalls) */ - long callcount; /* how many times this was called */ - long recursivecallcount; /* how many times called recursively */ - long recursionLevel; - rotating_node_t *calls; + rotating_node_t header; + PyObject *userObj; /* PyCodeObject, or a descriptive str for builtins */ + PY_LONG_LONG tt; /* total time in this entry */ + PY_LONG_LONG it; /* inline time in this entry (not in subcalls) */ + long callcount; /* how many times this was called */ + long recursivecallcount; /* how many times called recursively */ + long recursionLevel; + rotating_node_t *calls; } ProfilerEntry; typedef struct _ProfilerContext { - PY_LONG_LONG t0; - PY_LONG_LONG subt; - struct _ProfilerContext *previous; - ProfilerEntry *ctxEntry; + PY_LONG_LONG t0; + PY_LONG_LONG subt; + struct _ProfilerContext *previous; + ProfilerEntry *ctxEntry; } ProfilerContext; typedef struct { - PyObject_HEAD - rotating_node_t *profilerEntries; - ProfilerContext *currentProfilerContext; - ProfilerContext *freelistProfilerContext; - int flags; - PyObject *externalTimer; - double externalTimerUnit; + PyObject_HEAD + rotating_node_t *profilerEntries; + ProfilerContext *currentProfilerContext; + ProfilerContext *freelistProfilerContext; + int flags; + PyObject *externalTimer; + double externalTimerUnit; } ProfilerObject; #define POF_ENABLED 0x001 @@ -129,407 +129,407 @@ static PyObject *empty_tuple; static PY_LONG_LONG CallExternalTimer(ProfilerObject *pObj) { - PY_LONG_LONG result; - PyObject *o = PyObject_Call(pObj->externalTimer, empty_tuple, NULL); - if (o == NULL) { - PyErr_WriteUnraisable(pObj->externalTimer); - return 0; - } - if (pObj->externalTimerUnit > 0.0) { - /* interpret the result as an integer that will be scaled - in profiler_getstats() */ - result = PyLong_AsLongLong(o); - } - else { - /* interpret the result as a double measured in seconds. - As the profiler works with PY_LONG_LONG internally - we convert it to a large integer */ - double val = PyFloat_AsDouble(o); - /* error handling delayed to the code below */ - result = (PY_LONG_LONG) (val * DOUBLE_TIMER_PRECISION); - } - Py_DECREF(o); - if (PyErr_Occurred()) { - PyErr_WriteUnraisable(pObj->externalTimer); - return 0; - } - return result; + PY_LONG_LONG result; + PyObject *o = PyObject_Call(pObj->externalTimer, empty_tuple, NULL); + if (o == NULL) { + PyErr_WriteUnraisable(pObj->externalTimer); + return 0; + } + if (pObj->externalTimerUnit > 0.0) { + /* interpret the result as an integer that will be scaled + in profiler_getstats() */ + result = PyLong_AsLongLong(o); + } + else { + /* interpret the result as a double measured in seconds. + As the profiler works with PY_LONG_LONG internally + we convert it to a large integer */ + double val = PyFloat_AsDouble(o); + /* error handling delayed to the code below */ + result = (PY_LONG_LONG) (val * DOUBLE_TIMER_PRECISION); + } + Py_DECREF(o); + if (PyErr_Occurred()) { + PyErr_WriteUnraisable(pObj->externalTimer); + return 0; + } + return result; } -#define CALL_TIMER(pObj) ((pObj)->externalTimer ? \ - CallExternalTimer(pObj) : \ - hpTimer()) +#define CALL_TIMER(pObj) ((pObj)->externalTimer ? \ + CallExternalTimer(pObj) : \ + hpTimer()) /*** ProfilerObject ***/ static PyObject * normalizeUserObj(PyObject *obj) { - PyCFunctionObject *fn; - if (!PyCFunction_Check(obj)) { - Py_INCREF(obj); - return obj; - } - /* Replace built-in function objects with a descriptive string - because of built-in methods -- keeping a reference to - __self__ is probably not a good idea. */ - fn = (PyCFunctionObject *)obj; - - if (fn->m_self == NULL) { - /* built-in function: look up the module name */ - PyObject *mod = fn->m_module; - const char *modname; - if (mod && PyUnicode_Check(mod)) { - modname = _PyUnicode_AsString(mod); - } - else if (mod && PyModule_Check(mod)) { - modname = PyModule_GetName(mod); - if (modname == NULL) { - PyErr_Clear(); - modname = "builtins"; - } - } - else { - modname = "builtins"; - } - if (strcmp(modname, "builtins") != 0) - return PyUnicode_FromFormat("<%s.%s>", - modname, - fn->m_ml->ml_name); - else - return PyUnicode_FromFormat("<%s>", - fn->m_ml->ml_name); - } - else { - /* built-in method: try to return - repr(getattr(type(__self__), __name__)) - */ - PyObject *self = fn->m_self; - PyObject *name = PyUnicode_FromString(fn->m_ml->ml_name); - if (name != NULL) { - PyObject *mo = _PyType_Lookup(Py_TYPE(self), name); - Py_XINCREF(mo); - Py_DECREF(name); - if (mo != NULL) { - PyObject *res = PyObject_Repr(mo); - Py_DECREF(mo); - if (res != NULL) - return res; - } - } - PyErr_Clear(); - return PyUnicode_FromFormat("<built-in method %s>", - fn->m_ml->ml_name); - } + PyCFunctionObject *fn; + if (!PyCFunction_Check(obj)) { + Py_INCREF(obj); + return obj; + } + /* Replace built-in function objects with a descriptive string + because of built-in methods -- keeping a reference to + __self__ is probably not a good idea. */ + fn = (PyCFunctionObject *)obj; + + if (fn->m_self == NULL) { + /* built-in function: look up the module name */ + PyObject *mod = fn->m_module; + const char *modname; + if (mod && PyUnicode_Check(mod)) { + modname = _PyUnicode_AsString(mod); + } + else if (mod && PyModule_Check(mod)) { + modname = PyModule_GetName(mod); + if (modname == NULL) { + PyErr_Clear(); + modname = "builtins"; + } + } + else { + modname = "builtins"; + } + if (strcmp(modname, "builtins") != 0) + return PyUnicode_FromFormat("<%s.%s>", + modname, + fn->m_ml->ml_name); + else + return PyUnicode_FromFormat("<%s>", + fn->m_ml->ml_name); + } + else { + /* built-in method: try to return + repr(getattr(type(__self__), __name__)) + */ + PyObject *self = fn->m_self; + PyObject *name = PyUnicode_FromString(fn->m_ml->ml_name); + if (name != NULL) { + PyObject *mo = _PyType_Lookup(Py_TYPE(self), name); + Py_XINCREF(mo); + Py_DECREF(name); + if (mo != NULL) { + PyObject *res = PyObject_Repr(mo); + Py_DECREF(mo); + if (res != NULL) + return res; + } + } + PyErr_Clear(); + return PyUnicode_FromFormat("<built-in method %s>", + fn->m_ml->ml_name); + } } static ProfilerEntry* newProfilerEntry(ProfilerObject *pObj, void *key, PyObject *userObj) { - ProfilerEntry *self; - self = (ProfilerEntry*) malloc(sizeof(ProfilerEntry)); - if (self == NULL) { - pObj->flags |= POF_NOMEMORY; - return NULL; - } - userObj = normalizeUserObj(userObj); - if (userObj == NULL) { - PyErr_Clear(); - free(self); - pObj->flags |= POF_NOMEMORY; - return NULL; - } - self->header.key = key; - self->userObj = userObj; - self->tt = 0; - self->it = 0; - self->callcount = 0; - self->recursivecallcount = 0; - self->recursionLevel = 0; - self->calls = EMPTY_ROTATING_TREE; - RotatingTree_Add(&pObj->profilerEntries, &self->header); - return self; + ProfilerEntry *self; + self = (ProfilerEntry*) malloc(sizeof(ProfilerEntry)); + if (self == NULL) { + pObj->flags |= POF_NOMEMORY; + return NULL; + } + userObj = normalizeUserObj(userObj); + if (userObj == NULL) { + PyErr_Clear(); + free(self); + pObj->flags |= POF_NOMEMORY; + return NULL; + } + self->header.key = key; + self->userObj = userObj; + self->tt = 0; + self->it = 0; + self->callcount = 0; + self->recursivecallcount = 0; + self->recursionLevel = 0; + self->calls = EMPTY_ROTATING_TREE; + RotatingTree_Add(&pObj->profilerEntries, &self->header); + return self; } static ProfilerEntry* getEntry(ProfilerObject *pObj, void *key) { - return (ProfilerEntry*) RotatingTree_Get(&pObj->profilerEntries, key); + return (ProfilerEntry*) RotatingTree_Get(&pObj->profilerEntries, key); } -static ProfilerSubEntry * +static ProfilerSubEntry * getSubEntry(ProfilerObject *pObj, ProfilerEntry *caller, ProfilerEntry* entry) { - return (ProfilerSubEntry*) RotatingTree_Get(&caller->calls, - (void *)entry); + return (ProfilerSubEntry*) RotatingTree_Get(&caller->calls, + (void *)entry); } static ProfilerSubEntry * newSubEntry(ProfilerObject *pObj, ProfilerEntry *caller, ProfilerEntry* entry) { - ProfilerSubEntry *self; - self = (ProfilerSubEntry*) malloc(sizeof(ProfilerSubEntry)); - if (self == NULL) { - pObj->flags |= POF_NOMEMORY; - return NULL; - } - self->header.key = (void *)entry; - self->tt = 0; - self->it = 0; - self->callcount = 0; - self->recursivecallcount = 0; - self->recursionLevel = 0; - RotatingTree_Add(&caller->calls, &self->header); - return self; + ProfilerSubEntry *self; + self = (ProfilerSubEntry*) malloc(sizeof(ProfilerSubEntry)); + if (self == NULL) { + pObj->flags |= POF_NOMEMORY; + return NULL; + } + self->header.key = (void *)entry; + self->tt = 0; + self->it = 0; + self->callcount = 0; + self->recursivecallcount = 0; + self->recursionLevel = 0; + RotatingTree_Add(&caller->calls, &self->header); + return self; } static int freeSubEntry(rotating_node_t *header, void *arg) { - ProfilerSubEntry *subentry = (ProfilerSubEntry*) header; - free(subentry); - return 0; + ProfilerSubEntry *subentry = (ProfilerSubEntry*) header; + free(subentry); + return 0; } static int freeEntry(rotating_node_t *header, void *arg) { - ProfilerEntry *entry = (ProfilerEntry*) header; - RotatingTree_Enum(entry->calls, freeSubEntry, NULL); - Py_DECREF(entry->userObj); - free(entry); - return 0; + ProfilerEntry *entry = (ProfilerEntry*) header; + RotatingTree_Enum(entry->calls, freeSubEntry, NULL); + Py_DECREF(entry->userObj); + free(entry); + return 0; } static void clearEntries(ProfilerObject *pObj) { - RotatingTree_Enum(pObj->profilerEntries, freeEntry, NULL); - pObj->profilerEntries = EMPTY_ROTATING_TREE; - /* release the memory hold by the ProfilerContexts */ - if (pObj->currentProfilerContext) { - free(pObj->currentProfilerContext); - pObj->currentProfilerContext = NULL; - } - while (pObj->freelistProfilerContext) { - ProfilerContext *c = pObj->freelistProfilerContext; - pObj->freelistProfilerContext = c->previous; - free(c); - } - pObj->freelistProfilerContext = NULL; + RotatingTree_Enum(pObj->profilerEntries, freeEntry, NULL); + pObj->profilerEntries = EMPTY_ROTATING_TREE; + /* release the memory hold by the ProfilerContexts */ + if (pObj->currentProfilerContext) { + free(pObj->currentProfilerContext); + pObj->currentProfilerContext = NULL; + } + while (pObj->freelistProfilerContext) { + ProfilerContext *c = pObj->freelistProfilerContext; + pObj->freelistProfilerContext = c->previous; + free(c); + } + pObj->freelistProfilerContext = NULL; } 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); + 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); } 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; - } - } + 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; + } + } } static void ptrace_enter_call(PyObject *self, void *key, PyObject *userObj) { - /* entering a call to the function identified by 'key' - (which can be a PyCodeObject or a PyMethodDef pointer) */ - ProfilerObject *pObj = (ProfilerObject*)self; - ProfilerEntry *profEntry; - ProfilerContext *pContext; - - /* In the case of entering a generator expression frame via a - * throw (gen_send_ex(.., 1)), we may already have an - * Exception set here. We must not mess around with this - * exception, and some of the code under here assumes that - * PyErr_* is its own to mess around with, so we have to - * save and restore any current exception. */ - PyObject *last_type, *last_value, *last_tb; - PyErr_Fetch(&last_type, &last_value, &last_tb); - - profEntry = getEntry(pObj, key); - if (profEntry == NULL) { - profEntry = newProfilerEntry(pObj, key, userObj); - if (profEntry == NULL) - goto restorePyerr; - } - /* grab a ProfilerContext out of the free list */ - pContext = pObj->freelistProfilerContext; - if (pContext) { - pObj->freelistProfilerContext = pContext->previous; - } - else { - /* free list exhausted, allocate a new one */ - pContext = (ProfilerContext*) - malloc(sizeof(ProfilerContext)); - if (pContext == NULL) { - pObj->flags |= POF_NOMEMORY; - goto restorePyerr; - } - } - initContext(pObj, pContext, profEntry); + /* entering a call to the function identified by 'key' + (which can be a PyCodeObject or a PyMethodDef pointer) */ + ProfilerObject *pObj = (ProfilerObject*)self; + ProfilerEntry *profEntry; + ProfilerContext *pContext; + + /* In the case of entering a generator expression frame via a + * throw (gen_send_ex(.., 1)), we may already have an + * Exception set here. We must not mess around with this + * exception, and some of the code under here assumes that + * PyErr_* is its own to mess around with, so we have to + * save and restore any current exception. */ + PyObject *last_type, *last_value, *last_tb; + PyErr_Fetch(&last_type, &last_value, &last_tb); + + profEntry = getEntry(pObj, key); + if (profEntry == NULL) { + profEntry = newProfilerEntry(pObj, key, userObj); + if (profEntry == NULL) + goto restorePyerr; + } + /* grab a ProfilerContext out of the free list */ + pContext = pObj->freelistProfilerContext; + if (pContext) { + pObj->freelistProfilerContext = pContext->previous; + } + else { + /* free list exhausted, allocate a new one */ + pContext = (ProfilerContext*) + malloc(sizeof(ProfilerContext)); + if (pContext == NULL) { + pObj->flags |= POF_NOMEMORY; + goto restorePyerr; + } + } + initContext(pObj, pContext, profEntry); restorePyerr: - PyErr_Restore(last_type, last_value, last_tb); + PyErr_Restore(last_type, last_value, last_tb); } static void ptrace_leave_call(PyObject *self, void *key) { - /* leaving a call to the function identified by 'key' */ - ProfilerObject *pObj = (ProfilerObject*)self; - ProfilerEntry *profEntry; - ProfilerContext *pContext; - - pContext = pObj->currentProfilerContext; - if (pContext == NULL) - return; - profEntry = getEntry(pObj, key); - if (profEntry) { - Stop(pObj, pContext, profEntry); - } - else { - pObj->currentProfilerContext = pContext->previous; - } - /* put pContext into the free list */ - pContext->previous = pObj->freelistProfilerContext; - pObj->freelistProfilerContext = pContext; + /* leaving a call to the function identified by 'key' */ + ProfilerObject *pObj = (ProfilerObject*)self; + ProfilerEntry *profEntry; + ProfilerContext *pContext; + + pContext = pObj->currentProfilerContext; + if (pContext == NULL) + return; + profEntry = getEntry(pObj, key); + if (profEntry) { + Stop(pObj, pContext, profEntry); + } + else { + pObj->currentProfilerContext = pContext->previous; + } + /* put pContext into the free list */ + pContext->previous = pObj->freelistProfilerContext; + pObj->freelistProfilerContext = pContext; } static int profiler_callback(PyObject *self, PyFrameObject *frame, int what, - PyObject *arg) + PyObject *arg) { - 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; + 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; + default: + break; + } + return 0; } static int pending_exception(ProfilerObject *pObj) { - if (pObj->flags & POF_NOMEMORY) { - pObj->flags -= POF_NOMEMORY; - PyErr_SetString(PyExc_MemoryError, - "memory was exhausted while profiling"); - return -1; - } - return 0; + if (pObj->flags & POF_NOMEMORY) { + pObj->flags -= POF_NOMEMORY; + PyErr_SetString(PyExc_MemoryError, + "memory was exhausted while profiling"); + return -1; + } + return 0; } /************************************************************/ static PyStructSequence_Field profiler_entry_fields[] = { - {"code", "code object or built-in function name"}, - {"callcount", "how many times this was called"}, - {"reccallcount", "how many times called recursively"}, - {"totaltime", "total time in this entry"}, - {"inlinetime", "inline time in this entry (not in subcalls)"}, - {"calls", "details of the calls"}, - {0} + {"code", "code object or built-in function name"}, + {"callcount", "how many times this was called"}, + {"reccallcount", "how many times called recursively"}, + {"totaltime", "total time in this entry"}, + {"inlinetime", "inline time in this entry (not in subcalls)"}, + {"calls", "details of the calls"}, + {0} }; static PyStructSequence_Field profiler_subentry_fields[] = { - {"code", "called code object or built-in function name"}, - {"callcount", "how many times this is called"}, - {"reccallcount", "how many times this is called recursively"}, - {"totaltime", "total time spent in this call"}, - {"inlinetime", "inline time (not in further subcalls)"}, - {0} + {"code", "called code object or built-in function name"}, + {"callcount", "how many times this is called"}, + {"reccallcount", "how many times this is called recursively"}, + {"totaltime", "total time spent in this call"}, + {"inlinetime", "inline time (not in further subcalls)"}, + {0} }; static PyStructSequence_Desc profiler_entry_desc = { - "_lsprof.profiler_entry", /* name */ - NULL, /* doc */ - profiler_entry_fields, - 6 + "_lsprof.profiler_entry", /* name */ + NULL, /* doc */ + profiler_entry_fields, + 6 }; static PyStructSequence_Desc profiler_subentry_desc = { - "_lsprof.profiler_subentry", /* name */ - NULL, /* doc */ - profiler_subentry_fields, - 5 + "_lsprof.profiler_subentry", /* name */ + NULL, /* doc */ + profiler_subentry_fields, + 5 }; static int initialized; @@ -538,70 +538,70 @@ static PyTypeObject StatsSubEntryType; typedef struct { - PyObject *list; - PyObject *sublist; - double factor; + PyObject *list; + PyObject *sublist; + double factor; } statscollector_t; static int statsForSubEntry(rotating_node_t *node, void *arg) { - ProfilerSubEntry *sentry = (ProfilerSubEntry*) node; - statscollector_t *collect = (statscollector_t*) arg; - ProfilerEntry *entry = (ProfilerEntry*) sentry->header.key; - int err; - PyObject *sinfo; - sinfo = PyObject_CallFunction((PyObject*) &StatsSubEntryType, - "((Olldd))", - entry->userObj, - sentry->callcount, - sentry->recursivecallcount, - collect->factor * sentry->tt, - collect->factor * sentry->it); - if (sinfo == NULL) - return -1; - err = PyList_Append(collect->sublist, sinfo); - Py_DECREF(sinfo); - return err; + ProfilerSubEntry *sentry = (ProfilerSubEntry*) node; + statscollector_t *collect = (statscollector_t*) arg; + ProfilerEntry *entry = (ProfilerEntry*) sentry->header.key; + int err; + PyObject *sinfo; + sinfo = PyObject_CallFunction((PyObject*) &StatsSubEntryType, + "((Olldd))", + entry->userObj, + sentry->callcount, + sentry->recursivecallcount, + collect->factor * sentry->tt, + collect->factor * sentry->it); + if (sinfo == NULL) + return -1; + err = PyList_Append(collect->sublist, sinfo); + Py_DECREF(sinfo); + return err; } static int statsForEntry(rotating_node_t *node, void *arg) { - ProfilerEntry *entry = (ProfilerEntry*) node; - statscollector_t *collect = (statscollector_t*) arg; - PyObject *info; - int err; - if (entry->callcount == 0) - return 0; /* skip */ - - if (entry->calls != EMPTY_ROTATING_TREE) { - collect->sublist = PyList_New(0); - if (collect->sublist == NULL) - return -1; - if (RotatingTree_Enum(entry->calls, - statsForSubEntry, collect) != 0) { - Py_DECREF(collect->sublist); - return -1; - } - } - else { - Py_INCREF(Py_None); - collect->sublist = Py_None; - } - - info = PyObject_CallFunction((PyObject*) &StatsEntryType, - "((OllddO))", - entry->userObj, - entry->callcount, - entry->recursivecallcount, - collect->factor * entry->tt, - collect->factor * entry->it, - collect->sublist); - Py_DECREF(collect->sublist); - if (info == NULL) - return -1; - err = PyList_Append(collect->list, info); - Py_DECREF(info); - return err; + ProfilerEntry *entry = (ProfilerEntry*) node; + statscollector_t *collect = (statscollector_t*) arg; + PyObject *info; + int err; + if (entry->callcount == 0) + return 0; /* skip */ + + if (entry->calls != EMPTY_ROTATING_TREE) { + collect->sublist = PyList_New(0); + if (collect->sublist == NULL) + return -1; + if (RotatingTree_Enum(entry->calls, + statsForSubEntry, collect) != 0) { + Py_DECREF(collect->sublist); + return -1; + } + } + else { + Py_INCREF(Py_None); + collect->sublist = Py_None; + } + + info = PyObject_CallFunction((PyObject*) &StatsEntryType, + "((OllddO))", + entry->userObj, + entry->callcount, + entry->recursivecallcount, + collect->factor * entry->tt, + collect->factor * entry->it, + collect->sublist); + Py_DECREF(collect->sublist); + if (info == NULL) + return -1; + err = PyList_Append(collect->list, info); + Py_DECREF(info); + return err; } PyDoc_STRVAR(getstats_doc, "\ @@ -631,51 +631,51 @@ profiler_subentry objects:\n\ static PyObject* profiler_getstats(ProfilerObject *pObj, PyObject* noarg) { - statscollector_t collect; - if (pending_exception(pObj)) - return NULL; - if (!pObj->externalTimer) - collect.factor = hpTimerUnit(); - else if (pObj->externalTimerUnit > 0.0) - collect.factor = pObj->externalTimerUnit; - else - collect.factor = 1.0 / DOUBLE_TIMER_PRECISION; - collect.list = PyList_New(0); - if (collect.list == NULL) - return NULL; - if (RotatingTree_Enum(pObj->profilerEntries, statsForEntry, &collect) - != 0) { - Py_DECREF(collect.list); - return NULL; - } - return collect.list; + statscollector_t collect; + if (pending_exception(pObj)) + return NULL; + if (!pObj->externalTimer) + collect.factor = hpTimerUnit(); + else if (pObj->externalTimerUnit > 0.0) + collect.factor = pObj->externalTimerUnit; + else + collect.factor = 1.0 / DOUBLE_TIMER_PRECISION; + collect.list = PyList_New(0); + if (collect.list == NULL) + return NULL; + if (RotatingTree_Enum(pObj->profilerEntries, statsForEntry, &collect) + != 0) { + Py_DECREF(collect.list); + return NULL; + } + return collect.list; } static int setSubcalls(ProfilerObject *pObj, int nvalue) { - if (nvalue == 0) - pObj->flags &= ~POF_SUBCALLS; - else if (nvalue > 0) - pObj->flags |= POF_SUBCALLS; - return 0; + if (nvalue == 0) + pObj->flags &= ~POF_SUBCALLS; + else if (nvalue > 0) + pObj->flags |= POF_SUBCALLS; + return 0; } static int setBuiltins(ProfilerObject *pObj, int nvalue) { - if (nvalue == 0) - pObj->flags &= ~POF_BUILTINS; - else if (nvalue > 0) { + if (nvalue == 0) + pObj->flags &= ~POF_BUILTINS; + else if (nvalue > 0) { #ifndef PyTrace_C_CALL - PyErr_SetString(PyExc_ValueError, - "builtins=True requires Python >= 2.4"); - return -1; + PyErr_SetString(PyExc_ValueError, + "builtins=True requires Python >= 2.4"); + return -1; #else - pObj->flags |= POF_BUILTINS; + pObj->flags |= POF_BUILTINS; #endif - } - return 0; + } + return 0; } PyDoc_STRVAR(enable_doc, "\ @@ -691,33 +691,33 @@ built-in functions separately from their caller.\n\ static PyObject* profiler_enable(ProfilerObject *self, PyObject *args, PyObject *kwds) { - int subcalls = -1; - int builtins = -1; - static char *kwlist[] = {"subcalls", "builtins", 0}; - if (!PyArg_ParseTupleAndKeywords(args, kwds, "|ii:enable", - kwlist, &subcalls, &builtins)) - return NULL; - if (setSubcalls(self, subcalls) < 0 || setBuiltins(self, builtins) < 0) - return NULL; - PyEval_SetProfile(profiler_callback, (PyObject*)self); - self->flags |= POF_ENABLED; - Py_INCREF(Py_None); - return Py_None; + int subcalls = -1; + int builtins = -1; + static char *kwlist[] = {"subcalls", "builtins", 0}; + if (!PyArg_ParseTupleAndKeywords(args, kwds, "|ii:enable", + kwlist, &subcalls, &builtins)) + return NULL; + if (setSubcalls(self, subcalls) < 0 || setBuiltins(self, builtins) < 0) + return NULL; + PyEval_SetProfile(profiler_callback, (PyObject*)self); + self->flags |= POF_ENABLED; + Py_INCREF(Py_None); + return Py_None; } static void flush_unmatched(ProfilerObject *pObj) { - while (pObj->currentProfilerContext) { - ProfilerContext *pContext = pObj->currentProfilerContext; - ProfilerEntry *profEntry= pContext->ctxEntry; - if (profEntry) - Stop(pObj, pContext, profEntry); - else - pObj->currentProfilerContext = pContext->previous; - if (pContext) - free(pContext); - } + while (pObj->currentProfilerContext) { + ProfilerContext *pContext = pObj->currentProfilerContext; + ProfilerEntry *profEntry= pContext->ctxEntry; + if (profEntry) + Stop(pObj, pContext, profEntry); + else + pObj->currentProfilerContext = pContext->previous; + if (pContext) + free(pContext); + } } @@ -730,13 +730,13 @@ Stop collecting profiling information.\n\ static PyObject* profiler_disable(ProfilerObject *self, PyObject* noarg) { - self->flags &= ~POF_ENABLED; - PyEval_SetProfile(NULL, NULL); - flush_unmatched(self); - if (pending_exception(self)) - return NULL; - Py_INCREF(Py_None); - return Py_None; + self->flags &= ~POF_ENABLED; + PyEval_SetProfile(NULL, NULL); + flush_unmatched(self); + if (pending_exception(self)) + return NULL; + Py_INCREF(Py_None); + return Py_None; } PyDoc_STRVAR(clear_doc, "\ @@ -748,62 +748,62 @@ Clear all profiling information collected so far.\n\ static PyObject* profiler_clear(ProfilerObject *pObj, PyObject* noarg) { - clearEntries(pObj); - Py_INCREF(Py_None); - return Py_None; + clearEntries(pObj); + Py_INCREF(Py_None); + return Py_None; } static void profiler_dealloc(ProfilerObject *op) { - if (op->flags & POF_ENABLED) - PyEval_SetProfile(NULL, NULL); - flush_unmatched(op); - clearEntries(op); - Py_XDECREF(op->externalTimer); - Py_TYPE(op)->tp_free(op); + if (op->flags & POF_ENABLED) + PyEval_SetProfile(NULL, NULL); + flush_unmatched(op); + clearEntries(op); + Py_XDECREF(op->externalTimer); + Py_TYPE(op)->tp_free(op); } static int profiler_init(ProfilerObject *pObj, PyObject *args, PyObject *kw) { - PyObject *o; - PyObject *timer = NULL; - double timeunit = 0.0; - int subcalls = 1; + PyObject *o; + PyObject *timer = NULL; + double timeunit = 0.0; + int subcalls = 1; #ifdef PyTrace_C_CALL - int builtins = 1; + int builtins = 1; #else - int builtins = 0; + int builtins = 0; #endif - static char *kwlist[] = {"timer", "timeunit", - "subcalls", "builtins", 0}; - - if (!PyArg_ParseTupleAndKeywords(args, kw, "|Odii:Profiler", kwlist, - &timer, &timeunit, - &subcalls, &builtins)) - return -1; - - if (setSubcalls(pObj, subcalls) < 0 || setBuiltins(pObj, builtins) < 0) - return -1; - o = pObj->externalTimer; - pObj->externalTimer = timer; - Py_XINCREF(timer); - Py_XDECREF(o); - pObj->externalTimerUnit = timeunit; - return 0; + static char *kwlist[] = {"timer", "timeunit", + "subcalls", "builtins", 0}; + + if (!PyArg_ParseTupleAndKeywords(args, kw, "|Odii:Profiler", kwlist, + &timer, &timeunit, + &subcalls, &builtins)) + return -1; + + if (setSubcalls(pObj, subcalls) < 0 || setBuiltins(pObj, builtins) < 0) + return -1; + o = pObj->externalTimer; + pObj->externalTimer = timer; + Py_XINCREF(timer); + Py_XDECREF(o); + pObj->externalTimerUnit = timeunit; + return 0; } static PyMethodDef profiler_methods[] = { - {"getstats", (PyCFunction)profiler_getstats, - METH_NOARGS, getstats_doc}, - {"enable", (PyCFunction)profiler_enable, - METH_VARARGS | METH_KEYWORDS, enable_doc}, - {"disable", (PyCFunction)profiler_disable, - METH_NOARGS, disable_doc}, - {"clear", (PyCFunction)profiler_clear, - METH_NOARGS, clear_doc}, - {NULL, NULL} + {"getstats", (PyCFunction)profiler_getstats, + METH_NOARGS, getstats_doc}, + {"enable", (PyCFunction)profiler_enable, + METH_VARARGS | METH_KEYWORDS, enable_doc}, + {"disable", (PyCFunction)profiler_disable, + METH_NOARGS, disable_doc}, + {"clear", (PyCFunction)profiler_clear, + METH_NOARGS, clear_doc}, + {NULL, NULL} }; PyDoc_STRVAR(profiler_doc, "\ @@ -817,89 +817,89 @@ Profiler(custom_timer=None, time_unit=None, subcalls=True, builtins=True)\n\ "); static PyTypeObject PyProfiler_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_lsprof.Profiler", /* tp_name */ - sizeof(ProfilerObject), /* tp_basicsize */ - 0, /* tp_itemsize */ - (destructor)profiler_dealloc, /* tp_dealloc */ - 0, /* tp_print */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_reserved */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - 0, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ - profiler_doc, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - profiler_methods, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - (initproc)profiler_init, /* tp_init */ - PyType_GenericAlloc, /* tp_alloc */ - PyType_GenericNew, /* tp_new */ - PyObject_Del, /* tp_free */ + PyVarObject_HEAD_INIT(NULL, 0) + "_lsprof.Profiler", /* tp_name */ + sizeof(ProfilerObject), /* tp_basicsize */ + 0, /* tp_itemsize */ + (destructor)profiler_dealloc, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + profiler_doc, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + profiler_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)profiler_init, /* tp_init */ + PyType_GenericAlloc, /* tp_alloc */ + PyType_GenericNew, /* tp_new */ + PyObject_Del, /* tp_free */ }; static PyMethodDef moduleMethods[] = { - {NULL, NULL} + {NULL, NULL} }; static struct PyModuleDef _lsprofmodule = { - PyModuleDef_HEAD_INIT, - "_lsprof", - "Fast profiler", - -1, - moduleMethods, - NULL, - NULL, - NULL, - NULL + PyModuleDef_HEAD_INIT, + "_lsprof", + "Fast profiler", + -1, + moduleMethods, + NULL, + NULL, + NULL, + NULL }; PyMODINIT_FUNC PyInit__lsprof(void) { - PyObject *module, *d; - module = PyModule_Create(&_lsprofmodule); - if (module == NULL) - return NULL; - d = PyModule_GetDict(module); - if (PyType_Ready(&PyProfiler_Type) < 0) - return NULL; - PyDict_SetItemString(d, "Profiler", (PyObject *)&PyProfiler_Type); - - if (!initialized) { - PyStructSequence_InitType(&StatsEntryType, - &profiler_entry_desc); - PyStructSequence_InitType(&StatsSubEntryType, - &profiler_subentry_desc); - } - Py_INCREF((PyObject*) &StatsEntryType); - Py_INCREF((PyObject*) &StatsSubEntryType); - PyModule_AddObject(module, "profiler_entry", - (PyObject*) &StatsEntryType); - PyModule_AddObject(module, "profiler_subentry", - (PyObject*) &StatsSubEntryType); - empty_tuple = PyTuple_New(0); - initialized = 1; - return module; + PyObject *module, *d; + module = PyModule_Create(&_lsprofmodule); + if (module == NULL) + return NULL; + d = PyModule_GetDict(module); + if (PyType_Ready(&PyProfiler_Type) < 0) + return NULL; + PyDict_SetItemString(d, "Profiler", (PyObject *)&PyProfiler_Type); + + if (!initialized) { + PyStructSequence_InitType(&StatsEntryType, + &profiler_entry_desc); + PyStructSequence_InitType(&StatsSubEntryType, + &profiler_subentry_desc); + } + Py_INCREF((PyObject*) &StatsEntryType); + Py_INCREF((PyObject*) &StatsSubEntryType); + PyModule_AddObject(module, "profiler_entry", + (PyObject*) &StatsEntryType); + PyModule_AddObject(module, "profiler_subentry", + (PyObject*) &StatsSubEntryType); + empty_tuple = PyTuple_New(0); + initialized = 1; + return module; } |