Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(237)

Side by Side Diff: Source/platform/heap/Visitor.h

Issue 1120893003: Oilpan: Put all TraceTraits into TraceTraits.h (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « Source/platform/heap/TraceTraits.h ('k') | Source/platform/heap/blink_heap.gypi » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2013 Google Inc. All rights reserved. 2 * Copyright (C) 2013 Google Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are 5 * modification, are permitted provided that the following conditions are
6 * met: 6 * met:
7 * 7 *
8 * * Redistributions of source code must retain the above copyright 8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above 10 * * Redistributions in binary form must reproduce the above
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
45 #if ENABLE(GC_PROFILING) 45 #if ENABLE(GC_PROFILING)
46 #include "wtf/InstanceCounter.h" 46 #include "wtf/InstanceCounter.h"
47 #include "wtf/text/WTFString.h" 47 #include "wtf/text/WTFString.h"
48 #endif 48 #endif
49 49
50 namespace blink { 50 namespace blink {
51 51
52 template<typename T> class GarbageCollected; 52 template<typename T> class GarbageCollected;
53 class HeapObjectHeader; 53 class HeapObjectHeader;
54 class InlinedGlobalMarkingVisitor; 54 class InlinedGlobalMarkingVisitor;
55 template<typename T> class Member; 55 template<typename T> class TraceTrait;
56 template<typename T> class CrossThreadPersistent; 56 template<typename T> class TraceEagerlyTrait;
57 class Visitor; 57 class Visitor;
58 template<typename T> class WeakMember;
59 58
60 // The TraceMethodDelegate is used to convert a trace method for type T to a Tra ceCallback. 59 // The TraceMethodDelegate is used to convert a trace method for type T to a Tra ceCallback.
61 // This allows us to pass a type's trace method as a parameter to the Persistent Node 60 // This allows us to pass a type's trace method as a parameter to the Persistent Node
62 // constructor. The PersistentNode constructor needs the specific trace method d ue an issue 61 // constructor. The PersistentNode constructor needs the specific trace method d ue an issue
63 // with the Windows compiler which instantiates even unused variables. This caus es problems 62 // with the Windows compiler which instantiates even unused variables. This caus es problems
64 // in header files where we have only forward declarations of classes. 63 // in header files where we have only forward declarations of classes.
65 template<typename T, void (T::*method)(Visitor*)> 64 template<typename T, void (T::*method)(Visitor*)>
66 struct TraceMethodDelegate { 65 struct TraceMethodDelegate {
67 static void trampoline(Visitor* visitor, void* self) { (reinterpret_cast<T*> (self)->*method)(visitor); } 66 static void trampoline(Visitor* visitor, void* self) { (reinterpret_cast<T*> (self)->*method)(visitor); }
68 }; 67 };
69 68
70 template<typename T, bool = WTF::IsSubclassOfTemplate<typename WTF::RemoveConst< T>::Type, GarbageCollected>::value> class NeedsAdjustAndMark;
71
72 template<typename T>
73 class NeedsAdjustAndMark<T, true> {
74 public:
75 static const bool value = false;
76 };
77
78 template <typename T> const bool NeedsAdjustAndMark<T, true>::value;
79
80 template<typename T>
81 class NeedsAdjustAndMark<T, false> {
82 public:
83 static const bool value = IsGarbageCollectedMixin<typename WTF::RemoveConst< T>::Type>::value;
84 };
85
86 template <typename T> const bool NeedsAdjustAndMark<T, false>::value;
87
88 // HasInlinedTraceMethod<T>::value is true for T supporting 69 // HasInlinedTraceMethod<T>::value is true for T supporting
89 // T::trace(InlinedGlobalMarkingVisitor). 70 // T::trace(InlinedGlobalMarkingVisitor).
90 // The template works by checking if T::HasInlinedTraceMethodMarker type is 71 // The template works by checking if T::HasInlinedTraceMethodMarker type is
91 // available using SFINAE. The HasInlinedTraceMethodMarker type is defined 72 // available using SFINAE. The HasInlinedTraceMethodMarker type is defined
92 // by DECLARE_TRACE and DEFINE_INLINE_TRACE helper macros, which are used to 73 // by DECLARE_TRACE and DEFINE_INLINE_TRACE helper macros, which are used to
93 // define trace methods supporting both inlined/uninlined tracing. 74 // define trace methods supporting both inlined/uninlined tracing.
94 template <typename T> 75 template <typename T>
95 struct HasInlinedTraceMethod { 76 struct HasInlinedTraceMethod {
96 private: 77 private:
97 typedef char YesType; 78 typedef char YesType;
98 struct NoType { 79 struct NoType {
99 char padding[8]; 80 char padding[8];
100 }; 81 };
101 82
102 template <typename U> static YesType checkMarker(typename U::HasInlinedTrace MethodMarker*); 83 template <typename U> static YesType checkMarker(typename U::HasInlinedTrace MethodMarker*);
103 template <typename U> static NoType checkMarker(...); 84 template <typename U> static NoType checkMarker(...);
104 public: 85 public:
105 static const bool value = sizeof(checkMarker<T>(nullptr)) == sizeof(YesType) ; 86 static const bool value = sizeof(checkMarker<T>(nullptr)) == sizeof(YesType) ;
106 }; 87 };
107 88
108 template<typename T, bool = NeedsAdjustAndMark<T>::value> class DefaultTraceTrai t;
109
110 // The TraceTrait is used to specify how to mark an object pointer and
111 // how to trace all of the pointers in the object.
112 //
113 // By default, the 'trace' method implemented on an object itself is
114 // used to trace the pointers to other heap objects inside the object.
115 //
116 // However, the TraceTrait can be specialized to use a different
117 // implementation. A common case where a TraceTrait specialization is
118 // needed is when multiple inheritance leads to pointers that are not
119 // to the start of the object in the Blink garbage-collected heap. In
120 // that case the pointer has to be adjusted before marking.
121 template<typename T>
122 class TraceTrait {
123 public:
124 static void trace(Visitor*, void* self);
125 static void trace(InlinedGlobalMarkingVisitor, void* self);
126
127 template<typename VisitorDispatcher>
128 static void mark(VisitorDispatcher visitor, const T* t)
129 {
130 DefaultTraceTrait<T>::mark(visitor, t);
131 }
132
133 #if ENABLE(ASSERT)
134 static void checkGCInfo(const T* t)
135 {
136 DefaultTraceTrait<T>::checkGCInfo(t);
137 }
138 #endif
139 };
140
141 template<typename T> class TraceTrait<const T> : public TraceTrait<T> { };
142
143 #define DECLARE_TRACE_IMPL(maybevirtual) \ 89 #define DECLARE_TRACE_IMPL(maybevirtual) \
144 public: \ 90 public: \
145 typedef int HasInlinedTraceMethodMarker; \ 91 typedef int HasInlinedTraceMethodMarker; \
146 maybevirtual void trace(Visitor*); \ 92 maybevirtual void trace(Visitor*); \
147 maybevirtual void trace(InlinedGlobalMarkingVisitor); \ 93 maybevirtual void trace(InlinedGlobalMarkingVisitor); \
148 \ 94 \
149 private: \ 95 private: \
150 template <typename VisitorDispatcher> void traceImpl(VisitorDispatcher); \ 96 template <typename VisitorDispatcher> void traceImpl(VisitorDispatcher); \
151 \ 97 \
152 public: 98 public:
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
185 template <typename VisitorDispatcher> \ 131 template <typename VisitorDispatcher> \
186 inline void traceAfterDispatchImpl(VisitorDispatcher visitor) 132 inline void traceAfterDispatchImpl(VisitorDispatcher visitor)
187 133
188 #define EMPTY_MACRO_ARGUMENT 134 #define EMPTY_MACRO_ARGUMENT
189 135
190 #define DECLARE_TRACE() DECLARE_TRACE_IMPL(EMPTY_MACRO_ARGUMENT) 136 #define DECLARE_TRACE() DECLARE_TRACE_IMPL(EMPTY_MACRO_ARGUMENT)
191 #define DECLARE_VIRTUAL_TRACE() DECLARE_TRACE_IMPL(virtual) 137 #define DECLARE_VIRTUAL_TRACE() DECLARE_TRACE_IMPL(virtual)
192 #define DEFINE_INLINE_TRACE() DEFINE_INLINE_TRACE_IMPL(EMPTY_MACRO_ARGUMENT) 138 #define DEFINE_INLINE_TRACE() DEFINE_INLINE_TRACE_IMPL(EMPTY_MACRO_ARGUMENT)
193 #define DEFINE_INLINE_VIRTUAL_TRACE() DEFINE_INLINE_TRACE_IMPL(virtual) 139 #define DEFINE_INLINE_VIRTUAL_TRACE() DEFINE_INLINE_TRACE_IMPL(virtual)
194 140
195 // If MARKER_EAGER_TRACING is set to 1, a marker thread is allowed 141 template<typename T, bool = WTF::IsSubclassOfTemplate<typename WTF::RemoveConst< T>::Type, GarbageCollected>::value> class NeedsAdjustAndMark;
196 // to directly invoke the trace() method of not-as-yet marked objects upon
197 // marking. If it is set to 0, the |trace()| callback for an object will
198 // be pushed onto an explicit mark stack, which the marker proceeds to
199 // iteratively pop and invoke. The eager scheme enables inlining of a trace()
200 // method inside another, the latter keeps system call stack usage bounded
201 // and under explicit control.
202 //
203 // If eager tracing leads to excessively deep |trace()| call chains (and
204 // the system stack usage that this brings), the marker implementation will
205 // switch to using an explicit mark stack. Recursive and deep object graphs
206 // are uncommon for Blink objects.
207 //
208 // A class type can opt out of eager tracing by declaring a TraceEagerlyTrait<>
209 // specialization, mapping the trait's |value| to |false| (see the
210 // WILL_NOT_BE_EAGERLY_TRACED_CLASS() macros below.) For Blink, this is done for
211 // the small set of GCed classes that are directly recursive.
212 //
213 // The TraceEagerlyTrait<T> trait controls whether or not a class
214 // (and its subclasses) should be eagerly traced or not.
215 //
216 // If |TraceEagerlyTrait<T>::value| is |true|, then the marker thread
217 // should invoke |trace()| on not-yet-marked objects deriving from class T
218 // right away, and not queue their trace callbacks on its marker stack,
219 // which it will do if |value| is |false|.
220 //
221 // The trait can be declared to enable/disable eager tracing for a class T
222 // and any of its subclasses, or just to the class T, but none of its
223 // subclasses.
224 //
225 template<typename T, typename Enabled = void>
226 class TraceEagerlyTrait {
227 public:
228 static const bool value = true;
229 };
230
231 // Disable eager tracing for TYPE, but not any of its subclasses.
232 #define WILL_NOT_BE_EAGERLY_TRACED_CLASS(TYPE) \
233 template<> \
234 class TraceEagerlyTrait<TYPE> { \
235 public: \
236 static const bool value = false; \
237 }
238 142
239 template<typename T> 143 template<typename T>
240 class TraceEagerlyTrait<Member<T>> { 144 class NeedsAdjustAndMark<T, true> {
241 public:
242 static const bool value = TraceEagerlyTrait<T>::value;
243 };
244
245 template<typename T>
246 class TraceEagerlyTrait<WeakMember<T>> {
247 public:
248 static const bool value = TraceEagerlyTrait<T>::value;
249 };
250
251 template<typename T>
252 class TraceEagerlyTrait<Persistent<T>> {
253 public:
254 static const bool value = TraceEagerlyTrait<T>::value;
255 };
256
257 template<typename T>
258 class TraceEagerlyTrait<CrossThreadPersistent<T>> {
259 public:
260 static const bool value = TraceEagerlyTrait<T>::value;
261 };
262
263 template<typename ValueArg, size_t inlineCapacity> class HeapListHashSetAllocato r;
264 template<typename T, size_t inlineCapacity>
265 class TraceEagerlyTrait<WTF::ListHashSetNode<T, HeapListHashSetAllocator<T, inli neCapacity>>> {
266 public: 145 public:
267 static const bool value = false; 146 static const bool value = false;
268 }; 147 };
148 template <typename T> const bool NeedsAdjustAndMark<T, true>::value;
149
150 template<typename T>
151 class NeedsAdjustAndMark<T, false> {
152 public:
153 static const bool value = IsGarbageCollectedMixin<typename WTF::RemoveConst< T>::Type>::value;
154 };
155 template <typename T> const bool NeedsAdjustAndMark<T, false>::value;
269 156
270 template<typename T, bool = NeedsAdjustAndMark<T>::value> class ObjectAliveTrait ; 157 template<typename T, bool = NeedsAdjustAndMark<T>::value> class ObjectAliveTrait ;
271 158
272 template<typename T> 159 template<typename T>
273 class ObjectAliveTrait<T, false> { 160 class ObjectAliveTrait<T, false> {
274 public: 161 public:
275 template<typename VisitorDispatcher> 162 template<typename VisitorDispatcher>
276 static bool isHeapObjectAlive(VisitorDispatcher visitor, T* obj) 163 static bool isHeapObjectAlive(VisitorDispatcher visitor, T* obj)
277 { 164 {
278 return visitor->isMarked(obj); 165 return visitor->isMarked(obj);
(...skipping 311 matching lines...) Expand 10 before | Expand all | Expand 10 after
590 477
591 template <typename Derived> 478 template <typename Derived>
592 template <typename T> 479 template <typename T>
593 void VisitorHelper<Derived>::handleWeakCell(Visitor* self, void* obj) 480 void VisitorHelper<Derived>::handleWeakCell(Visitor* self, void* obj)
594 { 481 {
595 T** cell = reinterpret_cast<T**>(obj); 482 T** cell = reinterpret_cast<T**>(obj);
596 if (*cell && !self->isHeapObjectAlive(*cell)) 483 if (*cell && !self->isHeapObjectAlive(*cell))
597 *cell = nullptr; 484 *cell = nullptr;
598 } 485 }
599 486
600 template<typename T> struct GCInfoTrait;
601
602 template<typename T>
603 class DefaultTraceTrait<T, false> {
604 public:
605 template<typename VisitorDispatcher>
606 static void mark(VisitorDispatcher visitor, const T* t)
607 {
608 // Default mark method of the trait just calls the two-argument mark
609 // method on the visitor. The second argument is the static trace method
610 // of the trait, which by default calls the instance method
611 // trace(Visitor*) on the object.
612 //
613 // If the trait allows it, invoke the trace callback right here on the
614 // not-yet-marked object.
615 if (TraceEagerlyTrait<T>::value) {
616 // Protect against too deep trace call chains, and the
617 // unbounded system stack usage they can bring about.
618 //
619 // Assert against deep stacks so as to flush them out,
620 // but test and appropriately handle them should they occur
621 // in release builds.
622 //
623 // ASan adds extra stack usage, so disable the assert when it is
624 // enabled so as to avoid testing against a much lower & too low,
625 // stack depth threshold.
626 #if !defined(ADDRESS_SANITIZER)
627 ASSERT(StackFrameDepth::isSafeToRecurse());
628 #endif
629 if (LIKELY(StackFrameDepth::isSafeToRecurse())) {
630 if (visitor->ensureMarked(t)) {
631 TraceTrait<T>::trace(visitor, const_cast<T*>(t));
632 }
633 return;
634 }
635 }
636 visitor->mark(const_cast<T*>(t), &TraceTrait<T>::trace);
637 }
638
639 #if ENABLE(ASSERT)
640 static void checkGCInfo(const T* t)
641 {
642 assertObjectHasGCInfo(const_cast<T*>(t), GCInfoTrait<T>::index());
643 }
644 #endif
645 };
646
647 template<typename T>
648 class DefaultTraceTrait<T, true> {
649 public:
650 template<typename VisitorDispatcher>
651 static void mark(VisitorDispatcher visitor, const T* self)
652 {
653 if (!self)
654 return;
655
656 // If you hit this ASSERT, it means that there is a dangling pointer
657 // from a live thread heap to a dead thread heap. We must eliminate
658 // the dangling pointer.
659 // Release builds don't have the ASSERT, but it is OK because
660 // release builds will crash at the following self->adjustAndMark
661 // because all the entries of the orphaned heaps are zeroed out and
662 // thus the item does not have a valid vtable.
663 ASSERT(!pageFromObject(self)->orphaned());
664 self->adjustAndMark(visitor);
665 }
666
667 #if ENABLE(ASSERT)
668 static void checkGCInfo(const T*) { }
669 #endif
670 };
671
672 #if ENABLE(GC_PROFILING) 487 #if ENABLE(GC_PROFILING)
673 template<typename T> 488 template<typename T>
674 struct TypenameStringTrait { 489 struct TypenameStringTrait {
675 static const String& get() 490 static const String& get()
676 { 491 {
677 DEFINE_STATIC_LOCAL(String, typenameString, (WTF::extractTypeNameFromFun ctionName(WTF::extractNameFunction<T>()))); 492 DEFINE_STATIC_LOCAL(String, typenameString, (WTF::extractTypeNameFromFun ctionName(WTF::extractNameFunction<T>())));
678 return typenameString; 493 return typenameString;
679 } 494 }
680 }; 495 };
681 #endif 496 #endif
682 497
683 } // namespace blink 498 } // namespace blink
684 499
685 #endif // Visitor_h 500 #endif // Visitor_h
OLDNEW
« no previous file with comments | « Source/platform/heap/TraceTraits.h ('k') | Source/platform/heap/blink_heap.gypi » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698