no bug - Bumping Firefox l10n changesets r=release a=l10n-bump DONTBUILD CLOSED TREE
[gecko.git] / memory / volatile / VolatileBufferWindows.cpp
blobfbd4eec07a0e347ec870ef4ed3a33b8a88edc178
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"
10 #include <windows.h>
12 #ifdef MOZ_MEMORY
13 extern "C" int posix_memalign(void** memptr, size_t alignment, size_t size);
14 #endif
16 #ifndef MEM_RESET_UNDO
17 # define MEM_RESET_UNDO 0x1000000
18 #endif
20 #define MIN_VOLATILE_ALLOC_SIZE 8192
22 namespace mozilla {
24 VolatileBuffer::VolatileBuffer()
25 : mMutex("VolatileBuffer"),
26 mBuf(nullptr),
27 mSize(0),
28 mLockCount(0),
29 mHeap(false),
30 mFirstLock(true) {}
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");
37 mSize = aSize;
38 if (aSize < MIN_VOLATILE_ALLOC_SIZE) {
39 goto heap_alloc;
42 mBuf = VirtualAllocEx(GetCurrentProcess(), nullptr, mSize,
43 MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
44 if (mBuf) {
45 return true;
48 heap_alloc:
49 #ifdef MOZ_MEMORY
50 posix_memalign(&mBuf, aAlignment, aSize);
51 #else
52 mBuf = _aligned_malloc(aSize, aAlignment);
53 #endif
54 mHeap = true;
55 return !!mBuf;
58 VolatileBuffer::~VolatileBuffer() {
59 MOZ_ASSERT(mLockCount == 0, "Being destroyed with non-zero lock count?");
61 if (OnHeap()) {
62 #ifdef MOZ_MEMORY
63 free(mBuf);
64 #else
65 _aligned_free(mBuf);
66 #endif
67 } else {
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");
77 *aBuf = mBuf;
78 if (++mLockCount > 1 || OnHeap()) {
79 return true;
82 // MEM_RESET_UNDO's behavior is undefined when called on memory that
83 // hasn't been MEM_RESET.
84 if (mFirstLock) {
85 mFirstLock = false;
86 return true;
89 void* addr = VirtualAllocEx(GetCurrentProcess(), mBuf, mSize, MEM_RESET_UNDO,
90 PAGE_READWRITE);
91 return !!addr;
94 void VolatileBuffer::Unlock() {
95 MutexAutoLock lock(mMutex);
97 MOZ_ASSERT(mLockCount > 0, "VolatileBuffer unlocked too many times!");
98 if (--mLockCount || OnHeap()) {
99 return;
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 {
111 if (OnHeap()) {
112 #ifdef MOZ_MEMORY
113 return aMallocSizeOf(mBuf);
114 #else
115 return mSize;
116 #endif
119 return 0;
122 size_t VolatileBuffer::NonHeapSizeOfExcludingThis() const {
123 if (OnHeap()) {
124 return 0;
127 return (mSize + 4095) & ~4095;
130 } // namespace mozilla