Back to index

python3.2  3.2.2
Classes | Defines | Typedefs | Functions | Variables
_lsprof.c File Reference
#include "Python.h"
#include "frameobject.h"
#include "rotatingtree.h"
#include <sys/resource.h>
#include <sys/times.h>

Go to the source code of this file.

Classes

struct  _ProfilerSubEntry
struct  _ProfilerEntry
struct  _ProfilerContext
struct  ProfilerObject
struct  statscollector_t

Defines

#define POF_ENABLED   0x001
#define POF_SUBCALLS   0x002
#define POF_BUILTINS   0x004
#define POF_NOMEMORY   0x100
#define PyProfiler_Check(op)   PyObject_TypeCheck(op, &PyProfiler_Type)
#define PyProfiler_CheckExact(op)   (Py_TYPE(op) == &PyProfiler_Type)
#define DOUBLE_TIMER_PRECISION   4294967296.0
#define CALL_TIMER(pObj)

Typedefs

typedef struct _ProfilerSubEntry ProfilerSubEntry
typedef struct _ProfilerEntry ProfilerEntry
typedef struct _ProfilerContext ProfilerContext

Functions

static PY_LONG_LONG hpTimer (void)
static double hpTimerUnit (void)
static PY_LONG_LONG CallExternalTimer (ProfilerObject *pObj)
static PyObjectnormalizeUserObj (PyObject *obj)
static ProfilerEntrynewProfilerEntry (ProfilerObject *pObj, void *key, PyObject *userObj)
static ProfilerEntrygetEntry (ProfilerObject *pObj, void *key)
static ProfilerSubEntrygetSubEntry (ProfilerObject *pObj, ProfilerEntry *caller, ProfilerEntry *entry)
static ProfilerSubEntrynewSubEntry (ProfilerObject *pObj, ProfilerEntry *caller, ProfilerEntry *entry)
static int freeSubEntry (rotating_node_t *header, void *arg)
static int freeEntry (rotating_node_t *header, void *arg)
static void clearEntries (ProfilerObject *pObj)
static void initContext (ProfilerObject *pObj, ProfilerContext *self, ProfilerEntry *entry)
static void Stop (ProfilerObject *pObj, ProfilerContext *self, ProfilerEntry *entry)
static void ptrace_enter_call (PyObject *self, void *key, PyObject *userObj)
static void ptrace_leave_call (PyObject *self, void *key)
static int profiler_callback (PyObject *self, PyFrameObject *frame, int what, PyObject *arg)
static int pending_exception (ProfilerObject *pObj)
static int statsForSubEntry (rotating_node_t *node, void *arg)
static int statsForEntry (rotating_node_t *node, void *arg)
 PyDoc_STRVAR (getstats_doc,"\ getstats() -> list of profiler_entry objects\n\ \n\ Return all information collected by the profiler.\n\ Each profiler_entry is a tuple-like object with the\n\ following attributes:\n\ \n\ code code object\n\ callcount how many times this was called\n\ reccallcount how many times called recursively\n\ totaltime total time in this entry\n\ inlinetime inline time in this entry (not in subcalls)\n\ calls details of the calls\n\ \n\ The calls attribute is either None or a list of\n\ profiler_subentry objects:\n\ \n\ code called code object\n\ callcount how many times this is called\n\ reccallcount how many times this is called recursively\n\ totaltime total time spent in this call\n\ inlinetime inline time (not in further subcalls)\n\ ")
static PyObjectprofiler_getstats (ProfilerObject *pObj, PyObject *noarg)
static int setSubcalls (ProfilerObject *pObj, int nvalue)
static int setBuiltins (ProfilerObject *pObj, int nvalue)
 PyDoc_STRVAR (enable_doc,"\ enable(subcalls=True, builtins=True)\n\ \n\ Start collecting profiling information.\n\ If 'subcalls' is True, also records for each function\n\ statistics separated according to its current caller.\n\ If 'builtins' is True, records the time spent in\n\ built-in functions separately from their caller.\n\ ")
static PyObjectprofiler_enable (ProfilerObject *self, PyObject *args, PyObject *kwds)
static void flush_unmatched (ProfilerObject *pObj)
 PyDoc_STRVAR (disable_doc,"\ disable()\n\ \n\ Stop collecting profiling information.\n\ ")
static PyObjectprofiler_disable (ProfilerObject *self, PyObject *noarg)
 PyDoc_STRVAR (clear_doc,"\ clear()\n\ \n\ Clear all profiling information collected so far.\n\ ")
