Changeset 263674 in webkit
- Timestamp:
- Jun 29, 2020 12:07:25 PM (4 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r263635 r263674 1 2020-06-29 Keith Miller <keith_miller@apple.com> 2 3 ConservativeRoots should mark any cell it finds an interior pointer to 4 https://bugs.webkit.org/show_bug.cgi?id=213686 5 6 Reviewed by Yusuke Suzuki. 7 8 Currently, if ConserativeRoots finds an interior pointer to a cell 9 it will only mark that cell if it's a butterfly of some 10 kind. However, this can cause problems if the C++ or B3 compilers 11 pre-compute the offset of some cell member they want to load from 12 after a call. If this happens and that interior pointer is the 13 only reference to the cell it can get collected while it is still 14 "alive". 15 16 A naive patch that doesn't return from 17 findGCObjectPointersForMarking after finding a live non-interior, 18 non-butterfly cell was a 2% regression on Speedometer2 and 19 JetStream2. So, this patch immediately returns after 20 marking some non-butterfly cell, which appears to have fixed the 21 regression locally. Given this was such a big regression (likely 22 from running MarkedBlock::isLive) more than once there's possibly 23 an optimization opportunity here. I filed 24 https://bugs.webkit.org/show_bug.cgi?id=213687 to investigate 25 further. 26 27 * heap/HeapCell.cpp: 28 (WTF::printInternal): 29 * heap/HeapCell.h: 30 (JSC::isJSCellKind): 31 (JSC::mayHaveIndexingHeader): 32 (JSC::hasInteriorPointers): Deleted. 33 * heap/HeapUtil.h: 34 (JSC::HeapUtil::findGCObjectPointersForMarking): 35 * heap/SlotVisitor.cpp: 36 (JSC::SlotVisitor::appendJSCellOrAuxiliary): 37 * runtime/VM.cpp: 38 (JSC::VM::VM): 39 1 40 2020-06-28 Geoffrey Garen <ggaren@apple.com> 2 41 -
trunk/Source/JavaScriptCore/heap/HeapCell.cpp
r259547 r263674 55 55 out.print("JSCell"); 56 56 return; 57 case HeapCell::JSCellWithIn teriorPointers:58 out.print("JSCellWithIn teriorPointers");57 case HeapCell::JSCellWithIndexingHeader: 58 out.print("JSCellWithIndexingHeader"); 59 59 return; 60 60 case HeapCell::Auxiliary: -
trunk/Source/JavaScriptCore/heap/HeapCell.h
r259547 r263674 43 43 enum Kind : int8_t { 44 44 JSCell, 45 JSCellWithIn teriorPointers,45 JSCellWithIndexingHeader, 46 46 Auxiliary 47 47 }; … … 94 94 inline bool isJSCellKind(HeapCell::Kind kind) 95 95 { 96 return kind == HeapCell::JSCell || kind == HeapCell::JSCellWithIn teriorPointers;96 return kind == HeapCell::JSCell || kind == HeapCell::JSCellWithIndexingHeader; 97 97 } 98 98 99 inline bool hasInteriorPointers(HeapCell::Kind kind)99 inline bool mayHaveIndexingHeader(HeapCell::Kind kind) 100 100 { 101 return kind == HeapCell::Auxiliary || kind == HeapCell::JSCellWithIn teriorPointers;101 return kind == HeapCell::Auxiliary || kind == HeapCell::JSCellWithIndexingHeader; 102 102 } 103 103 -
trunk/Source/JavaScriptCore/heap/HeapUtil.h
r254023 r263674 89 89 if (!filter.ruleOut(bitwise_cast<Bits>(previousCandidate)) 90 90 && set.contains(previousCandidate) 91 && hasInteriorPointers(previousCandidate->handle().cellKind())) {91 && mayHaveIndexingHeader(previousCandidate->handle().cellKind())) { 92 92 previousPointer = static_cast<char*>(previousCandidate->handle().cellAlign(previousPointer)); 93 93 if (previousCandidate->handle().isLiveCell(markingVersion, newlyAllocatedVersion, isMarking, previousPointer)) … … 107 107 108 108 auto tryPointer = [&] (void* pointer) { 109 if (candidate->handle().isLiveCell(markingVersion, newlyAllocatedVersion, isMarking, pointer)) 109 bool isLive = candidate->handle().isLiveCell(markingVersion, newlyAllocatedVersion, isMarking, pointer); 110 if (isLive) 110 111 func(pointer, cellKind); 112 // Only return early if we are marking a non-butterfly, since butterflies without indexed properties could point past the end of their allocation. 113 // If we do, and there is another live butterfly immediately following the first, we will mark the latter one here but we still need to 114 // mark the former. 115 return isLive && !mayHaveIndexingHeader(cellKind); 111 116 }; 112 117 113 118 if (isJSCellKind(cellKind)) { 114 if ( MarkedBlock::isAtomAligned(pointer))115 tryPointer(pointer);116 if (!hasInteriorPointers(cellKind))117 return;119 if (LIKELY(MarkedBlock::isAtomAligned(pointer))) { 120 if (tryPointer(pointer)) 121 return; 122 } 118 123 } 119 124 120 // A butterflycould point into the middle of an object.125 // We could point into the middle of an object. 121 126 char* alignedPointer = static_cast<char*>(candidate->handle().cellAlign(pointer)); 122 tryPointer(alignedPointer); 123 127 if (tryPointer(alignedPointer)) 128 return; 129 124 130 // Also, a butterfly could point at the end of an object plus sizeof(IndexingHeader). In that 125 131 // case, this is pointing to the object to the right of the one we should be marking. -
trunk/Source/JavaScriptCore/heap/SlotVisitor.cpp
r262928 r263674 209 209 switch (heapCell->cellKind()) { 210 210 case HeapCell::JSCell: 211 case HeapCell::JSCellWithIn teriorPointers: {211 case HeapCell::JSCellWithIndexingHeader: { 212 212 // We have ample budget to perform validation here. 213 213 -
trunk/Source/JavaScriptCore/runtime/VM.cpp
r263117 r263674 276 276 , jsValueGigacageAllocator(makeUnique<GigacageAlignedMemoryAllocator>(Gigacage::JSValue)) 277 277 , auxiliaryHeapCellType(makeUnique<HeapCellType>(CellAttributes(DoesNotNeedDestruction, HeapCell::Auxiliary))) 278 , immutableButterflyHeapCellType(makeUnique<HeapCellType>(CellAttributes(DoesNotNeedDestruction, HeapCell::JSCellWithIn teriorPointers)))278 , immutableButterflyHeapCellType(makeUnique<HeapCellType>(CellAttributes(DoesNotNeedDestruction, HeapCell::JSCellWithIndexingHeader))) 279 279 , cellHeapCellType(makeUnique<HeapCellType>(CellAttributes(DoesNotNeedDestruction, HeapCell::JSCell))) 280 280 , destructibleCellHeapCellType(makeUnique<HeapCellType>(CellAttributes(NeedsDestruction, HeapCell::JSCell))) … … 323 323 , primitiveGigacageAuxiliarySpace("Primitive Gigacage Auxiliary", heap, auxiliaryHeapCellType.get(), primitiveGigacageAllocator.get()) // Hash:0x3e7cd762 324 324 , jsValueGigacageAuxiliarySpace("JSValue Gigacage Auxiliary", heap, auxiliaryHeapCellType.get(), jsValueGigacageAllocator.get()) // Hash:0x241e946 325 , immutableButterflyJSValueGigacageAuxiliarySpace("ImmutableButterfly Gigacage JSCellWithIn teriorPointers", heap, immutableButterflyHeapCellType.get(), jsValueGigacageAllocator.get()) // Hash:0x7a945300325 , immutableButterflyJSValueGigacageAuxiliarySpace("ImmutableButterfly Gigacage JSCellWithIndexingHeader", heap, immutableButterflyHeapCellType.get(), jsValueGigacageAllocator.get()) // Hash:0x7a945300 326 326 , cellSpace("JSCell", heap, cellHeapCellType.get(), fastMallocAllocator.get()) // Hash:0xadfb5a79 327 327 , variableSizedCellSpace("Variable Sized JSCell", heap, cellHeapCellType.get(), fastMallocAllocator.get()) // Hash:0xbcd769cc
Note: See TracChangeset
for help on using the changeset viewer.