1b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Copyright 2013 the V8 project authors. All rights reserved.
2b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// found in the LICENSE file.
4b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/compiler/code-generator.h"
6b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
7014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/address-map.h"
8f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch#include "src/base/adapters.h"
9f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch#include "src/compilation-info.h"
10b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/compiler/code-generator-impl.h"
11b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/compiler/linkage.h"
12b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/compiler/pipeline.h"
13014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/frames-inl.h"
14b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
15b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace v8 {
16b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace internal {
17b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace compiler {
18b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
19014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass CodeGenerator::JumpTable final : public ZoneObject {
20014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch public:
21014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  JumpTable(JumpTable* next, Label** targets, size_t target_count)
22014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      : next_(next), targets_(targets), target_count_(target_count) {}
23014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
24014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Label* label() { return &label_; }
25014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  JumpTable* next() const { return next_; }
26014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Label** targets() const { return targets_; }
27014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  size_t target_count() const { return target_count_; }
28014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
29014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch private:
30014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Label label_;
31014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  JumpTable* const next_;
32014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Label** const targets_;
33014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  size_t const target_count_;
34014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch};
35014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
36958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierCodeGenerator::CodeGenerator(Frame* frame, Linkage* linkage,
37958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                             InstructionSequence* code, CompilationInfo* info)
38bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    : frame_access_state_(nullptr),
39958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      linkage_(linkage),
40958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      code_(code),
41f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      unwinding_info_writer_(zone()),
42958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      info_(info),
43958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      labels_(zone()->NewArray<Label>(code->InstructionBlockCount())),
44014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      current_block_(RpoNumber::Invalid()),
45014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      current_source_position_(SourcePosition::Unknown()),
46f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      masm_(info->isolate(), nullptr, 0, CodeObjectRequired::kNo),
47b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      resolver_(this),
48b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      safepoints_(code->zone()),
49014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      handlers_(code->zone()),
503b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      deoptimization_exits_(code->zone()),
51b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      deoptimization_states_(code->zone()),
52b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      deoptimization_literals_(code->zone()),
53014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      inlined_function_count_(0),
54b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      translations_(code->zone()),
55958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      last_lazy_deopt_pc_(0),
56014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      jump_tables_(nullptr),
57014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      ools_(nullptr),
58f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      osr_pc_offset_(-1),
5962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      optimized_out_literal_id_(-1),
60f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      source_position_table_builder_(code->zone(),
61f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                     info->SourcePositionRecordingMode()) {
62958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  for (int i = 0; i < code->InstructionBlockCount(); ++i) {
63958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    new (&labels_[i]) Label;
64958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
65bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  CreateFrameAccessState(frame);
66bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch}
67bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
68f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben MurdochIsolate* CodeGenerator::isolate() const { return info_->isolate(); }
69f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
70bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochvoid CodeGenerator::CreateFrameAccessState(Frame* frame) {
71bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  FinishFrame(frame);
72bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  frame_access_state_ = new (code()->zone()) FrameAccessState(frame);
73958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
74b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
7562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
76b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHandle<Code> CodeGenerator::GenerateCode() {
77958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  CompilationInfo* info = this->info();
78b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
79014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Open a frame scope to indicate that there is a frame on the stack.  The
80014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // MANUAL indicates that the scope shouldn't actually generate code to set up
81014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // the frame (that is done in AssemblePrologue).
82014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  FrameScope frame_scope(masm(), StackFrame::MANUAL);
83014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
8462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  if (info->is_source_positions_enabled()) {
8562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    SourcePosition source_position(info->shared_info()->start_position());
8662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    AssembleSourcePosition(source_position);
8762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
8862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
89b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Place function entry hook if requested to do so.
90b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (linkage()->GetIncomingDescriptor()->IsJSFunctionCall()) {
91b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ProfileEntryHookStub::MaybeCallEntryHook(masm());
92b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
93b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Architecture-specific, linkage-specific prologue.
94b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  info->set_prologue_offset(masm()->pc_offset());
95b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
96014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Define deoptimization literals for all inlined functions.
97014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK_EQ(0u, deoptimization_literals_.size());
98c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  for (CompilationInfo::InlinedFunctionHolder& inlined :
993b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch       info->inlined_functions()) {
100014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (!inlined.shared_info.is_identical_to(info->shared_info())) {
101c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      int index = DefineDeoptimizationLiteral(inlined.shared_info);
102c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      inlined.RegisterInlinedFunctionId(index);
103014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
104014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
105014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  inlined_function_count_ = deoptimization_literals_.size();
106014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
107014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Define deoptimization literals for all unoptimized code objects of inlined
108014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // functions. This ensures unoptimized code is kept alive by optimized code.
1093b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  for (const CompilationInfo::InlinedFunctionHolder& inlined :
1103b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch       info->inlined_functions()) {
111014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (!inlined.shared_info.is_identical_to(info->shared_info())) {
112014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      DefineDeoptimizationLiteral(inlined.inlined_code_object_root);
113014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
114014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
115014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
116f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  unwinding_info_writer_.SetNumberOfInstructionBlocks(
117f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      code()->InstructionBlockCount());
118f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
119958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // Assemble all non-deferred blocks, followed by deferred ones.
120958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  for (int deferred = 0; deferred < 2; ++deferred) {
1213b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    for (const InstructionBlock* block : code()->instruction_blocks()) {
122958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      if (block->IsDeferred() == (deferred == 0)) {
123958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        continue;
124958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      }
125958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      // Align loop headers on 16-byte boundaries.
126958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      if (block->IsLoopHeader()) masm()->Align(16);
127014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // Ensure lazy deopt doesn't patch handler entry points.
128014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (block->IsHandler()) EnsureSpaceForLazyDeopt();
129958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      // Bind a label for a block.
130958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      current_block_ = block->rpo_number();
131f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      unwinding_info_writer_.BeginInstructionBlock(masm()->pc_offset(), block);
132958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      if (FLAG_code_comments) {
133958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        // TODO(titzer): these code comments are a giant memory leak.
134014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        Vector<char> buffer = Vector<char>::New(200);
135014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        char* buffer_start = buffer.start();
136014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
137014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        int next = SNPrintF(
138014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            buffer, "-- B%d start%s%s%s%s", block->rpo_number().ToInt(),
139014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            block->IsDeferred() ? " (deferred)" : "",
140014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            block->needs_frame() ? "" : " (no frame)",
141014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            block->must_construct_frame() ? " (construct frame)" : "",
142014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            block->must_deconstruct_frame() ? " (deconstruct frame)" : "");
143014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
144014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        buffer = buffer.SubVector(next, buffer.length());
145014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
146014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        if (block->IsLoopHeader()) {
147014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          next =
148014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              SNPrintF(buffer, " (loop up to %d)", block->loop_end().ToInt());
149014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          buffer = buffer.SubVector(next, buffer.length());
150014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        }
151014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        if (block->loop_header().IsValid()) {
152014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          next =
153014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              SNPrintF(buffer, " (in loop %d)", block->loop_header().ToInt());
154014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          buffer = buffer.SubVector(next, buffer.length());
155014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        }
156014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        SNPrintF(buffer, " --");
157014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        masm()->RecordComment(buffer_start);
158958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      }
1593b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
1603b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      frame_access_state()->MarkHasFrame(block->needs_frame());
1613b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
162958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      masm()->bind(GetLabel(current_block_));
1633b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      if (block->must_construct_frame()) {
164bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch        AssembleConstructFrame();
1653b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        // We need to setup the root register after we assemble the prologue, to
1663b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        // avoid clobbering callee saved registers in case of C linkage and
1673b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        // using the roots.
1683b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        // TODO(mtrofin): investigate how we can avoid doing this repeatedly.
1693b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        if (linkage()->GetIncomingDescriptor()->InitializeRootRegister()) {
1703b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch          masm()->InitializeRootRegister();
1713b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        }
1723b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      }
1733b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
174bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      CodeGenResult result;
1753b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      if (FLAG_enable_embedded_constant_pool && !block->needs_frame()) {
1763b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        ConstantPoolUnavailableScope constant_pool_unavailable(masm());
177bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch        result = AssembleBlock(block);
1783b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      } else {
179bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch        result = AssembleBlock(block);
180958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      }
181bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      if (result != kSuccess) return Handle<Code>();
182f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      unwinding_info_writer_.EndInstructionBlock(block);
183958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }
184958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
185958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
186958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // Assemble all out-of-line code.
187958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (ools_) {
188958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    masm()->RecordComment("-- Out of line code --");
189958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    for (OutOfLineCode* ool = ools_; ool; ool = ool->next()) {
190958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      masm()->bind(ool->entry());
191958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      ool->Generate();
192014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (ool->exit()->is_bound()) masm()->jmp(ool->exit());
193958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }
194b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
195b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1963b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // Assemble all eager deoptimization exits.
1973b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  for (DeoptimizationExit* exit : deoptimization_exits_) {
1983b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    masm()->bind(exit->label());
19962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    AssembleDeoptimizerCall(exit->deoptimization_id(), exit->pos());
2003b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  }
2013b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
202958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // Ensure there is space for lazy deoptimization in the code.
203014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (info->ShouldEnsureSpaceForLazyDeopt()) {
204b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    int target_offset = masm()->pc_offset() + Deoptimizer::patch_size();
205b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    while (masm()->pc_offset() < target_offset) {
206b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      masm()->nop();
207b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
208b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
209b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
210014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  FinishCode(masm());
211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
212014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Emit the jump tables.
213014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (jump_tables_) {
214014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    masm()->Align(kPointerSize);
215014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    for (JumpTable* table = jump_tables_; table; table = table->next()) {
216014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      masm()->bind(table->label());
217014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      AssembleJumpTable(table->targets(), table->target_count());
218014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
219b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
220014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
221109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  safepoints()->Emit(masm(), frame()->GetTotalFrameSlotCount());
222014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
223f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  unwinding_info_writer_.Finish(masm()->pc_offset());
224f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
225f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Handle<Code> result = v8::internal::CodeGenerator::MakeCodeEpilogue(
226f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      masm(), unwinding_info_writer_.eh_frame_writer(), info, Handle<Object>());
227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  result->set_is_turbofanned(true);
228109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  result->set_stack_slots(frame()->GetTotalFrameSlotCount());
229b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  result->set_safepoint_table_offset(safepoints()->GetCodeOffset());
230f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Handle<ByteArray> source_positions =
231f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      source_position_table_builder_.ToSourcePositionTable(
232f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch          isolate(), Handle<AbstractCode>::cast(result));
233f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  result->set_source_position_table(*source_positions);
234b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
235014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Emit exception handler table.
236014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (!handlers_.empty()) {
237014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Handle<HandlerTable> table =
238014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        Handle<HandlerTable>::cast(isolate()->factory()->NewFixedArray(
239014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            HandlerTable::LengthForReturn(static_cast<int>(handlers_.size())),
240014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            TENURED));
241014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    for (size_t i = 0; i < handlers_.size(); ++i) {
242014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      table->SetReturnOffset(static_cast<int>(i), handlers_[i].pc_offset);
243f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      table->SetReturnHandler(static_cast<int>(i), handlers_[i].handler->pos());
244014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
245014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    result->set_handler_table(*table);
246014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
247014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
248b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  PopulateDeoptimizationData(result);
249b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
250958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // Ensure there is space for lazy deoptimization in the relocation info.
251014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (info->ShouldEnsureSpaceForLazyDeopt()) {
252958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    Deoptimizer::EnsureRelocSpaceForLazyDeoptimization(result);
253958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
254958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
255b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return result;
256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
257b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
258b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
259014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochbool CodeGenerator::IsNextInAssemblyOrder(RpoNumber block) const {
260014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return code()
261014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      ->InstructionBlockAt(current_block_)
262014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      ->ao_number()
263014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      .IsNext(code()->InstructionBlockAt(block)->ao_number());
264958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
265958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
266958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
267014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid CodeGenerator::RecordSafepoint(ReferenceMap* references,
268014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                    Safepoint::Kind kind, int arguments,
269b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                    Safepoint::DeoptMode deopt_mode) {
270b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Safepoint safepoint =
271b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      safepoints()->DefineSafepoint(masm(), kind, arguments, deopt_mode);
272014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int stackSlotToSpillSlotDelta =
273014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      frame()->GetTotalFrameSlotCount() - frame()->GetSpillSlotCount();
2743b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  for (const InstructionOperand& operand : references->reference_operands()) {
275014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (operand.IsStackSlot()) {
276014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int index = LocationOperand::cast(operand).index();
277014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      DCHECK(index >= 0);
278109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      // We might index values in the fixed part of the frame (i.e. the
279109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      // closure pointer or the context pointer); these are not spill slots
280109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      // and therefore don't work with the SafepointTable currently, but
281109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      // we also don't need to worry about them, since the GC has special
282109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      // knowledge about those fields anyway.
283109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      if (index < stackSlotToSpillSlotDelta) continue;
284014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      safepoint.DefinePointerSlot(index, zone());
285014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    } else if (operand.IsRegister() && (kind & Safepoint::kWithRegisters)) {
286014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Register reg = LocationOperand::cast(operand).GetRegister();
287b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      safepoint.DefinePointerRegister(reg, zone());
288b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
289b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
290b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
291b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
292014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochbool CodeGenerator::IsMaterializableFromRoot(
293014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Handle<HeapObject> object, Heap::RootListIndex* index_return) {
294014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const CallDescriptor* incoming_descriptor =
295014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      linkage()->GetIncomingDescriptor();
296014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (incoming_descriptor->flags() & CallDescriptor::kCanUseRoots) {
297014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    RootIndexMap map(isolate());
298014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    int root_index = map.Lookup(*object);
299014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (root_index != RootIndexMap::kInvalidRootIndex) {
300014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      *index_return = static_cast<Heap::RootListIndex>(root_index);
301014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return true;
302014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
303014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
304014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return false;
305014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
306014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
307bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben MurdochCodeGenerator::CodeGenResult CodeGenerator::AssembleBlock(
308bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    const InstructionBlock* block) {
3093b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  for (int i = block->code_start(); i < block->code_end(); ++i) {
3103b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    Instruction* instr = code()->InstructionAt(i);
311bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    CodeGenResult result = AssembleInstruction(instr, block);
312bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    if (result != kSuccess) return result;
3133b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  }
314bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  return kSuccess;
3153b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch}
316014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
317f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochbool CodeGenerator::IsValidPush(InstructionOperand source,
318f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                CodeGenerator::PushTypeFlags push_type) {
319f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  if (source.IsImmediate() &&
320f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      ((push_type & CodeGenerator::kImmediatePush) != 0)) {
321f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return true;
322f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
323f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  if ((source.IsRegister() || source.IsStackSlot()) &&
324f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      ((push_type & CodeGenerator::kScalarPush) != 0)) {
325f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return true;
326f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
327f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  if ((source.IsFloatRegister() || source.IsFloatStackSlot()) &&
328f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      ((push_type & CodeGenerator::kFloat32Push) != 0)) {
329f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return true;
330f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
331f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  if ((source.IsDoubleRegister() || source.IsFloatStackSlot()) &&
332f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      ((push_type & CodeGenerator::kFloat64Push) != 0)) {
333f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return true;
334f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
335f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  return false;
336f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
337f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
338f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid CodeGenerator::GetPushCompatibleMoves(Instruction* instr,
339f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                           PushTypeFlags push_type,
340f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                           ZoneVector<MoveOperands*>* pushes) {
341f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  pushes->clear();
342f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  for (int i = Instruction::FIRST_GAP_POSITION;
343f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch       i <= Instruction::LAST_GAP_POSITION; ++i) {
344f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    Instruction::GapPosition inner_pos =
345f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        static_cast<Instruction::GapPosition>(i);
346f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    ParallelMove* parallel_move = instr->GetParallelMove(inner_pos);
347f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    if (parallel_move != nullptr) {
348f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      for (auto move : *parallel_move) {
349f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        InstructionOperand source = move->source();
350f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        InstructionOperand destination = move->destination();
351f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        int first_push_compatible_index =
352f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch            V8_TARGET_ARCH_STORES_RETURN_ADDRESS_ON_STACK ? 1 : 0;
353f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        // If there are any moves from slots that will be overridden by pushes,
354f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        // then the full gap resolver must be used since optimization with
355f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        // pushes don't participate in the parallel move and might clobber
356f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        // values needed for the gap resolve.
357f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        if (source.IsStackSlot() &&
358f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch            LocationOperand::cast(source).index() >=
359f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                first_push_compatible_index) {
360f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch          pushes->clear();
361f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch          return;
362f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        }
363f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        // TODO(danno): Right now, only consider moves from the FIRST gap for
364f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        // pushes. Theoretically, we could extract pushes for both gaps (there
365f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        // are cases where this happens), but the logic for that would also have
366f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        // to check to make sure that non-memory inputs to the pushes from the
367f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        // LAST gap don't get clobbered in the FIRST gap.
368f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        if (i == Instruction::FIRST_GAP_POSITION) {
369f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch          if (destination.IsStackSlot() &&
370f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch              LocationOperand::cast(destination).index() >=
371f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                  first_push_compatible_index) {
372f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch            int index = LocationOperand::cast(destination).index();
373f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch            if (IsValidPush(source, push_type)) {
374f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch              if (index >= static_cast<int>(pushes->size())) {
375f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                pushes->resize(index + 1);
376f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch              }
377f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch              (*pushes)[index] = move;
378f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch            }
379f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch          }
380f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        }
381f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      }
382f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    }
383f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
384f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
385f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // For now, only support a set of continuous pushes at the end of the list.
386f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  size_t push_count_upper_bound = pushes->size();
387f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  size_t push_begin = push_count_upper_bound;
388f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  for (auto move : base::Reversed(*pushes)) {
389f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    if (move == nullptr) break;
390f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    push_begin--;
391f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
392f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  size_t push_count = pushes->size() - push_begin;
393f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  std::copy(pushes->begin() + push_begin,
394f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch            pushes->begin() + push_begin + push_count, pushes->begin());
395f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  pushes->resize(push_count);
396f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
397f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
398bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben MurdochCodeGenerator::CodeGenResult CodeGenerator::AssembleInstruction(
399bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    Instruction* instr, const InstructionBlock* block) {
400f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  int first_unused_stack_slot;
40162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  FlagsMode mode = FlagsModeField::decode(instr->opcode());
40262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  if (mode != kFlags_trap) {
40362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    AssembleSourcePosition(instr);
40462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
405f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  bool adjust_stack =
406f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      GetSlotAboveSPBeforeTailCall(instr, &first_unused_stack_slot);
407f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  if (adjust_stack) AssembleTailCallBeforeGap(instr, first_unused_stack_slot);
408014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  AssembleGaps(instr);
409f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  if (adjust_stack) AssembleTailCallAfterGap(instr, first_unused_stack_slot);
4103b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  DCHECK_IMPLIES(
4113b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      block->must_deconstruct_frame(),
4123b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      instr != code()->InstructionAt(block->last_instruction_index()) ||
4133b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch          instr->IsRet() || instr->IsJump());
4143b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  if (instr->IsJump() && block->must_deconstruct_frame()) {
4153b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    AssembleDeconstructFrame();
4163b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  }
417014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Assemble architecture-specific code for the instruction.
418bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  CodeGenResult result = AssembleArchInstruction(instr);
419bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  if (result != kSuccess) return result;
420014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
421014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  FlagsCondition condition = FlagsConditionField::decode(instr->opcode());
4223b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  switch (mode) {
4233b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    case kFlags_branch: {
4243b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      // Assemble a branch after this instruction.
4253b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      InstructionOperandConverter i(this, instr);
4263b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      RpoNumber true_rpo = i.InputRpo(instr->InputCount() - 2);
4273b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      RpoNumber false_rpo = i.InputRpo(instr->InputCount() - 1);
4283b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
4293b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      if (true_rpo == false_rpo) {
4303b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        // redundant branch.
4313b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        if (!IsNextInAssemblyOrder(true_rpo)) {
4323b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch          AssembleArchJump(true_rpo);
4333b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        }
434bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch        return kSuccess;
435958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      }
4363b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      if (IsNextInAssemblyOrder(true_rpo)) {
4373b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        // true block is next, can fall through if condition negated.
4383b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        std::swap(true_rpo, false_rpo);
4393b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        condition = NegateFlagsCondition(condition);
4403b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      }
4413b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      BranchInfo branch;
4423b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      branch.condition = condition;
4433b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      branch.true_label = GetLabel(true_rpo);
4443b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      branch.false_label = GetLabel(false_rpo);
4453b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      branch.fallthru = IsNextInAssemblyOrder(false_rpo);
4463b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      // Assemble architecture-specific branch.
4473b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      AssembleArchBranch(instr, &branch);
4483b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      break;
4493b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    }
4503b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    case kFlags_deoptimize: {
4513b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      // Assemble a conditional eager deoptimization after this instruction.
4523b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      InstructionOperandConverter i(this, instr);
4533b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      size_t frame_state_offset = MiscField::decode(instr->opcode());
4543b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      DeoptimizationExit* const exit =
4553b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch          AddDeoptimizationExit(instr, frame_state_offset);
4563b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      Label continue_label;
4573b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      BranchInfo branch;
4583b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      branch.condition = condition;
4593b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      branch.true_label = exit->label();
4603b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      branch.false_label = &continue_label;
4613b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      branch.fallthru = true;
4623b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      // Assemble architecture-specific branch.
4633b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      AssembleArchBranch(instr, &branch);
4643b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      masm()->bind(&continue_label);
4653b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      break;
4663b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    }
4673b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    case kFlags_set: {
4683b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      // Assemble a boolean materialization after this instruction.
4693b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      AssembleArchBoolean(instr, condition);
4703b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      break;
471014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
47262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    case kFlags_trap: {
47362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      AssembleArchTrap(instr, condition);
47462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      break;
47562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    }
4763b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    case kFlags_none: {
4773b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      break;
478b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
479b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
480bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  return kSuccess;
481b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
482b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
483014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid CodeGenerator::AssembleSourcePosition(Instruction* instr) {
484c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  SourcePosition source_position = SourcePosition::Unknown();
48562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  if (instr->IsNop() && instr->AreMovesRedundant()) return;
486014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (!code()->GetSourcePosition(instr, &source_position)) return;
48762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  AssembleSourcePosition(source_position);
48862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}
48962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
49062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochvoid CodeGenerator::AssembleSourcePosition(SourcePosition source_position) {
491b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (source_position == current_source_position_) return;
492014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  current_source_position_ = source_position;
493c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  if (!source_position.IsKnown()) return;
494c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  source_position_table_builder_.AddPosition(masm()->pc_offset(),
495c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch                                             source_position, false);
496014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (FLAG_code_comments) {
497014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    CompilationInfo* info = this->info();
49813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    if (!info->parse_info()) return;
499c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    std::ostringstream buffer;
50062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    buffer << "-- ";
50162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    if (FLAG_trace_turbo) {
50262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      buffer << source_position;
50362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    } else {
50462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      buffer << source_position.InliningStack(info);
50562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    }
50662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    buffer << " --";
507c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    masm()->RecordComment(StrDup(buffer.str().c_str()));
508b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
509b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
510b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
511f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochbool CodeGenerator::GetSlotAboveSPBeforeTailCall(Instruction* instr,
512f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                                 int* slot) {
513f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  if (instr->IsTailCall()) {
514f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    InstructionOperandConverter g(this, instr);
515f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    *slot = g.InputInt32(instr->InputCount() - 1);
516f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return true;
517f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  } else {
518f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return false;
519f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
520f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
521b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
522014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid CodeGenerator::AssembleGaps(Instruction* instr) {
523014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (int i = Instruction::FIRST_GAP_POSITION;
524014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch       i <= Instruction::LAST_GAP_POSITION; i++) {
525014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Instruction::GapPosition inner_pos =
526014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        static_cast<Instruction::GapPosition>(i);
527b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ParallelMove* move = instr->GetParallelMove(inner_pos);
528014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (move != nullptr) resolver()->Resolve(move);
529b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
530b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
531b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
532c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdochnamespace {
533c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch
534c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen MurdochHandle<PodArray<InliningPosition>> CreateInliningPositions(
535c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    CompilationInfo* info) {
536c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  const CompilationInfo::InlinedFunctionList& inlined_functions =
537c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      info->inlined_functions();
538c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  if (inlined_functions.size() == 0) {
539c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    return Handle<PodArray<InliningPosition>>::cast(
540c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        info->isolate()->factory()->empty_byte_array());
541c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  }
542c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  Handle<PodArray<InliningPosition>> inl_positions =
543c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      PodArray<InliningPosition>::New(
544c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch          info->isolate(), static_cast<int>(inlined_functions.size()), TENURED);
545c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  for (size_t i = 0; i < inlined_functions.size(); ++i) {
546c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    inl_positions->set(static_cast<int>(i), inlined_functions[i].position);
547c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  }
548c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  return inl_positions;
549c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch}
550c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch
551c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch}  // namespace
552b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
553b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid CodeGenerator::PopulateDeoptimizationData(Handle<Code> code_object) {
554958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  CompilationInfo* info = this->info();
555b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int deopt_count = static_cast<int>(deoptimization_states_.size());
556014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (deopt_count == 0 && !info->is_osr()) return;
557b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Handle<DeoptimizationInputData> data =
558b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      DeoptimizationInputData::New(isolate(), deopt_count, TENURED);
559b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
560b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Handle<ByteArray> translation_array =
561b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      translations_.CreateByteArray(isolate()->factory());
562b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
563b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  data->SetTranslationByteArray(*translation_array);
564014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  data->SetInlinedFunctionCount(
565014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Smi::FromInt(static_cast<int>(inlined_function_count_)));
566b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  data->SetOptimizationId(Smi::FromInt(info->optimization_id()));
567014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
568014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (info->has_shared_info()) {
569b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    data->SetSharedFunctionInfo(*info->shared_info());
570b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
571c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    data->SetSharedFunctionInfo(Smi::kZero);
572b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
573b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
574b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Handle<FixedArray> literals = isolate()->factory()->NewFixedArray(
575b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      static_cast<int>(deoptimization_literals_.size()), TENURED);
576b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  {
577b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    AllowDeferredHandleDereference copy_handles;
578b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (unsigned i = 0; i < deoptimization_literals_.size(); i++) {
579b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      literals->set(i, *deoptimization_literals_[i]);
580b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
581b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    data->SetLiteralArray(*literals);
582b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
583b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
584c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  Handle<PodArray<InliningPosition>> inl_pos = CreateInliningPositions(info);
585c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  data->SetInliningPositions(*inl_pos);
586c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch
587014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (info->is_osr()) {
588014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(osr_pc_offset_ >= 0);
589014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    data->SetOsrAstId(Smi::FromInt(info_->osr_ast_id().ToInt()));
590014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    data->SetOsrPcOffset(Smi::FromInt(osr_pc_offset_));
591014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
592014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    BailoutId osr_ast_id = BailoutId::None();
593014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    data->SetOsrAstId(Smi::FromInt(osr_ast_id.ToInt()));
594014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    data->SetOsrPcOffset(Smi::FromInt(-1));
595014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
596b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
597b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Populate deoptimization entries.
598b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (int i = 0; i < deopt_count; i++) {
599b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DeoptimizationState* deoptimization_state = deoptimization_states_[i];
600b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    data->SetAstId(i, deoptimization_state->bailout_id());
601014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    CHECK(deoptimization_states_[i]);
602b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    data->SetTranslationIndex(
603b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        i, Smi::FromInt(deoptimization_states_[i]->translation_id()));
604c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    data->SetArgumentsStackHeight(i, Smi::kZero);
605b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    data->SetPc(i, Smi::FromInt(deoptimization_state->pc_offset()));
606b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
607b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
608b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  code_object->set_deoptimization_data(*data);
609b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
610b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
611b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
612014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochLabel* CodeGenerator::AddJumpTable(Label** targets, size_t target_count) {
613014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  jump_tables_ = new (zone()) JumpTable(jump_tables_, targets, target_count);
614014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return jump_tables_->label();
615014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
616014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
617014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
618014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid CodeGenerator::RecordCallPosition(Instruction* instr) {
619b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CallDescriptor::Flags flags(MiscField::decode(instr->opcode()));
620b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
621b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool needs_frame_state = (flags & CallDescriptor::kNeedsFrameState);
622b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
623b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  RecordSafepoint(
624014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      instr->reference_map(), Safepoint::kSimple, 0,
625b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      needs_frame_state ? Safepoint::kLazyDeopt : Safepoint::kNoLazyDeopt);
626b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
627014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (flags & CallDescriptor::kHasExceptionHandler) {
628014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    InstructionOperandConverter i(this, instr);
629014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    RpoNumber handler_rpo = i.InputRpo(instr->InputCount() - 1);
630f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    handlers_.push_back({GetLabel(handler_rpo), masm()->pc_offset()});
631014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
632014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
633b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (needs_frame_state) {
634b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    MarkLazyDeoptSite();
635014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // If the frame state is present, it starts at argument 1 (just after the
636014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // code address).
637b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    size_t frame_state_offset = 1;
638b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    FrameStateDescriptor* descriptor =
639f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        GetDeoptimizationEntry(instr, frame_state_offset).descriptor();
640b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    int pc_offset = masm()->pc_offset();
641b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    int deopt_state_id = BuildTranslation(instr, pc_offset, frame_state_offset,
642b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                          descriptor->state_combine());
643b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // If the pre-call frame state differs from the post-call one, produce the
644b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // pre-call frame state, too.
645b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // TODO(jarin) We might want to avoid building the pre-call frame state
646b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // because it is only used to get locals and arguments (by the debugger and
647b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // f.arguments), and those are the same in the pre-call and post-call
648b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // states.
649958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    if (!descriptor->state_combine().IsOutputIgnored()) {
650958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      deopt_state_id = BuildTranslation(instr, -1, frame_state_offset,
651958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                                        OutputFrameStateCombine::Ignore());
652b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
653b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    safepoints()->RecordLazyDeoptimizationIndex(deopt_state_id);
654b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
655b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
656b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
657b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
658b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochint CodeGenerator::DefineDeoptimizationLiteral(Handle<Object> literal) {
659b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int result = static_cast<int>(deoptimization_literals_.size());
660b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (unsigned i = 0; i < deoptimization_literals_.size(); ++i) {
661b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (deoptimization_literals_[i].is_identical_to(literal)) return i;
662b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
663b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  deoptimization_literals_.push_back(literal);
664b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return result;
665b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
666b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
667f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochDeoptimizationEntry const& CodeGenerator::GetDeoptimizationEntry(
668b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Instruction* instr, size_t frame_state_offset) {
669b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  InstructionOperandConverter i(this, instr);
670f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  int const state_id = i.InputInt32(frame_state_offset);
671f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  return code()->GetDeoptimizationEntry(state_id);
672b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
673b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
67462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochDeoptimizeKind CodeGenerator::GetDeoptimizationKind(
67562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    int deoptimization_id) const {
67662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  size_t const index = static_cast<size_t>(deoptimization_id);
67762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  DCHECK_LT(index, deoptimization_states_.size());
67862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  return deoptimization_states_[index]->kind();
67962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}
68062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
681f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochDeoptimizeReason CodeGenerator::GetDeoptimizationReason(
682f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    int deoptimization_id) const {
683f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  size_t const index = static_cast<size_t>(deoptimization_id);
684f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  DCHECK_LT(index, deoptimization_states_.size());
685f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  return deoptimization_states_[index]->reason();
686f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
687958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
688014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid CodeGenerator::TranslateStateValueDescriptor(
68962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    StateValueDescriptor* desc, StateValueList* nested,
69062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Translation* translation, InstructionOperandIterator* iter) {
69162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // Note:
69262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // If translation is null, we just skip the relevant instruction operands.
693014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (desc->IsNested()) {
69462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    if (translation != nullptr) {
69562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      translation->BeginCapturedObject(static_cast<int>(nested->size()));
69662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    }
69762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    for (auto field : *nested) {
69862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      TranslateStateValueDescriptor(field.desc, field.nested, translation,
69962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                    iter);
70062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    }
70162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  } else if (desc->IsArguments()) {
70262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    if (translation != nullptr) {
70362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      translation->BeginArgumentsObject(0);
704014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
705014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else if (desc->IsDuplicate()) {
70662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    if (translation != nullptr) {
70762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      translation->DuplicateObject(static_cast<int>(desc->id()));
70862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    }
70962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  } else if (desc->IsPlain()) {
71062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    InstructionOperand* op = iter->Advance();
71162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    if (translation != nullptr) {
71262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      AddTranslationForOperand(translation, iter->instruction(), op,
71362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                               desc->type());
71462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    }
715014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
71662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    DCHECK(desc->IsOptimizedOut());
71762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    if (translation != nullptr) {
71862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      if (optimized_out_literal_id_ == -1) {
71962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        optimized_out_literal_id_ =
72062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch            DefineDeoptimizationLiteral(isolate()->factory()->optimized_out());
72162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      }
72262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      translation->StoreLiteral(optimized_out_literal_id_);
72362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    }
724014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
725014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
726014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
727958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
728014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid CodeGenerator::TranslateFrameStateDescriptorOperands(
729014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    FrameStateDescriptor* desc, InstructionOperandIterator* iter,
730014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    OutputFrameStateCombine combine, Translation* translation) {
73162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  size_t index = 0;
73262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  StateValueList* values = desc->GetStateValueDescriptors();
73362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  for (StateValueList::iterator it = values->begin(); it != values->end();
73462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch       ++it, ++index) {
73562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    StateValueDescriptor* value_desc = (*it).desc;
73662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    if (combine.kind() == OutputFrameStateCombine::kPokeAt) {
73762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      // The result of the call should be placed at position
73862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      // [index_from_top] in the stack (overwriting whatever was
73962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      // previously there).
74062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      size_t index_from_top =
74162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch          desc->GetSize(combine) - 1 - combine.GetOffsetToPokeAt();
74262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      if (index >= index_from_top &&
74362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch          index < index_from_top + iter->instruction()->OutputCount()) {
74462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        DCHECK_NOT_NULL(translation);
74562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        AddTranslationForOperand(
74662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch            translation, iter->instruction(),
74762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch            iter->instruction()->OutputAt(index - index_from_top),
74862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch            MachineType::AnyTagged());
74962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        // Skip the instruction operands.
75062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        TranslateStateValueDescriptor(value_desc, (*it).nested, nullptr, iter);
75162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        continue;
752958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      }
753958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }
75462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    TranslateStateValueDescriptor(value_desc, (*it).nested, translation, iter);
75562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
75662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  DCHECK_EQ(desc->GetSize(OutputFrameStateCombine::Ignore()), index);
75762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
75862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  if (combine.kind() == OutputFrameStateCombine::kPushOutput) {
75962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    DCHECK(combine.GetPushCount() <= iter->instruction()->OutputCount());
76062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    for (size_t output = 0; output < combine.GetPushCount(); output++) {
76162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      // Materialize the result of the call instruction in this slot.
76262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      AddTranslationForOperand(translation, iter->instruction(),
76362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                               iter->instruction()->OutputAt(output),
76462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                               MachineType::AnyTagged());
76562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    }
766958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
767958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
768958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
769b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
770b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid CodeGenerator::BuildTranslationForFrameStateDescriptor(
771014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    FrameStateDescriptor* descriptor, InstructionOperandIterator* iter,
772014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Translation* translation, OutputFrameStateCombine state_combine) {
773b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Outer-most state must be added to translation first.
774014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (descriptor->outer_state() != nullptr) {
775014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    BuildTranslationForFrameStateDescriptor(descriptor->outer_state(), iter,
776014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                            translation,
777958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                                            OutputFrameStateCombine::Ignore());
778b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
779b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
780014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Handle<SharedFunctionInfo> shared_info;
781014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (!descriptor->shared_info().ToHandle(&shared_info)) {
782014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (!info()->has_shared_info()) {
783014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return;  // Stub with no SharedFunctionInfo.
784014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
785014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    shared_info = info()->shared_info();
786b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
787014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int shared_info_id = DefineDeoptimizationLiteral(shared_info);
788b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
789b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  switch (descriptor->type()) {
790014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case FrameStateType::kJavaScriptFunction:
791b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      translation->BeginJSFrame(
792014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          descriptor->bailout_id(), shared_info_id,
793958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier          static_cast<unsigned int>(descriptor->GetSize(state_combine) -
794014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                    (1 + descriptor->parameters_count())));
795014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
796014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case FrameStateType::kInterpretedFunction:
797014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      translation->BeginInterpretedFrame(
798014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          descriptor->bailout_id(), shared_info_id,
799109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch          static_cast<unsigned int>(descriptor->locals_count() + 1));
800b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
801014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case FrameStateType::kArgumentsAdaptor:
802b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      translation->BeginArgumentsAdaptorFrame(
803014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          shared_info_id,
804014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          static_cast<unsigned int>(descriptor->parameters_count()));
805014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
8063b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    case FrameStateType::kTailCallerFunction:
8073b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      translation->BeginTailCallerFrame(shared_info_id);
8083b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      break;
809014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case FrameStateType::kConstructStub:
81062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      DCHECK(descriptor->bailout_id().IsValidForConstructStub());
811014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      translation->BeginConstructStubFrame(
81262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch          descriptor->bailout_id(), shared_info_id,
813014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          static_cast<unsigned int>(descriptor->parameters_count()));
814b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
815f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    case FrameStateType::kGetterStub:
816f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      translation->BeginGetterStubFrame(shared_info_id);
817f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      break;
818f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    case FrameStateType::kSetterStub:
819f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      translation->BeginSetterStubFrame(shared_info_id);
820f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      break;
821b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
822b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
823014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TranslateFrameStateDescriptorOperands(descriptor, iter, state_combine,
824014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                        translation);
825b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
826b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
827b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
828b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochint CodeGenerator::BuildTranslation(Instruction* instr, int pc_offset,
829b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                    size_t frame_state_offset,
830b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                    OutputFrameStateCombine state_combine) {
831f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  DeoptimizationEntry const& entry =
832f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      GetDeoptimizationEntry(instr, frame_state_offset);
833f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  FrameStateDescriptor* const descriptor = entry.descriptor();
834b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  frame_state_offset++;
835b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
836b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Translation translation(
837b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      &translations_, static_cast<int>(descriptor->GetFrameCount()),
838b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      static_cast<int>(descriptor->GetJSFrameCount()), zone());
839014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  InstructionOperandIterator iter(instr, frame_state_offset);
840014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  BuildTranslationForFrameStateDescriptor(descriptor, &iter, &translation,
841014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                          state_combine);
842b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
843b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int deoptimization_id = static_cast<int>(deoptimization_states_.size());
844b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
845b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  deoptimization_states_.push_back(new (zone()) DeoptimizationState(
84662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      descriptor->bailout_id(), translation.index(), pc_offset, entry.kind(),
847f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      entry.reason()));
848b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
849b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return deoptimization_id;
850b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
851b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
852b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
853b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid CodeGenerator::AddTranslationForOperand(Translation* translation,
854b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                             Instruction* instr,
855958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                                             InstructionOperand* op,
856958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                                             MachineType type) {
857b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (op->IsStackSlot()) {
858014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (type.representation() == MachineRepresentation::kBit) {
859014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      translation->StoreBoolStackSlot(LocationOperand::cast(op)->index());
860014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    } else if (type == MachineType::Int8() || type == MachineType::Int16() ||
861014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch               type == MachineType::Int32()) {
862014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      translation->StoreInt32StackSlot(LocationOperand::cast(op)->index());
863014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    } else if (type == MachineType::Uint8() || type == MachineType::Uint16() ||
864014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch               type == MachineType::Uint32()) {
865014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      translation->StoreUint32StackSlot(LocationOperand::cast(op)->index());
866958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    } else {
86762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      CHECK_EQ(MachineRepresentation::kTagged, type.representation());
86862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      translation->StoreStackSlot(LocationOperand::cast(op)->index());
869958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }
870bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  } else if (op->IsFPStackSlot()) {
87113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    if (type.representation() == MachineRepresentation::kFloat64) {
87213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      translation->StoreDoubleStackSlot(LocationOperand::cast(op)->index());
87313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    } else {
87462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      CHECK_EQ(MachineRepresentation::kFloat32, type.representation());
87513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      translation->StoreFloatStackSlot(LocationOperand::cast(op)->index());
87613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    }
877b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else if (op->IsRegister()) {
878b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    InstructionOperandConverter converter(this, instr);
879014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (type.representation() == MachineRepresentation::kBit) {
880014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      translation->StoreBoolRegister(converter.ToRegister(op));
881014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    } else if (type == MachineType::Int8() || type == MachineType::Int16() ||
882014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch               type == MachineType::Int32()) {
883958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      translation->StoreInt32Register(converter.ToRegister(op));
884014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    } else if (type == MachineType::Uint8() || type == MachineType::Uint16() ||
885014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch               type == MachineType::Uint32()) {
886958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      translation->StoreUint32Register(converter.ToRegister(op));
887958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    } else {
88862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      CHECK_EQ(MachineRepresentation::kTagged, type.representation());
88962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      translation->StoreRegister(converter.ToRegister(op));
890958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }
891bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  } else if (op->IsFPRegister()) {
892b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    InstructionOperandConverter converter(this, instr);
89313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    if (type.representation() == MachineRepresentation::kFloat64) {
89413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      translation->StoreDoubleRegister(converter.ToDoubleRegister(op));
89513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    } else {
89662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      CHECK_EQ(MachineRepresentation::kFloat32, type.representation());
89713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      translation->StoreFloatRegister(converter.ToFloatRegister(op));
89813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    }
89962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  } else {
90062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    CHECK(op->IsImmediate());
901b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    InstructionOperandConverter converter(this, instr);
902b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Constant constant = converter.ToConstant(op);
903b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Handle<Object> constant_object;
904b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    switch (constant.type()) {
905b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      case Constant::kInt32:
90662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        if (type.representation() == MachineRepresentation::kTagged) {
907f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch          // When pointers are 4 bytes, we can use int32 constants to represent
908f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch          // Smis.
909f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch          DCHECK_EQ(4, kPointerSize);
910f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch          constant_object =
911f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch              handle(reinterpret_cast<Smi*>(constant.ToInt32()), isolate());
912f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch          DCHECK(constant_object->IsSmi());
913c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        } else if (type.representation() == MachineRepresentation::kBit) {
914c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch          if (constant.ToInt32() == 0) {
915c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch            constant_object = isolate()->factory()->false_value();
916c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch          } else {
917c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch            DCHECK_EQ(1, constant.ToInt32());
918c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch            constant_object = isolate()->factory()->true_value();
919c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch          }
920f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        } else {
921c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch          // TODO(jarin,bmeurer): We currently pass in raw pointers to the
922c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch          // JSFunction::entry here. We should really consider fixing this.
923f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch          DCHECK(type == MachineType::Int32() ||
924f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                 type == MachineType::Uint32() ||
925c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch                 type.representation() == MachineRepresentation::kWord32 ||
926f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                 type.representation() == MachineRepresentation::kNone);
927f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch          DCHECK(type.representation() != MachineRepresentation::kNone ||
928f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                 constant.ToInt32() == FrameStateDescriptor::kImpossibleValue);
92962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch          if (type == MachineType::Uint32()) {
93062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch            constant_object =
93162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                isolate()->factory()->NewNumberFromUint(constant.ToInt32());
93262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch          } else {
93362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch            constant_object =
93462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                isolate()->factory()->NewNumberFromInt(constant.ToInt32());
93562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch          }
936f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        }
937f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        break;
938f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      case Constant::kInt64:
939f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        // When pointers are 8 bytes, we can use int64 constants to represent
940f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        // Smis.
941c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        // TODO(jarin,bmeurer): We currently pass in raw pointers to the
942c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        // JSFunction::entry here. We should really consider fixing this.
943c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        DCHECK(type.representation() == MachineRepresentation::kWord64 ||
94462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch               type.representation() == MachineRepresentation::kTagged);
945f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        DCHECK_EQ(8, kPointerSize);
946b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        constant_object =
947f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch            handle(reinterpret_cast<Smi*>(constant.ToInt64()), isolate());
948f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        DCHECK(constant_object->IsSmi());
949b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        break;
950014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case Constant::kFloat32:
95162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        DCHECK(type.representation() == MachineRepresentation::kFloat32 ||
95262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch               type.representation() == MachineRepresentation::kTagged);
953014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        constant_object = isolate()->factory()->NewNumber(constant.ToFloat32());
954014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        break;
955b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      case Constant::kFloat64:
95662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        DCHECK(type.representation() == MachineRepresentation::kFloat64 ||
95762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch               type.representation() == MachineRepresentation::kTagged);
958b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        constant_object = isolate()->factory()->NewNumber(constant.ToFloat64());
959b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        break;
960b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      case Constant::kHeapObject:
96162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        DCHECK_EQ(MachineRepresentation::kTagged, type.representation());
962b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        constant_object = constant.ToHeapObject();
963b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        break;
964b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      default:
96562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        UNREACHABLE();
966b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
967014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (constant_object.is_identical_to(info()->closure())) {
968014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      translation->StoreJSFrameFunction();
969014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    } else {
970014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int literal_id = DefineDeoptimizationLiteral(constant_object);
971014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      translation->StoreLiteral(literal_id);
972014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
973b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
974b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
975b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
976b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
977b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid CodeGenerator::MarkLazyDeoptSite() {
978b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  last_lazy_deopt_pc_ = masm()->pc_offset();
979b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
980b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
9813b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben MurdochDeoptimizationExit* CodeGenerator::AddDeoptimizationExit(
9823b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    Instruction* instr, size_t frame_state_offset) {
9833b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  int const deoptimization_id = BuildTranslation(
9843b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      instr, -1, frame_state_offset, OutputFrameStateCombine::Ignore());
985f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  DeoptimizationExit* const exit = new (zone())
986f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      DeoptimizationExit(deoptimization_id, current_source_position_);
9873b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  deoptimization_exits_.push_back(exit);
9883b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  return exit;
9893b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch}
990b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
991958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierOutOfLineCode::OutOfLineCode(CodeGenerator* gen)
992014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    : frame_(gen->frame()), masm_(gen->masm()), next_(gen->ools_) {
993958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  gen->ools_ = this;
994958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
995958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
996958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
997958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierOutOfLineCode::~OutOfLineCode() {}
998958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
999b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}  // namespace compiler
1000b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}  // namespace internal
1001b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}  // namespace v8
1002