diff --git a/js/src/jscompartment.cpp b/js/src/jscompartment.cpp index a34c038cba4..63c9289b081 100644 --- a/js/src/jscompartment.cpp +++ b/js/src/jscompartment.cpp @@ -601,6 +601,19 @@ JSCompartment::incBackEdgeCount(jsbytecode *pc) } bool -JSCompartment::isAboutToBeCollected(JSGCInvocationKind gckind) { +JSCompartment::isAboutToBeCollected(JSGCInvocationKind gckind) +{ return !hold && (arenaListsAreEmpty() || gckind == GC_LAST_CONTEXT); } + +void +JSCompartment::removeDebug(Debug *dbg) +{ + for (Debug **p = debuggers.begin(); p != debuggers.end(); p++) { + if (*p == dbg) { + debuggers.erase(p); + return; + } + } + JS_NOT_REACHED("JSCompartment::removeDebug"); +} diff --git a/js/src/jscompartment.h b/js/src/jscompartment.h index 4ab81f6f792..374bb1137d8 100644 --- a/js/src/jscompartment.h +++ b/js/src/jscompartment.h @@ -506,9 +506,6 @@ struct JS_FRIEND_API(JSCompartment) { DebugVector debuggers; - // Implemented in jsdbg.cpp - JSTrapStatus dispatchDebuggerStatement(JSContext *cx, js::Value *vp); - JSCompartment *thisForCtor() { return this; } public: js::MathCache *getMathCache(JSContext *cx) { @@ -520,10 +517,6 @@ struct JS_FRIEND_API(JSCompartment) { const DebugVector &getDebuggers() const { return debuggers; } - JSTrapStatus onDebuggerStatement(JSContext *cx, js::Value *vp) { - return debuggers.empty() ? JSTRAP_CONTINUE : dispatchDebuggerStatement(cx, vp); - } - bool addDebug(js::Debug *dbg) { return debuggers.append(dbg); } void removeDebug(js::Debug *dbg); }; diff --git a/js/src/jsdbg.cpp b/js/src/jsdbg.cpp index e8ab7a0ea28..85d5b29d9f4 100644 --- a/js/src/jsdbg.cpp +++ b/js/src/jsdbg.cpp @@ -206,11 +206,9 @@ CallMethodIfPresent(JSContext *cx, JSObject *obj, const char *name, int argc, Va } JSTrapStatus -Debug::onDebuggerStatement(JSContext *cx, Value *vp) +Debug::handleDebuggerStatement(JSContext *cx, Value *vp) { - if (!hasDebuggerHandler) - return JSTRAP_CONTINUE; - + JS_ASSERT(hasDebuggerHandler); AutoCompartment ac(cx, hooksObject); if (!ac.enter()) return JSTRAP_ERROR; @@ -222,7 +220,7 @@ Debug::onDebuggerStatement(JSContext *cx, Value *vp) } JSTrapStatus -JSCompartment::dispatchDebuggerStatement(JSContext *cx, js::Value *vp) +Debug::dispatchDebuggerStatement(JSContext *cx, js::Value *vp) { // Determine which debuggers will receive this event, and in what order. // Make a copy of the list, since the original is mutable and we will be @@ -230,6 +228,8 @@ JSCompartment::dispatchDebuggerStatement(JSContext *cx, js::Value *vp) // Note: In the general case, 'triggered' contains references to objects in // different compartments--every compartment *except* this one. AutoValueVector triggered(cx); + JSCompartment *compartment = cx->compartment; + const JSCompartment::DebugVector &debuggers = compartment->getDebuggers(); for (Debug **p = debuggers.begin(); p != debuggers.end(); p++) { Debug *dbg = *p; if (dbg->observesDebuggerStatement()) { @@ -242,7 +242,7 @@ JSCompartment::dispatchDebuggerStatement(JSContext *cx, js::Value *vp) // should still be delivered. for (Value *p = triggered.begin(); p != triggered.end(); p++) { Debug *dbg = Debug::fromJSObject(&p->toObject()); - if (dbg->observesCompartment(this) && dbg->observesDebuggerStatement()) { + if (dbg->observesCompartment(compartment) && dbg->observesDebuggerStatement()) { JSTrapStatus st = dbg->onDebuggerStatement(cx, vp); if (st != JSTRAP_CONTINUE) return st; @@ -301,18 +301,6 @@ Debug::trace(JSTracer *trc, JSObject *obj) } } -void -JSCompartment::removeDebug(Debug *dbg) -{ - for (Debug **p = debuggers.begin(); p != debuggers.end(); p++) { - if (*p == dbg) { - debuggers.erase(p); - return; - } - } - JS_NOT_REACHED("JSCompartment::removeDebug"); -} - void Debug::finalize(JSContext *cx, JSObject *obj) { @@ -458,7 +446,7 @@ JSPropertySpec Debug::properties[] = { Debug::setUncaughtExceptionHook, 0), JS_PS_END }; - + extern JS_PUBLIC_API(JSBool) JS_DefineDebugObject(JSContext *cx, JSObject *obj) diff --git a/js/src/jsdbg.h b/js/src/jsdbg.h index 57533f2b628..bddc27f7373 100644 --- a/js/src/jsdbg.h +++ b/js/src/jsdbg.h @@ -43,6 +43,7 @@ #define jsdbg_h__ #include "jsapi.h" +#include "jscompartment.h" #include "jsgc.h" #include "jswrapper.h" #include "jsvalue.h" @@ -80,7 +81,11 @@ class Debug { static JSBool construct(JSContext *cx, uintN argc, Value *vp); static JSPropertySpec properties[]; - bool hasAnyLiveHooks() const { return observesDebuggerStatement(); } + inline bool hasAnyLiveHooks() const; + + inline bool observesDebuggerStatement() const; + static JSTrapStatus dispatchDebuggerStatement(JSContext *cx, Value *vp); + JSTrapStatus handleDebuggerStatement(JSContext *cx, Value *vp); public: Debug(JSObject *dbg, JSObject *hooks, JSCompartment *compartment); @@ -101,25 +106,55 @@ class Debug { // static bool mark(GCMarker *trc, JSCompartment *compartment, JSGCInvocationKind gckind); - JSObject *toJSObject() const { - JS_ASSERT(object); - return object; - } + inline JSObject *toJSObject() const; + static inline Debug *fromJSObject(JSObject *obj); - static Debug *fromJSObject(JSObject *obj) { - JS_ASSERT(obj->getClass() == &jsclass); - return (Debug *) obj->getPrivate(); - } + inline bool observesCompartment(JSCompartment *c) const; - bool observesCompartment(JSCompartment *c) const { - JS_ASSERT(c); - return debuggeeCompartment == c; - } - - bool observesDebuggerStatement() const { return enabled && hasDebuggerHandler; } - JSTrapStatus onDebuggerStatement(JSContext *cx, Value *vp); + static inline JSTrapStatus onDebuggerStatement(JSContext *cx, js::Value *vp); }; +bool +Debug::hasAnyLiveHooks() const +{ + return observesDebuggerStatement(); +} + +bool +Debug::observesCompartment(JSCompartment *c) const +{ + JS_ASSERT(c); + return debuggeeCompartment == c; +} + +JSObject * +Debug::toJSObject() const +{ + JS_ASSERT(object); + return object; +} + +Debug * +Debug::fromJSObject(JSObject *obj) +{ + JS_ASSERT(obj->getClass() == &jsclass); + return (Debug *) obj->getPrivate(); +} + +bool +Debug::observesDebuggerStatement() const +{ + return enabled && hasDebuggerHandler; +} + +JSTrapStatus +Debug::onDebuggerStatement(JSContext *cx, js::Value *vp) +{ + return cx->compartment->getDebuggers().empty() + ? JSTRAP_CONTINUE + : dispatchDebuggerStatement(cx, vp); +} + } #endif /* jsdbg_h__ */ diff --git a/js/src/jsinterp.cpp b/js/src/jsinterp.cpp index a780feae424..e8a3a3c7885 100644 --- a/js/src/jsinterp.cpp +++ b/js/src/jsinterp.cpp @@ -56,6 +56,7 @@ #include "jscntxt.h" #include "jsdate.h" #include "jsversion.h" +#include "jsdbg.h" #include "jsdbgapi.h" #include "jsfun.h" #include "jsgc.h" @@ -6173,7 +6174,7 @@ BEGIN_CASE(JSOP_DEBUGGER) if (JSDebuggerHandler handler = cx->debugHooks->debuggerHandler) st = handler(cx, script, regs.pc, Jsvalify(&rval), cx->debugHooks->debuggerHandlerData); if (st == JSTRAP_CONTINUE) - st = cx->compartment->onDebuggerStatement(cx, &rval); + st = Debug::onDebuggerStatement(cx, &rval); switch (st) { case JSTRAP_ERROR: goto error; diff --git a/js/src/methodjit/StubCalls.cpp b/js/src/methodjit/StubCalls.cpp index 3532e9923bb..8c1945e4886 100644 --- a/js/src/methodjit/StubCalls.cpp +++ b/js/src/methodjit/StubCalls.cpp @@ -42,6 +42,7 @@ #include "jsscope.h" #include "jsobj.h" #include "jslibmath.h" +#include "jsdbg.h" #include "jsiter.h" #include "jsnum.h" #include "jsxml.h" @@ -1175,7 +1176,7 @@ stubs::Debugger(VMFrame &f, jsbytecode *pc) f.cx->debugHooks->debuggerHandlerData); } if (st == JSTRAP_CONTINUE) - st = f.cx->compartment->onDebuggerStatement(f.cx, &rval); + st = Debug::onDebuggerStatement(f.cx, &rval); switch (st) { case JSTRAP_THROW: