diff --git a/content/base/src/nsGenericElement.cpp b/content/base/src/nsGenericElement.cpp index 08b464114b3..d74e266ded4 100644 --- a/content/base/src/nsGenericElement.cpp +++ b/content/base/src/nsGenericElement.cpp @@ -176,7 +176,7 @@ nsWrapperCache::RemoveExpandoObject() if (expando) { JSCompartment *compartment = js::GetObjectCompartment(expando); xpc::CompartmentPrivate *priv = - static_cast(js_GetCompartmentPrivate(compartment)); + static_cast(JS_GetCompartmentPrivate(compartment)); priv->RemoveDOMExpandoObject(expando); } } diff --git a/dom/base/nsGlobalWindow.cpp b/dom/base/nsGlobalWindow.cpp index 31707965ca5..db44ca952ca 100644 --- a/dom/base/nsGlobalWindow.cpp +++ b/dom/base/nsGlobalWindow.cpp @@ -2091,7 +2091,7 @@ nsGlobalWindow::SetNewDocument(nsIDocument* aDocument, JSCompartment *compartment = js::GetObjectCompartment(mJSObject); xpc::CompartmentPrivate *priv = - static_cast(JS_GetCompartmentPrivate(cx, compartment)); + static_cast(JS_GetCompartmentPrivate(compartment)); if (priv && priv->waiverWrapperMap) { NS_ASSERTION(!JS_IsExceptionPending(cx), "We might overwrite a pending exception!"); diff --git a/js/src/MemoryMetrics.cpp b/js/src/MemoryMetrics.cpp index 47336b96386..fed46a7eb00 100644 --- a/js/src/MemoryMetrics.cpp +++ b/js/src/MemoryMetrics.cpp @@ -217,8 +217,7 @@ CollectRuntimeStats(JSRuntime *rt, RuntimeStats *rtStats) rtStats->runtimeAtomsTable = rt->atomState.atoms.sizeOfExcludingThis(rtStats->mallocSizeOf); - JSContext *acx, *iter = NULL; - while ((acx = JS_ContextIteratorUnlocked(rt, &iter)) != NULL) + for (ContextIter acx(rt); !acx.done(); acx.next()) rtStats->runtimeContexts += acx->sizeOfIncludingThis(rtStats->mallocSizeOf); } diff --git a/js/src/jsapi.cpp b/js/src/jsapi.cpp index f5e0c84d009..562246019d5 100644 --- a/js/src/jsapi.cpp +++ b/js/src/jsapi.cpp @@ -760,6 +760,7 @@ JSRuntime::JSRuntime() gcBlackRootsData(NULL), gcGrayRootsTraceOp(NULL), gcGrayRootsData(NULL), + autoGCRooters(NULL), scriptPCCounters(NULL), NaNValue(UndefinedValue()), negativeInfinityValue(UndefinedValue()), @@ -866,12 +867,11 @@ JSRuntime::~JSRuntime() #ifdef DEBUG /* Don't hurt everyone in leaky ol' Mozilla with a fatal JS_ASSERT! */ if (!JS_CLIST_IS_EMPTY(&contextList)) { - JSContext *cx, *iter = NULL; unsigned cxcount = 0; - while ((cx = js_ContextIterator(this, JS_TRUE, &iter)) != NULL) { + for (ContextIter acx(this); !acx.done(); acx.next()) { fprintf(stderr, "JS API usage error: found live context at %p\n", - (void *) cx); + acx.get()); cxcount++; } fprintf(stderr, @@ -1198,13 +1198,11 @@ JS_GetRuntime(JSContext *cx) JS_PUBLIC_API(JSContext *) JS_ContextIterator(JSRuntime *rt, JSContext **iterp) { - return js_ContextIterator(rt, JS_TRUE, iterp); -} - -JS_PUBLIC_API(JSContext *) -JS_ContextIteratorUnlocked(JSRuntime *rt, JSContext **iterp) -{ - return js_ContextIterator(rt, JS_FALSE, iterp); + JSContext *cx = *iterp; + JSCList *next = cx ? cx->link.next : rt->contextList.next; + cx = (next == &rt->contextList) ? NULL : JSContext::fromLinkField(next); + *iterp = cx; + return cx; } JS_PUBLIC_API(JSVersion) @@ -1479,20 +1477,16 @@ AutoEnterFrameCompartment::enter(JSContext *cx, JSStackFrame *target) } /* namespace JS */ -JS_PUBLIC_API(void *) -JS_SetCompartmentPrivate(JSContext *cx, JSCompartment *compartment, void *data) +JS_PUBLIC_API(void) +JS_SetCompartmentPrivate(JSCompartment *compartment, void *data) { - CHECK_REQUEST(cx); - void *old = compartment->data; compartment->data = data; - return old; } JS_PUBLIC_API(void *) -JS_GetCompartmentPrivate(JSContext *cx, JSCompartment *compartment) +JS_GetCompartmentPrivate(JSCompartment *compartment) { - CHECK_REQUEST(cx); - return js_GetCompartmentPrivate(compartment); + return compartment->data; } JS_PUBLIC_API(JSBool) @@ -6633,12 +6627,6 @@ JS_ScheduleGC(JSContext *cx, uint32_t count, JSBool compartment) } #endif -JS_FRIEND_API(void *) -js_GetCompartmentPrivate(JSCompartment *compartment) -{ - return compartment->data; -} - /************************************************************************/ #if !defined(STATIC_EXPORTABLE_JS_API) && !defined(STATIC_JS_API) && defined(XP_WIN) @@ -6701,27 +6689,16 @@ JS_CallOnce(JSCallOnceType *once, JSInitCallback func) namespace JS { AutoGCRooter::AutoGCRooter(JSContext *cx, ptrdiff_t tag) - : down(cx->autoGCRooters), tag(tag), context(cx) + : down(cx->runtime->autoGCRooters), tag(tag), stackTop(&cx->runtime->autoGCRooters) { - JS_ASSERT(this != cx->autoGCRooters); - CHECK_REQUEST(cx); - cx->autoGCRooters = this; -} - -AutoGCRooter::~AutoGCRooter() -{ - JS_ASSERT(this == context->autoGCRooters); - CHECK_REQUEST(context); - context->autoGCRooters = down; + JS_ASSERT(this != *stackTop); + *stackTop = this; } AutoEnumStateRooter::~AutoEnumStateRooter() { - if (!stateValue.isNull()) { - DebugOnly ok = - obj->enumerate(context, JSENUMERATE_DESTROY, &stateValue, 0); - JS_ASSERT(ok); - } + if (!stateValue.isNull()) + MOZ_ALWAYS_TRUE(obj->enumerate(context, JSENUMERATE_DESTROY, &stateValue, 0)); } } // namespace JS diff --git a/js/src/jsapi.h b/js/src/jsapi.h index 4cb69f9e7dd..2f64bd96267 100644 --- a/js/src/jsapi.h +++ b/js/src/jsapi.h @@ -823,11 +823,15 @@ class JS_PUBLIC_API(AutoCheckRequestDepth) class JS_PUBLIC_API(AutoGCRooter) { public: AutoGCRooter(JSContext *cx, ptrdiff_t tag); - ~AutoGCRooter(); + + ~AutoGCRooter() { + JS_ASSERT(this == *stackTop); + *stackTop = down; + } /* Implemented in jsgc.cpp. */ inline void trace(JSTracer *trc); - void traceAll(JSTracer *trc); + static void traceAll(JSTracer *trc); protected: AutoGCRooter * const down; @@ -841,8 +845,6 @@ class JS_PUBLIC_API(AutoGCRooter) { */ ptrdiff_t tag; - JSContext * const context; - enum { JSVAL = -1, /* js::AutoValueRooter */ VALARRAY = -2, /* js::AutoValueArrayRooter */ @@ -863,6 +865,8 @@ class JS_PUBLIC_API(AutoGCRooter) { }; private: + AutoGCRooter ** const stackTop; + /* No copy or assignment semantics. */ AutoGCRooter(AutoGCRooter &ida) MOZ_DELETE; void operator=(AutoGCRooter &ida) MOZ_DELETE; @@ -1013,7 +1017,7 @@ class AutoEnumStateRooter : private AutoGCRooter public: AutoEnumStateRooter(JSContext *cx, JSObject *obj JS_GUARD_OBJECT_NOTIFIER_PARAM) - : AutoGCRooter(cx, ENUMERATOR), obj(obj), stateValue() + : AutoGCRooter(cx, ENUMERATOR), obj(obj), stateValue(), context(cx) { JS_GUARD_OBJECT_NOTIFIER_INIT; JS_ASSERT(obj); @@ -1033,6 +1037,7 @@ class AutoEnumStateRooter : private AutoGCRooter private: Value stateValue; + JSContext *context; JS_DECL_USE_GUARD_OBJECT_NOTIFIER }; @@ -2490,9 +2495,6 @@ JS_GetRuntime(JSContext *cx); extern JS_PUBLIC_API(JSContext *) JS_ContextIterator(JSRuntime *rt, JSContext **iterp); -extern JS_PUBLIC_API(JSContext *) -JS_ContextIteratorUnlocked(JSRuntime *rt, JSContext **iterp); - extern JS_PUBLIC_API(JSVersion) JS_GetVersion(JSContext *cx); @@ -2607,11 +2609,11 @@ JS_EnterCrossCompartmentCall(JSContext *cx, JSObject *target); extern JS_PUBLIC_API(void) JS_LeaveCrossCompartmentCall(JSCrossCompartmentCall *call); -extern JS_PUBLIC_API(void *) -JS_SetCompartmentPrivate(JSContext *cx, JSCompartment *compartment, void *data); +extern JS_PUBLIC_API(void) +JS_SetCompartmentPrivate(JSCompartment *compartment, void *data); extern JS_PUBLIC_API(void *) -JS_GetCompartmentPrivate(JSContext *cx, JSCompartment *compartment); +JS_GetCompartmentPrivate(JSCompartment *compartment); extern JS_PUBLIC_API(JSBool) JS_WrapObject(JSContext *cx, JSObject **objp); @@ -2636,9 +2638,6 @@ js_TransplantObjectWithWrapper(JSContext *cx, JSObject *targetobj, JSObject *targetwrapper); -extern JS_FRIEND_API(void *) -js_GetCompartmentPrivate(JSCompartment *compartment); - #ifdef __cplusplus JS_END_EXTERN_C @@ -3508,7 +3507,7 @@ namespace JS { class AutoIdArray : private AutoGCRooter { public: AutoIdArray(JSContext *cx, JSIdArray *ida JS_GUARD_OBJECT_NOTIFIER_PARAM) - : AutoGCRooter(cx, IDARRAY), idArray(ida) + : AutoGCRooter(cx, IDARRAY), context(cx), idArray(ida) { JS_GUARD_OBJECT_NOTIFIER_INIT; } @@ -3540,6 +3539,7 @@ class AutoIdArray : private AutoGCRooter { inline void trace(JSTracer *trc); private: + JSContext *context; JSIdArray *idArray; JS_DECL_USE_GUARD_OBJECT_NOTIFIER diff --git a/js/src/jscntxt.cpp b/js/src/jscntxt.cpp index ede93d4eb5d..3750b1eb4f6 100644 --- a/js/src/jscntxt.cpp +++ b/js/src/jscntxt.cpp @@ -173,11 +173,6 @@ js_NewContext(JSRuntime *rt, size_t stackChunkSize) { JS_AbortIfWrongThread(rt); - /* - * We need to initialize the new context fully before adding it to the - * runtime list. After that it can be accessed from another thread via - * js_ContextIterator. - */ JSContext *cx = OffTheBooks::new_(rt); if (!cx) return NULL; @@ -301,21 +296,6 @@ js_DestroyContext(JSContext *cx, JSDestroyContextMode mode) Foreground::delete_(cx); } -JSContext * -js_ContextIterator(JSRuntime *rt, JSBool unlocked, JSContext **iterp) -{ - JSContext *cx = *iterp; - - Maybe lockIf; - if (unlocked) - lockIf.construct(rt); - cx = JSContext::fromLinkField(cx ? cx->link.next : rt->contextList.next); - if (&cx->link == &rt->contextList) - cx = NULL; - *iterp = cx; - return cx; -} - namespace js { bool @@ -978,7 +958,6 @@ JSContext::JSContext(JSRuntime *rt) #ifdef JS_THREADSAFE outstandingRequests(0), #endif - autoGCRooters(NULL), securityCallbacks(NULL), resolveFlags(0), rngSeed(0), @@ -1000,9 +979,6 @@ JSContext::JSContext(JSRuntime *rt) #endif { PodZero(&link); -#ifdef JS_THREADSAFE - PodZero(&threadLinks); -#endif #ifdef JSGC_ROOT_ANALYSIS PodArrayZero(thingGCRooters); #ifdef DEBUG @@ -1154,16 +1130,6 @@ JSRuntime::onOutOfMemory(void *p, size_t nbytes, JSContext *cx) return NULL; } -void -JSRuntime::purge(JSContext *cx) -{ - tempLifoAlloc.freeUnused(); - gsnCache.purge(); - - /* FIXME: bug 506341 */ - propertyCache.purge(cx); -} - void JSContext::purge() { @@ -1279,9 +1245,6 @@ JSContext::mark(JSTracer *trc) if (isExceptionPending()) MarkValueRoot(trc, &exception, "exception"); - if (autoGCRooters) - autoGCRooters->traceAll(trc); - if (sharpObjectMap.depth > 0) js_TraceSharpMap(trc, &sharpObjectMap); diff --git a/js/src/jscntxt.h b/js/src/jscntxt.h index 2db5a2a66ee..2bd18f7d47e 100644 --- a/js/src/jscntxt.h +++ b/js/src/jscntxt.h @@ -457,6 +457,9 @@ struct JSRuntime : js::RuntimeFriendFields JSTraceDataOp gcGrayRootsTraceOp; void *gcGrayRootsData; + /* Stack of thread-stack-allocated GC roots. */ + js::AutoGCRooter *autoGCRooters; + /* Strong references on scripts held for PCCount profiling API. */ js::ScriptOpcodeCountsVector *scriptPCCounters; @@ -690,8 +693,6 @@ struct JSRuntime : js::RuntimeFriendFields void sizeOfExcludingThis(JSMallocSizeOfFun mallocSizeOf, size_t *normal, size_t *temporary, size_t *regexpCode, size_t *stackCommitted, size_t *gcMarker); - - void purge(JSContext *cx); }; /* Common macros to access thread-local caches in JSRuntime. */ @@ -985,11 +986,8 @@ struct JSContext : js::ContextFriendFields unsigned outstandingRequests;/* number of JS_BeginRequest calls without the corresponding JS_EndRequest. */ - JSCList threadLinks; /* JSThread contextList linkage */ #endif - /* Stack of thread-stack-allocated GC roots. */ - js::AutoGCRooter *autoGCRooters; #ifdef JSGC_ROOT_ANALYSIS @@ -1349,25 +1347,39 @@ class JSAutoResolveFlags namespace js { /* - * Enumerate all contexts in a runtime that are in the same thread as a given - * context. + * Enumerate all contexts in a runtime. */ -class ThreadContextRange { +class ContextIter { JSCList *begin; JSCList *end; public: - explicit ThreadContextRange(JSContext *cx) { - end = &cx->runtime->contextList; + explicit ContextIter(JSRuntime *rt) { + end = &rt->contextList; begin = end->next; } - bool empty() const { return begin == end; } - void popFront() { JS_ASSERT(!empty()); begin = begin->next; } + bool done() const { + return begin == end; + } - JSContext *front() const { + void next() { + JS_ASSERT(!done()); + begin = begin->next; + } + + JSContext *get() const { + JS_ASSERT(!done()); return JSContext::fromLinkField(begin); } + + operator JSContext *() const { + return get(); + } + + JSContext *operator ->() const { + return get(); + } }; } /* namespace js */ @@ -1389,13 +1401,6 @@ typedef enum JSDestroyContextMode { extern void js_DestroyContext(JSContext *cx, JSDestroyContextMode mode); -/* - * If unlocked, acquire and release rt->gcLock around *iterp update; otherwise - * the caller must be holding rt->gcLock. - */ -extern JSContext * -js_ContextIterator(JSRuntime *rt, JSBool unlocked, JSContext **iterp); - #ifdef va_start extern JSBool js_ReportErrorVA(JSContext *cx, unsigned flags, const char *format, va_list ap); diff --git a/js/src/jscntxtinlines.h b/js/src/jscntxtinlines.h index a7c92ab1374..4a9d260e1b9 100644 --- a/js/src/jscntxtinlines.h +++ b/js/src/jscntxtinlines.h @@ -92,7 +92,8 @@ GetGSNCache(JSContext *cx) class AutoNamespaceArray : protected AutoGCRooter { public: - AutoNamespaceArray(JSContext *cx) : AutoGCRooter(cx, NAMESPACES) { + AutoNamespaceArray(JSContext *cx) + : AutoGCRooter(cx, NAMESPACES), context(cx) { array.init(); } @@ -102,9 +103,11 @@ class AutoNamespaceArray : protected AutoGCRooter { uint32_t length() const { return array.length; } - public: + private: + JSContext *context; friend void AutoGCRooter::trace(JSTracer *trc); + public: JSXMLArray array; }; diff --git a/js/src/jscompartment.cpp b/js/src/jscompartment.cpp index 3a93c06c70f..1541e74df2d 100644 --- a/js/src/jscompartment.cpp +++ b/js/src/jscompartment.cpp @@ -569,7 +569,7 @@ JSCompartment::sweep(JSContext *cx, bool releaseTypes) } void -JSCompartment::purge(JSContext *cx) +JSCompartment::purge() { dtoaCache.purge(); @@ -627,9 +627,9 @@ JSCompartment::allocMathCache(JSContext *cx) } bool -JSCompartment::hasScriptsOnStack(JSContext *cx) +JSCompartment::hasScriptsOnStack() { - for (AllFramesIter i(cx->stack.space()); !i.done(); ++i) { + for (AllFramesIter i(rt->stackSpace); !i.done(); ++i) { JSScript *script = i.fp()->maybeScript(); if (script && script->compartment() == this) return true; @@ -655,7 +655,7 @@ JSCompartment::setDebugModeFromC(JSContext *cx, bool b) // bool onStack = false; if (enabledBefore != enabledAfter) { - onStack = hasScriptsOnStack(cx); + onStack = hasScriptsOnStack(); if (b && onStack) { JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_DEBUG_NOT_IDLE); return false; @@ -672,18 +672,17 @@ JSCompartment::setDebugModeFromC(JSContext *cx, bool b) void JSCompartment::updateForDebugMode(JSContext *cx) { - for (ThreadContextRange r(cx); !r.empty(); r.popFront()) { - JSContext *cx = r.front(); - if (cx->compartment == this) - cx->updateJITEnabled(); + for (ContextIter acx(rt); !acx.done(); acx.next()) { + if (acx->compartment == this) + acx->updateJITEnabled(); } #ifdef JS_METHODJIT bool enabled = debugMode(); if (enabled) { - JS_ASSERT(!hasScriptsOnStack(cx)); - } else if (hasScriptsOnStack(cx)) { + JS_ASSERT(!hasScriptsOnStack()); + } else if (hasScriptsOnStack()) { hasDebugModeCodeToDrop = true; return; } diff --git a/js/src/jscompartment.h b/js/src/jscompartment.h index 4ab3e88d922..61ce6db8ef3 100644 --- a/js/src/jscompartment.h +++ b/js/src/jscompartment.h @@ -341,7 +341,7 @@ struct JSCompartment void markTypes(JSTracer *trc); void discardJitCode(JSContext *cx); void sweep(JSContext *cx, bool releaseTypes); - void purge(JSContext *cx); + void purge(); void setGCLastBytes(size_t lastBytes, js::JSGCInvocationKind gckind); void reduceGCTriggerBytes(size_t amount); @@ -388,12 +388,8 @@ struct JSCompartment */ bool debugMode() const { return !!debugModeBits; } - /* - * True if any scripts from this compartment are on the JS stack in the - * calling thread. cx is a context in the calling thread, and it is assumed - * that no other thread is using this compartment. - */ - bool hasScriptsOnStack(JSContext *cx); + /* True if any scripts from this compartment are on the JS stack. */ + bool hasScriptsOnStack(); private: /* This is called only when debugMode() has just toggled. */ diff --git a/js/src/jsfriendapi.cpp b/js/src/jsfriendapi.cpp index 6f0c04e77aa..0fbe6b1162f 100644 --- a/js/src/jsfriendapi.cpp +++ b/js/src/jsfriendapi.cpp @@ -222,9 +222,9 @@ js::IsSystemCompartment(const JSCompartment *c) } JS_FRIEND_API(bool) -js::IsAtomsCompartmentFor(const JSContext *cx, const JSCompartment *c) +js::IsAtomsCompartment(const JSCompartment *c) { - return c == cx->runtime->atomsCompartment; + return c == c->rt->atomsCompartment; } JS_FRIEND_API(bool) diff --git a/js/src/jsfriendapi.h b/js/src/jsfriendapi.h index 94ae774cd50..8706bcc275f 100644 --- a/js/src/jsfriendapi.h +++ b/js/src/jsfriendapi.h @@ -255,7 +255,7 @@ extern JS_FRIEND_API(bool) IsSystemCompartment(const JSCompartment *compartment); extern JS_FRIEND_API(bool) -IsAtomsCompartmentFor(const JSContext *cx, const JSCompartment *c); +IsAtomsCompartment(const JSCompartment *c); /* * Check whether it is OK to assign an undeclared property with name diff --git a/js/src/jsgc.cpp b/js/src/jsgc.cpp index 2d6f915f308..d09ede283ba 100644 --- a/js/src/jsgc.cpp +++ b/js/src/jsgc.cpp @@ -1227,15 +1227,15 @@ ConservativeGCData::recordStackTop() #endif } -void -RecordNativeStackTopForGC(JSContext *cx) +static void +RecordNativeStackTopForGC(JSRuntime *rt) { - ConservativeGCData *cgcd = &cx->runtime->conservativeGC; + ConservativeGCData *cgcd = &rt->conservativeGC; #ifdef JS_THREADSAFE /* Record the stack top here only if we are called from a request. */ - JS_ASSERT(cx->runtime->requestDepth >= cgcd->requestThreshold); - if (cx->runtime->requestDepth == cgcd->requestThreshold) + JS_ASSERT(rt->requestDepth >= cgcd->requestThreshold); + if (rt->requestDepth == cgcd->requestThreshold) return; #endif cgcd->recordStackTop(); @@ -2330,10 +2330,10 @@ AutoGCRooter::trace(JSTracer *trc) "JS::AutoArrayRooter.array"); } -void +/* static */ void AutoGCRooter::traceAll(JSTracer *trc) { - for (js::AutoGCRooter *gcr = this; gcr; gcr = gcr->down) + for (js::AutoGCRooter *gcr = trc->runtime->autoGCRooters; gcr; gcr = gcr->down) gcr->trace(trc); } @@ -2350,6 +2350,8 @@ MarkRuntime(JSTracer *trc, bool useSavedRoots = false) Debugger::markCrossCompartmentDebuggerObjectReferents(trc); } + AutoGCRooter::traceAll(trc); + if (rt->hasContexts()) MarkConservativeStackRoots(trc, useSavedRoots); @@ -2368,8 +2370,7 @@ MarkRuntime(JSTracer *trc, bool useSavedRoots = false) js_TraceAtomState(trc); rt->staticStrings.trace(trc); - JSContext *iter = NULL; - while (JSContext *acx = js_ContextIterator(rt, JS_TRUE, &iter)) + for (ContextIter acx(rt); !acx.done(); acx.next()) acx->mark(trc); for (GCCompartmentsIter c(rt); !c.done(); c.next()) { @@ -2903,10 +2904,8 @@ GCHelperThread::doSweep() } /* namespace js */ static bool -ReleaseObservedTypes(JSContext *cx) +ReleaseObservedTypes(JSRuntime *rt) { - JSRuntime *rt = cx->runtime; - bool releaseTypes = false; int64_t now = PRMJ_Now(); if (now >= rt->gcJitReleaseTime) { @@ -2950,26 +2949,24 @@ SweepCompartments(JSContext *cx, JSGCInvocationKind gckind) } static void -PurgeRuntime(JSContext *cx) +PurgeRuntime(JSRuntime *rt) { - JSRuntime *rt = cx->runtime; - for (GCCompartmentsIter c(rt); !c.done(); c.next()) - c->purge(cx); + c->purge(); - rt->purge(cx); + rt->tempLifoAlloc.freeUnused(); + rt->gsnCache.purge(); - { - JSContext *iter = NULL; - while (JSContext *acx = js_ContextIterator(rt, JS_TRUE, &iter)) - acx->purge(); - } + /* FIXME: bug 506341 */ + rt->propertyCache.purge(rt); + + for (ContextIter acx(rt); !acx.done(); acx.next()) + acx->purge(); } static void -BeginMarkPhase(JSContext *cx) +BeginMarkPhase(JSRuntime *rt) { - JSRuntime *rt = cx->runtime; GCMarker *gcmarker = &rt->gcMarker; rt->gcStartNumber = rt->gcNumber; @@ -2986,7 +2983,7 @@ BeginMarkPhase(JSContext *cx) * to the object and start using it. This object might never be marked, so * a GC hazard would exist. */ - PurgeRuntime(cx); + PurgeRuntime(rt); /* * Mark phase. @@ -3015,9 +3012,8 @@ MarkWeakReferences(GCMarker *gcmarker) } static void -MarkGrayAndWeak(JSContext *cx) +MarkGrayAndWeak(JSRuntime *rt) { - JSRuntime *rt = cx->runtime; FullGCMarker *gcmarker = &rt->gcMarker; JS_ASSERT(gcmarker->isDrained()); @@ -3049,7 +3045,7 @@ EndMarkPhase(JSContext *cx) { gcstats::AutoPhase ap1(rt->gcStats, gcstats::PHASE_MARK); gcstats::AutoPhase ap2(rt->gcStats, gcstats::PHASE_MARK_OTHER); - MarkGrayAndWeak(cx); + MarkGrayAndWeak(rt); } JS_ASSERT(rt->gcMarker.isDrained()); @@ -3123,7 +3119,7 @@ ValidateIncrementalMarking(JSContext *cx) MarkRuntime(gcmarker, true); SliceBudget budget; rt->gcMarker.drainMarkStack(budget); - MarkGrayAndWeak(cx); + MarkGrayAndWeak(rt); /* Now verify that we have the same mark bits as before. */ for (GCChunkSet::Range r(rt->gcChunkSet.all()); !r.empty(); r.popFront()) { @@ -3210,7 +3206,7 @@ SweepPhase(JSContext *cx, JSGCInvocationKind gckind) if (!rt->gcCurrentCompartment) Debugger::sweepAll(cx); - bool releaseTypes = !rt->gcCurrentCompartment && ReleaseObservedTypes(cx); + bool releaseTypes = !rt->gcCurrentCompartment && ReleaseObservedTypes(rt); for (GCCompartmentsIter c(rt); !c.done(); c.next()) c->sweep(cx, releaseTypes); @@ -3297,7 +3293,7 @@ MarkAndSweep(JSContext *cx, JSGCInvocationKind gckind) rt->gcMarker.start(rt, cx); JS_ASSERT(!rt->gcMarker.callback); - BeginMarkPhase(cx); + BeginMarkPhase(rt); { gcstats::AutoPhase ap(rt->gcStats, gcstats::PHASE_MARK); SliceBudget budget; @@ -3315,11 +3311,11 @@ MarkAndSweep(JSContext *cx, JSGCInvocationKind gckind) */ class AutoHeapSession { public: - explicit AutoHeapSession(JSContext *cx); + explicit AutoHeapSession(JSRuntime *rt); ~AutoHeapSession(); protected: - JSContext *context; + JSRuntime *runtime; private: AutoHeapSession(const AutoHeapSession&) MOZ_DELETE; @@ -3341,50 +3337,45 @@ class AutoGCSession : AutoHeapSession { }; /* Start a new heap session. */ -AutoHeapSession::AutoHeapSession(JSContext *cx) - : context(cx) +AutoHeapSession::AutoHeapSession(JSRuntime *rt) + : runtime(rt) { - JS_ASSERT(!cx->runtime->noGCOrAllocationCheck); - JSRuntime *rt = cx->runtime; + JS_ASSERT(!rt->noGCOrAllocationCheck); JS_ASSERT(!rt->gcRunning); rt->gcRunning = true; } AutoHeapSession::~AutoHeapSession() { - JSRuntime *rt = context->runtime; - rt->gcRunning = false; + JS_ASSERT(runtime->gcRunning); + runtime->gcRunning = false; } AutoGCSession::AutoGCSession(JSContext *cx, JSCompartment *comp) - : AutoHeapSession(cx), + : AutoHeapSession(cx->runtime), switcher(cx, (JSCompartment *)NULL) { - JSRuntime *rt = cx->runtime; + JS_ASSERT(!runtime->gcCurrentCompartment); + runtime->gcCurrentCompartment = comp; - JS_ASSERT(!rt->gcCurrentCompartment); - rt->gcCurrentCompartment = comp; + runtime->gcIsNeeded = false; + runtime->gcTriggerCompartment = NULL; + runtime->gcInterFrameGC = true; - rt->gcIsNeeded = false; - rt->gcTriggerCompartment = NULL; - rt->gcInterFrameGC = true; + runtime->gcNumber++; - rt->gcNumber++; - - rt->resetGCMallocBytes(); + runtime->resetGCMallocBytes(); /* Clear gcMallocBytes for all compartments */ - for (CompartmentsIter c(rt); !c.done(); c.next()) + for (CompartmentsIter c(runtime); !c.done(); c.next()) c->resetGCMallocBytes(); } AutoGCSession::~AutoGCSession() { - JSRuntime *rt = context->runtime; - - rt->gcCurrentCompartment = NULL; - rt->gcNextFullGCTime = PRMJ_Now() + GC_IDLE_FULL_SPAN; - rt->gcChunkAllocationSinceLastGC = false; + runtime->gcCurrentCompartment = NULL; + runtime->gcNextFullGCTime = PRMJ_Now() + GC_IDLE_FULL_SPAN; + runtime->gcChunkAllocationSinceLastGC = false; } static void @@ -3501,7 +3492,7 @@ IncrementalGCSlice(JSContext *cx, int64_t budget, JSGCInvocationKind gckind) c->barrierMarker_.start(rt, NULL); } - BeginMarkPhase(cx); + BeginMarkPhase(rt); rt->gcIncrementalState = MARK; } @@ -3553,10 +3544,8 @@ IncrementalGCSlice(JSContext *cx, int64_t budget, JSGCInvocationKind gckind) } static bool -IsIncrementalGCSafe(JSContext *cx) +IsIncrementalGCSafe(JSRuntime *rt) { - JSRuntime *rt = cx->runtime; - if (rt->gcCompartmentCreated) { rt->gcCompartmentCreated = false; return false; @@ -3583,10 +3572,8 @@ IsIncrementalGCSafe(JSContext *cx) } static bool -IsIncrementalGCAllowed(JSContext *cx) +IsIncrementalGCAllowed(JSRuntime *rt) { - JSRuntime *rt = cx->runtime; - if (rt->gcMode != JSGC_MODE_INCREMENTAL) return false; @@ -3595,7 +3582,7 @@ IsIncrementalGCAllowed(JSContext *cx) return false; #endif - if (!IsIncrementalGCSafe(cx)) + if (!IsIncrementalGCSafe(rt)) return false; for (CompartmentsIter c(rt); !c.done(); c.next()) { @@ -3642,7 +3629,7 @@ GCCycle(JSContext *cx, JSCompartment *comp, int64_t budget, JSGCInvocationKind g #endif if (budget != SliceBudget::Unlimited) { - if (!IsIncrementalGCAllowed(cx)) + if (!IsIncrementalGCAllowed(rt)) budget = SliceBudget::Unlimited; } @@ -3693,7 +3680,7 @@ Collect(JSContext *cx, JSCompartment *comp, int64_t budget, } av(cx); #endif - RecordNativeStackTopForGC(cx); + RecordNativeStackTopForGC(rt); /* This is a heuristic to avoid resets. */ if (rt->gcIncrementalState != NO_INCREMENTAL && !rt->gcIncrementalCompartment) @@ -3771,24 +3758,23 @@ TraceRuntime(JSTracer *trc) #ifdef JS_THREADSAFE { - JSContext *cx = trc->context; - JSRuntime *rt = cx->runtime; + JSRuntime *rt = trc->runtime; if (!rt->gcRunning) { AutoLockGC lock(rt); - AutoHeapSession session(cx); + AutoHeapSession session(rt); rt->gcHelperThread.waitBackgroundSweepEnd(); AutoUnlockGC unlock(rt); AutoCopyFreeListToArenas copy(rt); - RecordNativeStackTopForGC(trc->context); + RecordNativeStackTopForGC(rt); MarkRuntime(trc); return; } } #else AutoCopyFreeListToArenas copy(trc->runtime); - RecordNativeStackTopForGC(trc->context); + RecordNativeStackTopForGC(trc->runtime); #endif /* @@ -3838,7 +3824,7 @@ IterateCompartmentsArenasCells(JSContext *cx, void *data, JS_ASSERT(!rt->gcRunning); AutoLockGC lock(rt); - AutoHeapSession session(cx); + AutoHeapSession session(rt); #ifdef JS_THREADSAFE rt->gcHelperThread.waitBackgroundSweepEnd(); #endif @@ -3868,7 +3854,7 @@ IterateChunks(JSContext *cx, void *data, IterateChunkCallback chunkCallback) JS_ASSERT(!rt->gcRunning); AutoLockGC lock(rt); - AutoHeapSession session(cx); + AutoHeapSession session(rt); #ifdef JS_THREADSAFE rt->gcHelperThread.waitBackgroundSweepEnd(); #endif @@ -3889,7 +3875,7 @@ IterateCells(JSContext *cx, JSCompartment *compartment, AllocKind thingKind, JS_ASSERT(!rt->gcRunning); AutoLockGC lock(rt); - AutoHeapSession session(cx); + AutoHeapSession session(rt); #ifdef JS_THREADSAFE rt->gcHelperThread.waitBackgroundSweepEnd(); #endif @@ -3998,22 +3984,20 @@ CheckStackRoot(JSTracer *trc, uintptr_t *w) JSContext *iter = NULL; bool matched = false; JSRuntime *rt = trc->runtime; - while (JSContext *acx = js_ContextIterator(rt, JS_TRUE, &iter)) { - for (unsigned i = 0; i < THING_ROOT_COUNT; i++) { - Root *rooter = acx->thingGCRooters[i]; - while (rooter) { - if (rooter->address() == (Cell **) w) - matched = true; - rooter = rooter->previous(); - } - } - CheckRoot *check = acx->checkGCRooters; - while (check) { - if (check->contains(static_cast(w), sizeof(w))) + for (unsigned i = 0; i < THING_ROOT_COUNT; i++) { + Root *rooter = rt->thingGCRooters[i]; + while (rooter) { + if (rooter->address() == (Cell **) w) matched = true; - check = check->previous(); + rooter = rooter->previous(); } } + CheckRoot *check = rt->checkGCRooters; + while (check) { + if (check->contains(static_cast(w), sizeof(w))) + matched = true; + check = check->previous(); + } if (!matched) { /* * Only poison the last byte in the word. It is easy to get @@ -4199,9 +4183,9 @@ StartVerifyBarriers(JSContext *cx) return; AutoLockGC lock(rt); - AutoHeapSession session(cx); + AutoHeapSession session(rt); - if (!IsIncrementalGCSafe(cx)) + if (!IsIncrementalGCSafe(rt)) return; #ifdef JS_THREADSAFE @@ -4211,7 +4195,7 @@ StartVerifyBarriers(JSContext *cx) AutoUnlockGC unlock(rt); AutoCopyFreeListToArenas copy(rt); - RecordNativeStackTopForGC(cx); + RecordNativeStackTopForGC(rt); for (GCChunkSet::Range r(rt->gcChunkSet.all()); !r.empty(); r.popFront()) r.front()->bitmap.clear(); @@ -4219,7 +4203,7 @@ StartVerifyBarriers(JSContext *cx) for (CompartmentsIter c(rt); !c.done(); c.next()) c->discardJitCode(cx); - PurgeRuntime(cx); + PurgeRuntime(rt); VerifyTracer *trc = new (js_malloc(sizeof(VerifyTracer))) VerifyTracer(cx); @@ -4343,7 +4327,7 @@ EndVerifyBarriers(JSContext *cx) JSRuntime *rt = cx->runtime; AutoLockGC lock(rt); - AutoHeapSession session(cx); + AutoHeapSession session(rt); #ifdef JS_THREADSAFE rt->gcHelperThread.waitBackgroundSweepOrAllocEnd(); @@ -4352,7 +4336,7 @@ EndVerifyBarriers(JSContext *cx) AutoUnlockGC unlock(rt); AutoCopyFreeListToArenas copy(rt); - RecordNativeStackTopForGC(cx); + RecordNativeStackTopForGC(rt); VerifyTracer *trc = (VerifyTracer *)rt->gcVerifyData; @@ -4378,13 +4362,9 @@ EndVerifyBarriers(JSContext *cx) JS_TracerInit(trc, cx, MarkFromAutorooter); - JSContext *iter = NULL; - while (JSContext *acx = js_ContextIterator(rt, JS_TRUE, &iter)) { - if (acx->autoGCRooters) - acx->autoGCRooters->traceAll(trc); - } + AutoGCRooter::traceAll(trc); - if (IsIncrementalGCSafe(cx)) { + if (IsIncrementalGCSafe(rt)) { /* * Verify that all the current roots were reachable previously, or else * are marked. @@ -4588,7 +4568,7 @@ JS_IterateCompartments(JSContext *cx, void *data, JS_ASSERT(!rt->gcRunning); AutoLockGC lock(rt); - AutoHeapSession session(cx); + AutoHeapSession session(rt); for (CompartmentsIter c(rt); !c.done(); c.next()) (*compartmentCallback)(cx, data, c); diff --git a/js/src/jsinfer.cpp b/js/src/jsinfer.cpp index e7b5e19bdc8..7f74261571c 100644 --- a/js/src/jsinfer.cpp +++ b/js/src/jsinfer.cpp @@ -2193,12 +2193,8 @@ TypeCompartment::nukeTypes(JSContext *cx) inferenceEnabled = false; /* Update the cached inferenceEnabled bit in all contexts. */ - for (JSCList *cl = cx->runtime->contextList.next; - cl != &cx->runtime->contextList; - cl = cl->next) { - JSContext *cx = JSContext::fromLinkField(cl); - cx->setCompartment(cx->compartment); - } + for (ContextIter acx(cx->runtime); !acx.done(); acx.next()) + acx->setCompartment(acx->compartment); #ifdef JS_METHODJIT diff --git a/js/src/jspropertycache.cpp b/js/src/jspropertycache.cpp index 057d5ea5c2d..ead3f86f18b 100644 --- a/js/src/jspropertycache.cpp +++ b/js/src/jspropertycache.cpp @@ -263,7 +263,7 @@ PropertyCache::assertEmpty() #endif void -PropertyCache::purge(JSContext *cx) +PropertyCache::purge(JSRuntime *rt) { if (empty) { assertEmpty(); @@ -279,10 +279,7 @@ PropertyCache::purge(JSContext *cx) fp = fopen("/tmp/propcache.stats", "w"); if (fp) { fputs("Property cache stats for ", fp); -#ifdef JS_THREADSAFE - fprintf(fp, "thread %lu, ", (unsigned long) cx->thread->id); -#endif - fprintf(fp, "GC %lu\n", (unsigned long)cx->runtime->gcNumber); + fprintf(fp, "GC %lu\n", (unsigned long)rt->gcNumber); # define P(mem) fprintf(fp, "%11s %10lu\n", #mem, (unsigned long)mem) P(fills); diff --git a/js/src/jspropertycache.h b/js/src/jspropertycache.h index ee8383e92a3..89b5023d063 100644 --- a/js/src/jspropertycache.h +++ b/js/src/jspropertycache.h @@ -219,7 +219,7 @@ class PropertyCache PropertyCacheEntry *fill(JSContext *cx, JSObject *obj, unsigned scopeIndex, JSObject *pobj, const js::Shape *shape); - void purge(JSContext *cx); + void purge(JSRuntime *rt); /* Restore an entry that may have been purged during a GC. */ void restore(PropertyCacheEntry *entry); diff --git a/js/src/vm/Debugger.cpp b/js/src/vm/Debugger.cpp index e892d2d3d47..b4b682f3a37 100644 --- a/js/src/vm/Debugger.cpp +++ b/js/src/vm/Debugger.cpp @@ -1722,7 +1722,7 @@ Debugger::addDebuggeeGlobal(JSContext *cx, GlobalObject *global) } /* Refuse to enable debug mode for a compartment that has running scripts. */ - if (!debuggeeCompartment->debugMode() && debuggeeCompartment->hasScriptsOnStack(cx)) { + if (!debuggeeCompartment->debugMode() && debuggeeCompartment->hasScriptsOnStack()) { JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_DEBUG_NOT_IDLE); return false; } diff --git a/js/src/vm/Stack.h b/js/src/vm/Stack.h index cfe1a866851..ccc1eb6de4c 100644 --- a/js/src/vm/Stack.h +++ b/js/src/vm/Stack.h @@ -1558,7 +1558,7 @@ class StackSpace class ContextStack { StackSegment *seg_; - StackSpace *space_; + StackSpace *const space_; JSContext *cx_; /* diff --git a/js/xpconnect/src/XPCComponents.cpp b/js/xpconnect/src/XPCComponents.cpp index 8c172c0e348..c3e884934c5 100644 --- a/js/xpconnect/src/XPCComponents.cpp +++ b/js/xpconnect/src/XPCComponents.cpp @@ -3053,7 +3053,7 @@ xpc_CreateSandboxObject(JSContext * cx, jsval * vp, nsISupports *prinOrSop, JSOb } xpc::CompartmentPrivate *compartmentPrivate = - static_cast(JS_GetCompartmentPrivate(cx, compartment)); + static_cast(JS_GetCompartmentPrivate(compartment)); compartmentPrivate->location = sandboxName; return NS_OK; @@ -3235,7 +3235,7 @@ nsXPCComponents_utils_Sandbox::CallOrConstruct(nsIXPConnectWrappedNative *wrappe return ThrowAndFail(NS_ERROR_INVALID_ARG, cx, _retval); void* privateValue = - JS_GetCompartmentPrivate(cx, GetObjectCompartment(unwrapped)); + JS_GetCompartmentPrivate(GetObjectCompartment(unwrapped)); xpc::CompartmentPrivate *compartmentPrivate = static_cast(privateValue); @@ -3556,7 +3556,7 @@ xpc_EvalInSandbox(JSContext *cx, JSObject *sandbox, const nsAString& source, xpc::CompartmentPrivate *sandboxdata = static_cast - (JS_GetCompartmentPrivate(cx, js::GetObjectCompartment(sandbox))); + (JS_GetCompartmentPrivate(js::GetObjectCompartment(sandbox))); if (!ac.enter(cx, callingScope) || !WrapForSandbox(cx, sandboxdata->wantXrays, &v)) { rv = NS_ERROR_FAILURE; diff --git a/js/xpconnect/src/XPCJSRuntime.cpp b/js/xpconnect/src/XPCJSRuntime.cpp index 04942011414..06116f90bc2 100644 --- a/js/xpconnect/src/XPCJSRuntime.cpp +++ b/js/xpconnect/src/XPCJSRuntime.cpp @@ -257,10 +257,13 @@ CompartmentCallback(JSContext *cx, JSCompartment *compartment, unsigned op) if (!self) return true; - nsAutoPtr priv(static_cast(JS_SetCompartmentPrivate(cx, compartment, nsnull))); + nsAutoPtr + priv(static_cast(JS_GetCompartmentPrivate(compartment))); if (!priv) return true; + JS_SetCompartmentPrivate(compartment, nsnull); + xpc::PtrAndPrincipalHashKey *key = priv->key; XPCCompartmentMap &map = self->GetCompartmentMap(); #ifdef DEBUG @@ -400,8 +403,8 @@ TraceDOMExpandos(nsPtrHashKey *expando, void *aClosure) static PLDHashOperator TraceCompartment(xpc::PtrAndPrincipalHashKey *aKey, JSCompartment *compartment, void *aClosure) { - xpc::CompartmentPrivate *priv = (xpc::CompartmentPrivate *) - JS_GetCompartmentPrivate(static_cast(aClosure)->context, compartment); + xpc::CompartmentPrivate *priv = + static_cast(JS_GetCompartmentPrivate(compartment)); if (priv->expandoMap) priv->expandoMap->Enumerate(TraceExpandos, aClosure); if (priv->domExpandoMap) @@ -437,7 +440,6 @@ void XPCJSRuntime::TraceXPConnectRoots(JSTracer *trc) struct Closure { - JSContext *cx; bool cycleCollectionEnabled; nsCycleCollectionTraversalCallback *cb; }; @@ -473,7 +475,7 @@ NoteJSHolder(JSDHashTable *table, JSDHashEntryHdr *hdr, uint32_t number, // static void -XPCJSRuntime::SuspectWrappedNative(JSContext *cx, XPCWrappedNative *wrapper, +XPCJSRuntime::SuspectWrappedNative(XPCWrappedNative *wrapper, nsCycleCollectionTraversalCallback &cb) { if (!wrapper->IsValid() || wrapper->IsWrapperExpired()) @@ -494,7 +496,7 @@ static PLDHashOperator SuspectExpandos(XPCWrappedNative *wrapper, JSObject *expando, void *arg) { Closure* closure = static_cast(arg); - XPCJSRuntime::SuspectWrappedNative(closure->cx, wrapper, *closure->cb); + XPCJSRuntime::SuspectWrappedNative(wrapper, *closure->cb); return PL_DHASH_NEXT; } @@ -510,9 +512,8 @@ SuspectDOMExpandos(nsPtrHashKey *expando, void *arg) static PLDHashOperator SuspectCompartment(xpc::PtrAndPrincipalHashKey *key, JSCompartment *compartment, void *arg) { - Closure* closure = static_cast(arg); - xpc::CompartmentPrivate *priv = (xpc::CompartmentPrivate *) - JS_GetCompartmentPrivate(closure->cx, compartment); + xpc::CompartmentPrivate *priv = + static_cast(JS_GetCompartmentPrivate(compartment)); if (priv->expandoMap) priv->expandoMap->EnumerateRead(SuspectExpandos, arg); if (priv->domExpandoMap) @@ -521,8 +522,7 @@ SuspectCompartment(xpc::PtrAndPrincipalHashKey *key, JSCompartment *compartment, } void -XPCJSRuntime::AddXPConnectRoots(JSContext* cx, - nsCycleCollectionTraversalCallback &cb) +XPCJSRuntime::AddXPConnectRoots(nsCycleCollectionTraversalCallback &cb) { // For all JS objects that are held by native objects but aren't held // through rooting or locking, we need to add all the native objects that @@ -540,7 +540,7 @@ XPCJSRuntime::AddXPConnectRoots(JSContext* cx, XPCAutoLock lock(mMapLock); - XPCWrappedNativeScope::SuspectAllWrappers(this, cx, cb); + XPCWrappedNativeScope::SuspectAllWrappers(this, cb); for (XPCRootSetElem *e = mVariantRoots; e ; e = e->GetNextRoot()) { XPCTraceableVariant* v = static_cast(e); @@ -570,7 +570,7 @@ XPCJSRuntime::AddXPConnectRoots(JSContext* cx, cb.NoteXPCOMRoot(static_cast(wrappedJS)); } - Closure closure = { cx, true, &cb }; + Closure closure = { true, &cb }; if (mJSHolders.ops) { JS_DHashTableEnumerate(&mJSHolders, NoteJSHolder, &closure); } @@ -644,8 +644,9 @@ SweepExpandos(XPCWrappedNative *wn, JSObject *&expando, void *arg) static PLDHashOperator SweepCompartment(nsCStringHashKey& aKey, JSCompartment *compartment, void *aClosure) { - xpc::CompartmentPrivate *priv = (xpc::CompartmentPrivate *) - JS_GetCompartmentPrivate((JSContext *)aClosure, compartment); + MOZ_ASSERT(!aClosure); + xpc::CompartmentPrivate *priv = + static_cast(JS_GetCompartmentPrivate(compartment)); if (priv->waiverWrapperMap) priv->waiverWrapperMap->Enumerate(SweepWaiverWrappers, nsnull); if (priv->expandoMap) @@ -704,7 +705,7 @@ JSBool XPCJSRuntime::GCCallback(JSContext *cx, JSGCStatus status) // Sweep compartments. self->GetCompartmentMap().EnumerateRead((XPCCompartmentMap::EnumReadFunction) - SweepCompartment, cx); + SweepCompartment, nsnull); self->mDoingFinalization = true; break; @@ -1208,13 +1209,11 @@ XPCJSRuntime::~XPCJSRuntime() XPCPerThreadData::ShutDown(); } -namespace xpc { - -void* -GetCompartmentNameHelper(JSContext *cx, JSCompartment *c, bool getAddress) +static void* +GetCompartmentNameHelper(JSCompartment *c, bool getAddress) { nsCString* name = new nsCString(); - if (js::IsAtomsCompartmentFor(cx, c)) { + if (js::IsAtomsCompartment(c)) { name->AssignLiteral("atoms"); } else if (JSPrincipals *principals = JS_GetCompartmentPrincipals(c)) { if (principals->codebase) { @@ -1226,7 +1225,7 @@ GetCompartmentNameHelper(JSContext *cx, JSCompartment *c, bool getAddress) // distinguished. if (js::IsSystemCompartment(c)) { xpc::CompartmentPrivate *compartmentPrivate = - static_cast(JS_GetCompartmentPrivate(cx, c)); + static_cast(JS_GetCompartmentPrivate(c)); if (compartmentPrivate && !compartmentPrivate->location.IsEmpty()) { name->AppendLiteral(", "); @@ -1254,16 +1253,18 @@ GetCompartmentNameHelper(JSContext *cx, JSCompartment *c, bool getAddress) return name; } +namespace xpc { + void* GetCompartmentName(JSContext *cx, JSCompartment *c) { - return GetCompartmentNameHelper(cx, c, /* get address = */false); + return GetCompartmentNameHelper(c, /* get address = */false); } void* GetCompartmentNameAndAddress(JSContext *cx, JSCompartment *c) { - return GetCompartmentNameHelper(cx, c, /* get address = */true); + return GetCompartmentNameHelper(c, /* get address = */true); } void diff --git a/js/xpconnect/src/XPCWrappedNative.cpp b/js/xpconnect/src/XPCWrappedNative.cpp index 2ba6b20fe48..a15dac1a22e 100644 --- a/js/xpconnect/src/XPCWrappedNative.cpp +++ b/js/xpconnect/src/XPCWrappedNative.cpp @@ -81,7 +81,6 @@ NS_CYCLE_COLLECTION_CLASSNAME(XPCWrappedNative)::Unlink(void *p) struct TraverseExpandoObjectClosure { - JSContext *cx; XPCWrappedNative *wn; nsCycleCollectionTraversalCallback &cb; }; @@ -91,7 +90,7 @@ TraverseExpandoObjects(xpc::PtrAndPrincipalHashKey *aKey, JSCompartment *compart { TraverseExpandoObjectClosure *closure = static_cast(aClosure); xpc::CompartmentPrivate *priv = - (xpc::CompartmentPrivate *)JS_GetCompartmentPrivate(closure->cx, compartment); + static_cast(JS_GetCompartmentPrivate(compartment)); NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(closure->cb, "XPCWrappedNative expando object"); closure->cb.NoteScriptChild(nsIProgrammingLanguage::JAVASCRIPT, @@ -142,11 +141,7 @@ NS_CYCLE_COLLECTION_CLASSNAME(XPCWrappedNative)::Traverse(void *p, if (tmp->MightHaveExpandoObject()) { XPCJSRuntime *rt = tmp->GetRuntime(); - TraverseExpandoObjectClosure closure = { - rt->GetXPConnect()->GetCycleCollectionContext()->GetJSContext(), - tmp, - cb - }; + TraverseExpandoObjectClosure closure = { tmp, cb }; rt->GetCompartmentMap().EnumerateRead(TraverseExpandoObjects, &closure); } diff --git a/js/xpconnect/src/XPCWrappedNativeScope.cpp b/js/xpconnect/src/XPCWrappedNativeScope.cpp index 2a200dcf2b8..b1addb8ce4d 100644 --- a/js/xpconnect/src/XPCWrappedNativeScope.cpp +++ b/js/xpconnect/src/XPCWrappedNativeScope.cpp @@ -360,17 +360,6 @@ XPCWrappedNativeScope::TraceJS(JSTracer* trc, XPCJSRuntime* rt) } } -struct SuspectClosure -{ - SuspectClosure(JSContext *aCx, nsCycleCollectionTraversalCallback& aCb) - : cx(aCx), cb(aCb) - { - } - - JSContext* cx; - nsCycleCollectionTraversalCallback& cb; -}; - static JSDHashOperator WrappedNativeSuspecter(JSDHashTable *table, JSDHashEntryHdr *hdr, uint32_t number, void *arg) @@ -378,8 +367,9 @@ WrappedNativeSuspecter(JSDHashTable *table, JSDHashEntryHdr *hdr, XPCWrappedNative* wrapper = ((Native2WrappedNativeMap::Entry*)hdr)->value; if (wrapper->HasExternalReference()) { - SuspectClosure* closure = static_cast(arg); - XPCJSRuntime::SuspectWrappedNative(closure->cx, wrapper, closure->cb); + nsCycleCollectionTraversalCallback *cb = + static_cast(arg); + XPCJSRuntime::SuspectWrappedNative(wrapper, *cb); } return JS_DHASH_NEXT; @@ -387,14 +377,13 @@ WrappedNativeSuspecter(JSDHashTable *table, JSDHashEntryHdr *hdr, // static void -XPCWrappedNativeScope::SuspectAllWrappers(XPCJSRuntime* rt, JSContext* cx, +XPCWrappedNativeScope::SuspectAllWrappers(XPCJSRuntime* rt, nsCycleCollectionTraversalCallback& cb) { XPCAutoLock lock(rt->GetMapLock()); - SuspectClosure closure(cx, cb); for (XPCWrappedNativeScope* cur = gScopes; cur; cur = cur->mNext) { - cur->mWrappedNativeMap->Enumerate(WrappedNativeSuspecter, &closure); + cur->mWrappedNativeMap->Enumerate(WrappedNativeSuspecter, &cb); } } @@ -749,7 +738,7 @@ XPCWrappedNativeScope::FindInJSObjectScope(JSContext* cx, JSObject* obj, obj = JS_GetGlobalForObject(cx, obj); if (js::GetObjectClass(obj)->flags & JSCLASS_XPCONNECT_GLOBAL) { - scope = XPCWrappedNativeScope::GetNativeScope(cx, obj); + scope = XPCWrappedNativeScope::GetNativeScope(obj); if (scope) return scope; } diff --git a/js/xpconnect/src/dombindings.cpp b/js/xpconnect/src/dombindings.cpp index 46d40f38544..b65b42bbfa4 100644 --- a/js/xpconnect/src/dombindings.cpp +++ b/js/xpconnect/src/dombindings.cpp @@ -756,7 +756,7 @@ ListBase::ensureExpandoObject(JSContext *cx, JSObject *obj) JSCompartment *compartment = js::GetObjectCompartment(obj); xpc::CompartmentPrivate *priv = - static_cast(js_GetCompartmentPrivate(compartment)); + static_cast(JS_GetCompartmentPrivate(compartment)); if (!priv->RegisterDOMExpandoObject(expando)) return NULL; diff --git a/js/xpconnect/src/nsXPConnect.cpp b/js/xpconnect/src/nsXPConnect.cpp index 55853ae4f1b..693243a5eaf 100644 --- a/js/xpconnect/src/nsXPConnect.cpp +++ b/js/xpconnect/src/nsXPConnect.cpp @@ -564,9 +564,7 @@ nsXPConnect::BeginCycleCollection(nsCycleCollectionTraversalCallback &cb, static bool gcHasRun = false; if (!gcHasRun) { - JSRuntime* rt = JS_GetRuntime(mCycleCollectionContext->GetJSContext()); - if (!rt) - NS_RUNTIMEABORT("Failed to get JS runtime!"); + JSRuntime* rt = GetRuntime()->GetJSRuntime(); uint32_t gcNumber = JS_GetGCParameter(rt, JSGC_NUMBER); if (!gcNumber) NS_RUNTIMEABORT("Cannot cycle collect if GC has not run first!"); @@ -598,7 +596,7 @@ nsXPConnect::BeginCycleCollection(nsCycleCollectionTraversalCallback &cb, NS_ASSERTION(!explainLiveExpectedGarbage, "Didn't call nsXPConnect::Collect()?"); #endif - GetRuntime()->AddXPConnectRoots(mCycleCollectionContext->GetJSContext(), cb); + GetRuntime()->AddXPConnectRoots(cb); NoteWeakMapsTracer trc(mCycleCollectionContext->GetJSContext(), TraceWeakMapping, cb); @@ -1156,8 +1154,7 @@ CreateNewCompartment(JSContext *cx, JSClass *clasp, nsIPrincipal *principal, *global = tempGlobal; *compartment = js::GetObjectCompartment(tempGlobal); - js::AutoSwitchCompartment sc(cx, *compartment); - JS_SetCompartmentPrivate(cx, *compartment, priv_holder.forget()); + JS_SetCompartmentPrivate(*compartment, priv_holder.forget()); return true; } @@ -1188,9 +1185,7 @@ TraceXPCGlobal(JSTracer *trc, JSObject *obj) } #endif - XPCWrappedNativeScope *scope = - XPCWrappedNativeScope::GetNativeScope(trc->context, obj); - if (scope) + if (XPCWrappedNativeScope *scope = XPCWrappedNativeScope::GetNativeScope(obj)) scope->TraceDOMPrototypes(trc); } diff --git a/js/xpconnect/src/xpcprivate.h b/js/xpconnect/src/xpcprivate.h index 60dded54cda..7b6317b64c2 100644 --- a/js/xpconnect/src/xpcprivate.h +++ b/js/xpconnect/src/xpcprivate.h @@ -748,8 +748,7 @@ public: static void TraceBlackJS(JSTracer* trc, void* data); static void TraceGrayJS(JSTracer* trc, void* data); void TraceXPConnectRoots(JSTracer *trc); - void AddXPConnectRoots(JSContext* cx, - nsCycleCollectionTraversalCallback& cb); + void AddXPConnectRoots(nsCycleCollectionTraversalCallback& cb); void UnmarkSkippableJSHolders(); static JSBool GCCallback(JSContext *cx, JSGCStatus status); @@ -761,7 +760,7 @@ public: nsresult AddJSHolder(void* aHolder, nsScriptObjectTracer* aTracer); nsresult RemoveJSHolder(void* aHolder); - static void SuspectWrappedNative(JSContext *cx, XPCWrappedNative *wrapper, + static void SuspectWrappedNative(XPCWrappedNative *wrapper, nsCycleCollectionTraversalCallback &cb); void DebugDump(PRInt16 depth); @@ -1556,8 +1555,7 @@ public: TraceJS(JSTracer* trc, XPCJSRuntime* rt); static void - SuspectAllWrappers(XPCJSRuntime* rt, JSContext* cx, - nsCycleCollectionTraversalCallback &cb); + SuspectAllWrappers(XPCJSRuntime* rt, nsCycleCollectionTraversalCallback &cb); static void FinishedMarkPhaseOfGC(JSContext* cx, XPCJSRuntime* rt); @@ -1610,7 +1608,7 @@ public: return mCachedDOMPrototypes; } - static XPCWrappedNativeScope *GetNativeScope(JSContext *cx, JSObject *obj) + static XPCWrappedNativeScope *GetNativeScope(JSObject *obj) { MOZ_ASSERT(js::GetObjectClass(obj)->flags & JSCLASS_XPCONNECT_GLOBAL); diff --git a/js/xpconnect/wrappers/WrapperFactory.cpp b/js/xpconnect/wrappers/WrapperFactory.cpp index 752b3d30344..0dd509a9572 100644 --- a/js/xpconnect/wrappers/WrapperFactory.cpp +++ b/js/xpconnect/wrappers/WrapperFactory.cpp @@ -101,7 +101,7 @@ WrapperFactory::WaiveXray(JSContext *cx, JSObject *obj) { // See if we already have a waiver wrapper for this object. CompartmentPrivate *priv = - (CompartmentPrivate *)JS_GetCompartmentPrivate(cx, js::GetObjectCompartment(obj)); + (CompartmentPrivate *)JS_GetCompartmentPrivate(js::GetObjectCompartment(obj)); JSObject *wobj = nsnull; if (priv && priv->waiverWrapperMap) { wobj = priv->waiverWrapperMap->Find(obj); @@ -279,7 +279,7 @@ WrapperFactory::Rewrap(JSContext *cx, JSObject *obj, JSObject *wrappedProto, JSO Wrapper *wrapper; CompartmentPrivate *targetdata = - static_cast(JS_GetCompartmentPrivate(cx, target)); + static_cast(JS_GetCompartmentPrivate(target)); if (AccessCheck::isChrome(target)) { if (AccessCheck::isChrome(origin)) { wrapper = &CrossCompartmentWrapper::singleton; diff --git a/js/xpconnect/wrappers/XrayWrapper.cpp b/js/xpconnect/wrappers/XrayWrapper.cpp index 5d01bbc29ce..1a9e5a18fe9 100644 --- a/js/xpconnect/wrappers/XrayWrapper.cpp +++ b/js/xpconnect/wrappers/XrayWrapper.cpp @@ -159,7 +159,7 @@ EnsureExpandoObject(JSContext *cx, JSObject *holder) if (expando) return expando; CompartmentPrivate *priv = - (CompartmentPrivate *)JS_GetCompartmentPrivate(cx, js::GetObjectCompartment(holder)); + (CompartmentPrivate *)JS_GetCompartmentPrivate(js::GetObjectCompartment(holder)); XPCWrappedNative *wn = GetWrappedNativeFromHolder(holder); expando = priv->LookupExpandoObject(wn); if (!expando) { @@ -1052,7 +1052,7 @@ XrayWrapper::createHolder(JSContext *cx, JSObject *wrappedNative, JSObject return nsnull; CompartmentPrivate *priv = - (CompartmentPrivate *)JS_GetCompartmentPrivate(cx, js::GetObjectCompartment(holder)); + (CompartmentPrivate *)JS_GetCompartmentPrivate(js::GetObjectCompartment(holder)); JSObject *inner = JS_ObjectToInnerObject(cx, wrappedNative); XPCWrappedNative *wn = GetWrappedNative(inner); Value expando = ObjectOrNullValue(priv->LookupExpandoObject(wn));