Index: Source/platform/heap/Heap.cpp |
diff --git a/Source/platform/heap/Heap.cpp b/Source/platform/heap/Heap.cpp |
index 111562a5ce26c4e116118796c3a6c9f0b8a67811..4174cdb281f82d71daea83ff3cb4d19c0a9de84a 100644 |
--- a/Source/platform/heap/Heap.cpp |
+++ b/Source/platform/heap/Heap.cpp |
@@ -521,23 +521,42 @@ void LargeHeapObject<Header>::checkAndMarkPointer(Visitor* visitor, Address addr |
mark(visitor); |
} |
+#if ENABLE(ASSERT) |
+static bool isUninitializedMemory(void* objectPointer, size_t objectSize) |
+{ |
+ // Scan through the object's fields and check that they are all zero. |
+ Address* objectFields = reinterpret_cast<Address*>(objectPointer); |
+ for (size_t i = 0; i < objectSize / sizeof(Address); ++i) { |
+ if (objectFields[i] != 0) |
+ return false; |
+ } |
+ return true; |
+} |
+#endif |
+ |
template<> |
void LargeHeapObject<FinalizedHeapObjectHeader>::mark(Visitor* visitor) |
{ |
- if (heapObjectHeader()->hasVTable() && !vTableInitialized(payload())) |
- visitor->markConservatively(heapObjectHeader()); |
- else |
+ if (heapObjectHeader()->hasVTable() && !vTableInitialized(payload())) { |
+ FinalizedHeapObjectHeader* header = heapObjectHeader(); |
+ visitor->markNoTracing(header); |
+ ASSERT(isUninitializedMemory(header->payload(), header->payloadSize())); |
+ } else { |
visitor->mark(heapObjectHeader(), heapObjectHeader()->traceCallback()); |
+ } |
} |
template<> |
void LargeHeapObject<HeapObjectHeader>::mark(Visitor* visitor) |
{ |
ASSERT(gcInfo()); |
- if (gcInfo()->hasVTable() && !vTableInitialized(payload())) |
- visitor->markConservatively(heapObjectHeader()); |
- else |
+ if (gcInfo()->hasVTable() && !vTableInitialized(payload())) { |
+ HeapObjectHeader* header = heapObjectHeader(); |
+ visitor->markNoTracing(header); |
+ ASSERT(isUninitializedMemory(header->payload(), header->payloadSize())); |
+ } else { |
visitor->mark(heapObjectHeader(), gcInfo()->m_trace); |
+ } |
} |
template<> |
@@ -1362,10 +1381,12 @@ void HeapPage<Header>::checkAndMarkPointer(Visitor* visitor, Address address) |
#if ENABLE(GC_PROFILE_MARKING) |
visitor->setHostInfo(&address, "stack"); |
#endif |
- if (hasVTable(header) && !vTableInitialized(header->payload())) |
- visitor->markConservatively(header); |
- else |
+ if (hasVTable(header) && !vTableInitialized(header->payload())) { |
+ visitor->markNoTracing(header); |
+ ASSERT(isUninitializedMemory(header->payload(), header->payloadSize())); |
+ } else { |
visitor->mark(header, traceCallback(header)); |
+ } |
} |
#if ENABLE(GC_PROFILE_MARKING) |
@@ -1780,35 +1801,6 @@ public: |
visitHeader(header, header->payload(), callback); |
} |
- |
- inline void visitConservatively(HeapObjectHeader* header, void* objectPointer, size_t objectSize) |
- { |
- ASSERT(header); |
- ASSERT(objectPointer); |
- if (header->isMarked()) |
- return; |
- header->mark(); |
- |
- // Scan through the object's fields and visit them conservatively. |
- Address* objectFields = reinterpret_cast<Address*>(objectPointer); |
- for (size_t i = 0; i < objectSize / sizeof(Address); ++i) |
- Heap::checkAndMarkPointer(this, objectFields[i]); |
- } |
- |
- virtual void markConservatively(HeapObjectHeader* header) |
- { |
- // We need both the HeapObjectHeader and FinalizedHeapObjectHeader |
- // version to correctly find the payload. |
- visitConservatively(header, header->payload(), header->payloadSize()); |
- } |
- |
- virtual void markConservatively(FinalizedHeapObjectHeader* header) |
- { |
- // We need both the HeapObjectHeader and FinalizedHeapObjectHeader |
- // version to correctly find the payload. |
- visitConservatively(header, header->payload(), header->payloadSize()); |
- } |
- |
virtual void registerWeakMembers(const void* closure, const void* containingObject, WeakPointerCallback callback) OVERRIDE |
{ |
Heap::pushWeakObjectPointerCallback(const_cast<void*>(closure), const_cast<void*>(containingObject), callback); |