LCOV - code coverage report
Current view: top level - src - compiler.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 464 524 88.5 %
Date: 2017-10-20 Functions: 46 49 93.9 %

          Line data    Source code
       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
       3             : // found in the LICENSE file.
       4             : 
       5             : #include "src/compiler.h"
       6             : 
       7             : #include <algorithm>
       8             : #include <memory>
       9             : 
      10             : #include "src/api.h"
      11             : #include "src/asmjs/asm-js.h"
      12             : #include "src/assembler-inl.h"
      13             : #include "src/ast/ast-numbering.h"
      14             : #include "src/ast/prettyprinter.h"
      15             : #include "src/ast/scopes.h"
      16             : #include "src/base/optional.h"
      17             : #include "src/bootstrapper.h"
      18             : #include "src/compilation-cache.h"
      19             : #include "src/compilation-info.h"
      20             : #include "src/compiler-dispatcher/compiler-dispatcher.h"
      21             : #include "src/compiler-dispatcher/optimizing-compile-dispatcher.h"
      22             : #include "src/compiler/pipeline.h"
      23             : #include "src/debug/debug.h"
      24             : #include "src/debug/liveedit.h"
      25             : #include "src/frames-inl.h"
      26             : #include "src/globals.h"
      27             : #include "src/heap/heap.h"
      28             : #include "src/interpreter/interpreter.h"
      29             : #include "src/isolate-inl.h"
      30             : #include "src/log-inl.h"
      31             : #include "src/messages.h"
      32             : #include "src/objects/map.h"
      33             : #include "src/parsing/parse-info.h"
      34             : #include "src/parsing/parsing.h"
      35             : #include "src/parsing/rewriter.h"
      36             : #include "src/parsing/scanner-character-streams.h"
      37             : #include "src/runtime-profiler.h"
      38             : #include "src/snapshot/code-serializer.h"
      39             : #include "src/vm-state-inl.h"
      40             : 
      41             : namespace v8 {
      42             : namespace internal {
      43             : 
      44             : // A wrapper around a CompilationInfo that detaches the Handles from
      45             : // the underlying DeferredHandleScope and stores them in info_ on
      46             : // destruction.
      47             : class CompilationHandleScope final {
      48             :  public:
      49        8605 :   explicit CompilationHandleScope(CompilationInfo* info)
      50        8605 :       : deferred_(info->isolate()), info_(info) {}
      51        8605 :   ~CompilationHandleScope() { info_->set_deferred_handles(deferred_.Detach()); }
      52             : 
      53             :  private:
      54             :   DeferredHandleScope deferred_;
      55             :   CompilationInfo* info_;
      56             : };
      57             : 
      58             : // Helper that times a scoped region and records the elapsed time.
      59             : struct ScopedTimer {
      60     8861606 :   explicit ScopedTimer(base::TimeDelta* location) : location_(location) {
      61             :     DCHECK_NOT_NULL(location_);
      62             :     timer_.Start();
      63             :   }
      64             : 
      65    26584950 :   ~ScopedTimer() { *location_ += timer_.Elapsed(); }
      66             : 
      67             :   base::ElapsedTimer timer_;
      68             :   base::TimeDelta* location_;
      69             : };
      70             : 
      71             : // ----------------------------------------------------------------------------
      72             : // Implementation of CompilationJob
      73             : 
      74     3162360 : CompilationJob::CompilationJob(Isolate* isolate, ParseInfo* parse_info,
      75             :                                CompilationInfo* compilation_info,
      76             :                                const char* compiler_name, State initial_state)
      77             :     : parse_info_(parse_info),
      78             :       compilation_info_(compilation_info),
      79             :       isolate_thread_id_(isolate->thread_id()),
      80             :       compiler_name_(compiler_name),
      81             :       state_(initial_state),
      82     3162360 :       stack_limit_(isolate->stack_guard()->real_climit()),
      83     9487080 :       executed_on_background_thread_(false) {}
      84             : 
      85     2916448 : CompilationJob::Status CompilationJob::PrepareJob() {
      86             :   DCHECK(
      87             :       ThreadId::Current().Equals(compilation_info()->isolate()->thread_id()));
      88     2916448 :   DisallowJavascriptExecution no_js(isolate());
      89             : 
      90     2916450 :   if (FLAG_trace_opt && compilation_info()->IsOptimizing()) {
      91           0 :     OFStream os(stdout);
      92           0 :     os << "[compiling method " << Brief(*compilation_info()->closure())
      93           0 :        << " using " << compiler_name_;
      94           0 :     if (compilation_info()->is_osr()) os << " OSR";
      95           0 :     os << "]" << std::endl;
      96             :   }
      97             : 
      98             :   // Delegate to the underlying implementation.
      99             :   DCHECK_EQ(state(), State::kReadyToPrepare);
     100     5832894 :   ScopedTimer t(&time_taken_to_prepare_);
     101     5832902 :   return UpdateState(PrepareJobImpl(), State::kReadyToExecute);
     102             : }
     103             : 
     104     3144326 : CompilationJob::Status CompilationJob::ExecuteJob() {
     105             :   base::Optional<DisallowHeapAllocation> no_allocation;
     106             :   base::Optional<DisallowHandleAllocation> no_handles;
     107             :   base::Optional<DisallowHandleDereference> no_deref;
     108             :   base::Optional<DisallowCodeDependencyChange> no_dependency_change;
     109     3144326 :   if (can_execute_on_background_thread()) {
     110             :     no_allocation.emplace();
     111             :     no_handles.emplace();
     112             :     no_deref.emplace();
     113             :     no_dependency_change.emplace();
     114             :     executed_on_background_thread_ =
     115     6288657 :         !ThreadId::Current().Equals(isolate_thread_id_);
     116             :   } else {
     117             :     DCHECK(ThreadId::Current().Equals(isolate_thread_id_));
     118             :   }
     119             : 
     120             :   // Delegate to the underlying implementation.
     121             :   DCHECK_EQ(state(), State::kReadyToExecute);
     122     3144328 :   ScopedTimer t(&time_taken_to_execute_);
     123     6288753 :   return UpdateState(ExecuteJobImpl(), State::kReadyToFinalize);
     124             : }
     125             : 
     126     2800827 : CompilationJob::Status CompilationJob::FinalizeJob() {
     127             :   DCHECK(
     128             :       ThreadId::Current().Equals(compilation_info()->isolate()->thread_id()));
     129             :   DisallowCodeDependencyChange no_dependency_change;
     130     2800827 :   DisallowJavascriptExecution no_js(isolate());
     131             :   DCHECK(!compilation_info()->dependencies()->HasAborted());
     132             : 
     133             :   // Delegate to the underlying implementation.
     134             :   DCHECK_EQ(state(), State::kReadyToFinalize);
     135     5601653 :   ScopedTimer t(&time_taken_to_finalize_);
     136     5601658 :   return UpdateState(FinalizeJobImpl(), State::kSucceeded);
     137             : }
     138             : 
     139           0 : CompilationJob::Status CompilationJob::RetryOptimization(BailoutReason reason) {
     140             :   DCHECK(compilation_info_->IsOptimizing());
     141          41 :   compilation_info_->RetryOptimization(reason);
     142          41 :   state_ = State::kFailed;
     143           0 :   return FAILED;
     144             : }
     145             : 
     146           0 : CompilationJob::Status CompilationJob::AbortOptimization(BailoutReason reason) {
     147             :   DCHECK(compilation_info_->IsOptimizing());
     148           0 :   compilation_info_->AbortOptimization(reason);
     149           0 :   state_ = State::kFailed;
     150           0 :   return FAILED;
     151             : }
     152             : 
     153     2134855 : void CompilationJob::RecordUnoptimizedCompilationStats() const {
     154             :   int code_size;
     155     2134855 :   if (compilation_info()->has_bytecode_array()) {
     156     2131308 :     code_size = compilation_info()->bytecode_array()->SizeIncludingMetadata();
     157             :   } else {
     158        3547 :     code_size = compilation_info()->code()->SizeIncludingMetadata();
     159             :   }
     160             : 
     161             :   Counters* counters = isolate()->counters();
     162             :   // TODO(4280): Rename counters from "baseline" to "unoptimized" eventually.
     163     2134855 :   counters->total_baseline_code_size()->Increment(code_size);
     164     2134855 :   counters->total_baseline_compile_count()->Increment(1);
     165             : 
     166             :   // TODO(5203): Add timers for each phase of compilation.
     167     2134855 : }
     168             : 
     169      438219 : void CompilationJob::RecordOptimizedCompilationStats() const {
     170             :   DCHECK(compilation_info()->IsOptimizing());
     171             :   Handle<JSFunction> function = compilation_info()->closure();
     172      438219 :   double ms_creategraph = time_taken_to_prepare_.InMillisecondsF();
     173      438219 :   double ms_optimize = time_taken_to_execute_.InMillisecondsF();
     174      438219 :   double ms_codegen = time_taken_to_finalize_.InMillisecondsF();
     175      438219 :   if (FLAG_trace_opt) {
     176           0 :     PrintF("[optimizing ");
     177           0 :     function->ShortPrint();
     178             :     PrintF(" - took %0.3f, %0.3f, %0.3f ms]\n", ms_creategraph, ms_optimize,
     179           0 :            ms_codegen);
     180             :   }
     181      438219 :   if (FLAG_trace_opt_stats) {
     182             :     static double compilation_time = 0.0;
     183             :     static int compiled_functions = 0;
     184             :     static int code_size = 0;
     185             : 
     186           0 :     compilation_time += (ms_creategraph + ms_optimize + ms_codegen);
     187           0 :     compiled_functions++;
     188           0 :     code_size += function->shared()->SourceSize();
     189             :     PrintF("Compiled: %d functions with %d byte source size in %fms.\n",
     190           0 :            compiled_functions, code_size, compilation_time);
     191             :   }
     192      438219 : }
     193             : 
     194    12718363 : Isolate* CompilationJob::isolate() const {
     195    12718363 :   return compilation_info()->isolate();
     196             : }
     197             : 
     198             : // ----------------------------------------------------------------------------
     199             : // Local helper methods that make up the compilation pipeline.
     200             : 
     201             : namespace {
     202             : 
     203     2573073 : void RecordFunctionCompilation(CodeEventListener::LogEventsAndTags tag,
     204             :                                Handle<Script> script,
     205     2574671 :                                CompilationInfo* compilation_info) {
     206             :   // Log the code generation. If source information is available include
     207             :   // script name and line number. Check explicitly whether logging is
     208             :   // enabled as finding the line number is not free.
     209     7718859 :   if (compilation_info->isolate()->logger()->is_logging_code_events() ||
     210     2572713 :       compilation_info->isolate()->is_profiling()) {
     211             :     Handle<SharedFunctionInfo> shared = compilation_info->shared_info();
     212             :     Handle<AbstractCode> abstract_code =
     213             :         compilation_info->has_bytecode_array()
     214             :             ? Handle<AbstractCode>::cast(compilation_info->bytecode_array())
     215         869 :             : Handle<AbstractCode>::cast(compilation_info->code());
     216         869 :     if (abstract_code.is_identical_to(
     217        1738 :             BUILTIN_CODE(compilation_info->isolate(), CompileLazy))) {
     218     2573073 :       return;
     219             :     }
     220         869 :     int line_num = Script::GetLineNumber(script, shared->start_position()) + 1;
     221             :     int column_num =
     222         869 :         Script::GetColumnNumber(script, shared->start_position()) + 1;
     223             :     String* script_name =
     224             :         script->name()->IsString()
     225             :             ? String::cast(script->name())
     226        1598 :             : compilation_info->isolate()->heap()->empty_string();
     227             :     CodeEventListener::LogEventsAndTags log_tag =
     228             :         Logger::ToNativeByScript(tag, *script);
     229         869 :     PROFILE(compilation_info->isolate(),
     230             :             CodeCreateEvent(log_tag, *abstract_code, *shared, script_name,
     231             :                             line_num, column_num));
     232             :   }
     233             : }
     234             : 
     235     4269710 : void EnsureFeedbackMetadata(CompilationInfo* compilation_info) {
     236             :   DCHECK(compilation_info->has_shared_info());
     237             : 
     238             :   // If no type feedback metadata exists, create it. At this point the
     239             :   // AstNumbering pass has already run. Note the snapshot can contain outdated
     240             :   // vectors for a different configuration, hence we also recreate a new vector
     241             :   // when the function is not compiled (i.e. no code was serialized).
     242             : 
     243             :   // TODO(mvstanton): reintroduce is_empty() predicate to feedback_metadata().
     244     2147558 :   if (compilation_info->shared_info()->feedback_metadata()->length() == 0 ||
     245             :       !compilation_info->shared_info()->is_compiled()) {
     246             :     Handle<FeedbackMetadata> feedback_metadata = FeedbackMetadata::New(
     247     4269710 :         compilation_info->isolate(), compilation_info->feedback_vector_spec());
     248     2134854 :     compilation_info->shared_info()->set_feedback_metadata(*feedback_metadata);
     249             :   }
     250             : 
     251             :   // It's very important that recompiles do not alter the structure of the type
     252             :   // feedback vector. Verify that the structure fits the function literal.
     253     4269710 :   CHECK(!compilation_info->shared_info()->feedback_metadata()->SpecDiffersFrom(
     254             :       compilation_info->feedback_vector_spec()));
     255     2134854 : }
     256             : 
     257     3927896 : bool UseAsmWasm(FunctionLiteral* literal, bool asm_wasm_broken) {
     258             :   // Check whether asm.js validation is enabled.
     259     2134847 :   if (!FLAG_validate_asm) return false;
     260             : 
     261             :   // Modules that have validated successfully, but were subsequently broken by
     262             :   // invalid module instantiation attempts are off limit forever.
     263     2134838 :   if (asm_wasm_broken) return false;
     264             : 
     265             :   // In stress mode we want to run the validator on everything.
     266     2134658 :   if (FLAG_stress_validate_asm) return true;
     267             : 
     268             :   // In general, we respect the "use asm" directive.
     269     1793049 :   return literal->scope()->IsAsmModule();
     270             : }
     271             : 
     272     2135636 : void InstallUnoptimizedCode(CompilationInfo* compilation_info) {
     273             :   Handle<SharedFunctionInfo> shared = compilation_info->shared_info();
     274             :   DCHECK_EQ(compilation_info->shared_info()->language_mode(),
     275             :             compilation_info->literal()->language_mode());
     276             : 
     277             :   // Ensure feedback metadata is installed.
     278     2134855 :   EnsureFeedbackMetadata(compilation_info);
     279             : 
     280             :   // Update the shared function info with the scope info.
     281     2134855 :   Handle<ScopeInfo> scope_info = compilation_info->scope()->scope_info();
     282     2134855 :   shared->set_scope_info(*scope_info);
     283     2134855 :   Scope* outer_scope = compilation_info->scope()->GetOuterScopeWithContext();
     284     2134855 :   if (outer_scope) {
     285     1927124 :     shared->set_outer_scope_info(*outer_scope->scope_info());
     286             :   }
     287             : 
     288             :   DCHECK(!compilation_info->code().is_null());
     289     2134855 :   shared->set_code(*compilation_info->code());
     290     2134855 :   if (compilation_info->has_bytecode_array()) {
     291             :     DCHECK(!shared->HasBytecodeArray());  // Only compiled once.
     292             :     DCHECK(!compilation_info->has_asm_wasm_data());
     293             :     shared->set_bytecode_array(*compilation_info->bytecode_array());
     294        3547 :   } else if (compilation_info->has_asm_wasm_data()) {
     295             :     shared->set_asm_wasm_data(*compilation_info->asm_wasm_data());
     296             :   }
     297             : 
     298             :   // Install coverage info on the shared function info.
     299     2134855 :   if (compilation_info->has_coverage_info()) {
     300             :     DCHECK(compilation_info->isolate()->is_block_code_coverage());
     301             :     compilation_info->isolate()->debug()->InstallCoverageInfo(
     302         781 :         compilation_info->shared_info(), compilation_info->coverage_info());
     303             :   }
     304     2134855 : }
     305             : 
     306     2022462 : void EnsureSharedFunctionInfosArrayOnScript(ParseInfo* parse_info,
     307             :                                             Isolate* isolate) {
     308             :   DCHECK(parse_info->is_toplevel());
     309             :   DCHECK(!parse_info->script().is_null());
     310     1011231 :   if (parse_info->script()->shared_function_infos()->length() > 0) {
     311             :     DCHECK_EQ(parse_info->script()->shared_function_infos()->length(),
     312             :               parse_info->max_function_literal_id() + 1);
     313           0 :     return;
     314             :   }
     315             :   Handle<FixedArray> infos(isolate->factory()->NewFixedArray(
     316     1011231 :       parse_info->max_function_literal_id() + 1));
     317     1011231 :   parse_info->script()->set_shared_function_infos(*infos);
     318             : }
     319             : 
     320     6759599 : void SetSharedFunctionFlagsFromLiteral(FunctionLiteral* literal,
     321             :                                        Handle<SharedFunctionInfo> shared_info) {
     322             :   // Don't overwrite values set by the bootstrapper.
     323     2134855 :   if (!shared_info->HasLength()) {
     324             :     shared_info->set_length(literal->function_length());
     325             :   }
     326             :   shared_info->set_has_duplicate_parameters(
     327             :       literal->has_duplicate_parameters());
     328     2134855 :   shared_info->SetExpectedNofPropertiesFromEstimate(literal);
     329     2134855 :   if (literal->dont_optimize_reason() != kNoReason) {
     330        1413 :     shared_info->DisableOptimization(literal->dont_optimize_reason());
     331             :   }
     332     2134855 : }
     333             : 
     334     2134855 : CompilationJob::Status FinalizeUnoptimizedCompilationJob(CompilationJob* job) {
     335     2134855 :   CompilationInfo* compilation_info = job->compilation_info();
     336             :   ParseInfo* parse_info = job->parse_info();
     337             : 
     338             :   SetSharedFunctionFlagsFromLiteral(compilation_info->literal(),
     339     2134855 :                                     compilation_info->shared_info());
     340             : 
     341     2134855 :   CompilationJob::Status status = job->FinalizeJob();
     342     2134855 :   if (status == CompilationJob::SUCCEEDED) {
     343     2134855 :     InstallUnoptimizedCode(compilation_info);
     344             :     CodeEventListener::LogEventsAndTags log_tag;
     345     2134855 :     if (parse_info->is_toplevel()) {
     346             :       log_tag = compilation_info->is_eval() ? CodeEventListener::EVAL_TAG
     347     1554885 :                                             : CodeEventListener::SCRIPT_TAG;
     348             :     } else {
     349             :       log_tag = parse_info->lazy_compile() ? CodeEventListener::LAZY_COMPILE_TAG
     350      579970 :                                            : CodeEventListener::FUNCTION_TAG;
     351             :     }
     352     2134855 :     RecordFunctionCompilation(log_tag, parse_info->script(), compilation_info);
     353     2134855 :     job->RecordUnoptimizedCompilationStats();
     354             :   }
     355     2134855 :   return status;
     356             : }
     357             : 
     358     4889792 : bool Renumber(ParseInfo* parse_info,
     359             :               Compiler::EagerInnerFunctionLiterals* eager_literals) {
     360             :   RuntimeCallTimerScope runtimeTimer(parse_info->runtime_call_stats(),
     361     1629930 :                                      &RuntimeCallStats::CompileRenumber);
     362             :   return AstNumbering::Renumber(parse_info->stack_limit(), parse_info->zone(),
     363     3259862 :                                 parse_info->literal(), eager_literals);
     364             : }
     365             : 
     366     2134847 : std::unique_ptr<CompilationJob> PrepareAndExecuteUnoptimizedCompileJob(
     367             :     ParseInfo* parse_info, FunctionLiteral* literal, Isolate* isolate) {
     368     2134847 :   if (UseAsmWasm(literal, parse_info->is_asm_wasm_broken())) {
     369             :     std::unique_ptr<CompilationJob> asm_job(
     370      346048 :         AsmJs::NewCompilationJob(parse_info, literal, isolate));
     371      692095 :     if (asm_job->PrepareJob() == CompilationJob::SUCCEEDED &&
     372      346048 :         asm_job->ExecuteJob() == CompilationJob::SUCCEEDED) {
     373             :       return asm_job;
     374             :     }
     375             :     // asm.js validation failed, fall through to standard unoptimized compile.
     376             :     // Note: we rely on the fact that AsmJs jobs have done all validation in the
     377             :     // PrepareJob and ExecuteJob phases and can't fail in FinalizeJob with
     378             :     // with a validation error or another error that could be solve by falling
     379             :     // through to standard unoptimized compile.
     380             :   }
     381             :   std::unique_ptr<CompilationJob> job(
     382             :       interpreter::Interpreter::NewCompilationJob(parse_info, literal,
     383     2131304 :                                                   isolate));
     384     4262606 :   if (job->PrepareJob() == CompilationJob::SUCCEEDED &&
     385     2131304 :       job->ExecuteJob() == CompilationJob::SUCCEEDED) {
     386             :     return job;
     387             :   }
     388             :   return std::unique_ptr<CompilationJob>();  // Compilation failed, return null.
     389             : }
     390             : 
     391             : // TODO(rmcilroy): Remove |isolate| once CompilationJob doesn't need it.
     392     1587388 : std::unique_ptr<CompilationJob> GenerateUnoptimizedCode(
     393     1587359 :     ParseInfo* parse_info, Isolate* isolate,
     394             :     std::forward_list<std::unique_ptr<CompilationJob>>* inner_function_jobs) {
     395             :   DisallowHeapAllocation no_allocation;
     396             :   DisallowHandleAllocation no_handles;
     397             :   DisallowHandleDereference no_deref;
     398             :   DCHECK(inner_function_jobs->empty());
     399             : 
     400             :   DCHECK_IMPLIES(parse_info->consumed_preparsed_scope_data()->HasData(),
     401             :                  ThreadId::Current().Equals(isolate->thread_id()));
     402             : 
     403             :   Compiler::EagerInnerFunctionLiterals inner_literals;
     404     1587388 :   if (!Compiler::Analyze(parse_info, &inner_literals)) {
     405             :     return std::unique_ptr<CompilationJob>();
     406             :   }
     407             : 
     408             :   // Prepare and execute compilation of the outer-most function.
     409             :   std::unique_ptr<CompilationJob> outer_function_job(
     410             :       PrepareAndExecuteUnoptimizedCompileJob(parse_info, parse_info->literal(),
     411     1587359 :                                              isolate));
     412     1587357 :   if (!outer_function_job) return std::unique_ptr<CompilationJob>();
     413             : 
     414             :   // Prepare and execute compilation jobs for eager inner functions.
     415     4269674 :   for (auto it : inner_literals) {
     416             :     FunctionLiteral* inner_literal = it->value();
     417             :     std::unique_ptr<CompilationJob> inner_job(
     418             :         PrepareAndExecuteUnoptimizedCompileJob(parse_info, inner_literal,
     419      547489 :                                                isolate));
     420      547490 :     if (!inner_job) return std::unique_ptr<CompilationJob>();
     421             :     inner_function_jobs->emplace_front(std::move(inner_job));
     422             :   }
     423             : 
     424             :   // Character stream shouldn't be used again.
     425     1587349 :   parse_info->ResetCharacterStream();
     426             : 
     427             :   return outer_function_job;
     428             : }
     429             : 
     430     1587350 : bool FinalizeUnoptimizedCode(
     431             :     ParseInfo* parse_info, Isolate* isolate,
     432     1587350 :     Handle<SharedFunctionInfo> shared_info, CompilationJob* outer_function_job,
     433             :     std::forward_list<std::unique_ptr<CompilationJob>>* inner_function_jobs) {
     434             :   DCHECK(AllowCompilation::IsAllowed(isolate));
     435             : 
     436             :   // Allocate scope infos for the literal.
     437             :   DeclarationScope::AllocateScopeInfos(parse_info, isolate,
     438     1587350 :                                        AnalyzeMode::kRegular);
     439             : 
     440             :   // Finalize the outer-most function's compilation job.
     441             :   outer_function_job->compilation_info()->set_shared_info(shared_info);
     442     1587350 :   if (FinalizeUnoptimizedCompilationJob(outer_function_job) !=
     443             :       CompilationJob::SUCCEEDED) {
     444             :     return false;
     445             :   }
     446             : 
     447             :   // Finalize the inner functions' compilation jobs.
     448     3722191 :   for (auto&& inner_job : *inner_function_jobs) {
     449             :     Handle<SharedFunctionInfo> inner_shared_info =
     450             :         Compiler::GetSharedFunctionInfo(
     451             :             inner_job->compilation_info()->literal(), parse_info->script(),
     452      547491 :             isolate);
     453             :     // The inner function might be compiled already if compiling for debug.
     454             :     // TODO(rmcilroy): Fix this and DCHECK !is_compiled() once Full-Codegen dies
     455      547496 :     if (inner_shared_info->is_compiled()) continue;
     456      547486 :     inner_job->compilation_info()->set_shared_info(inner_shared_info);
     457      547486 :     if (FinalizeUnoptimizedCompilationJob(inner_job.get()) !=
     458             :         CompilationJob::SUCCEEDED) {
     459           0 :       return false;
     460             :     }
     461             :   }
     462             :   return true;
     463             : }
     464             : 
     465      457031 : MUST_USE_RESULT MaybeHandle<Code> GetCodeFromOptimizedCodeCache(
     466             :     Handle<JSFunction> function, BailoutId osr_offset) {
     467             :   RuntimeCallTimerScope runtimeTimer(
     468             :       function->GetIsolate(),
     469      457031 :       &RuntimeCallStats::CompileGetFromOptimizedCodeMap);
     470             :   Handle<SharedFunctionInfo> shared(function->shared());
     471             :   DisallowHeapAllocation no_gc;
     472      457030 :   if (osr_offset.IsNone()) {
     473      450995 :     if (function->feedback_vector_cell()->value()->IsFeedbackVector()) {
     474             :       FeedbackVector* feedback_vector = function->feedback_vector();
     475             :       feedback_vector->EvictOptimizedCodeMarkedForDeoptimization(
     476      450995 :           function->shared(), "GetCodeFromOptimizedCodeCache");
     477             :       Code* code = feedback_vector->optimized_code();
     478             : 
     479      450995 :       if (code != nullptr) {
     480             :         // Caching of optimized code enabled and optimized code found.
     481             :         DCHECK(!code->marked_for_deoptimization());
     482             :         DCHECK(function->shared()->is_compiled());
     483           0 :         return Handle<Code>(code);
     484             :       }
     485             :     }
     486             :   }
     487      457030 :   return MaybeHandle<Code>();
     488             : }
     489             : 
     490      419612 : void ClearOptimizedCodeCache(CompilationInfo* compilation_info) {
     491             :   Handle<JSFunction> function = compilation_info->closure();
     492      419612 :   if (compilation_info->osr_offset().IsNone()) {
     493             :     Handle<FeedbackVector> vector =
     494             :         handle(function->feedback_vector(), function->GetIsolate());
     495      413853 :     vector->ClearOptimizedCode();
     496             :   }
     497      419613 : }
     498             : 
     499      438218 : void InsertCodeIntoOptimizedCodeCache(CompilationInfo* compilation_info) {
     500             :   Handle<Code> code = compilation_info->code();
     501      438218 :   if (code->kind() != Code::OPTIMIZED_FUNCTION) return;  // Nothing to do.
     502             : 
     503             :   // Function context specialization folds-in the function context,
     504             :   // so no sharing can occur.
     505      438218 :   if (compilation_info->is_function_context_specializing()) {
     506             :     // Native context specialized code is not shared, so make sure the optimized
     507             :     // code cache is clear.
     508      419612 :     ClearOptimizedCodeCache(compilation_info);
     509      419613 :     return;
     510             :   }
     511             : 
     512             :   // Cache optimized context-specific code.
     513             :   Handle<JSFunction> function = compilation_info->closure();
     514             :   Handle<SharedFunctionInfo> shared(function->shared());
     515             :   Handle<Context> native_context(function->context()->native_context());
     516       18606 :   if (compilation_info->osr_offset().IsNone()) {
     517             :     Handle<FeedbackVector> vector =
     518       18557 :         handle(function->feedback_vector(), function->GetIsolate());
     519       18557 :     FeedbackVector::SetOptimizedCode(vector, code);
     520             :   }
     521             : }
     522             : 
     523      860927 : bool GetOptimizedCodeNow(CompilationJob* job) {
     524      430469 :   CompilationInfo* compilation_info = job->compilation_info();
     525             :   Isolate* isolate = compilation_info->isolate();
     526             :   TimerEventScope<TimerEventRecompileSynchronous> timer(isolate);
     527             :   RuntimeCallTimerScope runtimeTimer(isolate,
     528      430469 :                                      &RuntimeCallStats::RecompileSynchronous);
     529     1291406 :   TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"),
     530             :                "V8.RecompileSynchronous");
     531             : 
     532     1291405 :   if (job->PrepareJob() != CompilationJob::SUCCEEDED ||
     533      860927 :       job->ExecuteJob() != CompilationJob::SUCCEEDED ||
     534      430459 :       job->FinalizeJob() != CompilationJob::SUCCEEDED) {
     535          10 :     if (FLAG_trace_opt) {
     536           0 :       PrintF("[aborted optimizing ");
     537           0 :       compilation_info->closure()->ShortPrint();
     538             :       PrintF(" because: %s]\n",
     539           0 :              GetBailoutReason(compilation_info->bailout_reason()));
     540             :     }
     541             :     return false;
     542             :   }
     543             : 
     544             :   // Success!
     545      430459 :   job->RecordOptimizedCompilationStats();
     546             :   DCHECK(!isolate->has_pending_exception());
     547      430458 :   InsertCodeIntoOptimizedCodeCache(compilation_info);
     548             :   RecordFunctionCompilation(CodeEventListener::LAZY_COMPILE_TAG,
     549      430458 :                             job->parse_info()->script(), compilation_info);
     550      430458 :   return true;
     551             : }
     552             : 
     553        8605 : bool GetOptimizedCodeLater(CompilationJob* job) {
     554        8605 :   CompilationInfo* compilation_info = job->compilation_info();
     555       17210 :   Isolate* isolate = compilation_info->isolate();
     556             : 
     557        8605 :   if (!isolate->optimizing_compile_dispatcher()->IsQueueAvailable()) {
     558           0 :     if (FLAG_trace_concurrent_recompilation) {
     559           0 :       PrintF("  ** Compilation queue full, will retry optimizing ");
     560           0 :       compilation_info->closure()->ShortPrint();
     561           0 :       PrintF(" later.\n");
     562             :     }
     563             :     return false;
     564             :   }
     565             : 
     566        8605 :   if (isolate->heap()->HighMemoryPressure()) {
     567           0 :     if (FLAG_trace_concurrent_recompilation) {
     568           0 :       PrintF("  ** High memory pressure, will retry optimizing ");
     569           0 :       compilation_info->closure()->ShortPrint();
     570           0 :       PrintF(" later.\n");
     571             :     }
     572             :     return false;
     573             :   }
     574             : 
     575             :   TimerEventScope<TimerEventRecompileSynchronous> timer(isolate);
     576             :   RuntimeCallTimerScope runtimeTimer(isolate,
     577        8605 :                                      &RuntimeCallStats::RecompileSynchronous);
     578       25815 :   TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"),
     579             :                "V8.RecompileSynchronous");
     580             : 
     581        8605 :   if (job->PrepareJob() != CompilationJob::SUCCEEDED) return false;
     582        8605 :   isolate->optimizing_compile_dispatcher()->QueueForOptimization(job);
     583             : 
     584        8605 :   if (FLAG_trace_concurrent_recompilation) {
     585           0 :     PrintF("  ** Queued ");
     586           0 :     compilation_info->closure()->ShortPrint();
     587           0 :     PrintF(" for concurrent optimization.\n");
     588             :   }
     589             :   return true;
     590             : }
     591             : 
     592      457031 : MaybeHandle<Code> GetOptimizedCode(Handle<JSFunction> function,
     593             :                                    ConcurrencyMode mode,
     594             :                                    BailoutId osr_offset = BailoutId::None(),
     595             :                                    JavaScriptFrame* osr_frame = nullptr) {
     596             :   Isolate* isolate = function->GetIsolate();
     597             :   Handle<SharedFunctionInfo> shared(function->shared(), isolate);
     598             : 
     599             :   // Make sure we clear the optimization marker on the function so that we
     600             :   // don't try to re-optimize.
     601      457031 :   if (function->HasOptimizationMarker()) {
     602             :     function->ClearOptimizationMarker();
     603             :   }
     604             : 
     605             :   Handle<Code> cached_code;
     606      457031 :   if (GetCodeFromOptimizedCodeCache(function, osr_offset)
     607      914062 :           .ToHandle(&cached_code)) {
     608           0 :     if (FLAG_trace_opt) {
     609           0 :       PrintF("[found optimized code for ");
     610           0 :       function->ShortPrint();
     611           0 :       if (!osr_offset.IsNone()) {
     612           0 :         PrintF(" at OSR AST id %d", osr_offset.ToInt());
     613             :       }
     614           0 :       PrintF("]\n");
     615             :     }
     616           0 :     return cached_code;
     617             :   }
     618             : 
     619             :   // Reset profiler ticks, function is no longer considered hot.
     620             :   DCHECK(shared->is_compiled());
     621             :   function->feedback_vector()->set_profiler_ticks(0);
     622             : 
     623             :   VMState<COMPILER> state(isolate);
     624             :   DCHECK(!isolate->has_pending_exception());
     625             :   PostponeInterruptsScope postpone(isolate);
     626             :   bool has_script = shared->script()->IsScript();
     627             :   // BUG(5946): This DCHECK is necessary to make certain that we won't
     628             :   // tolerate the lack of a script without bytecode.
     629             :   DCHECK_IMPLIES(!has_script, shared->HasBytecodeArray());
     630             :   std::unique_ptr<CompilationJob> job(
     631      457030 :       compiler::Pipeline::NewCompilationJob(function, has_script));
     632      457030 :   CompilationInfo* compilation_info = job->compilation_info();
     633      457030 :   ParseInfo* parse_info = job->parse_info();
     634             : 
     635             :   compilation_info->SetOptimizingForOsr(osr_offset, osr_frame);
     636             : 
     637             :   // Do not use TurboFan if we need to be able to set break points.
     638      457030 :   if (compilation_info->shared_info()->HasBreakInfo()) {
     639         674 :     compilation_info->AbortOptimization(kFunctionBeingDebugged);
     640         674 :     return MaybeHandle<Code>();
     641             :   }
     642             : 
     643             :   // Do not use TurboFan when %NeverOptimizeFunction was applied.
     644      456356 :   if (shared->optimization_disabled() &&
     645             :       shared->disable_optimization_reason() == kOptimizationDisabledForTest) {
     646          82 :     compilation_info->AbortOptimization(kOptimizationDisabledForTest);
     647          82 :     return MaybeHandle<Code>();
     648             :   }
     649             : 
     650             :   // Do not use TurboFan if optimization is disabled or function doesn't pass
     651             :   // turbo_filter.
     652      456274 :   if (!FLAG_opt || !shared->PassesFilter(FLAG_turbo_filter)) {
     653       17201 :     compilation_info->AbortOptimization(kOptimizationDisabled);
     654       17201 :     return MaybeHandle<Code>();
     655             :   }
     656             : 
     657             :   TimerEventScope<TimerEventOptimizeCode> optimize_code_timer(isolate);
     658      439073 :   RuntimeCallTimerScope runtimeTimer(isolate, &RuntimeCallStats::OptimizeCode);
     659     1317217 :   TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.OptimizeCode");
     660             : 
     661             :   // In case of concurrent recompilation, all handles below this point will be
     662             :   // allocated in a deferred handle scope that is detached and handed off to
     663             :   // the background thread when we return.
     664      439072 :   base::Optional<CompilationHandleScope> compilation;
     665      439072 :   if (mode == ConcurrencyMode::kConcurrent) {
     666        8605 :     compilation.emplace(compilation_info);
     667             :   }
     668             : 
     669             :   // All handles below will be canonicalized.
     670      878145 :   CanonicalHandleScope canonical(isolate);
     671             : 
     672             :   // Reopen handles in the new CompilationHandleScope.
     673      439073 :   compilation_info->ReopenHandlesInNewHandleScope();
     674      439074 :   parse_info->ReopenHandlesInNewHandleScope();
     675             : 
     676      439074 :   if (mode == ConcurrencyMode::kConcurrent) {
     677        8605 :     if (GetOptimizedCodeLater(job.get())) {
     678             :       job.release();  // The background recompile job owns this now.
     679             : 
     680             :       // Set the optimization marker and return a code object which checks it.
     681             :       function->SetOptimizationMarker(OptimizationMarker::kInOptimizationQueue);
     682        8605 :       if (function->IsInterpreted()) {
     683        8465 :         return BUILTIN_CODE(isolate, InterpreterEntryTrampoline);
     684             :       } else {
     685         140 :         return BUILTIN_CODE(isolate, CheckOptimizationMarker);
     686             :       }
     687             :     }
     688             :   } else {
     689      430469 :     if (GetOptimizedCodeNow(job.get())) return compilation_info->code();
     690             :   }
     691             : 
     692           9 :   if (isolate->has_pending_exception()) isolate->clear_pending_exception();
     693          10 :   return MaybeHandle<Code>();
     694             : }
     695             : 
     696       23365 : CompilationJob::Status FinalizeOptimizedCompilationJob(CompilationJob* job) {
     697        7802 :   CompilationInfo* compilation_info = job->compilation_info();
     698             :   Isolate* isolate = compilation_info->isolate();
     699             : 
     700             :   TimerEventScope<TimerEventRecompileSynchronous> timer(isolate);
     701             :   RuntimeCallTimerScope runtimeTimer(isolate,
     702        7802 :                                      &RuntimeCallStats::RecompileSynchronous);
     703       23406 :   TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"),
     704             :                "V8.RecompileSynchronous");
     705             : 
     706             :   Handle<SharedFunctionInfo> shared = compilation_info->shared_info();
     707             : 
     708             :   // Reset profiler ticks, function is no longer considered hot.
     709             :   compilation_info->closure()->feedback_vector()->set_profiler_ticks(0);
     710             : 
     711             :   DCHECK(!shared->HasBreakInfo());
     712             : 
     713             :   // 1) Optimization on the concurrent thread may have failed.
     714             :   // 2) The function may have already been optimized by OSR.  Simply continue.
     715             :   //    Except when OSR already disabled optimization for some reason.
     716             :   // 3) The code may have already been invalidated due to dependency change.
     717             :   // 4) Code generation may have failed.
     718        7802 :   if (job->state() == CompilationJob::State::kReadyToFinalize) {
     719        7802 :     if (shared->optimization_disabled()) {
     720             :       job->RetryOptimization(kOptimizationDisabled);
     721        7802 :     } else if (compilation_info->dependencies()->HasAborted()) {
     722             :       job->RetryOptimization(kBailedOutDueToDependencyChange);
     723        7761 :     } else if (job->FinalizeJob() == CompilationJob::SUCCEEDED) {
     724        7761 :       job->RecordOptimizedCompilationStats();
     725             :       RecordFunctionCompilation(CodeEventListener::LAZY_COMPILE_TAG,
     726        7761 :                                 job->parse_info()->script(), compilation_info);
     727        7761 :       InsertCodeIntoOptimizedCodeCache(compilation_info);
     728        7761 :       if (FLAG_trace_opt) {
     729           0 :         PrintF("[completed optimizing ");
     730           0 :         compilation_info->closure()->ShortPrint();
     731           0 :         PrintF("]\n");
     732             :       }
     733        7761 :       compilation_info->closure()->set_code(*compilation_info->code());
     734        7761 :       return CompilationJob::SUCCEEDED;
     735             :     }
     736             :   }
     737             : 
     738             :   DCHECK_EQ(job->state(), CompilationJob::State::kFailed);
     739          41 :   if (FLAG_trace_opt) {
     740           0 :     PrintF("[aborted optimizing ");
     741           0 :     compilation_info->closure()->ShortPrint();
     742             :     PrintF(" because: %s]\n",
     743           0 :            GetBailoutReason(compilation_info->bailout_reason()));
     744             :   }
     745          41 :   compilation_info->closure()->set_code(shared->code());
     746             :   // Clear the InOptimizationQueue marker, if it exists.
     747          41 :   if (compilation_info->closure()->IsInOptimizationQueue()) {
     748             :     compilation_info->closure()->ClearOptimizationMarker();
     749             :   }
     750             :   return CompilationJob::FAILED;
     751             : }
     752             : 
     753     3247302 : MaybeHandle<SharedFunctionInfo> CompileToplevel(ParseInfo* parse_info,
     754             :                                                 Isolate* isolate) {
     755             :   TimerEventScope<TimerEventCompileCode> top_level_timer(isolate);
     756     3354109 :   TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.CompileCode");
     757             :   PostponeInterruptsScope postpone(isolate);
     758             :   DCHECK(!isolate->native_context().is_null());
     759             :   RuntimeCallTimerScope runtimeTimer(
     760             :       isolate, parse_info->is_eval() ? &RuntimeCallStats::CompileEval
     761     1118037 :                                      : &RuntimeCallStats::CompileScript);
     762             : 
     763             :   Handle<Script> script = parse_info->script();
     764             :   Handle<SharedFunctionInfo> result;
     765             :   VMState<BYTECODE_COMPILER> state(isolate);
     766     2235976 :   if (parse_info->literal() == nullptr &&
     767     1117941 :       !parsing::ParseProgram(parse_info, isolate)) {
     768      106796 :     return MaybeHandle<SharedFunctionInfo>();
     769             :   }
     770             :   // Measure how long it takes to do the compilation; only take the
     771             :   // rest of the function into account to avoid overlap with the
     772             :   // parsing statistics.
     773             :   HistogramTimer* rate = parse_info->is_eval()
     774             :                              ? isolate->counters()->compile_eval()
     775     2022478 :                              : isolate->counters()->compile();
     776             :   HistogramTimerScope timer(rate);
     777     3033723 :   TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"),
     778             :                parse_info->is_eval() ? "V8.CompileEval" : "V8.Compile");
     779             : 
     780             :   // Generate the unoptimized bytecode or asm-js data.
     781             :   std::forward_list<std::unique_ptr<CompilationJob>> inner_function_jobs;
     782             :   std::unique_ptr<CompilationJob> outer_function_job(
     783     1011241 :       GenerateUnoptimizedCode(parse_info, isolate, &inner_function_jobs));
     784     1011238 :   if (!outer_function_job) {
     785          10 :     if (!isolate->has_pending_exception()) isolate->StackOverflow();
     786          10 :     return MaybeHandle<SharedFunctionInfo>();
     787             :   }
     788             : 
     789             :   // Internalize ast values onto the heap.
     790     1011228 :   parse_info->ast_value_factory()->Internalize(isolate);
     791             : 
     792             :   // Create shared function infos for top level and shared function infos array
     793             :   // for inner functions.
     794     1011229 :   EnsureSharedFunctionInfosArrayOnScript(parse_info, isolate);
     795             :   DCHECK_EQ(kNoSourcePosition,
     796             :             parse_info->literal()->function_token_position());
     797             :   Handle<SharedFunctionInfo> shared_info =
     798             :       isolate->factory()->NewSharedFunctionInfoForLiteral(parse_info->literal(),
     799     1011231 :                                                           parse_info->script());
     800             :   shared_info->set_is_toplevel(true);
     801             : 
     802             :   // Finalize compilation of the unoptimized bytecode or asm-js data.
     803     1011231 :   if (!FinalizeUnoptimizedCode(parse_info, isolate, shared_info,
     804             :                                outer_function_job.get(),
     805     1011231 :                                &inner_function_jobs)) {
     806           0 :     if (!isolate->has_pending_exception()) isolate->StackOverflow();
     807           0 :     return MaybeHandle<SharedFunctionInfo>();
     808             :   }
     809             : 
     810     1011231 :   if (!script.is_null()) {
     811     1011231 :     script->set_compilation_state(Script::COMPILATION_STATE_COMPILED);
     812             :   }
     813             : 
     814     1011231 :   return shared_info;
     815             : }
     816             : 
     817         485 : bool FailWithPendingException(Isolate* isolate,
     818             :                               Compiler::ClearExceptionFlag flag) {
     819         485 :   if (flag == Compiler::CLEAR_EXCEPTION) {
     820             :     isolate->clear_pending_exception();
     821         470 :   } else if (!isolate->has_pending_exception()) {
     822          30 :     isolate->StackOverflow();
     823             :   }
     824         485 :   return false;
     825             : }
     826             : 
     827             : }  // namespace
     828             : 
     829             : // ----------------------------------------------------------------------------
     830             : // Implementation of Compiler
     831             : 
     832     1629929 : bool Compiler::Analyze(ParseInfo* parse_info,
     833             :                        EagerInnerFunctionLiterals* eager_literals) {
     834             :   DCHECK_NOT_NULL(parse_info->literal());
     835             :   RuntimeCallTimerScope runtimeTimer(parse_info->runtime_call_stats(),
     836     1629929 :                                      &RuntimeCallStats::CompileAnalyse);
     837     1629929 :   if (!Rewriter::Rewrite(parse_info)) return false;
     838     1629931 :   DeclarationScope::Analyze(parse_info);
     839     1629930 :   if (!Renumber(parse_info, eager_literals)) return false;
     840     1629900 :   return true;
     841             : }
     842             : 
     843           0 : bool Compiler::ParseAndAnalyze(ParseInfo* parse_info,
     844             :                                Handle<SharedFunctionInfo> shared_info,
     845             :                                Isolate* isolate) {
     846           0 :   if (!parsing::ParseAny(parse_info, shared_info, isolate)) {
     847             :     return false;
     848             :   }
     849           0 :   return Compiler::Analyze(parse_info);
     850             : }
     851             : 
     852      576607 : bool Compiler::Compile(Handle<SharedFunctionInfo> shared_info,
     853             :                        ClearExceptionFlag flag) {
     854             :   // We should never reach here if the function is already compiled.
     855             :   DCHECK(!shared_info->is_compiled());
     856             : 
     857      576607 :   Isolate* isolate = shared_info->GetIsolate();
     858             :   DCHECK(!isolate->has_pending_exception());
     859             :   DCHECK(!shared_info->HasBytecodeArray());
     860             :   VMState<BYTECODE_COMPILER> state(isolate);
     861             :   PostponeInterruptsScope postpone(isolate);
     862             :   TimerEventScope<TimerEventCompileCode> compile_timer(isolate);
     863             :   RuntimeCallTimerScope runtimeTimer(isolate,
     864      576607 :                                      &RuntimeCallStats::CompileFunction);
     865     1729821 :   TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.CompileCode");
     866     1153214 :   AggregatedHistogramTimerScope timer(isolate->counters()->compile_lazy());
     867             : 
     868             :   // Check if the compiler dispatcher has shared_info enqueued for compile.
     869             :   CompilerDispatcher* dispatcher = isolate->compiler_dispatcher();
     870      576607 :   if (dispatcher->IsEnqueued(shared_info)) {
     871           3 :     if (!dispatcher->FinishNow(shared_info)) {
     872           0 :       return FailWithPendingException(isolate, flag);
     873             :     }
     874             :     return true;
     875             :   }
     876             : 
     877             :   // Set up parse info.
     878     1153208 :   ParseInfo parse_info(shared_info);
     879             :   parse_info.set_lazy_compile();
     880      576604 :   if (FLAG_preparser_scope_analysis) {
     881      576604 :     if (shared_info->HasPreParsedScopeData()) {
     882             :       Handle<PreParsedScopeData> data(
     883             :           PreParsedScopeData::cast(shared_info->preparsed_scope_data()));
     884       19142 :       parse_info.consumed_preparsed_scope_data()->SetData(data);
     885             :       // After we've compiled the function, we don't need data about its
     886             :       // skippable functions any more.
     887       38284 :       shared_info->set_preparsed_scope_data(isolate->heap()->null_value());
     888             :     }
     889             :   }
     890             : 
     891             :   // Parse and update ParseInfo with the results.
     892      576604 :   if (!parsing::ParseFunction(&parse_info, shared_info, isolate)) {
     893         455 :     return FailWithPendingException(isolate, flag);
     894             :   }
     895             : 
     896             :   // Generate the unoptimized bytecode or asm-js data.
     897             :   std::forward_list<std::unique_ptr<CompilationJob>> inner_function_jobs;
     898             :   std::unique_ptr<CompilationJob> outer_function_job(
     899      576147 :       GenerateUnoptimizedCode(&parse_info, isolate, &inner_function_jobs));
     900      576148 :   if (!outer_function_job) {
     901          30 :     return FailWithPendingException(isolate, flag);
     902             :   }
     903             : 
     904             :   // Internalize ast values onto the heap.
     905      576118 :   parse_info.ast_value_factory()->Internalize(isolate);
     906             : 
     907             :   // Finalize compilation of the unoptimized bytecode or asm-js data.
     908      576119 :   if (!FinalizeUnoptimizedCode(&parse_info, isolate, shared_info,
     909             :                                outer_function_job.get(),
     910      576119 :                                &inner_function_jobs)) {
     911           0 :     return FailWithPendingException(isolate, flag);
     912             :   }
     913             : 
     914             :   DCHECK(!isolate->has_pending_exception());
     915             :   return true;
     916             : }
     917             : 
     918      717628 : bool Compiler::Compile(Handle<JSFunction> function, ClearExceptionFlag flag) {
     919             :   // We should never reach here if the function is already compiled or optimized
     920             :   DCHECK(!function->is_compiled());
     921             :   DCHECK(!function->IsOptimized());
     922             :   DCHECK(!function->HasOptimizationMarker());
     923             :   DCHECK(!function->HasOptimizedCode());
     924             : 
     925             :   Isolate* isolate = function->GetIsolate();
     926             :   Handle<SharedFunctionInfo> shared_info = handle(function->shared());
     927             :   DCHECK(AllowCompilation::IsAllowed(isolate));
     928             : 
     929             :   // Ensure shared function info is compiled.
     930      717628 :   if (!shared_info->is_compiled() && !Compile(shared_info, flag)) return false;
     931             :   Handle<Code> code = handle(shared_info->code(), isolate);
     932             : 
     933             :   // Allocate literals for the JSFunction.
     934      717148 :   JSFunction::EnsureLiterals(function);
     935             : 
     936             :   // Optimize now if --always-opt is enabled.
     937      867304 :   if (FLAG_always_opt && !function->shared()->HasAsmWasmData()) {
     938      149741 :     if (FLAG_trace_opt) {
     939           0 :       PrintF("[optimizing ");
     940           0 :       function->ShortPrint();
     941           0 :       PrintF(" because --always-opt]\n");
     942             :     }
     943             :     Handle<Code> opt_code;
     944      149740 :     if (GetOptimizedCode(function, ConcurrencyMode::kNotConcurrent)
     945      299481 :             .ToHandle(&opt_code)) {
     946             :       code = opt_code;
     947             :     }
     948             :   }
     949             : 
     950             :   // Install code on closure.
     951      717147 :   function->set_code(*code);
     952             : 
     953             :   // Check postconditions on success.
     954             :   DCHECK(!isolate->has_pending_exception());
     955             :   DCHECK(function->shared()->is_compiled());
     956             :   DCHECK(function->is_compiled());
     957      717148 :   return true;
     958             : }
     959             : 
     960      301254 : bool Compiler::CompileOptimized(Handle<JSFunction> function,
     961             :                                 ConcurrencyMode mode) {
     962      301254 :   if (function->IsOptimized()) return true;
     963             :   Isolate* isolate = function->GetIsolate();
     964             :   DCHECK(AllowCompilation::IsAllowed(isolate));
     965             : 
     966             :   // Start a compilation.
     967             :   Handle<Code> code;
     968      602507 :   if (!GetOptimizedCode(function, mode).ToHandle(&code)) {
     969             :     // Optimization failed, get unoptimized code. Unoptimized code must exist
     970             :     // already if we are optimizing.
     971             :     DCHECK(!isolate->has_pending_exception());
     972             :     DCHECK(function->shared()->is_compiled());
     973             :     code = handle(function->shared()->code(), isolate);
     974             :   }
     975             : 
     976             :   // Install code on closure.
     977      301253 :   function->set_code(*code);
     978             : 
     979             :   // Check postconditions on success.
     980             :   DCHECK(!isolate->has_pending_exception());
     981             :   DCHECK(function->shared()->is_compiled());
     982             :   DCHECK(function->is_compiled());
     983             :   DCHECK_IMPLIES(function->HasOptimizationMarker(),
     984             :                  function->IsInOptimizationQueue());
     985             :   DCHECK_IMPLIES(function->HasOptimizationMarker(),
     986             :                  function->ChecksOptimizationMarker());
     987             :   DCHECK_IMPLIES(function->IsInOptimizationQueue(),
     988             :                  mode == ConcurrencyMode::kConcurrent);
     989      301254 :   return true;
     990             : }
     991             : 
     992        1156 : MaybeHandle<JSArray> Compiler::CompileForLiveEdit(Handle<Script> script) {
     993             :   Isolate* isolate = script->GetIsolate();
     994             :   DCHECK(AllowCompilation::IsAllowed(isolate));
     995             : 
     996             :   // In order to ensure that live edit function info collection finds the newly
     997             :   // generated shared function infos, clear the script's list temporarily
     998             :   // and restore it at the end of this method.
     999             :   Handle<FixedArray> old_function_infos(script->shared_function_infos(),
    1000             :                                         isolate);
    1001        2312 :   script->set_shared_function_infos(isolate->heap()->empty_fixed_array());
    1002             : 
    1003             :   // Start a compilation.
    1004        1156 :   ParseInfo parse_info(script);
    1005             :   parse_info.set_eager();
    1006             : 
    1007             :   // TODO(635): support extensions.
    1008             :   Handle<JSArray> infos;
    1009             :   Handle<SharedFunctionInfo> shared_info;
    1010        2312 :   if (CompileToplevel(&parse_info, isolate).ToHandle(&shared_info)) {
    1011             :     // Check postconditions on success.
    1012             :     DCHECK(!isolate->has_pending_exception());
    1013             :     infos = LiveEditFunctionTracker::Collect(parse_info.literal(), script,
    1014        1137 :                                              parse_info.zone(), isolate);
    1015             :   }
    1016             : 
    1017             :   // Restore the original function info list in order to remain side-effect
    1018             :   // free as much as possible, since some code expects the old shared function
    1019             :   // infos to stick around.
    1020        1156 :   script->set_shared_function_infos(*old_function_infos);
    1021             : 
    1022        1156 :   return infos;
    1023             : }
    1024             : 
    1025     3647841 : MaybeHandle<JSFunction> Compiler::GetFunctionFromEval(
    1026             :     Handle<String> source, Handle<SharedFunctionInfo> outer_info,
    1027             :     Handle<Context> context, LanguageMode language_mode,
    1028             :     ParseRestriction restriction, int parameters_end_pos,
    1029             :     int eval_scope_position, int eval_position, int line_offset,
    1030             :     int column_offset, Handle<Object> script_name,
    1031             :     ScriptOriginOptions options) {
    1032     7190419 :   Isolate* isolate = source->GetIsolate();
    1033             :   int source_length = source->length();
    1034     3647841 :   isolate->counters()->total_eval_size()->Increment(source_length);
    1035     3647841 :   isolate->counters()->total_compile_size()->Increment(source_length);
    1036             : 
    1037             :   // The cache lookup key needs to be aware of the separation between the
    1038             :   // parameters and the body to prevent this valid invocation:
    1039             :   //   Function("", "function anonymous(\n/**/) {\n}");
    1040             :   // from adding an entry that falsely approves this invalid invocation:
    1041             :   //   Function("\n/**/) {\nfunction anonymous(", "}");
    1042             :   // The actual eval_scope_position for indirect eval and CreateDynamicFunction
    1043             :   // is unused (just 0), which means it's an available field to use to indicate
    1044             :   // this separation. But to make sure we're not causing other false hits, we
    1045             :   // negate the scope position.
    1046             :   int position = eval_scope_position;
    1047     3647841 :   if (FLAG_harmony_function_tostring &&
    1048       16454 :       restriction == ONLY_SINGLE_FUNCTION_LITERAL &&
    1049        8227 :       parameters_end_pos != kNoSourcePosition) {
    1050             :     // use the parameters_end_pos as the eval_scope_position in the eval cache.
    1051             :     DCHECK_EQ(eval_scope_position, 0);
    1052        5495 :     position = -parameters_end_pos;
    1053             :   }
    1054             :   CompilationCache* compilation_cache = isolate->compilation_cache();
    1055             :   InfoVectorPair eval_result = compilation_cache->LookupEval(
    1056     3647841 :       source, outer_info, context, language_mode, position);
    1057             :   Handle<Cell> vector;
    1058     3647841 :   if (eval_result.has_vector()) {
    1059     2313581 :     vector = Handle<Cell>(eval_result.vector(), isolate);
    1060             :   }
    1061             : 
    1062             :   Handle<SharedFunctionInfo> shared_info;
    1063             :   Handle<Script> script;
    1064     3647841 :   if (eval_result.has_shared()) {
    1065             :     shared_info = Handle<SharedFunctionInfo>(eval_result.shared(), isolate);
    1066             :     script = Handle<Script>(Script::cast(shared_info->script()), isolate);
    1067             :   } else {
    1068      971748 :     script = isolate->factory()->NewScript(source);
    1069      971748 :     if (isolate->NeedsSourcePositionsForProfiling()) {
    1070       14009 :       Script::InitLineEnds(script);
    1071             :     }
    1072      971748 :     if (!script_name.is_null()) {
    1073          18 :       script->set_name(*script_name);
    1074             :       script->set_line_offset(line_offset);
    1075             :       script->set_column_offset(column_offset);
    1076             :     }
    1077      971748 :     script->set_origin_options(options);
    1078      971748 :     script->set_compilation_type(Script::COMPILATION_TYPE_EVAL);
    1079             : 
    1080      971748 :     script->set_eval_from_shared(*outer_info);
    1081      971748 :     if (eval_position == kNoSourcePosition) {
    1082             :       // If the position is missing, attempt to get the code offset by
    1083             :       // walking the stack. Do not translate the code offset into source
    1084             :       // position, but store it as negative value for lazy translation.
    1085      373277 :       StackTraceFrameIterator it(script->GetIsolate());
    1086      746488 :       if (!it.done() && it.is_javascript()) {
    1087      373211 :         FrameSummary summary = FrameSummary::GetTop(it.javascript_frame());
    1088             :         script->set_eval_from_shared(
    1089      373211 :             summary.AsJavaScript().function()->shared());
    1090      373211 :         eval_position = -summary.code_offset();
    1091             :       } else {
    1092             :         eval_position = 0;
    1093             :       }
    1094             :     }
    1095             :     script->set_eval_from_position(eval_position);
    1096             : 
    1097      971748 :     ParseInfo parse_info(script);
    1098             :     parse_info.set_eval();
    1099             :     parse_info.set_language_mode(language_mode);
    1100             :     parse_info.set_parse_restriction(restriction);
    1101             :     parse_info.set_parameters_end_pos(parameters_end_pos);
    1102      971748 :     if (!context->IsNativeContext()) {
    1103      563575 :       parse_info.set_outer_scope_info(handle(context->scope_info()));
    1104             :     }
    1105             : 
    1106     1943496 :     if (!CompileToplevel(&parse_info, isolate).ToHandle(&shared_info)) {
    1107      105263 :       return MaybeHandle<JSFunction>();
    1108      866485 :     }
    1109             :   }
    1110             : 
    1111             :   // If caller is strict mode, the result must be in strict mode as well.
    1112             :   DCHECK(is_sloppy(language_mode) || is_strict(shared_info->language_mode()));
    1113             : 
    1114             :   Handle<JSFunction> result;
    1115     3542578 :   if (eval_result.has_shared()) {
    1116     2676093 :     if (eval_result.has_vector()) {
    1117             :       result = isolate->factory()->NewFunctionFromSharedFunctionInfo(
    1118     2313581 :           shared_info, context, vector, NOT_TENURED);
    1119             :     } else {
    1120             :       result = isolate->factory()->NewFunctionFromSharedFunctionInfo(
    1121      362512 :           shared_info, context, NOT_TENURED);
    1122      362512 :       JSFunction::EnsureLiterals(result);
    1123             :       // Make sure to cache this result.
    1124             :       Handle<Cell> new_vector(result->feedback_vector_cell(), isolate);
    1125             :       compilation_cache->PutEval(source, outer_info, context, shared_info,
    1126      362512 :                                  new_vector, eval_scope_position);
    1127             :     }
    1128             :   } else {
    1129             :     result = isolate->factory()->NewFunctionFromSharedFunctionInfo(
    1130      866485 :         shared_info, context, NOT_TENURED);
    1131      866485 :     JSFunction::EnsureLiterals(result);
    1132             :     // Add the SharedFunctionInfo and the LiteralsArray to the eval cache if
    1133             :     // we didn't retrieve from there.
    1134             :     Handle<Cell> vector(result->feedback_vector_cell(), isolate);
    1135             :     compilation_cache->PutEval(source, outer_info, context, shared_info, vector,
    1136      866485 :                                eval_scope_position);
    1137             :   }
    1138             : 
    1139             :   // OnAfterCompile has to be called after we create the JSFunction, which we
    1140             :   // may require to recompile the eval for debugging, if we find a function
    1141             :   // that contains break points in the eval script.
    1142     3542578 :   isolate->debug()->OnAfterCompile(script);
    1143             : 
    1144     3542578 :   return result;
    1145             : }
    1146             : 
    1147             : namespace {
    1148             : 
    1149         310 : bool ContainsAsmModule(Handle<Script> script) {
    1150             :   DisallowHeapAllocation no_gc;
    1151         310 :   SharedFunctionInfo::ScriptIterator iter(script);
    1152        7113 :   while (SharedFunctionInfo* info = iter.Next()) {
    1153        6813 :     if (info->HasAsmWasmData()) return true;
    1154             :   }
    1155             :   return false;
    1156             : }
    1157             : 
    1158             : bool ShouldProduceCodeCache(ScriptCompiler::CompileOptions options) {
    1159      237196 :   return options == ScriptCompiler::kProduceCodeCache ||
    1160             :          options == ScriptCompiler::kProduceFullCodeCache;
    1161             : }
    1162             : 
    1163             : }  // namespace
    1164             : 
    1165          64 : bool Compiler::CodeGenerationFromStringsAllowed(Isolate* isolate,
    1166             :                                                 Handle<Context> context,
    1167             :                                                 Handle<String> source) {
    1168             :   DCHECK(context->allow_code_gen_from_strings()->IsFalse(isolate));
    1169             :   // Check with callback if set.
    1170             :   AllowCodeGenerationFromStringsCallback callback =
    1171             :       isolate->allow_code_gen_callback();
    1172          64 :   if (callback == nullptr) {
    1173             :     // No callback set and code generation disallowed.
    1174             :     return false;
    1175             :   } else {
    1176             :     // Callback set. Let it decide if code generation is allowed.
    1177          46 :     VMState<EXTERNAL> state(isolate);
    1178          46 :     return callback(v8::Utils::ToLocal(context), v8::Utils::ToLocal(source));
    1179             :   }
    1180             : }
    1181             : 
    1182     1198425 : MaybeHandle<JSFunction> Compiler::GetFunctionFromString(
    1183             :     Handle<Context> context, Handle<String> source,
    1184             :     ParseRestriction restriction, int parameters_end_pos) {
    1185             :   Isolate* const isolate = context->GetIsolate();
    1186             :   Handle<Context> native_context(context->native_context(), isolate);
    1187             : 
    1188             :   // Check if native context allows code generation from
    1189             :   // strings. Throw an exception if it doesn't.
    1190     1198461 :   if (native_context->allow_code_gen_from_strings()->IsFalse(isolate) &&
    1191          36 :       !CodeGenerationFromStringsAllowed(isolate, native_context, source)) {
    1192             :     Handle<Object> error_message =
    1193          24 :         native_context->ErrorMessageForCodeGenerationFromStrings();
    1194          48 :     THROW_NEW_ERROR(isolate, NewEvalError(MessageTemplate::kCodeGenFromStrings,
    1195             :                                           error_message),
    1196             :                     JSFunction);
    1197             :   }
    1198             : 
    1199             :   // Compile source string in the native context.
    1200             :   int eval_scope_position = 0;
    1201             :   int eval_position = kNoSourcePosition;
    1202             :   Handle<SharedFunctionInfo> outer_info(native_context->closure()->shared());
    1203             :   return Compiler::GetFunctionFromEval(
    1204             :       source, outer_info, native_context, LanguageMode::kSloppy, restriction,
    1205     1198401 :       parameters_end_pos, eval_scope_position, eval_position);
    1206             : }
    1207             : 
    1208      236715 : MaybeHandle<SharedFunctionInfo> Compiler::GetSharedFunctionInfoForScript(
    1209             :     Handle<String> source, MaybeHandle<Object> maybe_script_name,
    1210             :     int line_offset, int column_offset, ScriptOriginOptions resource_options,
    1211             :     MaybeHandle<Object> maybe_source_map_url, Handle<Context> context,
    1212             :     v8::Extension* extension, ScriptData** cached_data,
    1213             :     ScriptCompiler::CompileOptions compile_options, NativesFlag natives,
    1214             :     MaybeHandle<FixedArray> maybe_host_defined_options) {
    1215      525722 :   Isolate* isolate = source->GetIsolate();
    1216      236715 :   if (compile_options == ScriptCompiler::kNoCompileOptions) {
    1217             :     cached_data = nullptr;
    1218         785 :   } else if (compile_options == ScriptCompiler::kProduceParserCache ||
    1219             :              ShouldProduceCodeCache(compile_options)) {
    1220             :     DCHECK(cached_data && !*cached_data);
    1221             :     DCHECK_NULL(extension);
    1222             :     DCHECK(!isolate->debug()->is_loaded());
    1223             :   } else {
    1224             :     DCHECK(compile_options == ScriptCompiler::kConsumeParserCache ||
    1225             :            compile_options == ScriptCompiler::kConsumeCodeCache);
    1226             :     DCHECK(cached_data && *cached_data);
    1227             :     DCHECK_NULL(extension);
    1228             :   }
    1229             :   int source_length = source->length();
    1230      236715 :   isolate->counters()->total_load_size()->Increment(source_length);
    1231      236716 :   isolate->counters()->total_compile_size()->Increment(source_length);
    1232             : 
    1233      236716 :   LanguageMode language_mode = construct_language_mode(FLAG_use_strict);
    1234             :   CompilationCache* compilation_cache = isolate->compilation_cache();
    1235             : 
    1236             :   // Do a lookup in the compilation cache but not for extensions.
    1237             :   MaybeHandle<SharedFunctionInfo> maybe_result;
    1238             :   Handle<Cell> vector;
    1239      236716 :   if (extension == nullptr) {
    1240             :     // First check per-isolate compilation cache.
    1241             :     InfoVectorPair pair = compilation_cache->LookupScript(
    1242             :         source, maybe_script_name, line_offset, column_offset, resource_options,
    1243      233578 :         context, language_mode);
    1244      375698 :     if (!pair.has_shared() &&
    1245      233813 :         compile_options == ScriptCompiler::kConsumeCodeCache &&
    1246             :         !isolate->debug()->is_loaded()) {
    1247             :       // Then check cached code provided by embedder.
    1248         235 :       HistogramTimerScope timer(isolate->counters()->compile_deserialize());
    1249             :       RuntimeCallTimerScope runtimeTimer(isolate,
    1250         235 :                                          &RuntimeCallStats::CompileDeserialize);
    1251         485 :       TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"),
    1252             :                    "V8.CompileDeserialize");
    1253             :       Handle<SharedFunctionInfo> inner_result;
    1254         470 :       if (CodeSerializer::Deserialize(isolate, *cached_data, source)
    1255         470 :               .ToHandle(&inner_result)) {
    1256             :         // Promote to per-isolate compilation cache.
    1257             :         DCHECK(inner_result->is_compiled());
    1258             :         Handle<FeedbackVector> feedback_vector =
    1259         220 :             FeedbackVector::New(isolate, inner_result);
    1260         220 :         vector = isolate->factory()->NewCell(feedback_vector);
    1261             :         compilation_cache->PutScript(source, context, language_mode,
    1262         220 :                                      inner_result, vector);
    1263             :         Handle<Script> script(Script::cast(inner_result->script()), isolate);
    1264         220 :         isolate->debug()->OnAfterCompile(script);
    1265         220 :         return inner_result;
    1266             :       }
    1267             :       // Deserializer failed. Fall through to compile.
    1268             :     } else {
    1269      233343 :       if (pair.has_shared()) {
    1270             :         maybe_result = MaybeHandle<SharedFunctionInfo>(pair.shared(), isolate);
    1271             :       }
    1272      233343 :       if (pair.has_vector()) {
    1273             :         vector = Handle<Cell>(pair.vector(), isolate);
    1274             :       }
    1275             :     }
    1276             :   }
    1277             : 
    1278             :   base::ElapsedTimer timer;
    1279      236496 :   if (FLAG_profile_deserialization && ShouldProduceCodeCache(compile_options)) {
    1280             :     timer.Start();
    1281             :   }
    1282             : 
    1283      327954 :   if (maybe_result.is_null() || ShouldProduceCodeCache(compile_options)) {
    1284             :     // No cache entry found, or embedder wants a code cache. Compile the script.
    1285             : 
    1286             :     // Create a script object describing the script to be compiled.
    1287      145038 :     Handle<Script> script = isolate->factory()->NewScript(source);
    1288      145038 :     if (isolate->NeedsSourcePositionsForProfiling()) {
    1289       10229 :       Script::InitLineEnds(script);
    1290             :     }
    1291      145038 :     if (natives == NATIVES_CODE) {
    1292             :       script->set_type(Script::TYPE_NATIVE);
    1293      132711 :     } else if (natives == EXTENSION_CODE) {
    1294             :       script->set_type(Script::TYPE_EXTENSION);
    1295      129507 :     } else if (natives == INSPECTOR_CODE) {
    1296             :       script->set_type(Script::TYPE_INSPECTOR);
    1297             :     }
    1298             :     Handle<Object> script_name;
    1299      145038 :     if (maybe_script_name.ToHandle(&script_name)) {
    1300       93675 :       script->set_name(*script_name);
    1301             :       script->set_line_offset(line_offset);
    1302             :       script->set_column_offset(column_offset);
    1303             :     }
    1304      145038 :     script->set_origin_options(resource_options);
    1305             :     Handle<Object> source_map_url;
    1306      145038 :     if (maybe_source_map_url.ToHandle(&source_map_url)) {
    1307        5591 :       script->set_source_mapping_url(*source_map_url);
    1308             :     }
    1309             :     Handle<FixedArray> host_defined_options;
    1310      145038 :     if (maybe_host_defined_options.ToHandle(&host_defined_options)) {
    1311      126256 :       script->set_host_defined_options(*host_defined_options);
    1312             :     }
    1313             : 
    1314             :     // Compile the function and add it to the cache.
    1315      145038 :     ParseInfo parse_info(script);
    1316      290075 :     Zone compile_zone(isolate->allocator(), ZONE_NAME);
    1317      145038 :     if (resource_options.IsModule()) parse_info.set_module();
    1318      145038 :     if (compile_options != ScriptCompiler::kNoCompileOptions) {
    1319             :       parse_info.set_cached_data(cached_data);
    1320             :     }
    1321             :     parse_info.set_compile_options(compile_options);
    1322             :     parse_info.set_extension(extension);
    1323      145038 :     if (!context->IsNativeContext()) {
    1324           0 :       parse_info.set_outer_scope_info(handle(context->scope_info()));
    1325             :     }
    1326      145038 :     if (ShouldProduceCodeCache(compile_options)) {
    1327             :       parse_info.set_will_serialize();
    1328             :       parse_info.set_eager(compile_options ==
    1329             :                            ScriptCompiler::kProduceFullCodeCache);
    1330             :     }
    1331             : 
    1332             :     parse_info.set_language_mode(
    1333             :         stricter_language_mode(parse_info.language_mode(), language_mode));
    1334      145038 :     maybe_result = CompileToplevel(&parse_info, isolate);
    1335             :     Handle<SharedFunctionInfo> result;
    1336      286938 :     if (extension == nullptr && maybe_result.ToHandle(&result)) {
    1337             :       // We need a feedback vector.
    1338             :       DCHECK(result->is_compiled());
    1339             :       Handle<FeedbackVector> feedback_vector =
    1340      140406 :           FeedbackVector::New(isolate, result);
    1341      140406 :       vector = isolate->factory()->NewCell(feedback_vector);
    1342             :       compilation_cache->PutScript(source, context, language_mode, result,
    1343      140406 :                                    vector);
    1344      140716 :       if (ShouldProduceCodeCache(compile_options) &&
    1345         310 :           !ContainsAsmModule(script)) {
    1346             :         HistogramTimerScope histogram_timer(
    1347         300 :             isolate->counters()->compile_serialize());
    1348             :         RuntimeCallTimerScope runtimeTimer(isolate,
    1349         300 :                                            &RuntimeCallStats::CompileSerialize);
    1350         900 :         TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"),
    1351             :                      "V8.CompileSerialize");
    1352         300 :         *cached_data = CodeSerializer::Serialize(isolate, result, source);
    1353         300 :         if (FLAG_profile_deserialization) {
    1354             :           PrintF("[Compiling and serializing took %0.3f ms]\n",
    1355           0 :                  timer.Elapsed().InMillisecondsF());
    1356             :         }
    1357             :       }
    1358             :     }
    1359             : 
    1360      145038 :     if (maybe_result.is_null()) {
    1361        1524 :       if (natives != EXTENSION_CODE && natives != NATIVES_CODE) {
    1362        1494 :         isolate->ReportPendingMessages();
    1363             :       }
    1364             :     } else {
    1365      143514 :       isolate->debug()->OnAfterCompile(script);
    1366      145038 :     }
    1367             :   }
    1368      236496 :   return maybe_result;
    1369             : }
    1370             : 
    1371          95 : Handle<SharedFunctionInfo> Compiler::GetSharedFunctionInfoForStreamedScript(
    1372             :     Handle<Script> script, ParseInfo* parse_info, int source_length) {
    1373          95 :   Isolate* isolate = script->GetIsolate();
    1374             :   // TODO(titzer): increment the counters in caller.
    1375          95 :   isolate->counters()->total_load_size()->Increment(source_length);
    1376          95 :   isolate->counters()->total_compile_size()->Increment(source_length);
    1377             : 
    1378          95 :   LanguageMode language_mode = construct_language_mode(FLAG_use_strict);
    1379             :   parse_info->set_language_mode(
    1380             :       stricter_language_mode(parse_info->language_mode(), language_mode));
    1381             : 
    1382             :   Handle<SharedFunctionInfo> result;
    1383         190 :   if (CompileToplevel(parse_info, isolate).ToHandle(&result)) {
    1384          95 :     isolate->debug()->OnAfterCompile(script);
    1385             :   }
    1386          95 :   return result;
    1387             : }
    1388             : 
    1389     4704561 : Handle<SharedFunctionInfo> Compiler::GetSharedFunctionInfo(
    1390     4155760 :     FunctionLiteral* literal, Handle<Script> script, Isolate* isolate) {
    1391             :   // Precondition: code has been parsed and scopes have been analyzed.
    1392             :   MaybeHandle<SharedFunctionInfo> maybe_existing;
    1393             : 
    1394             :   // Find any previously allocated shared function info for the given literal.
    1395     4704561 :   maybe_existing = script->FindSharedFunctionInfo(isolate, literal);
    1396             : 
    1397             :   // If we found an existing shared function info, return it.
    1398             :   Handle<SharedFunctionInfo> existing;
    1399     4704561 :   if (maybe_existing.ToHandle(&existing)) {
    1400             :     DCHECK(!existing->is_toplevel());
    1401      548801 :     return existing;
    1402             :   }
    1403             : 
    1404             :   // Allocate a shared function info object which will be compiled lazily.
    1405             :   Handle<SharedFunctionInfo> result =
    1406     4155760 :       isolate->factory()->NewSharedFunctionInfoForLiteral(literal, script);
    1407             :   result->set_is_toplevel(false);
    1408     4155760 :   Scope* outer_scope = literal->scope()->GetOuterScopeWithContext();
    1409     4155760 :   if (outer_scope) {
    1410     3754634 :     result->set_outer_scope_info(*outer_scope->scope_info());
    1411             :   }
    1412     4155760 :   return result;
    1413             : }
    1414             : 
    1415        1678 : Handle<SharedFunctionInfo> Compiler::GetSharedFunctionInfoForNative(
    1416             :     v8::Extension* extension, Handle<String> name) {
    1417             :   Isolate* isolate = name->GetIsolate();
    1418             :   v8::Isolate* v8_isolate = reinterpret_cast<v8::Isolate*>(isolate);
    1419             : 
    1420             :   // Compute the function template for the native function.
    1421             :   v8::Local<v8::FunctionTemplate> fun_template =
    1422             :       extension->GetNativeFunctionTemplate(v8_isolate,
    1423        1678 :                                            v8::Utils::ToLocal(name));
    1424             :   DCHECK(!fun_template.IsEmpty());
    1425             : 
    1426             :   // Instantiate the function and create a shared function info from it.
    1427             :   Handle<JSFunction> fun = Handle<JSFunction>::cast(Utils::OpenHandle(
    1428        1678 :       *fun_template->GetFunction(v8_isolate->GetCurrentContext())
    1429        1678 :            .ToLocalChecked()));
    1430             :   Handle<Code> code = Handle<Code>(fun->shared()->code());
    1431             :   Handle<Code> construct_stub = Handle<Code>(fun->shared()->construct_stub());
    1432             :   Handle<SharedFunctionInfo> shared = isolate->factory()->NewSharedFunctionInfo(
    1433             :       name, FunctionKind::kNormalFunction, code,
    1434        1678 :       Handle<ScopeInfo>(fun->shared()->scope_info()));
    1435        1678 :   shared->set_outer_scope_info(fun->shared()->outer_scope_info());
    1436        1678 :   shared->SetConstructStub(*construct_stub);
    1437        1678 :   shared->set_feedback_metadata(fun->shared()->feedback_metadata());
    1438             : 
    1439             :   // Copy the function data to the shared function info.
    1440        1678 :   shared->set_function_data(fun->shared()->function_data());
    1441             :   int parameters = fun->shared()->internal_formal_parameter_count();
    1442             :   shared->set_internal_formal_parameter_count(parameters);
    1443             : 
    1444        1678 :   return shared;
    1445             : }
    1446             : 
    1447        6036 : MaybeHandle<Code> Compiler::GetOptimizedCodeForOSR(Handle<JSFunction> function,
    1448             :                                                    BailoutId osr_offset,
    1449             :                                                    JavaScriptFrame* osr_frame) {
    1450             :   DCHECK(!osr_offset.IsNone());
    1451             :   DCHECK_NOT_NULL(osr_frame);
    1452             :   return GetOptimizedCode(function, ConcurrencyMode::kNotConcurrent, osr_offset,
    1453        6036 :                           osr_frame);
    1454             : }
    1455             : 
    1456          25 : CompilationJob* Compiler::PrepareUnoptimizedCompilationJob(
    1457          25 :     ParseInfo* parse_info, Isolate* isolate) {
    1458             :   VMState<BYTECODE_COMPILER> state(isolate);
    1459             :   std::unique_ptr<CompilationJob> job(
    1460             :       interpreter::Interpreter::NewCompilationJob(
    1461          25 :           parse_info, parse_info->literal(), isolate));
    1462          25 :   if (job->PrepareJob() != CompilationJob::SUCCEEDED) {
    1463             :     return nullptr;
    1464             :   }
    1465          25 :   return job.release();
    1466             : }
    1467             : 
    1468        7821 : bool Compiler::FinalizeCompilationJob(CompilationJob* raw_job) {
    1469             :   // Take ownership of compilation job.  Deleting job also tears down the zone.
    1470             :   std::unique_ptr<CompilationJob> job(raw_job);
    1471             : 
    1472        7821 :   if (job->compilation_info()->IsOptimizing()) {
    1473        7802 :     VMState<COMPILER> state(job->compilation_info()->isolate());
    1474        7802 :     return FinalizeOptimizedCompilationJob(job.get()) ==
    1475        7802 :            CompilationJob::SUCCEEDED;
    1476             :   } else {
    1477          19 :     VMState<BYTECODE_COMPILER> state(job->compilation_info()->isolate());
    1478          19 :     return FinalizeUnoptimizedCompilationJob(job.get()) ==
    1479          19 :            CompilationJob::SUCCEEDED;
    1480             :   }
    1481             : }
    1482             : 
    1483    14429117 : void Compiler::PostInstantiation(Handle<JSFunction> function,
    1484             :                                  PretenureFlag pretenure) {
    1485             :   Handle<SharedFunctionInfo> shared(function->shared());
    1486             : 
    1487    16712126 :   if (FLAG_always_opt && shared->allows_lazy_compilation() &&
    1488    16354149 :       !shared->optimization_disabled() && !shared->HasAsmWasmData() &&
    1489             :       shared->is_compiled()) {
    1490             :     // TODO(mvstanton): pass pretenure flag to EnsureLiterals.
    1491      466900 :     JSFunction::EnsureLiterals(function);
    1492             : 
    1493      466900 :     if (!function->IsOptimized()) {
    1494             :       // Only mark for optimization if we don't already have optimized code.
    1495      466900 :       if (!function->HasOptimizedCode()) {
    1496      188821 :         function->MarkForOptimization(ConcurrencyMode::kNotConcurrent);
    1497             :       }
    1498             :     }
    1499             :   }
    1500             : 
    1501    14429117 :   if (shared->is_compiled() && !shared->HasAsmWasmData()) {
    1502             :     // TODO(mvstanton): pass pretenure flag to EnsureLiterals.
    1503     9524740 :     JSFunction::EnsureLiterals(function);
    1504             : 
    1505             :     Code* code = function->feedback_vector()->optimized_code();
    1506     9524741 :     if (code != nullptr) {
    1507             :       // Caching of optimized code enabled and optimized code found.
    1508             :       DCHECK(!code->marked_for_deoptimization());
    1509             :       DCHECK(function->shared()->is_compiled());
    1510      494189 :       function->set_code(code);
    1511             :     }
    1512             :   }
    1513    14429119 : }
    1514             : 
    1515             : }  // namespace internal
    1516             : }  // namespace v8

Generated by: LCOV version 1.10