OLD | NEW |
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" |
(...skipping 416 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
427 CompilationJob::Status FinalizeUnoptimizedCompilationJob(CompilationJob* job) { | 427 CompilationJob::Status FinalizeUnoptimizedCompilationJob(CompilationJob* job) { |
428 CompilationJob::Status status = job->FinalizeJob(); | 428 CompilationJob::Status status = job->FinalizeJob(); |
429 if (status == CompilationJob::SUCCEEDED) { | 429 if (status == CompilationJob::SUCCEEDED) { |
430 EnsureFeedbackMetadata(job->info()); | 430 EnsureFeedbackMetadata(job->info()); |
431 InstallUnoptimizedCode(job->info()); | 431 InstallUnoptimizedCode(job->info()); |
432 job->RecordUnoptimizedCompilationStats(); | 432 job->RecordUnoptimizedCompilationStats(); |
433 } | 433 } |
434 return status; | 434 return status; |
435 } | 435 } |
436 | 436 |
437 void SetSharedFunctionFlagsFromLiteral(FunctionLiteral* literal, | |
438 Handle<SharedFunctionInfo> shared_info) { | |
439 shared_info->set_ast_node_count(literal->ast_node_count()); | |
440 if (literal->dont_optimize_reason() != kNoReason) { | |
441 shared_info->DisableOptimization(literal->dont_optimize_reason()); | |
442 } | |
443 if (literal->flags() & AstProperties::kMustUseIgnitionTurbo) { | |
444 shared_info->set_must_use_ignition_turbo(true); | |
445 } | |
446 } | |
447 | |
448 bool Renumber(ParseInfo* parse_info, | 437 bool Renumber(ParseInfo* parse_info, |
449 Compiler::EagerInnerFunctionLiterals* eager_literals) { | 438 Compiler::EagerInnerFunctionLiterals* eager_literals) { |
450 RuntimeCallTimerScope runtimeTimer(parse_info->isolate(), | 439 RuntimeCallTimerScope runtimeTimer(parse_info->isolate(), |
451 &RuntimeCallStats::CompileRenumber); | 440 &RuntimeCallStats::CompileRenumber); |
452 if (!AstNumbering::Renumber( | 441 if (!AstNumbering::Renumber( |
453 parse_info->isolate()->stack_guard()->real_climit(), | 442 parse_info->isolate()->stack_guard()->real_climit(), |
454 parse_info->zone(), parse_info->literal(), eager_literals)) { | 443 parse_info->zone(), parse_info->literal(), eager_literals)) { |
455 return false; | 444 return false; |
456 } | 445 } |
457 if (!parse_info->shared_info().is_null()) { | 446 Handle<SharedFunctionInfo> shared_info = parse_info->shared_info(); |
458 SetSharedFunctionFlagsFromLiteral(parse_info->literal(), | 447 if (!shared_info.is_null()) { |
459 parse_info->shared_info()); | 448 FunctionLiteral* lit = parse_info->literal(); |
| 449 shared_info->set_ast_node_count(lit->ast_node_count()); |
| 450 if (lit->dont_optimize_reason() != kNoReason) { |
| 451 shared_info->DisableOptimization(lit->dont_optimize_reason()); |
| 452 } |
| 453 if (lit->flags() & AstProperties::kMustUseIgnitionTurbo) { |
| 454 shared_info->set_must_use_ignition_turbo(true); |
| 455 } |
460 } | 456 } |
461 return true; | 457 return true; |
462 } | 458 } |
463 | 459 |
464 bool GenerateUnoptimizedCode(CompilationInfo* info) { | 460 bool GenerateUnoptimizedCode(CompilationInfo* info) { |
465 if (FLAG_validate_asm && info->scope()->asm_module() && | 461 if (FLAG_validate_asm && info->scope()->asm_module() && |
466 !info->shared_info()->is_asm_wasm_broken() && !info->is_debug()) { | 462 !info->shared_info()->is_asm_wasm_broken() && !info->is_debug()) { |
467 EnsureFeedbackMetadata(info); | 463 EnsureFeedbackMetadata(info); |
468 MaybeHandle<FixedArray> wasm_data; | 464 MaybeHandle<FixedArray> wasm_data; |
469 wasm_data = AsmJs::CompileAsmViaWasm(info); | 465 wasm_data = AsmJs::CompileAsmViaWasm(info); |
470 if (!wasm_data.is_null()) { | 466 if (!wasm_data.is_null()) { |
471 info->shared_info()->set_asm_wasm_data(*wasm_data.ToHandleChecked()); | 467 info->shared_info()->set_asm_wasm_data(*wasm_data.ToHandleChecked()); |
472 info->SetCode(info->isolate()->builtins()->InstantiateAsmJs()); | 468 info->SetCode(info->isolate()->builtins()->InstantiateAsmJs()); |
473 InstallUnoptimizedCode(info); | 469 InstallUnoptimizedCode(info); |
474 return true; | 470 return true; |
475 } | 471 } |
476 } | 472 } |
477 | 473 |
478 std::unique_ptr<CompilationJob> job(GetUnoptimizedCompilationJob(info)); | 474 std::unique_ptr<CompilationJob> job(GetUnoptimizedCompilationJob(info)); |
479 if (job->PrepareJob() != CompilationJob::SUCCEEDED) return false; | 475 if (job->PrepareJob() != CompilationJob::SUCCEEDED) return false; |
480 if (job->ExecuteJob() != CompilationJob::SUCCEEDED) return false; | 476 if (job->ExecuteJob() != CompilationJob::SUCCEEDED) return false; |
481 if (FinalizeUnoptimizedCompilationJob(job.get()) != | 477 if (FinalizeUnoptimizedCompilationJob(job.get()) != |
482 CompilationJob::SUCCEEDED) { | 478 CompilationJob::SUCCEEDED) { |
483 return false; | 479 return false; |
484 } | 480 } |
485 return true; | 481 return true; |
486 } | 482 } |
487 | 483 |
488 bool CompileUnoptimizedInnerFunctions( | 484 bool CompileUnoptimizedInnerFunctionsRecursively( |
489 ThreadedList<ThreadedListZoneEntry<FunctionLiteral*>>* literals, | 485 ThreadedList<ThreadedListZoneEntry<FunctionLiteral*>>* literals, |
490 CompilationInfo* outer_info) { | 486 CompilationInfo* outer_info) { |
491 Isolate* isolate = outer_info->isolate(); | 487 Isolate* isolate = outer_info->isolate(); |
492 Handle<Script> script = outer_info->script(); | 488 Handle<Script> script = outer_info->script(); |
493 RuntimeCallTimerScope runtimeTimer(isolate, | 489 RuntimeCallTimerScope runtimeTimer(isolate, |
494 &RuntimeCallStats::CompileInnerFunction); | 490 &RuntimeCallStats::CompileInnerFunction); |
495 | 491 |
496 for (auto it : *literals) { | 492 for (auto it : *literals) { |
497 FunctionLiteral* literal = it->value(); | 493 FunctionLiteral* literal = it->value(); |
498 Handle<SharedFunctionInfo> shared = | |
499 Compiler::GetSharedFunctionInfo(literal, script, outer_info); | |
500 if (shared->is_compiled()) continue; | |
501 | 494 |
502 // The {literal} has already been numbered because AstNumbering decends into | 495 // Find any previously allocated shared function info for the given literal. |
503 // eagerly compiled function literals. | 496 Handle<SharedFunctionInfo> shared; |
504 SetSharedFunctionFlagsFromLiteral(literal, shared); | 497 MaybeHandle<SharedFunctionInfo> maybe_existing = |
| 498 script->FindSharedFunctionInfo(isolate, literal); |
| 499 if (maybe_existing.ToHandle(&shared)) { |
| 500 DCHECK(!shared->is_toplevel()); |
| 501 // If we found an existing shared function info with compiled code, |
| 502 // we are done. |
| 503 if (shared->is_compiled()) continue; |
| 504 } else { |
| 505 shared = |
| 506 isolate->factory()->NewSharedFunctionInfoForLiteral(literal, script); |
| 507 shared->set_is_toplevel(false); |
| 508 } |
505 | 509 |
506 ParseInfo parse_info(script); | 510 ParseInfo parse_info(script); |
507 parse_info.set_literal(literal); | 511 parse_info.set_literal(literal); |
508 parse_info.set_shared_info(shared); | 512 parse_info.set_shared_info(shared); |
509 parse_info.set_function_literal_id(shared->function_literal_id()); | 513 parse_info.set_function_literal_id(shared->function_literal_id()); |
510 parse_info.set_language_mode(literal->scope()->language_mode()); | 514 parse_info.set_language_mode(literal->scope()->language_mode()); |
511 parse_info.set_ast_value_factory( | 515 parse_info.set_ast_value_factory( |
512 outer_info->parse_info()->ast_value_factory()); | 516 outer_info->parse_info()->ast_value_factory()); |
513 parse_info.set_ast_value_factory_owned(false); | 517 parse_info.set_ast_value_factory_owned(false); |
514 | 518 |
515 CompilationInfo info(&parse_info, Handle<JSFunction>::null()); | 519 CompilationInfo info(&parse_info, Handle<JSFunction>::null()); |
516 if (outer_info->will_serialize()) info.PrepareForSerializing(); | 520 if (outer_info->will_serialize()) info.PrepareForSerializing(); |
517 if (outer_info->is_debug()) info.MarkAsDebug(); | 521 if (outer_info->is_debug()) info.MarkAsDebug(); |
518 | 522 |
519 if (!GenerateUnoptimizedCode(&info)) { | 523 Compiler::EagerInnerFunctionLiterals inner_literals; |
| 524 if (!Renumber(&parse_info, &inner_literals) || |
| 525 !CompileUnoptimizedInnerFunctionsRecursively(&inner_literals, |
| 526 outer_info) || |
| 527 !GenerateUnoptimizedCode(&info)) { |
520 if (!isolate->has_pending_exception()) isolate->StackOverflow(); | 528 if (!isolate->has_pending_exception()) isolate->StackOverflow(); |
521 return false; | 529 return false; |
522 } | 530 } |
523 | 531 |
524 DCHECK(!info.code().is_null()); | 532 DCHECK(!info.code().is_null()); |
525 RecordFunctionCompilation(CodeEventListener::FUNCTION_TAG, &info); | 533 RecordFunctionCompilation(CodeEventListener::FUNCTION_TAG, &info); |
526 if (literal->should_be_used_once_hint()) { | 534 if (literal->should_be_used_once_hint()) { |
527 info.code()->MarkToBeExecutedOnce(isolate); | 535 info.code()->MarkToBeExecutedOnce(isolate); |
528 } | 536 } |
529 } | 537 } |
530 return true; | 538 return true; |
531 } | 539 } |
532 | 540 |
533 bool CompileUnoptimizedCode(CompilationInfo* info) { | 541 bool CompileUnoptimizedCode(CompilationInfo* info) { |
534 Isolate* isolate = info->isolate(); | 542 Isolate* isolate = info->isolate(); |
535 DCHECK(AllowCompilation::IsAllowed(isolate)); | 543 DCHECK(AllowCompilation::IsAllowed(isolate)); |
536 | 544 |
537 Compiler::EagerInnerFunctionLiterals inner_literals; | 545 Compiler::EagerInnerFunctionLiterals inner_literals; |
538 if (!Compiler::Analyze(info->parse_info(), &inner_literals) || | 546 if (!Compiler::Analyze(info->parse_info(), &inner_literals) || |
539 !CompileUnoptimizedInnerFunctions(&inner_literals, info) || | 547 !CompileUnoptimizedInnerFunctionsRecursively(&inner_literals, info) || |
540 !GenerateUnoptimizedCode(info)) { | 548 !GenerateUnoptimizedCode(info)) { |
541 if (!isolate->has_pending_exception()) isolate->StackOverflow(); | 549 if (!isolate->has_pending_exception()) isolate->StackOverflow(); |
542 return false; | 550 return false; |
543 } | 551 } |
544 | 552 |
545 return true; | 553 return true; |
546 } | 554 } |
547 | 555 |
548 void EnsureSharedFunctionInfosArrayOnScript(ParseInfo* info) { | 556 void EnsureSharedFunctionInfosArrayOnScript(ParseInfo* info) { |
549 DCHECK(info->is_toplevel()); | 557 DCHECK(info->is_toplevel()); |
(...skipping 1197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1747 } | 1755 } |
1748 | 1756 |
1749 if (shared->is_compiled()) { | 1757 if (shared->is_compiled()) { |
1750 // TODO(mvstanton): pass pretenure flag to EnsureLiterals. | 1758 // TODO(mvstanton): pass pretenure flag to EnsureLiterals. |
1751 JSFunction::EnsureLiterals(function); | 1759 JSFunction::EnsureLiterals(function); |
1752 } | 1760 } |
1753 } | 1761 } |
1754 | 1762 |
1755 } // namespace internal | 1763 } // namespace internal |
1756 } // namespace v8 | 1764 } // namespace v8 |
OLD | NEW |