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

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

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