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"
8b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/compiler/code-generator-impl.h"
9b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/compiler/linkage.h"
10b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/compiler/pipeline.h"
11014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/frames-inl.h"
12b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
13b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace v8 {
14b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace internal {
15b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace compiler {
16b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
17014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass CodeGenerator::JumpTable final : public ZoneObject {
18014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch public:
19014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  JumpTable(JumpTable* next, Label** targets, size_t target_count)
20014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      : next_(next), targets_(targets), target_count_(target_count) {}
21014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
22014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Label* label() { return &label_; }
23014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  JumpTable* next() const { return next_; }
24014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Label** targets() const { return targets_; }
25014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  size_t target_count() const { return target_count_; }
26014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
27014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch private:
28014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Label label_;
29014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  JumpTable* const next_;
30014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Label** const targets_;
31014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  size_t const target_count_;
32014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch};
33014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
34014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
35958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierCodeGenerator::CodeGenerator(Frame* frame, Linkage* linkage,
36958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                             InstructionSequence* code, CompilationInfo* info)
37014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    : frame_access_state_(new (code->zone()) FrameAccessState(frame)),
38958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      linkage_(linkage),
39958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      code_(code),
40958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      info_(info),
41958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      labels_(zone()->NewArray<Label>(code->InstructionBlockCount())),
42014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      current_block_(RpoNumber::Invalid()),
43014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      current_source_position_(SourcePosition::Unknown()),
44014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      masm_(info->isolate(), nullptr, 0, CodeObjectRequired::kYes),
45b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      resolver_(this),
46b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      safepoints_(code->zone()),
47014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      handlers_(code->zone()),
48b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      deoptimization_states_(code->zone()),
49b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      deoptimization_literals_(code->zone()),
50014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      inlined_function_count_(0),
51b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      translations_(code->zone()),
52958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      last_lazy_deopt_pc_(0),
53014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      jump_tables_(nullptr),
54014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      ools_(nullptr),
55014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      osr_pc_offset_(-1) {
56958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  for (int i = 0; i < code->InstructionBlockCount(); ++i) {
57958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    new (&labels_[i]) Label;
58958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
59014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (code->ContainsCall()) {
60014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    frame->MarkNeedsFrame();
61014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
62958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
63b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
64b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
65b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHandle<Code> CodeGenerator::GenerateCode() {
66958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  CompilationInfo* info = this->info();
67b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
68014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Open a frame scope to indicate that there is a frame on the stack.  The
69014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // MANUAL indicates that the scope shouldn't actually generate code to set up
70014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // the frame (that is done in AssemblePrologue).
71014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  FrameScope frame_scope(masm(), StackFrame::MANUAL);
72014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
73b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Emit a code line info recording start event.
74b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  PositionsRecorder* recorder = masm()->positions_recorder();
75b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LOG_CODE_EVENT(isolate(), CodeStartLinePosInfoRecordEvent(recorder));
76b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
77b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Place function entry hook if requested to do so.
78b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (linkage()->GetIncomingDescriptor()->IsJSFunctionCall()) {
79b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ProfileEntryHookStub::MaybeCallEntryHook(masm());
80b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
81b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
82b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Architecture-specific, linkage-specific prologue.
83b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  info->set_prologue_offset(masm()->pc_offset());
84b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  AssemblePrologue();
85b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
86014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Define deoptimization literals for all inlined functions.
87014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK_EQ(0u, deoptimization_literals_.size());
88014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (auto& inlined : info->inlined_functions()) {
89014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (!inlined.shared_info.is_identical_to(info->shared_info())) {
90014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      DefineDeoptimizationLiteral(inlined.shared_info);
91014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
92014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
93014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  inlined_function_count_ = deoptimization_literals_.size();
94014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
95014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Define deoptimization literals for all unoptimized code objects of inlined
96014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // functions. This ensures unoptimized code is kept alive by optimized code.
97014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (auto& inlined : info->inlined_functions()) {
98014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (!inlined.shared_info.is_identical_to(info->shared_info())) {
99014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      DefineDeoptimizationLiteral(inlined.inlined_code_object_root);
100014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
101014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
102014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
103958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // Assemble all non-deferred blocks, followed by deferred ones.
104958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  for (int deferred = 0; deferred < 2; ++deferred) {
105958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    for (auto const block : code()->instruction_blocks()) {
106958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      if (block->IsDeferred() == (deferred == 0)) {
107958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        continue;
108958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      }
109958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      // Align loop headers on 16-byte boundaries.
110958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      if (block->IsLoopHeader()) masm()->Align(16);
111014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // Ensure lazy deopt doesn't patch handler entry points.
112014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (block->IsHandler()) EnsureSpaceForLazyDeopt();
113958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      // Bind a label for a block.
114958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      current_block_ = block->rpo_number();
115958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      if (FLAG_code_comments) {
116958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        // TODO(titzer): these code comments are a giant memory leak.
117014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        Vector<char> buffer = Vector<char>::New(200);
118014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        char* buffer_start = buffer.start();
119014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
120014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        int next = SNPrintF(
121014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            buffer, "-- B%d start%s%s%s%s", block->rpo_number().ToInt(),
122014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            block->IsDeferred() ? " (deferred)" : "",
123014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            block->needs_frame() ? "" : " (no frame)",
124014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            block->must_construct_frame() ? " (construct frame)" : "",
125014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            block->must_deconstruct_frame() ? " (deconstruct frame)" : "");
126014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
127014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        buffer = buffer.SubVector(next, buffer.length());
128014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
129014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        if (block->IsLoopHeader()) {
130014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          next =
131014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              SNPrintF(buffer, " (loop up to %d)", block->loop_end().ToInt());
132014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          buffer = buffer.SubVector(next, buffer.length());
133014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        }
134014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        if (block->loop_header().IsValid()) {
135014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          next =
136014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              SNPrintF(buffer, " (in loop %d)", block->loop_header().ToInt());
137014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          buffer = buffer.SubVector(next, buffer.length());
138014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        }
139014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        SNPrintF(buffer, " --");
140014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        masm()->RecordComment(buffer_start);
141958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      }
142958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      masm()->bind(GetLabel(current_block_));
143958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      for (int i = block->code_start(); i < block->code_end(); ++i) {
144958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        AssembleInstruction(code()->InstructionAt(i));
145958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      }
146958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }
147958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
148958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
149958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // Assemble all out-of-line code.
150958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (ools_) {
151958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    masm()->RecordComment("-- Out of line code --");
152958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    for (OutOfLineCode* ool = ools_; ool; ool = ool->next()) {
153958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      masm()->bind(ool->entry());
154958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      ool->Generate();
155014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (ool->exit()->is_bound()) masm()->jmp(ool->exit());
156958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }
157b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
159958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // Ensure there is space for lazy deoptimization in the code.
160014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (info->ShouldEnsureSpaceForLazyDeopt()) {
161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    int target_offset = masm()->pc_offset() + Deoptimizer::patch_size();
162b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    while (masm()->pc_offset() < target_offset) {
163b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      masm()->nop();
164b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
167014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  FinishCode(masm());
168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
169014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Emit the jump tables.
170014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (jump_tables_) {
171014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    masm()->Align(kPointerSize);
172014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    for (JumpTable* table = jump_tables_; table; table = table->next()) {
173014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      masm()->bind(table->label());
174014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      AssembleJumpTable(table->targets(), table->target_count());
175014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
176b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
177014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
178014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  safepoints()->Emit(masm(), frame()->GetSpillSlotCount());
179014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
180014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Handle<Code> result =
181014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      v8::internal::CodeGenerator::MakeCodeEpilogue(masm(), info);
182b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  result->set_is_turbofanned(true);
183b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  result->set_stack_slots(frame()->GetSpillSlotCount());
184b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  result->set_safepoint_table_offset(safepoints()->GetCodeOffset());
185b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
186014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Emit exception handler table.
187014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (!handlers_.empty()) {
188014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Handle<HandlerTable> table =
189014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        Handle<HandlerTable>::cast(isolate()->factory()->NewFixedArray(
190014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            HandlerTable::LengthForReturn(static_cast<int>(handlers_.size())),
191014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            TENURED));
192014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    for (size_t i = 0; i < handlers_.size(); ++i) {
193014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int position = handlers_[i].handler->pos();
194014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      HandlerTable::CatchPrediction prediction = handlers_[i].caught_locally
195014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                                     ? HandlerTable::CAUGHT
196014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                                     : HandlerTable::UNCAUGHT;
197014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      table->SetReturnOffset(static_cast<int>(i), handlers_[i].pc_offset);
198014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      table->SetReturnHandler(static_cast<int>(i), position, prediction);
199014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
200014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    result->set_handler_table(*table);
201014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
202014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
203b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  PopulateDeoptimizationData(result);
204b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
205958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // Ensure there is space for lazy deoptimization in the relocation info.
206014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (info->ShouldEnsureSpaceForLazyDeopt()) {
207958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    Deoptimizer::EnsureRelocSpaceForLazyDeoptimization(result);
208958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
209958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Emit a code line info recording stop event.
211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void* line_info = recorder->DetachJITHandlerData();
212b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LOG_CODE_EVENT(isolate(), CodeEndLinePosInfoRecordEvent(*result, line_info));
213b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
214b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return result;
215b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
216b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
217b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
218014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochbool CodeGenerator::IsNextInAssemblyOrder(RpoNumber block) const {
219014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return code()
220014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      ->InstructionBlockAt(current_block_)
221014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      ->ao_number()
222014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      .IsNext(code()->InstructionBlockAt(block)->ao_number());
223958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
224958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
225958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
226014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid CodeGenerator::RecordSafepoint(ReferenceMap* references,
227014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                    Safepoint::Kind kind, int arguments,
228b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                    Safepoint::DeoptMode deopt_mode) {
229b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Safepoint safepoint =
230b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      safepoints()->DefineSafepoint(masm(), kind, arguments, deopt_mode);
231014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int stackSlotToSpillSlotDelta =
232014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      frame()->GetTotalFrameSlotCount() - frame()->GetSpillSlotCount();
233014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (auto& operand : references->reference_operands()) {
234014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (operand.IsStackSlot()) {
235014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int index = LocationOperand::cast(operand).index();
236014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      DCHECK(index >= 0);
237014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // Safepoint table indices are 0-based from the beginning of the spill
238014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // slot area, adjust appropriately.
239014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      index -= stackSlotToSpillSlotDelta;
240014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      safepoint.DefinePointerSlot(index, zone());
241014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    } else if (operand.IsRegister() && (kind & Safepoint::kWithRegisters)) {
242014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Register reg = LocationOperand::cast(operand).GetRegister();
243b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      safepoint.DefinePointerRegister(reg, zone());
244b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
245b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
246b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
247b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
248b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
249014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochbool CodeGenerator::IsMaterializableFromFrame(Handle<HeapObject> object,
250014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                              int* offset_return) {
251014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (linkage()->GetIncomingDescriptor()->IsJSFunctionCall()) {
252014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (info()->has_context() && object.is_identical_to(info()->context()) &&
253014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        !info()->is_osr()) {
254014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      *offset_return = StandardFrameConstants::kContextOffset;
255014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return true;
256014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    } else if (object.is_identical_to(info()->closure())) {
257014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      *offset_return = JavaScriptFrameConstants::kFunctionOffset;
258014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return true;
259014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
260014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
261014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return false;
262014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
263014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
264014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
265014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochbool CodeGenerator::IsMaterializableFromRoot(
266014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Handle<HeapObject> object, Heap::RootListIndex* index_return) {
267014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const CallDescriptor* incoming_descriptor =
268014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      linkage()->GetIncomingDescriptor();
269014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (incoming_descriptor->flags() & CallDescriptor::kCanUseRoots) {
270014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    RootIndexMap map(isolate());
271014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    int root_index = map.Lookup(*object);
272014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (root_index != RootIndexMap::kInvalidRootIndex) {
273014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      *index_return = static_cast<Heap::RootListIndex>(root_index);
274014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return true;
275014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
276014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
277014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return false;
278014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
279014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
280014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
281b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid CodeGenerator::AssembleInstruction(Instruction* instr) {
282014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  AssembleGaps(instr);
283014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  AssembleSourcePosition(instr);
284014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Assemble architecture-specific code for the instruction.
285014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  AssembleArchInstruction(instr);
286014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
287014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  FlagsMode mode = FlagsModeField::decode(instr->opcode());
288014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  FlagsCondition condition = FlagsConditionField::decode(instr->opcode());
289014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (mode == kFlags_branch) {
290014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Assemble a branch after this instruction.
291014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    InstructionOperandConverter i(this, instr);
292014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    RpoNumber true_rpo = i.InputRpo(instr->InputCount() - 2);
293014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    RpoNumber false_rpo = i.InputRpo(instr->InputCount() - 1);
294014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
295014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (true_rpo == false_rpo) {
296014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // redundant branch.
297014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (!IsNextInAssemblyOrder(true_rpo)) {
298014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        AssembleArchJump(true_rpo);
299958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      }
300014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return;
301014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
302014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (IsNextInAssemblyOrder(true_rpo)) {
303014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // true block is next, can fall through if condition negated.
304014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      std::swap(true_rpo, false_rpo);
305014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      condition = NegateFlagsCondition(condition);
306b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
307014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    BranchInfo branch;
308014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    branch.condition = condition;
309014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    branch.true_label = GetLabel(true_rpo);
310014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    branch.false_label = GetLabel(false_rpo);
311014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    branch.fallthru = IsNextInAssemblyOrder(false_rpo);
312014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Assemble architecture-specific branch.
313014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    AssembleArchBranch(instr, &branch);
314014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else if (mode == kFlags_set) {
315014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Assemble a boolean materialization after this instruction.
316014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    AssembleArchBoolean(instr, condition);
317b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
318b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
319b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
320b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
321014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid CodeGenerator::AssembleSourcePosition(Instruction* instr) {
322014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  SourcePosition source_position;
323014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (!code()->GetSourcePosition(instr, &source_position)) return;
324b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (source_position == current_source_position_) return;
325014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  current_source_position_ = source_position;
326014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (source_position.IsUnknown()) return;
327014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int code_pos = source_position.raw();
328014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  masm()->positions_recorder()->RecordPosition(code_pos);
329014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  masm()->positions_recorder()->WriteRecordedPositions();
330014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (FLAG_code_comments) {
331014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Vector<char> buffer = Vector<char>::New(256);
332014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    CompilationInfo* info = this->info();
333014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    int ln = Script::GetLineNumber(info->script(), code_pos);
334014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    int cn = Script::GetColumnNumber(info->script(), code_pos);
335014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (info->script()->name()->IsString()) {
336014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Handle<String> file(String::cast(info->script()->name()));
337014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      base::OS::SNPrintF(buffer.start(), buffer.length(), "-- %s:%d:%d --",
338014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                         file->ToCString().get(), ln, cn);
339014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    } else {
340014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      base::OS::SNPrintF(buffer.start(), buffer.length(),
341014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                         "-- <unknown>:%d:%d --", ln, cn);
342b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
343014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    masm()->RecordComment(buffer.start());
344b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
345b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
346b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
347b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
348014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid CodeGenerator::AssembleGaps(Instruction* instr) {
349014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (int i = Instruction::FIRST_GAP_POSITION;
350014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch       i <= Instruction::LAST_GAP_POSITION; i++) {
351014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Instruction::GapPosition inner_pos =
352014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        static_cast<Instruction::GapPosition>(i);
353b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ParallelMove* move = instr->GetParallelMove(inner_pos);
354014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (move != nullptr) resolver()->Resolve(move);
355b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
356b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
357b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
358b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
359b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid CodeGenerator::PopulateDeoptimizationData(Handle<Code> code_object) {
360958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  CompilationInfo* info = this->info();
361b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int deopt_count = static_cast<int>(deoptimization_states_.size());
362014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (deopt_count == 0 && !info->is_osr()) return;
363b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Handle<DeoptimizationInputData> data =
364b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      DeoptimizationInputData::New(isolate(), deopt_count, TENURED);
365b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
366b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Handle<ByteArray> translation_array =
367b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      translations_.CreateByteArray(isolate()->factory());
368b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
369b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  data->SetTranslationByteArray(*translation_array);
370014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  data->SetInlinedFunctionCount(
371014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Smi::FromInt(static_cast<int>(inlined_function_count_)));
372b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  data->SetOptimizationId(Smi::FromInt(info->optimization_id()));
373014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
374014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (info->has_shared_info()) {
375b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    data->SetSharedFunctionInfo(*info->shared_info());
376b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
377b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    data->SetSharedFunctionInfo(Smi::FromInt(0));
378b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
379b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
380b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Handle<FixedArray> literals = isolate()->factory()->NewFixedArray(
381b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      static_cast<int>(deoptimization_literals_.size()), TENURED);
382b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  {
383b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    AllowDeferredHandleDereference copy_handles;
384b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (unsigned i = 0; i < deoptimization_literals_.size(); i++) {
385b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      literals->set(i, *deoptimization_literals_[i]);
386b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
387b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    data->SetLiteralArray(*literals);
388b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
389b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
390014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (info->is_osr()) {
391014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(osr_pc_offset_ >= 0);
392014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    data->SetOsrAstId(Smi::FromInt(info_->osr_ast_id().ToInt()));
393014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    data->SetOsrPcOffset(Smi::FromInt(osr_pc_offset_));
394014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
395014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    BailoutId osr_ast_id = BailoutId::None();
396014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    data->SetOsrAstId(Smi::FromInt(osr_ast_id.ToInt()));
397014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    data->SetOsrPcOffset(Smi::FromInt(-1));
398014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
399b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
400b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Populate deoptimization entries.
401b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (int i = 0; i < deopt_count; i++) {
402b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DeoptimizationState* deoptimization_state = deoptimization_states_[i];
403b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    data->SetAstId(i, deoptimization_state->bailout_id());
404014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    CHECK(deoptimization_states_[i]);
405b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    data->SetTranslationIndex(
406b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        i, Smi::FromInt(deoptimization_states_[i]->translation_id()));
407b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    data->SetArgumentsStackHeight(i, Smi::FromInt(0));
408b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    data->SetPc(i, Smi::FromInt(deoptimization_state->pc_offset()));
409b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
410b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
411b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  code_object->set_deoptimization_data(*data);
412b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
413b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
414b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
415014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochLabel* CodeGenerator::AddJumpTable(Label** targets, size_t target_count) {
416014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  jump_tables_ = new (zone()) JumpTable(jump_tables_, targets, target_count);
417014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return jump_tables_->label();
418014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
419014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
420014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
421014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid CodeGenerator::RecordCallPosition(Instruction* instr) {
422b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CallDescriptor::Flags flags(MiscField::decode(instr->opcode()));
423b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
424b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool needs_frame_state = (flags & CallDescriptor::kNeedsFrameState);
425b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
426b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  RecordSafepoint(
427014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      instr->reference_map(), Safepoint::kSimple, 0,
428b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      needs_frame_state ? Safepoint::kLazyDeopt : Safepoint::kNoLazyDeopt);
429b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
430014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (flags & CallDescriptor::kHasExceptionHandler) {
431014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    InstructionOperandConverter i(this, instr);
432014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bool caught = flags & CallDescriptor::kHasLocalCatchHandler;
433014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    RpoNumber handler_rpo = i.InputRpo(instr->InputCount() - 1);
434014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    handlers_.push_back({caught, GetLabel(handler_rpo), masm()->pc_offset()});
435014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
436014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
437b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (flags & CallDescriptor::kNeedsNopAfterCall) {
438b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    AddNopForSmiCodeInlining();
439b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
440b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
441b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (needs_frame_state) {
442b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    MarkLazyDeoptSite();
443014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // If the frame state is present, it starts at argument 1 (just after the
444014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // code address).
445b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    size_t frame_state_offset = 1;
446b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    FrameStateDescriptor* descriptor =
447b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        GetFrameStateDescriptor(instr, frame_state_offset);
448b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    int pc_offset = masm()->pc_offset();
449b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    int deopt_state_id = BuildTranslation(instr, pc_offset, frame_state_offset,
450b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                          descriptor->state_combine());
451b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // If the pre-call frame state differs from the post-call one, produce the
452b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // pre-call frame state, too.
453b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // TODO(jarin) We might want to avoid building the pre-call frame state
454b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // because it is only used to get locals and arguments (by the debugger and
455b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // f.arguments), and those are the same in the pre-call and post-call
456b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // states.
457958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    if (!descriptor->state_combine().IsOutputIgnored()) {
458958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      deopt_state_id = BuildTranslation(instr, -1, frame_state_offset,
459958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                                        OutputFrameStateCombine::Ignore());
460b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
461b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#if DEBUG
462b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Make sure all the values live in stack slots or they are immediates.
463b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // (The values should not live in register because registers are clobbered
464b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // by calls.)
465958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    for (size_t i = 0; i < descriptor->GetSize(); i++) {
466b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      InstructionOperand* op = instr->InputAt(frame_state_offset + 1 + i);
467958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      CHECK(op->IsStackSlot() || op->IsDoubleStackSlot() || op->IsImmediate());
468b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
469b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif
470b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    safepoints()->RecordLazyDeoptimizationIndex(deopt_state_id);
471b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
472b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
473b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
474b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
475b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochint CodeGenerator::DefineDeoptimizationLiteral(Handle<Object> literal) {
476b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int result = static_cast<int>(deoptimization_literals_.size());
477b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (unsigned i = 0; i < deoptimization_literals_.size(); ++i) {
478b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (deoptimization_literals_[i].is_identical_to(literal)) return i;
479b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
480b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  deoptimization_literals_.push_back(literal);
481b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return result;
482b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
483b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
484b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
485b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochFrameStateDescriptor* CodeGenerator::GetFrameStateDescriptor(
486b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Instruction* instr, size_t frame_state_offset) {
487b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  InstructionOperandConverter i(this, instr);
488014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  InstructionSequence::StateId state_id =
489014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      InstructionSequence::StateId::FromInt(i.InputInt32(frame_state_offset));
490b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return code()->GetFrameStateDescriptor(state_id);
491b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
492b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
493958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
494014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid CodeGenerator::TranslateStateValueDescriptor(
495014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    StateValueDescriptor* desc, Translation* translation,
496014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    InstructionOperandIterator* iter) {
497014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (desc->IsNested()) {
498014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    translation->BeginCapturedObject(static_cast<int>(desc->size()));
499014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    for (size_t index = 0; index < desc->fields().size(); index++) {
500014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      TranslateStateValueDescriptor(&desc->fields()[index], translation, iter);
501014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
502014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else if (desc->IsDuplicate()) {
503014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    translation->DuplicateObject(static_cast<int>(desc->id()));
504014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
505014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(desc->IsPlain());
506014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    AddTranslationForOperand(translation, iter->instruction(), iter->Advance(),
507014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                             desc->type());
508014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
509014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
510014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
511958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
512014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid CodeGenerator::TranslateFrameStateDescriptorOperands(
513014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    FrameStateDescriptor* desc, InstructionOperandIterator* iter,
514014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    OutputFrameStateCombine combine, Translation* translation) {
515014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (size_t index = 0; index < desc->GetSize(combine); index++) {
516014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    switch (combine.kind()) {
517014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case OutputFrameStateCombine::kPushOutput: {
518014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        DCHECK(combine.GetPushCount() <= iter->instruction()->OutputCount());
519014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        size_t size_without_output =
520014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            desc->GetSize(OutputFrameStateCombine::Ignore());
521014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        // If the index is past the existing stack items in values_.
522014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        if (index >= size_without_output) {
523014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          // Materialize the result of the call instruction in this slot.
524014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          AddTranslationForOperand(
525014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              translation, iter->instruction(),
526014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              iter->instruction()->OutputAt(index - size_without_output),
527014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              MachineType::AnyTagged());
528014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          continue;
529014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        }
530014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        break;
531958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      }
532014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case OutputFrameStateCombine::kPokeAt:
533014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        // The result of the call should be placed at position
534014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        // [index_from_top] in the stack (overwriting whatever was
535014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        // previously there).
536014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        size_t index_from_top =
537014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            desc->GetSize(combine) - 1 - combine.GetOffsetToPokeAt();
538014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        if (index >= index_from_top &&
539014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            index < index_from_top + iter->instruction()->OutputCount()) {
540014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          AddTranslationForOperand(
541014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              translation, iter->instruction(),
542014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              iter->instruction()->OutputAt(index - index_from_top),
543014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              MachineType::AnyTagged());
544014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          iter->Advance();  // We do not use this input, but we need to
545014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                            // advace, as the input got replaced.
546014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          continue;
547014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        }
548014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        break;
549958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }
550014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    StateValueDescriptor* value_desc = desc->GetStateValueDescriptor();
551014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    TranslateStateValueDescriptor(&value_desc->fields()[index], translation,
552014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                  iter);
553958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
554958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
555958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
556b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
557b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid CodeGenerator::BuildTranslationForFrameStateDescriptor(
558014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    FrameStateDescriptor* descriptor, InstructionOperandIterator* iter,
559014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Translation* translation, OutputFrameStateCombine state_combine) {
560b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Outer-most state must be added to translation first.
561014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (descriptor->outer_state() != nullptr) {
562014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    BuildTranslationForFrameStateDescriptor(descriptor->outer_state(), iter,
563014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                            translation,
564958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                                            OutputFrameStateCombine::Ignore());
565b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
566b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
567014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Handle<SharedFunctionInfo> shared_info;
568014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (!descriptor->shared_info().ToHandle(&shared_info)) {
569014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (!info()->has_shared_info()) {
570014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return;  // Stub with no SharedFunctionInfo.
571014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
572014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    shared_info = info()->shared_info();
573b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
574014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int shared_info_id = DefineDeoptimizationLiteral(shared_info);
575b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
576b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  switch (descriptor->type()) {
577014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case FrameStateType::kJavaScriptFunction:
578b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      translation->BeginJSFrame(
579014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          descriptor->bailout_id(), shared_info_id,
580958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier          static_cast<unsigned int>(descriptor->GetSize(state_combine) -
581014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                    (1 + descriptor->parameters_count())));
582014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
583014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case FrameStateType::kInterpretedFunction:
584014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      translation->BeginInterpretedFrame(
585014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          descriptor->bailout_id(), shared_info_id,
586014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          static_cast<unsigned int>(descriptor->locals_count()));
587b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
588014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case FrameStateType::kArgumentsAdaptor:
589b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      translation->BeginArgumentsAdaptorFrame(
590014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          shared_info_id,
591014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          static_cast<unsigned int>(descriptor->parameters_count()));
592014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
593014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case FrameStateType::kConstructStub:
594014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      translation->BeginConstructStubFrame(
595014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          shared_info_id,
596014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          static_cast<unsigned int>(descriptor->parameters_count()));
597b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
598b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
599b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
600014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TranslateFrameStateDescriptorOperands(descriptor, iter, state_combine,
601014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                        translation);
602b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
603b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
604b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
605b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochint CodeGenerator::BuildTranslation(Instruction* instr, int pc_offset,
606b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                    size_t frame_state_offset,
607b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                    OutputFrameStateCombine state_combine) {
608b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  FrameStateDescriptor* descriptor =
609b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      GetFrameStateDescriptor(instr, frame_state_offset);
610b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  frame_state_offset++;
611b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
612b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Translation translation(
613b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      &translations_, static_cast<int>(descriptor->GetFrameCount()),
614b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      static_cast<int>(descriptor->GetJSFrameCount()), zone());
615014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  InstructionOperandIterator iter(instr, frame_state_offset);
616014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  BuildTranslationForFrameStateDescriptor(descriptor, &iter, &translation,
617014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                          state_combine);
618b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
619b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int deoptimization_id = static_cast<int>(deoptimization_states_.size());
620b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
621b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  deoptimization_states_.push_back(new (zone()) DeoptimizationState(
622b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      descriptor->bailout_id(), translation.index(), pc_offset));
623b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
624b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return deoptimization_id;
625b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
626b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
627b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
628b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid CodeGenerator::AddTranslationForOperand(Translation* translation,
629b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                             Instruction* instr,
630958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                                             InstructionOperand* op,
631958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                                             MachineType type) {
632b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (op->IsStackSlot()) {
633014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (type.representation() == MachineRepresentation::kBit) {
634014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      translation->StoreBoolStackSlot(LocationOperand::cast(op)->index());
635014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    } else if (type == MachineType::Int8() || type == MachineType::Int16() ||
636014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch               type == MachineType::Int32()) {
637014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      translation->StoreInt32StackSlot(LocationOperand::cast(op)->index());
638014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    } else if (type == MachineType::Uint8() || type == MachineType::Uint16() ||
639014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch               type == MachineType::Uint32()) {
640014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      translation->StoreUint32StackSlot(LocationOperand::cast(op)->index());
641014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    } else if (type.representation() == MachineRepresentation::kTagged) {
642014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      translation->StoreStackSlot(LocationOperand::cast(op)->index());
643958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    } else {
644958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      CHECK(false);
645958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }
646b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else if (op->IsDoubleStackSlot()) {
647014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(IsFloatingPoint(type.representation()));
648014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    translation->StoreDoubleStackSlot(LocationOperand::cast(op)->index());
649b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else if (op->IsRegister()) {
650b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    InstructionOperandConverter converter(this, instr);
651014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (type.representation() == MachineRepresentation::kBit) {
652014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      translation->StoreBoolRegister(converter.ToRegister(op));
653014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    } else if (type == MachineType::Int8() || type == MachineType::Int16() ||
654014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch               type == MachineType::Int32()) {
655958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      translation->StoreInt32Register(converter.ToRegister(op));
656014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    } else if (type == MachineType::Uint8() || type == MachineType::Uint16() ||
657014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch               type == MachineType::Uint32()) {
658958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      translation->StoreUint32Register(converter.ToRegister(op));
659014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    } else if (type.representation() == MachineRepresentation::kTagged) {
660958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      translation->StoreRegister(converter.ToRegister(op));
661958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    } else {
662958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      CHECK(false);
663958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }
664b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else if (op->IsDoubleRegister()) {
665014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(IsFloatingPoint(type.representation()));
666b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    InstructionOperandConverter converter(this, instr);
667b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    translation->StoreDoubleRegister(converter.ToDoubleRegister(op));
668b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else if (op->IsImmediate()) {
669b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    InstructionOperandConverter converter(this, instr);
670b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Constant constant = converter.ToConstant(op);
671b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Handle<Object> constant_object;
672b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    switch (constant.type()) {
673b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      case Constant::kInt32:
674014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        DCHECK(type == MachineType::Int32() || type == MachineType::Uint32() ||
675014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch               type.representation() == MachineRepresentation::kBit);
676b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        constant_object =
677b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            isolate()->factory()->NewNumberFromInt(constant.ToInt32());
678b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        break;
679014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case Constant::kFloat32:
680014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        DCHECK(type.representation() == MachineRepresentation::kFloat32 ||
681014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch               type.representation() == MachineRepresentation::kTagged);
682014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        constant_object = isolate()->factory()->NewNumber(constant.ToFloat32());
683014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        break;
684b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      case Constant::kFloat64:
685014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        DCHECK(type.representation() == MachineRepresentation::kFloat64 ||
686014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch               type.representation() == MachineRepresentation::kTagged);
687b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        constant_object = isolate()->factory()->NewNumber(constant.ToFloat64());
688b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        break;
689b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      case Constant::kHeapObject:
690014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        DCHECK(type.representation() == MachineRepresentation::kTagged);
691b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        constant_object = constant.ToHeapObject();
692b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        break;
693b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      default:
694958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        CHECK(false);
695b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
696014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (constant_object.is_identical_to(info()->closure())) {
697014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      translation->StoreJSFrameFunction();
698014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    } else {
699014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int literal_id = DefineDeoptimizationLiteral(constant_object);
700014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      translation->StoreLiteral(literal_id);
701014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
702b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
703958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    CHECK(false);
704b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
705b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
706b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
707b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
708b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid CodeGenerator::MarkLazyDeoptSite() {
709b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  last_lazy_deopt_pc_ = masm()->pc_offset();
710b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
711b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
712b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
713014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochint CodeGenerator::TailCallFrameStackSlotDelta(int stack_param_delta) {
714014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  CallDescriptor* descriptor = linkage()->GetIncomingDescriptor();
715014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int spill_slots = frame()->GetSpillSlotCount();
716014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool has_frame = descriptor->IsJSFunctionCall() || spill_slots > 0;
717014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Leave the PC on the stack on platforms that have that as part of their ABI
718014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int pc_slots = V8_TARGET_ARCH_STORES_RETURN_ADDRESS_ON_STACK ? 1 : 0;
719014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int sp_slot_delta =
720014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      has_frame ? (frame()->GetTotalFrameSlotCount() - pc_slots) : 0;
721014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Discard only slots that won't be used by new parameters.
722014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  sp_slot_delta += stack_param_delta;
723014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return sp_slot_delta;
724b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
725b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
726b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
727958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierOutOfLineCode::OutOfLineCode(CodeGenerator* gen)
728014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    : frame_(gen->frame()), masm_(gen->masm()), next_(gen->ools_) {
729958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  gen->ools_ = this;
730958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
731958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
732958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
733958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierOutOfLineCode::~OutOfLineCode() {}
734958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
735b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}  // namespace compiler
736b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}  // namespace internal
737b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}  // namespace v8
738