Thu, 22 Jan 2015 13:21:57 +0100
Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6
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/RefPtr.h"
10 #include "mozilla/MemoryReporting.h"
11 #include "mozilla/NullPtr.h"
13 /* VolatileBuffer
14 *
15 * This class represents a piece of memory that can potentially be reclaimed
16 * by the OS when not in use. As long as there are one or more
17 * VolatileBufferPtrs holding on to a VolatileBuffer, the memory will remain
18 * available. However, when there are no VolatileBufferPtrs holding a
19 * VolatileBuffer, the OS can purge the pages if it wants to. The OS can make
20 * better decisions about what pages to purge than we can.
21 *
22 * VolatileBuffers may not always be volatile - if the allocation is too small,
23 * or if the OS doesn't support the feature, or if the OS doesn't want to,
24 * the buffer will be allocated on heap.
25 *
26 * VolatileBuffer allocations are fallible. They are intended for uses where
27 * one may allocate large buffers for caching data. Init() must be called
28 * exactly once.
29 *
30 * After getting a reference to VolatileBuffer using VolatileBufferPtr,
31 * WasPurged() can be used to check if the OS purged any pages in the buffer.
32 * The OS cannot purge a buffer immediately after a VolatileBuffer is
33 * initialized. At least one VolatileBufferPtr must be created before the
34 * buffer can be purged, so the first use of VolatileBufferPtr does not need
35 * to check WasPurged().
36 *
37 * When a buffer is purged, some or all of the buffer is zeroed out. This
38 * API cannot tell which parts of the buffer were lost.
39 *
40 * VolatileBuffer is not thread safe. Do not use VolatileBufferPtrs on
41 * different threads.
42 */
44 namespace mozilla {
46 class MOZALLOC_EXPORT VolatileBuffer : public RefCounted<VolatileBuffer>
47 {
48 friend class VolatileBufferPtr_base;
49 public:
50 MOZ_DECLARE_REFCOUNTED_TYPENAME(VolatileBuffer)
51 VolatileBuffer();
52 ~VolatileBuffer();
54 /* aAlignment must be a multiple of the pointer size */
55 bool Init(size_t aSize, size_t aAlignment = sizeof(void*));
57 size_t HeapSizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const;
58 size_t NonHeapSizeOfExcludingThis() const;
59 bool OnHeap() const;
61 protected:
62 bool Lock(void** aBuf);
63 void Unlock();
65 private:
66 void* mBuf;
67 size_t mSize;
68 int mLockCount;
69 #if defined(ANDROID)
70 int mFd;
71 #elif defined(XP_DARWIN)
72 bool mHeap;
73 #elif defined(XP_WIN)
74 bool mHeap;
75 bool mFirstLock;
76 #endif
77 };
79 class VolatileBufferPtr_base {
80 public:
81 VolatileBufferPtr_base(VolatileBuffer* vbuf) : mVBuf(vbuf) {
82 if (vbuf) {
83 mPurged = !vbuf->Lock(&mMapping);
84 } else {
85 mMapping = nullptr;
86 mPurged = false;
87 }
88 }
90 ~VolatileBufferPtr_base() {
91 if (mVBuf) {
92 mVBuf->Unlock();
93 }
94 }
96 bool WasBufferPurged() const {
97 return mPurged;
98 }
100 protected:
101 void* mMapping;
103 private:
104 RefPtr<VolatileBuffer> mVBuf;
105 bool mPurged;
106 };
108 template <class T>
109 class VolatileBufferPtr : public VolatileBufferPtr_base
110 {
111 public:
112 VolatileBufferPtr(VolatileBuffer* vbuf) : VolatileBufferPtr_base(vbuf) {}
114 operator T*() const {
115 return (T*) mMapping;
116 }
117 };
119 }; /* namespace mozilla */
121 #endif /* mozalloc_VolatileBuffer_h */