unittests: Provide Context in TestWithHeapInternals

Change-Id: I54e658325dfbfb425c41cab2fd7b32253b380e37
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3247038
Commit-Queue: Michael Lippautz <mlippautz@chromium.org>
Commit-Queue: Omer Katz <omerkatz@chromium.org>
Auto-Submit: Michael Lippautz <mlippautz@chromium.org>
Reviewed-by: Omer Katz <omerkatz@chromium.org>
Cr-Commit-Position: refs/heads/main@{#77577}
This commit is contained in:
Michael Lippautz 2021-10-27 15:10:43 +02:00 committed by V8 LUCI CQ
parent 99284e344b
commit f300a01a63
3 changed files with 107 additions and 154 deletions

View File

@ -37,12 +37,13 @@ class WithHeapInternals : public TMixin, HeapInternalsBase {
}
};
using TestWithHeapInternals = //
WithHeapInternals< //
WithInternalIsolateMixin< //
WithIsolateScopeMixin< //
WithIsolateMixin< //
::testing::Test>>>>;
using TestWithHeapInternals = //
WithHeapInternals< //
WithContextMixin< //
WithInternalIsolateMixin< //
WithIsolateScopeMixin< //
WithIsolateMixin< //
::testing::Test>>>>>;
} // namespace internal
} // namespace v8

View File

