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 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
88 #ifdef _WIN64 | 88 #ifdef _WIN64 |
89 return reinterpret_cast<void*>(__readgsqword(offsetof(NT_TIB64, StackBase)))
; | 89 return reinterpret_cast<void*>(__readgsqword(offsetof(NT_TIB64, StackBase)))
; |
90 #else | 90 #else |
91 return reinterpret_cast<void*>(__readfsdword(offsetof(NT_TIB, StackBase))); | 91 return reinterpret_cast<void*>(__readfsdword(offsetof(NT_TIB, StackBase))); |
92 #endif | 92 #endif |
93 #else | 93 #else |
94 #error Unsupported getStackStart on this platform. | 94 #error Unsupported getStackStart on this platform. |
95 #endif | 95 #endif |
96 } | 96 } |
97 | 97 |
98 // The maximum number of WrapperPersistentRegions to keep around in the | |
99 // m_pooledWrapperPersistentRegions pool. | |
100 static const size_t MaxPooledWrapperPersistentRegionCount = 2; | |
101 | 98 |
102 WTF::ThreadSpecific<ThreadState*>* ThreadState::s_threadSpecific = 0; | 99 WTF::ThreadSpecific<ThreadState*>* ThreadState::s_threadSpecific = 0; |
103 uint8_t ThreadState::s_mainThreadStateStorage[sizeof(ThreadState)]; | 100 uint8_t ThreadState::s_mainThreadStateStorage[sizeof(ThreadState)]; |
104 SafePointBarrier* ThreadState::s_safePointBarrier = 0; | 101 SafePointBarrier* ThreadState::s_safePointBarrier = 0; |
105 bool ThreadState::s_inGC = false; | 102 bool ThreadState::s_inGC = false; |
106 | 103 |
107 static Mutex& threadAttachMutex() | 104 static Mutex& threadAttachMutex() |
108 { | 105 { |
109 AtomicallyInitializedStatic(Mutex&, mutex = *new Mutex); | 106 AtomicallyInitializedStatic(Mutex&, mutex = *new Mutex); |
110 return mutex; | 107 return mutex; |
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
261 barrier->doEnterSafePoint(state, stackEnd); | 258 barrier->doEnterSafePoint(state, stackEnd); |
262 } | 259 } |
263 | 260 |
264 volatile int m_canResume; | 261 volatile int m_canResume; |
265 volatile int m_unparkedThreadCount; | 262 volatile int m_unparkedThreadCount; |
266 Mutex m_mutex; | 263 Mutex m_mutex; |
267 ThreadCondition m_parked; | 264 ThreadCondition m_parked; |
268 ThreadCondition m_resume; | 265 ThreadCondition m_resume; |
269 }; | 266 }; |
270 | 267 |
| 268 |
271 BaseHeapPage::BaseHeapPage(PageMemory* storage, const GCInfo* gcInfo, ThreadStat
e* state) | 269 BaseHeapPage::BaseHeapPage(PageMemory* storage, const GCInfo* gcInfo, ThreadStat
e* state) |
272 : m_storage(storage) | 270 : m_storage(storage) |
273 , m_gcInfo(gcInfo) | 271 , m_gcInfo(gcInfo) |
274 , m_threadState(state) | 272 , m_threadState(state) |
275 , m_terminating(false) | 273 , m_terminating(false) |
276 , m_tracedAfterOrphaned(false) | 274 , m_tracedAfterOrphaned(false) |
277 { | 275 { |
278 ASSERT(isPageHeaderAddress(reinterpret_cast<Address>(this))); | 276 ASSERT(isPageHeaderAddress(reinterpret_cast<Address>(this))); |
279 } | 277 } |
280 | 278 |
281 // Statically unfold the heap initialization loop so the compiler statically | 279 // Statically unfold the heap initialization loop so the compiler statically |
282 // knows the heap index when using HeapIndexTrait. | 280 // knows the heap index when using HeapIndexTrait. |
283 template<int num> struct InitializeHeaps { | 281 template<int num> struct InitializeHeaps { |
284 static const int index = num - 1; | 282 static const int index = num - 1; |
285 static void init(BaseHeap** heaps, ThreadState* state) | 283 static void init(BaseHeap** heaps, ThreadState* state) |
286 { | 284 { |
287 InitializeHeaps<index>::init(heaps, state); | 285 InitializeHeaps<index>::init(heaps, state); |
288 heaps[index] = new typename HeapIndexTrait<index>::HeapType(state, index
); | 286 heaps[index] = new typename HeapIndexTrait<index>::HeapType(state, index
); |
289 } | 287 } |
290 }; | 288 }; |
291 template<> struct InitializeHeaps<0> { | 289 template<> struct InitializeHeaps<0> { |
292 static void init(BaseHeap** heaps, ThreadState* state) { } | 290 static void init(BaseHeap** heaps, ThreadState* state) { } |
293 }; | 291 }; |
294 | 292 |
295 ThreadState::ThreadState() | 293 ThreadState::ThreadState() |
296 : m_thread(currentThread()) | 294 : m_thread(currentThread()) |
297 , m_liveWrapperPersistents(new WrapperPersistentRegion()) | |
298 , m_pooledWrapperPersistents(0) | |
299 , m_pooledWrapperPersistentRegionCount(0) | |
300 , m_persistents(adoptPtr(new PersistentAnchor())) | 295 , m_persistents(adoptPtr(new PersistentAnchor())) |
301 , m_startOfStack(reinterpret_cast<intptr_t*>(getStackStart())) | 296 , m_startOfStack(reinterpret_cast<intptr_t*>(getStackStart())) |
302 , m_endOfStack(reinterpret_cast<intptr_t*>(getStackStart())) | 297 , m_endOfStack(reinterpret_cast<intptr_t*>(getStackStart())) |
303 , m_safePointScopeMarker(0) | 298 , m_safePointScopeMarker(0) |
304 , m_atSafePoint(false) | 299 , m_atSafePoint(false) |
305 , m_interruptors() | 300 , m_interruptors() |
306 , m_gcRequested(false) | 301 , m_gcRequested(false) |
307 , m_forcePreciseGCForTesting(false) | 302 , m_forcePreciseGCForTesting(false) |
308 , m_sweepRequested(0) | 303 , m_sweepRequested(0) |
309 , m_sweepInProgress(false) | 304 , m_sweepInProgress(false) |
(...skipping 18 matching lines...) Expand all Loading... |
328 m_sweeperThread = adoptPtr(blink::Platform::current()->createThread("Bli
nk GC Sweeper")); | 323 m_sweeperThread = adoptPtr(blink::Platform::current()->createThread("Bli
nk GC Sweeper")); |
329 } | 324 } |
330 | 325 |
331 ThreadState::~ThreadState() | 326 ThreadState::~ThreadState() |
332 { | 327 { |
333 checkThread(); | 328 checkThread(); |
334 CallbackStack::shutdown(&m_weakCallbackStack); | 329 CallbackStack::shutdown(&m_weakCallbackStack); |
335 for (int i = 0; i < NumberOfHeaps; i++) | 330 for (int i = 0; i < NumberOfHeaps; i++) |
336 delete m_heaps[i]; | 331 delete m_heaps[i]; |
337 deleteAllValues(m_interruptors); | 332 deleteAllValues(m_interruptors); |
338 while (m_liveWrapperPersistents) { | |
339 WrapperPersistentRegion* region = WrapperPersistentRegion::removeHead(&m
_liveWrapperPersistents); | |
340 delete region; | |
341 } | |
342 while (m_pooledWrapperPersistents) { | |
343 WrapperPersistentRegion* region = WrapperPersistentRegion::removeHead(&m
_pooledWrapperPersistents); | |
344 delete region; | |
345 } | |
346 **s_threadSpecific = 0; | 333 **s_threadSpecific = 0; |
347 } | 334 } |
348 | 335 |
349 void ThreadState::init() | 336 void ThreadState::init() |
350 { | 337 { |
351 s_threadSpecific = new WTF::ThreadSpecific<ThreadState*>(); | 338 s_threadSpecific = new WTF::ThreadSpecific<ThreadState*>(); |
352 s_safePointBarrier = new SafePointBarrier; | 339 s_safePointBarrier = new SafePointBarrier; |
353 } | 340 } |
354 | 341 |
355 void ThreadState::shutdown() | 342 void ThreadState::shutdown() |
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
567 __msan_unpoison(&ptr, sizeof(ptr)); | 554 __msan_unpoison(&ptr, sizeof(ptr)); |
568 #endif | 555 #endif |
569 Heap::checkAndMarkPointer(visitor, ptr); | 556 Heap::checkAndMarkPointer(visitor, ptr); |
570 visitAsanFakeStackForPointer(visitor, ptr); | 557 visitAsanFakeStackForPointer(visitor, ptr); |
571 } | 558 } |
572 } | 559 } |
573 | 560 |
574 void ThreadState::visitPersistents(Visitor* visitor) | 561 void ThreadState::visitPersistents(Visitor* visitor) |
575 { | 562 { |
576 m_persistents->trace(visitor); | 563 m_persistents->trace(visitor); |
577 WrapperPersistentRegion::trace(m_liveWrapperPersistents, visitor); | |
578 } | 564 } |
579 | 565 |
580 bool ThreadState::checkAndMarkPointer(Visitor* visitor, Address address) | 566 bool ThreadState::checkAndMarkPointer(Visitor* visitor, Address address) |
581 { | 567 { |
582 // If thread is terminating ignore conservative pointers. | 568 // If thread is terminating ignore conservative pointers. |
583 if (m_isTerminating) | 569 if (m_isTerminating) |
584 return false; | 570 return false; |
585 | 571 |
586 // This checks for normal pages and for large objects which span the extent | 572 // This checks for normal pages and for large objects which span the extent |
587 // of several normal pages. | 573 // of several normal pages. |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
687 { | 673 { |
688 CallbackStack::Item* slot = m_weakCallbackStack->allocateEntry(&m_weakCallba
ckStack); | 674 CallbackStack::Item* slot = m_weakCallbackStack->allocateEntry(&m_weakCallba
ckStack); |
689 *slot = CallbackStack::Item(object, callback); | 675 *slot = CallbackStack::Item(object, callback); |
690 } | 676 } |
691 | 677 |
692 bool ThreadState::popAndInvokeWeakPointerCallback(Visitor* visitor) | 678 bool ThreadState::popAndInvokeWeakPointerCallback(Visitor* visitor) |
693 { | 679 { |
694 return m_weakCallbackStack->popAndInvokeCallback<WeaknessProcessing>(&m_weak
CallbackStack, visitor); | 680 return m_weakCallbackStack->popAndInvokeCallback<WeaknessProcessing>(&m_weak
CallbackStack, visitor); |
695 } | 681 } |
696 | 682 |
697 WrapperPersistentRegion* ThreadState::takeWrapperPersistentRegion() | |
698 { | |
699 WrapperPersistentRegion* region; | |
700 if (m_pooledWrapperPersistentRegionCount) { | |
701 region = WrapperPersistentRegion::removeHead(&m_pooledWrapperPersistents
); | |
702 m_pooledWrapperPersistentRegionCount--; | |
703 } else { | |
704 region = new WrapperPersistentRegion(); | |
705 } | |
706 ASSERT(region); | |
707 WrapperPersistentRegion::insertHead(&m_liveWrapperPersistents, region); | |
708 return region; | |
709 } | |
710 | |
711 void ThreadState::freeWrapperPersistentRegion(WrapperPersistentRegion* region) | |
712 { | |
713 if (!region->removeIfNotLast(&m_liveWrapperPersistents)) | |
714 return; | |
715 | |
716 // Region was removed, ie. it was not the last region in the list. | |
717 if (m_pooledWrapperPersistentRegionCount < MaxPooledWrapperPersistentRegionC
ount) { | |
718 WrapperPersistentRegion::insertHead(&m_pooledWrapperPersistents, region)
; | |
719 m_pooledWrapperPersistentRegionCount++; | |
720 } else { | |
721 delete region; | |
722 } | |
723 } | |
724 | |
725 PersistentNode* ThreadState::globalRoots() | 683 PersistentNode* ThreadState::globalRoots() |
726 { | 684 { |
727 AtomicallyInitializedStatic(PersistentNode*, anchor = new PersistentAnchor); | 685 AtomicallyInitializedStatic(PersistentNode*, anchor = new PersistentAnchor); |
728 return anchor; | 686 return anchor; |
729 } | 687 } |
730 | 688 |
731 Mutex& ThreadState::globalRootsMutex() | 689 Mutex& ThreadState::globalRootsMutex() |
732 { | 690 { |
733 AtomicallyInitializedStatic(Mutex&, mutex = *new Mutex); | 691 AtomicallyInitializedStatic(Mutex&, mutex = *new Mutex); |
734 return mutex; | 692 return mutex; |
(...skipping 505 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1240 return gcInfo; | 1198 return gcInfo; |
1241 } | 1199 } |
1242 } | 1200 } |
1243 if (needLockForIteration) | 1201 if (needLockForIteration) |
1244 threadAttachMutex().unlock(); | 1202 threadAttachMutex().unlock(); |
1245 return 0; | 1203 return 0; |
1246 } | 1204 } |
1247 #endif | 1205 #endif |
1248 | 1206 |
1249 } | 1207 } |
OLD | NEW |