OLD | NEW |
---|---|
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 22 matching lines...) Expand all Loading... | |
33 | 33 |
34 #include "platform/ScriptForbiddenScope.h" | 34 #include "platform/ScriptForbiddenScope.h" |
35 #include "platform/Task.h" | 35 #include "platform/Task.h" |
36 #include "platform/TraceEvent.h" | 36 #include "platform/TraceEvent.h" |
37 #include "platform/heap/CallbackStack.h" | 37 #include "platform/heap/CallbackStack.h" |
38 #include "platform/heap/MarkingVisitorImpl.h" | 38 #include "platform/heap/MarkingVisitorImpl.h" |
39 #include "platform/heap/ThreadState.h" | 39 #include "platform/heap/ThreadState.h" |
40 #include "public/platform/Platform.h" | 40 #include "public/platform/Platform.h" |
41 #include "wtf/AddressSpaceRandomization.h" | 41 #include "wtf/AddressSpaceRandomization.h" |
42 #include "wtf/Assertions.h" | 42 #include "wtf/Assertions.h" |
43 #include "wtf/ContainerAnnotations.h" | |
43 #include "wtf/LeakAnnotations.h" | 44 #include "wtf/LeakAnnotations.h" |
44 #include "wtf/PassOwnPtr.h" | 45 #include "wtf/PassOwnPtr.h" |
45 #if ENABLE(GC_PROFILING) | 46 #if ENABLE(GC_PROFILING) |
46 #include "platform/TracedValue.h" | 47 #include "platform/TracedValue.h" |
47 #include "wtf/HashMap.h" | 48 #include "wtf/HashMap.h" |
48 #include "wtf/HashSet.h" | 49 #include "wtf/HashSet.h" |
49 #include "wtf/text/StringBuilder.h" | 50 #include "wtf/text/StringBuilder.h" |
50 #include "wtf/text/StringHash.h" | 51 #include "wtf/text/StringHash.h" |
51 #include <stdio.h> | 52 #include <stdio.h> |
52 #include <utility> | 53 #include <utility> |
53 #endif | 54 #endif |
54 | 55 |
55 #if OS(POSIX) | 56 #if OS(POSIX) |
56 #include <sys/mman.h> | 57 #include <sys/mman.h> |
57 #include <unistd.h> | 58 #include <unistd.h> |
58 #elif OS(WIN) | 59 #elif OS(WIN) |
59 #include <windows.h> | 60 #include <windows.h> |
60 #endif | 61 #endif |
61 | 62 |
63 #ifdef ANNOTATE_CONTIGUOUS_CONTAINER | |
64 #define ENABLE_ASAN_CONTAINER_ANNOTATIONS 1 | |
65 // Remove the contiguous container annotation, as non-inlined vector backings | |
66 // aren't finalized. | |
67 #define ASAN_RETIRE_CONTAINER_ANNOTATION(heapIndex, payload, payloadSize) \ | |
haraken
2015/02/20 20:57:56
You might remove the heapIndex parameter from ASAN
sof
2015/02/21 08:52:34
Done.
| |
68 if (heapIndex == VectorHeapIndex) \ | |
69 ANNOTATE_DELETE_BUFFER(payload, payloadSize, 0) | |
70 #else | |
71 #define ASAN_RETIRE_CONTAINER_ANNOTATION(heapIndex, payload, payloadSize) | |
72 #endif | |
73 | |
62 namespace blink { | 74 namespace blink { |
63 | 75 |
64 #if ENABLE(GC_PROFILING) | 76 #if ENABLE(GC_PROFILING) |
65 static String classOf(const void* object) | 77 static String classOf(const void* object) |
66 { | 78 { |
67 if (const GCInfo* gcInfo = Heap::findGCInfo(reinterpret_cast<Address>(const_ cast<void*>(object)))) | 79 if (const GCInfo* gcInfo = Heap::findGCInfo(reinterpret_cast<Address>(const_ cast<void*>(object)))) |
68 return gcInfo->m_className; | 80 return gcInfo->m_className; |
69 return "unknown"; | 81 return "unknown"; |
70 } | 82 } |
71 #endif | 83 #endif |
(...skipping 810 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
882 header->checkHeader(); | 894 header->checkHeader(); |
883 Address address = reinterpret_cast<Address>(header); | 895 Address address = reinterpret_cast<Address>(header); |
884 Address payload = header->payload(); | 896 Address payload = header->payload(); |
885 size_t size = header->size(); | 897 size_t size = header->size(); |
886 size_t payloadSize = header->payloadSize(); | 898 size_t payloadSize = header->payloadSize(); |
887 ASSERT(size > 0); | 899 ASSERT(size > 0); |
888 ASSERT(pageFromObject(address) == findPageFromAddress(address)); | 900 ASSERT(pageFromObject(address) == findPageFromAddress(address)); |
889 | 901 |
890 { | 902 { |
891 ThreadState::SweepForbiddenScope forbiddenScope(threadState()); | 903 ThreadState::SweepForbiddenScope forbiddenScope(threadState()); |
904 ASAN_RETIRE_CONTAINER_ANNOTATION(heapIndex(), payload, payloadSize); | |
892 header->finalize(payload, payloadSize); | 905 header->finalize(payload, payloadSize); |
893 if (address + size == m_currentAllocationPoint) { | 906 if (address + size == m_currentAllocationPoint) { |
894 m_currentAllocationPoint = address; | 907 m_currentAllocationPoint = address; |
895 if (m_lastRemainingAllocationSize == m_remainingAllocationSize) { | 908 if (m_lastRemainingAllocationSize == m_remainingAllocationSize) { |
896 Heap::decreaseAllocatedObjectSize(size); | 909 Heap::decreaseAllocatedObjectSize(size); |
897 m_lastRemainingAllocationSize += size; | 910 m_lastRemainingAllocationSize += size; |
898 } | 911 } |
899 m_remainingAllocationSize += size; | 912 m_remainingAllocationSize += size; |
900 FILL_ZERO_IF_PRODUCTION(address, size); | 913 FILL_ZERO_IF_PRODUCTION(address, size); |
901 ASAN_POISON_MEMORY_REGION(address, size); | 914 ASAN_POISON_MEMORY_REGION(address, size); |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1012 Address NormalPageHeap::outOfLineAllocate(size_t allocationSize, size_t gcInfoIn dex) | 1025 Address NormalPageHeap::outOfLineAllocate(size_t allocationSize, size_t gcInfoIn dex) |
1013 { | 1026 { |
1014 ASSERT(allocationSize > remainingAllocationSize()); | 1027 ASSERT(allocationSize > remainingAllocationSize()); |
1015 ASSERT(allocationSize >= allocationGranularity); | 1028 ASSERT(allocationSize >= allocationGranularity); |
1016 | 1029 |
1017 #if ENABLE(GC_PROFILING) | 1030 #if ENABLE(GC_PROFILING) |
1018 threadState()->snapshotFreeListIfNecessary(); | 1031 threadState()->snapshotFreeListIfNecessary(); |
1019 #endif | 1032 #endif |
1020 | 1033 |
1021 // 1. If this allocation is big enough, allocate a large object. | 1034 // 1. If this allocation is big enough, allocate a large object. |
1022 if (allocationSize >= largeObjectSizeThreshold) | 1035 if (allocationSize >= largeObjectSizeThreshold) { |
1023 return static_cast<LargeObjectHeap*>(threadState()->heap(LargeObjectHeap Index))->allocateLargeObjectPage(allocationSize, gcInfoIndex); | 1036 Address largeObject = static_cast<LargeObjectHeap*>(threadState()->heap( LargeObjectHeapIndex))->allocateLargeObjectPage(allocationSize, gcInfoIndex); |
1037 #if ENABLE(ASAN_CONTAINER_ANNOTATIONS) | |
1038 if (heapIndex() == VectorHeapIndex) { | |
haraken
2015/02/20 20:57:56
Can we move this logic to doAllocateLargeObject, w
sof
2015/02/20 21:06:43
Don't see how without passing in the heapIndex as
haraken
2015/02/20 21:11:09
You can get heapIndex from payload. payload => pag
sof
2015/02/20 21:45:17
I don't get it; payload of what? LargeObjectHeap h
haraken
2015/02/21 06:56:35
As commented above, I think you can get a right he
sof
2015/02/21 08:52:34
Addressed in the tidiest manner I could think of.
| |
1039 BasePage* largePage = pageFromObject(largeObject); | |
1040 ASSERT(largePage->isLargeObjectPage()); | |
1041 static_cast<LargeObjectPage*>(largePage)->setIsVectorBackingPage(); | |
1042 } | |
1043 #endif | |
1044 return largeObject; | |
1045 } | |
1024 | 1046 |
1025 // 2. Check if we should trigger a GC. | 1047 // 2. Check if we should trigger a GC. |
1026 updateRemainingAllocationSize(); | 1048 updateRemainingAllocationSize(); |
1027 threadState()->scheduleGCIfNeeded(); | 1049 threadState()->scheduleGCIfNeeded(); |
1028 | 1050 |
1029 // 3. Try to allocate from a free list. | 1051 // 3. Try to allocate from a free list. |
1030 Address result = allocateFromFreeList(allocationSize, gcInfoIndex); | 1052 Address result = allocateFromFreeList(allocationSize, gcInfoIndex); |
1031 if (result) | 1053 if (result) |
1032 return result; | 1054 return result; |
1033 | 1055 |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1149 | 1171 |
1150 largeObject->link(&m_firstPage); | 1172 largeObject->link(&m_firstPage); |
1151 | 1173 |
1152 Heap::increaseAllocatedSpace(largeObject->size()); | 1174 Heap::increaseAllocatedSpace(largeObject->size()); |
1153 Heap::increaseAllocatedObjectSize(largeObject->size()); | 1175 Heap::increaseAllocatedObjectSize(largeObject->size()); |
1154 return result; | 1176 return result; |
1155 } | 1177 } |
1156 | 1178 |
1157 void LargeObjectHeap::freeLargeObjectPage(LargeObjectPage* object) | 1179 void LargeObjectHeap::freeLargeObjectPage(LargeObjectPage* object) |
1158 { | 1180 { |
1181 #if ENABLE(ASAN_CONTAINER_ANNOTATIONS) | |
1182 if (object->isVectorBackingPage()) | |
1183 ASAN_RETIRE_CONTAINER_ANNOTATION(VectorHeapIndex, object->payload(), obj ect->payloadSize()); | |
1184 #endif | |
1159 object->heapObjectHeader()->finalize(object->payload(), object->payloadSize( )); | 1185 object->heapObjectHeader()->finalize(object->payload(), object->payloadSize( )); |
1160 Heap::decreaseAllocatedSpace(object->size()); | 1186 Heap::decreaseAllocatedSpace(object->size()); |
1161 | 1187 |
1162 // Unpoison the object header and allocationGranularity bytes after the | 1188 // Unpoison the object header and allocationGranularity bytes after the |
1163 // object before freeing. | 1189 // object before freeing. |
1164 ASAN_UNPOISON_MEMORY_REGION(object->heapObjectHeader(), sizeof(HeapObjectHea der)); | 1190 ASAN_UNPOISON_MEMORY_REGION(object->heapObjectHeader(), sizeof(HeapObjectHea der)); |
1165 ASAN_UNPOISON_MEMORY_REGION(object->address() + object->size(), allocationGr anularity); | 1191 ASAN_UNPOISON_MEMORY_REGION(object->address() + object->size(), allocationGr anularity); |
1166 | 1192 |
1167 if (object->terminating()) { | 1193 if (object->terminating()) { |
1168 ASSERT(ThreadState::current()->isTerminating()); | 1194 ASSERT(ThreadState::current()->isTerminating()); |
(...skipping 339 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1508 if (!header->isMarked()) { | 1534 if (!header->isMarked()) { |
1509 size_t size = header->size(); | 1535 size_t size = header->size(); |
1510 // This is a fast version of header->payloadSize(). | 1536 // This is a fast version of header->payloadSize(). |
1511 size_t payloadSize = size - sizeof(HeapObjectHeader); | 1537 size_t payloadSize = size - sizeof(HeapObjectHeader); |
1512 Address payload = header->payload(); | 1538 Address payload = header->payload(); |
1513 // For ASan we unpoison the specific object when calling the | 1539 // For ASan we unpoison the specific object when calling the |
1514 // finalizer and poison it again when done to allow the object's own | 1540 // finalizer and poison it again when done to allow the object's own |
1515 // finalizer to operate on the object, but not have other finalizers | 1541 // finalizer to operate on the object, but not have other finalizers |
1516 // be allowed to access it. | 1542 // be allowed to access it. |
1517 ASAN_UNPOISON_MEMORY_REGION(payload, payloadSize); | 1543 ASAN_UNPOISON_MEMORY_REGION(payload, payloadSize); |
1544 ASAN_RETIRE_CONTAINER_ANNOTATION(heap()->heapIndex(), payload, paylo adSize); | |
1518 header->finalize(payload, payloadSize); | 1545 header->finalize(payload, payloadSize); |
1519 // This memory will be added to the freelist. Maintain the invariant | 1546 // This memory will be added to the freelist. Maintain the invariant |
1520 // that memory on the freelist is zero filled. | 1547 // that memory on the freelist is zero filled. |
1521 FILL_ZERO_IF_PRODUCTION(headerAddress, size); | 1548 FILL_ZERO_IF_PRODUCTION(headerAddress, size); |
1522 ASAN_POISON_MEMORY_REGION(payload, payloadSize); | 1549 ASAN_POISON_MEMORY_REGION(payload, payloadSize); |
1523 headerAddress += size; | 1550 headerAddress += size; |
1524 continue; | 1551 continue; |
1525 } | 1552 } |
1526 | 1553 |
1527 if (startOfGap != headerAddress) | 1554 if (startOfGap != headerAddress) |
(...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1767 #endif | 1794 #endif |
1768 | 1795 |
1769 NormalPageHeap* NormalPage::heapForNormalPage() | 1796 NormalPageHeap* NormalPage::heapForNormalPage() |
1770 { | 1797 { |
1771 return static_cast<NormalPageHeap*>(heap()); | 1798 return static_cast<NormalPageHeap*>(heap()); |
1772 } | 1799 } |
1773 | 1800 |
1774 LargeObjectPage::LargeObjectPage(PageMemory* storage, BaseHeap* heap, size_t pay loadSize) | 1801 LargeObjectPage::LargeObjectPage(PageMemory* storage, BaseHeap* heap, size_t pay loadSize) |
1775 : BasePage(storage, heap) | 1802 : BasePage(storage, heap) |
1776 , m_payloadSize(payloadSize) | 1803 , m_payloadSize(payloadSize) |
1804 #if ENABLE(ASAN_CONTAINER_ANNOTATIONS) | |
1805 , m_isVectorBackingPage(false) | |
1806 #endif | |
1777 { | 1807 { |
1778 } | 1808 } |
1779 | 1809 |
1780 size_t LargeObjectPage::objectPayloadSizeForTesting() | 1810 size_t LargeObjectPage::objectPayloadSizeForTesting() |
1781 { | 1811 { |
1782 markAsSwept(); | 1812 markAsSwept(); |
1783 return payloadSize(); | 1813 return payloadSize(); |
1784 } | 1814 } |
1785 | 1815 |
1786 bool LargeObjectPage::isEmpty() | 1816 bool LargeObjectPage::isEmpty() |
(...skipping 1037 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2824 bool Heap::s_shutdownCalled = false; | 2854 bool Heap::s_shutdownCalled = false; |
2825 bool Heap::s_lastGCWasConservative = false; | 2855 bool Heap::s_lastGCWasConservative = false; |
2826 FreePagePool* Heap::s_freePagePool; | 2856 FreePagePool* Heap::s_freePagePool; |
2827 OrphanedPagePool* Heap::s_orphanedPagePool; | 2857 OrphanedPagePool* Heap::s_orphanedPagePool; |
2828 Heap::RegionTree* Heap::s_regionTree = nullptr; | 2858 Heap::RegionTree* Heap::s_regionTree = nullptr; |
2829 size_t Heap::s_allocatedObjectSize = 0; | 2859 size_t Heap::s_allocatedObjectSize = 0; |
2830 size_t Heap::s_allocatedSpace = 0; | 2860 size_t Heap::s_allocatedSpace = 0; |
2831 size_t Heap::s_markedObjectSize = 0; | 2861 size_t Heap::s_markedObjectSize = 0; |
2832 | 2862 |
2833 } // namespace blink | 2863 } // namespace blink |
OLD | NEW |