Bug 1877642 - Disable browser_fullscreen-tab-close-race.js on apple_silicon !debug...
[gecko.git] / js / src / gc / GCLock.h
blob64c28ac544afd4820fcba615b8b713f6597f736d
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 * vim: set ts=8 sts=2 et sw=2 tw=80:
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 /*
8 * GC-internal classes for acquiring and releasing the GC lock.
9 */
11 #ifndef gc_GCLock_h
12 #define gc_GCLock_h
14 #include "vm/Runtime.h"
16 namespace js {
18 class AutoUnlockGC;
21 * RAII class that takes the GC lock while it is live.
23 * Usually functions will pass const references of this class. However
24 * non-const references can be used to either temporarily release the lock by
25 * use of AutoUnlockGC or to start background allocation when the lock is
26 * released.
28 class MOZ_RAII AutoLockGC {
29 public:
30 explicit AutoLockGC(gc::GCRuntime* gc) : gc(gc) { lock(); }
31 explicit AutoLockGC(JSRuntime* rt) : AutoLockGC(&rt->gc) {}
33 ~AutoLockGC() { lockGuard_.reset(); }
35 js::LockGuard<js::Mutex>& guard() { return lockGuard_.ref(); }
37 protected:
38 void lock() {
39 MOZ_ASSERT(lockGuard_.isNothing());
40 lockGuard_.emplace(gc->lock);
43 void unlock() {
44 MOZ_ASSERT(lockGuard_.isSome());
45 lockGuard_.reset();
48 gc::GCRuntime* const gc;
50 private:
51 mozilla::Maybe<js::LockGuard<js::Mutex>> lockGuard_;
53 AutoLockGC(const AutoLockGC&) = delete;
54 AutoLockGC& operator=(const AutoLockGC&) = delete;
56 friend class AutoUnlockGC; // For lock/unlock.
60 * Same as AutoLockGC except it can optionally start a background chunk
61 * allocation task when the lock is released.
63 class MOZ_RAII AutoLockGCBgAlloc : public AutoLockGC {
64 public:
65 explicit AutoLockGCBgAlloc(gc::GCRuntime* gc) : AutoLockGC(gc) {}
66 explicit AutoLockGCBgAlloc(JSRuntime* rt) : AutoLockGCBgAlloc(&rt->gc) {}
68 ~AutoLockGCBgAlloc() {
69 unlock();
72 * We have to do this after releasing the lock because it may acquire
73 * the helper lock which could cause lock inversion if we still held
74 * the GC lock.
76 if (startBgAlloc) {
77 gc->startBackgroundAllocTaskIfIdle();
82 * This can be used to start a background allocation task (if one isn't
83 * already running) that allocates chunks and makes them available in the
84 * free chunks list. This happens after the lock is released in order to
85 * avoid lock inversion.
87 void tryToStartBackgroundAllocation() { startBgAlloc = true; }
89 private:
90 // true if we should start a background chunk allocation task after the
91 // lock is released.
92 bool startBgAlloc = false;
95 class MOZ_RAII AutoUnlockGC {
96 public:
97 explicit AutoUnlockGC(AutoLockGC& lock) : lock(lock) { lock.unlock(); }
99 ~AutoUnlockGC() { lock.lock(); }
101 private:
102 AutoLockGC& lock;
104 AutoUnlockGC(const AutoUnlockGC&) = delete;
105 AutoUnlockGC& operator=(const AutoUnlockGC&) = delete;
108 } // namespace js
110 #endif /* gc_GCLock_h */