chromium/third_party/blink/renderer/platform/heap/test/heap_test.cc

/*
 * Copyright (C) 2013 Google Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 * copyright notice, this list of conditions and the following disclaimer
 * in the documentation and/or other materials provided with the
 * distribution.
 *     * Neither the name of Google Inc. nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#ifdef UNSAFE_BUFFERS_BUILD
// TODO(crbug.com/351564777): Remove this and convert code to safer constructs.
#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;

}  // namespace

#if DCHECK_IS_ON()
// Following 3 tests check for allocation failures. These failures happen
// only when DCHECK is on.

namespace {
class PreFinalizerBackingShrinkForbidden final
    : public GarbageCollected<PreFinalizerBackingShrinkForbidden> {};
}  // namespace

TEST_F(HeapTest, PreFinalizerBackingShrinkForbidden) {}

namespace {
class PreFinalizerVectorBackingExpandForbidden final
    : public GarbageCollected<PreFinalizerVectorBackingExpandForbidden> {};
}  // namespace

TEST_F(HeapDeathTest, PreFinalizerVectorBackingExpandForbidden) {}

namespace {
class PreFinalizerHashTableBackingExpandForbidden final
    : public GarbageCollected<PreFinalizerHashTableBackingExpandForbidden> {};
}  // namespace

TEST_F(HeapDeathTest, PreFinalizerHashTableBackingExpandForbidden) {}

namespace {
class HeapTestResurrectingPreFinalizer
    : public GarbageCollected<HeapTestResurrectingPreFinalizer> {};
}  // namespace

TEST_F(HeapDeathTest, DiesOnResurrectedHeapVectorMember) {}

TEST_F(HeapDeathTest, DiesOnResurrectedHeapHashSetMember) {}

TEST_F(HeapDeathTest, DiesOnResurrectedHeapHashSetWeakMember) {}
#endif  // DCHECK_IS_ON()

namespace {
class ThreadedTesterBase {};

// Needed to give this variable a definition (the initializer above is only a
// declaration), so that subclasses can use it.
const int ThreadedTesterBase::kNumberOfThreads;

class ThreadedHeapTester : public ThreadedTesterBase {};
}  // namespace

TEST_F(HeapTest, Threading) {}

namespace {
class ThreadMarker {};
}  // namespace

}  // namespace blink

namespace WTF {

// ThreadMarkerHash is the default hash for ThreadMarker
template <>
struct HashTraits<blink::ThreadMarker>
    : SimpleClassHashTraits<blink::ThreadMarker> {};

}  // namespace WTF

namespace blink {

namespace {
class ThreadedWeaknessTester : public ThreadedTesterBase {};
}  // namespace

TEST_F(HeapTest, ThreadedWeakness) {}

namespace {
class ThreadPersistentHeapTester : public ThreadedTesterBase {};
}  // namespace

TEST_F(HeapTest, ThreadPersistent) {}

namespace {
size_t GetOverallObjectSize() {}
}  // namespace

TEST_F(HeapTest, HashMapOfMembers) {}

namespace {

static constexpr size_t kLargeObjectSize =;

}  // namespace

// This test often fails on Android (https://crbug.com/843032).
// We run out of memory on Android devices because ReserveCapacityForSize
// actually allocates a much larger backing than specified (in this case 400MB).
#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> {};
}  // namespace

TEST_F(HeapTest, HeapVectorOnStackLargeObjectPageSized) {}

namespace {
template <typename T, typename U>
bool DequeContains(HeapDeque<T>& deque, U u) {}
}  // namespace

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> {};
}  // namespace

TEST_F(HeapTest, HeapHashMapWithInlinedObject) {}

TEST_F(HeapTest, HeapWeakCollectionSimple) {}

namespace {
template <typename Set>
void OrderedSetHelper(bool strong) {}
}  // namespace

TEST_F(HeapTest, HeapWeakLinkedHashSet) {}

namespace {
template <typename Set>
class SetOwner final : public GarbageCollected<SetOwner<Set>> {};

template <typename Set>
void ClearInWeakProcessingHelper() {}
}  // namespace

TEST_F(HeapTest, ClearInWeakProcessing) {}

namespace {
class ThingWithDestructor {};
int ThingWithDestructor::live_things_with_destructor_;

// This test class served a more important role while Blink
// was transitioned over to using Oilpan. That required classes
// that were hybrid, both ref-counted and on the Oilpan heap
// (the RefCountedGarbageCollected<> class providing just that.)
//
// There's no current need for having a ref-counted veneer on
// top of a GCed class, but we preserve it here to exercise the
// implementation technique that it used -- keeping an internal
// "keep alive" persistent reference that is set & cleared across
// ref-counting operations.
//
class RefCountedAndGarbageCollected final
    : public GarbageCollected<RefCountedAndGarbageCollected> {};
int RefCountedAndGarbageCollected::destructor_calls_ =;

static void HeapMapDestructorHelper(bool clear_maps) {}
}  // namespace

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) {}
}  // namespace

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 {};
}  // namespace

}  // namespace blink

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_ =;
}  // namespace

}  // namespace blink

WTF_ALLOW_MOVE_AND_INIT_WITH_MEM_FUNCTIONS()

namespace blink {

namespace {
class InlinedVectorObjectWrapper final
    : public GarbageCollected<InlinedVectorObjectWrapper> {};
}  // namespace

TEST_F(HeapTest, VectorDestructors) {}

namespace {
class InlinedVectorObjectWithVtable {};
int InlinedVectorObjectWithVtable::destructor_calls_ =;

class InlinedVectorObjectWithVtableWrapper final
    : public GarbageCollected<InlinedVectorObjectWithVtableWrapper> {};
}  // namespace

// TODO(Oilpan): when Vector.h's contiguous container support no longer disables
// Vector<>s with inline capacity, enable this test.
#if !defined(ANNOTATE_CONTIGUOUS_CONTAINER)
TEST_F(HeapTest, VectorDestructorsWithVtable) {}
#endif

namespace {
class SimpleClassWithDestructor {};
bool SimpleClassWithDestructor::was_destructed_;
}  // namespace

TEST_F(HeapTest, DestructorsCalled) {}

namespace {
static void AddElementsToWeakMap(
    HeapHashMap<int, WeakMember<IntWrapper>>* map) {}
}  // namespace

// crbug.com/402426
// If it doesn't assert a concurrent modification to the map, then it's passing.
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_ =;
}  // namespace

TEST_F(HeapTest, Bind) {}

TEST_F(HeapTest, EphemeronsInEphemerons) {}

namespace {
class EphemeronWrapper : public GarbageCollected<EphemeronWrapper> {};
}  // namespace

TEST_F(HeapTest, EphemeronsPointToEphemerons) {}

TEST_F(HeapTest, Ephemeron) {}

namespace {
class Link1 : public GarbageCollected<Link1> {};
}  // namespace

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 {};
}  // namespace

}  // namespace blink

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() {}
}  // namespace

TEST_F(HeapTest, TestClearOnShutdown) {}

namespace {
class KeyWithCopyingMoveConstructor final {};
}  // namespace

}  // namespace blink

namespace WTF {

template <>
struct HashTraits<blink::KeyWithCopyingMoveConstructor>
    : public SimpleClassHashTraits<blink::KeyWithCopyingMoveConstructor> {};

}  // namespace WTF

namespace blink {

TEST_F(HeapTest, HeapHashMapCallsDestructor) {}

namespace {
class FakeCSSValue : public GarbageCollected<FakeCSSValue> {};

class FakeNode : public GarbageCollected<FakeNode> {};
}  // namespace

}  // namespace blink

namespace cppgc {

template <>
struct SpaceTrait<blink::FakeCSSValue> {};

template <>
struct SpaceTrait<blink::FakeNode> {};

}  // namespace cppgc

namespace blink {

TEST_F(HeapTest, CollectNodeAndCssStatistics) {}

TEST_F(HeapTest, ContainerAnnotationOnTinyBacking) {}

}  // namespace blink