13ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Copyright 2012 the V8 project authors. All rights reserved.
2b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// Redistribution and use in source and binary forms, with or without
3b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// modification, are permitted provided that the following conditions are
4b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// met:
5b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch//
6b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch//     * Redistributions of source code must retain the above copyright
7b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch//       notice, this list of conditions and the following disclaimer.
8b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch//     * Redistributions in binary form must reproduce the above
9b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch//       copyright notice, this list of conditions and the following
10b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch//       disclaimer in the documentation and/or other materials provided
11b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch//       with the distribution.
12b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch//     * Neither the name of Google Inc. nor the names of its
13b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch//       contributors may be used to endorse or promote products derived
14b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch//       from this software without specific prior written permission.
15b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch//
16b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
28b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#ifndef V8_HYDROGEN_H_
29b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#define V8_HYDROGEN_H_
30b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
31b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#include "v8.h"
32b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
33257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch#include "allocation.h"
34b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#include "ast.h"
35b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#include "compiler.h"
36b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#include "hydrogen-instructions.h"
37257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch#include "type-info.h"
38b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#include "zone.h"
39b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
40b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochnamespace v8 {
41b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochnamespace internal {
42b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
43b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// Forward declarations.
44257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochclass BitVector;
45b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochclass HEnvironment;
46b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochclass HGraph;
47b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochclass HLoopInformation;
48b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochclass HTracer;
49b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochclass LAllocator;
50b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochclass LChunk;
51b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochclass LiveRange;
52b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
53b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
54b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochclass HBasicBlock: public ZoneObject {
55b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch public:
56b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  explicit HBasicBlock(HGraph* graph);
57b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  virtual ~HBasicBlock() { }
58b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
59b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Simple accessors.
60b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  int block_id() const { return block_id_; }
61b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void set_block_id(int id) { block_id_ = id; }
62b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  HGraph* graph() const { return graph_; }
63b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  const ZoneList<HPhi*>* phis() const { return &phis_; }
64b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  HInstruction* first() const { return first_; }
65e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  HInstruction* last() const { return last_; }
66e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  void set_last(HInstruction* instr) { last_ = instr; }
67b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  HInstruction* GetLastInstruction();
68b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  HControlInstruction* end() const { return end_; }
69b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  HLoopInformation* loop_information() const { return loop_information_; }
70b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  const ZoneList<HBasicBlock*>* predecessors() const { return &predecessors_; }
71b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  bool HasPredecessor() const { return predecessors_.length() > 0; }
72b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  const ZoneList<HBasicBlock*>* dominated_blocks() const {
73b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    return &dominated_blocks_;
74b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
75b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  const ZoneList<int>* deleted_phis() const {
76b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    return &deleted_phis_;
77b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
78b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void RecordDeletedPhi(int merge_index) {
79b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    deleted_phis_.Add(merge_index);
80b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
81b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  HBasicBlock* dominator() const { return dominator_; }
82b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  HEnvironment* last_environment() const { return last_environment_; }
83b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  int argument_count() const { return argument_count_; }
84b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void set_argument_count(int count) { argument_count_ = count; }
85b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  int first_instruction_index() const { return first_instruction_index_; }
86b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void set_first_instruction_index(int index) {
87b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    first_instruction_index_ = index;
88b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
89b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  int last_instruction_index() const { return last_instruction_index_; }
90b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void set_last_instruction_index(int index) {
91b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    last_instruction_index_ = index;
92b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
93b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
94b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void AttachLoopInformation();
95b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void DetachLoopInformation();
96b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  bool IsLoopHeader() const { return loop_information() != NULL; }
97b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  bool IsStartBlock() const { return block_id() == 0; }
98b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void PostProcessLoopHeader(IterationStatement* stmt);
99b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
100b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  bool IsFinished() const { return end_ != NULL; }
101b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void AddPhi(HPhi* phi);
102b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void RemovePhi(HPhi* phi);
103b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void AddInstruction(HInstruction* instr);
104b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  bool Dominates(HBasicBlock* other) const;
105589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  int LoopNestingDepth() const;
106b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
107b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void SetInitialEnvironment(HEnvironment* env);
108b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void ClearEnvironment() { last_environment_ = NULL; }
109b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  bool HasEnvironment() const { return last_environment_ != NULL; }
110b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void UpdateEnvironment(HEnvironment* env) { last_environment_ = env; }
1111e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  HBasicBlock* parent_loop_header() const { return parent_loop_header_; }
112b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
113b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void set_parent_loop_header(HBasicBlock* block) {
1141e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    ASSERT(parent_loop_header_ == NULL);
1151e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    parent_loop_header_ = block;
116b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
117b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1181e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  bool HasParentLoopHeader() const { return parent_loop_header_ != NULL; }
119b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1203fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  void SetJoinId(int ast_id);
121b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
122b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void Finish(HControlInstruction* last);
123e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  void FinishExit(HControlInstruction* instruction);
1243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void Goto(HBasicBlock* block, bool drop_extra = false);
125b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
126b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  int PredecessorIndexOf(HBasicBlock* predecessor) const;
1273fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  void AddSimulate(int ast_id) { AddInstruction(CreateSimulate(ast_id)); }
128b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void AssignCommonDominator(HBasicBlock* other);
1293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void AssignLoopSuccessorDominators();
130b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
131257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  void FinishExitWithDeoptimization(HDeoptimize::UseEnvironment has_uses) {
132257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    FinishExit(CreateDeoptimize(has_uses));
13344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
13444f0eee88ff00398ff7f715fab053374d808c90dSteve Block
135b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Add the inlined function exit sequence, adding an HLeaveInlined
136b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // instruction and updating the bailout environment.
1373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void AddLeaveInlined(HValue* return_value,
1383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                       HBasicBlock* target,
1393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                       bool drop_extra = false);
140b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
141b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // If a target block is tagged as an inline function return, all
142b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // predecessors should contain the inlined exit sequence:
143b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  //
144b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // LeaveInlined
145b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Simulate (caller's environment)
146b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Goto (target block)
147b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  bool IsInlineReturnTarget() const { return is_inline_return_target_; }
148b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void MarkAsInlineReturnTarget() { is_inline_return_target_ = true; }
149b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1503fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  bool IsDeoptimizing() const { return is_deoptimizing_; }
1513fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  void MarkAsDeoptimizing() { is_deoptimizing_ = true; }
1523fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
1533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  bool IsLoopSuccessorDominator() const {
1543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    return dominates_loop_successors_;
1553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
1563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void MarkAsLoopSuccessorDominator() {
1573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    dominates_loop_successors_ = true;
1583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
1593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1608b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  inline Zone* zone();
1618b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
162b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#ifdef DEBUG
163b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void Verify();
164b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#endif
165b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
166b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch private:
167b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void RegisterPredecessor(HBasicBlock* pred);
168b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void AddDominatedBlock(HBasicBlock* block);
169b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1703fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  HSimulate* CreateSimulate(int ast_id);
171257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  HDeoptimize* CreateDeoptimize(HDeoptimize::UseEnvironment has_uses);
172b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
173b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  int block_id_;
174b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  HGraph* graph_;
175b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  ZoneList<HPhi*> phis_;
176b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  HInstruction* first_;
177e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  HInstruction* last_;
178b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  HControlInstruction* end_;
179b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  HLoopInformation* loop_information_;
180b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  ZoneList<HBasicBlock*> predecessors_;
181b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  HBasicBlock* dominator_;
182b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  ZoneList<HBasicBlock*> dominated_blocks_;
183b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  HEnvironment* last_environment_;
184b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Outgoing parameter count at block exit, set during lithium translation.
185b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  int argument_count_;
186b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Instruction indices into the lithium code stream.
187b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  int first_instruction_index_;
188b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  int last_instruction_index_;
189b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  ZoneList<int> deleted_phis_;
1901e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  HBasicBlock* parent_loop_header_;
191b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  bool is_inline_return_target_;
1923fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  bool is_deoptimizing_;
1933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  bool dominates_loop_successors_;
1943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch};
1953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochclass HPredecessorIterator BASE_EMBEDDED {
1983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch public:
1993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  explicit HPredecessorIterator(HBasicBlock* block)
2003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      : predecessor_list_(block->predecessors()), current_(0) { }
2013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
2023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  bool Done() { return current_ >= predecessor_list_->length(); }
2033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  HBasicBlock* Current() { return predecessor_list_->at(current_); }
2043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void Advance() { current_++; }
2053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
2063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch private:
2073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  const ZoneList<HBasicBlock*>* predecessor_list_;
2083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  int current_;
209b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch};
210b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
211b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
212b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochclass HLoopInformation: public ZoneObject {
213b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch public:
214b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  explicit HLoopInformation(HBasicBlock* loop_header)
2153fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      : back_edges_(4),
2163fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch        loop_header_(loop_header),
2173fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch        blocks_(8),
2183fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch        stack_check_(NULL) {
219b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    blocks_.Add(loop_header);
220b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
221b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  virtual ~HLoopInformation() {}
222b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
223b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  const ZoneList<HBasicBlock*>* back_edges() const { return &back_edges_; }
224b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  const ZoneList<HBasicBlock*>* blocks() const { return &blocks_; }
225b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  HBasicBlock* loop_header() const { return loop_header_; }
226b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  HBasicBlock* GetLastBackEdge() const;
227b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void RegisterBackEdge(HBasicBlock* block);
228b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2293fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  HStackCheck* stack_check() const { return stack_check_; }
2303fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  void set_stack_check(HStackCheck* stack_check) {
2313fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    stack_check_ = stack_check;
2323fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  }
2333fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
234b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch private:
235b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void AddBlock(HBasicBlock* block);
236b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
237b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  ZoneList<HBasicBlock*> back_edges_;
238b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  HBasicBlock* loop_header_;
239b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  ZoneList<HBasicBlock*> blocks_;
2403fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  HStackCheck* stack_check_;
241b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch};
242b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
243b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
24444f0eee88ff00398ff7f715fab053374d808c90dSteve Blockclass HGraph: public ZoneObject {
245b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch public:
246b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  explicit HGraph(CompilationInfo* info);
247b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2488b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  Isolate* isolate() { return isolate_; }
2498b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  Zone* zone() { return isolate_->zone(); }
2508b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
251b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  const ZoneList<HBasicBlock*>* blocks() const { return &blocks_; }
252b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  const ZoneList<HPhi*>* phi_list() const { return phi_list_; }
25344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  HBasicBlock* entry_block() const { return entry_block_; }
254b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  HEnvironment* start_environment() const { return start_environment_; }
255b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
256b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void InitializeInferredTypes();
257b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void InsertTypeConversions();
258b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void InsertRepresentationChanges();
2597d3e7fc4b65010eabe860313ee0c64f50843f6e3Ben Murdoch  void MarkDeoptimizeOnUndefined();
2601e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  void ComputeMinusZeroChecks();
261b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  bool ProcessArgumentsObject();
262b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void EliminateRedundantPhis();
26344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  void EliminateUnreachablePhis();
264b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void Canonicalize();
265b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void OrderBlocks();
266b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void AssignDominators();
2677d3e7fc4b65010eabe860313ee0c64f50843f6e3Ben Murdoch  void ReplaceCheckedValues();
26869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  void PropagateDeoptimizingMark();
269b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
270b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Returns false if there are phi-uses of the arguments-object
271b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // which are not supported by the optimizing compiler.
2723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  bool CheckArgumentsPhiUses();
2733fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
2743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Returns false if there are phi-uses of an uninitialized const
2753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // which are not supported by the optimizing compiler.
2763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  bool CheckConstPhiUses();
2773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
2783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void CollectPhis();
279b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
280e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  Handle<Code> Compile(CompilationInfo* info);
281b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
282b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void set_undefined_constant(HConstant* constant) {
283b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    undefined_constant_.set(constant);
284b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
285b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  HConstant* GetConstantUndefined() const { return undefined_constant_.get(); }
286b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  HConstant* GetConstant1();
287b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  HConstant* GetConstantMinus1();
288b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  HConstant* GetConstantTrue();
289b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  HConstant* GetConstantFalse();
2903fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  HConstant* GetConstantHole();
291b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
292b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  HBasicBlock* CreateBasicBlock();
293b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  HArgumentsObject* GetArgumentsObject() const {
294b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    return arguments_object_.get();
295b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
296b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
297b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void SetArgumentsObject(HArgumentsObject* object) {
298b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    arguments_object_.set(object);
299b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
300b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
301b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  int GetMaximumValueID() const { return values_.length(); }
302b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  int GetNextBlockID() { return next_block_id_++; }
303b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  int GetNextValueID(HValue* value) {
304b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    values_.Add(value);
305b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    return values_.length() - 1;
306b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
307b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  HValue* LookupValue(int id) const {
308b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    if (id >= 0 && id < values_.length()) return values_[id];
309b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    return NULL;
310b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
311b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
312b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#ifdef DEBUG
3133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void Verify(bool do_full_verify) const;
314b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#endif
315b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
3163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  bool has_osr_loop_entry() {
3173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    return osr_loop_entry_.is_set();
3183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
3193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  HBasicBlock* osr_loop_entry() {
3213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    return osr_loop_entry_.get();
3223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
3233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void set_osr_loop_entry(HBasicBlock* entry) {
3253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    osr_loop_entry_.set(entry);
3263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
3273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  ZoneList<HUnknownOSRValue*>* osr_values() {
3293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    return osr_values_.get();
3303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
3313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void set_osr_values(ZoneList<HUnknownOSRValue*>* values) {
3333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    osr_values_.set(values);
3343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
3353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
336b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch private:
337b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void Postorder(HBasicBlock* block,
338b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                 BitVector* visited,
339b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                 ZoneList<HBasicBlock*>* order,
340b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                 HBasicBlock* loop_header);
341b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void PostorderLoopBlocks(HLoopInformation* loop,
342b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                           BitVector* visited,
343b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                           ZoneList<HBasicBlock*>* order,
344b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                           HBasicBlock* loop_header);
345b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  HConstant* GetConstant(SetOncePointer<HConstant>* pointer,
346b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                         Object* value);
347b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
34869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  void MarkAsDeoptimizingRecursively(HBasicBlock* block);
349b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void InsertTypeConversions(HInstruction* instr);
350b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void PropagateMinusZeroChecks(HValue* value, BitVector* visited);
3517d3e7fc4b65010eabe860313ee0c64f50843f6e3Ben Murdoch  void RecursivelyMarkPhiDeoptimizeOnUndefined(HPhi* phi);
352b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void InsertRepresentationChangeForUse(HValue* value,
353257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                                        HValue* use_value,
354257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                                        int use_index,
355e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch                                        Representation to);
356257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  void InsertRepresentationChangesForValue(HValue* value);
357b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void InferTypes(ZoneList<HValue*>* worklist);
358b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void InitializeInferredTypes(int from_inclusive, int to_inclusive);
359b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void CheckForBackEdge(HBasicBlock* block, HBasicBlock* successor);
360b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
36144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Isolate* isolate_;
362b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  int next_block_id_;
36344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  HBasicBlock* entry_block_;
364b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  HEnvironment* start_environment_;
365b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  ZoneList<HBasicBlock*> blocks_;
366b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  ZoneList<HValue*> values_;
367b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  ZoneList<HPhi*>* phi_list_;
368b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  SetOncePointer<HConstant> undefined_constant_;
369b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  SetOncePointer<HConstant> constant_1_;
370b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  SetOncePointer<HConstant> constant_minus1_;
371b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  SetOncePointer<HConstant> constant_true_;
372b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  SetOncePointer<HConstant> constant_false_;
3733fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  SetOncePointer<HConstant> constant_hole_;
374b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  SetOncePointer<HArgumentsObject> arguments_object_;
375b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
3763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  SetOncePointer<HBasicBlock> osr_loop_entry_;
3773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  SetOncePointer<ZoneList<HUnknownOSRValue*> > osr_values_;
3783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
379b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  DISALLOW_COPY_AND_ASSIGN(HGraph);
380b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch};
381b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
382b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
3838b112d2025046f85ef7f6be087c6129c872ebad2Ben MurdochZone* HBasicBlock::zone() { return graph_->zone(); }
3848b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
3858b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
3863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Type of stack frame an environment might refer to.
3873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochenum FrameType { JS_FUNCTION, JS_CONSTRUCT, ARGUMENTS_ADAPTOR };
3883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
390b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochclass HEnvironment: public ZoneObject {
391b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch public:
392b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  HEnvironment(HEnvironment* outer,
393b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch               Scope* scope,
394b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch               Handle<JSFunction> closure);
395b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
3963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  HEnvironment* DiscardInlined(bool drop_extra) {
3973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    HEnvironment* outer = outer_;
3983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    while (outer->frame_type() != JS_FUNCTION) outer = outer->outer_;
3993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    if (drop_extra) outer->Drop(1);
4003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    return outer;
4013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
4023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
4033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  HEnvironment* arguments_environment() {
4043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    return outer()->frame_type() == ARGUMENTS_ADAPTOR ? outer() : this;
4053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
4063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
4079fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block  // Simple accessors.
4089fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block  Handle<JSFunction> closure() const { return closure_; }
4099fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block  const ZoneList<HValue*>* values() const { return &values_; }
4109fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block  const ZoneList<int>* assigned_variables() const {
4119fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block    return &assigned_variables_;
4129fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block  }
4133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  FrameType frame_type() const { return frame_type_; }
4149fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block  int parameter_count() const { return parameter_count_; }
415257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  int specials_count() const { return specials_count_; }
4169fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block  int local_count() const { return local_count_; }
4179fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block  HEnvironment* outer() const { return outer_; }
4189fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block  int pop_count() const { return pop_count_; }
4199fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block  int push_count() const { return push_count_; }
4209fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block
4219fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block  int ast_id() const { return ast_id_; }
4229fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block  void set_ast_id(int id) { ast_id_ = id; }
4239fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block
4249fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block  int length() const { return values_.length(); }
425257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  bool is_special_index(int i) const {
426257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    return i >= parameter_count() && i < parameter_count() + specials_count();
427257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
4289fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block
4293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  int first_expression_index() const {
4303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    return parameter_count() + specials_count() + local_count();
4313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
4323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
433b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void Bind(Variable* variable, HValue* value) {
434b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    Bind(IndexFor(variable), value);
435b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
436b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
4379fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block  void Bind(int index, HValue* value);
438b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
439257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  void BindContext(HValue* value) {
440257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    Bind(parameter_count(), value);
441257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
442257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
443b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  HValue* Lookup(Variable* variable) const {
444b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    return Lookup(IndexFor(variable));
445b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
4469fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block
447b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  HValue* Lookup(int index) const {
448b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    HValue* result = values_[index];
449b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    ASSERT(result != NULL);
450b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    return result;
451b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
452b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
453257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  HValue* LookupContext() const {
454257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    // Return first special.
455257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    return Lookup(parameter_count());
456257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
457257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
458b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void Push(HValue* value) {
459b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    ASSERT(value != NULL);
460b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    ++push_count_;
461b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    values_.Add(value);
462b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
463b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
464b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  HValue* Pop() {
4659fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block    ASSERT(!ExpressionStackIsEmpty());
466b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    if (push_count_ > 0) {
467b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      --push_count_;
468b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    } else {
469b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      ++pop_count_;
470b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    }
471b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    return values_.RemoveLast();
472b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
473b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
4749fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block  void Drop(int count);
475b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
4769fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block  HValue* Top() const { return ExpressionStackAt(0); }
477b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
478257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  bool ExpressionStackIsEmpty() const;
479257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
4809fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block  HValue* ExpressionStackAt(int index_from_top) const {
4819fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block    int index = length() - index_from_top - 1;
4829fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block    ASSERT(HasExpressionAt(index));
4839fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block    return values_[index];
484b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
4859fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block
4869fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block  void SetExpressionStackAt(int index_from_top, HValue* value);
4879fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block
488b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  HEnvironment* Copy() const;
489b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  HEnvironment* CopyWithoutHistory() const;
490b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  HEnvironment* CopyAsLoopHeader(HBasicBlock* block) const;
491b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
492b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Create an "inlined version" of this environment, where the original
493b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // environment is the outer environment but the top expression stack
4943fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // elements are moved to an inner environment as parameters.
495b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  HEnvironment* CopyForInlining(Handle<JSFunction> target,
4963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                int arguments,
497b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                                FunctionLiteral* function,
498257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                                HConstant* undefined,
4993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                CallKind call_kind,
5003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                bool is_construct) const;
501b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
502b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void AddIncomingEdge(HBasicBlock* block, HEnvironment* other);
5039fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block
504b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void ClearHistory() {
505b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    pop_count_ = 0;
506b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    push_count_ = 0;
50744f0eee88ff00398ff7f715fab053374d808c90dSteve Block    assigned_variables_.Rewind(0);
508b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
5099fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block
510b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void SetValueAt(int index, HValue* value) {
5119fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block    ASSERT(index < length());
512b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    values_[index] = value;
513b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
514b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
515b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void PrintTo(StringStream* stream);
516b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void PrintToStd();
517b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
518b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch private:
519b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  explicit HEnvironment(const HEnvironment* other);
520b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
5213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  HEnvironment(HEnvironment* outer,
5223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch               Handle<JSFunction> closure,
5233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch               FrameType frame_type,
5243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch               int arguments);
5253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
5263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Create an artificial stub environment (e.g. for argument adaptor or
5273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // constructor stub).
5283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  HEnvironment* CreateStubEnvironment(HEnvironment* outer,
5293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                      Handle<JSFunction> target,
5303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                      FrameType frame_type,
5313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                      int arguments) const;
5323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
5339fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block  // True if index is included in the expression stack part of the environment.
5349fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block  bool HasExpressionAt(int index) const;
5359fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block
536b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void Initialize(int parameter_count, int local_count, int stack_height);
537b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void Initialize(const HEnvironment* other);
5389fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block
5399fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block  // Map a variable to an environment index.  Parameter indices are shifted
5409fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block  // by 1 (receiver is parameter index -1 but environment index 0).
5419fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block  // Stack-allocated local indices are shifted by the number of parameters.
5429fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block  int IndexFor(Variable* variable) const {
543589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    ASSERT(variable->IsStackAllocated());
544589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    int shift = variable->IsParameter()
545257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch        ? 1
546257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch        : parameter_count_ + specials_count_;
547589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    return variable->index() + shift;
5489fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block  }
549b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
550b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  Handle<JSFunction> closure_;
551257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // Value array [parameters] [specials] [locals] [temporaries].
552b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  ZoneList<HValue*> values_;
553b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  ZoneList<int> assigned_variables_;
5543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  FrameType frame_type_;
555b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  int parameter_count_;
556257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  int specials_count_;
557b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  int local_count_;
558b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  HEnvironment* outer_;
559b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  int pop_count_;
560b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  int push_count_;
561b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  int ast_id_;
562b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch};
563b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
564b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
565b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochclass HGraphBuilder;
566b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
567257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochenum ArgumentsAllowedFlag {
568257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  ARGUMENTS_NOT_ALLOWED,
569257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  ARGUMENTS_ALLOWED
570257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch};
571257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
572e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch// This class is not BASE_EMBEDDED because our inlining implementation uses
573e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch// new and delete.
574b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochclass AstContext {
575b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch public:
576b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  bool IsEffect() const { return kind_ == Expression::kEffect; }
577b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  bool IsValue() const { return kind_ == Expression::kValue; }
578b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  bool IsTest() const { return kind_ == Expression::kTest; }
579b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
580b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // 'Fill' this context with a hydrogen value.  The value is assumed to
581b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // have already been inserted in the instruction stream (or not need to
582b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // be, e.g., HPhi).  Call this function in tail position in the Visit
583b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // functions for expressions.
584b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  virtual void ReturnValue(HValue* value) = 0;
585b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
586b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Add a hydrogen instruction to the instruction stream (recording an
587b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // environment simulation if necessary) and then fill this context with
588b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // the instruction as value.
589b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  virtual void ReturnInstruction(HInstruction* instr, int ast_id) = 0;
590b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
5913fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // Finishes the current basic block and materialize a boolean for
5923fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // value context, nothing for effect, generate a branch for test context.
5933fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // Call this function in tail position in the Visit functions for
5943fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // expressions.
5953fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  virtual void ReturnControl(HControlInstruction* instr, int ast_id) = 0;
5963fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
5978b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  void set_for_typeof(bool for_typeof) { for_typeof_ = for_typeof; }
5988b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  bool is_for_typeof() { return for_typeof_; }
5998b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
600b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch protected:
601b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  AstContext(HGraphBuilder* owner, Expression::Context kind);
602b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  virtual ~AstContext();
603b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
604b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  HGraphBuilder* owner() const { return owner_; }
605b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
6068b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  inline Zone* zone();
6078b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
608b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // We want to be able to assert, in a context-specific way, that the stack
609b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // height makes sense when the context is filled.
610b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#ifdef DEBUG
6119fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block  int original_length_;
612b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#endif
613b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
614b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch private:
615b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  HGraphBuilder* owner_;
616b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  Expression::Context kind_;
617b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  AstContext* outer_;
6188b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  bool for_typeof_;
619b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch};
620b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
621b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
622b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochclass EffectContext: public AstContext {
623b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch public:
624b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  explicit EffectContext(HGraphBuilder* owner)
625b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      : AstContext(owner, Expression::kEffect) {
626b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
627b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  virtual ~EffectContext();
628b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
629b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  virtual void ReturnValue(HValue* value);
630b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  virtual void ReturnInstruction(HInstruction* instr, int ast_id);
6313fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  virtual void ReturnControl(HControlInstruction* instr, int ast_id);
632b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch};
633b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
634b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
635b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochclass ValueContext: public AstContext {
636b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch public:
637257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  explicit ValueContext(HGraphBuilder* owner, ArgumentsAllowedFlag flag)
638257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      : AstContext(owner, Expression::kValue), flag_(flag) {
639b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
640b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  virtual ~ValueContext();
641b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
642b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  virtual void ReturnValue(HValue* value);
643b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  virtual void ReturnInstruction(HInstruction* instr, int ast_id);
6443fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  virtual void ReturnControl(HControlInstruction* instr, int ast_id);
645257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
646257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  bool arguments_allowed() { return flag_ == ARGUMENTS_ALLOWED; }
647257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
648257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch private:
649257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  ArgumentsAllowedFlag flag_;
650b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch};
651b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
652b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
653b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochclass TestContext: public AstContext {
654b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch public:
655b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  TestContext(HGraphBuilder* owner,
6563fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch              Expression* condition,
657b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch              HBasicBlock* if_true,
658b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch              HBasicBlock* if_false)
659b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      : AstContext(owner, Expression::kTest),
6603fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch        condition_(condition),
661b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch        if_true_(if_true),
662b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch        if_false_(if_false) {
663b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
664b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
665b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  virtual void ReturnValue(HValue* value);
666b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  virtual void ReturnInstruction(HInstruction* instr, int ast_id);
6673fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  virtual void ReturnControl(HControlInstruction* instr, int ast_id);
668b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
669b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  static TestContext* cast(AstContext* context) {
670b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    ASSERT(context->IsTest());
671b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    return reinterpret_cast<TestContext*>(context);
672b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
673b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
6743fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  Expression* condition() const { return condition_; }
675b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  HBasicBlock* if_true() const { return if_true_; }
676b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  HBasicBlock* if_false() const { return if_false_; }
677b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
678b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch private:
679b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Build the shared core part of the translation unpacking a value into
680b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // control flow.
681b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void BuildBranch(HValue* value);
682b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
6833fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  Expression* condition_;
684b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  HBasicBlock* if_true_;
685b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  HBasicBlock* if_false_;
686b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch};
687b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
688b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
6893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochenum ReturnHandlingFlag {
6903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  NORMAL_RETURN,
6913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  DROP_EXTRA_ON_RETURN,
6923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  CONSTRUCT_CALL_RETURN
6933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch};
6943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
6953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
6963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochclass FunctionState {
697e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch public:
698e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  FunctionState(HGraphBuilder* owner,
699e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch                CompilationInfo* info,
7003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                TypeFeedbackOracle* oracle,
7013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                ReturnHandlingFlag return_handling);
702e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  ~FunctionState();
703e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
704e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  CompilationInfo* compilation_info() { return compilation_info_; }
705e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  TypeFeedbackOracle* oracle() { return oracle_; }
706e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  AstContext* call_context() { return call_context_; }
7073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  bool drop_extra() { return return_handling_ == DROP_EXTRA_ON_RETURN; }
7083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  bool is_construct() { return return_handling_ == CONSTRUCT_CALL_RETURN; }
709e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  HBasicBlock* function_return() { return function_return_; }
710e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  TestContext* test_context() { return test_context_; }
711e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  void ClearInlinedTestContext() {
712e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch    delete test_context_;
713e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch    test_context_ = NULL;
714e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  }
715e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
7168b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  FunctionState* outer() { return outer_; }
7178b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
718e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch private:
719e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  HGraphBuilder* owner_;
720e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
721e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  CompilationInfo* compilation_info_;
722e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  TypeFeedbackOracle* oracle_;
723e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
724e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  // During function inlining, expression context of the call being
725e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  // inlined. NULL when not inlining.
726e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  AstContext* call_context_;
727e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
7283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Indicate whether we have to perform special handling on return from
7293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // inlined functions.
7303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // - DROP_EXTRA_ON_RETURN: Drop an extra value from the environment.
7313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // - CONSTRUCT_CALL_RETURN: Either use allocated receiver or return value.
7323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  ReturnHandlingFlag return_handling_;
7333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
7343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // When inlining in an effect or value context, this is the return block.
735e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  // It is NULL otherwise.  When inlining in a test context, there are a
736e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  // pair of return blocks in the context.  When not inlining, there is no
737e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  // local return point.
738e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  HBasicBlock* function_return_;
739e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
740e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  // When inlining a call in a test context, a context containing a pair of
741e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  // return blocks.  NULL in all other cases.
742e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  TestContext* test_context_;
743e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
744e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  FunctionState* outer_;
745e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch};
746e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
747e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
748b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochclass HGraphBuilder: public AstVisitor {
749b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch public:
750e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  enum BreakType { BREAK, CONTINUE };
7513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  enum SwitchType { UNKNOWN_SWITCH, SMI_SWITCH, STRING_SWITCH };
752e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
753e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  // A class encapsulating (lazily-allocated) break and continue blocks for
754e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  // a breakable statement.  Separated from BreakAndContinueScope so that it
755e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  // can have a separate lifetime.
756e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  class BreakAndContinueInfo BASE_EMBEDDED {
757e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch   public:
7583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    explicit BreakAndContinueInfo(BreakableStatement* target,
7593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                  int drop_extra = 0)
7603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        : target_(target),
7613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch          break_block_(NULL),
7623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch          continue_block_(NULL),
7633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch          drop_extra_(drop_extra) {
764e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch    }
765e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
766e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch    BreakableStatement* target() { return target_; }
767e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch    HBasicBlock* break_block() { return break_block_; }
768e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch    void set_break_block(HBasicBlock* block) { break_block_ = block; }
769e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch    HBasicBlock* continue_block() { return continue_block_; }
770e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch    void set_continue_block(HBasicBlock* block) { continue_block_ = block; }
7713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    int drop_extra() { return drop_extra_; }
772e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
773e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch   private:
774e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch    BreakableStatement* target_;
775e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch    HBasicBlock* break_block_;
776e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch    HBasicBlock* continue_block_;
7773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    int drop_extra_;
778e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  };
779e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
780e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  // A helper class to maintain a stack of current BreakAndContinueInfo
781e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  // structures mirroring BreakableStatement nesting.
782e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  class BreakAndContinueScope BASE_EMBEDDED {
783e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch   public:
784e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch    BreakAndContinueScope(BreakAndContinueInfo* info, HGraphBuilder* owner)
785e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch        : info_(info), owner_(owner), next_(owner->break_scope()) {
786e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch      owner->set_break_scope(this);
787e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch    }
788e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
789e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch    ~BreakAndContinueScope() { owner_->set_break_scope(next_); }
790e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
791e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch    BreakAndContinueInfo* info() { return info_; }
792e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch    HGraphBuilder* owner() { return owner_; }
793e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch    BreakAndContinueScope* next() { return next_; }
794e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
795e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch    // Search the break stack for a break or continue target.
7963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    HBasicBlock* Get(BreakableStatement* stmt, BreakType type, int* drop_extra);
797e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
798e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch   private:
799e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch    BreakAndContinueInfo* info_;
800e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch    HGraphBuilder* owner_;
801e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch    BreakAndContinueScope* next_;
802e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  };
803e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
804257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  HGraphBuilder(CompilationInfo* info, TypeFeedbackOracle* oracle);
805b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
806e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  HGraph* CreateGraph();
807b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
808b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Simple accessors.
809b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  HGraph* graph() const { return graph_; }
810e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  BreakAndContinueScope* break_scope() const { return break_scope_; }
811e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  void set_break_scope(BreakAndContinueScope* head) { break_scope_ = head; }
812b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
81344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  HBasicBlock* current_block() const { return current_block_; }
81444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  void set_current_block(HBasicBlock* block) { current_block_ = block; }
815e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  HEnvironment* environment() const {
816e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch    return current_block()->last_environment();
817e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  }
818b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
819257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  bool inline_bailout() { return inline_bailout_; }
820257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
821b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Adding instructions.
822b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  HInstruction* AddInstruction(HInstruction* instr);
8233fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  void AddSimulate(int ast_id);
824b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
825b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Bailout environment manipulation.
826b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void Push(HValue* value) { environment()->Push(value); }
827b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  HValue* Pop() { return environment()->Pop(); }
828b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
829257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  void Bailout(const char* reason);
830257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
8313fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  HBasicBlock* CreateJoin(HBasicBlock* first,
8323fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                          HBasicBlock* second,
8333fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                          int join_id);
8343fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
83569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  TypeFeedbackOracle* oracle() const { return function_state()->oracle(); }
83669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch
8373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  FunctionState* function_state() const { return function_state_; }
8383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
8393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void VisitDeclarations(ZoneList<Declaration*>* declarations);
8403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
841b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch private:
842b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Type of a member function that generates inline code for a native function.
843e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  typedef void (HGraphBuilder::*InlineFunctionGenerator)(CallRuntime* call);
844b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
845b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Forward declarations for inner scope classes.
846b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  class SubgraphScope;
847b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
848b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  static const InlineFunctionGenerator kInlineFunctionGenerators[];
849b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
850b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  static const int kMaxCallPolymorphism = 4;
851b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  static const int kMaxLoadPolymorphism = 4;
852b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  static const int kMaxStorePolymorphism = 4;
853b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
854b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  static const int kMaxInlinedNodes = 196;
855b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  static const int kMaxInlinedSize = 196;
856b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  static const int kMaxSourceSize = 600;
857b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
8583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Even in the 'unlimited' case we have to have some limit in order not to
8593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // overflow the stack.
8603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static const int kUnlimitedMaxInlinedNodes = 1000;
8613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static const int kUnlimitedMaxInlinedSize = 1000;
8623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static const int kUnlimitedMaxSourceSize = 600;
8633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
864b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Simple accessors.
865e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  void set_function_state(FunctionState* state) { function_state_ = state; }
866e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
867b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  AstContext* ast_context() const { return ast_context_; }
868b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void set_ast_context(AstContext* context) { ast_context_ = context; }
869e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
870e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  // Accessors forwarded to the function state.
871e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  CompilationInfo* info() const {
872e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch    return function_state()->compilation_info();
873e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  }
874e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  AstContext* call_context() const {
875e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch    return function_state()->call_context();
876e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  }
877e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  HBasicBlock* function_return() const {
878e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch    return function_state()->function_return();
879e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  }
880e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  TestContext* inlined_test_context() const {
881e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch    return function_state()->test_context();
882e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  }
883e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  void ClearInlinedTestContext() {
884e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch    function_state()->ClearInlinedTestContext();
885e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  }
8863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  StrictModeFlag function_strict_mode_flag() {
8873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    return function_state()->compilation_info()->is_classic_mode()
8883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        ? kNonStrictMode : kStrictMode;
8898b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  }
890b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
891b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Generators for inline runtime functions.
892b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#define INLINE_FUNCTION_GENERATOR_DECLARATION(Name, argc, ressize)      \
893e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  void Generate##Name(CallRuntime* call);
894b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
895b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  INLINE_FUNCTION_LIST(INLINE_FUNCTION_GENERATOR_DECLARATION)
896b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  INLINE_RUNTIME_FUNCTION_LIST(INLINE_FUNCTION_GENERATOR_DECLARATION)
897b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#undef INLINE_FUNCTION_GENERATOR_DECLARATION
898b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
899589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  void HandleDeclaration(VariableProxy* proxy,
9003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                         VariableMode mode,
9013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                         FunctionLiteral* function,
9023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                         int* global_count);
903589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
904257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  void VisitDelete(UnaryOperation* expr);
905257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  void VisitVoid(UnaryOperation* expr);
906257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  void VisitTypeof(UnaryOperation* expr);
907257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  void VisitAdd(UnaryOperation* expr);
908257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  void VisitSub(UnaryOperation* expr);
909257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  void VisitBitNot(UnaryOperation* expr);
910257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  void VisitNot(UnaryOperation* expr);
911257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
912257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  void VisitComma(BinaryOperation* expr);
9133fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  void VisitLogicalExpression(BinaryOperation* expr);
9143fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  void VisitArithmeticExpression(BinaryOperation* expr);
915b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
9163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  bool PreProcessOsrEntry(IterationStatement* statement);
917e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  // True iff. we are compiling for OSR and the statement is the entry.
918e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  bool HasOsrEntryAt(IterationStatement* statement);
9193fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  void VisitLoopBody(IterationStatement* stmt,
9203fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                     HBasicBlock* loop_entry,
9213fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                     BreakAndContinueInfo* break_info);
922e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
923e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  // Create a back edge in the flow graph.  body_exit is the predecessor
924e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  // block and loop_entry is the successor block.  loop_successor is the
925e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  // block where control flow exits the loop normally (e.g., via failure of
926e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  // the condition) and break_block is the block where control flow breaks
927e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  // from the loop.  All blocks except loop_entry can be NULL.  The return
928e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  // value is the new successor block which is the join of loop_successor
929e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  // and break_block, or NULL.
930e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  HBasicBlock* CreateLoop(IterationStatement* statement,
931e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch                          HBasicBlock* loop_entry,
932e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch                          HBasicBlock* body_exit,
933e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch                          HBasicBlock* loop_successor,
934e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch                          HBasicBlock* break_block);
935e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
936e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  HBasicBlock* JoinContinue(IterationStatement* statement,
937e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch                            HBasicBlock* exit_block,
938e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch                            HBasicBlock* continue_block);
939b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
940b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  HValue* Top() const { return environment()->Top(); }
941b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void Drop(int n) { environment()->Drop(n); }
942b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void Bind(Variable* var, HValue* value) { environment()->Bind(var, value); }
943b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
944257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // The value of the arguments object is allowed in some but not most value
945257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // contexts.  (It's allowed in all effect contexts and disallowed in all
946257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // test contexts.)
947257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  void VisitForValue(Expression* expr,
948257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                     ArgumentsAllowedFlag flag = ARGUMENTS_NOT_ALLOWED);
9498b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  void VisitForTypeOf(Expression* expr);
950b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void VisitForEffect(Expression* expr);
951b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void VisitForControl(Expression* expr,
952b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                       HBasicBlock* true_block,
953b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                       HBasicBlock* false_block);
954b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
955e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  // Visit an argument subexpression and emit a push to the outgoing
9563fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // arguments.  Returns the hydrogen value that was pushed.
9573fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  HValue* VisitArgument(Expression* expr);
9583fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
959b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void VisitArgumentList(ZoneList<Expression*>* arguments);
960b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
961e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  // Visit a list of expressions from left to right, each in a value context.
962e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  void VisitExpressions(ZoneList<Expression*>* exprs);
963e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
964b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void AddPhi(HPhi* phi);
965b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
966b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void PushAndAdd(HInstruction* instr);
967b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
968b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Remove the arguments from the bailout environment and emit instructions
969b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // to push them as outgoing parameters.
9703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  template <class Instruction> HInstruction* PreProcessCall(Instruction* call);
971b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
972257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  void TraceRepresentation(Token::Value op,
973257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                           TypeInfo info,
974257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                           HValue* value,
975257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                           Representation rep);
976b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  static Representation ToRepresentation(TypeInfo info);
977b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
9783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void SetUpScope(Scope* scope);
979b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  virtual void VisitStatements(ZoneList<Statement*>* statements);
980b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
981b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#define DECLARE_VISIT(type) virtual void Visit##type(type* node);
982b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  AST_NODE_LIST(DECLARE_VISIT)
983b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#undef DECLARE_VISIT
984b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
985b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  HBasicBlock* CreateBasicBlock(HEnvironment* env);
986e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  HBasicBlock* CreateLoopHeaderBlock();
987b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
988b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Helpers for flow graph construction.
9898b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  enum GlobalPropertyAccess {
9908b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    kUseCell,
9918b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    kUseGeneric
9928b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  };
9938b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  GlobalPropertyAccess LookupGlobalProperty(Variable* var,
9948b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch                                            LookupResult* lookup,
9958b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch                                            bool is_store);
996b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
997b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  bool TryArgumentsAccess(Property* expr);
99842effa50d92d47f80404ee63808dbde9921e6202Ben Murdoch
99942effa50d92d47f80404ee63808dbde9921e6202Ben Murdoch  // Try to optimize fun.apply(receiver, arguments) pattern.
1000b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  bool TryCallApply(Call* expr);
100142effa50d92d47f80404ee63808dbde9921e6202Ben Murdoch
10023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  bool TryInline(CallKind call_kind,
10033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                 Handle<JSFunction> target,
10043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                 ZoneList<Expression*>* arguments,
10053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                 HValue* receiver,
10063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                 int ast_id,
10073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                 int return_id,
10083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                 ReturnHandlingFlag return_handling);
10093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
10103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  bool TryInlineCall(Call* expr, bool drop_extra = false);
10113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  bool TryInlineConstruct(CallNew* expr, HValue* receiver);
10123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  bool TryInlineBuiltinMethodCall(Call* expr,
10133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                  HValue* receiver,
10143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                  Handle<Map> receiver_map,
10153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                  CheckType check_type);
10163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  bool TryInlineBuiltinFunctionCall(Call* expr, bool drop_extra);
1017e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
1018e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  // If --trace-inlining, print a line of the inlining trace.  Inlining
1019e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  // succeeded if the reason string is NULL and failed if there is a
1020e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  // non-NULL reason string.
1021257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  void TraceInline(Handle<JSFunction> target,
1022257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                   Handle<JSFunction> caller,
1023257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                   const char* failure_reason);
1024b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1025b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void HandleGlobalVariableAssignment(Variable* var,
1026b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                                      HValue* value,
1027b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                                      int position,
1028b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                                      int ast_id);
1029b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1030b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void HandlePropertyAssignment(Assignment* expr);
1031b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void HandleCompoundAssignment(Assignment* expr);
1032b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void HandlePolymorphicStoreNamedField(Assignment* expr,
1033b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                                        HValue* object,
1034b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                                        HValue* value,
103569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch                                        SmallMapList* types,
1036b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                                        Handle<String> name);
1037b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void HandlePolymorphicCallNamed(Call* expr,
1038b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                                  HValue* receiver,
103969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch                                  SmallMapList* types,
1040b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                                  Handle<String> name);
10413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void HandleLiteralCompareTypeof(CompareOperation* expr,
10423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                  HTypeof* typeof_expr,
10433fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                                  Handle<String> check);
10443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void HandleLiteralCompareNil(CompareOperation* expr,
10453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                               HValue* value,
10463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                               NilValue nil);
10473fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
10483fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  HStringCharCodeAt* BuildStringCharCodeAt(HValue* context,
10493fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                                           HValue* string,
10501e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block                                           HValue* index);
1051b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  HInstruction* BuildBinaryOperation(BinaryOperation* expr,
1052b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                                     HValue* left,
1053b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                                     HValue* right);
1054257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  HInstruction* BuildIncrement(bool returns_original_input,
1055257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                               CountOperation* expr);
1056b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  HLoadNamedField* BuildLoadNamedField(HValue* object,
1057b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                                       Property* expr,
1058b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                                       Handle<Map> type,
1059b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                                       LookupResult* result,
1060b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                                       bool smi_and_map_check);
1061b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  HInstruction* BuildLoadNamedGeneric(HValue* object, Property* expr);
1062b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  HInstruction* BuildLoadKeyedGeneric(HValue* object,
1063b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                                      HValue* key);
10643fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  HInstruction* BuildExternalArrayElementAccess(
10653fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      HValue* external_elements,
10663fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      HValue* checked_key,
10673fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      HValue* val,
1068589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      ElementsKind elements_kind,
10693fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      bool is_store);
10703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  HInstruction* BuildFastElementAccess(HValue* elements,
10713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                       HValue* checked_key,
10723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                       HValue* val,
10733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                       ElementsKind elements_kind,
10743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                       bool is_store);
10753fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
10763fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  HInstruction* BuildMonomorphicElementAccess(HValue* object,
10773fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                                              HValue* key,
10783fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                                              HValue* val,
10793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                              Handle<Map> map,
10803fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                                              bool is_store);
10813fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  HValue* HandlePolymorphicElementAccess(HValue* object,
10823fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                                         HValue* key,
10833fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                                         HValue* val,
10843fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                                         Expression* prop,
10853fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                                         int ast_id,
10863fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                                         int position,
10873fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                                         bool is_store,
10883fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                                         bool* has_side_effects);
10893fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
10903fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  HValue* HandleKeyedElementAccess(HValue* obj,
10913fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                                   HValue* key,
10923fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                                   HValue* val,
10933fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                                   Expression* expr,
10943fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                                   int ast_id,
10953fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                                   int position,
10963fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                                   bool is_store,
10973fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                                   bool* has_side_effects);
10988b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
1099b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  HInstruction* BuildLoadNamed(HValue* object,
1100b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                               Property* prop,
1101b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                               Handle<Map> map,
1102b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                               Handle<String> name);
1103b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  HInstruction* BuildStoreNamed(HValue* object,
1104b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                                HValue* value,
1105b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                                Expression* expr);
11063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  HInstruction* BuildStoreNamed(HValue* object,
11073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                HValue* value,
11083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                ObjectLiteral::Property* prop);
1109b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  HInstruction* BuildStoreNamedField(HValue* object,
1110b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                                     Handle<String> name,
1111b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                                     HValue* value,
1112b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                                     Handle<Map> type,
1113b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                                     LookupResult* lookup,
1114b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                                     bool smi_and_map_check);
1115b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  HInstruction* BuildStoreNamedGeneric(HValue* object,
1116b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                                       Handle<String> name,
1117b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                                       HValue* value);
1118b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  HInstruction* BuildStoreKeyedGeneric(HValue* object,
1119b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                                       HValue* key,
1120b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                                       HValue* value);
1121b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
11221e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  HValue* BuildContextChainWalk(Variable* var);
11231e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
1124b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void AddCheckConstantFunction(Call* expr,
1125b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                                HValue* receiver,
1126b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                                Handle<Map> receiver_map,
1127b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                                bool smi_and_map_check);
1128b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
11298b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  Zone* zone() { return zone_; }
1130b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1131e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  // The translation state of the currently-being-translated function.
1132e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  FunctionState* function_state_;
1133e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
1134e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  // The base of the function state stack.
1135e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  FunctionState initial_function_state_;
1136e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
1137b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Expression context of the currently visited subexpression. NULL when
1138b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // visiting statements.
1139b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  AstContext* ast_context_;
1140b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1141e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  // A stack of breakable statements entered.
1142e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  BreakAndContinueScope* break_scope_;
1143b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1144e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  HGraph* graph_;
114544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  HBasicBlock* current_block_;
1146b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1147b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  int inlined_count_;
1148b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
11498b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  Zone* zone_;
11508b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
1151257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  bool inline_bailout_;
1152257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
1153e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  friend class FunctionState;  // Pushes and pops the state stack.
1154b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  friend class AstContext;  // Pushes and pops the AST context stack.
1155b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1156b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  DISALLOW_COPY_AND_ASSIGN(HGraphBuilder);
1157b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch};
1158b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1159b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
11608b112d2025046f85ef7f6be087c6129c872ebad2Ben MurdochZone* AstContext::zone() { return owner_->zone(); }
11618b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
11628b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
1163b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochclass HValueMap: public ZoneObject {
1164b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch public:
1165b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  HValueMap()
1166b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      : array_size_(0),
1167b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch        lists_size_(0),
1168b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch        count_(0),
1169b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch        present_flags_(0),
1170b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch        array_(NULL),
1171b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch        lists_(NULL),
1172b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch        free_list_head_(kNil) {
1173b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    ResizeLists(kInitialSize);
1174b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    Resize(kInitialSize);
1175b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
1176b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
11773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void Kill(GVNFlagSet flags);
1178b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1179b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void Add(HValue* value) {
11803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    present_flags_.Add(value->gvn_flags());
1181b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    Insert(value);
1182b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
1183b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1184b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  HValue* Lookup(HValue* value) const;
11858b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
11868b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  HValueMap* Copy(Zone* zone) const {
1187257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    return new(zone) HValueMap(zone, this);
11888b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  }
1189b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1190257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  bool IsEmpty() const { return count_ == 0; }
1191257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
1192b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch private:
1193b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // A linked list of HValue* values.  Stored in arrays.
1194b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  struct HValueMapListElement {
1195b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    HValue* value;
1196b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    int next;  // Index in the array of the next list element.
1197b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  };
1198b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  static const int kNil = -1;  // The end of a linked list
1199b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1200b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Must be a power of 2.
1201b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  static const int kInitialSize = 16;
1202b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1203257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  HValueMap(Zone* zone, const HValueMap* other);
1204b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1205b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void Resize(int new_size);
1206b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void ResizeLists(int new_size);
1207b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void Insert(HValue* value);
1208b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  uint32_t Bound(uint32_t value) const { return value & (array_size_ - 1); }
1209b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1210b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  int array_size_;
1211b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  int lists_size_;
1212b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  int count_;  // The number of values stored in the HValueMap.
12133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  GVNFlagSet present_flags_;  // All flags that are in any value in the
12143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                              // HValueMap.
1215b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  HValueMapListElement* array_;  // Primary store - contains the first value
1216b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // with a given hash.  Colliding elements are stored in linked lists.
1217b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  HValueMapListElement* lists_;  // The linked lists containing hash collisions.
1218b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  int free_list_head_;  // Unused elements in lists_ are on the free list.
1219b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch};
1220b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1221b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1222b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochclass HStatistics: public Malloced {
1223b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch public:
122444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  void Initialize(CompilationInfo* info);
1225b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void Print();
1226b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  void SaveTiming(const char* name, int64_t ticks, unsigned size);
1227b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  static HStatistics* Instance() {
1228b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    static SetOncePointer<HStatistics> instance;
1229b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    if (!instance.is_set()) {
1230b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      instance.set(new HStatistics());
1231b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    }
1232b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    return instance.get();
1233b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
1234b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1235b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch private:
1236b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  HStatistics()
1237b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch      : timing_(5),
1238b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch        names_(5),
1239b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch        sizes_(5),
1240b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch        total_(0),
1241b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch        total_size_(0),
124244f0eee88ff00398ff7f715fab053374d808c90dSteve Block        full_code_gen_(0),
124344f0eee88ff00398ff7f715fab053374d808c90dSteve Block        source_size_(0) { }
1244b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1245b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  List<int64_t> timing_;
1246b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  List<const char*> names_;
1247b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  List<unsigned> sizes_;
1248b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  int64_t total_;
1249b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  unsigned total_size_;
1250b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  int64_t full_code_gen_;
125144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  double source_size_;
1252b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch};
1253b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1254b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1255b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochclass HPhase BASE_EMBEDDED {
1256b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch public:
1257b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  static const char* const kFullCodeGen;
1258b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  static const char* const kTotal;
1259b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1260b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  explicit HPhase(const char* name) { Begin(name, NULL, NULL, NULL); }
1261b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  HPhase(const char* name, HGraph* graph) {
1262b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    Begin(name, graph, NULL, NULL);
1263b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
1264b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  HPhase(const char* name, LChunk* chunk) {
1265b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    Begin(name, NULL, chunk, NULL);
1266b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
1267b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  HPhase(const char* name, LAllocator* allocator) {
1268b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    Begin(name, NULL, NULL, allocator);
1269b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
1270b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1271b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  ~HPhase() {
1272b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    End();
1273b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
1274b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1275b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch private:
1276b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void Begin(const char* name,
1277b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch             HGraph* graph,
1278b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch             LChunk* chunk,
1279b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch             LAllocator* allocator);
1280b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void End() const;
1281b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1282b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  int64_t start_;
1283b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  const char* name_;
1284b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  HGraph* graph_;
1285b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  LChunk* chunk_;
1286b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  LAllocator* allocator_;
1287b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  unsigned start_allocation_size_;
1288b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch};
1289b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1290b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1291b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochclass HTracer: public Malloced {
1292b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch public:
1293b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void TraceCompilation(FunctionLiteral* function);
1294b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void TraceHydrogen(const char* name, HGraph* graph);
1295b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void TraceLithium(const char* name, LChunk* chunk);
1296b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void TraceLiveRanges(const char* name, LAllocator* allocator);
1297b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1298b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  static HTracer* Instance() {
1299b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    static SetOncePointer<HTracer> instance;
1300b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    if (!instance.is_set()) {
1301b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      instance.set(new HTracer("hydrogen.cfg"));
1302b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    }
1303b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    return instance.get();
1304b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
1305b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1306b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch private:
1307b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  class Tag BASE_EMBEDDED {
1308b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch   public:
1309b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    Tag(HTracer* tracer, const char* name) {
1310b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      name_ = name;
1311b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      tracer_ = tracer;
1312b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      tracer->PrintIndent();
1313b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      tracer->trace_.Add("begin_%s\n", name);
1314b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      tracer->indent_++;
1315b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    }
1316b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1317b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    ~Tag() {
1318b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      tracer_->indent_--;
1319b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      tracer_->PrintIndent();
1320b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      tracer_->trace_.Add("end_%s\n", name_);
1321b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      ASSERT(tracer_->indent_ >= 0);
1322b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      tracer_->FlushToFile();
1323b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    }
1324b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1325b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch   private:
1326b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    HTracer* tracer_;
1327b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    const char* name_;
1328b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  };
1329b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1330b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  explicit HTracer(const char* filename)
1331b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      : filename_(filename), trace_(&string_allocator_), indent_(0) {
1332b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    WriteChars(filename, "", 0, false);
1333b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
1334b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1335b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void TraceLiveRange(LiveRange* range, const char* type);
1336b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void Trace(const char* name, HGraph* graph, LChunk* chunk);
1337b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void FlushToFile();
1338b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1339b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void PrintEmptyProperty(const char* name) {
1340b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    PrintIndent();
1341b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    trace_.Add("%s\n", name);
1342b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
1343b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1344b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void PrintStringProperty(const char* name, const char* value) {
1345b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    PrintIndent();
1346b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    trace_.Add("%s \"%s\"\n", name, value);
1347b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
1348b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1349b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void PrintLongProperty(const char* name, int64_t value) {
1350b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    PrintIndent();
1351b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    trace_.Add("%s %d000\n", name, static_cast<int>(value / 1000));
1352b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
1353b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1354b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void PrintBlockProperty(const char* name, int block_id) {
1355b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    PrintIndent();
1356b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    trace_.Add("%s \"B%d\"\n", name, block_id);
1357b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
1358b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1359b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void PrintIntProperty(const char* name, int value) {
1360b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    PrintIndent();
1361b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    trace_.Add("%s %d\n", name, value);
1362b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
1363b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1364b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void PrintIndent() {
1365b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    for (int i = 0; i < indent_; i++) {
1366b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      trace_.Add("  ");
1367b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    }
1368b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
1369b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1370b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  const char* filename_;
1371b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  HeapStringAllocator string_allocator_;
1372b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  StringStream trace_;
1373b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  int indent_;
1374b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch};
1375b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1376b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1377b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} }  // namespace v8::internal
1378b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1379b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#endif  // V8_HYDROGEN_H_
1380