Mercurial > cpython-lru_cache-weakref
annotate Modules/_lsprof.c @ 80272:ec00f8570c55
Merge typo fix.
| author | Ezio Melotti <ezio.melotti@gmail.com> |
|---|---|
| date | Mon, 05 Nov 2012 22:23:16 +0200 |
| parents | dea15868963f |
| children | 41ef797e6639 |
| rev | line source |
|---|---|
| 36459 | 1 #include "Python.h" |
| 2 #include "frameobject.h" | |
| 3 #include "rotatingtree.h" | |
| 4 | |
| 5 #if !defined(HAVE_LONG_LONG) | |
| 6 #error "This module requires long longs!" | |
| 7 #endif | |
| 8 | |
| 9 /*** Selection of a high-precision timer ***/ | |
| 10 | |
| 11 #ifdef MS_WINDOWS | |
| 12 | |
| 13 #include <windows.h> | |
| 14 | |
| 15 static PY_LONG_LONG | |
| 16 hpTimer(void) | |
| 17 { | |
|
61466
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
18 LARGE_INTEGER li; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
19 QueryPerformanceCounter(&li); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
20 return li.QuadPart; |
| 36459 | 21 } |
| 22 | |
| 23 static double | |
| 24 hpTimerUnit(void) | |
| 25 { | |
|
61466
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
26 LARGE_INTEGER li; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
27 if (QueryPerformanceFrequency(&li)) |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
28 return 1.0 / li.QuadPart; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
29 else |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
30 return 0.000001; /* unlikely */ |
| 36459 | 31 } |
| 32 | |
| 33 #else /* !MS_WINDOWS */ | |
| 34 | |
| 35 #ifndef HAVE_GETTIMEOFDAY | |
| 36 #error "This module requires gettimeofday() on non-Windows platforms!" | |
| 37 #endif | |
| 38 | |
| 39 #include <sys/resource.h> | |
| 40 #include <sys/times.h> | |
| 41 | |
| 42 static PY_LONG_LONG | |
| 43 hpTimer(void) | |
| 44 { | |
|
61466
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
45 struct timeval tv; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
46 PY_LONG_LONG ret; |
| 36459 | 47 #ifdef GETTIMEOFDAY_NO_TZ |
|
61466
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
48 gettimeofday(&tv); |
| 36459 | 49 #else |
|
61466
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
50 gettimeofday(&tv, (struct timezone *)NULL); |
| 36459 | 51 #endif |
|
61466
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
52 ret = tv.tv_sec; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
53 ret = ret * 1000000 + tv.tv_usec; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
54 return ret; |
| 36459 | 55 } |
| 56 | |
| 57 static double | |
| 58 hpTimerUnit(void) | |
| 59 { | |
|
61466
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
60 return 0.000001; |
| 36459 | 61 } |
| 62 | |
| 63 #endif /* MS_WINDOWS */ | |
| 64 | |
| 65 /************************************************************/ | |
| 66 /* Written by Brett Rosen and Ted Czotter */ | |
| 67 | |
| 68 struct _ProfilerEntry; | |
| 69 | |
| 70 /* represents a function called from another function */ | |
| 71 typedef struct _ProfilerSubEntry { | |
|
61466
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
72 rotating_node_t header; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
73 PY_LONG_LONG tt; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
74 PY_LONG_LONG it; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
75 long callcount; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
76 long recursivecallcount; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
77 long recursionLevel; |
| 36459 | 78 } ProfilerSubEntry; |
| 79 | |
| 80 /* represents a function or user defined block */ | |
| 81 typedef struct _ProfilerEntry { | |
|
61466
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
82 rotating_node_t header; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
83 PyObject *userObj; /* PyCodeObject, or a descriptive str for builtins */ |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
84 PY_LONG_LONG tt; /* total time in this entry */ |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
85 PY_LONG_LONG it; /* inline time in this entry (not in subcalls) */ |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
86 long callcount; /* how many times this was called */ |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
87 long recursivecallcount; /* how many times called recursively */ |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
88 long recursionLevel; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
89 rotating_node_t *calls; |
| 36459 | 90 } ProfilerEntry; |
| 91 | |
| 92 typedef struct _ProfilerContext { | |
|
61466
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
93 PY_LONG_LONG t0; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
94 PY_LONG_LONG subt; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
95 struct _ProfilerContext *previous; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
96 ProfilerEntry *ctxEntry; |
| 36459 | 97 } ProfilerContext; |
| 98 | |
| 99 typedef struct { | |
|
61466
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
100 PyObject_HEAD |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
101 rotating_node_t *profilerEntries; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
102 ProfilerContext *currentProfilerContext; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
103 ProfilerContext *freelistProfilerContext; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
104 int flags; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
105 PyObject *externalTimer; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
106 double externalTimerUnit; |
| 36459 | 107 } ProfilerObject; |
| 108 | |
| 109 #define POF_ENABLED 0x001 | |
| 110 #define POF_SUBCALLS 0x002 | |
| 111 #define POF_BUILTINS 0x004 | |
| 112 #define POF_NOMEMORY 0x100 | |
| 113 | |
|
37144
91dd4d44d3bc
Finish getting rid of statichere/staticforward
Neal Norwitz <nnorwitz@gmail.com>
parents:
36861
diff
changeset
|
114 static PyTypeObject PyProfiler_Type; |
| 36459 | 115 |
| 116 #define PyProfiler_Check(op) PyObject_TypeCheck(op, &PyProfiler_Type) | |
|
44351
86a2679dca46
#1629: Renamed Py_Size, Py_Type and Py_Refcnt to Py_SIZE, Py_TYPE and Py_REFCNT.
Christian Heimes <christian@cheimes.de>
parents:
44098
diff
changeset
|
117 #define PyProfiler_CheckExact(op) (Py_TYPE(op) == &PyProfiler_Type) |
| 36459 | 118 |
| 119 /*** External Timers ***/ | |
| 120 | |
| 121 #define DOUBLE_TIMER_PRECISION 4294967296.0 | |
| 122 static PyObject *empty_tuple; | |
| 123 | |
| 124 static PY_LONG_LONG CallExternalTimer(ProfilerObject *pObj) | |
| 125 { | |
|
61466
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
126 PY_LONG_LONG result; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
127 PyObject *o = PyObject_Call(pObj->externalTimer, empty_tuple, NULL); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
128 if (o == NULL) { |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
129 PyErr_WriteUnraisable(pObj->externalTimer); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
130 return 0; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
131 } |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
132 if (pObj->externalTimerUnit > 0.0) { |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
133 /* interpret the result as an integer that will be scaled |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
134 in profiler_getstats() */ |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
135 result = PyLong_AsLongLong(o); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
136 } |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
137 else { |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
138 /* interpret the result as a double measured in seconds. |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
139 As the profiler works with PY_LONG_LONG internally |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
140 we convert it to a large integer */ |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
141 double val = PyFloat_AsDouble(o); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
142 /* error handling delayed to the code below */ |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
143 result = (PY_LONG_LONG) (val * DOUBLE_TIMER_PRECISION); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
144 } |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
145 Py_DECREF(o); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
146 if (PyErr_Occurred()) { |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
147 PyErr_WriteUnraisable(pObj->externalTimer); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
148 return 0; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
149 } |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
150 return result; |
| 36459 | 151 } |
| 152 | |
|
61466
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
153 #define CALL_TIMER(pObj) ((pObj)->externalTimer ? \ |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
154 CallExternalTimer(pObj) : \ |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
155 hpTimer()) |
| 36459 | 156 |
| 157 /*** ProfilerObject ***/ | |
| 158 | |
| 159 static PyObject * | |
| 160 normalizeUserObj(PyObject *obj) | |
| 161 { | |
|
61466
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
162 PyCFunctionObject *fn; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
163 if (!PyCFunction_Check(obj)) { |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
164 Py_INCREF(obj); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
165 return obj; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
166 } |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
167 /* Replace built-in function objects with a descriptive string |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
168 because of built-in methods -- keeping a reference to |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
169 __self__ is probably not a good idea. */ |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
170 fn = (PyCFunctionObject *)obj; |
| 36459 | 171 |
|
61466
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
172 if (fn->m_self == NULL) { |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
173 /* built-in function: look up the module name */ |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
174 PyObject *mod = fn->m_module; |
|
70899
b87eac0369b5
Issue #6697: _lsprof: normalizeUserObj() doesn't encode/decode (UTF-8) the
Victor Stinner <victor.stinner@haypocalc.com>
parents:
66822
diff
changeset
|
175 PyObject *modname = NULL; |
|
b87eac0369b5
Issue #6697: _lsprof: normalizeUserObj() doesn't encode/decode (UTF-8) the
Victor Stinner <victor.stinner@haypocalc.com>
parents:
66822
diff
changeset
|
176 if (mod != NULL) { |
|
b87eac0369b5
Issue #6697: _lsprof: normalizeUserObj() doesn't encode/decode (UTF-8) the
Victor Stinner <victor.stinner@haypocalc.com>
parents:
66822
diff
changeset
|
177 if (PyUnicode_Check(mod)) { |
|
b87eac0369b5
Issue #6697: _lsprof: normalizeUserObj() doesn't encode/decode (UTF-8) the
Victor Stinner <victor.stinner@haypocalc.com>
parents:
66822
diff
changeset
|
178 modname = mod; |
|
b87eac0369b5
Issue #6697: _lsprof: normalizeUserObj() doesn't encode/decode (UTF-8) the
Victor Stinner <victor.stinner@haypocalc.com>
parents:
66822
diff
changeset
|
179 Py_INCREF(modname); |
|
b87eac0369b5
Issue #6697: _lsprof: normalizeUserObj() doesn't encode/decode (UTF-8) the
Victor Stinner <victor.stinner@haypocalc.com>
parents:
66822
diff
changeset
|
180 } |
|
b87eac0369b5
Issue #6697: _lsprof: normalizeUserObj() doesn't encode/decode (UTF-8) the
Victor Stinner <victor.stinner@haypocalc.com>
parents:
66822
diff
changeset
|
181 else if (PyModule_Check(mod)) { |
|
b87eac0369b5
Issue #6697: _lsprof: normalizeUserObj() doesn't encode/decode (UTF-8) the
Victor Stinner <victor.stinner@haypocalc.com>
parents:
66822
diff
changeset
|
182 modname = PyModule_GetNameObject(mod); |
|
b87eac0369b5
Issue #6697: _lsprof: normalizeUserObj() doesn't encode/decode (UTF-8) the
Victor Stinner <victor.stinner@haypocalc.com>
parents:
66822
diff
changeset
|
183 if (modname == NULL) |
|
b87eac0369b5
Issue #6697: _lsprof: normalizeUserObj() doesn't encode/decode (UTF-8) the
Victor Stinner <victor.stinner@haypocalc.com>
parents:
66822
diff
changeset
|
184 PyErr_Clear(); |
|
66799
50d170bb71c7
Issue #6697: Fixed instances of _PyUnicode_AsString() result not checked for NULL
Alexander Belopolsky <alexander.belopolsky@gmail.com>
parents:
66556
diff
changeset
|
185 } |
|
61466
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
186 } |
|
70899
b87eac0369b5
Issue #6697: _lsprof: normalizeUserObj() doesn't encode/decode (UTF-8) the
Victor Stinner <victor.stinner@haypocalc.com>
parents:
66822
diff
changeset
|
187 if (modname != NULL) { |
|
b87eac0369b5
Issue #6697: _lsprof: normalizeUserObj() doesn't encode/decode (UTF-8) the
Victor Stinner <victor.stinner@haypocalc.com>
parents:
66822
diff
changeset
|
188 if (PyUnicode_CompareWithASCIIString(modname, "builtins") != 0) { |
|
b87eac0369b5
Issue #6697: _lsprof: normalizeUserObj() doesn't encode/decode (UTF-8) the
Victor Stinner <victor.stinner@haypocalc.com>
parents:
66822
diff
changeset
|
189 PyObject *result; |
|
b87eac0369b5
Issue #6697: _lsprof: normalizeUserObj() doesn't encode/decode (UTF-8) the
Victor Stinner <victor.stinner@haypocalc.com>
parents:
66822
diff
changeset
|
190 result = PyUnicode_FromFormat("<%U.%s>", modname, |
|
b87eac0369b5
Issue #6697: _lsprof: normalizeUserObj() doesn't encode/decode (UTF-8) the
Victor Stinner <victor.stinner@haypocalc.com>
parents:
66822
diff
changeset
|
191 fn->m_ml->ml_name); |
|
b87eac0369b5
Issue #6697: _lsprof: normalizeUserObj() doesn't encode/decode (UTF-8) the
Victor Stinner <victor.stinner@haypocalc.com>
parents:
66822
diff
changeset
|
192 Py_DECREF(modname); |
|
b87eac0369b5
Issue #6697: _lsprof: normalizeUserObj() doesn't encode/decode (UTF-8) the
Victor Stinner <victor.stinner@haypocalc.com>
parents:
66822
diff
changeset
|
193 return result; |
|
66822
4f849720bf41
Reverted accidental commit (from r87159)
Alexander Belopolsky <alexander.belopolsky@gmail.com>
parents:
66821
diff
changeset
|
194 } |
|
70899
b87eac0369b5
Issue #6697: _lsprof: normalizeUserObj() doesn't encode/decode (UTF-8) the
Victor Stinner <victor.stinner@haypocalc.com>
parents:
66822
diff
changeset
|
195 Py_DECREF(modname); |
|
66822
4f849720bf41
Reverted accidental commit (from r87159)
Alexander Belopolsky <alexander.belopolsky@gmail.com>
parents:
66821
diff
changeset
|
196 } |
|
70899
b87eac0369b5
Issue #6697: _lsprof: normalizeUserObj() doesn't encode/decode (UTF-8) the
Victor Stinner <victor.stinner@haypocalc.com>
parents:
66822
diff
changeset
|
197 return PyUnicode_FromFormat("<%s>", fn->m_ml->ml_name); |
|
61466
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
198 } |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
199 else { |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
200 /* built-in method: try to return |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
201 repr(getattr(type(__self__), __name__)) |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
202 */ |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
203 PyObject *self = fn->m_self; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
204 PyObject *name = PyUnicode_FromString(fn->m_ml->ml_name); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
205 if (name != NULL) { |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
206 PyObject *mo = _PyType_Lookup(Py_TYPE(self), name); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
207 Py_XINCREF(mo); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
208 Py_DECREF(name); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
209 if (mo != NULL) { |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
210 PyObject *res = PyObject_Repr(mo); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
211 Py_DECREF(mo); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
212 if (res != NULL) |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
213 return res; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
214 } |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
215 } |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
216 PyErr_Clear(); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
217 return PyUnicode_FromFormat("<built-in method %s>", |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
218 fn->m_ml->ml_name); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
219 } |
| 36459 | 220 } |
| 221 | |
| 222 static ProfilerEntry* | |
| 223 newProfilerEntry(ProfilerObject *pObj, void *key, PyObject *userObj) | |
| 224 { | |
|
61466
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
225 ProfilerEntry *self; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
226 self = (ProfilerEntry*) malloc(sizeof(ProfilerEntry)); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
227 if (self == NULL) { |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
228 pObj->flags |= POF_NOMEMORY; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
229 return NULL; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
230 } |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
231 userObj = normalizeUserObj(userObj); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
232 if (userObj == NULL) { |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
233 PyErr_Clear(); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
234 free(self); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
235 pObj->flags |= POF_NOMEMORY; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
236 return NULL; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
237 } |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
238 self->header.key = key; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
239 self->userObj = userObj; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
240 self->tt = 0; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
241 self->it = 0; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
242 self->callcount = 0; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
243 self->recursivecallcount = 0; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
244 self->recursionLevel = 0; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
245 self->calls = EMPTY_ROTATING_TREE; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
246 RotatingTree_Add(&pObj->profilerEntries, &self->header); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
247 return self; |
| 36459 | 248 } |
| 249 | |
| 250 static ProfilerEntry* | |
| 251 getEntry(ProfilerObject *pObj, void *key) | |
| 252 { | |
|
61466
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
253 return (ProfilerEntry*) RotatingTree_Get(&pObj->profilerEntries, key); |
| 36459 | 254 } |
| 255 | |
|
61466
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
256 static ProfilerSubEntry * |
| 36459 | 257 getSubEntry(ProfilerObject *pObj, ProfilerEntry *caller, ProfilerEntry* entry) |
| 258 { | |
|
61466
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
259 return (ProfilerSubEntry*) RotatingTree_Get(&caller->calls, |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
260 (void *)entry); |
| 36459 | 261 } |
| 262 | |
| 263 static ProfilerSubEntry * | |
| 264 newSubEntry(ProfilerObject *pObj, ProfilerEntry *caller, ProfilerEntry* entry) | |
| 265 { | |
|
61466
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
266 ProfilerSubEntry *self; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
267 self = (ProfilerSubEntry*) malloc(sizeof(ProfilerSubEntry)); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
268 if (self == NULL) { |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
269 pObj->flags |= POF_NOMEMORY; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
270 return NULL; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
271 } |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
272 self->header.key = (void *)entry; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
273 self->tt = 0; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
274 self->it = 0; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
275 self->callcount = 0; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
276 self->recursivecallcount = 0; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
277 self->recursionLevel = 0; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
278 RotatingTree_Add(&caller->calls, &self->header); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
279 return self; |
| 36459 | 280 } |
| 281 | |
| 282 static int freeSubEntry(rotating_node_t *header, void *arg) | |
| 283 { | |
|
61466
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
284 ProfilerSubEntry *subentry = (ProfilerSubEntry*) header; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
285 free(subentry); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
286 return 0; |
| 36459 | 287 } |
| 288 | |
| 289 static int freeEntry(rotating_node_t *header, void *arg) | |
| 290 { | |
|
61466
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
291 ProfilerEntry *entry = (ProfilerEntry*) header; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
292 RotatingTree_Enum(entry->calls, freeSubEntry, NULL); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
293 Py_DECREF(entry->userObj); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
294 free(entry); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
295 return 0; |
| 36459 | 296 } |
| 297 | |
| 298 static void clearEntries(ProfilerObject *pObj) | |
| 299 { | |
|
61466
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
300 RotatingTree_Enum(pObj->profilerEntries, freeEntry, NULL); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
301 pObj->profilerEntries = EMPTY_ROTATING_TREE; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
302 /* release the memory hold by the ProfilerContexts */ |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
303 if (pObj->currentProfilerContext) { |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
304 free(pObj->currentProfilerContext); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
305 pObj->currentProfilerContext = NULL; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
306 } |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
307 while (pObj->freelistProfilerContext) { |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
308 ProfilerContext *c = pObj->freelistProfilerContext; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
309 pObj->freelistProfilerContext = c->previous; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
310 free(c); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
311 } |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
312 pObj->freelistProfilerContext = NULL; |
| 36459 | 313 } |
| 314 | |
| 315 static void | |
| 316 initContext(ProfilerObject *pObj, ProfilerContext *self, ProfilerEntry *entry) | |
| 317 { | |
|
61466
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
318 self->ctxEntry = entry; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
319 self->subt = 0; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
320 self->previous = pObj->currentProfilerContext; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
321 pObj->currentProfilerContext = self; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
322 ++entry->recursionLevel; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
323 if ((pObj->flags & POF_SUBCALLS) && self->previous) { |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
324 /* find or create an entry for me in my caller's entry */ |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
325 ProfilerEntry *caller = self->previous->ctxEntry; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
326 ProfilerSubEntry *subentry = getSubEntry(pObj, caller, entry); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
327 if (subentry == NULL) |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
328 subentry = newSubEntry(pObj, caller, entry); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
329 if (subentry) |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
330 ++subentry->recursionLevel; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
331 } |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
332 self->t0 = CALL_TIMER(pObj); |
| 36459 | 333 } |
| 334 | |
| 335 static void | |
| 336 Stop(ProfilerObject *pObj, ProfilerContext *self, ProfilerEntry *entry) | |
| 337 { | |
|
61466
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
338 PY_LONG_LONG tt = CALL_TIMER(pObj) - self->t0; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
339 PY_LONG_LONG it = tt - self->subt; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
340 if (self->previous) |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
341 self->previous->subt += tt; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
342 pObj->currentProfilerContext = self->previous; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
343 if (--entry->recursionLevel == 0) |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
344 entry->tt += tt; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
345 else |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
346 ++entry->recursivecallcount; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
347 entry->it += it; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
348 entry->callcount++; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
349 if ((pObj->flags & POF_SUBCALLS) && self->previous) { |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
350 /* find or create an entry for me in my caller's entry */ |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
351 ProfilerEntry *caller = self->previous->ctxEntry; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
352 ProfilerSubEntry *subentry = getSubEntry(pObj, caller, entry); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
353 if (subentry) { |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
354 if (--subentry->recursionLevel == 0) |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
355 subentry->tt += tt; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
356 else |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
357 ++subentry->recursivecallcount; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
358 subentry->it += it; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
359 ++subentry->callcount; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
360 } |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
361 } |
| 36459 | 362 } |
| 363 | |
| 364 static void | |
| 365 ptrace_enter_call(PyObject *self, void *key, PyObject *userObj) | |
| 366 { | |
|
61466
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
367 /* entering a call to the function identified by 'key' |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
368 (which can be a PyCodeObject or a PyMethodDef pointer) */ |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
369 ProfilerObject *pObj = (ProfilerObject*)self; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
370 ProfilerEntry *profEntry; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
371 ProfilerContext *pContext; |
| 36459 | 372 |
|
61466
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
373 /* In the case of entering a generator expression frame via a |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
374 * throw (gen_send_ex(.., 1)), we may already have an |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
375 * Exception set here. We must not mess around with this |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
376 * exception, and some of the code under here assumes that |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
377 * PyErr_* is its own to mess around with, so we have to |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
378 * save and restore any current exception. */ |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
379 PyObject *last_type, *last_value, *last_tb; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
380 PyErr_Fetch(&last_type, &last_value, &last_tb); |
|
43292
876b7ef4775d
Merged revisions 57778-58052 via svnmerge from
Thomas Wouters <thomas@python.org>
parents:
42888
diff
changeset
|
381 |
|
61466
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
382 profEntry = getEntry(pObj, key); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
383 if (profEntry == NULL) { |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
384 profEntry = newProfilerEntry(pObj, key, userObj); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
385 if (profEntry == NULL) |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
386 goto restorePyerr; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
387 } |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
388 /* grab a ProfilerContext out of the free list */ |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
389 pContext = pObj->freelistProfilerContext; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
390 if (pContext) { |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
391 pObj->freelistProfilerContext = pContext->previous; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
392 } |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
393 else { |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
394 /* free list exhausted, allocate a new one */ |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
395 pContext = (ProfilerContext*) |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
396 malloc(sizeof(ProfilerContext)); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
397 if (pContext == NULL) { |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
398 pObj->flags |= POF_NOMEMORY; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
399 goto restorePyerr; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
400 } |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
401 } |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
402 initContext(pObj, pContext, profEntry); |
|
43292
876b7ef4775d
Merged revisions 57778-58052 via svnmerge from
Thomas Wouters <thomas@python.org>
parents:
42888
diff
changeset
|
403 |
|
876b7ef4775d
Merged revisions 57778-58052 via svnmerge from
Thomas Wouters <thomas@python.org>
parents:
42888
diff
changeset
|
404 restorePyerr: |
|
61466
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
405 PyErr_Restore(last_type, last_value, last_tb); |
| 36459 | 406 } |
| 407 | |
| 408 static void | |
| 409 ptrace_leave_call(PyObject *self, void *key) | |
| 410 { | |
|
61466
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
411 /* leaving a call to the function identified by 'key' */ |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
412 ProfilerObject *pObj = (ProfilerObject*)self; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
413 ProfilerEntry *profEntry; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
414 ProfilerContext *pContext; |
| 36459 | 415 |
|
61466
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
416 pContext = pObj->currentProfilerContext; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
417 if (pContext == NULL) |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
418 return; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
419 profEntry = getEntry(pObj, key); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
420 if (profEntry) { |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
421 Stop(pObj, pContext, profEntry); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
422 } |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
423 else { |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
424 pObj->currentProfilerContext = pContext->previous; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
425 } |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
426 /* put pContext into the free list */ |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
427 pContext->previous = pObj->freelistProfilerContext; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
428 pObj->freelistProfilerContext = pContext; |
| 36459 | 429 } |
| 430 | |
| 431 static int | |
| 432 profiler_callback(PyObject *self, PyFrameObject *frame, int what, | |
|
61466
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
433 PyObject *arg) |
| 36459 | 434 { |
|
61466
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
435 switch (what) { |
| 36459 | 436 |
|
61466
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
437 /* the 'frame' of a called function is about to start its execution */ |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
438 case PyTrace_CALL: |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
439 ptrace_enter_call(self, (void *)frame->f_code, |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
440 (PyObject *)frame->f_code); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
441 break; |
| 36459 | 442 |
|
61466
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
443 /* the 'frame' of a called function is about to finish |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
444 (either normally or with an exception) */ |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
445 case PyTrace_RETURN: |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
446 ptrace_leave_call(self, (void *)frame->f_code); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
447 break; |
| 36459 | 448 |
|
61466
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
449 /* case PyTrace_EXCEPTION: |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
450 If the exception results in the function exiting, a |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
451 PyTrace_RETURN event will be generated, so we don't need to |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
452 handle it. */ |
| 36459 | 453 |
|
61466
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
454 #ifdef PyTrace_C_CALL /* not defined in Python <= 2.3 */ |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
455 /* the Python function 'frame' is issuing a call to the built-in |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
456 function 'arg' */ |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
457 case PyTrace_C_CALL: |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
458 if ((((ProfilerObject *)self)->flags & POF_BUILTINS) |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
459 && PyCFunction_Check(arg)) { |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
460 ptrace_enter_call(self, |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
461 ((PyCFunctionObject *)arg)->m_ml, |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
462 arg); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
463 } |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
464 break; |
| 36459 | 465 |
|
61466
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
466 /* the call to the built-in function 'arg' is returning into its |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
467 caller 'frame' */ |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
468 case PyTrace_C_RETURN: /* ...normally */ |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
469 case PyTrace_C_EXCEPTION: /* ...with an exception set */ |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
470 if ((((ProfilerObject *)self)->flags & POF_BUILTINS) |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
471 && PyCFunction_Check(arg)) { |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
472 ptrace_leave_call(self, |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
473 ((PyCFunctionObject *)arg)->m_ml); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
474 } |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
475 break; |
| 36459 | 476 #endif |
| 477 | |
|
61466
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
478 default: |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
479 break; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
480 } |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
481 return 0; |
| 36459 | 482 } |
| 483 | |
| 484 static int | |
| 485 pending_exception(ProfilerObject *pObj) | |
| 486 { | |
|
61466
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
487 if (pObj->flags & POF_NOMEMORY) { |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
488 pObj->flags -= POF_NOMEMORY; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
489 PyErr_SetString(PyExc_MemoryError, |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
490 "memory was exhausted while profiling"); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
491 return -1; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
492 } |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
493 return 0; |
| 36459 | 494 } |
| 495 | |
| 496 /************************************************************/ | |
| 497 | |
| 498 static PyStructSequence_Field profiler_entry_fields[] = { | |
|
61466
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
499 {"code", "code object or built-in function name"}, |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
500 {"callcount", "how many times this was called"}, |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
501 {"reccallcount", "how many times called recursively"}, |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
502 {"totaltime", "total time in this entry"}, |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
503 {"inlinetime", "inline time in this entry (not in subcalls)"}, |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
504 {"calls", "details of the calls"}, |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
505 {0} |
| 36459 | 506 }; |
| 507 | |
| 508 static PyStructSequence_Field profiler_subentry_fields[] = { | |
|
61466
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
509 {"code", "called code object or built-in function name"}, |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
510 {"callcount", "how many times this is called"}, |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
511 {"reccallcount", "how many times this is called recursively"}, |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
512 {"totaltime", "total time spent in this call"}, |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
513 {"inlinetime", "inline time (not in further subcalls)"}, |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
514 {0} |
| 36459 | 515 }; |
| 516 | |
| 517 static PyStructSequence_Desc profiler_entry_desc = { | |
|
61466
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
518 "_lsprof.profiler_entry", /* name */ |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
519 NULL, /* doc */ |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
520 profiler_entry_fields, |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
521 6 |
| 36459 | 522 }; |
| 523 | |
| 524 static PyStructSequence_Desc profiler_subentry_desc = { | |
|
61466
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
525 "_lsprof.profiler_subentry", /* name */ |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
526 NULL, /* doc */ |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
527 profiler_subentry_fields, |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
528 5 |
| 36459 | 529 }; |
| 530 | |
|
37879
f731859e9b3b
Merge p3yk branch with the trunk up to revision 45595. This breaks a fair
Thomas Wouters <thomas@python.org>
parents:
37144
diff
changeset
|
531 static int initialized; |
| 36459 | 532 static PyTypeObject StatsEntryType; |
| 533 static PyTypeObject StatsSubEntryType; | |
| 534 | |
| 535 | |
| 536 typedef struct { | |
|
61466
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
537 PyObject *list; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
538 PyObject *sublist; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
539 double factor; |
| 36459 | 540 } statscollector_t; |
| 541 | |
| 542 static int statsForSubEntry(rotating_node_t *node, void *arg) | |
| 543 { | |
|
61466
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
544 ProfilerSubEntry *sentry = (ProfilerSubEntry*) node; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
545 statscollector_t *collect = (statscollector_t*) arg; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
546 ProfilerEntry *entry = (ProfilerEntry*) sentry->header.key; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
547 int err; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
548 PyObject *sinfo; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
549 sinfo = PyObject_CallFunction((PyObject*) &StatsSubEntryType, |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
550 "((Olldd))", |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
551 entry->userObj, |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
552 sentry->callcount, |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
553 sentry->recursivecallcount, |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
554 collect->factor * sentry->tt, |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
555 collect->factor * sentry->it); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
556 if (sinfo == NULL) |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
557 return -1; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
558 err = PyList_Append(collect->sublist, sinfo); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
559 Py_DECREF(sinfo); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
560 return err; |
| 36459 | 561 } |
| 562 | |
| 563 static int statsForEntry(rotating_node_t *node, void *arg) | |
| 564 { | |
|
61466
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
565 ProfilerEntry *entry = (ProfilerEntry*) node; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
566 statscollector_t *collect = (statscollector_t*) arg; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
567 PyObject *info; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
568 int err; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
569 if (entry->callcount == 0) |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
570 return 0; /* skip */ |
| 36459 | 571 |
|
61466
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
572 if (entry->calls != EMPTY_ROTATING_TREE) { |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
573 collect->sublist = PyList_New(0); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
574 if (collect->sublist == NULL) |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
575 return -1; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
576 if (RotatingTree_Enum(entry->calls, |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
577 statsForSubEntry, collect) != 0) { |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
578 Py_DECREF(collect->sublist); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
579 return -1; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
580 } |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
581 } |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
582 else { |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
583 Py_INCREF(Py_None); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
584 collect->sublist = Py_None; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
585 } |
| 36459 | 586 |
|
61466
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
587 info = PyObject_CallFunction((PyObject*) &StatsEntryType, |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
588 "((OllddO))", |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
589 entry->userObj, |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
590 entry->callcount, |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
591 entry->recursivecallcount, |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
592 collect->factor * entry->tt, |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
593 collect->factor * entry->it, |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
594 collect->sublist); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
595 Py_DECREF(collect->sublist); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
596 if (info == NULL) |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
597 return -1; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
598 err = PyList_Append(collect->list, info); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
599 Py_DECREF(info); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
600 return err; |
| 36459 | 601 } |
| 602 | |
| 603 PyDoc_STRVAR(getstats_doc, "\ | |
| 604 getstats() -> list of profiler_entry objects\n\ | |
| 605 \n\ | |
| 606 Return all information collected by the profiler.\n\ | |
| 607 Each profiler_entry is a tuple-like object with the\n\ | |
| 608 following attributes:\n\ | |
| 609 \n\ | |
| 610 code code object\n\ | |
| 611 callcount how many times this was called\n\ | |
| 612 reccallcount how many times called recursively\n\ | |
| 613 totaltime total time in this entry\n\ | |
| 614 inlinetime inline time in this entry (not in subcalls)\n\ | |
| 615 calls details of the calls\n\ | |
| 616 \n\ | |
| 617 The calls attribute is either None or a list of\n\ | |
| 618 profiler_subentry objects:\n\ | |
| 619 \n\ | |
| 620 code called code object\n\ | |
| 621 callcount how many times this is called\n\ | |
| 622 reccallcount how many times this is called recursively\n\ | |
| 623 totaltime total time spent in this call\n\ | |
| 624 inlinetime inline time (not in further subcalls)\n\ | |
| 625 "); | |
| 626 | |
| 627 static PyObject* | |
| 628 profiler_getstats(ProfilerObject *pObj, PyObject* noarg) | |
| 629 { | |
|
61466
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
630 statscollector_t collect; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
631 if (pending_exception(pObj)) |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
632 return NULL; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
633 if (!pObj->externalTimer) |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
634 collect.factor = hpTimerUnit(); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
635 else if (pObj->externalTimerUnit > 0.0) |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
636 collect.factor = pObj->externalTimerUnit; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
637 else |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
638 collect.factor = 1.0 / DOUBLE_TIMER_PRECISION; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
639 collect.list = PyList_New(0); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
640 if (collect.list == NULL) |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
641 return NULL; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
642 if (RotatingTree_Enum(pObj->profilerEntries, statsForEntry, &collect) |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
643 != 0) { |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
644 Py_DECREF(collect.list); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
645 return NULL; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
646 } |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
647 return collect.list; |
| 36459 | 648 } |
| 649 | |
| 650 static int | |
| 651 setSubcalls(ProfilerObject *pObj, int nvalue) | |
| 652 { | |
|
61466
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
653 if (nvalue == 0) |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
654 pObj->flags &= ~POF_SUBCALLS; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
655 else if (nvalue > 0) |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
656 pObj->flags |= POF_SUBCALLS; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
657 return 0; |
| 36459 | 658 } |
| 659 | |
| 660 static int | |
| 661 setBuiltins(ProfilerObject *pObj, int nvalue) | |
| 662 { | |
|
61466
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
663 if (nvalue == 0) |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
664 pObj->flags &= ~POF_BUILTINS; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
665 else if (nvalue > 0) { |
| 36459 | 666 #ifndef PyTrace_C_CALL |
|
61466
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
667 PyErr_SetString(PyExc_ValueError, |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
668 "builtins=True requires Python >= 2.4"); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
669 return -1; |
| 36459 | 670 #else |
|
61466
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
671 pObj->flags |= POF_BUILTINS; |
| 36459 | 672 #endif |
|
61466
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
673 } |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
674 return 0; |
| 36459 | 675 } |
| 676 | |
| 677 PyDoc_STRVAR(enable_doc, "\ | |
| 678 enable(subcalls=True, builtins=True)\n\ | |
| 679 \n\ | |
| 680 Start collecting profiling information.\n\ | |
| 681 If 'subcalls' is True, also records for each function\n\ | |
| 682 statistics separated according to its current caller.\n\ | |
| 683 If 'builtins' is True, records the time spent in\n\ | |
| 684 built-in functions separately from their caller.\n\ | |
| 685 "); | |
| 686 | |
| 687 static PyObject* | |
| 688 profiler_enable(ProfilerObject *self, PyObject *args, PyObject *kwds) | |
| 689 { | |
|
61466
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
690 int subcalls = -1; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
691 int builtins = -1; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
692 static char *kwlist[] = {"subcalls", "builtins", 0}; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
693 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|ii:enable", |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
694 kwlist, &subcalls, &builtins)) |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
695 return NULL; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
696 if (setSubcalls(self, subcalls) < 0 || setBuiltins(self, builtins) < 0) |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
697 return NULL; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
698 PyEval_SetProfile(profiler_callback, (PyObject*)self); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
699 self->flags |= POF_ENABLED; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
700 Py_INCREF(Py_None); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
701 return Py_None; |
| 36459 | 702 } |
| 703 | |
| 704 static void | |
| 705 flush_unmatched(ProfilerObject *pObj) | |
| 706 { | |
|
61466
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
707 while (pObj->currentProfilerContext) { |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
708 ProfilerContext *pContext = pObj->currentProfilerContext; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
709 ProfilerEntry *profEntry= pContext->ctxEntry; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
710 if (profEntry) |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
711 Stop(pObj, pContext, profEntry); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
712 else |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
713 pObj->currentProfilerContext = pContext->previous; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
714 if (pContext) |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
715 free(pContext); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
716 } |
| 36459 | 717 |
| 718 } | |
| 719 | |
| 720 PyDoc_STRVAR(disable_doc, "\ | |
| 721 disable()\n\ | |
| 722 \n\ | |
| 723 Stop collecting profiling information.\n\ | |
| 724 "); | |
| 725 | |
| 726 static PyObject* | |
| 727 profiler_disable(ProfilerObject *self, PyObject* noarg) | |
| 728 { | |
|
61466
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
729 self->flags &= ~POF_ENABLED; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
730 PyEval_SetProfile(NULL, NULL); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
731 flush_unmatched(self); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
732 if (pending_exception(self)) |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
733 return NULL; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
734 Py_INCREF(Py_None); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
735 return Py_None; |
| 36459 | 736 } |
| 737 | |
| 738 PyDoc_STRVAR(clear_doc, "\ | |
| 739 clear()\n\ | |
| 740 \n\ | |
| 741 Clear all profiling information collected so far.\n\ | |
| 742 "); | |
| 743 | |
| 744 static PyObject* | |
| 745 profiler_clear(ProfilerObject *pObj, PyObject* noarg) | |
| 746 { | |
|
61466
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
747 clearEntries(pObj); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
748 Py_INCREF(Py_None); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
749 return Py_None; |
| 36459 | 750 } |
| 751 | |
| 752 static void | |
| 753 profiler_dealloc(ProfilerObject *op) | |
| 754 { | |
|
61466
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
755 if (op->flags & POF_ENABLED) |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
756 PyEval_SetProfile(NULL, NULL); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
757 flush_unmatched(op); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
758 clearEntries(op); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
759 Py_XDECREF(op->externalTimer); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
760 Py_TYPE(op)->tp_free(op); |
| 36459 | 761 } |
| 762 | |
| 763 static int | |
| 764 profiler_init(ProfilerObject *pObj, PyObject *args, PyObject *kw) | |
| 765 { | |
|
61466
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
766 PyObject *o; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
767 PyObject *timer = NULL; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
768 double timeunit = 0.0; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
769 int subcalls = 1; |
| 36459 | 770 #ifdef PyTrace_C_CALL |
|
61466
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
771 int builtins = 1; |
| 36459 | 772 #else |
|
61466
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
773 int builtins = 0; |
| 36459 | 774 #endif |
|
61466
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
775 static char *kwlist[] = {"timer", "timeunit", |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
776 "subcalls", "builtins", 0}; |
| 36459 | 777 |
|
61466
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
778 if (!PyArg_ParseTupleAndKeywords(args, kw, "|Odii:Profiler", kwlist, |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
779 &timer, &timeunit, |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
780 &subcalls, &builtins)) |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
781 return -1; |
| 36459 | 782 |
|
61466
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
783 if (setSubcalls(pObj, subcalls) < 0 || setBuiltins(pObj, builtins) < 0) |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
784 return -1; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
785 o = pObj->externalTimer; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
786 pObj->externalTimer = timer; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
787 Py_XINCREF(timer); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
788 Py_XDECREF(o); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
789 pObj->externalTimerUnit = timeunit; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
790 return 0; |
| 36459 | 791 } |
| 792 | |
| 793 static PyMethodDef profiler_methods[] = { | |
|
61466
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
794 {"getstats", (PyCFunction)profiler_getstats, |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
795 METH_NOARGS, getstats_doc}, |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
796 {"enable", (PyCFunction)profiler_enable, |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
797 METH_VARARGS | METH_KEYWORDS, enable_doc}, |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
798 {"disable", (PyCFunction)profiler_disable, |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
799 METH_NOARGS, disable_doc}, |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
800 {"clear", (PyCFunction)profiler_clear, |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
801 METH_NOARGS, clear_doc}, |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
802 {NULL, NULL} |
| 36459 | 803 }; |
| 804 | |
| 805 PyDoc_STRVAR(profiler_doc, "\ | |
| 806 Profiler(custom_timer=None, time_unit=None, subcalls=True, builtins=True)\n\ | |
| 807 \n\ | |
| 808 Builds a profiler object using the specified timer function.\n\ | |
| 809 The default timer is a fast built-in one based on real time.\n\ | |
| 810 For custom timer functions returning integers, time_unit can\n\ | |
| 811 be a float specifying a scale (i.e. how long each integer unit\n\ | |
| 812 is, in seconds).\n\ | |
| 813 "); | |
| 814 | |
|
37144
91dd4d44d3bc
Finish getting rid of statichere/staticforward
Neal Norwitz <nnorwitz@gmail.com>
parents:
36861
diff
changeset
|
815 static PyTypeObject PyProfiler_Type = { |
|
61466
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
816 PyVarObject_HEAD_INIT(NULL, 0) |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
817 "_lsprof.Profiler", /* tp_name */ |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
818 sizeof(ProfilerObject), /* tp_basicsize */ |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
819 0, /* tp_itemsize */ |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
820 (destructor)profiler_dealloc, /* tp_dealloc */ |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
821 0, /* tp_print */ |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
822 0, /* tp_getattr */ |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
823 0, /* tp_setattr */ |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
824 0, /* tp_reserved */ |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
825 0, /* tp_repr */ |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
826 0, /* tp_as_number */ |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
827 0, /* tp_as_sequence */ |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
828 0, /* tp_as_mapping */ |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
829 0, /* tp_hash */ |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
830 0, /* tp_call */ |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
831 0, /* tp_str */ |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
832 0, /* tp_getattro */ |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
833 0, /* tp_setattro */ |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
834 0, /* tp_as_buffer */ |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
835 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
836 profiler_doc, /* tp_doc */ |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
837 0, /* tp_traverse */ |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
838 0, /* tp_clear */ |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
839 0, /* tp_richcompare */ |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
840 0, /* tp_weaklistoffset */ |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
841 0, /* tp_iter */ |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
842 0, /* tp_iternext */ |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
843 profiler_methods, /* tp_methods */ |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
844 0, /* tp_members */ |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
845 0, /* tp_getset */ |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
846 0, /* tp_base */ |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
847 0, /* tp_dict */ |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
848 0, /* tp_descr_get */ |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
849 0, /* tp_descr_set */ |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
850 0, /* tp_dictoffset */ |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
851 (initproc)profiler_init, /* tp_init */ |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
852 PyType_GenericAlloc, /* tp_alloc */ |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
853 PyType_GenericNew, /* tp_new */ |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
854 PyObject_Del, /* tp_free */ |
| 36459 | 855 }; |
| 856 | |
| 857 static PyMethodDef moduleMethods[] = { | |
|
61466
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
858 {NULL, NULL} |
| 36459 | 859 }; |
| 860 | |
|
47580
94f64f11fdd0
Implement PEP 3121: new module initialization and finalization API.
Martin v. Löwis <martin@v.loewis.de>
parents:
44351
diff
changeset
|
861 |
|
94f64f11fdd0
Implement PEP 3121: new module initialization and finalization API.
Martin v. Löwis <martin@v.loewis.de>
parents:
44351
diff
changeset
|
862 static struct PyModuleDef _lsprofmodule = { |
|
61466
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
863 PyModuleDef_HEAD_INIT, |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
864 "_lsprof", |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
865 "Fast profiler", |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
866 -1, |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
867 moduleMethods, |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
868 NULL, |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
869 NULL, |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
870 NULL, |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
871 NULL |
|
47580
94f64f11fdd0
Implement PEP 3121: new module initialization and finalization API.
Martin v. Löwis <martin@v.loewis.de>
parents:
44351
diff
changeset
|
872 }; |
|
94f64f11fdd0
Implement PEP 3121: new module initialization and finalization API.
Martin v. Löwis <martin@v.loewis.de>
parents:
44351
diff
changeset
|
873 |
| 36459 | 874 PyMODINIT_FUNC |
|
47580
94f64f11fdd0
Implement PEP 3121: new module initialization and finalization API.
Martin v. Löwis <martin@v.loewis.de>
parents:
44351
diff
changeset
|
875 PyInit__lsprof(void) |
| 36459 | 876 { |
|
61466
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
877 PyObject *module, *d; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
878 module = PyModule_Create(&_lsprofmodule); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
879 if (module == NULL) |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
880 return NULL; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
881 d = PyModule_GetDict(module); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
882 if (PyType_Ready(&PyProfiler_Type) < 0) |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
883 return NULL; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
884 PyDict_SetItemString(d, "Profiler", (PyObject *)&PyProfiler_Type); |
| 36459 | 885 |
|
61466
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
886 if (!initialized) { |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
887 PyStructSequence_InitType(&StatsEntryType, |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
888 &profiler_entry_desc); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
889 PyStructSequence_InitType(&StatsSubEntryType, |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
890 &profiler_subentry_desc); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
891 } |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
892 Py_INCREF((PyObject*) &StatsEntryType); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
893 Py_INCREF((PyObject*) &StatsSubEntryType); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
894 PyModule_AddObject(module, "profiler_entry", |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
895 (PyObject*) &StatsEntryType); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
896 PyModule_AddObject(module, "profiler_subentry", |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
897 (PyObject*) &StatsSubEntryType); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
898 empty_tuple = PyTuple_New(0); |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
899 initialized = 1; |
|
cab14be0ada1
Recorded merge of revisions 81029 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
59319
diff
changeset
|
900 return module; |
| 36459 | 901 } |
