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 183 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
194 SafePointScope m_safePointScope; | 194 SafePointScope m_safePointScope; |
195 ThreadState::GCType m_gcType; | 195 ThreadState::GCType m_gcType; |
196 OwnPtr<Visitor> m_visitor; | 196 OwnPtr<Visitor> m_visitor; |
197 bool m_parkedAllThreads; // False if we fail to park all threads | 197 bool m_parkedAllThreads; // False if we fail to park all threads |
198 }; | 198 }; |
199 | 199 |
200 #if ENABLE(ASSERT) | 200 #if ENABLE(ASSERT) |
201 NO_SANITIZE_ADDRESS | 201 NO_SANITIZE_ADDRESS |
202 void HeapObjectHeader::zapMagic() | 202 void HeapObjectHeader::zapMagic() |
203 { | 203 { |
204 checkHeader(); | 204 ASSERT(checkHeader()); |
205 m_magic = zappedMagic; | 205 m_magic = zappedMagic; |
206 } | 206 } |
207 #endif | 207 #endif |
208 | 208 |
209 void HeapObjectHeader::finalize(Address object, size_t objectSize) | 209 void HeapObjectHeader::finalize(Address object, size_t objectSize) |
210 { | 210 { |
211 const GCInfo* gcInfo = Heap::gcInfo(gcInfoIndex()); | 211 const GCInfo* gcInfo = Heap::gcInfo(gcInfoIndex()); |
212 if (gcInfo->hasFinalizer()) { | 212 if (gcInfo->hasFinalizer()) { |
213 gcInfo->m_finalize(object); | 213 gcInfo->m_finalize(object); |
214 } | 214 } |
(...skipping 494 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
709 } | 709 } |
710 if (header->isFree()) { | 710 if (header->isFree()) { |
711 // Zero the memory in the free list header to maintain the | 711 // Zero the memory in the free list header to maintain the |
712 // invariant that memory on the free list is zero filled. | 712 // invariant that memory on the free list is zero filled. |
713 // The rest of the memory is already on the free list and is | 713 // The rest of the memory is already on the free list and is |
714 // therefore already zero filled. | 714 // therefore already zero filled. |
715 FILL_ZERO_IF_PRODUCTION(headerAddress, size < sizeof(FreeListEnt
ry) ? size : sizeof(FreeListEntry)); | 715 FILL_ZERO_IF_PRODUCTION(headerAddress, size < sizeof(FreeListEnt
ry) ? size : sizeof(FreeListEntry)); |
716 headerAddress += size; | 716 headerAddress += size; |
717 continue; | 717 continue; |
718 } | 718 } |
719 header->checkHeader(); | 719 ASSERT(header->checkHeader()); |
720 if (startOfGap != headerAddress) | 720 if (startOfGap != headerAddress) |
721 addToFreeList(startOfGap, headerAddress - startOfGap); | 721 addToFreeList(startOfGap, headerAddress - startOfGap); |
722 | 722 |
723 headerAddress += size; | 723 headerAddress += size; |
724 startOfGap = headerAddress; | 724 startOfGap = headerAddress; |
725 } | 725 } |
726 | 726 |
727 if (startOfGap != page->payloadEnd()) | 727 if (startOfGap != page->payloadEnd()) |
728 addToFreeList(startOfGap, page->payloadEnd() - startOfGap); | 728 addToFreeList(startOfGap, page->payloadEnd() - startOfGap); |
729 } | 729 } |
730 Heap::decreaseAllocatedObjectSize(freedSize); | 730 Heap::decreaseAllocatedObjectSize(freedSize); |
731 ASSERT(m_promptlyFreedSize == freedSize); | 731 ASSERT(m_promptlyFreedSize == freedSize); |
732 m_promptlyFreedSize = 0; | 732 m_promptlyFreedSize = 0; |
733 return true; | 733 return true; |
734 } | 734 } |
735 | 735 |
736 void NormalPageHeap::promptlyFreeObject(HeapObjectHeader* header) | 736 void NormalPageHeap::promptlyFreeObject(HeapObjectHeader* header) |
737 { | 737 { |
738 ASSERT(!threadState()->sweepForbidden()); | 738 ASSERT(!threadState()->sweepForbidden()); |
739 header->checkHeader(); | 739 ASSERT(header->checkHeader()); |
740 Address address = reinterpret_cast<Address>(header); | 740 Address address = reinterpret_cast<Address>(header); |
741 Address payload = header->payload(); | 741 Address payload = header->payload(); |
742 size_t size = header->size(); | 742 size_t size = header->size(); |
743 size_t payloadSize = header->payloadSize(); | 743 size_t payloadSize = header->payloadSize(); |
744 ASSERT(size > 0); | 744 ASSERT(size > 0); |
745 ASSERT(pageFromObject(address) == findPageFromAddress(address)); | 745 ASSERT(pageFromObject(address) == findPageFromAddress(address)); |
746 | 746 |
747 { | 747 { |
748 ThreadState::SweepForbiddenScope forbiddenScope(threadState()); | 748 ThreadState::SweepForbiddenScope forbiddenScope(threadState()); |
749 header->finalize(payload, payloadSize); | 749 header->finalize(payload, payloadSize); |
(...skipping 13 matching lines...) Expand all Loading... |
763 } | 763 } |
764 | 764 |
765 m_promptlyFreedSize += size; | 765 m_promptlyFreedSize += size; |
766 } | 766 } |
767 | 767 |
768 bool NormalPageHeap::expandObject(HeapObjectHeader* header, size_t newSize) | 768 bool NormalPageHeap::expandObject(HeapObjectHeader* header, size_t newSize) |
769 { | 769 { |
770 // It's possible that Vector requests a smaller expanded size because | 770 // It's possible that Vector requests a smaller expanded size because |
771 // Vector::shrinkCapacity can set a capacity smaller than the actual payload | 771 // Vector::shrinkCapacity can set a capacity smaller than the actual payload |
772 // size. | 772 // size. |
773 header->checkHeader(); | 773 ASSERT(header->checkHeader()); |
774 if (header->payloadSize() >= newSize) | 774 if (header->payloadSize() >= newSize) |
775 return true; | 775 return true; |
776 size_t allocationSize = Heap::allocationSizeFromSize(newSize); | 776 size_t allocationSize = Heap::allocationSizeFromSize(newSize); |
777 ASSERT(allocationSize > header->size()); | 777 ASSERT(allocationSize > header->size()); |
778 size_t expandSize = allocationSize - header->size(); | 778 size_t expandSize = allocationSize - header->size(); |
779 if (header->payloadEnd() == m_currentAllocationPoint && expandSize <= m_rema
iningAllocationSize) { | 779 if (header->payloadEnd() == m_currentAllocationPoint && expandSize <= m_rema
iningAllocationSize) { |
780 m_currentAllocationPoint += expandSize; | 780 m_currentAllocationPoint += expandSize; |
781 m_remainingAllocationSize -= expandSize; | 781 m_remainingAllocationSize -= expandSize; |
782 | 782 |
783 // Unpoison the memory used for the object (payload). | 783 // Unpoison the memory used for the object (payload). |
784 ASAN_UNPOISON_MEMORY_REGION(header->payloadEnd(), expandSize); | 784 ASAN_UNPOISON_MEMORY_REGION(header->payloadEnd(), expandSize); |
785 FILL_ZERO_IF_NOT_PRODUCTION(header->payloadEnd(), expandSize); | 785 FILL_ZERO_IF_NOT_PRODUCTION(header->payloadEnd(), expandSize); |
786 header->setSize(allocationSize); | 786 header->setSize(allocationSize); |
787 ASSERT(findPageFromAddress(header->payloadEnd() - 1)); | 787 ASSERT(findPageFromAddress(header->payloadEnd() - 1)); |
788 return true; | 788 return true; |
789 } | 789 } |
790 return false; | 790 return false; |
791 } | 791 } |
792 | 792 |
793 bool NormalPageHeap::shrinkObject(HeapObjectHeader* header, size_t newSize) | 793 bool NormalPageHeap::shrinkObject(HeapObjectHeader* header, size_t newSize) |
794 { | 794 { |
795 header->checkHeader(); | 795 ASSERT(header->checkHeader()); |
796 ASSERT(header->payloadSize() > newSize); | 796 ASSERT(header->payloadSize() > newSize); |
797 size_t allocationSize = Heap::allocationSizeFromSize(newSize); | 797 size_t allocationSize = Heap::allocationSizeFromSize(newSize); |
798 ASSERT(header->size() > allocationSize); | 798 ASSERT(header->size() > allocationSize); |
799 size_t shrinkSize = header->size() - allocationSize; | 799 size_t shrinkSize = header->size() - allocationSize; |
800 if (header->payloadEnd() == m_currentAllocationPoint) { | 800 if (header->payloadEnd() == m_currentAllocationPoint) { |
801 m_currentAllocationPoint -= shrinkSize; | 801 m_currentAllocationPoint -= shrinkSize; |
802 m_remainingAllocationSize += shrinkSize; | 802 m_remainingAllocationSize += shrinkSize; |
803 FILL_ZERO_IF_PRODUCTION(m_currentAllocationPoint, shrinkSize); | 803 FILL_ZERO_IF_PRODUCTION(m_currentAllocationPoint, shrinkSize); |
804 ASAN_POISON_MEMORY_REGION(m_currentAllocationPoint, shrinkSize); | 804 ASAN_POISON_MEMORY_REGION(m_currentAllocationPoint, shrinkSize); |
805 header->setSize(allocationSize); | 805 header->setSize(allocationSize); |
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1001 #if ENABLE(ASSERT) | 1001 #if ENABLE(ASSERT) |
1002 // Verify that the allocated PageMemory is expectedly zeroed. | 1002 // Verify that the allocated PageMemory is expectedly zeroed. |
1003 for (size_t i = 0; i < largeObjectSize; ++i) | 1003 for (size_t i = 0; i < largeObjectSize; ++i) |
1004 ASSERT(!largeObjectAddress[i]); | 1004 ASSERT(!largeObjectAddress[i]); |
1005 #endif | 1005 #endif |
1006 ASSERT(gcInfoIndex > 0); | 1006 ASSERT(gcInfoIndex > 0); |
1007 HeapObjectHeader* header = new (NotNull, headerAddress) HeapObjectHeader(lar
geObjectSizeInHeader, gcInfoIndex); | 1007 HeapObjectHeader* header = new (NotNull, headerAddress) HeapObjectHeader(lar
geObjectSizeInHeader, gcInfoIndex); |
1008 Address result = headerAddress + sizeof(*header); | 1008 Address result = headerAddress + sizeof(*header); |
1009 ASSERT(!(reinterpret_cast<uintptr_t>(result) & allocationMask)); | 1009 ASSERT(!(reinterpret_cast<uintptr_t>(result) & allocationMask)); |
1010 LargeObjectPage* largeObject = new (largeObjectAddress) LargeObjectPage(page
Memory, this, allocationSize); | 1010 LargeObjectPage* largeObject = new (largeObjectAddress) LargeObjectPage(page
Memory, this, allocationSize); |
1011 header->checkHeader(); | 1011 ASSERT(header->checkHeader()); |
1012 | 1012 |
1013 // Poison the object header and allocationGranularity bytes after the object | 1013 // Poison the object header and allocationGranularity bytes after the object |
1014 ASAN_POISON_MEMORY_REGION(header, sizeof(*header)); | 1014 ASAN_POISON_MEMORY_REGION(header, sizeof(*header)); |
1015 ASAN_POISON_MEMORY_REGION(largeObject->address() + largeObject->size(), allo
cationGranularity); | 1015 ASAN_POISON_MEMORY_REGION(largeObject->address() + largeObject->size(), allo
cationGranularity); |
1016 | 1016 |
1017 largeObject->link(&m_firstPage); | 1017 largeObject->link(&m_firstPage); |
1018 | 1018 |
1019 Heap::increaseAllocatedSpace(largeObject->size()); | 1019 Heap::increaseAllocatedSpace(largeObject->size()); |
1020 Heap::increaseAllocatedObjectSize(largeObject->size()); | 1020 Heap::increaseAllocatedObjectSize(largeObject->size()); |
1021 return result; | 1021 return result; |
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1201 | 1201 |
1202 size_t NormalPage::objectPayloadSizeForTesting() | 1202 size_t NormalPage::objectPayloadSizeForTesting() |
1203 { | 1203 { |
1204 size_t objectPayloadSize = 0; | 1204 size_t objectPayloadSize = 0; |
1205 Address headerAddress = payload(); | 1205 Address headerAddress = payload(); |
1206 markAsSwept(); | 1206 markAsSwept(); |
1207 ASSERT(headerAddress != payloadEnd()); | 1207 ASSERT(headerAddress != payloadEnd()); |
1208 do { | 1208 do { |
1209 HeapObjectHeader* header = reinterpret_cast<HeapObjectHeader*>(headerAdd
ress); | 1209 HeapObjectHeader* header = reinterpret_cast<HeapObjectHeader*>(headerAdd
ress); |
1210 if (!header->isFree()) { | 1210 if (!header->isFree()) { |
1211 header->checkHeader(); | 1211 ASSERT(header->checkHeader()); |
1212 objectPayloadSize += header->payloadSize(); | 1212 objectPayloadSize += header->payloadSize(); |
1213 } | 1213 } |
1214 ASSERT(header->size() < blinkPagePayloadSize()); | 1214 ASSERT(header->size() < blinkPagePayloadSize()); |
1215 headerAddress += header->size(); | 1215 headerAddress += header->size(); |
1216 ASSERT(headerAddress <= payloadEnd()); | 1216 ASSERT(headerAddress <= payloadEnd()); |
1217 } while (headerAddress < payloadEnd()); | 1217 } while (headerAddress < payloadEnd()); |
1218 return objectPayloadSize; | 1218 return objectPayloadSize; |
1219 } | 1219 } |
1220 | 1220 |
1221 bool NormalPage::isEmpty() | 1221 bool NormalPage::isEmpty() |
(...skipping 23 matching lines...) Expand all Loading... |
1245 if (header->isFree()) { | 1245 if (header->isFree()) { |
1246 size_t size = header->size(); | 1246 size_t size = header->size(); |
1247 // Zero the memory in the free list header to maintain the | 1247 // Zero the memory in the free list header to maintain the |
1248 // invariant that memory on the free list is zero filled. | 1248 // invariant that memory on the free list is zero filled. |
1249 // The rest of the memory is already on the free list and is | 1249 // The rest of the memory is already on the free list and is |
1250 // therefore already zero filled. | 1250 // therefore already zero filled. |
1251 FILL_ZERO_IF_PRODUCTION(headerAddress, size < sizeof(FreeListEntry)
? size : sizeof(FreeListEntry)); | 1251 FILL_ZERO_IF_PRODUCTION(headerAddress, size < sizeof(FreeListEntry)
? size : sizeof(FreeListEntry)); |
1252 headerAddress += size; | 1252 headerAddress += size; |
1253 continue; | 1253 continue; |
1254 } | 1254 } |
1255 header->checkHeader(); | 1255 ASSERT(header->checkHeader()); |
1256 | 1256 |
1257 if (!header->isMarked()) { | 1257 if (!header->isMarked()) { |
1258 size_t size = header->size(); | 1258 size_t size = header->size(); |
1259 // This is a fast version of header->payloadSize(). | 1259 // This is a fast version of header->payloadSize(). |
1260 size_t payloadSize = size - sizeof(HeapObjectHeader); | 1260 size_t payloadSize = size - sizeof(HeapObjectHeader); |
1261 Address payload = header->payload(); | 1261 Address payload = header->payload(); |
1262 // For ASan we unpoison the specific object when calling the | 1262 // For ASan we unpoison the specific object when calling the |
1263 // finalizer and poison it again when done to allow the object's own | 1263 // finalizer and poison it again when done to allow the object's own |
1264 // finalizer to operate on the object. Given all other unmarked | 1264 // finalizer to operate on the object. Given all other unmarked |
1265 // objects are poisoned, ASan will detect an error if the finalizer | 1265 // objects are poisoned, ASan will detect an error if the finalizer |
(...skipping 26 matching lines...) Expand all Loading... |
1292 size_t markedObjectSize = 0; | 1292 size_t markedObjectSize = 0; |
1293 for (Address headerAddress = payload(); headerAddress < payloadEnd();) { | 1293 for (Address headerAddress = payload(); headerAddress < payloadEnd();) { |
1294 HeapObjectHeader* header = reinterpret_cast<HeapObjectHeader*>(headerAdd
ress); | 1294 HeapObjectHeader* header = reinterpret_cast<HeapObjectHeader*>(headerAdd
ress); |
1295 ASSERT(header->size() < blinkPagePayloadSize()); | 1295 ASSERT(header->size() < blinkPagePayloadSize()); |
1296 // Check if a free list entry first since we cannot call | 1296 // Check if a free list entry first since we cannot call |
1297 // isMarked on a free list entry. | 1297 // isMarked on a free list entry. |
1298 if (header->isFree()) { | 1298 if (header->isFree()) { |
1299 headerAddress += header->size(); | 1299 headerAddress += header->size(); |
1300 continue; | 1300 continue; |
1301 } | 1301 } |
1302 header->checkHeader(); | 1302 ASSERT(header->checkHeader()); |
1303 if (header->isMarked()) { | 1303 if (header->isMarked()) { |
1304 header->unmark(); | 1304 header->unmark(); |
1305 markedObjectSize += header->size(); | 1305 markedObjectSize += header->size(); |
1306 } else { | 1306 } else { |
1307 header->markDead(); | 1307 header->markDead(); |
1308 } | 1308 } |
1309 headerAddress += header->size(); | 1309 headerAddress += header->size(); |
1310 } | 1310 } |
1311 if (markedObjectSize) | 1311 if (markedObjectSize) |
1312 Heap::increaseMarkedObjectSize(markedObjectSize); | 1312 Heap::increaseMarkedObjectSize(markedObjectSize); |
1313 } | 1313 } |
1314 | 1314 |
1315 void NormalPage::makeConsistentForMutator() | 1315 void NormalPage::makeConsistentForMutator() |
1316 { | 1316 { |
1317 Address startOfGap = payload(); | 1317 Address startOfGap = payload(); |
1318 for (Address headerAddress = payload(); headerAddress < payloadEnd();) { | 1318 for (Address headerAddress = payload(); headerAddress < payloadEnd();) { |
1319 HeapObjectHeader* header = reinterpret_cast<HeapObjectHeader*>(headerAdd
ress); | 1319 HeapObjectHeader* header = reinterpret_cast<HeapObjectHeader*>(headerAdd
ress); |
1320 ASSERT(header->size() < blinkPagePayloadSize()); | 1320 ASSERT(header->size() < blinkPagePayloadSize()); |
1321 if (header->isPromptlyFreed()) | 1321 if (header->isPromptlyFreed()) |
1322 heapForNormalPage()->decreasePromptlyFreedSize(header->size()); | 1322 heapForNormalPage()->decreasePromptlyFreedSize(header->size()); |
1323 if (header->isFree()) { | 1323 if (header->isFree()) { |
1324 headerAddress += header->size(); | 1324 headerAddress += header->size(); |
1325 continue; | 1325 continue; |
1326 } | 1326 } |
1327 header->checkHeader(); | 1327 ASSERT(header->checkHeader()); |
1328 | 1328 |
1329 if (startOfGap != headerAddress) | 1329 if (startOfGap != headerAddress) |
1330 heapForNormalPage()->addToFreeList(startOfGap, headerAddress - start
OfGap); | 1330 heapForNormalPage()->addToFreeList(startOfGap, headerAddress - start
OfGap); |
1331 if (header->isMarked()) | 1331 if (header->isMarked()) |
1332 header->unmark(); | 1332 header->unmark(); |
1333 headerAddress += header->size(); | 1333 headerAddress += header->size(); |
1334 startOfGap = headerAddress; | 1334 startOfGap = headerAddress; |
1335 } | 1335 } |
1336 if (startOfGap != payloadEnd()) | 1336 if (startOfGap != payloadEnd()) |
1337 heapForNormalPage()->addToFreeList(startOfGap, payloadEnd() - startOfGap
); | 1337 heapForNormalPage()->addToFreeList(startOfGap, payloadEnd() - startOfGap
); |
1338 } | 1338 } |
1339 | 1339 |
1340 #if defined(ADDRESS_SANITIZER) | 1340 #if defined(ADDRESS_SANITIZER) |
1341 void NormalPage::poisonObjects(ObjectsToPoison objectsToPoison, Poisoning poison
ing) | 1341 void NormalPage::poisonObjects(ObjectsToPoison objectsToPoison, Poisoning poison
ing) |
1342 { | 1342 { |
1343 for (Address headerAddress = payload(); headerAddress < payloadEnd();) { | 1343 for (Address headerAddress = payload(); headerAddress < payloadEnd();) { |
1344 HeapObjectHeader* header = reinterpret_cast<HeapObjectHeader*>(headerAdd
ress); | 1344 HeapObjectHeader* header = reinterpret_cast<HeapObjectHeader*>(headerAdd
ress); |
1345 ASSERT(header->size() < blinkPagePayloadSize()); | 1345 ASSERT(header->size() < blinkPagePayloadSize()); |
1346 // Check if a free list entry first since we cannot call | 1346 // Check if a free list entry first since we cannot call |
1347 // isMarked on a free list entry. | 1347 // isMarked on a free list entry. |
1348 if (header->isFree()) { | 1348 if (header->isFree()) { |
1349 headerAddress += header->size(); | 1349 headerAddress += header->size(); |
1350 continue; | 1350 continue; |
1351 } | 1351 } |
1352 header->checkHeader(); | 1352 ASSERT(header->checkHeader()); |
1353 if (objectsToPoison == MarkedAndUnmarked || !header->isMarked()) { | 1353 if (objectsToPoison == MarkedAndUnmarked || !header->isMarked()) { |
1354 if (poisoning == SetPoison) | 1354 if (poisoning == SetPoison) |
1355 ASAN_POISON_MEMORY_REGION(header->payload(), header->payloadSize
()); | 1355 ASAN_POISON_MEMORY_REGION(header->payload(), header->payloadSize
()); |
1356 else | 1356 else |
1357 ASAN_UNPOISON_MEMORY_REGION(header->payload(), header->payloadSi
ze()); | 1357 ASAN_UNPOISON_MEMORY_REGION(header->payload(), header->payloadSi
ze()); |
1358 } | 1358 } |
1359 headerAddress += header->size(); | 1359 headerAddress += header->size(); |
1360 } | 1360 } |
1361 } | 1361 } |
1362 #endif | 1362 #endif |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1418 ASSERT(mapIndex > 0); | 1418 ASSERT(mapIndex > 0); |
1419 byte = m_objectStartBitMap[--mapIndex]; | 1419 byte = m_objectStartBitMap[--mapIndex]; |
1420 } | 1420 } |
1421 int leadingZeroes = numberOfLeadingZeroes(byte); | 1421 int leadingZeroes = numberOfLeadingZeroes(byte); |
1422 objectStartNumber = (mapIndex * 8) + 7 - leadingZeroes; | 1422 objectStartNumber = (mapIndex * 8) + 7 - leadingZeroes; |
1423 objectOffset = objectStartNumber * allocationGranularity; | 1423 objectOffset = objectStartNumber * allocationGranularity; |
1424 Address objectAddress = objectOffset + payload(); | 1424 Address objectAddress = objectOffset + payload(); |
1425 HeapObjectHeader* header = reinterpret_cast<HeapObjectHeader*>(objectAddress
); | 1425 HeapObjectHeader* header = reinterpret_cast<HeapObjectHeader*>(objectAddress
); |
1426 if (header->isFree()) | 1426 if (header->isFree()) |
1427 return nullptr; | 1427 return nullptr; |
1428 header->checkHeader(); | 1428 ASSERT(header->checkHeader()); |
1429 return header; | 1429 return header; |
1430 } | 1430 } |
1431 | 1431 |
1432 #if ENABLE(ASSERT) | 1432 #if ENABLE(ASSERT) |
1433 static bool isUninitializedMemory(void* objectPointer, size_t objectSize) | 1433 static bool isUninitializedMemory(void* objectPointer, size_t objectSize) |
1434 { | 1434 { |
1435 // Scan through the object's fields and check that they are all zero. | 1435 // Scan through the object's fields and check that they are all zero. |
1436 Address* objectFields = reinterpret_cast<Address*>(objectPointer); | 1436 Address* objectFields = reinterpret_cast<Address*>(objectPointer); |
1437 for (size_t i = 0; i < objectSize / sizeof(Address); ++i) { | 1437 for (size_t i = 0; i < objectSize / sizeof(Address); ++i) { |
1438 if (objectFields[i] != 0) | 1438 if (objectFields[i] != 0) |
1439 return false; | 1439 return false; |
1440 } | 1440 } |
1441 return true; | 1441 return true; |
1442 } | 1442 } |
1443 #endif | 1443 #endif |
1444 | 1444 |
1445 static void markPointer(Visitor* visitor, HeapObjectHeader* header) | 1445 static void markPointer(Visitor* visitor, HeapObjectHeader* header) |
1446 { | 1446 { |
1447 header->checkHeader(); | 1447 ASSERT(header->checkHeader()); |
1448 const GCInfo* gcInfo = Heap::gcInfo(header->gcInfoIndex()); | 1448 const GCInfo* gcInfo = Heap::gcInfo(header->gcInfoIndex()); |
1449 if (gcInfo->hasVTable() && !vTableInitialized(header->payload())) { | 1449 if (gcInfo->hasVTable() && !vTableInitialized(header->payload())) { |
1450 // We hit this branch when a GC strikes before GarbageCollected<>'s | 1450 // We hit this branch when a GC strikes before GarbageCollected<>'s |
1451 // constructor runs. | 1451 // constructor runs. |
1452 // | 1452 // |
1453 // class A : public GarbageCollected<A> { virtual void f() = 0; }; | 1453 // class A : public GarbageCollected<A> { virtual void f() = 0; }; |
1454 // class B : public A { | 1454 // class B : public A { |
1455 // B() : A(foo()) { }; | 1455 // B() : A(foo()) { }; |
1456 // }; | 1456 // }; |
1457 // | 1457 // |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1540 { | 1540 { |
1541 HeapObjectHeader* header = nullptr; | 1541 HeapObjectHeader* header = nullptr; |
1542 for (Address addr = payload(); addr < payloadEnd(); addr += header->size())
{ | 1542 for (Address addr = payload(); addr < payloadEnd(); addr += header->size())
{ |
1543 header = reinterpret_cast<HeapObjectHeader*>(addr); | 1543 header = reinterpret_cast<HeapObjectHeader*>(addr); |
1544 if (json) | 1544 if (json) |
1545 json->pushInteger(header->encodedSize()); | 1545 json->pushInteger(header->encodedSize()); |
1546 if (header->isFree()) { | 1546 if (header->isFree()) { |
1547 info->freeSize += header->size(); | 1547 info->freeSize += header->size(); |
1548 continue; | 1548 continue; |
1549 } | 1549 } |
1550 header->checkHeader(); | 1550 ASSERT(header->checkHeader()); |
1551 | 1551 |
1552 size_t tag = info->getClassTag(Heap::gcInfo(header->gcInfoIndex())); | 1552 size_t tag = info->getClassTag(Heap::gcInfo(header->gcInfoIndex())); |
1553 size_t age = header->age(); | 1553 size_t age = header->age(); |
1554 if (json) | 1554 if (json) |
1555 json->pushInteger(tag); | 1555 json->pushInteger(tag); |
1556 if (header->isMarked()) { | 1556 if (header->isMarked()) { |
1557 info->liveCount[tag] += 1; | 1557 info->liveCount[tag] += 1; |
1558 info->liveSize[tag] += header->size(); | 1558 info->liveSize[tag] += header->size(); |
1559 // Count objects that are live when promoted to the final generation
. | 1559 // Count objects that are live when promoted to the final generation
. |
1560 if (age == maxHeapObjectAge - 1) | 1560 if (age == maxHeapObjectAge - 1) |
(...skipping 882 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2443 size_t Heap::s_allocatedObjectSize = 0; | 2443 size_t Heap::s_allocatedObjectSize = 0; |
2444 size_t Heap::s_allocatedSpace = 0; | 2444 size_t Heap::s_allocatedSpace = 0; |
2445 size_t Heap::s_markedObjectSize = 0; | 2445 size_t Heap::s_markedObjectSize = 0; |
2446 // We don't want to use 0 KB for the initial value because it may end up | 2446 // We don't want to use 0 KB for the initial value because it may end up |
2447 // triggering the first GC of some thread too prematurely. | 2447 // triggering the first GC of some thread too prematurely. |
2448 size_t Heap::s_estimatedLiveObjectSize = 512 * 1024; | 2448 size_t Heap::s_estimatedLiveObjectSize = 512 * 1024; |
2449 size_t Heap::s_externalObjectSizeAtLastGC = 0; | 2449 size_t Heap::s_externalObjectSizeAtLastGC = 0; |
2450 double Heap::s_estimatedMarkingTimePerByte = 0.0; | 2450 double Heap::s_estimatedMarkingTimePerByte = 0.0; |
2451 | 2451 |
2452 } // namespace blink | 2452 } // namespace blink |
OLD | NEW |