Bug 1464134 part 1 - Fix various places to use Realm instead of JSCompartment. r=luke

This commit is contained in:
Jan de Mooij 2018-05-27 11:53:11 +02:00
parent 4a95166f46
commit 1879873837
26 changed files with 123 additions and 119 deletions

View file

@ -87,12 +87,8 @@ jsfuzz_init(JSContext** cx, JS::PersistentRootedObject* global)
} }
static void static void
jsfuzz_uninit(JSContext* cx, JSCompartment* oldCompartment) jsfuzz_uninit(JSContext* cx)
{ {
if (oldCompartment) {
JS::LeaveRealm(cx, JS::GetRealmForCompartment(oldCompartment));
oldCompartment = nullptr;
}
if (cx) { if (cx) {
JS_EndRequest(cx); JS_EndRequest(cx);
JS_DestroyContext(cx); JS_DestroyContext(cx);
@ -143,7 +139,7 @@ main(int argc, char* argv[])
testingFunc(nullptr, 0); testingFunc(nullptr, 0);
#endif #endif
jsfuzz_uninit(gCx, nullptr); jsfuzz_uninit(gCx);
JS_ShutDown(); JS_ShutDown();

View file

@ -7914,9 +7914,8 @@ AutoPrepareForTracing::AutoPrepareForTracing(JSContext* cx)
session_.emplace(cx->runtime()); session_.emplace(cx->runtime());
} }
JSCompartment* Realm*
js::NewCompartment(JSContext* cx, JSPrincipals* principals, js::NewRealm(JSContext* cx, JSPrincipals* principals, const JS::RealmOptions& options)
const JS::RealmOptions& options)
{ {
JSRuntime* rt = cx->runtime(); JSRuntime* rt = cx->runtime();
JS_AbortIfWrongThread(cx); JS_AbortIfWrongThread(cx);
@ -7983,30 +7982,28 @@ js::NewCompartment(JSContext* cx, JSPrincipals* principals,
} }
zoneHolder.forget(); zoneHolder.forget();
return JS::GetCompartmentForRealm(realm.forget()); return realm.forget();
} }
void void
gc::MergeCompartments(JSCompartment* source, JSCompartment* target) gc::MergeRealms(Realm* source, Realm* target)
{ {
JSRuntime* rt = source->runtimeFromMainThread(); JSRuntime* rt = source->runtimeFromMainThread();
rt->gc.mergeCompartments(source, target); rt->gc.mergeRealms(source, target);
AutoLockGC lock(rt); AutoLockGC lock(rt);
rt->gc.maybeAllocTriggerZoneGC(target->zone(), lock); rt->gc.maybeAllocTriggerZoneGC(target->zone(), lock);
} }
void void
GCRuntime::mergeCompartments(JSCompartment* source, JSCompartment* target) GCRuntime::mergeRealms(Realm* source, Realm* target)
{ {
// The source realm must be specifically flagged as mergable. This // The source realm must be specifically flagged as mergable. This
// also implies that the realm is not visible to the debugger. // also implies that the realm is not visible to the debugger.
Realm* sourceRealm = JS::GetRealmForCompartment(source); MOZ_ASSERT(source->creationOptions().mergeable());
Realm* targetRealm = JS::GetRealmForCompartment(target); MOZ_ASSERT(source->creationOptions().invisibleToDebugger());
MOZ_ASSERT(sourceRealm->creationOptions().mergeable());
MOZ_ASSERT(sourceRealm->creationOptions().invisibleToDebugger());
MOZ_ASSERT(!sourceRealm->hasBeenEntered()); MOZ_ASSERT(!source->hasBeenEntered());
MOZ_ASSERT(source->zone()->compartments().length() == 1); MOZ_ASSERT(source->zone()->compartments().length() == 1);
JSContext* cx = rt->mainContextFromOwnThread(); JSContext* cx = rt->mainContextFromOwnThread();
@ -8019,35 +8016,35 @@ GCRuntime::mergeCompartments(JSCompartment* source, JSCompartment* target)
// Cleanup tables and other state in the source realm/zone that will be // Cleanup tables and other state in the source realm/zone that will be
// meaningless after merging into the target realm/zone. // meaningless after merging into the target realm/zone.
sourceRealm->clearTables(); source->clearTables();
source->zone()->clearTables(); source->zone()->clearTables();
sourceRealm->unsetIsDebuggee(); source->unsetIsDebuggee();
// The delazification flag indicates the presence of LazyScripts in a // The delazification flag indicates the presence of LazyScripts in a
// realm for the Debugger API, so if the source realm created LazyScripts, // realm for the Debugger API, so if the source realm created LazyScripts,
// the flag must be propagated to the target realm. // the flag must be propagated to the target realm.
if (sourceRealm->needsDelazificationForDebugger()) if (source->needsDelazificationForDebugger())
targetRealm->scheduleDelazificationForDebugger(); target->scheduleDelazificationForDebugger();
// Release any relocated arenas which we may be holding on to as they might // Release any relocated arenas which we may be holding on to as they might
// be in the source zone // be in the source zone
releaseHeldRelocatedArenas(); releaseHeldRelocatedArenas();
// Fixup compartment pointers in source to refer to target, and make sure // Fixup realm pointers in source to refer to target, and make sure
// type information generations are in sync. // type information generations are in sync.
for (auto script = source->zone()->cellIter<JSScript>(); !script.done(); script.next()) { for (auto script = source->zone()->cellIter<JSScript>(); !script.done(); script.next()) {
MOZ_ASSERT(script->compartment() == source); MOZ_ASSERT(script->realm() == source);
script->realm_ = JS::GetRealmForCompartment(target); script->realm_ = target;
script->setTypesGeneration(target->zone()->types.generation); script->setTypesGeneration(target->zone()->types.generation);
} }
GlobalObject* global = targetRealm->maybeGlobal(); GlobalObject* global = target->maybeGlobal();
MOZ_ASSERT(global); MOZ_ASSERT(global);
for (auto group = source->zone()->cellIter<ObjectGroup>(); !group.done(); group.next()) { for (auto group = source->zone()->cellIter<ObjectGroup>(); !group.done(); group.next()) {
// Replace placeholder object prototypes with the correct prototype in // Replace placeholder object prototypes with the correct prototype in
// the target compartment. // the target realm.
TaggedProto proto(group->proto()); TaggedProto proto(group->proto());
if (proto.isObject()) { if (proto.isObject()) {
JSObject* obj = proto.toObject(); JSObject* obj = proto.toObject();
@ -8063,13 +8060,13 @@ GCRuntime::mergeCompartments(JSCompartment* source, JSCompartment* target)
} }
group->setGeneration(target->zone()->types.generation); group->setGeneration(target->zone()->types.generation);
group->realm_ = JS::GetRealmForCompartment(target); group->realm_ = target;
// Remove any unboxed layouts from the list in the off thread // Remove any unboxed layouts from the list in the off thread
// compartment. These do not need to be reinserted in the target // realm. These do not need to be reinserted in the target
// compartment's list, as the list is not required to be complete. // realm's list, as the list is not required to be complete.
if (UnboxedLayout* layout = group->maybeUnboxedLayoutDontCheckGeneration()) if (UnboxedLayout* layout = group->maybeUnboxedLayoutDontCheckGeneration())
layout->detachFromCompartment(); layout->detachFromRealm();
} }
// Fixup zone pointers in source's zone to refer to target's zone. // Fixup zone pointers in source's zone to refer to target's zone.
@ -8092,9 +8089,9 @@ GCRuntime::mergeCompartments(JSCompartment* source, JSCompartment* target)
} }
} }
// The source should be the only compartment in its zone. // The source should be the only realm in its zone.
for (CompartmentsInZoneIter c(source->zone()); !c.done(); c.next()) for (RealmsInZoneIter r(source->zone()); !r.done(); r.next())
MOZ_ASSERT(c.get() == source); MOZ_ASSERT(r.get() == source);
// Merge the allocator, stats and UIDs in source's zone into target's zone. // Merge the allocator, stats and UIDs in source's zone into target's zone.
target->zone()->arenas.adoptArenas(rt, &source->zone()->arenas, targetZoneIsCollecting); target->zone()->arenas.adoptArenas(rt, &source->zone()->arenas, targetZoneIsCollecting);
@ -8109,37 +8106,37 @@ GCRuntime::mergeCompartments(JSCompartment* source, JSCompartment* target)
// Atoms which are marked in source's zone are now marked in target's zone. // Atoms which are marked in source's zone are now marked in target's zone.
atomMarking.adoptMarkedAtoms(target->zone(), source->zone()); atomMarking.adoptMarkedAtoms(target->zone(), source->zone());
// Merge script name maps in the target compartment's map. // Merge script name maps in the target realm's map.
if (rt->lcovOutput().isEnabled() && sourceRealm->scriptNameMap) { if (rt->lcovOutput().isEnabled() && source->scriptNameMap) {
AutoEnterOOMUnsafeRegion oomUnsafe; AutoEnterOOMUnsafeRegion oomUnsafe;
if (!targetRealm->scriptNameMap) { if (!target->scriptNameMap) {
targetRealm->scriptNameMap = cx->make_unique<ScriptNameMap>(); target->scriptNameMap = cx->make_unique<ScriptNameMap>();
if (!targetRealm->scriptNameMap) if (!target->scriptNameMap)
oomUnsafe.crash("Failed to create a script name map."); oomUnsafe.crash("Failed to create a script name map.");
if (!targetRealm->scriptNameMap->init()) if (!target->scriptNameMap->init())
oomUnsafe.crash("Failed to initialize a script name map."); oomUnsafe.crash("Failed to initialize a script name map.");
} }
for (ScriptNameMap::Range r = sourceRealm->scriptNameMap->all(); !r.empty(); r.popFront()) { for (ScriptNameMap::Range r = source->scriptNameMap->all(); !r.empty(); r.popFront()) {
JSScript* key = r.front().key(); JSScript* key = r.front().key();
auto value = Move(r.front().value()); auto value = Move(r.front().value());
if (!targetRealm->scriptNameMap->putNew(key, Move(value))) if (!target->scriptNameMap->putNew(key, Move(value)))
oomUnsafe.crash("Failed to add an entry in the script name map."); oomUnsafe.crash("Failed to add an entry in the script name map.");
} }
sourceRealm->scriptNameMap->clear(); source->scriptNameMap->clear();
} }
// The source compartment is now completely empty, and is the only // The source realm is now completely empty, and is the only realm in its
// compartment in its zone, which is the only zone in its group. Delete // compartment, which is the only compartment in its zone. Delete realm,
// compartment, zone and group without waiting for this to be cleaned up by // compartment and zone without waiting for this to be cleaned up by a full
// a full GC. // GC.
Zone* sourceZone = source->zone(); Zone* sourceZone = source->zone();
sourceZone->deleteEmptyCompartment(source); sourceZone->deleteEmptyCompartment(source->compartment());
deleteEmptyZone(sourceZone); deleteEmptyZone(sourceZone);
} }

