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 
      9 #include "src/ast/ast-numbering.h"
     10 #include "src/ast/prettyprinter.h"
     11 #include "src/ast/scopeinfo.h"
     12 #include "src/ast/scopes.h"
     13 #include "src/bootstrapper.h"
     14 #include "src/codegen.h"
     15 #include "src/compilation-cache.h"
     16 #include "src/compiler/pipeline.h"
     17 #include "src/crankshaft/hydrogen.h"
     18 #include "src/crankshaft/lithium.h"
     19 #include "src/crankshaft/typing.h"
     20 #include "src/debug/debug.h"
     21 #include "src/debug/liveedit.h"
     22 #include "src/deoptimizer.h"
     23 #include "src/full-codegen/full-codegen.h"
     24 #include "src/gdb-jit.h"
     25 #include "src/interpreter/interpreter.h"
     26 #include "src/isolate-inl.h"
     27 #include "src/log-inl.h"
     28 #include "src/messages.h"
     29 #include "src/parsing/parser.h"
     30 #include "src/parsing/rewriter.h"
     31 #include "src/parsing/scanner-character-streams.h"
     32 #include "src/profiler/cpu-profiler.h"
     33 #include "src/runtime-profiler.h"
     34 #include "src/snapshot/serialize.h"
     35 #include "src/vm-state-inl.h"
     36 
     37 namespace v8 {
     38 namespace internal {
     39 
     40 std::ostream& operator<<(std::ostream& os, const SourcePosition& p) {
     41   if (p.IsUnknown()) {
     42     return os << "<?>";
     43   } else if (FLAG_hydrogen_track_positions) {
     44     return os << "<" << p.inlining_id() << ":" << p.position() << ">";
     45   } else {
     46     return os << "<0:" << p.raw() << ">";
     47   }
     48 }
     49 
     50 
     51 #define PARSE_INFO_GETTER(type, name)  \
     52   type CompilationInfo::name() const { \
     53     CHECK(parse_info());               \
     54     return parse_info()->name();       \
     55   }
     56 
     57 
     58 #define PARSE_INFO_GETTER_WITH_DEFAULT(type, name, def) \
     59   type CompilationInfo::name() const {                  \
     60     return parse_info() ? parse_info()->name() : def;   \
     61   }
     62 
     63 
     64 PARSE_INFO_GETTER(Handle<Script>, script)
     65 PARSE_INFO_GETTER(bool, is_eval)
     66 PARSE_INFO_GETTER(bool, is_native)
     67 PARSE_INFO_GETTER(bool, is_module)
     68 PARSE_INFO_GETTER(FunctionLiteral*, literal)
     69 PARSE_INFO_GETTER_WITH_DEFAULT(LanguageMode, language_mode, STRICT)
     70 PARSE_INFO_GETTER_WITH_DEFAULT(Handle<JSFunction>, closure,
     71                                Handle<JSFunction>::null())
     72 PARSE_INFO_GETTER_WITH_DEFAULT(Scope*, scope, nullptr)
     73 PARSE_INFO_GETTER(Handle<Context>, context)
     74 PARSE_INFO_GETTER(Handle<SharedFunctionInfo>, shared_info)
     75 
     76 #undef PARSE_INFO_GETTER
     77 #undef PARSE_INFO_GETTER_WITH_DEFAULT
     78 
     79 
     80 // Exactly like a CompilationInfo, except being allocated via {new} and it also
     81 // creates and enters a Zone on construction and deallocates it on destruction.
     82 class CompilationInfoWithZone : public CompilationInfo {
     83  public:
     84   explicit CompilationInfoWithZone(Handle<JSFunction> function)
     85       : CompilationInfo(new ParseInfo(&zone_, function)) {}
     86 
     87   // Virtual destructor because a CompilationInfoWithZone has to exit the
     88   // zone scope and get rid of dependent maps even when the destructor is
     89   // called when cast as a CompilationInfo.
     90   virtual ~CompilationInfoWithZone() {
     91     DisableFutureOptimization();
     92     dependencies()->Rollback();
     93     delete parse_info_;
     94     parse_info_ = nullptr;
     95   }
     96 
     97  private:
     98   Zone zone_;
     99 };
    100 
    101 
    102 bool CompilationInfo::has_shared_info() const {
    103   return parse_info_ && !parse_info_->shared_info().is_null();
    104 }
    105 
    106 
    107 bool CompilationInfo::has_context() const {
    108   return parse_info_ && !parse_info_->context().is_null();
    109 }
    110 
    111 
    112 bool CompilationInfo::has_literal() const {
    113   return parse_info_ && parse_info_->literal() != nullptr;
    114 }
    115 
    116 
    117 bool CompilationInfo::has_scope() const {
    118   return parse_info_ && parse_info_->scope() != nullptr;
    119 }
    120 
    121 
    122 CompilationInfo::CompilationInfo(ParseInfo* parse_info)
    123     : CompilationInfo(parse_info, nullptr, nullptr, BASE, parse_info->isolate(),
    124                       parse_info->zone()) {
    125   // Compiling for the snapshot typically results in different code than
    126   // compiling later on. This means that code recompiled with deoptimization
    127   // support won't be "equivalent" (as defined by SharedFunctionInfo::
    128   // EnableDeoptimizationSupport), so it will replace the old code and all
    129   // its type feedback. To avoid this, always compile functions in the snapshot
    130   // with deoptimization support.
    131   if (isolate_->serializer_enabled()) EnableDeoptimizationSupport();
    132 
    133   if (FLAG_function_context_specialization) MarkAsFunctionContextSpecializing();
    134   if (FLAG_turbo_inlining) MarkAsInliningEnabled();
    135   if (FLAG_turbo_source_positions) MarkAsSourcePositionsEnabled();
    136   if (FLAG_turbo_splitting) MarkAsSplittingEnabled();
    137   if (FLAG_turbo_types) MarkAsTypingEnabled();
    138 
    139   if (has_shared_info()) {
    140     if (shared_info()->is_compiled()) {
    141       // We should initialize the CompilationInfo feedback vector from the
    142       // passed in shared info, rather than creating a new one.
    143       feedback_vector_ = Handle<TypeFeedbackVector>(
    144           shared_info()->feedback_vector(), parse_info->isolate());
    145     }
    146     if (shared_info()->never_compiled()) MarkAsFirstCompile();
    147   }
    148 }
    149 
    150 
    151 CompilationInfo::CompilationInfo(CodeStub* stub, Isolate* isolate, Zone* zone)
    152     : CompilationInfo(nullptr, stub, CodeStub::MajorName(stub->MajorKey()),
    153                       STUB, isolate, zone) {}
    154 
    155 CompilationInfo::CompilationInfo(const char* debug_name, Isolate* isolate,
    156                                  Zone* zone)
    157     : CompilationInfo(nullptr, nullptr, debug_name, STUB, isolate, zone) {
    158   set_output_code_kind(Code::STUB);
    159 }
    160 
    161 CompilationInfo::CompilationInfo(ParseInfo* parse_info, CodeStub* code_stub,
    162                                  const char* debug_name, Mode mode,
    163                                  Isolate* isolate, Zone* zone)
    164     : parse_info_(parse_info),
    165       isolate_(isolate),
    166       flags_(0),
    167       code_stub_(code_stub),
    168       mode_(mode),
    169       osr_ast_id_(BailoutId::None()),
    170       zone_(zone),
    171       deferred_handles_(nullptr),
    172       dependencies_(isolate, zone),
    173       bailout_reason_(kNoReason),
    174       prologue_offset_(Code::kPrologueOffsetNotSet),
    175       track_positions_(FLAG_hydrogen_track_positions ||
    176                        isolate->cpu_profiler()->is_profiling()),
    177       opt_count_(has_shared_info() ? shared_info()->opt_count() : 0),
    178       parameter_count_(0),
    179       optimization_id_(-1),
    180       osr_expr_stack_height_(0),
    181       debug_name_(debug_name) {
    182   // Parameter count is number of stack parameters.
    183   if (code_stub_ != NULL) {
    184     CodeStubDescriptor descriptor(code_stub_);
    185     parameter_count_ = descriptor.GetStackParameterCount();
    186     if (descriptor.function_mode() == NOT_JS_FUNCTION_STUB_MODE) {
    187       parameter_count_--;
    188     }
    189     set_output_code_kind(code_stub->GetCodeKind());
    190   } else {
    191     set_output_code_kind(Code::FUNCTION);
    192   }
    193 }
    194 
    195 
    196 CompilationInfo::~CompilationInfo() {
    197   DisableFutureOptimization();
    198   delete deferred_handles_;
    199 #ifdef DEBUG
    200   // Check that no dependent maps have been added or added dependent maps have
    201   // been rolled back or committed.
    202   DCHECK(dependencies()->IsEmpty());
    203 #endif  // DEBUG
    204 }
    205 
    206 
    207 int CompilationInfo::num_parameters() const {
    208   return has_scope() ? scope()->num_parameters() : parameter_count_;
    209 }
    210 
    211 
    212 int CompilationInfo::num_parameters_including_this() const {
    213   return num_parameters() + (is_this_defined() ? 1 : 0);
    214 }
    215 
    216 
    217 bool CompilationInfo::is_this_defined() const { return !IsStub(); }
    218 
    219 
    220 int CompilationInfo::num_heap_slots() const {
    221   return has_scope() ? scope()->num_heap_slots() : 0;
    222 }
    223 
    224 
    225 // Primitive functions are unlikely to be picked up by the stack-walking
    226 // profiler, so they trigger their own optimization when they're called
    227 // for the SharedFunctionInfo::kCallsUntilPrimitiveOptimization-th time.
    228 bool CompilationInfo::ShouldSelfOptimize() {
    229   return FLAG_crankshaft &&
    230          !(literal()->flags() & AstProperties::kDontSelfOptimize) &&
    231          !literal()->dont_optimize() &&
    232          literal()->scope()->AllowsLazyCompilation() &&
    233          (!has_shared_info() || !shared_info()->optimization_disabled());
    234 }
    235 
    236 
    237 void CompilationInfo::EnsureFeedbackVector() {
    238   if (feedback_vector_.is_null()) {
    239     Handle<TypeFeedbackMetadata> feedback_metadata =
    240         TypeFeedbackMetadata::New(isolate(), literal()->feedback_vector_spec());
    241     feedback_vector_ = TypeFeedbackVector::New(isolate(), feedback_metadata);
    242   }
    243 
    244   // It's very important that recompiles do not alter the structure of the
    245   // type feedback vector.
    246   CHECK(!feedback_vector_->metadata()->SpecDiffersFrom(
    247       literal()->feedback_vector_spec()));
    248 }
    249 
    250 
    251 bool CompilationInfo::has_simple_parameters() {
    252   return scope()->has_simple_parameters();
    253 }
    254 
    255 
    256 int CompilationInfo::TraceInlinedFunction(Handle<SharedFunctionInfo> shared,
    257                                           SourcePosition position,
    258                                           int parent_id) {
    259   DCHECK(track_positions_);
    260 
    261   int inline_id = static_cast<int>(inlined_function_infos_.size());
    262   InlinedFunctionInfo info(parent_id, position, UnboundScript::kNoScriptId,
    263       shared->start_position());
    264   if (!shared->script()->IsUndefined()) {
    265     Handle<Script> script(Script::cast(shared->script()));
    266     info.script_id = script->id();
    267 
    268     if (FLAG_hydrogen_track_positions && !script->source()->IsUndefined()) {
    269       CodeTracer::Scope tracing_scope(isolate()->GetCodeTracer());
    270       OFStream os(tracing_scope.file());
    271       os << "--- FUNCTION SOURCE (" << shared->DebugName()->ToCString().get()
    272          << ") id{" << optimization_id() << "," << inline_id << "} ---\n";
    273       {
    274         DisallowHeapAllocation no_allocation;
    275         int start = shared->start_position();
    276         int len = shared->end_position() - start;
    277         String::SubStringRange source(String::cast(script->source()), start,
    278                                       len);
    279         for (const auto& c : source) {
    280           os << AsReversiblyEscapedUC16(c);
    281         }
    282       }
    283 
    284       os << "\n--- END ---\n";
    285     }
    286   }
    287 
    288   inlined_function_infos_.push_back(info);
    289 
    290   if (FLAG_hydrogen_track_positions && inline_id != 0) {
    291     CodeTracer::Scope tracing_scope(isolate()->GetCodeTracer());
    292     OFStream os(tracing_scope.file());
    293     os << "INLINE (" << shared->DebugName()->ToCString().get() << ") id{"
    294        << optimization_id() << "," << inline_id << "} AS " << inline_id
    295        << " AT " << position << std::endl;
    296   }
    297 
    298   return inline_id;
    299 }
    300 
    301 
    302 void CompilationInfo::LogDeoptCallPosition(int pc_offset, int inlining_id) {
    303   if (!track_positions_ || IsStub()) return;
    304   DCHECK_LT(static_cast<size_t>(inlining_id), inlined_function_infos_.size());
    305   inlined_function_infos_.at(inlining_id).deopt_pc_offsets.push_back(pc_offset);
    306 }
    307 
    308 
    309 base::SmartArrayPointer<char> CompilationInfo::GetDebugName() const {
    310   if (parse_info()) {
    311     AllowHandleDereference allow_deref;
    312     return parse_info()->literal()->debug_name()->ToCString();
    313   }
    314   const char* str = debug_name_ ? debug_name_ : "unknown";
    315   size_t len = strlen(str) + 1;
    316   base::SmartArrayPointer<char> name(new char[len]);
    317   memcpy(name.get(), str, len);
    318   return name;
    319 }
    320 
    321 
    322 bool CompilationInfo::ExpectsJSReceiverAsReceiver() {
    323   return is_sloppy(language_mode()) && !is_native();
    324 }
    325 
    326 
    327 class HOptimizedGraphBuilderWithPositions: public HOptimizedGraphBuilder {
    328  public:
    329   explicit HOptimizedGraphBuilderWithPositions(CompilationInfo* info)
    330       : HOptimizedGraphBuilder(info) {
    331   }
    332 
    333 #define DEF_VISIT(type)                                      \
    334   void Visit##type(type* node) override {                    \
    335     SourcePosition old_position = SourcePosition::Unknown(); \
    336     if (node->position() != RelocInfo::kNoPosition) {        \
    337       old_position = source_position();                      \
    338       SetSourcePosition(node->position());                   \
    339     }                                                        \
    340     HOptimizedGraphBuilder::Visit##type(node);               \
    341     if (!old_position.IsUnknown()) {                         \
    342       set_source_position(old_position);                     \
    343     }                                                        \
    344   }
    345   EXPRESSION_NODE_LIST(DEF_VISIT)
    346 #undef DEF_VISIT
    347 
    348 #define DEF_VISIT(type)                                      \
    349   void Visit##type(type* node) override {                    \
    350     SourcePosition old_position = SourcePosition::Unknown(); \
    351     if (node->position() != RelocInfo::kNoPosition) {        \
    352       old_position = source_position();                      \
    353       SetSourcePosition(node->position());                   \
    354     }                                                        \
    355     HOptimizedGraphBuilder::Visit##type(node);               \
    356     if (!old_position.IsUnknown()) {                         \
    357       set_source_position(old_position);                     \
    358     }                                                        \
    359   }
    360   STATEMENT_NODE_LIST(DEF_VISIT)
    361 #undef DEF_VISIT
    362 
    363 #define DEF_VISIT(type)                        \
    364   void Visit##type(type* node) override {      \
    365     HOptimizedGraphBuilder::Visit##type(node); \
    366   }
    367   DECLARATION_NODE_LIST(DEF_VISIT)
    368 #undef DEF_VISIT
    369 };
    370 
    371 
    372 OptimizedCompileJob::Status OptimizedCompileJob::CreateGraph() {
    373   DCHECK(info()->IsOptimizing());
    374 
    375   // Do not use Crankshaft/TurboFan if we need to be able to set break points.
    376   if (info()->shared_info()->HasDebugInfo()) {
    377     return AbortOptimization(kFunctionBeingDebugged);
    378   }
    379 
    380   // Limit the number of times we try to optimize functions.
    381   const int kMaxOptCount =
    382       FLAG_deopt_every_n_times == 0 ? FLAG_max_opt_count : 1000;
    383   if (info()->opt_count() > kMaxOptCount) {
    384     return AbortOptimization(kOptimizedTooManyTimes);
    385   }
    386 
    387   // Check the whitelist for Crankshaft.
    388   if (!info()->closure()->PassesFilter(FLAG_hydrogen_filter)) {
    389     return AbortOptimization(kHydrogenFilter);
    390   }
    391 
    392   // Optimization requires a version of fullcode with deoptimization support.
    393   // Recompile the unoptimized version of the code if the current version
    394   // doesn't have deoptimization support already.
    395   // Otherwise, if we are gathering compilation time and space statistics
    396   // for hydrogen, gather baseline statistics for a fullcode compilation.
    397   bool should_recompile = !info()->shared_info()->has_deoptimization_support();
    398   if (should_recompile || FLAG_hydrogen_stats) {
    399     base::ElapsedTimer timer;
    400     if (FLAG_hydrogen_stats) {
    401       timer.Start();
    402     }
    403     if (!Compiler::EnsureDeoptimizationSupport(info())) {
    404       return SetLastStatus(FAILED);
    405     }
    406     if (FLAG_hydrogen_stats) {
    407       isolate()->GetHStatistics()->IncrementFullCodeGen(timer.Elapsed());
    408     }
    409   }
    410 
    411   DCHECK(info()->shared_info()->has_deoptimization_support());
    412   DCHECK(!info()->is_first_compile());
    413 
    414   bool optimization_disabled = info()->shared_info()->optimization_disabled();
    415   bool dont_crankshaft = info()->shared_info()->dont_crankshaft();
    416 
    417   // Check the enabling conditions for Turbofan.
    418   // 1. "use asm" code.
    419   bool is_turbofanable_asm = FLAG_turbo_asm &&
    420                              info()->shared_info()->asm_function() &&
    421                              !optimization_disabled;
    422 
    423   // 2. Fallback for features unsupported by Crankshaft.
    424   bool is_unsupported_by_crankshaft_but_turbofanable =
    425       dont_crankshaft && strcmp(FLAG_turbo_filter, "~~") == 0 &&
    426       !optimization_disabled;
    427 
    428   // 3. Explicitly enabled by the command-line filter.
    429   bool passes_turbo_filter = info()->closure()->PassesFilter(FLAG_turbo_filter);
    430 
    431   // If this is OSR request, OSR must be enabled by Turbofan.
    432   bool passes_osr_test = FLAG_turbo_osr || !info()->is_osr();
    433 
    434   if ((is_turbofanable_asm || is_unsupported_by_crankshaft_but_turbofanable ||
    435        passes_turbo_filter) &&
    436       passes_osr_test) {
    437     // Use TurboFan for the compilation.
    438     if (FLAG_trace_opt) {
    439       OFStream os(stdout);
    440       os << "[compiling method " << Brief(*info()->closure())
    441          << " using TurboFan";
    442       if (info()->is_osr()) os << " OSR";
    443       os << "]" << std::endl;
    444     }
    445 
    446     if (info()->shared_info()->asm_function()) {
    447       if (info()->osr_frame()) info()->MarkAsFrameSpecializing();
    448       info()->MarkAsFunctionContextSpecializing();
    449     } else if (info()->has_global_object() &&
    450                FLAG_native_context_specialization) {
    451       info()->MarkAsNativeContextSpecializing();
    452       info()->MarkAsTypingEnabled();
    453     }
    454     if (!info()->shared_info()->asm_function() ||
    455         FLAG_turbo_asm_deoptimization) {
    456       info()->MarkAsDeoptimizationEnabled();
    457     }
    458 
    459     Timer t(this, &time_taken_to_create_graph_);
    460     compiler::Pipeline pipeline(info());
    461     pipeline.GenerateCode();
    462     if (!info()->code().is_null()) {
    463       return SetLastStatus(SUCCEEDED);
    464     }
    465   }
    466 
    467   if (!isolate()->use_crankshaft() || dont_crankshaft) {
    468     // Crankshaft is entirely disabled.
    469     return SetLastStatus(FAILED);
    470   }
    471 
    472   Scope* scope = info()->scope();
    473   if (LUnallocated::TooManyParameters(scope->num_parameters())) {
    474     // Crankshaft would require too many Lithium operands.
    475     return AbortOptimization(kTooManyParameters);
    476   }
    477 
    478   if (info()->is_osr() &&
    479       LUnallocated::TooManyParametersOrStackSlots(scope->num_parameters(),
    480                                                   scope->num_stack_slots())) {
    481     // Crankshaft would require too many Lithium operands.
    482     return AbortOptimization(kTooManyParametersLocals);
    483   }
    484 
    485   if (scope->HasIllegalRedeclaration()) {
    486     // Crankshaft cannot handle illegal redeclarations.
    487     return AbortOptimization(kFunctionWithIllegalRedeclaration);
    488   }
    489 
    490   if (FLAG_trace_opt) {
    491     OFStream os(stdout);
    492     os << "[compiling method " << Brief(*info()->closure())
    493        << " using Crankshaft";
    494     if (info()->is_osr()) os << " OSR";
    495     os << "]" << std::endl;
    496   }
    497 
    498   if (FLAG_trace_hydrogen) {
    499     isolate()->GetHTracer()->TraceCompilation(info());
    500   }
    501 
    502   // Type-check the function.
    503   AstTyper(info()->isolate(), info()->zone(), info()->closure(),
    504            info()->scope(), info()->osr_ast_id(), info()->literal())
    505       .Run();
    506 
    507   // Optimization could have been disabled by the parser. Note that this check
    508   // is only needed because the Hydrogen graph builder is missing some bailouts.
    509   if (info()->shared_info()->optimization_disabled()) {
    510     return AbortOptimization(
    511         info()->shared_info()->disable_optimization_reason());
    512   }
    513 
    514   graph_builder_ = (info()->is_tracking_positions() || FLAG_trace_ic)
    515                        ? new (info()->zone())
    516                              HOptimizedGraphBuilderWithPositions(info())
    517                        : new (info()->zone()) HOptimizedGraphBuilder(info());
    518 
    519   Timer t(this, &time_taken_to_create_graph_);
    520   graph_ = graph_builder_->CreateGraph();
    521 
    522   if (isolate()->has_pending_exception()) {
    523     return SetLastStatus(FAILED);
    524   }
    525 
    526   if (graph_ == NULL) return SetLastStatus(BAILED_OUT);
    527 
    528   if (info()->dependencies()->HasAborted()) {
    529     // Dependency has changed during graph creation. Let's try again later.
    530     return RetryOptimization(kBailedOutDueToDependencyChange);
    531   }
    532 
    533   return SetLastStatus(SUCCEEDED);
    534 }
    535 
    536 
    537 OptimizedCompileJob::Status OptimizedCompileJob::OptimizeGraph() {
    538   DisallowHeapAllocation no_allocation;
    539   DisallowHandleAllocation no_handles;
    540   DisallowHandleDereference no_deref;
    541   DisallowCodeDependencyChange no_dependency_change;
    542 
    543   DCHECK(last_status() == SUCCEEDED);
    544   // TODO(turbofan): Currently everything is done in the first phase.
    545   if (!info()->code().is_null()) {
    546     return last_status();
    547   }
    548 
    549   Timer t(this, &time_taken_to_optimize_);
    550   DCHECK(graph_ != NULL);
    551   BailoutReason bailout_reason = kNoReason;
    552 
    553   if (graph_->Optimize(&bailout_reason)) {
    554     chunk_ = LChunk::NewChunk(graph_);
    555     if (chunk_ != NULL) return SetLastStatus(SUCCEEDED);
    556   } else if (bailout_reason != kNoReason) {
    557     graph_builder_->Bailout(bailout_reason);
    558   }
    559 
    560   return SetLastStatus(BAILED_OUT);
    561 }
    562 
    563 
    564 namespace {
    565 
    566 void AddWeakObjectToCodeDependency(Isolate* isolate, Handle<HeapObject> object,
    567                                    Handle<Code> code) {
    568   Handle<WeakCell> cell = Code::WeakCellFor(code);
    569   Heap* heap = isolate->heap();
    570   Handle<DependentCode> dep(heap->LookupWeakObjectToCodeDependency(object));
    571   dep = DependentCode::InsertWeakCode(dep, DependentCode::kWeakCodeGroup, cell);
    572   heap->AddWeakObjectToCodeDependency(object, dep);
    573 }
    574 
    575 
    576 void RegisterWeakObjectsInOptimizedCode(Handle<Code> code) {
    577   // TODO(turbofan): Move this to pipeline.cc once Crankshaft dies.
    578   Isolate* const isolate = code->GetIsolate();
    579   DCHECK(code->is_optimized_code());
    580   std::vector<Handle<Map>> maps;
    581   std::vector<Handle<HeapObject>> objects;
    582   {
    583     DisallowHeapAllocation no_gc;
    584     int const mode_mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT) |
    585                           RelocInfo::ModeMask(RelocInfo::CELL);
    586     for (RelocIterator it(*code, mode_mask); !it.done(); it.next()) {
    587       RelocInfo::Mode mode = it.rinfo()->rmode();
    588       if (mode == RelocInfo::CELL &&
    589           code->IsWeakObjectInOptimizedCode(it.rinfo()->target_cell())) {
    590         objects.push_back(handle(it.rinfo()->target_cell(), isolate));
    591       } else if (mode == RelocInfo::EMBEDDED_OBJECT &&
    592                  code->IsWeakObjectInOptimizedCode(
    593                      it.rinfo()->target_object())) {
    594         Handle<HeapObject> object(HeapObject::cast(it.rinfo()->target_object()),
    595                                   isolate);
    596         if (object->IsMap()) {
    597           maps.push_back(Handle<Map>::cast(object));
    598         } else {
    599           objects.push_back(object);
    600         }
    601       }
    602     }
    603   }
    604   for (Handle<Map> map : maps) {
    605     if (map->dependent_code()->IsEmpty(DependentCode::kWeakCodeGroup)) {
    606       isolate->heap()->AddRetainedMap(map);
    607     }
    608     Map::AddDependentCode(map, DependentCode::kWeakCodeGroup, code);
    609   }
    610   for (Handle<HeapObject> object : objects) {
    611     AddWeakObjectToCodeDependency(isolate, object, code);
    612   }
    613   code->set_can_have_weak_objects(true);
    614 }
    615 
    616 }  // namespace
    617 
    618 
    619 OptimizedCompileJob::Status OptimizedCompileJob::GenerateCode() {
    620   DCHECK(last_status() == SUCCEEDED);
    621   // TODO(turbofan): Currently everything is done in the first phase.
    622   if (!info()->code().is_null()) {
    623     info()->dependencies()->Commit(info()->code());
    624     if (info()->is_deoptimization_enabled()) {
    625       info()->parse_info()->context()->native_context()->AddOptimizedCode(
    626           *info()->code());
    627       RegisterWeakObjectsInOptimizedCode(info()->code());
    628     }
    629     RecordOptimizationStats();
    630     return last_status();
    631   }
    632 
    633   DCHECK(!info()->dependencies()->HasAborted());
    634   DisallowCodeDependencyChange no_dependency_change;
    635   DisallowJavascriptExecution no_js(isolate());
    636   {  // Scope for timer.
    637     Timer timer(this, &time_taken_to_codegen_);
    638     DCHECK(chunk_ != NULL);
    639     DCHECK(graph_ != NULL);
    640     // Deferred handles reference objects that were accessible during
    641     // graph creation.  To make sure that we don't encounter inconsistencies
    642     // between graph creation and code generation, we disallow accessing
    643     // objects through deferred handles during the latter, with exceptions.
    644     DisallowDeferredHandleDereference no_deferred_handle_deref;
    645     Handle<Code> optimized_code = chunk_->Codegen();
    646     if (optimized_code.is_null()) {
    647       if (info()->bailout_reason() == kNoReason) {
    648         return AbortOptimization(kCodeGenerationFailed);
    649       }
    650       return SetLastStatus(BAILED_OUT);
    651     }
    652     RegisterWeakObjectsInOptimizedCode(optimized_code);
    653     info()->SetCode(optimized_code);
    654   }
    655   RecordOptimizationStats();
    656   // Add to the weak list of optimized code objects.
    657   info()->context()->native_context()->AddOptimizedCode(*info()->code());
    658   return SetLastStatus(SUCCEEDED);
    659 }
    660 
    661 
    662 void OptimizedCompileJob::RecordOptimizationStats() {
    663   Handle<JSFunction> function = info()->closure();
    664   if (!function->IsOptimized()) {
    665     // Concurrent recompilation and OSR may race.  Increment only once.
    666     int opt_count = function->shared()->opt_count();
    667     function->shared()->set_opt_count(opt_count + 1);
    668   }
    669   double ms_creategraph = time_taken_to_create_graph_.InMillisecondsF();
    670   double ms_optimize = time_taken_to_optimize_.InMillisecondsF();
    671   double ms_codegen = time_taken_to_codegen_.InMillisecondsF();
    672   if (FLAG_trace_opt) {
    673     PrintF("[optimizing ");
    674     function->ShortPrint();
    675     PrintF(" - took %0.3f, %0.3f, %0.3f ms]\n", ms_creategraph, ms_optimize,
    676            ms_codegen);
    677   }
    678   if (FLAG_trace_opt_stats) {
    679     static double compilation_time = 0.0;
    680     static int compiled_functions = 0;
    681     static int code_size = 0;
    682 
    683     compilation_time += (ms_creategraph + ms_optimize + ms_codegen);
    684     compiled_functions++;
    685     code_size += function->shared()->SourceSize();
    686     PrintF("Compiled: %d functions with %d byte source size in %fms.\n",
    687            compiled_functions,
    688            code_size,
    689            compilation_time);
    690   }
    691   if (FLAG_hydrogen_stats) {
    692     isolate()->GetHStatistics()->IncrementSubtotals(time_taken_to_create_graph_,
    693                                                     time_taken_to_optimize_,
    694                                                     time_taken_to_codegen_);
    695   }
    696 }
    697 
    698 
    699 // Sets the expected number of properties based on estimate from compiler.
    700 void SetExpectedNofPropertiesFromEstimate(Handle<SharedFunctionInfo> shared,
    701                                           int estimate) {
    702   // If no properties are added in the constructor, they are more likely
    703   // to be added later.
    704   if (estimate == 0) estimate = 2;
    705 
    706   // TODO(yangguo): check whether those heuristics are still up-to-date.
    707   // We do not shrink objects that go into a snapshot (yet), so we adjust
    708   // the estimate conservatively.
    709   if (shared->GetIsolate()->serializer_enabled()) {
    710     estimate += 2;
    711   } else {
    712     // Inobject slack tracking will reclaim redundant inobject space later,
    713     // so we can afford to adjust the estimate generously.
    714     estimate += 8;
    715   }
    716 
    717   shared->set_expected_nof_properties(estimate);
    718 }
    719 
    720 
    721 static void MaybeDisableOptimization(Handle<SharedFunctionInfo> shared_info,
    722                                      BailoutReason bailout_reason) {
    723   if (bailout_reason != kNoReason) {
    724     shared_info->DisableOptimization(bailout_reason);
    725   }
    726 }
    727 
    728 
    729 static void RecordFunctionCompilation(Logger::LogEventsAndTags tag,
    730                                       CompilationInfo* info,
    731                                       Handle<SharedFunctionInfo> shared) {
    732   // SharedFunctionInfo is passed separately, because if CompilationInfo
    733   // was created using Script object, it will not have it.
    734 
    735   // Log the code generation. If source information is available include
    736   // script name and line number. Check explicitly whether logging is
    737   // enabled as finding the line number is not free.
    738   if (info->isolate()->logger()->is_logging_code_events() ||
    739       info->isolate()->cpu_profiler()->is_profiling()) {
    740     Handle<Script> script = info->parse_info()->script();
    741     Handle<Code> code = info->code();
    742     if (code.is_identical_to(info->isolate()->builtins()->CompileLazy())) {
    743       return;
    744     }
    745     int line_num = Script::GetLineNumber(script, shared->start_position()) + 1;
    746     int column_num =
    747         Script::GetColumnNumber(script, shared->start_position()) + 1;
    748     String* script_name = script->name()->IsString()
    749                               ? String::cast(script->name())
    750                               : info->isolate()->heap()->empty_string();
    751     Logger::LogEventsAndTags log_tag = Logger::ToNativeByScript(tag, *script);
    752     PROFILE(info->isolate(),
    753             CodeCreateEvent(log_tag, *code, *shared, info, script_name,
    754                             line_num, column_num));
    755   }
    756 }
    757 
    758 
    759 static bool CompileUnoptimizedCode(CompilationInfo* info) {
    760   DCHECK(AllowCompilation::IsAllowed(info->isolate()));
    761   if (!Compiler::Analyze(info->parse_info()) ||
    762       !FullCodeGenerator::MakeCode(info)) {
    763     Isolate* isolate = info->isolate();
    764     if (!isolate->has_pending_exception()) isolate->StackOverflow();
    765     return false;
    766   }
    767   return true;
    768 }
    769 
    770 
    771 // TODO(rmcilroy): Remove this temporary work-around when ignition supports
    772 // catch and eval.
    773 static bool IgnitionShouldFallbackToFullCodeGen(Scope* scope) {
    774   if (scope->is_eval_scope() || scope->is_catch_scope() ||
    775       scope->calls_eval()) {
    776     return true;
    777   }
    778   for (auto inner_scope : *scope->inner_scopes()) {
    779     if (IgnitionShouldFallbackToFullCodeGen(inner_scope)) return true;
    780   }
    781   return false;
    782 }
    783 
    784 
    785 static bool UseIgnition(CompilationInfo* info) {
    786   // Cannot use Ignition when the {function_data} is already used.
    787   if (info->has_shared_info() && info->shared_info()->HasBuiltinFunctionId()) {
    788     return false;
    789   }
    790 
    791   // Checks whether the scope chain is supported.
    792   if (FLAG_ignition_fallback_on_eval_and_catch &&
    793       IgnitionShouldFallbackToFullCodeGen(info->scope())) {
    794     return false;
    795   }
    796 
    797   // Checks whether top level functions should be passed by the filter.
    798   if (info->closure().is_null()) {
    799     Vector<const char> filter = CStrVector(FLAG_ignition_filter);
    800     return (filter.length() == 0) || (filter.length() == 1 && filter[0] == '*');
    801   }
    802 
    803   // Finally respect the filter.
    804   return info->closure()->PassesFilter(FLAG_ignition_filter);
    805 }
    806 
    807 
    808 static bool GenerateBaselineCode(CompilationInfo* info) {
    809   if (FLAG_ignition && UseIgnition(info)) {
    810     return interpreter::Interpreter::MakeBytecode(info);
    811   } else {
    812     return FullCodeGenerator::MakeCode(info);
    813   }
    814 }
    815 
    816 
    817 static bool CompileBaselineCode(CompilationInfo* info) {
    818   DCHECK(AllowCompilation::IsAllowed(info->isolate()));
    819   if (!Compiler::Analyze(info->parse_info()) || !GenerateBaselineCode(info)) {
    820     Isolate* isolate = info->isolate();
    821     if (!isolate->has_pending_exception()) isolate->StackOverflow();
    822     return false;
    823   }
    824   return true;
    825 }
    826 
    827 
    828 MUST_USE_RESULT static MaybeHandle<Code> GetUnoptimizedCodeCommon(
    829     CompilationInfo* info) {
    830   VMState<COMPILER> state(info->isolate());
    831   PostponeInterruptsScope postpone(info->isolate());
    832 
    833   // Parse and update CompilationInfo with the results.
    834   if (!Parser::ParseStatic(info->parse_info())) return MaybeHandle<Code>();
    835   Handle<SharedFunctionInfo> shared = info->shared_info();
    836   FunctionLiteral* lit = info->literal();
    837   DCHECK_EQ(shared->language_mode(), lit->language_mode());
    838   SetExpectedNofPropertiesFromEstimate(shared, lit->expected_property_count());
    839   MaybeDisableOptimization(shared, lit->dont_optimize_reason());
    840 
    841   // Compile either unoptimized code or bytecode for the interpreter.
    842   if (!CompileBaselineCode(info)) return MaybeHandle<Code>();
    843   if (info->code()->kind() == Code::FUNCTION) {  // Only for full code.
    844     RecordFunctionCompilation(Logger::LAZY_COMPILE_TAG, info, shared);
    845   }
    846 
    847   // Update the shared function info with the scope info. Allocating the
    848   // ScopeInfo object may cause a GC.
    849   Handle<ScopeInfo> scope_info =
    850       ScopeInfo::Create(info->isolate(), info->zone(), info->scope());
    851   shared->set_scope_info(*scope_info);
    852 
    853   // Update the code and feedback vector for the shared function info.
    854   shared->ReplaceCode(*info->code());
    855   shared->set_feedback_vector(*info->feedback_vector());
    856   if (info->has_bytecode_array()) {
    857     DCHECK(shared->function_data()->IsUndefined());
    858     shared->set_function_data(*info->bytecode_array());
    859   }
    860 
    861   return info->code();
    862 }
    863 
    864 
    865 MUST_USE_RESULT static MaybeHandle<Code> GetCodeFromOptimizedCodeMap(
    866     Handle<JSFunction> function, BailoutId osr_ast_id) {
    867   Handle<SharedFunctionInfo> shared(function->shared());
    868   DisallowHeapAllocation no_gc;
    869   CodeAndLiterals cached = shared->SearchOptimizedCodeMap(
    870       function->context()->native_context(), osr_ast_id);
    871   if (cached.code != nullptr) {
    872     // Caching of optimized code enabled and optimized code found.
    873     if (cached.literals != nullptr) function->set_literals(cached.literals);
    874     DCHECK(!cached.code->marked_for_deoptimization());
    875     DCHECK(function->shared()->is_compiled());
    876     return Handle<Code>(cached.code);
    877   }
    878   return MaybeHandle<Code>();
    879 }
    880 
    881 
    882 static void InsertCodeIntoOptimizedCodeMap(CompilationInfo* info) {
    883   Handle<Code> code = info->code();
    884   if (code->kind() != Code::OPTIMIZED_FUNCTION) return;  // Nothing to do.
    885 
    886   // Function context specialization folds-in the function context,
    887   // so no sharing can occur.
    888   if (info->is_function_context_specializing()) return;
    889   // Frame specialization implies function context specialization.
    890   DCHECK(!info->is_frame_specializing());
    891 
    892   // Cache optimized context-specific code.
    893   Handle<JSFunction> function = info->closure();
    894   Handle<SharedFunctionInfo> shared(function->shared());
    895   Handle<LiteralsArray> literals(function->literals());
    896   Handle<Context> native_context(function->context()->native_context());
    897   SharedFunctionInfo::AddToOptimizedCodeMap(shared, native_context, code,
    898                                             literals, info->osr_ast_id());
    899 
    900   // Do not cache (native) context-independent code compiled for OSR.
    901   if (code->is_turbofanned() && info->is_osr()) return;
    902 
    903   // Cache optimized (native) context-independent code.
    904   if (FLAG_turbo_cache_shared_code && code->is_turbofanned() &&
    905       !info->is_native_context_specializing()) {
    906     DCHECK(!info->is_function_context_specializing());
    907     DCHECK(info->osr_ast_id().IsNone());
    908     Handle<SharedFunctionInfo> shared(function->shared());
    909     SharedFunctionInfo::AddSharedCodeToOptimizedCodeMap(shared, code);
    910   }
    911 }
    912 
    913 
    914 static bool Renumber(ParseInfo* parse_info) {
    915   if (!AstNumbering::Renumber(parse_info->isolate(), parse_info->zone(),
    916                               parse_info->literal())) {
    917     return false;
    918   }
    919   Handle<SharedFunctionInfo> shared_info = parse_info->shared_info();
    920   if (!shared_info.is_null()) {
    921     FunctionLiteral* lit = parse_info->literal();
    922     shared_info->set_ast_node_count(lit->ast_node_count());
    923     MaybeDisableOptimization(shared_info, lit->dont_optimize_reason());
    924     shared_info->set_dont_crankshaft(lit->flags() &
    925                                      AstProperties::kDontCrankshaft);
    926   }
    927   return true;
    928 }
    929 
    930 
    931 bool Compiler::Analyze(ParseInfo* info) {
    932   DCHECK_NOT_NULL(info->literal());
    933   if (!Rewriter::Rewrite(info)) return false;
    934   if (!Scope::Analyze(info)) return false;
    935   if (!Renumber(info)) return false;
    936   DCHECK_NOT_NULL(info->scope());
    937   return true;
    938 }
    939 
    940 
    941 bool Compiler::ParseAndAnalyze(ParseInfo* info) {
    942   if (!Parser::ParseStatic(info)) return false;
    943   return Compiler::Analyze(info);
    944 }
    945 
    946 
    947 static bool GetOptimizedCodeNow(CompilationInfo* info) {
    948   Isolate* isolate = info->isolate();
    949   CanonicalHandleScope canonical(isolate);
    950 
    951   if (!Compiler::ParseAndAnalyze(info->parse_info())) return false;
    952 
    953   TimerEventScope<TimerEventRecompileSynchronous> timer(isolate);
    954 
    955   OptimizedCompileJob job(info);
    956   if (job.CreateGraph() != OptimizedCompileJob::SUCCEEDED ||
    957       job.OptimizeGraph() != OptimizedCompileJob::SUCCEEDED ||
    958       job.GenerateCode() != OptimizedCompileJob::SUCCEEDED) {
    959     if (FLAG_trace_opt) {
    960       PrintF("[aborted optimizing ");
    961       info->closure()->ShortPrint();
    962       PrintF(" because: %s]\n", GetBailoutReason(info->bailout_reason()));
    963     }
    964     return false;
    965   }
    966 
    967   // Success!
    968   DCHECK(!isolate->has_pending_exception());
    969   InsertCodeIntoOptimizedCodeMap(info);
    970   RecordFunctionCompilation(Logger::LAZY_COMPILE_TAG, info,
    971                             info->shared_info());
    972   return true;
    973 }
    974 
    975 
    976 static bool GetOptimizedCodeLater(CompilationInfo* info) {
    977   Isolate* isolate = info->isolate();
    978   CanonicalHandleScope canonical(isolate);
    979 
    980   if (!isolate->optimizing_compile_dispatcher()->IsQueueAvailable()) {
    981     if (FLAG_trace_concurrent_recompilation) {
    982       PrintF("  ** Compilation queue full, will retry optimizing ");
    983       info->closure()->ShortPrint();
    984       PrintF(" later.\n");
    985     }
    986     return false;
    987   }
    988 
    989   CompilationHandleScope handle_scope(info);
    990   if (!Compiler::ParseAndAnalyze(info->parse_info())) return false;
    991 
    992   // Reopen handles in the new CompilationHandleScope.
    993   info->ReopenHandlesInNewHandleScope();
    994   info->parse_info()->ReopenHandlesInNewHandleScope();
    995 
    996   TimerEventScope<TimerEventRecompileSynchronous> timer(info->isolate());
    997 
    998   OptimizedCompileJob* job = new (info->zone()) OptimizedCompileJob(info);
    999   OptimizedCompileJob::Status status = job->CreateGraph();
   1000   if (status != OptimizedCompileJob::SUCCEEDED) return false;
   1001   isolate->optimizing_compile_dispatcher()->QueueForOptimization(job);
   1002 
   1003   if (FLAG_trace_concurrent_recompilation) {
   1004     PrintF("  ** Queued ");
   1005     info->closure()->ShortPrint();
   1006     if (info->is_osr()) {
   1007       PrintF(" for concurrent OSR at %d.\n", info->osr_ast_id().ToInt());
   1008     } else {
   1009       PrintF(" for concurrent optimization.\n");
   1010     }
   1011   }
   1012   return true;
   1013 }
   1014 
   1015 
   1016 MaybeHandle<Code> Compiler::GetUnoptimizedCode(Handle<JSFunction> function) {
   1017   DCHECK(!function->GetIsolate()->has_pending_exception());
   1018   DCHECK(!function->is_compiled());
   1019   if (function->shared()->is_compiled()) {
   1020     return Handle<Code>(function->shared()->code());
   1021   }
   1022 
   1023   CompilationInfoWithZone info(function);
   1024   Handle<Code> result;
   1025   ASSIGN_RETURN_ON_EXCEPTION(info.isolate(), result,
   1026                              GetUnoptimizedCodeCommon(&info),
   1027                              Code);
   1028   return result;
   1029 }
   1030 
   1031 
   1032 MaybeHandle<Code> Compiler::GetLazyCode(Handle<JSFunction> function) {
   1033   Isolate* isolate = function->GetIsolate();
   1034   DCHECK(!isolate->has_pending_exception());
   1035   DCHECK(!function->is_compiled());
   1036   AggregatedHistogramTimerScope timer(isolate->counters()->compile_lazy());
   1037   // If the debugger is active, do not compile with turbofan unless we can
   1038   // deopt from turbofan code.
   1039   if (FLAG_turbo_asm && function->shared()->asm_function() &&
   1040       (FLAG_turbo_asm_deoptimization || !isolate->debug()->is_active()) &&
   1041       !FLAG_turbo_osr) {
   1042     CompilationInfoWithZone info(function);
   1043 
   1044     VMState<COMPILER> state(isolate);
   1045     PostponeInterruptsScope postpone(isolate);
   1046 
   1047     info.SetOptimizing(BailoutId::None(), handle(function->shared()->code()));
   1048 
   1049     if (GetOptimizedCodeNow(&info)) {
   1050       DCHECK(function->shared()->is_compiled());
   1051       return info.code();
   1052     }
   1053     // We have failed compilation. If there was an exception clear it so that
   1054     // we can compile unoptimized code.
   1055     if (isolate->has_pending_exception()) isolate->clear_pending_exception();
   1056   }
   1057 
   1058   if (function->shared()->is_compiled()) {
   1059     return Handle<Code>(function->shared()->code());
   1060   }
   1061 
   1062   CompilationInfoWithZone info(function);
   1063   Handle<Code> result;
   1064   ASSIGN_RETURN_ON_EXCEPTION(isolate, result, GetUnoptimizedCodeCommon(&info),
   1065                              Code);
   1066 
   1067   if (FLAG_always_opt) {
   1068     Handle<Code> opt_code;
   1069     if (Compiler::GetOptimizedCode(
   1070             function, result,
   1071             Compiler::NOT_CONCURRENT).ToHandle(&opt_code)) {
   1072       result = opt_code;
   1073     }
   1074   }
   1075 
   1076   return result;
   1077 }
   1078 
   1079 
   1080 bool Compiler::Compile(Handle<JSFunction> function, ClearExceptionFlag flag) {
   1081   if (function->is_compiled()) return true;
   1082   MaybeHandle<Code> maybe_code = Compiler::GetLazyCode(function);
   1083   Handle<Code> code;
   1084   if (!maybe_code.ToHandle(&code)) {
   1085     if (flag == CLEAR_EXCEPTION) {
   1086       function->GetIsolate()->clear_pending_exception();
   1087     }
   1088     return false;
   1089   }
   1090   function->ReplaceCode(*code);
   1091   DCHECK(function->is_compiled());
   1092   return true;
   1093 }
   1094 
   1095 
   1096 // TODO(turbofan): In the future, unoptimized code with deopt support could
   1097 // be generated lazily once deopt is triggered.
   1098 bool Compiler::EnsureDeoptimizationSupport(CompilationInfo* info) {
   1099   DCHECK_NOT_NULL(info->literal());
   1100   DCHECK(info->has_scope());
   1101   Handle<SharedFunctionInfo> shared = info->shared_info();
   1102   if (!shared->has_deoptimization_support()) {
   1103     // TODO(titzer): just reuse the ParseInfo for the unoptimized compile.
   1104     CompilationInfoWithZone unoptimized(info->closure());
   1105     // Note that we use the same AST that we will use for generating the
   1106     // optimized code.
   1107     ParseInfo* parse_info = unoptimized.parse_info();
   1108     parse_info->set_literal(info->literal());
   1109     parse_info->set_scope(info->scope());
   1110     parse_info->set_context(info->context());
   1111     unoptimized.EnableDeoptimizationSupport();
   1112     // If the current code has reloc info for serialization, also include
   1113     // reloc info for serialization for the new code, so that deopt support
   1114     // can be added without losing IC state.
   1115     if (shared->code()->kind() == Code::FUNCTION &&
   1116         shared->code()->has_reloc_info_for_serialization()) {
   1117       unoptimized.PrepareForSerializing();
   1118     }
   1119     if (!FullCodeGenerator::MakeCode(&unoptimized)) return false;
   1120 
   1121     shared->EnableDeoptimizationSupport(*unoptimized.code());
   1122     shared->set_feedback_vector(*unoptimized.feedback_vector());
   1123 
   1124     info->MarkAsCompiled();
   1125 
   1126     // The scope info might not have been set if a lazily compiled
   1127     // function is inlined before being called for the first time.
   1128     if (shared->scope_info() == ScopeInfo::Empty(info->isolate())) {
   1129       Handle<ScopeInfo> target_scope_info =
   1130           ScopeInfo::Create(info->isolate(), info->zone(), info->scope());
   1131       shared->set_scope_info(*target_scope_info);
   1132     }
   1133 
   1134     // The existing unoptimized code was replaced with the new one.
   1135     RecordFunctionCompilation(Logger::LAZY_COMPILE_TAG, &unoptimized, shared);
   1136   }
   1137   return true;
   1138 }
   1139 
   1140 
   1141 bool CompileEvalForDebugging(Handle<JSFunction> function,
   1142                              Handle<SharedFunctionInfo> shared) {
   1143   Handle<Script> script(Script::cast(shared->script()));
   1144   Handle<Context> context(function->context());
   1145 
   1146   Zone zone;
   1147   ParseInfo parse_info(&zone, script);
   1148   CompilationInfo info(&parse_info);
   1149   Isolate* isolate = info.isolate();
   1150 
   1151   parse_info.set_eval();
   1152   parse_info.set_context(context);
   1153   if (context->IsNativeContext()) parse_info.set_global();
   1154   parse_info.set_toplevel();
   1155   parse_info.set_allow_lazy_parsing(false);
   1156   parse_info.set_language_mode(shared->language_mode());
   1157   parse_info.set_parse_restriction(NO_PARSE_RESTRICTION);
   1158   info.MarkAsDebug();
   1159 
   1160   VMState<COMPILER> state(info.isolate());
   1161 
   1162   if (!Parser::ParseStatic(&parse_info)) {
   1163     isolate->clear_pending_exception();
   1164     return false;
   1165   }
   1166 
   1167   FunctionLiteral* lit = parse_info.literal();
   1168   LiveEditFunctionTracker live_edit_tracker(isolate, lit);
   1169 
   1170   if (!CompileUnoptimizedCode(&info)) {
   1171     isolate->clear_pending_exception();
   1172     return false;
   1173   }
   1174   shared->ReplaceCode(*info.code());
   1175   return true;
   1176 }
   1177 
   1178 
   1179 bool CompileForDebugging(CompilationInfo* info) {
   1180   info->MarkAsDebug();
   1181   if (GetUnoptimizedCodeCommon(info).is_null()) {
   1182     info->isolate()->clear_pending_exception();
   1183     return false;
   1184   }
   1185   return true;
   1186 }
   1187 
   1188 
   1189 static inline bool IsEvalToplevel(Handle<SharedFunctionInfo> shared) {
   1190   return shared->is_toplevel() && shared->script()->IsScript() &&
   1191          Script::cast(shared->script())->compilation_type() ==
   1192              Script::COMPILATION_TYPE_EVAL;
   1193 }
   1194 
   1195 
   1196 bool Compiler::CompileDebugCode(Handle<JSFunction> function) {
   1197   Handle<SharedFunctionInfo> shared(function->shared());
   1198   if (IsEvalToplevel(shared)) {
   1199     return CompileEvalForDebugging(function, shared);
   1200   } else {
   1201     CompilationInfoWithZone info(function);
   1202     return CompileForDebugging(&info);
   1203   }
   1204 }
   1205 
   1206 
   1207 bool Compiler::CompileDebugCode(Handle<SharedFunctionInfo> shared) {
   1208   DCHECK(shared->allows_lazy_compilation_without_context());
   1209   DCHECK(!IsEvalToplevel(shared));
   1210   Zone zone;
   1211   ParseInfo parse_info(&zone, shared);
   1212   CompilationInfo info(&parse_info);
   1213   return CompileForDebugging(&info);
   1214 }
   1215 
   1216 
   1217 void Compiler::CompileForLiveEdit(Handle<Script> script) {
   1218   // TODO(635): support extensions.
   1219   Zone zone;
   1220   ParseInfo parse_info(&zone, script);
   1221   CompilationInfo info(&parse_info);
   1222   PostponeInterruptsScope postpone(info.isolate());
   1223   VMState<COMPILER> state(info.isolate());
   1224 
   1225   // Get rid of old list of shared function infos.
   1226   info.MarkAsFirstCompile();
   1227   info.MarkAsDebug();
   1228   info.parse_info()->set_global();
   1229   if (!Parser::ParseStatic(info.parse_info())) return;
   1230 
   1231   LiveEditFunctionTracker tracker(info.isolate(), parse_info.literal());
   1232   if (!CompileUnoptimizedCode(&info)) return;
   1233   if (info.has_shared_info()) {
   1234     Handle<ScopeInfo> scope_info =
   1235         ScopeInfo::Create(info.isolate(), info.zone(), info.scope());
   1236     info.shared_info()->set_scope_info(*scope_info);
   1237   }
   1238   tracker.RecordRootFunctionInfo(info.code());
   1239 }
   1240 
   1241 
   1242 static Handle<SharedFunctionInfo> CompileToplevel(CompilationInfo* info) {
   1243   Isolate* isolate = info->isolate();
   1244   PostponeInterruptsScope postpone(isolate);
   1245   DCHECK(!isolate->native_context().is_null());
   1246   ParseInfo* parse_info = info->parse_info();
   1247   Handle<Script> script = parse_info->script();
   1248 
   1249   // TODO(svenpanne) Obscure place for this, perhaps move to OnBeforeCompile?
   1250   FixedArray* array = isolate->native_context()->embedder_data();
   1251   script->set_context_data(array->get(v8::Context::kDebugIdIndex));
   1252 
   1253   isolate->debug()->OnBeforeCompile(script);
   1254 
   1255   DCHECK(parse_info->is_eval() || parse_info->is_global() ||
   1256          parse_info->is_module());
   1257 
   1258   parse_info->set_toplevel();
   1259 
   1260   Handle<SharedFunctionInfo> result;
   1261 
   1262   { VMState<COMPILER> state(info->isolate());
   1263     if (parse_info->literal() == NULL) {
   1264       // Parse the script if needed (if it's already parsed, literal() is
   1265       // non-NULL). If compiling for debugging, we may eagerly compile inner
   1266       // functions, so do not parse lazily in that case.
   1267       ScriptCompiler::CompileOptions options = parse_info->compile_options();
   1268       bool parse_allow_lazy = (options == ScriptCompiler::kConsumeParserCache ||
   1269                                String::cast(script->source())->length() >
   1270                                    FLAG_min_preparse_length) &&
   1271                               !info->is_debug();
   1272 
   1273       parse_info->set_allow_lazy_parsing(parse_allow_lazy);
   1274       if (!parse_allow_lazy &&
   1275           (options == ScriptCompiler::kProduceParserCache ||
   1276            options == ScriptCompiler::kConsumeParserCache)) {
   1277         // We are going to parse eagerly, but we either 1) have cached data
   1278         // produced by lazy parsing or 2) are asked to generate cached data.
   1279         // Eager parsing cannot benefit from cached data, and producing cached
   1280         // data while parsing eagerly is not implemented.
   1281         parse_info->set_cached_data(nullptr);
   1282         parse_info->set_compile_options(ScriptCompiler::kNoCompileOptions);
   1283       }
   1284       if (!Parser::ParseStatic(parse_info)) {
   1285         return Handle<SharedFunctionInfo>::null();
   1286       }
   1287     }
   1288 
   1289     DCHECK(!info->is_debug() || !parse_info->allow_lazy_parsing());
   1290 
   1291     info->MarkAsFirstCompile();
   1292 
   1293     FunctionLiteral* lit = parse_info->literal();
   1294     LiveEditFunctionTracker live_edit_tracker(isolate, lit);
   1295 
   1296     // Measure how long it takes to do the compilation; only take the
   1297     // rest of the function into account to avoid overlap with the
   1298     // parsing statistics.
   1299     HistogramTimer* rate = info->is_eval()
   1300           ? info->isolate()->counters()->compile_eval()
   1301           : info->isolate()->counters()->compile();
   1302     HistogramTimerScope timer(rate);
   1303 
   1304     // Compile the code.
   1305     if (!CompileBaselineCode(info)) {
   1306       return Handle<SharedFunctionInfo>::null();
   1307     }
   1308 
   1309     // Allocate function.
   1310     DCHECK(!info->code().is_null());
   1311     result = isolate->factory()->NewSharedFunctionInfo(
   1312         lit->name(), lit->materialized_literal_count(), lit->kind(),
   1313         info->code(),
   1314         ScopeInfo::Create(info->isolate(), info->zone(), info->scope()),
   1315         info->feedback_vector());
   1316     if (info->has_bytecode_array()) {
   1317       DCHECK(result->function_data()->IsUndefined());
   1318       result->set_function_data(*info->bytecode_array());
   1319     }
   1320 
   1321     DCHECK_EQ(RelocInfo::kNoPosition, lit->function_token_position());
   1322     SharedFunctionInfo::InitFromFunctionLiteral(result, lit);
   1323     SharedFunctionInfo::SetScript(result, script);
   1324     result->set_is_toplevel(true);
   1325     if (info->is_eval()) {
   1326       // Eval scripts cannot be (re-)compiled without context.
   1327       result->set_allows_lazy_compilation_without_context(false);
   1328     }
   1329 
   1330     Handle<String> script_name =
   1331         script->name()->IsString()
   1332             ? Handle<String>(String::cast(script->name()))
   1333             : isolate->factory()->empty_string();
   1334     Logger::LogEventsAndTags log_tag = info->is_eval()
   1335         ? Logger::EVAL_TAG
   1336         : Logger::ToNativeByScript(Logger::SCRIPT_TAG, *script);
   1337 
   1338     PROFILE(isolate, CodeCreateEvent(
   1339                 log_tag, *info->code(), *result, info, *script_name));
   1340 
   1341     // Hint to the runtime system used when allocating space for initial
   1342     // property space by setting the expected number of properties for
   1343     // the instances of the function.
   1344     SetExpectedNofPropertiesFromEstimate(result,
   1345                                          lit->expected_property_count());
   1346 
   1347     if (!script.is_null())
   1348       script->set_compilation_state(Script::COMPILATION_STATE_COMPILED);
   1349 
   1350     live_edit_tracker.RecordFunctionInfo(result, lit, info->zone());
   1351   }
   1352 
   1353   return result;
   1354 }
   1355 
   1356 
   1357 MaybeHandle<JSFunction> Compiler::GetFunctionFromEval(
   1358     Handle<String> source, Handle<SharedFunctionInfo> outer_info,
   1359     Handle<Context> context, LanguageMode language_mode,
   1360     ParseRestriction restriction, int line_offset, int column_offset,
   1361     Handle<Object> script_name, ScriptOriginOptions options) {
   1362   Isolate* isolate = source->GetIsolate();
   1363   int source_length = source->length();
   1364   isolate->counters()->total_eval_size()->Increment(source_length);
   1365   isolate->counters()->total_compile_size()->Increment(source_length);
   1366 
   1367   CompilationCache* compilation_cache = isolate->compilation_cache();
   1368   MaybeHandle<SharedFunctionInfo> maybe_shared_info =
   1369       compilation_cache->LookupEval(source, outer_info, context, language_mode,
   1370                                     line_offset);
   1371   Handle<SharedFunctionInfo> shared_info;
   1372 
   1373   Handle<Script> script;
   1374   if (!maybe_shared_info.ToHandle(&shared_info)) {
   1375     script = isolate->factory()->NewScript(source);
   1376     if (!script_name.is_null()) {
   1377       script->set_name(*script_name);
   1378       script->set_line_offset(line_offset);
   1379       script->set_column_offset(column_offset);
   1380     }
   1381     script->set_origin_options(options);
   1382     Zone zone;
   1383     ParseInfo parse_info(&zone, script);
   1384     CompilationInfo info(&parse_info);
   1385     parse_info.set_eval();
   1386     if (context->IsNativeContext()) parse_info.set_global();
   1387     parse_info.set_language_mode(language_mode);
   1388     parse_info.set_parse_restriction(restriction);
   1389     parse_info.set_context(context);
   1390 
   1391     Debug::RecordEvalCaller(script);
   1392 
   1393     shared_info = CompileToplevel(&info);
   1394 
   1395     if (shared_info.is_null()) {
   1396       return MaybeHandle<JSFunction>();
   1397     } else {
   1398       // Explicitly disable optimization for eval code. We're not yet prepared
   1399       // to handle eval-code in the optimizing compiler.
   1400       if (restriction != ONLY_SINGLE_FUNCTION_LITERAL) {
   1401         shared_info->DisableOptimization(kEval);
   1402       }
   1403 
   1404       // If caller is strict mode, the result must be in strict mode as well.
   1405       DCHECK(is_sloppy(language_mode) ||
   1406              is_strict(shared_info->language_mode()));
   1407       compilation_cache->PutEval(source, outer_info, context, shared_info,
   1408                                  line_offset);
   1409     }
   1410   } else if (shared_info->ic_age() != isolate->heap()->global_ic_age()) {
   1411     shared_info->ResetForNewContext(isolate->heap()->global_ic_age());
   1412   }
   1413 
   1414   Handle<JSFunction> result =
   1415       isolate->factory()->NewFunctionFromSharedFunctionInfo(
   1416           shared_info, context, NOT_TENURED);
   1417 
   1418   // OnAfterCompile has to be called after we create the JSFunction, which we
   1419   // may require to recompile the eval for debugging, if we find a function
   1420   // that contains break points in the eval script.
   1421   isolate->debug()->OnAfterCompile(script);
   1422 
   1423   return result;
   1424 }
   1425 
   1426 
   1427 Handle<SharedFunctionInfo> Compiler::CompileScript(
   1428     Handle<String> source, Handle<Object> script_name, int line_offset,
   1429     int column_offset, ScriptOriginOptions resource_options,
   1430     Handle<Object> source_map_url, Handle<Context> context,
   1431     v8::Extension* extension, ScriptData** cached_data,
   1432     ScriptCompiler::CompileOptions compile_options, NativesFlag natives,
   1433     bool is_module) {
   1434   Isolate* isolate = source->GetIsolate();
   1435   if (compile_options == ScriptCompiler::kNoCompileOptions) {
   1436     cached_data = NULL;
   1437   } else if (compile_options == ScriptCompiler::kProduceParserCache ||
   1438              compile_options == ScriptCompiler::kProduceCodeCache) {
   1439     DCHECK(cached_data && !*cached_data);
   1440     DCHECK(extension == NULL);
   1441     DCHECK(!isolate->debug()->is_loaded());
   1442   } else {
   1443     DCHECK(compile_options == ScriptCompiler::kConsumeParserCache ||
   1444            compile_options == ScriptCompiler::kConsumeCodeCache);
   1445     DCHECK(cached_data && *cached_data);
   1446     DCHECK(extension == NULL);
   1447   }
   1448   int source_length = source->length();
   1449   isolate->counters()->total_load_size()->Increment(source_length);
   1450   isolate->counters()->total_compile_size()->Increment(source_length);
   1451 
   1452   // TODO(rossberg): The natives do not yet obey strong mode rules
   1453   // (for example, some macros use '==').
   1454   bool use_strong = FLAG_use_strong && !isolate->bootstrapper()->IsActive();
   1455   LanguageMode language_mode =
   1456       construct_language_mode(FLAG_use_strict, use_strong);
   1457 
   1458   CompilationCache* compilation_cache = isolate->compilation_cache();
   1459 
   1460   // Do a lookup in the compilation cache but not for extensions.
   1461   MaybeHandle<SharedFunctionInfo> maybe_result;
   1462   Handle<SharedFunctionInfo> result;
   1463   if (extension == NULL) {
   1464     // First check per-isolate compilation cache.
   1465     maybe_result = compilation_cache->LookupScript(
   1466         source, script_name, line_offset, column_offset, resource_options,
   1467         context, language_mode);
   1468     if (maybe_result.is_null() && FLAG_serialize_toplevel &&
   1469         compile_options == ScriptCompiler::kConsumeCodeCache &&
   1470         !isolate->debug()->is_loaded()) {
   1471       // Then check cached code provided by embedder.
   1472       HistogramTimerScope timer(isolate->counters()->compile_deserialize());
   1473       Handle<SharedFunctionInfo> result;
   1474       if (CodeSerializer::Deserialize(isolate, *cached_data, source)
   1475               .ToHandle(&result)) {
   1476         // Promote to per-isolate compilation cache.
   1477         compilation_cache->PutScript(source, context, language_mode, result);
   1478         return result;
   1479       }
   1480       // Deserializer failed. Fall through to compile.
   1481     }
   1482   }
   1483 
   1484   base::ElapsedTimer timer;
   1485   if (FLAG_profile_deserialization && FLAG_serialize_toplevel &&
   1486       compile_options == ScriptCompiler::kProduceCodeCache) {
   1487     timer.Start();
   1488   }
   1489 
   1490   if (!maybe_result.ToHandle(&result)) {
   1491     // No cache entry found. Compile the script.
   1492 
   1493     // Create a script object describing the script to be compiled.
   1494     Handle<Script> script = isolate->factory()->NewScript(source);
   1495     if (natives == NATIVES_CODE) {
   1496       script->set_type(Script::TYPE_NATIVE);
   1497       script->set_hide_source(true);
   1498     }
   1499     if (!script_name.is_null()) {
   1500       script->set_name(*script_name);
   1501       script->set_line_offset(line_offset);
   1502       script->set_column_offset(column_offset);
   1503     }
   1504     script->set_origin_options(resource_options);
   1505     if (!source_map_url.is_null()) {
   1506       script->set_source_mapping_url(*source_map_url);
   1507     }
   1508 
   1509     // Compile the function and add it to the cache.
   1510     Zone zone;
   1511     ParseInfo parse_info(&zone, script);
   1512     CompilationInfo info(&parse_info);
   1513     if (FLAG_harmony_modules && is_module) {
   1514       parse_info.set_module();
   1515     } else {
   1516       parse_info.set_global();
   1517     }
   1518     if (compile_options != ScriptCompiler::kNoCompileOptions) {
   1519       parse_info.set_cached_data(cached_data);
   1520     }
   1521     parse_info.set_compile_options(compile_options);
   1522     parse_info.set_extension(extension);
   1523     parse_info.set_context(context);
   1524     if (FLAG_serialize_toplevel &&
   1525         compile_options == ScriptCompiler::kProduceCodeCache) {
   1526       info.PrepareForSerializing();
   1527     }
   1528 
   1529     parse_info.set_language_mode(
   1530         static_cast<LanguageMode>(info.language_mode() | language_mode));
   1531     result = CompileToplevel(&info);
   1532     if (extension == NULL && !result.is_null()) {
   1533       compilation_cache->PutScript(source, context, language_mode, result);
   1534       if (FLAG_serialize_toplevel &&
   1535           compile_options == ScriptCompiler::kProduceCodeCache) {
   1536         HistogramTimerScope histogram_timer(
   1537             isolate->counters()->compile_serialize());
   1538         *cached_data = CodeSerializer::Serialize(isolate, result, source);
   1539         if (FLAG_profile_deserialization) {
   1540           PrintF("[Compiling and serializing took %0.3f ms]\n",
   1541                  timer.Elapsed().InMillisecondsF());
   1542         }
   1543       }
   1544     }
   1545 
   1546     if (result.is_null()) {
   1547       isolate->ReportPendingMessages();
   1548     } else {
   1549       isolate->debug()->OnAfterCompile(script);
   1550     }
   1551   } else if (result->ic_age() != isolate->heap()->global_ic_age()) {
   1552     result->ResetForNewContext(isolate->heap()->global_ic_age());
   1553   }
   1554   return result;
   1555 }
   1556 
   1557 
   1558 Handle<SharedFunctionInfo> Compiler::CompileStreamedScript(
   1559     Handle<Script> script, ParseInfo* parse_info, int source_length) {
   1560   Isolate* isolate = script->GetIsolate();
   1561   // TODO(titzer): increment the counters in caller.
   1562   isolate->counters()->total_load_size()->Increment(source_length);
   1563   isolate->counters()->total_compile_size()->Increment(source_length);
   1564 
   1565   LanguageMode language_mode =
   1566       construct_language_mode(FLAG_use_strict, FLAG_use_strong);
   1567   parse_info->set_language_mode(
   1568       static_cast<LanguageMode>(parse_info->language_mode() | language_mode));
   1569 
   1570   CompilationInfo compile_info(parse_info);
   1571 
   1572   // The source was parsed lazily, so compiling for debugging is not possible.
   1573   DCHECK(!compile_info.is_debug());
   1574 
   1575   Handle<SharedFunctionInfo> result = CompileToplevel(&compile_info);
   1576   if (!result.is_null()) isolate->debug()->OnAfterCompile(script);
   1577   return result;
   1578 }
   1579 
   1580 
   1581 Handle<SharedFunctionInfo> Compiler::GetSharedFunctionInfo(
   1582     FunctionLiteral* literal, Handle<Script> script,
   1583     CompilationInfo* outer_info) {
   1584   // Precondition: code has been parsed and scopes have been analyzed.
   1585   Isolate* isolate = outer_info->isolate();
   1586   MaybeHandle<SharedFunctionInfo> maybe_existing;
   1587   if (outer_info->is_first_compile()) {
   1588     // On the first compile, there are no existing shared function info for
   1589     // inner functions yet, so do not try to find them. All bets are off for
   1590     // live edit though.
   1591     DCHECK(script->FindSharedFunctionInfo(literal).is_null() ||
   1592            isolate->debug()->live_edit_enabled());
   1593   } else {
   1594     maybe_existing = script->FindSharedFunctionInfo(literal);
   1595   }
   1596   // We found an existing shared function info. If it's already compiled,
   1597   // don't worry about compiling it, and simply return it. If it's not yet
   1598   // compiled, continue to decide whether to eagerly compile.
   1599   // Carry on if we are compiling eager to obtain code for debugging,
   1600   // unless we already have code with debut break slots.
   1601   Handle<SharedFunctionInfo> existing;
   1602   if (maybe_existing.ToHandle(&existing) && existing->is_compiled()) {
   1603     if (!outer_info->is_debug() || existing->HasDebugCode()) {
   1604       return existing;
   1605     }
   1606   }
   1607 
   1608   Zone zone;
   1609   ParseInfo parse_info(&zone, script);
   1610   CompilationInfo info(&parse_info);
   1611   parse_info.set_literal(literal);
   1612   parse_info.set_scope(literal->scope());
   1613   parse_info.set_language_mode(literal->scope()->language_mode());
   1614   if (outer_info->will_serialize()) info.PrepareForSerializing();
   1615   if (outer_info->is_first_compile()) info.MarkAsFirstCompile();
   1616   if (outer_info->is_debug()) info.MarkAsDebug();
   1617 
   1618   LiveEditFunctionTracker live_edit_tracker(isolate, literal);
   1619   // Determine if the function can be lazily compiled. This is necessary to
   1620   // allow some of our builtin JS files to be lazily compiled. These
   1621   // builtins cannot be handled lazily by the parser, since we have to know
   1622   // if a function uses the special natives syntax, which is something the
   1623   // parser records.
   1624   // If the debugger requests compilation for break points, we cannot be
   1625   // aggressive about lazy compilation, because it might trigger compilation
   1626   // of functions without an outer context when setting a breakpoint through
   1627   // Debug::FindSharedFunctionInfoInScript.
   1628   bool allow_lazy_without_ctx = literal->AllowsLazyCompilationWithoutContext();
   1629   // Compile eagerly for live edit. When compiling debug code, eagerly compile
   1630   // unless we can lazily compile without the context.
   1631   bool allow_lazy = literal->AllowsLazyCompilation() &&
   1632                     !LiveEditFunctionTracker::IsActive(isolate) &&
   1633                     (!info.is_debug() || allow_lazy_without_ctx);
   1634 
   1635   bool lazy = FLAG_lazy && allow_lazy && !literal->should_eager_compile();
   1636 
   1637   // Generate code
   1638   Handle<ScopeInfo> scope_info;
   1639   if (lazy) {
   1640     Handle<Code> code = isolate->builtins()->CompileLazy();
   1641     info.SetCode(code);
   1642     // There's no need in theory for a lazy-compiled function to have a type
   1643     // feedback vector, but some parts of the system expect all
   1644     // SharedFunctionInfo instances to have one.  The size of the vector depends
   1645     // on how many feedback-needing nodes are in the tree, and when lazily
   1646     // parsing we might not know that, if this function was never parsed before.
   1647     // In that case the vector will be replaced the next time MakeCode is
   1648     // called.
   1649     info.EnsureFeedbackVector();
   1650     scope_info = Handle<ScopeInfo>(ScopeInfo::Empty(isolate));
   1651   } else if (Renumber(info.parse_info()) && GenerateBaselineCode(&info)) {
   1652     // Code generation will ensure that the feedback vector is present and
   1653     // appropriately sized.
   1654     DCHECK(!info.code().is_null());
   1655     scope_info = ScopeInfo::Create(info.isolate(), info.zone(), info.scope());
   1656     if (literal->should_eager_compile() &&
   1657         literal->should_be_used_once_hint()) {
   1658       info.code()->MarkToBeExecutedOnce(isolate);
   1659     }
   1660   } else {
   1661     return Handle<SharedFunctionInfo>::null();
   1662   }
   1663 
   1664   if (maybe_existing.is_null()) {
   1665     // Create a shared function info object.
   1666     Handle<SharedFunctionInfo> result =
   1667         isolate->factory()->NewSharedFunctionInfo(
   1668             literal->name(), literal->materialized_literal_count(),
   1669             literal->kind(), info.code(), scope_info, info.feedback_vector());
   1670     if (info.has_bytecode_array()) {
   1671       DCHECK(result->function_data()->IsUndefined());
   1672       result->set_function_data(*info.bytecode_array());
   1673     }
   1674 
   1675     SharedFunctionInfo::InitFromFunctionLiteral(result, literal);
   1676     SharedFunctionInfo::SetScript(result, script);
   1677     result->set_is_toplevel(false);
   1678     // If the outer function has been compiled before, we cannot be sure that
   1679     // shared function info for this function literal has been created for the
   1680     // first time. It may have already been compiled previously.
   1681     result->set_never_compiled(outer_info->is_first_compile() && lazy);
   1682 
   1683     RecordFunctionCompilation(Logger::FUNCTION_TAG, &info, result);
   1684     result->set_allows_lazy_compilation(literal->AllowsLazyCompilation());
   1685     result->set_allows_lazy_compilation_without_context(allow_lazy_without_ctx);
   1686 
   1687     // Set the expected number of properties for instances and return
   1688     // the resulting function.
   1689     SetExpectedNofPropertiesFromEstimate(result,
   1690                                          literal->expected_property_count());
   1691     live_edit_tracker.RecordFunctionInfo(result, literal, info.zone());
   1692     return result;
   1693   } else if (!lazy) {
   1694     // Assert that we are not overwriting (possibly patched) debug code.
   1695     DCHECK(!existing->HasDebugCode());
   1696     existing->ReplaceCode(*info.code());
   1697     existing->set_scope_info(*scope_info);
   1698     existing->set_feedback_vector(*info.feedback_vector());
   1699   }
   1700   return existing;
   1701 }
   1702 
   1703 
   1704 MaybeHandle<Code> Compiler::GetOptimizedCode(Handle<JSFunction> function,
   1705                                              Handle<Code> current_code,
   1706                                              ConcurrencyMode mode,
   1707                                              BailoutId osr_ast_id,
   1708                                              JavaScriptFrame* osr_frame) {
   1709   Isolate* isolate = function->GetIsolate();
   1710   Handle<SharedFunctionInfo> shared(function->shared(), isolate);
   1711   if (shared->HasDebugInfo()) return MaybeHandle<Code>();
   1712 
   1713   Handle<Code> cached_code;
   1714   if (GetCodeFromOptimizedCodeMap(
   1715           function, osr_ast_id).ToHandle(&cached_code)) {
   1716     if (FLAG_trace_opt) {
   1717       PrintF("[found optimized code for ");
   1718       function->ShortPrint();
   1719       if (!osr_ast_id.IsNone()) {
   1720         PrintF(" at OSR AST id %d", osr_ast_id.ToInt());
   1721       }
   1722       PrintF("]\n");
   1723     }
   1724     return cached_code;
   1725   }
   1726 
   1727   DCHECK(AllowCompilation::IsAllowed(isolate));
   1728 
   1729   if (!shared->is_compiled() ||
   1730       shared->scope_info() == ScopeInfo::Empty(isolate)) {
   1731     // The function was never compiled. Compile it unoptimized first.
   1732     // TODO(titzer): reuse the AST and scope info from this compile.
   1733     CompilationInfoWithZone unoptimized(function);
   1734     unoptimized.EnableDeoptimizationSupport();
   1735     if (!GetUnoptimizedCodeCommon(&unoptimized).ToHandle(&current_code)) {
   1736       return MaybeHandle<Code>();
   1737     }
   1738     shared->ReplaceCode(*current_code);
   1739   }
   1740 
   1741   current_code->set_profiler_ticks(0);
   1742 
   1743   // TODO(mstarzinger): We cannot properly deserialize a scope chain containing
   1744   // an eval scope and hence would fail at parsing the eval source again.
   1745   if (shared->disable_optimization_reason() == kEval) {
   1746     return MaybeHandle<Code>();
   1747   }
   1748 
   1749   // TODO(mstarzinger): We cannot properly deserialize a scope chain for the
   1750   // builtin context, hence Genesis::InstallExperimentalNatives would fail.
   1751   if (shared->is_toplevel() && isolate->bootstrapper()->IsActive()) {
   1752     return MaybeHandle<Code>();
   1753   }
   1754 
   1755   base::SmartPointer<CompilationInfo> info(
   1756       new CompilationInfoWithZone(function));
   1757   VMState<COMPILER> state(isolate);
   1758   DCHECK(!isolate->has_pending_exception());
   1759   PostponeInterruptsScope postpone(isolate);
   1760 
   1761   info->SetOptimizing(osr_ast_id, current_code);
   1762 
   1763   if (mode == CONCURRENT) {
   1764     if (GetOptimizedCodeLater(info.get())) {
   1765       info.Detach();  // The background recompile job owns this now.
   1766       return isolate->builtins()->InOptimizationQueue();
   1767     }
   1768   } else {
   1769     info->set_osr_frame(osr_frame);
   1770     if (GetOptimizedCodeNow(info.get())) return info->code();
   1771   }
   1772 
   1773   if (isolate->has_pending_exception()) isolate->clear_pending_exception();
   1774   return MaybeHandle<Code>();
   1775 }
   1776 
   1777 
   1778 Handle<Code> Compiler::GetConcurrentlyOptimizedCode(OptimizedCompileJob* job) {
   1779   // Take ownership of compilation info.  Deleting compilation info
   1780   // also tears down the zone and the recompile job.
   1781   base::SmartPointer<CompilationInfo> info(job->info());
   1782   Isolate* isolate = info->isolate();
   1783 
   1784   VMState<COMPILER> state(isolate);
   1785   TimerEventScope<TimerEventRecompileSynchronous> timer(info->isolate());
   1786 
   1787   Handle<SharedFunctionInfo> shared = info->shared_info();
   1788   shared->code()->set_profiler_ticks(0);
   1789 
   1790   DCHECK(!shared->HasDebugInfo());
   1791 
   1792   // 1) Optimization on the concurrent thread may have failed.
   1793   // 2) The function may have already been optimized by OSR.  Simply continue.
   1794   //    Except when OSR already disabled optimization for some reason.
   1795   // 3) The code may have already been invalidated due to dependency change.
   1796   // 4) Code generation may have failed.
   1797   if (job->last_status() == OptimizedCompileJob::SUCCEEDED) {
   1798     if (shared->optimization_disabled()) {
   1799       job->RetryOptimization(kOptimizationDisabled);
   1800     } else if (info->dependencies()->HasAborted()) {
   1801       job->RetryOptimization(kBailedOutDueToDependencyChange);
   1802     } else if (job->GenerateCode() == OptimizedCompileJob::SUCCEEDED) {
   1803       RecordFunctionCompilation(Logger::LAZY_COMPILE_TAG, info.get(), shared);
   1804       if (shared->SearchOptimizedCodeMap(info->context()->native_context(),
   1805                                          info->osr_ast_id()).code == nullptr) {
   1806         InsertCodeIntoOptimizedCodeMap(info.get());
   1807       }
   1808       if (FLAG_trace_opt) {
   1809         PrintF("[completed optimizing ");
   1810         info->closure()->ShortPrint();
   1811         PrintF("]\n");
   1812       }
   1813       return Handle<Code>(*info->code());
   1814     }
   1815   }
   1816 
   1817   DCHECK(job->last_status() != OptimizedCompileJob::SUCCEEDED);
   1818   if (FLAG_trace_opt) {
   1819     PrintF("[aborted optimizing ");
   1820     info->closure()->ShortPrint();
   1821     PrintF(" because: %s]\n", GetBailoutReason(info->bailout_reason()));
   1822   }
   1823   return Handle<Code>::null();
   1824 }
   1825 
   1826 
   1827 CompilationPhase::CompilationPhase(const char* name, CompilationInfo* info)
   1828     : name_(name), info_(info) {
   1829   if (FLAG_hydrogen_stats) {
   1830     info_zone_start_allocation_size_ = info->zone()->allocation_size();
   1831     timer_.Start();
   1832   }
   1833 }
   1834 
   1835 
   1836 CompilationPhase::~CompilationPhase() {
   1837   if (FLAG_hydrogen_stats) {
   1838     size_t size = zone()->allocation_size();
   1839     size += info_->zone()->allocation_size() - info_zone_start_allocation_size_;
   1840     isolate()->GetHStatistics()->SaveTiming(name_, timer_.Elapsed(), size);
   1841   }
   1842 }
   1843 
   1844 
   1845 bool CompilationPhase::ShouldProduceTraceOutput() const {
   1846   // Trace if the appropriate trace flag is set and the phase name's first
   1847   // character is in the FLAG_trace_phase command line parameter.
   1848   AllowHandleDereference allow_deref;
   1849   bool tracing_on = info()->IsStub()
   1850       ? FLAG_trace_hydrogen_stubs
   1851       : (FLAG_trace_hydrogen &&
   1852          info()->closure()->PassesFilter(FLAG_trace_hydrogen_filter));
   1853   return (tracing_on &&
   1854       base::OS::StrChr(const_cast<char*>(FLAG_trace_phase), name_[0]) != NULL);
   1855 }
   1856 
   1857 #if DEBUG
   1858 void CompilationInfo::PrintAstForTesting() {
   1859   PrintF("--- Source from AST ---\n%s\n",
   1860          PrettyPrinter(isolate()).PrintProgram(literal()));
   1861 }
   1862 #endif
   1863 }  // namespace internal
   1864 }  // namespace v8
   1865