Changeset 277027 in webkit
- Timestamp:
- May 5, 2021, 10:28:13 AM (4 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 10 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/CMakeLists.txt
r276676 r277027 673 673 heap/IsoSubspaceInlines.h 674 674 heap/IsoSubspacePerVM.h 675 heap/JITStubRoutineSet.h 675 676 heap/LocalAllocator.h 676 677 heap/LocalAllocatorInlines.h -
trunk/Source/JavaScriptCore/ChangeLog
r276942 r277027 1 2021-05-05 Mark Lam <mark.lam@apple.com> 2 3 Enable incremental sweeping of GCAwareJITStubRoutines. 4 https://bugs.webkit.org/show_bug.cgi?id=225376 5 6 Reviewed by Filip Pizlo. 7 8 This patch makes the following changes: 9 10 1. Enhance JITStubRoutineSet::deleteUnmarkedJettisonedStubRoutines() to be able to 11 run in an incremental time slice. 12 13 2. Added JITStubRoutineSet::notifyHaveRoutinesToDelete() so that 14 GCAwareJITStubRoutine::observeZeroRefCount() can flag that the GC may have 15 some dead GCAwareJITStubRoutines to delete. 16 17 3. Added JITStubRoutineSet::mayHaveRoutinesToDelete() so that clients can do 18 a cheap check ahead of time to determine if there's work to do, and avoid 19 calling JITStubRoutineSet::deleteUnmarkedJettisonedStubRoutines() altogether 20 if not needed. 21 22 4. Added Heap::mayHaveJITStubRoutinesToDelete() and Heap::deleteDeadJITStubRoutines() 23 as wrappers around JITStubRoutineSet::mayHaveRoutinesToDelete() and 24 JITStubRoutineSet::deleteUnmarkedJettisonedStubRoutines() because the use of 25 the JITStubRoutineSet is a heap internal implementation detail. 26 27 5. Enhanced the IncrementalSweeper to also call Heap::deleteDeadJITStubRoutines() 28 if needed. 29 30 6. Enhanced Heap::sweepSynchronously() to also call Heap::deleteDeadJITStubRoutines() 31 if needed. 32 33 7. Time slices for Heap::deleteDeadJITStubRoutines() is currently set at the 34 current values: 35 a. max of 1 ms (1/10 of the IncreamentalSweeper's time slice) when invoked from 36 the IncreamentalSweeper. 37 b. max of 5 ms when invoked from Heap::deleteUnmarkedCompiledCode(). 38 c. unlimited time (with a sanity check) when called from Heap::sweepSynchronously(). 39 40 The choices of 1ms and 5ms were picked to not be too long, but would still delete 41 the bulk of the dead GCAwareJITStubRoutines quickly enough based on data from my 42 instrumented runs the CLI version of JetStream2. 43 44 I think these hardcoded values will do for now. If need be, we can try something 45 more sophisticated later. 46 47 * CMakeLists.txt: 48 * heap/Heap.cpp: 49 (JSC::Heap::deleteUnmarkedCompiledCode): 50 (JSC::Heap::sweepSynchronously): 51 * heap/Heap.h: 52 * heap/HeapInlines.h: 53 (JSC::Heap::mayHaveJITStubRoutinesToDelete): 54 (JSC::Heap::deleteDeadJITStubRoutines): 55 * heap/IncrementalSweeper.cpp: 56 (JSC::IncrementalSweeper::doSweep): 57 * heap/JITStubRoutineSet.cpp: 58 (JSC::JITStubRoutineSet::deleteUnmarkedJettisonedStubRoutines): 59 * heap/JITStubRoutineSet.h: 60 (JSC::JITStubRoutineSet::mayHaveRoutinesToDelete): 61 (JSC::JITStubRoutineSet::notifyHaveRoutinesToDelete): 62 (JSC::JITStubRoutineSet::deleteUnmarkedJettisonedStubRoutines): 63 * jit/GCAwareJITStubRoutine.cpp: 64 (JSC::GCAwareJITStubRoutine::observeZeroRefCount): 65 * jit/JITStubRoutine.h: 66 (JSC::JITStubRoutine::createSelfManagedRoutine): Deleted. 67 1 68 2021-05-03 Mark Lam <mark.lam@apple.com> 2 69 -
trunk/Source/JavaScriptCore/heap/Heap.cpp
r276324 r277027 974 974 // And CodeBlock destructor is assuming that CodeBlock gets destroyed before UnlinkedCodeBlock gets destroyed. 975 975 vm().forEachCodeBlockSpace([] (auto& space) { space.space.sweep(); }); 976 m_jitStubRoutines->deleteUnmarkedJettisonedStubRoutines(); 976 if (mayHaveJITStubRoutinesToDelete()) 977 deleteDeadJITStubRoutines(5_ms); 977 978 } 978 979 … … 1041 1042 m_objectSpace.sweepBlocks(); 1042 1043 m_objectSpace.shrink(); 1044 1045 unsigned passes = 0; 1046 while (mayHaveJITStubRoutinesToDelete()) { 1047 constexpr Seconds unlimitedTime = 600_s; 1048 deleteDeadJITStubRoutines(unlimitedTime); 1049 RELEASE_ASSERT(passes++ < 100); 1050 } 1051 1043 1052 if (UNLIKELY(Options::logGC())) { 1044 1053 MonotonicTime after = MonotonicTime::now(); -
trunk/Source/JavaScriptCore/heap/Heap.h
r276324 r277027 407 407 bool isMarkingForGCVerifier() const { return m_isMarkingForGCVerifier; } 408 408 409 static bool mayHaveJITStubRoutinesToDelete(); 410 void deleteDeadJITStubRoutines(Seconds timeSlice); 411 409 412 private: 410 413 friend class AllocatingScope; -
trunk/Source/JavaScriptCore/heap/HeapInlines.h
r273138 r277027 30 30 #include "HeapCellInlines.h" 31 31 #include "IndexingHeader.h" 32 #include "JITStubRoutineSet.h" 32 33 #include "JSCast.h" 33 34 #include "Structure.h" … … 280 281 } 281 282 283 inline bool Heap::mayHaveJITStubRoutinesToDelete() 284 { 285 return JITStubRoutineSet::mayHaveRoutinesToDelete(); 286 } 287 288 inline void Heap::deleteDeadJITStubRoutines(Seconds timeSlice) 289 { 290 m_jitStubRoutines->deleteUnmarkedJettisonedStubRoutines(timeSlice); 291 } 292 282 293 } // namespace JSC -
trunk/Source/JavaScriptCore/heap/IncrementalSweeper.cpp
r261895 r277027 37 37 static constexpr double sweepTimeTotal = .10; 38 38 static constexpr double sweepTimeMultiplier = 1.0 / sweepTimeTotal; 39 static constexpr Seconds deleteJITStubRoutinesTimeSlice = std::min(sweepTimeSlice / 10, 1_ms); 39 40 40 41 void IncrementalSweeper::scheduleTimer() … … 56 57 void IncrementalSweeper::doSweep(VM& vm, MonotonicTime sweepBeginTime) 57 58 { 58 while (sweepNextBlock(vm)) { 59 bool hasMoreBlocksToSweep = true; 60 bool hasMoreWork = true; 61 while (hasMoreWork) { 62 if (hasMoreBlocksToSweep) 63 hasMoreBlocksToSweep = sweepNextBlock(vm); 64 65 if (Heap::mayHaveJITStubRoutinesToDelete()) 66 vm.heap.deleteDeadJITStubRoutines(deleteJITStubRoutinesTimeSlice); 67 68 hasMoreWork = hasMoreBlocksToSweep || Heap::mayHaveJITStubRoutinesToDelete(); 69 59 70 Seconds elapsedTime = MonotonicTime::now() - sweepBeginTime; 60 71 if (elapsedTime < sweepTimeSlice) -
trunk/Source/JavaScriptCore/heap/JITStubRoutineSet.cpp
r275490 r277027 30 30 31 31 #include "GCAwareJITStubRoutine.h" 32 #include <algorithm> 32 33 33 34 namespace JSC { 35 36 using WTF::Range; 37 38 bool JITStubRoutineSet::s_mayHaveRoutinesToDelete = false; 34 39 35 40 JITStubRoutineSet::JITStubRoutineSet() { } … … 114 119 } 115 120 116 void JITStubRoutineSet::deleteUnmarkedJettisonedStubRoutines( )121 void JITStubRoutineSet::deleteUnmarkedJettisonedStubRoutines(Seconds timeSlice) 117 122 { 123 ASSERT(s_mayHaveRoutinesToDelete); 124 125 MonotonicTime startTime = MonotonicTime::now(); 126 Seconds elapsedTime; 127 constexpr unsigned maxBatchSize = 100; 128 129 unsigned endIndex = m_routines.size(); 130 131 // Clear the s_mayHaveRoutinesToDelete flag before we start. 132 // Destruction of a MarkingGCAwareJITStubRoutine can trigger more routines 133 // to be deleted, and some of those may be the ones we have already iterated 134 // pass. 135 s_mayHaveRoutinesToDelete = false; 136 118 137 unsigned srcIndex = 0; 119 unsigned dstIndex = srcIndex; 120 while (srcIndex < m_routines.size()) { 121 Routine routine = m_routines[srcIndex++]; 122 if (!routine.routine->m_isJettisoned || routine.routine->m_mayBeExecuting) { 123 m_routines[dstIndex++] = routine; 124 continue; 138 while (srcIndex < endIndex) { 139 unsigned batchSize = std::min<unsigned>(maxBatchSize, endIndex - srcIndex); 140 while (batchSize--) { 141 Routine routine = m_routines[srcIndex]; 142 if (!routine.routine->m_isJettisoned || routine.routine->m_mayBeExecuting) { 143 srcIndex++; 144 continue; 145 } 146 m_routines[srcIndex] = m_routines[--endIndex]; 147 148 routine.routine->deleteFromGC(); 125 149 } 126 routine.routine->deleteFromGC(); 150 151 elapsedTime = MonotonicTime::now() - startTime; 152 if (elapsedTime > timeSlice) { 153 // We timed out. Assume there's more to do, and that we should check 154 // again next time slice. 155 s_mayHaveRoutinesToDelete = true; 156 break; 157 } 127 158 } 128 m_routines.shrinkCapacity(dstIndex); 159 160 m_routines.shrinkCapacity(endIndex); 129 161 } 130 162 -
trunk/Source/JavaScriptCore/heap/JITStubRoutineSet.h
r273138 r277027 32 32 #include <wtf/Vector.h> 33 33 34 using WTF::Range;35 36 34 namespace JSC { 37 35 … … 62 60 void prepareForConservativeScan(); 63 61 64 void deleteUnmarkedJettisonedStubRoutines( );62 void deleteUnmarkedJettisonedStubRoutines(Seconds timeSlice); 65 63 66 64 template<typename Visitor> void traceMarkedStubRoutines(Visitor&); 67 65 66 static bool mayHaveRoutinesToDelete() { return s_mayHaveRoutinesToDelete; } 67 static void notifyHaveRoutinesToDelete() { s_mayHaveRoutinesToDelete = true; } 68 68 69 private: 69 70 void markSlow(uintptr_t address); … … 74 75 }; 75 76 Vector<Routine> m_routines; 76 Range<uintptr_t> m_range { 0, 0 }; 77 WTF::Range<uintptr_t> m_range { 0, 0 }; 78 79 static bool s_mayHaveRoutinesToDelete; 77 80 }; 78 81 … … 91 94 void mark(void*) { } 92 95 void prepareForConservativeScan() { } 93 void deleteUnmarkedJettisonedStubRoutines( ) { }96 void deleteUnmarkedJettisonedStubRoutines(Seconds) { } 94 97 template<typename Visitor> void traceMarkedStubRoutines(Visitor&) { } 98 99 static bool mayHaveRoutinesToDelete() { return false; } 100 static void notifyHaveRoutinesToDelete() { } 95 101 }; 96 102 -
trunk/Source/JavaScriptCore/jit/GCAwareJITStubRoutine.cpp
r273138 r277027 63 63 64 64 m_isJettisoned = true; 65 JITStubRoutineSet::notifyHaveRoutinesToDelete(); 65 66 } 66 67 -
trunk/Source/JavaScriptCore/jit/JITStubRoutine.h
r230748 r277027 1 1 /* 2 * Copyright (C) 2012-20 18Apple Inc. All rights reserved.2 * Copyright (C) 2012-2021 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 54 54 , m_refCount(1) 55 55 { 56 }57 58 // Use this if you want to pass a CodePtr to someone who insists on taking59 // a RefPtr<JITStubRoutine>.60 static Ref<JITStubRoutine> createSelfManagedRoutine(61 MacroAssemblerCodePtr<JITStubRoutinePtrTag> rawCodePointer)62 {63 return adoptRef(*new JITStubRoutine(MacroAssemblerCodeRef<JITStubRoutinePtrTag>::createSelfManagedCodeRef(rawCodePointer)));64 56 } 65 57
Note:
See TracChangeset
for help on using the changeset viewer.