Bug 1464134 part 1 - Fix various places to use Realm instead of JSCompartment. r=luke
authorJan de Mooij <jdemooij@mozilla.com>
Sun, 27 May 2018 11:53:11 +0200
changeset 474284 bf36035bed13ab8fa1777955a299837d3e10d398
parent 474283 698b35dd4f6a7ab5291fd864a282f9cfc79ea45b
child 474285 2435b35bcd6863fadd0007fd73f83079d351743a
push id9374
push userjlund@mozilla.com
push dateMon, 18 Jun 2018 21:43:20 +0000
treeherdermozilla-beta@160e085dfb0b [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersluke
bugs1464134
milestone62.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1464134 part 1 - Fix various places to use Realm instead of JSCompartment. r=luke
js/src/fuzz-tests/tests.cpp
js/src/gc/GC.cpp
js/src/gc/GC.h
js/src/gc/GCRuntime.h
js/src/jit/Ion.cpp
js/src/jsapi.cpp
js/src/jsapi.h
js/src/proxy/CrossCompartmentWrapper.cpp
js/src/vm/Debugger.cpp
js/src/vm/GlobalObject.cpp
js/src/vm/HelperThreads.cpp
js/src/vm/HelperThreads.h
js/src/vm/JSCompartment-inl.h
js/src/vm/JSCompartment.h
js/src/vm/ObjectGroup.h
js/src/vm/Runtime.cpp
js/src/vm/SavedStacks.cpp
js/src/vm/SelfHosting.cpp
js/src/vm/Shape.h
js/src/vm/Stack.cpp
js/src/vm/Stack.h
js/src/vm/TypeInference.cpp
js/src/vm/UnboxedObject.cpp
js/src/vm/UnboxedObject.h
js/src/wasm/WasmSignalHandlers.cpp
xpcom/tests/gtest/TestGCPostBarriers.cpp
--- a/js/src/fuzz-tests/tests.cpp
+++ b/js/src/fuzz-tests/tests.cpp
@@ -82,22 +82,18 @@ jsfuzz_init(JSContext** cx, JS::Persiste
     *global = jsfuzz_createGlobal(*cx, nullptr);
     if (!*global)
         return false;
     JS::EnterRealm(*cx, *global);
     return true;
 }
 
 static void
-jsfuzz_uninit(JSContext* cx, JSCompartment* oldCompartment)
+jsfuzz_uninit(JSContext* cx)
 {
-    if (oldCompartment) {
-        JS::LeaveRealm(cx, JS::GetRealmForCompartment(oldCompartment));
-        oldCompartment = nullptr;
-    }
     if (cx) {
         JS_EndRequest(cx);
         JS_DestroyContext(cx);
         cx = nullptr;
     }
 }
 
 int
@@ -138,14 +134,14 @@ main(int argc, char* argv[])
     }
 
 #ifdef LIBFUZZER
     fuzzer::FuzzerDriver(&argc, &argv, testingFunc);
 #elif __AFL_COMPILER
     testingFunc(nullptr, 0);
 #endif
 
-    jsfuzz_uninit(gCx, nullptr);
+    jsfuzz_uninit(gCx);
 
     JS_ShutDown();
 
     return 0;
 }
--- a/js/src/gc/GC.cpp
+++ b/js/src/gc/GC.cpp
@@ -7909,19 +7909,18 @@ js::gc::FinishGC(JSContext* cx)
 }
 
 AutoPrepareForTracing::AutoPrepareForTracing(JSContext* cx)
 {
     js::gc::FinishGC(cx);
     session_.emplace(cx->runtime());
 }
 
-JSCompartment*
-js::NewCompartment(JSContext* cx, JSPrincipals* principals,
-                   const JS::RealmOptions& options)
+Realm*
+js::NewRealm(JSContext* cx, JSPrincipals* principals, const JS::RealmOptions& options)
 {
     JSRuntime* rt = cx->runtime();
     JS_AbortIfWrongThread(cx);
 
     ScopedJSDeletePtr<Zone> zoneHolder;
 
     Zone* zone = nullptr;
     JS::ZoneSpecifier zoneSpec = options.creationOptions().zoneSpecifier();
@@ -7978,103 +7977,101 @@ js::NewCompartment(JSContext* cx, JSPrin
         if (zoneSpec == JS::SystemZone) {
             MOZ_RELEASE_ASSERT(!rt->gc.systemZone);
             rt->gc.systemZone = zone;
             zone->isSystem = true;
         }
     }
 
     zoneHolder.forget();
-    return JS::GetCompartmentForRealm(realm.forget());
-}
-
-void
-gc::MergeCompartments(JSCompartment* source, JSCompartment* target)
+    return realm.forget();
+}
+
+void
+gc::MergeRealms(Realm* source, Realm* target)
 {
     JSRuntime* rt = source->runtimeFromMainThread();
-    rt->gc.mergeCompartments(source, target);
+    rt->gc.mergeRealms(source, target);
 
     AutoLockGC lock(rt);
     rt->gc.maybeAllocTriggerZoneGC(target->zone(), lock);
 }
 
 void
