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 #include "VolatileBuffer.h"
6 #include "mozilla/Assertions.h"
7 #include "mozilla/DebugOnly.h"
8 #include "mozilla/mozalloc.h"
13 extern "C" int posix_memalign(void** memptr
, size_t alignment
, size_t size
);
16 #ifndef MEM_RESET_UNDO
17 # define MEM_RESET_UNDO 0x1000000
20 #define MIN_VOLATILE_ALLOC_SIZE 8192
24 VolatileBuffer::VolatileBuffer()
25 : mMutex("VolatileBuffer"),
32 bool VolatileBuffer::Init(size_t aSize
, size_t aAlignment
) {
33 MOZ_ASSERT(!mSize
&& !mBuf
, "Init called twice");
34 MOZ_ASSERT(!(aAlignment
% sizeof(void*)),
35 "Alignment must be multiple of pointer size");
38 if (aSize
< MIN_VOLATILE_ALLOC_SIZE
) {
42 mBuf
= VirtualAllocEx(GetCurrentProcess(), nullptr, mSize
,
43 MEM_COMMIT
| MEM_RESERVE
, PAGE_READWRITE
);
50 posix_memalign(&mBuf
, aAlignment
, aSize
);
52 mBuf
= _aligned_malloc(aSize
, aAlignment
);
58 VolatileBuffer::~VolatileBuffer() {
59 MOZ_ASSERT(mLockCount
== 0, "Being destroyed with non-zero lock count?");
68 VirtualFreeEx(GetCurrentProcess(), mBuf
, 0, MEM_RELEASE
);
72 bool VolatileBuffer::Lock(void** aBuf
) {
73 MutexAutoLock
lock(mMutex
);
75 MOZ_ASSERT(mBuf
, "Attempting to lock an uninitialized VolatileBuffer");
78 if (++mLockCount
> 1 || OnHeap()) {
82 // MEM_RESET_UNDO's behavior is undefined when called on memory that
83 // hasn't been MEM_RESET.
89 void* addr
= VirtualAllocEx(GetCurrentProcess(), mBuf
, mSize
, MEM_RESET_UNDO
,
94 void VolatileBuffer::Unlock() {
95 MutexAutoLock
lock(mMutex
);
97 MOZ_ASSERT(mLockCount
> 0, "VolatileBuffer unlocked too many times!");
98 if (--mLockCount
|| OnHeap()) {
102 DebugOnly
<void*> addr
= VirtualAllocEx(GetCurrentProcess(), mBuf
, mSize
,
103 MEM_RESET
, PAGE_READWRITE
);
104 MOZ_ASSERT(addr
, "Failed to MEM_RESET");
107 bool VolatileBuffer::OnHeap() const { return mHeap
; }
109 size_t VolatileBuffer::HeapSizeOfExcludingThis(
110 MallocSizeOf aMallocSizeOf
) const {
113 return aMallocSizeOf(mBuf
);
122 size_t VolatileBuffer::NonHeapSizeOfExcludingThis() const {
127 return (mSize
+ 4095) & ~4095;
130 } // namespace mozilla