LCOV - code coverage report
Current view: top level - src/full-codegen - full-codegen.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 688 734 93.7 %
Date: 2017-04-26 Functions: 114 134 85.1 %

          Line data    Source code
       1             : // Copyright 2012 the V8 project authors. All rights reserved.
       2             : // Use of this source code is governed by a BSD-style license that can be
       3             : // found in the LICENSE file.
       4             : 
       5             : #include "src/full-codegen/full-codegen.h"
       6             : 
       7             : #include "src/ast/ast-numbering.h"
       8             : #include "src/ast/ast.h"
       9             : #include "src/ast/prettyprinter.h"
      10             : #include "src/ast/scopes.h"
      11             : #include "src/code-factory.h"
      12             : #include "src/codegen.h"
      13             : #include "src/compilation-info.h"
      14             : #include "src/compiler.h"
      15             : #include "src/debug/debug.h"
      16             : #include "src/debug/liveedit.h"
      17             : #include "src/frames-inl.h"
      18             : #include "src/globals.h"
      19             : #include "src/isolate-inl.h"
      20             : #include "src/macro-assembler-inl.h"
      21             : #include "src/macro-assembler.h"
      22             : #include "src/snapshot/snapshot.h"
      23             : #include "src/tracing/trace-event.h"
      24             : 
      25             : namespace v8 {
      26             : namespace internal {
      27             : 
      28             : #define __ ACCESS_MASM(masm())
      29             : 
      30     1696592 : class FullCodegenCompilationJob final : public CompilationJob {
      31             :  public:
      32      848300 :   explicit FullCodegenCompilationJob(CompilationInfo* info)
      33      848300 :       : CompilationJob(info->isolate(), info, "Full-Codegen") {}
      34             : 
      35      848297 :   bool can_execute_on_background_thread() const override { return false; }
      36             : 
      37      848297 :   CompilationJob::Status PrepareJobImpl() final { return SUCCEEDED; }
      38             : 
      39      848294 :   CompilationJob::Status ExecuteJobImpl() final {
      40             :     DCHECK(ThreadId::Current().Equals(isolate()->thread_id()));
      41      848294 :     return FullCodeGenerator::MakeCode(info(), stack_limit()) ? SUCCEEDED
      42      848300 :                                                               : FAILED;
      43             :   }
      44             : 
      45      848294 :   CompilationJob::Status FinalizeJobImpl() final { return SUCCEEDED; }
      46             : 
      47             :  private:
      48             :   DISALLOW_COPY_AND_ASSIGN(FullCodegenCompilationJob);
      49             : };
      50             : 
      51     1079863 : FullCodeGenerator::FullCodeGenerator(MacroAssembler* masm,
      52     5399310 :                                      CompilationInfo* info,
      53             :                                      uintptr_t stack_limit)
      54             :     : masm_(masm),
      55             :       info_(info),
      56             :       isolate_(info->isolate()),
      57             :       zone_(info->zone()),
      58     1079863 :       scope_(info->scope()),
      59             :       nesting_stack_(NULL),
      60             :       loop_depth_(0),
      61             :       operand_stack_depth_(0),
      62             :       globals_(NULL),
      63             :       context_(NULL),
      64             :       bailout_entries_(info->HasDeoptimizationSupport()
      65      236325 :                            ? info->literal()->ast_node_count()
      66             :                            : 0,
      67             :                        info->zone()),
      68             :       back_edges_(2, info->zone()),
      69             :       source_position_table_builder_(info->zone(),
      70             :                                      info->SourcePositionRecordingMode()),
      71     9718762 :       ic_total_count_(0) {
      72             :   DCHECK(!info->IsStub());
      73             :   Initialize(stack_limit);
      74     1079858 : }
      75             : 
      76             : // static
      77      848295 : CompilationJob* FullCodeGenerator::NewCompilationJob(CompilationInfo* info) {
      78     1696594 :   return new FullCodegenCompilationJob(info);
      79             : }
      80             : 
      81             : // static
      82      231562 : bool FullCodeGenerator::MakeCode(CompilationInfo* info) {
      83      231562 :   return MakeCode(info, info->isolate()->stack_guard()->real_climit());
      84             : }
      85             : 
      86             : // static
      87     3239569 : bool FullCodeGenerator::MakeCode(CompilationInfo* info, uintptr_t stack_limit) {
      88     1079862 :   Isolate* isolate = info->isolate();
      89             : 
      90             :   DCHECK(!info->shared_info()->must_use_ignition_turbo());
      91             :   DCHECK(!FLAG_minimal);
      92             :   RuntimeCallTimerScope runtimeTimer(isolate,
      93     1079852 :                                      &RuntimeCallStats::CompileFullCode);
      94             :   TimerEventScope<TimerEventCompileFullCode> timer(info->isolate());
      95     3239580 :   TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.CompileFullCode");
      96             : 
      97     1079859 :   Handle<Script> script = info->script();
      98     2159721 :   if (!script->IsUndefined(isolate) &&
      99             :       !script->source()->IsUndefined(isolate)) {
     100             :     int len = String::cast(script->source())->length();
     101     1079862 :     isolate->counters()->total_full_codegen_source_size()->Increment(len);
     102             :   }
     103     1079860 :   CodeGenerator::MakeCodePrologue(info, "full");
     104             :   const int kInitialBufferSize = 4 * KB;
     105             :   MacroAssembler masm(info->isolate(), NULL, kInitialBufferSize,
     106     1079860 :                       CodeObjectRequired::kYes);
     107     1079863 :   if (info->will_serialize()) masm.enable_serializer();
     108             : 
     109     1079863 :   FullCodeGenerator cgen(&masm, info, stack_limit);
     110     1079858 :   cgen.Generate();
     111     1079862 :   if (cgen.HasStackOverflow()) {
     112             :     DCHECK(!isolate->has_pending_exception());
     113             :     return false;
     114             :   }
     115     1079856 :   unsigned table_offset = cgen.EmitBackEdgeTable();
     116             : 
     117             :   Handle<Code> code =
     118     1079856 :       CodeGenerator::MakeCodeEpilogue(&masm, nullptr, info, masm.CodeObject());
     119     1079857 :   cgen.PopulateDeoptimizationData(code);
     120     1079857 :   cgen.PopulateTypeFeedbackInfo(code);
     121             :   code->set_has_deoptimization_support(info->HasDeoptimizationSupport());
     122             :   code->set_has_reloc_info_for_serialization(info->will_serialize());
     123             :   code->set_allow_osr_at_loop_nesting_level(0);
     124             :   code->set_profiler_ticks(0);
     125             :   code->set_back_edge_table_offset(table_offset);
     126             :   Handle<ByteArray> source_positions =
     127             :       cgen.source_position_table_builder_.ToSourcePositionTable(
     128     1079857 :           isolate, Handle<AbstractCode>::cast(code));
     129     1079855 :   code->set_source_position_table(*source_positions);
     130     1079856 :   CodeGenerator::PrintCode(code, info);
     131             :   info->SetCode(code);
     132             : 
     133             : #ifdef DEBUG
     134             :   // Check that no context-specific object has been embedded.
     135             :   code->VerifyEmbeddedObjects(Code::kNoContextSpecificPointers);
     136             : #endif  // DEBUG
     137     1079855 :   return true;
     138             : }
     139             : 
     140             : 
     141     2448946 : unsigned FullCodeGenerator::EmitBackEdgeTable() {
     142             :   // The back edge table consists of a length (in number of entries)
     143             :   // field, and then a sequence of entries.  Each entry is a pair of AST id
     144             :   // and code-relative pc offset.
     145     1079856 :   masm()->Align(kPointerSize);
     146     2159714 :   unsigned offset = masm()->pc_offset();
     147     1369090 :   unsigned length = back_edges_.length();
     148     1079857 :   __ dd(length);
     149     1176266 :   for (unsigned i = 0; i < length; ++i) {
     150      289233 :     __ dd(back_edges_[i].id.ToInt());
     151      192822 :     __ dd(back_edges_[i].pc);
     152      192822 :     __ dd(back_edges_[i].loop_depth);
     153             :   }
     154     1079855 :   return offset;
     155             : }
     156             : 
     157             : 
     158     1316183 : void FullCodeGenerator::PopulateDeoptimizationData(Handle<Code> code) {
     159             :   // Fill in the deoptimization information.
     160             :   DCHECK(info_->HasDeoptimizationSupport() || bailout_entries_.is_empty());
     161     3239571 :   if (!info_->HasDeoptimizationSupport()) return;
     162    17058434 :   int length = bailout_entries_.length();
     163             :   Handle<DeoptimizationOutputData> data =
     164      236326 :       DeoptimizationOutputData::New(isolate(), length, TENURED);
     165     8647379 :   for (int i = 0; i < length; i++) {
     166     8411053 :     data->SetAstId(i, bailout_entries_[i].id);
     167     8411055 :     data->SetPcAndState(i, Smi::FromInt(bailout_entries_[i].pc_and_state));
     168             :   }
     169      236326 :   code->set_deoptimization_data(*data);
     170             : }
     171             : 
     172             : 
     173     1079855 : void FullCodeGenerator::PopulateTypeFeedbackInfo(Handle<Code> code) {
     174     1079855 :   Handle<TypeFeedbackInfo> info = isolate()->factory()->NewTypeFeedbackInfo();
     175     1079855 :   info->set_ic_total_count(ic_total_count_);
     176             :   DCHECK(!isolate()->heap()->InNewSpace(*info));
     177     1079855 :   code->set_type_feedback_info(*info);
     178     1079857 : }
     179             : 
     180             : 
     181      144158 : bool FullCodeGenerator::MustCreateObjectLiteralWithRuntime(
     182      144158 :     ObjectLiteral* expr) const {
     183      144158 :   return masm()->serializer_enabled() || !expr->IsFastCloningSupported();
     184             : }
     185             : 
     186             : 
     187       73967 : bool FullCodeGenerator::MustCreateArrayLiteralWithRuntime(
     188             :     ArrayLiteral* expr) const {
     189       73967 :   return !expr->IsFastCloningSupported();
     190             : }
     191             : 
     192           0 : void FullCodeGenerator::Initialize(uintptr_t stack_limit) {
     193             :   InitializeAstVisitor(stack_limit);
     194     1079858 :   masm_->set_emit_debug_code(FLAG_debug_code);
     195             :   masm_->set_predictable_code_size(true);
     196           0 : }
     197             : 
     198     4098723 : void FullCodeGenerator::PrepareForBailout(Expression* node,
     199             :                                           BailoutState state) {
     200    18298567 :   PrepareForBailoutForId(node->id(), state);
     201     4098724 : }
     202             : 
     203     5513770 : void FullCodeGenerator::CallIC(Handle<Code> code, TypeFeedbackId ast_id) {
     204     2756885 :   ic_total_count_++;
     205     2756885 :   __ Call(code, RelocInfo::CODE_TARGET, ast_id);
     206     2756886 : }
     207             : 
     208     6974371 : void FullCodeGenerator::CallLoadIC(FeedbackSlot slot, Handle<Object> name) {
     209             :   DCHECK(name->IsName());
     210     3487185 :   __ Move(LoadDescriptor::NameRegister(), name);
     211             : 
     212     1743593 :   EmitLoadSlot(LoadDescriptor::SlotRegister(), slot);
     213             : 
     214     3487186 :   Handle<Code> code = CodeFactory::LoadIC(isolate()).code();
     215     1743593 :   __ Call(code, RelocInfo::CODE_TARGET);
     216     1743593 :   RestoreContext();
     217     1743593 : }
     218             : 
     219     1157906 : void FullCodeGenerator::CallStoreIC(FeedbackSlot slot, Handle<Object> name,
     220     3473718 :                                     StoreICKind store_ic_kind) {
     221             :   DCHECK(name->IsName());
     222     2315812 :   __ Move(StoreDescriptor::NameRegister(), name);
     223             : 
     224             :   STATIC_ASSERT(!StoreDescriptor::kPassLastArgsOnStack ||
     225             :                 StoreDescriptor::kStackArgumentsCount == 2);
     226             :   if (StoreDescriptor::kPassLastArgsOnStack) {
     227             :     __ Push(StoreDescriptor::ValueRegister());
     228             :     EmitPushSlot(slot);
     229             :   } else {
     230     1157906 :     EmitLoadSlot(StoreDescriptor::SlotRegister(), slot);
     231             :   }
     232             : 
     233             :   Handle<Code> code;
     234     1157906 :   switch (store_ic_kind) {
     235             :     case kStoreOwn:
     236             :       DCHECK_EQ(FeedbackSlotKind::kStoreOwnNamed,
     237             :                 feedback_vector_spec()->GetKind(slot));
     238      379862 :       code = CodeFactory::StoreOwnIC(isolate()).code();
     239      189931 :       break;
     240             :     case kStoreGlobal:
     241             :       // Ensure that language mode is in sync with the IC slot kind.
     242             :       DCHECK_EQ(
     243             :           GetLanguageModeFromSlotKind(feedback_vector_spec()->GetKind(slot)),
     244             :           language_mode());
     245      119720 :       code = CodeFactory::StoreGlobalIC(isolate(), language_mode()).code();
     246       59860 :       break;
     247             :     case kStoreNamed:
     248             :       // Ensure that language mode is in sync with the IC slot kind.
     249             :       DCHECK_EQ(
     250             :           GetLanguageModeFromSlotKind(feedback_vector_spec()->GetKind(slot)),
     251             :           language_mode());
     252     1816230 :       code = CodeFactory::StoreIC(isolate(), language_mode()).code();
     253      908115 :       break;
     254             :   }
     255     1157906 :   __ Call(code, RelocInfo::CODE_TARGET);
     256     1157906 :   RestoreContext();
     257     1157906 : }
     258             : 
     259      612618 : void FullCodeGenerator::CallKeyedStoreIC(FeedbackSlot slot) {
     260             :   STATIC_ASSERT(!StoreDescriptor::kPassLastArgsOnStack ||
     261             :                 StoreDescriptor::kStackArgumentsCount == 2);
     262             :   if (StoreDescriptor::kPassLastArgsOnStack) {
     263             :     __ Push(StoreDescriptor::ValueRegister());
     264             :     EmitPushSlot(slot);
     265             :   } else {
     266      204206 :     EmitLoadSlot(StoreDescriptor::SlotRegister(), slot);
     267             :   }
     268             : 
     269             :   // Ensure that language mode is in sync with the IC slot kind.
     270             :   DCHECK_EQ(GetLanguageModeFromSlotKind(feedback_vector_spec()->GetKind(slot)),
     271             :             language_mode());
     272             :   Handle<Code> code =
     273      408412 :       CodeFactory::KeyedStoreIC(isolate(), language_mode()).code();
     274      204206 :   __ Call(code, RelocInfo::CODE_TARGET);
     275      204206 :   RestoreContext();
     276      204206 : }
     277             : 
     278     1104051 : void FullCodeGenerator::RecordJSReturnSite(Call* call) {
     279             :   // We record the offset of the function return so we can rebuild the frame
     280             :   // if the function was inlined, i.e., this is the return address in the
     281             :   // inlined function's frame.
     282             :   //
     283             :   // The bailout state is ignored.  We defensively set it to TOS_REGISTER, which
     284             :   // is the real state of the unoptimized code at the return site.
     285     1104051 :   PrepareForBailoutForId(call->ReturnId(), BailoutState::TOS_REGISTER);
     286             : #ifdef DEBUG
     287             :   // In debug builds, mark the return so we can verify that this function
     288             :   // was called.
     289             :   DCHECK(!call->return_is_recorded_);
     290             :   call->return_is_recorded_ = true;
     291             : #endif
     292     1104052 : }
     293             : 
     294    42291673 : void FullCodeGenerator::PrepareForBailoutForId(BailoutId id,
     295     8411028 :                                                BailoutState state) {
     296             :   // There's no need to prepare this code for bailouts from already optimized
     297             :   // code or code that can't be optimized.
     298   118463991 :   if (!info_->HasDeoptimizationSupport()) return;
     299             :   unsigned pc_and_state =
     300    25233084 :       BailoutStateField::encode(state) | PcField::encode(masm_->pc_offset());
     301             :   DCHECK(Smi::IsValid(pc_and_state));
     302             : #ifdef DEBUG
     303             :   for (int i = 0; i < bailout_entries_.length(); ++i) {
     304             :     DCHECK(bailout_entries_[i].id != id);
     305             :   }
     306             : #endif
     307     8411028 :   BailoutEntry entry = { id, pc_and_state };
     308             :   bailout_entries_.Add(entry, zone());
     309             : }
     310             : 
     311             : 
     312      192822 : void FullCodeGenerator::RecordBackEdge(BailoutId ast_id) {
     313             :   // The pc offset does not need to be encoded and packed together with a state.
     314             :   DCHECK(masm_->pc_offset() > 0);
     315             :   DCHECK(loop_depth() > 0);
     316             :   uint8_t depth = Min(loop_depth(), AbstractCode::kMaxLoopNestingMarker);
     317             :   BackEdgeEntry entry =
     318      192822 :       { ast_id, static_cast<unsigned>(masm_->pc_offset()), depth };
     319             :   back_edges_.Add(entry, zone());
     320       96411 : }
     321             : 
     322             : 
     323      655671 : bool FullCodeGenerator::ShouldInlineSmiCase(Token::Value op) {
     324             :   // Inline smi case inside loops, but not division and modulo which
     325             :   // are too complicated and take up too much space.
     326     1297922 :   if (op == Token::DIV ||op == Token::MOD) return false;
     327     1255642 :   if (FLAG_always_inline_smi_code) return true;
     328     1253362 :   return loop_depth_ > 0;
     329             : }
     330             : 
     331             : 
     332        2340 : void FullCodeGenerator::EffectContext::Plug(Variable* var) const {
     333             :   DCHECK(var->IsStackAllocated() || var->IsContextSlot());
     334        2340 : }
     335             : 
     336             : 
     337     2539929 : void FullCodeGenerator::AccumulatorValueContext::Plug(Variable* var) const {
     338             :   DCHECK(var->IsStackAllocated() || var->IsContextSlot());
     339     2539929 :   codegen()->GetVar(result_register(), var);
     340     2539935 : }
     341             : 
     342             : 
     343      149700 : void FullCodeGenerator::TestContext::Plug(Variable* var) const {
     344             :   DCHECK(var->IsStackAllocated() || var->IsContextSlot());
     345             :   // For simplicity we always test the accumulator register.
     346      224550 :   codegen()->GetVar(result_register(), var);
     347       74850 :   codegen()->PrepareForBailoutBeforeSplit(condition(), false, NULL, NULL);
     348             :   codegen()->DoTest(this);
     349       74850 : }
     350             : 
     351             : 
     352     2943246 : void FullCodeGenerator::EffectContext::Plug(Register reg) const {
     353     2943246 : }
     354             : 
     355             : 
     356     2588223 : void FullCodeGenerator::AccumulatorValueContext::Plug(Register reg) const {
     357     2588223 :   __ Move(result_register(), reg);
     358     2588226 : }
     359             : 
     360             : 
     361     2208378 : void FullCodeGenerator::StackValueContext::Plug(Register reg) const {
     362     2208378 :   codegen()->PushOperand(reg);
     363     2208381 : }
     364             : 
     365             : 
     366       91562 : void FullCodeGenerator::TestContext::Plug(Register reg) const {
     367             :   // For simplicity we always test the accumulator register.
     368      137343 :   __ Move(result_register(), reg);
     369       45781 :   codegen()->PrepareForBailoutBeforeSplit(condition(), false, NULL, NULL);
     370             :   codegen()->DoTest(this);
     371       45781 : }
     372             : 
     373             : 
     374          35 : void FullCodeGenerator::EffectContext::Plug(bool flag) const {}
     375             : 
     376      466432 : void FullCodeGenerator::EffectContext::DropAndPlug(int count,
     377             :                                                    Register reg) const {
     378             :   DCHECK(count > 0);
     379      466432 :   codegen()->DropOperands(count);
     380      466431 : }
     381             : 
     382      426664 : void FullCodeGenerator::AccumulatorValueContext::DropAndPlug(
     383             :     int count, Register reg) const {
     384             :   DCHECK(count > 0);
     385      853330 :   codegen()->DropOperands(count);
     386      853331 :   __ Move(result_register(), reg);
     387      426666 : }
     388             : 
     389       60934 : void FullCodeGenerator::TestContext::DropAndPlug(int count,
     390       60934 :                                                  Register reg) const {
     391             :   DCHECK(count > 0);
     392             :   // For simplicity we always test the accumulator register.
     393      243736 :   codegen()->DropOperands(count);
     394      121868 :   __ Move(result_register(), reg);
     395       60934 :   codegen()->PrepareForBailoutBeforeSplit(condition(), false, NULL, NULL);
     396             :   codegen()->DoTest(this);
     397       60934 : }
     398             : 
     399          71 : void FullCodeGenerator::EffectContext::PlugTOS() const {
     400          71 :   codegen()->DropOperands(1);
     401          71 : }
     402             : 
     403             : 
     404       62392 : void FullCodeGenerator::AccumulatorValueContext::PlugTOS() const {
     405       62392 :   codegen()->PopOperand(result_register());
     406       62392 : }
     407             : 
     408             : 
     409       36257 : void FullCodeGenerator::StackValueContext::PlugTOS() const {
     410       36257 : }
     411             : 
     412             : 
     413       14036 : void FullCodeGenerator::TestContext::PlugTOS() const {
     414             :   // For simplicity we always test the accumulator register.
     415       21054 :   codegen()->PopOperand(result_register());
     416        7018 :   codegen()->PrepareForBailoutBeforeSplit(condition(), false, NULL, NULL);
     417             :   codegen()->DoTest(this);
     418        7018 : }
     419             : 
     420             : 
     421         123 : void FullCodeGenerator::EffectContext::PrepareTest(
     422             :     Label* materialize_true,
     423             :     Label* materialize_false,
     424             :     Label** if_true,
     425             :     Label** if_false,
     426             :     Label** fall_through) const {
     427             :   // In an effect context, the true and the false case branch to the
     428             :   // same label.
     429         123 :   *if_true = *if_false = *fall_through = materialize_true;
     430         123 : }
     431             : 
     432             : 
     433       54246 : void FullCodeGenerator::AccumulatorValueContext::PrepareTest(
     434             :     Label* materialize_true,
     435             :     Label* materialize_false,
     436             :     Label** if_true,
     437             :     Label** if_false,
     438             :     Label** fall_through) const {
     439       54246 :   *if_true = *fall_through = materialize_true;
     440       54246 :   *if_false = materialize_false;
     441       54246 : }
     442             : 
     443             : 
     444        6586 : void FullCodeGenerator::StackValueContext::PrepareTest(
     445             :     Label* materialize_true,
     446             :     Label* materialize_false,
     447             :     Label** if_true,
     448             :     Label** if_false,
     449             :     Label** fall_through) const {
     450        6586 :   *if_true = *fall_through = materialize_true;
     451        6586 :   *if_false = materialize_false;
     452        6586 : }
     453             : 
     454             : 
     455      518168 : void FullCodeGenerator::TestContext::PrepareTest(
     456             :     Label* materialize_true,
     457             :     Label* materialize_false,
     458             :     Label** if_true,
     459             :     Label** if_false,
     460             :     Label** fall_through) const {
     461      518168 :   *if_true = true_label_;
     462      518168 :   *if_false = false_label_;
     463      518168 :   *fall_through = fall_through_;
     464      518168 : }
     465             : 
     466             : 
     467      188587 : void FullCodeGenerator::DoTest(const TestContext* context) {
     468             :   DoTest(context->condition(),
     469             :          context->true_label(),
     470             :          context->false_label(),
     471      188587 :          context->fall_through());
     472           4 : }
     473             : 
     474     2290865 : void FullCodeGenerator::VisitDeclarations(Declaration::List* declarations) {
     475     1125814 :   ZoneList<Handle<Object> >* saved_globals = globals_;
     476     1125814 :   ZoneList<Handle<Object> > inner_globals(10, zone());
     477     1125818 :   globals_ = &inner_globals;
     478             : 
     479             :   AstVisitor<FullCodeGenerator>::VisitDeclarations(declarations);
     480             : 
     481     2956295 :   if (!globals_->is_empty()) {
     482             :     // Invoke the platform-dependent code generator to do the actual
     483             :     // declaration of the global functions and variables.
     484             :     Handle<FixedArray> array =
     485       39237 :        isolate()->factory()->NewFixedArray(globals_->length(), TENURED);
     486     3660954 :     for (int i = 0; i < globals_->length(); ++i)
     487     1791240 :       array->set(i, *globals_->at(i));
     488       39237 :     DeclareGlobals(array);
     489             :   }
     490             : 
     491     1125818 :   globals_ = saved_globals;
     492     1125818 : }
     493             : 
     494             : 
     495           0 : void FullCodeGenerator::VisitVariableProxy(VariableProxy* expr) {
     496             :   Comment cmnt(masm_, "[ VariableProxy");
     497     5648572 :   EmitVariableLoad(expr);
     498           0 : }
     499             : 
     500      813718 : void FullCodeGenerator::EmitGlobalVariableLoad(VariableProxy* proxy,
     501     2441156 :                                                TypeofMode typeof_mode) {
     502      813718 :   Variable* var = proxy->var();
     503             :   DCHECK(var->IsUnallocated());
     504     1627436 :   __ Move(LoadDescriptor::NameRegister(), var->name());
     505             : 
     506             :   FeedbackSlot slot = proxy->VariableFeedbackSlot();
     507             :   // Ensure that typeof mode is in sync with the IC slot kind.
     508             :   DCHECK_EQ(GetTypeofModeFromSlotKind(feedback_vector_spec()->GetKind(slot)),
     509             :             typeof_mode);
     510             : 
     511             :   EmitLoadSlot(LoadGlobalDescriptor::SlotRegister(), slot);
     512     1627438 :   Handle<Code> code = CodeFactory::LoadGlobalIC(isolate(), typeof_mode).code();
     513      813720 :   __ Call(code, RelocInfo::CODE_TARGET);
     514      813720 :   RestoreContext();
     515      813721 : }
     516             : 
     517        1142 : void FullCodeGenerator::VisitSloppyBlockFunctionStatement(
     518        1142 :     SloppyBlockFunctionStatement* declaration) {
     519        1142 :   Visit(declaration->statement());
     520        1142 : }
     521             : 
     522             : 
     523       39237 : int FullCodeGenerator::DeclareGlobalsFlags() {
     524       39237 :   return info_->GetDeclareGlobalsFlags();
     525             : }
     526             : 
     527      639442 : void FullCodeGenerator::PushOperand(Handle<Object> handle) {
     528             :   OperandStackDepthIncrement(1);
     529      322025 :   __ Push(handle);
     530      317417 : }
     531             : 
     532       16078 : void FullCodeGenerator::PushOperand(Smi* smi) {
     533             :   OperandStackDepthIncrement(1);
     534        8039 :   __ Push(smi);
     535        8039 : }
     536             : 
     537     2566510 : void FullCodeGenerator::PushOperand(Register reg) {
     538             :   OperandStackDepthIncrement(1);
     539     2387444 :   __ Push(reg);
     540      179066 : }
     541             : 
     542     4659222 : void FullCodeGenerator::PopOperand(Register reg) {
     543             :   OperandStackDepthDecrement(1);
     544     2472996 :   __ Pop(reg);
     545     2186226 : }
     546             : 
     547      982577 : void FullCodeGenerator::DropOperands(int count) {
     548             :   OperandStackDepthDecrement(count);
     549      968339 :   __ Drop(count);
     550       14238 : }
     551             : 
     552       94814 : void FullCodeGenerator::CallRuntimeWithOperands(Runtime::FunctionId id) {
     553       47407 :   OperandStackDepthDecrement(Runtime::FunctionForId(id)->nargs);
     554       47407 :   __ CallRuntime(id);
     555       47407 : }
     556             : 
     557     5050954 : void FullCodeGenerator::OperandStackDepthIncrement(int count) {
     558             :   DCHECK_IMPLIES(!HasStackOverflow(), operand_stack_depth_ >= 0);
     559             :   DCHECK_GE(count, 0);
     560     8058392 :   operand_stack_depth_ += count;
     561     5050954 : }
     562             : 
     563     1271830 : void FullCodeGenerator::OperandStackDepthDecrement(int count) {
     564             :   DCHECK_IMPLIES(!HasStackOverflow(), operand_stack_depth_ >= count);
     565             :   DCHECK_GE(count, 0);
     566     4969097 :   operand_stack_depth_ -= count;
     567     1271830 : }
     568             : 
     569        1580 : void FullCodeGenerator::EmitSubString(CallRuntime* expr) {
     570             :   // Load the arguments on the stack and call the stub.
     571             :   SubStringStub stub(isolate());
     572             :   ZoneList<Expression*>* args = expr->arguments();
     573             :   DCHECK(args->length() == 3);
     574         395 :   VisitForStackValue(args->at(0));
     575         395 :   VisitForStackValue(args->at(1));
     576         395 :   VisitForStackValue(args->at(2));
     577         395 :   __ CallStub(&stub);
     578         395 :   RestoreContext();
     579             :   OperandStackDepthDecrement(3);
     580         395 :   context()->Plug(result_register());
     581         395 : }
     582             : 
     583             : 
     584       11176 : void FullCodeGenerator::EmitIntrinsicAsStubCall(CallRuntime* expr,
     585       33528 :                                                 const Callable& callable) {
     586             :   ZoneList<Expression*>* args = expr->arguments();
     587             :   int param_count = callable.descriptor().GetRegisterParameterCount();
     588             :   DCHECK_EQ(args->length(), param_count);
     589             : 
     590       11176 :   if (param_count > 0) {
     591       11176 :     int last = param_count - 1;
     592             :     // Put all but last arguments on stack.
     593       11176 :     for (int i = 0; i < last; i++) {
     594           0 :       VisitForStackValue(args->at(i));
     595             :     }
     596             :     // The last argument goes to the accumulator.
     597       11176 :     VisitForAccumulatorValue(args->at(last));
     598             : 
     599             :     // Move the arguments to the registers, as required by the stub.
     600             :     __ Move(callable.descriptor().GetRegisterParameter(last),
     601       22352 :             result_register());
     602       22352 :     for (int i = last; i-- > 0;) {
     603             :       PopOperand(callable.descriptor().GetRegisterParameter(i));
     604             :     }
     605             :   }
     606       11176 :   __ Call(callable.code(), RelocInfo::CODE_TARGET);
     607             : 
     608             :   // Reload the context register after the call as i.e. TurboFan code stubs
     609             :   // won't preserve the context register.
     610             :   LoadFromFrameField(StandardFrameConstants::kContextOffset,
     611       11176 :                      context_register());
     612       11176 :   context()->Plug(result_register());
     613       11176 : }
     614             : 
     615             : 
     616        5540 : void FullCodeGenerator::EmitToString(CallRuntime* expr) {
     617        5540 :   EmitIntrinsicAsStubCall(expr, CodeFactory::ToString(isolate()));
     618        5540 : }
     619             : 
     620             : 
     621        1792 : void FullCodeGenerator::EmitToLength(CallRuntime* expr) {
     622        1792 :   EmitIntrinsicAsStubCall(expr, CodeFactory::ToLength(isolate()));
     623        1792 : }
     624             : 
     625        1419 : void FullCodeGenerator::EmitToInteger(CallRuntime* expr) {
     626        1419 :   EmitIntrinsicAsStubCall(expr, CodeFactory::ToInteger(isolate()));
     627        1419 : }
     628             : 
     629         324 : void FullCodeGenerator::EmitToNumber(CallRuntime* expr) {
     630         324 :   EmitIntrinsicAsStubCall(expr, CodeFactory::ToNumber(isolate()));
     631         324 : }
     632             : 
     633             : 
     634        2101 : void FullCodeGenerator::EmitToObject(CallRuntime* expr) {
     635        2101 :   EmitIntrinsicAsStubCall(expr, CodeFactory::ToObject(isolate()));
     636        2101 : }
     637             : 
     638             : 
     639       12660 : void FullCodeGenerator::EmitHasProperty() {
     640        6330 :   Callable callable = CodeFactory::HasProperty(isolate());
     641             :   PopOperand(callable.descriptor().GetRegisterParameter(1));
     642             :   PopOperand(callable.descriptor().GetRegisterParameter(0));
     643        6330 :   __ Call(callable.code(), RelocInfo::CODE_TARGET);
     644        6330 :   RestoreContext();
     645        6330 : }
     646             : 
     647     6359592 : void FullCodeGenerator::RecordStatementPosition(int pos) {
     648             :   DCHECK_NE(kNoSourcePosition, pos);
     649     6359592 :   source_position_table_builder_.AddPosition(masm_->pc_offset(),
     650     6359592 :                                              SourcePosition(pos), true);
     651     6359604 : }
     652             : 
     653    14948104 : void FullCodeGenerator::RecordPosition(int pos) {
     654             :   DCHECK_NE(kNoSourcePosition, pos);
     655    14948104 :   source_position_table_builder_.AddPosition(masm_->pc_offset(),
     656    14948104 :                                              SourcePosition(pos), false);
     657    14948128 : }
     658             : 
     659             : 
     660     1079855 : void FullCodeGenerator::SetFunctionPosition(FunctionLiteral* fun) {
     661     1079855 :   RecordPosition(fun->start_position());
     662     1079859 : }
     663             : 
     664             : 
     665     1079863 : void FullCodeGenerator::SetReturnPosition(FunctionLiteral* fun) {
     666             :   // For default constructors, start position equals end position, and there
     667             :   // is no source code besides the class literal.
     668     1079863 :   RecordStatementPosition(fun->return_position());
     669     1079863 :   if (info_->is_debug()) {
     670             :     // Always emit a debug break slot before a return.
     671        3431 :     DebugCodegen::GenerateSlot(masm_, RelocInfo::DEBUG_BREAK_SLOT_AT_RETURN);
     672             :   }
     673     1079863 : }
     674             : 
     675             : 
     676     5796846 : void FullCodeGenerator::SetStatementPosition(
     677             :     Statement* stmt, FullCodeGenerator::InsertBreak insert_break) {
     678    11593698 :   if (stmt->position() == kNoSourcePosition) return;
     679     5191750 :   RecordStatementPosition(stmt->position());
     680     5202315 :   if (insert_break == INSERT_BREAK && info_->is_debug() &&
     681             :       !stmt->IsDebuggerStatement()) {
     682       10556 :     DebugCodegen::GenerateSlot(masm_, RelocInfo::DEBUG_BREAK_SLOT_AT_POSITION);
     683             :   }
     684             : }
     685             : 
     686     9492681 : void FullCodeGenerator::SetExpressionPosition(Expression* expr) {
     687    23219184 :   if (expr->position() == kNoSourcePosition) return;
     688    12619789 :   RecordPosition(expr->position());
     689             : }
     690             : 
     691             : 
     692       92880 : void FullCodeGenerator::SetExpressionAsStatementPosition(Expression* expr) {
     693      185760 :   if (expr->position() == kNoSourcePosition) return;
     694       87983 :   RecordStatementPosition(expr->position());
     695       87983 :   if (info_->is_debug()) {
     696          74 :     DebugCodegen::GenerateSlot(masm_, RelocInfo::DEBUG_BREAK_SLOT_AT_POSITION);
     697             :   }
     698             : }
     699             : 
     700     1248507 : void FullCodeGenerator::SetCallPosition(Expression* expr,
     701             :                                         TailCallMode tail_call_mode) {
     702     2497015 :   if (expr->position() == kNoSourcePosition) return;
     703     1248508 :   RecordPosition(expr->position());
     704     1248509 :   if (info_->is_debug()) {
     705             :     RelocInfo::Mode mode = (tail_call_mode == TailCallMode::kAllow)
     706             :                                ? RelocInfo::DEBUG_BREAK_SLOT_AT_TAIL_CALL
     707        2957 :                                : RelocInfo::DEBUG_BREAK_SLOT_AT_CALL;
     708             :     // Always emit a debug break slot before a call.
     709        2957 :     DebugCodegen::GenerateSlot(masm_, mode);
     710             :   }
     711             : }
     712             : 
     713             : 
     714           0 : void FullCodeGenerator::VisitSuperPropertyReference(
     715           0 :     SuperPropertyReference* super) {
     716           0 :   __ CallRuntime(Runtime::kThrowUnsupportedSuperError);
     717             :   // Even though this expression doesn't produce a value, we need to simulate
     718             :   // plugging of the value context to ensure stack depth tracking is in sync.
     719           0 :   if (context()->IsStackValue()) OperandStackDepthIncrement(1);
     720           0 : }
     721             : 
     722             : 
     723           0 : void FullCodeGenerator::VisitSuperCallReference(SuperCallReference* super) {
     724             :   // Handled by VisitCall
     725           0 :   UNREACHABLE();
     726             : }
     727             : 
     728             : 
     729           0 : void FullCodeGenerator::EmitDebugBreakInOptimizedCode(CallRuntime* expr) {
     730           0 :   context()->Plug(handle(Smi::kZero, isolate()));
     731           0 : }
     732             : 
     733             : 
     734      812660 : void FullCodeGenerator::VisitBinaryOperation(BinaryOperation* expr) {
     735      812660 :   switch (expr->op()) {
     736             :     case Token::COMMA:
     737       23068 :       return VisitComma(expr);
     738             :     case Token::OR:
     739             :     case Token::AND:
     740      147341 :       return VisitLogicalExpression(expr);
     741             :     default:
     742      642251 :       return VisitArithmeticExpression(expr);
     743             :   }
     744             : }
     745             : 
     746             : 
     747      924049 : void FullCodeGenerator::VisitInDuplicateContext(Expression* expr) {
     748      299207 :   if (context()->IsEffect()) {
     749        7511 :     VisitForEffect(expr);
     750      291696 :   } else if (context()->IsAccumulatorValue()) {
     751      169314 :     VisitForAccumulatorValue(expr);
     752      122382 :   } else if (context()->IsStackValue()) {
     753       17000 :     VisitForStackValue(expr);
     754      105382 :   } else if (context()->IsTest()) {
     755      105382 :     const TestContext* test = TestContext::cast(context());
     756             :     VisitForControl(expr, test->true_label(), test->false_label(),
     757      105382 :                     test->fall_through());
     758             :   }
     759      299207 : }
     760             : 
     761             : 
     762       46136 : void FullCodeGenerator::VisitComma(BinaryOperation* expr) {
     763             :   Comment cmnt(masm_, "[ Comma");
     764       23068 :   VisitForEffect(expr->left());
     765       23068 :   VisitInDuplicateContext(expr->right());
     766       23068 : }
     767             : 
     768             : 
     769     1089904 : void FullCodeGenerator::VisitLogicalExpression(BinaryOperation* expr) {
     770      147341 :   bool is_logical_and = expr->op() == Token::AND;
     771             :   Comment cmnt(masm_, is_logical_and ? "[ Logical AND" :  "[ Logical OR");
     772             :   Expression* left = expr->left();
     773             :   Expression* right = expr->right();
     774      147341 :   BailoutId right_id = expr->RightId();
     775             :   Label done;
     776             : 
     777      147341 :   if (context()->IsTest()) {
     778             :     Label eval_right;
     779      104521 :     const TestContext* test = TestContext::cast(context());
     780      104521 :     if (is_logical_and) {
     781       39520 :       VisitForControl(left, &eval_right, test->false_label(), &eval_right);
     782             :     } else {
     783       65001 :       VisitForControl(left, test->true_label(), &eval_right, &eval_right);
     784             :     }
     785      104521 :     PrepareForBailoutForId(right_id, BailoutState::NO_REGISTERS);
     786      104521 :     __ bind(&eval_right);
     787             : 
     788       42820 :   } else if (context()->IsAccumulatorValue()) {
     789       38727 :     VisitForAccumulatorValue(left);
     790             :     // We want the value in the accumulator for the test, and on the stack in
     791             :     // case we need it.
     792       77454 :     __ Push(result_register());
     793             :     Label discard, restore;
     794       38727 :     if (is_logical_and) {
     795       22746 :       DoTest(left, &discard, &restore, &restore);
     796             :     } else {
     797       15981 :       DoTest(left, &restore, &discard, &restore);
     798             :     }
     799       38727 :     __ bind(&restore);
     800       77454 :     __ Pop(result_register());
     801       38727 :     __ jmp(&done);
     802       38727 :     __ bind(&discard);
     803       38727 :     __ Drop(1);
     804       38727 :     PrepareForBailoutForId(right_id, BailoutState::NO_REGISTERS);
     805             : 
     806        4093 :   } else if (context()->IsStackValue()) {
     807        4065 :     VisitForAccumulatorValue(left);
     808             :     // We want the value in the accumulator for the test, and on the stack in
     809             :     // case we need it.
     810        8130 :     __ Push(result_register());
     811             :     Label discard;
     812        4065 :     if (is_logical_and) {
     813         188 :       DoTest(left, &discard, &done, &discard);
     814             :     } else {
     815        3877 :       DoTest(left, &done, &discard, &discard);
     816             :     }
     817        4065 :     __ bind(&discard);
     818        4065 :     __ Drop(1);
     819        4065 :     PrepareForBailoutForId(right_id, BailoutState::NO_REGISTERS);
     820             : 
     821             :   } else {
     822             :     DCHECK(context()->IsEffect());
     823             :     Label eval_right;
     824          28 :     if (is_logical_and) {
     825          24 :       VisitForControl(left, &eval_right, &done, &eval_right);
     826             :     } else {
     827           4 :       VisitForControl(left, &done, &eval_right, &eval_right);
     828             :     }
     829          28 :     PrepareForBailoutForId(right_id, BailoutState::NO_REGISTERS);
     830          28 :     __ bind(&eval_right);
     831             :   }
     832             : 
     833      147341 :   VisitInDuplicateContext(right);
     834      147341 :   __ bind(&done);
     835      147341 : }
     836             : 
     837             : 
     838     1284502 : void FullCodeGenerator::VisitArithmeticExpression(BinaryOperation* expr) {
     839             :   Token::Value op = expr->op();
     840             :   Comment cmnt(masm_, "[ ArithmeticExpression");
     841             :   Expression* left = expr->left();
     842             :   Expression* right = expr->right();
     843             : 
     844      642251 :   VisitForStackValue(left);
     845      642251 :   VisitForAccumulatorValue(right);
     846             : 
     847             :   SetExpressionPosition(expr);
     848      642251 :   if (ShouldInlineSmiCase(op)) {
     849      214199 :     EmitInlineSmiBinaryOp(expr, op, left, right);
     850             :   } else {
     851      428052 :     EmitBinaryOp(expr, op);
     852             :   }
     853      642251 : }
     854             : 
     855     7451302 : void FullCodeGenerator::VisitProperty(Property* expr) {
     856             :   Comment cmnt(masm_, "[ Property");
     857             :   SetExpressionPosition(expr);
     858             : 
     859             :   Expression* key = expr->key();
     860             : 
     861     1449320 :   if (key->IsPropertyName()) {
     862             :     DCHECK(!expr->IsSuperAccess());
     863     1244620 :     VisitForAccumulatorValue(expr->obj());
     864     2489240 :     __ Move(LoadDescriptor::ReceiverRegister(), result_register());
     865     1244620 :     EmitNamedPropertyLoad(expr);
     866             :   } else {
     867             :     DCHECK(!expr->IsSuperAccess());
     868      204700 :     VisitForStackValue(expr->obj());
     869      204700 :     VisitForAccumulatorValue(expr->key());
     870      409400 :     __ Move(LoadDescriptor::NameRegister(), result_register());
     871      204700 :     PopOperand(LoadDescriptor::ReceiverRegister());
     872      204700 :     EmitKeyedPropertyLoad(expr);
     873             :   }
     874     1449321 :   PrepareForBailoutForId(expr->LoadId(), BailoutState::TOS_REGISTER);
     875     1449321 :   context()->Plug(result_register());
     876     1449321 : }
     877             : 
     878       84124 : void FullCodeGenerator::VisitForTypeofValue(Expression* expr) {
     879      164720 :   VariableProxy* proxy = expr->AsVariableProxy();
     880             :   DCHECK(!context()->IsEffect());
     881             :   DCHECK(!context()->IsTest());
     882             : 
     883      164720 :   if (proxy != NULL && proxy->var()->IsUnallocated()) {
     884         272 :     EmitVariableLoad(proxy, INSIDE_TYPEOF);
     885             :     PrepareForBailout(proxy, BailoutState::TOS_REGISTER);
     886             :   } else {
     887             :     // This expression cannot throw a reference error at the top level.
     888       83852 :     VisitInDuplicateContext(expr);
     889             :   }
     890       84124 : }
     891             : 
     892             : 
     893     5952155 : void FullCodeGenerator::VisitBlock(Block* stmt) {
     894             :   Comment cmnt(masm_, "[ Block");
     895             :   NestedBlock nested_block(this, stmt);
     896             : 
     897             :   {
     898             :     EnterBlockScopeIfNeeded block_scope_state(
     899     1984052 :         this, stmt->scope(), stmt->EntryId(), stmt->DeclsId(), stmt->ExitId());
     900     1984052 :     VisitStatements(stmt->statements());
     901     1984051 :     __ bind(nested_block.break_label());
     902             :   }
     903     1984050 : }
     904             : 
     905             : 
     906         528 : void FullCodeGenerator::VisitDoExpression(DoExpression* expr) {
     907             :   Comment cmnt(masm_, "[ Do Expression");
     908             :   SetExpressionPosition(expr);
     909         176 :   VisitBlock(expr->block());
     910         176 :   VisitInDuplicateContext(expr->result());
     911         176 : }
     912             : 
     913             : 
     914     7970298 : void FullCodeGenerator::VisitExpressionStatement(ExpressionStatement* stmt) {
     915             :   Comment cmnt(masm_, "[ ExpressionStatement");
     916     3985148 :   SetStatementPosition(stmt);
     917     3985150 :   VisitForEffect(stmt->expression());
     918     3985153 : }
     919             : 
     920             : 
     921           8 : void FullCodeGenerator::VisitEmptyStatement(EmptyStatement* stmt) {
     922             :   Comment cmnt(masm_, "[ EmptyStatement");
     923           8 : }
     924             : 
     925             : 
     926     2717094 : void FullCodeGenerator::VisitIfStatement(IfStatement* stmt) {
     927             :   Comment cmnt(masm_, "[ IfStatement");
     928      494043 :   SetStatementPosition(stmt);
     929             :   Label then_part, else_part, done;
     930             : 
     931      494043 :   if (stmt->HasElseStatement()) {
     932       82293 :     VisitForControl(stmt->condition(), &then_part, &else_part, &then_part);
     933       82293 :     PrepareForBailoutForId(stmt->ThenId(), BailoutState::NO_REGISTERS);
     934       82293 :     __ bind(&then_part);
     935       82293 :     Visit(stmt->then_statement());
     936       82293 :     __ jmp(&done);
     937             : 
     938       82293 :     PrepareForBailoutForId(stmt->ElseId(), BailoutState::NO_REGISTERS);
     939       82293 :     __ bind(&else_part);
     940       82293 :     Visit(stmt->else_statement());
     941             :   } else {
     942      411750 :     VisitForControl(stmt->condition(), &then_part, &done, &then_part);
     943      411750 :     PrepareForBailoutForId(stmt->ThenId(), BailoutState::NO_REGISTERS);
     944      411750 :     __ bind(&then_part);
     945      411750 :     Visit(stmt->then_statement());
     946             : 
     947      411750 :     PrepareForBailoutForId(stmt->ElseId(), BailoutState::NO_REGISTERS);
     948             :   }
     949      494043 :   __ bind(&done);
     950      494043 :   PrepareForBailoutForId(stmt->IfId(), BailoutState::NO_REGISTERS);
     951      494043 : }
     952             : 
     953       18865 : void FullCodeGenerator::EmitContinue(Statement* target) {
     954        7604 :   NestedStatement* current = nesting_stack_;
     955        3802 :   int context_length = 0;
     956             :   // When continuing, we clobber the unpredictable value in the accumulator
     957             :   // with one that's safe for GC.
     958        3802 :   ClearAccumulator();
     959       15063 :   while (!current->IsContinueTarget(target)) {
     960        7459 :     if (HasStackOverflow()) return;
     961        7459 :     current = current->Exit(&context_length);
     962             :   }
     963             :   int stack_depth = current->GetStackDepthAtTarget();
     964        3802 :   int stack_drop = operand_stack_depth_ - stack_depth;
     965             :   DCHECK_GE(stack_drop, 0);
     966        3802 :   __ Drop(stack_drop);
     967        3802 :   if (context_length > 0) {
     968           0 :     while (context_length > 0) {
     969           0 :       LoadContextField(context_register(), Context::PREVIOUS_INDEX);
     970           0 :       --context_length;
     971             :     }
     972             :     StoreToFrameField(StandardFrameConstants::kContextOffset,
     973           0 :                       context_register());
     974             :   }
     975             : 
     976        7604 :   __ jmp(current->AsIteration()->continue_label());
     977             : }
     978             : 
     979        7604 : void FullCodeGenerator::VisitContinueStatement(ContinueStatement* stmt) {
     980             :   Comment cmnt(masm_, "[ ContinueStatement");
     981        3802 :   SetStatementPosition(stmt);
     982        3802 :   EmitContinue(stmt->target());
     983        3802 : }
     984             : 
     985      164959 : void FullCodeGenerator::EmitBreak(Statement* target) {
     986       80570 :   NestedStatement* current = nesting_stack_;
     987       40285 :   int context_length = 0;
     988             :   // When breaking, we clobber the unpredictable value in the accumulator
     989             :   // with one that's safe for GC.
     990       40285 :   ClearAccumulator();
     991      124674 :   while (!current->IsBreakTarget(target)) {
     992       44104 :     if (HasStackOverflow()) return;
     993       44104 :     current = current->Exit(&context_length);
     994             :   }
     995             :   int stack_depth = current->GetStackDepthAtTarget();
     996       40285 :   int stack_drop = operand_stack_depth_ - stack_depth;
     997             :   DCHECK_GE(stack_drop, 0);
     998       40285 :   __ Drop(stack_drop);
     999       40285 :   if (context_length > 0) {
    1000        4908 :     while (context_length > 0) {
    1001        2454 :       LoadContextField(context_register(), Context::PREVIOUS_INDEX);
    1002        2454 :       --context_length;
    1003             :     }
    1004             :     StoreToFrameField(StandardFrameConstants::kContextOffset,
    1005        2454 :                       context_register());
    1006             :   }
    1007             : 
    1008       80570 :   __ jmp(current->AsBreakable()->break_label());
    1009             : }
    1010             : 
    1011       80570 : void FullCodeGenerator::VisitBreakStatement(BreakStatement* stmt) {
    1012             :   Comment cmnt(masm_, "[ BreakStatement");
    1013       40285 :   SetStatementPosition(stmt);
    1014       40285 :   EmitBreak(stmt->target());
    1015       40285 : }
    1016             : 
    1017     1354446 : void FullCodeGenerator::EmitUnwindAndReturn() {
    1018     1112705 :   NestedStatement* current = nesting_stack_;
    1019     1112705 :   int context_length = 0;
    1020     2467152 :   while (current != NULL) {
    1021      241741 :     if (HasStackOverflow()) return;
    1022      241741 :     current = current->Exit(&context_length);
    1023             :   }
    1024     1112706 :   EmitReturnSequence();
    1025             : }
    1026             : 
    1027     1342731 : void FullCodeGenerator::EmitNewClosure(Handle<SharedFunctionInfo> info,
    1028     8258169 :                                        FeedbackSlot slot, bool pretenure) {
    1029             :   // If slot is invalid, then it's a native function literal and we
    1030             :   // can pass the empty array or empty literal array, something like that...
    1031             : 
    1032             :   // If we're running with the --always-opt or the --prepare-always-opt
    1033             :   // flag, we need to use the runtime function so that the new function
    1034             :   // we are creating here gets a chance to have its code optimized and
    1035             :   // doesn't just get a copy of the existing unoptimized code.
    1036     1544511 :   if (!FLAG_always_opt && !FLAG_prepare_always_opt && !pretenure &&
    1037      201780 :       scope()->is_function_scope()) {
    1038       93640 :     Callable callable = CodeFactory::FastNewClosure(isolate());
    1039       93640 :     __ Move(callable.descriptor().GetRegisterParameter(0), info);
    1040       93640 :     __ EmitLoadFeedbackVector(callable.descriptor().GetRegisterParameter(1));
    1041             :     __ Move(callable.descriptor().GetRegisterParameter(2), SmiFromSlot(slot));
    1042       93640 :     __ Call(callable.code(), RelocInfo::CODE_TARGET);
    1043             :   } else {
    1044     1249091 :     __ Push(info);
    1045     2498185 :     __ EmitLoadFeedbackVector(result_register());
    1046     2498186 :     __ Push(result_register());
    1047     1249093 :     __ Push(SmiFromSlot(slot));
    1048             :     __ CallRuntime(pretenure ? Runtime::kNewClosure_Tenured
    1049     2498176 :                              : Runtime::kNewClosure);
    1050             :   }
    1051     1342732 :   context()->Plug(result_register());
    1052     1342731 : }
    1053             : 
    1054     3487183 : void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) {
    1055             :   SetExpressionPosition(prop);
    1056     3487185 :   Literal* key = prop->key()->AsLiteral();
    1057             :   DCHECK(!key->value()->IsSmi());
    1058             :   DCHECK(!prop->IsSuperAccess());
    1059             : 
    1060     1743593 :   CallLoadIC(prop->PropertyFeedbackSlot(), key->value());
    1061     1743593 : }
    1062             : 
    1063      622227 : void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) {
    1064             :   SetExpressionPosition(prop);
    1065             : 
    1066      207409 :   EmitLoadSlot(LoadDescriptor::SlotRegister(), prop->PropertyFeedbackSlot());
    1067             : 
    1068      414818 :   Handle<Code> code = CodeFactory::KeyedLoadIC(isolate()).code();
    1069      207409 :   __ Call(code, RelocInfo::CODE_TARGET);
    1070      207409 :   RestoreContext();
    1071      207409 : }
    1072             : 
    1073     4126831 : void FullCodeGenerator::EmitLoadSlot(Register destination, FeedbackSlot slot) {
    1074             :   DCHECK(!slot.IsInvalid());
    1075             :   __ Move(destination, SmiFromSlot(slot));
    1076           0 : }
    1077             : 
    1078           0 : void FullCodeGenerator::EmitPushSlot(FeedbackSlot slot) {
    1079           0 :   __ Push(SmiFromSlot(slot));
    1080           0 : }
    1081             : 
    1082     2225413 : void FullCodeGenerator::VisitReturnStatement(ReturnStatement* stmt) {
    1083             :   Comment cmnt(masm_, "[ ReturnStatement");
    1084     1112705 :   SetStatementPosition(stmt);
    1085             :   Expression* expr = stmt->expression();
    1086     1112708 :   VisitForAccumulatorValue(expr);
    1087     1112707 :   EmitUnwindAndReturn();
    1088     1112706 : }
    1089             : 
    1090             : 
    1091           0 : void FullCodeGenerator::VisitWithStatement(WithStatement* stmt) {
    1092             :   // Dynamic scoping is not supported.
    1093           0 :   UNREACHABLE();
    1094             : }
    1095             : 
    1096             : 
    1097       26440 : void FullCodeGenerator::VisitDoWhileStatement(DoWhileStatement* stmt) {
    1098             :   Comment cmnt(masm_, "[ DoWhileStatement");
    1099             :   // Do not insert break location as we do that below.
    1100        3305 :   SetStatementPosition(stmt, SKIP_BREAK);
    1101             : 
    1102             :   Label body, book_keeping;
    1103             : 
    1104             :   Iteration loop_statement(this, stmt);
    1105             :   increment_loop_depth();
    1106             : 
    1107        3305 :   __ bind(&body);
    1108        3305 :   Visit(stmt->body());
    1109             : 
    1110             :   // Record the position of the do while condition and make sure it is
    1111             :   // possible to break on the condition.
    1112        3305 :   __ bind(loop_statement.continue_label());
    1113        3305 :   PrepareForBailoutForId(stmt->ContinueId(), BailoutState::NO_REGISTERS);
    1114             : 
    1115             :   // Here is the actual 'while' keyword.
    1116        3305 :   SetExpressionAsStatementPosition(stmt->cond());
    1117             :   VisitForControl(stmt->cond(),
    1118             :                   &book_keeping,
    1119             :                   loop_statement.break_label(),
    1120        3305 :                   &book_keeping);
    1121             : 
    1122             :   // Check stack before looping.
    1123        3305 :   PrepareForBailoutForId(stmt->BackEdgeId(), BailoutState::NO_REGISTERS);
    1124        3305 :   __ bind(&book_keeping);
    1125        3305 :   EmitBackEdgeBookkeeping(stmt, &body);
    1126        3305 :   __ jmp(&body);
    1127             : 
    1128        3305 :   PrepareForBailoutForId(stmt->ExitId(), BailoutState::NO_REGISTERS);
    1129        3305 :   __ bind(loop_statement.break_label());
    1130             :   decrement_loop_depth();
    1131        3305 : }
    1132             : 
    1133             : 
    1134       89160 : void FullCodeGenerator::VisitWhileStatement(WhileStatement* stmt) {
    1135             :   Comment cmnt(masm_, "[ WhileStatement");
    1136             :   Label loop, body;
    1137             : 
    1138             :   Iteration loop_statement(this, stmt);
    1139             :   increment_loop_depth();
    1140             : 
    1141       11145 :   __ bind(&loop);
    1142             : 
    1143       11145 :   SetExpressionAsStatementPosition(stmt->cond());
    1144             :   VisitForControl(stmt->cond(),
    1145             :                   &body,
    1146             :                   loop_statement.break_label(),
    1147       11145 :                   &body);
    1148             : 
    1149       11145 :   PrepareForBailoutForId(stmt->BodyId(), BailoutState::NO_REGISTERS);
    1150       11145 :   __ bind(&body);
    1151       11145 :   Visit(stmt->body());
    1152             : 
    1153       11145 :   __ bind(loop_statement.continue_label());
    1154             : 
    1155             :   // Check stack before looping.
    1156       11145 :   EmitBackEdgeBookkeeping(stmt, &loop);
    1157       11145 :   __ jmp(&loop);
    1158             : 
    1159       11145 :   PrepareForBailoutForId(stmt->ExitId(), BailoutState::NO_REGISTERS);
    1160       11145 :   __ bind(loop_statement.break_label());
    1161             :   decrement_loop_depth();
    1162       11145 : }
    1163             : 
    1164             : 
    1165      857847 : void FullCodeGenerator::VisitForStatement(ForStatement* stmt) {
    1166             :   Comment cmnt(masm_, "[ ForStatement");
    1167             :   // Do not insert break location as we do it below.
    1168       79389 :   SetStatementPosition(stmt, SKIP_BREAK);
    1169             : 
    1170             :   Label test, body;
    1171             : 
    1172             :   Iteration loop_statement(this, stmt);
    1173             : 
    1174       79389 :   if (stmt->init() != NULL) {
    1175       59142 :     Visit(stmt->init());
    1176             :   }
    1177             : 
    1178             :   increment_loop_depth();
    1179             :   // Emit the test at the bottom of the loop (even if empty).
    1180       79389 :   __ jmp(&test);
    1181             : 
    1182       79389 :   PrepareForBailoutForId(stmt->BodyId(), BailoutState::NO_REGISTERS);
    1183       79389 :   __ bind(&body);
    1184       79389 :   Visit(stmt->body());
    1185             : 
    1186       79389 :   PrepareForBailoutForId(stmt->ContinueId(), BailoutState::NO_REGISTERS);
    1187       79389 :   __ bind(loop_statement.continue_label());
    1188       79389 :   if (stmt->next() != NULL) {
    1189       63957 :     SetStatementPosition(stmt->next());
    1190       63957 :     Visit(stmt->next());
    1191             :   }
    1192             : 
    1193             :   // Check stack before looping.
    1194       79389 :   EmitBackEdgeBookkeeping(stmt, &body);
    1195             : 
    1196       79389 :   __ bind(&test);
    1197       79389 :   if (stmt->cond() != NULL) {
    1198       73286 :     SetExpressionAsStatementPosition(stmt->cond());
    1199             :     VisitForControl(stmt->cond(),
    1200             :                     &body,
    1201             :                     loop_statement.break_label(),
    1202       73286 :                     loop_statement.break_label());
    1203             :   } else {
    1204        6103 :     __ jmp(&body);
    1205             :   }
    1206             : 
    1207       79389 :   PrepareForBailoutForId(stmt->ExitId(), BailoutState::NO_REGISTERS);
    1208       79389 :   __ bind(loop_statement.break_label());
    1209             :   decrement_loop_depth();
    1210       79389 : }
    1211             : 
    1212             : 
    1213           0 : void FullCodeGenerator::VisitForOfStatement(ForOfStatement* stmt) {
    1214             :   // Iterator looping is not supported.
    1215           0 :   UNREACHABLE();
    1216             : }
    1217             : 
    1218       58848 : void FullCodeGenerator::VisitThisFunction(ThisFunction* expr) {
    1219             :   LoadFromFrameField(JavaScriptFrameConstants::kFunctionOffset,
    1220       29422 :                      result_register());
    1221       29426 :   context()->Plug(result_register());
    1222       29426 : }
    1223             : 
    1224           0 : void FullCodeGenerator::VisitTryCatchStatement(TryCatchStatement* stmt) {
    1225             :   // Exception handling is not supported.
    1226           0 :   UNREACHABLE();
    1227             : }
    1228             : 
    1229             : 
    1230           0 : void FullCodeGenerator::VisitTryFinallyStatement(TryFinallyStatement* stmt) {
    1231             :   // Exception handling is not supported.
    1232           0 :   UNREACHABLE();
    1233             : }
    1234             : 
    1235             : 
    1236           0 : void FullCodeGenerator::VisitDebuggerStatement(DebuggerStatement* stmt) {
    1237             :   // Debugger statement is not supported.
    1238           0 :   UNREACHABLE();
    1239             : }
    1240             : 
    1241             : 
    1242           0 : void FullCodeGenerator::VisitCaseClause(CaseClause* clause) {
    1243           0 :   UNREACHABLE();
    1244             : }
    1245             : 
    1246             : 
    1247      271720 : void FullCodeGenerator::VisitConditional(Conditional* expr) {
    1248             :   Comment cmnt(masm_, "[ Conditional");
    1249             :   Label true_case, false_case, done;
    1250       22695 :   VisitForControl(expr->condition(), &true_case, &false_case, &true_case);
    1251             : 
    1252       22695 :   int original_stack_depth = operand_stack_depth_;
    1253       22695 :   PrepareForBailoutForId(expr->ThenId(), BailoutState::NO_REGISTERS);
    1254       22695 :   __ bind(&true_case);
    1255             :   SetExpressionPosition(expr->then_expression());
    1256       22695 :   if (context()->IsTest()) {
    1257         620 :     const TestContext* for_test = TestContext::cast(context());
    1258             :     VisitForControl(expr->then_expression(),
    1259             :                     for_test->true_label(),
    1260             :                     for_test->false_label(),
    1261         620 :                     NULL);
    1262             :   } else {
    1263       22075 :     VisitInDuplicateContext(expr->then_expression());
    1264       22075 :     __ jmp(&done);
    1265             :   }
    1266             : 
    1267       22695 :   operand_stack_depth_ = original_stack_depth;
    1268       22695 :   PrepareForBailoutForId(expr->ElseId(), BailoutState::NO_REGISTERS);
    1269       22695 :   __ bind(&false_case);
    1270             :   SetExpressionPosition(expr->else_expression());
    1271       22695 :   VisitInDuplicateContext(expr->else_expression());
    1272             :   // If control flow falls through Visit, merge it with true case here.
    1273       22695 :   if (!context()->IsTest()) {
    1274       22075 :     __ bind(&done);
    1275             :   }
    1276       22695 : }
    1277             : 
    1278             : 
    1279     6412072 : void FullCodeGenerator::VisitLiteral(Literal* expr) {
    1280             :   Comment cmnt(masm_, "[ Literal");
    1281     6412072 :   context()->Plug(expr->value());
    1282     3206037 : }
    1283             : 
    1284             : 
    1285     2684450 : void FullCodeGenerator::VisitFunctionLiteral(FunctionLiteral* expr) {
    1286             :   Comment cmnt(masm_, "[ FunctionLiteral");
    1287             : 
    1288             :   // Build the function boilerplate and instantiate it.
    1289             :   Handle<SharedFunctionInfo> function_info =
    1290     2684447 :       Compiler::GetSharedFunctionInfo(expr, script(), info_);
    1291     1342227 :   if (function_info.is_null()) {
    1292             :     SetStackOverflow();
    1293     1342226 :     return;
    1294             :   }
    1295     1342227 :   EmitNewClosure(function_info, expr->LiteralFeedbackSlot(), expr->pretenure());
    1296             : }
    1297             : 
    1298             : 
    1299           0 : void FullCodeGenerator::VisitClassLiteral(ClassLiteral* lit) {
    1300             :   // Unsupported
    1301           0 :   UNREACHABLE();
    1302             : }
    1303             : 
    1304      198928 : void FullCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) {
    1305             :   Comment cmnt(masm_, "[ RegExpLiteral");
    1306       24866 :   Callable callable = CodeFactory::FastCloneRegExp(isolate());
    1307             :   CallInterfaceDescriptor descriptor = callable.descriptor();
    1308             :   LoadFromFrameField(JavaScriptFrameConstants::kFunctionOffset,
    1309       24866 :                      descriptor.GetRegisterParameter(0));
    1310             :   __ Move(descriptor.GetRegisterParameter(1),
    1311             :           SmiFromSlot(expr->literal_slot()));
    1312       24866 :   __ Move(descriptor.GetRegisterParameter(2), expr->pattern());
    1313             :   __ Move(descriptor.GetRegisterParameter(3), Smi::FromInt(expr->flags()));
    1314       24866 :   __ Call(callable.code(), RelocInfo::CODE_TARGET);
    1315             : 
    1316             :   // Reload the context register after the call as i.e. TurboFan code stubs
    1317             :   // won't preserve the context register.
    1318             :   LoadFromFrameField(StandardFrameConstants::kContextOffset,
    1319       24866 :                      context_register());
    1320       24866 :   context()->Plug(result_register());
    1321       24866 : }
    1322             : 
    1323         505 : void FullCodeGenerator::VisitNativeFunctionLiteral(
    1324        1010 :     NativeFunctionLiteral* expr) {
    1325             :   Comment cmnt(masm_, "[ NativeFunctionLiteral");
    1326             :   Handle<SharedFunctionInfo> shared =
    1327         505 :       Compiler::GetSharedFunctionInfoForNative(expr->extension(), expr->name());
    1328         505 :   EmitNewClosure(shared, expr->LiteralFeedbackSlot(), false);
    1329         505 : }
    1330             : 
    1331             : 
    1332       49298 : void FullCodeGenerator::VisitThrow(Throw* expr) {
    1333             :   Comment cmnt(masm_, "[ Throw");
    1334       24649 :   VisitForStackValue(expr->exception());
    1335             :   SetExpressionPosition(expr);
    1336       24649 :   CallRuntimeWithOperands(Runtime::kThrow);
    1337             :   // Never returns here.
    1338             : 
    1339             :   // Even though this expression doesn't produce a value, we need to simulate
    1340             :   // plugging of the value context to ensure stack depth tracking is in sync.
    1341       24649 :   if (context()->IsStackValue()) OperandStackDepthIncrement(1);
    1342       24649 : }
    1343             : 
    1344             : 
    1345     2498012 : void FullCodeGenerator::VisitCall(Call* expr) {
    1346             : #ifdef DEBUG
    1347             :   // We want to verify that RecordJSReturnSite gets called on all paths
    1348             :   // through this function.  Avoid early returns.
    1349             :   expr->return_is_recorded_ = false;
    1350             : #endif
    1351             : 
    1352             :   Comment cmnt(masm_, (expr->tail_call_mode() == TailCallMode::kAllow)
    1353             :                           ? "[ TailCall"
    1354             :                           : "[ Call");
    1355             :   Expression* callee = expr->expression();
    1356     1104048 :   Call::CallType call_type = expr->GetCallType();
    1357             : 
    1358             :   // Eval is unsupported.
    1359     1104050 :   CHECK(!expr->is_possibly_eval());
    1360             : 
    1361     1104050 :   switch (call_type) {
    1362             :     case Call::GLOBAL_CALL:
    1363      317417 :       EmitCallWithLoadIC(expr);
    1364      317417 :       break;
    1365             :     case Call::NAMED_PROPERTY_CALL: {
    1366      989728 :       Property* property = callee->AsProperty();
    1367      494864 :       VisitForStackValue(property->obj());
    1368      494864 :       EmitCallWithLoadIC(expr);
    1369      494865 :       break;
    1370             :     }
    1371             :     case Call::KEYED_PROPERTY_CALL: {
    1372        5571 :       Property* property = callee->AsProperty();
    1373        1857 :       VisitForStackValue(property->obj());
    1374        1857 :       EmitKeyedCallWithLoadIC(expr, property->key());
    1375        1857 :       break;
    1376             :     }
    1377             :     case Call::OTHER_CALL:
    1378             :       // Call to an arbitrary expression not handled specially above.
    1379      289909 :       VisitForStackValue(callee);
    1380             :       OperandStackDepthIncrement(1);
    1381      289914 :       __ PushRoot(Heap::kUndefinedValueRootIndex);
    1382             :       // Emit function call.
    1383      289914 :       EmitCall(expr);
    1384      289914 :       break;
    1385             :     case Call::NAMED_SUPER_PROPERTY_CALL:
    1386             :     case Call::KEYED_SUPER_PROPERTY_CALL:
    1387             :     case Call::SUPER_CALL:
    1388             :     case Call::WITH_CALL:
    1389           0 :       UNREACHABLE();
    1390             :   }
    1391             : 
    1392             : #ifdef DEBUG
    1393             :   // RecordJSReturnSite should have been called.
    1394             :   DCHECK(expr->return_is_recorded_);
    1395             : #endif
    1396     1104056 : }
    1397             : 
    1398     1043656 : void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
    1399             :   ZoneList<Expression*>* args = expr->arguments();
    1400      303237 :   int arg_count = args->length();
    1401             : 
    1402      303237 :   if (expr->is_jsruntime()) {
    1403             :     Comment cmnt(masm_, "[ CallRuntime");
    1404       20922 :     EmitLoadJSRuntimeFunction(expr);
    1405             : 
    1406             :     // Push the arguments ("left-to-right").
    1407       66103 :     for (int i = 0; i < arg_count; i++) {
    1408       45181 :       VisitForStackValue(args->at(i));
    1409             :     }
    1410             : 
    1411       20922 :     PrepareForBailoutForId(expr->CallId(), BailoutState::NO_REGISTERS);
    1412       20922 :     EmitCallJSRuntimeFunction(expr);
    1413       20922 :     context()->DropAndPlug(1, result_register());
    1414             : 
    1415             :   } else {
    1416             :     const Runtime::Function* function = expr->function();
    1417      282315 :     switch (function->function_id) {
    1418             : #define CALL_INTRINSIC_GENERATOR(Name)     \
    1419             :   case Runtime::kInline##Name: {           \
    1420             :     Comment cmnt(masm_, "[ Inline" #Name); \
    1421             :     return Emit##Name(expr);               \
    1422             :   }
    1423        3154 :       FOR_EACH_FULL_CODE_INTRINSIC(CALL_INTRINSIC_GENERATOR)
    1424             : #undef CALL_INTRINSIC_GENERATOR
    1425             :       default: {
    1426             :         Comment cmnt(masm_, "[ CallRuntime for unhandled intrinsic");
    1427             :         // Push the arguments ("left-to-right").
    1428      402660 :         for (int i = 0; i < arg_count; i++) {
    1429      402659 :           VisitForStackValue(args->at(i));
    1430             :         }
    1431             : 
    1432             :         // Call the C runtime function.
    1433      208130 :         PrepareForBailoutForId(expr->CallId(), BailoutState::NO_REGISTERS);
    1434      208130 :         __ CallRuntime(expr->function(), arg_count);
    1435             :         OperandStackDepthDecrement(arg_count);
    1436      208130 :         context()->Plug(result_register());
    1437             :       }
    1438             :     }
    1439             :   }
    1440             : }
    1441             : 
    1442           0 : void FullCodeGenerator::VisitSpread(Spread* expr) { UNREACHABLE(); }
    1443             : 
    1444             : 
    1445           0 : void FullCodeGenerator::VisitEmptyParentheses(EmptyParentheses* expr) {
    1446           0 :   UNREACHABLE();
    1447             : }
    1448             : 
    1449           0 : void FullCodeGenerator::VisitGetIterator(GetIterator* expr) { UNREACHABLE(); }
    1450             : 
    1451           0 : void FullCodeGenerator::VisitImportCallExpression(ImportCallExpression* expr) {
    1452           0 :   UNREACHABLE();
    1453             : }
    1454             : 
    1455          54 : void FullCodeGenerator::VisitRewritableExpression(RewritableExpression* expr) {
    1456          54 :   Visit(expr->expression());
    1457          54 : }
    1458             : 
    1459             : 
    1460      569015 : bool FullCodeGenerator::TryLiteralCompare(CompareOperation* expr) {
    1461             :   Expression* sub_expr;
    1462             :   Literal* literal;
    1463      569015 :   if (expr->IsLiteralCompareTypeof(&sub_expr, &literal)) {
    1464             :     SetExpressionPosition(expr);
    1465             :     EmitLiteralCompareTypeof(expr, sub_expr,
    1466      117022 :                              Handle<String>::cast(literal->value()));
    1467       58511 :     return true;
    1468             :   }
    1469             : 
    1470      510504 :   if (expr->IsLiteralCompareUndefined(&sub_expr)) {
    1471             :     SetExpressionPosition(expr);
    1472       40635 :     EmitLiteralCompareNil(expr, sub_expr, kUndefinedValue);
    1473       40635 :     return true;
    1474             :   }
    1475             : 
    1476      469869 :   if (expr->IsLiteralCompareNull(&sub_expr)) {
    1477             :     SetExpressionPosition(expr);
    1478       21886 :     EmitLiteralCompareNil(expr, sub_expr, kNullValue);
    1479       21886 :     return true;
    1480             :   }
    1481             : 
    1482             :   return false;
    1483             : }
    1484             : 
    1485             : 
    1486       10560 : void BackEdgeTable::Patch(Isolate* isolate, Code* unoptimized) {
    1487             :   DisallowHeapAllocation no_gc;
    1488             :   Code* patch = isolate->builtins()->builtin(Builtins::kOnStackReplacement);
    1489             : 
    1490             :   // Increment loop nesting level by one and iterate over the back edge table
    1491             :   // to find the matching loops to patch the interrupt
    1492             :   // call to an unconditional call to the replacement code.
    1493       10560 :   int loop_nesting_level = unoptimized->allow_osr_at_loop_nesting_level() + 1;
    1494       21120 :   if (loop_nesting_level > AbstractCode::kMaxLoopNestingMarker) return;
    1495             : 
    1496             :   BackEdgeTable back_edges(unoptimized, &no_gc);
    1497       28625 :   for (uint32_t i = 0; i < back_edges.length(); i++) {
    1498       19184 :     if (static_cast<int>(back_edges.loop_depth(i)) == loop_nesting_level) {
    1499             :       DCHECK_EQ(INTERRUPT, GetBackEdgeState(isolate,
    1500             :                                             unoptimized,
    1501             :                                             back_edges.pc(i)));
    1502        4826 :       PatchAt(unoptimized, back_edges.pc(i), ON_STACK_REPLACEMENT, patch);
    1503             :     }
    1504             :   }
    1505             : 
    1506             :   unoptimized->set_allow_osr_at_loop_nesting_level(loop_nesting_level);
    1507             :   DCHECK(Verify(isolate, unoptimized));
    1508             : }
    1509             : 
    1510             : 
    1511        2639 : void BackEdgeTable::Revert(Isolate* isolate, Code* unoptimized) {
    1512             :   DisallowHeapAllocation no_gc;
    1513             :   Code* patch = isolate->builtins()->builtin(Builtins::kInterruptCheck);
    1514             : 
    1515             :   // Iterate over the back edge table and revert the patched interrupt calls.
    1516             :   int loop_nesting_level = unoptimized->allow_osr_at_loop_nesting_level();
    1517             : 
    1518             :   BackEdgeTable back_edges(unoptimized, &no_gc);
    1519        7772 :   for (uint32_t i = 0; i < back_edges.length(); i++) {
    1520        5133 :     if (static_cast<int>(back_edges.loop_depth(i)) <= loop_nesting_level) {
    1521             :       DCHECK_NE(INTERRUPT, GetBackEdgeState(isolate,
    1522             :                                             unoptimized,
    1523             :                                             back_edges.pc(i)));
    1524        4819 :       PatchAt(unoptimized, back_edges.pc(i), INTERRUPT, patch);
    1525             :     }
    1526             :   }
    1527             : 
    1528             :   unoptimized->set_allow_osr_at_loop_nesting_level(0);
    1529             :   // Assert that none of the back edges are patched anymore.
    1530             :   DCHECK(Verify(isolate, unoptimized));
    1531        2639 : }
    1532             : 
    1533             : 
    1534             : #ifdef DEBUG
    1535             : bool BackEdgeTable::Verify(Isolate* isolate, Code* unoptimized) {
    1536             :   DisallowHeapAllocation no_gc;
    1537             :   int loop_nesting_level = unoptimized->allow_osr_at_loop_nesting_level();
    1538             :   BackEdgeTable back_edges(unoptimized, &no_gc);
    1539             :   for (uint32_t i = 0; i < back_edges.length(); i++) {
    1540             :     uint32_t loop_depth = back_edges.loop_depth(i);
    1541             :     CHECK_LE(static_cast<int>(loop_depth), AbstractCode::kMaxLoopNestingMarker);
    1542             :     // Assert that all back edges for shallower loops (and only those)
    1543             :     // have already been patched.
    1544             :     CHECK_EQ((static_cast<int>(loop_depth) <= loop_nesting_level),
    1545             :              GetBackEdgeState(isolate,
    1546             :                               unoptimized,
    1547             :                               back_edges.pc(i)) != INTERRUPT);
    1548             :   }
    1549             :   return true;
    1550             : }
    1551             : #endif  // DEBUG
    1552             : 
    1553             : 
    1554     1984052 : FullCodeGenerator::EnterBlockScopeIfNeeded::EnterBlockScopeIfNeeded(
    1555       45960 :     FullCodeGenerator* codegen, Scope* scope, BailoutId entry_id,
    1556             :     BailoutId declarations_id, BailoutId exit_id)
    1557     1984052 :     : codegen_(codegen), exit_id_(exit_id) {
    1558     1984052 :   saved_scope_ = codegen_->scope();
    1559             : 
    1560     1984052 :   if (scope == NULL) {
    1561     1938092 :     codegen_->PrepareForBailoutForId(entry_id, BailoutState::NO_REGISTERS);
    1562     1938092 :     needs_block_context_ = false;
    1563             :   } else {
    1564       45960 :     needs_block_context_ = scope->NeedsContext();
    1565       45960 :     codegen_->scope_ = scope;
    1566             :     {
    1567       45960 :       if (needs_block_context_) {
    1568             :         Comment cmnt(masm(), "[ Extend block context");
    1569             :         codegen_->PushOperand(scope->scope_info());
    1570        4608 :         codegen_->PushFunctionArgumentForContextAllocation();
    1571        4608 :         codegen_->CallRuntimeWithOperands(Runtime::kPushBlockContext);
    1572             : 
    1573             :         // Replace the context stored in the frame.
    1574             :         codegen_->StoreToFrameField(StandardFrameConstants::kContextOffset,
    1575        4608 :                                     codegen_->context_register());
    1576             :       }
    1577       45960 :       CHECK_EQ(0, scope->num_stack_slots());
    1578       45960 :       codegen_->PrepareForBailoutForId(entry_id, BailoutState::NO_REGISTERS);
    1579             :     }
    1580             :     {
    1581             :       Comment cmnt(masm(), "[ Declarations");
    1582       45960 :       codegen_->VisitDeclarations(scope->declarations());
    1583             :       codegen_->PrepareForBailoutForId(declarations_id,
    1584       45960 :                                        BailoutState::NO_REGISTERS);
    1585             :     }
    1586             :   }
    1587     1984052 : }
    1588             : 
    1589             : 
    1590     1984051 : FullCodeGenerator::EnterBlockScopeIfNeeded::~EnterBlockScopeIfNeeded() {
    1591     1984051 :   if (needs_block_context_) {
    1592             :     codegen_->LoadContextField(codegen_->context_register(),
    1593        4608 :                                Context::PREVIOUS_INDEX);
    1594             :     // Update local stack frame context field.
    1595             :     codegen_->StoreToFrameField(StandardFrameConstants::kContextOffset,
    1596        4608 :                                 codegen_->context_register());
    1597             :   }
    1598     1984051 :   codegen_->PrepareForBailoutForId(exit_id_, BailoutState::NO_REGISTERS);
    1599     1984051 :   codegen_->scope_ = saved_scope_;
    1600     1984051 : }
    1601             : 
    1602     1428567 : Handle<Script> FullCodeGenerator::script() { return info_->script(); }
    1603             : 
    1604     1200119 : LanguageMode FullCodeGenerator::language_mode() {
    1605       27938 :   return scope()->language_mode();
    1606             : }
    1607             : 
    1608        1399 : bool FullCodeGenerator::has_simple_parameters() {
    1609        1399 :   return info_->has_simple_parameters();
    1610             : }
    1611             : 
    1612     3240955 : FunctionLiteral* FullCodeGenerator::literal() const { return info_->literal(); }
    1613             : 
    1614           0 : const FeedbackVectorSpec* FullCodeGenerator::feedback_vector_spec() const {
    1615           0 :   return literal()->feedback_vector_spec();
    1616             : }
    1617             : 
    1618             : #undef __
    1619             : 
    1620             : 
    1621             : }  // namespace internal
    1622             : }  // namespace v8

Generated by: LCOV version 1.10