@ -10,155 +10,119 @@
namespace v8 {
namespace internal {
using TracedReferenceTest = TestWithIsolate;
using TracedReferenceTest = TestWithContext;
TEST_F(TracedReferenceTest, ResetFromLocal) {
v8::Local<v8::Context> context = v8::Context::New(v8_isolate());
v8::Context::Scope context_scope(context);
v8::TracedReference<v8::Object> ref;
{
v8::HandleScope handles(v8_isolate());
v8::Local<v8::Object> local =
v8::Local<v8::Object>::New(v8_isolate(), v8::Object::New(v8_isolate()));
EXPECT_TRUE(ref.IsEmpty());
EXPECT_NE(ref, local);
ref.Reset(v8_isolate(), local);
EXPECT_FALSE(ref.IsEmpty());
EXPECT_EQ(ref, local);
}
v8::HandleScope handles(v8_isolate());
v8::Local<v8::Object> local =
v8::Local<v8::Object>::New(v8_isolate(), v8::Object::New(v8_isolate()));
EXPECT_TRUE(ref.IsEmpty());
EXPECT_NE(ref, local);
ref.Reset(v8_isolate(), local);
EXPECT_FALSE(ref.IsEmpty());
EXPECT_EQ(ref, local);
}
TEST_F(TracedReferenceTest, ConstructFromLocal) {
v8::Local<v8::Context> context = v8::Context::New(v8_isolate());
v8::Context::Scope context_scope(context);
{
v8::HandleScope handles(v8_isolate());
v8::Local<v8::Object> local =
v8::Local<v8::Object>::New(v8_isolate(), v8::Object::New(v8_isolate()));
v8::TracedReference<v8::Object> ref(v8_isolate(), local);
EXPECT_FALSE(ref.IsEmpty());
EXPECT_EQ(ref, local);
}
v8::HandleScope handles(v8_isolate());
v8::Local<v8::Object> local =
v8::Local<v8::Object>::New(v8_isolate(), v8::Object::New(v8_isolate()));
v8::TracedReference<v8::Object> ref(v8_isolate(), local);
EXPECT_FALSE(ref.IsEmpty());
EXPECT_EQ(ref, local);
}
TEST_F(TracedReferenceTest, Reset) {
v8::Local<v8::Context> context = v8::Context::New(v8_isolate());
v8::Context::Scope context_scope(context);
{
v8::HandleScope handles(v8_isolate());
v8::Local<v8::Object> local =
v8::Local<v8::Object>::New(v8_isolate(), v8::Object::New(v8_isolate()));
v8::TracedReference<v8::Object> ref(v8_isolate(), local);
EXPECT_FALSE(ref.IsEmpty());
EXPECT_EQ(ref, local);
ref.Reset();
EXPECT_TRUE(ref.IsEmpty());
EXPECT_NE(ref, local);
}
v8::HandleScope handles(v8_isolate());
v8::Local<v8::Object> local =
v8::Local<v8::Object>::New(v8_isolate(), v8::Object::New(v8_isolate()));
v8::TracedReference<v8::Object> ref(v8_isolate(), local);
EXPECT_FALSE(ref.IsEmpty());
EXPECT_EQ(ref, local);
ref.Reset();
EXPECT_TRUE(ref.IsEmpty());
EXPECT_NE(ref, local);
}
TEST_F(TracedReferenceTest, Copy) {
v8::Local<v8::Context> context = v8::Context::New(v8_isolate());
v8::Context::Scope context_scope(context);
{
v8::HandleScope handles(v8_isolate());
v8::Local<v8::Object> local =
v8::Local<v8::Object>::New(v8_isolate(), v8::Object::New(v8_isolate()));
v8::TracedReference<v8::Object> ref(v8_isolate(), local);
v8::TracedReference<v8::Object> ref_copy1(ref);
v8::TracedReference<v8::Object> ref_copy2 = ref;
EXPECT_EQ(ref, local);
EXPECT_EQ(ref_copy1, local);
EXPECT_EQ(ref_copy2, local);
}
v8::HandleScope handles(v8_isolate());
v8::Local<v8::Object> local =
v8::Local<v8::Object>::New(v8_isolate(), v8::Object::New(v8_isolate()));
v8::TracedReference<v8::Object> ref(v8_isolate(), local);
v8::TracedReference<v8::Object> ref_copy1(ref);
v8::TracedReference<v8::Object> ref_copy2 = ref;
EXPECT_EQ(ref, local);
EXPECT_EQ(ref_copy1, local);
EXPECT_EQ(ref_copy2, local);
}
TEST_F(TracedReferenceTest, CopyHeterogenous) {
v8::Local<v8::Context> context = v8::Context::New(v8_isolate());
v8::Context::Scope context_scope(context);
{
v8::HandleScope handles(v8_isolate());
v8::Local<v8::Object> local =
v8::Local<v8::Object>::New(v8_isolate(), v8::Object::New(v8_isolate()));
v8::TracedReference<v8::Object> ref(v8_isolate(), local);
v8::TracedReference<v8::Value> ref_copy1(ref);
v8::TracedReference<v8::Value> ref_copy2 = ref;
EXPECT_EQ(ref, local);
EXPECT_EQ(ref_copy1, local);
EXPECT_EQ(ref_copy2, local);
}
v8::HandleScope handles(v8_isolate());
v8::Local<v8::Object> local =
v8::Local<v8::Object>::New(v8_isolate(), v8::Object::New(v8_isolate()));
v8::TracedReference<v8::Object> ref(v8_isolate(), local);
v8::TracedReference<v8::Value> ref_copy1(ref);
v8::TracedReference<v8::Value> ref_copy2 = ref;
EXPECT_EQ(ref, local);
EXPECT_EQ(ref_copy1, local);
EXPECT_EQ(ref_copy2, local);
}
TEST_F(TracedReferenceTest, Move) {
v8::Local<v8::Context> context = v8::Context::New(v8_isolate());
v8::Context::Scope context_scope(context);
{
v8::HandleScope handles(v8_isolate());
v8::Local<v8::Object> local =
v8::Local<v8::Object>::New(v8_isolate(), v8::Object::New(v8_isolate()));
v8::TracedReference<v8::Object> ref(v8_isolate(), local);
v8::TracedReference<v8::Object> ref_moved1(std::move(ref));
v8::TracedReference<v8::Object> ref_moved2 = std::move(ref_moved1);
EXPECT_TRUE(ref.IsEmpty());
EXPECT_TRUE(ref_moved1.IsEmpty());
EXPECT_EQ(ref_moved2, local);
}
v8::HandleScope handles(v8_isolate());
v8::Local<v8::Object> local =
v8::Local<v8::Object>::New(v8_isolate(), v8::Object::New(v8_isolate()));
v8::TracedReference<v8::Object> ref(v8_isolate(), local);
v8::TracedReference<v8::Object> ref_moved1(std::move(ref));
v8::TracedReference<v8::Object> ref_moved2 = std::move(ref_moved1);
EXPECT_TRUE(ref.IsEmpty());
EXPECT_TRUE(ref_moved1.IsEmpty());
EXPECT_EQ(ref_moved2, local);
}
TEST_F(TracedReferenceTest, MoveHeterogenous) {
v8::Local<v8::Context> context = v8::Context::New(v8_isolate());
v8::Context::Scope context_scope(context);
{
v8::HandleScope handles(v8_isolate());
v8::Local<v8::Object> local =
v8::Local<v8::Object>::New(v8_isolate(), v8::Object::New(v8_isolate()));
v8::TracedReference<v8::Object> ref1(v8_isolate(), local);
v8::TracedReference<v8::Value> ref_moved1(std::move(ref1));
v8::TracedReference<v8::Object> ref2(v8_isolate(), local);
v8::TracedReference<v8::Object> ref_moved2 = std::move(ref2);
EXPECT_TRUE(ref1.IsEmpty());
EXPECT_EQ(ref_moved1, local);
EXPECT_TRUE(ref2.IsEmpty());
EXPECT_EQ(ref_moved2, local);
}
v8::HandleScope handles(v8_isolate());
v8::Local<v8::Object> local =
v8::Local<v8::Object>::New(v8_isolate(), v8::Object::New(v8_isolate()));
v8::TracedReference<v8::Object> ref1(v8_isolate(), local);
v8::TracedReference<v8::Value> ref_moved1(std::move(ref1));
v8::TracedReference<v8::Object> ref2(v8_isolate(), local);
v8::TracedReference<v8::Object> ref_moved2 = std::move(ref2);
EXPECT_TRUE(ref1.IsEmpty());
EXPECT_EQ(ref_moved1, local);
EXPECT_TRUE(ref2.IsEmpty());
EXPECT_EQ(ref_moved2, local);
}
TEST_F(TracedReferenceTest, Equality) {
v8::Local<v8::Context> context = v8::Context::New(v8_isolate());
v8::Context::Scope context_scope(context);
{
v8::HandleScope handles(v8_isolate());
v8::Local<v8::Object> local1 =
v8::Local<v8::Object>::New(v8_isolate(), v8::Object::New(v8_isolate()));
v8::TracedReference<v8::Object> ref1(v8_isolate(), local1);
v8::TracedReference<v8::Object> ref2(v8_isolate(), local1);
EXPECT_EQ(ref1, ref2);
EXPECT_EQ(ref2, ref1);
v8::Local<v8::Object> local2 =
v8::Local<v8::Object>::New(v8_isolate(), v8::Object::New(v8_isolate()));
v8::TracedReference<v8::Object> ref3(v8_isolate(), local2);
EXPECT_NE(ref2, ref3);
EXPECT_NE(ref3, ref2);
}
v8::HandleScope handles(v8_isolate());
v8::Local<v8::Object> local1 =
v8::Local<v8::Object>::New(v8_isolate(), v8::Object::New(v8_isolate()));
v8::TracedReference<v8::Object> ref1(v8_isolate(), local1);
v8::TracedReference<v8::Object> ref2(v8_isolate(), local1);
EXPECT_EQ(ref1, ref2);
EXPECT_EQ(ref2, ref1);
v8::Local<v8::Object> local2 =
v8::Local<v8::Object>::New(v8_isolate(), v8::Object::New(v8_isolate()));
v8::TracedReference<v8::Object> ref3(v8_isolate(), local2);
EXPECT_NE(ref2, ref3);
EXPECT_NE(ref3, ref2);
}
TEST_F(TracedReferenceTest, EqualityHeterogenous) {
v8::Local<v8::Context> context = v8::Context::New(v8_isolate());
v8::Context::Scope context_scope(context);
{
v8::HandleScope handles(v8_isolate());
v8::Local<v8::Object> local1 =
v8::Local<v8::Object>::New(v8_isolate(), v8::Object::New(v8_isolate()));
v8::TracedReference<v8::Object> ref1(v8_isolate(), local1);
v8::TracedReference<v8::Value> ref2(v8_isolate(), local1);
EXPECT_EQ(ref1, ref2);
EXPECT_EQ(ref2, ref1);
v8::Local<v8::Object> local2 =
v8::Local<v8::Object>::New(v8_isolate(), v8::Object::New(v8_isolate()));
v8::TracedReference<v8::Object> ref3(v8_isolate(), local2);
EXPECT_NE(ref2, ref3);
EXPECT_NE(ref3, ref2);
}
v8::HandleScope handles(v8_isolate());
v8::Local<v8::Object> local1 =
v8::Local<v8::Object>::New(v8_isolate(), v8::Object::New(v8_isolate()));
v8::TracedReference<v8::Object> ref1(v8_isolate(), local1);
v8::TracedReference<v8::Value> ref2(v8_isolate(), local1);
EXPECT_EQ(ref1, ref2);
EXPECT_EQ(ref2, ref1);
v8::Local<v8::Object> local2 =
v8::Local<v8::Object>::New(v8_isolate(), v8::Object::New(v8_isolate()));
v8::TracedReference<v8::Object> ref3(v8_isolate(), local2);
EXPECT_NE(ref2, ref3);
EXPECT_NE(ref3, ref2);
}
namespace {
@ -185,19 +149,15 @@ class JSVisitorForTesting final : public JSVisitor {
} // namespace
TEST_F(TracedReferenceTest, TracedReferenceTrace) {
v8::Local<v8::Context> context = v8::Context::New(v8_isolate());
v8::Context::Scope context_scope(context);
{
v8::HandleScope handles(v8_isolate());
v8::Local<v8::Object> local =
v8::Local<v8::Object>::New(v8_isolate(), v8::Object::New(v8_isolate()));
v8::TracedReference<v8::Object> js_member(v8_isolate(), local);
JSVisitorForTesting visitor(local);
// Cast to cppgc::Visitor to ensure that we dispatch through the base
// visitor and use traits.
static_cast<cppgc::Visitor&>(visitor).Trace(js_member);
EXPECT_EQ(1u, visitor.visit_count());
}
v8::HandleScope handles(v8_isolate());
v8::Local<v8::Object> local =
v8::Local<v8::Object>::New(v8_isolate(), v8::Object::New(v8_isolate()));
v8::TracedReference<v8::Object> js_member(v8_isolate(), local);
JSVisitorForTesting visitor(local);
// Cast to cppgc::Visitor to ensure that we dispatch through the base
// visitor and use traits.
static_cast<cppgc::Visitor&>(visitor).Trace(js_member);
EXPECT_EQ(1u, visitor.visit_count());
}
} // namespace internal

View File

@ -60,11 +60,9 @@ TEST_F(UnifiedHeapTest, OnlyGC) { CollectGarbageWithEmbedderStack(); }
TEST_F(UnifiedHeapTest, FindingV8ToBlinkReference) {
v8::HandleScope scope(v8_isolate());
v8::Local<v8::Context> context = v8::Context::New(v8_isolate());
v8::Context::Scope context_scope(context);
uint16_t wrappable_type = WrapperHelper::kTracedEmbedderId;
v8::Local<v8::Object> api_object = WrapperHelper::CreateWrapper(
context, &wrappable_type,
context(), &wrappable_type,
cppgc::MakeGarbageCollected<Wrappable>(allocation_handle()));
Wrappable::destructor_callcount = 0;
EXPECT_FALSE(api_object.IsEmpty());
@ -78,12 +76,11 @@ TEST_F(UnifiedHeapTest, FindingV8ToBlinkReference) {
TEST_F(UnifiedHeapTest, WriteBarrierV8ToCppReference) {
if (!FLAG_incremental_marking) return;
v8::HandleScope scope(v8_isolate());
v8::Local<v8::Context> context = v8::Context::New(v8_isolate());
v8::Context::Scope context_scope(context);
void* wrappable = cppgc::MakeGarbageCollected<Wrappable>(allocation_handle());
v8::Local<v8::Object> api_object =
WrapperHelper::CreateWrapper(context, nullptr, nullptr);
WrapperHelper::CreateWrapper(context(), nullptr, nullptr);
Wrappable::destructor_callcount = 0;
WrapperHelper::ResetWrappableConnection(api_object);
SimulateIncrementalMarking();
@ -105,9 +102,8 @@ TEST_F(UnifiedHeapTest, WriteBarrierV8ToCppReference) {
TEST_F(UnifiedHeapTest, WriteBarrierCppToV8Reference) {
if (!FLAG_incremental_marking) return;
v8::HandleScope scope(v8_isolate());
v8::Local<v8::Context> context = v8::Context::New(v8_isolate());
v8::Context::Scope context_scope(context);
cppgc::Persistent<Wrappable> wrappable =
cppgc::MakeGarbageCollected<Wrappable>(allocation_handle());
Wrappable::destructor_callcount = 0;
@ -119,7 +115,7 @@ TEST_F(UnifiedHeapTest, WriteBarrierCppToV8Reference) {
// setter for C++ to JS references.
v8::HandleScope nested_scope(v8_isolate());
v8::Local<v8::Object> api_object =
WrapperHelper::CreateWrapper(context, nullptr, nullptr);
WrapperHelper::CreateWrapper(context(), nullptr, nullptr);
// Setting only one field to avoid treating this as wrappable backref, see
// `LocalEmbedderHeapTracer::ExtractWrapperInfo`.
api_object->SetAlignedPointerInInternalField(1, kMagicAddress);
@ -148,8 +144,6 @@ class Unreferenced : public cppgc::GarbageCollected<Unreferenced> {
TEST_F(UnifiedHeapTest, FreeUnreferencedDuringNoGcScope) {
v8::HandleScope handle_scope(v8_isolate());
v8::Local<v8::Context> context = v8::Context::New(v8_isolate());
v8::Context::Scope context_scope(context);
auto* unreferenced = cppgc::MakeGarbageCollected<Unreferenced>(
allocation_handle(),
cppgc::AdditionalBytes(cppgc::internal::api_constants::kMB));
@ -178,8 +172,6 @@ TEST_F(UnifiedHeapTest, FreeUnreferencedDuringNoGcScope) {
#if !V8_OS_FUCHSIA
TEST_F(UnifiedHeapTest, TracedReferenceRetainsFromStack) {
v8::HandleScope handle_scope(v8_isolate());
v8::Local<v8::Context> context = v8::Context::New(v8_isolate());
v8::Context::Scope context_scope(context);
TracedReference<v8::Object> holder;
{
v8::HandleScope inner_handle_scope(v8_isolate());