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     1697684 : class FullCodegenCompilationJob final : public CompilationJob {
      31             :  public:
      32      848845 :   explicit FullCodegenCompilationJob(CompilationInfo* info)
      33      848845 :       : CompilationJob(info->isolate(), info, "Full-Codegen") {}
      34             : 
      35      848839 :   bool can_execute_on_background_thread() const override { return false; }
      36             : 
      37      848836 :   CompilationJob::Status PrepareJobImpl() final { return SUCCEEDED; }
      38             : 
      39      848842 :   CompilationJob::Status ExecuteJobImpl() final {
      40             :     DCHECK(ThreadId::Current().Equals(isolate()->thread_id()));
      41      848842 :     return FullCodeGenerator::MakeCode(info(), stack_limit()) ? SUCCEEDED
      42      848842 :                                                               : FAILED;
      43             :   }
      44             : 
      45      848835 :   CompilationJob::Status FinalizeJobImpl() final { return SUCCEEDED; }
      46             : 
      47             :  private:
      48             :   DISALLOW_COPY_AND_ASSIGN(FullCodegenCompilationJob);
      49             : };
      50             : 
      51     1080619 : FullCodeGenerator::FullCodeGenerator(MacroAssembler* masm,
      52     5403086 :                                      CompilationInfo* info,
      53             :                                      uintptr_t stack_limit)
      54             :     : masm_(masm),
      55             :       info_(info),
      56             :       isolate_(info->isolate()),
      57             :       zone_(info->zone()),
      58     1080619 :       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      236543 :                            ? 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     9725556 :       ic_total_count_(0) {
      72             :   DCHECK(!info->IsStub());
      73             :   Initialize(stack_limit);
      74     1080610 : }
      75             : 
      76             : // static
      77      848835 : CompilationJob* FullCodeGenerator::NewCompilationJob(CompilationInfo* info) {
      78     1697673 :   return new FullCodegenCompilationJob(info);
      79             : }
      80             : 
      81             : // static
      82      231775 : bool FullCodeGenerator::MakeCode(CompilationInfo* info) {
      83      231775 :   return MakeCode(info, info->isolate()->stack_guard()->real_climit());
      84             : }
      85             : 
      86             : // static
      87     3241844 : bool FullCodeGenerator::MakeCode(CompilationInfo* info, uintptr_t stack_limit) {
      88     1080616 :   Isolate* isolate = info->isolate();
      89             : 
      90             :   DCHECK(!info->shared_info()->must_use_ignition_turbo());
      91             :   DCHECK(!FLAG_minimal);
      92             :   RuntimeCallTimerScope runtimeTimer(isolate,
      93     1080614 :                                      &RuntimeCallStats::CompileFullCode);
      94             :   TimerEventScope<TimerEventCompileFullCode> timer(info->isolate());
      95     3241854 :   TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.CompileFullCode");
      96             : 
      97     1080617 :   Handle<Script> script = info->script();
      98     2161229 :   if (!script->IsUndefined(isolate) &&
      99             :       !script->source()->IsUndefined(isolate)) {
     100             :     int len = String::cast(script->source())->length();
     101     1080616 :     isolate->counters()->total_full_codegen_source_size()->Increment(len);
     102             :   }
     103     1080614 :   CodeGenerator::MakeCodePrologue(info, "full");
     104             :   const int kInitialBufferSize = 4 * KB;
     105             :   MacroAssembler masm(info->isolate(), NULL, kInitialBufferSize,
     106     1080616 :                       CodeObjectRequired::kYes);
     107     1080619 :   if (info->will_serialize()) masm.enable_serializer();
     108             : 
     109     1080619 :   FullCodeGenerator cgen(&masm, info, stack_limit);
     110     1080611 :   cgen.Generate();
     111     1080612 :   if (cgen.HasStackOverflow()) {
     112             :     DCHECK(!isolate->has_pending_exception());
     113             :     return false;
     114             :   }
     115     1080606 :   unsigned table_offset = cgen.EmitBackEdgeTable();
     116             : 
     117             :   Handle<Code> code =
     118     1080607 :       CodeGenerator::MakeCodeEpilogue(&masm, nullptr, info, masm.CodeObject());
     119     1080612 :   cgen.PopulateDeoptimizationData(code);
     120     1080611 :   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     1080610 :           isolate, Handle<AbstractCode>::cast(code));
     129     1080608 :   code->set_source_position_table(*source_positions);
     130     1080609 :   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     1080608 :   return true;
     138             : }
     139             : 
     140             : 
     141     2450682 : 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     1080603 :   masm()->Align(kPointerSize);
     146     2161218 :   unsigned offset = masm()->pc_offset();
     147     1370079 :   unsigned length = back_edges_.length();
     148     1080609 :   __ dd(length);
     149     1177097 :   for (unsigned i = 0; i < length; ++i) {
     150      289470 :     __ dd(back_edges_[i].id.ToInt());
     151      192980 :     __ dd(back_edges_[i].pc);
     152      192980 :     __ dd(back_edges_[i].loop_depth);
     153             :   }
     154     1080607 :   return offset;
     155             : }
     156             : 
     157             : 
     158     1317155 : void FullCodeGenerator::PopulateDeoptimizationData(Handle<Code> code) {
     159             :   // Fill in the deoptimization information.
     160             :   DCHECK(info_->HasDeoptimizationSupport() || bailout_entries_.is_empty());
     161     3241833 :   if (!info_->HasDeoptimizationSupport()) return;
     162    17077242 :   int length = bailout_entries_.length();
     163             :   Handle<DeoptimizationOutputData> data =
     164      236544 :       DeoptimizationOutputData::New(isolate(), length, TENURED);
     165     8656893 :   for (int i = 0; i < length; i++) {
     166     8420349 :     data->SetAstId(i, bailout_entries_[i].id);
     167     8420349 :     data->SetPcAndState(i, Smi::FromInt(bailout_entries_[i].pc_and_state));
     168             :   }
     169      236544 :   code->set_deoptimization_data(*data);
     170             : }
     171             : 
     172             : 
     173     1080608 : void FullCodeGenerator::PopulateTypeFeedbackInfo(Handle<Code> code) {
     174     1080608 :   Handle<TypeFeedbackInfo> info = isolate()->factory()->NewTypeFeedbackInfo();
     175     1080614 :   info->set_ic_total_count(ic_total_count_);
     176             :   DCHECK(!isolate()->heap()->InNewSpace(*info));
     177     1080614 :   code->set_type_feedback_info(*info);
     178     1080609 : }
     179             : 
     180             : 
     181      144384 : bool FullCodeGenerator::MustCreateObjectLiteralWithRuntime(
     182      144384 :     ObjectLiteral* expr) const {
     183      144384 :   return masm()->serializer_enabled() || !expr->IsFastCloningSupported();
     184             : }
     185             : 
     186             : 
     187       74125 : bool FullCodeGenerator::MustCreateArrayLiteralWithRuntime(
     188             :     ArrayLiteral* expr) const {
     189       74125 :   return !expr->IsFastCloningSupported();
     190             : }
     191             : 
     192           0 : void FullCodeGenerator::Initialize(uintptr_t stack_limit) {
     193             :   InitializeAstVisitor(stack_limit);
     194     1080610 :   masm_->set_emit_debug_code(FLAG_debug_code);
     195             :   masm_->set_predictable_code_size(true);
     196           0 : }
     197             : 
     198     4103114 : void FullCodeGenerator::PrepareForBailout(Expression* node,
     199             :                                           BailoutState state) {
     200    18317217 :   PrepareForBailoutForId(node->id(), state);
     201     4103116 : }
     202             : 
     203     5520108 : void FullCodeGenerator::CallIC(Handle<Code> code, TypeFeedbackId ast_id) {
     204     2760054 :   ic_total_count_++;
     205     2760054 :   __ Call(code, RelocInfo::CODE_TARGET, ast_id);
     206     2760058 : }
     207             : 
     208     6982308 : void FullCodeGenerator::CallLoadIC(FeedbackSlot slot, Handle<Object> name) {
     209             :   DCHECK(name->IsName());
     210     3491154 :   __ Move(LoadDescriptor::NameRegister(), name);
     211             : 
     212     1745577 :   EmitLoadSlot(LoadDescriptor::SlotRegister(), slot);
     213             : 
     214     3491154 :   Handle<Code> code = CodeFactory::LoadIC(isolate()).code();
     215     1745577 :   __ Call(code, RelocInfo::CODE_TARGET);
     216     1745577 :   RestoreContext();
     217     1745577 : }
     218             : 
     219     1159102 : void FullCodeGenerator::CallStoreIC(FeedbackSlot slot, Handle<Object> name,
     220     3477306 :                                     StoreICKind store_ic_kind) {
     221             :   DCHECK(name->IsName());
     222     2318204 :   __ 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     1159102 :     EmitLoadSlot(StoreDescriptor::SlotRegister(), slot);
     231             :   }
     232             : 
     233             :   Handle<Code> code;
     234     1159102 :   switch (store_ic_kind) {
     235             :     case kStoreOwn:
     236             :       DCHECK_EQ(FeedbackSlotKind::kStoreOwnNamed,
     237             :                 feedback_vector_spec()->GetKind(slot));
     238      380208 :       code = CodeFactory::StoreOwnIC(isolate()).code();
     239      190104 :       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      119746 :       code = CodeFactory::StoreGlobalIC(isolate(), language_mode()).code();
     246       59873 :       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     1818250 :       code = CodeFactory::StoreIC(isolate(), language_mode()).code();
     253      909125 :       break;
     254             :   }
     255     1159102 :   __ Call(code, RelocInfo::CODE_TARGET);
     256     1159102 :   RestoreContext();
     257     1159102 : }
     258             : 
     259      613137 : 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      204379 :     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      408758 :       CodeFactory::KeyedStoreIC(isolate(), language_mode()).code();
     274      204379 :   __ Call(code, RelocInfo::CODE_TARGET);
     275      204379 :   RestoreContext();
     276      204379 : }
     277             : 
     278     1105372 : 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     1105372 :   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     1105379 : }
     293             : 
     294    42334958 : void FullCodeGenerator::PrepareForBailoutForId(BailoutId id,
     295     8420295 :                                                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   118584579 :   if (!info_->HasDeoptimizationSupport()) return;
     299             :   unsigned pc_and_state =
     300    25260885 :       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     8420295 :   BailoutEntry entry = { id, pc_and_state };
     308             :   bailout_entries_.Add(entry, zone());
     309             : }
     310             : 
     311             : 
     312      192980 : 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      192980 :       { ast_id, static_cast<unsigned>(masm_->pc_offset()), depth };
     319             :   back_edges_.Add(entry, zone());
     320       96490 : }
     321             : 
     322             : 
     323      656293 : 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     1299194 :   if (op == Token::DIV ||op == Token::MOD) return false;
     327     1256885 :   if (FLAG_always_inline_smi_code) return true;
     328     1254605 :   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     2542424 : void FullCodeGenerator::AccumulatorValueContext::Plug(Variable* var) const {
     338             :   DCHECK(var->IsStackAllocated() || var->IsContextSlot());
     339     2542424 :   codegen()->GetVar(result_register(), var);
     340     2542433 : }
     341             : 
     342             : 
     343      149954 : void FullCodeGenerator::TestContext::Plug(Variable* var) const {
     344             :   DCHECK(var->IsStackAllocated() || var->IsContextSlot());
     345             :   // For simplicity we always test the accumulator register.
     346      224931 :   codegen()->GetVar(result_register(), var);
     347       74977 :   codegen()->PrepareForBailoutBeforeSplit(condition(), false, NULL, NULL);
     348             :   codegen()->DoTest(this);
     349       74977 : }
     350             : 
     351             : 
     352     2945955 : void FullCodeGenerator::EffectContext::Plug(Register reg) const {
     353     2945955 : }
     354             : 
     355             : 
     356     2590830 : void FullCodeGenerator::AccumulatorValueContext::Plug(Register reg) const {
     357     2590830 :   __ Move(result_register(), reg);
     358     2590833 : }
     359             : 
     360             : 
     361     2211038 : void FullCodeGenerator::StackValueContext::Plug(Register reg) const {
     362     2211038 :   codegen()->PushOperand(reg);
     363     2211039 : }
     364             : 
     365             : 
     366       91684 : void FullCodeGenerator::TestContext::Plug(Register reg) const {
     367             :   // For simplicity we always test the accumulator register.
     368      137526 :   __ Move(result_register(), reg);
     369       45842 :   codegen()->PrepareForBailoutBeforeSplit(condition(), false, NULL, NULL);
     370             :   codegen()->DoTest(this);
     371       45842 : }
     372             : 
     373             : 
     374          35 : void FullCodeGenerator::EffectContext::Plug(bool flag) const {}
     375             : 
     376      466950 : void FullCodeGenerator::EffectContext::DropAndPlug(int count,
     377             :                                                    Register reg) const {
     378             :   DCHECK(count > 0);
     379      466950 :   codegen()->DropOperands(count);
     380      466950 : }
     381             : 
     382      427232 : void FullCodeGenerator::AccumulatorValueContext::DropAndPlug(
     383             :     int count, Register reg) const {
     384             :   DCHECK(count > 0);
     385      854473 :   codegen()->DropOperands(count);
     386      854482 :   __ Move(result_register(), reg);
     387      427241 : }
     388             : 
     389       61012 : void FullCodeGenerator::TestContext::DropAndPlug(int count,
     390       61012 :                                                  Register reg) const {
     391             :   DCHECK(count > 0);
     392             :   // For simplicity we always test the accumulator register.
     393      244048 :   codegen()->DropOperands(count);
     394      122024 :   __ Move(result_register(), reg);
     395       61012 :   codegen()->PrepareForBailoutBeforeSplit(condition(), false, NULL, NULL);
     396             :   codegen()->DoTest(this);
     397       61012 : }
     398             : 
     399          71 : void FullCodeGenerator::EffectContext::PlugTOS() const {
     400          71 :   codegen()->DropOperands(1);
     401          71 : }
     402             : 
     403             : 
     404       62450 : void FullCodeGenerator::AccumulatorValueContext::PlugTOS() const {
     405       62450 :   codegen()->PopOperand(result_register());
     406       62450 : }
     407             : 
     408             : 
     409       36293 : void FullCodeGenerator::StackValueContext::PlugTOS() const {
     410       36293 : }
     411             : 
     412             : 
     413       14046 : void FullCodeGenerator::TestContext::PlugTOS() const {
     414             :   // For simplicity we always test the accumulator register.
     415       21069 :   codegen()->PopOperand(result_register());
     416        7023 :   codegen()->PrepareForBailoutBeforeSplit(condition(), false, NULL, NULL);
     417             :   codegen()->DoTest(this);
     418        7023 : }
     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       54288 : 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       54288 :   *if_true = *fall_through = materialize_true;
     440       54288 :   *if_false = materialize_false;
     441       54288 : }
     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      518828 : 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      518828 :   *if_true = true_label_;
     462      518828 :   *if_false = false_label_;
     463      518828 :   *fall_through = fall_through_;
     464      518828 : }
     465             : 
     466             : 
     467      188858 : void FullCodeGenerator::DoTest(const TestContext* context) {
     468             :   DoTest(context->condition(),
     469             :          context->true_label(),
     470             :          context->false_label(),
     471      188858 :          context->fall_through());
     472           4 : }
     473             : 
     474     2292377 : void FullCodeGenerator::VisitDeclarations(Declaration::List* declarations) {
     475     1126560 :   ZoneList<Handle<Object> >* saved_globals = globals_;
     476     1126560 :   ZoneList<Handle<Object> > inner_globals(10, zone());
     477     1126572 :   globals_ = &inner_globals;
     478             : 
     479             :   AstVisitor<FullCodeGenerator>::VisitDeclarations(declarations);
     480             : 
     481     2958049 :   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       39257 :        isolate()->factory()->NewFixedArray(globals_->length(), TENURED);
     486     3662954 :     for (int i = 0; i < globals_->length(); ++i)
     487     1792220 :       array->set(i, *globals_->at(i));
     488       39257 :     DeclareGlobals(array);
     489             :   }
     490             : 
     491     1126572 :   globals_ = saved_globals;
     492     1126572 : }
     493             : 
     494             : 
     495           0 : void FullCodeGenerator::VisitVariableProxy(VariableProxy* expr) {
     496             :   Comment cmnt(masm_, "[ VariableProxy");
     497     5655445 :   EmitVariableLoad(expr);
     498           0 : }
     499             : 
     500      814565 : void FullCodeGenerator::EmitGlobalVariableLoad(VariableProxy* proxy,
     501     2443693 :                                                TypeofMode typeof_mode) {
     502      814565 :   Variable* var = proxy->var();
     503             :   DCHECK(var->IsUnallocated());
     504     1629129 :   __ 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     1629129 :   Handle<Code> code = CodeFactory::LoadGlobalIC(isolate(), typeof_mode).code();
     513      814564 :   __ Call(code, RelocInfo::CODE_TARGET);
     514      814565 :   RestoreContext();
     515      814565 : }
     516             : 
     517        1142 : void FullCodeGenerator::VisitSloppyBlockFunctionStatement(
     518        1142 :     SloppyBlockFunctionStatement* declaration) {
     519        1142 :   Visit(declaration->statement());
     520        1142 : }
     521             : 
     522             : 
     523       39257 : int FullCodeGenerator::DeclareGlobalsFlags() {
     524       39257 :   return info_->GetDeclareGlobalsFlags();
     525             : }
     526             : 
     527      639878 : void FullCodeGenerator::PushOperand(Handle<Object> handle) {
     528             :   OperandStackDepthIncrement(1);
     529      322243 :   __ Push(handle);
     530      317635 : }
     531             : 
     532       16092 : void FullCodeGenerator::PushOperand(Smi* smi) {
     533             :   OperandStackDepthIncrement(1);
     534        8046 :   __ Push(smi);
     535        8046 : }
     536             : 
     537     2569516 : void FullCodeGenerator::PushOperand(Register reg) {
     538             :   OperandStackDepthIncrement(1);
     539     2390277 :   __ Push(reg);
     540      179239 : }
     541             : 
     542     4664219 : void FullCodeGenerator::PopOperand(Register reg) {
     543             :   OperandStackDepthDecrement(1);
     544     2475646 :   __ Pop(reg);
     545     2188573 : }
     546             : 
     547      983751 : void FullCodeGenerator::DropOperands(int count) {
     548             :   OperandStackDepthDecrement(count);
     549      969508 :   __ Drop(count);
     550       14243 : }
     551             : 
     552       94958 : void FullCodeGenerator::CallRuntimeWithOperands(Runtime::FunctionId id) {
     553       47479 :   OperandStackDepthDecrement(Runtime::FunctionForId(id)->nargs);
     554       47479 :   __ CallRuntime(id);
     555       47479 : }
     556             : 
     557     5056803 : void FullCodeGenerator::OperandStackDepthIncrement(int count) {
     558             :   DCHECK_IMPLIES(!HasStackOverflow(), operand_stack_depth_ >= 0);
     559             :   DCHECK_GE(count, 0);
     560     8067727 :   operand_stack_depth_ += count;
     561     5056803 : }
     562             : 
     563     1273489 : void FullCodeGenerator::OperandStackDepthDecrement(int count) {
     564             :   DCHECK_IMPLIES(!HasStackOverflow(), operand_stack_depth_ >= count);
     565             :   DCHECK_GE(count, 0);
     566     4975143 :   operand_stack_depth_ -= count;
     567     1273489 : }
     568             : 
     569        1592 : 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         398 :   VisitForStackValue(args->at(0));
     575         398 :   VisitForStackValue(args->at(1));
     576         398 :   VisitForStackValue(args->at(2));
     577         398 :   __ CallStub(&stub);
     578         398 :   RestoreContext();
     579             :   OperandStackDepthDecrement(3);
     580         398 :   context()->Plug(result_register());
     581         398 : }
     582             : 
     583             : 
     584       11214 : void FullCodeGenerator::EmitIntrinsicAsStubCall(CallRuntime* expr,
     585       33642 :                                                 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       11214 :   if (param_count > 0) {
     591       11214 :     int last = param_count - 1;
     592             :     // Put all but last arguments on stack.
     593       11214 :     for (int i = 0; i < last; i++) {
     594           0 :       VisitForStackValue(args->at(i));
     595             :     }
     596             :     // The last argument goes to the accumulator.
     597       11214 :     VisitForAccumulatorValue(args->at(last));
     598             : 
     599             :     // Move the arguments to the registers, as required by the stub.
     600             :     __ Move(callable.descriptor().GetRegisterParameter(last),
     601       22428 :             result_register());
     602       22428 :     for (int i = last; i-- > 0;) {
     603             :       PopOperand(callable.descriptor().GetRegisterParameter(i));
     604             :     }
     605             :   }
     606       11214 :   __ 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       11214 :                      context_register());
     612       11214 :   context()->Plug(result_register());
     613       11214 : }
     614             : 
     615             : 
     616        5564 : void FullCodeGenerator::EmitToString(CallRuntime* expr) {
     617        5564 :   EmitIntrinsicAsStubCall(expr, CodeFactory::ToString(isolate()));
     618        5564 : }
     619             : 
     620             : 
     621        1796 : void FullCodeGenerator::EmitToLength(CallRuntime* expr) {
     622        1796 :   EmitIntrinsicAsStubCall(expr, CodeFactory::ToLength(isolate()));
     623        1796 : }
     624             : 
     625        1427 : void FullCodeGenerator::EmitToInteger(CallRuntime* expr) {
     626        1427 :   EmitIntrinsicAsStubCall(expr, CodeFactory::ToInteger(isolate()));
     627        1427 : }
     628             : 
     629         324 : void FullCodeGenerator::EmitToNumber(CallRuntime* expr) {
     630         324 :   EmitIntrinsicAsStubCall(expr, CodeFactory::ToNumber(isolate()));
     631         324 : }
     632             : 
     633             : 
     634        2103 : void FullCodeGenerator::EmitToObject(CallRuntime* expr) {
     635        2103 :   EmitIntrinsicAsStubCall(expr, CodeFactory::ToObject(isolate()));
     636        2103 : }
     637             : 
     638             : 
     639       12668 : void FullCodeGenerator::EmitHasProperty() {
     640        6334 :   Callable callable = CodeFactory::HasProperty(isolate());
     641             :   PopOperand(callable.descriptor().GetRegisterParameter(1));
     642             :   PopOperand(callable.descriptor().GetRegisterParameter(0));
     643        6334 :   __ Call(callable.code(), RelocInfo::CODE_TARGET);
     644        6334 :   RestoreContext();
     645        6334 : }
     646             : 
     647     6365048 : void FullCodeGenerator::RecordStatementPosition(int pos) {
     648             :   DCHECK_NE(kNoSourcePosition, pos);
     649     6365048 :   source_position_table_builder_.AddPosition(masm_->pc_offset(),
     650     6365048 :                                              SourcePosition(pos), true);
     651     6365071 : }
     652             : 
     653    14965087 : void FullCodeGenerator::RecordPosition(int pos) {
     654             :   DCHECK_NE(kNoSourcePosition, pos);
     655    14965087 :   source_position_table_builder_.AddPosition(masm_->pc_offset(),
     656    14965087 :                                              SourcePosition(pos), false);
     657    14965105 : }
     658             : 
     659             : 
     660     1080604 : void FullCodeGenerator::SetFunctionPosition(FunctionLiteral* fun) {
     661     1080604 :   RecordPosition(fun->start_position());
     662     1080618 : }
     663             : 
     664             : 
     665     1080615 : 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     1080615 :   RecordStatementPosition(fun->return_position());
     669     1080621 :   if (info_->is_debug()) {
     670             :     // Always emit a debug break slot before a return.
     671        3435 :     DebugCodegen::GenerateSlot(masm_, RelocInfo::DEBUG_BREAK_SLOT_AT_RETURN);
     672             :   }
     673     1080620 : }
     674             : 
     675             : 
     676     5801718 : void FullCodeGenerator::SetStatementPosition(
     677             :     Statement* stmt, FullCodeGenerator::InsertBreak insert_break) {
     678    11603443 :   if (stmt->position() == kNoSourcePosition) return;
     679     5196383 :   RecordStatementPosition(stmt->position());
     680     5206950 :   if (insert_break == INSERT_BREAK && info_->is_debug() &&
     681             :       !stmt->IsDebuggerStatement()) {
     682       10560 :     DebugCodegen::GenerateSlot(masm_, RelocInfo::DEBUG_BREAK_SLOT_AT_POSITION);
     683             :   }
     684             : }
     685             : 
     686     9502935 : void FullCodeGenerator::SetExpressionPosition(Expression* expr) {
     687    23244376 :   if (expr->position() == kNoSourcePosition) return;
     688    12634360 :   RecordPosition(expr->position());
     689             : }
     690             : 
     691             : 
     692       92959 : void FullCodeGenerator::SetExpressionAsStatementPosition(Expression* expr) {
     693      185918 :   if (expr->position() == kNoSourcePosition) return;
     694       88062 :   RecordStatementPosition(expr->position());
     695       88062 :   if (info_->is_debug()) {
     696          74 :     DebugCodegen::GenerateSlot(masm_, RelocInfo::DEBUG_BREAK_SLOT_AT_POSITION);
     697             :   }
     698             : }
     699             : 
     700     1250135 : void FullCodeGenerator::SetCallPosition(Expression* expr,
     701             :                                         TailCallMode tail_call_mode) {
     702     2500271 :   if (expr->position() == kNoSourcePosition) return;
     703     1250140 :   RecordPosition(expr->position());
     704     1250142 :   if (info_->is_debug()) {
     705             :     RelocInfo::Mode mode = (tail_call_mode == TailCallMode::kAllow)
     706             :                                ? RelocInfo::DEBUG_BREAK_SLOT_AT_TAIL_CALL
     707        2959 :                                : RelocInfo::DEBUG_BREAK_SLOT_AT_CALL;
     708             :     // Always emit a debug break slot before a call.
     709        2959 :     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      813522 : void FullCodeGenerator::VisitBinaryOperation(BinaryOperation* expr) {
     735      813522 :   switch (expr->op()) {
     736             :     case Token::COMMA:
     737       23069 :       return VisitComma(expr);
     738             :     case Token::OR:
     739             :     case Token::AND:
     740      147552 :       return VisitLogicalExpression(expr);
     741             :     default:
     742      642901 :       return VisitArithmeticExpression(expr);
     743             :   }
     744             : }
     745             : 
     746             : 
     747      925293 : void FullCodeGenerator::VisitInDuplicateContext(Expression* expr) {
     748      299592 :   if (context()->IsEffect()) {
     749        7511 :     VisitForEffect(expr);
     750      292081 :   } else if (context()->IsAccumulatorValue()) {
     751      169529 :     VisitForAccumulatorValue(expr);
     752      122552 :   } else if (context()->IsStackValue()) {
     753       17018 :     VisitForStackValue(expr);
     754      105534 :   } else if (context()->IsTest()) {
     755      105534 :     const TestContext* test = TestContext::cast(context());
     756             :     VisitForControl(expr, test->true_label(), test->false_label(),
     757      105534 :                     test->fall_through());
     758             :   }
     759      299592 : }
     760             : 
     761             : 
     762       46138 : void FullCodeGenerator::VisitComma(BinaryOperation* expr) {
     763             :   Comment cmnt(masm_, "[ Comma");
     764       23069 :   VisitForEffect(expr->left());
     765       23069 :   VisitInDuplicateContext(expr->right());
     766       23069 : }
     767             : 
     768             : 
     769     1091443 : void FullCodeGenerator::VisitLogicalExpression(BinaryOperation* expr) {
     770      147552 :   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      147552 :   BailoutId right_id = expr->RightId();
     775             :   Label done;
     776             : 
     777      147552 :   if (context()->IsTest()) {
     778             :     Label eval_right;
     779      104673 :     const TestContext* test = TestContext::cast(context());
     780      104673 :     if (is_logical_and) {
     781       39592 :       VisitForControl(left, &eval_right, test->false_label(), &eval_right);
     782             :     } else {
     783       65081 :       VisitForControl(left, test->true_label(), &eval_right, &eval_right);
     784             :     }
     785      104673 :     PrepareForBailoutForId(right_id, BailoutState::NO_REGISTERS);
     786      104673 :     __ bind(&eval_right);
     787             : 
     788       42879 :   } else if (context()->IsAccumulatorValue()) {
     789       38775 :     VisitForAccumulatorValue(left);
     790             :     // We want the value in the accumulator for the test, and on the stack in
     791             :     // case we need it.
     792       77550 :     __ Push(result_register());
     793             :     Label discard, restore;
     794       38775 :     if (is_logical_and) {
     795       22769 :       DoTest(left, &discard, &restore, &restore);
     796             :     } else {
     797       16006 :       DoTest(left, &restore, &discard, &restore);
     798             :     }
     799       38775 :     __ bind(&restore);
     800       77550 :     __ Pop(result_register());
     801       38775 :     __ jmp(&done);
     802       38775 :     __ bind(&discard);
     803       38775 :     __ Drop(1);
     804       38775 :     PrepareForBailoutForId(right_id, BailoutState::NO_REGISTERS);
     805             : 
     806        4104 :   } else if (context()->IsStackValue()) {
     807        4076 :     VisitForAccumulatorValue(left);
     808             :     // We want the value in the accumulator for the test, and on the stack in
     809             :     // case we need it.
     810        8152 :     __ Push(result_register());
     811             :     Label discard;
     812        4076 :     if (is_logical_and) {
     813         188 :       DoTest(left, &discard, &done, &discard);
     814             :     } else {
     815        3888 :       DoTest(left, &done, &discard, &discard);
     816             :     }
     817        4076 :     __ bind(&discard);
     818        4076 :     __ Drop(1);
     819        4076 :     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      147552 :   VisitInDuplicateContext(right);
     834      147552 :   __ bind(&done);
     835      147552 : }
     836             : 
     837             : 
     838     1285802 : 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      642901 :   VisitForStackValue(left);
     845      642901 :   VisitForAccumulatorValue(right);
     846             : 
     847             :   SetExpressionPosition(expr);
     848      642901 :   if (ShouldInlineSmiCase(op)) {
     849      214288 :     EmitInlineSmiBinaryOp(expr, op, left, right);
     850             :   } else {
     851      428613 :     EmitBinaryOp(expr, op);
     852             :   }
     853      642901 : }
     854             : 
     855     7459157 : void FullCodeGenerator::VisitProperty(Property* expr) {
     856             :   Comment cmnt(masm_, "[ Property");
     857             :   SetExpressionPosition(expr);
     858             : 
     859             :   Expression* key = expr->key();
     860             : 
     861     1450845 :   if (key->IsPropertyName()) {
     862             :     DCHECK(!expr->IsSuperAccess());
     863     1245913 :     VisitForAccumulatorValue(expr->obj());
     864     2491826 :     __ Move(LoadDescriptor::ReceiverRegister(), result_register());
     865     1245913 :     EmitNamedPropertyLoad(expr);
     866             :   } else {
     867             :     DCHECK(!expr->IsSuperAccess());
     868      204932 :     VisitForStackValue(expr->obj());
     869      204932 :     VisitForAccumulatorValue(expr->key());
     870      409864 :     __ Move(LoadDescriptor::NameRegister(), result_register());
     871      204932 :     PopOperand(LoadDescriptor::ReceiverRegister());
     872      204932 :     EmitKeyedPropertyLoad(expr);
     873             :   }
     874     1450845 :   PrepareForBailoutForId(expr->LoadId(), BailoutState::TOS_REGISTER);
     875     1450845 :   context()->Plug(result_register());
     876     1450845 : }
     877             : 
     878       84209 : void FullCodeGenerator::VisitForTypeofValue(Expression* expr) {
     879      164888 :   VariableProxy* proxy = expr->AsVariableProxy();
     880             :   DCHECK(!context()->IsEffect());
     881             :   DCHECK(!context()->IsTest());
     882             : 
     883      164888 :   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       83937 :     VisitInDuplicateContext(expr);
     889             :   }
     890       84209 : }
     891             : 
     892             : 
     893     5957024 : void FullCodeGenerator::VisitBlock(Block* stmt) {
     894             :   Comment cmnt(masm_, "[ Block");
     895             :   NestedBlock nested_block(this, stmt);
     896             : 
     897             :   {
     898             :     EnterBlockScopeIfNeeded block_scope_state(
     899     1985675 :         this, stmt->scope(), stmt->EntryId(), stmt->DeclsId(), stmt->ExitId());
     900     1985675 :     VisitStatements(stmt->statements());
     901     1985674 :     __ bind(nested_block.break_label());
     902             :   }
     903     1985675 : }
     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     7976897 : void FullCodeGenerator::VisitExpressionStatement(ExpressionStatement* stmt) {
     915             :   Comment cmnt(masm_, "[ ExpressionStatement");
     916     3988447 :   SetStatementPosition(stmt);
     917     3988450 :   VisitForEffect(stmt->expression());
     918     3988446 : }
     919             : 
     920             : 
     921           8 : void FullCodeGenerator::VisitEmptyStatement(EmptyStatement* stmt) {
     922             :   Comment cmnt(masm_, "[ EmptyStatement");
     923           8 : }
     924             : 
     925             : 
     926     2720509 : void FullCodeGenerator::VisitIfStatement(IfStatement* stmt) {
     927             :   Comment cmnt(masm_, "[ IfStatement");
     928      494672 :   SetStatementPosition(stmt);
     929             :   Label then_part, else_part, done;
     930             : 
     931      494672 :   if (stmt->HasElseStatement()) {
     932       82383 :     VisitForControl(stmt->condition(), &then_part, &else_part, &then_part);
     933       82383 :     PrepareForBailoutForId(stmt->ThenId(), BailoutState::NO_REGISTERS);
     934       82383 :     __ bind(&then_part);
     935       82383 :     Visit(stmt->then_statement());
     936       82383 :     __ jmp(&done);
     937             : 
     938       82383 :     PrepareForBailoutForId(stmt->ElseId(), BailoutState::NO_REGISTERS);
     939       82383 :     __ bind(&else_part);
     940       82383 :     Visit(stmt->else_statement());
     941             :   } else {
     942      412289 :     VisitForControl(stmt->condition(), &then_part, &done, &then_part);
     943      412289 :     PrepareForBailoutForId(stmt->ThenId(), BailoutState::NO_REGISTERS);
     944      412289 :     __ bind(&then_part);
     945      412289 :     Visit(stmt->then_statement());
     946             : 
     947      412289 :     PrepareForBailoutForId(stmt->ElseId(), BailoutState::NO_REGISTERS);
     948             :   }
     949      494672 :   __ bind(&done);
     950      494672 :   PrepareForBailoutForId(stmt->IfId(), BailoutState::NO_REGISTERS);
     951      494672 : }
     952             : 
     953       18877 : void FullCodeGenerator::EmitContinue(Statement* target) {
     954        7610 :   NestedStatement* current = nesting_stack_;
     955        3805 :   int context_length = 0;
     956             :   // When continuing, we clobber the unpredictable value in the accumulator
     957             :   // with one that's safe for GC.
     958        3805 :   ClearAccumulator();
     959       15072 :   while (!current->IsContinueTarget(target)) {
     960        7462 :     if (HasStackOverflow()) return;
     961        7462 :     current = current->Exit(&context_length);
     962             :   }
     963             :   int stack_depth = current->GetStackDepthAtTarget();
     964        3805 :   int stack_drop = operand_stack_depth_ - stack_depth;
     965             :   DCHECK_GE(stack_drop, 0);
     966        3805 :   __ Drop(stack_drop);
     967        3805 :   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        7610 :   __ jmp(current->AsIteration()->continue_label());
     977             : }
     978             : 
     979        7610 : void FullCodeGenerator::VisitContinueStatement(ContinueStatement* stmt) {
     980             :   Comment cmnt(masm_, "[ ContinueStatement");
     981        3805 :   SetStatementPosition(stmt);
     982        3805 :   EmitContinue(stmt->target());
     983        3805 : }
     984             : 
     985      164998 : void FullCodeGenerator::EmitBreak(Statement* target) {
     986       80594 :   NestedStatement* current = nesting_stack_;
     987       40297 :   int context_length = 0;
     988             :   // When breaking, we clobber the unpredictable value in the accumulator
     989             :   // with one that's safe for GC.
     990       40297 :   ClearAccumulator();
     991      124701 :   while (!current->IsBreakTarget(target)) {
     992       44107 :     if (HasStackOverflow()) return;
     993       44107 :     current = current->Exit(&context_length);
     994             :   }
     995             :   int stack_depth = current->GetStackDepthAtTarget();
     996       40297 :   int stack_drop = operand_stack_depth_ - stack_depth;
     997             :   DCHECK_GE(stack_drop, 0);
     998       40297 :   __ Drop(stack_drop);
     999       40297 :   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       80594 :   __ jmp(current->AsBreakable()->break_label());
    1009             : }
    1010             : 
    1011       80594 : void FullCodeGenerator::VisitBreakStatement(BreakStatement* stmt) {
    1012             :   Comment cmnt(masm_, "[ BreakStatement");
    1013       40297 :   SetStatementPosition(stmt);
    1014       40297 :   EmitBreak(stmt->target());
    1015       40297 : }
    1016             : 
    1017     1355463 : void FullCodeGenerator::EmitUnwindAndReturn() {
    1018     1113493 :   NestedStatement* current = nesting_stack_;
    1019     1113493 :   int context_length = 0;
    1020     2468956 :   while (current != NULL) {
    1021      241970 :     if (HasStackOverflow()) return;
    1022      241970 :     current = current->Exit(&context_length);
    1023             :   }
    1024     1113493 :   EmitReturnSequence();
    1025             : }
    1026             : 
    1027     1343927 : void FullCodeGenerator::EmitNewClosure(Handle<SharedFunctionInfo> info,
    1028     8265553 :                                        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     1545920 :   if (!FLAG_always_opt && !FLAG_prepare_always_opt && !pretenure &&
    1037      201993 :       scope()->is_function_scope()) {
    1038       93791 :     Callable callable = CodeFactory::FastNewClosure(isolate());
    1039       93791 :     __ Move(callable.descriptor().GetRegisterParameter(0), info);
    1040       93791 :     __ EmitLoadFeedbackVector(callable.descriptor().GetRegisterParameter(1));
    1041             :     __ Move(callable.descriptor().GetRegisterParameter(2), SmiFromSlot(slot));
    1042       93791 :     __ Call(callable.code(), RelocInfo::CODE_TARGET);
    1043             :   } else {
    1044     1250136 :     __ Push(info);
    1045     2500277 :     __ EmitLoadFeedbackVector(result_register());
    1046     2500277 :     __ Push(result_register());
    1047     1250137 :     __ Push(SmiFromSlot(slot));
    1048             :     __ CallRuntime(pretenure ? Runtime::kNewClosure_Tenured
    1049     2500256 :                              : Runtime::kNewClosure);
    1050             :   }
    1051     1343926 :   context()->Plug(result_register());
    1052     1343928 : }
    1053             : 
    1054     3491153 : void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) {
    1055             :   SetExpressionPosition(prop);
    1056     3491154 :   Literal* key = prop->key()->AsLiteral();
    1057             :   DCHECK(!key->value()->IsSmi());
    1058             :   DCHECK(!prop->IsSuperAccess());
    1059             : 
    1060     1745577 :   CallLoadIC(prop->PropertyFeedbackSlot(), key->value());
    1061     1745577 : }
    1062             : 
    1063      622923 : void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) {
    1064             :   SetExpressionPosition(prop);
    1065             : 
    1066      207641 :   EmitLoadSlot(LoadDescriptor::SlotRegister(), prop->PropertyFeedbackSlot());
    1067             : 
    1068      415282 :   Handle<Code> code = CodeFactory::KeyedLoadIC(isolate()).code();
    1069      207641 :   __ Call(code, RelocInfo::CODE_TARGET);
    1070      207641 :   RestoreContext();
    1071      207641 : }
    1072             : 
    1073     4131263 : 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     2226999 : void FullCodeGenerator::VisitReturnStatement(ReturnStatement* stmt) {
    1083             :   Comment cmnt(masm_, "[ ReturnStatement");
    1084     1113496 :   SetStatementPosition(stmt);
    1085             :   Expression* expr = stmt->expression();
    1086     1113503 :   VisitForAccumulatorValue(expr);
    1087     1113502 :   EmitUnwindAndReturn();
    1088     1113498 : }
    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       89272 : 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       11159 :   __ bind(&loop);
    1142             : 
    1143       11159 :   SetExpressionAsStatementPosition(stmt->cond());
    1144             :   VisitForControl(stmt->cond(),
    1145             :                   &body,
    1146             :                   loop_statement.break_label(),
    1147       11159 :                   &body);
    1148             : 
    1149       11159 :   PrepareForBailoutForId(stmt->BodyId(), BailoutState::NO_REGISTERS);
    1150       11159 :   __ bind(&body);
    1151       11159 :   Visit(stmt->body());
    1152             : 
    1153       11159 :   __ bind(loop_statement.continue_label());
    1154             : 
    1155             :   // Check stack before looping.
    1156       11159 :   EmitBackEdgeBookkeeping(stmt, &loop);
    1157       11159 :   __ jmp(&loop);
    1158             : 
    1159       11159 :   PrepareForBailoutForId(stmt->ExitId(), BailoutState::NO_REGISTERS);
    1160       11159 :   __ bind(loop_statement.break_label());
    1161             :   decrement_loop_depth();
    1162       11159 : }
    1163             : 
    1164             : 
    1165      858561 : void FullCodeGenerator::VisitForStatement(ForStatement* stmt) {
    1166             :   Comment cmnt(masm_, "[ ForStatement");
    1167             :   // Do not insert break location as we do it below.
    1168       79454 :   SetStatementPosition(stmt, SKIP_BREAK);
    1169             : 
    1170             :   Label test, body;
    1171             : 
    1172             :   Iteration loop_statement(this, stmt);
    1173             : 
    1174       79454 :   if (stmt->init() != NULL) {
    1175       59207 :     Visit(stmt->init());
    1176             :   }
    1177             : 
    1178             :   increment_loop_depth();
    1179             :   // Emit the test at the bottom of the loop (even if empty).
    1180       79454 :   __ jmp(&test);
    1181             : 
    1182       79454 :   PrepareForBailoutForId(stmt->BodyId(), BailoutState::NO_REGISTERS);
    1183       79454 :   __ bind(&body);
    1184       79454 :   Visit(stmt->body());
    1185             : 
    1186       79454 :   PrepareForBailoutForId(stmt->ContinueId(), BailoutState::NO_REGISTERS);
    1187       79454 :   __ bind(loop_statement.continue_label());
    1188       79454 :   if (stmt->next() != NULL) {
    1189       64021 :     SetStatementPosition(stmt->next());
    1190       64021 :     Visit(stmt->next());
    1191             :   }
    1192             : 
    1193             :   // Check stack before looping.
    1194       79454 :   EmitBackEdgeBookkeeping(stmt, &body);
    1195             : 
    1196       79454 :   __ bind(&test);
    1197       79454 :   if (stmt->cond() != NULL) {
    1198       73351 :     SetExpressionAsStatementPosition(stmt->cond());
    1199             :     VisitForControl(stmt->cond(),
    1200             :                     &body,
    1201             :                     loop_statement.break_label(),
    1202       73351 :                     loop_statement.break_label());
    1203             :   } else {
    1204        6103 :     __ jmp(&body);
    1205             :   }
    1206             : 
    1207       79454 :   PrepareForBailoutForId(stmt->ExitId(), BailoutState::NO_REGISTERS);
    1208       79454 :   __ bind(loop_statement.break_label());
    1209             :   decrement_loop_depth();
    1210       79454 : }
    1211             : 
    1212             : 
    1213           0 : void FullCodeGenerator::VisitForOfStatement(ForOfStatement* stmt) {
    1214             :   // Iterator looping is not supported.
    1215           0 :   UNREACHABLE();
    1216             : }
    1217             : 
    1218       59054 : void FullCodeGenerator::VisitThisFunction(ThisFunction* expr) {
    1219             :   LoadFromFrameField(JavaScriptFrameConstants::kFunctionOffset,
    1220       29523 :                      result_register());
    1221       29531 :   context()->Plug(result_register());
    1222       29529 : }
    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      272248 : void FullCodeGenerator::VisitConditional(Conditional* expr) {
    1248             :   Comment cmnt(masm_, "[ Conditional");
    1249             :   Label true_case, false_case, done;
    1250       22739 :   VisitForControl(expr->condition(), &true_case, &false_case, &true_case);
    1251             : 
    1252       22739 :   int original_stack_depth = operand_stack_depth_;
    1253       22739 :   PrepareForBailoutForId(expr->ThenId(), BailoutState::NO_REGISTERS);
    1254       22739 :   __ bind(&true_case);
    1255             :   SetExpressionPosition(expr->then_expression());
    1256       22739 :   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       22119 :     VisitInDuplicateContext(expr->then_expression());
    1264       22119 :     __ jmp(&done);
    1265             :   }
    1266             : 
    1267       22739 :   operand_stack_depth_ = original_stack_depth;
    1268       22739 :   PrepareForBailoutForId(expr->ElseId(), BailoutState::NO_REGISTERS);
    1269       22739 :   __ bind(&false_case);
    1270             :   SetExpressionPosition(expr->else_expression());
    1271       22739 :   VisitInDuplicateContext(expr->else_expression());
    1272             :   // If control flow falls through Visit, merge it with true case here.
    1273       22739 :   if (!context()->IsTest()) {
    1274       22119 :     __ bind(&done);
    1275             :   }
    1276       22739 : }
    1277             : 
    1278             : 
    1279     6415696 : void FullCodeGenerator::VisitLiteral(Literal* expr) {
    1280             :   Comment cmnt(masm_, "[ Literal");
    1281     6415696 :   context()->Plug(expr->value());
    1282     3207844 : }
    1283             : 
    1284             : 
    1285     2686840 : 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     2686835 :       Compiler::GetSharedFunctionInfo(expr, script(), info_);
    1291     1343423 :   if (function_info.is_null()) {
    1292             :     SetStackOverflow();
    1293     1343423 :     return;
    1294             :   }
    1295     1343423 :   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      198976 : void FullCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) {
    1305             :   Comment cmnt(masm_, "[ RegExpLiteral");
    1306       24872 :   Callable callable = CodeFactory::FastCloneRegExp(isolate());
    1307             :   CallInterfaceDescriptor descriptor = callable.descriptor();
    1308             :   LoadFromFrameField(JavaScriptFrameConstants::kFunctionOffset,
    1309       24872 :                      descriptor.GetRegisterParameter(0));
    1310             :   __ Move(descriptor.GetRegisterParameter(1),
    1311             :           SmiFromSlot(expr->literal_slot()));
    1312       24872 :   __ Move(descriptor.GetRegisterParameter(2), expr->pattern());
    1313             :   __ Move(descriptor.GetRegisterParameter(3), Smi::FromInt(expr->flags()));
    1314       24872 :   __ 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       24872 :                      context_register());
    1320       24872 :   context()->Plug(result_register());
    1321       24872 : }
    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       49402 : void FullCodeGenerator::VisitThrow(Throw* expr) {
    1333             :   Comment cmnt(masm_, "[ Throw");
    1334       24701 :   VisitForStackValue(expr->exception());
    1335             :   SetExpressionPosition(expr);
    1336       24701 :   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       24701 :   if (context()->IsStackValue()) OperandStackDepthIncrement(1);
    1342       24701 : }
    1343             : 
    1344             : 
    1345     2501100 : 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     1105379 :   Call::CallType call_type = expr->GetCallType();
    1357             : 
    1358             :   // Eval is unsupported.
    1359     1105379 :   CHECK(!expr->is_possibly_eval());
    1360             : 
    1361     1105379 :   switch (call_type) {
    1362             :     case Call::GLOBAL_CALL:
    1363      317635 :       EmitCallWithLoadIC(expr);
    1364      317635 :       break;
    1365             :     case Call::NAMED_PROPERTY_CALL: {
    1366      991098 :       Property* property = callee->AsProperty();
    1367      495549 :       VisitForStackValue(property->obj());
    1368      495549 :       EmitCallWithLoadIC(expr);
    1369      495549 :       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      290334 :       VisitForStackValue(callee);
    1380             :       OperandStackDepthIncrement(1);
    1381      290342 :       __ PushRoot(Heap::kUndefinedValueRootIndex);
    1382             :       // Emit function call.
    1383      290342 :       EmitCall(expr);
    1384      290340 :       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     1105385 : }
    1397             : 
    1398     1046188 : void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
    1399             :   ZoneList<Expression*>* args = expr->arguments();
    1400      303978 :   int arg_count = args->length();
    1401             : 
    1402      303978 :   if (expr->is_jsruntime()) {
    1403             :     Comment cmnt(masm_, "[ CallRuntime");
    1404       20986 :     EmitLoadJSRuntimeFunction(expr);
    1405             : 
    1406             :     // Push the arguments ("left-to-right").
    1407       66349 :     for (int i = 0; i < arg_count; i++) {
    1408       45363 :       VisitForStackValue(args->at(i));
    1409             :     }
    1410             : 
    1411       20986 :     PrepareForBailoutForId(expr->CallId(), BailoutState::NO_REGISTERS);
    1412       20986 :     EmitCallJSRuntimeFunction(expr);
    1413       20986 :     context()->DropAndPlug(1, result_register());
    1414             : 
    1415             :   } else {
    1416             :     const Runtime::Function* function = expr->function();
    1417      282992 :     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        3162 :       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      403477 :         for (int i = 0; i < arg_count; i++) {
    1429      403477 :           VisitForStackValue(args->at(i));
    1430             :         }
    1431             : 
    1432             :         // Call the C runtime function.
    1433      208623 :         PrepareForBailoutForId(expr->CallId(), BailoutState::NO_REGISTERS);
    1434      208623 :         __ CallRuntime(expr->function(), arg_count);
    1435             :         OperandStackDepthDecrement(arg_count);
    1436      208623 :         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      569677 : bool FullCodeGenerator::TryLiteralCompare(CompareOperation* expr) {
    1461             :   Expression* sub_expr;
    1462             :   Literal* literal;
    1463      569677 :   if (expr->IsLiteralCompareTypeof(&sub_expr, &literal)) {
    1464             :     SetExpressionPosition(expr);
    1465             :     EmitLiteralCompareTypeof(expr, sub_expr,
    1466      117146 :                              Handle<String>::cast(literal->value()));
    1467       58573 :     return true;
    1468             :   }
    1469             : 
    1470      511103 :   if (expr->IsLiteralCompareUndefined(&sub_expr)) {
    1471             :     SetExpressionPosition(expr);
    1472       40694 :     EmitLiteralCompareNil(expr, sub_expr, kUndefinedValue);
    1473       40694 :     return true;
    1474             :   }
    1475             : 
    1476      470409 :   if (expr->IsLiteralCompareNull(&sub_expr)) {
    1477             :     SetExpressionPosition(expr);
    1478       21918 :     EmitLiteralCompareNil(expr, sub_expr, kNullValue);
    1479       21918 :     return true;
    1480             :   }
    1481             : 
    1482             :   return false;
    1483             : }
    1484             : 
    1485             : 
    1486       10638 : 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       10638 :   int loop_nesting_level = unoptimized->allow_osr_at_loop_nesting_level() + 1;
    1494       21276 :   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       19182 :     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        4831 :       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        2641 : 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        7774 :   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        4824 :       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        2641 : }
    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     1985675 : FullCodeGenerator::EnterBlockScopeIfNeeded::EnterBlockScopeIfNeeded(
    1555       45958 :     FullCodeGenerator* codegen, Scope* scope, BailoutId entry_id,
    1556             :     BailoutId declarations_id, BailoutId exit_id)
    1557     1985675 :     : codegen_(codegen), exit_id_(exit_id) {
    1558     1985675 :   saved_scope_ = codegen_->scope();
    1559             : 
    1560     1985675 :   if (scope == NULL) {
    1561     1939717 :     codegen_->PrepareForBailoutForId(entry_id, BailoutState::NO_REGISTERS);
    1562     1939717 :     needs_block_context_ = false;
    1563             :   } else {
    1564       45958 :     needs_block_context_ = scope->NeedsContext();
    1565       45958 :     codegen_->scope_ = scope;
    1566             :     {
    1567       45958 :       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       45958 :       CHECK_EQ(0, scope->num_stack_slots());
    1578       45958 :       codegen_->PrepareForBailoutForId(entry_id, BailoutState::NO_REGISTERS);
    1579             :     }
    1580             :     {
    1581             :       Comment cmnt(masm(), "[ Declarations");
    1582       45958 :       codegen_->VisitDeclarations(scope->declarations());
    1583             :       codegen_->PrepareForBailoutForId(declarations_id,
    1584       45958 :                                        BailoutState::NO_REGISTERS);
    1585             :     }
    1586             :   }
    1587     1985675 : }
    1588             : 
    1589             : 
    1590     1985674 : FullCodeGenerator::EnterBlockScopeIfNeeded::~EnterBlockScopeIfNeeded() {
    1591     1985674 :   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     1985674 :   codegen_->PrepareForBailoutForId(exit_id_, BailoutState::NO_REGISTERS);
    1599     1985674 :   codegen_->scope_ = saved_scope_;
    1600     1985674 : }
    1601             : 
    1602     1429748 : Handle<Script> FullCodeGenerator::script() { return info_->script(); }
    1603             : 
    1604     1201322 : LanguageMode FullCodeGenerator::language_mode() {
    1605       27945 :   return scope()->language_mode();
    1606             : }
    1607             : 
    1608        1402 : bool FullCodeGenerator::has_simple_parameters() {
    1609        1402 :   return info_->has_simple_parameters();
    1610             : }
    1611             : 
    1612     3243216 : 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