Bug 588537 - Inject probe points all over the JS tree (r=gal)

This commit is contained in:
Steve Fink 2010-09-20 12:43:53 -07:00
parent 25b41ac85e
commit 0897291047
11 changed files with 82 additions and 9 deletions

View File

@ -76,6 +76,7 @@
#include "jsobj.h"
#include "jsopcode.h"
#include "jsparse.h"
#include "jsprobes.h"
#include "jsproxy.h"
#include "jsregexp.h"
#include "jsscope.h"
@ -2717,7 +2718,9 @@ JS_PUBLIC_API(JSString *)
JS_NewExternalString(JSContext *cx, const jschar *chars, size_t length, intN type)
{
CHECK_REQUEST(cx);
return JSExternalString::new_(cx, chars, length, type, NULL);
JSString *s = JSExternalString::new_(cx, chars, length, type, NULL);
Probes::createString(cx, s, length);
return s;
}
extern JS_PUBLIC_API(JSString *)

View File

@ -149,6 +149,20 @@ ThreadData::triggerOperationCallback(JSRuntime *rt)
} /* namespace js */
JSScript *
js_GetCurrentScript(JSContext *cx)
{
#ifdef JS_TRACER
VOUCH_DOES_NOT_REQUIRE_STACK();
if (JS_ON_TRACE(cx)) {
VMSideExit *bailExit = JS_TRACE_MONITOR_ON_TRACE(cx)->bailExit;
return bailExit ? bailExit->script : NULL;
}
#endif
return cx->hasfp() ? cx->fp()->maybeScript() : NULL;
}
#ifdef JS_THREADSAFE
JSThread *

View File

@ -2283,6 +2283,9 @@ js_GetScriptedCaller(JSContext *cx, js::StackFrame *fp);
extern jsbytecode*
js_GetCurrentBytecodePC(JSContext* cx);
extern JSScript *
js_GetCurrentScript(JSContext* cx);
extern bool
js_CurrentPCIsInImacro(JSContext *cx);

View File

