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