LCOV - code coverage report
Current view: top level - src - compiler.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 661 735 89.9 %
Date: 2019-01-20 Functions: 65 67 97.0 %

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

Generated by: LCOV version 1.10