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

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