@ -369,6 +369,7 @@ Chunk::allocateArena(JSContext *cx, unsigned thingKind)
--info.numFree;
JSRuntime *rt = info.runtime;
Probes::resizeHeap(comp, rt->gcBytes, rt->gcBytes + ArenaSize);
JS_ATOMIC_ADD(&rt->gcBytes, ArenaSize);
JS_ATOMIC_ADD(&comp->gcBytes, ArenaSize);
if (comp->gcBytes >= comp->gcTriggerBytes)
@ -388,6 +389,7 @@ Chunk::releaseArena(ArenaHeader *aheader)
#endif
JSCompartment *comp = aheader->compartment;
Probes::resizeHeap(comp, rt->gcBytes, rt->gcBytes - ArenaSize);
JS_ASSERT(size_t(rt->gcBytes) >= ArenaSize);
JS_ASSERT(size_t(comp->gcBytes) >= ArenaSize);
#ifdef JS_THREADSAFE
@ -2199,6 +2201,7 @@ SweepCompartments(JSContext *cx, JSGCInvocationKind gckind)
(compartment->arenaListsAreEmpty() || gckind == GC_LAST_CONTEXT))
{
compartment->freeLists.checkEmpty();
Probes::GCEndSweepPhase(compartment);
if (callback)
JS_ALWAYS_TRUE(callback(cx, compartment, JSCOMPARTMENT_DESTROY));
if (compartment->principals)
@ -2351,9 +2354,17 @@ MarkAndSweep(JSContext *cx, JSCompartment *comp, JSGCInvocationKind gckind GCTIM
comp->finalizeShapeArenaLists(cx);
GCTIMESTAMP(sweepShapeEnd);
} else {
/*
* Some sweeping is not compartment-specific. Start a NULL-compartment
* phase to demarcate all of that. (The compartment sweeps will nest
* within.)
*/
Probes::GCStartSweepPhase(NULL);
SweepCrossCompartmentWrappers(cx);
for (JSCompartment **c = rt->compartments.begin(); c != rt->compartments.end(); c++)
for (JSCompartment **c = rt->compartments.begin(); c != rt->compartments.end(); c++) {
Probes::GCStartSweepPhase(*c);
(*c)->finalizeObjectArenaLists(cx);
}
GCTIMESTAMP(sweepObjectEnd);
@ -2362,8 +2373,10 @@ MarkAndSweep(JSContext *cx, JSCompartment *comp, JSGCInvocationKind gckind GCTIM
GCTIMESTAMP(sweepStringEnd);
for (JSCompartment **c = rt->compartments.begin(); c != rt->compartments.end(); c++)
for (JSCompartment **c = rt->compartments.begin(); c != rt->compartments.end(); c++) {
(*c)->finalizeShapeArenaLists(cx);
Probes::GCEndSweepPhase(*c);
}
GCTIMESTAMP(sweepShapeEnd);
}
@ -2382,6 +2395,9 @@ MarkAndSweep(JSContext *cx, JSCompartment *comp, JSGCInvocationKind gckind GCTIM
* script's filename. See bug 323267.
*/
js_SweepScriptFilenames(rt);
/* non-compartmental sweep pieces */
Probes::GCEndSweepPhase(NULL);
}
#ifndef JS_THREADSAFE
@ -2696,6 +2712,16 @@ js_GC(JSContext *cx, JSCompartment *comp, JSGCInvocationKind gckind)
GCTIMER_BEGIN(rt, comp);
struct AutoGCProbe {
JSCompartment *comp;
AutoGCProbe(JSCompartment *comp) : comp(comp) {
Probes::GCStart(comp);
}
~AutoGCProbe() {
Probes::GCEnd(comp); /* background thread may still be sweeping */
}
} autoGCProbe(comp);
do {
/*
* Let the API user decide to defer a GC if it wants to (unless this

View File

@ -1201,7 +1201,10 @@ InvokeConstructor(JSContext *cx, const CallArgs &argsRef)
if (fun->isConstructor()) {
args.thisv().setMagicWithObjectOrNullPayload(NULL);
return CallJSNativeConstructor(cx, fun->u.n.native, args);
Probes::calloutBegin(cx, fun);
bool ok = CallJSNativeConstructor(cx, fun->u.n.native, args);
Probes::calloutEnd(cx, fun);
return ok;
}
if (!fun->isInterpretedConstructor())
@ -1245,7 +1248,9 @@ InvokeConstructorWithGivenThis(JSContext *cx, JSObject *thisobj, const Value &fv
bool ok;
if (clasp == &js_FunctionClass && (fun = callee.getFunctionPrivate())->isConstructor()) {
args.thisv().setMagicWithObjectOrNullPayload(thisobj);
Probes::calloutBegin(cx, fun);
ok = CallJSNativeConstructor(cx, fun->u.n.native, args);
Probes::calloutEnd(cx, fun);
} else if (clasp->construct) {
args.thisv().setMagicWithObjectOrNullPayload(thisobj);
ok = CallJSNativeConstructor(cx, clasp->construct, args);

View File

@ -70,6 +70,7 @@
#include "jsonparser.h"
#include "jsopcode.h"
#include "jsparse.h"
#include "jsprobes.h"
#include "jsproxy.h"
#include "jsscope.h"
#include "jsscript.h"
@ -100,7 +101,6 @@
#include "jsxdrapi.h"
#endif
#include "jsprobes.h"
#include "jsatominlines.h"
#include "jsobjinlines.h"
#include "jsscriptinlines.h"
@ -3961,6 +3961,7 @@ bool
JSObject::allocSlots(JSContext *cx, size_t newcap)
{
uint32 oldcap = numSlots();
size_t oldSize = slotsAndStructSize();
JS_ASSERT(newcap >= oldcap && !hasSlotsArray());
@ -3979,6 +3980,8 @@ JSObject::allocSlots(JSContext *cx, size_t newcap)
/* Copy over anything from the inline buffer. */
memcpy(slots, fixedSlots(), oldcap * sizeof(Value));
ClearValueRange(slots + oldcap, newcap - oldcap, isDenseArray());
Probes::resizeObject(cx, this, oldSize, slotsAndStructSize());
return true;
}
@ -4021,11 +4024,14 @@ JSObject::growSlots(JSContext *cx, size_t newcap)
Value *tmpslots = (Value*) cx->realloc_(slots, oldcap * sizeof(Value), actualCapacity * sizeof(Value));
if (!tmpslots)
return false; /* Leave dslots as its old size. */
size_t oldSize = slotsAndStructSize();
slots = tmpslots;
capacity = actualCapacity;
/* Initialize the additional slots we added. */
ClearValueRange(slots + oldcap, actualCapacity - oldcap, isDenseArray());
Probes::resizeObject(cx, this, oldSize, slotsAndStructSize());
return true;
}
@ -4051,6 +4057,7 @@ JSObject::shrinkSlots(JSContext *cx, size_t newcap)
Value *tmpslots = (Value*) cx->realloc_(slots, newcap * sizeof(Value));
if (!tmpslots)
return; /* Leave slots at its old size. */
size_t oldSize = slotsAndStructSize();
slots = tmpslots;
capacity = newcap;
@ -4058,6 +4065,8 @@ JSObject::shrinkSlots(JSContext *cx, size_t newcap)
/* Clear any excess holes if we tried to shrink below SLOT_CAPACITY_MIN. */
ClearValueRange(slots + fill, newcap - fill, isDenseArray());
}
Probes::resizeObject(cx, this, oldSize, slotsAndStructSize());
}
bool

View File

@ -135,13 +135,13 @@ JSObject::finalize(JSContext *cx)
if (isNewborn())
return;
js::Probes::finalizeObject(this);
/* Finalize obj first, in case it needs map and slots. */
js::Class *clasp = getClass();
if (clasp->finalize)
clasp->finalize(cx, this);
js::Probes::finalizeObject(this);
finish(cx);
}

View File

@ -74,6 +74,7 @@
#include "jsobj.h"
#include "jsopcode.h"
#include "jsparse.h"
#include "jsprobes.h"
#include "jsscan.h"
#include "jsscope.h"
#include "jsscript.h"
@ -929,6 +930,8 @@ Compiler::compileScript(JSContext *cx, JSObject *scopeChain, StackFrame *callerF
if (!cg.init(cx, JSTreeContext::USED_AS_TREE_CONTEXT))
return NULL;
Probes::compileScriptBegin(cx, filename, lineno);
MUST_FLOW_THROUGH("out");
// We can specialize a bit for the given scope chain if that scope chain is the global object.
@ -1123,6 +1126,7 @@ Compiler::compileScript(JSContext *cx, JSObject *scopeChain, StackFrame *callerF
out:
JS_FinishArenaPool(&codePool);
JS_FinishArenaPool(&notePool);
Probes::compileScriptEnd(cx, script, filename, lineno);
return script;
too_many_slots:

View File

@ -67,6 +67,7 @@
#include "jsnum.h"
#include "jsobj.h"
#include "jsopcode.h"
#include "jsprobes.h"
#include "jsregexp.h"
#include "jsscope.h"
#include "jsstaticcheck.h"
@ -3223,7 +3224,9 @@ js_NewString(JSContext *cx, jschar *chars, size_t length)
if (!CheckStringLength(cx, length))
return NULL;
return JSFixedString::new_(cx, chars, length);
JSFixedString *s = JSFixedString::new_(cx, chars, length);
Probes::createString(cx, s, length);
return s;
}
static JS_ALWAYS_INLINE JSFixedString *
@ -3244,6 +3247,7 @@ NewShortString(JSContext *cx, const jschar *chars, size_t length)
jschar *storage = str->init(length);
PodCopy(storage, chars, length);
storage[length] = 0;
Probes::createString(cx, str, length);
return str;
}
@ -3274,6 +3278,7 @@ NewShortString(JSContext *cx, const char *chars, size_t length)
*p++ = (unsigned char)*chars++;
*p = 0;
}
Probes::createString(cx, str, length);
return str;
}
@ -3364,7 +3369,9 @@ js_NewDependentString(JSContext *cx, JSString *baseArg, size_t start, size_t len
if (JSLinearString *staticStr = JSAtom::lookupStatic(chars, length))
return staticStr;
return JSDependentString::new_(cx, base, chars, length);
JSLinearString *s = JSDependentString::new_(cx, base, chars, length);
Probes::createString(cx, s, length);
return s;
}
JSFixedString *

View File

@ -4405,6 +4405,7 @@ TraceRecorder::snapshot(ExitType exitType)
0;
exit->exitType = exitType;
exit->pc = pc;
exit->script = fp->maybeScript();
exit->imacpc = fp->maybeImacropc();
exit->sp_adj = (stackSlots * sizeof(double)) - tree->nativeStackBase;
exit->rp_adj = exit->calldepth * sizeof(FrameInfo*);

View File

@ -364,6 +364,7 @@ struct FrameInfo;
struct VMSideExit : public nanojit::SideExit
{
JSScript* script;
jsbytecode* pc;
jsbytecode* imacpc;
intptr_t sp_adj;