Bug 1521127 - Part 3: Don't check for singleton allocation sites when creating typed arrays. r=jandem
☠☠ backed out by 1f92e62a285c ☠ ☠
authorAndré Bargull <andre.bargull@gmail.com>
Fri, 18 Jan 2019 09:35:27 -0800
changeset 515088 6ac126ad6e18cdc00fc6b0b15a1242c1028a135f
parent 515083 24be3a3e0faa957699636bd988ec678c68295365
child 515089 232668044fbfc003f8ab57e80f0acddda67b2f31
push id1953
push userffxbld-merge
push dateMon, 11 Mar 2019 12:10:20 +0000
treeherdermozilla-release@9c35dcbaa899 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjandem
bugs1521127
milestone66.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 1521127 - Part 3: Don't check for singleton allocation sites when creating typed arrays. r=jandem
js/src/builtin/DataViewObject.cpp
js/src/vm/JSObject.cpp
js/src/vm/ObjectGroup.cpp
js/src/vm/ObjectGroup.h
js/src/vm/TypedArrayObject.cpp
--- a/js/src/builtin/DataViewObject.cpp
+++ b/js/src/builtin/DataViewObject.cpp
@@ -928,17 +928,17 @@ JS_FRIEND_API uint32_t JS_GetDataViewByt
     return 0;
   }
   return obj->as<DataViewObject>().byteLength();
 }
 
 JS_FRIEND_API JSObject* JS_NewDataView(JSContext* cx, HandleObject buffer,
                                        uint32_t byteOffset,
                                        int32_t byteLength) {
-  JSProtoKey key = JSCLASS_CACHED_PROTO_KEY(&DataViewObject::class_);
+  JSProtoKey key = JSProto_DataView;
   RootedObject constructor(cx, GlobalObject::getOrCreateConstructor(cx, key));
   if (!constructor) {
     return nullptr;
   }
 
   FixedConstructArgs<3> cargs(cx);
 
   cargs[0].setObject(*buffer);
--- a/js/src/vm/JSObject.cpp
+++ b/js/src/vm/JSObject.cpp
@@ -996,18 +996,18 @@ JSObject* js::NewObjectWithGroupCommon(J
   return obj;
 }
 
 bool js::NewObjectScriptedCall(JSContext* cx, MutableHandleObject pobj) {
   jsbytecode* pc;
   RootedScript script(cx, cx->currentScript(&pc));
   gc::AllocKind allocKind = NewObjectGCKind(&PlainObject::class_);
   NewObjectKind newKind = GenericObject;
-  if (script && ObjectGroup::useSingletonForAllocationSite(
-                    script, pc, &PlainObject::class_)) {
+  if (script &&
+      ObjectGroup::useSingletonForAllocationSite(script, pc, JSProto_Object)) {
     newKind = SingletonObject;
   }
   RootedObject obj(
       cx, NewBuiltinClassInstance<PlainObject>(cx, allocKind, newKind));
   if (!obj) {
     return false;
   }
 
--- a/js/src/vm/ObjectGroup.cpp
+++ b/js/src/vm/ObjectGroup.cpp
@@ -721,48 +721,29 @@ MOZ_ALWAYS_INLINE ObjectGroup* ObjectGro
 inline const Class* GetClassForProtoKey(JSProtoKey key) {
   switch (key) {
     case JSProto_Null:
     case JSProto_Object:
       return &PlainObject::class_;
     case JSProto_Array:
       return &ArrayObject::class_;
 
-    case JSProto_Number:
-      return &NumberObject::class_;
-    case JSProto_Boolean:
-      return &BooleanObject::class_;
-    case JSProto_String:
-      return &StringObject::class_;
-    case JSProto_Symbol:
-      return &SymbolObject::class_;
-    case JSProto_RegExp:
-      return &RegExpObject::class_;
-
     case JSProto_Int8Array:
     case JSProto_Uint8Array:
     case JSProto_Int16Array:
     case JSProto_Uint16Array:
     case JSProto_Int32Array:
     case JSProto_Uint32Array:
     case JSProto_Float32Array:
     case JSProto_Float64Array:
     case JSProto_Uint8ClampedArray:
       return &TypedArrayObject::classes[key - JSProto_Int8Array];
 
-    case JSProto_ArrayBuffer:
-      return &ArrayBufferObject::class_;
-
-    case JSProto_SharedArrayBuffer:
-      return &SharedArrayBufferObject::class_;
-
-    case JSProto_DataView:
-      return &DataViewObject::class_;
-
     default:
+      // We only expect to see plain objects, arrays, and typed arrays here.
       MOZ_CRASH("Bad proto key");
   }
 }
 
 /* static */ ObjectGroup* ObjectGroup::defaultNewGroup(JSContext* cx,
                                                        JSProtoKey key) {
   JSObject* proto = nullptr;
   if (key != JSProto_Null) {
@@ -1759,25 +1740,23 @@ ObjectGroup* ObjectGroupRealm::getString
   ObjectGroup* group = groups.stringSplitStringGroup.get();
   if (group) {
     return group;
   }
 
   // The following code is a specialized version of the code
   // for ObjectGroup::allocationSiteGroup().
 
-  const Class* clasp = GetClassForProtoKey(JSProto_Array);
-
   JSObject* proto = GlobalObject::getOrCreateArrayPrototype(cx, cx->global());
   if (!proto) {
     return nullptr;
   }
   Rooted<TaggedProto> tagged(cx, TaggedProto(proto));
 
-  group = makeGroup(cx, cx->realm(), clasp, tagged, /* initialFlags = */ 0);
+  group = makeGroup(cx, cx->realm(), &ArrayObject::class_, tagged);
   if (!group) {
     return nullptr;
   }
 
   groups.stringSplitStringGroup.set(group);
   return group;
 }
 
--- a/js/src/vm/ObjectGroup.h
+++ b/js/src/vm/ObjectGroup.h
@@ -516,18 +516,16 @@ class ObjectGroup : public gc::TenuredCe
 
   // Whether to make a singleton when calling 'new' at script/pc.
   static bool useSingletonForNewObject(JSContext* cx, JSScript* script,
                                        jsbytecode* pc);
 
   // Whether to make a singleton object at an allocation site.
   static bool useSingletonForAllocationSite(JSScript* script, jsbytecode* pc,
                                             JSProtoKey key);
-  static bool useSingletonForAllocationSite(JSScript* script, jsbytecode* pc,
-                                            const Class* clasp);
 
   // Static accessors for ObjectGroupRealm NewTable.
 
   static ObjectGroup* defaultNewGroup(JSContext* cx, const Class* clasp,
                                       TaggedProto proto,
                                       JSObject* associated = nullptr);
   static ObjectGroup* lazySingletonGroup(JSContext* cx, ObjectGroup* oldGroup,
                                          const Class* clasp, TaggedProto proto);
--- a/js/src/vm/TypedArrayObject.cpp
+++ b/js/src/vm/TypedArrayObject.cpp
@@ -358,57 +358,54 @@ class TypedArrayObjectTemplate : public 
       setIndex(tarray, index, NativeType(d));
     } else {
       MOZ_ASSERT(sizeof(NativeType) <= 4);
       int32_t n = ToInt32(d);
       setIndex(tarray, index, NativeType(n));
     }
   }
 
+  static TypedArrayObject* newBuiltinClassInstance(JSContext* cx,
+                                                   gc::AllocKind allocKind,
+                                                   NewObjectKind newKind) {
+    JSObject* obj =
+        NewBuiltinClassInstance(cx, instanceClass(), allocKind, newKind);
+    return obj ? &obj->as<TypedArrayObject>() : nullptr;
+  }
+
   static TypedArrayObject* makeProtoInstance(JSContext* cx, HandleObject proto,
                                              gc::AllocKind allocKind) {
     MOZ_ASSERT(proto);
 
     JSObject* obj =
         NewObjectWithGivenProto(cx, instanceClass(), proto, allocKind);
     return obj ? &obj->as<TypedArrayObject>() : nullptr;
   }
 
   static TypedArrayObject* makeTypedInstance(JSContext* cx,
                                              CreateSingleton createSingleton,
                                              gc::AllocKind allocKind) {
-    const Class* clasp = instanceClass();
     if (createSingleton == CreateSingleton::Yes) {
-      JSObject* obj =
-          NewBuiltinClassInstance(cx, clasp, allocKind, SingletonObject);
-      if (!obj) {
-        return nullptr;
-      }
-      return &obj->as<TypedArrayObject>();
+      return newBuiltinClassInstance(cx, allocKind, SingletonObject);
     }
 
     jsbytecode* pc;
     RootedScript script(cx, cx->currentScript(&pc));
-    NewObjectKind newKind = GenericObject;
-    if (script &&
-        ObjectGroup::useSingletonForAllocationSite(script, pc, clasp)) {
-      newKind = SingletonObject;
-    }
-    RootedObject obj(cx,
-                     NewBuiltinClassInstance(cx, clasp, allocKind, newKind));
+    Rooted<TypedArrayObject*> obj(
+        cx, newBuiltinClassInstance(cx, allocKind, GenericObject));
     if (!obj) {
       return nullptr;
     }
 
     if (script && !ObjectGroup::setAllocationSiteObjectGroup(
-                      cx, script, pc, obj, newKind == SingletonObject)) {
+                      cx, script, pc, obj, /* singleton = */ false)) {
       return nullptr;
     }
 
-    return &obj->as<TypedArrayObject>();
+    return obj;
   }
 
   static TypedArrayObject* makeInstance(
       JSContext* cx, Handle<ArrayBufferObjectMaybeShared*> buffer,
       CreateSingleton createSingleton, uint32_t byteOffset, uint32_t len,
       HandleObject proto) {
     MOZ_ASSERT(len < INT32_MAX / BYTES_PER_ELEMENT);
 
@@ -416,18 +413,17 @@ class TypedArrayObjectTemplate : public 
         buffer ? gc::GetGCObjectKind(instanceClass())
                : AllocKindForLazyBuffer(len * BYTES_PER_ELEMENT);
 
     // Subclassing mandates that we hand in the proto every time. Most of
     // the time, though, that [[Prototype]] will not be interesting. If
     // it isn't, we can do some more TI optimizations.
     RootedObject checkProto(cx);
     if (proto) {
-      checkProto = GlobalObject::getOrCreatePrototype(
-          cx, JSCLASS_CACHED_PROTO_KEY(instanceClass()));
+      checkProto = GlobalObject::getOrCreatePrototype(cx, protoKey());
       if (!checkProto) {
         return nullptr;
       }
     }
 
     AutoSetNewObjectMetadata metadata(cx);
     Rooted<TypedArrayObject*> obj(cx);
     if (proto && proto != checkProto) {
@@ -442,44 +438,38 @@ class TypedArrayObjectTemplate : public 
     return obj;
   }
 
   static TypedArrayObject* makeTemplateObject(JSContext* cx, int32_t len) {
     MOZ_ASSERT(len >= 0);
     size_t nbytes;
     MOZ_ALWAYS_TRUE(CalculateAllocSize<NativeType>(len, &nbytes));
     MOZ_ASSERT(nbytes < TypedArrayObject::SINGLETON_BYTE_LENGTH);
-    NewObjectKind newKind = TenuredObject;
     bool fitsInline = nbytes <= INLINE_BUFFER_LIMIT;
-    const Class* clasp = instanceClass();
-    gc::AllocKind allocKind = !fitsInline ? gc::GetGCObjectKind(clasp)
+    gc::AllocKind allocKind = !fitsInline ? gc::GetGCObjectKind(instanceClass())
                                           : AllocKindForLazyBuffer(nbytes);
 
     AutoSetNewObjectMetadata metadata(cx);
     jsbytecode* pc;
     RootedScript script(cx, cx->currentScript(&pc));
-    if (script &&
-        ObjectGroup::useSingletonForAllocationSite(script, pc, clasp)) {
-      newKind = SingletonObject;
-    }
-    JSObject* tmp = NewBuiltinClassInstance(cx, clasp, allocKind, newKind);
-    if (!tmp) {
+    Rooted<TypedArrayObject*> tarray(
+        cx, newBuiltinClassInstance(cx, allocKind, TenuredObject));
+    if (!tarray) {
       return nullptr;
     }
 
-    Rooted<TypedArrayObject*> tarray(cx, &tmp->as<TypedArrayObject>());
     initTypedArraySlots(tarray, len);
 
     // Template objects do not need memory for its elements, since there
     // won't be any elements to store. Therefore, we set the pointer to
     // nullptr and avoid allocating memory that will never be used.
     tarray->initPrivate(nullptr);
 
     if (script && !ObjectGroup::setAllocationSiteObjectGroup(
-                      cx, script, pc, tarray, newKind == SingletonObject)) {
+                      cx, script, pc, tarray, /* singleton = */ false)) {
       return nullptr;
     }
 
     return tarray;
   }
 
   static void initTypedArraySlots(TypedArrayObject* tarray, int32_t len) {
     MOZ_ASSERT(len >= 0);
@@ -782,18 +772,17 @@ class TypedArrayObjectTemplate : public 
                                &length)) {
       return nullptr;
     }
 
     // Make sure to get the [[Prototype]] for the created typed array from
     // this compartment.
     RootedObject protoRoot(cx, proto);
     if (!protoRoot) {
-      protoRoot = GlobalObject::getOrCreatePrototype(
-          cx, JSCLASS_CACHED_PROTO_KEY(instanceClass()));
+      protoRoot = GlobalObject::getOrCreatePrototype(cx, protoKey());
       if (!protoRoot) {
         return nullptr;
       }
     }
 
     RootedObject typedArray(cx);
     {
       JSAutoRealm ar(cx, unwrappedBuffer);