Commit 784b75f4 authored by Michael Lippautz's avatar Michael Lippautz Committed by Commit Bot

[wrapper-tracing] Move visitor parts to blink::Visitor

Move wrapper tracing visitation to regular blink::Visitor and inherit
from that in blink::ScriptWrappableVisitor. This is prework for removing
TraceWrappers and solely rely on Trace methods, even for wrapper tracing.

The bigger idea is to bring Trace in sync with TraceWrappers and drop
TraceWrappers completely. The visitors should distinguish which part
of the graph the would like to trace.

Bug: chromium:841830
Change-Id: Iae4d000318f8fd2f81eb9c66ed0a625699bada34
Reviewed-on: https://chromium-review.googlesource.com/1068890Reviewed-by: default avatarKentaro Hara <haraken@chromium.org>
Commit-Queue: Michael Lippautz <mlippautz@chromium.org>
Cr-Commit-Position: refs/heads/master@{#561395}
parent de423d75
...@@ -110,7 +110,7 @@ void V8EmbedderGraphBuilder::VisitPersistentHandle( ...@@ -110,7 +110,7 @@ void V8EmbedderGraphBuilder::VisitPersistentHandle(
EmbedderNode* graph_node = GraphNode( EmbedderNode* graph_node = GraphNode(
traceable, traceable->NameInHeapSnapshot(), wrapper, dom_tree_state); traceable, traceable->NameInHeapSnapshot(), wrapper, dom_tree_state);
const TraceWrapperDescriptor& wrapper_descriptor = const TraceWrapperDescriptor& wrapper_descriptor =
WrapperDescriptorFor<ScriptWrappable>(traceable); TraceWrapperDescriptorFor<ScriptWrappable>(traceable);
WorklistItem item = ToWorklistItem(graph_node, wrapper_descriptor); WorklistItem item = ToWorklistItem(graph_node, wrapper_descriptor);
switch (graph_node->GetDomTreeState()) { switch (graph_node->GetDomTreeState()) {
case DomTreeState::kAttached: case DomTreeState::kAttached:
...@@ -135,8 +135,8 @@ void V8EmbedderGraphBuilder::Visit( ...@@ -135,8 +135,8 @@ void V8EmbedderGraphBuilder::Visit(
} }
} }
void V8EmbedderGraphBuilder::Visit( void V8EmbedderGraphBuilder::Visit(void* object,
const TraceWrapperDescriptor& wrapper_descriptor) { TraceWrapperDescriptor wrapper_descriptor) {
// Add an edge from the current parent to this object. // Add an edge from the current parent to this object.
// Also push the object to the worklist in order to process its members. // Also push the object to the worklist in order to process its members.
const void* traceable = wrapper_descriptor.base_object_payload; const void* traceable = wrapper_descriptor.base_object_payload;
......
...@@ -26,12 +26,14 @@ class V8EmbedderGraphBuilder : public ScriptWrappableVisitor, ...@@ -26,12 +26,14 @@ class V8EmbedderGraphBuilder : public ScriptWrappableVisitor,
void VisitPersistentHandle(v8::Persistent<v8::Value>*, void VisitPersistentHandle(v8::Persistent<v8::Value>*,
uint16_t class_id) override; uint16_t class_id) override;
protected: // Visitor overrides.
// ScriptWrappableVisitor overrides.
void Visit(const TraceWrapperV8Reference<v8::Value>&) final; void Visit(const TraceWrapperV8Reference<v8::Value>&) final;
void Visit(const TraceWrapperDescriptor&) final; void Visit(void*, TraceWrapperDescriptor) final;
void Visit(DOMWrapperMap<ScriptWrappable>*, const ScriptWrappable*) final; void Visit(DOMWrapperMap<ScriptWrappable>*, const ScriptWrappable*) final;
protected:
using Visitor::Visit;
private: private:
// Information about whether a node is attached to the main DOM tree // Information about whether a node is attached to the main DOM tree
// or not. It is computed as follows: // or not. It is computed as follows:
......
...@@ -253,7 +253,8 @@ void ScriptWrappableMarkingVisitor::Visit( ...@@ -253,7 +253,8 @@ void ScriptWrappableMarkingVisitor::Visit(
} }
void ScriptWrappableMarkingVisitor::Visit( void ScriptWrappableMarkingVisitor::Visit(
const TraceWrapperDescriptor& wrapper_descriptor) { void* object,
TraceWrapperDescriptor wrapper_descriptor) {
HeapObjectHeader* header = HeapObjectHeader* header =
HeapObjectHeader::FromPayload(wrapper_descriptor.base_object_payload); HeapObjectHeader::FromPayload(wrapper_descriptor.base_object_payload);
if (header->IsWrapperHeaderMarked()) if (header->IsWrapperHeaderMarked())
......
...@@ -72,7 +72,8 @@ class PLATFORM_EXPORT ScriptWrappableMarkingVisitor ...@@ -72,7 +72,8 @@ class PLATFORM_EXPORT ScriptWrappableMarkingVisitor
return; return;
CurrentVisitor(thread_state->GetIsolate()) CurrentVisitor(thread_state->GetIsolate())
->Visit(WrapperDescriptorFor(dst_object)); ->Visit(const_cast<T*>(dst_object),
TraceWrapperDescriptorFor(dst_object));
} }
static void WriteBarrier(v8::Isolate*, static void WriteBarrier(v8::Isolate*,
...@@ -98,13 +99,15 @@ class PLATFORM_EXPORT ScriptWrappableMarkingVisitor ...@@ -98,13 +99,15 @@ class PLATFORM_EXPORT ScriptWrappableMarkingVisitor
void EnterFinalPause() override; void EnterFinalPause() override;
size_t NumberOfWrappersToTrace() override; size_t NumberOfWrappersToTrace() override;
protected: // Visitor interface.
// ScriptWrappableVisitor interface.
void Visit(const TraceWrapperV8Reference<v8::Value>&) override; void Visit(const TraceWrapperV8Reference<v8::Value>&) override;
void Visit(const TraceWrapperDescriptor&) override; void Visit(void*, TraceWrapperDescriptor) override;
void Visit(DOMWrapperMap<ScriptWrappable>*, void Visit(DOMWrapperMap<ScriptWrappable>*,
const ScriptWrappable* key) override; const ScriptWrappable* key) override;
protected:
using Visitor::Visit;
v8::Isolate* isolate() const { return isolate_; } v8::Isolate* isolate() const { return isolate_; }
private: private:
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include "third_party/blink/renderer/platform/bindings/trace_wrapper_base.h" #include "third_party/blink/renderer/platform/bindings/trace_wrapper_base.h"
#include "third_party/blink/renderer/platform/heap/heap_page.h" #include "third_party/blink/renderer/platform/heap/heap_page.h"
#include "third_party/blink/renderer/platform/heap/threading_traits.h" #include "third_party/blink/renderer/platform/heap/threading_traits.h"
#include "third_party/blink/renderer/platform/heap/visitor.h"
#include "third_party/blink/renderer/platform/platform_export.h" #include "third_party/blink/renderer/platform/platform_export.h"
#include "third_party/blink/renderer/platform/wtf/deque.h" #include "third_party/blink/renderer/platform/wtf/deque.h"
#include "third_party/blink/renderer/platform/wtf/vector.h" #include "third_party/blink/renderer/platform/wtf/vector.h"
...@@ -43,13 +44,15 @@ class TraceWrapperV8Reference; ...@@ -43,13 +44,15 @@ class TraceWrapperV8Reference;
// - Call visitor.DispatchTraceWrappers(traceable). // - Call visitor.DispatchTraceWrappers(traceable).
// DispatchTraceWrappers will invoke Visit() method for all // DispatchTraceWrappers will invoke Visit() method for all
// wrapper references in traceable. // wrapper references in traceable.
class PLATFORM_EXPORT ScriptWrappableVisitor { class PLATFORM_EXPORT ScriptWrappableVisitor : public Visitor {
public: public:
template <typename T> template <typename T>
static NOINLINE void MissedWriteBarrier() { static NOINLINE void MissedWriteBarrier() {
NOTREACHED(); NOTREACHED();
} }
ScriptWrappableVisitor() : Visitor(ThreadState::Current()) {}
// Trace all wrappers of |tracable|. // Trace all wrappers of |tracable|.
// //
// If you cannot use TraceWrapperMember & the corresponding TraceWrappers() // If you cannot use TraceWrapperMember & the corresponding TraceWrappers()
...@@ -103,18 +106,25 @@ class PLATFORM_EXPORT ScriptWrappableVisitor { ...@@ -103,18 +106,25 @@ class PLATFORM_EXPORT ScriptWrappableVisitor {
// Catch all handlers needed because of mixins except for Supplement<T>. // Catch all handlers needed because of mixins except for Supplement<T>.
void DispatchTraceWrappers(const void*) const { CHECK(false); } void DispatchTraceWrappers(const void*) const { CHECK(false); }
protected: // Unused blink::Visitor overrides. Derived visitors should still override
// The visitor interface. Derived visitors should override this // the cross-component visitation methods. See Visitor documentation.
// function to visit V8 references and ScriptWrappables. void Visit(void* object, TraceDescriptor desc) final {}
virtual void Visit(const TraceWrapperV8Reference<v8::Value>&) = 0; void VisitWeak(void* object,
virtual void Visit(const TraceWrapperDescriptor&) = 0; void** object_slot,
virtual void Visit(DOMWrapperMap<ScriptWrappable>*, TraceDescriptor desc,
const ScriptWrappable* key) = 0; WeakCallback callback) final {}
void VisitBackingStoreStrongly(void*, void**, TraceDescriptor) final {}
void VisitBackingStoreWeakly(void*,
void**,
TraceDescriptor,
WeakCallback,
void*) final {}
void VisitBackingStoreOnly(void*, void**) final {}
void RegisterBackingStoreCallback(void*, MovingObjectCallback, void*) final {}
void RegisterWeakCallback(void*, WeakCallback) final {}
template <typename T> protected:
static TraceWrapperDescriptor WrapperDescriptorFor(const T* traceable) { using Visitor::Visit;
return TraceTrait<T>::GetTraceWrapperDescriptor(const_cast<T*>(traceable));
}
private: private:
// Helper method to invoke the virtual Visit method with wrapper descriptor. // Helper method to invoke the virtual Visit method with wrapper descriptor.
...@@ -123,7 +133,7 @@ class PLATFORM_EXPORT ScriptWrappableVisitor { ...@@ -123,7 +133,7 @@ class PLATFORM_EXPORT ScriptWrappableVisitor {
static_assert(sizeof(T), "T must be fully defined"); static_assert(sizeof(T), "T must be fully defined");
if (!traceable) if (!traceable)
return; return;
Visit(WrapperDescriptorFor(traceable)); Visit(const_cast<T*>(traceable), TraceWrapperDescriptorFor(traceable));
} }
// Supplement-specific implementation of DispatchTraceWrappers. The suffix of // Supplement-specific implementation of DispatchTraceWrappers. The suffix of
......
...@@ -15,9 +15,10 @@ namespace blink { ...@@ -15,9 +15,10 @@ namespace blink {
// after marking is complete. The Visit method checks that the given wrapper // after marking is complete. The Visit method checks that the given wrapper
// is also marked. // is also marked.
class ScriptWrappableVisitorVerifier final : public ScriptWrappableVisitor { class ScriptWrappableVisitorVerifier final : public ScriptWrappableVisitor {
protected: public:
void Visit(const TraceWrapperV8Reference<v8::Value>&) final {} void Visit(const TraceWrapperV8Reference<v8::Value>&) final {}
void Visit(const TraceWrapperDescriptor& descriptor) final {
void Visit(void* object, TraceWrapperDescriptor descriptor) final {
HeapObjectHeader* header = HeapObjectHeader* header =
HeapObjectHeader::FromPayload(descriptor.base_object_payload); HeapObjectHeader::FromPayload(descriptor.base_object_payload);
const char* name = GCInfoTable::Get() const char* name = GCInfoTable::Get()
...@@ -35,8 +36,14 @@ class ScriptWrappableVisitorVerifier final : public ScriptWrappableVisitor { ...@@ -35,8 +36,14 @@ class ScriptWrappableVisitorVerifier final : public ScriptWrappableVisitor {
LOG_IF(FATAL, !header->IsWrapperHeaderMarked()) LOG_IF(FATAL, !header->IsWrapperHeaderMarked())
<< "Write barrier missed for " << name; << "Write barrier missed for " << name;
} }
void Visit(DOMWrapperMap<ScriptWrappable>*, void Visit(DOMWrapperMap<ScriptWrappable>*,
const ScriptWrappable* key) final {} const ScriptWrappable* key) final {}
protected:
using Visitor::Visit;
}; };
}
#endif } // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_BINDINGS_SCRIPT_WRAPPABLE_VISITOR_VERIFIER_H_
...@@ -69,6 +69,10 @@ class BackingVisitor : public Visitor { ...@@ -69,6 +69,10 @@ class BackingVisitor : public Visitor {
MovingObjectCallback, MovingObjectCallback,
void* callback_data) final {} void* callback_data) final {}
void RegisterWeakCallback(void* closure, WeakCallback) final {} void RegisterWeakCallback(void* closure, WeakCallback) final {}
void Visit(const TraceWrapperV8Reference<v8::Value>&) final {}
void Visit(DOMWrapperMap<ScriptWrappable>*,
const ScriptWrappable* key) final {}
void Visit(void*, TraceWrapperDescriptor) final {}
private: private:
std::vector<void*>* objects_; std::vector<void*>* objects_;
......
...@@ -55,6 +55,10 @@ class MarkingVerifier final : public Visitor { ...@@ -55,6 +55,10 @@ class MarkingVerifier final : public Visitor {
void VisitBackingStoreOnly(void*, void**) final {} void VisitBackingStoreOnly(void*, void**) final {}
void RegisterBackingStoreCallback(void*, MovingObjectCallback, void*) final {} void RegisterBackingStoreCallback(void*, MovingObjectCallback, void*) final {}
void RegisterWeakCallback(void*, WeakCallback) final {} void RegisterWeakCallback(void*, WeakCallback) final {}
void Visit(const TraceWrapperV8Reference<v8::Value>&) final {}
void Visit(DOMWrapperMap<ScriptWrappable>*,
const ScriptWrappable* key) final {}
void Visit(void*, TraceWrapperDescriptor) final {}
private: private:
void VerifyChild(void* base_object_payload) { void VerifyChild(void* base_object_payload) {
......
...@@ -109,6 +109,10 @@ class PLATFORM_EXPORT MarkingVisitor final : public Visitor { ...@@ -109,6 +109,10 @@ class PLATFORM_EXPORT MarkingVisitor final : public Visitor {
desc.callback); desc.callback);
} }
void Visit(void*, TraceWrapperDescriptor) final {
// Ignore as the object is also passed to Visit(void*, TraceDescriptor).
}
void VisitWeak(void* object, void VisitWeak(void* object,
void** object_slot, void** object_slot,
TraceDescriptor desc, TraceDescriptor desc,
...@@ -147,6 +151,11 @@ class PLATFORM_EXPORT MarkingVisitor final : public Visitor { ...@@ -147,6 +151,11 @@ class PLATFORM_EXPORT MarkingVisitor final : public Visitor {
EphemeronCallback iteration_callback) final; EphemeronCallback iteration_callback) final;
void RegisterWeakCallback(void* closure, WeakCallback) final; void RegisterWeakCallback(void* closure, WeakCallback) final;
// Unused cross-component visit methods.
void Visit(const TraceWrapperV8Reference<v8::Value>&) final {}
void Visit(DOMWrapperMap<ScriptWrappable>*,
const ScriptWrappable* key) final {}
private: private:
void RegisterBackingStoreReference(void* slot); void RegisterBackingStoreReference(void* slot);
......
...@@ -39,19 +39,25 @@ ...@@ -39,19 +39,25 @@
#include "third_party/blink/renderer/platform/wtf/forward.h" #include "third_party/blink/renderer/platform/wtf/forward.h"
#include "third_party/blink/renderer/platform/wtf/hash_traits.h" #include "third_party/blink/renderer/platform/wtf/hash_traits.h"
#include "third_party/blink/renderer/platform/wtf/type_traits.h" #include "third_party/blink/renderer/platform/wtf/type_traits.h"
#include "v8/include/v8.h"
namespace blink { namespace blink {
template <typename T> template <typename T>
class GarbageCollected; class GarbageCollected;
template <typename T> template <typename T>
class DOMWrapperMap;
template <typename T>
class TraceTrait; class TraceTrait;
class ThreadState; class ThreadState;
class Visitor; class Visitor;
template <typename T> template <typename T>
class SameThreadCheckedMember; class SameThreadCheckedMember;
class ScriptWrappable;
template <typename T> template <typename T>
class TraceWrapperMember; class TraceWrapperMember;
template <typename T>
class TraceWrapperV8Reference;
// The TraceMethodDelegate is used to convert a trace method for type T to a // The TraceMethodDelegate is used to convert a trace method for type T to a
// TraceCallback. This allows us to pass a type's trace method as a parameter // TraceCallback. This allows us to pass a type's trace method as a parameter
...@@ -85,11 +91,6 @@ class PLATFORM_EXPORT Visitor { ...@@ -85,11 +91,6 @@ class PLATFORM_EXPORT Visitor {
Trace(t.Get()); Trace(t.Get());
} }
template <typename T>
void Trace(const TraceWrapperMember<T>& t) {
Trace(*(static_cast<const Member<T>*>(&t)));
}
template <typename T> template <typename T>
void Trace(const SameThreadCheckedMember<T>& t) { void Trace(const SameThreadCheckedMember<T>& t) {
Trace(*(static_cast<const Member<T>*>(&t))); Trace(*(static_cast<const Member<T>*>(&t)));
...@@ -110,8 +111,7 @@ class PLATFORM_EXPORT Visitor { ...@@ -110,8 +111,7 @@ class PLATFORM_EXPORT Visitor {
if (!t) if (!t)
return; return;
Visit(const_cast<void*>(reinterpret_cast<const void*>(t)), Visit(const_cast<void*>(reinterpret_cast<const void*>(t)),
TraceTrait<T>::GetTraceDescriptor( TraceDescriptorFor(t));
const_cast<void*>(reinterpret_cast<const void*>(t))));
} }
template <typename T> template <typename T>
...@@ -124,8 +124,7 @@ class PLATFORM_EXPORT Visitor { ...@@ -124,8 +124,7 @@ class PLATFORM_EXPORT Visitor {
return; return;
VisitBackingStoreStrongly(reinterpret_cast<void*>(backing_store), VisitBackingStoreStrongly(reinterpret_cast<void*>(backing_store),
reinterpret_cast<void**>(backing_store_slot), reinterpret_cast<void**>(backing_store_slot),
TraceTrait<T>::GetTraceDescriptor( TraceDescriptorFor(backing_store));
reinterpret_cast<void*>(backing_store)));
} }
template <typename T> template <typename T>
...@@ -208,10 +207,42 @@ class PLATFORM_EXPORT Visitor { ...@@ -208,10 +207,42 @@ class PLATFORM_EXPORT Visitor {
&TraceMethodDelegate<T, method>::Trampoline); &TraceMethodDelegate<T, method>::Trampoline);
} }
// Cross-component tracing interface.
// TODO(mlippautz): Add required Trace methods to delegate to the subgraph
// relevant for wrapper tracing.
template <typename T>
void Trace(const TraceWrapperMember<T>& t) {
DCHECK(!t.IsHashTableDeletedValue());
TraceWithWrappers(t.Get());
}
template <typename T>
void TraceWithWrappers(T* t) {
static_assert(sizeof(T), "T must be fully defined");
static_assert(IsGarbageCollectedType<T>::value,
"T needs to be a garbage collected object");
if (!t)
return;
// Dispatch two both, the TraceDescritpor and the TraceWrapperDescriptor,
// versions of the visitor. This way the wrapper-tracing world can ignore
// the TraceDescriptor versions.
Visit(const_cast<void*>(reinterpret_cast<const void*>(t)),
TraceDescriptorFor(t));
Visit(const_cast<void*>(reinterpret_cast<const void*>(t)),
TraceWrapperDescriptorFor(t));
}
// Dynamic visitor interface. // Dynamic visitor interface.
// Visits an object through a strong reference. // Visits an object through a strong reference.
virtual void Visit(void*, TraceDescriptor) = 0; virtual void Visit(void*, TraceDescriptor) = 0;
// Subgraph of objects that are interested in wrappers. Note that the same
// object is also passed to Visit(void*, TraceDescriptor).
// TODO(mlippautz): Remove this visit method once wrapper tracing also uses
// Trace() instead of TraceWrappers().
virtual void Visit(void*, TraceWrapperDescriptor) = 0;
// Visits an object through a weak reference. // Visits an object through a weak reference.
virtual void VisitWeak(void*, void**, TraceDescriptor, WeakCallback) = 0; virtual void VisitWeak(void*, void**, TraceDescriptor, WeakCallback) = 0;
...@@ -225,6 +256,12 @@ class PLATFORM_EXPORT Visitor { ...@@ -225,6 +256,12 @@ class PLATFORM_EXPORT Visitor {
void*) = 0; void*) = 0;
virtual void VisitBackingStoreOnly(void*, void**) = 0; virtual void VisitBackingStoreOnly(void*, void**) = 0;
// Visits cross-component references to V8.
virtual void Visit(const TraceWrapperV8Reference<v8::Value>&) = 0;
virtual void Visit(DOMWrapperMap<ScriptWrappable>*,
const ScriptWrappable* key) = 0;
// Registers backing store pointers so that they can be moved and properly // Registers backing store pointers so that they can be moved and properly
// updated. // updated.
virtual void RegisterBackingStoreCallback(void* backing_store, virtual void RegisterBackingStoreCallback(void* backing_store,
...@@ -247,6 +284,18 @@ class PLATFORM_EXPORT Visitor { ...@@ -247,6 +284,18 @@ class PLATFORM_EXPORT Visitor {
// WeakMember elements though. // WeakMember elements though.
virtual void RegisterWeakCallback(void* closure, WeakCallback) = 0; virtual void RegisterWeakCallback(void* closure, WeakCallback) = 0;
protected:
template <typename T>
static inline TraceDescriptor TraceDescriptorFor(const T* traceable) {
return TraceTrait<T>::GetTraceDescriptor(const_cast<T*>(traceable));
}
template <typename T>
static inline TraceWrapperDescriptor TraceWrapperDescriptorFor(
const T* traceable) {
return TraceTrait<T>::GetTraceWrapperDescriptor(const_cast<T*>(traceable));
}
private: private:
template <typename T> template <typename T>
static void HandleWeakCell(Visitor* self, void*); static void HandleWeakCell(Visitor* self, void*);
......
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