Bug 1595745 - Part 7: Change Atomics to use ClassSpec. r=mgaudet
☠☠ backed out by ec8cad689121 ☠ ☠
authorAndré Bargull <andre.bargull@gmail.com>
Fri, 15 Nov 2019 15:03:42 +0000
changeset 502201 fef5c8d5cb909dd147da181f45851603cddeb045
parent 502200 68c5cdced300d92c3102c2fdddab32459e14e95d
child 502202 3b0e242d762a12cdcb16a0e9f2ac60ce3af21833
push id114172
push userdluca@mozilla.com
push dateTue, 19 Nov 2019 11:31:10 +0000
treeherdermozilla-inbound@b5c5ba07d3db [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmgaudet
bugs1595745
milestone72.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 1595745 - Part 7: Change Atomics to use ClassSpec. r=mgaudet Similar changes like in part 5, only now for the Atomics object. Differential Revision: https://phabricator.services.mozilla.com/D52663
js/public/ProtoKey.h
js/src/builtin/AtomicsObject.cpp
js/src/builtin/AtomicsObject.h
--- a/js/public/ProtoKey.h
+++ b/js/public/ProtoKey.h
@@ -103,17 +103,17 @@
   REAL_IF_INTL(RelativeTimeFormat, InitViaClassSpec,                         \
                OCLASP(RelativeTimeFormat))                                   \
   REAL_IF_BDATA(TypedObject, InitTypedObjectModuleObject,                    \
                 OCLASP(TypedObjectModule))                                   \
   REAL(Reflect, InitReflect, nullptr)                                        \
   REAL(WeakSet, InitViaClassSpec, OCLASP(WeakSet))                           \
   REAL(TypedArray, InitViaClassSpec,                                         \
        &js::TypedArrayObject::sharedTypedArrayPrototypeClass)                \
-  REAL(Atomics, InitAtomicsClass, OCLASP(Atomics))                           \
+  REAL(Atomics, InitViaClassSpec, OCLASP(Atomics))                           \
   REAL(SavedFrame, InitViaClassSpec, &js::SavedFrame::class_)                \
   REAL(Promise, InitViaClassSpec, OCLASP(Promise))                           \
   REAL(AsyncFunction, InitAsyncFunction, nullptr)                            \
   REAL(GeneratorFunction, InitGeneratorFunction, nullptr)                    \
   REAL(AsyncGeneratorFunction, InitAsyncGeneratorFunction, nullptr)          \
   REAL(ReadableStream, InitViaClassSpec, &js::ReadableStream::class_)        \
   REAL(ReadableStreamDefaultReader, InitViaClassSpec,                        \
        &js::ReadableStreamDefaultReader::class_)                             \
--- a/js/src/builtin/AtomicsObject.cpp
+++ b/js/src/builtin/AtomicsObject.cpp
@@ -67,19 +67,16 @@
 #include "vm/Time.h"
 #include "vm/TypedArrayObject.h"
 #include "wasm/WasmInstance.h"
 
 #include "vm/JSObject-inl.h"
 
 using namespace js;
 
-const JSClass AtomicsObject::class_ = {
-    "Atomics", JSCLASS_HAS_CACHED_PROTO(JSProto_Atomics)};
-
 static bool ReportBadArrayType(JSContext* cx) {
   JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
                             JSMSG_ATOMICS_BAD_ARRAY);
   return false;
 }
 
 static bool ReportOutOfRange(JSContext* cx) {
   // Use JSMSG_BAD_INDEX here, it is what ToIndex uses for some cases that it
@@ -952,47 +949,30 @@ const JSFunctionSpec AtomicsMethods[] = 
     JS_INLINABLE_FN("or", atomics_or, 3, 0, AtomicsOr),
     JS_INLINABLE_FN("xor", atomics_xor, 3, 0, AtomicsXor),
     JS_INLINABLE_FN("isLockFree", atomics_isLockFree, 1, 0, AtomicsIsLockFree),
     JS_FN("wait", atomics_wait, 4, 0),
     JS_FN("notify", atomics_notify, 3, 0),
     JS_FN("wake", atomics_notify, 3, 0),  // Legacy name
     JS_FS_END};
 
