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