Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(237)

Unified Diff: third_party/tcmalloc/chromium/src/system-alloc.cc

Issue 7050034: Merge google-perftools r109 (the current contents of third_party/tcmalloc/vendor) (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 9 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: third_party/tcmalloc/chromium/src/system-alloc.cc
===================================================================
--- third_party/tcmalloc/chromium/src/system-alloc.cc (revision 87277)
+++ third_party/tcmalloc/chromium/src/system-alloc.cc (working copy)
@@ -31,26 +31,29 @@
// Author: Sanjay Ghemawat
#include <config.h>
+#include <errno.h> // for EAGAIN, errno
+#include <fcntl.h> // for open, O_RDWR
+#include <stddef.h> // for size_t, NULL, ptrdiff_t
#if defined HAVE_STDINT_H
-#include <stdint.h>
+#include <stdint.h> // for uintptr_t, intptr_t
#elif defined HAVE_INTTYPES_H
#include <inttypes.h>
#else
#include <sys/types.h>
#endif
+#ifdef HAVE_MMAP
+#include <sys/mman.h> // for munmap, mmap, MADV_DONTNEED, etc
+#endif
#ifdef HAVE_UNISTD_H
-#include <unistd.h>
+#include <unistd.h> // for sbrk, getpagesize, off_t
#endif
-#include <fcntl.h> // for open()
-#ifdef HAVE_MMAP
-#include <sys/mman.h>
-#endif
-#include <errno.h>
-#include "system-alloc.h"
+#include <new> // for operator new
+#include <google/malloc_extension.h>
+#include "base/basictypes.h"
+#include "base/commandlineflags.h"
+#include "base/spinlock.h" // for SpinLockHolder, SpinLock, etc
+#include "common.h"
#include "internal_logging.h"
-#include "base/logging.h"
-#include "base/commandlineflags.h"
-#include "base/spinlock.h"
// On systems (like freebsd) that don't define MAP_ANONYMOUS, use the old
// form of the name instead.
@@ -73,6 +76,24 @@
static const bool kDebugMode = true;
#endif
+// Anonymous namespace to avoid name conflicts on "CheckAddressBits".
+namespace {
+
+// Check that no bit is set at position ADDRESS_BITS or higher.
+template <int ADDRESS_BITS> bool CheckAddressBits(uintptr_t ptr) {
+ return (ptr >> ADDRESS_BITS) == 0;
+}
+
+// Specialize for the bit width of a pointer to avoid undefined shift.
+template <> bool CheckAddressBits<8 * sizeof(void*)>(uintptr_t ptr) {
+ return true;
+}
+
+} // Anonymous namespace to avoid name conflicts on "CheckAddressBits".
+
+COMPILE_ASSERT(kAddressBits <= 8 * sizeof(void*),
+ address_bits_larger_than_pointer_size);
+
// Structure for discovering alignment
union MemoryAligner {
void* p;
@@ -87,8 +108,10 @@
static size_t pagesize = 0;
#endif
+// The current system allocator
+SysAllocator* sys_alloc = NULL;
+
// Configuration parameters.
-
DEFINE_int32(malloc_devmem_start,
EnvToInt("TCMALLOC_DEVMEM_START", 0),
"Physical memory starting location in MB for /dev/mem allocation."
@@ -110,7 +133,7 @@
SbrkSysAllocator() : SysAllocator() {
}
void* Alloc(size_t size, size_t *actual_size, size_t alignment);
- void DumpStats(TCMalloc_Printer* printer);
+ void FlagsInitialized() {}
};
static char sbrk_space[sizeof(SbrkSysAllocator)];
@@ -119,7 +142,7 @@
MmapSysAllocator() : SysAllocator() {
}
void* Alloc(size_t size, size_t *actual_size, size_t alignment);
- void DumpStats(TCMalloc_Printer* printer);
+ void FlagsInitialized() {}
};
static char mmap_space[sizeof(MmapSysAllocator)];
@@ -128,30 +151,41 @@
DevMemSysAllocator() : SysAllocator() {
}
void* Alloc(size_t size, size_t *actual_size, size_t alignment);
- void DumpStats(TCMalloc_Printer* printer);
+ void FlagsInitialized() {}
};
-static char devmem_space[sizeof(DevMemSysAllocator)];
-static const int kStaticAllocators = 3;
-// kMaxDynamicAllocators + kStaticAllocators;
-static const int kMaxAllocators = 5;
-static SysAllocator *allocators[kMaxAllocators];
+class DefaultSysAllocator : public SysAllocator {
+ public:
+ DefaultSysAllocator() : SysAllocator() {
+ for (int i = 0; i < kMaxAllocators; i++) {
+ failed_[i] = true;
+ allocs_[i] = NULL;
+ }
+ }
+ void SetChildAllocator(SysAllocator* alloc, unsigned int index,
+ const char* name) {
+ if (index < kMaxAllocators && alloc != NULL) {
+ allocs_[index] = alloc;
+ failed_[index] = false;
+ }
+ }
+ void* Alloc(size_t size, size_t *actual_size, size_t alignment);
+ void FlagsInitialized() {}
-bool RegisterSystemAllocator(SysAllocator *a, int priority) {
- SpinLockHolder lock_holder(&spinlock);
+ private:
+ static const int kMaxAllocators = 2;
+ bool failed_[kMaxAllocators];
+ SysAllocator* allocs_[kMaxAllocators];
+ const char* names_[kMaxAllocators];
+};
+static char default_space[sizeof(DefaultSysAllocator)];
+static const char sbrk_name[] = "SbrkSysAllocator";
+static const char mmap_name[] = "MmapSysAllocator";
- // No two allocators should have a priority conflict, since the order
- // is determined at compile time.
- CHECK_CONDITION(allocators[priority] == NULL);
- allocators[priority] = a;
- return true;
-}
-
void* SbrkSysAllocator::Alloc(size_t size, size_t *actual_size,
size_t alignment) {
#ifndef HAVE_SBRK
- failed_ = true;
return NULL;
#else
// Check if we should use sbrk allocation.
@@ -186,13 +220,11 @@
// http://sourceware.org/cgi-bin/cvsweb.cgi/~checkout~/libc/misc/sbrk.c?rev=1.1.2.1&content-type=text/plain&cvsroot=glibc
// Without this check, sbrk may succeed when it ought to fail.)
if (reinterpret_cast<intptr_t>(sbrk(0)) + size < size) {
- failed_ = true;
return NULL;
}
void* result = sbrk(size);
if (result == reinterpret_cast<void*>(-1)) {
- failed_ = true;
return NULL;
}
@@ -212,7 +244,6 @@
// that we can find an aligned region within it.
result = sbrk(size + alignment - 1);
if (result == reinterpret_cast<void*>(-1)) {
- failed_ = true;
return NULL;
}
ptr = reinterpret_cast<uintptr_t>(result);
@@ -223,14 +254,9 @@
#endif // HAVE_SBRK
}
-void SbrkSysAllocator::DumpStats(TCMalloc_Printer* printer) {
- printer->printf("SbrkSysAllocator: failed_=%d\n", failed_);
-}
-
void* MmapSysAllocator::Alloc(size_t size, size_t *actual_size,
size_t alignment) {
#ifndef HAVE_MMAP
- failed_ = true;
return NULL;
#else
// Check if we should use mmap allocation.
@@ -273,7 +299,6 @@
MAP_PRIVATE|MAP_ANONYMOUS,
-1, 0);
if (result == reinterpret_cast<void*>(MAP_FAILED)) {
- failed_ = true;
return NULL;
}
@@ -297,14 +322,9 @@
#endif // HAVE_MMAP
}
-void MmapSysAllocator::DumpStats(TCMalloc_Printer* printer) {
- printer->printf("MmapSysAllocator: failed_=%d\n", failed_);
-}
-
void* DevMemSysAllocator::Alloc(size_t size, size_t *actual_size,
size_t alignment) {
#ifndef HAVE_MMAP
- failed_ = true;
return NULL;
#else
static bool initialized = false;
@@ -325,7 +345,6 @@
if (!initialized) {
physmem_fd = open("/dev/mem", O_RDWR);
if (physmem_fd < 0) {
- failed_ = true;
return NULL;
}
physmem_base = FLAGS_malloc_devmem_start*1024LL*1024LL;
@@ -357,7 +376,6 @@
// check to see if we have any memory left
if (physmem_limit != 0 &&
((size + extra) > (physmem_limit - physmem_base))) {
- failed_ = true;
return NULL;
}
@@ -368,7 +386,6 @@
void *result = mmap(0, size + extra, PROT_WRITE|PROT_READ,
MAP_SHARED, physmem_fd, physmem_base);
if (result == reinterpret_cast<void*>(MAP_FAILED)) {
- failed_ = true;
return NULL;
}
uintptr_t ptr = reinterpret_cast<uintptr_t>(result);
@@ -394,15 +411,30 @@
#endif // HAVE_MMAP
}
-void DevMemSysAllocator::DumpStats(TCMalloc_Printer* printer) {
- printer->printf("DevMemSysAllocator: failed_=%d\n", failed_);
+void* DefaultSysAllocator::Alloc(size_t size, size_t *actual_size,
+ size_t alignment) {
+ for (int i = 0; i < kMaxAllocators; i++) {
+ if (!failed_[i] && allocs_[i] != NULL) {
+ void* result = allocs_[i]->Alloc(size, actual_size, alignment);
+ if (result != NULL) {
+ return result;
+ }
+ TCMalloc_MESSAGE(__FILE__, __LINE__, "%s failed.\n", names_[i]);
+ failed_[i] = true;
+ }
+ }
+ // After both failed, reset "failed_" to false so that a single failed
+ // allocation won't make the allocator never work again.
+ for (int i = 0; i < kMaxAllocators; i++) {
+ failed_[i] = false;
+ }
+ return NULL;
}
static bool system_alloc_inited = false;
void InitSystemAllocators(void) {
- // This determines the order in which system allocators are called
- int i = kMaxDynamicAllocators;
- allocators[i++] = new (devmem_space) DevMemSysAllocator();
+ MmapSysAllocator *mmap = new (mmap_space) MmapSysAllocator();
+ SbrkSysAllocator *sbrk = new (sbrk_space) SbrkSysAllocator();
// In 64-bit debug mode, place the mmap allocator first since it
// allocates pointers that do not fit in 32 bits and therefore gives
@@ -411,13 +443,15 @@
// likely to look like pointers and therefore the conservative gc in
// the heap-checker is less likely to misinterpret a number as a
// pointer).
+ DefaultSysAllocator *sdef = new (default_space) DefaultSysAllocator();
if (kDebugMode && sizeof(void*) > 4) {
- allocators[i++] = new (mmap_space) MmapSysAllocator();
- allocators[i++] = new (sbrk_space) SbrkSysAllocator();
+ sdef->SetChildAllocator(mmap, 0, mmap_name);
+ sdef->SetChildAllocator(sbrk, 1, sbrk_name);
} else {
- allocators[i++] = new (sbrk_space) SbrkSysAllocator();
- allocators[i++] = new (mmap_space) MmapSysAllocator();
+ sdef->SetChildAllocator(sbrk, 0, sbrk_name);
+ sdef->SetChildAllocator(mmap, 1, mmap_name);
}
+ sys_alloc = sdef;
}
void* TCMalloc_SystemAlloc(size_t size, size_t *actual_size,
@@ -435,26 +469,17 @@
// Enforce minimum alignment
if (alignment < sizeof(MemoryAligner)) alignment = sizeof(MemoryAligner);
- // Try twice, once avoiding allocators that failed before, and once
- // more trying all allocators even if they failed before.
- for (int i = 0; i < 2; i++) {
- for (int j = 0; j < kMaxAllocators; j++) {
- SysAllocator *a = allocators[j];
- if (a == NULL) continue;
- if (a->usable_ && !a->failed_) {
- void* result = a->Alloc(size, actual_size, alignment);
- if (result != NULL) return result;
- }
+ void* result = sys_alloc->Alloc(size, actual_size, alignment);
+ if (result != NULL) {
+ if (actual_size) {
+ CheckAddressBits<kAddressBits>(
+ reinterpret_cast<uintptr_t>(result) + *actual_size - 1);
+ } else {
+ CheckAddressBits<kAddressBits>(
+ reinterpret_cast<uintptr_t>(result) + size - 1);
}
-
- // nothing worked - reset failed_ flags and try again
- for (int j = 0; j < kMaxAllocators; j++) {
- SysAllocator *a = allocators[j];
- if (a == NULL) continue;
- a->failed_ = false;
- }
}
- return NULL;
+ return result;
}
void TCMalloc_SystemRelease(void* start, size_t length) {
@@ -498,13 +523,3 @@
// such that they need to be re-committed before they can be used by the
// application.
}
-
-void DumpSystemAllocatorStats(TCMalloc_Printer* printer) {
- for (int j = 0; j < kMaxAllocators; j++) {
- SysAllocator *a = allocators[j];
- if (a == NULL) continue;
- if (a->usable_) {
- a->DumpStats(printer);
- }
- }
-}

Powered by Google App Engine
This is Rietveld 408576698