blob: 38eebbef946e6f0cffec01f566c61ecad7a16ee9 [file] [log] [blame]
// Copyright 2019 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.
#include "third_party/blink/renderer/platform/heap/impl/marking_verifier.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
#include "third_party/blink/renderer/platform/heap/heap.h"
#include "third_party/blink/renderer/platform/heap/heap_test_utilities.h"
#include "third_party/blink/renderer/platform/heap/persistent.h"
namespace blink {
#if DCHECK_IS_ON()
class MarkingVerifierDeathTest : public TestSupportingGC {};
namespace {
class ResurrectingPreFinalizer
: public GarbageCollected<ResurrectingPreFinalizer> {
USING_PRE_FINALIZER(ResurrectingPreFinalizer, Dispose);
public:
enum TestType {
kMember,
kWeakMember,
};
class GlobalStorage : public GarbageCollected<GlobalStorage> {
public:
void Trace(Visitor* visitor) const {
visitor->Trace(strong);
visitor->Trace(weak);
}
Member<LinkedObject> strong;
WeakMember<LinkedObject> weak;
};
ResurrectingPreFinalizer(TestType test_type,
GlobalStorage* storage,
LinkedObject* object_that_dies)
: test_type_(test_type),
storage_(storage),
object_that_dies_(object_that_dies) {}
void Trace(Visitor* visitor) const {
visitor->Trace(storage_);
visitor->Trace(object_that_dies_);
}
private:
void Dispose() {
switch (test_type_) {
case TestType::kMember:
storage_->strong = object_that_dies_;
break;
case TestType::kWeakMember:
storage_->weak = object_that_dies_;
break;
}
}
TestType test_type_;
Member<GlobalStorage> storage_;
Member<LinkedObject> object_that_dies_;
};
} // namespace
TEST_F(MarkingVerifierDeathTest, DiesOnResurrectedMember) {
if (!ThreadState::Current()->IsVerifyMarkingEnabled())
return;
Persistent<ResurrectingPreFinalizer::GlobalStorage> storage(
MakeGarbageCollected<ResurrectingPreFinalizer::GlobalStorage>());
MakeGarbageCollected<ResurrectingPreFinalizer>(
ResurrectingPreFinalizer::kMember, storage.Get(),
MakeGarbageCollected<LinkedObject>());
ASSERT_DEATH_IF_SUPPORTED(PreciselyCollectGarbage(),
"MarkingVerifier: Encountered unmarked object.");
}
TEST_F(MarkingVerifierDeathTest, DiesOnResurrectedWeakMember) {
if (!ThreadState::Current()->IsVerifyMarkingEnabled())
return;
Persistent<ResurrectingPreFinalizer::GlobalStorage> storage(
MakeGarbageCollected<ResurrectingPreFinalizer::GlobalStorage>());
MakeGarbageCollected<ResurrectingPreFinalizer>(
ResurrectingPreFinalizer::kWeakMember, storage.Get(),
MakeGarbageCollected<LinkedObject>());
ASSERT_DEATH_IF_SUPPORTED(PreciselyCollectGarbage(),
"MarkingVerifier: Encountered unmarked object.");
}
#endif // DCHECK_IS_ON()
} // namespace blink