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

Generated by: LCOV version 1.10