105ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org// Copyright 2012 the V8 project authors. All rights reserved.
23484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org// Use of this source code is governed by a BSD-style license that can be
33484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org// found in the LICENSE file.
4a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
5a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#ifndef V8_HYDROGEN_H_
6a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#define V8_HYDROGEN_H_
7a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
8196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/v8.h"
9a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
10196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/accessors.h"
11196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/allocation.h"
12196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/ast.h"
13b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org#include "src/bailout-reason.h"
14196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/compiler.h"
15196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/hydrogen-instructions.h"
16196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/scopes.h"
174b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org#include "src/zone.h"
18a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
19a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgnamespace v8 {
20a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgnamespace internal {
21a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
22a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// Forward declarations.
23fb144a0716afe7ab8bf245f2391a9e53b3db3c89fschneider@chromium.orgclass BitVector;
2428faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.orgclass FunctionState;
25a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgclass HEnvironment;
26a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgclass HGraph;
27a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgclass HLoopInformation;
28c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.orgclass HOsrBuilder;
29a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgclass HTracer;
30a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgclass LAllocator;
3128583c92ca8f528df625800519088ac88996d504jkummerow@chromium.orgclass LChunk;
32a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgclass LiveRange;
33a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
34a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
35ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.orgclass HBasicBlock FINAL : public ZoneObject {
36a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org public:
37a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  explicit HBasicBlock(HGraph* graph);
3832cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org  ~HBasicBlock() { }
39a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
40a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Simple accessors.
41a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  int block_id() const { return block_id_; }
42a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void set_block_id(int id) { block_id_ = id; }
43a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  HGraph* graph() const { return graph_; }
44750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  Isolate* isolate() const;
45a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  const ZoneList<HPhi*>* phis() const { return &phis_; }
46a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  HInstruction* first() const { return first_; }
4749edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org  HInstruction* last() const { return last_; }
4849edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org  void set_last(HInstruction* instr) { last_ = instr; }
49a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  HControlInstruction* end() const { return end_; }
50a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  HLoopInformation* loop_information() const { return loop_information_; }
51fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  HLoopInformation* current_loop() const {
52fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org    return IsLoopHeader() ? loop_information()
53fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org                          : (parent_loop_header() != NULL
54fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org                            ? parent_loop_header()->loop_information() : NULL);
55fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  }
56a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  const ZoneList<HBasicBlock*>* predecessors() const { return &predecessors_; }
57a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  bool HasPredecessor() const { return predecessors_.length() > 0; }
58a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  const ZoneList<HBasicBlock*>* dominated_blocks() const {
59a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    return &dominated_blocks_;
60a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
61a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  const ZoneList<int>* deleted_phis() const {
62a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    return &deleted_phis_;
63a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
64a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void RecordDeletedPhi(int merge_index) {
657028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org    deleted_phis_.Add(merge_index, zone());
66a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
67a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  HBasicBlock* dominator() const { return dominator_; }
68a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  HEnvironment* last_environment() const { return last_environment_; }
69a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  int argument_count() const { return argument_count_; }
70a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void set_argument_count(int count) { argument_count_ = count; }
71a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  int first_instruction_index() const { return first_instruction_index_; }
72a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void set_first_instruction_index(int index) {
73a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    first_instruction_index_ = index;
74a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
75a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  int last_instruction_index() const { return last_instruction_index_; }
76a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void set_last_instruction_index(int index) {
77a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    last_instruction_index_ = index;
78a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
797c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org  bool is_osr_entry() { return is_osr_entry_; }
807c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org  void set_osr_entry() { is_osr_entry_ = true; }
81a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
82a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void AttachLoopInformation();
83a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void DetachLoopInformation();
84a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  bool IsLoopHeader() const { return loop_information() != NULL; }
85a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  bool IsStartBlock() const { return block_id() == 0; }
86a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void PostProcessLoopHeader(IterationStatement* stmt);
87a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
88a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  bool IsFinished() const { return end_ != NULL; }
89a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void AddPhi(HPhi* phi);
90a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void RemovePhi(HPhi* phi);
91f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  void AddInstruction(HInstruction* instr, HSourcePosition position);
92a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  bool Dominates(HBasicBlock* other) const;
9357a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org  bool EqualToOrDominates(HBasicBlock* other) const;
9483e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org  int LoopNestingDepth() const;
95a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
96b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org  void SetInitialEnvironment(HEnvironment* env);
97d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  void ClearEnvironment() {
98e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(IsFinished());
99e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(end()->SuccessorCount() == 0);
100d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org    last_environment_ = NULL;
101d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  }
102a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  bool HasEnvironment() const { return last_environment_ != NULL; }
103d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  void UpdateEnvironment(HEnvironment* env);
104496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org  HBasicBlock* parent_loop_header() const { return parent_loop_header_; }
105a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
106a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void set_parent_loop_header(HBasicBlock* block) {
107e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(parent_loop_header_ == NULL);
108496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org    parent_loop_header_ = block;
109a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
110a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
111496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org  bool HasParentLoopHeader() const { return parent_loop_header_ != NULL; }
112a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
113471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org  void SetJoinId(BailoutId ast_id);
114a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
115a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  int PredecessorIndexOf(HBasicBlock* predecessor) const;
116ad75d6febf45d81dda1f4cd158c7eb97c0408a25danno@chromium.org  HPhi* AddNewPhi(int merged_index);
117ad75d6febf45d81dda1f4cd158c7eb97c0408a25danno@chromium.org  HSimulate* AddNewSimulate(BailoutId ast_id,
118f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org                            HSourcePosition position,
119ad75d6febf45d81dda1f4cd158c7eb97c0408a25danno@chromium.org                            RemovableSimulate removable = FIXED_SIMULATE) {
120c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org    HSimulate* instr = CreateSimulate(ast_id, removable);
12171f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org    AddInstruction(instr, position);
122c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org    return instr;
123fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org  }
124a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void AssignCommonDominator(HBasicBlock* other);
12578d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  void AssignLoopSuccessorDominators();
126a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
127a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // If a target block is tagged as an inline function return, all
128a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // predecessors should contain the inlined exit sequence:
129a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  //
130a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // LeaveInlined
131a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Simulate (caller's environment)
132a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Goto (target block)
133a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  bool IsInlineReturnTarget() const { return is_inline_return_target_; }
134d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  void MarkAsInlineReturnTarget(HBasicBlock* inlined_entry_block) {
135d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org    is_inline_return_target_ = true;
136d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org    inlined_entry_block_ = inlined_entry_block;
137d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  }
138d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  HBasicBlock* inlined_entry_block() { return inlined_entry_block_; }
139a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
140d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org  bool IsDeoptimizing() const {
141d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org    return end() != NULL && end()->IsDeoptimize();
142d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org  }
143d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org
144d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org  void MarkUnreachable();
145d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org  bool IsUnreachable() const { return !is_reachable_; }
146d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org  bool IsReachable() const { return is_reachable_; }
1476d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org
14878d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  bool IsLoopSuccessorDominator() const {
14978d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org    return dominates_loop_successors_;
15078d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  }
15178d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  void MarkAsLoopSuccessorDominator() {
15278d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org    dominates_loop_successors_ = true;
15378d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  }
15478d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org
15554ae5fb0902b9e1b89c178fa5a7ba4e1a74daa41machenbach@chromium.org  bool IsOrdered() const { return is_ordered_; }
15654ae5fb0902b9e1b89c178fa5a7ba4e1a74daa41machenbach@chromium.org  void MarkAsOrdered() { is_ordered_ = true; }
15754ae5fb0902b9e1b89c178fa5a7ba4e1a74daa41machenbach@chromium.org
158f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  void MarkSuccEdgeUnreachable(int succ);
159f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org
1607028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  inline Zone* zone() const;
16174f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org
162a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#ifdef DEBUG
163a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void Verify();
164a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#endif
165a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
16671f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org protected:
167c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  friend class HGraphBuilder;
168c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org
16971f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org  HSimulate* CreateSimulate(BailoutId ast_id, RemovableSimulate removable);
170f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  void Finish(HControlInstruction* last, HSourcePosition position);
171f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  void FinishExit(HControlInstruction* instruction, HSourcePosition position);
17271f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org  void Goto(HBasicBlock* block,
173f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org            HSourcePosition position,
17471f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org            FunctionState* state = NULL,
17571f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org            bool add_simulate = true);
176f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  void GotoNoSimulate(HBasicBlock* block, HSourcePosition position) {
17771f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org    Goto(block, position, NULL, false);
17871f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org  }
17971f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org
18071f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org  // Add the inlined function exit sequence, adding an HLeaveInlined
18171f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org  // instruction and updating the bailout environment.
18271f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org  void AddLeaveInlined(HValue* return_value,
18371f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org                       FunctionState* state,
184f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org                       HSourcePosition position);
18571f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org
18671f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org private:
187a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void RegisterPredecessor(HBasicBlock* pred);
188a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void AddDominatedBlock(HBasicBlock* block);
189a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
190a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  int block_id_;
191a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  HGraph* graph_;
192a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  ZoneList<HPhi*> phis_;
193a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  HInstruction* first_;
19449edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org  HInstruction* last_;
195a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  HControlInstruction* end_;
196a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  HLoopInformation* loop_information_;
197a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  ZoneList<HBasicBlock*> predecessors_;
198a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  HBasicBlock* dominator_;
199a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  ZoneList<HBasicBlock*> dominated_blocks_;
200a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  HEnvironment* last_environment_;
201a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Outgoing parameter count at block exit, set during lithium translation.
202a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  int argument_count_;
203a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Instruction indices into the lithium code stream.
204a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  int first_instruction_index_;
205a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  int last_instruction_index_;
206a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  ZoneList<int> deleted_phis_;
207496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org  HBasicBlock* parent_loop_header_;
208d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  // For blocks marked as inline return target: the block with HEnterInlined.
209d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  HBasicBlock* inlined_entry_block_;
210d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  bool is_inline_return_target_ : 1;
211d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org  bool is_reachable_ : 1;
212d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  bool dominates_loop_successors_ : 1;
213d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  bool is_osr_entry_ : 1;
21454ae5fb0902b9e1b89c178fa5a7ba4e1a74daa41machenbach@chromium.org  bool is_ordered_ : 1;
21578d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org};
21678d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org
21778d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org
218f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.orgOStream& operator<<(OStream& os, const HBasicBlock& b);
219f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org
220f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org
221ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.orgclass HPredecessorIterator FINAL BASE_EMBEDDED {
22278d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org public:
22378d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  explicit HPredecessorIterator(HBasicBlock* block)
22478d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org      : predecessor_list_(block->predecessors()), current_(0) { }
22578d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org
22678d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  bool Done() { return current_ >= predecessor_list_->length(); }
22778d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  HBasicBlock* Current() { return predecessor_list_->at(current_); }
22878d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  void Advance() { current_++; }
22978d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org
23078d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org private:
23178d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  const ZoneList<HBasicBlock*>* predecessor_list_;
23278d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  int current_;
233a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org};
234a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
235a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
236ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.orgclass HInstructionIterator FINAL BASE_EMBEDDED {
23793a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org public:
238169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  explicit HInstructionIterator(HBasicBlock* block)
239169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org      : instr_(block->first()) {
240169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    next_ = Done() ? NULL : instr_->next();
241169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  }
24293a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org
243169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  inline bool Done() const { return instr_ == NULL; }
244169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  inline HInstruction* Current() { return instr_; }
245169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  inline void Advance() {
246169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    instr_ = next_;
247169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    next_ = Done() ? NULL : instr_->next();
248169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  }
24993a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org
25093a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org private:
25193a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org  HInstruction* instr_;
252169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  HInstruction* next_;
25393a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org};
25493a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org
25593a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org
256ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.orgclass HLoopInformation FINAL : public ZoneObject {
257a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org public:
2587028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  HLoopInformation(HBasicBlock* loop_header, Zone* zone)
2597028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org      : back_edges_(4, zone),
26004921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org        loop_header_(loop_header),
2617028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org        blocks_(8, zone),
26204921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org        stack_check_(NULL) {
2637028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org    blocks_.Add(loop_header, zone);
264a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
26532cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org  ~HLoopInformation() {}
266a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
267a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  const ZoneList<HBasicBlock*>* back_edges() const { return &back_edges_; }
268a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  const ZoneList<HBasicBlock*>* blocks() const { return &blocks_; }
269a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  HBasicBlock* loop_header() const { return loop_header_; }
270a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  HBasicBlock* GetLastBackEdge() const;
271a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void RegisterBackEdge(HBasicBlock* block);
272a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
27304921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org  HStackCheck* stack_check() const { return stack_check_; }
27404921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org  void set_stack_check(HStackCheck* stack_check) {
27504921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org    stack_check_ = stack_check;
27604921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org  }
27704921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org
278fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  bool IsNestedInThisLoop(HLoopInformation* other) {
279fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org    while (other != NULL) {
280fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org      if (other == this) {
281fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org        return true;
282fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org      }
283fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org      other = other->parent_loop();
284fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org    }
285fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org    return false;
286fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  }
287fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  HLoopInformation* parent_loop() {
288fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org    HBasicBlock* parent_header = loop_header()->parent_loop_header();
289fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org    return parent_header != NULL ? parent_header->loop_information() : NULL;
290fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  }
291fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org
292a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org private:
293a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void AddBlock(HBasicBlock* block);
294a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
295a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  ZoneList<HBasicBlock*> back_edges_;
296a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  HBasicBlock* loop_header_;
297a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  ZoneList<HBasicBlock*> blocks_;
29804921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org  HStackCheck* stack_check_;
299a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org};
300a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
301b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org
302efdb9d70bddd496ceb6a281dadcc065efbce37a1yangguo@chromium.orgclass BoundsCheckTable;
303fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.orgclass InductionVariableBlocksTable;
304ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.orgclass HGraph FINAL : public ZoneObject {
305a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org public:
3065a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  explicit HGraph(CompilationInfo* info);
307a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
30809d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org  Isolate* isolate() const { return isolate_; }
3097028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  Zone* zone() const { return zone_; }
3105a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  CompilationInfo* info() const { return info_; }
31174f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org
312a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  const ZoneList<HBasicBlock*>* blocks() const { return &blocks_; }
313a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  const ZoneList<HPhi*>* phi_list() const { return phi_list_; }
3144d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org  HBasicBlock* entry_block() const { return entry_block_; }
315a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  HEnvironment* start_environment() const { return start_environment_; }
316a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
3173d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org  void FinalizeUniqueness();
318a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  bool ProcessArgumentsObject();
319a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void OrderBlocks();
320a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void AssignDominators();
321068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org  void RestoreActualValues();
322a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
323a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Returns false if there are phi-uses of the arguments-object
324a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // which are not supported by the optimizing compiler.
325c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  bool CheckArgumentsPhiUses();
326d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org
327c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // Returns false if there are phi-uses of an uninitialized const
328c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // which are not supported by the optimizing compiler.
329c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  bool CheckConstPhiUses();
330c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
331c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void CollectPhis();
332a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
33371f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org  HConstant* GetConstantUndefined();
33494b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org  HConstant* GetConstant0();
335a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  HConstant* GetConstant1();
336a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  HConstant* GetConstantMinus1();
337a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  HConstant* GetConstantTrue();
338a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  HConstant* GetConstantFalse();
339d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org  HConstant* GetConstantHole();
340ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  HConstant* GetConstantNull();
341876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org  HConstant* GetInvalidContext();
342a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
343935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org  bool IsConstantUndefined(HConstant* constant);
344935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org  bool IsConstant0(HConstant* constant);
345935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org  bool IsConstant1(HConstant* constant);
346935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org  bool IsConstantMinus1(HConstant* constant);
347935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org  bool IsConstantTrue(HConstant* constant);
348935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org  bool IsConstantFalse(HConstant* constant);
349935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org  bool IsConstantHole(HConstant* constant);
350935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org  bool IsConstantNull(HConstant* constant);
351e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org  bool IsStandardConstant(HConstant* constant);
352e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org
353a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  HBasicBlock* CreateBasicBlock();
354a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  HArgumentsObject* GetArgumentsObject() const {
355a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    return arguments_object_.get();
356a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
357a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
358a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void SetArgumentsObject(HArgumentsObject* object) {
359a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    arguments_object_.set(object);
360a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
361a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
362a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  int GetMaximumValueID() const { return values_.length(); }
363a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  int GetNextBlockID() { return next_block_id_++; }
364a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  int GetNextValueID(HValue* value) {
365e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(!disallow_adding_new_values_);
3667028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org    values_.Add(value, zone());
367a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    return values_.length() - 1;
368a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
369a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  HValue* LookupValue(int id) const {
370a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    if (id >= 0 && id < values_.length()) return values_[id];
371a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    return NULL;
372a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
373935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org  void DisallowAddingNewValues() {
374935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org    disallow_adding_new_values_ = true;
375935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org  }
376a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
377594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  bool Optimize(BailoutReason* bailout_reason);
37828583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org
379a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#ifdef DEBUG
380c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void Verify(bool do_full_verify) const;
381a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#endif
382a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
383c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org  bool has_osr() {
384c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org    return osr_ != NULL;
3852c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org  }
3862c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org
387c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org  void set_osr(HOsrBuilder* osr) {
388c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org    osr_ = osr;
3892c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org  }
3902c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org
391c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org  HOsrBuilder* osr() {
392c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org    return osr_;
3932c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org  }
3942c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org
39546839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  int update_type_change_checksum(int delta) {
39646839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org    type_change_checksum_ += delta;
39746839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org    return type_change_checksum_;
39846839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  }
39946839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org
400d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  void update_maximum_environment_size(int environment_size) {
401d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org    if (environment_size > maximum_environment_size_) {
402d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org      maximum_environment_size_ = environment_size;
403d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org    }
404d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  }
405d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  int maximum_environment_size() { return maximum_environment_size_; }
406d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org
40746839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  bool use_optimistic_licm() {
40846839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org    return use_optimistic_licm_;
40946839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  }
41046839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org
41146839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  void set_use_optimistic_licm(bool value) {
41246839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org    use_optimistic_licm_ = value;
41346839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  }
41446839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org
4157028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  void MarkRecursive() {
4167028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org    is_recursive_ = true;
4177028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  }
4187028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org
4197028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  bool is_recursive() const {
4207028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org    return is_recursive_;
4217028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  }
4227028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org
423906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org  void MarkDependsOnEmptyArrayProtoElements() {
42441728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org    // Add map dependency if not already added.
42541728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org    if (depends_on_empty_array_proto_elements_) return;
426e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org    Map::AddDependentCompilationInfo(
427e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org        handle(isolate()->initial_object_prototype()->map()),
42841728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org        DependentCode::kElementsCantBeAddedGroup, info());
429e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org    Map::AddDependentCompilationInfo(
430e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org        handle(isolate()->initial_array_prototype()->map()),
43141728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org        DependentCode::kElementsCantBeAddedGroup, info());
432906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org    depends_on_empty_array_proto_elements_ = true;
433906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org  }
434906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org
435b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org  bool depends_on_empty_array_proto_elements() {
436b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org    return depends_on_empty_array_proto_elements_;
437b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org  }
438b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org
43993a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org  bool has_uint32_instructions() {
440e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(uint32_instructions_ == NULL || !uint32_instructions_->is_empty());
44193a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org    return uint32_instructions_ != NULL;
44293a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org  }
44393a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org
44493a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org  ZoneList<HInstruction*>* uint32_instructions() {
445e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(uint32_instructions_ == NULL || !uint32_instructions_->is_empty());
44693a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org    return uint32_instructions_;
44793a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org  }
44893a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org
44946839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  void RecordUint32Instruction(HInstruction* instr) {
450e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(uint32_instructions_ == NULL || !uint32_instructions_->is_empty());
45146839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org    if (uint32_instructions_ == NULL) {
45246839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org      uint32_instructions_ = new(zone()) ZoneList<HInstruction*>(4, zone());
45346839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org    }
45446839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org    uint32_instructions_->Add(instr, zone());
45546839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  }
45646839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org
457ad75d6febf45d81dda1f4cd158c7eb97c0408a25danno@chromium.org  void IncrementInNoSideEffectsScope() { no_side_effects_scope_count_++; }
458ad75d6febf45d81dda1f4cd158c7eb97c0408a25danno@chromium.org  void DecrementInNoSideEffectsScope() { no_side_effects_scope_count_--; }
459ad75d6febf45d81dda1f4cd158c7eb97c0408a25danno@chromium.org  bool IsInsideNoSideEffectsScope() { return no_side_effects_scope_count_ > 0; }
460ad75d6febf45d81dda1f4cd158c7eb97c0408a25danno@chromium.org
461f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  // If we are tracking source positions then this function assigns a unique
462f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  // identifier to each inlining and dumps function source if it was inlined
463f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  // for the first time during the current optimization.
464f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  int TraceInlinedFunction(Handle<SharedFunctionInfo> shared,
465f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org                           HSourcePosition position);
466f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org
467f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  // Converts given HSourcePosition to the absolute offset from the start of
468f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  // the corresponding script.
469f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  int SourcePositionToScriptPosition(HSourcePosition position);
470f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org
471a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org private:
47271f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org  HConstant* ReinsertConstantIfNecessary(HConstant* constant);
473b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org  HConstant* GetConstant(SetOncePointer<HConstant>* pointer,
474b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org                         int32_t integer_value);
475a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
4761510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  template<class Phase>
4771510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  void Run() {
4781510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    Phase phase(this);
4791510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    phase.Run();
4801510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  }
4811510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
482fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  void EliminateRedundantBoundsChecksUsingInductionVariables();
483a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
484ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Isolate* isolate_;
485a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  int next_block_id_;
4864d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org  HBasicBlock* entry_block_;
487a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  HEnvironment* start_environment_;
488a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  ZoneList<HBasicBlock*> blocks_;
489a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  ZoneList<HValue*> values_;
490a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  ZoneList<HPhi*>* phi_list_;
49146839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  ZoneList<HInstruction*>* uint32_instructions_;
49271f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org  SetOncePointer<HConstant> constant_undefined_;
49394b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org  SetOncePointer<HConstant> constant_0_;
494a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  SetOncePointer<HConstant> constant_1_;
495a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  SetOncePointer<HConstant> constant_minus1_;
496a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  SetOncePointer<HConstant> constant_true_;
497a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  SetOncePointer<HConstant> constant_false_;
4982bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org  SetOncePointer<HConstant> constant_the_hole_;
499ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  SetOncePointer<HConstant> constant_null_;
500876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org  SetOncePointer<HConstant> constant_invalid_context_;
501a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  SetOncePointer<HArgumentsObject> arguments_object_;
502a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
503c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org  HOsrBuilder* osr_;
5042c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org
5055a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  CompilationInfo* info_;
5067028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  Zone* zone_;
5077028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org
5087028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  bool is_recursive_;
50946839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  bool use_optimistic_licm_;
510906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org  bool depends_on_empty_array_proto_elements_;
51146839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  int type_change_checksum_;
512d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  int maximum_environment_size_;
513ad75d6febf45d81dda1f4cd158c7eb97c0408a25danno@chromium.org  int no_side_effects_scope_count_;
514935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org  bool disallow_adding_new_values_;
5157028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org
516f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  class InlinedFunctionInfo {
517f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org   public:
518f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    explicit InlinedFunctionInfo(Handle<SharedFunctionInfo> shared)
519f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org      : shared_(shared), start_position_(shared->start_position()) {
520f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    }
521f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org
522f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    Handle<SharedFunctionInfo> shared() const { return shared_; }
523f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    int start_position() const { return start_position_; }
524f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org
525f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org   private:
526f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    Handle<SharedFunctionInfo> shared_;
527f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    int start_position_;
528f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  };
529f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org
530f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  int next_inline_id_;
531f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  ZoneList<InlinedFunctionInfo> inlined_functions_;
532f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org
533a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  DISALLOW_COPY_AND_ASSIGN(HGraph);
534a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org};
535a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
536a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
5377028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.orgZone* HBasicBlock::zone() const { return graph_->zone(); }
53874f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org
53974f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org
540967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org// Type of stack frame an environment might refer to.
541471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.orgenum FrameType {
542471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org  JS_FUNCTION,
543471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org  JS_CONSTRUCT,
544de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org  JS_GETTER,
545471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org  JS_SETTER,
546a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  ARGUMENTS_ADAPTOR,
547a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  STUB
548471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org};
549967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org
550967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org
551ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.orgclass HEnvironment FINAL : public ZoneObject {
552a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org public:
553a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  HEnvironment(HEnvironment* outer,
554a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org               Scope* scope,
5557028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org               Handle<JSFunction> closure,
5567028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org               Zone* zone);
557a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
55809d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org  HEnvironment(Zone* zone, int parameter_count);
559a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
5606ff651481ed0a881f176f6d55e26679ca359792bulan@chromium.org  HEnvironment* arguments_environment() {
5616ff651481ed0a881f176f6d55e26679ca359792bulan@chromium.org    return outer()->frame_type() == ARGUMENTS_ADAPTOR ? outer() : this;
5626ff651481ed0a881f176f6d55e26679ca359792bulan@chromium.org  }
5636ff651481ed0a881f176f6d55e26679ca359792bulan@chromium.org
5645d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org  // Simple accessors.
5655d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org  Handle<JSFunction> closure() const { return closure_; }
5665d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org  const ZoneList<HValue*>* values() const { return &values_; }
56759297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  const GrowableBitVector* assigned_variables() const {
5685d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org    return &assigned_variables_;
5695d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org  }
570967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org  FrameType frame_type() const { return frame_type_; }
5715d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org  int parameter_count() const { return parameter_count_; }
57283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  int specials_count() const { return specials_count_; }
5735d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org  int local_count() const { return local_count_; }
5745d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org  HEnvironment* outer() const { return outer_; }
5755d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org  int pop_count() const { return pop_count_; }
5765d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org  int push_count() const { return push_count_; }
5775d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org
578471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org  BailoutId ast_id() const { return ast_id_; }
579471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org  void set_ast_id(BailoutId id) { ast_id_ = id; }
5805d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org
58156c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org  HEnterInlined* entry() const { return entry_; }
58256c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org  void set_entry(HEnterInlined* entry) { entry_ = entry; }
58356c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org
5845d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org  int length() const { return values_.length(); }
5855d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org
586be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org  int first_expression_index() const {
587be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org    return parameter_count() + specials_count() + local_count();
588be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org  }
589be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org
590d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  int first_local_index() const {
591d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org    return parameter_count() + specials_count();
592d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  }
593d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org
594a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void Bind(Variable* variable, HValue* value) {
595a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    Bind(IndexFor(variable), value);
596a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
597a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
5985d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org  void Bind(int index, HValue* value);
599a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
60083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  void BindContext(HValue* value) {
60183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    Bind(parameter_count(), value);
60283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  }
60383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
604a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  HValue* Lookup(Variable* variable) const {
605a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    return Lookup(IndexFor(variable));
606a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
6075d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org
608a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  HValue* Lookup(int index) const {
609a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    HValue* result = values_[index];
610e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(result != NULL);
611a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    return result;
612a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
613a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
614d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  HValue* context() const {
61583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    // Return first special.
61683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    return Lookup(parameter_count());
61783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  }
61883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
619a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void Push(HValue* value) {
620e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(value != NULL);
621a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    ++push_count_;
6227028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org    values_.Add(value, zone());
623a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
624a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
625a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  HValue* Pop() {
626e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(!ExpressionStackIsEmpty());
627a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    if (push_count_ > 0) {
628a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      --push_count_;
629a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    } else {
630a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      ++pop_count_;
631a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    }
632a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    return values_.RemoveLast();
633a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
634a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
6355d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org  void Drop(int count);
636a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
6375d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org  HValue* Top() const { return ExpressionStackAt(0); }
638a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
63983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  bool ExpressionStackIsEmpty() const;
64083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
6415d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org  HValue* ExpressionStackAt(int index_from_top) const {
6425d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org    int index = length() - index_from_top - 1;
643e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(HasExpressionAt(index));
6445d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org    return values_[index];
645a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
6465d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org
6475d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org  void SetExpressionStackAt(int index_from_top, HValue* value);
6485d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org
649a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  HEnvironment* Copy() const;
650a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  HEnvironment* CopyWithoutHistory() const;
651a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  HEnvironment* CopyAsLoopHeader(HBasicBlock* block) const;
652a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
653a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Create an "inlined version" of this environment, where the original
654a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // environment is the outer environment but the top expression stack
6553cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org  // elements are moved to an inner environment as parameters.
656a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  HEnvironment* CopyForInlining(Handle<JSFunction> target,
657659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org                                int arguments,
658a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org                                FunctionLiteral* function,
65940cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org                                HConstant* undefined,
660e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org                                InliningKind inlining_kind) const;
661a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
66256c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org  HEnvironment* DiscardInlined(bool drop_extra) {
66356c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org    HEnvironment* outer = outer_;
66456c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org    while (outer->frame_type() != JS_FUNCTION) outer = outer->outer_;
66556c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org    if (drop_extra) outer->Drop(1);
66656c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org    return outer;
66756c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org  }
66856c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org
669a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void AddIncomingEdge(HBasicBlock* block, HEnvironment* other);
6705d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org
671a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void ClearHistory() {
672a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    pop_count_ = 0;
673a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    push_count_ = 0;
67459297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org    assigned_variables_.Clear();
675a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
6765d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org
677a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void SetValueAt(int index, HValue* value) {
678e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(index < length());
679a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    values_[index] = value;
680a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
681a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
682d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  // Map a variable to an environment index.  Parameter indices are shifted
683d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  // by 1 (receiver is parameter index -1 but environment index 0).
684d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  // Stack-allocated local indices are shifted by the number of parameters.
685d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  int IndexFor(Variable* variable) const {
686e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(variable->IsStackAllocated());
687d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org    int shift = variable->IsParameter()
688d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org        ? 1
689d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org        : parameter_count_ + specials_count_;
690d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org    return variable->index() + shift;
691d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  }
692d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org
693d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  bool is_local_index(int i) const {
694c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org    return i >= first_local_index() && i < first_expression_index();
695c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org  }
696c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org
697c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org  bool is_parameter_index(int i) const {
698c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org    return i >= 0 && i < parameter_count();
699c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org  }
700c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org
701c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org  bool is_special_index(int i) const {
702c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org    return i >= parameter_count() && i < parameter_count() + specials_count();
703d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  }
704d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org
7057028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  Zone* zone() const { return zone_; }
7067028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org
707a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org private:
7087028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  HEnvironment(const HEnvironment* other, Zone* zone);
709a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
710967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org  HEnvironment(HEnvironment* outer,
711967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org               Handle<JSFunction> closure,
712967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org               FrameType frame_type,
7137028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org               int arguments,
7147028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org               Zone* zone);
715659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org
716967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org  // Create an artificial stub environment (e.g. for argument adaptor or
717967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org  // constructor stub).
718967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org  HEnvironment* CreateStubEnvironment(HEnvironment* outer,
719967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org                                      Handle<JSFunction> target,
720967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org                                      FrameType frame_type,
721967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org                                      int arguments) const;
722659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org
7235d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org  // True if index is included in the expression stack part of the environment.
7245d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org  bool HasExpressionAt(int index) const;
7255d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org
726a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void Initialize(int parameter_count, int local_count, int stack_height);
727a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void Initialize(const HEnvironment* other);
7285d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org
729a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  Handle<JSFunction> closure_;
73083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  // Value array [parameters] [specials] [locals] [temporaries].
731a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  ZoneList<HValue*> values_;
73259297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  GrowableBitVector assigned_variables_;
733967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org  FrameType frame_type_;
734a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  int parameter_count_;
73583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  int specials_count_;
736a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  int local_count_;
737a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  HEnvironment* outer_;
73856c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org  HEnterInlined* entry_;
739a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  int pop_count_;
740a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  int push_count_;
741471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org  BailoutId ast_id_;
7427028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  Zone* zone_;
743a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org};
744a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
745a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
746f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.orgOStream& operator<<(OStream& os, const HEnvironment& env);
747f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org
748f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org
749a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgclass HOptimizedGraphBuilder;
750a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
7518e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.orgenum ArgumentsAllowedFlag {
7528e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  ARGUMENTS_NOT_ALLOWED,
7538e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  ARGUMENTS_ALLOWED
7548e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org};
7558e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org
756b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org
757b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.orgclass HIfContinuation;
758b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org
7598f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org// This class is not BASE_EMBEDDED because our inlining implementation uses
7608f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org// new and delete.
761a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgclass AstContext {
762a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org public:
763a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  bool IsEffect() const { return kind_ == Expression::kEffect; }
764a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  bool IsValue() const { return kind_ == Expression::kValue; }
765a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  bool IsTest() const { return kind_ == Expression::kTest; }
766a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
7675f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  // 'Fill' this context with a hydrogen value.  The value is assumed to
7685f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  // have already been inserted in the instruction stream (or not need to
7695f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  // be, e.g., HPhi).  Call this function in tail position in the Visit
7705f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  // functions for expressions.
7715f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  virtual void ReturnValue(HValue* value) = 0;
7725f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org
7735f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  // Add a hydrogen instruction to the instruction stream (recording an
7745f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  // environment simulation if necessary) and then fill this context with
7755f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  // the instruction as value.
776471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org  virtual void ReturnInstruction(HInstruction* instr, BailoutId ast_id) = 0;
7775f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org
7784f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  // Finishes the current basic block and materialize a boolean for
7794f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  // value context, nothing for effect, generate a branch for test context.
7804f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  // Call this function in tail position in the Visit functions for
7814f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  // expressions.
782471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org  virtual void ReturnControl(HControlInstruction* instr, BailoutId ast_id) = 0;
7834f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org
784b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org  // Finishes the current basic block and materialize a boolean for
785b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org  // value context, nothing for effect, generate a branch for test context.
786b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org  // Call this function in tail position in the Visit functions for
787b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org  // expressions that use an IfBuilder.
788b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org  virtual void ReturnContinuation(HIfContinuation* continuation,
789b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org                                  BailoutId ast_id) = 0;
790b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org
791c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  void set_for_typeof(bool for_typeof) { for_typeof_ = for_typeof; }
792c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  bool is_for_typeof() { return for_typeof_; }
793c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org
794a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org protected:
795a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  AstContext(HOptimizedGraphBuilder* owner, Expression::Context kind);
796a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  virtual ~AstContext();
797a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
798a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  HOptimizedGraphBuilder* owner() const { return owner_; }
7995f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org
8007028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  inline Zone* zone() const;
80174f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org
8025f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  // We want to be able to assert, in a context-specific way, that the stack
8035f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  // height makes sense when the context is filled.
8045f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org#ifdef DEBUG
8055d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org  int original_length_;
8065f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org#endif
8075f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org
808a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org private:
809a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  HOptimizedGraphBuilder* owner_;
810a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  Expression::Context kind_;
811a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  AstContext* outer_;
812c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  bool for_typeof_;
813a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org};
814a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
815a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
816ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.orgclass EffectContext FINAL : public AstContext {
817a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org public:
818a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  explicit EffectContext(HOptimizedGraphBuilder* owner)
819a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      : AstContext(owner, Expression::kEffect) {
820a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
8215f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  virtual ~EffectContext();
8225f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org
823ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  virtual void ReturnValue(HValue* value) OVERRIDE;
82432cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org  virtual void ReturnInstruction(HInstruction* instr,
825ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org                                 BailoutId ast_id) OVERRIDE;
82632cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org  virtual void ReturnControl(HControlInstruction* instr,
827ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org                             BailoutId ast_id) OVERRIDE;
828b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org  virtual void ReturnContinuation(HIfContinuation* continuation,
829ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org                                  BailoutId ast_id) OVERRIDE;
830a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org};
831a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
832a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
833ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.orgclass ValueContext FINAL : public AstContext {
834a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org public:
835a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  ValueContext(HOptimizedGraphBuilder* owner, ArgumentsAllowedFlag flag)
8368e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org      : AstContext(owner, Expression::kValue), flag_(flag) {
837a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
8385f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  virtual ~ValueContext();
8395f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org
840ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  virtual void ReturnValue(HValue* value) OVERRIDE;
84132cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org  virtual void ReturnInstruction(HInstruction* instr,
842ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org                                 BailoutId ast_id) OVERRIDE;
84332cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org  virtual void ReturnControl(HControlInstruction* instr,
844ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org                             BailoutId ast_id) OVERRIDE;
845b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org  virtual void ReturnContinuation(HIfContinuation* continuation,
846ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org                                  BailoutId ast_id) OVERRIDE;
8478e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org
8488e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  bool arguments_allowed() { return flag_ == ARGUMENTS_ALLOWED; }
8498e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org
8508e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org private:
8518e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  ArgumentsAllowedFlag flag_;
852a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org};
853a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
854a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
855ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.orgclass TestContext FINAL : public AstContext {
856a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org public:
857a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  TestContext(HOptimizedGraphBuilder* owner,
8586d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org              Expression* condition,
859a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org              HBasicBlock* if_true,
8605f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org              HBasicBlock* if_false)
861a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      : AstContext(owner, Expression::kTest),
8626d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org        condition_(condition),
863a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        if_true_(if_true),
8645f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org        if_false_(if_false) {
865a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
866a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
867ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  virtual void ReturnValue(HValue* value) OVERRIDE;
86832cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org  virtual void ReturnInstruction(HInstruction* instr,
869ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org                                 BailoutId ast_id) OVERRIDE;
87032cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org  virtual void ReturnControl(HControlInstruction* instr,
871ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org                             BailoutId ast_id) OVERRIDE;
872b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org  virtual void ReturnContinuation(HIfContinuation* continuation,
873ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org                                  BailoutId ast_id) OVERRIDE;
8745f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org
875a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  static TestContext* cast(AstContext* context) {
876e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(context->IsTest());
877a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    return reinterpret_cast<TestContext*>(context);
878a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
879a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
8806d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  Expression* condition() const { return condition_; }
881a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  HBasicBlock* if_true() const { return if_true_; }
882a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  HBasicBlock* if_false() const { return if_false_; }
883a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
884a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org private:
8855f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  // Build the shared core part of the translation unpacking a value into
8865f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  // control flow.
8875f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  void BuildBranch(HValue* value);
8885f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org
8896d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  Expression* condition_;
890a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  HBasicBlock* if_true_;
891a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  HBasicBlock* if_false_;
892a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org};
893a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
894a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
895ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.orgclass FunctionState FINAL {
8968f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org public:
897a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  FunctionState(HOptimizedGraphBuilder* owner,
8988f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org                CompilationInfo* info,
899f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org                InliningKind inlining_kind,
900f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org                int inlining_id);
9018f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org  ~FunctionState();
9028f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org
9038f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org  CompilationInfo* compilation_info() { return compilation_info_; }
9048f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org  AstContext* call_context() { return call_context_; }
905471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org  InliningKind inlining_kind() const { return inlining_kind_; }
9068f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org  HBasicBlock* function_return() { return function_return_; }
9078f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org  TestContext* test_context() { return test_context_; }
9088f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org  void ClearInlinedTestContext() {
9098f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org    delete test_context_;
9108f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org    test_context_ = NULL;
9118f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org  }
9128f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org
913c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  FunctionState* outer() { return outer_; }
914c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org
91528faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org  HEnterInlined* entry() { return entry_; }
91628faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org  void set_entry(HEnterInlined* entry) { entry_ = entry; }
91728faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org
918b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org  HArgumentsObject* arguments_object() { return arguments_object_; }
919b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org  void set_arguments_object(HArgumentsObject* arguments_object) {
920b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org    arguments_object_ = arguments_object;
921b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org  }
922b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org
92328faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org  HArgumentsElements* arguments_elements() { return arguments_elements_; }
92428faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org  void set_arguments_elements(HArgumentsElements* arguments_elements) {
92528faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org    arguments_elements_ = arguments_elements;
92628faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org  }
92728faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org
92828faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org  bool arguments_pushed() { return arguments_elements() != NULL; }
92928faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org
930f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  int inlining_id() const { return inlining_id_; }
931f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org
9328f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org private:
933a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  HOptimizedGraphBuilder* owner_;
9348f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org
9358f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org  CompilationInfo* compilation_info_;
9368f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org
9378f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org  // During function inlining, expression context of the call being
9388f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org  // inlined. NULL when not inlining.
9398f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org  AstContext* call_context_;
9408f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org
941471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org  // The kind of call which is currently being inlined.
942471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org  InliningKind inlining_kind_;
943394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
944967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org  // When inlining in an effect or value context, this is the return block.
9458f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org  // It is NULL otherwise.  When inlining in a test context, there are a
9468f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org  // pair of return blocks in the context.  When not inlining, there is no
9478f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org  // local return point.
9488f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org  HBasicBlock* function_return_;
9498f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org
9508f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org  // When inlining a call in a test context, a context containing a pair of
9518f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org  // return blocks.  NULL in all other cases.
9528f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org  TestContext* test_context_;
9538f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org
95428faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org  // When inlining HEnterInlined instruction corresponding to the function
95528faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org  // entry.
95628faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org  HEnterInlined* entry_;
95728faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org
958b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org  HArgumentsObject* arguments_object_;
95928faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org  HArgumentsElements* arguments_elements_;
96028faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org
961f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  int inlining_id_;
962f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  HSourcePosition outer_source_position_;
963f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org
9648f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org  FunctionState* outer_;
9658f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org};
9668f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org
9678f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org
968ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.orgclass HIfContinuation FINAL {
969b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org public:
970ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  HIfContinuation()
971ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    : continuation_captured_(false),
972ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org      true_branch_(NULL),
973ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org      false_branch_(NULL) {}
974528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  HIfContinuation(HBasicBlock* true_branch,
97571f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org                  HBasicBlock* false_branch)
976528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org      : continuation_captured_(true), true_branch_(true_branch),
97771f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org        false_branch_(false_branch) {}
978e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  ~HIfContinuation() { DCHECK(!continuation_captured_); }
979b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org
980b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org  void Capture(HBasicBlock* true_branch,
98171f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org               HBasicBlock* false_branch) {
982e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(!continuation_captured_);
983b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org    true_branch_ = true_branch;
984b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org    false_branch_ = false_branch;
985b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org    continuation_captured_ = true;
986b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org  }
987b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org
988b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org  void Continue(HBasicBlock** true_branch,
98971f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org                HBasicBlock** false_branch) {
990e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(continuation_captured_);
991b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org    *true_branch = true_branch_;
992b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org    *false_branch = false_branch_;
993b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org    continuation_captured_ = false;
994b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org  }
995b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org
996b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org  bool IsTrueReachable() { return true_branch_ != NULL; }
997b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org  bool IsFalseReachable() { return false_branch_ != NULL; }
998b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org  bool TrueAndFalseReachable() {
999b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org    return IsTrueReachable() || IsFalseReachable();
1000b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org  }
1001b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org
1002528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  HBasicBlock* true_branch() const { return true_branch_; }
1003528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  HBasicBlock* false_branch() const { return false_branch_; }
1004528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org
1005528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org private:
1006b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org  bool continuation_captured_;
1007b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org  HBasicBlock* true_branch_;
1008b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org  HBasicBlock* false_branch_;
1009b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org};
1010b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org
1011b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org
1012ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.orgclass HAllocationMode FINAL BASE_EMBEDDED {
10130f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org public:
10140f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org  explicit HAllocationMode(Handle<AllocationSite> feedback_site)
10150f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org      : current_site_(NULL), feedback_site_(feedback_site),
10160f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org        pretenure_flag_(NOT_TENURED) {}
10170f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org  explicit HAllocationMode(HValue* current_site)
10180f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org      : current_site_(current_site), pretenure_flag_(NOT_TENURED) {}
10190f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org  explicit HAllocationMode(PretenureFlag pretenure_flag)
10200f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org      : current_site_(NULL), pretenure_flag_(pretenure_flag) {}
102169f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org  HAllocationMode()
102269f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org      : current_site_(NULL), pretenure_flag_(NOT_TENURED) {}
10230f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org
10240f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org  HValue* current_site() const { return current_site_; }
10250f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org  Handle<AllocationSite> feedback_site() const { return feedback_site_; }
10260f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org
1027ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  bool CreateAllocationMementos() const WARN_UNUSED_RESULT {
10280f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org    return current_site() != NULL;
10290f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org  }
10300f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org
1031ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  PretenureFlag GetPretenureMode() const WARN_UNUSED_RESULT {
10320f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org    if (!feedback_site().is_null()) return feedback_site()->GetPretenureMode();
10330f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org    return pretenure_flag_;
10340f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org  }
10350f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org
10360f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org private:
10370f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org  HValue* current_site_;
10380f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org  Handle<AllocationSite> feedback_site_;
10390f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org  PretenureFlag pretenure_flag_;
10400f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org};
10410f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org
10420f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org
1043a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgclass HGraphBuilder {
1044a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org public:
1045a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  explicit HGraphBuilder(CompilationInfo* info)
1046e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      : info_(info),
1047e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org        graph_(NULL),
104871f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org        current_block_(NULL),
10491e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org        scope_(info->scope()),
1050f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org        position_(HSourcePosition::Unknown()),
1051f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org        start_position_(0) {}
1052a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  virtual ~HGraphBuilder() {}
1053a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
10541e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org  Scope* scope() const { return scope_; }
10551e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org  void set_scope(Scope* scope) { scope_ = scope; }
10561e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org
1057a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  HBasicBlock* current_block() const { return current_block_; }
1058a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  void set_current_block(HBasicBlock* block) { current_block_ = block; }
1059a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  HEnvironment* environment() const {
1060a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    return current_block()->last_environment();
1061a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  }
1062a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  Zone* zone() const { return info_->zone(); }
1063750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  HGraph* graph() const { return graph_; }
1064750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  Isolate* isolate() const { return graph_->isolate(); }
106541728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  CompilationInfo* top_info() { return info_; }
1066a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
1067a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  HGraph* CreateGraph();
1068a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
1069ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  // Bailout environment manipulation.
1070ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  void Push(HValue* value) { environment()->Push(value); }
1071ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  HValue* Pop() { return environment()->Pop(); }
1072ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org
1073d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  virtual HValue* context() = 0;
1074d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org
1075a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  // Adding instructions.
1076a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  HInstruction* AddInstruction(HInstruction* instr);
107771f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org  void FinishCurrentBlock(HControlInstruction* last);
107871f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org  void FinishExitCurrentBlock(HControlInstruction* instruction);
107971f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org
108071f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org  void Goto(HBasicBlock* from,
108171f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org            HBasicBlock* target,
108271f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org            FunctionState* state = NULL,
108371f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org            bool add_simulate = true) {
1084f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    from->Goto(target, source_position(), state, add_simulate);
108571f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org  }
108671f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org  void Goto(HBasicBlock* target,
108771f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org            FunctionState* state = NULL,
108871f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org            bool add_simulate = true) {
108971f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org    Goto(current_block(), target, state, add_simulate);
109071f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org  }
109171f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org  void GotoNoSimulate(HBasicBlock* from, HBasicBlock* target) {
109271f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org    Goto(from, target, NULL, false);
109371f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org  }
109471f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org  void GotoNoSimulate(HBasicBlock* target) {
109571f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org    Goto(target, NULL, false);
109671f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org  }
109771f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org  void AddLeaveInlined(HBasicBlock* block,
109871f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org                       HValue* return_value,
109971f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org                       FunctionState* state) {
1100f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    block->AddLeaveInlined(return_value, state, source_position());
110171f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org  }
110271f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org  void AddLeaveInlined(HValue* return_value, FunctionState* state) {
110371f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org    return AddLeaveInlined(current_block(), return_value, state);
110471f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org  }
11051510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
11061510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  template<class I>
1107d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  HInstruction* NewUncasted() { return I::New(zone(), context()); }
1108d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org
1109d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  template<class I>
1110f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org  I* New() { return I::New(zone(), context()); }
1111d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org
1112d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  template<class I>
1113d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  HInstruction* AddUncasted() { return AddInstruction(NewUncasted<I>());}
1114d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org
1115d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  template<class I>
1116f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org  I* Add() { return AddInstructionTyped(New<I>());}
1117d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org
1118d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  template<class I, class P1>
1119d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  HInstruction* NewUncasted(P1 p1) {
1120d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org    return I::New(zone(), context(), p1);
1121d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  }
1122d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org
1123d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  template<class I, class P1>
1124f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org  I* New(P1 p1) { return I::New(zone(), context(), p1); }
1125d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org
1126d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  template<class I, class P1>
1127d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  HInstruction* AddUncasted(P1 p1) {
1128d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org    HInstruction* result = AddInstruction(NewUncasted<I>(p1));
1129d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org    // Specializations must have their parameters properly casted
1130d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org    // to avoid landing here.
1131e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(!result->IsReturn() && !result->IsSimulate() &&
1132d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org           !result->IsDeoptimize());
1133d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org    return result;
1134d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  }
11351510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
11361510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  template<class I, class P1>
11371510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  I* Add(P1 p1) {
1138f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org    I* result = AddInstructionTyped(New<I>(p1));
1139f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org    // Specializations must have their parameters properly casted
1140f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org    // to avoid landing here.
1141e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(!result->IsReturn() && !result->IsSimulate() &&
1142f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org           !result->IsDeoptimize());
1143f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org    return result;
1144d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  }
1145d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org
1146d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  template<class I, class P1, class P2>
1147d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  HInstruction* NewUncasted(P1 p1, P2 p2) {
1148d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org    return I::New(zone(), context(), p1, p2);
1149d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  }
1150d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org
1151d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  template<class I, class P1, class P2>
1152d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  I* New(P1 p1, P2 p2) {
1153f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org    return I::New(zone(), context(), p1, p2);
1154d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  }
1155d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org
1156d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  template<class I, class P1, class P2>
1157d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  HInstruction* AddUncasted(P1 p1, P2 p2) {
1158d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org    HInstruction* result = AddInstruction(NewUncasted<I>(p1, p2));
1159d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org    // Specializations must have their parameters properly casted
1160d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org    // to avoid landing here.
1161e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(!result->IsSimulate());
1162d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org    return result;
11631510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  }
11641510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
11651510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  template<class I, class P1, class P2>
11661510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  I* Add(P1 p1, P2 p2) {
1167f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org    I* result = AddInstructionTyped(New<I>(p1, p2));
1168f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org    // Specializations must have their parameters properly casted
1169f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org    // to avoid landing here.
1170e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(!result->IsSimulate());
1171f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org    return result;
1172d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  }
1173d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org
1174d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  template<class I, class P1, class P2, class P3>
1175d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  HInstruction* NewUncasted(P1 p1, P2 p2, P3 p3) {
1176d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org    return I::New(zone(), context(), p1, p2, p3);
1177d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  }
1178d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org
1179d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  template<class I, class P1, class P2, class P3>
1180d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  I* New(P1 p1, P2 p2, P3 p3) {
1181f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org    return I::New(zone(), context(), p1, p2, p3);
1182d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  }
1183d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org
1184d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  template<class I, class P1, class P2, class P3>
1185d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  HInstruction* AddUncasted(P1 p1, P2 p2, P3 p3) {
1186d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org    return AddInstruction(NewUncasted<I>(p1, p2, p3));
11871510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  }
11881510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
11891510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  template<class I, class P1, class P2, class P3>
11901510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  I* Add(P1 p1, P2 p2, P3 p3) {
1191f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org    return AddInstructionTyped(New<I>(p1, p2, p3));
1192d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  }
1193d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org
1194d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  template<class I, class P1, class P2, class P3, class P4>
1195d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  HInstruction* NewUncasted(P1 p1, P2 p2, P3 p3, P4 p4) {
1196d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org    return I::New(zone(), context(), p1, p2, p3, p4);
1197d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  }
1198d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org
1199d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  template<class I, class P1, class P2, class P3, class P4>
1200d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  I* New(P1 p1, P2 p2, P3 p3, P4 p4) {
1201f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org    return I::New(zone(), context(), p1, p2, p3, p4);
1202d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  }
1203d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org
1204d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  template<class I, class P1, class P2, class P3, class P4>
1205d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  HInstruction* AddUncasted(P1 p1, P2 p2, P3 p3, P4 p4) {
1206d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org    return AddInstruction(NewUncasted<I>(p1, p2, p3, p4));
12071510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  }
12081510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
12091510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  template<class I, class P1, class P2, class P3, class P4>
12101510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  I* Add(P1 p1, P2 p2, P3 p3, P4 p4) {
1211f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org    return AddInstructionTyped(New<I>(p1, p2, p3, p4));
1212d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  }
1213d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org
1214d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  template<class I, class P1, class P2, class P3, class P4, class P5>
1215d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  HInstruction* NewUncasted(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) {
1216d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org    return I::New(zone(), context(), p1, p2, p3, p4, p5);
1217d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  }
1218d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org
1219d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  template<class I, class P1, class P2, class P3, class P4, class P5>
1220d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  I* New(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) {
1221f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org    return I::New(zone(), context(), p1, p2, p3, p4, p5);
1222d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  }
1223d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org
1224d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  template<class I, class P1, class P2, class P3, class P4, class P5>
1225d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  HInstruction* AddUncasted(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) {
1226d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org    return AddInstruction(NewUncasted<I>(p1, p2, p3, p4, p5));
12271510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  }
12281510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
12291510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  template<class I, class P1, class P2, class P3, class P4, class P5>
12301510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  I* Add(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) {
1231f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org    return AddInstructionTyped(New<I>(p1, p2, p3, p4, p5));
1232d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  }
1233d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org
1234d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  template<class I, class P1, class P2, class P3, class P4, class P5, class P6>
1235d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  HInstruction* NewUncasted(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6) {
1236d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org    return I::New(zone(), context(), p1, p2, p3, p4, p5, p6);
1237d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  }
1238d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org
1239d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  template<class I, class P1, class P2, class P3, class P4, class P5, class P6>
1240d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  I* New(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6) {
1241f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org    return I::New(zone(), context(), p1, p2, p3, p4, p5, p6);
1242d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  }
1243d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org
1244d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  template<class I, class P1, class P2, class P3, class P4, class P5, class P6>
1245d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  HInstruction* AddUncasted(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6) {
1246d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org    return AddInstruction(NewUncasted<I>(p1, p2, p3, p4, p5, p6));
12471510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  }
12481510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
12491510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  template<class I, class P1, class P2, class P3, class P4, class P5, class P6>
12501510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  I* Add(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6) {
1251f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org    return AddInstructionTyped(New<I>(p1, p2, p3, p4, p5, p6));
1252d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  }
1253d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org
1254d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  template<class I, class P1, class P2, class P3, class P4,
1255d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org      class P5, class P6, class P7>
1256d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  HInstruction* NewUncasted(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7) {
1257d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org    return I::New(zone(), context(), p1, p2, p3, p4, p5, p6, p7);
1258d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  }
1259d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org
1260d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  template<class I, class P1, class P2, class P3, class P4,
1261d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org      class P5, class P6, class P7>
1262d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org      I* New(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7) {
1263f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org    return I::New(zone(), context(), p1, p2, p3, p4, p5, p6, p7);
1264d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  }
1265d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org
1266d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  template<class I, class P1, class P2, class P3,
1267d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org           class P4, class P5, class P6, class P7>
1268d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  HInstruction* AddUncasted(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7) {
1269d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org    return AddInstruction(NewUncasted<I>(p1, p2, p3, p4, p5, p6, p7));
12701510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  }
12711510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
12721510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  template<class I, class P1, class P2, class P3,
12731510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org           class P4, class P5, class P6, class P7>
12741510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  I* Add(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7) {
1275f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org    return AddInstructionTyped(New<I>(p1, p2, p3, p4, p5, p6, p7));
1276d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  }
1277d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org
1278d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  template<class I, class P1, class P2, class P3, class P4,
1279d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org      class P5, class P6, class P7, class P8>
1280d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  HInstruction* NewUncasted(P1 p1, P2 p2, P3 p3, P4 p4,
1281d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org                            P5 p5, P6 p6, P7 p7, P8 p8) {
1282d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org    return I::New(zone(), context(), p1, p2, p3, p4, p5, p6, p7, p8);
1283d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  }
1284d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org
1285d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  template<class I, class P1, class P2, class P3, class P4,
1286d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org      class P5, class P6, class P7, class P8>
1287d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org      I* New(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8) {
1288f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org    return I::New(zone(), context(), p1, p2, p3, p4, p5, p6, p7, p8);
1289d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  }
1290d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org
1291d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  template<class I, class P1, class P2, class P3, class P4,
1292d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org           class P5, class P6, class P7, class P8>
1293d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  HInstruction* AddUncasted(P1 p1, P2 p2, P3 p3, P4 p4,
1294d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org                            P5 p5, P6 p6, P7 p7, P8 p8) {
1295d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org    return AddInstruction(NewUncasted<I>(p1, p2, p3, p4, p5, p6, p7, p8));
12961510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  }
12971510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
12981510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  template<class I, class P1, class P2, class P3, class P4,
12991510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org           class P5, class P6, class P7, class P8>
13001510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  I* Add(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8) {
1301f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org    return AddInstructionTyped(New<I>(p1, p2, p3, p4, p5, p6, p7, p8));
13021510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  }
13031510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
1304ad75d6febf45d81dda1f4cd158c7eb97c0408a25danno@chromium.org  void AddSimulate(BailoutId id, RemovableSimulate removable = FIXED_SIMULATE);
1305e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
13067e6132b924829c353864933f29124419916db550machenbach@chromium.org  // When initializing arrays, we'll unfold the loop if the number of elements
13077e6132b924829c353864933f29124419916db550machenbach@chromium.org  // is known at compile time and is <= kElementLoopUnrollThreshold.
13087e6132b924829c353864933f29124419916db550machenbach@chromium.org  static const int kElementLoopUnrollThreshold = 8;
13097e6132b924829c353864933f29124419916db550machenbach@chromium.org
1310a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org protected:
1311a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  virtual bool BuildGraph() = 0;
1312a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
1313b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org  HBasicBlock* CreateBasicBlock(HEnvironment* env);
1314b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org  HBasicBlock* CreateLoopHeaderBlock();
1315b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org
13161845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org  template <class BitFieldClass>
13171845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org  HValue* BuildDecodeField(HValue* encoded_field) {
1318d574d98bea4e0a0bee2d1d2d858bf6d24c873d7eyangguo@chromium.org    HValue* mask_value = Add<HConstant>(static_cast<int>(BitFieldClass::kMask));
1319d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org    HValue* masked_field =
1320d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org        AddUncasted<HBitwise>(Token::BIT_AND, encoded_field, mask_value);
1321d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org    return AddUncasted<HShr>(masked_field,
1322d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org        Add<HConstant>(static_cast<int>(BitFieldClass::kShift)));
13231845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org  }
13241845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org
13251845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org  HValue* BuildGetElementsKind(HValue* object);
13261845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org
13271510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  HValue* BuildCheckHeapObject(HValue* object);
132890dca01eac542464c29011d239bf18f26e0b8f00machenbach@chromium.org  HValue* BuildCheckString(HValue* string);
1329c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  HValue* BuildWrapReceiver(HValue* object, HValue* function);
133094b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org
1331a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  // Building common constructs
13327bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org  HValue* BuildCheckForCapacityGrow(HValue* object,
13337bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org                                    HValue* elements,
13347bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org                                    ElementsKind kind,
13357bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org                                    HValue* length,
13367bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org                                    HValue* key,
133771ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org                                    bool is_js_array,
1338f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org                                    PropertyAccessType access_type);
13397bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org
13407bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org  HValue* BuildCopyElementsOnWrite(HValue* object,
13417bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org                                   HValue* elements,
13427bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org                                   ElementsKind kind,
13437bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org                                   HValue* length);
1344a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
1345ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  void BuildTransitionElementsKind(HValue* object,
1346ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org                                   HValue* map,
1347ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org                                   ElementsKind from_kind,
1348ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org                                   ElementsKind to_kind,
1349ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org                                   bool is_jsarray);
1350ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org
13516d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org  HValue* BuildNumberToString(HValue* object, Type* type);
13523d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org
13531845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org  void BuildJSObjectCheck(HValue* receiver,
13541845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org                          int bit_field_mask);
13551845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org
13561845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org  // Checks a key value that's being used for a keyed element access context. If
13571845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org  // the key is a index, i.e. a smi or a number in a unique string with a cached
13581845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org  // numeric value, the "true" of the continuation is joined. Otherwise,
13591845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org  // if the key is a name or a unique string, the "false" of the continuation is
13601845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org  // joined. Otherwise, a deoptimization is triggered. In both paths of the
13611845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org  // continuation, the key is pushed on the top of the environment.
13621845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org  void BuildKeyedIndexCheck(HValue* key,
13631845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org                            HIfContinuation* join_continuation);
13641845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org
13651845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org  // Checks the properties of an object if they are in dictionary case, in which
13661845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org  // case "true" of continuation is taken, otherwise the "false"
13671845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org  void BuildTestForDictionaryProperties(HValue* object,
13681845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org                                        HIfContinuation* continuation);
13691845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org
13701845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org  void BuildNonGlobalObjectCheck(HValue* receiver);
13711845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org
13721845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org  HValue* BuildKeyedLookupCacheHash(HValue* object,
13731845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org                                    HValue* key);
13741845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org
1375ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  HValue* BuildUncheckedDictionaryElementLoad(HValue* receiver,
13761845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org                                              HValue* elements,
13771845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org                                              HValue* key,
13781845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org                                              HValue* hash);
1379ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org
138009cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org  HValue* BuildRegExpConstructResult(HValue* length,
138109cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org                                     HValue* index,
138209cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org                                     HValue* input);
138309cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org
13840f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org  // Allocates a new object according with the given allocation properties.
13850f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org  HAllocate* BuildAllocate(HValue* object_size,
13860f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org                           HType type,
13870f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org                           InstanceType instance_type,
13880f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org                           HAllocationMode allocation_mode);
13890f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org  // Computes the sum of two string lengths, taking care of overflow handling.
13900f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org  HValue* BuildAddStringLengths(HValue* left_length, HValue* right_length);
13910f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org  // Creates a cons string using the two input strings.
13920f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org  HValue* BuildCreateConsString(HValue* length,
13930f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org                                HValue* left,
13940f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org                                HValue* right,
13950f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org                                HAllocationMode allocation_mode);
13960cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org  // Copies characters from one sequential string to another.
13970cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org  void BuildCopySeqStringChars(HValue* src,
13980cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org                               HValue* src_offset,
13990cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org                               String::Encoding src_encoding,
14000cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org                               HValue* dst,
14010cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org                               HValue* dst_offset,
14020cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org                               String::Encoding dst_encoding,
14030cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org                               HValue* length);
1404895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org
1405895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org  // Align an object size to object alignment boundary
1406895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org  HValue* BuildObjectSizeAlignment(HValue* unaligned_size, int header_size);
1407895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org
14080cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org  // Both operands are non-empty strings.
14090cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org  HValue* BuildUncheckedStringAdd(HValue* left,
14100cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org                                  HValue* right,
14110f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org                                  HAllocationMode allocation_mode);
14120f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org  // Add two strings using allocation mode, validating type feedback.
14130cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org  HValue* BuildStringAdd(HValue* left,
14140cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org                         HValue* right,
14150f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org                         HAllocationMode allocation_mode);
14160cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org
1417a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  HInstruction* BuildUncheckedMonomorphicElementAccess(
14181e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org      HValue* checked_object,
1419a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      HValue* key,
1420a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      HValue* val,
1421a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      bool is_js_array,
1422a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      ElementsKind elements_kind,
1423f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org      PropertyAccessType access_type,
1424906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org      LoadKeyedHoleMode load_mode,
142553ad17558c81e6099cef4442237d7da643a5becfsvenpanne@chromium.org      KeyedAccessStoreMode store_mode);
1426a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
1427b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org  HInstruction* AddElementAccess(
1428ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org      HValue* elements,
1429ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org      HValue* checked_key,
1430ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org      HValue* val,
1431ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org      HValue* dependency,
1432ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org      ElementsKind elements_kind,
1433f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org      PropertyAccessType access_type,
1434b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org      LoadKeyedHoleMode load_mode = NEVER_RETURN_HOLE);
1435ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org
14360f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org  HInstruction* AddLoadStringInstanceType(HValue* string);
14370f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org  HInstruction* AddLoadStringLength(HValue* string);
14386a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org  HStoreNamedField* AddStoreMapConstant(HValue* object, Handle<Map> map) {
14396a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org    return Add<HStoreNamedField>(object, HObjectAccess::ForMap(),
14406a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org                                 Add<HConstant>(map));
14410cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org  }
144238de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org  HLoadNamedField* AddLoadMap(HValue* object,
144338de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org                              HValue* dependency = NULL);
1444a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org  HLoadNamedField* AddLoadElements(HValue* object,
1445a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org                                   HValue* dependency = NULL);
1446528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org
1447528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  bool MatchRotateRight(HValue* left,
1448528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org                        HValue* right,
1449528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org                        HValue** operand,
1450528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org                        HValue** shift_amount);
1451528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org
14527ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org  HValue* BuildBinaryOperation(Token::Value op,
14537ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org                               HValue* left,
14547ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org                               HValue* right,
14556d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org                               Type* left_type,
14566d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org                               Type* right_type,
14576d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org                               Type* result_type,
14580f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org                               Maybe<int> fixed_right_arg,
14590f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org                               HAllocationMode allocation_mode);
1460528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org
1461a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org  HLoadNamedField* AddLoadFixedArrayLength(HValue *object,
1462a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org                                           HValue *dependency = NULL);
1463a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org
1464a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org  HLoadNamedField* AddLoadArrayLength(HValue *object,
1465a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org                                      ElementsKind kind,
1466a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org                                      HValue *dependency = NULL);
1467c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org
1468d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  HValue* AddLoadJSBuiltin(Builtins::JavaScript builtin);
1469e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org
14706d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org  HValue* EnforceNumberType(HValue* number, Type* expected);
14716d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org  HValue* TruncateToNumber(HValue* value, Type** expected);
1472e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org
1473f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  void FinishExitWithHardDeoptimization(const char* reason);
1474e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org
1475528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  void AddIncrementCounter(StatsCounter* counter);
1476d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org
1477ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  class IfBuilder FINAL {
147894b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org   public:
1479f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org    // If using this constructor, Initialize() must be called explicitly!
1480f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org    IfBuilder();
1481f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org
148271f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org    explicit IfBuilder(HGraphBuilder* builder);
1483b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org    IfBuilder(HGraphBuilder* builder,
1484b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org              HIfContinuation* continuation);
1485b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org
148694b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org    ~IfBuilder() {
148794b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org      if (!finished_) End();
148894b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org    }
148994b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org
1490f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org    void Initialize(HGraphBuilder* builder);
1491f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org
1492b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org    template<class Condition>
1493528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    Condition* If(HValue *p) {
1494528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org      Condition* compare = builder()->New<Condition>(p);
1495b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org      AddCompare(compare);
1496b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org      return compare;
1497b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org    }
1498b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org
1499b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org    template<class Condition, class P2>
1500528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    Condition* If(HValue* p1, P2 p2) {
1501528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org      Condition* compare = builder()->New<Condition>(p1, p2);
1502b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org      AddCompare(compare);
1503b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org      return compare;
1504b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org    }
1505b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org
1506e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org    template<class Condition, class P2, class P3>
1507528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    Condition* If(HValue* p1, P2 p2, P3 p3) {
1508528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org      Condition* compare = builder()->New<Condition>(p1, p2, p3);
1509e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org      AddCompare(compare);
1510e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org      return compare;
1511e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org    }
1512e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org
1513528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    template<class Condition>
1514528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    Condition* IfNot(HValue* p) {
1515528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org      Condition* compare = If<Condition>(p);
1516528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org      compare->Not();
1517528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org      return compare;
1518528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    }
1519528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org
152032d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org    template<class Condition, class P2>
1521528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    Condition* IfNot(HValue* p1, P2 p2) {
1522528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org      Condition* compare = If<Condition>(p1, p2);
1523528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org      compare->Not();
152432d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org      return compare;
152532d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org    }
152632d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org
1527e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org    template<class Condition, class P2, class P3>
1528528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    Condition* IfNot(HValue* p1, P2 p2, P3 p3) {
1529528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org      Condition* compare = If<Condition>(p1, p2, p3);
1530528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org      compare->Not();
1531e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org      return compare;
1532b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org    }
1533b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org
1534b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org    template<class Condition>
1535528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    Condition* OrIf(HValue *p) {
1536b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org      Or();
1537b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org      return If<Condition>(p);
1538b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org    }
1539b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org
1540b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org    template<class Condition, class P2>
1541528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    Condition* OrIf(HValue* p1, P2 p2) {
1542b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org      Or();
1543b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org      return If<Condition>(p1, p2);
1544b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org    }
1545b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org
1546e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org    template<class Condition, class P2, class P3>
1547528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    Condition* OrIf(HValue* p1, P2 p2, P3 p3) {
1548e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org      Or();
1549e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org      return If<Condition>(p1, p2, p3);
1550b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org    }
1551b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org
1552b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org    template<class Condition>
1553528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    Condition* AndIf(HValue *p) {
1554b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org      And();
1555b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org      return If<Condition>(p);
1556b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org    }
1557b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org
1558b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org    template<class Condition, class P2>
1559528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    Condition* AndIf(HValue* p1, P2 p2) {
1560b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org      And();
1561b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org      return If<Condition>(p1, p2);
1562b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org    }
1563b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org
1564e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org    template<class Condition, class P2, class P3>
1565528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    Condition* AndIf(HValue* p1, P2 p2, P3 p3) {
1566e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org      And();
1567e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org      return If<Condition>(p1, p2, p3);
1568e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org    }
1569e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org
1570b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org    void Or();
1571b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org    void And();
1572b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org
1573528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    // Captures the current state of this IfBuilder in the specified
1574528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    // continuation and ends this IfBuilder.
1575b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org    void CaptureContinuation(HIfContinuation* continuation);
1576b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org
1577528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    // Joins the specified continuation from this IfBuilder and ends this
1578528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    // IfBuilder. This appends a Goto instruction from the true branch of
1579528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    // this IfBuilder to the true branch of the continuation unless the
1580528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    // true branch of this IfBuilder is already finished. And vice versa
1581528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    // for the false branch.
1582528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    //
1583528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    // The basic idea is as follows: You have several nested IfBuilder's
1584528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    // that you want to join based on two possible outcomes (i.e. success
1585528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    // and failure, or whatever). You can do this easily using this method
1586528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    // now, for example:
1587528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    //
1588528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    //   HIfContinuation cont(graph()->CreateBasicBlock(),
1589528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    //                        graph()->CreateBasicBlock());
1590528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    //   ...
1591528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    //     IfBuilder if_whatever(this);
1592528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    //     if_whatever.If<Condition>(arg);
1593528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    //     if_whatever.Then();
1594528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    //     ...
1595528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    //     if_whatever.Else();
1596528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    //     ...
1597528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    //     if_whatever.JoinContinuation(&cont);
1598528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    //   ...
1599528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    //     IfBuilder if_something(this);
1600528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    //     if_something.If<Condition>(arg1, arg2);
1601528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    //     if_something.Then();
1602528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    //     ...
1603528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    //     if_something.Else();
1604528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    //     ...
1605528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    //     if_something.JoinContinuation(&cont);
1606528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    //   ...
1607528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    //   IfBuilder if_finally(this, &cont);
1608528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    //   if_finally.Then();
1609528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    //   // continues after then code of if_whatever or if_something.
1610528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    //   ...
1611528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    //   if_finally.Else();
1612528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    //   // continues after else code of if_whatever or if_something.
1613528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    //   ...
1614528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    //   if_finally.End();
1615528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    void JoinContinuation(HIfContinuation* continuation);
1616528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org
1617b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org    void Then();
1618b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org    void Else();
161994b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org    void End();
162094b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org
1621594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    void Deopt(const char* reason);
1622ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    void ThenDeopt(const char* reason) {
1623ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org      Then();
1624ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org      Deopt(reason);
1625ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    }
1626594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    void ElseDeopt(const char* reason) {
162732d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org      Else();
1628594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      Deopt(reason);
162932d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org    }
1630b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org
1631ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org    void Return(HValue* value);
1632ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org
163394b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org   private:
1634f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org    void InitializeDontCreateBlocks(HGraphBuilder* builder);
1635f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org
1636528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    HControlInstruction* AddCompare(HControlInstruction* compare);
1637b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org
1638f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org    HGraphBuilder* builder() const {
1639e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      DCHECK(builder_ != NULL);  // Have you called "Initialize"?
1640f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org      return builder_;
1641f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org    }
164271fc3467b5396c27d0b701d88e196e88c78d8864mstarzinger@chromium.org
1643ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    void AddMergeAtJoinBlock(bool deopt);
1644ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org
1645ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    void Finish();
1646ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    void Finish(HBasicBlock** then_continuation,
1647ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org                HBasicBlock** else_continuation);
1648ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org
1649ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    class MergeAtJoinBlock : public ZoneObject {
1650ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org     public:
1651ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org      MergeAtJoinBlock(HBasicBlock* block,
1652ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org                       bool deopt,
1653ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org                       MergeAtJoinBlock* next)
1654ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org        : block_(block),
1655ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org          deopt_(deopt),
1656ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org          next_(next) {}
1657ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org      HBasicBlock* block_;
1658ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org      bool deopt_;
1659ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org      MergeAtJoinBlock* next_;
1660ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    };
1661ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org
166294b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org    HGraphBuilder* builder_;
1663b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org    bool finished_ : 1;
1664b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org    bool did_then_ : 1;
1665b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org    bool did_else_ : 1;
1666ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    bool did_else_if_ : 1;
1667b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org    bool did_and_ : 1;
1668b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org    bool did_or_ : 1;
1669b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org    bool captured_ : 1;
1670b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org    bool needs_compare_ : 1;
1671ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    bool pending_merge_block_ : 1;
167209d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org    HBasicBlock* first_true_block_;
167309d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org    HBasicBlock* first_false_block_;
1674b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org    HBasicBlock* split_edge_merge_block_;
1675ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    MergeAtJoinBlock* merge_at_join_blocks_;
1676ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    int normal_merge_at_join_block_count_;
1677ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    int deopt_merge_at_join_block_count_;
167894b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org  };
167994b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org
1680ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  class LoopBuilder FINAL {
168194b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org   public:
168294b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org    enum Direction {
168394b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org      kPreIncrement,
168494b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org      kPostIncrement,
168594b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org      kPreDecrement,
1686d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org      kPostDecrement,
1687d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org      kWhileTrue
168894b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org    };
168994b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org
1690d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org    explicit LoopBuilder(HGraphBuilder* builder);  // while (true) {...}
169194b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org    LoopBuilder(HGraphBuilder* builder,
169294b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org                HValue* context,
16932d18b3604565efb0b4d300dd899901ed866eaaaedanno@chromium.org                Direction direction);
1694662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org    LoopBuilder(HGraphBuilder* builder,
1695662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org                HValue* context,
1696662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org                Direction direction,
1697662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org                HValue* increment_amount);
1698662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org
169994b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org    ~LoopBuilder() {
1700e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      DCHECK(finished_);
170194b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org    }
170294b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org
170309d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org    HValue* BeginBody(
170409d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org        HValue* initial,
170509d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org        HValue* terminating,
1706dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org        Token::Value token);
1707662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org
1708d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org    void BeginBody(int drop_count);
1709d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org
1710662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org    void Break();
1711662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org
171294b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org    void EndBody();
171394b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org
171494b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org   private:
1715d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org    void Initialize(HGraphBuilder* builder, HValue* context,
1716d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org                    Direction direction, HValue* increment_amount);
171771fc3467b5396c27d0b701d88e196e88c78d8864mstarzinger@chromium.org    Zone* zone() { return builder_->zone(); }
171871fc3467b5396c27d0b701d88e196e88c78d8864mstarzinger@chromium.org
171994b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org    HGraphBuilder* builder_;
172094b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org    HValue* context_;
1721662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org    HValue* increment_amount_;
172294b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org    HInstruction* increment_;
172394b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org    HPhi* phi_;
172494b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org    HBasicBlock* header_block_;
172594b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org    HBasicBlock* body_block_;
172694b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org    HBasicBlock* exit_block_;
1727662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org    HBasicBlock* exit_trampoline_block_;
172894b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org    Direction direction_;
172994b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org    bool finished_;
173094b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org  };
173194b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org
1732d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  HValue* BuildNewElementsCapacity(HValue* old_capacity);
17337bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org
1734ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  class JSArrayBuilder FINAL {
1735ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org   public:
1736ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org    JSArrayBuilder(HGraphBuilder* builder,
1737ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org                   ElementsKind kind,
1738ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org                   HValue* allocation_site_payload,
17391510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org                   HValue* constructor_function,
17401510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org                   AllocationSiteOverrideMode override_mode);
1741d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org
1742d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org    JSArrayBuilder(HGraphBuilder* builder,
1743d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org                   ElementsKind kind,
1744ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org                   HValue* constructor_function = NULL);
1745ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org
1746b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org    enum FillMode {
1747b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org      DONT_FILL_WITH_HOLE,
1748b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org      FILL_WITH_HOLE
1749b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org    };
1750b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org
1751b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org    ElementsKind kind() { return kind_; }
175238de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org    HAllocate* elements_location() { return elements_location_; }
175338de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org
175438de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org    HAllocate* AllocateEmptyArray();
175538de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org    HAllocate* AllocateArray(HValue* capacity,
175638de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org                             HValue* length_field,
175738de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org                             FillMode fill_mode = FILL_WITH_HOLE);
175838de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org    // Use these allocators when capacity could be unknown at compile time
175938de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org    // but its limit is known. For constant |capacity| the value of
176038de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org    // |capacity_upper_bound| is ignored and the actual |capacity|
176138de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org    // value is used as an upper bound.
176238de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org    HAllocate* AllocateArray(HValue* capacity,
176338de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org                             int capacity_upper_bound,
176438de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org                             HValue* length_field,
176538de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org                             FillMode fill_mode = FILL_WITH_HOLE);
176638de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org    HAllocate* AllocateArray(HValue* capacity,
176738de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org                             HConstant* capacity_upper_bound,
176838de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org                             HValue* length_field,
176938de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org                             FillMode fill_mode = FILL_WITH_HOLE);
1770ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org    HValue* GetElementsLocation() { return elements_location_; }
1771ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    HValue* EmitMapCode();
1772ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org
1773ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org   private:
1774ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org    Zone* zone() const { return builder_->zone(); }
1775ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org    int elements_size() const {
1776ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org      return IsFastDoubleElementsKind(kind_) ? kDoubleSize : kPointerSize;
1777ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org    }
1778ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org    HGraphBuilder* builder() { return builder_; }
1779ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org    HGraph* graph() { return builder_->graph(); }
1780ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org    int initial_capacity() {
1781ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org      STATIC_ASSERT(JSArray::kPreallocatedArrayElements > 0);
1782ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org      return JSArray::kPreallocatedArrayElements;
1783ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org    }
1784ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org
1785d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org    HValue* EmitInternalMapCode();
1786ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org
1787ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org    HGraphBuilder* builder_;
1788ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org    ElementsKind kind_;
1789ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org    AllocationSiteMode mode_;
1790ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org    HValue* allocation_site_payload_;
1791d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org    HValue* constructor_function_;
179238de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org    HAllocate* elements_location_;
1793ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  };
1794ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org
1795b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  HValue* BuildAllocateArrayFromLength(JSArrayBuilder* array_builder,
1796b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org                                       HValue* length_argument);
179738de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org  HValue* BuildCalculateElementsSize(ElementsKind kind,
179838de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org                                     HValue* capacity);
179938de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org  HAllocate* AllocateJSArrayObject(AllocationSiteMode mode);
180038de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org  HConstant* EstablishElementsAllocationSize(ElementsKind kind, int capacity);
1801b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org
180238de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org  HAllocate* BuildAllocateElements(ElementsKind kind, HValue* size_in_bytes);
18037bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org
1804c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org  void BuildInitializeElementsHeader(HValue* elements,
1805c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org                                     ElementsKind kind,
1806c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org                                     HValue* capacity);
1807e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
1808d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  HValue* BuildAllocateElementsAndInitializeElementsHeader(ElementsKind kind,
1809c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org                                                           HValue* capacity);
1810e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
181138de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org  // |array| must have been allocated with enough room for
181238de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org  // 1) the JSArray and 2) an AllocationMemento if mode requires it.
181338de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org  // If the |elements| value provided is NULL then the array elements storage
181438de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org  // is initialized with empty array.
181538de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org  void BuildJSArrayHeader(HValue* array,
181638de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org                          HValue* array_map,
181738de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org                          HValue* elements,
181838de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org                          AllocationSiteMode mode,
181938de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org                          ElementsKind elements_kind,
182038de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org                          HValue* allocation_site_payload,
182138de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org                          HValue* length_field);
1822ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org
18237bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org  HValue* BuildGrowElementsCapacity(HValue* object,
18247bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org                                    HValue* elements,
18257bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org                                    ElementsKind kind,
1826bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org                                    ElementsKind new_kind,
18277bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org                                    HValue* length,
18282d18b3604565efb0b4d300dd899901ed866eaaaedanno@chromium.org                                    HValue* new_capacity);
18297bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org
183038de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org  void BuildFillElementsWithValue(HValue* elements,
183138de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org                                  ElementsKind elements_kind,
183238de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org                                  HValue* from,
183338de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org                                  HValue* to,
183438de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org                                  HValue* value);
183538de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org
1836d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  void BuildFillElementsWithHole(HValue* elements,
18377bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org                                 ElementsKind elements_kind,
18387bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org                                 HValue* from,
18392d18b3604565efb0b4d300dd899901ed866eaaaedanno@chromium.org                                 HValue* to);
18407bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org
184138de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org  void BuildCopyElements(HValue* from_elements,
184294b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org                         ElementsKind from_elements_kind,
184394b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org                         HValue* to_elements,
184494b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org                         ElementsKind to_elements_kind,
18457bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org                         HValue* length,
18462d18b3604565efb0b4d300dd899901ed866eaaaedanno@chromium.org                         HValue* capacity);
184794b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org
1848a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org  HValue* BuildCloneShallowArrayCow(HValue* boilerplate,
1849a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org                                    HValue* allocation_site,
1850a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org                                    AllocationSiteMode mode,
1851a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org                                    ElementsKind kind);
1852a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org
1853a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org  HValue* BuildCloneShallowArrayEmpty(HValue* boilerplate,
1854a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org                                      HValue* allocation_site,
1855a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org                                      AllocationSiteMode mode);
1856a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org
1857a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org  HValue* BuildCloneShallowArrayNonEmpty(HValue* boilerplate,
1858a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org                                         HValue* allocation_site,
1859a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org                                         AllocationSiteMode mode,
1860a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org                                         ElementsKind kind);
1861e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
1862ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  HValue* BuildElementIndexHash(HValue* index);
1863ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org
1864ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  void BuildCompareNil(
1865ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org      HValue* value,
18666d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org      Type* type,
1867ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org      HIfContinuation* continuation);
1868ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org
1869ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org  void BuildCreateAllocationMemento(HValue* previous_object,
1870ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org                                    HValue* previous_object_size,
1871ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org                                    HValue* payload);
1872ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org
1873af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org  HInstruction* BuildConstantMapCheck(Handle<JSObject> constant);
1874ec6855e761a7474a580d750a45d748323dd3b7c7verwaest@chromium.org  HInstruction* BuildCheckPrototypeMaps(Handle<JSObject> prototype,
1875ec6855e761a7474a580d750a45d748323dd3b7c7verwaest@chromium.org                                        Handle<JSObject> holder);
1876594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
1877034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.org  HInstruction* BuildGetNativeContext(HValue* closure);
1878d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  HInstruction* BuildGetNativeContext();
1879d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  HInstruction* BuildGetArrayFunction();
188057ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org
188171f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org protected:
188271f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org  void SetSourcePosition(int position) {
1883e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(position != RelocInfo::kNoPosition);
1884f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    position_.set_position(position - start_position_);
1885f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  }
1886f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org
1887f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  void EnterInlinedSource(int start_position, int id) {
1888f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    if (FLAG_hydrogen_track_positions) {
1889f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org      start_position_ = start_position;
1890f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org      position_.set_inlining_id(id);
1891f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    }
1892f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  }
1893f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org
1894f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  // Convert the given absolute offset from the start of the script to
1895f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  // the HSourcePosition assuming that this position corresponds to the
1896f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  // same function as current position_.
1897f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  HSourcePosition ScriptPositionToSourcePosition(int position) {
1898f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    HSourcePosition pos = position_;
1899f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    pos.set_position(position - start_position_);
1900f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    return pos;
1901f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  }
1902f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org
1903f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  HSourcePosition source_position() { return position_; }
1904f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  void set_source_position(HSourcePosition position) {
190571f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org    position_ = position;
190671f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org  }
190771f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org
190837be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org  template <typename ViewClass>
190937be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org  void BuildArrayBufferViewInitialization(HValue* obj,
191037be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org                                          HValue* buffer,
191137be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org                                          HValue* byte_offset,
191237be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org                                          HValue* byte_length);
191337be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org
1914a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org private:
1915a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  HGraphBuilder();
1916c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org
1917f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org  template <class I>
1918f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org  I* AddInstructionTyped(I* instr) {
1919f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org    return I::cast(AddInstruction(instr));
1920f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org  }
1921f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org
1922a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  CompilationInfo* info_;
1923a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  HGraph* graph_;
1924a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  HBasicBlock* current_block_;
19251e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org  Scope* scope_;
1926f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  HSourcePosition position_;
1927f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  int start_position_;
1928a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org};
1929a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
1930c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org
1931c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.orgtemplate<>
1932f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.orginline HDeoptimize* HGraphBuilder::Add<HDeoptimize>(
1933594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    const char* reason, Deoptimizer::BailoutType type) {
1934c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  if (type == Deoptimizer::SOFT) {
1935c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org    isolate()->counters()->soft_deopts_requested()->Increment();
1936c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org    if (FLAG_always_opt) return NULL;
1937c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  }
1938c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  if (current_block()->IsDeoptimizing()) return NULL;
1939d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org  HBasicBlock* after_deopt_block = CreateBasicBlock(
1940d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org      current_block()->last_environment());
1941d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org  HDeoptimize* instr = New<HDeoptimize>(reason, type, after_deopt_block);
1942c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  if (type == Deoptimizer::SOFT) {
1943c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org    isolate()->counters()->soft_deopts_inserted()->Increment();
1944c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  }
194571f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org  FinishCurrentBlock(instr);
1946d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org  set_current_block(after_deopt_block);
1947c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  return instr;
1948c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org}
1949c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org
1950c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org
1951c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.orgtemplate<>
1952f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.orginline HInstruction* HGraphBuilder::AddUncasted<HDeoptimize>(
1953594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    const char* reason, Deoptimizer::BailoutType type) {
1954f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org  return Add<HDeoptimize>(reason, type);
1955d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org}
1956d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org
1957d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org
1958d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.orgtemplate<>
1959f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.orginline HSimulate* HGraphBuilder::Add<HSimulate>(
1960d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org    BailoutId id,
1961d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org    RemovableSimulate removable) {
1962c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  HSimulate* instr = current_block()->CreateSimulate(id, removable);
1963c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  AddInstruction(instr);
1964c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  return instr;
1965c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org}
1966c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org
1967c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org
1968c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.orgtemplate<>
1969f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.orginline HSimulate* HGraphBuilder::Add<HSimulate>(
1970f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org    BailoutId id) {
1971f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org  return Add<HSimulate>(id, FIXED_SIMULATE);
1972f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org}
1973f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org
1974f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org
1975f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.orgtemplate<>
1976d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.orginline HInstruction* HGraphBuilder::AddUncasted<HSimulate>(BailoutId id) {
1977f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org  return Add<HSimulate>(id, FIXED_SIMULATE);
1978d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org}
1979d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org
1980d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org
1981d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.orgtemplate<>
1982f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.orginline HReturn* HGraphBuilder::Add<HReturn>(HValue* value) {
1983c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  int num_parameters = graph()->info()->num_parameters();
1984d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  HValue* params = AddUncasted<HConstant>(num_parameters);
1985d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  HReturn* return_instruction = New<HReturn>(value, params);
198671f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org  FinishExitCurrentBlock(return_instruction);
1987c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  return return_instruction;
1988c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org}
1989c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org
1990c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org
1991c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.orgtemplate<>
1992f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.orginline HReturn* HGraphBuilder::Add<HReturn>(HConstant* value) {
1993f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org  return Add<HReturn>(static_cast<HValue*>(value));
1994f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org}
1995f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org
1996f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.orgtemplate<>
1997f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.orginline HInstruction* HGraphBuilder::AddUncasted<HReturn>(HValue* value) {
1998f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org  return Add<HReturn>(value);
1999f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org}
2000f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org
2001f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org
2002f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.orgtemplate<>
2003d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.orginline HInstruction* HGraphBuilder::AddUncasted<HReturn>(HConstant* value) {
2004f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org  return Add<HReturn>(value);
2005d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org}
2006d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org
2007d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org
2008d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.orgtemplate<>
2009f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.orginline HCallRuntime* HGraphBuilder::Add<HCallRuntime>(
2010fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org    Handle<String> name,
2011fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org    const Runtime::Function* c_function,
2012fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org    int argument_count) {
2013fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org  HCallRuntime* instr = New<HCallRuntime>(name, c_function, argument_count);
2014fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org  if (graph()->info()->IsStub()) {
2015fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org    // When compiling code stubs, we don't want to save all double registers
2016fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org    // upon entry to the stub, but instead have the call runtime instruction
2017fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org    // save the double registers only on-demand (in the fallback case).
2018fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org    instr->set_save_doubles(kSaveFPRegs);
2019fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org  }
2020fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org  AddInstruction(instr);
2021fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org  return instr;
2022fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org}
2023fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org
2024fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org
2025fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.orgtemplate<>
2026f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.orginline HInstruction* HGraphBuilder::AddUncasted<HCallRuntime>(
2027f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org    Handle<String> name,
2028f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org    const Runtime::Function* c_function,
2029f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org    int argument_count) {
2030f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org  return Add<HCallRuntime>(name, c_function, argument_count);
2031f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org}
2032f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org
2033f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org
2034f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.orgtemplate<>
2035f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.orginline HContext* HGraphBuilder::New<HContext>() {
2036d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  return HContext::New(zone());
2037c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org}
2038c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org
2039c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org
2040f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.orgtemplate<>
2041f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.orginline HInstruction* HGraphBuilder::NewUncasted<HContext>() {
2042f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org  return New<HContext>();
2043f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org}
2044f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org
204571f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.orgclass HOptimizedGraphBuilder : public HGraphBuilder, public AstVisitor {
2046a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org public:
20473a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  // A class encapsulating (lazily-allocated) break and continue blocks for
20483a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  // a breakable statement.  Separated from BreakAndContinueScope so that it
20493a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  // can have a separate lifetime.
2050ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  class BreakAndContinueInfo FINAL BASE_EMBEDDED {
20513a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org   public:
2052be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org    explicit BreakAndContinueInfo(BreakableStatement* target,
20531e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org                                  Scope* scope,
2054be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org                                  int drop_extra = 0)
2055be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org        : target_(target),
2056be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org          break_block_(NULL),
2057be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org          continue_block_(NULL),
20581e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org          scope_(scope),
2059be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org          drop_extra_(drop_extra) {
20603a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    }
20613a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org
20623a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    BreakableStatement* target() { return target_; }
20633a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    HBasicBlock* break_block() { return break_block_; }
20643a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    void set_break_block(HBasicBlock* block) { break_block_ = block; }
20653a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    HBasicBlock* continue_block() { return continue_block_; }
20663a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    void set_continue_block(HBasicBlock* block) { continue_block_ = block; }
20671e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org    Scope* scope() { return scope_; }
2068be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org    int drop_extra() { return drop_extra_; }
20693a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org
20703a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org   private:
20713a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    BreakableStatement* target_;
20723a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    HBasicBlock* break_block_;
20733a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    HBasicBlock* continue_block_;
20741e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org    Scope* scope_;
2075be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org    int drop_extra_;
20763a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  };
20773a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org
20783a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  // A helper class to maintain a stack of current BreakAndContinueInfo
20793a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  // structures mirroring BreakableStatement nesting.
2080ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  class BreakAndContinueScope FINAL BASE_EMBEDDED {
20813a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org   public:
2082a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    BreakAndContinueScope(BreakAndContinueInfo* info,
2083a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org                          HOptimizedGraphBuilder* owner)
20843a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org        : info_(info), owner_(owner), next_(owner->break_scope()) {
20853a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org      owner->set_break_scope(this);
20863a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    }
20873a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org
20883a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    ~BreakAndContinueScope() { owner_->set_break_scope(next_); }
20893a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org
20903a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    BreakAndContinueInfo* info() { return info_; }
2091a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    HOptimizedGraphBuilder* owner() { return owner_; }
20923a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    BreakAndContinueScope* next() { return next_; }
20933a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org
20943a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    // Search the break stack for a break or continue target.
2095c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org    enum BreakType { BREAK, CONTINUE };
20961e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org    HBasicBlock* Get(BreakableStatement* stmt, BreakType type,
20971e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org                     Scope** scope, int* drop_extra);
20983a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org
20993a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org   private:
21003a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    BreakAndContinueInfo* info_;
2101a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    HOptimizedGraphBuilder* owner_;
21023a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    BreakAndContinueScope* next_;
21033a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  };
21043a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org
2105c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org  explicit HOptimizedGraphBuilder(CompilationInfo* info);
2106a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2107ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  virtual bool BuildGraph() OVERRIDE;
2108a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
21095f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  // Simple accessors.
21103a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  BreakAndContinueScope* break_scope() const { return break_scope_; }
21113a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  void set_break_scope(BreakAndContinueScope* head) { break_scope_ = head; }
21125f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org
2113d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  HValue* context() { return environment()->context(); }
2114d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org
2115c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org  HOsrBuilder* osr() const { return osr_; }
2116c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org
2117594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  void Bailout(BailoutReason reason);
21188e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org
21194f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  HBasicBlock* CreateJoin(HBasicBlock* first,
21204f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org                          HBasicBlock* second,
2121471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org                          BailoutId join_id);
21224f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org
2123394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  FunctionState* function_state() const { return function_state_; }
2124394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
212556454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org  void VisitDeclarations(ZoneList<Declaration*>* declarations);
212656454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org
2127178fb15415fbc935540c9780a526d104437fdf17verwaest@chromium.org  void* operator new(size_t size, Zone* zone) {
2128178fb15415fbc935540c9780a526d104437fdf17verwaest@chromium.org    return zone->New(static_cast<int>(size));
2129178fb15415fbc935540c9780a526d104437fdf17verwaest@chromium.org  }
2130304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org  void operator delete(void* pointer, Zone* zone) { }
2131304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org  void operator delete(void* pointer) { }
2132178fb15415fbc935540c9780a526d104437fdf17verwaest@chromium.org
2133a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  DEFINE_AST_VISITOR_SUBCLASS_MEMBERS();
2134a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
213571f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org protected:
2136a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Type of a member function that generates inline code for a native function.
2137a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  typedef void (HOptimizedGraphBuilder::*InlineFunctionGenerator)
2138a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      (CallRuntime* call);
2139a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2140a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Forward declarations for inner scope classes.
2141a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  class SubgraphScope;
2142a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2143a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  static const InlineFunctionGenerator kInlineFunctionGenerators[];
2144a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2145a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  static const int kMaxCallPolymorphism = 4;
2146a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  static const int kMaxLoadPolymorphism = 4;
2147a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  static const int kMaxStorePolymorphism = 4;
2148a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2149fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  // Even in the 'unlimited' case we have to have some limit in order not to
2150fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  // overflow the stack.
215188d326b0935b802e71e3a75e02f31fae8c2af96cmstarzinger@chromium.org  static const int kUnlimitedMaxInlinedSourceSize = 100000;
215288d326b0935b802e71e3a75e02f31fae8c2af96cmstarzinger@chromium.org  static const int kUnlimitedMaxInlinedNodes = 10000;
215388d326b0935b802e71e3a75e02f31fae8c2af96cmstarzinger@chromium.org  static const int kUnlimitedMaxInlinedNodesCumulative = 10000;
2154fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org
2155e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  // Maximum depth and total number of elements and properties for literal
2156e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  // graphs to be considered for fast deep-copying.
2157e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  static const int kMaxFastLiteralDepth = 3;
2158e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  static const int kMaxFastLiteralProperties = 8;
2159e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
2160a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Simple accessors.
21618f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org  void set_function_state(FunctionState* state) { function_state_ = state; }
21628f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org
2163a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  AstContext* ast_context() const { return ast_context_; }
2164a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void set_ast_context(AstContext* context) { ast_context_ = context; }
21658f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org
21668f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org  // Accessors forwarded to the function state.
216741728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  CompilationInfo* current_info() const {
21688f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org    return function_state()->compilation_info();
21698f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org  }
21708f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org  AstContext* call_context() const {
21718f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org    return function_state()->call_context();
21728f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org  }
21738f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org  HBasicBlock* function_return() const {
21748f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org    return function_state()->function_return();
21758f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org  }
21768f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org  TestContext* inlined_test_context() const {
21778f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org    return function_state()->test_context();
21788f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org  }
21798f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org  void ClearInlinedTestContext() {
21808f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org    function_state()->ClearInlinedTestContext();
21818f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org  }
2182486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org  StrictMode function_strict_mode() {
2183486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org    return function_state()->compilation_info()->strict_mode();
218444bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org  }
2185a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2186a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Generators for inline runtime functions.
21875f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org#define INLINE_FUNCTION_GENERATOR_DECLARATION(Name, argc, ressize)      \
21883a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  void Generate##Name(CallRuntime* call);
2189a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2190a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  INLINE_FUNCTION_LIST(INLINE_FUNCTION_GENERATOR_DECLARATION)
21919b95fd75bfb24acf6b51a360058331013e74fc73machenbach@chromium.org  INLINE_OPTIMIZED_FUNCTION_LIST(INLINE_FUNCTION_GENERATOR_DECLARATION)
2192a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#undef INLINE_FUNCTION_GENERATOR_DECLARATION
2193a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
219483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  void VisitDelete(UnaryOperation* expr);
219583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  void VisitVoid(UnaryOperation* expr);
219683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  void VisitTypeof(UnaryOperation* expr);
219783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  void VisitNot(UnaryOperation* expr);
219883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
219983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  void VisitComma(BinaryOperation* expr);
2200d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com  void VisitLogicalExpression(BinaryOperation* expr);
2201d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com  void VisitArithmeticExpression(BinaryOperation* expr);
220283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
22032c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org  bool PreProcessOsrEntry(IterationStatement* statement);
2204ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org  void VisitLoopBody(IterationStatement* stmt,
22051e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org                     HBasicBlock* loop_entry);
22065d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org
22078f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org  // Create a back edge in the flow graph.  body_exit is the predecessor
22088f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org  // block and loop_entry is the successor block.  loop_successor is the
22098f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org  // block where control flow exits the loop normally (e.g., via failure of
22108f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org  // the condition) and break_block is the block where control flow breaks
22118f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org  // from the loop.  All blocks except loop_entry can be NULL.  The return
22128f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org  // value is the new successor block which is the join of loop_successor
22138f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org  // and break_block, or NULL.
22148f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org  HBasicBlock* CreateLoop(IterationStatement* statement,
22158f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org                          HBasicBlock* loop_entry,
22168f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org                          HBasicBlock* body_exit,
22178f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org                          HBasicBlock* loop_successor,
22188f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org                          HBasicBlock* break_block);
22198f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org
2220c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org  // Build a loop entry
2221c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org  HBasicBlock* BuildLoopEntry();
2222c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org
2223c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org  // Builds a loop entry respectful of OSR requirements
2224c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org  HBasicBlock* BuildLoopEntry(IterationStatement* statement);
2225c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org
22265d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org  HBasicBlock* JoinContinue(IterationStatement* statement,
22275d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org                            HBasicBlock* exit_block,
22285d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org                            HBasicBlock* continue_block);
22295d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org
2230a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  HValue* Top() const { return environment()->Top(); }
2231a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void Drop(int n) { environment()->Drop(n); }
2232a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void Bind(Variable* var, HValue* value) { environment()->Bind(var, value); }
2233d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  bool IsEligibleForEnvironmentLivenessAnalysis(Variable* var,
2234d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org                                                int index,
2235d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org                                                HValue* value,
2236d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org                                                HEnvironment* env) {
2237d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org    if (!FLAG_analyze_environment_liveness) return false;
2238d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org    // |this| and |arguments| are always live; zapping parameters isn't
2239d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org    // safe because function.arguments can inspect them at any time.
2240d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org    return !var->is_this() &&
2241d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org           !var->is_arguments() &&
2242d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org           !value->IsArgumentsObject() &&
2243d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org           env->is_local_index(index);
2244d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  }
2245d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  void BindIfLive(Variable* var, HValue* value) {
2246d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org    HEnvironment* env = environment();
2247d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org    int index = env->IndexFor(var);
2248d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org    env->Bind(index, value);
2249d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org    if (IsEligibleForEnvironmentLivenessAnalysis(var, index, value, env)) {
2250d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org      HEnvironmentMarker* bind =
2251db783297aea0c1b0faf438598202d2abe10da70ebmeurer@chromium.org          Add<HEnvironmentMarker>(HEnvironmentMarker::BIND, index);
2252db783297aea0c1b0faf438598202d2abe10da70ebmeurer@chromium.org      USE(bind);
2253d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org#ifdef DEBUG
2254d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org      bind->set_closure(env->closure());
2255d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org#endif
2256d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org    }
2257d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  }
2258db783297aea0c1b0faf438598202d2abe10da70ebmeurer@chromium.org
2259d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  HValue* LookupAndMakeLive(Variable* var) {
2260d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org    HEnvironment* env = environment();
2261d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org    int index = env->IndexFor(var);
2262d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org    HValue* value = env->Lookup(index);
2263d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org    if (IsEligibleForEnvironmentLivenessAnalysis(var, index, value, env)) {
2264d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org      HEnvironmentMarker* lookup =
2265db783297aea0c1b0faf438598202d2abe10da70ebmeurer@chromium.org          Add<HEnvironmentMarker>(HEnvironmentMarker::LOOKUP, index);
2266db783297aea0c1b0faf438598202d2abe10da70ebmeurer@chromium.org      USE(lookup);
2267d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org#ifdef DEBUG
2268d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org      lookup->set_closure(env->closure());
2269d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org#endif
2270d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org    }
2271d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org    return value;
2272d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  }
2273a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
22748e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  // The value of the arguments object is allowed in some but not most value
22758e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  // contexts.  (It's allowed in all effect contexts and disallowed in all
22768e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  // test contexts.)
22778e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  void VisitForValue(Expression* expr,
22788e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org                     ArgumentsAllowedFlag flag = ARGUMENTS_NOT_ALLOWED);
2279c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  void VisitForTypeOf(Expression* expr);
2280a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void VisitForEffect(Expression* expr);
2281a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void VisitForControl(Expression* expr,
2282a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org                       HBasicBlock* true_block,
22835f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org                       HBasicBlock* false_block);
22845f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org
22853a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  // Visit a list of expressions from left to right, each in a value context.
22863a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  void VisitExpressions(ZoneList<Expression*>* exprs);
22873a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org
22885f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  // Remove the arguments from the bailout environment and emit instructions
22895f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  // to push them as outgoing parameters.
2290967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org  template <class Instruction> HInstruction* PreProcessCall(Instruction* call);
229126ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org  void PushArgumentsFromEnvironment(int count);
2292a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2293f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  void SetUpScope(Scope* scope);
2294ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  virtual void VisitStatements(ZoneList<Statement*>* statements) OVERRIDE;
2295a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2296ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org#define DECLARE_VISIT(type) virtual void Visit##type(type* node) OVERRIDE;
2297a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  AST_NODE_LIST(DECLARE_VISIT)
2298a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#undef DECLARE_VISIT
2299a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2300d3df75b4472c9d5d4d2615aaea74d2adce4160f8machenbach@chromium.org  Type* ToType(Handle<Map> map);
23010a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org
230271f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org private:
2303a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Helpers for flow graph construction.
2304c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  enum GlobalPropertyAccess {
2305c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org    kUseCell,
2306c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org    kUseGeneric
2307c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  };
23087dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org  GlobalPropertyAccess LookupGlobalProperty(Variable* var, LookupIterator* it,
2309f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org                                            PropertyAccessType access_type);
2310a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
231128faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org  void EnsureArgumentsArePushedForAccess();
2312a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  bool TryArgumentsAccess(Property* expr);
23134acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org
23143ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org  // Try to optimize fun.apply(receiver, arguments) pattern.
23153ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org  bool TryCallApply(Call* expr);
23164acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org
23177e6132b924829c353864933f29124419916db550machenbach@chromium.org  bool TryHandleArrayCall(Call* expr, HValue* function);
23187e6132b924829c353864933f29124419916db550machenbach@chromium.org  bool TryHandleArrayCallNew(CallNew* expr, HValue* function);
23197e6132b924829c353864933f29124419916db550machenbach@chromium.org  void BuildArrayCall(Expression* expr, int arguments_count, HValue* function,
23207e6132b924829c353864933f29124419916db550machenbach@chromium.org                      Handle<AllocationSite> cell);
23217e6132b924829c353864933f29124419916db550machenbach@chromium.org
2322196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  enum ArrayIndexOfMode { kFirstIndexOf, kLastIndexOf };
2323196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  HValue* BuildArrayIndexOf(HValue* receiver,
2324196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org                            HValue* search_element,
2325196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org                            ElementsKind kind,
2326196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org                            ArrayIndexOfMode mode);
2327196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org
2328e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org  HValue* ImplicitReceiverFor(HValue* function,
2329e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org                              Handle<JSFunction> target);
2330e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org
2331212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org  int InliningAstSize(Handle<JSFunction> target);
2332e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org  bool TryInline(Handle<JSFunction> target,
2333304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org                 int arguments_count,
2334471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org                 HValue* implicit_return_value,
2335471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org                 BailoutId ast_id,
2336471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org                 BailoutId return_id,
2337f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org                 InliningKind inlining_kind,
2338f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org                 HSourcePosition position);
2339967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org
2340a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org  bool TryInlineCall(Call* expr);
2341471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org  bool TryInlineConstruct(CallNew* expr, HValue* implicit_return_value);
23423d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org  bool TryInlineGetter(Handle<JSFunction> getter,
23438297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org                       Handle<Map> receiver_map,
23443d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org                       BailoutId ast_id,
23453d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org                       BailoutId return_id);
2346471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org  bool TryInlineSetter(Handle<JSFunction> setter,
234725530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org                       Handle<Map> receiver_map,
2348b0deb658b04208a80c51265c6499f9eb564f1db3danno@chromium.org                       BailoutId id,
2349b0deb658b04208a80c51265c6499f9eb564f1db3danno@chromium.org                       BailoutId assignment_id,
2350471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org                       HValue* implicit_return_value);
23513ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org  bool TryInlineApply(Handle<JSFunction> function,
23523ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org                      Call* expr,
23533ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org                      int arguments_count);
235478d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  bool TryInlineBuiltinMethodCall(Call* expr,
23553ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org                                  HValue* receiver,
23563ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org                                  Handle<Map> receiver_map);
2357a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org  bool TryInlineBuiltinFunctionCall(Call* expr);
23588297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org  enum ApiCallType {
23598297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org    kCallApiFunction,
23608297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org    kCallApiMethod,
236125530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org    kCallApiGetter,
236225530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org    kCallApiSetter
23638297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org  };
2364a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org  bool TryInlineApiMethodCall(Call* expr,
2365a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org                              HValue* receiver,
23668297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org                              SmallMapList* receiver_types);
2367a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org  bool TryInlineApiFunctionCall(Call* expr, HValue* receiver);
23688297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org  bool TryInlineApiGetter(Handle<JSFunction> function,
23698297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org                          Handle<Map> receiver_map,
23708297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org                          BailoutId ast_id);
237125530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org  bool TryInlineApiSetter(Handle<JSFunction> function,
237225530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org                          Handle<Map> receiver_map,
237325530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org                          BailoutId ast_id);
23748297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org  bool TryInlineApiCall(Handle<JSFunction> function,
23758297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org                         HValue* receiver,
23768297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org                         SmallMapList* receiver_maps,
23778297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org                         int argc,
23788297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org                         BailoutId ast_id,
23798297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org                         ApiCallType call_type);
23808f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org
23818f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org  // If --trace-inlining, print a line of the inlining trace.  Inlining
23828f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org  // succeeded if the reason string is NULL and failed if there is a
23838f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org  // non-NULL reason string.
2384ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org  void TraceInline(Handle<JSFunction> target,
2385ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org                   Handle<JSFunction> caller,
2386ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org                   const char* failure_reason);
2387a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
23885f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  void HandleGlobalVariableAssignment(Variable* var,
2389a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org                                      HValue* value,
2390471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org                                      BailoutId ast_id);
23915f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org
2392a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void HandlePropertyAssignment(Assignment* expr);
2393a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void HandleCompoundAssignment(Assignment* expr);
23948297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org  void HandlePolymorphicNamedFieldAccess(PropertyAccessType access_type,
23959d1a7a8cdb664730cf5703185e85a4716748c564machenbach@chromium.org                                         Expression* expr,
23968297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org                                         BailoutId ast_id,
23978297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org                                         BailoutId return_id,
23988297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org                                         HValue* object,
23998297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org                                         HValue* value,
24008297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org                                         SmallMapList* types,
24018297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org                                         Handle<String> name);
2402528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org
2403895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org  HValue* BuildAllocateExternalElements(
2404895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org      ExternalArrayType array_type,
2405895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org      bool is_zero_byte_offset,
2406895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org      HValue* buffer, HValue* byte_offset, HValue* length);
2407895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org  HValue* BuildAllocateFixedTypedArray(
2408895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org      ExternalArrayType array_type, size_t element_size,
2409895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org      ElementsKind fixed_elements_kind,
2410895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org      HValue* byte_length, HValue* length);
2411895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org
24127e6132b924829c353864933f29124419916db550machenbach@chromium.org  Handle<JSFunction> array_function() {
24137e6132b924829c353864933f29124419916db550machenbach@chromium.org    return handle(isolate()->native_context()->array_function());
24147e6132b924829c353864933f29124419916db550machenbach@chromium.org  }
24157e6132b924829c353864933f29124419916db550machenbach@chromium.org
24167e6132b924829c353864933f29124419916db550machenbach@chromium.org  bool IsCallArrayInlineable(int argument_count, Handle<AllocationSite> site);
24177e6132b924829c353864933f29124419916db550machenbach@chromium.org  void BuildInlinedCallArray(Expression* expression, int argument_count,
24187e6132b924829c353864933f29124419916db550machenbach@chromium.org                             Handle<AllocationSite> site);
2419b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org
2420528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  class PropertyAccessInfo {
2421528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org   public:
242257a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org    PropertyAccessInfo(HOptimizedGraphBuilder* builder,
24230a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org                       PropertyAccessType access_type,
24240a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org                       Type* type,
242557a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org                       Handle<String> name)
242657a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org        : lookup_(builder->isolate()),
242757a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org          builder_(builder),
24280a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org          access_type_(access_type),
242957a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org          type_(type),
2430528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org          name_(name),
24315924917d324a643d00a8aefee030bd4acea0de0bmachenbach@chromium.org          field_type_(HType::Tagged()),
2432528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org          access_(HObjectAccess::ForMap()) { }
2433528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org
2434528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    // Checkes whether this PropertyAccessInfo can be handled as a monomorphic
2435528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    // load named. It additionally fills in the fields necessary to generate the
2436528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    // lookup code.
24370a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org    bool CanAccessMonomorphic();
2438528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org
2439528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    // Checks whether all types behave uniform when loading name. If all maps
2440528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    // behave the same, a single monomorphic load instruction can be emitted,
2441528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    // guarded by a single map-checks instruction that whether the receiver is
2442528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    // an instance of any of the types.
2443528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    // This method skips the first type in types, assuming that this
2444528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    // PropertyAccessInfo is built for types->first().
24450a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org    bool CanAccessAsMonomorphic(SmallMapList* types);
2446528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org
2447474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org    Handle<Map> map();
24480a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org    Type* type() const { return type_; }
244957a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org    Handle<String> name() const { return name_; }
245057a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org
24518e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org    bool IsJSObjectFieldAccessor() {
24528e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org      int offset;  // unused
24530a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org      return Accessors::IsJSObjectFieldAccessor<Type>(type_, name_, &offset);
2454528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    }
2455528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org
24568e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org    bool GetJSObjectFieldAccess(HObjectAccess* access) {
245757a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org      int offset;
24580a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org      if (Accessors::IsJSObjectFieldAccessor<Type>(type_, name_, &offset)) {
24590a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org        if (type_->Is(Type::String())) {
2460e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org          DCHECK(String::Equals(isolate()->factory()->length_string(), name_));
246157a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org          *access = HObjectAccess::ForStringLength();
246225530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org        } else if (type_->Is(Type::Array())) {
2463e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org          DCHECK(String::Equals(isolate()->factory()->length_string(), name_));
246425530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org          *access = HObjectAccess::ForArrayLength(map()->elements_kind());
246557a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org        } else {
24660a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org          *access = HObjectAccess::ForMapAndOffset(map(), offset);
24678e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org        }
246857a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org        return true;
24698e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org      }
247057a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org      return false;
2471528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    }
2472528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org
2473528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    bool has_holder() { return !holder_.is_null(); }
24748297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org    bool IsLoad() const { return access_type_ == LOAD; }
2475528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org
2476528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    Handle<JSObject> holder() { return holder_; }
2477528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    Handle<JSFunction> accessor() { return accessor_; }
2478528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    Handle<Object> constant() { return constant_; }
2479bfd1d202fb7cd6d54d956414bad9f75a995d0f65machenbach@chromium.org    Handle<Map> transition() { return handle(lookup_.GetTransitionTarget()); }
24809fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    SmallMapList* field_maps() { return &field_maps_; }
24815924917d324a643d00a8aefee030bd4acea0de0bmachenbach@chromium.org    HType field_type() const { return field_type_; }
2482528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    HObjectAccess access() { return access_; }
2483528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org
2484f1a5a1dc668380a183184ee7629703846eefcfaemachenbach@chromium.org    bool IsFound() const { return lookup_.IsFound(); }
2485f1a5a1dc668380a183184ee7629703846eefcfaemachenbach@chromium.org    bool IsProperty() const { return lookup_.IsProperty(); }
2486f1a5a1dc668380a183184ee7629703846eefcfaemachenbach@chromium.org    bool IsField() const { return lookup_.IsField(); }
2487f1a5a1dc668380a183184ee7629703846eefcfaemachenbach@chromium.org    bool IsConstant() const { return lookup_.IsConstant(); }
2488f1a5a1dc668380a183184ee7629703846eefcfaemachenbach@chromium.org    bool IsAccessor() const { return lookup_.IsPropertyCallbacks(); }
2489f1a5a1dc668380a183184ee7629703846eefcfaemachenbach@chromium.org    bool IsTransition() const { return lookup_.IsTransition(); }
2490f1a5a1dc668380a183184ee7629703846eefcfaemachenbach@chromium.org
2491f1a5a1dc668380a183184ee7629703846eefcfaemachenbach@chromium.org    bool IsConfigurable() const { return lookup_.IsConfigurable(); }
2492f1a5a1dc668380a183184ee7629703846eefcfaemachenbach@chromium.org    bool IsReadOnly() const { return lookup_.IsReadOnly(); }
2493f1a5a1dc668380a183184ee7629703846eefcfaemachenbach@chromium.org
2494528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org   private:
2495f1a5a1dc668380a183184ee7629703846eefcfaemachenbach@chromium.org    Handle<Object> GetAccessorsFromMap(Handle<Map> map) const {
2496f1a5a1dc668380a183184ee7629703846eefcfaemachenbach@chromium.org      return handle(lookup_.GetValueFromMap(*map), isolate());
2497f1a5a1dc668380a183184ee7629703846eefcfaemachenbach@chromium.org    }
2498f1a5a1dc668380a183184ee7629703846eefcfaemachenbach@chromium.org    Handle<Object> GetConstantFromMap(Handle<Map> map) const {
2499f1a5a1dc668380a183184ee7629703846eefcfaemachenbach@chromium.org      return handle(lookup_.GetConstantFromMap(*map), isolate());
2500f1a5a1dc668380a183184ee7629703846eefcfaemachenbach@chromium.org    }
2501f1a5a1dc668380a183184ee7629703846eefcfaemachenbach@chromium.org    Handle<HeapType> GetFieldTypeFromMap(Handle<Map> map) const {
2502f1a5a1dc668380a183184ee7629703846eefcfaemachenbach@chromium.org      return handle(lookup_.GetFieldTypeFromMap(*map), isolate());
2503f1a5a1dc668380a183184ee7629703846eefcfaemachenbach@chromium.org    }
2504f1a5a1dc668380a183184ee7629703846eefcfaemachenbach@chromium.org    Handle<Map> GetFieldOwnerFromMap(Handle<Map> map) const {
2505f1a5a1dc668380a183184ee7629703846eefcfaemachenbach@chromium.org      return handle(lookup_.GetFieldOwnerFromMap(*map));
2506f1a5a1dc668380a183184ee7629703846eefcfaemachenbach@chromium.org    }
2507f1a5a1dc668380a183184ee7629703846eefcfaemachenbach@chromium.org    int GetLocalFieldIndexFromMap(Handle<Map> map) const {
2508f1a5a1dc668380a183184ee7629703846eefcfaemachenbach@chromium.org      return lookup_.GetLocalFieldIndexFromMap(*map);
2509f1a5a1dc668380a183184ee7629703846eefcfaemachenbach@chromium.org    }
2510f1a5a1dc668380a183184ee7629703846eefcfaemachenbach@chromium.org    Representation representation() const { return lookup_.representation(); }
2511f1a5a1dc668380a183184ee7629703846eefcfaemachenbach@chromium.org
25120a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org    Type* ToType(Handle<Map> map) { return builder_->ToType(map); }
25139fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    Zone* zone() { return builder_->zone(); }
2514f1a5a1dc668380a183184ee7629703846eefcfaemachenbach@chromium.org    Isolate* isolate() const { return lookup_.isolate(); }
2515e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org    CompilationInfo* top_info() { return builder_->top_info(); }
251657a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org    CompilationInfo* current_info() { return builder_->current_info(); }
25178e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org
2518528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    bool LoadResult(Handle<Map> map);
25199fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    void LoadFieldMaps(Handle<Map> map);
2520528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    bool LookupDescriptor();
2521528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    bool LookupInPrototypes();
25220a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org    bool IsCompatible(PropertyAccessInfo* other);
2523528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org
2524528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    void GeneralizeRepresentation(Representation r) {
2525528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org      access_ = access_.WithRepresentation(
2526528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org          access_.representation().generalize(r));
2527528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    }
2528528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org
2529528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    LookupResult lookup_;
253057a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org    HOptimizedGraphBuilder* builder_;
25310a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org    PropertyAccessType access_type_;
25320a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org    Type* type_;
2533528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    Handle<String> name_;
2534528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    Handle<JSObject> holder_;
2535528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    Handle<JSFunction> accessor_;
25368297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org    Handle<JSObject> api_holder_;
2537528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    Handle<Object> constant_;
25389fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    SmallMapList field_maps_;
25395924917d324a643d00a8aefee030bd4acea0de0bmachenbach@chromium.org    HType field_type_;
2540528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    HObjectAccess access_;
2541528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  };
2542528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org
25438297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org  HInstruction* BuildMonomorphicAccess(PropertyAccessInfo* info,
25448297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org                                       HValue* object,
25458297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org                                       HValue* checked_object,
25468297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org                                       HValue* value,
25478297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org                                       BailoutId ast_id,
25488297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org                                       BailoutId return_id,
25498297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org                                       bool can_inline_accessor = true);
25508297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org
25518297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org  HInstruction* BuildNamedAccess(PropertyAccessType access,
25528297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org                                 BailoutId ast_id,
25538297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org                                 BailoutId reutrn_id,
25548297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org                                 Expression* expr,
25558297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org                                 HValue* object,
25568297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org                                 Handle<String> name,
25578297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org                                 HValue* value,
25588297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org                                 bool is_uninitialized = false);
2559528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org
2560a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void HandlePolymorphicCallNamed(Call* expr,
2561a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org                                  HValue* receiver,
2562ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org                                  SmallMapList* types,
2563a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org                                  Handle<String> name);
2564c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void HandleLiteralCompareTypeof(CompareOperation* expr,
256596a3c512c0c7fd9e0e1d6bb0a965a3fd051705eajkummerow@chromium.org                                  Expression* sub_expr,
256604921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org                                  Handle<String> check);
2567c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void HandleLiteralCompareNil(CompareOperation* expr,
256896a3c512c0c7fd9e0e1d6bb0a965a3fd051705eajkummerow@chromium.org                               Expression* sub_expr,
2569c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                               NilValue nil);
257025530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org
257125530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org  enum PushBeforeSimulateBehavior {
257225530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org    PUSH_BEFORE_SIMULATE,
257325530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org    NO_PUSH_BEFORE_SIMULATE
257425530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org  };
2575f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org
2576f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  HControlInstruction* BuildCompareInstruction(
2577f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org      Token::Value op,
2578f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org      HValue* left,
2579f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org      HValue* right,
2580f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org      Type* left_type,
2581f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org      Type* right_type,
2582f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org      Type* combined_type,
2583f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org      HSourcePosition left_position,
2584f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org      HSourcePosition right_position,
2585f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org      PushBeforeSimulateBehavior push_sim_result,
2586f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org      BailoutId bailout_id);
2587f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org
2588f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  HInstruction* BuildStringCharCodeAt(HValue* string,
2589f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org                                      HValue* index);
2590f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org
259125530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org  HValue* BuildBinaryOperation(
259225530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org      BinaryOperation* expr,
259325530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org      HValue* left,
259425530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org      HValue* right,
259525530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org      PushBeforeSimulateBehavior push_sim_result);
2596c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org  HInstruction* BuildIncrement(bool returns_original_input,
25978e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org                               CountOperation* expr);
2598f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  HInstruction* BuildKeyedGeneric(PropertyAccessType access_type,
25999d1a7a8cdb664730cf5703185e85a4716748c564machenbach@chromium.org                                  Expression* expr,
2600f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org                                  HValue* object,
2601f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org                                  HValue* key,
2602f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org                                  HValue* value);
26037b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org
2604c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org  HInstruction* TryBuildConsolidatedElementLoad(HValue* object,
2605c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org                                                HValue* key,
2606c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org                                                HValue* val,
2607c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org                                                SmallMapList* maps);
2608c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org
26091e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org  LoadKeyedHoleMode BuildKeyedHoleMode(Handle<Map> map);
26101e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org
26117b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  HInstruction* BuildMonomorphicElementAccess(HValue* object,
26127b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org                                              HValue* key,
26137b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org                                              HValue* val,
2614830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org                                              HValue* dependency,
2615394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                                              Handle<Map> map,
2616f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org                                              PropertyAccessType access_type,
26177bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org                                              KeyedAccessStoreMode store_mode);
2618c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org
26199d1a7a8cdb664730cf5703185e85a4716748c564machenbach@chromium.org  HValue* HandlePolymorphicElementAccess(Expression* expr,
26209d1a7a8cdb664730cf5703185e85a4716748c564machenbach@chromium.org                                         HValue* object,
26217b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org                                         HValue* key,
26227b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org                                         HValue* val,
26234a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org                                         SmallMapList* maps,
2624f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org                                         PropertyAccessType access_type,
26257bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org                                         KeyedAccessStoreMode store_mode,
26267b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org                                         bool* has_side_effects);
26277b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org
2628a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org  HValue* HandleKeyedElementAccess(HValue* obj, HValue* key, HValue* val,
262906b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org                                   Expression* expr, BailoutId ast_id,
263006b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org                                   BailoutId return_id,
2631f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org                                   PropertyAccessType access_type,
26327b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org                                   bool* has_side_effects);
263344bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org
2634f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  HInstruction* BuildNamedGeneric(PropertyAccessType access,
26359d1a7a8cdb664730cf5703185e85a4716748c564machenbach@chromium.org                                  Expression* expr,
2636f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org                                  HValue* object,
2637f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org                                  Handle<String> name,
2638f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org                                  HValue* value,
2639f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org                                  bool is_uninitialized = false);
2640ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org
2641003a9255d4e3b18b610295c0de79b1dbedc021c7verwaest@chromium.org  HCheckMaps* AddCheckMap(HValue* object, Handle<Map> map);
2642f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org
26433d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org  void BuildLoad(Property* property,
26443d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org                 BailoutId ast_id);
26453d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org  void PushLoad(Property* property,
26463d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org                HValue* object,
264771f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org                HValue* key);
26483d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org
2649639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org  void BuildStoreForEffect(Expression* expression,
2650639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org                           Property* prop,
2651639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org                           BailoutId ast_id,
2652639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org                           BailoutId return_id,
2653639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org                           HValue* object,
2654639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org                           HValue* key,
2655639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org                           HValue* value);
2656639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org
2657639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org  void BuildStore(Expression* expression,
2658639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org                  Property* prop,
2659639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org                  BailoutId ast_id,
2660639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org                  BailoutId return_id,
2661639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org                  bool is_uninitialized = false);
2662b0deb658b04208a80c51265c6499f9eb564f1db3danno@chromium.org
2663f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  HInstruction* BuildLoadNamedField(PropertyAccessInfo* info,
2664f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org                                    HValue* checked_object);
26650a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org  HInstruction* BuildStoreNamedField(PropertyAccessInfo* info,
26660a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org                                     HValue* checked_object,
26670a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org                                     HValue* value);
2668a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
266983aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org  HValue* BuildContextChainWalk(Variable* var);
267083aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org
26715a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  HInstruction* BuildThisFunction();
26725a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org
2673b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org  HInstruction* BuildFastLiteral(Handle<JSObject> boilerplate_object,
267437be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org                                 AllocationSiteUsageContext* site_context);
2675e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
2676dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org  void BuildEmitObjectHeader(Handle<JSObject> boilerplate_object,
2677dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org                             HInstruction* object);
2678dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org
2679dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org  void BuildInitElementsInObjectHeader(Handle<JSObject> boilerplate_object,
2680dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org                                       HInstruction* object,
2681dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org                                       HInstruction* object_elements);
2682e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
2683c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org  void BuildEmitInObjectProperties(Handle<JSObject> boilerplate_object,
2684b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org                                   HInstruction* object,
2685c86e8c29eea534916f0d6a2a285b65a86d1b3b67machenbach@chromium.org                                   AllocationSiteUsageContext* site_context,
2686c86e8c29eea534916f0d6a2a285b65a86d1b3b67machenbach@chromium.org                                   PretenureFlag pretenure_flag);
2687dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org
2688dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org  void BuildEmitElements(Handle<JSObject> boilerplate_object,
2689dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org                         Handle<FixedArrayBase> elements,
2690b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org                         HValue* object_elements,
269137be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org                         AllocationSiteUsageContext* site_context);
2692c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org
2693c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org  void BuildEmitFixedDoubleArray(Handle<FixedArrayBase> elements,
2694c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org                                 ElementsKind kind,
2695c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org                                 HValue* object_elements);
2696c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org
2697c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org  void BuildEmitFixedArray(Handle<FixedArrayBase> elements,
2698c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org                           ElementsKind kind,
2699b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org                           HValue* object_elements,
270037be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org                           AllocationSiteUsageContext* site_context);
2701c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org
2702e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  void AddCheckPrototypeMaps(Handle<JSObject> holder,
2703e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org                             Handle<Map> receiver_map);
2704e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org
270526ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org  HInstruction* NewPlainFunctionCall(HValue* fun,
270626ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org                                     int argument_count,
270726ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org                                     bool pass_argument_count);
270826ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org
270926ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org  HInstruction* NewArgumentAdaptorCall(HValue* fun, HValue* context,
271026ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org                                       int argument_count,
271126ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org                                       HValue* expected_param_count);
271226ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org
271326ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org  HInstruction* BuildCallConstantFunction(Handle<JSFunction> target,
271426ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org                                          int argument_count);
271526ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org
27168f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org  // The translation state of the currently-being-translated function.
27178f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org  FunctionState* function_state_;
27188f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org
27198f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org  // The base of the function state stack.
27208f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org  FunctionState initial_function_state_;
27218f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org
2722a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Expression context of the currently visited subexpression. NULL when
2723a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // visiting statements.
2724a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  AstContext* ast_context_;
2725a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
27268f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org  // A stack of breakable statements entered.
27278f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org  BreakAndContinueScope* break_scope_;
2728a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2729a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  int inlined_count_;
2730ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com  ZoneList<Handle<Object> > globals_;
2731a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2732ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org  bool inline_bailout_;
2733ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org
2734c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org  HOsrBuilder* osr_;
2735c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org
27368f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org  friend class FunctionState;  // Pushes and pops the state stack.
2737a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  friend class AstContext;  // Pushes and pops the AST context stack.
2738a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  friend class KeyedLoadFastElementStub;
2739c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org  friend class HOsrBuilder;
2740a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2741a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  DISALLOW_COPY_AND_ASSIGN(HOptimizedGraphBuilder);
2742a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org};
2743a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2744a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
27457028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.orgZone* AstContext::zone() const { return owner_->zone(); }
274674f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org
274774f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org
2748ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.orgclass HStatistics FINAL: public Malloced {
2749a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org public:
2750750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  HStatistics()
2751dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org      : times_(5),
2752750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org        names_(5),
2753750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org        sizes_(5),
2754750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org        total_size_(0),
2755750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org        source_size_(0) { }
2756750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org
2757b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org  void Initialize(CompilationInfo* info);
27587d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  void Print(const char* stats_name);
27595de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org  void SaveTiming(const char* name, base::TimeDelta time, unsigned size);
2760a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
27615de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org  void IncrementFullCodeGen(base::TimeDelta full_code_gen) {
27621510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    full_code_gen_ += full_code_gen;
27631510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  }
27641510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
27657d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  void IncrementCreateGraph(base::TimeDelta delta) { create_graph_ += delta; }
27667d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
27677d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  void IncrementOptimizeGraph(base::TimeDelta delta) {
27687d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    optimize_graph_ += delta;
27697d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  }
27707d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
27717d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  void IncrementGenerateCode(base::TimeDelta delta) { generate_code_ += delta; }
27727d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
27735de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org  void IncrementSubtotals(base::TimeDelta create_graph,
27745de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org                          base::TimeDelta optimize_graph,
27755de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org                          base::TimeDelta generate_code) {
27767d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    IncrementCreateGraph(create_graph);
27777d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    IncrementOptimizeGraph(optimize_graph);
27787d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    IncrementGenerateCode(generate_code);
27798e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  }
27808e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org
2781a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org private:
27825de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org  List<base::TimeDelta> times_;
2783a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  List<const char*> names_;
2784c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org  List<unsigned> sizes_;
27855de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org  base::TimeDelta create_graph_;
27865de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org  base::TimeDelta optimize_graph_;
27875de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org  base::TimeDelta generate_code_;
2788c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org  unsigned total_size_;
27895de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org  base::TimeDelta full_code_gen_;
2790b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org  double source_size_;
2791a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org};
2792a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2793a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
27941510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgclass HPhase : public CompilationPhase {
2795a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org public:
27961510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  HPhase(const char* name, HGraph* graph)
27971510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org      : CompilationPhase(name, graph->info()),
27981510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org        graph_(graph) { }
2799750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  ~HPhase();
2800a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
28011510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org protected:
28021510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  HGraph* graph() const { return graph_; }
2803a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
28041510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org private:
2805a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  HGraph* graph_;
28061510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
28071510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  DISALLOW_COPY_AND_ASSIGN(HPhase);
2808a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org};
2809a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2810a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2811ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.orgclass HTracer FINAL : public Malloced {
2812a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org public:
2813750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  explicit HTracer(int isolate_id)
2814750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org      : trace_(&string_allocator_), indent_(0) {
2815fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org    if (FLAG_trace_hydrogen_file == NULL) {
281670ec1a2160dd946b9578d04d97d631a6d4ab4f8cbmeurer@chromium.org      SNPrintF(filename_,
281770ec1a2160dd946b9578d04d97d631a6d4ab4f8cbmeurer@chromium.org               "hydrogen-%d-%d.cfg",
28185de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org               base::OS::GetCurrentProcessId(),
281970ec1a2160dd946b9578d04d97d631a6d4ab4f8cbmeurer@chromium.org               isolate_id);
2820fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org    } else {
282170ec1a2160dd946b9578d04d97d631a6d4ab4f8cbmeurer@chromium.org      StrNCpy(filename_, FLAG_trace_hydrogen_file, filename_.length());
2822fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org    }
2823750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    WriteChars(filename_.start(), "", 0, false);
2824750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  }
2825750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org
2826a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  void TraceCompilation(CompilationInfo* info);
2827a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void TraceHydrogen(const char* name, HGraph* graph);
282828583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org  void TraceLithium(const char* name, LChunk* chunk);
2829a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void TraceLiveRanges(const char* name, LAllocator* allocator);
2830a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2831a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org private:
2832ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  class Tag FINAL BASE_EMBEDDED {
2833a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org   public:
2834a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    Tag(HTracer* tracer, const char* name) {
2835a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      name_ = name;
2836a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      tracer_ = tracer;
2837a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      tracer->PrintIndent();
2838a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      tracer->trace_.Add("begin_%s\n", name);
2839a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      tracer->indent_++;
2840a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    }
2841a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2842a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    ~Tag() {
2843a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      tracer_->indent_--;
2844a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      tracer_->PrintIndent();
2845a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      tracer_->trace_.Add("end_%s\n", name_);
2846e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      DCHECK(tracer_->indent_ >= 0);
2847a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      tracer_->FlushToFile();
2848a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    }
2849a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2850a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org   private:
2851a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    HTracer* tracer_;
2852a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    const char* name_;
2853a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  };
2854a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
28557028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  void TraceLiveRange(LiveRange* range, const char* type, Zone* zone);
285628583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org  void Trace(const char* name, HGraph* graph, LChunk* chunk);
2857a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void FlushToFile();
2858a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2859a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void PrintEmptyProperty(const char* name) {
2860a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    PrintIndent();
2861a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    trace_.Add("%s\n", name);
2862a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
2863a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2864a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void PrintStringProperty(const char* name, const char* value) {
2865a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    PrintIndent();
2866a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    trace_.Add("%s \"%s\"\n", name, value);
2867a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
2868a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2869a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void PrintLongProperty(const char* name, int64_t value) {
2870a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    PrintIndent();
2871a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    trace_.Add("%s %d000\n", name, static_cast<int>(value / 1000));
2872a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
2873a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2874a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void PrintBlockProperty(const char* name, int block_id) {
2875a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    PrintIndent();
2876a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    trace_.Add("%s \"B%d\"\n", name, block_id);
2877a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
2878a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2879a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void PrintIntProperty(const char* name, int value) {
2880a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    PrintIndent();
2881a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    trace_.Add("%s %d\n", name, value);
2882a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
2883a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2884a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void PrintIndent() {
2885a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    for (int i = 0; i < indent_; i++) {
2886a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      trace_.Add("  ");
2887a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    }
2888a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
2889a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2890750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  EmbeddedVector<char, 64> filename_;
2891a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  HeapStringAllocator string_allocator_;
2892a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  StringStream trace_;
2893a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  int indent_;
2894a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org};
2895a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2896a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2897ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.orgclass NoObservableSideEffectsScope FINAL {
2898ad75d6febf45d81dda1f4cd158c7eb97c0408a25danno@chromium.org public:
2899ad75d6febf45d81dda1f4cd158c7eb97c0408a25danno@chromium.org  explicit NoObservableSideEffectsScope(HGraphBuilder* builder) :
2900ad75d6febf45d81dda1f4cd158c7eb97c0408a25danno@chromium.org      builder_(builder) {
2901ad75d6febf45d81dda1f4cd158c7eb97c0408a25danno@chromium.org    builder_->graph()->IncrementInNoSideEffectsScope();
2902ad75d6febf45d81dda1f4cd158c7eb97c0408a25danno@chromium.org  }
2903ad75d6febf45d81dda1f4cd158c7eb97c0408a25danno@chromium.org  ~NoObservableSideEffectsScope() {
2904ad75d6febf45d81dda1f4cd158c7eb97c0408a25danno@chromium.org    builder_->graph()->DecrementInNoSideEffectsScope();
2905ad75d6febf45d81dda1f4cd158c7eb97c0408a25danno@chromium.org  }
2906ad75d6febf45d81dda1f4cd158c7eb97c0408a25danno@chromium.org
2907ad75d6febf45d81dda1f4cd158c7eb97c0408a25danno@chromium.org private:
2908ad75d6febf45d81dda1f4cd158c7eb97c0408a25danno@chromium.org  HGraphBuilder* builder_;
2909ad75d6febf45d81dda1f4cd158c7eb97c0408a25danno@chromium.org};
2910ad75d6febf45d81dda1f4cd158c7eb97c0408a25danno@chromium.org
2911ad75d6febf45d81dda1f4cd158c7eb97c0408a25danno@chromium.org
2912a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} }  // namespace v8::internal
2913a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2914a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#endif  // V8_HYDROGEN_H_
2915