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):

File:
1 edited

Legend:

Unmodified
Added
Removed
  • 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
Note: See TracChangeset for help on using the changeset viewer.