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 #ifndef js_RefCounted_h
8 #define js_RefCounted_h
10 #include "mozilla/Atomics.h"
11 #include "mozilla/RefCountType.h"
13 #include "js/Utility.h"
15 // These types implement the same interface as mozilla::(Atomic)RefCounted and
16 // must be used instead of mozilla::(Atomic)RefCounted for everything in
17 // SpiderMonkey. There are two reasons:
18 // - Release() needs to call js_delete, not delete
19 // - SpiderMonkey does not have MOZILLA_INTERNAL_API defined which can lead
20 // to ODR violations that show up as spurious leak reports when ref-counted
21 // types are allocated by SpiderMonkey and released by Gecko (or vice versa).
27 static const MozRefCountType DEAD
= 0xffffdead;
30 RefCounted() : mRefCnt(0) {}
31 ~RefCounted() { MOZ_ASSERT(mRefCnt
== DEAD
); }
35 MOZ_ASSERT(int32_t(mRefCnt
) >= 0);
39 void Release() const {
40 MOZ_ASSERT(int32_t(mRefCnt
) > 0);
41 MozRefCountType cnt
= --mRefCnt
;
46 js_delete(const_cast<T
*>(static_cast<const T
*>(this)));
51 mutable MozRefCountType mRefCnt
;
55 class AtomicRefCounted
{
56 // On 64-bit systems, if the refcount type is small (say, 32 bits), there's
57 // a risk that it could overflow. So require it to be large enough.
59 static_assert(sizeof(MozRefCountType
) == sizeof(uintptr_t),
60 "You're at risk for ref count overflow.");
62 static const MozRefCountType DEAD
= ~MozRefCountType(0xffff) | 0xdead;
65 AtomicRefCounted() = default;
66 ~AtomicRefCounted() { MOZ_ASSERT(mRefCnt
== DEAD
); }
71 MOZ_ASSERT(mRefCnt
!= DEAD
);
74 void Release() const {
75 MOZ_ASSERT(mRefCnt
!= 0);
76 MozRefCountType cnt
= --mRefCnt
;
81 js_delete(const_cast<T
*>(static_cast<const T
*>(this)));
85 bool hasOneRef() const {
86 MOZ_ASSERT(mRefCnt
> 0);
91 mutable mozilla::Atomic
<MozRefCountType
> mRefCnt
{0};
96 #endif /* js_RefCounted_h */