Ignore:
Timestamp:
Mar 19, 2014, 11:31:01 PM (11 years ago)
Author:
dmik
Message:

python: Merge vendor 2.7.6 to trunk.

Location:
python/trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • python/trunk

  • python/trunk/Modules/_lsprof.c

    r2 r391  
    1818hpTimer(void)
    1919{
    20         LARGE_INTEGER li;
    21         QueryPerformanceCounter(&li);
    22         return li.QuadPart;
     20    LARGE_INTEGER li;
     21    QueryPerformanceCounter(&li);
     22    return li.QuadPart;
    2323}
    2424
     
    2626hpTimerUnit(void)
    2727{
    28         LARGE_INTEGER li;
    29         if (QueryPerformanceFrequency(&li))
    30                 return 1.0 / li.QuadPart;
    31         else
    32                 return 0.000001;  /* unlikely */
     28    LARGE_INTEGER li;
     29    if (QueryPerformanceFrequency(&li))
     30        return 1.0 / li.QuadPart;
     31    else
     32        return 0.000001;  /* unlikely */
    3333}
    3434
     
    4949hpTimer(void)
    5050{
    51         struct timeval tv;
    52         PY_LONG_LONG ret;
     51    struct timeval tv;
     52    PY_LONG_LONG ret;
    5353#ifdef GETTIMEOFDAY_NO_TZ
    54         gettimeofday(&tv);
     54    gettimeofday(&tv);
    5555#else
    56         gettimeofday(&tv, (struct timezone *)NULL);
     56    gettimeofday(&tv, (struct timezone *)NULL);
    5757#endif
    58         ret = tv.tv_sec;
    59         ret = ret * 1000000 + tv.tv_usec;
    60         return ret;
     58    ret = tv.tv_sec;
     59    ret = ret * 1000000 + tv.tv_usec;
     60    return ret;
    6161}
    6262
     
    6464hpTimerUnit(void)
    6565{
    66         return 0.000001;
     66    return 0.000001;
    6767}
    6868
     
    7676/* represents a function called from another function */
    7777typedef struct _ProfilerSubEntry {
    78         rotating_node_t header;
    79         PY_LONG_LONG tt;
    80         PY_LONG_LONG it;
    81         long callcount;
    82         long recursivecallcount;
    83         long recursionLevel;
     78    rotating_node_t header;
     79    PY_LONG_LONG tt;
     80    PY_LONG_LONG it;
     81    long callcount;
     82    long recursivecallcount;
     83    long recursionLevel;
    8484} ProfilerSubEntry;
    8585
    8686/* represents a function or user defined block */
    8787typedef struct _ProfilerEntry {
    88         rotating_node_t header;
    89         PyObject *userObj; /* PyCodeObject, or a descriptive str for builtins */
    90         PY_LONG_LONG tt; /* total time in this entry */
    91         PY_LONG_LONG it; /* inline time in this entry (not in subcalls) */
    92         long callcount; /* how many times this was called */
    93         long recursivecallcount; /* how many times called recursively */
    94         long recursionLevel;
    95         rotating_node_t *calls;
     88    rotating_node_t header;
     89    PyObject *userObj; /* PyCodeObject, or a descriptive str for builtins */
     90    PY_LONG_LONG tt; /* total time in this entry */
     91    PY_LONG_LONG it; /* inline time in this entry (not in subcalls) */
     92    long callcount; /* how many times this was called */
     93    long recursivecallcount; /* how many times called recursively */
     94    long recursionLevel;
     95    rotating_node_t *calls;
    9696} ProfilerEntry;
    9797
    9898typedef struct _ProfilerContext {
    99         PY_LONG_LONG t0;
    100         PY_LONG_LONG subt;
    101         struct _ProfilerContext *previous;
    102         ProfilerEntry *ctxEntry;
     99    PY_LONG_LONG t0;
     100    PY_LONG_LONG subt;
     101    struct _ProfilerContext *previous;
     102    ProfilerEntry *ctxEntry;
    103103} ProfilerContext;
    104104
    105105typedef struct {
    106         PyObject_HEAD
    107         rotating_node_t *profilerEntries;
    108         ProfilerContext *currentProfilerContext;
    109         ProfilerContext *freelistProfilerContext;
    110         int flags;
    111         PyObject *externalTimer;
    112         double externalTimerUnit;
     106    PyObject_HEAD
     107    rotating_node_t *profilerEntries;
     108    ProfilerContext *currentProfilerContext;
     109    ProfilerContext *freelistProfilerContext;
     110    int flags;
     111    PyObject *externalTimer;
     112    double externalTimerUnit;
    113113} ProfilerObject;
    114114
     
    130130static PY_LONG_LONG CallExternalTimer(ProfilerObject *pObj)
    131131{
    132         PY_LONG_LONG result;
    133         PyObject *o = PyObject_Call(pObj->externalTimer, empty_tuple, NULL);
    134         if (o == NULL) {
    135                 PyErr_WriteUnraisable(pObj->externalTimer);
    136                 return 0;
    137         }
    138         if (pObj->externalTimerUnit > 0.0) {
    139                 /* interpret the result as an integer that will be scaled
    140                    in profiler_getstats() */
    141                 result = PyLong_AsLongLong(o);
    142         }
    143         else {
    144                 /* interpret the result as a double measured in seconds.
    145                    As the profiler works with PY_LONG_LONG internally
    146                    we convert it to a large integer */
    147                 double val = PyFloat_AsDouble(o);
    148                 /* error handling delayed to the code below */
    149                 result = (PY_LONG_LONG) (val * DOUBLE_TIMER_PRECISION);
    150         }
    151         Py_DECREF(o);
    152         if (PyErr_Occurred()) {
    153                 PyErr_WriteUnraisable(pObj->externalTimer);
    154                 return 0;
    155         }
    156         return result;
    157 }
    158 
    159 #define CALL_TIMER(pObj)        ((pObj)->externalTimer ?                \
    160                                         CallExternalTimer(pObj) :       \
    161                                         hpTimer())
     132    PY_LONG_LONG result;
     133    PyObject *o = PyObject_Call(pObj->externalTimer, empty_tuple, NULL);
     134    if (o == NULL) {
     135        PyErr_WriteUnraisable(pObj->externalTimer);
     136        return 0;
     137    }
     138    if (pObj->externalTimerUnit > 0.0) {
     139        /* interpret the result as an integer that will be scaled
     140           in profiler_getstats() */
     141        result = PyLong_AsLongLong(o);
     142    }
     143    else {
     144        /* interpret the result as a double measured in seconds.
     145           As the profiler works with PY_LONG_LONG internally
     146           we convert it to a large integer */
     147        double val = PyFloat_AsDouble(o);
     148        /* error handling delayed to the code below */
     149        result = (PY_LONG_LONG) (val * DOUBLE_TIMER_PRECISION);
     150    }
     151    Py_DECREF(o);
     152    if (PyErr_Occurred()) {
     153        PyErr_WriteUnraisable(pObj->externalTimer);
     154        return 0;
     155    }
     156    return result;
     157}
     158
     159#define CALL_TIMER(pObj)        ((pObj)->externalTimer ?                \
     160                                        CallExternalTimer(pObj) :       \
     161                                        hpTimer())
    162162
    163163/*** ProfilerObject ***/
     
    166166normalizeUserObj(PyObject *obj)
    167167{
    168         PyCFunctionObject *fn;
    169         if (!PyCFunction_Check(obj)) {
    170                 Py_INCREF(obj);
    171                 return obj;
    172         }
    173         /* Replace built-in function objects with a descriptive string
    174            because of built-in methods -- keeping a reference to
    175            __self__ is probably not a good idea. */
    176         fn = (PyCFunctionObject *)obj;
    177 
    178         if (fn->m_self == NULL) {
    179                 /* built-in function: look up the module name */
    180                 PyObject *mod = fn->m_module;
    181                 char *modname;
    182                 if (mod && PyString_Check(mod)) {
    183                         modname = PyString_AS_STRING(mod);
    184                 }
    185                 else if (mod && PyModule_Check(mod)) {
    186                         modname = PyModule_GetName(mod);
    187                         if (modname == NULL) {
    188                                 PyErr_Clear();
    189                                 modname = "__builtin__";
    190                         }
    191                 }
    192                 else {
    193                         modname = "__builtin__";
    194                 }
    195                 if (strcmp(modname, "__builtin__") != 0)
    196                         return PyString_FromFormat("<%s.%s>",
    197                                                    modname,
    198                                                    fn->m_ml->ml_name);
    199                 else
    200                         return PyString_FromFormat("<%s>",
    201                                                    fn->m_ml->ml_name);
    202         }
    203         else {
    204                 /* built-in method: try to return
    205                         repr(getattr(type(__self__), __name__))
    206                 */
    207                 PyObject *self = fn->m_self;
    208                 PyObject *name = PyString_FromString(fn->m_ml->ml_name);
    209                 if (name != NULL) {
    210                         PyObject *mo = _PyType_Lookup(Py_TYPE(self), name);
    211                         Py_XINCREF(mo);
    212                         Py_DECREF(name);
    213                         if (mo != NULL) {
    214                                 PyObject *res = PyObject_Repr(mo);
    215                                 Py_DECREF(mo);
    216                                 if (res != NULL)
    217                                         return res;
    218                         }
    219                 }
    220                 PyErr_Clear();
    221                 return PyString_FromFormat("<built-in method %s>",
    222                                            fn->m_ml->ml_name);
    223         }
     168    PyCFunctionObject *fn;
     169    if (!PyCFunction_Check(obj)) {
     170        Py_INCREF(obj);
     171        return obj;
     172    }
     173    /* Replace built-in function objects with a descriptive string
     174       because of built-in methods -- keeping a reference to
     175       __self__ is probably not a good idea. */
     176    fn = (PyCFunctionObject *)obj;
     177
     178    if (fn->m_self == NULL) {
     179        /* built-in function: look up the module name */
     180        PyObject *mod = fn->m_module;
     181        char *modname;
     182        if (mod && PyString_Check(mod)) {
     183            modname = PyString_AS_STRING(mod);
     184        }
     185        else if (mod && PyModule_Check(mod)) {
     186            modname = PyModule_GetName(mod);
     187            if (modname == NULL) {
     188                PyErr_Clear();
     189                modname = "__builtin__";
     190            }
     191        }
     192        else {
     193            modname = "__builtin__";
     194        }
     195        if (strcmp(modname, "__builtin__") != 0)
     196            return PyString_FromFormat("<%s.%s>",
     197                                       modname,
     198                                       fn->m_ml->ml_name);
     199        else
     200            return PyString_FromFormat("<%s>",
     201                                       fn->m_ml->ml_name);
     202    }
     203    else {
     204        /* built-in method: try to return
     205            repr(getattr(type(__self__), __name__))
     206        */
     207        PyObject *self = fn->m_self;
     208        PyObject *name = PyString_FromString(fn->m_ml->ml_name);
     209        if (name != NULL) {
     210            PyObject *mo = _PyType_Lookup(Py_TYPE(self), name);
     211            Py_XINCREF(mo);
     212            Py_DECREF(name);
     213            if (mo != NULL) {
     214                PyObject *res = PyObject_Repr(mo);
     215                Py_DECREF(mo);
     216                if (res != NULL)
     217                    return res;
     218            }
     219        }
     220        PyErr_Clear();
     221        return PyString_FromFormat("<built-in method %s>",
     222                                   fn->m_ml->ml_name);
     223    }
    224224}
    225225
     
    227227newProfilerEntry(ProfilerObject *pObj, void *key, PyObject *userObj)
    228228{
    229         ProfilerEntry *self;
    230         self = (ProfilerEntry*) malloc(sizeof(ProfilerEntry));
    231         if (self == NULL) {
    232                 pObj->flags |= POF_NOMEMORY;
    233                 return NULL;
    234         }
    235         userObj = normalizeUserObj(userObj);
    236         if (userObj == NULL) {
    237                 PyErr_Clear();
    238                 free(self);
    239                 pObj->flags |= POF_NOMEMORY;
    240                 return NULL;
    241         }
    242         self->header.key = key;
    243         self->userObj = userObj;
    244         self->tt = 0;
    245         self->it = 0;
    246         self->callcount = 0;
    247         self->recursivecallcount = 0;
    248         self->recursionLevel = 0;
    249         self->calls = EMPTY_ROTATING_TREE;
    250         RotatingTree_Add(&pObj->profilerEntries, &self->header);
    251         return self;
     229    ProfilerEntry *self;
     230    self = (ProfilerEntry*) malloc(sizeof(ProfilerEntry));
     231    if (self == NULL) {
     232        pObj->flags |= POF_NOMEMORY;
     233        return NULL;
     234    }
     235    userObj = normalizeUserObj(userObj);
     236    if (userObj == NULL) {
     237        PyErr_Clear();
     238        free(self);
     239        pObj->flags |= POF_NOMEMORY;
     240        return NULL;
     241    }
     242    self->header.key = key;
     243    self->userObj = userObj;
     244    self->tt = 0;
     245    self->it = 0;
     246    self->callcount = 0;
     247    self->recursivecallcount = 0;
     248    self->recursionLevel = 0;
     249    self->calls = EMPTY_ROTATING_TREE;
     250    RotatingTree_Add(&pObj->profilerEntries, &self->header);
     251    return self;
    252252}
    253253
     
    255255getEntry(ProfilerObject *pObj, void *key)
    256256{
    257         return (ProfilerEntry*) RotatingTree_Get(&pObj->profilerEntries, key);
    258 }
    259 
    260 static ProfilerSubEntry * 
     257    return (ProfilerEntry*) RotatingTree_Get(&pObj->profilerEntries, key);
     258}
     259
     260static ProfilerSubEntry *
    261261getSubEntry(ProfilerObject *pObj, ProfilerEntry *caller, ProfilerEntry* entry)
    262262{
    263         return (ProfilerSubEntry*) RotatingTree_Get(&caller->calls,
    264                                                     (void *)entry);
     263    return (ProfilerSubEntry*) RotatingTree_Get(&caller->calls,
     264                                                (void *)entry);
    265265}
    266266
     
    268268newSubEntry(ProfilerObject *pObj,  ProfilerEntry *caller, ProfilerEntry* entry)
    269269{
    270         ProfilerSubEntry *self;
    271         self = (ProfilerSubEntry*) malloc(sizeof(ProfilerSubEntry));
    272         if (self == NULL) {
    273                 pObj->flags |= POF_NOMEMORY;
    274                 return NULL;
    275         }
    276         self->header.key = (void *)entry;
    277         self->tt = 0;
    278         self->it = 0;
    279         self->callcount = 0;
    280         self->recursivecallcount = 0;
    281         self->recursionLevel = 0;
    282         RotatingTree_Add(&caller->calls, &self->header);
    283         return self;
     270    ProfilerSubEntry *self;
     271    self = (ProfilerSubEntry*) malloc(sizeof(ProfilerSubEntry));
     272    if (self == NULL) {
     273        pObj->flags |= POF_NOMEMORY;
     274        return NULL;
     275    }
     276    self->header.key = (void *)entry;
     277    self->tt = 0;
     278    self->it = 0;
     279    self->callcount = 0;
     280    self->recursivecallcount = 0;
     281    self->recursionLevel = 0;
     282    RotatingTree_Add(&caller->calls, &self->header);
     283    return self;
    284284}
    285285
    286286static int freeSubEntry(rotating_node_t *header, void *arg)
    287287{
    288         ProfilerSubEntry *subentry = (ProfilerSubEntry*) header;
    289         free(subentry);
    290         return 0;
     288    ProfilerSubEntry *subentry = (ProfilerSubEntry*) header;
     289    free(subentry);
     290    return 0;
    291291}
    292292
    293293static int freeEntry(rotating_node_t *header, void *arg)
    294294{
    295         ProfilerEntry *entry = (ProfilerEntry*) header;
    296         RotatingTree_Enum(entry->calls, freeSubEntry, NULL);
    297         Py_DECREF(entry->userObj);
    298         free(entry);
    299         return 0;
     295    ProfilerEntry *entry = (ProfilerEntry*) header;
     296    RotatingTree_Enum(entry->calls, freeSubEntry, NULL);
     297    Py_DECREF(entry->userObj);
     298    free(entry);
     299    return 0;
    300300}
    301301
    302302static void clearEntries(ProfilerObject *pObj)
    303303{
    304         RotatingTree_Enum(pObj->profilerEntries, freeEntry, NULL);
    305         pObj->profilerEntries = EMPTY_ROTATING_TREE;
    306         /* release the memory hold by the free list of ProfilerContexts */
    307         while (pObj->freelistProfilerContext) {
    308                 ProfilerContext *c = pObj->freelistProfilerContext;
    309                 pObj->freelistProfilerContext = c->previous;
    310                 free(c);
    311         }
     304    RotatingTree_Enum(pObj->profilerEntries, freeEntry, NULL);
     305    pObj->profilerEntries = EMPTY_ROTATING_TREE;
     306    /* release the memory hold by the ProfilerContexts */
     307    if (pObj->currentProfilerContext) {
     308        free(pObj->currentProfilerContext);
     309        pObj->currentProfilerContext = NULL;
     310    }
     311    while (pObj->freelistProfilerContext) {
     312        ProfilerContext *c = pObj->freelistProfilerContext;
     313        pObj->freelistProfilerContext = c->previous;
     314        free(c);
     315    }
     316    pObj->freelistProfilerContext = NULL;
    312317}
    313318
     
    315320initContext(ProfilerObject *pObj, ProfilerContext *self, ProfilerEntry *entry)
    316321{
    317         self->ctxEntry = entry;
    318         self->subt = 0;
    319         self->previous = pObj->currentProfilerContext;
    320         pObj->currentProfilerContext = self;
    321         ++entry->recursionLevel;
    322         if ((pObj->flags & POF_SUBCALLS) && self->previous) {
    323                 /* find or create an entry for me in my caller's entry */
    324                 ProfilerEntry *caller = self->previous->ctxEntry;
    325                 ProfilerSubEntry *subentry = getSubEntry(pObj, caller, entry);
    326                 if (subentry == NULL)
    327                         subentry = newSubEntry(pObj, caller, entry);
    328                 if (subentry)
    329                         ++subentry->recursionLevel;
    330         }
    331         self->t0 = CALL_TIMER(pObj);
     322    self->ctxEntry = entry;
     323    self->subt = 0;
     324    self->previous = pObj->currentProfilerContext;
     325    pObj->currentProfilerContext = self;
     326    ++entry->recursionLevel;
     327    if ((pObj->flags & POF_SUBCALLS) && self->previous) {
     328        /* find or create an entry for me in my caller's entry */
     329        ProfilerEntry *caller = self->previous->ctxEntry;
     330        ProfilerSubEntry *subentry = getSubEntry(pObj, caller, entry);
     331        if (subentry == NULL)
     332            subentry = newSubEntry(pObj, caller, entry);
     333        if (subentry)
     334            ++subentry->recursionLevel;
     335    }
     336    self->t0 = CALL_TIMER(pObj);
    332337}
    333338
     
    335340Stop(ProfilerObject *pObj, ProfilerContext *self, ProfilerEntry *entry)
    336341{
    337         PY_LONG_LONG tt = CALL_TIMER(pObj) - self->t0;
    338         PY_LONG_LONG it = tt - self->subt;
    339         if (self->previous)
    340                 self->previous->subt += tt;
    341         pObj->currentProfilerContext = self->previous;
    342         if (--entry->recursionLevel == 0)
    343                 entry->tt += tt;
    344         else
    345                 ++entry->recursivecallcount;
    346         entry->it += it;
    347         entry->callcount++;
    348         if ((pObj->flags & POF_SUBCALLS) && self->previous) {
    349                 /* find or create an entry for me in my caller's entry */
    350                 ProfilerEntry *caller = self->previous->ctxEntry;
    351                 ProfilerSubEntry *subentry = getSubEntry(pObj, caller, entry);
    352                 if (subentry) {
    353                         if (--subentry->recursionLevel == 0)
    354                                 subentry->tt += tt;
    355                         else
    356                                 ++subentry->recursivecallcount;
    357                         subentry->it += it;
    358                         ++subentry->callcount;
    359                 }
    360         }
     342    PY_LONG_LONG tt = CALL_TIMER(pObj) - self->t0;
     343    PY_LONG_LONG it = tt - self->subt;
     344    if (self->previous)
     345        self->previous->subt += tt;
     346    pObj->currentProfilerContext = self->previous;
     347    if (--entry->recursionLevel == 0)
     348        entry->tt += tt;
     349    else
     350        ++entry->recursivecallcount;
     351    entry->it += it;
     352    entry->callcount++;
     353    if ((pObj->flags & POF_SUBCALLS) && self->previous) {
     354        /* find or create an entry for me in my caller's entry */
     355        ProfilerEntry *caller = self->previous->ctxEntry;
     356        ProfilerSubEntry *subentry = getSubEntry(pObj, caller, entry);
     357        if (subentry) {
     358            if (--subentry->recursionLevel == 0)
     359                subentry->tt += tt;
     360            else
     361                ++subentry->recursivecallcount;
     362            subentry->it += it;
     363            ++subentry->callcount;
     364        }
     365    }
    361366}
    362367
     
    364369ptrace_enter_call(PyObject *self, void *key, PyObject *userObj)
    365370{
    366         /* entering a call to the function identified by 'key'
    367            (which can be a PyCodeObject or a PyMethodDef pointer) */
    368         ProfilerObject *pObj = (ProfilerObject*)self;
    369         ProfilerEntry *profEntry;
    370         ProfilerContext *pContext;
    371 
    372         /* In the case of entering a generator expression frame via a
    373         * throw (gen_send_ex(.., 1)), we may already have an
    374         * Exception set here. We must not mess around with this
    375         * exception, and some of the code under here assumes that
    376         * PyErr_* is its own to mess around with, so we have to
    377         * save and restore any current exception. */
    378         PyObject *last_type, *last_value, *last_tb;
    379         PyErr_Fetch(&last_type, &last_value, &last_tb);
    380 
    381         profEntry = getEntry(pObj, key);
    382         if (profEntry == NULL) {
    383                 profEntry = newProfilerEntry(pObj, key, userObj);
    384                 if (profEntry == NULL)
    385                         goto restorePyerr;
    386         }
    387         /* grab a ProfilerContext out of the free list */
    388         pContext = pObj->freelistProfilerContext;
    389         if (pContext) {
    390                 pObj->freelistProfilerContext = pContext->previous;
    391         }
    392         else {
    393                 /* free list exhausted, allocate a new one */
    394                 pContext = (ProfilerContext*)
    395                         malloc(sizeof(ProfilerContext));
    396                 if (pContext == NULL) {
    397                         pObj->flags |= POF_NOMEMORY;
    398                         goto restorePyerr;
    399                 }
    400         }
    401         initContext(pObj, pContext, profEntry);
     371    /* entering a call to the function identified by 'key'
     372       (which can be a PyCodeObject or a PyMethodDef pointer) */
     373    ProfilerObject *pObj = (ProfilerObject*)self;
     374    ProfilerEntry *profEntry;
     375    ProfilerContext *pContext;
     376
     377    /* In the case of entering a generator expression frame via a
     378    * throw (gen_send_ex(.., 1)), we may already have an
     379    * Exception set here. We must not mess around with this
     380    * exception, and some of the code under here assumes that
     381    * PyErr_* is its own to mess around with, so we have to
     382    * save and restore any current exception. */
     383    PyObject *last_type, *last_value, *last_tb;
     384    PyErr_Fetch(&last_type, &last_value, &last_tb);
     385
     386    profEntry = getEntry(pObj, key);
     387    if (profEntry == NULL) {
     388        profEntry = newProfilerEntry(pObj, key, userObj);
     389        if (profEntry == NULL)
     390            goto restorePyerr;
     391    }
     392    /* grab a ProfilerContext out of the free list */
     393    pContext = pObj->freelistProfilerContext;
     394    if (pContext) {
     395        pObj->freelistProfilerContext = pContext->previous;
     396    }
     397    else {
     398        /* free list exhausted, allocate a new one */
     399        pContext = (ProfilerContext*)
     400            malloc(sizeof(ProfilerContext));
     401        if (pContext == NULL) {
     402            pObj->flags |= POF_NOMEMORY;
     403            goto restorePyerr;
     404        }
     405    }
     406    initContext(pObj, pContext, profEntry);
    402407
    403408restorePyerr:
    404         PyErr_Restore(last_type, last_value, last_tb);
     409    PyErr_Restore(last_type, last_value, last_tb);
    405410}
    406411
     
    408413ptrace_leave_call(PyObject *self, void *key)
    409414{
    410         /* leaving a call to the function identified by 'key' */
    411         ProfilerObject *pObj = (ProfilerObject*)self;
    412         ProfilerEntry *profEntry;
    413         ProfilerContext *pContext;
    414 
    415         pContext = pObj->currentProfilerContext;
    416         if (pContext == NULL)
    417                 return;
    418         profEntry = getEntry(pObj, key);
    419         if (profEntry) {
    420                 Stop(pObj, pContext, profEntry);
    421         }
    422         else {
    423                 pObj->currentProfilerContext = pContext->previous;
    424         }
    425         /* put pContext into the free list */
    426         pContext->previous = pObj->freelistProfilerContext;
    427         pObj->freelistProfilerContext = pContext;
     415    /* leaving a call to the function identified by 'key' */
     416    ProfilerObject *pObj = (ProfilerObject*)self;
     417    ProfilerEntry *profEntry;
     418    ProfilerContext *pContext;
     419
     420    pContext = pObj->currentProfilerContext;
     421    if (pContext == NULL)
     422        return;
     423    profEntry = getEntry(pObj, key);
     424    if (profEntry) {
     425        Stop(pObj, pContext, profEntry);
     426    }
     427    else {
     428        pObj->currentProfilerContext = pContext->previous;
     429    }
     430    /* put pContext into the free list */
     431    pContext->previous = pObj->freelistProfilerContext;
     432    pObj->freelistProfilerContext = pContext;
    428433}
    429434
    430435static int
    431436profiler_callback(PyObject *self, PyFrameObject *frame, int what,
    432                   PyObject *arg)
    433 {
    434         switch (what) {
    435 
    436         /* the 'frame' of a called function is about to start its execution */
    437         case PyTrace_CALL:
    438                 ptrace_enter_call(self, (void *)frame->f_code,
    439                                         (PyObject *)frame->f_code);
    440                 break;
    441 
    442         /* the 'frame' of a called function is about to finish
    443            (either normally or with an exception) */
    444         case PyTrace_RETURN:
    445                 ptrace_leave_call(self, (void *)frame->f_code);
    446                 break;
    447 
    448         /* case PyTrace_EXCEPTION:
    449                 If the exception results in the function exiting, a
    450                 PyTrace_RETURN event will be generated, so we don't need to
    451                 handle it. */
    452 
    453 #ifdef PyTrace_C_CALL   /* not defined in Python <= 2.3 */
    454         /* the Python function 'frame' is issuing a call to the built-in
    455            function 'arg' */
    456         case PyTrace_C_CALL:
    457                 if ((((ProfilerObject *)self)->flags & POF_BUILTINS)
    458                     && PyCFunction_Check(arg)) {
    459                         ptrace_enter_call(self,
    460                                           ((PyCFunctionObject *)arg)->m_ml,
    461                                           arg);
    462                 }
    463                 break;
    464 
    465         /* the call to the built-in function 'arg' is returning into its
    466            caller 'frame' */
    467         case PyTrace_C_RETURN:          /* ...normally */
    468         case PyTrace_C_EXCEPTION:       /* ...with an exception set */
    469                 if ((((ProfilerObject *)self)->flags & POF_BUILTINS)
    470                     && PyCFunction_Check(arg)) {
    471                         ptrace_leave_call(self,
    472                                           ((PyCFunctionObject *)arg)->m_ml);
    473                 }
    474                 break;
     437                  PyObject *arg)
     438{
     439    switch (what) {
     440
     441    /* the 'frame' of a called function is about to start its execution */
     442    case PyTrace_CALL:
     443        ptrace_enter_call(self, (void *)frame->f_code,
     444                                (PyObject *)frame->f_code);
     445        break;
     446
     447    /* the 'frame' of a called function is about to finish
     448       (either normally or with an exception) */
     449    case PyTrace_RETURN:
     450        ptrace_leave_call(self, (void *)frame->f_code);
     451        break;
     452
     453    /* case PyTrace_EXCEPTION:
     454        If the exception results in the function exiting, a
     455        PyTrace_RETURN event will be generated, so we don't need to
     456        handle it. */
     457
     458#ifdef PyTrace_C_CALL   /* not defined in Python <= 2.3 */
     459    /* the Python function 'frame' is issuing a call to the built-in
     460       function 'arg' */
     461    case PyTrace_C_CALL:
     462        if ((((ProfilerObject *)self)->flags & POF_BUILTINS)
     463            && PyCFunction_Check(arg)) {
     464            ptrace_enter_call(self,
     465                              ((PyCFunctionObject *)arg)->m_ml,
     466                              arg);
     467        }
     468        break;
     469
     470    /* the call to the built-in function 'arg' is returning into its
     471       caller 'frame' */
     472    case PyTrace_C_RETURN:              /* ...normally */
     473    case PyTrace_C_EXCEPTION:           /* ...with an exception set */
     474        if ((((ProfilerObject *)self)->flags & POF_BUILTINS)
     475            && PyCFunction_Check(arg)) {
     476            ptrace_leave_call(self,
     477                              ((PyCFunctionObject *)arg)->m_ml);
     478        }
     479        break;
    475480#endif
    476481
    477         default:
    478                 break;
    479         }
    480         return 0;
     482    default:
     483        break;
     484    }
     485    return 0;
    481486}
    482487
     
    484489pending_exception(ProfilerObject *pObj)
    485490{
    486         if (pObj->flags & POF_NOMEMORY) {
    487                 pObj->flags -= POF_NOMEMORY;
    488                 PyErr_SetString(PyExc_MemoryError,
    489                                 "memory was exhausted while profiling");
    490                 return -1;
    491         }
    492         return 0;
     491    if (pObj->flags & POF_NOMEMORY) {
     492        pObj->flags -= POF_NOMEMORY;
     493        PyErr_SetString(PyExc_MemoryError,
     494                        "memory was exhausted while profiling");
     495        return -1;
     496    }
     497    return 0;
    493498}
    494499
     
    496501
    497502static PyStructSequence_Field profiler_entry_fields[] = {
    498         {"code",         "code object or built-in function name"},
    499         {"callcount",    "how many times this was called"},
    500         {"reccallcount", "how many times called recursively"},
    501         {"totaltime",    "total time in this entry"},
    502         {"inlinetime",   "inline time in this entry (not in subcalls)"},
    503         {"calls",        "details of the calls"},
    504         {0}
     503    {"code",         "code object or built-in function name"},
     504    {"callcount",    "how many times this was called"},
     505    {"reccallcount", "how many times called recursively"},
     506    {"totaltime",    "total time in this entry"},
     507    {"inlinetime",   "inline time in this entry (not in subcalls)"},
     508    {"calls",        "details of the calls"},
     509    {0}
    505510};
    506511
    507512static PyStructSequence_Field profiler_subentry_fields[] = {
    508         {"code",         "called code object or built-in function name"},
    509         {"callcount",    "how many times this is called"},
    510         {"reccallcount", "how many times this is called recursively"},
    511         {"totaltime",    "total time spent in this call"},
    512         {"inlinetime",   "inline time (not in further subcalls)"},
    513         {0}
     513    {"code",         "called code object or built-in function name"},
     514    {"callcount",    "how many times this is called"},
     515    {"reccallcount", "how many times this is called recursively"},
     516    {"totaltime",    "total time spent in this call"},
     517    {"inlinetime",   "inline time (not in further subcalls)"},
     518    {0}
    514519};
    515520
    516521static PyStructSequence_Desc profiler_entry_desc = {
    517         "_lsprof.profiler_entry", /* name */
    518         NULL, /* doc */
    519         profiler_entry_fields,
    520         6
     522    "_lsprof.profiler_entry", /* name */
     523    NULL, /* doc */
     524    profiler_entry_fields,
     525    6
    521526};
    522527
    523528static PyStructSequence_Desc profiler_subentry_desc = {
    524         "_lsprof.profiler_subentry", /* name */
    525         NULL, /* doc */
    526         profiler_subentry_fields,
    527         5
     529    "_lsprof.profiler_subentry", /* name */
     530    NULL, /* doc */
     531    profiler_subentry_fields,
     532    5
    528533};
    529534
     
    534539
    535540typedef struct {
    536         PyObject *list;
    537         PyObject *sublist;
    538         double factor;
     541    PyObject *list;
     542    PyObject *sublist;
     543    double factor;
    539544} statscollector_t;
    540545
    541546static int statsForSubEntry(rotating_node_t *node, void *arg)
    542547{
    543         ProfilerSubEntry *sentry = (ProfilerSubEntry*) node;
    544         statscollector_t *collect = (statscollector_t*) arg;
    545         ProfilerEntry *entry = (ProfilerEntry*) sentry->header.key;
    546         int err;
    547         PyObject *sinfo;
    548         sinfo = PyObject_CallFunction((PyObject*) &StatsSubEntryType,
    549                                       "((Olldd))",
    550                                       entry->userObj,
    551                                       sentry->callcount,
    552                                       sentry->recursivecallcount,
    553                                       collect->factor * sentry->tt,
    554                                       collect->factor * sentry->it);
    555         if (sinfo == NULL)
    556                 return -1;
    557         err = PyList_Append(collect->sublist, sinfo);
    558         Py_DECREF(sinfo);
    559         return err;
     548    ProfilerSubEntry *sentry = (ProfilerSubEntry*) node;
     549    statscollector_t *collect = (statscollector_t*) arg;
     550    ProfilerEntry *entry = (ProfilerEntry*) sentry->header.key;
     551    int err;
     552    PyObject *sinfo;
     553    sinfo = PyObject_CallFunction((PyObject*) &StatsSubEntryType,
     554                                  "((Olldd))",
     555                                  entry->userObj,
     556                                  sentry->callcount,
     557                                  sentry->recursivecallcount,
     558                                  collect->factor * sentry->tt,
     559                                  collect->factor * sentry->it);
     560    if (sinfo == NULL)
     561        return -1;
     562    err = PyList_Append(collect->sublist, sinfo);
     563    Py_DECREF(sinfo);
     564    return err;
    560565}
    561566
    562567static int statsForEntry(rotating_node_t *node, void *arg)
    563568{
    564         ProfilerEntry *entry = (ProfilerEntry*) node;
    565         statscollector_t *collect = (statscollector_t*) arg;
    566         PyObject *info;
    567         int err;
    568         if (entry->callcount == 0)
    569                 return 0;   /* skip */
    570 
    571         if (entry->calls != EMPTY_ROTATING_TREE) {
    572                 collect->sublist = PyList_New(0);
    573                 if (collect->sublist == NULL)
    574                         return -1;
    575                 if (RotatingTree_Enum(entry->calls,
    576                                       statsForSubEntry, collect) != 0) {
    577                         Py_DECREF(collect->sublist);
    578                         return -1;
    579                 }
    580         }
    581         else {
    582                 Py_INCREF(Py_None);
    583                 collect->sublist = Py_None;
    584         }
    585 
    586         info = PyObject_CallFunction((PyObject*) &StatsEntryType,
    587                                      "((OllddO))",
    588                                      entry->userObj,
    589                                      entry->callcount,
    590                                      entry->recursivecallcount,
    591                                      collect->factor * entry->tt,
    592                                      collect->factor * entry->it,
    593                                      collect->sublist);
    594         Py_DECREF(collect->sublist);
    595         if (info == NULL)
    596                 return -1;
    597         err = PyList_Append(collect->list, info);
    598         Py_DECREF(info);
    599         return err;
     569    ProfilerEntry *entry = (ProfilerEntry*) node;
     570    statscollector_t *collect = (statscollector_t*) arg;
     571    PyObject *info;
     572    int err;
     573    if (entry->callcount == 0)
     574        return 0;   /* skip */
     575
     576    if (entry->calls != EMPTY_ROTATING_TREE) {
     577        collect->sublist = PyList_New(0);
     578        if (collect->sublist == NULL)
     579            return -1;
     580        if (RotatingTree_Enum(entry->calls,
     581                              statsForSubEntry, collect) != 0) {
     582            Py_DECREF(collect->sublist);
     583            return -1;
     584        }
     585    }
     586    else {
     587        Py_INCREF(Py_None);
     588        collect->sublist = Py_None;
     589    }
     590
     591    info = PyObject_CallFunction((PyObject*) &StatsEntryType,
     592                                 "((OllddO))",
     593                                 entry->userObj,
     594                                 entry->callcount,
     595                                 entry->recursivecallcount,
     596                                 collect->factor * entry->tt,
     597                                 collect->factor * entry->it,
     598                                 collect->sublist);
     599    Py_DECREF(collect->sublist);
     600    if (info == NULL)
     601        return -1;
     602    err = PyList_Append(collect->list, info);
     603    Py_DECREF(info);
     604    return err;
    600605}
    601606
     
    627632profiler_getstats(ProfilerObject *pObj, PyObject* noarg)
    628633{
    629         statscollector_t collect;
    630         if (pending_exception(pObj))
    631                 return NULL;
    632         if (!pObj->externalTimer)
    633                 collect.factor = hpTimerUnit();
    634         else if (pObj->externalTimerUnit > 0.0)
    635                 collect.factor = pObj->externalTimerUnit;
    636         else
    637                 collect.factor = 1.0 / DOUBLE_TIMER_PRECISION;
    638         collect.list = PyList_New(0);
    639         if (collect.list == NULL)
    640                 return NULL;
    641         if (RotatingTree_Enum(pObj->profilerEntries, statsForEntry, &collect)
    642             != 0) {
    643                 Py_DECREF(collect.list);
    644                 return NULL;
    645         }
    646         return collect.list;
     634    statscollector_t collect;
     635    if (pending_exception(pObj))
     636        return NULL;
     637    if (!pObj->externalTimer)
     638        collect.factor = hpTimerUnit();
     639    else if (pObj->externalTimerUnit > 0.0)
     640        collect.factor = pObj->externalTimerUnit;
     641    else
     642        collect.factor = 1.0 / DOUBLE_TIMER_PRECISION;
     643    collect.list = PyList_New(0);
     644    if (collect.list == NULL)
     645        return NULL;
     646    if (RotatingTree_Enum(pObj->profilerEntries, statsForEntry, &collect)
     647        != 0) {
     648        Py_DECREF(collect.list);
     649        return NULL;
     650    }
     651    return collect.list;
    647652}
    648653
     
    650655setSubcalls(ProfilerObject *pObj, int nvalue)
    651656{
    652         if (nvalue == 0)
    653                 pObj->flags &= ~POF_SUBCALLS;
    654         else if (nvalue > 0)
    655                 pObj->flags |=  POF_SUBCALLS;
    656         return 0;
     657    if (nvalue == 0)
     658        pObj->flags &= ~POF_SUBCALLS;
     659    else if (nvalue > 0)
     660        pObj->flags |=  POF_SUBCALLS;
     661    return 0;
    657662}
    658663
     
    660665setBuiltins(ProfilerObject *pObj, int nvalue)
    661666{
    662         if (nvalue == 0)
    663                 pObj->flags &= ~POF_BUILTINS;
    664         else if (nvalue > 0) {
     667    if (nvalue == 0)
     668        pObj->flags &= ~POF_BUILTINS;
     669    else if (nvalue > 0) {
    665670#ifndef PyTrace_C_CALL
    666                 PyErr_SetString(PyExc_ValueError,
    667                                 "builtins=True requires Python >= 2.4");
    668                 return -1;
     671        PyErr_SetString(PyExc_ValueError,
     672                        "builtins=True requires Python >= 2.4");
     673        return -1;
    669674#else
    670                 pObj->flags |=  POF_BUILTINS;
     675        pObj->flags |=  POF_BUILTINS;
    671676#endif
    672         }
    673         return 0;
     677    }
     678    return 0;
    674679}
    675680
     
    687692profiler_enable(ProfilerObject *self, PyObject *args, PyObject *kwds)
    688693{
    689         int subcalls = -1;
    690         int builtins = -1;
    691         static char *kwlist[] = {"subcalls", "builtins", 0};
    692         if (!PyArg_ParseTupleAndKeywords(args, kwds, "|ii:enable",
    693                                         kwlist, &subcalls, &builtins))
    694                 return NULL;
    695         if (setSubcalls(self, subcalls) < 0 || setBuiltins(self, builtins) < 0)
    696                 return NULL;
    697         PyEval_SetProfile(profiler_callback, (PyObject*)self);
    698         self->flags |= POF_ENABLED;
    699         Py_INCREF(Py_None);
    700         return Py_None;
     694    int subcalls = -1;
     695    int builtins = -1;
     696    static char *kwlist[] = {"subcalls", "builtins", 0};
     697    if (!PyArg_ParseTupleAndKeywords(args, kwds, "|ii:enable",
     698                                    kwlist, &subcalls, &builtins))
     699        return NULL;
     700    if (setSubcalls(self, subcalls) < 0 || setBuiltins(self, builtins) < 0)
     701        return NULL;
     702    PyEval_SetProfile(profiler_callback, (PyObject*)self);
     703    self->flags |= POF_ENABLED;
     704    Py_INCREF(Py_None);
     705    return Py_None;
    701706}
    702707
     
    704709flush_unmatched(ProfilerObject *pObj)
    705710{
    706         while (pObj->currentProfilerContext) {
    707                 ProfilerContext *pContext = pObj->currentProfilerContext;
    708                 ProfilerEntry *profEntry= pContext->ctxEntry;
    709                 if (profEntry)
    710                         Stop(pObj, pContext, profEntry);
    711                 else
    712                         pObj->currentProfilerContext = pContext->previous;
    713                 if (pContext)
    714                         free(pContext);
    715         }
     711    while (pObj->currentProfilerContext) {
     712        ProfilerContext *pContext = pObj->currentProfilerContext;
     713        ProfilerEntry *profEntry= pContext->ctxEntry;
     714        if (profEntry)
     715            Stop(pObj, pContext, profEntry);
     716        else
     717            pObj->currentProfilerContext = pContext->previous;
     718        if (pContext)
     719            free(pContext);
     720    }
    716721
    717722}
     
    726731profiler_disable(ProfilerObject *self, PyObject* noarg)
    727732{
    728         self->flags &= ~POF_ENABLED;
    729         PyEval_SetProfile(NULL, NULL);
    730         flush_unmatched(self);
    731         if (pending_exception(self))
    732                 return NULL;
    733         Py_INCREF(Py_None);
    734         return Py_None;
     733    self->flags &= ~POF_ENABLED;
     734    PyEval_SetProfile(NULL, NULL);
     735    flush_unmatched(self);
     736    if (pending_exception(self))
     737        return NULL;
     738    Py_INCREF(Py_None);
     739    return Py_None;
    735740}
    736741
     
    744749profiler_clear(ProfilerObject *pObj, PyObject* noarg)
    745750{
    746         clearEntries(pObj);
    747         Py_INCREF(Py_None);
    748         return Py_None;
     751    clearEntries(pObj);
     752    Py_INCREF(Py_None);
     753    return Py_None;
    749754}
    750755
     
    752757profiler_dealloc(ProfilerObject *op)
    753758{
    754         if (op->flags & POF_ENABLED)
    755                 PyEval_SetProfile(NULL, NULL);
    756         flush_unmatched(op);
    757         clearEntries(op);
    758         Py_XDECREF(op->externalTimer);
    759         Py_TYPE(op)->tp_free(op);
     759    if (op->flags & POF_ENABLED)
     760        PyEval_SetProfile(NULL, NULL);
     761    flush_unmatched(op);
     762    clearEntries(op);
     763    Py_XDECREF(op->externalTimer);
     764    Py_TYPE(op)->tp_free(op);
    760765}
    761766
     
    763768profiler_init(ProfilerObject *pObj, PyObject *args, PyObject *kw)
    764769{
    765         PyObject *o;
    766         PyObject *timer = NULL;
    767         double timeunit = 0.0;
    768         int subcalls = 1;
     770    PyObject *o;
     771    PyObject *timer = NULL;
     772    double timeunit = 0.0;
     773    int subcalls = 1;
    769774#ifdef PyTrace_C_CALL
    770         int builtins = 1;
     775    int builtins = 1;
    771776#else
    772         int builtins = 0;
     777    int builtins = 0;
    773778#endif
    774         static char *kwlist[] = {"timer", "timeunit",
    775                                        "subcalls", "builtins", 0};
    776 
    777         if (!PyArg_ParseTupleAndKeywords(args, kw, "|Odii:Profiler", kwlist,
    778                                         &timer, &timeunit,
    779                                         &subcalls, &builtins))
    780                 return -1;
    781 
    782         if (setSubcalls(pObj, subcalls) < 0 || setBuiltins(pObj, builtins) < 0)
    783                 return -1;
    784         o = pObj->externalTimer;
    785         pObj->externalTimer = timer;
    786         Py_XINCREF(timer);
    787         Py_XDECREF(o);
    788         pObj->externalTimerUnit = timeunit;
    789         return 0;
     779    static char *kwlist[] = {"timer", "timeunit",
     780                                   "subcalls", "builtins", 0};
     781
     782    if (!PyArg_ParseTupleAndKeywords(args, kw, "|Odii:Profiler", kwlist,
     783                                    &timer, &timeunit,
     784                                    &subcalls, &builtins))
     785        return -1;
     786
     787    if (setSubcalls(pObj, subcalls) < 0 || setBuiltins(pObj, builtins) < 0)
     788        return -1;
     789    o = pObj->externalTimer;
     790    pObj->externalTimer = timer;
     791    Py_XINCREF(timer);
     792    Py_XDECREF(o);
     793    pObj->externalTimerUnit = timeunit;
     794    return 0;
    790795}
    791796
    792797static PyMethodDef profiler_methods[] = {
    793         {"getstats",    (PyCFunction)profiler_getstats,
    794                         METH_NOARGS,                    getstats_doc},
    795         {"enable",      (PyCFunction)profiler_enable,
    796                         METH_VARARGS | METH_KEYWORDS,   enable_doc},
    797         {"disable",     (PyCFunction)profiler_disable,
    798                         METH_NOARGS,                    disable_doc},
    799         {"clear",       (PyCFunction)profiler_clear,
    800                         METH_NOARGS,                    clear_doc},
    801         {NULL, NULL}
     798    {"getstats",    (PyCFunction)profiler_getstats,
     799                    METH_NOARGS,                        getstats_doc},
     800    {"enable",          (PyCFunction)profiler_enable,
     801                    METH_VARARGS | METH_KEYWORDS,       enable_doc},
     802    {"disable",         (PyCFunction)profiler_disable,
     803                    METH_NOARGS,                        disable_doc},
     804    {"clear",           (PyCFunction)profiler_clear,
     805                    METH_NOARGS,                        clear_doc},
     806    {NULL, NULL}
    802807};
    803808
     
    813818
    814819statichere PyTypeObject PyProfiler_Type = {
    815         PyObject_HEAD_INIT(NULL)
    816         0,                                      /* ob_size */
    817         "_lsprof.Profiler",                     /* tp_name */
    818         sizeof(ProfilerObject),                 /* tp_basicsize */
    819         0,                                      /* tp_itemsize */
    820         (destructor)profiler_dealloc,           /* tp_dealloc */
    821         0,                                      /* tp_print */
    822         0,                                      /* tp_getattr */
    823         0,                                      /* tp_setattr */
    824         0,                                      /* tp_compare */
    825         0,                                      /* tp_repr */
    826         0,                                      /* tp_as_number */
    827         0,                                      /* tp_as_sequence */
    828         0,                                      /* tp_as_mapping */
    829         0,                                      /* tp_hash */
    830         0,                                      /* tp_call */
    831         0,                                      /* tp_str */
    832         0,                                      /* tp_getattro */
    833         0,                                      /* tp_setattro */
    834         0,                                      /* tp_as_buffer */
    835         Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
    836         profiler_doc,                           /* tp_doc */
    837         0,                                      /* tp_traverse */
    838         0,                                      /* tp_clear */
    839         0,                                      /* tp_richcompare */
    840         0,                                      /* tp_weaklistoffset */
    841         0,                                      /* tp_iter */
    842         0,                                      /* tp_iternext */
    843         profiler_methods,                       /* tp_methods */
    844         0,                                      /* tp_members */
    845         0,                                      /* tp_getset */
    846         0,                                      /* tp_base */
    847         0,                                      /* tp_dict */
    848         0,                                      /* tp_descr_get */
    849         0,                                      /* tp_descr_set */
    850         0,                                      /* tp_dictoffset */
    851         (initproc)profiler_init,                /* tp_init */
    852         PyType_GenericAlloc,                    /* tp_alloc */
    853         PyType_GenericNew,                      /* tp_new */
    854         PyObject_Del,                           /* tp_free */
     820    PyObject_HEAD_INIT(NULL)
     821    0,                                      /* ob_size */
     822    "_lsprof.Profiler",                     /* tp_name */
     823    sizeof(ProfilerObject),                 /* tp_basicsize */
     824    0,                                      /* tp_itemsize */
     825    (destructor)profiler_dealloc,           /* tp_dealloc */
     826    0,                                      /* tp_print */
     827    0,                                      /* tp_getattr */
     828    0,                                      /* tp_setattr */
     829    0,                                      /* tp_compare */
     830    0,                                      /* tp_repr */
     831    0,                                      /* tp_as_number */
     832    0,                                      /* tp_as_sequence */
     833    0,                                      /* tp_as_mapping */
     834    0,                                      /* tp_hash */
     835    0,                                      /* tp_call */
     836    0,                                      /* tp_str */
     837    0,                                      /* tp_getattro */
     838    0,                                      /* tp_setattro */
     839    0,                                      /* tp_as_buffer */
     840    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
     841    profiler_doc,                           /* tp_doc */
     842    0,                                      /* tp_traverse */
     843    0,                                      /* tp_clear */
     844    0,                                      /* tp_richcompare */
     845    0,                                      /* tp_weaklistoffset */
     846    0,                                      /* tp_iter */
     847    0,                                      /* tp_iternext */
     848    profiler_methods,                       /* tp_methods */
     849    0,                                      /* tp_members */
     850    0,                                      /* tp_getset */
     851    0,                                      /* tp_base */
     852    0,                                      /* tp_dict */
     853    0,                                      /* tp_descr_get */
     854    0,                                      /* tp_descr_set */
     855    0,                                      /* tp_dictoffset */
     856    (initproc)profiler_init,                /* tp_init */
     857    PyType_GenericAlloc,                    /* tp_alloc */
     858    PyType_GenericNew,                      /* tp_new */
     859    PyObject_Del,                           /* tp_free */
    855860};
    856861
    857862static PyMethodDef moduleMethods[] = {
    858         {NULL, NULL}
     863    {NULL, NULL}
    859864};
    860865
     
    862867init_lsprof(void)
    863868{
    864         PyObject *module, *d;
    865         module = Py_InitModule3("_lsprof", moduleMethods, "Fast profiler");
    866         if (module == NULL)
    867                 return;
    868         d = PyModule_GetDict(module);
    869         if (PyType_Ready(&PyProfiler_Type) < 0)
    870                 return;
    871         PyDict_SetItemString(d, "Profiler", (PyObject *)&PyProfiler_Type);
    872 
    873         if (!initialized) {
    874                 PyStructSequence_InitType(&StatsEntryType,
    875                                           &profiler_entry_desc);
    876                 PyStructSequence_InitType(&StatsSubEntryType,
    877                                           &profiler_subentry_desc);
    878         }
    879         Py_INCREF((PyObject*) &StatsEntryType);
    880         Py_INCREF((PyObject*) &StatsSubEntryType);
    881         PyModule_AddObject(module, "profiler_entry",
    882                            (PyObject*) &StatsEntryType);
    883         PyModule_AddObject(module, "profiler_subentry",
    884                            (PyObject*) &StatsSubEntryType);
    885         empty_tuple = PyTuple_New(0);
    886         initialized = 1;
    887 }
     869    PyObject *module, *d;
     870    module = Py_InitModule3("_lsprof", moduleMethods, "Fast profiler");
     871    if (module == NULL)
     872        return;
     873    d = PyModule_GetDict(module);
     874    if (PyType_Ready(&PyProfiler_Type) < 0)
     875        return;
     876    PyDict_SetItemString(d, "Profiler", (PyObject *)&PyProfiler_Type);
     877
     878    if (!initialized) {
     879        PyStructSequence_InitType(&StatsEntryType,
     880                                  &profiler_entry_desc);
     881        PyStructSequence_InitType(&StatsSubEntryType,
     882                                  &profiler_subentry_desc);
     883    }
     884    Py_INCREF((PyObject*) &StatsEntryType);
     885    Py_INCREF((PyObject*) &StatsSubEntryType);
     886    PyModule_AddObject(module, "profiler_entry",
     887                       (PyObject*) &StatsEntryType);
     888    PyModule_AddObject(module, "profiler_subentry",
     889                       (PyObject*) &StatsSubEntryType);
     890    empty_tuple = PyTuple_New(0);
     891    initialized = 1;
     892}
Note: See TracChangeset for help on using the changeset viewer.