Bug 1320408 - Part 14: Change some GlobalObject methods to static method. r=jandem
authorTooru Fujisawa <arai_a@mac.com>
Sat, 21 Jan 2017 17:25:45 +0900
changeset 377820 bdafc05f51e8164e3a8923637f7248f7c1124066
parent 377819 93ce2713f21dca17968d4080700a6eed22f75939
child 377821 7fcfc41e319c5fcedf2f1661adf1030247e73a8f
push id1419
push userjlund@mozilla.com
push dateMon, 10 Apr 2017 20:44:07 +0000
treeherdermozilla-release@5e6801b73ef6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjandem
bugs1320408
milestone53.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 1320408 - Part 14: Change some GlobalObject methods to static method. r=jandem
js/src/builtin/AtomicsObject.cpp
js/src/builtin/Intl.cpp
js/src/builtin/MapObject.cpp
js/src/builtin/ModuleObject.cpp
js/src/builtin/Promise.cpp
js/src/builtin/Reflect.cpp
js/src/builtin/RegExp.cpp
js/src/builtin/SIMD.cpp
js/src/builtin/SymbolObject.cpp
js/src/builtin/TypedObject.cpp
js/src/builtin/WeakMapObject.cpp
js/src/builtin/WeakSetObject.cpp
js/src/builtin/WeakSetObject.h
js/src/jit/CodeGenerator.cpp
js/src/jsapi.cpp
js/src/jsarray.cpp
js/src/jsbool.cpp
js/src/jsdate.cpp
js/src/jsexn.cpp
js/src/jsfun.cpp
js/src/jsiter.cpp
js/src/jsmath.cpp
js/src/jsnum.cpp
js/src/jsobj.cpp
js/src/json.cpp
js/src/jsstr.cpp
js/src/proxy/Proxy.cpp
js/src/vm/ArgumentsObject.cpp
js/src/vm/ArrayBufferObject.cpp
js/src/vm/Debugger.cpp
js/src/vm/GeneratorObject.cpp
js/src/vm/GlobalObject.cpp
js/src/vm/GlobalObject.h
js/src/vm/RegExpObject.cpp
js/src/vm/SharedArrayObject.cpp
js/src/vm/TypedArrayObject.cpp
js/src/wasm/WasmJS.cpp
--- a/js/src/builtin/AtomicsObject.cpp
+++ b/js/src/builtin/AtomicsObject.cpp
@@ -1110,17 +1110,17 @@ const JSFunctionSpec AtomicsMethods[] = 
     JS_FN("wake",                         atomics_wake,               3,0),
     JS_FS_END
 };
 
 JSObject*
 AtomicsObject::initClass(JSContext* cx, Handle<GlobalObject*> global)
 {
     // Create Atomics Object.
-    RootedObject objProto(cx, global->getOrCreateObjectPrototype(cx));
+    RootedObject objProto(cx, GlobalObject::getOrCreateObjectPrototype(cx, global));
     if (!objProto)
         return nullptr;
     RootedObject Atomics(cx, NewObjectWithGivenProto(cx, &AtomicsObject::class_, objProto,
                                                      SingletonObject));
     if (!Atomics)
         return nullptr;
 
     if (!JS_DefineFunctions(cx, Atomics, AtomicsMethods))
--- a/js/src/builtin/Intl.cpp
+++ b/js/src/builtin/Intl.cpp
@@ -999,17 +999,17 @@ Collator(JSContext* cx, const CallArgs& 
 {
     RootedObject obj(cx);
 
     // We're following ECMA-402 1st Edition when Collator is called because of
     // backward compatibility issues.
     // See https://github.com/tc39/ecma402/issues/57
     if (!construct) {
         // ES Intl 1st ed., 10.1.2.1 step 3
-        JSObject* intl = cx->global()->getOrCreateIntlObject(cx);
+        JSObject* intl = GlobalObject::getOrCreateIntlObject(cx, cx->global());
         if (!intl)
             return false;
         RootedValue self(cx, args.thisv());
         if (!self.isUndefined() && (!self.isObject() || self.toObject() != *intl)) {
             // ES Intl 1st ed., 10.1.2.1 step 4
             obj = ToObject(cx, self);
             if (!obj)
                 return false;
@@ -1028,17 +1028,17 @@ Collator(JSContext* cx, const CallArgs& 
 
     if (construct) {
         // Steps 2-5 (Inlined 9.1.14, OrdinaryCreateFromConstructor).
         RootedObject proto(cx);
         if (args.isConstructing() && !GetPrototypeFromCallableConstructor(cx, args, &proto))
             return false;
 
         if (!proto) {
-            proto = cx->global()->getOrCreateCollatorPrototype(cx);
+            proto = GlobalObject::getOrCreateCollatorPrototype(cx, cx->global());
             if (!proto)
                 return false;
         }
 
         obj = NewObjectWithGivenProto(cx, &CollatorClass, proto);
         if (!obj)
             return false;
 
@@ -1088,21 +1088,22 @@ collator_finalize(FreeOp* fop, JSObject*
         if (UCollator* coll = static_cast<UCollator*>(slot.toPrivate()))
             ucol_close(coll);
     }
 }
 
 static JSObject*
 CreateCollatorPrototype(JSContext* cx, HandleObject Intl, Handle<GlobalObject*> global)
 {
-    RootedFunction ctor(cx, global->createConstructor(cx, &Collator, cx->names().Collator, 0));
+    RootedFunction ctor(cx, GlobalObject::createConstructor(cx, &Collator, cx->names().Collator,
+                                                            0));
     if (!ctor)
         return nullptr;
 
-    RootedNativeObject proto(cx, global->createBlankPrototype(cx, &CollatorClass));
+    RootedNativeObject proto(cx, GlobalObject::createBlankPrototype(cx, global, &CollatorClass));
     if (!proto)
         return nullptr;
     proto->setReservedSlot(UCOLLATOR_SLOT, PrivateValue(nullptr));
 
     if (!LinkConstructorAndPrototype(cx, ctor, proto))
         return nullptr;
 
     // 10.2.2
@@ -1499,17 +1500,17 @@ NumberFormat(JSContext* cx, const CallAr
 {
     RootedObject obj(cx);
 
     // We're following ECMA-402 1st Edition when NumberFormat is called
     // because of backward compatibility issues.
     // See https://github.com/tc39/ecma402/issues/57
     if (!construct) {
         // ES Intl 1st ed., 11.1.2.1 step 3
-        JSObject* intl = cx->global()->getOrCreateIntlObject(cx);
+        JSObject* intl = GlobalObject::getOrCreateIntlObject(cx, cx->global());
         if (!intl)
             return false;
         RootedValue self(cx, args.thisv());
         if (!self.isUndefined() && (!self.isObject() || self.toObject() != *intl)) {
             // ES Intl 1st ed., 11.1.2.1 step 4
             obj = ToObject(cx, self);
             if (!obj)
                 return false;
@@ -1528,17 +1529,17 @@ NumberFormat(JSContext* cx, const CallAr
 
     if (construct) {
         // Step 2 (Inlined 9.1.14, OrdinaryCreateFromConstructor).
         RootedObject proto(cx);
         if (args.isConstructing() && !GetPrototypeFromCallableConstructor(cx, args, &proto))
             return false;
 
         if (!proto) {
-            proto = cx->global()->getOrCreateNumberFormatPrototype(cx);
+            proto = GlobalObject::getOrCreateNumberFormatPrototype(cx, cx->global());
             if (!proto)
                 return false;
         }
 
         obj = NewObjectWithGivenProto(cx, &NumberFormatClass, proto);
         if (!obj)
             return false;
 
@@ -1590,21 +1591,22 @@ numberFormat_finalize(FreeOp* fop, JSObj
             unum_close(nf);
     }
 }
 
 static JSObject*
 CreateNumberFormatPrototype(JSContext* cx, HandleObject Intl, Handle<GlobalObject*> global)
 {
     RootedFunction ctor(cx);
-    ctor = global->createConstructor(cx, &NumberFormat, cx->names().NumberFormat, 0);
+    ctor = GlobalObject::createConstructor(cx, &NumberFormat, cx->names().NumberFormat, 0);
     if (!ctor)
         return nullptr;
 
-    RootedNativeObject proto(cx, global->createBlankPrototype(cx, &NumberFormatClass));
+    RootedNativeObject proto(cx, GlobalObject::createBlankPrototype(cx, global,
+                                                                    &NumberFormatClass));
     if (!proto)
         return nullptr;
     proto->setReservedSlot(UNUMBER_FORMAT_SLOT, PrivateValue(nullptr));
 
     if (!LinkConstructorAndPrototype(cx, ctor, proto))
         return nullptr;
 
     // 11.3.2
@@ -2510,17 +2512,17 @@ DateTimeFormat(JSContext* cx, const Call
 {
     RootedObject obj(cx);
 
     // We're following ECMA-402 1st Edition when DateTimeFormat is called
     // because of backward compatibility issues.
     // See https://github.com/tc39/ecma402/issues/57
     if (!construct) {
         // ES Intl 1st ed., 12.1.2.1 step 3
-        JSObject* intl = cx->global()->getOrCreateIntlObject(cx);
+        JSObject* intl = GlobalObject::getOrCreateIntlObject(cx, cx->global());
         if (!intl)
             return false;
         RootedValue self(cx, args.thisv());
         if (!self.isUndefined() && (!self.isObject() || self.toObject() != *intl)) {
             // ES Intl 1st ed., 12.1.2.1 step 4
             obj = ToObject(cx, self);
             if (!obj)
                 return false;
@@ -2539,17 +2541,17 @@ DateTimeFormat(JSContext* cx, const Call
 
     if (construct) {
         // Step 2 (Inlined 9.1.14, OrdinaryCreateFromConstructor).
         RootedObject proto(cx);
         if (args.isConstructing() && !GetPrototypeFromCallableConstructor(cx, args, &proto))
             return false;
 
         if (!proto) {
-            proto = cx->global()->getOrCreateDateTimeFormatPrototype(cx);
+            proto = GlobalObject::getOrCreateDateTimeFormatPrototype(cx, cx->global());
             if (!proto)
                 return false;
         }
 
         obj = NewObjectWithGivenProto(cx, &DateTimeFormatClass, proto);
         if (!obj)
             return false;
 
@@ -2601,21 +2603,22 @@ dateTimeFormat_finalize(FreeOp* fop, JSO
             udat_close(df);
     }
 }
 
 static JSObject*
 CreateDateTimeFormatPrototype(JSContext* cx, HandleObject Intl, Handle<GlobalObject*> global)
 {
     RootedFunction ctor(cx);
-    ctor = global->createConstructor(cx, &DateTimeFormat, cx->names().DateTimeFormat, 0);
+    ctor = GlobalObject::createConstructor(cx, &DateTimeFormat, cx->names().DateTimeFormat, 0);
     if (!ctor)
         return nullptr;
 
-    RootedNativeObject proto(cx, global->createBlankPrototype(cx, &DateTimeFormatClass));
+    RootedNativeObject proto(cx, GlobalObject::createBlankPrototype(cx, global,
+                                                                    &DateTimeFormatClass));
     if (!proto)
         return nullptr;
     proto->setReservedSlot(UDATE_FORMAT_SLOT, PrivateValue(nullptr));
 
     if (!LinkConstructorAndPrototype(cx, ctor, proto))
         return nullptr;
 
     // 12.3.2
@@ -3634,17 +3637,17 @@ PluralRules(JSContext* cx, unsigned argc
     // Step 1 (Handled by OrdinaryCreateFromConstructor fallback code).
 
     // Step 2 (Inlined 9.1.14, OrdinaryCreateFromConstructor).
     RootedObject proto(cx);
     if (args.isConstructing() && !GetPrototypeFromCallableConstructor(cx, args, &proto))
         return false;
 
     if (!proto) {
-        proto = cx->global()->getOrCreatePluralRulesPrototype(cx);
+        proto = GlobalObject::getOrCreatePluralRulesPrototype(cx, cx->global());
         if (!proto)
             return false;
     }
 
     RootedObject obj(cx, NewObjectWithGivenProto(cx, &PluralRulesClass, proto));
     if (!obj)
         return false;
 
@@ -3680,17 +3683,18 @@ pluralRules_finalize(FreeOp* fop, JSObje
 static JSObject*
 CreatePluralRulesPrototype(JSContext* cx, HandleObject Intl, Handle<GlobalObject*> global)
 {
     RootedFunction ctor(cx);
     ctor = global->createConstructor(cx, &PluralRules, cx->names().PluralRules, 0);
     if (!ctor)
         return nullptr;
 
-    RootedNativeObject proto(cx, global->createBlankPrototype(cx, &PluralRulesClass));
+    RootedNativeObject proto(cx, GlobalObject::createBlankPrototype(cx, global,
+                                                                    &PluralRulesClass));
     if (!proto)
         return nullptr;
     MOZ_ASSERT(proto->getReservedSlot(UPLURAL_RULES_SLOT).isUndefined(),
                "improperly creating PluralRules more than once for a single "
                "global?");
     proto->setReservedSlot(UPLURAL_RULES_SLOT, PrivateValue(nullptr));
 
     if (!LinkConstructorAndPrototype(cx, ctor, proto))
@@ -4413,20 +4417,20 @@ static const JSFunctionSpec intl_static_
     JS_SELF_HOSTED_FN("getCanonicalLocales", "Intl_getCanonicalLocales", 1, 0),
     JS_FS_END
 };
 
 /**
  * Initializes the Intl Object and its standard built-in properties.
  * Spec: ECMAScript Internationalization API Specification, 8.0, 8.1
  */
-bool
+/* static */ bool
 GlobalObject::initIntlObject(JSContext* cx, Handle<GlobalObject*> global)
 {
-    RootedObject proto(cx, global->getOrCreateObjectPrototype(cx));
+    RootedObject proto(cx, GlobalObject::getOrCreateObjectPrototype(cx, global));
     if (!proto)
         return false;
 
     // The |Intl| object is just a plain object with some "static" function
     // properties and some constructor properties.
     RootedObject intl(cx, NewObjectWithGivenProto(cx, &IntlClass, proto, SingletonObject));
     if (!intl)
         return false;
--- a/js/src/builtin/MapObject.cpp
+++ b/js/src/builtin/MapObject.cpp
@@ -159,17 +159,17 @@ MapIteratorObjectRange(NativeObject* obj
 inline MapObject::IteratorKind
 MapIteratorObject::kind() const
 {
     int32_t i = getSlot(KindSlot).toInt32();
     MOZ_ASSERT(i == MapObject::Keys || i == MapObject::Values || i == MapObject::Entries);
     return MapObject::IteratorKind(i);
 }
 
-bool
+/* static */ bool
 GlobalObject::initMapIteratorProto(JSContext* cx, Handle<GlobalObject*> global)
 {
     Rooted<JSObject*> base(cx, GlobalObject::getOrCreateIteratorPrototype(cx, global));
     if (!base)
         return false;
     RootedPlainObject proto(cx, NewObjectWithGivenProto<PlainObject>(cx, base));
     if (!proto)
         return false;
@@ -276,17 +276,17 @@ MapIteratorObject::createResultPair(JSCo
 }
 
 
 /*** Map *****************************************************************************************/
 
 static JSObject*
 CreateMapPrototype(JSContext* cx, JSProtoKey key)
 {
-    return cx->global()->createBlankPrototype(cx, &MapObject::protoClass_);
+    return GlobalObject::createBlankPrototype(cx, cx->global(), &MapObject::protoClass_);
 }
 
 const ClassOps MapObject::classOps_ = {
     nullptr, // addProperty
     nullptr, // delProperty
     nullptr, // getProperty
     nullptr, // setProperty
     nullptr, // enumerate
@@ -894,17 +894,17 @@ SetIteratorObjectRange(NativeObject* obj
 inline SetObject::IteratorKind
 SetIteratorObject::kind() const
 {
     int32_t i = getSlot(KindSlot).toInt32();
     MOZ_ASSERT(i == SetObject::Values || i == SetObject::Entries);
     return SetObject::IteratorKind(i);
 }
 
-bool
+/* static */ bool
 GlobalObject::initSetIteratorProto(JSContext* cx, Handle<GlobalObject*> global)
 {
     Rooted<JSObject*> base(cx, GlobalObject::getOrCreateIteratorPrototype(cx, global));
     if (!base)
         return false;
     RootedPlainObject proto(cx, NewObjectWithGivenProto<PlainObject>(cx, base));
     if (!proto)
         return false;
@@ -998,17 +998,17 @@ SetIteratorObject::createResult(JSContex
 }
 
 
 /*** Set *****************************************************************************************/
 
 static JSObject*
 CreateSetPrototype(JSContext* cx, JSProtoKey key)
 {
-    return cx->global()->createBlankPrototype(cx, &SetObject::protoClass_);
+    return GlobalObject::createBlankPrototype(cx, cx->global(), &SetObject::protoClass_);
 }
 
 const ClassOps SetObject::classOps_ = {
     nullptr, // addProperty
     nullptr, // delProperty
     nullptr, // getProperty
     nullptr, // setProperty
     nullptr, // enumerate
--- a/js/src/builtin/ModuleObject.cpp
+++ b/js/src/builtin/ModuleObject.cpp
@@ -98,17 +98,17 @@ GlobalObject::initImportEntryProto(JSCon
 {
     static const JSPropertySpec protoAccessors[] = {
         JS_PSG("moduleRequest", ImportEntryObject_moduleRequestGetter, 0),
         JS_PSG("importName", ImportEntryObject_importNameGetter, 0),
         JS_PSG("localName", ImportEntryObject_localNameGetter, 0),
         JS_PS_END
     };
 
-    RootedObject proto(cx, global->createBlankPrototype<PlainObject>(cx));
+    RootedObject proto(cx, GlobalObject::createBlankPrototype<PlainObject>(cx, global));
     if (!proto)
         return false;
 
     if (!DefinePropertiesAndFunctions(cx, proto, protoAccessors, nullptr))
         return false;
 
     global->setReservedSlot(IMPORT_ENTRY_PROTO, ObjectValue(*proto));
     return true;
@@ -164,17 +164,17 @@ GlobalObject::initExportEntryProto(JSCon
     static const JSPropertySpec protoAccessors[] = {
         JS_PSG("exportName", ExportEntryObject_exportNameGetter, 0),
         JS_PSG("moduleRequest", ExportEntryObject_moduleRequestGetter, 0),
         JS_PSG("importName", ExportEntryObject_importNameGetter, 0),
         JS_PSG("localName", ExportEntryObject_localNameGetter, 0),
         JS_PS_END
     };
 
-    RootedObject proto(cx, global->createBlankPrototype<PlainObject>(cx));
+    RootedObject proto(cx, GlobalObject::createBlankPrototype<PlainObject>(cx, global));
     if (!proto)
         return false;
 
     if (!DefinePropertiesAndFunctions(cx, proto, protoAccessors, nullptr))
         return false;
 
     global->setReservedSlot(EXPORT_ENTRY_PROTO, ObjectValue(*proto));
     return true;
@@ -991,17 +991,17 @@ GlobalObject::initModuleProto(JSContext*
     static const JSFunctionSpec protoFunctions[] = {
         JS_SELF_HOSTED_FN("getExportedNames", "ModuleGetExportedNames", 1, 0),
         JS_SELF_HOSTED_FN("resolveExport", "ModuleResolveExport", 3, 0),
         JS_SELF_HOSTED_FN("declarationInstantiation", "ModuleDeclarationInstantiation", 0, 0),
         JS_SELF_HOSTED_FN("evaluation", "ModuleEvaluation", 0, 0),
         JS_FS_END
     };
 
-    RootedObject proto(cx, global->createBlankPrototype<PlainObject>(cx));
+    RootedObject proto(cx, GlobalObject::createBlankPrototype<PlainObject>(cx, global));
     if (!proto)
         return false;
 
     if (!DefinePropertiesAndFunctions(cx, proto, protoAccessors, protoFunctions))
         return false;
 
     global->setReservedSlot(MODULE_PROTO, ObjectValue(*proto));
     return true;
--- a/js/src/builtin/Promise.cpp
+++ b/js/src/builtin/Promise.cpp
@@ -2686,17 +2686,17 @@ PromiseTask::executeAndFinish(JSContext*
     MOZ_ASSERT(!CanUseExtraThreads());
     execute();
     return finishPromise(cx, promise_);
 }
 
 static JSObject*
 CreatePromisePrototype(JSContext* cx, JSProtoKey key)
 {
-    return cx->global()->createBlankPrototype(cx, &PromiseObject::protoClass_);
+    return GlobalObject::createBlankPrototype(cx, cx->global(), &PromiseObject::protoClass_);
 }
 
 static const JSFunctionSpec promise_methods[] = {
     JS_SELF_HOSTED_FN("catch", "Promise_catch", 1, 0),
     JS_FN("then", Promise_then, 2, 0),
     JS_FS_END
 };
 
--- a/js/src/builtin/Reflect.cpp
+++ b/js/src/builtin/Reflect.cpp
@@ -263,17 +263,18 @@ static const JSFunctionSpec methods[] = 
 };
 
 
 /*** Setup **************************************************************************************/
 
 JSObject*
 js::InitReflect(JSContext* cx, HandleObject obj)
 {
-    RootedObject proto(cx, obj->as<GlobalObject>().getOrCreateObjectPrototype(cx));
+    Handle<GlobalObject*> global = obj.as<GlobalObject>();
+    RootedObject proto(cx, GlobalObject::getOrCreateObjectPrototype(cx, global));
     if (!proto)
         return nullptr;
 
     RootedObject reflect(cx, NewObjectWithGivenProto<PlainObject>(cx, proto, SingletonObject));
     if (!reflect)
         return nullptr;
     if (!JS_DefineFunctions(cx, reflect, methods))
         return nullptr;
--- a/js/src/builtin/RegExp.cpp
+++ b/js/src/builtin/RegExp.cpp
@@ -796,17 +796,17 @@ const JSFunctionSpec js::regexp_methods[
  *  RegExp.rightContext         $'
  */
 
 #define DEFINE_STATIC_GETTER(name, code)                                        \
     static bool                                                                 \
     name(JSContext* cx, unsigned argc, Value* vp)                               \
     {                                                                           \
         CallArgs args = CallArgsFromVp(argc, vp);                               \
-        RegExpStatics* res = cx->global()->getRegExpStatics(cx);                \
+        RegExpStatics* res = GlobalObject::getRegExpStatics(cx, cx->global());  \
         if (!res)                                                               \
             return false;                                                       \
         code;                                                                   \
     }
 
 DEFINE_STATIC_GETTER(static_input_getter,        return res->createPendingInput(cx, args.rval()))
 DEFINE_STATIC_GETTER(static_lastMatch_getter,    return res->createLastMatch(cx, args.rval()))
 DEFINE_STATIC_GETTER(static_lastParen_getter,    return res->createLastParen(cx, args.rval()))
@@ -822,28 +822,28 @@ DEFINE_STATIC_GETTER(static_paren6_gette
 DEFINE_STATIC_GETTER(static_paren7_getter,       STATIC_PAREN_GETTER_CODE(7))
 DEFINE_STATIC_GETTER(static_paren8_getter,       STATIC_PAREN_GETTER_CODE(8))
 DEFINE_STATIC_GETTER(static_paren9_getter,       STATIC_PAREN_GETTER_CODE(9))
 
 #define DEFINE_STATIC_SETTER(name, code)                                        \
     static bool                                                                 \
     name(JSContext* cx, unsigned argc, Value* vp)                               \
     {                                                                           \
-        RegExpStatics* res = cx->global()->getRegExpStatics(cx);                \
+        RegExpStatics* res = GlobalObject::getRegExpStatics(cx, cx->global());  \
         if (!res)                                                               \
             return false;                                                       \
         code;                                                                   \
         return true;                                                            \
     }
 
 static bool
 static_input_setter(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
-    RegExpStatics* res = cx->global()->getRegExpStatics(cx);
+    RegExpStatics* res = GlobalObject::getRegExpStatics(cx, cx->global());
     if (!res)
         return false;
 
     RootedString str(cx, ToString<CanGC>(cx, args.get(0)));
     if (!str)
         return false;
 
     res->setPendingInput(str);
@@ -918,17 +918,17 @@ ExecuteRegExp(JSContext* cx, HandleObjec
     Rooted<RegExpObject*> reobj(cx, &regexp->as<RegExpObject>());
 
     RegExpGuard re(cx);
     if (!reobj->getShared(cx, &re))
         return RegExpRunStatus_Error;
 
     RegExpStatics* res;
     if (staticsUpdate == UpdateRegExpStatics) {
-        res = cx->global()->getRegExpStatics(cx);
+        res = GlobalObject::getRegExpStatics(cx, cx->global());
         if (!res)
             return RegExpRunStatus_Error;
     } else {
         res = nullptr;
     }
 
     RootedLinearString input(cx, string->ensureLinear(cx));
     if (!input)
--- a/js/src/builtin/SIMD.cpp
+++ b/js/src/builtin/SIMD.cpp
@@ -470,29 +470,29 @@ static const ClassOps SimdObjectClassOps
 };
 
 const Class SimdObject::class_ = {
     "SIMD",
     JSCLASS_HAS_RESERVED_SLOTS(uint32_t(SimdType::Count)),
     &SimdObjectClassOps
 };
 
-bool
+/* static */ bool
 GlobalObject::initSimdObject(JSContext* cx, Handle<GlobalObject*> global)
 {
     // SIMD relies on the TypedObject module being initialized.
     // In particular, the self-hosted code for array() wants
     // to be able to call GetTypedObjectModule(). It is NOT necessary
     // to install the TypedObjectModule global, but at the moment
     // those two things are not separable.
-    if (!global->getOrCreateTypedObjectModule(cx))
+    if (!GlobalObject::getOrCreateTypedObjectModule(cx, global))
         return false;
 
     RootedObject globalSimdObject(cx);
-    RootedObject objProto(cx, global->getOrCreateObjectPrototype(cx));
+    RootedObject objProto(cx, GlobalObject::getOrCreateObjectPrototype(cx, global));
     if (!objProto)
         return false;
 
     globalSimdObject = NewObjectWithGivenProto(cx, &SimdObject::class_, objProto, SingletonObject);
     if (!globalSimdObject)
         return false;
 
     RootedValue globalSimdValue(cx, ObjectValue(*globalSimdObject));
@@ -505,17 +505,17 @@ GlobalObject::initSimdObject(JSContext* 
     global->setConstructor(JSProto_SIMD, globalSimdValue);
     return true;
 }
 
 static bool
 CreateSimdType(JSContext* cx, Handle<GlobalObject*> global, HandlePropertyName stringRepr,
                SimdType simdType, const JSFunctionSpec* methods)
 {
-    RootedObject funcProto(cx, global->getOrCreateFunctionPrototype(cx));
+    RootedObject funcProto(cx, GlobalObject::getOrCreateFunctionPrototype(cx, global));
     if (!funcProto)
         return false;
 
     // Create type constructor itself and initialize its reserved slots.
     Rooted<SimdTypeDescr*> typeDescr(cx);
     typeDescr = NewObjectWithGivenProto<SimdTypeDescr>(cx, funcProto, SingletonObject);
     if (!typeDescr)
         return false;
@@ -526,17 +526,17 @@ CreateSimdType(JSContext* cx, Handle<Glo
     typeDescr->initReservedSlot(JS_DESCR_SLOT_SIZE, Int32Value(SimdTypeDescr::size(simdType)));
     typeDescr->initReservedSlot(JS_DESCR_SLOT_OPAQUE, BooleanValue(false));
     typeDescr->initReservedSlot(JS_DESCR_SLOT_TYPE, Int32Value(uint8_t(simdType)));
 
     if (!CreateUserSizeAndAlignmentProperties(cx, typeDescr))
         return false;
 
     // Create prototype property, which inherits from Object.prototype.
-    RootedObject objProto(cx, global->getOrCreateObjectPrototype(cx));
+    RootedObject objProto(cx, GlobalObject::getOrCreateObjectPrototype(cx, global));
     if (!objProto)
         return false;
     Rooted<TypedProto*> proto(cx);
     proto = NewObjectWithGivenProto<TypedProto>(cx, objProto, SingletonObject);
     if (!proto)
         return false;
     typeDescr->initReservedSlot(JS_DESCR_SLOT_TYPROTO, ObjectValue(*proto));
 
@@ -546,56 +546,56 @@ CreateSimdType(JSContext* cx, Handle<Glo
 
     if (!LinkConstructorAndPrototype(cx, typeDescr, proto) ||
         !JS_DefineFunctions(cx, proto, SimdTypedObjectMethods))
     {
         return false;
     }
 
     // Bind type descriptor to the global SIMD object
-    RootedObject globalSimdObject(cx, global->getOrCreateSimdGlobalObject(cx));
+    RootedObject globalSimdObject(cx, GlobalObject::getOrCreateSimdGlobalObject(cx, global));
     MOZ_ASSERT(globalSimdObject);
 
     RootedValue typeValue(cx, ObjectValue(*typeDescr));
     if (!JS_DefineFunctions(cx, typeDescr, methods) ||
         !DefineProperty(cx, globalSimdObject, stringRepr, typeValue, nullptr, nullptr,
                         JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_RESOLVING))
     {
         return false;
     }
 
     uint32_t slot = uint32_t(typeDescr->type());
     MOZ_ASSERT(globalSimdObject->as<NativeObject>().getReservedSlot(slot).isUndefined());
     globalSimdObject->as<NativeObject>().setReservedSlot(slot, ObjectValue(*typeDescr));
     return !!typeDescr;
 }
 
-bool
+/* static */ bool
 GlobalObject::initSimdType(JSContext* cx, Handle<GlobalObject*> global, SimdType simdType)
 {
 #define CREATE_(Type) \
     case SimdType::Type: \
       return CreateSimdType(cx, global, cx->names().Type, simdType, Type##Defn::Methods);
 
     switch (simdType) {
       FOR_EACH_SIMD(CREATE_)
       case SimdType::Count: break;
     }
     MOZ_CRASH("unexpected simd type");
 
 #undef CREATE_
 }
 
-SimdTypeDescr*
+/* static */ SimdTypeDescr*
 GlobalObject::getOrCreateSimdTypeDescr(JSContext* cx, Handle<GlobalObject*> global,
                                        SimdType simdType)
 {
     MOZ_ASSERT(unsigned(simdType) < unsigned(SimdType::Count), "Invalid SIMD type");
 
-    RootedObject globalSimdObject(cx, global->getOrCreateSimdGlobalObject(cx));
+    RootedObject globalSimdObject(cx, GlobalObject::getOrCreateSimdGlobalObject(cx, global));
     if (!globalSimdObject)
        return nullptr;
 
     uint32_t typeSlotIndex = uint32_t(simdType);
     if (globalSimdObject->as<NativeObject>().getReservedSlot(typeSlotIndex).isUndefined() &&
         !GlobalObject::initSimdType(cx, global, simdType))
     {
         return nullptr;
@@ -623,18 +623,18 @@ SimdObject::resolve(JSContext* cx, JS::H
     FOR_EACH_SIMD(TRY_RESOLVE_)
 #undef TRY_RESOLVE_
     return true;
 }
 
 JSObject*
 js::InitSimdClass(JSContext* cx, HandleObject obj)
 {
-    Rooted<GlobalObject*> global(cx, &obj->as<GlobalObject>());
-    return global->getOrCreateSimdGlobalObject(cx);
+    Handle<GlobalObject*> global = obj.as<GlobalObject>();
+    return GlobalObject::getOrCreateSimdGlobalObject(cx, global);
 }
 
 template<typename V>
 JSObject*
 js::CreateSimd(JSContext* cx, const typename V::Elem* data)
 {
     typedef typename V::Elem Elem;
     Rooted<TypeDescr*> typeDescr(cx, GetTypeDescr<V>(cx));
--- a/js/src/builtin/SymbolObject.cpp
+++ b/js/src/builtin/SymbolObject.cpp
@@ -47,27 +47,27 @@ const JSFunctionSpec SymbolObject::stati
     JS_FN("for", for_, 1, 0),
     JS_FN("keyFor", keyFor, 1, 0),
     JS_FS_END
 };
 
 JSObject*
 SymbolObject::initClass(JSContext* cx, HandleObject obj)
 {
-    Rooted<GlobalObject*> global(cx, &obj->as<GlobalObject>());
+    Handle<GlobalObject*> global = obj.as<GlobalObject>();
 
     // This uses &JSObject::class_ because: "The Symbol prototype object is an
     // ordinary object. It is not a Symbol instance and does not have a
     // [[SymbolData]] internal slot." (ES6 rev 24, 19.4.3)
-    RootedObject proto(cx, global->createBlankPrototype<PlainObject>(cx));
+    RootedObject proto(cx, GlobalObject::createBlankPrototype<PlainObject>(cx, global));
     if (!proto)
         return nullptr;
 
-    RootedFunction ctor(cx, global->createConstructor(cx, construct,
-                                                      ClassName(JSProto_Symbol, cx), 0));
+    RootedFunction ctor(cx, GlobalObject::createConstructor(cx, construct,
+                                                            ClassName(JSProto_Symbol, cx), 0));
     if (!ctor)
         return nullptr;
 
     // Define the well-known symbol properties, such as Symbol.iterator.
     ImmutablePropertyNamePtr* names = cx->names().wellKnownSymbolNames();
     RootedValue value(cx);
     unsigned attrs = JSPROP_READONLY | JSPROP_PERMANENT;
     WellKnownSymbols* wks = cx->runtime()->wellKnownSymbols;
--- a/js/src/builtin/TypedObject.cpp
+++ b/js/src/builtin/TypedObject.cpp
@@ -1119,21 +1119,21 @@ StructTypeDescr::fieldDescr(size_t index
 template<typename T>
 static bool
 DefineSimpleTypeDescr(JSContext* cx,
                       Handle<GlobalObject*> global,
                       HandleObject module,
                       typename T::Type type,
                       HandlePropertyName className)
 {
-    RootedObject objProto(cx, global->getOrCreateObjectPrototype(cx));
+    RootedObject objProto(cx, GlobalObject::getOrCreateObjectPrototype(cx, global));
     if (!objProto)
         return false;
 
-    RootedObject funcProto(cx, global->getOrCreateFunctionPrototype(cx));
+    RootedObject funcProto(cx, GlobalObject::getOrCreateFunctionPrototype(cx, global));
     if (!funcProto)
         return false;
 
     Rooted<T*> descr(cx);
     descr = NewObjectWithGivenProto<T>(cx, funcProto, SingletonObject);
     if (!descr)
         return false;
 
@@ -1180,29 +1180,29 @@ DefineMetaTypeDescr(JSContext* cx,
                     Handle<GlobalObject*> global,
                     Handle<TypedObjectModuleObject*> module,
                     TypedObjectModuleObject::Slot protoSlot)
 {
     RootedAtom className(cx, Atomize(cx, name, strlen(name)));
     if (!className)
         return nullptr;
 
-    RootedObject funcProto(cx, global->getOrCreateFunctionPrototype(cx));
+    RootedObject funcProto(cx, GlobalObject::getOrCreateFunctionPrototype(cx, global));
     if (!funcProto)
         return nullptr;
 
     // Create ctor.prototype, which inherits from Function.__proto__
 
     RootedObject proto(cx, NewObjectWithGivenProto<PlainObject>(cx, funcProto, SingletonObject));
     if (!proto)
         return nullptr;
 
     // Create ctor.prototype.prototype, which inherits from Object.__proto__
 
-    RootedObject objProto(cx, global->getOrCreateObjectPrototype(cx));
+    RootedObject objProto(cx, GlobalObject::getOrCreateObjectPrototype(cx, global));
     if (!objProto)
         return nullptr;
     RootedObject protoProto(cx);
     protoProto = NewObjectWithGivenProto<PlainObject>(cx, objProto, SingletonObject);
     if (!protoProto)
         return nullptr;
 
     RootedValue protoProtoValue(cx, ObjectValue(*protoProto));
@@ -1211,17 +1211,17 @@ DefineMetaTypeDescr(JSContext* cx,
     {
         return nullptr;
     }
 
     // Create ctor itself
 
     const int constructorLength = 2;
     RootedFunction ctor(cx);
-    ctor = global->createConstructor(cx, T::construct, className, constructorLength);
+    ctor = GlobalObject::createConstructor(cx, T::construct, className, constructorLength);
     if (!ctor ||
         !LinkConstructorAndPrototype(cx, ctor, proto) ||
         !DefinePropertiesAndFunctions(cx, proto,
                                       T::typeObjectProperties,
                                       T::typeObjectMethods) ||
         !DefinePropertiesAndFunctions(cx, protoProto,
                                       T::typedObjectProperties,
                                       T::typedObjectMethods))
@@ -1235,20 +1235,20 @@ DefineMetaTypeDescr(JSContext* cx,
 }
 
 /*  The initialization strategy for TypedObjects is mildly unusual
  * compared to other classes. Because all of the types are members
  * of a single global, `TypedObject`, we basically make the
  * initializer for the `TypedObject` class populate the
  * `TypedObject` global (which is referred to as "module" herein).
  */
-bool
+/* static */ bool
 GlobalObject::initTypedObjectModule(JSContext* cx, Handle<GlobalObject*> global)
 {
-    RootedObject objProto(cx, global->getOrCreateObjectPrototype(cx));
+    RootedObject objProto(cx, GlobalObject::getOrCreateObjectPrototype(cx, global));
     if (!objProto)
         return false;
 
     Rooted<TypedObjectModuleObject*> module(cx);
     module = NewObjectWithGivenProto<TypedObjectModuleObject>(cx, objProto);
     if (!module)
         return false;
 
@@ -1312,19 +1312,18 @@ GlobalObject::initTypedObjectModule(JSCo
     global->setConstructor(JSProto_TypedObject, moduleValue);
 
     return module;
 }
 
 JSObject*
 js::InitTypedObjectModuleObject(JSContext* cx, HandleObject obj)
 {
-    MOZ_ASSERT(obj->is<GlobalObject>());
-    Rooted<GlobalObject*> global(cx, &obj->as<GlobalObject>());
-    return global->getOrCreateTypedObjectModule(cx);
+    Handle<GlobalObject*> global = obj.as<GlobalObject>();
+    return GlobalObject::getOrCreateTypedObjectModule(cx, global);
 }
 
 /******************************************************************************
  * Typed objects
  */
 
 uint32_t
 TypedObject::offset() const
--- a/js/src/builtin/WeakMapObject.cpp
+++ b/js/src/builtin/WeakMapObject.cpp
@@ -345,24 +345,24 @@ static const JSFunctionSpec weak_map_met
     JS_FS_END
 };
 
 static JSObject*
 InitWeakMapClass(JSContext* cx, HandleObject obj, bool defineMembers)
 {
     MOZ_ASSERT(obj->isNative());
 
-    Rooted<GlobalObject*> global(cx, &obj->as<GlobalObject>());
+    Handle<GlobalObject*> global = obj.as<GlobalObject>();
 
     RootedPlainObject proto(cx, NewBuiltinClassInstance<PlainObject>(cx));
     if (!proto)
         return nullptr;
 
-    RootedFunction ctor(cx, global->createConstructor(cx, WeakMap_construct,
-                                                      cx->names().WeakMap, 0));
+    RootedFunction ctor(cx, GlobalObject::createConstructor(cx, WeakMap_construct,
+                                                            cx->names().WeakMap, 0));
     if (!ctor)
         return nullptr;
 
     if (!LinkConstructorAndPrototype(cx, ctor, proto))
         return nullptr;
 
     if (defineMembers) {
         if (!DefinePropertiesAndFunctions(cx, proto, nullptr, weak_map_methods))
--- a/js/src/builtin/WeakSetObject.cpp
+++ b/js/src/builtin/WeakSetObject.cpp
@@ -36,24 +36,25 @@ const JSPropertySpec WeakSetObject::prop
 const JSFunctionSpec WeakSetObject::methods[] = {
     JS_SELF_HOSTED_FN("add",    "WeakSet_add",    1, 0),
     JS_SELF_HOSTED_FN("delete", "WeakSet_delete", 1, 0),
     JS_SELF_HOSTED_FN("has",    "WeakSet_has",    1, 0),
     JS_FS_END
 };
 
 JSObject*
-WeakSetObject::initClass(JSContext* cx, JSObject* obj)
+WeakSetObject::initClass(JSContext* cx, HandleObject obj)
 {
-    Rooted<GlobalObject*> global(cx, &obj->as<GlobalObject>());
+    Handle<GlobalObject*> global = obj.as<GlobalObject>();
     RootedPlainObject proto(cx, NewBuiltinClassInstance<PlainObject>(cx));
     if (!proto)
         return nullptr;
 
-    Rooted<JSFunction*> ctor(cx, global->createConstructor(cx, construct, ClassName(JSProto_WeakSet, cx), 0));
+    Rooted<JSFunction*> ctor(cx, GlobalObject::createConstructor(cx, construct,
+                                                                 ClassName(JSProto_WeakSet, cx), 0));
     if (!ctor ||
         !LinkConstructorAndPrototype(cx, ctor, proto) ||
         !DefinePropertiesAndFunctions(cx, proto, properties, methods) ||
         !DefineToStringTag(cx, proto, cx->names().WeakSet) ||
         !GlobalObject::initBuiltinConstructor(cx, global, JSProto_WeakSet, ctor, proto))
     {
         return nullptr;
     }
--- a/js/src/builtin/WeakSetObject.h
+++ b/js/src/builtin/WeakSetObject.h
@@ -11,17 +11,17 @@
 
 namespace js {
 
 class WeakSetObject : public NativeObject
 {
   public:
     static const unsigned RESERVED_SLOTS = 1;
 
-    static JSObject* initClass(JSContext* cx, JSObject* obj);
+    static JSObject* initClass(JSContext* cx, HandleObject obj);
     static const Class class_;
 
   private:
     static const JSPropertySpec properties[];
     static const JSFunctionSpec methods[];
 
     static WeakSetObject* create(JSContext* cx, HandleObject proto = nullptr);
     static MOZ_MUST_USE bool construct(JSContext* cx, unsigned argc, Value* vp);
--- a/js/src/jit/CodeGenerator.cpp
+++ b/js/src/jit/CodeGenerator.cpp
@@ -1157,17 +1157,17 @@ PrepareAndExecuteRegExp(JSContext* cx, M
         inputOutputDataStartOffset + offsetof(irregexp::InputOutputData, result));
 
     Address pairCountAddress = RegExpPairCountAddress(masm, inputOutputDataStartOffset);
     Address pairsPointerAddress(masm.getStackPointer(),
         matchPairsStartOffset + MatchPairs::offsetOfPairs());
 
     Address pairsVectorAddress(masm.getStackPointer(), pairsVectorStartOffset);
 
-    RegExpStatics* res = cx->global()->getRegExpStatics(cx);
+    RegExpStatics* res = GlobalObject::getRegExpStatics(cx, cx->global());
     if (!res)
         return false;
 #ifdef JS_USE_LINK_REGISTER
     if (mode != RegExpShared::MatchOnly)
         masm.pushReturnAddress();
 #endif
     if (mode == RegExpShared::Normal) {
         // First, fill in a skeletal MatchPairs instance on the stack. This will be
--- a/js/src/jsapi.cpp
+++ b/js/src/jsapi.cpp
@@ -1025,17 +1025,17 @@ JS_PUBLIC_API(bool)
 JS_ResolveStandardClass(JSContext* cx, HandleObject obj, HandleId id, bool* resolved)
 {
     const JSStdName* stdnm;
 
     AssertHeapIsIdle(cx);
     CHECK_REQUEST(cx);
     assertSameCompartment(cx, obj, id);
 
-    Rooted<GlobalObject*> global(cx, &obj->as<GlobalObject>());
+    Handle<GlobalObject*> global = obj.as<GlobalObject>();
     *resolved = false;
 
     if (!JSID_IS_ATOM(id))
         return true;
 
     /* Check whether we're resolving 'undefined', and define it if so. */
     JSAtom* idAtom = JSID_TO_ATOM(id);
     JSAtom* undefinedAtom = cx->names().undefined;
@@ -1069,17 +1069,17 @@ JS_ResolveStandardClass(JSContext* cx, H
         }
     }
 
     // There is no such property to resolve. An ordinary resolve hook would
     // just return true at this point. But the global object is special in one
     // more way: its prototype chain is lazily initialized. That is,
     // global->getProto() might be null right now because we haven't created
     // Object.prototype yet. Force it now.
-    return global->getOrCreateObjectPrototype(cx);
+    return GlobalObject::getOrCreateObjectPrototype(cx, global);
 }
 
 JS_PUBLIC_API(bool)
 JS_MayResolveStandardClass(const JSAtomState& names, jsid id, JSObject* maybeObj)
 {
     MOZ_ASSERT_IF(maybeObj, maybeObj->is<GlobalObject>());
 
     // The global object's resolve hook is special: JS_ResolveStandardClass
@@ -1102,18 +1102,17 @@ JS_MayResolveStandardClass(const JSAtomS
 }
 
 JS_PUBLIC_API(bool)
 JS_EnumerateStandardClasses(JSContext* cx, HandleObject obj)
 {
     AssertHeapIsIdle(cx);
     CHECK_REQUEST(cx);
     assertSameCompartment(cx, obj);
-    MOZ_ASSERT(obj->is<GlobalObject>());
-    Rooted<GlobalObject*> global(cx, &obj->as<GlobalObject>());
+    Handle<GlobalObject*> global = obj.as<GlobalObject>();
     return GlobalObject::initStandardClasses(cx, global);
 }
 
 JS_PUBLIC_API(bool)
 JS_GetClassObject(JSContext* cx, JSProtoKey key, MutableHandleObject objp)
 {
     AssertHeapIsIdle(cx);
     CHECK_REQUEST(cx);
@@ -1159,25 +1158,27 @@ JS_IdToProtoKey(JSContext* cx, HandleId 
     return static_cast<JSProtoKey>(stdnm - standard_class_names);
 }
 
 JS_PUBLIC_API(JSObject*)
 JS_GetObjectPrototype(JSContext* cx, HandleObject forObj)
 {
     CHECK_REQUEST(cx);
     assertSameCompartment(cx, forObj);
-    return forObj->global().getOrCreateObjectPrototype(cx);
+    Rooted<GlobalObject*> global(cx, &forObj->global());
+    return GlobalObject::getOrCreateObjectPrototype(cx, global);
 }
 
 JS_PUBLIC_API(JSObject*)
 JS_GetFunctionPrototype(JSContext* cx, HandleObject forObj)
 {
     CHECK_REQUEST(cx);
     assertSameCompartment(cx, forObj);
-    return forObj->global().getOrCreateFunctionPrototype(cx);
+    Rooted<GlobalObject*> global(cx, &forObj->global());
+    return GlobalObject::getOrCreateFunctionPrototype(cx, global);
 }
 
 JS_PUBLIC_API(JSObject*)
 JS_GetArrayPrototype(JSContext* cx, HandleObject forObj)
 {
     CHECK_REQUEST(cx);
     assertSameCompartment(cx, forObj);
     Rooted<GlobalObject*> global(cx, &forObj->global());
@@ -5920,47 +5921,50 @@ JS_NewUCRegExpObject(JSContext* cx, cons
 
 JS_PUBLIC_API(bool)
 JS_SetRegExpInput(JSContext* cx, HandleObject obj, HandleString input)
 {
     AssertHeapIsIdle(cx);
     CHECK_REQUEST(cx);
     assertSameCompartment(cx, input);
 
-    RegExpStatics* res = obj->as<GlobalObject>().getRegExpStatics(cx);
+    Handle<GlobalObject*> global = obj.as<GlobalObject>();
+    RegExpStatics* res = GlobalObject::getRegExpStatics(cx, global);
     if (!res)
         return false;
 
     res->reset(cx, input);
     return true;
 }
 
 JS_PUBLIC_API(bool)
 JS_ClearRegExpStatics(JSContext* cx, HandleObject obj)
 {
     AssertHeapIsIdle(cx);
     CHECK_REQUEST(cx);
     MOZ_ASSERT(obj);
 
-    RegExpStatics* res = obj->as<GlobalObject>().getRegExpStatics(cx);
+    Handle<GlobalObject*> global = obj.as<GlobalObject>();
+    RegExpStatics* res = GlobalObject::getRegExpStatics(cx, global);
     if (!res)
         return false;
 
     res->clear();
     return true;
 }
 
 JS_PUBLIC_API(bool)
 JS_ExecuteRegExp(JSContext* cx, HandleObject obj, HandleObject reobj, char16_t* chars,
                  size_t length, size_t* indexp, bool test, MutableHandleValue rval)
 {
     AssertHeapIsIdle(cx);
     CHECK_REQUEST(cx);
 
-    RegExpStatics* res = obj->as<GlobalObject>().getRegExpStatics(cx);
+    Handle<GlobalObject*> global = obj.as<GlobalObject>();
+    RegExpStatics* res = GlobalObject::getRegExpStatics(cx, global);
     if (!res)
         return false;
 
     RootedLinearString input(cx, NewStringCopyN<CanGC>(cx, chars, length));
     if (!input)
         return false;
 
     return ExecuteRegExpLegacy(cx, res, reobj->as<RegExpObject>(), input, indexp, test, rval);
--- a/js/src/jsarray.cpp
+++ b/js/src/jsarray.cpp
@@ -3256,17 +3256,17 @@ js::ArrayConstructorOneArg(JSContext* cx
     uint32_t length = uint32_t(lengthInt);
     return NewPartlyAllocatedArrayTryUseGroup(cx, group, length);
 }
 
 static JSObject*
 CreateArrayPrototype(JSContext* cx, JSProtoKey key)
 {
     MOZ_ASSERT(key == JSProto_Array);
-    RootedObject proto(cx, cx->global()->getOrCreateObjectPrototype(cx));
+    RootedObject proto(cx, GlobalObject::getOrCreateObjectPrototype(cx, cx->global()));
     if (!proto)
         return nullptr;
 
     RootedObjectGroup group(cx, ObjectGroup::defaultNewGroup(cx, &ArrayObject::class_,
                                                              TaggedProto(proto)));
     if (!group)
         return nullptr;
 
--- a/js/src/jsbool.cpp
+++ b/js/src/jsbool.cpp
@@ -132,24 +132,24 @@ Boolean(JSContext* cx, unsigned argc, Va
     return true;
 }
 
 JSObject*
 js::InitBooleanClass(JSContext* cx, HandleObject obj)
 {
     MOZ_ASSERT(obj->isNative());
 
-    Rooted<GlobalObject*> global(cx, &obj->as<GlobalObject>());
+    Handle<GlobalObject*> global = obj.as<GlobalObject>();
 
-    Rooted<BooleanObject*> booleanProto(cx, global->createBlankPrototype<BooleanObject>(cx));
+    Rooted<BooleanObject*> booleanProto(cx, GlobalObject::createBlankPrototype<BooleanObject>(cx, global));
     if (!booleanProto)
         return nullptr;
     booleanProto->setFixedSlot(BooleanObject::PRIMITIVE_VALUE_SLOT, BooleanValue(false));
 
-    RootedFunction ctor(cx, global->createConstructor(cx, Boolean, cx->names().Boolean, 1));
+    RootedFunction ctor(cx, GlobalObject::createConstructor(cx, Boolean, cx->names().Boolean, 1));
     if (!ctor)
         return nullptr;
 
     if (!LinkConstructorAndPrototype(cx, ctor, booleanProto))
         return nullptr;
 
     if (!DefinePropertiesAndFunctions(cx, booleanProto, nullptr, boolean_methods))
         return nullptr;
--- a/js/src/jsdate.cpp
+++ b/js/src/jsdate.cpp
@@ -3232,17 +3232,17 @@ js::DateConstructor(JSContext* cx, unsig
 
     return DateMultipleArguments(cx, args);
 }
 
 // ES6 final draft 20.3.4.
 static JSObject*
 CreateDatePrototype(JSContext* cx, JSProtoKey key)
 {
-    return cx->global()->createBlankPrototype(cx, &DateObject::protoClass_);
+    return GlobalObject::createBlankPrototype(cx, cx->global(), &DateObject::protoClass_);
 }
 
 static bool
 FinishDateClassInit(JSContext* cx, HandleObject ctor, HandleObject proto)
 {
     /*
      * Date.prototype.toGMTString has the same initial value as
      * Date.prototype.toUTCString.
--- a/js/src/jsexn.cpp
+++ b/js/src/jsexn.cpp
@@ -511,24 +511,27 @@ exn_toSource(JSContext* cx, unsigned arg
 }
 #endif
 
 /* static */ JSObject*
 ErrorObject::createProto(JSContext* cx, JSProtoKey key)
 {
     JSExnType type = ExnTypeFromProtoKey(key);
 
-    if (type == JSEXN_ERR)
-        return cx->global()->createBlankPrototype(cx, &ErrorObject::protoClasses[JSEXN_ERR]);
+    if (type == JSEXN_ERR) {
+        return GlobalObject::createBlankPrototype(cx, cx->global(),
+                                                  &ErrorObject::protoClasses[JSEXN_ERR]);
+    }
 
     RootedObject protoProto(cx, GlobalObject::getOrCreateErrorPrototype(cx, cx->global()));
     if (!protoProto)
         return nullptr;
 
-    return cx->global()->createBlankPrototypeInheriting(cx, &ErrorObject::protoClasses[type],
+    return GlobalObject::createBlankPrototypeInheriting(cx, cx->global(),
+                                                        &ErrorObject::protoClasses[type],
                                                         protoProto);
 }
 
 /* static */ JSObject*
 ErrorObject::createConstructor(JSContext* cx, JSProtoKey key)
 {
     JSExnType type = ExnTypeFromProtoKey(key);
     RootedObject ctor(cx);
--- a/js/src/jsfun.cpp
+++ b/js/src/jsfun.cpp
@@ -412,17 +412,17 @@ ResolveInterpretedFunctionPrototype(JSCo
     // that case, per the 15 July 2013 ES6 draft, section 15.19.3, its parent is
     // the GeneratorObjectPrototype singleton.
     bool isStarGenerator = fun->isStarGenerator();
     Rooted<GlobalObject*> global(cx, &fun->global());
     RootedObject objProto(cx);
     if (isStarGenerator)
         objProto = GlobalObject::getOrCreateStarGeneratorObjectPrototype(cx, global);
     else
-        objProto = fun->global().getOrCreateObjectPrototype(cx);
+        objProto = GlobalObject::getOrCreateObjectPrototype(cx, global);
     if (!objProto)
         return false;
 
     RootedPlainObject proto(cx, NewObjectWithGivenProto<PlainObject>(cx, objProto,
                                                                      SingletonObject));
     if (!proto)
         return false;
 
--- a/js/src/jsiter.cpp
+++ b/js/src/jsiter.cpp
@@ -938,17 +938,17 @@ js::GetIteratorObject(JSContext* cx, Han
 }
 
 JSObject*
 js::CreateItrResultObject(JSContext* cx, HandleValue value, bool done)
 {
     // FIXME: We can cache the iterator result object shape somewhere.
     AssertHeapIsIdle(cx);
 
-    RootedObject proto(cx, cx->global()->getOrCreateObjectPrototype(cx));
+    RootedObject proto(cx, GlobalObject::getOrCreateObjectPrototype(cx, cx->global()));
     if (!proto)
         return nullptr;
 
     RootedPlainObject obj(cx, NewObjectWithGivenProto<PlainObject>(cx, proto));
     if (!obj)
         return nullptr;
 
     if (!DefineProperty(cx, obj, cx->names().value, value))
@@ -1502,17 +1502,17 @@ static const JSFunctionSpec iterator_pro
 };
 
 /* static */ bool
 GlobalObject::initIteratorProto(JSContext* cx, Handle<GlobalObject*> global)
 {
     if (global->getReservedSlot(ITERATOR_PROTO).isObject())
         return true;
 
-    RootedObject proto(cx, global->createBlankPrototype<PlainObject>(cx));
+    RootedObject proto(cx, GlobalObject::createBlankPrototype<PlainObject>(cx, global));
     if (!proto || !DefinePropertiesAndFunctions(cx, proto, nullptr, iterator_proto_methods))
         return false;
 
     global->setReservedSlot(ITERATOR_PROTO, ObjectValue(*proto));
     return true;
 }
 
 /* static */ bool
@@ -1521,17 +1521,18 @@ GlobalObject::initArrayIteratorProto(JSC
     if (global->getReservedSlot(ARRAY_ITERATOR_PROTO).isObject())
         return true;
 
     RootedObject iteratorProto(cx, GlobalObject::getOrCreateIteratorPrototype(cx, global));
     if (!iteratorProto)
         return false;
 
     const Class* cls = &ArrayIteratorPrototypeClass;
-    RootedObject proto(cx, global->createBlankPrototypeInheriting(cx, cls, iteratorProto));
+    RootedObject proto(cx, GlobalObject::createBlankPrototypeInheriting(cx, global, cls,
+                                                                        iteratorProto));
     if (!proto ||
         !DefinePropertiesAndFunctions(cx, proto, nullptr, array_iterator_methods) ||
         !DefineToStringTag(cx, proto, cx->names().ArrayIterator))
     {
         return false;
     }
 
     global->setReservedSlot(ARRAY_ITERATOR_PROTO, ObjectValue(*proto));
@@ -1544,17 +1545,18 @@ GlobalObject::initStringIteratorProto(JS
     if (global->getReservedSlot(STRING_ITERATOR_PROTO).isObject())
         return true;
 
     RootedObject iteratorProto(cx, GlobalObject::getOrCreateIteratorPrototype(cx, global));
     if (!iteratorProto)
         return false;
 
     const Class* cls = &StringIteratorPrototypeClass;
-    RootedObject proto(cx, global->createBlankPrototypeInheriting(cx, cls, iteratorProto));
+    RootedObject proto(cx, GlobalObject::createBlankPrototypeInheriting(cx, global, cls,
+                                                                        iteratorProto));
     if (!proto ||
         !DefinePropertiesAndFunctions(cx, proto, nullptr, string_iterator_methods) ||
         !DefineToStringTag(cx, proto, cx->names().StringIterator))
     {
         return false;
     }
 
     global->setReservedSlot(STRING_ITERATOR_PROTO, ObjectValue(*proto));
@@ -1565,29 +1567,30 @@ JSObject*
 js::InitLegacyIteratorClass(JSContext* cx, HandleObject obj)
 {
     Handle<GlobalObject*> global = obj.as<GlobalObject>();
 
     if (global->getPrototype(JSProto_Iterator).isObject())
         return &global->getPrototype(JSProto_Iterator).toObject();
 
     RootedObject iteratorProto(cx);
-    iteratorProto = global->createBlankPrototype(cx, &PropertyIteratorObject::class_);
+    iteratorProto = GlobalObject::createBlankPrototype(cx, global,
+                                                       &PropertyIteratorObject::class_);
     if (!iteratorProto)
         return nullptr;
 
     NativeIterator* ni = NativeIterator::allocateIterator(cx, 0, 0);
     if (!ni)
         return nullptr;
 
     iteratorProto->as<PropertyIteratorObject>().setNativeIterator(ni);
     ni->init(nullptr, nullptr, 0 /* flags */, 0, 0);
 
     Rooted<JSFunction*> ctor(cx);
-    ctor = global->createConstructor(cx, IteratorConstructor, cx->names().Iterator, 2);
+    ctor = GlobalObject::createConstructor(cx, IteratorConstructor, cx->names().Iterator, 2);
     if (!ctor)
         return nullptr;
     if (!LinkConstructorAndPrototype(cx, ctor, iteratorProto))
         return nullptr;
     if (!DefinePropertiesAndFunctions(cx, iteratorProto, nullptr, legacy_iterator_methods))
         return nullptr;
     if (!GlobalObject::initBuiltinConstructor(cx, global, JSProto_Iterator,
                                               ctor, iteratorProto))
@@ -1598,17 +1601,18 @@ js::InitLegacyIteratorClass(JSContext* c
     return &global->getPrototype(JSProto_Iterator).toObject();
 }
 
 JSObject*
 js::InitStopIterationClass(JSContext* cx, HandleObject obj)
 {
     Handle<GlobalObject*> global = obj.as<GlobalObject>();
     if (!global->getPrototype(JSProto_StopIteration).isObject()) {
-        RootedObject proto(cx, global->createBlankPrototype(cx, &StopIterationObject::class_));
+        RootedObject proto(cx, GlobalObject::createBlankPrototype(cx, global,
+                                                                  &StopIterationObject::class_));
         if (!proto || !FreezeObject(cx, proto))
             return nullptr;
 
         // This should use a non-JSProtoKey'd slot, but this is easier for now.
         if (!GlobalObject::initBuiltinConstructor(cx, global, JSProto_StopIteration, proto, proto))
             return nullptr;
 
         global->setConstructor(JSProto_StopIteration, ObjectValue(*proto));
--- a/js/src/jsmath.cpp
+++ b/js/src/jsmath.cpp
@@ -1367,17 +1367,18 @@ static const JSFunctionSpec math_static_
     JS_INLINABLE_FN("sign",   math_sign,            1, 0, MathSign),
     JS_INLINABLE_FN("cbrt",   math_cbrt,            1, 0, MathCbrt),
     JS_FS_END
 };
 
 JSObject*
 js::InitMathClass(JSContext* cx, HandleObject obj)
 {
-    RootedObject proto(cx, obj->as<GlobalObject>().getOrCreateObjectPrototype(cx));
+    Handle<GlobalObject*> global = obj.as<GlobalObject>();
+    RootedObject proto(cx, GlobalObject::getOrCreateObjectPrototype(cx, global));
     if (!proto)
         return nullptr;
     RootedObject Math(cx, NewObjectWithGivenProto(cx, &MathClass, proto, SingletonObject));
     if (!Math)
         return nullptr;
 
     if (!JS_DefineProperty(cx, obj, js_Math_str, Math, JSPROP_RESOLVING,
                            JS_STUBGETTER, JS_STUBSETTER))
--- a/js/src/jsnum.cpp
+++ b/js/src/jsnum.cpp
@@ -1204,25 +1204,26 @@ js::FinishRuntimeNumberState(JSRuntime* 
 JSObject*
 js::InitNumberClass(JSContext* cx, HandleObject obj)
 {
     MOZ_ASSERT(obj->isNative());
 
     /* XXX must do at least once per new thread, so do it per JSContext... */
     FIX_FPU();
 
-    Rooted<GlobalObject*> global(cx, &obj->as<GlobalObject>());
+    Handle<GlobalObject*> global = obj.as<GlobalObject>();
 
-    RootedObject numberProto(cx, global->createBlankPrototype(cx, &NumberObject::class_));
+    RootedObject numberProto(cx, GlobalObject::createBlankPrototype(cx, global,
+                                                                    &NumberObject::class_));
     if (!numberProto)
         return nullptr;
     numberProto->as<NumberObject>().setPrimitiveValue(0);
 
     RootedFunction ctor(cx);
-    ctor = global->createConstructor(cx, Number, cx->names().Number, 1);
+    ctor = GlobalObject::createConstructor(cx, Number, cx->names().Number, 1);
     if (!ctor)
         return nullptr;
 
     if (!LinkConstructorAndPrototype(cx, ctor, numberProto))
         return nullptr;
 
     /*
      * Our NaN must be one particular canonical value, because we rely on NaN
--- a/js/src/jsobj.cpp
+++ b/js/src/jsobj.cpp
@@ -1998,17 +1998,18 @@ js::GetObjectFromIncumbentGlobal(JSConte
     RootedObject globalObj(cx, cx->runtime()->getIncumbentGlobal(cx));
     if (!globalObj) {
         obj.set(nullptr);
         return true;
     }
 
     {
         AutoCompartment ac(cx, globalObj);
-        obj.set(globalObj->as<GlobalObject>().getOrCreateObjectPrototype(cx));
+        Handle<GlobalObject*> global = globalObj.as<GlobalObject>();
+        obj.set(GlobalObject::getOrCreateObjectPrototype(cx, global));
         if (!obj)
             return false;
     }
 
     // The object might be from a different compartment, so wrap it.
     if (obj && !cx->compartment()->wrap(cx, obj))
         return false;
 
@@ -2573,17 +2574,17 @@ js::SetPrototype(JSContext* cx, HandleOb
         return false;
     if (!extensible)
         return result.fail(JSMSG_CANT_SET_PROTO);
 
     // If this is a global object, resolve the Object class so that its
     // [[Prototype]] chain is always properly immutable, even in the presence
     // of lazy standard classes.
     if (obj->is<GlobalObject>()) {
-        Rooted<GlobalObject*> global(cx, &obj->as<GlobalObject>());
+        Handle<GlobalObject*> global = obj.as<GlobalObject>();
         if (!GlobalObject::ensureConstructor(cx, global, JSProto_Object))
             return false;
     }
 
     /*
      * ES6 9.1.2 step 6 forbids generating cyclical prototype chains. But we
      * have to do this comparison on the observable WindowProxy, not on the
      * possibly-Window object we're setting the proto on.
--- a/js/src/json.cpp
+++ b/js/src/json.cpp
@@ -966,19 +966,19 @@ static const JSFunctionSpec json_static_
     JS_FN("parse",          json_parse,         2, 0),
     JS_FN("stringify",      json_stringify,     3, 0),
     JS_FS_END
 };
 
 JSObject*
 js::InitJSONClass(JSContext* cx, HandleObject obj)
 {
-    Rooted<GlobalObject*> global(cx, &obj->as<GlobalObject>());
+    Handle<GlobalObject*> global = obj.as<GlobalObject>();
 
-    RootedObject proto(cx, global->getOrCreateObjectPrototype(cx));
+    RootedObject proto(cx, GlobalObject::getOrCreateObjectPrototype(cx, global));
     if (!proto)
         return nullptr;
     RootedObject JSON(cx, NewObjectWithGivenProto(cx, &JSONClass, proto, SingletonObject));
     if (!JSON)
         return nullptr;
 
     if (!JS_DefineProperty(cx, global, js_JSON_str, JSON, JSPROP_RESOLVING,
                            JS_STUBGETTER, JS_STUBSETTER))
--- a/js/src/jsstr.cpp
+++ b/js/src/jsstr.cpp
@@ -3002,27 +3002,27 @@ StringObject::assignInitialShape(Exclusi
                                 JSPROP_PERMANENT | JSPROP_READONLY);
 }
 
 JSObject*
 js::InitStringClass(JSContext* cx, HandleObject obj)
 {
     MOZ_ASSERT(obj->isNative());
 
-    Rooted<GlobalObject*> global(cx, &obj->as<GlobalObject>());
+    Handle<GlobalObject*> global = obj.as<GlobalObject>();
 
     Rooted<JSString*> empty(cx, cx->runtime()->emptyString);
-    RootedObject proto(cx, global->createBlankPrototype(cx, &StringObject::class_));
+    RootedObject proto(cx, GlobalObject::createBlankPrototype(cx, global, &StringObject::class_));
     if (!proto || !proto->as<StringObject>().init(cx, empty))
         return nullptr;
 
     /* Now create the String function. */
     RootedFunction ctor(cx);
-    ctor = global->createConstructor(cx, StringConstructor, cx->names().String, 1,
-                                     AllocKind::FUNCTION, &jit::JitInfo_String);
+    ctor = GlobalObject::createConstructor(cx, StringConstructor, cx->names().String, 1,
+                                           AllocKind::FUNCTION, &jit::JitInfo_String);
     if (!ctor)
         return nullptr;
 
     if (!LinkConstructorAndPrototype(cx, ctor, proto))
         return nullptr;
 
     if (!DefinePropertiesAndFunctions(cx, proto, nullptr, string_methods) ||
         !DefinePropertiesAndFunctions(cx, ctor, nullptr, string_static_methods))
--- a/js/src/proxy/Proxy.cpp
+++ b/js/src/proxy/Proxy.cpp
@@ -739,19 +739,19 @@ ProxyObject::renew(JSContext* cx, const 
 JS_FRIEND_API(JSObject*)
 js::InitProxyClass(JSContext* cx, HandleObject obj)
 {
     static const JSFunctionSpec static_methods[] = {
         JS_FN("revocable",      proxy_revocable,       2, 0),
         JS_FS_END
     };
 
-    Rooted<GlobalObject*> global(cx, &obj->as<GlobalObject>());
+    Handle<GlobalObject*> global = obj.as<GlobalObject>();
     RootedFunction ctor(cx);
-    ctor = global->createConstructor(cx, proxy, cx->names().Proxy, 2);
+    ctor = GlobalObject::createConstructor(cx, proxy, cx->names().Proxy, 2);
     if (!ctor)
         return nullptr;
 
     if (!JS_DefineFunctions(cx, ctor, static_methods))
         return nullptr;
     if (!JS_DefineProperty(cx, obj, "Proxy", ctor, JSPROP_RESOLVING, JS_STUBGETTER, JS_STUBSETTER))
         return nullptr;
 
--- a/js/src/vm/ArgumentsObject.cpp
+++ b/js/src/vm/ArgumentsObject.cpp
@@ -209,17 +209,17 @@ struct CopyScriptFrameIterArgs
 
 ArgumentsObject*
 ArgumentsObject::createTemplateObject(JSContext* cx, bool mapped)
 {
     const Class* clasp = mapped
                          ? &MappedArgumentsObject::class_
                          : &UnmappedArgumentsObject::class_;
 
-    RootedObject proto(cx, cx->global()->getOrCreateObjectPrototype(cx));
+    RootedObject proto(cx, GlobalObject::getOrCreateObjectPrototype(cx, cx->global()));
     if (!proto)
         return nullptr;
 
     RootedObjectGroup group(cx, ObjectGroup::defaultNewGroup(cx, clasp, TaggedProto(proto.get())));
     if (!group)
         return nullptr;
 
     RootedShape shape(cx, EmptyShape::getInitialShape(cx, clasp, TaggedProto(proto),
--- a/js/src/vm/ArrayBufferObject.cpp
+++ b/js/src/vm/ArrayBufferObject.cpp
@@ -97,17 +97,17 @@ js::ToClampedIndex(JSContext* cx, Handle
 
 /*
  * ArrayBufferObject (base)
  */
 
 static JSObject*
 CreateArrayBufferPrototype(JSContext* cx, JSProtoKey key)
 {
-    return cx->global()->createBlankPrototype(cx, &ArrayBufferObject::protoClass_);
+    return GlobalObject::createBlankPrototype(cx, cx->global(), &ArrayBufferObject::protoClass_);
 }
 
 static const ClassOps ArrayBufferObjectClassOps = {
     nullptr,        /* addProperty */
     nullptr,        /* delProperty */
     nullptr,        /* getProperty */
     nullptr,        /* setProperty */
     nullptr,        /* enumerate */
--- a/js/src/vm/Debugger.cpp
+++ b/js/src/vm/Debugger.cpp
@@ -7339,18 +7339,18 @@ ScriptedOnPopHandler::onPop(JSContext* c
         return false;
 
     return ParseResumptionValue(cx, rval, statusp, vp);
 };
 
 /* static */ NativeObject*
 DebuggerFrame::initClass(JSContext* cx, HandleObject dbgCtor, HandleObject obj)
 {
-    Rooted<GlobalObject*> global(cx, &obj->as<GlobalObject>());
-    RootedObject objProto(cx, global->getOrCreateObjectPrototype(cx));
+    Handle<GlobalObject*> global = obj.as<GlobalObject>();
+    RootedObject objProto(cx, GlobalObject::getOrCreateObjectPrototype(cx, global));
 
     return InitClass(cx, dbgCtor, objProto, &class_, construct, 0, properties_,
                      methods_, nullptr, nullptr);
 }
 
 /* static */ DebuggerFrame*
 DebuggerFrame::create(JSContext* cx, HandleObject proto, AbstractFramePtr referent,
                       const FrameIter* maybeIter, HandleNativeObject debugger)
@@ -9639,18 +9639,18 @@ const JSFunctionSpec DebuggerObject::met
     JS_FN("unsafeDereference", DebuggerObject::unsafeDereferenceMethod, 0, 0),
     JS_FN("unwrap", DebuggerObject::unwrapMethod, 0, 0),
     JS_FS_END
 };
 
 /* static */ NativeObject*
 DebuggerObject::initClass(JSContext* cx, HandleObject obj, HandleObject debugCtor)
 {
-    Rooted<GlobalObject*> global(cx, &obj->as<GlobalObject>());
-    RootedObject objProto(cx, global->getOrCreateObjectPrototype(cx));
+    Handle<GlobalObject*> global = obj.as<GlobalObject>();
+    RootedObject objProto(cx, GlobalObject::getOrCreateObjectPrototype(cx, global));
 
     RootedNativeObject objectProto(cx, InitClass(cx, debugCtor, objProto, &class_,
                                                  construct, 0, properties_,
                                                  methods_, nullptr, nullptr));
 
     if (!objectProto)
         return nullptr;
 
@@ -10832,18 +10832,18 @@ const JSFunctionSpec DebuggerEnvironment
     JS_FN("getVariable", DebuggerEnvironment::getVariableMethod, 1, 0),
     JS_FN("setVariable", DebuggerEnvironment::setVariableMethod, 2, 0),
     JS_FS_END
 };
 
 /* static */ NativeObject*
 DebuggerEnvironment::initClass(JSContext* cx, HandleObject dbgCtor, HandleObject obj)
 {
-    Rooted<GlobalObject*> global(cx, &obj->as<GlobalObject>());
-    RootedObject objProto(cx, global->getOrCreateObjectPrototype(cx));
+    Handle<GlobalObject*> global = obj.as<GlobalObject>();
+    RootedObject objProto(cx, GlobalObject::getOrCreateObjectPrototype(cx, global));
 
     return InitClass(cx, dbgCtor, objProto, &DebuggerEnvironment::class_, construct, 0,
                      properties_, methods_, nullptr, nullptr);
 }
 
 /* static */ DebuggerEnvironment*
 DebuggerEnvironment::create(JSContext* cx, HandleObject proto, HandleObject referent,
                             HandleNativeObject debugger)
@@ -11198,19 +11198,19 @@ JS_DefineDebuggerObject(JSContext* cx, H
         frameProto(cx),
         scriptProto(cx),
         sourceProto(cx),
         objectProto(cx),
         envProto(cx),
         memoryProto(cx);
     RootedObject debuggeeWouldRunProto(cx);
     RootedValue debuggeeWouldRunCtor(cx);
-    Rooted<GlobalObject*> global(cx, &obj->as<GlobalObject>());
-
-    objProto = global->getOrCreateObjectPrototype(cx);
+    Handle<GlobalObject*> global = obj.as<GlobalObject>();
+
+    objProto = GlobalObject::getOrCreateObjectPrototype(cx, global);
     if (!objProto)
         return false;
     debugProto = InitClass(cx, obj,
                            objProto, &Debugger::class_, Debugger::construct,
                            1, Debugger::properties, Debugger::methods, nullptr,
                            Debugger::static_methods, debugCtor.address());
     if (!debugProto)
         return false;
--- a/js/src/vm/GeneratorObject.cpp
+++ b/js/src/vm/GeneratorObject.cpp
@@ -251,26 +251,26 @@ static const JSFunctionSpec legacy_gener
     JS_FS_END
 };
 
 #undef JSPROP_ROPERM
 
 static JSObject*
 NewSingletonObjectWithObjectPrototype(JSContext* cx, Handle<GlobalObject*> global)
 {
-    RootedObject proto(cx, global->getOrCreateObjectPrototype(cx));
+    RootedObject proto(cx, GlobalObject::getOrCreateObjectPrototype(cx, global));
     if (!proto)
         return nullptr;
     return NewObjectWithGivenProto<PlainObject>(cx, proto, SingletonObject);
 }
 
 JSObject*
 js::NewSingletonObjectWithFunctionPrototype(JSContext* cx, Handle<GlobalObject*> global)
 {
-    RootedObject proto(cx, global->getOrCreateFunctionPrototype(cx));
+    RootedObject proto(cx, GlobalObject::getOrCreateFunctionPrototype(cx, global));
     if (!proto)
         return nullptr;
     return NewObjectWithGivenProto<PlainObject>(cx, proto, SingletonObject);
 }
 
 /* static */ bool
 GlobalObject::initLegacyGeneratorProto(JSContext* cx, Handle<GlobalObject*> global)
 {
@@ -292,19 +292,19 @@ GlobalObject::initStarGenerators(JSConte
 {
     if (global->getReservedSlot(STAR_GENERATOR_OBJECT_PROTO).isObject())
         return true;
 
     RootedObject iteratorProto(cx, GlobalObject::getOrCreateIteratorPrototype(cx, global));
     if (!iteratorProto)
         return false;
 
-    RootedObject genObjectProto(cx, global->createBlankPrototypeInheriting(cx,
-                                                                           &PlainObject::class_,
-                                                                           iteratorProto));
+    RootedObject genObjectProto(cx, GlobalObject::createBlankPrototypeInheriting(cx, global,
+                                                                                 &PlainObject::class_,
+                                                                                 iteratorProto));
     if (!genObjectProto)
         return false;
     if (!DefinePropertiesAndFunctions(cx, genObjectProto, nullptr, star_generator_methods) ||
         !DefineToStringTag(cx, genObjectProto, cx->names().Generator))
     {
         return false;
     }
 
--- a/js/src/vm/GlobalObject.cpp
+++ b/js/src/vm/GlobalObject.cpp
@@ -332,17 +332,17 @@ GlobalObject::createInternal(JSContext* 
     if (!JSObject::setQualifiedVarObj(cx, global))
         return nullptr;
     if (!JSObject::setDelegate(cx, global))
         return nullptr;
 
     return global;
 }
 
-GlobalObject*
+/* static */ GlobalObject*
 GlobalObject::new_(JSContext* cx, const Class* clasp, JSPrincipals* principals,
                    JS::OnNewGlobalHookOption hookOption,
                    const JS::CompartmentOptions& options)
 {
     MOZ_ASSERT(!cx->isExceptionPending());
     MOZ_ASSERT(!cx->runtime()->isAtomsCompartment(cx->compartment()));
 
     JSRuntime* rt = cx->runtime();
@@ -393,17 +393,17 @@ GlobalObject::emptyGlobalScope() const
     MOZ_ASSERT(v.isPrivateGCThing() && v.traceKind() == JS::TraceKind::Scope);
     return static_cast<Scope*>(v.toGCThing())->as<GlobalScope>();
 }
 
 /* static */ bool
 GlobalObject::getOrCreateEval(JSContext* cx, Handle<GlobalObject*> global,
                               MutableHandleObject eval)
 {
-    if (!global->getOrCreateObjectPrototype(cx))
+    if (!getOrCreateObjectPrototype(cx, global))
         return false;
     eval.set(&global->getSlot(EVAL).toObject());
     return true;
 }
 
 bool
 GlobalObject::valueIsEval(const Value& val)
 {
@@ -568,17 +568,17 @@ GlobalObject::warnOnceAbout(JSContext* c
         if (v.isUndefined())
             v.init(global, HeapSlot::Slot, WARNED_ONCE_FLAGS, Int32Value(flags | flag));
         else
             v.set(global, HeapSlot::Slot, WARNED_ONCE_FLAGS, Int32Value(flags | flag));
     }
     return true;
 }
 
-JSFunction*
+/* static */ JSFunction*
 GlobalObject::createConstructor(JSContext* cx, Native ctor, JSAtom* nameArg, unsigned length,
                                 gc::AllocKind kind, const JSJitInfo* jitInfo)
 {
     RootedAtom name(cx, nameArg);
     JSFunction* fun = NewNativeConstructor(cx, ctor, length, name, kind);
     if (!fun)
         return nullptr;
 
@@ -596,32 +596,31 @@ CreateBlankProto(JSContext* cx, const Cl
     RootedNativeObject blankProto(cx, NewNativeObjectWithGivenProto(cx, clasp, proto,
                                                                     SingletonObject));
     if (!blankProto || !JSObject::setDelegate(cx, blankProto))
         return nullptr;
 
     return blankProto;
 }
 
-NativeObject*
-GlobalObject::createBlankPrototype(JSContext* cx, const Class* clasp)
+/* static */ NativeObject*
+GlobalObject::createBlankPrototype(JSContext* cx, Handle<GlobalObject*> global, const Class* clasp)
 {
-    Rooted<GlobalObject*> self(cx, this);
-    RootedObject objectProto(cx, getOrCreateObjectPrototype(cx));
+    RootedObject objectProto(cx, getOrCreateObjectPrototype(cx, global));
     if (!objectProto)
         return nullptr;
 
-    return CreateBlankProto(cx, clasp, objectProto, self);
+    return CreateBlankProto(cx, clasp, objectProto, global);
 }
 
-NativeObject*
-GlobalObject::createBlankPrototypeInheriting(JSContext* cx, const Class* clasp, HandleObject proto)
+/* static */ NativeObject*
+GlobalObject::createBlankPrototypeInheriting(JSContext* cx, Handle<GlobalObject*> global,
+                                             const Class* clasp, HandleObject proto)
 {
-    Rooted<GlobalObject*> self(cx, this);
-    return CreateBlankProto(cx, clasp, proto, self);
+    return CreateBlankProto(cx, clasp, proto, global);
 }
 
 bool
 js::LinkConstructorAndPrototype(JSContext* cx, JSObject* ctor_, JSObject* proto_,
                                 unsigned prototypeAttrs, unsigned constructorAttrs)
 {
     RootedObject ctor(cx, ctor_), proto(cx, proto_);
 
@@ -725,31 +724,29 @@ GlobalObject::getOrCreateForOfPICObject(
 }
 
 bool
 GlobalObject::hasRegExpStatics() const
 {
     return !getSlot(REGEXP_STATICS).isUndefined();
 }
 
-RegExpStatics*
-GlobalObject::getRegExpStatics(ExclusiveContext* cx) const
+/* static */ RegExpStatics*
+GlobalObject::getRegExpStatics(ExclusiveContext* cx, Handle<GlobalObject*> global)
 {
     MOZ_ASSERT(cx);
-    Rooted<GlobalObject*> self(cx, const_cast<GlobalObject*>(this));
-
     RegExpStaticsObject* resObj = nullptr;
-    const Value& val = this->getSlot(REGEXP_STATICS);
+    const Value& val = global->getSlot(REGEXP_STATICS);
     if (!val.isObject()) {
         MOZ_ASSERT(val.isUndefined());
-        resObj = RegExpStatics::create(cx, self);
+        resObj = RegExpStatics::create(cx, global);
         if (!resObj)
             return nullptr;
 
-        self->initSlot(REGEXP_STATICS, ObjectValue(*resObj));
+        global->initSlot(REGEXP_STATICS, ObjectValue(*resObj));
     } else {
         resObj = &val.toObject().as<RegExpStaticsObject>();
     }
     return static_cast<RegExpStatics*>(resObj->getPrivate(/* nfixed = */ 1));
 }
 
 RegExpStatics*
 GlobalObject::getAlreadyCreatedRegExpStatics() const
@@ -862,12 +859,12 @@ GlobalObject::addIntrinsicValue(JSContex
 
     holder->setSlot(shape->slot(), value);
     return true;
 }
 
 /* static */ bool
 GlobalObject::ensureModulePrototypesCreated(JSContext *cx, Handle<GlobalObject*> global)
 {
-    return global->getOrCreateObject(cx, MODULE_PROTO, initModuleProto) &&
-           global->getOrCreateObject(cx, IMPORT_ENTRY_PROTO, initImportEntryProto) &&
-           global->getOrCreateObject(cx, EXPORT_ENTRY_PROTO, initExportEntryProto);
+    return getOrCreateObject(cx, global, MODULE_PROTO, initModuleProto) &&
+           getOrCreateObject(cx, global, IMPORT_ENTRY_PROTO, initImportEntryProto) &&
+           getOrCreateObject(cx, global, EXPORT_ENTRY_PROTO, initExportEntryProto);
 }
--- a/js/src/vm/GlobalObject.h
+++ b/js/src/vm/GlobalObject.h
@@ -278,146 +278,150 @@ class GlobalObject : public NativeObject
     static GlobalObject*
     new_(JSContext* cx, const Class* clasp, JSPrincipals* principals,
          JS::OnNewGlobalHookOption hookOption, const JS::CompartmentOptions& options);
 
     /*
      * Create a constructor function with the specified name and length using
      * ctor, a method which creates objects with the given class.
      */
-    JSFunction*
-    createConstructor(JSContext* cx, JSNative ctor, JSAtom* name, unsigned length,
+    static JSFunction*
+    createConstructor(JSContext* cx,  JSNative ctor, JSAtom* name, unsigned length,
                       gc::AllocKind kind = gc::AllocKind::FUNCTION,
                       const JSJitInfo* jitInfo = nullptr);
 
     /*
      * Create an object to serve as [[Prototype]] for instances of the given
      * class, using |Object.prototype| as its [[Prototype]].  Users creating
      * prototype objects with particular internal structure (e.g. reserved
      * slots guaranteed to contain values of particular types) must immediately
      * complete the minimal initialization to make the returned object safe to
      * touch.
      */
-    NativeObject* createBlankPrototype(JSContext* cx, const js::Class* clasp);
+    static NativeObject*
+    createBlankPrototype(JSContext* cx, Handle<GlobalObject*> global, const js::Class* clasp);
 
     /*
      * Identical to createBlankPrototype, but uses proto as the [[Prototype]]
      * of the returned blank prototype.
      */
-    NativeObject* createBlankPrototypeInheriting(JSContext* cx, const js::Class* clasp,
-                                                 HandleObject proto);
+    static NativeObject*
+    createBlankPrototypeInheriting(JSContext* cx, Handle<GlobalObject*> global,
+                                   const js::Class* clasp, HandleObject proto);
 
     template <typename T>
-    T* createBlankPrototype(JSContext* cx) {
-        NativeObject* res = createBlankPrototype(cx, &T::class_);
+    static T*
+    createBlankPrototype(JSContext* cx, Handle<GlobalObject*> global) {
+        NativeObject* res = createBlankPrototype(cx, global, &T::class_);
         return res ? &res->template as<T>() : nullptr;
     }
 
-    NativeObject* getOrCreateObjectPrototype(JSContext* cx) {
-        if (functionObjectClassesInitialized())
-            return &getPrototype(JSProto_Object).toObject().as<NativeObject>();
-        RootedGlobalObject self(cx, this);
-        if (!ensureConstructor(cx, self, JSProto_Object))
+    static NativeObject*
+    getOrCreateObjectPrototype(JSContext* cx, Handle<GlobalObject*> global) {
+        if (global->functionObjectClassesInitialized())
+            return &global->getPrototype(JSProto_Object).toObject().as<NativeObject>();
+        if (!ensureConstructor(cx, global, JSProto_Object))
             return nullptr;
-        return &self->getPrototype(JSProto_Object).toObject().as<NativeObject>();
-    }
-
-    static NativeObject* getOrCreateObjectPrototype(JSContext* cx, Handle<GlobalObject*> global) {
-        return global->getOrCreateObjectPrototype(cx);
+        return &global->getPrototype(JSProto_Object).toObject().as<NativeObject>();
     }
 
-    NativeObject* getOrCreateFunctionPrototype(JSContext* cx) {
-        if (functionObjectClassesInitialized())
-            return &getPrototype(JSProto_Function).toObject().as<NativeObject>();
-        RootedGlobalObject self(cx, this);
-        if (!ensureConstructor(cx, self, JSProto_Object))
+    static NativeObject*
+    getOrCreateFunctionPrototype(JSContext* cx, Handle<GlobalObject*> global) {
+        if (global->functionObjectClassesInitialized())
+            return &global->getPrototype(JSProto_Function).toObject().as<NativeObject>();
+        if (!ensureConstructor(cx, global, JSProto_Object))
             return nullptr;
-        return &self->getPrototype(JSProto_Function).toObject().as<NativeObject>();
+        return &global->getPrototype(JSProto_Function).toObject().as<NativeObject>();
     }
 
-    static NativeObject* getOrCreateFunctionPrototype(JSContext* cx, Handle<GlobalObject*> global) {
-        return global->getOrCreateFunctionPrototype(cx);
-    }
-
-    static NativeObject* getOrCreateArrayPrototype(JSContext* cx, Handle<GlobalObject*> global) {
+    static NativeObject*
+    getOrCreateArrayPrototype(JSContext* cx, Handle<GlobalObject*> global) {
         if (!ensureConstructor(cx, global, JSProto_Array))
             return nullptr;
         return &global->getPrototype(JSProto_Array).toObject().as<NativeObject>();
     }
 
     NativeObject* maybeGetArrayPrototype() {
         if (arrayClassInitialized())
             return &getPrototype(JSProto_Array).toObject().as<NativeObject>();
         return nullptr;
     }
 
-    static NativeObject* getOrCreateBooleanPrototype(JSContext* cx, Handle<GlobalObject*> global) {
+    static NativeObject*
+    getOrCreateBooleanPrototype(JSContext* cx, Handle<GlobalObject*> global) {
         if (!ensureConstructor(cx, global, JSProto_Boolean))
             return nullptr;
         return &global->getPrototype(JSProto_Boolean).toObject().as<NativeObject>();
     }
 
-    static NativeObject* getOrCreateNumberPrototype(JSContext* cx, Handle<GlobalObject*> global) {
+    static NativeObject*
+    getOrCreateNumberPrototype(JSContext* cx, Handle<GlobalObject*> global) {
         if (!ensureConstructor(cx, global, JSProto_Number))
             return nullptr;
         return &global->getPrototype(JSProto_Number).toObject().as<NativeObject>();
     }
 
-    static NativeObject* getOrCreateStringPrototype(JSContext* cx, Handle<GlobalObject*> global) {
+    static NativeObject*
+    getOrCreateStringPrototype(JSContext* cx, Handle<GlobalObject*> global) {
         if (!ensureConstructor(cx, global, JSProto_String))
             return nullptr;
         return &global->getPrototype(JSProto_String).toObject().as<NativeObject>();
     }
 
-    static NativeObject* getOrCreateSymbolPrototype(JSContext* cx, Handle<GlobalObject*> global) {
+    static NativeObject*
+    getOrCreateSymbolPrototype(JSContext* cx, Handle<GlobalObject*> global) {
         if (!ensureConstructor(cx, global, JSProto_Symbol))
             return nullptr;
         return &global->getPrototype(JSProto_Symbol).toObject().as<NativeObject>();
     }
 
-    static NativeObject* getOrCreatePromisePrototype(JSContext* cx, Handle<GlobalObject*> global) {
+    static NativeObject*
+    getOrCreatePromisePrototype(JSContext* cx, Handle<GlobalObject*> global) {
         if (!ensureConstructor(cx, global, JSProto_Promise))
             return nullptr;
         return &global->getPrototype(JSProto_Promise).toObject().as<NativeObject>();
     }
 
-    static NativeObject* getOrCreateRegExpPrototype(JSContext* cx, Handle<GlobalObject*> global) {
+    static NativeObject*
+    getOrCreateRegExpPrototype(JSContext* cx, Handle<GlobalObject*> global) {
         if (!ensureConstructor(cx, global, JSProto_RegExp))
             return nullptr;
         return &global->getPrototype(JSProto_RegExp).toObject().as<NativeObject>();
     }
 
     JSObject* maybeGetRegExpPrototype() {
         if (regexpClassInitialized())
             return &getPrototype(JSProto_RegExp).toObject();
         return nullptr;
     }
 
-    static NativeObject* getOrCreateSavedFramePrototype(JSContext* cx,
-                                                        Handle<GlobalObject*> global) {
+    static NativeObject*
+    getOrCreateSavedFramePrototype(JSContext* cx, Handle<GlobalObject*> global) {
         if (!ensureConstructor(cx, global, JSProto_SavedFrame))
             return nullptr;
         return &global->getPrototype(JSProto_SavedFrame).toObject().as<NativeObject>();
     }
 
-    static JSObject* getOrCreateArrayBufferPrototype(JSContext* cx, Handle<GlobalObject*> global) {
+    static JSObject*
+    getOrCreateArrayBufferPrototype(JSContext* cx, Handle<GlobalObject*> global) {
         if (!ensureConstructor(cx, global, JSProto_ArrayBuffer))
             return nullptr;
         return &global->getPrototype(JSProto_ArrayBuffer).toObject();
     }
 
-    JSObject* getOrCreateSharedArrayBufferPrototype(JSContext* cx, Handle<GlobalObject*> global) {
+    static JSObject*
+    getOrCreateSharedArrayBufferPrototype(JSContext* cx, Handle<GlobalObject*> global) {
         if (!ensureConstructor(cx, global, JSProto_SharedArrayBuffer))
             return nullptr;
         return &global->getPrototype(JSProto_SharedArrayBuffer).toObject();
     }
 
-    static JSObject* getOrCreateCustomErrorPrototype(JSContext* cx,
-                                                     Handle<GlobalObject*> global,
-                                                     JSExnType exnType)
+    static JSObject*
+    getOrCreateCustomErrorPrototype(JSContext* cx, Handle<GlobalObject*> global,
+                                    JSExnType exnType)
     {
         JSProtoKey key = GetExceptionProtoKey(exnType);
         if (!ensureConstructor(cx, global, key))
             return nullptr;
         return &global->getPrototype(key).toObject();
     }
 
     static JSFunction*
@@ -427,66 +431,76 @@ class GlobalObject : public NativeObject
         return &global->getConstructor(JSProto_Error).toObject().as<JSFunction>();
     }
 
     static JSObject*
     getOrCreateErrorPrototype(JSContext* cx, Handle<GlobalObject*> global) {
         return getOrCreateCustomErrorPrototype(cx, global, JSEXN_ERR);
     }
 
-    static NativeObject* getOrCreateSetPrototype(JSContext* cx, Handle<GlobalObject*> global) {
+    static NativeObject*
+    getOrCreateSetPrototype(JSContext* cx, Handle<GlobalObject*> global) {
         if (!ensureConstructor(cx, global, JSProto_Set))
             return nullptr;
         return &global->getPrototype(JSProto_Set).toObject().as<NativeObject>();
     }
 
-    static NativeObject* getOrCreateWeakSetPrototype(JSContext* cx, Handle<GlobalObject*> global) {
+    static NativeObject*
+    getOrCreateWeakSetPrototype(JSContext* cx, Handle<GlobalObject*> global) {
         if (!ensureConstructor(cx, global, JSProto_WeakSet))
             return nullptr;
         return &global->getPrototype(JSProto_WeakSet).toObject().as<NativeObject>();
     }
 
-    JSObject* getOrCreateIntlObject(JSContext* cx) {
-        return getOrCreateObject(cx, APPLICATION_SLOTS + JSProto_Intl, initIntlObject);
+    static JSObject*
+    getOrCreateIntlObject(JSContext* cx, Handle<GlobalObject*> global) {
+        return getOrCreateObject(cx, global, APPLICATION_SLOTS + JSProto_Intl, initIntlObject);
     }
 
-    JSObject* getOrCreateTypedObjectModule(JSContext* cx) {
-        return getOrCreateObject(cx, APPLICATION_SLOTS + JSProto_TypedObject, initTypedObjectModule);
+    static JSObject*
+    getOrCreateTypedObjectModule(JSContext* cx, Handle<GlobalObject*> global) {
+        return getOrCreateObject(cx, global, APPLICATION_SLOTS + JSProto_TypedObject,
+                                 initTypedObjectModule);
     }
 
-    JSObject* getOrCreateSimdGlobalObject(JSContext* cx) {
-        return getOrCreateObject(cx, APPLICATION_SLOTS + JSProto_SIMD, initSimdObject);
+    static JSObject*
+    getOrCreateSimdGlobalObject(JSContext* cx, Handle<GlobalObject*> global) {
+        return getOrCreateObject(cx, global, APPLICATION_SLOTS + JSProto_SIMD, initSimdObject);
     }
 
     // Get the type descriptor for one of the SIMD types.
     // simdType is one of the JS_SIMDTYPEREPR_* constants.
     // Implemented in builtin/SIMD.cpp.
-    static SimdTypeDescr* getOrCreateSimdTypeDescr(JSContext* cx, Handle<GlobalObject*> global,
-                                                   SimdType simdType);
+    static SimdTypeDescr*
+    getOrCreateSimdTypeDescr(JSContext* cx, Handle<GlobalObject*> global, SimdType simdType);
 
     TypedObjectModuleObject& getTypedObjectModule() const;
 
     JSObject* getLegacyIteratorPrototype() {
         return &getPrototype(JSProto_Iterator).toObject();
     }
 
-    JSObject* getOrCreateCollatorPrototype(JSContext* cx) {
-        return getOrCreateObject(cx, COLLATOR_PROTO, initIntlObject);
+    static JSObject*
+    getOrCreateCollatorPrototype(JSContext* cx, Handle<GlobalObject*> global) {
+        return getOrCreateObject(cx, global, COLLATOR_PROTO, initIntlObject);
     }
 
-    JSObject* getOrCreateNumberFormatPrototype(JSContext* cx) {
-        return getOrCreateObject(cx, NUMBER_FORMAT_PROTO, initIntlObject);
+    static JSObject*
+    getOrCreateNumberFormatPrototype(JSContext* cx, Handle<GlobalObject*> global) {
+        return getOrCreateObject(cx, global, NUMBER_FORMAT_PROTO, initIntlObject);
     }
 
-    JSObject* getOrCreateDateTimeFormatPrototype(JSContext* cx) {
-        return getOrCreateObject(cx, DATE_TIME_FORMAT_PROTO, initIntlObject);
+    static JSObject*
+    getOrCreateDateTimeFormatPrototype(JSContext* cx, Handle<GlobalObject*> global) {
+        return getOrCreateObject(cx, global, DATE_TIME_FORMAT_PROTO, initIntlObject);
     }
 
-    JSObject* getOrCreatePluralRulesPrototype(JSContext* cx) {
-        return getOrCreateObject(cx, PLURAL_RULES_PROTO, initIntlObject);
+    static JSObject*
+    getOrCreatePluralRulesPrototype(JSContext* cx, Handle<GlobalObject*> global) {
+        return getOrCreateObject(cx, global, PLURAL_RULES_PROTO, initIntlObject);
     }
 
     static bool ensureModulePrototypesCreated(JSContext *cx, Handle<GlobalObject*> global);
 
     JSObject* maybeGetModulePrototype() {
         Value value = getSlot(MODULE_PROTO);
         return value.isUndefined() ? nullptr : &value.toObject();
     }
@@ -531,98 +545,96 @@ class GlobalObject : public NativeObject
         if (!ensureConstructor(cx, global, JSProto_TypedArray))
             return nullptr;
         return &global->getPrototype(JSProto_TypedArray).toObject();
     }
 
   private:
     typedef bool (*ObjectInitOp)(JSContext* cx, Handle<GlobalObject*> global);
 
-    JSObject* getOrCreateObject(JSContext* cx, unsigned slot, ObjectInitOp init) {
-        Value v = getSlotRef(slot);
+    static JSObject*
+    getOrCreateObject(JSContext* cx, Handle<GlobalObject*> global, unsigned slot,
+                      ObjectInitOp init)
+    {
+        Value v = global->getSlotRef(slot);
         if (v.isObject())
             return &v.toObject();
-        RootedGlobalObject self(cx, this);
-        if (!init(cx, self))
+        if (!init(cx, global))
             return nullptr;
-        return &self->getSlot(slot).toObject();
+        return &global->getSlot(slot).toObject();
     }
 
   public:
-    static NativeObject* getOrCreateIteratorPrototype(JSContext* cx, Handle<GlobalObject*> global)
-    {
-        return MaybeNativeObject(global->getOrCreateObject(cx, ITERATOR_PROTO, initIteratorProto));
+    static NativeObject*
+    getOrCreateIteratorPrototype(JSContext* cx, Handle<GlobalObject*> global) {
+        return MaybeNativeObject(getOrCreateObject(cx, global, ITERATOR_PROTO, initIteratorProto));
     }
 
-    static NativeObject* getOrCreateArrayIteratorPrototype(JSContext* cx, Handle<GlobalObject*> global)
-    {
-        return MaybeNativeObject(global->getOrCreateObject(cx, ARRAY_ITERATOR_PROTO, initArrayIteratorProto));
-    }
-
-    static NativeObject* getOrCreateStringIteratorPrototype(JSContext* cx,
-                                                            Handle<GlobalObject*> global)
-    {
-        return MaybeNativeObject(global->getOrCreateObject(cx, STRING_ITERATOR_PROTO, initStringIteratorProto));
+    static NativeObject*
+    getOrCreateArrayIteratorPrototype(JSContext* cx, Handle<GlobalObject*> global) {
+        return MaybeNativeObject(getOrCreateObject(cx, global, ARRAY_ITERATOR_PROTO,
+                                                   initArrayIteratorProto));
     }
 
-    static NativeObject* getOrCreateLegacyGeneratorObjectPrototype(JSContext* cx,
-                                                                   Handle<GlobalObject*> global)
-    {
-        return MaybeNativeObject(global->getOrCreateObject(cx, LEGACY_GENERATOR_OBJECT_PROTO,
-                                                           initLegacyGeneratorProto));
+    static NativeObject*
+    getOrCreateStringIteratorPrototype(JSContext* cx, Handle<GlobalObject*> global) {
+        return MaybeNativeObject(getOrCreateObject(cx, global, STRING_ITERATOR_PROTO,
+                                                   initStringIteratorProto));
     }
 
-    static NativeObject* getOrCreateStarGeneratorObjectPrototype(JSContext* cx,
-                                                                 Handle<GlobalObject*> global)
-    {
-        return MaybeNativeObject(global->getOrCreateObject(cx, STAR_GENERATOR_OBJECT_PROTO, initStarGenerators));
+    static NativeObject*
+    getOrCreateLegacyGeneratorObjectPrototype(JSContext* cx, Handle<GlobalObject*> global) {
+        return MaybeNativeObject(getOrCreateObject(cx, global, LEGACY_GENERATOR_OBJECT_PROTO,
+                                                   initLegacyGeneratorProto));
     }
 
-    static NativeObject* getOrCreateStarGeneratorFunctionPrototype(JSContext* cx,
-                                                                   Handle<GlobalObject*> global)
+    static NativeObject*
+    getOrCreateStarGeneratorObjectPrototype(JSContext* cx, Handle<GlobalObject*> global)
     {
-        return MaybeNativeObject(global->getOrCreateObject(cx, STAR_GENERATOR_FUNCTION_PROTO, initStarGenerators));
+        return MaybeNativeObject(getOrCreateObject(cx, global, STAR_GENERATOR_OBJECT_PROTO,
+                                                   initStarGenerators));
     }
 
-    static JSObject* getOrCreateStarGeneratorFunction(JSContext* cx,
-                                                      Handle<GlobalObject*> global)
-    {
-        return global->getOrCreateObject(cx, STAR_GENERATOR_FUNCTION, initStarGenerators);
+    static NativeObject*
+    getOrCreateStarGeneratorFunctionPrototype(JSContext* cx, Handle<GlobalObject*> global) {
+        return MaybeNativeObject(getOrCreateObject(cx, global, STAR_GENERATOR_FUNCTION_PROTO,
+                                                   initStarGenerators));
     }
 
-    static NativeObject* getOrCreateAsyncFunctionPrototype(JSContext* cx,
-                                                           Handle<GlobalObject*> global)
-    {
-        return MaybeNativeObject(global->getOrCreateObject(cx, ASYNC_FUNCTION_PROTO,
-                                                           initAsyncFunction));
+    static JSObject*
+    getOrCreateStarGeneratorFunction(JSContext* cx, Handle<GlobalObject*> global) {
+        return getOrCreateObject(cx, global, STAR_GENERATOR_FUNCTION, initStarGenerators);
+    }
+
+    static NativeObject*
+    getOrCreateAsyncFunctionPrototype(JSContext* cx, Handle<GlobalObject*> global) {
+        return MaybeNativeObject(getOrCreateObject(cx, global, ASYNC_FUNCTION_PROTO,
+                                                   initAsyncFunction));
     }
 
-    static JSObject* getOrCreateAsyncFunction(JSContext* cx,
-                                              Handle<GlobalObject*> global)
-    {
-        return global->getOrCreateObject(cx, ASYNC_FUNCTION, initAsyncFunction);
+    static JSObject*
+    getOrCreateAsyncFunction(JSContext* cx, Handle<GlobalObject*> global) {
+        return getOrCreateObject(cx, global, ASYNC_FUNCTION, initAsyncFunction);
     }
 
-    static JSObject* getOrCreateMapIteratorPrototype(JSContext* cx,
-                                                     Handle<GlobalObject*> global)
-    {
-        return global->getOrCreateObject(cx, MAP_ITERATOR_PROTO, initMapIteratorProto);
+    static JSObject*
+    getOrCreateMapIteratorPrototype(JSContext* cx, Handle<GlobalObject*> global) {
+        return getOrCreateObject(cx, global, MAP_ITERATOR_PROTO, initMapIteratorProto);
     }
 
-    static JSObject* getOrCreateSetIteratorPrototype(JSContext* cx,
-                                                     Handle<GlobalObject*> global)
-    {
-        return global->getOrCreateObject(cx, SET_ITERATOR_PROTO, initSetIteratorProto);
+    static JSObject*
+    getOrCreateSetIteratorPrototype(JSContext* cx, Handle<GlobalObject*> global) {
+        return getOrCreateObject(cx, global, SET_ITERATOR_PROTO, initSetIteratorProto);
     }
 
-    JSObject* getOrCreateDataViewPrototype(JSContext* cx) {
-        RootedGlobalObject self(cx, this);
-        if (!ensureConstructor(cx, self, JSProto_DataView))
+    static JSObject*
+    getOrCreateDataViewPrototype(JSContext* cx, Handle<GlobalObject*> global) {
+        if (!ensureConstructor(cx, global, JSProto_DataView))
             return nullptr;
-        return &self->getPrototype(JSProto_DataView).toObject();
+        return &global->getPrototype(JSProto_DataView).toObject();
     }
 
     static JSFunction*
     getOrCreatePromiseConstructor(JSContext* cx, Handle<GlobalObject*> global) {
         if (!ensureConstructor(cx, global, JSProto_Promise))
             return nullptr;
         return &global->getConstructor(JSProto_Promise).toObject().as<JSFunction>();
     }
@@ -670,18 +682,19 @@ class GlobalObject : public NativeObject
             *exists = true;
         } else {
             *exists = false;
         }
 
         return true;
     }
 
-    static bool getIntrinsicValue(JSContext* cx, Handle<GlobalObject*> global,
-                                  HandlePropertyName name, MutableHandleValue value)
+    static bool
+    getIntrinsicValue(JSContext* cx, Handle<GlobalObject*> global,
+                      HandlePropertyName name, MutableHandleValue value)
     {
         bool exists = false;
         if (!GlobalObject::maybeGetIntrinsicValue(cx, global, name, value, &exists))
             return false;
         if (exists)
             return true;
         if (!cx->runtime()->cloneSelfHostedValue(cx, name, value))
             return false;
@@ -701,17 +714,18 @@ class GlobalObject : public NativeObject
         return SetProperty(cx, holder, name, value);
     }
 
     static bool getSelfHostedFunction(JSContext* cx, Handle<GlobalObject*> global,
                                       HandlePropertyName selfHostedName, HandleAtom name,
                                       unsigned nargs, MutableHandleValue funVal);
 
     bool hasRegExpStatics() const;
-    RegExpStatics* getRegExpStatics(ExclusiveContext* cx) const;
+    static RegExpStatics* getRegExpStatics(ExclusiveContext* cx,
+                                           Handle<GlobalObject*> global);
     RegExpStatics* getAlreadyCreatedRegExpStatics() const;
 
     JSObject* getThrowTypeError() const {
         const Value v = getReservedSlot(THROWTYPEERROR);
         MOZ_ASSERT(v.isObject(),
                    "attempting to access [[ThrowTypeError]] too early");
         return &v.toObject();
     }
@@ -980,30 +994,30 @@ DefineToStringTag(JSContext *cx, HandleO
 
 template<JSNative ctor, unsigned length, gc::AllocKind kind, const JSJitInfo* jitInfo = nullptr>
 JSObject*
 GenericCreateConstructor(JSContext* cx, JSProtoKey key)
 {
     // Note - We duplicate the trick from ClassName() so that we don't need to
     // include jsatominlines.h here.
     PropertyName* name = (&cx->names().Null)[key];
-    return cx->global()->createConstructor(cx, ctor, name, length, kind, jitInfo);
+    return GlobalObject::createConstructor(cx, ctor, name, length, kind, jitInfo);
 }
 
 inline JSObject*
 GenericCreatePrototype(JSContext* cx, JSProtoKey key)
 {
     MOZ_ASSERT(key != JSProto_Object);
     const Class* clasp = ProtoKeyToClass(key);
     MOZ_ASSERT(clasp);
     JSProtoKey protoKey = InheritanceProtoKeyForStandardClass(key);
     if (!GlobalObject::ensureConstructor(cx, cx->global(), protoKey))
         return nullptr;
     RootedObject parentProto(cx, &cx->global()->getPrototype(protoKey).toObject());
-    return cx->global()->createBlankPrototypeInheriting(cx, clasp, parentProto);
+    return GlobalObject::createBlankPrototypeInheriting(cx, cx->global(), clasp, parentProto);
 }
 
 inline JSProtoKey
 StandardProtoKeyOrNull(const JSObject* obj)
 {
     return JSCLASS_CACHED_PROTO_KEY(obj->getClass());
 }
 
--- a/js/src/vm/RegExpObject.cpp
+++ b/js/src/vm/RegExpObject.cpp
@@ -192,17 +192,17 @@ RegExpObject::trace(JSTracer* trc, JSObj
     } else {
         shared->trace(trc);
     }
 }
 
 static JSObject*
 CreateRegExpPrototype(JSContext* cx, JSProtoKey key)
 {
-    return cx->global()->createBlankPrototype(cx, &RegExpObject::protoClass_);
+    return GlobalObject::createBlankPrototype(cx, cx->global(), &RegExpObject::protoClass_);
 }
 
 static const ClassOps RegExpObjectClassOps = {
     nullptr, /* addProperty */
     nullptr, /* delProperty */
     nullptr, /* getProperty */
     nullptr, /* setProperty */
     nullptr, /* enumerate */
--- a/js/src/vm/SharedArrayObject.cpp
+++ b/js/src/vm/SharedArrayObject.cpp
@@ -339,17 +339,18 @@ SharedArrayBufferObject::copyData(Handle
     jit::AtomicOperations::memcpySafeWhenRacy(toBuffer->dataPointerShared(),
                                               fromBuffer->dataPointerShared() + fromIndex,
                                               count);
 }
 
 static JSObject*
 CreateSharedArrayBufferPrototype(JSContext* cx, JSProtoKey key)
 {
-    return cx->global()->createBlankPrototype(cx, &SharedArrayBufferObject::protoClass_);
+    return GlobalObject::createBlankPrototype(cx, cx->global(),
+                                              &SharedArrayBufferObject::protoClass_);
 }
 
 static const ClassOps SharedArrayBufferObjectClassOps = {
     nullptr, /* addProperty */
     nullptr, /* delProperty */
     nullptr, /* getProperty */
     nullptr, /* setProperty */
     nullptr, /* enumerate */
--- a/js/src/vm/TypedArrayObject.cpp
+++ b/js/src/vm/TypedArrayObject.cpp
@@ -357,17 +357,17 @@ class TypedArrayObjectTemplate : public 
     createPrototype(JSContext* cx, JSProtoKey key)
     {
         Handle<GlobalObject*> global = cx->global();
         RootedObject typedArrayProto(cx, GlobalObject::getOrCreateTypedArrayPrototype(cx, global));
         if (!typedArrayProto)
             return nullptr;
 
         const Class* clasp = TypedArrayObject::protoClassForType(ArrayTypeID());
-        return global->createBlankPrototypeInheriting(cx, clasp, typedArrayProto);
+        return GlobalObject::createBlankPrototypeInheriting(cx, global, clasp, typedArrayProto);
     }
 
     static JSObject*
     createConstructor(JSContext* cx, JSProtoKey key)
     {
         Handle<GlobalObject*> global = cx->global();
         RootedFunction ctorProto(cx, GlobalObject::getOrCreateTypedArrayConstructor(cx, global));
         if (!ctorProto)
@@ -1910,17 +1910,17 @@ DataViewObject::constructWrapped(JSConte
     // compartment.
     RootedObject proto(cx);
     RootedObject newTarget(cx, &args.newTarget().toObject());
     if (!GetPrototypeFromConstructor(cx, newTarget, &proto))
         return false;
 
     Rooted<GlobalObject*> global(cx, cx->compartment()->maybeGlobal());
     if (!proto) {
-        proto = global->getOrCreateDataViewPrototype(cx);
+        proto = GlobalObject::getOrCreateDataViewPrototype(cx, global);
         if (!proto)
             return false;
     }
 
     RootedObject dv(cx);
     {
         JSAutoCompartment ac(cx, unwrapped);
 
@@ -2907,22 +2907,23 @@ DataViewObject::defineGetter(JSContext* 
 
 /* static */ bool
 DataViewObject::initClass(JSContext* cx)
 {
     Rooted<GlobalObject*> global(cx, cx->compartment()->maybeGlobal());
     if (global->isStandardClassResolved(JSProto_DataView))
         return true;
 
-    RootedNativeObject proto(cx, global->createBlankPrototype(cx, &DataViewObject::protoClass));
+    RootedNativeObject proto(cx, GlobalObject::createBlankPrototype(cx, global,
+                                                                    &DataViewObject::protoClass));
     if (!proto)
         return false;
 
-    RootedFunction ctor(cx, global->createConstructor(cx, DataViewObject::class_constructor,
-                                                      cx->names().DataView, 3));
+    RootedFunction ctor(cx, GlobalObject::createConstructor(cx, DataViewObject::class_constructor,
+                                                            cx->names().DataView, 3));
     if (!ctor)
         return false;
 
     if (!LinkConstructorAndPrototype(cx, ctor, proto))
         return false;
 
     if (!defineGetter<bufferValue>(cx, cx->names().buffer, proto))
         return false;
--- a/js/src/wasm/WasmJS.cpp
+++ b/js/src/wasm/WasmJS.cpp
@@ -2093,17 +2093,17 @@ InitErrorClass(JSContext* cx, HandleObje
 JSObject*
 js::InitWebAssemblyClass(JSContext* cx, HandleObject obj)
 {
     MOZ_RELEASE_ASSERT(HasSupport(cx));
 
     Handle<GlobalObject*> global = obj.as<GlobalObject>();
     MOZ_ASSERT(!global->isStandardClassResolved(JSProto_WebAssembly));
 
-    RootedObject proto(cx, global->getOrCreateObjectPrototype(cx));
+    RootedObject proto(cx, GlobalObject::getOrCreateObjectPrototype(cx, global));
     if (!proto)
         return nullptr;
 
     RootedObject wasm(cx, NewObjectWithGivenProto(cx, &WebAssemblyClass, proto, SingletonObject));
     if (!wasm)
         return nullptr;
 
     if (!JS_DefineFunctions(cx, wasm, WebAssembly_static_methods))