LCOV - code coverage report
Current view: top level - src - compiler.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 676 752 89.9 %
Date: 2019-02-19 Functions: 66 68 97.1 %

          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-inl.h"
      11             : #include "src/asmjs/asm-js.h"
      12             : #include "src/assembler-inl.h"
      13             : #include "src/ast/prettyprinter.h"
      14             : #include "src/ast/scopes.h"
      15             : #include "src/base/optional.h"
      16             : #include "src/bootstrapper.h"
      17             : #include "src/compilation-cache.h"
      18             : #include "src/compiler-dispatcher/compiler-dispatcher.h"
      19             : #include "src/compiler-dispatcher/optimizing-compile-dispatcher.h"
      20             : #include "src/compiler/pipeline.h"
      21             : #include "src/debug/debug.h"
      22             : #include "src/debug/liveedit.h"
      23             : #include "src/frames-inl.h"
      24             : #include "src/globals.h"
      25             : #include "src/heap/heap.h"
      26             : #include "src/interpreter/interpreter.h"
      27             : #include "src/isolate-inl.h"
      28             : #include "src/log-inl.h"
      29             : #include "src/message-template.h"
      30             : #include "src/objects/feedback-cell-inl.h"
      31             : #include "src/objects/map.h"
      32             : #include "src/optimized-compilation-info.h"
      33             : #include "src/ostreams.h"
      34             : #include "src/parsing/parse-info.h"
      35             : #include "src/parsing/parser.h"
      36             : #include "src/parsing/parsing.h"
      37             : #include "src/parsing/rewriter.h"
      38             : #include "src/parsing/scanner-character-streams.h"
      39             : #include "src/runtime-profiler.h"
      40             : #include "src/snapshot/code-serializer.h"
      41             : #include "src/unoptimized-compilation-info.h"
      42             : #include "src/vm-state-inl.h"
      43             : #include "src/zone/zone-list-inl.h"  // crbug.com/v8/8816
      44             : 
      45             : namespace v8 {
      46             : namespace internal {
      47             : 
      48             : // A wrapper around a OptimizedCompilationInfo that detaches the Handles from
      49             : // the underlying DeferredHandleScope and stores them in info_ on
      50             : // destruction.
      51             : class CompilationHandleScope final {
      52             :  public:
      53             :   explicit CompilationHandleScope(Isolate* isolate,
      54             :                                   OptimizedCompilationInfo* info)
      55        7169 :       : deferred_(isolate), info_(info) {}
      56        7169 :   ~CompilationHandleScope() { info_->set_deferred_handles(deferred_.Detach()); }
      57             : 
      58             :  private:
      59             :   DeferredHandleScope deferred_;
      60             :   OptimizedCompilationInfo* info_;
      61             : };
      62             : 
      63             : // Helper that times a scoped region and records the elapsed time.
      64             : struct ScopedTimer {
      65     5516704 :   explicit ScopedTimer(base::TimeDelta* location) : location_(location) {
      66             :     DCHECK_NOT_NULL(location_);
      67             :     timer_.Start();
      68             :   }
      69             : 
      70    16549859 :   ~ScopedTimer() { *location_ += timer_.Elapsed(); }
      71             : 
      72             :   base::ElapsedTimer timer_;
      73             :   base::TimeDelta* location_;
      74             : };
      75             : 
      76             : namespace {
      77             : 
      78     2519105 : void LogFunctionCompilation(CodeEventListener::LogEventsAndTags tag,
      79             :                             Handle<SharedFunctionInfo> shared,
      80             :                             Handle<Script> script,
      81             :                             Handle<AbstractCode> abstract_code, bool optimizing,
      82     5037888 :                             double time_taken_ms, Isolate* isolate) {
      83             :   DCHECK(!abstract_code.is_null());
      84             :   DCHECK(!abstract_code.is_identical_to(BUILTIN_CODE(isolate, CompileLazy)));
      85             : 
      86             :   // Log the code generation. If source information is available include
      87             :   // script name and line number. Check explicitly whether logging is
      88             :   // enabled as finding the line number is not free.
      89     7556939 :   if (!isolate->logger()->is_listening_to_code_events() &&
      90     7555988 :       !isolate->is_profiling() && !FLAG_log_function_events &&
      91             :       !isolate->code_event_dispatcher()->IsListeningToCodeEvents()) {
      92     2519051 :     return;
      93             :   }
      94             : 
      95         705 :   int line_num = Script::GetLineNumber(script, shared->StartPosition()) + 1;
      96         705 :   int column_num = Script::GetColumnNumber(script, shared->StartPosition()) + 1;
      97        1410 :   String script_name = script->name()->IsString()
      98             :                            ? String::cast(script->name())
      99        1410 :                            : ReadOnlyRoots(isolate).empty_string();
     100             :   CodeEventListener::LogEventsAndTags log_tag =
     101             :       Logger::ToNativeByScript(tag, *script);
     102         705 :   PROFILE(isolate, CodeCreateEvent(log_tag, *abstract_code, *shared,
     103             :                                    script_name, line_num, column_num));
     104         705 :   if (!FLAG_log_function_events) return;
     105             : 
     106             :   DisallowHeapAllocation no_gc;
     107             : 
     108          55 :   std::string name = optimizing ? "optimize" : "compile";
     109          55 :   switch (tag) {
     110             :     case CodeEventListener::EVAL_TAG:
     111             :       name += "-eval";
     112             :       break;
     113             :     case CodeEventListener::SCRIPT_TAG:
     114             :       break;
     115             :     case CodeEventListener::LAZY_COMPILE_TAG:
     116             :       name += "-lazy";
     117             :       break;
     118             :     case CodeEventListener::FUNCTION_TAG:
     119             :       break;
     120             :     default:
     121           0 :       UNREACHABLE();
     122             :   }
     123             : 
     124         275 :   LOG(isolate, FunctionEvent(name.c_str(), script->id(), time_taken_ms,
     125             :                              shared->StartPosition(), shared->EndPosition(),
     126             :                              shared->DebugName()));
     127             : }
     128             : 
     129     1305223 : ScriptOriginOptions OriginOptionsForEval(Object script) {
     130     1305223 :   if (!script->IsScript()) return ScriptOriginOptions();
     131             : 
     132     1305223 :   const auto outer_origin_options = Script::cast(script)->origin_options();
     133             :   return ScriptOriginOptions(outer_origin_options.IsSharedCrossOrigin(),
     134     1305223 :                              outer_origin_options.IsOpaque());
     135             : }
     136             : 
     137             : }  // namespace
     138             : 
     139             : // ----------------------------------------------------------------------------
     140             : // Implementation of UnoptimizedCompilationJob
     141             : 
     142     2090821 : CompilationJob::Status UnoptimizedCompilationJob::ExecuteJob() {
     143             :   DisallowHeapAccess no_heap_access;
     144             :   // Delegate to the underlying implementation.
     145             :   DCHECK_EQ(state(), State::kReadyToExecute);
     146     2090821 :   ScopedTimer t(&time_taken_to_execute_);
     147     4181484 :   return UpdateState(ExecuteJobImpl(), State::kReadyToFinalize);
     148             : }
     149             : 
     150     2065968 : CompilationJob::Status UnoptimizedCompilationJob::FinalizeJob(
     151             :     Handle<SharedFunctionInfo> shared_info, Isolate* isolate) {
     152             :   DCHECK(ThreadId::Current().Equals(isolate->thread_id()));
     153             :   DisallowCodeDependencyChange no_dependency_change;
     154     2065968 :   DisallowJavascriptExecution no_js(isolate);
     155             : 
     156             :   // Delegate to the underlying implementation.
     157             :   DCHECK_EQ(state(), State::kReadyToFinalize);
     158     4131937 :   ScopedTimer t(&time_taken_to_finalize_);
     159     4131945 :   return UpdateState(FinalizeJobImpl(shared_info, isolate), State::kSucceeded);
     160             : }
     161             : 
     162     2065959 : void UnoptimizedCompilationJob::RecordCompilationStats(Isolate* isolate) const {
     163             :   int code_size;
     164     2065959 :   if (compilation_info()->has_bytecode_array()) {
     165     2063520 :     code_size = compilation_info()->bytecode_array()->SizeIncludingMetadata();
     166             :   } else {
     167             :     DCHECK(compilation_info()->has_asm_wasm_data());
     168        2439 :     code_size = compilation_info()->asm_wasm_data()->Size();
     169             :   }
     170             : 
     171             :   Counters* counters = isolate->counters();
     172             :   // TODO(4280): Rename counters from "baseline" to "unoptimized" eventually.
     173     2065959 :   counters->total_baseline_code_size()->Increment(code_size);
     174     2065955 :   counters->total_baseline_compile_count()->Increment(1);
     175             : 
     176             :   // TODO(5203): Add timers for each phase of compilation.
     177     2065956 : }
     178             : 
     179     2065953 : void UnoptimizedCompilationJob::RecordFunctionCompilation(
     180             :     CodeEventListener::LogEventsAndTags tag, Handle<SharedFunctionInfo> shared,
     181     4131913 :     Isolate* isolate) const {
     182             :   Handle<AbstractCode> abstract_code;
     183     2065953 :   if (compilation_info()->has_bytecode_array()) {
     184             :     abstract_code =
     185     2063514 :         Handle<AbstractCode>::cast(compilation_info()->bytecode_array());
     186             :   } else {
     187             :     DCHECK(compilation_info()->has_asm_wasm_data());
     188             :     abstract_code =
     189        2439 :         Handle<AbstractCode>::cast(BUILTIN_CODE(isolate, InstantiateAsmJs));
     190             :   }
     191             : 
     192     2065956 :   double time_taken_ms = time_taken_to_execute_.InMillisecondsF() +
     193     2065960 :                          time_taken_to_finalize_.InMillisecondsF();
     194             : 
     195             :   LogFunctionCompilation(tag, shared, parse_info()->script(), abstract_code,
     196     2065960 :                          false, time_taken_ms, isolate);
     197     2065959 : }
     198             : 
     199             : // ----------------------------------------------------------------------------
     200             : // Implementation of OptimizedCompilationJob
     201             : 
     202      455385 : CompilationJob::Status OptimizedCompilationJob::PrepareJob(Isolate* isolate) {
     203             :   DCHECK(ThreadId::Current().Equals(isolate->thread_id()));
     204      453369 :   DisallowJavascriptExecution no_js(isolate);
     205             : 
     206      454041 :   if (FLAG_trace_opt && compilation_info()->IsOptimizing()) {
     207         672 :     StdoutStream os;
     208        1344 :     os << "[compiling method " << Brief(*compilation_info()->closure())
     209        1344 :        << " using " << compiler_name_;
     210         672 :     if (compilation_info()->is_osr()) os << " OSR";
     211        1344 :     os << "]" << std::endl;
     212             :   }
     213             : 
     214             :   // Delegate to the underlying implementation.
     215             :   DCHECK_EQ(state(), State::kReadyToPrepare);
     216      906738 :   ScopedTimer t(&time_taken_to_prepare_);
     217      906738 :   return UpdateState(PrepareJobImpl(isolate), State::kReadyToExecute);
     218             : }
     219             : 
     220      453331 : CompilationJob::Status OptimizedCompilationJob::ExecuteJob() {
     221             :   DisallowHeapAccess no_heap_access;
     222             :   // Delegate to the underlying implementation.
     223             :   DCHECK_EQ(state(), State::kReadyToExecute);
     224      453331 :   ScopedTimer t(&time_taken_to_execute_);
     225      906649 :   return UpdateState(ExecuteJobImpl(), State::kReadyToFinalize);
     226             : }
     227             : 
     228      453214 : CompilationJob::Status OptimizedCompilationJob::FinalizeJob(Isolate* isolate) {
     229             :   DCHECK(ThreadId::Current().Equals(isolate->thread_id()));
     230      453214 :   DisallowJavascriptExecution no_js(isolate);
     231             : 
     232             :   // Delegate to the underlying implementation.
     233             :   DCHECK_EQ(state(), State::kReadyToFinalize);
     234      906430 :   ScopedTimer t(&time_taken_to_finalize_);
     235      906432 :   return UpdateState(FinalizeJobImpl(isolate), State::kSucceeded);
     236             : }
     237             : 
     238          58 : CompilationJob::Status OptimizedCompilationJob::RetryOptimization(
     239             :     BailoutReason reason) {
     240             :   DCHECK(compilation_info_->IsOptimizing());
     241          58 :   compilation_info_->RetryOptimization(reason);
     242          58 :   return UpdateState(FAILED, State::kFailed);
     243             : }
     244             : 
     245          14 : CompilationJob::Status OptimizedCompilationJob::AbortOptimization(
     246             :     BailoutReason reason) {
     247             :   DCHECK(compilation_info_->IsOptimizing());
     248          14 :   compilation_info_->AbortOptimization(reason);
     249          14 :   return UpdateState(FAILED, State::kFailed);
     250             : }
     251             : 
     252      453149 : void OptimizedCompilationJob::RecordCompilationStats() const {
     253             :   DCHECK(compilation_info()->IsOptimizing());
     254             :   Handle<JSFunction> function = compilation_info()->closure();
     255      453149 :   double ms_creategraph = time_taken_to_prepare_.InMillisecondsF();
     256      453149 :   double ms_optimize = time_taken_to_execute_.InMillisecondsF();
     257      453149 :   double ms_codegen = time_taken_to_finalize_.InMillisecondsF();
     258      453149 :   if (FLAG_trace_opt) {
     259         672 :     PrintF("[optimizing ");
     260        1344 :     function->ShortPrint();
     261             :     PrintF(" - took %0.3f, %0.3f, %0.3f ms]\n", ms_creategraph, ms_optimize,
     262         672 :            ms_codegen);
     263             :   }
     264      453149 :   if (FLAG_trace_opt_stats) {
     265             :     static double compilation_time = 0.0;
     266             :     static int compiled_functions = 0;
     267             :     static int code_size = 0;
     268             : 
     269           0 :     compilation_time += (ms_creategraph + ms_optimize + ms_codegen);
     270           0 :     compiled_functions++;
     271           0 :     code_size += function->shared()->SourceSize();
     272             :     PrintF("Compiled: %d functions with %d byte source size in %fms.\n",
     273           0 :            compiled_functions, code_size, compilation_time);
     274             :   }
     275      453149 : }
     276             : 
     277      453149 : void OptimizedCompilationJob::RecordFunctionCompilation(
     278     1359447 :     CodeEventListener::LogEventsAndTags tag, Isolate* isolate) const {
     279             :   Handle<AbstractCode> abstract_code =
     280      453149 :       Handle<AbstractCode>::cast(compilation_info()->code());
     281             : 
     282      906298 :   double time_taken_ms = time_taken_to_prepare_.InMillisecondsF() +
     283      453149 :                          time_taken_to_execute_.InMillisecondsF() +
     284      453149 :                          time_taken_to_finalize_.InMillisecondsF();
     285             : 
     286             :   Handle<Script> script(
     287      906298 :       Script::cast(compilation_info()->shared_info()->script()), isolate);
     288             :   LogFunctionCompilation(tag, compilation_info()->shared_info(), script,
     289      453149 :                          abstract_code, true, time_taken_ms, isolate);
     290      453149 : }
     291             : 
     292             : // ----------------------------------------------------------------------------
     293             : // Local helper methods that make up the compilation pipeline.
     294             : 
     295             : namespace {
     296             : 
     297     3868925 : bool UseAsmWasm(FunctionLiteral* literal, bool asm_wasm_broken) {
     298             :   // Check whether asm.js validation is enabled.
     299     2089573 :   if (!FLAG_validate_asm) return false;
     300             : 
     301             :   // Modules that have validated successfully, but were subsequently broken by
     302             :   // invalid module instantiation attempts are off limit forever.
     303     1779523 :   if (asm_wasm_broken) return false;
     304             : 
     305             :   // In stress mode we want to run the validator on everything.
     306     1779353 :   if (FLAG_stress_validate_asm) return true;
     307             : 
     308             :   // In general, we respect the "use asm" directive.
     309     1779352 :   return literal->scope()->IsAsmModule();
     310             : }
     311             : 
     312     2063517 : void InstallBytecodeArray(Handle<BytecodeArray> bytecode_array,
     313             :                           Handle<SharedFunctionInfo> shared_info,
     314             :                           ParseInfo* parse_info, Isolate* isolate) {
     315     2063517 :   if (!FLAG_interpreted_frames_native_stack) {
     316     4126966 :     shared_info->set_bytecode_array(*bytecode_array);
     317     4127001 :     return;
     318             :   }
     319             : 
     320             :   Handle<Code> code = isolate->factory()->CopyCode(Handle<Code>::cast(
     321          35 :       isolate->factory()->interpreter_entry_trampoline_for_profiling()));
     322             : 
     323             :   Handle<InterpreterData> interpreter_data = Handle<InterpreterData>::cast(
     324          35 :       isolate->factory()->NewStruct(INTERPRETER_DATA_TYPE, TENURED));
     325             : 
     326          35 :   interpreter_data->set_bytecode_array(*bytecode_array);
     327          35 :   interpreter_data->set_interpreter_trampoline(*code);
     328             : 
     329          70 :   shared_info->set_interpreter_data(*interpreter_data);
     330             : 
     331             :   Handle<Script> script = parse_info->script();
     332          35 :   Handle<AbstractCode> abstract_code = Handle<AbstractCode>::cast(code);
     333             :   int line_num =
     334          35 :       Script::GetLineNumber(script, shared_info->StartPosition()) + 1;
     335             :   int column_num =
     336          35 :       Script::GetColumnNumber(script, shared_info->StartPosition()) + 1;
     337          70 :   String script_name = script->name()->IsString()
     338             :                            ? String::cast(script->name())
     339          70 :                            : ReadOnlyRoots(isolate).empty_string();
     340             :   CodeEventListener::LogEventsAndTags log_tag = Logger::ToNativeByScript(
     341             :       CodeEventListener::INTERPRETED_FUNCTION_TAG, *script);
     342          35 :   PROFILE(isolate, CodeCreateEvent(log_tag, *abstract_code, *shared_info,
     343             :                                    script_name, line_num, column_num));
     344             : }
     345             : 
     346     2065955 : void InstallUnoptimizedCode(UnoptimizedCompilationInfo* compilation_info,
     347             :                             Handle<SharedFunctionInfo> shared_info,
     348         872 :                             ParseInfo* parse_info, Isolate* isolate) {
     349             :   DCHECK_EQ(shared_info->language_mode(),
     350             :             compilation_info->literal()->language_mode());
     351             : 
     352             :   // Update the shared function info with the scope info.
     353     2065955 :   Handle<ScopeInfo> scope_info = compilation_info->scope()->scope_info();
     354     2065961 :   shared_info->set_scope_info(*scope_info);
     355             : 
     356     2065961 :   if (compilation_info->has_bytecode_array()) {
     357             :     DCHECK(!shared_info->HasBytecodeArray());  // Only compiled once.
     358             :     DCHECK(!compilation_info->has_asm_wasm_data());
     359             :     DCHECK(!shared_info->HasFeedbackMetadata());
     360             : 
     361             :     InstallBytecodeArray(compilation_info->bytecode_array(), shared_info,
     362     2063522 :                          parse_info, isolate);
     363             :     if (FLAG_lite_mode) {
     364             :       // Clear the feedback metadata field. In lite mode we don't need feedback
     365             :       // metadata since we never allocate feedback vectors.
     366             :       shared_info->set_raw_outer_scope_info_or_feedback_metadata(
     367             :           ReadOnlyRoots(isolate).undefined_value());
     368             :     } else {
     369             :       Handle<FeedbackMetadata> feedback_metadata = FeedbackMetadata::New(
     370     2063517 :           isolate, compilation_info->feedback_vector_spec());
     371     4127035 :       shared_info->set_feedback_metadata(*feedback_metadata);
     372             :     }
     373             :   } else {
     374             :     DCHECK(compilation_info->has_asm_wasm_data());
     375        4878 :     shared_info->set_asm_wasm_data(*compilation_info->asm_wasm_data());
     376             :     shared_info->set_feedback_metadata(
     377        4878 :         ReadOnlyRoots(isolate).empty_feedback_metadata());
     378             :   }
     379             : 
     380             :   // Install coverage info on the shared function info.
     381     6197859 :   if (compilation_info->has_coverage_info() &&
     382     2067721 :       !shared_info->HasCoverageInfo()) {
     383             :     DCHECK(isolate->is_block_code_coverage());
     384             :     isolate->debug()->InstallCoverageInfo(shared_info,
     385         872 :                                           compilation_info->coverage_info());
     386             :   }
     387     2065953 : }
     388             : 
     389     1999718 : void EnsureSharedFunctionInfosArrayOnScript(ParseInfo* parse_info,
     390             :                                             Isolate* isolate) {
     391             :   DCHECK(parse_info->is_toplevel());
     392             :   DCHECK(!parse_info->script().is_null());
     393     1999719 :   if (parse_info->script()->shared_function_infos()->length() > 0) {
     394             :     DCHECK_EQ(parse_info->script()->shared_function_infos()->length(),
     395             :               parse_info->max_function_literal_id() + 1);
     396           0 :     return;
     397             :   }
     398             :   Handle<WeakFixedArray> infos(isolate->factory()->NewWeakFixedArray(
     399      999860 :       parse_info->max_function_literal_id() + 1));
     400      999859 :   parse_info->script()->set_shared_function_infos(*infos);
     401             : }
     402             : 
     403     8816980 : void SetSharedFunctionFlagsFromLiteral(FunctionLiteral* literal,
     404             :                                        Handle<SharedFunctionInfo> shared_info) {
     405             :   // Don't overwrite values set by the bootstrapper.
     406     2065956 :   if (!shared_info->HasLength()) {
     407             :     shared_info->set_length(literal->function_length());
     408             :   }
     409             :   shared_info->set_has_duplicate_parameters(
     410     4131916 :       literal->has_duplicate_parameters());
     411     4131915 :   shared_info->set_is_oneshot_iife(literal->is_oneshot_iife());
     412     2065959 :   shared_info->SetExpectedNofPropertiesFromEstimate(literal);
     413     2065958 :   if (literal->dont_optimize_reason() != BailoutReason::kNoReason) {
     414           0 :     shared_info->DisableOptimization(literal->dont_optimize_reason());
     415             :   }
     416     2065958 : }
     417             : 
     418     2065958 : CompilationJob::Status FinalizeUnoptimizedCompilationJob(
     419     2065958 :     UnoptimizedCompilationJob* job, Handle<SharedFunctionInfo> shared_info,
     420             :     Isolate* isolate) {
     421     2065958 :   UnoptimizedCompilationInfo* compilation_info = job->compilation_info();
     422             :   ParseInfo* parse_info = job->parse_info();
     423             : 
     424     2065958 :   SetSharedFunctionFlagsFromLiteral(compilation_info->literal(), shared_info);
     425             : 
     426     2065958 :   CompilationJob::Status status = job->FinalizeJob(shared_info, isolate);
     427     2065961 :   if (status == CompilationJob::SUCCEEDED) {
     428     2065961 :     InstallUnoptimizedCode(compilation_info, shared_info, parse_info, isolate);
     429             :     CodeEventListener::LogEventsAndTags log_tag;
     430     2065960 :     if (parse_info->is_toplevel()) {
     431             :       log_tag = compilation_info->is_eval() ? CodeEventListener::EVAL_TAG
     432     1504423 :                                             : CodeEventListener::SCRIPT_TAG;
     433             :     } else {
     434             :       log_tag = parse_info->lazy_compile() ? CodeEventListener::LAZY_COMPILE_TAG
     435      561537 :                                            : CodeEventListener::FUNCTION_TAG;
     436             :     }
     437     2065960 :     job->RecordFunctionCompilation(log_tag, shared_info, isolate);
     438     2065959 :     job->RecordCompilationStats(isolate);
     439             :   }
     440     2065956 :   return status;
     441             : }
     442             : 
     443      585302 : std::unique_ptr<UnoptimizedCompilationJob> ExecuteUnoptimizedCompileJobs(
     444             :     ParseInfo* parse_info, FunctionLiteral* literal,
     445             :     AccountingAllocator* allocator,
     446             :     UnoptimizedCompilationJobList* inner_function_jobs) {
     447      585302 :   if (UseAsmWasm(literal, parse_info->is_asm_wasm_broken())) {
     448             :     std::unique_ptr<UnoptimizedCompilationJob> asm_job(
     449        1840 :         AsmJs::NewCompilationJob(parse_info, literal, allocator));
     450        1840 :     if (asm_job->ExecuteJob() == CompilationJob::SUCCEEDED) {
     451             :       return asm_job;
     452             :     }
     453             :     // asm.js validation failed, fall through to standard unoptimized compile.
     454             :     // Note: we rely on the fact that AsmJs jobs have done all validation in the
     455             :     // PrepareJob and ExecuteJob phases and can't fail in FinalizeJob with
     456             :     // with a validation error or another error that could be solve by falling
     457             :     // through to standard unoptimized compile.
     458             :   }
     459             :   std::vector<FunctionLiteral*> eager_inner_literals;
     460             :   std::unique_ptr<UnoptimizedCompilationJob> job(
     461             :       interpreter::Interpreter::NewCompilationJob(
     462      583967 :           parse_info, literal, allocator, &eager_inner_literals));
     463             : 
     464      583966 :   if (job->ExecuteJob() != CompilationJob::SUCCEEDED) {
     465             :     // Compilation failed, return null.
     466             :     return std::unique_ptr<UnoptimizedCompilationJob>();
     467             :   }
     468             : 
     469             :   // Recursively compile eager inner literals.
     470     1182679 :   for (FunctionLiteral* inner_literal : eager_inner_literals) {
     471             :     std::unique_ptr<UnoptimizedCompilationJob> inner_job(
     472             :         ExecuteUnoptimizedCompileJobs(parse_info, inner_literal, allocator,
     473       14761 :                                       inner_function_jobs));
     474             :     // Compilation failed, return null.
     475       14761 :     if (!inner_job) return std::unique_ptr<UnoptimizedCompilationJob>();
     476             :     inner_function_jobs->emplace_front(std::move(inner_job));
     477             :   }
     478             : 
     479             :   return job;
     480             : }
     481             : 
     482      570547 : std::unique_ptr<UnoptimizedCompilationJob> GenerateUnoptimizedCode(
     483      570547 :     ParseInfo* parse_info, AccountingAllocator* allocator,
     484             :     UnoptimizedCompilationJobList* inner_function_jobs) {
     485             :   DisallowHeapAccess no_heap_access;
     486             :   DCHECK(inner_function_jobs->empty());
     487             : 
     488      570547 :   if (!Compiler::Analyze(parse_info)) {
     489             :     return std::unique_ptr<UnoptimizedCompilationJob>();
     490             :   }
     491             : 
     492             :   // Prepare and execute compilation of the outer-most function.
     493             :   std::unique_ptr<UnoptimizedCompilationJob> outer_function_job(
     494             :       ExecuteUnoptimizedCompileJobs(parse_info, parse_info->literal(),
     495      570547 :                                     allocator, inner_function_jobs));
     496      570543 :   if (!outer_function_job) return std::unique_ptr<UnoptimizedCompilationJob>();
     497             : 
     498             :   // Character stream shouldn't be used again.
     499      570540 :   parse_info->ResetCharacterStream();
     500             : 
     501             :   return outer_function_job;
     502             : }
     503             : 
     504      999722 : MaybeHandle<SharedFunctionInfo> GenerateUnoptimizedCodeForToplevel(
     505     1999401 :     Isolate* isolate, ParseInfo* parse_info, AccountingAllocator* allocator,
     506             :     IsCompiledScope* is_compiled_scope) {
     507      999722 :   EnsureSharedFunctionInfosArrayOnScript(parse_info, isolate);
     508      999722 :   parse_info->ast_value_factory()->Internalize(isolate);
     509             : 
     510      999722 :   if (!Compiler::Analyze(parse_info)) return MaybeHandle<SharedFunctionInfo>();
     511      999700 :   DeclarationScope::AllocateScopeInfos(parse_info, isolate);
     512             : 
     513             :   // Prepare and execute compilation of the outer-most function.
     514             :   // Create the SharedFunctionInfo and add it to the script's list.
     515      999701 :   Handle<Script> script = parse_info->script();
     516             :   Handle<SharedFunctionInfo> top_level =
     517             :       isolate->factory()->NewSharedFunctionInfoForLiteral(parse_info->literal(),
     518      999701 :                                                           script, true);
     519             : 
     520             :   std::vector<FunctionLiteral*> functions_to_compile;
     521     1999399 :   functions_to_compile.push_back(parse_info->literal());
     522             : 
     523     3503675 :   while (!functions_to_compile.empty()) {
     524     1504275 :     FunctionLiteral* literal = functions_to_compile.back();
     525             :     functions_to_compile.pop_back();
     526             :     Handle<SharedFunctionInfo> shared_info =
     527     1504275 :         Compiler::GetSharedFunctionInfo(literal, script, isolate);
     528     1504274 :     if (shared_info->is_compiled()) continue;
     529     1504273 :     if (UseAsmWasm(literal, parse_info->is_asm_wasm_broken())) {
     530             :       std::unique_ptr<UnoptimizedCompilationJob> asm_job(
     531        1881 :           AsmJs::NewCompilationJob(parse_info, literal, allocator));
     532        3009 :       if (asm_job->ExecuteJob() == CompilationJob::SUCCEEDED &&
     533             :           FinalizeUnoptimizedCompilationJob(asm_job.get(), shared_info,
     534        1128 :                                             isolate) ==
     535             :               CompilationJob::SUCCEEDED) {
     536             :         continue;
     537             :       }
     538             :       // asm.js validation failed, fall through to standard unoptimized compile.
     539             :       // Note: we rely on the fact that AsmJs jobs have done all validation in
     540             :       // the PrepareJob and ExecuteJob phases and can't fail in FinalizeJob with
     541             :       // with a validation error or another error that could be solve by falling
     542             :       // through to standard unoptimized compile.
     543             :     }
     544             : 
     545             :     std::unique_ptr<UnoptimizedCompilationJob> job(
     546             :         interpreter::Interpreter::NewCompilationJob(
     547     1503146 :             parse_info, literal, allocator, &functions_to_compile));
     548             : 
     549     3006287 :     if (job->ExecuteJob() == CompilationJob::FAILED ||
     550     1503149 :         FinalizeUnoptimizedCompilationJob(job.get(), shared_info, isolate) ==
     551             :             CompilationJob::FAILED) {
     552           0 :       return MaybeHandle<SharedFunctionInfo>();
     553             :     }
     554             : 
     555     1503141 :     if (shared_info.is_identical_to(top_level)) {
     556             :       // Ensure that the top level function is retained.
     557      999697 :       *is_compiled_scope = shared_info->is_compiled_scope();
     558             :       DCHECK(is_compiled_scope->is_compiled());
     559             :     }
     560             :   }
     561             : 
     562             :   // Character stream shouldn't be used again.
     563      999701 :   parse_info->ResetCharacterStream();
     564             : 
     565      999698 :   return top_level;
     566             : }
     567             : 
     568      557665 : bool FinalizeUnoptimizedCode(
     569             :     ParseInfo* parse_info, Isolate* isolate,
     570             :     Handle<SharedFunctionInfo> shared_info,
     571             :     UnoptimizedCompilationJob* outer_function_job,
     572             :     UnoptimizedCompilationJobList* inner_function_jobs) {
     573             :   DCHECK(AllowCompilation::IsAllowed(isolate));
     574             : 
     575             :   // TODO(rmcilroy): Clear native context in debug once AsmJS generates doesn't
     576             :   // rely on accessing native context during finalization.
     577             : 
     578             :   // Allocate scope infos for the literal.
     579      557665 :   DeclarationScope::AllocateScopeInfos(parse_info, isolate);
     580             : 
     581             :   // Finalize the outer-most function's compilation job.
     582      557671 :   if (FinalizeUnoptimizedCompilationJob(outer_function_job, shared_info,
     583      557672 :                                         isolate) != CompilationJob::SUCCEEDED) {
     584             :     return false;
     585             :   }
     586             : 
     587             :   // Finalize the inner functions' compilation jobs.
     588     1119358 :   for (auto&& inner_job : *inner_function_jobs) {
     589             :     Handle<SharedFunctionInfo> inner_shared_info =
     590             :         Compiler::GetSharedFunctionInfo(
     591             :             inner_job->compilation_info()->literal(), parse_info->script(),
     592        4020 :             isolate);
     593             :     // The inner function might be compiled already if compiling for debug.
     594        4025 :     if (inner_shared_info->is_compiled()) continue;
     595        4015 :     if (FinalizeUnoptimizedCompilationJob(inner_job.get(), inner_shared_info,
     596        4015 :                                           isolate) !=
     597             :         CompilationJob::SUCCEEDED) {
     598           0 :       return false;
     599             :     }
     600             :   }
     601             : 
     602             :   // Report any warnings generated during compilation.
     603      557669 :   if (parse_info->pending_error_handler()->has_pending_warnings()) {
     604             :     parse_info->pending_error_handler()->ReportWarnings(isolate,
     605         445 :                                                         parse_info->script());
     606             :   }
     607             : 
     608             :   return true;
     609             : }
     610             : 
     611      471944 : V8_WARN_UNUSED_RESULT MaybeHandle<Code> GetCodeFromOptimizedCodeCache(
     612             :     Handle<JSFunction> function, BailoutId osr_offset) {
     613             :   RuntimeCallTimerScope runtimeTimer(
     614             :       function->GetIsolate(),
     615      471944 :       RuntimeCallCounterId::kCompileGetFromOptimizedCodeMap);
     616      943888 :   Handle<SharedFunctionInfo> shared(function->shared(), function->GetIsolate());
     617             :   DisallowHeapAllocation no_gc;
     618      471944 :   if (osr_offset.IsNone()) {
     619      466697 :     if (function->has_feedback_vector()) {
     620      466697 :       FeedbackVector feedback_vector = function->feedback_vector();
     621             :       feedback_vector->EvictOptimizedCodeMarkedForDeoptimization(
     622      466697 :           function->shared(), "GetCodeFromOptimizedCodeCache");
     623      466696 :       Code code = feedback_vector->optimized_code();
     624             : 
     625      466696 :       if (!code.is_null()) {
     626             :         // Caching of optimized code enabled and optimized code found.
     627             :         DCHECK(!code->marked_for_deoptimization());
     628             :         DCHECK(function->shared()->is_compiled());
     629           0 :         return Handle<Code>(code, feedback_vector->GetIsolate());
     630             :       }
     631             :     }
     632             :   }
     633      471943 :   return MaybeHandle<Code>();
     634             : }
     635             : 
     636      430095 : void ClearOptimizedCodeCache(OptimizedCompilationInfo* compilation_info) {
     637             :   Handle<JSFunction> function = compilation_info->closure();
     638      430095 :   if (compilation_info->osr_offset().IsNone()) {
     639             :     Handle<FeedbackVector> vector =
     640      850358 :         handle(function->feedback_vector(), function->GetIsolate());
     641      425179 :     vector->ClearOptimizationMarker();
     642             :   }
     643      430095 : }
     644             : 
     645      453149 : void InsertCodeIntoOptimizedCodeCache(
     646             :     OptimizedCompilationInfo* compilation_info) {
     647             :   Handle<Code> code = compilation_info->code();
     648      453149 :   if (code->kind() != Code::OPTIMIZED_FUNCTION) return;  // Nothing to do.
     649             : 
     650             :   // Function context specialization folds-in the function context,
     651             :   // so no sharing can occur.
     652      453149 :   if (compilation_info->is_function_context_specializing()) {
     653             :     // Native context specialized code is not shared, so make sure the optimized
     654             :     // code cache is clear.
     655      430095 :     ClearOptimizedCodeCache(compilation_info);
     656      430095 :     return;
     657             :   }
     658             : 
     659             :   // Cache optimized context-specific code.
     660             :   Handle<JSFunction> function = compilation_info->closure();
     661       46108 :   Handle<SharedFunctionInfo> shared(function->shared(), function->GetIsolate());
     662       46108 :   Handle<Context> native_context(function->context()->native_context(),
     663       46108 :                                  function->GetIsolate());
     664       23054 :   if (compilation_info->osr_offset().IsNone()) {
     665             :     Handle<FeedbackVector> vector =
     666       45986 :         handle(function->feedback_vector(), function->GetIsolate());
     667       22993 :     FeedbackVector::SetOptimizedCode(vector, code);
     668             :   }
     669             : }
     670             : 
     671      892400 : bool GetOptimizedCodeNow(OptimizedCompilationJob* job, Isolate* isolate) {
     672             :   TimerEventScope<TimerEventRecompileSynchronous> timer(isolate);
     673             :   RuntimeCallTimerScope runtimeTimer(
     674      446200 :       isolate, RuntimeCallCounterId::kRecompileSynchronous);
     675           0 :   OptimizedCompilationInfo* compilation_info = job->compilation_info();
     676     1338600 :   TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"),
     677             :                "V8.RecompileSynchronous");
     678             : 
     679     1338591 :   if (job->PrepareJob(isolate) != CompilationJob::SUCCEEDED ||
     680      892388 :       job->ExecuteJob() != CompilationJob::SUCCEEDED ||
     681      446184 :       job->FinalizeJob(isolate) != CompilationJob::SUCCEEDED) {
     682          37 :     if (FLAG_trace_opt) {
     683           0 :       PrintF("[aborted optimizing ");
     684           0 :       compilation_info->closure()->ShortPrint();
     685             :       PrintF(" because: %s]\n",
     686           0 :              GetBailoutReason(compilation_info->bailout_reason()));
     687             :     }
     688             :     return false;
     689             :   }
     690             : 
     691             :   // Success!
     692      446163 :   job->RecordCompilationStats();
     693             :   DCHECK(!isolate->has_pending_exception());
     694      446163 :   InsertCodeIntoOptimizedCodeCache(compilation_info);
     695      446163 :   job->RecordFunctionCompilation(CodeEventListener::LAZY_COMPILE_TAG, isolate);
     696      446163 :   return true;
     697             : }
     698             : 
     699       14338 : bool GetOptimizedCodeLater(OptimizedCompilationJob* job, Isolate* isolate) {
     700             :   OptimizedCompilationInfo* compilation_info = job->compilation_info();
     701        7169 :   if (!isolate->optimizing_compile_dispatcher()->IsQueueAvailable()) {
     702           0 :     if (FLAG_trace_concurrent_recompilation) {
     703           0 :       PrintF("  ** Compilation queue full, will retry optimizing ");
     704           0 :       compilation_info->closure()->ShortPrint();
     705           0 :       PrintF(" later.\n");
     706             :     }
     707             :     return false;
     708             :   }
     709             : 
     710        7169 :   if (isolate->heap()->HighMemoryPressure()) {
     711           0 :     if (FLAG_trace_concurrent_recompilation) {
     712           0 :       PrintF("  ** High memory pressure, will retry optimizing ");
     713           0 :       compilation_info->closure()->ShortPrint();
     714           0 :       PrintF(" later.\n");
     715             :     }
     716             :     return false;
     717             :   }
     718             : 
     719             :   TimerEventScope<TimerEventRecompileSynchronous> timer(isolate);
     720             :   RuntimeCallTimerScope runtimeTimer(
     721        7169 :       isolate, RuntimeCallCounterId::kRecompileSynchronous);
     722       21507 :   TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"),
     723             :                "V8.RecompileSynchronous");
     724             : 
     725        7169 :   if (job->PrepareJob(isolate) != CompilationJob::SUCCEEDED) return false;
     726        7169 :   isolate->optimizing_compile_dispatcher()->QueueForOptimization(job);
     727             : 
     728        7169 :   if (FLAG_trace_concurrent_recompilation) {
     729           0 :     PrintF("  ** Queued ");
     730           0 :     compilation_info->closure()->ShortPrint();
     731           0 :     PrintF(" for concurrent optimization.\n");
     732             :   }
     733             :   return true;
     734             : }
     735             : 
     736      481436 : MaybeHandle<Code> GetOptimizedCode(Handle<JSFunction> function,
     737             :                                    ConcurrencyMode mode,
     738             :                                    BailoutId osr_offset = BailoutId::None(),
     739             :                                    JavaScriptFrame* osr_frame = nullptr) {
     740      481436 :   Isolate* isolate = function->GetIsolate();
     741     1444254 :   Handle<SharedFunctionInfo> shared(function->shared(), isolate);
     742             : 
     743             :   // Make sure we clear the optimization marker on the function so that we
     744             :   // don't try to re-optimize.
     745      481437 :   if (function->HasOptimizationMarker()) {
     746      657930 :     function->ClearOptimizationMarker();
     747             :   }
     748             : 
     749      486932 :   if (shared->optimization_disabled() &&
     750             :       shared->disable_optimization_reason() == BailoutReason::kNeverOptimize) {
     751          56 :     return MaybeHandle<Code>();
     752             :   }
     753             : 
     754      962762 :   if (isolate->debug()->needs_check_on_function_call()) {
     755             :     // Do not optimize when debugger needs to hook into every call.
     756        9437 :     return MaybeHandle<Code>();
     757             :   }
     758             : 
     759             :   Handle<Code> cached_code;
     760      471944 :   if (GetCodeFromOptimizedCodeCache(function, osr_offset)
     761      943888 :           .ToHandle(&cached_code)) {
     762           0 :     if (FLAG_trace_opt) {
     763           0 :       PrintF("[found optimized code for ");
     764           0 :       function->ShortPrint();
     765           0 :       if (!osr_offset.IsNone()) {
     766           0 :         PrintF(" at OSR AST id %d", osr_offset.ToInt());
     767             :       }
     768           0 :       PrintF("]\n");
     769             :     }
     770           0 :     return cached_code;
     771             :   }
     772             : 
     773             :   // Reset profiler ticks, function is no longer considered hot.
     774             :   DCHECK(shared->is_compiled());
     775      943888 :   function->feedback_vector()->set_profiler_ticks(0);
     776             : 
     777      471944 :   VMState<COMPILER> state(isolate);
     778             :   DCHECK(!isolate->has_pending_exception());
     779             :   PostponeInterruptsScope postpone(isolate);
     780      943888 :   bool has_script = shared->script()->IsScript();
     781             :   // BUG(5946): This DCHECK is necessary to make certain that we won't
     782             :   // tolerate the lack of a script without bytecode.
     783             :   DCHECK_IMPLIES(!has_script, shared->HasBytecodeArray());
     784             :   std::unique_ptr<OptimizedCompilationJob> job(
     785      471944 :       compiler::Pipeline::NewCompilationJob(isolate, function, has_script));
     786      471940 :   OptimizedCompilationInfo* compilation_info = job->compilation_info();
     787             : 
     788             :   compilation_info->SetOptimizingForOsr(osr_offset, osr_frame);
     789             : 
     790             :   // Do not use TurboFan if we need to be able to set break points.
     791      471942 :   if (compilation_info->shared_info()->HasBreakInfo()) {
     792         560 :     compilation_info->AbortOptimization(BailoutReason::kFunctionBeingDebugged);
     793         560 :     return MaybeHandle<Code>();
     794             :   }
     795             : 
     796             :   // Do not use TurboFan if optimization is disabled or function doesn't pass
     797             :   // turbo_filter.
     798      924859 :   if (!FLAG_opt || !shared->PassesFilter(FLAG_turbo_filter)) {
     799       18015 :     compilation_info->AbortOptimization(BailoutReason::kOptimizationDisabled);
     800       18015 :     return MaybeHandle<Code>();
     801             :   }
     802             : 
     803      453369 :   TimerEventScope<TimerEventOptimizeCode> optimize_code_timer(isolate);
     804             :   RuntimeCallTimerScope runtimeTimer(isolate,
     805      453368 :                                      RuntimeCallCounterId::kOptimizeCode);
     806     1360105 :   TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.OptimizeCode");
     807             : 
     808             :   // In case of concurrent recompilation, all handles below this point will be
     809             :   // allocated in a deferred handle scope that is detached and handed off to
     810             :   // the background thread when we return.
     811      453368 :   base::Optional<CompilationHandleScope> compilation;
     812      453368 :   if (mode == ConcurrencyMode::kConcurrent) {
     813        7169 :     compilation.emplace(isolate, compilation_info);
     814             :   }
     815             : 
     816             :   // All handles below will be canonicalized.
     817      906737 :   CanonicalHandleScope canonical(isolate);
     818             : 
     819             :   // Reopen handles in the new CompilationHandleScope.
     820      453367 :   compilation_info->ReopenHandlesInNewHandleScope(isolate);
     821             : 
     822      453369 :   if (mode == ConcurrencyMode::kConcurrent) {
     823        7169 :     if (GetOptimizedCodeLater(job.get(), isolate)) {
     824             :       job.release();  // The background recompile job owns this now.
     825             : 
     826             :       // Set the optimization marker and return a code object which checks it.
     827       14338 :       function->SetOptimizationMarker(OptimizationMarker::kInOptimizationQueue);
     828             :       DCHECK(function->IsInterpreted() ||
     829             :              (!function->is_compiled() && function->shared()->IsInterpreted()));
     830             :       DCHECK(function->shared()->HasBytecodeArray());
     831        7169 :       return BUILTIN_CODE(isolate, InterpreterEntryTrampoline);
     832             :     }
     833             :   } else {
     834      446200 :     if (GetOptimizedCodeNow(job.get(), isolate))
     835      446163 :       return compilation_info->code();
     836             :   }
     837             : 
     838          37 :   if (isolate->has_pending_exception()) isolate->clear_pending_exception();
     839          37 :   return MaybeHandle<Code>();
     840             : }
     841             : 
     842         790 : bool FailWithPendingException(Isolate* isolate, ParseInfo* parse_info,
     843             :                               Compiler::ClearExceptionFlag flag) {
     844         790 :   if (flag == Compiler::CLEAR_EXCEPTION) {
     845         240 :     isolate->clear_pending_exception();
     846         550 :   } else if (!isolate->has_pending_exception()) {
     847         132 :     if (parse_info->pending_error_handler()->has_pending_error()) {
     848             :       parse_info->pending_error_handler()->ReportErrors(
     849         130 :           isolate, parse_info->script(), parse_info->ast_value_factory());
     850             :     } else {
     851           2 :       isolate->StackOverflow();
     852             :     }
     853             :   }
     854         790 :   return false;
     855             : }
     856             : 
     857      999835 : void FinalizeScriptCompilation(Isolate* isolate, ParseInfo* parse_info) {
     858             :   Handle<Script> script = parse_info->script();
     859      999838 :   script->set_compilation_state(Script::COMPILATION_STATE_COMPILED);
     860             : 
     861             :   // Register any pending parallel tasks with the associated SFI.
     862      999837 :   if (parse_info->parallel_tasks()) {
     863          15 :     CompilerDispatcher* dispatcher = parse_info->parallel_tasks()->dispatcher();
     864          85 :     for (auto& it : *parse_info->parallel_tasks()) {
     865          55 :       FunctionLiteral* literal = it.first;
     866          55 :       CompilerDispatcher::JobId job_id = it.second;
     867             :       MaybeHandle<SharedFunctionInfo> maybe_shared_for_task =
     868          55 :           script->FindSharedFunctionInfo(isolate, literal);
     869             :       Handle<SharedFunctionInfo> shared_for_task;
     870          55 :       if (maybe_shared_for_task.ToHandle(&shared_for_task)) {
     871          50 :         dispatcher->RegisterSharedFunctionInfo(job_id, *shared_for_task);
     872             :       } else {
     873           5 :         dispatcher->AbortJob(job_id);
     874             :       }
     875             :     }
     876             :   }
     877      999837 : }
     878             : 
     879         138 : MaybeHandle<SharedFunctionInfo> FinalizeTopLevel(
     880         138 :     ParseInfo* parse_info, Isolate* isolate,
     881             :     UnoptimizedCompilationJob* outer_function_job,
     882             :     UnoptimizedCompilationJobList* inner_function_jobs) {
     883             :   // Internalize ast values onto the heap.
     884         138 :   parse_info->ast_value_factory()->Internalize(isolate);
     885             : 
     886             :   // Create shared function infos for top level and shared function infos array
     887             :   // for inner functions.
     888         138 :   EnsureSharedFunctionInfosArrayOnScript(parse_info, isolate);
     889             :   DCHECK_EQ(kNoSourcePosition,
     890             :             parse_info->literal()->function_token_position());
     891             :   Handle<SharedFunctionInfo> shared_info =
     892             :       isolate->factory()->NewSharedFunctionInfoForLiteral(
     893         138 :           parse_info->literal(), parse_info->script(), true);
     894             : 
     895             :   // Finalize compilation of the unoptimized bytecode or asm-js data.
     896         138 :   if (!FinalizeUnoptimizedCode(parse_info, isolate, shared_info,
     897         138 :                                outer_function_job, inner_function_jobs)) {
     898             :     FailWithPendingException(isolate, parse_info,
     899           0 :                              Compiler::ClearExceptionFlag::KEEP_EXCEPTION);
     900           0 :     return MaybeHandle<SharedFunctionInfo>();
     901             :   }
     902             : 
     903         138 :   FinalizeScriptCompilation(isolate, parse_info);
     904             : 
     905         138 :   return shared_info;
     906             : }
     907             : 
     908     1109008 : MaybeHandle<SharedFunctionInfo> CompileToplevel(
     909     2108732 :     ParseInfo* parse_info, Isolate* isolate,
     910             :     IsCompiledScope* is_compiled_scope) {
     911             :   TimerEventScope<TimerEventCompileCode> top_level_timer(isolate);
     912     3327028 :   TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.CompileCode");
     913             :   DCHECK(ThreadId::Current().Equals(isolate->thread_id()));
     914             : 
     915             :   PostponeInterruptsScope postpone(isolate);
     916             :   DCHECK(!isolate->native_context().is_null());
     917             :   RuntimeCallTimerScope runtimeTimer(
     918             :       isolate, parse_info->is_eval() ? RuntimeCallCounterId::kCompileEval
     919     1109009 :                                      : RuntimeCallCounterId::kCompileScript);
     920             :   VMState<BYTECODE_COMPILER> state(isolate);
     921     2218021 :   if (parse_info->literal() == nullptr &&
     922     1109011 :       !parsing::ParseProgram(parse_info, isolate)) {
     923      109287 :     return MaybeHandle<SharedFunctionInfo>();
     924             :   }
     925             :   // Measure how long it takes to do the compilation; only take the
     926             :   // rest of the function into account to avoid overlap with the
     927             :   // parsing statistics.
     928             :   HistogramTimer* rate = parse_info->is_eval()
     929             :                              ? isolate->counters()->compile_eval()
     930     1999446 :                              : isolate->counters()->compile();
     931             :   HistogramTimerScope timer(rate);
     932     2999165 :   TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"),
     933             :                parse_info->is_eval() ? "V8.CompileEval" : "V8.Compile");
     934             : 
     935             :   // Generate the unoptimized bytecode or asm-js data.
     936             :   MaybeHandle<SharedFunctionInfo> shared_info =
     937             :       GenerateUnoptimizedCodeForToplevel(
     938      999722 :           isolate, parse_info, isolate->allocator(), is_compiled_scope);
     939      999724 :   if (shared_info.is_null()) {
     940             :     FailWithPendingException(isolate, parse_info,
     941          23 :                              Compiler::ClearExceptionFlag::KEEP_EXCEPTION);
     942          23 :     return MaybeHandle<SharedFunctionInfo>();
     943             :   }
     944             : 
     945      999701 :   FinalizeScriptCompilation(isolate, parse_info);
     946      999698 :   return shared_info;
     947             : }
     948             : 
     949       13073 : std::unique_ptr<UnoptimizedCompilationJob> CompileOnBackgroundThread(
     950       13073 :     ParseInfo* parse_info, AccountingAllocator* allocator,
     951             :     UnoptimizedCompilationJobList* inner_function_jobs) {
     952             :   DisallowHeapAccess no_heap_access;
     953       26146 :   TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"),
     954             :                "V8.CompileCodeBackground");
     955             :   RuntimeCallTimerScope runtimeTimer(
     956             :       parse_info->runtime_call_stats(),
     957             :       parse_info->is_toplevel()
     958             :           ? parse_info->is_eval()
     959             :                 ? RuntimeCallCounterId::kCompileBackgroundEval
     960             :                 : RuntimeCallCounterId::kCompileBackgroundScript
     961       39145 :           : RuntimeCallCounterId::kCompileBackgroundFunction);
     962             : 
     963             :   // Generate the unoptimized bytecode or asm-js data.
     964             :   std::unique_ptr<UnoptimizedCompilationJob> outer_function_job(
     965       13073 :       GenerateUnoptimizedCode(parse_info, allocator, inner_function_jobs));
     966       13073 :   return outer_function_job;
     967             : }
     968             : 
     969             : }  // namespace
     970             : 
     971       13104 : BackgroundCompileTask::BackgroundCompileTask(ScriptStreamingData* streamed_data,
     972       26208 :                                              Isolate* isolate)
     973       13104 :     : info_(new ParseInfo(isolate)),
     974             :       stack_size_(i::FLAG_stack_size),
     975             :       worker_thread_runtime_call_stats_(
     976       13104 :           isolate->counters()->worker_thread_runtime_call_stats()),
     977             :       allocator_(isolate->allocator()),
     978       78624 :       timer_(isolate->counters()->compile_script_on_background()) {
     979             :   VMState<PARSER> state(isolate);
     980             : 
     981             :   // Prepare the data for the internalization phase and compilation phase, which
     982             :   // will happen in the main thread after parsing.
     983       13104 :   LOG(isolate, ScriptEvent(Logger::ScriptEventType::kStreamingCompile,
     984             :                            info_->script_id()));
     985             :   info_->set_toplevel();
     986             :   info_->set_allow_lazy_parsing();
     987       13104 :   if (V8_UNLIKELY(info_->block_coverage_enabled())) {
     988           0 :     info_->AllocateSourceRangeMap();
     989             :   }
     990       13104 :   LanguageMode language_mode = construct_language_mode(FLAG_use_strict);
     991             :   info_->set_language_mode(
     992             :       stricter_language_mode(info_->language_mode(), language_mode));
     993             : 
     994             :   std::unique_ptr<Utf16CharacterStream> stream(ScannerStream::For(
     995       26208 :       streamed_data->source_stream.get(), streamed_data->encoding));
     996       26208 :   info_->set_character_stream(std::move(stream));
     997       13104 : }
     998             : 
     999          80 : BackgroundCompileTask::BackgroundCompileTask(
    1000             :     AccountingAllocator* allocator, const ParseInfo* outer_parse_info,
    1001          80 :     const AstRawString* function_name, const FunctionLiteral* function_literal,
    1002             :     WorkerThreadRuntimeCallStats* worker_thread_runtime_stats,
    1003             :     TimedHistogram* timer, int max_stack_size)
    1004             :     : info_(ParseInfo::FromParent(outer_parse_info, allocator, function_literal,
    1005             :                                   function_name)),
    1006             :       stack_size_(max_stack_size),
    1007             :       worker_thread_runtime_call_stats_(worker_thread_runtime_stats),
    1008             :       allocator_(allocator),
    1009         160 :       timer_(timer) {
    1010             :   DCHECK(outer_parse_info->is_toplevel());
    1011             :   DCHECK(!function_literal->is_toplevel());
    1012             : 
    1013             :   // Clone the character stream so both can be accessed independently.
    1014             :   std::unique_ptr<Utf16CharacterStream> character_stream =
    1015          80 :       outer_parse_info->character_stream()->Clone();
    1016         160 :   character_stream->Seek(function_literal->start_position());
    1017         160 :   info_->set_character_stream(std::move(character_stream));
    1018             : 
    1019             :   // Get preparsed scope data from the function literal.
    1020          80 :   if (function_literal->produced_preparse_data()) {
    1021             :     ZonePreparseData* serialized_data =
    1022          20 :         function_literal->produced_preparse_data()->Serialize(info_->zone());
    1023             :     info_->set_consumed_preparse_data(
    1024          20 :         ConsumedPreparseData::For(info_->zone(), serialized_data));
    1025             :   }
    1026          80 : }
    1027             : 
    1028             : BackgroundCompileTask::~BackgroundCompileTask() = default;
    1029             : 
    1030             : namespace {
    1031             : 
    1032             : // A scope object that ensures a parse info's runtime call stats, stack limit
    1033             : // and on_background_thread fields is set correctly during worker-thread
    1034             : // compile, and restores it after going out of scope.
    1035             : class OffThreadParseInfoScope {
    1036             :  public:
    1037       13178 :   OffThreadParseInfoScope(
    1038             :       ParseInfo* parse_info,
    1039             :       WorkerThreadRuntimeCallStats* worker_thread_runtime_stats, int stack_size)
    1040             :       : parse_info_(parse_info),
    1041       26356 :         original_runtime_call_stats_(parse_info_->runtime_call_stats()),
    1042             :         original_stack_limit_(parse_info_->stack_limit()),
    1043       39534 :         worker_thread_scope_(worker_thread_runtime_stats) {
    1044       13178 :     parse_info_->set_on_background_thread(true);
    1045       13178 :     parse_info_->set_runtime_call_stats(worker_thread_scope_.Get());
    1046       13178 :     parse_info_->set_stack_limit(GetCurrentStackPosition() - stack_size * KB);
    1047       13179 :   }
    1048             : 
    1049       26358 :   ~OffThreadParseInfoScope() {
    1050       13179 :     parse_info_->set_stack_limit(original_stack_limit_);
    1051       13179 :     parse_info_->set_runtime_call_stats(original_runtime_call_stats_);
    1052       13179 :     parse_info_->set_on_background_thread(false);
    1053       13179 :   }
    1054             : 
    1055             :  private:
    1056             :   ParseInfo* parse_info_;
    1057             :   RuntimeCallStats* original_runtime_call_stats_;
    1058             :   uintptr_t original_stack_limit_;
    1059             :   WorkerThreadRuntimeCallStatsScope worker_thread_scope_;
    1060             : 
    1061             :   DISALLOW_COPY_AND_ASSIGN(OffThreadParseInfoScope);
    1062             : };
    1063             : 
    1064             : }  // namespace
    1065             : 
    1066       13179 : void BackgroundCompileTask::Run() {
    1067             :   DisallowHeapAllocation no_allocation;
    1068             :   DisallowHandleAllocation no_handles;
    1069             :   DisallowHeapAccess no_heap_access;
    1070             : 
    1071       13179 :   TimedHistogramScope timer(timer_);
    1072             :   OffThreadParseInfoScope off_thread_scope(
    1073       39535 :       info_.get(), worker_thread_runtime_call_stats_, stack_size_);
    1074       39537 :   TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"),
    1075             :                "BackgroundCompileTask::Run");
    1076             :   RuntimeCallTimerScope runtimeTimer(
    1077             :       info_->runtime_call_stats(),
    1078       13179 :       RuntimeCallCounterId::kCompileBackgroundCompileTask);
    1079             : 
    1080             :   // Update the character stream's runtime call stats.
    1081             :   info_->character_stream()->set_runtime_call_stats(
    1082       13179 :       info_->runtime_call_stats());
    1083             : 
    1084             :   // Parser needs to stay alive for finalizing the parsing on the main
    1085             :   // thread.
    1086       13179 :   parser_.reset(new Parser(info_.get()));
    1087       13179 :   parser_->InitializeEmptyScopeChain(info_.get());
    1088             : 
    1089       13179 :   parser_->ParseOnBackground(info_.get());
    1090       13179 :   if (info_->literal() != nullptr) {
    1091             :     // Parsing has succeeded, compile.
    1092       26146 :     outer_function_job_ = CompileOnBackgroundThread(info_.get(), allocator_,
    1093             :                                                     &inner_function_jobs_);
    1094             :   }
    1095       13179 : }
    1096             : 
    1097             : 
    1098             : // ----------------------------------------------------------------------------
    1099             : // Implementation of Compiler
    1100             : 
    1101     3205722 : bool Compiler::Analyze(ParseInfo* parse_info) {
    1102             :   DCHECK_NOT_NULL(parse_info->literal());
    1103             :   RuntimeCallTimerScope runtimeTimer(
    1104             :       parse_info->runtime_call_stats(),
    1105             :       parse_info->on_background_thread()
    1106             :           ? RuntimeCallCounterId::kCompileBackgroundAnalyse
    1107     3205722 :           : RuntimeCallCounterId::kCompileAnalyse);
    1108     1602863 :   if (!Rewriter::Rewrite(parse_info)) return false;
    1109     1602855 :   if (!DeclarationScope::Analyze(parse_info)) return false;
    1110     1602837 :   return true;
    1111             : }
    1112             : 
    1113           0 : bool Compiler::ParseAndAnalyze(ParseInfo* parse_info,
    1114             :                                Handle<SharedFunctionInfo> shared_info,
    1115             :                                Isolate* isolate) {
    1116           0 :   if (!parsing::ParseAny(parse_info, shared_info, isolate)) {
    1117             :     return false;
    1118             :   }
    1119           0 :   return Compiler::Analyze(parse_info);
    1120             : }
    1121             : 
    1122             : // static
    1123          20 : bool Compiler::CollectSourcePositions(Isolate* isolate,
    1124             :                                       Handle<SharedFunctionInfo> shared_info) {
    1125             :   DCHECK(shared_info->is_compiled());
    1126             :   DCHECK(shared_info->HasBytecodeArray());
    1127             :   DCHECK(!shared_info->GetBytecodeArray()->HasSourcePositionTable());
    1128             : 
    1129             :   // TODO(v8:8510): Push the CLEAR_EXCEPTION flag or something like it down into
    1130             :   // the parser so it aborts without setting a pending exception, which then
    1131             :   // gets thrown. This would avoid the situation where potentially we'd reparse
    1132             :   // several times (running out of stack each time) before hitting this limit.
    1133          10 :   if (GetCurrentStackPosition() < isolate->stack_guard()->real_climit())
    1134             :     return false;
    1135             : 
    1136             :   DCHECK(AllowCompilation::IsAllowed(isolate));
    1137             :   DCHECK(ThreadId::Current().Equals(isolate->thread_id()));
    1138             :   DCHECK(!isolate->has_pending_exception());
    1139             :   VMState<BYTECODE_COMPILER> state(isolate);
    1140             :   PostponeInterruptsScope postpone(isolate);
    1141             :   RuntimeCallTimerScope runtimeTimer(
    1142          10 :       isolate, RuntimeCallCounterId::kCompileCollectSourcePositions);
    1143          30 :   TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"),
    1144             :                "V8.CollectSourcePositions");
    1145          10 :   HistogramTimerScope timer(isolate->counters()->collect_source_positions());
    1146             : 
    1147             :   // Set up parse info.
    1148          20 :   ParseInfo parse_info(isolate, shared_info);
    1149             :   parse_info.set_lazy_compile();
    1150             :   parse_info.set_collect_source_positions();
    1151          10 :   if (FLAG_allow_natives_syntax) parse_info.set_allow_natives_syntax();
    1152             : 
    1153             :   // Parse and update ParseInfo with the results.
    1154          10 :   if (!parsing::ParseAny(&parse_info, shared_info, isolate)) {
    1155             :     return FailWithPendingException(
    1156           0 :         isolate, &parse_info, Compiler::ClearExceptionFlag::CLEAR_EXCEPTION);
    1157             :   }
    1158             : 
    1159             :   // Generate the unoptimized bytecode.
    1160             :   // TODO(v8:8510): Consider forcing preparsing of inner functions to avoid
    1161             :   // wasting time fully parsing them when they won't ever be used.
    1162             :   UnoptimizedCompilationJobList inner_function_jobs;
    1163             :   std::unique_ptr<UnoptimizedCompilationJob> outer_function_job(
    1164             :       GenerateUnoptimizedCode(&parse_info, isolate->allocator(),
    1165          10 :                               &inner_function_jobs));
    1166          10 :   if (!outer_function_job) {
    1167             :     return FailWithPendingException(
    1168           0 :         isolate, &parse_info, Compiler::ClearExceptionFlag::CLEAR_EXCEPTION);
    1169             :   }
    1170             : 
    1171             :   DCHECK(outer_function_job->compilation_info()->collect_source_positions());
    1172             : 
    1173             :   // TODO(v8:8510) Avoid re-allocating bytecode array/constant pool and
    1174             :   // re-internalizeing the ast values. Maybe we could use the
    1175             :   // unoptimized_compilation_flag to signal that all we need is the source
    1176             :   // position table (and we could do the DCHECK that the bytecode array is the
    1177             :   // same in the bytecode-generator, by comparing the real bytecode array on the
    1178             :   // SFI with the off-heap bytecode array).
    1179             : 
    1180             :   // Internalize ast values onto the heap.
    1181          10 :   parse_info.ast_value_factory()->Internalize(isolate);
    1182             : 
    1183             :   {
    1184             :     // Allocate scope infos for the literal.
    1185          10 :     DeclarationScope::AllocateScopeInfos(&parse_info, isolate);
    1186          10 :     CHECK_EQ(outer_function_job->FinalizeJob(shared_info, isolate),
    1187             :              CompilationJob::SUCCEEDED);
    1188             :   }
    1189             : 
    1190             :   // Update the source position table on the original bytecode.
    1191             :   Handle<BytecodeArray> bytecode =
    1192          20 :       handle(shared_info->GetBytecodeArray(), isolate);
    1193             :   DCHECK(bytecode->IsBytecodeEqual(
    1194             :       *outer_function_job->compilation_info()->bytecode_array()));
    1195             :   DCHECK(outer_function_job->compilation_info()->has_bytecode_array());
    1196             :   bytecode->set_source_position_table(outer_function_job->compilation_info()
    1197          10 :                                           ->bytecode_array()
    1198          20 :                                           ->SourcePositionTable());
    1199             : 
    1200             :   DCHECK(!isolate->has_pending_exception());
    1201             :   DCHECK(shared_info->is_compiled_scope().is_compiled());
    1202          10 :   return true;
    1203             : }
    1204             : 
    1205      558166 : bool Compiler::Compile(Handle<SharedFunctionInfo> shared_info,
    1206             :                        ClearExceptionFlag flag,
    1207             :                        IsCompiledScope* is_compiled_scope) {
    1208             :   // We should never reach here if the function is already compiled.
    1209             :   DCHECK(!shared_info->is_compiled());
    1210             :   DCHECK(!is_compiled_scope->is_compiled());
    1211             : 
    1212     1115630 :   Isolate* isolate = shared_info->GetIsolate();
    1213             :   DCHECK(AllowCompilation::IsAllowed(isolate));
    1214             :   DCHECK(ThreadId::Current().Equals(isolate->thread_id()));
    1215             :   DCHECK(!isolate->has_pending_exception());
    1216             :   DCHECK(!shared_info->HasBytecodeArray());
    1217             :   VMState<BYTECODE_COMPILER> state(isolate);
    1218             :   PostponeInterruptsScope postpone(isolate);
    1219             :   TimerEventScope<TimerEventCompileCode> compile_timer(isolate);
    1220             :   RuntimeCallTimerScope runtimeTimer(isolate,
    1221      558168 :                                      RuntimeCallCounterId::kCompileFunction);
    1222     1674505 :   TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.CompileCode");
    1223     1116337 :   AggregatedHistogramTimerScope timer(isolate->counters()->compile_lazy());
    1224             : 
    1225             :   // Set up parse info.
    1226     1116331 :   ParseInfo parse_info(isolate, shared_info);
    1227             :   parse_info.set_lazy_compile();
    1228             : 
    1229             :   // Check if the compiler dispatcher has shared_info enqueued for compile.
    1230             :   CompilerDispatcher* dispatcher = isolate->compiler_dispatcher();
    1231      558166 :   if (dispatcher->IsEnqueued(shared_info)) {
    1232          43 :     if (!dispatcher->FinishNow(shared_info)) {
    1233           0 :       return FailWithPendingException(isolate, &parse_info, flag);
    1234             :     }
    1235          43 :     *is_compiled_scope = shared_info->is_compiled_scope();
    1236             :     DCHECK(is_compiled_scope->is_compiled());
    1237          43 :     return true;
    1238             :   }
    1239             : 
    1240      558124 :   if (shared_info->HasUncompiledDataWithPreparseData()) {
    1241             :     parse_info.set_consumed_preparse_data(ConsumedPreparseData::For(
    1242             :         isolate,
    1243             :         handle(
    1244       38438 :             shared_info->uncompiled_data_with_preparse_data()->preparse_data(),
    1245       57657 :             isolate)));
    1246             :   }
    1247             : 
    1248             :   // Parse and update ParseInfo with the results.
    1249      558126 :   if (!parsing::ParseAny(&parse_info, shared_info, isolate)) {
    1250         657 :     return FailWithPendingException(isolate, &parse_info, flag);
    1251             :   }
    1252             : 
    1253             :   // Generate the unoptimized bytecode or asm-js data.
    1254             :   UnoptimizedCompilationJobList inner_function_jobs;
    1255             :   std::unique_ptr<UnoptimizedCompilationJob> outer_function_job(
    1256             :       GenerateUnoptimizedCode(&parse_info, isolate->allocator(),
    1257      557464 :                               &inner_function_jobs));
    1258      557461 :   if (!outer_function_job) {
    1259           0 :     return FailWithPendingException(isolate, &parse_info, flag);
    1260             :   }
    1261             : 
    1262             :   // Internalize ast values onto the heap.
    1263      557461 :   parse_info.ast_value_factory()->Internalize(isolate);
    1264             : 
    1265             :   // Finalize compilation of the unoptimized bytecode or asm-js data.
    1266      557467 :   if (!FinalizeUnoptimizedCode(&parse_info, isolate, shared_info,
    1267             :                                outer_function_job.get(),
    1268      557464 :                                &inner_function_jobs)) {
    1269           0 :     return FailWithPendingException(isolate, &parse_info, flag);
    1270             :   }
    1271             : 
    1272             :   DCHECK(!isolate->has_pending_exception());
    1273      557468 :   *is_compiled_scope = shared_info->is_compiled_scope();
    1274             :   DCHECK(is_compiled_scope->is_compiled());
    1275      557468 :   return true;
    1276             : }
    1277             : 
    1278      681982 : bool Compiler::Compile(Handle<JSFunction> function, ClearExceptionFlag flag,
    1279      681987 :                        IsCompiledScope* is_compiled_scope) {
    1280             :   // We should never reach here if the function is already compiled or optimized
    1281             :   DCHECK(!function->is_compiled());
    1282             :   DCHECK(!function->IsOptimized());
    1283             :   DCHECK(!function->HasOptimizationMarker());
    1284             :   DCHECK(!function->HasOptimizedCode());
    1285             : 
    1286             :   // Reset the JSFunction if we are recompiling due to the bytecode having been
    1287             :   // flushed.
    1288      681983 :   function->ResetIfBytecodeFlushed();
    1289             : 
    1290             :   Isolate* isolate = function->GetIsolate();
    1291     1363972 :   Handle<SharedFunctionInfo> shared_info = handle(function->shared(), isolate);
    1292             : 
    1293             :   // Ensure shared function info is compiled.
    1294      681986 :   *is_compiled_scope = shared_info->is_compiled_scope();
    1295     1236650 :   if (!is_compiled_scope->is_compiled() &&
    1296      554665 :       !Compile(shared_info, flag, is_compiled_scope)) {
    1297             :     return false;
    1298             :   }
    1299             :   DCHECK(is_compiled_scope->is_compiled());
    1300     1362665 :   Handle<Code> code = handle(shared_info->GetCode(), isolate);
    1301             : 
    1302             :   // Allocate FeedbackVector for the JSFunction.
    1303      681332 :   JSFunction::EnsureFeedbackVector(function);
    1304             : 
    1305             :   // Optimize now if --always-opt is enabled.
    1306      833918 :   if (FLAG_always_opt && !function->shared()->HasAsmWasmData()) {
    1307      152179 :     if (FLAG_trace_opt) {
    1308           0 :       PrintF("[optimizing ");
    1309           0 :       function->ShortPrint();
    1310           0 :       PrintF(" because --always-opt]\n");
    1311             :     }
    1312             :     Handle<Code> opt_code;
    1313      152178 :     if (GetOptimizedCode(function, ConcurrencyMode::kNotConcurrent)
    1314      304357 :             .ToHandle(&opt_code)) {
    1315             :       code = opt_code;
    1316             :     }
    1317             :   }
    1318             : 
    1319             :   // Install code on closure.
    1320      681331 :   function->set_code(*code);
    1321             : 
    1322             :   // Check postconditions on success.
    1323             :   DCHECK(!isolate->has_pending_exception());
    1324             :   DCHECK(function->shared()->is_compiled());
    1325             :   DCHECK(function->is_compiled());
    1326      681334 :   return true;
    1327             : }
    1328             : 
    1329          69 : bool Compiler::FinalizeBackgroundCompileTask(
    1330             :     BackgroundCompileTask* task, Handle<SharedFunctionInfo> shared_info,
    1331             :     Isolate* isolate, ClearExceptionFlag flag) {
    1332         138 :   TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"),
    1333             :                "V8.FinalizeBackgroundCompileTask");
    1334             :   RuntimeCallTimerScope runtimeTimer(
    1335          69 :       isolate, RuntimeCallCounterId::kCompileFinalizeBackgroundCompileTask);
    1336             :   HandleScope scope(isolate);
    1337          69 :   ParseInfo* parse_info = task->info();
    1338             :   DCHECK(!parse_info->is_toplevel());
    1339             :   DCHECK(!shared_info->is_compiled());
    1340             : 
    1341         138 :   Handle<Script> script(Script::cast(shared_info->script()), isolate);
    1342          69 :   parse_info->set_script(script);
    1343             : 
    1344          69 :   task->parser()->UpdateStatistics(isolate, script);
    1345          69 :   task->parser()->HandleSourceURLComments(isolate, script);
    1346             : 
    1347         137 :   if (parse_info->literal() == nullptr || !task->outer_function_job()) {
    1348             :     // Parsing or compile failed on background thread - report error messages.
    1349           4 :     return FailWithPendingException(isolate, parse_info, flag);
    1350             :   }
    1351             : 
    1352             :   // Parsing has succeeded - finalize compilation.
    1353          65 :   parse_info->ast_value_factory()->Internalize(isolate);
    1354          65 :   if (!FinalizeUnoptimizedCode(parse_info, isolate, shared_info,
    1355             :                                task->outer_function_job(),
    1356         130 :                                task->inner_function_jobs())) {
    1357             :     // Finalization failed - throw an exception.
    1358           0 :     return FailWithPendingException(isolate, parse_info, flag);
    1359             :   }
    1360             : 
    1361             :   DCHECK(!isolate->has_pending_exception());
    1362             :   DCHECK(shared_info->is_compiled());
    1363          69 :   return true;
    1364             : }
    1365             : 
    1366      316969 : bool Compiler::CompileOptimized(Handle<JSFunction> function,
    1367             :                                 ConcurrencyMode mode) {
    1368      316969 :   if (function->IsOptimized()) return true;
    1369             :   Isolate* isolate = function->GetIsolate();
    1370             :   DCHECK(AllowCompilation::IsAllowed(isolate));
    1371             : 
    1372             :   // Start a compilation.
    1373             :   Handle<Code> code;
    1374      633938 :   if (!GetOptimizedCode(function, mode).ToHandle(&code)) {
    1375             :     // Optimization failed, get unoptimized code. Unoptimized code must exist
    1376             :     // already if we are optimizing.
    1377             :     DCHECK(!isolate->has_pending_exception());
    1378             :     DCHECK(function->shared()->is_compiled());
    1379             :     DCHECK(function->shared()->IsInterpreted());
    1380       20150 :     code = BUILTIN_CODE(isolate, InterpreterEntryTrampoline);
    1381             :   }
    1382             : 
    1383             :   // Install code on closure.
    1384      316969 :   function->set_code(*code);
    1385             : 
    1386             :   // Check postconditions on success.
    1387             :   DCHECK(!isolate->has_pending_exception());
    1388             :   DCHECK(function->shared()->is_compiled());
    1389             :   DCHECK(function->is_compiled());
    1390             :   DCHECK_IMPLIES(function->HasOptimizationMarker(),
    1391             :                  function->IsInOptimizationQueue());
    1392             :   DCHECK_IMPLIES(function->HasOptimizationMarker(),
    1393             :                  function->ChecksOptimizationMarker());
    1394             :   DCHECK_IMPLIES(function->IsInOptimizationQueue(),
    1395             :                  mode == ConcurrencyMode::kConcurrent);
    1396      316969 :   return true;
    1397             : }
    1398             : 
    1399         761 : MaybeHandle<SharedFunctionInfo> Compiler::CompileForLiveEdit(
    1400             :     ParseInfo* parse_info, Isolate* isolate) {
    1401             :   IsCompiledScope is_compiled_scope;
    1402         761 :   return CompileToplevel(parse_info, isolate, &is_compiled_scope);
    1403             : }
    1404             : 
    1405     3553125 : MaybeHandle<JSFunction> Compiler::GetFunctionFromEval(
    1406             :     Handle<String> source, Handle<SharedFunctionInfo> outer_info,
    1407             :     Handle<Context> context, LanguageMode language_mode,
    1408             :     ParseRestriction restriction, int parameters_end_pos,
    1409             :     int eval_scope_position, int eval_position) {
    1410     3553125 :   Isolate* isolate = context->GetIsolate();
    1411             :   int source_length = source->length();
    1412     3553125 :   isolate->counters()->total_eval_size()->Increment(source_length);
    1413     3553125 :   isolate->counters()->total_compile_size()->Increment(source_length);
    1414             : 
    1415             :   // The cache lookup key needs to be aware of the separation between the
    1416             :   // parameters and the body to prevent this valid invocation:
    1417             :   //   Function("", "function anonymous(\n/**/) {\n}");
    1418             :   // from adding an entry that falsely approves this invalid invocation:
    1419             :   //   Function("\n/**/) {\nfunction anonymous(", "}");
    1420             :   // The actual eval_scope_position for indirect eval and CreateDynamicFunction
    1421             :   // is unused (just 0), which means it's an available field to use to indicate
    1422             :   // this separation. But to make sure we're not causing other false hits, we
    1423             :   // negate the scope position.
    1424     7106250 :   if (restriction == ONLY_SINGLE_FUNCTION_LITERAL &&
    1425     3553125 :       parameters_end_pos != kNoSourcePosition) {
    1426             :     // use the parameters_end_pos as the eval_scope_position in the eval cache.
    1427             :     DCHECK_EQ(eval_scope_position, 0);
    1428     1088628 :     eval_scope_position = -parameters_end_pos;
    1429             :   }
    1430             :   CompilationCache* compilation_cache = isolate->compilation_cache();
    1431             :   InfoCellPair eval_result = compilation_cache->LookupEval(
    1432     3553125 :       source, outer_info, context, language_mode, eval_scope_position);
    1433             :   Handle<FeedbackCell> feedback_cell;
    1434     3553125 :   if (eval_result.has_feedback_cell()) {
    1435     2230918 :     feedback_cell = handle(eval_result.feedback_cell(), isolate);
    1436             :   }
    1437             : 
    1438             :   Handle<SharedFunctionInfo> shared_info;
    1439             :   Handle<Script> script;
    1440             :   IsCompiledScope is_compiled_scope;
    1441             :   bool allow_eval_cache;
    1442     3553125 :   if (eval_result.has_shared()) {
    1443             :     shared_info = Handle<SharedFunctionInfo>(eval_result.shared(), isolate);
    1444     5199842 :     script = Handle<Script>(Script::cast(shared_info->script()), isolate);
    1445     2599921 :     is_compiled_scope = shared_info->is_compiled_scope();
    1446             :     allow_eval_cache = true;
    1447             :   } else {
    1448      953204 :     ParseInfo parse_info(isolate);
    1449             :     script = parse_info.CreateScript(
    1450      953204 :         isolate, source, OriginOptionsForEval(outer_info->script()));
    1451      953204 :     script->set_compilation_type(Script::COMPILATION_TYPE_EVAL);
    1452     1906408 :     script->set_eval_from_shared(*outer_info);
    1453      953204 :     if (eval_position == kNoSourcePosition) {
    1454             :       // If the position is missing, attempt to get the code offset by
    1455             :       // walking the stack. Do not translate the code offset into source
    1456             :       // position, but store it as negative value for lazy translation.
    1457      352019 :       StackTraceFrameIterator it(isolate);
    1458      704038 :       if (!it.done() && it.is_javascript()) {
    1459      352019 :         FrameSummary summary = FrameSummary::GetTop(it.javascript_frame());
    1460             :         script->set_eval_from_shared(
    1461     1056057 :             summary.AsJavaScript().function()->shared());
    1462     1056057 :         script->set_origin_options(OriginOptionsForEval(*summary.script()));
    1463      352019 :         eval_position = -summary.code_offset();
    1464             :       } else {
    1465             :         eval_position = 0;
    1466             :       }
    1467             :     }
    1468             :     script->set_eval_from_position(eval_position);
    1469             : 
    1470             :     parse_info.set_eval();
    1471             :     parse_info.set_language_mode(language_mode);
    1472             :     parse_info.set_parse_restriction(restriction);
    1473             :     parse_info.set_parameters_end_pos(parameters_end_pos);
    1474     1906408 :     if (!context->IsNativeContext()) {
    1475     1136972 :       parse_info.set_outer_scope_info(handle(context->scope_info(), isolate));
    1476             :     }
    1477             :     DCHECK(!parse_info.is_module());
    1478             : 
    1479      953204 :     if (!CompileToplevel(&parse_info, isolate, &is_compiled_scope)
    1480     1906408 :              .ToHandle(&shared_info)) {
    1481      107087 :       return MaybeHandle<JSFunction>();
    1482             :     }
    1483      846117 :     allow_eval_cache = parse_info.allow_eval_cache();
    1484             :   }
    1485             : 
    1486             :   // If caller is strict mode, the result must be in strict mode as well.
    1487             :   DCHECK(is_sloppy(language_mode) || is_strict(shared_info->language_mode()));
    1488             : 
    1489             :   Handle<JSFunction> result;
    1490     3446038 :   if (eval_result.has_shared()) {
    1491     2599921 :     if (eval_result.has_feedback_cell()) {
    1492             :       result = isolate->factory()->NewFunctionFromSharedFunctionInfo(
    1493     2230918 :           shared_info, context, feedback_cell, NOT_TENURED);
    1494             :     } else {
    1495             :       result = isolate->factory()->NewFunctionFromSharedFunctionInfo(
    1496      369003 :           shared_info, context, NOT_TENURED);
    1497      369003 :       JSFunction::EnsureFeedbackVector(result);
    1498      369003 :       if (allow_eval_cache) {
    1499             :         // Make sure to cache this result.
    1500             :         Handle<FeedbackCell> new_feedback_cell(result->raw_feedback_cell(),
    1501      738006 :                                                isolate);
    1502             :         compilation_cache->PutEval(source, outer_info, context, shared_info,
    1503      369003 :                                    new_feedback_cell, eval_scope_position);
    1504             :       }
    1505             :     }
    1506             :   } else {
    1507             :     result = isolate->factory()->NewFunctionFromSharedFunctionInfo(
    1508      846117 :         shared_info, context, NOT_TENURED);
    1509      846117 :     JSFunction::EnsureFeedbackVector(result);
    1510      846117 :     if (allow_eval_cache) {
    1511             :       // Add the SharedFunctionInfo and the LiteralsArray to the eval cache if
    1512             :       // we didn't retrieve from there.
    1513             :       Handle<FeedbackCell> new_feedback_cell(result->raw_feedback_cell(),
    1514     1691336 :                                              isolate);
    1515             :       compilation_cache->PutEval(source, outer_info, context, shared_info,
    1516      845668 :                                  new_feedback_cell, eval_scope_position);
    1517             :     }
    1518             :   }
    1519             :   DCHECK(is_compiled_scope.is_compiled());
    1520             : 
    1521     3446038 :   return result;
    1522             : }
    1523             : 
    1524             : 
    1525          96 : bool Compiler::CodeGenerationFromStringsAllowed(Isolate* isolate,
    1526             :                                                 Handle<Context> context,
    1527             :                                                 Handle<String> source) {
    1528             :   DCHECK(context->allow_code_gen_from_strings()->IsFalse(isolate));
    1529             :   // Check with callback if set.
    1530             :   AllowCodeGenerationFromStringsCallback callback =
    1531             :       isolate->allow_code_gen_callback();
    1532          96 :   if (callback == nullptr) {
    1533             :     // No callback set and code generation disallowed.
    1534             :     return false;
    1535             :   } else {
    1536             :     // Callback set. Let it decide if code generation is allowed.
    1537          46 :     VMState<EXTERNAL> state(isolate);
    1538          46 :     return callback(v8::Utils::ToLocal(context), v8::Utils::ToLocal(source));
    1539             :   }
    1540             : }
    1541             : 
    1542     1090135 : MaybeHandle<JSFunction> Compiler::GetFunctionFromString(
    1543             :     Handle<Context> context, Handle<String> source,
    1544             :     ParseRestriction restriction, int parameters_end_pos) {
    1545             :   Isolate* const isolate = context->GetIsolate();
    1546     2180270 :   Handle<Context> native_context(context->native_context(), isolate);
    1547             : 
    1548             :   // Check if native context allows code generation from
    1549             :   // strings. Throw an exception if it doesn't.
    1550     2180315 :   if (native_context->allow_code_gen_from_strings()->IsFalse(isolate) &&
    1551          45 :       !CodeGenerationFromStringsAllowed(isolate, native_context, source)) {
    1552             :     Handle<Object> error_message =
    1553          33 :         native_context->ErrorMessageForCodeGenerationFromStrings();
    1554          33 :     THROW_NEW_ERROR(isolate, NewEvalError(MessageTemplate::kCodeGenFromStrings,
    1555             :                                           error_message),
    1556             :                     JSFunction);
    1557             :   }
    1558             : 
    1559             :   // Compile source string in the native context.
    1560             :   int eval_scope_position = 0;
    1561             :   int eval_position = kNoSourcePosition;
    1562             :   Handle<SharedFunctionInfo> outer_info(
    1563     2180204 :       native_context->empty_function()->shared(), isolate);
    1564             :   return Compiler::GetFunctionFromEval(
    1565             :       source, outer_info, native_context, LanguageMode::kSloppy, restriction,
    1566     1090102 :       parameters_end_pos, eval_scope_position, eval_position);
    1567             : }
    1568             : 
    1569             : namespace {
    1570             : 
    1571             : struct ScriptCompileTimerScope {
    1572             :  public:
    1573             :   // TODO(leszeks): There are too many blink-specific entries in this enum,
    1574             :   // figure out a way to push produce/hit-isolate-cache/consume/consume-failed
    1575             :   // back up the API and log them in blink instead.
    1576             :   enum class CacheBehaviour {
    1577             :     kProduceCodeCache,
    1578             :     kHitIsolateCacheWhenNoCache,
    1579             :     kConsumeCodeCache,
    1580             :     kConsumeCodeCacheFailed,
    1581             :     kNoCacheBecauseInlineScript,
    1582             :     kNoCacheBecauseScriptTooSmall,
    1583             :     kNoCacheBecauseCacheTooCold,
    1584             :     kNoCacheNoReason,
    1585             :     kNoCacheBecauseNoResource,
    1586             :     kNoCacheBecauseInspector,
    1587             :     kNoCacheBecauseCachingDisabled,
    1588             :     kNoCacheBecauseModule,
    1589             :     kNoCacheBecauseStreamingSource,
    1590             :     kNoCacheBecauseV8Extension,
    1591             :     kHitIsolateCacheWhenProduceCodeCache,
    1592             :     kHitIsolateCacheWhenConsumeCodeCache,
    1593             :     kNoCacheBecauseExtensionModule,
    1594             :     kNoCacheBecausePacScript,
    1595             :     kNoCacheBecauseInDocumentWrite,
    1596             :     kNoCacheBecauseResourceWithNoCacheHandler,
    1597             :     kHitIsolateCacheWhenStreamingSource,
    1598             :     kCount
    1599             :   };
    1600             : 
    1601      284650 :   explicit ScriptCompileTimerScope(
    1602             :       Isolate* isolate, ScriptCompiler::NoCacheReason no_cache_reason)
    1603             :       : isolate_(isolate),
    1604             :         all_scripts_histogram_scope_(isolate->counters()->compile_script(),
    1605             :                                      true),
    1606             :         no_cache_reason_(no_cache_reason),
    1607             :         hit_isolate_cache_(false),
    1608             :         producing_code_cache_(false),
    1609             :         consuming_code_cache_(false),
    1610      853956 :         consuming_code_cache_failed_(false) {}
    1611             : 
    1612      284649 :   ~ScriptCompileTimerScope() {
    1613      284649 :     CacheBehaviour cache_behaviour = GetCacheBehaviour();
    1614             : 
    1615             :     Histogram* cache_behaviour_histogram =
    1616      569296 :         isolate_->counters()->compile_script_cache_behaviour();
    1617             :     // Sanity check that the histogram has exactly one bin per enum entry.
    1618             :     DCHECK_EQ(0, cache_behaviour_histogram->min());
    1619             :     DCHECK_EQ(static_cast<int>(CacheBehaviour::kCount),
    1620             :               cache_behaviour_histogram->max() + 1);
    1621             :     DCHECK_EQ(static_cast<int>(CacheBehaviour::kCount),
    1622             :               cache_behaviour_histogram->num_buckets());
    1623      284648 :     cache_behaviour_histogram->AddSample(static_cast<int>(cache_behaviour));
    1624             : 
    1625             :     histogram_scope_.set_histogram(
    1626      284651 :         GetCacheBehaviourTimedHistogram(cache_behaviour));
    1627      284652 :   }
    1628             : 
    1629      129154 :   void set_hit_isolate_cache() { hit_isolate_cache_ = true; }
    1630             : 
    1631             :   void set_producing_code_cache() { producing_code_cache_ = true; }
    1632             : 
    1633         478 :   void set_consuming_code_cache() { consuming_code_cache_ = true; }
    1634             : 
    1635             :   void set_consuming_code_cache_failed() {
    1636          30 :     consuming_code_cache_failed_ = true;
    1637             :   }
    1638             : 
    1639             :  private:
    1640             :   Isolate* isolate_;
    1641             :   LazyTimedHistogramScope histogram_scope_;
    1642             :   // TODO(leszeks): This timer is the sum of the other times, consider removing
    1643             :   // it to save space.
    1644             :   HistogramTimerScope all_scripts_histogram_scope_;
    1645             :   ScriptCompiler::NoCacheReason no_cache_reason_;
    1646             :   bool hit_isolate_cache_;
    1647             :   bool producing_code_cache_;
    1648             :   bool consuming_code_cache_;
    1649             :   bool consuming_code_cache_failed_;
    1650             : 
    1651      284649 :   CacheBehaviour GetCacheBehaviour() {
    1652      284649 :     if (producing_code_cache_) {
    1653           0 :       if (hit_isolate_cache_) {
    1654             :         return CacheBehaviour::kHitIsolateCacheWhenProduceCodeCache;
    1655             :       } else {
    1656           0 :         return CacheBehaviour::kProduceCodeCache;
    1657             :       }
    1658             :     }
    1659             : 
    1660      284649 :     if (consuming_code_cache_) {
    1661         244 :       if (hit_isolate_cache_) {
    1662             :         return CacheBehaviour::kHitIsolateCacheWhenConsumeCodeCache;
    1663         239 :       } else if (consuming_code_cache_failed_) {
    1664             :         return CacheBehaviour::kConsumeCodeCacheFailed;
    1665             :       }
    1666         209 :       return CacheBehaviour::kConsumeCodeCache;
    1667             :     }
    1668             : 
    1669      284405 :     if (hit_isolate_cache_) {
    1670      129149 :       if (no_cache_reason_ == ScriptCompiler::kNoCacheBecauseStreamingSource) {
    1671             :         return CacheBehaviour::kHitIsolateCacheWhenStreamingSource;
    1672             :       }
    1673      116289 :       return CacheBehaviour::kHitIsolateCacheWhenNoCache;
    1674             :     }
    1675             : 
    1676      155256 :     switch (no_cache_reason_) {
    1677             :       case ScriptCompiler::kNoCacheBecauseInlineScript:
    1678             :         return CacheBehaviour::kNoCacheBecauseInlineScript;
    1679             :       case ScriptCompiler::kNoCacheBecauseScriptTooSmall:
    1680           0 :         return CacheBehaviour::kNoCacheBecauseScriptTooSmall;
    1681             :       case ScriptCompiler::kNoCacheBecauseCacheTooCold:
    1682           0 :         return CacheBehaviour::kNoCacheBecauseCacheTooCold;
    1683             :       case ScriptCompiler::kNoCacheNoReason:
    1684      151545 :         return CacheBehaviour::kNoCacheNoReason;
    1685             :       case ScriptCompiler::kNoCacheBecauseNoResource:
    1686           0 :         return CacheBehaviour::kNoCacheBecauseNoResource;
    1687             :       case ScriptCompiler::kNoCacheBecauseInspector:
    1688         261 :         return CacheBehaviour::kNoCacheBecauseInspector;
    1689             :       case ScriptCompiler::kNoCacheBecauseCachingDisabled:
    1690           0 :         return CacheBehaviour::kNoCacheBecauseCachingDisabled;
    1691             :       case ScriptCompiler::kNoCacheBecauseModule:
    1692           0 :         return CacheBehaviour::kNoCacheBecauseModule;
    1693             :       case ScriptCompiler::kNoCacheBecauseStreamingSource:
    1694         244 :         return CacheBehaviour::kNoCacheBecauseStreamingSource;
    1695             :       case ScriptCompiler::kNoCacheBecauseV8Extension:
    1696        3206 :         return CacheBehaviour::kNoCacheBecauseV8Extension;
    1697             :       case ScriptCompiler::kNoCacheBecauseExtensionModule:
    1698           0 :         return CacheBehaviour::kNoCacheBecauseExtensionModule;
    1699             :       case ScriptCompiler::kNoCacheBecausePacScript:
    1700           0 :         return CacheBehaviour::kNoCacheBecausePacScript;
    1701             :       case ScriptCompiler::kNoCacheBecauseInDocumentWrite:
    1702           0 :         return CacheBehaviour::kNoCacheBecauseInDocumentWrite;
    1703             :       case ScriptCompiler::kNoCacheBecauseResourceWithNoCacheHandler:
    1704           0 :         return CacheBehaviour::kNoCacheBecauseResourceWithNoCacheHandler;
    1705             :       case ScriptCompiler::kNoCacheBecauseDeferredProduceCodeCache: {
    1706           0 :         if (hit_isolate_cache_) {
    1707             :           return CacheBehaviour::kHitIsolateCacheWhenProduceCodeCache;
    1708             :         } else {
    1709           0 :           return CacheBehaviour::kProduceCodeCache;
    1710             :         }
    1711             :       }
    1712             :     }
    1713           0 :     UNREACHABLE();
    1714             :   }
    1715             : 
    1716      284651 :   TimedHistogram* GetCacheBehaviourTimedHistogram(
    1717             :       CacheBehaviour cache_behaviour) {
    1718      284651 :     switch (cache_behaviour) {
    1719             :       case CacheBehaviour::kProduceCodeCache:
    1720             :       // Even if we hit the isolate's compilation cache, we currently recompile
    1721             :       // when we want to produce the code cache.
    1722             :       case CacheBehaviour::kHitIsolateCacheWhenProduceCodeCache:
    1723           0 :         return isolate_->counters()->compile_script_with_produce_cache();
    1724             :       case CacheBehaviour::kHitIsolateCacheWhenNoCache:
    1725             :       case CacheBehaviour::kHitIsolateCacheWhenConsumeCodeCache:
    1726             :       case CacheBehaviour::kHitIsolateCacheWhenStreamingSource:
    1727      258308 :         return isolate_->counters()->compile_script_with_isolate_cache_hit();
    1728             :       case CacheBehaviour::kConsumeCodeCacheFailed:
    1729          60 :         return isolate_->counters()->compile_script_consume_failed();
    1730             :       case CacheBehaviour::kConsumeCodeCache:
    1731         418 :         return isolate_->counters()->compile_script_with_consume_cache();
    1732             : 
    1733             :       case CacheBehaviour::kNoCacheBecauseInlineScript:
    1734             :         return isolate_->counters()
    1735           0 :             ->compile_script_no_cache_because_inline_script();
    1736             :       case CacheBehaviour::kNoCacheBecauseScriptTooSmall:
    1737             :         return isolate_->counters()
    1738           0 :             ->compile_script_no_cache_because_script_too_small();
    1739             :       case CacheBehaviour::kNoCacheBecauseCacheTooCold:
    1740             :         return isolate_->counters()
    1741           0 :             ->compile_script_no_cache_because_cache_too_cold();
    1742             : 
    1743             :       // Aggregate all the other "no cache" counters into a single histogram, to
    1744             :       // save space.
    1745             :       case CacheBehaviour::kNoCacheNoReason:
    1746             :       case CacheBehaviour::kNoCacheBecauseNoResource:
    1747             :       case CacheBehaviour::kNoCacheBecauseInspector:
    1748             :       case CacheBehaviour::kNoCacheBecauseCachingDisabled:
    1749             :       // TODO(leszeks): Consider counting separately once modules are more
    1750             :       // common.
    1751             :       case CacheBehaviour::kNoCacheBecauseModule:
    1752             :       // TODO(leszeks): Count separately or remove entirely once we have
    1753             :       // background compilation.
    1754             :       case CacheBehaviour::kNoCacheBecauseStreamingSource:
    1755             :       case CacheBehaviour::kNoCacheBecauseV8Extension:
    1756             :       case CacheBehaviour::kNoCacheBecauseExtensionModule:
    1757             :       case CacheBehaviour::kNoCacheBecausePacScript:
    1758             :       case CacheBehaviour::kNoCacheBecauseInDocumentWrite:
    1759             :       case CacheBehaviour::kNoCacheBecauseResourceWithNoCacheHandler:
    1760      310516 :         return isolate_->counters()->compile_script_no_cache_other();
    1761             : 
    1762             :       case CacheBehaviour::kCount:
    1763           0 :         UNREACHABLE();
    1764             :     }
    1765           0 :     UNREACHABLE();
    1766             :   }
    1767             : };
    1768             : 
    1769      310575 : Handle<Script> NewScript(Isolate* isolate, ParseInfo* parse_info,
    1770             :                          Handle<String> source,
    1771             :                          Compiler::ScriptDetails script_details,
    1772             :                          ScriptOriginOptions origin_options,
    1773             :                          NativesFlag natives) {
    1774             :   // Create a script object describing the script to be compiled.
    1775             :   Handle<Script> script =
    1776      155290 :       parse_info->CreateScript(isolate, source, origin_options, natives);
    1777             :   Handle<Object> script_name;
    1778      155288 :   if (script_details.name_obj.ToHandle(&script_name)) {
    1779       89418 :     script->set_name(*script_name);
    1780       89415 :     script->set_line_offset(script_details.line_offset);
    1781       89415 :     script->set_column_offset(script_details.column_offset);
    1782             :   }
    1783             :   Handle<Object> source_map_url;
    1784      155285 :   if (script_details.source_map_url.ToHandle(&source_map_url)) {
    1785         739 :     script->set_source_mapping_url(*source_map_url);
    1786             :   }
    1787             :   Handle<FixedArray> host_defined_options;
    1788      155285 :   if (script_details.host_defined_options.ToHandle(&host_defined_options)) {
    1789      143576 :     script->set_host_defined_options(*host_defined_options);
    1790             :   }
    1791      155337 :   LOG(isolate, ScriptDetails(*script));
    1792      155285 :   return script;
    1793             : }
    1794             : 
    1795             : }  // namespace
    1796             : 
    1797      271467 : MaybeHandle<SharedFunctionInfo> Compiler::GetSharedFunctionInfoForScript(
    1798      271470 :     Isolate* isolate, Handle<String> source,
    1799             :     const Compiler::ScriptDetails& script_details,
    1800             :     ScriptOriginOptions origin_options, v8::Extension* extension,
    1801             :     ScriptData* cached_data, ScriptCompiler::CompileOptions compile_options,
    1802             :     ScriptCompiler::NoCacheReason no_cache_reason, NativesFlag natives) {
    1803      271467 :   ScriptCompileTimerScope compile_timer(isolate, no_cache_reason);
    1804             : 
    1805             :   if (compile_options == ScriptCompiler::kNoCompileOptions ||
    1806             :       compile_options == ScriptCompiler::kEagerCompile) {
    1807             :     DCHECK_NULL(cached_data);
    1808             :   } else {
    1809             :     DCHECK(compile_options == ScriptCompiler::kConsumeCodeCache);
    1810             :     DCHECK(cached_data);
    1811             :     DCHECK_NULL(extension);
    1812             :   }
    1813             :   int source_length = source->length();
    1814      271470 :   isolate->counters()->total_load_size()->Increment(source_length);
    1815      271470 :   isolate->counters()->total_compile_size()->Increment(source_length);
    1816             : 
    1817      271470 :   LanguageMode language_mode = construct_language_mode(FLAG_use_strict);
    1818             :   CompilationCache* compilation_cache = isolate->compilation_cache();
    1819             : 
    1820             :   // Do a lookup in the compilation cache but not for extensions.
    1821             :   MaybeHandle<SharedFunctionInfo> maybe_result;
    1822             :   IsCompiledScope is_compiled_scope;
    1823      271470 :   if (extension == nullptr) {
    1824             :     bool can_consume_code_cache =
    1825      268261 :         compile_options == ScriptCompiler::kConsumeCodeCache;
    1826      268261 :     if (can_consume_code_cache) {
    1827             :       compile_timer.set_consuming_code_cache();
    1828             :     }
    1829             : 
    1830             :     // First check per-isolate compilation cache.
    1831             :     maybe_result = compilation_cache->LookupScript(
    1832             :         source, script_details.name_obj, script_details.line_offset,
    1833             :         script_details.column_offset, origin_options, isolate->native_context(),
    1834      536522 :         language_mode);
    1835      268261 :     if (!maybe_result.is_null()) {
    1836             :       compile_timer.set_hit_isolate_cache();
    1837      151967 :     } else if (can_consume_code_cache) {
    1838             :       compile_timer.set_consuming_code_cache();
    1839             :       // Then check cached code provided by embedder.
    1840         234 :       HistogramTimerScope timer(isolate->counters()->compile_deserialize());
    1841             :       RuntimeCallTimerScope runtimeTimer(
    1842         234 :           isolate, RuntimeCallCounterId::kCompileDeserialize);
    1843         702 :       TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"),
    1844             :                    "V8.CompileDeserialize");
    1845             :       Handle<SharedFunctionInfo> inner_result;
    1846         234 :       if (CodeSerializer::Deserialize(isolate, cached_data, source,
    1847             :                                       origin_options)
    1848         468 :               .ToHandle(&inner_result)) {
    1849             :         // Promote to per-isolate compilation cache.
    1850         204 :         is_compiled_scope = inner_result->is_compiled_scope();
    1851             :         DCHECK(is_compiled_scope.is_compiled());
    1852             :         compilation_cache->PutScript(source, isolate->native_context(),
    1853         408 :                                      language_mode, inner_result);
    1854         408 :         Handle<Script> script(Script::cast(inner_result->script()), isolate);
    1855             :         maybe_result = inner_result;
    1856             :       } else {
    1857             :         // Deserializer failed. Fall through to compile.
    1858             :         compile_timer.set_consuming_code_cache_failed();
    1859             :       }
    1860             :     }
    1861             :   }
    1862             : 
    1863      271470 :   if (maybe_result.is_null()) {
    1864      154972 :     ParseInfo parse_info(isolate);
    1865             :     // No cache entry found compile the script.
    1866             :     NewScript(isolate, &parse_info, source, script_details, origin_options,
    1867      154972 :               natives);
    1868             : 
    1869             :     // Compile the function and add it to the isolate cache.
    1870      154967 :     if (origin_options.IsModule()) parse_info.set_module();
    1871             :     parse_info.set_extension(extension);
    1872             :     parse_info.set_eager(compile_options == ScriptCompiler::kEagerCompile);
    1873             : 
    1874             :     parse_info.set_language_mode(
    1875             :         stricter_language_mode(parse_info.language_mode(), language_mode));
    1876      154967 :     maybe_result = CompileToplevel(&parse_info, isolate, &is_compiled_scope);
    1877             :     Handle<SharedFunctionInfo> result;
    1878      306734 :     if (extension == nullptr && maybe_result.ToHandle(&result)) {
    1879             :       DCHECK(is_compiled_scope.is_compiled());
    1880             :       compilation_cache->PutScript(source, isolate->native_context(),
    1881      299218 :                                    language_mode, result);
    1882        5362 :     } else if (maybe_result.is_null() && natives != EXTENSION_CODE &&
    1883             :                natives != NATIVES_CODE) {
    1884        2154 :       isolate->ReportPendingMessages();
    1885      154970 :     }
    1886             :   }
    1887             : 
    1888      271470 :   return maybe_result;
    1889             : }
    1890             : 
    1891          79 : MaybeHandle<JSFunction> Compiler::GetWrappedFunction(
    1892             :     Handle<String> source, Handle<FixedArray> arguments,
    1893             :     Handle<Context> context, const Compiler::ScriptDetails& script_details,
    1894             :     ScriptOriginOptions origin_options, ScriptData* cached_data,
    1895             :     v8::ScriptCompiler::CompileOptions compile_options,
    1896             :     v8::ScriptCompiler::NoCacheReason no_cache_reason) {
    1897             :   Isolate* isolate = context->GetIsolate();
    1898          79 :   ScriptCompileTimerScope compile_timer(isolate, no_cache_reason);
    1899             : 
    1900             :   if (compile_options == ScriptCompiler::kNoCompileOptions ||
    1901             :       compile_options == ScriptCompiler::kEagerCompile) {
    1902             :     DCHECK_NULL(cached_data);
    1903             :   } else {
    1904             :     DCHECK(compile_options == ScriptCompiler::kConsumeCodeCache);
    1905             :     DCHECK(cached_data);
    1906             :   }
    1907             : 
    1908             :   int source_length = source->length();
    1909          79 :   isolate->counters()->total_compile_size()->Increment(source_length);
    1910             : 
    1911          79 :   LanguageMode language_mode = construct_language_mode(FLAG_use_strict);
    1912             : 
    1913             :   MaybeHandle<SharedFunctionInfo> maybe_result;
    1914             :   bool can_consume_code_cache =
    1915             :       compile_options == ScriptCompiler::kConsumeCodeCache;
    1916          79 :   if (can_consume_code_cache) {
    1917             :     compile_timer.set_consuming_code_cache();
    1918             :     // Then check cached code provided by embedder.
    1919           5 :     HistogramTimerScope timer(isolate->counters()->compile_deserialize());
    1920             :     RuntimeCallTimerScope runtimeTimer(
    1921           5 :         isolate, RuntimeCallCounterId::kCompileDeserialize);
    1922          15 :     TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"),
    1923             :                  "V8.CompileDeserialize");
    1924             :     maybe_result = CodeSerializer::Deserialize(isolate, cached_data, source,
    1925           5 :                                                origin_options);
    1926           5 :     if (maybe_result.is_null()) {
    1927             :       // Deserializer failed. Fall through to compile.
    1928             :       compile_timer.set_consuming_code_cache_failed();
    1929             :     }
    1930             :   }
    1931             : 
    1932             :   Handle<SharedFunctionInfo> wrapped;
    1933             :   Handle<Script> script;
    1934             :   IsCompiledScope is_compiled_scope;
    1935          79 :   if (!maybe_result.ToHandle(&wrapped)) {
    1936          74 :     ParseInfo parse_info(isolate);
    1937             :     script = NewScript(isolate, &parse_info, source, script_details,
    1938          74 :                        origin_options, NOT_NATIVES_CODE);
    1939         148 :     script->set_wrapped_arguments(*arguments);
    1940             : 
    1941             :     parse_info.set_eval();  // Use an eval scope as declaration scope.
    1942             :     parse_info.set_wrapped_as_function();
    1943             :     // parse_info.set_eager(compile_options == ScriptCompiler::kEagerCompile);
    1944         148 :     if (!context->IsNativeContext()) {
    1945          38 :       parse_info.set_outer_scope_info(handle(context->scope_info(), isolate));
    1946             :     }
    1947             :     parse_info.set_language_mode(
    1948             :         stricter_language_mode(parse_info.language_mode(), language_mode));
    1949             : 
    1950             :     Handle<SharedFunctionInfo> top_level;
    1951          74 :     maybe_result = CompileToplevel(&parse_info, isolate, &is_compiled_scope);
    1952          74 :     if (maybe_result.is_null()) isolate->ReportPendingMessages();
    1953          74 :     ASSIGN_RETURN_ON_EXCEPTION(isolate, top_level, maybe_result, JSFunction);
    1954             : 
    1955          64 :     SharedFunctionInfo::ScriptIterator infos(isolate, *script);
    1956         256 :     for (SharedFunctionInfo info = infos.Next(); !info.is_null();
    1957             :          info = infos.Next()) {
    1958         128 :       if (info->is_wrapped()) {
    1959             :         wrapped = Handle<SharedFunctionInfo>(info, isolate);
    1960          64 :         break;
    1961             :       }
    1962             :     }
    1963          64 :     DCHECK(!wrapped.is_null());
    1964             :   } else {
    1965           5 :     is_compiled_scope = wrapped->is_compiled_scope();
    1966          10 :     script = Handle<Script>(Script::cast(wrapped->script()), isolate);
    1967             :   }
    1968             :   DCHECK(is_compiled_scope.is_compiled());
    1969             : 
    1970             :   return isolate->factory()->NewFunctionFromSharedFunctionInfo(wrapped, context,
    1971          69 :                                                                NOT_TENURED);
    1972             : }
    1973             : 
    1974             : MaybeHandle<SharedFunctionInfo>
    1975       13104 : Compiler::GetSharedFunctionInfoForStreamedScript(
    1976       13104 :     Isolate* isolate, Handle<String> source,
    1977             :     const ScriptDetails& script_details, ScriptOriginOptions origin_options,
    1978             :     ScriptStreamingData* streaming_data) {
    1979             :   ScriptCompileTimerScope compile_timer(
    1980       13104 :       isolate, ScriptCompiler::kNoCacheBecauseStreamingSource);
    1981             :   PostponeInterruptsScope postpone(isolate);
    1982             : 
    1983             :   int source_length = source->length();
    1984       13104 :   isolate->counters()->total_load_size()->Increment(source_length);
    1985       13104 :   isolate->counters()->total_compile_size()->Increment(source_length);
    1986             : 
    1987             :   BackgroundCompileTask* task = streaming_data->task.get();
    1988         244 :   ParseInfo* parse_info = task->info();
    1989             :   DCHECK(parse_info->is_toplevel());
    1990             :   // Check if compile cache already holds the SFI, if so no need to finalize
    1991             :   // the code compiled on the background thread.
    1992             :   CompilationCache* compilation_cache = isolate->compilation_cache();
    1993             :   MaybeHandle<SharedFunctionInfo> maybe_result =
    1994             :       compilation_cache->LookupScript(
    1995             :           source, script_details.name_obj, script_details.line_offset,
    1996             :           script_details.column_offset, origin_options,
    1997       26208 :           isolate->native_context(), parse_info->language_mode());
    1998       13104 :   if (!maybe_result.is_null()) {
    1999             :     compile_timer.set_hit_isolate_cache();
    2000             :   }
    2001             : 
    2002       13104 :   if (maybe_result.is_null()) {
    2003             :     // No cache entry found, finalize compilation of the script and add it to
    2004             :     // the isolate cache.
    2005             :     Handle<Script> script =
    2006             :         NewScript(isolate, parse_info, source, script_details, origin_options,
    2007         244 :                   NOT_NATIVES_CODE);
    2008         244 :     task->parser()->UpdateStatistics(isolate, script);
    2009         244 :     task->parser()->HandleSourceURLComments(isolate, script);
    2010             : 
    2011         383 :     if (parse_info->literal() == nullptr || !task->outer_function_job()) {
    2012             :       // Parsing has failed - report error messages.
    2013             :       FailWithPendingException(isolate, parse_info,
    2014         106 :                                Compiler::ClearExceptionFlag::KEEP_EXCEPTION);
    2015             :     } else {
    2016             :       // Parsing has succeeded - finalize compilation.
    2017             :       maybe_result =
    2018             :           FinalizeTopLevel(parse_info, isolate, task->outer_function_job(),
    2019         276 :                            task->inner_function_jobs());
    2020         138 :       if (maybe_result.is_null()) {
    2021             :         // Finalization failed - throw an exception.
    2022             :         FailWithPendingException(isolate, parse_info,
    2023           0 :                                  Compiler::ClearExceptionFlag::KEEP_EXCEPTION);
    2024             :       }
    2025             :     }
    2026             : 
    2027             :     // Add compiled code to the isolate cache.
    2028             :     Handle<SharedFunctionInfo> result;
    2029         244 :     if (maybe_result.ToHandle(&result)) {
    2030             :       compilation_cache->PutScript(source, isolate->native_context(),
    2031         276 :                                    parse_info->language_mode(), result);
    2032             :     }
    2033             :   }
    2034             : 
    2035             :   streaming_data->Release();
    2036       26208 :   return maybe_result;
    2037             : }
    2038             : 
    2039     4086635 : Handle<SharedFunctionInfo> Compiler::GetSharedFunctionInfo(
    2040             :     FunctionLiteral* literal, Handle<Script> script, Isolate* isolate) {
    2041             :   // Precondition: code has been parsed and scopes have been analyzed.
    2042             :   MaybeHandle<SharedFunctionInfo> maybe_existing;
    2043             : 
    2044             :   // Find any previously allocated shared function info for the given literal.
    2045     4086639 :   maybe_existing = script->FindSharedFunctionInfo(isolate, literal);
    2046             : 
    2047             :   // If we found an existing shared function info, return it.
    2048             :   Handle<SharedFunctionInfo> existing;
    2049     4086639 :   if (maybe_existing.ToHandle(&existing)) return existing;
    2050             : 
    2051             :   // Allocate a shared function info object which will be compiled lazily.
    2052             :   Handle<SharedFunctionInfo> result =
    2053             :       isolate->factory()->NewSharedFunctionInfoForLiteral(literal, script,
    2054     2577041 :                                                           false);
    2055     2577043 :   return result;
    2056             : }
    2057             : 
    2058       12289 : MaybeHandle<Code> Compiler::GetOptimizedCodeForOSR(Handle<JSFunction> function,
    2059             :                                                    BailoutId osr_offset,
    2060             :                                                    JavaScriptFrame* osr_frame) {
    2061             :   DCHECK(!osr_offset.IsNone());
    2062             :   DCHECK_NOT_NULL(osr_frame);
    2063             :   return GetOptimizedCode(function, ConcurrencyMode::kNotConcurrent, osr_offset,
    2064       12289 :                           osr_frame);
    2065             : }
    2066             : 
    2067       14060 : bool Compiler::FinalizeOptimizedCompilationJob(OptimizedCompilationJob* job,
    2068             :                                                Isolate* isolate) {
    2069             :   VMState<COMPILER> state(isolate);
    2070             :   // Take ownership of compilation job.  Deleting job also tears down the zone.
    2071             :   std::unique_ptr<OptimizedCompilationJob> job_scope(job);
    2072           0 :   OptimizedCompilationInfo* compilation_info = job->compilation_info();
    2073             : 
    2074             :   TimerEventScope<TimerEventRecompileSynchronous> timer(isolate);
    2075             :   RuntimeCallTimerScope runtimeTimer(
    2076        7030 :       isolate, RuntimeCallCounterId::kRecompileSynchronous);
    2077       21090 :   TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"),
    2078             :                "V8.RecompileSynchronous");
    2079             : 
    2080             :   Handle<SharedFunctionInfo> shared = compilation_info->shared_info();
    2081             : 
    2082             :   // Reset profiler ticks, function is no longer considered hot.
    2083       14060 :   compilation_info->closure()->feedback_vector()->set_profiler_ticks(0);
    2084             : 
    2085             :   DCHECK(!shared->HasBreakInfo());
    2086             : 
    2087             :   // 1) Optimization on the concurrent thread may have failed.
    2088             :   // 2) The function may have already been optimized by OSR.  Simply continue.
    2089             :   //    Except when OSR already disabled optimization for some reason.
    2090             :   // 3) The code may have already been invalidated due to dependency change.
    2091             :   // 4) Code generation may have failed.
    2092        7030 :   if (job->state() == CompilationJob::State::kReadyToFinalize) {
    2093        7030 :     if (shared->optimization_disabled()) {
    2094             :       job->RetryOptimization(BailoutReason::kOptimizationDisabled);
    2095        7030 :     } else if (job->FinalizeJob(isolate) == CompilationJob::SUCCEEDED) {
    2096        6986 :       job->RecordCompilationStats();
    2097             :       job->RecordFunctionCompilation(CodeEventListener::LAZY_COMPILE_TAG,
    2098        6986 :                                      isolate);
    2099        6986 :       InsertCodeIntoOptimizedCodeCache(compilation_info);
    2100        6986 :       if (FLAG_trace_opt) {
    2101           0 :         PrintF("[completed optimizing ");
    2102           0 :         compilation_info->closure()->ShortPrint();
    2103           0 :         PrintF("]\n");
    2104             :       }
    2105        6986 :       compilation_info->closure()->set_code(*compilation_info->code());
    2106        6986 :       return CompilationJob::SUCCEEDED;
    2107             :     }
    2108             :   }
    2109             : 
    2110             :   DCHECK_EQ(job->state(), CompilationJob::State::kFailed);
    2111          44 :   if (FLAG_trace_opt) {
    2112           0 :     PrintF("[aborted optimizing ");
    2113           0 :     compilation_info->closure()->ShortPrint();
    2114             :     PrintF(" because: %s]\n",
    2115           0 :            GetBailoutReason(compilation_info->bailout_reason()));
    2116             :   }
    2117          88 :   compilation_info->closure()->set_code(shared->GetCode());
    2118             :   // Clear the InOptimizationQueue marker, if it exists.
    2119          44 :   if (compilation_info->closure()->IsInOptimizationQueue()) {
    2120          88 :     compilation_info->closure()->ClearOptimizationMarker();
    2121             :   }
    2122             :   return CompilationJob::FAILED;
    2123             : }
    2124             : 
    2125    13099176 : void Compiler::PostInstantiation(Handle<JSFunction> function,
    2126             :                                  PretenureFlag pretenure) {
    2127     3729459 :   Isolate* isolate = function->GetIsolate();
    2128    26198353 :   Handle<SharedFunctionInfo> shared(function->shared(), isolate);
    2129    13099177 :   IsCompiledScope is_compiled_scope(shared->is_compiled_scope());
    2130             : 
    2131             :   // If code is compiled to bytecode (i.e., isn't asm.js), then allocate a
    2132             :   // feedback and check for optimized code.
    2133    22982166 :   if (is_compiled_scope.is_compiled() && shared->HasBytecodeArray()) {
    2134     6253562 :     JSFunction::EnsureFeedbackVector(function);
    2135             : 
    2136    12507117 :     Code code = function->has_feedback_vector()
    2137    12507121 :                     ? function->feedback_vector()->optimized_code()
    2138    12507122 :                     : Code();
    2139     6253558 :     if (!code.is_null()) {
    2140             :       // Caching of optimized code enabled and optimized code found.
    2141             :       DCHECK(!code->marked_for_deoptimization());
    2142             :       DCHECK(function->shared()->is_compiled());
    2143      440653 :       function->set_code(code);
    2144             :     }
    2145             : 
    2146     7199516 :     if (FLAG_always_opt && shared->allows_lazy_compilation() &&
    2147    13652358 :         !shared->optimization_disabled() && !function->IsOptimized() &&
    2148     6453398 :         !function->HasOptimizedCode()) {
    2149      199840 :       function->MarkForOptimization(ConcurrencyMode::kNotConcurrent);
    2150             :     }
    2151             :   }
    2152             : 
    2153    22468956 :   if (shared->is_toplevel() || shared->is_wrapped()) {
    2154             :     // If it's a top-level script, report compilation to the debugger.
    2155     7458919 :     Handle<Script> script(Script::cast(shared->script()), isolate);
    2156     3729459 :     isolate->debug()->OnAfterCompile(script);
    2157             :   }
    2158    13099177 : }
    2159             : 
    2160             : // ----------------------------------------------------------------------------
    2161             : // Implementation of ScriptStreamingData
    2162             : 
    2163       13104 : ScriptStreamingData::ScriptStreamingData(
    2164             :     ScriptCompiler::ExternalSourceStream* source_stream,
    2165             :     ScriptCompiler::StreamedSource::Encoding encoding)
    2166       13104 :     : source_stream(source_stream), encoding(encoding) {}
    2167             : 
    2168             : ScriptStreamingData::~ScriptStreamingData() = default;
    2169             : 
    2170           0 : void ScriptStreamingData::Release() { task.reset(); }
    2171             : 
    2172             : }  // namespace internal
    2173      178779 : }  // namespace v8

Generated by: LCOV version 1.10