| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2013 Google Inc. All rights reserved. | 2 * Copyright (C) 2013 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 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 51 | 51 |
| 52 namespace blink { | 52 namespace blink { |
| 53 | 53 |
| 54 class BasePage; | 54 class BasePage; |
| 55 class CallbackStack; | 55 class CallbackStack; |
| 56 struct GCInfo; | 56 struct GCInfo; |
| 57 class GarbageCollectedMixinConstructorMarker; | 57 class GarbageCollectedMixinConstructorMarker; |
| 58 class HeapObjectHeader; | 58 class HeapObjectHeader; |
| 59 class PersistentNode; | 59 class PersistentNode; |
| 60 class PersistentRegion; | 60 class PersistentRegion; |
| 61 class BaseHeap; | 61 class BaseArena; |
| 62 class SafePointAwareMutexLocker; | 62 class SafePointAwareMutexLocker; |
| 63 class SafePointBarrier; | 63 class SafePointBarrier; |
| 64 class ThreadState; | 64 class ThreadState; |
| 65 class Visitor; | 65 class Visitor; |
| 66 class Heap; |
| 66 | 67 |
| 67 // Declare that a class has a pre-finalizer. The pre-finalizer is called | 68 // Declare that a class has a pre-finalizer. The pre-finalizer is called |
| 68 // before any object gets swept, so it is safe to touch on-heap objects | 69 // before any object gets swept, so it is safe to touch on-heap objects |
| 69 // that may be collected in the same GC cycle. If you cannot avoid touching | 70 // that may be collected in the same GC cycle. If you cannot avoid touching |
| 70 // on-heap objects in a destructor (which is not allowed), you can consider | 71 // on-heap objects in a destructor (which is not allowed), you can consider |
| 71 // using the pre-finalizer. The only restriction is that the pre-finalizer | 72 // using the pre-finalizer. The only restriction is that the pre-finalizer |
| 72 // must not resurrect dead objects (e.g., store unmarked objects into | 73 // must not resurrect dead objects (e.g., store unmarked objects into |
| 73 // Members etc). The pre-finalizer is called on the thread that registered | 74 // Members etc). The pre-finalizer is called on the thread that registered |
| 74 // the pre-finalizer. | 75 // the pre-finalizer. |
| 75 // | 76 // |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 167 } | 168 } |
| 168 ~SweepForbiddenScope() | 169 ~SweepForbiddenScope() |
| 169 { | 170 { |
| 170 ASSERT(m_state->m_sweepForbidden); | 171 ASSERT(m_state->m_sweepForbidden); |
| 171 m_state->m_sweepForbidden = false; | 172 m_state->m_sweepForbidden = false; |
| 172 } | 173 } |
| 173 private: | 174 private: |
| 174 ThreadState* m_state; | 175 ThreadState* m_state; |
| 175 }; | 176 }; |
| 176 | 177 |
| 177 // The set of ThreadStates for all threads attached to the Blink | |
| 178 // garbage collector. | |
| 179 using AttachedThreadStateSet = HashSet<ThreadState*>; | |
| 180 static AttachedThreadStateSet& attachedThreads(); | |
| 181 static RecursiveMutex& threadAttachMutex(); | |
| 182 static void lockThreadAttachMutex(); | |
| 183 static void unlockThreadAttachMutex(); | |
| 184 | |
| 185 // Initialize threading infrastructure. Should be called from the main | 178 // Initialize threading infrastructure. Should be called from the main |
| 186 // thread. | 179 // thread. |
| 187 static void init(); | 180 static void init(); |
| 188 static void shutdown(); | 181 static void shutdown(); |
| 189 static void shutdownHeapIfNecessary(); | 182 static void shutdownHeapIfNecessary(); |
| 190 bool isTerminating() { return m_isTerminating; } | 183 bool isTerminating() { return m_isTerminating; } |
| 191 | 184 |
| 192 static void attachMainThread(); | 185 static void attachMainThread(); |
| 193 static void detachMainThread(); | 186 static void detachMainThread(); |
| 194 | 187 |
| 195 // Trace all persistent roots, called when marking the managed heap objects. | 188 // Trace all persistent roots, called when marking the managed heap objects. |
| 196 static void visitPersistentRoots(Visitor*); | 189 static void visitPersistentRoots(Visitor*); |
| 197 | 190 |
| 198 // Trace all objects found on the stack, used when doing conservative GCs. | 191 // Trace all objects found on the stack, used when doing conservative GCs. |
| 199 static void visitStackRoots(Visitor*); | 192 static void visitStackRoots(Visitor*); |
| 200 | 193 |
| 201 // Associate ThreadState object with the current thread. After this | 194 // Associate ThreadState object with the current thread. After this |
| 202 // call thread can start using the garbage collected heap infrastructure. | 195 // call thread can start using the garbage collected heap infrastructure. |
| 203 // It also has to periodically check for safepoints. | 196 // It also has to periodically check for safepoints. |
| 204 static void attach(); | 197 static void attach(); |
| 205 | 198 |
| 206 // Disassociate attached ThreadState from the current thread. The thread | 199 // Disassociate attached ThreadState from the current thread. The thread |
| 207 // can no longer use the garbage collected heap after this call. | 200 // can no longer use the garbage collected heap after this call. |
| 208 static void detach(); | 201 static void detachCurrentThread(); |
| 202 void detach(); |
| 209 | 203 |
| 210 static ThreadState* current() | 204 static ThreadState* current() |
| 211 { | 205 { |
| 212 #if defined(__GLIBC__) || OS(ANDROID) || OS(FREEBSD) | 206 #if defined(__GLIBC__) || OS(ANDROID) || OS(FREEBSD) |
| 213 // TLS lookup is fast in these platforms. | 207 // TLS lookup is fast in these platforms. |
| 214 return **s_threadSpecific; | 208 return **s_threadSpecific; |
| 215 #else | 209 #else |
| 216 uintptr_t dummy; | 210 uintptr_t dummy; |
| 217 uintptr_t addressDiff = s_mainThreadStackStart - reinterpret_cast<uintpt
r_t>(&dummy); | 211 uintptr_t addressDiff = s_mainThreadStackStart - reinterpret_cast<uintpt
r_t>(&dummy); |
| 218 // This is a fast way to judge if we are in the main thread. | 212 // This is a fast way to judge if we are in the main thread. |
| 219 // If |&dummy| is within |s_mainThreadUnderestimatedStackSize| byte from | 213 // If |&dummy| is within |s_mainThreadUnderestimatedStackSize| byte from |
| 220 // the stack start of the main thread, we judge that we are in | 214 // the stack start of the main thread, we judge that we are in |
| 221 // the main thread. | 215 // the main thread. |
| 222 if (LIKELY(addressDiff < s_mainThreadUnderestimatedStackSize)) { | 216 if (LIKELY(addressDiff < s_mainThreadUnderestimatedStackSize)) { |
| 223 ASSERT(**s_threadSpecific == mainThreadState()); | 217 ASSERT(**s_threadSpecific == mainThreadState()); |
| 224 return mainThreadState(); | 218 return mainThreadState(); |
| 225 } | 219 } |
| 226 // TLS lookup is slow. | 220 // TLS lookup is slow. |
| 227 return **s_threadSpecific; | 221 return **s_threadSpecific; |
| 228 #endif | 222 #endif |
| 229 } | 223 } |
| 230 | 224 |
| 231 static ThreadState* mainThreadState() | 225 static ThreadState* mainThreadState() |
| 232 { | 226 { |
| 233 return reinterpret_cast<ThreadState*>(s_mainThreadStateStorage); | 227 return reinterpret_cast<ThreadState*>(s_mainThreadStateStorage); |
| 234 } | 228 } |
| 235 | 229 |
| 230 static ThreadState* fromObject(const void*); |
| 231 |
| 236 bool isMainThread() const { return this == mainThreadState(); } | 232 bool isMainThread() const { return this == mainThreadState(); } |
| 237 #if ENABLE(ASSERT) | 233 #if ENABLE(ASSERT) |
| 238 bool checkThread() const { return m_thread == currentThread(); } | 234 bool checkThread() const { return m_thread == currentThread(); } |
| 239 #endif | 235 #endif |
| 240 | 236 |
| 237 Heap& heap() { return *m_heap; } |
| 238 |
| 239 // When ThreadState is detaching from non-main thread its |
| 240 // heap is expected to be empty (because it is going away). |
| 241 // Perform registered cleanup tasks and garbage collection |
| 242 // to sweep away any objects that are left on this heap. |
| 243 // We assert that nothing must remain after this cleanup. |
| 244 // If assertion does not hold we crash as we are potentially |
| 245 // in the dangling pointer situation. |
| 246 void cleanup(); |
| 247 |
| 241 void performIdleGC(double deadlineSeconds); | 248 void performIdleGC(double deadlineSeconds); |
| 242 void performIdleLazySweep(double deadlineSeconds); | 249 void performIdleLazySweep(double deadlineSeconds); |
| 243 | 250 |
| 244 void scheduleIdleGC(); | 251 void scheduleIdleGC(); |
| 245 void scheduleIdleLazySweep(); | 252 void scheduleIdleLazySweep(); |
| 246 void schedulePreciseGC(); | 253 void schedulePreciseGC(); |
| 247 void scheduleV8FollowupGCIfNeeded(BlinkGC::V8GCType); | 254 void scheduleV8FollowupGCIfNeeded(BlinkGC::V8GCType); |
| 248 void schedulePageNavigationGCIfNeeded(float estimatedRemovalRatio); | 255 void schedulePageNavigationGCIfNeeded(float estimatedRemovalRatio); |
| 249 void schedulePageNavigationGC(); | 256 void schedulePageNavigationGC(); |
| 250 void scheduleGCIfNeeded(); | 257 void scheduleGCIfNeeded(); |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 322 // there is a GC in progress. | 329 // there is a GC in progress. |
| 323 // | 330 // |
| 324 // Each thread that has ThreadState attached must: | 331 // Each thread that has ThreadState attached must: |
| 325 // - periodically check if GC is requested from another thread by calling
a safePoint() method; | 332 // - periodically check if GC is requested from another thread by calling
a safePoint() method; |
| 326 // - use SafePointScope around long running loops that have no safePoint()
invocation inside, | 333 // - use SafePointScope around long running loops that have no safePoint()
invocation inside, |
| 327 // such loops must not touch any heap object; | 334 // such loops must not touch any heap object; |
| 328 // - register an BlinkGCInterruptor that can interrupt long running loops
that have no calls to safePoint and | 335 // - register an BlinkGCInterruptor that can interrupt long running loops
that have no calls to safePoint and |
| 329 // are not wrapped in a SafePointScope (e.g. BlinkGCInterruptor for Java
Script code) | 336 // are not wrapped in a SafePointScope (e.g. BlinkGCInterruptor for Java
Script code) |
| 330 // | 337 // |
| 331 | 338 |
| 332 // Request all other threads to stop. Must only be called if the current thr
ead is at safepoint. | |
| 333 static bool stopThreads(); | |
| 334 static void resumeThreads(); | |
| 335 | |
| 336 // Check if GC is requested by another thread and pause this thread if this
is the case. | 339 // Check if GC is requested by another thread and pause this thread if this
is the case. |
| 337 // Can only be called when current thread is in a consistent state. | 340 // Can only be called when current thread is in a consistent state. |
| 338 void safePoint(BlinkGC::StackState); | 341 void safePoint(BlinkGC::StackState); |
| 339 | 342 |
| 340 // Mark current thread as running inside safepoint. | 343 // Mark current thread as running inside safepoint. |
| 341 void enterSafePoint(BlinkGC::StackState, void*); | 344 void enterSafePoint(BlinkGC::StackState, void*); |
| 342 void leaveSafePoint(SafePointAwareMutexLocker* = nullptr); | 345 void leaveSafePoint(SafePointAwareMutexLocker* = nullptr); |
| 343 bool isAtSafePoint() const { return m_atSafePoint; } | 346 bool isAtSafePoint() const { return m_atSafePoint; } |
| 344 | 347 |
| 345 void addInterruptor(PassOwnPtr<BlinkGCInterruptor>); | 348 void addInterruptor(PassOwnPtr<BlinkGCInterruptor>); |
| 346 void removeInterruptor(BlinkGCInterruptor*); | 349 void removeInterruptor(BlinkGCInterruptor*); |
| 347 | 350 |
| 348 void recordStackEnd(intptr_t* endOfStack) | 351 void recordStackEnd(intptr_t* endOfStack) |
| 349 { | 352 { |
| 350 m_endOfStack = endOfStack; | 353 m_endOfStack = endOfStack; |
| 351 } | 354 } |
| 352 | 355 |
| 353 // Get one of the heap structures for this thread. | 356 // Get one of the heap structures for this thread. |
| 354 // The thread heap is split into multiple heap parts based on object types | 357 // The thread heap is split into multiple heap parts based on object types |
| 355 // and object sizes. | 358 // and object sizes. |
| 356 BaseHeap* heap(int heapIndex) const | 359 BaseArena* arena(int arenaIndex) const |
| 357 { | 360 { |
| 358 ASSERT(0 <= heapIndex); | 361 ASSERT(0 <= arenaIndex); |
| 359 ASSERT(heapIndex < BlinkGC::NumberOfHeaps); | 362 ASSERT(arenaIndex < BlinkGC::NumberOfArenas); |
| 360 return m_heaps[heapIndex]; | 363 return m_arenas[arenaIndex]; |
| 361 } | 364 } |
| 362 | 365 |
| 363 #if ENABLE(ASSERT) | 366 #if ENABLE(ASSERT) |
| 364 // Infrastructure to determine if an address is within one of the | 367 // Infrastructure to determine if an address is within one of the |
| 365 // address ranges for the Blink heap. If the address is in the Blink | 368 // address ranges for the Blink heap. If the address is in the Blink |
| 366 // heap the containing heap page is returned. | 369 // heap the containing heap page is returned. |
| 367 BasePage* findPageFromAddress(Address); | 370 BasePage* findPageFromAddress(Address); |
| 368 BasePage* findPageFromAddress(const void* pointer) { return findPageFromAddr
ess(reinterpret_cast<Address>(const_cast<void*>(pointer))); } | 371 BasePage* findPageFromAddress(const void* pointer) { return findPageFromAddr
ess(reinterpret_cast<Address>(const_cast<void*>(pointer))); } |
| 369 #endif | 372 #endif |
| 370 | 373 |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 449 } | 452 } |
| 450 void leaveGCForbiddenScopeIfNeeded(GarbageCollectedMixinConstructorMarker* g
cMixinMarker) | 453 void leaveGCForbiddenScopeIfNeeded(GarbageCollectedMixinConstructorMarker* g
cMixinMarker) |
| 451 { | 454 { |
| 452 ASSERT(checkThread()); | 455 ASSERT(checkThread()); |
| 453 if (m_gcMixinMarker == gcMixinMarker) { | 456 if (m_gcMixinMarker == gcMixinMarker) { |
| 454 leaveGCForbiddenScope(); | 457 leaveGCForbiddenScope(); |
| 455 m_gcMixinMarker = nullptr; | 458 m_gcMixinMarker = nullptr; |
| 456 } | 459 } |
| 457 } | 460 } |
| 458 | 461 |
| 459 // vectorBackingHeap() returns a heap that the vector allocation should use. | 462 // vectorBackingArena() returns a arena that the vector allocation should us
e. |
| 460 // We have four vector heaps and want to choose the best heap here. | 463 // We have four vector arenas and want to choose the best arena here. |
| 461 // | 464 // |
| 462 // The goal is to improve the succession rate where expand and | 465 // The goal is to improve the succession rate where expand and |
| 463 // promptlyFree happen at an allocation point. This is a key for reusing | 466 // promptlyFree happen at an allocation point. This is a key for reusing |
| 464 // the same memory as much as possible and thus improves performance. | 467 // the same memory as much as possible and thus improves performance. |
| 465 // To achieve the goal, we use the following heuristics: | 468 // To achieve the goal, we use the following heuristics: |
| 466 // | 469 // |
| 467 // - A vector that has been expanded recently is likely to be expanded | 470 // - A vector that has been expanded recently is likely to be expanded |
| 468 // again soon. | 471 // again soon. |
| 469 // - A vector is likely to be promptly freed if the same type of vector | 472 // - A vector is likely to be promptly freed if the same type of vector |
| 470 // has been frequently promptly freed in the past. | 473 // has been frequently promptly freed in the past. |
| 471 // - Given the above, when allocating a new vector, look at the four vectors | 474 // - Given the above, when allocating a new vector, look at the four vectors |
| 472 // that are placed immediately prior to the allocation point of each heap. | 475 // that are placed immediately prior to the allocation point of each heap. |
| 473 // Choose the heap where the vector is least likely to be expanded | 476 // Choose the heap where the vector is least likely to be expanded |
| 474 // nor promptly freed. | 477 // nor promptly freed. |
| 475 // | 478 // |
| 476 // To implement the heuristics, we add a heapAge to each heap. The heapAge | 479 // To implement the heuristics, we add a arenaAge to each arena. The arenaAg
e |
| 477 // is updated if: | 480 // is updated if: |
| 478 // | 481 // |
| 479 // - a vector on the heap is expanded; or | 482 // - a vector on the arena is expanded; or |
| 480 // - a vector that meets the condition (*) is allocated on the heap | 483 // - a vector that meets the condition (*) is allocated on the arena |
| 481 // | 484 // |
| 482 // (*) More than 33% of the same type of vectors have been promptly | 485 // (*) More than 33% of the same type of vectors have been promptly |
| 483 // freed since the last GC. | 486 // freed since the last GC. |
| 484 // | 487 // |
| 485 BaseHeap* vectorBackingHeap(size_t gcInfoIndex) | 488 BaseArena* vectorBackingArena(size_t gcInfoIndex) |
| 486 { | 489 { |
| 487 ASSERT(checkThread()); | 490 ASSERT(checkThread()); |
| 488 size_t entryIndex = gcInfoIndex & likelyToBePromptlyFreedArrayMask; | 491 size_t entryIndex = gcInfoIndex & likelyToBePromptlyFreedArrayMask; |
| 489 --m_likelyToBePromptlyFreed[entryIndex]; | 492 --m_likelyToBePromptlyFreed[entryIndex]; |
| 490 int heapIndex = m_vectorBackingHeapIndex; | 493 int arenaIndex = m_vectorBackingArenaIndex; |
| 491 // If m_likelyToBePromptlyFreed[entryIndex] > 0, that means that | 494 // If m_likelyToBePromptlyFreed[entryIndex] > 0, that means that |
| 492 // more than 33% of vectors of the type have been promptly freed | 495 // more than 33% of vectors of the type have been promptly freed |
| 493 // since the last GC. | 496 // since the last GC. |
| 494 if (m_likelyToBePromptlyFreed[entryIndex] > 0) { | 497 if (m_likelyToBePromptlyFreed[entryIndex] > 0) { |
| 495 m_heapAges[heapIndex] = ++m_currentHeapAges; | 498 m_arenaAges[arenaIndex] = ++m_currentHeapAges; |
| 496 m_vectorBackingHeapIndex = heapIndexOfVectorHeapLeastRecentlyExpande
d(BlinkGC::Vector1HeapIndex, BlinkGC::Vector4HeapIndex); | 499 m_vectorBackingArenaIndex = arenaIndexOfVectorHeapLeastRecentlyExpan
ded(BlinkGC::Vector1ArenaIndex, BlinkGC::Vector4ArenaIndex); |
| 497 } | 500 } |
| 498 ASSERT(isVectorHeapIndex(heapIndex)); | 501 ASSERT(isVectorArenaIndex(arenaIndex)); |
| 499 return m_heaps[heapIndex]; | 502 return m_arenas[arenaIndex]; |
| 500 } | 503 } |
| 501 BaseHeap* expandedVectorBackingHeap(size_t gcInfoIndex); | 504 BaseArena* expandedVectorBackingArena(size_t gcInfoIndex); |
| 502 static bool isVectorHeapIndex(int heapIndex) | 505 static bool isVectorArenaIndex(int arenaIndex) |
| 503 { | 506 { |
| 504 return BlinkGC::Vector1HeapIndex <= heapIndex && heapIndex <= BlinkGC::V
ector4HeapIndex; | 507 return BlinkGC::Vector1ArenaIndex <= arenaIndex && arenaIndex <= BlinkGC
::Vector4ArenaIndex; |
| 505 } | 508 } |
| 506 void allocationPointAdjusted(int heapIndex); | 509 void allocationPointAdjusted(int arenaIndex); |
| 507 void promptlyFreed(size_t gcInfoIndex); | 510 void promptlyFreed(size_t gcInfoIndex); |
| 508 | 511 |
| 509 void accumulateSweepingTime(double time) { m_accumulatedSweepingTime += time
; } | 512 void accumulateSweepingTime(double time) { m_accumulatedSweepingTime += time
; } |
| 510 | 513 |
| 511 #if OS(WIN) && COMPILER(MSVC) | 514 #if OS(WIN) && COMPILER(MSVC) |
| 512 size_t threadStackSize(); | 515 size_t threadStackSize(); |
| 513 #endif | 516 #endif |
| 514 | 517 |
| 515 #if defined(LEAK_SANITIZER) | 518 #if defined(LEAK_SANITIZER) |
| 516 void registerStaticPersistentNode(PersistentNode*); | 519 void registerStaticPersistentNode(PersistentNode*); |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 578 | 581 |
| 579 void runScheduledGC(BlinkGC::StackState); | 582 void runScheduledGC(BlinkGC::StackState); |
| 580 | 583 |
| 581 void eagerSweep(); | 584 void eagerSweep(); |
| 582 | 585 |
| 583 #if defined(ADDRESS_SANITIZER) | 586 #if defined(ADDRESS_SANITIZER) |
| 584 void poisonEagerHeap(BlinkGC::Poisoning); | 587 void poisonEagerHeap(BlinkGC::Poisoning); |
| 585 void poisonAllHeaps(); | 588 void poisonAllHeaps(); |
| 586 #endif | 589 #endif |
| 587 | 590 |
| 588 // When ThreadState is detaching from non-main thread its | |
| 589 // heap is expected to be empty (because it is going away). | |
| 590 // Perform registered cleanup tasks and garbage collection | |
| 591 // to sweep away any objects that are left on this heap. | |
| 592 // We assert that nothing must remain after this cleanup. | |
| 593 // If assertion does not hold we crash as we are potentially | |
| 594 // in the dangling pointer situation. | |
| 595 void cleanup(); | |
| 596 void cleanupPages(); | 591 void cleanupPages(); |
| 597 | 592 |
| 598 void prepareForThreadStateTermination(); | 593 void prepareForThreadStateTermination(); |
| 599 | 594 |
| 600 void invokePreFinalizers(); | 595 void invokePreFinalizers(); |
| 601 | 596 |
| 602 void takeSnapshot(SnapshotType); | 597 void takeSnapshot(SnapshotType); |
| 603 void clearHeapAges(); | 598 void clearHeapAges(); |
| 604 int heapIndexOfVectorHeapLeastRecentlyExpanded(int beginHeapIndex, int endHe
apIndex); | 599 int arenaIndexOfVectorHeapLeastRecentlyExpanded(int beginArenaIndex, int end
ArenaIndex); |
| 605 | 600 |
| 606 void reportMemoryToV8(); | 601 void reportMemoryToV8(); |
| 607 | 602 |
| 608 // Should only be called under protection of threadAttachMutex(). | 603 // Should only be called under protection of threadAttachMutex(). |
| 609 const Vector<OwnPtr<BlinkGCInterruptor>>& interruptors() const { return m_in
terruptors; } | 604 const Vector<OwnPtr<BlinkGCInterruptor>>& interruptors() const { return m_in
terruptors; } |
| 610 | 605 |
| 611 friend class SafePointAwareMutexLocker; | 606 friend class SafePointAwareMutexLocker; |
| 612 friend class SafePointBarrier; | 607 friend class SafePointBarrier; |
| 613 friend class SafePointScope; | 608 friend class SafePointScope; |
| 614 | 609 |
| 615 static WTF::ThreadSpecific<ThreadState*>* s_threadSpecific; | 610 static WTF::ThreadSpecific<ThreadState*>* s_threadSpecific; |
| 616 static uintptr_t s_mainThreadStackStart; | 611 static uintptr_t s_mainThreadStackStart; |
| 617 static uintptr_t s_mainThreadUnderestimatedStackSize; | 612 static uintptr_t s_mainThreadUnderestimatedStackSize; |
| 618 static SafePointBarrier* s_safePointBarrier; | |
| 619 | 613 |
| 620 // We can't create a static member of type ThreadState here | 614 // We can't create a static member of type ThreadState here |
| 621 // because it will introduce global constructor and destructor. | 615 // because it will introduce global constructor and destructor. |
| 622 // We would like to manage lifetime of the ThreadState attached | 616 // We would like to manage lifetime of the ThreadState attached |
| 623 // to the main thread explicitly instead and still use normal | 617 // to the main thread explicitly instead and still use normal |
| 624 // constructor and destructor for the ThreadState class. | 618 // constructor and destructor for the ThreadState class. |
| 625 // For this we reserve static storage for the main ThreadState | 619 // For this we reserve static storage for the main ThreadState |
| 626 // and lazily construct ThreadState in it using placement new. | 620 // and lazily construct ThreadState in it using placement new. |
| 627 static uint8_t s_mainThreadStateStorage[]; | 621 static uint8_t s_mainThreadStateStorage[]; |
| 628 | 622 |
| 623 Heap* m_heap; |
| 629 ThreadIdentifier m_thread; | 624 ThreadIdentifier m_thread; |
| 630 OwnPtr<PersistentRegion> m_persistentRegion; | 625 OwnPtr<PersistentRegion> m_persistentRegion; |
| 631 BlinkGC::StackState m_stackState; | 626 BlinkGC::StackState m_stackState; |
| 632 #if OS(WIN) && COMPILER(MSVC) | 627 #if OS(WIN) && COMPILER(MSVC) |
| 633 size_t m_threadStackSize; | 628 size_t m_threadStackSize; |
| 634 #endif | 629 #endif |
| 635 intptr_t* m_startOfStack; | 630 intptr_t* m_startOfStack; |
| 636 intptr_t* m_endOfStack; | 631 intptr_t* m_endOfStack; |
| 637 | 632 |
| 638 void* m_safePointScopeMarker; | 633 void* m_safePointScopeMarker; |
| 639 Vector<Address> m_safePointStackCopy; | 634 Vector<Address> m_safePointStackCopy; |
| 640 bool m_atSafePoint; | 635 bool m_atSafePoint; |
| 641 Vector<OwnPtr<BlinkGCInterruptor>> m_interruptors; | 636 Vector<OwnPtr<BlinkGCInterruptor>> m_interruptors; |
| 642 bool m_sweepForbidden; | 637 bool m_sweepForbidden; |
| 643 size_t m_noAllocationCount; | 638 size_t m_noAllocationCount; |
| 644 size_t m_gcForbiddenCount; | 639 size_t m_gcForbiddenCount; |
| 645 double m_accumulatedSweepingTime; | 640 double m_accumulatedSweepingTime; |
| 646 | 641 |
| 647 BaseHeap* m_heaps[BlinkGC::NumberOfHeaps]; | 642 BaseArena* m_arenas[BlinkGC::NumberOfArenas]; |
| 648 int m_vectorBackingHeapIndex; | 643 int m_vectorBackingArenaIndex; |
| 649 size_t m_heapAges[BlinkGC::NumberOfHeaps]; | 644 size_t m_arenaAges[BlinkGC::NumberOfArenas]; |
| 650 size_t m_currentHeapAges; | 645 size_t m_currentHeapAges; |
| 651 | 646 |
| 652 bool m_isTerminating; | 647 bool m_isTerminating; |
| 653 GarbageCollectedMixinConstructorMarker* m_gcMixinMarker; | 648 GarbageCollectedMixinConstructorMarker* m_gcMixinMarker; |
| 654 | 649 |
| 655 bool m_shouldFlushHeapDoesNotContainCache; | 650 bool m_shouldFlushHeapDoesNotContainCache; |
| 656 GCState m_gcState; | 651 GCState m_gcState; |
| 657 | 652 |
| 658 CallbackStack* m_threadLocalWeakCallbackStack; | 653 CallbackStack* m_threadLocalWeakCallbackStack; |
| 659 | 654 |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 707 | 702 |
| 708 template<> class ThreadStateFor<AnyThread> { | 703 template<> class ThreadStateFor<AnyThread> { |
| 709 STATIC_ONLY(ThreadStateFor); | 704 STATIC_ONLY(ThreadStateFor); |
| 710 public: | 705 public: |
| 711 static ThreadState* state() { return ThreadState::current(); } | 706 static ThreadState* state() { return ThreadState::current(); } |
| 712 }; | 707 }; |
| 713 | 708 |
| 714 } // namespace blink | 709 } // namespace blink |
| 715 | 710 |
| 716 #endif // ThreadState_h | 711 #endif // ThreadState_h |
| OLD | NEW |