-JSObject* AtomicsObject::initClass(JSContext* cx,
-                                   Handle<GlobalObject*> global) {
-  // Create Atomics Object.
-  RootedObject objProto(cx,
-                        GlobalObject::getOrCreateObjectPrototype(cx, global));
-  if (!objProto) {
-    return nullptr;
-  }
-  RootedObject Atomics(cx, NewObjectWithGivenProto(cx, &AtomicsObject::class_,
-                                                   objProto, SingletonObject));
-  if (!Atomics) {
-    return nullptr;
-  }
+static const JSPropertySpec AtomicsProperties[] = {
+    JS_STRING_SYM_PS(toStringTag, "Atomics", JSPROP_READONLY), JS_PS_END};
 
-  if (!JS_DefineFunctions(cx, Atomics, AtomicsMethods)) {
+static JSObject* CreateAtomicsObject(JSContext* cx, JSProtoKey key) {
+  Handle<GlobalObject*> global = cx->global();
+  RootedObject proto(cx, GlobalObject::getOrCreateObjectPrototype(cx, global));
+  if (!proto) {
     return nullptr;
   }
-  if (!DefineToStringTag(cx, Atomics, cx->names().Atomics)) {
-    return nullptr;
-  }
-
-  RootedValue AtomicsValue(cx, ObjectValue(*Atomics));
-
-  // Everything is set up, install Atomics on the global object.
-  if (!DefineDataProperty(cx, global, cx->names().Atomics, AtomicsValue,
-                          JSPROP_RESOLVING)) {
-    return nullptr;
-  }
-
-  global->setConstructor(JSProto_Atomics, AtomicsValue);
-  return Atomics;
+  return NewObjectWithGivenProto(cx, &AtomicsObject::class_, proto,
+                                 SingletonObject);
 }
 
-JSObject* js::InitAtomicsClass(JSContext* cx, Handle<GlobalObject*> global) {
-  return AtomicsObject::initClass(cx, global);
-}
+static const ClassSpec AtomicsClassSpec = {CreateAtomicsObject, nullptr,
+                                           AtomicsMethods, AtomicsProperties};
+
+const JSClass AtomicsObject::class_ = {
+    "Atomics", JSCLASS_HAS_CACHED_PROTO(JSProto_Atomics), JS_NULL_CLASS_OPS,
+    &AtomicsClassSpec};
 
 #undef CXX11_ATOMICS
 #undef GNU_ATOMICS
--- a/js/src/builtin/AtomicsObject.h
+++ b/js/src/builtin/AtomicsObject.h
@@ -13,25 +13,21 @@
 #include "threading/ConditionVariable.h"
 #include "threading/ProtectedData.h"  // js::ThreadData
 #include "vm/JSObject.h"
 #include "vm/MutexIDs.h"
 #include "vm/NativeObject.h"
 
 namespace js {
 
-class GlobalObject;
 class SharedArrayRawBuffer;
 
 class AtomicsObject : public NativeObject {
  public:
   static const JSClass class_;
-  static JSObject* initClass(JSContext* cx, Handle<GlobalObject*> global);
-  static MOZ_MUST_USE bool toString(JSContext* cx, unsigned int argc,
-                                    Value* vp);
 };
 
 MOZ_MUST_USE bool atomics_compareExchange(JSContext* cx, unsigned argc,
                                           Value* vp);
 MOZ_MUST_USE bool atomics_exchange(JSContext* cx, unsigned argc, Value* vp);
 MOZ_MUST_USE bool atomics_load(JSContext* cx, unsigned argc, Value* vp);
 MOZ_MUST_USE bool atomics_store(JSContext* cx, unsigned argc, Value* vp);
 MOZ_MUST_USE bool atomics_add(JSContext* cx, unsigned argc, Value* vp);
@@ -136,18 +132,16 @@ class FutexThread {
   static mozilla::Atomic<js::Mutex*, mozilla::SequentiallyConsistent,
                          mozilla::recordreplay::Behavior::DontPreserve>
       lock_;
 
   // A flag that controls whether waiting is allowed.
   ThreadData<bool> canWait_;
 };
 
-JSObject* InitAtomicsClass(JSContext* cx, Handle<GlobalObject*> global);
-
 // Go to sleep if the int32_t value at the given address equals `value`.
 MOZ_MUST_USE FutexThread::WaitResult atomics_wait_impl(
     JSContext* cx, SharedArrayRawBuffer* sarb, uint32_t byteOffset,
     int32_t value, const mozilla::Maybe<mozilla::TimeDuration>& timeout);
 
 // Go to sleep if the int64_t value at the given address equals `value`.
 MOZ_MUST_USE FutexThread::WaitResult atomics_wait_impl(
     JSContext* cx, SharedArrayRawBuffer* sarb, uint32_t byteOffset,