Bug 1281529 part 1 - Make JSContext inherit from JSRuntime. r=luke

This commit is contained in:
Jan de Mooij 2016-06-24 14:16:47 +02:00
Родитель e5276c42ac
Коммит 0dea76ff67
11 изменённых файлов: 71 добавлений и 66 удалений

Просмотреть файл

@ -223,16 +223,13 @@ AutoGCRooter::trace(JSTracer* trc)
/* static */ void
AutoGCRooter::traceAll(JSTracer* trc)
{
if (JSContext* cx = trc->runtime()->maybeContextFromMainThread())
traceAllInContext(cx, trc);
traceAllInContext(trc->runtime()->contextFromMainThread(), trc);
}
/* static */ void
AutoGCRooter::traceAllWrappers(JSTracer* trc)
{
JSContext* cx = trc->runtime()->maybeContextFromMainThread();
if (!cx)
return;
JSContext* cx = trc->runtime()->contextFromMainThread();
for (AutoGCRooter* gcr = cx->roots.autoGCRooters_; gcr; gcr = gcr->down) {
if (gcr->tag_ == WRAPVECTOR || gcr->tag_ == WRAPPER)
@ -320,8 +317,7 @@ js::gc::GCRuntime::markRuntime(JSTracer* trc, TraceOrMarkRuntime traceOrMark,
if (rt->isHeapMinorCollecting())
jit::JitRuntime::MarkJitcodeGlobalTableUnconditionally(trc);
if (JSContext* cx = rt->maybeContextFromMainThread())
cx->mark(trc);
rt->contextFromMainThread()->mark(trc);
for (CompartmentsIter c(rt, SkipAtoms); !c.done(); c.next())
c->traceRoots(trc, traceOrMark);

Просмотреть файл

@ -466,22 +466,14 @@ JS_NewRuntime(uint32_t maxbytes, uint32_t maxNurseryBytes, JSRuntime* parentRunt
while (parentRuntime && parentRuntime->parentRuntime)
parentRuntime = parentRuntime->parentRuntime;
JSRuntime* rt = js_new<JSRuntime>(parentRuntime);
if (!rt)
return nullptr;
if (!rt->init(maxbytes, maxNurseryBytes)) {
JS_DestroyRuntime(rt);
return nullptr;
}
return rt;
return NewContext(maxbytes, maxNurseryBytes, parentRuntime);
}
JS_PUBLIC_API(void)
JS_DestroyRuntime(JSRuntime* rt)
{
js_delete(rt);
JSContext* cx = rt->contextFromMainThread();
DestroyContext(cx);
}
static JS_CurrentEmbedderTimeFunction currentEmbedderTimeFunction;

Просмотреть файл

@ -209,12 +209,6 @@ ClassName(JSProtoKey key, JSAtomState& atomState)
return (&atomState.Null)[key];
}
inline Handle<PropertyName*>
ClassName(JSProtoKey key, JSRuntime* rt)
{
return ClassName(key, *rt->commonNames);
}
inline Handle<PropertyName*>
ClassName(JSProtoKey key, ExclusiveContext* cx)
{

Просмотреть файл

@ -87,18 +87,26 @@ js::TraceCycleDetectionSet(JSTracer* trc, AutoCycleDetector::Set& set)
TraceRoot(trc, &e.mutableFront(), "cycle detector table entry");
}
JSContext*
js::NewContext(JSRuntime* rt)
bool
JSContext::init(uint32_t maxBytes, uint32_t maxNurseryBytes)
{
MOZ_ASSERT(!rt->maybeContextFromMainThread());
if (!JSRuntime::init(maxBytes, maxNurseryBytes))
return false;
JS_AbortIfWrongThread(rt);
return true;
}
JSContext* cx = js_new<JSContext>(rt);
JSContext*
js::NewContext(uint32_t maxBytes, uint32_t maxNurseryBytes, JSRuntime* parentRuntime)
{
UniquePtr<JSContext> cx(js_new<JSContext>(parentRuntime));
if (!cx)
return nullptr;
return cx;
if (!cx->init(maxBytes, maxNurseryBytes))
return nullptr;
return cx.release();
}
void
@ -858,8 +866,9 @@ ExclusiveContext::recoverFromOutOfMemory()
task->outOfMemory = false;
}
JSContext::JSContext(JSRuntime* rt)
: ExclusiveContext(rt, &rt->mainThread, Context_JS),
JSContext::JSContext(JSRuntime* parentRuntime)
: ExclusiveContext(this, &this->JSRuntime::mainThread, Context_JS),
JSRuntime(this, parentRuntime),
throwing(false),
unwrappedException_(this),
overRecursed_(false),
@ -880,6 +889,8 @@ JSContext::JSContext(JSRuntime* rt)
JSContext::~JSContext()
{
destroyRuntime();
/* Free the stuff hanging off of cx. */
MOZ_ASSERT(!resolvingList);
}
@ -1024,9 +1035,8 @@ JSContext::sizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const
void
JSContext::mark(JSTracer* trc)
{
/* Stack frames and slots are traced by StackSpace::mark. */
TraceCycleDetectionSet(trc, cycleDetectorSet);
if (cycleDetectorSet.initialized())
TraceCycleDetectionSet(trc, cycleDetectorSet);
if (compartment_)
compartment_->mark();

Просмотреть файл

@ -295,11 +295,29 @@ void ReportOverRecursed(JSContext* cx, unsigned errorNumber);
} /* namespace js */
struct JSContext : public js::ExclusiveContext
struct JSContext : public js::ExclusiveContext,
public JSRuntime
{
explicit JSContext(JSRuntime* rt);
explicit JSContext(JSRuntime* parentRuntime);
~JSContext();
bool init(uint32_t maxBytes, uint32_t maxNurseryBytes);
// For names that exist in both ExclusiveContext and JSRuntime, pick the
// ExclusiveContext version.
using ExclusiveContext::atomsCompartment;
using ExclusiveContext::buildIdOp;
using ExclusiveContext::emptyString;
using ExclusiveContext::jitSupportsSimd;
using ExclusiveContext::make_pod_array;
using ExclusiveContext::make_unique;
using ExclusiveContext::new_;
using ExclusiveContext::permanentAtoms;
using ExclusiveContext::pod_calloc;
using ExclusiveContext::pod_malloc;
using ExclusiveContext::staticStrings;
using ExclusiveContext::wellKnownSymbols;
JSRuntime* runtime() const { return runtime_; }
js::PerThreadData& mainThread() const { return runtime()->mainThread; }
@ -495,7 +513,7 @@ struct MOZ_RAII AutoResolving {
* and exclusively owned.
*/
extern JSContext*
NewContext(JSRuntime* rt);
NewContext(uint32_t maxBytes, uint32_t maxNurseryBytes, JSRuntime* parentRuntime);
extern void
DestroyContext(JSContext* cx);
@ -721,6 +739,10 @@ class MOZ_RAII AutoLockForExclusiveAccess
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
init(rt);
}
explicit AutoLockForExclusiveAccess(JSContext* cx MOZ_GUARD_OBJECT_NOTIFIER_PARAM) {
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
init(cx->runtime());
}
~AutoLockForExclusiveAccess() {
if (runtime->numExclusiveThreads) {
#ifdef DEBUG

Просмотреть файл

@ -522,7 +522,7 @@ js::GetErrorTypeName(JSRuntime* rt, int16_t exnType)
return nullptr;
}
JSProtoKey key = GetExceptionProtoKey(JSExnType(exnType));
return ClassName(key, rt);
return ClassName(key, rt->contextFromMainThread());
}
void

Просмотреть файл

@ -6985,8 +6985,8 @@ AutoSuppressGC::AutoSuppressGC(JSCompartment* comp)
suppressGC_++;
}
AutoSuppressGC::AutoSuppressGC(JSRuntime* rt)
: suppressGC_(rt->mainThread.suppressGC)
AutoSuppressGC::AutoSuppressGC(JSContext* cx)
: suppressGC_(cx->mainThread().suppressGC)
{
suppressGC_++;
}

Просмотреть файл

@ -1276,7 +1276,7 @@ class MOZ_RAII JS_HAZ_GC_SUPPRESSED AutoSuppressGC
public:
explicit AutoSuppressGC(ExclusiveContext* cx);
explicit AutoSuppressGC(JSCompartment* comp);
explicit AutoSuppressGC(JSRuntime* rt);
explicit AutoSuppressGC(JSContext* cx);
~AutoSuppressGC()
{

Просмотреть файл

@ -128,7 +128,7 @@ ReturnZeroSize(const void* p)
return 0;
}
JSRuntime::JSRuntime(JSRuntime* parentRuntime)
JSRuntime::JSRuntime(JSContext* cx, JSRuntime* parentRuntime)
: mainThread(this),
jitTop(nullptr),
jitJSContext(nullptr),
@ -173,7 +173,7 @@ JSRuntime::JSRuntime(JSRuntime* parentRuntime)
ownerThread_(nullptr),
ownerThreadNative_(0),
tempLifoAlloc(TEMP_LIFO_ALLOC_PRIMARY_CHUNK_SIZE),
context_(nullptr),
context_(cx),
jitRuntime_(nullptr),
selfHostingGlobal_(nullptr),
nativeStackBase(GetNativeStackBase()),
@ -371,20 +371,12 @@ JSRuntime::init(uint32_t maxbytes, uint32_t maxNurseryBytes)
return false;
}
context_ = NewContext(this);
if (!context_)
return false;
return true;
}
JSRuntime::~JSRuntime()
void
JSRuntime::destroyRuntime()
{
if (context_) {
DestroyContext(context_);
context_ = nullptr;
}
MOZ_ASSERT(!isHeapBusy());
MOZ_ASSERT(childRuntimeCount == 0);
@ -758,7 +750,7 @@ JSRuntime::triggerActivityCallback(bool active)
* suppression serves to inform the exact rooting hazard analysis of this
* property and ensures that it remains true in the future.
*/
AutoSuppressGC suppress(this);
AutoSuppressGC suppress(contextFromMainThread());
activityCallback(activityCallbackArg, active);
}

