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

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

Issue 1098953006: Oilpan: Support polymorphic objects in HeapVectorBackings (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 | « no previous file | Source/platform/heap/Heap.cpp » ('j') | Source/wtf/Vector.h » ('J')
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: Source/platform/heap/Heap.h
diff --git a/Source/platform/heap/Heap.h b/Source/platform/heap/Heap.h
index 161a8ffe92a3a20e4c30a10384871417b598c1ff..9f2eb4df89ffe09dd5a8e6d41875fbf4c5ddb4ca 100644
--- a/Source/platform/heap/Heap.h
+++ b/Source/platform/heap/Heap.h
@@ -336,8 +336,12 @@ inline Address blinkPageAddress(Address address)
return reinterpret_cast<Address>(reinterpret_cast<uintptr_t>(address) & blinkPageBaseMask);
}
-#if ENABLE(ASSERT)
+inline bool vTableInitialized(void* objectPointer)
+{
+ return !!(*reinterpret_cast<Address*>(objectPointer));
+}
+#if ENABLE(ASSERT)
// Sanity check for a page header address: the address of the page
// header should be OS page size away from being Blink page size
// aligned.
@@ -1713,25 +1717,41 @@ struct TraceInCollectionTrait<NoWeakHandlingInCollections, strongify, blink::Hea
static bool trace(VisitorDispatcher visitor, void* self)
{
// HeapVectorBacking does not know the exact size of the vector
- // and thus cannot avoid tracing all slots in the backing.
- // This works correctly as long as unused slots are cleared out
- // (this is done by VectorUnusedSlotClearer) and T can be initialized
- // with memset (if T can be initialized with memset, it is safe to
- // treat a zeroed object as a valid object).
- static_assert(!ShouldBeTraced<Traits>::value || Traits::canInitializeWithMemset, "HeapVectorBacking doesn't support objects that cannot be initialized with memset.");
+ // and just knows the capacity of the vector. Due to the constraint,
+ // HeapVectorBacking can support only the following objects:
+ //
+ // - An object that has a vtable. In this case, HeapVectorBacking
+ // traces only slots that are not zeroed out. This is because if
+ // the object has a vtable, the zeroed slot means that it is
+ // an unused slot (Remember that the unused slots are guaranteed
+ // to be zeroed out by VectorUnusedSlotClearer).
+ //
+ // - An object that can be initialized with memset. In this case,
+ // HeapVectorBacking traces all slots including unused slots.
+ // This is fine because the fact that the object can be initialized
+ // with memset indicates that it is safe to treat the zerod slot
+ // as a valid object.
+ static_assert(!ShouldBeTraced<Traits>::value || Traits::canInitializeWithMemset || WTF::IsPolymorphic<T>::value, "HeapVectorBacking doesn't support objects that cannot be initialized with memset.");
T* array = reinterpret_cast<T*>(self);
blink::HeapObjectHeader* header = blink::HeapObjectHeader::fromPayload(self);
// Use the payload size as recorded by the heap to determine how many
// elements to trace.
size_t length = header->payloadSize() / sizeof(T);
+ if (WTF::IsPolymorphic<T>::value) {
+ for (size_t i = 0; i < length; ++i) {
+ if (blink::vTableInitialized(&array[i]))
+ blink::CollectionBackingTraceTrait<ShouldBeTraced<Traits>::value, Traits::weakHandlingFlag, WeakPointersActStrong, T, Traits>::trace(visitor, array[i]);
+ }
+ } else {
#ifdef ANNOTATE_CONTIGUOUS_CONTAINER
- // As commented above, HeapVectorBacking can trace unused slots
- // (which are already zeroed out).
- ANNOTATE_CHANGE_SIZE(array, length, 0, length);
+ // As commented above, HeapVectorBacking can trace unused slots
+ // (which are already zeroed out).
+ ANNOTATE_CHANGE_SIZE(array, length, 0, length);
#endif
- for (size_t i = 0; i < length; ++i)
- blink::CollectionBackingTraceTrait<ShouldBeTraced<Traits>::value, Traits::weakHandlingFlag, WeakPointersActStrong, T, Traits>::trace(visitor, array[i]);
+ for (size_t i = 0; i < length; ++i)
+ blink::CollectionBackingTraceTrait<ShouldBeTraced<Traits>::value, Traits::weakHandlingFlag, WeakPointersActStrong, T, Traits>::trace(visitor, array[i]);
+ }
return false;
}
};
@@ -2009,13 +2029,8 @@ template<typename T, typename Traits>
void HeapVectorBacking<T, Traits>::finalize(void* pointer)
{
static_assert(Traits::needsDestruction, "Only vector buffers with items requiring destruction should be finalized");
- // HeapVectorBacking does not know the exact size of the vector
- // and thus cannot avoid calling finalizers for all slots in the backing.
- // This works correctly as long as unused slots are cleared out
- // (this is done by VectorUnusedSlotClearer) and T can be initialized
- // with memset (if T can be initialized with memset, it is safe to
- // treat a zeroed object as a valid object).
- static_assert(Traits::canInitializeWithMemset, "HeapVectorBacking doesn't support objects that cannot be initialized with memset.");
+ // See the comment in HeapVectorBacking::trace.
+ static_assert(Traits::canInitializeWithMemset || WTF::IsPolymorphic<T>::value, "HeapVectorBacking doesn't support objects that cannot be initialized with memset or don't have a vtable");
ASSERT(!WTF::IsTriviallyDestructible<T>::value);
HeapObjectHeader* header = HeapObjectHeader::fromPayload(pointer);
@@ -2028,8 +2043,16 @@ void HeapVectorBacking<T, Traits>::finalize(void* pointer)
// (which are already zeroed out).
ANNOTATE_CHANGE_SIZE(buffer, length, 0, length);
#endif
- for (unsigned i = 0; i < length; ++i)
- buffer[i].~T();
+ if (WTF::IsPolymorphic<T>::value) {
+ for (unsigned i = 0; i < length; ++i) {
+ if (blink::vTableInitialized(&buffer[i]))
+ buffer[i].~T();
+ }
+ } else {
+ for (unsigned i = 0; i < length; ++i) {
+ buffer[i].~T();
+ }
+ }
}
template<typename Table>
« no previous file with comments | « no previous file | Source/platform/heap/Heap.cpp » ('j') | Source/wtf/Vector.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698