Changeset 207061 in webkit
- Timestamp:
- Oct 11, 2016 12:38:03 AM (8 years ago)
- Location:
- releases/WebKitGTK/webkit-2.14/Source
- Files:
-
- 13 edited
Legend:
- Unmodified
- Added
- Removed
-
releases/WebKitGTK/webkit-2.14/Source/JavaScriptCore/ChangeLog
r207059 r207061 1 2016-09-08 Filip Pizlo <fpizlo@apple.com> 2 3 Heap::isMarked() shouldn't pay the price of concurrent lazy flipping 4 https://bugs.webkit.org/show_bug.cgi?id=161760 5 6 Reviewed by Mark Lam. 7 8 To fix a race condition in marking, I made Heap::isMarked() and Heap::isLive() atomic by 9 using flipIfNecessaryConcurrently() instead of flipIfNecessary(). 10 11 This introduces three unnecessary overheads: 12 13 - isLive() is not called by marking, so that change was not necessary. 14 15 - isMarked() gets calls many times outside of marking, so it shouldn't always do the 16 concurrent thing. This adds isMarkedConcurrently() for use in marking, and reverts 17 isMarked(). 18 19 - isMarked() and isMarkedConcurrently() don't actually have to do the lazy flip. They can 20 return false if the flip is necessary. 21 22 I added a bunch of debug assertions to make sure that isLive() and isMarked() are not called 23 during marking. 24 25 If we needed to, we could remove most of the calls to isMarkedConcurrently(). As a kind of 26 optimization, CodeBlock does an initial fixpoint iteration during marking, and so all of the 27 code called from CodeBlock's fixpoint iterator needs to use isMarkedConcurrently(). But we 28 could probably arrange for CodeBlock only do fixpoint iterating during the weak reference 29 thing. 30 31 * bytecode/CodeBlock.cpp: 32 (JSC::CodeBlock::visitWeakly): 33 (JSC::CodeBlock::shouldJettisonDueToOldAge): 34 (JSC::shouldMarkTransition): 35 (JSC::CodeBlock::propagateTransitions): 36 (JSC::CodeBlock::determineLiveness): 37 * bytecode/PolymorphicAccess.cpp: 38 (JSC::AccessCase::propagateTransitions): 39 * heap/Heap.h: 40 * heap/HeapInlines.h: 41 (JSC::Heap::isLive): 42 (JSC::Heap::isMarked): 43 (JSC::Heap::isMarkedConcurrently): 44 * heap/MarkedBlock.cpp: 45 (JSC::MarkedBlock::flipIfNecessarySlow): 46 (JSC::MarkedBlock::flipIfNecessaryConcurrentlySlow): 47 (JSC::MarkedBlock::needsFlip): 48 * heap/MarkedBlock.h: 49 (JSC::MarkedBlock::needsFlip): 50 (JSC::MarkedBlock::flipIfNecessary): 51 (JSC::MarkedBlock::flipIfNecessaryConcurrently): 52 * heap/SlotVisitor.cpp: 53 (JSC::SlotVisitor::appendToMarkStack): 54 (JSC::SlotVisitor::markAuxiliary): 55 (JSC::SlotVisitor::visitChildren): 56 * runtime/Structure.cpp: 57 (JSC::Structure::isCheapDuringGC): 58 (JSC::Structure::markIfCheap): 59 1 60 2016-09-08 Saam Barati <sbarati@apple.com> 2 61 -
releases/WebKitGTK/webkit-2.14/Source/JavaScriptCore/bytecode/CodeBlock.cpp
r205717 r207061 2486 2486 return; 2487 2487 2488 if (Heap::isMarked (this))2488 if (Heap::isMarkedConcurrently(this)) 2489 2489 return; 2490 2490 … … 2629 2629 bool CodeBlock::shouldJettisonDueToOldAge() 2630 2630 { 2631 if (Heap::isMarked (this))2631 if (Heap::isMarkedConcurrently(this)) 2632 2632 return false; 2633 2633 … … 2644 2644 static bool shouldMarkTransition(DFG::WeakReferenceTransition& transition) 2645 2645 { 2646 if (transition.m_codeOrigin && !Heap::isMarked (transition.m_codeOrigin.get()))2646 if (transition.m_codeOrigin && !Heap::isMarkedConcurrently(transition.m_codeOrigin.get())) 2647 2647 return false; 2648 2648 2649 if (!Heap::isMarked (transition.m_from.get()))2649 if (!Heap::isMarkedConcurrently(transition.m_from.get())) 2650 2650 return false; 2651 2651 … … 2678 2678 Structure* newStructure = 2679 2679 m_vm->heap.structureIDTable().get(newStructureID); 2680 if (Heap::isMarked (oldStructure))2680 if (Heap::isMarkedConcurrently(oldStructure)) 2681 2681 visitor.appendUnbarrieredReadOnlyPointer(newStructure); 2682 2682 else … … 2750 2750 bool allAreLiveSoFar = true; 2751 2751 for (unsigned i = 0; i < dfgCommon->weakReferences.size(); ++i) { 2752 if (!Heap::isMarked (dfgCommon->weakReferences[i].get())) {2752 if (!Heap::isMarkedConcurrently(dfgCommon->weakReferences[i].get())) { 2753 2753 allAreLiveSoFar = false; 2754 2754 break; … … 2757 2757 if (allAreLiveSoFar) { 2758 2758 for (unsigned i = 0; i < dfgCommon->weakStructureReferences.size(); ++i) { 2759 if (!Heap::isMarked (dfgCommon->weakStructureReferences[i].get())) {2759 if (!Heap::isMarkedConcurrently(dfgCommon->weakStructureReferences[i].get())) { 2760 2760 allAreLiveSoFar = false; 2761 2761 break; -
releases/WebKitGTK/webkit-2.14/Source/JavaScriptCore/bytecode/PolymorphicAccess.cpp
r205717 r207061 556 556 switch (m_type) { 557 557 case Transition: 558 if (Heap::isMarked (m_structure->previousID()))558 if (Heap::isMarkedConcurrently(m_structure->previousID())) 559 559 visitor.appendUnbarrieredReadOnlyPointer(m_structure.get()); 560 560 else -
releases/WebKitGTK/webkit-2.14/Source/JavaScriptCore/heap/Heap.h
r207055 r207061 102 102 static bool isLive(const void*); 103 103 static bool isMarked(const void*); 104 static bool isMarkedConcurrently(const void*); 104 105 static bool testAndSetMarked(HeapVersion, const void*); 105 106 static void setMarked(const void*); -
releases/WebKitGTK/webkit-2.14/Source/JavaScriptCore/heap/HeapInlines.h
r207055 r207061 36 36 #include <type_traits> 37 37 #include <wtf/Assertions.h> 38 #include <wtf/MainThread.h> 38 39 #include <wtf/RandomNumber.h> 39 40 … … 77 78 inline bool Heap::isLive(const void* rawCell) 78 79 { 80 ASSERT(!mayBeGCThread()); 79 81 HeapCell* cell = bitwise_cast<HeapCell*>(rawCell); 80 82 if (cell->isLargeAllocation()) 81 83 return cell->largeAllocation().isLive(); 82 84 MarkedBlock& block = cell->markedBlock(); 83 block.flipIfNecessary Concurrently(block.vm()->heap.objectSpace().version());85 block.flipIfNecessary(block.vm()->heap.objectSpace().version()); 84 86 return block.handle().isLiveCell(cell); 85 87 } … … 87 89 ALWAYS_INLINE bool Heap::isMarked(const void* rawCell) 88 90 { 91 ASSERT(!mayBeGCThread()); 89 92 HeapCell* cell = bitwise_cast<HeapCell*>(rawCell); 90 93 if (cell->isLargeAllocation()) 91 94 return cell->largeAllocation().isMarked(); 92 95 MarkedBlock& block = cell->markedBlock(); 93 block.flipIfNecessaryConcurrently(block.vm()->heap.objectSpace().version()); 96 if (block.needsFlip(block.vm()->heap.objectSpace().version())) 97 return false; 98 return block.isMarked(cell); 99 } 100 101 ALWAYS_INLINE bool Heap::isMarkedConcurrently(const void* rawCell) 102 { 103 HeapCell* cell = bitwise_cast<HeapCell*>(rawCell); 104 if (cell->isLargeAllocation()) 105 return cell->largeAllocation().isMarked(); 106 MarkedBlock& block = cell->markedBlock(); 107 if (block.needsFlip(block.vm()->heap.objectSpace().version())) 108 return false; 109 WTF::loadLoadFence(); 94 110 return block.isMarked(cell); 95 111 } -
releases/WebKitGTK/webkit-2.14/Source/JavaScriptCore/heap/HeapSnapshotBuilder.cpp
r202383 r207061 67 67 { 68 68 ASSERT(m_profiler.activeSnapshotBuilder() == this); 69 ASSERT(Heap::isMarked (cell));69 ASSERT(Heap::isMarkedConcurrently(cell)); 70 70 71 71 if (hasExistingNodeForCell(cell)) -
releases/WebKitGTK/webkit-2.14/Source/JavaScriptCore/heap/MarkedBlock.cpp
r207055 r207061 358 358 void MarkedBlock::flipIfNecessarySlow() 359 359 { 360 ASSERT( m_version != vm()->heap.objectSpace().version());360 ASSERT(needsFlip()); 361 361 clearMarks(); 362 362 } … … 365 365 { 366 366 LockHolder locker(m_lock); 367 if ( m_version != vm()->heap.objectSpace().version())367 if (needsFlip()) 368 368 clearMarks(); 369 369 } … … 389 389 bool MarkedBlock::needsFlip() 390 390 { 391 return vm()->heap.objectSpace().version() != m_version;391 return needsFlip(vm()->heap.objectSpace().version()); 392 392 } 393 393 -
releases/WebKitGTK/webkit-2.14/Source/JavaScriptCore/heap/MarkedBlock.h
r207055 r207061 265 265 WeakSet& weakSet(); 266 266 267 bool needsFlip(HeapVersion); 267 268 bool needsFlip(); 268 269 … … 463 464 } 464 465 466 inline bool MarkedBlock::needsFlip(HeapVersion heapVersion) 467 { 468 return heapVersion != m_version; 469 } 470 465 471 inline void MarkedBlock::flipIfNecessary(HeapVersion heapVersion) 466 472 { 467 if (UNLIKELY( heapVersion != m_version))473 if (UNLIKELY(needsFlip(heapVersion))) 468 474 flipIfNecessarySlow(); 469 475 } … … 471 477 inline void MarkedBlock::flipIfNecessaryConcurrently(HeapVersion heapVersion) 472 478 { 473 if (UNLIKELY( heapVersion != m_version))479 if (UNLIKELY(needsFlip(heapVersion))) 474 480 flipIfNecessaryConcurrentlySlow(); 475 481 WTF::loadLoadFence(); -
releases/WebKitGTK/webkit-2.14/Source/JavaScriptCore/heap/SlotVisitor.cpp
r207055 r207061 228 228 ALWAYS_INLINE void SlotVisitor::appendToMarkStack(ContainerType& container, JSCell* cell) 229 229 { 230 ASSERT(Heap::isMarked (cell));230 ASSERT(Heap::isMarkedConcurrently(cell)); 231 231 ASSERT(!cell->isZapped()); 232 232 … … 249 249 250 250 if (Heap::testAndSetMarked(m_version, cell)) { 251 RELEASE_ASSERT(Heap::isMarked (cell));251 RELEASE_ASSERT(Heap::isMarkedConcurrently(cell)); 252 252 return; 253 253 } … … 294 294 ALWAYS_INLINE void SlotVisitor::visitChildren(const JSCell* cell) 295 295 { 296 ASSERT(Heap::isMarked (cell));296 ASSERT(Heap::isMarkedConcurrently(cell)); 297 297 298 298 SetCurrentCellScope currentCellScope(*this, cell); -
releases/WebKitGTK/webkit-2.14/Source/JavaScriptCore/runtime/Structure.cpp
r204424 r207061 1141 1141 // https://bugs.webkit.org/show_bug.cgi?id=157334 1142 1142 1143 return (!m_globalObject || Heap::isMarked (m_globalObject.get()))1144 && (!storedPrototypeObject() || Heap::isMarked (storedPrototypeObject()));1143 return (!m_globalObject || Heap::isMarkedConcurrently(m_globalObject.get())) 1144 && (!storedPrototypeObject() || Heap::isMarkedConcurrently(storedPrototypeObject())); 1145 1145 } 1146 1146 … … 1148 1148 { 1149 1149 if (!isCheapDuringGC()) 1150 return Heap::isMarked (this);1150 return Heap::isMarkedConcurrently(this); 1151 1151 1152 1152 visitor.appendUnbarrieredReadOnlyPointer(this); -
releases/WebKitGTK/webkit-2.14/Source/WTF/ChangeLog
r205730 r207061 1 2016-09-08 Filip Pizlo <fpizlo@apple.com> 2 3 Heap::isMarked() shouldn't pay the price of concurrent lazy flipping 4 https://bugs.webkit.org/show_bug.cgi?id=161760 5 6 Reviewed by Mark Lam. 7 8 * wtf/MainThread.cpp: 9 (WTF::isMainThreadOrGCThread): 10 (WTF::mayBeGCThread): 11 * wtf/MainThread.h: 12 1 13 2016-09-06 Saam Barati <sbarati@apple.com> 2 14 -
releases/WebKitGTK/webkit-2.14/Source/WTF/wtf/MainThread.cpp
r202736 r207061 1 1 /* 2 * Copyright (C) 2007, 2008, 2015 Apple Inc. All rights reserved.2 * Copyright (C) 2007, 2008, 2015-2016 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 211 211 bool isMainThreadOrGCThread() 212 212 { 213 if ( isGCThread->isSet() && **isGCThread)213 if (mayBeGCThread()) 214 214 return true; 215 215 … … 217 217 } 218 218 219 bool mayBeGCThread() 220 { 221 return isGCThread->isSet() && **isGCThread; 222 } 223 219 224 } // namespace WTF -
releases/WebKitGTK/webkit-2.14/Source/WTF/wtf/MainThread.h
r202439 r207061 1 1 /* 2 * Copyright (C) 2007, 2008, 2010 Apple Inc. All rights reserved.2 * Copyright (C) 2007, 2008, 2010, 2016 Apple Inc. All rights reserved. 3 3 * Copyright (C) 2007 Justin Haygood (jhaygood@reaktix.com) 4 4 * … … 69 69 70 70 WTF_EXPORT_PRIVATE void registerGCThread(); 71 WTF_EXPORT_PRIVATE bool mayBeGCThread(); 71 72 WTF_EXPORT_PRIVATE bool isMainThreadOrGCThread(); 72 73 … … 89 90 90 91 using WTF::callOnMainThread; 92 using WTF::canAccessThreadLocalDataForThread; 93 using WTF::isMainThread; 94 using WTF::isMainThreadOrGCThread; 95 using WTF::isUIThread; 96 using WTF::isWebThread; 97 using WTF::mayBeGCThread; 98 using WTF::setMainThreadCallbacksPaused; 91 99 #if PLATFORM(COCOA) 92 100 using WTF::callOnWebThreadOrDispatchAsyncOnMainThread; 93 101 #endif 94 using WTF::setMainThreadCallbacksPaused;95 using WTF::isMainThread;96 using WTF::isMainThreadOrGCThread;97 using WTF::canAccessThreadLocalDataForThread;98 using WTF::isUIThread;99 using WTF::isWebThread;100 102 #if USE(WEB_THREAD) 101 103 using WTF::initializeWebThread;
Note: See TracChangeset
for help on using the changeset viewer.