Chromium Code Reviews| 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 |