| OLD | NEW | 
|     1 // Copyright 2012 the V8 project authors. All rights reserved. |     1 // Copyright 2012 the V8 project authors. All rights reserved. | 
|     2 // Use of this source code is governed by a BSD-style license that can be |     2 // Use of this source code is governed by a BSD-style license that can be | 
|     3 // found in the LICENSE file. |     3 // found in the LICENSE file. | 
|     4  |     4  | 
|     5 #ifndef V8_FULL_CODEGEN_FULL_CODEGEN_H_ |     5 #ifndef V8_FULL_CODEGEN_FULL_CODEGEN_H_ | 
|     6 #define V8_FULL_CODEGEN_FULL_CODEGEN_H_ |     6 #define V8_FULL_CODEGEN_FULL_CODEGEN_H_ | 
|     7  |     7  | 
|     8 #include "src/allocation.h" |     8 #include "src/allocation.h" | 
|     9 #include "src/assert-scope.h" |     9 #include "src/assert-scope.h" | 
|    10 #include "src/ast/ast.h" |    10 #include "src/ast/ast.h" | 
| (...skipping 24 matching lines...) Expand all  Loading... | 
|    35  |    35  | 
|    36   FullCodeGenerator(MacroAssembler* masm, CompilationInfo* info) |    36   FullCodeGenerator(MacroAssembler* masm, CompilationInfo* info) | 
|    37       : masm_(masm), |    37       : masm_(masm), | 
|    38         info_(info), |    38         info_(info), | 
|    39         isolate_(info->isolate()), |    39         isolate_(info->isolate()), | 
|    40         zone_(info->zone()), |    40         zone_(info->zone()), | 
|    41         scope_(info->scope()), |    41         scope_(info->scope()), | 
|    42         nesting_stack_(NULL), |    42         nesting_stack_(NULL), | 
|    43         loop_depth_(0), |    43         loop_depth_(0), | 
|    44         try_catch_depth_(0), |    44         try_catch_depth_(0), | 
 |    45         operand_stack_depth_(0), | 
