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

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

Issue 2686673002: [Compiler] Avoid blocking on inner function parallel compilation. (Closed)
Patch Set: Add another test Created 3 years, 10 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"
(...skipping 270 matching lines...) Expand 10 before | Expand all | Expand 10 after
281 PrintF("\n"); 281 PrintF("\n");
282 } 282 }
283 JobMap::const_iterator job = GetJobFor(function); 283 JobMap::const_iterator job = GetJobFor(function);
284 DoNextStepOnMainThread(isolate_, job->second.get(), 284 DoNextStepOnMainThread(isolate_, job->second.get(),
285 ExceptionHandling::kSwallow); 285 ExceptionHandling::kSwallow);
286 ConsiderJobForBackgroundProcessing(job->second.get()); 286 ConsiderJobForBackgroundProcessing(job->second.get());
287 return true; 287 return true;
288 } 288 }
289 289
290 bool CompilerDispatcher::Enqueue( 290 bool CompilerDispatcher::Enqueue(
291 Handle<SharedFunctionInfo> function, FunctionLiteral* literal, 291 Handle<Script> script, Handle<SharedFunctionInfo> function,
292 std::shared_ptr<Zone> parse_zone, 292 FunctionLiteral* literal, std::shared_ptr<Zone> parse_zone,
293 std::shared_ptr<DeferredHandles> parse_handles, 293 std::shared_ptr<DeferredHandles> parse_handles,
294 std::shared_ptr<DeferredHandles> compile_handles) { 294 std::shared_ptr<DeferredHandles> compile_handles) {
295 if (!CanEnqueue(function)) return false; 295 if (!CanEnqueue(function)) return false;
296 if (IsEnqueued(function)) return true; 296 if (IsEnqueued(function)) return true;
297 297
298 if (trace_compiler_dispatcher_) { 298 if (trace_compiler_dispatcher_) {
299 PrintF("CompilerDispatcher: enqueuing "); 299 PrintF("CompilerDispatcher: enqueuing ");
300 function->ShortPrint(); 300 function->ShortPrint();
301 PrintF(" for compile\n"); 301 PrintF(" for compile\n");
302 } 302 }
303 303
304 std::unique_ptr<CompilerDispatcherJob> job(new CompilerDispatcherJob( 304 std::unique_ptr<CompilerDispatcherJob> job(new CompilerDispatcherJob(
305 isolate_, tracer_.get(), function, literal, parse_zone, parse_handles, 305 isolate_, tracer_.get(), script, function, literal, parse_zone,
306 compile_handles, max_stack_size_)); 306 parse_handles, compile_handles, max_stack_size_));
307 std::pair<int, int> key(Script::cast(function->script())->id(), 307 std::pair<int, int> key(Script::cast(function->script())->id(),
308 function->function_literal_id()); 308 function->function_literal_id());
309 jobs_.insert(std::make_pair(key, std::move(job))); 309 jobs_.insert(std::make_pair(key, std::move(job)));
310 ScheduleIdleTaskIfNeeded(); 310 ScheduleIdleTaskIfNeeded();
311 return true; 311 return true;
312 } 312 }
313 313
314 bool CompilerDispatcher::EnqueueAndStep( 314 bool CompilerDispatcher::EnqueueAndStep(
315 Handle<SharedFunctionInfo> function, FunctionLiteral* literal, 315 Handle<Script> script, Handle<SharedFunctionInfo> function,
316 std::shared_ptr<Zone> parse_zone, 316 FunctionLiteral* literal, std::shared_ptr<Zone> parse_zone,
317 std::shared_ptr<DeferredHandles> parse_handles, 317 std::shared_ptr<DeferredHandles> parse_handles,
318 std::shared_ptr<DeferredHandles> compile_handles) { 318 std::shared_ptr<DeferredHandles> compile_handles) {
319 if (!Enqueue(function, literal, parse_zone, parse_handles, compile_handles)) { 319 if (!Enqueue(script, function, literal, parse_zone, parse_handles,
320 compile_handles)) {
320 return false; 321 return false;
321 } 322 }
322 323
323 if (trace_compiler_dispatcher_) { 324 if (trace_compiler_dispatcher_) {
324 PrintF("CompilerDispatcher: stepping "); 325 PrintF("CompilerDispatcher: stepping ");
325 function->ShortPrint(); 326 function->ShortPrint();
326 PrintF("\n"); 327 PrintF("\n");
327 } 328 }
328 JobMap::const_iterator job = GetJobFor(function); 329 JobMap::const_iterator job = GetJobFor(function);
329 DoNextStepOnMainThread(isolate_, job->second.get(), 330 DoNextStepOnMainThread(isolate_, job->second.get(),
330 ExceptionHandling::kSwallow); 331 ExceptionHandling::kSwallow);
331 ConsiderJobForBackgroundProcessing(job->second.get()); 332 ConsiderJobForBackgroundProcessing(job->second.get());
332 return true; 333 return true;
333 } 334 }
334 335
335 bool CompilerDispatcher::IsEnabled() const { return FLAG_compiler_dispatcher; } 336 bool CompilerDispatcher::IsEnabled() const { return FLAG_compiler_dispatcher; }
336 337
337 bool CompilerDispatcher::IsEnqueued(Handle<SharedFunctionInfo> function) const { 338 bool CompilerDispatcher::IsEnqueued(Handle<SharedFunctionInfo> function) const {
338 return GetJobFor(function) != jobs_.end(); 339 return GetJobFor(function) != jobs_.end();
339 } 340 }
340 341
341 void CompilerDispatcher::WaitForJobIfRunningOnBackground( 342 void CompilerDispatcher::WaitForJobIfRunningOnBackground(
342 CompilerDispatcherJob* job) { 343 CompilerDispatcherJob* job) {
344 RuntimeCallTimerScope runtimeTimer(
345 isolate_, &RuntimeCallStats::CompileWaitForDispatcher);
346
343 base::LockGuard<base::Mutex> lock(&mutex_); 347 base::LockGuard<base::Mutex> lock(&mutex_);
344 if (running_background_jobs_.find(job) == running_background_jobs_.end()) { 348 if (running_background_jobs_.find(job) == running_background_jobs_.end()) {
345 pending_background_jobs_.erase(job); 349 pending_background_jobs_.erase(job);
346 return; 350 return;
347 } 351 }
348 DCHECK_NULL(main_thread_blocking_on_job_); 352 DCHECK_NULL(main_thread_blocking_on_job_);
349 main_thread_blocking_on_job_ = job; 353 main_thread_blocking_on_job_ = job;
350 while (main_thread_blocking_on_job_ != nullptr) { 354 while (main_thread_blocking_on_job_ != nullptr) {
351 main_thread_blocking_signal_.Wait(&mutex_); 355 main_thread_blocking_signal_.Wait(&mutex_);
352 } 356 }
353 DCHECK(pending_background_jobs_.find(job) == pending_background_jobs_.end()); 357 DCHECK(pending_background_jobs_.find(job) == pending_background_jobs_.end());
354 DCHECK(running_background_jobs_.find(job) == running_background_jobs_.end()); 358 DCHECK(running_background_jobs_.find(job) == running_background_jobs_.end());
355 } 359 }
356 360
357 bool CompilerDispatcher::FinishNow(CompilerDispatcherJob* job) {
358 WaitForJobIfRunningOnBackground(job);
359 while (!IsFinished(job)) {
360 DoNextStepOnMainThread(isolate_, job, ExceptionHandling::kThrow);
361 }
362 bool result = job->status() != CompileJobStatus::kFailed;
363 job->ResetOnMainThread();
364 return result;
365 }
366
367 bool CompilerDispatcher::FinishNow(Handle<SharedFunctionInfo> function) { 361 bool CompilerDispatcher::FinishNow(Handle<SharedFunctionInfo> function) {
368 JobMap::const_iterator job = GetJobFor(function); 362 JobMap::const_iterator job = GetJobFor(function);
369 CHECK(job != jobs_.end()); 363 CHECK(job != jobs_.end());
370 364
371 if (trace_compiler_dispatcher_) { 365 if (trace_compiler_dispatcher_) {
372 PrintF("CompilerDispatcher: finishing "); 366 PrintF("CompilerDispatcher: finishing ");
373 function->ShortPrint(); 367 function->ShortPrint();
374 PrintF(" now\n"); 368 PrintF(" now\n");
375 } 369 }
376 370
377 bool result = FinishNow(job->second.get()); 371 WaitForJobIfRunningOnBackground(job->second.get());
372 while (!IsFinished(job->second.get())) {
373 DoNextStepOnMainThread(isolate_, job->second.get(),
374 ExceptionHandling::kThrow);
375 }
376 bool result = job->second->status() != CompileJobStatus::kFailed;
378 377
379 if (trace_compiler_dispatcher_) { 378 if (trace_compiler_dispatcher_) {
380 PrintF("CompilerDispatcher: finished working on "); 379 PrintF("CompilerDispatcher: finished working on ");
381 function->ShortPrint(); 380 function->ShortPrint();
382 PrintF(": %s\n", result ? "success" : "failure"); 381 PrintF(": %s\n", result ? "success" : "failure");
383 tracer_->DumpStatistics(); 382 tracer_->DumpStatistics();
384 } 383 }
385 384
385 job->second->ResetOnMainThread();
386 jobs_.erase(job); 386 jobs_.erase(job);
387 if (jobs_.empty()) { 387 if (jobs_.empty()) {
388 base::LockGuard<base::Mutex> lock(&mutex_); 388 base::LockGuard<base::Mutex> lock(&mutex_);
389 abort_ = false; 389 abort_ = false;
390 } 390 }
391 return result; 391 return result;
392 } 392 }
393 393
394 bool CompilerDispatcher::FinishAllNow() {
395 if (trace_compiler_dispatcher_) {
396 PrintF("CompilerDispatcher: finishing all jobs now\n");
397 }
398
399 bool result = true;
400 for (auto& it : jobs_) {
401 result &= FinishNow(it.second.get());
402 }
403
404 if (trace_compiler_dispatcher_) {
405 PrintF("CompilerDispatcher: finished all jobs\n");
406 }
407
408 jobs_.clear();
409 {
410 base::LockGuard<base::Mutex> lock(&mutex_);
411 DCHECK(pending_background_jobs_.empty());
412 DCHECK(running_background_jobs_.empty());
413 abort_ = false;
414 }
415 return result;
416 }
417
418 void CompilerDispatcher::AbortAll(BlockingBehavior blocking) { 394 void CompilerDispatcher::AbortAll(BlockingBehavior blocking) {
419 bool background_tasks_running = 395 bool background_tasks_running =
420 task_manager_->TryAbortAll() == CancelableTaskManager::kTaskRunning; 396 task_manager_->TryAbortAll() == CancelableTaskManager::kTaskRunning;
421 if (!background_tasks_running || blocking == BlockingBehavior::kBlock) { 397 if (!background_tasks_running || blocking == BlockingBehavior::kBlock) {
422 for (auto& it : jobs_) { 398 for (auto& it : jobs_) {
423 WaitForJobIfRunningOnBackground(it.second.get()); 399 WaitForJobIfRunningOnBackground(it.second.get());
424 if (trace_compiler_dispatcher_) { 400 if (trace_compiler_dispatcher_) {
425 PrintF("CompilerDispatcher: aborted "); 401 PrintF("CompilerDispatcher: aborted ");
426 it.second->ShortPrint(); 402 it.second->ShortPrint();
427 PrintF("\n"); 403 PrintF("\n");
(...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after
702 lock.reset(); 678 lock.reset();
703 DoNextStepOnMainThread(isolate_, job->second.get(), 679 DoNextStepOnMainThread(isolate_, job->second.get(),
704 ExceptionHandling::kSwallow); 680 ExceptionHandling::kSwallow);
705 } 681 }
706 } 682 }
707 if (jobs_.size() > too_long_jobs) ScheduleIdleTaskIfNeeded(); 683 if (jobs_.size() > too_long_jobs) ScheduleIdleTaskIfNeeded();
708 } 684 }
709 685
710 } // namespace internal 686 } // namespace internal
711 } // namespace v8 687 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698