v8  3.25.30(node0.11.13)
V8 is Google's open source JavaScript engine
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
hydrogen.h
Go to the documentation of this file.
1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are
4 // met:
5 //
6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided
11 // with the distribution.
12 // * Neither the name of Google Inc. nor the names of its
13 // contributors may be used to endorse or promote products derived
14 // from this software without specific prior written permission.
15 //
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 
28 #ifndef V8_HYDROGEN_H_
29 #define V8_HYDROGEN_H_
30 
31 #include "v8.h"
32 
33 #include "accessors.h"
34 #include "allocation.h"
35 #include "ast.h"
36 #include "compiler.h"
37 #include "hydrogen-instructions.h"
38 #include "zone.h"
39 #include "scopes.h"
40 
41 namespace v8 {
42 namespace internal {
43 
44 // Forward declarations.
45 class BitVector;
46 class FunctionState;
47 class HEnvironment;
48 class HGraph;
49 class HLoopInformation;
50 class HOsrBuilder;
51 class HTracer;
52 class LAllocator;
53 class LChunk;
54 class LiveRange;
55 
56 
57 class HBasicBlock V8_FINAL : public ZoneObject {
58  public:
59  explicit HBasicBlock(HGraph* graph);
61 
62  // Simple accessors.
63  int block_id() const { return block_id_; }
64  void set_block_id(int id) { block_id_ = id; }
65  HGraph* graph() const { return graph_; }
66  Isolate* isolate() const;
67  const ZoneList<HPhi*>* phis() const { return &phis_; }
68  HInstruction* first() const { return first_; }
69  HInstruction* last() const { return last_; }
70  void set_last(HInstruction* instr) { last_ = instr; }
71  HControlInstruction* end() const { return end_; }
72  HLoopInformation* loop_information() const { return loop_information_; }
73  HLoopInformation* current_loop() const {
74  return IsLoopHeader() ? loop_information()
75  : (parent_loop_header() != NULL
76  ? parent_loop_header()->loop_information() : NULL);
77  }
78  const ZoneList<HBasicBlock*>* predecessors() const { return &predecessors_; }
79  bool HasPredecessor() const { return predecessors_.length() > 0; }
81  return &dominated_blocks_;
82  }
83  const ZoneList<int>* deleted_phis() const {
84  return &deleted_phis_;
85  }
86  void RecordDeletedPhi(int merge_index) {
87  deleted_phis_.Add(merge_index, zone());
88  }
89  HBasicBlock* dominator() const { return dominator_; }
90  HEnvironment* last_environment() const { return last_environment_; }
91  int argument_count() const { return argument_count_; }
92  void set_argument_count(int count) { argument_count_ = count; }
93  int first_instruction_index() const { return first_instruction_index_; }
94  void set_first_instruction_index(int index) {
95  first_instruction_index_ = index;
96  }
97  int last_instruction_index() const { return last_instruction_index_; }
98  void set_last_instruction_index(int index) {
99  last_instruction_index_ = index;
100  }
101  bool is_osr_entry() { return is_osr_entry_; }
102  void set_osr_entry() { is_osr_entry_ = true; }
103 
104  void AttachLoopInformation();
105  void DetachLoopInformation();
106  bool IsLoopHeader() const { return loop_information() != NULL; }
107  bool IsStartBlock() const { return block_id() == 0; }
108  void PostProcessLoopHeader(IterationStatement* stmt);
109 
110  bool IsFinished() const { return end_ != NULL; }
111  void AddPhi(HPhi* phi);
112  void RemovePhi(HPhi* phi);
113  void AddInstruction(HInstruction* instr, HSourcePosition position);
114  bool Dominates(HBasicBlock* other) const;
115  bool EqualToOrDominates(HBasicBlock* other) const;
116  int LoopNestingDepth() const;
117 
118  void SetInitialEnvironment(HEnvironment* env);
120  ASSERT(IsFinished());
121  ASSERT(end()->SuccessorCount() == 0);
122  last_environment_ = NULL;
123  }
124  bool HasEnvironment() const { return last_environment_ != NULL; }
125  void UpdateEnvironment(HEnvironment* env);
126  HBasicBlock* parent_loop_header() const { return parent_loop_header_; }
127 
128  void set_parent_loop_header(HBasicBlock* block) {
129  ASSERT(parent_loop_header_ == NULL);
130  parent_loop_header_ = block;
131  }
132 
133  bool HasParentLoopHeader() const { return parent_loop_header_ != NULL; }
134 
135  void SetJoinId(BailoutId ast_id);
136 
137  int PredecessorIndexOf(HBasicBlock* predecessor) const;
138  HPhi* AddNewPhi(int merged_index);
139  HSimulate* AddNewSimulate(BailoutId ast_id,
140  HSourcePosition position,
141  RemovableSimulate removable = FIXED_SIMULATE) {
142  HSimulate* instr = CreateSimulate(ast_id, removable);
143  AddInstruction(instr, position);
144  return instr;
145  }
146  void AssignCommonDominator(HBasicBlock* other);
147  void AssignLoopSuccessorDominators();
148 
149  // If a target block is tagged as an inline function return, all
150  // predecessors should contain the inlined exit sequence:
151  //
152  // LeaveInlined
153  // Simulate (caller's environment)
154  // Goto (target block)
155  bool IsInlineReturnTarget() const { return is_inline_return_target_; }
156  void MarkAsInlineReturnTarget(HBasicBlock* inlined_entry_block) {
157  is_inline_return_target_ = true;
158  inlined_entry_block_ = inlined_entry_block;
159  }
160  HBasicBlock* inlined_entry_block() { return inlined_entry_block_; }
161 
162  bool IsDeoptimizing() const {
163  return end() != NULL && end()->IsDeoptimize();
164  }
165 
166  void MarkUnreachable();
167  bool IsUnreachable() const { return !is_reachable_; }
168  bool IsReachable() const { return is_reachable_; }
169 
171  return dominates_loop_successors_;
172  }
174  dominates_loop_successors_ = true;
175  }
176 
177  void MarkSuccEdgeUnreachable(int succ);
178 
179  inline Zone* zone() const;
180 
181 #ifdef DEBUG
182  void Verify();
183 #endif
184 
185  protected:
186  friend class HGraphBuilder;
187 
188  HSimulate* CreateSimulate(BailoutId ast_id, RemovableSimulate removable);
189  void Finish(HControlInstruction* last, HSourcePosition position);
190  void FinishExit(HControlInstruction* instruction, HSourcePosition position);
191  void Goto(HBasicBlock* block,
192  HSourcePosition position,
193  FunctionState* state = NULL,
194  bool add_simulate = true);
195  void GotoNoSimulate(HBasicBlock* block, HSourcePosition position) {
196  Goto(block, position, NULL, false);
197  }
198 
199  // Add the inlined function exit sequence, adding an HLeaveInlined
200  // instruction and updating the bailout environment.
201  void AddLeaveInlined(HValue* return_value,
202  FunctionState* state,
203  HSourcePosition position);
204 
205  private:
206  void RegisterPredecessor(HBasicBlock* pred);
207  void AddDominatedBlock(HBasicBlock* block);
208 
209  int block_id_;
210  HGraph* graph_;
211  ZoneList<HPhi*> phis_;
212  HInstruction* first_;
213  HInstruction* last_;
215  HLoopInformation* loop_information_;
216  ZoneList<HBasicBlock*> predecessors_;
217  HBasicBlock* dominator_;
218  ZoneList<HBasicBlock*> dominated_blocks_;
219  HEnvironment* last_environment_;
220  // Outgoing parameter count at block exit, set during lithium translation.
221  int argument_count_;
222  // Instruction indices into the lithium code stream.
223  int first_instruction_index_;
224  int last_instruction_index_;
225  ZoneList<int> deleted_phis_;
226  HBasicBlock* parent_loop_header_;
227  // For blocks marked as inline return target: the block with HEnterInlined.
228  HBasicBlock* inlined_entry_block_;
229  bool is_inline_return_target_ : 1;
230  bool is_reachable_ : 1;
231  bool dominates_loop_successors_ : 1;
232  bool is_osr_entry_ : 1;
233 };
234 
235 
236 class HPredecessorIterator V8_FINAL BASE_EMBEDDED {
237  public:
238  explicit HPredecessorIterator(HBasicBlock* block)
239  : predecessor_list_(block->predecessors()), current_(0) { }
240 
241  bool Done() { return current_ >= predecessor_list_->length(); }
242  HBasicBlock* Current() { return predecessor_list_->at(current_); }
243  void Advance() { current_++; }
244 
245  private:
246  const ZoneList<HBasicBlock*>* predecessor_list_;
247  int current_;
248 };
249 
250 
251 class HInstructionIterator V8_FINAL BASE_EMBEDDED {
252  public:
253  explicit HInstructionIterator(HBasicBlock* block)
254  : instr_(block->first()) {
255  next_ = Done() ? NULL : instr_->next();
256  }
257 
258  inline bool Done() const { return instr_ == NULL; }
259  inline HInstruction* Current() { return instr_; }
260  inline void Advance() {
261  instr_ = next_;
262  next_ = Done() ? NULL : instr_->next();
263  }
264 
265  private:
266  HInstruction* instr_;
267  HInstruction* next_;
268 };
269 
270 
271 class HLoopInformation V8_FINAL : public ZoneObject {
272  public:
273  HLoopInformation(HBasicBlock* loop_header, Zone* zone)
274  : back_edges_(4, zone),
275  loop_header_(loop_header),
276  blocks_(8, zone),
277  stack_check_(NULL) {
278  blocks_.Add(loop_header, zone);
279  }
281 
282  const ZoneList<HBasicBlock*>* back_edges() const { return &back_edges_; }
283  const ZoneList<HBasicBlock*>* blocks() const { return &blocks_; }
284  HBasicBlock* loop_header() const { return loop_header_; }
285  HBasicBlock* GetLastBackEdge() const;
286  void RegisterBackEdge(HBasicBlock* block);
287 
288  HStackCheck* stack_check() const { return stack_check_; }
289  void set_stack_check(HStackCheck* stack_check) {
290  stack_check_ = stack_check;
291  }
292 
293  bool IsNestedInThisLoop(HLoopInformation* other) {
294  while (other != NULL) {
295  if (other == this) {
296  return true;
297  }
298  other = other->parent_loop();
299  }
300  return false;
301  }
302  HLoopInformation* parent_loop() {
303  HBasicBlock* parent_header = loop_header()->parent_loop_header();
304  return parent_header != NULL ? parent_header->loop_information() : NULL;
305  }
306 
307  private:
308  void AddBlock(HBasicBlock* block);
309 
310  ZoneList<HBasicBlock*> back_edges_;
311  HBasicBlock* loop_header_;
312  ZoneList<HBasicBlock*> blocks_;
313  HStackCheck* stack_check_;
314 };
315 
316 
317 class BoundsCheckTable;
318 class InductionVariableBlocksTable;
319 class HGraph V8_FINAL : public ZoneObject {
320  public:
321  explicit HGraph(CompilationInfo* info);
322 
323  Isolate* isolate() const { return isolate_; }
324  Zone* zone() const { return zone_; }
325  CompilationInfo* info() const { return info_; }
326 
327  const ZoneList<HBasicBlock*>* blocks() const { return &blocks_; }
328  const ZoneList<HPhi*>* phi_list() const { return phi_list_; }
329  HBasicBlock* entry_block() const { return entry_block_; }
330  HEnvironment* start_environment() const { return start_environment_; }
331 
332  void FinalizeUniqueness();
333  bool ProcessArgumentsObject();
334  void OrderBlocks();
335  void AssignDominators();
336  void RestoreActualValues();
337 
338  // Returns false if there are phi-uses of the arguments-object
339  // which are not supported by the optimizing compiler.
340  bool CheckArgumentsPhiUses();
341 
342  // Returns false if there are phi-uses of an uninitialized const
343  // which are not supported by the optimizing compiler.
344  bool CheckConstPhiUses();
345 
346  void CollectPhis();
347 
348  HConstant* GetConstantUndefined();
349  HConstant* GetConstant0();
350  HConstant* GetConstant1();
351  HConstant* GetConstantMinus1();
352  HConstant* GetConstantTrue();
353  HConstant* GetConstantFalse();
354  HConstant* GetConstantHole();
355  HConstant* GetConstantNull();
356  HConstant* GetInvalidContext();
357 
358  bool IsConstantUndefined(HConstant* constant);
359  bool IsConstant0(HConstant* constant);
360  bool IsConstant1(HConstant* constant);
361  bool IsConstantMinus1(HConstant* constant);
362  bool IsConstantTrue(HConstant* constant);
363  bool IsConstantFalse(HConstant* constant);
364  bool IsConstantHole(HConstant* constant);
365  bool IsConstantNull(HConstant* constant);
366  bool IsStandardConstant(HConstant* constant);
367 
368  HBasicBlock* CreateBasicBlock();
369  HArgumentsObject* GetArgumentsObject() const {
370  return arguments_object_.get();
371  }
372 
373  void SetArgumentsObject(HArgumentsObject* object) {
374  arguments_object_.set(object);
375  }
376 
377  int GetMaximumValueID() const { return values_.length(); }
378  int GetNextBlockID() { return next_block_id_++; }
379  int GetNextValueID(HValue* value) {
380  ASSERT(!disallow_adding_new_values_);
381  values_.Add(value, zone());
382  return values_.length() - 1;
383  }
384  HValue* LookupValue(int id) const {
385  if (id >= 0 && id < values_.length()) return values_[id];
386  return NULL;
387  }
389  disallow_adding_new_values_ = true;
390  }
391 
392  bool Optimize(BailoutReason* bailout_reason);
393 
394 #ifdef DEBUG
395  void Verify(bool do_full_verify) const;
396 #endif
397 
398  bool has_osr() {
399  return osr_ != NULL;
400  }
401 
402  void set_osr(HOsrBuilder* osr) {
403  osr_ = osr;
404  }
405 
407  return osr_;
408  }
409 
411  type_change_checksum_ += delta;
412  return type_change_checksum_;
413  }
414 
415  void update_maximum_environment_size(int environment_size) {
416  if (environment_size > maximum_environment_size_) {
417  maximum_environment_size_ = environment_size;
418  }
419  }
420  int maximum_environment_size() { return maximum_environment_size_; }
421 
423  return use_optimistic_licm_;
424  }
425 
426  void set_use_optimistic_licm(bool value) {
427  use_optimistic_licm_ = value;
428  }
429 
430  void MarkRecursive() {
431  is_recursive_ = true;
432  }
433 
434  bool is_recursive() const {
435  return is_recursive_;
436  }
437 
439  // Add map dependency if not already added.
440  if (depends_on_empty_array_proto_elements_) return;
441  isolate()->initial_object_prototype()->map()->AddDependentCompilationInfo(
443  isolate()->initial_array_prototype()->map()->AddDependentCompilationInfo(
445  depends_on_empty_array_proto_elements_ = true;
446  }
447 
449  return depends_on_empty_array_proto_elements_;
450  }
451 
453  ASSERT(uint32_instructions_ == NULL || !uint32_instructions_->is_empty());
454  return uint32_instructions_ != NULL;
455  }
456 
458  ASSERT(uint32_instructions_ == NULL || !uint32_instructions_->is_empty());
459  return uint32_instructions_;
460  }
461 
463  ASSERT(uint32_instructions_ == NULL || !uint32_instructions_->is_empty());
464  if (uint32_instructions_ == NULL) {
465  uint32_instructions_ = new(zone()) ZoneList<HInstruction*>(4, zone());
466  }
467  uint32_instructions_->Add(instr, zone());
468  }
469 
470  void IncrementInNoSideEffectsScope() { no_side_effects_scope_count_++; }
471  void DecrementInNoSideEffectsScope() { no_side_effects_scope_count_--; }
472  bool IsInsideNoSideEffectsScope() { return no_side_effects_scope_count_ > 0; }
473 
474  // If we are tracking source positions then this function assigns a unique
475  // identifier to each inlining and dumps function source if it was inlined
476  // for the first time during the current optimization.
477  int TraceInlinedFunction(Handle<SharedFunctionInfo> shared,
478  HSourcePosition position);
479 
480  // Converts given HSourcePosition to the absolute offset from the start of
481  // the corresponding script.
482  int SourcePositionToScriptPosition(HSourcePosition position);
483 
484  private:
485  HConstant* ReinsertConstantIfNecessary(HConstant* constant);
486  HConstant* GetConstant(SetOncePointer<HConstant>* pointer,
487  int32_t integer_value);
488 
489  template<class Phase>
490  void Run() {
491  Phase phase(this);
492  phase.Run();
493  }
494 
495  void EliminateRedundantBoundsChecksUsingInductionVariables();
496 
497  Isolate* isolate_;
498  int next_block_id_;
499  HBasicBlock* entry_block_;
500  HEnvironment* start_environment_;
501  ZoneList<HBasicBlock*> blocks_;
502  ZoneList<HValue*> values_;
503  ZoneList<HPhi*>* phi_list_;
504  ZoneList<HInstruction*>* uint32_instructions_;
505  SetOncePointer<HConstant> constant_undefined_;
506  SetOncePointer<HConstant> constant_0_;
507  SetOncePointer<HConstant> constant_1_;
508  SetOncePointer<HConstant> constant_minus1_;
509  SetOncePointer<HConstant> constant_true_;
510  SetOncePointer<HConstant> constant_false_;
511  SetOncePointer<HConstant> constant_the_hole_;
512  SetOncePointer<HConstant> constant_null_;
513  SetOncePointer<HConstant> constant_invalid_context_;
514  SetOncePointer<HArgumentsObject> arguments_object_;
515 
516  HOsrBuilder* osr_;
517 
518  CompilationInfo* info_;
519  Zone* zone_;
520 
521  bool is_recursive_;
522  bool use_optimistic_licm_;
523  bool depends_on_empty_array_proto_elements_;
524  int type_change_checksum_;
525  int maximum_environment_size_;
526  int no_side_effects_scope_count_;
527  bool disallow_adding_new_values_;
528 
529  class InlinedFunctionInfo {
530  public:
531  explicit InlinedFunctionInfo(Handle<SharedFunctionInfo> shared)
532  : shared_(shared), start_position_(shared->start_position()) {
533  }
534 
535  Handle<SharedFunctionInfo> shared() const { return shared_; }
536  int start_position() const { return start_position_; }
537 
538  private:
539  Handle<SharedFunctionInfo> shared_;
540  int start_position_;
541  };
542 
543  int next_inline_id_;
544  ZoneList<InlinedFunctionInfo> inlined_functions_;
545 
546  DISALLOW_COPY_AND_ASSIGN(HGraph);
547 };
548 
549 
550 Zone* HBasicBlock::zone() const { return graph_->zone(); }
551 
552 
553 // Type of stack frame an environment might refer to.
554 enum FrameType {
561 };
562 
563 
564 class HEnvironment V8_FINAL : public ZoneObject {
565  public:
566  HEnvironment(HEnvironment* outer,
567  Scope* scope,
568  Handle<JSFunction> closure,
569  Zone* zone);
570 
571  HEnvironment(Zone* zone, int parameter_count);
572 
573  HEnvironment* arguments_environment() {
574  return outer()->frame_type() == ARGUMENTS_ADAPTOR ? outer() : this;
575  }
576 
577  // Simple accessors.
578  Handle<JSFunction> closure() const { return closure_; }
579  const ZoneList<HValue*>* values() const { return &values_; }
580  const GrowableBitVector* assigned_variables() const {
581  return &assigned_variables_;
582  }
583  FrameType frame_type() const { return frame_type_; }
584  int parameter_count() const { return parameter_count_; }
585  int specials_count() const { return specials_count_; }
586  int local_count() const { return local_count_; }
587  HEnvironment* outer() const { return outer_; }
588  int pop_count() const { return pop_count_; }
589  int push_count() const { return push_count_; }
590 
591  BailoutId ast_id() const { return ast_id_; }
592  void set_ast_id(BailoutId id) { ast_id_ = id; }
593 
594  HEnterInlined* entry() const { return entry_; }
595  void set_entry(HEnterInlined* entry) { entry_ = entry; }
596 
597  int length() const { return values_.length(); }
598 
600  return parameter_count() + specials_count() + local_count();
601  }
602 
603  int first_local_index() const {
604  return parameter_count() + specials_count();
605  }
606 
607  void Bind(Variable* variable, HValue* value) {
608  Bind(IndexFor(variable), value);
609  }
610 
611  void Bind(int index, HValue* value);
612 
613  void BindContext(HValue* value) {
614  Bind(parameter_count(), value);
615  }
616 
617  HValue* Lookup(Variable* variable) const {
618  return Lookup(IndexFor(variable));
619  }
620 
621  HValue* Lookup(int index) const {
622  HValue* result = values_[index];
623  ASSERT(result != NULL);
624  return result;
625  }
626 
627  HValue* context() const {
628  // Return first special.
629  return Lookup(parameter_count());
630  }
631 
632  void Push(HValue* value) {
633  ASSERT(value != NULL);
634  ++push_count_;
635  values_.Add(value, zone());
636  }
637 
638  HValue* Pop() {
639  ASSERT(!ExpressionStackIsEmpty());
640  if (push_count_ > 0) {
641  --push_count_;
642  } else {
643  ++pop_count_;
644  }
645  return values_.RemoveLast();
646  }
647 
648  void Drop(int count);
649 
650  HValue* Top() const { return ExpressionStackAt(0); }
651 
652  bool ExpressionStackIsEmpty() const;
653 
654  HValue* ExpressionStackAt(int index_from_top) const {
655  int index = length() - index_from_top - 1;
656  ASSERT(HasExpressionAt(index));
657  return values_[index];
658  }
659 
660  void SetExpressionStackAt(int index_from_top, HValue* value);
661 
662  HEnvironment* Copy() const;
663  HEnvironment* CopyWithoutHistory() const;
664  HEnvironment* CopyAsLoopHeader(HBasicBlock* block) const;
665 
666  // Create an "inlined version" of this environment, where the original
667  // environment is the outer environment but the top expression stack
668  // elements are moved to an inner environment as parameters.
669  HEnvironment* CopyForInlining(Handle<JSFunction> target,
670  int arguments,
671  FunctionLiteral* function,
672  HConstant* undefined,
673  InliningKind inlining_kind) const;
674 
675  HEnvironment* DiscardInlined(bool drop_extra) {
676  HEnvironment* outer = outer_;
677  while (outer->frame_type() != JS_FUNCTION) outer = outer->outer_;
678  if (drop_extra) outer->Drop(1);
679  return outer;
680  }
681 
682  void AddIncomingEdge(HBasicBlock* block, HEnvironment* other);
683 
684  void ClearHistory() {
685  pop_count_ = 0;
686  push_count_ = 0;
687  assigned_variables_.Clear();
688  }
689 
690  void SetValueAt(int index, HValue* value) {
691  ASSERT(index < length());
692  values_[index] = value;
693  }
694 
695  // Map a variable to an environment index. Parameter indices are shifted
696  // by 1 (receiver is parameter index -1 but environment index 0).
697  // Stack-allocated local indices are shifted by the number of parameters.
698  int IndexFor(Variable* variable) const {
699  ASSERT(variable->IsStackAllocated());
700  int shift = variable->IsParameter()
701  ? 1
702  : parameter_count_ + specials_count_;
703  return variable->index() + shift;
704  }
705 
706  bool is_local_index(int i) const {
707  return i >= first_local_index() && i < first_expression_index();
708  }
709 
710  bool is_parameter_index(int i) const {
711  return i >= 0 && i < parameter_count();
712  }
713 
714  bool is_special_index(int i) const {
715  return i >= parameter_count() && i < parameter_count() + specials_count();
716  }
717 
718  void PrintTo(StringStream* stream);
719  void PrintToStd();
720 
721  Zone* zone() const { return zone_; }
722 
723  private:
724  HEnvironment(const HEnvironment* other, Zone* zone);
725 
726  HEnvironment(HEnvironment* outer,
727  Handle<JSFunction> closure,
728  FrameType frame_type,
729  int arguments,
730  Zone* zone);
731 
732  // Create an artificial stub environment (e.g. for argument adaptor or
733  // constructor stub).
734  HEnvironment* CreateStubEnvironment(HEnvironment* outer,
735  Handle<JSFunction> target,
736  FrameType frame_type,
737  int arguments) const;
738 
739  // True if index is included in the expression stack part of the environment.
740  bool HasExpressionAt(int index) const;
741 
742  void Initialize(int parameter_count, int local_count, int stack_height);
743  void Initialize(const HEnvironment* other);
744 
745  Handle<JSFunction> closure_;
746  // Value array [parameters] [specials] [locals] [temporaries].
747  ZoneList<HValue*> values_;
748  GrowableBitVector assigned_variables_;
749  FrameType frame_type_;
750  int parameter_count_;
751  int specials_count_;
752  int local_count_;
753  HEnvironment* outer_;
754  HEnterInlined* entry_;
755  int pop_count_;
756  int push_count_;
757  BailoutId ast_id_;
758  Zone* zone_;
759 };
760 
761 
762 class HOptimizedGraphBuilder;
763 
767 };
768 
769 
770 class HIfContinuation;
771 
772 // This class is not BASE_EMBEDDED because our inlining implementation uses
773 // new and delete.
774 class AstContext {
775  public:
776  bool IsEffect() const { return kind_ == Expression::kEffect; }
777  bool IsValue() const { return kind_ == Expression::kValue; }
778  bool IsTest() const { return kind_ == Expression::kTest; }
779 
780  // 'Fill' this context with a hydrogen value. The value is assumed to
781  // have already been inserted in the instruction stream (or not need to
782  // be, e.g., HPhi). Call this function in tail position in the Visit
783  // functions for expressions.
784  virtual void ReturnValue(HValue* value) = 0;
785 
786  // Add a hydrogen instruction to the instruction stream (recording an
787  // environment simulation if necessary) and then fill this context with
788  // the instruction as value.
789  virtual void ReturnInstruction(HInstruction* instr, BailoutId ast_id) = 0;
790 
791  // Finishes the current basic block and materialize a boolean for
792  // value context, nothing for effect, generate a branch for test context.
793  // Call this function in tail position in the Visit functions for
794  // expressions.
795  virtual void ReturnControl(HControlInstruction* instr, BailoutId ast_id) = 0;
796 
797  // Finishes the current basic block and materialize a boolean for
798  // value context, nothing for effect, generate a branch for test context.
799  // Call this function in tail position in the Visit functions for
800  // expressions that use an IfBuilder.
801  virtual void ReturnContinuation(HIfContinuation* continuation,
802  BailoutId ast_id) = 0;
803 
804  void set_for_typeof(bool for_typeof) { for_typeof_ = for_typeof; }
805  bool is_for_typeof() { return for_typeof_; }
806 
807  protected:
809  virtual ~AstContext();
810 
811  HOptimizedGraphBuilder* owner() const { return owner_; }
812 
813  inline Zone* zone() const;
814 
815  // We want to be able to assert, in a context-specific way, that the stack
816  // height makes sense when the context is filled.
817 #ifdef DEBUG
818  int original_length_;
819 #endif
820 
821  private:
822  HOptimizedGraphBuilder* owner_;
823  Expression::Context kind_;
824  AstContext* outer_;
825  bool for_typeof_;
826 };
827 
828 
829 class EffectContext V8_FINAL : public AstContext {
830  public:
832  : AstContext(owner, Expression::kEffect) {
833  }
834  virtual ~EffectContext();
835 
836  virtual void ReturnValue(HValue* value) V8_OVERRIDE;
837  virtual void ReturnInstruction(HInstruction* instr,
838  BailoutId ast_id) V8_OVERRIDE;
839  virtual void ReturnControl(HControlInstruction* instr,
840  BailoutId ast_id) V8_OVERRIDE;
841  virtual void ReturnContinuation(HIfContinuation* continuation,
842  BailoutId ast_id) V8_OVERRIDE;
843 };
844 
845 
846 class ValueContext V8_FINAL : public AstContext {
847  public:
849  : AstContext(owner, Expression::kValue), flag_(flag) {
850  }
851  virtual ~ValueContext();
852 
853  virtual void ReturnValue(HValue* value) V8_OVERRIDE;
854  virtual void ReturnInstruction(HInstruction* instr,
855  BailoutId ast_id) V8_OVERRIDE;
856  virtual void ReturnControl(HControlInstruction* instr,
857  BailoutId ast_id) V8_OVERRIDE;
858  virtual void ReturnContinuation(HIfContinuation* continuation,
859  BailoutId ast_id) V8_OVERRIDE;
860 
861  bool arguments_allowed() { return flag_ == ARGUMENTS_ALLOWED; }
862 
863  private:
864  ArgumentsAllowedFlag flag_;
865 };
866 
867 
868 class TestContext V8_FINAL : public AstContext {
869  public:
871  Expression* condition,
872  HBasicBlock* if_true,
873  HBasicBlock* if_false)
874  : AstContext(owner, Expression::kTest),
875  condition_(condition),
876  if_true_(if_true),
877  if_false_(if_false) {
878  }
879 
880  virtual void ReturnValue(HValue* value) V8_OVERRIDE;
881  virtual void ReturnInstruction(HInstruction* instr,
882  BailoutId ast_id) V8_OVERRIDE;
883  virtual void ReturnControl(HControlInstruction* instr,
884  BailoutId ast_id) V8_OVERRIDE;
885  virtual void ReturnContinuation(HIfContinuation* continuation,
886  BailoutId ast_id) V8_OVERRIDE;
887 
888  static TestContext* cast(AstContext* context) {
889  ASSERT(context->IsTest());
890  return reinterpret_cast<TestContext*>(context);
891  }
892 
893  Expression* condition() const { return condition_; }
894  HBasicBlock* if_true() const { return if_true_; }
895  HBasicBlock* if_false() const { return if_false_; }
896 
897  private:
898  // Build the shared core part of the translation unpacking a value into
899  // control flow.
900  void BuildBranch(HValue* value);
901 
902  Expression* condition_;
903  HBasicBlock* if_true_;
904  HBasicBlock* if_false_;
905 };
906 
907 
908 class FunctionState V8_FINAL {
909  public:
910  FunctionState(HOptimizedGraphBuilder* owner,
911  CompilationInfo* info,
912  InliningKind inlining_kind,
913  int inlining_id);
914  ~FunctionState();
915 
916  CompilationInfo* compilation_info() { return compilation_info_; }
917  AstContext* call_context() { return call_context_; }
918  InliningKind inlining_kind() const { return inlining_kind_; }
919  HBasicBlock* function_return() { return function_return_; }
920  TestContext* test_context() { return test_context_; }
922  delete test_context_;
923  test_context_ = NULL;
924  }
925 
926  FunctionState* outer() { return outer_; }
927 
928  HEnterInlined* entry() { return entry_; }
929  void set_entry(HEnterInlined* entry) { entry_ = entry; }
930 
931  HArgumentsObject* arguments_object() { return arguments_object_; }
932  void set_arguments_object(HArgumentsObject* arguments_object) {
933  arguments_object_ = arguments_object;
934  }
935 
936  HArgumentsElements* arguments_elements() { return arguments_elements_; }
937  void set_arguments_elements(HArgumentsElements* arguments_elements) {
938  arguments_elements_ = arguments_elements;
939  }
940 
941  bool arguments_pushed() { return arguments_elements() != NULL; }
942 
943  int inlining_id() const { return inlining_id_; }
944 
945  private:
946  HOptimizedGraphBuilder* owner_;
947 
948  CompilationInfo* compilation_info_;
949 
950  // During function inlining, expression context of the call being
951  // inlined. NULL when not inlining.
952  AstContext* call_context_;
953 
954  // The kind of call which is currently being inlined.
955  InliningKind inlining_kind_;
956 
957  // When inlining in an effect or value context, this is the return block.
958  // It is NULL otherwise. When inlining in a test context, there are a
959  // pair of return blocks in the context. When not inlining, there is no
960  // local return point.
961  HBasicBlock* function_return_;
962 
963  // When inlining a call in a test context, a context containing a pair of
964  // return blocks. NULL in all other cases.
965  TestContext* test_context_;
966 
967  // When inlining HEnterInlined instruction corresponding to the function
968  // entry.
969  HEnterInlined* entry_;
970 
971  HArgumentsObject* arguments_object_;
972  HArgumentsElements* arguments_elements_;
973 
974  int inlining_id_;
975  HSourcePosition outer_source_position_;
976 
977  FunctionState* outer_;
978 };
979 
980 
981 class HIfContinuation V8_FINAL {
982  public:
984  : continuation_captured_(false),
985  true_branch_(NULL),
986  false_branch_(NULL) {}
987  HIfContinuation(HBasicBlock* true_branch,
988  HBasicBlock* false_branch)
989  : continuation_captured_(true), true_branch_(true_branch),
990  false_branch_(false_branch) {}
991  ~HIfContinuation() { ASSERT(!continuation_captured_); }
992 
993  void Capture(HBasicBlock* true_branch,
994  HBasicBlock* false_branch) {
995  ASSERT(!continuation_captured_);
996  true_branch_ = true_branch;
997  false_branch_ = false_branch;
998  continuation_captured_ = true;
999  }
1000 
1001  void Continue(HBasicBlock** true_branch,
1002  HBasicBlock** false_branch) {
1003  ASSERT(continuation_captured_);
1004  *true_branch = true_branch_;
1005  *false_branch = false_branch_;
1006  continuation_captured_ = false;
1007  }
1008 
1009  bool IsTrueReachable() { return true_branch_ != NULL; }
1010  bool IsFalseReachable() { return false_branch_ != NULL; }
1012  return IsTrueReachable() || IsFalseReachable();
1013  }
1014 
1015  HBasicBlock* true_branch() const { return true_branch_; }
1016  HBasicBlock* false_branch() const { return false_branch_; }
1017 
1018  private:
1019  bool continuation_captured_;
1020  HBasicBlock* true_branch_;
1021  HBasicBlock* false_branch_;
1022 };
1023 
1024 
1025 class HAllocationMode V8_FINAL BASE_EMBEDDED {
1026  public:
1027  explicit HAllocationMode(Handle<AllocationSite> feedback_site)
1028  : current_site_(NULL), feedback_site_(feedback_site),
1029  pretenure_flag_(NOT_TENURED) {}
1030  explicit HAllocationMode(HValue* current_site)
1031  : current_site_(current_site), pretenure_flag_(NOT_TENURED) {}
1032  explicit HAllocationMode(PretenureFlag pretenure_flag)
1033  : current_site_(NULL), pretenure_flag_(pretenure_flag) {}
1035  : current_site_(NULL), pretenure_flag_(NOT_TENURED) {}
1036 
1037  HValue* current_site() const { return current_site_; }
1038  Handle<AllocationSite> feedback_site() const { return feedback_site_; }
1039 
1041  return current_site() != NULL;
1042  }
1043 
1045  if (!feedback_site().is_null()) return feedback_site()->GetPretenureMode();
1046  return pretenure_flag_;
1047  }
1048 
1049  private:
1050  HValue* current_site_;
1051  Handle<AllocationSite> feedback_site_;
1052  PretenureFlag pretenure_flag_;
1053 };
1054 
1055 
1057  public:
1059  : info_(info),
1060  graph_(NULL),
1061  current_block_(NULL),
1062  position_(HSourcePosition::Unknown()),
1063  start_position_(0) {}
1064  virtual ~HGraphBuilder() {}
1065 
1066  HBasicBlock* current_block() const { return current_block_; }
1067  void set_current_block(HBasicBlock* block) { current_block_ = block; }
1068  HEnvironment* environment() const {
1069  return current_block()->last_environment();
1070  }
1071  Zone* zone() const { return info_->zone(); }
1072  HGraph* graph() const { return graph_; }
1073  Isolate* isolate() const { return graph_->isolate(); }
1074  CompilationInfo* top_info() { return info_; }
1075 
1076  HGraph* CreateGraph();
1077 
1078  // Bailout environment manipulation.
1079  void Push(HValue* value) { environment()->Push(value); }
1080  HValue* Pop() { return environment()->Pop(); }
1081 
1082  virtual HValue* context() = 0;
1083 
1084  // Adding instructions.
1087  void FinishExitCurrentBlock(HControlInstruction* instruction);
1088 
1089  void Goto(HBasicBlock* from,
1090  HBasicBlock* target,
1091  FunctionState* state = NULL,
1092  bool add_simulate = true) {
1093  from->Goto(target, source_position(), state, add_simulate);
1094  }
1095  void Goto(HBasicBlock* target,
1096  FunctionState* state = NULL,
1097  bool add_simulate = true) {
1098  Goto(current_block(), target, state, add_simulate);
1099  }
1100  void GotoNoSimulate(HBasicBlock* from, HBasicBlock* target) {
1101  Goto(from, target, NULL, false);
1102  }
1103  void GotoNoSimulate(HBasicBlock* target) {
1104  Goto(target, NULL, false);
1105  }
1106  void AddLeaveInlined(HBasicBlock* block,
1107  HValue* return_value,
1108  FunctionState* state) {
1109  block->AddLeaveInlined(return_value, state, source_position());
1110  }
1111  void AddLeaveInlined(HValue* return_value, FunctionState* state) {
1112  return AddLeaveInlined(current_block(), return_value, state);
1113  }
1114 
1115  template<class I>
1116  HInstruction* NewUncasted() { return I::New(zone(), context()); }
1117 
1118  template<class I>
1119  I* New() { return I::New(zone(), context()); }
1120 
1121  template<class I>
1122  HInstruction* AddUncasted() { return AddInstruction(NewUncasted<I>());}
1123 
1124  template<class I>
1125  I* Add() { return AddInstructionTyped(New<I>());}
1126 
1127  template<class I, class P1>
1129  return I::New(zone(), context(), p1);
1130  }
1131 
1132  template<class I, class P1>
1133  I* New(P1 p1) { return I::New(zone(), context(), p1); }
1134 
1135  template<class I, class P1>
1137  HInstruction* result = AddInstruction(NewUncasted<I>(p1));
1138  // Specializations must have their parameters properly casted
1139  // to avoid landing here.
1140  ASSERT(!result->IsReturn() && !result->IsSimulate() &&
1141  !result->IsDeoptimize());
1142  return result;
1143  }
1144 
1145  template<class I, class P1>
1146  I* Add(P1 p1) {
1147  I* result = AddInstructionTyped(New<I>(p1));
1148  // Specializations must have their parameters properly casted
1149  // to avoid landing here.
1150  ASSERT(!result->IsReturn() && !result->IsSimulate() &&
1151  !result->IsDeoptimize());
1152  return result;
1153  }
1154 
1155  template<class I, class P1, class P2>
1157  return I::New(zone(), context(), p1, p2);
1158  }
1159 
1160  template<class I, class P1, class P2>
1161  I* New(P1 p1, P2 p2) {
1162  return I::New(zone(), context(), p1, p2);
1163  }
1164 
1165  template<class I, class P1, class P2>
1167  HInstruction* result = AddInstruction(NewUncasted<I>(p1, p2));
1168  // Specializations must have their parameters properly casted
1169  // to avoid landing here.
1170  ASSERT(!result->IsSimulate());
1171  return result;
1172  }
1173 
1174  template<class I, class P1, class P2>
1175  I* Add(P1 p1, P2 p2) {
1176  I* result = AddInstructionTyped(New<I>(p1, p2));
1177  // Specializations must have their parameters properly casted
1178  // to avoid landing here.
1179  ASSERT(!result->IsSimulate());
1180  return result;
1181  }
1182 
1183  template<class I, class P1, class P2, class P3>
1185  return I::New(zone(), context(), p1, p2, p3);
1186  }
1187 
1188  template<class I, class P1, class P2, class P3>
1189  I* New(P1 p1, P2 p2, P3 p3) {
1190  return I::New(zone(), context(), p1, p2, p3);
1191  }
1192 
1193  template<class I, class P1, class P2, class P3>
1195  return AddInstruction(NewUncasted<I>(p1, p2, p3));
1196  }
1197 
1198  template<class I, class P1, class P2, class P3>
1199  I* Add(P1 p1, P2 p2, P3 p3) {
1200  return AddInstructionTyped(New<I>(p1, p2, p3));
1201  }
1202 
1203  template<class I, class P1, class P2, class P3, class P4>
1204  HInstruction* NewUncasted(P1 p1, P2 p2, P3 p3, P4 p4) {
1205  return I::New(zone(), context(), p1, p2, p3, p4);
1206  }
1207 
1208  template<class I, class P1, class P2, class P3, class P4>
1209  I* New(P1 p1, P2 p2, P3 p3, P4 p4) {
1210  return I::New(zone(), context(), p1, p2, p3, p4);
1211  }
1212 
1213  template<class I, class P1, class P2, class P3, class P4>
1214  HInstruction* AddUncasted(P1 p1, P2 p2, P3 p3, P4 p4) {
1215  return AddInstruction(NewUncasted<I>(p1, p2, p3, p4));
1216  }
1217 
1218  template<class I, class P1, class P2, class P3, class P4>
1219  I* Add(P1 p1, P2 p2, P3 p3, P4 p4) {
1220  return AddInstructionTyped(New<I>(p1, p2, p3, p4));
1221  }
1222 
1223  template<class I, class P1, class P2, class P3, class P4, class P5>
1224  HInstruction* NewUncasted(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) {
1225  return I::New(zone(), context(), p1, p2, p3, p4, p5);
1226  }
1227 
1228  template<class I, class P1, class P2, class P3, class P4, class P5>
1229  I* New(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) {
1230  return I::New(zone(), context(), p1, p2, p3, p4, p5);
1231  }
1232 
1233  template<class I, class P1, class P2, class P3, class P4, class P5>
1234  HInstruction* AddUncasted(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) {
1235  return AddInstruction(NewUncasted<I>(p1, p2, p3, p4, p5));
1236  }
1237 
1238  template<class I, class P1, class P2, class P3, class P4, class P5>
1239  I* Add(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) {
1240  return AddInstructionTyped(New<I>(p1, p2, p3, p4, p5));
1241  }
1242 
1243  template<class I, class P1, class P2, class P3, class P4, class P5, class P6>
1244  HInstruction* NewUncasted(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6) {
1245  return I::New(zone(), context(), p1, p2, p3, p4, p5, p6);
1246  }
1247 
1248  template<class I, class P1, class P2, class P3, class P4, class P5, class P6>
1249  I* New(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6) {
1250  return I::New(zone(), context(), p1, p2, p3, p4, p5, p6);
1251  }
1252 
1253  template<class I, class P1, class P2, class P3, class P4, class P5, class P6>
1254  HInstruction* AddUncasted(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6) {
1255  return AddInstruction(NewUncasted<I>(p1, p2, p3, p4, p5, p6));
1256  }
1257 
1258  template<class I, class P1, class P2, class P3, class P4, class P5, class P6>
1259  I* Add(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6) {
1260  return AddInstructionTyped(New<I>(p1, p2, p3, p4, p5, p6));
1261  }
1262 
1263  template<class I, class P1, class P2, class P3, class P4,
1264  class P5, class P6, class P7>
1265  HInstruction* NewUncasted(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7) {
1266  return I::New(zone(), context(), p1, p2, p3, p4, p5, p6, p7);
1267  }
1268 
1269  template<class I, class P1, class P2, class P3, class P4,
1270  class P5, class P6, class P7>
1271  I* New(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7) {
1272  return I::New(zone(), context(), p1, p2, p3, p4, p5, p6, p7);
1273  }
1274 
1275  template<class I, class P1, class P2, class P3,
1276  class P4, class P5, class P6, class P7>
1277  HInstruction* AddUncasted(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7) {
1278  return AddInstruction(NewUncasted<I>(p1, p2, p3, p4, p5, p6, p7));
1279  }
1280 
1281  template<class I, class P1, class P2, class P3,
1282  class P4, class P5, class P6, class P7>
1283  I* Add(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7) {
1284  return AddInstructionTyped(New<I>(p1, p2, p3, p4, p5, p6, p7));
1285  }
1286 
1287  template<class I, class P1, class P2, class P3, class P4,
1288  class P5, class P6, class P7, class P8>
1289  HInstruction* NewUncasted(P1 p1, P2 p2, P3 p3, P4 p4,
1290  P5 p5, P6 p6, P7 p7, P8 p8) {
1291  return I::New(zone(), context(), p1, p2, p3, p4, p5, p6, p7, p8);
1292  }
1293 
1294  template<class I, class P1, class P2, class P3, class P4,
1295  class P5, class P6, class P7, class P8>
1296  I* New(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8) {
1297  return I::New(zone(), context(), p1, p2, p3, p4, p5, p6, p7, p8);
1298  }
1299 
1300  template<class I, class P1, class P2, class P3, class P4,
1301  class P5, class P6, class P7, class P8>
1302  HInstruction* AddUncasted(P1 p1, P2 p2, P3 p3, P4 p4,
1303  P5 p5, P6 p6, P7 p7, P8 p8) {
1304  return AddInstruction(NewUncasted<I>(p1, p2, p3, p4, p5, p6, p7, p8));
1305  }
1306 
1307  template<class I, class P1, class P2, class P3, class P4,
1308  class P5, class P6, class P7, class P8>
1309  I* Add(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8) {
1310  return AddInstructionTyped(New<I>(p1, p2, p3, p4, p5, p6, p7, p8));
1311  }
1312 
1313  void AddSimulate(BailoutId id, RemovableSimulate removable = FIXED_SIMULATE);
1314 
1315  protected:
1316  virtual bool BuildGraph() = 0;
1317 
1318  HBasicBlock* CreateBasicBlock(HEnvironment* env);
1319  HBasicBlock* CreateLoopHeaderBlock();
1320 
1323  HValue* BuildCheckString(HValue* string);
1324  HValue* BuildWrapReceiver(HValue* object, HValue* function);
1325 
1326  // Building common constructs
1328  HValue* elements,
1329  ElementsKind kind,
1330  HValue* length,
1331  HValue* key,
1332  bool is_js_array,
1333  PropertyAccessType access_type);
1334 
1336  HValue* elements,
1337  ElementsKind kind,
1338  HValue* length);
1339 
1340  void BuildTransitionElementsKind(HValue* object,
1341  HValue* map,
1342  ElementsKind from_kind,
1343  ElementsKind to_kind,
1344  bool is_jsarray);
1345 
1346  HValue* BuildNumberToString(HValue* object, Type* type);
1347 
1349  HValue* key);
1350 
1352  HValue* index,
1353  HValue* input);
1354 
1355  // Allocates a new object according with the given allocation properties.
1356  HAllocate* BuildAllocate(HValue* object_size,
1357  HType type,
1358  InstanceType instance_type,
1359  HAllocationMode allocation_mode);
1360  // Computes the sum of two string lengths, taking care of overflow handling.
1361  HValue* BuildAddStringLengths(HValue* left_length, HValue* right_length);
1362  // Creates a cons string using the two input strings.
1364  HValue* left,
1365  HValue* right,
1366  HAllocationMode allocation_mode);
1367  // Copies characters from one sequential string to another.
1368  void BuildCopySeqStringChars(HValue* src,
1369  HValue* src_offset,
1370  String::Encoding src_encoding,
1371  HValue* dst,
1372  HValue* dst_offset,
1373  String::Encoding dst_encoding,
1374  HValue* length);
1375 
1376  // Align an object size to object alignment boundary
1377  HValue* BuildObjectSizeAlignment(HValue* unaligned_size, int header_size);
1378 
1379  // Both operands are non-empty strings.
1381  HValue* right,
1382  HAllocationMode allocation_mode);
1383  // Add two strings using allocation mode, validating type feedback.
1384  HValue* BuildStringAdd(HValue* left,
1385  HValue* right,
1386  HAllocationMode allocation_mode);
1387 
1389  HValue* checked_object,
1390  HValue* key,
1391  HValue* val,
1392  bool is_js_array,
1393  ElementsKind elements_kind,
1394  PropertyAccessType access_type,
1395  LoadKeyedHoleMode load_mode,
1396  KeyedAccessStoreMode store_mode);
1397 
1399  HValue* elements,
1400  HValue* checked_key,
1401  HValue* val,
1402  HValue* dependency,
1403  ElementsKind elements_kind,
1404  PropertyAccessType access_type,
1405  LoadKeyedHoleMode load_mode = NEVER_RETURN_HOLE);
1406 
1409  HStoreNamedField* AddStoreMapNoWriteBarrier(HValue* object, HValue* map) {
1410  HStoreNamedField* store_map = Add<HStoreNamedField>(
1411  object, HObjectAccess::ForMap(), map);
1412  store_map->SkipWriteBarrier();
1413  return store_map;
1414  }
1415  HStoreNamedField* AddStoreMapConstant(HValue* object, Handle<Map> map);
1416  HStoreNamedField* AddStoreMapConstantNoWriteBarrier(HValue* object,
1417  Handle<Map> map) {
1418  HStoreNamedField* store_map = AddStoreMapConstant(object, map);
1419  store_map->SkipWriteBarrier();
1420  return store_map;
1421  }
1422  HLoadNamedField* AddLoadElements(HValue* object);
1423 
1424  bool MatchRotateRight(HValue* left,
1425  HValue* right,
1426  HValue** operand,
1427  HValue** shift_amount);
1428 
1430  HValue* left,
1431  HValue* right,
1432  Type* left_type,
1433  Type* right_type,
1434  Type* result_type,
1435  Maybe<int> fixed_right_arg,
1436  HAllocationMode allocation_mode);
1437 
1438  HLoadNamedField* AddLoadFixedArrayLength(HValue *object);
1439 
1441 
1442  HValue* EnforceNumberType(HValue* number, Type* expected);
1443  HValue* TruncateToNumber(HValue* value, Type** expected);
1444 
1445  void FinishExitWithHardDeoptimization(const char* reason);
1446 
1447  void AddIncrementCounter(StatsCounter* counter);
1448 
1449  class IfBuilder V8_FINAL {
1450  public:
1451  explicit IfBuilder(HGraphBuilder* builder);
1452  IfBuilder(HGraphBuilder* builder,
1453  HIfContinuation* continuation);
1454 
1456  if (!finished_) End();
1457  }
1458 
1459  template<class Condition>
1461  Condition* compare = builder()->New<Condition>(p);
1462  AddCompare(compare);
1463  return compare;
1464  }
1465 
1466  template<class Condition, class P2>
1468  Condition* compare = builder()->New<Condition>(p1, p2);
1469  AddCompare(compare);
1470  return compare;
1471  }
1472 
1473  template<class Condition, class P2, class P3>
1474  Condition* If(HValue* p1, P2 p2, P3 p3) {
1475  Condition* compare = builder()->New<Condition>(p1, p2, p3);
1476  AddCompare(compare);
1477  return compare;
1478  }
1479 
1480  template<class Condition>
1482  Condition* compare = If<Condition>(p);
1483  compare->Not();
1484  return compare;
1485  }
1486 
1487  template<class Condition, class P2>
1489  Condition* compare = If<Condition>(p1, p2);
1490  compare->Not();
1491  return compare;
1492  }
1493 
1494  template<class Condition, class P2, class P3>
1495  Condition* IfNot(HValue* p1, P2 p2, P3 p3) {
1496  Condition* compare = If<Condition>(p1, p2, p3);
1497  compare->Not();
1498  return compare;
1499  }
1500 
1501  template<class Condition>
1503  Or();
1504  return If<Condition>(p);
1505  }
1506 
1507  template<class Condition, class P2>
1509  Or();
1510  return If<Condition>(p1, p2);
1511  }
1512 
1513  template<class Condition, class P2, class P3>
1514  Condition* OrIf(HValue* p1, P2 p2, P3 p3) {
1515  Or();
1516  return If<Condition>(p1, p2, p3);
1517  }
1518 
1519  template<class Condition>
1521  And();
1522  return If<Condition>(p);
1523  }
1524 
1525  template<class Condition, class P2>
1527  And();
1528  return If<Condition>(p1, p2);
1529  }
1530 
1531  template<class Condition, class P2, class P3>
1532  Condition* AndIf(HValue* p1, P2 p2, P3 p3) {
1533  And();
1534  return If<Condition>(p1, p2, p3);
1535  }
1536 
1537  void Or();
1538  void And();
1539 
1540  // Captures the current state of this IfBuilder in the specified
1541  // continuation and ends this IfBuilder.
1542  void CaptureContinuation(HIfContinuation* continuation);
1543 
1544  // Joins the specified continuation from this IfBuilder and ends this
1545  // IfBuilder. This appends a Goto instruction from the true branch of
1546  // this IfBuilder to the true branch of the continuation unless the
1547  // true branch of this IfBuilder is already finished. And vice versa
1548  // for the false branch.
1549  //
1550  // The basic idea is as follows: You have several nested IfBuilder's
1551  // that you want to join based on two possible outcomes (i.e. success
1552  // and failure, or whatever). You can do this easily using this method
1553  // now, for example:
1554  //
1555  // HIfContinuation cont(graph()->CreateBasicBlock(),
1556  // graph()->CreateBasicBlock());
1557  // ...
1558  // IfBuilder if_whatever(this);
1559  // if_whatever.If<Condition>(arg);
1560  // if_whatever.Then();
1561  // ...
1562  // if_whatever.Else();
1563  // ...
1564  // if_whatever.JoinContinuation(&cont);
1565  // ...
1566  // IfBuilder if_something(this);
1567  // if_something.If<Condition>(arg1, arg2);
1568  // if_something.Then();
1569  // ...
1570  // if_something.Else();
1571  // ...
1572  // if_something.JoinContinuation(&cont);
1573  // ...
1574  // IfBuilder if_finally(this, &cont);
1575  // if_finally.Then();
1576  // // continues after then code of if_whatever or if_something.
1577  // ...
1578  // if_finally.Else();
1579  // // continues after else code of if_whatever or if_something.
1580  // ...
1581  // if_finally.End();
1582  void JoinContinuation(HIfContinuation* continuation);
1583 
1584  void Then();
1585  void Else();
1586  void End();
1587 
1588  void Deopt(const char* reason);
1589  void ThenDeopt(const char* reason) {
1590  Then();
1591  Deopt(reason);
1592  }
1593  void ElseDeopt(const char* reason) {
1594  Else();
1595  Deopt(reason);
1596  }
1597 
1598  void Return(HValue* value);
1599 
1600  private:
1601  HControlInstruction* AddCompare(HControlInstruction* compare);
1602 
1603  HGraphBuilder* builder() const { return builder_; }
1604 
1605  void AddMergeAtJoinBlock(bool deopt);
1606 
1607  void Finish();
1608  void Finish(HBasicBlock** then_continuation,
1609  HBasicBlock** else_continuation);
1610 
1611  class MergeAtJoinBlock : public ZoneObject {
1612  public:
1613  MergeAtJoinBlock(HBasicBlock* block,
1614  bool deopt,
1615  MergeAtJoinBlock* next)
1616  : block_(block),
1617  deopt_(deopt),
1618  next_(next) {}
1619  HBasicBlock* block_;
1620  bool deopt_;
1621  MergeAtJoinBlock* next_;
1622  };
1623 
1624  HGraphBuilder* builder_;
1625  bool finished_ : 1;
1626  bool did_then_ : 1;
1627  bool did_else_ : 1;
1628  bool did_else_if_ : 1;
1629  bool did_and_ : 1;
1630  bool did_or_ : 1;
1631  bool captured_ : 1;
1632  bool needs_compare_ : 1;
1633  bool pending_merge_block_ : 1;
1634  HBasicBlock* first_true_block_;
1635  HBasicBlock* first_false_block_;
1636  HBasicBlock* split_edge_merge_block_;
1637  MergeAtJoinBlock* merge_at_join_blocks_;
1638  int normal_merge_at_join_block_count_;
1639  int deopt_merge_at_join_block_count_;
1640  };
1641 
1642  class LoopBuilder V8_FINAL {
1643  public:
1644  enum Direction {
1648  kPostDecrement
1649  };
1650 
1651  LoopBuilder(HGraphBuilder* builder,
1652  HValue* context,
1653  Direction direction);
1654  LoopBuilder(HGraphBuilder* builder,
1655  HValue* context,
1656  Direction direction,
1657  HValue* increment_amount);
1658 
1660  ASSERT(finished_);
1661  }
1662 
1663  HValue* BeginBody(
1664  HValue* initial,
1665  HValue* terminating,
1666  Token::Value token);
1667 
1668  void Break();
1669 
1670  void EndBody();
1671 
1672  private:
1673  Zone* zone() { return builder_->zone(); }
1674 
1675  HGraphBuilder* builder_;
1676  HValue* context_;
1677  HValue* increment_amount_;
1678  HInstruction* increment_;
1679  HPhi* phi_;
1680  HBasicBlock* header_block_;
1681  HBasicBlock* body_block_;
1682  HBasicBlock* exit_block_;
1683  HBasicBlock* exit_trampoline_block_;
1684  Direction direction_;
1685  bool finished_;
1686  };
1687 
1688  HValue* BuildNewElementsCapacity(HValue* old_capacity);
1689 
1690  void BuildNewSpaceArrayCheck(HValue* length,
1691  ElementsKind kind);
1692 
1693  class JSArrayBuilder V8_FINAL {
1694  public:
1695  JSArrayBuilder(HGraphBuilder* builder,
1696  ElementsKind kind,
1697  HValue* allocation_site_payload,
1698  HValue* constructor_function,
1699  AllocationSiteOverrideMode override_mode);
1700 
1701  JSArrayBuilder(HGraphBuilder* builder,
1702  ElementsKind kind,
1703  HValue* constructor_function = NULL);
1704 
1705  enum FillMode {
1707  FILL_WITH_HOLE
1708  };
1709 
1710  ElementsKind kind() { return kind_; }
1711 
1712  HValue* AllocateEmptyArray();
1713  HValue* AllocateArray(HValue* capacity, HValue* length_field,
1714  FillMode fill_mode = FILL_WITH_HOLE);
1715  HValue* GetElementsLocation() { return elements_location_; }
1716  HValue* EmitMapCode();
1717 
1718  private:
1719  Zone* zone() const { return builder_->zone(); }
1720  int elements_size() const {
1722  }
1723  HGraphBuilder* builder() { return builder_; }
1724  HGraph* graph() { return builder_->graph(); }
1725  int initial_capacity() {
1728  }
1729 
1730  HValue* EmitInternalMapCode();
1731  HValue* EstablishEmptyArrayAllocationSize();
1732  HValue* EstablishAllocationSize(HValue* length_node);
1733  HValue* AllocateArray(HValue* size_in_bytes, HValue* capacity,
1734  HValue* length_field,
1735  FillMode fill_mode = FILL_WITH_HOLE);
1736 
1737  HGraphBuilder* builder_;
1738  ElementsKind kind_;
1739  AllocationSiteMode mode_;
1740  HValue* allocation_site_payload_;
1741  HValue* constructor_function_;
1742  HInnerAllocatedObject* elements_location_;
1743  };
1744 
1745  HValue* BuildAllocateArrayFromLength(JSArrayBuilder* array_builder,
1746  HValue* length_argument);
1747 
1748  HValue* BuildAllocateElements(ElementsKind kind,
1749  HValue* capacity);
1750 
1751  void BuildInitializeElementsHeader(HValue* elements,
1752  ElementsKind kind,
1753  HValue* capacity);
1754 
1756  HValue* capacity);
1757 
1758  // array must have been allocated with enough room for
1759  // 1) the JSArray, 2) a AllocationMemento if mode requires it,
1760  // 3) a FixedArray or FixedDoubleArray.
1761  // A pointer to the Fixed(Double)Array is returned.
1762  HInnerAllocatedObject* BuildJSArrayHeader(HValue* array,
1763  HValue* array_map,
1765  ElementsKind elements_kind,
1766  HValue* allocation_site_payload,
1767  HValue* length_field);
1768 
1769  HValue* BuildGrowElementsCapacity(HValue* object,
1770  HValue* elements,
1771  ElementsKind kind,
1772  ElementsKind new_kind,
1773  HValue* length,
1774  HValue* new_capacity);
1775 
1776  void BuildFillElementsWithHole(HValue* elements,
1777  ElementsKind elements_kind,
1778  HValue* from,
1779  HValue* to);
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  HValue* BuildCloneShallowArray(HValue* boilerplate,
1789  HValue* allocation_site,
1791  ElementsKind kind,
1792  int length);
1793 
1794  HValue* BuildElementIndexHash(HValue* index);
1795 
1796  void BuildCompareNil(
1797  HValue* value,
1798  Type* type,
1799  HIfContinuation* continuation);
1800 
1801  void BuildCreateAllocationMemento(HValue* previous_object,
1802  HValue* previous_object_size,
1803  HValue* payload);
1804 
1805  HInstruction* BuildConstantMapCheck(Handle<JSObject> constant,
1806  CompilationInfo* info);
1807  HInstruction* BuildCheckPrototypeMaps(Handle<JSObject> prototype,
1808  Handle<JSObject> holder);
1809 
1810  HInstruction* BuildGetNativeContext(HValue* closure);
1811  HInstruction* BuildGetNativeContext();
1812  HInstruction* BuildGetArrayFunction();
1813 
1814  protected:
1815  void SetSourcePosition(int position) {
1816  ASSERT(position != RelocInfo::kNoPosition);
1817  position_.set_position(position - start_position_);
1818  }
1819 
1820  void EnterInlinedSource(int start_position, int id) {
1821  if (FLAG_hydrogen_track_positions) {
1822  start_position_ = start_position;
1823  position_.set_inlining_id(id);
1824  }
1825  }
1826 
1827  // Convert the given absolute offset from the start of the script to
1828  // the HSourcePosition assuming that this position corresponds to the
1829  // same function as current position_.
1831  HSourcePosition pos = position_;
1832  pos.set_position(position - start_position_);
1833  return pos;
1834  }
1835 
1836  HSourcePosition source_position() { return position_; }
1838  position_ = position;
1839  }
1840 
1841  template <typename ViewClass>
1843  HValue* buffer,
1844  HValue* byte_offset,
1845  HValue* byte_length);
1846 
1847  private:
1848  HGraphBuilder();
1849 
1850  HValue* BuildUncheckedDictionaryElementLoadHelper(
1851  HValue* elements,
1852  HValue* key,
1853  HValue* hash,
1854  HValue* mask,
1855  int current_probe);
1856 
1857  template <class I>
1858  I* AddInstructionTyped(I* instr) {
1859  return I::cast(AddInstruction(instr));
1860  }
1861 
1862  CompilationInfo* info_;
1863  HGraph* graph_;
1864  HBasicBlock* current_block_;
1865  HSourcePosition position_;
1866  int start_position_;
1867 };
1868 
1869 
1870 template<>
1871 inline HDeoptimize* HGraphBuilder::Add<HDeoptimize>(
1872  const char* reason, Deoptimizer::BailoutType type) {
1873  if (type == Deoptimizer::SOFT) {
1874  isolate()->counters()->soft_deopts_requested()->Increment();
1875  if (FLAG_always_opt) return NULL;
1876  }
1877  if (current_block()->IsDeoptimizing()) return NULL;
1878  HBasicBlock* after_deopt_block = CreateBasicBlock(
1879  current_block()->last_environment());
1880  HDeoptimize* instr = New<HDeoptimize>(reason, type, after_deopt_block);
1881  if (type == Deoptimizer::SOFT) {
1882  isolate()->counters()->soft_deopts_inserted()->Increment();
1883  }
1884  FinishCurrentBlock(instr);
1885  set_current_block(after_deopt_block);
1886  return instr;
1887 }
1888 
1889 
1890 template<>
1891 inline HInstruction* HGraphBuilder::AddUncasted<HDeoptimize>(
1892  const char* reason, Deoptimizer::BailoutType type) {
1893  return Add<HDeoptimize>(reason, type);
1894 }
1895 
1896 
1897 template<>
1898 inline HSimulate* HGraphBuilder::Add<HSimulate>(
1899  BailoutId id,
1900  RemovableSimulate removable) {
1901  HSimulate* instr = current_block()->CreateSimulate(id, removable);
1902  AddInstruction(instr);
1903  return instr;
1904 }
1905 
1906 
1907 template<>
1908 inline HSimulate* HGraphBuilder::Add<HSimulate>(
1909  BailoutId id) {
1910  return Add<HSimulate>(id, FIXED_SIMULATE);
1911 }
1912 
1913 
1914 template<>
1915 inline HInstruction* HGraphBuilder::AddUncasted<HSimulate>(BailoutId id) {
1916  return Add<HSimulate>(id, FIXED_SIMULATE);
1917 }
1918 
1919 
1920 template<>
1921 inline HReturn* HGraphBuilder::Add<HReturn>(HValue* value) {
1922  int num_parameters = graph()->info()->num_parameters();
1923  HValue* params = AddUncasted<HConstant>(num_parameters);
1924  HReturn* return_instruction = New<HReturn>(value, params);
1925  FinishExitCurrentBlock(return_instruction);
1926  return return_instruction;
1927 }
1928 
1929 
1930 template<>
1931 inline HReturn* HGraphBuilder::Add<HReturn>(HConstant* value) {
1932  return Add<HReturn>(static_cast<HValue*>(value));
1933 }
1934 
1935 template<>
1936 inline HInstruction* HGraphBuilder::AddUncasted<HReturn>(HValue* value) {
1937  return Add<HReturn>(value);
1938 }
1939 
1940 
1941 template<>
1942 inline HInstruction* HGraphBuilder::AddUncasted<HReturn>(HConstant* value) {
1943  return Add<HReturn>(value);
1944 }
1945 
1946 
1947 template<>
1948 inline HCallRuntime* HGraphBuilder::Add<HCallRuntime>(
1950  const Runtime::Function* c_function,
1951  int argument_count) {
1952  HCallRuntime* instr = New<HCallRuntime>(name, c_function, argument_count);
1953  if (graph()->info()->IsStub()) {
1954  // When compiling code stubs, we don't want to save all double registers
1955  // upon entry to the stub, but instead have the call runtime instruction
1956  // save the double registers only on-demand (in the fallback case).
1957  instr->set_save_doubles(kSaveFPRegs);
1958  }
1959  AddInstruction(instr);
1960  return instr;
1961 }
1962 
1963 
1964 template<>
1965 inline HInstruction* HGraphBuilder::AddUncasted<HCallRuntime>(
1967  const Runtime::Function* c_function,
1968  int argument_count) {
1969  return Add<HCallRuntime>(name, c_function, argument_count);
1970 }
1971 
1972 
1973 template<>
1974 inline HContext* HGraphBuilder::New<HContext>() {
1975  return HContext::New(zone());
1976 }
1977 
1978 
1979 template<>
1980 inline HInstruction* HGraphBuilder::NewUncasted<HContext>() {
1981  return New<HContext>();
1982 }
1983 
1984 class HOptimizedGraphBuilder : public HGraphBuilder, public AstVisitor {
1985  public:
1986  // A class encapsulating (lazily-allocated) break and continue blocks for
1987  // a breakable statement. Separated from BreakAndContinueScope so that it
1988  // can have a separate lifetime.
1989  class BreakAndContinueInfo V8_FINAL BASE_EMBEDDED {
1990  public:
1992  int drop_extra = 0)
1993  : target_(target),
1994  break_block_(NULL),
1995  continue_block_(NULL),
1996  drop_extra_(drop_extra) {
1997  }
1998 
1999  BreakableStatement* target() { return target_; }
2000  HBasicBlock* break_block() { return break_block_; }
2001  void set_break_block(HBasicBlock* block) { break_block_ = block; }
2002  HBasicBlock* continue_block() { return continue_block_; }
2003  void set_continue_block(HBasicBlock* block) { continue_block_ = block; }
2004  int drop_extra() { return drop_extra_; }
2005 
2006  private:
2007  BreakableStatement* target_;
2008  HBasicBlock* break_block_;
2009  HBasicBlock* continue_block_;
2010  int drop_extra_;
2011  };
2012 
2013  // A helper class to maintain a stack of current BreakAndContinueInfo
2014  // structures mirroring BreakableStatement nesting.
2015  class BreakAndContinueScope V8_FINAL BASE_EMBEDDED {
2016  public:
2017  BreakAndContinueScope(BreakAndContinueInfo* info,
2018  HOptimizedGraphBuilder* owner)
2019  : info_(info), owner_(owner), next_(owner->break_scope()) {
2020  owner->set_break_scope(this);
2021  }
2022 
2023  ~BreakAndContinueScope() { owner_->set_break_scope(next_); }
2024 
2025  BreakAndContinueInfo* info() { return info_; }
2026  HOptimizedGraphBuilder* owner() { return owner_; }
2027  BreakAndContinueScope* next() { return next_; }
2028 
2029  // Search the break stack for a break or continue target.
2030  enum BreakType { BREAK, CONTINUE };
2031  HBasicBlock* Get(BreakableStatement* stmt, BreakType type, int* drop_extra);
2032 
2033  private:
2034  BreakAndContinueInfo* info_;
2035  HOptimizedGraphBuilder* owner_;
2036  BreakAndContinueScope* next_;
2037  };
2038 
2040 
2041  virtual bool BuildGraph() V8_OVERRIDE;
2042 
2043  // Simple accessors.
2044  BreakAndContinueScope* break_scope() const { return break_scope_; }
2045  void set_break_scope(BreakAndContinueScope* head) { break_scope_ = head; }
2046 
2047  bool inline_bailout() { return inline_bailout_; }
2048 
2049  HValue* context() { return environment()->context(); }
2050 
2051  HOsrBuilder* osr() const { return osr_; }
2052 
2053  void Bailout(BailoutReason reason);
2054 
2055  HBasicBlock* CreateJoin(HBasicBlock* first,
2056  HBasicBlock* second,
2057  BailoutId join_id);
2058 
2059  FunctionState* function_state() const { return function_state_; }
2060 
2061  void VisitDeclarations(ZoneList<Declaration*>* declarations);
2062 
2063  void* operator new(size_t size, Zone* zone) {
2064  return zone->New(static_cast<int>(size));
2065  }
2066  void operator delete(void* pointer, Zone* zone) { }
2067  void operator delete(void* pointer) { }
2068 
2070 
2071  protected:
2072  // Type of a member function that generates inline code for a native function.
2074  (CallRuntime* call);
2075 
2076  // Forward declarations for inner scope classes.
2077  class SubgraphScope;
2078 
2080 
2081  static const int kMaxCallPolymorphism = 4;
2082  static const int kMaxLoadPolymorphism = 4;
2083  static const int kMaxStorePolymorphism = 4;
2084 
2085  // Even in the 'unlimited' case we have to have some limit in order not to
2086  // overflow the stack.
2087  static const int kUnlimitedMaxInlinedSourceSize = 100000;
2088  static const int kUnlimitedMaxInlinedNodes = 10000;
2089  static const int kUnlimitedMaxInlinedNodesCumulative = 10000;
2090 
2091  // Maximum depth and total number of elements and properties for literal
2092  // graphs to be considered for fast deep-copying.
2093  static const int kMaxFastLiteralDepth = 3;
2094  static const int kMaxFastLiteralProperties = 8;
2095 
2096  // Simple accessors.
2097  void set_function_state(FunctionState* state) { function_state_ = state; }
2098 
2099  AstContext* ast_context() const { return ast_context_; }
2100  void set_ast_context(AstContext* context) { ast_context_ = context; }
2101 
2102  // Accessors forwarded to the function state.
2104  return function_state()->compilation_info();
2105  }
2107  return function_state()->call_context();
2108  }
2109  HBasicBlock* function_return() const {
2110  return function_state()->function_return();
2111  }
2112  TestContext* inlined_test_context() const {
2113  return function_state()->test_context();
2114  }
2116  function_state()->ClearInlinedTestContext();
2117  }
2119  return function_state()->compilation_info()->strict_mode();
2120  }
2121 
2122  // Generators for inline runtime functions.
2123 #define INLINE_FUNCTION_GENERATOR_DECLARATION(Name, argc, ressize) \
2124  void Generate##Name(CallRuntime* call);
2125 
2128 #undef INLINE_FUNCTION_GENERATOR_DECLARATION
2129 
2130  void VisitDelete(UnaryOperation* expr);
2131  void VisitVoid(UnaryOperation* expr);
2132  void VisitTypeof(UnaryOperation* expr);
2133  void VisitNot(UnaryOperation* expr);
2134 
2135  void VisitComma(BinaryOperation* expr);
2136  void VisitLogicalExpression(BinaryOperation* expr);
2137  void VisitArithmeticExpression(BinaryOperation* expr);
2138 
2139  bool PreProcessOsrEntry(IterationStatement* statement);
2140  void VisitLoopBody(IterationStatement* stmt,
2141  HBasicBlock* loop_entry,
2142  BreakAndContinueInfo* break_info);
2143 
2144  // Create a back edge in the flow graph. body_exit is the predecessor
2145  // block and loop_entry is the successor block. loop_successor is the
2146  // block where control flow exits the loop normally (e.g., via failure of
2147  // the condition) and break_block is the block where control flow breaks
2148  // from the loop. All blocks except loop_entry can be NULL. The return
2149  // value is the new successor block which is the join of loop_successor
2150  // and break_block, or NULL.
2151  HBasicBlock* CreateLoop(IterationStatement* statement,
2152  HBasicBlock* loop_entry,
2153  HBasicBlock* body_exit,
2154  HBasicBlock* loop_successor,
2155  HBasicBlock* break_block);
2156 
2157  // Build a loop entry
2158  HBasicBlock* BuildLoopEntry();
2159 
2160  // Builds a loop entry respectful of OSR requirements
2161  HBasicBlock* BuildLoopEntry(IterationStatement* statement);
2162 
2163  HBasicBlock* JoinContinue(IterationStatement* statement,
2164  HBasicBlock* exit_block,
2165  HBasicBlock* continue_block);
2166 
2167  HValue* Top() const { return environment()->Top(); }
2168  void Drop(int n) { environment()->Drop(n); }
2169  void Bind(Variable* var, HValue* value) { environment()->Bind(var, value); }
2171  int index,
2172  HValue* value,
2173  HEnvironment* env) {
2174  if (!FLAG_analyze_environment_liveness) return false;
2175  // |this| and |arguments| are always live; zapping parameters isn't
2176  // safe because function.arguments can inspect them at any time.
2177  return !var->is_this() &&
2178  !var->is_arguments() &&
2179  !value->IsArgumentsObject() &&
2180  env->is_local_index(index);
2181  }
2182  void BindIfLive(Variable* var, HValue* value) {
2183  HEnvironment* env = environment();
2184  int index = env->IndexFor(var);
2185  env->Bind(index, value);
2186  if (IsEligibleForEnvironmentLivenessAnalysis(var, index, value, env)) {
2187  HEnvironmentMarker* bind =
2188  Add<HEnvironmentMarker>(HEnvironmentMarker::BIND, index);
2189  USE(bind);
2190 #ifdef DEBUG
2191  bind->set_closure(env->closure());
2192 #endif
2193  }
2194  }
2195 
2197  HEnvironment* env = environment();
2198  int index = env->IndexFor(var);
2199  HValue* value = env->Lookup(index);
2200  if (IsEligibleForEnvironmentLivenessAnalysis(var, index, value, env)) {
2201  HEnvironmentMarker* lookup =
2202  Add<HEnvironmentMarker>(HEnvironmentMarker::LOOKUP, index);
2203  USE(lookup);
2204 #ifdef DEBUG
2205  lookup->set_closure(env->closure());
2206 #endif
2207  }
2208  return value;
2209  }
2210 
2211  // The value of the arguments object is allowed in some but not most value
2212  // contexts. (It's allowed in all effect contexts and disallowed in all
2213  // test contexts.)
2214  void VisitForValue(Expression* expr,
2216  void VisitForTypeOf(Expression* expr);
2217  void VisitForEffect(Expression* expr);
2218  void VisitForControl(Expression* expr,
2219  HBasicBlock* true_block,
2220  HBasicBlock* false_block);
2221 
2222  // Visit a list of expressions from left to right, each in a value context.
2224 
2225  // Remove the arguments from the bailout environment and emit instructions
2226  // to push them as outgoing parameters.
2227  template <class Instruction> HInstruction* PreProcessCall(Instruction* call);
2228  void PushArgumentsFromEnvironment(int count);
2229 
2230  void SetUpScope(Scope* scope);
2231  virtual void VisitStatements(ZoneList<Statement*>* statements) V8_OVERRIDE;
2232 
2233 #define DECLARE_VISIT(type) virtual void Visit##type(type* node) V8_OVERRIDE;
2235 #undef DECLARE_VISIT
2236 
2237  Type* ToType(Handle<Map> map) { return IC::MapToType<Type>(map, zone()); }
2238 
2239  private:
2240  // Helpers for flow graph construction.
2241  enum GlobalPropertyAccess {
2242  kUseCell,
2243  kUseGeneric
2244  };
2245  GlobalPropertyAccess LookupGlobalProperty(Variable* var,
2246  LookupResult* lookup,
2247  PropertyAccessType access_type);
2248 
2249  void EnsureArgumentsArePushedForAccess();
2250  bool TryArgumentsAccess(Property* expr);
2251 
2252  // Try to optimize fun.apply(receiver, arguments) pattern.
2253  bool TryCallApply(Call* expr);
2254 
2255  HValue* ImplicitReceiverFor(HValue* function,
2256  Handle<JSFunction> target);
2257 
2258  int InliningAstSize(Handle<JSFunction> target);
2259  bool TryInline(Handle<JSFunction> target,
2260  int arguments_count,
2261  HValue* implicit_return_value,
2262  BailoutId ast_id,
2263  BailoutId return_id,
2264  InliningKind inlining_kind,
2265  HSourcePosition position);
2266 
2267  bool TryInlineCall(Call* expr);
2268  bool TryInlineConstruct(CallNew* expr, HValue* implicit_return_value);
2269  bool TryInlineGetter(Handle<JSFunction> getter,
2270  Handle<Map> receiver_map,
2271  BailoutId ast_id,
2272  BailoutId return_id);
2273  bool TryInlineSetter(Handle<JSFunction> setter,
2274  Handle<Map> receiver_map,
2275  BailoutId id,
2276  BailoutId assignment_id,
2277  HValue* implicit_return_value);
2278  bool TryInlineApply(Handle<JSFunction> function,
2279  Call* expr,
2280  int arguments_count);
2281  bool TryInlineBuiltinMethodCall(Call* expr,
2282  HValue* receiver,
2283  Handle<Map> receiver_map);
2284  bool TryInlineBuiltinFunctionCall(Call* expr);
2285  enum ApiCallType {
2286  kCallApiFunction,
2287  kCallApiMethod,
2288  kCallApiGetter,
2289  kCallApiSetter
2290  };
2291  bool TryInlineApiMethodCall(Call* expr,
2292  HValue* receiver,
2293  SmallMapList* receiver_types);
2294  bool TryInlineApiFunctionCall(Call* expr, HValue* receiver);
2295  bool TryInlineApiGetter(Handle<JSFunction> function,
2296  Handle<Map> receiver_map,
2297  BailoutId ast_id);
2298  bool TryInlineApiSetter(Handle<JSFunction> function,
2299  Handle<Map> receiver_map,
2300  BailoutId ast_id);
2301  bool TryInlineApiCall(Handle<JSFunction> function,
2302  HValue* receiver,
2303  SmallMapList* receiver_maps,
2304  int argc,
2305  BailoutId ast_id,
2306  ApiCallType call_type);
2307 
2308  // If --trace-inlining, print a line of the inlining trace. Inlining
2309  // succeeded if the reason string is NULL and failed if there is a
2310  // non-NULL reason string.
2311  void TraceInline(Handle<JSFunction> target,
2312  Handle<JSFunction> caller,
2313  const char* failure_reason);
2314 
2315  void HandleGlobalVariableAssignment(Variable* var,
2316  HValue* value,
2317  BailoutId ast_id);
2318 
2319  void HandlePropertyAssignment(Assignment* expr);
2320  void HandleCompoundAssignment(Assignment* expr);
2321  void HandlePolymorphicNamedFieldAccess(PropertyAccessType access_type,
2322  BailoutId ast_id,
2323  BailoutId return_id,
2324  HValue* object,
2325  HValue* value,
2326  SmallMapList* types,
2327  Handle<String> name);
2328 
2329  HValue* BuildAllocateExternalElements(
2330  ExternalArrayType array_type,
2331  bool is_zero_byte_offset,
2332  HValue* buffer, HValue* byte_offset, HValue* length);
2333  HValue* BuildAllocateFixedTypedArray(
2334  ExternalArrayType array_type, size_t element_size,
2335  ElementsKind fixed_elements_kind,
2336  HValue* byte_length, HValue* length);
2337 
2338  bool IsCallNewArrayInlineable(CallNew* expr);
2339  void BuildInlinedCallNewArray(CallNew* expr);
2340 
2341  class PropertyAccessInfo {
2342  public:
2343  PropertyAccessInfo(HOptimizedGraphBuilder* builder,
2344  PropertyAccessType access_type,
2345  Type* type,
2346  Handle<String> name)
2347  : lookup_(builder->isolate()),
2348  builder_(builder),
2349  access_type_(access_type),
2350  type_(type),
2351  name_(name),
2352  access_(HObjectAccess::ForMap()) { }
2353 
2354  // Checkes whether this PropertyAccessInfo can be handled as a monomorphic
2355  // load named. It additionally fills in the fields necessary to generate the
2356  // lookup code.
2357  bool CanAccessMonomorphic();
2358 
2359  // Checks whether all types behave uniform when loading name. If all maps
2360  // behave the same, a single monomorphic load instruction can be emitted,
2361  // guarded by a single map-checks instruction that whether the receiver is
2362  // an instance of any of the types.
2363  // This method skips the first type in types, assuming that this
2364  // PropertyAccessInfo is built for types->first().
2365  bool CanAccessAsMonomorphic(SmallMapList* types);
2366 
2367  Handle<Map> map() {
2368  if (type_->Is(Type::Number())) {
2369  Context* context = current_info()->closure()->context();
2370  context = context->native_context();
2371  return handle(context->number_function()->initial_map());
2372  } else if (type_->Is(Type::Boolean())) {
2373  Context* context = current_info()->closure()->context();
2374  context = context->native_context();
2375  return handle(context->boolean_function()->initial_map());
2376  } else if (type_->Is(Type::String())) {
2377  Context* context = current_info()->closure()->context();
2378  context = context->native_context();
2379  return handle(context->string_function()->initial_map());
2380  } else {
2381  return type_->AsClass();
2382  }
2383  }
2384  Type* type() const { return type_; }
2385  Handle<String> name() const { return name_; }
2386 
2387  bool IsJSObjectFieldAccessor() {
2388  int offset; // unused
2389  return Accessors::IsJSObjectFieldAccessor<Type>(type_, name_, &offset);
2390  }
2391 
2392  bool GetJSObjectFieldAccess(HObjectAccess* access) {
2393  int offset;
2394  if (Accessors::IsJSObjectFieldAccessor<Type>(type_, name_, &offset)) {
2395  if (type_->Is(Type::String())) {
2396  ASSERT(name_->Equals(isolate()->heap()->length_string()));
2397  *access = HObjectAccess::ForStringLength();
2398  } else if (type_->Is(Type::Array())) {
2399  ASSERT(name_->Equals(isolate()->heap()->length_string()));
2400  *access = HObjectAccess::ForArrayLength(map()->elements_kind());
2401  } else {
2402  *access = HObjectAccess::ForMapAndOffset(map(), offset);
2403  }
2404  return true;
2405  }
2406  return false;
2407  }
2408 
2409  bool has_holder() { return !holder_.is_null(); }
2410  bool IsLoad() const { return access_type_ == LOAD; }
2411 
2412  LookupResult* lookup() { return &lookup_; }
2413  Handle<JSObject> holder() { return holder_; }
2414  Handle<JSFunction> accessor() { return accessor_; }
2415  Handle<Object> constant() { return constant_; }
2416  Handle<Map> transition() { return handle(lookup_.GetTransitionTarget()); }
2417  HObjectAccess access() { return access_; }
2418 
2419  private:
2420  Type* ToType(Handle<Map> map) { return builder_->ToType(map); }
2421  Isolate* isolate() { return lookup_.isolate(); }
2422  CompilationInfo* current_info() { return builder_->current_info(); }
2423 
2424  bool LoadResult(Handle<Map> map);
2425  bool LookupDescriptor();
2426  bool LookupInPrototypes();
2427  bool IsCompatible(PropertyAccessInfo* other);
2428 
2429  void GeneralizeRepresentation(Representation r) {
2430  access_ = access_.WithRepresentation(
2431  access_.representation().generalize(r));
2432  }
2433 
2434  LookupResult lookup_;
2435  HOptimizedGraphBuilder* builder_;
2436  PropertyAccessType access_type_;
2437  Type* type_;
2438  Handle<String> name_;
2439  Handle<JSObject> holder_;
2440  Handle<JSFunction> accessor_;
2441  Handle<JSObject> api_holder_;
2442  Handle<Object> constant_;
2443  HObjectAccess access_;
2444  };
2445 
2446  HInstruction* BuildMonomorphicAccess(PropertyAccessInfo* info,
2447  HValue* object,
2448  HValue* checked_object,
2449  HValue* value,
2450  BailoutId ast_id,
2451  BailoutId return_id,
2452  bool can_inline_accessor = true);
2453 
2454  HInstruction* BuildNamedAccess(PropertyAccessType access,
2455  BailoutId ast_id,
2456  BailoutId reutrn_id,
2457  Expression* expr,
2458  HValue* object,
2459  Handle<String> name,
2460  HValue* value,
2461  bool is_uninitialized = false);
2462 
2463  void HandlePolymorphicCallNamed(Call* expr,
2464  HValue* receiver,
2465  SmallMapList* types,
2466  Handle<String> name);
2467  void HandleLiteralCompareTypeof(CompareOperation* expr,
2468  Expression* sub_expr,
2469  Handle<String> check);
2470  void HandleLiteralCompareNil(CompareOperation* expr,
2471  Expression* sub_expr,
2472  NilValue nil);
2473 
2474  enum PushBeforeSimulateBehavior {
2475  PUSH_BEFORE_SIMULATE,
2476  NO_PUSH_BEFORE_SIMULATE
2477  };
2478 
2479  HControlInstruction* BuildCompareInstruction(
2480  Token::Value op,
2481  HValue* left,
2482  HValue* right,
2483  Type* left_type,
2484  Type* right_type,
2485  Type* combined_type,
2486  HSourcePosition left_position,
2487  HSourcePosition right_position,
2488  PushBeforeSimulateBehavior push_sim_result,
2489  BailoutId bailout_id);
2490 
2491  HInstruction* BuildStringCharCodeAt(HValue* string,
2492  HValue* index);
2493 
2494  HValue* BuildBinaryOperation(
2495  BinaryOperation* expr,
2496  HValue* left,
2497  HValue* right,
2498  PushBeforeSimulateBehavior push_sim_result);
2499  HInstruction* BuildIncrement(bool returns_original_input,
2500  CountOperation* expr);
2501  HInstruction* BuildKeyedGeneric(PropertyAccessType access_type,
2502  HValue* object,
2503  HValue* key,
2504  HValue* value);
2505 
2506  HInstruction* TryBuildConsolidatedElementLoad(HValue* object,
2507  HValue* key,
2508  HValue* val,
2509  SmallMapList* maps);
2510 
2511  LoadKeyedHoleMode BuildKeyedHoleMode(Handle<Map> map);
2512 
2513  HInstruction* BuildMonomorphicElementAccess(HValue* object,
2514  HValue* key,
2515  HValue* val,
2516  HValue* dependency,
2517  Handle<Map> map,
2518  PropertyAccessType access_type,
2519  KeyedAccessStoreMode store_mode);
2520 
2521  HValue* HandlePolymorphicElementAccess(HValue* object,
2522  HValue* key,
2523  HValue* val,
2524  SmallMapList* maps,
2525  PropertyAccessType access_type,
2526  KeyedAccessStoreMode store_mode,
2527  bool* has_side_effects);
2528 
2529  HValue* HandleKeyedElementAccess(HValue* obj,
2530  HValue* key,
2531  HValue* val,
2532  Expression* expr,
2533  PropertyAccessType access_type,
2534  bool* has_side_effects);
2535 
2536  HInstruction* BuildNamedGeneric(PropertyAccessType access,
2537  HValue* object,
2538  Handle<String> name,
2539  HValue* value,
2540  bool is_uninitialized = false);
2541 
2542  HCheckMaps* AddCheckMap(HValue* object, Handle<Map> map);
2543 
2544  void BuildLoad(Property* property,
2545  BailoutId ast_id);
2546  void PushLoad(Property* property,
2547  HValue* object,
2548  HValue* key);
2549 
2550  void BuildStoreForEffect(Expression* expression,
2551  Property* prop,
2552  BailoutId ast_id,
2553  BailoutId return_id,
2554  HValue* object,
2555  HValue* key,
2556  HValue* value);
2557 
2558  void BuildStore(Expression* expression,
2559  Property* prop,
2560  BailoutId ast_id,
2561  BailoutId return_id,
2562  bool is_uninitialized = false);
2563 
2564  HInstruction* BuildLoadNamedField(PropertyAccessInfo* info,
2565  HValue* checked_object);
2566  HInstruction* BuildStoreNamedField(PropertyAccessInfo* info,
2567  HValue* checked_object,
2568  HValue* value);
2569 
2570  HValue* BuildContextChainWalk(Variable* var);
2571 
2572  HInstruction* BuildThisFunction();
2573 
2574  HInstruction* BuildFastLiteral(Handle<JSObject> boilerplate_object,
2575  AllocationSiteUsageContext* site_context);
2576 
2577  void BuildEmitObjectHeader(Handle<JSObject> boilerplate_object,
2578  HInstruction* object);
2579 
2580  void BuildInitElementsInObjectHeader(Handle<JSObject> boilerplate_object,
2581  HInstruction* object,
2582  HInstruction* object_elements);
2583 
2584  void BuildEmitInObjectProperties(Handle<JSObject> boilerplate_object,
2585  HInstruction* object,
2586  AllocationSiteUsageContext* site_context,
2587  PretenureFlag pretenure_flag);
2588 
2589  void BuildEmitElements(Handle<JSObject> boilerplate_object,
2590  Handle<FixedArrayBase> elements,
2591  HValue* object_elements,
2592  AllocationSiteUsageContext* site_context);
2593 
2594  void BuildEmitFixedDoubleArray(Handle<FixedArrayBase> elements,
2595  ElementsKind kind,
2596  HValue* object_elements);
2597 
2598  void BuildEmitFixedArray(Handle<FixedArrayBase> elements,
2599  ElementsKind kind,
2600  HValue* object_elements,
2601  AllocationSiteUsageContext* site_context);
2602 
2603  void AddCheckPrototypeMaps(Handle<JSObject> holder,
2604  Handle<Map> receiver_map);
2605 
2606  HInstruction* NewPlainFunctionCall(HValue* fun,
2607  int argument_count,
2608  bool pass_argument_count);
2609 
2610  HInstruction* NewArgumentAdaptorCall(HValue* fun, HValue* context,
2611  int argument_count,
2612  HValue* expected_param_count);
2613 
2614  HInstruction* BuildCallConstantFunction(Handle<JSFunction> target,
2615  int argument_count);
2616 
2617  // The translation state of the currently-being-translated function.
2618  FunctionState* function_state_;
2619 
2620  // The base of the function state stack.
2621  FunctionState initial_function_state_;
2622 
2623  // Expression context of the currently visited subexpression. NULL when
2624  // visiting statements.
2625  AstContext* ast_context_;
2626 
2627  // A stack of breakable statements entered.
2628  BreakAndContinueScope* break_scope_;
2629 
2630  int inlined_count_;
2631  ZoneList<Handle<Object> > globals_;
2632 
2633  bool inline_bailout_;
2634 
2635  HOsrBuilder* osr_;
2636 
2637  friend class FunctionState; // Pushes and pops the state stack.
2638  friend class AstContext; // Pushes and pops the AST context stack.
2640  friend class HOsrBuilder;
2641 
2643 };
2644 
2645 
2646 Zone* AstContext::zone() const { return owner_->zone(); }
2647 
2648 
2649 class HStatistics V8_FINAL: public Malloced {
2650  public:
2652  : times_(5),
2653  names_(5),
2654  sizes_(5),
2655  total_size_(0),
2656  source_size_(0) { }
2657 
2658  void Initialize(CompilationInfo* info);
2659  void Print();
2660  void SaveTiming(const char* name, TimeDelta time, unsigned size);
2661 
2662  void IncrementFullCodeGen(TimeDelta full_code_gen) {
2663  full_code_gen_ += full_code_gen;
2664  }
2665 
2666  void IncrementSubtotals(TimeDelta create_graph,
2667  TimeDelta optimize_graph,
2668  TimeDelta generate_code) {
2669  create_graph_ += create_graph;
2670  optimize_graph_ += optimize_graph;
2671  generate_code_ += generate_code;
2672  }
2673 
2674  private:
2675  List<TimeDelta> times_;
2676  List<const char*> names_;
2677  List<unsigned> sizes_;
2678  TimeDelta create_graph_;
2679  TimeDelta optimize_graph_;
2680  TimeDelta generate_code_;
2681  unsigned total_size_;
2682  TimeDelta full_code_gen_;
2683  double source_size_;
2684 };
2685 
2686 
2687 class HPhase : public CompilationPhase {
2688  public:
2689  HPhase(const char* name, HGraph* graph)
2690  : CompilationPhase(name, graph->info()),
2691  graph_(graph) { }
2692  ~HPhase();
2693 
2694  protected:
2695  HGraph* graph() const { return graph_; }
2696 
2697  private:
2698  HGraph* graph_;
2699 
2700  DISALLOW_COPY_AND_ASSIGN(HPhase);
2701 };
2702 
2703 
2704 class HTracer V8_FINAL : public Malloced {
2705  public:
2706  explicit HTracer(int isolate_id)
2707  : trace_(&string_allocator_), indent_(0) {
2708  if (FLAG_trace_hydrogen_file == NULL) {
2709  OS::SNPrintF(filename_,
2710  "hydrogen-%d-%d.cfg",
2712  isolate_id);
2713  } else {
2714  OS::StrNCpy(filename_, FLAG_trace_hydrogen_file, filename_.length());
2715  }
2716  WriteChars(filename_.start(), "", 0, false);
2717  }
2718 
2719  void TraceCompilation(CompilationInfo* info);
2720  void TraceHydrogen(const char* name, HGraph* graph);
2721  void TraceLithium(const char* name, LChunk* chunk);
2722  void TraceLiveRanges(const char* name, LAllocator* allocator);
2723 
2724  private:
2725  class Tag V8_FINAL BASE_EMBEDDED {
2726  public:
2727  Tag(HTracer* tracer, const char* name) {
2728  name_ = name;
2729  tracer_ = tracer;
2730  tracer->PrintIndent();
2731  tracer->trace_.Add("begin_%s\n", name);
2732  tracer->indent_++;
2733  }
2734 
2735  ~Tag() {
2736  tracer_->indent_--;
2737  tracer_->PrintIndent();
2738  tracer_->trace_.Add("end_%s\n", name_);
2739  ASSERT(tracer_->indent_ >= 0);
2740  tracer_->FlushToFile();
2741  }
2742 
2743  private:
2744  HTracer* tracer_;
2745  const char* name_;
2746  };
2747 
2748  void TraceLiveRange(LiveRange* range, const char* type, Zone* zone);
2749  void Trace(const char* name, HGraph* graph, LChunk* chunk);
2750  void FlushToFile();
2751 
2752  void PrintEmptyProperty(const char* name) {
2753  PrintIndent();
2754  trace_.Add("%s\n", name);
2755  }
2756 
2757  void PrintStringProperty(const char* name, const char* value) {
2758  PrintIndent();
2759  trace_.Add("%s \"%s\"\n", name, value);
2760  }
2761 
2762  void PrintLongProperty(const char* name, int64_t value) {
2763  PrintIndent();
2764  trace_.Add("%s %d000\n", name, static_cast<int>(value / 1000));
2765  }
2766 
2767  void PrintBlockProperty(const char* name, int block_id) {
2768  PrintIndent();
2769  trace_.Add("%s \"B%d\"\n", name, block_id);
2770  }
2771 
2772  void PrintIntProperty(const char* name, int value) {
2773  PrintIndent();
2774  trace_.Add("%s %d\n", name, value);
2775  }
2776 
2777  void PrintIndent() {
2778  for (int i = 0; i < indent_; i++) {
2779  trace_.Add(" ");
2780  }
2781  }
2782 
2783  EmbeddedVector<char, 64> filename_;
2784  HeapStringAllocator string_allocator_;
2785  StringStream trace_;
2786  int indent_;
2787 };
2788 
2789 
2790 class NoObservableSideEffectsScope V8_FINAL {
2791  public:
2793  builder_(builder) {
2794  builder_->graph()->IncrementInNoSideEffectsScope();
2795  }
2797  builder_->graph()->DecrementInNoSideEffectsScope();
2798  }
2799 
2800  private:
2801  HGraphBuilder* builder_;
2802 };
2803 
2804 
2805 } } // namespace v8::internal
2806 
2807 #endif // V8_HYDROGEN_H_
const ZoneList< HPhi * > * phi_list() const
Definition: hydrogen.h:328
HInstruction * NewUncasted(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6)
Definition: hydrogen.h:1244
int update_type_change_checksum(int delta)
Definition: hydrogen.h:410
bool IsNestedInThisLoop(HLoopInformation *other)
Definition: hydrogen.h:293
enable upcoming ES6 features enable harmony block scoping enable harmony enable harmony proxies enable harmony generators enable harmony numeric enable harmony string enable harmony math functions harmony_scoping harmony_symbols harmony_collections harmony_iteration harmony_strings harmony_scoping harmony_maths tracks arrays with only smi values Optimize object Array DOM strings and string pretenure call new trace pretenuring decisions of HAllocate instructions track fields with only smi values track fields with heap values track_fields track_fields Enables optimizations which favor memory size over execution speed use string slices optimization filter maximum number of GVN fix point iterations use function inlining use allocation folding eliminate write barriers targeting allocations in optimized code maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining crankshaft harvests type feedback from stub cache trace check elimination phase hydrogen tracing filter NULL
Definition: flags.cc:269
#define INLINE_FUNCTION_LIST(F)
Definition: runtime.h:643
bool IsTest() const
Definition: hydrogen.h:778
AstContext(HOptimizedGraphBuilder *owner, Expression::Context kind)
Definition: hydrogen.cc:3641
I * New(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8)
Definition: hydrogen.h:1296
HValue * TruncateToNumber(HValue *value, Type **expected)
Definition: hydrogen.cc:9139
const ZoneList< HBasicBlock * > * blocks() const
Definition: hydrogen.h:283
ArgumentsAllowedFlag
Definition: hydrogen.h:764
void GotoNoSimulate(HBasicBlock *from, HBasicBlock *target)
Definition: hydrogen.h:1100
static const int kUnlimitedMaxInlinedNodesCumulative
Definition: hydrogen.h:2089
void BindContext(HValue *value)
Definition: hydrogen.h:613
Isolate * isolate() const
Definition: hydrogen.h:1073
Condition * AndIf(HValue *p1, P2 p2, P3 p3)
Definition: hydrogen.h:1532
void BuildTransitionElementsKind(HValue *object, HValue *map, ElementsKind from_kind, ElementsKind to_kind, bool is_jsarray)
Definition: hydrogen.cc:1387
int push_count() const
Definition: hydrogen.h:589
virtual bool BuildGraph()=0
void DisallowAddingNewValues()
Definition: hydrogen.h:388
void set_arguments_object(HArgumentsObject *arguments_object)
Definition: hydrogen.h:932
HBasicBlock * function_return()
Definition: hydrogen.h:919
void BuildCreateAllocationMemento(HValue *previous_object, HValue *previous_object_size, HValue *payload)
Definition: hydrogen.cc:2713
void VisitTypeof(UnaryOperation *expr)
Definition: hydrogen.cc:8826
HInstruction * BuildGetArrayFunction()
Definition: hydrogen.cc:2772
void set_parent_loop_header(HBasicBlock *block)
Definition: hydrogen.h:128
const ZoneList< HPhi * > * phis() const
Definition: hydrogen.h:67
Condition * OrIf(HValue *p)
Definition: hydrogen.h:1502
void set_argument_count(int count)
Definition: hydrogen.h:92
uint16_t current_
HInstruction * Current()
Definition: hydrogen.h:259
void set_ast_context(AstContext *context)
Definition: hydrogen.h:2100
Condition * IfNot(HValue *p)
Definition: hydrogen.h:1481
enable upcoming ES6 features enable harmony block scoping enable harmony enable harmony proxies enable harmony generators enable harmony numeric enable harmony string enable harmony math functions harmony_scoping harmony_symbols harmony_collections harmony_iteration harmony_strings harmony_scoping harmony_maths true
Definition: flags.cc:208
void Continue(HBasicBlock **true_branch, HBasicBlock **false_branch)
Definition: hydrogen.h:1001
void VisitVoid(UnaryOperation *expr)
Definition: hydrogen.cc:8820
HValue * BuildCloneShallowArray(HValue *boilerplate, HValue *allocation_site, AllocationSiteMode mode, ElementsKind kind, int length)
Definition: hydrogen.cc:2587
void GotoNoSimulate(HBasicBlock *target)
Definition: hydrogen.h:1103
HInstruction * NewUncasted(P1 p1, P2 p2, P3 p3, P4 p4)
Definition: hydrogen.h:1204
void set_for_typeof(bool for_typeof)
Definition: hydrogen.h:804
enable upcoming ES6 features enable harmony block scoping enable harmony enable harmony proxies enable harmony generators enable harmony numeric enable harmony string enable harmony math functions harmony_scoping harmony_symbols harmony_collections harmony_iteration harmony_strings harmony_scoping harmony_maths tracks arrays with only smi values Optimize object Array DOM strings and string pretenure call new trace pretenuring decisions of HAllocate instructions track fields with only smi values track fields with heap values track_fields track_fields Enables optimizations which favor memory size over execution speed use string slices optimization filter maximum number of GVN fix point iterations use function inlining use allocation folding eliminate write barriers targeting allocations in optimized code maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining crankshaft harvests type feedback from stub cache trace check elimination phase hydrogen tracing filter trace hydrogen to given file name trace inlining decisions trace store elimination trace all use positions trace global value numbering trace hydrogen escape analysis trace the tracking of allocation sites trace map generalization environment for every instruction deoptimize every n garbage collections put a break point before deoptimizing deoptimize uncommon cases use on stack replacement trace array bounds check elimination perform array index dehoisting use load elimination use store elimination use constant folding eliminate unreachable code number of stress runs when picking a function to watch for shared function not JSFunction itself flushes the cache of optimized code for closures on every GC functions with arguments object maximum number of escape analysis fix point iterations allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms concurrent on stack replacement do not emit check maps for constant values that have a leaf map
Definition: flags.cc:350
void PushArgumentsFromEnvironment(int count)
Definition: hydrogen.cc:4109
void set_osr(HOsrBuilder *osr)
Definition: hydrogen.h:402
bool is_local_index(int i) const
Definition: hydrogen.h:706
BailoutId ast_id() const
Definition: hydrogen.h:591
CompilationInfo * info() const
Definition: hydrogen.h:325
int IndexFor(Variable *variable) const
Definition: hydrogen.h:698
PretenureFlag GetPretenureMode() const V8_WARN_UNUSED_RESULT
Definition: hydrogen.h:1044
HInstruction * AddUncasted(P1 p1, P2 p2)
Definition: hydrogen.h:1166
void RecordUint32Instruction(HInstruction *instr)
Definition: hydrogen.h:462
#define DECLARE_VISIT(type)
Definition: hydrogen.h:2233
bool IsEffect() const
Definition: hydrogen.h:776
HBasicBlock * if_false() const
Definition: hydrogen.h:895
I * New(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7)
Definition: hydrogen.h:1271
FunctionState * outer()
Definition: hydrogen.h:926
Zone * zone() const
Definition: hydrogen.h:324
HBasicBlock * Current()
Definition: hydrogen.h:242
int GetNextValueID(HValue *value)
Definition: hydrogen.h:379
void VisitForValue(Expression *expr, ArgumentsAllowedFlag flag=ARGUMENTS_NOT_ALLOWED)
Definition: hydrogen.cc:3880
I * Add(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6)
Definition: hydrogen.h:1259
void AddIncrementCounter(StatsCounter *counter)
Definition: hydrogen.cc:1214
void ThenDeopt(const char *reason)
Definition: hydrogen.h:1589
void set_ast_id(BailoutId id)
Definition: hydrogen.h:592
bool IsInlineReturnTarget() const
Definition: hydrogen.h:155
HBasicBlock * CreateLoop(IterationStatement *statement, HBasicBlock *loop_entry, HBasicBlock *body_exit, HBasicBlock *loop_successor, HBasicBlock *break_block)
Definition: hydrogen.cc:3030
void BuildCopySeqStringChars(HValue *src, HValue *src_offset, String::Encoding src_encoding, HValue *dst, HValue *dst_offset, String::Encoding dst_encoding, HValue *length)
Definition: hydrogen.cc:1885
HInstruction * AddLoadStringInstanceType(HValue *string)
Definition: hydrogen.cc:6205
void AddLeaveInlined(HBasicBlock *block, HValue *return_value, FunctionState *state)
Definition: hydrogen.h:1106
void VisitDelete(UnaryOperation *expr)
Definition: hydrogen.cc:8780
HOsrBuilder * osr() const
Definition: hydrogen.h:2051
bool HasEnvironment() const
Definition: hydrogen.h:124
HValue * LookupValue(int id) const
Definition: hydrogen.h:384
HLoopInformation * loop_information() const
Definition: hydrogen.h:72
Condition * OrIf(HValue *p1, P2 p2, P3 p3)
Definition: hydrogen.h:1514
HInstruction * first() const
Definition: hydrogen.h:68
HEnvironment * start_environment() const
Definition: hydrogen.h:330
HInstruction * AddUncasted(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7)
Definition: hydrogen.h:1277
void set_source_position(HSourcePosition position)
Definition: hydrogen.h:1837
void Push(HValue *value)
Definition: hydrogen.h:1079
virtual void ReturnInstruction(HInstruction *instr, BailoutId ast_id)=0
HBasicBlock * function_return() const
Definition: hydrogen.h:2109
HStoreNamedField * AddStoreMapNoWriteBarrier(HValue *object, HValue *map)
Definition: hydrogen.h:1409
TestContext(HOptimizedGraphBuilder *owner, Expression *condition, HBasicBlock *if_true, HBasicBlock *if_false)
Definition: hydrogen.h:870
HBasicBlock * if_true() const
Definition: hydrogen.h:894
HStoreNamedField * AddStoreMapConstantNoWriteBarrier(HValue *object, Handle< Map > map)
Definition: hydrogen.h:1416
HValue * BuildBinaryOperation(Token::Value op, HValue *left, HValue *right, Type *left_type, Type *right_type, Type *result_type, Maybe< int > fixed_right_arg, HAllocationMode allocation_mode)
Definition: hydrogen.cc:9219
TypeImpl< ZoneTypeConfig > Type
int int32_t
Definition: unicode.cc:47
KeyedAccessStoreMode
Definition: objects.h:164
HInstruction * AddUncasted(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8)
Definition: hydrogen.h:1302
HArgumentsObject * arguments_object()
Definition: hydrogen.h:931
HValue * BuildUncheckedStringAdd(HValue *left, HValue *right, HAllocationMode allocation_mode)
Definition: hydrogen.cc:1920
void AddSimulate(BailoutId id, RemovableSimulate removable=FIXED_SIMULATE)
Definition: hydrogen.cc:1227
const ZoneList< HBasicBlock * > * predecessors() const
Definition: hydrogen.h:78
virtual void ReturnControl(HControlInstruction *instr, BailoutId ast_id)=0
bool IsStackAllocated() const
Definition: variables.h:118
bool IsFinished() const
Definition: hydrogen.h:110
HOptimizedGraphBuilder * owner() const
Definition: hydrogen.h:811
HSourcePosition source_position()
Definition: hydrogen.h:1836
AllocationSiteOverrideMode
Definition: code-stubs.h:759
Condition * IfNot(HValue *p1, P2 p2)
Definition: hydrogen.h:1488
HLoopInformation(HBasicBlock *loop_header, Zone *zone)
Definition: hydrogen.h:273
int length() const
Definition: hydrogen.h:597
void IncrementInNoSideEffectsScope()
Definition: hydrogen.h:470
HValue * BuildGrowElementsCapacity(HValue *object, HValue *elements, ElementsKind kind, ElementsKind new_kind, HValue *length, HValue *new_capacity)
Definition: hydrogen.cc:2457
#define ASSERT(condition)
Definition: checks.h:329
BreakAndContinueInfo(BreakableStatement *target, int drop_extra=0)
Definition: hydrogen.h:1991
void DecrementInNoSideEffectsScope()
Definition: hydrogen.h:471
HBasicBlock * current_block() const
Definition: hydrogen.h:1066
HArgumentsElements * arguments_elements()
Definition: hydrogen.h:936
HGraph * graph() const
Definition: hydrogen.h:2695
ExternalArrayType
Definition: v8.h:2113
FunctionState * function_state() const
Definition: hydrogen.h:2059
HPredecessorIterator(HBasicBlock *block)
Definition: hydrogen.h:238
void VisitLoopBody(IterationStatement *stmt, HBasicBlock *loop_entry, BreakAndContinueInfo *break_info)
Definition: hydrogen.cc:4512
bool is_special_index(int i) const
Definition: hydrogen.h:714
static const int kUnlimitedMaxInlinedNodes
Definition: hydrogen.h:2088
bool is_this() const
Definition: variables.h:129
I * Add(P1 p1, P2 p2, P3 p3)
Definition: hydrogen.h:1199
HSourcePosition ScriptPositionToSourcePosition(int position)
Definition: hydrogen.h:1830
Condition * AndIf(HValue *p1, P2 p2)
Definition: hydrogen.h:1526
void VisitDeclarations(ZoneList< Declaration * > *declarations)
Definition: hydrogen.cc:10156
I * New(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5)
Definition: hydrogen.h:1229
HOsrBuilder * osr()
Definition: hydrogen.h:406
int maximum_environment_size()
Definition: hydrogen.h:420
I * Add(P1 p1, P2 p2, P3 p3, P4 p4)
Definition: hydrogen.h:1219
static const int kMaxStorePolymorphism
Definition: hydrogen.h:2083
HValue * BuildCreateConsString(HValue *length, HValue *left, HValue *right, HAllocationMode allocation_mode)
Definition: hydrogen.cc:1803
HEnterInlined * entry() const
Definition: hydrogen.h:594
HEnvironment * environment() const
Definition: hydrogen.h:1068
FrameType frame_type() const
Definition: hydrogen.h:583
HPhase(const char *name, HGraph *graph)
Definition: hydrogen.h:2689
bool HasPredecessor() const
Definition: hydrogen.h:79
HInstruction * PreProcessCall(Instruction *call)
Definition: hydrogen.cc:4122
static const int kUnlimitedMaxInlinedSourceSize
Definition: hydrogen.h:2087
HAllocate * BuildAllocate(HValue *object_size, HType type, InstanceType instance_type, HAllocationMode allocation_mode)
Definition: hydrogen.cc:1766
static TestContext * cast(AstContext *context)
Definition: hydrogen.h:888
kInstanceClassNameOffset flag
Definition: objects-inl.h:5115
HAllocationMode(PretenureFlag pretenure_flag)
Definition: hydrogen.h:1032
const GrowableBitVector * assigned_variables() const
Definition: hydrogen.h:580
CompilationInfo * current_info() const
Definition: hydrogen.h:2103
int first_local_index() const
Definition: hydrogen.h:603
bool IsDeoptimizing() const
Definition: hydrogen.h:162
HValue * Lookup(Variable *variable) const
Definition: hydrogen.h:617
void RecordDeletedPhi(int merge_index)
Definition: hydrogen.h:86
void Bailout(BailoutReason reason)
Definition: hydrogen.cc:3868
const ZoneList< HValue * > * values() const
Definition: hydrogen.h:579
void Bind(Variable *var, HValue *value)
Definition: hydrogen.h:2169
virtual HValue * context()=0
I * New(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6)
Definition: hydrogen.h:1249
void ElseDeopt(const char *reason)
Definition: hydrogen.h:1593
void EnterInlinedSource(int start_position, int id)
Definition: hydrogen.h:1820
AstContext * call_context()
Definition: hydrogen.h:917
void(HOptimizedGraphBuilder::* InlineFunctionGenerator)(CallRuntime *call)
Definition: hydrogen.h:2074
HControlInstruction * end() const
Definition: hydrogen.h:71
I * New(P1 p1, P2 p2, P3 p3)
Definition: hydrogen.h:1189
int first_expression_index() const
Definition: hydrogen.h:599
enable upcoming ES6 features enable harmony block scoping enable harmony enable harmony proxies enable harmony generators enable harmony numeric enable harmony string enable harmony math functions harmony_scoping harmony_symbols harmony_collections harmony_iteration harmony_strings harmony_scoping harmony_maths tracks arrays with only smi values Optimize object Array DOM strings and string pretenure call new trace pretenuring decisions of HAllocate instructions track fields with only smi values track fields with heap values track_fields track_fields Enables optimizations which favor memory size over execution speed use string slices optimization filter maximum number of GVN fix point iterations use function inlining use allocation folding eliminate write barriers targeting allocations in optimized code maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining crankshaft harvests type feedback from stub cache trace check elimination phase hydrogen tracing filter trace hydrogen to given file name trace inlining decisions trace store elimination trace all use positions trace global value numbering trace hydrogen escape analysis trace the tracking of allocation sites trace map generalization environment for every instruction deoptimize every n garbage collections put a break point before deoptimizing deoptimize uncommon cases use on stack replacement trace array bounds check elimination perform array index dehoisting use load elimination use store elimination use constant folding eliminate unreachable code number of stress runs when picking a function to watch for shared function not JSFunction itself flushes the cache of optimized code for closures on every GC functions with arguments object maximum number of escape analysis fix point iterations allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms concurrent on stack replacement do not emit check maps for constant values that have a leaf deoptimize the optimized code if the layout of the maps changes number of stack frames inspected by the profiler percentage of ICs that must have type info to allow optimization extra verbose compilation tracing generate extra emit comments in code disassembly enable use of SSE3 instructions if available enable use of CMOV instruction if available enable use of VFP3 instructions if available enable use of NEON instructions if enable use of SDIV and UDIV instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of d16 d31 registers on ARM this requires VFP3 force all emitted branches to be in long mode(MIPS only)") DEFINE_string(expose_natives_as
enable upcoming ES6 features enable harmony block scoping enable harmony enable harmony proxies enable harmony generators enable harmony numeric enable harmony string enable harmony math functions harmony_scoping harmony_symbols harmony_collections harmony_iteration harmony_strings harmony_scoping harmony_maths tracks arrays with only smi values Optimize object size
Definition: flags.cc:211
void FinishExitWithHardDeoptimization(const char *reason)
Definition: hydrogen.cc:1257
STATIC_ASSERT(sizeof(CPURegister)==sizeof(Register))
CompilationInfo * compilation_info()
Definition: hydrogen.h:916
I * Add(P1 p1, P2 p2)
Definition: hydrogen.h:1175
const int kDoubleSize
Definition: globals.h:266
const ZoneList< HBasicBlock * > * dominated_blocks() const
Definition: hydrogen.h:80
AstContext * call_context() const
Definition: hydrogen.h:2106
void VisitForEffect(Expression *expr)
Definition: hydrogen.cc:3874
const ZoneList< HBasicBlock * > * back_edges() const
Definition: hydrogen.h:282
int specials_count() const
Definition: hydrogen.h:585
NilValue
Definition: v8.h:133
HValue * BuildElementIndexHash(HValue *index)
Definition: hydrogen.cc:1506
Handle< AllocationSite > feedback_site() const
Definition: hydrogen.h:1038
static const int kMaxFastLiteralDepth
Definition: hydrogen.h:2093
const int kPointerSize
Definition: globals.h:268
void check(i::Vector< const uint8_t > string)
void set_current_block(HBasicBlock *block)
Definition: hydrogen.h:1067
bool depends_on_empty_array_proto_elements()
Definition: hydrogen.h:448
void set_entry(HEnterInlined *entry)
Definition: hydrogen.h:595
HEnvironment * DiscardInlined(bool drop_extra)
Definition: hydrogen.h:675
void MarkDependsOnEmptyArrayProtoElements()
Definition: hydrogen.h:438
enable upcoming ES6 features enable harmony block scoping enable harmony enable harmony proxies enable harmony generators enable harmony numeric enable harmony string enable harmony math functions harmony_scoping harmony_symbols harmony_collections harmony_iteration harmony_strings harmony_scoping harmony_maths tracks arrays with only smi values Optimize object Array shift
Definition: flags.cc:211
void IncrementSubtotals(TimeDelta create_graph, TimeDelta optimize_graph, TimeDelta generate_code)
Definition: hydrogen.h:2666
BreakAndContinueScope * break_scope() const
Definition: hydrogen.h:2044
static const InlineFunctionGenerator kInlineFunctionGenerators[]
Definition: hydrogen.h:2077
void IncrementFullCodeGen(TimeDelta full_code_gen)
Definition: hydrogen.h:2662
HValue * LookupAndMakeLive(Variable *var)
Definition: hydrogen.h:2196
void BuildArrayBufferViewInitialization(HValue *obj, HValue *buffer, HValue *byte_offset, HValue *byte_length)
Definition: hydrogen.cc:8418
HLoopInformation * current_loop() const
Definition: hydrogen.h:73
static const int kMaxLoadPolymorphism
Definition: hydrogen.h:2082
HInstruction * BuildCheckPrototypeMaps(Handle< JSObject > prototype, Handle< JSObject > holder)
Definition: hydrogen.cc:6785
HValue * context() const
Definition: hydrogen.h:627
Condition * If(HValue *p1, P2 p2)
Definition: hydrogen.h:1467
void Bind(Variable *variable, HValue *value)
Definition: hydrogen.h:607
bool IsStartBlock() const
Definition: hydrogen.h:107
void set_arguments_elements(HArgumentsElements *arguments_elements)
Definition: hydrogen.h:937
#define DISALLOW_COPY_AND_ASSIGN(TypeName)
Definition: globals.h:359
HInstruction * AddLoadStringLength(HValue *string)
Definition: hydrogen.cc:6219
virtual void ReturnContinuation(HIfContinuation *continuation, BailoutId ast_id)=0
int index() const
Definition: variables.h:147
static int GetCurrentProcessId()
#define INLINE_FUNCTION_GENERATOR_DECLARATION(Name, argc, ressize)
Definition: hydrogen.h:2123
bool HasParentLoopHeader() const
Definition: hydrogen.h:133
I * New(P1 p1, P2 p2)
Definition: hydrogen.h:1161
HEnterInlined * entry()
Definition: hydrogen.h:928
HInstruction * AddUncasted(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6)
Definition: hydrogen.h:1254
HValue * Lookup(int index) const
Definition: hydrogen.h:621
Condition * OrIf(HValue *p1, P2 p2)
Definition: hydrogen.h:1508
Definition: v8.h:123
HGraphBuilder(CompilationInfo *info)
Definition: hydrogen.h:1058
void VisitLogicalExpression(BinaryOperation *expr)
Definition: hydrogen.cc:9478
HValue * BuildAllocateArrayFromLength(JSArrayBuilder *array_builder, HValue *length_argument)
Definition: hydrogen.cc:2255
#define BASE_EMBEDDED
Definition: allocation.h:68
HValue * BuildAllocateElementsAndInitializeElementsHeader(ElementsKind kind, HValue *capacity)
Definition: hydrogen.cc:2340
Handle< JSFunction > closure() const
Definition: compiler.h:81
HOptimizedGraphBuilder(CompilationInfo *info)
Definition: hydrogen.cc:2980
#define AST_NODE_LIST(V)
Definition: ast.h:121
HInstruction * BuildGetNativeContext()
Definition: hydrogen.cc:2760
HBasicBlock * true_branch() const
Definition: hydrogen.h:1015
const ZoneList< int > * deleted_phis() const
Definition: hydrogen.h:83
BreakAndContinueScope(BreakAndContinueInfo *info, HOptimizedGraphBuilder *owner)
Definition: hydrogen.h:2017
HInstructionIterator(HBasicBlock *block)
Definition: hydrogen.h:253
HInstruction * AddUncasted()
Definition: hydrogen.h:1122
void VisitForTypeOf(Expression *expr)
Definition: hydrogen.cc:3887
void Capture(HBasicBlock *true_branch, HBasicBlock *false_branch)
Definition: hydrogen.h:993
void BuildCompareNil(HValue *value, Type *type, HIfContinuation *continuation)
Definition: hydrogen.cc:2661
void VisitNot(UnaryOperation *expr)
Definition: hydrogen.cc:8834
void MarkAsLoopSuccessorDominator()
Definition: hydrogen.h:173
void set_stack_check(HStackCheck *stack_check)
Definition: hydrogen.h:289
void update_maximum_environment_size(int environment_size)
Definition: hydrogen.h:415
void set_first_instruction_index(int index)
Definition: hydrogen.h:94
HBasicBlock * CreateJoin(HBasicBlock *first, HBasicBlock *second, BailoutId join_id)
Definition: hydrogen.cc:3001
static int SNPrintF(Vector< char > str, const char *format,...)
HInstruction * AddElementAccess(HValue *elements, HValue *checked_key, HValue *val, HValue *dependency, ElementsKind elements_kind, PropertyAccessType access_type, LoadKeyedHoleMode load_mode=NEVER_RETURN_HOLE)
Definition: hydrogen.cc:2386
HBasicBlock * dominator() const
Definition: hydrogen.h:89
int WriteChars(const char *filename, const char *str, int size, bool verbose)
Definition: v8utils.cc:231
HValue * BuildNewElementsCapacity(HValue *old_capacity)
Definition: hydrogen.cc:2431
HEnvironment * last_environment() const
Definition: hydrogen.h:90
void VisitForControl(Expression *expr, HBasicBlock *true_block, HBasicBlock *false_block)
Definition: hydrogen.cc:3894
void Goto(HBasicBlock *target, FunctionState *state=NULL, bool add_simulate=true)
Definition: hydrogen.h:1095
HValue * BuildAddStringLengths(HValue *left_length, HValue *right_length)
Definition: hydrogen.cc:1793
I * Add(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7)
Definition: hydrogen.h:1283
Expression * condition() const
Definition: hydrogen.h:893
bool has_uint32_instructions()
Definition: hydrogen.h:452
HValue * BuildWrapReceiver(HValue *object, HValue *function)
Definition: hydrogen.cc:1279
I * Add(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5)
Definition: hydrogen.h:1239
int last_instruction_index() const
Definition: hydrogen.h:97
void BuildNewSpaceArrayCheck(HValue *length, ElementsKind kind)
Definition: hydrogen.cc:2447
Isolate * isolate() const
Definition: hydrogen.h:323
void set_use_optimistic_licm(bool value)
Definition: hydrogen.h:426
HValue * BuildObjectSizeAlignment(HValue *unaligned_size, int header_size)
Definition: hydrogen.cc:1907
void SetSourcePosition(int position)
Definition: hydrogen.h:1815
bool is_parameter_index(int i) const
Definition: hydrogen.h:710
HValue * EnforceNumberType(HValue *number, Type *expected)
Definition: hydrogen.cc:9126
HValue * BuildRegExpConstructResult(HValue *length, HValue *index, HValue *input)
Definition: hydrogen.cc:1560
void AddLeaveInlined(HValue *return_value, FunctionState *state)
Definition: hydrogen.h:1111
HTracer(int isolate_id)
Definition: hydrogen.h:2706
int inlining_id() const
Definition: hydrogen.h:943
HValue * BuildAllocateElements(ElementsKind kind, HValue *capacity)
Definition: hydrogen.cc:2297
#define V8_OVERRIDE
Definition: v8config.h:402
Handle< T > handle(T *t, Isolate *isolate)
Definition: handles.h:103
HInstruction * NewUncasted()
Definition: hydrogen.h:1116
enable upcoming ES6 features enable harmony block scoping enable harmony enable harmony proxies enable harmony generators enable harmony numeric enable harmony string enable harmony math functions harmony_scoping harmony_symbols harmony_collections harmony_iteration harmony_strings harmony_scoping harmony_maths tracks arrays with only smi values Optimize object Array DOM strings and string pretenure call new trace pretenuring decisions of HAllocate instructions track fields with only smi values track fields with heap values track_fields track_fields Enables optimizations which favor memory size over execution speed use string slices optimization filter maximum number of GVN fix point iterations use function inlining use allocation folding eliminate write barriers targeting allocations in optimized code maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining crankshaft harvests type feedback from stub cache trace check elimination phase hydrogen tracing filter trace hydrogen to given file name trace inlining decisions trace store elimination trace all use positions trace global value numbering trace hydrogen escape analysis trace the tracking of allocation sites trace map generalization environment for every instruction deoptimize every n garbage collections put a break point before deoptimizing deoptimize uncommon cases use on stack replacement trace array bounds check elimination perform array index dehoisting use load elimination use store elimination use constant folding eliminate unreachable code number of stress runs when picking a function to watch for shared function info
Definition: flags.cc:317
bool IsInsideNoSideEffectsScope()
Definition: hydrogen.h:472
HBasicBlock * parent_loop_header() const
Definition: hydrogen.h:126
Condition * IfNot(HValue *p1, P2 p2, P3 p3)
Definition: hydrogen.h:1495
HGraph * graph() const
Definition: hydrogen.h:65
HArgumentsObject * GetArgumentsObject() const
Definition: hydrogen.h:369
bool IsParameter() const
Definition: variables.h:116
int argument_count() const
Definition: hydrogen.h:91
bool is_arguments() const
Definition: variables.h:130
HInstruction * NewUncasted(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8)
Definition: hydrogen.h:1289
static const int kMaxFastLiteralProperties
Definition: hydrogen.h:2094
HInstruction * NewUncasted(P1 p1, P2 p2, P3 p3)
Definition: hydrogen.h:1184
int block_id() const
Definition: hydrogen.h:63
HValue * BuildCheckString(HValue *string)
Definition: hydrogen.cc:1268
bool IsEligibleForEnvironmentLivenessAnalysis(Variable *var, int index, HValue *value, HEnvironment *env)
Definition: hydrogen.h:2170
HBasicBlock * CreateLoopHeaderBlock()
Definition: hydrogen.cc:1242
Type * ToType(Handle< Map > map)
Definition: hydrogen.h:2237
CompilationInfo * top_info()
Definition: hydrogen.h:1074
HValue * BuildCopyElementsOnWrite(HValue *object, HValue *elements, ElementsKind kind, HValue *length)
Definition: hydrogen.cc:1359
HInstruction * AddUncasted(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5)
Definition: hydrogen.h:1234
int parameter_count() const
Definition: hydrogen.h:584
bool is_recursive() const
Definition: hydrogen.h:434
void VisitExpressions(ZoneList< Expression * > *exprs)
Definition: hydrogen.cc:3902
HInstruction * NewUncasted(P1 p1)
Definition: hydrogen.h:1128
bool CreateAllocationMementos() const V8_WARN_UNUSED_RESULT
Definition: hydrogen.h:1040
HValue * BuildNumberToString(HValue *object, Type *type)
Definition: hydrogen.cc:1627
bool IsLoopSuccessorDominator() const
Definition: hydrogen.h:170
HBasicBlock * CreateBasicBlock(HEnvironment *env)
Definition: hydrogen.cc:1235
HValue * ExpressionStackAt(int index_from_top) const
Definition: hydrogen.h:654
#define V8_WARN_UNUSED_RESULT
Definition: v8config.h:361
void SetArgumentsObject(HArgumentsObject *object)
Definition: hydrogen.h:373
void BuildInitializeElementsHeader(HValue *elements, ElementsKind kind, HValue *capacity)
Definition: hydrogen.cc:2326
NoObservableSideEffectsScope(HGraphBuilder *builder)
Definition: hydrogen.h:2792
void set_inlining_id(int inlining_id)
virtual void VisitStatements(ZoneList< Statement * > *statements) V8_OVERRIDE
Definition: hydrogen.cc:4167
HInstruction * last() const
Definition: hydrogen.h:69
void VisitComma(BinaryOperation *expr)
Definition: hydrogen.cc:9470
void USE(T)
Definition: globals.h:341
HBasicBlock * inlined_entry_block()
Definition: hydrogen.h:160
Condition * AndIf(HValue *p)
Definition: hydrogen.h:1520
HEnvironment * arguments_environment()
Definition: hydrogen.h:573
static void StrNCpy(Vector< char > dest, const char *src, size_t n)
bool end_
HInstruction * NewUncasted(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5)
Definition: hydrogen.h:1224
void Print(const v8::FunctionCallbackInfo< v8::Value > &args)
HStoreNamedField * AddStoreMapConstant(HValue *object, Handle< Map > map)
Definition: hydrogen.cc:2958
HAllocationMode(Handle< AllocationSite > feedback_site)
Definition: hydrogen.h:1027
Zone * zone() const
Definition: hydrogen.h:2646
int GetMaximumValueID() const
Definition: hydrogen.h:377
HInstruction * NewUncasted(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7)
Definition: hydrogen.h:1265
void Add(const T &element, AllocationPolicy allocator=AllocationPolicy())
Definition: list-inl.h:39
bool PreProcessOsrEntry(IterationStatement *statement)
HLoopInformation * parent_loop()
Definition: hydrogen.h:302
void set_block_id(int id)
Definition: hydrogen.h:64
bool IsLoopHeader() const
Definition: hydrogen.h:106
static const int kPreallocatedArrayElements
Definition: objects.h:10073
void GotoNoSimulate(HBasicBlock *block, HSourcePosition position)
Definition: hydrogen.h:195
HInstruction * AddUncasted(P1 p1)
Definition: hydrogen.h:1136
static const int kMaxCallPolymorphism
Definition: hydrogen.h:2081
HInstruction * BuildUncheckedMonomorphicElementAccess(HValue *checked_object, HValue *key, HValue *val, bool is_js_array, ElementsKind elements_kind, PropertyAccessType access_type, LoadKeyedHoleMode load_mode, KeyedAccessStoreMode store_mode)
Definition: hydrogen.cc:2141
ZoneList< HInstruction * > * uint32_instructions()
Definition: hydrogen.h:457
HeapObject * obj
EffectContext(HOptimizedGraphBuilder *owner)
Definition: hydrogen.h:831
void set_last_instruction_index(int index)
Definition: hydrogen.h:98
HValue * BuildCheckForCapacityGrow(HValue *object, HValue *elements, ElementsKind kind, HValue *length, HValue *key, bool is_js_array, PropertyAccessType access_type)
Definition: hydrogen.cc:1292
void Push(HValue *value)
Definition: hydrogen.h:632
HLoadNamedField * AddLoadElements(HValue *object)
Definition: hydrogen.cc:2419
HBasicBlock * entry_block() const
Definition: hydrogen.h:329
HValue * BuildCheckMap(HValue *obj, Handle< Map > map)
Definition: hydrogen.cc:1263
bool IsValue() const
Definition: hydrogen.h:777
HSimulate * AddNewSimulate(BailoutId ast_id, HSourcePosition position, RemovableSimulate removable=FIXED_SIMULATE)
Definition: hydrogen.h:139
int first_instruction_index() const
Definition: hydrogen.h:93
Condition * If(HValue *p1, P2 p2, P3 p3)
Definition: hydrogen.h:1474
Handle< JSFunction > closure() const
Definition: hydrogen.h:578
AstContext * ast_context() const
Definition: hydrogen.h:2099
void set_function_state(FunctionState *state)
Definition: hydrogen.h:2097
HInstruction * AddUncasted(P1 p1, P2 p2, P3 p3)
Definition: hydrogen.h:1194
HValue * BuildUncheckedDictionaryElementLoad(HValue *receiver, HValue *key)
Definition: hydrogen.cc:1539
bool TrueAndFalseReachable()
Definition: hydrogen.h:1011
HInstruction * BuildConstantMapCheck(Handle< JSObject > constant, CompilationInfo *info)
Definition: hydrogen.cc:6767
void FinishCurrentBlock(HControlInstruction *last)
Definition: hydrogen.cc:1193
virtual bool BuildGraph() V8_OVERRIDE
Definition: hydrogen.cc:3910
bool MatchRotateRight(HValue *left, HValue *right, HValue **operand, HValue **shift_amount)
Definition: hydrogen.cc:9087
HValue * Top() const
Definition: hydrogen.h:650
void * New(int size)
Definition: zone-inl.h:51
bool IsUnreachable() const
Definition: hydrogen.h:167
void ClearInlinedTestContext()
Definition: hydrogen.h:921
void BuildCopyElements(HValue *from_elements, ElementsKind from_elements_kind, HValue *to_elements, ElementsKind to_elements_kind, HValue *length, HValue *capacity)
Definition: hydrogen.cc:2528
HValue * current_site() const
Definition: hydrogen.h:1037
void BuildFillElementsWithHole(HValue *elements, ElementsKind elements_kind, HValue *from, HValue *to)
Definition: hydrogen.cc:2479
void BindIfLive(Variable *var, HValue *value)
Definition: hydrogen.h:2182
int pop_count() const
Definition: hydrogen.h:588
HLoadNamedField * AddLoadFixedArrayLength(HValue *object)
Definition: hydrogen.cc:2425
HInnerAllocatedObject * BuildJSArrayHeader(HValue *array, HValue *array_map, AllocationSiteMode mode, ElementsKind elements_kind, HValue *allocation_site_payload, HValue *length_field)
Definition: hydrogen.cc:2352
enable upcoming ES6 features enable harmony block scoping enable harmony enable harmony proxies enable harmony generators enable harmony numeric enable harmony string enable harmony math functions harmony_scoping harmony_symbols harmony_collections harmony_iteration harmony_strings harmony_scoping harmony_maths tracks arrays with only smi values Optimize object Array DOM strings and string pretenure call new trace pretenuring decisions of HAllocate instructions track fields with only smi values track fields with heap values track_fields track_fields Enables optimizations which favor memory size over execution speed use string slices optimization filter maximum number of GVN fix point iterations use function inlining use allocation folding eliminate write barriers targeting allocations in optimized code maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining crankshaft harvests type feedback from stub cache trace check elimination phase hydrogen tracing filter trace hydrogen to given file name trace inlining decisions trace store elimination trace all use positions trace global value numbering trace hydrogen escape analysis trace the tracking of allocation sites trace map generalization environment for every instruction deoptimize every n garbage collections put a break point before deoptimizing deoptimize uncommon cases use on stack replacement trace array bounds check elimination perform array index dehoisting use load elimination use store elimination use constant folding eliminate unreachable code number of stress runs when picking a function to watch for shared function not JSFunction itself flushes the cache of optimized code for closures on every GC functions with arguments object maximum number of escape analysis fix point iterations allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms concurrent on stack replacement do not emit check maps for constant values that have a leaf deoptimize the optimized code if the layout of the maps changes number of stack frames inspected by the profiler percentage of ICs that must have type info to allow optimization extra verbose compilation tracing generate extra emit comments in code disassembly enable use of SSE3 instructions if available enable use of CMOV instruction if available enable use of VFP3 instructions if available enable use of NEON instructions if enable use of SDIV and UDIV instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of d16 d31 registers on ARM this requires VFP3 force all emitted branches to be in long expose natives in global object expose freeBuffer extension expose gc extension under the specified name expose externalize string extension number of stack frames to capture disable builtin natives files print name of functions for which code is generated use random jit cookie to mask large constants trace lazy optimization use adaptive optimizations always try to OSR functions trace optimize function deoptimization minimum length for automatic enable preparsing maximum number of optimization attempts before giving up cache prototype transitions trace debugging JSON request response trace out of bounds accesses to external arrays trace_js_array_abuse automatically set the debug break flag when debugger commands are in the queue abort by crashing maximum length of function source code printed in a stack trace max size of the new max size of the old max size of executable always perform global GCs print one trace line following each garbage collection do not print trace line after scavenger collection print statistics of the maximum memory committed for the heap in name
Definition: flags.cc:505
void MarkAsInlineReturnTarget(HBasicBlock *inlined_entry_block)
Definition: hydrogen.h:156
HInstruction * NewUncasted(P1 p1, P2 p2)
Definition: hydrogen.h:1156
HIfContinuation(HBasicBlock *true_branch, HBasicBlock *false_branch)
Definition: hydrogen.h:987
HValue * BuildCheckHeapObject(HValue *object)
Definition: hydrogen.cc:1251
virtual void ReturnValue(HValue *value)=0
HValue * BuildStringAdd(HValue *left, HValue *right, HAllocationMode allocation_mode)
Definition: hydrogen.cc:2092
HBasicBlock * false_branch() const
Definition: hydrogen.h:1016
ValueContext(HOptimizedGraphBuilder *owner, ArgumentsAllowedFlag flag)
Definition: hydrogen.h:848
HInstruction * AddUncasted(P1 p1, P2 p2, P3 p3, P4 p4)
Definition: hydrogen.h:1214
TestContext * test_context()
Definition: hydrogen.h:920
int local_count() const
Definition: hydrogen.h:586
I * Add(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8)
Definition: hydrogen.h:1309
bool use_optimistic_licm()
Definition: hydrogen.h:422
I * New(P1 p1, P2 p2, P3 p3, P4 p4)
Definition: hydrogen.h:1209
HStackCheck * stack_check() const
Definition: hydrogen.h:288
HBasicBlock * loop_header() const
Definition: hydrogen.h:284
HEnvironment * outer() const
Definition: hydrogen.h:587
HValue * AddLoadJSBuiltin(Builtins::JavaScript builtin)
Definition: hydrogen.cc:2965
void set_break_scope(BreakAndContinueScope *head)
Definition: hydrogen.h:2045
bool IsReachable() const
Definition: hydrogen.h:168
void SetValueAt(int index, HValue *value)
Definition: hydrogen.h:690
HAllocationMode(HValue *current_site)
Definition: hydrogen.h:1030
HGraph * graph() const
Definition: hydrogen.h:1072
HInstruction * AddInstruction(HInstruction *instr)
Definition: hydrogen.cc:1180
void set_last(HInstruction *instr)
Definition: hydrogen.h:70
bool IsFastDoubleElementsKind(ElementsKind kind)
HBasicBlock * JoinContinue(IterationStatement *statement, HBasicBlock *exit_block, HBasicBlock *continue_block)
Definition: hydrogen.cc:3018
void Goto(HBasicBlock *from, HBasicBlock *target, FunctionState *state=NULL, bool add_simulate=true)
Definition: hydrogen.h:1089
void VisitArithmeticExpression(BinaryOperation *expr)
Definition: hydrogen.cc:9581
void FinishExitCurrentBlock(HControlInstruction *instruction)
Definition: hydrogen.cc:1204
InliningKind inlining_kind() const
Definition: hydrogen.h:918
TestContext * inlined_test_context() const
Definition: hydrogen.h:2112
#define INLINE_OPTIMIZED_FUNCTION_LIST(F)
Definition: runtime.h:692
Zone * zone() const
Definition: hydrogen.h:1071