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 560 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
571 for (BasePage* page = m_firstPage; page; page = page->next()) { | 571 for (BasePage* page = m_firstPage; page; page = page->next()) { |
572 page->setTerminating(); | 572 page->setTerminating(); |
573 } | 573 } |
574 } | 574 } |
575 | 575 |
576 void BaseHeap::prepareForSweep() | 576 void BaseHeap::prepareForSweep() |
577 { | 577 { |
578 ASSERT(!threadState()->isInGC()); | 578 ASSERT(!threadState()->isInGC()); |
579 ASSERT(!m_firstUnsweptPage); | 579 ASSERT(!m_firstUnsweptPage); |
580 | 580 |
581 #if defined(ADDRESS_SANITIZER) | |
582 for (BasePage* page = m_firstPage; page; page = page->next()) { | |
583 page->poisonUnmarkedObjects(); | |
584 } | |
585 #endif | |
586 | |
581 // Move all pages to a list of unswept pages. | 587 // Move all pages to a list of unswept pages. |
582 m_firstUnsweptPage = m_firstPage; | 588 m_firstUnsweptPage = m_firstPage; |
583 m_firstPage = nullptr; | 589 m_firstPage = nullptr; |
584 } | 590 } |
585 | 591 |
586 Address BaseHeap::lazySweep(size_t allocationSize, size_t gcInfoIndex) | 592 Address BaseHeap::lazySweep(size_t allocationSize, size_t gcInfoIndex) |
587 { | 593 { |
588 // If there are no pages to be swept, return immediately. | 594 // If there are no pages to be swept, return immediately. |
589 if (!m_firstUnsweptPage) | 595 if (!m_firstUnsweptPage) |
590 return nullptr; | 596 return nullptr; |
(...skipping 908 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1499 } | 1505 } |
1500 header->checkHeader(); | 1506 header->checkHeader(); |
1501 | 1507 |
1502 if (!header->isMarked()) { | 1508 if (!header->isMarked()) { |
1503 size_t size = header->size(); | 1509 size_t size = header->size(); |
1504 // This is a fast version of header->payloadSize(). | 1510 // This is a fast version of header->payloadSize(). |
1505 size_t payloadSize = size - sizeof(HeapObjectHeader); | 1511 size_t payloadSize = size - sizeof(HeapObjectHeader); |
1506 Address payload = header->payload(); | 1512 Address payload = header->payload(); |
1507 // For ASan we unpoison the specific object when calling the | 1513 // For ASan we unpoison the specific object when calling the |
1508 // finalizer and poison it again when done to allow the object's own | 1514 // finalizer and poison it again when done to allow the object's own |
1509 // finalizer to operate on the object, but not have other finalizers | 1515 // finalizer to operate on the object. Given all other unmarked |
1510 // be allowed to access it. | 1516 // objects are poisoned, ASan will detech an error if the finalizer |
sof
2015/04/28 09:15:25
nit: s/detech/detect/
| |
1517 // touches any other on-heap object that die at the same GC cycle. | |
1511 ASAN_UNPOISON_MEMORY_REGION(payload, payloadSize); | 1518 ASAN_UNPOISON_MEMORY_REGION(payload, payloadSize); |
1512 header->finalize(payload, payloadSize); | 1519 header->finalize(payload, payloadSize); |
1513 // This memory will be added to the freelist. Maintain the invariant | 1520 // This memory will be added to the freelist. Maintain the invariant |
1514 // that memory on the freelist is zero filled. | 1521 // that memory on the freelist is zero filled. |
1515 FILL_ZERO_IF_PRODUCTION(headerAddress, size); | 1522 FILL_ZERO_IF_PRODUCTION(headerAddress, size); |
1516 ASAN_POISON_MEMORY_REGION(payload, payloadSize); | 1523 ASAN_POISON_MEMORY_REGION(payload, payloadSize); |
1517 headerAddress += size; | 1524 headerAddress += size; |
1518 continue; | 1525 continue; |
1519 } | 1526 } |
1520 | 1527 |
(...skipping 29 matching lines...) Expand all Loading... | |
1550 markedObjectSize += header->size(); | 1557 markedObjectSize += header->size(); |
1551 } else { | 1558 } else { |
1552 header->markDead(); | 1559 header->markDead(); |
1553 } | 1560 } |
1554 headerAddress += header->size(); | 1561 headerAddress += header->size(); |
1555 } | 1562 } |
1556 if (markedObjectSize) | 1563 if (markedObjectSize) |
1557 Heap::increaseMarkedObjectSize(markedObjectSize); | 1564 Heap::increaseMarkedObjectSize(markedObjectSize); |
1558 } | 1565 } |
1559 | 1566 |
1567 #if defined(ADDRESS_SANITIZER) | |
1568 void NormalPage::poisonUnmarkedObjects() | |
1569 { | |
1570 for (Address headerAddress = payload(); headerAddress < payloadEnd();) { | |
1571 HeapObjectHeader* header = reinterpret_cast<HeapObjectHeader*>(headerAdd ress); | |
1572 ASSERT(header->size() < blinkPagePayloadSize()); | |
1573 // Check if a free list entry first since we cannot call | |
1574 // isMarked on a free list entry. | |
1575 if (header->isFree()) { | |
1576 headerAddress += header->size(); | |
1577 continue; | |
1578 } | |
1579 header->checkHeader(); | |
1580 if (!header->isMarked()) { | |
1581 ASAN_POISON_MEMORY_REGION(header->payload(), header->payloadSize()); | |
1582 } | |
1583 headerAddress += header->size(); | |
1584 } | |
1585 } | |
1586 #endif | |
1587 | |
1560 void NormalPage::populateObjectStartBitMap() | 1588 void NormalPage::populateObjectStartBitMap() |
1561 { | 1589 { |
1562 memset(&m_objectStartBitMap, 0, objectStartBitMapSize); | 1590 memset(&m_objectStartBitMap, 0, objectStartBitMapSize); |
1563 Address start = payload(); | 1591 Address start = payload(); |
1564 for (Address headerAddress = start; headerAddress < payloadEnd();) { | 1592 for (Address headerAddress = start; headerAddress < payloadEnd();) { |
1565 HeapObjectHeader* header = reinterpret_cast<HeapObjectHeader*>(headerAdd ress); | 1593 HeapObjectHeader* header = reinterpret_cast<HeapObjectHeader*>(headerAdd ress); |
1566 size_t objectOffset = headerAddress - start; | 1594 size_t objectOffset = headerAddress - start; |
1567 ASSERT(!(objectOffset & allocationMask)); | 1595 ASSERT(!(objectOffset & allocationMask)); |
1568 size_t objectStartNumber = objectOffset / allocationGranularity; | 1596 size_t objectStartNumber = objectOffset / allocationGranularity; |
1569 size_t mapIndex = objectStartNumber / 8; | 1597 size_t mapIndex = objectStartNumber / 8; |
(...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1816 { | 1844 { |
1817 HeapObjectHeader* header = heapObjectHeader(); | 1845 HeapObjectHeader* header = heapObjectHeader(); |
1818 if (header->isMarked()) { | 1846 if (header->isMarked()) { |
1819 header->unmark(); | 1847 header->unmark(); |
1820 Heap::increaseMarkedObjectSize(size()); | 1848 Heap::increaseMarkedObjectSize(size()); |
1821 } else { | 1849 } else { |
1822 header->markDead(); | 1850 header->markDead(); |
1823 } | 1851 } |
1824 } | 1852 } |
1825 | 1853 |
1854 #if defined(ADDRESS_SANITIZER) | |
1855 void LargeObjectPage::poisonUnmarkedObjects() | |
1856 { | |
1857 HeapObjectHeader* header = heapObjectHeader(); | |
1858 if (!header->isMarked()) | |
1859 ASAN_POISON_MEMORY_REGION(header->payload(), header->payloadSize()); | |
1860 } | |
1861 #endif | |
1862 | |
1826 void LargeObjectPage::checkAndMarkPointer(Visitor* visitor, Address address) | 1863 void LargeObjectPage::checkAndMarkPointer(Visitor* visitor, Address address) |
1827 { | 1864 { |
1828 ASSERT(contains(address)); | 1865 ASSERT(contains(address)); |
1829 if (!containedInObjectPayload(address) || heapObjectHeader()->isDead()) | 1866 if (!containedInObjectPayload(address) || heapObjectHeader()->isDead()) |
1830 return; | 1867 return; |
1831 #if ENABLE(GC_PROFILING) | 1868 #if ENABLE(GC_PROFILING) |
1832 visitor->setHostInfo(&address, "stack"); | 1869 visitor->setHostInfo(&address, "stack"); |
1833 #endif | 1870 #endif |
1834 markPointer(visitor, heapObjectHeader()); | 1871 markPointer(visitor, heapObjectHeader()); |
1835 } | 1872 } |
(...skipping 852 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2688 size_t Heap::s_allocatedObjectSize = 0; | 2725 size_t Heap::s_allocatedObjectSize = 0; |
2689 size_t Heap::s_allocatedSpace = 0; | 2726 size_t Heap::s_allocatedSpace = 0; |
2690 size_t Heap::s_markedObjectSize = 0; | 2727 size_t Heap::s_markedObjectSize = 0; |
2691 // We don't want to use 0 KB for the initial value because it may end up | 2728 // We don't want to use 0 KB for the initial value because it may end up |
2692 // triggering the first GC of some thread too prematurely. | 2729 // triggering the first GC of some thread too prematurely. |
2693 size_t Heap::s_estimatedLiveObjectSize = 512 * 1024; | 2730 size_t Heap::s_estimatedLiveObjectSize = 512 * 1024; |
2694 size_t Heap::s_externalObjectSizeAtLastGC = 0; | 2731 size_t Heap::s_externalObjectSizeAtLastGC = 0; |
2695 double Heap::s_estimatedMarkingTimePerByte = 0.0; | 2732 double Heap::s_estimatedMarkingTimePerByte = 0.0; |
2696 | 2733 |
2697 } // namespace blink | 2734 } // namespace blink |
OLD | NEW |