Changeset 227718 in webkit
- Timestamp:
- Jan 28, 2018 11:08:08 AM (6 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r227717 r227718 1 2018-01-27 Filip Pizlo <fpizlo@apple.com> 2 3 Make MarkedBlock::Footer bigger 4 https://bugs.webkit.org/show_bug.cgi?id=182220 5 6 Reviewed by JF Bastien. 7 8 This makes the block footer larger by moving the newlyAllocated bits from the handle into 9 the footer. 10 11 It used to be profitable to put anything we could into the handle because that would free up 12 payload space inside the block. But now that we want to use the footer for padding, it's 13 profitable to put GC state information - especially data that is used by the GC itself and so 14 is not useful for a Spectre attack - into the footer to increase object distancing. 15 16 * heap/CellContainer.cpp: 17 (JSC::CellContainer::isNewlyAllocated const): 18 * heap/IsoCellSet.cpp: 19 (JSC::IsoCellSet::sweepToFreeList): 20 * heap/MarkedBlock.cpp: 21 (JSC::MarkedBlock::Handle::Handle): 22 (JSC::MarkedBlock::Footer::Footer): 23 (JSC::MarkedBlock::Handle::stopAllocating): 24 (JSC::MarkedBlock::Handle::lastChanceToFinalize): 25 (JSC::MarkedBlock::Handle::resumeAllocating): 26 (JSC::MarkedBlock::aboutToMarkSlow): 27 (JSC::MarkedBlock::resetAllocated): 28 (JSC::MarkedBlock::Handle::resetAllocated): Deleted. 29 * heap/MarkedBlock.h: 30 (JSC::MarkedBlock::newlyAllocatedVersion const): 31 (JSC::MarkedBlock::isNewlyAllocated): 32 (JSC::MarkedBlock::setNewlyAllocated): 33 (JSC::MarkedBlock::clearNewlyAllocated): 34 (JSC::MarkedBlock::newlyAllocated const): 35 (JSC::MarkedBlock::Handle::newlyAllocatedVersion const): Deleted. 36 (JSC::MarkedBlock::Handle::isNewlyAllocated): Deleted. 37 (JSC::MarkedBlock::Handle::setNewlyAllocated): Deleted. 38 (JSC::MarkedBlock::Handle::clearNewlyAllocated): Deleted. 39 (JSC::MarkedBlock::Handle::newlyAllocated const): Deleted. 40 * heap/MarkedBlockInlines.h: 41 (JSC::MarkedBlock::isNewlyAllocatedStale const): 42 (JSC::MarkedBlock::hasAnyNewlyAllocated): 43 (JSC::MarkedBlock::Handle::isLive): 44 (JSC::MarkedBlock::Handle::specializedSweep): 45 (JSC::MarkedBlock::Handle::newlyAllocatedMode): 46 (JSC::MarkedBlock::Handle::isNewlyAllocatedStale const): Deleted. 47 (JSC::MarkedBlock::Handle::hasAnyNewlyAllocated): Deleted. 48 * heap/MarkedSpace.cpp: 49 (JSC::MarkedSpace::endMarking): 50 * heap/SlotVisitor.cpp: 51 (JSC::SlotVisitor::appendJSCellOrAuxiliary): 52 1 53 2018-01-27 Filip Pizlo <fpizlo@apple.com> 2 54 -
trunk/Source/JavaScriptCore/heap/CellContainer.cpp
r209808 r227718 1 1 /* 2 * Copyright (C) 2016 Apple Inc. All rights reserved.2 * Copyright (C) 2016-2018 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 35 35 if (isLargeAllocation()) 36 36 return largeAllocation().isNewlyAllocated(); 37 MarkedBlock ::Handle& handle = markedBlock().handle();38 return ! handle.isNewlyAllocatedStale()39 && handle.isNewlyAllocated(cell);37 MarkedBlock& block = markedBlock(); 38 return !block.isNewlyAllocatedStale() 39 && block.isNewlyAllocated(cell); 40 40 } 41 41 -
trunk/Source/JavaScriptCore/heap/IsoCellSet.cpp
r226822 r227718 127 127 } 128 128 129 if (block-> hasAnyNewlyAllocated()) {130 m_bits[block->index()]->concurrentFilter(block-> newlyAllocated());129 if (block->block().hasAnyNewlyAllocated()) { 130 m_bits[block->index()]->concurrentFilter(block->block().newlyAllocated()); 131 131 return; 132 132 } -
trunk/Source/JavaScriptCore/heap/MarkedBlock.cpp
r227717 r227718 63 63 : m_alignedMemoryAllocator(alignedMemoryAllocator) 64 64 , m_weakSet(heap.vm(), CellContainer()) 65 , m_newlyAllocatedVersion(MarkedSpace::nullVersion)66 65 { 67 66 m_block = new (NotNull, blockSpace) MarkedBlock(*heap.vm(), *this); … … 102 101 , m_vm(&vm) 103 102 , m_markingVersion(MarkedSpace::nullVersion) 103 , m_newlyAllocatedVersion(MarkedSpace::nullVersion) 104 104 { 105 105 } … … 145 145 // way to tell what's live vs dead. 146 146 147 m_newlyAllocated.clearAll();148 m_newlyAllocatedVersion = heap()->objectSpace().newlyAllocatedVersion();147 blockFooter().m_newlyAllocated.clearAll(); 148 blockFooter().m_newlyAllocatedVersion = heap()->objectSpace().newlyAllocatedVersion(); 149 149 150 150 forEachCell( 151 151 [&] (HeapCell* cell, HeapCell::Kind) -> IterationStatus { 152 setNewlyAllocated(cell);152 block().setNewlyAllocated(cell); 153 153 return IterationStatus::Continue; 154 154 }); … … 160 160 if (m_attributes.destruction == NeedsDestruction) 161 161 cell->zap(); 162 clearNewlyAllocated(cell);162 block().clearNewlyAllocated(cell); 163 163 }); 164 164 … … 174 174 blockFooter().m_markingVersion = heap()->objectSpace().markingVersion(); 175 175 m_weakSet.lastChanceToFinalize(); 176 m_newlyAllocated.clearAll();177 m_newlyAllocatedVersion = heap()->objectSpace().newlyAllocatedVersion();176 blockFooter().m_newlyAllocated.clearAll(); 177 blockFooter().m_newlyAllocatedVersion = heap()->objectSpace().newlyAllocatedVersion(); 178 178 sweep(nullptr); 179 179 } … … 189 189 ASSERT(!isFreeListed()); 190 190 191 if (! hasAnyNewlyAllocated()) {191 if (!block().hasAnyNewlyAllocated()) { 192 192 if (false) 193 193 dataLog("There ain't no newly allocated.\n"); … … 237 237 dataLog(RawPointer(this), ": Doing things.\n"); 238 238 HeapVersion newlyAllocatedVersion = space()->newlyAllocatedVersion(); 239 if ( handle().m_newlyAllocatedVersion == newlyAllocatedVersion) {239 if (footer().m_newlyAllocatedVersion == newlyAllocatedVersion) { 240 240 // When do we get here? The block could not have been filled up. The newlyAllocated bits would 241 241 // have had to be created since the end of the last collection. The only things that create … … 245 245 // computed the newlyAllocated bits just before the start of an increment. When we are in that 246 246 // mode, it seems as if newlyAllocated should subsume marks. 247 ASSERT( handle().m_newlyAllocated.subsumes(footer().m_marks));247 ASSERT(footer().m_newlyAllocated.subsumes(footer().m_marks)); 248 248 footer().m_marks.clearAll(); 249 249 } else { 250 handle().m_newlyAllocated.setAndClear(footer().m_marks);251 handle().m_newlyAllocatedVersion = newlyAllocatedVersion;250 footer().m_newlyAllocated.setAndClear(footer().m_marks); 251 footer().m_newlyAllocatedVersion = newlyAllocatedVersion; 252 252 } 253 253 } … … 260 260 } 261 261 262 void MarkedBlock:: Handle::resetAllocated()263 { 264 m_newlyAllocated.clearAll();265 m_newlyAllocatedVersion = MarkedSpace::nullVersion;262 void MarkedBlock::resetAllocated() 263 { 264 footer().m_newlyAllocated.clearAll(); 265 footer().m_newlyAllocatedVersion = MarkedSpace::nullVersion; 266 266 } 267 267 -
trunk/Source/JavaScriptCore/heap/MarkedBlock.h
r227717 r227718 175 175 bool isFreeListedCell(const void* target) const; 176 176 177 bool isNewlyAllocated(const void*);178 void setNewlyAllocated(const void*);179 void clearNewlyAllocated(const void*);180 const Bitmap<atomsPerBlock>& newlyAllocated() const;181 182 HeapVersion newlyAllocatedVersion() const { return m_newlyAllocatedVersion; }183 184 inline bool isNewlyAllocatedStale() const;185 186 inline bool hasAnyNewlyAllocated();187 void resetAllocated();188 189 177 template <typename Functor> IterationStatus forEachCell(const Functor&); 190 178 template <typename Functor> inline IterationStatus forEachLiveCell(const Functor&); … … 233 221 size_t m_endAtom { std::numeric_limits<size_t>::max() }; // This is a fuzzy end. Always test for < m_endAtom. 234 222 235 Bitmap<atomsPerBlock> m_newlyAllocated;236 237 223 CellAttributes m_attributes; 238 224 bool m_isFreeListed { false }; … … 243 229 WeakSet m_weakSet; 244 230 245 HeapVersion m_newlyAllocatedVersion;246 247 231 MarkedBlock* m_block { nullptr }; 248 232 }; … … 297 281 298 282 HeapVersion m_markingVersion; 283 HeapVersion m_newlyAllocatedVersion; 299 284 300 285 Bitmap<atomsPerBlock> m_marks; 286 Bitmap<atomsPerBlock> m_newlyAllocated; 301 287 }; 302 288 … … 331 317 void clearMarked(const void*); 332 318 319 bool isNewlyAllocated(const void*); 320 void setNewlyAllocated(const void*); 321 void clearNewlyAllocated(const void*); 322 const Bitmap<atomsPerBlock>& newlyAllocated() const; 323 324 HeapVersion newlyAllocatedVersion() const { return footer().m_newlyAllocatedVersion; } 325 326 inline bool isNewlyAllocatedStale() const; 327 328 inline bool hasAnyNewlyAllocated(); 329 void resetAllocated(); 330 333 331 size_t cellSize(); 334 332 const CellAttributes& attributes() const; … … 585 583 } 586 584 587 inline bool MarkedBlock:: Handle::isNewlyAllocated(const void* p)588 { 589 return m_newlyAllocated.get(m_block->atomNumber(p));590 } 591 592 inline void MarkedBlock:: Handle::setNewlyAllocated(const void* p)593 { 594 m_newlyAllocated.set(m_block->atomNumber(p));595 } 596 597 inline void MarkedBlock:: Handle::clearNewlyAllocated(const void* p)598 { 599 m_newlyAllocated.clear(m_block->atomNumber(p));600 } 601 602 inline const Bitmap<MarkedBlock::atomsPerBlock>& MarkedBlock:: Handle::newlyAllocated() const603 { 604 return m_newlyAllocated;585 inline bool MarkedBlock::isNewlyAllocated(const void* p) 586 { 587 return footer().m_newlyAllocated.get(atomNumber(p)); 588 } 589 590 inline void MarkedBlock::setNewlyAllocated(const void* p) 591 { 592 footer().m_newlyAllocated.set(atomNumber(p)); 593 } 594 595 inline void MarkedBlock::clearNewlyAllocated(const void* p) 596 { 597 footer().m_newlyAllocated.clear(atomNumber(p)); 598 } 599 600 inline const Bitmap<MarkedBlock::atomsPerBlock>& MarkedBlock::newlyAllocated() const 601 { 602 return footer().m_newlyAllocated; 605 603 } 606 604 -
trunk/Source/JavaScriptCore/heap/MarkedBlockInlines.h
r227717 r227718 41 41 } 42 42 43 inline bool MarkedBlock:: Handle::isNewlyAllocatedStale() const44 { 45 return m_newlyAllocatedVersion != space()->newlyAllocatedVersion();46 } 47 48 inline bool MarkedBlock:: Handle::hasAnyNewlyAllocated()43 inline bool MarkedBlock::isNewlyAllocatedStale() const 44 { 45 return footer().m_newlyAllocatedVersion != space()->newlyAllocatedVersion(); 46 } 47 48 inline bool MarkedBlock::hasAnyNewlyAllocated() 49 49 { 50 50 return !isNewlyAllocatedStale(); … … 144 144 if (count.value) { 145 145 Dependency fenceBefore = Dependency::fence(count.input); 146 MarkedBlock& fencedBlock = *fenceBefore.consume(&block); 147 MarkedBlock::Footer& fencedFooter = fencedBlock.footer(); 146 148 MarkedBlock::Handle* fencedThis = fenceBefore.consume(this); 147 149 148 ASSERT (!fencedThis->isFreeListed());149 150 HeapVersion myNewlyAllocatedVersion = fenced This->m_newlyAllocatedVersion;150 ASSERT_UNUSED(fencedThis, !fencedThis->isFreeListed()); 151 152 HeapVersion myNewlyAllocatedVersion = fencedFooter.m_newlyAllocatedVersion; 151 153 if (myNewlyAllocatedVersion == newlyAllocatedVersion) { 152 bool result = fenced This->isNewlyAllocated(cell);154 bool result = fencedBlock.isNewlyAllocated(cell); 153 155 if (footer.m_lock.fencelessValidate(count.value, Dependency::fence(result))) 154 156 return result; 155 157 } else { 156 MarkedBlock& fencedBlock = *fenceBefore.consume(&block);157 MarkedBlock::Footer& fencedFooter = fencedBlock.footer();158 159 158 HeapVersion myMarkingVersion = fencedFooter.m_markingVersion; 160 159 if (myMarkingVersion != markingVersion … … 174 173 ASSERT(!isFreeListed()); 175 174 176 HeapVersion myNewlyAllocatedVersion = m_newlyAllocatedVersion;175 HeapVersion myNewlyAllocatedVersion = footer.m_newlyAllocatedVersion; 177 176 if (myNewlyAllocatedVersion == newlyAllocatedVersion) 178 return isNewlyAllocated(cell);177 return block.isNewlyAllocated(cell); 179 178 180 179 if (block.areMarksStale(markingVersion)) { … … 327 326 if (emptyMode == NotEmpty 328 327 && ((marksMode == MarksNotStale && footer.m_marks.get(i)) 329 || (newlyAllocatedMode == HasNewlyAllocated && m_newlyAllocated.get(i)))) {328 || (newlyAllocatedMode == HasNewlyAllocated && footer.m_newlyAllocated.get(i)))) { 330 329 isEmpty = false; 331 330 continue; … … 341 340 // otherwise we would lose information on what's currently alive. 342 341 if (sweepMode == SweepToFreeList && newlyAllocatedMode == HasNewlyAllocated) 343 m_newlyAllocatedVersion = MarkedSpace::nullVersion;342 footer.m_newlyAllocatedVersion = MarkedSpace::nullVersion; 344 343 345 344 if (space()->isMarking()) … … 465 464 inline MarkedBlock::Handle::NewlyAllocatedMode MarkedBlock::Handle::newlyAllocatedMode() 466 465 { 467 return hasAnyNewlyAllocated() ? HasNewlyAllocated : DoesNotHaveNewlyAllocated;466 return block().hasAnyNewlyAllocated() ? HasNewlyAllocated : DoesNotHaveNewlyAllocated; 468 467 } 469 468 -
trunk/Source/JavaScriptCore/heap/MarkedSpace.cpp
r227717 r227718 45 45 result = new Vector<size_t>(); 46 46 47 if (Options::dumpSizeClasses()) { 48 dataLog("Block size: ", MarkedBlock::blockSize, "\n"); 49 dataLog("Footer size: ", sizeof(MarkedBlock::Footer), "\n"); 50 } 51 47 52 auto add = [&] (size_t sizeClass) { 48 53 sizeClass = WTF::roundUpToMultipleOf<MarkedBlock::atomSize>(sizeClass); … … 425 430 forEachBlock( 426 431 [&] (MarkedBlock::Handle* handle) { 427 handle-> resetAllocated();432 handle->block().resetAllocated(); 428 433 }); 429 434 } -
trunk/Source/JavaScriptCore/heap/SlotVisitor.cpp
r227617 r227718 1 1 /* 2 * Copyright (C) 2012-201 7Apple Inc. All rights reserved.2 * Copyright (C) 2012-2018 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 171 171 out.print("Marking version: ", block.markingVersion(), "\n"); 172 172 out.print("Heap marking version: ", heap()->objectSpace().markingVersion(), "\n"); 173 out.print("Is newly allocated raw: ", block. handle().isNewlyAllocated(jsCell), "\n");174 out.print("Newly allocated version: ", block. handle().newlyAllocatedVersion(), "\n");173 out.print("Is newly allocated raw: ", block.isNewlyAllocated(jsCell), "\n"); 174 out.print("Newly allocated version: ", block.newlyAllocatedVersion(), "\n"); 175 175 out.print("Heap newly allocated version: ", heap()->objectSpace().newlyAllocatedVersion(), "\n"); 176 176 }
Note: See TracChangeset
for help on using the changeset viewer.