Bug 1519397 - Factor GC locking RAII classes out of vm/Runtime.h r=pbone
authorJon Coppeard <jcoppeard@mozilla.com>
Mon, 14 Jan 2019 11:02:35 +0000
changeset 513696 1cebf4f5c850ad22500a360c2742de3c9dd78c81
parent 513695 c879dc493add8fc475fc27f697460d77d213c6a8
child 513697 2b2c8d1455411dcddd3e5fbb615af1d7efe4aa95
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)
reviewerspbone
bugs1519397
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 1519397 - Factor GC locking RAII classes out of vm/Runtime.h r=pbone
js/src/gc/Allocator.h
js/src/gc/GC.cpp
js/src/gc/GCLock.h
js/src/gc/Verifier.cpp
js/src/jsapi-tests/testGCChunkPool.cpp
js/src/vm/Runtime.h
--- a/js/src/gc/Allocator.h
+++ b/js/src/gc/Allocator.h
@@ -2,16 +2,17 @@
  * vim: set ts=8 sts=2 et sw=2 tw=80:
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef gc_Allocator_h
 #define gc_Allocator_h
 
+#include "gc/GCLock.h"
 #include "gc/Heap.h"
 #include "js/RootingAPI.h"
 
 class JSFatInlineString;
 
 namespace js {
 
 struct Class;
--- a/js/src/gc/GC.cpp
+++ b/js/src/gc/GC.cpp
@@ -211,16 +211,17 @@
 #include "jsapi.h"
 #include "jsfriendapi.h"
 #include "jstypes.h"
 #include "jsutil.h"
 
 #include "gc/FindSCCs.h"
 #include "gc/FreeOp.h"
 #include "gc/GCInternals.h"
+#include "gc/GCLock.h"
 #include "gc/GCTrace.h"
 #include "gc/Memory.h"
 #include "gc/Policy.h"
 #include "gc/WeakMap.h"
 #include "jit/BaselineJIT.h"
 #include "jit/IonCode.h"
 #include "jit/JitcodeMap.h"
 #include "jit/JitRealm.h"
new file mode 100644
--- /dev/null
+++ b/js/src/gc/GCLock.h
@@ -0,0 +1,118 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ * vim: set ts=8 sts=2 et sw=2 tw=80:
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/*
+ * GC-internal classes for acquiring and releasing the GC lock.
+ */
+
+#ifndef gc_GCLock_h
+#define gc_GCLock_h
+
+#include "vm/Runtime.h"
+
+namespace js {
+
+class AutoUnlockGC;
+
+/*
+ * RAII class that takes the GC lock while it is live.
+ *
+ * Usually functions will pass const references of this class.  However
+ * non-const references can be used to either temporarily release the lock by
+ * use of AutoUnlockGC or to start background allocation when the lock is
+ * released.
+ */
+class MOZ_RAII AutoLockGC {
+ public:
+  explicit AutoLockGC(JSRuntime* rt MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
+      : runtime_(rt) {
+    MOZ_GUARD_OBJECT_NOTIFIER_INIT;
+    lock();
+  }
+
+  ~AutoLockGC() { lockGuard_.reset(); }
+
+  void lock() {
+    MOZ_ASSERT(lockGuard_.isNothing());
+    lockGuard_.emplace(runtime_->gc.lock);
+  }
+
+  void unlock() {
+    MOZ_ASSERT(lockGuard_.isSome());
+    lockGuard_.reset();
+  }
+
+ protected:
+  js::LockGuard<js::Mutex>& guard() { return lockGuard_.ref(); }
+
+  JSRuntime* runtime() const { return runtime_; }
+
+ private:
+  JSRuntime* runtime_;
+  mozilla::Maybe<js::LockGuard<js::Mutex>> lockGuard_;
+  MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
+
+  AutoLockGC(const AutoLockGC&) = delete;
+  AutoLockGC& operator=(const AutoLockGC&) = delete;
+};
+
+/*
+ * Same as AutoLockGC except it can optionally start a background chunk
+ * allocation task when the lock is released.
+ */
+class MOZ_RAII AutoLockGCBgAlloc : public AutoLockGC {
+ public:
+  explicit AutoLockGCBgAlloc(JSRuntime* rt)
+      : AutoLockGC(rt), startBgAlloc(false) {}
+
+  ~AutoLockGCBgAlloc() {
+    unlock();
+
+    /*
+     * We have to do this after releasing the lock because it may acquire
+     * the helper lock which could cause lock inversion if we still held
+     * the GC lock.
+     */
+    if (startBgAlloc) {
+      runtime()->gc.startBackgroundAllocTaskIfIdle();  // Ignore failure.
+    }
+  }
+
+  /*
+   * This can be used to start a background allocation task (if one isn't
+   * already running) that allocates chunks and makes them available in the
+   * free chunks list.  This happens after the lock is released in order to
+   * avoid lock inversion.
+   */
+  void tryToStartBackgroundAllocation() { startBgAlloc = true; }
+
+ private:
+  // true if we should start a background chunk allocation task after the
+  // lock is released.
+  bool startBgAlloc;
+};
+
+class MOZ_RAII AutoUnlockGC {
+ public:
+  explicit AutoUnlockGC(AutoLockGC& lock MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
+      : lock(lock) {
+    MOZ_GUARD_OBJECT_NOTIFIER_INIT;
+    lock.unlock();
+  }
+
+  ~AutoUnlockGC() { lock.lock(); }
+
+ private:
+  AutoLockGC& lock;
+  MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
+
+  AutoUnlockGC(const AutoUnlockGC&) = delete;
+  AutoUnlockGC& operator=(const AutoUnlockGC&) = delete;
+};
+
+} // namespace js
+
+#endif /* gc_GCLock_h */
--- a/js/src/gc/Verifier.cpp
+++ b/js/src/gc/Verifier.cpp
@@ -8,16 +8,17 @@
 #include "mozilla/IntegerPrintfMacros.h"
 #include "mozilla/Sprintf.h"
 
 #ifdef MOZ_VALGRIND
 #include <valgrind/memcheck.h>
 #endif
 
 #include "gc/GCInternals.h"
+#include "gc/GCLock.h"
 #include "gc/PublicIterators.h"
 #include "gc/WeakMap.h"
 #include "gc/Zone.h"
 #include "js/HashTable.h"
 #include "vm/JSContext.h"
 
 #include "gc/ArenaList-inl.h"
 #include "gc/GC-inl.h"
--- a/js/src/jsapi-tests/testGCChunkPool.cpp
+++ b/js/src/jsapi-tests/testGCChunkPool.cpp
@@ -2,16 +2,17 @@
  * vim: set ts=8 sts=2 et sw=2 tw=80:
  */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozilla/Move.h"
 
+#include "gc/GCLock.h"
 #include "gc/GCRuntime.h"
 #include "gc/Heap.h"
 
 #include "jsapi-tests/tests.h"
 
 BEGIN_TEST(testGCChunkPool) {
   const int N = 10;
   js::gc::ChunkPool pool;
--- a/js/src/vm/Runtime.h
+++ b/js/src/vm/Runtime.h
@@ -1007,114 +1007,16 @@ struct JSRuntime : public js::MallocProv
     JSErrorInterceptor* interceptor;
   };
   ErrorInterceptionSupport errorInterception;
 #endif  // defined(NIGHTLY_BUILD)
 };
 
 namespace js {
 
-/*
- * RAII class that takes the GC lock while it is live.
- *
- * Usually functions will pass const references of this class.  However
- * non-const references can be used to either temporarily release the lock by
- * use of AutoUnlockGC or to start background allocation when the lock is
- * released.
- */
-class MOZ_RAII AutoLockGC {
- public:
-  explicit AutoLockGC(JSRuntime* rt MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
-      : runtime_(rt) {
-    MOZ_GUARD_OBJECT_NOTIFIER_INIT;
-    lock();
-  }
-
-  ~AutoLockGC() { lockGuard_.reset(); }
-
-  void lock() {
-    MOZ_ASSERT(lockGuard_.isNothing());
-    lockGuard_.emplace(runtime_->gc.lock);
-  }
-
-  void unlock() {
-    MOZ_ASSERT(lockGuard_.isSome());
-    lockGuard_.reset();
-  }
-
-  js::LockGuard<js::Mutex>& guard() { return lockGuard_.ref(); }
-
- protected:
-  JSRuntime* runtime() const { return runtime_; }
-
- private:
-  JSRuntime* runtime_;
-  mozilla::Maybe<js::LockGuard<js::Mutex>> lockGuard_;
-  MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
-
-  AutoLockGC(const AutoLockGC&) = delete;
-  AutoLockGC& operator=(const AutoLockGC&) = delete;
-};
-
-/*
- * Same as AutoLockGC except it can optionally start a background chunk
- * allocation task when the lock is released.
- */
-class MOZ_RAII AutoLockGCBgAlloc : public AutoLockGC {
- public:
-  explicit AutoLockGCBgAlloc(JSRuntime* rt)
-      : AutoLockGC(rt), startBgAlloc(false) {}
-
-  ~AutoLockGCBgAlloc() {
-    unlock();
-
-    /*
-     * We have to do this after releasing the lock because it may acquire
-     * the helper lock which could cause lock inversion if we still held
-     * the GC lock.
-     */
-    if (startBgAlloc) {
-      runtime()->gc.startBackgroundAllocTaskIfIdle();  // Ignore failure.
-    }
-  }
-
-  /*
-   * This can be used to start a background allocation task (if one isn't
-   * already running) that allocates chunks and makes them available in the
-   * free chunks list.  This happens after the lock is released in order to
-   * avoid lock inversion.
-   */
-  void tryToStartBackgroundAllocation() { startBgAlloc = true; }
-
- private:
-  // true if we should start a background chunk allocation task after the
-  // lock is released.
-  bool startBgAlloc;
-};
-
-class MOZ_RAII AutoUnlockGC {
- public:
-  explicit AutoUnlockGC(AutoLockGC& lock MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
-      : lock(lock) {
-    MOZ_GUARD_OBJECT_NOTIFIER_INIT;
-    lock.unlock();
-  }
-
-  ~AutoUnlockGC() { lock.lock(); }
-
- private:
-  AutoLockGC& lock;
-  MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
-
-  AutoUnlockGC(const AutoUnlockGC&) = delete;
-  AutoUnlockGC& operator=(const AutoUnlockGC&) = delete;
-};
-
-/************************************************************************/
-
 static MOZ_ALWAYS_INLINE void MakeRangeGCSafe(Value* vec, size_t len) {
   // Don't PodZero here because JS::Value is non-trivial.
   for (size_t i = 0; i < len; i++) {
     vec[i].setDouble(+0.0);
   }
 }
 
 static MOZ_ALWAYS_INLINE void MakeRangeGCSafe(Value* beg, Value* end) {