1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/layout/base/StackArena.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,98 @@ 1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this file, 1.6 + * You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.7 + 1.8 +#ifndef StackArena_h 1.9 +#define StackArena_h 1.10 + 1.11 +#include "nsError.h" 1.12 +#include "mozilla/Assertions.h" 1.13 +#include "mozilla/MemoryReporting.h" 1.14 +#include "mozilla/NullPtr.h" 1.15 + 1.16 +namespace mozilla { 1.17 + 1.18 +struct StackBlock; 1.19 +struct StackMark; 1.20 +class AutoStackArena; 1.21 + 1.22 +// Private helper class for AutoStackArena. 1.23 +class StackArena { 1.24 +private: 1.25 + friend class AutoStackArena; 1.26 + StackArena(); 1.27 + ~StackArena(); 1.28 + 1.29 + nsresult Init() { return mBlocks ? NS_OK : NS_ERROR_OUT_OF_MEMORY; } 1.30 + 1.31 + // Memory management functions. 1.32 + void* Allocate(size_t aSize); 1.33 + void Push(); 1.34 + void Pop(); 1.35 + 1.36 + size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const; 1.37 + 1.38 + // Our current position in memory. 1.39 + size_t mPos; 1.40 + 1.41 + // A list of memory blocks. Usually there is only one 1.42 + // but if we overrun our stack size we can get more memory. 1.43 + StackBlock* mBlocks; 1.44 + 1.45 + // The current block. 1.46 + StackBlock* mCurBlock; 1.47 + 1.48 + // Our stack of mark where push has been called. 1.49 + StackMark* mMarks; 1.50 + 1.51 + // The current top of the mark list. 1.52 + uint32_t mStackTop; 1.53 + 1.54 + // The size of the mark array. 1.55 + uint32_t mMarkLength; 1.56 +}; 1.57 + 1.58 +// Class for stack scoped arena memory allocations. 1.59 +// 1.60 +// Callers who wish to allocate memory whose lifetime corresponds to the 1.61 +// lifetime of a stack-allocated object can use this class. First, 1.62 +// declare an AutoStackArena object on the stack. Then all subsequent 1.63 +// calls to Allocate will allocate memory from an arena pool that will 1.64 +// be freed when that variable goes out of scope. Nesting is allowed. 1.65 +// 1.66 +// Individual allocations cannot exceed StackBlock::MAX_USABLE_SIZE 1.67 +// bytes. 1.68 +// 1.69 +class MOZ_STACK_CLASS AutoStackArena { 1.70 +public: 1.71 + AutoStackArena() 1.72 + : mOwnsStackArena(false) 1.73 + { 1.74 + if (!gStackArena) { 1.75 + gStackArena = new StackArena(); 1.76 + mOwnsStackArena = true; 1.77 + gStackArena->Init(); 1.78 + } 1.79 + gStackArena->Push(); 1.80 + } 1.81 + 1.82 + ~AutoStackArena() { 1.83 + gStackArena->Pop(); 1.84 + if (mOwnsStackArena) { 1.85 + delete gStackArena; 1.86 + gStackArena = nullptr; 1.87 + } 1.88 + } 1.89 + 1.90 + static void* Allocate(size_t aSize) { 1.91 + return gStackArena->Allocate(aSize); 1.92 + } 1.93 + 1.94 +private: 1.95 + static StackArena* gStackArena; 1.96 + bool mOwnsStackArena; 1.97 +}; 1.98 + 1.99 +} // namespace mozilla 1.100 + 1.101 +#endif