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