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 |