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

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

Issue 1213133002: Oilpan: Reduce sizeof(Persistent) to 16 byte (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 5 years, 5 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/PersistentNode.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 16 matching lines...) Expand all
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */ 29 */
30 30
31 #ifndef Handle_h 31 #ifndef Handle_h
32 #define Handle_h 32 #define Handle_h
33 33
34 #include "platform/heap/Heap.h" 34 #include "platform/heap/Heap.h"
35 #include "platform/heap/HeapAllocator.h" 35 #include "platform/heap/HeapAllocator.h"
36 #include "platform/heap/InlinedGlobalMarkingVisitor.h" 36 #include "platform/heap/InlinedGlobalMarkingVisitor.h"
37 #include "platform/heap/PersistentNode.h"
37 #include "platform/heap/ThreadState.h" 38 #include "platform/heap/ThreadState.h"
38 #include "platform/heap/TraceTraits.h" 39 #include "platform/heap/TraceTraits.h"
39 #include "platform/heap/Visitor.h" 40 #include "platform/heap/Visitor.h"
40 #include "wtf/Functional.h" 41 #include "wtf/Functional.h"
41 #include "wtf/HashFunctions.h" 42 #include "wtf/HashFunctions.h"
42 #include "wtf/Locker.h" 43 #include "wtf/Locker.h"
44 #include "wtf/MainThread.h"
43 #include "wtf/RawPtr.h" 45 #include "wtf/RawPtr.h"
44 #include "wtf/RefCounted.h" 46 #include "wtf/RefCounted.h"
45 #include "wtf/TypeTraits.h" 47 #include "wtf/TypeTraits.h"
46 48
47 namespace blink { 49 namespace blink {
48 50
49 template<typename T> class HeapTerminatedArray; 51 template<typename T> class HeapTerminatedArray;
50 52
51 class PersistentNode {
52 public:
53 explicit PersistentNode(TraceCallback trace)
54 : m_trace(trace)
55 {
56 }
57
58 NO_LAZY_SWEEP_SANITIZE_ADDRESS
59 bool isHeapObjectAlive() { return m_trace; }
60
61 // This operator= is important. Without having the operator=, m_next and
62 // m_prev are inproperly copied and it breaks the link list of the
63 // persistent handles.
64 inline PersistentNode& operator=(const PersistentNode& otherref) { return *t his; }
65
66 private:
67 // Ideally the trace method should be virtual and automatically dispatch
68 // to the most specific implementation. However having a virtual method
69 // on PersistentNode leads to too eager template instantiation with MSVC
70 // which leads to include cycles.
71 // Instead we call the constructor with a TraceCallback which knows the
72 // type of the most specific child and calls trace directly. See
73 // TraceMethodDelegate in Visitor.h for how this is done.
74 void tracePersistentNode(Visitor* visitor)
75 {
76 m_trace(visitor, this);
77 }
78
79 ~PersistentNode()
80 {
81 }
82
83 TraceCallback m_trace;
84 PersistentNode* m_next;
85 PersistentNode* m_prev;
86
87 template<typename T> friend class CrossThreadPersistent;
88 template<typename T> friend class Persistent;
89 template<typename Collection> friend class PersistentHeapCollectionBase;
90 friend class PersistentAnchor;
91 friend class ThreadState;
92 };
93
94 // A dummy Persistent handle that ensures the list of persistents is never null.
95 // This removes a test from a hot path.
96 class PersistentAnchor : public PersistentNode {
97 public:
98 void tracePersistentNodes(Visitor* visitor)
99 {
100 for (PersistentNode* current = m_next; current != this; current = curren t->m_next)
101 current->tracePersistentNode(visitor);
102 }
103
104 int numberOfPersistents()
105 {
106 int numberOfPersistents = 0;
107 for (PersistentNode* current = m_next; current != this; current = curren t->m_next)
108 ++numberOfPersistents;
109 return numberOfPersistents;
110 }
111
112 ~PersistentAnchor()
113 {
114 m_trace = nullptr;
115 }
116
117 template<typename VisitorDispatcher>
118 void trace(VisitorDispatcher visitor)
119 {
120 ASSERT_NOT_REACHED();
121 }
122
123 private:
124 PersistentAnchor() : PersistentNode(TraceMethodDelegate<PersistentAnchor, &P ersistentAnchor::trace>::trampoline)
125 {
126 m_next = this;
127 m_prev = this;
128 }
129
130 friend class ThreadState;
131 };
132
133 // Persistent handles are used to store pointers into the 53 // Persistent handles are used to store pointers into the
134 // managed heap. As long as the Persistent handle is alive 54 // managed heap. As long as the Persistent handle is alive
135 // the GC will keep the object pointed to alive. Persistent 55 // the GC will keep the object pointed to alive. Persistent
136 // handles can be stored in objects and they are not scoped. 56 // handles can be stored in objects and they are not scoped.
137 // Persistent handles must not be used to contain pointers 57 // Persistent handles must not be used to contain pointers
138 // between objects that are in the managed heap. They are only 58 // between objects that are in the managed heap. They are only
139 // meant to point to managed heap objects from variables/members 59 // meant to point to managed heap objects from variables/members
140 // outside the managed heap. 60 // outside the managed heap.
141 // 61 //
142 // A Persistent is always a GC root from the point of view of 62 // A Persistent is always a GC root from the point of view of
143 // the garbage collector. 63 // the garbage collector.
144 // 64 //
145 // We have to construct and destruct Persistent in the same thread. 65 // We have to construct and destruct Persistent in the same thread.
146 template<typename T> 66 template<typename T>
147 class Persistent : public PersistentNode { 67 class Persistent final {
148 public: 68 public:
149 Persistent() : PersistentNode(TraceMethodDelegate<Persistent<T>, &Persistent <T>::trace>::trampoline), m_raw(nullptr) 69 Persistent() : m_raw(nullptr)
150 { 70 {
151 initialize(); 71 initialize();
152 } 72 }
153 73
154 Persistent(std::nullptr_t) : PersistentNode(TraceMethodDelegate<Persistent<T >, &Persistent<T>::trace>::trampoline), m_raw(nullptr) 74 Persistent(std::nullptr_t) : m_raw(nullptr)
155 { 75 {
156 initialize(); 76 initialize();
157 } 77 }
158 78
159 Persistent(T* raw) : PersistentNode(TraceMethodDelegate<Persistent<T>, &Pers istent<T>::trace>::trampoline), m_raw(raw) 79 Persistent(T* raw) : m_raw(raw)
160 { 80 {
161 initialize(); 81 initialize();
162 checkPointer(); 82 checkPointer();
163 recordBacktrace(); 83 recordBacktrace();
164 } 84 }
165 85
166 Persistent(T& raw) : PersistentNode(TraceMethodDelegate<Persistent<T>, &Pers istent<T>::trace>::trampoline), m_raw(&raw) 86 Persistent(T& raw) : m_raw(&raw)
167 { 87 {
168 initialize(); 88 initialize();
169 checkPointer(); 89 checkPointer();
170 recordBacktrace(); 90 recordBacktrace();
171 } 91 }
172 92
173 Persistent(const Persistent& other) : PersistentNode(TraceMethodDelegate<Per sistent<T>, &Persistent<T>::trace>::trampoline), m_raw(other) 93 Persistent(const Persistent& other) : m_raw(other)
174 { 94 {
175 initialize(); 95 initialize();
176 checkPointer(); 96 checkPointer();
177 recordBacktrace(); 97 recordBacktrace();
178 } 98 }
179 99
180 template<typename U> 100 template<typename U>
181 Persistent(const Persistent<U>& other) : PersistentNode(TraceMethodDelegate< Persistent<T>, &Persistent<T>::trace>::trampoline), m_raw(other) 101 Persistent(const Persistent<U>& other) : m_raw(other)
182 { 102 {
183 initialize(); 103 initialize();
184 checkPointer(); 104 checkPointer();
185 recordBacktrace(); 105 recordBacktrace();
186 } 106 }
187 107
188 template<typename U> 108 template<typename U>
189 Persistent(const Member<U>& other) : PersistentNode(TraceMethodDelegate<Pers istent<T>, &Persistent<T>::trace>::trampoline), m_raw(other) 109 Persistent(const Member<U>& other) : m_raw(other)
190 { 110 {
191 initialize(); 111 initialize();
192 checkPointer(); 112 checkPointer();
193 recordBacktrace(); 113 recordBacktrace();
194 } 114 }
195 115
196 template<typename U> 116 template<typename U>
197 Persistent(const RawPtr<U>& other) : PersistentNode(TraceMethodDelegate<Pers istent<T>, &Persistent<T>::trace>::trampoline), m_raw(other.get()) 117 Persistent(const RawPtr<U>& other) : m_raw(other.get())
198 { 118 {
199 initialize(); 119 initialize();
200 checkPointer(); 120 checkPointer();
201 recordBacktrace(); 121 recordBacktrace();
202 } 122 }
203 123
204 void clear() { m_raw = nullptr; } 124 void clear() { m_raw = nullptr; }
205 125
206 ~Persistent() 126 ~Persistent()
207 { 127 {
208 uninitialize(); 128 uninitialize();
209 m_raw = nullptr; 129 m_raw = nullptr;
210 m_trace = nullptr;
211 } 130 }
212 131
213 template<typename VisitorDispatcher> 132 template<typename VisitorDispatcher>
214 void trace(VisitorDispatcher visitor) 133 void trace(VisitorDispatcher visitor)
215 { 134 {
216 static_assert(sizeof(T), "T must be fully defined"); 135 static_assert(sizeof(T), "T must be fully defined");
217 static_assert(IsGarbageCollectedType<T>::value, "T needs to be a garbage collected object"); 136 static_assert(IsGarbageCollectedType<T>::value, "T needs to be a garbage collected object");
218 visitor->mark(m_raw); 137 visitor->mark(m_raw);
219 } 138 }
220 139
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
284 return *this; 203 return *this;
285 } 204 }
286 205
287 T* get() const { return m_raw; } 206 T* get() const { return m_raw; }
288 207
289 private: 208 private:
290 void initialize() 209 void initialize()
291 { 210 {
292 ThreadState* state = ThreadStateFor<ThreadingTrait<T>::Affinity>::state( ); 211 ThreadState* state = ThreadStateFor<ThreadingTrait<T>::Affinity>::state( );
293 state->checkThread(); 212 state->checkThread();
294 m_prev = state->roots(); 213 m_persistentNode = state->persistentRegion()->allocatePersistentNode(thi s, TraceMethodDelegate<Persistent<T>, &Persistent<T>::trace>::trampoline);
295 m_next = m_prev->m_next;
296 m_prev->m_next = this;
297 m_next->m_prev = this;
298 } 214 }
299 215
300 NO_LAZY_SWEEP_SANITIZE_ADDRESS
301 void uninitialize() 216 void uninitialize()
302 { 217 {
303 ASSERT(isHeapObjectAlive()); 218 ThreadState* state = ThreadStateFor<ThreadingTrait<T>::Affinity>::state( );
304 ASSERT(m_next->isHeapObjectAlive()); 219 state->checkThread();
305 ASSERT(m_prev->isHeapObjectAlive()); 220 state->persistentRegion()->freePersistentNode(m_persistentNode);
sof 2015/06/30 10:08:11 Is this ASan friendly with lazy-sweeping enabled?
306 m_next->m_prev = m_prev;
307 m_prev->m_next = m_next;
308 } 221 }
309 222
310 void checkPointer() 223 void checkPointer()
311 { 224 {
312 #if ENABLE(ASSERT) 225 #if ENABLE(ASSERT)
313 if (!m_raw) 226 if (!m_raw)
314 return; 227 return;
315 228
316 // Heap::isHeapObjectAlive(m_raw) checks that m_raw is a traceable 229 // Heap::isHeapObjectAlive(m_raw) checks that m_raw is a traceable
317 // object. In other words, it checks that the pointer is either of: 230 // object. In other words, it checks that the pointer is either of:
(...skipping 11 matching lines...) Expand all
329 void recordBacktrace() 242 void recordBacktrace()
330 { 243 {
331 if (m_raw) 244 if (m_raw)
332 m_tracingName = Heap::createBacktraceString(); 245 m_tracingName = Heap::createBacktraceString();
333 } 246 }
334 247
335 String m_tracingName; 248 String m_tracingName;
336 #else 249 #else
337 inline void recordBacktrace() const { } 250 inline void recordBacktrace() const { }
338 #endif 251 #endif
252 // m_raw is accessed most, so put it at the first field.
339 T* m_raw; 253 T* m_raw;
254 PersistentNode* m_persistentNode;
340 }; 255 };
341 256
342 // Unlike Persistent, we can destruct a CrossThreadPersistent in a thread 257 // Unlike Persistent, we can destruct a CrossThreadPersistent in a thread
343 // different from the construction thread. 258 // different from the construction thread.
344 template<typename T> 259 template<typename T>
345 class CrossThreadPersistent : public PersistentNode { 260 class CrossThreadPersistent final {
346 public: 261 public:
347 CrossThreadPersistent() : PersistentNode(TraceMethodDelegate<CrossThreadPers istent<T>, &CrossThreadPersistent<T>::trace>::trampoline), m_raw(nullptr) 262 CrossThreadPersistent() : m_raw(nullptr)
348 { 263 {
349 initialize(); 264 initialize();
350 } 265 }
351 266
352 CrossThreadPersistent(std::nullptr_t) : PersistentNode(TraceMethodDelegate<C rossThreadPersistent<T>, &CrossThreadPersistent<T>::trace>::trampoline), m_raw(n ullptr) 267 CrossThreadPersistent(std::nullptr_t) : m_raw(nullptr)
353 { 268 {
354 initialize(); 269 initialize();
355 } 270 }
356 271
357 CrossThreadPersistent(T* raw) : PersistentNode(TraceMethodDelegate<CrossThre adPersistent<T>, &CrossThreadPersistent<T>::trace>::trampoline), m_raw(raw) 272 CrossThreadPersistent(T* raw) : m_raw(raw)
358 { 273 {
359 initialize(); 274 initialize();
360 checkPointer(); 275 checkPointer();
361 recordBacktrace(); 276 recordBacktrace();
362 } 277 }
363 278
364 CrossThreadPersistent(T& raw) : PersistentNode(TraceMethodDelegate<CrossThre adPersistent<T>, &CrossThreadPersistent<T>::trace>::trampoline), m_raw(&raw) 279 CrossThreadPersistent(T& raw) : m_raw(&raw)
365 { 280 {
366 initialize(); 281 initialize();
367 checkPointer(); 282 checkPointer();
368 recordBacktrace(); 283 recordBacktrace();
369 } 284 }
370 285
371 CrossThreadPersistent(const CrossThreadPersistent& other) : PersistentNode(T raceMethodDelegate<CrossThreadPersistent<T>, &CrossThreadPersistent<T>::trace>:: trampoline), m_raw(other) 286 CrossThreadPersistent(const CrossThreadPersistent& other) : m_raw(other)
372 { 287 {
373 initialize(); 288 initialize();
374 checkPointer(); 289 checkPointer();
375 recordBacktrace(); 290 recordBacktrace();
376 } 291 }
377 292
378 template<typename U> 293 template<typename U>
379 CrossThreadPersistent(const CrossThreadPersistent<U>& other) : PersistentNod e(TraceMethodDelegate<CrossThreadPersistent<T>, &CrossThreadPersistent<T>::trace >::trampoline), m_raw(other) 294 CrossThreadPersistent(const CrossThreadPersistent<U>& other) : m_raw(other)
380 { 295 {
381 initialize(); 296 initialize();
382 checkPointer(); 297 checkPointer();
383 recordBacktrace(); 298 recordBacktrace();
384 } 299 }
385 300
386 template<typename U> 301 template<typename U>
387 CrossThreadPersistent(const Member<U>& other) : PersistentNode(TraceMethodDe legate<CrossThreadPersistent<T>, &CrossThreadPersistent<T>::trace>::trampoline), m_raw(other) 302 CrossThreadPersistent(const Member<U>& other) : m_raw(other)
388 { 303 {
389 initialize(); 304 initialize();
390 checkPointer(); 305 checkPointer();
391 recordBacktrace(); 306 recordBacktrace();
392 } 307 }
393 308
394 template<typename U> 309 template<typename U>
395 CrossThreadPersistent(const RawPtr<U>& other) : PersistentNode(TraceMethodDe legate<CrossThreadPersistent<T>, &CrossThreadPersistent<T>::trace>::trampoline), m_raw(other.get()) 310 CrossThreadPersistent(const RawPtr<U>& other) : m_raw(other.get())
396 { 311 {
397 initialize(); 312 initialize();
398 checkPointer(); 313 checkPointer();
399 recordBacktrace(); 314 recordBacktrace();
400 } 315 }
401 316
402 void clear() { m_raw = nullptr; } 317 void clear() { m_raw = nullptr; }
403 318
404 ~CrossThreadPersistent() 319 ~CrossThreadPersistent()
405 { 320 {
406 uninitialize(); 321 uninitialize();
407 m_raw = nullptr; 322 m_raw = nullptr;
408 m_trace = nullptr;
409 } 323 }
410 324
411 template<typename VisitorDispatcher> 325 template<typename VisitorDispatcher>
412 void trace(VisitorDispatcher visitor) 326 void trace(VisitorDispatcher visitor)
413 { 327 {
414 static_assert(sizeof(T), "T must be fully defined"); 328 static_assert(sizeof(T), "T must be fully defined");
415 static_assert(IsGarbageCollectedType<T>::value, "T needs to be a garbage collected object"); 329 static_assert(IsGarbageCollectedType<T>::value, "T needs to be a garbage collected object");
416 visitor->mark(m_raw); 330 visitor->mark(m_raw);
417 } 331 }
418 332
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
480 checkPointer(); 394 checkPointer();
481 recordBacktrace(); 395 recordBacktrace();
482 return *this; 396 return *this;
483 } 397 }
484 398
485 T* get() const { return m_raw; } 399 T* get() const { return m_raw; }
486 400
487 private: 401 private:
488 void initialize() 402 void initialize()
489 { 403 {
490 MutexLocker m_locker(ThreadState::globalRootsMutex()); 404 m_persistentNode = ThreadState::crossThreadPersistentRegion().allocatePe rsistentNode(this, TraceMethodDelegate<CrossThreadPersistent<T>, &CrossThreadPer sistent<T>::trace>::trampoline);
491 m_prev = &ThreadState::globalRoots();
492 m_next = m_prev->m_next;
493 m_prev->m_next = this;
494 m_next->m_prev = this;
495 } 405 }
496 406
497 NO_LAZY_SWEEP_SANITIZE_ADDRESS
498 void uninitialize() 407 void uninitialize()
499 { 408 {
500 MutexLocker m_locker(ThreadState::globalRootsMutex()); 409 ThreadState::crossThreadPersistentRegion().freePersistentNode(m_persiste ntNode);
sof 2015/06/30 10:08:11 Is this ASan friendly?
501 ASSERT(isHeapObjectAlive());
502 ASSERT(m_next->isHeapObjectAlive());
503 ASSERT(m_prev->isHeapObjectAlive());
504 m_next->m_prev = m_prev;
505 m_prev->m_next = m_next;
506 } 410 }
507 411
508 void checkPointer() 412 void checkPointer()
509 { 413 {
510 #if ENABLE(ASSERT) 414 #if ENABLE(ASSERT)
511 if (!m_raw) 415 if (!m_raw)
512 return; 416 return;
513 // Heap::isHeapObjectAlive(m_raw) checks that m_raw is a traceable 417 // Heap::isHeapObjectAlive(m_raw) checks that m_raw is a traceable
514 // object. In other words, it checks that the pointer is either of: 418 // object. In other words, it checks that the pointer is either of:
515 // 419 //
(...skipping 10 matching lines...) Expand all
526 void recordBacktrace() 430 void recordBacktrace()
527 { 431 {
528 if (m_raw) 432 if (m_raw)
529 m_tracingName = Heap::createBacktraceString(); 433 m_tracingName = Heap::createBacktraceString();
530 } 434 }
531 435
532 String m_tracingName; 436 String m_tracingName;
533 #else 437 #else
534 inline void recordBacktrace() const { } 438 inline void recordBacktrace() const { }
535 #endif 439 #endif
440 // m_raw is accessed most, so put it at the first field.
536 T* m_raw; 441 T* m_raw;
442 PersistentNode* m_persistentNode;
537 }; 443 };
538 444
539 // PersistentNode must be the left-most class to let the 445 // PersistentNode must be the left-most class to let the
540 // visitor->trace(static_cast<Collection*>(this)) trace the correct position. 446 // visitor->trace(static_cast<Collection*>(this)) trace the correct position.
541 // FIXME: derive affinity based on the collection. 447 // FIXME: derive affinity based on the collection.
542 template<typename Collection> 448 template<typename Collection>
543 class PersistentHeapCollectionBase : public PersistentNode, public Collection { 449 class PersistentHeapCollectionBase : public Collection {
544 // We overload the various new and delete operators with using the WTF Defau ltAllocator to ensure persistent 450 // We overload the various new and delete operators with using the WTF Defau ltAllocator to ensure persistent
545 // heap collections are always allocated off-heap. This allows persistent co llections to be used in 451 // heap collections are always allocated off-heap. This allows persistent co llections to be used in
546 // DEFINE_STATIC_LOCAL et. al. 452 // DEFINE_STATIC_LOCAL et. al.
547 WTF_USE_ALLOCATOR(PersistentHeapCollectionBase, WTF::DefaultAllocator); 453 WTF_USE_ALLOCATOR(PersistentHeapCollectionBase, WTF::DefaultAllocator);
548 public: 454 public:
549 PersistentHeapCollectionBase() : PersistentNode(TraceMethodDelegate<Persiste ntHeapCollectionBase<Collection>, &PersistentHeapCollectionBase<Collection>::tra ce>::trampoline) 455 PersistentHeapCollectionBase()
550 { 456 {
551 initialize(); 457 initialize();
552 } 458 }
553 459
554 PersistentHeapCollectionBase(const PersistentHeapCollectionBase& other) : Pe rsistentNode(TraceMethodDelegate<PersistentHeapCollectionBase<Collection>, &Pers istentHeapCollectionBase<Collection>::trace>::trampoline), Collection(other) 460 PersistentHeapCollectionBase(const PersistentHeapCollectionBase& other) : Co llection(other)
555 { 461 {
556 initialize(); 462 initialize();
557 } 463 }
558 464
559 template<typename OtherCollection> 465 template<typename OtherCollection>
560 PersistentHeapCollectionBase(const OtherCollection& other) : PersistentNode( TraceMethodDelegate<PersistentHeapCollectionBase<Collection>, &PersistentHeapCol lectionBase<Collection>::trace>::trampoline), Collection(other) 466 PersistentHeapCollectionBase(const OtherCollection& other) : Collection(othe r)
561 { 467 {
562 initialize(); 468 initialize();
563 } 469 }
564 470
565 ~PersistentHeapCollectionBase() 471 ~PersistentHeapCollectionBase()
566 { 472 {
567 uninitialize(); 473 uninitialize();
568 m_trace = nullptr;
569 } 474 }
570 475
571 template<typename VisitorDispatcher> 476 template<typename VisitorDispatcher>
572 void trace(VisitorDispatcher visitor) 477 void trace(VisitorDispatcher visitor)
573 { 478 {
574 static_assert(sizeof(Collection), "Collection must be fully defined"); 479 static_assert(sizeof(Collection), "Collection must be fully defined");
575 visitor->trace(*static_cast<Collection*>(this)); 480 visitor->trace(*static_cast<Collection*>(this));
576 } 481 }
577 482
578 private: 483 private:
579 void initialize() 484 void initialize()
580 { 485 {
581 ThreadState* state = ThreadState::current(); 486 ThreadState* state = ThreadState::current();
582 m_prev = state->roots(); 487 state->checkThread();
583 m_next = m_prev->m_next; 488 m_persistentNode = state->persistentRegion()->allocatePersistentNode(thi s, TraceMethodDelegate<PersistentHeapCollectionBase<Collection>, &PersistentHeap CollectionBase<Collection>::trace>::trampoline);
584 m_prev->m_next = this;
585 m_next->m_prev = this;
586 } 489 }
587 490
588 NO_LAZY_SWEEP_SANITIZE_ADDRESS
589 void uninitialize() 491 void uninitialize()
590 { 492 {
591 ASSERT(isHeapObjectAlive()); 493 ThreadState* state = ThreadState::current();
592 ASSERT(m_next->isHeapObjectAlive()); 494 state->checkThread();
593 ASSERT(m_prev->isHeapObjectAlive()); 495 state->persistentRegion()->freePersistentNode(m_persistentNode);
sof 2015/06/30 10:08:11 Ditto.
594 m_next->m_prev = m_prev;
595 m_prev->m_next = m_next;
596 } 496 }
497
498 PersistentNode* m_persistentNode;
597 }; 499 };
598 500
599 template< 501 template<
600 typename KeyArg, 502 typename KeyArg,
601 typename MappedArg, 503 typename MappedArg,
602 typename HashArg = typename DefaultHash<KeyArg>::Hash, 504 typename HashArg = typename DefaultHash<KeyArg>::Hash,
603 typename KeyTraitsArg = HashTraits<KeyArg>, 505 typename KeyTraitsArg = HashTraits<KeyArg>,
604 typename MappedTraitsArg = HashTraits<MappedArg>> 506 typename MappedTraitsArg = HashTraits<MappedArg>>
605 class PersistentHeapHashMap : public PersistentHeapCollectionBase<HeapHashMap<Ke yArg, MappedArg, HashArg, KeyTraitsArg, MappedTraitsArg>> { }; 507 class PersistentHeapHashMap : public PersistentHeapCollectionBase<HeapHashMap<Ke yArg, MappedArg, HashArg, KeyTraitsArg, MappedTraitsArg>> { };
606 508
(...skipping 680 matching lines...) Expand 10 before | Expand all | Expand 10 after
1287 struct ParamStorageTraits<RawPtr<T>> : public PointerParamStorageTraits<T*, blin k::IsGarbageCollectedType<T>::value> { 1189 struct ParamStorageTraits<RawPtr<T>> : public PointerParamStorageTraits<T*, blin k::IsGarbageCollectedType<T>::value> {
1288 static_assert(sizeof(T), "T must be fully defined"); 1190 static_assert(sizeof(T), "T must be fully defined");
1289 }; 1191 };
1290 1192
1291 template<typename T> 1193 template<typename T>
1292 PassRefPtr<T> adoptRef(blink::RefCountedGarbageCollected<T>*) = delete; 1194 PassRefPtr<T> adoptRef(blink::RefCountedGarbageCollected<T>*) = delete;
1293 1195
1294 } // namespace WTF 1196 } // namespace WTF
1295 1197
1296 #endif 1198 #endif
OLDNEW
« no previous file with comments | « no previous file | Source/platform/heap/PersistentNode.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698