You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

905 lines
27 KiB

Merged revisions 57778-58052 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r57820 | georg.brandl | 2007-08-31 08:59:27 +0200 (Fri, 31 Aug 2007) | 2 lines Document new shorthand notation for index entries. ........ r57827 | georg.brandl | 2007-08-31 10:47:51 +0200 (Fri, 31 Aug 2007) | 2 lines Fix subitem markup. ........ r57833 | martin.v.loewis | 2007-08-31 12:01:07 +0200 (Fri, 31 Aug 2007) | 1 line Mark registry components as 64-bit on Win64. ........ r57854 | bill.janssen | 2007-08-31 21:02:23 +0200 (Fri, 31 Aug 2007) | 1 line deprecate use of FakeSocket ........ r57855 | bill.janssen | 2007-08-31 21:02:46 +0200 (Fri, 31 Aug 2007) | 1 line remove mentions of socket.ssl in comments ........ r57856 | bill.janssen | 2007-08-31 21:03:31 +0200 (Fri, 31 Aug 2007) | 1 line remove use of non-existent SSLFakeSocket in apparently untested code ........ r57859 | martin.v.loewis | 2007-09-01 08:36:03 +0200 (Sat, 01 Sep 2007) | 3 lines Bug #1737210: Change Manufacturer of Windows installer to PSF. Will backport to 2.5. ........ r57865 | georg.brandl | 2007-09-01 09:51:24 +0200 (Sat, 01 Sep 2007) | 2 lines Fix RST link (backport from Py3k). ........ r57876 | georg.brandl | 2007-09-01 17:49:49 +0200 (Sat, 01 Sep 2007) | 2 lines Document sets' ">" and "<" operations (backport from py3k). ........ r57878 | skip.montanaro | 2007-09-01 19:40:03 +0200 (Sat, 01 Sep 2007) | 4 lines Added a note and examples to explain that re.split does not split on an empty pattern match. (issue 852532). ........ r57879 | walter.doerwald | 2007-09-01 20:18:09 +0200 (Sat, 01 Sep 2007) | 2 lines Fix wrong function names. ........ r57880 | walter.doerwald | 2007-09-01 20:34:05 +0200 (Sat, 01 Sep 2007) | 2 lines Fix typo. ........ r57889 | andrew.kuchling | 2007-09-01 22:31:59 +0200 (Sat, 01 Sep 2007) | 1 line Markup fix ........ r57892 | andrew.kuchling | 2007-09-01 22:43:36 +0200 (Sat, 01 Sep 2007) | 1 line Add various items ........ r57895 | andrew.kuchling | 2007-09-01 23:17:58 +0200 (Sat, 01 Sep 2007) | 1 line Wording change ........ r57896 | andrew.kuchling | 2007-09-01 23:18:31 +0200 (Sat, 01 Sep 2007) | 1 line Add more items ........ r57904 | ronald.oussoren | 2007-09-02 11:46:07 +0200 (Sun, 02 Sep 2007) | 3 lines Macosx: this patch ensures that the value of MACOSX_DEPLOYMENT_TARGET used by the Makefile is also used at configure-time. ........ r57925 | georg.brandl | 2007-09-03 09:16:46 +0200 (Mon, 03 Sep 2007) | 2 lines Fix #883466: don't allow Unicode as arguments to quopri and uu codecs. ........ r57936 | matthias.klose | 2007-09-04 01:33:04 +0200 (Tue, 04 Sep 2007) | 2 lines - Added support for linking the bsddb module against BerkeleyDB 4.6.x. ........ r57954 | mark.summerfield | 2007-09-04 10:16:15 +0200 (Tue, 04 Sep 2007) | 3 lines Added cross-references plus a note about dict & list shallow copying. ........ r57958 | martin.v.loewis | 2007-09-04 11:51:57 +0200 (Tue, 04 Sep 2007) | 3 lines Document that we rely on the OS to release the crypto context. Fixes #1626801. ........ r57960 | martin.v.loewis | 2007-09-04 15:13:14 +0200 (Tue, 04 Sep 2007) | 3 lines Patch #1388440: Add set_completion_display_matches_hook and get_completion_type to readline. ........ r57961 | martin.v.loewis | 2007-09-04 16:19:28 +0200 (Tue, 04 Sep 2007) | 3 lines Patch #1031213: Decode source line in SyntaxErrors back to its original source encoding. Will backport to 2.5. ........ r57972 | matthias.klose | 2007-09-04 20:17:36 +0200 (Tue, 04 Sep 2007) | 3 lines - Makefile.pre.in(buildbottest): Run an optional script pybuildbot.identify to include some information about the build environment. ........ r57973 | matthias.klose | 2007-09-04 21:05:38 +0200 (Tue, 04 Sep 2007) | 2 lines - Makefile.pre.in(buildbottest): Remove whitespace at eol. ........ r57975 | matthias.klose | 2007-09-04 22:46:02 +0200 (Tue, 04 Sep 2007) | 2 lines - Fix libffi configure for hppa*-*-linux* | parisc*-*-linux*. ........ r57980 | bill.janssen | 2007-09-05 02:46:27 +0200 (Wed, 05 Sep 2007) | 1 line SSL certificate distinguished names should be represented by tuples ........ r57985 | martin.v.loewis | 2007-09-05 08:39:17 +0200 (Wed, 05 Sep 2007) | 3 lines Patch #1105: Explain that one needs to build the solution to get dependencies right. ........ r57987 | armin.rigo | 2007-09-05 09:51:21 +0200 (Wed, 05 Sep 2007) | 4 lines PyDict_GetItem() returns a borrowed reference. There are probably a number of places that are open to attacks such as the following one, in bltinmodule.c:min_max(). ........ r57991 | martin.v.loewis | 2007-09-05 13:47:34 +0200 (Wed, 05 Sep 2007) | 3 lines Patch #786737: Allow building in a tree of symlinks pointing to a readonly source. ........ r57993 | georg.brandl | 2007-09-05 15:36:44 +0200 (Wed, 05 Sep 2007) | 2 lines Backport from Py3k: Bug #1684991: explain lookup semantics for __special__ methods (new-style classes only). ........ r58004 | armin.rigo | 2007-09-06 10:30:51 +0200 (Thu, 06 Sep 2007) | 4 lines Patch #1733973 by peaker: ptrace_enter_call() assumes no exception is currently set. This assumption is broken when throwing into a generator. ........ r58006 | armin.rigo | 2007-09-06 11:30:38 +0200 (Thu, 06 Sep 2007) | 4 lines PyDict_GetItem() returns a borrowed reference. This attack is against ceval.c:IMPORT_NAME, which calls an object (__builtin__.__import__) without holding a reference to it. ........ r58013 | georg.brandl | 2007-09-06 16:49:56 +0200 (Thu, 06 Sep 2007) | 2 lines Backport from 3k: #1116: fix reference to old filename. ........ r58021 | thomas.heller | 2007-09-06 22:26:20 +0200 (Thu, 06 Sep 2007) | 1 line Fix typo: c_float represents to C float type. ........ r58022 | skip.montanaro | 2007-09-07 00:29:06 +0200 (Fri, 07 Sep 2007) | 3 lines If this is correct for py3k branch and it's already in the release25-maint branch, seems like it ought to be on the trunk as well. ........ r58023 | gregory.p.smith | 2007-09-07 00:59:59 +0200 (Fri, 07 Sep 2007) | 4 lines Apply the fix from Issue1112 to make this test more robust and keep windows happy. ........ r58031 | brett.cannon | 2007-09-07 05:17:50 +0200 (Fri, 07 Sep 2007) | 4 lines Make uuid1 and uuid4 tests conditional on whether ctypes can be imported; implementation of either function depends on ctypes but uuid as a whole does not. ........ r58032 | brett.cannon | 2007-09-07 06:18:30 +0200 (Fri, 07 Sep 2007) | 6 lines Fix a crasher where Python code managed to infinitely recurse in C code without ever going back out to Python code in PyObject_Call(). Required introducing a static RuntimeError instance so that normalizing an exception there is no reliance on a recursive call that would put the exception system over the recursion check itself. ........ r58034 | thomas.heller | 2007-09-07 08:32:17 +0200 (Fri, 07 Sep 2007) | 1 line Add a 'c_longdouble' type to the ctypes module. ........ r58035 | thomas.heller | 2007-09-07 11:30:40 +0200 (Fri, 07 Sep 2007) | 1 line Remove unneeded #include. ........ r58036 | thomas.heller | 2007-09-07 11:33:24 +0200 (Fri, 07 Sep 2007) | 6 lines Backport from py3k branch: Add a workaround for a strange bug on win64, when _ctypes is compiled with the SDK compiler. This should fix the failing Lib\ctypes\test\test_as_parameter.py test. ........ r58037 | georg.brandl | 2007-09-07 16:14:40 +0200 (Fri, 07 Sep 2007) | 2 lines Fix a wrong indentation for sublists. ........ r58043 | georg.brandl | 2007-09-07 22:10:49 +0200 (Fri, 07 Sep 2007) | 2 lines #1095: ln -f doesn't work portably, fix in Makefile. ........ r58049 | skip.montanaro | 2007-09-08 02:34:17 +0200 (Sat, 08 Sep 2007) | 1 line be explicit about the actual location of the missing file ........
19 years ago
  1. #include "Python.h"
  2. #include "frameobject.h"
  3. #include "rotatingtree.h"
  4. #if !defined(HAVE_LONG_LONG)
  5. #error "This module requires long longs!"
  6. #endif
  7. /*** Selection of a high-precision timer ***/
  8. #ifdef MS_WINDOWS
  9. #include <windows.h>
  10. static PY_LONG_LONG
  11. hpTimer(void)
  12. {
  13. LARGE_INTEGER li;
  14. QueryPerformanceCounter(&li);
  15. return li.QuadPart;
  16. }
  17. static double
  18. hpTimerUnit(void)
  19. {
  20. LARGE_INTEGER li;
  21. if (QueryPerformanceFrequency(&li))
  22. return 1.0 / li.QuadPart;
  23. else
  24. return 0.000001; /* unlikely */
  25. }
  26. #else /* !MS_WINDOWS */
  27. #ifndef HAVE_GETTIMEOFDAY
  28. #error "This module requires gettimeofday() on non-Windows platforms!"
  29. #endif
  30. #if (defined(PYOS_OS2) && defined(PYCC_GCC))
  31. #include <sys/time.h>
  32. #else
  33. #include <sys/resource.h>
  34. #include <sys/times.h>
  35. #endif
  36. static PY_LONG_LONG
  37. hpTimer(void)
  38. {
  39. struct timeval tv;
  40. PY_LONG_LONG ret;
  41. #ifdef GETTIMEOFDAY_NO_TZ
  42. gettimeofday(&tv);
  43. #else
  44. gettimeofday(&tv, (struct timezone *)NULL);
  45. #endif
  46. ret = tv.tv_sec;
  47. ret = ret * 1000000 + tv.tv_usec;
  48. return ret;
  49. }
  50. static double
  51. hpTimerUnit(void)
  52. {
  53. return 0.000001;
  54. }
  55. #endif /* MS_WINDOWS */
  56. /************************************************************/
  57. /* Written by Brett Rosen and Ted Czotter */
  58. struct _ProfilerEntry;
  59. /* represents a function called from another function */
  60. typedef struct _ProfilerSubEntry {
  61. rotating_node_t header;
  62. PY_LONG_LONG tt;
  63. PY_LONG_LONG it;
  64. long callcount;
  65. long recursivecallcount;
  66. long recursionLevel;
  67. } ProfilerSubEntry;
  68. /* represents a function or user defined block */
  69. typedef struct _ProfilerEntry {
  70. rotating_node_t header;
  71. PyObject *userObj; /* PyCodeObject, or a descriptive str for builtins */
  72. PY_LONG_LONG tt; /* total time in this entry */
  73. PY_LONG_LONG it; /* inline time in this entry (not in subcalls) */
  74. long callcount; /* how many times this was called */
  75. long recursivecallcount; /* how many times called recursively */
  76. long recursionLevel;
  77. rotating_node_t *calls;
  78. } ProfilerEntry;
  79. typedef struct _ProfilerContext {
  80. PY_LONG_LONG t0;
  81. PY_LONG_LONG subt;
  82. struct _ProfilerContext *previous;
  83. ProfilerEntry *ctxEntry;
  84. } ProfilerContext;
  85. typedef struct {
  86. PyObject_HEAD
  87. rotating_node_t *profilerEntries;
  88. ProfilerContext *currentProfilerContext;
  89. ProfilerContext *freelistProfilerContext;
  90. int flags;
  91. PyObject *externalTimer;
  92. double externalTimerUnit;
  93. } ProfilerObject;
  94. #define POF_ENABLED 0x001
  95. #define POF_SUBCALLS 0x002
  96. #define POF_BUILTINS 0x004
  97. #define POF_NOMEMORY 0x100
  98. static PyTypeObject PyProfiler_Type;
  99. #define PyProfiler_Check(op) PyObject_TypeCheck(op, &PyProfiler_Type)
  100. #define PyProfiler_CheckExact(op) (Py_TYPE(op) == &PyProfiler_Type)
  101. /*** External Timers ***/
  102. #define DOUBLE_TIMER_PRECISION 4294967296.0
  103. static PyObject *empty_tuple;
  104. static PY_LONG_LONG CallExternalTimer(ProfilerObject *pObj)
  105. {
  106. PY_LONG_LONG result;
  107. PyObject *o = PyObject_Call(pObj->externalTimer, empty_tuple, NULL);
  108. if (o == NULL) {
  109. PyErr_WriteUnraisable(pObj->externalTimer);
  110. return 0;
  111. }
  112. if (pObj->externalTimerUnit > 0.0) {
  113. /* interpret the result as an integer that will be scaled
  114. in profiler_getstats() */
  115. result = PyLong_AsLongLong(o);
  116. }
  117. else {
  118. /* interpret the result as a double measured in seconds.
  119. As the profiler works with PY_LONG_LONG internally
  120. we convert it to a large integer */
  121. double val = PyFloat_AsDouble(o);
  122. /* error handling delayed to the code below */
  123. result = (PY_LONG_LONG) (val * DOUBLE_TIMER_PRECISION);
  124. }
  125. Py_DECREF(o);
  126. if (PyErr_Occurred()) {
  127. PyErr_WriteUnraisable(pObj->externalTimer);
  128. return 0;
  129. }
  130. return result;
  131. }
  132. #define CALL_TIMER(pObj) ((pObj)->externalTimer ? \
  133. CallExternalTimer(pObj) : \
  134. hpTimer())
  135. /*** ProfilerObject ***/
  136. static PyObject *
  137. normalizeUserObj(PyObject *obj)
  138. {
  139. PyCFunctionObject *fn;
  140. if (!PyCFunction_Check(obj)) {
  141. Py_INCREF(obj);
  142. return obj;
  143. }
  144. /* Replace built-in function objects with a descriptive string
  145. because of built-in methods -- keeping a reference to
  146. __self__ is probably not a good idea. */
  147. fn = (PyCFunctionObject *)obj;
  148. if (fn->m_self == NULL) {
  149. /* built-in function: look up the module name */
  150. PyObject *mod = fn->m_module;
  151. PyObject *modname = NULL;
  152. if (mod != NULL) {
  153. if (PyUnicode_Check(mod)) {
  154. modname = mod;
  155. Py_INCREF(modname);
  156. }
  157. else if (PyModule_Check(mod)) {
  158. modname = PyModule_GetNameObject(mod);
  159. if (modname == NULL)
  160. PyErr_Clear();
  161. }
  162. }
  163. if (modname != NULL) {
  164. if (PyUnicode_CompareWithASCIIString(modname, "builtins") != 0) {
  165. PyObject *result;
  166. result = PyUnicode_FromFormat("<%U.%s>", modname,
  167. fn->m_ml->ml_name);
  168. Py_DECREF(modname);
  169. return result;
  170. }
  171. Py_DECREF(modname);
  172. }
  173. return PyUnicode_FromFormat("<%s>", fn->m_ml->ml_name);
  174. }
  175. else {
  176. /* built-in method: try to return
  177. repr(getattr(type(__self__), __name__))
  178. */
  179. PyObject *self = fn->m_self;
  180. PyObject *name = PyUnicode_FromString(fn->m_ml->ml_name);
  181. if (name != NULL) {
  182. PyObject *mo = _PyType_Lookup(Py_TYPE(self), name);
  183. Py_XINCREF(mo);
  184. Py_DECREF(name);
  185. if (mo != NULL) {
  186. PyObject *res = PyObject_Repr(mo);
  187. Py_DECREF(mo);
  188. if (res != NULL)
  189. return res;
  190. }
  191. }
  192. PyErr_Clear();
  193. return PyUnicode_FromFormat("<built-in method %s>",
  194. fn->m_ml->ml_name);
  195. }
  196. }
  197. static ProfilerEntry*
  198. newProfilerEntry(ProfilerObject *pObj, void *key, PyObject *userObj)
  199. {
  200. ProfilerEntry *self;
  201. self = (ProfilerEntry*) malloc(sizeof(ProfilerEntry));
  202. if (self == NULL) {
  203. pObj->flags |= POF_NOMEMORY;
  204. return NULL;
  205. }
  206. userObj = normalizeUserObj(userObj);
  207. if (userObj == NULL) {
  208. PyErr_Clear();
  209. free(self);
  210. pObj->flags |= POF_NOMEMORY;
  211. return NULL;
  212. }
  213. self->header.key = key;
  214. self->userObj = userObj;
  215. self->tt = 0;
  216. self->it = 0;
  217. self->callcount = 0;
  218. self->recursivecallcount = 0;
  219. self->recursionLevel = 0;
  220. self->calls = EMPTY_ROTATING_TREE;
  221. RotatingTree_Add(&pObj->profilerEntries, &self->header);
  222. return self;
  223. }
  224. static ProfilerEntry*
  225. getEntry(ProfilerObject *pObj, void *key)
  226. {
  227. return (ProfilerEntry*) RotatingTree_Get(&pObj->profilerEntries, key);
  228. }
  229. static ProfilerSubEntry *
  230. getSubEntry(ProfilerObject *pObj, ProfilerEntry *caller, ProfilerEntry* entry)
  231. {
  232. return (ProfilerSubEntry*) RotatingTree_Get(&caller->calls,
  233. (void *)entry);
  234. }
  235. static ProfilerSubEntry *
  236. newSubEntry(ProfilerObject *pObj, ProfilerEntry *caller, ProfilerEntry* entry)
  237. {
  238. ProfilerSubEntry *self;
  239. self = (ProfilerSubEntry*) malloc(sizeof(ProfilerSubEntry));
  240. if (self == NULL) {
  241. pObj->flags |= POF_NOMEMORY;
  242. return NULL;
  243. }
  244. self->header.key = (void *)entry;
  245. self->tt = 0;
  246. self->it = 0;
  247. self->callcount = 0;
  248. self->recursivecallcount = 0;
  249. self->recursionLevel = 0;
  250. RotatingTree_Add(&caller->calls, &self->header);
  251. return self;
  252. }
  253. static int freeSubEntry(rotating_node_t *header, void *arg)
  254. {
  255. ProfilerSubEntry *subentry = (ProfilerSubEntry*) header;
  256. free(subentry);
  257. return 0;
  258. }
  259. static int freeEntry(rotating_node_t *header, void *arg)
  260. {
  261. ProfilerEntry *entry = (ProfilerEntry*) header;
  262. RotatingTree_Enum(entry->calls, freeSubEntry, NULL);
  263. Py_DECREF(entry->userObj);
  264. free(entry);
  265. return 0;
  266. }
  267. static void clearEntries(ProfilerObject *pObj)
  268. {
  269. RotatingTree_Enum(pObj->profilerEntries, freeEntry, NULL);
  270. pObj->profilerEntries = EMPTY_ROTATING_TREE;
  271. /* release the memory hold by the ProfilerContexts */
  272. if (pObj->currentProfilerContext) {
  273. free(pObj->currentProfilerContext);
  274. pObj->currentProfilerContext = NULL;
  275. }
  276. while (pObj->freelistProfilerContext) {
  277. ProfilerContext *c = pObj->freelistProfilerContext;
  278. pObj->freelistProfilerContext = c->previous;
  279. free(c);
  280. }
  281. pObj->freelistProfilerContext = NULL;
  282. }
  283. static void
  284. initContext(ProfilerObject *pObj, ProfilerContext *self, ProfilerEntry *entry)
  285. {
  286. self->ctxEntry = entry;
  287. self->subt = 0;
  288. self->previous = pObj->currentProfilerContext;
  289. pObj->currentProfilerContext = self;
  290. ++entry->recursionLevel;
  291. if ((pObj->flags & POF_SUBCALLS) && self->previous) {
  292. /* find or create an entry for me in my caller's entry */
  293. ProfilerEntry *caller = self->previous->ctxEntry;
  294. ProfilerSubEntry *subentry = getSubEntry(pObj, caller, entry);
  295. if (subentry == NULL)
  296. subentry = newSubEntry(pObj, caller, entry);
  297. if (subentry)
  298. ++subentry->recursionLevel;
  299. }
  300. self->t0 = CALL_TIMER(pObj);
  301. }
  302. static void
  303. Stop(ProfilerObject *pObj, ProfilerContext *self, ProfilerEntry *entry)
  304. {
  305. PY_LONG_LONG tt = CALL_TIMER(pObj) - self->t0;
  306. PY_LONG_LONG it = tt - self->subt;
  307. if (self->previous)
  308. self->previous->subt += tt;
  309. pObj->currentProfilerContext = self->previous;
  310. if (--entry->recursionLevel == 0)
  311. entry->tt += tt;
  312. else
  313. ++entry->recursivecallcount;
  314. entry->it += it;
  315. entry->callcount++;
  316. if ((pObj->flags & POF_SUBCALLS) && self->previous) {
  317. /* find or create an entry for me in my caller's entry */
  318. ProfilerEntry *caller = self->previous->ctxEntry;
  319. ProfilerSubEntry *subentry = getSubEntry(pObj, caller, entry);
  320. if (subentry) {
  321. if (--subentry->recursionLevel == 0)
  322. subentry->tt += tt;
  323. else
  324. ++subentry->recursivecallcount;
  325. subentry->it += it;
  326. ++subentry->callcount;
  327. }
  328. }
  329. }
  330. static void
  331. ptrace_enter_call(PyObject *self, void *key, PyObject *userObj)
  332. {
  333. /* entering a call to the function identified by 'key'
  334. (which can be a PyCodeObject or a PyMethodDef pointer) */
  335. ProfilerObject *pObj = (ProfilerObject*)self;
  336. ProfilerEntry *profEntry;
  337. ProfilerContext *pContext;
  338. /* In the case of entering a generator expression frame via a
  339. * throw (gen_send_ex(.., 1)), we may already have an
  340. * Exception set here. We must not mess around with this
  341. * exception, and some of the code under here assumes that
  342. * PyErr_* is its own to mess around with, so we have to
  343. * save and restore any current exception. */
  344. PyObject *last_type, *last_value, *last_tb;
  345. PyErr_Fetch(&last_type, &last_value, &last_tb);
  346. profEntry = getEntry(pObj, key);
  347. if (profEntry == NULL) {
  348. profEntry = newProfilerEntry(pObj, key, userObj);
  349. if (profEntry == NULL)
  350. goto restorePyerr;
  351. }
  352. /* grab a ProfilerContext out of the free list */
  353. pContext = pObj->freelistProfilerContext;
  354. if (pContext) {
  355. pObj->freelistProfilerContext = pContext->previous;
  356. }
  357. else {
  358. /* free list exhausted, allocate a new one */
  359. pContext = (ProfilerContext*)
  360. malloc(sizeof(ProfilerContext));
  361. if (pContext == NULL) {
  362. pObj->flags |= POF_NOMEMORY;
  363. goto restorePyerr;
  364. }
  365. }
  366. initContext(pObj, pContext, profEntry);
  367. restorePyerr:
  368. PyErr_Restore(last_type, last_value, last_tb);
  369. }
  370. static void
  371. ptrace_leave_call(PyObject *self, void *key)
  372. {
  373. /* leaving a call to the function identified by 'key' */
  374. ProfilerObject *pObj = (ProfilerObject*)self;
  375. ProfilerEntry *profEntry;
  376. ProfilerContext *pContext;
  377. pContext = pObj->currentProfilerContext;
  378. if (pContext == NULL)
  379. return;
  380. profEntry = getEntry(pObj, key);
  381. if (profEntry) {
  382. Stop(pObj, pContext, profEntry);
  383. }
  384. else {
  385. pObj->currentProfilerContext = pContext->previous;
  386. }
  387. /* put pContext into the free list */
  388. pContext->previous = pObj->freelistProfilerContext;
  389. pObj->freelistProfilerContext = pContext;
  390. }
  391. static int
  392. profiler_callback(PyObject *self, PyFrameObject *frame, int what,
  393. PyObject *arg)
  394. {
  395. switch (what) {
  396. /* the 'frame' of a called function is about to start its execution */
  397. case PyTrace_CALL:
  398. ptrace_enter_call(self, (void *)frame->f_code,
  399. (PyObject *)frame->f_code);
  400. break;
  401. /* the 'frame' of a called function is about to finish
  402. (either normally or with an exception) */
  403. case PyTrace_RETURN:
  404. ptrace_leave_call(self, (void *)frame->f_code);
  405. break;
  406. /* case PyTrace_EXCEPTION:
  407. If the exception results in the function exiting, a
  408. PyTrace_RETURN event will be generated, so we don't need to
  409. handle it. */
  410. #ifdef PyTrace_C_CALL /* not defined in Python <= 2.3 */
  411. /* the Python function 'frame' is issuing a call to the built-in
  412. function 'arg' */
  413. case PyTrace_C_CALL:
  414. if ((((ProfilerObject *)self)->flags & POF_BUILTINS)
  415. && PyCFunction_Check(arg)) {
  416. ptrace_enter_call(self,
  417. ((PyCFunctionObject *)arg)->m_ml,
  418. arg);
  419. }
  420. break;
  421. /* the call to the built-in function 'arg' is returning into its
  422. caller 'frame' */
  423. case PyTrace_C_RETURN: /* ...normally */
  424. case PyTrace_C_EXCEPTION: /* ...with an exception set */
  425. if ((((ProfilerObject *)self)->flags & POF_BUILTINS)
  426. && PyCFunction_Check(arg)) {
  427. ptrace_leave_call(self,
  428. ((PyCFunctionObject *)arg)->m_ml);
  429. }
  430. break;
  431. #endif
  432. default:
  433. break;
  434. }
  435. return 0;
  436. }
  437. static int
  438. pending_exception(ProfilerObject *pObj)
  439. {
  440. if (pObj->flags & POF_NOMEMORY) {
  441. pObj->flags -= POF_NOMEMORY;
  442. PyErr_SetString(PyExc_MemoryError,
  443. "memory was exhausted while profiling");
  444. return -1;
  445. }
  446. return 0;
  447. }
  448. /************************************************************/
  449. static PyStructSequence_Field profiler_entry_fields[] = {
  450. {"code", "code object or built-in function name"},
  451. {"callcount", "how many times this was called"},
  452. {"reccallcount", "how many times called recursively"},
  453. {"totaltime", "total time in this entry"},
  454. {"inlinetime", "inline time in this entry (not in subcalls)"},
  455. {"calls", "details of the calls"},
  456. {0}
  457. };
  458. static PyStructSequence_Field profiler_subentry_fields[] = {
  459. {"code", "called code object or built-in function name"},
  460. {"callcount", "how many times this is called"},
  461. {"reccallcount", "how many times this is called recursively"},
  462. {"totaltime", "total time spent in this call"},
  463. {"inlinetime", "inline time (not in further subcalls)"},
  464. {0}
  465. };
  466. static PyStructSequence_Desc profiler_entry_desc = {
  467. "_lsprof.profiler_entry", /* name */
  468. NULL, /* doc */
  469. profiler_entry_fields,
  470. 6
  471. };
  472. static PyStructSequence_Desc profiler_subentry_desc = {
  473. "_lsprof.profiler_subentry", /* name */
  474. NULL, /* doc */
  475. profiler_subentry_fields,
  476. 5
  477. };
  478. static int initialized;
  479. static PyTypeObject StatsEntryType;
  480. static PyTypeObject StatsSubEntryType;
  481. typedef struct {
  482. PyObject *list;
  483. PyObject *sublist;
  484. double factor;
  485. } statscollector_t;
  486. static int statsForSubEntry(rotating_node_t *node, void *arg)
  487. {
  488. ProfilerSubEntry *sentry = (ProfilerSubEntry*) node;
  489. statscollector_t *collect = (statscollector_t*) arg;
  490. ProfilerEntry *entry = (ProfilerEntry*) sentry->header.key;
  491. int err;
  492. PyObject *sinfo;
  493. sinfo = PyObject_CallFunction((PyObject*) &StatsSubEntryType,
  494. "((Olldd))",
  495. entry->userObj,
  496. sentry->callcount,
  497. sentry->recursivecallcount,
  498. collect->factor * sentry->tt,
  499. collect->factor * sentry->it);
  500. if (sinfo == NULL)
  501. return -1;
  502. err = PyList_Append(collect->sublist, sinfo);
  503. Py_DECREF(sinfo);
  504. return err;
  505. }
  506. static int statsForEntry(rotating_node_t *node, void *arg)
  507. {
  508. ProfilerEntry *entry = (ProfilerEntry*) node;
  509. statscollector_t *collect = (statscollector_t*) arg;
  510. PyObject *info;
  511. int err;
  512. if (entry->callcount == 0)
  513. return 0; /* skip */
  514. if (entry->calls != EMPTY_ROTATING_TREE) {
  515. collect->sublist = PyList_New(0);
  516. if (collect->sublist == NULL)
  517. return -1;
  518. if (RotatingTree_Enum(entry->calls,
  519. statsForSubEntry, collect) != 0) {
  520. Py_DECREF(collect->sublist);
  521. return -1;
  522. }
  523. }
  524. else {
  525. Py_INCREF(Py_None);
  526. collect->sublist = Py_None;
  527. }
  528. info = PyObject_CallFunction((PyObject*) &StatsEntryType,
  529. "((OllddO))",
  530. entry->userObj,
  531. entry->callcount,
  532. entry->recursivecallcount,
  533. collect->factor * entry->tt,
  534. collect->factor * entry->it,
  535. collect->sublist);
  536. Py_DECREF(collect->sublist);
  537. if (info == NULL)
  538. return -1;
  539. err = PyList_Append(collect->list, info);
  540. Py_DECREF(info);
  541. return err;
  542. }
  543. PyDoc_STRVAR(getstats_doc, "\
  544. getstats() -> list of profiler_entry objects\n\
  545. \n\
  546. Return all information collected by the profiler.\n\
  547. Each profiler_entry is a tuple-like object with the\n\
  548. following attributes:\n\
  549. \n\
  550. code code object\n\
  551. callcount how many times this was called\n\
  552. reccallcount how many times called recursively\n\
  553. totaltime total time in this entry\n\
  554. inlinetime inline time in this entry (not in subcalls)\n\
  555. calls details of the calls\n\
  556. \n\
  557. The calls attribute is either None or a list of\n\
  558. profiler_subentry objects:\n\
  559. \n\
  560. code called code object\n\
  561. callcount how many times this is called\n\
  562. reccallcount how many times this is called recursively\n\
  563. totaltime total time spent in this call\n\
  564. inlinetime inline time (not in further subcalls)\n\
  565. ");
  566. static PyObject*
  567. profiler_getstats(ProfilerObject *pObj, PyObject* noarg)
  568. {
  569. statscollector_t collect;
  570. if (pending_exception(pObj))
  571. return NULL;
  572. if (!pObj->externalTimer)
  573. collect.factor = hpTimerUnit();
  574. else if (pObj->externalTimerUnit > 0.0)
  575. collect.factor = pObj->externalTimerUnit;
  576. else
  577. collect.factor = 1.0 / DOUBLE_TIMER_PRECISION;
  578. collect.list = PyList_New(0);
  579. if (collect.list == NULL)
  580. return NULL;
  581. if (RotatingTree_Enum(pObj->profilerEntries, statsForEntry, &collect)
  582. != 0) {
  583. Py_DECREF(collect.list);
  584. return NULL;
  585. }
  586. return collect.list;
  587. }
  588. static int
  589. setSubcalls(ProfilerObject *pObj, int nvalue)
  590. {
  591. if (nvalue == 0)
  592. pObj->flags &= ~POF_SUBCALLS;
  593. else if (nvalue > 0)
  594. pObj->flags |= POF_SUBCALLS;
  595. return 0;
  596. }
  597. static int
  598. setBuiltins(ProfilerObject *pObj, int nvalue)
  599. {
  600. if (nvalue == 0)
  601. pObj->flags &= ~POF_BUILTINS;
  602. else if (nvalue > 0) {
  603. #ifndef PyTrace_C_CALL
  604. PyErr_SetString(PyExc_ValueError,
  605. "builtins=True requires Python >= 2.4");
  606. return -1;
  607. #else
  608. pObj->flags |= POF_BUILTINS;
  609. #endif
  610. }
  611. return 0;
  612. }
  613. PyDoc_STRVAR(enable_doc, "\
  614. enable(subcalls=True, builtins=True)\n\
  615. \n\
  616. Start collecting profiling information.\n\
  617. If 'subcalls' is True, also records for each function\n\
  618. statistics separated according to its current caller.\n\
  619. If 'builtins' is True, records the time spent in\n\
  620. built-in functions separately from their caller.\n\
  621. ");
  622. static PyObject*
  623. profiler_enable(ProfilerObject *self, PyObject *args, PyObject *kwds)
  624. {
  625. int subcalls = -1;
  626. int builtins = -1;
  627. static char *kwlist[] = {"subcalls", "builtins", 0};
  628. if (!PyArg_ParseTupleAndKeywords(args, kwds, "|ii:enable",
  629. kwlist, &subcalls, &builtins))
  630. return NULL;
  631. if (setSubcalls(self, subcalls) < 0 || setBuiltins(self, builtins) < 0)
  632. return NULL;
  633. PyEval_SetProfile(profiler_callback, (PyObject*)self);
  634. self->flags |= POF_ENABLED;
  635. Py_INCREF(Py_None);
  636. return Py_None;
  637. }
  638. static void
  639. flush_unmatched(ProfilerObject *pObj)
  640. {
  641. while (pObj->currentProfilerContext) {
  642. ProfilerContext *pContext = pObj->currentProfilerContext;
  643. ProfilerEntry *profEntry= pContext->ctxEntry;
  644. if (profEntry)
  645. Stop(pObj, pContext, profEntry);
  646. else
  647. pObj->currentProfilerContext = pContext->previous;
  648. if (pContext)
  649. free(pContext);
  650. }
  651. }
  652. PyDoc_STRVAR(disable_doc, "\
  653. disable()\n\
  654. \n\
  655. Stop collecting profiling information.\n\
  656. ");
  657. static PyObject*
  658. profiler_disable(ProfilerObject *self, PyObject* noarg)
  659. {
  660. self->flags &= ~POF_ENABLED;
  661. PyEval_SetProfile(NULL, NULL);
  662. flush_unmatched(self);
  663. if (pending_exception(self))
  664. return NULL;
  665. Py_INCREF(Py_None);
  666. return Py_None;
  667. }
  668. PyDoc_STRVAR(clear_doc, "\
  669. clear()\n\
  670. \n\
  671. Clear all profiling information collected so far.\n\
  672. ");
  673. static PyObject*
  674. profiler_clear(ProfilerObject *pObj, PyObject* noarg)
  675. {
  676. clearEntries(pObj);
  677. Py_INCREF(Py_None);
  678. return Py_None;
  679. }
  680. static void
  681. profiler_dealloc(ProfilerObject *op)
  682. {
  683. if (op->flags & POF_ENABLED)
  684. PyEval_SetProfile(NULL, NULL);
  685. flush_unmatched(op);
  686. clearEntries(op);
  687. Py_XDECREF(op->externalTimer);
  688. Py_TYPE(op)->tp_free(op);
  689. }
  690. static int
  691. profiler_init(ProfilerObject *pObj, PyObject *args, PyObject *kw)
  692. {
  693. PyObject *o;
  694. PyObject *timer = NULL;
  695. double timeunit = 0.0;
  696. int subcalls = 1;
  697. #ifdef PyTrace_C_CALL
  698. int builtins = 1;
  699. #else
  700. int builtins = 0;
  701. #endif
  702. static char *kwlist[] = {"timer", "timeunit",
  703. "subcalls", "builtins", 0};
  704. if (!PyArg_ParseTupleAndKeywords(args, kw, "|Odii:Profiler", kwlist,
  705. &timer, &timeunit,
  706. &subcalls, &builtins))
  707. return -1;
  708. if (setSubcalls(pObj, subcalls) < 0 || setBuiltins(pObj, builtins) < 0)
  709. return -1;
  710. o = pObj->externalTimer;
  711. pObj->externalTimer = timer;
  712. Py_XINCREF(timer);
  713. Py_XDECREF(o);
  714. pObj->externalTimerUnit = timeunit;
  715. return 0;
  716. }
  717. static PyMethodDef profiler_methods[] = {
  718. {"getstats", (PyCFunction)profiler_getstats,
  719. METH_NOARGS, getstats_doc},
  720. {"enable", (PyCFunction)profiler_enable,
  721. METH_VARARGS | METH_KEYWORDS, enable_doc},
  722. {"disable", (PyCFunction)profiler_disable,
  723. METH_NOARGS, disable_doc},
  724. {"clear", (PyCFunction)profiler_clear,
  725. METH_NOARGS, clear_doc},
  726. {NULL, NULL}
  727. };
  728. PyDoc_STRVAR(profiler_doc, "\
  729. Profiler(custom_timer=None, time_unit=None, subcalls=True, builtins=True)\n\
  730. \n\
  731. Builds a profiler object using the specified timer function.\n\
  732. The default timer is a fast built-in one based on real time.\n\
  733. For custom timer functions returning integers, time_unit can\n\
  734. be a float specifying a scale (i.e. how long each integer unit\n\
  735. is, in seconds).\n\
  736. ");
  737. static PyTypeObject PyProfiler_Type = {
  738. PyVarObject_HEAD_INIT(NULL, 0)
  739. "_lsprof.Profiler", /* tp_name */
  740. sizeof(ProfilerObject), /* tp_basicsize */
  741. 0, /* tp_itemsize */
  742. (destructor)profiler_dealloc, /* tp_dealloc */
  743. 0, /* tp_print */
  744. 0, /* tp_getattr */
  745. 0, /* tp_setattr */
  746. 0, /* tp_reserved */
  747. 0, /* tp_repr */
  748. 0, /* tp_as_number */
  749. 0, /* tp_as_sequence */
  750. 0, /* tp_as_mapping */
  751. 0, /* tp_hash */
  752. 0, /* tp_call */
  753. 0, /* tp_str */
  754. 0, /* tp_getattro */
  755. 0, /* tp_setattro */
  756. 0, /* tp_as_buffer */
  757. Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
  758. profiler_doc, /* tp_doc */
  759. 0, /* tp_traverse */
  760. 0, /* tp_clear */
  761. 0, /* tp_richcompare */
  762. 0, /* tp_weaklistoffset */
  763. 0, /* tp_iter */
  764. 0, /* tp_iternext */
  765. profiler_methods, /* tp_methods */
  766. 0, /* tp_members */
  767. 0, /* tp_getset */
  768. 0, /* tp_base */
  769. 0, /* tp_dict */
  770. 0, /* tp_descr_get */
  771. 0, /* tp_descr_set */
  772. 0, /* tp_dictoffset */
  773. (initproc)profiler_init, /* tp_init */
  774. PyType_GenericAlloc, /* tp_alloc */
  775. PyType_GenericNew, /* tp_new */
  776. PyObject_Del, /* tp_free */
  777. };
  778. static PyMethodDef moduleMethods[] = {
  779. {NULL, NULL}
  780. };
  781. static struct PyModuleDef _lsprofmodule = {
  782. PyModuleDef_HEAD_INIT,
  783. "_lsprof",
  784. "Fast profiler",
  785. -1,
  786. moduleMethods,
  787. NULL,
  788. NULL,
  789. NULL,
  790. NULL
  791. };
  792. PyMODINIT_FUNC
  793. PyInit__lsprof(void)
  794. {
  795. PyObject *module, *d;
  796. module = PyModule_Create(&_lsprofmodule);
  797. if (module == NULL)
  798. return NULL;
  799. d = PyModule_GetDict(module);
  800. if (PyType_Ready(&PyProfiler_Type) < 0)
  801. return NULL;
  802. PyDict_SetItemString(d, "Profiler", (PyObject *)&PyProfiler_Type);
  803. if (!initialized) {
  804. PyStructSequence_InitType(&StatsEntryType,
  805. &profiler_entry_desc);
  806. PyStructSequence_InitType(&StatsSubEntryType,
  807. &profiler_subentry_desc);
  808. }
  809. Py_INCREF((PyObject*) &StatsEntryType);
  810. Py_INCREF((PyObject*) &StatsSubEntryType);
  811. PyModule_AddObject(module, "profiler_entry",
  812. (PyObject*) &StatsEntryType);
  813. PyModule_AddObject(module, "profiler_subentry",
  814. (PyObject*) &StatsSubEntryType);
  815. empty_tuple = PyTuple_New(0);
  816. initialized = 1;
  817. return module;
  818. }