Changeset 226667 in webkit


Ignore:
Timestamp:
Jan 9, 2018, 4:30:38 PM (8 years ago)
Author:
[email protected]
Message:

CodeBlocks should be in IsoSubspaces
https://bugs.webkit.org/show_bug.cgi?id=180884

Reviewed by Saam Barati.
Source/JavaScriptCore:


This moves CodeBlocks into IsoSubspaces. Doing so means that we no longer need to have the
special CodeBlockSet HashSets of new and old CodeBlocks. We also no longer use
WeakReferenceHarvester or UnconditionalFinalizer. Instead:

  • Code block sweeping is now just eager sweeping. This means that it automatically takes advantage of our unswept set, which roughly corresponds to what CodeBlockSet used to use its eden set for.


  • Those idea of Executable "weakly visiting" the CodeBlock is replaced by Executable marking a ExecutableToCodeBlockEdge object. That object being marked corresponds to what we used to call CodeBlock "having been weakly visited". This means that CodeBlockSet no longer has to clear the set of weakly visited code blocks. This also means that determining CodeBlock liveness, propagating CodeBlock transitions, and jettisoning CodeBlocks during GC are now the edge's job. The edge is also in an IsoSubspace and it has IsoCellSets to tell us which edges have output constraints (what we used to call CodeBlock's weak reference harvester) and which have unconditional finalizers.


  • CodeBlock now uses an IsoCellSet to tell if it has an unconditional finalizer.


  • CodeBlockSet still exists! It has one unified HashSet of CodeBlocks that we use to handle requests from the sampler, debugger, and other facilities. They may want to ask if some pointer corresponds to a CodeBlock during stages of execution during which the GC is unable to answer isLive() queries. The trickiest is the sampling profiler thread. There is no way that the GC's isLive could tell us of a CodeBlock that had already been allocated has now been full constructed.


  • JavaScriptCore.xcodeproj/project.pbxproj:
  • Sources.txt:
  • bytecode/CodeBlock.cpp:

(JSC::CodeBlock::CodeBlock):
(JSC::CodeBlock::finishCreation):
(JSC::CodeBlock::finishCreationCommon):
(JSC::CodeBlock::~CodeBlock):
(JSC::CodeBlock::visitChildren):
(JSC::CodeBlock::propagateTransitions):
(JSC::CodeBlock::determineLiveness):
(JSC::CodeBlock::finalizeUnconditionally):
(JSC::CodeBlock::stronglyVisitStrongReferences):
(JSC::CodeBlock::hasInstalledVMTrapBreakpoints const):
(JSC::CodeBlock::installVMTrapBreakpoints):
(JSC::CodeBlock::dumpMathICStats):
(JSC::CodeBlock::visitWeakly): Deleted.
(JSC::CodeBlock::WeakReferenceHarvester::visitWeakReferences): Deleted.
(JSC::CodeBlock::UnconditionalFinalizer::finalizeUnconditionally): Deleted.

  • bytecode/CodeBlock.h:

(JSC::CodeBlock::subspaceFor):
(JSC::CodeBlock::ownerEdge const):
(JSC::CodeBlock::clearVisitWeaklyHasBeenCalled): Deleted.

  • bytecode/EvalCodeBlock.h:

(JSC::EvalCodeBlock::create): Deleted.
(JSC::EvalCodeBlock::createStructure): Deleted.
(JSC::EvalCodeBlock::variable): Deleted.
(JSC::EvalCodeBlock::numVariables): Deleted.
(JSC::EvalCodeBlock::functionHoistingCandidate): Deleted.
(JSC::EvalCodeBlock::numFunctionHoistingCandidates): Deleted.
(JSC::EvalCodeBlock::EvalCodeBlock): Deleted.
(JSC::EvalCodeBlock::unlinkedEvalCodeBlock const): Deleted.

  • bytecode/ExecutableToCodeBlockEdge.cpp: Added.

(JSC::ExecutableToCodeBlockEdge::createStructure):
(JSC::ExecutableToCodeBlockEdge::create):
(JSC::ExecutableToCodeBlockEdge::visitChildren):
(JSC::ExecutableToCodeBlockEdge::visitOutputConstraints):
(JSC::ExecutableToCodeBlockEdge::finalizeUnconditionally):
(JSC::ExecutableToCodeBlockEdge::activate):
(JSC::ExecutableToCodeBlockEdge::deactivate):
(JSC::ExecutableToCodeBlockEdge::deactivateAndUnwrap):
(JSC::ExecutableToCodeBlockEdge::wrap):
(JSC::ExecutableToCodeBlockEdge::wrapAndActivate):
(JSC::ExecutableToCodeBlockEdge::ExecutableToCodeBlockEdge):
(JSC::ExecutableToCodeBlockEdge::runConstraint):

  • bytecode/ExecutableToCodeBlockEdge.h: Added.

(JSC::ExecutableToCodeBlockEdge::subspaceFor):
(JSC::ExecutableToCodeBlockEdge::codeBlock const):
(JSC::ExecutableToCodeBlockEdge::unwrap):

  • bytecode/FunctionCodeBlock.h:

(JSC::FunctionCodeBlock::subspaceFor):
(JSC::FunctionCodeBlock::createStructure):

  • bytecode/ModuleProgramCodeBlock.h:

(JSC::ModuleProgramCodeBlock::create): Deleted.
(JSC::ModuleProgramCodeBlock::createStructure): Deleted.
(JSC::ModuleProgramCodeBlock::ModuleProgramCodeBlock): Deleted.

  • bytecode/ProgramCodeBlock.h:

(JSC::ProgramCodeBlock::create): Deleted.
(JSC::ProgramCodeBlock::createStructure): Deleted.
(JSC::ProgramCodeBlock::ProgramCodeBlock): Deleted.

  • debugger/Debugger.cpp:

(JSC::Debugger::SetSteppingModeFunctor::operator() const):
(JSC::Debugger::ToggleBreakpointFunctor::operator() const):
(JSC::Debugger::ClearCodeBlockDebuggerRequestsFunctor::operator() const):
(JSC::Debugger::ClearDebuggerRequestsFunctor::operator() const):

  • heap/CodeBlockSet.cpp:

(JSC::CodeBlockSet::contains):
(JSC::CodeBlockSet::dump const):
(JSC::CodeBlockSet::add):
(JSC::CodeBlockSet::remove):
(JSC::CodeBlockSet::promoteYoungCodeBlocks): Deleted.
(JSC::CodeBlockSet::clearMarksForFullCollection): Deleted.
(JSC::CodeBlockSet::lastChanceToFinalize): Deleted.
(JSC::CodeBlockSet::deleteUnmarkedAndUnreferenced): Deleted.

  • heap/CodeBlockSet.h:
  • heap/CodeBlockSetInlines.h:

(JSC::CodeBlockSet::iterate):
(JSC::CodeBlockSet::iterateViaSubspaces):

  • heap/ConservativeRoots.cpp:

(JSC::ConservativeRoots::genericAddPointer):
(JSC::DummyMarkHook::markKnownJSCell):
(JSC::CompositeMarkHook::mark):
(JSC::CompositeMarkHook::markKnownJSCell):

  • heap/ConservativeRoots.h:
  • heap/Heap.cpp:

(JSC::Heap::lastChanceToFinalize):
(JSC::Heap::finalizeMarkedUnconditionalFinalizers):
(JSC::Heap::finalizeUnconditionalFinalizers):
(JSC::Heap::beginMarking):
(JSC::Heap::deleteUnmarkedCompiledCode):
(JSC::Heap::sweepInFinalize):
(JSC::Heap::forEachCodeBlockImpl):
(JSC::Heap::forEachCodeBlockIgnoringJITPlansImpl):
(JSC::Heap::addCoreConstraints):
(JSC::Heap::finalizeUnconditionalFinalizersInIsoSubspace): Deleted.

  • heap/Heap.h:
  • heap/HeapCell.h:
  • heap/HeapCellInlines.h:

(JSC::HeapCell::subspace const):

  • heap/HeapInlines.h:

(JSC::Heap::forEachCodeBlock):
(JSC::Heap::forEachCodeBlockIgnoringJITPlans):

  • heap/HeapUtil.h:

(JSC::HeapUtil::findGCObjectPointersForMarking):

  • heap/IsoCellSet.cpp:

(JSC::IsoCellSet::parallelNotEmptyMarkedBlockSource):

  • heap/IsoCellSet.h:
  • heap/IsoCellSetInlines.h:

(JSC::IsoCellSet::forEachMarkedCellInParallel):
(JSC::IsoCellSet::forEachLiveCell):

  • heap/LargeAllocation.h:

(JSC::LargeAllocation::subspace const):

  • heap/MarkStackMergingConstraint.cpp:

(JSC::MarkStackMergingConstraint::executeImpl):

  • heap/MarkStackMergingConstraint.h:
  • heap/MarkedAllocator.cpp:

(JSC::MarkedAllocator::parallelNotEmptyBlockSource):

  • heap/MarkedBlock.cpp:

(JSC::MarkedBlock::Handle::didAddToAllocator):
(JSC::MarkedBlock::Handle::didRemoveFromAllocator):

  • heap/MarkedBlock.h:

(JSC::MarkedBlock::subspace const):

  • heap/MarkedBlockInlines.h:

(JSC::MarkedBlock::Handle::forEachLiveCell):

  • heap/MarkedSpaceInlines.h:

(JSC::MarkedSpace::forEachLiveCell):

  • heap/MarkingConstraint.cpp:

(JSC::MarkingConstraint::execute):
(JSC::MarkingConstraint::doParallelWork):
(JSC::MarkingConstraint::finishParallelWork): Deleted.
(JSC::MarkingConstraint::doParallelWorkImpl): Deleted.
(JSC::MarkingConstraint::finishParallelWorkImpl): Deleted.

  • heap/MarkingConstraint.h:
  • heap/MarkingConstraintSet.cpp:

(JSC::MarkingConstraintSet::add):

  • heap/MarkingConstraintSet.h:

(JSC::MarkingConstraintSet::add):

  • heap/MarkingConstraintSolver.cpp:

(JSC::MarkingConstraintSolver::execute):
(JSC::MarkingConstraintSolver::addParallelTask):
(JSC::MarkingConstraintSolver::runExecutionThread):
(JSC::MarkingConstraintSolver::didExecute): Deleted.

  • heap/MarkingConstraintSolver.h:

(JSC::MarkingConstraintSolver::TaskWithConstraint::TaskWithConstraint):
(JSC::MarkingConstraintSolver::TaskWithConstraint::operator== const):

  • heap/SimpleMarkingConstraint.cpp:

(JSC::SimpleMarkingConstraint::SimpleMarkingConstraint):
(JSC::SimpleMarkingConstraint::executeImpl):

  • heap/SimpleMarkingConstraint.h:

(JSC::SimpleMarkingConstraint::SimpleMarkingConstraint):

  • heap/SlotVisitor.cpp:

(JSC::SlotVisitor::addParallelConstraintTask):

  • heap/SlotVisitor.h:
  • heap/Subspace.cpp:

(JSC::Subspace::sweep):

  • heap/Subspace.h:
  • heap/SubspaceInlines.h:

(JSC::Subspace::forEachLiveCell):

  • llint/LowLevelInterpreter.asm:
  • runtime/EvalExecutable.cpp:

(JSC::EvalExecutable::visitChildren):

  • runtime/EvalExecutable.h:

(JSC::EvalExecutable::codeBlock):

  • runtime/FunctionExecutable.cpp:

(JSC::FunctionExecutable::baselineCodeBlockFor):
(JSC::FunctionExecutable::visitChildren):

  • runtime/FunctionExecutable.h:
  • runtime/JSType.h:
  • runtime/ModuleProgramExecutable.cpp:

(JSC::ModuleProgramExecutable::visitChildren):

  • runtime/ModuleProgramExecutable.h:
  • runtime/ProgramExecutable.cpp:

(JSC::ProgramExecutable::visitChildren):

  • runtime/ProgramExecutable.h:
  • runtime/ScriptExecutable.cpp:

(JSC::ScriptExecutable::installCode):
(JSC::ScriptExecutable::newReplacementCodeBlockFor):

  • runtime/VM.cpp:

(JSC::VM::VM):

  • runtime/VM.h:

(JSC::VM::SpaceAndFinalizerSet::SpaceAndFinalizerSet):
(JSC::VM::SpaceAndFinalizerSet::finalizerSetFor):
(JSC::VM::forEachCodeBlockSpace):

  • runtime/VMTraps.cpp:

(JSC::VMTraps::handleTraps):

  • tools/VMInspector.cpp:

(JSC::VMInspector::codeBlockForMachinePC):
(JSC::VMInspector::isValidCodeBlock):

Source/WebCore:

No new tests because no new behavior.

Adopting new parallel constraint API, so that more of the logic of doing parallel
constraint solving is shared between the DOM's output constraints and JSC's output
constraints.

  • bindings/js/DOMGCOutputConstraint.cpp:

(WebCore::DOMGCOutputConstraint::executeImpl):
(WebCore::DOMGCOutputConstraint::doParallelWorkImpl): Deleted.
(WebCore::DOMGCOutputConstraint::finishParallelWorkImpl): Deleted.

  • bindings/js/DOMGCOutputConstraint.h:

Source/WTF:


Deque<>::contains() is helpful for a debug ASSERT.

  • wtf/Deque.h:

(WTF::inlineCapacity>::contains):

Location:
trunk
Files:
2 added
66 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r226658 r226667  
     12018-01-04  Filip Pizlo  <[email protected]>
     2
     3        CodeBlocks should be in IsoSubspaces
     4        https://bugs.webkit.org/show_bug.cgi?id=180884
     5
     6        Reviewed by Saam Barati.
     7       
     8        This moves CodeBlocks into IsoSubspaces. Doing so means that we no longer need to have the
     9        special CodeBlockSet HashSets of new and old CodeBlocks. We also no longer use
     10        WeakReferenceHarvester or UnconditionalFinalizer. Instead:
     11       
     12        - Code block sweeping is now just eager sweeping. This means that it automatically takes
     13          advantage of our unswept set, which roughly corresponds to what CodeBlockSet used to use
     14          its eden set for.
     15       
     16        - Those idea of Executable "weakly visiting" the CodeBlock is replaced by Executable
     17          marking a ExecutableToCodeBlockEdge object. That object being marked corresponds to what
     18          we used to call CodeBlock "having been weakly visited". This means that CodeBlockSet no
     19          longer has to clear the set of weakly visited code blocks. This also means that
     20          determining CodeBlock liveness, propagating CodeBlock transitions, and jettisoning
     21          CodeBlocks during GC are now the edge's job. The edge is also in an IsoSubspace and it
     22          has IsoCellSets to tell us which edges have output constraints (what we used to call
     23          CodeBlock's weak reference harvester) and which have unconditional finalizers.
     24       
     25        - CodeBlock now uses an IsoCellSet to tell if it has an unconditional finalizer.
     26       
     27        - CodeBlockSet still exists!  It has one unified HashSet of CodeBlocks that we use to
     28          handle requests from the sampler, debugger, and other facilities. They may want to ask
     29          if some pointer corresponds to a CodeBlock during stages of execution during which the
     30          GC is unable to answer isLive() queries. The trickiest is the sampling profiler thread.
     31          There is no way that the GC's isLive could tell us of a CodeBlock that had already been
     32          allocated has now been full constructed.
     33       
     34        * JavaScriptCore.xcodeproj/project.pbxproj:
     35        * Sources.txt:
     36        * bytecode/CodeBlock.cpp:
     37        (JSC::CodeBlock::CodeBlock):
     38        (JSC::CodeBlock::finishCreation):
     39        (JSC::CodeBlock::finishCreationCommon):
     40        (JSC::CodeBlock::~CodeBlock):
     41        (JSC::CodeBlock::visitChildren):
     42        (JSC::CodeBlock::propagateTransitions):
     43        (JSC::CodeBlock::determineLiveness):
     44        (JSC::CodeBlock::finalizeUnconditionally):
     45        (JSC::CodeBlock::stronglyVisitStrongReferences):
     46        (JSC::CodeBlock::hasInstalledVMTrapBreakpoints const):
     47        (JSC::CodeBlock::installVMTrapBreakpoints):
     48        (JSC::CodeBlock::dumpMathICStats):
     49        (JSC::CodeBlock::visitWeakly): Deleted.
     50        (JSC::CodeBlock::WeakReferenceHarvester::visitWeakReferences): Deleted.
     51        (JSC::CodeBlock::UnconditionalFinalizer::finalizeUnconditionally): Deleted.
     52        * bytecode/CodeBlock.h:
     53        (JSC::CodeBlock::subspaceFor):
     54        (JSC::CodeBlock::ownerEdge const):
     55        (JSC::CodeBlock::clearVisitWeaklyHasBeenCalled): Deleted.
     56        * bytecode/EvalCodeBlock.h:
     57        (JSC::EvalCodeBlock::create): Deleted.
     58        (JSC::EvalCodeBlock::createStructure): Deleted.
     59        (JSC::EvalCodeBlock::variable): Deleted.
     60        (JSC::EvalCodeBlock::numVariables): Deleted.
     61        (JSC::EvalCodeBlock::functionHoistingCandidate): Deleted.
     62        (JSC::EvalCodeBlock::numFunctionHoistingCandidates): Deleted.
     63        (JSC::EvalCodeBlock::EvalCodeBlock): Deleted.
     64        (JSC::EvalCodeBlock::unlinkedEvalCodeBlock const): Deleted.
     65        * bytecode/ExecutableToCodeBlockEdge.cpp: Added.
     66        (JSC::ExecutableToCodeBlockEdge::createStructure):
     67        (JSC::ExecutableToCodeBlockEdge::create):
     68        (JSC::ExecutableToCodeBlockEdge::visitChildren):
     69        (JSC::ExecutableToCodeBlockEdge::visitOutputConstraints):
     70        (JSC::ExecutableToCodeBlockEdge::finalizeUnconditionally):
     71        (JSC::ExecutableToCodeBlockEdge::activate):
     72        (JSC::ExecutableToCodeBlockEdge::deactivate):
     73        (JSC::ExecutableToCodeBlockEdge::deactivateAndUnwrap):
     74        (JSC::ExecutableToCodeBlockEdge::wrap):
     75        (JSC::ExecutableToCodeBlockEdge::wrapAndActivate):
     76        (JSC::ExecutableToCodeBlockEdge::ExecutableToCodeBlockEdge):
     77        (JSC::ExecutableToCodeBlockEdge::runConstraint):
     78        * bytecode/ExecutableToCodeBlockEdge.h: Added.
     79        (JSC::ExecutableToCodeBlockEdge::subspaceFor):
     80        (JSC::ExecutableToCodeBlockEdge::codeBlock const):
     81        (JSC::ExecutableToCodeBlockEdge::unwrap):
     82        * bytecode/FunctionCodeBlock.h:
     83        (JSC::FunctionCodeBlock::subspaceFor):
     84        (JSC::FunctionCodeBlock::createStructure):
     85        * bytecode/ModuleProgramCodeBlock.h:
     86        (JSC::ModuleProgramCodeBlock::create): Deleted.
     87        (JSC::ModuleProgramCodeBlock::createStructure): Deleted.
     88        (JSC::ModuleProgramCodeBlock::ModuleProgramCodeBlock): Deleted.
     89        * bytecode/ProgramCodeBlock.h:
     90        (JSC::ProgramCodeBlock::create): Deleted.
     91        (JSC::ProgramCodeBlock::createStructure): Deleted.
     92        (JSC::ProgramCodeBlock::ProgramCodeBlock): Deleted.
     93        * debugger/Debugger.cpp:
     94        (JSC::Debugger::SetSteppingModeFunctor::operator() const):
     95        (JSC::Debugger::ToggleBreakpointFunctor::operator() const):
     96        (JSC::Debugger::ClearCodeBlockDebuggerRequestsFunctor::operator() const):
     97        (JSC::Debugger::ClearDebuggerRequestsFunctor::operator() const):
     98        * heap/CodeBlockSet.cpp:
     99        (JSC::CodeBlockSet::contains):
     100        (JSC::CodeBlockSet::dump const):
     101        (JSC::CodeBlockSet::add):
     102        (JSC::CodeBlockSet::remove):
     103        (JSC::CodeBlockSet::promoteYoungCodeBlocks): Deleted.
     104        (JSC::CodeBlockSet::clearMarksForFullCollection): Deleted.
     105        (JSC::CodeBlockSet::lastChanceToFinalize): Deleted.
     106        (JSC::CodeBlockSet::deleteUnmarkedAndUnreferenced): Deleted.
     107        * heap/CodeBlockSet.h:
     108        * heap/CodeBlockSetInlines.h:
     109        (JSC::CodeBlockSet::iterate):
     110        (JSC::CodeBlockSet::iterateViaSubspaces):
     111        * heap/ConservativeRoots.cpp:
     112        (JSC::ConservativeRoots::genericAddPointer):
     113        (JSC::DummyMarkHook::markKnownJSCell):
     114        (JSC::CompositeMarkHook::mark):
     115        (JSC::CompositeMarkHook::markKnownJSCell):
     116        * heap/ConservativeRoots.h:
     117        * heap/Heap.cpp:
     118        (JSC::Heap::lastChanceToFinalize):
     119        (JSC::Heap::finalizeMarkedUnconditionalFinalizers):
     120        (JSC::Heap::finalizeUnconditionalFinalizers):
     121        (JSC::Heap::beginMarking):
     122        (JSC::Heap::deleteUnmarkedCompiledCode):
     123        (JSC::Heap::sweepInFinalize):
     124        (JSC::Heap::forEachCodeBlockImpl):
     125        (JSC::Heap::forEachCodeBlockIgnoringJITPlansImpl):
     126        (JSC::Heap::addCoreConstraints):
     127        (JSC::Heap::finalizeUnconditionalFinalizersInIsoSubspace): Deleted.
     128        * heap/Heap.h:
     129        * heap/HeapCell.h:
     130        * heap/HeapCellInlines.h:
     131        (JSC::HeapCell::subspace const):
     132        * heap/HeapInlines.h:
     133        (JSC::Heap::forEachCodeBlock):
     134        (JSC::Heap::forEachCodeBlockIgnoringJITPlans):
     135        * heap/HeapUtil.h:
     136        (JSC::HeapUtil::findGCObjectPointersForMarking):
     137        * heap/IsoCellSet.cpp:
     138        (JSC::IsoCellSet::parallelNotEmptyMarkedBlockSource):
     139        * heap/IsoCellSet.h:
     140        * heap/IsoCellSetInlines.h:
     141        (JSC::IsoCellSet::forEachMarkedCellInParallel):
     142        (JSC::IsoCellSet::forEachLiveCell):
     143        * heap/LargeAllocation.h:
     144        (JSC::LargeAllocation::subspace const):
     145        * heap/MarkStackMergingConstraint.cpp:
     146        (JSC::MarkStackMergingConstraint::executeImpl):
     147        * heap/MarkStackMergingConstraint.h:
     148        * heap/MarkedAllocator.cpp:
     149        (JSC::MarkedAllocator::parallelNotEmptyBlockSource):
     150        * heap/MarkedBlock.cpp:
     151        (JSC::MarkedBlock::Handle::didAddToAllocator):
     152        (JSC::MarkedBlock::Handle::didRemoveFromAllocator):
     153        * heap/MarkedBlock.h:
     154        (JSC::MarkedBlock::subspace const):
     155        * heap/MarkedBlockInlines.h:
     156        (JSC::MarkedBlock::Handle::forEachLiveCell):
     157        * heap/MarkedSpaceInlines.h:
     158        (JSC::MarkedSpace::forEachLiveCell):
     159        * heap/MarkingConstraint.cpp:
     160        (JSC::MarkingConstraint::execute):
     161        (JSC::MarkingConstraint::doParallelWork):
     162        (JSC::MarkingConstraint::finishParallelWork): Deleted.
     163        (JSC::MarkingConstraint::doParallelWorkImpl): Deleted.
     164        (JSC::MarkingConstraint::finishParallelWorkImpl): Deleted.
     165        * heap/MarkingConstraint.h:
     166        * heap/MarkingConstraintSet.cpp:
     167        (JSC::MarkingConstraintSet::add):
     168        * heap/MarkingConstraintSet.h:
     169        (JSC::MarkingConstraintSet::add):
     170        * heap/MarkingConstraintSolver.cpp:
     171        (JSC::MarkingConstraintSolver::execute):
     172        (JSC::MarkingConstraintSolver::addParallelTask):
     173        (JSC::MarkingConstraintSolver::runExecutionThread):
     174        (JSC::MarkingConstraintSolver::didExecute): Deleted.
     175        * heap/MarkingConstraintSolver.h:
     176        (JSC::MarkingConstraintSolver::TaskWithConstraint::TaskWithConstraint):
     177        (JSC::MarkingConstraintSolver::TaskWithConstraint::operator== const):
     178        * heap/SimpleMarkingConstraint.cpp:
     179        (JSC::SimpleMarkingConstraint::SimpleMarkingConstraint):
     180        (JSC::SimpleMarkingConstraint::executeImpl):
     181        * heap/SimpleMarkingConstraint.h:
     182        (JSC::SimpleMarkingConstraint::SimpleMarkingConstraint):
     183        * heap/SlotVisitor.cpp:
     184        (JSC::SlotVisitor::addParallelConstraintTask):
     185        * heap/SlotVisitor.h:
     186        * heap/Subspace.cpp:
     187        (JSC::Subspace::sweep):
     188        * heap/Subspace.h:
     189        * heap/SubspaceInlines.h:
     190        (JSC::Subspace::forEachLiveCell):
     191        * llint/LowLevelInterpreter.asm:
     192        * runtime/EvalExecutable.cpp:
     193        (JSC::EvalExecutable::visitChildren):
     194        * runtime/EvalExecutable.h:
     195        (JSC::EvalExecutable::codeBlock):
     196        * runtime/FunctionExecutable.cpp:
     197        (JSC::FunctionExecutable::baselineCodeBlockFor):
     198        (JSC::FunctionExecutable::visitChildren):
     199        * runtime/FunctionExecutable.h:
     200        * runtime/JSType.h:
     201        * runtime/ModuleProgramExecutable.cpp:
     202        (JSC::ModuleProgramExecutable::visitChildren):
     203        * runtime/ModuleProgramExecutable.h:
     204        * runtime/ProgramExecutable.cpp:
     205        (JSC::ProgramExecutable::visitChildren):
     206        * runtime/ProgramExecutable.h:
     207        * runtime/ScriptExecutable.cpp:
     208        (JSC::ScriptExecutable::installCode):
     209        (JSC::ScriptExecutable::newReplacementCodeBlockFor):
     210        * runtime/VM.cpp:
     211        (JSC::VM::VM):
     212        * runtime/VM.h:
     213        (JSC::VM::SpaceAndFinalizerSet::SpaceAndFinalizerSet):
     214        (JSC::VM::SpaceAndFinalizerSet::finalizerSetFor):
     215        (JSC::VM::forEachCodeBlockSpace):
     216        * runtime/VMTraps.cpp:
     217        (JSC::VMTraps::handleTraps):
     218        * tools/VMInspector.cpp:
     219        (JSC::VMInspector::codeBlockForMachinePC):
     220        (JSC::VMInspector::isValidCodeBlock):
     221
    12222018-01-09  Michael Saboff  <[email protected]>
    2223
  • trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj

    r226407 r226667  
    344344                0F5EF91F16878F7D003E5C25 /* JITThunks.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F5EF91C16878F78003E5C25 /* JITThunks.h */; settings = {ATTRIBUTES = (Private, ); }; };
    345345                0F5F08CF146C7633000472A9 /* UnconditionalFinalizer.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F5F08CE146C762F000472A9 /* UnconditionalFinalizer.h */; settings = {ATTRIBUTES = (Private, ); }; };
     346                0F60FE901FFC37020003320A /* ExecutableToCodeBlockEdge.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F60FE8E1FFC36FD0003320A /* ExecutableToCodeBlockEdge.h */; settings = {ATTRIBUTES = (Private, ); }; };
    346347                0F61832A1C45BF070072450B /* AirCCallingConvention.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F6183211C45BF070072450B /* AirCCallingConvention.h */; };
    347348                0F61832D1C45BF070072450B /* AirEmitShuffle.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F6183241C45BF070072450B /* AirEmitShuffle.h */; };
     
    23392340                0F5EF91C16878F78003E5C25 /* JITThunks.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JITThunks.h; sourceTree = "<group>"; };
    23402341                0F5F08CE146C762F000472A9 /* UnconditionalFinalizer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UnconditionalFinalizer.h; sourceTree = "<group>"; };
     2342                0F60FE8D1FFC36FC0003320A /* ExecutableToCodeBlockEdge.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ExecutableToCodeBlockEdge.cpp; sourceTree = "<group>"; };
     2343                0F60FE8E1FFC36FD0003320A /* ExecutableToCodeBlockEdge.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ExecutableToCodeBlockEdge.h; sourceTree = "<group>"; };
    23412344                0F6183201C45BF070072450B /* AirCCallingConvention.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = AirCCallingConvention.cpp; path = b3/air/AirCCallingConvention.cpp; sourceTree = "<group>"; };
    23422345                0F6183211C45BF070072450B /* AirCCallingConvention.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AirCCallingConvention.h; path = b3/air/AirCCallingConvention.h; sourceTree = "<group>"; };
     
    75237526                                14AD91061DCA92940014F9FE /* EvalCodeBlock.h */,
    75247527                                14142E521B796EDD00F4BF4B /* ExecutableInfo.h */,
     7528                                0F60FE8D1FFC36FC0003320A /* ExecutableToCodeBlockEdge.cpp */,
     7529                                0F60FE8E1FFC36FD0003320A /* ExecutableToCodeBlockEdge.h */,
    75257530                                0F56A1D415001CF2002992B1 /* ExecutionCounter.cpp */,
    75267531                                0F56A1D115000F31002992B1 /* ExecutionCounter.h */,
     
    83198324                                BC18C3F30E16F5CD00B34460 /* CommonIdentifiers.h in Headers */,
    83208325                                0F15F15F14B7A73E005DE37D /* CommonSlowPaths.h in Headers */,
     8326                                0F60FE901FFC37020003320A /* ExecutableToCodeBlockEdge.h in Headers */,
    83218327                                6553A33217A1F1EE008CF6F3 /* CommonSlowPathsExceptions.h in Headers */,
    83228328                                0FD82E39141AB14D00179C94 /* CompactJITCodeMap.h in Headers */,
  • trunk/Source/JavaScriptCore/Sources.txt

    r226407 r226667  
    211211bytecode/DirectEvalCodeCache.cpp
    212212bytecode/EvalCodeBlock.cpp
     213bytecode/ExecutableToCodeBlockEdge.cpp
    213214bytecode/ExecutionCounter.cpp
    214215bytecode/ExitKind.cpp
  • trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp

    r226556 r226667  
    5252#include "InlineCallFrame.h"
    5353#include "InterpreterInlines.h"
     54#include "IsoCellSetInlines.h"
    5455#include "JIT.h"
    5556#include "JITMathIC.h"
     
    330331    , m_reoptimizationRetryCounter(0)
    331332    , m_creationTime(MonotonicTime::now())
    332     , m_unconditionalFinalizer(makePoisonedUnique<UnconditionalFinalizer>(*this))
    333     , m_weakReferenceHarvester(makePoisonedUnique<WeakReferenceHarvester>(*this))
    334 {
    335     m_visitWeaklyHasBeenCalled = false;
    336 
     333{
    337334    ASSERT(heap()->isDeferred());
    338335    ASSERT(m_scopeRegister.isLocal());
    339336
    340337    setNumParameters(other.numParameters());
     338   
     339    vm->heap.codeBlockSet().add(this);
    341340}
    342341
     
    344343{
    345344    Base::finishCreation(vm);
     345    finishCreationCommon(vm);
    346346
    347347    optimizeAfterWarmUp();
     
    355355        m_rareData->m_stringSwitchJumpTables = other.m_rareData->m_stringSwitchJumpTables;
    356356    }
    357    
    358     heap()->m_codeBlocks->add(this);
    359357}
    360358
     
    390388    , m_reoptimizationRetryCounter(0)
    391389    , m_creationTime(MonotonicTime::now())
    392     , m_unconditionalFinalizer(makePoisonedUnique<UnconditionalFinalizer>(*this))
    393     , m_weakReferenceHarvester(makePoisonedUnique<WeakReferenceHarvester>(*this))
    394 {
    395     m_visitWeaklyHasBeenCalled = false;
    396 
     390{
    397391    ASSERT(heap()->isDeferred());
    398392    ASSERT(m_scopeRegister.isLocal());
     
    400394    ASSERT(m_source);
    401395    setNumParameters(unlinkedCodeBlock->numParameters());
     396   
     397    vm->heap.codeBlockSet().add(this);
    402398}
    403399
     
    414410{
    415411    Base::finishCreation(vm);
     412    finishCreationCommon(vm);
    416413
    417414    auto throwScope = DECLARE_THROW_SCOPE(vm);
     
    850847        dumpBytecode();
    851848
    852     heap()->m_codeBlocks->add(this);
    853849    heap()->reportExtraMemoryAllocated(m_instructions.size() * sizeof(Instruction));
    854850
     
    856852}
    857853
     854void CodeBlock::finishCreationCommon(VM& vm)
     855{
     856    m_ownerEdge.set(vm, this, ExecutableToCodeBlockEdge::create(vm, this));
     857}
     858
    858859CodeBlock::~CodeBlock()
    859860{
    860861    VM& vm = *m_poisonedVM;
     862
     863    vm.heap.codeBlockSet().remove(this);
     864   
    861865    if (UNLIKELY(vm.m_perBytecodeProfiler))
    862866        vm.m_perBytecodeProfiler->notifyDestruction(this);
    863867
    864     if (unlinkedCodeBlock()->didOptimize() == MixedTriState)
     868    if (!vm.heap.isShuttingDown() && unlinkedCodeBlock()->didOptimize() == MixedTriState)
    865869        unlinkedCodeBlock()->setDidOptimize(FalseTriState);
    866870
     
    976980}
    977981
    978 void CodeBlock::visitWeakly(SlotVisitor& visitor)
    979 {
    980     ConcurrentJSLocker locker(m_lock);
    981     if (m_visitWeaklyHasBeenCalled)
    982         return;
    983    
    984     m_visitWeaklyHasBeenCalled = true;
    985 
    986     if (Heap::isMarked(this))
    987         return;
    988 
    989     if (shouldVisitStrongly(locker)) {
    990         visitor.appendUnbarriered(this);
    991         return;
    992     }
    993    
    994     // There are two things that may use unconditional finalizers: inline cache clearing
    995     // and jettisoning. The probability of us wanting to do at least one of those things
    996     // is probably quite close to 1. So we add one no matter what and when it runs, it
    997     // figures out whether it has any work to do.
    998     visitor.addUnconditionalFinalizer(m_unconditionalFinalizer.get());
    999 
    1000     if (!JITCode::isOptimizingJIT(jitType()))
    1001         return;
    1002 
    1003     // If we jettison ourselves we'll install our alternative, so make sure that it
    1004     // survives GC even if we don't.
    1005     visitor.append(m_alternative);
    1006    
    1007     // There are two things that we use weak reference harvesters for: DFG fixpoint for
    1008     // jettisoning, and trying to find structures that would be live based on some
    1009     // inline cache. So it makes sense to register them regardless.
    1010     visitor.addWeakReferenceHarvester(m_weakReferenceHarvester.get());
    1011 
    1012 #if ENABLE(DFG_JIT)
    1013     // We get here if we're live in the sense that our owner executable is live,
    1014     // but we're not yet live for sure in another sense: we may yet decide that this
    1015     // code block should be jettisoned based on its outgoing weak references being
    1016     // stale. Set a flag to indicate that we're still assuming that we're dead, and
    1017     // perform one round of determining if we're live. The GC may determine, based on
    1018     // either us marking additional objects, or by other objects being marked for
    1019     // other reasons, that this iteration should run again; it will notify us of this
    1020     // decision by calling harvestWeakReferences().
    1021 
    1022     m_allTransitionsHaveBeenMarked = false;
    1023     propagateTransitions(locker, visitor);
    1024 
    1025     m_jitCode->dfgCommon()->livenessHasBeenProved = false;
    1026     determineLiveness(locker, visitor);
    1027 #endif // ENABLE(DFG_JIT)
    1028 }
    1029 
    1030982size_t CodeBlock::estimatedSize(JSCell* cell)
    1031983{
     
    1042994    ASSERT_GC_OBJECT_INHERITS(thisObject, info());
    1043995    JSCell::visitChildren(thisObject, visitor);
     996    visitor.append(thisObject->m_ownerEdge);
    1044997    thisObject->visitChildren(visitor);
    1045998}
     
    10481001{
    10491002    ConcurrentJSLocker locker(m_lock);
    1050     // There are two things that may use unconditional finalizers: inline cache clearing
    1051     // and jettisoning. The probability of us wanting to do at least one of those things
    1052     // is probably quite close to 1. So we add one no matter what and when it runs, it
    1053     // figures out whether it has any work to do.
    1054     visitor.addUnconditionalFinalizer(m_unconditionalFinalizer.get());
    1055 
    10561003    if (CodeBlock* otherBlock = specialOSREntryBlockOrNull())
    10571004        visitor.appendUnbarriered(otherBlock);
     
    10721019    stronglyVisitStrongReferences(locker, visitor);
    10731020    stronglyVisitWeakReferences(locker, visitor);
    1074 
    1075     m_allTransitionsHaveBeenMarked = false;
    1076     propagateTransitions(locker, visitor);
     1021   
     1022    VM::SpaceAndFinalizerSet::finalizerSetFor(*subspace()).add(this);
    10771023}
    10781024
     
    11651111    UNUSED_PARAM(visitor);
    11661112
    1167     if (m_allTransitionsHaveBeenMarked)
    1168         return;
    1169 
    11701113    VM& vm = *m_poisonedVM;
    1171     bool allAreMarkedSoFar = true;
    1172        
     1114
    11731115    if (jitType() == JITCode::InterpreterThunk) {
    11741116        const Vector<unsigned>& propertyAccessInstructions = m_unlinkedCode->propertyAccessInstructions();
     
    11871129                if (Heap::isMarked(oldStructure))
    11881130                    visitor.appendUnbarriered(newStructure);
    1189                 else
    1190                     allAreMarkedSoFar = false;
    11911131                break;
    11921132            }
     
    12001140    if (JITCode::isJIT(jitType())) {
    12011141        for (auto iter = m_stubInfos.begin(); !!iter; ++iter)
    1202             allAreMarkedSoFar &= (*iter)->propagateTransitions(visitor);
     1142            (*iter)->propagateTransitions(visitor);
    12031143    }
    12041144#endif // ENABLE(JIT)
     
    12081148        DFG::CommonData* dfgCommon = m_jitCode->dfgCommon();
    12091149        for (auto& weakReference : dfgCommon->weakStructureReferences)
    1210             allAreMarkedSoFar &= weakReference->markIfCheap(visitor);
     1150            weakReference->markIfCheap(visitor);
    12111151
    12121152        for (auto& transition : dfgCommon->transitions) {
     
    12321172
    12331173                visitor.append(transition.m_to);
    1234             } else
    1235                 allAreMarkedSoFar = false;
     1174            }
    12361175        }
    12371176    }
    12381177#endif // ENABLE(DFG_JIT)
    1239    
    1240     if (allAreMarkedSoFar)
    1241         m_allTransitionsHaveBeenMarked = true;
    12421178}
    12431179
     
    12471183   
    12481184#if ENABLE(DFG_JIT)
    1249     // Check if we have any remaining work to do.
     1185    if (Heap::isMarked(this))
     1186        return;
     1187   
     1188    // In rare and weird cases, this could be called on a baseline CodeBlock. One that I found was
     1189    // that we might decide that the CodeBlock should be jettisoned due to old age, so the
     1190    // isMarked check doesn't protect us.
     1191    if (!JITCode::isOptimizingJIT(jitType()))
     1192        return;
     1193   
    12501194    DFG::CommonData* dfgCommon = m_jitCode->dfgCommon();
    1251     if (dfgCommon->livenessHasBeenProved)
    1252         return;
    1253    
    12541195    // Now check all of our weak references. If all of them are live, then we
    12551196    // have proved liveness and so we scan our strong references. If at end of
     
    12801221    // All weak references are live. Record this information so we don't
    12811222    // come back here again, and scan the strong references.
    1282     dfgCommon->livenessHasBeenProved = true;
    12831223    visitor.appendUnbarriered(this);
    12841224#endif // ENABLE(DFG_JIT)
    1285 }
    1286 
    1287 void CodeBlock::WeakReferenceHarvester::visitWeakReferences(SlotVisitor& visitor)
    1288 {
    1289     codeBlock.propagateTransitions(NoLockingNecessary, visitor);
    1290     codeBlock.determineLiveness(NoLockingNecessary, visitor);
    12911225}
    12921226
     
    14221356}
    14231357
    1424 void CodeBlock::UnconditionalFinalizer::finalizeUnconditionally()
    1425 {
    1426     codeBlock.updateAllPredictions();
    1427    
    1428     if (!Heap::isMarked(&codeBlock)) {
    1429         if (codeBlock.shouldJettisonDueToWeakReference())
    1430             codeBlock.jettison(Profiler::JettisonDueToWeakReference);
    1431         else
    1432             codeBlock.jettison(Profiler::JettisonDueToOldAge);
    1433         return;
    1434     }
    1435 
    1436     if (JITCode::couldBeInterpreted(codeBlock.jitType()))
    1437         codeBlock.finalizeLLIntInlineCaches();
     1358void CodeBlock::finalizeUnconditionally(VM&)
     1359{
     1360    updateAllPredictions();
     1361   
     1362    if (JITCode::couldBeInterpreted(jitType()))
     1363        finalizeLLIntInlineCaches();
    14381364
    14391365#if ENABLE(JIT)
    1440     if (!!codeBlock.jitCode())
    1441         codeBlock.finalizeBaselineJITInlineCaches();
    1442 #endif
     1366    if (!!jitCode())
     1367        finalizeBaselineJITInlineCaches();
     1368#endif
     1369
     1370    VM::SpaceAndFinalizerSet::finalizerSetFor(*subspace()).remove(this);
    14431371}
    14441372
     
    15941522   
    15951523    visitor.append(m_globalObject);
    1596     visitor.append(m_ownerExecutable);
     1524    visitor.append(m_ownerExecutable); // This is extra important since it causes the ExecutableToCodeBlockEdge to be marked.
    15971525    visitor.append(m_unlinkedCode);
    15981526    if (m_rareData)
     
    31333061{
    31343062#if ENABLE(SIGNAL_BASED_VM_TRAPS)
    3135    
    31363063    // This function may be called from a signal handler. We need to be
    31373064    // careful to not call anything that is not signal handler safe, e.g.
     
    31533080    if (!JITCode::isOptimizingJIT(jitType()))
    31543081        return false;
    3155     m_jitCode->dfgCommon()->installVMTrapBreakpoints(this);
     3082    auto& commonData = *m_jitCode->dfgCommon();
     3083    commonData.installVMTrapBreakpoints(this);
    31563084    return true;
    31573085#else
     
    31933121            totalSubSize += subIC->codeSize();
    31943122        }
    3195 
    3196         return false;
    31973123    };
    31983124    heap()->forEachCodeBlock(countICs);
  • trunk/Source/JavaScriptCore/bytecode/CodeBlock.h

    r226556 r226667  
    8888class CodeBlockSet;
    8989class ExecState;
     90class ExecutableToCodeBlockEdge;
    9091class JSModuleEnvironment;
    9192class LLIntOffsetsExtractor;
     
    108109    friend class LLIntOffsetsExtractor;
    109110
    110     struct UnconditionalFinalizer : public JSC::UnconditionalFinalizer {
    111         UnconditionalFinalizer(CodeBlock& codeBlock)
    112             : codeBlock(codeBlock)
    113         { }
    114         void finalizeUnconditionally() override;
    115         CodeBlock& codeBlock;
    116     };
    117 
    118     struct WeakReferenceHarvester : public JSC::WeakReferenceHarvester {
    119         WeakReferenceHarvester(CodeBlock& codeBlock)
    120             : codeBlock(codeBlock)
    121         { }
    122         void visitWeakReferences(SlotVisitor&) override;
    123         CodeBlock& codeBlock;
    124     };
    125 
    126111public:
    127112
     
    129114
    130115    static const unsigned StructureFlags = Base::StructureFlags | StructureIsImmortal;
     116    static const bool needsDestruction = true;
     117
     118    template<typename>
     119    static void subspaceFor(VM&) { }
    131120
    132121    DECLARE_INFO;
     
    138127    void finishCreation(VM&, CopyParsedBlockTag, CodeBlock& other);
    139128    bool finishCreation(VM&, ScriptExecutable* ownerExecutable, UnlinkedCodeBlock*, JSScope*);
     129   
     130    void finishCreationCommon(VM&);
    140131
    141132    WriteBarrier<JSGlobalObject> m_globalObject;
     
    201192    static void visitChildren(JSCell*, SlotVisitor&);
    202193    void visitChildren(SlotVisitor&);
    203     void visitWeakly(SlotVisitor&);
    204     void clearVisitWeaklyHasBeenCalled();
     194    void finalizeUnconditionally(VM&);
    205195
    206196    void dumpSource();
     
    370360    ExecutableBase* ownerExecutable() const { return m_ownerExecutable.get(); }
    371361    ScriptExecutable* ownerScriptExecutable() const { return jsCast<ScriptExecutable*>(m_ownerExecutable.get()); }
     362   
     363    ExecutableToCodeBlockEdge* ownerEdge() const { return m_ownerEdge.get(); }
    372364
    373365    VM* vm() const { return m_poisonedVM.unpoisoned(); }
     
    830822    mutable ConcurrentJSLock m_lock;
    831823
    832     bool m_visitWeaklyHasBeenCalled;
    833 
    834824    bool m_shouldAlwaysBeInlined; // Not a bitfield because the JIT wants to store to it.
    835825
     
    919909private:
    920910    friend class CodeBlockSet;
     911    friend class ExecutableToCodeBlockEdge;
    921912
    922913    BytecodeLivenessAnalysis& livenessAnalysisSlow();
     
    983974    };
    984975    WriteBarrier<ExecutableBase> m_ownerExecutable;
     976    WriteBarrier<ExecutableToCodeBlockEdge> m_ownerEdge;
    985977    ConstExprPoisoned<CodeBlockPoison, VM*> m_poisonedVM;
    986978
     
    10471039
    10481040    std::unique_ptr<RareData> m_rareData;
    1049 
    1050     PoisonedUniquePtr<CodeBlockPoison, UnconditionalFinalizer> m_unconditionalFinalizer;
    1051     PoisonedUniquePtr<CodeBlockPoison, WeakReferenceHarvester> m_weakReferenceHarvester;
    10521041};
    10531042
     
    10741063{
    10751064    return uncheckedR(reg.offset());
    1076 }
    1077 
    1078 inline void CodeBlock::clearVisitWeaklyHasBeenCalled()
    1079 {
    1080     m_visitWeaklyHasBeenCalled = false;
    10811065}
    10821066
  • trunk/Source/JavaScriptCore/bytecode/EvalCodeBlock.h

    r215984 r226667  
    3434namespace JSC {
    3535
    36 class EvalCodeBlock : public GlobalCodeBlock {
     36class EvalCodeBlock final : public GlobalCodeBlock {
    3737public:
    3838    typedef GlobalCodeBlock Base;
    3939    DECLARE_INFO;
     40
     41    template<typename>
     42    static IsoSubspace* subspaceFor(VM& vm)
     43    {
     44        return &vm.evalCodeBlockSpace.space;
     45    }
    4046
    4147    static EvalCodeBlock* create(VM* vm, CopyParsedBlockTag, EvalCodeBlock& other)
     
    5965    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
    6066    {
    61         return Structure::create(vm, globalObject, prototype, TypeInfo(CellType, StructureFlags), info());
     67        return Structure::create(vm, globalObject, prototype, TypeInfo(CodeBlockType, StructureFlags), info());
    6268    }
    6369
  • trunk/Source/JavaScriptCore/bytecode/FunctionCodeBlock.h

    r213697 r226667  
    4040    DECLARE_INFO;
    4141
     42    template<typename>
     43    static IsoSubspace* subspaceFor(VM& vm)
     44    {
     45        return &vm.functionCodeBlockSpace.space;
     46    }
     47
    4248    static FunctionCodeBlock* create(VM* vm, CopyParsedBlockTag, FunctionCodeBlock& other)
    4349    {
     
    6066    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
    6167    {
    62         return Structure::create(vm, globalObject, prototype, TypeInfo(CellType, StructureFlags), info());
     68        return Structure::create(vm, globalObject, prototype, TypeInfo(CodeBlockType, StructureFlags), info());
    6369    }
    6470
  • trunk/Source/JavaScriptCore/bytecode/ModuleProgramCodeBlock.h

    r213697 r226667  
    3535namespace JSC {
    3636
    37 class ModuleProgramCodeBlock : public GlobalCodeBlock {
     37class ModuleProgramCodeBlock final : public GlobalCodeBlock {
    3838public:
    3939    typedef GlobalCodeBlock Base;
    4040    DECLARE_INFO;
     41
     42    template<typename>
     43    static IsoSubspace* subspaceFor(VM& vm)
     44    {
     45        return &vm.moduleProgramCodeBlockSpace.space;
     46    }
    4147
    4248    static ModuleProgramCodeBlock* create(VM* vm, CopyParsedBlockTag, ModuleProgramCodeBlock& other)
     
    6066    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
    6167    {
    62         return Structure::create(vm, globalObject, prototype, TypeInfo(CellType, StructureFlags), info());
     68        return Structure::create(vm, globalObject, prototype, TypeInfo(CodeBlockType, StructureFlags), info());
    6369    }
    6470
  • trunk/Source/JavaScriptCore/bytecode/ProgramCodeBlock.h

    r213697 r226667  
    3535namespace JSC {
    3636
    37 class ProgramCodeBlock : public GlobalCodeBlock {
     37class ProgramCodeBlock final : public GlobalCodeBlock {
    3838public:
    3939    typedef GlobalCodeBlock Base;
    4040    DECLARE_INFO;
     41
     42    template<typename>
     43    static IsoSubspace* subspaceFor(VM& vm)
     44    {
     45        return &vm.programCodeBlockSpace.space;
     46    }
    4147
    4248    static ProgramCodeBlock* create(VM* vm, CopyParsedBlockTag, ProgramCodeBlock& other)
     
    6066    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
    6167    {
    62         return Structure::create(vm, globalObject, prototype, TypeInfo(CellType, StructureFlags), info());
     68        return Structure::create(vm, globalObject, prototype, TypeInfo(CodeBlockType, StructureFlags), info());
    6369    }
    6470
  • trunk/Source/JavaScriptCore/debugger/Debugger.cpp

    r223738 r226667  
    208208    }
    209209
    210     bool operator()(CodeBlock* codeBlock) const
     210    void operator()(CodeBlock* codeBlock) const
    211211    {
    212212        if (m_debugger == codeBlock->globalObject()->debugger()) {
     
    216216                codeBlock->setSteppingMode(CodeBlock::SteppingModeDisabled);
    217217        }
    218         return false;
    219218    }
    220219
     
    316315    }
    317316
    318     bool operator()(CodeBlock* codeBlock) const
     317    void operator()(CodeBlock* codeBlock) const
    319318    {
    320319        if (m_debugger == codeBlock->globalObject()->debugger())
    321320            m_debugger->toggleBreakpoint(codeBlock, m_breakpoint, m_enabledOrNot);
    322         return false;
    323321    }
    324322
     
    529527    }
    530528
    531     bool operator()(CodeBlock* codeBlock) const
     529    void operator()(CodeBlock* codeBlock) const
    532530    {
    533531        if (codeBlock->hasDebuggerRequests() && m_debugger == codeBlock->globalObject()->debugger())
    534532            codeBlock->clearDebuggerRequests();
    535         return false;
    536533    }
    537534
     
    559556    }
    560557
    561     bool operator()(CodeBlock* codeBlock) const
     558    void operator()(CodeBlock* codeBlock) const
    562559    {
    563560        if (codeBlock->hasDebuggerRequests() && m_globalObject == codeBlock->globalObject())
    564561            codeBlock->clearDebuggerRequests();
    565         return false;
    566562    }
    567563
  • trunk/Source/JavaScriptCore/heap/CodeBlockSet.cpp

    r225315 r226667  
    4242}
    4343
    44 void CodeBlockSet::add(CodeBlock* codeBlock)
    45 {
    46     LockHolder locker(&m_lock);
    47     bool isNewEntry = m_newCodeBlocks.add(codeBlock).isNewEntry;
    48     ASSERT_UNUSED(isNewEntry, isNewEntry);
    49 }
    50 
    51 void CodeBlockSet::promoteYoungCodeBlocks(const AbstractLocker&)
    52 {
    53     ASSERT(m_lock.isLocked());
    54     m_oldCodeBlocks.add(m_newCodeBlocks.begin(), m_newCodeBlocks.end());
    55     m_newCodeBlocks.clear();
    56 }
    57 
    58 void CodeBlockSet::clearMarksForFullCollection()
    59 {
    60     LockHolder locker(&m_lock);
    61     for (CodeBlock* codeBlock : m_oldCodeBlocks)
    62         codeBlock->clearVisitWeaklyHasBeenCalled();
    63 }
    64 
    65 void CodeBlockSet::lastChanceToFinalize(VM& vm)
    66 {
    67     LockHolder locker(&m_lock);
    68     for (CodeBlock* codeBlock : m_newCodeBlocks)
    69         codeBlock->structure(vm)->classInfo()->methodTable.destroy(codeBlock);
    70 
    71     for (CodeBlock* codeBlock : m_oldCodeBlocks)
    72         codeBlock->structure(vm)->classInfo()->methodTable.destroy(codeBlock);
    73 }
    74 
    75 void CodeBlockSet::deleteUnmarkedAndUnreferenced(VM& vm, CollectionScope scope)
    76 {
    77     LockHolder locker(&m_lock);
    78    
    79     // Destroying a CodeBlock takes about 1us on average in Speedometer. Full collections in Speedometer
    80     // usually have ~2000 CodeBlocks to process. The time it takes to process the whole list varies a
    81     // lot. In one extreme case I saw 18ms (on my fast MBP).
    82     //
    83     // FIXME: use Subspace instead of HashSet and adopt Subspace-based constraint solving. This may
    84     // remove the need to eagerly destruct CodeBlocks.
    85     // https://bugs.webkit.org/show_bug.cgi?id=180089
    86     //
    87     // FIXME: make CodeBlock::~CodeBlock a lot faster. It seems insane for that to take 1us or more.
    88     // https://bugs.webkit.org/show_bug.cgi?id=180109
    89    
    90     auto consider = [&] (HashSet<CodeBlock*>& set) {
    91         set.removeIf(
    92             [&] (CodeBlock* codeBlock) -> bool {
    93                 if (Heap::isMarked(codeBlock))
    94                     return false;
    95                 codeBlock->structure(vm)->classInfo()->methodTable.destroy(codeBlock);
    96                 return true;
    97             });
    98     };
    99 
    100     switch (scope) {
    101     case CollectionScope::Eden:
    102         consider(m_newCodeBlocks);
    103         break;
    104     case CollectionScope::Full:
    105         consider(m_oldCodeBlocks);
    106         consider(m_newCodeBlocks);
    107         break;
    108     }
    109 
    110     // Any remaining young CodeBlocks are live and need to be promoted to the set of old CodeBlocks.
    111     promoteYoungCodeBlocks(locker);
    112 }
    113 
    11444bool CodeBlockSet::contains(const AbstractLocker&, void* candidateCodeBlock)
    11545{
     
    11848    if (!HashSet<CodeBlock*>::isValidValue(codeBlock))
    11949        return false;
    120     return m_oldCodeBlocks.contains(codeBlock) || m_newCodeBlocks.contains(codeBlock) || m_currentlyExecuting.contains(codeBlock);
     50    return m_codeBlocks.contains(codeBlock);
    12151}
    12252
     
    12959{
    13060    CommaPrinter comma;
    131     out.print("{old = [");
    132     for (CodeBlock* codeBlock : m_oldCodeBlocks)
    133         out.print(comma, pointerDump(codeBlock));
    134     out.print("], new = [");
    135     comma = CommaPrinter();
    136     for (CodeBlock* codeBlock : m_newCodeBlocks)
     61    out.print("{codeBlocks = [");
     62    for (CodeBlock* codeBlock : m_codeBlocks)
    13763        out.print(comma, pointerDump(codeBlock));
    13864    out.print("], currentlyExecuting = [");
     
    14369}
    14470
     71void CodeBlockSet::add(CodeBlock* codeBlock)
     72{
     73    auto locker = holdLock(m_lock);
     74    auto result = m_codeBlocks.add(codeBlock);
     75    RELEASE_ASSERT(result);
     76}
     77
     78void CodeBlockSet::remove(CodeBlock* codeBlock)
     79{
     80    auto locker = holdLock(m_lock);
     81    bool result = m_codeBlocks.remove(codeBlock);
     82    RELEASE_ASSERT(result);
     83}
     84
    14585} // namespace JSC
    14686
  • trunk/Source/JavaScriptCore/heap/CodeBlockSet.h

    r218794 r226667  
    5050    ~CodeBlockSet();
    5151
    52     void lastChanceToFinalize(VM&);
    53    
    54     // Add a CodeBlock. This is only called by CodeBlock constructors.
    55     void add(CodeBlock*);
    56    
    57     // Clear all mark bits for all CodeBlocks.
    58     void clearMarksForFullCollection();
    59 
    60     // Mark a pointer that may be a CodeBlock that belongs to the set of DFG
    61     // blocks. This is defined in CodeBlock.h.
    62 private:
    6352    void mark(const AbstractLocker&, CodeBlock* candidateCodeBlock);
    64 public:
    65     void mark(const AbstractLocker&, void* candidateCodeBlock);
    66    
    67     // Delete all code blocks that are only referenced by this set (i.e. owned
    68     // by this set), and that have not been marked.
    69     void deleteUnmarkedAndUnreferenced(VM&, CollectionScope);
    7053   
    7154    void clearCurrentlyExecuting();
     
    7962    template<typename Functor> void iterate(const Functor&);
    8063    template<typename Functor> void iterate(const AbstractLocker&, const Functor&);
     64
     65    template<typename Functor> void iterateViaSubspaces(VM&, const Functor&);
    8166   
    8267    template<typename Functor> void iterateCurrentlyExecuting(const Functor&);
    8368   
    8469    void dump(PrintStream&) const;
     70   
     71    void add(CodeBlock*);
     72    void remove(CodeBlock*);
    8573
    8674private:
    87     void promoteYoungCodeBlocks(const AbstractLocker&);
    88 
    89     HashSet<CodeBlock*> m_oldCodeBlocks;
    90     HashSet<CodeBlock*> m_newCodeBlocks;
     75    HashSet<CodeBlock*> m_codeBlocks;
    9176    HashSet<CodeBlock*> m_currentlyExecuting;
    9277    Lock m_lock;
  • trunk/Source/JavaScriptCore/heap/CodeBlockSetInlines.h

    r213657 r226667  
    3434namespace JSC {
    3535
    36 inline void CodeBlockSet::mark(const AbstractLocker& locker, void* candidateCodeBlock)
    37 {
    38     ASSERT(m_lock.isLocked());
    39     // We have to check for 0 and -1 because those are used by the HashMap as markers.
    40     uintptr_t value = reinterpret_cast<uintptr_t>(candidateCodeBlock);
    41    
    42     // This checks for both of those nasty cases in one go.
    43     // 0 + 1 = 1
    44     // -1 + 1 = 0
    45     if (value + 1 <= 1)
    46         return;
    47 
    48     CodeBlock* codeBlock = static_cast<CodeBlock*>(candidateCodeBlock);
    49     if (!m_oldCodeBlocks.contains(codeBlock) && !m_newCodeBlocks.contains(codeBlock))
    50         return;
    51 
    52     mark(locker, codeBlock);
    53 }
    54 
    5536inline void CodeBlockSet::mark(const AbstractLocker&, CodeBlock* codeBlock)
    5637{
     
    7152void CodeBlockSet::iterate(const AbstractLocker&, const Functor& functor)
    7253{
    73     for (auto& codeBlock : m_oldCodeBlocks) {
    74         bool done = functor(codeBlock);
    75         if (done)
    76             return;
    77     }
    78    
    79     for (auto& codeBlock : m_newCodeBlocks) {
    80         bool done = functor(codeBlock);
    81         if (done)
    82             return;
    83     }
     54    for (CodeBlock* codeBlock : m_codeBlocks)
     55        functor(codeBlock);
     56}
     57
     58template<typename Functor>
     59void CodeBlockSet::iterateViaSubspaces(VM& vm, const Functor& functor)
     60{
     61    vm.forEachCodeBlockSpace(
     62        [&] (IsoSubspace& space) {
     63            space.forEachLiveCell(
     64                [&] (HeapCell* cell, HeapCell::Kind) {
     65                    functor(jsCast<CodeBlock*>(static_cast<JSCell*>(cell)));
     66                });
     67        });
    8468}
    8569
  • trunk/Source/JavaScriptCore/heap/ConservativeRoots.cpp

    r225524 r226667  
    7373    HeapUtil::findGCObjectPointersForMarking(
    7474        m_heap, markingVersion, newlyAllocatedVersion, filter, p,
    75         [&] (void* p) {
     75        [&] (void* p, HeapCell::Kind cellKind) {
     76            if (cellKind == HeapCell::JSCell)
     77                markHook.markKnownJSCell(static_cast<JSCell*>(p));
     78           
    7679            if (m_size == m_capacity)
    7780                grow();
     
    104107public:
    105108    void mark(void*) { }
     109    void markKnownJSCell(JSCell*) { }
    106110};
    107111
     
    110114    DummyMarkHook dummy;
    111115    genericAddSpan(begin, end, dummy);
    112 }
    113 
    114 void ConservativeRoots::add(void* begin, void* end, JITStubRoutineSet& jitStubRoutines)
    115 {
    116     genericAddSpan(begin, end, jitStubRoutines);
    117116}
    118117
     
    129128    {
    130129        m_stubRoutines.mark(address);
    131         m_codeBlocks.mark(m_codeBlocksLocker, address);
     130    }
     131   
     132    void markKnownJSCell(JSCell* cell)
     133    {
     134        if (cell->type() == CodeBlockType)
     135            m_codeBlocks.mark(m_codeBlocksLocker, jsCast<CodeBlock*>(cell));
    132136    }
    133137
  • trunk/Source/JavaScriptCore/heap/ConservativeRoots.h

    r225524 r226667  
    4040
    4141    void add(void* begin, void* end);
    42     void add(void* begin, void* end, JITStubRoutineSet&);
    4342    void add(void* begin, void* end, JITStubRoutineSet&, CodeBlockSet&);
    4443   
  • trunk/Source/JavaScriptCore/heap/Heap.cpp

    r226437 r226667  
    11/*
    2  *  Copyright (C) 2003-2017 Apple Inc. All rights reserved.
     2 *  Copyright (C) 2003-2018 Apple Inc. All rights reserved.
    33 *  Copyright (C) 2007 Eric Seidel <[email protected]>
    44 *
     
    368368    }
    369369   
     370    m_isShuttingDown = true;
     371   
    370372    RELEASE_ASSERT(!m_vm->entryScope);
    371373    RELEASE_ASSERT(m_mutatorState == MutatorState::Running);
     
    437439   
    438440    m_arrayBuffers.lastChanceToFinalize();
    439     m_codeBlocks->lastChanceToFinalize(*m_vm);
    440441    m_objectSpace.stopAllocating();
    441442    m_objectSpace.lastChanceToFinalize();
     
    559560
    560561template<typename CellType, typename CellSet>
    561 void Heap::finalizeUnconditionalFinalizers(CellSet& cellSet)
     562void Heap::finalizeMarkedUnconditionalFinalizers(CellSet& cellSet)
    562563{
    563564    cellSet.forEachMarkedCell(
     
    567568}
    568569
    569 template<typename CellType>
    570 void Heap::finalizeUnconditionalFinalizersInIsoSubspace()
    571 {
    572     JSC::subspaceFor<CellType>(*vm())->forEachMarkedCell(
    573         [&] (HeapCell* cell, HeapCell::Kind) {
    574             static_cast<CellType*>(cell)->finalizeUnconditionally(*vm());
     570void Heap::finalizeUnconditionalFinalizers()
     571{
     572    finalizeMarkedUnconditionalFinalizers<InferredType>(vm()->inferredTypesWithFinalizers);
     573    finalizeMarkedUnconditionalFinalizers<InferredValue>(vm()->inferredValuesWithFinalizers);
     574    vm()->forEachCodeBlockSpace(
     575        [&] (auto& space) {
     576            this->finalizeMarkedUnconditionalFinalizers<CodeBlock>(space.finalizerSet);
    575577        });
    576 }
    577 
    578 void Heap::finalizeUnconditionalFinalizers()
    579 {
    580     finalizeUnconditionalFinalizers<InferredType>(vm()->inferredTypesWithFinalizers);
    581     finalizeUnconditionalFinalizers<InferredValue>(vm()->inferredValuesWithFinalizers);
    582     finalizeUnconditionalFinalizersInIsoSubspace<JSWeakSet>();
    583     finalizeUnconditionalFinalizersInIsoSubspace<JSWeakMap>();
     578    finalizeMarkedUnconditionalFinalizers<ExecutableToCodeBlockEdge>(vm()->executableToCodeBlockEdgesWithFinalizers);
     579    finalizeMarkedUnconditionalFinalizers<JSWeakSet>(vm()->weakSetSpace);
     580    finalizeMarkedUnconditionalFinalizers<JSWeakMap>(vm()->weakMapSpace);
    584581   
    585582    while (m_unconditionalFinalizers.hasNext()) {
     
    678675{
    679676    TimingScope timingScope(*this, "Heap::beginMarking");
    680     if (m_collectionScope == CollectionScope::Full)
    681         m_codeBlocks->clearMarksForFullCollection();
    682677    m_jitStubRoutines->clearMarks();
    683678    m_objectSpace.beginMarking();
     
    940935{
    941936    clearUnmarkedExecutables();
    942     m_codeBlocks->deleteUnmarkedAndUnreferenced(*m_vm, *m_lastCollectionScope);
    943937    m_jitStubRoutines->deleteUnmarkedJettisonedStubRoutines();
    944938}
     
    20892083{
    20902084    m_objectSpace.sweepLargeAllocations();
    2091    
    2092     auto sweepBlock = [&] (MarkedBlock::Handle* handle) {
    2093         handle->sweep(nullptr);
    2094     };
    2095    
    2096     vm()->eagerlySweptDestructibleObjectSpace.forEachMarkedBlock(sweepBlock);
     2085    vm()->forEachCodeBlockSpace([] (auto& space) { space.space.sweep(); });
     2086    vm()->eagerlySweptDestructibleObjectSpace.sweep();
    20972087}
    20982088
     
    24692459}
    24702460
    2471 void Heap::forEachCodeBlockImpl(const ScopedLambda<bool(CodeBlock*)>& func)
     2461void Heap::forEachCodeBlockImpl(const ScopedLambda<void(CodeBlock*)>& func)
    24722462{
    24732463    // We don't know the full set of CodeBlocks until compilation has terminated.
     
    24772467}
    24782468
    2479 void Heap::forEachCodeBlockIgnoringJITPlansImpl(const AbstractLocker& locker, const ScopedLambda<bool(CodeBlock*)>& func)
     2469void Heap::forEachCodeBlockIgnoringJITPlansImpl(const AbstractLocker& locker, const ScopedLambda<void(CodeBlock*)>& func)
    24802470{
    24812471    return m_codeBlocks->iterate(locker, func);
     
    27132703        },
    27142704        ConstraintVolatility::GreyedByMarking);
     2705   
     2706    m_constraintSet->add(
     2707        "O", "Output",
     2708        [this] (SlotVisitor& slotVisitor) {
     2709            VM& vm = slotVisitor.vm();
     2710           
     2711            auto callOutputConstraint = [] (SlotVisitor& slotVisitor, HeapCell* heapCell, HeapCell::Kind) {
     2712                VM& vm = slotVisitor.vm();
     2713                JSCell* cell = static_cast<JSCell*>(heapCell);
     2714                cell->methodTable(vm)->visitOutputConstraints(cell, slotVisitor);
     2715            };
     2716           
     2717            auto add = [&] (auto& set) {
     2718                slotVisitor.addParallelConstraintTask(set.forEachMarkedCellInParallel(callOutputConstraint));
     2719            };
     2720           
     2721            add(vm.executableToCodeBlockEdgesWithConstraints);
     2722        },
     2723        ConstraintVolatility::GreyedByMarking,
     2724        ConstraintParallelism::Parallel);
    27152725   
    27162726#if ENABLE(DFG_JIT)
  • trunk/Source/JavaScriptCore/heap/Heap.h

    r226437 r226667  
    168168    void notifyIsSafeToCollect();
    169169    bool isSafeToCollect() const { return m_isSafeToCollect; }
     170   
     171    bool isShuttingDown() const { return m_isShuttingDown; }
    170172
    171173    JS_EXPORT_PRIVATE bool isHeapSnapshotting() const;
     
    497499
    498500    template<typename CellType, typename CellSet>
    499     void finalizeUnconditionalFinalizers(CellSet&);
    500 
    501     template<typename CellType>
    502     void finalizeUnconditionalFinalizersInIsoSubspace();
    503    
     501    void finalizeMarkedUnconditionalFinalizers(CellSet&);
     502
    504503    void finalizeUnconditionalFinalizers();
    505504   
     
    528527    size_t bytesVisited();
    529528   
    530     void forEachCodeBlockImpl(const ScopedLambda<bool(CodeBlock*)>&);
    531     void forEachCodeBlockIgnoringJITPlansImpl(const AbstractLocker& codeBlockSetLocker, const ScopedLambda<bool(CodeBlock*)>&);
     529    void forEachCodeBlockImpl(const ScopedLambda<void(CodeBlock*)>&);
     530    void forEachCodeBlockIgnoringJITPlansImpl(const AbstractLocker& codeBlockSetLocker, const ScopedLambda<void(CodeBlock*)>&);
    532531   
    533532    void setMutatorShouldBeFenced(bool value);
     
    610609   
    611610    bool m_isSafeToCollect;
     611    bool m_isShuttingDown { false };
    612612
    613613    bool m_mutatorShouldBeFenced { Options::forceFencedBarrier() };
  • trunk/Source/JavaScriptCore/heap/HeapCell.h

    r217429 r226667  
    3434class LargeAllocation;
    3535class MarkedBlock;
     36class Subspace;
    3637class VM;
    3738struct AllocatorAttributes;
     
    6970    DestructionMode destructionMode() const;
    7071    Kind cellKind() const;
     72    Subspace* subspace() const;
    7173   
    7274    // Call use() after the last point where you need `this` pointer to be kept alive. You usually don't
  • trunk/Source/JavaScriptCore/heap/HeapCellInlines.h

    r220322 r226667  
    9191}
    9292
     93ALWAYS_INLINE Subspace* HeapCell::subspace() const
     94{
     95    if (isLargeAllocation())
     96        return largeAllocation().subspace();
     97    return markedBlock().subspace();
     98}
     99
    93100} // namespace JSC
    94101
  • trunk/Source/JavaScriptCore/heap/HeapInlines.h

    r226437 r226667  
    145145template<typename Functor> inline void Heap::forEachCodeBlock(const Functor& func)
    146146{
    147     forEachCodeBlockImpl(scopedLambdaRef<bool(CodeBlock*)>(func));
     147    forEachCodeBlockImpl(scopedLambdaRef<void(CodeBlock*)>(func));
    148148}
    149149
    150150template<typename Functor> inline void Heap::forEachCodeBlockIgnoringJITPlans(const AbstractLocker& codeBlockSetLocker, const Functor& func)
    151151{
    152     forEachCodeBlockIgnoringJITPlansImpl(codeBlockSetLocker, scopedLambdaRef<bool(CodeBlock*)>(func));
     152    forEachCodeBlockIgnoringJITPlansImpl(codeBlockSetLocker, scopedLambdaRef<void(CodeBlock*)>(func));
    153153}
    154154
  • trunk/Source/JavaScriptCore/heap/HeapUtil.h

    r225524 r226667  
    6767                    [] (LargeAllocation** ptr) -> LargeAllocation* { return *ptr; });
    6868                if (result) {
    69                     if (result > heap.objectSpace().largeAllocationsForThisCollectionBegin()
    70                         && result[-1]->contains(pointer))
    71                         func(result[-1]->cell());
    72                     if (result[0]->contains(pointer))
    73                         func(result[0]->cell());
    74                     if (result + 1 < heap.objectSpace().largeAllocationsForThisCollectionEnd()
    75                         && result[1]->contains(pointer))
    76                         func(result[1]->cell());
     69                    auto attemptLarge = [&] (LargeAllocation* allocation) {
     70                        if (allocation->contains(pointer))
     71                            func(allocation->cell(), allocation->attributes().cellKind);
     72                    };
     73                   
     74                    if (result > heap.objectSpace().largeAllocationsForThisCollectionBegin())
     75                        attemptLarge(result[-1]);
     76                    attemptLarge(result[0]);
     77                    if (result + 1 < heap.objectSpace().largeAllocationsForThisCollectionEnd())
     78                        attemptLarge(result[1]);
    7779                }
    7880            }
     
    9092                previousPointer = static_cast<char*>(previousCandidate->handle().cellAlign(previousPointer));
    9193                if (previousCandidate->handle().isLiveCell(markingVersion, newlyAllocatedVersion, isMarking, previousPointer))
    92                     func(previousPointer);
     94                    func(previousPointer, previousCandidate->handle().cellKind());
    9395            }
    9496        }
     
    101103        if (!set.contains(candidate))
    102104            return;
     105
     106        HeapCell::Kind cellKind = candidate->handle().cellKind();
    103107       
    104108        auto tryPointer = [&] (void* pointer) {
    105109            if (candidate->handle().isLiveCell(markingVersion, newlyAllocatedVersion, isMarking, pointer))
    106                 func(pointer);
     110                func(pointer, cellKind);
    107111        };
    108112   
  • trunk/Source/JavaScriptCore/heap/IsoCellSet.cpp

    r225831 r226667  
    4545    if (isOnList())
    4646        BasicRawSentinelNode<IsoCellSet>::remove();
     47}
     48
     49RefPtr<SharedTask<MarkedBlock::Handle*()>> IsoCellSet::parallelNotEmptyMarkedBlockSource()
     50{
     51    class Task : public SharedTask<MarkedBlock::Handle*()> {
     52    public:
     53        Task(IsoCellSet& set)
     54            : m_set(set)
     55            , m_allocator(set.m_subspace.m_allocator)
     56        {
     57        }
     58       
     59        MarkedBlock::Handle* run() override
     60        {
     61            if (m_done)
     62                return nullptr;
     63            auto locker = holdLock(m_lock);
     64            auto bits = m_allocator.m_markingNotEmpty & m_set.m_blocksWithBits;
     65            m_index = bits.findBit(m_index, true);
     66            if (m_index >= m_allocator.m_blocks.size()) {
     67                m_done = true;
     68                return nullptr;
     69            }
     70            return m_allocator.m_blocks[m_index++];
     71        }
     72       
     73    private:
     74        IsoCellSet& m_set;
     75        MarkedAllocator& m_allocator;
     76        size_t m_index { 0 };
     77        Lock m_lock;
     78        bool m_done { false };
     79    };
     80   
     81    return adoptRef(new Task(*this));
    4782}
    4883
  • trunk/Source/JavaScriptCore/heap/IsoCellSet.h

    r225831 r226667  
    4949    bool contains(HeapCell* cell) const;
    5050   
     51    JS_EXPORT_PRIVATE RefPtr<SharedTask<MarkedBlock::Handle*()>> parallelNotEmptyMarkedBlockSource();
     52   
    5153    // This will have to do a combined search over whatever Subspace::forEachMarkedCell uses and
    5254    // our m_blocksWithBits.
    5355    template<typename Func>
    5456    void forEachMarkedCell(const Func&);
     57
     58    template<typename Func>
     59    RefPtr<SharedTask<void(SlotVisitor&)>> forEachMarkedCellInParallel(const Func&);
     60   
     61    template<typename Func>
     62    void forEachLiveCell(const Func&);
    5563   
    5664private:
  • trunk/Source/JavaScriptCore/heap/IsoCellSetInlines.h

    r225831 r226667  
    7979}
    8080
     81template<typename Func>
     82RefPtr<SharedTask<void(SlotVisitor&)>> IsoCellSet::forEachMarkedCellInParallel(const Func& func)
     83{
     84    class Task : public SharedTask<void(SlotVisitor&)> {
     85    public:
     86        Task(IsoCellSet& set, const Func& func)
     87            : m_set(set)
     88            , m_blockSource(set.parallelNotEmptyMarkedBlockSource())
     89            , m_func(func)
     90        {
     91        }
     92       
     93        void run(SlotVisitor& visitor) override
     94        {
     95            while (MarkedBlock::Handle* handle = m_blockSource->run()) {
     96                size_t blockIndex = handle->index();
     97                auto* bits = m_set.m_bits[blockIndex].get();
     98                handle->forEachMarkedCell(
     99                    [&] (size_t atomNumber, HeapCell* cell, HeapCell::Kind kind) -> IterationStatus {
     100                        if (bits->get(atomNumber))
     101                            m_func(visitor, cell, kind);
     102                        return IterationStatus::Continue;
     103                    });
     104            }
     105        }
     106       
     107    private:
     108        IsoCellSet& m_set;
     109        RefPtr<SharedTask<MarkedBlock::Handle*()>> m_blockSource;
     110        Func m_func;
     111        Lock m_lock;
     112    };
     113   
     114    return adoptRef(new Task(*this, func));
     115}
     116
     117template<typename Func>
     118void IsoCellSet::forEachLiveCell(const Func& func)
     119{
     120    MarkedAllocator& allocator = m_subspace.m_allocator;
     121    m_blocksWithBits.forEachSetBit(
     122        [&] (size_t blockIndex) {
     123            MarkedBlock::Handle* block = allocator.m_blocks[blockIndex];
     124
     125            // FIXME: We could optimize this by checking our bits before querying isLive.
     126            // OOPS! (need bug URL)
     127            auto* bits = m_bits[blockIndex].get();
     128            block->forEachLiveCell(
     129                [&] (size_t atomNumber, HeapCell* cell, HeapCell::Kind kind) -> IterationStatus {
     130                    if (bits->get(atomNumber))
     131                        func(cell, kind);
     132                    return IterationStatus::Continue;
     133                });
     134        });
     135}
     136
    81137} // namespace JSC
    82138
  • trunk/Source/JavaScriptCore/heap/LargeAllocation.h

    r225524 r226667  
    5858        return bitwise_cast<uintptr_t>(cell) & halfAlignment;
    5959    }
     60   
     61    Subspace* subspace() const { return m_subspace; }
    6062   
    6163    void lastChanceToFinalize();
  • trunk/Source/JavaScriptCore/heap/MarkStackMergingConstraint.cpp

    r225524 r226667  
    5555}
    5656
    57 ConstraintParallelism MarkStackMergingConstraint::executeImpl(SlotVisitor& visitor)
     57void MarkStackMergingConstraint::executeImpl(SlotVisitor& visitor)
    5858{
    5959    m_heap.m_mutatorMarkStack->transferTo(visitor.mutatorMarkStack());
    6060    m_heap.m_raceMarkStack->transferTo(visitor.mutatorMarkStack());
    61     return ConstraintParallelism::Sequential;
    6261}
    6362
  • trunk/Source/JavaScriptCore/heap/MarkStackMergingConstraint.h

    r225524 r226667  
    3939protected:
    4040    void prepareToExecuteImpl(const AbstractLocker& constraintSolvingLocker, SlotVisitor&) override;
    41     ConstraintParallelism executeImpl(SlotVisitor&) override;
     41    void executeImpl(SlotVisitor&) override;
    4242   
    4343private:
  • trunk/Source/JavaScriptCore/heap/MarkedAllocator.cpp

    r225831 r226667  
    459459        MarkedBlock::Handle* run() override
    460460        {
     461            if (m_done)
     462                return nullptr;
    461463            auto locker = holdLock(m_lock);
    462464            m_index = m_allocator.m_markingNotEmpty.findBit(m_index, true);
    463             if (m_index >= m_allocator.m_blocks.size())
     465            if (m_index >= m_allocator.m_blocks.size()) {
     466                m_done = true;
    464467                return nullptr;
     468            }
    465469            return m_allocator.m_blocks[m_index++];
    466470        }
     
    470474        size_t m_index { 0 };
    471475        Lock m_lock;
     476        bool m_done { false };
    472477    };
    473478   
  • trunk/Source/JavaScriptCore/heap/MarkedBlock.cpp

    r225831 r226667  
    330330    m_index = index;
    331331    m_allocator = allocator;
     332    m_block->m_subspace = allocator->subspace();
    332333   
    333334    size_t cellSize = allocator->cellSize();
     
    357358    m_index = std::numeric_limits<size_t>::max();
    358359    m_allocator = nullptr;
     360    m_block->m_subspace = nullptr;
    359361}
    360362
  • trunk/Source/JavaScriptCore/heap/MarkedBlock.h

    r225831 r226667  
    301301   
    302302    CountingLock& lock() { return m_lock; }
     303   
     304    Subspace* subspace() const { return m_subspace; }
    303305
    304306private:
     
    320322    Handle& m_handle;
    321323    VM* m_vm;
     324    Subspace* m_subspace;
    322325
    323326    CountingLock m_lock;
  • trunk/Source/JavaScriptCore/heap/MarkedBlockInlines.h

    r225831 r226667  
    484484    // a race ought to mean that it just returns false when it should have returned true - but this is
    485485    // something that would have to be verified carefully.
     486    //
     487    // NOTE: Some users of forEachLiveCell require that their callback is called exactly once for
     488    // each live cell. We could optimize this function for those users by using a slow loop if the
     489    // block is in marks-mean-live mode. That would only affect blocks that had partial survivors
     490    // during the last collection and no survivors (yet) during this collection.
     491    //
    486492    // https://bugs.webkit.org/show_bug.cgi?id=180315
    487493   
     
    492498            continue;
    493499
    494         if (functor(cell, kind) == IterationStatus::Done)
     500        if (functor(i, cell, kind) == IterationStatus::Done)
    495501            return IterationStatus::Done;
    496502    }
  • trunk/Source/JavaScriptCore/heap/MarkedSpaceInlines.h

    r213883 r226667  
    4141    BlockIterator end = m_blocks.set().end();
    4242    for (BlockIterator it = m_blocks.set().begin(); it != end; ++it) {
    43         if ((*it)->handle().forEachLiveCell(functor) == IterationStatus::Done)
     43        IterationStatus result = (*it)->handle().forEachLiveCell(
     44            [&] (size_t, HeapCell* cell, HeapCell::Kind kind) -> IterationStatus {
     45                return functor(cell, kind);
     46            });
     47        if (result == IterationStatus::Done)
    4448            return;
    4549    }
  • trunk/Source/JavaScriptCore/heap/MarkingConstraint.cpp

    r225524 r226667  
    5252}
    5353
    54 ConstraintParallelism MarkingConstraint::execute(SlotVisitor& visitor)
     54void MarkingConstraint::execute(SlotVisitor& visitor)
    5555{
    5656    VisitCounter visitCounter(visitor);
    57     ConstraintParallelism result = executeImpl(visitor);
     57    executeImpl(visitor);
    5858    m_lastVisitCount += visitCounter.visitCount();
    5959    if (verboseMarkingConstraint && visitCounter.visitCount())
    6060        dataLog("(", abbreviatedName(), " visited ", visitCounter.visitCount(), " in execute)");
    61     if (result == ConstraintParallelism::Parallel) {
    62         // It's illegal to produce parallel work if you haven't advertised it upfront because the solver
    63         // has optimizations for constraints that promise to never produce parallel work.
    64         RELEASE_ASSERT(m_parallelism == ConstraintParallelism::Parallel);
    65     }
    66     return result;
    6761}
    6862
     
    8882}
    8983
    90 void MarkingConstraint::doParallelWork(SlotVisitor& visitor)
     84void MarkingConstraint::doParallelWork(SlotVisitor& visitor, SharedTask<void(SlotVisitor&)>& task)
    9185{
    9286    VisitCounter visitCounter(visitor);
    93     doParallelWorkImpl(visitor);
     87    task.run(visitor);
    9488    if (verboseMarkingConstraint && visitCounter.visitCount())
    9589        dataLog("(", abbreviatedName(), " visited ", visitCounter.visitCount(), " in doParallelWork)");
     
    10094}
    10195
    102 void MarkingConstraint::finishParallelWork(SlotVisitor& visitor)
    103 {
    104     VisitCounter visitCounter(visitor);
    105     finishParallelWorkImpl(visitor);
    106     m_lastVisitCount += visitCounter.visitCount();
    107     if (verboseMarkingConstraint && visitCounter.visitCount())
    108         dataLog("(", abbreviatedName(), " visited ", visitCounter.visitCount(), " in finishParallelWork)");
    109 }
    110 
    11196void MarkingConstraint::prepareToExecuteImpl(const AbstractLocker&, SlotVisitor&)
    112 {
    113 }
    114 
    115 void MarkingConstraint::doParallelWorkImpl(SlotVisitor&)
    116 {
    117     UNREACHABLE_FOR_PLATFORM();
    118 }
    119 
    120 void MarkingConstraint::finishParallelWorkImpl(SlotVisitor&)
    12197{
    12298}
  • trunk/Source/JavaScriptCore/heap/MarkingConstraint.h

    r225524 r226667  
    3333#include <wtf/Lock.h>
    3434#include <wtf/Noncopyable.h>
     35#include <wtf/SharedTask.h>
    3536#include <wtf/text/CString.h>
    3637
     
    6061    size_t lastVisitCount() const { return m_lastVisitCount; }
    6162   
    62     ConstraintParallelism execute(SlotVisitor&);
     63    void execute(SlotVisitor&);
    6364   
    6465    JS_EXPORT_PRIVATE virtual double quickWorkEstimate(SlotVisitor& visitor);
     
    6869    void prepareToExecute(const AbstractLocker& constraintSolvingLocker, SlotVisitor&);
    6970   
    70     void doParallelWork(SlotVisitor&);
    71     void finishParallelWork(SlotVisitor&);
     71    void doParallelWork(SlotVisitor&, SharedTask<void(SlotVisitor&)>&);
    7272   
    7373    ConstraintVolatility volatility() const { return m_volatility; }
     
    7777
    7878protected:
    79     virtual ConstraintParallelism executeImpl(SlotVisitor&) = 0;
     79    virtual void executeImpl(SlotVisitor&) = 0;
    8080    JS_EXPORT_PRIVATE virtual void prepareToExecuteImpl(const AbstractLocker& constraintSolvingLocker, SlotVisitor&);
    81     virtual void doParallelWorkImpl(SlotVisitor&);
    82     virtual void finishParallelWorkImpl(SlotVisitor&);
    8381   
    8482private:
  • trunk/Source/JavaScriptCore/heap/MarkingConstraintSet.cpp

    r225524 r226667  
    6666}
    6767
    68 void MarkingConstraintSet::add(CString abbreviatedName, CString name, ::Function<void(SlotVisitor&)> function, ConstraintVolatility volatility, ConstraintConcurrency concurrency)
     68void MarkingConstraintSet::add(CString abbreviatedName, CString name, ::Function<void(SlotVisitor&)> function, ConstraintVolatility volatility, ConstraintConcurrency concurrency, ConstraintParallelism parallelism)
    6969{
    70     add(std::make_unique<SimpleMarkingConstraint>(WTFMove(abbreviatedName), WTFMove(name), WTFMove(function), volatility, concurrency));
     70    add(std::make_unique<SimpleMarkingConstraint>(WTFMove(abbreviatedName), WTFMove(name), WTFMove(function), volatility, concurrency, parallelism));
    7171}
    7272
  • trunk/Source/JavaScriptCore/heap/MarkingConstraintSet.h

    r226010 r226667  
    4747        ::Function<void(SlotVisitor&)>,
    4848        ConstraintVolatility,
    49         ConstraintConcurrency = ConstraintConcurrency::Concurrent);
     49        ConstraintConcurrency = ConstraintConcurrency::Concurrent,
     50        ConstraintParallelism = ConstraintParallelism::Sequential);
     51   
     52    void add(
     53        CString abbreviatedName, CString name,
     54        ::Function<void(SlotVisitor&)> func,
     55        ConstraintVolatility volatility,
     56        ConstraintParallelism parallelism)
     57    {
     58        add(abbreviatedName, name, WTFMove(func), volatility, ConstraintConcurrency::Concurrent, parallelism);
     59    }
    5060   
    5161    void add(std::unique_ptr<MarkingConstraint>);
  • trunk/Source/JavaScriptCore/heap/MarkingConstraintSolver.cpp

    r226437 r226667  
    7979    RELEASE_ASSERT(!m_numThreadsThatMayProduceWork);
    8080       
    81     for (unsigned indexToRun : m_didExecuteInParallel)
    82         m_set.m_set[indexToRun]->finishParallelWork(m_mainVisitor);
    83     m_didExecuteInParallel.clear();
    84    
    8581    if (!m_toExecuteSequentially.isEmpty()) {
    8682        for (unsigned indexToRun : m_toExecuteSequentially)
     
    9086       
    9187    RELEASE_ASSERT(m_toExecuteInParallel.isEmpty());
    92     RELEASE_ASSERT(!m_toExecuteInParallelSet.bitCount());
    9388}
    9489
     
    157152   
    158153    constraint.prepareToExecute(NoLockingNecessary, m_mainVisitor);
    159     ConstraintParallelism parallelism = constraint.execute(m_mainVisitor);
    160     didExecute(parallelism, constraint.index());
     154    constraint.execute(m_mainVisitor);
     155    m_executed.set(constraint.index());
     156}
     157
     158void MarkingConstraintSolver::addParallelTask(RefPtr<SharedTask<void(SlotVisitor&)>> task, MarkingConstraint& constraint)
     159{
     160    auto locker = holdLock(m_lock);
     161    m_toExecuteInParallel.append(TaskWithConstraint(WTFMove(task), &constraint));
    161162}
    162163
     
    165166    for (;;) {
    166167        bool doParallelWorkMode;
    167         unsigned indexToRun;
     168        MarkingConstraint* constraint = nullptr;
     169        unsigned indexToRun = UINT_MAX;
     170        TaskWithConstraint task;
    168171        {
    169172            auto locker = holdLock(m_lock);
     
    174177                        return false;
    175178                   
    176                     indexToRun = m_toExecuteInParallel.first();
     179                    task = m_toExecuteInParallel.first();
     180                    constraint = task.constraint;
    177181                    doParallelWorkMode = true;
    178182                    return true;
    179183                };
    180                            
     184               
    181185                auto tryNextConstraint = [&] () -> bool {
    182186                    if (!m_pickNextIsStillActive)
     
    193197                            continue;
    194198                                   
    195                         MarkingConstraint& constraint = *m_set.m_set[*pickResult];
    196                         if (constraint.concurrency() == ConstraintConcurrency::Sequential) {
     199                        MarkingConstraint& candidateConstraint = *m_set.m_set[*pickResult];
     200                        if (candidateConstraint.concurrency() == ConstraintConcurrency::Sequential) {
    197201                            m_toExecuteSequentially.append(*pickResult);
    198202                            continue;
    199203                        }
    200                         if (constraint.parallelism() == ConstraintParallelism::Parallel)
     204                        if (candidateConstraint.parallelism() == ConstraintParallelism::Parallel)
    201205                            m_numThreadsThatMayProduceWork++;
    202206                        indexToRun = *pickResult;
     207                        constraint = &candidateConstraint;
    203208                        doParallelWorkMode = false;
    204                         constraint.prepareToExecute(locker, visitor);
     209                        constraint->prepareToExecute(locker, visitor);
    205210                        return true;
    206211                    }
     
    227232        }
    228233                   
    229         ConstraintParallelism parallelism = ConstraintParallelism::Sequential;
    230                    
    231         MarkingConstraint& constraint = *m_set.m_set[indexToRun];
    232                    
    233234        if (doParallelWorkMode)
    234             constraint.doParallelWork(visitor);
    235         else
    236             parallelism = constraint.execute(visitor);
    237                    
     235            constraint->doParallelWork(visitor, *task.task);
     236        else {
     237            if (constraint->parallelism() == ConstraintParallelism::Parallel) {
     238                visitor.m_currentConstraint = constraint;
     239                visitor.m_currentSolver = this;
     240            }
     241           
     242            constraint->execute(visitor);
     243           
     244            visitor.m_currentConstraint = nullptr;
     245            visitor.m_currentSolver = nullptr;
     246        }
     247       
    238248        {
    239249            auto locker = holdLock(m_lock);
    240                        
     250           
    241251            if (doParallelWorkMode) {
    242                 if (m_toExecuteInParallelSet.get(indexToRun)) {
    243                     m_didExecuteInParallel.append(indexToRun);
    244                                
    245                     m_toExecuteInParallel.takeFirst(
    246                         [&] (unsigned value) { return value == indexToRun; });
    247                     m_toExecuteInParallelSet.clear(indexToRun);
    248                 }
     252                if (!m_toExecuteInParallel.isEmpty()
     253                    && task == m_toExecuteInParallel.first())
     254                    m_toExecuteInParallel.takeFirst();
     255                else
     256                    ASSERT(!m_toExecuteInParallel.contains(task));
    249257            } else {
    250                 if (constraint.parallelism() == ConstraintParallelism::Parallel)
     258                if (constraint->parallelism() == ConstraintParallelism::Parallel)
    251259                    m_numThreadsThatMayProduceWork--;
    252260                m_executed.set(indexToRun);
    253                 if (parallelism == ConstraintParallelism::Parallel) {
    254                     m_toExecuteInParallel.append(indexToRun);
    255                     m_toExecuteInParallelSet.set(indexToRun);
    256                 }
    257261            }
    258262                       
     
    262266}
    263267
    264 void MarkingConstraintSolver::didExecute(ConstraintParallelism parallelism, unsigned index)
    265 {
    266     m_executed.set(index);
    267     if (parallelism == ConstraintParallelism::Parallel) {
    268         m_toExecuteInParallel.append(index);
    269         m_toExecuteInParallelSet.set(index);
    270     }
    271 }
    272 
    273268} // namespace JSC
    274269
  • trunk/Source/JavaScriptCore/heap/MarkingConstraintSolver.h

    r225524 r226667  
    6565    void execute(MarkingConstraint&);
    6666   
     67    // Parallel constraints can add parallel tasks.
     68    void addParallelTask(RefPtr<SharedTask<void(SlotVisitor&)>>, MarkingConstraint&);
     69   
    6770private:
    6871    void runExecutionThread(SlotVisitor&, SchedulerPreference, ScopedLambda<std::optional<unsigned>()> pickNext);
    6972   
    70     void didExecute(ConstraintParallelism, unsigned index);
    71 
     73    struct TaskWithConstraint {
     74        TaskWithConstraint() { }
     75       
     76        TaskWithConstraint(RefPtr<SharedTask<void(SlotVisitor&)>> task, MarkingConstraint* constraint)
     77            : task(WTFMove(task))
     78            , constraint(constraint)
     79        {
     80        }
     81       
     82        bool operator==(const TaskWithConstraint& other) const
     83        {
     84            return task == other.task
     85                && constraint == other.constraint;
     86        }
     87       
     88        RefPtr<SharedTask<void(SlotVisitor&)>> task;
     89        MarkingConstraint* constraint { nullptr };
     90    };
     91   
    7292    Heap& m_heap;
    7393    SlotVisitor& m_mainVisitor;
    7494    MarkingConstraintSet& m_set;
    7595    BitVector m_executed;
    76     Deque<unsigned, 32> m_toExecuteInParallel;
    77     BitVector m_toExecuteInParallelSet;
    78     Vector<unsigned, 32> m_didExecuteInParallel;
     96    Deque<TaskWithConstraint, 32> m_toExecuteInParallel;
    7997    Vector<unsigned, 32> m_toExecuteSequentially;
    8098    Lock m_lock;
  • trunk/Source/JavaScriptCore/heap/SimpleMarkingConstraint.cpp

    r225524 r226667  
    3232    CString abbreviatedName, CString name,
    3333    ::Function<void(SlotVisitor&)> executeFunction,
    34     ConstraintVolatility volatility, ConstraintConcurrency concurrency)
    35     : MarkingConstraint(WTFMove(abbreviatedName), WTFMove(name), volatility, concurrency, ConstraintParallelism::Sequential)
     34    ConstraintVolatility volatility, ConstraintConcurrency concurrency,
     35    ConstraintParallelism parallelism)
     36    : MarkingConstraint(WTFMove(abbreviatedName), WTFMove(name), volatility, concurrency, parallelism)
    3637    , m_executeFunction(WTFMove(executeFunction))
    3738{
     
    4243}
    4344
    44 ConstraintParallelism SimpleMarkingConstraint::executeImpl(SlotVisitor& visitor)
     45void SimpleMarkingConstraint::executeImpl(SlotVisitor& visitor)
    4546{
    4647    m_executeFunction(visitor);
    47     return ConstraintParallelism::Sequential;
    4848}
    4949
  • trunk/Source/JavaScriptCore/heap/SimpleMarkingConstraint.h

    r225524 r226667  
    3232
    3333// This allows for an informal way to define constraints. Just pass a lambda to the constructor. The only
    34 // downside is that this makes it hard for constraints to be stateful, which is necessary for them to be
    35 // parallel. In those cases, it's easier to just subclass MarkingConstraint.
     34// downside is that this makes it hard for constraints to override any functions in MarkingConstraint
     35// other than executeImpl. In those cases, just subclass MarkingConstraint.
    3636class SimpleMarkingConstraint : public MarkingConstraint {
    3737public:
     
    4040        ::Function<void(SlotVisitor&)>,
    4141        ConstraintVolatility,
    42         ConstraintConcurrency = ConstraintConcurrency::Concurrent);
     42        ConstraintConcurrency = ConstraintConcurrency::Concurrent,
     43        ConstraintParallelism = ConstraintParallelism::Sequential);
     44   
     45    SimpleMarkingConstraint(
     46        CString abbreviatedName, CString name,
     47        ::Function<void(SlotVisitor&)> func,
     48        ConstraintVolatility volatility,
     49        ConstraintParallelism parallelism)
     50        : SimpleMarkingConstraint(abbreviatedName, name, WTFMove(func), volatility, ConstraintConcurrency::Concurrent, parallelism)
     51    {
     52    }
    4353   
    4454    JS_EXPORT_PRIVATE ~SimpleMarkingConstraint();
    4555   
    4656private:
    47     ConstraintParallelism executeImpl(SlotVisitor&) override;
     57    void executeImpl(SlotVisitor&) override;
    4858
    4959    ::Function<void(SlotVisitor&)> m_executeFunction;
  • trunk/Source/JavaScriptCore/heap/SlotVisitor.cpp

    r225524 r226667  
    787787}
    788788
     789void SlotVisitor::addParallelConstraintTask(RefPtr<SharedTask<void(SlotVisitor&)>> task)
     790{
     791    RELEASE_ASSERT(m_currentSolver);
     792    RELEASE_ASSERT(m_currentConstraint);
     793    RELEASE_ASSERT(task);
     794   
     795    m_currentSolver->addParallelTask(task, *m_currentConstraint);
     796}
     797
    789798} // namespace JSC
  • trunk/Source/JavaScriptCore/heap/SlotVisitor.h

    r225524 r226667  
    4141class HeapSnapshotBuilder;
    4242class MarkedBlock;
     43class MarkingConstraintSolver;
    4344class UnconditionalFinalizer;
    4445template<typename T> class Weak;
     
    171172   
    172173    const char* codeName() const { return m_codeName.data(); }
     174   
     175    JS_EXPORT_PRIVATE void addParallelConstraintTask(RefPtr<SharedTask<void(SlotVisitor&)>>);
    173176
    174177private:
    175178    friend class ParallelModeEnabler;
     179    friend class MarkingConstraintSolver;
    176180   
    177181    void appendJSCellOrAuxiliary(HeapCell*);
     
    229233   
    230234    CString m_codeName;
     235   
     236    MarkingConstraint* m_currentConstraint { nullptr };
     237    MarkingConstraintSolver* m_currentSolver { nullptr };
    231238   
    232239public:
  • trunk/Source/JavaScriptCore/heap/Subspace.cpp

    r225831 r226667  
    127127}
    128128
     129void Subspace::sweep()
     130{
     131    forEachAllocator(
     132        [&] (MarkedAllocator& allocator) {
     133            allocator.sweep();
     134        });
     135}
     136
    129137void Subspace::didResizeBits(size_t)
    130138{
  • trunk/Source/JavaScriptCore/heap/Subspace.h

    r225831 r226667  
    9292    void forEachLiveCell(const Func&);
    9393   
     94    void sweep();
     95   
    9496    Subspace* nextSubspaceInAlignedMemoryAllocator() const { return m_nextSubspaceInAlignedMemoryAllocator; }
    9597    void setNextSubspaceInAlignedMemoryAllocator(Subspace* subspace) { m_nextSubspaceInAlignedMemoryAllocator = subspace; }
  • trunk/Source/JavaScriptCore/heap/SubspaceInlines.h

    r225831 r226667  
    137137        [&] (MarkedBlock::Handle* handle) {
    138138            handle->forEachLiveCell(
    139                 [&] (HeapCell* cell, HeapCell::Kind kind) -> IterationStatus {
     139                [&] (size_t, HeapCell* cell, HeapCell::Kind kind) -> IterationStatus {
    140140                    func(cell, kind);
    141141                    return IterationStatus::Continue;
  • trunk/Source/JavaScriptCore/llint/LowLevelInterpreter.asm

    r226556 r226667  
    948948    loadp JSFunction::m_executable[targetRegister], targetRegister
    949949    loadp FunctionExecutable::m_codeBlockForCall[targetRegister], targetRegister
     950    loadp ExecutableToCodeBlockEdge::m_codeBlock[targetRegister], targetRegister
    950951end
    951952
     
    958959    loadp JSFunction::m_executable[targetRegister], targetRegister
    959960    loadp FunctionExecutable::m_codeBlockForConstruct[targetRegister], targetRegister
     961    loadp ExecutableToCodeBlockEdge::m_codeBlock[targetRegister], targetRegister
    960962end
    961963
  • trunk/Source/JavaScriptCore/runtime/EvalExecutable.cpp

    r217108 r226667  
    5151    ScriptExecutable::visitChildren(thisObject, visitor);
    5252    visitor.append(thisObject->m_unlinkedEvalCodeBlock);
    53     if (EvalCodeBlock* evalCodeBlock = thisObject->m_evalCodeBlock.get())
    54         evalCodeBlock->visitWeakly(visitor);
     53    visitor.append(thisObject->m_evalCodeBlock);
    5554}
    5655
  • trunk/Source/JavaScriptCore/runtime/EvalExecutable.h

    r225314 r226667  
    2626#pragma once
    2727
     28#include "ExecutableToCodeBlockEdge.h"
    2829#include "ScriptExecutable.h"
    2930#include "UnlinkedEvalCodeBlock.h"
     
    4142    EvalCodeBlock* codeBlock()
    4243    {
    43         return m_evalCodeBlock.get();
     44        return bitwise_cast<EvalCodeBlock*>(ExecutableToCodeBlockEdge::unwrap(m_evalCodeBlock.get()));
    4445    }
    4546
     
    7172    static void visitChildren(JSCell*, SlotVisitor&);
    7273
    73     WriteBarrier<EvalCodeBlock> m_evalCodeBlock;
     74    WriteBarrier<ExecutableToCodeBlockEdge> m_evalCodeBlock;
    7475    WriteBarrier<UnlinkedEvalCodeBlock> m_unlinkedEvalCodeBlock;
    7576};
  • trunk/Source/JavaScriptCore/runtime/FunctionExecutable.cpp

    r222827 r226667  
    11/*
    2  * Copyright (C) 2009, 2010, 2013, 2015-2016 Apple Inc. All rights reserved.
     2 * Copyright (C) 2009-2018 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    6969FunctionCodeBlock* FunctionExecutable::baselineCodeBlockFor(CodeSpecializationKind kind)
    7070{
    71     FunctionCodeBlock* result;
     71    ExecutableToCodeBlockEdge* edge;
    7272    if (kind == CodeForCall)
    73         result = m_codeBlockForCall.get();
     73        edge = m_codeBlockForCall.get();
    7474    else {
    7575        RELEASE_ASSERT(kind == CodeForConstruct);
    76         result = m_codeBlockForConstruct.get();
     76        edge = m_codeBlockForConstruct.get();
    7777    }
    78     if (!result)
     78    if (!edge)
    7979        return 0;
    80     return static_cast<FunctionCodeBlock*>(result->baselineAlternative());
     80    return static_cast<FunctionCodeBlock*>(edge->codeBlock()->baselineAlternative());
    8181}
    8282
     
    8686    ASSERT_GC_OBJECT_INHERITS(thisObject, info());
    8787    ScriptExecutable::visitChildren(thisObject, visitor);
    88     if (FunctionCodeBlock* codeBlockForCall = thisObject->m_codeBlockForCall.get())
    89         codeBlockForCall->visitWeakly(visitor);
    90     if (FunctionCodeBlock* codeBlockForConstruct = thisObject->m_codeBlockForConstruct.get())
    91         codeBlockForConstruct->visitWeakly(visitor);
     88    visitor.append(thisObject->m_codeBlockForCall);
     89    visitor.append(thisObject->m_codeBlockForConstruct);
    9290    visitor.append(thisObject->m_unlinkedExecutable);
    9391    visitor.append(thisObject->m_singletonFunction);
  • trunk/Source/JavaScriptCore/runtime/FunctionExecutable.h

    r225314 r226667  
    11/*
    2  * Copyright (C) 2009-2017 Apple Inc. All rights reserved.
     2 * Copyright (C) 2009-2018 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    2626#pragma once
    2727
     28#include "ExecutableToCodeBlockEdge.h"
    2829#include "ScriptExecutable.h"
    2930#include "SourceCode.h"
     
    6970    FunctionCodeBlock* eitherCodeBlock()
    7071    {
     72        ExecutableToCodeBlockEdge* edge;
    7173        if (m_codeBlockForCall)
    72             return m_codeBlockForCall.get();
    73         return m_codeBlockForConstruct.get();
     74            edge = m_codeBlockForCall.get();
     75        else
     76            edge = m_codeBlockForConstruct.get();
     77        return bitwise_cast<FunctionCodeBlock*>(ExecutableToCodeBlockEdge::unwrap(edge));
    7478    }
    7579       
     
    8185    FunctionCodeBlock* codeBlockForCall()
    8286    {
    83         return m_codeBlockForCall.get();
     87        return bitwise_cast<FunctionCodeBlock*>(ExecutableToCodeBlockEdge::unwrap(m_codeBlockForCall.get()));
    8488    }
    8589
    8690    bool isGeneratedForConstruct() const
    8791    {
    88         return m_codeBlockForConstruct.get();
     92        return !!m_codeBlockForConstruct;
    8993    }
    9094
    9195    FunctionCodeBlock* codeBlockForConstruct()
    9296    {
    93         return m_codeBlockForConstruct.get();
     97        return bitwise_cast<FunctionCodeBlock*>(ExecutableToCodeBlockEdge::unwrap(m_codeBlockForConstruct.get()));
    9498    }
    9599       
     
    205209    unsigned m_parametersStartOffset;
    206210    WriteBarrier<UnlinkedFunctionExecutable> m_unlinkedExecutable;
    207     WriteBarrier<FunctionCodeBlock> m_codeBlockForCall;
    208     WriteBarrier<FunctionCodeBlock> m_codeBlockForConstruct;
     211    WriteBarrier<ExecutableToCodeBlockEdge> m_codeBlockForCall;
     212    WriteBarrier<ExecutableToCodeBlockEdge> m_codeBlockForConstruct;
    209213    RefPtr<TypeSet> m_returnStatementTypeSet;
    210214    WriteBarrier<InferredValue> m_singletonFunction;
  • trunk/Source/JavaScriptCore/runtime/JSType.h

    r226311 r226667  
    4444    UnlinkedEvalCodeBlockType,
    4545    UnlinkedFunctionCodeBlockType,
     46       
     47    CodeBlockType,
    4648
    4749    JSFixedArrayType,
  • trunk/Source/JavaScriptCore/runtime/ModuleProgramExecutable.cpp

    r221822 r226667  
    9494    visitor.append(thisObject->m_unlinkedModuleProgramCodeBlock);
    9595    visitor.append(thisObject->m_moduleEnvironmentSymbolTable);
    96     if (ModuleProgramCodeBlock* moduleProgramCodeBlock = thisObject->m_moduleProgramCodeBlock.get())
    97         moduleProgramCodeBlock->visitWeakly(visitor);
     96    visitor.append(thisObject->m_moduleProgramCodeBlock);
    9897}
    9998
  • trunk/Source/JavaScriptCore/runtime/ModuleProgramExecutable.h

    r225314 r226667  
    11/*
    2  * Copyright (C) 2009, 2010, 2013-2016 Apple Inc. All rights reserved.
     2 * Copyright (C) 2009-2017 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    2626#pragma once
    2727
     28#include "ExecutableToCodeBlockEdge.h"
    2829#include "ScriptExecutable.h"
    2930
     
    4849    ModuleProgramCodeBlock* codeBlock()
    4950    {
    50         return m_moduleProgramCodeBlock.get();
     51        return bitwise_cast<ModuleProgramCodeBlock*>(ExecutableToCodeBlockEdge::unwrap(m_moduleProgramCodeBlock.get()));
    5152    }
    5253
     
    7980    WriteBarrier<UnlinkedModuleProgramCodeBlock> m_unlinkedModuleProgramCodeBlock;
    8081    WriteBarrier<SymbolTable> m_moduleEnvironmentSymbolTable;
    81     WriteBarrier<ModuleProgramCodeBlock> m_moduleProgramCodeBlock;
     82    WriteBarrier<ExecutableToCodeBlockEdge> m_moduleProgramCodeBlock;
    8283};
    8384
  • trunk/Source/JavaScriptCore/runtime/ProgramExecutable.cpp

    r223746 r226667  
    210210    ScriptExecutable::visitChildren(thisObject, visitor);
    211211    visitor.append(thisObject->m_unlinkedProgramCodeBlock);
    212     if (ProgramCodeBlock* programCodeBlock = thisObject->m_programCodeBlock.get())
    213         programCodeBlock->visitWeakly(visitor);
     212    visitor.append(thisObject->m_programCodeBlock);
    214213}
    215214
  • trunk/Source/JavaScriptCore/runtime/ProgramExecutable.h

    r225314 r226667  
    11/*
    2  * Copyright (C) 2009, 2010, 2013-2016 Apple Inc. All rights reserved.
     2 * Copyright (C) 2009-2017 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    2626#pragma once
    2727
     28#include "ExecutableToCodeBlockEdge.h"
    2829#include "ScriptExecutable.h"
    2930
     
    5657    ProgramCodeBlock* codeBlock()
    5758    {
    58         return m_programCodeBlock.get();
     59        return bitwise_cast<ProgramCodeBlock*>(ExecutableToCodeBlockEdge::unwrap(m_programCodeBlock.get()));
    5960    }
    6061
     
    8485
    8586    WriteBarrier<UnlinkedProgramCodeBlock> m_unlinkedProgramCodeBlock;
    86     WriteBarrier<ProgramCodeBlock> m_programCodeBlock;
     87    WriteBarrier<ExecutableToCodeBlockEdge> m_programCodeBlock;
    8788};
    8889
  • trunk/Source/JavaScriptCore/runtime/ScriptExecutable.cpp

    r221849 r226667  
    9090        ASSERT(kind == CodeForCall);
    9191       
    92         oldCodeBlock = executable->m_programCodeBlock.get();
    93         executable->m_programCodeBlock.setMayBeNull(vm, this, codeBlock);
     92        oldCodeBlock = ExecutableToCodeBlockEdge::deactivateAndUnwrap(executable->m_programCodeBlock.get());
     93        executable->m_programCodeBlock.setMayBeNull(vm, this, ExecutableToCodeBlockEdge::wrapAndActivate(codeBlock));
    9494        break;
    9595    }
     
    101101        ASSERT(kind == CodeForCall);
    102102
    103         oldCodeBlock = executable->m_moduleProgramCodeBlock.get();
    104         executable->m_moduleProgramCodeBlock.setMayBeNull(vm, this, codeBlock);
     103        oldCodeBlock = ExecutableToCodeBlockEdge::deactivateAndUnwrap(executable->m_moduleProgramCodeBlock.get());
     104        executable->m_moduleProgramCodeBlock.setMayBeNull(vm, this, ExecutableToCodeBlockEdge::wrapAndActivate(codeBlock));
    105105        break;
    106106    }
     
    112112        ASSERT(kind == CodeForCall);
    113113       
    114         oldCodeBlock = executable->m_evalCodeBlock.get();
    115         executable->m_evalCodeBlock.setMayBeNull(vm, this, codeBlock);
     114        oldCodeBlock = ExecutableToCodeBlockEdge::deactivateAndUnwrap(executable->m_evalCodeBlock.get());
     115        executable->m_evalCodeBlock.setMayBeNull(vm, this, ExecutableToCodeBlockEdge::wrapAndActivate(codeBlock));
    116116        break;
    117117    }
     
    123123        switch (kind) {
    124124        case CodeForCall:
    125             oldCodeBlock = executable->m_codeBlockForCall.get();
    126             executable->m_codeBlockForCall.setMayBeNull(vm, this, codeBlock);
     125            oldCodeBlock = ExecutableToCodeBlockEdge::deactivateAndUnwrap(executable->m_codeBlockForCall.get());
     126            executable->m_codeBlockForCall.setMayBeNull(vm, this, ExecutableToCodeBlockEdge::wrapAndActivate(codeBlock));
    127127            break;
    128128        case CodeForConstruct:
    129             oldCodeBlock = executable->m_codeBlockForConstruct.get();
    130             executable->m_codeBlockForConstruct.setMayBeNull(vm, this, codeBlock);
     129            oldCodeBlock = ExecutableToCodeBlockEdge::deactivateAndUnwrap(executable->m_codeBlockForConstruct.get());
     130            executable->m_codeBlockForConstruct.setMayBeNull(vm, this, ExecutableToCodeBlockEdge::wrapAndActivate(codeBlock));
    131131            break;
    132132        }
     
    269269        EvalExecutable* executable = jsCast<EvalExecutable*>(this);
    270270        EvalCodeBlock* baseline = static_cast<EvalCodeBlock*>(
    271             executable->m_evalCodeBlock->baselineVersion());
     271            executable->codeBlock()->baselineVersion());
    272272        EvalCodeBlock* result = EvalCodeBlock::create(&vm,
    273273            CodeBlock::CopyParsedBlock, *baseline);
     
    280280        ProgramExecutable* executable = jsCast<ProgramExecutable*>(this);
    281281        ProgramCodeBlock* baseline = static_cast<ProgramCodeBlock*>(
    282             executable->m_programCodeBlock->baselineVersion());
     282            executable->codeBlock()->baselineVersion());
    283283        ProgramCodeBlock* result = ProgramCodeBlock::create(&vm,
    284284            CodeBlock::CopyParsedBlock, *baseline);
     
    291291        ModuleProgramExecutable* executable = jsCast<ModuleProgramExecutable*>(this);
    292292        ModuleProgramCodeBlock* baseline = static_cast<ModuleProgramCodeBlock*>(
    293             executable->m_moduleProgramCodeBlock->baselineVersion());
     293            executable->codeBlock()->baselineVersion());
    294294        ModuleProgramCodeBlock* result = ModuleProgramCodeBlock::create(&vm,
    295295            CodeBlock::CopyParsedBlock, *baseline);
  • trunk/Source/JavaScriptCore/runtime/VM.cpp

    r226295 r226667  
    4545#include "EvalCodeBlock.h"
    4646#include "Exception.h"
     47#include "ExecutableToCodeBlockEdge.h"
    4748#include "FTLThunks.h"
    4849#include "FastMallocAlignedMemoryAllocator.h"
     
    250251#endif
    251252    , directEvalExecutableSpace ISO_SUBSPACE_INIT(heap, destructibleCellHeapCellType.get(), DirectEvalExecutable)
     253    , executableToCodeBlockEdgeSpace ISO_SUBSPACE_INIT(heap, cellHeapCellType.get(), ExecutableToCodeBlockEdge)
    252254    , functionExecutableSpace ISO_SUBSPACE_INIT(heap, destructibleCellHeapCellType.get(), FunctionExecutable)
    253255    , indirectEvalExecutableSpace ISO_SUBSPACE_INIT(heap, destructibleCellHeapCellType.get(), IndirectEvalExecutable)
     
    262264    , weakSetSpace ISO_SUBSPACE_INIT(heap, destructibleObjectHeapCellType.get(), JSWeakSet)
    263265    , weakMapSpace ISO_SUBSPACE_INIT(heap, destructibleObjectHeapCellType.get(), JSWeakMap)
     266    , executableToCodeBlockEdgesWithConstraints(executableToCodeBlockEdgeSpace)
     267    , executableToCodeBlockEdgesWithFinalizers(executableToCodeBlockEdgeSpace)
    264268    , inferredTypesWithFinalizers(inferredTypeSpace)
    265269    , inferredValuesWithFinalizers(inferredValueSpace)
     270    , evalCodeBlockSpace ISO_SUBSPACE_INIT(heap, destructibleCellHeapCellType.get(), EvalCodeBlock)
     271    , functionCodeBlockSpace ISO_SUBSPACE_INIT(heap, destructibleCellHeapCellType.get(), FunctionCodeBlock)
     272    , moduleProgramCodeBlockSpace ISO_SUBSPACE_INIT(heap, destructibleCellHeapCellType.get(), ModuleProgramCodeBlock)
     273    , programCodeBlockSpace ISO_SUBSPACE_INIT(heap, destructibleCellHeapCellType.get(), ProgramCodeBlock)
    266274    , vmType(vmType)
    267275    , clientData(0)
     
    353361    mapIteratorStructure.set(*this, JSMapIterator::createStructure(*this, 0, jsNull()));
    354362    bigIntStructure.set(*this, JSBigInt::createStructure(*this, 0, jsNull()));
     363    executableToCodeBlockEdgeStructure.set(*this, ExecutableToCodeBlockEdge::createStructure(*this, nullptr, jsNull()));
    355364
    356365    sentinelSetBucket.set(*this, JSSet::BucketType::createSentinel(*this));
  • trunk/Source/JavaScriptCore/runtime/VM.h

    r226017 r226667  
    11/*
    2  * Copyright (C) 2008-2017 Apple Inc. All rights reserved.
     2 * Copyright (C) 2008-2018 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    340340   
    341341    IsoSubspace directEvalExecutableSpace;
     342    IsoSubspace executableToCodeBlockEdgeSpace;
    342343    IsoSubspace functionExecutableSpace;
    343344    IsoSubspace indirectEvalExecutableSpace;
     
    353354    IsoSubspace weakMapSpace;
    354355   
     356    IsoCellSet executableToCodeBlockEdgesWithConstraints;
     357    IsoCellSet executableToCodeBlockEdgesWithFinalizers;
    355358    IsoCellSet inferredTypesWithFinalizers;
    356359    IsoCellSet inferredValuesWithFinalizers;
    357 
     360   
     361    struct SpaceAndFinalizerSet {
     362        IsoSubspace space;
     363        IsoCellSet finalizerSet;
     364       
     365        template<typename... Arguments>
     366        SpaceAndFinalizerSet(Arguments&&... arguments)
     367            : space(std::forward<Arguments>(arguments)...)
     368            , finalizerSet(space)
     369        {
     370        }
     371       
     372        static IsoCellSet& finalizerSetFor(Subspace& space)
     373        {
     374            return *bitwise_cast<IsoCellSet*>(
     375                bitwise_cast<char*>(&space) -
     376                OBJECT_OFFSETOF(SpaceAndFinalizerSet, space) +
     377                OBJECT_OFFSETOF(SpaceAndFinalizerSet, finalizerSet));
     378        }
     379    };
     380   
     381    SpaceAndFinalizerSet evalCodeBlockSpace;
     382    SpaceAndFinalizerSet functionCodeBlockSpace;
     383    SpaceAndFinalizerSet moduleProgramCodeBlockSpace;
     384    SpaceAndFinalizerSet programCodeBlockSpace;
     385
     386    template<typename Func>
     387    void forEachCodeBlockSpace(const Func& func)
     388    {
     389        // This should not include webAssemblyCodeBlockSpace because this is about subsclasses of
     390        // JSC::CodeBlock.
     391        func(evalCodeBlockSpace);
     392        func(functionCodeBlockSpace);
     393        func(moduleProgramCodeBlockSpace);
     394        func(programCodeBlockSpace);
     395    }
     396   
    358397    VMType vmType;
    359398    ClientData* clientData;
     
    419458    Strong<Structure> mapIteratorStructure;
    420459    Strong<Structure> bigIntStructure;
     460    Strong<Structure> executableToCodeBlockEdgeStructure;
    421461
    422462    Strong<JSCell> emptyPropertyNameEnumerator;
  • trunk/Source/JavaScriptCore/runtime/VMTraps.cpp

    r223738 r226667  
    231231                        codeBlock->jettison(Profiler::JettisonDueToVMTraps);
    232232                    }
    233                     return false;
    234233                });
    235234                RELEASE_ASSERT(sawCurrentCodeBlock);
     
    342341            if (codeBlock->hasInstalledVMTrapBreakpoints())
    343342                codeBlock->jettison(Profiler::JettisonDueToVMTraps);
    344             return false;
    345343        });
    346344    }
  • trunk/Source/JavaScriptCore/tools/VMInspector.cpp

    r224838 r226667  
    172172                // compiled, its jitCode will be null, and we can disregard it as a match for
    173173                // the machinePC we're searching for.
    174                 return false;
     174                return;
    175175            }
    176176
    177177            if (!JITCode::isJIT(jitCode->jitType()))
    178                 return false;
     178                return;
    179179
    180180            if (jitCode->contains(machinePC)) {
    181181                codeBlock = cb;
    182                 return true;
     182                return;
    183183            }
    184             return false;
    185184        });
    186185        if (codeBlock)
     
    277276        }
    278277
    279         bool operator()(CodeBlock* codeBlock) const
     278        void operator()(CodeBlock* codeBlock) const
    280279        {
    281280            if (codeBlock == candidate)
    282281                found = true;
    283             return found;
    284282        }
    285283
  • trunk/Source/WTF/ChangeLog

    r226601 r226667  
     12018-01-04  Filip Pizlo  <[email protected]>
     2
     3        CodeBlocks should be in IsoSubspaces
     4        https://bugs.webkit.org/show_bug.cgi?id=180884
     5
     6        Reviewed by Saam Barati.
     7       
     8        Deque<>::contains() is helpful for a debug ASSERT.
     9
     10        * wtf/Deque.h:
     11        (WTF::inlineCapacity>::contains):
     12
    1132018-01-08  Don Olmstead  <[email protected]>
    214
  • trunk/Source/WTF/wtf/Deque.h

    r225524 r226667  
    7676    const_reverse_iterator rbegin() const { return const_reverse_iterator(end()); }
    7777    const_reverse_iterator rend() const { return const_reverse_iterator(begin()); }
     78   
     79    template<typename U> bool contains(const U&);
    7880
    7981    T& first() { ASSERT(m_start != m_end); return m_buffer.buffer()[m_start]; }
     
    439441
    440442template<typename T, size_t inlineCapacity>
     443template<typename U>
     444bool Deque<T, inlineCapacity>::contains(const U& searchValue)
     445{
     446    for (auto& value : *this) {
     447        if (value == searchValue)
     448            return true;
     449    }
     450    return false;
     451}
     452
     453template<typename T, size_t inlineCapacity>
    441454inline auto Deque<T, inlineCapacity>::takeFirst() -> T
    442455{
  • trunk/Source/WebCore/ChangeLog

    r226666 r226667  
     12018-01-04  Filip Pizlo  <[email protected]>
     2
     3        CodeBlocks should be in IsoSubspaces
     4        https://bugs.webkit.org/show_bug.cgi?id=180884
     5
     6        Reviewed by Saam Barati.
     7
     8        No new tests because no new behavior.
     9       
     10        Adopting new parallel constraint API, so that more of the logic of doing parallel
     11        constraint solving is shared between the DOM's output constraints and JSC's output
     12        constraints.
     13
     14        * bindings/js/DOMGCOutputConstraint.cpp:
     15        (WebCore::DOMGCOutputConstraint::executeImpl):
     16        (WebCore::DOMGCOutputConstraint::doParallelWorkImpl): Deleted.
     17        (WebCore::DOMGCOutputConstraint::finishParallelWorkImpl): Deleted.
     18        * bindings/js/DOMGCOutputConstraint.h:
     19
    1202018-01-08  Simon Fraser  <[email protected]>
    221
  • trunk/Source/WebCore/bindings/js/DOMGCOutputConstraint.cpp

    r225524 r226667  
    11/*
    2  * Copyright (C) 2017 Apple Inc. All rights reserved.
     2 * Copyright (C) 2017-2018 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    5050}
    5151
    52 ConstraintParallelism DOMGCOutputConstraint::executeImpl(SlotVisitor&)
     52void DOMGCOutputConstraint::executeImpl(SlotVisitor& visitor)
    5353{
    5454    Heap& heap = m_vm.heap;
    5555   
    5656    if (heap.mutatorExecutionVersion() == m_lastExecutionVersion)
    57         return ConstraintParallelism::Sequential;
     57        return;
    5858   
    5959    m_lastExecutionVersion = heap.mutatorExecutionVersion();
    6060   
    61     RELEASE_ASSERT(m_tasks.isEmpty());
    6261    m_clientData.forEachOutputConstraintSpace(
    6362        [&] (Subspace& subspace) {
     
    6766            };
    6867           
    69             m_tasks.append(subspace.forEachMarkedCellInParallel(func));
     68            visitor.addParallelConstraintTask(subspace.forEachMarkedCellInParallel(func));
    7069        });
    71    
    72     return ConstraintParallelism::Parallel;
    7370}
    7471       
    75 void DOMGCOutputConstraint::doParallelWorkImpl(SlotVisitor& visitor)
    76 {
    77     for (auto& task : m_tasks)
    78         task->run(visitor);
    79 }
    80        
    81 void DOMGCOutputConstraint::finishParallelWorkImpl(SlotVisitor&)
    82 {
    83     m_tasks.clear();
    84 }
    85 
    8672} // namespace WebCore
    8773
  • trunk/Source/WebCore/bindings/js/DOMGCOutputConstraint.h

    r225524 r226667  
    11/*
    2  * Copyright (C) 2017 Apple Inc. All rights reserved.
     2 * Copyright (C) 2017-2018 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    4040   
    4141protected:
    42     JSC::ConstraintParallelism executeImpl(JSC::SlotVisitor&) override;
    43     void doParallelWorkImpl(JSC::SlotVisitor&) override;
    44     void finishParallelWorkImpl(JSC::SlotVisitor&) override;
     42    void executeImpl(JSC::SlotVisitor&) override;
    4543
    4644private:
     
    4846    JSVMClientData& m_clientData;
    4947    uint64_t m_lastExecutionVersion;
    50     Vector<RefPtr<SharedTask<void(SlotVisitor&)>>> m_tasks;
    5148};
    5249
  • trunk/Tools/Scripts/run-jsc-benchmarks

    r225524 r226667  
    217217$quantum=1000
    218218$includeSunSpider=true
    219 $includeLongSpider=true
     219$includeLongSpider=false
    220220$includeV8=true
    221221$includeKraken=true
     
    227227$includeBrowsermarkDOM=false
    228228$includeOctane=true
    229 $includeCompressionBench = true
    230 $includeSixSpeed = true
     229$includeCompressionBench = false
     230$includeSixSpeed = false
    231231$includeTailBench = true
    232232$measureGC=false
Note: See TracChangeset for help on using the changeset viewer.