Index: Makefile.in =================================================================== diff -u -r9a578692ecf2d05eb4da0de37c7e0bdca3819570 -r0078146a2bcee10f8f7f65313b86b288f6d2f652 --- Makefile.in (.../Makefile.in) (revision 9a578692ecf2d05eb4da0de37c7e0bdca3819570) +++ Makefile.in (.../Makefile.in) (revision 0078146a2bcee10f8f7f65313b86b288f6d2f652) @@ -80,6 +80,12 @@ # are correct. #======================================================================== +#DTRACE_OBJ = nsfDTrace.o +#DTRACE_OBJ = @DTRACE_OBJ@ +DTRACE_OBJ = +DTRACE_HDR = $(src_generic_dir)/nsfDTrace.h +DTRACE_SRC = $(src_generic_dir)/nsfDTrace.d + #======================================================================== # The names of the source files is defined in the configure script. # The object files are used for linking into the final library. @@ -89,7 +95,7 @@ #======================================================================== PKG_SOURCES = @PKG_SOURCES@ -PKG_OBJECTS = @PKG_OBJECTS@ +PKG_OBJECTS = @PKG_OBJECTS@ ${DTRACE_OBJ} PKG_STUB_SOURCES = @PKG_STUB_SOURCES@ PKG_STUB_OBJECTS = @PKG_STUB_OBJECTS@ @@ -164,6 +170,9 @@ TCL_DEFS = @TCL_DEFS@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_SRC_DIR = @TCL_SRC_DIR@ +# +DTRACE = dtrace +# # Not used, but retained for reference of what libs Tcl required TCL_LIBS = @TCL_LIBS@ @@ -551,6 +560,17 @@ if [ $$match -eq 0 ]; then echo $$i; fi \ done +# DTrace support + +$(PKG_OBJECTS): $(DTRACE_HDR) + +$(DTRACE_HDR): $(DTRACE_SRC) + $(DTRACE) -h $(DTRACE_SWITCHES) -o $@ -s $(DTRACE_SRC) + +#$(DTRACE_OBJ): $(DTRACE_SRC) $(TCL_OBJS) +# $(DTRACE) -G $(DTRACE_SWITCHES) -o $@ -s $(DTRACE_SRC) $(TCL_OBJS) + + #======================================================================== # End of user-definable section #======================================================================== Index: generic/nsf.h =================================================================== diff -u -rb0adbc0c160788b189124e9988437ef7f2ec036c -r0078146a2bcee10f8f7f65313b86b288f6d2f652 --- generic/nsf.h (.../nsf.h) (revision b0adbc0c160788b189124e9988437ef7f2ec036c) +++ generic/nsf.h (.../nsf.h) (revision 0078146a2bcee10f8f7f65313b86b288f6d2f652) @@ -72,7 +72,9 @@ /* activate/deacticate profiling information at the end of running the program #define NSF_PROFILE 1 +#define NSF_DTRACE 1 */ +//#define NSF_DTRACE 1 /* are we developing? #define NSF_DEVELOPMENT 1 Index: generic/nsfDTrace.d =================================================================== diff -u --- generic/nsfDTrace.d (revision 0) +++ generic/nsfDTrace.d (revision 0078146a2bcee10f8f7f65313b86b288f6d2f652) @@ -0,0 +1,127 @@ +/* + * nsfDTrace.d -- + * + * Next Scripting Framework DTrace provider. + * + * Copyright (c) 2011 Gustaf Neumann + * + * See the file "license.terms" for information on usage and redistribution of + * this file, and for a DISCLAIMER OF ALL WARRANTIES. + * + */ + +typedef struct Tcl_Obj Tcl_Obj; + +/* + * Next Scripting DTrace probes + * + * Modeled in alignment with the Tcl DTrace probes + */ + +provider nsf { + /***************************** proc probes *****************************/ + /* + * nsf*:::method-entry probe + * triggered immediately before method bytecode execution + * arg0: class/object name (string) + * arg1: method name (string) + * arg2: number of arguments (int) + * arg3: array of proc argument objects (Tcl_Obj**) + */ + probe method__entry(char *class, char* method, int objc, Tcl_Obj **objv); + /* + * nsf*:::proc-return probe + * triggered immediately after proc bytecode execution + * arg0: class/object name (string) + * arg1: method name (string) + * arg2: return code (int) + */ + probe method__return(char *class, char* name, int code); + /* + * tcl*:::proc-result probe + * triggered after proc-return probe and result processing + * arg0: proc name (string) + * arg1: return code (int) + * arg2: proc result (string) + * arg3: proc result object (Tcl_Obj*) + */ + + /***************************** Object probes ******************************/ + /* + * nsf*:::object-create-start probe + * triggered when an NSF object creation starts + * arg0: class (string) + * arg1: object (string) + */ + probe object__create_start(char *class, char *object); + /* + * nsf*:::object-create-end probe + * triggered when an NSF object creation ends + * arg0: class (string) + * arg1: object (string) + */ + probe object__create_end(char *class, char *object); + /* + * nsf*:::object-destroy probe + * triggered whean an NSF object is destroyed + * arg0: class (string) + * arg1: object (string) + */ + probe object__destroy(char *class, char *object); + +}; + +/* + * Tcl types and constants for use in DTrace scripts + */ + +typedef struct Tcl_ObjType { + char *name; + void *freeIntRepProc; + void *dupIntRepProc; + void *updateStringProc; + void *setFromAnyProc; +} Tcl_ObjType; + +struct Tcl_Obj { + int refCount; + char *bytes; + int length; + Tcl_ObjType *typePtr; + union { + long longValue; + double doubleValue; + void *otherValuePtr; + int64_t wideValue; + struct { + void *ptr1; + void *ptr2; + } twoPtrValue; + struct { + void *ptr; + unsigned long value; + } ptrAndLongRep; + } internalRep; +}; + +enum return_codes { + TCL_OK = 0, + TCL_ERROR, + TCL_RETURN, + TCL_BREAK, + TCL_CONTINUE +}; + +#pragma D attributes Evolving/Evolving/Common provider nsf provider +#pragma D attributes Private/Private/Common provider nsf module +#pragma D attributes Private/Private/Common provider nsf function +#pragma D attributes Evolving/Evolving/Common provider nsf name +#pragma D attributes Evolving/Evolving/Common provider nsf args + +/* + * Local Variables: + * mode: c + * c-basic-offset: 4 + * fill-column: 78 + * End: + */ Index: generic/nsfDTrace.h =================================================================== diff -u --- generic/nsfDTrace.h (revision 0) +++ generic/nsfDTrace.h (revision 0078146a2bcee10f8f7f65313b86b288f6d2f652) @@ -0,0 +1,75 @@ +/* + * Generated by dtrace(1M). + */ + +#ifndef _NSFDTRACE_H +#define _NSFDTRACE_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define NSF_STABILITY "___dtrace_stability$nsf$v1$5_5_5_1_1_5_1_1_5_5_5_5_5_5_5" + +#define NSF_TYPEDEFS "___dtrace_typedefs$nsf$v2$54636c5f4f626a" + +#define NSF_METHOD_ENTRY(arg0, arg1, arg2, arg3) \ +do { \ + __asm__ volatile(".reference " NSF_TYPEDEFS); \ + __dtrace_probe$nsf$method__entry$v1$63686172202a$63686172202a$696e74$54636c5f4f626a202a2a(arg0, arg1, arg2, arg3); \ + __asm__ volatile(".reference " NSF_STABILITY); \ +} while (0) +#define NSF_METHOD_ENTRY_ENABLED() \ + __dtrace_isenabled$nsf$method__entry$v1() +#define NSF_METHOD_RETURN(arg0, arg1, arg2) \ +do { \ + __asm__ volatile(".reference " NSF_TYPEDEFS); \ + __dtrace_probe$nsf$method__return$v1$63686172202a$63686172202a$696e74(arg0, arg1, arg2); \ + __asm__ volatile(".reference " NSF_STABILITY); \ +} while (0) +#define NSF_METHOD_RETURN_ENABLED() \ + __dtrace_isenabled$nsf$method__return$v1() +#define NSF_OBJECT_CREATE_END(arg0, arg1) \ +do { \ + __asm__ volatile(".reference " NSF_TYPEDEFS); \ + __dtrace_probe$nsf$object__create_end$v1$63686172202a$63686172202a(arg0, arg1); \ + __asm__ volatile(".reference " NSF_STABILITY); \ +} while (0) +#define NSF_OBJECT_CREATE_END_ENABLED() \ + __dtrace_isenabled$nsf$object__create_end$v1() +#define NSF_OBJECT_CREATE_START(arg0, arg1) \ +do { \ + __asm__ volatile(".reference " NSF_TYPEDEFS); \ + __dtrace_probe$nsf$object__create_start$v1$63686172202a$63686172202a(arg0, arg1); \ + __asm__ volatile(".reference " NSF_STABILITY); \ +} while (0) +#define NSF_OBJECT_CREATE_START_ENABLED() \ + __dtrace_isenabled$nsf$object__create_start$v1() +#define NSF_OBJECT_DESTROY(arg0, arg1) \ +do { \ + __asm__ volatile(".reference " NSF_TYPEDEFS); \ + __dtrace_probe$nsf$object__destroy$v1$63686172202a$63686172202a(arg0, arg1); \ + __asm__ volatile(".reference " NSF_STABILITY); \ +} while (0) +#define NSF_OBJECT_DESTROY_ENABLED() \ + __dtrace_isenabled$nsf$object__destroy$v1() + + +extern void __dtrace_probe$nsf$method__entry$v1$63686172202a$63686172202a$696e74$54636c5f4f626a202a2a(char *, char *, int, Tcl_Obj **); +extern int __dtrace_isenabled$nsf$method__entry$v1(void); +extern void __dtrace_probe$nsf$method__return$v1$63686172202a$63686172202a$696e74(char *, char *, int); +extern int __dtrace_isenabled$nsf$method__return$v1(void); +extern void __dtrace_probe$nsf$object__create_end$v1$63686172202a$63686172202a(char *, char *); +extern int __dtrace_isenabled$nsf$object__create_end$v1(void); +extern void __dtrace_probe$nsf$object__create_start$v1$63686172202a$63686172202a(char *, char *); +extern int __dtrace_isenabled$nsf$object__create_start$v1(void); +extern void __dtrace_probe$nsf$object__destroy$v1$63686172202a$63686172202a(char *, char *); +extern int __dtrace_isenabled$nsf$object__destroy$v1(void); + +#ifdef __cplusplus +} +#endif + +#endif /* _NSFDTRACE_H */ Index: generic/nsfInt.h =================================================================== diff -u -r19ef72a5f87241def42fa2a2ec15e28a8717b59b -r0078146a2bcee10f8f7f65313b86b288f6d2f652 --- generic/nsfInt.h (.../nsfInt.h) (revision 19ef72a5f87241def42fa2a2ec15e28a8717b59b) +++ generic/nsfInt.h (.../nsfInt.h) (revision 0078146a2bcee10f8f7f65313b86b288f6d2f652) @@ -28,9 +28,29 @@ #endif #if defined(NSF_PROFILE) -# include +# include #endif +#if defined(NSF_DTRACE) +# include "nsfDTrace.h" +# if defined(__GNUC__) && __GNUC__ > 2 +/* Use gcc branch prediction hint to minimize cost of DTrace ENABLED checks. */ +# define unlikely(x) (__builtin_expect((x), 0)) +# else +# define unlikely(x) (x) +# endif +# define NSF_DTRACE_METHOD_ENTRY_ENABLED() unlikely(NSF_METHOD_ENTRY_ENABLED()) +# define NSF_DTRACE_METHOD_RETURN_ENABLED() unlikely(NSF_METHOD_RETURN_ENABLED()) +# define NSF_DTRACE_METHOD_ENTRY(a0, a1, a2, a3) NSF_METHOD_ENTRY(a0, a1, a2, a3) +# define NSF_DTRACE_METHOD_RETURN(a0, a1, a2) NSF_METHOD_RETURN(a0, a1, a2) +#else +# define NSF_DTRACE_METHOD_ENTRY_ENABLED() 0 +# define NSF_DTRACE_METHOD_RETURN_ENABLED() 0 +# define NSF_DTRACE_METHOD_ENTRY(a0, a1, a2, a3) {} +# define NSF_DTRACE_METHOD_RETURN(a0, a1, a2) {} +#endif + + #ifdef DMALLOC # include "dmalloc.h" #endif Index: generic/nsfStack.c =================================================================== diff -u -r19ef72a5f87241def42fa2a2ec15e28a8717b59b -r0078146a2bcee10f8f7f65313b86b288f6d2f652 --- generic/nsfStack.c (.../nsfStack.c) (revision 19ef72a5f87241def42fa2a2ec15e28a8717b59b) +++ generic/nsfStack.c (.../nsfStack.c) (revision 0078146a2bcee10f8f7f65313b86b288f6d2f652) @@ -830,6 +830,12 @@ * cases, we maintain an activation count. */ if (cmd) { + if (NSF_DTRACE_METHOD_ENTRY_ENABLED()) { + // TODO: missing arg list + NSF_DTRACE_METHOD_ENTRY(cl ? ClassName(cl) : ObjectName(object), + Tcl_GetCommandName(object->teardown,cmd), + 0, ""); + } /* * Track object activations */ @@ -896,6 +902,11 @@ NsfProfileRecordMethodData(interp, cscPtr); } #endif + if (NSF_DTRACE_METHOD_RETURN_ENABLED()) { + // TODO: missing returcode handling, currently just when cmdPtr is set + NSF_DTRACE_METHOD_RETURN(cscPtr->cl ? ClassName(cscPtr->cl) : ObjectName(cscPtr->self), + cscPtr->methodName, TCL_OK); + } object = cscPtr->self;