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

Side by Side Diff: Source/wtf/FastMalloc.cpp

Issue 22038002: Get rid of the tryFast*alloc API. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Review item. Created 7 years, 4 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 | Annotate | Revision Log
« no previous file with comments | « Source/wtf/FastMalloc.h ('k') | Source/wtf/PageAllocator.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2005, 2007, Google Inc. 1 // Copyright (c) 2005, 2007, Google Inc.
2 // All rights reserved. 2 // All rights reserved.
3 // Copyright (C) 2005, 2006, 2007, 2008, 2009, 2011 Apple Inc. All rights reserv ed. 3 // Copyright (C) 2005, 2006, 2007, 2008, 2009, 2011 Apple Inc. All rights reserv ed.
4 // 4 //
5 // Redistribution and use in source and binary forms, with or without 5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are 6 // modification, are permitted provided that the following conditions are
7 // met: 7 // met:
8 // 8 //
9 // * Redistributions of source code must retain the above copyright 9 // * Redistributions of source code must retain the above copyright
10 // notice, this list of conditions and the following disclaimer. 10 // notice, this list of conditions and the following disclaimer.
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
85 #if OS(DARWIN) 85 #if OS(DARWIN)
86 #include <AvailabilityMacros.h> 86 #include <AvailabilityMacros.h>
87 #endif 87 #endif
88 88
89 #include <limits> 89 #include <limits>
90 #if OS(WINDOWS) 90 #if OS(WINDOWS)
91 #include <windows.h> 91 #include <windows.h>
92 #else 92 #else
93 #include <pthread.h> 93 #include <pthread.h>
94 #endif 94 #endif
95 #include <stdlib.h>
95 #include <string.h> 96 #include <string.h>
96 97
97 #ifndef NO_TCMALLOC_SAMPLES 98 #ifndef NO_TCMALLOC_SAMPLES
98 #define NO_TCMALLOC_SAMPLES 99 #define NO_TCMALLOC_SAMPLES
99 #endif 100 #endif
100 101
101 #if !USE(SYSTEM_MALLOC) && defined(NDEBUG) 102 #if !USE(SYSTEM_MALLOC) && defined(NDEBUG)
102 #define FORCE_SYSTEM_MALLOC 0 103 #define FORCE_SYSTEM_MALLOC 0
103 #else 104 #else
104 #define FORCE_SYSTEM_MALLOC 1 105 #define FORCE_SYSTEM_MALLOC 1
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
178 pthread_once(&isForbiddenKeyOnce, initializeIsForbiddenKey); 179 pthread_once(&isForbiddenKeyOnce, initializeIsForbiddenKey);
179 pthread_setspecific(isForbiddenKey, 0); 180 pthread_setspecific(isForbiddenKey, 0);
180 } 181 }
181 #endif // OS(WINDOWS) 182 #endif // OS(WINDOWS)
182 183
183 } // namespace WTF 184 } // namespace WTF
184 #endif // NDEBUG 185 #endif // NDEBUG
185 186
186 namespace WTF { 187 namespace WTF {
187 188
188
189 namespace Internal {
190 #if !ENABLE(WTF_MALLOC_VALIDATION)
191 void fastMallocMatchFailed(void*);
192 #else
193 COMPILE_ASSERT(((sizeof(ValidationHeader) % sizeof(AllocAlignmentInteger)) == 0) , ValidationHeader_must_produce_correct_alignment);
194 #endif
195
196 NO_RETURN_DUE_TO_CRASH void fastMallocMatchFailed(void*)
197 {
198 CRASH();
199 }
200
201 } // namespace Internal
202
203
204 void* fastZeroedMalloc(size_t n) 189 void* fastZeroedMalloc(size_t n)
205 { 190 {
206 void* result = fastMalloc(n); 191 void* result = fastMalloc(n);
207 memset(result, 0, n); 192 memset(result, 0, n);
208 return result; 193 return result;
209 } 194 }
210 195
211 char* fastStrDup(const char* src) 196 char* fastStrDup(const char* src)
212 { 197 {
213 size_t len = strlen(src) + 1; 198 size_t len = strlen(src) + 1;
214 char* dup = static_cast<char*>(fastMalloc(len)); 199 char* dup = static_cast<char*>(fastMalloc(len));
215 memcpy(dup, src, len); 200 memcpy(dup, src, len);
216 return dup; 201 return dup;
217 } 202 }
218 203
219 TryMallocReturnValue tryFastZeroedMalloc(size_t n)
220 {
221 void* result;
222 if (!tryFastMalloc(n).getValue(result))
223 return 0;
224 memset(result, 0, n);
225 return result;
226 }
227
228 } // namespace WTF 204 } // namespace WTF
229 205
230 #if FORCE_SYSTEM_MALLOC 206 #if FORCE_SYSTEM_MALLOC
231 207
232 #if OS(DARWIN) 208 #if OS(DARWIN)
233 #include <malloc/malloc.h> 209 #include <malloc/malloc.h>
234 #elif OS(WINDOWS) 210 #elif OS(WINDOWS)
235 #include <malloc.h> 211 #include <malloc.h>
236 #endif 212 #endif
237 213
238 namespace WTF { 214 namespace WTF {
239 215
240 size_t fastMallocGoodSize(size_t bytes) 216 size_t fastMallocGoodSize(size_t bytes)
241 { 217 {
242 #if OS(DARWIN) 218 #if OS(DARWIN)
243 return malloc_good_size(bytes); 219 return malloc_good_size(bytes);
244 #else 220 #else
245 return bytes; 221 return bytes;
246 #endif 222 #endif
247 } 223 }
248 224
249 TryMallocReturnValue tryFastMalloc(size_t n)
250 {
251 ASSERT(!isForbidden());
252
253 #if ENABLE(WTF_MALLOC_VALIDATION)
254 if (std::numeric_limits<size_t>::max() - Internal::ValidationBufferSize <= n ) // If overflow would occur...
255 return 0;
256
257 void* result = malloc(n + Internal::ValidationBufferSize);
258 if (!result)
259 return 0;
260 Internal::ValidationHeader* header = static_cast<Internal::ValidationHeader* >(result);
261 header->m_size = n;
262 header->m_type = Internal::AllocTypeMalloc;
263 header->m_prefix = static_cast<unsigned>(Internal::ValidationPrefix);
264 result = header + 1;
265 *Internal::fastMallocValidationSuffix(result) = Internal::ValidationSuffix;
266 fastMallocValidate(result);
267 return result;
268 #else
269 return malloc(n);
270 #endif
271 }
272
273 void* fastMalloc(size_t n) 225 void* fastMalloc(size_t n)
274 { 226 {
275 ASSERT(!isForbidden()); 227 ASSERT(!isForbidden());
276 228
277 #if ENABLE(WTF_MALLOC_VALIDATION)
278 TryMallocReturnValue returnValue = tryFastMalloc(n);
279 void* result;
280 if (!returnValue.getValue(result))
281 CRASH();
282 #else
283 void* result = malloc(n); 229 void* result = malloc(n);
284 #endif
285
286 ASSERT(result); // We expect tcmalloc underneath, which would crash instead of getting here. 230 ASSERT(result); // We expect tcmalloc underneath, which would crash instead of getting here.
287 231
288 return result; 232 return result;
289 } 233 }
290 234
291 TryMallocReturnValue tryFastCalloc(size_t n_elements, size_t element_size)
292 {
293 ASSERT(!isForbidden());
294
295 #if ENABLE(WTF_MALLOC_VALIDATION)
296 size_t totalBytes = n_elements * element_size;
297 if (n_elements > 1 && element_size && (totalBytes / element_size) != n_eleme nts)
298 return 0;
299
300 TryMallocReturnValue returnValue = tryFastMalloc(totalBytes);
301 void* result;
302 if (!returnValue.getValue(result))
303 return 0;
304 memset(result, 0, totalBytes);
305 fastMallocValidate(result);
306 return result;
307 #else
308 return calloc(n_elements, element_size);
309 #endif
310 }
311
312 void* fastCalloc(size_t n_elements, size_t element_size) 235 void* fastCalloc(size_t n_elements, size_t element_size)
313 { 236 {
314 ASSERT(!isForbidden()); 237 ASSERT(!isForbidden());
315 238
316 #if ENABLE(WTF_MALLOC_VALIDATION)
317 TryMallocReturnValue returnValue = tryFastCalloc(n_elements, element_size);
318 void* result;
319 if (!returnValue.getValue(result))
320 CRASH();
321 #else
322 void* result = calloc(n_elements, element_size); 239 void* result = calloc(n_elements, element_size);
323 #endif
324
325 ASSERT(result); // We expect tcmalloc underneath, which would crash instead of getting here. 240 ASSERT(result); // We expect tcmalloc underneath, which would crash instead of getting here.
326 241
327 return result; 242 return result;
328 } 243 }
329 244
330 void fastFree(void* p) 245 void fastFree(void* p)
331 { 246 {
332 ASSERT(!isForbidden()); 247 ASSERT(!isForbidden());
333 248
334 #if ENABLE(WTF_MALLOC_VALIDATION)
335 if (!p)
336 return;
337
338 fastMallocMatchValidateFree(p, Internal::AllocTypeMalloc);
339 Internal::ValidationHeader* header = Internal::fastMallocValidationHeader(p) ;
340 memset(p, 0xCC, header->m_size);
341 free(header);
342 #else
343 free(p); 249 free(p);
344 #endif
345 }
346
347 TryMallocReturnValue tryFastRealloc(void* p, size_t n)
348 {
349 ASSERT(!isForbidden());
350
351 #if ENABLE(WTF_MALLOC_VALIDATION)
352 if (p) {
353 if (std::numeric_limits<size_t>::max() - Internal::ValidationBufferSize <= n) // If overflow would occur...
354 return 0;
355 fastMallocValidate(p);
356 Internal::ValidationHeader* result = static_cast<Internal::ValidationHea der*>(realloc(Internal::fastMallocValidationHeader(p), n + Internal::ValidationB ufferSize));
357 if (!result)
358 return 0;
359 result->m_size = n;
360 result = result + 1;
361 *fastMallocValidationSuffix(result) = Internal::ValidationSuffix;
362 fastMallocValidate(result);
363 return result;
364 } else {
365 return fastMalloc(n);
366 }
367 #else
368 return realloc(p, n);
369 #endif
370 } 250 }
371 251
372 void* fastRealloc(void* p, size_t n) 252 void* fastRealloc(void* p, size_t n)
373 { 253 {
374 ASSERT(!isForbidden()); 254 ASSERT(!isForbidden());
375 255
376 #if ENABLE(WTF_MALLOC_VALIDATION)
377 TryMallocReturnValue returnValue = tryFastRealloc(p, n);
378 void* result;
379 if (!returnValue.getValue(result))
380 CRASH();
381 #else
382 void* result = realloc(p, n); 256 void* result = realloc(p, n);
383 #endif
384
385 ASSERT(result); // We expect tcmalloc underneath, which would crash instead of getting here. 257 ASSERT(result); // We expect tcmalloc underneath, which would crash instead of getting here.
386 258
387 return result; 259 return result;
388 } 260 }
389 261
390 void releaseFastMallocFreeMemory() { } 262 void releaseFastMallocFreeMemory() { }
391 263
392 FastMallocStatistics fastMallocStatistics() 264 FastMallocStatistics fastMallocStatistics()
393 { 265 {
394 FastMallocStatistics statistics = { 0, 0, 0 }; 266 FastMallocStatistics statistics = { 0, 0, 0 };
(...skipping 12 matching lines...) Expand all
407 279
408 #include "Compiler.h" 280 #include "Compiler.h"
409 #include "TCPackedCache.h" 281 #include "TCPackedCache.h"
410 #include "TCPageMap.h" 282 #include "TCPageMap.h"
411 #include "TCSpinLock.h" 283 #include "TCSpinLock.h"
412 #include "TCSystemAlloc.h" 284 #include "TCSystemAlloc.h"
413 #include <algorithm> 285 #include <algorithm>
414 #include <pthread.h> 286 #include <pthread.h>
415 #include <stdarg.h> 287 #include <stdarg.h>
416 #include <stddef.h> 288 #include <stddef.h>
417 #include <stdint.h>
418 #include <stdio.h> 289 #include <stdio.h>
419 #if HAVE(ERRNO_H) 290 #if HAVE(ERRNO_H)
420 #include <errno.h> 291 #include <errno.h>
421 #endif 292 #endif
422 #if OS(UNIX) 293 #if OS(UNIX)
423 #include <unistd.h> 294 #include <unistd.h>
424 #endif 295 #endif
425 #if OS(WINDOWS) 296 #if OS(WINDOWS)
426 #ifndef WIN32_LEAN_AND_MEAN 297 #ifndef WIN32_LEAN_AND_MEAN
427 #define WIN32_LEAN_AND_MEAN 298 #define WIN32_LEAN_AND_MEAN
428 #endif 299 #endif
429 #include <windows.h> 300 #include <windows.h>
430 #endif 301 #endif
431 302
432 #if OS(DARWIN) 303 #if OS(DARWIN)
433 #include "MallocZoneSupport.h" 304 #include "MallocZoneSupport.h"
434 #include "wtf/HashSet.h" 305 #include "wtf/HashSet.h"
435 #include "wtf/Vector.h" 306 #include "wtf/Vector.h"
307 #else
308 #include "wtf/CurrentTime.h"
436 #endif 309 #endif
437 310
438 #if HAVE(DISPATCH_H) 311 #if HAVE(DISPATCH_H)
439 #include <dispatch/dispatch.h> 312 #include <dispatch/dispatch.h>
440 #endif 313 #endif
441 314
442 #ifdef __has_include 315 #ifdef __has_include
443 #if __has_include(<System/pthread_machdep.h>) 316 #if __has_include(<System/pthread_machdep.h>)
444 317
445 #include <System/pthread_machdep.h> 318 #include <System/pthread_machdep.h>
(...skipping 3037 matching lines...) Expand 10 before | Expand all | Expand 10 after
3483 } 3356 }
3484 3357
3485 static inline void* SpanToMallocResult(Span *span) { 3358 static inline void* SpanToMallocResult(Span *span) {
3486 ASSERT_SPAN_COMMITTED(span); 3359 ASSERT_SPAN_COMMITTED(span);
3487 pageheap->CacheSizeClass(span->start, 0); 3360 pageheap->CacheSizeClass(span->start, 0);
3488 void* result = reinterpret_cast<void*>(span->start << kPageShift); 3361 void* result = reinterpret_cast<void*>(span->start << kPageShift);
3489 POISON_ALLOCATION(result, span->length << kPageShift); 3362 POISON_ALLOCATION(result, span->length << kPageShift);
3490 return CheckedMallocResult(result); 3363 return CheckedMallocResult(result);
3491 } 3364 }
3492 3365
3493 template <bool crashOnFailure>
3494 static ALWAYS_INLINE void* do_malloc(size_t size) { 3366 static ALWAYS_INLINE void* do_malloc(size_t size) {
3495 void* ret = NULL; 3367 void* ret = 0;
3496 3368
3497 ASSERT(!isForbidden()); 3369 ASSERT(!isForbidden());
3498 3370
3499 // The following call forces module initialization 3371 // The following call forces module initialization
3500 TCMalloc_ThreadCache* heap = TCMalloc_ThreadCache::GetCache(); 3372 TCMalloc_ThreadCache* heap = TCMalloc_ThreadCache::GetCache();
3501 if (size > kMaxSize) { 3373 if (size > kMaxSize) {
3502 // Use page-level allocator 3374 // Use page-level allocator
3503 SpinLockHolder h(&pageheap_lock); 3375 SpinLockHolder h(&pageheap_lock);
3504 Span* span = pageheap->New(pages(size)); 3376 Span* span = pageheap->New(pages(size));
3505 if (span != NULL) { 3377 if (span)
3506 ret = SpanToMallocResult(span); 3378 ret = SpanToMallocResult(span);
3379 } else {
3380 // The common case, and also the simplest. This just pops the
3381 // size-appropriate freelist, afer replenishing it if it's empty.
3382 ret = CheckedMallocResult(heap->Allocate(size));
3507 } 3383 }
3508 } else { 3384 if (!ret)
3509 // The common case, and also the simplest. This just pops the
3510 // size-appropriate freelist, afer replenishing it if it's empty.
3511 ret = CheckedMallocResult(heap->Allocate(size));
3512 }
3513 if (!ret) {
3514 if (crashOnFailure) // This branch should be optimized out by the compiler.
3515 CRASH(); 3385 CRASH();
3516 } 3386 return ret;
3517 return ret;
3518 } 3387 }
3519 3388
3520 static ALWAYS_INLINE void do_free(void* ptr) { 3389 static ALWAYS_INLINE void do_free(void* ptr) {
3521 if (ptr == NULL) return; 3390 if (ptr == NULL) return;
3522 ASSERT(pageheap != NULL); // Should not call free() before malloc() 3391 ASSERT(pageheap != NULL); // Should not call free() before malloc()
3523 const PageID p = reinterpret_cast<uintptr_t>(ptr) >> kPageShift; 3392 const PageID p = reinterpret_cast<uintptr_t>(ptr) >> kPageShift;
3524 Span* span = NULL; 3393 Span* span = NULL;
3525 size_t cl = pageheap->GetSizeClassIfCached(p); 3394 size_t cl = pageheap->GetSizeClassIfCached(p);
3526 3395
3527 if (cl == 0) { 3396 if (cl == 0) {
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
3594 3463
3595 //------------------------------------------------------------------- 3464 //-------------------------------------------------------------------
3596 // Exported routines 3465 // Exported routines
3597 //------------------------------------------------------------------- 3466 //-------------------------------------------------------------------
3598 3467
3599 // CAVEAT: The code structure below ensures that MallocHook methods are always 3468 // CAVEAT: The code structure below ensures that MallocHook methods are always
3600 // called from the stack frame of the invoked allocation function. 3469 // called from the stack frame of the invoked allocation function.
3601 // heap-checker.cc depends on this to start a stack trace from 3470 // heap-checker.cc depends on this to start a stack trace from
3602 // the call to the (de)allocation function. 3471 // the call to the (de)allocation function.
3603 3472
3604 #define do_malloc do_malloc<crashOnFailure>
3605
3606 template <bool crashOnFailure>
3607 ALWAYS_INLINE void* malloc(size_t);
3608
3609 void* fastMalloc(size_t size) 3473 void* fastMalloc(size_t size)
3610 { 3474 {
3611 return malloc<true>(size); 3475 return do_malloc(size);
3612 } 3476 }
3613 3477
3614 TryMallocReturnValue tryFastMalloc(size_t size) 3478 void fastFree(void* ptr)
3615 { 3479 {
3616 return malloc<false>(size); 3480 do_free(ptr);
3617 } 3481 }
3618 3482
3619 template <bool crashOnFailure>
3620 ALWAYS_INLINE
3621 void* malloc(size_t size) {
3622 #if ENABLE(WTF_MALLOC_VALIDATION)
3623 if (std::numeric_limits<size_t>::max() - Internal::ValidationBufferSize <= s ize) // If overflow would occur...
3624 return 0;
3625 void* result = do_malloc(size + Internal::ValidationBufferSize);
3626 if (!result)
3627 return 0;
3628
3629 Internal::ValidationHeader* header = static_cast<Internal::ValidationHeader* >(result);
3630 header->m_size = size;
3631 header->m_type = Internal::AllocTypeMalloc;
3632 header->m_prefix = static_cast<unsigned>(Internal::ValidationPrefix);
3633 result = header + 1;
3634 *Internal::fastMallocValidationSuffix(result) = Internal::ValidationSuffix;
3635 fastMallocValidate(result);
3636 #else
3637 void* result = do_malloc(size);
3638 #endif
3639
3640 return result;
3641 }
3642
3643 void free(void* ptr) {
3644 #if ENABLE(WTF_MALLOC_VALIDATION)
3645 if (!ptr)
3646 return;
3647
3648 fastMallocValidate(ptr);
3649 Internal::ValidationHeader* header = Internal::fastMallocValidationHeader(pt r);
3650 memset(ptr, 0xCC, header->m_size);
3651 do_free(header);
3652 #else
3653 do_free(ptr);
3654 #endif
3655 }
3656
3657 template <bool crashOnFailure>
3658 ALWAYS_INLINE void* calloc(size_t, size_t);
3659
3660 void* fastCalloc(size_t n, size_t elem_size) 3483 void* fastCalloc(size_t n, size_t elem_size)
3661 { 3484 {
3662 void* result = calloc<true>(n, elem_size);
3663 #if ENABLE(WTF_MALLOC_VALIDATION)
3664 fastMallocValidate(result);
3665 #endif
3666 return result;
3667 }
3668
3669 TryMallocReturnValue tryFastCalloc(size_t n, size_t elem_size)
3670 {
3671 void* result = calloc<false>(n, elem_size);
3672 #if ENABLE(WTF_MALLOC_VALIDATION)
3673 fastMallocValidate(result);
3674 #endif
3675 return result;
3676 }
3677
3678 template <bool crashOnFailure>
3679 ALWAYS_INLINE
3680 void* calloc(size_t n, size_t elem_size) {
3681 size_t totalBytes = n * elem_size; 3485 size_t totalBytes = n * elem_size;
3682 3486
3683 // Protect against overflow 3487 // Protect against overflow
3684 if (n > 1 && elem_size && (totalBytes / elem_size) != n) 3488 if (n > 1 && elem_size && (totalBytes / elem_size) != n)
3685 return 0; 3489 return 0;
3686 3490
3687 #if ENABLE(WTF_MALLOC_VALIDATION) 3491 void* result = do_malloc(totalBytes);
3688 void* result = malloc<crashOnFailure>(totalBytes);
3689 if (!result)
3690 return 0;
3691
3692 memset(result, 0, totalBytes); 3492 memset(result, 0, totalBytes);
3693 fastMallocValidate(result);
3694 #else
3695 void* result = do_malloc(totalBytes);
3696 if (result != NULL) {
3697 memset(result, 0, totalBytes);
3698 }
3699 #endif
3700 3493
3701 return result; 3494 return result;
3702 } 3495 }
3703 3496
3704 // Since cfree isn't used anywhere, we don't compile it in.
3705 template <bool crashOnFailure>
3706 ALWAYS_INLINE void* realloc(void*, size_t);
3707
3708 void* fastRealloc(void* old_ptr, size_t new_size) 3497 void* fastRealloc(void* old_ptr, size_t new_size)
3709 { 3498 {
3710 #if ENABLE(WTF_MALLOC_VALIDATION)
3711 fastMallocValidate(old_ptr);
3712 #endif
3713 void* result = realloc<true>(old_ptr, new_size);
3714 #if ENABLE(WTF_MALLOC_VALIDATION)
3715 fastMallocValidate(result);
3716 #endif
3717 return result;
3718 }
3719
3720 TryMallocReturnValue tryFastRealloc(void* old_ptr, size_t new_size)
3721 {
3722 #if ENABLE(WTF_MALLOC_VALIDATION)
3723 fastMallocValidate(old_ptr);
3724 #endif
3725 void* result = realloc<false>(old_ptr, new_size);
3726 #if ENABLE(WTF_MALLOC_VALIDATION)
3727 fastMallocValidate(result);
3728 #endif
3729 return result;
3730 }
3731
3732 template <bool crashOnFailure>
3733 ALWAYS_INLINE
3734 void* realloc(void* old_ptr, size_t new_size) {
3735 if (old_ptr == NULL) { 3499 if (old_ptr == NULL) {
3736 #if ENABLE(WTF_MALLOC_VALIDATION) 3500 return do_malloc(new_size);
3737 void* result = malloc<crashOnFailure>(new_size);
3738 #else
3739 void* result = do_malloc(new_size);
3740 #endif
3741 return result;
3742 } 3501 }
3743 if (new_size == 0) { 3502 if (new_size == 0) {
3744 free(old_ptr); 3503 free(old_ptr);
3745 return NULL; 3504 return NULL;
3746 } 3505 }
3747 3506
3748 #if ENABLE(WTF_MALLOC_VALIDATION)
3749 if (std::numeric_limits<size_t>::max() - Internal::ValidationBufferSize <= n ew_size) // If overflow would occur...
3750 return 0;
3751 Internal::ValidationHeader* header = Internal::fastMallocValidationHeader(ol d_ptr);
3752 fastMallocValidate(old_ptr);
3753 old_ptr = header;
3754 header->m_size = new_size;
3755 new_size += Internal::ValidationBufferSize;
3756 #endif
3757
3758 // Get the size of the old entry 3507 // Get the size of the old entry
3759 const PageID p = reinterpret_cast<uintptr_t>(old_ptr) >> kPageShift; 3508 const PageID p = reinterpret_cast<uintptr_t>(old_ptr) >> kPageShift;
3760 size_t cl = pageheap->GetSizeClassIfCached(p); 3509 size_t cl = pageheap->GetSizeClassIfCached(p);
3761 Span *span = NULL; 3510 Span *span = NULL;
3762 size_t old_size; 3511 size_t old_size;
3763 if (cl == 0) { 3512 if (cl == 0) {
3764 span = pageheap->GetDescriptor(p); 3513 span = pageheap->GetDescriptor(p);
3765 cl = span->sizeclass; 3514 cl = span->sizeclass;
3766 pageheap->CacheSizeClass(p, cl); 3515 pageheap->CacheSizeClass(p, cl);
3767 } 3516 }
3768 if (cl != 0) { 3517 if (cl != 0) {
3769 old_size = ByteSizeForClass(cl); 3518 old_size = ByteSizeForClass(cl);
3770 } else { 3519 } else {
3771 ASSERT(span != NULL); 3520 ASSERT(span != NULL);
3772 old_size = span->length << kPageShift; 3521 old_size = span->length << kPageShift;
3773 } 3522 }
3774 3523
3775 // Reallocate if the new size is larger than the old size, 3524 // Reallocate if the new size is larger than the old size,
3776 // or if the new size is significantly smaller than the old size. 3525 // or if the new size is significantly smaller than the old size.
3777 if ((new_size > old_size) || (AllocationSize(new_size) < old_size)) { 3526 if ((new_size > old_size) || (AllocationSize(new_size) < old_size)) {
3778 // Need to reallocate 3527 // Need to reallocate
3779 void* new_ptr = do_malloc(new_size); 3528 void* new_ptr = do_malloc(new_size);
3780 if (new_ptr == NULL) {
3781 return NULL;
3782 }
3783 memcpy(new_ptr, old_ptr, ((old_size < new_size) ? old_size : new_size)); 3529 memcpy(new_ptr, old_ptr, ((old_size < new_size) ? old_size : new_size));
3784 // We could use a variant of do_free() that leverages the fact 3530 // We could use a variant of do_free() that leverages the fact
3785 // that we already know the sizeclass of old_ptr. The benefit 3531 // that we already know the sizeclass of old_ptr. The benefit
3786 // would be small, so don't bother. 3532 // would be small, so don't bother.
3787 do_free(old_ptr); 3533 do_free(old_ptr);
3788 #if ENABLE(WTF_MALLOC_VALIDATION)
3789 new_ptr = static_cast<Internal::ValidationHeader*>(new_ptr) + 1;
3790 *Internal::fastMallocValidationSuffix(new_ptr) = Internal::ValidationSuffix;
3791 #endif
3792 return new_ptr; 3534 return new_ptr;
3793 } else { 3535 } else {
3794 #if ENABLE(WTF_MALLOC_VALIDATION)
3795 old_ptr = static_cast<Internal::ValidationHeader*>(old_ptr) + 1; // Set old_ ptr back to the user pointer.
3796 *Internal::fastMallocValidationSuffix(old_ptr) = Internal::ValidationSuffix;
3797 #endif
3798 return old_ptr; 3536 return old_ptr;
3799 } 3537 }
3800 } 3538 }
3801 3539
3802 #undef do_malloc
3803
3804 void releaseFastMallocFreeMemory() 3540 void releaseFastMallocFreeMemory()
3805 { 3541 {
3806 // Flush free pages in the current thread cache back to the page heap. 3542 // Flush free pages in the current thread cache back to the page heap.
3807 if (TCMalloc_ThreadCache* threadCache = TCMalloc_ThreadCache::GetCacheIfPres ent()) 3543 if (TCMalloc_ThreadCache* threadCache = TCMalloc_ThreadCache::GetCacheIfPres ent())
3808 threadCache->Cleanup(); 3544 threadCache->Cleanup();
3809 3545
3810 SpinLockHolder h(&pageheap_lock); 3546 SpinLockHolder h(&pageheap_lock);
3811 pageheap->ReleaseFreePages(); 3547 pageheap->ReleaseFreePages();
3812 } 3548 }
3813 3549
(...skipping 346 matching lines...) Expand 10 before | Expand all | Expand 10 after
4160 void FastMallocZone::init() 3896 void FastMallocZone::init()
4161 { 3897 {
4162 static FastMallocZone zone(pageheap, &thread_heaps, static_cast<TCMalloc_Cen tral_FreeListPadded*>(central_cache), &span_allocator, &threadheap_allocator); 3898 static FastMallocZone zone(pageheap, &thread_heaps, static_cast<TCMalloc_Cen tral_FreeListPadded*>(central_cache), &span_allocator, &threadheap_allocator);
4163 } 3899 }
4164 3900
4165 #endif // OS(DARWIN) 3901 #endif // OS(DARWIN)
4166 3902
4167 } // namespace WTF 3903 } // namespace WTF
4168 3904
4169 #endif // FORCE_SYSTEM_MALLOC 3905 #endif // FORCE_SYSTEM_MALLOC
OLDNEW
« no previous file with comments | « Source/wtf/FastMalloc.h ('k') | Source/wtf/PageAllocator.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698