static PyObjectprofiler_clear (ProfilerObject *pObj, PyObject *noarg)
static void profiler_dealloc (ProfilerObject *op)
static int profiler_init (ProfilerObject *pObj, PyObject *args, PyObject *kw)
 PyDoc_STRVAR (profiler_doc,"\ Profiler(custom_timer=None, time_unit=None, subcalls=True, builtins=True)\n\ \n\ Builds a profiler object using the specified timer function.\n\ The default timer is a fast built-in one based on real time.\n\ For custom timer functions returning integers, time_unit can\n\ be a float specifying a scale (i.e. how long each integer unit\n\ is, in seconds).\n\ ")
PyMODINIT_FUNC PyInit__lsprof (void)

Variables

static PyTypeObject PyProfiler_Type
static PyObjectempty_tuple
static PyStructSequence_Field profiler_entry_fields []
static PyStructSequence_Field profiler_subentry_fields []
static PyStructSequence_Desc profiler_entry_desc
static PyStructSequence_Desc profiler_subentry_desc
static int initialized
static PyTypeObject StatsEntryType
static PyTypeObject StatsSubEntryType
static PyMethodDef profiler_methods []
static PyMethodDef moduleMethods []
static struct PyModuleDef

Class Documentation

struct _ProfilerSubEntry

Definition at line 75 of file _lsprof.c.

Class Members
long callcount
rotating_node_t header
PY_LONG_LONG it
long recursionLevel
long recursivecallcount
PY_LONG_LONG tt
struct _ProfilerEntry

Definition at line 85 of file _lsprof.c.

Collaboration diagram for _ProfilerEntry:
Class Members
long callcount
rotating_node_t * calls
rotating_node_t header
PY_LONG_LONG it
long recursionLevel
long recursivecallcount
PY_LONG_LONG tt
PyObject * userObj
struct _ProfilerContext

Definition at line 96 of file _lsprof.c.

Collaboration diagram for _ProfilerContext:
Class Members
ProfilerEntry * ctxEntry
struct _ProfilerContext * previous
PY_LONG_LONG subt
PY_LONG_LONG t0
struct ProfilerObject

Definition at line 103 of file _lsprof.c.

Collaboration diagram for ProfilerObject:
Class Members
ProfilerContext * currentProfilerContext
PyObject * externalTimer
double externalTimerUnit
int flags
ProfilerContext * freelistProfilerContext
PyObject_HEAD rotating_node_t * profilerEntries
struct statscollector_t

Definition at line 547 of file _lsprof.c.

Collaboration diagram for statscollector_t:
Class Members
double factor
PyObject * list
PyObject * sublist

Define Documentation

#define CALL_TIMER (   pObj)
Value:
((pObj)->externalTimer ?                \
                                        CallExternalTimer(pObj) :       \
                                        hpTimer())

Definition at line 157 of file _lsprof.c.

#define DOUBLE_TIMER_PRECISION   4294967296.0

Definition at line 125 of file _lsprof.c.

#define POF_BUILTINS   0x004

Definition at line 115 of file _lsprof.c.

#define POF_ENABLED   0x001

Definition at line 113 of file _lsprof.c.

#define POF_NOMEMORY   0x100

Definition at line 116 of file _lsprof.c.

#define POF_SUBCALLS   0x002

Definition at line 114 of file _lsprof.c.

Definition at line 120 of file _lsprof.c.

#define PyProfiler_CheckExact (   op)    (Py_TYPE(op) == &PyProfiler_Type)

Definition at line 121 of file _lsprof.c.


Typedef Documentation

typedef struct _ProfilerEntry ProfilerEntry

Function Documentation

static PY_LONG_LONG CallExternalTimer ( ProfilerObject pObj) [static]

Definition at line 128 of file _lsprof.c.

{
    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;
}

Here is the call graph for this function:

static void clearEntries ( ProfilerObject pObj) [static]

Definition at line 309 of file _lsprof.c.

{
    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;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void flush_unmatched ( ProfilerObject pObj) [static]

Definition at line 716 of file _lsprof.c.

{
    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);
    }

}

Here is the call graph for this function:

Here is the caller graph for this function:

static int freeEntry ( rotating_node_t *  header,
void arg 
) [static]

Definition at line 300 of file _lsprof.c.

