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

Side by Side Diff: third_party/WebKit/Source/wtf/PartitionAlloc.h

Issue 1391933004: [Tracing] Add hook to PartitionAlloc for heap profiling (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Address review comments Created 5 years, 2 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
1 /* 1 /*
2 * Copyright (C) 2013 Google Inc. All rights reserved. 2 * Copyright (C) 2013 Google Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are 5 * modification, are permitted provided that the following conditions are
6 * met: 6 * met:
7 * 7 *
8 * * Redistributions of source code must retain the above copyright 8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above 10 * * Redistributions in binary form must reproduce the above
(...skipping 393 matching lines...) Expand 10 before | Expand all | Expand 10 after
404 WTF_EXPORT void partitionPurgeMemory(PartitionRoot*, int); 404 WTF_EXPORT void partitionPurgeMemory(PartitionRoot*, int);
405 WTF_EXPORT void partitionPurgeMemoryGeneric(PartitionRootGeneric*, int); 405 WTF_EXPORT void partitionPurgeMemoryGeneric(PartitionRootGeneric*, int);
406 406
407 WTF_EXPORT NEVER_INLINE void* partitionAllocSlowPath(PartitionRootBase*, int, si ze_t, PartitionBucket*); 407 WTF_EXPORT NEVER_INLINE void* partitionAllocSlowPath(PartitionRootBase*, int, si ze_t, PartitionBucket*);
408 WTF_EXPORT NEVER_INLINE void partitionFreeSlowPath(PartitionPage*); 408 WTF_EXPORT NEVER_INLINE void partitionFreeSlowPath(PartitionPage*);
409 WTF_EXPORT NEVER_INLINE void* partitionReallocGeneric(PartitionRootGeneric*, voi d*, size_t); 409 WTF_EXPORT NEVER_INLINE void* partitionReallocGeneric(PartitionRootGeneric*, voi d*, size_t);
410 410
411 WTF_EXPORT void partitionDumpStats(PartitionRoot*, const char* partitionName, bo ol isLightDump, PartitionStatsDumper*); 411 WTF_EXPORT void partitionDumpStats(PartitionRoot*, const char* partitionName, bo ol isLightDump, PartitionStatsDumper*);
412 WTF_EXPORT void partitionDumpStatsGeneric(PartitionRootGeneric*, const char* par titionName, bool isLightDump, PartitionStatsDumper*); 412 WTF_EXPORT void partitionDumpStatsGeneric(PartitionRootGeneric*, const char* par titionName, bool isLightDump, PartitionStatsDumper*);
413 413
414 class WTF_EXPORT PartitionAllocHooks {
415 public:
416 typedef void AllocationHook(void* address, size_t);
417 typedef void FreeHook(void* address);
haraken 2015/10/20 12:42:00 typedef => using
Ruud van Asseldonk 2015/10/20 13:22:16 Curiously, a using causes compile errors on MSVC b
418
419 static void setAllocationHook(AllocationHook* hook) { m_allocationHook = hoo k; }
420 static void setFreeHook(FreeHook* hook) { m_freeHook = hook; }
421
422 static void allocationHookIfEnabled(void* address, size_t size)
423 {
424 AllocationHook* allocationHook = m_allocationHook;
425 if (UNLIKELY(allocationHook != nullptr))
426 allocationHook(address, size);
427 }
428
429 static void freeHookIfEnabled(void* address)
430 {
431 FreeHook* freeHook = m_freeHook;
432 if (UNLIKELY(freeHook != nullptr))
433 freeHook(address);
434 }
435
436 static void reallocHookIfEnabled(void* oldAddress, void* newAddress, size_t size)
437 {
438 // Report a reallocation as a free followed by an allocation.
439 AllocationHook* allocationHook = m_allocationHook;
440 FreeHook* freeHook = m_freeHook;
441 if (UNLIKELY(allocationHook && freeHook)) {
haraken 2015/10/20 12:42:00 if (UNLIKELY(allocationHook)) { ASSERT(freeHook)
Ruud van Asseldonk 2015/10/20 13:22:16 Done. Why will it be faster though? I expect that
haraken 2015/10/20 13:25:01 Yeah, you're right. Let's check both. BTW, what h
442 freeHook(oldAddress);
443 allocationHook(newAddress, size);
444 }
445 }
446
447 private:
448 // Pointers to hook functions that PartitionAlloc will call on allocation an d
449 // free if the pointers are non-null.
450 static AllocationHook* m_allocationHook;
451 static FreeHook* m_freeHook;
452 };
453
414 ALWAYS_INLINE PartitionFreelistEntry* partitionFreelistMask(PartitionFreelistEnt ry* ptr) 454 ALWAYS_INLINE PartitionFreelistEntry* partitionFreelistMask(PartitionFreelistEnt ry* ptr)
415 { 455 {
416 // We use bswap on little endian as a fast mask for two reasons: 456 // We use bswap on little endian as a fast mask for two reasons:
417 // 1) If an object is freed and its vtable used where the attacker doesn't 457 // 1) If an object is freed and its vtable used where the attacker doesn't
418 // get the chance to run allocations between the free and use, the vtable 458 // get the chance to run allocations between the free and use, the vtable
419 // dereference is likely to fault. 459 // dereference is likely to fault.
420 // 2) If the attacker has a linear buffer overflow and elects to try and 460 // 2) If the attacker has a linear buffer overflow and elects to try and
421 // corrupt a freelist pointer, partial pointer overwrite attacks are 461 // corrupt a freelist pointer, partial pointer overwrite attacks are
422 // thwarted. 462 // thwarted.
423 // For big endian, similar guarantees are arrived at with a negation. 463 // For big endian, similar guarantees are arrived at with a negation.
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after
622 void* result = malloc(size); 662 void* result = malloc(size);
623 RELEASE_ASSERT(result); 663 RELEASE_ASSERT(result);
624 return result; 664 return result;
625 #else 665 #else
626 size = partitionCookieSizeAdjustAdd(size); 666 size = partitionCookieSizeAdjustAdd(size);
627 ASSERT(root->initialized); 667 ASSERT(root->initialized);
628 size_t index = size >> kBucketShift; 668 size_t index = size >> kBucketShift;
629 ASSERT(index < root->numBuckets); 669 ASSERT(index < root->numBuckets);
630 ASSERT(size == index << kBucketShift); 670 ASSERT(size == index << kBucketShift);
631 PartitionBucket* bucket = &root->buckets()[index]; 671 PartitionBucket* bucket = &root->buckets()[index];
632 return partitionBucketAlloc(root, 0, size, bucket); 672 void* result = partitionBucketAlloc(root, 0, size, bucket);
673 PartitionAllocHooks::allocationHookIfEnabled(result, size);
674 return result;
633 #endif // defined(MEMORY_TOOL_REPLACES_ALLOCATOR) 675 #endif // defined(MEMORY_TOOL_REPLACES_ALLOCATOR)
634 } 676 }
635 677
636 ALWAYS_INLINE void partitionFreeWithPage(void* ptr, PartitionPage* page) 678 ALWAYS_INLINE void partitionFreeWithPage(void* ptr, PartitionPage* page)
637 { 679 {
638 // If these asserts fire, you probably corrupted memory. 680 // If these asserts fire, you probably corrupted memory.
639 #if ENABLE(ASSERT) 681 #if ENABLE(ASSERT)
640 size_t slotSize = page->bucket->slotSize; 682 size_t slotSize = page->bucket->slotSize;
641 size_t rawSize = partitionPageGetRawSize(page); 683 size_t rawSize = partitionPageGetRawSize(page);
642 if (rawSize) 684 if (rawSize)
(...skipping 22 matching lines...) Expand all
665 707
666 ALWAYS_INLINE void partitionFree(void* ptr) 708 ALWAYS_INLINE void partitionFree(void* ptr)
667 { 709 {
668 #if defined(MEMORY_TOOL_REPLACES_ALLOCATOR) 710 #if defined(MEMORY_TOOL_REPLACES_ALLOCATOR)
669 free(ptr); 711 free(ptr);
670 #else 712 #else
671 ptr = partitionCookieFreePointerAdjust(ptr); 713 ptr = partitionCookieFreePointerAdjust(ptr);
672 ASSERT(partitionPointerIsValid(ptr)); 714 ASSERT(partitionPointerIsValid(ptr));
673 PartitionPage* page = partitionPointerToPage(ptr); 715 PartitionPage* page = partitionPointerToPage(ptr);
674 partitionFreeWithPage(ptr, page); 716 partitionFreeWithPage(ptr, page);
717 PartitionAllocHooks::freeHookIfEnabled(ptr);
675 #endif 718 #endif
676 } 719 }
677 720
678 ALWAYS_INLINE PartitionBucket* partitionGenericSizeToBucket(PartitionRootGeneric * root, size_t size) 721 ALWAYS_INLINE PartitionBucket* partitionGenericSizeToBucket(PartitionRootGeneric * root, size_t size)
679 { 722 {
680 size_t order = kBitsPerSizet - countLeadingZerosSizet(size); 723 size_t order = kBitsPerSizet - countLeadingZerosSizet(size);
681 // The order index is simply the next few bits after the most significant bi t. 724 // The order index is simply the next few bits after the most significant bi t.
682 size_t orderIndex = (size >> root->orderIndexShifts[order]) & (kGenericNumBu cketsPerOrder - 1); 725 size_t orderIndex = (size >> root->orderIndexShifts[order]) & (kGenericNumBu cketsPerOrder - 1);
683 // And if the remaining bits are non-zero we must bump the bucket up. 726 // And if the remaining bits are non-zero we must bump the bucket up.
684 size_t subOrderIndex = size & root->orderSubIndexMasks[order]; 727 size_t subOrderIndex = size & root->orderSubIndexMasks[order];
685 PartitionBucket* bucket = root->bucketLookups[(order << kGenericNumBucketsPe rOrderBits) + orderIndex + !!subOrderIndex]; 728 PartitionBucket* bucket = root->bucketLookups[(order << kGenericNumBucketsPe rOrderBits) + orderIndex + !!subOrderIndex];
686 ASSERT(!bucket->slotSize || bucket->slotSize >= size); 729 ASSERT(!bucket->slotSize || bucket->slotSize >= size);
687 ASSERT(!(bucket->slotSize % kGenericSmallestBucket)); 730 ASSERT(!(bucket->slotSize % kGenericSmallestBucket));
688 return bucket; 731 return bucket;
689 } 732 }
690 733
691 ALWAYS_INLINE void* partitionAllocGenericFlags(PartitionRootGeneric* root, int f lags, size_t size) 734 ALWAYS_INLINE void* partitionAllocGenericFlags(PartitionRootGeneric* root, int f lags, size_t size)
692 { 735 {
693 #if defined(MEMORY_TOOL_REPLACES_ALLOCATOR) 736 #if defined(MEMORY_TOOL_REPLACES_ALLOCATOR)
694 void* result = malloc(size); 737 void* result = malloc(size);
695 RELEASE_ASSERT(result); 738 RELEASE_ASSERT(result);
696 return result; 739 return result;
697 #else 740 #else
698 ASSERT(root->initialized); 741 ASSERT(root->initialized);
699 size = partitionCookieSizeAdjustAdd(size); 742 size = partitionCookieSizeAdjustAdd(size);
700 PartitionBucket* bucket = partitionGenericSizeToBucket(root, size); 743 PartitionBucket* bucket = partitionGenericSizeToBucket(root, size);
701 spinLockLock(&root->lock); 744 spinLockLock(&root->lock);
702 void* ret = partitionBucketAlloc(root, flags, size, bucket); 745 void* ret = partitionBucketAlloc(root, flags, size, bucket);
703 spinLockUnlock(&root->lock); 746 spinLockUnlock(&root->lock);
747 PartitionAllocHooks::allocationHookIfEnabled(ret, size);
704 return ret; 748 return ret;
705 #endif 749 #endif
706 } 750 }
707 751
708 ALWAYS_INLINE void* partitionAllocGeneric(PartitionRootGeneric* root, size_t siz e) 752 ALWAYS_INLINE void* partitionAllocGeneric(PartitionRootGeneric* root, size_t siz e)
709 { 753 {
710 return partitionAllocGenericFlags(root, 0, size); 754 return partitionAllocGenericFlags(root, 0, size);
711 } 755 }
712 756
713 ALWAYS_INLINE void partitionFreeGeneric(PartitionRootGeneric* root, void* ptr) 757 ALWAYS_INLINE void partitionFreeGeneric(PartitionRootGeneric* root, void* ptr)
714 { 758 {
715 #if defined(MEMORY_TOOL_REPLACES_ALLOCATOR) 759 #if defined(MEMORY_TOOL_REPLACES_ALLOCATOR)
716 free(ptr); 760 free(ptr);
717 #else 761 #else
718 ASSERT(root->initialized); 762 ASSERT(root->initialized);
719 763
720 if (UNLIKELY(!ptr)) 764 if (UNLIKELY(!ptr))
721 return; 765 return;
722 766
723 ptr = partitionCookieFreePointerAdjust(ptr); 767 ptr = partitionCookieFreePointerAdjust(ptr);
724 ASSERT(partitionPointerIsValid(ptr)); 768 ASSERT(partitionPointerIsValid(ptr));
725 PartitionPage* page = partitionPointerToPage(ptr); 769 PartitionPage* page = partitionPointerToPage(ptr);
726 spinLockLock(&root->lock); 770 spinLockLock(&root->lock);
727 partitionFreeWithPage(ptr, page); 771 partitionFreeWithPage(ptr, page);
728 spinLockUnlock(&root->lock); 772 spinLockUnlock(&root->lock);
773 PartitionAllocHooks::freeHookIfEnabled(ptr);
729 #endif 774 #endif
730 } 775 }
731 776
732 ALWAYS_INLINE size_t partitionDirectMapSize(size_t size) 777 ALWAYS_INLINE size_t partitionDirectMapSize(size_t size)
733 { 778 {
734 // Caller must check that the size is not above the kGenericMaxDirectMapped 779 // Caller must check that the size is not above the kGenericMaxDirectMapped
735 // limit before calling. This also guards against integer overflow in the 780 // limit before calling. This also guards against integer overflow in the
736 // calculation here. 781 // calculation here.
737 ASSERT(size <= kGenericMaxDirectMapped); 782 ASSERT(size <= kGenericMaxDirectMapped);
738 return (size + kSystemPageOffsetMask) & kSystemPageBaseMask; 783 return (size + kSystemPageOffsetMask) & kSystemPageBaseMask;
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
814 using WTF::partitionAlloc; 859 using WTF::partitionAlloc;
815 using WTF::partitionFree; 860 using WTF::partitionFree;
816 using WTF::partitionAllocGeneric; 861 using WTF::partitionAllocGeneric;
817 using WTF::partitionFreeGeneric; 862 using WTF::partitionFreeGeneric;
818 using WTF::partitionReallocGeneric; 863 using WTF::partitionReallocGeneric;
819 using WTF::partitionAllocActualSize; 864 using WTF::partitionAllocActualSize;
820 using WTF::partitionAllocSupportsGetSize; 865 using WTF::partitionAllocSupportsGetSize;
821 using WTF::partitionAllocGetSize; 866 using WTF::partitionAllocGetSize;
822 867
823 #endif // WTF_PartitionAlloc_h 868 #endif // WTF_PartitionAlloc_h
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698