Commit 0396620c authored by Michael Lippautz's avatar Michael Lippautz Committed by Commit Bot

Reland "[wrapper-tracing] Add ScriptWrappableVisitor unit tests"

Add unit tests that make sure that visitor dispatch reaches the expected leafs.

Reland:
- Avoid anon namespace in header file.

This reverts commit a398ea4f.

Bug: chromium:841830
Change-Id: I870d7f06baac17661a0d8bd16ee4ece78f8cdda6
Reviewed-on: https://chromium-review.googlesource.com/1073168Reviewed-by: default avatarKentaro Hara <haraken@chromium.org>
Commit-Queue: Michael Lippautz <mlippautz@chromium.org>
Cr-Commit-Position: refs/heads/master@{#561814}
parent 3eb7e652
......@@ -198,6 +198,7 @@ bindings_unittest_files =
"core/v8/script_promise_test.cc",
"core/v8/script_streamer_test.cc",
"core/v8/script_wrappable_marking_visitor_test.cc",
"core/v8/script_wrappable_visitor_test.cc",
"core/v8/to_v8_test.cc",
"core/v8/trace_wrapper_member_test.cc",
"core/v8/v8_binding_for_testing.cc",
......
// Copyright 2018 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/bindings/script_wrappable_visitor.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/renderer/core/testing/death_aware_script_wrappable.h"
#include "third_party/blink/renderer/platform/heap/trace_traits.h"
namespace blink {
namespace {
class VerifyingScriptWrappableVisitor : public ScriptWrappableVisitor {
public:
// Visitor interface.
void Visit(const TraceWrapperV8Reference<v8::Value>&) override {}
void Visit(DOMWrapperMap<ScriptWrappable>*,
const ScriptWrappable* key) override {}
void Visit(void*, TraceWrapperDescriptor desc) override {
visited_objects_.push_back(desc.base_object_payload);
}
bool DidVisitObject(const ScriptWrappable* script_wrappable) const {
return std::find(visited_objects_.begin(), visited_objects_.end(),
script_wrappable) != visited_objects_.end();
}
protected:
using Visitor::Visit;
private:
std::vector<void*> visited_objects_;
};
class ExpectObjectsVisited {
public:
ExpectObjectsVisited(VerifyingScriptWrappableVisitor* visitor,
std::initializer_list<ScriptWrappable*> objects)
: visitor_(visitor), expected_objects_(objects) {}
~ExpectObjectsVisited() {
for (const ScriptWrappable* expected_object : expected_objects_) {
EXPECT_TRUE(visitor_->DidVisitObject(expected_object));
}
}
private:
VerifyingScriptWrappableVisitor* visitor_;
std::vector<ScriptWrappable*> expected_objects_;
};
} // namespace
TEST(ScriptWrappableVisitorTest, TraceWrapperMember) {
VerifyingScriptWrappableVisitor verifying_visitor;
DeathAwareScriptWrappable* parent = DeathAwareScriptWrappable::Create();
DeathAwareScriptWrappable* child = DeathAwareScriptWrappable::Create();
parent->SetWrappedDependency(child);
{
ExpectObjectsVisited expected(&verifying_visitor, {child});
TraceTrait<DeathAwareScriptWrappable>::TraceWrappers(&verifying_visitor,
parent);
}
}
TEST(ScriptWrappableVisitorTest, HeapVectorOfTraceWrapperMember) {
VerifyingScriptWrappableVisitor verifying_visitor;
DeathAwareScriptWrappable* parent = DeathAwareScriptWrappable::Create();
DeathAwareScriptWrappable* child = DeathAwareScriptWrappable::Create();
parent->AddWrappedVectorDependency(child);
{
ExpectObjectsVisited expected(&verifying_visitor, {child});
TraceTrait<DeathAwareScriptWrappable>::TraceWrappers(&verifying_visitor,
parent);
}
}
TEST(ScriptWrappableVisitorTest, HeapHashMapOfTraceWrapperMember) {
VerifyingScriptWrappableVisitor verifying_visitor;
DeathAwareScriptWrappable* parent = DeathAwareScriptWrappable::Create();
DeathAwareScriptWrappable* key = DeathAwareScriptWrappable::Create();
DeathAwareScriptWrappable* value = DeathAwareScriptWrappable::Create();
parent->AddWrappedHashMapDependency(key, value);
{
ExpectObjectsVisited expected(&verifying_visitor, {key, value});
TraceTrait<DeathAwareScriptWrappable>::TraceWrappers(&verifying_visitor,
parent);
}
}
TEST(ScriptWrappableVisitorTest, InObjectUsingTraceWrapperMember) {
VerifyingScriptWrappableVisitor verifying_visitor;
DeathAwareScriptWrappable* parent = DeathAwareScriptWrappable::Create();
DeathAwareScriptWrappable* child = DeathAwareScriptWrappable::Create();
parent->AddInObjectDependency(child);
{
ExpectObjectsVisited expected(&verifying_visitor, {child});
TraceTrait<DeathAwareScriptWrappable>::TraceWrappers(&verifying_visitor,
parent);
}
}
} // namespace blink
......@@ -9,10 +9,37 @@
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
#include "third_party/blink/renderer/platform/bindings/trace_wrapper_member.h"
#include "third_party/blink/renderer/platform/heap/heap.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
namespace blink {
class DeathAwareScriptWrappable;
namespace internal {
class InObjectContainer {
DISALLOW_NEW_EXCEPT_PLACEMENT_NEW();
public:
explicit InObjectContainer(DeathAwareScriptWrappable* dependency)
: dependency_(dependency) {}
virtual ~InObjectContainer() {}
virtual void Trace(Visitor* visitor) { visitor->Trace(dependency_); }
virtual void TraceWrappers(ScriptWrappableVisitor* visitor) const {
visitor->TraceWrappers(dependency_);
}
private:
TraceWrapperMember<DeathAwareScriptWrappable> dependency_;
};
} // namespace internal
// ScriptWrappable that can be used to
// (a) build a graph of ScriptWrappables, and
// (b) observe a single DeathAwareScriptWrappable for being garbage collected.
class DeathAwareScriptWrappable : public ScriptWrappable {
DEFINE_WRAPPERTYPEINFO();
static DeathAwareScriptWrappable* instance_;
......@@ -21,12 +48,6 @@ class DeathAwareScriptWrappable : public ScriptWrappable {
public:
typedef TraceWrapperMember<DeathAwareScriptWrappable> Wrapper;
~DeathAwareScriptWrappable() override {
if (this == instance_) {
has_died_ = true;
}
}
static DeathAwareScriptWrappable* Create() {
return new DeathAwareScriptWrappable();
}
......@@ -37,10 +58,17 @@ class DeathAwareScriptWrappable : public ScriptWrappable {
instance_ = instance;
}
~DeathAwareScriptWrappable() override {
if (this == instance_) {
has_died_ = true;
}
}
void Trace(blink::Visitor* visitor) override {
visitor->Trace(wrapped_dependency_);
visitor->Trace(wrapped_vector_dependency_);
visitor->Trace(wrapped_hash_map_dependency_);
visitor->Trace(in_object_dependency_);
ScriptWrappable::Trace(visitor);
}
......@@ -53,6 +81,9 @@ class DeathAwareScriptWrappable : public ScriptWrappable {
visitor->TraceWrappers(pair.key);
visitor->TraceWrappers(pair.value);
}
for (const auto& in_object_dependency : in_object_dependency_) {
in_object_dependency.TraceWrappers(visitor);
}
ScriptWrappable::TraceWrappers(visitor);
}
......@@ -69,12 +100,17 @@ class DeathAwareScriptWrappable : public ScriptWrappable {
wrapped_hash_map_dependency_.insert(key, value);
}
void AddInObjectDependency(DeathAwareScriptWrappable* dependency) {
in_object_dependency_.push_back(internal::InObjectContainer(dependency));
}
private:
DeathAwareScriptWrappable() = default;
Wrapper wrapped_dependency_;
HeapVector<Wrapper> wrapped_vector_dependency_;
HeapHashMap<Wrapper, Wrapper> wrapped_hash_map_dependency_;
HeapVector<internal::InObjectContainer> in_object_dependency_;
};
} // namespace blink
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment