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