{
    ProfilerEntry *entry = (ProfilerEntry*) header;
    RotatingTree_Enum(entry->calls, freeSubEntry, NULL);
    Py_DECREF(entry->userObj);
    free(entry);
    return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int freeSubEntry ( rotating_node_t *  header,
void arg 
) [static]

Definition at line 293 of file _lsprof.c.

{
    ProfilerSubEntry *subentry = (ProfilerSubEntry*) header;
    free(subentry);
    return 0;
}

Here is the caller graph for this function:

static ProfilerEntry* getEntry ( ProfilerObject pObj,
void key 
) [static]

Definition at line 262 of file _lsprof.c.

Here is the call graph for this function:

Here is the caller graph for this function:

static ProfilerSubEntry* getSubEntry ( ProfilerObject pObj,
ProfilerEntry caller,
ProfilerEntry entry 
) [static]

Definition at line 268 of file _lsprof.c.

{
    return (ProfilerSubEntry*) RotatingTree_Get(&caller->calls,
                                                (void *)entry);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static PY_LONG_LONG hpTimer ( void  ) [static]

Definition at line 47 of file _lsprof.c.

{
    struct timeval tv;
    PY_LONG_LONG ret;
#ifdef GETTIMEOFDAY_NO_TZ
    gettimeofday(&tv);
#else
    gettimeofday(&tv, (struct timezone *)NULL);
#endif
    ret = tv.tv_sec;
    ret = ret * 1000000 + tv.tv_usec;
    return ret;
}
static double hpTimerUnit ( void  ) [static]

Definition at line 62 of file _lsprof.c.

{
    return 0.000001;
}

Here is the caller graph for this function:

static void initContext ( ProfilerObject pObj,
ProfilerContext self,
ProfilerEntry entry 
) [static]

Definition at line 327 of file _lsprof.c.

{
    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);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static ProfilerEntry* newProfilerEntry ( ProfilerObject pObj,
void key,
PyObject userObj 
) [static]

Definition at line 234 of file _lsprof.c.

{
    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;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static ProfilerSubEntry* newSubEntry ( ProfilerObject pObj,
ProfilerEntry caller,
ProfilerEntry entry 
) [static]

Definition at line 275 of file _lsprof.c.

{
    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;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static PyObject* normalizeUserObj ( PyObject obj) [static]

Definition at line 164 of file _lsprof.c.

{
    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)) {
            /* XXX: The following will truncate module names with embedded
             * null-characters.  It is unlikely that this can happen in
             * practice and the concequences are not serious enough to
             * introduce extra checks here.
             */
            modname = _PyUnicode_AsString(mod);
            if (modname == NULL) {
                modname = "<encoding error>";
                PyErr_Clear();
            }
        }
        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);
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int pending_exception ( ProfilerObject pObj) [static]

Definition at line 496 of file _lsprof.c.

{
    if (pObj->flags & POF_NOMEMORY) {
        pObj->flags -= POF_NOMEMORY;
        PyErr_SetString(PyExc_MemoryError,
                        "memory was exhausted while profiling");
        return -1;
    }
    return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int profiler_callback ( PyObject self,
PyFrameObject frame,
int  what,
PyObject arg 
) [static]

Definition at line 443 of file _lsprof.c.

{
    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;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static PyObject* profiler_clear ( ProfilerObject pObj,
PyObject noarg 
) [static]

Definition at line 756 of file _lsprof.c.

{
    clearEntries(pObj);
    Py_INCREF(Py_None);
    return Py_None;
}

Here is the call graph for this function:

static void profiler_dealloc ( ProfilerObject op) [static]

Definition at line 764 of file _lsprof.c.

Here is the call graph for this function:

static PyObject* profiler_disable ( ProfilerObject self,
PyObject noarg 
) [static]

Definition at line 738 of file _lsprof.c.

{
    self->flags &= ~POF_ENABLED;
    PyEval_SetProfile(NULL, NULL);
    flush_unmatched(self);
    if (pending_exception(self))
        return NULL;
    Py_INCREF(Py_None);
    return Py_None;
}

Here is the call graph for this function:

static PyObject* profiler_enable ( ProfilerObject self,
PyObject args,
PyObject kwds 
) [static]

Definition at line 699 of file _lsprof.c.

{
    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;
}

Here is the call graph for this function:

static PyObject* profiler_getstats ( ProfilerObject pObj,
PyObject noarg 
) [static]

Definition at line 639 of file _lsprof.c.

{
    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;
}

Here is the call graph for this function:

static int profiler_init ( ProfilerObject pObj,
PyObject args,
PyObject kw 
) [static]

Definition at line 775 of file _lsprof.c.

{
    PyObject *o;
    PyObject *timer = NULL;
    double timeunit = 0.0;
    int subcalls = 1;
#ifdef PyTrace_C_CALL
    int builtins = 1;
#else
    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;
}

Here is the call graph for this function:

static void ptrace_enter_call ( PyObject self,
void key,
PyObject userObj 
) [static]

Definition at line 376 of file _lsprof.c.

{
    /* 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);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void ptrace_leave_call ( PyObject self,
void key 
) [static]

Definition at line 420 of file _lsprof.c.

{
    /* 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;
}

Here is the call graph for this function:

Here is the caller graph for this function:

PyDoc_STRVAR ( getstats_doc  ,
"\getstats() -> list of profiler_entry objects\n\\n\Return all information collected by the profiler.\n\Each profiler_entry is a tuple-like object with the\n\following attributes:\n\\n\ code code object\n\ callcount how many times this was called\n\ reccallcount how many times called recursively\n\ totaltime total time in this entry\n\ inlinetime inline time in this entry (not in subcalls)\n\ calls details of the calls\n\\n\The calls attribute is either None or a list of\n\profiler_subentry objects:\n\\n\ code called code object\n\ callcount how many times this is called\n\ reccallcount how many times this is called recursively\n\ totaltime total time spent in this call\n\ inlinetime inline time (not in further subcalls)\n\"   
)
PyDoc_STRVAR ( enable_doc  ,
"\enable(subcalls=True, builtins=True)\n\\n\Start collecting profiling information.\n\If 'subcalls' is  True,
also records for each function\n\statistics separated according to its current caller.\n\If 'builtins'is  True,
records the time spent in\n\built-in functions separately from their caller.\n\"   
)
PyDoc_STRVAR ( disable_doc  ,
"\disable()\n\\n\Stop collecting profiling information.\n\"   
)
PyDoc_STRVAR ( clear_doc  ,
"\clear()\n\\n\Clear all profiling information collected so far.\n\"   
)
PyDoc_STRVAR ( profiler_doc  ,
"\Profiler(custom_timer=None, time_unit=None, subcalls=True, builtins=True)\n\\n\ Builds a profiler object using the specified timer function.\n\ The default timer is a fast built-in one based on real time.\n\ For custom timer functions returning  integers,
time_unit can\n\be a float specifying a scale(i.e.how long each integer unit\n\is, in seconds).\n\"   
)

Definition at line 886 of file _lsprof.c.

Here is the call graph for this function:

static int setBuiltins ( ProfilerObject pObj,
int  nvalue 
) [static]

Definition at line 672 of file _lsprof.c.

{
    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;
#else
        pObj->flags |=  POF_BUILTINS;
#endif
    }
    return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int setSubcalls ( ProfilerObject pObj,
int  nvalue 
) [static]

Definition at line 662 of file _lsprof.c.

{
    if (nvalue == 0)
        pObj->flags &= ~POF_SUBCALLS;
    else if (nvalue > 0)
        pObj->flags |=  POF_SUBCALLS;
    return 0;
}

Here is the caller graph for this function:

static int statsForEntry ( rotating_node_t *  node,
void arg 
) [static]

Definition at line 574 of file _lsprof.c.

{
    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;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int statsForSubEntry ( rotating_node_t *  node,
void arg 
) [static]

Definition at line 553 of file _lsprof.c.

{
    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;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void Stop ( ProfilerObject pObj,
ProfilerContext self,
ProfilerEntry entry 
) [static]

Definition at line 347 of file _lsprof.c.

{
    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;
        }
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:


Variable Documentation

PyObject* empty_tuple [static]

Definition at line 126 of file _lsprof.c.

int initialized [static]

Definition at line 542 of file _lsprof.c.

Initial value:
 {
    {NULL, NULL}
}

Definition at line 868 of file _lsprof.c.

Initial value:
 {
    "_lsprof.profiler_entry", 
    NULL, 
    profiler_entry_fields,
    6
}

Definition at line 528 of file _lsprof.c.

Initial value:
 {
    {"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}
}

Definition at line 509 of file _lsprof.c.

Initial value:
 {
    {"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}
}

Definition at line 804 of file _lsprof.c.

Initial value:
 {
    "_lsprof.profiler_subentry", 
    NULL, 
    profiler_subentry_fields,
    5
}

Definition at line 535 of file _lsprof.c.

Initial value:
 {
    {"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}
}

Definition at line 519 of file _lsprof.c.

struct PyModuleDef [static]
Initial value:
 {
    PyModuleDef_HEAD_INIT,
    "_lsprof",
    "Fast profiler",
    -1,
    moduleMethods,
    NULL,
    NULL,
    NULL,
    NULL
}

Definition at line 873 of file _lsprof.c.

static PyTypeObject PyProfiler_Type [static]

Definition at line 118 of file _lsprof.c.

Definition at line 543 of file _lsprof.c.

Definition at line 544 of file _lsprof.c.