| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "base/allocator/allocator_shim.h" | 5 #include "base/allocator/allocator_shim.h" |
| 6 | 6 |
| 7 #include <config.h> | 7 #include <config.h> |
| 8 #include "base/allocator/allocator_extension_thunks.h" | 8 #include "base/allocator/allocator_extension_thunks.h" |
| 9 #include "base/profiler/alternate_timer.h" | 9 #include "base/profiler/alternate_timer.h" |
| 10 #include "base/sysinfo.h" | 10 #include "base/sysinfo.h" |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 66 // Forward declarations from jemalloc. | 66 // Forward declarations from jemalloc. |
| 67 extern "C" { | 67 extern "C" { |
| 68 void* je_malloc(size_t s); | 68 void* je_malloc(size_t s); |
| 69 void* je_realloc(void* p, size_t s); | 69 void* je_realloc(void* p, size_t s); |
| 70 void je_free(void* s); | 70 void je_free(void* s); |
| 71 size_t je_msize(void* p); | 71 size_t je_msize(void* p); |
| 72 bool je_malloc_init_hard(); | 72 bool je_malloc_init_hard(); |
| 73 void* je_memalign(size_t a, size_t s); | 73 void* je_memalign(size_t a, size_t s); |
| 74 } | 74 } |
| 75 | 75 |
| 76 extern "C" { | |
| 77 | |
| 78 // Call the new handler, if one has been set. | 76 // Call the new handler, if one has been set. |
| 79 // Returns true on successfully calling the handler, false otherwise. | 77 // Returns true on successfully calling the handler, false otherwise. |
| 80 inline bool call_new_handler(bool nothrow) { | 78 inline bool call_new_handler(bool nothrow) { |
| 81 // Get the current new handler. NB: this function is not | 79 // Get the current new handler. NB: this function is not |
| 82 // thread-safe. We make a feeble stab at making it so here, but | 80 // thread-safe. We make a feeble stab at making it so here, but |
| 83 // this lock only protects against tcmalloc interfering with | 81 // this lock only protects against tcmalloc interfering with |
| 84 // itself, not with other libraries calling set_new_handler. | 82 // itself, not with other libraries calling set_new_handler. |
| 85 std::new_handler nh; | 83 std::new_handler nh; |
| 86 { | 84 { |
| 87 SpinLockHolder h(&set_new_handler_lock); | 85 SpinLockHolder h(&set_new_handler_lock); |
| 88 nh = std::set_new_handler(0); | 86 nh = std::set_new_handler(0); |
| 89 (void) std::set_new_handler(nh); | 87 (void) std::set_new_handler(nh); |
| 90 } | 88 } |
| 91 #if (defined(__GNUC__) && !defined(__EXCEPTIONS)) || (defined(_HAS_EXCEPTIONS) &
& !_HAS_EXCEPTIONS) | 89 #if (defined(__GNUC__) && !defined(__EXCEPTIONS)) || \ |
| 90 (defined(_HAS_EXCEPTIONS) && !_HAS_EXCEPTIONS) |
| 92 if (!nh) | 91 if (!nh) |
| 93 return false; | 92 return false; |
| 94 // Since exceptions are disabled, we don't really know if new_handler | 93 // Since exceptions are disabled, we don't really know if new_handler |
| 95 // failed. Assume it will abort if it fails. | 94 // failed. Assume it will abort if it fails. |
| 96 (*nh)(); | 95 (*nh)(); |
| 97 return false; // break out of the retry loop. | 96 return false; // break out of the retry loop. |
| 98 #else | 97 #else |
| 99 // If no new_handler is established, the allocation failed. | 98 // If no new_handler is established, the allocation failed. |
| 100 if (!nh) { | 99 if (!nh) { |
| 101 if (nothrow) | 100 if (nothrow) |
| 102 return 0; | 101 return false; |
| 103 throw std::bad_alloc(); | 102 throw std::bad_alloc(); |
| 104 } | 103 } |
| 105 // Otherwise, try the new_handler. If it returns, retry the | 104 // Otherwise, try the new_handler. If it returns, retry the |
| 106 // allocation. If it throws std::bad_alloc, fail the allocation. | 105 // allocation. If it throws std::bad_alloc, fail the allocation. |
| 107 // if it throws something else, don't interfere. | 106 // if it throws something else, don't interfere. |
| 108 try { | 107 try { |
| 109 (*nh)(); | 108 (*nh)(); |
| 110 } catch (const std::bad_alloc&) { | 109 } catch (const std::bad_alloc&) { |
| 111 if (!nothrow) | 110 if (!nothrow) |
| 112 throw; | 111 throw; |
| 113 return true; | 112 return true; |
| 114 } | 113 } |
| 115 #endif // (defined(__GNUC__) && !defined(__EXCEPTIONS)) || (defined(_HAS_EXCEPT
IONS) && !_HAS_EXCEPTIONS) | 114 #endif // (defined(__GNUC__) && !defined(__EXCEPTIONS)) || (defined(_HAS_EXCEPT
IONS) && !_HAS_EXCEPTIONS) |
| 115 return false; |
| 116 } | 116 } |
| 117 | 117 |
| 118 extern "C" { |
| 118 void* malloc(size_t size) __THROW { | 119 void* malloc(size_t size) __THROW { |
| 119 void* ptr; | 120 void* ptr; |
| 120 for (;;) { | 121 for (;;) { |
| 121 #ifdef ENABLE_DYNAMIC_ALLOCATOR_SWITCHING | 122 #ifdef ENABLE_DYNAMIC_ALLOCATOR_SWITCHING |
| 122 switch (allocator) { | 123 switch (allocator) { |
| 123 case JEMALLOC: | 124 case JEMALLOC: |
| 124 ptr = je_malloc(size); | 125 ptr = je_malloc(size); |
| 125 break; | 126 break; |
| 126 case WINHEAP: | 127 case WINHEAP: |
| 127 case WINLFH: | 128 case WINLFH: |
| (...skipping 308 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 436 void TCMallocDoFreeForTest(void* ptr) { | 437 void TCMallocDoFreeForTest(void* ptr) { |
| 437 do_free(ptr); | 438 do_free(ptr); |
| 438 } | 439 } |
| 439 | 440 |
| 440 size_t ExcludeSpaceForMarkForTest(size_t size) { | 441 size_t ExcludeSpaceForMarkForTest(size_t size) { |
| 441 return ExcludeSpaceForMark(size); | 442 return ExcludeSpaceForMark(size); |
| 442 } | 443 } |
| 443 | 444 |
| 444 } // namespace allocator. | 445 } // namespace allocator. |
| 445 } // namespace base. | 446 } // namespace base. |
| OLD | NEW |