| Index: base/allocator/allocator_shim.cc
|
| diff --git a/base/allocator/allocator_shim.cc b/base/allocator/allocator_shim.cc
|
| index af08ec039fd73af7a90a879c6fd54cd88060d883..57a398aaa55e089de33f119912c5ce7d11558de8 100644
|
| --- a/base/allocator/allocator_shim.cc
|
| +++ b/base/allocator/allocator_shim.cc
|
| @@ -5,16 +5,22 @@
|
| #include "base/allocator/allocator_shim.h"
|
|
|
| #include <errno.h>
|
| -#include <unistd.h>
|
|
|
| #include <new>
|
|
|
| #include "base/atomicops.h"
|
| #include "base/logging.h"
|
| #include "base/macros.h"
|
| +#include "base/process/process_metrics.h"
|
| #include "base/threading/platform_thread.h"
|
| #include "build/build_config.h"
|
|
|
| +#if !defined(OS_WIN)
|
| +#include <unistd.h>
|
| +#else
|
| +#include "base/allocator/winheap_stubs_win.h"
|
| +#endif
|
| +
|
| // No calls to malloc / new in this file. They would would cause re-entrancy of
|
| // the shim, which is hard to deal with. Keep this code as simple as possible
|
| // and don't use any external C++ object here, not even //base ones. Even if
|
| @@ -42,16 +48,19 @@ bool CalledOnValidThread() {
|
| return prev_tid == kInvalidTID || prev_tid == cur_tid;
|
| }
|
|
|
| -inline size_t GetPageSize() {
|
| +inline size_t GetCachedPageSize() {
|
| static size_t pagesize = 0;
|
| if (!pagesize)
|
| - pagesize = sysconf(_SC_PAGESIZE);
|
| + pagesize = base::GetPageSize();
|
| return pagesize;
|
| }
|
|
|
| // Calls the std::new handler thread-safely. Returns true if a new_handler was
|
| // set and called, false if no new_handler was set.
|
| -bool CallNewHandler() {
|
| +bool CallNewHandler(size_t size) {
|
| +#if defined(OS_WIN)
|
| + return base::allocator::WinCallNewHandler(size);
|
| +#else
|
| // TODO(primiano): C++11 has introduced ::get_new_handler() which is supposed
|
| // to be thread safe and would avoid the spinlock boilerplate here. However
|
| // it doesn't seem to be available yet in the Linux chroot headers yet.
|
| @@ -69,6 +78,7 @@ bool CallNewHandler() {
|
| // Assume the new_handler will abort if it fails. Exception are disabled and
|
| // we don't support the case of a new_handler throwing std::bad_balloc.
|
| return true;
|
| +#endif
|
| }
|
|
|
| inline const allocator::AllocatorDispatch* GetChainHead() {
|
| @@ -148,7 +158,7 @@ void* ShimCppNew(size_t size) {
|
| void* ptr;
|
| do {
|
| ptr = chain_head->alloc_function(chain_head, size);
|
| - } while (!ptr && CallNewHandler());
|
| + } while (!ptr && CallNewHandler(size));
|
| return ptr;
|
| }
|
|
|
| @@ -162,7 +172,8 @@ void* ShimMalloc(size_t size) {
|
| void* ptr;
|
| do {
|
| ptr = chain_head->alloc_function(chain_head, size);
|
| - } while (!ptr && g_call_new_handler_on_malloc_failure && CallNewHandler());
|
| + } while (!ptr && g_call_new_handler_on_malloc_failure &&
|
| + CallNewHandler(size));
|
| return ptr;
|
| }
|
|
|
| @@ -171,7 +182,8 @@ void* ShimCalloc(size_t n, size_t size) {
|
| void* ptr;
|
| do {
|
| ptr = chain_head->alloc_zero_initialized_function(chain_head, n, size);
|
| - } while (!ptr && g_call_new_handler_on_malloc_failure && CallNewHandler());
|
| + } while (!ptr && g_call_new_handler_on_malloc_failure &&
|
| + CallNewHandler(size));
|
| return ptr;
|
| }
|
|
|
| @@ -183,7 +195,7 @@ void* ShimRealloc(void* address, size_t size) {
|
| do {
|
| ptr = chain_head->realloc_function(chain_head, address, size);
|
| } while (!ptr && size && g_call_new_handler_on_malloc_failure &&
|
| - CallNewHandler());
|
| + CallNewHandler(size));
|
| return ptr;
|
| }
|
|
|
| @@ -192,7 +204,8 @@ void* ShimMemalign(size_t alignment, size_t size) {
|
| void* ptr;
|
| do {
|
| ptr = chain_head->alloc_aligned_function(chain_head, alignment, size);
|
| - } while (!ptr && g_call_new_handler_on_malloc_failure && CallNewHandler());
|
| + } while (!ptr && g_call_new_handler_on_malloc_failure &&
|
| + CallNewHandler(size));
|
| return ptr;
|
| }
|
|
|
| @@ -209,17 +222,17 @@ int ShimPosixMemalign(void** res, size_t alignment, size_t size) {
|
| }
|
|
|
| void* ShimValloc(size_t size) {
|
| - return ShimMemalign(GetPageSize(), size);
|
| + return ShimMemalign(GetCachedPageSize(), size);
|
| }
|
|
|
| void* ShimPvalloc(size_t size) {
|
| // pvalloc(0) should allocate one page, according to its man page.
|
| if (size == 0) {
|
| - size = GetPageSize();
|
| + size = GetCachedPageSize();
|
| } else {
|
| - size = (size + GetPageSize() - 1) & ~(GetPageSize() - 1);
|
| + size = (size + GetCachedPageSize() - 1) & ~(GetCachedPageSize() - 1);
|
| }
|
| - return ShimMemalign(GetPageSize(), size);
|
| + return ShimMemalign(GetCachedPageSize(), size);
|
| }
|
|
|
| void ShimFree(void* address) {
|
| @@ -229,16 +242,22 @@ void ShimFree(void* address) {
|
|
|
| } // extern "C"
|
|
|
| -// Cpp symbols (new / delete) should always be routed through the shim layer.
|
| +#if !defined(OS_WIN)
|
| +// Cpp symbols (new / delete) should always be routed through the shim layer
|
| +// except on Windows where the malloc intercept is deep enough that it also
|
| +// catches the cpp calls.
|
| #include "base/allocator/allocator_shim_override_cpp_symbols.h"
|
| +#endif
|
|
|
| +#if defined(OS_ANDROID)
|
| // Android does not support symbol interposition. The way malloc symbols are
|
| // intercepted on Android is by using link-time -wrap flags.
|
| -#if !defined(OS_ANDROID)
|
| -// Ditto for plain malloc() / calloc() / free() etc. symbols.
|
| -#include "base/allocator/allocator_shim_override_libc_symbols.h"
|
| -#else
|
| #include "base/allocator/allocator_shim_override_linker_wrapped_symbols.h"
|
| +#elif defined(OS_WIN)
|
| +// On Windows we use plain link-time overriding of the CRT symbols.
|
| +#include "base/allocator/allocator_shim_override_ucrt_symbols_win.h"
|
| +#else
|
| +#include "base/allocator/allocator_shim_override_libc_symbols.h"
|
| #endif
|
|
|
| // In the case of tcmalloc we also want to plumb into the glibc hooks
|
|
|