ef3bbed
diff -up Python-2.6.4/configure.in.systemtap Python-2.6.4/configure.in
ef3bbed
--- Python-2.6.4/configure.in.systemtap	2009-12-18 15:37:15.632242686 -0500
ef3bbed
+++ Python-2.6.4/configure.in	2009-12-18 15:37:15.713244483 -0500
ef3bbed
@@ -2481,6 +2481,38 @@ if test "$with_valgrind" != no; then
ef3bbed
     )
ef3bbed
 fi
ef3bbed
 
ef3bbed
+# Check for dtrace support
ef3bbed
+AC_MSG_CHECKING(for --with-dtrace)
ef3bbed
+AC_ARG_WITH(dtrace,
ef3bbed
+            AC_HELP_STRING(--with(out)-dtrace, disable/enable dtrace support))
ef3bbed
+
ef3bbed
+if test ! -z "$with_dtrace"
ef3bbed
+then
ef3bbed
+    if dtrace -G -o /dev/null -s $srcdir/Include/pydtrace.d 2>/dev/null
ef3bbed
+    then
ef3bbed
+	AC_DEFINE(WITH_DTRACE, 1, 
ef3bbed
+	 [Define if you want to compile in Dtrace support])
ef3bbed
+	with_dtrace="Sun"
ef3bbed
+	DTRACEOBJS="Python/phelper.o Python/dtrace.o"
ef3bbed
+	DTRADEHDRS=""
ef3bbed
+    elif dtrace -h -o /dev/null -s $srcdir/Include/pydtrace.d
ef3bbed
+    then
ef3bbed
+	AC_DEFINE(WITH_DTRACE, 1, 
ef3bbed
+	 [Define if you want to compile in Dtrace support])
ef3bbed
+	with_dtrace="Apple"
ef3bbed
+	DTRACEOBJS=""
ef3bbed
+	DTRADEHDRS="phelper.h pydtrace.h"
ef3bbed
+    else
ef3bbed
+	with_dtrace="no"
ef3bbed
+    fi
ef3bbed
+else
ef3bbed
+    with_dtrace="no"
ef3bbed
+fi
ef3bbed
+
ef3bbed
+AC_MSG_RESULT($with_dtrace)
ef3bbed
+AC_SUBST(DTRACEOBJS)
ef3bbed
+AC_SUBST(DTRACEHDRS)
ef3bbed
+
ef3bbed
 # Check for --with-wctype-functions
ef3bbed
 AC_MSG_CHECKING(for --with-wctype-functions)
