Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 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/allocator/allocator_shim.h" | 5 #include "base/allocator/allocator_shim.h" |
| 6 | 6 |
| 7 #include <config.h> | 7 #include <config.h> |
| 8 #include "base/allocator/allocator_extension_thunks.h" | 8 #include "base/allocator/allocator_extension_thunks.h" |
| 9 #include "base/logging.h" | |
| 9 #include "base/profiler/alternate_timer.h" | 10 #include "base/profiler/alternate_timer.h" |
| 10 #include "base/sysinfo.h" | 11 #include "base/sysinfo.h" |
| 11 #include "jemalloc.h" | 12 #include "jemalloc.h" |
| 12 | 13 |
| 13 // When defined, different heap allocators can be used via an environment | 14 // This shim make it possible to use different allocators via an environment |
| 14 // variable set before running the program. This may reduce the amount | 15 // variable set before running the program. This may reduce the |
| 15 // of inlining that we get with malloc/free/etc. Disabling makes it | 16 // amount of inlining that we get with malloc/free/etc. |
| 16 // so that only tcmalloc can be used. | |
| 17 #define ENABLE_DYNAMIC_ALLOCATOR_SWITCHING | |
| 18 | 17 |
| 19 // TODO(mbelshe): Ensure that all calls to tcmalloc have the proper call depth | 18 // TODO(mbelshe): Ensure that all calls to tcmalloc have the proper call depth |
| 20 // from the "user code" so that debugging tools (HeapChecker) can work. | 19 // from the "user code" so that debugging tools (HeapChecker) can work. |
| 21 | 20 |
| 22 // __THROW is defined in glibc systems. It means, counter-intuitively, | 21 // __THROW is defined in glibc systems. It means, counter-intuitively, |
| 23 // "This function will never throw an exception." It's an optional | 22 // "This function will never throw an exception." It's an optional |
| 24 // optimization tool, but we may need to use it to match glibc prototypes. | 23 // optimization tool, but we may need to use it to match glibc prototypes. |
| 25 #ifndef __THROW // I guess we're not on a glibc system | 24 #ifndef __THROW // I guess we're not on a glibc system |
| 26 # define __THROW // __THROW is just an optimization, so ok to make it "" | 25 # define __THROW // __THROW is just an optimization, so ok to make it "" |
| 27 #endif | 26 #endif |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 112 return true; | 111 return true; |
| 113 } | 112 } |
| 114 #endif // (defined(__GNUC__) && !defined(__EXCEPTIONS)) || (defined(_HAS_EXCEPT IONS) && !_HAS_EXCEPTIONS) | 113 #endif // (defined(__GNUC__) && !defined(__EXCEPTIONS)) || (defined(_HAS_EXCEPT IONS) && !_HAS_EXCEPTIONS) |
| 115 return false; | 114 return false; |
| 116 } | 115 } |
| 117 | 116 |
| 118 extern "C" { | 117 extern "C" { |
| 119 void* malloc(size_t size) __THROW { | 118 void* malloc(size_t size) __THROW { |
| 120 void* ptr; | 119 void* ptr; |
| 121 for (;;) { | 120 for (;;) { |
| 122 #ifdef ENABLE_DYNAMIC_ALLOCATOR_SWITCHING | |
| 123 switch (allocator) { | 121 switch (allocator) { |
| 124 case JEMALLOC: | 122 case JEMALLOC: |
| 125 ptr = je_malloc(size); | 123 ptr = je_malloc(size); |
| 126 break; | 124 break; |
| 127 case WINHEAP: | 125 case WINHEAP: |
| 128 case WINLFH: | 126 case WINLFH: |
| 129 ptr = win_heap_malloc(size); | 127 ptr = win_heap_malloc(size); |
| 130 break; | 128 break; |
| 131 case TCMALLOC: | 129 case TCMALLOC: |
| 132 default: | 130 default: |
| 133 ptr = do_malloc(size); | 131 ptr = do_malloc(size); |
| 134 break; | 132 break; |
| 135 } | 133 } |
| 136 #else | |
| 137 // TCMalloc case. | |
| 138 ptr = do_malloc(size); | |
| 139 #endif | |
| 140 if (ptr) | 134 if (ptr) |
| 141 return ptr; | 135 return ptr; |
| 142 | 136 |
| 143 if (!new_mode || !call_new_handler(true)) | 137 if (!new_mode || !call_new_handler(true)) |
| 144 break; | 138 break; |
| 145 } | 139 } |
| 146 return ptr; | 140 return ptr; |
| 147 } | 141 } |
| 148 | 142 |
| 149 void free(void* p) __THROW { | 143 void free(void* p) __THROW { |
| 150 #ifdef ENABLE_DYNAMIC_ALLOCATOR_SWITCHING | |
| 151 switch (allocator) { | 144 switch (allocator) { |
| 152 case JEMALLOC: | 145 case JEMALLOC: |
| 153 je_free(p); | 146 je_free(p); |
| 154 return; | 147 return; |
| 155 case WINHEAP: | 148 case WINHEAP: |
| 156 case WINLFH: | 149 case WINLFH: |
| 157 win_heap_free(p); | 150 win_heap_free(p); |
| 158 return; | 151 return; |
| 152 case TCMALLOC: | |
| 153 do_free(p); | |
| 154 return; | |
| 159 } | 155 } |
| 160 #endif | |
| 161 // TCMalloc case. | |
| 162 do_free(p); | |
| 163 } | 156 } |
| 164 | 157 |
| 165 void* realloc(void* ptr, size_t size) __THROW { | 158 void* realloc(void* ptr, size_t size) __THROW { |
| 166 // Webkit is brittle for allocators that return NULL for malloc(0). The | 159 // Webkit is brittle for allocators that return NULL for malloc(0). The |
| 167 // realloc(0, 0) code path does not guarantee a non-NULL return, so be sure | 160 // realloc(0, 0) code path does not guarantee a non-NULL return, so be sure |
| 168 // to call malloc for this case. | 161 // to call malloc for this case. |
| 169 if (!ptr) | 162 if (!ptr) |
| 170 return malloc(size); | 163 return malloc(size); |
| 171 | 164 |
| 172 void* new_ptr; | 165 void* new_ptr; |
| 173 for (;;) { | 166 for (;;) { |
| 174 #ifdef ENABLE_DYNAMIC_ALLOCATOR_SWITCHING | |
| 175 switch (allocator) { | 167 switch (allocator) { |
| 176 case JEMALLOC: | 168 case JEMALLOC: |
| 177 new_ptr = je_realloc(ptr, size); | 169 new_ptr = je_realloc(ptr, size); |
| 178 break; | 170 break; |
| 179 case WINHEAP: | 171 case WINHEAP: |
| 180 case WINLFH: | 172 case WINLFH: |
| 181 new_ptr = win_heap_realloc(ptr, size); | 173 new_ptr = win_heap_realloc(ptr, size); |
| 182 break; | 174 break; |
| 183 case TCMALLOC: | 175 case TCMALLOC: |
| 184 default: | 176 default: |
| 185 new_ptr = do_realloc(ptr, size); | 177 new_ptr = do_realloc(ptr, size); |
| 186 break; | 178 break; |
| 187 } | 179 } |
| 188 #else | |
| 189 // TCMalloc case. | |
| 190 new_ptr = do_realloc(ptr, size); | |
| 191 #endif | |
| 192 | 180 |
| 193 // Subtle warning: NULL return does not alwas indicate out-of-memory. If | 181 // Subtle warning: NULL return does not alwas indicate out-of-memory. If |
| 194 // the requested new size is zero, realloc should free the ptr and return | 182 // the requested new size is zero, realloc should free the ptr and return |
| 195 // NULL. | 183 // NULL. |
| 196 if (new_ptr || !size) | 184 if (new_ptr || !size) |
| 197 return new_ptr; | 185 return new_ptr; |
| 198 if (!new_mode || !call_new_handler(true)) | 186 if (!new_mode || !call_new_handler(true)) |
| 199 break; | 187 break; |
| 200 } | 188 } |
| 201 return new_ptr; | 189 return new_ptr; |
| 202 } | 190 } |
| 203 | 191 |
| 204 // TODO(mbelshe): Implement this for other allocators. | 192 // TODO(mbelshe): Implement this for other allocators. |
| 205 void malloc_stats(void) __THROW { | 193 void malloc_stats(void) __THROW { |
| 206 #ifdef ENABLE_DYNAMIC_ALLOCATOR_SWITCHING | |
| 207 switch (allocator) { | 194 switch (allocator) { |
| 208 case JEMALLOC: | 195 case JEMALLOC: |
| 209 // No stats. | 196 // No stats. |
| 210 return; | 197 return; |
| 211 case WINHEAP: | 198 case WINHEAP: |
| 212 case WINLFH: | 199 case WINLFH: |
| 213 // No stats. | 200 // No stats. |
| 214 return; | 201 return; |
| 202 case TCMALLOC: | |
| 203 tc_malloc_stats(); | |
| 204 return; | |
| 215 } | 205 } |
| 216 #endif | |
| 217 tc_malloc_stats(); | |
| 218 } | 206 } |
| 219 | 207 |
| 220 #ifdef WIN32 | 208 #ifdef WIN32 |
| 221 | 209 |
| 222 extern "C" size_t _msize(void* p) { | 210 extern "C" size_t _msize(void* p) { |
| 223 #ifdef ENABLE_DYNAMIC_ALLOCATOR_SWITCHING | |
| 224 switch (allocator) { | 211 switch (allocator) { |
| 225 case JEMALLOC: | 212 case JEMALLOC: |
| 226 return je_msize(p); | 213 return je_msize(p); |
| 227 case WINHEAP: | 214 case WINHEAP: |
| 228 case WINLFH: | 215 case WINLFH: |
| 229 return win_heap_msize(p); | 216 return win_heap_msize(p); |
| 217 case TCMALLOC: | |
| 218 return MallocExtension::instance()->GetAllocatedSize(p); | |
| 230 } | 219 } |
| 231 #endif | 220 |
| 232 return MallocExtension::instance()->GetAllocatedSize(p); | 221 NOTREACHED(); |
|
jar (doing other things)
2013/11/07 19:22:37
Although this is a reasonable debug check.... it i
| |
| 222 return 0; | |
| 233 } | 223 } |
| 234 | 224 |
| 235 // This is included to resolve references from libcmt. | 225 // This is included to resolve references from libcmt. |
| 236 extern "C" intptr_t _get_heap_handle() { | 226 extern "C" intptr_t _get_heap_handle() { |
| 237 return 0; | 227 return 0; |
| 238 } | 228 } |
| 239 | 229 |
| 240 static bool get_allocator_waste_size_thunk(size_t* size) { | 230 static bool get_allocator_waste_size_thunk(size_t* size) { |
| 241 #ifdef ENABLE_DYNAMIC_ALLOCATOR_SWITCHING | |
| 242 switch (allocator) { | 231 switch (allocator) { |
| 243 case JEMALLOC: | 232 case JEMALLOC: |
| 244 case WINHEAP: | 233 case WINHEAP: |
| 245 case WINLFH: | 234 case WINLFH: |
| 246 // TODO(alexeif): Implement for allocators other than tcmalloc. | 235 // TODO(alexeif): Implement for allocators other than tcmalloc. |
| 247 return false; | 236 return false; |
| 248 } | 237 } |
| 249 #endif | |
| 250 size_t heap_size, allocated_bytes, unmapped_bytes; | 238 size_t heap_size, allocated_bytes, unmapped_bytes; |
| 251 MallocExtension* ext = MallocExtension::instance(); | 239 MallocExtension* ext = MallocExtension::instance(); |
| 252 if (ext->GetNumericProperty("generic.heap_size", &heap_size) && | 240 if (ext->GetNumericProperty("generic.heap_size", &heap_size) && |
| 253 ext->GetNumericProperty("generic.current_allocated_bytes", | 241 ext->GetNumericProperty("generic.current_allocated_bytes", |
| 254 &allocated_bytes) && | 242 &allocated_bytes) && |
| 255 ext->GetNumericProperty("tcmalloc.pageheap_unmapped_bytes", | 243 ext->GetNumericProperty("tcmalloc.pageheap_unmapped_bytes", |
| 256 &unmapped_bytes)) { | 244 &unmapped_bytes)) { |
| 257 *size = heap_size - allocated_bytes - unmapped_bytes; | 245 *size = heap_size - allocated_bytes - unmapped_bytes; |
| 258 return true; | 246 return true; |
| 259 } | 247 } |
| 260 return false; | 248 return false; |
| 261 } | 249 } |
| 262 | 250 |
| 263 static void get_stats_thunk(char* buffer, int buffer_length) { | 251 static void get_stats_thunk(char* buffer, int buffer_length) { |
| 264 MallocExtension::instance()->GetStats(buffer, buffer_length); | 252 MallocExtension::instance()->GetStats(buffer, buffer_length); |
| 265 } | 253 } |
| 266 | 254 |
| 267 static void release_free_memory_thunk() { | 255 static void release_free_memory_thunk() { |
| 268 MallocExtension::instance()->ReleaseFreeMemory(); | 256 MallocExtension::instance()->ReleaseFreeMemory(); |
| 269 } | 257 } |
| 270 | 258 |
| 271 // The CRT heap initialization stub. | 259 // The CRT heap initialization stub. |
| 272 extern "C" int _heap_init() { | 260 extern "C" int _heap_init() { |
| 273 #ifdef ENABLE_DYNAMIC_ALLOCATOR_SWITCHING | |
| 274 // Don't use the environment variable if ADDRESS_SANITIZER is defined on | 261 // Don't use the environment variable if ADDRESS_SANITIZER is defined on |
| 275 // Windows, as the implementation requires Winheap to be the allocator. | 262 // Windows, as the implementation requires Winheap to be the allocator. |
| 276 #if !(defined(ADDRESS_SANITIZER) && defined(OS_WIN)) | 263 #if !(defined(ADDRESS_SANITIZER) && defined(OS_WIN)) |
| 277 const char* environment_value = GetenvBeforeMain(primary_name); | 264 const char* environment_value = GetenvBeforeMain(primary_name); |
| 278 if (environment_value) { | 265 if (environment_value) { |
| 279 if (!stricmp(environment_value, "jemalloc")) | 266 if (!stricmp(environment_value, "jemalloc")) |
| 280 allocator = JEMALLOC; | 267 allocator = JEMALLOC; |
| 281 else if (!stricmp(environment_value, "winheap")) | 268 else if (!stricmp(environment_value, "winheap")) |
| 282 allocator = WINHEAP; | 269 allocator = WINHEAP; |
| 283 else if (!stricmp(environment_value, "winlfh")) | 270 else if (!stricmp(environment_value, "winlfh")) |
| 284 allocator = WINLFH; | 271 allocator = WINLFH; |
| 285 else if (!stricmp(environment_value, "tcmalloc")) | 272 else if (!stricmp(environment_value, "tcmalloc")) |
| 286 allocator = TCMALLOC; | 273 allocator = TCMALLOC; |
| 287 } | 274 } |
| 288 #endif | 275 #endif |
| 289 | 276 |
| 290 switch (allocator) { | 277 switch (allocator) { |
| 291 case JEMALLOC: | 278 case JEMALLOC: |
| 292 return je_malloc_init_hard() ? 0 : 1; | 279 return je_malloc_init_hard() ? 0 : 1; |
| 293 case WINHEAP: | 280 case WINHEAP: |
| 294 return win_heap_init(false) ? 1 : 0; | 281 return win_heap_init(false) ? 1 : 0; |
| 295 case WINLFH: | 282 case WINLFH: |
| 296 return win_heap_init(true) ? 1 : 0; | 283 return win_heap_init(true) ? 1 : 0; |
| 297 case TCMALLOC: | 284 case TCMALLOC: |
| 298 default: | 285 default: |
| 299 // fall through | 286 // fall through |
| 300 break; | 287 break; |
| 301 } | 288 } |
| 302 #endif | 289 |
| 303 // Initializing tcmalloc. | 290 // Initializing tcmalloc. |
| 304 // We intentionally leak this object. It lasts for the process | 291 // We intentionally leak this object. It lasts for the process |
| 305 // lifetime. Trying to teardown at _heap_term() is so late that | 292 // lifetime. Trying to teardown at _heap_term() is so late that |
| 306 // you can't do anything useful anyway. | 293 // you can't do anything useful anyway. |
| 307 new TCMallocGuard(); | 294 new TCMallocGuard(); |
| 308 | 295 |
| 309 // Provide optional hook for monitoring allocation quantities on a per-thread | 296 // Provide optional hook for monitoring allocation quantities on a per-thread |
| 310 // basis. Only set the hook if the environment indicates this needs to be | 297 // basis. Only set the hook if the environment indicates this needs to be |
| 311 // enabled. | 298 // enabled. |
| 312 const char* profiling = | 299 const char* profiling = |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 339 void* _aligned_malloc(size_t size, size_t alignment) { | 326 void* _aligned_malloc(size_t size, size_t alignment) { |
| 340 // _aligned_malloc guarantees parameter validation, so do so here. These | 327 // _aligned_malloc guarantees parameter validation, so do so here. These |
| 341 // checks are somewhat stricter than _aligned_malloc() since we're effectively | 328 // checks are somewhat stricter than _aligned_malloc() since we're effectively |
| 342 // using memalign() under the hood. | 329 // using memalign() under the hood. |
| 343 DCHECK_GT(size, 0U); | 330 DCHECK_GT(size, 0U); |
| 344 DCHECK_EQ(alignment & (alignment - 1), 0U); | 331 DCHECK_EQ(alignment & (alignment - 1), 0U); |
| 345 DCHECK_EQ(alignment % sizeof(void*), 0U); | 332 DCHECK_EQ(alignment % sizeof(void*), 0U); |
| 346 | 333 |
| 347 void* ptr; | 334 void* ptr; |
| 348 for (;;) { | 335 for (;;) { |
| 349 #ifdef ENABLE_DYNAMIC_ALLOCATOR_SWITCHING | |
| 350 switch (allocator) { | 336 switch (allocator) { |
| 351 case JEMALLOC: | 337 case JEMALLOC: |
| 352 ptr = je_memalign(alignment, size); | 338 ptr = je_memalign(alignment, size); |
| 353 break; | 339 break; |
| 354 case WINHEAP: | 340 case WINHEAP: |
| 355 case WINLFH: | 341 case WINLFH: |
| 356 ptr = win_heap_memalign(alignment, size); | 342 ptr = win_heap_memalign(alignment, size); |
| 357 break; | 343 break; |
| 358 case TCMALLOC: | 344 case TCMALLOC: |
| 359 default: | 345 default: |
| 360 ptr = tc_memalign(alignment, size); | 346 ptr = tc_memalign(alignment, size); |
| 361 break; | 347 break; |
| 362 } | 348 } |
| 363 #else | 349 |
| 364 // TCMalloc case. | |
| 365 ptr = tc_memalign(alignment, size); | |
| 366 #endif | |
| 367 if (ptr) { | 350 if (ptr) { |
| 368 // Sanity check alignment. | 351 // Sanity check alignment. |
| 369 DCHECK_EQ(reinterpret_cast<uintptr_t>(ptr) & (alignment - 1), 0U); | 352 DCHECK_EQ(reinterpret_cast<uintptr_t>(ptr) & (alignment - 1), 0U); |
| 370 return ptr; | 353 return ptr; |
| 371 } | 354 } |
| 372 | 355 |
| 373 if (!new_mode || !call_new_handler(true)) | 356 if (!new_mode || !call_new_handler(true)) |
| 374 break; | 357 break; |
| 375 } | 358 } |
| 376 return ptr; | 359 return ptr; |
| 377 } | 360 } |
| 378 | 361 |
| 379 void _aligned_free(void* p) { | 362 void _aligned_free(void* p) { |
| 380 // Both JEMalloc and TCMalloc return pointers from memalign() that are safe to | 363 // Both JEMalloc and TCMalloc return pointers from memalign() that are safe to |
| 381 // use with free(). Pointers allocated with win_heap_memalign() MUST be freed | 364 // use with free(). Pointers allocated with win_heap_memalign() MUST be freed |
| 382 // via win_heap_memalign_free() since the aligned pointer is not the real one. | 365 // via win_heap_memalign_free() since the aligned pointer is not the real one. |
| 383 #ifdef ENABLE_DYNAMIC_ALLOCATOR_SWITCHING | |
| 384 switch (allocator) { | 366 switch (allocator) { |
| 385 case JEMALLOC: | 367 case JEMALLOC: |
| 386 je_free(p); | 368 je_free(p); |
| 387 return; | 369 return; |
| 388 case WINHEAP: | 370 case WINHEAP: |
| 389 case WINLFH: | 371 case WINLFH: |
| 390 win_heap_memalign_free(p); | 372 win_heap_memalign_free(p); |
| 391 return; | 373 return; |
| 374 case TCMALLOC: | |
| 375 do_free(p); | |
| 392 } | 376 } |
| 393 #endif | |
| 394 // TCMalloc case. | |
| 395 do_free(p); | |
| 396 } | 377 } |
| 397 | 378 |
| 398 #endif // WIN32 | 379 #endif // WIN32 |
| 399 | 380 |
| 400 #include "generic_allocators.cc" | 381 #include "generic_allocators.cc" |
| 401 | 382 |
| 402 } // extern C | 383 } // extern C |
| 403 | 384 |
| 404 namespace base { | 385 namespace base { |
| 405 namespace allocator { | 386 namespace allocator { |
| 406 | 387 |
| 407 void SetupSubprocessAllocator() { | 388 void SetupSubprocessAllocator() { |
| 408 #ifdef ENABLE_DYNAMIC_ALLOCATOR_SWITCHING | |
| 409 size_t primary_length = 0; | 389 size_t primary_length = 0; |
| 410 getenv_s(&primary_length, NULL, 0, primary_name); | 390 getenv_s(&primary_length, NULL, 0, primary_name); |
| 411 | 391 |
| 412 size_t secondary_length = 0; | 392 size_t secondary_length = 0; |
| 413 char buffer[20]; | 393 char buffer[20]; |
| 414 getenv_s(&secondary_length, buffer, sizeof(buffer), secondary_name); | 394 getenv_s(&secondary_length, buffer, sizeof(buffer), secondary_name); |
| 415 DCHECK_GT(sizeof(buffer), secondary_length); | 395 DCHECK_GT(sizeof(buffer), secondary_length); |
| 416 buffer[sizeof(buffer) - 1] = '\0'; | 396 buffer[sizeof(buffer) - 1] = '\0'; |
| 417 | 397 |
| 418 if (secondary_length || !primary_length) { | 398 if (secondary_length || !primary_length) { |
| 419 // Don't use the environment variable if ADDRESS_SANITIZER is defined on | 399 // Don't use the environment variable if ADDRESS_SANITIZER is defined on |
| 420 // Windows, as the implementation require Winheap to be the allocator. | 400 // Windows, as the implementation require Winheap to be the allocator. |
| 421 #if !(defined(ADDRESS_SANITIZER) && defined(OS_WIN)) | 401 #if !(defined(ADDRESS_SANITIZER) && defined(OS_WIN)) |
| 422 const char* secondary_value = secondary_length ? buffer : "TCMALLOC"; | 402 const char* secondary_value = secondary_length ? buffer : "TCMALLOC"; |
| 423 // Force renderer (or other subprocesses) to use secondary_value. | 403 // Force renderer (or other subprocesses) to use secondary_value. |
| 424 #else | 404 #else |
| 425 const char* secondary_value = "WINHEAP"; | 405 const char* secondary_value = "WINHEAP"; |
| 426 #endif | 406 #endif |
| 427 int ret_val = _putenv_s(primary_name, secondary_value); | 407 int ret_val = _putenv_s(primary_name, secondary_value); |
| 428 DCHECK_EQ(0, ret_val); | 408 DCHECK_EQ(0, ret_val); |
| 429 } | 409 } |
| 430 #endif // ENABLE_DYNAMIC_ALLOCATOR_SWITCHING | |
| 431 } | 410 } |
| 432 | 411 |
| 433 void* TCMallocDoMallocForTest(size_t size) { | 412 void* TCMallocDoMallocForTest(size_t size) { |
| 434 return do_malloc(size); | 413 return do_malloc(size); |
| 435 } | 414 } |
| 436 | 415 |
| 437 void TCMallocDoFreeForTest(void* ptr) { | 416 void TCMallocDoFreeForTest(void* ptr) { |
| 438 do_free(ptr); | 417 do_free(ptr); |
| 439 } | 418 } |
| 440 | 419 |
| 441 size_t ExcludeSpaceForMarkForTest(size_t size) { | 420 size_t ExcludeSpaceForMarkForTest(size_t size) { |
| 442 return ExcludeSpaceForMark(size); | 421 return ExcludeSpaceForMark(size); |
| 443 } | 422 } |
| 444 | 423 |
| 445 } // namespace allocator. | 424 } // namespace allocator. |
| 446 } // namespace base. | 425 } // namespace base. |
| OLD | NEW |