Commit 07861913 authored by Michael Lippautz's avatar Michael Lippautz Committed by Commit Bot

Reland "[wrapper-tracing] Only return trace descriptor for wrapper tracing"

Similar to Oilpan, only return a struct of callbacks and don't actually call
further into visitors.

This reverts commit 559a8e6a.

Change-Id: I430c72fd4bee22e7a9f49404f7d461076c613350
Bug: chromium:802273, chromium:819134
Reviewed-on: https://chromium-review.googlesource.com/950904
Commit-Queue: Michael Lippautz <mlippautz@chromium.org>
Reviewed-by: default avatarKentaro Hara <haraken@chromium.org>
Cr-Commit-Position: refs/heads/master@{#541267}
parent 493cc87e
...@@ -501,7 +501,6 @@ TEST(ScriptWrappableMarkingVisitorTest, MixinTracing) { ...@@ -501,7 +501,6 @@ TEST(ScriptWrappableMarkingVisitorTest, MixinTracing) {
DeathAwareScriptWrappable::Create(); DeathAwareScriptWrappable::Create();
Base* base = Base::Create(base_wrapper, mixin_wrapper); Base* base = Base::Create(base_wrapper, mixin_wrapper);
Mixin* mixin = static_cast<Mixin*>(base); Mixin* mixin = static_cast<Mixin*>(base);
HeapObjectHeader* base_header = HeapObjectHeader::FromPayload(base); HeapObjectHeader* base_header = HeapObjectHeader::FromPayload(base);
EXPECT_FALSE(base_header->IsWrapperHeaderMarked()); EXPECT_FALSE(base_header->IsWrapperHeaderMarked());
...@@ -516,7 +515,7 @@ TEST(ScriptWrappableMarkingVisitorTest, MixinTracing) { ...@@ -516,7 +515,7 @@ TEST(ScriptWrappableMarkingVisitorTest, MixinTracing) {
TraceWrapperMember<Mixin> mixin_handle = mixin; TraceWrapperMember<Mixin> mixin_handle = mixin;
EXPECT_TRUE(base_header->IsWrapperHeaderMarked()); EXPECT_TRUE(base_header->IsWrapperHeaderMarked());
EXPECT_FALSE(visitor->MarkingDeque()->IsEmpty()); EXPECT_FALSE(visitor->MarkingDeque()->IsEmpty());
EXPECT_TRUE(visitor->MarkingDequeContains(mixin)); EXPECT_TRUE(visitor->MarkingDequeContains(base));
visitor->AdvanceTracing( visitor->AdvanceTracing(
0, v8::EmbedderHeapTracer::AdvanceTracingActions( 0, v8::EmbedderHeapTracer::AdvanceTracingActions(
......
...@@ -61,10 +61,10 @@ void V8EmbedderGraphBuilder::Visit( ...@@ -61,10 +61,10 @@ void V8EmbedderGraphBuilder::Visit(
} }
void V8EmbedderGraphBuilder::Visit( void V8EmbedderGraphBuilder::Visit(
const WrapperDescriptor& wrapper_descriptor) const { const TraceWrapperDescriptor& wrapper_descriptor) const {
// 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.traceable; const void* traceable = wrapper_descriptor.base_object_payload;
Graph::Node* graph_node = Graph::Node* graph_node =
GraphNode(traceable, wrapper_descriptor.name_callback(traceable)); GraphNode(traceable, wrapper_descriptor.name_callback(traceable));
graph_->AddEdge(current_parent_, graph_node); graph_->AddEdge(current_parent_, graph_node);
...@@ -112,8 +112,8 @@ void V8EmbedderGraphBuilder::VisitPendingActivities() { ...@@ -112,8 +112,8 @@ void V8EmbedderGraphBuilder::VisitPendingActivities() {
V8EmbedderGraphBuilder::WorklistItem V8EmbedderGraphBuilder::ToWorklistItem( V8EmbedderGraphBuilder::WorklistItem V8EmbedderGraphBuilder::ToWorklistItem(
Graph::Node* node, Graph::Node* node,
const WrapperDescriptor& wrapper_descriptor) const { const TraceWrapperDescriptor& wrapper_descriptor) const {
return {node, wrapper_descriptor.traceable, return {node, wrapper_descriptor.base_object_payload,
wrapper_descriptor.trace_wrappers_callback}; wrapper_descriptor.trace_wrappers_callback};
} }
...@@ -123,7 +123,7 @@ void V8EmbedderGraphBuilder::VisitTransitiveClosure() { ...@@ -123,7 +123,7 @@ void V8EmbedderGraphBuilder::VisitTransitiveClosure() {
auto item = worklist_.back(); auto item = worklist_.back();
worklist_.pop_back(); worklist_.pop_back();
ParentScope parent(this, item.node); ParentScope parent(this, item.node);
item.trace_wrappers_callback(this, item.traceable); item.trace_wrappers_callback(this, const_cast<void*>(item.traceable));
} }
} }
......
...@@ -29,7 +29,7 @@ class V8EmbedderGraphBuilder : public ScriptWrappableVisitor, ...@@ -29,7 +29,7 @@ class V8EmbedderGraphBuilder : public ScriptWrappableVisitor,
protected: protected:
// ScriptWrappableVisitor overrides. // ScriptWrappableVisitor overrides.
void Visit(const TraceWrapperV8Reference<v8::Value>&) const final; void Visit(const TraceWrapperV8Reference<v8::Value>&) const final;
void Visit(const WrapperDescriptor&) const final; void Visit(const TraceWrapperDescriptor&) const final;
void Visit(DOMWrapperMap<ScriptWrappable>*, void Visit(DOMWrapperMap<ScriptWrappable>*,
const ScriptWrappable*) const final; const ScriptWrappable*) const final;
...@@ -74,7 +74,8 @@ class V8EmbedderGraphBuilder : public ScriptWrappableVisitor, ...@@ -74,7 +74,8 @@ class V8EmbedderGraphBuilder : public ScriptWrappableVisitor,
TraceWrappersCallback trace_wrappers_callback; TraceWrappersCallback trace_wrappers_callback;
}; };
WorklistItem ToWorklistItem(Graph::Node*, const WrapperDescriptor&) const; WorklistItem ToWorklistItem(Graph::Node*,
const TraceWrapperDescriptor&) const;
Graph::Node* GraphNode(const v8::Local<v8::Value>&) const; Graph::Node* GraphNode(const v8::Local<v8::Value>&) const;
Graph::Node* GraphNode(Traceable, const char* name) const; Graph::Node* GraphNode(Traceable, const char* name) const;
......
...@@ -253,9 +253,9 @@ void ScriptWrappableMarkingVisitor::Visit( ...@@ -253,9 +253,9 @@ void ScriptWrappableMarkingVisitor::Visit(
} }
void ScriptWrappableMarkingVisitor::Visit( void ScriptWrappableMarkingVisitor::Visit(
const WrapperDescriptor& wrapper_descriptor) const { const TraceWrapperDescriptor& wrapper_descriptor) const {
HeapObjectHeader* header = wrapper_descriptor.heap_object_header_callback( HeapObjectHeader* header =
wrapper_descriptor.traceable); HeapObjectHeader::FromPayload(wrapper_descriptor.base_object_payload);
if (header->IsWrapperHeaderMarked()) if (header->IsWrapperHeaderMarked())
return; return;
MarkWrapperHeader(header); MarkWrapperHeader(header);
......
...@@ -66,7 +66,8 @@ class PLATFORM_EXPORT ScriptWrappableMarkingVisitor ...@@ -66,7 +66,8 @@ class PLATFORM_EXPORT ScriptWrappableMarkingVisitor
return; return;
// If the wrapper is already marked we can bail out here. // If the wrapper is already marked we can bail out here.
if (TraceTrait<T>::GetHeapObjectHeader(dst_object)->IsWrapperHeaderMarked()) if (TraceTrait<T>::GetHeapObjectHeader(const_cast<T*>(dst_object))
->IsWrapperHeaderMarked())
return; return;
CurrentVisitor(thread_state->GetIsolate()) CurrentVisitor(thread_state->GetIsolate())
...@@ -99,7 +100,7 @@ class PLATFORM_EXPORT ScriptWrappableMarkingVisitor ...@@ -99,7 +100,7 @@ class PLATFORM_EXPORT ScriptWrappableMarkingVisitor
protected: protected:
// ScriptWrappableVisitor interface. // ScriptWrappableVisitor interface.
void Visit(const TraceWrapperV8Reference<v8::Value>&) const override; void Visit(const TraceWrapperV8Reference<v8::Value>&) const override;
void Visit(const WrapperDescriptor&) const override; void Visit(const TraceWrapperDescriptor&) const override;
void Visit(DOMWrapperMap<ScriptWrappable>*, void Visit(DOMWrapperMap<ScriptWrappable>*,
const ScriptWrappable* key) const override; const ScriptWrappable* key) const override;
...@@ -108,20 +109,18 @@ class PLATFORM_EXPORT ScriptWrappableMarkingVisitor ...@@ -108,20 +109,18 @@ class PLATFORM_EXPORT ScriptWrappableMarkingVisitor
private: private:
class MarkingDequeItem { class MarkingDequeItem {
public: public:
explicit MarkingDequeItem(const WrapperDescriptor& wrapper_descriptor) explicit MarkingDequeItem(const TraceWrapperDescriptor& wrapper_descriptor)
: trace_wrappers_callback_(wrapper_descriptor.trace_wrappers_callback), : raw_object_pointer_(wrapper_descriptor.base_object_payload),
heap_object_header_callback_( trace_wrappers_callback_(wrapper_descriptor.trace_wrappers_callback) {
wrapper_descriptor.heap_object_header_callback),
raw_object_pointer_(wrapper_descriptor.traceable) {
DCHECK(trace_wrappers_callback_);
DCHECK(heap_object_header_callback_);
DCHECK(raw_object_pointer_); DCHECK(raw_object_pointer_);
DCHECK(trace_wrappers_callback_);
} }
// Traces wrappers if the underlying object has not yet been invalidated. // Traces wrappers if the underlying object has not yet been invalidated.
inline void TraceWrappers(ScriptWrappableVisitor* visitor) const { inline void TraceWrappers(ScriptWrappableVisitor* visitor) const {
if (raw_object_pointer_) { if (raw_object_pointer_) {
trace_wrappers_callback_(visitor, raw_object_pointer_); trace_wrappers_callback_(visitor,
const_cast<void*>(raw_object_pointer_));
} }
} }
...@@ -139,13 +138,11 @@ class PLATFORM_EXPORT ScriptWrappableMarkingVisitor ...@@ -139,13 +138,11 @@ class PLATFORM_EXPORT ScriptWrappableMarkingVisitor
private: private:
inline const HeapObjectHeader* GetHeapObjectHeader() { inline const HeapObjectHeader* GetHeapObjectHeader() {
DCHECK(raw_object_pointer_); return HeapObjectHeader::FromPayload(raw_object_pointer_);
return heap_object_header_callback_(raw_object_pointer_);
} }
TraceWrappersCallback trace_wrappers_callback_;
HeapObjectHeaderCallback heap_object_header_callback_;
const void* raw_object_pointer_; const void* raw_object_pointer_;
TraceWrappersCallback trace_wrappers_callback_;
}; };
void MarkWrapperHeader(HeapObjectHeader*) const; void MarkWrapperHeader(HeapObjectHeader*) const;
......
...@@ -17,7 +17,6 @@ namespace blink { ...@@ -17,7 +17,6 @@ namespace blink {
template <typename T> template <typename T>
class DOMWrapperMap; class DOMWrapperMap;
class HeapObjectHeader;
class ScriptWrappable; class ScriptWrappable;
class ScriptWrappableVisitor; class ScriptWrappableVisitor;
template <typename T> template <typename T>
...@@ -27,32 +26,16 @@ class TraceWrapperBaseForSupplement; ...@@ -27,32 +26,16 @@ class TraceWrapperBaseForSupplement;
template <typename T> template <typename T>
class TraceWrapperV8Reference; class TraceWrapperV8Reference;
using HeapObjectHeaderCallback = HeapObjectHeader* (*)(const void*); #define DEFINE_TRAIT_FOR_TRACE_WRAPPERS(ClassName) \
using MissedWriteBarrierCallback = void (*)(); template <> \
using TraceWrappersCallback = void (*)(const ScriptWrappableVisitor*, inline void TraceTrait<ClassName>::TraceWrappers( \
const void* self); ScriptWrappableVisitor* visitor, void* t) { \
using NameCallback = const char* (*)(const void* self); static_assert(sizeof(ClassName), "type needs to be defined"); \
static_assert(IsGarbageCollectedType<ClassName>::value, \
#define DEFINE_TRAIT_FOR_TRACE_WRAPPERS(ClassName) \ "only objects deriving from GarbageCollected can be used"); \
template <> \ static_cast<ClassName*>(t)->TraceWrappers(visitor); \
inline void TraceTrait<ClassName>::TraceMarkedWrapper( \
const ScriptWrappableVisitor* visitor, const void* t) { \
const ClassName* traceable = ToWrapperTracingType(t); \
traceable->TraceWrappers(visitor); \
} }
// WrapperDescriptor contains enough information to visit a
// ScriptWrappable without knowing its type statically.
// It is passed to ScriptWrappableVisitor::Visit method.
struct WrapperDescriptor {
STACK_ALLOCATED();
const void* traceable;
TraceWrappersCallback trace_wrappers_callback;
HeapObjectHeaderCallback heap_object_header_callback;
MissedWriteBarrierCallback missed_write_barrier_callback;
NameCallback name_callback;
};
// Abstract visitor for wrapper references in a ScriptWrappable. // Abstract visitor for wrapper references in a ScriptWrappable.
// Usage: // Usage:
// - Define a derived class that overrides Visit(..) methods. // - Define a derived class that overrides Visit(..) methods.
...@@ -62,6 +45,17 @@ struct WrapperDescriptor { ...@@ -62,6 +45,17 @@ struct WrapperDescriptor {
// wrapper references in traceable. // wrapper references in traceable.
class PLATFORM_EXPORT ScriptWrappableVisitor { class PLATFORM_EXPORT ScriptWrappableVisitor {
public: public:
template <typename T>
static NOINLINE void MissedWriteBarrier() {
NOTREACHED();
}
template <typename T>
static const char* NameCallback(const void* traceable) {
// Mixns never inherit from TraceWrapperBase.
return NameInHeapSnapshot(static_cast<const T*>(traceable));
}
// 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()
...@@ -119,24 +113,16 @@ class PLATFORM_EXPORT ScriptWrappableVisitor { ...@@ -119,24 +113,16 @@ class PLATFORM_EXPORT ScriptWrappableVisitor {
// The visitor interface. Derived visitors should override this // The visitor interface. Derived visitors should override this
// function to visit V8 references and ScriptWrappables. // function to visit V8 references and ScriptWrappables.
virtual void Visit(const TraceWrapperV8Reference<v8::Value>&) const = 0; virtual void Visit(const TraceWrapperV8Reference<v8::Value>&) const = 0;
virtual void Visit(const WrapperDescriptor&) const = 0; virtual void Visit(const TraceWrapperDescriptor&) const = 0;
virtual void Visit(DOMWrapperMap<ScriptWrappable>*, virtual void Visit(DOMWrapperMap<ScriptWrappable>*,
const ScriptWrappable* key) const = 0; const ScriptWrappable* key) const = 0;
template <typename T> template <typename T>
static WrapperDescriptor WrapperDescriptorFor(const T* traceable) { static TraceWrapperDescriptor WrapperDescriptorFor(const T* traceable) {
return {traceable, TraceTrait<T>::TraceMarkedWrapper, return TraceTrait<T>::GetTraceWrapperDescriptor(const_cast<T*>(traceable));
TraceTrait<T>::GetHeapObjectHeader,
ScriptWrappableVisitor::MissedWriteBarrier<T>,
ScriptWrappableVisitor::NameCallback<T>};
} }
private: private:
template <typename T>
static NOINLINE void MissedWriteBarrier() {
NOTREACHED();
}
static const char* NameInHeapSnapshot(const TraceWrapperBase* traceable) { static const char* NameInHeapSnapshot(const TraceWrapperBase* traceable) {
return traceable->NameInHeapSnapshot(); return traceable->NameInHeapSnapshot();
} }
...@@ -146,11 +132,6 @@ class PLATFORM_EXPORT ScriptWrappableVisitor { ...@@ -146,11 +132,6 @@ class PLATFORM_EXPORT ScriptWrappableVisitor {
return "InternalNode"; return "InternalNode";
} }
template <typename T>
static const char* NameCallback(const void* traceable) {
return NameInHeapSnapshot(static_cast<const T*>(traceable));
}
// Helper method to invoke the virtual Visit method with wrapper descriptor. // Helper method to invoke the virtual Visit method with wrapper descriptor.
template <typename T> template <typename T>
void Visit(const T* traceable) const { void Visit(const T* traceable) const {
......
...@@ -15,10 +15,9 @@ namespace blink { ...@@ -15,10 +15,9 @@ namespace blink {
class ScriptWrappableVisitorVerifier final : public ScriptWrappableVisitor { class ScriptWrappableVisitorVerifier final : public ScriptWrappableVisitor {
protected: protected:
void Visit(const TraceWrapperV8Reference<v8::Value>&) const final {} void Visit(const TraceWrapperV8Reference<v8::Value>&) const final {}
void Visit(const WrapperDescriptor& wrapper_descriptor) const final { void Visit(const TraceWrapperDescriptor& descriptor) const final {
HeapObjectHeader* header = wrapper_descriptor.heap_object_header_callback( if (!HeapObjectHeader::FromPayload(descriptor.base_object_payload)
wrapper_descriptor.traceable); ->IsWrapperHeaderMarked()) {
if (!header->IsWrapperHeaderMarked()) {
// If this branch is hit, it means that a white (not discovered by // If this branch is hit, it means that a white (not discovered by
// traceWrappers) object was assigned as a member to a black object // traceWrappers) object was assigned as a member to a black object
// (already processed by traceWrappers). Black object will not be // (already processed by traceWrappers). Black object will not be
...@@ -29,7 +28,7 @@ class ScriptWrappableVisitorVerifier final : public ScriptWrappableVisitor { ...@@ -29,7 +28,7 @@ class ScriptWrappableVisitorVerifier final : public ScriptWrappableVisitor {
// This means there is a write barrier missing somewhere. Check the // This means there is a write barrier missing somewhere. Check the
// backtrace to see which types are causing this and review all the // backtrace to see which types are causing this and review all the
// places where white object is set to a black object. // places where white object is set to a black object.
wrapper_descriptor.missed_write_barrier_callback(); descriptor.missed_write_barrier_callback();
NOTREACHED(); NOTREACHED();
} }
} }
......
...@@ -16,6 +16,7 @@ namespace blink { ...@@ -16,6 +16,7 @@ namespace blink {
class MarkingVisitor; class MarkingVisitor;
class Visitor; class Visitor;
class ScriptWrappableVisitor;
using Address = uint8_t*; using Address = uint8_t*;
...@@ -23,8 +24,11 @@ using FinalizationCallback = void (*)(void*); ...@@ -23,8 +24,11 @@ using FinalizationCallback = void (*)(void*);
using VisitorCallback = void (*)(Visitor*, void*); using VisitorCallback = void (*)(Visitor*, void*);
using MarkingVisitorCallback = void (*)(MarkingVisitor*, void*); using MarkingVisitorCallback = void (*)(MarkingVisitor*, void*);
using TraceCallback = VisitorCallback; using TraceCallback = VisitorCallback;
using TraceWrappersCallback = void (*)(ScriptWrappableVisitor*, void*);
using WeakCallback = VisitorCallback; using WeakCallback = VisitorCallback;
using EphemeronCallback = VisitorCallback; using EphemeronCallback = VisitorCallback;
using MissedWriteBarrierCallback = void (*)();
using NameCallback = const char* (*)(const void* self);
// Simple alias to avoid heap compaction type signatures turning into // Simple alias to avoid heap compaction type signatures turning into
// a sea of generic |void*|s. // a sea of generic |void*|s.
......
...@@ -16,7 +16,6 @@ namespace blink { ...@@ -16,7 +16,6 @@ namespace blink {
template <typename T> template <typename T>
class GarbageCollected; class GarbageCollected;
class HeapObjectHeader; class HeapObjectHeader;
class ScriptWrappableVisitor;
// GC_PLUGIN_IGNORE is used to make the plugin ignore a particular class or // GC_PLUGIN_IGNORE is used to make the plugin ignore a particular class or
// field when checking for proper usage. When using GC_PLUGIN_IGNORE // field when checking for proper usage. When using GC_PLUGIN_IGNORE
...@@ -54,6 +53,14 @@ struct TraceDescriptor { ...@@ -54,6 +53,14 @@ struct TraceDescriptor {
bool can_trace_eagerly; bool can_trace_eagerly;
}; };
struct TraceWrapperDescriptor {
STACK_ALLOCATED();
void* base_object_payload;
TraceWrappersCallback trace_wrappers_callback;
MissedWriteBarrierCallback missed_write_barrier_callback;
NameCallback name_callback;
};
// The GarbageCollectedMixin interface and helper macro // The GarbageCollectedMixin interface and helper macro
// USING_GARBAGE_COLLECTED_MIXIN can be used to automatically define // USING_GARBAGE_COLLECTED_MIXIN can be used to automatically define
// TraceTrait/ObjectAliveTrait on non-leftmost deriving classes // TraceTrait/ObjectAliveTrait on non-leftmost deriving classes
...@@ -71,43 +78,41 @@ struct TraceDescriptor { ...@@ -71,43 +78,41 @@ struct TraceDescriptor {
// }; // };
// //
// With the helper, as long as we are using Member<B>, TypeTrait<B> will // With the helper, as long as we are using Member<B>, TypeTrait<B> will
// dispatch adjustAndMark dynamically to find collect addr of the object header. // dispatch dynamically to retrieve the necessary tracing and header methods.
// Note that this is only enabled for Member<B>. For Member<A> which we can // Note that this is only enabled for Member<B>. For Member<A> which we can
// compute the object header addr statically, this dynamic dispatch is not used. // compute the necessary methods and pointers statically and this dynamic
// // dispatch is not used.
class PLATFORM_EXPORT GarbageCollectedMixin { class PLATFORM_EXPORT GarbageCollectedMixin {
public: public:
typedef int IsGarbageCollectedMixinMarker; typedef int IsGarbageCollectedMixinMarker;
virtual void Trace(Visitor*) {} virtual void Trace(Visitor*) {}
virtual TraceDescriptor GetTraceDescriptor() const = 0;
virtual HeapObjectHeader* GetHeapObjectHeader() const = 0; virtual HeapObjectHeader* GetHeapObjectHeader() const = 0;
virtual void AdjustAndTraceMarkedWrapper( virtual TraceDescriptor GetTraceDescriptor() const = 0;
const ScriptWrappableVisitor*) const = 0; virtual TraceWrapperDescriptor GetTraceWrapperDescriptor() const = 0;
}; };
#define DEFINE_GARBAGE_COLLECTED_MIXIN_METHODS(TYPE) \ #define DEFINE_GARBAGE_COLLECTED_MIXIN_METHODS(TYPE) \
public: \ public: \
TraceDescriptor GetTraceDescriptor() const override { \ HeapObjectHeader* GetHeapObjectHeader() const override { \
typedef WTF::IsSubclassOfTemplate<typename std::remove_const<TYPE>::type, \ static_assert( \
blink::GarbageCollected> \ WTF::IsSubclassOfTemplate<typename std::remove_const<TYPE>::type, \
IsSubclassOfGarbageCollected; \ blink::GarbageCollected>::value, \
static_assert( \ "only garbage collected objects can have garbage collected mixins"); \
IsSubclassOfGarbageCollected::value, \ return HeapObjectHeader::FromPayload(static_cast<const TYPE*>(this)); \
"only garbage collected objects can have garbage collected mixins"); \ } \
return {const_cast<TYPE*>(static_cast<const TYPE*>(this)), \ \
TraceTrait<TYPE>::Trace, TraceEagerlyTrait<TYPE>::value}; \ TraceDescriptor GetTraceDescriptor() const override { \
} \ return {const_cast<TYPE*>(static_cast<const TYPE*>(this)), \
\ TraceTrait<TYPE>::Trace, TraceEagerlyTrait<TYPE>::value}; \
void AdjustAndTraceMarkedWrapper(const ScriptWrappableVisitor* visitor) \ } \
const override { \ \
const TYPE* base = static_cast<const TYPE*>(this); \ TraceWrapperDescriptor GetTraceWrapperDescriptor() const override { \
TraceTrait<TYPE>::TraceMarkedWrapper(visitor, base); \ return {const_cast<TYPE*>(static_cast<const TYPE*>(this)), \
} \ TraceTrait<TYPE>::TraceWrappers, \
\ ScriptWrappableVisitor::MissedWriteBarrier<TYPE>, \
HeapObjectHeader* GetHeapObjectHeader() const override { \ ScriptWrappableVisitor::NameCallback<TYPE>}; \
return HeapObjectHeader::FromPayload(static_cast<const TYPE*>(this)); \ } \
} \ \
\
private: private:
// A C++ object's vptr will be initialized to its leftmost base's vtable after // A C++ object's vptr will be initialized to its leftmost base's vtable after
...@@ -212,14 +217,13 @@ class GarbageCollectedMixinConstructorMarker ...@@ -212,14 +217,13 @@ class GarbageCollectedMixinConstructorMarker
// // ambiguous. USING_GARBAGE_COLLECTED_MIXIN(TYPE) overrides them later // // ambiguous. USING_GARBAGE_COLLECTED_MIXIN(TYPE) overrides them later
// // and provides the implementations. // // and provides the implementations.
// }; // };
#define MERGE_GARBAGE_COLLECTED_MIXINS() \ #define MERGE_GARBAGE_COLLECTED_MIXINS() \
public: \ public: \
TraceDescriptor GetTraceDescriptor() const override = 0; \ HeapObjectHeader* GetHeapObjectHeader() const override = 0; \
HeapObjectHeader* GetHeapObjectHeader() const override = 0; \ TraceDescriptor GetTraceDescriptor() const override = 0; \
void AdjustAndTraceMarkedWrapper(const ScriptWrappableVisitor*) \ TraceWrapperDescriptor GetTraceWrapperDescriptor() const override = 0; \
const override = 0; \ \
\ private: \
private: \
using merge_garbage_collected_mixins_requires_semicolon = void using merge_garbage_collected_mixins_requires_semicolon = void
// Base class for objects allocated in the Blink garbage-collected heap. // Base class for objects allocated in the Blink garbage-collected heap.
......
...@@ -54,20 +54,18 @@ class AdjustAndMarkTrait<T, false> { ...@@ -54,20 +54,18 @@ class AdjustAndMarkTrait<T, false> {
return {self, TraceTrait<T>::Trace, TraceEagerlyTrait<T>::value}; return {self, TraceTrait<T>::Trace, TraceEagerlyTrait<T>::value};
} }
static HeapObjectHeader* GetHeapObjectHeader(const T* self) { static TraceWrapperDescriptor GetTraceWrapperDescriptor(void* self) {
return {self, TraceTrait<T>::TraceWrappers,
ScriptWrappableVisitor::MissedWriteBarrier<T>,
ScriptWrappableVisitor::NameCallback<T>};
}
static HeapObjectHeader* GetHeapObjectHeader(void* self) {
#if DCHECK_IS_ON() #if DCHECK_IS_ON()
HeapObjectHeader::CheckFromPayload(self); HeapObjectHeader::CheckFromPayload(self);
#endif #endif
return HeapObjectHeader::FromPayload(self); return HeapObjectHeader::FromPayload(self);
} }
static void TraceMarkedWrapper(const ScriptWrappableVisitor* visitor,
const T* self) {
// The term *mark* is misleading here as we effectively trace through the
// API boundary, i.e., tell V8 that an object is alive. Actual marking
// will be done in V8.
visitor->DispatchTraceWrappers(self);
}
}; };
template <typename T> template <typename T>
...@@ -75,18 +73,19 @@ class AdjustAndMarkTrait<T, true> { ...@@ -75,18 +73,19 @@ class AdjustAndMarkTrait<T, true> {
STATIC_ONLY(AdjustAndMarkTrait); STATIC_ONLY(AdjustAndMarkTrait);
public: public:
static HeapObjectHeader* GetHeapObjectHeader(const T* self) { static TraceDescriptor GetTraceDescriptor(const T* self) {
return self->GetHeapObjectHeader(); DCHECK(self);
return self->GetTraceDescriptor();
} }
static TraceDescriptor GetTraceDescriptor(T* self) { static TraceWrapperDescriptor GetTraceWrapperDescriptor(const T* self) {
DCHECK(self); DCHECK(self);
return self->GetTraceDescriptor(); return self->GetTraceWrapperDescriptor();
} }
static void TraceMarkedWrapper(const ScriptWrappableVisitor* visitor, static HeapObjectHeader* GetHeapObjectHeader(const T* self) {
const T* self) { DCHECK(self);
self->AdjustAndTraceMarkedWrapper(visitor); return self->GetHeapObjectHeader();
} }
}; };
...@@ -173,10 +172,11 @@ struct TraceCollectionIfEnabled { ...@@ -173,10 +172,11 @@ struct TraceCollectionIfEnabled {
} }
}; };
// The TraceTrait is used to specify how to mark an object pointer and // The TraceTrait is used to specify how to trace and object for Oilpan and
// how to trace all of the pointers in the object. // wrapper tracing.
// //
// By default, the 'trace' method implemented on an object itself is //
// By default, the 'Trace' method implemented on an object itself is
// used to trace the pointers to other heap objects inside the object. // used to trace the pointers to other heap objects inside the object.
// //
// However, the TraceTrait can be specialized to use a different // However, the TraceTrait can be specialized to use a different
...@@ -193,17 +193,17 @@ class TraceTrait { ...@@ -193,17 +193,17 @@ class TraceTrait {
return AdjustAndMarkTrait<T>::GetTraceDescriptor(static_cast<T*>(self)); return AdjustAndMarkTrait<T>::GetTraceDescriptor(static_cast<T*>(self));
} }
static void Trace(Visitor*, void* self); static TraceWrapperDescriptor GetTraceWrapperDescriptor(void* self) {
static void TraceMarkedWrapper(const ScriptWrappableVisitor*, const void*); return AdjustAndMarkTrait<T>::GetTraceWrapperDescriptor(
static HeapObjectHeader* GetHeapObjectHeader(const void*); static_cast<T*>(self));
}
private: static HeapObjectHeader* GetHeapObjectHeader(void* self) {
static const T* ToWrapperTracingType(const void* t) { return AdjustAndMarkTrait<T>::GetHeapObjectHeader(static_cast<T*>(self));
static_assert(sizeof(T), "type needs to be defined");
static_assert(IsGarbageCollectedType<T>::value,
"only objects deriving from GarbageCollected can be used");
return reinterpret_cast<const T*>(t);
} }
static void Trace(Visitor*, void* self);
static void TraceWrappers(ScriptWrappableVisitor*, void*);
}; };
template <typename T> template <typename T>
...@@ -216,16 +216,13 @@ void TraceTrait<T>::Trace(Visitor* visitor, void* self) { ...@@ -216,16 +216,13 @@ void TraceTrait<T>::Trace(Visitor* visitor, void* self) {
} }
template <typename T> template <typename T>
void TraceTrait<T>::TraceMarkedWrapper(const ScriptWrappableVisitor* visitor, void TraceTrait<T>::TraceWrappers(ScriptWrappableVisitor* visitor, void* self) {
const void* t) { static_assert(sizeof(T), "type needs to be defined");
const T* traceable = ToWrapperTracingType(t); static_assert(IsGarbageCollectedType<T>::value,
AdjustAndMarkTrait<T>::TraceMarkedWrapper(visitor, traceable); "only objects deriving from GarbageCollected can be used");
visitor->DispatchTraceWrappers(static_cast<T*>(self));
} }
template <typename T>
HeapObjectHeader* TraceTrait<T>::GetHeapObjectHeader(const void* t) {
return AdjustAndMarkTrait<T>::GetHeapObjectHeader(ToWrapperTracingType(t));
}
template <typename T, typename Traits> template <typename T, typename Traits>
struct TraceTrait<HeapVectorBacking<T, Traits>> { struct TraceTrait<HeapVectorBacking<T, Traits>> {
......
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