| OLD | NEW |
| 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 14 matching lines...) Expand all Loading... |
| 25 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 25 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| 26 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 26 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 27 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 27 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 28 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 28 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 29 | 29 |
| 30 // --- | 30 // --- |
| 31 // Author: Sanjay Ghemawat <opensource@google.com> | 31 // Author: Sanjay Ghemawat <opensource@google.com> |
| 32 | 32 |
| 33 #include <config.h> | 33 #include <config.h> |
| 34 #include <assert.h> | 34 #include <assert.h> |
| 35 #include <stdio.h> | |
| 36 #include <string.h> | 35 #include <string.h> |
| 37 #include <stdio.h> | 36 #include <stdio.h> |
| 38 #if defined HAVE_STDINT_H | 37 #if defined HAVE_STDINT_H |
| 39 #include <stdint.h> | 38 #include <stdint.h> |
| 40 #elif defined HAVE_INTTYPES_H | 39 #elif defined HAVE_INTTYPES_H |
| 41 #include <inttypes.h> | 40 #include <inttypes.h> |
| 42 #else | 41 #else |
| 43 #include <sys/types.h> | 42 #include <sys/types.h> |
| 44 #endif | 43 #endif |
| 45 #include <string> | 44 #include <string> |
| 46 #include "base/dynamic_annotations.h" | 45 #include "base/dynamic_annotations.h" |
| 47 #include "base/sysinfo.h" // for FillProcSelfMaps | 46 #include "base/sysinfo.h" // for FillProcSelfMaps |
| 48 #ifndef NO_HEAP_CHECK | 47 #ifndef NO_HEAP_CHECK |
| 49 #include "google/heap-checker.h" | 48 #include "google/heap-checker.h" |
| 50 #endif | 49 #endif |
| 51 #include "google/malloc_extension.h" | 50 #include "google/malloc_extension.h" |
| 52 #include "maybe_threads.h" | 51 #include "maybe_threads.h" |
| 53 | 52 |
| 54 using STL_NAMESPACE::string; | 53 using STL_NAMESPACE::string; |
| 54 using STL_NAMESPACE::vector; |
| 55 | 55 |
| 56 static void DumpAddressMap(string* result) { | 56 static void DumpAddressMap(string* result) { |
| 57 *result += "\nMAPPED_LIBRARIES:\n"; | 57 *result += "\nMAPPED_LIBRARIES:\n"; |
| 58 // We keep doubling until we get a fit | 58 // We keep doubling until we get a fit |
| 59 const size_t old_resultlen = result->size(); | 59 const size_t old_resultlen = result->size(); |
| 60 for (int amap_size = 10240; amap_size < 10000000; amap_size *= 2) { | 60 for (int amap_size = 10240; amap_size < 10000000; amap_size *= 2) { |
| 61 result->resize(old_resultlen + amap_size); | 61 result->resize(old_resultlen + amap_size); |
| 62 bool wrote_all = false; |
| 62 const int bytes_written = | 63 const int bytes_written = |
| 63 tcmalloc::FillProcSelfMaps(&((*result)[old_resultlen]), amap_size); | 64 tcmalloc::FillProcSelfMaps(&((*result)[old_resultlen]), amap_size, |
| 64 if (bytes_written < amap_size - 1) { // we fit! | 65 &wrote_all); |
| 66 if (wrote_all) { // we fit! |
| 65 (*result)[old_resultlen + bytes_written] = '\0'; | 67 (*result)[old_resultlen + bytes_written] = '\0'; |
| 66 result->resize(old_resultlen + bytes_written); | 68 result->resize(old_resultlen + bytes_written); |
| 67 return; | 69 return; |
| 68 } | 70 } |
| 69 } | 71 } |
| 70 result->reserve(old_resultlen); // just don't print anything | 72 result->reserve(old_resultlen); // just don't print anything |
| 71 } | 73 } |
| 72 | 74 |
| 73 // Note: this routine is meant to be called before threads are spawned. | 75 // Note: this routine is meant to be called before threads are spawned. |
| 74 void MallocExtension::Initialize() { | 76 void MallocExtension::Initialize() { |
| (...skipping 17 matching lines...) Expand all Loading... |
| 92 | 94 |
| 93 // Now we need to make the setenv 'stick', which it may not do since | 95 // Now we need to make the setenv 'stick', which it may not do since |
| 94 // the env is flakey before main() is called. But luckily stl only | 96 // the env is flakey before main() is called. But luckily stl only |
| 95 // looks at this env var the first time it tries to do an alloc, and | 97 // looks at this env var the first time it tries to do an alloc, and |
| 96 // caches what it finds. So we just cause an stl alloc here. | 98 // caches what it finds. So we just cause an stl alloc here. |
| 97 string dummy("I need to be allocated"); | 99 string dummy("I need to be allocated"); |
| 98 dummy += "!"; // so the definition of dummy isn't optimized out | 100 dummy += "!"; // so the definition of dummy isn't optimized out |
| 99 #endif /* __GLIBC__ */ | 101 #endif /* __GLIBC__ */ |
| 100 } | 102 } |
| 101 | 103 |
| 104 // SysAllocator implementation |
| 105 SysAllocator::~SysAllocator() {} |
| 106 |
| 102 // Default implementation -- does nothing | 107 // Default implementation -- does nothing |
| 103 MallocExtension::~MallocExtension() { } | 108 MallocExtension::~MallocExtension() { } |
| 104 bool MallocExtension::VerifyAllMemory() { return true; } | 109 bool MallocExtension::VerifyAllMemory() { return true; } |
| 105 bool MallocExtension::VerifyNewMemory(void* p) { return true; } | 110 bool MallocExtension::VerifyNewMemory(void* p) { return true; } |
| 106 bool MallocExtension::VerifyArrayNewMemory(void* p) { return true; } | 111 bool MallocExtension::VerifyArrayNewMemory(void* p) { return true; } |
| 107 bool MallocExtension::VerifyMallocMemory(void* p) { return true; } | 112 bool MallocExtension::VerifyMallocMemory(void* p) { return true; } |
| 108 | 113 |
| 109 bool MallocExtension::GetNumericProperty(const char* property, size_t* value) { | 114 bool MallocExtension::GetNumericProperty(const char* property, size_t* value) { |
| 110 return false; | 115 return false; |
| 111 } | 116 } |
| (...skipping 24 matching lines...) Expand all Loading... |
| 136 } | 141 } |
| 137 | 142 |
| 138 void MallocExtension::MarkThreadIdle() { | 143 void MallocExtension::MarkThreadIdle() { |
| 139 // Default implementation does nothing | 144 // Default implementation does nothing |
| 140 } | 145 } |
| 141 | 146 |
| 142 void MallocExtension::MarkThreadBusy() { | 147 void MallocExtension::MarkThreadBusy() { |
| 143 // Default implementation does nothing | 148 // Default implementation does nothing |
| 144 } | 149 } |
| 145 | 150 |
| 151 SysAllocator* MallocExtension::GetSystemAllocator() { |
| 152 return NULL; |
| 153 } |
| 154 |
| 155 void MallocExtension::SetSystemAllocator(SysAllocator *a) { |
| 156 // Default implementation does nothing |
| 157 } |
| 158 |
| 146 void MallocExtension::ReleaseToSystem(size_t num_bytes) { | 159 void MallocExtension::ReleaseToSystem(size_t num_bytes) { |
| 147 // Default implementation does nothing | 160 // Default implementation does nothing |
| 148 } | 161 } |
| 149 | 162 |
| 150 void MallocExtension::ReleaseFreeMemory() { | 163 void MallocExtension::ReleaseFreeMemory() { |
| 151 ReleaseToSystem(static_cast<size_t>(-1)); // SIZE_T_MAX | 164 ReleaseToSystem(static_cast<size_t>(-1)); // SIZE_T_MAX |
| 152 } | 165 } |
| 153 | 166 |
| 154 void MallocExtension::SetMemoryReleaseRate(double rate) { | 167 void MallocExtension::SetMemoryReleaseRate(double rate) { |
| 155 // Default implementation does nothing | 168 // Default implementation does nothing |
| 156 } | 169 } |
| 157 | 170 |
| 158 double MallocExtension::GetMemoryReleaseRate() { | 171 double MallocExtension::GetMemoryReleaseRate() { |
| 159 return -1.0; | 172 return -1.0; |
| 160 } | 173 } |
| 161 | 174 |
| 162 size_t MallocExtension::GetEstimatedAllocatedSize(size_t size) { | 175 size_t MallocExtension::GetEstimatedAllocatedSize(size_t size) { |
| 163 return size; | 176 return size; |
| 164 } | 177 } |
| 165 | 178 |
| 166 size_t MallocExtension::GetAllocatedSize(void* p) { | 179 size_t MallocExtension::GetAllocatedSize(void* p) { |
| 167 return 0; | 180 return 0; |
| 168 } | 181 } |
| 169 | 182 |
| 183 void MallocExtension::GetFreeListSizes( |
| 184 vector<MallocExtension::FreeListInfo>* v) { |
| 185 v->clear(); |
| 186 } |
| 187 |
| 170 // The current malloc extension object. | 188 // The current malloc extension object. |
| 171 | 189 |
| 172 static pthread_once_t module_init = PTHREAD_ONCE_INIT; | 190 static pthread_once_t module_init = PTHREAD_ONCE_INIT; |
| 173 static MallocExtension* current_instance = NULL; | 191 static MallocExtension* current_instance = NULL; |
| 174 | 192 |
| 175 static void InitModule() { | 193 static void InitModule() { |
| 176 current_instance = new MallocExtension; | 194 current_instance = new MallocExtension; |
| 177 #ifndef NO_HEAP_CHECK | 195 #ifndef NO_HEAP_CHECK |
| 178 HeapLeakChecker::IgnoreObject(current_instance); | 196 HeapLeakChecker::IgnoreObject(current_instance); |
| 179 #endif | 197 #endif |
| (...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 332 (const char* property, size_t* value), (property, value)); | 350 (const char* property, size_t* value), (property, value)); |
| 333 C_SHIM(SetNumericProperty, int, | 351 C_SHIM(SetNumericProperty, int, |
| 334 (const char* property, size_t value), (property, value)); | 352 (const char* property, size_t value), (property, value)); |
| 335 | 353 |
| 336 C_SHIM(MarkThreadIdle, void, (void), ()); | 354 C_SHIM(MarkThreadIdle, void, (void), ()); |
| 337 C_SHIM(MarkThreadBusy, void, (void), ()); | 355 C_SHIM(MarkThreadBusy, void, (void), ()); |
| 338 C_SHIM(ReleaseFreeMemory, void, (void), ()); | 356 C_SHIM(ReleaseFreeMemory, void, (void), ()); |
| 339 C_SHIM(ReleaseToSystem, void, (size_t num_bytes), (num_bytes)); | 357 C_SHIM(ReleaseToSystem, void, (size_t num_bytes), (num_bytes)); |
| 340 C_SHIM(GetEstimatedAllocatedSize, size_t, (size_t size), (size)); | 358 C_SHIM(GetEstimatedAllocatedSize, size_t, (size_t size), (size)); |
| 341 C_SHIM(GetAllocatedSize, size_t, (void* p), (p)); | 359 C_SHIM(GetAllocatedSize, size_t, (void* p), (p)); |
| OLD | NEW |