bug 730281 - remove cx argument from GC and compartment related functions. r=:billm

This commit is contained in:
Igor Bukanov 2012-02-29 13:18:16 +01:00
parent 7795682ab9
commit 9174f0c095
27 changed files with 215 additions and 322 deletions

View File

@ -176,7 +176,7 @@ nsWrapperCache::RemoveExpandoObject()
if (expando) {
JSCompartment *compartment = js::GetObjectCompartment(expando);
xpc::CompartmentPrivate *priv =
static_cast<xpc::CompartmentPrivate *>(js_GetCompartmentPrivate(compartment));
static_cast<xpc::CompartmentPrivate *>(JS_GetCompartmentPrivate(compartment));
priv->RemoveDOMExpandoObject(expando);
}
}

View File

@ -2091,7 +2091,7 @@ nsGlobalWindow::SetNewDocument(nsIDocument* aDocument,
JSCompartment *compartment = js::GetObjectCompartment(mJSObject);
xpc::CompartmentPrivate *priv =
static_cast<xpc::CompartmentPrivate*>(JS_GetCompartmentPrivate(cx, compartment));
static_cast<xpc::CompartmentPrivate*>(JS_GetCompartmentPrivate(compartment));
if (priv && priv->waiverWrapperMap) {
NS_ASSERTION(!JS_IsExceptionPending(cx),
"We might overwrite a pending exception!");

View File

@ -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);
}

View File

@ -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<JSBool> 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

View File

@ -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

View File

@ -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_<JSContext>(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<AutoLockGC> 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);

View File

@ -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);

View File

@ -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<JSObject> array;
};

View File

@ -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;
}

View File

@ -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. */

View File

@ -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)

View File

@ -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

View File

@ -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<Cell*> *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<uint8_t*>(w), sizeof(w)))
for (unsigned i = 0; i < THING_ROOT_COUNT; i++) {
Root<Cell*> *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<uint8_t*>(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);

View File

@ -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

View File

@ -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);

View File

@ -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);

View File

@ -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;
}

View File

@ -1558,7 +1558,7 @@ class StackSpace
class ContextStack
{
StackSegment *seg_;
StackSpace *space_;
StackSpace *const space_;
JSContext *cx_;
/*

View File

@ -3053,7 +3053,7 @@ xpc_CreateSandboxObject(JSContext * cx, jsval * vp, nsISupports *prinOrSop, JSOb
}
xpc::CompartmentPrivate *compartmentPrivate =
static_cast<xpc::CompartmentPrivate*>(JS_GetCompartmentPrivate(cx, compartment));
static_cast<xpc::CompartmentPrivate*>(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<xpc::CompartmentPrivate*>(privateValue);
@ -3556,7 +3556,7 @@ xpc_EvalInSandbox(JSContext *cx, JSObject *sandbox, const nsAString& source,
xpc::CompartmentPrivate *sandboxdata =
static_cast<xpc::CompartmentPrivate *>
(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;

View File

@ -257,10 +257,13 @@ CompartmentCallback(JSContext *cx, JSCompartment *compartment, unsigned op)
if (!self)
return true;
nsAutoPtr<xpc::CompartmentPrivate> priv(static_cast<xpc::CompartmentPrivate*>(JS_SetCompartmentPrivate(cx, compartment, nsnull)));
nsAutoPtr<xpc::CompartmentPrivate>
priv(static_cast<xpc::CompartmentPrivate*>(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<JSObject> *expando, void *aClosure)
static PLDHashOperator
TraceCompartment(xpc::PtrAndPrincipalHashKey *aKey, JSCompartment *compartment, void *aClosure)
{
xpc::CompartmentPrivate *priv = (xpc::CompartmentPrivate *)
JS_GetCompartmentPrivate(static_cast<JSTracer *>(aClosure)->context, compartment);
xpc::CompartmentPrivate *priv =
static_cast<xpc::CompartmentPrivate *>(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<Closure*>(arg);
XPCJSRuntime::SuspectWrappedNative(closure->cx, wrapper, *closure->cb);
XPCJSRuntime::SuspectWrappedNative(wrapper, *closure->cb);
return PL_DHASH_NEXT;
}
@ -510,9 +512,8 @@ SuspectDOMExpandos(nsPtrHashKey<JSObject> *expando, void *arg)
static PLDHashOperator
SuspectCompartment(xpc::PtrAndPrincipalHashKey *key, JSCompartment *compartment, void *arg)
{
Closure* closure = static_cast<Closure*>(arg);
xpc::CompartmentPrivate *priv = (xpc::CompartmentPrivate *)
JS_GetCompartmentPrivate(closure->cx, compartment);
xpc::CompartmentPrivate *priv =
static_cast<xpc::CompartmentPrivate *>(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<XPCTraceableVariant*>(e);
@ -570,7 +570,7 @@ XPCJSRuntime::AddXPConnectRoots(JSContext* cx,
cb.NoteXPCOMRoot(static_cast<nsIXPConnectWrappedJS *>(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<xpc::CompartmentPrivate *>(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<xpc::CompartmentPrivate*>(JS_GetCompartmentPrivate(cx, c));
static_cast<xpc::CompartmentPrivate*>(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

View File

@ -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<TraverseExpandoObjectClosure*>(aClosure);
xpc::CompartmentPrivate *priv =
(xpc::CompartmentPrivate *)JS_GetCompartmentPrivate(closure->cx, compartment);
static_cast<xpc::CompartmentPrivate *>(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);
}

View File

@ -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<SuspectClosure*>(arg);
XPCJSRuntime::SuspectWrappedNative(closure->cx, wrapper, closure->cb);
nsCycleCollectionTraversalCallback *cb =
static_cast<nsCycleCollectionTraversalCallback *>(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;
}

View File

@ -756,7 +756,7 @@ ListBase<LC>::ensureExpandoObject(JSContext *cx, JSObject *obj)
JSCompartment *compartment = js::GetObjectCompartment(obj);
xpc::CompartmentPrivate *priv =
static_cast<xpc::CompartmentPrivate *>(js_GetCompartmentPrivate(compartment));
static_cast<xpc::CompartmentPrivate *>(JS_GetCompartmentPrivate(compartment));
if (!priv->RegisterDOMExpandoObject(expando))
return NULL;

View File

@ -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);
}

View File

@ -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);

View File

@ -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<CompartmentPrivate *>(JS_GetCompartmentPrivate(cx, target));
static_cast<CompartmentPrivate *>(JS_GetCompartmentPrivate(target));
if (AccessCheck::isChrome(target)) {
if (AccessCheck::isChrome(origin)) {
wrapper = &CrossCompartmentWrapper::singleton;

View File

@ -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<Base>::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));