| 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 251 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 262 barrier->doEnterSafePoint(state, stackEnd); | 262 barrier->doEnterSafePoint(state, stackEnd); |
| 263 } | 263 } |
| 264 | 264 |
| 265 volatile int m_canResume; | 265 volatile int m_canResume; |
| 266 volatile int m_unparkedThreadCount; | 266 volatile int m_unparkedThreadCount; |
| 267 Mutex m_mutex; | 267 Mutex m_mutex; |
| 268 ThreadCondition m_parked; | 268 ThreadCondition m_parked; |
| 269 ThreadCondition m_resume; | 269 ThreadCondition m_resume; |
| 270 }; | 270 }; |
| 271 | 271 |
| 272 BaseHeapPage::BaseHeapPage(PageMemory* storage, const GCInfo* gcInfo, ThreadStat
e* state) | |
| 273 : m_storage(storage) | |
| 274 , m_gcInfo(gcInfo) | |
| 275 , m_threadState(state) | |
| 276 , m_terminating(false) | |
| 277 , m_tracedAfterOrphaned(false) | |
| 278 { | |
| 279 ASSERT(isPageHeaderAddress(reinterpret_cast<Address>(this))); | |
| 280 } | |
| 281 | |
| 282 // Statically unfold the heap initialization loop so the compiler statically | 272 // Statically unfold the heap initialization loop so the compiler statically |
| 283 // knows the heap index when using HeapIndexTrait. | 273 // knows the heap index when using HeapIndexTrait. |
| 284 template<int num> struct InitializeHeaps { | 274 template<int num> struct InitializeHeaps { |
| 285 static const int index = num - 1; | 275 static const int index = num - 1; |
| 286 static void init(BaseHeap** heaps, ThreadState* state) | 276 static void init(BaseHeap** heaps, ThreadState* state) |
| 287 { | 277 { |
| 288 InitializeHeaps<index>::init(heaps, state); | 278 InitializeHeaps<index>::init(heaps, state); |
| 289 heaps[index] = new typename HeapIndexTrait<index>::HeapType(state, index
); | 279 heaps[index] = new typename HeapIndexTrait<index>::HeapType(state, index
); |
| 290 } | 280 } |
| 291 }; | 281 }; |
| (...skipping 11 matching lines...) Expand all Loading... |
| 303 , m_endOfStack(reinterpret_cast<intptr_t*>(getStackStart())) | 293 , m_endOfStack(reinterpret_cast<intptr_t*>(getStackStart())) |
| 304 , m_safePointScopeMarker(0) | 294 , m_safePointScopeMarker(0) |
| 305 , m_atSafePoint(false) | 295 , m_atSafePoint(false) |
| 306 , m_interruptors() | 296 , m_interruptors() |
| 307 , m_gcRequested(false) | 297 , m_gcRequested(false) |
| 308 , m_forcePreciseGCForTesting(false) | 298 , m_forcePreciseGCForTesting(false) |
| 309 , m_sweepRequested(0) | 299 , m_sweepRequested(0) |
| 310 , m_sweepInProgress(false) | 300 , m_sweepInProgress(false) |
| 311 , m_noAllocationCount(0) | 301 , m_noAllocationCount(0) |
| 312 , m_inGC(false) | 302 , m_inGC(false) |
| 313 , m_heapContainsCache(adoptPtr(new HeapContainsCache())) | |
| 314 , m_isTerminating(false) | 303 , m_isTerminating(false) |
| 315 , m_lowCollectionRate(false) | 304 , m_lowCollectionRate(false) |
| 316 , m_numberOfSweeperTasks(0) | 305 , m_numberOfSweeperTasks(0) |
| 317 #if defined(ADDRESS_SANITIZER) | 306 #if defined(ADDRESS_SANITIZER) |
| 318 , m_asanFakeStack(__asan_get_current_fake_stack()) | 307 , m_asanFakeStack(__asan_get_current_fake_stack()) |
| 319 #endif | 308 #endif |
| 320 { | 309 { |
| 321 ASSERT(!**s_threadSpecific); | 310 ASSERT(!**s_threadSpecific); |
| 322 **s_threadSpecific = this; | 311 **s_threadSpecific = this; |
| 323 | 312 |
| (...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 574 visitAsanFakeStackForPointer(visitor, ptr); | 563 visitAsanFakeStackForPointer(visitor, ptr); |
| 575 } | 564 } |
| 576 } | 565 } |
| 577 | 566 |
| 578 void ThreadState::visitPersistents(Visitor* visitor) | 567 void ThreadState::visitPersistents(Visitor* visitor) |
| 579 { | 568 { |
| 580 m_persistents->trace(visitor); | 569 m_persistents->trace(visitor); |
| 581 WrapperPersistentRegion::trace(m_liveWrapperPersistents, visitor); | 570 WrapperPersistentRegion::trace(m_liveWrapperPersistents, visitor); |
| 582 } | 571 } |
| 583 | 572 |
| 584 bool ThreadState::checkAndMarkPointer(Visitor* visitor, Address address) | |
| 585 { | |
| 586 // If thread is terminating ignore conservative pointers. | |
| 587 if (m_isTerminating) | |
| 588 return false; | |
| 589 | |
| 590 // This checks for normal pages and for large objects which span the extent | |
| 591 // of several normal pages. | |
| 592 BaseHeapPage* page = heapPageFromAddress(address); | |
| 593 if (page) { | |
| 594 page->checkAndMarkPointer(visitor, address); | |
| 595 // Whether or not the pointer was within an object it was certainly | |
| 596 // within a page that is part of the heap, so we don't want to ask the | |
| 597 // other other heaps or put this address in the | |
| 598 // HeapDoesNotContainCache. | |
| 599 return true; | |
| 600 } | |
| 601 | |
| 602 return false; | |
| 603 } | |
| 604 | |
| 605 #if ENABLE(GC_PROFILE_MARKING) | 573 #if ENABLE(GC_PROFILE_MARKING) |
| 606 const GCInfo* ThreadState::findGCInfo(Address address) | 574 const GCInfo* ThreadState::findGCInfo(Address address) |
| 607 { | 575 { |
| 608 BaseHeapPage* page = heapPageFromAddress(address); | 576 BaseHeapPage* page = heapPageFromAddress(address); |
| 609 if (page) { | 577 if (page) { |
| 610 return page->findGCInfo(address); | 578 return page->findGCInfo(address); |
| 611 } | 579 } |
| 612 return 0; | 580 return 0; |
| 613 } | 581 } |
| 614 #endif | 582 #endif |
| (...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 863 bool ThreadState::isConsistentForSweeping() | 831 bool ThreadState::isConsistentForSweeping() |
| 864 { | 832 { |
| 865 for (int i = 0; i < NumberOfHeaps; i++) { | 833 for (int i = 0; i < NumberOfHeaps; i++) { |
| 866 if (!m_heaps[i]->isConsistentForSweeping()) | 834 if (!m_heaps[i]->isConsistentForSweeping()) |
| 867 return false; | 835 return false; |
| 868 } | 836 } |
| 869 return true; | 837 return true; |
| 870 } | 838 } |
| 871 #endif | 839 #endif |
| 872 | 840 |
| 841 void ThreadState::prepareRegionTree() |
| 842 { |
| 843 // Add the regions allocated by this thread to the region search tree. |
| 844 for (size_t i = 0; i < m_allocatedRegionsSinceLastGC.size(); ++i) |
| 845 Heap::addPageMemoryRegion(m_allocatedRegionsSinceLastGC[i]); |
| 846 m_allocatedRegionsSinceLastGC.clear(); |
| 847 } |
| 848 |
| 873 void ThreadState::prepareForGC() | 849 void ThreadState::prepareForGC() |
| 874 { | 850 { |
| 875 for (int i = 0; i < NumberOfHeaps; i++) { | 851 for (int i = 0; i < NumberOfHeaps; i++) { |
| 876 BaseHeap* heap = m_heaps[i]; | 852 BaseHeap* heap = m_heaps[i]; |
| 877 heap->makeConsistentForSweeping(); | 853 heap->makeConsistentForSweeping(); |
| 878 // If a new GC is requested before this thread got around to sweep, ie.
due to the | 854 // If a new GC is requested before this thread got around to sweep, ie.
due to the |
| 879 // thread doing a long running operation, we clear the mark bits and mar
k any of | 855 // thread doing a long running operation, we clear the mark bits and mar
k any of |
| 880 // the dead objects as dead. The latter is used to ensure the next GC ma
rking does | 856 // the dead objects as dead. The latter is used to ensure the next GC ma
rking does |
| 881 // not trace already dead objects. If we trace a dead object we could en
d up tracing | 857 // not trace already dead objects. If we trace a dead object we could en
d up tracing |
| 882 // into garbage or the middle of another object via the newly conservati
vely found | 858 // into garbage or the middle of another object via the newly conservati
vely found |
| 883 // object. | 859 // object. |
| 884 if (sweepRequested()) | 860 if (sweepRequested()) |
| 885 heap->clearLiveAndMarkDead(); | 861 heap->clearLiveAndMarkDead(); |
| 886 } | 862 } |
| 863 prepareRegionTree(); |
| 887 setSweepRequested(); | 864 setSweepRequested(); |
| 888 } | 865 } |
| 889 | 866 |
| 890 void ThreadState::setupHeapsForTermination() | 867 void ThreadState::setupHeapsForTermination() |
| 891 { | 868 { |
| 892 for (int i = 0; i < NumberOfHeaps; i++) | 869 for (int i = 0; i < NumberOfHeaps; i++) |
| 893 m_heaps[i]->prepareHeapForTermination(); | 870 m_heaps[i]->prepareHeapForTermination(); |
| 894 } | 871 } |
| 895 | 872 |
| 896 BaseHeapPage* ThreadState::heapPageFromAddress(Address address) | 873 BaseHeapPage* ThreadState::heapPageFromAddress(Address address) |
| 897 { | 874 { |
| 898 BaseHeapPage* cachedPage = heapContainsCache()->lookup(address); | |
| 899 #if !ENABLE(ASSERT) | |
| 900 if (cachedPage) | |
| 901 return cachedPage; | |
| 902 #endif | |
| 903 | |
| 904 for (int i = 0; i < NumberOfHeaps; i++) { | 875 for (int i = 0; i < NumberOfHeaps; i++) { |
| 905 BaseHeapPage* page = m_heaps[i]->heapPageFromAddress(address); | 876 if (BaseHeapPage* page = m_heaps[i]->heapPageFromAddress(address)) |
| 906 if (page) { | |
| 907 // Asserts that make sure heapPageFromAddress takes addresses from | |
| 908 // the whole aligned blinkPageSize memory area. This is necessary | |
| 909 // for the negative cache to work. | |
| 910 ASSERT(page->isLargeObject() || page == m_heaps[i]->heapPageFromAddr
ess(roundToBlinkPageStart(address))); | |
| 911 if (roundToBlinkPageStart(address) != roundToBlinkPageEnd(address)) | |
| 912 ASSERT(page->isLargeObject() || page == m_heaps[i]->heapPageFrom
Address(roundToBlinkPageEnd(address) - 1)); | |
| 913 ASSERT(!cachedPage || page == cachedPage); | |
| 914 if (!cachedPage) | |
| 915 heapContainsCache()->addEntry(address, page); | |
| 916 return page; | 877 return page; |
| 917 } | |
| 918 } | 878 } |
| 919 ASSERT(!cachedPage); | |
| 920 return 0; | 879 return 0; |
| 921 } | 880 } |
| 922 | 881 |
| 923 void ThreadState::getStats(HeapStats& stats) | 882 void ThreadState::getStats(HeapStats& stats) |
| 924 { | 883 { |
| 925 stats = m_stats; | 884 stats = m_stats; |
| 926 #if ENABLE(ASSERT) | 885 #if ENABLE(ASSERT) |
| 927 if (isConsistentForSweeping()) { | 886 if (isConsistentForSweeping()) { |
| 928 HeapStats scannedStats; | 887 HeapStats scannedStats; |
| 929 for (int i = 0; i < NumberOfHeaps; i++) | 888 for (int i = 0; i < NumberOfHeaps; i++) |
| (...skipping 332 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1262 return gcInfo; | 1221 return gcInfo; |
| 1263 } | 1222 } |
| 1264 } | 1223 } |
| 1265 if (needLockForIteration) | 1224 if (needLockForIteration) |
| 1266 threadAttachMutex().unlock(); | 1225 threadAttachMutex().unlock(); |
| 1267 return 0; | 1226 return 0; |
| 1268 } | 1227 } |
| 1269 #endif | 1228 #endif |
| 1270 | 1229 |
| 1271 } | 1230 } |
| OLD | NEW |