memory/mozalloc/VolatileBufferWindows.cpp

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     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 #if defined(XP_WIN)
     6 #  define MOZALLOC_EXPORT __declspec(dllexport)
     7 #endif
     9 #include "VolatileBuffer.h"
    10 #include "mozilla/Assertions.h"
    11 #include "mozilla/mozalloc.h"
    12 #include "mozilla/WindowsVersion.h"
    14 #include <windows.h>
    16 #ifdef MOZ_MEMORY
    17 extern "C" int posix_memalign(void** memptr, size_t alignment, size_t size);
    18 #endif
    20 #ifndef MEM_RESET_UNDO
    21 #define MEM_RESET_UNDO 0x1000000
    22 #endif
    24 #define MIN_VOLATILE_ALLOC_SIZE 8192
    26 namespace mozilla {
    28 VolatileBuffer::VolatileBuffer()
    29   : mBuf(nullptr)
    30   , mSize(0)
    31   , mLockCount(0)
    32   , mHeap(false)
    33   , mFirstLock(true)
    34 {
    35 }
    37 bool
    38 VolatileBuffer::Init(size_t aSize, size_t aAlignment)
    39 {
    40   MOZ_ASSERT(!mSize && !mBuf, "Init called twice");
    41   MOZ_ASSERT(!(aAlignment % sizeof(void *)),
    42              "Alignment must be multiple of pointer size");
    44   mSize = aSize;
    45   if (aSize < MIN_VOLATILE_ALLOC_SIZE) {
    46     goto heap_alloc;
    47   }
    49   static bool sUndoSupported = IsWin8OrLater();
    50   if (!sUndoSupported) {
    51     goto heap_alloc;
    52   }
    54   mBuf = VirtualAllocEx(GetCurrentProcess(),
    55                         nullptr,
    56                         mSize,
    57                         MEM_COMMIT | MEM_RESERVE,
    58                         PAGE_READWRITE);
    59   if (mBuf) {
    60     return true;
    61   }
    63 heap_alloc:
    64 #ifdef MOZ_MEMORY
    65   posix_memalign(&mBuf, aAlignment, aSize);
    66 #else
    67   mBuf = _aligned_malloc(aSize, aAlignment);
    68 #endif
    69   mHeap = true;
    70   return !!mBuf;
    71 }
    73 VolatileBuffer::~VolatileBuffer()
    74 {
    75   if (OnHeap()) {
    76 #ifdef MOZ_MEMORY
    77     free(mBuf);
    78 #else
    79     _aligned_free(mBuf);
    80 #endif
    81   } else {
    82     VirtualFreeEx(GetCurrentProcess(), mBuf, 0, MEM_RELEASE);
    83   }
    84 }
    86 bool
    87 VolatileBuffer::Lock(void** aBuf)
    88 {
    89   MOZ_ASSERT(mBuf, "Attempting to lock an uninitialized VolatileBuffer");
    91   *aBuf = mBuf;
    92   if (++mLockCount > 1 || OnHeap()) {
    93     return true;
    94   }
    96   // MEM_RESET_UNDO's behavior is undefined when called on memory that
    97   // hasn't been MEM_RESET.
    98   if (mFirstLock) {
    99     mFirstLock = false;
   100     return true;
   101   }
   103   void* addr = VirtualAllocEx(GetCurrentProcess(),
   104                               mBuf,
   105                               mSize,
   106                               MEM_RESET_UNDO,
   107                               PAGE_READWRITE);
   108   return !!addr;
   109 }
   111 void
   112 VolatileBuffer::Unlock()
   113 {
   114   MOZ_ASSERT(mLockCount > 0, "VolatileBuffer unlocked too many times!");
   115   if (--mLockCount || OnHeap()) {
   116     return;
   117   }
   119   void* addr = VirtualAllocEx(GetCurrentProcess(),
   120                               mBuf,
   121                               mSize,
   122                               MEM_RESET,
   123                               PAGE_READWRITE);
   124   MOZ_ASSERT(addr, "Failed to MEM_RESET");
   125 }
   127 bool
   128 VolatileBuffer::OnHeap() const
   129 {
   130   return mHeap;
   131 }
   133 size_t
   134 VolatileBuffer::HeapSizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const
   135 {
   136   if (OnHeap()) {
   137 #ifdef MOZ_MEMORY
   138     return aMallocSizeOf(mBuf);
   139 #else
   140     return mSize;
   141 #endif
   142   }
   144   return 0;
   145 }
   147 size_t
   148 VolatileBuffer::NonHeapSizeOfExcludingThis() const
   149 {
   150   if (OnHeap()) {
   151     return 0;
   152   }
   154   return (mSize + 4095) & ~4095;
   155 }
   157 } // namespace mozilla

mercurial