1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120
|
// Copyright 2014 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.
#ifndef InlinedGlobalMarkingVisitor_h
#define InlinedGlobalMarkingVisitor_h
#include "platform/heap/MarkingVisitorImpl.h"
namespace blink {
class InlinedGlobalMarkingVisitor final : public VisitorHelper<InlinedGlobalMarkingVisitor>, public MarkingVisitorImpl<InlinedGlobalMarkingVisitor> {
public:
friend class VisitorHelper<InlinedGlobalMarkingVisitor>;
using Helper = VisitorHelper<InlinedGlobalMarkingVisitor>;
friend class MarkingVisitorImpl<InlinedGlobalMarkingVisitor>;
using Impl = MarkingVisitorImpl<InlinedGlobalMarkingVisitor>;
explicit InlinedGlobalMarkingVisitor(Visitor* visitor)
: m_visitor(visitor)
{
ASSERT(visitor->isGlobalMarkingVisitor());
}
// Hack to unify interface to visitor->trace().
// Without this hack, we need to use visitor.trace() for
// trace(InlinedGlobalMarkingVisitor) and visitor->trace() for trace(Visitor*).
InlinedGlobalMarkingVisitor* operator->() { return this; }
// FIXME: This is a temporary hack to cheat old Blink GC plugin checks.
// Old GC Plugin doesn't accept calling Helper::trace
// as a valid mark. This manual redirect worksaround the issue by
// making the method declaration on Visitor class.
template <typename T>
void trace(const T& t)
{
Helper::trace(t);
}
using Helper::mark;
inline void mark(const void* objectPointer, TraceCallback callback)
{
Impl::mark(objectPointer, callback);
}
using Helper::registerWeakMembers;
inline void registerWeakMembers(const void* closure, const void* objectPointer, WeakPointerCallback callback)
{
Impl::registerWeakMembers(closure, objectPointer, callback);
}
using Impl::ensureMarked;
inline bool canTraceEagerly() const { return m_visitor->canTraceEagerly(); }
Visitor* getUninlined() { return m_visitor; }
protected:
// Methods to be called from MarkingVisitorImpl.
inline bool shouldMarkObject(const void*)
{
// As this is global marking visitor, we need to mark all objects.
return true;
}
#if ENABLE(GC_PROFILE_MARKING)
inline void recordObjectGraphEdge(const void* objectPointer)
{
m_visitor->recordObjectGraphEdge(objectPointer);
}
#endif
private:
static InlinedGlobalMarkingVisitor fromHelper(Helper* helper)
{
return *static_cast<InlinedGlobalMarkingVisitor*>(helper);
}
Visitor* m_visitor;
};
// If T does not support trace(InlinedGlobalMarkingVisitor).
template <typename T>
struct TraceCompatibilityAdaptor<T, false> {
inline static void trace(blink::Visitor* visitor, T* self)
{
self->trace(visitor);
}
inline static void trace(InlinedGlobalMarkingVisitor visitor, T* self)
{
// We revert to dynamic trace(Visitor*) for tracing T.
self->trace(visitor.getUninlined());
}
};
// If T supports trace(InlinedGlobalMarkingVisitor).
template <typename T>
struct TraceCompatibilityAdaptor<T, true> {
inline static void trace(blink::Visitor* visitor, T* self)
{
if (visitor->isGlobalMarkingVisitor()) {
// Switch to inlined global marking dispatch.
self->trace(InlinedGlobalMarkingVisitor(visitor));
} else {
self->trace(visitor);
}
}
inline static void trace(InlinedGlobalMarkingVisitor visitor, T* self)
{
self->trace(visitor);
}
};
} // namespace blink
#endif
|