OLD | NEW |
1 /* Copyright (c) 2006, Google Inc. | 1 /* Copyright (c) 2006, Google Inc. |
2 * All rights reserved. | 2 * 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 639 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
650 Unlock(); | 650 Unlock(); |
651 return; | 651 return; |
652 } | 652 } |
653 if (!recursive_insert) { | 653 if (!recursive_insert) { |
654 HandleSavedRegionsLocked(&InsertRegionLocked); | 654 HandleSavedRegionsLocked(&InsertRegionLocked); |
655 } | 655 } |
656 // first handle adding saved regions if any | 656 // first handle adding saved regions if any |
657 uintptr_t start_addr = reinterpret_cast<uintptr_t>(start); | 657 uintptr_t start_addr = reinterpret_cast<uintptr_t>(start); |
658 uintptr_t end_addr = start_addr + size; | 658 uintptr_t end_addr = start_addr + size; |
659 // subtract start_addr, end_addr from all the regions | 659 // subtract start_addr, end_addr from all the regions |
660 RAW_VLOG(10, "Removing global region %p..%p; have %"PRIuS" regions", | 660 RAW_VLOG(10, "Removing global region %p..%p; have %" PRIuS " regions", |
661 reinterpret_cast<void*>(start_addr), | 661 reinterpret_cast<void*>(start_addr), |
662 reinterpret_cast<void*>(end_addr), | 662 reinterpret_cast<void*>(end_addr), |
663 regions_->size()); | 663 regions_->size()); |
664 Region sample; | 664 Region sample; |
665 sample.SetRegionSetKey(start_addr); | 665 sample.SetRegionSetKey(start_addr); |
666 // Only iterate over the regions that might overlap start_addr..end_addr: | 666 // Only iterate over the regions that might overlap start_addr..end_addr: |
667 for (RegionSet::iterator region = regions_->lower_bound(sample); | 667 for (RegionSet::iterator region = regions_->lower_bound(sample); |
668 region != regions_->end() && region->start_addr < end_addr; | 668 region != regions_->end() && region->start_addr < end_addr; |
669 /*noop*/) { | 669 /*noop*/) { |
670 RAW_VLOG(13, "Looking at region %p..%p", | 670 RAW_VLOG(13, "Looking at region %p..%p", |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
717 RegionSet::iterator d = region; | 717 RegionSet::iterator d = region; |
718 ++region; | 718 ++region; |
719 // It's safe to erase before inserting since r is independent of *d: | 719 // It's safe to erase before inserting since r is independent of *d: |
720 // r contains an own copy of the call stack: | 720 // r contains an own copy of the call stack: |
721 regions_->erase(d); | 721 regions_->erase(d); |
722 InsertRegionLocked(r); | 722 InsertRegionLocked(r); |
723 continue; | 723 continue; |
724 } | 724 } |
725 ++region; | 725 ++region; |
726 } | 726 } |
727 RAW_VLOG(12, "Removed region %p..%p; have %"PRIuS" regions", | 727 RAW_VLOG(12, "Removed region %p..%p; have %" PRIuS " regions", |
728 reinterpret_cast<void*>(start_addr), | 728 reinterpret_cast<void*>(start_addr), |
729 reinterpret_cast<void*>(end_addr), | 729 reinterpret_cast<void*>(end_addr), |
730 regions_->size()); | 730 regions_->size()); |
731 if (VLOG_IS_ON(12)) LogAllLocked(); | 731 if (VLOG_IS_ON(12)) LogAllLocked(); |
732 unmap_size_ += size; | 732 unmap_size_ += size; |
733 Unlock(); | 733 Unlock(); |
734 } | 734 } |
735 | 735 |
736 void MemoryRegionMap::RecordRegionRemovalInBucket(int depth, | 736 void MemoryRegionMap::RecordRegionRemovalInBucket(int depth, |
737 const void* const stack[], | 737 const void* const stack[], |
738 size_t size) { | 738 size_t size) { |
739 RAW_CHECK(LockIsHeld(), "should be held (by this thread)"); | 739 RAW_CHECK(LockIsHeld(), "should be held (by this thread)"); |
740 if (bucket_table_ == NULL) return; | 740 if (bucket_table_ == NULL) return; |
741 HeapProfileBucket* b = GetBucket(depth, stack); | 741 HeapProfileBucket* b = GetBucket(depth, stack); |
742 ++b->frees; | 742 ++b->frees; |
743 b->free_size += size; | 743 b->free_size += size; |
744 } | 744 } |
745 | 745 |
746 void MemoryRegionMap::MmapHook(const void* result, | 746 void MemoryRegionMap::MmapHook(const void* result, |
747 const void* start, size_t size, | 747 const void* start, size_t size, |
748 int prot, int flags, | 748 int prot, int flags, |
749 int fd, off_t offset) { | 749 int fd, off_t offset) { |
750 // TODO(maxim): replace all 0x%"PRIxS" by %p when RAW_VLOG uses a safe | 750 // TODO(maxim): replace all 0x%"PRIxS" by %p when RAW_VLOG uses a safe |
751 // snprintf reimplementation that does not malloc to pretty-print NULL | 751 // snprintf reimplementation that does not malloc to pretty-print NULL |
752 RAW_VLOG(10, "MMap = 0x%"PRIxPTR" of %"PRIuS" at %"PRIu64" " | 752 RAW_VLOG(10, "MMap = 0x%" PRIxPTR " of %" PRIuS " at %" PRIu64 " " |
753 "prot %d flags %d fd %d offs %"PRId64, | 753 "prot %d flags %d fd %d offs %" PRId64, |
754 reinterpret_cast<uintptr_t>(result), size, | 754 reinterpret_cast<uintptr_t>(result), size, |
755 reinterpret_cast<uint64>(start), prot, flags, fd, | 755 reinterpret_cast<uint64>(start), prot, flags, fd, |
756 static_cast<int64>(offset)); | 756 static_cast<int64>(offset)); |
757 if (result != reinterpret_cast<void*>(MAP_FAILED) && size != 0) { | 757 if (result != reinterpret_cast<void*>(MAP_FAILED) && size != 0) { |
758 RecordRegionAddition(result, size); | 758 RecordRegionAddition(result, size); |
759 } | 759 } |
760 } | 760 } |
761 | 761 |
762 void MemoryRegionMap::MunmapHook(const void* ptr, size_t size) { | 762 void MemoryRegionMap::MunmapHook(const void* ptr, size_t size) { |
763 RAW_VLOG(10, "MUnmap of %p %"PRIuS"", ptr, size); | 763 RAW_VLOG(10, "MUnmap of %p %" PRIuS, ptr, size); |
764 if (size != 0) { | 764 if (size != 0) { |
765 RecordRegionRemoval(ptr, size); | 765 RecordRegionRemoval(ptr, size); |
766 } | 766 } |
767 } | 767 } |
768 | 768 |
769 void MemoryRegionMap::MremapHook(const void* result, | 769 void MemoryRegionMap::MremapHook(const void* result, |
770 const void* old_addr, size_t old_size, | 770 const void* old_addr, size_t old_size, |
771 size_t new_size, int flags, | 771 size_t new_size, int flags, |
772 const void* new_addr) { | 772 const void* new_addr) { |
773 RAW_VLOG(10, "MRemap = 0x%"PRIxPTR" of 0x%"PRIxPTR" %"PRIuS" " | 773 RAW_VLOG(10, "MRemap = 0x%" PRIxPTR " of 0x%" PRIxPTR " %" PRIuS " " |
774 "to %"PRIuS" flags %d new_addr=0x%"PRIxPTR, | 774 "to %" PRIuS " flags %d new_addr=0x%" PRIxPTR, |
775 (uintptr_t)result, (uintptr_t)old_addr, | 775 (uintptr_t)result, (uintptr_t)old_addr, |
776 old_size, new_size, flags, | 776 old_size, new_size, flags, |
777 flags & MREMAP_FIXED ? (uintptr_t)new_addr : 0); | 777 flags & MREMAP_FIXED ? (uintptr_t)new_addr : 0); |
778 if (result != reinterpret_cast<void*>(-1)) { | 778 if (result != reinterpret_cast<void*>(-1)) { |
779 RecordRegionRemoval(old_addr, old_size); | 779 RecordRegionRemoval(old_addr, old_size); |
780 RecordRegionAddition(result, new_size); | 780 RecordRegionAddition(result, new_size); |
781 } | 781 } |
782 } | 782 } |
783 | 783 |
784 extern "C" void* __sbrk(ptrdiff_t increment); // defined in libc | 784 extern "C" void* __sbrk(ptrdiff_t increment); // defined in libc |
785 | 785 |
786 void MemoryRegionMap::SbrkHook(const void* result, ptrdiff_t increment) { | 786 void MemoryRegionMap::SbrkHook(const void* result, ptrdiff_t increment) { |
787 RAW_VLOG(10, "Sbrk = 0x%"PRIxPTR" of %"PRIdS"", (uintptr_t)result, increment); | 787 RAW_VLOG(10, "Sbrk = 0x%" PRIxPTR " of %" PRIdS, |
| 788 (uintptr_t)result, increment); |
788 if (result != reinterpret_cast<void*>(-1)) { | 789 if (result != reinterpret_cast<void*>(-1)) { |
789 if (increment > 0) { | 790 if (increment > 0) { |
790 void* new_end = sbrk(0); | 791 void* new_end = sbrk(0); |
791 RecordRegionAddition(result, reinterpret_cast<uintptr_t>(new_end) - | 792 RecordRegionAddition(result, reinterpret_cast<uintptr_t>(new_end) - |
792 reinterpret_cast<uintptr_t>(result)); | 793 reinterpret_cast<uintptr_t>(result)); |
793 } else if (increment < 0) { | 794 } else if (increment < 0) { |
794 void* new_end = sbrk(0); | 795 void* new_end = sbrk(0); |
795 RecordRegionRemoval(new_end, reinterpret_cast<uintptr_t>(result) - | 796 RecordRegionRemoval(new_end, reinterpret_cast<uintptr_t>(result) - |
796 reinterpret_cast<uintptr_t>(new_end)); | 797 reinterpret_cast<uintptr_t>(new_end)); |
797 } | 798 } |
798 } | 799 } |
799 } | 800 } |
800 | 801 |
801 void MemoryRegionMap::LogAllLocked() { | 802 void MemoryRegionMap::LogAllLocked() { |
802 RAW_CHECK(LockIsHeld(), "should be held (by this thread)"); | 803 RAW_CHECK(LockIsHeld(), "should be held (by this thread)"); |
803 RAW_LOG(INFO, "List of regions:"); | 804 RAW_LOG(INFO, "List of regions:"); |
804 uintptr_t previous = 0; | 805 uintptr_t previous = 0; |
805 for (RegionSet::const_iterator r = regions_->begin(); | 806 for (RegionSet::const_iterator r = regions_->begin(); |
806 r != regions_->end(); ++r) { | 807 r != regions_->end(); ++r) { |
807 RAW_LOG(INFO, "Memory region 0x%"PRIxPTR"..0x%"PRIxPTR" " | 808 RAW_LOG(INFO, "Memory region 0x%" PRIxPTR "..0x%" PRIxPTR " " |
808 "from 0x%"PRIxPTR" stack=%d", | 809 "from 0x%" PRIxPTR " stack=%d", |
809 r->start_addr, r->end_addr, r->caller(), r->is_stack); | 810 r->start_addr, r->end_addr, r->caller(), r->is_stack); |
810 RAW_CHECK(previous < r->end_addr, "wow, we messed up the set order"); | 811 RAW_CHECK(previous < r->end_addr, "wow, we messed up the set order"); |
811 // this must be caused by uncontrolled recursive operations on regions_ | 812 // this must be caused by uncontrolled recursive operations on regions_ |
812 previous = r->end_addr; | 813 previous = r->end_addr; |
813 } | 814 } |
814 RAW_LOG(INFO, "End of regions list"); | 815 RAW_LOG(INFO, "End of regions list"); |
815 } | 816 } |
OLD | NEW |