1b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Copyright 2014 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#ifndef V8_COMPILER_CODE_GENERATOR_H_
6b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define V8_COMPILER_CODE_GENERATOR_H_
7b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
8b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/compiler/gap-resolver.h"
9b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/compiler/instruction.h"
10f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch#include "src/compiler/unwinding-info-writer.h"
11b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/deoptimizer.h"
12b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/macro-assembler.h"
13b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/safepoint-table.h"
14f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch#include "src/source-position-table.h"
1562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch#include "src/trap-handler/trap-handler.h"
16b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
17b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace v8 {
18b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace internal {
19f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
20f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochclass CompilationInfo;
21f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
22b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace compiler {
23b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
24958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// Forward declarations.
253b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdochclass DeoptimizationExit;
26014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass FrameAccessState;
27958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierclass Linkage;
28958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierclass OutOfLineCode;
29958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
30958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierstruct BranchInfo {
31958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  FlagsCondition condition;
32958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  Label* true_label;
33958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  Label* false_label;
34958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  bool fallthru;
35958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier};
36958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
37958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
38014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass InstructionOperandIterator {
39014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch public:
40014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  InstructionOperandIterator(Instruction* instr, size_t pos)
41014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      : instr_(instr), pos_(pos) {}
42014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
43014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Instruction* instruction() const { return instr_; }
44014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  InstructionOperand* Advance() { return instr_->InputAt(pos_++); }
45014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
46014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch private:
47014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Instruction* instr_;
48014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  size_t pos_;
49014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch};
50014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
51014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
52b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Generates native code for a sequence of instructions.
53014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass CodeGenerator final : public GapResolver::Assembler {
54b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public:
55958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  explicit CodeGenerator(Frame* frame, Linkage* linkage,
56958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                         InstructionSequence* code, CompilationInfo* info);
57b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
58b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Generate native code.
59b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Handle<Code> GenerateCode();
60b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
61b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  InstructionSequence* code() const { return code_; }
62014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  FrameAccessState* frame_access_state() const { return frame_access_state_; }
63bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  const Frame* frame() const { return frame_access_state_->frame(); }
64f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  Isolate* isolate() const;
65958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  Linkage* linkage() const { return linkage_; }
66958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
67014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Label* GetLabel(RpoNumber rpo) { return &labels_[rpo.ToSize()]; }
68b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  void AssembleSourcePosition(Instruction* instr);
7062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
7162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  void AssembleSourcePosition(SourcePosition source_position);
7262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
7362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // Record a safepoint with the given pointer map.
7462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  void RecordSafepoint(ReferenceMap* references, Safepoint::Kind kind,
7562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                       int arguments, Safepoint::DeoptMode deopt_mode);
7662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
77b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private:
78b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  MacroAssembler* masm() { return &masm_; }
79b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GapResolver* resolver() { return &resolver_; }
80b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  SafepointTableBuilder* safepoints() { return &safepoints_; }
81b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Zone* zone() const { return code()->zone(); }
82958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  CompilationInfo* info() const { return info_; }
83b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
84bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  // Create the FrameAccessState object. The Frame is immutable from here on.
85bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  void CreateFrameAccessState(Frame* frame);
86bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
87bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  // Architecture - specific frame finalization.
88bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  void FinishFrame(Frame* frame);
89bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
90b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Checks if {block} will appear directly after {current_block_} when
91b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // assembling code, in which case, a fall-through can be used.
92014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool IsNextInAssemblyOrder(RpoNumber block) const;
93b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
94014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Check if a heap object can be materialized by loading from a heap root,
95014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // which is cheaper on some platforms than materializing the actual heap
96014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // object constant.
97014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool IsMaterializableFromRoot(Handle<HeapObject> object,
98014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                Heap::RootListIndex* index_return);
99014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
100bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  enum CodeGenResult { kSuccess, kTooManyDeoptimizationBailouts };
101bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
1023b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // Assemble instructions for the specified block.
103bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  CodeGenResult AssembleBlock(const InstructionBlock* block);
1043b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Assemble code for the specified instruction.
106bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  CodeGenResult AssembleInstruction(Instruction* instr,
107bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                                    const InstructionBlock* block);
108014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void AssembleGaps(Instruction* instr);
109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
110f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // Returns true if a instruction is a tail call that needs to adjust the stack
111f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // pointer before execution. The stack slot index to the empty slot above the
112f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // adjusted stack pointer is returned in |slot|.
113f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  bool GetSlotAboveSPBeforeTailCall(Instruction* instr, int* slot);
114f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // ===========================================================================
116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // ============= Architecture-specific code generation methods. ==============
117b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // ===========================================================================
118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
119bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  CodeGenResult AssembleArchInstruction(Instruction* instr);
120014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void AssembleArchJump(RpoNumber target);
121958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void AssembleArchBranch(Instruction* instr, BranchInfo* branch);
122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void AssembleArchBoolean(Instruction* instr, FlagsCondition condition);
12362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  void AssembleArchTrap(Instruction* instr, FlagsCondition condition);
124014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void AssembleArchLookupSwitch(Instruction* instr);
125014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void AssembleArchTableSwitch(Instruction* instr);
126b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
127bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  CodeGenResult AssembleDeoptimizerCall(int deoptimization_id,
128f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                        SourcePosition pos);
129b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
130b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Generates an architecture-specific, descriptor-specific prologue
131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // to set up a stack frame.
132bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  void AssembleConstructFrame();
1333b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
134b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Generates an architecture-specific, descriptor-specific return sequence
135b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // to tear down a stack frame.
136c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  void AssembleReturn(InstructionOperand* pop);
137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1383b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  void AssembleDeconstructFrame();
1393b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
140014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Generates code to manipulate the stack in preparation for a tail call.
141f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  void AssemblePrepareTailCall();
142014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1433b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // Generates code to pop current frame if it is an arguments adaptor frame.
1443b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  void AssemblePopArgumentsAdaptorFrame(Register args_reg, Register scratch1,
1453b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                                        Register scratch2, Register scratch3);
1463b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
147f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  enum PushTypeFlag {
148f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    kImmediatePush = 0x1,
149f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    kScalarPush = 0x2,
150f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    kFloat32Push = 0x4,
151f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    kFloat64Push = 0x8,
152f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    kFloatPush = kFloat32Push | kFloat64Push
153f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  };
154f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
155f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  typedef base::Flags<PushTypeFlag> PushTypeFlags;
156f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
157f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  static bool IsValidPush(InstructionOperand source, PushTypeFlags push_type);
158f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
159f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // Generate a list moves from an instruction that are candidates to be turned
160f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // into push instructions on platforms that support them. In general, the list
161f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // of push candidates are moves to a set of contiguous destination
162f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // InstructionOperand locations on the stack that don't clobber values that
163f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // are needed for resolve the gap or use values generated by the gap,
164f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // i.e. moves that can be hoisted together before the actual gap and assembled
165f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // together.
166f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  static void GetPushCompatibleMoves(Instruction* instr,
167f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                     PushTypeFlags push_type,
168f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                     ZoneVector<MoveOperands*>* pushes);
169f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
170f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // Called before a tail call |instr|'s gap moves are assembled and allows
171f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // gap-specific pre-processing, e.g. adjustment of the sp for tail calls that
172f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // need it before gap moves or conversion of certain gap moves into pushes.
173f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  void AssembleTailCallBeforeGap(Instruction* instr,
174f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                 int first_unused_stack_slot);
175f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // Called after a tail call |instr|'s gap moves are assembled and allows
176f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // gap-specific post-processing, e.g. adjustment of the sp for tail calls that
177f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // need it after gap moves.
178f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  void AssembleTailCallAfterGap(Instruction* instr,
179f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                int first_unused_stack_slot);
180f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // ===========================================================================
182b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // ============== Architecture-specific gap resolver methods. ================
183b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // ===========================================================================
184b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
185b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Interface used by the gap resolver to emit moves and swaps.
186958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void AssembleMove(InstructionOperand* source,
187014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                    InstructionOperand* destination) final;
188958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void AssembleSwap(InstructionOperand* source,
189014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                    InstructionOperand* destination) final;
190b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
191b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // ===========================================================================
192014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // =================== Jump table construction methods. ======================
193014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // ===========================================================================
194014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
195014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  class JumpTable;
196014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Adds a jump table that is emitted after the actual code.  Returns label
197014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // pointing to the beginning of the table.  {targets} is assumed to be static
198014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // or zone allocated.
199014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Label* AddJumpTable(Label** targets, size_t target_count);
200014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Emits a jump table.
201014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void AssembleJumpTable(Label** targets, size_t target_count);
202014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
203014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // ===========================================================================
204014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // ================== Deoptimization table construction. =====================
205014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // ===========================================================================
206014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
207014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void RecordCallPosition(Instruction* instr);
208b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void PopulateDeoptimizationData(Handle<Code> code);
209b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int DefineDeoptimizationLiteral(Handle<Object> literal);
210f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  DeoptimizationEntry const& GetDeoptimizationEntry(Instruction* instr,
211f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                                    size_t frame_state_offset);
21262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  DeoptimizeKind GetDeoptimizationKind(int deoptimization_id) const;
213f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  DeoptimizeReason GetDeoptimizationReason(int deoptimization_id) const;
214b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int BuildTranslation(Instruction* instr, int pc_offset,
2153b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                       size_t frame_state_offset,
216b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                       OutputFrameStateCombine state_combine);
217b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void BuildTranslationForFrameStateDescriptor(
218014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      FrameStateDescriptor* descriptor, InstructionOperandIterator* iter,
219014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Translation* translation, OutputFrameStateCombine state_combine);
220014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void TranslateStateValueDescriptor(StateValueDescriptor* desc,
22162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                     StateValueList* nested,
222014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                     Translation* translation,
223014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                     InstructionOperandIterator* iter);
224014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void TranslateFrameStateDescriptorOperands(FrameStateDescriptor* desc,
225014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                             InstructionOperandIterator* iter,
226014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                             OutputFrameStateCombine combine,
227014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                             Translation* translation);
228b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void AddTranslationForOperand(Translation* translation, Instruction* instr,
229958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                                InstructionOperand* op, MachineType type);
230b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void EnsureSpaceForLazyDeopt();
231b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void MarkLazyDeoptSite();
232b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2333b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  DeoptimizationExit* AddDeoptimizationExit(Instruction* instr,
2343b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                                            size_t frame_state_offset);
2353b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
236b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // ===========================================================================
237014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
238f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  class DeoptimizationState final : public ZoneObject {
239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch   public:
240f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    DeoptimizationState(BailoutId bailout_id, int translation_id, int pc_offset,
24162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                        DeoptimizeKind kind, DeoptimizeReason reason)
242f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        : bailout_id_(bailout_id),
243f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch          translation_id_(translation_id),
244f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch          pc_offset_(pc_offset),
24562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch          kind_(kind),
246f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch          reason_(reason) {}
247f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
248b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    BailoutId bailout_id() const { return bailout_id_; }
249b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    int translation_id() const { return translation_id_; }
250b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    int pc_offset() const { return pc_offset_; }
25162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    DeoptimizeKind kind() const { return kind_; }
252f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    DeoptimizeReason reason() const { return reason_; }
253b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
254b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch   private:
255b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    BailoutId bailout_id_;
256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    int translation_id_;
257b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    int pc_offset_;
25862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    DeoptimizeKind kind_;
259f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    DeoptimizeReason reason_;
260b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  };
261b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
262014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  struct HandlerInfo {
263014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Label* handler;
264014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    int pc_offset;
265014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  };
266014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
267958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  friend class OutOfLineCode;
268958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
269014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  FrameAccessState* frame_access_state_;
270958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  Linkage* const linkage_;
271958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  InstructionSequence* const code_;
272f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  UnwindingInfoWriter unwinding_info_writer_;
273958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  CompilationInfo* const info_;
274958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  Label* const labels_;
275014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Label return_label_;
276014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  RpoNumber current_block_;
277b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  SourcePosition current_source_position_;
278b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  MacroAssembler masm_;
279b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GapResolver resolver_;
280b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  SafepointTableBuilder safepoints_;
281014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  ZoneVector<HandlerInfo> handlers_;
2823b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  ZoneDeque<DeoptimizationExit*> deoptimization_exits_;
283b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ZoneDeque<DeoptimizationState*> deoptimization_states_;
284014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  ZoneDeque<Handle<Object>> deoptimization_literals_;
285014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  size_t inlined_function_count_;
286b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  TranslationBuffer translations_;
287b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int last_lazy_deopt_pc_;
288014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  JumpTable* jump_tables_;
289958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  OutOfLineCode* ools_;
290014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int osr_pc_offset_;
29162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  int optimized_out_literal_id_;
292f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  SourcePositionTableBuilder source_position_table_builder_;
293b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
294b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
295b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}  // namespace compiler
296b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}  // namespace internal
297b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}  // namespace v8
298b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
299b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif  // V8_COMPILER_CODE_GENERATOR_H
300