-GCRuntime::mergeCompartments(JSCompartment* source, JSCompartment* target)
+GCRuntime::mergeRealms(Realm* source, Realm* target)
 {
     // The source realm must be specifically flagged as mergable.  This
     // also implies that the realm is not visible to the debugger.
-    Realm* sourceRealm = JS::GetRealmForCompartment(source);
-    Realm* targetRealm = JS::GetRealmForCompartment(target);
-    MOZ_ASSERT(sourceRealm->creationOptions().mergeable());
-    MOZ_ASSERT(sourceRealm->creationOptions().invisibleToDebugger());
-
-    MOZ_ASSERT(!sourceRealm->hasBeenEntered());
+    MOZ_ASSERT(source->creationOptions().mergeable());
+    MOZ_ASSERT(source->creationOptions().invisibleToDebugger());
+
+    MOZ_ASSERT(!source->hasBeenEntered());
     MOZ_ASSERT(source->zone()->compartments().length() == 1);
 
     JSContext* cx = rt->mainContextFromOwnThread();
 
     MOZ_ASSERT(!source->zone()->wasGCStarted());
     JS::AutoAssertNoGC nogc(cx);
 
     AutoTraceSession session(rt);
 
     // Cleanup tables and other state in the source realm/zone that will be
     // meaningless after merging into the target realm/zone.
 
-    sourceRealm->clearTables();
+    source->clearTables();
     source->zone()->clearTables();
-    sourceRealm->unsetIsDebuggee();
+    source->unsetIsDebuggee();
 
     // The delazification flag indicates the presence of LazyScripts in a
     // realm for the Debugger API, so if the source realm created LazyScripts,
     // the flag must be propagated to the target realm.
-    if (sourceRealm->needsDelazificationForDebugger())
-        targetRealm->scheduleDelazificationForDebugger();
+    if (source->needsDelazificationForDebugger())
+        target->scheduleDelazificationForDebugger();
 
     // Release any relocated arenas which we may be holding on to as they might
     // be in the source zone
     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.
 
     for (auto script = source->zone()->cellIter<JSScript>(); !script.done(); script.next()) {
-        MOZ_ASSERT(script->compartment() == source);
-        script->realm_ = JS::GetRealmForCompartment(target);
+        MOZ_ASSERT(script->realm() == source);
+        script->realm_ = target;
         script->setTypesGeneration(target->zone()->types.generation);
     }
 
-    GlobalObject* global = targetRealm->maybeGlobal();
+    GlobalObject* global = target->maybeGlobal();
     MOZ_ASSERT(global);
 
     for (auto group = source->zone()->cellIter<ObjectGroup>(); !group.done(); group.next()) {
         // Replace placeholder object prototypes with the correct prototype in
-        // the target compartment.
+        // the target realm.
         TaggedProto proto(group->proto());
         if (proto.isObject()) {
             JSObject* obj = proto.toObject();
             if (GlobalObject::isOffThreadPrototypePlaceholder(obj)) {
                 JSObject* targetProto = global->getPrototypeForOffThreadPlaceholder(obj);
                 MOZ_ASSERT(targetProto->isDelegate());
                 MOZ_ASSERT_IF(targetProto->staticPrototypeIsImmutable(),
                               obj->staticPrototypeIsImmutable());
                 MOZ_ASSERT_IF(targetProto->isNewGroupUnknown(),
                               obj->isNewGroupUnknown());
                 group->setProtoUnchecked(TaggedProto(targetProto));
             }
         }
 
         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
-        // compartment. These do not need to be reinserted in the target
-        // compartment's list, as the list is not required to be complete.
+        // realm. These do not need to be reinserted in the target
+        // realm's list, as the list is not required to be complete.
         if (UnboxedLayout* layout = group->maybeUnboxedLayoutDontCheckGeneration())
-            layout->detachFromCompartment();
+            layout->detachFromRealm();
     }
 
     // Fixup zone pointers in source's zone to refer to target's zone.
 
     bool targetZoneIsCollecting = isIncrementalGCInProgress() && target->zone()->wasGCStarted();
     for (auto thingKind : AllAllocKinds()) {
         for (ArenaIter aiter(source->zone(), thingKind); !aiter.done(); aiter.next()) {
             Arena* arena = aiter.get();
@@ -8087,64 +8084,64 @@ GCRuntime::mergeCompartments(JSCompartme
                     TenuredCell* cell = iter.getCell();
                     MOZ_ASSERT(!cell->isMarkedAny());
                     cell->markBlack();
                 }
             }
         }
     }
 
-    // The source should be the only compartment in its zone.
-    for (CompartmentsInZoneIter c(source->zone()); !c.done(); c.next())
-        MOZ_ASSERT(c.get() == source);
+    // The source should be the only realm in its zone.
+    for (RealmsInZoneIter r(source->zone()); !r.done(); r.next())
+        MOZ_ASSERT(r.get() == source);
 
     // 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()->usage.adopt(source->zone()->usage);
     target->zone()->adoptUniqueIds(source->zone());
     target->zone()->adoptMallocBytes(source->zone());
 
     // Merge other info in source's zone into target's zone.
     target->zone()->types.typeLifoAlloc().transferFrom(&source->zone()->types.typeLifoAlloc());
     MOZ_RELEASE_ASSERT(source->zone()->types.sweepTypeLifoAlloc.ref().isEmpty());
 
     // Atoms which are marked in source's zone are now marked in target's zone.
     atomMarking.adoptMarkedAtoms(target->zone(), source->zone());
 
-    // Merge script name maps in the target compartment's map.
-    if (rt->lcovOutput().isEnabled() && sourceRealm->scriptNameMap) {
+    // Merge script name maps in the target realm's map.
+    if (rt->lcovOutput().isEnabled() && source->scriptNameMap) {
         AutoEnterOOMUnsafeRegion oomUnsafe;
 
-        if (!targetRealm->scriptNameMap) {
-            targetRealm->scriptNameMap = cx->make_unique<ScriptNameMap>();
-
-            if (!targetRealm->scriptNameMap)
+        if (!target->scriptNameMap) {
+            target->scriptNameMap = cx->make_unique<ScriptNameMap>();
+
+            if (!target->scriptNameMap)
                 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.");
         }
 
-        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();
             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.");
         }
 
-        sourceRealm->scriptNameMap->clear();
-    }
-
-    // The source compartment is now completely empty, and is the only
-    // compartment in its zone, which is the only zone in its group. Delete
-    // compartment, zone and group without waiting for this to be cleaned up by
-    // a full GC.
+        source->scriptNameMap->clear();
+    }
+
+    // The source realm is now completely empty, and is the only realm in its
+    // compartment, which is the only compartment in its zone. Delete realm,
+    // compartment and zone without waiting for this to be cleaned up by a full
+    // GC.
 
     Zone* sourceZone = source->zone();
