Squashed 'third_party/gperftools/' content from commit 54505f1

Change-Id: Id02e833828732b0efe7dac722b8485279e67c5fa
git-subtree-dir: third_party/gperftools
git-subtree-split: 54505f1d50c2d1f4676f5e87090b64a117fd980e
diff --git a/src/page_heap_allocator.h b/src/page_heap_allocator.h
new file mode 100644
index 0000000..892d1c1
--- /dev/null
+++ b/src/page_heap_allocator.h
@@ -0,0 +1,114 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
+// Copyright (c) 2008, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// ---
+// Author: Sanjay Ghemawat <opensource@google.com>
+
+#ifndef TCMALLOC_PAGE_HEAP_ALLOCATOR_H_
+#define TCMALLOC_PAGE_HEAP_ALLOCATOR_H_
+
+#include <stddef.h>                     // for NULL, size_t
+
+#include "common.h"            // for MetaDataAlloc
+#include "internal_logging.h"  // for ASSERT
+
+namespace tcmalloc {
+
+// Simple allocator for objects of a specified type.  External locking
+// is required before accessing one of these objects.
+template <class T>
+class PageHeapAllocator {
+ public:
+  // We use an explicit Init function because these variables are statically
+  // allocated and their constructors might not have run by the time some
+  // other static variable tries to allocate memory.
+  void Init() {
+    ASSERT(sizeof(T) <= kAllocIncrement);
+    inuse_ = 0;
+    free_area_ = NULL;
+    free_avail_ = 0;
+    free_list_ = NULL;
+    // Reserve some space at the beginning to avoid fragmentation.
+    Delete(New());
+  }
+
+  T* New() {
+    // Consult free list
+    void* result;
+    if (free_list_ != NULL) {
+      result = free_list_;
+      free_list_ = *(reinterpret_cast<void**>(result));
+    } else {
+      if (free_avail_ < sizeof(T)) {
+        // Need more room. We assume that MetaDataAlloc returns
+        // suitably aligned memory.
+        free_area_ = reinterpret_cast<char*>(MetaDataAlloc(kAllocIncrement));
+        if (free_area_ == NULL) {
+          Log(kCrash, __FILE__, __LINE__,
+              "FATAL ERROR: Out of memory trying to allocate internal "
+              "tcmalloc data (bytes, object-size)",
+              kAllocIncrement, sizeof(T));
+        }
+        free_avail_ = kAllocIncrement;
+      }
+      result = free_area_;
+      free_area_ += sizeof(T);
+      free_avail_ -= sizeof(T);
+    }
+    inuse_++;
+    return reinterpret_cast<T*>(result);
+  }
+
+  void Delete(T* p) {
+    *(reinterpret_cast<void**>(p)) = free_list_;
+    free_list_ = p;
+    inuse_--;
+  }
+
+  int inuse() const { return inuse_; }
+
+ private:
+  // How much to allocate from system at a time
+  static const int kAllocIncrement = 128 << 10;
+
+  // Free area from which to carve new objects
+  char* free_area_;
+  size_t free_avail_;
+
+  // Free list of already carved objects
+  void* free_list_;
+
+  // Number of allocated but unfreed objects
+  int inuse_;
+};
+
+}  // namespace tcmalloc
+
+#endif  // TCMALLOC_PAGE_HEAP_ALLOCATOR_H_