diff --git a/Python/ceval.c b/Python/ceval.c index 06d524b..2c0f2ba 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -19,6 +19,38 @@ #include +#ifdef ENABLE_DTRACE + +#include "pydtrace.h" + +#define PYTHON_DTRACE_ENTRY(py_frame) \ + if (PYTHON_FUNCTION_ENTRY_ENABLED()) { \ + char *fl_name = ((PyStringObject *)py_frame->f_code-> \ + co_filename)->ob_sval; \ + char *fn_name = ((PyStringObject *)py_frame->f_code-> \ + co_name)->ob_sval; \ + \ + PYTHON_FUNCTION_ENTRY(fl_name, fn_name, py_frame->f_lineno, \ + py_frame->f_code->co_argcount); \ + } + +#define PYTHON_DTRACE_RETURN(py_frame, object) \ + if (PYTHON_FUNCTION_RETURN_ENABLED()) { \ + char *fl_name = ((PyStringObject *)py_frame->f_code-> \ + co_filename)->ob_sval; \ + char *fn_name = ((PyStringObject *)py_frame->f_code-> \ + co_name)->ob_sval; \ + \ + PYTHON_FUNCTION_RETURN(fl_name, fn_name, object); \ + } + +#else + +#define PYTHON_DTRACE_ENTRY(py_frame) /* nothing */ +#define PYTHON_DTRACE_RETURN(py_frame, object) /* nothing */ + +#endif /* ENABLE_DTRACE */ + #ifndef WITH_TSC #define READ_TIMESTAMP(var) @@ -2266,6 +2298,8 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) PyObject **sp; PCALL(PCALL_ALL); sp = stack_pointer; + + PYTHON_DTRACE_ENTRY(f); #ifdef WITH_TSC x = call_function(&sp, oparg, &intr0, &intr1); #else @@ -2273,8 +2307,13 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) #endif stack_pointer = sp; PUSH(x); - if (x != NULL) + if (x != NULL) { + PYTHON_DTRACE_RETURN(f, (char *)x->ob_type->tp_name); continue; + } + + PYTHON_DTRACE_RETURN(f, "error"); + break; } diff --git a/Python/pydtrace.h b/Python/pydtrace.h new file mode 100644 index 0000000..4614042 --- /dev/null +++ b/Python/pydtrace.h @@ -0,0 +1,45 @@ +/* + * Generated by dtrace(1M). + */ + +#ifndef _PYTRACE_H +#define _PYTRACE_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define PYTHON_STABILITY "___dtrace_stability$python$v1$4_4_5_4_4_5_4_4_5_4_4_5_4_4_5" + +#define PYTHON_TYPEDEFS "___dtrace_typedefs$python$v1" + +#define PYTHON_FUNCTION_ENTRY(arg0, arg1, arg2, arg3) \ +{ \ + __asm__ volatile(".reference " PYTHON_TYPEDEFS); \ + __dtrace_probe$python$function__entry$v1$63686172202a$63686172202a$696e74$696e74(arg0, arg1, arg2, arg3); \ + __asm__ volatile(".reference " PYTHON_STABILITY); \ +} +#define PYTHON_FUNCTION_ENTRY_ENABLED() \ + __dtrace_isenabled$python$function__entry$v1() +#define PYTHON_FUNCTION_RETURN(arg0, arg1, arg2) \ +{ \ + __asm__ volatile(".reference " PYTHON_TYPEDEFS); \ + __dtrace_probe$python$function__return$v1$63686172202a$63686172202a$63686172202a(arg0, arg1, arg2); \ + __asm__ volatile(".reference " PYTHON_STABILITY); \ +} +#define PYTHON_FUNCTION_RETURN_ENABLED() \ + __dtrace_isenabled$python$function__return$v1() + + +extern void __dtrace_probe$python$function__entry$v1$63686172202a$63686172202a$696e74$696e74(char *, char *, int, int); +extern int __dtrace_isenabled$python$function__entry$v1(void); +extern void __dtrace_probe$python$function__return$v1$63686172202a$63686172202a$63686172202a(char *, char *, char *); +extern int __dtrace_isenabled$python$function__return$v1(void); + +#ifdef __cplusplus +} +#endif + +#endif /* _PYTRACE_H */ diff --git a/configure.in b/configure.in index b014e8f..a5ddff4 100644 --- a/configure.in +++ b/configure.in @@ -3035,6 +3035,29 @@ else AC_MSG_RESULT($PY_UNICODE_TYPE) fi + +# Check if dtrace should be enabled + +AC_MSG_CHECKING([if dtrace should be enabled]) + +AC_CHECK_HEADER([sys/sdt.h], [HAVE_SDT_H="yes"]) + +AC_ARG_ENABLE(dtrace, + [ --enable-dtrace enable DTrace support.], + [enable_dtrace=$enableval]) + if test "$enable_dtrace" == "yes" -a "$HAVE_SDT_H" == "yes"; then + OPT="$OPT -DENABLE_DTRACE" + if test -x "/usr/bin/isainfo"; then + arch=`/usr/bin/isainfo -n | cut -b1-5` + if test "$arch" == "sparc"; then + OPT="-DENABLE_DTRACE -xarch=v7" + fi + fi + else + AC_MSG_ERROR([sys/sdt.h was not found]) + fi +AC_SUBST(OPT) + # check for endianness AC_C_BIGENDIAN AH_VERBATIM([WORDS_BIGENDIAN],