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 |