Просмотреть файл

@ -1054,17 +1054,10 @@ struct JSRuntime : public JS::shadow::Runtime,
return interpreterStack_;
}
// The runtime's context can be nullptr only while we're initializing or
// destroying the runtime.
JSContext* maybeContextFromMainThread() {
JSContext* contextFromMainThread() {
MOZ_ASSERT(CurrentThreadCanAccessRuntime(this));
return context_;
}
JSContext* contextFromMainThread() {
JSContext* cx = maybeContextFromMainThread();
MOZ_ASSERT(cx);
return cx;
}
bool enqueuePromiseJob(JSContext* cx, js::HandleFunction job, js::HandleObject promise);
void addUnhandledRejectedPromise(JSContext* cx, js::HandleObject promise);
@ -1495,13 +1488,18 @@ struct JSRuntime : public JS::shadow::Runtime,
return liveRuntimesCount > 0;
}
explicit JSRuntime(JSRuntime* parentRuntime);
~JSRuntime();
protected:
JSRuntime(JSContext* cx, JSRuntime* parentRuntime);
// destroyRuntime is used instead of a destructor, to ensure the downcast
// to JSContext remains valid. The final GC triggered here depends on this.
void destroyRuntime();
bool init(uint32_t maxbytes, uint32_t maxNurseryBytes);
JSRuntime* thisFromCtor() { return this; }
public:
/*
* Call this after allocating memory held by GC things, to update memory
* pressure counters or report the OOM error if necessary. If oomError and

Просмотреть файл

@ -298,7 +298,8 @@ struct AutoEnterAnalysis
}
AutoEnterAnalysis(FreeOp* fop, Zone* zone)
: suppressGC(zone->runtimeFromMainThread()), oom(zone), suppressMetadata(zone)
: suppressGC(zone->runtimeFromMainThread()->contextFromMainThread()),
oom(zone), suppressMetadata(zone)
{
init(fop, zone);
}