ef3bbed
 AC_ARG_WITH(wctype-functions, 
ef3bbed
diff -up Python-2.6.4/Include/frameobject.h.systemtap Python-2.6.4/Include/frameobject.h
ef3bbed
--- Python-2.6.4/Include/frameobject.h.systemtap	2008-02-14 07:47:33.000000000 -0500
ef3bbed
+++ Python-2.6.4/Include/frameobject.h	2009-12-18 15:37:15.714243772 -0500
ef3bbed
@@ -41,6 +41,9 @@ typedef struct _frame {
ef3bbed
     /* As of 2.3 f_lineno is only valid when tracing is active (i.e. when
ef3bbed
        f_trace is set) -- at other times use PyCode_Addr2Line instead. */
ef3bbed
     int f_lineno;		/* Current line number */
ef3bbed
+#ifdef WITH_DTRACE
ef3bbed
+    int f_calllineno;		/* line number of call site */
ef3bbed
+#endif
ef3bbed
     int f_iblock;		/* index in f_blockstack */
ef3bbed
     PyTryBlock f_blockstack[CO_MAXBLOCKS]; /* for try and loop blocks */
ef3bbed
     PyObject *f_localsplus[1];	/* locals+stack, dynamically sized */
ef3bbed
diff -up Python-2.6.4/Include/phelper.d.systemtap Python-2.6.4/Include/phelper.d
ef3bbed
--- Python-2.6.4/Include/phelper.d.systemtap	2009-12-18 15:37:15.698243410 -0500
ef3bbed
+++ Python-2.6.4/Include/phelper.d	2009-12-18 15:37:15.697243772 -0500
ef3bbed
@@ -0,0 +1,139 @@
ef3bbed
+
ef3bbed
+/*
ef3bbed
+ * Python ustack helper.  This relies on the first argument (PyFrame *) being
ef3bbed
+ * on the stack; see Python/ceval.c for the contortions we go through to ensure
ef3bbed
+ * this is the case.
ef3bbed
+ *
ef3bbed
+ * On x86, the PyFrame * is two slots up from the frame pointer; on SPARC, it's
ef3bbed
+ * eight.
ef3bbed
+ */
ef3bbed
+
ef3bbed
+/*
ef3bbed
+ * Yes, this is as gross as it looks. DTrace cannot handle static functions,
ef3bbed
+ * and our stat_impl.h has them in ILP32.
ef3bbed
+ */
ef3bbed
+#define _SYS_STAT_H
ef3bbed
+
ef3bbed
+#include <stdio.h>
ef3bbed
+#include <sys/types.h>
ef3bbed
+
ef3bbed
+#include "pyport.h"
ef3bbed
+#include "object.h"
ef3bbed
+#include "pystate.h"
ef3bbed
+#include "pyarena.h"
ef3bbed
+#include "pythonrun.h"
ef3bbed
+#include "compile.h"
ef3bbed
+#include "frameobject.h"
ef3bbed
+#include "stringobject.h"
ef3bbed
+
ef3bbed
+#if defined(__i386)
ef3bbed
+#define	startframe PyEval_EvalFrameEx
ef3bbed
+#define	endframe PyEval_EvalCodeEx
ef3bbed
+#elif defined(__amd64)
ef3bbed
+#define	PyEval_EvalFrameEx PyEval_EvalFrameExReal
ef3bbed
+#define	startframe PyEval_EvalFrameExReal
ef3bbed
+#define	endframe PyEval_EvalCodeEx
ef3bbed
+#elif defined(__sparc)
ef3bbed
+#define	PyEval_EvalFrameEx PyEval_EvalFrameExReal
ef3bbed
+#define	startframe PyEval_EvalFrameEx
ef3bbed
+#define	endframe PyEval_EvalFrameExReal
ef3bbed
+#endif
ef3bbed
+
ef3bbed
+#ifdef __sparcv9
ef3bbed
+#define	STACK_BIAS (2048-1)
ef3bbed
+#else
ef3bbed
+#define	STACK_BIAS 0
ef3bbed
+#endif
ef3bbed
+
ef3bbed
+/*
ef3bbed
+ * Not defining PHELPER lets us test this code as a normal D script.
ef3bbed
+ */
ef3bbed
+#ifdef PHELPER
ef3bbed
+
ef3bbed
+#define	at_evalframe(addr) \
ef3bbed
+    ((uintptr_t)addr >= ((uintptr_t)&``startframe) && \
ef3bbed
+     (uintptr_t)addr < ((uintptr_t)&``endframe))
ef3bbed
+#define	probe dtrace:helper:ustack:
ef3bbed
+#define	print_result(r) (r)
ef3bbed
+
ef3bbed
+#if defined(__i386) || defined(__amd64)
ef3bbed
+#define	frame_ptr_addr ((uintptr_t)arg1 + sizeof(uintptr_t) * 2)
ef3bbed
+#elif defined(__sparc)
ef3bbed
+#define	frame_ptr_addr ((uintptr_t)arg1 + STACK_BIAS + sizeof(uintptr_t) * 8)
ef3bbed
+#else
ef3bbed
+#error unknown architecture
ef3bbed
+#endif
ef3bbed
+
ef3bbed
+#else /* PHELPER */
ef3bbed
+
ef3bbed
+#define	at_evalframe(addr) (1)
ef3bbed
+#define	probe pid$target::PyEval_EvalFrame:entry
ef3bbed
+#define print_result(r) (trace(r))
ef3bbed
+
ef3bbed
+#if defined(__i386) || defined(__amd64)
ef3bbed
+#define	frame_ptr_addr ((uintptr_t)uregs[R_SP] + sizeof(uintptr_t))
ef3bbed
+#elif defined(__sparc)
ef3bbed
+/*
ef3bbed
+ * Not implemented: we could just use R_I0, but what's the point?
ef3bbed
+ */
ef3bbed
+#else
ef3bbed
+#error unknown architecture
ef3bbed
+#endif
ef3bbed
+
ef3bbed
+#endif /* PHELPER */
ef3bbed
+
ef3bbed
+extern uintptr_t PyEval_EvalFrameEx;
ef3bbed
+extern uintptr_t PyEval_EvalCodeEx;
ef3bbed
+
ef3bbed
+#define	copyin_obj(addr, obj) ((obj *)copyin((uintptr_t)addr, sizeof(obj)))
ef3bbed
+#define	pystr_addr(addr) ((char *)addr + offsetof(PyStringObject, ob_sval))
ef3bbed
+#define	copyin_str(dest, addr, obj) \
ef3bbed
+    (copyinto((uintptr_t)pystr_addr(addr), obj->ob_size, (dest)))
ef3bbed
+#define	add_str(addr, obj) \
ef3bbed
+    copyin_str(this->result + this->pos, addr, obj); \
ef3bbed
+    this->pos += obj->ob_size; \
ef3bbed
+    this->result[this->pos] = '\0';
ef3bbed
+#define	add_digit(nr, div) ((nr / div) ? \
ef3bbed
+    (this->result[this->pos++] = '0' + ((nr / div) % 10)) : \
ef3bbed
+    (this->result[this->pos] = '\0'))
ef3bbed
+#define	add_char(c) (this->result[this->pos++] = c)
ef3bbed
+
ef3bbed
+probe /at_evalframe(arg0)/ 
ef3bbed
+{
ef3bbed
+	this->framep = *(uintptr_t *)copyin(frame_ptr_addr, sizeof(uintptr_t));
ef3bbed
+	this->frameo = copyin_obj(this->framep, PyFrameObject);
ef3bbed
+	this->codep = this->frameo->f_code;
ef3bbed
+	this->lineno = this->frameo->f_calllineno;
ef3bbed
+	this->codeo = copyin_obj(this->codep, PyCodeObject);
ef3bbed
+	this->filenamep = this->codeo->co_filename;
ef3bbed
+	this->fnamep = this->codeo->co_name;
ef3bbed
+	this->filenameo = copyin_obj(this->filenamep, PyStringObject);
ef3bbed
+	this->fnameo = copyin_obj(this->fnamep, PyStringObject);
ef3bbed
+
ef3bbed
+	this->len = 1 + this->filenameo->ob_size + 1 + 5 + 2 +
ef3bbed
+	    this->fnameo->ob_size + 1 + 1;
ef3bbed
+
ef3bbed
+	this->result = (char *)alloca(this->len);
ef3bbed
+	this->pos = 0;
ef3bbed
+
ef3bbed
+	add_char('@');
ef3bbed
+	add_str(this->filenamep, this->filenameo);
ef3bbed
+	add_char(':');
ef3bbed
+	add_digit(this->lineno, 10000);
ef3bbed
+	add_digit(this->lineno, 1000);
ef3bbed
+	add_digit(this->lineno, 100);
ef3bbed
+	add_digit(this->lineno, 10);
ef3bbed
+	add_digit(this->lineno, 1);
ef3bbed
+	add_char(' ');
ef3bbed
+	add_char('(');
ef3bbed
+	add_str(this->fnamep, this->fnameo);
ef3bbed
+	add_char(')');
ef3bbed
+	this->result[this->pos] = '\0';
ef3bbed
+
ef3bbed
+	print_result(stringof(this->result));
ef3bbed
+}
ef3bbed
+
ef3bbed
+probe /!at_evalframe(arg0)/
ef3bbed
+{
ef3bbed
+	NULL;
ef3bbed
+}
ef3bbed
diff -up Python-2.6.4/Include/pydtrace.d.systemtap Python-2.6.4/Include/pydtrace.d
ef3bbed
--- Python-2.6.4/Include/pydtrace.d.systemtap	2009-12-18 15:37:15.697243772 -0500
ef3bbed
+++ Python-2.6.4/Include/pydtrace.d	2009-12-18 15:37:15.697243772 -0500
ef3bbed
@@ -0,0 +1,10 @@
ef3bbed
+provider python {
ef3bbed
+	probe function__entry(const char *, const char *, int);
ef3bbed
+	probe function__return(const char *, const char *, int);
ef3bbed
+};
ef3bbed
+
ef3bbed
+#pragma D attributes Evolving/Evolving/Common provider python provider
ef3bbed
+#pragma D attributes Private/Private/Common provider python module
ef3bbed
+#pragma D attributes Private/Private/Common provider python function
ef3bbed
+#pragma D attributes Evolving/Evolving/Common provider python name
ef3bbed
+#pragma D attributes Evolving/Evolving/Common provider python args
ef3bbed
diff -up Python-2.6.4/Makefile.pre.in.systemtap Python-2.6.4/Makefile.pre.in
ef3bbed
--- Python-2.6.4/Makefile.pre.in.systemtap	2009-12-18 15:37:15.399242581 -0500
ef3bbed
+++ Python-2.6.4/Makefile.pre.in	2009-12-18 15:37:15.715242573 -0500
ef3bbed
@@ -290,6 +290,7 @@ PYTHON_OBJS=	\
ef3bbed
 		Python/formatter_unicode.o \
ef3bbed
 		Python/formatter_string.o \
ef3bbed
 		Python/$(DYNLOADFILE) \
ef3bbed
+		@DTRACEOBJS@ \
ef3bbed
 		$(LIBOBJS) \
ef3bbed
 		$(MACHDEP_OBJS) \
ef3bbed
 		$(THREADOBJ)
ef3bbed
@@ -577,6 +578,23 @@ Python/formatter_unicode.o: $(srcdir)/Py
ef3bbed
 Python/formatter_string.o: $(srcdir)/Python/formatter_string.c \
ef3bbed
 				$(STRINGLIB_HEADERS)
ef3bbed
 
ef3bbed
+# Only needed with --with-dtrace
ef3bbed
+buildinclude:
ef3bbed
+	mkdir -p Include
ef3bbed
+Python/phelper.o: buildinclude $(srcdir)/Include/phelper.d
ef3bbed
+	dtrace -o $@ -DPHELPER $(DFLAGS) $(CPPFLAGS) -C -G -s $(srcdir)/Include/phelper.d
ef3bbed
+
ef3bbed
+Include/pydtrace.h: buildinclude $(srcdir)/Include/pydtrace.d
ef3bbed
+	dtrace -o $@ $(DFLAGS) -C -h -s $(srcdir)/Include/pydtrace.d
ef3bbed
+
ef3bbed
+Include/phelper.h: buildinclude $(srcdir)/Include/phelper.d
ef3bbed
+	dtrace -o $@ $(DFLAGS) -C -h -s $(srcdir)/Python/python.d
ef3bbed
+
ef3bbed
+Python/ceval.o: Include/pydtrace.h
ef3bbed
+
ef3bbed
+Python/dtrace.o: buildinclude $(srcdir)/Include/pydtrace.d Python/ceval.o
ef3bbed
+	dtrace -o $@ $(DFLAGS) -C -G -s $(srcdir)/Include/pydtrace.d Python/ceval.o
ef3bbed
+
ef3bbed
 ############################################################################
ef3bbed
 # Header files
ef3bbed
 
ef3bbed
@@ -1213,6 +1231,6 @@ Python/thread.o: @THREADHEADERS@
ef3bbed
 .PHONY: frameworkinstall frameworkinstallframework frameworkinstallstructure
ef3bbed
 .PHONY: frameworkinstallmaclib frameworkinstallapps frameworkinstallunixtools
ef3bbed
 .PHONY: frameworkaltinstallunixtools recheck autoconf clean clobber distclean 
ef3bbed
-.PHONY: smelly funny patchcheck
ef3bbed
+.PHONY: smelly funny patchcheck buildinclude
ef3bbed
 
ef3bbed
 # IF YOU PUT ANYTHING HERE IT WILL GO AWAY
ef3bbed
diff -up Python-2.6.4/Objects/frameobject.c.systemtap Python-2.6.4/Objects/frameobject.c
ef3bbed
--- Python-2.6.4/Objects/frameobject.c.systemtap	2009-06-01 19:27:15.000000000 -0400
ef3bbed
+++ Python-2.6.4/Objects/frameobject.c	2009-12-18 15:37:15.715242573 -0500
ef3bbed
@@ -698,6 +698,9 @@ PyFrame_New(PyThreadState *tstate, PyCod
ef3bbed
 	f->f_tstate = tstate;
ef3bbed
 
ef3bbed
 	f->f_lasti = -1;
ef3bbed
+#ifdef WITH_DTRACE
ef3bbed
+ 	f->f_calllineno = code->co_firstlineno;
ef3bbed
+#endif
ef3bbed
 	f->f_lineno = code->co_firstlineno;
ef3bbed
 	f->f_iblock = 0;
ef3bbed
 
ef3bbed
diff -up Python-2.6.4/pyconfig.h.in.systemtap Python-2.6.4/pyconfig.h.in
ef3bbed
--- Python-2.6.4/pyconfig.h.in.systemtap	2009-12-18 15:37:15.649243175 -0500
ef3bbed
+++ Python-2.6.4/pyconfig.h.in	2009-12-18 15:37:15.719242803 -0500
ef3bbed
@@ -5,6 +5,9 @@
ef3bbed
 #define Py_PYCONFIG_H
ef3bbed
 
ef3bbed
 
ef3bbed
+/* Define if building universal (internal helper macro) */
ef3bbed
+#undef AC_APPLE_UNIVERSAL_BUILD
ef3bbed
+
ef3bbed
 /* Define for AIX if your compiler is a genuine IBM xlC/xlC_r and you want
ef3bbed
    support for AIX C++ shared extension modules. */
ef3bbed
 #undef AIX_GENUINE_CPLUSPLUS
ef3bbed
@@ -945,6 +948,28 @@
ef3bbed
 /* Define to 1 if your <sys/time.h> declares `struct tm'. */
ef3bbed
 #undef TM_IN_SYS_TIME
ef3bbed
 
ef3bbed
+/* Enable extensions on AIX 3, Interix.  */
ef3bbed
+#ifndef _ALL_SOURCE
ef3bbed
+# undef _ALL_SOURCE
ef3bbed
+#endif
ef3bbed
+/* Enable GNU extensions on systems that have them.  */
ef3bbed
+#ifndef _GNU_SOURCE
ef3bbed
+# undef _GNU_SOURCE
ef3bbed
+#endif
ef3bbed
+/* Enable threading extensions on Solaris.  */
ef3bbed
+#ifndef _POSIX_PTHREAD_SEMANTICS
ef3bbed
+# undef _POSIX_PTHREAD_SEMANTICS
ef3bbed
+#endif
ef3bbed
+/* Enable extensions on HP NonStop.  */
ef3bbed
+#ifndef _TANDEM_SOURCE
ef3bbed
+# undef _TANDEM_SOURCE
ef3bbed
+#endif
ef3bbed
+/* Enable general extensions on Solaris.  */
ef3bbed
+#ifndef __EXTENSIONS__
ef3bbed
+# undef __EXTENSIONS__
ef3bbed
+#endif
ef3bbed
+
ef3bbed
+
ef3bbed
 /* Define if you want to use MacPython modules on MacOSX in unix-Python. */
ef3bbed
 #undef USE_TOOLBOX_OBJECT_GLUE
ef3bbed
 
ef3bbed
@@ -964,6 +989,9 @@
ef3bbed
 /* Define if you want documentation strings in extension modules */
ef3bbed
 #undef WITH_DOC_STRINGS
ef3bbed
 
ef3bbed
+/* Define if you want to compile in Dtrace support */
ef3bbed
+#undef WITH_DTRACE
ef3bbed
+
ef3bbed
 /* Define if you want to use the new-style (Openstep, Rhapsody, MacOS) dynamic
ef3bbed
    linker (dyld) instead of the old-style (NextStep) dynamic linker (rld).
ef3bbed
    Dyld is necessary to support frameworks. */
ef3bbed
@@ -1017,15 +1045,25 @@
ef3bbed
 /* This must be defined on some systems to enable large file support. */
ef3bbed
 #undef _LARGEFILE_SOURCE
ef3bbed
 
ef3bbed
+/* Define to 1 if on MINIX. */
ef3bbed
+#undef _MINIX
ef3bbed
+
ef3bbed
 /* Define on NetBSD to activate all library features */
ef3bbed
 #undef _NETBSD_SOURCE
ef3bbed
 
ef3bbed
 /* Define _OSF_SOURCE to get the makedev macro. */
ef3bbed
 #undef _OSF_SOURCE
ef3bbed
 
ef3bbed
+/* Define to 2 if the system does not provide POSIX.1 features except with
ef3bbed
+   this defined. */
ef3bbed
+#undef _POSIX_1_SOURCE
ef3bbed
+
ef3bbed
 /* Define to activate features from IEEE Stds 1003.1-2001 */
ef3bbed
 #undef _POSIX_C_SOURCE
ef3bbed
 
ef3bbed
+/* Define to 1 if you need to in order for `stat' and other things to work. */
ef3bbed
+#undef _POSIX_SOURCE
ef3bbed
+
ef3bbed
 /* Define if you have POSIX threads, and your system does not define that. */
ef3bbed
 #undef _POSIX_THREADS
ef3bbed
 
ef3bbed
diff -up Python-2.6.4/Python/ceval.c.systemtap Python-2.6.4/Python/ceval.c
ef3bbed
--- Python-2.6.4/Python/ceval.c.systemtap	2009-05-30 17:43:48.000000000 -0400
ef3bbed
+++ Python-2.6.4/Python/ceval.c	2009-12-18 15:37:15.723242474 -0500
ef3bbed
@@ -19,6 +19,10 @@
ef3bbed
 
ef3bbed
 #include <ctype.h>
ef3bbed
 
ef3bbed
+#ifdef WITH_DTRACE
ef3bbed
+#include "pydtrace.h"
ef3bbed
+#endif
ef3bbed
+
ef3bbed
 #ifndef WITH_TSC
ef3bbed
 
ef3bbed
 #define READ_TIMESTAMP(var)
ef3bbed
@@ -527,6 +531,55 @@ PyEval_EvalCode(PyCodeObject *co, PyObje
ef3bbed
 			  NULL);
ef3bbed
 }
ef3bbed
 
ef3bbed
+#ifdef WITH_DTRACE
ef3bbed
+static void
ef3bbed
+dtrace_entry(PyFrameObject *f)
ef3bbed
+{
ef3bbed
+	const char *filename;
ef3bbed
+	const char *fname;
ef3bbed
+	int lineno;
ef3bbed
+	
ef3bbed
+	filename = PyString_AsString(f->f_code->co_filename);
ef3bbed
+	fname = PyString_AsString(f->f_code->co_name);
ef3bbed
+	lineno = PyCode_Addr2Line(f->f_code, f->f_lasti);
ef3bbed
+
ef3bbed
+	PYTHON_FUNCTION_ENTRY((char *)filename, (char *)fname, lineno);
ef3bbed
+
ef3bbed
+	/*
ef3bbed
+	 * Currently a USDT tail-call will not receive the correct arguments.
ef3bbed
+	 * Disable the tail call here.
ef3bbed
+	 */
ef3bbed
+#if defined(__sparc)
ef3bbed
+	asm("nop");
ef3bbed
+#endif
ef3bbed
+}
ef3bbed
+
ef3bbed
+static void
ef3bbed
+dtrace_return(PyFrameObject *f)
ef3bbed
+{
ef3bbed
+	const char *filename;
ef3bbed
+	const char *fname;
ef3bbed
+	int lineno;
ef3bbed
+	
ef3bbed
+	filename = PyString_AsString(f->f_code->co_filename);
ef3bbed
+	fname = PyString_AsString(f->f_code->co_name);
ef3bbed
+	lineno = PyCode_Addr2Line(f->f_code, f->f_lasti);
ef3bbed
+	PYTHON_FUNCTION_RETURN((char *)filename, (char *)fname, lineno);
ef3bbed
+
ef3bbed
+	/*
ef3bbed
+	 * Currently a USDT tail-call will not receive the correct arguments.
ef3bbed
+	 * Disable the tail call here.
ef3bbed
+	 */
ef3bbed
+#if defined(__sparc)
ef3bbed
+	asm("nop");
ef3bbed
+#endif
ef3bbed
+}
ef3bbed
+#else
ef3bbed
+#define	PYTHON_FUNCTION_ENTRY_ENABLED() 0
ef3bbed
+#define	PYTHON_FUNCTION_RETURN_ENABLED() 0
ef3bbed
+#define	dtrace_entry(f)
ef3bbed
+#define	dtrace_return(f)
ef3bbed
+#endif
ef3bbed
 
ef3bbed
 /* Interpreter main loop */
ef3bbed
 
ef3bbed
@@ -538,9 +591,84 @@ PyEval_EvalFrame(PyFrameObject *f) {
ef3bbed
 	return PyEval_EvalFrameEx(f, 0);
ef3bbed
 }
ef3bbed
 
ef3bbed
+/*
ef3bbed
+ * These shenanigans look like utter madness, but what we're actually doing is
ef3bbed
+ * making sure that the ustack helper will see the PyFrameObject pointer on the
ef3bbed
+ * stack. We have two tricky cases:
ef3bbed
+ *
ef3bbed
+ * amd64
ef3bbed
+ *
ef3bbed
+ * We use up the six registers for passing arguments, meaning the call can't
ef3bbed
+ * use a register for passing 'f', and has to push it onto the stack in a known
ef3bbed
+ * location.
ef3bbed
+ *
ef3bbed
+ * And how does "throwflag" figure in to this? -PN
ef3bbed
+ *
ef3bbed
+ * SPARC
ef3bbed
+ *
ef3bbed
+ * Here the problem is that (on 32-bit) the compiler is re-using %i0 before
ef3bbed
+ * some calls inside PyEval_EvalFrameReal(), which means that when it's saved,
ef3bbed
+ * it's just some junk value rather than the real first argument. So, instead,
ef3bbed
+ * we trace our proxy PyEval_EvalFrame(), where we 'know' the compiler won't
ef3bbed
+ * decide to re-use %i0. We also need to defeat optimization of our proxy.
ef3bbed
+ */
ef3bbed
+
ef3bbed
+#if defined(WITH_DTRACE)
ef3bbed
+
ef3bbed
+#if defined(__amd64)
ef3bbed
+PyObject *PyEval_EvalFrameExReal(long, long, long, long, long, long,
ef3bbed
+    PyFrameObject *, int throwflag);
ef3bbed
+
ef3bbed
+
ef3bbed
+
ef3bbed
 PyObject *
ef3bbed
 PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
ef3bbed
 {
ef3bbed
+	volatile PyObject *f2;
ef3bbed
+	f2 = PyEval_EvalFrameExReal(0, 0, 0, 0, 0, 0, f, throwflag);
ef3bbed
+	return (PyObject *)f2;
ef3bbed
+}
ef3bbed
+
ef3bbed
+PyObject *
ef3bbed
+PyEval_EvalFrameExReal(long a1, long a2, long a3, long a4, long a5, long a6,
ef3bbed
+    PyFrameObject *f, int throwflag)
ef3bbed
+{
ef3bbed
+
ef3bbed
+#elif defined(__sparc)
ef3bbed
+
ef3bbed
+PyObject *PyEval_EvalFrameExReal(PyFrameObject *f, int throwflag);
ef3bbed
+
ef3bbed
+volatile int dummy;
ef3bbed
+
ef3bbed
+PyObject *
ef3bbed
+PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
ef3bbed
+{
ef3bbed
+	volatile PyObject *f2;
ef3bbed
+	f2 = PyEval_EvalFrameExReal(f, throwflag);
ef3bbed
+	dummy = f->ob_refcnt;
ef3bbed
+	return (PyObject *)f2;
ef3bbed
+}
ef3bbed
+
ef3bbed
+PyObject *
ef3bbed
+PyEval_EvalFrameExReal(PyFrameObject *f, int throwflag)
ef3bbed
+{
ef3bbed
+
ef3bbed
+#else /* __amd64 || __sparc */
ef3bbed
+
ef3bbed
+PyObject *
ef3bbed
+PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
ef3bbed
+{
ef3bbed
+
ef3bbed
+#endif /* __amd64 || __sparc */
ef3bbed
+
ef3bbed
+#else /* WITH_DTRACE not defined */
ef3bbed
+
ef3bbed
+PyObject *
ef3bbed
+PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
ef3bbed
+{
ef3bbed
+
ef3bbed
+#endif /* WITH_DTRACE */
ef3bbed
+
ef3bbed
 #ifdef DXPAIRS
ef3bbed
 	int lastopcode = 0;
ef3bbed
 #endif
ef3bbed
@@ -763,6 +891,9 @@ PyEval_EvalFrameEx(PyFrameObject *f, int
ef3bbed
 		}
ef3bbed
 	}
ef3bbed
 
ef3bbed
+        if (PYTHON_FUNCTION_ENTRY_ENABLED())
ef3bbed
+                dtrace_entry(f);
ef3bbed
+
ef3bbed
 	co = f->f_code;
ef3bbed
 	names = co->co_names;
ef3bbed
 	consts = co->co_consts;
ef3bbed
@@ -2383,6 +2514,10 @@ PyEval_EvalFrameEx(PyFrameObject *f, int
ef3bbed
 			PyObject **sp;
ef3bbed
 			PCALL(PCALL_ALL);
ef3bbed
 			sp = stack_pointer;
ef3bbed
+#ifdef WITH_DTRACE
ef3bbed
+			f->f_calllineno = PyCode_Addr2Line(f->f_code,
ef3bbed
+							   f->f_lasti);
ef3bbed
+#endif
ef3bbed
 #ifdef WITH_TSC
ef3bbed
 			x = call_function(&sp, oparg, &intr0, &intr1);
ef3bbed
 #else
ef3bbed
@@ -2425,6 +2560,11 @@ PyEval_EvalFrameEx(PyFrameObject *f, int
ef3bbed
 		    } else
ef3bbed
 			    Py_INCREF(func);
ef3bbed
 		    sp = stack_pointer;
ef3bbed
+#ifdef WITH_DTRACE
ef3bbed
+		    f->f_calllineno = PyCode_Addr2Line(f->f_code,
ef3bbed
+		                                       f->f_lasti);
ef3bbed
+#endif
ef3bbed
+
ef3bbed
 		    READ_TIMESTAMP(intr0);
ef3bbed
 		    x = ext_do_call(func, &sp, flags, na, nk);
ef3bbed
 		    READ_TIMESTAMP(intr1);
ef3bbed
@@ -2723,6 +2863,8 @@ fast_yield:
ef3bbed
 
ef3bbed
 	/* pop frame */
ef3bbed
 exit_eval_frame:
ef3bbed
+	if (PYTHON_FUNCTION_RETURN_ENABLED())
ef3bbed
+		dtrace_return(f);
ef3bbed
 	Py_LeaveRecursiveCall();
ef3bbed
 	tstate->frame = f->f_back;
ef3bbed