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

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 | « Source/platform/heap/BUILD.gn ('k') | Source/platform/heap/HeapTest.cpp » ('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 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
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 NO_LAZY_SWEEP_SANITIZE_ADDRESS 209 NO_LAZY_SWEEP_SANITIZE_ADDRESS
291 void initialize() 210 void initialize()
292 { 211 {
293 ThreadState* state = ThreadStateFor<ThreadingTrait<T>::Affinity>::state( ); 212 ThreadState* state = ThreadStateFor<ThreadingTrait<T>::Affinity>::state( );
294 state->checkThread(); 213 state->checkThread();
295 m_prev = state->roots(); 214 m_persistentNode = state->persistentRegion()->allocatePersistentNode(thi s, TraceMethodDelegate<Persistent<T>, &Persistent<T>::trace>::trampoline);
296 m_next = m_prev->m_next;
297 m_prev->m_next = this;
298 m_next->m_prev = this;
299 } 215 }
300 216
301 NO_LAZY_SWEEP_SANITIZE_ADDRESS
302 void uninitialize() 217 void uninitialize()
303 { 218 {
304 ASSERT(isHeapObjectAlive()); 219 ThreadState* state = ThreadStateFor<ThreadingTrait<T>::Affinity>::state( );
305 ASSERT(m_next->isHeapObjectAlive()); 220 state->checkThread();
306 ASSERT(m_prev->isHeapObjectAlive()); 221 state->persistentRegion()->freePersistentNode(m_persistentNode);
307 m_next->m_prev = m_prev;
308 m_prev->m_next = m_next;
309 } 222 }
310 223
311 void checkPointer() 224 void checkPointer()
312 { 225 {
313 #if ENABLE(ASSERT) 226 #if ENABLE(ASSERT)
314 if (!m_raw) 227 if (!m_raw)
315 return; 228 return;
316 229
317 // Heap::isHeapObjectAlive(m_raw) checks that m_raw is a traceable 230 // Heap::isHeapObjectAlive(m_raw) checks that m_raw is a traceable
318 // object. In other words, it checks that the pointer is either of: 231 // object. In other words, it checks that the pointer is either of:
(...skipping 11 matching lines...) Expand all
330 void recordBacktrace() 243 void recordBacktrace()
331 { 244 {
332 if (m_raw) 245 if (m_raw)
333 m_tracingName = Heap::createBacktraceString(); 246 m_tracingName = Heap::createBacktraceString();
334 } 247 }
335 248
336 String m_tracingName; 249 String m_tracingName;
337 #else 250 #else
338 inline void recordBacktrace() const { } 251 inline void recordBacktrace() const { }
339 #endif 252 #endif
253 // m_raw is accessed most, so put it at the first field.
340 T* m_raw; 254 T* m_raw;
255 PersistentNode* m_persistentNode;
341 }; 256 };
342 257
343 // Unlike Persistent, we can destruct a CrossThreadPersistent in a thread 258 // Unlike Persistent, we can destruct a CrossThreadPersistent in a thread
344 // different from the construction thread. 259 // different from the construction thread.
345 template<typename T> 260 template<typename T>
346 class CrossThreadPersistent : public PersistentNode { 261 class CrossThreadPersistent final {
347 public: 262 public:
348 CrossThreadPersistent() : PersistentNode(TraceMethodDelegate<CrossThreadPers istent<T>, &CrossThreadPersistent<T>::trace>::trampoline), m_raw(nullptr) 263 CrossThreadPersistent() : m_raw(nullptr)
349 { 264 {
350 initialize(); 265 initialize();
351 } 266 }
352 267
353 CrossThreadPersistent(std::nullptr_t) : PersistentNode(TraceMethodDelegate<C rossThreadPersistent<T>, &CrossThreadPersistent<T>::trace>::trampoline), m_raw(n ullptr) 268 CrossThreadPersistent(std::nullptr_t) : m_raw(nullptr)
354 { 269 {
355 initialize(); 270 initialize();
356 } 271 }
357 272
358 CrossThreadPersistent(T* raw) : PersistentNode(TraceMethodDelegate<CrossThre adPersistent<T>, &CrossThreadPersistent<T>::trace>::trampoline), m_raw(raw) 273 CrossThreadPersistent(T* raw) : m_raw(raw)
359 { 274 {
360 initialize(); 275 initialize();
361 checkPointer(); 276 checkPointer();
362 recordBacktrace(); 277 recordBacktrace();
363 } 278 }
364 279
365 CrossThreadPersistent(T& raw) : PersistentNode(TraceMethodDelegate<CrossThre adPersistent<T>, &CrossThreadPersistent<T>::trace>::trampoline), m_raw(&raw) 280 CrossThreadPersistent(T& raw) : m_raw(&raw)
366 { 281 {
367 initialize(); 282 initialize();
368 checkPointer(); 283 checkPointer();
369 recordBacktrace(); 284 recordBacktrace();
370 } 285 }
371 286
372 CrossThreadPersistent(const CrossThreadPersistent& other) : PersistentNode(T raceMethodDelegate<CrossThreadPersistent<T>, &CrossThreadPersistent<T>::trace>:: trampoline), m_raw(other) 287 CrossThreadPersistent(const CrossThreadPersistent& other) : m_raw(other)
373 { 288 {
374 initialize(); 289 initialize();
375 checkPointer(); 290 checkPointer();
376 recordBacktrace(); 291 recordBacktrace();
377 } 292 }
378 293
379 template<typename U> 294 template<typename U>
380 CrossThreadPersistent(const CrossThreadPersistent<U>& other) : PersistentNod e(TraceMethodDelegate<CrossThreadPersistent<T>, &CrossThreadPersistent<T>::trace >::trampoline), m_raw(other) 295 CrossThreadPersistent(const CrossThreadPersistent<U>& other) : m_raw(other)
381 { 296 {
382 initialize(); 297 initialize();
383 checkPointer(); 298 checkPointer();
384 recordBacktrace(); 299 recordBacktrace();
385 } 300 }
386 301
387 template<typename U> 302 template<typename U>
388 CrossThreadPersistent(const Member<U>& other) : PersistentNode(TraceMethodDe legate<CrossThreadPersistent<T>, &CrossThreadPersistent<T>::trace>::trampoline), m_raw(other) 303 CrossThreadPersistent(const Member<U>& other) : m_raw(other)
389 { 304 {
390 initialize(); 305 initialize();
391 checkPointer(); 306 checkPointer();
392 recordBacktrace(); 307 recordBacktrace();
393 } 308 }
394 309
395 template<typename U> 310 template<typename U>
396 CrossThreadPersistent(const RawPtr<U>& other) : PersistentNode(TraceMethodDe legate<CrossThreadPersistent<T>, &CrossThreadPersistent<T>::trace>::trampoline), m_raw(other.get()) 311 CrossThreadPersistent(const RawPtr<U>& other) : m_raw(other.get())
397 { 312 {
398 initialize(); 313 initialize();
399 checkPointer(); 314 checkPointer();
400 recordBacktrace(); 315 recordBacktrace();
401 } 316 }
402 317
403 void clear() { m_raw = nullptr; } 318 void clear() { m_raw = nullptr; }
404 319
405 ~CrossThreadPersistent() 320 ~CrossThreadPersistent()
406 { 321 {
407 uninitialize(); 322 uninitialize();
408 m_raw = nullptr; 323 m_raw = nullptr;
409 m_trace = nullptr;
410 } 324 }
411 325
412 template<typename VisitorDispatcher> 326 template<typename VisitorDispatcher>
413 void trace(VisitorDispatcher visitor) 327 void trace(VisitorDispatcher visitor)
414 { 328 {
415 static_assert(sizeof(T), "T must be fully defined"); 329 static_assert(sizeof(T), "T must be fully defined");
416 static_assert(IsGarbageCollectedType<T>::value, "T needs to be a garbage collected object"); 330 static_assert(IsGarbageCollectedType<T>::value, "T needs to be a garbage collected object");
417 visitor->mark(m_raw); 331 visitor->mark(m_raw);
418 } 332 }
419 333
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
482 recordBacktrace(); 396 recordBacktrace();
483 return *this; 397 return *this;
484 } 398 }
485 399
486 T* get() const { return m_raw; } 400 T* get() const { return m_raw; }
487 401
488 private: 402 private:
489 NO_LAZY_SWEEP_SANITIZE_ADDRESS 403 NO_LAZY_SWEEP_SANITIZE_ADDRESS
490 void initialize() 404 void initialize()
491 { 405 {
492 MutexLocker m_locker(ThreadState::globalRootsMutex()); 406 m_persistentNode = ThreadState::crossThreadPersistentRegion().allocatePe rsistentNode(this, TraceMethodDelegate<CrossThreadPersistent<T>, &CrossThreadPer sistent<T>::trace>::trampoline);
493 m_prev = &ThreadState::globalRoots();
494 m_next = m_prev->m_next;
495 m_prev->m_next = this;
496 m_next->m_prev = this;
497 } 407 }
498 408
499 NO_LAZY_SWEEP_SANITIZE_ADDRESS
500 void uninitialize() 409 void uninitialize()
501 { 410 {
502 MutexLocker m_locker(ThreadState::globalRootsMutex()); 411 ThreadState::crossThreadPersistentRegion().freePersistentNode(m_persiste ntNode);
503 ASSERT(isHeapObjectAlive());
504 ASSERT(m_next->isHeapObjectAlive());
505 ASSERT(m_prev->isHeapObjectAlive());
506 m_next->m_prev = m_prev;
507 m_prev->m_next = m_next;
508 } 412 }
509 413
510 void checkPointer() 414 void checkPointer()
511 { 415 {
512 #if ENABLE(ASSERT) 416 #if ENABLE(ASSERT)
513 if (!m_raw) 417 if (!m_raw)
514 return; 418 return;
515 // Heap::isHeapObjectAlive(m_raw) checks that m_raw is a traceable 419 // Heap::isHeapObjectAlive(m_raw) checks that m_raw is a traceable
516 // object. In other words, it checks that the pointer is either of: 420 // object. In other words, it checks that the pointer is either of:
517 // 421 //
(...skipping 10 matching lines...) Expand all
528 void recordBacktrace() 432 void recordBacktrace()
529 { 433 {
530 if (m_raw) 434 if (m_raw)
531 m_tracingName = Heap::createBacktraceString(); 435 m_tracingName = Heap::createBacktraceString();
532 } 436 }
533 437
534 String m_tracingName; 438 String m_tracingName;
535 #else 439 #else
536 inline void recordBacktrace() const { } 440 inline void recordBacktrace() const { }
537 #endif 441 #endif
442 // m_raw is accessed most, so put it at the first field.
538 T* m_raw; 443 T* m_raw;
444 PersistentNode* m_persistentNode;
539 }; 445 };
540 446
541 // PersistentNode must be the left-most class to let the 447 // PersistentNode must be the left-most class to let the
542 // visitor->trace(static_cast<Collection*>(this)) trace the correct position. 448 // visitor->trace(static_cast<Collection*>(this)) trace the correct position.
543 // FIXME: derive affinity based on the collection. 449 // FIXME: derive affinity based on the collection.
544 template<typename Collection> 450 template<typename Collection>
545 class PersistentHeapCollectionBase : public PersistentNode, public Collection { 451 class PersistentHeapCollectionBase : public Collection {
546 // We overload the various new and delete operators with using the WTF Defau ltAllocator to ensure persistent 452 // We overload the various new and delete operators with using the WTF Defau ltAllocator to ensure persistent
547 // heap collections are always allocated off-heap. This allows persistent co llections to be used in 453 // heap collections are always allocated off-heap. This allows persistent co llections to be used in
548 // DEFINE_STATIC_LOCAL et. al. 454 // DEFINE_STATIC_LOCAL et. al.
549 WTF_USE_ALLOCATOR(PersistentHeapCollectionBase, WTF::DefaultAllocator); 455 WTF_USE_ALLOCATOR(PersistentHeapCollectionBase, WTF::DefaultAllocator);
550 public: 456 public:
551 PersistentHeapCollectionBase() : PersistentNode(TraceMethodDelegate<Persiste ntHeapCollectionBase<Collection>, &PersistentHeapCollectionBase<Collection>::tra ce>::trampoline) 457 PersistentHeapCollectionBase()
552 { 458 {
553 initialize(); 459 initialize();
554 } 460 }
555 461
556 PersistentHeapCollectionBase(const PersistentHeapCollectionBase& other) : Pe rsistentNode(TraceMethodDelegate<PersistentHeapCollectionBase<Collection>, &Pers istentHeapCollectionBase<Collection>::trace>::trampoline), Collection(other) 462 PersistentHeapCollectionBase(const PersistentHeapCollectionBase& other) : Co llection(other)
557 { 463 {
558 initialize(); 464 initialize();
559 } 465 }
560 466
561 template<typename OtherCollection> 467 template<typename OtherCollection>
562 PersistentHeapCollectionBase(const OtherCollection& other) : PersistentNode( TraceMethodDelegate<PersistentHeapCollectionBase<Collection>, &PersistentHeapCol lectionBase<Collection>::trace>::trampoline), Collection(other) 468 PersistentHeapCollectionBase(const OtherCollection& other) : Collection(othe r)
563 { 469 {
564 initialize(); 470 initialize();
565 } 471 }
566 472
567 ~PersistentHeapCollectionBase() 473 ~PersistentHeapCollectionBase()
568 { 474 {
569 uninitialize(); 475 uninitialize();
570 m_trace = nullptr;
571 } 476 }
572 477
573 template<typename VisitorDispatcher> 478 template<typename VisitorDispatcher>
574 void trace(VisitorDispatcher visitor) 479 void trace(VisitorDispatcher visitor)
575 { 480 {
576 static_assert(sizeof(Collection), "Collection must be fully defined"); 481 static_assert(sizeof(Collection), "Collection must be fully defined");
577 visitor->trace(*static_cast<Collection*>(this)); 482 visitor->trace(*static_cast<Collection*>(this));
578 } 483 }
579 484
580 private: 485 private:
581 NO_LAZY_SWEEP_SANITIZE_ADDRESS 486 NO_LAZY_SWEEP_SANITIZE_ADDRESS
582 void initialize() 487 void initialize()
583 { 488 {
584 ThreadState* state = ThreadState::current(); 489 ThreadState* state = ThreadState::current();
585 m_prev = state->roots(); 490 state->checkThread();
586 m_next = m_prev->m_next; 491 m_persistentNode = state->persistentRegion()->allocatePersistentNode(thi s, TraceMethodDelegate<PersistentHeapCollectionBase<Collection>, &PersistentHeap CollectionBase<Collection>::trace>::trampoline);
587 m_prev->m_next = this;
588 m_next->m_prev = this;
589 } 492 }
590 493
591 NO_LAZY_SWEEP_SANITIZE_ADDRESS
592 void uninitialize() 494 void uninitialize()
593 { 495 {
594 ASSERT(isHeapObjectAlive()); 496 ThreadState* state = ThreadState::current();
595 ASSERT(m_next->isHeapObjectAlive()); 497 state->checkThread();
596 ASSERT(m_prev->isHeapObjectAlive()); 498 state->persistentRegion()->freePersistentNode(m_persistentNode);
597 m_next->m_prev = m_prev;
598 m_prev->m_next = m_next;
599 } 499 }
500
501 PersistentNode* m_persistentNode;
600 }; 502 };
601 503
602 template< 504 template<
603 typename KeyArg, 505 typename KeyArg,
604 typename MappedArg, 506 typename MappedArg,
605 typename HashArg = typename DefaultHash<KeyArg>::Hash, 507 typename HashArg = typename DefaultHash<KeyArg>::Hash,
606 typename KeyTraitsArg = HashTraits<KeyArg>, 508 typename KeyTraitsArg = HashTraits<KeyArg>,
607 typename MappedTraitsArg = HashTraits<MappedArg>> 509 typename MappedTraitsArg = HashTraits<MappedArg>>
608 class PersistentHeapHashMap : public PersistentHeapCollectionBase<HeapHashMap<Ke yArg, MappedArg, HashArg, KeyTraitsArg, MappedTraitsArg>> { }; 510 class PersistentHeapHashMap : public PersistentHeapCollectionBase<HeapHashMap<Ke yArg, MappedArg, HashArg, KeyTraitsArg, MappedTraitsArg>> { };
609 511
(...skipping 681 matching lines...) Expand 10 before | Expand all | Expand 10 after
1291 struct ParamStorageTraits<RawPtr<T>> : public PointerParamStorageTraits<T*, blin k::IsGarbageCollectedType<T>::value> { 1193 struct ParamStorageTraits<RawPtr<T>> : public PointerParamStorageTraits<T*, blin k::IsGarbageCollectedType<T>::value> {
1292 static_assert(sizeof(T), "T must be fully defined"); 1194 static_assert(sizeof(T), "T must be fully defined");
1293 }; 1195 };
1294 1196
1295 template<typename T> 1197 template<typename T>
1296 PassRefPtr<T> adoptRef(blink::RefCountedGarbageCollected<T>*) = delete; 1198 PassRefPtr<T> adoptRef(blink::RefCountedGarbageCollected<T>*) = delete;
1297 1199
1298 } // namespace WTF 1200 } // namespace WTF
1299 1201
1300 #endif 1202 #endif
OLDNEW
« no previous file with comments | « Source/platform/heap/BUILD.gn ('k') | Source/platform/heap/HeapTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698