-    sourceZone->deleteEmptyCompartment(source);
+    sourceZone->deleteEmptyCompartment(source->compartment());
     deleteEmptyZone(sourceZone);
 }
 
 void
 GCRuntime::runDebugGC()
 {
 #ifdef JS_GC_ZEAL
     if (rt->mainContextFromOwnThread()->suppressGC)
--- a/js/src/gc/GC.h
+++ b/js/src/gc/GC.h
@@ -117,30 +117,29 @@ typedef void (*IterateScriptCallback)(JS
 /*
  * Invoke scriptCallback on every in-use script for
  * the given compartment or for all compartments if it is null.
  */
 extern void
 IterateScripts(JSContext* cx, JSCompartment* compartment,
                void* data, IterateScriptCallback scriptCallback);
 
-JSCompartment*
-NewCompartment(JSContext* cx, JSPrincipals* principals,
-               const JS::RealmOptions& options);
+JS::Realm*
+NewRealm(JSContext* cx, JSPrincipals* principals, const JS::RealmOptions& options);
 
 namespace gc {
 
 void FinishGC(JSContext* cx);
 
 /*
  * 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
-MergeCompartments(JSCompartment* source, JSCompartment* target);
+MergeRealms(JS::Realm* source, JS::Realm* target);
 
 enum VerifierType {
     PreBarrierVerifier
 };
 
 #ifdef JS_GC_ZEAL
 
 extern const char* ZealModeHelpText;
--- a/js/src/gc/GCRuntime.h
+++ b/js/src/gc/GCRuntime.h
@@ -490,17 +490,17 @@ class GCRuntime
     /*
      * Concurrent sweep infrastructure.
      */
     void startTask(GCParallelTask& task, gcstats::PhaseKind phase,
                    AutoLockHelperThreadState& locked);
     void joinTask(GCParallelTask& task, gcstats::PhaseKind phase,
                   AutoLockHelperThreadState& locked);
 
-    void mergeCompartments(JSCompartment* source, JSCompartment* target);
+    void mergeRealms(JS::Realm* source, JS::Realm* target);
 
   private:
     enum IncrementalResult
     {
         Reset = 0,
         Ok
     };
 
--- a/js/src/jit/Ion.cpp
+++ b/js/src/jit/Ion.cpp
@@ -627,17 +627,17 @@ JitRuntime::SweepJitcodeGlobalTable(JSRu
     if (rt->hasJitRuntime() && rt->jitRuntime()->hasJitcodeGlobalTable())
         rt->jitRuntime()->getJitcodeGlobalTable()->sweep(rt);
 }
 
 void
 JitRealm::sweep(JS::Realm* realm)
 {
     // Any outstanding compilations should have been cancelled by the GC.
-    MOZ_ASSERT(!HasOffThreadIonCompile(JS::GetCompartmentForRealm(realm)));
+    MOZ_ASSERT(!HasOffThreadIonCompile(realm));
 
     stubCodes_->sweep();
 
     // If the sweep removed a bailout Fallback stub, nullptr the corresponding return addr.
     for (auto& it : bailoutReturnStubInfo_) {
         if (!stubCodes_->lookup(it.key))
            it = BailoutReturnStubInfo();
     }
@@ -2838,18 +2838,18 @@ InvalidateActivation(FreeOp* fop, const 
     JitSpew(JitSpew_IonInvalidate, "END invalidating activation");
 }
 
 void
 jit::InvalidateAll(FreeOp* fop, Zone* zone)
 {
     // The caller should previously have cancelled off thread compilation.
 #ifdef DEBUG
-    for (CompartmentsInZoneIter comp(zone); !comp.done(); comp.next())
-        MOZ_ASSERT(!HasOffThreadIonCompile(comp));
+    for (RealmsInZoneIter realm(zone); !realm.done(); realm.next())
+        MOZ_ASSERT(!HasOffThreadIonCompile(realm));
 #endif
     if (zone->isAtomsZone())
         return;
     JSContext* cx = TlsContext.get();
     for (JitActivationIterator iter(cx); !iter.done(); ++iter) {
         if (iter->compartment()->zone() == zone) {
             JitSpew(JitSpew_IonInvalidate, "Invalidating all frames for GC");
             InvalidateActivation(fop, iter, true);
--- a/js/src/jsapi.cpp
+++ b/js/src/jsapi.cpp
@@ -669,25 +669,25 @@ JS_SetWrapObjectCallbacks(JSContext* cx,
 }
 
 JS_PUBLIC_API(void)
 JS_SetExternalStringSizeofCallback(JSContext* cx, JSExternalStringSizeofCallback callback)
 {
     cx->runtime()->externalStringSizeofCallback = callback;
 }
 
-JS_PUBLIC_API(JSCompartment*)
+JS_PUBLIC_API(Realm*)
 JS::EnterRealm(JSContext* cx, JSObject* target)
 {
     AssertHeapIsIdle();
     CHECK_REQUEST(cx);
 
     Realm* oldRealm = cx->realm();
     cx->enterRealmOf(target);
-    return JS::GetCompartmentForRealm(oldRealm);
+    return oldRealm;
 }
 
 JS_PUBLIC_API(void)
 JS::LeaveRealm(JSContext* cx, JS::Realm* oldRealm)
 {
     AssertHeapIsIdle();
     CHECK_REQUEST(cx);
     cx->leaveRealm(oldRealm);
@@ -885,17 +885,17 @@ JS_TransplantObject(JSContext* cx, Handl
 
     JSCompartment* destination = target->compartment();
 
     if (origobj->compartment() == destination) {
         // If the original object is in the same compartment as the
         // destination, then we know that we won't find a wrapper in the
         // destination's cross compartment map and that the same
         // object will continue to work.
-        AutoRealmUnchecked ar(cx, origobj->compartment());
+        AutoRealmUnchecked ar(cx, origobj->realm());
         if (!JSObject::swap(cx, origobj, target))
             MOZ_CRASH();
         newIdentity = origobj;
     } else if (WrapperMap::Ptr p = destination->lookupWrapper(origv)) {
         // There might already be a wrapper for the original object in
         // the new compartment. If there is, we use its identity and swap
         // in the contents of |target|.
         newIdentity = &p->value().get().toObject();
@@ -919,17 +919,17 @@ JS_TransplantObject(JSContext* cx, Handl
     // `newIdentity == origobj`, because this process also clears out any
     // cached wrapper state.
     if (!RemapAllWrappersForObject(cx, origobj, newIdentity))
         MOZ_CRASH();
 
     // Lastly, update the original object to point to the new one.
     if (origobj->compartment() != destination) {
         RootedObject newIdentityWrapper(cx, newIdentity);
-        AutoRealmUnchecked ar(cx, origobj->compartment());
+        AutoRealmUnchecked ar(cx, origobj->realm());
         if (!JS_WrapObject(cx, &newIdentityWrapper))
             MOZ_CRASH();
         MOZ_ASSERT(Wrapper::wrappedObject(newIdentityWrapper) == newIdentity);
         if (!JSObject::swap(cx, origobj, newIdentityWrapper))
             MOZ_CRASH();
         if (!origobj->compartment()->putWrapper(cx, CrossCompartmentKey(newIdentity), origv))
             MOZ_CRASH();
     }
--- a/js/src/jsapi.h
+++ b/js/src/jsapi.h
@@ -1041,17 +1041,17 @@ JS_RefreshCrossCompartmentWrappers(JSCon
  *     // back in realm 'r'
  *   }
  *
  * For more complicated uses that don't neatly fit in a C++ stack frame, the
  * realm can be entered and left using separate function calls:
  *
  *   void foo(JSContext* cx, JSObject* obj) {
  *     // in 'oldRealm'
- *     JSCompartment* oldRealm = JS::EnterRealm(cx, obj);
+ *     JS::Realm* oldRealm = JS::EnterRealm(cx, obj);
  *     // in the realm of 'obj'
  *     JS::LeaveRealm(cx, oldRealm);
  *     // back in 'oldRealm'
  *   }
  *
  * Note: these calls must still execute in a LIFO manner w.r.t all other
  * enter/leave calls on the context. Furthermore, only the return value of a
  * JS::EnterRealm call may be passed as the 'oldRealm' argument of
@@ -1084,20 +1084,20 @@ class MOZ_RAII JS_PUBLIC_API(JSAutoNulla
 
     MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
 };
 
 namespace JS {
 
 /** 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
- * matching JS::LeaveRealm() call.
- */
-extern JS_PUBLIC_API(JSCompartment*)
+ * Entering a realm roots the realm and its global object until the matching
+ * JS::LeaveRealm() call.
+ */
+extern JS_PUBLIC_API(JS::Realm*)
 EnterRealm(JSContext* cx, JSObject* target);
 
 extern JS_PUBLIC_API(void)
 LeaveRealm(JSContext* cx, JS::Realm* oldRealm);
 
 } // namespace JS
 
 typedef void (*JSIterateCompartmentCallback)(JSContext* cx, void* data, JSCompartment* compartment);
--- a/js/src/proxy/CrossCompartmentWrapper.cpp
+++ b/js/src/proxy/CrossCompartmentWrapper.cpp
@@ -608,16 +608,17 @@ js::RemapWrapper(JSContext* cx, JSObject
     RootedObject newTarget(cx, newTargetArg);
     MOZ_ASSERT(wobj->is<CrossCompartmentWrapperObject>());
     MOZ_ASSERT(!newTarget->is<CrossCompartmentWrapperObject>());
     JSObject* origTarget = Wrapper::wrappedObject(wobj);
     MOZ_ASSERT(origTarget);
     MOZ_ASSERT(!JS_IsDeadWrapper(origTarget),
                "We don't want a dead proxy in the wrapper map");
     Value origv = ObjectValue(*origTarget);
+    Realm* wrealm = wobj->realm();
     JSCompartment* wcompartment = wobj->compartment();
 
     AutoDisableProxyCheck adpc;
 
     // If we're mapping to a different target (as opposed to just recomputing
     // for the same target), we must not have an existing wrapper for the new
     // target, otherwise this will break.
     MOZ_ASSERT_IF(origTarget != newTarget,
@@ -632,17 +633,17 @@ js::RemapWrapper(JSContext* cx, JSObject
     // When we remove origv from the wrapper map, its wrapper, wobj, must
     // immediately cease to be a cross-compartment wrapper. Nuke it.
     NukeCrossCompartmentWrapper(cx, wobj);
 
     // First, we wrap it in the new compartment. We try to use the existing
     // wrapper, |wobj|, since it's been nuked anyway. The wrap() function has
     // the choice to reuse |wobj| or not.
     RootedObject tobj(cx, newTarget);
-    AutoRealmUnchecked ar(cx, wcompartment);
+    AutoRealmUnchecked ar(cx, wrealm);
     if (!wcompartment->rewrap(cx, &tobj, wobj))
         MOZ_CRASH();
 
     // If wrap() reused |wobj|, it will have overwritten it and returned with
     // |tobj == wobj|. Otherwise, |tobj| will point to a new wrapper and |wobj|
     // will still be nuked. In the latter case, we replace |wobj| with the
     // contents of the new wrapper in |tobj|.
     if (tobj != wobj) {
--- a/js/src/vm/Debugger.cpp
+++ b/js/src/vm/Debugger.cpp
@@ -2390,18 +2390,17 @@ class MOZ_RAII ExecutionObservableRealms
     const HashSet<Zone*>* zones() const override { return &zones_; }
     bool shouldRecompileOrInvalidate(JSScript* script) const override {
         return script->hasBaselineScript() && realms_.has(script->realm());
     }
     bool shouldMarkAsDebuggee(FrameIter& iter) const override {
         // AbstractFramePtr can't refer to non-remateralized Ion frames or
         // non-debuggee wasm frames, so if iter refers to one such, we know we
         // don't match.
-        return iter.hasUsableAbstractFramePtr() &&
-               realms_.has(JS::GetRealmForCompartment(iter.compartment()));
+        return iter.hasUsableAbstractFramePtr() && realms_.has(iter.realm());
     }
 
     MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
 };
 
 // Given a particular AbstractFramePtr F that has become observable, this
 // represents the stack frames that need to be bailed out or marked as
 // debuggees, and the scripts that need to be recompiled, taking inlining into
@@ -3740,17 +3739,17 @@ Debugger::addDebuggee(JSContext* cx, uns
 /* static */ bool
 Debugger::addAllGlobalsAsDebuggees(JSContext* cx, unsigned argc, Value* vp)
 {
     THIS_DEBUGGER(cx, argc, vp, "addAllGlobalsAsDebuggees", args, dbg);
     for (ZonesIter zone(cx->runtime(), SkipAtoms); !zone.done(); zone.next()) {
         for (RealmsInZoneIter r(zone); !r.done(); r.next()) {
             if (r == dbg->object->realm() || r->creationOptions().invisibleToDebugger())
                 continue;
-            JS::GetCompartmentForRealm(r)->scheduledForDestruction = false;
+            r->compartment()->scheduledForDestruction = false;
             GlobalObject* global = r->maybeGlobal();
             if (global) {
                 Rooted<GlobalObject*> rg(cx, global);
                 if (!dbg->addDebuggeeGlobal(cx, rg))
                     return false;
             }
         }
     }
@@ -4957,17 +4956,17 @@ Debugger::findAllGlobals(JSContext* cx, 
         // Accumulate the list of globals before wrapping them, because
         // wrapping can GC and collect realms from under us, while iterating.
         JS::AutoCheckCannotGC nogc;
 
         for (RealmsIter r(cx->runtime(), SkipAtoms); !r.done(); r.next()) {
             if (r->creationOptions().invisibleToDebugger())
                 continue;
 
-            JS::GetCompartmentForRealm(r)->scheduledForDestruction = false;
+            r->compartment()->scheduledForDestruction = false;
 
             GlobalObject* global = r->maybeGlobal();
 
             if (cx->runtime()->isSelfHostingGlobal(global))
                 continue;
 
             if (global) {
                 /*
--- a/js/src/vm/GlobalObject.cpp
+++ b/js/src/vm/GlobalObject.cpp
@@ -501,23 +501,23 @@ GlobalObject::createInternal(JSContext* 
 /* static */ GlobalObject*
 GlobalObject::new_(JSContext* cx, const Class* clasp, JSPrincipals* principals,
                    JS::OnNewGlobalHookOption hookOption,
                    const JS::RealmOptions& options)
 {
     MOZ_ASSERT(!cx->isExceptionPending());
     MOZ_ASSERT_IF(cx->realm(), !cx->realm()->isAtomsRealm());
 
-    JSCompartment* compartment = NewCompartment(cx, principals, options);
-    if (!compartment)
+    Realm* realm = NewRealm(cx, principals, options);
+    if (!realm)
         return nullptr;
 
     Rooted<GlobalObject*> global(cx);
     {
-        AutoRealmUnchecked ar(cx, compartment);
+        AutoRealmUnchecked ar(cx, realm);
         global = GlobalObject::createInternal(cx, clasp);
         if (!global)
             return nullptr;
 
         if (hookOption == JS::FireOnNewGlobalHook)
             JS_FireOnNewGlobalObject(cx, global);
     }
 
--- a/js/src/vm/HelperThreads.cpp
+++ b/js/src/vm/HelperThreads.cpp
@@ -214,34 +214,34 @@ FinishOffThreadIonCompile(jit::IonBuilde
 }
 
 static JSRuntime*
 GetSelectorRuntime(const CompilationSelector& selector)
 {
     struct Matcher
     {
         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(ZonesInState zbs)    { return zbs.runtime; }
         JSRuntime* match(JSRuntime* runtime)  { return runtime; }
         JSRuntime* match(AllCompilations all) { return nullptr; }
         JSRuntime* match(CompilationsUsingNursery cun) { return cun.runtime; }
     };
 
     return selector.match(Matcher());
 }
 
 static bool
 JitDataStructuresExist(const CompilationSelector& selector)
 {
     struct Matcher
     {
         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(ZonesInState zbs)    { return zbs.runtime->hasJitRuntime(); }
         bool match(JSRuntime* runtime)  { return runtime->hasJitRuntime(); }
         bool match(AllCompilations all) { return true; }
         bool match(CompilationsUsingNursery cun) { return cun.runtime->hasJitRuntime(); }
     };
 
     return selector.match(Matcher());
@@ -250,17 +250,17 @@ JitDataStructuresExist(const Compilation
 static bool
 IonBuilderMatches(const CompilationSelector& selector, jit::IonBuilder* builder)
 {
     struct BuilderMatches
     {
         jit::IonBuilder* builder_;
 
         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(JSRuntime* runtime)  { return runtime == builder_->script()->runtimeFromAnyThread(); }
         bool match(AllCompilations all) { return true; }
         bool match(ZonesInState zbs)    {
             return zbs.runtime == builder_->script()->runtimeFromAnyThread() &&
                    zbs.state == builder_->script()->zoneFromAnyThread()->gcState();
         }
         bool match(CompilationsUsingNursery cun) {
@@ -338,46 +338,46 @@ js::CancelOffThreadIonCompile(const Comp
         return;
 
     AutoLockHelperThreadState lock;
     CancelOffThreadIonCompileLocked(selector, discardLazyLinkList, lock);
 }
 
 #ifdef DEBUG
 bool
-js::HasOffThreadIonCompile(JSCompartment* comp)
+js::HasOffThreadIonCompile(Realm* realm)
 {
     AutoLockHelperThreadState lock;
 
-    if (!HelperThreadState().threads || JS::GetRealmForCompartment(comp)->isAtomsRealm())
+    if (!HelperThreadState().threads || realm->isAtomsRealm())
         return false;
 
     GlobalHelperThreadState::IonBuilderVector& worklist = HelperThreadState().ionWorklist(lock);
     for (size_t i = 0; i < worklist.length(); i++) {
         jit::IonBuilder* builder = worklist[i];
-        if (builder->script()->compartment() == comp)
+        if (builder->script()->realm() == realm)
             return true;
     }
 
     for (auto& helper : *HelperThreadState().threads) {
-        if (helper.ionBuilder() && helper.ionBuilder()->script()->compartment() == comp)
+        if (helper.ionBuilder() && helper.ionBuilder()->script()->realm() == realm)
             return true;
     }
 
     GlobalHelperThreadState::IonBuilderVector& finished = HelperThreadState().ionFinishedList(lock);
     for (size_t i = 0; i < finished.length(); i++) {
         jit::IonBuilder* builder = finished[i];
-        if (builder->script()->compartment() == comp)
+        if (builder->script()->realm() == realm)
             return true;
     }
 
-    JSRuntime* rt = comp->runtimeFromMainThread();
+    JSRuntime* rt = realm->runtimeFromMainThread();
     jit::IonBuilder* builder = rt->jitRuntime()->ionLazyLinkList(rt).getFirst();
     while (builder) {
-        if (builder->script()->compartment() == comp)
+        if (builder->script()->realm() == realm)
             return true;
         builder = builder->getNext();
     }
 
     return false;
 }
 #endif
 
@@ -1647,28 +1647,28 @@ GlobalHelperThreadState::removeFinishedP
     return task;
 }
 
 template <typename F, typename>
 bool
 GlobalHelperThreadState::finishParseTask(JSContext* cx, ParseTaskKind kind,
                                          JS::OffThreadToken* token, F&& finishCallback)
 {
-    MOZ_ASSERT(cx->compartment());
+    MOZ_ASSERT(cx->realm());
 
     ScopedJSDeletePtr<ParseTask> parseTask(removeFinishedParseTask(kind, token));
 
     // Make sure we have all the constructors we need for the prototype
     // remapping below, since we can't GC while that's happening.
     if (!EnsureParserCreatedClasses(cx, kind)) {
         LeaveParseTaskZone(cx->runtime(), parseTask);
         return false;
     }
 
-    mergeParseTaskCompartment(cx, parseTask, cx->compartment());
+    mergeParseTaskRealm(cx, parseTask, cx->realm());
 
     bool ok = finishCallback(parseTask);
 
     for (auto& script : parseTask->scripts)
         releaseAssertSameCompartment(cx, script);
 
     if (!parseTask->finish(cx) || !ok)
         return false;
@@ -1823,28 +1823,27 @@ void
 GlobalHelperThreadState::cancelParseTask(JSRuntime* rt, ParseTaskKind kind,
                                          JS::OffThreadToken* token)
 {
     ScopedJSDeletePtr<ParseTask> parseTask(removeFinishedParseTask(kind, token));
     LeaveParseTaskZone(rt, parseTask);
 }
 
 void
-GlobalHelperThreadState::mergeParseTaskCompartment(JSContext* cx, ParseTask* parseTask,
-                                                   JSCompartment* dest)
+GlobalHelperThreadState::mergeParseTaskRealm(JSContext* cx, ParseTask* parseTask, Realm* dest)
 {
     // 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
-    // destination compartment.
+    // finished merging the contents of the parse task's realm into the
+    // destination realm.
     JS::AutoAssertNoGC nogc(cx);
 
     LeaveParseTaskZone(cx->runtime(), parseTask);
 
-    // Move the parsed script and all its contents into the desired compartment.
-    gc::MergeCompartments(parseTask->parseGlobal->compartment(), dest);
+    // Move the parsed script and all its contents into the desired realm.
+    gc::MergeRealms(parseTask->parseGlobal->realm(), dest);
 }
 
 void
 HelperThread::destroy()
 {
     if (thread.isSome()) {
         {
             AutoLockHelperThreadState lock;
--- a/js/src/vm/HelperThreads.h
+++ b/js/src/vm/HelperThreads.h
@@ -300,17 +300,17 @@ class GlobalHelperThreadState
     bool finishParseTask(JSContext* cx, ParseTaskKind kind, JS::OffThreadToken* token, F&& finishCallback);
 
     JSScript* finishParseTask(JSContext* cx, ParseTaskKind kind, JS::OffThreadToken* token);
 
     bool finishParseTask(JSContext* cx, ParseTaskKind kind, JS::OffThreadToken* token, MutableHandle<ScriptVector> scripts);
 
     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);
 
     JSScript* finishScriptParseTask(JSContext* cx, JS::OffThreadToken* token);
     JSScript* finishScriptDecodeTask(JSContext* cx, JS::OffThreadToken* token);
     bool finishMultiScriptsDecodeTask(JSContext* cx, JS::OffThreadToken* token, MutableHandle<ScriptVector> scripts);
     JSObject* finishModuleParseTask(JSContext* cx, JS::OffThreadToken* token);
 
@@ -524,17 +524,17 @@ StartOffThreadIonCompile(jit::IonBuilder
 bool
 StartOffThreadIonFree(jit::IonBuilder* builder, const AutoLockHelperThreadState& lock);
 
 struct AllCompilations {};
 struct ZonesInState { JSRuntime* runtime; JS::Zone::GCState state; };
 struct CompilationsUsingNursery { JSRuntime* runtime; };
 
 using CompilationSelector = mozilla::Variant<JSScript*,
-                                             JSCompartment*,
+                                             JS::Realm*,
                                              Zone*,
                                              ZonesInState,
                                              JSRuntime*,
                                              CompilationsUsingNursery,
                                              AllCompilations>;
 
 /*
  * Cancel scheduled or in progress Ion compilations.
@@ -544,19 +544,19 @@ CancelOffThreadIonCompile(const Compilat
 
 inline void
 CancelOffThreadIonCompile(JSScript* script)
 {
     CancelOffThreadIonCompile(CompilationSelector(script), true);
 }
 
 inline void
-CancelOffThreadIonCompile(JSCompartment* comp)
+CancelOffThreadIonCompile(JS::Realm* realm)
 {
-    CancelOffThreadIonCompile(CompilationSelector(comp), true);
+    CancelOffThreadIonCompile(CompilationSelector(realm), true);
 }
 
 inline void
 CancelOffThreadIonCompile(Zone* zone)
 {
     CancelOffThreadIonCompile(CompilationSelector(zone), true);
 }
 
@@ -575,17 +575,17 @@ CancelOffThreadIonCompile(JSRuntime* run
 inline void
 CancelOffThreadIonCompilesUsingNurseryPointers(JSRuntime* runtime)
 {
     CancelOffThreadIonCompile(CompilationSelector(CompilationsUsingNursery{runtime}), true);
 }
 
 #ifdef DEBUG
 bool
-HasOffThreadIonCompile(JSCompartment* comp);
+HasOffThreadIonCompile(JS::Realm* realm);
 #endif
 
 /* Cancel all scheduled, in progress or finished parses for runtime. */
 void
 CancelOffThreadParses(JSRuntime* runtime);
 
 /*
  * Start a parse/emit cycle for a stream of source. The characters must stay
--- a/js/src/vm/JSCompartment-inl.h
+++ b/js/src/vm/JSCompartment-inl.h
@@ -86,18 +86,18 @@ js::AutoRealm::~AutoRealm()
     cx_->leaveRealm(origin_, maybeLock_);
 }
 
 js::AutoAtomsRealm::AutoAtomsRealm(JSContext* cx,
                                    js::AutoLockForExclusiveAccess& lock)
   : AutoRealm(cx, cx->atomsRealm(lock), lock)
 {}
 
-js::AutoRealmUnchecked::AutoRealmUnchecked(JSContext* cx, JSCompartment* target)
-  : AutoRealm(cx, JS::GetRealmForCompartment(target))
+js::AutoRealmUnchecked::AutoRealmUnchecked(JSContext* cx, JS::Realm* target)
+  : AutoRealm(cx, target)
 {}
 
 inline bool
 JSCompartment::wrap(JSContext* cx, JS::MutableHandleValue vp)
 {
     /* Only GC things have to be wrapped or copied. */
     if (!vp.isGCThing())
         return true;
--- a/js/src/vm/JSCompartment.h
+++ b/js/src/vm/JSCompartment.h
@@ -899,16 +899,20 @@ class JS::Realm : private JSCompartment
                                 size_t* crossCompartmentWrappers,
                                 size_t* savedStacksSet,
                                 size_t* varNamesSet,
                                 size_t* nonSyntacticLexicalScopes,
                                 size_t* jitRealm,
                                 size_t* privateData,
                                 size_t* scriptCountsMapArg);
 
+    JSCompartment* compartment() {
+        return this;
+    }
+
     JS::Zone* zone() {
         return zone_;
     }
     const JS::Zone* zone() const {
         return zone_;
     }
 
     JSRuntime* runtimeFromMainThread() const {
@@ -1379,17 +1383,17 @@ class AutoAtomsRealm : protected AutoRea
 };
 
 // Enter a realm directly. Only use this where there's no target GC thing
 // to pass to AutoRealm or where you need to avoid the assertions in
 // JS::Compartment::enterCompartmentOf().
 class AutoRealmUnchecked : protected AutoRealm
 {
   public:
-    inline AutoRealmUnchecked(JSContext* cx, JSCompartment* target);
+    inline AutoRealmUnchecked(JSContext* cx, JS::Realm* target);
 };
 
 /*
  * Use this to change the behavior of an AutoRealm slightly on error. If
  * the exception happens to be an Error object, copy it to the origin compartment
  * instead of wrapping it.
  */
 class ErrorCopier
--- a/js/src/vm/ObjectGroup.h
+++ b/js/src/vm/ObjectGroup.h
@@ -27,17 +27,17 @@ class PreliminaryObjectArrayWithTemplate
 class TypeNewScript;
 class HeapTypeSet;
 class AutoClearTypeInferenceStateOnOOM;
 class AutoSweepObjectGroup;
 class CompilerConstraintList;
 class ObjectGroupRealm;
 
 namespace gc {
-void MergeCompartments(JSCompartment* source, JSCompartment* target);
+void MergeRealms(JS::Realm* source, JS::Realm* target);
 } // namespace gc
 
 /*
  * The NewObjectKind allows an allocation site to specify the type properties
  * and lifetime requirements that must be fixed at allocation time.
  */
 enum NewObjectKind {
     /* This is the default. Most objects are generic. */
--- a/js/src/vm/Runtime.cpp
+++ b/js/src/vm/Runtime.cpp
@@ -220,17 +220,17 @@ JSRuntime::init(JSContext* cx, uint32_t 
         return false;
 
     JS::RealmOptions options;
     ScopedJSDeletePtr<Realm> atomsRealm(js_new<Realm>(atomsZone.get(), options));
     if (!atomsRealm || !atomsRealm->init(nullptr))
         return false;
 
     gc.atomsZone = atomsZone.get();
-    if (!atomsZone->compartments().append(JS::GetCompartmentForRealm(atomsRealm.get())))
+    if (!atomsZone->compartments().append(atomsRealm->compartment()))
         return false;
 
     atomsRealm->setIsSystem(true);
     atomsRealm->setIsAtomsRealm();
 
     atomsZone.forget();
     this->atomsRealm_ = atomsRealm.forget();
 
--- a/js/src/vm/SavedStacks.cpp
+++ b/js/src/vm/SavedStacks.cpp
@@ -1469,17 +1469,17 @@ SavedStacks::insertFrames(JSContext* cx,
             if (parent)
                 break;
         }
 
         // We'll be pushing this frame onto stackChain. Gather the information
         // needed to construct the SavedFrame::Lookup.
         Rooted<LocationValue> location(cx);
         {
-            AutoRealmUnchecked ar(cx, iter.compartment());
+            AutoRealmUnchecked ar(cx, iter.realm());
             if (!cx->realm()->savedStacks().getLocation(cx, iter, &location))
                 return false;
         }
 
         RootedAtom displayAtom(cx, iter.maybeFunctionDisplayAtom());
 
         auto principals = JS::GetRealmForCompartment(iter.compartment())->principals();
         MOZ_ASSERT_IF(framePtr && !iter.isWasm(), iter.pc());
--- a/js/src/vm/SelfHosting.cpp
+++ b/js/src/vm/SelfHosting.cpp
@@ -2786,35 +2786,33 @@ JSRuntime::createSelfHostingGlobal(JSCon
 {
     MOZ_ASSERT(!cx->isExceptionPending());
     MOZ_ASSERT(!cx->realm());
 
     JS::RealmOptions options;
     options.creationOptions().setNewZone();
     options.behaviors().setDiscardSource(true);
 
-    JSCompartment* compartment = NewCompartment(cx, nullptr, options);
-    if (!compartment)
+    Realm* realm = NewRealm(cx, nullptr, options);
+    if (!realm)
         return nullptr;
 
-    JS::Realm* realm = JS::GetRealmForCompartment(compartment);
-
     static const ClassOps shgClassOps = {
         nullptr, nullptr, nullptr, nullptr,
         nullptr, nullptr, nullptr, nullptr,
         nullptr, nullptr,
         JS_GlobalObjectTraceHook
     };
 
     static const Class shgClass = {
         "self-hosting-global", JSCLASS_GLOBAL_FLAGS,
         &shgClassOps
     };
 
-    AutoRealmUnchecked ar(cx, compartment);
+    AutoRealmUnchecked ar(cx, realm);
     Rooted<GlobalObject*> shg(cx, GlobalObject::createInternal(cx, &shgClass));
     if (!shg)
         return nullptr;
 
     cx->runtime()->selfHostingGlobal_ = shg;
     realm->setIsSelfHostingRealm();
     realm->setIsSystem(true);
 
--- a/js/src/vm/Shape.h
+++ b/js/src/vm/Shape.h
@@ -446,17 +446,16 @@ class UnownedBaseShape;
 struct StackBaseShape;
 
 class BaseShape : public gc::TenuredCell
 {
   public:
     friend class Shape;
     friend struct StackBaseShape;
     friend struct StackShape;
-    friend void gc::MergeCompartments(JSCompartment* source, JSCompartment* target);
 
     enum Flag {
         /* Owned by the referring shape. */
         OWNED_SHAPE        = 0x1,
 
         /* (0x2 and 0x4 are unused) */
 
         /*
--- a/js/src/vm/Stack.cpp
+++ b/js/src/vm/Stack.cpp
@@ -896,16 +896,27 @@ FrameIter::compartment() const
         break;
       case INTERP:
       case JIT:
         return data_.activations_->compartment();
     }
     MOZ_CRASH("Unexpected state");
 }
 
+Realm*
+FrameIter::realm() const
+{
+    MOZ_ASSERT(!done());
+
+    if (hasScript())
+        return script()->realm();
+
+    return wasmInstance()->realm();
+}
+
 bool
 FrameIter::isEvalFrame() const
 {
     switch (data_.state_) {
       case DONE:
         break;
       case INTERP:
         return interpFrame()->isEvalFrame();
@@ -1617,19 +1628,19 @@ jit::JitActivation::getRematerializedFra
         // frames. Since inlined frames do not exist outside of snapshots, it
         // is impossible to synchronize their rematerialized copies to
         // preserve identity. Therefore, we always rematerialize an uninlined
         // frame and all its inlined frames at once.
         InlineFrameIterator inlineIter(cx, &iter);
         MaybeReadFallback recover(cx, this, &iter);
 
         // Frames are often rematerialized with the cx inside a Debugger's
-        // compartment. To recover slots and to create CallObjects, we need to
-        // be in the activation's compartment.
-        AutoRealmUnchecked ar(cx, compartment_);
+        // realm. To recover slots and to create CallObjects, we need to
+        // be in the script's realm.
+        AutoRealmUnchecked ar(cx, iter.script()->realm());
 
         if (!RematerializedFrame::RematerializeInlineFrames(cx, top, inlineIter, recover, frames))
             return nullptr;
 
         if (!rematerializedFrames_->add(p, top, Move(frames))) {
             ReportOutOfMemory(cx);
             return nullptr;
         }
--- a/js/src/vm/Stack.h
+++ b/js/src/vm/Stack.h
@@ -2040,16 +2040,17 @@ class FrameIter
     bool done() const { return data_.state_ == DONE; }
 
     // -------------------------------------------------------
     // The following functions can only be called when !done()
     // -------------------------------------------------------
 
     FrameIter& operator++();
 
+    JS::Realm* realm() const;
     JSCompartment* compartment() const;
     Activation* activation() const { return data_.activations_.activation(); }
 
     bool isInterp() const {
         MOZ_ASSERT(!done());
         return data_.state_ == INTERP;
     }
     bool isJSJit() const {
--- a/js/src/vm/TypeInference.cpp
+++ b/js/src/vm/TypeInference.cpp
@@ -4412,20 +4412,20 @@ ObjectGroup::sweep(const AutoSweepObject
 
     Maybe<AutoClearTypeInferenceStateOnOOM> fallbackOOM;
     EnsureHasAutoClearTypeInferenceStateOnOOM(oom, zone(), fallbackOOM);
 
     AutoTouchingGrayThings tgt;
 
     if (auto* layout = maybeUnboxedLayout(sweep)) {
         // 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;
         if (IsAboutToBeFinalizedUnbarriered(&group))
-            layout->detachFromCompartment();
+            layout->detachFromRealm();
 
         if (layout->newScript())
             layout->newScript()->sweep();
 
         // Discard constructor code to avoid holding onto ExecutablePools.
         if (zone()->isGCCompacting())
             layout->setConstructorCode(nullptr);
     }
--- a/js/src/vm/UnboxedObject.cpp
+++ b/js/src/vm/UnboxedObject.cpp
@@ -300,17 +300,17 @@ UnboxedLayout::makeConstructorCode(JSCon
     if (!code)
         return false;
 
     layout.setConstructorCode(code);
     return true;
 }
 
 void
-UnboxedLayout::detachFromCompartment()
+UnboxedLayout::detachFromRealm()
 {
     if (isInList())
         remove();
 }
 
 static Value
 GetUnboxedValue(uint8_t* p, JSValueType type, bool maybeUninitialized)
 {
--- a/js/src/vm/UnboxedObject.h
+++ b/js/src/vm/UnboxedObject.h
@@ -119,17 +119,17 @@ class UnboxedLayout : public mozilla::Li
         js_free(traceList_);
 
         nativeGroup_.init(nullptr);
         nativeShape_.init(nullptr);
         replacementGroup_.init(nullptr);
         constructorCode_.init(nullptr);
     }
 
-    void detachFromCompartment();
+    void detachFromRealm();
 
     const PropertyVector& properties() const {
         return properties_;
     }
 
     TypeNewScript* newScript() const {
         return newScript_;
     }
--- a/js/src/wasm/WasmSignalHandlers.cpp
+++ b/js/src/wasm/WasmSignalHandlers.cpp
@@ -949,17 +949,17 @@ HandleFault(PEXCEPTION_POINTERS exceptio
 
     uint8_t* faultingAddress = reinterpret_cast<uint8_t*>(record->ExceptionInformation[1]);
 
     // This check isn't necessary, but, since we can, check anyway to make
     // sure we aren't covering up a real bug.
     if (!IsHeapAccessAddress(*instance, faultingAddress))
         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);
 }
 
 static LONG WINAPI
 WasmFaultHandler(LPEXCEPTION_POINTERS exception)
 {
     // Before anything else, prevent handler recursion.
@@ -1056,17 +1056,17 @@ HandleMachException(JSContext* cx, const
 
     const ModuleSegment* moduleSegment = codeSegment->asModule();
 
     const Instance* instance = LookupFaultingInstance(*moduleSegment, pc, ContextToFP(&context));
     if (!instance)
         return false;
 
     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) {
         Trap trap;
         BytecodeOffset bytecode;
         if (!moduleSegment->code().lookupTrap(pc, &trap, &bytecode))
             return false;
 
         activation->startWasmTrap(trap, bytecode.offset(), ToRegisterState(&context));
@@ -1278,17 +1278,17 @@ HandleFault(int signum, siginfo_t* info,
 
     const ModuleSegment* moduleSegment = segment->asModule();
 
     const Instance* instance = LookupFaultingInstance(*moduleSegment, pc, ContextToFP(context));
     if (!instance)
         return false;
 
     JitActivation* activation = TlsContext.get()->activation()->asJit();
-    MOZ_ASSERT(activation->compartment() == JS::GetCompartmentForRealm(instance->realm()));
+    MOZ_ASSERT(activation->compartment() == instance->realm()->compartment());
 
     if (signum == kWasmTrapSignal) {
         // Wasm traps for MIPS raise only integer overflow fp exception.
 #ifdef __mips__
         if (info->si_code != FPE_INTOVF)
             return false;
 #endif
         Trap trap;
--- a/xpcom/tests/gtest/TestGCPostBarriers.cpp
+++ b/xpcom/tests/gtest/TestGCPostBarriers.cpp
@@ -95,17 +95,17 @@ CreateGlobalAndRunTest(JSContext* cx)
     &GlobalClassOps
   };
 
   JS::RealmOptions options;
   JS::PersistentRootedObject global(cx);
   global = JS_NewGlobalObject(cx, &GlobalClass, nullptr, JS::FireOnNewGlobalHook, options);
   ASSERT_TRUE(global != nullptr);
 
-  JS::Realm* oldRealm = JS::GetRealmForCompartment(JS::EnterRealm(cx, global));
+  JS::Realm* oldRealm = JS::EnterRealm(cx, global);
 
   typedef Heap<JSObject*> ElementT;
 
   {
     nsTArray<ElementT>* array = new nsTArray<ElementT>(InitialElements);
     RunTest(cx, array);
     delete array;
   }