| 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" |
| 11 #include "src/ast/scopes.h" | 11 #include "src/ast/scopes.h" |
| 12 #include "src/bit-vector.h" | 12 #include "src/bit-vector.h" |
| 13 #include "src/code-factory.h" | 13 #include "src/code-factory.h" |
| 14 #include "src/code-stubs.h" | 14 #include "src/code-stubs.h" |
| 15 #include "src/codegen.h" | 15 #include "src/codegen.h" |
| 16 #include "src/compiler.h" | 16 #include "src/compiler.h" |
| 17 #include "src/deoptimizer.h" | |
| 18 #include "src/globals.h" | 17 #include "src/globals.h" |
| 19 #include "src/objects.h" | 18 #include "src/objects.h" |
| 20 | 19 |
| 21 namespace v8 { | 20 namespace v8 { |
| 22 namespace internal { | 21 namespace internal { |
| 23 | 22 |
| 24 // Forward declarations. | 23 // Forward declarations. |
| 25 class JumpPatchSite; | 24 class JumpPatchSite; |
| 26 | 25 |
| 27 // ----------------------------------------------------------------------------- | 26 // ----------------------------------------------------------------------------- |
| 28 // Full code generator. | 27 // Full code generator. |
| 29 | 28 |
| 30 class FullCodeGenerator: public AstVisitor { | 29 class FullCodeGenerator: public AstVisitor { |
| 31 public: | 30 public: |
| 31 enum State { |
| 32 NO_REGISTERS, |
| 33 TOS_REG |
| 34 }; |
| 35 |
| 32 FullCodeGenerator(MacroAssembler* masm, CompilationInfo* info) | 36 FullCodeGenerator(MacroAssembler* masm, CompilationInfo* info) |
| 33 : masm_(masm), | 37 : masm_(masm), |
| 34 info_(info), | 38 info_(info), |
| 35 isolate_(info->isolate()), | 39 isolate_(info->isolate()), |
| 36 zone_(info->zone()), | 40 zone_(info->zone()), |
| 37 scope_(info->scope()), | 41 scope_(info->scope()), |
| 38 nesting_stack_(NULL), | 42 nesting_stack_(NULL), |
| 39 loop_depth_(0), | 43 loop_depth_(0), |
| 40 try_catch_depth_(0), | 44 try_catch_depth_(0), |
| 41 operand_stack_depth_(0), | 45 operand_stack_depth_(0), |
| 42 globals_(NULL), | 46 globals_(NULL), |
| 43 context_(NULL), | 47 context_(NULL), |
| 44 bailout_entries_(info->HasDeoptimizationSupport() | 48 bailout_entries_(info->HasDeoptimizationSupport() |
| 45 ? info->literal()->ast_node_count() | 49 ? info->literal()->ast_node_count() |
| 46 : 0, | 50 : 0, |
| 47 info->zone()), | 51 info->zone()), |
| 48 back_edges_(2, info->zone()), | 52 back_edges_(2, info->zone()), |
| 49 handler_table_(info->zone()), | 53 handler_table_(info->zone()), |
| 50 ic_total_count_(0) { | 54 ic_total_count_(0) { |
| 51 DCHECK(!info->IsStub()); | 55 DCHECK(!info->IsStub()); |
| 52 Initialize(); | 56 Initialize(); |
| 53 } | 57 } |
| 54 | 58 |
| 55 void Initialize(); | 59 void Initialize(); |
| 56 | 60 |
| 57 static bool MakeCode(CompilationInfo* info); | 61 static bool MakeCode(CompilationInfo* info); |
| 58 | 62 |
| 59 // Encode bailout state and pc-offset as a BitField<type, start, size>. | 63 // Encode state and pc-offset as a BitField<type, start, size>. |
| 60 // Only use 30 bits because we encode the result as a smi. | 64 // Only use 30 bits because we encode the result as a smi. |
| 61 class BailoutStateField : public BitField<Deoptimizer::BailoutState, 0, 1> {}; | 65 class StateField : public BitField<State, 0, 1> { }; |
| 62 class PcField : public BitField<unsigned, 1, 30 - 1> {}; | 66 class PcField : public BitField<unsigned, 1, 30-1> { }; |
| 67 |
| 68 static const char* State2String(State state) { |
| 69 switch (state) { |
| 70 case NO_REGISTERS: return "NO_REGISTERS"; |
| 71 case TOS_REG: return "TOS_REG"; |
| 72 } |
| 73 UNREACHABLE(); |
| 74 return NULL; |
| 75 } |
| 63 | 76 |
| 64 static const int kMaxBackEdgeWeight = 127; | 77 static const int kMaxBackEdgeWeight = 127; |
| 65 | 78 |
| 66 // Platform-specific code size multiplier. | 79 // Platform-specific code size multiplier. |
| 67 #if V8_TARGET_ARCH_IA32 || V8_TARGET_ARCH_X87 | 80 #if V8_TARGET_ARCH_IA32 || V8_TARGET_ARCH_X87 |
| 68 static const int kCodeSizeMultiplier = 105; | 81 static const int kCodeSizeMultiplier = 105; |
| 69 #elif V8_TARGET_ARCH_X64 | 82 #elif V8_TARGET_ARCH_X64 |
| 70 static const int kCodeSizeMultiplier = 165; | 83 static const int kCodeSizeMultiplier = 165; |
| 71 #elif V8_TARGET_ARCH_ARM | 84 #elif V8_TARGET_ARCH_ARM |
| 72 static const int kCodeSizeMultiplier = 149; | 85 static const int kCodeSizeMultiplier = 149; |
| (...skipping 13 matching lines...) Expand all Loading... |
| 86 #elif V8_TARGET_ARCH_S390X | 99 #elif V8_TARGET_ARCH_S390X |
| 87 // TODO(joransiu): Copied PPC value. Check this is sensible for S390X. | 100 // TODO(joransiu): Copied PPC value. Check this is sensible for S390X. |
| 88 static const int kCodeSizeMultiplier = 200; | 101 static const int kCodeSizeMultiplier = 200; |
| 89 #else | 102 #else |
| 90 #error Unsupported target architecture. | 103 #error Unsupported target architecture. |
| 91 #endif | 104 #endif |
| 92 | 105 |
| 93 static Register result_register(); | 106 static Register result_register(); |
| 94 | 107 |
| 95 private: | 108 private: |
| 96 typedef Deoptimizer::BailoutState BailoutState; | |
| 97 | |
| 98 class Breakable; | 109 class Breakable; |
| 99 class Iteration; | 110 class Iteration; |
| 100 class TryFinally; | 111 class TryFinally; |
| 101 | 112 |
| 102 class TestContext; | 113 class TestContext; |
| 103 | 114 |
| 104 class NestedStatement BASE_EMBEDDED { | 115 class NestedStatement BASE_EMBEDDED { |
| 105 public: | 116 public: |
| 106 explicit NestedStatement(FullCodeGenerator* codegen) | 117 explicit NestedStatement(FullCodeGenerator* codegen) |
| 107 : codegen_(codegen), | 118 : codegen_(codegen), |
| (...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 348 // An operand used to read/write a known (PARAMETER, LOCAL, or CONTEXT) | 359 // An operand used to read/write a known (PARAMETER, LOCAL, or CONTEXT) |
| 349 // variable. May emit code to traverse the context chain, loading the | 360 // variable. May emit code to traverse the context chain, loading the |
| 350 // found context into the scratch register. Writing to this operand will | 361 // found context into the scratch register. Writing to this operand will |
| 351 // need the write barrier if location is CONTEXT. | 362 // need the write barrier if location is CONTEXT. |
| 352 MemOperand VarOperand(Variable* var, Register scratch); | 363 MemOperand VarOperand(Variable* var, Register scratch); |
| 353 | 364 |
| 354 void VisitForEffect(Expression* expr) { | 365 void VisitForEffect(Expression* expr) { |
| 355 if (FLAG_verify_operand_stack_depth) EmitOperandStackDepthCheck(); | 366 if (FLAG_verify_operand_stack_depth) EmitOperandStackDepthCheck(); |
| 356 EffectContext context(this); | 367 EffectContext context(this); |
| 357 Visit(expr); | 368 Visit(expr); |
| 358 PrepareForBailout(expr, BailoutState::NO_REGISTERS); | 369 PrepareForBailout(expr, NO_REGISTERS); |
| 359 } | 370 } |
| 360 | 371 |
| 361 void VisitForAccumulatorValue(Expression* expr) { | 372 void VisitForAccumulatorValue(Expression* expr) { |
| 362 if (FLAG_verify_operand_stack_depth) EmitOperandStackDepthCheck(); | 373 if (FLAG_verify_operand_stack_depth) EmitOperandStackDepthCheck(); |
| 363 AccumulatorValueContext context(this); | 374 AccumulatorValueContext context(this); |
| 364 Visit(expr); | 375 Visit(expr); |
| 365 PrepareForBailout(expr, BailoutState::TOS_REGISTER); | 376 PrepareForBailout(expr, TOS_REG); |
| 366 } | 377 } |
| 367 | 378 |
| 368 void VisitForStackValue(Expression* expr) { | 379 void VisitForStackValue(Expression* expr) { |
| 369 if (FLAG_verify_operand_stack_depth) EmitOperandStackDepthCheck(); | 380 if (FLAG_verify_operand_stack_depth) EmitOperandStackDepthCheck(); |
| 370 StackValueContext context(this); | 381 StackValueContext context(this); |
| 371 Visit(expr); | 382 Visit(expr); |
| 372 PrepareForBailout(expr, BailoutState::NO_REGISTERS); | 383 PrepareForBailout(expr, NO_REGISTERS); |
| 373 } | 384 } |
| 374 | 385 |
| 375 void VisitForControl(Expression* expr, | 386 void VisitForControl(Expression* expr, |
| 376 Label* if_true, | 387 Label* if_true, |
| 377 Label* if_false, | 388 Label* if_false, |
| 378 Label* fall_through) { | 389 Label* fall_through) { |
| 379 if (FLAG_verify_operand_stack_depth) EmitOperandStackDepthCheck(); | 390 if (FLAG_verify_operand_stack_depth) EmitOperandStackDepthCheck(); |
| 380 TestContext context(this, expr, if_true, if_false, fall_through); | 391 TestContext context(this, expr, if_true, if_false, fall_through); |
| 381 Visit(expr); | 392 Visit(expr); |
| 382 // For test contexts, we prepare for bailout before branching, not at | 393 // For test contexts, we prepare for bailout before branching, not at |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 434 void EmitLiteralCompareTypeof(Expression* expr, | 445 void EmitLiteralCompareTypeof(Expression* expr, |
| 435 Expression* sub_expr, | 446 Expression* sub_expr, |
| 436 Handle<String> check); | 447 Handle<String> check); |
| 437 | 448 |
| 438 // Platform-specific code for equality comparison with a nil-like value. | 449 // Platform-specific code for equality comparison with a nil-like value. |
| 439 void EmitLiteralCompareNil(CompareOperation* expr, | 450 void EmitLiteralCompareNil(CompareOperation* expr, |
| 440 Expression* sub_expr, | 451 Expression* sub_expr, |
| 441 NilValue nil); | 452 NilValue nil); |
| 442 | 453 |
| 443 // Bailout support. | 454 // Bailout support. |
| 444 void PrepareForBailout(Expression* node, Deoptimizer::BailoutState state); | 455 void PrepareForBailout(Expression* node, State state); |
| 445 void PrepareForBailoutForId(BailoutId id, Deoptimizer::BailoutState state); | 456 void PrepareForBailoutForId(BailoutId id, State state); |
| 446 | 457 |
| 447 // Returns a smi for the index into the FixedArray that backs the feedback | 458 // Returns a smi for the index into the FixedArray that backs the feedback |
| 448 // vector | 459 // vector |
| 449 Smi* SmiFromSlot(FeedbackVectorSlot slot) const { | 460 Smi* SmiFromSlot(FeedbackVectorSlot slot) const { |
| 450 return Smi::FromInt(TypeFeedbackVector::GetIndexFromSpec( | 461 return Smi::FromInt(TypeFeedbackVector::GetIndexFromSpec( |
| 451 literal()->feedback_vector_spec(), slot)); | 462 literal()->feedback_vector_spec(), slot)); |
| 452 } | 463 } |
| 453 | 464 |
| 454 // Record a call's return site offset, used to rebuild the frame if the | 465 // Record a call's return site offset, used to rebuild the frame if the |
| 455 // called function was inlined at the site. | 466 // called function was inlined at the site. |
| (...skipping 603 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1059 Address start_; | 1070 Address start_; |
| 1060 Address instruction_start_; | 1071 Address instruction_start_; |
| 1061 uint32_t length_; | 1072 uint32_t length_; |
| 1062 }; | 1073 }; |
| 1063 | 1074 |
| 1064 | 1075 |
| 1065 } // namespace internal | 1076 } // namespace internal |
| 1066 } // namespace v8 | 1077 } // namespace v8 |
| 1067 | 1078 |
| 1068 #endif // V8_FULL_CODEGEN_FULL_CODEGEN_H_ | 1079 #endif // V8_FULL_CODEGEN_FULL_CODEGEN_H_ |
| OLD | NEW |