author Gregory Szorc <>
Fri, 20 Sep 2013 15:46:23 -0700
changeset 148199 c678ea1db9c9233f23fb97345302f1991c81a201
parent 143253 94faaa7e4d408654ffea00ad038b9e2f870ef92c
child 148781 48fc29474b4d8c1b087e0f8fe2da56ea6572a24f
permissions -rw-r--r--
Bug 794506 - Part 1: Move virtualenv code under mozbuild; r=ted

/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
 * You can obtain one at */

#include "nsError.h"
#include "mozilla/Assertions.h"
#include "mozilla/MemoryReporting.h"
#include "mozilla/NullPtr.h"

namespace mozilla {

struct StackBlock;
struct StackMark;
class AutoStackArena;
 * Private helper class for AutoStackArena.
class StackArena {
  friend class AutoStackArena;

  nsresult Init() { return mBlocks ? NS_OK : NS_ERROR_OUT_OF_MEMORY; }

  // Memory management functions
  void* Allocate(size_t aSize);
  void Push();
  void Pop();

  size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;

  // our current position in memory
  size_t mPos;

  // a list of memory block. Usually there is only one
  // but if we overrun our stack size we can get more memory.
  StackBlock* mBlocks;

  // the current block of memory we are passing our chucks of
  StackBlock* mCurBlock;

  // our stack of mark where push has been called
  StackMark* mMarks;

  // the current top of the mark list
  uint32_t mStackTop;

  // the size of the mark array
  uint32_t mMarkLength;

 * Class for stack scoped arena memory allocations.
 * Callers who wish to allocate memory whose lifetime corresponds to
 * the lifetime of a stack-allocated object can use this class.
 * First, declare an AutoStackArena object on the stack.
 * Then all subsequent calls to Allocate will allocate memory from an
 * arena pool that will be freed when that variable goes out of scope.
 * Nesting is allowed.
 * The allocations cannot be for more than 4044 bytes.
class MOZ_STACK_CLASS AutoStackArena {
  AutoStackArena() : mOwnsStackArena(false) {
    if (!gStackArena) {
      gStackArena = new StackArena();
      mOwnsStackArena = true;

  ~AutoStackArena() {
    if (mOwnsStackArena) {
      delete gStackArena;
      gStackArena = nullptr;

  static void* Allocate(size_t aSize) {
    MOZ_ASSERT(aSize <= 4044);
    return gStackArena->Allocate(aSize);

  static StackArena* gStackArena;
  bool mOwnsStackArena;

} // namespace mozilla