| 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 20 matching lines...) Expand all  Loading... | 
| 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  Loading... | 
| 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  Loading... | 
| 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  Loading... | 
| 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  Loading... | 
| 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  Loading... | 
| 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  Loading... | 
| 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  Loading... | 
| 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  Loading... | 
| 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 | 
| OLD | NEW | 
|---|