Commit 8c8bb2b1 authored by Michael Lippautz's avatar Michael Lippautz Committed by Commit Bot

[heap] Templatize Worklist segment size

Bug: chromium:738865
Change-Id: I67b65f3006d6fe7e88854806f364d9863076b49b
Reviewed-on: https://chromium-review.googlesource.com/558969
Commit-Queue: Michael Lippautz <mlippautz@chromium.org>
Reviewed-by: 's avatarUlan Degenbaev <ulan@chromium.org>
Cr-Commit-Position: refs/heads/master@{#46397}
parent ff3b948c
......@@ -48,7 +48,8 @@ class ConcurrentMarkingVisitor final
public:
using BaseClass = HeapVisitor<int, ConcurrentMarkingVisitor>;
explicit ConcurrentMarkingVisitor(Worklist* shared, Worklist* bailout,
explicit ConcurrentMarkingVisitor(ConcurrentMarking::MarkingWorklist* shared,
ConcurrentMarking::MarkingWorklist* bailout,
int task_id)
: shared_(shared, task_id), bailout_(bailout, task_id) {}
......@@ -246,8 +247,8 @@ class ConcurrentMarkingVisitor final
return MarkingState::Internal(object);
}
WorklistView shared_;
WorklistView bailout_;
ConcurrentMarking::MarkingWorklist::View shared_;
ConcurrentMarking::MarkingWorklist::View bailout_;
SlotSnapshot slot_snapshot_;
};
......@@ -275,8 +276,8 @@ class ConcurrentMarking::Task : public CancelableTask {
DISALLOW_COPY_AND_ASSIGN(Task);
};
ConcurrentMarking::ConcurrentMarking(Heap* heap, Worklist* shared,
Worklist* bailout)
ConcurrentMarking::ConcurrentMarking(Heap* heap, MarkingWorklist* shared,
MarkingWorklist* bailout)
: heap_(heap),
pending_task_semaphore_(0),
shared_(shared),
......
......@@ -15,11 +15,15 @@ namespace internal {
class Heap;
class Isolate;
template <int SEGMENT_SIZE>
class Worklist;
class ConcurrentMarking {
public:
ConcurrentMarking(Heap* heap, Worklist* shared_, Worklist* bailout_);
using MarkingWorklist = Worklist<64 /* segment size */>;
ConcurrentMarking(Heap* heap, MarkingWorklist* shared_,
MarkingWorklist* bailout_);
void StartTask();
void WaitForTaskToComplete();
......@@ -31,8 +35,8 @@ class ConcurrentMarking {
void Run(int task_id);
Heap* heap_;
base::Semaphore pending_task_semaphore_;
Worklist* shared_;
Worklist* bailout_;
MarkingWorklist* shared_;
MarkingWorklist* bailout_;
bool is_task_pending_;
};
......
......@@ -2182,7 +2182,8 @@ void MarkCompactCollector::RecordObjectStats() {
class YoungGenerationMarkingVisitor final
: public NewSpaceVisitor<YoungGenerationMarkingVisitor> {
public:
YoungGenerationMarkingVisitor(Heap* heap, Worklist* global_worklist,
YoungGenerationMarkingVisitor(
Heap* heap, MinorMarkCompactCollector::MarkingWorklist* global_worklist,
int task_id)
: heap_(heap), worklist_(global_worklist, task_id) {}
......@@ -2218,7 +2219,7 @@ class YoungGenerationMarkingVisitor final
}
Heap* heap_;
MinorMarkCompactCollector::MarkingWorklist worklist_;
MinorMarkCompactCollector::MarkingWorklist::View worklist_;
};
class MinorMarkCompactCollector::RootMarkingVisitor : public RootVisitor {
......@@ -2272,9 +2273,9 @@ class MarkingItem : public ItemParallelJob::Item {
class YoungGenerationMarkingTask : public ItemParallelJob::Task {
public:
YoungGenerationMarkingTask(Isolate* isolate,
MinorMarkCompactCollector* collector,
Worklist* global_worklist, int task_id)
YoungGenerationMarkingTask(
Isolate* isolate, MinorMarkCompactCollector* collector,
MinorMarkCompactCollector::MarkingWorklist* global_worklist, int task_id)
: ItemParallelJob::Task(isolate),
collector_(collector),
marking_worklist_(global_worklist, task_id),
......@@ -2347,7 +2348,7 @@ class YoungGenerationMarkingTask : public ItemParallelJob::Task {
}
MinorMarkCompactCollector* collector_;
MinorMarkCompactCollector::MarkingWorklist marking_worklist_;
MinorMarkCompactCollector::MarkingWorklist::View marking_worklist_;
YoungGenerationMarkingVisitor visitor_;
std::unordered_map<Page*, intptr_t, Page::Hasher> local_live_bytes_;
};
......@@ -2511,11 +2512,12 @@ class MinorMarkCompactCollector::RootMarkingVisitorSeedOnly
MinorMarkCompactCollector::MinorMarkCompactCollector(Heap* heap)
: MarkCompactCollectorBase(heap),
worklist_(new Worklist()),
worklist_(new MinorMarkCompactCollector::MarkingWorklist()),
main_marking_visitor_(
new YoungGenerationMarkingVisitor(heap, worklist_, kMainMarker)),
page_parallel_job_semaphore_(0) {
static_assert(kNumMarkers <= Worklist::kMaxNumTasks,
static_assert(
kNumMarkers <= MinorMarkCompactCollector::MarkingWorklist::kMaxNumTasks,
"more marker tasks than marking deque can handle");
}
......@@ -2617,7 +2619,7 @@ void MinorMarkCompactCollector::ProcessMarkingWorklist() {
}
void MinorMarkCompactCollector::EmptyMarkingWorklist() {
MarkingWorklist marking_worklist(worklist(), kMainMarker);
MarkingWorklist::View marking_worklist(worklist(), kMainMarker);
HeapObject* object = nullptr;
while (marking_worklist.Pop(&object)) {
DCHECK(!object->IsFiller());
......
......@@ -24,7 +24,9 @@ class ItemParallelJob;
class MigrationObserver;
class RecordMigratedSlotVisitor;
class YoungGenerationMarkingVisitor;
template <int SEGMENT_SIZE>
class Worklist;
template <int SEGMENT_SIZE>
class WorklistView;
class ObjectMarking : public AllStatic {
......@@ -348,14 +350,14 @@ class MinorMarkCompactCollector final : public MarkCompactCollectorBase {
void CleanupSweepToIteratePages();
private:
using MarkingWorklist = WorklistView;
using MarkingWorklist = Worklist<64 /* segment size */>;
class RootMarkingVisitorSeedOnly;
class RootMarkingVisitor;
static const int kNumMarkers = 8;
static const int kMainMarker = 0;
inline Worklist* worklist() { return worklist_; }
inline MarkingWorklist* worklist() { return worklist_; }
inline YoungGenerationMarkingVisitor* main_marking_visitor() {
return main_marking_visitor_;
......@@ -377,7 +379,7 @@ class MinorMarkCompactCollector final : public MarkCompactCollectorBase {
int NumberOfParallelMarkingTasks(int pages);
Worklist* worklist_;
MarkingWorklist* worklist_;
YoungGenerationMarkingVisitor* main_marking_visitor_;
base::Semaphore page_parallel_job_semaphore_;
std::vector<Page*> new_space_evacuation_pages_;
......@@ -394,6 +396,8 @@ class MarkCompactCollector final : public MarkCompactCollectorBase {
// Wrapper for the shared and bailout worklists.
class MarkingWorklist {
public:
using ConcurrentMarkingWorklist = Worklist<64>;
static const int kMainThread = 0;
// The heap parameter is not used but needed to match the sequential case.
explicit MarkingWorklist(Heap* heap) {}
......@@ -439,8 +443,8 @@ class MarkCompactCollector final : public MarkCompactCollectorBase {
shared_.Update(callback);
}
Worklist* shared() { return &shared_; }
Worklist* bailout() { return &bailout_; }
ConcurrentMarkingWorklist* shared() { return &shared_; }
ConcurrentMarkingWorklist* bailout() { return &bailout_; }
// These empty functions are needed to match the interface
// of the sequential marking deque.
......@@ -453,8 +457,8 @@ class MarkCompactCollector final : public MarkCompactCollectorBase {
bool overflowed() const { return false; }
private:
Worklist shared_;
Worklist bailout_;
ConcurrentMarkingWorklist shared_;
ConcurrentMarkingWorklist bailout_;
};
#else
using MarkingWorklist = SequentialMarkingDeque;
......
......@@ -25,10 +25,34 @@ class HeapObject;
//
// Work stealing is best effort, i.e., there is no way to inform other tasks
// of the need of items.
template <int SEGMENT_SIZE>
class Worklist {
public:
class View {
public:
View(Worklist<SEGMENT_SIZE>* worklist, int task_id)
: worklist_(worklist), task_id_(task_id) {}
// Pushes an object onto the worklist.
bool Push(HeapObject* object) { return worklist_->Push(task_id_, object); }
// Pops an object from the worklist.
bool Pop(HeapObject** object) { return worklist_->Pop(task_id_, object); }
// Returns true if the local portion of the worklist is empty.
bool IsLocalEmpty() { return worklist_->IsLocalEmpty(task_id_); }
// Returns true if the worklist is empty. Can only be used from the main
// thread without concurrent access.
bool IsGlobalEmpty() { return worklist_->IsGlobalEmpty(); }
private:
Worklist<SEGMENT_SIZE>* worklist_;
int task_id_;
};
static const int kMaxNumTasks = 8;
static const int kSegmentCapacity = 64;
static const int kSegmentCapacity = SEGMENT_SIZE;
Worklist() {
for (int i = 0; i < kMaxNumTasks; i++) {
......@@ -141,16 +165,17 @@ class Worklist {
}
private:
FRIEND_TEST(Worklist, SegmentCreate);
FRIEND_TEST(Worklist, SegmentPush);
FRIEND_TEST(Worklist, SegmentPushPop);
FRIEND_TEST(Worklist, SegmentIsEmpty);
FRIEND_TEST(Worklist, SegmentIsFull);
FRIEND_TEST(Worklist, SegmentClear);
FRIEND_TEST(Worklist, SegmentFullPushFails);
FRIEND_TEST(Worklist, SegmentEmptyPopFails);
FRIEND_TEST(Worklist, SegmentUpdateNull);
FRIEND_TEST(Worklist, SegmentUpdate);
using TestWorklist = Worklist<64>;
FRIEND_TEST(TestWorklist, SegmentCreate);
FRIEND_TEST(TestWorklist, SegmentPush);
FRIEND_TEST(TestWorklist, SegmentPushPop);
FRIEND_TEST(TestWorklist, SegmentIsEmpty);
FRIEND_TEST(TestWorklist, SegmentIsFull);
FRIEND_TEST(TestWorklist, SegmentClear);
FRIEND_TEST(TestWorklist, SegmentFullPushFails);
FRIEND_TEST(TestWorklist, SegmentEmptyPopFails);
FRIEND_TEST(TestWorklist, SegmentUpdateNull);
FRIEND_TEST(TestWorklist, SegmentUpdate);
class Segment {
public:
......@@ -227,29 +252,6 @@ class Worklist {
std::vector<Segment*> global_pool_;
};
class WorklistView {
public:
WorklistView(Worklist* worklist, int task_id)
: worklist_(worklist), task_id_(task_id) {}
// Pushes an object onto the worklist.
bool Push(HeapObject* object) { return worklist_->Push(task_id_, object); }
// Pops an object from the worklist.
bool Pop(HeapObject** object) { return worklist_->Pop(task_id_, object); }
// Returns true if the local portion of the worklist is empty.
bool IsLocalEmpty() { return worklist_->IsLocalEmpty(task_id_); }
// Returns true if the worklist is empty. Can only be used from the main
// thread without concurrent access.
bool IsGlobalEmpty() { return worklist_->IsGlobalEmpty(); }
private:
Worklist* worklist_;
int task_id_;
};
} // namespace internal
} // namespace v8
......
......@@ -19,8 +19,9 @@ TEST(ConcurrentMarking) {
if (!i::FLAG_concurrent_marking) return;
CcTest::InitializeVM();
Heap* heap = CcTest::heap();
Worklist shared, bailout;
for (int i = 0; i <= Worklist::kSegmentCapacity; i++) {
ConcurrentMarking::MarkingWorklist shared, bailout;
for (int i = 0; i <= ConcurrentMarking::MarkingWorklist::kSegmentCapacity;
i++) {
shared.Push(0, heap->undefined_value());
}
HeapObject* object;
......
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment