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

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

Issue 9667026: Revert 126020 - Experiment for updating the tcmalloc chromium branch to r144 (gperftools 2.0). (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 8 years, 9 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2005, Google Inc. 1 // Copyright (c) 2005, Google Inc.
2 // All rights reserved. 2 // All rights reserved.
3 // 3 //
4 // Redistribution and use in source and binary forms, with or without 4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are 5 // modification, are permitted provided that the following conditions are
6 // met: 6 // met:
7 // 7 //
8 // * Redistributions of source code must retain the above copyright 8 // * Redistributions of source code must retain the above copyright
9 // notice, this list of conditions and the following disclaimer. 9 // notice, this list of conditions and the following disclaimer.
10 // * Redistributions in binary form must reproduce the above 10 // * Redistributions in binary form must reproduce the above
(...skipping 30 matching lines...) Expand all
41 #else 41 #else
42 #include <sys/types.h> 42 #include <sys/types.h>
43 #endif 43 #endif
44 #ifdef HAVE_MMAP 44 #ifdef HAVE_MMAP
45 #include <sys/mman.h> // for munmap, mmap, MADV_DONTNEED, etc 45 #include <sys/mman.h> // for munmap, mmap, MADV_DONTNEED, etc
46 #endif 46 #endif
47 #ifdef HAVE_UNISTD_H 47 #ifdef HAVE_UNISTD_H
48 #include <unistd.h> // for sbrk, getpagesize, off_t 48 #include <unistd.h> // for sbrk, getpagesize, off_t
49 #endif 49 #endif
50 #include <new> // for operator new 50 #include <new> // for operator new
51 #include <gperftools/malloc_extension.h> 51 #include <google/malloc_extension.h>
52 #include "base/basictypes.h" 52 #include "base/basictypes.h"
53 #include "base/commandlineflags.h" 53 #include "base/commandlineflags.h"
54 #include "base/spinlock.h" // for SpinLockHolder, SpinLock, etc 54 #include "base/spinlock.h" // for SpinLockHolder, SpinLock, etc
55 #include "common.h" 55 #include "common.h"
56 #include "internal_logging.h" 56 #include "internal_logging.h"
57 57
58 // On systems (like freebsd) that don't define MAP_ANONYMOUS, use the old 58 // On systems (like freebsd) that don't define MAP_ANONYMOUS, use the old
59 // form of the name instead. 59 // form of the name instead.
60 #ifndef MAP_ANONYMOUS 60 #ifndef MAP_ANONYMOUS
61 # define MAP_ANONYMOUS MAP_ANON 61 # define MAP_ANONYMOUS MAP_ANON
62 #endif 62 #endif
63 63
64 // MADV_FREE is specifically designed for use by malloc(), but only
65 // FreeBSD supports it; in linux we fall back to the somewhat inferior
66 // MADV_DONTNEED.
67 #if !defined(MADV_FREE) && defined(MADV_DONTNEED)
68 # define MADV_FREE MADV_DONTNEED
69 #endif
70
71 // Solaris has a bug where it doesn't declare madvise() for C++. 64 // Solaris has a bug where it doesn't declare madvise() for C++.
72 // http://www.opensolaris.org/jive/thread.jspa?threadID=21035&tstart=0 65 // http://www.opensolaris.org/jive/thread.jspa?threadID=21035&tstart=0
73 #if defined(__sun) && defined(__SVR4) 66 #if defined(__sun) && defined(__SVR4)
74 # include <sys/types.h> // for caddr_t 67 # include <sys/types.h> // for caddr_t
75 extern "C" { extern int madvise(caddr_t, size_t, int); } 68 extern "C" { extern int madvise(caddr_t, size_t, int); }
76 #endif 69 #endif
77 70
78 // Set kDebugMode mode so that we can have use C++ conditionals 71 // Set kDebugMode mode so that we can have use C++ conditionals
79 // instead of preprocessor conditionals. 72 // instead of preprocessor conditionals.
80 #ifdef NDEBUG 73 #ifdef NDEBUG
81 static const bool kDebugMode = false; 74 static const bool kDebugMode = false;
82 #else 75 #else
83 static const bool kDebugMode = true; 76 static const bool kDebugMode = true;
84 #endif 77 #endif
85 78
86 // TODO(sanjay): Move the code below into the tcmalloc namespace
87 using tcmalloc::kLog;
88 using tcmalloc::Log;
89
90 // Anonymous namespace to avoid name conflicts on "CheckAddressBits". 79 // Anonymous namespace to avoid name conflicts on "CheckAddressBits".
91 namespace { 80 namespace {
92 81
93 // Check that no bit is set at position ADDRESS_BITS or higher. 82 // Check that no bit is set at position ADDRESS_BITS or higher.
94 template <int ADDRESS_BITS> bool CheckAddressBits(uintptr_t ptr) { 83 template <int ADDRESS_BITS> bool CheckAddressBits(uintptr_t ptr) {
95 return (ptr >> ADDRESS_BITS) == 0; 84 return (ptr >> ADDRESS_BITS) == 0;
96 } 85 }
97 86
98 // Specialize for the bit width of a pointer to avoid undefined shift. 87 // Specialize for the bit width of a pointer to avoid undefined shift.
99 template <> bool CheckAddressBits<8 * sizeof(void*)>(uintptr_t ptr) { 88 template <> bool CheckAddressBits<8 * sizeof(void*)>(uintptr_t ptr) {
100 return true; 89 return true;
101 } 90 }
102 91
103 } // Anonymous namespace to avoid name conflicts on "CheckAddressBits". 92 } // Anonymous namespace to avoid name conflicts on "CheckAddressBits".
104 93
105 COMPILE_ASSERT(kAddressBits <= 8 * sizeof(void*), 94 COMPILE_ASSERT(kAddressBits <= 8 * sizeof(void*),
106 address_bits_larger_than_pointer_size); 95 address_bits_larger_than_pointer_size);
107 96
108 // Structure for discovering alignment 97 // Structure for discovering alignment
109 union MemoryAligner { 98 union MemoryAligner {
110 void* p; 99 void* p;
111 double d; 100 double d;
112 size_t s; 101 size_t s;
113 } CACHELINE_ALIGNED; 102 } CACHELINE_ALIGNED;
114 103
115 static SpinLock spinlock(SpinLock::LINKER_INITIALIZED); 104 static SpinLock spinlock(SpinLock::LINKER_INITIALIZED);
116 105
117 #if defined(HAVE_MMAP) || defined(MADV_FREE)
118 #ifdef HAVE_GETPAGESIZE 106 #ifdef HAVE_GETPAGESIZE
119 static size_t pagesize = 0; 107 static size_t pagesize = 0;
120 #endif 108 #endif
121 #endif
122 109
123 // The current system allocator 110 // The current system allocator
124 SysAllocator* sys_alloc = NULL; 111 SysAllocator* sys_alloc = NULL;
125 112
126 // Configuration parameters. 113 // Configuration parameters.
127 DEFINE_int32(malloc_devmem_start, 114 DEFINE_int32(malloc_devmem_start,
128 EnvToInt("TCMALLOC_DEVMEM_START", 0), 115 EnvToInt("TCMALLOC_DEVMEM_START", 0),
129 "Physical memory starting location in MB for /dev/mem allocation." 116 "Physical memory starting location in MB for /dev/mem allocation."
130 " Setting this to 0 disables /dev/mem allocation"); 117 " Setting this to 0 disables /dev/mem allocation");
131 DEFINE_int32(malloc_devmem_limit, 118 DEFINE_int32(malloc_devmem_limit,
132 EnvToInt("TCMALLOC_DEVMEM_LIMIT", 0), 119 EnvToInt("TCMALLOC_DEVMEM_LIMIT", 0),
133 "Physical memory limit location in MB for /dev/mem allocation." 120 "Physical memory limit location in MB for /dev/mem allocation."
134 " Setting this to 0 means no limit."); 121 " Setting this to 0 means no limit.");
135 DEFINE_bool(malloc_skip_sbrk, 122 DEFINE_bool(malloc_skip_sbrk,
136 EnvToBool("TCMALLOC_SKIP_SBRK", false), 123 EnvToBool("TCMALLOC_SKIP_SBRK", false),
137 "Whether sbrk can be used to obtain memory."); 124 "Whether sbrk can be used to obtain memory.");
138 DEFINE_bool(malloc_skip_mmap, 125 DEFINE_bool(malloc_skip_mmap,
139 EnvToBool("TCMALLOC_SKIP_MMAP", false), 126 EnvToBool("TCMALLOC_SKIP_MMAP", false),
140 "Whether mmap can be used to obtain memory."); 127 "Whether mmap can be used to obtain memory.");
141 128
142 // static allocators 129 // static allocators
143 class SbrkSysAllocator : public SysAllocator { 130 class SbrkSysAllocator : public SysAllocator {
144 public: 131 public:
145 SbrkSysAllocator() : SysAllocator() { 132 SbrkSysAllocator() : SysAllocator() {
146 } 133 }
147 void* Alloc(size_t size, size_t *actual_size, size_t alignment); 134 void* Alloc(size_t size, size_t *actual_size, size_t alignment);
135 void FlagsInitialized() {}
148 }; 136 };
149 static char sbrk_space[sizeof(SbrkSysAllocator)]; 137 static char sbrk_space[sizeof(SbrkSysAllocator)];
150 138
151 class MmapSysAllocator : public SysAllocator { 139 class MmapSysAllocator : public SysAllocator {
152 public: 140 public:
153 MmapSysAllocator() : SysAllocator() { 141 MmapSysAllocator() : SysAllocator() {
154 } 142 }
155 void* Alloc(size_t size, size_t *actual_size, size_t alignment); 143 void* Alloc(size_t size, size_t *actual_size, size_t alignment);
144 void FlagsInitialized() {}
156 }; 145 };
157 static char mmap_space[sizeof(MmapSysAllocator)]; 146 static char mmap_space[sizeof(MmapSysAllocator)];
158 147
159 class DevMemSysAllocator : public SysAllocator { 148 class DevMemSysAllocator : public SysAllocator {
160 public: 149 public:
161 DevMemSysAllocator() : SysAllocator() { 150 DevMemSysAllocator() : SysAllocator() {
162 } 151 }
163 void* Alloc(size_t size, size_t *actual_size, size_t alignment); 152 void* Alloc(size_t size, size_t *actual_size, size_t alignment);
153 void FlagsInitialized() {}
164 }; 154 };
165 155
166 class DefaultSysAllocator : public SysAllocator { 156 class DefaultSysAllocator : public SysAllocator {
167 public: 157 public:
168 DefaultSysAllocator() : SysAllocator() { 158 DefaultSysAllocator() : SysAllocator() {
169 for (int i = 0; i < kMaxAllocators; i++) { 159 for (int i = 0; i < kMaxAllocators; i++) {
170 failed_[i] = true; 160 failed_[i] = true;
171 allocs_[i] = NULL; 161 allocs_[i] = NULL;
172 names_[i] = NULL; 162 names_[i] = NULL;
173 } 163 }
174 } 164 }
175 void SetChildAllocator(SysAllocator* alloc, unsigned int index, 165 void SetChildAllocator(SysAllocator* alloc, unsigned int index,
176 const char* name) { 166 const char* name) {
177 if (index < kMaxAllocators && alloc != NULL) { 167 if (index < kMaxAllocators && alloc != NULL) {
178 allocs_[index] = alloc; 168 allocs_[index] = alloc;
179 failed_[index] = false; 169 failed_[index] = false;
180 names_[index] = name; 170 names_[index] = name;
181 } 171 }
182 } 172 }
183 void* Alloc(size_t size, size_t *actual_size, size_t alignment); 173 void* Alloc(size_t size, size_t *actual_size, size_t alignment);
174 void FlagsInitialized() {}
184 175
185 private: 176 private:
186 static const int kMaxAllocators = 2; 177 static const int kMaxAllocators = 2;
187 bool failed_[kMaxAllocators]; 178 bool failed_[kMaxAllocators];
188 SysAllocator* allocs_[kMaxAllocators]; 179 SysAllocator* allocs_[kMaxAllocators];
189 const char* names_[kMaxAllocators]; 180 const char* names_[kMaxAllocators];
190 }; 181 };
191 static char default_space[sizeof(DefaultSysAllocator)]; 182 static char default_space[sizeof(DefaultSysAllocator)];
192 static const char sbrk_name[] = "SbrkSysAllocator"; 183 static const char sbrk_name[] = "SbrkSysAllocator";
193 static const char mmap_name[] = "MmapSysAllocator"; 184 static const char mmap_name[] = "MmapSysAllocator";
(...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after
422 } 413 }
423 414
424 void* DefaultSysAllocator::Alloc(size_t size, size_t *actual_size, 415 void* DefaultSysAllocator::Alloc(size_t size, size_t *actual_size,
425 size_t alignment) { 416 size_t alignment) {
426 for (int i = 0; i < kMaxAllocators; i++) { 417 for (int i = 0; i < kMaxAllocators; i++) {
427 if (!failed_[i] && allocs_[i] != NULL) { 418 if (!failed_[i] && allocs_[i] != NULL) {
428 void* result = allocs_[i]->Alloc(size, actual_size, alignment); 419 void* result = allocs_[i]->Alloc(size, actual_size, alignment);
429 if (result != NULL) { 420 if (result != NULL) {
430 return result; 421 return result;
431 } 422 }
423 TCMalloc_MESSAGE(__FILE__, __LINE__, "%s failed.\n", names_[i]);
432 failed_[i] = true; 424 failed_[i] = true;
433 } 425 }
434 } 426 }
435 // After both failed, reset "failed_" to false so that a single failed 427 // After both failed, reset "failed_" to false so that a single failed
436 // allocation won't make the allocator never work again. 428 // allocation won't make the allocator never work again.
437 for (int i = 0; i < kMaxAllocators; i++) { 429 for (int i = 0; i < kMaxAllocators; i++) {
438 failed_[i] = false; 430 failed_[i] = false;
439 } 431 }
440 return NULL; 432 return NULL;
441 } 433 }
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
500 return 0; 492 return 0;
501 493
502 if (!mprotect(start, pagesize, PROT_NONE)) 494 if (!mprotect(start, pagesize, PROT_NONE))
503 return pagesize; 495 return pagesize;
504 #endif 496 #endif
505 497
506 return 0; 498 return 0;
507 } 499 }
508 500
509 void TCMalloc_SystemRelease(void* start, size_t length) { 501 void TCMalloc_SystemRelease(void* start, size_t length) {
510 #ifdef MADV_FREE 502 #ifdef MADV_DONTNEED
511 if (FLAGS_malloc_devmem_start) { 503 if (FLAGS_malloc_devmem_start) {
512 // It's not safe to use MADV_FREE/MADV_DONTNEED if we've been 504 // It's not safe to use MADV_DONTNEED if we've been mapping
513 // mapping /dev/mem for heap memory. 505 // /dev/mem for heap memory
514 return; 506 return;
515 } 507 }
516 if (pagesize == 0) pagesize = getpagesize(); 508 if (pagesize == 0) pagesize = getpagesize();
517 const size_t pagemask = pagesize - 1; 509 const size_t pagemask = pagesize - 1;
518 510
519 size_t new_start = reinterpret_cast<size_t>(start); 511 size_t new_start = reinterpret_cast<size_t>(start);
520 size_t end = new_start + length; 512 size_t end = new_start + length;
521 size_t new_end = end; 513 size_t new_end = end;
522 514
523 // Round up the starting address and round down the ending address 515 // Round up the starting address and round down the ending address
524 // to be page aligned: 516 // to be page aligned:
525 new_start = (new_start + pagesize - 1) & ~pagemask; 517 new_start = (new_start + pagesize - 1) & ~pagemask;
526 new_end = new_end & ~pagemask; 518 new_end = new_end & ~pagemask;
527 519
528 ASSERT((new_start & pagemask) == 0); 520 ASSERT((new_start & pagemask) == 0);
529 ASSERT((new_end & pagemask) == 0); 521 ASSERT((new_end & pagemask) == 0);
530 ASSERT(new_start >= reinterpret_cast<size_t>(start)); 522 ASSERT(new_start >= reinterpret_cast<size_t>(start));
531 ASSERT(new_end <= end); 523 ASSERT(new_end <= end);
532 524
533 if (new_end > new_start) { 525 if (new_end > new_start) {
534 // Note -- ignoring most return codes, because if this fails it 526 // Note -- ignoring most return codes, because if this fails it
535 // doesn't matter... 527 // doesn't matter...
536 while (madvise(reinterpret_cast<char*>(new_start), new_end - new_start, 528 while (madvise(reinterpret_cast<char*>(new_start), new_end - new_start,
537 MADV_FREE) == -1 && 529 MADV_DONTNEED) == -1 &&
538 errno == EAGAIN) { 530 errno == EAGAIN) {
539 // NOP 531 // NOP
540 } 532 }
541 } 533 }
542 #endif 534 #endif
543 } 535 }
544 536
545 void TCMalloc_SystemCommit(void* start, size_t length) { 537 void TCMalloc_SystemCommit(void* start, size_t length) {
546 // Nothing to do here. TCMalloc_SystemRelease does not alter pages 538 // Nothing to do here. TCMalloc_SystemRelease does not alter pages
547 // such that they need to be re-committed before they can be used by the 539 // such that they need to be re-committed before they can be used by the
548 // application. 540 // application.
549 } 541 }
OLDNEW
« no previous file with comments | « third_party/tcmalloc/chromium/src/symbolize.cc ('k') | third_party/tcmalloc/chromium/src/tcmalloc.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698