|    45         globals_(NULL), |    46         globals_(NULL), | 
|    46         context_(NULL), |    47         context_(NULL), | 
|    47         bailout_entries_(info->HasDeoptimizationSupport() |    48         bailout_entries_(info->HasDeoptimizationSupport() | 
|    48                              ? info->literal()->ast_node_count() |    49                              ? info->literal()->ast_node_count() | 
|    49                              : 0, |    50                              : 0, | 
|    50                          info->zone()), |    51                          info->zone()), | 
|    51         back_edges_(2, info->zone()), |    52         back_edges_(2, info->zone()), | 
|    52         handler_table_(info->zone()), |    53         handler_table_(info->zone()), | 
|    53         ic_total_count_(0) { |    54         ic_total_count_(0) { | 
|    54     DCHECK(!info->IsStub()); |    55     DCHECK(!info->IsStub()); | 
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   129     // Notify the statement that we are exiting it via break, continue, or |   130     // Notify the statement that we are exiting it via break, continue, or | 
|   130     // return and give it a chance to generate cleanup code.  Return the |   131     // return and give it a chance to generate cleanup code.  Return the | 
|   131     // next outer statement in the nesting stack.  We accumulate in |   132     // next outer statement in the nesting stack.  We accumulate in | 
|   132     // *stack_depth the amount to drop the stack and in *context_length the |   133     // *stack_depth the amount to drop the stack and in *context_length the | 
|   133     // number of context chain links to unwind as we traverse the nesting |   134     // number of context chain links to unwind as we traverse the nesting | 
|   134     // stack from an exit to its target. |   135     // stack from an exit to its target. | 
|   135     virtual NestedStatement* Exit(int* stack_depth, int* context_length) { |   136     virtual NestedStatement* Exit(int* stack_depth, int* context_length) { | 
|   136       return previous_; |   137       return previous_; | 
|   137     } |   138     } | 
|   138  |   139  | 
|   139     // Like the Exit() method above, but limited to accumulating stack depth. |  | 
|   140     virtual NestedStatement* AccumulateDepth(int* stack_depth) { |  | 
|   141       return previous_; |  | 
|   142     } |  | 
|   143  |  | 
|   144    protected: |   140    protected: | 
|   145     MacroAssembler* masm() { return codegen_->masm(); } |   141     MacroAssembler* masm() { return codegen_->masm(); } | 
|   146  |   142  | 
|   147     FullCodeGenerator* codegen_; |   143     FullCodeGenerator* codegen_; | 
|   148     NestedStatement* previous_; |   144     NestedStatement* previous_; | 
|   149  |   145  | 
|   150    private: |   146    private: | 
|   151     DISALLOW_COPY_AND_ASSIGN(NestedStatement); |   147     DISALLOW_COPY_AND_ASSIGN(NestedStatement); | 
|   152   }; |   148   }; | 
|   153  |   149  | 
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   209   class TryCatch : public NestedStatement { |   205   class TryCatch : public NestedStatement { | 
|   210    public: |   206    public: | 
|   211     static const int kElementCount = TryBlockConstant::kElementCount; |   207     static const int kElementCount = TryBlockConstant::kElementCount; | 
|   212  |   208  | 
|   213     explicit TryCatch(FullCodeGenerator* codegen) : NestedStatement(codegen) {} |   209     explicit TryCatch(FullCodeGenerator* codegen) : NestedStatement(codegen) {} | 
|   214  |   210  | 
|   215     NestedStatement* Exit(int* stack_depth, int* context_length) override { |   211     NestedStatement* Exit(int* stack_depth, int* context_length) override { | 
|   216       *stack_depth += kElementCount; |   212       *stack_depth += kElementCount; | 
|   217       return previous_; |   213       return previous_; | 
|   218     } |   214     } | 
|   219     NestedStatement* AccumulateDepth(int* stack_depth) override { |  | 
|   220       *stack_depth += kElementCount; |  | 
|   221       return previous_; |  | 
|   222     } |  | 
|   223   }; |   215   }; | 
|   224  |   216  | 
|   225   class DeferredCommands { |   217   class DeferredCommands { | 
|   226    public: |   218    public: | 
|   227     enum Command { kReturn, kThrow, kBreak, kContinue }; |   219     enum Command { kReturn, kThrow, kBreak, kContinue }; | 
|   228     typedef int TokenId; |   220     typedef int TokenId; | 
|   229     struct DeferredCommand { |   221     struct DeferredCommand { | 
|   230       Command command; |   222       Command command; | 
|   231       TokenId token; |   223       TokenId token; | 
|   232       Statement* target; |   224       Statement* target; | 
| (...skipping 28 matching lines...) Expand all  Loading... | 
|   261  |   253  | 
|   262   // The try block of a try/finally statement. |   254   // The try block of a try/finally statement. | 
|   263   class TryFinally : public NestedStatement { |   255   class TryFinally : public NestedStatement { | 
|   264    public: |   256    public: | 
|   265     static const int kElementCount = TryBlockConstant::kElementCount; |   257     static const int kElementCount = TryBlockConstant::kElementCount; | 
|   266  |   258  | 
|   267     TryFinally(FullCodeGenerator* codegen, DeferredCommands* commands) |   259     TryFinally(FullCodeGenerator* codegen, DeferredCommands* commands) | 
|   268         : NestedStatement(codegen), deferred_commands_(commands) {} |   260         : NestedStatement(codegen), deferred_commands_(commands) {} | 
|   269  |   261  | 
|   270     NestedStatement* Exit(int* stack_depth, int* context_length) override; |   262     NestedStatement* Exit(int* stack_depth, int* context_length) override; | 
|   271     NestedStatement* AccumulateDepth(int* stack_depth) override { |  | 
|   272       *stack_depth += kElementCount; |  | 
|   273       return previous_; |  | 
|   274     } |  | 
|   275  |   263  | 
|   276     bool IsTryFinally() override { return true; } |   264     bool IsTryFinally() override { return true; } | 
|   277     TryFinally* AsTryFinally() override { return this; } |   265     TryFinally* AsTryFinally() override { return this; } | 
|   278  |   266  | 
|   279     DeferredCommands* deferred_commands() { return deferred_commands_; } |   267     DeferredCommands* deferred_commands() { return deferred_commands_; } | 
|   280  |   268  | 
|   281    private: |   269    private: | 
|   282     DeferredCommands* deferred_commands_; |   270     DeferredCommands* deferred_commands_; | 
|   283   }; |   271   }; | 
|   284  |   272  | 
|   285   // The finally block of a try/finally statement. |   273   // The finally block of a try/finally statement. | 
|   286   class Finally : public NestedStatement { |   274   class Finally : public NestedStatement { | 
|   287    public: |   275    public: | 
|   288     static const int kElementCount = 3; |   276     static const int kElementCount = 3; | 
|   289  |   277  | 
|   290     explicit Finally(FullCodeGenerator* codegen) : NestedStatement(codegen) {} |   278     explicit Finally(FullCodeGenerator* codegen) : NestedStatement(codegen) {} | 
|   291  |   279  | 
|   292     NestedStatement* Exit(int* stack_depth, int* context_length) override { |   280     NestedStatement* Exit(int* stack_depth, int* context_length) override { | 
|   293       *stack_depth += kElementCount; |   281       *stack_depth += kElementCount; | 
|   294       return previous_; |   282       return previous_; | 
|   295     } |   283     } | 
|   296     NestedStatement* AccumulateDepth(int* stack_depth) override { |  | 
|   297       *stack_depth += kElementCount; |  | 
|   298       return previous_; |  | 
|   299     } |  | 
|   300   }; |   284   }; | 
|   301  |   285  | 
|   302   // The body of a for/in loop. |   286   // The body of a for/in loop. | 
|   303   class ForIn : public Iteration { |   287   class ForIn : public Iteration { | 
|   304    public: |   288    public: | 
|   305     static const int kElementCount = 5; |   289     static const int kElementCount = 5; | 
|   306  |   290  | 
|   307     ForIn(FullCodeGenerator* codegen, ForInStatement* statement) |   291     ForIn(FullCodeGenerator* codegen, ForInStatement* statement) | 
|   308         : Iteration(codegen, statement) { |   292         : Iteration(codegen, statement) { | 
|   309     } |   293     } | 
|   310  |   294  | 
|   311     NestedStatement* Exit(int* stack_depth, int* context_length) override { |   295     NestedStatement* Exit(int* stack_depth, int* context_length) override { | 
|   312       *stack_depth += kElementCount; |   296       *stack_depth += kElementCount; | 
|   313       return previous_; |   297       return previous_; | 
|   314     } |   298     } | 
|   315     NestedStatement* AccumulateDepth(int* stack_depth) override { |  | 
|   316       *stack_depth += kElementCount; |  | 
|   317       return previous_; |  | 
|   318     } |  | 
|   319   }; |   299   }; | 
|   320  |   300  | 
|   321  |   301  | 
|   322   // The body of a with or catch. |   302   // The body of a with or catch. | 
|   323   class WithOrCatch : public NestedStatement { |   303   class WithOrCatch : public NestedStatement { | 
|   324    public: |   304    public: | 
|   325     explicit WithOrCatch(FullCodeGenerator* codegen) |   305     explicit WithOrCatch(FullCodeGenerator* codegen) | 
|   326         : NestedStatement(codegen) { |   306         : NestedStatement(codegen) { | 
|   327     } |   307     } | 
|   328  |   308  | 
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   393   // variable.  Writing does not need the write barrier. |   373   // variable.  Writing does not need the write barrier. | 
|   394   MemOperand StackOperand(Variable* var); |   374   MemOperand StackOperand(Variable* var); | 
|   395  |   375  | 
|   396   // An operand used to read/write a known (PARAMETER, LOCAL, or CONTEXT) |   376   // An operand used to read/write a known (PARAMETER, LOCAL, or CONTEXT) | 
|   397   // variable.  May emit code to traverse the context chain, loading the |   377   // variable.  May emit code to traverse the context chain, loading the | 
|   398   // found context into the scratch register.  Writing to this operand will |   378   // found context into the scratch register.  Writing to this operand will | 
|   399   // need the write barrier if location is CONTEXT. |   379   // need the write barrier if location is CONTEXT. | 
|   400   MemOperand VarOperand(Variable* var, Register scratch); |   380   MemOperand VarOperand(Variable* var, Register scratch); | 
|   401  |   381  | 
|   402   void VisitForEffect(Expression* expr) { |   382   void VisitForEffect(Expression* expr) { | 
 |   383     if (FLAG_verify_operand_stack_depth) EmitOperandStackDepthCheck(); | 
|   403     EffectContext context(this); |   384     EffectContext context(this); | 
|   404     Visit(expr); |   385     Visit(expr); | 
|   405     PrepareForBailout(expr, NO_REGISTERS); |   386     PrepareForBailout(expr, NO_REGISTERS); | 
|   406   } |   387   } | 
|   407  |   388  | 
|   408   void VisitForAccumulatorValue(Expression* expr) { |   389   void VisitForAccumulatorValue(Expression* expr) { | 
 |   390     if (FLAG_verify_operand_stack_depth) EmitOperandStackDepthCheck(); | 
|   409     AccumulatorValueContext context(this); |   391     AccumulatorValueContext context(this); | 
|   410     Visit(expr); |   392     Visit(expr); | 
|   411     PrepareForBailout(expr, TOS_REG); |   393     PrepareForBailout(expr, TOS_REG); | 
|   412   } |   394   } | 
|   413  |   395  | 
|   414   void VisitForStackValue(Expression* expr) { |   396   void VisitForStackValue(Expression* expr) { | 
 |   397     if (FLAG_verify_operand_stack_depth) EmitOperandStackDepthCheck(); | 
|   415     StackValueContext context(this); |   398     StackValueContext context(this); | 
|   416     Visit(expr); |   399     Visit(expr); | 
|   417     PrepareForBailout(expr, NO_REGISTERS); |   400     PrepareForBailout(expr, NO_REGISTERS); | 
|   418   } |   401   } | 
|   419  |   402  | 
|   420   void VisitForControl(Expression* expr, |   403   void VisitForControl(Expression* expr, | 
|   421                        Label* if_true, |   404                        Label* if_true, | 
|   422                        Label* if_false, |   405                        Label* if_false, | 
|   423                        Label* fall_through) { |   406                        Label* fall_through) { | 
 |   407     if (FLAG_verify_operand_stack_depth) EmitOperandStackDepthCheck(); | 
|   424     TestContext context(this, expr, if_true, if_false, fall_through); |   408     TestContext context(this, expr, if_true, if_false, fall_through); | 
|   425     Visit(expr); |   409     Visit(expr); | 
|   426     // For test contexts, we prepare for bailout before branching, not at |   410     // For test contexts, we prepare for bailout before branching, not at | 
|   427     // the end of the entire expression.  This happens as part of visiting |   411     // the end of the entire expression.  This happens as part of visiting | 
|   428     // the expression. |   412     // the expression. | 
|   429   } |   413   } | 
|   430  |   414  | 
|   431   void VisitInDuplicateContext(Expression* expr); |   415   void VisitInDuplicateContext(Expression* expr); | 
|   432  |   416  | 
|   433   void VisitDeclarations(ZoneList<Declaration*>* declarations) override; |   417   void VisitDeclarations(ZoneList<Declaration*>* declarations) override; | 
|   434   void DeclareModules(Handle<FixedArray> descriptions); |   418   void DeclareModules(Handle<FixedArray> descriptions); | 
|   435   void DeclareGlobals(Handle<FixedArray> pairs); |   419   void DeclareGlobals(Handle<FixedArray> pairs); | 
|   436   int DeclareGlobalsFlags(); |   420   int DeclareGlobalsFlags(); | 
|   437  |   421  | 
 |   422   // Push, pop or drop values onto/from the operand stack. | 
 |   423   void PushOperand(Register reg); | 
 |   424   void PopOperand(Register reg); | 
 |   425   void DropOperands(int count); | 
 |   426  | 
 |   427   // Convenience helpers for pushing onto the operand stack. | 
 |   428   void PushOperand(MemOperand operand); | 
 |   429   void PushOperand(Handle<Object> handle); | 
 |   430   void PushOperand(Smi* smi); | 
 |   431  | 
 |   432   // Convenience helper for calling a runtime function that consumes arguments | 
 |   433   // from the operand stack (only usable for functions with known arity). | 
 |   434   void CallRuntimeWithOperands(Runtime::FunctionId function_id); | 
 |   435  | 
 |   436   // Static tracking of the operand stack depth. | 
 |   437   void OperandStackDepthDecrement(int count); | 
 |   438   void OperandStackDepthIncrement(int count); | 
 |   439  | 
 |   440   // Generate debug code that verifies that our static tracking of the operand | 
 |   441   // stack depth is in sync with the actual operand stack during runtime. | 
 |   442   void EmitOperandStackDepthCheck(); | 
 |   443  | 
|   438   // Generate code to create an iterator result object.  The "value" property is |   444   // Generate code to create an iterator result object.  The "value" property is | 
|   439   // set to a value popped from the stack, and "done" is set according to the |   445   // set to a value popped from the stack, and "done" is set according to the | 
|   440   // argument.  The result object is left in the result register. |   446   // argument.  The result object is left in the result register. | 
|   441   void EmitCreateIteratorResult(bool done); |   447   void EmitCreateIteratorResult(bool done); | 
|   442  |   448  | 
|   443   // Try to perform a comparison as a fast inlined literal compare if |   449   // Try to perform a comparison as a fast inlined literal compare if | 
|   444   // the operands allow it.  Returns true if the compare operations |   450   // the operands allow it.  Returns true if the compare operations | 
|   445   // has been matched and all code generated; false otherwise. |   451   // has been matched and all code generated; false otherwise. | 
|   446   bool TryLiteralCompare(CompareOperation* compare); |   452   bool TryLiteralCompare(CompareOperation* compare); | 
|   447  |   453  | 
| (...skipping 533 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   981  |   987  | 
|   982   MacroAssembler* masm_; |   988   MacroAssembler* masm_; | 
|   983   CompilationInfo* info_; |   989   CompilationInfo* info_; | 
|   984   Isolate* isolate_; |   990   Isolate* isolate_; | 
|   985   Zone* zone_; |   991   Zone* zone_; | 
|   986   Scope* scope_; |   992   Scope* scope_; | 
|   987   Label return_label_; |   993   Label return_label_; | 
|   988   NestedStatement* nesting_stack_; |   994   NestedStatement* nesting_stack_; | 
|   989   int loop_depth_; |   995   int loop_depth_; | 
|   990   int try_catch_depth_; |   996   int try_catch_depth_; | 
 |   997   int operand_stack_depth_; | 
|   991   ZoneList<Handle<Object> >* globals_; |   998   ZoneList<Handle<Object> >* globals_; | 
|   992   Handle<FixedArray> modules_; |   999   Handle<FixedArray> modules_; | 
|   993   int module_index_; |  1000   int module_index_; | 
|   994   const ExpressionContext* context_; |  1001   const ExpressionContext* context_; | 
|   995   ZoneList<BailoutEntry> bailout_entries_; |  1002   ZoneList<BailoutEntry> bailout_entries_; | 
|   996   ZoneList<BackEdgeEntry> back_edges_; |  1003   ZoneList<BackEdgeEntry> back_edges_; | 
|   997   ZoneVector<HandlerTableEntry> handler_table_; |  1004   ZoneVector<HandlerTableEntry> handler_table_; | 
|   998   int ic_total_count_; |  1005   int ic_total_count_; | 
|   999   Handle<Cell> profiling_counter_; |  1006   Handle<Cell> profiling_counter_; | 
|  1000   bool generate_debug_code_; |  1007   bool generate_debug_code_; | 
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  1086   Address start_; |  1093   Address start_; | 
|  1087   Address instruction_start_; |  1094   Address instruction_start_; | 
|  1088   uint32_t length_; |  1095   uint32_t length_; | 
|  1089 }; |  1096 }; | 
|  1090  |  1097  | 
|  1091  |  1098  | 
|  1092 }  // namespace internal |  1099 }  // namespace internal | 
|  1093 }  // namespace v8 |  1100 }  // namespace v8 | 
|  1094  |  1101  | 
|  1095 #endif  // V8_FULL_CODEGEN_FULL_CODEGEN_H_ |  1102 #endif  // V8_FULL_CODEGEN_FULL_CODEGEN_H_ | 
| OLD | NEW |