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 410 92.9 %

          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      758026 : class HCompilationJob final : public CompilationJob {
      40             :  public:
      41      379023 :   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     1516094 :         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     2371608 :   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    24946719 :   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     6441876 :   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     4511609 :   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     4511610 :     first_instruction_index_ = index;
     100             :   }
     101             :   int last_instruction_index() const { return last_instruction_index_; }
     102             :   void set_last_instruction_index(int index) {
     103     4511610 :     last_instruction_index_ = index;
     104             :   }
     105     3237958 :   bool is_osr_entry() { return is_osr_entry_; }
     106        2438 :   void set_osr_entry() { is_osr_entry_ = true; }
     107             : 
     108             :   void AttachLoopInformation();
     109             :   void DetachLoopInformation();
     110    72056920 :   bool IsLoopHeader() const { return loop_information() != NULL; }
     111    30386310 :   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      358204 :     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      859427 :     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     2843257 :   HSimulate* AddNewSimulate(BailoutId ast_id, SourcePosition position,
     144             :                             RemovableSimulate removable = FIXED_SIMULATE) {
     145     2843257 :     HSimulate* instr = CreateSimulate(ast_id, removable);
     146     2843257 :     AddInstruction(instr, position);
     147     2843257 :     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     4170316 :   bool IsInlineReturnTarget() const { return is_inline_return_target_; }
     159             :   void MarkAsInlineReturnTarget(HBasicBlock* inlined_entry_block) {
     160      126935 :     is_inline_return_target_ = true;
     161      126935 :     inlined_entry_block_ = inlined_entry_block;
     162             :   }
     163             :   HBasicBlock* inlined_entry_block() { return inlined_entry_block_; }
     164             : 
     165    14151204 :   bool IsDeoptimizing() const {
     166    28112938 :     return end() != NULL && end()->IsDeoptimize();
     167             :   }
     168             : 
     169             :   void MarkUnreachable();
     170     8883417 :   bool IsUnreachable() const { return !is_reachable_; }
     171    72763523 :   bool IsReachable() const { return is_reachable_; }
     172             : 
     173             :   bool IsLoopSuccessorDominator() const {
     174      603289 :     return dominates_loop_successors_;
     175             :   }
     176             :   void MarkAsLoopSuccessorDominator() {
     177      306212 :     dominates_loop_successors_ = true;
     178             :   }
     179             : 
     180     6749193 :   bool IsOrdered() const { return is_ordered_; }
     181     4521958 :   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    10952116 :       : predecessor_list_(block->predecessors()), current_(0) { }
     247             : 
     248    13511622 :   bool Done() { return current_ >= predecessor_list_->length(); }
     249    10817931 :   HBasicBlock* Current() { return predecessor_list_->at(current_); }
     250     2559506 :   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    71310562 :   explicit HInstructionIterator(HBasicBlock* block)
     261             :       : instr_(block->first()) {
     262    71310562 :     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   442359758 :     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       61252 :   HLoopInformation(HBasicBlock* loop_header, Zone* zone)
     281             :       : back_edges_(4, zone),
     282             :         loop_header_(loop_header),
     283             :         blocks_(8, zone),
     284       61252 :         stack_check_(NULL) {
     285             :     blocks_.Add(loop_header, zone);
     286       61252 :   }
     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       45588 :     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     1418641 :   int GetMaximumValueID() const { return values_.length(); }
     377     4622691 :   int GetNextBlockID() { return next_block_id_++; }
     378    33186205 :   int GetNextValueID(HValue* value) {
     379             :     DCHECK(!disallow_adding_new_values_);
     380             :     values_.Add(value, zone());
     381    33186153 :     return values_.length() - 1;
     382             :   }
     383             :   HValue* LookupValue(int id) const {
     384    80421849 :     if (id >= 0 && id < values_.length()) return values_[id];
     385             :     return NULL;
     386             :   }
     387             :   void DisallowAddingNewValues() {
     388      283726 :     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        2438 :     osr_ = osr;
     403             :   }
     404             : 
     405             :   HOsrBuilder* osr() {
     406             :     return osr_;
     407             :   }
     408             : 
     409             :   int update_type_change_checksum(int delta) {
     410      367622 :     type_change_checksum_ += delta;
     411             :     return type_change_checksum_;
     412             :   }
     413             : 
     414             :   void update_maximum_environment_size(int environment_size) {
     415    10471935 :     if (environment_size > maximum_environment_size_) {
     416      302421 :       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      260261 :   void set_allow_code_motion(bool value) { allow_code_motion_ = value; }
     423             : 
     424             :   bool use_optimistic_licm() const { return use_optimistic_licm_; }
     425      260261 :   void set_use_optimistic_licm(bool value) { use_optimistic_licm_ = value; }
     426             : 
     427        9256 :   void MarkDependsOnEmptyArrayProtoElements() {
     428             :     // Add map dependency if not already added.
     429        7420 :     if (depends_on_empty_array_proto_elements_) return;
     430             :     info()->dependencies()->AssumePropertyCell(
     431        2773 :         isolate()->factory()->array_protector());
     432        2773 :     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       16540 :   void MarkDependsOnStringLengthOverflow() {
     440       23700 :     if (depends_on_string_length_overflow_) return;
     441             :     info()->dependencies()->AssumePropertyCell(
     442        2345 :         isolate()->factory()->string_length_protector());
     443        2345 :     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        8516 :   void RecordUint32Instruction(HInstruction* instr) {
     457             :     DCHECK(uint32_instructions_ == NULL || !uint32_instructions_->is_empty());
     458        3674 :     if (uint32_instructions_ == NULL) {
     459        1168 :       uint32_instructions_ = new(zone()) ZoneList<HInstruction*>(4, zone());
     460             :     }
     461        3674 :     uint32_instructions_->Add(instr, zone());
     462        3674 :   }
     463             : 
     464      758035 :   void IncrementInNoSideEffectsScope() { no_side_effects_scope_count_++; }
     465      758035 :   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     5103753 :   void Run() {
     475     2549823 :     Phase phase(this);
     476     4535946 :     phase.Run();
     477     5103766 :   }
     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    57972143 : 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      671114 :   HEnvironment* arguments_environment() {
     541      671114 :     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     7856243 :   void set_ast_id(BailoutId id) { ast_id_ = id; }
     560             : 
     561             :   HEnterInlined* entry() const { return entry_; }
     562      106691 :   void set_entry(HEnterInlined* entry) { entry_ = entry; }
     563             : 
     564    94999998 :   int length() const { return values_.length(); }
     565             : 
     566    22230028 :   int first_expression_index() const {
     567    22230028 :     return parameter_count() + specials_count() + local_count();
     568             :   }
     569             : 
     570     2506361 :   int first_local_index() const {
     571     2506361 :     return parameter_count() + specials_count();
     572             :   }
     573             : 
     574       26664 :   void Bind(Variable* variable, HValue* value) {
     575         354 :     Bind(IndexFor(variable), value);
     576       26664 :   }
     577             : 
     578             :   void Bind(int index, HValue* value);
     579             : 
     580      770042 :   void BindContext(HValue* value) {
     581      132662 :     Bind(parameter_count(), value);
     582      637380 :   }
     583             : 
     584             :   HValue* Lookup(Variable* variable) const {
     585             :     return Lookup(IndexFor(variable));
     586             :   }
     587             : 
     588             :   HValue* Lookup(int index) const {
     589    37295680 :     HValue* result = values_[index];
     590             :     DCHECK(result != NULL);
     591             :     return result;
     592             :   }
     593             : 
     594    15082189 :   HValue* context() const {
     595             :     // Return first special.
     596             :     return Lookup(parameter_count());
     597             :   }
     598             : 
     599    10242697 :   void Push(HValue* value) {
     600             :     DCHECK(value != NULL);
     601    10242697 :     ++push_count_;
     602             :     values_.Add(value, zone());
     603             :   }
     604             : 
     605    10977700 :   HValue* Pop() {
     606             :     DCHECK(!ExpressionStackIsEmpty());
     607    10977700 :     if (push_count_ > 0) {
     608     7646779 :       --push_count_;
     609             :     } else {
     610     3330921 :       ++pop_count_;
     611             :     }
     612    21955236 :     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     4529309 :     int index = length() - index_from_top - 1;
     623             :     DCHECK(HasExpressionAt(index));
     624     9054330 :     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     1121298 :   HEnvironment* DiscardInlined(bool drop_extra) {
     645     3447999 :     HEnvironment* outer = outer_;
     646     1205403 :     while (outer->frame_type() != JS_FUNCTION &&
     647             :            outer->frame_type() != TAIL_CALLER_FUNCTION) {
     648       84105 :       outer = outer->outer_;
     649             :     }
     650     1121298 :     if (drop_extra) outer->Drop(1);
     651     1121298 :     if (outer->frame_type() == TAIL_CALLER_FUNCTION) {
     652         179 :       outer->ClearTailCallerMark();
     653             :     }
     654     1121298 :     return outer;
     655             :   }
     656             : 
     657             :   void AddIncomingEdge(HBasicBlock* block, HEnvironment* other);
     658             : 
     659             :   void ClearHistory() {
     660     5844364 :     pop_count_ = 0;
     661     5844364 :     push_count_ = 0;
     662             :     assigned_variables_.Clear();
     663             :   }
     664             : 
     665             :   void SetValueAt(int index, HValue* value) {
     666             :     DCHECK(index < length());
     667     2778290 :     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     2869421 :   int IndexFor(Variable* variable) const {
     674             :     DCHECK(variable->IsStackAllocated());
     675             :     int shift = variable->IsParameter()
     676             :         ? 1
     677     2869421 :         : parameter_count_ + specials_count_;
     678     2869421 :     return variable->index() + shift;
     679             :   }
     680             : 
     681             :   bool is_local_index(int i) const {
     682     3777246 :     return i >= first_local_index() && i < first_expression_index();
     683             :   }
     684             : 
     685       14103 :   bool is_parameter_index(int i) const {
     686       28206 :     return i >= 0 && i < parameter_count();
     687             :   }
     688             : 
     689   113008239 :   bool is_special_index(int i) const {
     690   113008239 :     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      106725 :   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      922161 :       : 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     5358949 :       : 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     1054571 : 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     1054571 :         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       19537 :   void ClearInlinedTestContext() {
     896       19537 :     delete test_context_;
     897       19537 :     test_context_ = NULL;
     898       19537 :   }
     899             : 
     900             :   FunctionState* outer() { return outer_; }
     901             : 
     902             :   TailCallMode ComputeTailCallMode(TailCallMode tail_call_mode) const {
     903      767872 :     if (tail_call_mode_ == TailCallMode::kDisallow) return tail_call_mode_;
     904             :     return tail_call_mode;
     905             :   }
     906             : 
     907             :   HEnterInlined* entry() { return entry_; }
     908      107398 :   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         232 :     arguments_elements_ = arguments_elements;
     918             :   }
     919             : 
     920         341 :   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         838 :       false_branch_(NULL) {}
     976             :   HIfContinuation(HBasicBlock* true_branch,
     977             :                   HBasicBlock* false_branch)
     978             :       : continuation_captured_(true), true_branch_(true_branch),
     979        5187 :         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         838 :     true_branch_ = true_branch;
     986         838 :     false_branch_ = false_branch;
     987         838 :     continuation_captured_ = true;
     988             :   }
     989             : 
     990             :   void Continue(HBasicBlock** true_branch,
     991             :                 HBasicBlock** false_branch) {
     992             :     DCHECK(continuation_captured_);
     993        6025 :     *true_branch = true_branch_;
     994        6025 :     *false_branch = false_branch_;
     995        6025 :     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        7734 :       : current_site_(current_site), pretenure_flag_(NOT_TENURED) {}
    1021             :   explicit HAllocationMode(PretenureFlag pretenure_flag)
    1022       11712 :       : current_site_(NULL), pretenure_flag_(pretenure_flag) {}
    1023             :   HAllocationMode()
    1024      772270 :       : 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        3812 :   bool CreateAllocationMementos() const WARN_UNUSED_RESULT {
    1030             :     return current_site() != NULL;
    1031             :   }
    1032             : 
    1033             :   PretenureFlag GetPretenureMode() const WARN_UNUSED_RESULT {
    1034       72375 :     if (!feedback_site().is_null()) return feedback_site()->GetPretenureMode();
    1035       15167 :     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      287446 :         scope_(info->scope()),
    1055             :         position_(SourcePosition::Unknown()),
    1056      862338 :         track_positions_(track_positions) {}
    1057       23533 :   virtual ~HGraphBuilder() {}
    1058             : 
    1059             :   Scope* scope() const { return scope_; }
    1060      900662 :   void set_scope(Scope* scope) { scope_ = scope; }
    1061             : 
    1062             :   HBasicBlock* current_block() const { return current_block_; }
    1063     5302157 :   void set_current_block(HBasicBlock* block) { current_block_ = block; }
    1064    35687055 :   HEnvironment* environment() const {
    1065    35793456 :     return current_block()->last_environment();
    1066             :   }
    1067    23452444 :   Zone* zone() const { return info_->zone(); }
    1068             :   HGraph* graph() const { return graph_; }
    1069     8344073 :   Isolate* isolate() const { return graph_->isolate(); }
    1070             :   CompilationInfo* top_info() { return info_; }
    1071             : 
    1072             :   HGraph* CreateGraph();
    1073             : 
    1074             :   // Bailout environment manipulation.
    1075    14717148 :   void Push(HValue* value) { environment()->Push(value); }
    1076     5178863 :   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     2805327 :     from->Goto(target, source_position(), state, add_simulate);
    1090             :   }
    1091             :   void Goto(HBasicBlock* target,
    1092             :             FunctionState* state = NULL,
    1093      633484 :             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       39593 :     block->AddLeaveInlined(return_value, state, source_position());
    1106             :   }
    1107       35954 :   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     1310502 :   I* New() {
    1118     1310502 :     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     1107593 :   I* Add() { return AddInstructionTyped(New<I>());}
    1126             : 
    1127             :   template<class I, class P1>
    1128      658846 :   HInstruction* NewUncasted(P1 p1) {
    1129      658330 :     return I::New(isolate(), zone(), context(), p1);
    1130             :   }
    1131             : 
    1132             :   template <class I, class P1>
    1133    14983812 :   I* New(P1 p1) {
    1134    14983812 :     return I::New(isolate(), zone(), context(), p1);
    1135             :   }
    1136             : 
    1137             :   template<class I, class P1>
    1138      328649 :   HInstruction* AddUncasted(P1 p1) {
    1139      328649 :     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      328648 :     return result;
    1145             :   }
    1146             : 
    1147             :   template<class I, class P1>
    1148     5661220 :   I* Add(P1 p1) {
    1149     5233429 :     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     5661219 :     return result;
    1155             :   }
    1156             : 
    1157             :   template<class I, class P1, class P2>
    1158     1550542 :   HInstruction* NewUncasted(P1 p1, P2 p2) {
    1159     1034028 :     return I::New(isolate(), zone(), context(), p1, p2);
    1160             :   }
    1161             : 
    1162             :   template<class I, class P1, class P2>
    1163     5896296 :   I* New(P1 p1, P2 p2) {
    1164     5715876 :     return I::New(isolate(), zone(), context(), p1, p2);
    1165             :   }
    1166             : 
    1167             :   template<class I, class P1, class P2>
    1168      486586 :   HInstruction* AddUncasted(P1 p1, P2 p2) {
    1169      486586 :     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      486586 :     return result;
    1174             :   }
    1175             : 
    1176             :   template<class I, class P1, class P2>
    1177     1952914 :   I* Add(P1 p1, P2 p2) {
    1178     1952914 :     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     1952914 :     return result;
    1183             :   }
    1184             : 
    1185             :   template<class I, class P1, class P2, class P3>
    1186      479082 :   HInstruction* NewUncasted(P1 p1, P2 p2, P3 p3) {
    1187      319388 :     return I::New(isolate(), zone(), context(), p1, p2, p3);
    1188             :   }
    1189             : 
    1190             :   template<class I, class P1, class P2, class P3>
    1191     2658234 :   I* New(P1 p1, P2 p2, P3 p3) {
    1192     2658668 :     return I::New(isolate(), zone(), context(), p1, p2, p3);
    1193             :   }
    1194             : 
    1195             :   template<class I, class P1, class P2, class P3>
    1196      157943 :   HInstruction* AddUncasted(P1 p1, P2 p2, P3 p3) {
    1197      157943 :     return AddInstruction(NewUncasted<I>(p1, p2, p3));
    1198             :   }
    1199             : 
    1200             :   template<class I, class P1, class P2, class P3>
    1201      815078 :   I* Add(P1 p1, P2 p2, P3 p3) {
    1202     1630156 :     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      663476 :   I* New(P1 p1, P2 p2, P3 p3, P4 p4) {
    1212      663476 :     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      127403 :   I* Add(P1 p1, P2 p2, P3 p3, P4 p4) {
    1222      254806 :     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       80601 :   HInstruction* NewUncasted(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) {
    1227       53734 :     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     2103326 :   I* New(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) {
    1232     2103326 :     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       26867 :   HInstruction* AddUncasted(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) {
    1237       26867 :     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       33069 :   I* Add(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) {
    1242       66138 :     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         888 :   HInstruction* NewUncasted(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6) {
    1247         888 :     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      187822 :   I* New(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6) {
    1252      187822 :     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         444 :   HInstruction* AddUncasted(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6) {
    1257         444 :     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       86026 :   I* Add(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6) {
    1262      172052 :     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      214796 :   I* New(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8, P9 p9) {
    1318      107398 :     return I::New(isolate(), zone(), context(), p1, p2, p3, p4, p5, p6, p7, p8,
    1319      214796 :                   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      107398 :   I* Add(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8, P9 p9) {
    1332      214796 :     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        1081 :   HValue* BuildDecodeField(HValue* encoded_field) {
    1349        1081 :     HValue* mask_value = Add<HConstant>(static_cast<int>(BitFieldClass::kMask));
    1350             :     HValue* masked_field =
    1351        1081 :         AddUncasted<HBitwise>(Token::BIT_AND, encoded_field, mask_value);
    1352             :     return AddUncasted<HShr>(masked_field,
    1353        1081 :         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             :   HValue* BuildNumberToString(HValue* object, AstType* type);
    1383             :   HValue* BuildToNumber(HValue* input);
    1384             :   HValue* BuildToObject(HValue* receiver);
    1385             : 
    1386             :   // ES6 section 7.4.7 CreateIterResultObject ( value, done )
    1387             :   HValue* BuildCreateIterResultObject(HValue* value, HValue* done);
    1388             : 
    1389             :   // Allocates a new object according with the given allocation properties.
    1390             :   HAllocate* BuildAllocate(HValue* object_size,
    1391             :                            HType type,
    1392             :                            InstanceType instance_type,
    1393             :                            HAllocationMode allocation_mode);
    1394             :   // Computes the sum of two string lengths, taking care of overflow handling.
    1395             :   HValue* BuildAddStringLengths(HValue* left_length, HValue* right_length);
    1396             :   // Creates a cons string using the two input strings.
    1397             :   HValue* BuildCreateConsString(HValue* length,
    1398             :                                 HValue* left,
    1399             :                                 HValue* right,
    1400             :                                 HAllocationMode allocation_mode);
    1401             :   // Copies characters from one sequential string to another.
    1402             :   void BuildCopySeqStringChars(HValue* src,
    1403             :                                HValue* src_offset,
    1404             :                                String::Encoding src_encoding,
    1405             :                                HValue* dst,
    1406             :                                HValue* dst_offset,
    1407             :                                String::Encoding dst_encoding,
    1408             :                                HValue* length);
    1409             : 
    1410             :   // Align an object size to object alignment boundary
    1411             :   HValue* BuildObjectSizeAlignment(HValue* unaligned_size, int header_size);
    1412             : 
    1413             :   // Both operands are non-empty strings.
    1414             :   HValue* BuildUncheckedStringAdd(HValue* left,
    1415             :                                   HValue* right,
    1416             :                                   HAllocationMode allocation_mode);
    1417             :   // Add two strings using allocation mode, validating type feedback.
    1418             :   HValue* BuildStringAdd(HValue* left,
    1419             :                          HValue* right,
    1420             :                          HAllocationMode allocation_mode);
    1421             : 
    1422             :   HInstruction* BuildUncheckedMonomorphicElementAccess(
    1423             :       HValue* checked_object,
    1424             :       HValue* key,
    1425             :       HValue* val,
    1426             :       bool is_js_array,
    1427             :       ElementsKind elements_kind,
    1428             :       PropertyAccessType access_type,
    1429             :       LoadKeyedHoleMode load_mode,
    1430             :       KeyedAccessStoreMode store_mode);
    1431             : 
    1432             :   HInstruction* AddElementAccess(
    1433             :       HValue* elements, HValue* checked_key, HValue* val, HValue* dependency,
    1434             :       HValue* backing_store_owner, ElementsKind elements_kind,
    1435             :       PropertyAccessType access_type,
    1436             :       LoadKeyedHoleMode load_mode = NEVER_RETURN_HOLE);
    1437             : 
    1438             :   HInstruction* AddLoadStringInstanceType(HValue* string);
    1439             :   HInstruction* AddLoadStringLength(HValue* string);
    1440             :   HInstruction* BuildLoadStringLength(HValue* string);
    1441       14508 :   HStoreNamedField* AddStoreMapConstant(HValue* object, Handle<Map> map) {
    1442             :     return Add<HStoreNamedField>(object, HObjectAccess::ForMap(),
    1443       14508 :                                  Add<HConstant>(map));
    1444             :   }
    1445             :   HLoadNamedField* AddLoadMap(HValue* object,
    1446             :                               HValue* dependency = NULL);
    1447             :   HLoadNamedField* AddLoadElements(HValue* object,
    1448             :                                    HValue* dependency = NULL);
    1449             : 
    1450             :   bool MatchRotateRight(HValue* left,
    1451             :                         HValue* right,
    1452             :                         HValue** operand,
    1453             :                         HValue** shift_amount);
    1454             : 
    1455             :   HValue* BuildBinaryOperation(Token::Value op, HValue* left, HValue* right,
    1456             :                                AstType* left_type, AstType* right_type,
    1457             :                                AstType* result_type, Maybe<int> fixed_right_arg,
    1458             :                                HAllocationMode allocation_mode,
    1459             :                                BailoutId opt_id = BailoutId::None());
    1460             : 
    1461             :   HLoadNamedField* AddLoadFixedArrayLength(HValue *object,
    1462             :                                            HValue *dependency = NULL);
    1463             : 
    1464             :   HLoadNamedField* AddLoadArrayLength(HValue *object,
    1465             :                                       ElementsKind kind,
    1466             :                                       HValue *dependency = NULL);
    1467             : 
    1468             :   HValue* EnforceNumberType(HValue* number, AstType* expected);
    1469             :   HValue* TruncateToNumber(HValue* value, AstType** expected);
    1470             : 
    1471             :   void FinishExitWithHardDeoptimization(DeoptimizeReason reason);
    1472             : 
    1473             :   void AddIncrementCounter(StatsCounter* counter);
    1474             : 
    1475             :   class IfBuilder final {
    1476             :    public:
    1477             :     // If using this constructor, Initialize() must be called explicitly!
    1478             :     IfBuilder();
    1479             : 
    1480             :     explicit IfBuilder(HGraphBuilder* builder);
    1481             :     IfBuilder(HGraphBuilder* builder,
    1482             :               HIfContinuation* continuation);
    1483             : 
    1484             :     ~IfBuilder() {
    1485       99567 :       if (!finished_) End();
    1486             :     }
    1487             : 
    1488             :     void Initialize(HGraphBuilder* builder);
    1489             : 
    1490             :     template<class Condition>
    1491        7357 :     Condition* If(HValue *p) {
    1492        7357 :       Condition* compare = builder()->New<Condition>(p);
    1493        7357 :       AddCompare(compare);
    1494        7357 :       return compare;
    1495             :     }
    1496             : 
    1497             :     template<class Condition, class P2>
    1498       27035 :     Condition* If(HValue* p1, P2 p2) {
    1499       27035 :       Condition* compare = builder()->New<Condition>(p1, p2);
    1500       27035 :       AddCompare(compare);
    1501       27035 :       return compare;
    1502             :     }
    1503             : 
    1504             :     template<class Condition, class P2, class P3>
    1505       93816 :     Condition* If(HValue* p1, P2 p2, P3 p3) {
    1506       93816 :       Condition* compare = builder()->New<Condition>(p1, p2, p3);
    1507       93816 :       AddCompare(compare);
    1508       93816 :       return compare;
    1509             :     }
    1510             : 
    1511             :     template<class Condition>
    1512             :     Condition* IfNot(HValue* p) {
    1513        1392 :       Condition* compare = If<Condition>(p);
    1514        1392 :       compare->Not();
    1515             :       return compare;
    1516             :     }
    1517             : 
    1518             :     template<class Condition, class P2>
    1519             :     Condition* IfNot(HValue* p1, P2 p2) {
    1520         262 :       Condition* compare = If<Condition>(p1, p2);
    1521         262 :       compare->Not();
    1522             :       return compare;
    1523             :     }
    1524             : 
    1525             :     template<class Condition, class P2, class P3>
    1526             :     Condition* IfNot(HValue* p1, P2 p2, P3 p3) {
    1527         133 :       Condition* compare = If<Condition>(p1, p2, p3);
    1528         133 :       compare->Not();
    1529             :       return compare;
    1530             :     }
    1531             : 
    1532             :     template<class Condition>
    1533             :     Condition* OrIf(HValue *p) {
    1534             :       Or();
    1535             :       return If<Condition>(p);
    1536             :     }
    1537             : 
    1538             :     template<class Condition, class P2>
    1539             :     Condition* OrIf(HValue* p1, P2 p2) {
    1540         170 :       Or();
    1541         170 :       return If<Condition>(p1, p2);
    1542             :     }
    1543             : 
    1544             :     template<class Condition, class P2, class P3>
    1545             :     Condition* OrIf(HValue* p1, P2 p2, P3 p3) {
    1546             :       Or();
    1547             :       return If<Condition>(p1, p2, p3);
    1548             :     }
    1549             : 
    1550             :     template<class Condition>
    1551             :     Condition* AndIf(HValue *p) {
    1552             :       And();
    1553             :       return If<Condition>(p);
    1554             :     }
    1555             : 
    1556             :     template<class Condition, class P2>
    1557             :     Condition* AndIf(HValue* p1, P2 p2) {
    1558          99 :       And();
    1559          99 :       return If<Condition>(p1, p2);
    1560             :     }
    1561             : 
    1562             :     template<class Condition, class P2, class P3>
    1563             :     Condition* AndIf(HValue* p1, P2 p2, P3 p3) {
    1564          85 :       And();
    1565          85 :       return If<Condition>(p1, p2, p3);
    1566             :     }
    1567             : 
    1568             :     void Or();
    1569             :     void And();
    1570             : 
    1571             :     // Captures the current state of this IfBuilder in the specified
    1572             :     // continuation and ends this IfBuilder.
    1573             :     void CaptureContinuation(HIfContinuation* continuation);
    1574             : 
    1575             :     // Joins the specified continuation from this IfBuilder and ends this
    1576             :     // IfBuilder. This appends a Goto instruction from the true branch of
    1577             :     // this IfBuilder to the true branch of the continuation unless the
    1578             :     // true branch of this IfBuilder is already finished. And vice versa
    1579             :     // for the false branch.
    1580             :     //
    1581             :     // The basic idea is as follows: You have several nested IfBuilder's
    1582             :     // that you want to join based on two possible outcomes (i.e. success
    1583             :     // and failure, or whatever). You can do this easily using this method
    1584             :     // now, for example:
    1585             :     //
    1586             :     //   HIfContinuation cont(graph()->CreateBasicBlock(),
    1587             :     //                        graph()->CreateBasicBlock());
    1588             :     //   ...
    1589             :     //     IfBuilder if_whatever(this);
    1590             :     //     if_whatever.If<Condition>(arg);
    1591             :     //     if_whatever.Then();
    1592             :     //     ...
    1593             :     //     if_whatever.Else();
    1594             :     //     ...
    1595             :     //     if_whatever.JoinContinuation(&cont);
    1596             :     //   ...
    1597             :     //     IfBuilder if_something(this);
    1598             :     //     if_something.If<Condition>(arg1, arg2);
    1599             :     //     if_something.Then();
    1600             :     //     ...
    1601             :     //     if_something.Else();
    1602             :     //     ...
    1603             :     //     if_something.JoinContinuation(&cont);
    1604             :     //   ...
    1605             :     //   IfBuilder if_finally(this, &cont);
    1606             :     //   if_finally.Then();
    1607             :     //   // continues after then code of if_whatever or if_something.
    1608             :     //   ...
    1609             :     //   if_finally.Else();
    1610             :     //   // continues after else code of if_whatever or if_something.
    1611             :     //   ...
    1612             :     //   if_finally.End();
    1613             :     void JoinContinuation(HIfContinuation* continuation);
    1614             : 
    1615             :     void Then();
    1616             :     void Else();
    1617             :     void End();
    1618             :     void EndUnreachable();
    1619             : 
    1620             :     void Deopt(DeoptimizeReason reason);
    1621             :     void ThenDeopt(DeoptimizeReason reason) {
    1622        1652 :       Then();
    1623        1652 :       Deopt(reason);
    1624             :     }
    1625         496 :     void ElseDeopt(DeoptimizeReason reason) {
    1626           0 :       Else();
    1627         496 :       Deopt(reason);
    1628         496 :     }
    1629             : 
    1630             :     void Return(HValue* value);
    1631             : 
    1632             :    private:
    1633             :     void InitializeDontCreateBlocks(HGraphBuilder* builder);
    1634             : 
    1635             :     HControlInstruction* AddCompare(HControlInstruction* compare);
    1636             : 
    1637             :     HGraphBuilder* builder() const {
    1638             :       DCHECK(builder_ != NULL);  // Have you called "Initialize"?
    1639             :       return builder_;
    1640             :     }
    1641             : 
    1642             :     void AddMergeAtJoinBlock(bool deopt);
    1643             : 
    1644             :     void Finish();
    1645             :     void Finish(HBasicBlock** then_continuation,
    1646             :                 HBasicBlock** else_continuation);
    1647             : 
    1648             :     class MergeAtJoinBlock : public ZoneObject {
    1649             :      public:
    1650             :       MergeAtJoinBlock(HBasicBlock* block,
    1651             :                        bool deopt,
    1652             :                        MergeAtJoinBlock* next)
    1653             :         : block_(block),
    1654             :           deopt_(deopt),
    1655      216730 :           next_(next) {}
    1656             :       HBasicBlock* block_;
    1657             :       bool deopt_;
    1658             :       MergeAtJoinBlock* next_;
    1659             :     };
    1660             : 
    1661             :     HGraphBuilder* builder_;
    1662             :     bool finished_ : 1;
    1663             :     bool did_then_ : 1;
    1664             :     bool did_else_ : 1;
    1665             :     bool did_else_if_ : 1;
    1666             :     bool did_and_ : 1;
    1667             :     bool did_or_ : 1;
    1668             :     bool captured_ : 1;
    1669             :     bool needs_compare_ : 1;
    1670             :     bool pending_merge_block_ : 1;
    1671             :     HBasicBlock* first_true_block_;
    1672             :     HBasicBlock* first_false_block_;
    1673             :     HBasicBlock* split_edge_merge_block_;
    1674             :     MergeAtJoinBlock* merge_at_join_blocks_;
    1675             :     int normal_merge_at_join_block_count_;
    1676             :     int deopt_merge_at_join_block_count_;
    1677             :   };
    1678             : 
    1679             :   class LoopBuilder final {
    1680             :    public:
    1681             :     enum Direction {
    1682             :       kPreIncrement,
    1683             :       kPostIncrement,
    1684             :       kPreDecrement,
    1685             :       kPostDecrement,
    1686             :       kWhileTrue
    1687             :     };
    1688             : 
    1689             :     explicit LoopBuilder(HGraphBuilder* builder);  // while (true) {...}
    1690             :     LoopBuilder(HGraphBuilder* builder,
    1691             :                 HValue* context,
    1692             :                 Direction direction);
    1693             :     LoopBuilder(HGraphBuilder* builder,
    1694             :                 HValue* context,
    1695             :                 Direction direction,
    1696             :                 HValue* increment_amount);
    1697             : 
    1698             :     ~LoopBuilder() {
    1699             :       DCHECK(finished_);
    1700             :     }
    1701             : 
    1702             :     HValue* BeginBody(
    1703             :         HValue* initial,
    1704             :         HValue* terminating,
    1705             :         Token::Value token);
    1706             : 
    1707             :     void BeginBody(int drop_count);
    1708             : 
    1709             :     void Break();
    1710             : 
    1711             :     void EndBody();
    1712             : 
    1713             :    private:
    1714             :     void Initialize(HGraphBuilder* builder, HValue* context,
    1715             :                     Direction direction, HValue* increment_amount);
    1716       15600 :     Zone* zone() { return builder_->zone(); }
    1717             : 
    1718             :     HGraphBuilder* builder_;
    1719             :     HValue* context_;
    1720             :     HValue* increment_amount_;
    1721             :     HInstruction* increment_;
    1722             :     HPhi* phi_;
    1723             :     HBasicBlock* header_block_;
    1724             :     HBasicBlock* body_block_;
    1725             :     HBasicBlock* exit_block_;
    1726             :     HBasicBlock* exit_trampoline_block_;
    1727             :     Direction direction_;
    1728             :     bool finished_;
    1729             :   };
    1730             : 
    1731             :   HValue* BuildNewElementsCapacity(HValue* old_capacity);
    1732             : 
    1733             :   HValue* BuildCalculateElementsSize(ElementsKind kind,
    1734             :                                      HValue* capacity);
    1735             :   HAllocate* AllocateJSArrayObject(AllocationSiteMode mode);
    1736             :   HConstant* EstablishElementsAllocationSize(ElementsKind kind, int capacity);
    1737             : 
    1738             :   HAllocate* BuildAllocateElements(ElementsKind kind, HValue* size_in_bytes);
    1739             : 
    1740             :   void BuildInitializeElementsHeader(HValue* elements,
    1741             :                                      ElementsKind kind,
    1742             :                                      HValue* capacity);
    1743             : 
    1744             :   // Build allocation and header initialization code for respective successor
    1745             :   // of FixedArrayBase.
    1746             :   HValue* BuildAllocateAndInitializeArray(ElementsKind kind, HValue* capacity);
    1747             : 
    1748             :   // |array| must have been allocated with enough room for
    1749             :   // 1) the JSArray and 2) an AllocationMemento if mode requires it.
    1750             :   // If the |elements| value provided is NULL then the array elements storage
    1751             :   // is initialized with empty array.
    1752             :   void BuildJSArrayHeader(HValue* array,
    1753             :                           HValue* array_map,
    1754             :                           HValue* elements,
    1755             :                           AllocationSiteMode mode,
    1756             :                           ElementsKind elements_kind,
    1757             :                           HValue* allocation_site_payload,
    1758             :                           HValue* length_field);
    1759             : 
    1760             :   HValue* BuildGrowElementsCapacity(HValue* object,
    1761             :                                     HValue* elements,
    1762             :                                     ElementsKind kind,
    1763             :                                     ElementsKind new_kind,
    1764             :                                     HValue* length,
    1765             :                                     HValue* new_capacity);
    1766             : 
    1767             :   void BuildFillElementsWithValue(HValue* elements,
    1768             :                                   ElementsKind elements_kind,
    1769             :                                   HValue* from,
    1770             :                                   HValue* to,
    1771             :                                   HValue* value);
    1772             : 
    1773             :   void BuildFillElementsWithHole(HValue* elements,
    1774             :                                  ElementsKind elements_kind,
    1775             :                                  HValue* from,
    1776             :                                  HValue* to);
    1777             : 
    1778             :   void BuildCopyProperties(HValue* from_properties, HValue* to_properties,
    1779             :                            HValue* length, HValue* capacity);
    1780             : 
    1781             :   void BuildCopyElements(HValue* from_elements,
    1782             :                          ElementsKind from_elements_kind,
    1783             :                          HValue* to_elements,
    1784             :                          ElementsKind to_elements_kind,
    1785             :                          HValue* length,
    1786             :                          HValue* capacity);
    1787             : 
    1788             :   void BuildCreateAllocationMemento(HValue* previous_object,
    1789             :                                     HValue* previous_object_size,
    1790             :                                     HValue* payload);
    1791             : 
    1792             :   HInstruction* BuildConstantMapCheck(Handle<JSObject> constant,
    1793             :                                       bool ensure_no_elements = false);
    1794             :   HInstruction* BuildCheckPrototypeMaps(Handle<JSObject> prototype,
    1795             :                                         Handle<JSObject> holder,
    1796             :                                         bool ensure_no_elements = false);
    1797             : 
    1798             :   HInstruction* BuildGetNativeContext();
    1799             : 
    1800             :   HValue* BuildArrayBufferViewFieldAccessor(HValue* object,
    1801             :                                             HValue* checked_object,
    1802             :                                             FieldIndex index);
    1803             : 
    1804             : 
    1805             :  protected:
    1806             :   void SetSourcePosition(int position) {
    1807     1709711 :     if (position != kNoSourcePosition) {
    1808             :       position_.SetScriptOffset(position);
    1809             :     }
    1810             :     // Otherwise position remains unknown.
    1811             :   }
    1812             : 
    1813             :   void EnterInlinedSource(int inlining_id) {
    1814         125 :     if (is_tracking_positions()) {
    1815             :       position_.SetInliningId(inlining_id);
    1816             :     }
    1817             :   }
    1818             : 
    1819             :   // Convert the given absolute offset from the start of the script to
    1820             :   // the SourcePosition assuming that this position corresponds to the
    1821             :   // same function as position_.
    1822             :   SourcePosition ScriptPositionToSourcePosition(int position) {
    1823      866052 :     if (position == kNoSourcePosition) {
    1824             :       return SourcePosition::Unknown();
    1825             :     }
    1826             :     return SourcePosition(position, position_.InliningId());
    1827             :   }
    1828             : 
    1829             :   SourcePosition source_position() { return position_; }
    1830        1841 :   void set_source_position(SourcePosition position) { position_ = position; }
    1831             : 
    1832             :   bool is_tracking_positions() { return track_positions_; }
    1833             : 
    1834             :   HValue* BuildAllocateEmptyArrayBuffer(HValue* byte_length);
    1835             :   template <typename ViewClass>
    1836             :   void BuildArrayBufferViewInitialization(HValue* obj,
    1837             :                                           HValue* buffer,
    1838             :                                           HValue* byte_offset,
    1839             :                                           HValue* byte_length);
    1840             : 
    1841             :  private:
    1842             :   HGraphBuilder();
    1843             : 
    1844             :   template <class I>
    1845             :   I* AddInstructionTyped(I* instr) {
    1846     9336903 :     return I::cast(AddInstruction(instr));
    1847             :   }
    1848             : 
    1849             :   CompilationInfo* info_;
    1850             :   CallInterfaceDescriptor descriptor_;
    1851             :   HGraph* graph_;
    1852             :   HBasicBlock* current_block_;
    1853             :   Scope* scope_;
    1854             :   SourcePosition position_;
    1855             :   bool track_positions_;
    1856             : };
    1857             : 
    1858             : template <>
    1859      644414 : inline HDeoptimize* HGraphBuilder::Add<HDeoptimize>(
    1860     1176614 :     DeoptimizeReason reason, Deoptimizer::BailoutType type) {
    1861      644414 :   if (type == Deoptimizer::SOFT) {
    1862      626303 :     isolate()->counters()->soft_deopts_requested()->Increment();
    1863      626303 :     if (FLAG_always_opt) return NULL;
    1864             :   }
    1865      189474 :   if (current_block()->IsDeoptimizing()) return NULL;
    1866             :   HBasicBlock* after_deopt_block = CreateBasicBlock(
    1867      189474 :       current_block()->last_environment());
    1868      189474 :   HDeoptimize* instr = New<HDeoptimize>(reason, type, after_deopt_block);
    1869      189474 :   if (type == Deoptimizer::SOFT) {
    1870      171363 :     isolate()->counters()->soft_deopts_inserted()->Increment();
    1871             :   }
    1872      189474 :   FinishCurrentBlock(instr);
    1873             :   set_current_block(after_deopt_block);
    1874      189474 :   return instr;
    1875             : }
    1876             : 
    1877             : template <>
    1878             : inline HInstruction* HGraphBuilder::AddUncasted<HDeoptimize>(
    1879             :     DeoptimizeReason reason, Deoptimizer::BailoutType type) {
    1880             :   return Add<HDeoptimize>(reason, type);
    1881             : }
    1882             : 
    1883             : 
    1884             : template<>
    1885     2121634 : inline HSimulate* HGraphBuilder::Add<HSimulate>(
    1886             :     BailoutId id,
    1887     2121634 :     RemovableSimulate removable) {
    1888     2121634 :   HSimulate* instr = current_block()->CreateSimulate(id, removable);
    1889     2121634 :   AddInstruction(instr);
    1890     2121634 :   return instr;
    1891             : }
    1892             : 
    1893             : 
    1894             : template<>
    1895             : inline HSimulate* HGraphBuilder::Add<HSimulate>(
    1896             :     BailoutId id) {
    1897      476434 :   return Add<HSimulate>(id, FIXED_SIMULATE);
    1898             : }
    1899             : 
    1900             : 
    1901             : template<>
    1902             : inline HInstruction* HGraphBuilder::AddUncasted<HSimulate>(BailoutId id) {
    1903             :   return Add<HSimulate>(id, FIXED_SIMULATE);
    1904             : }
    1905             : 
    1906             : 
    1907             : template<>
    1908      328649 : inline HReturn* HGraphBuilder::Add<HReturn>(HValue* value) {
    1909      328649 :   int num_parameters = graph()->info()->num_parameters();
    1910      328649 :   HValue* params = AddUncasted<HConstant>(num_parameters);
    1911      328648 :   HReturn* return_instruction = New<HReturn>(value, params);
    1912      328649 :   FinishExitCurrentBlock(return_instruction);
    1913      328649 :   return return_instruction;
    1914             : }
    1915             : 
    1916             : 
    1917             : template<>
    1918             : inline HReturn* HGraphBuilder::Add<HReturn>(HConstant* value) {
    1919       44200 :   return Add<HReturn>(static_cast<HValue*>(value));
    1920             : }
    1921             : 
    1922             : template<>
    1923             : inline HInstruction* HGraphBuilder::AddUncasted<HReturn>(HValue* value) {
    1924             :   return Add<HReturn>(value);
    1925             : }
    1926             : 
    1927             : 
    1928             : template<>
    1929             : inline HInstruction* HGraphBuilder::AddUncasted<HReturn>(HConstant* value) {
    1930             :   return Add<HReturn>(value);
    1931             : }
    1932             : 
    1933             : 
    1934             : template<>
    1935       57448 : inline HCallRuntime* HGraphBuilder::Add<HCallRuntime>(
    1936             :     const Runtime::Function* c_function,
    1937       57448 :     int argument_count) {
    1938       57448 :   HCallRuntime* instr = New<HCallRuntime>(c_function, argument_count);
    1939       57448 :   if (graph()->info()->IsStub()) {
    1940             :     // When compiling code stubs, we don't want to save all double registers
    1941             :     // upon entry to the stub, but instead have the call runtime instruction
    1942             :     // save the double registers only on-demand (in the fallback case).
    1943             :     instr->set_save_doubles(kSaveFPRegs);
    1944             :   }
    1945       57448 :   AddInstruction(instr);
    1946       57448 :   return instr;
    1947             : }
    1948             : 
    1949             : 
    1950             : template<>
    1951             : inline HInstruction* HGraphBuilder::AddUncasted<HCallRuntime>(
    1952             :     Handle<String> name,
    1953             :     const Runtime::Function* c_function,
    1954             :     int argument_count) {
    1955             :   return Add<HCallRuntime>(c_function, argument_count);
    1956             : }
    1957             : 
    1958             : 
    1959             : template <>
    1960      427791 : inline HParameter* HGraphBuilder::New<HParameter>(unsigned index) {
    1961      427791 :   return HParameter::New(isolate(), zone(), nullptr, index);
    1962             : }
    1963             : 
    1964             : 
    1965             : template <>
    1966             : inline HParameter* HGraphBuilder::New<HParameter>(
    1967             :     unsigned index, HParameter::ParameterKind kind) {
    1968             :   return HParameter::New(isolate(), zone(), nullptr, index, kind);
    1969             : }
    1970             : 
    1971             : 
    1972             : template <>
    1973             : inline HParameter* HGraphBuilder::New<HParameter>(
    1974             :     unsigned index, HParameter::ParameterKind kind, Representation r) {
    1975             :   return HParameter::New(isolate(), zone(), nullptr, index, kind, r);
    1976             : }
    1977             : 
    1978             : 
    1979             : template <>
    1980      263913 : inline HPrologue* HGraphBuilder::New<HPrologue>() {
    1981      263913 :   return HPrologue::New(zone());
    1982             : }
    1983             : 
    1984             : 
    1985             : template <>
    1986      289883 : inline HContext* HGraphBuilder::New<HContext>() {
    1987      289883 :   return HContext::New(zone());
    1988             : }
    1989             : 
    1990             : // This AstVistor is not final, and provides the AstVisitor methods as virtual
    1991             : // methods so they can be specialized by subclasses.
    1992           0 : class HOptimizedGraphBuilder : public HGraphBuilder,
    1993             :                                public AstVisitor<HOptimizedGraphBuilder> {
    1994             :  public:
    1995             :   // A class encapsulating (lazily-allocated) break and continue blocks for
    1996             :   // a breakable statement.  Separated from BreakAndContinueScope so that it
    1997             :   // can have a separate lifetime.
    1998             :   class BreakAndContinueInfo final BASE_EMBEDDED {
    1999             :    public:
    2000             :     explicit BreakAndContinueInfo(BreakableStatement* target,
    2001             :                                   Scope* scope,
    2002             :                                   int drop_extra = 0)
    2003             :         : target_(target),
    2004             :           break_block_(NULL),
    2005             :           continue_block_(NULL),
    2006             :           scope_(scope),
    2007      737144 :           drop_extra_(drop_extra) {
    2008             :     }
    2009             : 
    2010             :     BreakableStatement* target() { return target_; }
    2011             :     HBasicBlock* break_block() { return break_block_; }
    2012        3796 :     void set_break_block(HBasicBlock* block) { break_block_ = block; }
    2013             :     HBasicBlock* continue_block() { return continue_block_; }
    2014        1522 :     void set_continue_block(HBasicBlock* block) { continue_block_ = block; }
    2015             :     Scope* scope() { return scope_; }
    2016             :     int drop_extra() { return drop_extra_; }
    2017             : 
    2018             :    private:
    2019             :     BreakableStatement* target_;
    2020             :     HBasicBlock* break_block_;
    2021             :     HBasicBlock* continue_block_;
    2022             :     Scope* scope_;
    2023             :     int drop_extra_;
    2024             :   };
    2025             : 
    2026             :   // A helper class to maintain a stack of current BreakAndContinueInfo
    2027             :   // structures mirroring BreakableStatement nesting.
    2028             :   class BreakAndContinueScope final BASE_EMBEDDED {
    2029             :    public:
    2030             :     BreakAndContinueScope(BreakAndContinueInfo* info,
    2031      737144 :                           HOptimizedGraphBuilder* owner)
    2032     1474288 :         : info_(info), owner_(owner), next_(owner->break_scope()) {
    2033             :       owner->set_break_scope(this);
    2034             :     }
    2035             : 
    2036      737144 :     ~BreakAndContinueScope() { owner_->set_break_scope(next_); }
    2037             : 
    2038             :     BreakAndContinueInfo* info() { return info_; }
    2039             :     HOptimizedGraphBuilder* owner() { return owner_; }
    2040             :     BreakAndContinueScope* next() { return next_; }
    2041             : 
    2042             :     // Search the break stack for a break or continue target.
    2043             :     enum BreakType { BREAK, CONTINUE };
    2044             :     HBasicBlock* Get(BreakableStatement* stmt, BreakType type,
    2045             :                      Scope** scope, int* drop_extra);
    2046             : 
    2047             :    private:
    2048             :     BreakAndContinueInfo* info_;
    2049             :     HOptimizedGraphBuilder* owner_;
    2050             :     BreakAndContinueScope* next_;
    2051             :   };
    2052             : 
    2053             :   explicit HOptimizedGraphBuilder(CompilationInfo* info, bool track_positions);
    2054             : 
    2055             :   bool BuildGraph() override;
    2056             : 
    2057             :   // Simple accessors.
    2058             :   BreakAndContinueScope* break_scope() const { return break_scope_; }
    2059     1474288 :   void set_break_scope(BreakAndContinueScope* head) { break_scope_ = head; }
    2060             : 
    2061    28797222 :   HValue* context() override { return environment()->context(); }
    2062             : 
    2063             :   HOsrBuilder* osr() const { return osr_; }
    2064             : 
    2065             :   void Bailout(BailoutReason reason);
    2066             : 
    2067             :   HBasicBlock* CreateJoin(HBasicBlock* first,
    2068             :                           HBasicBlock* second,
    2069             :                           BailoutId join_id);
    2070             : 
    2071             :   FunctionState* function_state() const { return function_state_; }
    2072             : 
    2073             :   void VisitDeclarations(Declaration::List* declarations);
    2074             : 
    2075             :   AstTypeBounds* bounds() { return &bounds_; }
    2076             : 
    2077      263913 :   void* operator new(size_t size, Zone* zone) { return zone->New(size); }
    2078             :   void operator delete(void* pointer, Zone* zone) { }
    2079             :   void operator delete(void* pointer) { }
    2080             : 
    2081    43080470 :   DEFINE_AST_VISITOR_SUBCLASS_MEMBERS();
    2082             : 
    2083             :  protected:
    2084             :   // Forward declarations for inner scope classes.
    2085             :   class SubgraphScope;
    2086             : 
    2087             :   static const int kMaxCallPolymorphism = 4;
    2088             :   static const int kMaxLoadPolymorphism = 4;
    2089             :   static const int kMaxStorePolymorphism = 4;
    2090             : 
    2091             :   // Even in the 'unlimited' case we have to have some limit in order not to
    2092             :   // overflow the stack.
    2093             :   static const int kUnlimitedMaxInlinedSourceSize = 100000;
    2094             :   static const int kUnlimitedMaxInlinedNodes = 10000;
    2095             :   static const int kUnlimitedMaxInlinedNodesCumulative = 10000;
    2096             : 
    2097             :   // Maximum depth and total number of elements and properties for literal
    2098             :   // graphs to be considered for fast deep-copying. The limit is chosen to
    2099             :   // match the maximum number of inobject properties, to ensure that the
    2100             :   // performance of using object literals is not worse than using constructor
    2101             :   // functions, see crbug.com/v8/6211 for details.
    2102             :   static const int kMaxFastLiteralDepth = 3;
    2103             :   static const int kMaxFastLiteralProperties =
    2104             :       (JSObject::kMaxInstanceSize - JSObject::kHeaderSize) >> kPointerSizeLog2;
    2105             : 
    2106             :   // Simple accessors.
    2107      478709 :   void set_function_state(FunctionState* state) { function_state_ = state; }
    2108             : 
    2109             :   AstContext* ast_context() const { return ast_context_; }
    2110    14632286 :   void set_ast_context(AstContext* context) { ast_context_ = context; }
    2111             : 
    2112             :   // Accessors forwarded to the function state.
    2113     3967562 :   CompilationInfo* current_info() const {
    2114     3967584 :     return function_state()->compilation_info();
    2115             :   }
    2116        7106 :   AstContext* call_context() const {
    2117      616132 :     return function_state()->call_context();
    2118             :   }
    2119       94227 :   HBasicBlock* function_return() const {
    2120      238854 :     return function_state()->function_return();
    2121             :   }
    2122      107509 :   TestContext* inlined_test_context() const {
    2123      107523 :     return function_state()->test_context();
    2124             :   }
    2125             :   Handle<JSFunction> current_closure() const {
    2126             :     return current_info()->closure();
    2127             :   }
    2128             :   Handle<SharedFunctionInfo> current_shared_info() const {
    2129             :     return current_info()->shared_info();
    2130             :   }
    2131             :   FeedbackVector* current_feedback_vector() const {
    2132             :     return current_closure()->feedback_vector();
    2133             :   }
    2134             :   void ClearInlinedTestContext() {
    2135       19537 :     function_state()->ClearInlinedTestContext();
    2136             :   }
    2137       82843 :   LanguageMode function_language_mode() {
    2138       82843 :     return function_state()->compilation_info()->parse_info()->language_mode();
    2139             :   }
    2140             : 
    2141             : #define FOR_EACH_HYDROGEN_INTRINSIC(F) \
    2142             :   F(IsSmi)                             \
    2143             :   F(IsArray)                           \
    2144             :   F(IsTypedArray)                      \
    2145             :   F(IsJSProxy)                         \
    2146             :   F(Call)                              \
    2147             :   F(ToInteger)                         \
    2148             :   F(ToObject)                          \
    2149             :   F(ToString)                          \
    2150             :   F(ToLength)                          \
    2151             :   F(ToNumber)                          \
    2152             :   F(IsJSReceiver)                      \
    2153             :   F(DebugBreakInOptimizedCode)         \
    2154             :   F(StringCharCodeAt)                  \
    2155             :   F(SubString)                         \
    2156             :   F(DebugIsActive)                     \
    2157             :   /* Typed Arrays */                   \
    2158             :   F(MaxSmi)                            \
    2159             :   F(TypedArrayMaxSizeInHeap)           \
    2160             :   F(ArrayBufferViewGetByteLength)      \
    2161             :   F(ArrayBufferViewGetByteOffset)      \
    2162             :   F(ArrayBufferViewWasNeutered)        \
    2163             :   F(TypedArrayGetLength)               \
    2164             :   /* ArrayBuffer */                    \
    2165             :   F(ArrayBufferGetByteLength)          \
    2166             :   /* ES6 Collections */                \
    2167             :   F(MapClear)                          \
    2168             :   F(MapInitialize)                     \
    2169             :   F(SetClear)                          \
    2170             :   F(SetInitialize)                     \
    2171             :   F(FixedArrayGet)                     \
    2172             :   F(FixedArraySet)                     \
    2173             :   F(JSCollectionGetTable)              \
    2174             :   F(StringGetRawHashField)             \
    2175             :   F(TheHole)                           \
    2176             :   /* ES6 Iterators */                  \
    2177             :   F(CreateIterResultObject)            \
    2178             :   /* Arrays */                         \
    2179             :   F(HasFastPackedElements)
    2180             : 
    2181             : #define GENERATOR_DECLARATION(Name) void Generate##Name(CallRuntime* call);
    2182             :   FOR_EACH_HYDROGEN_INTRINSIC(GENERATOR_DECLARATION)
    2183             : #undef GENERATOR_DECLARATION
    2184             : 
    2185             :   void VisitDelete(UnaryOperation* expr);
    2186             :   void VisitVoid(UnaryOperation* expr);
    2187             :   void VisitTypeof(UnaryOperation* expr);
    2188             :   void VisitNot(UnaryOperation* expr);
    2189             : 
    2190             :   void VisitComma(BinaryOperation* expr);
    2191             :   void VisitLogicalExpression(BinaryOperation* expr);
    2192             :   void VisitArithmeticExpression(BinaryOperation* expr);
    2193             : 
    2194             :   void VisitLoopBody(IterationStatement* stmt, BailoutId stack_check_id,
    2195             :                      HBasicBlock* loop_entry);
    2196             : 
    2197             :   void BuildForInBody(ForInStatement* stmt, Variable* each_var,
    2198             :                       HValue* enumerable);
    2199             : 
    2200             :   // Create a back edge in the flow graph.  body_exit is the predecessor
    2201             :   // block and loop_entry is the successor block.  loop_successor is the
    2202             :   // block where control flow exits the loop normally (e.g., via failure of
    2203             :   // the condition) and break_block is the block where control flow breaks
    2204             :   // from the loop.  All blocks except loop_entry can be NULL.  The return
    2205             :   // value is the new successor block which is the join of loop_successor
    2206             :   // and break_block, or NULL.
    2207             :   HBasicBlock* CreateLoop(IterationStatement* statement,
    2208             :                           HBasicBlock* loop_entry,
    2209             :                           HBasicBlock* body_exit,
    2210             :                           HBasicBlock* loop_successor,
    2211             :                           HBasicBlock* break_block);
    2212             : 
    2213             :   // Build a loop entry
    2214             :   HBasicBlock* BuildLoopEntry();
    2215             : 
    2216             :   // Builds a loop entry respectful of OSR requirements
    2217             :   HBasicBlock* BuildLoopEntry(IterationStatement* statement);
    2218             : 
    2219             :   HBasicBlock* JoinContinue(IterationStatement* statement,
    2220             :                             BailoutId continue_id, HBasicBlock* exit_block,
    2221             :                             HBasicBlock* continue_block);
    2222             : 
    2223             :   HValue* Top() const { return environment()->Top(); }
    2224             :   void Drop(int n) { environment()->Drop(n); }
    2225        1072 :   void Bind(Variable* var, HValue* value) { environment()->Bind(var, value); }
    2226             :   bool IsEligibleForEnvironmentLivenessAnalysis(Variable* var,
    2227             :                                                 int index,
    2228             :                                                 HEnvironment* env) {
    2229     2615453 :     if (!FLAG_analyze_environment_liveness) return false;
    2230             :     // Zapping parameters isn't safe because function.arguments can inspect them
    2231             :     // at any time.
    2232             :     return env->is_local_index(index);
    2233             :   }
    2234      535269 :   void BindIfLive(Variable* var, HValue* value) {
    2235             :     HEnvironment* env = environment();
    2236             :     int index = env->IndexFor(var);
    2237             :     env->Bind(index, value);
    2238      535269 :     if (IsEligibleForEnvironmentLivenessAnalysis(var, index, env)) {
    2239             :       HEnvironmentMarker* bind =
    2240      504416 :           Add<HEnvironmentMarker>(HEnvironmentMarker::BIND, index);
    2241             :       USE(bind);
    2242             : #ifdef DEBUG
    2243             :       bind->set_closure(env->closure());
    2244             : #endif
    2245             :     }
    2246      535269 :   }
    2247     2080184 :   HValue* LookupAndMakeLive(Variable* var) {
    2248             :     HEnvironment* env = environment();
    2249             :     int index = env->IndexFor(var);
    2250     2080184 :     if (IsEligibleForEnvironmentLivenessAnalysis(var, index, env)) {
    2251             :       HEnvironmentMarker* lookup =
    2252      776866 :           Add<HEnvironmentMarker>(HEnvironmentMarker::LOOKUP, index);
    2253             :       USE(lookup);
    2254             : #ifdef DEBUG
    2255             :       lookup->set_closure(env->closure());
    2256             : #endif
    2257             :     }
    2258     2080184 :     return env->Lookup(index);
    2259             :   }
    2260             : 
    2261             :   // The value of the arguments object is allowed in some but not most value
    2262             :   // contexts.  (It's allowed in all effect contexts and disallowed in all
    2263             :   // test contexts.)
    2264             :   void VisitForValue(Expression* expr,
    2265             :                      ArgumentsAllowedFlag flag = ARGUMENTS_NOT_ALLOWED);
    2266             :   void VisitForTypeOf(Expression* expr);
    2267             :   void VisitForEffect(Expression* expr);
    2268             :   void VisitForControl(Expression* expr,
    2269             :                        HBasicBlock* true_block,
    2270             :                        HBasicBlock* false_block);
    2271             : 
    2272             :   // Visit a list of expressions from left to right, each in a value context.
    2273             :   void VisitExpressions(ZoneList<Expression*>* exprs);
    2274             :   void VisitExpressions(ZoneList<Expression*>* exprs,
    2275             :                         ArgumentsAllowedFlag flag);
    2276             : 
    2277             :   // Remove the arguments from the bailout environment and emit instructions
    2278             :   // to push them as outgoing parameters.
    2279             :   template <class Instruction> HInstruction* PreProcessCall(Instruction* call);
    2280             :   void PushArgumentsFromEnvironment(int count);
    2281             : 
    2282             :   void SetUpScope(DeclarationScope* scope);
    2283             :   void VisitStatements(ZoneList<Statement*>* statements);
    2284             : 
    2285             : #define DECLARE_VISIT(type) virtual void Visit##type(type* node);
    2286             :   AST_NODE_LIST(DECLARE_VISIT)
    2287             : #undef DECLARE_VISIT
    2288             : 
    2289             :  private:
    2290             :   bool CanInlineGlobalPropertyAccess(Variable* var, LookupIterator* it,
    2291             :                                      PropertyAccessType access_type);
    2292             : 
    2293             :   bool CanInlineGlobalPropertyAccess(LookupIterator* it,
    2294             :                                      PropertyAccessType access_type);
    2295             : 
    2296             :   void InlineGlobalPropertyLoad(LookupIterator* it, BailoutId ast_id);
    2297             :   HInstruction* InlineGlobalPropertyStore(LookupIterator* it, HValue* value,
    2298             :                                           BailoutId ast_id);
    2299             : 
    2300             :   void EnsureArgumentsArePushedForAccess();
    2301             :   bool TryArgumentsAccess(Property* expr);
    2302             : 
    2303             :   // Shared code for .call and .apply optimizations.
    2304             :   void HandleIndirectCall(Call* expr, HValue* function, int arguments_count);
    2305             :   // Try to optimize indirect calls such as fun.apply(receiver, arguments)
    2306             :   // or fun.call(...).
    2307             :   bool TryIndirectCall(Call* expr);
    2308             :   void BuildFunctionApply(Call* expr);
    2309             :   void BuildFunctionCall(Call* expr);
    2310             : 
    2311             :   template <class T>
    2312             :   bool TryHandleArrayCall(T* expr, HValue* function);
    2313             : 
    2314             :   enum ArrayIndexOfMode { kFirstIndexOf, kLastIndexOf };
    2315             :   HValue* BuildArrayIndexOf(HValue* receiver,
    2316             :                             HValue* search_element,
    2317             :                             ElementsKind kind,
    2318             :                             ArrayIndexOfMode mode);
    2319             : 
    2320             :   HValue* ImplicitReceiverFor(HValue* function,
    2321             :                               Handle<JSFunction> target);
    2322             : 
    2323             :   int InliningAstSize(Handle<JSFunction> target);
    2324             :   bool TryInline(Handle<JSFunction> target, int arguments_count,
    2325             :                  HValue* implicit_return_value, BailoutId ast_id,
    2326             :                  BailoutId return_id, InliningKind inlining_kind,
    2327             :                  TailCallMode syntactic_tail_call_mode);
    2328             : 
    2329             :   bool TryInlineCall(Call* expr);
    2330             :   bool TryInlineConstruct(CallNew* expr, HValue* implicit_return_value);
    2331             :   bool TryInlineGetter(Handle<Object> getter, Handle<Map> receiver_map,
    2332             :                        BailoutId ast_id, BailoutId return_id);
    2333             :   bool TryInlineSetter(Handle<Object> setter, Handle<Map> receiver_map,
    2334             :                        BailoutId id, BailoutId assignment_id,
    2335             :                        HValue* implicit_return_value);
    2336             :   bool TryInlineIndirectCall(Handle<JSFunction> function, Call* expr,
    2337             :                              int arguments_count);
    2338             :   bool TryInlineBuiltinGetterCall(Handle<JSFunction> function,
    2339             :                                   Handle<Map> receiver_map, BailoutId ast_id);
    2340             :   bool TryInlineBuiltinMethodCall(Handle<JSFunction> function,
    2341             :                                   Handle<Map> receiver_map, BailoutId ast_id,
    2342             :                                   int args_count_no_receiver);
    2343             :   bool TryInlineBuiltinFunctionCall(Call* expr);
    2344             :   enum ApiCallType {
    2345             :     kCallApiFunction,
    2346             :     kCallApiMethod,
    2347             :     kCallApiGetter,
    2348             :     kCallApiSetter
    2349             :   };
    2350             :   bool TryInlineApiMethodCall(Call* expr,
    2351             :                               HValue* receiver,
    2352             :                               SmallMapList* receiver_types);
    2353             :   bool TryInlineApiFunctionCall(Call* expr, HValue* receiver);
    2354             :   bool TryInlineApiGetter(Handle<Object> function, Handle<Map> receiver_map,
    2355             :                           BailoutId ast_id);
    2356             :   bool TryInlineApiSetter(Handle<Object> function, Handle<Map> receiver_map,
    2357             :                           BailoutId ast_id);
    2358             :   bool TryInlineApiCall(Handle<Object> function, HValue* receiver,
    2359             :                         SmallMapList* receiver_maps, int argc, BailoutId ast_id,
    2360             :                         ApiCallType call_type,
    2361             :                         TailCallMode syntactic_tail_call_mode);
    2362             :   static bool IsReadOnlyLengthDescriptor(Handle<Map> jsarray_map);
    2363             :   static bool CanInlineArrayResizeOperation(Handle<Map> receiver_map);
    2364             :   static bool NoElementsInPrototypeChain(Handle<Map> receiver_map);
    2365             : 
    2366             :   // If --trace-inlining, print a line of the inlining trace.  Inlining
    2367             :   // succeeded if the reason string is NULL and failed if there is a
    2368             :   // non-NULL reason string.
    2369             :   void TraceInline(Handle<JSFunction> target, Handle<JSFunction> caller,
    2370             :                    const char* failure_reason,
    2371             :                    TailCallMode tail_call_mode = TailCallMode::kDisallow);
    2372             : 
    2373             :   void HandleGlobalVariableAssignment(Variable* var, HValue* value,
    2374             :                                       FeedbackSlot slot, BailoutId ast_id);
    2375             : 
    2376             :   void HandlePropertyAssignment(Assignment* expr);
    2377             :   void HandleCompoundAssignment(Assignment* expr);
    2378             :   void HandlePolymorphicNamedFieldAccess(PropertyAccessType access_type,
    2379             :                                          Expression* expr, FeedbackSlot slot,
    2380             :                                          BailoutId ast_id, BailoutId return_id,
    2381             :                                          HValue* object, HValue* value,
    2382             :                                          SmallMapList* types,
    2383             :                                          Handle<Name> name);
    2384             : 
    2385             :   HValue* BuildAllocateExternalElements(
    2386             :       ExternalArrayType array_type,
    2387             :       bool is_zero_byte_offset,
    2388             :       HValue* buffer, HValue* byte_offset, HValue* length);
    2389             :   HValue* BuildAllocateFixedTypedArray(ExternalArrayType array_type,
    2390             :                                        size_t element_size,
    2391             :                                        ElementsKind fixed_elements_kind,
    2392             :                                        HValue* byte_length, HValue* length,
    2393             :                                        bool initialize);
    2394             : 
    2395             :   // TODO(adamk): Move all OrderedHashTable functions to their own class.
    2396             :   HValue* BuildOrderedHashTableHashToBucket(HValue* hash, HValue* num_buckets);
    2397             :   template <typename CollectionType>
    2398             :   HValue* BuildOrderedHashTableHashToEntry(HValue* table, HValue* hash,
    2399             :                                            HValue* num_buckets);
    2400             :   template <typename CollectionType>
    2401             :   HValue* BuildOrderedHashTableEntryToIndex(HValue* entry, HValue* num_buckets);
    2402             :   template <typename CollectionType>
    2403             :   HValue* BuildOrderedHashTableFindEntry(HValue* table, HValue* key,
    2404             :                                          HValue* hash);
    2405             :   template <typename CollectionType>
    2406             :   HValue* BuildOrderedHashTableAddEntry(HValue* table, HValue* key,
    2407             :                                         HValue* hash,
    2408             :                                         HIfContinuation* join_continuation);
    2409             :   template <typename CollectionType>
    2410             :   HValue* BuildAllocateOrderedHashTable();
    2411             :   template <typename CollectionType>
    2412             :   void BuildOrderedHashTableClear(HValue* receiver);
    2413             :   template <typename CollectionType>
    2414             :   void BuildJSCollectionDelete(CallRuntime* call,
    2415             :                                const Runtime::Function* c_function);
    2416             :   template <typename CollectionType>
    2417             :   void BuildJSCollectionHas(CallRuntime* call,
    2418             :                             const Runtime::Function* c_function);
    2419             :   HValue* BuildStringHashLoadIfIsStringAndHashComputed(
    2420             :       HValue* object, HIfContinuation* continuation);
    2421             : 
    2422      209615 :   Handle<JSFunction> array_function() {
    2423      628845 :     return handle(isolate()->native_context()->array_function());
    2424             :   }
    2425             : 
    2426             :   bool TryInlineArrayCall(Expression* expression, int argument_count,
    2427             :                           Handle<AllocationSite> site);
    2428             : 
    2429             :   void BuildInitializeInobjectProperties(HValue* receiver,
    2430             :                                          Handle<Map> initial_map);
    2431             : 
    2432             :   class PropertyAccessInfo {
    2433             :    public:
    2434      355073 :     PropertyAccessInfo(HOptimizedGraphBuilder* builder,
    2435             :                        PropertyAccessType access_type, Handle<Map> map,
    2436             :                        Handle<Name> name)
    2437             :         : builder_(builder),
    2438             :           access_type_(access_type),
    2439             :           map_(map),
    2440             :           name_(isolate()->factory()->InternalizeName(name)),
    2441             :           field_type_(HType::Tagged()),
    2442             :           access_(HObjectAccess::ForMap()),
    2443             :           lookup_type_(NOT_FOUND),
    2444             :           details_(PropertyDetails::Empty()),
    2445     1420292 :           store_mode_(STORE_TO_INITIALIZED_ENTRY) {}
    2446             : 
    2447             :     // Ensure the full store is performed.
    2448             :     void MarkAsInitializingStore() {
    2449             :       DCHECK_EQ(STORE, access_type_);
    2450       23473 :       store_mode_ = INITIALIZING_STORE;
    2451             :     }
    2452             : 
    2453             :     StoreFieldOrKeyedMode StoreMode() {
    2454             :       DCHECK_EQ(STORE, access_type_);
    2455             :       return store_mode_;
    2456             :     }
    2457             : 
    2458             :     // Checkes whether this PropertyAccessInfo can be handled as a monomorphic
    2459             :     // load named. It additionally fills in the fields necessary to generate the
    2460             :     // lookup code.
    2461             :     bool CanAccessMonomorphic();
    2462             : 
    2463             :     // Checks whether all types behave uniform when loading name. If all maps
    2464             :     // behave the same, a single monomorphic load instruction can be emitted,
    2465             :     // guarded by a single map-checks instruction that whether the receiver is
    2466             :     // an instance of any of the types.
    2467             :     // This method skips the first type in types, assuming that this
    2468             :     // PropertyAccessInfo is built for types->first().
    2469             :     bool CanAccessAsMonomorphic(SmallMapList* types);
    2470             : 
    2471             :     bool NeedsWrappingFor(Handle<JSFunction> target) const;
    2472             : 
    2473             :     Handle<Map> map();
    2474             :     Handle<Name> name() const { return name_; }
    2475             : 
    2476             :     bool IsJSObjectFieldAccessor() {
    2477             :       int offset;  // unused
    2478      334783 :       return Accessors::IsJSObjectFieldAccessor(map_, name_, &offset);
    2479             :     }
    2480             : 
    2481      488895 :     bool GetJSObjectFieldAccess(HObjectAccess* access) {
    2482             :       int offset;
    2483      488895 :       if (Accessors::IsJSObjectFieldAccessor(map_, name_, &offset)) {
    2484       35487 :         if (IsStringType()) {
    2485             :           DCHECK(Name::Equals(isolate()->factory()->length_string(), name_));
    2486       10228 :           *access = HObjectAccess::ForStringLength();
    2487       25259 :         } else if (IsArrayType()) {
    2488             :           DCHECK(Name::Equals(isolate()->factory()->length_string(), name_));
    2489       25259 :           *access = HObjectAccess::ForArrayLength(map_->elements_kind());
    2490             :         } else {
    2491           0 :           *access = HObjectAccess::ForMapAndOffset(map_, offset);
    2492             :         }
    2493             :         return true;
    2494             :       }
    2495             :       return false;
    2496             :     }
    2497             : 
    2498             :     bool has_holder() { return !holder_.is_null(); }
    2499       24273 :     bool IsLoad() const { return access_type_ == LOAD; }
    2500             : 
    2501     1128874 :     Isolate* isolate() const { return builder_->isolate(); }
    2502             :     Handle<JSObject> holder() { return holder_; }
    2503             :     Handle<Object> accessor() { return accessor_; }
    2504             :     Handle<Object> constant() { return constant_; }
    2505             :     Handle<Map> transition() { return transition_; }
    2506             :     SmallMapList* field_maps() { return &field_maps_; }
    2507             :     HType field_type() const { return field_type_; }
    2508             :     HObjectAccess access() { return access_; }
    2509             : 
    2510             :     bool IsFound() const { return lookup_type_ != NOT_FOUND; }
    2511       37215 :     bool IsProperty() const { return IsFound() && !IsTransition(); }
    2512       22238 :     bool IsTransition() const { return lookup_type_ == TRANSITION_TYPE; }
    2513             :     // TODO(ishell): rename to IsDataConstant() once constant field tracking
    2514             :     // is done.
    2515             :     bool IsDataConstantField() const {
    2516             :       return lookup_type_ == DESCRIPTOR_TYPE && details_.kind() == kData &&
    2517             :              details_.location() == kField && details_.constness() == kConst;
    2518             :     }
    2519             :     bool IsData() const {
    2520     1494093 :       return lookup_type_ == DESCRIPTOR_TYPE && details_.kind() == kData &&
    2521             :              details_.location() == kField;
    2522             :     }
    2523             :     bool IsDataConstant() const {
    2524      689238 :       return lookup_type_ == DESCRIPTOR_TYPE && details_.kind() == kData &&
    2525             :              details_.location() == kDescriptor;
    2526             :     }
    2527       17761 :     bool IsAccessorConstant() const {
    2528      829144 :       return !IsTransition() && details_.kind() == kAccessor &&
    2529             :              details_.location() == kDescriptor;
    2530             :     }
    2531             :     bool IsConfigurable() const { return details_.IsConfigurable(); }
    2532             :     bool IsReadOnly() const { return details_.IsReadOnly(); }
    2533             : 
    2534      121095 :     bool IsStringType() { return map_->instance_type() < FIRST_NONSTRING_TYPE; }
    2535             :     bool IsNumberType() { return map_->instance_type() == HEAP_NUMBER_TYPE; }
    2536       34283 :     bool IsValueWrapped() { return IsStringType() || IsNumberType(); }
    2537             :     bool IsArrayType() { return map_->instance_type() == JS_ARRAY_TYPE; }
    2538             : 
    2539             :    private:
    2540      201603 :     Handle<Object> GetConstantFromMap(Handle<Map> map) const {
    2541             :       DCHECK_EQ(DESCRIPTOR_TYPE, lookup_type_);
    2542             :       DCHECK(number_ < map->NumberOfOwnDescriptors());
    2543      403206 :       return handle(map->instance_descriptors()->GetValue(number_), isolate());
    2544             :     }
    2545             :     Handle<Object> GetAccessorsFromMap(Handle<Map> map) const {
    2546        7873 :       return GetConstantFromMap(map);
    2547             :     }
    2548             :     Handle<FieldType> GetFieldTypeFromMap(Handle<Map> map) const;
    2549       11980 :     Handle<Map> GetFieldOwnerFromMap(Handle<Map> map) const {
    2550             :       DCHECK(IsFound());
    2551             :       DCHECK(number_ < map->NumberOfOwnDescriptors());
    2552       35940 :       return handle(map->FindFieldOwner(number_));
    2553             :     }
    2554       96950 :     int GetLocalFieldIndexFromMap(Handle<Map> map) const {
    2555             :       DCHECK(lookup_type_ == DESCRIPTOR_TYPE ||
    2556             :              lookup_type_ == TRANSITION_TYPE);
    2557             :       DCHECK(number_ < map->NumberOfOwnDescriptors());
    2558       96950 :       int field_index = map->instance_descriptors()->GetFieldIndex(number_);
    2559       96950 :       return field_index - map->GetInObjectProperties();
    2560             :     }
    2561             : 
    2562      862008 :     void LookupDescriptor(Map* map, Name* name) {
    2563             :       DescriptorArray* descriptors = map->instance_descriptors();
    2564             :       int number = descriptors->SearchWithCache(isolate(), name, map);
    2565      862008 :       if (number == DescriptorArray::kNotFound) return NotFound();
    2566      298601 :       lookup_type_ = DESCRIPTOR_TYPE;
    2567      298601 :       details_ = descriptors->GetDetails(number);
    2568      298601 :       number_ = number;
    2569             :     }
    2570       17623 :     void LookupTransition(Map* map, Name* name, PropertyAttributes attributes) {
    2571             :       Map* target =
    2572       17623 :           TransitionArray::SearchTransition(map, kData, name, attributes);
    2573       35246 :       if (target == NULL) return NotFound();
    2574       17320 :       lookup_type_ = TRANSITION_TYPE;
    2575       17320 :       transition_ = handle(target);
    2576       17320 :       number_ = transition_->LastAdded();
    2577       17320 :       details_ = transition_->instance_descriptors()->GetDetails(number_);
    2578             :       MarkAsInitializingStore();
    2579             :     }
    2580             :     void NotFound() {
    2581      151692 :       lookup_type_ = NOT_FOUND;
    2582      151692 :       details_ = PropertyDetails::Empty();
    2583             :     }
    2584             :     Representation representation() const {
    2585             :       DCHECK(IsFound());
    2586             :       return details_.representation();
    2587             :     }
    2588       17623 :     bool IsTransitionToData() const {
    2589       52263 :       return IsTransition() && details_.kind() == kData &&
    2590             :              details_.location() == kField;
    2591             :     }
    2592             : 
    2593       24049 :     Zone* zone() { return builder_->zone(); }
    2594       11980 :     CompilationInfo* top_info() { return builder_->top_info(); }
    2595             :     CompilationInfo* current_info() { return builder_->current_info(); }
    2596             : 
    2597             :     bool LoadResult(Handle<Map> map);
    2598             :     bool LoadFieldMaps(Handle<Map> map);
    2599             :     bool LookupDescriptor();
    2600             :     bool LookupInPrototypes();
    2601             :     bool IsIntegerIndexedExotic();
    2602             :     bool IsCompatible(PropertyAccessInfo* other);
    2603             : 
    2604        3428 :     void GeneralizeRepresentation(Representation r) {
    2605             :       access_ = access_.WithRepresentation(
    2606        6856 :           access_.representation().generalize(r));
    2607        3428 :     }
    2608             : 
    2609             :     HOptimizedGraphBuilder* builder_;
    2610             :     PropertyAccessType access_type_;
    2611             :     Handle<Map> map_;
    2612             :     Handle<Name> name_;
    2613             :     Handle<JSObject> holder_;
    2614             :     Handle<Object> accessor_;
    2615             :     Handle<JSObject> api_holder_;
    2616             :     Handle<Object> constant_;
    2617             :     SmallMapList field_maps_;
    2618             :     HType field_type_;
    2619             :     HObjectAccess access_;
    2620             : 
    2621             :     enum { NOT_FOUND, DESCRIPTOR_TYPE, TRANSITION_TYPE } lookup_type_;
    2622             :     Handle<Map> transition_;
    2623             :     int number_;
    2624             :     PropertyDetails details_;
    2625             :     StoreFieldOrKeyedMode store_mode_;
    2626             :   };
    2627             : 
    2628             :   HValue* BuildMonomorphicAccess(PropertyAccessInfo* info, HValue* object,
    2629             :                                  HValue* checked_object, HValue* value,
    2630             :                                  BailoutId ast_id, BailoutId return_id,
    2631             :                                  bool can_inline_accessor = true);
    2632             : 
    2633             :   HValue* BuildNamedAccess(PropertyAccessType access, BailoutId ast_id,
    2634             :                            BailoutId reutrn_id, Expression* expr,
    2635             :                            FeedbackSlot slot, HValue* object, Handle<Name> name,
    2636             :                            HValue* value, bool is_uninitialized = false);
    2637             : 
    2638             :   void HandlePolymorphicCallNamed(Call* expr,
    2639             :                                   HValue* receiver,
    2640             :                                   SmallMapList* types,
    2641             :                                   Handle<String> name);
    2642             :   void HandleLiteralCompareTypeof(CompareOperation* expr,
    2643             :                                   Expression* sub_expr,
    2644             :                                   Handle<String> check);
    2645             :   void HandleLiteralCompareNil(CompareOperation* expr,
    2646             :                                Expression* sub_expr,
    2647             :                                NilValue nil);
    2648             : 
    2649             :   enum PushBeforeSimulateBehavior {
    2650             :     PUSH_BEFORE_SIMULATE,
    2651             :     NO_PUSH_BEFORE_SIMULATE
    2652             :   };
    2653             : 
    2654             :   HControlInstruction* BuildCompareInstruction(
    2655             :       Token::Value op, HValue* left, HValue* right, AstType* left_type,
    2656             :       AstType* right_type, AstType* combined_type, SourcePosition left_position,
    2657             :       SourcePosition right_position, PushBeforeSimulateBehavior push_sim_result,
    2658             :       BailoutId bailout_id);
    2659             : 
    2660             :   HInstruction* BuildStringCharCodeAt(HValue* string,
    2661             :                                       HValue* index);
    2662             : 
    2663             :   HValue* BuildBinaryOperation(
    2664             :       BinaryOperation* expr,
    2665             :       HValue* left,
    2666             :       HValue* right,
    2667             :       PushBeforeSimulateBehavior push_sim_result);
    2668             :   HInstruction* BuildIncrement(CountOperation* expr);
    2669             :   HInstruction* BuildKeyedGeneric(PropertyAccessType access_type,
    2670             :                                   Expression* expr, FeedbackSlot slot,
    2671             :                                   HValue* object, HValue* key, HValue* value);
    2672             : 
    2673             :   HInstruction* TryBuildConsolidatedElementLoad(HValue* object,
    2674             :                                                 HValue* key,
    2675             :                                                 HValue* val,
    2676             :                                                 SmallMapList* maps);
    2677             : 
    2678             :   LoadKeyedHoleMode BuildKeyedHoleMode(Handle<Map> map);
    2679             : 
    2680             :   HInstruction* BuildMonomorphicElementAccess(HValue* object,
    2681             :                                               HValue* key,
    2682             :                                               HValue* val,
    2683             :                                               HValue* dependency,
    2684             :                                               Handle<Map> map,
    2685             :                                               PropertyAccessType access_type,
    2686             :                                               KeyedAccessStoreMode store_mode);
    2687             : 
    2688             :   HValue* HandlePolymorphicElementAccess(Expression* expr, FeedbackSlot slot,
    2689             :                                          HValue* object, HValue* key,
    2690             :                                          HValue* val, SmallMapList* maps,
    2691             :                                          PropertyAccessType access_type,
    2692             :                                          KeyedAccessStoreMode store_mode,
    2693             :                                          bool* has_side_effects);
    2694             : 
    2695             :   HValue* HandleKeyedElementAccess(HValue* obj, HValue* key, HValue* val,
    2696             :                                    Expression* expr, FeedbackSlot slot,
    2697             :                                    BailoutId ast_id, BailoutId return_id,
    2698             :                                    PropertyAccessType access_type,
    2699             :                                    bool* has_side_effects);
    2700             : 
    2701             :   HInstruction* BuildNamedGeneric(PropertyAccessType access, Expression* expr,
    2702             :                                   FeedbackSlot slot, HValue* object,
    2703             :                                   Handle<Name> name, HValue* value,
    2704             :                                   bool is_uninitialized = false);
    2705             : 
    2706             :   HCheckMaps* AddCheckMap(HValue* object, Handle<Map> map);
    2707             : 
    2708             :   void BuildLoad(Property* property,
    2709             :                  BailoutId ast_id);
    2710             :   void PushLoad(Property* property,
    2711             :                 HValue* object,
    2712             :                 HValue* key);
    2713             : 
    2714             :   void BuildStoreForEffect(Expression* expression, Property* prop,
    2715             :                            FeedbackSlot slot, BailoutId ast_id,
    2716             :                            BailoutId return_id, HValue* object, HValue* key,
    2717             :                            HValue* value);
    2718             : 
    2719             :   void BuildStore(Expression* expression, Property* prop, FeedbackSlot slot,
    2720             :                   BailoutId ast_id, BailoutId return_id,
    2721             :                   bool is_uninitialized = false);
    2722             : 
    2723             :   HInstruction* BuildLoadNamedField(PropertyAccessInfo* info,
    2724             :                                     HValue* checked_object);
    2725             :   HValue* BuildStoreNamedField(PropertyAccessInfo* info, HValue* checked_object,
    2726             :                                HValue* value);
    2727             : 
    2728             :   HValue* BuildContextChainWalk(Variable* var);
    2729             : 
    2730             :   HValue* AddThisFunction();
    2731             :   HInstruction* BuildThisFunction();
    2732             : 
    2733             :   HInstruction* BuildFastLiteral(Handle<JSObject> boilerplate_object,
    2734             :                                  AllocationSiteUsageContext* site_context);
    2735             : 
    2736             :   void BuildEmitObjectHeader(Handle<JSObject> boilerplate_object,
    2737             :                              HInstruction* object);
    2738             : 
    2739             :   void BuildEmitInObjectProperties(Handle<JSObject> boilerplate_object,
    2740             :                                    HInstruction* object,
    2741             :                                    AllocationSiteUsageContext* site_context,
    2742             :                                    PretenureFlag pretenure_flag);
    2743             : 
    2744             :   void BuildEmitElements(Handle<JSObject> boilerplate_object,
    2745             :                          Handle<FixedArrayBase> elements,
    2746             :                          HValue* object_elements,
    2747             :                          AllocationSiteUsageContext* site_context);
    2748             : 
    2749             :   void BuildEmitFixedDoubleArray(Handle<FixedArrayBase> elements,
    2750             :                                  ElementsKind kind,
    2751             :                                  HValue* object_elements);
    2752             : 
    2753             :   void BuildEmitFixedArray(Handle<FixedArrayBase> elements,
    2754             :                            ElementsKind kind,
    2755             :                            HValue* object_elements,
    2756             :                            AllocationSiteUsageContext* site_context);
    2757             : 
    2758             :   void AddCheckPrototypeMaps(Handle<JSObject> holder,
    2759             :                              Handle<Map> receiver_map);
    2760             : 
    2761             :   void BuildEnsureCallable(HValue* object);
    2762             : 
    2763             :   HInstruction* NewCallFunction(HValue* function, int argument_count,
    2764             :                                 TailCallMode syntactic_tail_call_mode,
    2765             :                                 ConvertReceiverMode convert_mode,
    2766             :                                 TailCallMode tail_call_mode);
    2767             : 
    2768             :   HInstruction* NewCallFunctionViaIC(HValue* function, int argument_count,
    2769             :                                      TailCallMode syntactic_tail_call_mode,
    2770             :                                      ConvertReceiverMode convert_mode,
    2771             :                                      TailCallMode tail_call_mode,
    2772             :                                      FeedbackSlot slot);
    2773             : 
    2774             :   HInstruction* NewCallConstantFunction(Handle<JSFunction> target,
    2775             :                                         int argument_count,
    2776             :                                         TailCallMode syntactic_tail_call_mode,
    2777             :                                         TailCallMode tail_call_mode);
    2778             : 
    2779             :   bool CanBeFunctionApplyArguments(Call* expr);
    2780             : 
    2781             :   bool IsAnyParameterContextAllocated();
    2782             : 
    2783             :   // The translation state of the currently-being-translated function.
    2784             :   FunctionState* function_state_;
    2785             : 
    2786             :   // The base of the function state stack.
    2787             :   FunctionState initial_function_state_;
    2788             : 
    2789             :   // Expression context of the currently visited subexpression. NULL when
    2790             :   // visiting statements.
    2791             :   AstContext* ast_context_;
    2792             : 
    2793             :   // A stack of breakable statements entered.
    2794             :   BreakAndContinueScope* break_scope_;
    2795             : 
    2796             :   int inlined_count_;
    2797             :   ZoneList<Handle<Object> > globals_;
    2798             : 
    2799             :   bool inline_bailout_;
    2800             : 
    2801             :   HOsrBuilder* osr_;
    2802             : 
    2803             :   AstTypeBounds bounds_;
    2804             : 
    2805             :   friend class FunctionState;  // Pushes and pops the state stack.
    2806             :   friend class AstContext;  // Pushes and pops the AST context stack.
    2807             :   friend class HOsrBuilder;
    2808             : 
    2809             :   DISALLOW_COPY_AND_ASSIGN(HOptimizedGraphBuilder);
    2810             : };
    2811             : 
    2812             : 
    2813             : Zone* AstContext::zone() const { return owner_->zone(); }
    2814             : 
    2815             : 
    2816           0 : class HStatistics final : public Malloced {
    2817             :  public:
    2818           0 :   HStatistics()
    2819             :       : times_(5),
    2820             :         names_(5),
    2821             :         sizes_(5),
    2822             :         total_size_(0),
    2823           0 :         source_size_(0) { }
    2824             : 
    2825             :   void Initialize(CompilationInfo* info);
    2826             :   void Print();
    2827             :   void SaveTiming(const char* name, base::TimeDelta time, size_t size);
    2828             : 
    2829             :   void IncrementFullCodeGen(base::TimeDelta full_code_gen) {
    2830             :     full_code_gen_ += full_code_gen;
    2831             :   }
    2832             : 
    2833             :   void IncrementCreateGraph(base::TimeDelta delta) { create_graph_ += delta; }
    2834             : 
    2835             :   void IncrementOptimizeGraph(base::TimeDelta delta) {
    2836             :     optimize_graph_ += delta;
    2837             :   }
    2838             : 
    2839             :   void IncrementGenerateCode(base::TimeDelta delta) { generate_code_ += delta; }
    2840             : 
    2841             :   void IncrementSubtotals(base::TimeDelta create_graph,
    2842             :                           base::TimeDelta optimize_graph,
    2843             :                           base::TimeDelta generate_code) {
    2844             :     IncrementCreateGraph(create_graph);
    2845             :     IncrementOptimizeGraph(optimize_graph);
    2846             :     IncrementGenerateCode(generate_code);
    2847             :   }
    2848             : 
    2849             :  private:
    2850             :   List<base::TimeDelta> times_;
    2851             :   List<const char*> names_;
    2852             :   List<size_t> sizes_;
    2853             :   base::TimeDelta create_graph_;
    2854             :   base::TimeDelta optimize_graph_;
    2855             :   base::TimeDelta generate_code_;
    2856             :   size_t total_size_;
    2857             :   base::TimeDelta full_code_gen_;
    2858             :   double source_size_;
    2859             : };
    2860             : 
    2861             : 
    2862             : class HPhase : public CompilationPhase {
    2863             :  public:
    2864     5954989 :   HPhase(const char* name, HGraph* graph)
    2865             :       : CompilationPhase(name, graph->info()),
    2866     5954989 :         graph_(graph) { }
    2867             :   ~HPhase();
    2868             : 
    2869             :  protected:
    2870             :   HGraph* graph() const { return graph_; }
    2871             : 
    2872             :  private:
    2873             :   HGraph* graph_;
    2874             : 
    2875             :   DISALLOW_COPY_AND_ASSIGN(HPhase);
    2876             : };
    2877             : 
    2878             : 
    2879             : class HTracer final : public Malloced {
    2880             :  public:
    2881           0 :   explicit HTracer(int isolate_id)
    2882           0 :       : trace_(&string_allocator_), indent_(0) {
    2883           0 :     if (FLAG_trace_hydrogen_file == NULL) {
    2884             :       SNPrintF(filename_,
    2885             :                "hydrogen-%d-%d.cfg",
    2886             :                base::OS::GetCurrentProcessId(),
    2887           0 :                isolate_id);
    2888             :     } else {
    2889           0 :       StrNCpy(filename_, FLAG_trace_hydrogen_file, filename_.length());
    2890             :     }
    2891           0 :     WriteChars(filename_.start(), "", 0, false);
    2892           0 :   }
    2893             : 
    2894             :   void TraceCompilation(CompilationInfo* info);
    2895             :   void TraceHydrogen(const char* name, HGraph* graph);
    2896             :   void TraceLithium(const char* name, LChunk* chunk);
    2897             :   void TraceLiveRanges(const char* name, LAllocator* allocator);
    2898             : 
    2899             :  private:
    2900             :   class Tag final BASE_EMBEDDED {
    2901             :    public:
    2902           0 :     Tag(HTracer* tracer, const char* name) {
    2903           0 :       name_ = name;
    2904           0 :       tracer_ = tracer;
    2905             :       tracer->PrintIndent();
    2906           0 :       tracer->trace_.Add("begin_%s\n", name);
    2907           0 :       tracer->indent_++;
    2908           0 :     }
    2909             : 
    2910           0 :     ~Tag() {
    2911           0 :       tracer_->indent_--;
    2912             :       tracer_->PrintIndent();
    2913           0 :       tracer_->trace_.Add("end_%s\n", name_);
    2914             :       DCHECK(tracer_->indent_ >= 0);
    2915           0 :       tracer_->FlushToFile();
    2916           0 :     }
    2917             : 
    2918             :    private:
    2919             :     HTracer* tracer_;
    2920             :     const char* name_;
    2921             :   };
    2922             : 
    2923             :   void TraceLiveRange(LiveRange* range, const char* type, Zone* zone);
    2924             :   void Trace(const char* name, HGraph* graph, LChunk* chunk);
    2925             :   void FlushToFile();
    2926             : 
    2927           0 :   void PrintEmptyProperty(const char* name) {
    2928             :     PrintIndent();
    2929           0 :     trace_.Add("%s\n", name);
    2930           0 :   }
    2931             : 
    2932           0 :   void PrintStringProperty(const char* name, const char* value) {
    2933             :     PrintIndent();
    2934           0 :     trace_.Add("%s \"%s\"\n", name, value);
    2935           0 :   }
    2936             : 
    2937           0 :   void PrintLongProperty(const char* name, int64_t value) {
    2938             :     PrintIndent();
    2939           0 :     trace_.Add("%s %d000\n", name, static_cast<int>(value / 1000));
    2940           0 :   }
    2941             : 
    2942           0 :   void PrintBlockProperty(const char* name, int block_id) {
    2943             :     PrintIndent();
    2944           0 :     trace_.Add("%s \"B%d\"\n", name, block_id);
    2945           0 :   }
    2946             : 
    2947           0 :   void PrintIntProperty(const char* name, int value) {
    2948             :     PrintIndent();
    2949           0 :     trace_.Add("%s %d\n", name, value);
    2950           0 :   }
    2951             : 
    2952             :   void PrintIndent() {
    2953           0 :     for (int i = 0; i < indent_; i++) {
    2954           0 :       trace_.Add("  ");
    2955             :     }
    2956             :   }
    2957             : 
    2958             :   EmbeddedVector<char, 64> filename_;
    2959             :   HeapStringAllocator string_allocator_;
    2960             :   StringStream trace_;
    2961             :   int indent_;
    2962             : };
    2963             : 
    2964             : 
    2965             : class NoObservableSideEffectsScope final {
    2966             :  public:
    2967             :   explicit NoObservableSideEffectsScope(HGraphBuilder* builder) :
    2968             :       builder_(builder) {
    2969      758035 :     builder_->graph()->IncrementInNoSideEffectsScope();
    2970             :   }
    2971             :   ~NoObservableSideEffectsScope() {
    2972      758035 :     builder_->graph()->DecrementInNoSideEffectsScope();
    2973             :   }
    2974             : 
    2975             :  private:
    2976             :   HGraphBuilder* builder_;
    2977             : };
    2978             : 
    2979             : class DoExpressionScope final {
    2980             :  public:
    2981             :   explicit DoExpressionScope(HOptimizedGraphBuilder* builder)
    2982             :       : builder_(builder) {
    2983          62 :     builder_->function_state()->IncrementInDoExpressionScope();
    2984             :   }
    2985             :   ~DoExpressionScope() {
    2986          62 :     builder_->function_state()->DecrementInDoExpressionScope();
    2987             :   }
    2988             : 
    2989             :  private:
    2990             :   HOptimizedGraphBuilder* builder_;
    2991             : };
    2992             : 
    2993             : }  // namespace internal
    2994             : }  // namespace v8
    2995             : 
    2996             : #endif  // V8_CRANKSHAFT_HYDROGEN_H_

Generated by: LCOV version 1.10