MarkingConstraintSet.cpp [plain text]
#include "config.h"
#include "MarkingConstraintSet.h"
#include "JSCInlines.h"
#include "MarkingConstraintSolver.h"
#include "Options.h"
#include "SimpleMarkingConstraint.h"
#include "SuperSampler.h"
#include <wtf/Function.h>
#include <wtf/TimeWithDynamicClockType.h>
namespace JSC {
MarkingConstraintSet::MarkingConstraintSet(Heap& heap)
: m_heap(heap)
{
}
MarkingConstraintSet::~MarkingConstraintSet()
{
}
void MarkingConstraintSet::didStartMarking()
{
m_unexecutedRoots.clearAll();
m_unexecutedOutgrowths.clearAll();
for (auto& constraint : m_set) {
constraint->resetStats();
switch (constraint->volatility()) {
case ConstraintVolatility::GreyedByExecution:
m_unexecutedRoots.set(constraint->index());
break;
case ConstraintVolatility::GreyedByMarking:
m_unexecutedOutgrowths.set(constraint->index());
break;
case ConstraintVolatility::SeldomGreyed:
break;
}
}
m_iteration = 1;
}
void MarkingConstraintSet::add(CString abbreviatedName, CString name, ::Function<void(SlotVisitor&)> function, ConstraintVolatility volatility, ConstraintConcurrency concurrency, ConstraintParallelism parallelism)
{
add(std::make_unique<SimpleMarkingConstraint>(WTFMove(abbreviatedName), WTFMove(name), WTFMove(function), volatility, concurrency, parallelism));
}
void MarkingConstraintSet::add(
std::unique_ptr<MarkingConstraint> constraint)
{
constraint->m_index = m_set.size();
m_ordered.append(constraint.get());
if (constraint->volatility() == ConstraintVolatility::GreyedByMarking)
m_outgrowths.append(constraint.get());
m_set.append(WTFMove(constraint));
}
bool MarkingConstraintSet::executeConvergence(SlotVisitor& visitor)
{
bool result = executeConvergenceImpl(visitor);
if (Options::logGC())
dataLog(" ");
return result;
}
bool MarkingConstraintSet::isWavefrontAdvancing(SlotVisitor& visitor)
{
for (MarkingConstraint* outgrowth : m_outgrowths) {
if (outgrowth->workEstimate(visitor))
return true;
}
return false;
}
bool MarkingConstraintSet::executeConvergenceImpl(SlotVisitor& visitor)
{
SuperSamplerScope superSamplerScope(false);
MarkingConstraintSolver solver(*this);
unsigned iteration = m_iteration++;
if (Options::logGC())
dataLog("i#", iteration, ":");
if (iteration == 1) {
solver.drain(m_unexecutedRoots);
return false;
}
if (iteration == 2) {
solver.drain(m_unexecutedOutgrowths);
return false;
}
bool isWavefrontAdvancing = this->isWavefrontAdvancing(visitor);
std::sort(
m_ordered.begin(), m_ordered.end(),
[&] (MarkingConstraint* a, MarkingConstraint* b) -> bool {
auto volatilityScore = [] (MarkingConstraint* constraint) -> unsigned {
return constraint->volatility() == ConstraintVolatility::GreyedByMarking ? 1 : 0;
};
unsigned aVolatilityScore = volatilityScore(a);
unsigned bVolatilityScore = volatilityScore(b);
if (aVolatilityScore != bVolatilityScore) {
if (isWavefrontAdvancing)
return aVolatilityScore > bVolatilityScore;
else
return aVolatilityScore < bVolatilityScore;
}
double aWorkEstimate = a->workEstimate(visitor);
double bWorkEstimate = b->workEstimate(visitor);
if (aWorkEstimate != bWorkEstimate)
return aWorkEstimate > bWorkEstimate;
return a->volatility() > b->volatility();
});
solver.converge(m_ordered);
return !solver.didVisitSomething();
}
void MarkingConstraintSet::executeAll(SlotVisitor& visitor)
{
for (auto& constraint : m_set)
constraint->execute(visitor);
if (Options::logGC())
dataLog(" ");
}
}