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

Side by Side Diff: src/compiler.cc

Issue 2618553004: [compiler] Collect eager inner functions for compilation during renumbering. (Closed)
Patch Set: Address comments and remove field from ParseInfo 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
« no previous file with comments | « src/compiler.h ('k') | src/compiler-dispatcher/compiler-dispatcher-job.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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"
(...skipping 20 matching lines...) Expand all
31 #include "src/parsing/parsing.h" 31 #include "src/parsing/parsing.h"
32 #include "src/parsing/rewriter.h" 32 #include "src/parsing/rewriter.h"
33 #include "src/parsing/scanner-character-streams.h" 33 #include "src/parsing/scanner-character-streams.h"
34 #include "src/runtime-profiler.h" 34 #include "src/runtime-profiler.h"
35 #include "src/snapshot/code-serializer.h" 35 #include "src/snapshot/code-serializer.h"
36 #include "src/vm-state-inl.h" 36 #include "src/vm-state-inl.h"
37 37
38 namespace v8 { 38 namespace v8 {
39 namespace internal { 39 namespace internal {
40 40
41
42
43 // A wrapper around a CompilationInfo that detaches the Handles from 41 // A wrapper around a CompilationInfo that detaches the Handles from
44 // the underlying DeferredHandleScope and stores them in info_ on 42 // the underlying DeferredHandleScope and stores them in info_ on
45 // destruction. 43 // destruction.
46 class CompilationHandleScope final { 44 class CompilationHandleScope final {
47 public: 45 public:
48 explicit CompilationHandleScope(CompilationInfo* info) 46 explicit CompilationHandleScope(CompilationInfo* info)
49 : deferred_(info->isolate()), info_(info) {} 47 : deferred_(info->isolate()), info_(info) {}
50 ~CompilationHandleScope() { info_->set_deferred_handles(deferred_.Detach()); } 48 ~CompilationHandleScope() { info_->set_deferred_handles(deferred_.Detach()); }
51 49
52 private: 50 private:
(...skipping 317 matching lines...) Expand 10 before | Expand all | Expand 10 after
370 // Checks whether top level functions should be passed by the filter. 368 // Checks whether top level functions should be passed by the filter.
371 if (shared->is_toplevel()) { 369 if (shared->is_toplevel()) {
372 Vector<const char> filter = CStrVector(FLAG_ignition_filter); 370 Vector<const char> filter = CStrVector(FLAG_ignition_filter);
373 return (filter.length() == 0) || (filter.length() == 1 && filter[0] == '*'); 371 return (filter.length() == 0) || (filter.length() == 1 && filter[0] == '*');
374 } 372 }
375 373
376 // Finally respect the filter. 374 // Finally respect the filter.
377 return shared->PassesFilter(FLAG_ignition_filter); 375 return shared->PassesFilter(FLAG_ignition_filter);
378 } 376 }
379 377
380 CompilationJob* GetUnoptimizedCompilationJob(CompilationInfo* info, 378 CompilationJob* GetUnoptimizedCompilationJob(CompilationInfo* info) {
381 LazyCompilationMode mode) {
382 // Function should have been parsed and analyzed before creating a compilation 379 // Function should have been parsed and analyzed before creating a compilation
383 // job. 380 // job.
384 DCHECK_NOT_NULL(info->literal()); 381 DCHECK_NOT_NULL(info->literal());
385 DCHECK_NOT_NULL(info->scope()); 382 DCHECK_NOT_NULL(info->scope());
386 383
387 EnsureFeedbackMetadata(info); 384 EnsureFeedbackMetadata(info);
388 if (ShouldUseIgnition(info)) { 385 if (ShouldUseIgnition(info)) {
389 return interpreter::Interpreter::NewCompilationJob(info, mode); 386 return interpreter::Interpreter::NewCompilationJob(info);
390 } else { 387 } else {
391 return FullCodeGenerator::NewCompilationJob(info, mode); 388 return FullCodeGenerator::NewCompilationJob(info);
392 } 389 }
393 } 390 }
394 391
395 void InstallSharedScopeInfo(CompilationInfo* info, 392 void InstallSharedScopeInfo(CompilationInfo* info,
396 Handle<SharedFunctionInfo> shared) { 393 Handle<SharedFunctionInfo> shared) {
397 Handle<ScopeInfo> scope_info = info->scope()->scope_info(); 394 Handle<ScopeInfo> scope_info = info->scope()->scope_info();
398 shared->set_scope_info(*scope_info); 395 shared->set_scope_info(*scope_info);
399 Scope* outer_scope = info->scope()->GetOuterScopeWithContext(); 396 Scope* outer_scope = info->scope()->GetOuterScopeWithContext();
400 if (outer_scope) { 397 if (outer_scope) {
401 shared->set_outer_scope_info(*outer_scope->scope_info()); 398 shared->set_outer_scope_info(*outer_scope->scope_info());
(...skipping 28 matching lines...) Expand all
430 427
431 CompilationJob::Status FinalizeUnoptimizedCompilationJob(CompilationJob* job) { 428 CompilationJob::Status FinalizeUnoptimizedCompilationJob(CompilationJob* job) {
432 CompilationJob::Status status = job->FinalizeJob(); 429 CompilationJob::Status status = job->FinalizeJob();
433 if (status == CompilationJob::SUCCEEDED) { 430 if (status == CompilationJob::SUCCEEDED) {
434 InstallUnoptimizedCode(job->info()); 431 InstallUnoptimizedCode(job->info());
435 job->RecordUnoptimizedCompilationStats(); 432 job->RecordUnoptimizedCompilationStats();
436 } 433 }
437 return status; 434 return status;
438 } 435 }
439 436
437 bool Renumber(ParseInfo* parse_info,
438 Compiler::EagerInnerFunctionLiterals* eager_literals) {
439 RuntimeCallTimerScope runtimeTimer(parse_info->isolate(),
440 &RuntimeCallStats::CompileRenumber);
441 if (!AstNumbering::Renumber(parse_info->isolate(), parse_info->zone(),
442 parse_info->literal(), eager_literals)) {
443 return false;
444 }
445 Handle<SharedFunctionInfo> shared_info = parse_info->shared_info();
446 if (!shared_info.is_null()) {
447 FunctionLiteral* lit = parse_info->literal();
448 shared_info->set_ast_node_count(lit->ast_node_count());
449 if (lit->dont_optimize_reason() != kNoReason) {
450 shared_info->DisableOptimization(lit->dont_optimize_reason());
451 }
452 if (lit->flags() & AstProperties::kMustUseIgnitionTurbo) {
453 shared_info->set_must_use_ignition_turbo(true);
454 }
455 }
456 return true;
457 }
458
440 bool GenerateUnoptimizedCode(CompilationInfo* info) { 459 bool GenerateUnoptimizedCode(CompilationInfo* info) {
441 if (FLAG_validate_asm && info->scope()->asm_module() && 460 if (FLAG_validate_asm && info->scope()->asm_module() &&
442 !info->shared_info()->is_asm_wasm_broken() && !info->is_debug()) { 461 !info->shared_info()->is_asm_wasm_broken() && !info->is_debug()) {
443 EnsureFeedbackMetadata(info); 462 EnsureFeedbackMetadata(info);
444 MaybeHandle<FixedArray> wasm_data; 463 MaybeHandle<FixedArray> wasm_data;
445 wasm_data = AsmJs::CompileAsmViaWasm(info); 464 wasm_data = AsmJs::CompileAsmViaWasm(info);
446 if (!wasm_data.is_null()) { 465 if (!wasm_data.is_null()) {
447 info->shared_info()->set_asm_wasm_data(*wasm_data.ToHandleChecked()); 466 info->shared_info()->set_asm_wasm_data(*wasm_data.ToHandleChecked());
448 info->SetCode(info->isolate()->builtins()->InstantiateAsmJs()); 467 info->SetCode(info->isolate()->builtins()->InstantiateAsmJs());
449 InstallUnoptimizedCode(info); 468 InstallUnoptimizedCode(info);
450 return true; 469 return true;
451 } 470 }
452 } 471 }
453 472
454 std::unique_ptr<CompilationJob> job( 473 std::unique_ptr<CompilationJob> job(GetUnoptimizedCompilationJob(info));
455 GetUnoptimizedCompilationJob(info, LazyCompilationMode::kIfRequested));
456 if (job->PrepareJob() != CompilationJob::SUCCEEDED) return false; 474 if (job->PrepareJob() != CompilationJob::SUCCEEDED) return false;
457 if (job->ExecuteJob() != CompilationJob::SUCCEEDED) return false; 475 if (job->ExecuteJob() != CompilationJob::SUCCEEDED) return false;
458 if (FinalizeUnoptimizedCompilationJob(job.get()) != 476 if (FinalizeUnoptimizedCompilationJob(job.get()) !=
459 CompilationJob::SUCCEEDED) { 477 CompilationJob::SUCCEEDED) {
460 return false; 478 return false;
461 } 479 }
462 return true; 480 return true;
463 } 481 }
464 482
483 bool CompileUnoptimizedInnerFunctionsRecursively(
484 ThreadedList<ThreadedListZoneEntry<FunctionLiteral*>>* literals,
485 CompilationInfo* outer_info) {
486 Isolate* isolate = outer_info->isolate();
487 Handle<Script> script = outer_info->script();
488 RuntimeCallTimerScope runtimeTimer(isolate,
489 &RuntimeCallStats::CompileInnerFunction);
490
491 for (auto it : *literals) {
492 FunctionLiteral* literal = it->value();
493
494 // Find any previously allocated shared function info for the given literal.
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;
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();
529 return false;
530 }
531
532 DCHECK(!info.code().is_null());
533 RecordFunctionCompilation(CodeEventListener::FUNCTION_TAG, &info);
534 if (literal->should_be_used_once_hint()) {
535 info.code()->MarkToBeExecutedOnce(isolate);
536 }
537 }
538 return true;
539 }
540
465 bool CompileUnoptimizedCode(CompilationInfo* info) { 541 bool CompileUnoptimizedCode(CompilationInfo* info) {
466 DCHECK(AllowCompilation::IsAllowed(info->isolate())); 542 Isolate* isolate = info->isolate();
467 if (!Compiler::Analyze(info->parse_info()) || 543 DCHECK(AllowCompilation::IsAllowed(isolate));
544
545 Compiler::EagerInnerFunctionLiterals inner_literals;
546 if (!Compiler::Analyze(info->parse_info(), &inner_literals) ||
547 !CompileUnoptimizedInnerFunctionsRecursively(&inner_literals, info) ||
468 !GenerateUnoptimizedCode(info)) { 548 !GenerateUnoptimizedCode(info)) {
469 Isolate* isolate = info->isolate();
470 if (!isolate->has_pending_exception()) isolate->StackOverflow(); 549 if (!isolate->has_pending_exception()) isolate->StackOverflow();
471 return false; 550 return false;
472 } 551 }
552
473 return true; 553 return true;
474 } 554 }
475 555
476 void EnsureSharedFunctionInfosArrayOnScript(ParseInfo* info) { 556 void EnsureSharedFunctionInfosArrayOnScript(ParseInfo* info) {
477 DCHECK(info->is_toplevel()); 557 DCHECK(info->is_toplevel());
478 DCHECK(!info->script().is_null()); 558 DCHECK(!info->script().is_null());
479 if (info->script()->shared_function_infos()->length() > 0) { 559 if (info->script()->shared_function_infos()->length() > 0) {
480 DCHECK_EQ(info->script()->shared_function_infos()->length(), 560 DCHECK_EQ(info->script()->shared_function_infos()->length(),
481 info->max_function_literal_id() + 1); 561 info->max_function_literal_id() + 1);
482 return; 562 return;
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
545 625
546 // Cache optimized context-specific code. 626 // Cache optimized context-specific code.
547 Handle<JSFunction> function = info->closure(); 627 Handle<JSFunction> function = info->closure();
548 Handle<SharedFunctionInfo> shared(function->shared()); 628 Handle<SharedFunctionInfo> shared(function->shared());
549 Handle<LiteralsArray> literals(function->literals()); 629 Handle<LiteralsArray> literals(function->literals());
550 Handle<Context> native_context(function->context()->native_context()); 630 Handle<Context> native_context(function->context()->native_context());
551 SharedFunctionInfo::AddToOptimizedCodeMap(shared, native_context, code, 631 SharedFunctionInfo::AddToOptimizedCodeMap(shared, native_context, code,
552 literals, info->osr_ast_id()); 632 literals, info->osr_ast_id());
553 } 633 }
554 634
555 bool Renumber(ParseInfo* parse_info) {
556 RuntimeCallTimerScope runtimeTimer(parse_info->isolate(),
557 &RuntimeCallStats::CompileRenumber);
558 if (!AstNumbering::Renumber(parse_info->isolate(), parse_info->zone(),
559 parse_info->literal())) {
560 return false;
561 }
562 Handle<SharedFunctionInfo> shared_info = parse_info->shared_info();
563 if (!shared_info.is_null()) {
564 FunctionLiteral* lit = parse_info->literal();
565 shared_info->set_ast_node_count(lit->ast_node_count());
566 if (lit->dont_optimize_reason() != kNoReason) {
567 shared_info->DisableOptimization(lit->dont_optimize_reason());
568 }
569 if (lit->flags() & AstProperties::kMustUseIgnitionTurbo) {
570 shared_info->set_must_use_ignition_turbo(true);
571 }
572 }
573 return true;
574 }
575
576 bool GetOptimizedCodeNow(CompilationJob* job) { 635 bool GetOptimizedCodeNow(CompilationJob* job) {
577 CompilationInfo* info = job->info(); 636 CompilationInfo* info = job->info();
578 Isolate* isolate = info->isolate(); 637 Isolate* isolate = info->isolate();
579 638
580 // Parsing is not required when optimizing from existing bytecode. 639 // Parsing is not required when optimizing from existing bytecode.
581 if (!info->is_optimizing_from_bytecode()) { 640 if (!info->is_optimizing_from_bytecode()) {
582 if (!Compiler::ParseAndAnalyze(info->parse_info())) return false; 641 if (!Compiler::ParseAndAnalyze(info->parse_info())) return false;
583 EnsureFeedbackMetadata(info); 642 EnsureFeedbackMetadata(info);
584 } 643 }
585 644
(...skipping 423 matching lines...) Expand 10 before | Expand all | Expand 10 after
1009 Handle<SharedFunctionInfo> result; 1068 Handle<SharedFunctionInfo> result;
1010 1069
1011 { VMState<COMPILER> state(info->isolate()); 1070 { VMState<COMPILER> state(info->isolate());
1012 if (parse_info->literal() == nullptr && 1071 if (parse_info->literal() == nullptr &&
1013 !parsing::ParseProgram(parse_info)) { 1072 !parsing::ParseProgram(parse_info)) {
1014 return Handle<SharedFunctionInfo>::null(); 1073 return Handle<SharedFunctionInfo>::null();
1015 } 1074 }
1016 1075
1017 EnsureSharedFunctionInfosArrayOnScript(parse_info); 1076 EnsureSharedFunctionInfosArrayOnScript(parse_info);
1018 1077
1019 FunctionLiteral* lit = parse_info->literal();
1020
1021 // Measure how long it takes to do the compilation; only take the 1078 // Measure how long it takes to do the compilation; only take the
1022 // rest of the function into account to avoid overlap with the 1079 // rest of the function into account to avoid overlap with the
1023 // parsing statistics. 1080 // parsing statistics.
1024 HistogramTimer* rate = parse_info->is_eval() 1081 HistogramTimer* rate = parse_info->is_eval()
1025 ? info->isolate()->counters()->compile_eval() 1082 ? info->isolate()->counters()->compile_eval()
1026 : info->isolate()->counters()->compile(); 1083 : info->isolate()->counters()->compile();
1027 HistogramTimerScope timer(rate); 1084 HistogramTimerScope timer(rate);
1028 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), 1085 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"),
1029 parse_info->is_eval() ? "V8.CompileEval" : "V8.Compile"); 1086 parse_info->is_eval() ? "V8.CompileEval" : "V8.Compile");
1030 1087
1031 // Allocate a shared function info object. 1088 // Allocate a shared function info object.
1089 FunctionLiteral* lit = parse_info->literal();
1032 DCHECK_EQ(kNoSourcePosition, lit->function_token_position()); 1090 DCHECK_EQ(kNoSourcePosition, lit->function_token_position());
1033 result = isolate->factory()->NewSharedFunctionInfoForLiteral(lit, script); 1091 result = isolate->factory()->NewSharedFunctionInfoForLiteral(lit, script);
1034 result->set_is_toplevel(true); 1092 result->set_is_toplevel(true);
1035 parse_info->set_shared_info(result); 1093 parse_info->set_shared_info(result);
1036 parse_info->set_function_literal_id(result->function_literal_id()); 1094 parse_info->set_function_literal_id(result->function_literal_id());
1037 1095
1038 // Compile the code. 1096 // Compile the code.
1039 if (!CompileUnoptimizedCode(info)) { 1097 if (!CompileUnoptimizedCode(info)) {
1040 return Handle<SharedFunctionInfo>::null(); 1098 return Handle<SharedFunctionInfo>::null();
1041 } 1099 }
(...skipping 15 matching lines...) Expand all
1057 } 1115 }
1058 1116
1059 return result; 1117 return result;
1060 } 1118 }
1061 1119
1062 } // namespace 1120 } // namespace
1063 1121
1064 // ---------------------------------------------------------------------------- 1122 // ----------------------------------------------------------------------------
1065 // Implementation of Compiler 1123 // Implementation of Compiler
1066 1124
1067 bool Compiler::Analyze(ParseInfo* info) { 1125 bool Compiler::Analyze(ParseInfo* info,
1126 EagerInnerFunctionLiterals* eager_literals) {
1068 DCHECK_NOT_NULL(info->literal()); 1127 DCHECK_NOT_NULL(info->literal());
1069 RuntimeCallTimerScope runtimeTimer(info->isolate(), 1128 RuntimeCallTimerScope runtimeTimer(info->isolate(),
1070 &RuntimeCallStats::CompileAnalyse); 1129 &RuntimeCallStats::CompileAnalyse);
1071 if (!Rewriter::Rewrite(info)) return false; 1130 if (!Rewriter::Rewrite(info)) return false;
1072 DeclarationScope::Analyze(info, AnalyzeMode::kRegular); 1131 DeclarationScope::Analyze(info, AnalyzeMode::kRegular);
1073 if (!Renumber(info)) return false; 1132 if (!Renumber(info, eager_literals)) return false;
1074 DCHECK_NOT_NULL(info->scope()); 1133 DCHECK_NOT_NULL(info->scope());
1075 return true; 1134 return true;
1076 } 1135 }
1077 1136
1078 bool Compiler::ParseAndAnalyze(ParseInfo* info) { 1137 bool Compiler::ParseAndAnalyze(ParseInfo* info) {
1079 if (!parsing::ParseAny(info)) return false; 1138 if (!parsing::ParseAny(info)) return false;
1080 if (info->is_toplevel()) EnsureSharedFunctionInfosArrayOnScript(info); 1139 if (info->is_toplevel()) EnsureSharedFunctionInfosArrayOnScript(info);
1081 if (!Compiler::Analyze(info)) return false; 1140 if (!Compiler::Analyze(info)) return false;
1082 DCHECK_NOT_NULL(info->literal()); 1141 DCHECK_NOT_NULL(info->literal());
1083 DCHECK_NOT_NULL(info->scope()); 1142 DCHECK_NOT_NULL(info->scope());
(...skipping 501 matching lines...) Expand 10 before | Expand all | Expand 10 after
1585 // The source was parsed lazily, so compiling for debugging is not possible. 1644 // The source was parsed lazily, so compiling for debugging is not possible.
1586 DCHECK(!compile_info.is_debug()); 1645 DCHECK(!compile_info.is_debug());
1587 1646
1588 Handle<SharedFunctionInfo> result = CompileToplevel(&compile_info); 1647 Handle<SharedFunctionInfo> result = CompileToplevel(&compile_info);
1589 if (!result.is_null()) isolate->debug()->OnAfterCompile(script); 1648 if (!result.is_null()) isolate->debug()->OnAfterCompile(script);
1590 return result; 1649 return result;
1591 } 1650 }
1592 1651
1593 Handle<SharedFunctionInfo> Compiler::GetSharedFunctionInfo( 1652 Handle<SharedFunctionInfo> Compiler::GetSharedFunctionInfo(
1594 FunctionLiteral* literal, Handle<Script> script, 1653 FunctionLiteral* literal, Handle<Script> script,
1595 CompilationInfo* outer_info, LazyCompilationMode mode) { 1654 CompilationInfo* outer_info) {
1596 // Precondition: code has been parsed and scopes have been analyzed. 1655 // Precondition: code has been parsed and scopes have been analyzed.
1597 Isolate* isolate = outer_info->isolate(); 1656 Isolate* isolate = outer_info->isolate();
1598 MaybeHandle<SharedFunctionInfo> maybe_existing; 1657 MaybeHandle<SharedFunctionInfo> maybe_existing;
1599 1658
1600 // Find any previously allocated shared function info for the given literal. 1659 // Find any previously allocated shared function info for the given literal.
1601 maybe_existing = script->FindSharedFunctionInfo(isolate, literal); 1660 maybe_existing = script->FindSharedFunctionInfo(isolate, literal);
1602 1661
1603 // We found an existing shared function info. If it has any sort of code 1662 // If we found an existing shared function info, return it.
1604 // attached, don't worry about compiling and simply return it. Otherwise,
1605 // continue to decide whether to eagerly compile.
1606 // Note that we also carry on if we are compiling eager to obtain code for
1607 // debugging, unless we already have code with debug break slots.
1608 Handle<SharedFunctionInfo> existing; 1663 Handle<SharedFunctionInfo> existing;
1609 if (maybe_existing.ToHandle(&existing)) { 1664 if (maybe_existing.ToHandle(&existing)) {
1610 DCHECK(!existing->is_toplevel()); 1665 DCHECK(!existing->is_toplevel());
1611 if (existing->HasBaselineCode() || existing->HasBytecodeArray()) { 1666 return existing;
1612 if (!outer_info->is_debug() || existing->HasDebugCode()) {
1613 return existing;
1614 }
1615 }
1616 } 1667 }
1617 1668
1618 // Allocate a shared function info object. 1669 // Allocate a shared function info object which will be compiled lazily.
1619 Handle<SharedFunctionInfo> result; 1670 Handle<SharedFunctionInfo> result =
1620 if (!maybe_existing.ToHandle(&result)) { 1671 isolate->factory()->NewSharedFunctionInfoForLiteral(literal, script);
1621 result = 1672 result->set_is_toplevel(false);
1622 isolate->factory()->NewSharedFunctionInfoForLiteral(literal, script); 1673 Scope* outer_scope = literal->scope()->GetOuterScopeWithContext();
1623 result->set_is_toplevel(false); 1674 if (outer_scope) {
1675 result->set_outer_scope_info(*outer_scope->scope_info());
1624 } 1676 }
1625
1626 Zone zone(isolate->allocator(), ZONE_NAME);
1627 ParseInfo parse_info(&zone, script);
1628 CompilationInfo info(&parse_info, Handle<JSFunction>::null());
1629 parse_info.set_literal(literal);
1630 parse_info.set_shared_info(result);
1631 parse_info.set_function_literal_id(result->function_literal_id());
1632 parse_info.set_language_mode(literal->scope()->language_mode());
1633 parse_info.set_ast_value_factory(
1634 outer_info->parse_info()->ast_value_factory());
1635 parse_info.set_ast_value_factory_owned(false);
1636
1637 if (outer_info->will_serialize()) info.PrepareForSerializing();
1638 if (outer_info->is_debug()) info.MarkAsDebug();
1639
1640 // If this inner function is already compiled, we don't need to compile
1641 // again. When compiling for debug, we are not interested in having debug
1642 // break slots in inner functions, neither for setting break points nor
1643 // for revealing inner functions.
1644 // This is especially important for generators. We must not replace the
1645 // code for generators, as there may be suspended generator objects.
1646 if (!result->is_compiled()) {
1647 if (mode == LazyCompilationMode::kAlways ||
1648 !literal->ShouldEagerCompile()) {
1649 info.SetCode(isolate->builtins()->CompileLazy());
1650 Scope* outer_scope = literal->scope()->GetOuterScopeWithContext();
1651 if (outer_scope) {
1652 result->set_outer_scope_info(*outer_scope->scope_info());
1653 }
1654 } else {
1655 // Generate code
1656 TimerEventScope<TimerEventCompileCode> timer(isolate);
1657 RuntimeCallTimerScope runtimeTimer(
1658 isolate, &RuntimeCallStats::CompileInnerFunction);
1659 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.CompileCode");
1660 if (Renumber(info.parse_info()) && GenerateUnoptimizedCode(&info)) {
1661 // Code generation will ensure that the feedback vector is present and
1662 // appropriately sized.
1663 DCHECK(!info.code().is_null());
1664 if (literal->should_be_used_once_hint()) {
1665 info.code()->MarkToBeExecutedOnce(isolate);
1666 }
1667 } else {
1668 return Handle<SharedFunctionInfo>::null();
1669 }
1670 }
1671 }
1672
1673 if (maybe_existing.is_null()) {
1674 RecordFunctionCompilation(CodeEventListener::FUNCTION_TAG, &info);
1675 }
1676
1677 return result; 1677 return result;
1678 } 1678 }
1679 1679
1680 Handle<SharedFunctionInfo> Compiler::GetSharedFunctionInfoForNative( 1680 Handle<SharedFunctionInfo> Compiler::GetSharedFunctionInfoForNative(
1681 v8::Extension* extension, Handle<String> name) { 1681 v8::Extension* extension, Handle<String> name) {
1682 Isolate* isolate = name->GetIsolate(); 1682 Isolate* isolate = name->GetIsolate();
1683 v8::Isolate* v8_isolate = reinterpret_cast<v8::Isolate*>(isolate); 1683 v8::Isolate* v8_isolate = reinterpret_cast<v8::Isolate*>(isolate);
1684 1684
1685 // Compute the function template for the native function. 1685 // Compute the function template for the native function.
1686 v8::Local<v8::FunctionTemplate> fun_template = 1686 v8::Local<v8::FunctionTemplate> fun_template =
(...skipping 24 matching lines...) Expand all
1711 1711
1712 MaybeHandle<Code> Compiler::GetOptimizedCodeForOSR(Handle<JSFunction> function, 1712 MaybeHandle<Code> Compiler::GetOptimizedCodeForOSR(Handle<JSFunction> function,
1713 BailoutId osr_ast_id, 1713 BailoutId osr_ast_id,
1714 JavaScriptFrame* osr_frame) { 1714 JavaScriptFrame* osr_frame) {
1715 DCHECK(!osr_ast_id.IsNone()); 1715 DCHECK(!osr_ast_id.IsNone());
1716 DCHECK_NOT_NULL(osr_frame); 1716 DCHECK_NOT_NULL(osr_frame);
1717 return GetOptimizedCode(function, NOT_CONCURRENT, osr_ast_id, osr_frame); 1717 return GetOptimizedCode(function, NOT_CONCURRENT, osr_ast_id, osr_frame);
1718 } 1718 }
1719 1719
1720 CompilationJob* Compiler::PrepareUnoptimizedCompilationJob( 1720 CompilationJob* Compiler::PrepareUnoptimizedCompilationJob(
1721 CompilationInfo* info, LazyCompilationMode mode) { 1721 CompilationInfo* info) {
1722 VMState<COMPILER> state(info->isolate()); 1722 VMState<COMPILER> state(info->isolate());
1723 std::unique_ptr<CompilationJob> job(GetUnoptimizedCompilationJob(info, mode)); 1723 std::unique_ptr<CompilationJob> job(GetUnoptimizedCompilationJob(info));
1724 if (job->PrepareJob() != CompilationJob::SUCCEEDED) { 1724 if (job->PrepareJob() != CompilationJob::SUCCEEDED) {
1725 return nullptr; 1725 return nullptr;
1726 } 1726 }
1727 return job.release(); 1727 return job.release();
1728 } 1728 }
1729 1729
1730 bool Compiler::FinalizeCompilationJob(CompilationJob* raw_job) { 1730 bool Compiler::FinalizeCompilationJob(CompilationJob* raw_job) {
1731 // Take ownership of compilation job. Deleting job also tears down the zone. 1731 // Take ownership of compilation job. Deleting job also tears down the zone.
1732 std::unique_ptr<CompilationJob> job(raw_job); 1732 std::unique_ptr<CompilationJob> job(raw_job);
1733 1733
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
1769 DCHECK(shared->is_compiled()); 1769 DCHECK(shared->is_compiled());
1770 function->set_literals(cached.literals); 1770 function->set_literals(cached.literals);
1771 } else if (shared->is_compiled()) { 1771 } else if (shared->is_compiled()) {
1772 // TODO(mvstanton): pass pretenure flag to EnsureLiterals. 1772 // TODO(mvstanton): pass pretenure flag to EnsureLiterals.
1773 JSFunction::EnsureLiterals(function); 1773 JSFunction::EnsureLiterals(function);
1774 } 1774 }
1775 } 1775 }
1776 1776
1777 } // namespace internal 1777 } // namespace internal
1778 } // namespace v8 1778 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler.h ('k') | src/compiler-dispatcher/compiler-dispatcher-job.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698