1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 #ifndef mozalloc_VolatileBuffer_h
6 #define mozalloc_VolatileBuffer_h
8 #include "mozilla/mozalloc.h"
9 #include "mozilla/Mutex.h"
10 #include "mozilla/RefPtr.h"
11 #include "mozilla/MemoryReporting.h"
12 #include "mozilla/RefCounted.h"
16 * This class represents a piece of memory that can potentially be reclaimed
17 * by the OS when not in use. As long as there are one or more
18 * VolatileBufferPtrs holding on to a VolatileBuffer, the memory will remain
19 * available. However, when there are no VolatileBufferPtrs holding a
20 * VolatileBuffer, the OS can purge the pages if it wants to. The OS can make
21 * better decisions about what pages to purge than we can.
23 * VolatileBuffers may not always be volatile - if the allocation is too small,
24 * or if the OS doesn't support the feature, or if the OS doesn't want to,
25 * the buffer will be allocated on heap.
27 * VolatileBuffer allocations are fallible. They are intended for uses where
28 * one may allocate large buffers for caching data. Init() must be called
31 * After getting a reference to VolatileBuffer using VolatileBufferPtr,
32 * WasPurged() can be used to check if the OS purged any pages in the buffer.
33 * The OS cannot purge a buffer immediately after a VolatileBuffer is
34 * initialized. At least one VolatileBufferPtr must be created before the
35 * buffer can be purged, so the first use of VolatileBufferPtr does not need
36 * to check WasPurged().
38 * When a buffer is purged, some or all of the buffer is zeroed out. This
39 * API cannot tell which parts of the buffer were lost.
41 * VolatileBuffer and VolatileBufferPtr are threadsafe.
46 class VolatileBuffer
{
47 friend class VolatileBufferPtr_base
;
50 MOZ_DECLARE_REFCOUNTED_TYPENAME(VolatileBuffer
)
51 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(VolatileBuffer
)
55 /* aAlignment must be a multiple of the pointer size */
56 bool Init(size_t aSize
, size_t aAlignment
= sizeof(void*));
58 size_t HeapSizeOfExcludingThis(MallocSizeOf aMallocSizeOf
) const;
59 size_t NonHeapSizeOfExcludingThis() const;
63 bool Lock(void** aBuf
);
70 * Protects mLockCount, mFirstLock, and changes to the volatility of our
71 * buffer. Other member variables are read-only except in Init() and the
74 Mutex mMutex MOZ_UNANNOTATED
;
81 #elif defined(XP_DARWIN)
89 class VolatileBufferPtr_base
{
91 explicit VolatileBufferPtr_base(VolatileBuffer
* vbuf
)
92 : mVBuf(vbuf
), mMapping(nullptr), mPurged(false) {
96 ~VolatileBufferPtr_base() { Unlock(); }
98 bool WasBufferPurged() const { return mPurged
; }
101 RefPtr
<VolatileBuffer
> mVBuf
;
104 void Set(VolatileBuffer
* vbuf
) {
115 mPurged
= !mVBuf
->Lock(&mMapping
);
130 class VolatileBufferPtr
: public VolatileBufferPtr_base
{
132 explicit VolatileBufferPtr(VolatileBuffer
* vbuf
)
133 : VolatileBufferPtr_base(vbuf
) {}
134 VolatileBufferPtr() : VolatileBufferPtr_base(nullptr) {}
136 VolatileBufferPtr(VolatileBufferPtr
&& aOther
)
137 : VolatileBufferPtr_base(aOther
.mVBuf
) {
141 operator T
*() const { return (T
*)mMapping
; }
143 VolatileBufferPtr
& operator=(VolatileBuffer
* aVBuf
) {
148 VolatileBufferPtr
& operator=(VolatileBufferPtr
&& aOther
) {
149 MOZ_ASSERT(this != &aOther
, "Self-moves are prohibited");
156 VolatileBufferPtr(VolatileBufferPtr
const& vbufptr
) = delete;
159 } // namespace mozilla
161 #endif /* mozalloc_VolatileBuffer_h */