Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(33)

Side by Side Diff: base/allocator/allocator_shim_win.cc

Issue 774683003: Remove tcmalloc when not being used. Restore shim on Windows. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: fix prep_libc.py and rename allocator_shim.cc Created 5 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #include <malloc.h>
6 #include <new.h>
7 #include <windows.h>
8
9 #include <limits>
10
11 //#include "base/allocator/allocator_extension_thunks.h"
scottmg 2015/01/09 23:32:48 remove these?
cpu_(ooo_6.6-7.5) 2015/01/09 23:46:56 remove commented includes.
Will Harris 2015/01/11 06:30:39 Done.
Will Harris 2015/01/11 06:30:39 Done.
12 #include "base/basictypes.h"
13 //#include "base/profiler/alternate_timer.h"
cpu_(ooo_6.6-7.5) 2015/01/09 23:46:56 ditto
Will Harris 2015/01/11 06:30:39 Done.
14
15 // This shim make it possible to perform additional checks on allocations
16 // before passing them to the Heap functions.
17
18 // new_mode behaves similarly to MSVC's _set_new_mode.
19 // If flag is 0 (default), calls to malloc will behave normally.
20 // If flag is 1, calls to malloc will behave like calls to new,
21 // and the std_new_handler will be invoked on failure.
22 // Can be set by calling _set_new_mode().
23 static int new_mode = 0;
24
25 // This is a simple allocator based on the windows heap.
26 extern "C" {
cpu_(ooo_6.6-7.5) 2015/01/09 23:46:56 I don't think we need extern here, since these guy
Will Harris 2015/01/11 06:30:39 Done.
27
28 const size_t kWindowsPageSize = 4096;
29 size_t kMaxWindowsAllocation =
30 std::numeric_limits<int>::max() - kWindowsPageSize;
scottmg 2015/01/09 23:32:48 less confusing to delete this and leave the initia
Will Harris 2015/01/11 06:30:39 Done.
31 static HANDLE win_heap;
32
33 bool win_heap_init() {
cpu_(ooo_6.6-7.5) 2015/01/09 23:46:56 add comment, along the lines // VS2013 crt uses th
Will Harris 2015/01/11 06:30:39 Done.
34 win_heap = GetProcessHeap();
35 if (win_heap == NULL)
36 return false;
37
38 ULONG enable_lfh = 2;
39 // NOTE: Setting LFH may fail. Vista already has it enabled.
40 // And under the debugger, it won't use LFH. So we
41 // ignore any errors.
42 HeapSetInformation(win_heap, HeapCompatibilityInformation, &enable_lfh,
43 sizeof(enable_lfh));
44
45 // In Debug, _mt_init() performs an allocation before _cinit is called to
46 // initalize C data, so manually initialize kMaxWindowsAllocation here.
47 kMaxWindowsAllocation = std::numeric_limits<int>::max() - kWindowsPageSize;
cpu_(ooo_6.6-7.5) 2015/01/09 23:46:56 I think if define kMaxWindowAllocation without ...
Will Harris 2015/01/11 06:30:39 Done. The allocation limit is the same on both 32
48 return true;
49 }
50
51 void* win_heap_malloc(size_t size) {
52 if (size < kMaxWindowsAllocation)
53 return HeapAlloc(win_heap, 0, size);
54 return NULL;
55 }
56
57 void win_heap_free(void* size) {
58 HeapFree(win_heap, 0, size);
59 }
60
61 void* win_heap_realloc(void* ptr, size_t size) {
62 if (!ptr)
63 return win_heap_malloc(size);
64 if (!size) {
65 win_heap_free(ptr);
66 return NULL;
67 }
68 if (size < kMaxWindowsAllocation)
69 return HeapReAlloc(win_heap, 0, ptr, size);
70 return NULL;
71 }
72
73 size_t win_heap_msize(void* ptr) {
74 return HeapSize(win_heap, 0, ptr);
75 }
76
77 void* win_heap_memalign(size_t alignment, size_t size) {
78 // Reserve enough space to ensure we can align and set aligned_ptr[-1] to the
79 // original allocation for use with win_heap_memalign_free() later.
80 size_t allocation_size = size + (alignment - 1) + sizeof(void*);
81
82 // Check for overflow. Alignment and size are checked in allocator_shim.
83 if (size >= allocation_size || alignment >= allocation_size) {
84 return NULL;
85 }
86
87 // Since we're directly calling the allocator function, before OOM handling,
88 // we need to NULL check to ensure the allocation succeeded.
89 void* ptr = win_heap_malloc(allocation_size);
90 if (!ptr)
91 return ptr;
92
93 char* aligned_ptr = static_cast<char*>(ptr) + sizeof(void*);
94 aligned_ptr +=
95 alignment - reinterpret_cast<uintptr_t>(aligned_ptr) & (alignment - 1);
96
97 reinterpret_cast<void**>(aligned_ptr)[-1] = ptr;
98 return aligned_ptr;
99 }
100
101 void win_heap_memalign_free(void* ptr) {
102 if (ptr)
103 win_heap_free(static_cast<void**>(ptr)[-1]);
104 }
105
106 } // extern "C"
107
108 // Call the new handler, if one has been set.
109 // Returns true on successfully calling the handler, false otherwise.
110 inline bool call_new_handler(bool nothrow, size_t size) {
111 // Get the current new handler.
112 _PNH nh = _query_new_handler();
113 #if (defined(__GNUC__) && !defined(__EXCEPTIONS)) || \
cpu_(ooo_6.6-7.5) 2015/01/09 23:46:56 kill _GNUC_
Will Harris 2015/01/11 06:30:39 Done.
114 (defined(_HAS_EXCEPTIONS) && !_HAS_EXCEPTIONS)
115 if (!nh)
116 return false;
117 // Since exceptions are disabled, we don't really know if new_handler
118 // failed. Assume it will abort if it fails.
119 return nh(size);
120 #else
121 // If no new_handler is established, the allocation failed.
122 if (!nh) {
123 if (nothrow)
124 return false;
125 throw std::bad_alloc();
126 }
127 // Otherwise, try the new_handler. If it returns, retry the
128 // allocation. If it throws std::bad_alloc, fail the allocation.
129 // if it throws something else, don't interfere.
130 try {
131 return nh(size);
132 } catch (const std::bad_alloc&) {
133 if (!nothrow)
134 throw;
135 return true;
136 }
137 #endif // (defined(__GNUC__) && !defined(__EXCEPTIONS)) || (defined(_HAS_EXCEPT IONS) && !_HAS_EXCEPTIONS)
cpu_(ooo_6.6-7.5) 2015/01/09 23:46:56 instead of this monkeing, we should just #error if
138 return false;
139 }
140
141 extern "C" {
142 void* malloc(size_t size) {
143 void* ptr;
144 for (;;) {
145 ptr = win_heap_malloc(size);
146 if (ptr)
147 return ptr;
148
149 if (!new_mode || !call_new_handler(true, size))
150 break;
151 }
152 return ptr;
153 }
154
155 void free(void* p) {
156 win_heap_free(p);
157 return;
158 }
159
160 void* realloc(void* ptr, size_t size) {
161 // Webkit is brittle for allocators that return NULL for malloc(0). The
162 // realloc(0, 0) code path does not guarantee a non-NULL return, so be sure
163 // to call malloc for this case.
164 if (!ptr)
165 return malloc(size);
166
167 void* new_ptr;
168 for (;;) {
169 new_ptr = win_heap_realloc(ptr, size);
170
171 // Subtle warning: NULL return does not alwas indicate out-of-memory. If
172 // the requested new size is zero, realloc should free the ptr and return
173 // NULL.
174 if (new_ptr || !size)
175 return new_ptr;
176 if (!new_mode || !call_new_handler(true, size))
177 break;
178 }
179 return new_ptr;
180 }
181
182 // TODO(mbelshe): Implement this for other allocators.
cpu_(ooo_6.6-7.5) 2015/01/09 23:46:56 I think this can be deleted.
Will Harris 2015/01/11 06:30:39 Done.
183 void malloc_stats(void) {
184 // No stats.
185 return;
186 }
187
188 #ifdef WIN32
scottmg 2015/01/09 23:32:48 remove this #if since we're in a _win.cc.
Will Harris 2015/01/11 06:30:39 Done.
189
190 extern "C" size_t _msize(void* p) {
191 return win_heap_msize(p);
192 }
193
194 extern "C" intptr_t _get_heap_handle() {
195 return reinterpret_cast<intptr_t>(win_heap);
196 }
197
198 static bool get_allocator_waste_size_thunk(size_t* size) {
199 // TODO(alexeif): Implement for allocators other than tcmalloc.
200 return false;
201 }
202
203 // The CRT heap initialization stub.
204 extern "C" int _heap_init() {
205 return win_heap_init() ? 1 : 0;
206 }
207
208 // The CRT heap cleanup stub.
209 extern "C" void _heap_term() {}
210
211 // We set this to 1 because part of the CRT uses a check of _crtheap != 0
212 // to test whether the CRT has been initialized. Once we've ripped out
213 // the allocators from libcmt, we need to provide this definition so that
214 // the rest of the CRT is still usable.
215 extern "C" void* _crtheap = reinterpret_cast<void*>(1);
216
217 // Provide support for aligned memory through Windows only _aligned_malloc().
218 void* _aligned_malloc(size_t size, size_t alignment) {
219 // _aligned_malloc guarantees parameter validation, so do so here. These
220 // checks are somewhat stricter than _aligned_malloc() since we're effectively
221 // using memalign() under the hood.
222 if (size == 0U || (alignment & (alignment - 1)) != 0U ||
223 (alignment % sizeof(void*)) != 0U)
224 return NULL;
225
226 void* ptr;
227 for (;;) {
228 ptr = win_heap_memalign(alignment, size);
229
230 if (ptr) {
231 return ptr;
232 }
233
234 if (!new_mode || !call_new_handler(true, size))
235 break;
236 }
237 return ptr;
238 }
239
240 void _aligned_free(void* p) {
241 // Pointers allocated with win_heap_memalign() MUST be freed via
242 // win_heap_memalign_free() since the aligned pointer is not the real one.
243 win_heap_memalign_free(p);
244 }
245
246 #endif // WIN32
cpu_(ooo_6.6-7.5) 2015/01/09 23:46:56 kill this
Will Harris 2015/01/11 06:30:39 Done.
247
248 #include "generic_allocators.cc"
249
250 } // extern C
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698