1c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Copyright (c) 2009 The Chromium Authors. All rights reserved. 2c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Use of this source code is governed by a BSD-style license that can be 3c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// found in the LICENSE file. 4c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// When possible, we implement allocator functions on top of the basic 6c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// low-level functions malloc() and free(). This way, including a new 7c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// allocator is as simple as providing just a small interface. 8c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// 9c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// As such, this file should not contain any allocator-specific code. 10c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 11c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Implement a C++ style allocation, which always calls the new_handler 12c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// on failure. 13c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottinline void* generic_cpp_alloc(size_t size, bool nothrow) { 14c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void* ptr; 15c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott for (;;) { 16c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ptr = malloc(size); 17c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (ptr) 18c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return ptr; 19c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!call_new_handler(nothrow)) 20c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott break; 21c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 22c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return ptr; 23c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 24c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 25c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottextern "C++" { 26c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 27c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid* __cdecl operator new(size_t size) { 28c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return generic_cpp_alloc(size, false); 29c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 30c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 31c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid operator delete(void* p) __THROW { 32c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott free(p); 33c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 34c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 35c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid* operator new[](size_t size) { 36c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return generic_cpp_alloc(size, false); 37c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 38c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 39c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid operator delete[](void* p) __THROW { 40c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott free(p); 41c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 42c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 43c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid* operator new(size_t size, const std::nothrow_t& nt) __THROW { 44c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return generic_cpp_alloc(size, true); 45c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 46c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 47c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid* operator new[](size_t size, const std::nothrow_t& nt) __THROW { 48c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return generic_cpp_alloc(size, true); 49c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 50c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 51c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// This function behaves similarly to MSVC's _set_new_mode. 52c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// If flag is 0 (default), calls to malloc will behave normally. 53c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// If flag is 1, calls to malloc will behave like calls to new, 54c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// and the std_new_handler will be invoked on failure. 55c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Returns the previous mode. 56c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottint _set_new_mode(int flag) __THROW { 57c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int old_mode = new_mode; 58c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott new_mode = flag; 59c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return old_mode; 60c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 61c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 62c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} // extern "C++" 63c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 64c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottextern "C" { 65c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 66c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid* calloc(size_t n, size_t elem_size) __THROW { 67c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Overflow check 68c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const size_t size = n * elem_size; 69c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (elem_size != 0 && size / elem_size != n) return NULL; 70c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 71c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void* result = malloc(size); 72c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (result != NULL) { 73c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott memset(result, 0, size); 74c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 75c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return result; 76c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 77c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 78c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid cfree(void* p) __THROW { 79c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott free(p); 80c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 81c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 82c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#ifdef WIN32 83c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 84c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid* _recalloc(void* p, size_t n, size_t elem_size) { 85c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!p) 86c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return calloc(n, elem_size); 87c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 88c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // This API is a bit odd. 89c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Note: recalloc only guarantees zeroed memory when p is NULL. 90c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Generally, calls to malloc() have padding. So a request 91c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // to malloc N bytes actually malloc's N+x bytes. Later, if 92c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // that buffer is passed to recalloc, we don't know what N 93c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // was anymore. We only know what N+x is. As such, there is 94c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // no way to know what to zero out. 95c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const size_t size = n * elem_size; 96c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (elem_size != 0 && size / elem_size != n) return NULL; 97c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return realloc(p, size); 98c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 99c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 100c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid* _calloc_impl(size_t n, size_t size) { 101c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return calloc(n, size); 102c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 103c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 104c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#ifndef NDEBUG 105c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#undef malloc 106c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#undef free 107c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#undef calloc 108c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottint _CrtDbgReport(int, const char*, int, const char*, const char*, ...) { 109c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return 0; 110c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 111c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 112c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottint _CrtDbgReportW(int, const wchar_t*, int, const wchar_t*, 113c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const wchar_t*, ...) { 114c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return 0; 115c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 116c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 117c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottint _CrtSetReportMode(int, int) { 118c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return 0; 119c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 120c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 121c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid* _malloc_dbg(size_t size, int , const char*, int) { 122c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return malloc(size); 123c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 124c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 125c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid _free_dbg(void* ptr, int) { 126c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott free(ptr); 127c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 128c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 129c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid* _calloc_dbg(size_t n, size_t size, int, const char*, int) { 130c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return calloc(n, size); 131c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 132c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif // NDEBUG 133c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 134c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif // WIN32 135c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 136c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} // extern C 137c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 138