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