Chromium Code Reviews| Index: Source/platform/heap/Heap.cpp |
| diff --git a/Source/platform/heap/Heap.cpp b/Source/platform/heap/Heap.cpp |
| index c3c3eaddbfea5bb8fecfd098a1bce0840bbdaae0..efd3b679175d3d4e17326edc92f0013e3d4bbb12 100644 |
| --- a/Source/platform/heap/Heap.cpp |
| +++ b/Source/platform/heap/Heap.cpp |
| @@ -578,6 +578,12 @@ void BaseHeap::prepareForSweep() |
| ASSERT(!threadState()->isInGC()); |
| ASSERT(!m_firstUnsweptPage); |
| +#if defined(ADDRESS_SANITIZER) |
| + for (BasePage* page = m_firstPage; page; page = page->next()) { |
| + page->poisonUnmarkedObjects(); |
| + } |
| +#endif |
| + |
| // Move all pages to a list of unswept pages. |
| m_firstUnsweptPage = m_firstPage; |
| m_firstPage = nullptr; |
| @@ -1506,8 +1512,9 @@ void NormalPage::sweep() |
| Address payload = header->payload(); |
| // For ASan we unpoison the specific object when calling the |
| // finalizer and poison it again when done to allow the object's own |
| - // finalizer to operate on the object, but not have other finalizers |
| - // be allowed to access it. |
| + // finalizer to operate on the object. Given all other unmarked |
| + // objects are poisoned, ASan will detech an error if the finalizer |
|
sof
2015/04/28 09:15:25
nit: s/detech/detect/
|
| + // touches any other on-heap object that die at the same GC cycle. |
| ASAN_UNPOISON_MEMORY_REGION(payload, payloadSize); |
| header->finalize(payload, payloadSize); |
| // This memory will be added to the freelist. Maintain the invariant |
| @@ -1557,6 +1564,27 @@ void NormalPage::markUnmarkedObjectsDead() |
| Heap::increaseMarkedObjectSize(markedObjectSize); |
| } |
| +#if defined(ADDRESS_SANITIZER) |
| +void NormalPage::poisonUnmarkedObjects() |
| +{ |
| + for (Address headerAddress = payload(); headerAddress < payloadEnd();) { |
| + HeapObjectHeader* header = reinterpret_cast<HeapObjectHeader*>(headerAddress); |
| + ASSERT(header->size() < blinkPagePayloadSize()); |
| + // Check if a free list entry first since we cannot call |
| + // isMarked on a free list entry. |
| + if (header->isFree()) { |
| + headerAddress += header->size(); |
| + continue; |
| + } |
| + header->checkHeader(); |
| + if (!header->isMarked()) { |
| + ASAN_POISON_MEMORY_REGION(header->payload(), header->payloadSize()); |
| + } |
| + headerAddress += header->size(); |
| + } |
| +} |
| +#endif |
| + |
| void NormalPage::populateObjectStartBitMap() |
| { |
| memset(&m_objectStartBitMap, 0, objectStartBitMapSize); |
| @@ -1823,6 +1851,15 @@ void LargeObjectPage::markUnmarkedObjectsDead() |
| } |
| } |
| +#if defined(ADDRESS_SANITIZER) |
| +void LargeObjectPage::poisonUnmarkedObjects() |
| +{ |
| + HeapObjectHeader* header = heapObjectHeader(); |
| + if (!header->isMarked()) |
| + ASAN_POISON_MEMORY_REGION(header->payload(), header->payloadSize()); |
| +} |
| +#endif |
| + |
| void LargeObjectPage::checkAndMarkPointer(Visitor* visitor, Address address) |
| { |
| ASSERT(contains(address)); |