Chromium Code Reviews| 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 12 matching lines...) Expand all Loading... | |
| 23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | 23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 29 */ | 29 */ |
| 30 | 30 |
| 31 #include "platform/heap/HeapPage.h" | 31 #include "platform/heap/HeapPage.h" |
| 32 | 32 |
| 33 #include "base/sys_info.h" | |
| 33 #include "platform/ScriptForbiddenScope.h" | 34 #include "platform/ScriptForbiddenScope.h" |
| 34 #include "platform/Task.h" | 35 #include "platform/Task.h" |
| 35 #include "platform/TraceEvent.h" | 36 #include "platform/TraceEvent.h" |
| 36 #include "platform/heap/BlinkGCMemoryDumpProvider.h" | 37 #include "platform/heap/BlinkGCMemoryDumpProvider.h" |
| 37 #include "platform/heap/CallbackStack.h" | 38 #include "platform/heap/CallbackStack.h" |
| 38 #include "platform/heap/Heap.h" | 39 #include "platform/heap/Heap.h" |
| 39 #include "platform/heap/MarkingVisitor.h" | 40 #include "platform/heap/MarkingVisitor.h" |
| 40 #include "platform/heap/PageMemory.h" | 41 #include "platform/heap/PageMemory.h" |
| 41 #include "platform/heap/PagePool.h" | 42 #include "platform/heap/PagePool.h" |
| 42 #include "platform/heap/SafePoint.h" | 43 #include "platform/heap/SafePoint.h" |
| (...skipping 1054 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1097 { | 1098 { |
| 1098 HeapObjectHeader* header = reinterpret_cast<HeapObjectHeader*>(payload()); | 1099 HeapObjectHeader* header = reinterpret_cast<HeapObjectHeader*>(payload()); |
| 1099 return header->isFree() && header->size() == payloadSize(); | 1100 return header->isFree() && header->size() == payloadSize(); |
| 1100 } | 1101 } |
| 1101 | 1102 |
| 1102 void NormalPage::removeFromHeap() | 1103 void NormalPage::removeFromHeap() |
| 1103 { | 1104 { |
| 1104 heapForNormalPage()->freePage(this); | 1105 heapForNormalPage()->freePage(this); |
| 1105 } | 1106 } |
| 1106 | 1107 |
| 1108 #if !ENABLE(ASSERT) && !defined(LEAK_SANITIZER) && !defined(ADDRESS_SANITIZER) | |
| 1109 static void discardPages(Address begin, Address end) | |
| 1110 { | |
| 1111 uintptr_t beginAddress = WTF::roundUpToSystemPage(reinterpret_cast<uintptr_t >(begin)); | |
| 1112 uintptr_t endAddress = WTF::roundDownToSystemPage(reinterpret_cast<uintptr_t >(end)); | |
| 1113 if (beginAddress < endAddress) | |
| 1114 WTF::discardSystemPages(reinterpret_cast<void*>(beginAddress), endAddres s - beginAddress); | |
| 1115 } | |
| 1116 #endif | |
| 1117 | |
| 1107 void NormalPage::sweep() | 1118 void NormalPage::sweep() |
| 1108 { | 1119 { |
| 1120 bool isLowEndDevice = base::SysInfo::IsLowEndDevice(); | |
|
sof
2016/02/08 11:03:25
Do we have to sample this each time a page is swep
| |
| 1109 size_t markedObjectSize = 0; | 1121 size_t markedObjectSize = 0; |
| 1110 Address startOfGap = payload(); | 1122 Address startOfGap = payload(); |
| 1111 for (Address headerAddress = startOfGap; headerAddress < payloadEnd(); ) { | 1123 for (Address headerAddress = startOfGap; headerAddress < payloadEnd(); ) { |
| 1112 HeapObjectHeader* header = reinterpret_cast<HeapObjectHeader*>(headerAdd ress); | 1124 HeapObjectHeader* header = reinterpret_cast<HeapObjectHeader*>(headerAdd ress); |
| 1113 ASSERT(header->size() > 0); | 1125 size_t size = header->size(); |
| 1114 ASSERT(header->size() < blinkPagePayloadSize()); | 1126 ASSERT(size > 0); |
| 1127 ASSERT(size < blinkPagePayloadSize()); | |
| 1115 | 1128 |
| 1116 if (header->isPromptlyFreed()) | 1129 if (header->isPromptlyFreed()) |
| 1117 heapForNormalPage()->decreasePromptlyFreedSize(header->size()); | 1130 heapForNormalPage()->decreasePromptlyFreedSize(size); |
| 1118 if (header->isFree()) { | 1131 if (header->isFree()) { |
| 1119 size_t size = header->size(); | |
| 1120 // Zero the memory in the free list header to maintain the | 1132 // Zero the memory in the free list header to maintain the |
| 1121 // invariant that memory on the free list is zero filled. | 1133 // invariant that memory on the free list is zero filled. |
| 1122 // The rest of the memory is already on the free list and is | 1134 // The rest of the memory is already on the free list and is |
| 1123 // therefore already zero filled. | 1135 // therefore already zero filled. |
| 1124 SET_MEMORY_INACCESSIBLE(headerAddress, size < sizeof(FreeListEntry) ? size : sizeof(FreeListEntry)); | 1136 SET_MEMORY_INACCESSIBLE(headerAddress, size < sizeof(FreeListEntry) ? size : sizeof(FreeListEntry)); |
| 1125 CHECK_MEMORY_INACCESSIBLE(headerAddress, size); | 1137 CHECK_MEMORY_INACCESSIBLE(headerAddress, size); |
| 1126 headerAddress += size; | 1138 headerAddress += size; |
| 1127 continue; | 1139 continue; |
| 1128 } | 1140 } |
| 1129 ASSERT(header->checkHeader()); | 1141 ASSERT(header->checkHeader()); |
| 1130 | 1142 |
| 1131 if (!header->isMarked()) { | 1143 if (!header->isMarked()) { |
| 1132 size_t size = header->size(); | |
| 1133 // This is a fast version of header->payloadSize(). | 1144 // This is a fast version of header->payloadSize(). |
| 1134 size_t payloadSize = size - sizeof(HeapObjectHeader); | 1145 size_t payloadSize = size - sizeof(HeapObjectHeader); |
| 1135 Address payload = header->payload(); | 1146 Address payload = header->payload(); |
| 1136 // For ASan, unpoison the object before calling the finalizer. The | 1147 // For ASan, unpoison the object before calling the finalizer. The |
| 1137 // finalized object will be zero-filled and poison'ed afterwards. | 1148 // finalized object will be zero-filled and poison'ed afterwards. |
| 1138 // Given all other unmarked objects are poisoned, ASan will detect | 1149 // Given all other unmarked objects are poisoned, ASan will detect |
| 1139 // an error if the finalizer touches any other on-heap object that | 1150 // an error if the finalizer touches any other on-heap object that |
| 1140 // die at the same GC cycle. | 1151 // die at the same GC cycle. |
| 1141 ASAN_UNPOISON_MEMORY_REGION(payload, payloadSize); | 1152 ASAN_UNPOISON_MEMORY_REGION(payload, payloadSize); |
| 1142 header->finalize(payload, payloadSize); | 1153 header->finalize(payload, payloadSize); |
| 1143 // This memory will be added to the freelist. Maintain the invariant | 1154 // This memory will be added to the freelist. Maintain the invariant |
| 1144 // that memory on the freelist is zero filled. | 1155 // that memory on the freelist is zero filled. |
| 1145 SET_MEMORY_INACCESSIBLE(headerAddress, size); | 1156 SET_MEMORY_INACCESSIBLE(headerAddress, size); |
| 1146 headerAddress += size; | 1157 headerAddress += size; |
| 1147 continue; | 1158 continue; |
| 1148 } | 1159 } |
| 1149 if (startOfGap != headerAddress) | 1160 if (startOfGap != headerAddress) { |
| 1150 heapForNormalPage()->addToFreeList(startOfGap, headerAddress - start OfGap); | 1161 heapForNormalPage()->addToFreeList(startOfGap, headerAddress - start OfGap); |
| 1162 #if !ENABLE(ASSERT) && !defined(LEAK_SANITIZER) && !defined(ADDRESS_SANITIZER) | |
| 1163 // Discarding pages increases page faults and may regress performanc e. | |
| 1164 // So we enable this only on low-RAM devices. | |
| 1165 if (isLowEndDevice) | |
| 1166 discardPages(startOfGap + sizeof(FreeListEntry), headerAddress); | |
| 1167 #endif | |
| 1168 } | |
| 1151 header->unmark(); | 1169 header->unmark(); |
| 1152 headerAddress += header->size(); | 1170 headerAddress += size; |
| 1153 markedObjectSize += header->size(); | 1171 markedObjectSize += size; |
| 1154 startOfGap = headerAddress; | 1172 startOfGap = headerAddress; |
| 1155 } | 1173 } |
| 1156 if (startOfGap != payloadEnd()) | 1174 if (startOfGap != payloadEnd()) { |
| 1157 heapForNormalPage()->addToFreeList(startOfGap, payloadEnd() - startOfGap ); | 1175 heapForNormalPage()->addToFreeList(startOfGap, payloadEnd() - startOfGap ); |
| 1176 #if !ENABLE(ASSERT) && !defined(LEAK_SANITIZER) && !defined(ADDRESS_SANITIZER) | |
| 1177 if (isLowEndDevice) | |
| 1178 discardPages(startOfGap + sizeof(FreeListEntry), payloadEnd()); | |
| 1179 #endif | |
| 1180 } | |
| 1158 | 1181 |
| 1159 if (markedObjectSize) | 1182 if (markedObjectSize) |
| 1160 Heap::increaseMarkedObjectSize(markedObjectSize); | 1183 Heap::increaseMarkedObjectSize(markedObjectSize); |
| 1161 } | 1184 } |
| 1162 | 1185 |
| 1163 void NormalPage::makeConsistentForGC() | 1186 void NormalPage::makeConsistentForGC() |
| 1164 { | 1187 { |
| 1165 size_t markedObjectSize = 0; | 1188 size_t markedObjectSize = 0; |
| 1166 for (Address headerAddress = payload(); headerAddress < payloadEnd();) { | 1189 for (Address headerAddress = payload(); headerAddress < payloadEnd();) { |
| 1167 HeapObjectHeader* header = reinterpret_cast<HeapObjectHeader*>(headerAdd ress); | 1190 HeapObjectHeader* header = reinterpret_cast<HeapObjectHeader*>(headerAdd ress); |
| (...skipping 406 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1574 | 1597 |
| 1575 m_hasEntries = true; | 1598 m_hasEntries = true; |
| 1576 size_t index = hash(address); | 1599 size_t index = hash(address); |
| 1577 ASSERT(!(index & 1)); | 1600 ASSERT(!(index & 1)); |
| 1578 Address cachePage = roundToBlinkPageStart(address); | 1601 Address cachePage = roundToBlinkPageStart(address); |
| 1579 m_entries[index + 1] = m_entries[index]; | 1602 m_entries[index + 1] = m_entries[index]; |
| 1580 m_entries[index] = cachePage; | 1603 m_entries[index] = cachePage; |
| 1581 } | 1604 } |
| 1582 | 1605 |
| 1583 } // namespace blink | 1606 } // namespace blink |
| OLD | NEW |