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

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

Issue 1157203004: Revert 196501 "Oilpan: Make PersistentNode hold a raw pointer" (Closed) Base URL: svn://svn.chromium.org/blink/
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 | no next file » | 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 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
43 #include "wtf/RawPtr.h" 43 #include "wtf/RawPtr.h"
44 #include "wtf/RefCounted.h" 44 #include "wtf/RefCounted.h"
45 #include "wtf/TypeTraits.h" 45 #include "wtf/TypeTraits.h"
46 46
47 namespace blink { 47 namespace blink {
48 48
49 template<typename T> class HeapTerminatedArray; 49 template<typename T> class HeapTerminatedArray;
50 50
51 class PersistentNode { 51 class PersistentNode {
52 public: 52 public:
53 PersistentNode(void* raw, TraceCallback trace) 53 explicit PersistentNode(TraceCallback trace)
54 : m_raw(raw) 54 : m_trace(trace)
55 , m_trace(trace)
56 { 55 {
57 } 56 }
58 57
59 NO_LAZY_SWEEP_SANITIZE_ADDRESS 58 NO_LAZY_SWEEP_SANITIZE_ADDRESS
60 bool isHeapObjectAlive() { return m_trace; } 59 bool isHeapObjectAlive() { return m_trace; }
61 60
62 virtual ~PersistentNode() 61 virtual ~PersistentNode()
63 { 62 {
64 ASSERT(isHeapObjectAlive()); 63 ASSERT(isHeapObjectAlive());
65 m_trace = nullptr; 64 m_trace = nullptr;
66 } 65 }
67 66
68 // Ideally the trace method should be virtual and automatically dispatch 67 // Ideally the trace method should be virtual and automatically dispatch
69 // to the most specific implementation. However having a virtual method 68 // to the most specific implementation. However having a virtual method
70 // on PersistentNode leads to too eager template instantiation with MSVC 69 // on PersistentNode leads to too eager template instantiation with MSVC
71 // which leads to include cycles. 70 // which leads to include cycles.
72 // Instead we call the constructor with a TraceCallback which knows the 71 // Instead we call the constructor with a TraceCallback which knows the
73 // type of the most specific child and calls trace directly. See 72 // type of the most specific child and calls trace directly. See
74 // TraceMethodDelegate in Visitor.h for how this is done. 73 // TraceMethodDelegate in Visitor.h for how this is done.
75 void trace(Visitor* visitor) 74 void trace(Visitor* visitor)
76 { 75 {
77 m_trace(visitor, this); 76 m_trace(visitor, this);
78 } 77 }
79 78
80 protected: 79 protected:
81 void* m_raw;
82 TraceCallback m_trace; 80 TraceCallback m_trace;
83 81
84 private: 82 private:
85 PersistentNode* m_next; 83 PersistentNode* m_next;
86 PersistentNode* m_prev; 84 PersistentNode* m_prev;
87 85
88 template<typename RootsAccessor, typename Owner> friend class PersistentBase ; 86 template<typename RootsAccessor, typename Owner> friend class PersistentBase ;
89 friend class PersistentAnchor; 87 friend class PersistentAnchor;
90 friend class ThreadState; 88 friend class ThreadState;
91 }; 89 };
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
135 typename RootsAccessor::Lock lock; 133 typename RootsAccessor::Lock lock;
136 ASSERT(m_roots == RootsAccessor::roots()); // Check that the thread is u sing the same roots list. 134 ASSERT(m_roots == RootsAccessor::roots()); // Check that the thread is u sing the same roots list.
137 ASSERT(isHeapObjectAlive()); 135 ASSERT(isHeapObjectAlive());
138 ASSERT(m_next->isHeapObjectAlive()); 136 ASSERT(m_next->isHeapObjectAlive());
139 ASSERT(m_prev->isHeapObjectAlive()); 137 ASSERT(m_prev->isHeapObjectAlive());
140 m_next->m_prev = m_prev; 138 m_next->m_prev = m_prev;
141 m_prev->m_next = m_next; 139 m_prev->m_next = m_next;
142 } 140 }
143 141
144 protected: 142 protected:
145 inline PersistentBase(void* raw) 143 inline PersistentBase()
146 : PersistentNode(raw, TraceMethodDelegate<Owner, &Owner::trace>::trampol ine) 144 : PersistentNode(TraceMethodDelegate<Owner, &Owner::trace>::trampoline)
147 #if ENABLE(ASSERT) 145 #if ENABLE(ASSERT)
148 , m_roots(RootsAccessor::roots()) 146 , m_roots(RootsAccessor::roots())
149 #endif 147 #endif
150 { 148 {
151 // Persistent must belong to a thread that will GC it. 149 // Persistent must belong to a thread that will GC it.
152 ASSERT(m_roots == GlobalPersistents::roots() || ThreadState::current()); 150 ASSERT(m_roots == GlobalPersistents::roots() || ThreadState::current());
153 typename RootsAccessor::Lock lock; 151 typename RootsAccessor::Lock lock;
154 m_prev = RootsAccessor::roots(); 152 m_prev = RootsAccessor::roots();
155 m_next = m_prev->m_next; 153 m_next = m_prev->m_next;
156 m_prev->m_next = this; 154 m_prev->m_next = this;
(...skipping 28 matching lines...) Expand all
185 183
186 virtual ~PersistentAnchor() 184 virtual ~PersistentAnchor()
187 { 185 {
188 // FIXME: oilpan: Ideally we should have no left-over persistents at thi s point. However currently there is a 186 // FIXME: oilpan: Ideally we should have no left-over persistents at thi s point. However currently there is a
189 // large number of objects leaked when we tear down the main thread. Sin ce some of these might contain a 187 // large number of objects leaked when we tear down the main thread. Sin ce some of these might contain a
190 // persistent or e.g. be RefCountedGarbageCollected we cannot guarantee there are no remaining Persistents at 188 // persistent or e.g. be RefCountedGarbageCollected we cannot guarantee there are no remaining Persistents at
191 // this point. 189 // this point.
192 } 190 }
193 191
194 private: 192 private:
195 PersistentAnchor() : PersistentNode(nullptr, TraceMethodDelegate<PersistentA nchor, &PersistentAnchor::trace>::trampoline) 193 PersistentAnchor() : PersistentNode(TraceMethodDelegate<PersistentAnchor, &P ersistentAnchor::trace>::trampoline)
196 { 194 {
197 m_next = this; 195 m_next = this;
198 m_prev = this; 196 m_prev = this;
199 } 197 }
200 198
201 friend class ThreadState; 199 friend class ThreadState;
202 }; 200 };
203 201
204 template<typename T> 202 template<typename T>
205 class CrossThreadPersistent; 203 class CrossThreadPersistent;
206 204
207 // Persistent handles are used to store pointers into the 205 // Persistent handles are used to store pointers into the
208 // managed heap. As long as the Persistent handle is alive 206 // managed heap. As long as the Persistent handle is alive
209 // the GC will keep the object pointed to alive. Persistent 207 // the GC will keep the object pointed to alive. Persistent
210 // handles can be stored in objects and they are not scoped. 208 // handles can be stored in objects and they are not scoped.
211 // Persistent handles must not be used to contain pointers 209 // Persistent handles must not be used to contain pointers
212 // between objects that are in the managed heap. They are only 210 // between objects that are in the managed heap. They are only
213 // meant to point to managed heap objects from variables/members 211 // meant to point to managed heap objects from variables/members
214 // outside the managed heap. 212 // outside the managed heap.
215 // 213 //
216 // A Persistent is always a GC root from the point of view of 214 // A Persistent is always a GC root from the point of view of
217 // the garbage collector. 215 // the garbage collector.
218 // 216 //
219 // We have to construct and destruct Persistent in the same thread. 217 // We have to construct and destruct Persistent in the same thread.
220 template<typename T> 218 template<typename T>
221 class Persistent : public PersistentBase<ThreadLocalPersistents<ThreadingTrait<T >::Affinity>, Persistent<T>> { 219 class Persistent : public PersistentBase<ThreadLocalPersistents<ThreadingTrait<T >::Affinity>, Persistent<T>> {
222 public: 220 public:
223 typedef PersistentBase<ThreadLocalPersistents<ThreadingTrait<T>::Affinity>, Persistent<T>> ThreadLocalPersistentBase; 221 Persistent() : m_raw(nullptr) { }
224 222
225 Persistent() : ThreadLocalPersistentBase(nullptr) { } 223 Persistent(std::nullptr_t) : m_raw(nullptr) { }
226 224
227 Persistent(std::nullptr_t) : ThreadLocalPersistentBase(nullptr) { } 225 Persistent(T* raw) : m_raw(raw)
228
229 Persistent(T* raw) : ThreadLocalPersistentBase(raw)
230 { 226 {
231 checkPointer(); 227 checkPointer();
232 recordBacktrace(); 228 recordBacktrace();
233 } 229 }
234 230
235 Persistent(T& raw) : ThreadLocalPersistentBase(&raw) 231 explicit Persistent(T& raw) : m_raw(&raw)
236 { 232 {
237 checkPointer(); 233 checkPointer();
238 recordBacktrace(); 234 recordBacktrace();
239 } 235 }
240 236
241 Persistent(const Persistent& other) : ThreadLocalPersistentBase(static_cast< T*>(other.get())) 237 Persistent(const Persistent& other) : m_raw(other)
242 { 238 {
243 checkPointer(); 239 checkPointer();
244 recordBacktrace(); 240 recordBacktrace();
245 } 241 }
246 242
247 template<typename U> 243 template<typename U>
248 Persistent(const Persistent<U>& other) : ThreadLocalPersistentBase(static_ca st<T*>(other.get())) 244 Persistent(const Persistent<U>& other) : m_raw(other)
249 { 245 {
250 checkPointer(); 246 checkPointer();
251 recordBacktrace(); 247 recordBacktrace();
252 } 248 }
253 249
254 template<typename U> 250 template<typename U>
255 Persistent(const Member<U>& other) : ThreadLocalPersistentBase(static_cast<T *>(other.get())) 251 Persistent(const Member<U>& other) : m_raw(other)
256 { 252 {
257 checkPointer(); 253 checkPointer();
258 recordBacktrace(); 254 recordBacktrace();
259 } 255 }
260 256
261 template<typename U> 257 template<typename U>
262 Persistent(const RawPtr<U>& other) : ThreadLocalPersistentBase(static_cast<T *>(other.get())) 258 Persistent(const RawPtr<U>& other) : m_raw(other.get())
263 { 259 {
264 checkPointer(); 260 checkPointer();
265 recordBacktrace(); 261 recordBacktrace();
266 } 262 }
267 263
268 void clear() 264 void clear() { m_raw = nullptr; }
269 {
270 this->m_raw = nullptr;
271 }
272 265
273 virtual ~Persistent() 266 virtual ~Persistent()
274 { 267 {
275 this->m_raw = nullptr; 268 m_raw = nullptr;
276 } 269 }
277 270
278 template<typename VisitorDispatcher> 271 template<typename VisitorDispatcher>
279 void trace(VisitorDispatcher visitor) 272 void trace(VisitorDispatcher visitor)
280 { 273 {
281 static_assert(sizeof(T), "T must be fully defined"); 274 static_assert(sizeof(T), "T must be fully defined");
282 static_assert(IsGarbageCollectedType<T>::value, "T needs to be a garbage collected object"); 275 static_assert(IsGarbageCollectedType<T>::value, "T needs to be a garbage collected object");
283 #if ENABLE(GC_PROFILING) 276 #if ENABLE(GC_PROFILING)
284 visitor->setHostInfo(this, m_tracingName.isEmpty() ? "Persistent" : m_tr acingName); 277 visitor->setHostInfo(this, m_tracingName.isEmpty() ? "Persistent" : m_tr acingName);
285 #endif 278 #endif
286 visitor->mark(get()); 279 visitor->mark(m_raw);
287 } 280 }
288 281
289 RawPtr<T> release() 282 RawPtr<T> release()
290 { 283 {
291 RawPtr<T> result = get(); 284 RawPtr<T> result = m_raw;
292 this->m_raw = nullptr; 285 m_raw = nullptr;
293 return result; 286 return result;
294 } 287 }
295 288
296 T& operator*() const { return *get(); } 289 T& operator*() const { return *m_raw; }
297 290
298 bool operator!() const { return !get(); } 291 bool operator!() const { return !m_raw; }
299 292
300 operator T*() const { return get(); } 293 operator T*() const { return m_raw; }
301 operator RawPtr<T>() const { return get(); } 294 operator RawPtr<T>() const { return m_raw; }
302 295
303 T* operator->() const { return *this; } 296 T* operator->() const { return *this; }
304 297
305 template<typename U> 298 template<typename U>
306 Persistent& operator=(U* other) 299 Persistent& operator=(U* other)
307 { 300 {
308 this->m_raw = static_cast<T*>(other); 301 m_raw = other;
309 checkPointer(); 302 checkPointer();
310 recordBacktrace(); 303 recordBacktrace();
311 return *this; 304 return *this;
312 } 305 }
313 306
314 Persistent& operator=(std::nullptr_t) 307 Persistent& operator=(std::nullptr_t)
315 { 308 {
316 this->m_raw = nullptr; 309 m_raw = nullptr;
317 return *this; 310 return *this;
318 } 311 }
319 312
320 Persistent& operator=(const Persistent& other) 313 Persistent& operator=(const Persistent& other)
321 { 314 {
322 this->m_raw = static_cast<T*>(other.get()); 315 m_raw = other;
323 checkPointer(); 316 checkPointer();
324 recordBacktrace(); 317 recordBacktrace();
325 return *this; 318 return *this;
326 } 319 }
327 320
328 template<typename U> 321 template<typename U>
329 Persistent& operator=(const Persistent<U>& other) 322 Persistent& operator=(const Persistent<U>& other)
330 { 323 {
331 this->m_raw = static_cast<T*>(other.get()); 324 m_raw = other;
332 checkPointer(); 325 checkPointer();
333 recordBacktrace(); 326 recordBacktrace();
334 return *this; 327 return *this;
335 } 328 }
336 329
337 template<typename U> 330 template<typename U>
338 Persistent& operator=(const Member<U>& other) 331 Persistent& operator=(const Member<U>& other)
339 { 332 {
340 this->m_raw = static_cast<T*>(other.get()); 333 m_raw = other;
341 checkPointer(); 334 checkPointer();
342 recordBacktrace(); 335 recordBacktrace();
343 return *this; 336 return *this;
344 } 337 }
345 338
346 template<typename U> 339 template<typename U>
347 Persistent& operator=(const RawPtr<U>& other) 340 Persistent& operator=(const RawPtr<U>& other)
348 { 341 {
349 this->m_raw = static_cast<T*>(other.get()); 342 m_raw = other;
350 checkPointer(); 343 checkPointer();
351 recordBacktrace(); 344 recordBacktrace();
352 return *this; 345 return *this;
353 } 346 }
354 347
355 T* get() const { return reinterpret_cast<T*>(this->m_raw); } 348 T* get() const { return m_raw; }
356 349
357 private: 350 private:
358 void checkPointer() 351 void checkPointer()
359 { 352 {
360 #if ENABLE(ASSERT) 353 #if ENABLE(ASSERT)
361 if (!get()) 354 if (!m_raw)
362 return; 355 return;
363 356
364 // Heap::isHeapObjectAlive() checks that the pointer is a traceable 357 // Heap::isHeapObjectAlive(m_raw) checks that m_raw is a traceable
365 // object. In other words, it checks that the pointer is either of: 358 // object. In other words, it checks that the pointer is either of:
366 // 359 //
367 // (a) a pointer to the head of an on-heap object. 360 // (a) a pointer to the head of an on-heap object.
368 // (b) a pointer to the head of an on-heap mixin object. 361 // (b) a pointer to the head of an on-heap mixin object.
369 // 362 //
370 // Otherwise, Heap::isHeapObjectAlive will crash when it calls 363 // Otherwise, Heap::isHeapObjectAlive will crash when it calls
371 // header->checkHeader(). 364 // header->checkHeader().
372 Heap::isHeapObjectAlive(get()); 365 Heap::isHeapObjectAlive(m_raw);
373 #endif 366 #endif
374 } 367 }
375 368
376 #if ENABLE(GC_PROFILING) 369 #if ENABLE(GC_PROFILING)
377 void recordBacktrace() 370 void recordBacktrace()
378 { 371 {
379 if (get()) 372 if (m_raw)
380 m_tracingName = Heap::createBacktraceString(); 373 m_tracingName = Heap::createBacktraceString();
381 } 374 }
382 375
383 String m_tracingName; 376 String m_tracingName;
384 #else 377 #else
385 inline void recordBacktrace() const { } 378 inline void recordBacktrace() const { }
386 #endif 379 #endif
380 T* m_raw;
387 }; 381 };
388 382
389 // Unlike Persistent, we can destruct a CrossThreadPersistent in a thread 383 // Unlike Persistent, we can destruct a CrossThreadPersistent in a thread
390 // different from the construction thread. 384 // different from the construction thread.
391 template<typename T> 385 template<typename T>
392 class CrossThreadPersistent : public PersistentBase<GlobalPersistents, CrossThre adPersistent<T>> { 386 class CrossThreadPersistent : public PersistentBase<GlobalPersistents, CrossThre adPersistent<T>> {
393 public: 387 public:
394 typedef PersistentBase<GlobalPersistents, CrossThreadPersistent<T>> GlobalPe rsistentBase; 388 CrossThreadPersistent() : m_raw(nullptr) { }
395 389
396 CrossThreadPersistent() : GlobalPersistentBase(nullptr) { } 390 CrossThreadPersistent(std::nullptr_t) : m_raw(nullptr) { }
397 391
398 CrossThreadPersistent(std::nullptr_t) : GlobalPersistentBase(nullptr) { } 392 CrossThreadPersistent(T* raw) : m_raw(raw)
399
400 CrossThreadPersistent(T* raw) : GlobalPersistentBase(raw)
401 { 393 {
402 checkPointer(); 394 checkPointer();
403 recordBacktrace(); 395 recordBacktrace();
404 } 396 }
405 397
406 CrossThreadPersistent(T& raw) : GlobalPersistentBase(&raw) 398 explicit CrossThreadPersistent(T& raw) : m_raw(&raw)
407 { 399 {
408 checkPointer(); 400 checkPointer();
409 recordBacktrace(); 401 recordBacktrace();
410 } 402 }
411 403
412 CrossThreadPersistent(const CrossThreadPersistent& other) : GlobalPersistent Base(static_cast<T*>(other.get())) 404 CrossThreadPersistent(const CrossThreadPersistent& other) : m_raw(other)
413 { 405 {
414 checkPointer(); 406 checkPointer();
415 recordBacktrace(); 407 recordBacktrace();
416 } 408 }
417 409
418 template<typename U> 410 template<typename U>
419 CrossThreadPersistent(const CrossThreadPersistent<U>& other) : GlobalPersist entBase(static_cast<T*>(other.get())) 411 CrossThreadPersistent(const CrossThreadPersistent<U>& other) : m_raw(other)
420 { 412 {
421 checkPointer(); 413 checkPointer();
422 recordBacktrace(); 414 recordBacktrace();
423 } 415 }
424 416
425 template<typename U> 417 template<typename U>
426 CrossThreadPersistent(const Member<U>& other) : GlobalPersistentBase(static_ cast<T*>(other.get())) 418 CrossThreadPersistent(const Member<U>& other) : m_raw(other)
427 { 419 {
428 checkPointer(); 420 checkPointer();
429 recordBacktrace(); 421 recordBacktrace();
430 } 422 }
431 423
432 template<typename U> 424 template<typename U>
433 CrossThreadPersistent(const RawPtr<U>& other) : GlobalPersistentBase(static_ cast<T*>(other.get())) 425 CrossThreadPersistent(const RawPtr<U>& other) : m_raw(other.get())
434 { 426 {
435 checkPointer(); 427 checkPointer();
436 recordBacktrace(); 428 recordBacktrace();
437 } 429 }
438 430
439 void clear() 431 void clear() { m_raw = nullptr; }
440 {
441 this->m_raw = nullptr;
442 }
443 432
444 virtual ~CrossThreadPersistent() 433 virtual ~CrossThreadPersistent()
445 { 434 {
446 this->m_raw = nullptr; 435 m_raw = nullptr;
447 } 436 }
448 437
449 template<typename VisitorDispatcher> 438 template<typename VisitorDispatcher>
450 void trace(VisitorDispatcher visitor) 439 void trace(VisitorDispatcher visitor)
451 { 440 {
452 static_assert(sizeof(T), "T must be fully defined"); 441 static_assert(sizeof(T), "T must be fully defined");
453 static_assert(IsGarbageCollectedType<T>::value, "T needs to be a garbage collected object"); 442 static_assert(IsGarbageCollectedType<T>::value, "T needs to be a garbage collected object");
454 #if ENABLE(GC_PROFILING) 443 #if ENABLE(GC_PROFILING)
455 visitor->setHostInfo(this, m_tracingName.isEmpty() ? "CrossThreadPersist ent" : m_tracingName); 444 visitor->setHostInfo(this, m_tracingName.isEmpty() ? "CrossThreadPersist ent" : m_tracingName);
456 #endif 445 #endif
457 visitor->mark(get()); 446 visitor->mark(m_raw);
458 } 447 }
459 448
460 RawPtr<T> release() 449 RawPtr<T> release()
461 { 450 {
462 RawPtr<T> result = get(); 451 RawPtr<T> result = m_raw;
463 this->m_raw = nullptr; 452 m_raw = nullptr;
464 return result; 453 return result;
465 } 454 }
466 455
467 T& operator*() const { return *get(); } 456 T& operator*() const { return *m_raw; }
468 457
469 bool operator!() const { return !get(); } 458 bool operator!() const { return !m_raw; }
470 459
471 operator T*() const { return get(); } 460 operator T*() const { return m_raw; }
472 operator RawPtr<T>() const { return get(); } 461 operator RawPtr<T>() const { return m_raw; }
473 462
474 T* operator->() const { return *this; } 463 T* operator->() const { return *this; }
475 464
476 template<typename U> 465 template<typename U>
477 CrossThreadPersistent& operator=(U* other) 466 CrossThreadPersistent& operator=(U* other)
478 { 467 {
479 this->m_raw = static_cast<T*>(other); 468 m_raw = other;
480 checkPointer(); 469 checkPointer();
481 recordBacktrace(); 470 recordBacktrace();
482 return *this; 471 return *this;
483 } 472 }
484 473
485 CrossThreadPersistent& operator=(std::nullptr_t) 474 CrossThreadPersistent& operator=(std::nullptr_t)
486 { 475 {
487 this->m_raw = nullptr; 476 m_raw = nullptr;
488 return *this; 477 return *this;
489 } 478 }
490 479
491 CrossThreadPersistent& operator=(const CrossThreadPersistent& other) 480 CrossThreadPersistent& operator=(const CrossThreadPersistent& other)
492 { 481 {
493 this->m_raw = static_cast<T*>(other.get()); 482 m_raw = other;
494 checkPointer(); 483 checkPointer();
495 recordBacktrace(); 484 recordBacktrace();
496 return *this; 485 return *this;
497 } 486 }
498 487
499 template<typename U> 488 template<typename U>
500 CrossThreadPersistent& operator=(const CrossThreadPersistent<U>& other) 489 CrossThreadPersistent& operator=(const CrossThreadPersistent<U>& other)
501 { 490 {
502 this->m_raw = static_cast<T*>(other.get()); 491 m_raw = other;
503 checkPointer(); 492 checkPointer();
504 recordBacktrace(); 493 recordBacktrace();
505 return *this; 494 return *this;
506 } 495 }
507 496
508 template<typename U> 497 template<typename U>
509 CrossThreadPersistent& operator=(const Member<U>& other) 498 CrossThreadPersistent& operator=(const Member<U>& other)
510 { 499 {
511 this->m_raw = static_cast<T*>(other.get()); 500 m_raw = other;
512 checkPointer(); 501 checkPointer();
513 recordBacktrace(); 502 recordBacktrace();
514 return *this; 503 return *this;
515 } 504 }
516 505
517 template<typename U> 506 template<typename U>
518 CrossThreadPersistent& operator=(const RawPtr<U>& other) 507 CrossThreadPersistent& operator=(const RawPtr<U>& other)
519 { 508 {
520 this->m_raw = static_cast<T*>(other.get()); 509 m_raw = other;
521 checkPointer(); 510 checkPointer();
522 recordBacktrace(); 511 recordBacktrace();
523 return *this; 512 return *this;
524 } 513 }
525 514
526 T* get() const { return reinterpret_cast<T*>(this->m_raw); } 515 T* get() const { return m_raw; }
527 516
528 private: 517 private:
529 void checkPointer() 518 void checkPointer()
530 { 519 {
531 #if ENABLE(ASSERT) 520 #if ENABLE(ASSERT)
532 if (!get()) 521 if (!m_raw)
533 return; 522 return;
534 // Heap::isHeapObjectAlive() checks that the pointer is a traceable 523 // Heap::isHeapObjectAlive(m_raw) checks that m_raw is a traceable
535 // object. In other words, it checks that the pointer is either of: 524 // object. In other words, it checks that the pointer is either of:
536 // 525 //
537 // (a) a pointer to the head of an on-heap object. 526 // (a) a pointer to the head of an on-heap object.
538 // (b) a pointer to the head of an on-heap mixin object. 527 // (b) a pointer to the head of an on-heap mixin object.
539 // 528 //
540 // Otherwise, Heap::isHeapObjectAlive will crash when it calls 529 // Otherwise, Heap::isHeapObjectAlive will crash when it calls
541 // header->checkHeader(). 530 // header->checkHeader().
542 Heap::isHeapObjectAlive(get()); 531 Heap::isHeapObjectAlive(m_raw);
543 #endif 532 #endif
544 } 533 }
545 534
546 #if ENABLE(GC_PROFILING) 535 #if ENABLE(GC_PROFILING)
547 void recordBacktrace() 536 void recordBacktrace()
548 { 537 {
549 if (get()) 538 if (m_raw)
550 m_tracingName = Heap::createBacktraceString(); 539 m_tracingName = Heap::createBacktraceString();
551 } 540 }
552 541
553 String m_tracingName; 542 String m_tracingName;
554 #else 543 #else
555 inline void recordBacktrace() const { } 544 inline void recordBacktrace() const { }
556 #endif 545 #endif
546 T* m_raw;
557 }; 547 };
558 548
559 // FIXME: derive affinity based on the collection. 549 // FIXME: derive affinity based on the collection.
560 template<typename Collection, ThreadAffinity Affinity = AnyThread> 550 template<typename Collection, ThreadAffinity Affinity = AnyThread>
561 class PersistentHeapCollectionBase 551 class PersistentHeapCollectionBase
562 : public Collection 552 : public Collection
563 , public PersistentBase<ThreadLocalPersistents<Affinity>, PersistentHeapColl ectionBase<Collection, Affinity>> { 553 , public PersistentBase<ThreadLocalPersistents<Affinity>, PersistentHeapColl ectionBase<Collection, Affinity>> {
564 // We overload the various new and delete operators with using the WTF Defau ltAllocator to ensure persistent 554 // We overload the various new and delete operators with using the WTF Defau ltAllocator to ensure persistent
565 // heap collections are always allocated off-heap. This allows persistent co llections to be used in 555 // heap collections are always allocated off-heap. This allows persistent co llections to be used in
566 // DEFINE_STATIC_LOCAL et. al. 556 // DEFINE_STATIC_LOCAL et. al.
567 WTF_USE_ALLOCATOR(PersistentHeapCollectionBase, WTF::DefaultAllocator); 557 WTF_USE_ALLOCATOR(PersistentHeapCollectionBase, WTF::DefaultAllocator);
568 public: 558 public:
569 typedef PersistentBase<ThreadLocalPersistents<Affinity>, PersistentHeapColle ctionBase<Collection, Affinity>> CollectionPersistentBase; 559 PersistentHeapCollectionBase() { }
570 560
571 PersistentHeapCollectionBase() : CollectionPersistentBase(this) { } 561 PersistentHeapCollectionBase(const PersistentHeapCollectionBase& other) : Co llection(other) { }
572
573 PersistentHeapCollectionBase(const PersistentHeapCollectionBase& other) : Co llection(other), CollectionPersistentBase(this) { }
574 562
575 template<typename OtherCollection> 563 template<typename OtherCollection>
576 PersistentHeapCollectionBase(const OtherCollection& other) : Collection(othe r), CollectionPersistentBase(this) { } 564 PersistentHeapCollectionBase(const OtherCollection& other) : Collection(othe r) { }
577 565
578 template<typename VisitorDispatcher> 566 template<typename VisitorDispatcher>
579 void trace(VisitorDispatcher visitor) 567 void trace(VisitorDispatcher visitor)
580 { 568 {
581 static_assert(sizeof(Collection), "Collection must be fully defined"); 569 static_assert(sizeof(Collection), "Collection must be fully defined");
582 #if ENABLE(GC_PROFILING) 570 #if ENABLE(GC_PROFILING)
583 visitor->setHostInfo(this, "PersistentHeapCollectionBase"); 571 visitor->setHostInfo(this, "PersistentHeapCollectionBase");
584 #endif 572 #endif
585 visitor->trace(*static_cast<Collection*>(this)); 573 visitor->trace(*static_cast<Collection*>(this));
586 } 574 }
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
653 641
654 Member(std::nullptr_t) : m_raw(nullptr) 642 Member(std::nullptr_t) : m_raw(nullptr)
655 { 643 {
656 } 644 }
657 645
658 Member(T* raw) : m_raw(raw) 646 Member(T* raw) : m_raw(raw)
659 { 647 {
660 checkPointer(); 648 checkPointer();
661 } 649 }
662 650
663 Member(T& raw) : m_raw(&raw) 651 explicit Member(T& raw) : m_raw(&raw)
664 { 652 {
665 checkPointer(); 653 checkPointer();
666 } 654 }
667 655
668 template<typename U> 656 template<typename U>
669 Member(const RawPtr<U>& other) : m_raw(other.get()) 657 Member(const RawPtr<U>& other) : m_raw(other.get())
670 { 658 {
671 checkPointer(); 659 checkPointer();
672 } 660 }
673 661
(...skipping 597 matching lines...) Expand 10 before | Expand all | Expand 10 after
1271 struct ParamStorageTraits<RawPtr<T>> : public PointerParamStorageTraits<T*, blin k::IsGarbageCollectedType<T>::value> { 1259 struct ParamStorageTraits<RawPtr<T>> : public PointerParamStorageTraits<T*, blin k::IsGarbageCollectedType<T>::value> {
1272 static_assert(sizeof(T), "T must be fully defined"); 1260 static_assert(sizeof(T), "T must be fully defined");
1273 }; 1261 };
1274 1262
1275 template<typename T> 1263 template<typename T>
1276 PassRefPtr<T> adoptRef(blink::RefCountedGarbageCollected<T>*) = delete; 1264 PassRefPtr<T> adoptRef(blink::RefCountedGarbageCollected<T>*) = delete;
1277 1265
1278 } // namespace WTF 1266 } // namespace WTF
1279 1267
1280 #endif 1268 #endif
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698