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/asmjs/asm-js.h"
     11 #include "src/asmjs/asm-typer.h"
     12 #include "src/assembler-inl.h"
     13 #include "src/ast/ast-numbering.h"
     14 #include "src/ast/prettyprinter.h"
     15 #include "src/ast/scopes.h"
     16 #include "src/bootstrapper.h"
     17 #include "src/codegen.h"
     18 #include "src/compilation-cache.h"
     19 #include "src/compiler-dispatcher/compiler-dispatcher.h"
     20 #include "src/compiler-dispatcher/optimizing-compile-dispatcher.h"
     21 #include "src/compiler/pipeline.h"
     22 #include "src/crankshaft/hydrogen.h"
     23 #include "src/debug/debug.h"
     24 #include "src/debug/liveedit.h"
     25 #include "src/frames-inl.h"
     26 #include "src/full-codegen/full-codegen.h"
     27 #include "src/globals.h"
     28 #include "src/heap/heap.h"
     29 #include "src/interpreter/interpreter.h"
     30 #include "src/isolate-inl.h"
     31 #include "src/log-inl.h"
     32 #include "src/messages.h"
     33 #include "src/parsing/parsing.h"
     34 #include "src/parsing/rewriter.h"
     35 #include "src/parsing/scanner-character-streams.h"
     36 #include "src/runtime-profiler.h"
     37 #include "src/snapshot/code-serializer.h"
     38 #include "src/vm-state-inl.h"
     39 
     40 namespace v8 {
     41 namespace internal {
     42 
     43 // A wrapper around a ParseInfo that detaches the parser handles from the
     44 // underlying DeferredHandleScope and stores them in info_ on destruction.
     45 class ParseHandleScope final {
     46  public:
     47   explicit ParseHandleScope(ParseInfo* info)
     48       : deferred_(info->isolate()), info_(info) {}
     49   ~ParseHandleScope() { info_->set_deferred_handles(deferred_.Detach()); }
     50 
     51  private:
     52   DeferredHandleScope deferred_;
     53   ParseInfo* info_;
     54 };
     55 
     56 // A wrapper around a CompilationInfo that detaches the Handles from
     57 // the underlying DeferredHandleScope and stores them in info_ on
     58 // destruction.
     59 class CompilationHandleScope final {
     60  public:
     61   explicit CompilationHandleScope(CompilationInfo* info)
     62       : deferred_(info->isolate()), info_(info) {}
     63   ~CompilationHandleScope() { info_->set_deferred_handles(deferred_.Detach()); }
     64 
     65  private:
     66   DeferredHandleScope deferred_;
     67   CompilationInfo* info_;
     68 };
     69 
     70 // Helper that times a scoped region and records the elapsed time.
     71 struct ScopedTimer {
     72   explicit ScopedTimer(base::TimeDelta* location) : location_(location) {
     73     DCHECK(location_ != NULL);
     74     timer_.Start();
     75   }
     76 
     77   ~ScopedTimer() { *location_ += timer_.Elapsed(); }
     78 
     79   base::ElapsedTimer timer_;
     80   base::TimeDelta* location_;
     81 };
     82 
     83 // ----------------------------------------------------------------------------
     84 // Implementation of CompilationJob
     85 
     86 CompilationJob::CompilationJob(Isolate* isolate, CompilationInfo* info,
     87                                const char* compiler_name, State initial_state)
     88     : info_(info),
     89       isolate_thread_id_(isolate->thread_id()),
     90       compiler_name_(compiler_name),
     91       state_(initial_state),
     92       stack_limit_(isolate->stack_guard()->real_climit()),
     93       executed_on_background_thread_(false) {}
     94 
     95 CompilationJob::Status CompilationJob::PrepareJob() {
     96   DCHECK(ThreadId::Current().Equals(info()->isolate()->thread_id()));
     97   DisallowJavascriptExecution no_js(isolate());
     98 
     99   if (FLAG_trace_opt && info()->IsOptimizing()) {
    100     OFStream os(stdout);
    101     os << "[compiling method " << Brief(*info()->closure()) << " using "
    102        << compiler_name_;
    103     if (info()->is_osr()) os << " OSR";
    104     os << "]" << std::endl;
    105   }
    106 
    107   // Delegate to the underlying implementation.
    108   DCHECK(state() == State::kReadyToPrepare);
    109   ScopedTimer t(&time_taken_to_prepare_);
    110   return UpdateState(PrepareJobImpl(), State::kReadyToExecute);
    111 }
    112 
    113 CompilationJob::Status CompilationJob::ExecuteJob() {
    114   std::unique_ptr<DisallowHeapAllocation> no_allocation;
    115   std::unique_ptr<DisallowHandleAllocation> no_handles;
    116   std::unique_ptr<DisallowHandleDereference> no_deref;
    117   std::unique_ptr<DisallowCodeDependencyChange> no_dependency_change;
    118   if (can_execute_on_background_thread()) {
    119     no_allocation.reset(new DisallowHeapAllocation());
    120     no_handles.reset(new DisallowHandleAllocation());
    121     no_deref.reset(new DisallowHandleDereference());
    122     no_dependency_change.reset(new DisallowCodeDependencyChange());
    123     executed_on_background_thread_ =
    124         !ThreadId::Current().Equals(isolate_thread_id_);
    125   } else {
    126     DCHECK(ThreadId::Current().Equals(isolate_thread_id_));
    127   }
    128 
    129   // Delegate to the underlying implementation.
    130   DCHECK(state() == State::kReadyToExecute);
    131   ScopedTimer t(&time_taken_to_execute_);
    132   return UpdateState(ExecuteJobImpl(), State::kReadyToFinalize);
    133 }
    134 
    135 CompilationJob::Status CompilationJob::FinalizeJob() {
    136   DCHECK(ThreadId::Current().Equals(info()->isolate()->thread_id()));
    137   DisallowCodeDependencyChange no_dependency_change;
    138   DisallowJavascriptExecution no_js(isolate());
    139   DCHECK(!info()->dependencies()->HasAborted());
    140 
    141   // Delegate to the underlying implementation.
    142   DCHECK(state() == State::kReadyToFinalize);
    143   ScopedTimer t(&time_taken_to_finalize_);
    144   return UpdateState(FinalizeJobImpl(), State::kSucceeded);
    145 }
    146 
    147 CompilationJob::Status CompilationJob::RetryOptimization(BailoutReason reason) {
    148   DCHECK(info_->IsOptimizing());
    149   info_->RetryOptimization(reason);
    150   state_ = State::kFailed;
    151   return FAILED;
    152 }
    153 
    154 CompilationJob::Status CompilationJob::AbortOptimization(BailoutReason reason) {
    155   DCHECK(info_->IsOptimizing());
    156   info_->AbortOptimization(reason);
    157   state_ = State::kFailed;
    158   return FAILED;
    159 }
    160 
    161 void CompilationJob::RecordUnoptimizedCompilationStats() const {
    162   int code_size;
    163   if (info()->has_bytecode_array()) {
    164     code_size = info()->bytecode_array()->SizeIncludingMetadata();
    165   } else {
    166     code_size = info()->code()->SizeIncludingMetadata();
    167   }
    168 
    169   Counters* counters = isolate()->counters();
    170   // TODO(4280): Rename counters from "baseline" to "unoptimized" eventually.
    171   counters->total_baseline_code_size()->Increment(code_size);
    172   counters->total_baseline_compile_count()->Increment(1);
    173 
    174   // TODO(5203): Add timers for each phase of compilation.
    175 }
    176 
    177 void CompilationJob::RecordOptimizedCompilationStats() const {
    178   DCHECK(info()->IsOptimizing());
    179   Handle<JSFunction> function = info()->closure();
    180   if (!function->IsOptimized()) {
    181     // Concurrent recompilation and OSR may race.  Increment only once.
    182     int opt_count = function->shared()->opt_count();
    183     function->shared()->set_opt_count(opt_count + 1);
    184   }
    185   double ms_creategraph = time_taken_to_prepare_.InMillisecondsF();
    186   double ms_optimize = time_taken_to_execute_.InMillisecondsF();
    187   double ms_codegen = time_taken_to_finalize_.InMillisecondsF();
    188   if (FLAG_trace_opt) {
    189     PrintF("[optimizing ");
    190     function->ShortPrint();
    191     PrintF(" - took %0.3f, %0.3f, %0.3f ms]\n", ms_creategraph, ms_optimize,
    192            ms_codegen);
    193   }
    194   if (FLAG_trace_opt_stats) {
    195     static double compilation_time = 0.0;
    196     static int compiled_functions = 0;
    197     static int code_size = 0;
    198 
    199     compilation_time += (ms_creategraph + ms_optimize + ms_codegen);
    200     compiled_functions++;
    201     code_size += function->shared()->SourceSize();
    202     PrintF("Compiled: %d functions with %d byte source size in %fms.\n",
    203            compiled_functions, code_size, compilation_time);
    204   }
    205   if (FLAG_hydrogen_stats) {
    206     isolate()->GetHStatistics()->IncrementSubtotals(time_taken_to_prepare_,
    207                                                     time_taken_to_execute_,
    208                                                     time_taken_to_finalize_);
    209   }
    210 }
    211 
    212 Isolate* CompilationJob::isolate() const { return info()->isolate(); }
    213 
    214 namespace {
    215 
    216 void AddWeakObjectToCodeDependency(Isolate* isolate, Handle<HeapObject> object,
    217                                    Handle<Code> code) {
    218   Handle<WeakCell> cell = Code::WeakCellFor(code);
    219   Heap* heap = isolate->heap();
    220   if (heap->InNewSpace(*object)) {
    221     heap->AddWeakNewSpaceObjectToCodeDependency(object, cell);
    222   } else {
    223     Handle<DependentCode> dep(heap->LookupWeakObjectToCodeDependency(object));
    224     dep =
    225         DependentCode::InsertWeakCode(dep, DependentCode::kWeakCodeGroup, cell);
    226     heap->AddWeakObjectToCodeDependency(object, dep);
    227   }
    228 }
    229 
    230 }  // namespace
    231 
    232 void CompilationJob::RegisterWeakObjectsInOptimizedCode(Handle<Code> code) {
    233   // TODO(turbofan): Move this to pipeline.cc once Crankshaft dies.
    234   Isolate* const isolate = code->GetIsolate();
    235   DCHECK(code->is_optimized_code());
    236   std::vector<Handle<Map>> maps;
    237   std::vector<Handle<HeapObject>> objects;
    238   {
    239     DisallowHeapAllocation no_gc;
    240     int const mode_mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT) |
    241                           RelocInfo::ModeMask(RelocInfo::CELL);
    242     for (RelocIterator it(*code, mode_mask); !it.done(); it.next()) {
    243       RelocInfo::Mode mode = it.rinfo()->rmode();
    244       if (mode == RelocInfo::CELL &&
    245           code->IsWeakObjectInOptimizedCode(it.rinfo()->target_cell())) {
    246         objects.push_back(handle(it.rinfo()->target_cell(), isolate));
    247       } else if (mode == RelocInfo::EMBEDDED_OBJECT &&
    248                  code->IsWeakObjectInOptimizedCode(
    249                      it.rinfo()->target_object())) {
    250         Handle<HeapObject> object(HeapObject::cast(it.rinfo()->target_object()),
    251                                   isolate);
    252         if (object->IsMap()) {
    253           maps.push_back(Handle<Map>::cast(object));
    254         } else {
    255           objects.push_back(object);
    256         }
    257       }
    258     }
    259   }
    260   for (Handle<Map> map : maps) {
    261     if (map->dependent_code()->IsEmpty(DependentCode::kWeakCodeGroup)) {
    262       isolate->heap()->AddRetainedMap(map);
    263     }
    264     Map::AddDependentCode(map, DependentCode::kWeakCodeGroup, code);
    265   }
    266   for (Handle<HeapObject> object : objects) {
    267     AddWeakObjectToCodeDependency(isolate, object, code);
    268   }
    269   code->set_can_have_weak_objects(true);
    270 }
    271 
    272 // ----------------------------------------------------------------------------
    273 // Local helper methods that make up the compilation pipeline.
    274 
    275 namespace {
    276 
    277 void RecordFunctionCompilation(CodeEventListener::LogEventsAndTags tag,
    278                                CompilationInfo* info) {
    279   // Log the code generation. If source information is available include
    280   // script name and line number. Check explicitly whether logging is
    281   // enabled as finding the line number is not free.
    282   if (info->isolate()->logger()->is_logging_code_events() ||
    283       info->isolate()->is_profiling()) {
    284     Handle<SharedFunctionInfo> shared = info->shared_info();
    285     Handle<Script> script = info->parse_info()->script();
    286     Handle<AbstractCode> abstract_code =
    287         info->has_bytecode_array()
    288             ? Handle<AbstractCode>::cast(info->bytecode_array())
    289             : Handle<AbstractCode>::cast(info->code());
    290     if (abstract_code.is_identical_to(
    291             info->isolate()->builtins()->CompileLazy())) {
    292       return;
    293     }
    294     int line_num = Script::GetLineNumber(script, shared->start_position()) + 1;
    295     int column_num =
    296         Script::GetColumnNumber(script, shared->start_position()) + 1;
    297     String* script_name = script->name()->IsString()
    298                               ? String::cast(script->name())
    299                               : info->isolate()->heap()->empty_string();
    300     CodeEventListener::LogEventsAndTags log_tag =
    301         Logger::ToNativeByScript(tag, *script);
    302     PROFILE(info->isolate(),
    303             CodeCreateEvent(log_tag, *abstract_code, *shared, script_name,
    304                             line_num, column_num));
    305   }
    306 }
    307 
    308 void EnsureFeedbackMetadata(CompilationInfo* info) {
    309   DCHECK(info->has_shared_info());
    310 
    311   // If no type feedback metadata exists, create it. At this point the
    312   // AstNumbering pass has already run. Note the snapshot can contain outdated
    313   // vectors for a different configuration, hence we also recreate a new vector
    314   // when the function is not compiled (i.e. no code was serialized).
    315 
    316   // TODO(mvstanton): reintroduce is_empty() predicate to feedback_metadata().
    317   if (info->shared_info()->feedback_metadata()->length() == 0 ||
    318       !info->shared_info()->is_compiled()) {
    319     Handle<FeedbackMetadata> feedback_metadata = FeedbackMetadata::New(
    320         info->isolate(), info->literal()->feedback_vector_spec());
    321     info->shared_info()->set_feedback_metadata(*feedback_metadata);
    322   }
    323 
    324   // It's very important that recompiles do not alter the structure of the type
    325   // feedback vector. Verify that the structure fits the function literal.
    326   CHECK(!info->shared_info()->feedback_metadata()->SpecDiffersFrom(
    327       info->literal()->feedback_vector_spec()));
    328 }
    329 
    330 bool UseTurboFan(Handle<SharedFunctionInfo> shared) {
    331   if (shared->optimization_disabled()) {
    332     return false;
    333   }
    334 
    335   bool must_use_ignition_turbo = shared->must_use_ignition_turbo();
    336 
    337   // Check the enabling conditions for Turbofan.
    338   // 1. "use asm" code.
    339   bool is_turbofanable_asm = FLAG_turbo_asm && shared->asm_function();
    340 
    341   // 2. Fallback for features unsupported by Crankshaft.
    342   bool is_unsupported_by_crankshaft_but_turbofanable =
    343       must_use_ignition_turbo && strcmp(FLAG_turbo_filter, "~~") == 0;
    344 
    345   // 3. Explicitly enabled by the command-line filter.
    346   bool passes_turbo_filter = shared->PassesFilter(FLAG_turbo_filter);
    347 
    348   return is_turbofanable_asm || is_unsupported_by_crankshaft_but_turbofanable ||
    349          passes_turbo_filter;
    350 }
    351 
    352 bool ShouldUseIgnition(Handle<SharedFunctionInfo> shared,
    353                        bool marked_as_debug) {
    354   // Code which can't be supported by the old pipeline should use Ignition.
    355   if (shared->must_use_ignition_turbo()) return true;
    356 
    357   // Resumable functions are not supported by {FullCodeGenerator}, suspended
    358   // activations stored as {JSGeneratorObject} on the heap always assume the
    359   // underlying code to be based on the bytecode array.
    360   DCHECK(!IsResumableFunction(shared->kind()));
    361 
    362   // Skip Ignition for asm.js functions.
    363   if (shared->asm_function()) return false;
    364 
    365   // Skip Ignition for asm wasm code.
    366   if (FLAG_validate_asm && shared->HasAsmWasmData()) {
    367     return false;
    368   }
    369 
    370   // When requesting debug code as a replacement for existing code, we provide
    371   // the same kind as the existing code (to prevent implicit tier-change).
    372   if (marked_as_debug && shared->is_compiled()) {
    373     return !shared->HasBaselineCode();
    374   }
    375 
    376   // Code destined for TurboFan should be compiled with Ignition first.
    377   if (UseTurboFan(shared)) return true;
    378 
    379   // Only use Ignition for any other function if FLAG_ignition is true.
    380   return FLAG_ignition;
    381 }
    382 
    383 bool ShouldUseIgnition(CompilationInfo* info) {
    384   DCHECK(info->has_shared_info());
    385   return ShouldUseIgnition(info->shared_info(), info->is_debug());
    386 }
    387 
    388 bool UseAsmWasm(DeclarationScope* scope, Handle<SharedFunctionInfo> shared_info,
    389                 bool is_debug) {
    390   return FLAG_validate_asm && scope->asm_module() &&
    391          !shared_info->is_asm_wasm_broken() && !is_debug;
    392 }
    393 
    394 bool UseCompilerDispatcher(Compiler::ConcurrencyMode inner_function_mode,
    395                            CompilerDispatcher* dispatcher,
    396                            DeclarationScope* scope,
    397                            Handle<SharedFunctionInfo> shared_info,
    398                            bool is_debug, bool will_serialize) {
    399   return FLAG_compiler_dispatcher_eager_inner &&
    400          inner_function_mode == Compiler::CONCURRENT &&
    401          dispatcher->IsEnabled() && !is_debug && !will_serialize &&
    402          !UseAsmWasm(scope, shared_info, is_debug);
    403 }
    404 
    405 CompilationJob* GetUnoptimizedCompilationJob(CompilationInfo* info) {
    406   // Function should have been parsed and analyzed before creating a compilation
    407   // job.
    408   DCHECK_NOT_NULL(info->literal());
    409   DCHECK_NOT_NULL(info->scope());
    410 
    411   if (ShouldUseIgnition(info)) {
    412     return interpreter::Interpreter::NewCompilationJob(info);
    413   } else {
    414     return FullCodeGenerator::NewCompilationJob(info);
    415   }
    416 }
    417 
    418 void InstallSharedScopeInfo(CompilationInfo* info,
    419                             Handle<SharedFunctionInfo> shared) {
    420   Handle<ScopeInfo> scope_info = info->scope()->scope_info();
    421   shared->set_scope_info(*scope_info);
    422   Scope* outer_scope = info->scope()->GetOuterScopeWithContext();
    423   if (outer_scope) {
    424     shared->set_outer_scope_info(*outer_scope->scope_info());
    425   }
    426 }
    427 
    428 void InstallSharedCompilationResult(CompilationInfo* info,
    429                                     Handle<SharedFunctionInfo> shared) {
    430   // TODO(mstarzinger): Compiling for debug code might be used to reveal inner
    431   // functions via {FindSharedFunctionInfoInScript}, in which case we end up
    432   // regenerating existing bytecode. Fix this!
    433   if (info->is_debug() && info->has_bytecode_array()) {
    434     shared->ClearBytecodeArray();
    435   }
    436   DCHECK(!info->code().is_null());
    437   shared->ReplaceCode(*info->code());
    438   if (info->has_bytecode_array()) {
    439     DCHECK(!shared->HasBytecodeArray());  // Only compiled once.
    440     shared->set_bytecode_array(*info->bytecode_array());
    441   }
    442 }
    443 
    444 void InstallUnoptimizedCode(CompilationInfo* info) {
    445   Handle<SharedFunctionInfo> shared = info->shared_info();
    446 
    447   // Update the shared function info with the scope info.
    448   InstallSharedScopeInfo(info, shared);
    449 
    450   // Install compilation result on the shared function info
    451   InstallSharedCompilationResult(info, shared);
    452 }
    453 
    454 CompilationJob::Status FinalizeUnoptimizedCompilationJob(CompilationJob* job) {
    455   CompilationJob::Status status = job->FinalizeJob();
    456   if (status == CompilationJob::SUCCEEDED) {
    457     CompilationInfo* info = job->info();
    458     EnsureFeedbackMetadata(info);
    459     DCHECK(!info->code().is_null());
    460     if (info->parse_info()->literal()->should_be_used_once_hint()) {
    461       info->code()->MarkToBeExecutedOnce(info->isolate());
    462     }
    463     InstallUnoptimizedCode(info);
    464     RecordFunctionCompilation(CodeEventListener::FUNCTION_TAG, info);
    465     job->RecordUnoptimizedCompilationStats();
    466   }
    467   return status;
    468 }
    469 
    470 void SetSharedFunctionFlagsFromLiteral(FunctionLiteral* literal,
    471                                        Handle<SharedFunctionInfo> shared_info) {
    472   shared_info->set_ast_node_count(literal->ast_node_count());
    473   if (literal->dont_optimize_reason() != kNoReason) {
    474     shared_info->DisableOptimization(literal->dont_optimize_reason());
    475   }
    476   if (literal->flags() & AstProperties::kMustUseIgnitionTurbo) {
    477     shared_info->set_must_use_ignition_turbo(true);
    478   }
    479 }
    480 
    481 bool Renumber(ParseInfo* parse_info,
    482               Compiler::EagerInnerFunctionLiterals* eager_literals) {
    483   RuntimeCallTimerScope runtimeTimer(parse_info->isolate(),
    484                                      &RuntimeCallStats::CompileRenumber);
    485   if (!AstNumbering::Renumber(
    486           parse_info->isolate()->stack_guard()->real_climit(),
    487           parse_info->zone(), parse_info->literal(), eager_literals)) {
    488     return false;
    489   }
    490   if (!parse_info->shared_info().is_null()) {
    491     SetSharedFunctionFlagsFromLiteral(parse_info->literal(),
    492                                       parse_info->shared_info());
    493   }
    494   return true;
    495 }
    496 
    497 bool GenerateUnoptimizedCode(CompilationInfo* info) {
    498   if (UseAsmWasm(info->scope(), info->shared_info(), info->is_debug())) {
    499     EnsureFeedbackMetadata(info);
    500     MaybeHandle<FixedArray> wasm_data;
    501     wasm_data = AsmJs::CompileAsmViaWasm(info);
    502     if (!wasm_data.is_null()) {
    503       info->shared_info()->set_asm_wasm_data(*wasm_data.ToHandleChecked());
    504       info->SetCode(info->isolate()->builtins()->InstantiateAsmJs());
    505       InstallUnoptimizedCode(info);
    506       return true;
    507     }
    508   }
    509 
    510   std::unique_ptr<CompilationJob> job(GetUnoptimizedCompilationJob(info));
    511   if (job->PrepareJob() != CompilationJob::SUCCEEDED) return false;
    512   if (job->ExecuteJob() != CompilationJob::SUCCEEDED) return false;
    513   if (FinalizeUnoptimizedCompilationJob(job.get()) !=
    514       CompilationJob::SUCCEEDED) {
    515     return false;
    516   }
    517   return true;
    518 }
    519 
    520 bool CompileUnoptimizedInnerFunctions(
    521     Compiler::EagerInnerFunctionLiterals* literals,
    522     Compiler::ConcurrencyMode inner_function_mode,
    523     std::shared_ptr<Zone> parse_zone, CompilationInfo* outer_info) {
    524   TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"),
    525                "V8.CompileUnoptimizedInnerFunctions");
    526   Isolate* isolate = outer_info->isolate();
    527   Handle<Script> script = outer_info->script();
    528   bool is_debug = outer_info->is_debug();
    529   bool will_serialize = outer_info->will_serialize();
    530   RuntimeCallTimerScope runtimeTimer(isolate,
    531                                      &RuntimeCallStats::CompileInnerFunction);
    532 
    533   for (auto it : *literals) {
    534     FunctionLiteral* literal = it->value();
    535     Handle<SharedFunctionInfo> shared =
    536         Compiler::GetSharedFunctionInfo(literal, script, outer_info);
    537     if (shared->is_compiled()) continue;
    538 
    539     // The {literal} has already been numbered because AstNumbering decends into
    540     // eagerly compiled function literals.
    541     SetSharedFunctionFlagsFromLiteral(literal, shared);
    542 
    543     // Try to enqueue the eager function on the compiler dispatcher.
    544     CompilerDispatcher* dispatcher = isolate->compiler_dispatcher();
    545     if (UseCompilerDispatcher(inner_function_mode, dispatcher, literal->scope(),
    546                               shared, is_debug, will_serialize) &&
    547         dispatcher->EnqueueAndStep(outer_info->script(), shared, literal,
    548                                    parse_zone,
    549                                    outer_info->parse_info()->deferred_handles(),
    550                                    outer_info->deferred_handles())) {
    551       // If we have successfully queued up the function for compilation on the
    552       // compiler dispatcher then we are done.
    553       continue;
    554     } else {
    555       // Otherwise generate unoptimized code now.
    556       ParseInfo parse_info(script);
    557       CompilationInfo info(parse_info.zone(), &parse_info,
    558                            Handle<JSFunction>::null());
    559 
    560       parse_info.set_literal(literal);
    561       parse_info.set_shared_info(shared);
    562       parse_info.set_function_literal_id(shared->function_literal_id());
    563       parse_info.set_language_mode(literal->scope()->language_mode());
    564       parse_info.set_ast_value_factory(
    565           outer_info->parse_info()->ast_value_factory());
    566       parse_info.set_ast_value_factory_owned(false);
    567 
    568       if (will_serialize) info.PrepareForSerializing();
    569       if (is_debug) info.MarkAsDebug();
    570 
    571       if (!GenerateUnoptimizedCode(&info)) {
    572         if (!isolate->has_pending_exception()) isolate->StackOverflow();
    573         return false;
    574       }
    575     }
    576   }
    577   return true;
    578 }
    579 
    580 bool InnerFunctionIsAsmModule(
    581     ThreadedList<ThreadedListZoneEntry<FunctionLiteral*>>* literals) {
    582   for (auto it : *literals) {
    583     FunctionLiteral* literal = it->value();
    584     if (literal->scope()->IsAsmModule()) return true;
    585   }
    586   return false;
    587 }
    588 
    589 bool CompileUnoptimizedCode(CompilationInfo* info,
    590                             Compiler::ConcurrencyMode inner_function_mode) {
    591   Isolate* isolate = info->isolate();
    592   DCHECK(AllowCompilation::IsAllowed(isolate));
    593 
    594   Compiler::EagerInnerFunctionLiterals inner_literals;
    595   {
    596     std::unique_ptr<CompilationHandleScope> compilation_handle_scope;
    597     if (inner_function_mode == Compiler::CONCURRENT) {
    598       compilation_handle_scope.reset(new CompilationHandleScope(info));
    599     }
    600     if (!Compiler::Analyze(info->parse_info(), &inner_literals)) {
    601       if (!isolate->has_pending_exception()) isolate->StackOverflow();
    602       return false;
    603     }
    604   }
    605 
    606   // Disable concurrent inner compilation for asm-wasm code.
    607   // TODO(rmcilroy,bradnelson): Remove this AsmWasm check once the asm-wasm
    608   // builder doesn't do parsing when visiting function declarations.
    609   if (info->scope()->IsAsmModule() ||
    610       InnerFunctionIsAsmModule(&inner_literals)) {
    611     inner_function_mode = Compiler::NOT_CONCURRENT;
    612   }
    613 
    614   std::shared_ptr<Zone> parse_zone;
    615   if (inner_function_mode == Compiler::CONCURRENT) {
    616     // Seal the parse zone so that it can be shared by parallel inner function
    617     // compilation jobs.
    618     DCHECK_NE(info->parse_info()->zone(), info->zone());
    619     parse_zone = info->parse_info()->zone_shared();
    620     parse_zone->Seal();
    621   }
    622 
    623   if (!CompileUnoptimizedInnerFunctions(&inner_literals, inner_function_mode,
    624                                         parse_zone, info) ||
    625       !GenerateUnoptimizedCode(info)) {
    626     if (!isolate->has_pending_exception()) isolate->StackOverflow();
    627     return false;
    628   }
    629 
    630   return true;
    631 }
    632 
    633 void EnsureSharedFunctionInfosArrayOnScript(ParseInfo* info) {
    634   DCHECK(info->is_toplevel());
    635   DCHECK(!info->script().is_null());
    636   if (info->script()->shared_function_infos()->length() > 0) {
    637     DCHECK_EQ(info->script()->shared_function_infos()->length(),
    638               info->max_function_literal_id() + 1);
    639     return;
    640   }
    641   Isolate* isolate = info->isolate();
    642   Handle<FixedArray> infos(
    643       isolate->factory()->NewFixedArray(info->max_function_literal_id() + 1));
    644   info->script()->set_shared_function_infos(*infos);
    645 }
    646 
    647 MUST_USE_RESULT MaybeHandle<Code> GetUnoptimizedCode(
    648     CompilationInfo* info, Compiler::ConcurrencyMode inner_function_mode) {
    649   RuntimeCallTimerScope runtimeTimer(
    650       info->isolate(), &RuntimeCallStats::CompileGetUnoptimizedCode);
    651   VMState<COMPILER> state(info->isolate());
    652   PostponeInterruptsScope postpone(info->isolate());
    653 
    654   // Parse and update ParseInfo with the results.
    655   {
    656     if (!parsing::ParseAny(info->parse_info(),
    657                            inner_function_mode != Compiler::CONCURRENT)) {
    658       return MaybeHandle<Code>();
    659     }
    660 
    661     if (inner_function_mode == Compiler::CONCURRENT) {
    662       ParseHandleScope parse_handles(info->parse_info());
    663       info->parse_info()->ReopenHandlesInNewHandleScope();
    664       info->parse_info()->ast_value_factory()->Internalize(info->isolate());
    665     }
    666   }
    667 
    668   if (info->parse_info()->is_toplevel()) {
    669     EnsureSharedFunctionInfosArrayOnScript(info->parse_info());
    670   }
    671   DCHECK_EQ(info->shared_info()->language_mode(),
    672             info->literal()->language_mode());
    673 
    674   // Compile either unoptimized code or bytecode for the interpreter.
    675   if (!CompileUnoptimizedCode(info, inner_function_mode)) {
    676     return MaybeHandle<Code>();
    677   }
    678 
    679   // Record the function compilation event.
    680   RecordFunctionCompilation(CodeEventListener::LAZY_COMPILE_TAG, info);
    681 
    682   return info->code();
    683 }
    684 
    685 MUST_USE_RESULT MaybeHandle<Code> GetCodeFromOptimizedCodeMap(
    686     Handle<JSFunction> function, BailoutId osr_ast_id) {
    687   RuntimeCallTimerScope runtimeTimer(
    688       function->GetIsolate(),
    689       &RuntimeCallStats::CompileGetFromOptimizedCodeMap);
    690   Handle<SharedFunctionInfo> shared(function->shared());
    691   DisallowHeapAllocation no_gc;
    692   Code* code = shared->SearchOptimizedCodeMap(
    693       function->context()->native_context(), osr_ast_id);
    694   if (code != nullptr) {
    695     // Caching of optimized code enabled and optimized code found.
    696     DCHECK(!code->marked_for_deoptimization());
    697     DCHECK(function->shared()->is_compiled());
    698     return Handle<Code>(code);
    699   }
    700   return MaybeHandle<Code>();
    701 }
    702 
    703 void InsertCodeIntoOptimizedCodeMap(CompilationInfo* info) {
    704   Handle<Code> code = info->code();
    705   if (code->kind() != Code::OPTIMIZED_FUNCTION) return;  // Nothing to do.
    706 
    707   // Function context specialization folds-in the function context,
    708   // so no sharing can occur.
    709   if (info->is_function_context_specializing()) return;
    710   // Frame specialization implies function context specialization.
    711   DCHECK(!info->is_frame_specializing());
    712 
    713   // TODO(4764): When compiling for OSR from bytecode, BailoutId might derive
    714   // from bytecode offset and overlap with actual BailoutId. No caching!
    715   if (info->is_osr() && info->is_optimizing_from_bytecode()) return;
    716 
    717   // Cache optimized context-specific code.
    718   Handle<JSFunction> function = info->closure();
    719   Handle<SharedFunctionInfo> shared(function->shared());
    720   Handle<Context> native_context(function->context()->native_context());
    721   SharedFunctionInfo::AddToOptimizedCodeMap(shared, native_context, code,
    722                                             info->osr_ast_id());
    723 }
    724 
    725 bool GetOptimizedCodeNow(CompilationJob* job) {
    726   CompilationInfo* info = job->info();
    727   Isolate* isolate = info->isolate();
    728 
    729   // Parsing is not required when optimizing from existing bytecode.
    730   if (!info->is_optimizing_from_bytecode()) {
    731     if (!Compiler::ParseAndAnalyze(info->parse_info())) return false;
    732     EnsureFeedbackMetadata(info);
    733   }
    734 
    735   JSFunction::EnsureLiterals(info->closure());
    736 
    737   TimerEventScope<TimerEventRecompileSynchronous> timer(isolate);
    738   RuntimeCallTimerScope runtimeTimer(isolate,
    739                                      &RuntimeCallStats::RecompileSynchronous);
    740   TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"),
    741                "V8.RecompileSynchronous");
    742 
    743   if (job->PrepareJob() != CompilationJob::SUCCEEDED ||
    744       job->ExecuteJob() != CompilationJob::SUCCEEDED ||
    745       job->FinalizeJob() != CompilationJob::SUCCEEDED) {
    746     if (FLAG_trace_opt) {
    747       PrintF("[aborted optimizing ");
    748       info->closure()->ShortPrint();
    749       PrintF(" because: %s]\n", GetBailoutReason(info->bailout_reason()));
    750     }
    751     return false;
    752   }
    753 
    754   // Success!
    755   job->RecordOptimizedCompilationStats();
    756   DCHECK(!isolate->has_pending_exception());
    757   InsertCodeIntoOptimizedCodeMap(info);
    758   RecordFunctionCompilation(CodeEventListener::LAZY_COMPILE_TAG, info);
    759   return true;
    760 }
    761 
    762 bool GetOptimizedCodeLater(CompilationJob* job) {
    763   CompilationInfo* info = job->info();
    764   Isolate* isolate = info->isolate();
    765 
    766   if (!isolate->optimizing_compile_dispatcher()->IsQueueAvailable()) {
    767     if (FLAG_trace_concurrent_recompilation) {
    768       PrintF("  ** Compilation queue full, will retry optimizing ");
    769       info->closure()->ShortPrint();
    770       PrintF(" later.\n");
    771     }
    772     return false;
    773   }
    774 
    775   if (isolate->heap()->HighMemoryPressure()) {
    776     if (FLAG_trace_concurrent_recompilation) {
    777       PrintF("  ** High memory pressure, will retry optimizing ");
    778       info->closure()->ShortPrint();
    779       PrintF(" later.\n");
    780     }
    781     return false;
    782   }
    783 
    784   // Parsing is not required when optimizing from existing bytecode.
    785   if (!info->is_optimizing_from_bytecode()) {
    786     if (!Compiler::ParseAndAnalyze(info->parse_info())) return false;
    787     EnsureFeedbackMetadata(info);
    788   }
    789 
    790   JSFunction::EnsureLiterals(info->closure());
    791 
    792   TimerEventScope<TimerEventRecompileSynchronous> timer(info->isolate());
    793   RuntimeCallTimerScope runtimeTimer(info->isolate(),
    794                                      &RuntimeCallStats::RecompileSynchronous);
    795   TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"),
    796                "V8.RecompileSynchronous");
    797 
    798   if (job->PrepareJob() != CompilationJob::SUCCEEDED) return false;
    799   isolate->optimizing_compile_dispatcher()->QueueForOptimization(job);
    800 
    801   if (FLAG_trace_concurrent_recompilation) {
    802     PrintF("  ** Queued ");
    803     info->closure()->ShortPrint();
    804     PrintF(" for concurrent optimization.\n");
    805   }
    806   return true;
    807 }
    808 
    809 MaybeHandle<Code> GetOptimizedCode(Handle<JSFunction> function,
    810                                    Compiler::ConcurrencyMode mode,
    811                                    BailoutId osr_ast_id = BailoutId::None(),
    812                                    JavaScriptFrame* osr_frame = nullptr) {
    813   Isolate* isolate = function->GetIsolate();
    814   Handle<SharedFunctionInfo> shared(function->shared(), isolate);
    815 
    816   bool ignition_osr = osr_frame && osr_frame->is_interpreted();
    817   DCHECK_IMPLIES(ignition_osr, !osr_ast_id.IsNone());
    818   DCHECK_IMPLIES(ignition_osr, FLAG_ignition_osr);
    819 
    820   // Shared function no longer needs to be tiered up
    821   shared->set_marked_for_tier_up(false);
    822 
    823   Handle<Code> cached_code;
    824   // TODO(4764): When compiling for OSR from bytecode, BailoutId might derive
    825   // from bytecode offset and overlap with actual BailoutId. No lookup!
    826   if (!ignition_osr &&
    827       GetCodeFromOptimizedCodeMap(function, osr_ast_id)
    828           .ToHandle(&cached_code)) {
    829     if (FLAG_trace_opt) {
    830       PrintF("[found optimized code for ");
    831       function->ShortPrint();
    832       if (!osr_ast_id.IsNone()) {
    833         PrintF(" at OSR AST id %d", osr_ast_id.ToInt());
    834       }
    835       PrintF("]\n");
    836     }
    837     return cached_code;
    838   }
    839 
    840   // Reset profiler ticks, function is no longer considered hot.
    841   DCHECK(shared->is_compiled());
    842   if (shared->HasBaselineCode()) {
    843     shared->code()->set_profiler_ticks(0);
    844   } else if (shared->HasBytecodeArray()) {
    845     shared->set_profiler_ticks(0);
    846   }
    847 
    848   VMState<COMPILER> state(isolate);
    849   DCHECK(!isolate->has_pending_exception());
    850   PostponeInterruptsScope postpone(isolate);
    851   bool use_turbofan = UseTurboFan(shared) || ignition_osr;
    852   bool has_script = shared->script()->IsScript();
    853   // BUG(5946): This DCHECK is necessary to make certain that we won't tolerate
    854   // the lack of a script without bytecode.
    855   DCHECK_IMPLIES(!has_script, ShouldUseIgnition(shared, false));
    856   std::unique_ptr<CompilationJob> job(
    857       use_turbofan ? compiler::Pipeline::NewCompilationJob(function, has_script)
    858                    : new HCompilationJob(function));
    859   CompilationInfo* info = job->info();
    860   ParseInfo* parse_info = info->parse_info();
    861 
    862   info->SetOptimizingForOsr(osr_ast_id, osr_frame);
    863 
    864   // Do not use Crankshaft/TurboFan if we need to be able to set break points.
    865   if (info->shared_info()->HasDebugInfo()) {
    866     info->AbortOptimization(kFunctionBeingDebugged);
    867     return MaybeHandle<Code>();
    868   }
    869 
    870   // Limit the number of times we try to optimize functions.
    871   const int kMaxOptCount =
    872       FLAG_deopt_every_n_times == 0 ? FLAG_max_opt_count : 1000;
    873   if (info->shared_info()->opt_count() > kMaxOptCount) {
    874     info->AbortOptimization(kDeoptimizedTooManyTimes);
    875     return MaybeHandle<Code>();
    876   }
    877 
    878   TimerEventScope<TimerEventOptimizeCode> optimize_code_timer(isolate);
    879   RuntimeCallTimerScope runtimeTimer(isolate, &RuntimeCallStats::OptimizeCode);
    880   TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.OptimizeCode");
    881 
    882   // TurboFan can optimize directly from existing bytecode.
    883   if (use_turbofan && ShouldUseIgnition(info)) {
    884     if (info->is_osr() && !ignition_osr) return MaybeHandle<Code>();
    885     DCHECK(shared->HasBytecodeArray());
    886     info->MarkAsOptimizeFromBytecode();
    887   }
    888 
    889   // Verify that OSR compilations are delegated to the correct graph builder.
    890   // Depending on the underlying frame the semantics of the {BailoutId} differ
    891   // and the various graph builders hard-code a certain semantic:
    892   //  - Interpreter : The BailoutId represents a bytecode offset.
    893   //  - FullCodegen : The BailoutId represents the id of an AST node.
    894   DCHECK_IMPLIES(info->is_osr() && ignition_osr,
    895                  info->is_optimizing_from_bytecode());
    896   DCHECK_IMPLIES(info->is_osr() && !ignition_osr,
    897                  !info->is_optimizing_from_bytecode());
    898 
    899   // In case of concurrent recompilation, all handles below this point will be
    900   // allocated in a deferred handle scope that is detached and handed off to
    901   // the background thread when we return.
    902   std::unique_ptr<CompilationHandleScope> compilation;
    903   if (mode == Compiler::CONCURRENT) {
    904     compilation.reset(new CompilationHandleScope(info));
    905   }
    906 
    907   // In case of TurboFan, all handles below will be canonicalized.
    908   std::unique_ptr<CanonicalHandleScope> canonical;
    909   if (use_turbofan) canonical.reset(new CanonicalHandleScope(info->isolate()));
    910 
    911   // Reopen handles in the new CompilationHandleScope.
    912   info->ReopenHandlesInNewHandleScope();
    913   parse_info->ReopenHandlesInNewHandleScope();
    914 
    915   if (mode == Compiler::CONCURRENT) {
    916     if (GetOptimizedCodeLater(job.get())) {
    917       job.release();  // The background recompile job owns this now.
    918       return isolate->builtins()->InOptimizationQueue();
    919     }
    920   } else {
    921     if (GetOptimizedCodeNow(job.get())) return info->code();
    922   }
    923 
    924   if (isolate->has_pending_exception()) isolate->clear_pending_exception();
    925   return MaybeHandle<Code>();
    926 }
    927 
    928 CompilationJob::Status FinalizeOptimizedCompilationJob(CompilationJob* job) {
    929   CompilationInfo* info = job->info();
    930   Isolate* isolate = info->isolate();
    931 
    932   TimerEventScope<TimerEventRecompileSynchronous> timer(info->isolate());
    933   RuntimeCallTimerScope runtimeTimer(isolate,
    934                                      &RuntimeCallStats::RecompileSynchronous);
    935   TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"),
    936                "V8.RecompileSynchronous");
    937 
    938   Handle<SharedFunctionInfo> shared = info->shared_info();
    939 
    940   // Reset profiler ticks, function is no longer considered hot.
    941   if (shared->HasBaselineCode()) {
    942     shared->code()->set_profiler_ticks(0);
    943   } else if (shared->HasBytecodeArray()) {
    944     shared->set_profiler_ticks(0);
    945   }
    946 
    947   DCHECK(!shared->HasDebugInfo());
    948 
    949   // 1) Optimization on the concurrent thread may have failed.
    950   // 2) The function may have already been optimized by OSR.  Simply continue.
    951   //    Except when OSR already disabled optimization for some reason.
    952   // 3) The code may have already been invalidated due to dependency change.
    953   // 4) Code generation may have failed.
    954   if (job->state() == CompilationJob::State::kReadyToFinalize) {
    955     if (shared->optimization_disabled()) {
    956       job->RetryOptimization(kOptimizationDisabled);
    957     } else if (info->dependencies()->HasAborted()) {
    958       job->RetryOptimization(kBailedOutDueToDependencyChange);
    959     } else if (job->FinalizeJob() == CompilationJob::SUCCEEDED) {
    960       job->RecordOptimizedCompilationStats();
    961       RecordFunctionCompilation(CodeEventListener::LAZY_COMPILE_TAG, info);
    962       if (shared->SearchOptimizedCodeMap(info->context()->native_context(),
    963                                          info->osr_ast_id()) == nullptr) {
    964         InsertCodeIntoOptimizedCodeMap(info);
    965       }
    966       if (FLAG_trace_opt) {
    967         PrintF("[completed optimizing ");
    968         info->closure()->ShortPrint();
    969         PrintF("]\n");
    970       }
    971       info->closure()->ReplaceCode(*info->code());
    972       return CompilationJob::SUCCEEDED;
    973     }
    974   }
    975 
    976   DCHECK(job->state() == CompilationJob::State::kFailed);
    977   if (FLAG_trace_opt) {
    978     PrintF("[aborted optimizing ");
    979     info->closure()->ShortPrint();
    980     PrintF(" because: %s]\n", GetBailoutReason(info->bailout_reason()));
    981   }
    982   info->closure()->ReplaceCode(shared->code());
    983   return CompilationJob::FAILED;
    984 }
    985 
    986 MaybeHandle<Code> GetBaselineCode(Handle<JSFunction> function) {
    987   Isolate* isolate = function->GetIsolate();
    988   VMState<COMPILER> state(isolate);
    989   PostponeInterruptsScope postpone(isolate);
    990   ParseInfo parse_info(handle(function->shared()));
    991   CompilationInfo info(parse_info.zone(), &parse_info, function);
    992 
    993   DCHECK(function->shared()->is_compiled());
    994 
    995   // Function no longer needs to be tiered up
    996   function->shared()->set_marked_for_tier_up(false);
    997 
    998   // Reset profiler ticks, function is no longer considered hot.
    999   if (function->shared()->HasBytecodeArray()) {
   1000     function->shared()->set_profiler_ticks(0);
   1001   }
   1002 
   1003   // Nothing left to do if the function already has baseline code.
   1004   if (function->shared()->code()->kind() == Code::FUNCTION) {
   1005     return Handle<Code>(function->shared()->code());
   1006   }
   1007 
   1008   // We do not switch to baseline code when the debugger might have created a
   1009   // copy of the bytecode with break slots to be able to set break points.
   1010   if (function->shared()->HasDebugInfo()) {
   1011     return MaybeHandle<Code>();
   1012   }
   1013 
   1014   // Don't generate full-codegen code for functions it can't support.
   1015   if (function->shared()->must_use_ignition_turbo()) {
   1016     return MaybeHandle<Code>();
   1017   }
   1018   DCHECK(!IsResumableFunction(function->shared()->kind()));
   1019 
   1020   if (FLAG_trace_opt) {
   1021     OFStream os(stdout);
   1022     os << "[switching method " << Brief(*function) << " to baseline code]"
   1023        << std::endl;
   1024   }
   1025 
   1026   // Parse and update CompilationInfo with the results.
   1027   if (!parsing::ParseFunction(info.parse_info())) return MaybeHandle<Code>();
   1028   Handle<SharedFunctionInfo> shared = info.shared_info();
   1029   DCHECK_EQ(shared->language_mode(), info.literal()->language_mode());
   1030 
   1031   // Compile baseline code using the full code generator.
   1032   if (!Compiler::Analyze(info.parse_info()) ||
   1033       !FullCodeGenerator::MakeCode(&info)) {
   1034     if (!isolate->has_pending_exception()) isolate->StackOverflow();
   1035     return MaybeHandle<Code>();
   1036   }
   1037 
   1038   // Update the shared function info with the scope info.
   1039   InstallSharedScopeInfo(&info, shared);
   1040 
   1041   // Install compilation result on the shared function info
   1042   InstallSharedCompilationResult(&info, shared);
   1043 
   1044   // Record the function compilation event.
   1045   RecordFunctionCompilation(CodeEventListener::LAZY_COMPILE_TAG, &info);
   1046 
   1047   return info.code();
   1048 }
   1049 
   1050 MaybeHandle<Code> GetLazyCode(Handle<JSFunction> function) {
   1051   Isolate* isolate = function->GetIsolate();
   1052   DCHECK(!isolate->has_pending_exception());
   1053   DCHECK(!function->is_compiled());
   1054   TimerEventScope<TimerEventCompileCode> compile_timer(isolate);
   1055   RuntimeCallTimerScope runtimeTimer(isolate,
   1056                                      &RuntimeCallStats::CompileFunction);
   1057   TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.CompileCode");
   1058   AggregatedHistogramTimerScope timer(isolate->counters()->compile_lazy());
   1059 
   1060   Handle<Code> cached_code;
   1061   if (GetCodeFromOptimizedCodeMap(function, BailoutId::None())
   1062           .ToHandle(&cached_code)) {
   1063     if (FLAG_trace_opt) {
   1064       PrintF("[found optimized code for ");
   1065       function->ShortPrint();
   1066       PrintF(" during unoptimized compile]\n");
   1067     }
   1068     DCHECK(function->shared()->is_compiled());
   1069     return cached_code;
   1070   }
   1071 
   1072   if (function->shared()->is_compiled() &&
   1073       function->shared()->marked_for_tier_up()) {
   1074     DCHECK(FLAG_mark_shared_functions_for_tier_up);
   1075 
   1076     function->shared()->set_marked_for_tier_up(false);
   1077 
   1078     switch (Compiler::NextCompilationTier(*function)) {
   1079       case Compiler::BASELINE: {
   1080         // We don't try to handle baseline here because GetBaselineCode()
   1081         // doesn't handle top-level code. We aren't supporting
   1082         // the hybrid pipeline going forward (where Ignition is a first
   1083         // tier followed by full-code).
   1084         break;
   1085       }
   1086       case Compiler::OPTIMIZED: {
   1087         if (FLAG_trace_opt) {
   1088           PrintF("[optimizing method ");
   1089           function->ShortPrint();
   1090           PrintF(" eagerly (shared function marked for tier up)]\n");
   1091         }
   1092 
   1093         Handle<Code> code;
   1094         // TODO(leszeks): Look into performing this compilation concurrently.
   1095         if (GetOptimizedCode(function, Compiler::NOT_CONCURRENT)
   1096                 .ToHandle(&code)) {
   1097           return code;
   1098         }
   1099         break;
   1100       }
   1101       default:
   1102         UNREACHABLE();
   1103     }
   1104   }
   1105 
   1106   if (function->shared()->is_compiled()) {
   1107     return Handle<Code>(function->shared()->code());
   1108   }
   1109 
   1110   if (function->shared()->HasBytecodeArray()) {
   1111     Handle<Code> entry = isolate->builtins()->InterpreterEntryTrampoline();
   1112     function->shared()->ReplaceCode(*entry);
   1113     return entry;
   1114   }
   1115 
   1116   ParseInfo parse_info(handle(function->shared()));
   1117   Zone compile_zone(isolate->allocator(), ZONE_NAME);
   1118   CompilationInfo info(&compile_zone, &parse_info, function);
   1119   Handle<Code> result;
   1120   ASSIGN_RETURN_ON_EXCEPTION(
   1121       isolate, result, GetUnoptimizedCode(&info, Compiler::CONCURRENT), Code);
   1122 
   1123   if (FLAG_always_opt && !info.shared_info()->HasAsmWasmData()) {
   1124     Handle<Code> opt_code;
   1125     if (GetOptimizedCode(function, Compiler::NOT_CONCURRENT)
   1126             .ToHandle(&opt_code)) {
   1127       result = opt_code;
   1128     }
   1129   }
   1130 
   1131   return result;
   1132 }
   1133 
   1134 
   1135 Handle<SharedFunctionInfo> CompileToplevel(CompilationInfo* info) {
   1136   Isolate* isolate = info->isolate();
   1137   TimerEventScope<TimerEventCompileCode> timer(isolate);
   1138   TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.CompileCode");
   1139   PostponeInterruptsScope postpone(isolate);
   1140   DCHECK(!isolate->native_context().is_null());
   1141   ParseInfo* parse_info = info->parse_info();
   1142 
   1143   RuntimeCallTimerScope runtimeTimer(
   1144       isolate, parse_info->is_eval() ? &RuntimeCallStats::CompileEval
   1145                                      : &RuntimeCallStats::CompileScript);
   1146 
   1147   Handle<Script> script = parse_info->script();
   1148 
   1149   // TODO(svenpanne) Obscure place for this, perhaps move to OnBeforeCompile?
   1150   FixedArray* array = isolate->native_context()->embedder_data();
   1151   script->set_context_data(array->get(v8::Context::kDebugIdIndex));
   1152 
   1153   Handle<SharedFunctionInfo> result;
   1154 
   1155   { VMState<COMPILER> state(info->isolate());
   1156     if (parse_info->literal() == nullptr) {
   1157       if (!parsing::ParseProgram(parse_info, false)) {
   1158         return Handle<SharedFunctionInfo>::null();
   1159       }
   1160 
   1161       {
   1162         ParseHandleScope parse_handles(parse_info);
   1163         parse_info->ReopenHandlesInNewHandleScope();
   1164         parse_info->ast_value_factory()->Internalize(info->isolate());
   1165       }
   1166     }
   1167 
   1168     EnsureSharedFunctionInfosArrayOnScript(parse_info);
   1169 
   1170     // Measure how long it takes to do the compilation; only take the
   1171     // rest of the function into account to avoid overlap with the
   1172     // parsing statistics.
   1173     HistogramTimer* rate = parse_info->is_eval()
   1174                                ? info->isolate()->counters()->compile_eval()
   1175                                : info->isolate()->counters()->compile();
   1176     HistogramTimerScope timer(rate);
   1177     TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"),
   1178                  parse_info->is_eval() ? "V8.CompileEval" : "V8.Compile");
   1179 
   1180     // Allocate a shared function info object.
   1181     FunctionLiteral* lit = parse_info->literal();
   1182     DCHECK_EQ(kNoSourcePosition, lit->function_token_position());
   1183     result = isolate->factory()->NewSharedFunctionInfoForLiteral(lit, script);
   1184     result->set_is_toplevel(true);
   1185     parse_info->set_shared_info(result);
   1186     parse_info->set_function_literal_id(result->function_literal_id());
   1187 
   1188     // Compile the code.
   1189     if (!CompileUnoptimizedCode(info, Compiler::CONCURRENT)) {
   1190       return Handle<SharedFunctionInfo>::null();
   1191     }
   1192 
   1193     Handle<String> script_name =
   1194         script->name()->IsString()
   1195             ? Handle<String>(String::cast(script->name()))
   1196             : isolate->factory()->empty_string();
   1197     CodeEventListener::LogEventsAndTags log_tag =
   1198         parse_info->is_eval()
   1199             ? CodeEventListener::EVAL_TAG
   1200             : Logger::ToNativeByScript(CodeEventListener::SCRIPT_TAG, *script);
   1201 
   1202     PROFILE(isolate, CodeCreateEvent(log_tag, result->abstract_code(), *result,
   1203                                      *script_name));
   1204 
   1205     if (!script.is_null())
   1206       script->set_compilation_state(Script::COMPILATION_STATE_COMPILED);
   1207   }
   1208 
   1209   return result;
   1210 }
   1211 
   1212 }  // namespace
   1213 
   1214 // ----------------------------------------------------------------------------
   1215 // Implementation of Compiler
   1216 
   1217 bool Compiler::Analyze(ParseInfo* info,
   1218                        EagerInnerFunctionLiterals* eager_literals) {
   1219   DCHECK_NOT_NULL(info->literal());
   1220   RuntimeCallTimerScope runtimeTimer(info->isolate(),
   1221                                      &RuntimeCallStats::CompileAnalyse);
   1222   if (!Rewriter::Rewrite(info)) return false;
   1223   DeclarationScope::Analyze(info, AnalyzeMode::kRegular);
   1224   if (!Renumber(info, eager_literals)) {
   1225     return false;
   1226   }
   1227   DCHECK_NOT_NULL(info->scope());
   1228   return true;
   1229 }
   1230 
   1231 bool Compiler::ParseAndAnalyze(ParseInfo* info) {
   1232   if (!parsing::ParseAny(info)) return false;
   1233   if (info->is_toplevel()) EnsureSharedFunctionInfosArrayOnScript(info);
   1234   if (!Compiler::Analyze(info)) return false;
   1235   DCHECK_NOT_NULL(info->literal());
   1236   DCHECK_NOT_NULL(info->scope());
   1237   return true;
   1238 }
   1239 
   1240 bool Compiler::Compile(Handle<JSFunction> function, ClearExceptionFlag flag) {
   1241   if (function->is_compiled()) return true;
   1242   Isolate* isolate = function->GetIsolate();
   1243   DCHECK(AllowCompilation::IsAllowed(isolate));
   1244 
   1245   CompilerDispatcher* dispatcher = isolate->compiler_dispatcher();
   1246   Handle<SharedFunctionInfo> shared(function->shared(), isolate);
   1247   Handle<Code> code;
   1248   if (dispatcher->IsEnqueued(shared)) {
   1249     if (!dispatcher->FinishNow(shared)) {
   1250       if (flag == CLEAR_EXCEPTION) {
   1251         isolate->clear_pending_exception();
   1252       }
   1253       return false;
   1254     }
   1255     code = handle(shared->code(), isolate);
   1256   } else {
   1257     // Start a compilation.
   1258     if (!GetLazyCode(function).ToHandle(&code)) {
   1259       if (flag == CLEAR_EXCEPTION) {
   1260         isolate->clear_pending_exception();
   1261       }
   1262       return false;
   1263     }
   1264   }
   1265 
   1266   // Install code on closure.
   1267   function->ReplaceCode(*code);
   1268   JSFunction::EnsureLiterals(function);
   1269 
   1270   // Check postconditions on success.
   1271   DCHECK(!isolate->has_pending_exception());
   1272   DCHECK(function->shared()->is_compiled());
   1273   DCHECK(function->is_compiled());
   1274   return true;
   1275 }
   1276 
   1277 bool Compiler::CompileBaseline(Handle<JSFunction> function) {
   1278   Isolate* isolate = function->GetIsolate();
   1279   DCHECK(AllowCompilation::IsAllowed(isolate));
   1280 
   1281   // Start a compilation.
   1282   Handle<Code> code;
   1283   if (!GetBaselineCode(function).ToHandle(&code)) {
   1284     // Baseline generation failed, get unoptimized code.
   1285     DCHECK(function->shared()->is_compiled());
   1286     code = handle(function->shared()->code());
   1287     isolate->clear_pending_exception();
   1288   }
   1289 
   1290   // Install code on closure.
   1291   function->ReplaceCode(*code);
   1292   JSFunction::EnsureLiterals(function);
   1293 
   1294   // Check postconditions on success.
   1295   DCHECK(!isolate->has_pending_exception());
   1296   DCHECK(function->shared()->is_compiled());
   1297   DCHECK(function->is_compiled());
   1298   return true;
   1299 }
   1300 
   1301 bool Compiler::CompileOptimized(Handle<JSFunction> function,
   1302                                 ConcurrencyMode mode) {
   1303   if (function->IsOptimized()) return true;
   1304   Isolate* isolate = function->GetIsolate();
   1305   DCHECK(AllowCompilation::IsAllowed(isolate));
   1306 
   1307   // Start a compilation.
   1308   Handle<Code> code;
   1309   if (!GetOptimizedCode(function, mode).ToHandle(&code)) {
   1310     // Optimization failed, get unoptimized code. Unoptimized code must exist
   1311     // already if we are optimizing.
   1312     DCHECK(!isolate->has_pending_exception());
   1313     DCHECK(function->shared()->is_compiled());
   1314     code = handle(function->shared()->code(), isolate);
   1315   }
   1316 
   1317   // Install code on closure.
   1318   function->ReplaceCode(*code);
   1319   JSFunction::EnsureLiterals(function);
   1320 
   1321   // Check postconditions on success.
   1322   DCHECK(!isolate->has_pending_exception());
   1323   DCHECK(function->shared()->is_compiled());
   1324   DCHECK(function->is_compiled());
   1325   return true;
   1326 }
   1327 
   1328 bool Compiler::CompileDebugCode(Handle<SharedFunctionInfo> shared) {
   1329   Isolate* isolate = shared->GetIsolate();
   1330   DCHECK(AllowCompilation::IsAllowed(isolate));
   1331 
   1332   // Start a compilation.
   1333   ParseInfo parse_info(shared);
   1334   CompilationInfo info(parse_info.zone(), &parse_info,
   1335                        Handle<JSFunction>::null());
   1336   info.MarkAsDebug();
   1337   if (GetUnoptimizedCode(&info, Compiler::NOT_CONCURRENT).is_null()) {
   1338     isolate->clear_pending_exception();
   1339     return false;
   1340   }
   1341 
   1342   // Check postconditions on success.
   1343   DCHECK(!isolate->has_pending_exception());
   1344   DCHECK(shared->is_compiled());
   1345   DCHECK(shared->HasDebugCode());
   1346   return true;
   1347 }
   1348 
   1349 MaybeHandle<JSArray> Compiler::CompileForLiveEdit(Handle<Script> script) {
   1350   Isolate* isolate = script->GetIsolate();
   1351   DCHECK(AllowCompilation::IsAllowed(isolate));
   1352 
   1353   // In order to ensure that live edit function info collection finds the newly
   1354   // generated shared function infos, clear the script's list temporarily
   1355   // and restore it at the end of this method.
   1356   Handle<FixedArray> old_function_infos(script->shared_function_infos(),
   1357                                         isolate);
   1358   script->set_shared_function_infos(isolate->heap()->empty_fixed_array());
   1359 
   1360   // Start a compilation.
   1361   ParseInfo parse_info(script);
   1362   Zone compile_zone(isolate->allocator(), ZONE_NAME);
   1363   CompilationInfo info(&compile_zone, &parse_info, Handle<JSFunction>::null());
   1364   info.MarkAsDebug();
   1365 
   1366   // TODO(635): support extensions.
   1367   const bool compilation_succeeded = !CompileToplevel(&info).is_null();
   1368   Handle<JSArray> infos;
   1369   if (compilation_succeeded) {
   1370     // Check postconditions on success.
   1371     DCHECK(!isolate->has_pending_exception());
   1372     infos = LiveEditFunctionTracker::Collect(parse_info.literal(), script,
   1373                                              parse_info.zone(), isolate);
   1374   }
   1375 
   1376   // Restore the original function info list in order to remain side-effect
   1377   // free as much as possible, since some code expects the old shared function
   1378   // infos to stick around.
   1379   script->set_shared_function_infos(*old_function_infos);
   1380 
   1381   return infos;
   1382 }
   1383 
   1384 bool Compiler::EnsureBytecode(CompilationInfo* info) {
   1385   if (!info->shared_info()->is_compiled()) {
   1386     CompilerDispatcher* dispatcher = info->isolate()->compiler_dispatcher();
   1387     if (dispatcher->IsEnqueued(info->shared_info())) {
   1388       if (!dispatcher->FinishNow(info->shared_info())) return false;
   1389     } else if (GetUnoptimizedCode(info, Compiler::NOT_CONCURRENT).is_null()) {
   1390       return false;
   1391     }
   1392   }
   1393   DCHECK(info->shared_info()->is_compiled());
   1394 
   1395   if (info->shared_info()->HasAsmWasmData()) return false;
   1396 
   1397   DCHECK_EQ(ShouldUseIgnition(info), info->shared_info()->HasBytecodeArray());
   1398   return info->shared_info()->HasBytecodeArray();
   1399 }
   1400 
   1401 // TODO(turbofan): In the future, unoptimized code with deopt support could
   1402 // be generated lazily once deopt is triggered.
   1403 bool Compiler::EnsureDeoptimizationSupport(CompilationInfo* info) {
   1404   DCHECK_NOT_NULL(info->literal());
   1405   DCHECK_NOT_NULL(info->scope());
   1406   Handle<SharedFunctionInfo> shared = info->shared_info();
   1407 
   1408   CompilerDispatcher* dispatcher = info->isolate()->compiler_dispatcher();
   1409   if (dispatcher->IsEnqueued(shared)) {
   1410     if (!dispatcher->FinishNow(shared)) return false;
   1411   }
   1412 
   1413   if (!shared->has_deoptimization_support()) {
   1414     Zone compile_zone(info->isolate()->allocator(), ZONE_NAME);
   1415     CompilationInfo unoptimized(&compile_zone, info->parse_info(),
   1416                                 info->closure());
   1417     unoptimized.EnableDeoptimizationSupport();
   1418 
   1419     // Don't generate full-codegen code for functions it can't support.
   1420     if (shared->must_use_ignition_turbo()) return false;
   1421     DCHECK(!IsResumableFunction(shared->kind()));
   1422 
   1423     // When we call PrepareForSerializing below, we will change the shared
   1424     // ParseInfo. Make sure to reset it.
   1425     bool old_will_serialize_value = info->parse_info()->will_serialize();
   1426 
   1427     // If the current code has reloc info for serialization, also include
   1428     // reloc info for serialization for the new code, so that deopt support
   1429     // can be added without losing IC state.
   1430     if (shared->code()->kind() == Code::FUNCTION &&
   1431         shared->code()->has_reloc_info_for_serialization()) {
   1432       unoptimized.PrepareForSerializing();
   1433     }
   1434     EnsureFeedbackMetadata(&unoptimized);
   1435 
   1436     // Ensure we generate and install bytecode first if the function should use
   1437     // Ignition to avoid implicit tier-down.
   1438     if (!shared->is_compiled() && ShouldUseIgnition(info) &&
   1439         !GenerateUnoptimizedCode(info)) {
   1440       return false;
   1441     }
   1442 
   1443     if (!FullCodeGenerator::MakeCode(&unoptimized)) return false;
   1444 
   1445     info->parse_info()->set_will_serialize(old_will_serialize_value);
   1446 
   1447     // The scope info might not have been set if a lazily compiled
   1448     // function is inlined before being called for the first time.
   1449     if (shared->scope_info() == ScopeInfo::Empty(info->isolate())) {
   1450       InstallSharedScopeInfo(info, shared);
   1451     }
   1452 
   1453     // Install compilation result on the shared function info
   1454     shared->EnableDeoptimizationSupport(*unoptimized.code());
   1455 
   1456     // The existing unoptimized code was replaced with the new one.
   1457     RecordFunctionCompilation(CodeEventListener::LAZY_COMPILE_TAG,
   1458                               &unoptimized);
   1459   }
   1460   return true;
   1461 }
   1462 
   1463 // static
   1464 Compiler::CompilationTier Compiler::NextCompilationTier(JSFunction* function) {
   1465   Handle<SharedFunctionInfo> shared(function->shared(), function->GetIsolate());
   1466   if (shared->IsInterpreted()) {
   1467     if (UseTurboFan(shared)) {
   1468       return OPTIMIZED;
   1469     } else {
   1470       return BASELINE;
   1471     }
   1472   } else {
   1473     return OPTIMIZED;
   1474   }
   1475 }
   1476 
   1477 MaybeHandle<JSFunction> Compiler::GetFunctionFromEval(
   1478     Handle<String> source, Handle<SharedFunctionInfo> outer_info,
   1479     Handle<Context> context, LanguageMode language_mode,
   1480     ParseRestriction restriction, int parameters_end_pos,
   1481     int eval_scope_position, int eval_position, int line_offset,
   1482     int column_offset, Handle<Object> script_name,
   1483     ScriptOriginOptions options) {
   1484   Isolate* isolate = source->GetIsolate();
   1485   int source_length = source->length();
   1486   isolate->counters()->total_eval_size()->Increment(source_length);
   1487   isolate->counters()->total_compile_size()->Increment(source_length);
   1488 
   1489   // The cache lookup key needs to be aware of the separation between the
   1490   // parameters and the body to prevent this valid invocation:
   1491   //   Function("", "function anonymous(\n/**/) {\n}");
   1492   // from adding an entry that falsely approves this invalid invocation:
   1493   //   Function("\n/**/) {\nfunction anonymous(", "}");
   1494   // The actual eval_scope_position for indirect eval and CreateDynamicFunction
   1495   // is unused (just 0), which means it's an available field to use to indicate
   1496   // this separation. But to make sure we're not causing other false hits, we
   1497   // negate the scope position.
   1498   int position = eval_scope_position;
   1499   if (FLAG_harmony_function_tostring &&
   1500       restriction == ONLY_SINGLE_FUNCTION_LITERAL &&
   1501       parameters_end_pos != kNoSourcePosition) {
   1502     // use the parameters_end_pos as the eval_scope_position in the eval cache.
   1503     DCHECK_EQ(eval_scope_position, 0);
   1504     position = -parameters_end_pos;
   1505   }
   1506   CompilationCache* compilation_cache = isolate->compilation_cache();
   1507   InfoVectorPair eval_result = compilation_cache->LookupEval(
   1508       source, outer_info, context, language_mode, position);
   1509   Handle<SharedFunctionInfo> shared_info;
   1510   if (eval_result.has_shared()) {
   1511     shared_info = Handle<SharedFunctionInfo>(eval_result.shared(), isolate);
   1512   }
   1513   Handle<Cell> vector;
   1514   if (eval_result.has_vector()) {
   1515     vector = Handle<Cell>(eval_result.vector(), isolate);
   1516   }
   1517 
   1518   Handle<Script> script;
   1519   if (!eval_result.has_shared()) {
   1520     script = isolate->factory()->NewScript(source);
   1521     if (isolate->NeedsSourcePositionsForProfiling()) {
   1522       Script::InitLineEnds(script);
   1523     }
   1524     if (!script_name.is_null()) {
   1525       script->set_name(*script_name);
   1526       script->set_line_offset(line_offset);
   1527       script->set_column_offset(column_offset);
   1528     }
   1529     script->set_origin_options(options);
   1530     script->set_compilation_type(Script::COMPILATION_TYPE_EVAL);
   1531     Script::SetEvalOrigin(script, outer_info, eval_position);
   1532 
   1533     ParseInfo parse_info(script);
   1534     Zone compile_zone(isolate->allocator(), ZONE_NAME);
   1535     CompilationInfo info(&compile_zone, &parse_info,
   1536                          Handle<JSFunction>::null());
   1537     parse_info.set_eval();
   1538     parse_info.set_language_mode(language_mode);
   1539     parse_info.set_parse_restriction(restriction);
   1540     parse_info.set_parameters_end_pos(parameters_end_pos);
   1541     if (!context->IsNativeContext()) {
   1542       parse_info.set_outer_scope_info(handle(context->scope_info()));
   1543     }
   1544 
   1545     shared_info = CompileToplevel(&info);
   1546     if (shared_info.is_null()) {
   1547       return MaybeHandle<JSFunction>();
   1548     }
   1549   }
   1550 
   1551   // If caller is strict mode, the result must be in strict mode as well.
   1552   DCHECK(is_sloppy(language_mode) || is_strict(shared_info->language_mode()));
   1553 
   1554   Handle<JSFunction> result;
   1555   if (eval_result.has_shared()) {
   1556     if (eval_result.has_vector()) {
   1557       result = isolate->factory()->NewFunctionFromSharedFunctionInfo(
   1558           shared_info, context, vector, NOT_TENURED);
   1559     } else {
   1560       result = isolate->factory()->NewFunctionFromSharedFunctionInfo(
   1561           shared_info, context, NOT_TENURED);
   1562       JSFunction::EnsureLiterals(result);
   1563       // Make sure to cache this result.
   1564       Handle<Cell> new_vector(result->feedback_vector_cell(), isolate);
   1565       compilation_cache->PutEval(source, outer_info, context, shared_info,
   1566                                  new_vector, eval_scope_position);
   1567     }
   1568   } else {
   1569     result = isolate->factory()->NewFunctionFromSharedFunctionInfo(
   1570         shared_info, context, NOT_TENURED);
   1571     JSFunction::EnsureLiterals(result);
   1572     // Add the SharedFunctionInfo and the LiteralsArray to the eval cache if
   1573     // we didn't retrieve from there.
   1574     Handle<Cell> vector(result->feedback_vector_cell(), isolate);
   1575     compilation_cache->PutEval(source, outer_info, context, shared_info, vector,
   1576                                eval_scope_position);
   1577   }
   1578 
   1579   // OnAfterCompile has to be called after we create the JSFunction, which we
   1580   // may require to recompile the eval for debugging, if we find a function
   1581   // that contains break points in the eval script.
   1582   isolate->debug()->OnAfterCompile(script);
   1583 
   1584   return result;
   1585 }
   1586 
   1587 namespace {
   1588 
   1589 bool CodeGenerationFromStringsAllowed(Isolate* isolate,
   1590                                       Handle<Context> context) {
   1591   DCHECK(context->allow_code_gen_from_strings()->IsFalse(isolate));
   1592   // Check with callback if set.
   1593   AllowCodeGenerationFromStringsCallback callback =
   1594       isolate->allow_code_gen_callback();
   1595   if (callback == NULL) {
   1596     // No callback set and code generation disallowed.
   1597     return false;
   1598   } else {
   1599     // Callback set. Let it decide if code generation is allowed.
   1600     VMState<EXTERNAL> state(isolate);
   1601     return callback(v8::Utils::ToLocal(context));
   1602   }
   1603 }
   1604 
   1605 bool ContainsAsmModule(Handle<Script> script) {
   1606   DisallowHeapAllocation no_gc;
   1607   SharedFunctionInfo::ScriptIterator iter(script);
   1608   while (SharedFunctionInfo* info = iter.Next()) {
   1609     if (info->HasAsmWasmData()) return true;
   1610   }
   1611   return false;
   1612 }
   1613 
   1614 }  // namespace
   1615 
   1616 MaybeHandle<JSFunction> Compiler::GetFunctionFromString(
   1617     Handle<Context> context, Handle<String> source,
   1618     ParseRestriction restriction, int parameters_end_pos) {
   1619   Isolate* const isolate = context->GetIsolate();
   1620   Handle<Context> native_context(context->native_context(), isolate);
   1621 
   1622   // Check if native context allows code generation from
   1623   // strings. Throw an exception if it doesn't.
   1624   if (native_context->allow_code_gen_from_strings()->IsFalse(isolate) &&
   1625       !CodeGenerationFromStringsAllowed(isolate, native_context)) {
   1626     Handle<Object> error_message =
   1627         native_context->ErrorMessageForCodeGenerationFromStrings();
   1628     THROW_NEW_ERROR(isolate, NewEvalError(MessageTemplate::kCodeGenFromStrings,
   1629                                           error_message),
   1630                     JSFunction);
   1631   }
   1632 
   1633   // Compile source string in the native context.
   1634   int eval_scope_position = 0;
   1635   int eval_position = kNoSourcePosition;
   1636   Handle<SharedFunctionInfo> outer_info(native_context->closure()->shared());
   1637   return Compiler::GetFunctionFromEval(source, outer_info, native_context,
   1638                                        SLOPPY, restriction, parameters_end_pos,
   1639                                        eval_scope_position, eval_position);
   1640 }
   1641 
   1642 Handle<SharedFunctionInfo> Compiler::GetSharedFunctionInfoForScript(
   1643     Handle<String> source, Handle<Object> script_name, int line_offset,
   1644     int column_offset, ScriptOriginOptions resource_options,
   1645     Handle<Object> source_map_url, Handle<Context> context,
   1646     v8::Extension* extension, ScriptData** cached_data,
   1647     ScriptCompiler::CompileOptions compile_options, NativesFlag natives) {
   1648   Isolate* isolate = source->GetIsolate();
   1649   if (compile_options == ScriptCompiler::kNoCompileOptions) {
   1650     cached_data = NULL;
   1651   } else if (compile_options == ScriptCompiler::kProduceParserCache ||
   1652              compile_options == ScriptCompiler::kProduceCodeCache) {
   1653     DCHECK(cached_data && !*cached_data);
   1654     DCHECK(extension == NULL);
   1655     DCHECK(!isolate->debug()->is_loaded());
   1656   } else {
   1657     DCHECK(compile_options == ScriptCompiler::kConsumeParserCache ||
   1658            compile_options == ScriptCompiler::kConsumeCodeCache);
   1659     DCHECK(cached_data && *cached_data);
   1660     DCHECK(extension == NULL);
   1661   }
   1662   int source_length = source->length();
   1663   isolate->counters()->total_load_size()->Increment(source_length);
   1664   isolate->counters()->total_compile_size()->Increment(source_length);
   1665 
   1666   LanguageMode language_mode = construct_language_mode(FLAG_use_strict);
   1667   CompilationCache* compilation_cache = isolate->compilation_cache();
   1668 
   1669   // Do a lookup in the compilation cache but not for extensions.
   1670   Handle<SharedFunctionInfo> result;
   1671   Handle<Cell> vector;
   1672   if (extension == NULL) {
   1673     // First check per-isolate compilation cache.
   1674     InfoVectorPair pair = compilation_cache->LookupScript(
   1675         source, script_name, line_offset, column_offset, resource_options,
   1676         context, language_mode);
   1677     if (!pair.has_shared() && FLAG_serialize_toplevel &&
   1678         compile_options == ScriptCompiler::kConsumeCodeCache &&
   1679         !isolate->debug()->is_loaded()) {
   1680       // Then check cached code provided by embedder.
   1681       HistogramTimerScope timer(isolate->counters()->compile_deserialize());
   1682       RuntimeCallTimerScope runtimeTimer(isolate,
   1683                                          &RuntimeCallStats::CompileDeserialize);
   1684       TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"),
   1685                    "V8.CompileDeserialize");
   1686       Handle<SharedFunctionInfo> inner_result;
   1687       if (CodeSerializer::Deserialize(isolate, *cached_data, source)
   1688               .ToHandle(&inner_result)) {
   1689         // Promote to per-isolate compilation cache.
   1690         // TODO(mvstanton): create a feedback vector array here.
   1691         DCHECK(inner_result->is_compiled());
   1692         Handle<FeedbackVector> feedback_vector =
   1693             FeedbackVector::New(isolate, inner_result);
   1694         vector = isolate->factory()->NewCell(feedback_vector);
   1695         compilation_cache->PutScript(source, context, language_mode,
   1696                                      inner_result, vector);
   1697         return inner_result;
   1698       }
   1699       // Deserializer failed. Fall through to compile.
   1700     } else {
   1701       if (pair.has_shared()) {
   1702         result = Handle<SharedFunctionInfo>(pair.shared(), isolate);
   1703       }
   1704       if (pair.has_vector()) {
   1705         vector = Handle<Cell>(pair.vector(), isolate);
   1706       }
   1707     }
   1708   }
   1709 
   1710   base::ElapsedTimer timer;
   1711   if (FLAG_profile_deserialization && FLAG_serialize_toplevel &&
   1712       compile_options == ScriptCompiler::kProduceCodeCache) {
   1713     timer.Start();
   1714   }
   1715 
   1716   if (result.is_null() ||
   1717       (FLAG_serialize_toplevel &&
   1718        compile_options == ScriptCompiler::kProduceCodeCache)) {
   1719     // No cache entry found, or embedder wants a code cache. Compile the script.
   1720 
   1721     // Create a script object describing the script to be compiled.
   1722     Handle<Script> script = isolate->factory()->NewScript(source);
   1723     if (isolate->NeedsSourcePositionsForProfiling()) {
   1724       Script::InitLineEnds(script);
   1725     }
   1726     if (natives == NATIVES_CODE) {
   1727       script->set_type(Script::TYPE_NATIVE);
   1728     } else if (natives == EXTENSION_CODE) {
   1729       script->set_type(Script::TYPE_EXTENSION);
   1730     } else if (natives == INSPECTOR_CODE) {
   1731       script->set_type(Script::TYPE_INSPECTOR);
   1732     }
   1733     if (!script_name.is_null()) {
   1734       script->set_name(*script_name);
   1735       script->set_line_offset(line_offset);
   1736       script->set_column_offset(column_offset);
   1737     }
   1738     script->set_origin_options(resource_options);
   1739     if (!source_map_url.is_null()) {
   1740       script->set_source_mapping_url(*source_map_url);
   1741     }
   1742 
   1743     // Compile the function and add it to the cache.
   1744     ParseInfo parse_info(script);
   1745     Zone compile_zone(isolate->allocator(), ZONE_NAME);
   1746     CompilationInfo info(&compile_zone, &parse_info,
   1747                          Handle<JSFunction>::null());
   1748     if (resource_options.IsModule()) parse_info.set_module();
   1749     if (compile_options != ScriptCompiler::kNoCompileOptions) {
   1750       parse_info.set_cached_data(cached_data);
   1751     }
   1752     parse_info.set_compile_options(compile_options);
   1753     parse_info.set_extension(extension);
   1754     if (!context->IsNativeContext()) {
   1755       parse_info.set_outer_scope_info(handle(context->scope_info()));
   1756     }
   1757     if (FLAG_serialize_toplevel &&
   1758         compile_options == ScriptCompiler::kProduceCodeCache) {
   1759       info.PrepareForSerializing();
   1760     }
   1761 
   1762     parse_info.set_language_mode(
   1763         static_cast<LanguageMode>(parse_info.language_mode() | language_mode));
   1764     result = CompileToplevel(&info);
   1765     if (extension == NULL && !result.is_null()) {
   1766       // We need a feedback vector.
   1767       DCHECK(result->is_compiled());
   1768       Handle<FeedbackVector> feedback_vector =
   1769           FeedbackVector::New(isolate, result);
   1770       vector = isolate->factory()->NewCell(feedback_vector);
   1771       compilation_cache->PutScript(source, context, language_mode, result,
   1772                                    vector);
   1773       if (FLAG_serialize_toplevel &&
   1774           compile_options == ScriptCompiler::kProduceCodeCache &&
   1775           !ContainsAsmModule(script)) {
   1776         HistogramTimerScope histogram_timer(
   1777             isolate->counters()->compile_serialize());
   1778         RuntimeCallTimerScope runtimeTimer(isolate,
   1779                                            &RuntimeCallStats::CompileSerialize);
   1780         TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"),
   1781                      "V8.CompileSerialize");
   1782         *cached_data = CodeSerializer::Serialize(isolate, result, source);
   1783         if (FLAG_profile_deserialization) {
   1784           PrintF("[Compiling and serializing took %0.3f ms]\n",
   1785                  timer.Elapsed().InMillisecondsF());
   1786         }
   1787       }
   1788     }
   1789 
   1790     if (result.is_null()) {
   1791       if (natives != EXTENSION_CODE && natives != NATIVES_CODE) {
   1792         isolate->ReportPendingMessages();
   1793       }
   1794     } else {
   1795       isolate->debug()->OnAfterCompile(script);
   1796     }
   1797   } else if (result->ic_age() != isolate->heap()->global_ic_age()) {
   1798     result->ResetForNewContext(isolate->heap()->global_ic_age());
   1799   }
   1800   return result;
   1801 }
   1802 
   1803 Handle<SharedFunctionInfo> Compiler::GetSharedFunctionInfoForStreamedScript(
   1804     Handle<Script> script, ParseInfo* parse_info, int source_length) {
   1805   Isolate* isolate = script->GetIsolate();
   1806   // TODO(titzer): increment the counters in caller.
   1807   isolate->counters()->total_load_size()->Increment(source_length);
   1808   isolate->counters()->total_compile_size()->Increment(source_length);
   1809 
   1810   LanguageMode language_mode = construct_language_mode(FLAG_use_strict);
   1811   parse_info->set_language_mode(
   1812       static_cast<LanguageMode>(parse_info->language_mode() | language_mode));
   1813 
   1814   Zone compile_zone(isolate->allocator(), ZONE_NAME);
   1815   CompilationInfo compile_info(&compile_zone, parse_info,
   1816                                Handle<JSFunction>::null());
   1817 
   1818   // The source was parsed lazily, so compiling for debugging is not possible.
   1819   DCHECK(!compile_info.is_debug());
   1820 
   1821   Handle<SharedFunctionInfo> result = CompileToplevel(&compile_info);
   1822   if (!result.is_null()) isolate->debug()->OnAfterCompile(script);
   1823   return result;
   1824 }
   1825 
   1826 Handle<SharedFunctionInfo> Compiler::GetSharedFunctionInfo(
   1827     FunctionLiteral* literal, Handle<Script> script,
   1828     CompilationInfo* outer_info) {
   1829   // Precondition: code has been parsed and scopes have been analyzed.
   1830   Isolate* isolate = outer_info->isolate();
   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   result->set_is_toplevel(false);
   1847   Scope* outer_scope = literal->scope()->GetOuterScopeWithContext();
   1848   if (outer_scope) {
   1849     result->set_outer_scope_info(*outer_scope->scope_info());
   1850   }
   1851   return result;
   1852 }
   1853 
   1854 Handle<SharedFunctionInfo> Compiler::GetSharedFunctionInfoForNative(
   1855     v8::Extension* extension, Handle<String> name) {
   1856   Isolate* isolate = name->GetIsolate();
   1857   v8::Isolate* v8_isolate = reinterpret_cast<v8::Isolate*>(isolate);
   1858 
   1859   // Compute the function template for the native function.
   1860   v8::Local<v8::FunctionTemplate> fun_template =
   1861       extension->GetNativeFunctionTemplate(v8_isolate,
   1862                                            v8::Utils::ToLocal(name));
   1863   DCHECK(!fun_template.IsEmpty());
   1864 
   1865   // Instantiate the function and create a shared function info from it.
   1866   Handle<JSFunction> fun = Handle<JSFunction>::cast(Utils::OpenHandle(
   1867       *fun_template->GetFunction(v8_isolate->GetCurrentContext())
   1868            .ToLocalChecked()));
   1869   Handle<Code> code = Handle<Code>(fun->shared()->code());
   1870   Handle<Code> construct_stub = Handle<Code>(fun->shared()->construct_stub());
   1871   Handle<SharedFunctionInfo> shared = isolate->factory()->NewSharedFunctionInfo(
   1872       name, FunctionKind::kNormalFunction, code,
   1873       Handle<ScopeInfo>(fun->shared()->scope_info()));
   1874   shared->set_outer_scope_info(fun->shared()->outer_scope_info());
   1875   shared->SetConstructStub(*construct_stub);
   1876   shared->set_feedback_metadata(fun->shared()->feedback_metadata());
   1877 
   1878   // Copy the function data to the shared function info.
   1879   shared->set_function_data(fun->shared()->function_data());
   1880   int parameters = fun->shared()->internal_formal_parameter_count();
   1881   shared->set_internal_formal_parameter_count(parameters);
   1882 
   1883   return shared;
   1884 }
   1885 
   1886 MaybeHandle<Code> Compiler::GetOptimizedCodeForOSR(Handle<JSFunction> function,
   1887                                                    BailoutId osr_ast_id,
   1888                                                    JavaScriptFrame* osr_frame) {
   1889   DCHECK(!osr_ast_id.IsNone());
   1890   DCHECK_NOT_NULL(osr_frame);
   1891   return GetOptimizedCode(function, NOT_CONCURRENT, osr_ast_id, osr_frame);
   1892 }
   1893 
   1894 CompilationJob* Compiler::PrepareUnoptimizedCompilationJob(
   1895     CompilationInfo* info) {
   1896   VMState<COMPILER> state(info->isolate());
   1897   std::unique_ptr<CompilationJob> job(GetUnoptimizedCompilationJob(info));
   1898   if (job->PrepareJob() != CompilationJob::SUCCEEDED) {
   1899     return nullptr;
   1900   }
   1901   return job.release();
   1902 }
   1903 
   1904 bool Compiler::FinalizeCompilationJob(CompilationJob* raw_job) {
   1905   // Take ownership of compilation job.  Deleting job also tears down the zone.
   1906   std::unique_ptr<CompilationJob> job(raw_job);
   1907 
   1908   VMState<COMPILER> state(job->info()->isolate());
   1909   if (job->info()->IsOptimizing()) {
   1910     return FinalizeOptimizedCompilationJob(job.get()) ==
   1911            CompilationJob::SUCCEEDED;
   1912   } else {
   1913     return FinalizeUnoptimizedCompilationJob(job.get()) ==
   1914            CompilationJob::SUCCEEDED;
   1915   }
   1916 }
   1917 
   1918 void Compiler::PostInstantiation(Handle<JSFunction> function,
   1919                                  PretenureFlag pretenure) {
   1920   Handle<SharedFunctionInfo> shared(function->shared());
   1921 
   1922   if (FLAG_always_opt && shared->allows_lazy_compilation() &&
   1923       !function->shared()->HasAsmWasmData() &&
   1924       function->shared()->is_compiled()) {
   1925     function->MarkForOptimization();
   1926   }
   1927 
   1928   Code* code = shared->SearchOptimizedCodeMap(
   1929       function->context()->native_context(), BailoutId::None());
   1930   if (code != nullptr) {
   1931     // Caching of optimized code enabled and optimized code found.
   1932     DCHECK(!code->marked_for_deoptimization());
   1933     DCHECK(function->shared()->is_compiled());
   1934     function->ReplaceCode(code);
   1935   }
   1936 
   1937   if (shared->is_compiled()) {
   1938     // TODO(mvstanton): pass pretenure flag to EnsureLiterals.
   1939     JSFunction::EnsureLiterals(function);
   1940   }
   1941 }
   1942 
   1943 }  // namespace internal
   1944 }  // namespace v8
   1945