Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(7)

Unified Diff: Source/platform/heap/Heap.cpp

Issue 1110853002: Oilpan: In ASan, poison all unmarked objects before start sweeping (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 5 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « Source/platform/heap/Heap.h ('k') | Source/platform/heap/ThreadState.cpp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: Source/platform/heap/Heap.cpp
diff --git a/Source/platform/heap/Heap.cpp b/Source/platform/heap/Heap.cpp
index c3c3eaddbfea5bb8fecfd098a1bce0840bbdaae0..22469cb42314e4176d1df963e4ad80ebde5b757a 100644
--- a/Source/platform/heap/Heap.cpp
+++ b/Source/platform/heap/Heap.cpp
@@ -583,6 +583,17 @@ void BaseHeap::prepareForSweep()
m_firstPage = nullptr;
}
+#if defined(ADDRESS_SANITIZER)
+void BaseHeap::poisonUnmarkedObjects()
+{
+ // This method is called just before starting sweeping.
+ // Thus all dead objects are in the list of m_firstUnsweptPage.
+ for (BasePage* page = m_firstUnsweptPage; page; page = page->next()) {
+ page->poisonUnmarkedObjects();
+ }
+}
+#endif
+
Address BaseHeap::lazySweep(size_t allocationSize, size_t gcInfoIndex)
{
// If there are no pages to be swept, return immediately.
@@ -1506,8 +1517,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 detect an error if the finalizer
+ // 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 +1569,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 +1856,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));
« no previous file with comments | « Source/platform/heap/Heap.h ('k') | Source/platform/heap/ThreadState.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698