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/. */
8 * GC-internal classes for acquiring and releasing the GC lock.
14 #include "vm/Runtime.h"
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
28 class MOZ_RAII AutoLockGC
{
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(); }
39 MOZ_ASSERT(lockGuard_
.isNothing());
40 lockGuard_
.emplace(gc
->lock
);
44 MOZ_ASSERT(lockGuard_
.isSome());
48 gc::GCRuntime
* const gc
;
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
{
65 explicit AutoLockGCBgAlloc(gc::GCRuntime
* gc
) : AutoLockGC(gc
) {}
66 explicit AutoLockGCBgAlloc(JSRuntime
* rt
) : AutoLockGCBgAlloc(&rt
->gc
) {}
68 ~AutoLockGCBgAlloc() {
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
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; }
90 // true if we should start a background chunk allocation task after the
92 bool startBgAlloc
= false;
95 class MOZ_RAII AutoUnlockGC
{
97 explicit AutoUnlockGC(AutoLockGC
& lock
) : lock(lock
) { lock
.unlock(); }
99 ~AutoUnlockGC() { lock
.lock(); }
104 AutoUnlockGC(const AutoUnlockGC
&) = delete;
105 AutoUnlockGC
& operator=(const AutoUnlockGC
&) = delete;
110 #endif /* gc_GCLock_h */