Changeset 276324 in webkit
- Timestamp:
- Apr 20, 2021, 3:42:05 PM (5 years ago)
- Location:
- trunk/Source
- Files:
-
- 13 edited
-
JavaScriptCore/ChangeLog (modified) (1 diff)
-
JavaScriptCore/heap/BlockDirectory.cpp (modified) (2 diffs)
-
JavaScriptCore/heap/BlockDirectory.h (modified) (2 diffs)
-
JavaScriptCore/heap/FullGCActivityCallback.cpp (modified) (2 diffs)
-
JavaScriptCore/heap/Heap.cpp (modified) (1 diff)
-
JavaScriptCore/heap/Heap.h (modified) (1 diff)
-
JavaScriptCore/heap/MarkedSpace.cpp (modified) (2 diffs)
-
JavaScriptCore/heap/MarkedSpace.h (modified) (1 diff)
-
JavaScriptCore/runtime/OptionsList.h (modified) (1 diff)
-
WTF/ChangeLog (modified) (1 diff)
-
WTF/wtf/FunctionTraits.h (modified) (1 diff)
-
WebKit/ChangeLog (modified) (1 diff)
-
WebKit/WebProcess/com.apple.WebProcess.sb.in (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r276316 r276324 1 2021-04-20 Keith Miller <keith_miller@apple.com> 2 3 FullGCActivityCallback should use the percentage of pages uncompressed in RAM to determine deferral. 4 https://bugs.webkit.org/show_bug.cgi?id=224817 5 6 Reviewed by Filip Pizlo. 7 8 Right now we try to determine if too many pages are paged out by 9 dereferencing them and bailing out of the GC if we go over a 10 deadline. While this works if the only goal is to avoid causing 11 extensive thrashing on spinny disks (HDD), it doesn't prevent 12 thrashing when access to disk is fast (e.g. SSD). This is because 13 on fast disks the proportional time to load the memory from disk 14 is much lower. Additionally, on SSDs in particular we don't want 15 to load the pages into RAM then bail as that will force a 16 different page onto disk, increasing wear. 17 18 This patch switches to asking the OS if each MarkedBlock is paged 19 out. Then if we are over a threshold we wait until we would have 20 GC'd anyway. This patch uses the (maxVMGrowthFactor - 1) as the 21 percentage of "slow" pages (paged out or compressed) needed to 22 defer the GC. The idea behind that threshold is that if we add 23 that many pages then the same number of pages would be forced 24 out of RAM for us to do a GC anyway (in the limit). 25 26 * heap/BlockDirectory.cpp: 27 (JSC::BlockDirectory::updatePercentageOfPagedOutPages): 28 (JSC::BlockDirectory::isPagedOut): Deleted. 29 * heap/BlockDirectory.h: 30 * heap/FullGCActivityCallback.cpp: 31 (JSC::FullGCActivityCallback::doCollection): 32 * heap/Heap.cpp: 33 (JSC::Heap::isPagedOut): 34 * heap/Heap.h: 35 * heap/MarkedSpace.cpp: 36 (JSC::MarkedSpace::isPagedOut): 37 * heap/MarkedSpace.h: 38 * runtime/OptionsList.h: 39 1 40 2021-04-20 Don Olmstead <don.olmstead@sony.com> 2 41 -
trunk/Source/JavaScriptCore/heap/BlockDirectory.cpp
r276155 r276324 32 32 #include "SuperSampler.h" 33 33 34 #include <wtf/FunctionTraits.h> 35 #include <wtf/SimpleStats.h> 36 34 37 namespace JSC { 35 38 … … 54 57 } 55 58 56 bool BlockDirectory::isPagedOut(MonotonicTime deadline) 57 { 58 unsigned itersSinceLastTimeCheck = 0; 59 for (auto* block : m_blocks) { 60 if (block) 61 block->block().populatePage(); 62 ++itersSinceLastTimeCheck; 63 if (itersSinceLastTimeCheck >= Heap::s_timeCheckResolution) { 64 MonotonicTime currentTime = MonotonicTime::now(); 65 if (currentTime > deadline) 66 return true; 67 itersSinceLastTimeCheck = 0; 68 } 69 } 70 return false; 59 void BlockDirectory::updatePercentageOfPagedOutPages(SimpleStats& stats) 60 { 61 // FIXME: We should figure out a solution for Windows. 62 #if OS(UNIX) 63 size_t pageSize = WTF::pageSize(); 64 ASSERT(!(MarkedBlock::blockSize % pageSize)); 65 auto numberOfPagesInMarkedBlock = MarkedBlock::blockSize / pageSize; 66 // For some reason this can be unsigned char or char on different OSes... 67 using MincoreBufferType = std::remove_pointer_t<FunctionTraits<decltype(mincore)>::ArgumentType<2>>; 68 static_assert(std::is_same_v<std::make_unsigned_t<MincoreBufferType>, unsigned char>); 69 // pageSize is effectively a constant so this isn't really variable. 70 IGNORE_CLANG_WARNINGS_BEGIN("vla") 71 MincoreBufferType pagedBits[numberOfPagesInMarkedBlock]; 72 IGNORE_CLANG_WARNINGS_END 73 74 for (auto* handle : m_blocks) { 75 if (!handle) 76 continue; 77 78 auto markedBlockSizeInBytes = static_cast<size_t>(reinterpret_cast<char*>(handle->end()) - reinterpret_cast<char*>(handle->start())); 79 RELEASE_ASSERT(markedBlockSizeInBytes / pageSize <= numberOfPagesInMarkedBlock); 80 // We could cache this in bulk (e.g. 25 MB chunks) but we haven't seen any data that it actually matters. 81 auto result = mincore(handle->start(), markedBlockSizeInBytes, pagedBits); 82 RELEASE_ASSERT(!result); 83 constexpr unsigned pageIsResidentAndNotCompressed = 1; 84 for (unsigned i = 0; i < numberOfPagesInMarkedBlock; ++i) 85 stats.add(!(pagedBits[i] & pageIsResidentAndNotCompressed)); 86 } 87 #endif 71 88 } 72 89 -
trunk/Source/JavaScriptCore/heap/BlockDirectory.h
r276155 r276324 37 37 #include <wtf/SharedTask.h> 38 38 #include <wtf/Vector.h> 39 40 namespace WTF { 41 class SimpleStats; 42 } 39 43 40 44 namespace JSC { … … 88 92 void removeBlock(MarkedBlock::Handle*, WillDeleteBlock = WillDeleteBlock::No); 89 93 90 bool isPagedOut(MonotonicTime deadline);94 void updatePercentageOfPagedOutPages(WTF::SimpleStats&); 91 95 92 96 Lock& bitvectorLock() { return m_bitvectorLock; } -
trunk/Source/JavaScriptCore/heap/FullGCActivityCallback.cpp
r237266 r276324 31 31 namespace JSC { 32 32 33 #if !PLATFORM(IOS_FAMILY)34 const constexpr Seconds pagingTimeOut { 100_ms }; // Time in seconds to allow opportunistic timer to iterate over all blocks to see if the Heap is paged out.35 #endif36 37 33 FullGCActivityCallback::FullGCActivityCallback(Heap* heap) 38 34 : GCActivityCallback(heap) … … 45 41 m_didGCRecently = false; 46 42 47 #if !PLATFORM(IOS_FAMILY) 43 #if !PLATFORM(IOS_FAMILY) || PLATFORM(MACCATALYST) 48 44 MonotonicTime startTime = MonotonicTime::now(); 49 if (heap.isPagedOut( startTime + pagingTimeOut)) {45 if (heap.isPagedOut()) { 50 46 cancel(); 51 heap.increaseLastFullGCLength( pagingTimeOut);47 heap.increaseLastFullGCLength(MonotonicTime::now() - startTime); 52 48 return; 53 49 } -
trunk/Source/JavaScriptCore/heap/Heap.cpp
r275648 r276324 356 356 } 357 357 358 bool Heap::isPagedOut( MonotonicTime deadline)359 { 360 return m_objectSpace.isPagedOut( deadline);358 bool Heap::isPagedOut() 359 { 360 return m_objectSpace.isPagedOut(); 361 361 } 362 362 -
trunk/Source/JavaScriptCore/heap/Heap.h
r275261 r276324 271 271 272 272 void didAllocate(size_t); 273 bool isPagedOut( MonotonicTime deadline);273 bool isPagedOut(); 274 274 275 275 const JITStubRoutineSet& jitStubRoutines() { return *m_jitStubRoutines; } -
trunk/Source/JavaScriptCore/heap/MarkedSpace.cpp
r276155 r276324 28 28 #include "MarkedSpaceInlines.h" 29 29 #include <wtf/ListDump.h> 30 #include <wtf/SimpleStats.h> 30 31 31 32 namespace JSC { … … 359 360 } 360 361 361 bool MarkedSpace::isPagedOut(MonotonicTime deadline) 362 { 363 bool result = false; 364 forEachDirectory( 365 [&] (BlockDirectory& directory) -> IterationStatus { 366 if (directory.isPagedOut(deadline)) { 367 result = true; 368 return IterationStatus::Done; 369 } 362 bool MarkedSpace::isPagedOut() 363 { 364 SimpleStats pagedOutPagesStats; 365 366 forEachDirectory( 367 [&] (BlockDirectory& directory) -> IterationStatus { 368 directory.updatePercentageOfPagedOutPages(pagedOutPagesStats); 370 369 return IterationStatus::Continue; 371 370 }); 372 371 // FIXME: Consider taking PreciseAllocations into account here. 373 return result; 372 double maxHeapGrowthFactor = VM::isInMiniMode() ? Options::miniVMHeapGrowthFactor() : Options::largeHeapGrowthFactor(); 373 double bailoutPercentage = Options::customFullGCCallbackBailThreshold() == -1.0 ? maxHeapGrowthFactor - 1 : Options::customFullGCCallbackBailThreshold(); 374 return pagedOutPagesStats.mean() > pagedOutPagesStats.count() * bailoutPercentage; 374 375 } 375 376 -
trunk/Source/JavaScriptCore/heap/MarkedSpace.h
r273138 r276324 149 149 size_t capacity(); 150 150 151 bool isPagedOut( MonotonicTime deadline);151 bool isPagedOut(); 152 152 153 153 HeapVersion markingVersion() const { return m_markingVersion; } -
trunk/Source/JavaScriptCore/runtime/OptionsList.h
r275670 r276324 205 205 v(Double, miniVMHeapGrowthFactor, 1.27, Normal, nullptr) \ 206 206 v(Double, criticalGCMemoryThreshold, 0.80, Normal, "percent memory in use the GC considers critical. The collector is much more aggressive above this threshold") \ 207 v(Double, customFullGCCallbackBailThreshold, -1.0, Normal, "percent of memory paged out before we bail out of timer based Full GCs. -1.0 means use (maxHeapGrowthFactor - 1)") \ 207 208 v(Double, minimumMutatorUtilization, 0, Normal, nullptr) \ 208 209 v(Double, maximumMutatorUtilization, 0.7, Normal, nullptr) \ -
trunk/Source/WTF/ChangeLog
r276305 r276324 1 2021-04-20 Keith Miller <keith_miller@apple.com> 2 3 FullGCActivityCallback should use the percentage of pages uncompressed in RAM to determine deferral. 4 https://bugs.webkit.org/show_bug.cgi?id=224817 5 6 Reviewed by Filip Pizlo. 7 8 Add a noexcept flavor of FunctionTraits. On Linux mincore (and probably other syscalls) are marked noexcept so the existing overloads don't work. 9 10 * wtf/FunctionTraits.h: 11 1 12 2021-04-20 Chris Dumez <cdumez@apple.com> 2 13 -
trunk/Source/WTF/wtf/FunctionTraits.h
r233504 r276324 81 81 }; 82 82 83 template<typename Result, typename... Args> 84 struct FunctionTraits<Result(Args...) noexcept> : public FunctionTraits<Result(Args...)> { 85 }; 86 87 template<typename Result, typename... Args> 88 struct FunctionTraits<Result(*)(Args...) noexcept> : public FunctionTraits<Result(Args...)> { 89 }; 90 83 91 } // namespace WTF 84 92 -
trunk/Source/WebKit/ChangeLog
r276320 r276324 1 2021-04-20 Keith Miller <keith_miller@apple.com> 2 3 FullGCActivityCallback should use the percentage of pages uncompressed in RAM to determine deferral. 4 https://bugs.webkit.org/show_bug.cgi?id=224817 5 6 Reviewed by Filip Pizlo. 7 8 Add mincore to the acceptable syscall list. 9 10 * WebProcess/com.apple.WebProcess.sb.in: 11 1 12 2021-04-20 Jiewen Tan <jiewen_tan@apple.com> 2 13 -
trunk/Source/WebKit/WebProcess/com.apple.WebProcess.sb.in
r275764 r276324 1777 1777 (syscall-number SYS_mprotect) 1778 1778 (syscall-number SYS_madvise) 1779 (syscall-number SYS_mincore) 1779 1780 (syscall-number SYS_fcntl) 1780 1781 (syscall-number SYS_select)
Note:
See TracChangeset
for help on using the changeset viewer.