| 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 438 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 449 ThreadState::resumeThreads(); | 449 ThreadState::resumeThreads(); |
| 450 } | 450 } |
| 451 } | 451 } |
| 452 | 452 |
| 453 private: | 453 private: |
| 454 ThreadState* m_state; | 454 ThreadState* m_state; |
| 455 ThreadState::SafePointScope m_safePointScope; | 455 ThreadState::SafePointScope m_safePointScope; |
| 456 bool m_parkedAllThreads; // False if we fail to park all threads | 456 bool m_parkedAllThreads; // False if we fail to park all threads |
| 457 }; | 457 }; |
| 458 | 458 |
| 459 NO_SANITIZE_ADDRESS inline | 459 inline bool HeapObjectHeader::isMarked() const |
| 460 bool HeapObjectHeader::isMarked() const | |
| 461 { | 460 { |
| 462 checkHeader(); | 461 checkHeader(); |
| 463 return m_size & markBitMask; | 462 return pageHeaderFromObject(this)->objectIsMarked(reinterpret_cast<Address>(
const_cast<HeapObjectHeader*>(this))); |
| 464 } | 463 } |
| 465 | 464 |
| 466 NO_SANITIZE_ADDRESS inline | 465 NO_SANITIZE_ADDRESS inline |
| 467 void HeapObjectHeader::unmark() | |
| 468 { | |
| 469 checkHeader(); | |
| 470 m_size &= ~markBitMask; | |
| 471 } | |
| 472 | |
| 473 NO_SANITIZE_ADDRESS inline | |
| 474 bool HeapObjectHeader::hasDeadMark() const | 466 bool HeapObjectHeader::hasDeadMark() const |
| 475 { | 467 { |
| 476 checkHeader(); | 468 checkHeader(); |
| 477 return m_size & deadBitMask; | 469 return m_size & deadBitMask; |
| 478 } | 470 } |
| 479 | 471 |
| 480 NO_SANITIZE_ADDRESS inline | 472 NO_SANITIZE_ADDRESS inline |
| 481 void HeapObjectHeader::clearDeadMark() | 473 void HeapObjectHeader::clearDeadMark() |
| 482 { | 474 { |
| 483 checkHeader(); | 475 checkHeader(); |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 532 // This happens right after sweeping the page and before the thread commence
s execution. | 524 // This happens right after sweeping the page and before the thread commence
s execution. |
| 533 } | 525 } |
| 534 | 526 |
| 535 NO_SANITIZE_ADDRESS | 527 NO_SANITIZE_ADDRESS |
| 536 void FinalizedHeapObjectHeader::finalize() | 528 void FinalizedHeapObjectHeader::finalize() |
| 537 { | 529 { |
| 538 HeapObjectHeader::finalize(m_gcInfo, payload(), payloadSize()); | 530 HeapObjectHeader::finalize(m_gcInfo, payload(), payloadSize()); |
| 539 } | 531 } |
| 540 | 532 |
| 541 template<typename Header> | 533 template<typename Header> |
| 542 void LargeHeapObject<Header>::unmark() | |
| 543 { | |
| 544 return heapObjectHeader()->unmark(); | |
| 545 } | |
| 546 | |
| 547 template<typename Header> | |
| 548 bool LargeHeapObject<Header>::isMarked() | 534 bool LargeHeapObject<Header>::isMarked() |
| 549 { | 535 { |
| 550 return heapObjectHeader()->isMarked(); | 536 return heapObjectHeader()->isMarked(); |
| 551 } | 537 } |
| 552 | 538 |
| 553 template<typename Header> | 539 template<typename Header> |
| 554 void LargeHeapObject<Header>::setDeadMark() | 540 void LargeHeapObject<Header>::setDeadMark() |
| 555 { | 541 { |
| 556 heapObjectHeader()->setDeadMark(); | 542 heapObjectHeader()->setDeadMark(); |
| 557 } | 543 } |
| (...skipping 607 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1165 PageMemory* memory = page->storage(); | 1151 PageMemory* memory = page->storage(); |
| 1166 ASSERT(memory); | 1152 ASSERT(memory); |
| 1167 page->~BaseHeapPage(); | 1153 page->~BaseHeapPage(); |
| 1168 delete memory; | 1154 delete memory; |
| 1169 } | 1155 } |
| 1170 } | 1156 } |
| 1171 } | 1157 } |
| 1172 | 1158 |
| 1173 void OrphanedPagePool::addOrphanedPage(int index, BaseHeapPage* page) | 1159 void OrphanedPagePool::addOrphanedPage(int index, BaseHeapPage* page) |
| 1174 { | 1160 { |
| 1161 page->clearObjectMarkBitMap(); |
| 1175 page->markOrphaned(); | 1162 page->markOrphaned(); |
| 1176 PoolEntry* entry = new PoolEntry(page, m_pool[index]); | 1163 PoolEntry* entry = new PoolEntry(page, m_pool[index]); |
| 1177 m_pool[index] = entry; | 1164 m_pool[index] = entry; |
| 1178 } | 1165 } |
| 1179 | 1166 |
| 1180 NO_SANITIZE_ADDRESS | 1167 NO_SANITIZE_ADDRESS |
| 1181 void OrphanedPagePool::decommitOrphanedPages() | 1168 void OrphanedPagePool::decommitOrphanedPages() |
| 1182 { | 1169 { |
| 1183 #if ENABLE(ASSERT) | 1170 #if ENABLE(ASSERT) |
| 1184 // No locking needed as all threads are at safepoints at this point in time. | 1171 // No locking needed as all threads are at safepoints at this point in time. |
| (...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1407 } | 1394 } |
| 1408 | 1395 |
| 1409 template<typename Header> | 1396 template<typename Header> |
| 1410 void ThreadHeap<Header>::sweepLargePages() | 1397 void ThreadHeap<Header>::sweepLargePages() |
| 1411 { | 1398 { |
| 1412 TRACE_EVENT0("blink_gc", "ThreadHeap::sweepLargePages"); | 1399 TRACE_EVENT0("blink_gc", "ThreadHeap::sweepLargePages"); |
| 1413 LargeHeapObject<Header>** previousNext = &m_firstLargeHeapObject; | 1400 LargeHeapObject<Header>** previousNext = &m_firstLargeHeapObject; |
| 1414 for (LargeHeapObject<Header>* current = m_firstLargeHeapObject; current;) { | 1401 for (LargeHeapObject<Header>* current = m_firstLargeHeapObject; current;) { |
| 1415 if (current->isMarked()) { | 1402 if (current->isMarked()) { |
| 1416 Heap::increaseMarkedObjectSize(current->size()); | 1403 Heap::increaseMarkedObjectSize(current->size()); |
| 1417 current->unmark(); | |
| 1418 previousNext = ¤t->m_next; | 1404 previousNext = ¤t->m_next; |
| 1419 current = current->next(); | 1405 current = current->next(); |
| 1420 } else { | 1406 } else { |
| 1421 LargeHeapObject<Header>* next = current->next(); | 1407 LargeHeapObject<Header>* next = current->next(); |
| 1422 freeLargeObject(current, previousNext); | 1408 freeLargeObject(current, previousNext); |
| 1423 current = next; | 1409 current = next; |
| 1424 } | 1410 } |
| 1425 } | 1411 } |
| 1426 } | 1412 } |
| 1427 | 1413 |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1489 template<typename Header> | 1475 template<typename Header> |
| 1490 void ThreadHeap<Header>::makeConsistentForSweeping() | 1476 void ThreadHeap<Header>::makeConsistentForSweeping() |
| 1491 { | 1477 { |
| 1492 if (ownsNonEmptyAllocationArea()) | 1478 if (ownsNonEmptyAllocationArea()) |
| 1493 addToFreeList(currentAllocationPoint(), remainingAllocationSize()); | 1479 addToFreeList(currentAllocationPoint(), remainingAllocationSize()); |
| 1494 setAllocationPoint(0, 0); | 1480 setAllocationPoint(0, 0); |
| 1495 clearFreeLists(); | 1481 clearFreeLists(); |
| 1496 } | 1482 } |
| 1497 | 1483 |
| 1498 template<typename Header> | 1484 template<typename Header> |
| 1499 void ThreadHeap<Header>::clearLiveAndMarkDead() | 1485 void ThreadHeap<Header>::makeUnmarkedObjectsDead() |
| 1500 { | 1486 { |
| 1501 ASSERT(isConsistentForSweeping()); | 1487 ASSERT(isConsistentForSweeping()); |
| 1502 for (HeapPage<Header>* page = m_firstPage; page; page = page->next()) | 1488 for (HeapPage<Header>* page = m_firstPage; page; page = page->next()) { |
| 1503 page->clearLiveAndMarkDead(); | 1489 page->makeUnmarkedObjectsDead(); |
| 1490 } |
| 1504 for (LargeHeapObject<Header>* current = m_firstLargeHeapObject; current; cur
rent = current->next()) { | 1491 for (LargeHeapObject<Header>* current = m_firstLargeHeapObject; current; cur
rent = current->next()) { |
| 1505 if (current->isMarked()) | 1492 if (!current->isMarked()) |
| 1506 current->unmark(); | |
| 1507 else | |
| 1508 current->setDeadMark(); | 1493 current->setDeadMark(); |
| 1509 } | 1494 } |
| 1510 } | 1495 } |
| 1511 | 1496 |
| 1512 template<typename Header> | 1497 template<typename Header> |
| 1498 void ThreadHeap<Header>::clearObjectMarkBitMaps() |
| 1499 { |
| 1500 ASSERT(isConsistentForSweeping()); |
| 1501 for (HeapPage<Header>* page = m_firstPage; page; page = page->next()) { |
| 1502 page->clearObjectMarkBitMap(); |
| 1503 } |
| 1504 for (LargeHeapObject<Header>* current = m_firstLargeHeapObject; current; cur
rent = current->next()) { |
| 1505 current->clearObjectMarkBitMap(); |
| 1506 } |
| 1507 } |
| 1508 |
| 1509 template<typename Header> |
| 1513 void ThreadHeap<Header>::clearFreeLists() | 1510 void ThreadHeap<Header>::clearFreeLists() |
| 1514 { | 1511 { |
| 1515 m_promptlyFreedCount = 0; | 1512 m_promptlyFreedCount = 0; |
| 1516 m_freeList.clear(); | 1513 m_freeList.clear(); |
| 1517 } | 1514 } |
| 1518 | 1515 |
| 1519 template<typename Header> | 1516 template<typename Header> |
| 1520 void FreeList<Header>::clear() | 1517 void FreeList<Header>::clear() |
| 1521 { | 1518 { |
| 1522 m_biggestFreeListIndex = 0; | 1519 m_biggestFreeListIndex = 0; |
| (...skipping 19 matching lines...) Expand all Loading... |
| 1542 HeapPage<Header>::HeapPage(PageMemory* storage, ThreadHeap<Header>* heap, const
GCInfo* gcInfo) | 1539 HeapPage<Header>::HeapPage(PageMemory* storage, ThreadHeap<Header>* heap, const
GCInfo* gcInfo) |
| 1543 : BaseHeapPage(storage, gcInfo, heap->threadState()) | 1540 : BaseHeapPage(storage, gcInfo, heap->threadState()) |
| 1544 , m_next(0) | 1541 , m_next(0) |
| 1545 { | 1542 { |
| 1546 COMPILE_ASSERT(!(sizeof(HeapPage<Header>) & allocationMask), page_header_inc
orrectly_aligned); | 1543 COMPILE_ASSERT(!(sizeof(HeapPage<Header>) & allocationMask), page_header_inc
orrectly_aligned); |
| 1547 m_objectStartBitMapComputed = false; | 1544 m_objectStartBitMapComputed = false; |
| 1548 ASSERT(isPageHeaderAddress(reinterpret_cast<Address>(this))); | 1545 ASSERT(isPageHeaderAddress(reinterpret_cast<Address>(this))); |
| 1549 } | 1546 } |
| 1550 | 1547 |
| 1551 template<typename Header> | 1548 template<typename Header> |
| 1549 void HeapPage<Header>::clearObjectMarkBitMap() |
| 1550 { |
| 1551 memset(&m_objectMarkBitMap, 0, reservedForObjectMarkBitMap); |
| 1552 } |
| 1553 |
| 1554 template<typename Header> |
| 1552 void HeapPage<Header>::link(HeapPage** prevNext) | 1555 void HeapPage<Header>::link(HeapPage** prevNext) |
| 1553 { | 1556 { |
| 1554 m_next = *prevNext; | 1557 m_next = *prevNext; |
| 1555 *prevNext = this; | 1558 *prevNext = this; |
| 1556 } | 1559 } |
| 1557 | 1560 |
| 1558 template<typename Header> | 1561 template<typename Header> |
| 1559 void HeapPage<Header>::unlink(ThreadHeap<Header>* heap, HeapPage* unused, HeapPa
ge** prevNext) | 1562 void HeapPage<Header>::unlink(ThreadHeap<Header>* heap, HeapPage* unused, HeapPa
ge** prevNext) |
| 1560 { | 1563 { |
| 1561 *prevNext = unused->m_next; | 1564 *prevNext = unused->m_next; |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1627 // that memory on the freelist is zero filled. | 1630 // that memory on the freelist is zero filled. |
| 1628 memset(headerAddress, 0, size); | 1631 memset(headerAddress, 0, size); |
| 1629 #endif | 1632 #endif |
| 1630 ASAN_POISON_MEMORY_REGION(header->payload(), header->payloadSize()); | 1633 ASAN_POISON_MEMORY_REGION(header->payload(), header->payloadSize()); |
| 1631 headerAddress += size; | 1634 headerAddress += size; |
| 1632 continue; | 1635 continue; |
| 1633 } | 1636 } |
| 1634 | 1637 |
| 1635 if (startOfGap != headerAddress) | 1638 if (startOfGap != headerAddress) |
| 1636 heap->addToFreeList(startOfGap, headerAddress - startOfGap); | 1639 heap->addToFreeList(startOfGap, headerAddress - startOfGap); |
| 1637 header->unmark(); | |
| 1638 headerAddress += header->size(); | 1640 headerAddress += header->size(); |
| 1639 Heap::increaseMarkedObjectSize(header->size()); | 1641 Heap::increaseMarkedObjectSize(header->size()); |
| 1640 startOfGap = headerAddress; | 1642 startOfGap = headerAddress; |
| 1641 } | 1643 } |
| 1642 if (startOfGap != end()) | 1644 if (startOfGap != end()) |
| 1643 heap->addToFreeList(startOfGap, end() - startOfGap); | 1645 heap->addToFreeList(startOfGap, end() - startOfGap); |
| 1644 } | 1646 } |
| 1645 | 1647 |
| 1646 template<typename Header> | 1648 template<typename Header> |
| 1647 void HeapPage<Header>::clearLiveAndMarkDead() | 1649 void HeapPage<Header>::makeUnmarkedObjectsDead() |
| 1648 { | 1650 { |
| 1649 for (Address headerAddress = payload(); headerAddress < end();) { | 1651 for (Address headerAddress = payload(); headerAddress < end();) { |
| 1650 Header* header = reinterpret_cast<Header*>(headerAddress); | 1652 Header* header = reinterpret_cast<Header*>(headerAddress); |
| 1651 ASSERT(header->size() < blinkPagePayloadSize()); | 1653 ASSERT(header->size() < blinkPagePayloadSize()); |
| 1652 // Check if a free list entry first since we cannot call | 1654 // Check if a free list entry first since we cannot call |
| 1653 // isMarked on a free list entry. | 1655 // isMarked on a free list entry. |
| 1654 if (header->isFree()) { | 1656 if (header->isFree()) { |
| 1655 headerAddress += header->size(); | 1657 headerAddress += header->size(); |
| 1656 continue; | 1658 continue; |
| 1657 } | 1659 } |
| 1658 if (header->isMarked()) | 1660 if (!header->isMarked()) |
| 1659 header->unmark(); | |
| 1660 else | |
| 1661 header->setDeadMark(); | 1661 header->setDeadMark(); |
| 1662 headerAddress += header->size(); | 1662 headerAddress += header->size(); |
| 1663 } | 1663 } |
| 1664 } | 1664 } |
| 1665 | 1665 |
| 1666 template<typename Header> | 1666 template<typename Header> |
| 1667 void HeapPage<Header>::populateObjectStartBitMap() | 1667 void HeapPage<Header>::populateObjectStartBitMap() |
| 1668 { | 1668 { |
| 1669 memset(&m_objectStartBitMap, 0, objectStartBitMapSize); | 1669 memset(&m_objectStartBitMap, 0, objectStartBitMapSize); |
| 1670 Address start = payload(); | 1670 Address start = payload(); |
| (...skipping 1173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2844 bool Heap::s_shutdownCalled = false; | 2844 bool Heap::s_shutdownCalled = false; |
| 2845 bool Heap::s_lastGCWasConservative = false; | 2845 bool Heap::s_lastGCWasConservative = false; |
| 2846 FreePagePool* Heap::s_freePagePool; | 2846 FreePagePool* Heap::s_freePagePool; |
| 2847 OrphanedPagePool* Heap::s_orphanedPagePool; | 2847 OrphanedPagePool* Heap::s_orphanedPagePool; |
| 2848 Heap::RegionTree* Heap::s_regionTree = 0; | 2848 Heap::RegionTree* Heap::s_regionTree = 0; |
| 2849 size_t Heap::s_allocatedObjectSize = 0; | 2849 size_t Heap::s_allocatedObjectSize = 0; |
| 2850 size_t Heap::s_allocatedSpace = 0; | 2850 size_t Heap::s_allocatedSpace = 0; |
| 2851 size_t Heap::s_markedObjectSize = 0; | 2851 size_t Heap::s_markedObjectSize = 0; |
| 2852 | 2852 |
| 2853 } // namespace blink | 2853 } // namespace blink |
| OLD | NEW |