Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(161)

Side by Side Diff: src/heap/page-parallel-job.h

Issue 1775003003: Implement parallel pointer updates after evacuation. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Rebase Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/heap/mark-compact.cc ('k') | src/heap/remembered-set.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2016 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #ifndef V8_HEAP_PAGE_PARALLEL_JOB_
6 #define V8_HEAP_PAGE_PARALLEL_JOB_
7
8 #include "src/allocation.h"
9 #include "src/cancelable-task.h"
10 #include "src/utils.h"
11 #include "src/v8.h"
12
13 namespace v8 {
14 namespace internal {
15
16 class Heap;
17 class Isolate;
18
19 // This class manages background tasks that process set of pages in parallel.
20 // The JobTraits class needs to define:
21 // - PerPageData type - state associated with each page.
22 // - PerTaskData type - state associated with each task.
23 // - static bool ProcessPageInParallel(Heap* heap,
24 // PerTaskData task_data,
25 // MemoryChunk* page,
26 // PerPageData page_data)
27 // The function should return true iff processing succeeded.
28 // - static const bool NeedSequentialFinalization
29 // - static void FinalizePageSequentially(Heap* heap,
30 // bool processing_succeeded,
31 // MemoryChunk* page,
32 // PerPageData page_data)
33 template <typename JobTraits>
34 class PageParallelJob {
35 public:
36 PageParallelJob(Heap* heap, CancelableTaskManager* cancelable_task_manager)
37 : heap_(heap),
38 cancelable_task_manager_(cancelable_task_manager),
39 items_(nullptr),
40 num_items_(0),
41 pending_tasks_(0) {}
42
43 ~PageParallelJob() {
44 Item* item = items_;
45 while (item != nullptr) {
46 Item* next = item->next;
47 delete item;
48 item = next;
49 }
50 }
51
52 void AddPage(MemoryChunk* chunk, typename JobTraits::PerPageData data) {
53 Item* item = new Item(chunk, data, items_);
54 items_ = item;
55 ++num_items_;
56 }
57
58 int NumberOfPages() { return num_items_; }
59
60 // Runs the given number of tasks in parallel and processes the previosly
61 // added pages. This function blocks until all tasks finish.
62 // The callback takes the index of a task and returns data for that task.
63 template <typename Callback>
64 void Run(int num_tasks, Callback per_task_data_callback) {
65 if (num_items_ == 0) return;
66 DCHECK_GE(num_tasks, 1);
67 uint32_t task_ids[kMaxNumberOfTasks];
68 const int max_num_tasks = Min(
69 kMaxNumberOfTasks,
70 static_cast<int>(
71 V8::GetCurrentPlatform()->NumberOfAvailableBackgroundThreads()));
72 num_tasks = Max(1, Min(num_tasks, max_num_tasks));
73 int items_per_task = (num_items_ + num_tasks - 1) / num_tasks;
74 int start_index = 0;
75 Task* main_task = nullptr;
76 for (int i = 0; i < num_tasks; i++, start_index += items_per_task) {
77 if (start_index >= num_items_) {
78 start_index -= num_items_;
79 }
80 Task* task = new Task(heap_, items_, num_items_, start_index,
81 &pending_tasks_, per_task_data_callback(i));
82 task_ids[i] = task->id();
83 if (i > 0) {
84 V8::GetCurrentPlatform()->CallOnBackgroundThread(
85 task, v8::Platform::kShortRunningTask);
86 } else {
87 main_task = task;
88 }
89 }
90 // Contribute on main thread.
91 main_task->Run();
92 delete main_task;
93 // Wait for background tasks.
94 for (int i = 0; i < num_tasks; i++) {
95 if (!cancelable_task_manager_->TryAbort(task_ids[i])) {
96 pending_tasks_.Wait();
97 }
98 }
99 if (JobTraits::NeedSequentialFinalization) {
100 Item* item = items_;
101 while (item != nullptr) {
102 bool success = (item->state.Value() == kFinished);
103 JobTraits::FinalizePageSequentially(heap_, item->chunk, success,
104 item->data);
105 item = item->next;
106 }
107 }
108 }
109
110 private:
111 static const int kMaxNumberOfTasks = 10;
112
113 enum ProcessingState { kAvailable, kProcessing, kFinished, kFailed };
114
115 struct Item : public Malloced {
116 Item(MemoryChunk* chunk, typename JobTraits::PerPageData data, Item* next)
117 : chunk(chunk), state(kAvailable), data(data), next(next) {}
118 MemoryChunk* chunk;
119 AtomicValue<ProcessingState> state;
120 typename JobTraits::PerPageData data;
121 Item* next;
122 };
123
124 class Task : public CancelableTask {
125 public:
126 Task(Heap* heap, Item* items, int num_items, int start_index,
127 base::Semaphore* on_finish, typename JobTraits::PerTaskData data)
128 : CancelableTask(heap->isolate()),
129 heap_(heap),
130 items_(items),
131 num_items_(num_items),
132 start_index_(start_index),
133 on_finish_(on_finish),
134 data_(data) {}
135
136 virtual ~Task() {}
137
138 private:
139 // v8::internal::CancelableTask overrides.
140 void RunInternal() override {
141 // Each task starts at a different index to improve parallelization.
142 Item* current = items_;
143 int skip = start_index_;
144 while (skip-- > 0) {
145 current = current->next;
146 }
147 for (int i = 0; i < num_items_; i++) {
148 if (current->state.TrySetValue(kAvailable, kProcessing)) {
149 bool success = JobTraits::ProcessPageInParallel(
150 heap_, data_, current->chunk, current->data);
151 current->state.SetValue(success ? kFinished : kFailed);
152 }
153 current = current->next;
154 // Wrap around if needed.
155 if (current == nullptr) {
156 current = items_;
157 }
158 }
159 on_finish_->Signal();
160 }
161
162 Heap* heap_;
163 Item* items_;
164 int num_items_;
165 int start_index_;
166 base::Semaphore* on_finish_;
167 typename JobTraits::PerTaskData data_;
168 DISALLOW_COPY_AND_ASSIGN(Task);
169 };
170
171 Heap* heap_;
172 CancelableTaskManager* cancelable_task_manager_;
173 Item* items_;
174 int num_items_;
175 base::Semaphore pending_tasks_;
176 DISALLOW_COPY_AND_ASSIGN(PageParallelJob);
177 };
178
179 } // namespace internal
180 } // namespace v8
181
182 #endif // V8_HEAP_PAGE_PARALLEL_JOB_
OLDNEW
« no previous file with comments | « src/heap/mark-compact.cc ('k') | src/heap/remembered-set.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698