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.
Rolling this back in because it was rolled out by mistake. There was a flaky crash that was
happening before and after this change, but we misread the revision numbers at first and
thought that this was the cause.
* 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):
Tools:
Remove some less important benchmarks from the default run. Doing run-jsc-benchmarks
shouldn't take a long time due to benchmarks we don't optimize for.
* Scripts/run-jsc-benchmarks:
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@226783 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/JavaScriptCore/bytecode/CodeBlock.cpp b/Source/JavaScriptCore/bytecode/CodeBlock.cpp
index f9f6ad1..683a968 100644
--- a/Source/JavaScriptCore/bytecode/CodeBlock.cpp
+++ b/Source/JavaScriptCore/bytecode/CodeBlock.cpp
@@ -51,6 +51,7 @@
#include "GetPutInfo.h"
#include "InlineCallFrame.h"
#include "InterpreterInlines.h"
+#include "IsoCellSetInlines.h"
#include "JIT.h"
#include "JITMathIC.h"
#include "JSBigInt.h"
@@ -329,20 +330,19 @@
, m_optimizationDelayCounter(0)
, m_reoptimizationRetryCounter(0)
, m_creationTime(MonotonicTime::now())
- , m_unconditionalFinalizer(makePoisonedUnique<UnconditionalFinalizer>(*this))
- , m_weakReferenceHarvester(makePoisonedUnique<WeakReferenceHarvester>(*this))
{
- m_visitWeaklyHasBeenCalled = false;
-
ASSERT(heap()->isDeferred());
ASSERT(m_scopeRegister.isLocal());
setNumParameters(other.numParameters());
+
+ vm->heap.codeBlockSet().add(this);
}
void CodeBlock::finishCreation(VM& vm, CopyParsedBlockTag, CodeBlock& other)
{
Base::finishCreation(vm);
+ finishCreationCommon(vm);
optimizeAfterWarmUp();
jitAfterWarmUp();
@@ -354,8 +354,6 @@
m_rareData->m_switchJumpTables = other.m_rareData->m_switchJumpTables;
m_rareData->m_stringSwitchJumpTables = other.m_rareData->m_stringSwitchJumpTables;
}
-
- heap()->m_codeBlocks->add(this);
}
CodeBlock::CodeBlock(VM* vm, Structure* structure, ScriptExecutable* ownerExecutable, UnlinkedCodeBlock* unlinkedCodeBlock,
@@ -389,16 +387,14 @@
, m_optimizationDelayCounter(0)
, m_reoptimizationRetryCounter(0)
, m_creationTime(MonotonicTime::now())
- , m_unconditionalFinalizer(makePoisonedUnique<UnconditionalFinalizer>(*this))
- , m_weakReferenceHarvester(makePoisonedUnique<WeakReferenceHarvester>(*this))
{
- m_visitWeaklyHasBeenCalled = false;
-
ASSERT(heap()->isDeferred());
ASSERT(m_scopeRegister.isLocal());
ASSERT(m_source);
setNumParameters(unlinkedCodeBlock->numParameters());
+
+ vm->heap.codeBlockSet().add(this);
}
// The main purpose of this function is to generate linked bytecode from unlinked bytecode. The process
@@ -413,6 +409,7 @@
JSScope* scope)
{
Base::finishCreation(vm);
+ finishCreationCommon(vm);
auto throwScope = DECLARE_THROW_SCOPE(vm);
@@ -849,19 +846,26 @@
if (Options::dumpGeneratedBytecodes())
dumpBytecode();
- heap()->m_codeBlocks->add(this);
heap()->reportExtraMemoryAllocated(m_instructions.size() * sizeof(Instruction));
return true;
}
+void CodeBlock::finishCreationCommon(VM& vm)
+{
+ m_ownerEdge.set(vm, this, ExecutableToCodeBlockEdge::create(vm, this));
+}
+
CodeBlock::~CodeBlock()
{
VM& vm = *m_poisonedVM;
+
+ vm.heap.codeBlockSet().remove(this);
+
if (UNLIKELY(vm.m_perBytecodeProfiler))
vm.m_perBytecodeProfiler->notifyDestruction(this);
- if (unlinkedCodeBlock()->didOptimize() == MixedTriState)
+ if (!vm.heap.isShuttingDown() && unlinkedCodeBlock()->didOptimize() == MixedTriState)
unlinkedCodeBlock()->setDidOptimize(FalseTriState);
#if ENABLE(VERBOSE_VALUE_PROFILE)
@@ -975,58 +979,6 @@
#endif // ENABLE(FTL_JIT)
}
-void CodeBlock::visitWeakly(SlotVisitor& visitor)
-{
- ConcurrentJSLocker locker(m_lock);
- if (m_visitWeaklyHasBeenCalled)
- return;
-
- m_visitWeaklyHasBeenCalled = true;
-
- if (Heap::isMarked(this))
- return;
-
- if (shouldVisitStrongly(locker)) {
- visitor.appendUnbarriered(this);
- return;
- }
-
- // There are two things that may use unconditional finalizers: inline cache clearing
- // and jettisoning. The probability of us wanting to do at least one of those things
- // is probably quite close to 1. So we add one no matter what and when it runs, it
- // figures out whether it has any work to do.
- visitor.addUnconditionalFinalizer(m_unconditionalFinalizer.get());
-
- if (!JITCode::isOptimizingJIT(jitType()))
- return;
-
- // If we jettison ourselves we'll install our alternative, so make sure that it
- // survives GC even if we don't.
- visitor.append(m_alternative);
-
- // There are two things that we use weak reference harvesters for: DFG fixpoint for
- // jettisoning, and trying to find structures that would be live based on some
- // inline cache. So it makes sense to register them regardless.
- visitor.addWeakReferenceHarvester(m_weakReferenceHarvester.get());
-
-#if ENABLE(DFG_JIT)
- // We get here if we're live in the sense that our owner executable is live,
- // but we're not yet live for sure in another sense: we may yet decide that this
- // code block should be jettisoned based on its outgoing weak references being
- // stale. Set a flag to indicate that we're still assuming that we're dead, and
- // perform one round of determining if we're live. The GC may determine, based on
- // either us marking additional objects, or by other objects being marked for
- // other reasons, that this iteration should run again; it will notify us of this
- // decision by calling harvestWeakReferences().
-
- m_allTransitionsHaveBeenMarked = false;
- propagateTransitions(locker, visitor);
-
- m_jitCode->dfgCommon()->livenessHasBeenProved = false;
- determineLiveness(locker, visitor);
-#endif // ENABLE(DFG_JIT)
-}
-
size_t CodeBlock::estimatedSize(JSCell* cell)
{
CodeBlock* thisObject = jsCast<CodeBlock*>(cell);
@@ -1041,18 +993,13 @@
CodeBlock* thisObject = jsCast<CodeBlock*>(cell);
ASSERT_GC_OBJECT_INHERITS(thisObject, info());
JSCell::visitChildren(thisObject, visitor);
+ visitor.append(thisObject->m_ownerEdge);
thisObject->visitChildren(visitor);
}
void CodeBlock::visitChildren(SlotVisitor& visitor)
{
ConcurrentJSLocker locker(m_lock);
- // There are two things that may use unconditional finalizers: inline cache clearing
- // and jettisoning. The probability of us wanting to do at least one of those things
- // is probably quite close to 1. So we add one no matter what and when it runs, it
- // figures out whether it has any work to do.
- visitor.addUnconditionalFinalizer(m_unconditionalFinalizer.get());
-
if (CodeBlock* otherBlock = specialOSREntryBlockOrNull())
visitor.appendUnbarriered(otherBlock);
@@ -1071,9 +1018,8 @@
stronglyVisitStrongReferences(locker, visitor);
stronglyVisitWeakReferences(locker, visitor);
-
- m_allTransitionsHaveBeenMarked = false;
- propagateTransitions(locker, visitor);
+
+ VM::SpaceAndFinalizerSet::finalizerSetFor(*subspace()).add(this);
}
bool CodeBlock::shouldVisitStrongly(const ConcurrentJSLocker& locker)
@@ -1164,12 +1110,8 @@
{
UNUSED_PARAM(visitor);
- if (m_allTransitionsHaveBeenMarked)
- return;
-
VM& vm = *m_poisonedVM;
- bool allAreMarkedSoFar = true;
-
+
if (jitType() == JITCode::InterpreterThunk) {
const Vector<unsigned>& propertyAccessInstructions = m_unlinkedCode->propertyAccessInstructions();
for (size_t i = 0; i < propertyAccessInstructions.size(); ++i) {
@@ -1186,8 +1128,6 @@
vm.heap.structureIDTable().get(newStructureID);
if (Heap::isMarked(oldStructure))
visitor.appendUnbarriered(newStructure);
- else
- allAreMarkedSoFar = false;
break;
}
default:
@@ -1199,7 +1139,7 @@
#if ENABLE(JIT)
if (JITCode::isJIT(jitType())) {
for (auto iter = m_stubInfos.begin(); !!iter; ++iter)
- allAreMarkedSoFar &= (*iter)->propagateTransitions(visitor);
+ (*iter)->propagateTransitions(visitor);
}
#endif // ENABLE(JIT)
@@ -1207,7 +1147,7 @@
if (JITCode::isOptimizingJIT(jitType())) {
DFG::CommonData* dfgCommon = m_jitCode->dfgCommon();
for (auto& weakReference : dfgCommon->weakStructureReferences)
- allAreMarkedSoFar &= weakReference->markIfCheap(visitor);
+ weakReference->markIfCheap(visitor);
for (auto& transition : dfgCommon->transitions) {
if (shouldMarkTransition(transition)) {
@@ -1231,14 +1171,10 @@
// live).
visitor.append(transition.m_to);
- } else
- allAreMarkedSoFar = false;
+ }
}
}
#endif // ENABLE(DFG_JIT)
-
- if (allAreMarkedSoFar)
- m_allTransitionsHaveBeenMarked = true;
}
void CodeBlock::determineLiveness(const ConcurrentJSLocker&, SlotVisitor& visitor)
@@ -1246,11 +1182,16 @@
UNUSED_PARAM(visitor);
#if ENABLE(DFG_JIT)
- // Check if we have any remaining work to do.
- DFG::CommonData* dfgCommon = m_jitCode->dfgCommon();
- if (dfgCommon->livenessHasBeenProved)
+ if (Heap::isMarked(this))
return;
+ // In rare and weird cases, this could be called on a baseline CodeBlock. One that I found was
+ // that we might decide that the CodeBlock should be jettisoned due to old age, so the
+ // isMarked check doesn't protect us.
+ if (!JITCode::isOptimizingJIT(jitType()))
+ return;
+
+ DFG::CommonData* dfgCommon = m_jitCode->dfgCommon();
// Now check all of our weak references. If all of them are live, then we
// have proved liveness and so we scan our strong references. If at end of
// GC we still have not proved liveness, then this code block is toast.
@@ -1279,17 +1220,10 @@
// All weak references are live. Record this information so we don't
// come back here again, and scan the strong references.
- dfgCommon->livenessHasBeenProved = true;
visitor.appendUnbarriered(this);
#endif // ENABLE(DFG_JIT)
}
-void CodeBlock::WeakReferenceHarvester::visitWeakReferences(SlotVisitor& visitor)
-{
- codeBlock.propagateTransitions(NoLockingNecessary, visitor);
- codeBlock.determineLiveness(NoLockingNecessary, visitor);
-}
-
void CodeBlock::clearLLIntGetByIdCache(Instruction* instruction)
{
instruction[0].u.opcode = LLInt::getOpcode(op_get_by_id);
@@ -1421,25 +1355,19 @@
#endif
}
-void CodeBlock::UnconditionalFinalizer::finalizeUnconditionally()
+void CodeBlock::finalizeUnconditionally(VM&)
{
- codeBlock.updateAllPredictions();
+ updateAllPredictions();
- if (!Heap::isMarked(&codeBlock)) {
- if (codeBlock.shouldJettisonDueToWeakReference())
- codeBlock.jettison(Profiler::JettisonDueToWeakReference);
- else
- codeBlock.jettison(Profiler::JettisonDueToOldAge);
- return;
- }
-
- if (JITCode::couldBeInterpreted(codeBlock.jitType()))
- codeBlock.finalizeLLIntInlineCaches();
+ if (JITCode::couldBeInterpreted(jitType()))
+ finalizeLLIntInlineCaches();
#if ENABLE(JIT)
- if (!!codeBlock.jitCode())
- codeBlock.finalizeBaselineJITInlineCaches();
+ if (!!jitCode())
+ finalizeBaselineJITInlineCaches();
#endif
+
+ VM::SpaceAndFinalizerSet::finalizerSetFor(*subspace()).remove(this);
}
void CodeBlock::getStubInfoMap(const ConcurrentJSLocker&, StubInfoMap& result)
@@ -1593,7 +1521,7 @@
UNUSED_PARAM(locker);
visitor.append(m_globalObject);
- visitor.append(m_ownerExecutable);
+ visitor.append(m_ownerExecutable); // This is extra important since it causes the ExecutableToCodeBlockEdge to be marked.
visitor.append(m_unlinkedCode);
if (m_rareData)
m_rareData->m_directEvalCodeCache.visitAggregate(visitor);
@@ -3132,7 +3060,6 @@
bool CodeBlock::hasInstalledVMTrapBreakpoints() const
{
#if ENABLE(SIGNAL_BASED_VM_TRAPS)
-
// This function may be called from a signal handler. We need to be
// careful to not call anything that is not signal handler safe, e.g.
// we should not perturb the refCount of m_jitCode.
@@ -3152,7 +3079,8 @@
// we should not perturb the refCount of m_jitCode.
if (!JITCode::isOptimizingJIT(jitType()))
return false;
- m_jitCode->dfgCommon()->installVMTrapBreakpoints(this);
+ auto& commonData = *m_jitCode->dfgCommon();
+ commonData.installVMTrapBreakpoints(this);
return true;
#else
UNREACHABLE_FOR_PLATFORM();
@@ -3192,8 +3120,6 @@
numSubs++;
totalSubSize += subIC->codeSize();
}
-
- return false;
};
heap()->forEachCodeBlock(countICs);