Bug 1431726 part 2 - Replace GetBuiltinConstructor with GlobalObject::getOrCreateConstructor. r=anba
authorJan de Mooij <jdemooij@mozilla.com>
Sat, 20 Jan 2018 15:18:59 +0100
changeset 454425 712f3d9c1cf35d7c26fde310843836a08fa583a7
parent 454424 429a5e0d58c329c193b43bbf9a3fcdd3447f2e92
child 454426 a937ea520febcc4175e49d5d137bfe48d3d607c2
push id1648
push usermtabara@mozilla.com
push dateThu, 01 Mar 2018 12:45:47 +0000
treeherdermozilla-release@cbb9688c2eeb [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersanba
bugs1431726
milestone59.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 1431726 part 2 - Replace GetBuiltinConstructor with GlobalObject::getOrCreateConstructor. r=anba
js/src/builtin/DataViewObject.cpp
js/src/builtin/Promise.cpp
js/src/builtin/Stream.cpp
js/src/jsapi.cpp
js/src/jsobj.cpp
js/src/jsobj.h
js/src/vm/GlobalObject.h
js/src/vm/SelfHosting.cpp
--- a/js/src/builtin/DataViewObject.cpp
+++ b/js/src/builtin/DataViewObject.cpp
@@ -1047,19 +1047,19 @@ JS_GetDataViewByteLength(JSObject* obj)
     if (!obj)
         return 0;
     return obj->as<DataViewObject>().byteLength();
 }
 
 JS_FRIEND_API(JSObject*)
 JS_NewDataView(JSContext* cx, HandleObject buffer, uint32_t byteOffset, int32_t byteLength)
 {
-    RootedObject constructor(cx);
     JSProtoKey key = JSCLASS_CACHED_PROTO_KEY(&DataViewObject::class_);
-    if (!GetBuiltinConstructor(cx, key, &constructor))
+    RootedObject constructor(cx, GlobalObject::getOrCreateConstructor(cx, key));
+    if (!constructor)
         return nullptr;
 
     FixedConstructArgs<3> cargs(cx);
 
     cargs[0].setObject(*buffer);
     cargs[1].setNumber(byteOffset);
     cargs[2].setInt32(byteLength);
 
--- a/js/src/builtin/Promise.cpp
+++ b/js/src/builtin/Promise.cpp
@@ -1564,18 +1564,19 @@ PromiseConstructor(JSContext* cx, unsign
     if (IsWrapper(newTarget)) {
         JSObject* unwrappedNewTarget = CheckedUnwrap(newTarget);
         MOZ_ASSERT(unwrappedNewTarget);
         MOZ_ASSERT(unwrappedNewTarget != newTarget);
 
         newTarget = unwrappedNewTarget;
         {
             AutoCompartment ac(cx, newTarget);
-            RootedObject promiseCtor(cx);
-            if (!GetBuiltinConstructor(cx, JSProto_Promise, &promiseCtor))
+            Handle<GlobalObject*> global = cx->global();
+            RootedObject promiseCtor(cx, GlobalObject::getOrCreatePromiseConstructor(cx, global));
+            if (!promiseCtor)
                 return false;
 
             // Promise subclasses don't get the special Xray treatment, so
             // we only need to do the complex wrapping and unwrapping scheme
             // described above for instances of Promise itself.
             if (newTarget == promiseCtor) {
                 needsWrapping = true;
                 if (!GetBuiltinPrototype(cx, JSProto_Promise, &proto))
@@ -3164,18 +3165,19 @@ BlockOnPromise(JSContext* cx, HandleValu
     RootedValue thenVal(cx);
     if (!GetProperty(cx, promiseObj, promiseVal, cx->names().then, &thenVal))
         return false;
 
     if (promiseObj->is<PromiseObject>() && IsNativeFunction(thenVal, Promise_then)) {
         // |promise| is an unwrapped Promise, and |then| is the original
         // |Promise.prototype.then|, inline it here.
         // 25.4.5.3., step 3.
-        RootedObject PromiseCtor(cx);
-        if (!GetBuiltinConstructor(cx, JSProto_Promise, &PromiseCtor))
+        RootedObject PromiseCtor(cx,
+                                 GlobalObject::getOrCreatePromiseConstructor(cx, cx->global()));
+        if (!PromiseCtor)
             return false;
 
         RootedObject C(cx, SpeciesConstructor(cx, promiseObj, JSProto_Promise, IsPromiseSpecies));
         if (!C)
             return false;
 
         RootedObject resultPromise(cx, blockedPromise_);
         RootedObject resolveFun(cx);
--- a/js/src/builtin/Stream.cpp
+++ b/js/src/builtin/Stream.cpp
@@ -3926,17 +3926,18 @@ ReadableByteStreamControllerConvertPullI
     MOZ_ASSERT(bytesFilled % elementSize == 0);
 
     // Step 5: Return ! Construct(pullIntoDescriptor.[[ctor]],
     //                            pullIntoDescriptor.[[buffer]],
     //                            pullIntoDescriptor.[[byteOffset]],
     //                            bytesFilled / elementSize).
     RootedObject ctor(cx, pullIntoDescriptor->ctor());
     if (!ctor) {
-        if (!GetBuiltinConstructor(cx, JSProto_Uint8Array, &ctor))
+        ctor = GlobalObject::getOrCreateConstructor(cx, JSProto_Uint8Array);
+        if (!ctor)
             return nullptr;
     }
     RootedObject buffer(cx, pullIntoDescriptor->buffer());
     uint32_t byteOffset = pullIntoDescriptor->byteOffset();
     FixedConstructArgs<3> args(cx);
     args[0].setObject(*buffer);
     args[1].setInt32(byteOffset);
     args[2].setInt32(bytesFilled / elementSize);
@@ -4425,22 +4426,24 @@ ReadableByteStreamControllerPullInto(JSC
 
     RootedObject ctor(cx);
     // Step 4: If view has a [[TypedArrayName]] internal slot (i.e., it is not a
     //         DataView),
     if (view->is<TypedArrayObject>()) {
         JSProtoKey protoKey = StandardProtoKeyOrNull(view);
         MOZ_ASSERT(protoKey);
 
-        if (!GetBuiltinConstructor(cx, protoKey, &ctor))
+        ctor = GlobalObject::getOrCreateConstructor(cx, protoKey);
+        if (!ctor)
             return nullptr;
         elementSize = 1 << TypedArrayShift(view->as<TypedArrayObject>().type());
     } else {
         // Step 3: Let ctor be %DataView% (reordered).
-        if (!GetBuiltinConstructor(cx, JSProto_DataView, &ctor))
+        ctor = GlobalObject::getOrCreateConstructor(cx, JSProto_DataView);
+        if (!ctor)
             return nullptr;
     }
 
     // Step 5: Let pullIntoDescriptor be Record {[[buffer]]: view.[[ViewedArrayBuffer]],
     //                                           [[byteOffset]]: view.[[ByteOffset]],
     //                                           [[byteLength]]: view.[[ByteLength]],
     //                                           [[bytesFilled]]: 0,
     //                                           [[elementSize]]: elementSize,
--- a/js/src/jsapi.cpp
+++ b/js/src/jsapi.cpp
@@ -1219,17 +1219,21 @@ JS_NewEnumerateStandardClasses(JSContext
     return true;
 }
 
 JS_PUBLIC_API(bool)
 JS_GetClassObject(JSContext* cx, JSProtoKey key, MutableHandleObject objp)
 {
     AssertHeapIsIdle();
     CHECK_REQUEST(cx);
-    return GetBuiltinConstructor(cx, key, objp);
+    JSObject* obj = GlobalObject::getOrCreateConstructor(cx, key);
+    if (!obj)
+        return false;
+    objp.set(obj);
+    return true;
 }
 
 JS_PUBLIC_API(bool)
 JS_GetClassPrototype(JSContext* cx, JSProtoKey key, MutableHandleObject objp)
 {
     AssertHeapIsIdle();
     CHECK_REQUEST(cx);
     return GetBuiltinPrototype(cx, key, objp);
--- a/js/src/jsobj.cpp
+++ b/js/src/jsobj.cpp
@@ -2099,28 +2099,16 @@ JSObject::changeToSingleton(JSContext* c
     if (!group)
         return false;
 
     obj->group_ = group;
     return true;
 }
 
 bool
-js::GetBuiltinConstructor(JSContext* cx, JSProtoKey key, MutableHandleObject objp)
-{
-    MOZ_ASSERT(key != JSProto_Null);
-    Handle<GlobalObject*> global = cx->global();
-    if (!GlobalObject::ensureConstructor(cx, global, key))
-        return false;
-
-    objp.set(&global->getConstructor(key).toObject());
-    return true;
-}
-
-bool
 js::GetBuiltinPrototype(JSContext* cx, JSProtoKey key, MutableHandleObject protop)
 {
     MOZ_ASSERT(key != JSProto_Null);
     Handle<GlobalObject*> global = cx->global();
     if (!GlobalObject::ensureConstructor(cx, global, key))
         return false;
 
     protop.set(&global->getPrototype(key).toObject());
--- a/js/src/jsobj.h
+++ b/js/src/jsobj.h
@@ -1028,19 +1028,16 @@ Value
 GetThisValueOfWith(JSObject* env);
 
 /* * */
 
 typedef JSObject* (*ClassInitializerOp)(JSContext* cx, JS::HandleObject obj);
 
 /* Fast access to builtin constructors and prototypes. */
 bool
-GetBuiltinConstructor(JSContext* cx, JSProtoKey key, MutableHandleObject objp);
-
-bool
 GetBuiltinPrototype(JSContext* cx, JSProtoKey key, MutableHandleObject objp);
 
 JSObject*
 GetBuiltinPrototypePure(GlobalObject* global, JSProtoKey protoKey);
 
 extern bool
 IsStandardPrototype(JSObject* obj, JSProtoKey key);
 
--- a/js/src/vm/GlobalObject.h
+++ b/js/src/vm/GlobalObject.h
@@ -142,16 +142,24 @@ class GlobalObject : public NativeObject
 
   public:
     static bool ensureConstructor(JSContext* cx, Handle<GlobalObject*> global, JSProtoKey key) {
         if (global->isStandardClassResolved(key))
             return true;
         return resolveConstructor(cx, global, key);
     }
 
+    static JSObject* getOrCreateConstructor(JSContext* cx, JSProtoKey key) {
+        MOZ_ASSERT(key != JSProto_Null);
+        Handle<GlobalObject*> global = cx->global();
+        if (!GlobalObject::ensureConstructor(cx, global, key))
+            return nullptr;
+        return &global->getConstructor(key).toObject();
+    }
+
     void setConstructor(JSProtoKey key, const Value& v) {
         MOZ_ASSERT(key <= JSProto_LIMIT);
         setSlot(APPLICATION_SLOTS + key, v);
     }
 
     Value getPrototype(JSProtoKey key) const {
         MOZ_ASSERT(key <= JSProto_LIMIT);
         return getSlot(APPLICATION_SLOTS + JSProto_LIMIT + key);
--- a/js/src/vm/SelfHosting.cpp
+++ b/js/src/vm/SelfHosting.cpp
@@ -226,18 +226,18 @@ intrinsic_GetBuiltinConstructor(JSContex
     } else {
         atom = AtomizeString(cx, str);
         if (!atom)
             return false;
     }
     RootedId id(cx, AtomToId(atom));
     JSProtoKey key = JS_IdToProtoKey(cx, id);
     MOZ_ASSERT(key != JSProto_Null);
-    RootedObject ctor(cx);
-    if (!GetBuiltinConstructor(cx, key, &ctor))
+    JSObject* ctor = GlobalObject::getOrCreateConstructor(cx, key);
+    if (!ctor)
         return false;
     args.rval().setObject(*ctor);
     return true;
 }
 
 static bool
 intrinsic_SubstringKernel(JSContext* cx, unsigned argc, Value* vp)
 {
@@ -1987,18 +1987,18 @@ intrinsic_ConstructorForTypedArray(JSCon
     // seeing a typed array object implies that the TypedArray constructor
     // for that type is initialized on the compartment's global, this is not
     // the case. When we construct a typed array given a cross-compartment
     // ArrayBuffer, we put the constructed TypedArray in the same compartment
     // as the ArrayBuffer. Since we use the prototype from the initial
     // compartment, and never call the constructor in the ArrayBuffer's
     // compartment from script, we are not guaranteed to have initialized
     // the constructor.
-    RootedObject ctor(cx);
-    if (!GetBuiltinConstructor(cx, protoKey, &ctor))
+    JSObject* ctor = GlobalObject::getOrCreateConstructor(cx, protoKey);
+    if (!ctor)
         return false;
 
     args.rval().setObject(*ctor);
     return true;
 }
 
 static bool
 intrinsic_NameForTypedArray(JSContext* cx, unsigned argc, Value* vp)