#ifdef UNSAFE_BUFFERS_BUILD
#pragma allow_unsafe_buffers
#endif
#include "base/synchronization/lock.h"
#include "base/test/bind.h"
#include "base/test/scoped_feature_list.h"
#include "build/build_config.h"
#include "gin/public/v8_platform.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/common/features.h"
#include "third_party/blink/renderer/platform/heap/collection_support/heap_deque.h"
#include "third_party/blink/renderer/platform/heap/collection_support/heap_hash_counted_set.h"
#include "third_party/blink/renderer/platform/heap/collection_support/heap_hash_map.h"
#include "third_party/blink/renderer/platform/heap/collection_support/heap_hash_set.h"
#include "third_party/blink/renderer/platform/heap/collection_support/heap_linked_hash_set.h"
#include "third_party/blink/renderer/platform/heap/cross_thread_persistent.h"
#include "third_party/blink/renderer/platform/heap/garbage_collected.h"
#include "third_party/blink/renderer/platform/heap/heap_test_objects.h"
#include "third_party/blink/renderer/platform/heap/heap_test_platform.h"
#include "third_party/blink/renderer/platform/heap/heap_test_utilities.h"
#include "third_party/blink/renderer/platform/heap/prefinalizer.h"
#include "third_party/blink/renderer/platform/heap/self_keep_alive.h"
#include "third_party/blink/renderer/platform/heap/visitor.h"
#include "third_party/blink/renderer/platform/scheduler/public/non_main_thread.h"
#include "third_party/blink/renderer/platform/scheduler/public/post_cross_thread_task.h"
#include "third_party/blink/renderer/platform/testing/unit_test_helpers.h"
#include "third_party/blink/renderer/platform/wtf/cross_thread_functional.h"
#include "third_party/blink/renderer/platform/wtf/hash_traits.h"
#include "v8/include/cppgc/internal/api-constants.h"
namespace blink {
namespace {
class HeapTest : public TestSupportingGC { … };
class HeapDeathTest : public TestSupportingGC { … };
class IntWrapper : public GarbageCollected<IntWrapper> { … };
std::atomic_int IntWrapper::destructor_calls_{ … };
struct IntWrapperHashTraits : GenericHashTraits<IntWrapper> { … };
static_assert …;
static_assert …;
static_assert …;
static_assert …;
static_assert …;
}
#if DCHECK_IS_ON()
namespace {
class PreFinalizerBackingShrinkForbidden final
: public GarbageCollected<PreFinalizerBackingShrinkForbidden> { … };
}
TEST_F(HeapTest, PreFinalizerBackingShrinkForbidden) { … }
namespace {
class PreFinalizerVectorBackingExpandForbidden final
: public GarbageCollected<PreFinalizerVectorBackingExpandForbidden> { … };
}
TEST_F(HeapDeathTest, PreFinalizerVectorBackingExpandForbidden) { … }
namespace {
class PreFinalizerHashTableBackingExpandForbidden final
: public GarbageCollected<PreFinalizerHashTableBackingExpandForbidden> { … };
}
TEST_F(HeapDeathTest, PreFinalizerHashTableBackingExpandForbidden) { … }
namespace {
class HeapTestResurrectingPreFinalizer
: public GarbageCollected<HeapTestResurrectingPreFinalizer> { … };
}
TEST_F(HeapDeathTest, DiesOnResurrectedHeapVectorMember) { … }
TEST_F(HeapDeathTest, DiesOnResurrectedHeapHashSetMember) { … }
TEST_F(HeapDeathTest, DiesOnResurrectedHeapHashSetWeakMember) { … }
#endif
namespace {
class ThreadedTesterBase { … };
const int ThreadedTesterBase::kNumberOfThreads;
class ThreadedHeapTester : public ThreadedTesterBase { … };
}
TEST_F(HeapTest, Threading) { … }
namespace {
class ThreadMarker { … };
}
}
namespace WTF {
template <>
struct HashTraits<blink::ThreadMarker>
: SimpleClassHashTraits<blink::ThreadMarker> { … };
}
namespace blink {
namespace {
class ThreadedWeaknessTester : public ThreadedTesterBase { … };
}
TEST_F(HeapTest, ThreadedWeakness) { … }
namespace {
class ThreadPersistentHeapTester : public ThreadedTesterBase { … };
}
TEST_F(HeapTest, ThreadPersistent) { … }
namespace {
size_t GetOverallObjectSize() { … }
}
TEST_F(HeapTest, HashMapOfMembers) { … }
namespace {
static constexpr size_t kLargeObjectSize = …;
}
#if BUILDFLAG(IS_ANDROID)
#define MAYBE_LargeHashMap …
#else
#define MAYBE_LargeHashMap …
#endif
TEST_F(HeapTest, MAYBE_LargeHashMap) { … }
TEST_F(HeapTest, LargeVector) { … }
TEST_F(HeapTest, HeapVectorFilledWithValue) { … }
TEST_F(HeapTest, HeapVectorWithInlineCapacity) { … }
TEST_F(HeapTest, HeapVectorShrinkCapacity) { … }
TEST_F(HeapTest, HeapVectorShrinkInlineCapacity) { … }
namespace {
PairWrappedUnwrapped;
PairUnwrappedWrapped;
class Container final : public GarbageCollected<Container> { … };
}
TEST_F(HeapTest, HeapVectorOnStackLargeObjectPageSized) { … }
namespace {
template <typename T, typename U>
bool DequeContains(HeapDeque<T>& deque, U u) { … }
}
TEST_F(HeapTest, HeapCollectionTypes) { … }
TEST_F(HeapTest, PersistentVector) { … }
TEST_F(HeapTest, CrossThreadPersistentVector) { … }
TEST_F(HeapTest, PersistentSet) { … }
TEST_F(HeapTest, CrossThreadPersistentSet) { … }
namespace {
class NonTrivialObject final : public GarbageCollected<NonTrivialObject> { … };
}
TEST_F(HeapTest, HeapHashMapWithInlinedObject) { … }
TEST_F(HeapTest, HeapWeakCollectionSimple) { … }
namespace {
template <typename Set>
void OrderedSetHelper(bool strong) { … }
}
TEST_F(HeapTest, HeapWeakLinkedHashSet) { … }
namespace {
template <typename Set>
class SetOwner final : public GarbageCollected<SetOwner<Set>> { … };
template <typename Set>
void ClearInWeakProcessingHelper() { … }
}
TEST_F(HeapTest, ClearInWeakProcessing) { … }
namespace {
class ThingWithDestructor { … };
int ThingWithDestructor::live_things_with_destructor_;
class RefCountedAndGarbageCollected final
: public GarbageCollected<RefCountedAndGarbageCollected> { … };
int RefCountedAndGarbageCollected::destructor_calls_ = …;
static void HeapMapDestructorHelper(bool clear_maps) { … }
}
TEST_F(HeapTest, HeapMapDestructor) { … }
namespace {
template <typename T>
void MapIteratorCheck(T& it, const T& end, int expected) { … }
template <typename T>
void SetIteratorCheck(T& it, const T& end, int expected) { … }
}
TEST_F(HeapTest, HeapWeakCollectionTypes) { … }
TEST_F(HeapTest, HeapHashCountedSetToVector) { … }
TEST_F(HeapTest, WeakHeapHashCountedSetToVector) { … }
TEST_F(HeapTest, RefCountedGarbageCollected) { … }
TEST_F(HeapTest, CollectionNesting) { … }
TEST_F(HeapTest, CollectionNesting2) { … }
TEST_F(HeapTest, CollectionNesting3) { … }
namespace {
class SimpleFinalizedObject final
: public GarbageCollected<SimpleFinalizedObject> { … };
int SimpleFinalizedObject::destructor_calls_ = …;
class VectorObject { … };
class VectorObjectInheritedTrace : public VectorObject { … };
}
}
WTF_ALLOW_MOVE_INIT_AND_COMPARE_WITH_MEM_FUNCTIONS(…)
WTF_ALLOW_MOVE_INIT_AND_COMPARE_WITH_MEM_FUNCTIONS(…)
namespace blink {
TEST_F(HeapTest, EmbeddedInVector) { … }
namespace {
class InlinedVectorObject { … };
int InlinedVectorObject::destructor_calls_ = …;
}
}
WTF_ALLOW_MOVE_AND_INIT_WITH_MEM_FUNCTIONS(…)
namespace blink {
namespace {
class InlinedVectorObjectWrapper final
: public GarbageCollected<InlinedVectorObjectWrapper> { … };
}
TEST_F(HeapTest, VectorDestructors) { … }
namespace {
class InlinedVectorObjectWithVtable { … };
int InlinedVectorObjectWithVtable::destructor_calls_ = …;
class InlinedVectorObjectWithVtableWrapper final
: public GarbageCollected<InlinedVectorObjectWithVtableWrapper> { … };
}
#if !defined(ANNOTATE_CONTIGUOUS_CONTAINER)
TEST_F(HeapTest, VectorDestructorsWithVtable) { … }
#endif
namespace {
class SimpleClassWithDestructor { … };
bool SimpleClassWithDestructor::was_destructed_;
}
TEST_F(HeapTest, DestructorsCalled) { … }
namespace {
static void AddElementsToWeakMap(
HeapHashMap<int, WeakMember<IntWrapper>>* map) { … }
}
TEST_F(HeapTest, RegressNullIsStrongified) { … }
namespace {
class SimpleObject : public GarbageCollected<SimpleObject> { … };
class Mixin : public GarbageCollectedMixin { … };
class UseMixin : public SimpleObject, public Mixin { … };
int UseMixin::trace_count_ = …;
class Bar : public GarbageCollected<Bar> { … };
unsigned Bar::live_ = …;
class OffHeapInt : public RefCounted<OffHeapInt> { … };
int OffHeapInt::destructor_calls_ = …;
}
TEST_F(HeapTest, Bind) { … }
TEST_F(HeapTest, EphemeronsInEphemerons) { … }
namespace {
class EphemeronWrapper : public GarbageCollected<EphemeronWrapper> { … };
}
TEST_F(HeapTest, EphemeronsPointToEphemerons) { … }
TEST_F(HeapTest, Ephemeron) { … }
namespace {
class Link1 : public GarbageCollected<Link1> { … };
}
TEST_F(HeapTest, IndirectStrongToWeak) { … }
class AllocatesOnAssignment : public GarbageCollected<AllocatesOnAssignment> { … };
bool operator==(const AllocatesOnAssignment& a,
const AllocatesOnAssignment& b) { … }
void swap(AllocatesOnAssignment& a, AllocatesOnAssignment& b) { … }
TEST_F(HeapTest, GCInHashMapOperations) { … }
TEST_F(HeapTest, DequeExpand) { … }
namespace {
class SimpleRefValue : public RefCounted<SimpleRefValue> { … };
class PartObjectWithRef { … };
}
}
WTF_ALLOW_INIT_WITH_MEM_FUNCTIONS(…)
namespace blink {
TEST_F(HeapTest, HeapVectorPartObjects) { … }
namespace {
class ThreadedClearOnShutdownTester : public ThreadedTesterBase { … };
class ThreadedClearOnShutdownTester::HeapObject final
: public GarbageCollected<ThreadedClearOnShutdownTester::HeapObject> { … };
ThreadedClearOnShutdownTester::WeakHeapObjectSet&
ThreadedClearOnShutdownTester::GetWeakHeapObjectSet() { … }
ThreadedClearOnShutdownTester::HeapObjectSet&
ThreadedClearOnShutdownTester::GetHeapObjectSet() { … }
void ThreadedClearOnShutdownTester::RunWhileAttached() { … }
}
TEST_F(HeapTest, TestClearOnShutdown) { … }
namespace {
class KeyWithCopyingMoveConstructor final { … };
}
}
namespace WTF {
template <>
struct HashTraits<blink::KeyWithCopyingMoveConstructor>
: public SimpleClassHashTraits<blink::KeyWithCopyingMoveConstructor> { … };
}
namespace blink {
TEST_F(HeapTest, HeapHashMapCallsDestructor) { … }
namespace {
class FakeCSSValue : public GarbageCollected<FakeCSSValue> { … };
class FakeNode : public GarbageCollected<FakeNode> { … };
}
}
namespace cppgc {
template <>
struct SpaceTrait<blink::FakeCSSValue> { … };
template <>
struct SpaceTrait<blink::FakeNode> { … };
}
namespace blink {
TEST_F(HeapTest, CollectNodeAndCssStatistics) { … }
TEST_F(HeapTest, ContainerAnnotationOnTinyBacking) { … }
}