chromium/v8/test/unittests/heap/cppgc/prefinalizer-unittest.cc

// Copyright 2020 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "include/cppgc/prefinalizer.h"

#include "include/cppgc/allocation.h"
#include "include/cppgc/garbage-collected.h"
#include "include/cppgc/persistent.h"
#include "src/heap/cppgc/heap-object-header.h"
#include "src/heap/cppgc/heap.h"
#include "test/unittests/heap/cppgc/tests.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace cppgc {
namespace internal {

namespace {

class PrefinalizerTest : public testing::TestWithHeap {};

class GCed : public GarbageCollected<GCed> {};
size_t GCed::prefinalizer_callcount =;

}  // namespace

TEST_F(PrefinalizerTest, PrefinalizerCalledOnDeadObject) {}

TEST_F(PrefinalizerTest, PrefinalizerNotCalledOnLiveObject) {}

namespace {

class Mixin : public GarbageCollectedMixin {};
size_t Mixin::prefinalizer_callcount =;

class GCedWithMixin : public GarbageCollected<GCedWithMixin>, public Mixin {};

}  // namespace

TEST_F(PrefinalizerTest, PrefinalizerCalledOnDeadMixinObject) {}

TEST_F(PrefinalizerTest, PrefinalizerNotCalledOnLiveMixinObject) {}

namespace {

class BaseMixin : public GarbageCollectedMixin {};
size_t BaseMixin::prefinalizer_callcount =;

class InheritingMixin : public BaseMixin {};
size_t InheritingMixin::prefinalizer_callcount =;

class GCedWithMixins : public GarbageCollected<GCedWithMixins>,
                       public InheritingMixin {};
size_t GCedWithMixins::prefinalizer_callcount =;

void BaseMixin::PreFinalizer() {}

void InheritingMixin::PreFinalizer() {}

void GCedWithMixins::PreFinalizer() {}
}  // namespace

TEST_F(PrefinalizerTest, PrefinalizerInvocationPreservesOrder) {}

namespace {

class LinkedNode final : public GarbageCollected<LinkedNode> {};

class MutatingPrefinalizer final
    : public GarbageCollected<MutatingPrefinalizer> {};

}  // namespace

TEST_F(PrefinalizerTest, PrefinalizerCanRewireGraphWithLiveObjects) {}

namespace {

class PrefinalizerDeathTest : public testing::TestWithHeap {};

class AllocatingPrefinalizer : public GarbageCollected<AllocatingPrefinalizer> {};

}  // namespace

#ifdef CPPGC_ALLOW_ALLOCATIONS_IN_PREFINALIZERS
TEST_F(PrefinalizerTest, PrefinalizerDoesNotFailOnAllcoation) {
  auto* object = MakeGarbageCollected<AllocatingPrefinalizer>(
      GetAllocationHandle(), GetHeap());
  PreciseGC();
  USE(object);
}
#else
#ifdef DEBUG
TEST_F(PrefinalizerDeathTest, PrefinalizerFailsOnAllcoation) {}
#endif  // DEBUG
#endif  // CPPGC_ALLOW_ALLOCATIONS_IN_PREFINALIZERS

namespace {

template <template <typename T> class RefType>
class RessurectingPrefinalizer
    : public GarbageCollected<RessurectingPrefinalizer<RefType>> {};

class GCedHolder : public GarbageCollected<GCedHolder> {};

}  // namespace

#if DEBUG
#ifdef CPPGC_VERIFY_HEAP

TEST_F(PrefinalizerDeathTest, PrefinalizerCanRewireGraphWithDeadObjects) {}

TEST_F(PrefinalizerDeathTest, PrefinalizerCantRessurectObjectOnStack) {}

TEST_F(PrefinalizerDeathTest, PrefinalizerCantRessurectObjectOnHeap) {}

#endif  // CPPGC_VERIFY_HEAP
#endif  // DEBUG

#ifdef CPPGC_ALLOW_ALLOCATIONS_IN_PREFINALIZERS
TEST_F(PrefinalizerTest, AllocatingPrefinalizersInMultipleGCCycles) {
  auto* object = MakeGarbageCollected<AllocatingPrefinalizer>(
      GetAllocationHandle(), GetHeap());
  PreciseGC();
  auto* other_object = MakeGarbageCollected<AllocatingPrefinalizer>(
      GetAllocationHandle(), GetHeap());
  PreciseGC();
  USE(object);
  USE(other_object);
}
#endif

class GCedBase : public GarbageCollected<GCedBase> {};
size_t GCedBase::prefinalizer_count_ =;

class GCedInherited : public GCedBase {};
size_t GCedInherited::prefinalizer_count_ =;

TEST_F(PrefinalizerTest, VirtualPrefinalizer) {}

}  // namespace internal
}  // namespace cppgc