summaryrefslogtreecommitdiff
path: root/chromium/third_party/blink/renderer/platform/heap/impl/collection_support/heap_vector_backing.h
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2021-05-20 09:47:09 +0200
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2021-06-07 11:15:42 +0000
commit189d4fd8fad9e3c776873be51938cd31a42b6177 (patch)
tree6497caeff5e383937996768766ab3bb2081a40b2 /chromium/third_party/blink/renderer/platform/heap/impl/collection_support/heap_vector_backing.h
parent8bc75099d364490b22f43a7ce366b366c08f4164 (diff)
downloadqtwebengine-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.h213
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_