v8  3.14.5(node0.10.28)
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 "allocation.h"
34 #include "ast.h"
35 #include "compiler.h"
36 #include "hydrogen-instructions.h"
37 #include "type-info.h"
38 #include "zone.h"
39 
40 namespace v8 {
41 namespace internal {
42 
43 // Forward declarations.
44 class BitVector;
45 class FunctionState;
46 class HEnvironment;
47 class HGraph;
48 class HLoopInformation;
49 class HTracer;
50 class LAllocator;
51 class LChunk;
52 class LiveRange;
53 
54 
55 class HBasicBlock: public ZoneObject {
56  public:
57  explicit HBasicBlock(HGraph* graph);
58  virtual ~HBasicBlock() { }
59 
60  // Simple accessors.
61  int block_id() const { return block_id_; }
62  void set_block_id(int id) { block_id_ = id; }
63  HGraph* graph() const { return graph_; }
64  const ZoneList<HPhi*>* phis() const { return &phis_; }
65  HInstruction* first() const { return first_; }
66  HInstruction* last() const { return last_; }
67  void set_last(HInstruction* instr) { last_ = instr; }
69  HControlInstruction* end() const { return end_; }
70  HLoopInformation* loop_information() const { return loop_information_; }
71  const ZoneList<HBasicBlock*>* predecessors() const { return &predecessors_; }
72  bool HasPredecessor() const { return predecessors_.length() > 0; }
74  return &dominated_blocks_;
75  }
76  const ZoneList<int>* deleted_phis() const {
77  return &deleted_phis_;
78  }
79  void RecordDeletedPhi(int merge_index) {
80  deleted_phis_.Add(merge_index, zone());
81  }
82  HBasicBlock* dominator() const { return dominator_; }
83  HEnvironment* last_environment() const { return last_environment_; }
84  int argument_count() const { return argument_count_; }
85  void set_argument_count(int count) { argument_count_ = count; }
86  int first_instruction_index() const { return first_instruction_index_; }
87  void set_first_instruction_index(int index) {
88  first_instruction_index_ = index;
89  }
90  int last_instruction_index() const { return last_instruction_index_; }
91  void set_last_instruction_index(int index) {
92  last_instruction_index_ = index;
93  }
94 
95  void AttachLoopInformation();
96  void DetachLoopInformation();
97  bool IsLoopHeader() const { return loop_information() != NULL; }
98  bool IsStartBlock() const { return block_id() == 0; }
100 
101  bool IsFinished() const { return end_ != NULL; }
102  void AddPhi(HPhi* phi);
103  void RemovePhi(HPhi* phi);
104  void AddInstruction(HInstruction* instr);
105  bool Dominates(HBasicBlock* other) const;
106  int LoopNestingDepth() const;
107 
109  void ClearEnvironment() { last_environment_ = NULL; }
110  bool HasEnvironment() const { return last_environment_ != NULL; }
111  void UpdateEnvironment(HEnvironment* env) { last_environment_ = env; }
112  HBasicBlock* parent_loop_header() const { return parent_loop_header_; }
113 
115  ASSERT(parent_loop_header_ == NULL);
116  parent_loop_header_ = block;
117  }
118 
119  bool HasParentLoopHeader() const { return parent_loop_header_ != NULL; }
120 
121  void SetJoinId(BailoutId ast_id);
122 
124  void FinishExit(HControlInstruction* instruction);
125  void Goto(HBasicBlock* block, FunctionState* state = NULL);
126 
127  int PredecessorIndexOf(HBasicBlock* predecessor) const;
128  void AddSimulate(BailoutId ast_id) { AddInstruction(CreateSimulate(ast_id)); }
129  void AssignCommonDominator(HBasicBlock* other);
131 
133  FinishExit(CreateDeoptimize(has_uses));
134  }
135 
136  // Add the inlined function exit sequence, adding an HLeaveInlined
137  // instruction and updating the bailout environment.
138  void AddLeaveInlined(HValue* return_value, FunctionState* state);
139 
140  // If a target block is tagged as an inline function return, all
141  // predecessors should contain the inlined exit sequence:
142  //
143  // LeaveInlined
144  // Simulate (caller's environment)
145  // Goto (target block)
146  bool IsInlineReturnTarget() const { return is_inline_return_target_; }
147  void MarkAsInlineReturnTarget() { is_inline_return_target_ = true; }
148 
149  bool IsDeoptimizing() const { return is_deoptimizing_; }
150  void MarkAsDeoptimizing() { is_deoptimizing_ = true; }
151 
153  return dominates_loop_successors_;
154  }
156  dominates_loop_successors_ = true;
157  }
158 
159  inline Zone* zone() const;
160 
161 #ifdef DEBUG
162  void Verify();
163 #endif
164 
165  private:
166  void RegisterPredecessor(HBasicBlock* pred);
167  void AddDominatedBlock(HBasicBlock* block);
168 
169  HSimulate* CreateSimulate(BailoutId ast_id);
170  HDeoptimize* CreateDeoptimize(HDeoptimize::UseEnvironment has_uses);
171 
172  int block_id_;
173  HGraph* graph_;
174  ZoneList<HPhi*> phis_;
175  HInstruction* first_;
176  HInstruction* last_;
177  HControlInstruction* end_;
178  HLoopInformation* loop_information_;
179  ZoneList<HBasicBlock*> predecessors_;
180  HBasicBlock* dominator_;
181  ZoneList<HBasicBlock*> dominated_blocks_;
182  HEnvironment* last_environment_;
183  // Outgoing parameter count at block exit, set during lithium translation.
184  int argument_count_;
185  // Instruction indices into the lithium code stream.
186  int first_instruction_index_;
187  int last_instruction_index_;
188  ZoneList<int> deleted_phis_;
189  HBasicBlock* parent_loop_header_;
190  bool is_inline_return_target_;
191  bool is_deoptimizing_;
192  bool dominates_loop_successors_;
193 };
194 
195 
196 class HPredecessorIterator BASE_EMBEDDED {
197  public:
199  : predecessor_list_(block->predecessors()), current_(0) { }
200 
201  bool Done() { return current_ >= predecessor_list_->length(); }
202  HBasicBlock* Current() { return predecessor_list_->at(current_); }
203  void Advance() { current_++; }
204 
205  private:
206  const ZoneList<HBasicBlock*>* predecessor_list_;
207  int current_;
208 };
209 
210 
212  public:
214  : back_edges_(4, zone),
215  loop_header_(loop_header),
216  blocks_(8, zone),
217  stack_check_(NULL) {
218  blocks_.Add(loop_header, zone);
219  }
220  virtual ~HLoopInformation() {}
221 
222  const ZoneList<HBasicBlock*>* back_edges() const { return &back_edges_; }
223  const ZoneList<HBasicBlock*>* blocks() const { return &blocks_; }
224  HBasicBlock* loop_header() const { return loop_header_; }
225  HBasicBlock* GetLastBackEdge() const;
226  void RegisterBackEdge(HBasicBlock* block);
227 
228  HStackCheck* stack_check() const { return stack_check_; }
230  stack_check_ = stack_check;
231  }
232 
233  private:
234  void AddBlock(HBasicBlock* block);
235 
236  ZoneList<HBasicBlock*> back_edges_;
237  HBasicBlock* loop_header_;
238  ZoneList<HBasicBlock*> blocks_;
239  HStackCheck* stack_check_;
240 };
241 
242 class BoundsCheckTable;
243 class HGraph: public ZoneObject {
244  public:
245  explicit HGraph(CompilationInfo* info);
246 
247  Isolate* isolate() { return isolate_; }
248  Zone* zone() const { return zone_; }
249  CompilationInfo* info() const { return info_; }
250 
251  const ZoneList<HBasicBlock*>* blocks() const { return &blocks_; }
252  const ZoneList<HPhi*>* phi_list() const { return phi_list_; }
253  HBasicBlock* entry_block() const { return entry_block_; }
254  HEnvironment* start_environment() const { return start_environment_; }
255 
257  void InsertTypeConversions();
260  void ComputeMinusZeroChecks();
262  bool ProcessArgumentsObject();
263  void EliminateRedundantPhis();
265  void Canonicalize();
266  void OrderBlocks();
267  void AssignDominators();
268  void ReplaceCheckedValues();
271  void DeadCodeElimination();
273 
274  // Returns false if there are phi-uses of the arguments-object
275  // which are not supported by the optimizing compiler.
276  bool CheckArgumentsPhiUses();
277 
278  // Returns false if there are phi-uses of an uninitialized const
279  // which are not supported by the optimizing compiler.
280  bool CheckConstPhiUses();
281 
282  void CollectPhis();
283 
285  undefined_constant_.set(constant);
286  }
287  HConstant* GetConstantUndefined() const { return undefined_constant_.get(); }
293 
296  return arguments_object_.get();
297  }
298 
300  arguments_object_.set(object);
301  }
302 
303  int GetMaximumValueID() const { return values_.length(); }
304  int GetNextBlockID() { return next_block_id_++; }
305  int GetNextValueID(HValue* value) {
306  values_.Add(value, zone());
307  return values_.length() - 1;
308  }
309  HValue* LookupValue(int id) const {
310  if (id >= 0 && id < values_.length()) return values_[id];
311  return NULL;
312  }
313 
314  bool Optimize(SmartArrayPointer<char>* bailout_reason);
315 
316 #ifdef DEBUG
317  void Verify(bool do_full_verify) const;
318 #endif
319 
321  return osr_loop_entry_.is_set();
322  }
323 
325  return osr_loop_entry_.get();
326  }
327 
329  osr_loop_entry_.set(entry);
330  }
331 
333  return osr_values_.get();
334  }
335 
337  osr_values_.set(values);
338  }
339 
341  type_change_checksum_ += delta;
342  return type_change_checksum_;
343  }
344 
346  return use_optimistic_licm_;
347  }
348 
349  void set_use_optimistic_licm(bool value) {
350  use_optimistic_licm_ = value;
351  }
352 
353  void MarkRecursive() {
354  is_recursive_ = true;
355  }
356 
357  bool is_recursive() const {
358  return is_recursive_;
359  }
360 
362  if (uint32_instructions_ == NULL) {
363  uint32_instructions_ = new(zone()) ZoneList<HInstruction*>(4, zone());
364  }
365  uint32_instructions_->Add(instr, zone());
366  }
367 
368  private:
369  HConstant* GetConstant(SetOncePointer<HConstant>* pointer,
370  Handle<Object> value);
371  HConstant* GetConstantInt32(SetOncePointer<HConstant>* pointer,
372  int32_t integer_value);
373 
374  void MarkAsDeoptimizingRecursively(HBasicBlock* block);
375  void InsertTypeConversions(HInstruction* instr);
376  void PropagateMinusZeroChecks(HValue* value, BitVector* visited);
377  void RecursivelyMarkPhiDeoptimizeOnUndefined(HPhi* phi);
378  void InsertRepresentationChangeForUse(HValue* value,
379  HValue* use_value,
380  int use_index,
381  Representation to);
382  void InsertRepresentationChangesForValue(HValue* value);
383  void InferTypes(ZoneList<HValue*>* worklist);
384  void InitializeInferredTypes(int from_inclusive, int to_inclusive);
385  void CheckForBackEdge(HBasicBlock* block, HBasicBlock* successor);
387 
388  Isolate* isolate_;
389  int next_block_id_;
390  HBasicBlock* entry_block_;
391  HEnvironment* start_environment_;
392  ZoneList<HBasicBlock*> blocks_;
393  ZoneList<HValue*> values_;
394  ZoneList<HPhi*>* phi_list_;
395  ZoneList<HInstruction*>* uint32_instructions_;
396  SetOncePointer<HConstant> undefined_constant_;
397  SetOncePointer<HConstant> constant_1_;
398  SetOncePointer<HConstant> constant_minus1_;
399  SetOncePointer<HConstant> constant_true_;
400  SetOncePointer<HConstant> constant_false_;
401  SetOncePointer<HConstant> constant_hole_;
402  SetOncePointer<HArgumentsObject> arguments_object_;
403 
404  SetOncePointer<HBasicBlock> osr_loop_entry_;
406 
407  CompilationInfo* info_;
408  Zone* zone_;
409 
410  bool is_recursive_;
411  bool use_optimistic_licm_;
412  int type_change_checksum_;
413 
414  DISALLOW_COPY_AND_ASSIGN(HGraph);
415 };
416 
417 
418 Zone* HBasicBlock::zone() const { return graph_->zone(); }
419 
420 
421 // Type of stack frame an environment might refer to.
422 enum FrameType {
428 };
429 
430 
431 class HEnvironment: public ZoneObject {
432  public:
434  Scope* scope,
436  Zone* zone);
437 
439  return outer()->frame_type() == ARGUMENTS_ADAPTOR ? outer() : this;
440  }
441 
442  // Simple accessors.
443  Handle<JSFunction> closure() const { return closure_; }
444  const ZoneList<HValue*>* values() const { return &values_; }
446  return &assigned_variables_;
447  }
448  FrameType frame_type() const { return frame_type_; }
449  int parameter_count() const { return parameter_count_; }
450  int specials_count() const { return specials_count_; }
451  int local_count() const { return local_count_; }
452  HEnvironment* outer() const { return outer_; }
453  int pop_count() const { return pop_count_; }
454  int push_count() const { return push_count_; }
455 
456  BailoutId ast_id() const { return ast_id_; }
457  void set_ast_id(BailoutId id) { ast_id_ = id; }
458 
459  HEnterInlined* entry() const { return entry_; }
460  void set_entry(HEnterInlined* entry) { entry_ = entry; }
461 
462  int length() const { return values_.length(); }
463  bool is_special_index(int i) const {
464  return i >= parameter_count() && i < parameter_count() + specials_count();
465  }
466 
468  return parameter_count() + specials_count() + local_count();
469  }
470 
471  void Bind(Variable* variable, HValue* value) {
472  Bind(IndexFor(variable), value);
473  }
474 
475  void Bind(int index, HValue* value);
476 
477  void BindContext(HValue* value) {
478  Bind(parameter_count(), value);
479  }
480 
481  HValue* Lookup(Variable* variable) const {
482  return Lookup(IndexFor(variable));
483  }
484 
485  HValue* Lookup(int index) const {
486  HValue* result = values_[index];
487  ASSERT(result != NULL);
488  return result;
489  }
490 
492  // Return first special.
493  return Lookup(parameter_count());
494  }
495 
496  void Push(HValue* value) {
497  ASSERT(value != NULL);
498  ++push_count_;
499  values_.Add(value, zone());
500  }
501 
502  HValue* Pop() {
504  if (push_count_ > 0) {
505  --push_count_;
506  } else {
507  ++pop_count_;
508  }
509  return values_.RemoveLast();
510  }
511 
512  void Drop(int count);
513 
514  HValue* Top() const { return ExpressionStackAt(0); }
515 
516  bool ExpressionStackIsEmpty() const;
517 
518  HValue* ExpressionStackAt(int index_from_top) const {
519  int index = length() - index_from_top - 1;
520  ASSERT(HasExpressionAt(index));
521  return values_[index];
522  }
523 
524  void SetExpressionStackAt(int index_from_top, HValue* value);
525 
526  HEnvironment* Copy() const;
529 
530  // Create an "inlined version" of this environment, where the original
531  // environment is the outer environment but the top expression stack
532  // elements are moved to an inner environment as parameters.
534  int arguments,
535  FunctionLiteral* function,
536  HConstant* undefined,
537  CallKind call_kind,
538  InliningKind inlining_kind) const;
539 
540  HEnvironment* DiscardInlined(bool drop_extra) {
541  HEnvironment* outer = outer_;
542  while (outer->frame_type() != JS_FUNCTION) outer = outer->outer_;
543  if (drop_extra) outer->Drop(1);
544  return outer;
545  }
546 
547  void AddIncomingEdge(HBasicBlock* block, HEnvironment* other);
548 
549  void ClearHistory() {
550  pop_count_ = 0;
551  push_count_ = 0;
552  assigned_variables_.Rewind(0);
553  }
554 
555  void SetValueAt(int index, HValue* value) {
556  ASSERT(index < length());
557  values_[index] = value;
558  }
559 
560  void PrintTo(StringStream* stream);
561  void PrintToStd();
562 
563  Zone* zone() const { return zone_; }
564 
565  private:
566  HEnvironment(const HEnvironment* other, Zone* zone);
567 
568  HEnvironment(HEnvironment* outer,
569  Handle<JSFunction> closure,
571  int arguments,
572  Zone* zone);
573 
574  // Create an artificial stub environment (e.g. for argument adaptor or
575  // constructor stub).
576  HEnvironment* CreateStubEnvironment(HEnvironment* outer,
577  Handle<JSFunction> target,
579  int arguments) const;
580 
581  // True if index is included in the expression stack part of the environment.
582  bool HasExpressionAt(int index) const;
583 
584  void Initialize(int parameter_count, int local_count, int stack_height);
585  void Initialize(const HEnvironment* other);
586 
587  // Map a variable to an environment index. Parameter indices are shifted
588  // by 1 (receiver is parameter index -1 but environment index 0).
589  // Stack-allocated local indices are shifted by the number of parameters.
590  int IndexFor(Variable* variable) const {
591  ASSERT(variable->IsStackAllocated());
592  int shift = variable->IsParameter()
593  ? 1
594  : parameter_count_ + specials_count_;
595  return variable->index() + shift;
596  }
597 
598  Handle<JSFunction> closure_;
599  // Value array [parameters] [specials] [locals] [temporaries].
600  ZoneList<HValue*> values_;
601  ZoneList<int> assigned_variables_;
602  FrameType frame_type_;
603  int parameter_count_;
604  int specials_count_;
605  int local_count_;
606  HEnvironment* outer_;
607  HEnterInlined* entry_;
608  int pop_count_;
609  int push_count_;
610  BailoutId ast_id_;
611  Zone* zone_;
612 };
613 
614 
615 class HGraphBuilder;
616 
620 };
621 
622 // This class is not BASE_EMBEDDED because our inlining implementation uses
623 // new and delete.
624 class AstContext {
625  public:
626  bool IsEffect() const { return kind_ == Expression::kEffect; }
627  bool IsValue() const { return kind_ == Expression::kValue; }
628  bool IsTest() const { return kind_ == Expression::kTest; }
629 
630  // 'Fill' this context with a hydrogen value. The value is assumed to
631  // have already been inserted in the instruction stream (or not need to
632  // be, e.g., HPhi). Call this function in tail position in the Visit
633  // functions for expressions.
634  virtual void ReturnValue(HValue* value) = 0;
635 
636  // Add a hydrogen instruction to the instruction stream (recording an
637  // environment simulation if necessary) and then fill this context with
638  // the instruction as value.
639  virtual void ReturnInstruction(HInstruction* instr, BailoutId ast_id) = 0;
640 
641  // Finishes the current basic block and materialize a boolean for
642  // value context, nothing for effect, generate a branch for test context.
643  // Call this function in tail position in the Visit functions for
644  // expressions.
645  virtual void ReturnControl(HControlInstruction* instr, BailoutId ast_id) = 0;
646 
647  void set_for_typeof(bool for_typeof) { for_typeof_ = for_typeof; }
648  bool is_for_typeof() { return for_typeof_; }
649 
650  protected:
652  virtual ~AstContext();
653 
654  HGraphBuilder* owner() const { return owner_; }
655 
656  inline Zone* zone() const;
657 
658  // We want to be able to assert, in a context-specific way, that the stack
659  // height makes sense when the context is filled.
660 #ifdef DEBUG
661  int original_length_;
662 #endif
663 
664  private:
665  HGraphBuilder* owner_;
666  Expression::Context kind_;
667  AstContext* outer_;
668  bool for_typeof_;
669 };
670 
671 
672 class EffectContext: public AstContext {
673  public:
675  : AstContext(owner, Expression::kEffect) {
676  }
677  virtual ~EffectContext();
678 
679  virtual void ReturnValue(HValue* value);
680  virtual void ReturnInstruction(HInstruction* instr, BailoutId ast_id);
681  virtual void ReturnControl(HControlInstruction* instr, BailoutId ast_id);
682 };
683 
684 
685 class ValueContext: public AstContext {
686  public:
688  : AstContext(owner, Expression::kValue), flag_(flag) {
689  }
690  virtual ~ValueContext();
691 
692  virtual void ReturnValue(HValue* value);
693  virtual void ReturnInstruction(HInstruction* instr, BailoutId ast_id);
694  virtual void ReturnControl(HControlInstruction* instr, BailoutId ast_id);
695 
696  bool arguments_allowed() { return flag_ == ARGUMENTS_ALLOWED; }
697 
698  private:
699  ArgumentsAllowedFlag flag_;
700 };
701 
702 
703 class TestContext: public AstContext {
704  public:
710  : AstContext(owner, Expression::kTest),
711  condition_(condition),
712  oracle_(oracle),
713  if_true_(if_true),
714  if_false_(if_false) {
715  }
716 
717  virtual void ReturnValue(HValue* value);
718  virtual void ReturnInstruction(HInstruction* instr, BailoutId ast_id);
719  virtual void ReturnControl(HControlInstruction* instr, BailoutId ast_id);
720 
721  static TestContext* cast(AstContext* context) {
722  ASSERT(context->IsTest());
723  return reinterpret_cast<TestContext*>(context);
724  }
725 
726  Expression* condition() const { return condition_; }
727  TypeFeedbackOracle* oracle() const { return oracle_; }
728  HBasicBlock* if_true() const { return if_true_; }
729  HBasicBlock* if_false() const { return if_false_; }
730 
731  private:
732  // Build the shared core part of the translation unpacking a value into
733  // control flow.
734  void BuildBranch(HValue* value);
735 
736  Expression* condition_;
737  TypeFeedbackOracle* oracle_;
738  HBasicBlock* if_true_;
739  HBasicBlock* if_false_;
740 };
741 
742 
744  public:
746  CompilationInfo* info,
749  ~FunctionState();
750 
751  CompilationInfo* compilation_info() { return compilation_info_; }
752  TypeFeedbackOracle* oracle() { return oracle_; }
753  AstContext* call_context() { return call_context_; }
754  InliningKind inlining_kind() const { return inlining_kind_; }
755  HBasicBlock* function_return() { return function_return_; }
756  TestContext* test_context() { return test_context_; }
758  delete test_context_;
759  test_context_ = NULL;
760  }
761 
762  FunctionState* outer() { return outer_; }
763 
764  HEnterInlined* entry() { return entry_; }
765  void set_entry(HEnterInlined* entry) { entry_ = entry; }
766 
767  HArgumentsElements* arguments_elements() { return arguments_elements_; }
769  arguments_elements_ = arguments_elements;
770  }
771 
772  bool arguments_pushed() { return arguments_elements() != NULL; }
773 
774  private:
775  HGraphBuilder* owner_;
776 
777  CompilationInfo* compilation_info_;
778  TypeFeedbackOracle* oracle_;
779 
780  // During function inlining, expression context of the call being
781  // inlined. NULL when not inlining.
782  AstContext* call_context_;
783 
784  // The kind of call which is currently being inlined.
785  InliningKind inlining_kind_;
786 
787  // When inlining in an effect or value context, this is the return block.
788  // It is NULL otherwise. When inlining in a test context, there are a
789  // pair of return blocks in the context. When not inlining, there is no
790  // local return point.
791  HBasicBlock* function_return_;
792 
793  // When inlining a call in a test context, a context containing a pair of
794  // return blocks. NULL in all other cases.
795  TestContext* test_context_;
796 
797  // When inlining HEnterInlined instruction corresponding to the function
798  // entry.
799  HEnterInlined* entry_;
800 
801  HArgumentsElements* arguments_elements_;
802 
803  FunctionState* outer_;
804 };
805 
806 
807 class HGraphBuilder: public AstVisitor {
808  public:
811 
812  // A class encapsulating (lazily-allocated) break and continue blocks for
813  // a breakable statement. Separated from BreakAndContinueScope so that it
814  // can have a separate lifetime.
815  class BreakAndContinueInfo BASE_EMBEDDED {
816  public:
818  int drop_extra = 0)
819  : target_(target),
820  break_block_(NULL),
821  continue_block_(NULL),
822  drop_extra_(drop_extra) {
823  }
824 
825  BreakableStatement* target() { return target_; }
826  HBasicBlock* break_block() { return break_block_; }
827  void set_break_block(HBasicBlock* block) { break_block_ = block; }
828  HBasicBlock* continue_block() { return continue_block_; }
829  void set_continue_block(HBasicBlock* block) { continue_block_ = block; }
830  int drop_extra() { return drop_extra_; }
831 
832  private:
833  BreakableStatement* target_;
834  HBasicBlock* break_block_;
835  HBasicBlock* continue_block_;
836  int drop_extra_;
837  };
838 
839  // A helper class to maintain a stack of current BreakAndContinueInfo
840  // structures mirroring BreakableStatement nesting.
841  class BreakAndContinueScope BASE_EMBEDDED {
842  public:
843  BreakAndContinueScope(BreakAndContinueInfo* info, HGraphBuilder* owner)
844  : info_(info), owner_(owner), next_(owner->break_scope()) {
845  owner->set_break_scope(this);
846  }
847 
848  ~BreakAndContinueScope() { owner_->set_break_scope(next_); }
849 
850  BreakAndContinueInfo* info() { return info_; }
851  HGraphBuilder* owner() { return owner_; }
852  BreakAndContinueScope* next() { return next_; }
853 
854  // Search the break stack for a break or continue target.
855  HBasicBlock* Get(BreakableStatement* stmt, BreakType type, int* drop_extra);
856 
857  private:
858  BreakAndContinueInfo* info_;
859  HGraphBuilder* owner_;
860  BreakAndContinueScope* next_;
861  };
862 
864 
865  HGraph* CreateGraph();
866 
867  // Simple accessors.
868  HGraph* graph() const { return graph_; }
869  BreakAndContinueScope* break_scope() const { return break_scope_; }
870  void set_break_scope(BreakAndContinueScope* head) { break_scope_ = head; }
871 
872  HBasicBlock* current_block() const { return current_block_; }
873  void set_current_block(HBasicBlock* block) { current_block_ = block; }
875  return current_block()->last_environment();
876  }
877 
878  bool inline_bailout() { return inline_bailout_; }
879 
880  // Adding instructions.
882  void AddSimulate(BailoutId ast_id);
883 
884  // Bailout environment manipulation.
885  void Push(HValue* value) { environment()->Push(value); }
886  HValue* Pop() { return environment()->Pop(); }
887 
888  void Bailout(const char* reason);
889 
891  HBasicBlock* second,
892  BailoutId join_id);
893 
894  TypeFeedbackOracle* oracle() const { return function_state()->oracle(); }
895 
896  FunctionState* function_state() const { return function_state_; }
897 
898  void VisitDeclarations(ZoneList<Declaration*>* declarations);
899 
900  void* operator new(size_t size, Zone* zone) {
901  return zone->New(static_cast<int>(size));
902  }
903  void operator delete(void* pointer, Zone* zone) { }
904  void operator delete(void* pointer) { }
905 
906  private:
907  // Type of a member function that generates inline code for a native function.
908  typedef void (HGraphBuilder::*InlineFunctionGenerator)(CallRuntime* call);
909 
910  // Forward declarations for inner scope classes.
911  class SubgraphScope;
912 
913  static const InlineFunctionGenerator kInlineFunctionGenerators[];
914 
915  static const int kMaxCallPolymorphism = 4;
916  static const int kMaxLoadPolymorphism = 4;
917  static const int kMaxStorePolymorphism = 4;
918 
919  // Even in the 'unlimited' case we have to have some limit in order not to
920  // overflow the stack.
921  static const int kUnlimitedMaxInlinedSourceSize = 100000;
922  static const int kUnlimitedMaxInlinedNodes = 10000;
923  static const int kUnlimitedMaxInlinedNodesCumulative = 10000;
924 
925  // Simple accessors.
926  void set_function_state(FunctionState* state) { function_state_ = state; }
927 
928  AstContext* ast_context() const { return ast_context_; }
929  void set_ast_context(AstContext* context) { ast_context_ = context; }
930 
931  // Accessors forwarded to the function state.
932  CompilationInfo* info() const {
933  return function_state()->compilation_info();
934  }
935  AstContext* call_context() const {
936  return function_state()->call_context();
937  }
938  HBasicBlock* function_return() const {
939  return function_state()->function_return();
940  }
941  TestContext* inlined_test_context() const {
942  return function_state()->test_context();
943  }
944  void ClearInlinedTestContext() {
946  }
947  StrictModeFlag function_strict_mode_flag() {
950  }
951 
952  // Generators for inline runtime functions.
953 #define INLINE_FUNCTION_GENERATOR_DECLARATION(Name, argc, ressize) \
954  void Generate##Name(CallRuntime* call);
955 
958 #undef INLINE_FUNCTION_GENERATOR_DECLARATION
959 
960  void VisitDelete(UnaryOperation* expr);
961  void VisitVoid(UnaryOperation* expr);
962  void VisitTypeof(UnaryOperation* expr);
963  void VisitAdd(UnaryOperation* expr);
964  void VisitSub(UnaryOperation* expr);
965  void VisitBitNot(UnaryOperation* expr);
966  void VisitNot(UnaryOperation* expr);
967 
968  void VisitComma(BinaryOperation* expr);
969  void VisitLogicalExpression(BinaryOperation* expr);
970  void VisitArithmeticExpression(BinaryOperation* expr);
971 
972  bool PreProcessOsrEntry(IterationStatement* statement);
973  // True iff. we are compiling for OSR and the statement is the entry.
974  bool HasOsrEntryAt(IterationStatement* statement);
975  void VisitLoopBody(IterationStatement* stmt,
976  HBasicBlock* loop_entry,
977  BreakAndContinueInfo* break_info);
978 
979  // Create a back edge in the flow graph. body_exit is the predecessor
980  // block and loop_entry is the successor block. loop_successor is the
981  // block where control flow exits the loop normally (e.g., via failure of
982  // the condition) and break_block is the block where control flow breaks
983  // from the loop. All blocks except loop_entry can be NULL. The return
984  // value is the new successor block which is the join of loop_successor
985  // and break_block, or NULL.
986  HBasicBlock* CreateLoop(IterationStatement* statement,
987  HBasicBlock* loop_entry,
988  HBasicBlock* body_exit,
989  HBasicBlock* loop_successor,
990  HBasicBlock* break_block);
991 
992  HBasicBlock* JoinContinue(IterationStatement* statement,
993  HBasicBlock* exit_block,
994  HBasicBlock* continue_block);
995 
996  HValue* Top() const { return environment()->Top(); }
997  void Drop(int n) { environment()->Drop(n); }
998  void Bind(Variable* var, HValue* value) { environment()->Bind(var, value); }
999 
1000  // The value of the arguments object is allowed in some but not most value
1001  // contexts. (It's allowed in all effect contexts and disallowed in all
1002  // test contexts.)
1003  void VisitForValue(Expression* expr,
1005  void VisitForTypeOf(Expression* expr);
1006  void VisitForEffect(Expression* expr);
1007  void VisitForControl(Expression* expr,
1008  HBasicBlock* true_block,
1009  HBasicBlock* false_block);
1010 
1011  // Visit an argument subexpression and emit a push to the outgoing arguments.
1012  void VisitArgument(Expression* expr);
1013 
1014  void VisitArgumentList(ZoneList<Expression*>* arguments);
1015 
1016  // Visit a list of expressions from left to right, each in a value context.
1017  void VisitExpressions(ZoneList<Expression*>* exprs);
1018 
1019  void AddPhi(HPhi* phi);
1020 
1021  void PushAndAdd(HInstruction* instr);
1022 
1023  // Remove the arguments from the bailout environment and emit instructions
1024  // to push them as outgoing parameters.
1025  template <class Instruction> HInstruction* PreProcessCall(Instruction* call);
1026 
1027  void TraceRepresentation(Token::Value op,
1028  TypeInfo info,
1029  HValue* value,
1030  Representation rep);
1031  static Representation ToRepresentation(TypeInfo info);
1032 
1033  void SetUpScope(Scope* scope);
1034  virtual void VisitStatements(ZoneList<Statement*>* statements);
1035 
1036 #define DECLARE_VISIT(type) virtual void Visit##type(type* node);
1038 #undef DECLARE_VISIT
1039 
1040  HBasicBlock* CreateBasicBlock(HEnvironment* env);
1041  HBasicBlock* CreateLoopHeaderBlock();
1042 
1043  // Helpers for flow graph construction.
1044  enum GlobalPropertyAccess {
1045  kUseCell,
1046  kUseGeneric
1047  };
1048  GlobalPropertyAccess LookupGlobalProperty(Variable* var,
1049  LookupResult* lookup,
1050  bool is_store);
1051 
1052  void EnsureArgumentsArePushedForAccess();
1053  bool TryArgumentsAccess(Property* expr);
1054 
1055  // Try to optimize fun.apply(receiver, arguments) pattern.
1056  bool TryCallApply(Call* expr);
1057 
1058  int InliningAstSize(Handle<JSFunction> target);
1059  bool TryInline(CallKind call_kind,
1060  Handle<JSFunction> target,
1061  int arguments_count,
1062  HValue* implicit_return_value,
1063  BailoutId ast_id,
1064  BailoutId return_id,
1065  InliningKind inlining_kind);
1066 
1067  bool TryInlineCall(Call* expr, bool drop_extra = false);
1068  bool TryInlineConstruct(CallNew* expr, HValue* implicit_return_value);
1069  bool TryInlineGetter(Handle<JSFunction> getter, Property* prop);
1070  bool TryInlineSetter(Handle<JSFunction> setter,
1071  Assignment* assignment,
1072  HValue* implicit_return_value);
1073  bool TryInlineBuiltinMethodCall(Call* expr,
1074  HValue* receiver,
1075  Handle<Map> receiver_map,
1076  CheckType check_type);
1077  bool TryInlineBuiltinFunctionCall(Call* expr, bool drop_extra);
1078 
1079  // If --trace-inlining, print a line of the inlining trace. Inlining
1080  // succeeded if the reason string is NULL and failed if there is a
1081  // non-NULL reason string.
1082  void TraceInline(Handle<JSFunction> target,
1083  Handle<JSFunction> caller,
1084  const char* failure_reason);
1085 
1086  void HandleGlobalVariableAssignment(Variable* var,
1087  HValue* value,
1088  int position,
1089  BailoutId ast_id);
1090 
1091  void HandlePropertyAssignment(Assignment* expr);
1092  void HandleCompoundAssignment(Assignment* expr);
1093  void HandlePolymorphicLoadNamedField(Property* expr,
1094  HValue* object,
1095  SmallMapList* types,
1096  Handle<String> name);
1097  void HandlePolymorphicStoreNamedField(Assignment* expr,
1098  HValue* object,
1099  HValue* value,
1100  SmallMapList* types,
1101  Handle<String> name);
1102  void HandlePolymorphicCallNamed(Call* expr,
1103  HValue* receiver,
1104  SmallMapList* types,
1105  Handle<String> name);
1106  void HandleLiteralCompareTypeof(CompareOperation* expr,
1107  HTypeof* typeof_expr,
1108  Handle<String> check);
1109  void HandleLiteralCompareNil(CompareOperation* expr,
1110  HValue* value,
1111  NilValue nil);
1112 
1113  HStringCharCodeAt* BuildStringCharCodeAt(HValue* context,
1114  HValue* string,
1115  HValue* index);
1116  HInstruction* BuildBinaryOperation(BinaryOperation* expr,
1117  HValue* left,
1118  HValue* right);
1119  HInstruction* BuildIncrement(bool returns_original_input,
1120  CountOperation* expr);
1121  HInstruction* BuildFastElementAccess(HValue* elements,
1122  HValue* checked_key,
1123  HValue* val,
1124  HValue* dependency,
1125  ElementsKind elements_kind,
1126  bool is_store);
1127 
1128  HInstruction* TryBuildConsolidatedElementLoad(HValue* object,
1129  HValue* key,
1130  HValue* val,
1131  SmallMapList* maps);
1132 
1133  HInstruction* BuildUncheckedMonomorphicElementAccess(HValue* object,
1134  HValue* key,
1135  HValue* val,
1136  HCheckMaps* mapcheck,
1137  Handle<Map> map,
1138  bool is_store);
1139 
1140  HInstruction* BuildMonomorphicElementAccess(HValue* object,
1141  HValue* key,
1142  HValue* val,
1143  HValue* dependency,
1144  Handle<Map> map,
1145  bool is_store);
1146 
1147  HValue* HandlePolymorphicElementAccess(HValue* object,
1148  HValue* key,
1149  HValue* val,
1150  Expression* prop,
1151  BailoutId ast_id,
1152  int position,
1153  bool is_store,
1154  bool* has_side_effects);
1155 
1156  HValue* HandleKeyedElementAccess(HValue* obj,
1157  HValue* key,
1158  HValue* val,
1159  Expression* expr,
1160  BailoutId ast_id,
1161  int position,
1162  bool is_store,
1163  bool* has_side_effects);
1164 
1165  HLoadNamedField* BuildLoadNamedField(HValue* object,
1166  Handle<Map> map,
1167  LookupResult* result,
1168  bool smi_and_map_check);
1169  HInstruction* BuildLoadNamedGeneric(HValue* object,
1170  Handle<String> name,
1171  Property* expr);
1172  HInstruction* BuildCallGetter(HValue* object,
1173  Handle<Map> map,
1174  Handle<JSFunction> getter,
1175  Handle<JSObject> holder);
1176  HInstruction* BuildLoadNamedMonomorphic(HValue* object,
1177  Handle<String> name,
1178  Property* expr,
1179  Handle<Map> map);
1180  HInstruction* BuildLoadKeyedGeneric(HValue* object, HValue* key);
1181  HInstruction* BuildExternalArrayElementAccess(
1182  HValue* external_elements,
1183  HValue* checked_key,
1184  HValue* val,
1185  HValue* dependency,
1186  ElementsKind elements_kind,
1187  bool is_store);
1188 
1189  HInstruction* BuildStoreNamedField(HValue* object,
1190  Handle<String> name,
1191  HValue* value,
1192  Handle<Map> map,
1193  LookupResult* lookup,
1194  bool smi_and_map_check);
1195  HInstruction* BuildStoreNamedGeneric(HValue* object,
1196  Handle<String> name,
1197  HValue* value);
1198  HInstruction* BuildCallSetter(HValue* object,
1199  HValue* value,
1200  Handle<Map> map,
1201  Handle<JSFunction> setter,
1202  Handle<JSObject> holder);
1203  HInstruction* BuildStoreNamedMonomorphic(HValue* object,
1204  Handle<String> name,
1205  HValue* value,
1206  Handle<Map> map);
1207  HInstruction* BuildStoreKeyedGeneric(HValue* object,
1208  HValue* key,
1209  HValue* value);
1210 
1211  HValue* BuildContextChainWalk(Variable* var);
1212 
1213  HInstruction* BuildThisFunction();
1214 
1215  void AddCheckConstantFunction(Handle<JSObject> holder,
1216  HValue* receiver,
1217  Handle<Map> receiver_map,
1218  bool smi_and_map_check);
1219 
1220  Zone* zone() const { return zone_; }
1221 
1222  // The translation state of the currently-being-translated function.
1223  FunctionState* function_state_;
1224 
1225  // The base of the function state stack.
1226  FunctionState initial_function_state_;
1227 
1228  // Expression context of the currently visited subexpression. NULL when
1229  // visiting statements.
1230  AstContext* ast_context_;
1231 
1232  // A stack of breakable statements entered.
1233  BreakAndContinueScope* break_scope_;
1234 
1235  HGraph* graph_;
1236  HBasicBlock* current_block_;
1237 
1238  int inlined_count_;
1239  ZoneList<Handle<Object> > globals_;
1240 
1241  Zone* zone_;
1242 
1243  bool inline_bailout_;
1244 
1245  friend class FunctionState; // Pushes and pops the state stack.
1246  friend class AstContext; // Pushes and pops the AST context stack.
1247 
1249 };
1250 
1251 
1252 Zone* AstContext::zone() const { return owner_->zone(); }
1253 
1254 
1255 class HValueMap: public ZoneObject {
1256  public:
1257  explicit HValueMap(Zone* zone)
1258  : array_size_(0),
1259  lists_size_(0),
1260  count_(0),
1261  present_flags_(0),
1262  array_(NULL),
1263  lists_(NULL),
1264  free_list_head_(kNil) {
1265  ResizeLists(kInitialSize, zone);
1266  Resize(kInitialSize, zone);
1267  }
1268 
1269  void Kill(GVNFlagSet flags);
1270 
1271  void Add(HValue* value, Zone* zone) {
1272  present_flags_.Add(value->gvn_flags());
1273  Insert(value, zone);
1274  }
1275 
1276  HValue* Lookup(HValue* value) const;
1277 
1278  HValueMap* Copy(Zone* zone) const {
1279  return new(zone) HValueMap(zone, this);
1280  }
1281 
1282  bool IsEmpty() const { return count_ == 0; }
1283 
1284  private:
1285  // A linked list of HValue* values. Stored in arrays.
1286  struct HValueMapListElement {
1287  HValue* value;
1288  int next; // Index in the array of the next list element.
1289  };
1290  static const int kNil = -1; // The end of a linked list
1291 
1292  // Must be a power of 2.
1293  static const int kInitialSize = 16;
1294 
1295  HValueMap(Zone* zone, const HValueMap* other);
1296 
1297  void Resize(int new_size, Zone* zone);
1298  void ResizeLists(int new_size, Zone* zone);
1299  void Insert(HValue* value, Zone* zone);
1300  uint32_t Bound(uint32_t value) const { return value & (array_size_ - 1); }
1301 
1302  int array_size_;
1303  int lists_size_;
1304  int count_; // The number of values stored in the HValueMap.
1305  GVNFlagSet present_flags_; // All flags that are in any value in the
1306  // HValueMap.
1307  HValueMapListElement* array_; // Primary store - contains the first value
1308  // with a given hash. Colliding elements are stored in linked lists.
1309  HValueMapListElement* lists_; // The linked lists containing hash collisions.
1310  int free_list_head_; // Unused elements in lists_ are on the free list.
1311 };
1312 
1313 
1314 class HSideEffectMap BASE_EMBEDDED {
1315  public:
1316  HSideEffectMap();
1317  explicit HSideEffectMap(HSideEffectMap* other);
1318  HSideEffectMap& operator= (const HSideEffectMap& other);
1319 
1320  void Kill(GVNFlagSet flags);
1321 
1322  void Store(GVNFlagSet flags, HInstruction* instr);
1323 
1324  bool IsEmpty() const { return count_ == 0; }
1325 
1326  inline HInstruction* operator[](int i) const {
1327  ASSERT(0 <= i);
1329  return data_[i];
1330  }
1331  inline HInstruction* at(int i) const { return operator[](i); }
1332 
1333  private:
1334  int count_;
1336 };
1337 
1338 
1339 class HStatistics: public Malloced {
1340  public:
1341  void Initialize(CompilationInfo* info);
1342  void Print();
1343  void SaveTiming(const char* name, int64_t ticks, unsigned size);
1344  static HStatistics* Instance() {
1345  static SetOncePointer<HStatistics> instance;
1346  if (!instance.is_set()) {
1347  instance.set(new HStatistics());
1348  }
1349  return instance.get();
1350  }
1351 
1352  private:
1353  HStatistics()
1354  : timing_(5),
1355  names_(5),
1356  sizes_(5),
1357  total_(0),
1358  total_size_(0),
1359  full_code_gen_(0),
1360  source_size_(0) { }
1361 
1362  List<int64_t> timing_;
1363  List<const char*> names_;
1364  List<unsigned> sizes_;
1365  int64_t total_;
1366  unsigned total_size_;
1367  int64_t full_code_gen_;
1368  double source_size_;
1369 };
1370 
1371 
1372 class HPhase BASE_EMBEDDED {
1373  public:
1374  static const char* const kFullCodeGen;
1375  static const char* const kTotal;
1376 
1377  explicit HPhase(const char* name) { Begin(name, NULL, NULL, NULL); }
1378  HPhase(const char* name, HGraph* graph) {
1379  Begin(name, graph, NULL, NULL);
1380  }
1381  HPhase(const char* name, LChunk* chunk) {
1382  Begin(name, NULL, chunk, NULL);
1383  }
1384  HPhase(const char* name, LAllocator* allocator) {
1385  Begin(name, NULL, NULL, allocator);
1386  }
1387 
1389  End();
1390  }
1391 
1392  private:
1393  void Begin(const char* name,
1394  HGraph* graph,
1395  LChunk* chunk,
1396  LAllocator* allocator);
1397  void End() const;
1398 
1399  int64_t start_;
1400  const char* name_;
1401  HGraph* graph_;
1402  LChunk* chunk_;
1403  LAllocator* allocator_;
1404  unsigned start_allocation_size_;
1405 };
1406 
1407 
1408 class HTracer: public Malloced {
1409  public:
1410  void TraceCompilation(FunctionLiteral* function);
1411  void TraceHydrogen(const char* name, HGraph* graph);
1412  void TraceLithium(const char* name, LChunk* chunk);
1413  void TraceLiveRanges(const char* name, LAllocator* allocator);
1414 
1415  static HTracer* Instance() {
1416  static SetOncePointer<HTracer> instance;
1417  if (!instance.is_set()) {
1418  instance.set(new HTracer("hydrogen.cfg"));
1419  }
1420  return instance.get();
1421  }
1422 
1423  private:
1424  class Tag BASE_EMBEDDED {
1425  public:
1426  Tag(HTracer* tracer, const char* name) {
1427  name_ = name;
1428  tracer_ = tracer;
1429  tracer->PrintIndent();
1430  tracer->trace_.Add("begin_%s\n", name);
1431  tracer->indent_++;
1432  }
1433 
1434  ~Tag() {
1435  tracer_->indent_--;
1436  tracer_->PrintIndent();
1437  tracer_->trace_.Add("end_%s\n", name_);
1438  ASSERT(tracer_->indent_ >= 0);
1439  tracer_->FlushToFile();
1440  }
1441 
1442  private:
1443  HTracer* tracer_;
1444  const char* name_;
1445  };
1446 
1447  explicit HTracer(const char* filename)
1448  : filename_(filename), trace_(&string_allocator_), indent_(0) {
1449  WriteChars(filename, "", 0, false);
1450  }
1451 
1452  void TraceLiveRange(LiveRange* range, const char* type, Zone* zone);
1453  void Trace(const char* name, HGraph* graph, LChunk* chunk);
1454  void FlushToFile();
1455 
1456  void PrintEmptyProperty(const char* name) {
1457  PrintIndent();
1458  trace_.Add("%s\n", name);
1459  }
1460 
1461  void PrintStringProperty(const char* name, const char* value) {
1462  PrintIndent();
1463  trace_.Add("%s \"%s\"\n", name, value);
1464  }
1465 
1466  void PrintLongProperty(const char* name, int64_t value) {
1467  PrintIndent();
1468  trace_.Add("%s %d000\n", name, static_cast<int>(value / 1000));
1469  }
1470 
1471  void PrintBlockProperty(const char* name, int block_id) {
1472  PrintIndent();
1473  trace_.Add("%s \"B%d\"\n", name, block_id);
1474  }
1475 
1476  void PrintIntProperty(const char* name, int value) {
1477  PrintIndent();
1478  trace_.Add("%s %d\n", name, value);
1479  }
1480 
1481  void PrintIndent() {
1482  for (int i = 0; i < indent_; i++) {
1483  trace_.Add(" ");
1484  }
1485  }
1486 
1487  const char* filename_;
1488  HeapStringAllocator string_allocator_;
1489  StringStream trace_;
1490  int indent_;
1491 };
1492 
1493 
1494 } } // namespace v8::internal
1495 
1496 #endif // V8_HYDROGEN_H_
HValue * LookupValue(int id) const
Definition: hydrogen.h:309
Isolate * isolate()
Definition: hydrogen.h:247
void SetInitialEnvironment(HEnvironment *env)
Definition: hydrogen.cc:199
#define INLINE_FUNCTION_LIST(F)
Definition: runtime.h:503
bool IsTest() const
Definition: hydrogen.h:628
void set_break_scope(BreakAndContinueScope *head)
Definition: hydrogen.h:870
ArgumentsAllowedFlag
Definition: hydrogen.h:617
HPhase(const char *name, HGraph *graph)
Definition: hydrogen.h:1378
bool IsFinished() const
Definition: hydrogen.h:101
bool IsDeoptimizing() const
Definition: hydrogen.h:149
HBasicBlock * if_true() const
Definition: hydrogen.h:728
GVNFlagSet gvn_flags() const
HStackCheck * stack_check() const
Definition: hydrogen.h:228
virtual void ReturnInstruction(HInstruction *instr, BailoutId ast_id)
Definition: hydrogen.cc:3088
void DeadCodeElimination()
Definition: hydrogen.cc:3791
const ZoneList< int > * deleted_phis() const
Definition: hydrogen.h:76
void set_entry(HEnterInlined *entry)
Definition: hydrogen.h:765
virtual void ReturnControl(HControlInstruction *instr, BailoutId ast_id)
Definition: hydrogen.cc:3044
HValueMap * Copy(Zone *zone) const
Definition: hydrogen.h:1278
void set_for_typeof(bool for_typeof)
Definition: hydrogen.h:647
HBasicBlock * loop_header() const
Definition: hydrogen.h:224
EffectContext(HGraphBuilder *owner)
Definition: hydrogen.h:674
virtual void ReturnControl(HControlInstruction *instr, BailoutId ast_id)
Definition: hydrogen.cc:3103
int push_count() const
Definition: hydrogen.h:454
void set_block_id(int id)
Definition: hydrogen.h:62
#define DECLARE_VISIT(type)
Definition: hydrogen.h:1036
bool IsEffect() const
Definition: hydrogen.h:626
HBasicBlock * Current()
Definition: hydrogen.h:202
HEnvironment * CopyForInlining(Handle< JSFunction > target, int arguments, FunctionLiteral *function, HConstant *undefined, CallKind call_kind, InliningKind inlining_kind) const
Definition: hydrogen.cc:9573
HValue * LookupContext() const
Definition: hydrogen.h:491
HPhase(const char *name, LAllocator *allocator)
Definition: hydrogen.h:1384
int current_
InliningKind inlining_kind() const
Definition: hydrogen.h:754
bool Dominates(HBasicBlock *other) const
Definition: hydrogen.cc:222
void Kill(GVNFlagSet flags)
Definition: hydrogen.cc:1431
const ZoneList< int > * assigned_variables() const
Definition: hydrogen.h:445
void set_use_optimistic_licm(bool value)
Definition: hydrogen.h:349
HConstant * GetConstant1()
Definition: hydrogen.cc:594
FunctionState(HGraphBuilder *owner, CompilationInfo *info, TypeFeedbackOracle *oracle, InliningKind inlining_kind)
Definition: hydrogen.cc:2934
Expression * condition() const
Definition: hydrogen.h:726
void SetArgumentsObject(HArgumentsObject *object)
Definition: hydrogen.h:299
void Push(HValue *value)
Definition: hydrogen.h:885
void set_break_block(HBasicBlock *block)
Definition: hydrogen.h:827
void set_entry(HEnterInlined *entry)
Definition: hydrogen.h:460
virtual void ReturnInstruction(HInstruction *instr, BailoutId ast_id)=0
void Finish(HControlInstruction *last)
Definition: hydrogen.cc:158
HInstruction * first() const
Definition: hydrogen.h:65
HValueMap(Zone *zone)
Definition: hydrogen.h:1257
HGraph * graph() const
Definition: hydrogen.h:63
int int32_t
Definition: unicode.cc:47
HEnvironment * arguments_environment()
Definition: hydrogen.h:438
virtual void ReturnInstruction(HInstruction *instr, BailoutId ast_id)
Definition: hydrogen.cc:3037
HValue * Lookup(Variable *variable) const
Definition: hydrogen.h:481
void MarkAsLoopSuccessorDominator()
Definition: hydrogen.h:155
void Bind(Variable *variable, HValue *value)
Definition: hydrogen.h:471
virtual void ReturnValue(HValue *value)
Definition: hydrogen.cc:3032
HGraphBuilder * owner() const
Definition: hydrogen.h:654
void FinishExitWithDeoptimization(HDeoptimize::UseEnvironment has_uses)
Definition: hydrogen.h:132
HBasicBlock * dominator() const
Definition: hydrogen.h:82
void SetExpressionStackAt(int index_from_top, HValue *value)
Definition: hydrogen.cc:9511
virtual void ReturnControl(HControlInstruction *instr, BailoutId ast_id)=0
bool IsStackAllocated() const
Definition: variables.h:118
FrameType frame_type() const
Definition: hydrogen.h:448
bool CheckArgumentsPhiUses()
Definition: hydrogen.cc:1155
Zone * zone() const
Definition: hydrogen.h:563
int PredecessorIndexOf(HBasicBlock *predecessor) const
Definition: hydrogen.cc:381
#define ASSERT(condition)
Definition: checks.h:270
bool is_recursive() const
Definition: hydrogen.h:357
void SaveTiming(const char *name, int64_t ticks, unsigned size)
Definition: hydrogen.cc:9917
void InsertRepresentationChanges()
Definition: hydrogen.cc:2608
HBasicBlock * current_block() const
Definition: hydrogen.h:872
HConstant * GetConstantTrue()
Definition: hydrogen.cc:604
FunctionState * outer()
Definition: hydrogen.h:762
HLoopInformation(HBasicBlock *loop_header, Zone *zone)
Definition: hydrogen.h:213
const ZoneList< HBasicBlock * > * predecessors() const
Definition: hydrogen.h:71
BreakAndContinueInfo(BreakableStatement *target, int drop_extra=0)
Definition: hydrogen.h:817
HEnvironment * Copy() const
Definition: hydrogen.cc:9533
HPredecessorIterator(HBasicBlock *block)
Definition: hydrogen.h:198
void RegisterBackEdge(HBasicBlock *block)
Definition: hydrogen.cc:406
HEnterInlined * entry() const
Definition: hydrogen.h:459
HControlInstruction * end() const
Definition: hydrogen.h:69
static const char *const kFullCodeGen
Definition: hydrogen.h:1374
bool HasPredecessor() const
Definition: hydrogen.h:72
HValue * Top() const
Definition: hydrogen.h:514
HEnvironment * CopyAsLoopHeader(HBasicBlock *block) const
Definition: hydrogen.cc:9545
virtual void ReturnValue(HValue *value)
Definition: hydrogen.cc:3017
FunctionState * function_state() const
Definition: hydrogen.h:896
bool has_osr_loop_entry()
Definition: hydrogen.h:320
int GetMaximumValueID() const
Definition: hydrogen.h:303
int parameter_count() const
Definition: hydrogen.h:449
ZoneList< HUnknownOSRValue * > * osr_values()
Definition: hydrogen.h:332
void set(T *value)
Definition: utils.h:472
static HStatistics * Instance()
Definition: hydrogen.h:1344
TypeFeedbackOracle * oracle() const
Definition: hydrogen.h:894
void AssignCommonDominator(HBasicBlock *other)
Definition: hydrogen.cc:298
HEnvironment * environment() const
Definition: hydrogen.h:874
HEnvironment * last_environment() const
Definition: hydrogen.h:83
void DehoistSimpleArrayIndexComputations()
Definition: hydrogen.cc:3751
const ZoneList< HValue * > * values() const
Definition: hydrogen.h:444
int last_instruction_index() const
Definition: hydrogen.h:90
void TraceLithium(const char *name, LChunk *chunk)
Definition: hydrogen.cc:9672
AstContext(HGraphBuilder *owner, Expression::Context kind)
Definition: hydrogen.cc:2983
void Add(Vector< const char > format, Vector< FmtElm > elms)
HConstant * GetConstantFalse()
Definition: hydrogen.cc:609
void Initialize(CompilationInfo *info)
Definition: hydrogen.cc:9878
BreakAndContinueScope(BreakAndContinueInfo *info, HGraphBuilder *owner)
Definition: hydrogen.h:843
void RemovePhi(HPhi *phi)
Definition: hydrogen.cc:96
void VisitDeclarations(ZoneList< Declaration * > *declarations)
Definition: hydrogen.cc:8760
HEnvironment * outer() const
Definition: hydrogen.h:452
bool ExpressionStackIsEmpty() const
Definition: hydrogen.cc:9505
void set_stack_check(HStackCheck *stack_check)
Definition: hydrogen.h:229
TestContext(HGraphBuilder *owner, Expression *condition, TypeFeedbackOracle *oracle, HBasicBlock *if_true, HBasicBlock *if_false)
Definition: hydrogen.h:705
void set_osr_loop_entry(HBasicBlock *entry)
Definition: hydrogen.h:328
Zone * zone() const
Definition: hydrogen.h:248
void set_arguments_elements(HArgumentsElements *arguments_elements)
Definition: hydrogen.h:768
HBasicBlock * GetLastBackEdge() const
Definition: hydrogen.cc:412
const ZoneList< HBasicBlock * > * dominated_blocks() const
Definition: hydrogen.h:73
EnumSet< GVNFlag > GVNFlagSet
int first_expression_index() const
Definition: hydrogen.h:467
HConstant * GetConstantUndefined() const
Definition: hydrogen.h:287
void AddIncomingEdge(HBasicBlock *block, HEnvironment *other)
Definition: hydrogen.cc:9461
HBasicBlock(HGraph *graph)
Definition: hydrogen.cc:55
HInstruction * operator[](int i) const
Definition: hydrogen.h:1326
NilValue
Definition: v8.h:141
HInstruction * GetLastInstruction()
void PostProcessLoopHeader(IterationStatement *stmt)
Definition: hydrogen.cc:243
bool HasEnvironment() const
Definition: hydrogen.h:110
void set_current_block(HBasicBlock *block)
Definition: hydrogen.h:873
bool use_optimistic_licm()
Definition: hydrogen.h:345
TypeFeedbackOracle * oracle()
Definition: hydrogen.h:752
void UpdateEnvironment(HEnvironment *env)
Definition: hydrogen.h:111
BreakAndContinueScope * break_scope() const
Definition: hydrogen.h:869
HInstruction * at(int i) const
Definition: hydrogen.h:1331
bool HasParentLoopHeader() const
Definition: hydrogen.h:119
HArgumentsElements * arguments_elements()
Definition: hydrogen.h:767
void EliminateUnreachablePhis()
Definition: hydrogen.cc:1111
void set_undefined_constant(HConstant *constant)
Definition: hydrogen.h:284
void RecordUint32Instruction(HInstruction *instr)
Definition: hydrogen.h:361
static HTracer * Instance()
Definition: hydrogen.h:1415
CompilationInfo * info() const
Definition: hydrogen.h:249
HValue * ExpressionStackAt(int index_from_top) const
Definition: hydrogen.h:518
HEnvironment(HEnvironment *outer, Scope *scope, Handle< JSFunction > closure, Zone *zone)
Definition: hydrogen.cc:9375
#define DISALLOW_COPY_AND_ASSIGN(TypeName)
Definition: globals.h:307
static TestContext * cast(AstContext *context)
Definition: hydrogen.h:721
int pop_count() const
Definition: hydrogen.h:453
int index() const
Definition: variables.h:147
#define INLINE_FUNCTION_GENERATOR_DECLARATION(Name, argc, ressize)
Definition: hydrogen.h:953
void PropagateDeoptimizingMark()
Definition: hydrogen.cc:1064
HValue * Lookup(int index) const
Definition: hydrogen.h:485
int local_count() const
Definition: hydrogen.h:451
HBasicBlock * osr_loop_entry()
Definition: hydrogen.h:324
virtual void ReturnInstruction(HInstruction *instr, BailoutId ast_id)
Definition: hydrogen.cc:3057
HConstant * GetConstantMinus1()
Definition: hydrogen.cc:599
Definition: v8.h:105
const ZoneList< HBasicBlock * > * back_edges() const
Definition: hydrogen.h:222
HInstruction * last() const
Definition: hydrogen.h:66
#define BASE_EMBEDDED
Definition: allocation.h:68
void MarkDeoptimizeOnUndefined()
Definition: hydrogen.cc:2664
virtual void ReturnControl(HControlInstruction *instr, BailoutId ast_id)
Definition: hydrogen.cc:3068
void ComputeMinusZeroChecks()
Definition: hydrogen.cc:2908
void AddSimulate(BailoutId ast_id)
Definition: hydrogen.h:128
ValueContext(HGraphBuilder *owner, ArgumentsAllowedFlag flag)
Definition: hydrogen.h:687
void RecordDeletedPhi(int merge_index)
Definition: hydrogen.h:79
BreakAndContinueScope * next()
Definition: hydrogen.h:852
AstContext * call_context()
Definition: hydrogen.h:753
#define AST_NODE_LIST(V)
Definition: ast.h:115
void Drop(int count)
Definition: hydrogen.cc:9526
void SetJoinId(BailoutId ast_id)
Definition: hydrogen.cc:206
void set_last(HInstruction *instr)
Definition: hydrogen.h:67
HBasicBlock * CreateBasicBlock()
Definition: hydrogen.cc:709
bool IsInlineReturnTarget() const
Definition: hydrogen.h:146
bool is_classic_mode() const
Definition: compiler.h:60
void BindContext(HValue *value)
Definition: hydrogen.h:477
int specials_count() const
Definition: hydrogen.h:450
void SetValueAt(int index, HValue *value)
Definition: hydrogen.h:555
int WriteChars(const char *filename, const char *str, int size, bool verbose)
Definition: v8utils.cc:231
HArgumentsObject * GetArgumentsObject() const
Definition: hydrogen.h:295
const ZoneList< HBasicBlock * > * blocks() const
Definition: hydrogen.h:251
static const char *const kTotal
Definition: hydrogen.h:1375
int first_instruction_index() const
Definition: hydrogen.h:86
void set_last_instruction_index(int index)
Definition: hydrogen.h:91
int LoopNestingDepth() const
Definition: hydrogen.cc:232
const ZoneList< HPhi * > * phi_list() const
Definition: hydrogen.h:252
void set_argument_count(int count)
Definition: hydrogen.h:85
HBasicBlock * parent_loop_header() const
Definition: hydrogen.h:112
bool IsLoopSuccessorDominator() const
Definition: hydrogen.h:152
void InitializeInferredTypes()
Definition: hydrogen.cc:2466
HEnvironment * DiscardInlined(bool drop_extra)
Definition: hydrogen.h:540
void AddSimulate(BailoutId ast_id)
Definition: hydrogen.cc:3828
HEnterInlined * entry()
Definition: hydrogen.h:764
bool IsParameter() const
Definition: variables.h:116
void FinishExit(HControlInstruction *instruction)
Definition: hydrogen.cc:682
bool is_special_index(int i) const
Definition: hydrogen.h:463
HPhase(const char *name)
Definition: hydrogen.h:1377
bool IsEmpty() const
Definition: hydrogen.h:1282
void Add(HValue *value, Zone *zone)
Definition: hydrogen.h:1271
HGraph(CompilationInfo *info)
Definition: hydrogen.cc:688
void Goto(HBasicBlock *block, FunctionState *state=NULL)
Definition: hydrogen.cc:168
HGraphBuilder(CompilationInfo *info, TypeFeedbackOracle *oracle)
Definition: hydrogen.cc:619
void EliminateRedundantPhis()
Definition: hydrogen.cc:1077
HLoopInformation * loop_information() const
Definition: hydrogen.h:70
bool IsStartBlock() const
Definition: hydrogen.h:98
bool IsLoopHeader() const
Definition: hydrogen.h:97
virtual void ReturnValue(HValue *value)
Definition: hydrogen.cc:3022
void PrintTo(StringStream *stream)
Definition: hydrogen.cc:9634
void set_continue_block(HBasicBlock *block)
Definition: hydrogen.h:829
void set_parent_loop_header(HBasicBlock *block)
Definition: hydrogen.h:114
HBasicBlock * CreateJoin(HBasicBlock *first, HBasicBlock *second, BailoutId join_id)
Definition: hydrogen.cc:637
HConstant * GetConstantHole()
Definition: hydrogen.cc:614
void AddPhi(HPhi *phi)
Definition: hydrogen.cc:89
CompilationInfo * compilation_info()
Definition: hydrogen.h:751
int update_type_change_checksum(int delta)
Definition: hydrogen.h:340
Zone * zone() const
Definition: hydrogen.h:1252
void ComputeSafeUint32Operations()
Definition: hydrogen.cc:2887
void Add(const T &element, AllocationPolicy allocator=AllocationPolicy())
Definition: list-inl.h:38
void set_ast_id(BailoutId id)
Definition: hydrogen.h:457
HBasicBlock * if_false() const
Definition: hydrogen.h:729
activate correct semantics for inheriting readonliness enable harmony semantics for typeof enable harmony enable harmony proxies enable all harmony harmony_scoping harmony_proxies harmony_scoping tracks arrays with only smi values automatically unbox arrays of doubles use crankshaft use hydrogen range analysis use hydrogen global value numbering use function inlining maximum number of AST nodes considered for a single inlining loop invariant code motion print statistics for hydrogen trace generated IR for specified phases trace register allocator trace range analysis trace representation types environment for every instruction put a break point before deoptimizing polymorphic inlining perform array bounds checks elimination use dead code elimination trace on stack replacement optimize closures cache optimized code for closures functions with arguments object loop weight for representation inference allow uint32 values on optimize frames if they are used only in safe operations track parallel recompilation enable all profiler experiments number of stack frames inspected by the profiler call recompile stub directly when self optimizing trigger profiler ticks based on counting instead of timing weight back edges by jump distance for interrupt triggering percentage of ICs that must have type info to allow optimization watch_ic_patching retry_self_opt interrupt_at_exit 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 SAHF instruction if enable use of VFP3 instructions if available this implies enabling ARMv7 and VFP2 enable use of VFP2 instructions if available 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 MIPS FPU instructions if NULL
Definition: flags.cc:301
int GetNextValueID(HValue *value)
Definition: hydrogen.h:305
void EliminateRedundantBoundsChecks()
Definition: hydrogen.cc:3696
void TraceHydrogen(const char *name, HGraph *graph)
Definition: hydrogen.cc:9677
void Bailout(const char *reason)
Definition: hydrogen.cc:3153
const ZoneList< HPhi * > * phis() const
Definition: hydrogen.h:64
void TraceCompilation(FunctionLiteral *function)
Definition: hydrogen.cc:9663
void AssignLoopSuccessorDominators()
Definition: hydrogen.cc:325
TestContext * test_context()
Definition: hydrogen.h:756
int block_id() const
Definition: hydrogen.h:61
bool IsValue() const
Definition: hydrogen.h:627
void Push(HValue *value)
Definition: hydrogen.h:496
BailoutId ast_id() const
Definition: hydrogen.h:456
Handle< JSFunction > closure() const
Definition: hydrogen.h:443
int argument_count() const
Definition: hydrogen.h:84
#define INLINE_RUNTIME_FUNCTION_LIST(F)
Definition: runtime.h:541
Zone * zone() const
Definition: hydrogen.h:418
void * New(int size)
Definition: zone-inl.h:42
activate correct semantics for inheriting readonliness enable harmony semantics for typeof enable harmony enable harmony proxies enable all harmony harmony_scoping harmony_proxies harmony_scoping tracks arrays with only smi values automatically unbox arrays of doubles use crankshaft use hydrogen range analysis use hydrogen global value numbering use function inlining maximum number of AST nodes considered for a single inlining loop invariant code motion print statistics for hydrogen trace generated IR for specified phases trace register allocator trace range analysis trace representation types environment for every instruction put a break point before deoptimizing polymorphic inlining perform array bounds checks elimination use dead code elimination trace on stack replacement optimize closures cache optimized code for closures functions with arguments object loop weight for representation inference allow uint32 values on optimize frames if they are used only in safe operations track parallel recompilation enable all profiler experiments number of stack frames inspected by the profiler call recompile stub directly when self optimizing trigger profiler ticks based on counting instead of timing weight back edges by jump distance for interrupt triggering percentage of ICs that must have type info to allow optimization watch_ic_patching retry_self_opt interrupt_at_exit 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 SAHF instruction if enable use of VFP3 instructions if available this implies enabling ARMv7 and VFP2 enable use of VFP2 instructions if available 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 MIPS FPU instructions if expose natives in global object expose gc extension number of stack frames to capture disable builtin natives files print a stack trace if an assertion failure occurs use random jit cookie to mask large constants trace lazy optimization use adaptive optimizations prepare for turning on always opt minimum length for automatic enable preparsing maximum number of optimization attempts before giving up cache prototype transitions automatically set the debug break flag when debugger commands are in the queue always cause a debug break before aborting 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 more details following each garbage collection print amount of external allocated memory after each time it is adjusted flush code that we expect not to use again before full gc do incremental marking steps track object counts and memory usage use caching Perform compaction on every full GC Never perform compaction on full GC testing only Compact code space on full incremental collections Default seed for initializing random allows verbose printing trace parsing and preparsing Check icache flushes in ARM and MIPS simulator Stack alingment in bytes in print stack trace when throwing exceptions randomize hashes to avoid predictable hash Fixed seed to use to hash property activate a timer that switches between V8 threads testing_bool_flag float flag Seed used for threading test randomness A filename with extra code to be included in the Print usage including flags
Definition: flags.cc:495
void set_first_instruction_index(int index)
Definition: hydrogen.h:87
void Add(E element)
Definition: utils.h:973
void check(i::Vector< const char > string)
TypeFeedbackOracle * oracle() const
Definition: hydrogen.h:727
virtual void ReturnValue(HValue *value)=0
void TraceLiveRanges(const char *name, LAllocator *allocator)
Definition: hydrogen.cc:9794
HEnvironment * start_environment() const
Definition: hydrogen.h:254
void set_osr_values(ZoneList< HUnknownOSRValue * > *values)
Definition: hydrogen.h:336
HBasicBlock * entry_block() const
Definition: hydrogen.h:253
HValue * Lookup(HValue *value) const
Definition: hydrogen.cc:1479
bool Optimize(SmartArrayPointer< char > *bailout_reason)
Definition: hydrogen.cc:3287
void AddInstruction(HInstruction *instr)
Definition: hydrogen.cc:106
HGraph * graph() const
Definition: hydrogen.h:868
HInstruction * AddInstruction(HInstruction *instr)
Definition: hydrogen.cc:3821
HBasicBlock * function_return()
Definition: hydrogen.h:755
const ZoneList< HBasicBlock * > * blocks() const
Definition: hydrogen.h:223
HPhase(const char *name, LChunk *chunk)
Definition: hydrogen.h:1381
void AddLeaveInlined(HValue *return_value, FunctionState *state)
Definition: hydrogen.cc:183
friend class FunctionState
Definition: hydrogen.h:1245
HEnvironment * CopyWithoutHistory() const
Definition: hydrogen.cc:9538
kPropertyAccessorsOffset kNamedPropertyHandlerOffset kInstanceTemplateOffset kAccessCheckInfoOffset kEvalFrominstructionsOffsetOffset kInstanceClassNameOffset flag
Definition: objects-inl.h:3923
bool is_set() const
Definition: utils.h:465