| 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 helpers for pushing/popping multiple operands. |
| 433 void PushOperands(Register reg1, Register reg2); |
| 434 void PushOperands(Register reg1, Register reg2, Register reg3); |
| 435 void PushOperands(Register reg1, Register reg2, Register reg3, Register reg4); |
| 436 void PopOperands(Register reg1, Register reg2); |
| 437 |
| 438 // Convenience helper for calling a runtime function that consumes arguments |
| 439 // from the operand stack (only usable for functions with known arity). |
| 440 void CallRuntimeWithOperands(Runtime::FunctionId function_id); |
| 441 |
| 442 // Static tracking of the operand stack depth. |
| 443 void OperandStackDepthDecrement(int count); |
| 444 void OperandStackDepthIncrement(int count); |
| 445 |
| 446 // Generate debug code that verifies that our static tracking of the operand |
| 447 // stack depth is in sync with the actual operand stack during runtime. |
| 448 void EmitOperandStackDepthCheck(); |
| 449 |
| 438 // Generate code to create an iterator result object. The "value" property is | 450 // 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 | 451 // 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. | 452 // argument. The result object is left in the result register. |
| 441 void EmitCreateIteratorResult(bool done); | 453 void EmitCreateIteratorResult(bool done); |
| 442 | 454 |
| 443 // Try to perform a comparison as a fast inlined literal compare if | 455 // Try to perform a comparison as a fast inlined literal compare if |
| 444 // the operands allow it. Returns true if the compare operations | 456 // the operands allow it. Returns true if the compare operations |
| 445 // has been matched and all code generated; false otherwise. | 457 // has been matched and all code generated; false otherwise. |
| 446 bool TryLiteralCompare(CompareOperation* compare); | 458 bool TryLiteralCompare(CompareOperation* compare); |
| 447 | 459 |
| (...skipping 532 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 980 | 992 |
| 981 MacroAssembler* masm_; | 993 MacroAssembler* masm_; |
| 982 CompilationInfo* info_; | 994 CompilationInfo* info_; |
| 983 Isolate* isolate_; | 995 Isolate* isolate_; |
| 984 Zone* zone_; | 996 Zone* zone_; |
| 985 Scope* scope_; | 997 Scope* scope_; |
| 986 Label return_label_; | 998 Label return_label_; |
| 987 NestedStatement* nesting_stack_; | 999 NestedStatement* nesting_stack_; |
| 988 int loop_depth_; | 1000 int loop_depth_; |
| 989 int try_catch_depth_; | 1001 int try_catch_depth_; |
| 1002 int operand_stack_depth_; |
| 990 ZoneList<Handle<Object> >* globals_; | 1003 ZoneList<Handle<Object> >* globals_; |
| 991 Handle<FixedArray> modules_; | 1004 Handle<FixedArray> modules_; |
| 992 int module_index_; | 1005 int module_index_; |
| 993 const ExpressionContext* context_; | 1006 const ExpressionContext* context_; |
| 994 ZoneList<BailoutEntry> bailout_entries_; | 1007 ZoneList<BailoutEntry> bailout_entries_; |
| 995 ZoneList<BackEdgeEntry> back_edges_; | 1008 ZoneList<BackEdgeEntry> back_edges_; |
| 996 ZoneVector<HandlerTableEntry> handler_table_; | 1009 ZoneVector<HandlerTableEntry> handler_table_; |
| 997 int ic_total_count_; | 1010 int ic_total_count_; |
| 998 Handle<Cell> profiling_counter_; | 1011 Handle<Cell> profiling_counter_; |
| 999 bool generate_debug_code_; | 1012 bool generate_debug_code_; |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1085 Address start_; | 1098 Address start_; |
| 1086 Address instruction_start_; | 1099 Address instruction_start_; |
| 1087 uint32_t length_; | 1100 uint32_t length_; |
| 1088 }; | 1101 }; |
| 1089 | 1102 |
| 1090 | 1103 |
| 1091 } // namespace internal | 1104 } // namespace internal |
| 1092 } // namespace v8 | 1105 } // namespace v8 |
| 1093 | 1106 |
| 1094 #endif // V8_FULL_CODEGEN_FULL_CODEGEN_H_ | 1107 #endif // V8_FULL_CODEGEN_FULL_CODEGEN_H_ |
| OLD | NEW |