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

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

Issue 1168503008: Oilpan: Remove PersistentBase (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 5 years, 6 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 | « no previous file | Source/platform/heap/ThreadState.h » ('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) 2014 Google Inc. All rights reserved. 2 * Copyright (C) 2014 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 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
57 57
58 NO_LAZY_SWEEP_SANITIZE_ADDRESS 58 NO_LAZY_SWEEP_SANITIZE_ADDRESS
59 bool isHeapObjectAlive() { return m_trace; } 59 bool isHeapObjectAlive() { return m_trace; }
60 60
61 virtual ~PersistentNode() 61 virtual ~PersistentNode()
62 { 62 {
63 ASSERT(isHeapObjectAlive()); 63 ASSERT(isHeapObjectAlive());
64 m_trace = nullptr; 64 m_trace = nullptr;
65 } 65 }
66 66
67 // This operator= is important. Without having the operator=, m_next and
68 // m_prev are inproperly copied and it breaks the link list of the
69 // persistent handles.
70 inline PersistentNode& operator=(const PersistentNode& otherref) { return *t his; }
71
72 private:
67 // Ideally the trace method should be virtual and automatically dispatch 73 // Ideally the trace method should be virtual and automatically dispatch
68 // to the most specific implementation. However having a virtual method 74 // to the most specific implementation. However having a virtual method
69 // on PersistentNode leads to too eager template instantiation with MSVC 75 // on PersistentNode leads to too eager template instantiation with MSVC
70 // which leads to include cycles. 76 // which leads to include cycles.
71 // Instead we call the constructor with a TraceCallback which knows the 77 // Instead we call the constructor with a TraceCallback which knows the
72 // type of the most specific child and calls trace directly. See 78 // type of the most specific child and calls trace directly. See
73 // TraceMethodDelegate in Visitor.h for how this is done. 79 // TraceMethodDelegate in Visitor.h for how this is done.
74 void trace(Visitor* visitor) 80 void tracePersistentNode(Visitor* visitor)
75 { 81 {
76 m_trace(visitor, this); 82 m_trace(visitor, this);
77 } 83 }
78 84
79 protected:
80 TraceCallback m_trace; 85 TraceCallback m_trace;
81
82 private:
83 PersistentNode* m_next; 86 PersistentNode* m_next;
84 PersistentNode* m_prev; 87 PersistentNode* m_prev;
85 88
86 template<typename RootsAccessor, typename Owner> friend class PersistentBase ; 89 template<typename T> friend class CrossThreadPersistent;
90 template<typename T> friend class Persistent;
91 template<typename Collection> friend class PersistentHeapCollectionBase;
87 friend class PersistentAnchor; 92 friend class PersistentAnchor;
93 friend class PersistentNode;
88 friend class ThreadState; 94 friend class ThreadState;
89 }; 95 };
90 96
91 // RootsAccessor for Persistent that provides access to thread-local list
92 // of persistent handles. Can only be used to create handles that
93 // are constructed and destructed on the same thread.
94 template<ThreadAffinity Affinity>
95 class ThreadLocalPersistents {
96 public:
97 static PersistentNode* roots() { return state()->roots(); }
98
99 // No locking required. Just check that we are at the right thread.
100 class Lock {
101 public:
102 Lock() { state()->checkThread(); }
103 };
104
105 private:
106 static ThreadState* state() { return ThreadStateFor<Affinity>::state(); }
107 };
108
109 // RootsAccessor for Persistent that provides synchronized access to global
110 // list of persistent handles. Can be used for persistent handles that are
111 // passed between threads.
112 class GlobalPersistents {
113 public:
114 static PersistentNode* roots() { return &ThreadState::globalRoots(); }
115
116 class Lock {
117 public:
118 Lock() : m_locker(ThreadState::globalRootsMutex()) { }
119 private:
120 MutexLocker m_locker;
121 };
122 };
123
124 // Base class for persistent handles. RootsAccessor specifies which list to
125 // link resulting handle into. Owner specifies the class containing trace
126 // method.
127 template<typename RootsAccessor, typename Owner>
128 class PersistentBase : public PersistentNode {
129 public:
130 NO_LAZY_SWEEP_SANITIZE_ADDRESS
131 ~PersistentBase()
132 {
133 typename RootsAccessor::Lock lock;
134 ASSERT(m_roots == RootsAccessor::roots()); // Check that the thread is u sing the same roots list.
135 ASSERT(isHeapObjectAlive());
136 ASSERT(m_next->isHeapObjectAlive());
137 ASSERT(m_prev->isHeapObjectAlive());
138 m_next->m_prev = m_prev;
139 m_prev->m_next = m_next;
140 }
141
142 protected:
143 inline PersistentBase()
144 : PersistentNode(TraceMethodDelegate<Owner, &Owner::trace>::trampoline)
145 #if ENABLE(ASSERT)
146 , m_roots(RootsAccessor::roots())
147 #endif
148 {
149 // Persistent must belong to a thread that will GC it.
150 ASSERT(m_roots == GlobalPersistents::roots() || ThreadState::current());
151 typename RootsAccessor::Lock lock;
152 m_prev = RootsAccessor::roots();
153 m_next = m_prev->m_next;
154 m_prev->m_next = this;
155 m_next->m_prev = this;
156 }
157
158 inline PersistentBase& operator=(const PersistentBase& otherref) { return *t his; }
159
160 #if ENABLE(ASSERT)
161 private:
162 PersistentNode* m_roots;
163 #endif
164 };
165
166 // A dummy Persistent handle that ensures the list of persistents is never null. 97 // A dummy Persistent handle that ensures the list of persistents is never null.
167 // This removes a test from a hot path. 98 // This removes a test from a hot path.
168 class PersistentAnchor : public PersistentNode { 99 class PersistentAnchor : public PersistentNode {
169 public: 100 public:
170 void trace(Visitor* visitor) 101 void tracePersistentNodes(Visitor* visitor)
171 { 102 {
172 for (PersistentNode* current = m_next; current != this; current = curren t->m_next) 103 for (PersistentNode* current = m_next; current != this; current = curren t->m_next)
173 current->trace(visitor); 104 current->tracePersistentNode(visitor);
174 } 105 }
175 106
176 int numberOfPersistents() 107 int numberOfPersistents()
177 { 108 {
178 int numberOfPersistents = 0; 109 int numberOfPersistents = 0;
179 for (PersistentNode* current = m_next; current != this; current = curren t->m_next) 110 for (PersistentNode* current = m_next; current != this; current = curren t->m_next)
180 ++numberOfPersistents; 111 ++numberOfPersistents;
181 return numberOfPersistents; 112 return numberOfPersistents;
182 } 113 }
183 114
184 virtual ~PersistentAnchor() 115 virtual ~PersistentAnchor()
185 { 116 {
186 // FIXME: oilpan: Ideally we should have no left-over persistents at thi s point. However currently there is a 117 // FIXME: oilpan: Ideally we should have no left-over persistents at thi s point. However currently there is a
187 // large number of objects leaked when we tear down the main thread. Sin ce some of these might contain a 118 // large number of objects leaked when we tear down the main thread. Sin ce some of these might contain a
188 // persistent or e.g. be RefCountedGarbageCollected we cannot guarantee there are no remaining Persistents at 119 // persistent or e.g. be RefCountedGarbageCollected we cannot guarantee there are no remaining Persistents at
189 // this point. 120 // this point.
190 } 121 }
191 122
123 template<typename VisitorDispatcher>
124 void trace(VisitorDispatcher visitor)
125 {
126 ASSERT_NOT_REACHED();
127 }
128
192 private: 129 private:
193 PersistentAnchor() : PersistentNode(TraceMethodDelegate<PersistentAnchor, &P ersistentAnchor::trace>::trampoline) 130 PersistentAnchor() : PersistentNode(TraceMethodDelegate<PersistentAnchor, &P ersistentAnchor::trace>::trampoline)
194 { 131 {
195 m_next = this; 132 m_next = this;
196 m_prev = this; 133 m_prev = this;
197 } 134 }
198 135
199 friend class ThreadState; 136 friend class ThreadState;
200 }; 137 };
201 138
202 template<typename T>
203 class CrossThreadPersistent;
204
205 // Persistent handles are used to store pointers into the 139 // Persistent handles are used to store pointers into the
206 // managed heap. As long as the Persistent handle is alive 140 // managed heap. As long as the Persistent handle is alive
207 // the GC will keep the object pointed to alive. Persistent 141 // the GC will keep the object pointed to alive. Persistent
208 // handles can be stored in objects and they are not scoped. 142 // handles can be stored in objects and they are not scoped.
209 // Persistent handles must not be used to contain pointers 143 // Persistent handles must not be used to contain pointers
210 // between objects that are in the managed heap. They are only 144 // between objects that are in the managed heap. They are only
211 // meant to point to managed heap objects from variables/members 145 // meant to point to managed heap objects from variables/members
212 // outside the managed heap. 146 // outside the managed heap.
213 // 147 //
214 // A Persistent is always a GC root from the point of view of 148 // A Persistent is always a GC root from the point of view of
215 // the garbage collector. 149 // the garbage collector.
216 // 150 //
217 // We have to construct and destruct Persistent in the same thread. 151 // We have to construct and destruct Persistent in the same thread.
218 template<typename T> 152 template<typename T>
219 class Persistent : public PersistentBase<ThreadLocalPersistents<ThreadingTrait<T >::Affinity>, Persistent<T>> { 153 class Persistent : public PersistentNode {
220 public: 154 public:
221 Persistent() : m_raw(nullptr) { } 155 Persistent() : PersistentNode(TraceMethodDelegate<Persistent<T>, &Persistent <T>::trace>::trampoline), m_raw(nullptr)
haraken 2015/06/08 04:31:29 It is unfortunate that we have to write "TraceMeth
156 {
157 initialize();
158 }
222 159
223 Persistent(std::nullptr_t) : m_raw(nullptr) { } 160 Persistent(std::nullptr_t) : PersistentNode(TraceMethodDelegate<Persistent<T >, &Persistent<T>::trace>::trampoline), m_raw(nullptr)
161 {
162 initialize();
163 }
224 164
225 Persistent(T* raw) : m_raw(raw) 165 Persistent(T* raw) : PersistentNode(TraceMethodDelegate<Persistent<T>, &Pers istent<T>::trace>::trampoline), m_raw(raw)
226 { 166 {
167 initialize();
227 checkPointer(); 168 checkPointer();
228 recordBacktrace(); 169 recordBacktrace();
229 } 170 }
230 171
231 explicit Persistent(T& raw) : m_raw(&raw) 172 Persistent(T& raw) : PersistentNode(TraceMethodDelegate<Persistent<T>, &Pers istent<T>::trace>::trampoline), m_raw(&raw)
232 { 173 {
174 initialize();
233 checkPointer(); 175 checkPointer();
234 recordBacktrace(); 176 recordBacktrace();
235 } 177 }
236 178
237 Persistent(const Persistent& other) : m_raw(other) 179 Persistent(const Persistent& other) : PersistentNode(TraceMethodDelegate<Per sistent<T>, &Persistent<T>::trace>::trampoline), m_raw(other)
238 { 180 {
181 initialize();
239 checkPointer(); 182 checkPointer();
240 recordBacktrace(); 183 recordBacktrace();
241 } 184 }
242 185
243 template<typename U> 186 template<typename U>
244 Persistent(const Persistent<U>& other) : m_raw(other) 187 Persistent(const Persistent<U>& other) : PersistentNode(TraceMethodDelegate< Persistent<T>, &Persistent<T>::trace>::trampoline), m_raw(other)
245 { 188 {
189 initialize();
246 checkPointer(); 190 checkPointer();
247 recordBacktrace(); 191 recordBacktrace();
248 } 192 }
249 193
250 template<typename U> 194 template<typename U>
251 Persistent(const Member<U>& other) : m_raw(other) 195 Persistent(const Member<U>& other) : PersistentNode(TraceMethodDelegate<Pers istent<T>, &Persistent<T>::trace>::trampoline), m_raw(other)
252 { 196 {
197 initialize();
253 checkPointer(); 198 checkPointer();
254 recordBacktrace(); 199 recordBacktrace();
255 } 200 }
256 201
257 template<typename U> 202 template<typename U>
258 Persistent(const RawPtr<U>& other) : m_raw(other.get()) 203 Persistent(const RawPtr<U>& other) : PersistentNode(TraceMethodDelegate<Pers istent<T>, &Persistent<T>::trace>::trampoline), m_raw(other.get())
259 { 204 {
205 initialize();
260 checkPointer(); 206 checkPointer();
261 recordBacktrace(); 207 recordBacktrace();
262 } 208 }
263 209
264 void clear() { m_raw = nullptr; } 210 void clear() { m_raw = nullptr; }
265 211
266 virtual ~Persistent() 212 virtual ~Persistent()
267 { 213 {
214 uninitialize();
268 m_raw = nullptr; 215 m_raw = nullptr;
269 } 216 }
270 217
271 template<typename VisitorDispatcher> 218 template<typename VisitorDispatcher>
272 void trace(VisitorDispatcher visitor) 219 void trace(VisitorDispatcher visitor)
273 { 220 {
274 static_assert(sizeof(T), "T must be fully defined"); 221 static_assert(sizeof(T), "T must be fully defined");
275 static_assert(IsGarbageCollectedType<T>::value, "T needs to be a garbage collected object"); 222 static_assert(IsGarbageCollectedType<T>::value, "T needs to be a garbage collected object");
276 #if ENABLE(GC_PROFILING) 223 #if ENABLE(GC_PROFILING)
277 visitor->setHostInfo(this, m_tracingName.isEmpty() ? "Persistent" : m_tr acingName); 224 visitor->setHostInfo(this, m_tracingName.isEmpty() ? "Persistent" : m_tr acingName);
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
341 { 288 {
342 m_raw = other; 289 m_raw = other;
343 checkPointer(); 290 checkPointer();
344 recordBacktrace(); 291 recordBacktrace();
345 return *this; 292 return *this;
346 } 293 }
347 294
348 T* get() const { return m_raw; } 295 T* get() const { return m_raw; }
349 296
350 private: 297 private:
298 void initialize()
299 {
300 ThreadState* state = ThreadStateFor<ThreadingTrait<T>::Affinity>::state( );
301 state->checkThread();
302 m_prev = state->roots();
303 m_next = m_prev->m_next;
304 m_prev->m_next = this;
305 m_next->m_prev = this;
306 }
307
308 void uninitialize()
309 {
310 ASSERT(isHeapObjectAlive());
311 ASSERT(m_next->isHeapObjectAlive());
312 ASSERT(m_prev->isHeapObjectAlive());
313 m_next->m_prev = m_prev;
314 m_prev->m_next = m_next;
315 }
316
351 void checkPointer() 317 void checkPointer()
352 { 318 {
353 #if ENABLE(ASSERT) 319 #if ENABLE(ASSERT)
354 if (!m_raw) 320 if (!m_raw)
355 return; 321 return;
356 322
357 // Heap::isHeapObjectAlive(m_raw) checks that m_raw is a traceable 323 // Heap::isHeapObjectAlive(m_raw) checks that m_raw is a traceable
358 // object. In other words, it checks that the pointer is either of: 324 // object. In other words, it checks that the pointer is either of:
359 // 325 //
360 // (a) a pointer to the head of an on-heap object. 326 // (a) a pointer to the head of an on-heap object.
(...skipping 15 matching lines...) Expand all
376 String m_tracingName; 342 String m_tracingName;
377 #else 343 #else
378 inline void recordBacktrace() const { } 344 inline void recordBacktrace() const { }
379 #endif 345 #endif
380 T* m_raw; 346 T* m_raw;
381 }; 347 };
382 348
383 // Unlike Persistent, we can destruct a CrossThreadPersistent in a thread 349 // Unlike Persistent, we can destruct a CrossThreadPersistent in a thread
384 // different from the construction thread. 350 // different from the construction thread.
385 template<typename T> 351 template<typename T>
386 class CrossThreadPersistent : public PersistentBase<GlobalPersistents, CrossThre adPersistent<T>> { 352 class CrossThreadPersistent : public PersistentNode {
387 public: 353 public:
388 CrossThreadPersistent() : m_raw(nullptr) { } 354 CrossThreadPersistent() : PersistentNode(TraceMethodDelegate<CrossThreadPers istent<T>, &CrossThreadPersistent<T>::trace>::trampoline), m_raw(nullptr)
355 {
356 initialize();
357 }
389 358
390 CrossThreadPersistent(std::nullptr_t) : m_raw(nullptr) { } 359 CrossThreadPersistent(std::nullptr_t) : PersistentNode(TraceMethodDelegate<C rossThreadPersistent<T>, &CrossThreadPersistent<T>::trace>::trampoline), m_raw(n ullptr)
360 {
361 initialize();
362 }
391 363
392 CrossThreadPersistent(T* raw) : m_raw(raw) 364 CrossThreadPersistent(T* raw) : PersistentNode(TraceMethodDelegate<CrossThre adPersistent<T>, &CrossThreadPersistent<T>::trace>::trampoline), m_raw(raw)
393 { 365 {
366 initialize();
394 checkPointer(); 367 checkPointer();
395 recordBacktrace(); 368 recordBacktrace();
396 } 369 }
397 370
398 explicit CrossThreadPersistent(T& raw) : m_raw(&raw) 371 CrossThreadPersistent(T& raw) : PersistentNode(TraceMethodDelegate<CrossThre adPersistent<T>, &CrossThreadPersistent<T>::trace>::trampoline), m_raw(&raw)
399 { 372 {
373 initialize();
400 checkPointer(); 374 checkPointer();
401 recordBacktrace(); 375 recordBacktrace();
402 } 376 }
403 377
404 CrossThreadPersistent(const CrossThreadPersistent& other) : m_raw(other) 378 CrossThreadPersistent(const CrossThreadPersistent& other) : PersistentNode(T raceMethodDelegate<CrossThreadPersistent<T>, &CrossThreadPersistent<T>::trace>:: trampoline), m_raw(other)
405 { 379 {
380 initialize();
406 checkPointer(); 381 checkPointer();
407 recordBacktrace(); 382 recordBacktrace();
408 } 383 }
409 384
410 template<typename U> 385 template<typename U>
411 CrossThreadPersistent(const CrossThreadPersistent<U>& other) : m_raw(other) 386 CrossThreadPersistent(const CrossThreadPersistent<U>& other) : PersistentNod e(TraceMethodDelegate<CrossThreadPersistent<T>, &CrossThreadPersistent<T>::trace >::trampoline), m_raw(other)
412 { 387 {
388 initialize();
413 checkPointer(); 389 checkPointer();
414 recordBacktrace(); 390 recordBacktrace();
415 } 391 }
416 392
417 template<typename U> 393 template<typename U>
418 CrossThreadPersistent(const Member<U>& other) : m_raw(other) 394 CrossThreadPersistent(const Member<U>& other) : PersistentNode(TraceMethodDe legate<CrossThreadPersistent<T>, &CrossThreadPersistent<T>::trace>::trampoline), m_raw(other)
419 { 395 {
396 initialize();
420 checkPointer(); 397 checkPointer();
421 recordBacktrace(); 398 recordBacktrace();
422 } 399 }
423 400
424 template<typename U> 401 template<typename U>
425 CrossThreadPersistent(const RawPtr<U>& other) : m_raw(other.get()) 402 CrossThreadPersistent(const RawPtr<U>& other) : PersistentNode(TraceMethodDe legate<CrossThreadPersistent<T>, &CrossThreadPersistent<T>::trace>::trampoline), m_raw(other.get())
426 { 403 {
404 initialize();
427 checkPointer(); 405 checkPointer();
428 recordBacktrace(); 406 recordBacktrace();
429 } 407 }
430 408
431 void clear() { m_raw = nullptr; } 409 void clear() { m_raw = nullptr; }
432 410
433 virtual ~CrossThreadPersistent() 411 virtual ~CrossThreadPersistent()
434 { 412 {
413 uninitialize();
435 m_raw = nullptr; 414 m_raw = nullptr;
436 } 415 }
437 416
438 template<typename VisitorDispatcher> 417 template<typename VisitorDispatcher>
439 void trace(VisitorDispatcher visitor) 418 void trace(VisitorDispatcher visitor)
440 { 419 {
441 static_assert(sizeof(T), "T must be fully defined"); 420 static_assert(sizeof(T), "T must be fully defined");
442 static_assert(IsGarbageCollectedType<T>::value, "T needs to be a garbage collected object"); 421 static_assert(IsGarbageCollectedType<T>::value, "T needs to be a garbage collected object");
443 #if ENABLE(GC_PROFILING) 422 #if ENABLE(GC_PROFILING)
444 visitor->setHostInfo(this, m_tracingName.isEmpty() ? "CrossThreadPersist ent" : m_tracingName); 423 visitor->setHostInfo(this, m_tracingName.isEmpty() ? "CrossThreadPersist ent" : m_tracingName);
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
508 { 487 {
509 m_raw = other; 488 m_raw = other;
510 checkPointer(); 489 checkPointer();
511 recordBacktrace(); 490 recordBacktrace();
512 return *this; 491 return *this;
513 } 492 }
514 493
515 T* get() const { return m_raw; } 494 T* get() const { return m_raw; }
516 495
517 private: 496 private:
497 void initialize()
498 {
499 MutexLocker m_locker(ThreadState::globalRootsMutex());
500 m_prev = &ThreadState::globalRoots();
501 m_next = m_prev->m_next;
502 m_prev->m_next = this;
503 m_next->m_prev = this;
504 }
505
506 void uninitialize()
507 {
508 MutexLocker m_locker(ThreadState::globalRootsMutex());
509 ASSERT(isHeapObjectAlive());
510 ASSERT(m_next->isHeapObjectAlive());
511 ASSERT(m_prev->isHeapObjectAlive());
512 m_next->m_prev = m_prev;
513 m_prev->m_next = m_next;
514 }
515
518 void checkPointer() 516 void checkPointer()
519 { 517 {
520 #if ENABLE(ASSERT) 518 #if ENABLE(ASSERT)
521 if (!m_raw) 519 if (!m_raw)
522 return; 520 return;
523 // Heap::isHeapObjectAlive(m_raw) checks that m_raw is a traceable 521 // Heap::isHeapObjectAlive(m_raw) checks that m_raw is a traceable
524 // object. In other words, it checks that the pointer is either of: 522 // object. In other words, it checks that the pointer is either of:
525 // 523 //
526 // (a) a pointer to the head of an on-heap object. 524 // (a) a pointer to the head of an on-heap object.
527 // (b) a pointer to the head of an on-heap mixin object. 525 // (b) a pointer to the head of an on-heap mixin object.
(...skipping 12 matching lines...) Expand all
540 } 538 }
541 539
542 String m_tracingName; 540 String m_tracingName;
543 #else 541 #else
544 inline void recordBacktrace() const { } 542 inline void recordBacktrace() const { }
545 #endif 543 #endif
546 T* m_raw; 544 T* m_raw;
547 }; 545 };
548 546
549 // FIXME: derive affinity based on the collection. 547 // FIXME: derive affinity based on the collection.
550 template<typename Collection, ThreadAffinity Affinity = AnyThread> 548 template<typename Collection>
551 class PersistentHeapCollectionBase 549 class PersistentHeapCollectionBase : public Collection, public PersistentNode {
552 : public Collection
553 , public PersistentBase<ThreadLocalPersistents<Affinity>, PersistentHeapColl ectionBase<Collection, Affinity>> {
554 // We overload the various new and delete operators with using the WTF Defau ltAllocator to ensure persistent 550 // We overload the various new and delete operators with using the WTF Defau ltAllocator to ensure persistent
555 // heap collections are always allocated off-heap. This allows persistent co llections to be used in 551 // heap collections are always allocated off-heap. This allows persistent co llections to be used in
556 // DEFINE_STATIC_LOCAL et. al. 552 // DEFINE_STATIC_LOCAL et. al.
557 WTF_USE_ALLOCATOR(PersistentHeapCollectionBase, WTF::DefaultAllocator); 553 WTF_USE_ALLOCATOR(PersistentHeapCollectionBase, WTF::DefaultAllocator);
558 public: 554 public:
559 PersistentHeapCollectionBase() { } 555 PersistentHeapCollectionBase() : PersistentNode(TraceMethodDelegate<Persiste ntHeapCollectionBase<Collection>, &PersistentHeapCollectionBase<Collection>::tra ce>::trampoline)
556 {
557 initialize();
558 }
560 559
561 PersistentHeapCollectionBase(const PersistentHeapCollectionBase& other) : Co llection(other) { } 560 PersistentHeapCollectionBase(const PersistentHeapCollectionBase& other) : Co llection(other), PersistentNode(TraceMethodDelegate<PersistentHeapCollectionBase <Collection>, &PersistentHeapCollectionBase<Collection>::trace>::trampoline)
561 {
562 initialize();
563 }
562 564
563 template<typename OtherCollection> 565 template<typename OtherCollection>
564 PersistentHeapCollectionBase(const OtherCollection& other) : Collection(othe r) { } 566 PersistentHeapCollectionBase(const OtherCollection& other) : Collection(othe r), PersistentNode(TraceMethodDelegate<PersistentHeapCollectionBase<Collection>, &PersistentHeapCollectionBase<Collection>::trace>::trampoline)
567 {
568 initialize();
569 }
570
571 ~PersistentHeapCollectionBase()
572 {
573 uninitialize();
574 }
565 575
566 template<typename VisitorDispatcher> 576 template<typename VisitorDispatcher>
567 void trace(VisitorDispatcher visitor) 577 void trace(VisitorDispatcher visitor)
568 { 578 {
569 static_assert(sizeof(Collection), "Collection must be fully defined"); 579 static_assert(sizeof(Collection), "Collection must be fully defined");
570 #if ENABLE(GC_PROFILING) 580 #if ENABLE(GC_PROFILING)
571 visitor->setHostInfo(this, "PersistentHeapCollectionBase"); 581 visitor->setHostInfo(this, "PersistentHeapCollectionBase");
572 #endif 582 #endif
573 visitor->trace(*static_cast<Collection*>(this)); 583 visitor->trace(*static_cast<Collection*>(this));
574 } 584 }
585
586 private:
587 void initialize()
588 {
589 ThreadState* state = ThreadState::current();
590 m_prev = state->roots();
591 m_next = m_prev->m_next;
592 m_prev->m_next = this;
593 m_next->m_prev = this;
594 }
595
596 void uninitialize()
597 {
598 ASSERT(isHeapObjectAlive());
599 ASSERT(m_next->isHeapObjectAlive());
600 ASSERT(m_prev->isHeapObjectAlive());
601 m_next->m_prev = m_prev;
602 m_prev->m_next = m_next;
603 }
575 }; 604 };
576 605
577 template< 606 template<
578 typename KeyArg, 607 typename KeyArg,
579 typename MappedArg, 608 typename MappedArg,
580 typename HashArg = typename DefaultHash<KeyArg>::Hash, 609 typename HashArg = typename DefaultHash<KeyArg>::Hash,
581 typename KeyTraitsArg = HashTraits<KeyArg>, 610 typename KeyTraitsArg = HashTraits<KeyArg>,
582 typename MappedTraitsArg = HashTraits<MappedArg>> 611 typename MappedTraitsArg = HashTraits<MappedArg>>
583 class PersistentHeapHashMap : public PersistentHeapCollectionBase<HeapHashMap<Ke yArg, MappedArg, HashArg, KeyTraitsArg, MappedTraitsArg>> { }; 612 class PersistentHeapHashMap : public PersistentHeapCollectionBase<HeapHashMap<Ke yArg, MappedArg, HashArg, KeyTraitsArg, MappedTraitsArg>> { };
584 613
(...skipping 674 matching lines...) Expand 10 before | Expand all | Expand 10 after
1259 struct ParamStorageTraits<RawPtr<T>> : public PointerParamStorageTraits<T*, blin k::IsGarbageCollectedType<T>::value> { 1288 struct ParamStorageTraits<RawPtr<T>> : public PointerParamStorageTraits<T*, blin k::IsGarbageCollectedType<T>::value> {
1260 static_assert(sizeof(T), "T must be fully defined"); 1289 static_assert(sizeof(T), "T must be fully defined");
1261 }; 1290 };
1262 1291
1263 template<typename T> 1292 template<typename T>
1264 PassRefPtr<T> adoptRef(blink::RefCountedGarbageCollected<T>*) = delete; 1293 PassRefPtr<T> adoptRef(blink::RefCountedGarbageCollected<T>*) = delete;
1265 1294
1266 } // namespace WTF 1295 } // namespace WTF
1267 1296
1268 #endif 1297 #endif
OLDNEW
« no previous file with comments | « no previous file | Source/platform/heap/ThreadState.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698