OLD | NEW |
1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
11 // with the distribution. | 11 // with the distribution. |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
47 // allocator | 47 // allocator |
48 // AddDeferred | 48 // AddDeferred |
49 // in_spilled_code | 49 // in_spilled_code |
50 // set_in_spilled_code | 50 // set_in_spilled_code |
51 // RecordPositions | 51 // RecordPositions |
52 // | 52 // |
53 // These methods are either used privately by the shared code or implemented as | 53 // These methods are either used privately by the shared code or implemented as |
54 // shared code: | 54 // shared code: |
55 // CodeGenerator | 55 // CodeGenerator |
56 // ~CodeGenerator | 56 // ~CodeGenerator |
57 // ProcessDeferred | |
58 // Generate | 57 // Generate |
59 // ComputeLazyCompile | 58 // ComputeLazyCompile |
60 // BuildFunctionInfo | 59 // BuildFunctionInfo |
61 // ProcessDeclarations | 60 // ProcessDeclarations |
62 // DeclareGlobals | 61 // DeclareGlobals |
63 // CheckForInlineRuntimeCall | 62 // CheckForInlineRuntimeCall |
64 // AnalyzeCondition | 63 // AnalyzeCondition |
65 // CodeForFunctionPosition | 64 // CodeForFunctionPosition |
66 // CodeForReturnPosition | 65 // CodeForReturnPosition |
67 // CodeForStatementPosition | 66 // CodeForStatementPosition |
68 // CodeForDoWhileConditionPosition | 67 // CodeForDoWhileConditionPosition |
69 // CodeForSourcePosition | 68 // CodeForSourcePosition |
70 | 69 |
71 enum InitState { CONST_INIT, NOT_CONST_INIT }; | |
72 enum TypeofState { INSIDE_TYPEOF, NOT_INSIDE_TYPEOF }; | 70 enum TypeofState { INSIDE_TYPEOF, NOT_INSIDE_TYPEOF }; |
73 | 71 |
74 #if V8_TARGET_ARCH_IA32 | 72 #if V8_TARGET_ARCH_IA32 |
75 #include "ia32/codegen-ia32.h" | 73 #include "ia32/codegen-ia32.h" |
76 #elif V8_TARGET_ARCH_X64 | 74 #elif V8_TARGET_ARCH_X64 |
77 #include "x64/codegen-x64.h" | 75 #include "x64/codegen-x64.h" |
78 #elif V8_TARGET_ARCH_ARM | 76 #elif V8_TARGET_ARCH_ARM |
79 #include "arm/codegen-arm.h" | 77 #include "arm/codegen-arm.h" |
80 #elif V8_TARGET_ARCH_MIPS | 78 #elif V8_TARGET_ARCH_MIPS |
81 #include "mips/codegen-mips.h" | 79 #include "mips/codegen-mips.h" |
82 #else | 80 #else |
83 #error Unsupported target architecture. | 81 #error Unsupported target architecture. |
84 #endif | 82 #endif |
85 | 83 |
86 #include "register-allocator.h" | |
87 | |
88 namespace v8 { | |
89 namespace internal { | |
90 | |
91 // Code generation can be nested. Code generation scopes form a stack | |
92 // of active code generators. | |
93 class CodeGeneratorScope BASE_EMBEDDED { | |
94 public: | |
95 explicit CodeGeneratorScope(Isolate* isolate, CodeGenerator* cgen) | |
96 : isolate_(isolate) { | |
97 previous_ = isolate->current_code_generator(); | |
98 isolate->set_current_code_generator(cgen); | |
99 } | |
100 | |
101 ~CodeGeneratorScope() { | |
102 isolate_->set_current_code_generator(previous_); | |
103 } | |
104 | |
105 static CodeGenerator* Current(Isolate* isolate) { | |
106 ASSERT(isolate->current_code_generator() != NULL); | |
107 return isolate->current_code_generator(); | |
108 } | |
109 | |
110 private: | |
111 CodeGenerator* previous_; | |
112 Isolate* isolate_; | |
113 }; | |
114 | |
115 #if V8_TARGET_ARCH_IA32 || V8_TARGET_ARCH_X64 | |
116 | |
117 // State of used registers in a virtual frame. | |
118 class FrameRegisterState { | |
119 public: | |
120 // Captures the current state of the given frame. | |
121 explicit FrameRegisterState(VirtualFrame* frame); | |
122 | |
123 // Saves the state in the stack. | |
124 void Save(MacroAssembler* masm) const; | |
125 | |
126 // Restores the state from the stack. | |
127 void Restore(MacroAssembler* masm) const; | |
128 | |
129 private: | |
130 // Constants indicating special actions. They should not be multiples | |
131 // of kPointerSize so they will not collide with valid offsets from | |
132 // the frame pointer. | |
133 static const int kIgnore = -1; | |
134 static const int kPush = 1; | |
135 | |
136 // This flag is ored with a valid offset from the frame pointer, so | |
137 // it should fit in the low zero bits of a valid offset. | |
138 static const int kSyncedFlag = 2; | |
139 | |
140 int registers_[RegisterAllocator::kNumRegisters]; | |
141 }; | |
142 | |
143 #elif V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_MIPS | |
144 | |
145 | |
146 class FrameRegisterState { | |
147 public: | |
148 inline FrameRegisterState(VirtualFrame frame) : frame_(frame) { } | |
149 | |
150 inline const VirtualFrame* frame() const { return &frame_; } | |
151 | |
152 private: | |
153 VirtualFrame frame_; | |
154 }; | |
155 | |
156 #else | |
157 | |
158 #error Unsupported target architecture. | |
159 | |
160 #endif | |
161 | |
162 | |
163 // RuntimeCallHelper implementation that saves/restores state of a | |
164 // virtual frame. | |
165 class VirtualFrameRuntimeCallHelper : public RuntimeCallHelper { | |
166 public: | |
167 // Does not take ownership of |frame_state|. | |
168 explicit VirtualFrameRuntimeCallHelper(const FrameRegisterState* frame_state) | |
169 : frame_state_(frame_state) {} | |
170 | |
171 virtual void BeforeCall(MacroAssembler* masm) const; | |
172 | |
173 virtual void AfterCall(MacroAssembler* masm) const; | |
174 | |
175 private: | |
176 const FrameRegisterState* frame_state_; | |
177 }; | |
178 | |
179 | |
180 // Deferred code objects are small pieces of code that are compiled | |
181 // out of line. They are used to defer the compilation of uncommon | |
182 // paths thereby avoiding expensive jumps around uncommon code parts. | |
183 class DeferredCode: public ZoneObject { | |
184 public: | |
185 DeferredCode(); | |
186 virtual ~DeferredCode() { } | |
187 | |
188 virtual void Generate() = 0; | |
189 | |
190 MacroAssembler* masm() { return masm_; } | |
191 | |
192 int statement_position() const { return statement_position_; } | |
193 int position() const { return position_; } | |
194 | |
195 Label* entry_label() { return &entry_label_; } | |
196 Label* exit_label() { return &exit_label_; } | |
197 | |
198 #ifdef DEBUG | |
199 void set_comment(const char* comment) { comment_ = comment; } | |
200 const char* comment() const { return comment_; } | |
201 #else | |
202 void set_comment(const char* comment) { } | |
203 const char* comment() const { return ""; } | |
204 #endif | |
205 | |
206 inline void Jump(); | |
207 inline void Branch(Condition cc); | |
208 void BindExit() { masm_->bind(&exit_label_); } | |
209 | |
210 const FrameRegisterState* frame_state() const { return &frame_state_; } | |
211 | |
212 void SaveRegisters(); | |
213 void RestoreRegisters(); | |
214 void Exit(); | |
215 | |
216 // If this returns true then all registers will be saved for the duration | |
217 // of the Generate() call. Otherwise the registers are not saved and the | |
218 // Generate() call must bracket runtime any runtime calls with calls to | |
219 // SaveRegisters() and RestoreRegisters(). In this case the Generate | |
220 // method must also call Exit() in order to return to the non-deferred | |
221 // code. | |
222 virtual bool AutoSaveAndRestore() { return true; } | |
223 | |
224 protected: | |
225 MacroAssembler* masm_; | |
226 | |
227 private: | |
228 int statement_position_; | |
229 int position_; | |
230 | |
231 Label entry_label_; | |
232 Label exit_label_; | |
233 | |
234 FrameRegisterState frame_state_; | |
235 | |
236 #ifdef DEBUG | |
237 const char* comment_; | |
238 #endif | |
239 DISALLOW_COPY_AND_ASSIGN(DeferredCode); | |
240 }; | |
241 | |
242 | |
243 } } // namespace v8::internal | |
244 | |
245 #endif // V8_CODEGEN_H_ | 84 #endif // V8_CODEGEN_H_ |
OLD | NEW |