no bug - Bumping Firefox l10n changesets r=release a=l10n-bump DONTBUILD CLOSED TREE
[gecko.git] / memory / volatile / VolatileBuffer.h
blobbadd7f3cec5ee662cfff155df99a57d21d18a2f4
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"
14 /* VolatileBuffer
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
29 * exactly once.
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.
44 namespace mozilla {
46 class VolatileBuffer {
47 friend class VolatileBufferPtr_base;
49 public:
50 MOZ_DECLARE_REFCOUNTED_TYPENAME(VolatileBuffer)
51 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(VolatileBuffer)
53 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;
60 bool OnHeap() const;
62 protected:
63 bool Lock(void** aBuf);
64 void Unlock();
66 private:
67 ~VolatileBuffer();
69 /**
70 * Protects mLockCount, mFirstLock, and changes to the volatility of our
71 * buffer. Other member variables are read-only except in Init() and the
72 * destructor.
74 Mutex mMutex MOZ_UNANNOTATED;
76 void* mBuf;
77 size_t mSize;
78 int mLockCount;
79 #if defined(ANDROID)
80 int mFd;
81 #elif defined(XP_DARWIN)
82 bool mHeap;
83 #elif defined(XP_WIN)
84 bool mHeap;
85 bool mFirstLock;
86 #endif
89 class VolatileBufferPtr_base {
90 public:
91 explicit VolatileBufferPtr_base(VolatileBuffer* vbuf)
92 : mVBuf(vbuf), mMapping(nullptr), mPurged(false) {
93 Lock();
96 ~VolatileBufferPtr_base() { Unlock(); }
98 bool WasBufferPurged() const { return mPurged; }
100 protected:
101 RefPtr<VolatileBuffer> mVBuf;
102 void* mMapping;
104 void Set(VolatileBuffer* vbuf) {
105 Unlock();
106 mVBuf = vbuf;
107 Lock();
110 private:
111 bool mPurged;
113 void Lock() {
114 if (mVBuf) {
115 mPurged = !mVBuf->Lock(&mMapping);
116 } else {
117 mMapping = nullptr;
118 mPurged = false;
122 void Unlock() {
123 if (mVBuf) {
124 mVBuf->Unlock();
129 template <class T>
130 class VolatileBufferPtr : public VolatileBufferPtr_base {
131 public:
132 explicit VolatileBufferPtr(VolatileBuffer* vbuf)
133 : VolatileBufferPtr_base(vbuf) {}
134 VolatileBufferPtr() : VolatileBufferPtr_base(nullptr) {}
136 VolatileBufferPtr(VolatileBufferPtr&& aOther)
137 : VolatileBufferPtr_base(aOther.mVBuf) {
138 aOther.Set(nullptr);
141 operator T*() const { return (T*)mMapping; }
143 VolatileBufferPtr& operator=(VolatileBuffer* aVBuf) {
144 Set(aVBuf);
145 return *this;
148 VolatileBufferPtr& operator=(VolatileBufferPtr&& aOther) {
149 MOZ_ASSERT(this != &aOther, "Self-moves are prohibited");
150 Set(aOther.mVBuf);
151 aOther.Set(nullptr);
152 return *this;
155 private:
156 VolatileBufferPtr(VolatileBufferPtr const& vbufptr) = delete;
159 } // namespace mozilla
161 #endif /* mozalloc_VolatileBuffer_h */