layout/base/StackArena.h

changeset 0
6474c204b198
     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

mercurial