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 ...@@ -48,7 +48,8 @@ class ConcurrentMarkingVisitor final
public: public:
using BaseClass = HeapVisitor<int, ConcurrentMarkingVisitor>; using BaseClass = HeapVisitor<int, ConcurrentMarkingVisitor>;
explicit ConcurrentMarkingVisitor(Worklist* shared, Worklist* bailout, explicit ConcurrentMarkingVisitor(ConcurrentMarking::MarkingWorklist* shared,
ConcurrentMarking::MarkingWorklist* bailout,
int task_id) int task_id)
: shared_(shared, task_id), bailout_(bailout, task_id) {} : shared_(shared, task_id), bailout_(bailout, task_id) {}
...@@ -246,8 +247,8 @@ class ConcurrentMarkingVisitor final ...@@ -246,8 +247,8 @@ class ConcurrentMarkingVisitor final
return MarkingState::Internal(object); return MarkingState::Internal(object);
} }
WorklistView shared_; ConcurrentMarking::MarkingWorklist::View shared_;
WorklistView bailout_; ConcurrentMarking::MarkingWorklist::View bailout_;
SlotSnapshot slot_snapshot_; SlotSnapshot slot_snapshot_;
}; };
...@@ -275,8 +276,8 @@ class ConcurrentMarking::Task : public CancelableTask { ...@@ -275,8 +276,8 @@ class ConcurrentMarking::Task : public CancelableTask {
DISALLOW_COPY_AND_ASSIGN(Task); DISALLOW_COPY_AND_ASSIGN(Task);
}; };
ConcurrentMarking::ConcurrentMarking(Heap* heap, Worklist* shared, ConcurrentMarking::ConcurrentMarking(Heap* heap, MarkingWorklist* shared,
Worklist* bailout) MarkingWorklist* bailout)
: heap_(heap), : heap_(heap),
pending_task_semaphore_(0), pending_task_semaphore_(0),
shared_(shared), shared_(shared),
......
...@@ -15,11 +15,15 @@ namespace internal { ...@@ -15,11 +15,15 @@ namespace internal {
class Heap; class Heap;
class Isolate; class Isolate;
template <int SEGMENT_SIZE>
class Worklist; class Worklist;
class ConcurrentMarking { class ConcurrentMarking {
public: public:
ConcurrentMarking(Heap* heap, Worklist* shared_, Worklist* bailout_); using MarkingWorklist = Worklist<64 /* segment size */>;
ConcurrentMarking(Heap* heap, MarkingWorklist* shared_,
MarkingWorklist* bailout_);
void StartTask(); void StartTask();
void WaitForTaskToComplete(); void WaitForTaskToComplete();
...@@ -31,8 +35,8 @@ class ConcurrentMarking { ...@@ -31,8 +35,8 @@ class ConcurrentMarking {
void Run(int task_id); void Run(int task_id);
Heap* heap_; Heap* heap_;
base::Semaphore pending_task_semaphore_; base::Semaphore pending_task_semaphore_;
Worklist* shared_; MarkingWorklist* shared_;
Worklist* bailout_; MarkingWorklist* bailout_;
bool is_task_pending_; bool is_task_pending_;
}; };
......
...@@ -2182,8 +2182,9 @@ void MarkCompactCollector::RecordObjectStats() { ...@@ -2182,8 +2182,9 @@ void MarkCompactCollector::RecordObjectStats() {
class YoungGenerationMarkingVisitor final class YoungGenerationMarkingVisitor final
: public NewSpaceVisitor<YoungGenerationMarkingVisitor> { : public NewSpaceVisitor<YoungGenerationMarkingVisitor> {
public: public:
YoungGenerationMarkingVisitor(Heap* heap, Worklist* global_worklist, YoungGenerationMarkingVisitor(
int task_id) Heap* heap, MinorMarkCompactCollector::MarkingWorklist* global_worklist,
int task_id)
: heap_(heap), worklist_(global_worklist, task_id) {} : heap_(heap), worklist_(global_worklist, task_id) {}
V8_INLINE void VisitPointers(HeapObject* host, Object** start, V8_INLINE void VisitPointers(HeapObject* host, Object** start,
...@@ -2218,7 +2219,7 @@ class YoungGenerationMarkingVisitor final ...@@ -2218,7 +2219,7 @@ class YoungGenerationMarkingVisitor final
} }
Heap* heap_; Heap* heap_;
MinorMarkCompactCollector::MarkingWorklist worklist_; MinorMarkCompactCollector::MarkingWorklist::View worklist_;
}; };
class MinorMarkCompactCollector::RootMarkingVisitor : public RootVisitor { class MinorMarkCompactCollector::RootMarkingVisitor : public RootVisitor {
...@@ -2272,9 +2273,9 @@ class MarkingItem : public ItemParallelJob::Item { ...@@ -2272,9 +2273,9 @@ class MarkingItem : public ItemParallelJob::Item {
class YoungGenerationMarkingTask : public ItemParallelJob::Task { class YoungGenerationMarkingTask : public ItemParallelJob::Task {
public: public:
YoungGenerationMarkingTask(Isolate* isolate, YoungGenerationMarkingTask(
MinorMarkCompactCollector* collector, Isolate* isolate, MinorMarkCompactCollector* collector,
Worklist* global_worklist, int task_id) MinorMarkCompactCollector::MarkingWorklist* global_worklist, int task_id)
: ItemParallelJob::Task(isolate), : ItemParallelJob::Task(isolate),
collector_(collector), collector_(collector),
marking_worklist_(global_worklist, task_id), marking_worklist_(global_worklist, task_id),
...@@ -2347,7 +2348,7 @@ class YoungGenerationMarkingTask : public ItemParallelJob::Task { ...@@ -2347,7 +2348,7 @@ class YoungGenerationMarkingTask : public ItemParallelJob::Task {
} }
MinorMarkCompactCollector* collector_; MinorMarkCompactCollector* collector_;
MinorMarkCompactCollector::MarkingWorklist marking_worklist_; MinorMarkCompactCollector::MarkingWorklist::View marking_worklist_;
YoungGenerationMarkingVisitor visitor_; YoungGenerationMarkingVisitor visitor_;
std::unordered_map<Page*, intptr_t, Page::Hasher> local_live_bytes_; std::unordered_map<Page*, intptr_t, Page::Hasher> local_live_bytes_;
}; };
...@@ -2511,12 +2512,13 @@ class MinorMarkCompactCollector::RootMarkingVisitorSeedOnly ...@@ -2511,12 +2512,13 @@ class MinorMarkCompactCollector::RootMarkingVisitorSeedOnly
MinorMarkCompactCollector::MinorMarkCompactCollector(Heap* heap) MinorMarkCompactCollector::MinorMarkCompactCollector(Heap* heap)
: MarkCompactCollectorBase(heap), : MarkCompactCollectorBase(heap),
worklist_(new Worklist()), worklist_(new MinorMarkCompactCollector::MarkingWorklist()),
main_marking_visitor_( main_marking_visitor_(
new YoungGenerationMarkingVisitor(heap, worklist_, kMainMarker)), new YoungGenerationMarkingVisitor(heap, worklist_, kMainMarker)),
page_parallel_job_semaphore_(0) { page_parallel_job_semaphore_(0) {
static_assert(kNumMarkers <= Worklist::kMaxNumTasks, static_assert(
"more marker tasks than marking deque can handle"); kNumMarkers <= MinorMarkCompactCollector::MarkingWorklist::kMaxNumTasks,
"more marker tasks than marking deque can handle");
} }
MinorMarkCompactCollector::~MinorMarkCompactCollector() { MinorMarkCompactCollector::~MinorMarkCompactCollector() {
...@@ -2617,7 +2619,7 @@ void MinorMarkCompactCollector::ProcessMarkingWorklist() { ...@@ -2617,7 +2619,7 @@ void MinorMarkCompactCollector::ProcessMarkingWorklist() {
} }
void MinorMarkCompactCollector::EmptyMarkingWorklist() { void MinorMarkCompactCollector::EmptyMarkingWorklist() {
MarkingWorklist marking_worklist(worklist(), kMainMarker); MarkingWorklist::View marking_worklist(worklist(), kMainMarker);
HeapObject* object = nullptr; HeapObject* object = nullptr;
while (marking_worklist.Pop(&object)) { while (marking_worklist.Pop(&object)) {
DCHECK(!object->IsFiller()); DCHECK(!object->IsFiller());
......
...@@ -24,7 +24,9 @@ class ItemParallelJob; ...@@ -24,7 +24,9 @@ class ItemParallelJob;
class MigrationObserver; class MigrationObserver;
class RecordMigratedSlotVisitor; class RecordMigratedSlotVisitor;
class YoungGenerationMarkingVisitor; class YoungGenerationMarkingVisitor;
template <int SEGMENT_SIZE>
class Worklist; class Worklist;
template <int SEGMENT_SIZE>
class WorklistView; class WorklistView;
class ObjectMarking : public AllStatic { class ObjectMarking : public AllStatic {
...@@ -348,14 +350,14 @@ class MinorMarkCompactCollector final : public MarkCompactCollectorBase { ...@@ -348,14 +350,14 @@ class MinorMarkCompactCollector final : public MarkCompactCollectorBase {
void CleanupSweepToIteratePages(); void CleanupSweepToIteratePages();
private: private:
using MarkingWorklist = WorklistView; using MarkingWorklist = Worklist<64 /* segment size */>;
class RootMarkingVisitorSeedOnly; class RootMarkingVisitorSeedOnly;
class RootMarkingVisitor; class RootMarkingVisitor;
static const int kNumMarkers = 8; static const int kNumMarkers = 8;
static const int kMainMarker = 0; static const int kMainMarker = 0;
inline Worklist* worklist() { return worklist_; } inline MarkingWorklist* worklist() { return worklist_; }
inline YoungGenerationMarkingVisitor* main_marking_visitor() { inline YoungGenerationMarkingVisitor* main_marking_visitor() {
return main_marking_visitor_; return main_marking_visitor_;
...@@ -377,7 +379,7 @@ class MinorMarkCompactCollector final : public MarkCompactCollectorBase { ...@@ -377,7 +379,7 @@ class MinorMarkCompactCollector final : public MarkCompactCollectorBase {
int NumberOfParallelMarkingTasks(int pages); int NumberOfParallelMarkingTasks(int pages);
Worklist* worklist_; MarkingWorklist* worklist_;
YoungGenerationMarkingVisitor* main_marking_visitor_; YoungGenerationMarkingVisitor* main_marking_visitor_;
base::Semaphore page_parallel_job_semaphore_; base::Semaphore page_parallel_job_semaphore_;
std::vector<Page*> new_space_evacuation_pages_; std::vector<Page*> new_space_evacuation_pages_;
...@@ -394,6 +396,8 @@ class MarkCompactCollector final : public MarkCompactCollectorBase { ...@@ -394,6 +396,8 @@ class MarkCompactCollector final : public MarkCompactCollectorBase {
// Wrapper for the shared and bailout worklists. // Wrapper for the shared and bailout worklists.
class MarkingWorklist { class MarkingWorklist {
public: public:
using ConcurrentMarkingWorklist = Worklist<64>;
static const int kMainThread = 0; static const int kMainThread = 0;
// The heap parameter is not used but needed to match the sequential case. // The heap parameter is not used but needed to match the sequential case.
explicit MarkingWorklist(Heap* heap) {} explicit MarkingWorklist(Heap* heap) {}
...@@ -439,8 +443,8 @@ class MarkCompactCollector final : public MarkCompactCollectorBase { ...@@ -439,8 +443,8 @@ class MarkCompactCollector final : public MarkCompactCollectorBase {
shared_.Update(callback); shared_.Update(callback);
} }
Worklist* shared() { return &shared_; } ConcurrentMarkingWorklist* shared() { return &shared_; }
Worklist* bailout() { return &bailout_; } ConcurrentMarkingWorklist* bailout() { return &bailout_; }
// These empty functions are needed to match the interface // These empty functions are needed to match the interface
// of the sequential marking deque. // of the sequential marking deque.
...@@ -453,8 +457,8 @@ class MarkCompactCollector final : public MarkCompactCollectorBase { ...@@ -453,8 +457,8 @@ class MarkCompactCollector final : public MarkCompactCollectorBase {
bool overflowed() const { return false; } bool overflowed() const { return false; }
private: private:
Worklist shared_; ConcurrentMarkingWorklist shared_;
Worklist bailout_; ConcurrentMarkingWorklist bailout_;
}; };
#else #else
using MarkingWorklist = SequentialMarkingDeque; using MarkingWorklist = SequentialMarkingDeque;
......
...@@ -25,10 +25,34 @@ class HeapObject; ...@@ -25,10 +25,34 @@ class HeapObject;
// //
// Work stealing is best effort, i.e., there is no way to inform other tasks // Work stealing is best effort, i.e., there is no way to inform other tasks
// of the need of items. // of the need of items.
template <int SEGMENT_SIZE>
class Worklist { class Worklist {
public: 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 kMaxNumTasks = 8;
static const int kSegmentCapacity = 64; static const int kSegmentCapacity = SEGMENT_SIZE;
Worklist() { Worklist() {
for (int i = 0; i < kMaxNumTasks; i++) { for (int i = 0; i < kMaxNumTasks; i++) {
...@@ -141,16 +165,17 @@ class Worklist { ...@@ -141,16 +165,17 @@ class Worklist {
} }
private: private:
FRIEND_TEST(Worklist, SegmentCreate); using TestWorklist = Worklist<64>;
FRIEND_TEST(Worklist, SegmentPush); FRIEND_TEST(TestWorklist, SegmentCreate);
FRIEND_TEST(Worklist, SegmentPushPop); FRIEND_TEST(TestWorklist, SegmentPush);
FRIEND_TEST(Worklist, SegmentIsEmpty); FRIEND_TEST(TestWorklist, SegmentPushPop);
FRIEND_TEST(Worklist, SegmentIsFull); FRIEND_TEST(TestWorklist, SegmentIsEmpty);
FRIEND_TEST(Worklist, SegmentClear); FRIEND_TEST(TestWorklist, SegmentIsFull);
FRIEND_TEST(Worklist, SegmentFullPushFails); FRIEND_TEST(TestWorklist, SegmentClear);
FRIEND_TEST(Worklist, SegmentEmptyPopFails); FRIEND_TEST(TestWorklist, SegmentFullPushFails);
FRIEND_TEST(Worklist, SegmentUpdateNull); FRIEND_TEST(TestWorklist, SegmentEmptyPopFails);
FRIEND_TEST(Worklist, SegmentUpdate); FRIEND_TEST(TestWorklist, SegmentUpdateNull);
FRIEND_TEST(TestWorklist, SegmentUpdate);
class Segment { class Segment {
public: public:
...@@ -227,29 +252,6 @@ class Worklist { ...@@ -227,29 +252,6 @@ class Worklist {
std::vector<Segment*> global_pool_; 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 internal
} // namespace v8 } // namespace v8
......
...@@ -19,8 +19,9 @@ TEST(ConcurrentMarking) { ...@@ -19,8 +19,9 @@ TEST(ConcurrentMarking) {
if (!i::FLAG_concurrent_marking) return; if (!i::FLAG_concurrent_marking) return;
CcTest::InitializeVM(); CcTest::InitializeVM();
Heap* heap = CcTest::heap(); Heap* heap = CcTest::heap();
Worklist shared, bailout; ConcurrentMarking::MarkingWorklist shared, bailout;
for (int i = 0; i <= Worklist::kSegmentCapacity; i++) { for (int i = 0; i <= ConcurrentMarking::MarkingWorklist::kSegmentCapacity;
i++) {
shared.Push(0, heap->undefined_value()); shared.Push(0, heap->undefined_value());
} }
HeapObject* object; 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