summaryrefslogtreecommitdiffstats
path: root/Include
diff options
context:
space:
mode:
authorJeremy Hylton <jeremy@alum.mit.edu>2003-02-05 23:13:00 (GMT)
committerJeremy Hylton <jeremy@alum.mit.edu>2003-02-05 23:13:00 (GMT)
commit985eba53f5d1ac45037fbf19b6955c74823c1ded (patch)
treef847567e9468a46df6f0a55b7d437a3697e7f248 /Include
parentf3f4af55214370e5c6df928e8c8242d14060e204 (diff)
downloadcpython-985eba53f5d1ac45037fbf19b6955c74823c1ded.zip
cpython-985eba53f5d1ac45037fbf19b6955c74823c1ded.tar.gz
cpython-985eba53f5d1ac45037fbf19b6955c74823c1ded.tar.bz2
Small function call optimization and special build option for call stats.
-DCALL_PROFILE: Count the number of function calls executed. When this symbol is defined, the ceval mainloop and helper functions count the number of function calls made. It keeps detailed statistics about what kind of object was called and whether the call hit any of the special fast paths in the code. Optimization: When we take the fast_function() path, which seems to be taken for most function calls, and there is minimal frame setup to do, avoid call PyEval_EvalCodeEx(). The eval code ex function does a lot of work to handle keywords args and star args, free variables, generators, etc. The inlined version simply allocates the frame and copies the arguments values into the frame. The optimization gets a little help from compile.c which adds a CO_NOFREE flag to code objects that don't have free variables or cell variables. This change allows fast_function() to get into the fast path with fewer tests. I measure a couple of percent speedup in pystone with this change, but there's surely more that can be done.
Diffstat (limited to 'Include')
-rw-r--r--Include/ceval.h2
-rw-r--r--Include/compile.h6
2 files changed, 8 insertions, 0 deletions
diff --git a/Include/ceval.h b/Include/ceval.h
index e1af801..9bb145d 100644
--- a/Include/ceval.h
+++ b/Include/ceval.h
@@ -48,6 +48,8 @@ PyAPI_FUNC(int) Py_GetRecursionLimit(void);
PyAPI_FUNC(char *) PyEval_GetFuncName(PyObject *);
PyAPI_FUNC(char *) PyEval_GetFuncDesc(PyObject *);
+PyAPI_FUNC(PyObject *) PyEval_GetCallStats(PyObject *);
+
/* this used to be handled on a per-thread basis - now just two globals */
PyAPI_DATA(volatile int) _Py_Ticker;
PyAPI_DATA(int) _Py_CheckInterval;
diff --git a/Include/compile.h b/Include/compile.h
index a462d77..594d7df 100644
--- a/Include/compile.h
+++ b/Include/compile.h
@@ -34,6 +34,12 @@ typedef struct {
#define CO_VARKEYWORDS 0x0008
#define CO_NESTED 0x0010
#define CO_GENERATOR 0x0020
+/* The CO_NOFREE flag is set if there are no free or cell variables.
+ This information is redundant, but it allows a single flag test
+ to determine whether there is any extra work to be done when the
+ call frame it setup.
+*/
+#define CO_NOFREE 0x0040
/* XXX Temporary hack. Until generators are a permanent part of the
language, we need a way for a code object to record that generators
were *possible* when it was compiled. This is so code dynamically