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

Side by Side Diff: src/compiler-dispatcher/compiler-dispatcher.cc

Issue 2611313002: [complier] Enable parallel eager inner function compilation with compiler dispatcher. (Closed)
Patch Set: Created 3 years, 11 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
OLDNEW
1 // Copyright 2016 the V8 project authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/compiler-dispatcher/compiler-dispatcher.h" 5 #include "src/compiler-dispatcher/compiler-dispatcher.h"
6 6
7 #include "include/v8-platform.h" 7 #include "include/v8-platform.h"
8 #include "include/v8.h" 8 #include "include/v8.h"
9 #include "src/base/platform/time.h" 9 #include "src/base/platform/time.h"
10 #include "src/cancelable-task.h" 10 #include "src/cancelable-task.h"
11 #include "src/compilation-info.h"
11 #include "src/compiler-dispatcher/compiler-dispatcher-job.h" 12 #include "src/compiler-dispatcher/compiler-dispatcher-job.h"
12 #include "src/compiler-dispatcher/compiler-dispatcher-tracer.h" 13 #include "src/compiler-dispatcher/compiler-dispatcher-tracer.h"
13 #include "src/flags.h" 14 #include "src/flags.h"
14 #include "src/objects-inl.h" 15 #include "src/objects-inl.h"
15 16
16 namespace v8 { 17 namespace v8 {
17 namespace internal { 18 namespace internal {
18 19
19 namespace { 20 namespace {
20 21
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after
219 PrintF("CompilerDispatcher: dispatcher is disabled\n"); 220 PrintF("CompilerDispatcher: dispatcher is disabled\n");
220 } 221 }
221 } 222 }
222 223
223 CompilerDispatcher::~CompilerDispatcher() { 224 CompilerDispatcher::~CompilerDispatcher() {
224 // To avoid crashing in unit tests due to unfished jobs. 225 // To avoid crashing in unit tests due to unfished jobs.
225 AbortAll(BlockingBehavior::kBlock); 226 AbortAll(BlockingBehavior::kBlock);
226 task_manager_->CancelAndWait(); 227 task_manager_->CancelAndWait();
227 } 228 }
228 229
229 bool CompilerDispatcher::Enqueue(Handle<SharedFunctionInfo> function) { 230 bool CompilerDispatcher::CanEnqueueJobs() {
230 if (!IsEnabled()) return false; 231 if (!IsEnabled()) return false;
231 232
232 if (memory_pressure_level_.Value() != MemoryPressureLevel::kNone) { 233 if (memory_pressure_level_.Value() != MemoryPressureLevel::kNone) {
233 return false; 234 return false;
234 } 235 }
235 236
236 { 237 {
237 base::LockGuard<base::Mutex> lock(&mutex_); 238 base::LockGuard<base::Mutex> lock(&mutex_);
238 if (abort_) return false; 239 return !abort_;
239 } 240 }
241 }
242
243 bool CompilerDispatcher::Enqueue(Handle<SharedFunctionInfo> function) {
244 if (!CanEnqueueJobs()) return false;
240 245
241 // We only handle functions (no eval / top-level code / wasm) that are 246 // We only handle functions (no eval / top-level code / wasm) that are
242 // attached to a script. 247 // attached to a script.
243 if (!function->script()->IsScript() || !function->is_function() || 248 if (!function->script()->IsScript() || !function->is_function() ||
244 function->asm_function() || function->native()) { 249 function->asm_function() || function->native()) {
245 return false; 250 return false;
marja 2017/01/10 09:58:54 Doesn't this break the "if enqueue fails, it must
rmcilroy 2017/01/12 12:31:55 Yeah, this was part of the WIP stuff I hadn't quit
246 } 251 }
247 252
248 if (IsEnqueued(function)) return true; 253 if (IsEnqueued(function)) return true;
249 254
250 if (trace_compiler_dispatcher_) { 255 if (trace_compiler_dispatcher_) {
251 PrintF("CompilerDispatcher: enqueuing "); 256 PrintF("CompilerDispatcher: enqueuing ");
252 function->ShortPrint(); 257 function->ShortPrint();
253 PrintF("\n"); 258 PrintF(" for parse and compile\n");
254 } 259 }
255 260
256 std::unique_ptr<CompilerDispatcherJob> job(new CompilerDispatcherJob( 261 std::unique_ptr<CompilerDispatcherJob> job(new CompilerDispatcherJob(
257 isolate_, tracer_.get(), function, max_stack_size_)); 262 isolate_, tracer_.get(), function, max_stack_size_));
258 std::pair<int, int> key(Script::cast(function->script())->id(), 263 std::pair<int, int> key(Script::cast(function->script())->id(),
259 function->function_literal_id()); 264 function->function_literal_id());
260 jobs_.insert(std::make_pair(key, std::move(job))); 265 jobs_.insert(std::make_pair(key, std::move(job)));
261 ScheduleIdleTaskIfNeeded(); 266 ScheduleIdleTaskIfNeeded();
262 return true; 267 return true;
263 } 268 }
264 269
270 bool CompilerDispatcher::Enqueue(Zone* zone, ParseInfo* parse_info,
271 CompilationInfo* compile_info,
272 CompilationJob* compilation_job) {
273 if (!CanEnqueueJobs()) return false;
274
275 DCHECK(compile_info->has_shared_info());
276 Handle<SharedFunctionInfo> function = compile_info->shared_info();
277
278 if (IsEnqueued(function)) return true;
279
280 if (trace_compiler_dispatcher_) {
281 PrintF("CompilerDispatcher: enqueuing");
282 function->ShortPrint();
283 PrintF(" for compile\n");
284 }
285
286 CompilerDispatcherJob* job(new CompilerDispatcherJob(
287 isolate_, tracer_.get(), zone, parse_info, compile_info, compilation_job,
288 max_stack_size_));
289 std::pair<int, int> key(Script::cast(function->script())->id(),
290 function->function_literal_id());
291 jobs_.insert(std::make_pair(key, job));
292 ConsiderJobForBackgroundProcessing(job);
293 ScheduleIdleTaskIfNeeded();
294 return true;
295 }
296
265 bool CompilerDispatcher::IsEnabled() const { 297 bool CompilerDispatcher::IsEnabled() const {
266 v8::Isolate* v8_isolate = reinterpret_cast<v8::Isolate*>(isolate_); 298 v8::Isolate* v8_isolate = reinterpret_cast<v8::Isolate*>(isolate_);
267 return FLAG_compiler_dispatcher && platform_->IdleTasksEnabled(v8_isolate); 299 return FLAG_compiler_dispatcher && platform_->IdleTasksEnabled(v8_isolate);
268 } 300 }
269 301
270 bool CompilerDispatcher::IsEnqueued(Handle<SharedFunctionInfo> function) const { 302 bool CompilerDispatcher::IsEnqueued(Handle<SharedFunctionInfo> function) const {
271 return GetJobFor(function) != jobs_.end(); 303 return GetJobFor(function) != jobs_.end();
272 } 304 }
273 305
274 void CompilerDispatcher::WaitForJobIfRunningOnBackground( 306 void CompilerDispatcher::WaitForJobIfRunningOnBackground(
275 CompilerDispatcherJob* job) { 307 CompilerDispatcherJob* job) {
276 base::LockGuard<base::Mutex> lock(&mutex_); 308 base::LockGuard<base::Mutex> lock(&mutex_);
277 if (running_background_jobs_.find(job) == running_background_jobs_.end()) { 309 if (running_background_jobs_.find(job) == running_background_jobs_.end()) {
278 pending_background_jobs_.erase(job); 310 pending_background_jobs_.erase(job);
279 return; 311 return;
280 } 312 }
281 DCHECK_NULL(main_thread_blocking_on_job_); 313 DCHECK_NULL(main_thread_blocking_on_job_);
282 main_thread_blocking_on_job_ = job; 314 main_thread_blocking_on_job_ = job;
283 while (main_thread_blocking_on_job_ != nullptr) { 315 while (main_thread_blocking_on_job_ != nullptr) {
284 main_thread_blocking_signal_.Wait(&mutex_); 316 main_thread_blocking_signal_.Wait(&mutex_);
285 } 317 }
286 DCHECK(pending_background_jobs_.find(job) == pending_background_jobs_.end()); 318 DCHECK(pending_background_jobs_.find(job) == pending_background_jobs_.end());
287 DCHECK(running_background_jobs_.find(job) == running_background_jobs_.end()); 319 DCHECK(running_background_jobs_.find(job) == running_background_jobs_.end());
288 } 320 }
289 321
322 bool CompilerDispatcher::FinishNow(CompilerDispatcherJob* job) {
323 WaitForJobIfRunningOnBackground(job);
324 while (!IsFinished(job)) {
325 DoNextStepOnMainThread(isolate_, job, ExceptionHandling::kThrow);
326 }
327 bool result = job->status() != CompileJobStatus::kFailed;
328 job->ResetOnMainThread();
329 return result;
330 }
331
290 bool CompilerDispatcher::FinishNow(Handle<SharedFunctionInfo> function) { 332 bool CompilerDispatcher::FinishNow(Handle<SharedFunctionInfo> function) {
291 JobMap::const_iterator job = GetJobFor(function); 333 JobMap::const_iterator job = GetJobFor(function);
292 CHECK(job != jobs_.end()); 334 CHECK(job != jobs_.end());
293 335
294 if (trace_compiler_dispatcher_) { 336 if (trace_compiler_dispatcher_) {
295 PrintF("CompilerDispatcher: finishing "); 337 PrintF("CompilerDispatcher: finishing ");
296 function->ShortPrint(); 338 function->ShortPrint();
297 PrintF(" now\n"); 339 PrintF(" now\n");
298 } 340 }
299 341
300 WaitForJobIfRunningOnBackground(job->second.get()); 342 bool result = FinishNow(job->second.get());
301 while (!IsFinished(job->second.get())) {
302 DoNextStepOnMainThread(isolate_, job->second.get(),
303 ExceptionHandling::kThrow);
304 }
305 bool result = job->second->status() != CompileJobStatus::kFailed;
306 343
307 if (trace_compiler_dispatcher_) { 344 if (trace_compiler_dispatcher_) {
308 PrintF("CompilerDispatcher: finished working on "); 345 PrintF("CompilerDispatcher: finished working on ");
309 function->ShortPrint(); 346 function->ShortPrint();
310 PrintF(": %s\n", result ? "success" : "failure"); 347 PrintF(": %s\n", result ? "success" : "failure");
311 tracer_->DumpStatistics(); 348 tracer_->DumpStatistics();
312 } 349 }
313 350
314 job->second->ResetOnMainThread();
315 jobs_.erase(job); 351 jobs_.erase(job);
316 if (jobs_.empty()) { 352 if (jobs_.empty()) {
317 base::LockGuard<base::Mutex> lock(&mutex_); 353 base::LockGuard<base::Mutex> lock(&mutex_);
318 abort_ = false; 354 abort_ = false;
319 } 355 }
320 return result; 356 return result;
321 } 357 }
322 358
359 void CompilerDispatcher::FinishAllNow() {
360 if (trace_compiler_dispatcher_) {
361 PrintF("CompilerDispatcher: finishing all jobs now\n");
362 }
363
364 for (auto& it : jobs_) {
365 FinishNow(it.second.get());
366 }
367
368 if (trace_compiler_dispatcher_) {
369 PrintF("CompilerDispatcher: finished all jobs\n");
370 }
371
372 jobs_.clear();
373 {
374 base::LockGuard<base::Mutex> lock(&mutex_);
375 DCHECK(pending_background_jobs_.empty());
376 DCHECK(running_background_jobs_.empty());
377 abort_ = false;
378 }
379 }
380
323 void CompilerDispatcher::AbortAll(BlockingBehavior blocking) { 381 void CompilerDispatcher::AbortAll(BlockingBehavior blocking) {
324 bool background_tasks_running = 382 bool background_tasks_running =
325 task_manager_->TryAbortAll() == CancelableTaskManager::kTaskRunning; 383 task_manager_->TryAbortAll() == CancelableTaskManager::kTaskRunning;
326 if (!background_tasks_running || blocking == BlockingBehavior::kBlock) { 384 if (!background_tasks_running || blocking == BlockingBehavior::kBlock) {
327 for (auto& it : jobs_) { 385 for (auto& it : jobs_) {
328 WaitForJobIfRunningOnBackground(it.second.get()); 386 WaitForJobIfRunningOnBackground(it.second.get());
329 if (trace_compiler_dispatcher_) { 387 if (trace_compiler_dispatcher_) {
330 PrintF("CompilerDispatcher: aborted "); 388 PrintF("CompilerDispatcher: aborted ");
331 it.second->ShortPrint(); 389 it.second->ShortPrint();
332 PrintF("\n"); 390 PrintF("\n");
333 } 391 }
334 it.second->ResetOnMainThread(); 392 it.second->ResetOnMainThread();
335 } 393 }
336 jobs_.clear(); 394 jobs_.clear();
337 { 395 {
338 base::LockGuard<base::Mutex> lock(&mutex_); 396 base::LockGuard<base::Mutex> lock(&mutex_);
339 DCHECK(pending_background_jobs_.empty()); 397 DCHECK(pending_background_jobs_.empty());
340 DCHECK(running_background_jobs_.empty()); 398 DCHECK(running_background_jobs_.empty());
341 abort_ = false; 399 abort_ = false;
342 } 400 }
343 return;
marja 2017/01/10 09:58:54 Why?
rmcilroy 2017/01/12 12:31:55 Opps not sure how that happened - that explains th
344 } 401 }
345 402
346 { 403 {
347 base::LockGuard<base::Mutex> lock(&mutex_); 404 base::LockGuard<base::Mutex> lock(&mutex_);
348 abort_ = true; 405 abort_ = true;
349 pending_background_jobs_.clear(); 406 pending_background_jobs_.clear();
350 } 407 }
351 AbortInactiveJobs(); 408 AbortInactiveJobs();
352 409
353 // All running background jobs might already have scheduled idle tasks instead 410 // All running background jobs might already have scheduled idle tasks instead
(...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after
607 lock.reset(); 664 lock.reset();
608 DoNextStepOnMainThread(isolate_, job->second.get(), 665 DoNextStepOnMainThread(isolate_, job->second.get(),
609 ExceptionHandling::kSwallow); 666 ExceptionHandling::kSwallow);
610 } 667 }
611 } 668 }
612 if (jobs_.size() > too_long_jobs) ScheduleIdleTaskIfNeeded(); 669 if (jobs_.size() > too_long_jobs) ScheduleIdleTaskIfNeeded();
613 } 670 }
614 671
615 } // namespace internal 672 } // namespace internal
616 } // namespace v8 673 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698