13ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Copyright 2012 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.
4b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
5014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#ifndef V8_CRANKSHAFT_HYDROGEN_H_
6014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define V8_CRANKSHAFT_HYDROGEN_H_
7b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
8b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/accessors.h"
9b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/allocation.h"
10537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch#include "src/ast/ast-type-bounds.h"
11014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/ast/ast.h"
12014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/ast/scopes.h"
13b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/bailout-reason.h"
14b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/compiler.h"
151b268ca467c924004286c97bac133db489cf43d0Ben Murdoch#include "src/crankshaft/compilation-phase.h"
16014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/crankshaft/hydrogen-instructions.h"
17537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch#include "src/parsing/parser.h"
18b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/zone.h"
19b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
20b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochnamespace v8 {
21b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochnamespace internal {
22b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
23b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// Forward declarations.
24257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochclass BitVector;
25b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass FunctionState;
26b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochclass HEnvironment;
27b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochclass HGraph;
28b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochclass HLoopInformation;
29b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass HOsrBuilder;
30b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochclass HTracer;
31b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochclass LAllocator;
32b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochclass LChunk;
33b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochclass LiveRange;
34b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
35537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdochclass HCompilationJob final : public CompilationJob {
36537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch public:
37537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch  explicit HCompilationJob(Handle<JSFunction> function)
38537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch      : CompilationJob(&info_, "Crankshaft"),
39537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch        zone_(function->GetIsolate()->allocator()),
40537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch        parse_info_(&zone_, function),
41537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch        info_(&parse_info_, function),
42537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch        graph_(nullptr),
43537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch        chunk_(nullptr) {}
44537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch
45537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch protected:
46537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch  virtual Status CreateGraphImpl();
47537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch  virtual Status OptimizeGraphImpl();
48537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch  virtual Status GenerateCodeImpl();
49537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch
50537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch private:
51537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch  Zone zone_;
52537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch  ParseInfo parse_info_;
53537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch  CompilationInfo info_;
54537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch  HGraph* graph_;
55537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch  LChunk* chunk_;
56537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch};
57b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
58014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass HBasicBlock final : public ZoneObject {
59b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch public:
60b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  explicit HBasicBlock(HGraph* graph);
61b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ~HBasicBlock() { }
62b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
63b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Simple accessors.
64b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  int block_id() const { return block_id_; }
65b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void set_block_id(int id) { block_id_ = id; }
66b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  HGraph* graph() const { return graph_; }
67b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Isolate* isolate() const;
68b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  const ZoneList<HPhi*>* phis() const { return &phis_; }
69b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  HInstruction* first() const { return first_; }
70e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  HInstruction* last() const { return last_; }
71e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  void set_last(HInstruction* instr) { last_ = instr; }
72b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  HControlInstruction* end() const { return end_; }
73b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  HLoopInformation* loop_information() const { return loop_information_; }
74b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HLoopInformation* current_loop() const {
75b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return IsLoopHeader() ? loop_information()
76b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                          : (parent_loop_header() != NULL
77b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                            ? parent_loop_header()->loop_information() : NULL);
78b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
79b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  const ZoneList<HBasicBlock*>* predecessors() const { return &predecessors_; }
80b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  bool HasPredecessor() const { return predecessors_.length() > 0; }
81b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  const ZoneList<HBasicBlock*>* dominated_blocks() const {
82b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    return &dominated_blocks_;
83b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
84b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  const ZoneList<int>* deleted_phis() const {
85b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    return &deleted_phis_;
86b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
87b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void RecordDeletedPhi(int merge_index) {
88b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    deleted_phis_.Add(merge_index, zone());
89b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
90b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  HBasicBlock* dominator() const { return dominator_; }
91b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  HEnvironment* last_environment() const { return last_environment_; }
92b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  int argument_count() const { return argument_count_; }
93b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void set_argument_count(int count) { argument_count_ = count; }
94b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  int first_instruction_index() const { return first_instruction_index_; }
95b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void set_first_instruction_index(int index) {
96b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    first_instruction_index_ = index;
97b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
98b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  int last_instruction_index() const { return last_instruction_index_; }
99b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void set_last_instruction_index(int index) {
100b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    last_instruction_index_ = index;
101b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool is_osr_entry() { return is_osr_entry_; }
103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void set_osr_entry() { is_osr_entry_ = true; }
104b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
105b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void AttachLoopInformation();
106b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void DetachLoopInformation();
107b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  bool IsLoopHeader() const { return loop_information() != NULL; }
108b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  bool IsStartBlock() const { return block_id() == 0; }
109b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void PostProcessLoopHeader(IterationStatement* stmt);
110b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
111b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  bool IsFinished() const { return end_ != NULL; }
112b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void AddPhi(HPhi* phi);
113b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void RemovePhi(HPhi* phi);
114014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void AddInstruction(HInstruction* instr, SourcePosition position);
115b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  bool Dominates(HBasicBlock* other) const;
116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool EqualToOrDominates(HBasicBlock* other) const;
117589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  int LoopNestingDepth() const;
118b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
119b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void SetInitialEnvironment(HEnvironment* env);
120b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void ClearEnvironment() {
121b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(IsFinished());
122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(end()->SuccessorCount() == 0);
123b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    last_environment_ = NULL;
124b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
125b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  bool HasEnvironment() const { return last_environment_ != NULL; }
126b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void UpdateEnvironment(HEnvironment* env);
1271e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  HBasicBlock* parent_loop_header() const { return parent_loop_header_; }
128b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
129b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void set_parent_loop_header(HBasicBlock* block) {
130b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(parent_loop_header_ == NULL);
1311e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    parent_loop_header_ = block;
132b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
133b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1341e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  bool HasParentLoopHeader() const { return parent_loop_header_ != NULL; }
135b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void SetJoinId(BailoutId ast_id);
137b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
138b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  int PredecessorIndexOf(HBasicBlock* predecessor) const;
139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HPhi* AddNewPhi(int merged_index);
140014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HSimulate* AddNewSimulate(BailoutId ast_id, SourcePosition position,
141b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                            RemovableSimulate removable = FIXED_SIMULATE) {
142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    HSimulate* instr = CreateSimulate(ast_id, removable);
143b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    AddInstruction(instr, position);
144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return instr;
145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
146b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void AssignCommonDominator(HBasicBlock* other);
1473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void AssignLoopSuccessorDominators();
148b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
149b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // If a target block is tagged as an inline function return, all
150b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // predecessors should contain the inlined exit sequence:
151b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  //
152b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // LeaveInlined
153b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Simulate (caller's environment)
154b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Goto (target block)
155b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  bool IsInlineReturnTarget() const { return is_inline_return_target_; }
156b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void MarkAsInlineReturnTarget(HBasicBlock* inlined_entry_block) {
157b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    is_inline_return_target_ = true;
158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    inlined_entry_block_ = inlined_entry_block;
159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HBasicBlock* inlined_entry_block() { return inlined_entry_block_; }
161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
162b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool IsDeoptimizing() const {
163b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return end() != NULL && end()->IsDeoptimize();
164b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
165b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void MarkUnreachable();
167b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool IsUnreachable() const { return !is_reachable_; }
168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool IsReachable() const { return is_reachable_; }
1693fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
1703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  bool IsLoopSuccessorDominator() const {
1713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    return dominates_loop_successors_;
1723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
1733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void MarkAsLoopSuccessorDominator() {
1743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    dominates_loop_successors_ = true;
1753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
1763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
177b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool IsOrdered() const { return is_ordered_; }
178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void MarkAsOrdered() { is_ordered_ = true; }
179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
180b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void MarkSuccEdgeUnreachable(int succ);
181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
182b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  inline Zone* zone() const;
1838b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
184b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#ifdef DEBUG
185b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void Verify();
186b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#endif
187b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
188b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch protected:
189b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  friend class HGraphBuilder;
190b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
191b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HSimulate* CreateSimulate(BailoutId ast_id, RemovableSimulate removable);
192014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void Finish(HControlInstruction* last, SourcePosition position);
193014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void FinishExit(HControlInstruction* instruction, SourcePosition position);
194014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void Goto(HBasicBlock* block, SourcePosition position,
195014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            FunctionState* state = NULL, bool add_simulate = true);
196014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void GotoNoSimulate(HBasicBlock* block, SourcePosition position) {
197b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Goto(block, position, NULL, false);
198b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
199b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
200b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Add the inlined function exit sequence, adding an HLeaveInlined
201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // instruction and updating the bailout environment.
202014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void AddLeaveInlined(HValue* return_value, FunctionState* state,
203014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                       SourcePosition position);
204b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
205b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch private:
206b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void RegisterPredecessor(HBasicBlock* pred);
207b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void AddDominatedBlock(HBasicBlock* block);
208b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
209b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  int block_id_;
210b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  HGraph* graph_;
211b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  ZoneList<HPhi*> phis_;
212b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  HInstruction* first_;
213e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  HInstruction* last_;
214b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  HControlInstruction* end_;
215b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  HLoopInformation* loop_information_;
216b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  ZoneList<HBasicBlock*> predecessors_;
217b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  HBasicBlock* dominator_;
218b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  ZoneList<HBasicBlock*> dominated_blocks_;
219b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  HEnvironment* last_environment_;
220b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Outgoing parameter count at block exit, set during lithium translation.
221b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  int argument_count_;
222b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Instruction indices into the lithium code stream.
223b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  int first_instruction_index_;
224b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  int last_instruction_index_;
225b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  ZoneList<int> deleted_phis_;
2261e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  HBasicBlock* parent_loop_header_;
227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // For blocks marked as inline return target: the block with HEnterInlined.
228b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HBasicBlock* inlined_entry_block_;
229b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool is_inline_return_target_ : 1;
230b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool is_reachable_ : 1;
231b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool dominates_loop_successors_ : 1;
232b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool is_osr_entry_ : 1;
233b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool is_ordered_ : 1;
2343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch};
2353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
2363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
237958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierstd::ostream& operator<<(std::ostream& os, const HBasicBlock& b);
238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
240014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass HPredecessorIterator final BASE_EMBEDDED {
2413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch public:
2423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  explicit HPredecessorIterator(HBasicBlock* block)
2433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      : predecessor_list_(block->predecessors()), current_(0) { }
2443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
2453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  bool Done() { return current_ >= predecessor_list_->length(); }
2463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  HBasicBlock* Current() { return predecessor_list_->at(current_); }
2473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void Advance() { current_++; }
2483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
2493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch private:
2503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  const ZoneList<HBasicBlock*>* predecessor_list_;
2513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  int current_;
252b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch};
253b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
254b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
255014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass HInstructionIterator final BASE_EMBEDDED {
256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public:
257b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  explicit HInstructionIterator(HBasicBlock* block)
258b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      : instr_(block->first()) {
259b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    next_ = Done() ? NULL : instr_->next();
260b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
261b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
262b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  inline bool Done() const { return instr_ == NULL; }
263b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  inline HInstruction* Current() { return instr_; }
264b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  inline void Advance() {
265b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    instr_ = next_;
266b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    next_ = Done() ? NULL : instr_->next();
267b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
268b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
269b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private:
270b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HInstruction* instr_;
271b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HInstruction* next_;
272b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
273b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
274b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
275014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass HLoopInformation final : public ZoneObject {
276b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch public:
277b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HLoopInformation(HBasicBlock* loop_header, Zone* zone)
278b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      : back_edges_(4, zone),
2793fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch        loop_header_(loop_header),
280b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        blocks_(8, zone),
2813fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch        stack_check_(NULL) {
282b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    blocks_.Add(loop_header, zone);
283b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
284b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ~HLoopInformation() {}
285b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
286b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  const ZoneList<HBasicBlock*>* back_edges() const { return &back_edges_; }
287b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  const ZoneList<HBasicBlock*>* blocks() const { return &blocks_; }
288b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  HBasicBlock* loop_header() const { return loop_header_; }
289b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  HBasicBlock* GetLastBackEdge() const;
290b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void RegisterBackEdge(HBasicBlock* block);
291b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2923fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  HStackCheck* stack_check() const { return stack_check_; }
2933fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  void set_stack_check(HStackCheck* stack_check) {
2943fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    stack_check_ = stack_check;
2953fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  }
2963fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
297b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool IsNestedInThisLoop(HLoopInformation* other) {
298b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    while (other != NULL) {
299b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (other == this) {
300b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        return true;
301b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
302b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      other = other->parent_loop();
303b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
304b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return false;
305b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
306b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HLoopInformation* parent_loop() {
307b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    HBasicBlock* parent_header = loop_header()->parent_loop_header();
308b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return parent_header != NULL ? parent_header->loop_information() : NULL;
309b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
310b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
311b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch private:
312b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void AddBlock(HBasicBlock* block);
313b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
314b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  ZoneList<HBasicBlock*> back_edges_;
315b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  HBasicBlock* loop_header_;
316b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  ZoneList<HBasicBlock*> blocks_;
3173fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  HStackCheck* stack_check_;
318b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch};
319b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
320537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdochstruct HInlinedFunctionInfo {
321537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch  explicit HInlinedFunctionInfo(int start_position)
322537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch      : start_position(start_position) {}
323537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch  int start_position;
324537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch};
325b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
326014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass HGraph final : public ZoneObject {
327b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch public:
328342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch  explicit HGraph(CompilationInfo* info, CallInterfaceDescriptor descriptor);
329b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
330b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Isolate* isolate() const { return isolate_; }
331b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Zone* zone() const { return zone_; }
332b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CompilationInfo* info() const { return info_; }
333342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch  CallInterfaceDescriptor descriptor() const { return descriptor_; }
3348b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
335b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  const ZoneList<HBasicBlock*>* blocks() const { return &blocks_; }
336b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  const ZoneList<HPhi*>* phi_list() const { return phi_list_; }
33744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  HBasicBlock* entry_block() const { return entry_block_; }
338b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  HEnvironment* start_environment() const { return start_environment_; }
339b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
340b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void FinalizeUniqueness();
341b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void OrderBlocks();
342b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void AssignDominators();
343b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void RestoreActualValues();
344b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
345b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Returns false if there are phi-uses of the arguments-object
346b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // which are not supported by the optimizing compiler.
3473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  bool CheckArgumentsPhiUses();
3483fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
3493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Returns false if there are phi-uses of an uninitialized const
3503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // which are not supported by the optimizing compiler.
3513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  bool CheckConstPhiUses();
3523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void CollectPhis();
354b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
355b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HConstant* GetConstantUndefined();
356b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HConstant* GetConstant0();
357b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  HConstant* GetConstant1();
358b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  HConstant* GetConstantMinus1();
359b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  HConstant* GetConstantTrue();
360b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  HConstant* GetConstantFalse();
361014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HConstant* GetConstantBool(bool value);
3623fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  HConstant* GetConstantHole();
363b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HConstant* GetConstantNull();
3641b268ca467c924004286c97bac133db489cf43d0Ben Murdoch  HConstant* GetConstantOptimizedOut();
365b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HConstant* GetInvalidContext();
366b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
367b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool IsConstantUndefined(HConstant* constant);
368b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool IsConstant0(HConstant* constant);
369b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool IsConstant1(HConstant* constant);
370b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool IsConstantMinus1(HConstant* constant);
371b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool IsConstantTrue(HConstant* constant);
372b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool IsConstantFalse(HConstant* constant);
373b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool IsConstantHole(HConstant* constant);
374b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool IsConstantNull(HConstant* constant);
375b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool IsStandardConstant(HConstant* constant);
376b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
377b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  HBasicBlock* CreateBasicBlock();
378b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
379b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  int GetMaximumValueID() const { return values_.length(); }
380b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  int GetNextBlockID() { return next_block_id_++; }
381b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  int GetNextValueID(HValue* value) {
382b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(!disallow_adding_new_values_);
383b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    values_.Add(value, zone());
384b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    return values_.length() - 1;
385b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
386b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  HValue* LookupValue(int id) const {
387b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    if (id >= 0 && id < values_.length()) return values_[id];
388b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    return NULL;
389b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
390b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void DisallowAddingNewValues() {
391b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    disallow_adding_new_values_ = true;
392b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
393b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
394b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool Optimize(BailoutReason* bailout_reason);
395b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
396b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#ifdef DEBUG
3973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void Verify(bool do_full_verify) const;
398b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#endif
399b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
400b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool has_osr() {
401b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return osr_ != NULL;
402b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
403b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
404b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void set_osr(HOsrBuilder* osr) {
405b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    osr_ = osr;
406b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
407b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
408b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HOsrBuilder* osr() {
409b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return osr_;
410b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
411b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
412b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int update_type_change_checksum(int delta) {
413b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    type_change_checksum_ += delta;
414b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return type_change_checksum_;
415b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
416b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
417b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void update_maximum_environment_size(int environment_size) {
418b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (environment_size > maximum_environment_size_) {
419b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      maximum_environment_size_ = environment_size;
420b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
421b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
422b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int maximum_environment_size() { return maximum_environment_size_; }
423b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
424537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch  bool allow_code_motion() const { return allow_code_motion_; }
425537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch  void set_allow_code_motion(bool value) { allow_code_motion_ = value; }
426b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
427537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch  bool use_optimistic_licm() const { return use_optimistic_licm_; }
428537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch  void set_use_optimistic_licm(bool value) { use_optimistic_licm_ = value; }
4293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
430b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void MarkDependsOnEmptyArrayProtoElements() {
431b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Add map dependency if not already added.
432b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (depends_on_empty_array_proto_elements_) return;
433014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    info()->dependencies()->AssumePropertyCell(
434014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        isolate()->factory()->array_protector());
435b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    depends_on_empty_array_proto_elements_ = true;
4363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
4373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
438b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool depends_on_empty_array_proto_elements() {
439b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return depends_on_empty_array_proto_elements_;
4403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
4413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
442b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool has_uint32_instructions() {
443b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(uint32_instructions_ == NULL || !uint32_instructions_->is_empty());
444b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return uint32_instructions_ != NULL;
445b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
446b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
447b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ZoneList<HInstruction*>* uint32_instructions() {
448b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(uint32_instructions_ == NULL || !uint32_instructions_->is_empty());
449b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return uint32_instructions_;
450b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
451b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
452b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void RecordUint32Instruction(HInstruction* instr) {
453b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(uint32_instructions_ == NULL || !uint32_instructions_->is_empty());
454b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (uint32_instructions_ == NULL) {
455b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      uint32_instructions_ = new(zone()) ZoneList<HInstruction*>(4, zone());
456b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
457b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    uint32_instructions_->Add(instr, zone());
458b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
459b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
460b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void IncrementInNoSideEffectsScope() { no_side_effects_scope_count_++; }
461b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void DecrementInNoSideEffectsScope() { no_side_effects_scope_count_--; }
462b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool IsInsideNoSideEffectsScope() { return no_side_effects_scope_count_ > 0; }
463b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
464b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // If we are tracking source positions then this function assigns a unique
465b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // identifier to each inlining and dumps function source if it was inlined
466b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // for the first time during the current optimization.
467b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int TraceInlinedFunction(Handle<SharedFunctionInfo> shared,
468014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                           SourcePosition position);
469b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
470014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Converts given SourcePosition to the absolute offset from the start of
471b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // the corresponding script.
472014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int SourcePositionToScriptPosition(SourcePosition position);
473b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
474537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch  ZoneVector<HInlinedFunctionInfo>& inlined_function_infos() {
475537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch    return inlined_function_infos_;
476537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch  }
477537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch
478b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch private:
479b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HConstant* ReinsertConstantIfNecessary(HConstant* constant);
480b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  HConstant* GetConstant(SetOncePointer<HConstant>* pointer,
481b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                         int32_t integer_value);
482b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
483b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  template<class Phase>
484b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void Run() {
485b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Phase phase(this);
486b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    phase.Run();
487b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
488b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
48944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Isolate* isolate_;
490b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  int next_block_id_;
49144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  HBasicBlock* entry_block_;
492b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  HEnvironment* start_environment_;
493b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  ZoneList<HBasicBlock*> blocks_;
494b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  ZoneList<HValue*> values_;
495b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  ZoneList<HPhi*>* phi_list_;
496b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ZoneList<HInstruction*>* uint32_instructions_;
497b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  SetOncePointer<HConstant> constant_undefined_;
498b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  SetOncePointer<HConstant> constant_0_;
499b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  SetOncePointer<HConstant> constant_1_;
500b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  SetOncePointer<HConstant> constant_minus1_;
501b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  SetOncePointer<HConstant> constant_true_;
502b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  SetOncePointer<HConstant> constant_false_;
503b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  SetOncePointer<HConstant> constant_the_hole_;
504b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  SetOncePointer<HConstant> constant_null_;
5051b268ca467c924004286c97bac133db489cf43d0Ben Murdoch  SetOncePointer<HConstant> constant_optimized_out_;
506b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  SetOncePointer<HConstant> constant_invalid_context_;
507b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
508b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HOsrBuilder* osr_;
509b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
510b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CompilationInfo* info_;
511342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch  CallInterfaceDescriptor descriptor_;
512b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Zone* zone_;
513b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
514537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch  bool allow_code_motion_;
515b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool use_optimistic_licm_;
516b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool depends_on_empty_array_proto_elements_;
517b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int type_change_checksum_;
518b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int maximum_environment_size_;
519b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int no_side_effects_scope_count_;
520b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool disallow_adding_new_values_;
521b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
522537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch  ZoneVector<HInlinedFunctionInfo> inlined_function_infos_;
523537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch
524b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  DISALLOW_COPY_AND_ASSIGN(HGraph);
525b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch};
526b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
527b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
528b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochZone* HBasicBlock::zone() const { return graph_->zone(); }
5298b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
5308b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
5313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Type of stack frame an environment might refer to.
532b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochenum FrameType {
533b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  JS_FUNCTION,
534b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  JS_CONSTRUCT,
535b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  JS_GETTER,
536b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  JS_SETTER,
537b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ARGUMENTS_ADAPTOR,
5381b268ca467c924004286c97bac133db489cf43d0Ben Murdoch  TAIL_CALLER_FUNCTION,
539b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  STUB
540b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
5413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
542014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass HEnvironment final : public ZoneObject {
543b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch public:
544b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  HEnvironment(HEnvironment* outer,
545b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch               Scope* scope,
546b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch               Handle<JSFunction> closure,
547b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch               Zone* zone);
548b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
549b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HEnvironment(Zone* zone, int parameter_count);
5503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
5513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  HEnvironment* arguments_environment() {
5523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    return outer()->frame_type() == ARGUMENTS_ADAPTOR ? outer() : this;
5533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
5543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
5559fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block  // Simple accessors.
5569fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block  Handle<JSFunction> closure() const { return closure_; }
5579fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block  const ZoneList<HValue*>* values() const { return &values_; }
558b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const GrowableBitVector* assigned_variables() const {
5599fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block    return &assigned_variables_;
5609fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block  }
5613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  FrameType frame_type() const { return frame_type_; }
5629fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block  int parameter_count() const { return parameter_count_; }
563257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  int specials_count() const { return specials_count_; }
5649fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block  int local_count() const { return local_count_; }
5659fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block  HEnvironment* outer() const { return outer_; }
5669fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block  int pop_count() const { return pop_count_; }
5679fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block  int push_count() const { return push_count_; }
5689fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block
569b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  BailoutId ast_id() const { return ast_id_; }
570b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void set_ast_id(BailoutId id) { ast_id_ = id; }
571b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
572b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HEnterInlined* entry() const { return entry_; }
573b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void set_entry(HEnterInlined* entry) { entry_ = entry; }
5749fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block
5759fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block  int length() const { return values_.length(); }
5769fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block
5773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  int first_expression_index() const {
5783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    return parameter_count() + specials_count() + local_count();
5793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
5803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
581b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int first_local_index() const {
582b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return parameter_count() + specials_count();
583b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
584b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
585b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void Bind(Variable* variable, HValue* value) {
586b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    Bind(IndexFor(variable), value);
587b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
588b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
5899fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block  void Bind(int index, HValue* value);
590b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
591257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  void BindContext(HValue* value) {
592257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    Bind(parameter_count(), value);
593257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
594257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
595b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  HValue* Lookup(Variable* variable) const {
596b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    return Lookup(IndexFor(variable));
597b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
5989fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block
599b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  HValue* Lookup(int index) const {
600b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    HValue* result = values_[index];
601b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(result != NULL);
602b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    return result;
603b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
604b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
605b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HValue* context() const {
606257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    // Return first special.
607257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    return Lookup(parameter_count());
608257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
609257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
610b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void Push(HValue* value) {
611b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(value != NULL);
612b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    ++push_count_;
613b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    values_.Add(value, zone());
614b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
615b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
616b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  HValue* Pop() {
617b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(!ExpressionStackIsEmpty());
618b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    if (push_count_ > 0) {
619b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      --push_count_;
620b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    } else {
621b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      ++pop_count_;
622b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    }
623b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    return values_.RemoveLast();
624b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
625b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
6269fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block  void Drop(int count);
627b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
6289fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block  HValue* Top() const { return ExpressionStackAt(0); }
629b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
630257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  bool ExpressionStackIsEmpty() const;
631257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
6329fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block  HValue* ExpressionStackAt(int index_from_top) const {
6339fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block    int index = length() - index_from_top - 1;
634b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(HasExpressionAt(index));
6359fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block    return values_[index];
636b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
6379fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block
6389fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block  void SetExpressionStackAt(int index_from_top, HValue* value);
639958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  HValue* RemoveExpressionStackAt(int index_from_top);
6409fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block
641014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void Print() const;
642014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
643b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  HEnvironment* Copy() const;
644b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  HEnvironment* CopyWithoutHistory() const;
645b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  HEnvironment* CopyAsLoopHeader(HBasicBlock* block) const;
646b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
647b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Create an "inlined version" of this environment, where the original
648b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // environment is the outer environment but the top expression stack
6493fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // elements are moved to an inner environment as parameters.
6501b268ca467c924004286c97bac133db489cf43d0Ben Murdoch  HEnvironment* CopyForInlining(Handle<JSFunction> target, int arguments,
6511b268ca467c924004286c97bac133db489cf43d0Ben Murdoch                                FunctionLiteral* function, HConstant* undefined,
6521b268ca467c924004286c97bac133db489cf43d0Ben Murdoch                                InliningKind inlining_kind,
6531b268ca467c924004286c97bac133db489cf43d0Ben Murdoch                                TailCallMode syntactic_tail_call_mode) const;
654b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
655b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HEnvironment* DiscardInlined(bool drop_extra) {
656b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    HEnvironment* outer = outer_;
6571b268ca467c924004286c97bac133db489cf43d0Ben Murdoch    while (outer->frame_type() != JS_FUNCTION &&
6581b268ca467c924004286c97bac133db489cf43d0Ben Murdoch           outer->frame_type() != TAIL_CALLER_FUNCTION) {
6591b268ca467c924004286c97bac133db489cf43d0Ben Murdoch      outer = outer->outer_;
6601b268ca467c924004286c97bac133db489cf43d0Ben Murdoch    }
661b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (drop_extra) outer->Drop(1);
6621b268ca467c924004286c97bac133db489cf43d0Ben Murdoch    if (outer->frame_type() == TAIL_CALLER_FUNCTION) {
6631b268ca467c924004286c97bac133db489cf43d0Ben Murdoch      outer->ClearTailCallerMark();
6641b268ca467c924004286c97bac133db489cf43d0Ben Murdoch    }
665b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return outer;
666b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
667b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
668b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void AddIncomingEdge(HBasicBlock* block, HEnvironment* other);
6699fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block
670b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void ClearHistory() {
671b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    pop_count_ = 0;
672b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    push_count_ = 0;
673b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    assigned_variables_.Clear();
674b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
6759fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block
676b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void SetValueAt(int index, HValue* value) {
677b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(index < length());
678b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    values_[index] = value;
679b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
680b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
681b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Map a variable to an environment index.  Parameter indices are shifted
682b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // by 1 (receiver is parameter index -1 but environment index 0).
683b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Stack-allocated local indices are shifted by the number of parameters.
684b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int IndexFor(Variable* variable) const {
685b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(variable->IsStackAllocated());
686b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    int shift = variable->IsParameter()
687b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        ? 1
688b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        : parameter_count_ + specials_count_;
689b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return variable->index() + shift;
690b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
691b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
692b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool is_local_index(int i) const {
693b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return i >= first_local_index() && i < first_expression_index();
694b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
695b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
696b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool is_parameter_index(int i) const {
697b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return i >= 0 && i < parameter_count();
698b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
699b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
700b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool is_special_index(int i) const {
701b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return i >= parameter_count() && i < parameter_count() + specials_count();
702b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
703b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
704b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Zone* zone() const { return zone_; }
705b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
706b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch private:
707b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HEnvironment(const HEnvironment* other, Zone* zone);
708b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
7093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  HEnvironment(HEnvironment* outer,
7103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch               Handle<JSFunction> closure,
7113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch               FrameType frame_type,
712b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch               int arguments,
713b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch               Zone* zone);
7143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
7153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Create an artificial stub environment (e.g. for argument adaptor or
7163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // constructor stub).
7173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  HEnvironment* CreateStubEnvironment(HEnvironment* outer,
7183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                      Handle<JSFunction> target,
7193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                      FrameType frame_type,
7203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                      int arguments) const;
7213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
7221b268ca467c924004286c97bac133db489cf43d0Ben Murdoch  // Marks current environment as tail caller by setting frame type to
7231b268ca467c924004286c97bac133db489cf43d0Ben Murdoch  // TAIL_CALLER_FUNCTION.
7241b268ca467c924004286c97bac133db489cf43d0Ben Murdoch  void MarkAsTailCaller();
7251b268ca467c924004286c97bac133db489cf43d0Ben Murdoch  void ClearTailCallerMark();
7261b268ca467c924004286c97bac133db489cf43d0Ben Murdoch
7279fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block  // True if index is included in the expression stack part of the environment.
7289fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block  bool HasExpressionAt(int index) const;
7299fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block
730b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void Initialize(int parameter_count, int local_count, int stack_height);
731b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void Initialize(const HEnvironment* other);
7329fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block
733b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  Handle<JSFunction> closure_;
734257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // Value array [parameters] [specials] [locals] [temporaries].
735b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  ZoneList<HValue*> values_;
736b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GrowableBitVector assigned_variables_;
7373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  FrameType frame_type_;
738b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  int parameter_count_;
739257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  int specials_count_;
740b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  int local_count_;
741b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  HEnvironment* outer_;
742b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HEnterInlined* entry_;
743b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  int pop_count_;
744b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  int push_count_;
745b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  BailoutId ast_id_;
746b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Zone* zone_;
747b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch};
748b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
749b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
750958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierstd::ostream& operator<<(std::ostream& os, const HEnvironment& env);
751b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
752b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
753b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass HOptimizedGraphBuilder;
754b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
755257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochenum ArgumentsAllowedFlag {
756257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  ARGUMENTS_NOT_ALLOWED,
757958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  ARGUMENTS_ALLOWED,
758958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  ARGUMENTS_FAKED
759257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch};
760257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
761b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
762b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass HIfContinuation;
763b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
764e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch// This class is not BASE_EMBEDDED because our inlining implementation uses
765e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch// new and delete.
766b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochclass AstContext {
767b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch public:
768b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  bool IsEffect() const { return kind_ == Expression::kEffect; }
769b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  bool IsValue() const { return kind_ == Expression::kValue; }
770b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  bool IsTest() const { return kind_ == Expression::kTest; }
771b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
772b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // 'Fill' this context with a hydrogen value.  The value is assumed to
773b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // have already been inserted in the instruction stream (or not need to
774b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // be, e.g., HPhi).  Call this function in tail position in the Visit
775b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // functions for expressions.
776b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  virtual void ReturnValue(HValue* value) = 0;
777b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
778b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Add a hydrogen instruction to the instruction stream (recording an
779b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // environment simulation if necessary) and then fill this context with
780b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // the instruction as value.
781b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  virtual void ReturnInstruction(HInstruction* instr, BailoutId ast_id) = 0;
782b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
7833fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // Finishes the current basic block and materialize a boolean for
7843fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // value context, nothing for effect, generate a branch for test context.
7853fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // Call this function in tail position in the Visit functions for
7863fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // expressions.
787b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  virtual void ReturnControl(HControlInstruction* instr, BailoutId ast_id) = 0;
788b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
789b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Finishes the current basic block and materialize a boolean for
790b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // value context, nothing for effect, generate a branch for test context.
791b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Call this function in tail position in the Visit functions for
792b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // expressions that use an IfBuilder.
793b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  virtual void ReturnContinuation(HIfContinuation* continuation,
794b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                  BailoutId ast_id) = 0;
7953fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
796014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void set_typeof_mode(TypeofMode typeof_mode) { typeof_mode_ = typeof_mode; }
797014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TypeofMode typeof_mode() { return typeof_mode_; }
7988b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
799b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch protected:
800b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  AstContext(HOptimizedGraphBuilder* owner, Expression::Context kind);
801b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  virtual ~AstContext();
802b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
803b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HOptimizedGraphBuilder* owner() const { return owner_; }
804b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
805b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  inline Zone* zone() const;
8068b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
807b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // We want to be able to assert, in a context-specific way, that the stack
808b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // height makes sense when the context is filled.
809b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#ifdef DEBUG
8109fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block  int original_length_;
811b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#endif
812b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
813b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch private:
814b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HOptimizedGraphBuilder* owner_;
815b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  Expression::Context kind_;
816b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  AstContext* outer_;
817014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TypeofMode typeof_mode_;
818b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch};
819b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
820b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
821014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass EffectContext final : public AstContext {
822b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch public:
823b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  explicit EffectContext(HOptimizedGraphBuilder* owner)
824b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      : AstContext(owner, Expression::kEffect) {
825b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
826014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  ~EffectContext() override;
827b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
828014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void ReturnValue(HValue* value) override;
829014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void ReturnInstruction(HInstruction* instr, BailoutId ast_id) override;
830014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void ReturnControl(HControlInstruction* instr, BailoutId ast_id) override;
831014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void ReturnContinuation(HIfContinuation* continuation,
832014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                          BailoutId ast_id) override;
833b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch};
834b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
835b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
836014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass ValueContext final : public AstContext {
837b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch public:
838b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ValueContext(HOptimizedGraphBuilder* owner, ArgumentsAllowedFlag flag)
839257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      : AstContext(owner, Expression::kValue), flag_(flag) {
840b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
841014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  ~ValueContext() override;
842b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
843014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void ReturnValue(HValue* value) override;
844014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void ReturnInstruction(HInstruction* instr, BailoutId ast_id) override;
845014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void ReturnControl(HControlInstruction* instr, BailoutId ast_id) override;
846014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void ReturnContinuation(HIfContinuation* continuation,
847014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                          BailoutId ast_id) override;
848257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
849257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  bool arguments_allowed() { return flag_ == ARGUMENTS_ALLOWED; }
850257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
851257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch private:
852257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  ArgumentsAllowedFlag flag_;
853b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch};
854b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
855b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
856014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass TestContext final : public AstContext {
857b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch public:
858b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  TestContext(HOptimizedGraphBuilder* owner,
8593fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch              Expression* condition,
860b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch              HBasicBlock* if_true,
861b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch              HBasicBlock* if_false)
862b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      : AstContext(owner, Expression::kTest),
8633fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch        condition_(condition),
864b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch        if_true_(if_true),
865b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch        if_false_(if_false) {
866b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
867b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
868014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void ReturnValue(HValue* value) override;
869014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void ReturnInstruction(HInstruction* instr, BailoutId ast_id) override;
870014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void ReturnControl(HControlInstruction* instr, BailoutId ast_id) override;
871014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void ReturnContinuation(HIfContinuation* continuation,
872014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                          BailoutId ast_id) override;
873b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
874b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  static TestContext* cast(AstContext* context) {
875b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(context->IsTest());
876b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    return reinterpret_cast<TestContext*>(context);
877b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
878b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
8793fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  Expression* condition() const { return condition_; }
880b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  HBasicBlock* if_true() const { return if_true_; }
881b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  HBasicBlock* if_false() const { return if_false_; }
882b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
883b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch private:
884b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Build the shared core part of the translation unpacking a value into
885b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // control flow.
886b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void BuildBranch(HValue* value);
887b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
8883fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  Expression* condition_;
889b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  HBasicBlock* if_true_;
890b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  HBasicBlock* if_false_;
891b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch};
892b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
893b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
894014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass FunctionState final {
895e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch public:
8961b268ca467c924004286c97bac133db489cf43d0Ben Murdoch  FunctionState(HOptimizedGraphBuilder* owner, CompilationInfo* info,
8971b268ca467c924004286c97bac133db489cf43d0Ben Murdoch                InliningKind inlining_kind, int inlining_id,
8981b268ca467c924004286c97bac133db489cf43d0Ben Murdoch                TailCallMode tail_call_mode);
899e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  ~FunctionState();
900e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
901e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  CompilationInfo* compilation_info() { return compilation_info_; }
902e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  AstContext* call_context() { return call_context_; }
903b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  InliningKind inlining_kind() const { return inlining_kind_; }
904e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  HBasicBlock* function_return() { return function_return_; }
905e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  TestContext* test_context() { return test_context_; }
906e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  void ClearInlinedTestContext() {
907e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch    delete test_context_;
908e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch    test_context_ = NULL;
909e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  }
910e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
9118b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  FunctionState* outer() { return outer_; }
9128b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
9131b268ca467c924004286c97bac133db489cf43d0Ben Murdoch  TailCallMode ComputeTailCallMode(TailCallMode tail_call_mode) const {
9141b268ca467c924004286c97bac133db489cf43d0Ben Murdoch    if (tail_call_mode_ == TailCallMode::kDisallow) return tail_call_mode_;
9151b268ca467c924004286c97bac133db489cf43d0Ben Murdoch    return tail_call_mode;
9161b268ca467c924004286c97bac133db489cf43d0Ben Murdoch  }
9171b268ca467c924004286c97bac133db489cf43d0Ben Murdoch
918b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HEnterInlined* entry() { return entry_; }
919b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void set_entry(HEnterInlined* entry) { entry_ = entry; }
920b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
921b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HArgumentsObject* arguments_object() { return arguments_object_; }
922b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void set_arguments_object(HArgumentsObject* arguments_object) {
923b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    arguments_object_ = arguments_object;
924b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
925b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
926b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HArgumentsElements* arguments_elements() { return arguments_elements_; }
927b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void set_arguments_elements(HArgumentsElements* arguments_elements) {
928b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    arguments_elements_ = arguments_elements;
929b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
930b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
931b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool arguments_pushed() { return arguments_elements() != NULL; }
932b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
933b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int inlining_id() const { return inlining_id_; }
934b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
9351b268ca467c924004286c97bac133db489cf43d0Ben Murdoch  void IncrementInDoExpressionScope() { do_expression_scope_count_++; }
9361b268ca467c924004286c97bac133db489cf43d0Ben Murdoch  void DecrementInDoExpressionScope() { do_expression_scope_count_--; }
9371b268ca467c924004286c97bac133db489cf43d0Ben Murdoch  bool IsInsideDoExpressionScope() { return do_expression_scope_count_ > 0; }
9381b268ca467c924004286c97bac133db489cf43d0Ben Murdoch
939e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch private:
940b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HOptimizedGraphBuilder* owner_;
941e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
942e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  CompilationInfo* compilation_info_;
943e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
944e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  // During function inlining, expression context of the call being
945e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  // inlined. NULL when not inlining.
946e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  AstContext* call_context_;
947e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
948b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // The kind of call which is currently being inlined.
949b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  InliningKind inlining_kind_;
9503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
9511b268ca467c924004286c97bac133db489cf43d0Ben Murdoch  // Defines whether the calls with TailCallMode::kAllow in the function body
9521b268ca467c924004286c97bac133db489cf43d0Ben Murdoch  // can be generated as tail calls.
9531b268ca467c924004286c97bac133db489cf43d0Ben Murdoch  TailCallMode tail_call_mode_;
9541b268ca467c924004286c97bac133db489cf43d0Ben Murdoch
9553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // When inlining in an effect or value context, this is the return block.
956e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  // It is NULL otherwise.  When inlining in a test context, there are a
957e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  // pair of return blocks in the context.  When not inlining, there is no
958e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  // local return point.
959e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  HBasicBlock* function_return_;
960e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
961e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  // When inlining a call in a test context, a context containing a pair of
962e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  // return blocks.  NULL in all other cases.
963e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  TestContext* test_context_;
964e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
965b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // When inlining HEnterInlined instruction corresponding to the function
966b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // entry.
967b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HEnterInlined* entry_;
968b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
969b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HArgumentsObject* arguments_object_;
970b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HArgumentsElements* arguments_elements_;
971b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
972b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int inlining_id_;
973014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  SourcePosition outer_source_position_;
974b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
9751b268ca467c924004286c97bac133db489cf43d0Ben Murdoch  int do_expression_scope_count_;
9761b268ca467c924004286c97bac133db489cf43d0Ben Murdoch
977e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  FunctionState* outer_;
978e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch};
979e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
980e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
981014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass HIfContinuation final {
982b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch public:
983b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HIfContinuation()
984b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    : continuation_captured_(false),
985b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      true_branch_(NULL),
986b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      false_branch_(NULL) {}
987b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HIfContinuation(HBasicBlock* true_branch,
988b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                  HBasicBlock* false_branch)
989b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      : continuation_captured_(true), true_branch_(true_branch),
990b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        false_branch_(false_branch) {}
991b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ~HIfContinuation() { DCHECK(!continuation_captured_); }
992e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
993b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void Capture(HBasicBlock* true_branch,
994b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch               HBasicBlock* false_branch) {
995b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(!continuation_captured_);
996b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    true_branch_ = true_branch;
997b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    false_branch_ = false_branch;
998b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    continuation_captured_ = true;
999b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1000e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
1001b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void Continue(HBasicBlock** true_branch,
1002b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                HBasicBlock** false_branch) {
1003b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(continuation_captured_);
1004b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    *true_branch = true_branch_;
1005b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    *false_branch = false_branch_;
1006b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    continuation_captured_ = false;
1007b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1008e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
1009b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool IsTrueReachable() { return true_branch_ != NULL; }
1010b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool IsFalseReachable() { return false_branch_ != NULL; }
1011b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool TrueAndFalseReachable() {
1012b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return IsTrueReachable() || IsFalseReachable();
1013b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1014e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
1015b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HBasicBlock* true_branch() const { return true_branch_; }
1016b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HBasicBlock* false_branch() const { return false_branch_; }
1017e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
1018b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private:
1019b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool continuation_captured_;
1020b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HBasicBlock* true_branch_;
1021b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HBasicBlock* false_branch_;
1022b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
1023e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
1024e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
1025014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass HAllocationMode final BASE_EMBEDDED {
1026b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public:
1027b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  explicit HAllocationMode(Handle<AllocationSite> feedback_site)
1028b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      : current_site_(NULL), feedback_site_(feedback_site),
1029b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        pretenure_flag_(NOT_TENURED) {}
1030b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  explicit HAllocationMode(HValue* current_site)
1031b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      : current_site_(current_site), pretenure_flag_(NOT_TENURED) {}
1032b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  explicit HAllocationMode(PretenureFlag pretenure_flag)
1033b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      : current_site_(NULL), pretenure_flag_(pretenure_flag) {}
1034b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HAllocationMode()
1035b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      : current_site_(NULL), pretenure_flag_(NOT_TENURED) {}
1036e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
1037b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HValue* current_site() const { return current_site_; }
1038b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Handle<AllocationSite> feedback_site() const { return feedback_site_; }
1039e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
1040b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool CreateAllocationMementos() const WARN_UNUSED_RESULT {
1041b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return current_site() != NULL;
1042b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1043b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1044b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  PretenureFlag GetPretenureMode() const WARN_UNUSED_RESULT {
1045b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (!feedback_site().is_null()) return feedback_site()->GetPretenureMode();
1046b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return pretenure_flag_;
1047b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1048b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1049b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private:
1050b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HValue* current_site_;
1051b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Handle<AllocationSite> feedback_site_;
1052b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  PretenureFlag pretenure_flag_;
1053b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
1054b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1055b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1056b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass HGraphBuilder {
1057b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public:
1058342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch  explicit HGraphBuilder(CompilationInfo* info,
1059342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch                         CallInterfaceDescriptor descriptor)
1060b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      : info_(info),
1061342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch        descriptor_(descriptor),
1062b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        graph_(NULL),
1063b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        current_block_(NULL),
1064b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        scope_(info->scope()),
1065014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        position_(SourcePosition::Unknown()),
1066b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        start_position_(0) {}
1067b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  virtual ~HGraphBuilder() {}
1068b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1069b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Scope* scope() const { return scope_; }
1070b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void set_scope(Scope* scope) { scope_ = scope; }
1071b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
107244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  HBasicBlock* current_block() const { return current_block_; }
107344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  void set_current_block(HBasicBlock* block) { current_block_ = block; }
1074e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  HEnvironment* environment() const {
1075e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch    return current_block()->last_environment();
1076e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  }
1077b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Zone* zone() const { return info_->zone(); }
1078b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HGraph* graph() const { return graph_; }
1079b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Isolate* isolate() const { return graph_->isolate(); }
1080b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CompilationInfo* top_info() { return info_; }
1081b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1082b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HGraph* CreateGraph();
1083b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1084b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Bailout environment manipulation.
1085b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void Push(HValue* value) { environment()->Push(value); }
1086b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  HValue* Pop() { return environment()->Pop(); }
1087b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1088b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  virtual HValue* context() = 0;
1089257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
1090b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Adding instructions.
1091b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HInstruction* AddInstruction(HInstruction* instr);
1092b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void FinishCurrentBlock(HControlInstruction* last);
1093b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void FinishExitCurrentBlock(HControlInstruction* instruction);
10943fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
1095b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void Goto(HBasicBlock* from,
1096b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            HBasicBlock* target,
1097b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            FunctionState* state = NULL,
1098b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            bool add_simulate = true) {
1099b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    from->Goto(target, source_position(), state, add_simulate);
1100b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void Goto(HBasicBlock* target,
1102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            FunctionState* state = NULL,
1103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            bool add_simulate = true) {
1104b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Goto(current_block(), target, state, add_simulate);
1105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1106b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void GotoNoSimulate(HBasicBlock* from, HBasicBlock* target) {
1107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Goto(from, target, NULL, false);
1108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void GotoNoSimulate(HBasicBlock* target) {
1110b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Goto(target, NULL, false);
1111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1112b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void AddLeaveInlined(HBasicBlock* block,
1113b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                       HValue* return_value,
1114b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                       FunctionState* state) {
1115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    block->AddLeaveInlined(return_value, state, source_position());
1116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1117b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void AddLeaveInlined(HValue* return_value, FunctionState* state) {
1118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return AddLeaveInlined(current_block(), return_value, state);
1119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
112069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch
1121014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  template <class I>
1122014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HInstruction* NewUncasted() {
1123014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return I::New(isolate(), zone(), context());
1124014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
11253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1126014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  template <class I>
1127014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  I* New() {
1128014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return I::New(isolate(), zone(), context());
1129014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
11303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  template<class I>
1132b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HInstruction* AddUncasted() { return AddInstruction(NewUncasted<I>());}
1133b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1134b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  template<class I>
1135b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  I* Add() { return AddInstructionTyped(New<I>());}
1136b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  template<class I, class P1>
1138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HInstruction* NewUncasted(P1 p1) {
1139014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return I::New(isolate(), zone(), context(), p1);
1140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1141b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1142014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  template <class I, class P1>
1143014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  I* New(P1 p1) {
1144014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return I::New(isolate(), zone(), context(), p1);
1145014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1146b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  template<class I, class P1>
1148b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HInstruction* AddUncasted(P1 p1) {
1149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    HInstruction* result = AddInstruction(NewUncasted<I>(p1));
1150b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Specializations must have their parameters properly casted
1151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // to avoid landing here.
1152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(!result->IsReturn() && !result->IsSimulate() &&
1153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch           !result->IsDeoptimize());
1154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return result;
1155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1156b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1157b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  template<class I, class P1>
1158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  I* Add(P1 p1) {
1159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    I* result = AddInstructionTyped(New<I>(p1));
1160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Specializations must have their parameters properly casted
1161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // to avoid landing here.
1162b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(!result->IsReturn() && !result->IsSimulate() &&
1163b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch           !result->IsDeoptimize());
1164b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return result;
1165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
11663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1167b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  template<class I, class P1, class P2>
1168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HInstruction* NewUncasted(P1 p1, P2 p2) {
1169014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return I::New(isolate(), zone(), context(), p1, p2);
1170b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1171e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
1172b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  template<class I, class P1, class P2>
1173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  I* New(P1 p1, P2 p2) {
1174014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return I::New(isolate(), zone(), context(), p1, p2);
1175b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1176e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
1177b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  template<class I, class P1, class P2>
1178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HInstruction* AddUncasted(P1 p1, P2 p2) {
1179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    HInstruction* result = AddInstruction(NewUncasted<I>(p1, p2));
1180b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Specializations must have their parameters properly casted
1181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // to avoid landing here.
1182b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(!result->IsSimulate());
1183b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return result;
1184e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  }
1185b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1186b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  template<class I, class P1, class P2>
1187b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  I* Add(P1 p1, P2 p2) {
1188b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    I* result = AddInstructionTyped(New<I>(p1, p2));
1189b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Specializations must have their parameters properly casted
1190b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // to avoid landing here.
1191b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(!result->IsSimulate());
1192b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return result;
1193e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  }
1194b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1195b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  template<class I, class P1, class P2, class P3>
1196b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HInstruction* NewUncasted(P1 p1, P2 p2, P3 p3) {
1197014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return I::New(isolate(), zone(), context(), p1, p2, p3);
1198e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  }
1199b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1200b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  template<class I, class P1, class P2, class P3>
1201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  I* New(P1 p1, P2 p2, P3 p3) {
1202014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return I::New(isolate(), zone(), context(), p1, p2, p3);
1203b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1204b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1205b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  template<class I, class P1, class P2, class P3>
1206b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HInstruction* AddUncasted(P1 p1, P2 p2, P3 p3) {
1207b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return AddInstruction(NewUncasted<I>(p1, p2, p3));
1208b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1209b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  template<class I, class P1, class P2, class P3>
1211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  I* Add(P1 p1, P2 p2, P3 p3) {
1212b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return AddInstructionTyped(New<I>(p1, p2, p3));
1213b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1214b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1215b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  template<class I, class P1, class P2, class P3, class P4>
1216b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HInstruction* NewUncasted(P1 p1, P2 p2, P3 p3, P4 p4) {
1217014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return I::New(isolate(), zone(), context(), p1, p2, p3, p4);
1218b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1219b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  template<class I, class P1, class P2, class P3, class P4>
1221b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  I* New(P1 p1, P2 p2, P3 p3, P4 p4) {
1222014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return I::New(isolate(), zone(), context(), p1, p2, p3, p4);
1223b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1224b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1225b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  template<class I, class P1, class P2, class P3, class P4>
1226b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HInstruction* AddUncasted(P1 p1, P2 p2, P3 p3, P4 p4) {
1227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return AddInstruction(NewUncasted<I>(p1, p2, p3, p4));
1228b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1229b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1230b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  template<class I, class P1, class P2, class P3, class P4>
1231b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  I* Add(P1 p1, P2 p2, P3 p3, P4 p4) {
1232b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return AddInstructionTyped(New<I>(p1, p2, p3, p4));
1233b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1234b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1235b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  template<class I, class P1, class P2, class P3, class P4, class P5>
1236b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HInstruction* NewUncasted(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) {
1237014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return I::New(isolate(), zone(), context(), p1, p2, p3, p4, p5);
1238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  template<class I, class P1, class P2, class P3, class P4, class P5>
1241b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  I* New(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) {
1242014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return I::New(isolate(), zone(), context(), p1, p2, p3, p4, p5);
1243b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1244b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1245b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  template<class I, class P1, class P2, class P3, class P4, class P5>
1246b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HInstruction* AddUncasted(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) {
1247b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return AddInstruction(NewUncasted<I>(p1, p2, p3, p4, p5));
1248b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1249b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1250b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  template<class I, class P1, class P2, class P3, class P4, class P5>
1251b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  I* Add(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) {
1252b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return AddInstructionTyped(New<I>(p1, p2, p3, p4, p5));
1253b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1254b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1255b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  template<class I, class P1, class P2, class P3, class P4, class P5, class P6>
1256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HInstruction* NewUncasted(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6) {
1257014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return I::New(isolate(), zone(), context(), p1, p2, p3, p4, p5, p6);
1258b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1259b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1260b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  template<class I, class P1, class P2, class P3, class P4, class P5, class P6>
1261b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  I* New(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6) {
1262014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return I::New(isolate(), zone(), context(), p1, p2, p3, p4, p5, p6);
1263b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1264b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1265b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  template<class I, class P1, class P2, class P3, class P4, class P5, class P6>
1266b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HInstruction* AddUncasted(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6) {
1267b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return AddInstruction(NewUncasted<I>(p1, p2, p3, p4, p5, p6));
1268b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1269b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1270b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  template<class I, class P1, class P2, class P3, class P4, class P5, class P6>
1271b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  I* Add(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6) {
1272b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return AddInstructionTyped(New<I>(p1, p2, p3, p4, p5, p6));
1273b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1274b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1275b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  template<class I, class P1, class P2, class P3, class P4,
1276b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      class P5, class P6, class P7>
1277b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HInstruction* NewUncasted(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7) {
1278014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return I::New(isolate(), zone(), context(), p1, p2, p3, p4, p5, p6, p7);
1279b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1280b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1281b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  template<class I, class P1, class P2, class P3, class P4,
1282b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      class P5, class P6, class P7>
1283b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      I* New(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7) {
1284014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return I::New(isolate(), zone(), context(), p1, p2, p3, p4, p5, p6, p7);
1285b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1286b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1287b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  template<class I, class P1, class P2, class P3,
1288b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch           class P4, class P5, class P6, class P7>
1289b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HInstruction* AddUncasted(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7) {
1290b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return AddInstruction(NewUncasted<I>(p1, p2, p3, p4, p5, p6, p7));
1291b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1292b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1293b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  template<class I, class P1, class P2, class P3,
1294b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch           class P4, class P5, class P6, class P7>
1295b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  I* Add(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7) {
1296b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return AddInstructionTyped(New<I>(p1, p2, p3, p4, p5, p6, p7));
1297b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1298b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1299b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  template<class I, class P1, class P2, class P3, class P4,
1300b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      class P5, class P6, class P7, class P8>
1301b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HInstruction* NewUncasted(P1 p1, P2 p2, P3 p3, P4 p4,
1302b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                            P5 p5, P6 p6, P7 p7, P8 p8) {
1303014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return I::New(isolate(), zone(), context(), p1, p2, p3, p4, p5, p6, p7, p8);
1304b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1305b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1306b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  template<class I, class P1, class P2, class P3, class P4,
1307b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      class P5, class P6, class P7, class P8>
1308b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      I* New(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8) {
1309014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return I::New(isolate(), zone(), context(), p1, p2, p3, p4, p5, p6, p7, p8);
1310b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1311b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1312b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  template<class I, class P1, class P2, class P3, class P4,
1313b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch           class P5, class P6, class P7, class P8>
1314b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HInstruction* AddUncasted(P1 p1, P2 p2, P3 p3, P4 p4,
1315b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                            P5 p5, P6 p6, P7 p7, P8 p8) {
1316b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return AddInstruction(NewUncasted<I>(p1, p2, p3, p4, p5, p6, p7, p8));
1317b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1318b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1319b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  template<class I, class P1, class P2, class P3, class P4,
1320b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch           class P5, class P6, class P7, class P8>
1321b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  I* Add(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8) {
1322b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return AddInstructionTyped(New<I>(p1, p2, p3, p4, p5, p6, p7, p8));
1323b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1324b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
13251b268ca467c924004286c97bac133db489cf43d0Ben Murdoch  template <class I, class P1, class P2, class P3, class P4, class P5, class P6,
13261b268ca467c924004286c97bac133db489cf43d0Ben Murdoch            class P7, class P8, class P9>
13271b268ca467c924004286c97bac133db489cf43d0Ben Murdoch  I* New(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8, P9 p9) {
13281b268ca467c924004286c97bac133db489cf43d0Ben Murdoch    return I::New(isolate(), zone(), context(), p1, p2, p3, p4, p5, p6, p7, p8,
13291b268ca467c924004286c97bac133db489cf43d0Ben Murdoch                  p9);
13301b268ca467c924004286c97bac133db489cf43d0Ben Murdoch  }
13311b268ca467c924004286c97bac133db489cf43d0Ben Murdoch
13321b268ca467c924004286c97bac133db489cf43d0Ben Murdoch  template <class I, class P1, class P2, class P3, class P4, class P5, class P6,
13331b268ca467c924004286c97bac133db489cf43d0Ben Murdoch            class P7, class P8, class P9>
13341b268ca467c924004286c97bac133db489cf43d0Ben Murdoch  HInstruction* AddUncasted(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7,
13351b268ca467c924004286c97bac133db489cf43d0Ben Murdoch                            P8 p8, P9 p9) {
133621efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch    return AddInstruction(NewUncasted<I>(p1, p2, p3, p4, p5, p6, p7, p8, p9));
13371b268ca467c924004286c97bac133db489cf43d0Ben Murdoch  }
13381b268ca467c924004286c97bac133db489cf43d0Ben Murdoch
13391b268ca467c924004286c97bac133db489cf43d0Ben Murdoch  template <class I, class P1, class P2, class P3, class P4, class P5, class P6,
13401b268ca467c924004286c97bac133db489cf43d0Ben Murdoch            class P7, class P8, class P9>
13411b268ca467c924004286c97bac133db489cf43d0Ben Murdoch  I* Add(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8, P9 p9) {
13421b268ca467c924004286c97bac133db489cf43d0Ben Murdoch    return AddInstructionTyped(New<I>(p1, p2, p3, p4, p5, p6, p7, p8, p9));
13431b268ca467c924004286c97bac133db489cf43d0Ben Murdoch  }
13441b268ca467c924004286c97bac133db489cf43d0Ben Murdoch
1345b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void AddSimulate(BailoutId id, RemovableSimulate removable = FIXED_SIMULATE);
1346b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1347b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // When initializing arrays, we'll unfold the loop if the number of elements
1348b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // is known at compile time and is <= kElementLoopUnrollThreshold.
1349b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static const int kElementLoopUnrollThreshold = 8;
1350b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1351b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch protected:
1352b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  virtual bool BuildGraph() = 0;
1353b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1354b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HBasicBlock* CreateBasicBlock(HEnvironment* env);
1355b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HBasicBlock* CreateLoopHeaderBlock();
1356b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1357b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  template <class BitFieldClass>
1358b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HValue* BuildDecodeField(HValue* encoded_field) {
1359b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    HValue* mask_value = Add<HConstant>(static_cast<int>(BitFieldClass::kMask));
1360b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    HValue* masked_field =
1361b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        AddUncasted<HBitwise>(Token::BIT_AND, encoded_field, mask_value);
1362b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return AddUncasted<HShr>(masked_field,
1363b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        Add<HConstant>(static_cast<int>(BitFieldClass::kShift)));
1364b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1365b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1366b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HValue* BuildGetElementsKind(HValue* object);
1367b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1368342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch  HValue* BuildEnumLength(HValue* map);
1369342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch
1370b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HValue* BuildCheckHeapObject(HValue* object);
1371b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HValue* BuildCheckString(HValue* string);
1372b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HValue* BuildWrapReceiver(HValue* object, HValue* function);
1373b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1374b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Building common constructs
1375b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HValue* BuildCheckForCapacityGrow(HValue* object,
1376b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                    HValue* elements,
1377b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                    ElementsKind kind,
1378b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                    HValue* length,
1379b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                    HValue* key,
1380b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                    bool is_js_array,
1381b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                    PropertyAccessType access_type);
1382b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1383014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HValue* BuildCheckAndGrowElementsCapacity(HValue* object, HValue* elements,
1384014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                            ElementsKind kind, HValue* length,
1385014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                            HValue* capacity, HValue* key);
1386014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1387b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HValue* BuildCopyElementsOnWrite(HValue* object,
1388b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                   HValue* elements,
1389b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                   ElementsKind kind,
1390b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                   HValue* length);
1391b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1392b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void BuildTransitionElementsKind(HValue* object,
1393b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                   HValue* map,
1394b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                   ElementsKind from_kind,
1395b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                   ElementsKind to_kind,
1396b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                   bool is_jsarray);
1397b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1398b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HValue* BuildNumberToString(HValue* object, Type* type);
1399342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch  HValue* BuildToNumber(HValue* input);
1400014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HValue* BuildToObject(HValue* receiver);
1401b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1402b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void BuildJSObjectCheck(HValue* receiver,
1403b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                          int bit_field_mask);
1404b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1405b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Checks a key value that's being used for a keyed element access context. If
1406b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // the key is a index, i.e. a smi or a number in a unique string with a cached
1407b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // numeric value, the "true" of the continuation is joined. Otherwise,
1408b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // if the key is a name or a unique string, the "false" of the continuation is
1409b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // joined. Otherwise, a deoptimization is triggered. In both paths of the
1410b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // continuation, the key is pushed on the top of the environment.
1411b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void BuildKeyedIndexCheck(HValue* key,
1412b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                            HIfContinuation* join_continuation);
1413b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1414b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Checks the properties of an object if they are in dictionary case, in which
1415b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // case "true" of continuation is taken, otherwise the "false"
1416b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void BuildTestForDictionaryProperties(HValue* object,
1417b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                        HIfContinuation* continuation);
1418b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1419b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void BuildNonGlobalObjectCheck(HValue* receiver);
1420b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1421b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HValue* BuildKeyedLookupCacheHash(HValue* object,
1422b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                    HValue* key);
1423b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1424b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HValue* BuildUncheckedDictionaryElementLoad(HValue* receiver,
1425014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                              HValue* elements, HValue* key,
1426342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch                                              HValue* hash);
1427014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1428014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // ES6 section 7.4.7 CreateIterResultObject ( value, done )
1429014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HValue* BuildCreateIterResultObject(HValue* value, HValue* done);
1430b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1431b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HValue* BuildRegExpConstructResult(HValue* length,
1432b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                     HValue* index,
1433b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                     HValue* input);
1434b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1435b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Allocates a new object according with the given allocation properties.
1436b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HAllocate* BuildAllocate(HValue* object_size,
1437b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                           HType type,
1438b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                           InstanceType instance_type,
1439b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                           HAllocationMode allocation_mode);
1440b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Computes the sum of two string lengths, taking care of overflow handling.
1441b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HValue* BuildAddStringLengths(HValue* left_length, HValue* right_length);
1442b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Creates a cons string using the two input strings.
1443b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HValue* BuildCreateConsString(HValue* length,
1444b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                HValue* left,
1445b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                HValue* right,
1446b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                HAllocationMode allocation_mode);
1447b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Copies characters from one sequential string to another.
1448b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void BuildCopySeqStringChars(HValue* src,
1449b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                               HValue* src_offset,
1450b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                               String::Encoding src_encoding,
1451b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                               HValue* dst,
1452b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                               HValue* dst_offset,
1453b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                               String::Encoding dst_encoding,
1454b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                               HValue* length);
1455b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1456b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Align an object size to object alignment boundary
1457b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HValue* BuildObjectSizeAlignment(HValue* unaligned_size, int header_size);
1458b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1459b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Both operands are non-empty strings.
1460b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HValue* BuildUncheckedStringAdd(HValue* left,
1461b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                  HValue* right,
1462b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                  HAllocationMode allocation_mode);
1463b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Add two strings using allocation mode, validating type feedback.
1464b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HValue* BuildStringAdd(HValue* left,
1465b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                         HValue* right,
1466b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                         HAllocationMode allocation_mode);
1467b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1468b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HInstruction* BuildUncheckedMonomorphicElementAccess(
1469b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      HValue* checked_object,
1470b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      HValue* key,
1471b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      HValue* val,
1472b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      bool is_js_array,
1473b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      ElementsKind elements_kind,
1474b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      PropertyAccessType access_type,
1475b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      LoadKeyedHoleMode load_mode,
1476b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      KeyedAccessStoreMode store_mode);
1477b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1478b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HInstruction* AddElementAccess(
1479014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      HValue* elements, HValue* checked_key, HValue* val, HValue* dependency,
1480014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      HValue* backing_store_owner, ElementsKind elements_kind,
1481b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      PropertyAccessType access_type,
1482b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      LoadKeyedHoleMode load_mode = NEVER_RETURN_HOLE);
1483b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1484b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HInstruction* AddLoadStringInstanceType(HValue* string);
1485b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HInstruction* AddLoadStringLength(HValue* string);
1486014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HInstruction* BuildLoadStringLength(HValue* string);
1487b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HStoreNamedField* AddStoreMapConstant(HValue* object, Handle<Map> map) {
1488b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return Add<HStoreNamedField>(object, HObjectAccess::ForMap(),
1489b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                 Add<HConstant>(map));
1490b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1491b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HLoadNamedField* AddLoadMap(HValue* object,
1492b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                              HValue* dependency = NULL);
1493b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HLoadNamedField* AddLoadElements(HValue* object,
1494b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                   HValue* dependency = NULL);
1495b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1496b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool MatchRotateRight(HValue* left,
1497b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                        HValue* right,
1498b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                        HValue** operand,
1499b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                        HValue** shift_amount);
1500b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1501014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HValue* BuildBinaryOperation(Token::Value op, HValue* left, HValue* right,
1502014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                               Type* left_type, Type* right_type,
1503014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                               Type* result_type, Maybe<int> fixed_right_arg,
1504014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                               HAllocationMode allocation_mode,
1505014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                               BailoutId opt_id = BailoutId::None());
1506b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1507b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HLoadNamedField* AddLoadFixedArrayLength(HValue *object,
1508b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                           HValue *dependency = NULL);
1509b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1510b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HLoadNamedField* AddLoadArrayLength(HValue *object,
1511b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                      ElementsKind kind,
1512b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                      HValue *dependency = NULL);
1513b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1514014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HValue* AddLoadJSBuiltin(int context_index);
1515b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1516b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HValue* EnforceNumberType(HValue* number, Type* expected);
1517b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HValue* TruncateToNumber(HValue* value, Type** expected);
1518b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1519014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void FinishExitWithHardDeoptimization(Deoptimizer::DeoptReason reason);
1520b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1521b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void AddIncrementCounter(StatsCounter* counter);
1522b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1523014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  class IfBuilder final {
1524b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch   public:
1525b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // If using this constructor, Initialize() must be called explicitly!
1526b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    IfBuilder();
1527b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1528b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    explicit IfBuilder(HGraphBuilder* builder);
1529b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    IfBuilder(HGraphBuilder* builder,
1530b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch              HIfContinuation* continuation);
1531b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1532b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ~IfBuilder() {
1533b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (!finished_) End();
1534b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1535b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1536b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    void Initialize(HGraphBuilder* builder);
1537b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1538b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    template<class Condition>
1539b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Condition* If(HValue *p) {
1540b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Condition* compare = builder()->New<Condition>(p);
1541b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      AddCompare(compare);
1542b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return compare;
1543b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1544b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1545b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    template<class Condition, class P2>
1546b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Condition* If(HValue* p1, P2 p2) {
1547b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Condition* compare = builder()->New<Condition>(p1, p2);
1548b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      AddCompare(compare);
1549b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return compare;
1550b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1551b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1552b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    template<class Condition, class P2, class P3>
1553b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Condition* If(HValue* p1, P2 p2, P3 p3) {
1554b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Condition* compare = builder()->New<Condition>(p1, p2, p3);
1555b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      AddCompare(compare);
1556b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return compare;
1557b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1558b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1559b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    template<class Condition>
1560b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Condition* IfNot(HValue* p) {
1561b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Condition* compare = If<Condition>(p);
1562b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      compare->Not();
1563b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return compare;
1564b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1565b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1566b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    template<class Condition, class P2>
1567b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Condition* IfNot(HValue* p1, P2 p2) {
1568b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Condition* compare = If<Condition>(p1, p2);
1569b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      compare->Not();
1570b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return compare;
1571b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1572b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1573b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    template<class Condition, class P2, class P3>
1574b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Condition* IfNot(HValue* p1, P2 p2, P3 p3) {
1575b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Condition* compare = If<Condition>(p1, p2, p3);
1576b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      compare->Not();
1577b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return compare;
1578b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1579b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1580b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    template<class Condition>
1581b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Condition* OrIf(HValue *p) {
1582b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Or();
1583b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return If<Condition>(p);
1584b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1585b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1586b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    template<class Condition, class P2>
1587b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Condition* OrIf(HValue* p1, P2 p2) {
1588b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Or();
1589b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return If<Condition>(p1, p2);
1590b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1591b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1592b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    template<class Condition, class P2, class P3>
1593b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Condition* OrIf(HValue* p1, P2 p2, P3 p3) {
1594b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Or();
1595b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return If<Condition>(p1, p2, p3);
1596b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1597b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1598b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    template<class Condition>
1599b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Condition* AndIf(HValue *p) {
1600b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      And();
1601b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return If<Condition>(p);
1602b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1603b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1604b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    template<class Condition, class P2>
1605b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Condition* AndIf(HValue* p1, P2 p2) {
1606b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      And();
1607b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return If<Condition>(p1, p2);
1608b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1609b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1610b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    template<class Condition, class P2, class P3>
1611b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Condition* AndIf(HValue* p1, P2 p2, P3 p3) {
1612b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      And();
1613b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return If<Condition>(p1, p2, p3);
1614b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1615b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1616b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    void Or();
1617b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    void And();
1618b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1619b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Captures the current state of this IfBuilder in the specified
1620b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // continuation and ends this IfBuilder.
1621b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    void CaptureContinuation(HIfContinuation* continuation);
1622b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1623b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Joins the specified continuation from this IfBuilder and ends this
1624b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // IfBuilder. This appends a Goto instruction from the true branch of
1625b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // this IfBuilder to the true branch of the continuation unless the
1626b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // true branch of this IfBuilder is already finished. And vice versa
1627b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // for the false branch.
1628b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    //
1629b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // The basic idea is as follows: You have several nested IfBuilder's
1630b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // that you want to join based on two possible outcomes (i.e. success
1631b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // and failure, or whatever). You can do this easily using this method
1632b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // now, for example:
1633b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    //
1634b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    //   HIfContinuation cont(graph()->CreateBasicBlock(),
1635b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    //                        graph()->CreateBasicBlock());
1636b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    //   ...
1637b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    //     IfBuilder if_whatever(this);
1638b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    //     if_whatever.If<Condition>(arg);
1639b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    //     if_whatever.Then();
1640b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    //     ...
1641b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    //     if_whatever.Else();
1642b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    //     ...
1643b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    //     if_whatever.JoinContinuation(&cont);
1644b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    //   ...
1645b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    //     IfBuilder if_something(this);
1646b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    //     if_something.If<Condition>(arg1, arg2);
1647b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    //     if_something.Then();
1648b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    //     ...
1649b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    //     if_something.Else();
1650b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    //     ...
1651b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    //     if_something.JoinContinuation(&cont);
1652b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    //   ...
1653b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    //   IfBuilder if_finally(this, &cont);
1654b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    //   if_finally.Then();
1655b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    //   // continues after then code of if_whatever or if_something.
1656b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    //   ...
1657b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    //   if_finally.Else();
1658b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    //   // continues after else code of if_whatever or if_something.
1659b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    //   ...
1660b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    //   if_finally.End();
1661b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    void JoinContinuation(HIfContinuation* continuation);
1662b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1663b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    void Then();
1664b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    void Else();
1665b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    void End();
1666014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    void EndUnreachable();
1667b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1668014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    void Deopt(Deoptimizer::DeoptReason reason);
1669014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    void ThenDeopt(Deoptimizer::DeoptReason reason) {
1670b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Then();
1671b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Deopt(reason);
1672b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1673014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    void ElseDeopt(Deoptimizer::DeoptReason reason) {
1674b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Else();
1675b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Deopt(reason);
1676b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1677b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1678b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    void Return(HValue* value);
1679b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1680b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch   private:
1681b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    void InitializeDontCreateBlocks(HGraphBuilder* builder);
1682b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1683b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    HControlInstruction* AddCompare(HControlInstruction* compare);
1684b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1685b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    HGraphBuilder* builder() const {
1686b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      DCHECK(builder_ != NULL);  // Have you called "Initialize"?
1687b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return builder_;
1688b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1689b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1690b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    void AddMergeAtJoinBlock(bool deopt);
1691b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1692b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    void Finish();
1693b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    void Finish(HBasicBlock** then_continuation,
1694b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                HBasicBlock** else_continuation);
1695b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1696b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    class MergeAtJoinBlock : public ZoneObject {
1697b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch     public:
1698b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      MergeAtJoinBlock(HBasicBlock* block,
1699b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                       bool deopt,
1700b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                       MergeAtJoinBlock* next)
1701b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        : block_(block),
1702b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          deopt_(deopt),
1703b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          next_(next) {}
1704b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      HBasicBlock* block_;
1705b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      bool deopt_;
1706b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      MergeAtJoinBlock* next_;
1707b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    };
1708b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1709b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    HGraphBuilder* builder_;
1710b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    bool finished_ : 1;
1711b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    bool did_then_ : 1;
1712b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    bool did_else_ : 1;
1713b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    bool did_else_if_ : 1;
1714b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    bool did_and_ : 1;
1715b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    bool did_or_ : 1;
1716b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    bool captured_ : 1;
1717b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    bool needs_compare_ : 1;
1718b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    bool pending_merge_block_ : 1;
1719b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    HBasicBlock* first_true_block_;
1720b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    HBasicBlock* first_false_block_;
1721b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    HBasicBlock* split_edge_merge_block_;
1722b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    MergeAtJoinBlock* merge_at_join_blocks_;
1723b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    int normal_merge_at_join_block_count_;
1724b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    int deopt_merge_at_join_block_count_;
1725b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  };
1726b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1727014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  class LoopBuilder final {
1728b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch   public:
1729b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    enum Direction {
1730b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      kPreIncrement,
1731b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      kPostIncrement,
1732b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      kPreDecrement,
1733b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      kPostDecrement,
1734b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      kWhileTrue
1735b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    };
1736b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1737b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    explicit LoopBuilder(HGraphBuilder* builder);  // while (true) {...}
1738b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    LoopBuilder(HGraphBuilder* builder,
1739b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                HValue* context,
1740b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                Direction direction);
1741b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    LoopBuilder(HGraphBuilder* builder,
1742b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                HValue* context,
1743b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                Direction direction,
1744b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                HValue* increment_amount);
1745b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1746b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ~LoopBuilder() {
1747b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      DCHECK(finished_);
1748b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1749b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1750b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    HValue* BeginBody(
1751b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        HValue* initial,
1752b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        HValue* terminating,
1753b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        Token::Value token);
1754b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1755b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    void BeginBody(int drop_count);
1756b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1757b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    void Break();
1758b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1759b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    void EndBody();
1760b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1761b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch   private:
1762b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    void Initialize(HGraphBuilder* builder, HValue* context,
1763b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                    Direction direction, HValue* increment_amount);
1764b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Zone* zone() { return builder_->zone(); }
1765b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1766b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    HGraphBuilder* builder_;
1767b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    HValue* context_;
1768b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    HValue* increment_amount_;
1769b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    HInstruction* increment_;
1770b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    HPhi* phi_;
1771b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    HBasicBlock* header_block_;
1772b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    HBasicBlock* body_block_;
1773b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    HBasicBlock* exit_block_;
1774b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    HBasicBlock* exit_trampoline_block_;
1775b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Direction direction_;
1776b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    bool finished_;
1777b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  };
1778b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1779b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HValue* BuildNewElementsCapacity(HValue* old_capacity);
1780b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1781014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  class JSArrayBuilder final {
1782b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch   public:
1783b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    JSArrayBuilder(HGraphBuilder* builder,
1784b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                   ElementsKind kind,
1785b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                   HValue* allocation_site_payload,
1786b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                   HValue* constructor_function,
1787b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                   AllocationSiteOverrideMode override_mode);
1788b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1789b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    JSArrayBuilder(HGraphBuilder* builder,
1790b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                   ElementsKind kind,
1791b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                   HValue* constructor_function = NULL);
1792b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1793b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    enum FillMode {
1794b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      DONT_FILL_WITH_HOLE,
1795b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      FILL_WITH_HOLE
1796b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    };
1797b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1798b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ElementsKind kind() { return kind_; }
1799b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    HAllocate* elements_location() { return elements_location_; }
1800b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1801b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    HAllocate* AllocateEmptyArray();
1802b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    HAllocate* AllocateArray(HValue* capacity,
1803b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                             HValue* length_field,
1804b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                             FillMode fill_mode = FILL_WITH_HOLE);
1805b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    HValue* GetElementsLocation() { return elements_location_; }
1806b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    HValue* EmitMapCode();
1807b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1808b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch   private:
1809b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Zone* zone() const { return builder_->zone(); }
1810b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    int elements_size() const {
1811b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return IsFastDoubleElementsKind(kind_) ? kDoubleSize : kPointerSize;
1812b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1813b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    HGraphBuilder* builder() { return builder_; }
1814b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    HGraph* graph() { return builder_->graph(); }
1815b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    int initial_capacity() {
1816b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      STATIC_ASSERT(JSArray::kPreallocatedArrayElements > 0);
1817b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return JSArray::kPreallocatedArrayElements;
1818b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1819b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1820b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    HValue* EmitInternalMapCode();
1821b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1822b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    HGraphBuilder* builder_;
1823b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ElementsKind kind_;
1824b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    AllocationSiteMode mode_;
1825b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    HValue* allocation_site_payload_;
1826b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    HValue* constructor_function_;
1827b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    HAllocate* elements_location_;
1828b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  };
1829b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1830b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HValue* BuildAllocateArrayFromLength(JSArrayBuilder* array_builder,
1831b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                       HValue* length_argument);
1832b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HValue* BuildCalculateElementsSize(ElementsKind kind,
1833b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                     HValue* capacity);
1834b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HAllocate* AllocateJSArrayObject(AllocationSiteMode mode);
1835b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HConstant* EstablishElementsAllocationSize(ElementsKind kind, int capacity);
1836b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1837b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HAllocate* BuildAllocateElements(ElementsKind kind, HValue* size_in_bytes);
1838b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1839b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void BuildInitializeElementsHeader(HValue* elements,
1840b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                     ElementsKind kind,
1841b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                     HValue* capacity);
1842b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1843958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // Build allocation and header initialization code for respective successor
1844958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // of FixedArrayBase.
1845958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  HValue* BuildAllocateAndInitializeArray(ElementsKind kind, HValue* capacity);
1846b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1847b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // |array| must have been allocated with enough room for
1848b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // 1) the JSArray and 2) an AllocationMemento if mode requires it.
1849b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // If the |elements| value provided is NULL then the array elements storage
1850b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // is initialized with empty array.
1851b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void BuildJSArrayHeader(HValue* array,
1852b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                          HValue* array_map,
1853b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                          HValue* elements,
1854b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                          AllocationSiteMode mode,
1855b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                          ElementsKind elements_kind,
1856b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                          HValue* allocation_site_payload,
1857b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                          HValue* length_field);
1858b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1859b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HValue* BuildGrowElementsCapacity(HValue* object,
1860b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                    HValue* elements,
1861b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                    ElementsKind kind,
1862b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                    ElementsKind new_kind,
1863b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                    HValue* length,
1864b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                    HValue* new_capacity);
1865b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1866b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void BuildFillElementsWithValue(HValue* elements,
1867b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                  ElementsKind elements_kind,
1868b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                  HValue* from,
1869b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                  HValue* to,
1870b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                  HValue* value);
1871b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1872b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void BuildFillElementsWithHole(HValue* elements,
1873b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                 ElementsKind elements_kind,
1874b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                 HValue* from,
1875b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                 HValue* to);
1876b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1877958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void BuildCopyProperties(HValue* from_properties, HValue* to_properties,
1878958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                           HValue* length, HValue* capacity);
1879958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1880b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void BuildCopyElements(HValue* from_elements,
1881b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                         ElementsKind from_elements_kind,
1882b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                         HValue* to_elements,
1883b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                         ElementsKind to_elements_kind,
1884b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                         HValue* length,
1885b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                         HValue* capacity);
1886b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1887b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HValue* BuildCloneShallowArrayCow(HValue* boilerplate,
1888b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                    HValue* allocation_site,
1889b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                    AllocationSiteMode mode,
1890b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                    ElementsKind kind);
1891b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1892b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HValue* BuildCloneShallowArrayEmpty(HValue* boilerplate,
1893b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                      HValue* allocation_site,
1894b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                      AllocationSiteMode mode);
1895b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1896b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HValue* BuildCloneShallowArrayNonEmpty(HValue* boilerplate,
1897b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                         HValue* allocation_site,
1898b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                         AllocationSiteMode mode,
1899b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                         ElementsKind kind);
1900b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1901b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HValue* BuildElementIndexHash(HValue* index);
1902b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1903b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void BuildCreateAllocationMemento(HValue* previous_object,
1904b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                    HValue* previous_object_size,
1905b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                    HValue* payload);
1906b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1907b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HInstruction* BuildConstantMapCheck(Handle<JSObject> constant);
1908b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HInstruction* BuildCheckPrototypeMaps(Handle<JSObject> prototype,
1909b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                        Handle<JSObject> holder);
1910b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1911b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HInstruction* BuildGetNativeContext(HValue* closure);
1912b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HInstruction* BuildGetNativeContext();
1913958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  HInstruction* BuildGetScriptContext(int context_index);
1914014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Builds a loop version if |depth| is specified or unrolls the loop to
1915014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // |depth_value| iterations otherwise.
1916014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HValue* BuildGetParentContext(HValue* depth, int depth_value);
1917014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1918b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HInstruction* BuildGetArrayFunction();
1919014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HValue* BuildArrayBufferViewFieldAccessor(HValue* object,
1920014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                            HValue* checked_object,
1921014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                            FieldIndex index);
1922014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1923b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1924b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch protected:
1925b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void SetSourcePosition(int position) {
1926014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (position != RelocInfo::kNoPosition) {
1927014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      position_.set_position(position - start_position_);
1928014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1929014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Otherwise position remains unknown.
1930b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1931b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1932b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void EnterInlinedSource(int start_position, int id) {
1933014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (top_info()->is_tracking_positions()) {
1934b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      start_position_ = start_position;
1935b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      position_.set_inlining_id(id);
1936b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1937b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1938b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1939b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Convert the given absolute offset from the start of the script to
1940014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // the SourcePosition assuming that this position corresponds to the
1941b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // same function as current position_.
1942014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  SourcePosition ScriptPositionToSourcePosition(int position) {
1943014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (position == RelocInfo::kNoPosition) {
1944014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return SourcePosition::Unknown();
1945014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1946014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    SourcePosition pos = position_;
1947b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    pos.set_position(position - start_position_);
1948b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return pos;
1949b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1950b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1951014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  SourcePosition source_position() { return position_; }
1952014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void set_source_position(SourcePosition position) { position_ = position; }
1953b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1954537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch  int TraceInlinedFunction(Handle<SharedFunctionInfo> shared,
1955537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch                           SourcePosition position);
1956537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch
1957014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HValue* BuildAllocateEmptyArrayBuffer(HValue* byte_length);
1958b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  template <typename ViewClass>
1959b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void BuildArrayBufferViewInitialization(HValue* obj,
1960b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                          HValue* buffer,
1961b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                          HValue* byte_offset,
1962b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                          HValue* byte_length);
1963b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1964b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private:
1965b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HGraphBuilder();
1966b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1967b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  template <class I>
1968b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  I* AddInstructionTyped(I* instr) {
1969b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return I::cast(AddInstruction(instr));
1970b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1971b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1972b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CompilationInfo* info_;
1973342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch  CallInterfaceDescriptor descriptor_;
1974b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HGraph* graph_;
1975b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HBasicBlock* current_block_;
1976b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Scope* scope_;
1977014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  SourcePosition position_;
1978b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int start_position_;
1979b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
1980b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1981b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1982014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochtemplate <>
1983b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochinline HDeoptimize* HGraphBuilder::Add<HDeoptimize>(
1984014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Deoptimizer::DeoptReason reason, Deoptimizer::BailoutType type) {
1985b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (type == Deoptimizer::SOFT) {
1986b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    isolate()->counters()->soft_deopts_requested()->Increment();
1987b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (FLAG_always_opt) return NULL;
1988b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1989b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (current_block()->IsDeoptimizing()) return NULL;
1990b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HBasicBlock* after_deopt_block = CreateBasicBlock(
1991b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      current_block()->last_environment());
1992b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HDeoptimize* instr = New<HDeoptimize>(reason, type, after_deopt_block);
1993b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (type == Deoptimizer::SOFT) {
1994b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    isolate()->counters()->soft_deopts_inserted()->Increment();
1995b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1996b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  FinishCurrentBlock(instr);
1997b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  set_current_block(after_deopt_block);
1998b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return instr;
1999b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2000b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2001b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2002014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochtemplate <>
2003b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochinline HInstruction* HGraphBuilder::AddUncasted<HDeoptimize>(
2004014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Deoptimizer::DeoptReason reason, Deoptimizer::BailoutType type) {
2005b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return Add<HDeoptimize>(reason, type);
2006b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2007b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2008b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2009b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtemplate<>
2010b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochinline HSimulate* HGraphBuilder::Add<HSimulate>(
2011b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    BailoutId id,
2012b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    RemovableSimulate removable) {
2013b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HSimulate* instr = current_block()->CreateSimulate(id, removable);
2014b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  AddInstruction(instr);
2015b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return instr;
2016b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2017b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2018b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2019b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtemplate<>
2020b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochinline HSimulate* HGraphBuilder::Add<HSimulate>(
2021b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    BailoutId id) {
2022b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return Add<HSimulate>(id, FIXED_SIMULATE);
2023b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2024b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2025b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2026b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtemplate<>
2027b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochinline HInstruction* HGraphBuilder::AddUncasted<HSimulate>(BailoutId id) {
2028b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return Add<HSimulate>(id, FIXED_SIMULATE);
2029b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2030b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2031b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2032b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtemplate<>
2033b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochinline HReturn* HGraphBuilder::Add<HReturn>(HValue* value) {
2034b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int num_parameters = graph()->info()->num_parameters();
2035b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HValue* params = AddUncasted<HConstant>(num_parameters);
2036b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HReturn* return_instruction = New<HReturn>(value, params);
2037b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  FinishExitCurrentBlock(return_instruction);
2038b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return return_instruction;
2039b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2040b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2041b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2042b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtemplate<>
2043b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochinline HReturn* HGraphBuilder::Add<HReturn>(HConstant* value) {
2044b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return Add<HReturn>(static_cast<HValue*>(value));
2045b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2046b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2047b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtemplate<>
2048b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochinline HInstruction* HGraphBuilder::AddUncasted<HReturn>(HValue* value) {
2049b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return Add<HReturn>(value);
2050b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2051b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2052b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2053b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtemplate<>
2054b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochinline HInstruction* HGraphBuilder::AddUncasted<HReturn>(HConstant* value) {
2055b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return Add<HReturn>(value);
2056b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2057b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2058b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2059b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtemplate<>
2060b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochinline HCallRuntime* HGraphBuilder::Add<HCallRuntime>(
2061b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    const Runtime::Function* c_function,
2062b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    int argument_count) {
2063014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HCallRuntime* instr = New<HCallRuntime>(c_function, argument_count);
2064b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (graph()->info()->IsStub()) {
2065b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // When compiling code stubs, we don't want to save all double registers
2066b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // upon entry to the stub, but instead have the call runtime instruction
2067b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // save the double registers only on-demand (in the fallback case).
2068b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    instr->set_save_doubles(kSaveFPRegs);
2069b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2070b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  AddInstruction(instr);
2071b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return instr;
2072b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2073b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2074b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2075b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtemplate<>
2076b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochinline HInstruction* HGraphBuilder::AddUncasted<HCallRuntime>(
2077b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Handle<String> name,
2078b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    const Runtime::Function* c_function,
2079b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    int argument_count) {
2080014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return Add<HCallRuntime>(c_function, argument_count);
2081b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2082b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2083b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2084014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochtemplate <>
2085014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochinline HParameter* HGraphBuilder::New<HParameter>(unsigned index) {
2086014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return HParameter::New(isolate(), zone(), nullptr, index);
2087b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2088b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2089b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2090014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochtemplate <>
2091014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochinline HParameter* HGraphBuilder::New<HParameter>(
2092014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    unsigned index, HParameter::ParameterKind kind) {
2093014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return HParameter::New(isolate(), zone(), nullptr, index, kind);
2094014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2095014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2096014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2097014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochtemplate <>
2098014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochinline HParameter* HGraphBuilder::New<HParameter>(
2099014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    unsigned index, HParameter::ParameterKind kind, Representation r) {
2100014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return HParameter::New(isolate(), zone(), nullptr, index, kind, r);
2101014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2102014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2103014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2104014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochtemplate <>
2105014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochinline HPrologue* HGraphBuilder::New<HPrologue>() {
2106014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return HPrologue::New(zone());
2107014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2108014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2109014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2110014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochtemplate <>
2111014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochinline HContext* HGraphBuilder::New<HContext>() {
2112014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return HContext::New(zone());
2113b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2114b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2115014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass HOptimizedGraphBuilder : public HGraphBuilder, public AstVisitor {
2117b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public:
2118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // A class encapsulating (lazily-allocated) break and continue blocks for
2119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // a breakable statement.  Separated from BreakAndContinueScope so that it
2120b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // can have a separate lifetime.
2121014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  class BreakAndContinueInfo final BASE_EMBEDDED {
2122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch   public:
2123b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    explicit BreakAndContinueInfo(BreakableStatement* target,
2124b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                  Scope* scope,
2125b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                  int drop_extra = 0)
2126b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        : target_(target),
2127b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          break_block_(NULL),
2128b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          continue_block_(NULL),
2129b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          scope_(scope),
2130b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          drop_extra_(drop_extra) {
2131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
2132b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2133b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    BreakableStatement* target() { return target_; }
2134b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    HBasicBlock* break_block() { return break_block_; }
2135b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    void set_break_block(HBasicBlock* block) { break_block_ = block; }
2136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    HBasicBlock* continue_block() { return continue_block_; }
2137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    void set_continue_block(HBasicBlock* block) { continue_block_ = block; }
2138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Scope* scope() { return scope_; }
2139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    int drop_extra() { return drop_extra_; }
2140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2141b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch   private:
2142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    BreakableStatement* target_;
2143b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    HBasicBlock* break_block_;
2144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    HBasicBlock* continue_block_;
2145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Scope* scope_;
2146b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    int drop_extra_;
2147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  };
2148b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // A helper class to maintain a stack of current BreakAndContinueInfo
2150b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // structures mirroring BreakableStatement nesting.
2151014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  class BreakAndContinueScope final BASE_EMBEDDED {
2152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch   public:
2153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    BreakAndContinueScope(BreakAndContinueInfo* info,
2154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                          HOptimizedGraphBuilder* owner)
2155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        : info_(info), owner_(owner), next_(owner->break_scope()) {
2156b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      owner->set_break_scope(this);
2157b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
2158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ~BreakAndContinueScope() { owner_->set_break_scope(next_); }
2160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    BreakAndContinueInfo* info() { return info_; }
2162b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    HOptimizedGraphBuilder* owner() { return owner_; }
2163b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    BreakAndContinueScope* next() { return next_; }
2164b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Search the break stack for a break or continue target.
2166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    enum BreakType { BREAK, CONTINUE };
2167b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    HBasicBlock* Get(BreakableStatement* stmt, BreakType type,
2168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                     Scope** scope, int* drop_extra);
2169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2170b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch   private:
2171b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    BreakAndContinueInfo* info_;
2172b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    HOptimizedGraphBuilder* owner_;
2173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    BreakAndContinueScope* next_;
2174b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  };
2175b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2176b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  explicit HOptimizedGraphBuilder(CompilationInfo* info);
2177b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2178014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool BuildGraph() override;
2179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2180b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Simple accessors.
2181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  BreakAndContinueScope* break_scope() const { return break_scope_; }
2182b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void set_break_scope(BreakAndContinueScope* head) { break_scope_ = head; }
2183b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2184014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HValue* context() override { return environment()->context(); }
2185b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2186b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HOsrBuilder* osr() const { return osr_; }
2187b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2188b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void Bailout(BailoutReason reason);
2189b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2190b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HBasicBlock* CreateJoin(HBasicBlock* first,
2191b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                          HBasicBlock* second,
2192b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                          BailoutId join_id);
2193b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2194b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  FunctionState* function_state() const { return function_state_; }
2195b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2196014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void VisitDeclarations(ZoneList<Declaration*>* declarations) override;
2197b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2198537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch  AstTypeBounds* bounds() { return &bounds_; }
2199537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch
2200014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void* operator new(size_t size, Zone* zone) { return zone->New(size); }
2201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void operator delete(void* pointer, Zone* zone) { }
2202b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void operator delete(void* pointer) { }
2203b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2204b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DEFINE_AST_VISITOR_SUBCLASS_MEMBERS();
2205b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2206b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch protected:
2207b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Forward declarations for inner scope classes.
2208b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  class SubgraphScope;
2209b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static const int kMaxCallPolymorphism = 4;
2211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static const int kMaxLoadPolymorphism = 4;
2212b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static const int kMaxStorePolymorphism = 4;
2213b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2214b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Even in the 'unlimited' case we have to have some limit in order not to
2215b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // overflow the stack.
2216b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static const int kUnlimitedMaxInlinedSourceSize = 100000;
2217b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static const int kUnlimitedMaxInlinedNodes = 10000;
2218b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static const int kUnlimitedMaxInlinedNodesCumulative = 10000;
2219b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Maximum depth and total number of elements and properties for literal
2221b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // graphs to be considered for fast deep-copying.
2222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static const int kMaxFastLiteralDepth = 3;
2223b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static const int kMaxFastLiteralProperties = 8;
2224b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2225b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Simple accessors.
2226b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void set_function_state(FunctionState* state) { function_state_ = state; }
2227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2228b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  AstContext* ast_context() const { return ast_context_; }
2229b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void set_ast_context(AstContext* context) { ast_context_ = context; }
2230b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2231b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Accessors forwarded to the function state.
2232b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CompilationInfo* current_info() const {
2233b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return function_state()->compilation_info();
2234b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2235b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  AstContext* call_context() const {
2236b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return function_state()->call_context();
2237b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HBasicBlock* function_return() const {
2239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return function_state()->function_return();
2240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2241b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  TestContext* inlined_test_context() const {
2242b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return function_state()->test_context();
2243e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  }
224421efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch  Handle<JSFunction> current_closure() const {
224521efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch    return current_info()->closure();
224621efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch  }
2247014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Handle<SharedFunctionInfo> current_shared_info() const {
2248014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return current_info()->shared_info();
2249014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2250014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TypeFeedbackVector* current_feedback_vector() const {
225121efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch    return current_closure()->feedback_vector();
2252014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2253e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  void ClearInlinedTestContext() {
2254e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch    function_state()->ClearInlinedTestContext();
2255e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  }
2256014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  LanguageMode function_language_mode() {
2257537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch    return function_state()->compilation_info()->parse_info()->language_mode();
2258014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2259014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2260014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define FOR_EACH_HYDROGEN_INTRINSIC(F) \
2261014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  F(IsSmi)                             \
2262014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  F(IsArray)                           \
2263014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  F(IsTypedArray)                      \
2264014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  F(IsRegExp)                          \
2265014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  F(IsJSProxy)                         \
2266014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  F(Call)                              \
22671b268ca467c924004286c97bac133db489cf43d0Ben Murdoch  F(NewObject)                         \
2268014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  F(ValueOf)                           \
2269014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  F(StringCharFromCode)                \
2270014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  F(ToInteger)                         \
2271342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch  F(ToName)                            \
2272014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  F(ToObject)                          \
2273014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  F(ToString)                          \
2274014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  F(ToLength)                          \
2275014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  F(ToNumber)                          \
2276014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  F(IsJSReceiver)                      \
2277014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  F(MathPow)                           \
2278014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  F(HasCachedArrayIndex)               \
2279014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  F(GetCachedArrayIndex)               \
2280014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  F(DebugBreakInOptimizedCode)         \
2281014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  F(StringCharCodeAt)                  \
2282014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  F(SubString)                         \
2283014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  F(RegExpExec)                        \
2284014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  F(RegExpConstructResult)             \
2285014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  F(RegExpFlags)                       \
2286014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  F(RegExpSource)                      \
2287014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  F(NumberToString)                    \
2288014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  F(DebugIsActive)                     \
2289014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  /* Typed Arrays */                   \
2290014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  F(TypedArrayInitialize)              \
2291014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  F(MaxSmi)                            \
2292014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  F(TypedArrayMaxSizeInHeap)           \
2293014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  F(ArrayBufferViewGetByteLength)      \
2294014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  F(ArrayBufferViewGetByteOffset)      \
2295014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  F(TypedArrayGetLength)               \
2296014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  /* ArrayBuffer */                    \
2297014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  F(ArrayBufferGetByteLength)          \
2298014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  /* Maths */                          \
2299014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  F(DoubleHi)                          \
2300014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  F(DoubleLo)                          \
2301014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  /* ES6 Collections */                \
2302014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  F(MapClear)                          \
2303014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  F(MapInitialize)                     \
2304014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  F(SetClear)                          \
2305014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  F(SetInitialize)                     \
2306014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  F(FixedArrayGet)                     \
2307014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  F(FixedArraySet)                     \
2308014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  F(JSCollectionGetTable)              \
2309014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  F(StringGetRawHashField)             \
2310014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  F(TheHole)                           \
2311014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  /* ES6 Iterators */                  \
2312014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  F(CreateIterResultObject)            \
2313014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  /* Arrays */                         \
2314342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch  F(HasFastPackedElements)
2315014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2316014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define GENERATOR_DECLARATION(Name) void Generate##Name(CallRuntime* call);
2317014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  FOR_EACH_HYDROGEN_INTRINSIC(GENERATOR_DECLARATION)
2318014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#undef GENERATOR_DECLARATION
2319b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2320257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  void VisitDelete(UnaryOperation* expr);
2321257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  void VisitVoid(UnaryOperation* expr);
2322257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  void VisitTypeof(UnaryOperation* expr);
2323257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  void VisitNot(UnaryOperation* expr);
2324257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
2325257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  void VisitComma(BinaryOperation* expr);
23263fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  void VisitLogicalExpression(BinaryOperation* expr);
23273fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  void VisitArithmeticExpression(BinaryOperation* expr);
2328b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
23293fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  void VisitLoopBody(IterationStatement* stmt,
2330b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                     HBasicBlock* loop_entry);
2331e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
2332014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void BuildForInBody(ForInStatement* stmt, Variable* each_var,
2333014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                      HValue* enumerable);
2334014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2335e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  // Create a back edge in the flow graph.  body_exit is the predecessor
2336e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  // block and loop_entry is the successor block.  loop_successor is the
2337e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  // block where control flow exits the loop normally (e.g., via failure of
2338e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  // the condition) and break_block is the block where control flow breaks
2339e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  // from the loop.  All blocks except loop_entry can be NULL.  The return
2340e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  // value is the new successor block which is the join of loop_successor
2341e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  // and break_block, or NULL.
2342e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  HBasicBlock* CreateLoop(IterationStatement* statement,
2343e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch                          HBasicBlock* loop_entry,
2344e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch                          HBasicBlock* body_exit,
2345e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch                          HBasicBlock* loop_successor,
2346e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch                          HBasicBlock* break_block);
2347e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
2348b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Build a loop entry
2349b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HBasicBlock* BuildLoopEntry();
2350b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2351b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Builds a loop entry respectful of OSR requirements
2352b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HBasicBlock* BuildLoopEntry(IterationStatement* statement);
2353b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2354e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  HBasicBlock* JoinContinue(IterationStatement* statement,
2355e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch                            HBasicBlock* exit_block,
2356e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch                            HBasicBlock* continue_block);
2357b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2358b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  HValue* Top() const { return environment()->Top(); }
2359b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void Drop(int n) { environment()->Drop(n); }
2360b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void Bind(Variable* var, HValue* value) { environment()->Bind(var, value); }
2361b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool IsEligibleForEnvironmentLivenessAnalysis(Variable* var,
2362b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                                int index,
2363b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                                HEnvironment* env) {
2364b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (!FLAG_analyze_environment_liveness) return false;
2365b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // |this| and |arguments| are always live; zapping parameters isn't
2366b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // safe because function.arguments can inspect them at any time.
2367b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return !var->is_this() &&
2368b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch           !var->is_arguments() &&
2369b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch           env->is_local_index(index);
2370b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2371b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void BindIfLive(Variable* var, HValue* value) {
2372b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    HEnvironment* env = environment();
2373b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    int index = env->IndexFor(var);
2374b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    env->Bind(index, value);
237521efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch    if (IsEligibleForEnvironmentLivenessAnalysis(var, index, env)) {
2376b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      HEnvironmentMarker* bind =
2377b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          Add<HEnvironmentMarker>(HEnvironmentMarker::BIND, index);
2378b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      USE(bind);
2379b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef DEBUG
2380b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      bind->set_closure(env->closure());
2381b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif
2382b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
2383b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2384b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HValue* LookupAndMakeLive(Variable* var) {
2385b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    HEnvironment* env = environment();
2386b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    int index = env->IndexFor(var);
238721efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch    if (IsEligibleForEnvironmentLivenessAnalysis(var, index, env)) {
2388b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      HEnvironmentMarker* lookup =
2389b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          Add<HEnvironmentMarker>(HEnvironmentMarker::LOOKUP, index);
2390b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      USE(lookup);
2391b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef DEBUG
2392b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      lookup->set_closure(env->closure());
2393b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif
2394b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
239521efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch    return env->Lookup(index);
2396b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2397b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2398257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // The value of the arguments object is allowed in some but not most value
2399257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // contexts.  (It's allowed in all effect contexts and disallowed in all
2400257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // test contexts.)
2401257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  void VisitForValue(Expression* expr,
2402257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                     ArgumentsAllowedFlag flag = ARGUMENTS_NOT_ALLOWED);
24038b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  void VisitForTypeOf(Expression* expr);
2404b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void VisitForEffect(Expression* expr);
2405b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void VisitForControl(Expression* expr,
2406b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                       HBasicBlock* true_block,
2407b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                       HBasicBlock* false_block);
2408b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2409e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  // Visit a list of expressions from left to right, each in a value context.
2410014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void VisitExpressions(ZoneList<Expression*>* exprs) override;
2411958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void VisitExpressions(ZoneList<Expression*>* exprs,
2412958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                        ArgumentsAllowedFlag flag);
2413e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
2414b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Remove the arguments from the bailout environment and emit instructions
2415b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // to push them as outgoing parameters.
24163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  template <class Instruction> HInstruction* PreProcessCall(Instruction* call);
2417b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void PushArgumentsFromEnvironment(int count);
2418b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
24193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void SetUpScope(Scope* scope);
2420014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void VisitStatements(ZoneList<Statement*>* statements) override;
2421b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2422014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define DECLARE_VISIT(type) void Visit##type(type* node) override;
2423b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  AST_NODE_LIST(DECLARE_VISIT)
2424b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#undef DECLARE_VISIT
2425b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2426b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private:
2427b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Helpers for flow graph construction.
24288b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  enum GlobalPropertyAccess {
24298b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    kUseCell,
24308b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    kUseGeneric
24318b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  };
2432b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GlobalPropertyAccess LookupGlobalProperty(Variable* var, LookupIterator* it,
2433b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                            PropertyAccessType access_type);
2434b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2435b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void EnsureArgumentsArePushedForAccess();
2436b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  bool TryArgumentsAccess(Property* expr);
243742effa50d92d47f80404ee63808dbde9921e6202Ben Murdoch
2438958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // Shared code for .call and .apply optimizations.
2439958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void HandleIndirectCall(Call* expr, HValue* function, int arguments_count);
2440958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // Try to optimize indirect calls such as fun.apply(receiver, arguments)
2441958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // or fun.call(...).
2442958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  bool TryIndirectCall(Call* expr);
2443958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void BuildFunctionApply(Call* expr);
2444958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void BuildFunctionCall(Call* expr);
244542effa50d92d47f80404ee63808dbde9921e6202Ben Murdoch
2446b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool TryHandleArrayCall(Call* expr, HValue* function);
2447b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool TryHandleArrayCallNew(CallNew* expr, HValue* function);
2448b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void BuildArrayCall(Expression* expr, int arguments_count, HValue* function,
2449b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                      Handle<AllocationSite> cell);
2450b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2451b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  enum ArrayIndexOfMode { kFirstIndexOf, kLastIndexOf };
2452b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HValue* BuildArrayIndexOf(HValue* receiver,
2453b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                            HValue* search_element,
2454b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                            ElementsKind kind,
2455b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                            ArrayIndexOfMode mode);
2456b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2457b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HValue* ImplicitReceiverFor(HValue* function,
2458b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                              Handle<JSFunction> target);
2459b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2460b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int InliningAstSize(Handle<JSFunction> target);
2461014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool TryInline(Handle<JSFunction> target, int arguments_count,
2462014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                 HValue* implicit_return_value, BailoutId ast_id,
24631b268ca467c924004286c97bac133db489cf43d0Ben Murdoch                 BailoutId return_id, InliningKind inlining_kind,
24641b268ca467c924004286c97bac133db489cf43d0Ben Murdoch                 TailCallMode syntactic_tail_call_mode);
2465b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2466b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool TryInlineCall(Call* expr);
2467b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool TryInlineConstruct(CallNew* expr, HValue* implicit_return_value);
2468342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch  bool TryInlineGetter(Handle<Object> getter, Handle<Map> receiver_map,
2469342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch                       BailoutId ast_id, BailoutId return_id);
2470342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch  bool TryInlineSetter(Handle<Object> setter, Handle<Map> receiver_map,
2471342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch                       BailoutId id, BailoutId assignment_id,
2472b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                       HValue* implicit_return_value);
2473958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  bool TryInlineIndirectCall(Handle<JSFunction> function, Call* expr,
2474958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                             int arguments_count);
247521efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch  bool TryInlineBuiltinGetterCall(Handle<JSFunction> function,
247621efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch                                  Handle<Map> receiver_map, BailoutId ast_id);
247721efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch  bool TryInlineBuiltinMethodCall(Handle<JSFunction> function,
247821efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch                                  Handle<Map> receiver_map, BailoutId ast_id,
2479958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                                  int args_count_no_receiver);
2480b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool TryInlineBuiltinFunctionCall(Call* expr);
2481b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  enum ApiCallType {
2482b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    kCallApiFunction,
2483b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    kCallApiMethod,
2484b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    kCallApiGetter,
2485b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    kCallApiSetter
2486b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  };
2487b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool TryInlineApiMethodCall(Call* expr,
2488b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                              HValue* receiver,
2489b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                              SmallMapList* receiver_types);
2490b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool TryInlineApiFunctionCall(Call* expr, HValue* receiver);
2491342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch  bool TryInlineApiGetter(Handle<Object> function, Handle<Map> receiver_map,
2492b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                          BailoutId ast_id);
2493342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch  bool TryInlineApiSetter(Handle<Object> function, Handle<Map> receiver_map,
2494b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                          BailoutId ast_id);
2495342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch  bool TryInlineApiCall(Handle<Object> function, HValue* receiver,
2496342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch                        SmallMapList* receiver_maps, int argc, BailoutId ast_id,
24971b268ca467c924004286c97bac133db489cf43d0Ben Murdoch                        ApiCallType call_type,
24981b268ca467c924004286c97bac133db489cf43d0Ben Murdoch                        TailCallMode syntactic_tail_call_mode);
2499014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static bool IsReadOnlyLengthDescriptor(Handle<Map> jsarray_map);
2500014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static bool CanInlineArrayResizeOperation(Handle<Map> receiver_map);
2501e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
2502e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  // If --trace-inlining, print a line of the inlining trace.  Inlining
2503e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  // succeeded if the reason string is NULL and failed if there is a
2504e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  // non-NULL reason string.
25051b268ca467c924004286c97bac133db489cf43d0Ben Murdoch  void TraceInline(Handle<JSFunction> target, Handle<JSFunction> caller,
25061b268ca467c924004286c97bac133db489cf43d0Ben Murdoch                   const char* failure_reason,
25071b268ca467c924004286c97bac133db489cf43d0Ben Murdoch                   TailCallMode tail_call_mode = TailCallMode::kDisallow);
2508b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2509014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void HandleGlobalVariableAssignment(Variable* var, HValue* value,
2510014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                      FeedbackVectorSlot slot,
2511b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                      BailoutId ast_id);
2512b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2513b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void HandlePropertyAssignment(Assignment* expr);
2514b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void HandleCompoundAssignment(Assignment* expr);
2515014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void HandlePolymorphicNamedFieldAccess(
2516014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      PropertyAccessType access_type, Expression* expr, FeedbackVectorSlot slot,
2517014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      BailoutId ast_id, BailoutId return_id, HValue* object, HValue* value,
2518014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      SmallMapList* types, Handle<Name> name);
2519b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2520b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HValue* BuildAllocateExternalElements(
2521b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      ExternalArrayType array_type,
2522b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      bool is_zero_byte_offset,
2523b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      HValue* buffer, HValue* byte_offset, HValue* length);
2524014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HValue* BuildAllocateFixedTypedArray(ExternalArrayType array_type,
2525014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                       size_t element_size,
2526014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                       ElementsKind fixed_elements_kind,
2527014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                       HValue* byte_length, HValue* length,
2528014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                       bool initialize);
2529b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2530958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // TODO(adamk): Move all OrderedHashTable functions to their own class.
2531958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  HValue* BuildOrderedHashTableHashToBucket(HValue* hash, HValue* num_buckets);
2532958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  template <typename CollectionType>
2533958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  HValue* BuildOrderedHashTableHashToEntry(HValue* table, HValue* hash,
2534958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                                           HValue* num_buckets);
2535958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  template <typename CollectionType>
2536958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  HValue* BuildOrderedHashTableEntryToIndex(HValue* entry, HValue* num_buckets);
2537958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  template <typename CollectionType>
2538958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  HValue* BuildOrderedHashTableFindEntry(HValue* table, HValue* key,
2539958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                                         HValue* hash);
2540958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  template <typename CollectionType>
2541958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  HValue* BuildOrderedHashTableAddEntry(HValue* table, HValue* key,
2542958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                                        HValue* hash,
2543958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                                        HIfContinuation* join_continuation);
2544958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  template <typename CollectionType>
2545958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  HValue* BuildAllocateOrderedHashTable();
2546958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  template <typename CollectionType>
2547958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void BuildOrderedHashTableClear(HValue* receiver);
2548958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  template <typename CollectionType>
2549958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void BuildJSCollectionDelete(CallRuntime* call,
2550958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                               const Runtime::Function* c_function);
2551958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  template <typename CollectionType>
2552958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void BuildJSCollectionHas(CallRuntime* call,
2553958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                            const Runtime::Function* c_function);
2554958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  HValue* BuildStringHashLoadIfIsStringAndHashComputed(
2555958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      HValue* object, HIfContinuation* continuation);
2556958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
2557b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Handle<JSFunction> array_function() {
2558b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return handle(isolate()->native_context()->array_function());
2559b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2560b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2561b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool IsCallArrayInlineable(int argument_count, Handle<AllocationSite> site);
2562b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void BuildInlinedCallArray(Expression* expression, int argument_count,
2563b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                             Handle<AllocationSite> site);
2564b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2565014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void BuildInitializeInobjectProperties(HValue* receiver,
2566014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                         Handle<Map> initial_map);
2567014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2568b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  class PropertyAccessInfo {
2569b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch   public:
2570b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    PropertyAccessInfo(HOptimizedGraphBuilder* builder,
2571014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                       PropertyAccessType access_type, Handle<Map> map,
2572014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                       Handle<Name> name)
2573014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        : builder_(builder),
2574b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          access_type_(access_type),
2575014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          map_(map),
2576342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch          name_(isolate()->factory()->InternalizeName(name)),
2577b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          field_type_(HType::Tagged()),
2578014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          access_(HObjectAccess::ForMap()),
2579014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          lookup_type_(NOT_FOUND),
2580014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          details_(NONE, DATA, Representation::None()) {}
2581b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2582b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Checkes whether this PropertyAccessInfo can be handled as a monomorphic
2583b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // load named. It additionally fills in the fields necessary to generate the
2584b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // lookup code.
2585b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    bool CanAccessMonomorphic();
2586b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2587b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Checks whether all types behave uniform when loading name. If all maps
2588b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // behave the same, a single monomorphic load instruction can be emitted,
2589b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // guarded by a single map-checks instruction that whether the receiver is
2590b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // an instance of any of the types.
2591b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // This method skips the first type in types, assuming that this
2592b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // PropertyAccessInfo is built for types->first().
2593b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    bool CanAccessAsMonomorphic(SmallMapList* types);
2594b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2595014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bool NeedsWrappingFor(Handle<JSFunction> target) const;
2596014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2597b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Handle<Map> map();
2598014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Handle<Name> name() const { return name_; }
2599b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2600b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    bool IsJSObjectFieldAccessor() {
2601b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      int offset;  // unused
2602014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return Accessors::IsJSObjectFieldAccessor(map_, name_, &offset);
2603b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
2604b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2605b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    bool GetJSObjectFieldAccess(HObjectAccess* access) {
2606b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      int offset;
2607014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (Accessors::IsJSObjectFieldAccessor(map_, name_, &offset)) {
2608014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        if (IsStringType()) {
2609014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          DCHECK(Name::Equals(isolate()->factory()->length_string(), name_));
2610b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          *access = HObjectAccess::ForStringLength();
2611014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        } else if (IsArrayType()) {
2612014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          DCHECK(Name::Equals(isolate()->factory()->length_string(), name_));
2613014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          *access = HObjectAccess::ForArrayLength(map_->elements_kind());
2614b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        } else {
2615014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          *access = HObjectAccess::ForMapAndOffset(map_, offset);
2616b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        }
2617b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        return true;
2618b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
2619b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return false;
2620b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
2621b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2622b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    bool has_holder() { return !holder_.is_null(); }
2623b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    bool IsLoad() const { return access_type_ == LOAD; }
2624b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2625014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Isolate* isolate() const { return builder_->isolate(); }
2626b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Handle<JSObject> holder() { return holder_; }
2627342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch    Handle<Object> accessor() { return accessor_; }
2628b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Handle<Object> constant() { return constant_; }
2629014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Handle<Map> transition() { return transition_; }
2630b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SmallMapList* field_maps() { return &field_maps_; }
2631b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    HType field_type() const { return field_type_; }
2632b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    HObjectAccess access() { return access_; }
2633b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2634014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bool IsFound() const { return lookup_type_ != NOT_FOUND; }
2635014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bool IsProperty() const { return IsFound() && !IsTransition(); }
2636014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bool IsTransition() const { return lookup_type_ == TRANSITION_TYPE; }
2637014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bool IsData() const {
2638014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return lookup_type_ == DESCRIPTOR_TYPE && details_.type() == DATA;
2639014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
2640014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bool IsDataConstant() const {
2641014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return lookup_type_ == DESCRIPTOR_TYPE &&
2642014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch             details_.type() == DATA_CONSTANT;
2643014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
2644014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bool IsAccessorConstant() const {
2645014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return !IsTransition() && details_.type() == ACCESSOR_CONSTANT;
2646014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
2647014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bool IsConfigurable() const { return details_.IsConfigurable(); }
2648014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bool IsReadOnly() const { return details_.IsReadOnly(); }
2649b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2650014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bool IsStringType() { return map_->instance_type() < FIRST_NONSTRING_TYPE; }
2651014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bool IsNumberType() { return map_->instance_type() == HEAP_NUMBER_TYPE; }
2652014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bool IsValueWrapped() { return IsStringType() || IsNumberType(); }
2653014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bool IsArrayType() { return map_->instance_type() == JS_ARRAY_TYPE; }
2654b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2655b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch   private:
2656b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Handle<Object> GetConstantFromMap(Handle<Map> map) const {
2657014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      DCHECK_EQ(DESCRIPTOR_TYPE, lookup_type_);
2658014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      DCHECK(number_ < map->NumberOfOwnDescriptors());
2659014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return handle(map->instance_descriptors()->GetValue(number_), isolate());
2660014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
2661014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Handle<Object> GetAccessorsFromMap(Handle<Map> map) const {
2662014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return GetConstantFromMap(map);
2663b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
2664342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch    Handle<FieldType> GetFieldTypeFromMap(Handle<Map> map) const;
2665b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Handle<Map> GetFieldOwnerFromMap(Handle<Map> map) const {
2666014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      DCHECK(IsFound());
2667014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      DCHECK(number_ < map->NumberOfOwnDescriptors());
2668014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return handle(map->FindFieldOwner(number_));
2669b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
2670b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    int GetLocalFieldIndexFromMap(Handle<Map> map) const {
2671014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      DCHECK(lookup_type_ == DESCRIPTOR_TYPE ||
2672014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch             lookup_type_ == TRANSITION_TYPE);
2673014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      DCHECK(number_ < map->NumberOfOwnDescriptors());
2674014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int field_index = map->instance_descriptors()->GetFieldIndex(number_);
2675014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return field_index - map->GetInObjectProperties();
2676014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
2677014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2678014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    void LookupDescriptor(Map* map, Name* name) {
2679014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      DescriptorArray* descriptors = map->instance_descriptors();
2680342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch      int number = descriptors->SearchWithCache(isolate(), name, map);
2681014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (number == DescriptorArray::kNotFound) return NotFound();
2682014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      lookup_type_ = DESCRIPTOR_TYPE;
2683014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      details_ = descriptors->GetDetails(number);
2684014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      number_ = number;
2685014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
2686014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    void LookupTransition(Map* map, Name* name, PropertyAttributes attributes) {
2687014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Map* target =
2688014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          TransitionArray::SearchTransition(map, kData, name, attributes);
2689014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (target == NULL) return NotFound();
2690014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      lookup_type_ = TRANSITION_TYPE;
2691014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      transition_ = handle(target);
2692014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      number_ = transition_->LastAdded();
2693014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      details_ = transition_->instance_descriptors()->GetDetails(number_);
2694014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
2695014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    void NotFound() {
2696014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      lookup_type_ = NOT_FOUND;
2697014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      details_ = PropertyDetails::Empty();
2698014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
2699014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Representation representation() const {
2700014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      DCHECK(IsFound());
2701014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return details_.representation();
2702014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
2703014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bool IsTransitionToData() const {
2704014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return IsTransition() && details_.type() == DATA;
2705b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
2706b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2707b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Zone* zone() { return builder_->zone(); }
2708b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CompilationInfo* top_info() { return builder_->top_info(); }
2709b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CompilationInfo* current_info() { return builder_->current_info(); }
2710b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2711b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    bool LoadResult(Handle<Map> map);
2712014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bool LoadFieldMaps(Handle<Map> map);
2713b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    bool LookupDescriptor();
2714b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    bool LookupInPrototypes();
2715014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bool IsIntegerIndexedExotic();
2716b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    bool IsCompatible(PropertyAccessInfo* other);
2717b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2718b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    void GeneralizeRepresentation(Representation r) {
2719b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      access_ = access_.WithRepresentation(
2720b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          access_.representation().generalize(r));
2721b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
2722b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2723b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    HOptimizedGraphBuilder* builder_;
2724b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    PropertyAccessType access_type_;
2725014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Handle<Map> map_;
2726014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Handle<Name> name_;
2727b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Handle<JSObject> holder_;
2728342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch    Handle<Object> accessor_;
2729b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Handle<JSObject> api_holder_;
2730b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Handle<Object> constant_;
2731b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SmallMapList field_maps_;
2732b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    HType field_type_;
2733b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    HObjectAccess access_;
2734014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2735014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    enum { NOT_FOUND, DESCRIPTOR_TYPE, TRANSITION_TYPE } lookup_type_;
2736014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Handle<Map> transition_;
2737014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    int number_;
2738014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    PropertyDetails details_;
2739b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  };
2740b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2741014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HValue* BuildMonomorphicAccess(PropertyAccessInfo* info, HValue* object,
2742014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                 HValue* checked_object, HValue* value,
2743014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                 BailoutId ast_id, BailoutId return_id,
2744014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                 bool can_inline_accessor = true);
2745014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2746014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HValue* BuildNamedAccess(PropertyAccessType access, BailoutId ast_id,
2747014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                           BailoutId reutrn_id, Expression* expr,
2748014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                           FeedbackVectorSlot slot, HValue* object,
2749014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                           Handle<Name> name, HValue* value,
2750014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                           bool is_uninitialized = false);
2751b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2752b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void HandlePolymorphicCallNamed(Call* expr,
2753b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                                  HValue* receiver,
275469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch                                  SmallMapList* types,
2755b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                                  Handle<String> name);
27563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void HandleLiteralCompareTypeof(CompareOperation* expr,
2757b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                  Expression* sub_expr,
27583fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                                  Handle<String> check);
27593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void HandleLiteralCompareNil(CompareOperation* expr,
2760b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                               Expression* sub_expr,
27613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                               NilValue nil);
27623fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
2763b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  enum PushBeforeSimulateBehavior {
2764b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    PUSH_BEFORE_SIMULATE,
2765b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    NO_PUSH_BEFORE_SIMULATE
2766b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  };
2767b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2768b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HControlInstruction* BuildCompareInstruction(
2769014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Token::Value op, HValue* left, HValue* right, Type* left_type,
2770014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Type* right_type, Type* combined_type, SourcePosition left_position,
2771014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      SourcePosition right_position, PushBeforeSimulateBehavior push_sim_result,
2772b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      BailoutId bailout_id);
2773b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2774b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HInstruction* BuildStringCharCodeAt(HValue* string,
2775b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                      HValue* index);
2776b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2777b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HValue* BuildBinaryOperation(
2778b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      BinaryOperation* expr,
2779b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      HValue* left,
2780b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      HValue* right,
2781b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      PushBeforeSimulateBehavior push_sim_result);
2782257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  HInstruction* BuildIncrement(bool returns_original_input,
2783257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                               CountOperation* expr);
2784b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HInstruction* BuildKeyedGeneric(PropertyAccessType access_type,
2785014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                  Expression* expr, FeedbackVectorSlot slot,
2786014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                  HValue* object, HValue* key, HValue* value);
2787b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2788b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HInstruction* TryBuildConsolidatedElementLoad(HValue* object,
2789b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                                HValue* key,
2790b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                                HValue* val,
2791b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                                SmallMapList* maps);
2792b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2793b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LoadKeyedHoleMode BuildKeyedHoleMode(Handle<Map> map);
27943fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
27953fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  HInstruction* BuildMonomorphicElementAccess(HValue* object,
27963fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                                              HValue* key,
27973fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                                              HValue* val,
2798b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                              HValue* dependency,
27993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                              Handle<Map> map,
2800b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                              PropertyAccessType access_type,
2801b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                              KeyedAccessStoreMode store_mode);
2802b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2803014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HValue* HandlePolymorphicElementAccess(
2804014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Expression* expr, FeedbackVectorSlot slot, HValue* object, HValue* key,
2805014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      HValue* val, SmallMapList* maps, PropertyAccessType access_type,
2806014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      KeyedAccessStoreMode store_mode, bool* has_side_effects);
28073fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
2808b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HValue* HandleKeyedElementAccess(HValue* obj, HValue* key, HValue* val,
2809014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                   Expression* expr, FeedbackVectorSlot slot,
2810014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                   BailoutId ast_id, BailoutId return_id,
2811b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                   PropertyAccessType access_type,
28123fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                                   bool* has_side_effects);
28138b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
2814014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HInstruction* BuildNamedGeneric(PropertyAccessType access, Expression* expr,
2815014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                  FeedbackVectorSlot slot, HValue* object,
2816014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                  Handle<Name> name, HValue* value,
2817b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                  bool is_uninitialized = false);
2818b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2819b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HCheckMaps* AddCheckMap(HValue* object, Handle<Map> map);
2820b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2821b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void BuildLoad(Property* property,
2822b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                 BailoutId ast_id);
2823b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void PushLoad(Property* property,
2824b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                HValue* object,
2825b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                HValue* key);
2826b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2827014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void BuildStoreForEffect(Expression* expression, Property* prop,
2828014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                           FeedbackVectorSlot slot, BailoutId ast_id,
2829014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                           BailoutId return_id, HValue* object, HValue* key,
2830b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                           HValue* value);
2831b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2832014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void BuildStore(Expression* expression, Property* prop,
2833014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                  FeedbackVectorSlot slot, BailoutId ast_id,
2834014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                  BailoutId return_id, bool is_uninitialized = false);
2835b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2836b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HInstruction* BuildLoadNamedField(PropertyAccessInfo* info,
2837b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                    HValue* checked_object);
2838b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HInstruction* BuildStoreNamedField(PropertyAccessInfo* info,
2839b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                     HValue* checked_object,
2840b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                     HValue* value);
2841b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
28421e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  HValue* BuildContextChainWalk(Variable* var);
28431e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
2844014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HValue* AddThisFunction();
2845b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HInstruction* BuildThisFunction();
2846b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2847b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HInstruction* BuildFastLiteral(Handle<JSObject> boilerplate_object,
2848b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                 AllocationSiteUsageContext* site_context);
2849b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2850b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void BuildEmitObjectHeader(Handle<JSObject> boilerplate_object,
2851b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                             HInstruction* object);
2852b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2853b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void BuildEmitInObjectProperties(Handle<JSObject> boilerplate_object,
2854b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                   HInstruction* object,
2855b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                   AllocationSiteUsageContext* site_context,
2856b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                   PretenureFlag pretenure_flag);
2857b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2858b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void BuildEmitElements(Handle<JSObject> boilerplate_object,
2859b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                         Handle<FixedArrayBase> elements,
2860b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                         HValue* object_elements,
2861b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                         AllocationSiteUsageContext* site_context);
2862b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2863b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void BuildEmitFixedDoubleArray(Handle<FixedArrayBase> elements,
2864b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                 ElementsKind kind,
2865b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                 HValue* object_elements);
2866b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2867b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void BuildEmitFixedArray(Handle<FixedArrayBase> elements,
2868b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                           ElementsKind kind,
2869b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                           HValue* object_elements,
2870b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                           AllocationSiteUsageContext* site_context);
2871b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2872b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void AddCheckPrototypeMaps(Handle<JSObject> holder,
2873b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                             Handle<Map> receiver_map);
2874b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
28751b268ca467c924004286c97bac133db489cf43d0Ben Murdoch  void BuildEnsureCallable(HValue* object);
28761b268ca467c924004286c97bac133db489cf43d0Ben Murdoch
28771b268ca467c924004286c97bac133db489cf43d0Ben Murdoch  HInstruction* NewCallFunction(HValue* function, int argument_count,
28781b268ca467c924004286c97bac133db489cf43d0Ben Murdoch                                TailCallMode syntactic_tail_call_mode,
28791b268ca467c924004286c97bac133db489cf43d0Ben Murdoch                                ConvertReceiverMode convert_mode,
28801b268ca467c924004286c97bac133db489cf43d0Ben Murdoch                                TailCallMode tail_call_mode);
2881b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
28821b268ca467c924004286c97bac133db489cf43d0Ben Murdoch  HInstruction* NewCallFunctionViaIC(HValue* function, int argument_count,
28831b268ca467c924004286c97bac133db489cf43d0Ben Murdoch                                     TailCallMode syntactic_tail_call_mode,
28841b268ca467c924004286c97bac133db489cf43d0Ben Murdoch                                     ConvertReceiverMode convert_mode,
28851b268ca467c924004286c97bac133db489cf43d0Ben Murdoch                                     TailCallMode tail_call_mode,
28861b268ca467c924004286c97bac133db489cf43d0Ben Murdoch                                     FeedbackVectorSlot slot);
2887b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
28881b268ca467c924004286c97bac133db489cf43d0Ben Murdoch  HInstruction* NewCallConstantFunction(Handle<JSFunction> target,
28891b268ca467c924004286c97bac133db489cf43d0Ben Murdoch                                        int argument_count,
28901b268ca467c924004286c97bac133db489cf43d0Ben Murdoch                                        TailCallMode syntactic_tail_call_mode,
28911b268ca467c924004286c97bac133db489cf43d0Ben Murdoch                                        TailCallMode tail_call_mode);
2892b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2893958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  bool CanBeFunctionApplyArguments(Call* expr);
2894958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
2895e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  // The translation state of the currently-being-translated function.
2896e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  FunctionState* function_state_;
2897e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
2898e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  // The base of the function state stack.
2899e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  FunctionState initial_function_state_;
2900e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
2901b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Expression context of the currently visited subexpression. NULL when
2902b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // visiting statements.
2903b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  AstContext* ast_context_;
2904b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2905e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  // A stack of breakable statements entered.
2906e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  BreakAndContinueScope* break_scope_;
2907b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2908b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  int inlined_count_;
2909b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ZoneList<Handle<Object> > globals_;
29108b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
2911257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  bool inline_bailout_;
2912257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
2913b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HOsrBuilder* osr_;
2914b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2915537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch  AstTypeBounds bounds_;
2916537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch
2917e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  friend class FunctionState;  // Pushes and pops the state stack.
2918b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  friend class AstContext;  // Pushes and pops the AST context stack.
2919b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  friend class KeyedLoadFastElementStub;
2920b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  friend class HOsrBuilder;
2921b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2922b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DISALLOW_COPY_AND_ASSIGN(HOptimizedGraphBuilder);
2923b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch};
2924b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2925b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2926b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochZone* AstContext::zone() const { return owner_->zone(); }
29278b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
29288b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
2929014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass HStatistics final : public Malloced {
2930b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch public:
2931b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HStatistics()
2932b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      : times_(5),
2933b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        names_(5),
2934b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        sizes_(5),
2935b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        total_size_(0),
2936b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        source_size_(0) { }
2937b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2938b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void Initialize(CompilationInfo* info);
2939958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void Print();
2940014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void SaveTiming(const char* name, base::TimeDelta time, size_t size);
2941b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2942b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void IncrementFullCodeGen(base::TimeDelta full_code_gen) {
2943b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    full_code_gen_ += full_code_gen;
2944b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
2945b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2946b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void IncrementCreateGraph(base::TimeDelta delta) { create_graph_ += delta; }
29478b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
2948b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void IncrementOptimizeGraph(base::TimeDelta delta) {
2949b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    optimize_graph_ += delta;
29508b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  }
2951b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2952b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void IncrementGenerateCode(base::TimeDelta delta) { generate_code_ += delta; }
2953b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2954b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void IncrementSubtotals(base::TimeDelta create_graph,
2955b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                          base::TimeDelta optimize_graph,
2956b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                          base::TimeDelta generate_code) {
2957b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    IncrementCreateGraph(create_graph);
2958b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    IncrementOptimizeGraph(optimize_graph);
2959b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    IncrementGenerateCode(generate_code);
2960b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
2961b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2962b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch private:
2963b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  List<base::TimeDelta> times_;
2964b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  List<const char*> names_;
2965014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  List<size_t> sizes_;
2966b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  base::TimeDelta create_graph_;
2967b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  base::TimeDelta optimize_graph_;
2968b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  base::TimeDelta generate_code_;
2969014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  size_t total_size_;
2970b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  base::TimeDelta full_code_gen_;
297144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  double source_size_;
2972b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch};
2973b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2974b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2975b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass HPhase : public CompilationPhase {
2976b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch public:
2977b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HPhase(const char* name, HGraph* graph)
2978b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      : CompilationPhase(name, graph->info()),
2979b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        graph_(graph) { }
2980b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ~HPhase();
2981b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2982b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch protected:
2983b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HGraph* graph() const { return graph_; }
2984b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2985b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch private:
2986b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  HGraph* graph_;
2987b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2988b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DISALLOW_COPY_AND_ASSIGN(HPhase);
2989b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch};
2990b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2991b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2992014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass HTracer final : public Malloced {
2993b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch public:
2994b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  explicit HTracer(int isolate_id)
2995b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      : trace_(&string_allocator_), indent_(0) {
2996b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (FLAG_trace_hydrogen_file == NULL) {
2997b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      SNPrintF(filename_,
2998b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch               "hydrogen-%d-%d.cfg",
2999b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch               base::OS::GetCurrentProcessId(),
3000b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch               isolate_id);
3001b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else {
3002b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      StrNCpy(filename_, FLAG_trace_hydrogen_file, filename_.length());
3003b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
3004b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    WriteChars(filename_.start(), "", 0, false);
3005b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3006b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3007b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void TraceCompilation(CompilationInfo* info);
3008b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void TraceHydrogen(const char* name, HGraph* graph);
3009b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void TraceLithium(const char* name, LChunk* chunk);
3010b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void TraceLiveRanges(const char* name, LAllocator* allocator);
3011b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
3012b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch private:
3013014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  class Tag final BASE_EMBEDDED {
3014b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch   public:
3015b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    Tag(HTracer* tracer, const char* name) {
3016b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      name_ = name;
3017b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      tracer_ = tracer;
3018b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      tracer->PrintIndent();
3019b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      tracer->trace_.Add("begin_%s\n", name);
3020b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      tracer->indent_++;
3021b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    }
3022b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
3023b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    ~Tag() {
3024b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      tracer_->indent_--;
3025b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      tracer_->PrintIndent();
3026b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      tracer_->trace_.Add("end_%s\n", name_);
3027b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      DCHECK(tracer_->indent_ >= 0);
3028b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      tracer_->FlushToFile();
3029b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    }
3030b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
3031b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch   private:
3032b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    HTracer* tracer_;
3033b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    const char* name_;
3034b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  };
3035b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
3036b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void TraceLiveRange(LiveRange* range, const char* type, Zone* zone);
3037b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void Trace(const char* name, HGraph* graph, LChunk* chunk);
3038b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void FlushToFile();
3039b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
3040b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void PrintEmptyProperty(const char* name) {
3041b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    PrintIndent();
3042b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    trace_.Add("%s\n", name);
3043b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
3044b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
3045b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void PrintStringProperty(const char* name, const char* value) {
3046b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    PrintIndent();
3047b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    trace_.Add("%s \"%s\"\n", name, value);
3048b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
3049b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
3050b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void PrintLongProperty(const char* name, int64_t value) {
3051b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    PrintIndent();
3052b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    trace_.Add("%s %d000\n", name, static_cast<int>(value / 1000));
3053b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
3054b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
3055b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void PrintBlockProperty(const char* name, int block_id) {
3056b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    PrintIndent();
3057b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    trace_.Add("%s \"B%d\"\n", name, block_id);
3058b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
3059b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
3060b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void PrintIntProperty(const char* name, int value) {
3061b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    PrintIndent();
3062b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    trace_.Add("%s %d\n", name, value);
3063b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
3064b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
3065b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void PrintIndent() {
3066b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    for (int i = 0; i < indent_; i++) {
3067b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      trace_.Add("  ");
3068b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    }
3069b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
3070b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
3071b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EmbeddedVector<char, 64> filename_;
3072b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  HeapStringAllocator string_allocator_;
3073b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  StringStream trace_;
3074b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  int indent_;
3075b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch};
3076b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
3077b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
3078014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass NoObservableSideEffectsScope final {
3079b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public:
3080b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  explicit NoObservableSideEffectsScope(HGraphBuilder* builder) :
3081b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      builder_(builder) {
3082b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    builder_->graph()->IncrementInNoSideEffectsScope();
3083b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3084b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ~NoObservableSideEffectsScope() {
3085b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    builder_->graph()->DecrementInNoSideEffectsScope();
3086b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3087b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3088b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private:
3089b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HGraphBuilder* builder_;
3090b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
3091b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
30921b268ca467c924004286c97bac133db489cf43d0Ben Murdochclass DoExpressionScope final {
30931b268ca467c924004286c97bac133db489cf43d0Ben Murdoch public:
30941b268ca467c924004286c97bac133db489cf43d0Ben Murdoch  explicit DoExpressionScope(HOptimizedGraphBuilder* builder)
30951b268ca467c924004286c97bac133db489cf43d0Ben Murdoch      : builder_(builder) {
30961b268ca467c924004286c97bac133db489cf43d0Ben Murdoch    builder_->function_state()->IncrementInDoExpressionScope();
30971b268ca467c924004286c97bac133db489cf43d0Ben Murdoch  }
30981b268ca467c924004286c97bac133db489cf43d0Ben Murdoch  ~DoExpressionScope() {
30991b268ca467c924004286c97bac133db489cf43d0Ben Murdoch    builder_->function_state()->DecrementInDoExpressionScope();
31001b268ca467c924004286c97bac133db489cf43d0Ben Murdoch  }
31011b268ca467c924004286c97bac133db489cf43d0Ben Murdoch
31021b268ca467c924004286c97bac133db489cf43d0Ben Murdoch private:
31031b268ca467c924004286c97bac133db489cf43d0Ben Murdoch  HOptimizedGraphBuilder* builder_;
31041b268ca467c924004286c97bac133db489cf43d0Ben Murdoch};
3105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3106014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}  // namespace internal
3107014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}  // namespace v8
3108b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
3109014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#endif  // V8_CRANKSHAFT_HYDROGEN_H_
3110