diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2021-05-20 09:47:09 +0200 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2021-06-07 11:15:42 +0000 |
commit | 189d4fd8fad9e3c776873be51938cd31a42b6177 (patch) | |
tree | 6497caeff5e383937996768766ab3bb2081a40b2 /chromium/third_party/blink/renderer/platform/heap/impl/collection_support/heap_vector_backing.h | |
parent | 8bc75099d364490b22f43a7ce366b366c08f4164 (diff) | |
download | qtwebengine-chromium-189d4fd8fad9e3c776873be51938cd31a42b6177.tar.gz |
BASELINE: Update Chromium to 90.0.4430.221
Change-Id: Iff4d9d18d2fcf1a576f3b1f453010f744a232920
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'chromium/third_party/blink/renderer/platform/heap/impl/collection_support/heap_vector_backing.h')
-rw-r--r-- | chromium/third_party/blink/renderer/platform/heap/impl/collection_support/heap_vector_backing.h | 213 |
1 files changed, 213 insertions, 0 deletions
diff --git a/chromium/third_party/blink/renderer/platform/heap/impl/collection_support/heap_vector_backing.h b/chromium/third_party/blink/renderer/platform/heap/impl/collection_support/heap_vector_backing.h new file mode 100644 index 00000000000..c7b75baa8c7 --- /dev/null +++ b/chromium/third_party/blink/renderer/platform/heap/impl/collection_support/heap_vector_backing.h @@ -0,0 +1,213 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_COLLECTION_SUPPORT_HEAP_VECTOR_BACKING_H_ +#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_COLLECTION_SUPPORT_HEAP_VECTOR_BACKING_H_ + +#include "base/check_op.h" +#include "third_party/blink/renderer/platform/heap/heap.h" +#include "third_party/blink/renderer/platform/heap/impl/finalizer_traits.h" +#include "third_party/blink/renderer/platform/heap/impl/gc_info.h" +#include "third_party/blink/renderer/platform/heap/impl/threading_traits.h" +#include "third_party/blink/renderer/platform/heap/thread_state.h" +#include "third_party/blink/renderer/platform/heap/trace_traits.h" +#include "third_party/blink/renderer/platform/wtf/conditional_destructor.h" +#include "third_party/blink/renderer/platform/wtf/vector.h" + +namespace blink { + +template <typename T, typename Traits = WTF::VectorTraits<T>> +class HeapVectorBacking final + : public GarbageCollected<HeapVectorBacking<T, Traits>>, + public WTF::ConditionalDestructor<HeapVectorBacking<T, Traits>, + !Traits::kNeedsDestruction> { + public: + template <typename Backing> + static void* AllocateObject(size_t); + + // Conditionally invoked via destructor. + void Finalize(); +}; + +// static +template <typename T, typename Traits> +template <typename Backing> +void* HeapVectorBacking<T, Traits>::AllocateObject(size_t size) { + ThreadState* state = ThreadStateFor<ThreadingTrait<T>::kAffinity>::GetState(); + DCHECK(state->IsAllocationAllowed()); + return state->Heap().AllocateOnArenaIndex( + state, size, BlinkGC::kVectorArenaIndex, GCInfoTrait<Backing>::Index(), + WTF_HEAP_PROFILER_TYPE_NAME(Backing)); +} + +template <typename T, typename Traits> +void HeapVectorBacking<T, Traits>::Finalize() { + static_assert(Traits::kNeedsDestruction, + "Only vector buffers with items requiring destruction should " + "be finalized"); + static_assert( + Traits::kCanClearUnusedSlotsWithMemset || std::is_polymorphic<T>::value, + "HeapVectorBacking doesn't support objects that cannot be cleared as " + "unused with memset or don't have a vtable"); + + static_assert( + !std::is_trivially_destructible<T>::value, + "Finalization of trivially destructible classes should not happen."); + HeapObjectHeader* header = HeapObjectHeader::FromPayload(this); + // Use the payload size as recorded by the heap to determine how many + // elements to finalize. + size_t length = header->PayloadSize() / sizeof(T); + Address payload = header->Payload(); +#ifdef ANNOTATE_CONTIGUOUS_CONTAINER + ANNOTATE_CHANGE_SIZE(payload, length * sizeof(T), 0, length * sizeof(T)); +#endif + // As commented above, HeapVectorBacking calls finalizers for unused slots + // (which are already zeroed out). + if (std::is_polymorphic<T>::value) { + for (unsigned i = 0; i < length; ++i) { + Address element = payload + i * sizeof(T); + if (blink::VTableInitialized(element)) + reinterpret_cast<T*>(element)->~T(); + } + } else { + T* buffer = reinterpret_cast<T*>(payload); + for (unsigned i = 0; i < length; ++i) + buffer[i].~T(); + } +} + +template <typename T> +struct MakeGarbageCollectedTrait<HeapVectorBacking<T>> { + static HeapVectorBacking<T>* Call(size_t num_elements) { + static_assert(!std::is_polymorphic<HeapVectorBacking<T>>::value, + "HeapVectorBacking must not be polymorphic as it is " + "converted to a raw array of buckets for certain operation"); + CHECK_GT(num_elements, 0u); + void* memory = + HeapVectorBacking<T>::template AllocateObject<HeapVectorBacking<T>>( + num_elements * sizeof(T)); + HeapObjectHeader* header = HeapObjectHeader::FromPayload(memory); + // Placement new as regular operator new() is deleted. + HeapVectorBacking<T>* object = ::new (memory) HeapVectorBacking<T>(); + header->MarkFullyConstructed<HeapObjectHeader::AccessMode::kAtomic>(); + return object; + } +}; + +template <typename T, typename Traits> +struct ThreadingTrait<HeapVectorBacking<T, Traits>> { + STATIC_ONLY(ThreadingTrait); + static const ThreadAffinity kAffinity = ThreadingTrait<T>::Affinity; +}; + +template <typename T, typename Traits> +struct TraceTrait<HeapVectorBacking<T, Traits>> { + STATIC_ONLY(TraceTrait); + using Backing = HeapVectorBacking<T, Traits>; + + public: + static TraceDescriptor GetTraceDescriptor(const void* self) { + return {self, TraceTrait<Backing>::Trace}; + } + + static void Trace(Visitor* visitor, const void* self) { + if (!Traits::kCanTraceConcurrently && self) { + if (visitor->DeferredTraceIfConcurrent({self, &Trace}, + GetBackingStoreSize(self))) + return; + } + + static_assert(!WTF::IsWeak<T>::value, + "Weakness is not supported in HeapVector and HeapDeque"); + if (WTF::IsTraceableInCollectionTrait<Traits>::value) { + WTF::TraceInCollectionTrait<WTF::kNoWeakHandling, + HeapVectorBacking<T, Traits>, + void>::Trace(visitor, self); + } + } + + private: + static size_t GetBackingStoreSize(const void* backing_store) { + const HeapObjectHeader* header = + HeapObjectHeader::FromPayload(backing_store); + return header->IsLargeObject<HeapObjectHeader::AccessMode::kAtomic>() + ? static_cast<LargeObjectPage*>(PageFromObject(header)) + ->ObjectSize() + : header->size<HeapObjectHeader::AccessMode::kAtomic>(); + } +}; + +} // namespace blink + +namespace WTF { + +// This trace method is used for all HeapVectorBacking objects. On-stack objects +// are found and dispatched using conservative stack scanning. HeapVector (i.e. +// Vector) dispatches all regular on-heap backings to this method. +template <typename T, typename Traits> +struct TraceInCollectionTrait<kNoWeakHandling, + blink::HeapVectorBacking<T, Traits>, + void> { + static void Trace(blink::Visitor* visitor, const void* self) { + // HeapVectorBacking does not know the exact size of the vector + // 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(!IsTraceableInCollectionTrait<Traits>::value || + Traits::kCanClearUnusedSlotsWithMemset || + std::is_polymorphic<T>::value, + "HeapVectorBacking doesn't support objects that cannot be " + "cleared as unused with memset."); + + // This trace method is instantiated for vectors where + // IsTraceableInCollectionTrait<Traits>::value is false, but the trace + // method should not be called. Thus we cannot static-assert + // IsTraceableInCollectionTrait<Traits>::value but should runtime-assert it. + DCHECK(IsTraceableInCollectionTrait<Traits>::value); + + const T* array = reinterpret_cast<const 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); +#ifdef ANNOTATE_CONTIGUOUS_CONTAINER + // As commented above, HeapVectorBacking can trace unused slots + // (which are already zeroed out). + ANNOTATE_CHANGE_SIZE(array, length, 0, length); +#endif + if (std::is_polymorphic<T>::value) { + const char* pointer = reinterpret_cast<const char*>(array); + for (unsigned i = 0; i < length; ++i) { + const char* element = pointer + i * sizeof(T); + if (blink::VTableInitialized(element)) { + blink::TraceIfNeeded< + T, IsTraceableInCollectionTrait<Traits>::value>::Trace(visitor, + array[i]); + } + } + } else { + for (size_t i = 0; i < length; ++i) { + blink::TraceIfNeeded< + T, IsTraceableInCollectionTrait<Traits>::value>::Trace(visitor, + array[i]); + } + } + } +}; + +} // namespace WTF + +#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_COLLECTION_SUPPORT_HEAP_VECTOR_BACKING_H_ |