LCOV - code coverage report
Current view: top level - src/crankshaft - hydrogen.h (source / functions) Hit Total Coverage
Test: app.info Lines: 393 436 90.1 %
Date: 2017-04-26 Functions: 381 417 91.4 %

          Line data    Source code
       1             : // Copyright 2012 the V8 project authors. All rights reserved.
       2             : // Use of this source code is governed by a BSD-style license that can be
       3             : // found in the LICENSE file.
       4             : 
       5             : #ifndef V8_CRANKSHAFT_HYDROGEN_H_
       6             : #define V8_CRANKSHAFT_HYDROGEN_H_
       7             : 
       8             : #include "src/accessors.h"
       9             : #include "src/allocation.h"
      10             : #include "src/ast/ast-type-bounds.h"
      11             : #include "src/ast/scopes.h"
      12             : #include "src/bailout-reason.h"
      13             : #include "src/compilation-info.h"
      14             : #include "src/compiler.h"
      15             : #include "src/counters.h"
      16             : #include "src/crankshaft/compilation-phase.h"
      17             : #include "src/crankshaft/hydrogen-instructions.h"
      18             : #include "src/globals.h"
      19             : #include "src/parsing/parse-info.h"
      20             : #include "src/string-stream.h"
      21             : #include "src/transitions.h"
      22             : #include "src/zone/zone.h"
      23             : 
      24             : namespace v8 {
      25             : namespace internal {
      26             : 
      27             : // Forward declarations.
      28             : class BitVector;
      29             : class FunctionState;
      30             : class HEnvironment;
      31             : class HGraph;
      32             : class HLoopInformation;
      33             : class HOsrBuilder;
      34             : class HTracer;
      35             : class LAllocator;
      36             : class LChunk;
      37             : class LiveRange;
      38             : 
      39      757351 : class HCompilationJob final : public CompilationJob {
      40             :  public:
      41      378686 :   explicit HCompilationJob(Handle<JSFunction> function)
      42             :       : CompilationJob(function->GetIsolate(), &info_, "Crankshaft"),
      43             :         parse_info_(handle(function->shared())),
      44             :         info_(parse_info_.zone(), &parse_info_, function->GetIsolate(),
      45             :               function),
      46             :         graph_(nullptr),
      47     1514746 :         chunk_(nullptr) {}
      48             : 
      49             :  protected:
      50             :   virtual Status PrepareJobImpl();
      51             :   virtual Status ExecuteJobImpl();
      52             :   virtual Status FinalizeJobImpl();
      53             : 
      54             :  private:
      55             :   ParseInfo parse_info_;
      56             :   CompilationInfo info_;
      57             :   HGraph* graph_;
      58             :   LChunk* chunk_;
      59             : };
      60             : 
      61             : class HBasicBlock final : public ZoneObject {
      62             :  public:
      63             :   explicit HBasicBlock(HGraph* graph);
      64             :   ~HBasicBlock() { }
      65             : 
      66             :   // Simple accessors.
      67             :   int block_id() const { return block_id_; }
      68     2362327 :   void set_block_id(int id) { block_id_ = id; }
      69             :   HGraph* graph() const { return graph_; }
      70             :   Isolate* isolate() const;
      71             :   const ZoneList<HPhi*>* phis() const { return &phis_; }
      72             :   HInstruction* first() const { return first_; }
      73             :   HInstruction* last() const { return last_; }
      74    24896441 :   void set_last(HInstruction* instr) { last_ = instr; }
      75             :   HControlInstruction* end() const { return end_; }
      76             :   HLoopInformation* loop_information() const { return loop_information_; }
      77             :   HLoopInformation* current_loop() const {
      78             :     return IsLoopHeader() ? loop_information()
      79             :                           : (parent_loop_header() != NULL
      80             :                             ? parent_loop_header()->loop_information() : NULL);
      81             :   }
      82             :   const ZoneList<HBasicBlock*>* predecessors() const { return &predecessors_; }
      83     6415608 :   bool HasPredecessor() const { return predecessors_.length() > 0; }
      84             :   const ZoneList<HBasicBlock*>* dominated_blocks() const {
      85             :     return &dominated_blocks_;
      86             :   }
      87             :   const ZoneList<int>* deleted_phis() const {
      88             :     return &deleted_phis_;
      89             :   }
      90          25 :   void RecordDeletedPhi(int merge_index) {
      91             :     deleted_phis_.Add(merge_index, zone());
      92             :   }
      93             :   HBasicBlock* dominator() const { return dominator_; }
      94             :   HEnvironment* last_environment() const { return last_environment_; }
      95             :   int argument_count() const { return argument_count_; }
      96     4493522 :   void set_argument_count(int count) { argument_count_ = count; }
      97             :   int first_instruction_index() const { return first_instruction_index_; }
      98             :   void set_first_instruction_index(int index) {
      99     4493524 :     first_instruction_index_ = index;
     100             :   }
     101             :   int last_instruction_index() const { return last_instruction_index_; }
     102             :   void set_last_instruction_index(int index) {
     103     4493524 :     last_instruction_index_ = index;
     104             :   }
     105     3224341 :   bool is_osr_entry() { return is_osr_entry_; }
     106        2432 :   void set_osr_entry() { is_osr_entry_ = true; }
     107             : 
     108             :   void AttachLoopInformation();
     109             :   void DetachLoopInformation();
     110    71774137 :   bool IsLoopHeader() const { return loop_information() != NULL; }
     111    30316007 :   bool IsStartBlock() const { return block_id() == 0; }
     112             :   void PostProcessLoopHeader(IterationStatement* stmt);
     113             : 
     114             :   bool IsFinished() const { return end_ != NULL; }
     115             :   void AddPhi(HPhi* phi);
     116             :   void RemovePhi(HPhi* phi);
     117             :   void AddInstruction(HInstruction* instr, SourcePosition position);
     118             :   bool Dominates(HBasicBlock* other) const;
     119             :   bool EqualToOrDominates(HBasicBlock* other) const;
     120             :   int LoopNestingDepth() const;
     121             : 
     122             :   void SetInitialEnvironment(HEnvironment* env);
     123             :   void ClearEnvironment() {
     124             :     DCHECK(IsFinished());
     125             :     DCHECK(end()->SuccessorCount() == 0);
     126      356825 :     last_environment_ = NULL;
     127             :   }
     128             :   bool HasEnvironment() const { return last_environment_ != NULL; }
     129             :   void UpdateEnvironment(HEnvironment* env);
     130             :   HBasicBlock* parent_loop_header() const { return parent_loop_header_; }
     131             : 
     132             :   void set_parent_loop_header(HBasicBlock* block) {
     133             :     DCHECK(parent_loop_header_ == NULL);
     134      856816 :     parent_loop_header_ = block;
     135             :   }
     136             : 
     137             :   bool HasParentLoopHeader() const { return parent_loop_header_ != NULL; }
     138             : 
     139             :   void SetJoinId(BailoutId ast_id);
     140             : 
     141             :   int PredecessorIndexOf(HBasicBlock* predecessor) const;
     142             :   HPhi* AddNewPhi(int merged_index);
     143     2832759 :   HSimulate* AddNewSimulate(BailoutId ast_id, SourcePosition position,
     144             :                             RemovableSimulate removable = FIXED_SIMULATE) {
     145     2832759 :     HSimulate* instr = CreateSimulate(ast_id, removable);
     146     2832761 :     AddInstruction(instr, position);
     147     2832762 :     return instr;
     148             :   }
     149             :   void AssignCommonDominator(HBasicBlock* other);
     150             :   void AssignLoopSuccessorDominators();
     151             : 
     152             :   // If a target block is tagged as an inline function return, all
     153             :   // predecessors should contain the inlined exit sequence:
     154             :   //
     155             :   // LeaveInlined
     156             :   // Simulate (caller's environment)
     157             :   // Goto (target block)
     158     4153578 :   bool IsInlineReturnTarget() const { return is_inline_return_target_; }
     159             :   void MarkAsInlineReturnTarget(HBasicBlock* inlined_entry_block) {
     160      126831 :     is_inline_return_target_ = true;
     161      126831 :     inlined_entry_block_ = inlined_entry_block;
     162             :   }
     163             :   HBasicBlock* inlined_entry_block() { return inlined_entry_block_; }
     164             : 
     165    14100268 :   bool IsDeoptimizing() const {
     166    28012851 :     return end() != NULL && end()->IsDeoptimize();
     167             :   }
     168             : 
     169             :   void MarkUnreachable();
     170     8848059 :   bool IsUnreachable() const { return !is_reachable_; }
     171    72504445 :   bool IsReachable() const { return is_reachable_; }
     172             : 
     173             :   bool IsLoopSuccessorDominator() const {
     174      604489 :     return dominates_loop_successors_;
     175             :   }
     176             :   void MarkAsLoopSuccessorDominator() {
     177      305706 :     dominates_loop_successors_ = true;
     178             :   }
     179             : 
     180     6724179 :   bool IsOrdered() const { return is_ordered_; }
     181     4503783 :   void MarkAsOrdered() { is_ordered_ = true; }
     182             : 
     183             :   void MarkSuccEdgeUnreachable(int succ);
     184             : 
     185             :   inline Zone* zone() const;
     186             : 
     187             : #ifdef DEBUG
     188             :   void Verify();
     189             : #endif
     190             : 
     191             :  protected:
     192             :   friend class HGraphBuilder;
     193             : 
     194             :   HSimulate* CreateSimulate(BailoutId ast_id, RemovableSimulate removable);
     195             :   void Finish(HControlInstruction* last, SourcePosition position);
     196             :   void FinishExit(HControlInstruction* instruction, SourcePosition position);
     197             :   void Goto(HBasicBlock* block, SourcePosition position,
     198             :             FunctionState* state = NULL, bool add_simulate = true);
     199             :   void GotoNoSimulate(HBasicBlock* block, SourcePosition position) {
     200             :     Goto(block, position, NULL, false);
     201             :   }
     202             : 
     203             :   // Add the inlined function exit sequence, adding an HLeaveInlined
     204             :   // instruction and updating the bailout environment.
     205             :   void AddLeaveInlined(HValue* return_value, FunctionState* state,
     206             :                        SourcePosition position);
     207             : 
     208             :  private:
     209             :   void RegisterPredecessor(HBasicBlock* pred);
     210             :   void AddDominatedBlock(HBasicBlock* block);
     211             : 
     212             :   int block_id_;
     213             :   HGraph* graph_;
     214             :   ZoneList<HPhi*> phis_;
     215             :   HInstruction* first_;
     216             :   HInstruction* last_;
     217             :   HControlInstruction* end_;
     218             :   HLoopInformation* loop_information_;
     219             :   ZoneList<HBasicBlock*> predecessors_;
     220             :   HBasicBlock* dominator_;
     221             :   ZoneList<HBasicBlock*> dominated_blocks_;
     222             :   HEnvironment* last_environment_;
     223             :   // Outgoing parameter count at block exit, set during lithium translation.
     224             :   int argument_count_;
     225             :   // Instruction indices into the lithium code stream.
     226             :   int first_instruction_index_;
     227             :   int last_instruction_index_;
     228             :   ZoneList<int> deleted_phis_;
     229             :   HBasicBlock* parent_loop_header_;
     230             :   // For blocks marked as inline return target: the block with HEnterInlined.
     231             :   HBasicBlock* inlined_entry_block_;
     232             :   bool is_inline_return_target_ : 1;
     233             :   bool is_reachable_ : 1;
     234             :   bool dominates_loop_successors_ : 1;
     235             :   bool is_osr_entry_ : 1;
     236             :   bool is_ordered_ : 1;
     237             : };
     238             : 
     239             : 
     240             : std::ostream& operator<<(std::ostream& os, const HBasicBlock& b);
     241             : 
     242             : 
     243             : class HPredecessorIterator final BASE_EMBEDDED {
     244             :  public:
     245             :   explicit HPredecessorIterator(HBasicBlock* block)
     246    10910666 :       : predecessor_list_(block->predecessors()), current_(0) { }
     247             : 
     248    13460428 :   bool Done() { return current_ >= predecessor_list_->length(); }
     249    10775900 :   HBasicBlock* Current() { return predecessor_list_->at(current_); }
     250     2549762 :   void Advance() { current_++; }
     251             : 
     252             :  private:
     253             :   const ZoneList<HBasicBlock*>* predecessor_list_;
     254             :   int current_;
     255             : };
     256             : 
     257             : 
     258             : class HInstructionIterator final BASE_EMBEDDED {
     259             :  public:
     260    71033841 :   explicit HInstructionIterator(HBasicBlock* block)
     261             :       : instr_(block->first()) {
     262    71033841 :     next_ = Done() ? NULL : instr_->next();
     263             :   }
     264             : 
     265             :   inline bool Done() const { return instr_ == NULL; }
     266             :   inline HInstruction* Current() { return instr_; }
     267             :   inline void Advance() {
     268             :     instr_ = next_;
     269   441249619 :     next_ = Done() ? NULL : instr_->next();
     270             :   }
     271             : 
     272             :  private:
     273             :   HInstruction* instr_;
     274             :   HInstruction* next_;
     275             : };
     276             : 
     277             : 
     278             : class HLoopInformation final : public ZoneObject {
     279             :  public:
     280       61068 :   HLoopInformation(HBasicBlock* loop_header, Zone* zone)
     281             :       : back_edges_(4, zone),
     282             :         loop_header_(loop_header),
     283             :         blocks_(8, zone),
     284       61068 :         stack_check_(NULL) {
     285             :     blocks_.Add(loop_header, zone);
     286       61068 :   }
     287             :   ~HLoopInformation() {}
     288             : 
     289             :   const ZoneList<HBasicBlock*>* back_edges() const { return &back_edges_; }
     290             :   const ZoneList<HBasicBlock*>* blocks() const { return &blocks_; }
     291             :   HBasicBlock* loop_header() const { return loop_header_; }
     292             :   HBasicBlock* GetLastBackEdge() const;
     293             :   void RegisterBackEdge(HBasicBlock* block);
     294             : 
     295             :   HStackCheck* stack_check() const { return stack_check_; }
     296             :   void set_stack_check(HStackCheck* stack_check) {
     297       45458 :     stack_check_ = stack_check;
     298             :   }
     299             : 
     300             :   bool IsNestedInThisLoop(HLoopInformation* other) {
     301             :     while (other != NULL) {
     302             :       if (other == this) {
     303             :         return true;
     304             :       }
     305             :       other = other->parent_loop();
     306             :     }
     307             :     return false;
     308             :   }
     309             :   HLoopInformation* parent_loop() {
     310             :     HBasicBlock* parent_header = loop_header()->parent_loop_header();
     311             :     return parent_header != NULL ? parent_header->loop_information() : NULL;
     312             :   }
     313             : 
     314             :  private:
     315             :   void AddBlock(HBasicBlock* block);
     316             : 
     317             :   ZoneList<HBasicBlock*> back_edges_;
     318             :   HBasicBlock* loop_header_;
     319             :   ZoneList<HBasicBlock*> blocks_;
     320             :   HStackCheck* stack_check_;
     321             : };
     322             : 
     323             : class HGraph final : public ZoneObject {
     324             :  public:
     325             :   explicit HGraph(CompilationInfo* info, CallInterfaceDescriptor descriptor);
     326             : 
     327             :   Isolate* isolate() const { return isolate_; }
     328             :   Zone* zone() const { return zone_; }
     329             :   CompilationInfo* info() const { return info_; }
     330             :   CallInterfaceDescriptor descriptor() const { return descriptor_; }
     331             : 
     332             :   const ZoneList<HBasicBlock*>* blocks() const { return &blocks_; }
     333             :   const ZoneList<HPhi*>* phi_list() const { return phi_list_; }
     334             :   HBasicBlock* entry_block() const { return entry_block_; }
     335             :   HEnvironment* start_environment() const { return start_environment_; }
     336             : 
     337             :   void FinalizeUniqueness();
     338             :   void OrderBlocks();
     339             :   void AssignDominators();
     340             :   void RestoreActualValues();
     341             : 
     342             :   // Returns false if there are phi-uses of the arguments-object
     343             :   // which are not supported by the optimizing compiler.
     344             :   bool CheckArgumentsPhiUses();
     345             : 
     346             :   // Returns false if there are phi-uses of an uninitialized const
     347             :   // which are not supported by the optimizing compiler.
     348             :   bool CheckConstPhiUses();
     349             : 
     350             :   void CollectPhis();
     351             : 
     352             :   HConstant* GetConstantUndefined();
     353             :   HConstant* GetConstant0();
     354             :   HConstant* GetConstant1();
     355             :   HConstant* GetConstantMinus1();
     356             :   HConstant* GetConstantTrue();
     357             :   HConstant* GetConstantFalse();
     358             :   HConstant* GetConstantBool(bool value);
     359             :   HConstant* GetConstantHole();
     360             :   HConstant* GetConstantNull();
     361             :   HConstant* GetConstantOptimizedOut();
     362             :   HConstant* GetInvalidContext();
     363             : 
     364             :   bool IsConstantUndefined(HConstant* constant);
     365             :   bool IsConstant0(HConstant* constant);
     366             :   bool IsConstant1(HConstant* constant);
     367             :   bool IsConstantMinus1(HConstant* constant);
     368             :   bool IsConstantTrue(HConstant* constant);
     369             :   bool IsConstantFalse(HConstant* constant);
     370             :   bool IsConstantHole(HConstant* constant);
     371             :   bool IsConstantNull(HConstant* constant);
     372             :   bool IsStandardConstant(HConstant* constant);
     373             : 
     374             :   HBasicBlock* CreateBasicBlock();
     375             : 
     376     1415973 :   int GetMaximumValueID() const { return values_.length(); }
     377     4604288 :   int GetNextBlockID() { return next_block_id_++; }
     378    33109997 :   int GetNextValueID(HValue* value) {
     379             :     DCHECK(!disallow_adding_new_values_);
     380             :     values_.Add(value, zone());
     381    33109948 :     return values_.length() - 1;
     382             :   }
     383             :   HValue* LookupValue(int id) const {
     384    80319209 :     if (id >= 0 && id < values_.length()) return values_[id];
     385             :     return NULL;
     386             :   }
     387             :   void DisallowAddingNewValues() {
     388      283191 :     disallow_adding_new_values_ = true;
     389             :   }
     390             : 
     391             :   bool Optimize(BailoutReason* bailout_reason);
     392             : 
     393             : #ifdef DEBUG
     394             :   void Verify(bool do_full_verify) const;
     395             : #endif
     396             : 
     397             :   bool has_osr() {
     398             :     return osr_ != NULL;
     399             :   }
     400             : 
     401             :   void set_osr(HOsrBuilder* osr) {
     402        2432 :     osr_ = osr;
     403             :   }
     404             : 
     405             :   HOsrBuilder* osr() {
     406             :     return osr_;
     407             :   }
     408             : 
     409             :   int update_type_change_checksum(int delta) {
     410      367182 :     type_change_checksum_ += delta;
     411             :     return type_change_checksum_;
     412             :   }
     413             : 
     414             :   void update_maximum_environment_size(int environment_size) {
     415    10432202 :     if (environment_size > maximum_environment_size_) {
     416      301824 :       maximum_environment_size_ = environment_size;
     417             :     }
     418             :   }
     419             :   int maximum_environment_size() { return maximum_environment_size_; }
     420             : 
     421             :   bool allow_code_motion() const { return allow_code_motion_; }
     422      259782 :   void set_allow_code_motion(bool value) { allow_code_motion_ = value; }
     423             : 
     424             :   bool use_optimistic_licm() const { return use_optimistic_licm_; }
     425      259782 :   void set_use_optimistic_licm(bool value) { use_optimistic_licm_ = value; }
     426             : 
     427        9227 :   void MarkDependsOnEmptyArrayProtoElements() {
     428             :     // Add map dependency if not already added.
     429        7390 :     if (depends_on_empty_array_proto_elements_) return;
     430             :     info()->dependencies()->AssumePropertyCell(
     431        2766 :         isolate()->factory()->array_protector());
     432        2766 :     depends_on_empty_array_proto_elements_ = true;
     433             :   }
     434             : 
     435             :   bool depends_on_empty_array_proto_elements() {
     436             :     return depends_on_empty_array_proto_elements_;
     437             :   }
     438             : 
     439       16503 :   void MarkDependsOnStringLengthOverflow() {
     440       23666 :     if (depends_on_string_length_overflow_) return;
     441             :     info()->dependencies()->AssumePropertyCell(
     442        2335 :         isolate()->factory()->string_length_protector());
     443        2335 :     depends_on_string_length_overflow_ = true;
     444             :   }
     445             : 
     446             :   bool has_uint32_instructions() {
     447             :     DCHECK(uint32_instructions_ == NULL || !uint32_instructions_->is_empty());
     448             :     return uint32_instructions_ != NULL;
     449             :   }
     450             : 
     451             :   ZoneList<HInstruction*>* uint32_instructions() {
     452             :     DCHECK(uint32_instructions_ == NULL || !uint32_instructions_->is_empty());
     453             :     return uint32_instructions_;
     454             :   }
     455             : 
     456        8605 :   void RecordUint32Instruction(HInstruction* instr) {
     457             :     DCHECK(uint32_instructions_ == NULL || !uint32_instructions_->is_empty());
     458        3719 :     if (uint32_instructions_ == NULL) {
     459        1167 :       uint32_instructions_ = new(zone()) ZoneList<HInstruction*>(4, zone());
     460             :     }
     461        3719 :     uint32_instructions_->Add(instr, zone());
     462        3719 :   }
     463             : 
     464      766597 :   void IncrementInNoSideEffectsScope() { no_side_effects_scope_count_++; }
     465      766597 :   void DecrementInNoSideEffectsScope() { no_side_effects_scope_count_--; }
     466             :   bool IsInsideNoSideEffectsScope() { return no_side_effects_scope_count_ > 0; }
     467             : 
     468             :  private:
     469             :   HConstant* ReinsertConstantIfNecessary(HConstant* constant);
     470             :   HConstant* GetConstant(SetOncePointer<HConstant>* pointer,
     471             :                          int32_t integer_value);
     472             : 
     473             :   template<class Phase>
     474     5094163 :   void Run() {
     475     2545036 :     Phase phase(this);
     476     4527414 :     phase.Run();
     477     5094171 :   }
     478             : 
     479             :   Isolate* isolate_;
     480             :   int next_block_id_;
     481             :   HBasicBlock* entry_block_;
     482             :   HEnvironment* start_environment_;
     483             :   ZoneList<HBasicBlock*> blocks_;
     484             :   ZoneList<HValue*> values_;
     485             :   ZoneList<HPhi*>* phi_list_;
     486             :   ZoneList<HInstruction*>* uint32_instructions_;
     487             :   SetOncePointer<HConstant> constant_undefined_;
     488             :   SetOncePointer<HConstant> constant_0_;
     489             :   SetOncePointer<HConstant> constant_1_;
     490             :   SetOncePointer<HConstant> constant_minus1_;
     491             :   SetOncePointer<HConstant> constant_true_;
     492             :   SetOncePointer<HConstant> constant_false_;
     493             :   SetOncePointer<HConstant> constant_the_hole_;
     494             :   SetOncePointer<HConstant> constant_null_;
     495             :   SetOncePointer<HConstant> constant_optimized_out_;
     496             :   SetOncePointer<HConstant> constant_invalid_context_;
     497             : 
     498             :   HOsrBuilder* osr_;
     499             : 
     500             :   CompilationInfo* info_;
     501             :   CallInterfaceDescriptor descriptor_;
     502             :   Zone* zone_;
     503             : 
     504             :   bool allow_code_motion_;
     505             :   bool use_optimistic_licm_;
     506             :   bool depends_on_empty_array_proto_elements_;
     507             :   bool depends_on_string_length_overflow_;
     508             :   int type_change_checksum_;
     509             :   int maximum_environment_size_;
     510             :   int no_side_effects_scope_count_;
     511             :   bool disallow_adding_new_values_;
     512             : 
     513             :   DISALLOW_COPY_AND_ASSIGN(HGraph);
     514             : };
     515             : 
     516             : 
     517    57829054 : Zone* HBasicBlock::zone() const { return graph_->zone(); }
     518             : 
     519             : 
     520             : // Type of stack frame an environment might refer to.
     521             : enum FrameType {
     522             :   JS_FUNCTION,
     523             :   JS_CONSTRUCT,
     524             :   JS_GETTER,
     525             :   JS_SETTER,
     526             :   ARGUMENTS_ADAPTOR,
     527             :   TAIL_CALLER_FUNCTION,
     528             :   STUB
     529             : };
     530             : 
     531             : class HEnvironment final : public ZoneObject {
     532             :  public:
     533             :   HEnvironment(HEnvironment* outer,
     534             :                Scope* scope,
     535             :                Handle<JSFunction> closure,
     536             :                Zone* zone);
     537             : 
     538             :   HEnvironment(Zone* zone, int parameter_count);
     539             : 
     540      669483 :   HEnvironment* arguments_environment() {
     541      669483 :     return outer()->frame_type() == ARGUMENTS_ADAPTOR ? outer() : this;
     542             :   }
     543             : 
     544             :   // Simple accessors.
     545             :   Handle<JSFunction> closure() const { return closure_; }
     546             :   const ZoneList<HValue*>* values() const { return &values_; }
     547             :   const GrowableBitVector* assigned_variables() const {
     548             :     return &assigned_variables_;
     549             :   }
     550             :   FrameType frame_type() const { return frame_type_; }
     551             :   int parameter_count() const { return parameter_count_; }
     552             :   int specials_count() const { return specials_count_; }
     553             :   int local_count() const { return local_count_; }
     554             :   HEnvironment* outer() const { return outer_; }
     555             :   int pop_count() const { return pop_count_; }
     556             :   int push_count() const { return push_count_; }
     557             : 
     558             :   BailoutId ast_id() const { return ast_id_; }
     559     7832473 :   void set_ast_id(BailoutId id) { ast_id_ = id; }
     560             : 
     561             :   HEnterInlined* entry() const { return entry_; }
     562      106730 :   void set_entry(HEnterInlined* entry) { entry_ = entry; }
     563             : 
     564    94743807 :   int length() const { return values_.length(); }
     565             : 
     566    22155800 :   int first_expression_index() const {
     567    22155800 :     return parameter_count() + specials_count() + local_count();
     568             :   }
     569             : 
     570     2509090 :   int first_local_index() const {
     571     2509090 :     return parameter_count() + specials_count();
     572             :   }
     573             : 
     574       26641 :   void Bind(Variable* variable, HValue* value) {
     575         353 :     Bind(IndexFor(variable), value);
     576       26641 :   }
     577             : 
     578             :   void Bind(int index, HValue* value);
     579             : 
     580      769106 :   void BindContext(HValue* value) {
     581      132644 :     Bind(parameter_count(), value);
     582      636463 :   }
     583             : 
     584             :   HValue* Lookup(Variable* variable) const {
     585             :     return Lookup(IndexFor(variable));
     586             :   }
     587             : 
     588             :   HValue* Lookup(int index) const {
     589    37248254 :     HValue* result = values_[index];
     590             :     DCHECK(result != NULL);
     591             :     return result;
     592             :   }
     593             : 
     594    15057561 :   HValue* context() const {
     595             :     // Return first special.
     596             :     return Lookup(parameter_count());
     597             :   }
     598             : 
     599    10236447 :   void Push(HValue* value) {
     600             :     DCHECK(value != NULL);
     601    10236447 :     ++push_count_;
     602             :     values_.Add(value, zone());
     603             :   }
     604             : 
     605    10968869 :   HValue* Pop() {
     606             :     DCHECK(!ExpressionStackIsEmpty());
     607    10968869 :     if (push_count_ > 0) {
     608     7640805 :       --push_count_;
     609             :     } else {
     610     3328064 :       ++pop_count_;
     611             :     }
     612    21937639 :     return values_.RemoveLast();
     613             :   }
     614             : 
     615             :   void Drop(int count);
     616             : 
     617             :   HValue* Top() const { return ExpressionStackAt(0); }
     618             : 
     619             :   bool ExpressionStackIsEmpty() const;
     620             : 
     621             :   HValue* ExpressionStackAt(int index_from_top) const {
     622     4528690 :     int index = length() - index_from_top - 1;
     623             :     DCHECK(HasExpressionAt(index));
     624     9053068 :     return values_[index];
     625             :   }
     626             : 
     627             :   void SetExpressionStackAt(int index_from_top, HValue* value);
     628             :   HValue* RemoveExpressionStackAt(int index_from_top);
     629             : 
     630             :   void Print() const;
     631             : 
     632             :   HEnvironment* Copy() const;
     633             :   HEnvironment* CopyWithoutHistory() const;
     634             :   HEnvironment* CopyAsLoopHeader(HBasicBlock* block) const;
     635             : 
     636             :   // Create an "inlined version" of this environment, where the original
     637             :   // environment is the outer environment but the top expression stack
     638             :   // elements are moved to an inner environment as parameters.
     639             :   HEnvironment* CopyForInlining(Handle<JSFunction> target, int arguments,
     640             :                                 FunctionLiteral* function, HConstant* undefined,
     641             :                                 InliningKind inlining_kind,
     642             :                                 TailCallMode syntactic_tail_call_mode) const;
     643             : 
     644     1118007 :   HEnvironment* DiscardInlined(bool drop_extra) {
     645     3437858 :     HEnvironment* outer = outer_;
     646     1201844 :     while (outer->frame_type() != JS_FUNCTION &&
     647             :            outer->frame_type() != TAIL_CALLER_FUNCTION) {
     648       83837 :       outer = outer->outer_;
     649             :     }
     650     1118007 :     if (drop_extra) outer->Drop(1);
     651     1118007 :     if (outer->frame_type() == TAIL_CALLER_FUNCTION) {
     652         181 :       outer->ClearTailCallerMark();
     653             :     }
     654     1118007 :     return outer;
     655             :   }
     656             : 
     657             :   void AddIncomingEdge(HBasicBlock* block, HEnvironment* other);
     658             : 
     659             :   void ClearHistory() {
     660     5833217 :     pop_count_ = 0;
     661     5833217 :     push_count_ = 0;
     662             :     assigned_variables_.Clear();
     663             :   }
     664             : 
     665             :   void SetValueAt(int index, HValue* value) {
     666             :     DCHECK(index < length());
     667     2778758 :     values_[index] = value;
     668             :   }
     669             : 
     670             :   // Map a variable to an environment index.  Parameter indices are shifted
     671             :   // by 1 (receiver is parameter index -1 but environment index 0).
     672             :   // Stack-allocated local indices are shifted by the number of parameters.
     673     2870593 :   int IndexFor(Variable* variable) const {
     674             :     DCHECK(variable->IsStackAllocated());
     675             :     int shift = variable->IsParameter()
     676             :         ? 1
     677     2870593 :         : parameter_count_ + specials_count_;
     678     2870593 :     return variable->index() + shift;
     679             :   }
     680             : 
     681             :   bool is_local_index(int i) const {
     682     3785246 :     return i >= first_local_index() && i < first_expression_index();
     683             :   }
     684             : 
     685       14075 :   bool is_parameter_index(int i) const {
     686       28150 :     return i >= 0 && i < parameter_count();
     687             :   }
     688             : 
     689   112697176 :   bool is_special_index(int i) const {
     690   112697176 :     return i >= parameter_count() && i < parameter_count() + specials_count();
     691             :   }
     692             : 
     693             :   Zone* zone() const { return zone_; }
     694             : 
     695             :  private:
     696             :   HEnvironment(const HEnvironment* other, Zone* zone);
     697             : 
     698             :   HEnvironment(HEnvironment* outer,
     699             :                Handle<JSFunction> closure,
     700             :                FrameType frame_type,
     701             :                int arguments,
     702             :                Zone* zone);
     703             : 
     704             :   // Create an artificial stub environment (e.g. for argument adaptor or
     705             :   // constructor stub).
     706             :   HEnvironment* CreateStubEnvironment(HEnvironment* outer,
     707             :                                       Handle<JSFunction> target,
     708             :                                       FrameType frame_type,
     709             :                                       int arguments) const;
     710             : 
     711             :   // Marks current environment as tail caller by setting frame type to
     712             :   // TAIL_CALLER_FUNCTION.
     713             :   void MarkAsTailCaller();
     714             :   void ClearTailCallerMark();
     715             : 
     716             :   // True if index is included in the expression stack part of the environment.
     717             :   bool HasExpressionAt(int index) const;
     718             : 
     719             :   void Initialize(int parameter_count, int local_count, int stack_height);
     720             :   void Initialize(const HEnvironment* other);
     721             : 
     722             :   Handle<JSFunction> closure_;
     723             :   // Value array [parameters] [specials] [locals] [temporaries].
     724             :   ZoneList<HValue*> values_;
     725             :   GrowableBitVector assigned_variables_;
     726             :   FrameType frame_type_;
     727             :   int parameter_count_;
     728             :   int specials_count_;
     729             :   int local_count_;
     730             :   HEnvironment* outer_;
     731             :   HEnterInlined* entry_;
     732             :   int pop_count_;
     733             :   int push_count_;
     734             :   BailoutId ast_id_;
     735             :   Zone* zone_;
     736             : };
     737             : 
     738             : 
     739             : std::ostream& operator<<(std::ostream& os, const HEnvironment& env);
     740             : 
     741             : 
     742             : class HOptimizedGraphBuilder;
     743             : 
     744             : enum ArgumentsAllowedFlag {
     745             :   ARGUMENTS_NOT_ALLOWED,
     746             :   ARGUMENTS_ALLOWED,
     747             :   ARGUMENTS_FAKED
     748             : };
     749             : 
     750             : 
     751             : class HIfContinuation;
     752             : 
     753             : // This class is not BASE_EMBEDDED because our inlining implementation uses
     754             : // new and delete.
     755             : class AstContext {
     756             :  public:
     757             :   bool IsEffect() const { return kind_ == Expression::kEffect; }
     758             :   bool IsValue() const { return kind_ == Expression::kValue; }
     759             :   bool IsTest() const { return kind_ == Expression::kTest; }
     760             : 
     761             :   // 'Fill' this context with a hydrogen value.  The value is assumed to
     762             :   // have already been inserted in the instruction stream (or not need to
     763             :   // be, e.g., HPhi).  Call this function in tail position in the Visit
     764             :   // functions for expressions.
     765             :   virtual void ReturnValue(HValue* value) = 0;
     766             : 
     767             :   // Add a hydrogen instruction to the instruction stream (recording an
     768             :   // environment simulation if necessary) and then fill this context with
     769             :   // the instruction as value.
     770             :   virtual void ReturnInstruction(HInstruction* instr, BailoutId ast_id) = 0;
     771             : 
     772             :   // Finishes the current basic block and materialize a boolean for
     773             :   // value context, nothing for effect, generate a branch for test context.
     774             :   // Call this function in tail position in the Visit functions for
     775             :   // expressions.
     776             :   virtual void ReturnControl(HControlInstruction* instr, BailoutId ast_id) = 0;
     777             : 
     778             :   // Finishes the current basic block and materialize a boolean for
     779             :   // value context, nothing for effect, generate a branch for test context.
     780             :   // Call this function in tail position in the Visit functions for
     781             :   // expressions that use an IfBuilder.
     782             :   virtual void ReturnContinuation(HIfContinuation* continuation,
     783             :                                   BailoutId ast_id) = 0;
     784             : 
     785      106415 :   void set_typeof_mode(TypeofMode typeof_mode) { typeof_mode_ = typeof_mode; }
     786             :   TypeofMode typeof_mode() { return typeof_mode_; }
     787             : 
     788             :  protected:
     789             :   AstContext(HOptimizedGraphBuilder* owner, Expression::Context kind);
     790             :   virtual ~AstContext();
     791             : 
     792             :   HOptimizedGraphBuilder* owner() const { return owner_; }
     793             : 
     794             :   inline Zone* zone() const;
     795             : 
     796             :   // We want to be able to assert, in a context-specific way, that the stack
     797             :   // height makes sense when the context is filled.
     798             : #ifdef DEBUG
     799             :   int original_length_;
     800             : #endif
     801             : 
     802             :  private:
     803             :   HOptimizedGraphBuilder* owner_;
     804             :   Expression::Context kind_;
     805             :   AstContext* outer_;
     806             :   TypeofMode typeof_mode_;
     807             : };
     808             : 
     809             : 
     810             : class EffectContext final : public AstContext {
     811             :  public:
     812             :   explicit EffectContext(HOptimizedGraphBuilder* owner)
     813      923364 :       : AstContext(owner, Expression::kEffect) {
     814             :   }
     815             :   ~EffectContext() override;
     816             : 
     817             :   void ReturnValue(HValue* value) override;
     818             :   void ReturnInstruction(HInstruction* instr, BailoutId ast_id) override;
     819             :   void ReturnControl(HControlInstruction* instr, BailoutId ast_id) override;
     820             :   void ReturnContinuation(HIfContinuation* continuation,
     821             :                           BailoutId ast_id) override;
     822             : };
     823             : 
     824             : 
     825             : class ValueContext final : public AstContext {
     826             :  public:
     827             :   ValueContext(HOptimizedGraphBuilder* owner, ArgumentsAllowedFlag flag)
     828     5359101 :       : AstContext(owner, Expression::kValue), flag_(flag) {
     829             :   }
     830             :   ~ValueContext() override;
     831             : 
     832             :   void ReturnValue(HValue* value) override;
     833             :   void ReturnInstruction(HInstruction* instr, BailoutId ast_id) override;
     834             :   void ReturnControl(HControlInstruction* instr, BailoutId ast_id) override;
     835             :   void ReturnContinuation(HIfContinuation* continuation,
     836             :                           BailoutId ast_id) override;
     837             : 
     838             :   bool arguments_allowed() { return flag_ == ARGUMENTS_ALLOWED; }
     839             : 
     840             :  private:
     841             :   ArgumentsAllowedFlag flag_;
     842             : };
     843             : 
     844             : 
     845     1050593 : class TestContext final : public AstContext {
     846             :  public:
     847             :   TestContext(HOptimizedGraphBuilder* owner,
     848             :               Expression* condition,
     849             :               HBasicBlock* if_true,
     850             :               HBasicBlock* if_false)
     851             :       : AstContext(owner, Expression::kTest),
     852             :         condition_(condition),
     853             :         if_true_(if_true),
     854     1050593 :         if_false_(if_false) {
     855             :   }
     856             : 
     857             :   void ReturnValue(HValue* value) override;
     858             :   void ReturnInstruction(HInstruction* instr, BailoutId ast_id) override;
     859             :   void ReturnControl(HControlInstruction* instr, BailoutId ast_id) override;
     860             :   void ReturnContinuation(HIfContinuation* continuation,
     861             :                           BailoutId ast_id) override;
     862             : 
     863             :   static TestContext* cast(AstContext* context) {
     864             :     DCHECK(context->IsTest());
     865             :     return reinterpret_cast<TestContext*>(context);
     866             :   }
     867             : 
     868             :   Expression* condition() const { return condition_; }
     869             :   HBasicBlock* if_true() const { return if_true_; }
     870             :   HBasicBlock* if_false() const { return if_false_; }
     871             : 
     872             :  private:
     873             :   // Build the shared core part of the translation unpacking a value into
     874             :   // control flow.
     875             :   void BuildBranch(HValue* value);
     876             : 
     877             :   Expression* condition_;
     878             :   HBasicBlock* if_true_;
     879             :   HBasicBlock* if_false_;
     880             : };
     881             : 
     882             : 
     883             : class FunctionState final {
     884             :  public:
     885             :   FunctionState(HOptimizedGraphBuilder* owner, CompilationInfo* info,
     886             :                 InliningKind inlining_kind, int inlining_id,
     887             :                 TailCallMode tail_call_mode);
     888             :   ~FunctionState();
     889             : 
     890             :   CompilationInfo* compilation_info() { return compilation_info_; }
     891             :   AstContext* call_context() { return call_context_; }
     892             :   InliningKind inlining_kind() const { return inlining_kind_; }
     893             :   HBasicBlock* function_return() { return function_return_; }
     894             :   TestContext* test_context() { return test_context_; }
     895       19395 :   void ClearInlinedTestContext() {
     896       19395 :     delete test_context_;
     897       19395 :     test_context_ = NULL;
     898       19395 :   }
     899             : 
     900             :   FunctionState* outer() { return outer_; }
     901             : 
     902             :   TailCallMode ComputeTailCallMode(TailCallMode tail_call_mode) const {
     903      766698 :     if (tail_call_mode_ == TailCallMode::kDisallow) return tail_call_mode_;
     904             :     return tail_call_mode;
     905             :   }
     906             : 
     907             :   HEnterInlined* entry() { return entry_; }
     908      107436 :   void set_entry(HEnterInlined* entry) { entry_ = entry; }
     909             : 
     910             :   HArgumentsObject* arguments_object() { return arguments_object_; }
     911             :   void set_arguments_object(HArgumentsObject* arguments_object) {
     912             :     arguments_object_ = arguments_object;
     913             :   }
     914             : 
     915             :   HArgumentsElements* arguments_elements() { return arguments_elements_; }
     916             :   void set_arguments_elements(HArgumentsElements* arguments_elements) {
     917         231 :     arguments_elements_ = arguments_elements;
     918             :   }
     919             : 
     920         340 :   bool arguments_pushed() { return arguments_elements() != NULL; }
     921             : 
     922             :   int inlining_id() const { return inlining_id_; }
     923             : 
     924          62 :   void IncrementInDoExpressionScope() { do_expression_scope_count_++; }
     925          62 :   void DecrementInDoExpressionScope() { do_expression_scope_count_--; }
     926             :   bool IsInsideDoExpressionScope() { return do_expression_scope_count_ > 0; }
     927             : 
     928             :  private:
     929             :   HOptimizedGraphBuilder* owner_;
     930             : 
     931             :   CompilationInfo* compilation_info_;
     932             : 
     933             :   // During function inlining, expression context of the call being
     934             :   // inlined. NULL when not inlining.
     935             :   AstContext* call_context_;
     936             : 
     937             :   // The kind of call which is currently being inlined.
     938             :   InliningKind inlining_kind_;
     939             : 
     940             :   // Defines whether the calls with TailCallMode::kAllow in the function body
     941             :   // can be generated as tail calls.
     942             :   TailCallMode tail_call_mode_;
     943             : 
     944             :   // When inlining in an effect or value context, this is the return block.
     945             :   // It is NULL otherwise.  When inlining in a test context, there are a
     946             :   // pair of return blocks in the context.  When not inlining, there is no
     947             :   // local return point.
     948             :   HBasicBlock* function_return_;
     949             : 
     950             :   // When inlining a call in a test context, a context containing a pair of
     951             :   // return blocks.  NULL in all other cases.
     952             :   TestContext* test_context_;
     953             : 
     954             :   // When inlining HEnterInlined instruction corresponding to the function
     955             :   // entry.
     956             :   HEnterInlined* entry_;
     957             : 
     958             :   HArgumentsObject* arguments_object_;
     959             :   HArgumentsElements* arguments_elements_;
     960             : 
     961             :   int inlining_id_;
     962             :   SourcePosition outer_source_position_;
     963             : 
     964             :   int do_expression_scope_count_;
     965             : 
     966             :   FunctionState* outer_;
     967             : };
     968             : 
     969             : 
     970             : class HIfContinuation final {
     971             :  public:
     972             :   HIfContinuation()
     973             :     : continuation_captured_(false),
     974             :       true_branch_(NULL),
     975         843 :       false_branch_(NULL) {}
     976             :   HIfContinuation(HBasicBlock* true_branch,
     977             :                   HBasicBlock* false_branch)
     978             :       : continuation_captured_(true), true_branch_(true_branch),
     979        5184 :         false_branch_(false_branch) {}
     980             :   ~HIfContinuation() { DCHECK(!continuation_captured_); }
     981             : 
     982             :   void Capture(HBasicBlock* true_branch,
     983             :                HBasicBlock* false_branch) {
     984             :     DCHECK(!continuation_captured_);
     985         843 :     true_branch_ = true_branch;
     986         843 :     false_branch_ = false_branch;
     987         843 :     continuation_captured_ = true;
     988             :   }
     989             : 
     990             :   void Continue(HBasicBlock** true_branch,
     991             :                 HBasicBlock** false_branch) {
     992             :     DCHECK(continuation_captured_);
     993        6027 :     *true_branch = true_branch_;
     994        6027 :     *false_branch = false_branch_;
     995        6027 :     continuation_captured_ = false;
     996             :   }
     997             : 
     998             :   bool IsTrueReachable() { return true_branch_ != NULL; }
     999             :   bool IsFalseReachable() { return false_branch_ != NULL; }
    1000           0 :   bool TrueAndFalseReachable() {
    1001           0 :     return IsTrueReachable() || IsFalseReachable();
    1002             :   }
    1003             : 
    1004             :   HBasicBlock* true_branch() const { return true_branch_; }
    1005             :   HBasicBlock* false_branch() const { return false_branch_; }
    1006             : 
    1007             :  private:
    1008             :   bool continuation_captured_;
    1009             :   HBasicBlock* true_branch_;
    1010             :   HBasicBlock* false_branch_;
    1011             : };
    1012             : 
    1013             : 
    1014             : class HAllocationMode final BASE_EMBEDDED {
    1015             :  public:
    1016             :   explicit HAllocationMode(Handle<AllocationSite> feedback_site)
    1017             :       : current_site_(NULL), feedback_site_(feedback_site),
    1018             :         pretenure_flag_(NOT_TENURED) {}
    1019             :   explicit HAllocationMode(HValue* current_site)
    1020        7708 :       : current_site_(current_site), pretenure_flag_(NOT_TENURED) {}
    1021             :   explicit HAllocationMode(PretenureFlag pretenure_flag)
    1022       11710 :       : current_site_(NULL), pretenure_flag_(pretenure_flag) {}
    1023             :   HAllocationMode()
    1024      780728 :       : current_site_(NULL), pretenure_flag_(NOT_TENURED) {}
    1025             : 
    1026             :   HValue* current_site() const { return current_site_; }
    1027             :   Handle<AllocationSite> feedback_site() const { return feedback_site_; }
    1028             : 
    1029        3800 :   bool CreateAllocationMementos() const WARN_UNUSED_RESULT {
    1030             :     return current_site() != NULL;
    1031             :   }
    1032             : 
    1033             :   PretenureFlag GetPretenureMode() const WARN_UNUSED_RESULT {
    1034       72322 :     if (!feedback_site().is_null()) return feedback_site()->GetPretenureMode();
    1035       15085 :     return pretenure_flag_;
    1036             :   }
    1037             : 
    1038             :  private:
    1039             :   HValue* current_site_;
    1040             :   Handle<AllocationSite> feedback_site_;
    1041             :   PretenureFlag pretenure_flag_;
    1042             : };
    1043             : 
    1044             : 
    1045             : class HGraphBuilder {
    1046             :  public:
    1047             :   explicit HGraphBuilder(CompilationInfo* info,
    1048             :                          CallInterfaceDescriptor descriptor,
    1049             :                          bool track_positions)
    1050             :       : info_(info),
    1051             :         descriptor_(descriptor),
    1052             :         graph_(NULL),
    1053             :         current_block_(NULL),
    1054      286915 :         scope_(info->scope()),
    1055             :         position_(SourcePosition::Unknown()),
    1056      860745 :         track_positions_(track_positions) {}
    1057       23483 :   virtual ~HGraphBuilder() {}
    1058             : 
    1059             :   Scope* scope() const { return scope_; }
    1060      899418 :   void set_scope(Scope* scope) { scope_ = scope; }
    1061             : 
    1062             :   HBasicBlock* current_block() const { return current_block_; }
    1063     5282215 :   void set_current_block(HBasicBlock* block) { current_block_ = block; }
    1064    35658961 :   HEnvironment* environment() const {
    1065    35764416 :     return current_block()->last_environment();
    1066             :   }
    1067    23435080 :   Zone* zone() const { return info_->zone(); }
    1068             :   HGraph* graph() const { return graph_; }
    1069     8309981 :   Isolate* isolate() const { return graph_->isolate(); }
    1070             :   CompilationInfo* top_info() { return info_; }
    1071             : 
    1072             :   HGraph* CreateGraph();
    1073             : 
    1074             :   // Bailout environment manipulation.
    1075    14715176 :   void Push(HValue* value) { environment()->Push(value); }
    1076     5177261 :   HValue* Pop() { return environment()->Pop(); }
    1077             : 
    1078             :   virtual HValue* context() = 0;
    1079             : 
    1080             :   // Adding instructions.
    1081             :   HInstruction* AddInstruction(HInstruction* instr);
    1082             :   void FinishCurrentBlock(HControlInstruction* last);
    1083             :   void FinishExitCurrentBlock(HControlInstruction* instruction);
    1084             : 
    1085             :   void Goto(HBasicBlock* from,
    1086             :             HBasicBlock* target,
    1087             :             FunctionState* state = NULL,
    1088             :             bool add_simulate = true) {
    1089     2795308 :     from->Goto(target, source_position(), state, add_simulate);
    1090             :   }
    1091             :   void Goto(HBasicBlock* target,
    1092             :             FunctionState* state = NULL,
    1093      632143 :             bool add_simulate = true) {
    1094             :     Goto(current_block(), target, state, add_simulate);
    1095             :   }
    1096             :   void GotoNoSimulate(HBasicBlock* from, HBasicBlock* target) {
    1097             :     Goto(from, target, NULL, false);
    1098             :   }
    1099             :   void GotoNoSimulate(HBasicBlock* target) {
    1100             :     Goto(target, NULL, false);
    1101             :   }
    1102             :   void AddLeaveInlined(HBasicBlock* block,
    1103             :                        HValue* return_value,
    1104             :                        FunctionState* state) {
    1105       39834 :     block->AddLeaveInlined(return_value, state, source_position());
    1106             :   }
    1107       36233 :   void AddLeaveInlined(HValue* return_value, FunctionState* state) {
    1108             :     return AddLeaveInlined(current_block(), return_value, state);
    1109             :   }
    1110             : 
    1111             :   template <class I>
    1112             :   HInstruction* NewUncasted() {
    1113             :     return I::New(isolate(), zone(), context());
    1114             :   }
    1115             : 
    1116             :   template <class I>
    1117     1306424 :   I* New() {
    1118     1306424 :     return I::New(isolate(), zone(), context());
    1119             :   }
    1120             : 
    1121             :   template<class I>
    1122             :   HInstruction* AddUncasted() { return AddInstruction(NewUncasted<I>());}
    1123             : 
    1124             :   template<class I>
    1125     1105560 :   I* Add() { return AddInstructionTyped(New<I>());}
    1126             : 
    1127             :   template<class I, class P1>
    1128      657487 :   HInstruction* NewUncasted(P1 p1) {
    1129      656978 :     return I::New(isolate(), zone(), context(), p1);
    1130             :   }
    1131             : 
    1132             :   template <class I, class P1>
    1133    14952743 :   I* New(P1 p1) {
    1134    14952742 :     return I::New(isolate(), zone(), context(), p1);
    1135             :   }
    1136             : 
    1137             :   template<class I, class P1>
    1138      327980 :   HInstruction* AddUncasted(P1 p1) {
    1139      327980 :     HInstruction* result = AddInstruction(NewUncasted<I>(p1));
    1140             :     // Specializations must have their parameters properly casted
    1141             :     // to avoid landing here.
    1142             :     DCHECK(!result->IsReturn() && !result->IsSimulate() &&
    1143             :            !result->IsDeoptimize());
    1144      327980 :     return result;
    1145             :   }
    1146             : 
    1147             :   template<class I, class P1>
    1148     5647720 :   I* Add(P1 p1) {
    1149     5221015 :     I* result = AddInstructionTyped(New<I>(p1));
    1150             :     // Specializations must have their parameters properly casted
    1151             :     // to avoid landing here.
    1152             :     DCHECK(!result->IsReturn() && !result->IsSimulate() &&
    1153             :            !result->IsDeoptimize());
    1154     5647723 :     return result;
    1155             :   }
    1156             : 
    1157             :   template<class I, class P1, class P2>
    1158     1559835 :   HInstruction* NewUncasted(P1 p1, P2 p2) {
    1159     1040256 :     return I::New(isolate(), zone(), context(), p1, p2);
    1160             :   }
    1161             : 
    1162             :   template<class I, class P1, class P2>
    1163     5894179 :   I* New(P1 p1, P2 p2) {
    1164     5715210 :     return I::New(isolate(), zone(), context(), p1, p2);
    1165             :   }
    1166             : 
    1167             :   template<class I, class P1, class P2>
    1168      489802 :   HInstruction* AddUncasted(P1 p1, P2 p2) {
    1169      489802 :     HInstruction* result = AddInstruction(NewUncasted<I>(p1, p2));
    1170             :     // Specializations must have their parameters properly casted
    1171             :     // to avoid landing here.
    1172             :     DCHECK(!result->IsSimulate());
    1173      489802 :     return result;
    1174             :   }
    1175             : 
    1176             :   template<class I, class P1, class P2>
    1177     1955216 :   I* Add(P1 p1, P2 p2) {
    1178     1955216 :     I* result = AddInstructionTyped(New<I>(p1, p2));
    1179             :     // Specializations must have their parameters properly casted
    1180             :     // to avoid landing here.
    1181             :     DCHECK(!result->IsSimulate());
    1182     1955215 :     return result;
    1183             :   }
    1184             : 
    1185             :   template<class I, class P1, class P2, class P3>
    1186      480333 :   HInstruction* NewUncasted(P1 p1, P2 p2, P3 p3) {
    1187      320222 :     return I::New(isolate(), zone(), context(), p1, p2, p3);
    1188             :   }
    1189             : 
    1190             :   template<class I, class P1, class P2, class P3>
    1191     2645744 :   I* New(P1 p1, P2 p2, P3 p3) {
    1192     2646170 :     return I::New(isolate(), zone(), context(), p1, p2, p3);
    1193             :   }
    1194             : 
    1195             :   template<class I, class P1, class P2, class P3>
    1196      158361 :   HInstruction* AddUncasted(P1 p1, P2 p2, P3 p3) {
    1197      158361 :     return AddInstruction(NewUncasted<I>(p1, p2, p3));
    1198             :   }
    1199             : 
    1200             :   template<class I, class P1, class P2, class P3>
    1201      812726 :   I* Add(P1 p1, P2 p2, P3 p3) {
    1202     1625452 :     return AddInstructionTyped(New<I>(p1, p2, p3));
    1203             :   }
    1204             : 
    1205             :   template<class I, class P1, class P2, class P3, class P4>
    1206        1570 :   HInstruction* NewUncasted(P1 p1, P2 p2, P3 p3, P4 p4) {
    1207        1570 :     return I::New(isolate(), zone(), context(), p1, p2, p3, p4);
    1208             :   }
    1209             : 
    1210             :   template<class I, class P1, class P2, class P3, class P4>
    1211      657836 :   I* New(P1 p1, P2 p2, P3 p3, P4 p4) {
    1212      657836 :     return I::New(isolate(), zone(), context(), p1, p2, p3, p4);
    1213             :   }
    1214             : 
    1215             :   template<class I, class P1, class P2, class P3, class P4>
    1216         785 :   HInstruction* AddUncasted(P1 p1, P2 p2, P3 p3, P4 p4) {
    1217         785 :     return AddInstruction(NewUncasted<I>(p1, p2, p3, p4));
    1218             :   }
    1219             : 
    1220             :   template<class I, class P1, class P2, class P3, class P4>
    1221      127312 :   I* Add(P1 p1, P2 p2, P3 p3, P4 p4) {
    1222      254624 :     return AddInstructionTyped(New<I>(p1, p2, p3, p4));
    1223             :   }
    1224             : 
    1225             :   template<class I, class P1, class P2, class P3, class P4, class P5>
    1226       80643 :   HInstruction* NewUncasted(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) {
    1227       53762 :     return I::New(isolate(), zone(), context(), p1, p2, p3, p4, p5);
    1228             :   }
    1229             : 
    1230             :   template<class I, class P1, class P2, class P3, class P4, class P5>
    1231     2099876 :   I* New(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) {
    1232     2099876 :     return I::New(isolate(), zone(), context(), p1, p2, p3, p4, p5);
    1233             :   }
    1234             : 
    1235             :   template<class I, class P1, class P2, class P3, class P4, class P5>
    1236       26881 :   HInstruction* AddUncasted(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) {
    1237       26881 :     return AddInstruction(NewUncasted<I>(p1, p2, p3, p4, p5));
    1238             :   }
    1239             : 
    1240             :   template<class I, class P1, class P2, class P3, class P4, class P5>
    1241       33792 :   I* Add(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) {
    1242       67584 :     return AddInstructionTyped(New<I>(p1, p2, p3, p4, p5));
    1243             :   }
    1244             : 
    1245             :   template<class I, class P1, class P2, class P3, class P4, class P5, class P6>
    1246         896 :   HInstruction* NewUncasted(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6) {
    1247         896 :     return I::New(isolate(), zone(), context(), p1, p2, p3, p4, p5, p6);
    1248             :   }
    1249             : 
    1250             :   template<class I, class P1, class P2, class P3, class P4, class P5, class P6>
    1251      188982 :   I* New(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6) {
    1252      188982 :     return I::New(isolate(), zone(), context(), p1, p2, p3, p4, p5, p6);
    1253             :   }
    1254             : 
    1255             :   template<class I, class P1, class P2, class P3, class P4, class P5, class P6>
    1256         448 :   HInstruction* AddUncasted(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6) {
    1257         448 :     return AddInstruction(NewUncasted<I>(p1, p2, p3, p4, p5, p6));
    1258             :   }
    1259             : 
    1260             :   template<class I, class P1, class P2, class P3, class P4, class P5, class P6>
    1261       86583 :   I* Add(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6) {
    1262      173166 :     return AddInstructionTyped(New<I>(p1, p2, p3, p4, p5, p6));
    1263             :   }
    1264             : 
    1265             :   template<class I, class P1, class P2, class P3, class P4,
    1266             :       class P5, class P6, class P7>
    1267             :   HInstruction* NewUncasted(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7) {
    1268             :     return I::New(isolate(), zone(), context(), p1, p2, p3, p4, p5, p6, p7);
    1269             :   }
    1270             : 
    1271             :   template<class I, class P1, class P2, class P3, class P4,
    1272             :       class P5, class P6, class P7>
    1273             :       I* New(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7) {
    1274             :     return I::New(isolate(), zone(), context(), p1, p2, p3, p4, p5, p6, p7);
    1275             :   }
    1276             : 
    1277             :   template<class I, class P1, class P2, class P3,
    1278             :            class P4, class P5, class P6, class P7>
    1279             :   HInstruction* AddUncasted(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7) {
    1280             :     return AddInstruction(NewUncasted<I>(p1, p2, p3, p4, p5, p6, p7));
    1281             :   }
    1282             : 
    1283             :   template<class I, class P1, class P2, class P3,
    1284             :            class P4, class P5, class P6, class P7>
    1285             :   I* Add(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7) {
    1286             :     return AddInstructionTyped(New<I>(p1, p2, p3, p4, p5, p6, p7));
    1287             :   }
    1288             : 
    1289             :   template<class I, class P1, class P2, class P3, class P4,
    1290             :       class P5, class P6, class P7, class P8>
    1291             :   HInstruction* NewUncasted(P1 p1, P2 p2, P3 p3, P4 p4,
    1292             :                             P5 p5, P6 p6, P7 p7, P8 p8) {
    1293             :     return I::New(isolate(), zone(), context(), p1, p2, p3, p4, p5, p6, p7, p8);
    1294             :   }
    1295             : 
    1296             :   template<class I, class P1, class P2, class P3, class P4,
    1297             :       class P5, class P6, class P7, class P8>
    1298             :       I* New(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8) {
    1299             :     return I::New(isolate(), zone(), context(), p1, p2, p3, p4, p5, p6, p7, p8);
    1300             :   }
    1301             : 
    1302             :   template<class I, class P1, class P2, class P3, class P4,
    1303             :            class P5, class P6, class P7, class P8>
    1304             :   HInstruction* AddUncasted(P1 p1, P2 p2, P3 p3, P4 p4,
    1305             :                             P5 p5, P6 p6, P7 p7, P8 p8) {
    1306             :     return AddInstruction(NewUncasted<I>(p1, p2, p3, p4, p5, p6, p7, p8));
    1307             :   }
    1308             : 
    1309             :   template<class I, class P1, class P2, class P3, class P4,
    1310             :            class P5, class P6, class P7, class P8>
    1311             :   I* Add(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8) {
    1312             :     return AddInstructionTyped(New<I>(p1, p2, p3, p4, p5, p6, p7, p8));
    1313             :   }
    1314             : 
    1315             :   template <class I, class P1, class P2, class P3, class P4, class P5, class P6,
    1316             :             class P7, class P8, class P9>
    1317      214872 :   I* New(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8, P9 p9) {
    1318      107436 :     return I::New(isolate(), zone(), context(), p1, p2, p3, p4, p5, p6, p7, p8,
    1319      214872 :                   p9);
    1320             :   }
    1321             : 
    1322             :   template <class I, class P1, class P2, class P3, class P4, class P5, class P6,
    1323             :             class P7, class P8, class P9>
    1324             :   HInstruction* AddUncasted(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7,
    1325             :                             P8 p8, P9 p9) {
    1326             :     return AddInstruction(NewUncasted<I>(p1, p2, p3, p4, p5, p6, p7, p8, p9));
    1327             :   }
    1328             : 
    1329             :   template <class I, class P1, class P2, class P3, class P4, class P5, class P6,
    1330             :             class P7, class P8, class P9>
    1331      107436 :   I* Add(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8, P9 p9) {
    1332      214872 :     return AddInstructionTyped(New<I>(p1, p2, p3, p4, p5, p6, p7, p8, p9));
    1333             :   }
    1334             : 
    1335             :   void AddSimulate(BailoutId id, RemovableSimulate removable = FIXED_SIMULATE);
    1336             : 
    1337             :   // When initializing arrays, we'll unfold the loop if the number of elements
    1338             :   // is known at compile time and is <= kElementLoopUnrollThreshold.
    1339             :   static const int kElementLoopUnrollThreshold = 8;
    1340             : 
    1341             :  protected:
    1342             :   virtual bool BuildGraph() = 0;
    1343             : 
    1344             :   HBasicBlock* CreateBasicBlock(HEnvironment* env);
    1345             :   HBasicBlock* CreateLoopHeaderBlock();
    1346             : 
    1347             :   template <class BitFieldClass>
    1348        1088 :   HValue* BuildDecodeField(HValue* encoded_field) {
    1349        1088 :     HValue* mask_value = Add<HConstant>(static_cast<int>(BitFieldClass::kMask));
    1350             :     HValue* masked_field =
    1351        1088 :         AddUncasted<HBitwise>(Token::BIT_AND, encoded_field, mask_value);
    1352             :     return AddUncasted<HShr>(masked_field,
    1353        1088 :         Add<HConstant>(static_cast<int>(BitFieldClass::kShift)));
    1354             :   }
    1355             : 
    1356             :   HValue* BuildGetElementsKind(HValue* object);
    1357             : 
    1358             :   HValue* BuildEnumLength(HValue* map);
    1359             : 
    1360             :   HValue* BuildCheckHeapObject(HValue* object);
    1361             :   HValue* BuildCheckString(HValue* string);
    1362             :   HValue* BuildWrapReceiver(HValue* object, HValue* function);
    1363             : 
    1364             :   // Building common constructs
    1365             :   HValue* BuildCheckForCapacityGrow(HValue* object,
    1366             :                                     HValue* elements,
    1367             :                                     ElementsKind kind,
    1368             :                                     HValue* length,
    1369             :                                     HValue* key,
    1370             :                                     bool is_js_array,
    1371             :                                     PropertyAccessType access_type);
    1372             : 
    1373             :   HValue* BuildCheckAndGrowElementsCapacity(HValue* object, HValue* elements,
    1374             :                                             ElementsKind kind, HValue* length,
    1375             :                                             HValue* capacity, HValue* key);
    1376             : 
    1377             :   HValue* BuildCopyElementsOnWrite(HValue* object,
    1378             :                                    HValue* elements,
    1379             :                                    ElementsKind kind,
    1380             :                                    HValue* length);
    1381             : 
    1382             :   void BuildTransitionElementsKind(HValue* object,
    1383             :                                    HValue* map,
    1384             :                                    ElementsKind from_kind,
    1385             :                                    ElementsKind to_kind,
    1386             :                                    bool is_jsarray);
    1387             : 
    1388             :   HValue* BuildNumberToString(HValue* object, AstType* type);
    1389             :   HValue* BuildToNumber(HValue* input);
    1390             :   HValue* BuildToObject(HValue* receiver);
    1391             : 
    1392             :   HValue* BuildUncheckedDictionaryElementLoad(HValue* receiver,
    1393             :                                               HValue* elements, HValue* key,
    1394             :                                               HValue* hash);
    1395             : 
    1396             :   // ES6 section 7.4.7 CreateIterResultObject ( value, done )
    1397             :   HValue* BuildCreateIterResultObject(HValue* value, HValue* done);
    1398             : 
    1399             :   // Allocates a new object according with the given allocation properties.
    1400             :   HAllocate* BuildAllocate(HValue* object_size,
    1401             :                            HType type,
    1402             :                            InstanceType instance_type,
    1403             :                            HAllocationMode allocation_mode);
    1404             :   // Computes the sum of two string lengths, taking care of overflow handling.
    1405             :   HValue* BuildAddStringLengths(HValue* left_length, HValue* right_length);
    1406             :   // Creates a cons string using the two input strings.
    1407             :   HValue* BuildCreateConsString(HValue* length,
    1408             :                                 HValue* left,
    1409             :                                 HValue* right,
    1410             :                                 HAllocationMode allocation_mode);
    1411             :   // Copies characters from one sequential string to another.
    1412             :   void BuildCopySeqStringChars(HValue* src,
    1413             :                                HValue* src_offset,
    1414             :                                String::Encoding src_encoding,
    1415             :                                HValue* dst,
    1416             :                                HValue* dst_offset,
    1417             :                                String::Encoding dst_encoding,
    1418             :                                HValue* length);
    1419             : 
    1420             :   // Align an object size to object alignment boundary
    1421             :   HValue* BuildObjectSizeAlignment(HValue* unaligned_size, int header_size);
    1422             : 
    1423             :   // Both operands are non-empty strings.
    1424             :   HValue* BuildUncheckedStringAdd(HValue* left,
    1425             :                                   HValue* right,
    1426             :                                   HAllocationMode allocation_mode);
    1427             :   // Add two strings using allocation mode, validating type feedback.
    1428             :   HValue* BuildStringAdd(HValue* left,
    1429             :                          HValue* right,
    1430             :                          HAllocationMode allocation_mode);
    1431             : 
    1432             :   HInstruction* BuildUncheckedMonomorphicElementAccess(
    1433             :       HValue* checked_object,
    1434             :       HValue* key,
    1435             :       HValue* val,
    1436             :       bool is_js_array,
    1437             :       ElementsKind elements_kind,
    1438             :       PropertyAccessType access_type,
    1439             :       LoadKeyedHoleMode load_mode,
    1440             :       KeyedAccessStoreMode store_mode);
    1441             : 
    1442             :   HInstruction* AddElementAccess(
    1443             :       HValue* elements, HValue* checked_key, HValue* val, HValue* dependency,
    1444             :       HValue* backing_store_owner, ElementsKind elements_kind,
    1445             :       PropertyAccessType access_type,
    1446             :       LoadKeyedHoleMode load_mode = NEVER_RETURN_HOLE);
    1447             : 
    1448             :   HInstruction* AddLoadStringInstanceType(HValue* string);
    1449             :   HInstruction* AddLoadStringLength(HValue* string);
    1450             :   HInstruction* BuildLoadStringLength(HValue* string);
    1451       14465 :   HStoreNamedField* AddStoreMapConstant(HValue* object, Handle<Map> map) {
    1452             :     return Add<HStoreNamedField>(object, HObjectAccess::ForMap(),
    1453       14465 :                                  Add<HConstant>(map));
    1454             :   }
    1455             :   HLoadNamedField* AddLoadMap(HValue* object,
    1456             :                               HValue* dependency = NULL);
    1457             :   HLoadNamedField* AddLoadElements(HValue* object,
    1458             :                                    HValue* dependency = NULL);
    1459             : 
    1460             :   bool MatchRotateRight(HValue* left,
    1461             :                         HValue* right,
    1462             :                         HValue** operand,
    1463             :                         HValue** shift_amount);
    1464             : 
    1465             :   HValue* BuildBinaryOperation(Token::Value op, HValue* left, HValue* right,
    1466             :                                AstType* left_type, AstType* right_type,
    1467             :                                AstType* result_type, Maybe<int> fixed_right_arg,
    1468             :                                HAllocationMode allocation_mode,
    1469             :                                BailoutId opt_id = BailoutId::None());
    1470             : 
    1471             :   HLoadNamedField* AddLoadFixedArrayLength(HValue *object,
    1472             :                                            HValue *dependency = NULL);
    1473             : 
    1474             :   HLoadNamedField* AddLoadArrayLength(HValue *object,
    1475             :                                       ElementsKind kind,
    1476             :                                       HValue *dependency = NULL);
    1477             : 
    1478             :   HValue* AddLoadJSBuiltin(int context_index);
    1479             : 
    1480             :   HValue* EnforceNumberType(HValue* number, AstType* expected);
    1481             :   HValue* TruncateToNumber(HValue* value, AstType** expected);
    1482             : 
    1483             :   void FinishExitWithHardDeoptimization(DeoptimizeReason reason);
    1484             : 
    1485             :   void AddIncrementCounter(StatsCounter* counter);
    1486             : 
    1487             :   class IfBuilder final {
    1488             :    public:
    1489             :     // If using this constructor, Initialize() must be called explicitly!
    1490             :     IfBuilder();
    1491             : 
    1492             :     explicit IfBuilder(HGraphBuilder* builder);
    1493             :     IfBuilder(HGraphBuilder* builder,
    1494             :               HIfContinuation* continuation);
    1495             : 
    1496             :     ~IfBuilder() {
    1497       99375 :       if (!finished_) End();
    1498             :     }
    1499             : 
    1500             :     void Initialize(HGraphBuilder* builder);
    1501             : 
    1502             :     template<class Condition>
    1503        7351 :     Condition* If(HValue *p) {
    1504        7351 :       Condition* compare = builder()->New<Condition>(p);
    1505        7351 :       AddCompare(compare);
    1506        7351 :       return compare;
    1507             :     }
    1508             : 
    1509             :     template<class Condition, class P2>
    1510       26986 :     Condition* If(HValue* p1, P2 p2) {
    1511       26986 :       Condition* compare = builder()->New<Condition>(p1, p2);
    1512       26986 :       AddCompare(compare);
    1513       26986 :       return compare;
    1514             :     }
    1515             : 
    1516             :     template<class Condition, class P2, class P3>
    1517       93631 :     Condition* If(HValue* p1, P2 p2, P3 p3) {
    1518       93631 :       Condition* compare = builder()->New<Condition>(p1, p2, p3);
    1519       93631 :       AddCompare(compare);
    1520       93631 :       return compare;
    1521             :     }
    1522             : 
    1523             :     template<class Condition>
    1524             :     Condition* IfNot(HValue* p) {
    1525        1390 :       Condition* compare = If<Condition>(p);
    1526        1390 :       compare->Not();
    1527             :       return compare;
    1528             :     }
    1529             : 
    1530             :     template<class Condition, class P2>
    1531             :     Condition* IfNot(HValue* p1, P2 p2) {
    1532         271 :       Condition* compare = If<Condition>(p1, p2);
    1533         271 :       compare->Not();
    1534             :       return compare;
    1535             :     }
    1536             : 
    1537             :     template<class Condition, class P2, class P3>
    1538             :     Condition* IfNot(HValue* p1, P2 p2, P3 p3) {
    1539         133 :       Condition* compare = If<Condition>(p1, p2, p3);
    1540         133 :       compare->Not();
    1541             :       return compare;
    1542             :     }
    1543             : 
    1544             :     template<class Condition>
    1545             :     Condition* OrIf(HValue *p) {
    1546             :       Or();
    1547             :       return If<Condition>(p);
    1548             :     }
    1549             : 
    1550             :     template<class Condition, class P2>
    1551             :     Condition* OrIf(HValue* p1, P2 p2) {
    1552         170 :       Or();
    1553         170 :       return If<Condition>(p1, p2);
    1554             :     }
    1555             : 
    1556             :     template<class Condition, class P2, class P3>
    1557             :     Condition* OrIf(HValue* p1, P2 p2, P3 p3) {
    1558             :       Or();
    1559             :       return If<Condition>(p1, p2, p3);
    1560             :     }
    1561             : 
    1562             :     template<class Condition>
    1563             :     Condition* AndIf(HValue *p) {
    1564             :       And();
    1565             :       return If<Condition>(p);
    1566             :     }
    1567             : 
    1568             :     template<class Condition, class P2>
    1569             :     Condition* AndIf(HValue* p1, P2 p2) {
    1570         103 :       And();
    1571         103 :       return If<Condition>(p1, p2);
    1572             :     }
    1573             : 
    1574             :     template<class Condition, class P2, class P3>
    1575             :     Condition* AndIf(HValue* p1, P2 p2, P3 p3) {
    1576          85 :       And();
    1577          85 :       return If<Condition>(p1, p2, p3);
    1578             :     }
    1579             : 
    1580             :     void Or();
    1581             :     void And();
    1582             : 
    1583             :     // Captures the current state of this IfBuilder in the specified
    1584             :     // continuation and ends this IfBuilder.
    1585             :     void CaptureContinuation(HIfContinuation* continuation);
    1586             : 
    1587             :     // Joins the specified continuation from this IfBuilder and ends this
    1588             :     // IfBuilder. This appends a Goto instruction from the true branch of
    1589             :     // this IfBuilder to the true branch of the continuation unless the
    1590             :     // true branch of this IfBuilder is already finished. And vice versa
    1591             :     // for the false branch.
    1592             :     //
    1593             :     // The basic idea is as follows: You have several nested IfBuilder's
    1594             :     // that you want to join based on two possible outcomes (i.e. success
    1595             :     // and failure, or whatever). You can do this easily using this method
    1596             :     // now, for example:
    1597             :     //
    1598             :     //   HIfContinuation cont(graph()->CreateBasicBlock(),
    1599             :     //                        graph()->CreateBasicBlock());
    1600             :     //   ...
    1601             :     //     IfBuilder if_whatever(this);
    1602             :     //     if_whatever.If<Condition>(arg);
    1603             :     //     if_whatever.Then();
    1604             :     //     ...
    1605             :     //     if_whatever.Else();
    1606             :     //     ...
    1607             :     //     if_whatever.JoinContinuation(&cont);
    1608             :     //   ...
    1609             :     //     IfBuilder if_something(this);
    1610             :     //     if_something.If<Condition>(arg1, arg2);
    1611             :     //     if_something.Then();
    1612             :     //     ...
    1613             :     //     if_something.Else();
    1614             :     //     ...
    1615             :     //     if_something.JoinContinuation(&cont);
    1616             :     //   ...
    1617             :     //   IfBuilder if_finally(this, &cont);
    1618             :     //   if_finally.Then();
    1619             :     //   // continues after then code of if_whatever or if_something.
    1620             :     //   ...
    1621             :     //   if_finally.Else();
    1622             :     //   // continues after else code of if_whatever or if_something.
    1623             :     //   ...
    1624             :     //   if_finally.End();
    1625             :     void JoinContinuation(HIfContinuation* continuation);
    1626             : 
    1627             :     void Then();
    1628             :     void Else();
    1629             :     void End();
    1630             :     void EndUnreachable();
    1631             : 
    1632             :     void Deopt(DeoptimizeReason reason);
    1633             :     void ThenDeopt(DeoptimizeReason reason) {
    1634        1675 :       Then();
    1635        1675 :       Deopt(reason);
    1636             :     }
    1637         496 :     void ElseDeopt(DeoptimizeReason reason) {
    1638           0 :       Else();
    1639         496 :       Deopt(reason);
    1640         496 :     }
    1641             : 
    1642             :     void Return(HValue* value);
    1643             : 
    1644             :    private:
    1645             :     void InitializeDontCreateBlocks(HGraphBuilder* builder);
    1646             : 
    1647             :     HControlInstruction* AddCompare(HControlInstruction* compare);
    1648             : 
    1649             :     HGraphBuilder* builder() const {
    1650             :       DCHECK(builder_ != NULL);  // Have you called "Initialize"?
    1651             :       return builder_;
    1652             :     }
    1653             : 
    1654             :     void AddMergeAtJoinBlock(bool deopt);
    1655             : 
    1656             :     void Finish();
    1657             :     void Finish(HBasicBlock** then_continuation,
    1658             :                 HBasicBlock** else_continuation);
    1659             : 
    1660             :     class MergeAtJoinBlock : public ZoneObject {
    1661             :      public:
    1662             :       MergeAtJoinBlock(HBasicBlock* block,
    1663             :                        bool deopt,
    1664             :                        MergeAtJoinBlock* next)
    1665             :         : block_(block),
    1666             :           deopt_(deopt),
    1667      216314 :           next_(next) {}
    1668             :       HBasicBlock* block_;
    1669             :       bool deopt_;
    1670             :       MergeAtJoinBlock* next_;
    1671             :     };
    1672             : 
    1673             :     HGraphBuilder* builder_;
    1674             :     bool finished_ : 1;
    1675             :     bool did_then_ : 1;
    1676             :     bool did_else_ : 1;
    1677             :     bool did_else_if_ : 1;
    1678             :     bool did_and_ : 1;
    1679             :     bool did_or_ : 1;
    1680             :     bool captured_ : 1;
    1681             :     bool needs_compare_ : 1;
    1682             :     bool pending_merge_block_ : 1;
    1683             :     HBasicBlock* first_true_block_;
    1684             :     HBasicBlock* first_false_block_;
    1685             :     HBasicBlock* split_edge_merge_block_;
    1686             :     MergeAtJoinBlock* merge_at_join_blocks_;
    1687             :     int normal_merge_at_join_block_count_;
    1688             :     int deopt_merge_at_join_block_count_;
    1689             :   };
    1690             : 
    1691             :   class LoopBuilder final {
    1692             :    public:
    1693             :     enum Direction {
    1694             :       kPreIncrement,
    1695             :       kPostIncrement,
    1696             :       kPreDecrement,
    1697             :       kPostDecrement,
    1698             :       kWhileTrue
    1699             :     };
    1700             : 
    1701             :     explicit LoopBuilder(HGraphBuilder* builder);  // while (true) {...}
    1702             :     LoopBuilder(HGraphBuilder* builder,
    1703             :                 HValue* context,
    1704             :                 Direction direction);
    1705             :     LoopBuilder(HGraphBuilder* builder,
    1706             :                 HValue* context,
    1707             :                 Direction direction,
    1708             :                 HValue* increment_amount);
    1709             : 
    1710             :     ~LoopBuilder() {
    1711             :       DCHECK(finished_);
    1712             :     }
    1713             : 
    1714             :     HValue* BeginBody(
    1715             :         HValue* initial,
    1716             :         HValue* terminating,
    1717             :         Token::Value token);
    1718             : 
    1719             :     void BeginBody(int drop_count);
    1720             : 
    1721             :     void Break();
    1722             : 
    1723             :     void EndBody();
    1724             : 
    1725             :    private:
    1726             :     void Initialize(HGraphBuilder* builder, HValue* context,
    1727             :                     Direction direction, HValue* increment_amount);
    1728       15546 :     Zone* zone() { return builder_->zone(); }
    1729             : 
    1730             :     HGraphBuilder* builder_;
    1731             :     HValue* context_;
    1732             :     HValue* increment_amount_;
    1733             :     HInstruction* increment_;
    1734             :     HPhi* phi_;
    1735             :     HBasicBlock* header_block_;
    1736             :     HBasicBlock* body_block_;
    1737             :     HBasicBlock* exit_block_;
    1738             :     HBasicBlock* exit_trampoline_block_;
    1739             :     Direction direction_;
    1740             :     bool finished_;
    1741             :   };
    1742             : 
    1743             :   HValue* BuildNewElementsCapacity(HValue* old_capacity);
    1744             : 
    1745             :   HValue* BuildCalculateElementsSize(ElementsKind kind,
    1746             :                                      HValue* capacity);
    1747             :   HAllocate* AllocateJSArrayObject(AllocationSiteMode mode);
    1748             :   HConstant* EstablishElementsAllocationSize(ElementsKind kind, int capacity);
    1749             : 
    1750             :   HAllocate* BuildAllocateElements(ElementsKind kind, HValue* size_in_bytes);
    1751             : 
    1752             :   void BuildInitializeElementsHeader(HValue* elements,
    1753             :                                      ElementsKind kind,
    1754             :                                      HValue* capacity);
    1755             : 
    1756             :   // Build allocation and header initialization code for respective successor
    1757             :   // of FixedArrayBase.
    1758             :   HValue* BuildAllocateAndInitializeArray(ElementsKind kind, HValue* capacity);
    1759             : 
    1760             :   // |array| must have been allocated with enough room for
    1761             :   // 1) the JSArray and 2) an AllocationMemento if mode requires it.
    1762             :   // If the |elements| value provided is NULL then the array elements storage
    1763             :   // is initialized with empty array.
    1764             :   void BuildJSArrayHeader(HValue* array,
    1765             :                           HValue* array_map,
    1766             :                           HValue* elements,
    1767             :                           AllocationSiteMode mode,
    1768             :                           ElementsKind elements_kind,
    1769             :                           HValue* allocation_site_payload,
    1770             :                           HValue* length_field);
    1771             : 
    1772             :   HValue* BuildGrowElementsCapacity(HValue* object,
    1773             :                                     HValue* elements,
    1774             :                                     ElementsKind kind,
    1775             :                                     ElementsKind new_kind,
    1776             :                                     HValue* length,
    1777             :                                     HValue* new_capacity);
    1778             : 
    1779             :   void BuildFillElementsWithValue(HValue* elements,
    1780             :                                   ElementsKind elements_kind,
    1781             :                                   HValue* from,
    1782             :                                   HValue* to,
    1783             :                                   HValue* value);
    1784             : 
    1785             :   void BuildFillElementsWithHole(HValue* elements,
    1786             :                                  ElementsKind elements_kind,
    1787             :                                  HValue* from,
    1788             :                                  HValue* to);
    1789             : 
    1790             :   void BuildCopyProperties(HValue* from_properties, HValue* to_properties,
    1791             :                            HValue* length, HValue* capacity);
    1792             : 
    1793             :   void BuildCopyElements(HValue* from_elements,
    1794             :                          ElementsKind from_elements_kind,
    1795             :                          HValue* to_elements,
    1796             :                          ElementsKind to_elements_kind,
    1797             :                          HValue* length,
    1798             :                          HValue* capacity);
    1799             : 
    1800             :   HValue* BuildElementIndexHash(HValue* index);
    1801             : 
    1802             :   void BuildCreateAllocationMemento(HValue* previous_object,
    1803             :                                     HValue* previous_object_size,
    1804             :                                     HValue* payload);
    1805             : 
    1806             :   HInstruction* BuildConstantMapCheck(Handle<JSObject> constant,
    1807             :                                       bool ensure_no_elements = false);
    1808             :   HInstruction* BuildCheckPrototypeMaps(Handle<JSObject> prototype,
    1809             :                                         Handle<JSObject> holder,
    1810             :                                         bool ensure_no_elements = false);
    1811             : 
    1812             :   HInstruction* BuildGetNativeContext(HValue* closure);
    1813             :   HInstruction* BuildGetNativeContext();
    1814             : 
    1815             :   // Builds a loop version if |depth| is specified or unrolls the loop to
    1816             :   // |depth_value| iterations otherwise.
    1817             :   HValue* BuildGetParentContext(HValue* depth, int depth_value);
    1818             : 
    1819             :   HInstruction* BuildGetArrayFunction();
    1820             :   HValue* BuildArrayBufferViewFieldAccessor(HValue* object,
    1821             :                                             HValue* checked_object,
    1822             :                                             FieldIndex index);
    1823             : 
    1824             : 
    1825             :  protected:
    1826             :   void SetSourcePosition(int position) {
    1827     1710844 :     if (position != kNoSourcePosition) {
    1828             :       position_.SetScriptOffset(position);
    1829             :     }
    1830             :     // Otherwise position remains unknown.
    1831             :   }
    1832             : 
    1833             :   void EnterInlinedSource(int inlining_id) {
    1834         125 :     if (is_tracking_positions()) {
    1835             :       position_.SetInliningId(inlining_id);
    1836             :     }
    1837             :   }
    1838             : 
    1839             :   // Convert the given absolute offset from the start of the script to
    1840             :   // the SourcePosition assuming that this position corresponds to the
    1841             :   // same function as position_.
    1842             :   SourcePosition ScriptPositionToSourcePosition(int position) {
    1843      863354 :     if (position == kNoSourcePosition) {
    1844             :       return SourcePosition::Unknown();
    1845             :     }
    1846             :     return SourcePosition(position, position_.InliningId());
    1847             :   }
    1848             : 
    1849             :   SourcePosition source_position() { return position_; }
    1850        1841 :   void set_source_position(SourcePosition position) { position_ = position; }
    1851             : 
    1852             :   bool is_tracking_positions() { return track_positions_; }
    1853             : 
    1854             :   HValue* BuildAllocateEmptyArrayBuffer(HValue* byte_length);
    1855             :   template <typename ViewClass>
    1856             :   void BuildArrayBufferViewInitialization(HValue* obj,
    1857             :                                           HValue* buffer,
    1858             :                                           HValue* byte_offset,
    1859             :                                           HValue* byte_length);
    1860             : 
    1861             :  private:
    1862             :   HGraphBuilder();
    1863             : 
    1864             :   template <class I>
    1865             :   I* AddInstructionTyped(I* instr) {
    1866     9323562 :     return I::cast(AddInstruction(instr));
    1867             :   }
    1868             : 
    1869             :   CompilationInfo* info_;
    1870             :   CallInterfaceDescriptor descriptor_;
    1871             :   HGraph* graph_;
    1872             :   HBasicBlock* current_block_;
    1873             :   Scope* scope_;
    1874             :   SourcePosition position_;
    1875             :   bool track_positions_;
    1876             : };
    1877             : 
    1878             : template <>
    1879      641932 : inline HDeoptimize* HGraphBuilder::Add<HDeoptimize>(
    1880     1170110 :     DeoptimizeReason reason, Deoptimizer::BailoutType type) {
    1881      641932 :   if (type == Deoptimizer::SOFT) {
    1882      624483 :     isolate()->counters()->soft_deopts_requested()->Increment();
    1883      624483 :     if (FLAG_always_opt) return NULL;
    1884             :   }
    1885      187692 :   if (current_block()->IsDeoptimizing()) return NULL;
    1886             :   HBasicBlock* after_deopt_block = CreateBasicBlock(
    1887      187692 :       current_block()->last_environment());
    1888      187692 :   HDeoptimize* instr = New<HDeoptimize>(reason, type, after_deopt_block);
    1889      187692 :   if (type == Deoptimizer::SOFT) {
    1890      170243 :     isolate()->counters()->soft_deopts_inserted()->Increment();
    1891             :   }
    1892      187692 :   FinishCurrentBlock(instr);
    1893             :   set_current_block(after_deopt_block);
    1894      187692 :   return instr;
    1895             : }
    1896             : 
    1897             : template <>
    1898             : inline HInstruction* HGraphBuilder::AddUncasted<HDeoptimize>(
    1899             :     DeoptimizeReason reason, Deoptimizer::BailoutType type) {
    1900             :   return Add<HDeoptimize>(reason, type);
    1901             : }
    1902             : 
    1903             : 
    1904             : template<>
    1905     2122285 : inline HSimulate* HGraphBuilder::Add<HSimulate>(
    1906             :     BailoutId id,
    1907     2122285 :     RemovableSimulate removable) {
    1908     2122285 :   HSimulate* instr = current_block()->CreateSimulate(id, removable);
    1909     2122286 :   AddInstruction(instr);
    1910     2122286 :   return instr;
    1911             : }
    1912             : 
    1913             : 
    1914             : template<>
    1915             : inline HSimulate* HGraphBuilder::Add<HSimulate>(
    1916             :     BailoutId id) {
    1917      475767 :   return Add<HSimulate>(id, FIXED_SIMULATE);
    1918             : }
    1919             : 
    1920             : 
    1921             : template<>
    1922             : inline HInstruction* HGraphBuilder::AddUncasted<HSimulate>(BailoutId id) {
    1923             :   return Add<HSimulate>(id, FIXED_SIMULATE);
    1924             : }
    1925             : 
    1926             : 
    1927             : template<>
    1928      327980 : inline HReturn* HGraphBuilder::Add<HReturn>(HValue* value) {
    1929      327980 :   int num_parameters = graph()->info()->num_parameters();
    1930      327980 :   HValue* params = AddUncasted<HConstant>(num_parameters);
    1931      327980 :   HReturn* return_instruction = New<HReturn>(value, params);
    1932      327980 :   FinishExitCurrentBlock(return_instruction);
    1933      327980 :   return return_instruction;
    1934             : }
    1935             : 
    1936             : 
    1937             : template<>
    1938             : inline HReturn* HGraphBuilder::Add<HReturn>(HConstant* value) {
    1939       44081 :   return Add<HReturn>(static_cast<HValue*>(value));
    1940             : }
    1941             : 
    1942             : template<>
    1943             : inline HInstruction* HGraphBuilder::AddUncasted<HReturn>(HValue* value) {
    1944             :   return Add<HReturn>(value);
    1945             : }
    1946             : 
    1947             : 
    1948             : template<>
    1949             : inline HInstruction* HGraphBuilder::AddUncasted<HReturn>(HConstant* value) {
    1950             :   return Add<HReturn>(value);
    1951             : }
    1952             : 
    1953             : 
    1954             : template<>
    1955       57332 : inline HCallRuntime* HGraphBuilder::Add<HCallRuntime>(
    1956             :     const Runtime::Function* c_function,
    1957       57332 :     int argument_count) {
    1958       57332 :   HCallRuntime* instr = New<HCallRuntime>(c_function, argument_count);
    1959       57332 :   if (graph()->info()->IsStub()) {
    1960             :     // When compiling code stubs, we don't want to save all double registers
    1961             :     // upon entry to the stub, but instead have the call runtime instruction
    1962             :     // save the double registers only on-demand (in the fallback case).
    1963             :     instr->set_save_doubles(kSaveFPRegs);
    1964             :   }
    1965       57332 :   AddInstruction(instr);
    1966       57332 :   return instr;
    1967             : }
    1968             : 
    1969             : 
    1970             : template<>
    1971             : inline HInstruction* HGraphBuilder::AddUncasted<HCallRuntime>(
    1972             :     Handle<String> name,
    1973             :     const Runtime::Function* c_function,
    1974             :     int argument_count) {
    1975             :   return Add<HCallRuntime>(c_function, argument_count);
    1976             : }
    1977             : 
    1978             : 
    1979             : template <>
    1980      426705 : inline HParameter* HGraphBuilder::New<HParameter>(unsigned index) {
    1981      426705 :   return HParameter::New(isolate(), zone(), nullptr, index);
    1982             : }
    1983             : 
    1984             : 
    1985             : template <>
    1986             : inline HParameter* HGraphBuilder::New<HParameter>(
    1987             :     unsigned index, HParameter::ParameterKind kind) {
    1988             :   return HParameter::New(isolate(), zone(), nullptr, index, kind);
    1989             : }
    1990             : 
    1991             : 
    1992             : template <>
    1993             : inline HParameter* HGraphBuilder::New<HParameter>(
    1994             :     unsigned index, HParameter::ParameterKind kind, Representation r) {
    1995             :   return HParameter::New(isolate(), zone(), nullptr, index, kind, r);
    1996             : }
    1997             : 
    1998             : 
    1999             : template <>
    2000      263433 : inline HPrologue* HGraphBuilder::New<HPrologue>() {
    2001      263433 :   return HPrologue::New(zone());
    2002             : }
    2003             : 
    2004             : 
    2005             : template <>
    2006      289347 : inline HContext* HGraphBuilder::New<HContext>() {
    2007      289347 :   return HContext::New(zone());
    2008             : }
    2009             : 
    2010             : // This AstVistor is not final, and provides the AstVisitor methods as virtual
    2011             : // methods so they can be specialized by subclasses.
    2012           0 : class HOptimizedGraphBuilder : public HGraphBuilder,
    2013             :                                public AstVisitor<HOptimizedGraphBuilder> {
    2014             :  public:
    2015             :   // A class encapsulating (lazily-allocated) break and continue blocks for
    2016             :   // a breakable statement.  Separated from BreakAndContinueScope so that it
    2017             :   // can have a separate lifetime.
    2018             :   class BreakAndContinueInfo final BASE_EMBEDDED {
    2019             :    public:
    2020             :     explicit BreakAndContinueInfo(BreakableStatement* target,
    2021             :                                   Scope* scope,
    2022             :                                   int drop_extra = 0)
    2023             :         : target_(target),
    2024             :           break_block_(NULL),
    2025             :           continue_block_(NULL),
    2026             :           scope_(scope),
    2027      735644 :           drop_extra_(drop_extra) {
    2028             :     }
    2029             : 
    2030             :     BreakableStatement* target() { return target_; }
    2031             :     HBasicBlock* break_block() { return break_block_; }
    2032        3762 :     void set_break_block(HBasicBlock* block) { break_block_ = block; }
    2033             :     HBasicBlock* continue_block() { return continue_block_; }
    2034        1527 :     void set_continue_block(HBasicBlock* block) { continue_block_ = block; }
    2035             :     Scope* scope() { return scope_; }
    2036             :     int drop_extra() { return drop_extra_; }
    2037             : 
    2038             :    private:
    2039             :     BreakableStatement* target_;
    2040             :     HBasicBlock* break_block_;
    2041             :     HBasicBlock* continue_block_;
    2042             :     Scope* scope_;
    2043             :     int drop_extra_;
    2044             :   };
    2045             : 
    2046             :   // A helper class to maintain a stack of current BreakAndContinueInfo
    2047             :   // structures mirroring BreakableStatement nesting.
    2048             :   class BreakAndContinueScope final BASE_EMBEDDED {
    2049             :    public:
    2050             :     BreakAndContinueScope(BreakAndContinueInfo* info,
    2051      735644 :                           HOptimizedGraphBuilder* owner)
    2052     1471288 :         : info_(info), owner_(owner), next_(owner->break_scope()) {
    2053             :       owner->set_break_scope(this);
    2054             :     }
    2055             : 
    2056      735644 :     ~BreakAndContinueScope() { owner_->set_break_scope(next_); }
    2057             : 
    2058             :     BreakAndContinueInfo* info() { return info_; }
    2059             :     HOptimizedGraphBuilder* owner() { return owner_; }
    2060             :     BreakAndContinueScope* next() { return next_; }
    2061             : 
    2062             :     // Search the break stack for a break or continue target.
    2063             :     enum BreakType { BREAK, CONTINUE };
    2064             :     HBasicBlock* Get(BreakableStatement* stmt, BreakType type,
    2065             :                      Scope** scope, int* drop_extra);
    2066             : 
    2067             :    private:
    2068             :     BreakAndContinueInfo* info_;
    2069             :     HOptimizedGraphBuilder* owner_;
    2070             :     BreakAndContinueScope* next_;
    2071             :   };
    2072             : 
    2073             :   explicit HOptimizedGraphBuilder(CompilationInfo* info, bool track_positions);
    2074             : 
    2075             :   bool BuildGraph() override;
    2076             : 
    2077             :   // Simple accessors.
    2078             :   BreakAndContinueScope* break_scope() const { return break_scope_; }
    2079     1471288 :   void set_break_scope(BreakAndContinueScope* head) { break_scope_ = head; }
    2080             : 
    2081    28750048 :   HValue* context() override { return environment()->context(); }
    2082             : 
    2083             :   HOsrBuilder* osr() const { return osr_; }
    2084             : 
    2085             :   void Bailout(BailoutReason reason);
    2086             : 
    2087             :   HBasicBlock* CreateJoin(HBasicBlock* first,
    2088             :                           HBasicBlock* second,
    2089             :                           BailoutId join_id);
    2090             : 
    2091             :   FunctionState* function_state() const { return function_state_; }
    2092             : 
    2093             :   void VisitDeclarations(Declaration::List* declarations);
    2094             : 
    2095             :   AstTypeBounds* bounds() { return &bounds_; }
    2096             : 
    2097      263433 :   void* operator new(size_t size, Zone* zone) { return zone->New(size); }
    2098             :   void operator delete(void* pointer, Zone* zone) { }
    2099             :   void operator delete(void* pointer) { }
    2100             : 
    2101    43065520 :   DEFINE_AST_VISITOR_SUBCLASS_MEMBERS();
    2102             : 
    2103             :  protected:
    2104             :   // Forward declarations for inner scope classes.
    2105             :   class SubgraphScope;
    2106             : 
    2107             :   static const int kMaxCallPolymorphism = 4;
    2108             :   static const int kMaxLoadPolymorphism = 4;
    2109             :   static const int kMaxStorePolymorphism = 4;
    2110             : 
    2111             :   // Even in the 'unlimited' case we have to have some limit in order not to
    2112             :   // overflow the stack.
    2113             :   static const int kUnlimitedMaxInlinedSourceSize = 100000;
    2114             :   static const int kUnlimitedMaxInlinedNodes = 10000;
    2115             :   static const int kUnlimitedMaxInlinedNodesCumulative = 10000;
    2116             : 
    2117             :   // Maximum depth and total number of elements and properties for literal
    2118             :   // graphs to be considered for fast deep-copying. The limit is chosen to
    2119             :   // match the maximum number of inobject properties, to ensure that the
    2120             :   // performance of using object literals is not worse than using constructor
    2121             :   // functions, see crbug.com/v8/6211 for details.
    2122             :   static const int kMaxFastLiteralDepth = 3;
    2123             :   static const int kMaxFastLiteralProperties =
    2124             :       (JSObject::kMaxInstanceSize - JSObject::kHeaderSize) >> kPointerSizeLog2;
    2125             : 
    2126             :   // Simple accessors.
    2127      478304 :   void set_function_state(FunctionState* state) { function_state_ = state; }
    2128             : 
    2129             :   AstContext* ast_context() const { return ast_context_; }
    2130    14627323 :   void set_ast_context(AstContext* context) { ast_context_ = context; }
    2131             : 
    2132             :   // Accessors forwarded to the function state.
    2133     3955703 :   CompilationInfo* current_info() const {
    2134     3955725 :     return function_state()->compilation_info();
    2135             :   }
    2136        7071 :   AstContext* call_context() const {
    2137      614809 :     return function_state()->call_context();
    2138             :   }
    2139       94355 :   HBasicBlock* function_return() const {
    2140      239102 :     return function_state()->function_return();
    2141             :   }
    2142      107548 :   TestContext* inlined_test_context() const {
    2143      107562 :     return function_state()->test_context();
    2144             :   }
    2145             :   Handle<JSFunction> current_closure() const {
    2146             :     return current_info()->closure();
    2147             :   }
    2148             :   Handle<SharedFunctionInfo> current_shared_info() const {
    2149             :     return current_info()->shared_info();
    2150             :   }
    2151             :   FeedbackVector* current_feedback_vector() const {
    2152             :     return current_closure()->feedback_vector();
    2153             :   }
    2154             :   void ClearInlinedTestContext() {
    2155       19395 :     function_state()->ClearInlinedTestContext();
    2156             :   }
    2157       82545 :   LanguageMode function_language_mode() {
    2158       82545 :     return function_state()->compilation_info()->parse_info()->language_mode();
    2159             :   }
    2160             : 
    2161             : #define FOR_EACH_HYDROGEN_INTRINSIC(F) \
    2162             :   F(IsSmi)                             \
    2163             :   F(IsArray)                           \
    2164             :   F(IsTypedArray)                      \
    2165             :   F(IsJSProxy)                         \
    2166             :   F(Call)                              \
    2167             :   F(ToInteger)                         \
    2168             :   F(ToObject)                          \
    2169             :   F(ToString)                          \
    2170             :   F(ToLength)                          \
    2171             :   F(ToNumber)                          \
    2172             :   F(IsJSReceiver)                      \
    2173             :   F(DebugBreakInOptimizedCode)         \
    2174             :   F(StringCharCodeAt)                  \
    2175             :   F(SubString)                         \
    2176             :   F(DebugIsActive)                     \
    2177             :   /* Typed Arrays */                   \
    2178             :   F(MaxSmi)                            \
    2179             :   F(TypedArrayMaxSizeInHeap)           \
    2180             :   F(ArrayBufferViewGetByteLength)      \
    2181             :   F(ArrayBufferViewGetByteOffset)      \
    2182             :   F(ArrayBufferViewWasNeutered)        \
    2183             :   F(TypedArrayGetLength)               \
    2184             :   /* ArrayBuffer */                    \
    2185             :   F(ArrayBufferGetByteLength)          \
    2186             :   /* ES6 Collections */                \
    2187             :   F(MapClear)                          \
    2188             :   F(MapInitialize)                     \
    2189             :   F(SetClear)                          \
    2190             :   F(SetInitialize)                     \
    2191             :   F(FixedArrayGet)                     \
    2192             :   F(FixedArraySet)                     \
    2193             :   F(JSCollectionGetTable)              \
    2194             :   F(StringGetRawHashField)             \
    2195             :   F(TheHole)                           \
    2196             :   /* ES6 Iterators */                  \
    2197             :   F(CreateIterResultObject)            \
    2198             :   /* Arrays */                         \
    2199             :   F(HasFastPackedElements)
    2200             : 
    2201             : #define GENERATOR_DECLARATION(Name) void Generate##Name(CallRuntime* call);
    2202             :   FOR_EACH_HYDROGEN_INTRINSIC(GENERATOR_DECLARATION)
    2203             : #undef GENERATOR_DECLARATION
    2204             : 
    2205             :   void VisitDelete(UnaryOperation* expr);
    2206             :   void VisitVoid(UnaryOperation* expr);
    2207             :   void VisitTypeof(UnaryOperation* expr);
    2208             :   void VisitNot(UnaryOperation* expr);
    2209             : 
    2210             :   void VisitComma(BinaryOperation* expr);
    2211             :   void VisitLogicalExpression(BinaryOperation* expr);
    2212             :   void VisitArithmeticExpression(BinaryOperation* expr);
    2213             : 
    2214             :   void VisitLoopBody(IterationStatement* stmt, BailoutId stack_check_id,
    2215             :                      HBasicBlock* loop_entry);
    2216             : 
    2217             :   void BuildForInBody(ForInStatement* stmt, Variable* each_var,
    2218             :                       HValue* enumerable);
    2219             : 
    2220             :   // Create a back edge in the flow graph.  body_exit is the predecessor
    2221             :   // block and loop_entry is the successor block.  loop_successor is the
    2222             :   // block where control flow exits the loop normally (e.g., via failure of
    2223             :   // the condition) and break_block is the block where control flow breaks
    2224             :   // from the loop.  All blocks except loop_entry can be NULL.  The return
    2225             :   // value is the new successor block which is the join of loop_successor
    2226             :   // and break_block, or NULL.
    2227             :   HBasicBlock* CreateLoop(IterationStatement* statement,
    2228             :                           HBasicBlock* loop_entry,
    2229             :                           HBasicBlock* body_exit,
    2230             :                           HBasicBlock* loop_successor,
    2231             :                           HBasicBlock* break_block);
    2232             : 
    2233             :   // Build a loop entry
    2234             :   HBasicBlock* BuildLoopEntry();
    2235             : 
    2236             :   // Builds a loop entry respectful of OSR requirements
    2237             :   HBasicBlock* BuildLoopEntry(IterationStatement* statement);
    2238             : 
    2239             :   HBasicBlock* JoinContinue(IterationStatement* statement,
    2240             :                             BailoutId continue_id, HBasicBlock* exit_block,
    2241             :                             HBasicBlock* continue_block);
    2242             : 
    2243             :   HValue* Top() const { return environment()->Top(); }
    2244             :   void Drop(int n) { environment()->Drop(n); }
    2245        1078 :   void Bind(Variable* var, HValue* value) { environment()->Bind(var, value); }
    2246             :   bool IsEligibleForEnvironmentLivenessAnalysis(Variable* var,
    2247             :                                                 int index,
    2248             :                                                 HEnvironment* env) {
    2249     2618106 :     if (!FLAG_analyze_environment_liveness) return false;
    2250             :     // Zapping parameters isn't safe because function.arguments can inspect them
    2251             :     // at any time.
    2252             :     return env->is_local_index(index);
    2253             :   }
    2254      537628 :   void BindIfLive(Variable* var, HValue* value) {
    2255             :     HEnvironment* env = environment();
    2256             :     int index = env->IndexFor(var);
    2257             :     env->Bind(index, value);
    2258      537628 :     if (IsEligibleForEnvironmentLivenessAnalysis(var, index, env)) {
    2259             :       HEnvironmentMarker* bind =
    2260      506800 :           Add<HEnvironmentMarker>(HEnvironmentMarker::BIND, index);
    2261             :       USE(bind);
    2262             : #ifdef DEBUG
    2263             :       bind->set_closure(env->closure());
    2264             : #endif
    2265             :     }
    2266      537628 :   }
    2267     2080478 :   HValue* LookupAndMakeLive(Variable* var) {
    2268             :     HEnvironment* env = environment();
    2269             :     int index = env->IndexFor(var);
    2270     2080478 :     if (IsEligibleForEnvironmentLivenessAnalysis(var, index, env)) {
    2271             :       HEnvironmentMarker* lookup =
    2272      779732 :           Add<HEnvironmentMarker>(HEnvironmentMarker::LOOKUP, index);
    2273             :       USE(lookup);
    2274             : #ifdef DEBUG
    2275             :       lookup->set_closure(env->closure());
    2276             : #endif
    2277             :     }
    2278     2080477 :     return env->Lookup(index);
    2279             :   }
    2280             : 
    2281             :   // The value of the arguments object is allowed in some but not most value
    2282             :   // contexts.  (It's allowed in all effect contexts and disallowed in all
    2283             :   // test contexts.)
    2284             :   void VisitForValue(Expression* expr,
    2285             :                      ArgumentsAllowedFlag flag = ARGUMENTS_NOT_ALLOWED);
    2286             :   void VisitForTypeOf(Expression* expr);
    2287             :   void VisitForEffect(Expression* expr);
    2288             :   void VisitForControl(Expression* expr,
    2289             :                        HBasicBlock* true_block,
    2290             :                        HBasicBlock* false_block);
    2291             : 
    2292             :   // Visit a list of expressions from left to right, each in a value context.
    2293             :   void VisitExpressions(ZoneList<Expression*>* exprs);
    2294             :   void VisitExpressions(ZoneList<Expression*>* exprs,
    2295             :                         ArgumentsAllowedFlag flag);
    2296             : 
    2297             :   // Remove the arguments from the bailout environment and emit instructions
    2298             :   // to push them as outgoing parameters.
    2299             :   template <class Instruction> HInstruction* PreProcessCall(Instruction* call);
    2300             :   void PushArgumentsFromEnvironment(int count);
    2301             : 
    2302             :   void SetUpScope(DeclarationScope* scope);
    2303             :   void VisitStatements(ZoneList<Statement*>* statements);
    2304             : 
    2305             : #define DECLARE_VISIT(type) virtual void Visit##type(type* node);
    2306             :   AST_NODE_LIST(DECLARE_VISIT)
    2307             : #undef DECLARE_VISIT
    2308             : 
    2309             :  private:
    2310             :   bool CanInlineGlobalPropertyAccess(Variable* var, LookupIterator* it,
    2311             :                                      PropertyAccessType access_type);
    2312             : 
    2313             :   bool CanInlineGlobalPropertyAccess(LookupIterator* it,
    2314             :                                      PropertyAccessType access_type);
    2315             : 
    2316             :   void InlineGlobalPropertyLoad(LookupIterator* it, BailoutId ast_id);
    2317             :   HInstruction* InlineGlobalPropertyStore(LookupIterator* it, HValue* value,
    2318             :                                           BailoutId ast_id);
    2319             : 
    2320             :   void EnsureArgumentsArePushedForAccess();
    2321             :   bool TryArgumentsAccess(Property* expr);
    2322             : 
    2323             :   // Shared code for .call and .apply optimizations.
    2324             :   void HandleIndirectCall(Call* expr, HValue* function, int arguments_count);
    2325             :   // Try to optimize indirect calls such as fun.apply(receiver, arguments)
    2326             :   // or fun.call(...).
    2327             :   bool TryIndirectCall(Call* expr);
    2328             :   void BuildFunctionApply(Call* expr);
    2329             :   void BuildFunctionCall(Call* expr);
    2330             : 
    2331             :   template <class T>
    2332             :   bool TryHandleArrayCall(T* expr, HValue* function);
    2333             : 
    2334             :   enum ArrayIndexOfMode { kFirstIndexOf, kLastIndexOf };
    2335             :   HValue* BuildArrayIndexOf(HValue* receiver,
    2336             :                             HValue* search_element,
    2337             :                             ElementsKind kind,
    2338             :                             ArrayIndexOfMode mode);
    2339             : 
    2340             :   HValue* ImplicitReceiverFor(HValue* function,
    2341             :                               Handle<JSFunction> target);
    2342             : 
    2343             :   int InliningAstSize(Handle<JSFunction> target);
    2344             :   bool TryInline(Handle<JSFunction> target, int arguments_count,
    2345             :                  HValue* implicit_return_value, BailoutId ast_id,
    2346             :                  BailoutId return_id, InliningKind inlining_kind,
    2347             :                  TailCallMode syntactic_tail_call_mode);
    2348             : 
    2349             :   bool TryInlineCall(Call* expr);
    2350             :   bool TryInlineConstruct(CallNew* expr, HValue* implicit_return_value);
    2351             :   bool TryInlineGetter(Handle<Object> getter, Handle<Map> receiver_map,
    2352             :                        BailoutId ast_id, BailoutId return_id);
    2353             :   bool TryInlineSetter(Handle<Object> setter, Handle<Map> receiver_map,
    2354             :                        BailoutId id, BailoutId assignment_id,
    2355             :                        HValue* implicit_return_value);
    2356             :   bool TryInlineIndirectCall(Handle<JSFunction> function, Call* expr,
    2357             :                              int arguments_count);
    2358             :   bool TryInlineBuiltinGetterCall(Handle<JSFunction> function,
    2359             :                                   Handle<Map> receiver_map, BailoutId ast_id);
    2360             :   bool TryInlineBuiltinMethodCall(Handle<JSFunction> function,
    2361             :                                   Handle<Map> receiver_map, BailoutId ast_id,
    2362             :                                   int args_count_no_receiver);
    2363             :   bool TryInlineBuiltinFunctionCall(Call* expr);
    2364             :   enum ApiCallType {
    2365             :     kCallApiFunction,
    2366             :     kCallApiMethod,
    2367             :     kCallApiGetter,
    2368             :     kCallApiSetter
    2369             :   };
    2370             :   bool TryInlineApiMethodCall(Call* expr,
    2371             :                               HValue* receiver,
    2372             :                               SmallMapList* receiver_types);
    2373             :   bool TryInlineApiFunctionCall(Call* expr, HValue* receiver);
    2374             :   bool TryInlineApiGetter(Handle<Object> function, Handle<Map> receiver_map,
    2375             :                           BailoutId ast_id);
    2376             :   bool TryInlineApiSetter(Handle<Object> function, Handle<Map> receiver_map,
    2377             :                           BailoutId ast_id);
    2378             :   bool TryInlineApiCall(Handle<Object> function, HValue* receiver,
    2379             :                         SmallMapList* receiver_maps, int argc, BailoutId ast_id,
    2380             :                         ApiCallType call_type,
    2381             :                         TailCallMode syntactic_tail_call_mode);
    2382             :   static bool IsReadOnlyLengthDescriptor(Handle<Map> jsarray_map);
    2383             :   static bool CanInlineArrayResizeOperation(Handle<Map> receiver_map);
    2384             :   static bool NoElementsInPrototypeChain(Handle<Map> receiver_map);
    2385             : 
    2386             :   // If --trace-inlining, print a line of the inlining trace.  Inlining
    2387             :   // succeeded if the reason string is NULL and failed if there is a
    2388             :   // non-NULL reason string.
    2389             :   void TraceInline(Handle<JSFunction> target, Handle<JSFunction> caller,
    2390             :                    const char* failure_reason,
    2391             :                    TailCallMode tail_call_mode = TailCallMode::kDisallow);
    2392             : 
    2393             :   void HandleGlobalVariableAssignment(Variable* var, HValue* value,
    2394             :                                       FeedbackSlot slot, BailoutId ast_id);
    2395             : 
    2396             :   void HandlePropertyAssignment(Assignment* expr);
    2397             :   void HandleCompoundAssignment(Assignment* expr);
    2398             :   void HandlePolymorphicNamedFieldAccess(PropertyAccessType access_type,
    2399             :                                          Expression* expr, FeedbackSlot slot,
    2400             :                                          BailoutId ast_id, BailoutId return_id,
    2401             :                                          HValue* object, HValue* value,
    2402             :                                          SmallMapList* types,
    2403             :                                          Handle<Name> name);
    2404             : 
    2405             :   HValue* BuildAllocateExternalElements(
    2406             :       ExternalArrayType array_type,
    2407             :       bool is_zero_byte_offset,
    2408             :       HValue* buffer, HValue* byte_offset, HValue* length);
    2409             :   HValue* BuildAllocateFixedTypedArray(ExternalArrayType array_type,
    2410             :                                        size_t element_size,
    2411             :                                        ElementsKind fixed_elements_kind,
    2412             :                                        HValue* byte_length, HValue* length,
    2413             :                                        bool initialize);
    2414             : 
    2415             :   // TODO(adamk): Move all OrderedHashTable functions to their own class.
    2416             :   HValue* BuildOrderedHashTableHashToBucket(HValue* hash, HValue* num_buckets);
    2417             :   template <typename CollectionType>
    2418             :   HValue* BuildOrderedHashTableHashToEntry(HValue* table, HValue* hash,
    2419             :                                            HValue* num_buckets);
    2420             :   template <typename CollectionType>
    2421             :   HValue* BuildOrderedHashTableEntryToIndex(HValue* entry, HValue* num_buckets);
    2422             :   template <typename CollectionType>
    2423             :   HValue* BuildOrderedHashTableFindEntry(HValue* table, HValue* key,
    2424             :                                          HValue* hash);
    2425             :   template <typename CollectionType>
    2426             :   HValue* BuildOrderedHashTableAddEntry(HValue* table, HValue* key,
    2427             :                                         HValue* hash,
    2428             :                                         HIfContinuation* join_continuation);
    2429             :   template <typename CollectionType>
    2430             :   HValue* BuildAllocateOrderedHashTable();
    2431             :   template <typename CollectionType>
    2432             :   void BuildOrderedHashTableClear(HValue* receiver);
    2433             :   template <typename CollectionType>
    2434             :   void BuildJSCollectionDelete(CallRuntime* call,
    2435             :                                const Runtime::Function* c_function);
    2436             :   template <typename CollectionType>
    2437             :   void BuildJSCollectionHas(CallRuntime* call,
    2438             :                             const Runtime::Function* c_function);
    2439             :   HValue* BuildStringHashLoadIfIsStringAndHashComputed(
    2440             :       HValue* object, HIfContinuation* continuation);
    2441             : 
    2442      209503 :   Handle<JSFunction> array_function() {
    2443      628509 :     return handle(isolate()->native_context()->array_function());
    2444             :   }
    2445             : 
    2446             :   bool TryInlineArrayCall(Expression* expression, int argument_count,
    2447             :                           Handle<AllocationSite> site);
    2448             : 
    2449             :   void BuildInitializeInobjectProperties(HValue* receiver,
    2450             :                                          Handle<Map> initial_map);
    2451             : 
    2452             :   class PropertyAccessInfo {
    2453             :    public:
    2454      348175 :     PropertyAccessInfo(HOptimizedGraphBuilder* builder,
    2455             :                        PropertyAccessType access_type, Handle<Map> map,
    2456             :                        Handle<Name> name)
    2457             :         : builder_(builder),
    2458             :           access_type_(access_type),
    2459             :           map_(map),
    2460             :           name_(isolate()->factory()->InternalizeName(name)),
    2461             :           field_type_(HType::Tagged()),
    2462             :           access_(HObjectAccess::ForMap()),
    2463             :           lookup_type_(NOT_FOUND),
    2464             :           details_(PropertyDetails::Empty()),
    2465     1392700 :           store_mode_(STORE_TO_INITIALIZED_ENTRY) {}
    2466             : 
    2467             :     // Ensure the full store is performed.
    2468             :     void MarkAsInitializingStore() {
    2469             :       DCHECK_EQ(STORE, access_type_);
    2470       22666 :       store_mode_ = INITIALIZING_STORE;
    2471             :     }
    2472             : 
    2473             :     StoreFieldOrKeyedMode StoreMode() {
    2474             :       DCHECK_EQ(STORE, access_type_);
    2475             :       return store_mode_;
    2476             :     }
    2477             : 
    2478             :     // Checkes whether this PropertyAccessInfo can be handled as a monomorphic
    2479             :     // load named. It additionally fills in the fields necessary to generate the
    2480             :     // lookup code.
    2481             :     bool CanAccessMonomorphic();
    2482             : 
    2483             :     // Checks whether all types behave uniform when loading name. If all maps
    2484             :     // behave the same, a single monomorphic load instruction can be emitted,
    2485             :     // guarded by a single map-checks instruction that whether the receiver is
    2486             :     // an instance of any of the types.
    2487             :     // This method skips the first type in types, assuming that this
    2488             :     // PropertyAccessInfo is built for types->first().
    2489             :     bool CanAccessAsMonomorphic(SmallMapList* types);
    2490             : 
    2491             :     bool NeedsWrappingFor(Handle<JSFunction> target) const;
    2492             : 
    2493             :     Handle<Map> map();
    2494             :     Handle<Name> name() const { return name_; }
    2495             : 
    2496             :     bool IsJSObjectFieldAccessor() {
    2497             :       int offset;  // unused
    2498      328744 :       return Accessors::IsJSObjectFieldAccessor(map_, name_, &offset);
    2499             :     }
    2500             : 
    2501      482976 :     bool GetJSObjectFieldAccess(HObjectAccess* access) {
    2502             :       int offset;
    2503      482976 :       if (Accessors::IsJSObjectFieldAccessor(map_, name_, &offset)) {
    2504       35418 :         if (IsStringType()) {
    2505             :           DCHECK(Name::Equals(isolate()->factory()->length_string(), name_));
    2506       10180 :           *access = HObjectAccess::ForStringLength();
    2507       25238 :         } else if (IsArrayType()) {
    2508             :           DCHECK(Name::Equals(isolate()->factory()->length_string(), name_));
    2509       25238 :           *access = HObjectAccess::ForArrayLength(map_->elements_kind());
    2510             :         } else {
    2511           0 :           *access = HObjectAccess::ForMapAndOffset(map_, offset);
    2512             :         }
    2513             :         return true;
    2514             :       }
    2515             :       return false;
    2516             :     }
    2517             : 
    2518             :     bool has_holder() { return !holder_.is_null(); }
    2519       24248 :     bool IsLoad() const { return access_type_ == LOAD; }
    2520             : 
    2521     1106257 :     Isolate* isolate() const { return builder_->isolate(); }
    2522             :     Handle<JSObject> holder() { return holder_; }
    2523             :     Handle<Object> accessor() { return accessor_; }
    2524             :     Handle<Object> constant() { return constant_; }
    2525             :     Handle<Map> transition() { return transition_; }
    2526             :     SmallMapList* field_maps() { return &field_maps_; }
    2527             :     HType field_type() const { return field_type_; }
    2528             :     HObjectAccess access() { return access_; }
    2529             : 
    2530             :     bool IsFound() const { return lookup_type_ != NOT_FOUND; }
    2531       34687 :     bool IsProperty() const { return IsFound() && !IsTransition(); }
    2532       21285 :     bool IsTransition() const { return lookup_type_ == TRANSITION_TYPE; }
    2533             :     // TODO(ishell): rename to IsDataConstant() once constant field tracking
    2534             :     // is done.
    2535             :     bool IsDataConstantField() const {
    2536             :       return lookup_type_ == DESCRIPTOR_TYPE && details_.kind() == kData &&
    2537             :              details_.location() == kField && details_.constness() == kConst;
    2538             :     }
    2539             :     bool IsData() const {
    2540     1462541 :       return lookup_type_ == DESCRIPTOR_TYPE && details_.kind() == kData &&
    2541             :              details_.location() == kField;
    2542             :     }
    2543             :     bool IsDataConstant() const {
    2544      682504 :       return lookup_type_ == DESCRIPTOR_TYPE && details_.kind() == kData &&
    2545             :              details_.location() == kDescriptor;
    2546             :     }
    2547       16976 :     bool IsAccessorConstant() const {
    2548      819594 :       return !IsTransition() && details_.kind() == kAccessor &&
    2549             :              details_.location() == kDescriptor;
    2550             :     }
    2551             :     bool IsConfigurable() const { return details_.IsConfigurable(); }
    2552             :     bool IsReadOnly() const { return details_.IsReadOnly(); }
    2553             : 
    2554      114296 :     bool IsStringType() { return map_->instance_type() < FIRST_NONSTRING_TYPE; }
    2555             :     bool IsNumberType() { return map_->instance_type() == HEAP_NUMBER_TYPE; }
    2556       31580 :     bool IsValueWrapped() { return IsStringType() || IsNumberType(); }
    2557             :     bool IsArrayType() { return map_->instance_type() == JS_ARRAY_TYPE; }
    2558             : 
    2559             :    private:
    2560      200703 :     Handle<Object> GetConstantFromMap(Handle<Map> map) const {
    2561             :       DCHECK_EQ(DESCRIPTOR_TYPE, lookup_type_);
    2562             :       DCHECK(number_ < map->NumberOfOwnDescriptors());
    2563      401406 :       return handle(map->instance_descriptors()->GetValue(number_), isolate());
    2564             :     }
    2565             :     Handle<Object> GetAccessorsFromMap(Handle<Map> map) const {
    2566        7922 :       return GetConstantFromMap(map);
    2567             :     }
    2568             :     Handle<FieldType> GetFieldTypeFromMap(Handle<Map> map) const;
    2569       11950 :     Handle<Map> GetFieldOwnerFromMap(Handle<Map> map) const {
    2570             :       DCHECK(IsFound());
    2571             :       DCHECK(number_ < map->NumberOfOwnDescriptors());
    2572       35850 :       return handle(map->FindFieldOwner(number_));
    2573             :     }
    2574       91509 :     int GetLocalFieldIndexFromMap(Handle<Map> map) const {
    2575             :       DCHECK(lookup_type_ == DESCRIPTOR_TYPE ||
    2576             :              lookup_type_ == TRANSITION_TYPE);
    2577             :       DCHECK(number_ < map->NumberOfOwnDescriptors());
    2578       91509 :       int field_index = map->instance_descriptors()->GetFieldIndex(number_);
    2579       91509 :       return field_index - map->GetInObjectProperties();
    2580             :     }
    2581             : 
    2582      844490 :     void LookupDescriptor(Map* map, Name* name) {
    2583             :       DescriptorArray* descriptors = map->instance_descriptors();
    2584             :       int number = descriptors->SearchWithCache(isolate(), name, map);
    2585      844490 :       if (number == DescriptorArray::kNotFound) return NotFound();
    2586      292260 :       lookup_type_ = DESCRIPTOR_TYPE;
    2587      292260 :       details_ = descriptors->GetDetails(number);
    2588      292260 :       number_ = number;
    2589             :     }
    2590       16838 :     void LookupTransition(Map* map, Name* name, PropertyAttributes attributes) {
    2591             :       Map* target =
    2592       16838 :           TransitionArray::SearchTransition(map, kData, name, attributes);
    2593       33676 :       if (target == NULL) return NotFound();
    2594       16532 :       lookup_type_ = TRANSITION_TYPE;
    2595       16532 :       transition_ = handle(target);
    2596       16532 :       number_ = transition_->LastAdded();
    2597       16532 :       details_ = transition_->instance_descriptors()->GetDetails(number_);
    2598             :       MarkAsInitializingStore();
    2599             :     }
    2600             :     void NotFound() {
    2601      148968 :       lookup_type_ = NOT_FOUND;
    2602      148968 :       details_ = PropertyDetails::Empty();
    2603             :     }
    2604             :     Representation representation() const {
    2605             :       DCHECK(IsFound());
    2606             :       return details_.representation();
    2607             :     }
    2608       16838 :     bool IsTransitionToData() const {
    2609       49902 :       return IsTransition() && details_.kind() == kData &&
    2610             :              details_.location() == kField;
    2611             :     }
    2612             : 
    2613       23989 :     Zone* zone() { return builder_->zone(); }
    2614       11950 :     CompilationInfo* top_info() { return builder_->top_info(); }
    2615             :     CompilationInfo* current_info() { return builder_->current_info(); }
    2616             : 
    2617             :     bool LoadResult(Handle<Map> map);
    2618             :     bool LoadFieldMaps(Handle<Map> map);
    2619             :     bool LookupDescriptor();
    2620             :     bool LookupInPrototypes();
    2621             :     bool IsIntegerIndexedExotic();
    2622             :     bool IsCompatible(PropertyAccessInfo* other);
    2623             : 
    2624        3204 :     void GeneralizeRepresentation(Representation r) {
    2625             :       access_ = access_.WithRepresentation(
    2626        6408 :           access_.representation().generalize(r));
    2627        3204 :     }
    2628             : 
    2629             :     HOptimizedGraphBuilder* builder_;
    2630             :     PropertyAccessType access_type_;
    2631             :     Handle<Map> map_;
    2632             :     Handle<Name> name_;
    2633             :     Handle<JSObject> holder_;
    2634             :     Handle<Object> accessor_;
    2635             :     Handle<JSObject> api_holder_;
    2636             :     Handle<Object> constant_;
    2637             :     SmallMapList field_maps_;
    2638             :     HType field_type_;
    2639             :     HObjectAccess access_;
    2640             : 
    2641             :     enum { NOT_FOUND, DESCRIPTOR_TYPE, TRANSITION_TYPE } lookup_type_;
    2642             :     Handle<Map> transition_;
    2643             :     int number_;
    2644             :     PropertyDetails details_;
    2645             :     StoreFieldOrKeyedMode store_mode_;
    2646             :   };
    2647             : 
    2648             :   HValue* BuildMonomorphicAccess(PropertyAccessInfo* info, HValue* object,
    2649             :                                  HValue* checked_object, HValue* value,
    2650             :                                  BailoutId ast_id, BailoutId return_id,
    2651             :                                  bool can_inline_accessor = true);
    2652             : 
    2653             :   HValue* BuildNamedAccess(PropertyAccessType access, BailoutId ast_id,
    2654             :                            BailoutId reutrn_id, Expression* expr,
    2655             :                            FeedbackSlot slot, HValue* object, Handle<Name> name,
    2656             :                            HValue* value, bool is_uninitialized = false);
    2657             : 
    2658             :   void HandlePolymorphicCallNamed(Call* expr,
    2659             :                                   HValue* receiver,
    2660             :                                   SmallMapList* types,
    2661             :                                   Handle<String> name);
    2662             :   void HandleLiteralCompareTypeof(CompareOperation* expr,
    2663             :                                   Expression* sub_expr,
    2664             :                                   Handle<String> check);
    2665             :   void HandleLiteralCompareNil(CompareOperation* expr,
    2666             :                                Expression* sub_expr,
    2667             :                                NilValue nil);
    2668             : 
    2669             :   enum PushBeforeSimulateBehavior {
    2670             :     PUSH_BEFORE_SIMULATE,
    2671             :     NO_PUSH_BEFORE_SIMULATE
    2672             :   };
    2673             : 
    2674             :   HControlInstruction* BuildCompareInstruction(
    2675             :       Token::Value op, HValue* left, HValue* right, AstType* left_type,
    2676             :       AstType* right_type, AstType* combined_type, SourcePosition left_position,
    2677             :       SourcePosition right_position, PushBeforeSimulateBehavior push_sim_result,
    2678             :       BailoutId bailout_id);
    2679             : 
    2680             :   HInstruction* BuildStringCharCodeAt(HValue* string,
    2681             :                                       HValue* index);
    2682             : 
    2683             :   HValue* BuildBinaryOperation(
    2684             :       BinaryOperation* expr,
    2685             :       HValue* left,
    2686             :       HValue* right,
    2687             :       PushBeforeSimulateBehavior push_sim_result);
    2688             :   HInstruction* BuildIncrement(CountOperation* expr);
    2689             :   HInstruction* BuildKeyedGeneric(PropertyAccessType access_type,
    2690             :                                   Expression* expr, FeedbackSlot slot,
    2691             :                                   HValue* object, HValue* key, HValue* value);
    2692             : 
    2693             :   HInstruction* TryBuildConsolidatedElementLoad(HValue* object,
    2694             :                                                 HValue* key,
    2695             :                                                 HValue* val,
    2696             :                                                 SmallMapList* maps);
    2697             : 
    2698             :   LoadKeyedHoleMode BuildKeyedHoleMode(Handle<Map> map);
    2699             : 
    2700             :   HInstruction* BuildMonomorphicElementAccess(HValue* object,
    2701             :                                               HValue* key,
    2702             :                                               HValue* val,
    2703             :                                               HValue* dependency,
    2704             :                                               Handle<Map> map,
    2705             :                                               PropertyAccessType access_type,
    2706             :                                               KeyedAccessStoreMode store_mode);
    2707             : 
    2708             :   HValue* HandlePolymorphicElementAccess(Expression* expr, FeedbackSlot slot,
    2709             :                                          HValue* object, HValue* key,
    2710             :                                          HValue* val, SmallMapList* maps,
    2711             :                                          PropertyAccessType access_type,
    2712             :                                          KeyedAccessStoreMode store_mode,
    2713             :                                          bool* has_side_effects);
    2714             : 
    2715             :   HValue* HandleKeyedElementAccess(HValue* obj, HValue* key, HValue* val,
    2716             :                                    Expression* expr, FeedbackSlot slot,
    2717             :                                    BailoutId ast_id, BailoutId return_id,
    2718             :                                    PropertyAccessType access_type,
    2719             :                                    bool* has_side_effects);
    2720             : 
    2721             :   HInstruction* BuildNamedGeneric(PropertyAccessType access, Expression* expr,
    2722             :                                   FeedbackSlot slot, HValue* object,
    2723             :                                   Handle<Name> name, HValue* value,
    2724             :                                   bool is_uninitialized = false);
    2725             : 
    2726             :   HCheckMaps* AddCheckMap(HValue* object, Handle<Map> map);
    2727             : 
    2728             :   void BuildLoad(Property* property,
    2729             :                  BailoutId ast_id);
    2730             :   void PushLoad(Property* property,
    2731             :                 HValue* object,
    2732             :                 HValue* key);
    2733             : 
    2734             :   void BuildStoreForEffect(Expression* expression, Property* prop,
    2735             :                            FeedbackSlot slot, BailoutId ast_id,
    2736             :                            BailoutId return_id, HValue* object, HValue* key,
    2737             :                            HValue* value);
    2738             : 
    2739             :   void BuildStore(Expression* expression, Property* prop, FeedbackSlot slot,
    2740             :                   BailoutId ast_id, BailoutId return_id,
    2741             :                   bool is_uninitialized = false);
    2742             : 
    2743             :   HInstruction* BuildLoadNamedField(PropertyAccessInfo* info,
    2744             :                                     HValue* checked_object);
    2745             :   HValue* BuildStoreNamedField(PropertyAccessInfo* info, HValue* checked_object,
    2746             :                                HValue* value);
    2747             : 
    2748             :   HValue* BuildContextChainWalk(Variable* var);
    2749             : 
    2750             :   HValue* AddThisFunction();
    2751             :   HInstruction* BuildThisFunction();
    2752             : 
    2753             :   HInstruction* BuildFastLiteral(Handle<JSObject> boilerplate_object,
    2754             :                                  AllocationSiteUsageContext* site_context);
    2755             : 
    2756             :   void BuildEmitObjectHeader(Handle<JSObject> boilerplate_object,
    2757             :                              HInstruction* object);
    2758             : 
    2759             :   void BuildEmitInObjectProperties(Handle<JSObject> boilerplate_object,
    2760             :                                    HInstruction* object,
    2761             :                                    AllocationSiteUsageContext* site_context,
    2762             :                                    PretenureFlag pretenure_flag);
    2763             : 
    2764             :   void BuildEmitElements(Handle<JSObject> boilerplate_object,
    2765             :                          Handle<FixedArrayBase> elements,
    2766             :                          HValue* object_elements,
    2767             :                          AllocationSiteUsageContext* site_context);
    2768             : 
    2769             :   void BuildEmitFixedDoubleArray(Handle<FixedArrayBase> elements,
    2770             :                                  ElementsKind kind,
    2771             :                                  HValue* object_elements);
    2772             : 
    2773             :   void BuildEmitFixedArray(Handle<FixedArrayBase> elements,
    2774             :                            ElementsKind kind,
    2775             :                            HValue* object_elements,
    2776             :                            AllocationSiteUsageContext* site_context);
    2777             : 
    2778             :   void AddCheckPrototypeMaps(Handle<JSObject> holder,
    2779             :                              Handle<Map> receiver_map);
    2780             : 
    2781             :   void BuildEnsureCallable(HValue* object);
    2782             : 
    2783             :   HInstruction* NewCallFunction(HValue* function, int argument_count,
    2784             :                                 TailCallMode syntactic_tail_call_mode,
    2785             :                                 ConvertReceiverMode convert_mode,
    2786             :                                 TailCallMode tail_call_mode);
    2787             : 
    2788             :   HInstruction* NewCallFunctionViaIC(HValue* function, int argument_count,
    2789             :                                      TailCallMode syntactic_tail_call_mode,
    2790             :                                      ConvertReceiverMode convert_mode,
    2791             :                                      TailCallMode tail_call_mode,
    2792             :                                      FeedbackSlot slot);
    2793             : 
    2794             :   HInstruction* NewCallConstantFunction(Handle<JSFunction> target,
    2795             :                                         int argument_count,
    2796             :                                         TailCallMode syntactic_tail_call_mode,
    2797             :                                         TailCallMode tail_call_mode);
    2798             : 
    2799             :   bool CanBeFunctionApplyArguments(Call* expr);
    2800             : 
    2801             :   bool IsAnyParameterContextAllocated();
    2802             : 
    2803             :   // The translation state of the currently-being-translated function.
    2804             :   FunctionState* function_state_;
    2805             : 
    2806             :   // The base of the function state stack.
    2807             :   FunctionState initial_function_state_;
    2808             : 
    2809             :   // Expression context of the currently visited subexpression. NULL when
    2810             :   // visiting statements.
    2811             :   AstContext* ast_context_;
    2812             : 
    2813             :   // A stack of breakable statements entered.
    2814             :   BreakAndContinueScope* break_scope_;
    2815             : 
    2816             :   int inlined_count_;
    2817             :   ZoneList<Handle<Object> > globals_;
    2818             : 
    2819             :   bool inline_bailout_;
    2820             : 
    2821             :   HOsrBuilder* osr_;
    2822             : 
    2823             :   AstTypeBounds bounds_;
    2824             : 
    2825             :   friend class FunctionState;  // Pushes and pops the state stack.
    2826             :   friend class AstContext;  // Pushes and pops the AST context stack.
    2827             :   friend class HOsrBuilder;
    2828             : 
    2829             :   DISALLOW_COPY_AND_ASSIGN(HOptimizedGraphBuilder);
    2830             : };
    2831             : 
    2832             : 
    2833             : Zone* AstContext::zone() const { return owner_->zone(); }
    2834             : 
    2835             : 
    2836           0 : class HStatistics final : public Malloced {
    2837             :  public:
    2838           0 :   HStatistics()
    2839             :       : times_(5),
    2840             :         names_(5),
    2841             :         sizes_(5),
    2842             :         total_size_(0),
    2843           0 :         source_size_(0) { }
    2844             : 
    2845             :   void Initialize(CompilationInfo* info);
    2846             :   void Print();
    2847             :   void SaveTiming(const char* name, base::TimeDelta time, size_t size);
    2848             : 
    2849             :   void IncrementFullCodeGen(base::TimeDelta full_code_gen) {
    2850             :     full_code_gen_ += full_code_gen;
    2851             :   }
    2852             : 
    2853             :   void IncrementCreateGraph(base::TimeDelta delta) { create_graph_ += delta; }
    2854             : 
    2855             :   void IncrementOptimizeGraph(base::TimeDelta delta) {
    2856             :     optimize_graph_ += delta;
    2857             :   }
    2858             : 
    2859             :   void IncrementGenerateCode(base::TimeDelta delta) { generate_code_ += delta; }
    2860             : 
    2861             :   void IncrementSubtotals(base::TimeDelta create_graph,
    2862             :                           base::TimeDelta optimize_graph,
    2863             :                           base::TimeDelta generate_code) {
    2864             :     IncrementCreateGraph(create_graph);
    2865             :     IncrementOptimizeGraph(optimize_graph);
    2866             :     IncrementGenerateCode(generate_code);
    2867             :   }
    2868             : 
    2869             :  private:
    2870             :   List<base::TimeDelta> times_;
    2871             :   List<const char*> names_;
    2872             :   List<size_t> sizes_;
    2873             :   base::TimeDelta create_graph_;
    2874             :   base::TimeDelta optimize_graph_;
    2875             :   base::TimeDelta generate_code_;
    2876             :   size_t total_size_;
    2877             :   base::TimeDelta full_code_gen_;
    2878             :   double source_size_;
    2879             : };
    2880             : 
    2881             : 
    2882             : class HPhase : public CompilationPhase {
    2883             :  public:
    2884     5943791 :   HPhase(const char* name, HGraph* graph)
    2885             :       : CompilationPhase(name, graph->info()),
    2886     5943791 :         graph_(graph) { }
    2887             :   ~HPhase();
    2888             : 
    2889             :  protected:
    2890             :   HGraph* graph() const { return graph_; }
    2891             : 
    2892             :  private:
    2893             :   HGraph* graph_;
    2894             : 
    2895             :   DISALLOW_COPY_AND_ASSIGN(HPhase);
    2896             : };
    2897             : 
    2898             : 
    2899             : class HTracer final : public Malloced {
    2900             :  public:
    2901           0 :   explicit HTracer(int isolate_id)
    2902           0 :       : trace_(&string_allocator_), indent_(0) {
    2903           0 :     if (FLAG_trace_hydrogen_file == NULL) {
    2904             :       SNPrintF(filename_,
    2905             :                "hydrogen-%d-%d.cfg",
    2906             :                base::OS::GetCurrentProcessId(),
    2907           0 :                isolate_id);
    2908             :     } else {
    2909           0 :       StrNCpy(filename_, FLAG_trace_hydrogen_file, filename_.length());
    2910             :     }
    2911           0 :     WriteChars(filename_.start(), "", 0, false);
    2912           0 :   }
    2913             : 
    2914             :   void TraceCompilation(CompilationInfo* info);
    2915             :   void TraceHydrogen(const char* name, HGraph* graph);
    2916             :   void TraceLithium(const char* name, LChunk* chunk);
    2917             :   void TraceLiveRanges(const char* name, LAllocator* allocator);
    2918             : 
    2919             :  private:
    2920             :   class Tag final BASE_EMBEDDED {
    2921             :    public:
    2922           0 :     Tag(HTracer* tracer, const char* name) {
    2923           0 :       name_ = name;
    2924           0 :       tracer_ = tracer;
    2925             :       tracer->PrintIndent();
    2926           0 :       tracer->trace_.Add("begin_%s\n", name);
    2927           0 :       tracer->indent_++;
    2928           0 :     }
    2929             : 
    2930           0 :     ~Tag() {
    2931           0 :       tracer_->indent_--;
    2932             :       tracer_->PrintIndent();
    2933           0 :       tracer_->trace_.Add("end_%s\n", name_);
    2934             :       DCHECK(tracer_->indent_ >= 0);
    2935           0 :       tracer_->FlushToFile();
    2936           0 :     }
    2937             : 
    2938             :    private:
    2939             :     HTracer* tracer_;
    2940             :     const char* name_;
    2941             :   };
    2942             : 
    2943             :   void TraceLiveRange(LiveRange* range, const char* type, Zone* zone);
    2944             :   void Trace(const char* name, HGraph* graph, LChunk* chunk);
    2945             :   void FlushToFile();
    2946             : 
    2947           0 :   void PrintEmptyProperty(const char* name) {
    2948             :     PrintIndent();
    2949           0 :     trace_.Add("%s\n", name);
    2950           0 :   }
    2951             : 
    2952           0 :   void PrintStringProperty(const char* name, const char* value) {
    2953             :     PrintIndent();
    2954           0 :     trace_.Add("%s \"%s\"\n", name, value);
    2955           0 :   }
    2956             : 
    2957           0 :   void PrintLongProperty(const char* name, int64_t value) {
    2958             :     PrintIndent();
    2959           0 :     trace_.Add("%s %d000\n", name, static_cast<int>(value / 1000));
    2960           0 :   }
    2961             : 
    2962           0 :   void PrintBlockProperty(const char* name, int block_id) {
    2963             :     PrintIndent();
    2964           0 :     trace_.Add("%s \"B%d\"\n", name, block_id);
    2965           0 :   }
    2966             : 
    2967           0 :   void PrintIntProperty(const char* name, int value) {
    2968             :     PrintIndent();
    2969           0 :     trace_.Add("%s %d\n", name, value);
    2970           0 :   }
    2971             : 
    2972             :   void PrintIndent() {
    2973           0 :     for (int i = 0; i < indent_; i++) {
    2974           0 :       trace_.Add("  ");
    2975             :     }
    2976             :   }
    2977             : 
    2978             :   EmbeddedVector<char, 64> filename_;
    2979             :   HeapStringAllocator string_allocator_;
    2980             :   StringStream trace_;
    2981             :   int indent_;
    2982             : };
    2983             : 
    2984             : 
    2985             : class NoObservableSideEffectsScope final {
    2986             :  public:
    2987             :   explicit NoObservableSideEffectsScope(HGraphBuilder* builder) :
    2988             :       builder_(builder) {
    2989      766597 :     builder_->graph()->IncrementInNoSideEffectsScope();
    2990             :   }
    2991             :   ~NoObservableSideEffectsScope() {
    2992      766597 :     builder_->graph()->DecrementInNoSideEffectsScope();
    2993             :   }
    2994             : 
    2995             :  private:
    2996             :   HGraphBuilder* builder_;
    2997             : };
    2998             : 
    2999             : class DoExpressionScope final {
    3000             :  public:
    3001             :   explicit DoExpressionScope(HOptimizedGraphBuilder* builder)
    3002             :       : builder_(builder) {
    3003          62 :     builder_->function_state()->IncrementInDoExpressionScope();
    3004             :   }
    3005             :   ~DoExpressionScope() {
    3006          62 :     builder_->function_state()->DecrementInDoExpressionScope();
    3007             :   }
    3008             : 
    3009             :  private:
    3010             :   HOptimizedGraphBuilder* builder_;
    3011             : };
    3012             : 
    3013             : }  // namespace internal
    3014             : }  // namespace v8
    3015             : 
    3016             : #endif  // V8_CRANKSHAFT_HYDROGEN_H_

Generated by: LCOV version 1.10