OLD | NEW |
---|---|
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 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
152 } | 152 } |
153 | 153 |
154 Persistent(std::nullptr_t) : PersistentNode(TraceMethodDelegate<Persistent<T >, &Persistent<T>::trace>::trampoline), m_raw(nullptr) | 154 Persistent(std::nullptr_t) : PersistentNode(TraceMethodDelegate<Persistent<T >, &Persistent<T>::trace>::trampoline), m_raw(nullptr) |
155 { | 155 { |
156 initialize(); | 156 initialize(); |
157 } | 157 } |
158 | 158 |
159 Persistent(T* raw) : PersistentNode(TraceMethodDelegate<Persistent<T>, &Pers istent<T>::trace>::trampoline), m_raw(raw) | 159 Persistent(T* raw) : PersistentNode(TraceMethodDelegate<Persistent<T>, &Pers istent<T>::trace>::trampoline), m_raw(raw) |
160 { | 160 { |
161 initialize(); | 161 initialize(); |
162 checkPointer(); | 162 ASSERT(checkPointer()); |
163 recordBacktrace(); | 163 recordBacktrace(); |
164 } | 164 } |
165 | 165 |
166 Persistent(T& raw) : PersistentNode(TraceMethodDelegate<Persistent<T>, &Pers istent<T>::trace>::trampoline), m_raw(&raw) | 166 Persistent(T& raw) : PersistentNode(TraceMethodDelegate<Persistent<T>, &Pers istent<T>::trace>::trampoline), m_raw(&raw) |
167 { | 167 { |
168 initialize(); | 168 initialize(); |
169 checkPointer(); | 169 ASSERT(checkPointer()); |
170 recordBacktrace(); | 170 recordBacktrace(); |
171 } | 171 } |
172 | 172 |
173 Persistent(const Persistent& other) : PersistentNode(TraceMethodDelegate<Per sistent<T>, &Persistent<T>::trace>::trampoline), m_raw(other) | 173 Persistent(const Persistent& other) : PersistentNode(TraceMethodDelegate<Per sistent<T>, &Persistent<T>::trace>::trampoline), m_raw(other) |
174 { | 174 { |
175 initialize(); | 175 initialize(); |
176 checkPointer(); | 176 ASSERT(checkPointer()); |
177 recordBacktrace(); | 177 recordBacktrace(); |
178 } | 178 } |
179 | 179 |
180 template<typename U> | 180 template<typename U> |
181 Persistent(const Persistent<U>& other) : PersistentNode(TraceMethodDelegate< Persistent<T>, &Persistent<T>::trace>::trampoline), m_raw(other) | 181 Persistent(const Persistent<U>& other) : PersistentNode(TraceMethodDelegate< Persistent<T>, &Persistent<T>::trace>::trampoline), m_raw(other) |
182 { | 182 { |
183 initialize(); | 183 initialize(); |
184 checkPointer(); | 184 ASSERT(checkPointer()); |
185 recordBacktrace(); | 185 recordBacktrace(); |
186 } | 186 } |
187 | 187 |
188 template<typename U> | 188 template<typename U> |
189 Persistent(const Member<U>& other) : PersistentNode(TraceMethodDelegate<Pers istent<T>, &Persistent<T>::trace>::trampoline), m_raw(other) | 189 Persistent(const Member<U>& other) : PersistentNode(TraceMethodDelegate<Pers istent<T>, &Persistent<T>::trace>::trampoline), m_raw(other) |
190 { | 190 { |
191 initialize(); | 191 initialize(); |
192 checkPointer(); | 192 ASSERT(checkPointer()); |
193 recordBacktrace(); | 193 recordBacktrace(); |
194 } | 194 } |
195 | 195 |
196 template<typename U> | 196 template<typename U> |
197 Persistent(const RawPtr<U>& other) : PersistentNode(TraceMethodDelegate<Pers istent<T>, &Persistent<T>::trace>::trampoline), m_raw(other.get()) | 197 Persistent(const RawPtr<U>& other) : PersistentNode(TraceMethodDelegate<Pers istent<T>, &Persistent<T>::trace>::trampoline), m_raw(other.get()) |
198 { | 198 { |
199 initialize(); | 199 initialize(); |
200 checkPointer(); | 200 ASSERT(checkPointer()); |
201 recordBacktrace(); | 201 recordBacktrace(); |
202 } | 202 } |
203 | 203 |
204 void clear() { m_raw = nullptr; } | 204 void clear() { m_raw = nullptr; } |
205 | 205 |
206 ~Persistent() | 206 ~Persistent() |
207 { | 207 { |
208 uninitialize(); | 208 uninitialize(); |
209 m_raw = nullptr; | 209 m_raw = nullptr; |
210 m_trace = nullptr; | 210 m_trace = nullptr; |
(...skipping 20 matching lines...) Expand all Loading... | |
231 | 231 |
232 operator T*() const { return m_raw; } | 232 operator T*() const { return m_raw; } |
233 operator RawPtr<T>() const { return m_raw; } | 233 operator RawPtr<T>() const { return m_raw; } |
234 | 234 |
235 T* operator->() const { return *this; } | 235 T* operator->() const { return *this; } |
236 | 236 |
237 template<typename U> | 237 template<typename U> |
238 Persistent& operator=(U* other) | 238 Persistent& operator=(U* other) |
239 { | 239 { |
240 m_raw = other; | 240 m_raw = other; |
241 checkPointer(); | 241 ASSERT(checkPointer()); |
242 recordBacktrace(); | 242 recordBacktrace(); |
243 return *this; | 243 return *this; |
244 } | 244 } |
245 | 245 |
246 Persistent& operator=(std::nullptr_t) | 246 Persistent& operator=(std::nullptr_t) |
247 { | 247 { |
248 m_raw = nullptr; | 248 m_raw = nullptr; |
249 return *this; | 249 return *this; |
250 } | 250 } |
251 | 251 |
252 Persistent& operator=(const Persistent& other) | 252 Persistent& operator=(const Persistent& other) |
253 { | 253 { |
254 m_raw = other; | 254 m_raw = other; |
255 checkPointer(); | 255 ASSERT(checkPointer()); |
256 recordBacktrace(); | 256 recordBacktrace(); |
257 return *this; | 257 return *this; |
258 } | 258 } |
259 | 259 |
260 template<typename U> | 260 template<typename U> |
261 Persistent& operator=(const Persistent<U>& other) | 261 Persistent& operator=(const Persistent<U>& other) |
262 { | 262 { |
263 m_raw = other; | 263 m_raw = other; |
264 checkPointer(); | 264 ASSERT(checkPointer()); |
265 recordBacktrace(); | 265 recordBacktrace(); |
266 return *this; | 266 return *this; |
267 } | 267 } |
268 | 268 |
269 template<typename U> | 269 template<typename U> |
270 Persistent& operator=(const Member<U>& other) | 270 Persistent& operator=(const Member<U>& other) |
271 { | 271 { |
272 m_raw = other; | 272 m_raw = other; |
273 checkPointer(); | 273 ASSERT(checkPointer()); |
274 recordBacktrace(); | 274 recordBacktrace(); |
275 return *this; | 275 return *this; |
276 } | 276 } |
277 | 277 |
278 template<typename U> | 278 template<typename U> |
279 Persistent& operator=(const RawPtr<U>& other) | 279 Persistent& operator=(const RawPtr<U>& other) |
280 { | 280 { |
281 m_raw = other; | 281 m_raw = other; |
282 checkPointer(); | 282 ASSERT(checkPointer()); |
283 recordBacktrace(); | 283 recordBacktrace(); |
284 return *this; | 284 return *this; |
285 } | 285 } |
286 | 286 |
287 T* get() const { return m_raw; } | 287 T* get() const { return m_raw; } |
288 | 288 |
289 private: | 289 private: |
290 void initialize() | 290 void initialize() |
291 { | 291 { |
292 ThreadState* state = ThreadStateFor<ThreadingTrait<T>::Affinity>::state( ); | 292 ThreadState* state = ThreadStateFor<ThreadingTrait<T>::Affinity>::state( ); |
293 state->checkThread(); | 293 state->checkThread(); |
294 m_prev = state->roots(); | 294 m_prev = state->roots(); |
295 m_next = m_prev->m_next; | 295 m_next = m_prev->m_next; |
296 m_prev->m_next = this; | 296 m_prev->m_next = this; |
297 m_next->m_prev = this; | 297 m_next->m_prev = this; |
298 } | 298 } |
299 | 299 |
300 NO_LAZY_SWEEP_SANITIZE_ADDRESS | 300 NO_LAZY_SWEEP_SANITIZE_ADDRESS |
301 void uninitialize() | 301 void uninitialize() |
302 { | 302 { |
303 ASSERT(isHeapObjectAlive()); | 303 ASSERT(isHeapObjectAlive()); |
304 ASSERT(m_next->isHeapObjectAlive()); | 304 ASSERT(m_next->isHeapObjectAlive()); |
305 ASSERT(m_prev->isHeapObjectAlive()); | 305 ASSERT(m_prev->isHeapObjectAlive()); |
306 m_next->m_prev = m_prev; | 306 m_next->m_prev = m_prev; |
307 m_prev->m_next = m_next; | 307 m_prev->m_next = m_next; |
308 } | 308 } |
309 | 309 |
310 void checkPointer() | 310 #if ENABLE(ASSERT) |
311 bool checkPointer() | |
311 { | 312 { |
312 #if ENABLE(ASSERT) | |
313 if (!m_raw) | 313 if (!m_raw) |
314 return; | 314 return true; |
315 | 315 |
316 // Heap::isHeapObjectAlive(m_raw) checks that m_raw is a traceable | 316 // Heap::isHeapObjectAlive(m_raw) checks that m_raw is a traceable |
317 // object. In other words, it checks that the pointer is either of: | 317 // object. In other words, it checks that the pointer is either of: |
318 // | 318 // |
319 // (a) a pointer to the head of an on-heap object. | 319 // (a) a pointer to the head of an on-heap object. |
320 // (b) a pointer to the head of an on-heap mixin object. | 320 // (b) a pointer to the head of an on-heap mixin object. |
321 // | 321 // |
322 // Otherwise, Heap::isHeapObjectAlive will crash when it calls | 322 // Otherwise, Heap::isHeapObjectAlive will crash when it calls |
323 // header->checkHeader(). | 323 // header->checkHeader(). |
324 Heap::isHeapObjectAlive(m_raw); | 324 Heap::isHeapObjectAlive(m_raw); |
325 // We're not interested in the result of Heap::isHeapObjectAlive. | |
326 return true; | |
327 } | |
Yuta Kitamura
2015/06/30 06:15:21
IMO this use of ASSERT() is too confusing. When th
| |
325 #endif | 328 #endif |
326 } | |
327 | 329 |
328 #if ENABLE(GC_PROFILING) | 330 #if ENABLE(GC_PROFILING) |
329 void recordBacktrace() | 331 void recordBacktrace() |
330 { | 332 { |
331 if (m_raw) | 333 if (m_raw) |
332 m_tracingName = Heap::createBacktraceString(); | 334 m_tracingName = Heap::createBacktraceString(); |
333 } | 335 } |
334 | 336 |
335 String m_tracingName; | 337 String m_tracingName; |
336 #else | 338 #else |
(...skipping 13 matching lines...) Expand all Loading... | |
350 } | 352 } |
351 | 353 |
352 CrossThreadPersistent(std::nullptr_t) : PersistentNode(TraceMethodDelegate<C rossThreadPersistent<T>, &CrossThreadPersistent<T>::trace>::trampoline), m_raw(n ullptr) | 354 CrossThreadPersistent(std::nullptr_t) : PersistentNode(TraceMethodDelegate<C rossThreadPersistent<T>, &CrossThreadPersistent<T>::trace>::trampoline), m_raw(n ullptr) |
353 { | 355 { |
354 initialize(); | 356 initialize(); |
355 } | 357 } |
356 | 358 |
357 CrossThreadPersistent(T* raw) : PersistentNode(TraceMethodDelegate<CrossThre adPersistent<T>, &CrossThreadPersistent<T>::trace>::trampoline), m_raw(raw) | 359 CrossThreadPersistent(T* raw) : PersistentNode(TraceMethodDelegate<CrossThre adPersistent<T>, &CrossThreadPersistent<T>::trace>::trampoline), m_raw(raw) |
358 { | 360 { |
359 initialize(); | 361 initialize(); |
360 checkPointer(); | 362 ASSERT(checkPointer()); |
361 recordBacktrace(); | 363 recordBacktrace(); |
362 } | 364 } |
363 | 365 |
364 CrossThreadPersistent(T& raw) : PersistentNode(TraceMethodDelegate<CrossThre adPersistent<T>, &CrossThreadPersistent<T>::trace>::trampoline), m_raw(&raw) | 366 CrossThreadPersistent(T& raw) : PersistentNode(TraceMethodDelegate<CrossThre adPersistent<T>, &CrossThreadPersistent<T>::trace>::trampoline), m_raw(&raw) |
365 { | 367 { |
366 initialize(); | 368 initialize(); |
367 checkPointer(); | 369 ASSERT(checkPointer()); |
368 recordBacktrace(); | 370 recordBacktrace(); |
369 } | 371 } |
370 | 372 |
371 CrossThreadPersistent(const CrossThreadPersistent& other) : PersistentNode(T raceMethodDelegate<CrossThreadPersistent<T>, &CrossThreadPersistent<T>::trace>:: trampoline), m_raw(other) | 373 CrossThreadPersistent(const CrossThreadPersistent& other) : PersistentNode(T raceMethodDelegate<CrossThreadPersistent<T>, &CrossThreadPersistent<T>::trace>:: trampoline), m_raw(other) |
372 { | 374 { |
373 initialize(); | 375 initialize(); |
374 checkPointer(); | 376 ASSERT(checkPointer()); |
375 recordBacktrace(); | 377 recordBacktrace(); |
376 } | 378 } |
377 | 379 |
378 template<typename U> | 380 template<typename U> |
379 CrossThreadPersistent(const CrossThreadPersistent<U>& other) : PersistentNod e(TraceMethodDelegate<CrossThreadPersistent<T>, &CrossThreadPersistent<T>::trace >::trampoline), m_raw(other) | 381 CrossThreadPersistent(const CrossThreadPersistent<U>& other) : PersistentNod e(TraceMethodDelegate<CrossThreadPersistent<T>, &CrossThreadPersistent<T>::trace >::trampoline), m_raw(other) |
380 { | 382 { |
381 initialize(); | 383 initialize(); |
382 checkPointer(); | 384 ASSERT(checkPointer()); |
383 recordBacktrace(); | 385 recordBacktrace(); |
384 } | 386 } |
385 | 387 |
386 template<typename U> | 388 template<typename U> |
387 CrossThreadPersistent(const Member<U>& other) : PersistentNode(TraceMethodDe legate<CrossThreadPersistent<T>, &CrossThreadPersistent<T>::trace>::trampoline), m_raw(other) | 389 CrossThreadPersistent(const Member<U>& other) : PersistentNode(TraceMethodDe legate<CrossThreadPersistent<T>, &CrossThreadPersistent<T>::trace>::trampoline), m_raw(other) |
388 { | 390 { |
389 initialize(); | 391 initialize(); |
390 checkPointer(); | 392 ASSERT(checkPointer()); |
391 recordBacktrace(); | 393 recordBacktrace(); |
392 } | 394 } |
393 | 395 |
394 template<typename U> | 396 template<typename U> |
395 CrossThreadPersistent(const RawPtr<U>& other) : PersistentNode(TraceMethodDe legate<CrossThreadPersistent<T>, &CrossThreadPersistent<T>::trace>::trampoline), m_raw(other.get()) | 397 CrossThreadPersistent(const RawPtr<U>& other) : PersistentNode(TraceMethodDe legate<CrossThreadPersistent<T>, &CrossThreadPersistent<T>::trace>::trampoline), m_raw(other.get()) |
396 { | 398 { |
397 initialize(); | 399 initialize(); |
398 checkPointer(); | 400 ASSERT(checkPointer()); |
399 recordBacktrace(); | 401 recordBacktrace(); |
400 } | 402 } |
401 | 403 |
402 void clear() { m_raw = nullptr; } | 404 void clear() { m_raw = nullptr; } |
403 | 405 |
404 ~CrossThreadPersistent() | 406 ~CrossThreadPersistent() |
405 { | 407 { |
406 uninitialize(); | 408 uninitialize(); |
407 m_raw = nullptr; | 409 m_raw = nullptr; |
408 m_trace = nullptr; | 410 m_trace = nullptr; |
(...skipping 20 matching lines...) Expand all Loading... | |
429 | 431 |
430 operator T*() const { return m_raw; } | 432 operator T*() const { return m_raw; } |
431 operator RawPtr<T>() const { return m_raw; } | 433 operator RawPtr<T>() const { return m_raw; } |
432 | 434 |
433 T* operator->() const { return *this; } | 435 T* operator->() const { return *this; } |
434 | 436 |
435 template<typename U> | 437 template<typename U> |
436 CrossThreadPersistent& operator=(U* other) | 438 CrossThreadPersistent& operator=(U* other) |
437 { | 439 { |
438 m_raw = other; | 440 m_raw = other; |
439 checkPointer(); | 441 ASSERT(checkPointer()); |
440 recordBacktrace(); | 442 recordBacktrace(); |
441 return *this; | 443 return *this; |
442 } | 444 } |
443 | 445 |
444 CrossThreadPersistent& operator=(std::nullptr_t) | 446 CrossThreadPersistent& operator=(std::nullptr_t) |
445 { | 447 { |
446 m_raw = nullptr; | 448 m_raw = nullptr; |
447 return *this; | 449 return *this; |
448 } | 450 } |
449 | 451 |
450 CrossThreadPersistent& operator=(const CrossThreadPersistent& other) | 452 CrossThreadPersistent& operator=(const CrossThreadPersistent& other) |
451 { | 453 { |
452 m_raw = other; | 454 m_raw = other; |
453 checkPointer(); | 455 ASSERT(checkPointer()); |
454 recordBacktrace(); | 456 recordBacktrace(); |
455 return *this; | 457 return *this; |
456 } | 458 } |
457 | 459 |
458 template<typename U> | 460 template<typename U> |
459 CrossThreadPersistent& operator=(const CrossThreadPersistent<U>& other) | 461 CrossThreadPersistent& operator=(const CrossThreadPersistent<U>& other) |
460 { | 462 { |
461 m_raw = other; | 463 m_raw = other; |
462 checkPointer(); | 464 ASSERT(checkPointer()); |
463 recordBacktrace(); | 465 recordBacktrace(); |
464 return *this; | 466 return *this; |
465 } | 467 } |
466 | 468 |
467 template<typename U> | 469 template<typename U> |
468 CrossThreadPersistent& operator=(const Member<U>& other) | 470 CrossThreadPersistent& operator=(const Member<U>& other) |
469 { | 471 { |
470 m_raw = other; | 472 m_raw = other; |
471 checkPointer(); | 473 ASSERT(checkPointer()); |
472 recordBacktrace(); | 474 recordBacktrace(); |
473 return *this; | 475 return *this; |
474 } | 476 } |
475 | 477 |
476 template<typename U> | 478 template<typename U> |
477 CrossThreadPersistent& operator=(const RawPtr<U>& other) | 479 CrossThreadPersistent& operator=(const RawPtr<U>& other) |
478 { | 480 { |
479 m_raw = other; | 481 m_raw = other; |
480 checkPointer(); | 482 ASSERT(checkPointer()); |
481 recordBacktrace(); | 483 recordBacktrace(); |
482 return *this; | 484 return *this; |
483 } | 485 } |
484 | 486 |
485 T* get() const { return m_raw; } | 487 T* get() const { return m_raw; } |
486 | 488 |
487 private: | 489 private: |
488 void initialize() | 490 void initialize() |
489 { | 491 { |
490 MutexLocker m_locker(ThreadState::globalRootsMutex()); | 492 MutexLocker m_locker(ThreadState::globalRootsMutex()); |
491 m_prev = &ThreadState::globalRoots(); | 493 m_prev = &ThreadState::globalRoots(); |
492 m_next = m_prev->m_next; | 494 m_next = m_prev->m_next; |
493 m_prev->m_next = this; | 495 m_prev->m_next = this; |
494 m_next->m_prev = this; | 496 m_next->m_prev = this; |
495 } | 497 } |
496 | 498 |
497 NO_LAZY_SWEEP_SANITIZE_ADDRESS | 499 NO_LAZY_SWEEP_SANITIZE_ADDRESS |
498 void uninitialize() | 500 void uninitialize() |
499 { | 501 { |
500 MutexLocker m_locker(ThreadState::globalRootsMutex()); | 502 MutexLocker m_locker(ThreadState::globalRootsMutex()); |
501 ASSERT(isHeapObjectAlive()); | 503 ASSERT(isHeapObjectAlive()); |
502 ASSERT(m_next->isHeapObjectAlive()); | 504 ASSERT(m_next->isHeapObjectAlive()); |
503 ASSERT(m_prev->isHeapObjectAlive()); | 505 ASSERT(m_prev->isHeapObjectAlive()); |
504 m_next->m_prev = m_prev; | 506 m_next->m_prev = m_prev; |
505 m_prev->m_next = m_next; | 507 m_prev->m_next = m_next; |
506 } | 508 } |
507 | 509 |
508 void checkPointer() | 510 #if ENABLE(ASSERT) |
511 bool checkPointer() | |
509 { | 512 { |
510 #if ENABLE(ASSERT) | |
511 if (!m_raw) | 513 if (!m_raw) |
512 return; | 514 return true; |
513 // Heap::isHeapObjectAlive(m_raw) checks that m_raw is a traceable | 515 // Heap::isHeapObjectAlive(m_raw) checks that m_raw is a traceable |
514 // object. In other words, it checks that the pointer is either of: | 516 // object. In other words, it checks that the pointer is either of: |
515 // | 517 // |
516 // (a) a pointer to the head of an on-heap object. | 518 // (a) a pointer to the head of an on-heap object. |
517 // (b) a pointer to the head of an on-heap mixin object. | 519 // (b) a pointer to the head of an on-heap mixin object. |
518 // | 520 // |
519 // Otherwise, Heap::isHeapObjectAlive will crash when it calls | 521 // Otherwise, Heap::isHeapObjectAlive will crash when it calls |
520 // header->checkHeader(). | 522 // header->checkHeader(). |
521 Heap::isHeapObjectAlive(m_raw); | 523 Heap::isHeapObjectAlive(m_raw); |
524 // We're not interested in the result of isHeapObjectAlive. | |
525 return true; | |
526 } | |
522 #endif | 527 #endif |
523 } | |
524 | 528 |
525 #if ENABLE(GC_PROFILING) | 529 #if ENABLE(GC_PROFILING) |
526 void recordBacktrace() | 530 void recordBacktrace() |
527 { | 531 { |
528 if (m_raw) | 532 if (m_raw) |
529 m_tracingName = Heap::createBacktraceString(); | 533 m_tracingName = Heap::createBacktraceString(); |
530 } | 534 } |
531 | 535 |
532 String m_tracingName; | 536 String m_tracingName; |
533 #else | 537 #else |
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
660 Member() : m_raw(nullptr) | 664 Member() : m_raw(nullptr) |
661 { | 665 { |
662 } | 666 } |
663 | 667 |
664 Member(std::nullptr_t) : m_raw(nullptr) | 668 Member(std::nullptr_t) : m_raw(nullptr) |
665 { | 669 { |
666 } | 670 } |
667 | 671 |
668 Member(T* raw) : m_raw(raw) | 672 Member(T* raw) : m_raw(raw) |
669 { | 673 { |
670 checkPointer(); | 674 ASSERT(checkPointer()); |
671 } | 675 } |
672 | 676 |
673 explicit Member(T& raw) : m_raw(&raw) | 677 explicit Member(T& raw) : m_raw(&raw) |
674 { | 678 { |
675 checkPointer(); | 679 ASSERT(checkPointer()); |
676 } | 680 } |
677 | 681 |
678 template<typename U> | 682 template<typename U> |
679 Member(const RawPtr<U>& other) : m_raw(other.get()) | 683 Member(const RawPtr<U>& other) : m_raw(other.get()) |
680 { | 684 { |
681 checkPointer(); | 685 ASSERT(checkPointer()); |
682 } | 686 } |
683 | 687 |
684 Member(WTF::HashTableDeletedValueType) : m_raw(reinterpret_cast<T*>(-1)) | 688 Member(WTF::HashTableDeletedValueType) : m_raw(reinterpret_cast<T*>(-1)) |
685 { | 689 { |
686 } | 690 } |
687 | 691 |
688 bool isHashTableDeletedValue() const { return m_raw == reinterpret_cast<T*>( -1); } | 692 bool isHashTableDeletedValue() const { return m_raw == reinterpret_cast<T*>( -1); } |
689 | 693 |
690 template<typename U> | 694 template<typename U> |
691 Member(const Persistent<U>& other) : m_raw(other) | 695 Member(const Persistent<U>& other) : m_raw(other) |
692 { | 696 { |
693 checkPointer(); | 697 ASSERT(checkPointer()); |
694 } | 698 } |
695 | 699 |
696 Member(const Member& other) : m_raw(other) | 700 Member(const Member& other) : m_raw(other) |
697 { | 701 { |
698 checkPointer(); | 702 ASSERT(checkPointer()); |
699 } | 703 } |
700 | 704 |
701 template<typename U> | 705 template<typename U> |
702 Member(const Member<U>& other) : m_raw(other) | 706 Member(const Member<U>& other) : m_raw(other) |
703 { | 707 { |
704 checkPointer(); | 708 ASSERT(checkPointer()); |
705 } | 709 } |
706 | 710 |
707 T* release() | 711 T* release() |
708 { | 712 { |
709 T* result = m_raw; | 713 T* result = m_raw; |
710 m_raw = nullptr; | 714 m_raw = nullptr; |
711 return result; | 715 return result; |
712 } | 716 } |
713 | 717 |
714 bool operator!() const { return !m_raw; } | 718 bool operator!() const { return !m_raw; } |
715 | 719 |
716 operator T*() const { return m_raw; } | 720 operator T*() const { return m_raw; } |
717 | 721 |
718 T* operator->() const { return m_raw; } | 722 T* operator->() const { return m_raw; } |
719 T& operator*() const { return *m_raw; } | 723 T& operator*() const { return *m_raw; } |
720 template<typename U> | 724 template<typename U> |
721 operator RawPtr<U>() const { return m_raw; } | 725 operator RawPtr<U>() const { return m_raw; } |
722 | 726 |
723 template<typename U> | 727 template<typename U> |
724 Member& operator=(const Persistent<U>& other) | 728 Member& operator=(const Persistent<U>& other) |
725 { | 729 { |
726 m_raw = other; | 730 m_raw = other; |
727 checkPointer(); | 731 ASSERT(checkPointer()); |
728 return *this; | 732 return *this; |
729 } | 733 } |
730 | 734 |
731 template<typename U> | 735 template<typename U> |
732 Member& operator=(const Member<U>& other) | 736 Member& operator=(const Member<U>& other) |
733 { | 737 { |
734 m_raw = other; | 738 m_raw = other; |
735 checkPointer(); | 739 ASSERT(checkPointer()); |
736 return *this; | 740 return *this; |
737 } | 741 } |
738 | 742 |
739 template<typename U> | 743 template<typename U> |
740 Member& operator=(U* other) | 744 Member& operator=(U* other) |
741 { | 745 { |
742 m_raw = other; | 746 m_raw = other; |
743 checkPointer(); | 747 ASSERT(checkPointer()); |
744 return *this; | 748 return *this; |
745 } | 749 } |
746 | 750 |
747 template<typename U> | 751 template<typename U> |
748 Member& operator=(RawPtr<U> other) | 752 Member& operator=(RawPtr<U> other) |
749 { | 753 { |
750 m_raw = other; | 754 m_raw = other; |
751 checkPointer(); | 755 ASSERT(checkPointer()); |
752 return *this; | 756 return *this; |
753 } | 757 } |
754 | 758 |
755 Member& operator=(std::nullptr_t) | 759 Member& operator=(std::nullptr_t) |
756 { | 760 { |
757 m_raw = nullptr; | 761 m_raw = nullptr; |
758 return *this; | 762 return *this; |
759 } | 763 } |
760 | 764 |
761 void swap(Member<T>& other) | 765 void swap(Member<T>& other) |
762 { | 766 { |
763 std::swap(m_raw, other.m_raw); | 767 std::swap(m_raw, other.m_raw); |
764 checkPointer(); | 768 ASSERT(checkPointer()); |
765 } | 769 } |
766 | 770 |
767 T* get() const { return m_raw; } | 771 T* get() const { return m_raw; } |
768 | 772 |
769 void clear() { m_raw = nullptr; } | 773 void clear() { m_raw = nullptr; } |
770 | 774 |
771 | 775 |
772 protected: | 776 protected: |
773 void checkPointer() | 777 #if ENABLE(ASSERT) |
778 bool checkPointer() | |
774 { | 779 { |
775 #if ENABLE(ASSERT) | |
776 if (!m_raw) | 780 if (!m_raw) |
777 return; | 781 return true; |
778 // HashTable can store a special value (which is not aligned to the | 782 // HashTable can store a special value (which is not aligned to the |
779 // allocation granularity) to Member<> to represent a deleted entry. | 783 // allocation granularity) to Member<> to represent a deleted entry. |
780 // Thus we treat a pointer that is not aligned to the granularity | 784 // Thus we treat a pointer that is not aligned to the granularity |
781 // as a valid pointer. | 785 // as a valid pointer. |
782 if (reinterpret_cast<intptr_t>(m_raw) % allocationGranularity) | 786 if (reinterpret_cast<intptr_t>(m_raw) % allocationGranularity) |
783 return; | 787 return true; |
784 | 788 |
785 // TODO(haraken): What we really want to check here is that the pointer | 789 // TODO(haraken): What we really want to check here is that the pointer |
786 // is a traceable object. In other words, the pointer is either of: | 790 // is a traceable object. In other words, the pointer is either of: |
787 // | 791 // |
788 // (a) a pointer to the head of an on-heap object. | 792 // (a) a pointer to the head of an on-heap object. |
789 // (b) a pointer to the head of an on-heap mixin object. | 793 // (b) a pointer to the head of an on-heap mixin object. |
790 // | 794 // |
791 // We can check it by calling Heap::isHeapObjectAlive(m_raw), | 795 // We can check it by calling Heap::isHeapObjectAlive(m_raw), |
792 // but we cannot call it here because it requres to include T.h. | 796 // but we cannot call it here because it requres to include T.h. |
793 // So we currently implement only the check for (a). | 797 // So we currently implement only the check for (a). |
794 if (!IsGarbageCollectedMixin<T>::value) | 798 if (!IsGarbageCollectedMixin<T>::value) |
795 HeapObjectHeader::fromPayload(m_raw)->checkHeader(); | 799 HeapObjectHeader::fromPayload(m_raw)->checkHeader(); |
800 return true; | |
801 } | |
796 #endif | 802 #endif |
797 } | |
798 | 803 |
799 T* m_raw; | 804 T* m_raw; |
800 | 805 |
801 template<bool x, WTF::WeakHandlingFlag y, WTF::ShouldWeakPointersBeMarkedStr ongly z, typename U, typename V> friend struct CollectionBackingTraceTrait; | 806 template<bool x, WTF::WeakHandlingFlag y, WTF::ShouldWeakPointersBeMarkedStr ongly z, typename U, typename V> friend struct CollectionBackingTraceTrait; |
802 friend class Visitor; | 807 friend class Visitor; |
803 | 808 |
804 }; | 809 }; |
805 | 810 |
806 // WeakMember is similar to Member in that it is used to point to other oilpan | 811 // WeakMember is similar to Member in that it is used to point to other oilpan |
807 // heap allocated objects. | 812 // heap allocated objects. |
(...skipping 15 matching lines...) Expand all Loading... | |
823 template<typename U> | 828 template<typename U> |
824 WeakMember(const Persistent<U>& other) : Member<T>(other) { } | 829 WeakMember(const Persistent<U>& other) : Member<T>(other) { } |
825 | 830 |
826 template<typename U> | 831 template<typename U> |
827 WeakMember(const Member<U>& other) : Member<T>(other) { } | 832 WeakMember(const Member<U>& other) : Member<T>(other) { } |
828 | 833 |
829 template<typename U> | 834 template<typename U> |
830 WeakMember& operator=(const Persistent<U>& other) | 835 WeakMember& operator=(const Persistent<U>& other) |
831 { | 836 { |
832 this->m_raw = other; | 837 this->m_raw = other; |
833 this->checkPointer(); | 838 ASSERT(this->checkPointer()); |
834 return *this; | 839 return *this; |
835 } | 840 } |
836 | 841 |
837 template<typename U> | 842 template<typename U> |
838 WeakMember& operator=(const Member<U>& other) | 843 WeakMember& operator=(const Member<U>& other) |
839 { | 844 { |
840 this->m_raw = other; | 845 this->m_raw = other; |
841 this->checkPointer(); | 846 ASSERT(this->checkPointer()); |
842 return *this; | 847 return *this; |
843 } | 848 } |
844 | 849 |
845 template<typename U> | 850 template<typename U> |
846 WeakMember& operator=(U* other) | 851 WeakMember& operator=(U* other) |
847 { | 852 { |
848 this->m_raw = other; | 853 this->m_raw = other; |
849 this->checkPointer(); | 854 ASSERT(this->checkPointer()); |
850 return *this; | 855 return *this; |
851 } | 856 } |
852 | 857 |
853 template<typename U> | 858 template<typename U> |
854 WeakMember& operator=(const RawPtr<U>& other) | 859 WeakMember& operator=(const RawPtr<U>& other) |
855 { | 860 { |
856 this->m_raw = other; | 861 this->m_raw = other; |
857 this->checkPointer(); | 862 ASSERT(this->checkPointer()); |
858 return *this; | 863 return *this; |
859 } | 864 } |
860 | 865 |
861 WeakMember& operator=(std::nullptr_t) | 866 WeakMember& operator=(std::nullptr_t) |
862 { | 867 { |
863 this->m_raw = nullptr; | 868 this->m_raw = nullptr; |
864 return *this; | 869 return *this; |
865 } | 870 } |
866 | 871 |
867 private: | 872 private: |
(...skipping 419 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1287 struct ParamStorageTraits<RawPtr<T>> : public PointerParamStorageTraits<T*, blin k::IsGarbageCollectedType<T>::value> { | 1292 struct ParamStorageTraits<RawPtr<T>> : public PointerParamStorageTraits<T*, blin k::IsGarbageCollectedType<T>::value> { |
1288 static_assert(sizeof(T), "T must be fully defined"); | 1293 static_assert(sizeof(T), "T must be fully defined"); |
1289 }; | 1294 }; |
1290 | 1295 |
1291 template<typename T> | 1296 template<typename T> |
1292 PassRefPtr<T> adoptRef(blink::RefCountedGarbageCollected<T>*) = delete; | 1297 PassRefPtr<T> adoptRef(blink::RefCountedGarbageCollected<T>*) = delete; |
1293 | 1298 |
1294 } // namespace WTF | 1299 } // namespace WTF |
1295 | 1300 |
1296 #endif | 1301 #endif |
OLD | NEW |