Bug 497999: collect context-specific TraceVis data in JS objects, r=jorendorff
This commit is contained in:
Родитель
af688b6d08
Коммит
571bfdff48
|
@ -112,6 +112,7 @@ MOZ_JPROF = @MOZ_JPROF@
|
|||
MOZ_SHARK = @MOZ_SHARK@
|
||||
MOZ_CALLGRIND = @MOZ_CALLGRIND@
|
||||
MOZ_VTUNE = @MOZ_VTUNE@
|
||||
MOZ_TRACEVIS = @MOZ_TRACEVIS@
|
||||
DEHYDRA_PATH = @DEHYDRA_PATH@
|
||||
|
||||
MOZ_XPCTOOLS = @MOZ_XPCTOOLS@
|
||||
|
|
11
configure.in
11
configure.in
|
@ -6697,6 +6697,17 @@ MOZ_ARG_WITH_STRING(wrap-malloc,
|
|||
[ --with-wrap-malloc=DIR Location of malloc wrapper library],
|
||||
WRAP_MALLOC_LIB=$withval)
|
||||
|
||||
dnl ========================================================
|
||||
dnl = Use TraceVis
|
||||
dnl ========================================================
|
||||
MOZ_ARG_ENABLE_BOOL(tracevis,
|
||||
[ --enable-tracevis Enable TraceVis tracing tool (default=no)],
|
||||
MOZ_TRACEVIS=1,
|
||||
MOZ_TRACEVIS= )
|
||||
if test -n "$MOZ_TRACEVIS"; then
|
||||
AC_DEFINE(MOZ_TRACEVIS)
|
||||
fi
|
||||
|
||||
dnl ========================================================
|
||||
dnl = Use Valgrind
|
||||
dnl ========================================================
|
||||
|
|
|
@ -3269,6 +3269,14 @@ static JSFunctionSpec VtuneFunctions[] = {
|
|||
};
|
||||
#endif
|
||||
|
||||
#ifdef MOZ_TRACEVIS
|
||||
static JSFunctionSpec EthogramFunctions[] = {
|
||||
{"initEthogram", js_InitEthogram, 0, 0, 0},
|
||||
{"shutdownEthogram", js_ShutdownEthogram, 0, 0, 0},
|
||||
{nsnull, nsnull, 0, 0, 0}
|
||||
};
|
||||
#endif
|
||||
|
||||
nsresult
|
||||
nsJSContext::InitClasses(void *aGlobalObj)
|
||||
{
|
||||
|
@ -3316,6 +3324,11 @@ nsJSContext::InitClasses(void *aGlobalObj)
|
|||
::JS_DefineFunctions(mContext, globalObj, VtuneFunctions);
|
||||
#endif
|
||||
|
||||
#ifdef MOZ_TRACEVIS
|
||||
// Attempt to initialize Ethogram functions
|
||||
::JS_DefineFunctions(mContext, globalObj, EthogramFunctions);
|
||||
#endif
|
||||
|
||||
JSOptionChangedCallback(js_options_dot_str, this);
|
||||
|
||||
return rv;
|
||||
|
|
|
@ -2012,3 +2012,435 @@ js_ResumeVtune(JSContext *cx, JSObject *obj,
|
|||
}
|
||||
|
||||
#endif /* MOZ_VTUNE */
|
||||
|
||||
#ifdef MOZ_TRACEVIS
|
||||
/*
|
||||
* Ethogram - Javascript wrapper for TraceVis state
|
||||
*
|
||||
* ethology: The scientific study of animal behavior,
|
||||
* especially as it occurs in a natural environment.
|
||||
* ethogram: A pictorial catalog of the behavioral patterns of
|
||||
* an organism or a species.
|
||||
*
|
||||
*/
|
||||
#if defined(XP_WIN)
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
#include "jstracer.h"
|
||||
|
||||
#define ETHOGRAM_BUF_SIZE 65536
|
||||
|
||||
static JSBool
|
||||
ethogram_construct(JSContext *cx, JSObject *obj,
|
||||
uintN argc, jsval *argv, jsval *rval);
|
||||
static void
|
||||
ethogram_finalize(JSContext *cx, JSObject *obj);
|
||||
|
||||
static JSClass ethogram_class = {
|
||||
"Ethogram",
|
||||
JSCLASS_HAS_PRIVATE,
|
||||
JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
|
||||
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, ethogram_finalize,
|
||||
JSCLASS_NO_OPTIONAL_MEMBERS
|
||||
};
|
||||
|
||||
struct EthogramEvent {
|
||||
TraceVisState s;
|
||||
TraceVisExitReason r;
|
||||
int ts;
|
||||
int tus;
|
||||
JSString *filename;
|
||||
int lineno;
|
||||
};
|
||||
|
||||
static int
|
||||
compare_strings(const void *k1, const void *k2)
|
||||
{
|
||||
return strcmp((const char *) k1, (const char *) k2) == 0;
|
||||
}
|
||||
|
||||
class EthogramEventBuffer {
|
||||
private:
|
||||
EthogramEvent mBuf[ETHOGRAM_BUF_SIZE];
|
||||
int mReadPos;
|
||||
int mWritePos;
|
||||
JSObject *mFilenames;
|
||||
int mStartSecond;
|
||||
|
||||
struct EthogramScriptEntry {
|
||||
char *filename;
|
||||
JSString *jsfilename;
|
||||
|
||||
EthogramScriptEntry *next;
|
||||
};
|
||||
EthogramScriptEntry *mScripts;
|
||||
|
||||
public:
|
||||
friend JSBool
|
||||
ethogram_construct(JSContext *cx, JSObject *obj,
|
||||
uintN argc, jsval *argv, jsval *rval);
|
||||
|
||||
inline void push(TraceVisState s, TraceVisExitReason r, char *filename, int lineno) {
|
||||
mBuf[mWritePos].s = s;
|
||||
mBuf[mWritePos].r = r;
|
||||
#if defined(XP_WIN)
|
||||
FILETIME now;
|
||||
GetSystemTimeAsFileTime(&now);
|
||||
unsigned long long raw_us = 0.1 *
|
||||
(((unsigned long long) now.dwHighDateTime << 32ULL) |
|
||||
(unsigned long long) now.dwLowDateTime);
|
||||
unsigned int sec = raw_us / 1000000L;
|
||||
unsigned int usec = raw_us % 1000000L;
|
||||
mBuf[mWritePos].ts = sec - mStartSecond;
|
||||
mBuf[mWritePos].tus = usec;
|
||||
#else
|
||||
struct timeval tv;
|
||||
gettimeofday(&tv, NULL);
|
||||
mBuf[mWritePos].ts = tv.tv_sec - mStartSecond;
|
||||
mBuf[mWritePos].tus = tv.tv_usec;
|
||||
#endif
|
||||
|
||||
JSString *jsfilename = findScript(filename);
|
||||
mBuf[mWritePos].filename = jsfilename;
|
||||
mBuf[mWritePos].lineno = lineno;
|
||||
|
||||
mWritePos = (mWritePos + 1) % ETHOGRAM_BUF_SIZE;
|
||||
if (mWritePos == mReadPos) {
|
||||
mReadPos = (mWritePos + 1) % ETHOGRAM_BUF_SIZE;
|
||||
}
|
||||
}
|
||||
|
||||
inline EthogramEvent *pop() {
|
||||
EthogramEvent *e = &mBuf[mReadPos];
|
||||
mReadPos = (mReadPos + 1) % ETHOGRAM_BUF_SIZE;
|
||||
return e;
|
||||
}
|
||||
|
||||
bool isEmpty() {
|
||||
return (mReadPos == mWritePos);
|
||||
}
|
||||
|
||||
EthogramScriptEntry *addScript(JSContext *cx, JSObject *obj, char *filename, JSString *jsfilename) {
|
||||
JSHashNumber hash = JS_HashString(filename);
|
||||
JSHashEntry **hep = JS_HashTableRawLookup(traceVisScriptTable, hash, filename);
|
||||
if (*hep != NULL)
|
||||
return JS_FALSE;
|
||||
|
||||
JS_HashTableRawAdd(traceVisScriptTable, hep, hash, filename, this);
|
||||
|
||||
EthogramScriptEntry * entry = (EthogramScriptEntry *) JS_malloc(cx, sizeof(EthogramScriptEntry));
|
||||
if (entry == NULL)
|
||||
return NULL;
|
||||
|
||||
entry->next = mScripts;
|
||||
mScripts = entry;
|
||||
entry->filename = filename;
|
||||
entry->jsfilename = jsfilename;
|
||||
|
||||
return mScripts;
|
||||
}
|
||||
|
||||
void removeScripts(JSContext *cx) {
|
||||
EthogramScriptEntry *se = mScripts;
|
||||
while (se != NULL) {
|
||||
char *filename = se->filename;
|
||||
|
||||
JSHashNumber hash = JS_HashString(filename);
|
||||
JSHashEntry **hep = JS_HashTableRawLookup(traceVisScriptTable, hash, filename);
|
||||
JSHashEntry *he = *hep;
|
||||
if (he) {
|
||||
/* we hardly knew he */
|
||||
JS_HashTableRawRemove(traceVisScriptTable, hep, he);
|
||||
}
|
||||
|
||||
EthogramScriptEntry *se_head = se;
|
||||
se = se->next;
|
||||
JS_free(cx, se_head);
|
||||
}
|
||||
}
|
||||
|
||||
JSString *findScript(char *filename) {
|
||||
EthogramScriptEntry *se = mScripts;
|
||||
while (se != NULL) {
|
||||
if (compare_strings(se->filename, filename))
|
||||
return (se->jsfilename);
|
||||
se = se->next;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
JSObject *filenames() {
|
||||
return mFilenames;
|
||||
}
|
||||
|
||||
int length() {
|
||||
if (mWritePos < mReadPos)
|
||||
return (mWritePos + ETHOGRAM_BUF_SIZE) - mReadPos;
|
||||
else
|
||||
return mWritePos - mReadPos;
|
||||
}
|
||||
};
|
||||
|
||||
static char jstv_empty[] = "<null>";
|
||||
|
||||
inline char *
|
||||
jstv_Filename(JSStackFrame *fp)
|
||||
{
|
||||
while (fp && fp->script == NULL)
|
||||
fp = fp->down;
|
||||
return (fp && fp->script && fp->script->filename)
|
||||
? (char *)fp->script->filename
|
||||
: jstv_empty;
|
||||
}
|
||||
inline uintN
|
||||
jstv_Lineno(JSContext *cx, JSStackFrame *fp)
|
||||
{
|
||||
while (fp && fp->regs == NULL)
|
||||
fp = fp->down;
|
||||
return (fp && fp->regs) ? js_FramePCToLineNumber(cx, fp) : 0;
|
||||
}
|
||||
|
||||
/* Collect states here and distribute to a matching buffer, if any */
|
||||
JS_FRIEND_API(void)
|
||||
js_StoreTraceVisState(JSContext *cx, TraceVisState s, TraceVisExitReason r)
|
||||
{
|
||||
JSStackFrame *fp = cx->fp;
|
||||
|
||||
char *script_file = jstv_Filename(fp);
|
||||
JSHashNumber hash = JS_HashString(script_file);
|
||||
|
||||
JSHashEntry **hep = JS_HashTableRawLookup(traceVisScriptTable, hash, script_file);
|
||||
/* update event buffer, flag if overflowed */
|
||||
JSHashEntry *he = *hep;
|
||||
if (he) {
|
||||
EthogramEventBuffer *p;
|
||||
p = (EthogramEventBuffer *) he->value;
|
||||
|
||||
p->push(s, r, script_file, jstv_Lineno(cx, fp));
|
||||
}
|
||||
}
|
||||
|
||||
static JSBool
|
||||
ethogram_construct(JSContext *cx, JSObject *obj,
|
||||
uintN argc, jsval *argv, jsval *rval)
|
||||
{
|
||||
EthogramEventBuffer *p;
|
||||
|
||||
p = (EthogramEventBuffer *) JS_malloc(cx, sizeof(EthogramEventBuffer));
|
||||
|
||||
p->mReadPos = p->mWritePos = 0;
|
||||
p->mScripts = NULL;
|
||||
p->mFilenames = JS_NewArrayObject(cx, 0, NULL);
|
||||
|
||||
#if defined(XP_WIN)
|
||||
FILETIME now;
|
||||
GetSystemTimeAsFileTime(&now);
|
||||
unsigned long long raw_us = 0.1 *
|
||||
(((unsigned long long) now.dwHighDateTime << 32ULL) |
|
||||
(unsigned long long) now.dwLowDateTime);
|
||||
unsigned int s = raw_us / 1000000L;
|
||||
p->mStartSecond = s;
|
||||
#else
|
||||
struct timeval tv;
|
||||
gettimeofday(&tv, NULL);
|
||||
p->mStartSecond = tv.tv_sec;
|
||||
#endif
|
||||
jsval filenames = OBJECT_TO_JSVAL(p->filenames());
|
||||
if (!JS_DefineProperty(cx, obj, "filenames", filenames,
|
||||
NULL, NULL, JSPROP_READONLY|JSPROP_PERMANENT))
|
||||
return JS_FALSE;
|
||||
|
||||
if (!JS_IsConstructing(cx)) {
|
||||
obj = JS_NewObject(cx, ðogram_class, NULL, NULL);
|
||||
if (!obj)
|
||||
return JS_FALSE;
|
||||
*rval = OBJECT_TO_JSVAL(obj);
|
||||
}
|
||||
JS_SetPrivate(cx, obj, p);
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
ethogram_finalize(JSContext *cx, JSObject *obj)
|
||||
{
|
||||
EthogramEventBuffer *p;
|
||||
p = (EthogramEventBuffer *) JS_GetInstancePrivate(cx, obj, ðogram_class, NULL);
|
||||
if (!p)
|
||||
return;
|
||||
|
||||
p->removeScripts(cx);
|
||||
|
||||
JS_free(cx, p);
|
||||
}
|
||||
|
||||
static JSBool
|
||||
ethogram_addScript(JSContext *cx, JSObject *obj,
|
||||
uintN argc, jsval *argv, jsval *rval)
|
||||
{
|
||||
JSString *str;
|
||||
char *filename = NULL;
|
||||
if (argc > 0 && JSVAL_IS_STRING(argv[0])) {
|
||||
str = JSVAL_TO_STRING(argv[0]);
|
||||
filename = js_DeflateString(cx,
|
||||
str->chars(),
|
||||
str->length());
|
||||
}
|
||||
|
||||
/* silently ignore no args */
|
||||
if (!filename)
|
||||
return JS_TRUE;
|
||||
|
||||
EthogramEventBuffer *p = (EthogramEventBuffer *) JS_GetInstancePrivate(cx, obj, ðogram_class, argv);
|
||||
|
||||
p->addScript(cx, obj, filename, str);
|
||||
JS_CallFunctionName(cx, p->filenames(), "push", 1, argv, rval);
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
static JSBool
|
||||
ethogram_getAllEvents(JSContext *cx, JSObject *obj,
|
||||
uintN argc, jsval *argv, jsval *rval)
|
||||
{
|
||||
EthogramEventBuffer *p;
|
||||
|
||||
p = (EthogramEventBuffer *) JS_GetInstancePrivate(cx, obj, ðogram_class, argv);
|
||||
if (!p)
|
||||
return JS_FALSE;
|
||||
|
||||
if (p->isEmpty()) {
|
||||
*rval = JSVAL_NULL;
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
JSObject *rarray = JS_NewArrayObject(cx, 0, NULL);
|
||||
if (rarray == NULL) {
|
||||
*rval = JSVAL_NULL;
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
*rval = OBJECT_TO_JSVAL(rarray);
|
||||
|
||||
for (int i = 0; !p->isEmpty(); i++) {
|
||||
|
||||
JSObject *x = JS_NewObject(cx, NULL, NULL, NULL);
|
||||
if (x == NULL)
|
||||
return JS_FALSE;
|
||||
|
||||
EthogramEvent *e = p->pop();
|
||||
|
||||
jsval state = INT_TO_JSVAL(e->s);
|
||||
jsval reason = INT_TO_JSVAL(e->r);
|
||||
jsval ts = INT_TO_JSVAL(e->ts);
|
||||
jsval tus = INT_TO_JSVAL(e->tus);
|
||||
|
||||
jsval filename = STRING_TO_JSVAL(e->filename);
|
||||
jsval lineno = INT_TO_JSVAL(e->lineno);
|
||||
|
||||
if (!JS_SetProperty(cx, x, "state", &state))
|
||||
return JS_FALSE;
|
||||
if (!JS_SetProperty(cx, x, "reason", &reason))
|
||||
return JS_FALSE;
|
||||
if (!JS_SetProperty(cx, x, "ts", &ts))
|
||||
return JS_FALSE;
|
||||
if (!JS_SetProperty(cx, x, "tus", &tus))
|
||||
return JS_FALSE;
|
||||
|
||||
if (!JS_SetProperty(cx, x, "filename", &filename))
|
||||
return JS_FALSE;
|
||||
if (!JS_SetProperty(cx, x, "lineno", &lineno))
|
||||
return JS_FALSE;
|
||||
|
||||
jsval element = OBJECT_TO_JSVAL(x);
|
||||
JS_SetElement(cx, rarray, i, &element);
|
||||
}
|
||||
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
static JSBool
|
||||
ethogram_getNextEvent(JSContext *cx, JSObject *obj,
|
||||
uintN argc, jsval *argv, jsval *rval)
|
||||
{
|
||||
EthogramEventBuffer *p;
|
||||
|
||||
p = (EthogramEventBuffer *) JS_GetInstancePrivate(cx, obj, ðogram_class, argv);
|
||||
if (!p)
|
||||
return JS_FALSE;
|
||||
|
||||
JSObject *x = JS_NewObject(cx, NULL, NULL, NULL);
|
||||
if (x == NULL)
|
||||
return JS_FALSE;
|
||||
|
||||
if (p->isEmpty()) {
|
||||
*rval = JSVAL_NULL;
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
EthogramEvent *e = p->pop();
|
||||
jsval state = INT_TO_JSVAL(e->s);
|
||||
jsval reason = INT_TO_JSVAL(e->r);
|
||||
jsval ts = INT_TO_JSVAL(e->ts);
|
||||
jsval tus = INT_TO_JSVAL(e->tus);
|
||||
|
||||
jsval filename = STRING_TO_JSVAL(e->filename);
|
||||
jsval lineno = INT_TO_JSVAL(e->lineno);
|
||||
|
||||
if (!JS_SetProperty(cx, x, "state", &state))
|
||||
return JS_FALSE;
|
||||
if (!JS_SetProperty(cx, x, "reason", &reason))
|
||||
return JS_FALSE;
|
||||
if (!JS_SetProperty(cx, x, "ts", &ts))
|
||||
return JS_FALSE;
|
||||
if (!JS_SetProperty(cx, x, "tus", &tus))
|
||||
return JS_FALSE;
|
||||
if (!JS_SetProperty(cx, x, "filename", &filename))
|
||||
return JS_FALSE;
|
||||
|
||||
if (!JS_SetProperty(cx, x, "lineno", &lineno))
|
||||
return JS_FALSE;
|
||||
|
||||
*rval = OBJECT_TO_JSVAL(x);
|
||||
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
static JSFunctionSpec ethogram_methods[] = {
|
||||
{"addScript", ethogram_addScript, 1},
|
||||
{"getAllEvents", ethogram_getAllEvents, 0},
|
||||
{"getNextEvent", ethogram_getNextEvent, 0},
|
||||
{0}
|
||||
};
|
||||
|
||||
/*
|
||||
* An |Ethogram| organizes the output of a collection of files that should be
|
||||
* monitored together. A single object gets events for the group.
|
||||
*/
|
||||
JS_FRIEND_API(JSBool)
|
||||
js_InitEthogram(JSContext *cx, JSObject *obj,
|
||||
uintN argc, jsval *argv, jsval *rval)
|
||||
{
|
||||
if (!traceVisScriptTable) {
|
||||
traceVisScriptTable = JS_NewHashTable(8, JS_HashString, compare_strings,
|
||||
NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
JS_InitClass(cx, JS_GetGlobalObject(cx), NULL, ðogram_class,
|
||||
ethogram_construct, 0, NULL, ethogram_methods,
|
||||
NULL, NULL);
|
||||
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
JS_FRIEND_API(JSBool)
|
||||
js_ShutdownEthogram(JSContext *cx, JSObject *obj,
|
||||
uintN argc, jsval *argv, jsval *rval)
|
||||
{
|
||||
if (traceVisScriptTable)
|
||||
JS_HashTableDestroy(traceVisScriptTable);
|
||||
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
#endif /* MOZ_TRACEVIS */
|
||||
|
|
|
@ -495,6 +495,15 @@ js_ResumeVtune(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
|
|||
|
||||
#endif /* MOZ_VTUNE */
|
||||
|
||||
#ifdef MOZ_TRACEVIS
|
||||
extern JS_FRIEND_API(JSBool)
|
||||
js_InitEthogram(JSContext *cx, JSObject *obj,
|
||||
uintN argc, jsval *argv, jsval *rval);
|
||||
extern JS_FRIEND_API(JSBool)
|
||||
js_ShutdownEthogram(JSContext *cx, JSObject *obj,
|
||||
uintN argc, jsval *argv, jsval *rval);
|
||||
#endif /* MOZ_TRACEVIS */
|
||||
|
||||
JS_END_EXTERN_C
|
||||
|
||||
#endif /* jsdbgapi_h___ */
|
||||
|
|
|
@ -2664,7 +2664,7 @@ JS_REQUIRES_STACK JSBool
|
|||
js_Interpret(JSContext *cx)
|
||||
{
|
||||
#ifdef MOZ_TRACEVIS
|
||||
TraceVisStateObj tvso(S_INTERP);
|
||||
TraceVisStateObj tvso(cx, S_INTERP);
|
||||
#endif
|
||||
|
||||
JSRuntime *rt;
|
||||
|
@ -2880,11 +2880,18 @@ js_Interpret(JSContext *cx)
|
|||
#ifdef JS_TRACER
|
||||
|
||||
#ifdef MOZ_TRACEVIS
|
||||
#if JS_THREADED_INTERP
|
||||
#define MONITOR_BRANCH_TRACEVIS \
|
||||
JS_BEGIN_MACRO \
|
||||
if (jumpTable != interruptJumpTable) \
|
||||
js_EnterTraceVisState(S_RECORD, R_NONE); \
|
||||
js_EnterTraceVisState(cx, S_RECORD, R_NONE); \
|
||||
JS_END_MACRO
|
||||
#else /* !JS_THREADED_INTERP */
|
||||
#define MONITOR_BRANCH_TRACEVIS \
|
||||
JS_BEGIN_MACRO \
|
||||
js_EnterTraceVisState(cx, S_RECORD, R_NONE); \
|
||||
JS_END_MACRO
|
||||
#endif
|
||||
#else
|
||||
#define MONITOR_BRANCH_TRACEVIS
|
||||
#endif
|
||||
|
@ -3115,7 +3122,7 @@ js_Interpret(JSContext *cx)
|
|||
#if JS_THREADED_INTERP
|
||||
#ifdef MOZ_TRACEVIS
|
||||
if (!moreInterrupts)
|
||||
js_ExitTraceVisState(R_ABORT);
|
||||
js_ExitTraceVisState(cx, R_ABORT);
|
||||
#endif
|
||||
jumpTable = moreInterrupts ? interruptJumpTable : normalJumpTable;
|
||||
JS_EXTENSION_(goto *normalJumpTable[op]);
|
||||
|
|
|
@ -3729,7 +3729,7 @@ JS_REQUIRES_STACK void
|
|||
TraceRecorder::compile(JSTraceMonitor* tm)
|
||||
{
|
||||
#ifdef MOZ_TRACEVIS
|
||||
TraceVisStateObj tvso(S_COMPILE);
|
||||
TraceVisStateObj tvso(cx, S_COMPILE);
|
||||
#endif
|
||||
|
||||
if (tm->needFlush) {
|
||||
|
@ -5427,7 +5427,7 @@ ExecuteTree(JSContext* cx, Fragment* f, uintN& inlineCallCount,
|
|||
VMSideExit** innermostNestedGuardp)
|
||||
{
|
||||
#ifdef MOZ_TRACEVIS
|
||||
TraceVisStateObj tvso(S_EXECUTE);
|
||||
TraceVisStateObj tvso(cx, S_EXECUTE);
|
||||
#endif
|
||||
|
||||
JS_ASSERT(f->root == f && f->code() && f->vmprivate);
|
||||
|
@ -5525,7 +5525,7 @@ ExecuteTree(JSContext* cx, Fragment* f, uintN& inlineCallCount,
|
|||
// TraceVisStateObj constructors and destructors must run at the right times.
|
||||
{
|
||||
#ifdef MOZ_TRACEVIS
|
||||
TraceVisStateObj tvso_n(S_NATIVE);
|
||||
TraceVisStateObj tvso_n(cx, S_NATIVE);
|
||||
#endif
|
||||
#if defined(JS_NO_FASTCALL) && defined(NANOJIT_IA32)
|
||||
SIMULATE_FASTCALL(rec, state, NULL, u.func);
|
||||
|
@ -5837,7 +5837,7 @@ JS_REQUIRES_STACK bool
|
|||
js_MonitorLoopEdge(JSContext* cx, uintN& inlineCallCount)
|
||||
{
|
||||
#ifdef MOZ_TRACEVIS
|
||||
TraceVisStateObj tvso(S_MONITOR);
|
||||
TraceVisStateObj tvso(cx, S_MONITOR);
|
||||
#endif
|
||||
|
||||
JSTraceMonitor* tm = &JS_TRACE_MONITOR(cx);
|
||||
|
@ -12732,6 +12732,7 @@ DumpPeerStability(JSTraceMonitor* tm, const void* ip, JSObject* globalObj, uint3
|
|||
#ifdef MOZ_TRACEVIS
|
||||
|
||||
FILE* traceVisLogFile = NULL;
|
||||
JSHashTable *traceVisScriptTable = NULL;
|
||||
|
||||
JS_FRIEND_API(bool)
|
||||
JS_StartTraceVis(const char* filename = "tracevis.dat")
|
||||
|
|
|
@ -1005,14 +1005,18 @@ enum TraceVisExitReason {
|
|||
R_OTHER_EXIT
|
||||
};
|
||||
|
||||
const unsigned long long MS64_MASK = 0xfllu << 60;
|
||||
const unsigned long long MR64_MASK = 0x1fllu << 55;
|
||||
const unsigned long long MS64_MASK = 0xfull << 60;
|
||||
const unsigned long long MR64_MASK = 0x1full << 55;
|
||||
const unsigned long long MT64_MASK = ~(MS64_MASK | MR64_MASK);
|
||||
|
||||
extern FILE* traceVisLogFile;
|
||||
extern JSHashTable *traceVisScriptTable;
|
||||
|
||||
extern JS_FRIEND_API(void)
|
||||
js_StoreTraceVisState(JSContext *cx, TraceVisState s, TraceVisExitReason r);
|
||||
|
||||
static inline void
|
||||
js_LogTraceVisState(TraceVisState s, TraceVisExitReason r)
|
||||
js_LogTraceVisState(JSContext *cx, TraceVisState s, TraceVisExitReason r)
|
||||
{
|
||||
if (traceVisLogFile) {
|
||||
unsigned long long sllu = s;
|
||||
|
@ -1020,30 +1024,35 @@ js_LogTraceVisState(TraceVisState s, TraceVisExitReason r)
|
|||
unsigned long long d = (sllu << 60) | (rllu << 55) | (rdtsc() & MT64_MASK);
|
||||
fwrite(&d, sizeof(d), 1, traceVisLogFile);
|
||||
}
|
||||
if (traceVisScriptTable) {
|
||||
js_StoreTraceVisState(cx, s, r);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
js_EnterTraceVisState(TraceVisState s, TraceVisExitReason r)
|
||||
js_EnterTraceVisState(JSContext *cx, TraceVisState s, TraceVisExitReason r)
|
||||
{
|
||||
js_LogTraceVisState(s, r);
|
||||
js_LogTraceVisState(cx, s, r);
|
||||
}
|
||||
|
||||
static inline void
|
||||
js_ExitTraceVisState(TraceVisExitReason r)
|
||||
js_ExitTraceVisState(JSContext *cx, TraceVisExitReason r)
|
||||
{
|
||||
js_LogTraceVisState(S_EXITLAST, r);
|
||||
js_LogTraceVisState(cx, S_EXITLAST, r);
|
||||
}
|
||||
|
||||
struct TraceVisStateObj {
|
||||
TraceVisExitReason r;
|
||||
JSContext *mCx;
|
||||
|
||||
inline TraceVisStateObj(TraceVisState s) : r(R_NONE)
|
||||
inline TraceVisStateObj(JSContext *cx, TraceVisState s) : r(R_NONE)
|
||||
{
|
||||
js_EnterTraceVisState(s, R_NONE);
|
||||
js_EnterTraceVisState(cx, s, R_NONE);
|
||||
mCx = cx;
|
||||
}
|
||||
inline ~TraceVisStateObj()
|
||||
{
|
||||
js_ExitTraceVisState(r);
|
||||
js_ExitTraceVisState(mCx, r);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -83,7 +83,7 @@
|
|||
#include "prmem.h"
|
||||
#include "plbase64.h"
|
||||
|
||||
#if defined(MOZ_SHARK) || defined(MOZ_CALLGRIND) || defined(MOZ_VTUNE)
|
||||
#if defined(MOZ_SHARK) || defined(MOZ_CALLGRIND) || defined(MOZ_VTUNE) || defined(MOZ_TRACEVIS)
|
||||
#include "jsdbgapi.h"
|
||||
#endif
|
||||
|
||||
|
@ -291,6 +291,10 @@ static JSFunctionSpec gGlobalFun[] = {
|
|||
{"stopVtune", js_StopVtune, 0,0,0},
|
||||
{"pauseVtune", js_PauseVtune, 0,0,0},
|
||||
{"resumeVtune", js_ResumeVtune, 0,0,0},
|
||||
#endif
|
||||
#ifdef MOZ_TRACEVIS
|
||||
{"initEthogram", js_InitEthogram, 0,0,0},
|
||||
{"shutdownEthogram", js_ShutdownEthogram, 0,0,0},
|
||||
#endif
|
||||
{nsnull,nsnull,0,0,0}
|
||||
};
|
||||
|
|
Загрузка…
Ссылка в новой задаче