View file

@ -122,9 +122,8 @@ extern void
IterateScripts(JSContext* cx, JSCompartment* compartment, IterateScripts(JSContext* cx, JSCompartment* compartment,
void* data, IterateScriptCallback scriptCallback); void* data, IterateScriptCallback scriptCallback);
JSCompartment* JS::Realm*
NewCompartment(JSContext* cx, JSPrincipals* principals, NewRealm(JSContext* cx, JSPrincipals* principals, const JS::RealmOptions& options);
const JS::RealmOptions& options);
namespace gc { namespace gc {
@ -132,10 +131,10 @@ void FinishGC(JSContext* cx);
/* /*
* Merge all contents of source into target. This can only be used if source is * Merge all contents of source into target. This can only be used if source is
* the only compartment in its zone. * the only realm in its zone.
*/ */
void void
MergeCompartments(JSCompartment* source, JSCompartment* target); MergeRealms(JS::Realm* source, JS::Realm* target);
enum VerifierType { enum VerifierType {
PreBarrierVerifier PreBarrierVerifier

View file

@ -495,7 +495,7 @@ class GCRuntime
void joinTask(GCParallelTask& task, gcstats::PhaseKind phase, void joinTask(GCParallelTask& task, gcstats::PhaseKind phase,
AutoLockHelperThreadState& locked); AutoLockHelperThreadState& locked);
void mergeCompartments(JSCompartment* source, JSCompartment* target); void mergeRealms(JS::Realm* source, JS::Realm* target);
private: private:
enum IncrementalResult enum IncrementalResult

View file

@ -632,7 +632,7 @@ void
JitRealm::sweep(JS::Realm* realm) JitRealm::sweep(JS::Realm* realm)
{ {
// Any outstanding compilations should have been cancelled by the GC. // Any outstanding compilations should have been cancelled by the GC.
MOZ_ASSERT(!HasOffThreadIonCompile(JS::GetCompartmentForRealm(realm))); MOZ_ASSERT(!HasOffThreadIonCompile(realm));
stubCodes_->sweep(); stubCodes_->sweep();
@ -2843,8 +2843,8 @@ jit::InvalidateAll(FreeOp* fop, Zone* zone)
{ {
// The caller should previously have cancelled off thread compilation. // The caller should previously have cancelled off thread compilation.
#ifdef DEBUG #ifdef DEBUG
for (CompartmentsInZoneIter comp(zone); !comp.done(); comp.next()) for (RealmsInZoneIter realm(zone); !realm.done(); realm.next())
MOZ_ASSERT(!HasOffThreadIonCompile(comp)); MOZ_ASSERT(!HasOffThreadIonCompile(realm));
#endif #endif
if (zone->isAtomsZone()) if (zone->isAtomsZone())
return; return;

View file

@ -674,7 +674,7 @@ JS_SetExternalStringSizeofCallback(JSContext* cx, JSExternalStringSizeofCallback
cx->runtime()->externalStringSizeofCallback = callback; cx->runtime()->externalStringSizeofCallback = callback;
} }
JS_PUBLIC_API(JSCompartment*) JS_PUBLIC_API(Realm*)
JS::EnterRealm(JSContext* cx, JSObject* target) JS::EnterRealm(JSContext* cx, JSObject* target)
{ {
AssertHeapIsIdle(); AssertHeapIsIdle();
@ -682,7 +682,7 @@ JS::EnterRealm(JSContext* cx, JSObject* target)
Realm* oldRealm = cx->realm(); Realm* oldRealm = cx->realm();
cx->enterRealmOf(target); cx->enterRealmOf(target);
return JS::GetCompartmentForRealm(oldRealm); return oldRealm;
} }
JS_PUBLIC_API(void) JS_PUBLIC_API(void)
@ -890,7 +890,7 @@ JS_TransplantObject(JSContext* cx, HandleObject origobj, HandleObject target)
// destination, then we know that we won't find a wrapper in the // destination, then we know that we won't find a wrapper in the
// destination's cross compartment map and that the same // destination's cross compartment map and that the same
// object will continue to work. // object will continue to work.
AutoRealmUnchecked ar(cx, origobj->compartment()); AutoRealmUnchecked ar(cx, origobj->realm());
if (!JSObject::swap(cx, origobj, target)) if (!JSObject::swap(cx, origobj, target))
MOZ_CRASH(); MOZ_CRASH();
newIdentity = origobj; newIdentity = origobj;
@ -924,7 +924,7 @@ JS_TransplantObject(JSContext* cx, HandleObject origobj, HandleObject target)
// Lastly, update the original object to point to the new one. // Lastly, update the original object to point to the new one.
if (origobj->compartment() != destination) { if (origobj->compartment() != destination) {
RootedObject newIdentityWrapper(cx, newIdentity); RootedObject newIdentityWrapper(cx, newIdentity);
AutoRealmUnchecked ar(cx, origobj->compartment()); AutoRealmUnchecked ar(cx, origobj->realm());
if (!JS_WrapObject(cx, &newIdentityWrapper)) if (!JS_WrapObject(cx, &newIdentityWrapper))
MOZ_CRASH(); MOZ_CRASH();
MOZ_ASSERT(Wrapper::wrappedObject(newIdentityWrapper) == newIdentity); MOZ_ASSERT(Wrapper::wrappedObject(newIdentityWrapper) == newIdentity);

View file

@ -1046,7 +1046,7 @@ JS_RefreshCrossCompartmentWrappers(JSContext* cx, JS::Handle<JSObject*> obj);
* *
* void foo(JSContext* cx, JSObject* obj) { * void foo(JSContext* cx, JSObject* obj) {
* // in 'oldRealm' * // in 'oldRealm'
* JSCompartment* oldRealm = JS::EnterRealm(cx, obj); * JS::Realm* oldRealm = JS::EnterRealm(cx, obj);
* // in the realm of 'obj' * // in the realm of 'obj'
* JS::LeaveRealm(cx, oldRealm); * JS::LeaveRealm(cx, oldRealm);
* // back in 'oldRealm' * // back in 'oldRealm'
@ -1089,10 +1089,10 @@ namespace JS {
/** NB: This API is infallible; a nullptr return value does not indicate error. /** NB: This API is infallible; a nullptr return value does not indicate error.
* *
* Entering a compartment roots the compartment and its global object until the * Entering a realm roots the realm and its global object until the matching
* matching JS::LeaveRealm() call. * JS::LeaveRealm() call.
*/ */
extern JS_PUBLIC_API(JSCompartment*) extern JS_PUBLIC_API(JS::Realm*)
EnterRealm(JSContext* cx, JSObject* target); EnterRealm(JSContext* cx, JSObject* target);
extern JS_PUBLIC_API(void) extern JS_PUBLIC_API(void)

View file

@ -613,6 +613,7 @@ js::RemapWrapper(JSContext* cx, JSObject* wobjArg, JSObject* newTargetArg)
MOZ_ASSERT(!JS_IsDeadWrapper(origTarget), MOZ_ASSERT(!JS_IsDeadWrapper(origTarget),
"We don't want a dead proxy in the wrapper map"); "We don't want a dead proxy in the wrapper map");
Value origv = ObjectValue(*origTarget); Value origv = ObjectValue(*origTarget);
Realm* wrealm = wobj->realm();
JSCompartment* wcompartment = wobj->compartment(); JSCompartment* wcompartment = wobj->compartment();
AutoDisableProxyCheck adpc; AutoDisableProxyCheck adpc;
@ -637,7 +638,7 @@ js::RemapWrapper(JSContext* cx, JSObject* wobjArg, JSObject* newTargetArg)
// wrapper, |wobj|, since it's been nuked anyway. The wrap() function has // wrapper, |wobj|, since it's been nuked anyway. The wrap() function has
// the choice to reuse |wobj| or not. // the choice to reuse |wobj| or not.
RootedObject tobj(cx, newTarget); RootedObject tobj(cx, newTarget);
AutoRealmUnchecked ar(cx, wcompartment); AutoRealmUnchecked ar(cx, wrealm);
if (!wcompartment->rewrap(cx, &tobj, wobj)) if (!wcompartment->rewrap(cx, &tobj, wobj))
MOZ_CRASH(); MOZ_CRASH();

View file

@ -2395,8 +2395,7 @@ class MOZ_RAII ExecutionObservableRealms : public Debugger::ExecutionObservableS
// AbstractFramePtr can't refer to non-remateralized Ion frames or // AbstractFramePtr can't refer to non-remateralized Ion frames or
// non-debuggee wasm frames, so if iter refers to one such, we know we // non-debuggee wasm frames, so if iter refers to one such, we know we
// don't match. // don't match.
return iter.hasUsableAbstractFramePtr() && return iter.hasUsableAbstractFramePtr() && realms_.has(iter.realm());
realms_.has(JS::GetRealmForCompartment(iter.compartment()));
} }
MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
@ -3745,7 +3744,7 @@ Debugger::addAllGlobalsAsDebuggees(JSContext* cx, unsigned argc, Value* vp)
for (RealmsInZoneIter r(zone); !r.done(); r.next()) { for (RealmsInZoneIter r(zone); !r.done(); r.next()) {
if (r == dbg->object->realm() || r->creationOptions().invisibleToDebugger()) if (r == dbg->object->realm() || r->creationOptions().invisibleToDebugger())
continue; continue;
JS::GetCompartmentForRealm(r)->scheduledForDestruction = false; r->compartment()->scheduledForDestruction = false;
GlobalObject* global = r->maybeGlobal(); GlobalObject* global = r->maybeGlobal();
if (global) { if (global) {
Rooted<GlobalObject*> rg(cx, global); Rooted<GlobalObject*> rg(cx, global);
@ -4962,7 +4961,7 @@ Debugger::findAllGlobals(JSContext* cx, unsigned argc, Value* vp)
if (r->creationOptions().invisibleToDebugger()) if (r->creationOptions().invisibleToDebugger())
continue; continue;
JS::GetCompartmentForRealm(r)->scheduledForDestruction = false; r->compartment()->scheduledForDestruction = false;
GlobalObject* global = r->maybeGlobal(); GlobalObject* global = r->maybeGlobal();

View file

@ -506,13 +506,13 @@ GlobalObject::new_(JSContext* cx, const Class* clasp, JSPrincipals* principals,
MOZ_ASSERT(!cx->isExceptionPending()); MOZ_ASSERT(!cx->isExceptionPending());
MOZ_ASSERT_IF(cx->realm(), !cx->realm()->isAtomsRealm()); MOZ_ASSERT_IF(cx->realm(), !cx->realm()->isAtomsRealm());
JSCompartment* compartment = NewCompartment(cx, principals, options); Realm* realm = NewRealm(cx, principals, options);
if (!compartment) if (!realm)
return nullptr; return nullptr;
Rooted<GlobalObject*> global(cx); Rooted<GlobalObject*> global(cx);
{ {
AutoRealmUnchecked ar(cx, compartment); AutoRealmUnchecked ar(cx, realm);
global = GlobalObject::createInternal(cx, clasp); global = GlobalObject::createInternal(cx, clasp);
if (!global) if (!global)
return nullptr; return nullptr;

View file

@ -219,7 +219,7 @@ GetSelectorRuntime(const CompilationSelector& selector)
struct Matcher struct Matcher
{ {
JSRuntime* match(JSScript* script) { return script->runtimeFromMainThread(); } JSRuntime* match(JSScript* script) { return script->runtimeFromMainThread(); }
JSRuntime* match(JSCompartment* comp) { return comp->runtimeFromMainThread(); } JSRuntime* match(Realm* realm) { return realm->runtimeFromMainThread(); }
JSRuntime* match(Zone* zone) { return zone->runtimeFromMainThread(); } JSRuntime* match(Zone* zone) { return zone->runtimeFromMainThread(); }
JSRuntime* match(ZonesInState zbs) { return zbs.runtime; } JSRuntime* match(ZonesInState zbs) { return zbs.runtime; }
JSRuntime* match(JSRuntime* runtime) { return runtime; } JSRuntime* match(JSRuntime* runtime) { return runtime; }
@ -236,7 +236,7 @@ JitDataStructuresExist(const CompilationSelector& selector)
struct Matcher struct Matcher
{ {
bool match(JSScript* script) { return !!script->realm()->jitRealm(); } bool match(JSScript* script) { return !!script->realm()->jitRealm(); }
bool match(JSCompartment* comp) { return !!JS::GetRealmForCompartment(comp)->jitRealm(); } bool match(Realm* realm) { return !!realm->jitRealm(); }
bool match(Zone* zone) { return !!zone->jitZone(); } bool match(Zone* zone) { return !!zone->jitZone(); }
bool match(ZonesInState zbs) { return zbs.runtime->hasJitRuntime(); } bool match(ZonesInState zbs) { return zbs.runtime->hasJitRuntime(); }
bool match(JSRuntime* runtime) { return runtime->hasJitRuntime(); } bool match(JSRuntime* runtime) { return runtime->hasJitRuntime(); }
@ -255,7 +255,7 @@ IonBuilderMatches(const CompilationSelector& selector, jit::IonBuilder* builder)
jit::IonBuilder* builder_; jit::IonBuilder* builder_;
bool match(JSScript* script) { return script == builder_->script(); } bool match(JSScript* script) { return script == builder_->script(); }
bool match(JSCompartment* comp) { return comp == builder_->script()->compartment(); } bool match(Realm* realm) { return realm == builder_->script()->realm(); }
bool match(Zone* zone) { return zone == builder_->script()->zone(); } bool match(Zone* zone) { return zone == builder_->script()->zone(); }
bool match(JSRuntime* runtime) { return runtime == builder_->script()->runtimeFromAnyThread(); } bool match(JSRuntime* runtime) { return runtime == builder_->script()->runtimeFromAnyThread(); }
bool match(AllCompilations all) { return true; } bool match(AllCompilations all) { return true; }
@ -343,36 +343,36 @@ js::CancelOffThreadIonCompile(const CompilationSelector& selector, bool discardL
#ifdef DEBUG #ifdef DEBUG
bool bool
js::HasOffThreadIonCompile(JSCompartment* comp) js::HasOffThreadIonCompile(Realm* realm)
{ {
AutoLockHelperThreadState lock; AutoLockHelperThreadState lock;
if (!HelperThreadState().threads || JS::GetRealmForCompartment(comp)->isAtomsRealm()) if (!HelperThreadState().threads || realm->isAtomsRealm())
return false; return false;
GlobalHelperThreadState::IonBuilderVector& worklist = HelperThreadState().ionWorklist(lock); GlobalHelperThreadState::IonBuilderVector& worklist = HelperThreadState().ionWorklist(lock);
for (size_t i = 0; i < worklist.length(); i++) { for (size_t i = 0; i < worklist.length(); i++) {
jit::IonBuilder* builder = worklist[i]; jit::IonBuilder* builder = worklist[i];
if (builder->script()->compartment() == comp) if (builder->script()->realm() == realm)
return true; return true;
} }
for (auto& helper : *HelperThreadState().threads) { for (auto& helper : *HelperThreadState().threads) {
if (helper.ionBuilder() && helper.ionBuilder()->script()->compartment() == comp) if (helper.ionBuilder() && helper.ionBuilder()->script()->realm() == realm)
return true; return true;
} }
GlobalHelperThreadState::IonBuilderVector& finished = HelperThreadState().ionFinishedList(lock); GlobalHelperThreadState::IonBuilderVector& finished = HelperThreadState().ionFinishedList(lock);
for (size_t i = 0; i < finished.length(); i++) { for (size_t i = 0; i < finished.length(); i++) {
jit::IonBuilder* builder = finished[i]; jit::IonBuilder* builder = finished[i];
if (builder->script()->compartment() == comp) if (builder->script()->realm() == realm)
return true; return true;
} }
JSRuntime* rt = comp->runtimeFromMainThread(); JSRuntime* rt = realm->runtimeFromMainThread();
jit::IonBuilder* builder = rt->jitRuntime()->ionLazyLinkList(rt).getFirst(); jit::IonBuilder* builder = rt->jitRuntime()->ionLazyLinkList(rt).getFirst();
while (builder) { while (builder) {
if (builder->script()->compartment() == comp) if (builder->script()->realm() == realm)
return true; return true;
builder = builder->getNext(); builder = builder->getNext();
} }
@ -1652,7 +1652,7 @@ bool
GlobalHelperThreadState::finishParseTask(JSContext* cx, ParseTaskKind kind, GlobalHelperThreadState::finishParseTask(JSContext* cx, ParseTaskKind kind,
JS::OffThreadToken* token, F&& finishCallback) JS::OffThreadToken* token, F&& finishCallback)
{ {
MOZ_ASSERT(cx->compartment()); MOZ_ASSERT(cx->realm());
ScopedJSDeletePtr<ParseTask> parseTask(removeFinishedParseTask(kind, token)); ScopedJSDeletePtr<ParseTask> parseTask(removeFinishedParseTask(kind, token));
@ -1663,7 +1663,7 @@ GlobalHelperThreadState::finishParseTask(JSContext* cx, ParseTaskKind kind,
return false; return false;
} }
mergeParseTaskCompartment(cx, parseTask, cx->compartment()); mergeParseTaskRealm(cx, parseTask, cx->realm());
bool ok = finishCallback(parseTask); bool ok = finishCallback(parseTask);
@ -1828,18 +1828,17 @@ GlobalHelperThreadState::cancelParseTask(JSRuntime* rt, ParseTaskKind kind,
} }
void void
GlobalHelperThreadState::mergeParseTaskCompartment(JSContext* cx, ParseTask* parseTask, GlobalHelperThreadState::mergeParseTaskRealm(JSContext* cx, ParseTask* parseTask, Realm* dest)
JSCompartment* dest)
{ {
// After we call LeaveParseTaskZone() it's not safe to GC until we have // After we call LeaveParseTaskZone() it's not safe to GC until we have
// finished merging the contents of the parse task's compartment into the // finished merging the contents of the parse task's realm into the
// destination compartment. // destination realm.
JS::AutoAssertNoGC nogc(cx); JS::AutoAssertNoGC nogc(cx);
LeaveParseTaskZone(cx->runtime(), parseTask); LeaveParseTaskZone(cx->runtime(), parseTask);
// Move the parsed script and all its contents into the desired compartment. // Move the parsed script and all its contents into the desired realm.
gc::MergeCompartments(parseTask->parseGlobal->compartment(), dest); gc::MergeRealms(parseTask->parseGlobal->realm(), dest);
} }
void void

View file

@ -305,7 +305,7 @@ class GlobalHelperThreadState
void cancelParseTask(JSRuntime* rt, ParseTaskKind kind, JS::OffThreadToken* token); void cancelParseTask(JSRuntime* rt, ParseTaskKind kind, JS::OffThreadToken* token);
void mergeParseTaskCompartment(JSContext* cx, ParseTask* parseTask, JSCompartment* dest); void mergeParseTaskRealm(JSContext* cx, ParseTask* parseTask, JS::Realm* dest);
void trace(JSTracer* trc, js::gc::AutoTraceSession& session); void trace(JSTracer* trc, js::gc::AutoTraceSession& session);
@ -529,7 +529,7 @@ struct ZonesInState { JSRuntime* runtime; JS::Zone::GCState state; };
struct CompilationsUsingNursery { JSRuntime* runtime; }; struct CompilationsUsingNursery { JSRuntime* runtime; };
using CompilationSelector = mozilla::Variant<JSScript*, using CompilationSelector = mozilla::Variant<JSScript*,
JSCompartment*, JS::Realm*,
Zone*, Zone*,
ZonesInState, ZonesInState,
JSRuntime*, JSRuntime*,
@ -549,9 +549,9 @@ CancelOffThreadIonCompile(JSScript* script)
} }
inline void inline void
CancelOffThreadIonCompile(JSCompartment* comp) CancelOffThreadIonCompile(JS::Realm* realm)
{ {
CancelOffThreadIonCompile(CompilationSelector(comp), true); CancelOffThreadIonCompile(CompilationSelector(realm), true);
} }
inline void inline void
@ -580,7 +580,7 @@ CancelOffThreadIonCompilesUsingNurseryPointers(JSRuntime* runtime)
#ifdef DEBUG #ifdef DEBUG
bool bool
HasOffThreadIonCompile(JSCompartment* comp); HasOffThreadIonCompile(JS::Realm* realm);
#endif #endif
/* Cancel all scheduled, in progress or finished parses for runtime. */ /* Cancel all scheduled, in progress or finished parses for runtime. */

View file

@ -91,8 +91,8 @@ js::AutoAtomsRealm::AutoAtomsRealm(JSContext* cx,
: AutoRealm(cx, cx->atomsRealm(lock), lock) : AutoRealm(cx, cx->atomsRealm(lock), lock)
{} {}
js::AutoRealmUnchecked::AutoRealmUnchecked(JSContext* cx, JSCompartment* target) js::AutoRealmUnchecked::AutoRealmUnchecked(JSContext* cx, JS::Realm* target)
: AutoRealm(cx, JS::GetRealmForCompartment(target)) : AutoRealm(cx, target)
{} {}
inline bool inline bool

View file

@ -904,6 +904,10 @@ class JS::Realm : private JSCompartment
size_t* privateData, size_t* privateData,
size_t* scriptCountsMapArg); size_t* scriptCountsMapArg);
JSCompartment* compartment() {
return this;
}
JS::Zone* zone() { JS::Zone* zone() {
return zone_; return zone_;
} }
@ -1384,7 +1388,7 @@ class AutoAtomsRealm : protected AutoRealm
class AutoRealmUnchecked : protected AutoRealm class AutoRealmUnchecked : protected AutoRealm
{ {
public: public:
inline AutoRealmUnchecked(JSContext* cx, JSCompartment* target); inline AutoRealmUnchecked(JSContext* cx, JS::Realm* target);
}; };
/* /*

View file

@ -32,7 +32,7 @@ class CompilerConstraintList;
class ObjectGroupRealm; class ObjectGroupRealm;
namespace gc { namespace gc {
void MergeCompartments(JSCompartment* source, JSCompartment* target); void MergeRealms(JS::Realm* source, JS::Realm* target);
} // namespace gc } // namespace gc
/* /*

View file

@ -225,7 +225,7 @@ JSRuntime::init(JSContext* cx, uint32_t maxbytes, uint32_t maxNurseryBytes)
return false; return false;
gc.atomsZone = atomsZone.get(); gc.atomsZone = atomsZone.get();
if (!atomsZone->compartments().append(JS::GetCompartmentForRealm(atomsRealm.get()))) if (!atomsZone->compartments().append(atomsRealm->compartment()))
return false; return false;
atomsRealm->setIsSystem(true); atomsRealm->setIsSystem(true);

View file

@ -1474,7 +1474,7 @@ SavedStacks::insertFrames(JSContext* cx, MutableHandleSavedFrame frame,
// needed to construct the SavedFrame::Lookup. // needed to construct the SavedFrame::Lookup.
Rooted<LocationValue> location(cx); Rooted<LocationValue> location(cx);
{ {
AutoRealmUnchecked ar(cx, iter.compartment()); AutoRealmUnchecked ar(cx, iter.realm());
if (!cx->realm()->savedStacks().getLocation(cx, iter, &location)) if (!cx->realm()->savedStacks().getLocation(cx, iter, &location))
return false; return false;
} }

View file

@ -2791,12 +2791,10 @@ JSRuntime::createSelfHostingGlobal(JSContext* cx)
options.creationOptions().setNewZone(); options.creationOptions().setNewZone();
options.behaviors().setDiscardSource(true); options.behaviors().setDiscardSource(true);
JSCompartment* compartment = NewCompartment(cx, nullptr, options); Realm* realm = NewRealm(cx, nullptr, options);
if (!compartment) if (!realm)
return nullptr; return nullptr;
JS::Realm* realm = JS::GetRealmForCompartment(compartment);
static const ClassOps shgClassOps = { static const ClassOps shgClassOps = {
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
@ -2809,7 +2807,7 @@ JSRuntime::createSelfHostingGlobal(JSContext* cx)
&shgClassOps &shgClassOps
}; };
AutoRealmUnchecked ar(cx, compartment); AutoRealmUnchecked ar(cx, realm);
Rooted<GlobalObject*> shg(cx, GlobalObject::createInternal(cx, &shgClass)); Rooted<GlobalObject*> shg(cx, GlobalObject::createInternal(cx, &shgClass));
if (!shg) if (!shg)
return nullptr; return nullptr;

View file

@ -451,7 +451,6 @@ class BaseShape : public gc::TenuredCell
friend class Shape; friend class Shape;
friend struct StackBaseShape; friend struct StackBaseShape;
friend struct StackShape; friend struct StackShape;
friend void gc::MergeCompartments(JSCompartment* source, JSCompartment* target);
enum Flag { enum Flag {
/* Owned by the referring shape. */ /* Owned by the referring shape. */

View file

@ -901,6 +901,17 @@ FrameIter::compartment() const
MOZ_CRASH("Unexpected state"); MOZ_CRASH("Unexpected state");
} }
Realm*
FrameIter::realm() const
{
MOZ_ASSERT(!done());
if (hasScript())
return script()->realm();
return wasmInstance()->realm();
}
bool bool
FrameIter::isEvalFrame() const FrameIter::isEvalFrame() const
{ {
@ -1622,9 +1633,9 @@ jit::JitActivation::getRematerializedFrame(JSContext* cx, const JSJitFrameIter&
MaybeReadFallback recover(cx, this, &iter); MaybeReadFallback recover(cx, this, &iter);
// Frames are often rematerialized with the cx inside a Debugger's // Frames are often rematerialized with the cx inside a Debugger's
// compartment. To recover slots and to create CallObjects, we need to // realm. To recover slots and to create CallObjects, we need to
// be in the activation's compartment. // be in the script's realm.
AutoRealmUnchecked ar(cx, compartment_); AutoRealmUnchecked ar(cx, iter.script()->realm());
if (!RematerializedFrame::RematerializeInlineFrames(cx, top, inlineIter, recover, frames)) if (!RematerializedFrame::RematerializeInlineFrames(cx, top, inlineIter, recover, frames))
return nullptr; return nullptr;

View file

@ -2045,6 +2045,7 @@ class FrameIter
FrameIter& operator++(); FrameIter& operator++();
JS::Realm* realm() const;
JSCompartment* compartment() const; JSCompartment* compartment() const;
Activation* activation() const { return data_.activations_.activation(); } Activation* activation() const { return data_.activations_.activation(); }

View file

@ -4417,10 +4417,10 @@ ObjectGroup::sweep(const AutoSweepObjectGroup& sweep, AutoClearTypeInferenceStat
if (auto* layout = maybeUnboxedLayout(sweep)) { if (auto* layout = maybeUnboxedLayout(sweep)) {
// Remove unboxed layouts that are about to be finalized from the // Remove unboxed layouts that are about to be finalized from the
// compartment wide list while we are still on the main thread. // realm wide list while we are still on the main thread.
ObjectGroup* group = this; ObjectGroup* group = this;
if (IsAboutToBeFinalizedUnbarriered(&group)) if (IsAboutToBeFinalizedUnbarriered(&group))
layout->detachFromCompartment(); layout->detachFromRealm();
if (layout->newScript()) if (layout->newScript())
layout->newScript()->sweep(); layout->newScript()->sweep();

View file

@ -305,7 +305,7 @@ UnboxedLayout::makeConstructorCode(JSContext* cx, HandleObjectGroup group)
} }
void void
UnboxedLayout::detachFromCompartment() UnboxedLayout::detachFromRealm()
{ {
if (isInList()) if (isInList())
remove(); remove();

View file

@ -124,7 +124,7 @@ class UnboxedLayout : public mozilla::LinkedListElement<UnboxedLayout>
constructorCode_.init(nullptr); constructorCode_.init(nullptr);
} }
void detachFromCompartment(); void detachFromRealm();
const PropertyVector& properties() const { const PropertyVector& properties() const {
return properties_; return properties_;

View file

@ -954,7 +954,7 @@ HandleFault(PEXCEPTION_POINTERS exception)
if (!IsHeapAccessAddress(*instance, faultingAddress)) if (!IsHeapAccessAddress(*instance, faultingAddress))
return false; return false;
MOZ_ASSERT(activation->compartment() == JS::GetCompartmentForRealm(instance->realm())); MOZ_ASSERT(activation->compartment() == instance->realm()->compartment());
return HandleOutOfBounds(context, pc, faultingAddress, moduleSegment, *instance, activation, ppc); return HandleOutOfBounds(context, pc, faultingAddress, moduleSegment, *instance, activation, ppc);
} }
@ -1061,7 +1061,7 @@ HandleMachException(JSContext* cx, const ExceptionRequest& request)
return false; return false;
JitActivation* activation = cx->activation()->asJit(); JitActivation* activation = cx->activation()->asJit();
MOZ_ASSERT(activation->compartment() == JS::GetCompartmentForRealm(instance->realm())); MOZ_ASSERT(activation->compartment() == instance->realm()->compartment());
if (request.body.exception == EXC_BAD_INSTRUCTION) { if (request.body.exception == EXC_BAD_INSTRUCTION) {
Trap trap; Trap trap;
@ -1283,7 +1283,7 @@ HandleFault(int signum, siginfo_t* info, void* ctx)
return false; return false;
JitActivation* activation = TlsContext.get()->activation()->asJit(); JitActivation* activation = TlsContext.get()->activation()->asJit();
MOZ_ASSERT(activation->compartment() == JS::GetCompartmentForRealm(instance->realm())); MOZ_ASSERT(activation->compartment() == instance->realm()->compartment());
if (signum == kWasmTrapSignal) { if (signum == kWasmTrapSignal) {
// Wasm traps for MIPS raise only integer overflow fp exception. // Wasm traps for MIPS raise only integer overflow fp exception.

View file

@ -100,7 +100,7 @@ CreateGlobalAndRunTest(JSContext* cx)
global = JS_NewGlobalObject(cx, &GlobalClass, nullptr, JS::FireOnNewGlobalHook, options); global = JS_NewGlobalObject(cx, &GlobalClass, nullptr, JS::FireOnNewGlobalHook, options);
ASSERT_TRUE(global != nullptr); ASSERT_TRUE(global != nullptr);
JS::Realm* oldRealm = JS::GetRealmForCompartment(JS::EnterRealm(cx, global)); JS::Realm* oldRealm = JS::EnterRealm(cx, global);
typedef Heap<JSObject*> ElementT; typedef Heap<JSObject*> ElementT;