From 2bead260f3dc89fa9d695eadb8a84ab398b19ba0 Mon Sep 17 00:00:00 2001 From: "sayrer%gmail.com" Date: Wed, 16 Jan 2008 20:42:51 +0000 Subject: [PATCH] Bug 411365. Start and stop Shark from JS. r=crowder, sr=jst --- config/autoconf.mk.in | 1 + configure.in | 11 ++++ dom/src/base/Makefile.in | 6 ++ dom/src/base/nsJSEnvironment.cpp | 15 +++++ js/src/Makefile.in | 6 ++ js/src/Makefile.ref | 6 ++ js/src/js.c | 20 +++++- js/src/jsdbgapi.c | 95 +++++++++++++++++++++++++++++ js/src/jsdbgapi.h | 21 +++++++ js/src/xpconnect/shell/Makefile.in | 6 ++ js/src/xpconnect/shell/xpcshell.cpp | 16 ++++- 11 files changed, 201 insertions(+), 2 deletions(-) diff --git a/config/autoconf.mk.in b/config/autoconf.mk.in index fb191c49bb6..c6c21449a5e 100644 --- a/config/autoconf.mk.in +++ b/config/autoconf.mk.in @@ -101,6 +101,7 @@ MOZ_JSDEBUGGER = @MOZ_JSDEBUGGER@ MOZ_PERF_METRICS = @MOZ_PERF_METRICS@ MOZ_LEAKY = @MOZ_LEAKY@ MOZ_JPROF = @MOZ_JPROF@ +MOZ_SHARK = @MOZ_SHARK@ MOZ_XPCTOOLS = @MOZ_XPCTOOLS@ ENABLE_EAZEL_PROFILER=@ENABLE_EAZEL_PROFILER@ EAZEL_PROFILER_CFLAGS=@EAZEL_PROFILER_CFLAGS@ diff --git a/configure.in b/configure.in index 044b5a2c377..220bb27f831 100644 --- a/configure.in +++ b/configure.in @@ -6131,6 +6131,16 @@ if test -n "$MOZ_JPROF"; then AC_DEFINE(MOZ_JPROF) fi +dnl ======================================================== +dnl shark +dnl ======================================================== +MOZ_ARG_ENABLE_BOOL(shark, +[ --enable-shark Enable shark remote profiling (needs CHUD framework)], + MOZ_SHARK=1, + MOZ_SHARK= ) +if test -n "$MOZ_SHARK"; then + AC_DEFINE(MOZ_SHARK) +fi dnl ======================================================== dnl = Enable stripping of libs & executables @@ -7461,6 +7471,7 @@ AC_SUBST(GC_LEAK_DETECTOR) AC_SUBST(MOZ_LOG_REFCNT) AC_SUBST(MOZ_LEAKY) AC_SUBST(MOZ_JPROF) +AC_SUBST(MOZ_SHARK) AC_SUBST(MOZ_XPCTOOLS) AC_SUBST(MOZ_JSLOADER) AC_SUBST(MOZ_USE_NATIVE_UCONV) diff --git a/dom/src/base/Makefile.in b/dom/src/base/Makefile.in index 68d0de5eaaa..1dafbf2fa4c 100644 --- a/dom/src/base/Makefile.in +++ b/dom/src/base/Makefile.in @@ -135,6 +135,12 @@ LOCAL_INCLUDES = \ DEFINES += -D_IMPL_NS_LAYOUT +ifdef MOZ_SHARK +DEFINES += -DMOZ_SHARK +CFLAGS += -F/System/Library/PrivateFrameworks +LDFLAGS += -F/System/Library/PrivateFrameworks -framework CHUD +endif + ifdef MOZ_JSDEBUGGER DEFINES += -DMOZ_JSDEBUGGER endif diff --git a/dom/src/base/nsJSEnvironment.cpp b/dom/src/base/nsJSEnvironment.cpp index 55491b6faa4..9cdf85c6158 100644 --- a/dom/src/base/nsJSEnvironment.cpp +++ b/dom/src/base/nsJSEnvironment.cpp @@ -3097,6 +3097,16 @@ static JSFunctionSpec JProfFunctions[] = { #endif /* defined(MOZ_JPROF) */ +#ifdef MOZ_SHARK +static JSFunctionSpec SharkFunctions[] = { + {"startShark", StartShark, 0, 0, 0}, + {"stopShark", StopShark, 0, 0, 0}, + {"connectShark", ConnectShark, 0, 0, 0}, + {"disconnectShark", DisconnectShark, 0, 0, 0}, + {nsnull, nsnull, 0, 0, 0} +}; +#endif + nsresult nsJSContext::InitClasses(void *aGlobalObj) { @@ -3129,6 +3139,11 @@ nsJSContext::InitClasses(void *aGlobalObj) ::JS_DefineFunctions(mContext, globalObj, JProfFunctions); #endif +#ifdef MOZ_SHARK + // Attempt to initialize Shark functions + ::JS_DefineFunctions(mContext, globalObj, SharkFunctions); +#endif + JSOptionChangedCallback(js_options_dot_str, this); return rv; diff --git a/js/src/Makefile.in b/js/src/Makefile.in index 3a34cb4359f..a6fbec8330a 100644 --- a/js/src/Makefile.in +++ b/js/src/Makefile.in @@ -280,6 +280,12 @@ else NSPR_STATIC_PATH = $(DIST)/lib endif +ifdef MOZ_SHARK +DEFINES += -DMOZ_SHARK +CFLAGS += -F/System/Library/PrivateFrameworks +LDFLAGS += -F/System/Library/PrivateFrameworks -framework CHUD +endif + LDFLAGS += $(pathsubst -l%,$(NSPR_STATIC_PATH)/%.a,$(NSPR_LIBS)) # BeOS and HP-UX do not require the extra linking of "-lm" diff --git a/js/src/Makefile.ref b/js/src/Makefile.ref index e15d13f86f1..0f008a684f7 100644 --- a/js/src/Makefile.ref +++ b/js/src/Makefile.ref @@ -79,6 +79,12 @@ ifdef JS_HAS_FILE_OBJECT DEFINES += -DJS_HAS_FILE_OBJECT endif +ifdef MOZ_SHARK +DEFINES += -DMOZ_SHARK +CFLAGS += -F/System/Library/PrivateFrameworks +LDFLAGS += -F/System/Library/PrivateFrameworks -framework CHUD +endif + # # XCFLAGS may be set in the environment or on the gmake command line # diff --git a/js/src/js.c b/js/src/js.c index baf1656e701..fe2d46c6565 100644 --- a/js/src/js.c +++ b/js/src/js.c @@ -522,7 +522,11 @@ ProcessArgs(JSContext *cx, JSObject *obj, char **argv, int argc) case 'z': obj = split_setup(cx); break; - +#ifdef MOZ_SHARK + case 'k': + js_ConnectShark(); + break; +#endif default: return usage(); } @@ -2523,6 +2527,12 @@ static JSFunctionSpec shell_functions[] = { JS_FN("getslx", GetSLX, 1,1,0), JS_FN("toint32", ToInt32, 1,1,0), JS_FS("evalcx", EvalInContext, 1,0,0), +#ifdef MOZ_SHARK + JS_FS("startShark", StartShark, 0,0,0), + JS_FS("stopShark", StopShark, 0,0,0), + JS_FS("connectShark", ConnectShark, 0,0,0), + JS_FS("disconnectShark", DisconnectShark, 0,0,0), +#endif JS_FS_END }; @@ -2585,6 +2595,14 @@ static const char *const shell_help_messages[] = { " Evaluate s in optional sandbox object o\n" " if (s == '' && !o) return new o with eager standard classes\n" " if (s == 'lazy' && !o) return new o with lazy standard classes", +#ifdef MOZ_SHARK +"startShark() Start a Shark session.\n" +" Shark must be running with programatic sampling.", +"stopShark() Stop a running Shark session.", +"connectShark() Connect to Shark.\n" +" The -k switch does this automatically.", +"disconnectShark() Disconnect from Shark.", +#endif }; /* Help messages must match shell functions. */ diff --git a/js/src/jsdbgapi.c b/js/src/jsdbgapi.c index ea0e60788c4..9b5730fc650 100644 --- a/js/src/jsdbgapi.c +++ b/js/src/jsdbgapi.c @@ -62,6 +62,10 @@ #include "jsscript.h" #include "jsstr.h" +#ifdef MOZ_SHARK +#include +#endif + typedef struct JSTrap { JSCList links; JSScript *script; @@ -1669,3 +1673,94 @@ JS_SetContextDebugHooks(JSContext *cx, JSDebugHooks *hooks) cx->debugHooks = hooks; return old; } + +#ifdef MOZ_SHARK + +JS_FRIEND_API(JSBool) +js_StartChudRemote() +{ + if (chudIsRemoteAccessAcquired() && + (chudStartRemotePerfMonitor("Mozilla") == chudSuccess)) { + return JS_TRUE; + } + + return JS_FALSE; +} + +JS_FRIEND_API(JSBool) +js_StopChudRemote() +{ + if (chudIsRemoteAccessAcquired() && + (chudStopRemotePerfMonitor() == chudSuccess)) { + return JS_TRUE; + } + + return JS_FALSE; +} + +JS_FRIEND_API(JSBool) +js_ConnectShark() +{ + if (!chudIsInitialized() && (chudInitialize() != chudSuccess)) + return JS_FALSE; + + if (chudAcquireRemoteAccess() != chudSuccess) + return JS_FALSE; + + return JS_TRUE; +} + +JS_FRIEND_API(JSBool) +js_DisconnectShark() +{ + if (chudIsRemoteAccessAcquired() && (chudReleaseRemoteAccess() != chudSuccess)) + return JS_FALSE; + + return JS_TRUE; +} + +JS_FRIEND_API(JSBool) +StartShark(JSContext *cx, JSObject *obj, + uintN argc, jsval *argv, jsval *rval) +{ + if (!js_StartChudRemote()) { + JS_ReportError(cx, "Error starting CHUD."); + } + + return JS_TRUE; +} + +JS_FRIEND_API(JSBool) +StopShark(JSContext *cx, JSObject *obj, + uintN argc, jsval *argv, jsval *rval) +{ + if (!js_StopChudRemote()) { + JS_ReportError(cx, "Error stopping CHUD."); + } + + return JS_TRUE; +} + +JS_FRIEND_API(JSBool) +ConnectShark(JSContext *cx, JSObject *obj, + uintN argc, jsval *argv, jsval *rval) +{ + if (!js_ConnectShark()) { + JS_ReportError(cx, "Error connecting to Shark."); + } + + return JS_TRUE; +} + +JS_FRIEND_API(JSBool) +DisconnectShark(JSContext *cx, JSObject *obj, + uintN argc, jsval *argv, jsval *rval) +{ + if (!js_DisconnectShark()) { + JS_ReportError(cx, "Error disconnecting from Shark."); + } + + return JS_TRUE; +} + +#endif /* MOZ_SHARK */ diff --git a/js/src/jsdbgapi.h b/js/src/jsdbgapi.h index 84b09379d60..6c59e3fd87d 100644 --- a/js/src/jsdbgapi.h +++ b/js/src/jsdbgapi.h @@ -421,6 +421,27 @@ JS_GetGlobalDebugHooks(JSRuntime *rt); extern JS_PUBLIC_API(JSDebugHooks *) JS_SetContextDebugHooks(JSContext *cx, JSDebugHooks *hooks); +#ifdef MOZ_SHARK +extern JS_FRIEND_API(JSBool) js_StartChudRemote(); +extern JS_FRIEND_API(JSBool) js_StopChudRemote(); +extern JS_FRIEND_API(JSBool) js_ConnectShark(); +extern JS_FRIEND_API(JSBool) js_DisconnectShark(); + +extern JS_FRIEND_API(JSBool) StopShark(JSContext *cx, JSObject *obj, + uintN argc, jsval *argv, jsval *rval); + +extern JS_FRIEND_API(JSBool) StartShark(JSContext *cx, JSObject *obj, + uintN argc, jsval *argv, jsval *rval); + +extern JS_FRIEND_API(JSBool) ConnectShark(JSContext *cx, JSObject *obj, + uintN argc, jsval *argv, + jsval *rval); + +extern JS_FRIEND_API(JSBool) DisconnectShark(JSContext *cx, JSObject *obj, + uintN argc, jsval *argv, + jsval *rval); +#endif /* MOZ_SHARK */ + JS_END_EXTERN_C #endif /* jsdbgapi_h___ */ diff --git a/js/src/xpconnect/shell/Makefile.in b/js/src/xpconnect/shell/Makefile.in index cbc19bae447..e69d1a61611 100644 --- a/js/src/xpconnect/shell/Makefile.in +++ b/js/src/xpconnect/shell/Makefile.in @@ -65,6 +65,12 @@ include $(topsrcdir)/config/rules.mk DEFINES += -DJS_THREADSAFE +ifdef MOZ_SHARK +DEFINES += -DMOZ_SHARK +CFLAGS += -F/System/Library/PrivateFrameworks +LDFLAGS += -F/System/Library/PrivateFrameworks -framework CHUD +endif + # # Line editing support. If your OS supplies the readline library, define # JS_READLINE to get line editing in the xpcshell. diff --git a/js/src/xpconnect/shell/xpcshell.cpp b/js/src/xpconnect/shell/xpcshell.cpp index 5f950c19e26..7a761876c32 100644 --- a/js/src/xpconnect/shell/xpcshell.cpp +++ b/js/src/xpconnect/shell/xpcshell.cpp @@ -81,6 +81,10 @@ #include "nsIJSContextStack.h" +#ifdef MOZ_SHARK +#include "jsdbgapi.h" +#endif + /***************************************************************************/ #ifdef JS_THREADSAFE @@ -425,6 +429,12 @@ static JSFunctionSpec glob_functions[] = { {"clear", Clear, 1,0,0}, #ifdef DEBUG {"dumpHeap", DumpHeap, 5,0,0}, +#endif +#ifdef MOZ_SHARK + {"startShark", StartShark, 0,0,0}, + {"stopShark", StopShark, 0,0,0}, + {"connectShark", ConnectShark, 0,0,0}, + {"disconnectShark", DisconnectShark,0,0,0}, #endif {nsnull,nsnull,0,0,0} }; @@ -884,7 +894,11 @@ ProcessArgs(JSContext *cx, JSObject *obj, char **argv, int argc) compileOnly = JS_TRUE; isInteractive = JS_FALSE; break; - +#ifdef MOZ_SHARK + case 'k': + js_ConnectShark(); + break; +#endif default: return usage(); }