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

Side by Side Diff: src/compiler.cc

Issue 2611313002: [complier] Enable parallel eager inner function compilation with compiler dispatcher. (Closed)
Patch Set: Move flag 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 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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.h" 5 #include "src/compiler.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <memory> 8 #include <memory>
9 9
10 #include "src/asmjs/asm-js.h" 10 #include "src/asmjs/asm-js.h"
11 #include "src/asmjs/asm-typer.h" 11 #include "src/asmjs/asm-typer.h"
12 #include "src/ast/ast-numbering.h" 12 #include "src/ast/ast-numbering.h"
13 #include "src/ast/prettyprinter.h" 13 #include "src/ast/prettyprinter.h"
14 #include "src/ast/scopes.h" 14 #include "src/ast/scopes.h"
15 #include "src/bootstrapper.h" 15 #include "src/bootstrapper.h"
16 #include "src/codegen.h" 16 #include "src/codegen.h"
17 #include "src/compilation-cache.h" 17 #include "src/compilation-cache.h"
18 #include "src/compiler-dispatcher/compiler-dispatcher.h"
18 #include "src/compiler-dispatcher/optimizing-compile-dispatcher.h" 19 #include "src/compiler-dispatcher/optimizing-compile-dispatcher.h"
19 #include "src/compiler/pipeline.h" 20 #include "src/compiler/pipeline.h"
20 #include "src/crankshaft/hydrogen.h" 21 #include "src/crankshaft/hydrogen.h"
21 #include "src/debug/debug.h" 22 #include "src/debug/debug.h"
22 #include "src/debug/liveedit.h" 23 #include "src/debug/liveedit.h"
23 #include "src/frames-inl.h" 24 #include "src/frames-inl.h"
24 #include "src/full-codegen/full-codegen.h" 25 #include "src/full-codegen/full-codegen.h"
25 #include "src/globals.h" 26 #include "src/globals.h"
26 #include "src/heap/heap.h" 27 #include "src/heap/heap.h"
27 #include "src/interpreter/interpreter.h" 28 #include "src/interpreter/interpreter.h"
(...skipping 340 matching lines...) Expand 10 before | Expand all | Expand 10 after
368 // Checks whether top level functions should be passed by the filter. 369 // Checks whether top level functions should be passed by the filter.
369 if (shared->is_toplevel()) { 370 if (shared->is_toplevel()) {
370 Vector<const char> filter = CStrVector(FLAG_ignition_filter); 371 Vector<const char> filter = CStrVector(FLAG_ignition_filter);
371 return (filter.length() == 0) || (filter.length() == 1 && filter[0] == '*'); 372 return (filter.length() == 0) || (filter.length() == 1 && filter[0] == '*');
372 } 373 }
373 374
374 // Finally respect the filter. 375 // Finally respect the filter.
375 return shared->PassesFilter(FLAG_ignition_filter); 376 return shared->PassesFilter(FLAG_ignition_filter);
376 } 377 }
377 378
379 bool UseAsmWasm(DeclarationScope* scope, Handle<SharedFunctionInfo> shared_info,
380 bool is_debug) {
381 return FLAG_validate_asm && scope->asm_module() &&
382 !shared_info->is_asm_wasm_broken() && !is_debug;
383 }
384
385 bool UseCompilerDispatcher(CompilerDispatcher* dispatcher,
386 DeclarationScope* scope,
387 Handle<SharedFunctionInfo> shared_info,
388 bool is_debug, bool will_serialize) {
389 return dispatcher->IsEnabled() && !is_debug && !will_serialize &&
390 !UseAsmWasm(scope, shared_info, is_debug);
391 }
392
378 CompilationJob* GetUnoptimizedCompilationJob(CompilationInfo* info) { 393 CompilationJob* GetUnoptimizedCompilationJob(CompilationInfo* info) {
379 // Function should have been parsed and analyzed before creating a compilation 394 // Function should have been parsed and analyzed before creating a compilation
380 // job. 395 // job.
381 DCHECK_NOT_NULL(info->literal()); 396 DCHECK_NOT_NULL(info->literal());
382 DCHECK_NOT_NULL(info->scope()); 397 DCHECK_NOT_NULL(info->scope());
383 398
384 EnsureFeedbackMetadata(info); 399 EnsureFeedbackMetadata(info);
385 if (ShouldUseIgnition(info)) { 400 if (ShouldUseIgnition(info)) {
386 return interpreter::Interpreter::NewCompilationJob(info); 401 return interpreter::Interpreter::NewCompilationJob(info);
387 } else { 402 } else {
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
421 // Update the shared function info with the scope info. 436 // Update the shared function info with the scope info.
422 InstallSharedScopeInfo(info, shared); 437 InstallSharedScopeInfo(info, shared);
423 438
424 // Install compilation result on the shared function info 439 // Install compilation result on the shared function info
425 InstallSharedCompilationResult(info, shared); 440 InstallSharedCompilationResult(info, shared);
426 } 441 }
427 442
428 CompilationJob::Status FinalizeUnoptimizedCompilationJob(CompilationJob* job) { 443 CompilationJob::Status FinalizeUnoptimizedCompilationJob(CompilationJob* job) {
429 CompilationJob::Status status = job->FinalizeJob(); 444 CompilationJob::Status status = job->FinalizeJob();
430 if (status == CompilationJob::SUCCEEDED) { 445 if (status == CompilationJob::SUCCEEDED) {
431 InstallUnoptimizedCode(job->info()); 446 CompilationInfo* info = job->info();
447 DCHECK(!info->code().is_null());
448 if (info->parse_info()->literal()->should_be_used_once_hint()) {
449 info->code()->MarkToBeExecutedOnce(info->isolate());
450 }
451 InstallUnoptimizedCode(info);
432 job->RecordUnoptimizedCompilationStats(); 452 job->RecordUnoptimizedCompilationStats();
433 } 453 }
434 return status; 454 return status;
435 } 455 }
436 456
437 bool Renumber(ParseInfo* parse_info, 457 bool Renumber(Isolate* isolate, Zone* zone, FunctionLiteral* literal,
458 Handle<SharedFunctionInfo> shared_info,
438 Compiler::EagerInnerFunctionLiterals* eager_literals) { 459 Compiler::EagerInnerFunctionLiterals* eager_literals) {
439 RuntimeCallTimerScope runtimeTimer(parse_info->isolate(), 460 RuntimeCallTimerScope runtimeTimer(isolate,
440 &RuntimeCallStats::CompileRenumber); 461 &RuntimeCallStats::CompileRenumber);
441 if (!AstNumbering::Renumber(parse_info->isolate(), parse_info->zone(), 462 if (!AstNumbering::Renumber(isolate, zone, literal, eager_literals)) {
442 parse_info->literal(), eager_literals)) {
443 return false; 463 return false;
444 } 464 }
445 Handle<SharedFunctionInfo> shared_info = parse_info->shared_info();
446 if (!shared_info.is_null()) { 465 if (!shared_info.is_null()) {
447 FunctionLiteral* lit = parse_info->literal(); 466 shared_info->set_ast_node_count(literal->ast_node_count());
448 shared_info->set_ast_node_count(lit->ast_node_count()); 467 if (literal->dont_optimize_reason() != kNoReason) {
449 if (lit->dont_optimize_reason() != kNoReason) { 468 shared_info->DisableOptimization(literal->dont_optimize_reason());
450 shared_info->DisableOptimization(lit->dont_optimize_reason());
451 } 469 }
452 if (lit->flags() & AstProperties::kMustUseIgnitionTurbo) { 470 if (literal->flags() & AstProperties::kMustUseIgnitionTurbo) {
453 shared_info->set_must_use_ignition_turbo(true); 471 shared_info->set_must_use_ignition_turbo(true);
454 } 472 }
455 } 473 }
456 return true; 474 return true;
457 } 475 }
458 476
459 bool GenerateUnoptimizedCode(CompilationInfo* info) { 477 bool GenerateUnoptimizedCode(CompilationInfo* info) {
460 if (FLAG_validate_asm && info->scope()->asm_module() && 478 if (UseAsmWasm(info->scope(), info->shared_info(), info->is_debug())) {
461 !info->shared_info()->is_asm_wasm_broken() && !info->is_debug()) {
462 EnsureFeedbackMetadata(info); 479 EnsureFeedbackMetadata(info);
463 MaybeHandle<FixedArray> wasm_data; 480 MaybeHandle<FixedArray> wasm_data;
464 wasm_data = AsmJs::CompileAsmViaWasm(info); 481 wasm_data = AsmJs::CompileAsmViaWasm(info);
465 if (!wasm_data.is_null()) { 482 if (!wasm_data.is_null()) {
466 info->shared_info()->set_asm_wasm_data(*wasm_data.ToHandleChecked()); 483 info->shared_info()->set_asm_wasm_data(*wasm_data.ToHandleChecked());
467 info->SetCode(info->isolate()->builtins()->InstantiateAsmJs()); 484 info->SetCode(info->isolate()->builtins()->InstantiateAsmJs());
468 InstallUnoptimizedCode(info); 485 InstallUnoptimizedCode(info);
469 return true; 486 return true;
470 } 487 }
471 } 488 }
472 489
473 std::unique_ptr<CompilationJob> job(GetUnoptimizedCompilationJob(info)); 490 std::unique_ptr<CompilationJob> job(GetUnoptimizedCompilationJob(info));
474 if (job->PrepareJob() != CompilationJob::SUCCEEDED) return false; 491 if (job->PrepareJob() != CompilationJob::SUCCEEDED) return false;
475 if (job->ExecuteJob() != CompilationJob::SUCCEEDED) return false; 492 if (job->ExecuteJob() != CompilationJob::SUCCEEDED) return false;
476 if (FinalizeUnoptimizedCompilationJob(job.get()) != 493 if (FinalizeUnoptimizedCompilationJob(job.get()) !=
477 CompilationJob::SUCCEEDED) { 494 CompilationJob::SUCCEEDED) {
478 return false; 495 return false;
479 } 496 }
480 return true; 497 return true;
481 } 498 }
482 499
483 bool CompileUnoptimizedInnerFunctionsRecursively( 500 bool CompileUnoptimizedInnerFunctionsRecursively(
484 ThreadedList<ThreadedListZoneEntry<FunctionLiteral*>>* literals, 501 ThreadedList<ThreadedListZoneEntry<FunctionLiteral*>>* literals,
485 CompilationInfo* outer_info) { 502 CompilationInfo* outer_info) {
486 Isolate* isolate = outer_info->isolate(); 503 Isolate* isolate = outer_info->isolate();
487 Handle<Script> script = outer_info->script(); 504 Handle<Script> script = outer_info->script();
505 bool is_debug = outer_info->is_debug();
506 bool will_serialize = outer_info->will_serialize();
488 RuntimeCallTimerScope runtimeTimer(isolate, 507 RuntimeCallTimerScope runtimeTimer(isolate,
489 &RuntimeCallStats::CompileInnerFunction); 508 &RuntimeCallStats::CompileInnerFunction);
490 509
491 for (auto it : *literals) { 510 for (auto it : *literals) {
492 FunctionLiteral* literal = it->value(); 511 FunctionLiteral* literal = it->value();
493 512 Handle<SharedFunctionInfo> shared =
494 // Find any previously allocated shared function info for the given literal. 513 Compiler::GetSharedFunctionInfo(literal, script, outer_info);
495 Handle<SharedFunctionInfo> shared;
496 MaybeHandle<SharedFunctionInfo> maybe_existing =
497 script->FindSharedFunctionInfo(isolate, literal);
498 if (maybe_existing.ToHandle(&shared)) {
499 DCHECK(!shared->is_toplevel());
500 // If we found an existing shared function info with compiled code,
501 // we are done.
502 if (shared->is_compiled()) continue;
503 } else {
504 shared =
505 isolate->factory()->NewSharedFunctionInfoForLiteral(literal, script);
506 shared->set_is_toplevel(false);
507 }
508
509 Zone zone(isolate->allocator(), ZONE_NAME);
510 ParseInfo parse_info(&zone, script);
511 parse_info.set_literal(literal);
512 parse_info.set_shared_info(shared);
513 parse_info.set_function_literal_id(shared->function_literal_id());
514 parse_info.set_language_mode(literal->scope()->language_mode());
515 parse_info.set_ast_value_factory(
516 outer_info->parse_info()->ast_value_factory());
517 parse_info.set_ast_value_factory_owned(false);
518
519 CompilationInfo info(&parse_info, Handle<JSFunction>::null());
520 if (outer_info->will_serialize()) info.PrepareForSerializing();
521 if (outer_info->is_debug()) info.MarkAsDebug();
522
523 Compiler::EagerInnerFunctionLiterals inner_literals; 514 Compiler::EagerInnerFunctionLiterals inner_literals;
524 if (!Renumber(&parse_info, &inner_literals) || 515 if (!Renumber(isolate, outer_info->zone(), literal, shared,
516 &inner_literals) ||
525 !CompileUnoptimizedInnerFunctionsRecursively(&inner_literals, 517 !CompileUnoptimizedInnerFunctionsRecursively(&inner_literals,
526 outer_info) || 518 outer_info)) {
527 !GenerateUnoptimizedCode(&info)) {
528 if (!isolate->has_pending_exception()) isolate->StackOverflow(); 519 if (!isolate->has_pending_exception()) isolate->StackOverflow();
529 return false; 520 return false;
530 } 521 }
531 522
532 DCHECK(!info.code().is_null()); 523 // Try to enqueue the eager function on the compiler dispatcher.
533 RecordFunctionCompilation(CodeEventListener::FUNCTION_TAG, &info); 524 CompilerDispatcher* dispatcher = isolate->compiler_dispatcher();
534 if (literal->should_be_used_once_hint()) { 525 if (UseCompilerDispatcher(dispatcher, literal->scope(), shared, is_debug,
535 info.code()->MarkToBeExecutedOnce(isolate); 526 will_serialize) &&
527 dispatcher->EnqueueAndStep(
528 shared, literal, outer_info->parse_info()->ast_value_factory())) {
529 // If we have successfully queued up the function for compilation on the
530 // compiler dispatcher then we are done.
531 continue;
532 } else {
533 // Otherwise generate unoptimized code now.
534 Zone zone(isolate->allocator(), ZONE_NAME);
535 ParseInfo parse_info(&zone, script);
536 CompilationInfo info(&parse_info, Handle<JSFunction>::null());
537
538 parse_info.set_literal(literal);
539 parse_info.set_shared_info(shared);
540 parse_info.set_function_literal_id(shared->function_literal_id());
541 parse_info.set_language_mode(literal->scope()->language_mode());
542 parse_info.set_ast_value_factory(
543 outer_info->parse_info()->ast_value_factory());
544 parse_info.set_ast_value_factory_owned(false);
545
546 if (will_serialize) info.PrepareForSerializing();
547 if (is_debug) info.MarkAsDebug();
548
549 if (!GenerateUnoptimizedCode(&info)) {
550 if (!isolate->has_pending_exception()) isolate->StackOverflow();
551 return false;
552 }
536 } 553 }
537 } 554 }
538 return true; 555 return true;
539 } 556 }
540 557
541 bool CompileUnoptimizedCode(CompilationInfo* info) { 558 bool CompileUnoptimizedCode(CompilationInfo* info) {
542 Isolate* isolate = info->isolate(); 559 Isolate* isolate = info->isolate();
543 DCHECK(AllowCompilation::IsAllowed(isolate)); 560 DCHECK(AllowCompilation::IsAllowed(isolate));
544 561
545 Compiler::EagerInnerFunctionLiterals inner_literals; 562 Compiler::EagerInnerFunctionLiterals inner_literals;
546 if (!Compiler::Analyze(info->parse_info(), &inner_literals) || 563 if (!Compiler::Analyze(info->parse_info(), &inner_literals) ||
547 !CompileUnoptimizedInnerFunctionsRecursively(&inner_literals, info) || 564 !CompileUnoptimizedInnerFunctionsRecursively(&inner_literals, info) ||
548 !GenerateUnoptimizedCode(info)) { 565 !GenerateUnoptimizedCode(info)) {
549 if (!isolate->has_pending_exception()) isolate->StackOverflow(); 566 if (!isolate->has_pending_exception()) isolate->StackOverflow();
550 return false; 567 return false;
551 } 568 }
552 569
570 // TODO(rmcilroy): Remove this once the enqueued tasks can keep the parsed
571 // zone and handles alive and replace with a check in CompileLazy to finish
572 // the task itself.
573 if (isolate->compiler_dispatcher()->IsEnabled() &&
574 !isolate->compiler_dispatcher()->FinishAllNow()) {
575 if (!isolate->has_pending_exception()) isolate->StackOverflow();
576 return false;
577 }
578
553 return true; 579 return true;
554 } 580 }
555 581
556 void EnsureSharedFunctionInfosArrayOnScript(ParseInfo* info) { 582 void EnsureSharedFunctionInfosArrayOnScript(ParseInfo* info) {
557 DCHECK(info->is_toplevel()); 583 DCHECK(info->is_toplevel());
558 DCHECK(!info->script().is_null()); 584 DCHECK(!info->script().is_null());
559 if (info->script()->shared_function_infos()->length() > 0) { 585 if (info->script()->shared_function_infos()->length() > 0) {
560 DCHECK_EQ(info->script()->shared_function_infos()->length(), 586 DCHECK_EQ(info->script()->shared_function_infos()->length(),
561 info->max_function_literal_id() + 1); 587 info->max_function_literal_id() + 1);
562 return; 588 return;
(...skipping 555 matching lines...) Expand 10 before | Expand all | Expand 10 after
1118 // ---------------------------------------------------------------------------- 1144 // ----------------------------------------------------------------------------
1119 // Implementation of Compiler 1145 // Implementation of Compiler
1120 1146
1121 bool Compiler::Analyze(ParseInfo* info, 1147 bool Compiler::Analyze(ParseInfo* info,
1122 EagerInnerFunctionLiterals* eager_literals) { 1148 EagerInnerFunctionLiterals* eager_literals) {
1123 DCHECK_NOT_NULL(info->literal()); 1149 DCHECK_NOT_NULL(info->literal());
1124 RuntimeCallTimerScope runtimeTimer(info->isolate(), 1150 RuntimeCallTimerScope runtimeTimer(info->isolate(),
1125 &RuntimeCallStats::CompileAnalyse); 1151 &RuntimeCallStats::CompileAnalyse);
1126 if (!Rewriter::Rewrite(info)) return false; 1152 if (!Rewriter::Rewrite(info)) return false;
1127 DeclarationScope::Analyze(info, AnalyzeMode::kRegular); 1153 DeclarationScope::Analyze(info, AnalyzeMode::kRegular);
1128 if (!Renumber(info, eager_literals)) return false; 1154 if (!Renumber(info->isolate(), info->zone(), info->literal(),
1155 info->shared_info(), eager_literals)) {
1156 return false;
1157 }
1129 DCHECK_NOT_NULL(info->scope()); 1158 DCHECK_NOT_NULL(info->scope());
1130 return true; 1159 return true;
1131 } 1160 }
1132 1161
1133 bool Compiler::ParseAndAnalyze(ParseInfo* info) { 1162 bool Compiler::ParseAndAnalyze(ParseInfo* info) {
1134 if (!parsing::ParseAny(info)) return false; 1163 if (!parsing::ParseAny(info)) return false;
1135 if (info->is_toplevel()) EnsureSharedFunctionInfosArrayOnScript(info); 1164 if (info->is_toplevel()) EnsureSharedFunctionInfosArrayOnScript(info);
1136 if (!Compiler::Analyze(info)) return false; 1165 if (!Compiler::Analyze(info)) return false;
1137 DCHECK_NOT_NULL(info->literal()); 1166 DCHECK_NOT_NULL(info->literal());
1138 DCHECK_NOT_NULL(info->scope()); 1167 DCHECK_NOT_NULL(info->scope());
(...skipping 623 matching lines...) Expand 10 before | Expand all | Expand 10 after
1762 } 1791 }
1763 1792
1764 if (shared->is_compiled()) { 1793 if (shared->is_compiled()) {
1765 // TODO(mvstanton): pass pretenure flag to EnsureLiterals. 1794 // TODO(mvstanton): pass pretenure flag to EnsureLiterals.
1766 JSFunction::EnsureLiterals(function); 1795 JSFunction::EnsureLiterals(function);
1767 } 1796 }
1768 } 1797 }
1769 1798
1770 } // namespace internal 1799 } // namespace internal
1771 } // namespace v8 1800 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698