OLD | NEW |
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 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/process/memory.h" | 5 #include "base/process/memory.h" |
6 | 6 |
7 #include <CoreFoundation/CoreFoundation.h> | 7 #include <CoreFoundation/CoreFoundation.h> |
8 #include <errno.h> | 8 #include <errno.h> |
9 #include <mach/mach.h> | 9 #include <mach/mach.h> |
10 #include <mach/mach_vm.h> | 10 #include <mach/mach_vm.h> |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
124 calloc_type g_old_calloc_purgeable; | 124 calloc_type g_old_calloc_purgeable; |
125 valloc_type g_old_valloc_purgeable; | 125 valloc_type g_old_valloc_purgeable; |
126 free_type g_old_free_purgeable; | 126 free_type g_old_free_purgeable; |
127 realloc_type g_old_realloc_purgeable; | 127 realloc_type g_old_realloc_purgeable; |
128 memalign_type g_old_memalign_purgeable; | 128 memalign_type g_old_memalign_purgeable; |
129 | 129 |
130 void* oom_killer_malloc(struct _malloc_zone_t* zone, | 130 void* oom_killer_malloc(struct _malloc_zone_t* zone, |
131 size_t size) { | 131 size_t size) { |
132 void* result = g_old_malloc(zone, size); | 132 void* result = g_old_malloc(zone, size); |
133 if (!result && size) | 133 if (!result && size) |
134 debug::BreakDebugger(); | 134 TerminateBecauseOutOfMemory(size); |
135 return result; | 135 return result; |
136 } | 136 } |
137 | 137 |
138 void* oom_killer_calloc(struct _malloc_zone_t* zone, | 138 void* oom_killer_calloc(struct _malloc_zone_t* zone, |
139 size_t num_items, | 139 size_t num_items, |
140 size_t size) { | 140 size_t size) { |
141 void* result = g_old_calloc(zone, num_items, size); | 141 void* result = g_old_calloc(zone, num_items, size); |
142 if (!result && num_items && size) | 142 if (!result && num_items && size) |
143 debug::BreakDebugger(); | 143 TerminateBecauseOutOfMemory(num_items * size); |
144 return result; | 144 return result; |
145 } | 145 } |
146 | 146 |
147 void* oom_killer_valloc(struct _malloc_zone_t* zone, | 147 void* oom_killer_valloc(struct _malloc_zone_t* zone, |
148 size_t size) { | 148 size_t size) { |
149 void* result = g_old_valloc(zone, size); | 149 void* result = g_old_valloc(zone, size); |
150 if (!result && size) | 150 if (!result && size) |
151 debug::BreakDebugger(); | 151 TerminateBecauseOutOfMemory(size); |
152 return result; | 152 return result; |
153 } | 153 } |
154 | 154 |
155 void oom_killer_free(struct _malloc_zone_t* zone, | 155 void oom_killer_free(struct _malloc_zone_t* zone, |
156 void* ptr) { | 156 void* ptr) { |
157 g_old_free(zone, ptr); | 157 g_old_free(zone, ptr); |
158 } | 158 } |
159 | 159 |
160 void* oom_killer_realloc(struct _malloc_zone_t* zone, | 160 void* oom_killer_realloc(struct _malloc_zone_t* zone, |
161 void* ptr, | 161 void* ptr, |
162 size_t size) { | 162 size_t size) { |
163 void* result = g_old_realloc(zone, ptr, size); | 163 void* result = g_old_realloc(zone, ptr, size); |
164 if (!result && size) | 164 if (!result && size) |
165 debug::BreakDebugger(); | 165 TerminateBecauseOutOfMemory(size); |
166 return result; | 166 return result; |
167 } | 167 } |
168 | 168 |
169 void* oom_killer_memalign(struct _malloc_zone_t* zone, | 169 void* oom_killer_memalign(struct _malloc_zone_t* zone, |
170 size_t alignment, | 170 size_t alignment, |
171 size_t size) { | 171 size_t size) { |
172 void* result = g_old_memalign(zone, alignment, size); | 172 void* result = g_old_memalign(zone, alignment, size); |
173 // Only die if posix_memalign would have returned ENOMEM, since there are | 173 // Only die if posix_memalign would have returned ENOMEM, since there are |
174 // other reasons why NULL might be returned (see | 174 // other reasons why NULL might be returned (see |
175 // http://opensource.apple.com/source/Libc/Libc-583/gen/malloc.c ). | 175 // http://opensource.apple.com/source/Libc/Libc-583/gen/malloc.c ). |
176 if (!result && size && alignment >= sizeof(void*) && | 176 if (!result && size && alignment >= sizeof(void*) && |
177 (alignment & (alignment - 1)) == 0) { | 177 (alignment & (alignment - 1)) == 0) { |
178 debug::BreakDebugger(); | 178 TerminateBecauseOutOfMemory(size); |
179 } | 179 } |
180 return result; | 180 return result; |
181 } | 181 } |
182 | 182 |
183 void* oom_killer_malloc_purgeable(struct _malloc_zone_t* zone, | 183 void* oom_killer_malloc_purgeable(struct _malloc_zone_t* zone, |
184 size_t size) { | 184 size_t size) { |
185 void* result = g_old_malloc_purgeable(zone, size); | 185 void* result = g_old_malloc_purgeable(zone, size); |
186 if (!result && size) | 186 if (!result && size) |
187 debug::BreakDebugger(); | 187 TerminateBecauseOutOfMemory(size); |
188 return result; | 188 return result; |
189 } | 189 } |
190 | 190 |
191 void* oom_killer_calloc_purgeable(struct _malloc_zone_t* zone, | 191 void* oom_killer_calloc_purgeable(struct _malloc_zone_t* zone, |
192 size_t num_items, | 192 size_t num_items, |
193 size_t size) { | 193 size_t size) { |
194 void* result = g_old_calloc_purgeable(zone, num_items, size); | 194 void* result = g_old_calloc_purgeable(zone, num_items, size); |
195 if (!result && num_items && size) | 195 if (!result && num_items && size) |
196 debug::BreakDebugger(); | 196 TerminateBecauseOutOfMemory(num_items * size); |
197 return result; | 197 return result; |
198 } | 198 } |
199 | 199 |
200 void* oom_killer_valloc_purgeable(struct _malloc_zone_t* zone, | 200 void* oom_killer_valloc_purgeable(struct _malloc_zone_t* zone, |
201 size_t size) { | 201 size_t size) { |
202 void* result = g_old_valloc_purgeable(zone, size); | 202 void* result = g_old_valloc_purgeable(zone, size); |
203 if (!result && size) | 203 if (!result && size) |
204 debug::BreakDebugger(); | 204 TerminateBecauseOutOfMemory(size); |
205 return result; | 205 return result; |
206 } | 206 } |
207 | 207 |
208 void oom_killer_free_purgeable(struct _malloc_zone_t* zone, | 208 void oom_killer_free_purgeable(struct _malloc_zone_t* zone, |
209 void* ptr) { | 209 void* ptr) { |
210 g_old_free_purgeable(zone, ptr); | 210 g_old_free_purgeable(zone, ptr); |
211 } | 211 } |
212 | 212 |
213 void* oom_killer_realloc_purgeable(struct _malloc_zone_t* zone, | 213 void* oom_killer_realloc_purgeable(struct _malloc_zone_t* zone, |
214 void* ptr, | 214 void* ptr, |
215 size_t size) { | 215 size_t size) { |
216 void* result = g_old_realloc_purgeable(zone, ptr, size); | 216 void* result = g_old_realloc_purgeable(zone, ptr, size); |
217 if (!result && size) | 217 if (!result && size) |
218 debug::BreakDebugger(); | 218 TerminateBecauseOutOfMemory(size); |
219 return result; | 219 return result; |
220 } | 220 } |
221 | 221 |
222 void* oom_killer_memalign_purgeable(struct _malloc_zone_t* zone, | 222 void* oom_killer_memalign_purgeable(struct _malloc_zone_t* zone, |
223 size_t alignment, | 223 size_t alignment, |
224 size_t size) { | 224 size_t size) { |
225 void* result = g_old_memalign_purgeable(zone, alignment, size); | 225 void* result = g_old_memalign_purgeable(zone, alignment, size); |
226 // Only die if posix_memalign would have returned ENOMEM, since there are | 226 // Only die if posix_memalign would have returned ENOMEM, since there are |
227 // other reasons why NULL might be returned (see | 227 // other reasons why NULL might be returned (see |
228 // http://opensource.apple.com/source/Libc/Libc-583/gen/malloc.c ). | 228 // http://opensource.apple.com/source/Libc/Libc-583/gen/malloc.c ). |
229 if (!result && size && alignment >= sizeof(void*) | 229 if (!result && size && alignment >= sizeof(void*) |
230 && (alignment & (alignment - 1)) == 0) { | 230 && (alignment & (alignment - 1)) == 0) { |
231 debug::BreakDebugger(); | 231 TerminateBecauseOutOfMemory(size); |
232 } | 232 } |
233 return result; | 233 return result; |
234 } | 234 } |
235 | 235 |
236 #endif // !defined(ADDRESS_SANITIZER) | 236 #endif // !defined(ADDRESS_SANITIZER) |
237 | 237 |
238 // === C++ operator new === | 238 // === C++ operator new === |
239 | 239 |
240 void oom_killer_new() { | 240 void oom_killer_new() { |
241 debug::BreakDebugger(); | 241 TerminateBecauseOutOfMemory(0); |
242 } | 242 } |
243 | 243 |
244 #if !defined(ADDRESS_SANITIZER) | 244 #if !defined(ADDRESS_SANITIZER) |
245 | 245 |
246 // === Core Foundation CFAllocators === | 246 // === Core Foundation CFAllocators === |
247 | 247 |
248 bool CanGetContextForCFAllocator() { | 248 bool CanGetContextForCFAllocator() { |
249 return !base::mac::IsOSLaterThanYosemite_DontCallThis(); | 249 return !base::mac::IsOSLaterThanYosemite_DontCallThis(); |
250 } | 250 } |
251 | 251 |
(...skipping 18 matching lines...) Expand all Loading... |
270 | 270 |
271 CFAllocatorAllocateCallBack g_old_cfallocator_system_default; | 271 CFAllocatorAllocateCallBack g_old_cfallocator_system_default; |
272 CFAllocatorAllocateCallBack g_old_cfallocator_malloc; | 272 CFAllocatorAllocateCallBack g_old_cfallocator_malloc; |
273 CFAllocatorAllocateCallBack g_old_cfallocator_malloc_zone; | 273 CFAllocatorAllocateCallBack g_old_cfallocator_malloc_zone; |
274 | 274 |
275 void* oom_killer_cfallocator_system_default(CFIndex alloc_size, | 275 void* oom_killer_cfallocator_system_default(CFIndex alloc_size, |
276 CFOptionFlags hint, | 276 CFOptionFlags hint, |
277 void* info) { | 277 void* info) { |
278 void* result = g_old_cfallocator_system_default(alloc_size, hint, info); | 278 void* result = g_old_cfallocator_system_default(alloc_size, hint, info); |
279 if (!result) | 279 if (!result) |
280 debug::BreakDebugger(); | 280 TerminateBecauseOutOfMemory(alloc_size); |
281 return result; | 281 return result; |
282 } | 282 } |
283 | 283 |
284 void* oom_killer_cfallocator_malloc(CFIndex alloc_size, | 284 void* oom_killer_cfallocator_malloc(CFIndex alloc_size, |
285 CFOptionFlags hint, | 285 CFOptionFlags hint, |
286 void* info) { | 286 void* info) { |
287 void* result = g_old_cfallocator_malloc(alloc_size, hint, info); | 287 void* result = g_old_cfallocator_malloc(alloc_size, hint, info); |
288 if (!result) | 288 if (!result) |
289 debug::BreakDebugger(); | 289 TerminateBecauseOutOfMemory(alloc_size); |
290 return result; | 290 return result; |
291 } | 291 } |
292 | 292 |
293 void* oom_killer_cfallocator_malloc_zone(CFIndex alloc_size, | 293 void* oom_killer_cfallocator_malloc_zone(CFIndex alloc_size, |
294 CFOptionFlags hint, | 294 CFOptionFlags hint, |
295 void* info) { | 295 void* info) { |
296 void* result = g_old_cfallocator_malloc_zone(alloc_size, hint, info); | 296 void* result = g_old_cfallocator_malloc_zone(alloc_size, hint, info); |
297 if (!result) | 297 if (!result) |
298 debug::BreakDebugger(); | 298 TerminateBecauseOutOfMemory(alloc_size); |
299 return result; | 299 return result; |
300 } | 300 } |
301 | 301 |
302 #endif // !defined(ADDRESS_SANITIZER) | 302 #endif // !defined(ADDRESS_SANITIZER) |
303 | 303 |
304 // === Cocoa NSObject allocation === | 304 // === Cocoa NSObject allocation === |
305 | 305 |
306 typedef id (*allocWithZone_t)(id, SEL, NSZone*); | 306 typedef id (*allocWithZone_t)(id, SEL, NSZone*); |
307 allocWithZone_t g_old_allocWithZone; | 307 allocWithZone_t g_old_allocWithZone; |
308 | 308 |
309 id oom_killer_allocWithZone(id self, SEL _cmd, NSZone* zone) | 309 id oom_killer_allocWithZone(id self, SEL _cmd, NSZone* zone) |
310 { | 310 { |
311 id result = g_old_allocWithZone(self, _cmd, zone); | 311 id result = g_old_allocWithZone(self, _cmd, zone); |
312 if (!result) | 312 if (!result) |
313 debug::BreakDebugger(); | 313 TerminateBecauseOutOfMemory(0); |
314 return result; | 314 return result; |
315 } | 315 } |
316 | 316 |
317 } // namespace | 317 } // namespace |
318 | 318 |
319 bool UncheckedMalloc(size_t size, void** result) { | 319 bool UncheckedMalloc(size_t size, void** result) { |
320 #if defined(ADDRESS_SANITIZER) | 320 #if defined(ADDRESS_SANITIZER) |
321 *result = malloc(size); | 321 *result = malloc(size); |
322 #else | 322 #else |
323 if (g_old_malloc) { | 323 if (g_old_malloc) { |
(...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
552 @selector(allocWithZone:)); | 552 @selector(allocWithZone:)); |
553 g_old_allocWithZone = reinterpret_cast<allocWithZone_t>( | 553 g_old_allocWithZone = reinterpret_cast<allocWithZone_t>( |
554 method_getImplementation(orig_method)); | 554 method_getImplementation(orig_method)); |
555 CHECK(g_old_allocWithZone) | 555 CHECK(g_old_allocWithZone) |
556 << "Failed to get allocWithZone allocation function."; | 556 << "Failed to get allocWithZone allocation function."; |
557 method_setImplementation(orig_method, | 557 method_setImplementation(orig_method, |
558 reinterpret_cast<IMP>(oom_killer_allocWithZone)); | 558 reinterpret_cast<IMP>(oom_killer_allocWithZone)); |
559 } | 559 } |
560 | 560 |
561 } // namespace base | 561 } // namespace base |
OLD | NEW |