MarkingConstraintSolver.h [plain text]
#pragma once
#include "VisitCounter.h"
#include <wtf/BitVector.h>
#include <wtf/Condition.h>
#include <wtf/Deque.h>
#include <wtf/FastMalloc.h>
#include <wtf/Lock.h>
#include <wtf/Noncopyable.h>
#include <wtf/ScopedLambda.h>
#include <wtf/Vector.h>
namespace JSC {
class Heap;
class MarkingConstraint;
class MarkingConstraintSet;
class MarkingConstraintSolver {
WTF_MAKE_NONCOPYABLE(MarkingConstraintSolver);
WTF_MAKE_FAST_ALLOCATED;
public:
MarkingConstraintSolver(MarkingConstraintSet&);
~MarkingConstraintSolver();
bool didVisitSomething() const;
enum SchedulerPreference {
ParallelWorkFirst,
NextConstraintFirst
};
void execute(SchedulerPreference, ScopedLambda<Optional<unsigned>()> pickNext);
void drain(BitVector& unexecuted);
void converge(const Vector<MarkingConstraint*>& order);
void execute(MarkingConstraint&);
void addParallelTask(RefPtr<SharedTask<void(SlotVisitor&)>>, MarkingConstraint&);
private:
void runExecutionThread(SlotVisitor&, SchedulerPreference, ScopedLambda<Optional<unsigned>()> pickNext);
struct TaskWithConstraint {
TaskWithConstraint() { }
TaskWithConstraint(RefPtr<SharedTask<void(SlotVisitor&)>> task, MarkingConstraint* constraint)
: task(WTFMove(task))
, constraint(constraint)
{
}
bool operator==(const TaskWithConstraint& other) const
{
return task == other.task
&& constraint == other.constraint;
}
RefPtr<SharedTask<void(SlotVisitor&)>> task;
MarkingConstraint* constraint { nullptr };
};
Heap& m_heap;
SlotVisitor& m_mainVisitor;
MarkingConstraintSet& m_set;
BitVector m_executed;
Deque<TaskWithConstraint, 32> m_toExecuteInParallel;
Vector<unsigned, 32> m_toExecuteSequentially;
Lock m_lock;
Condition m_condition;
bool m_pickNextIsStillActive { true };
unsigned m_numThreadsThatMayProduceWork { 0 };
Vector<VisitCounter, 16> m_visitCounters;
};
}