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 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 |