| 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 |