OLD | NEW |
1 // Copyright 2011 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 |
(...skipping 27 matching lines...) Expand all Loading... |
38 | 38 |
39 // Forward declarations. | 39 // Forward declarations. |
40 class LCodeGen; | 40 class LCodeGen; |
41 class LEnvironment; | 41 class LEnvironment; |
42 class Translation; | 42 class Translation; |
43 | 43 |
44 | 44 |
45 // Type hierarchy: | 45 // Type hierarchy: |
46 // | 46 // |
47 // LInstruction | 47 // LInstruction |
| 48 // LDeoptimize |
48 // LGap | 49 // LGap |
| 50 // LLabel |
| 51 // LGoto |
| 52 // LLazyBailout |
| 53 // LOsrEntry |
49 | 54 |
50 #define LITHIUM_ALL_INSTRUCTION_LIST(V) \ | 55 #define LITHIUM_ALL_INSTRUCTION_LIST(V) \ |
51 LITHIUM_CONCRETE_INSTRUCTION_LIST(V) | 56 LITHIUM_CONCRETE_INSTRUCTION_LIST(V) |
52 | 57 |
53 #define LITHIUM_CONCRETE_INSTRUCTION_LIST(V) \ | 58 #define LITHIUM_CONCRETE_INSTRUCTION_LIST(V) \ |
54 V(Gap) | 59 V(Deoptimize) \ |
| 60 V(Gap) \ |
| 61 V(Goto) \ |
| 62 V(Label) \ |
| 63 V(LazyBailout) \ |
| 64 V(OsrEntry) |
55 | 65 |
56 | 66 |
57 #define DECLARE_INSTRUCTION(type) \ | 67 #define DECLARE_INSTRUCTION(type) \ |
58 virtual bool Is##type() const { return true; } \ | 68 virtual bool Is##type() const { return true; } \ |
59 static L##type* cast(LInstruction* instr) { \ | 69 static L##type* cast(LInstruction* instr) { \ |
60 ASSERT(instr->Is##type()); \ | 70 ASSERT(instr->Is##type()); \ |
61 return reinterpret_cast<L##type*>(instr); \ | 71 return reinterpret_cast<L##type*>(instr); \ |
62 } | 72 } |
63 | 73 |
64 | 74 |
65 #define DECLARE_CONCRETE_INSTRUCTION(type, mnemonic) \ | 75 #define DECLARE_CONCRETE_INSTRUCTION(type, mnemonic) \ |
66 virtual void CompileToNative(LCodeGen* generator); \ | 76 virtual void CompileToNative(LCodeGen* generator); \ |
67 virtual const char* Mnemonic() const { return mnemonic; } \ | 77 virtual const char* Mnemonic() const { return mnemonic; } \ |
68 DECLARE_INSTRUCTION(type) | 78 DECLARE_INSTRUCTION(type) |
69 | 79 |
70 | 80 |
71 #define DECLARE_HYDROGEN_ACCESSOR(type) \ | 81 #define DECLARE_HYDROGEN_ACCESSOR(type) \ |
72 H##type* hydrogen() const { \ | 82 H##type* hydrogen() const { \ |
73 return H##type::cast(hydrogen_value()); \ | 83 return H##type::cast(hydrogen_value()); \ |
74 } | 84 } |
75 | 85 |
76 | 86 |
77 class LInstruction: public ZoneObject { | 87 class LInstruction: public ZoneObject { |
78 public: | 88 public: |
79 LInstruction() | 89 LInstruction() |
80 : hydrogen_value_(NULL) { } | 90 : hydrogen_value_(NULL) { } |
81 virtual ~LInstruction() { } | 91 virtual ~LInstruction() { } |
82 | 92 |
83 // Predicates should be generated by macro as in lithium-ia32.h. | |
84 virtual bool IsLabel() const { | |
85 UNIMPLEMENTED(); | |
86 return false; | |
87 } | |
88 virtual bool IsOsrEntry() const { | |
89 UNIMPLEMENTED(); | |
90 return false; | |
91 } | |
92 | |
93 virtual void CompileToNative(LCodeGen* generator) = 0; | 93 virtual void CompileToNative(LCodeGen* generator) = 0; |
94 virtual const char* Mnemonic() const = 0; | 94 virtual const char* Mnemonic() const = 0; |
95 virtual void PrintTo(StringStream* stream) const; | 95 virtual void PrintTo(StringStream* stream); |
96 virtual void PrintDataTo(StringStream* stream) const { } | 96 virtual void PrintDataTo(StringStream* stream) { } |
97 | 97 |
98 // Declare virtual type testers. | 98 // Declare virtual type testers. |
99 #define DECLARE_DO(type) virtual bool Is##type() const { return false; } | 99 #define DECLARE_DO(type) virtual bool Is##type() const { return false; } |
100 LITHIUM_ALL_INSTRUCTION_LIST(DECLARE_DO) | 100 LITHIUM_ALL_INSTRUCTION_LIST(DECLARE_DO) |
101 #undef DECLARE_DO | 101 #undef DECLARE_DO |
102 virtual bool IsControl() const { return false; } | 102 virtual bool IsControl() const { return false; } |
103 | 103 |
104 void set_environment(LEnvironment* env) { environment_.set(env); } | 104 void set_environment(LEnvironment* env) { environment_.set(env); } |
105 LEnvironment* environment() const { return environment_.get(); } | 105 LEnvironment* environment() const { return environment_.get(); } |
106 bool HasEnvironment() const { return environment_.is_set(); } | 106 bool HasEnvironment() const { return environment_.is_set(); } |
107 | 107 |
108 void set_pointer_map(LPointerMap* p) { pointer_map_.set(p); } | 108 void set_pointer_map(LPointerMap* p) { pointer_map_.set(p); } |
109 LPointerMap* pointer_map() const { return pointer_map_.get(); } | 109 LPointerMap* pointer_map() const { return pointer_map_.get(); } |
110 bool HasPointerMap() const { return pointer_map_.is_set(); } | 110 bool HasPointerMap() const { return pointer_map_.is_set(); } |
111 | 111 |
112 void set_result(LOperand* operand) { result_.set(operand); } | 112 virtual bool HasResult() const = 0; |
113 LOperand* result() const { return result_.get(); } | |
114 bool HasResult() const { return result_.is_set(); } | |
115 | 113 |
116 void set_hydrogen_value(HValue* value) { hydrogen_value_ = value; } | 114 void set_hydrogen_value(HValue* value) { hydrogen_value_ = value; } |
117 HValue* hydrogen_value() const { return hydrogen_value_; } | 115 HValue* hydrogen_value() const { return hydrogen_value_; } |
118 | 116 |
119 void set_deoptimization_environment(LEnvironment* env) { | 117 void set_deoptimization_environment(LEnvironment* env) { |
120 deoptimization_environment_.set(env); | 118 deoptimization_environment_.set(env); |
121 } | 119 } |
122 LEnvironment* deoptimization_environment() const { | 120 LEnvironment* deoptimization_environment() const { |
123 return deoptimization_environment_.get(); | 121 return deoptimization_environment_.get(); |
124 } | 122 } |
125 bool HasDeoptimizationEnvironment() const { | 123 bool HasDeoptimizationEnvironment() const { |
126 return deoptimization_environment_.is_set(); | 124 return deoptimization_environment_.is_set(); |
127 } | 125 } |
128 | 126 |
129 private: | 127 private: |
130 SetOncePointer<LEnvironment> environment_; | 128 SetOncePointer<LEnvironment> environment_; |
131 SetOncePointer<LPointerMap> pointer_map_; | 129 SetOncePointer<LPointerMap> pointer_map_; |
132 SetOncePointer<LOperand> result_; | |
133 HValue* hydrogen_value_; | 130 HValue* hydrogen_value_; |
134 SetOncePointer<LEnvironment> deoptimization_environment_; | 131 SetOncePointer<LEnvironment> deoptimization_environment_; |
135 }; | 132 }; |
136 | 133 |
137 | 134 |
138 class LGap: public LInstruction { | 135 template <int Result> |
| 136 class LTemplateInstruction: public LInstruction { }; |
| 137 |
| 138 |
| 139 template<> |
| 140 class LTemplateInstruction<0>: public LInstruction { |
| 141 virtual bool HasResult() const { return false; } |
| 142 }; |
| 143 |
| 144 |
| 145 template<> |
| 146 class LTemplateInstruction<1>: public LInstruction { |
| 147 public: |
| 148 static LTemplateInstruction<1>* cast(LInstruction* instr) { |
| 149 ASSERT(instr->HasResult()); |
| 150 return reinterpret_cast<LTemplateInstruction<1>*>(instr); |
| 151 } |
| 152 void set_result(LOperand* operand) { result_.set(operand); } |
| 153 LOperand* result() const { return result_.get(); } |
| 154 virtual bool HasResult() const { return result_.is_set(); } |
| 155 private: |
| 156 SetOncePointer<LOperand> result_; |
| 157 }; |
| 158 |
| 159 |
| 160 class LGap: public LTemplateInstruction<0> { |
139 public: | 161 public: |
140 explicit LGap(HBasicBlock* block) | 162 explicit LGap(HBasicBlock* block) |
141 : block_(block) { | 163 : block_(block) { |
142 parallel_moves_[BEFORE] = NULL; | 164 parallel_moves_[BEFORE] = NULL; |
143 parallel_moves_[START] = NULL; | 165 parallel_moves_[START] = NULL; |
144 parallel_moves_[END] = NULL; | 166 parallel_moves_[END] = NULL; |
145 parallel_moves_[AFTER] = NULL; | 167 parallel_moves_[AFTER] = NULL; |
146 } | 168 } |
147 | 169 |
148 DECLARE_CONCRETE_INSTRUCTION(Gap, "gap") | 170 DECLARE_CONCRETE_INSTRUCTION(Gap, "gap") |
149 virtual void PrintDataTo(StringStream* stream) const; | 171 virtual void PrintDataTo(StringStream* stream); |
150 | 172 |
151 bool IsRedundant() const; | 173 bool IsRedundant() const; |
152 | 174 |
153 HBasicBlock* block() const { return block_; } | 175 HBasicBlock* block() const { return block_; } |
154 | 176 |
155 enum InnerPosition { | 177 enum InnerPosition { |
156 BEFORE, | 178 BEFORE, |
157 START, | 179 START, |
158 END, | 180 END, |
159 AFTER, | 181 AFTER, |
160 FIRST_INNER_POSITION = BEFORE, | 182 FIRST_INNER_POSITION = BEFORE, |
161 LAST_INNER_POSITION = AFTER | 183 LAST_INNER_POSITION = AFTER |
162 }; | 184 }; |
163 | 185 |
164 LParallelMove* GetOrCreateParallelMove(InnerPosition pos) { | 186 LParallelMove* GetOrCreateParallelMove(InnerPosition pos) { |
165 if (parallel_moves_[pos] == NULL) parallel_moves_[pos] = new LParallelMove; | 187 if (parallel_moves_[pos] == NULL) parallel_moves_[pos] = new LParallelMove; |
166 return parallel_moves_[pos]; | 188 return parallel_moves_[pos]; |
167 } | 189 } |
168 | 190 |
169 LParallelMove* GetParallelMove(InnerPosition pos) { | 191 LParallelMove* GetParallelMove(InnerPosition pos) { |
170 return parallel_moves_[pos]; | 192 return parallel_moves_[pos]; |
171 } | 193 } |
172 | 194 |
173 private: | 195 private: |
174 LParallelMove* parallel_moves_[LAST_INNER_POSITION + 1]; | 196 LParallelMove* parallel_moves_[LAST_INNER_POSITION + 1]; |
175 HBasicBlock* block_; | 197 HBasicBlock* block_; |
176 }; | 198 }; |
177 | 199 |
178 | 200 |
| 201 class LGoto: public LTemplateInstruction<0> { |
| 202 public: |
| 203 LGoto(int block_id, bool include_stack_check = false) |
| 204 : block_id_(block_id), include_stack_check_(include_stack_check) { } |
| 205 |
| 206 DECLARE_CONCRETE_INSTRUCTION(Goto, "goto") |
| 207 virtual void PrintDataTo(StringStream* stream); |
| 208 virtual bool IsControl() const { return true; } |
| 209 |
| 210 int block_id() const { return block_id_; } |
| 211 bool include_stack_check() const { return include_stack_check_; } |
| 212 |
| 213 private: |
| 214 int block_id_; |
| 215 bool include_stack_check_; |
| 216 }; |
| 217 |
| 218 |
| 219 class LLazyBailout: public LTemplateInstruction<0> { |
| 220 public: |
| 221 LLazyBailout() : gap_instructions_size_(0) { } |
| 222 |
| 223 DECLARE_CONCRETE_INSTRUCTION(LazyBailout, "lazy-bailout") |
| 224 |
| 225 void set_gap_instructions_size(int gap_instructions_size) { |
| 226 gap_instructions_size_ = gap_instructions_size; |
| 227 } |
| 228 int gap_instructions_size() { return gap_instructions_size_; } |
| 229 |
| 230 private: |
| 231 int gap_instructions_size_; |
| 232 }; |
| 233 |
| 234 |
| 235 class LDeoptimize: public LTemplateInstruction<0> { |
| 236 public: |
| 237 DECLARE_CONCRETE_INSTRUCTION(Deoptimize, "deoptimize") |
| 238 }; |
| 239 |
| 240 |
179 class LLabel: public LGap { | 241 class LLabel: public LGap { |
180 public: | 242 public: |
181 explicit LLabel(HBasicBlock* block) : LGap(block) { } | 243 explicit LLabel(HBasicBlock* block) |
| 244 : LGap(block), replacement_(NULL) { } |
| 245 |
| 246 DECLARE_CONCRETE_INSTRUCTION(Label, "label") |
| 247 |
| 248 virtual void PrintDataTo(StringStream* stream); |
| 249 |
| 250 int block_id() const { return block()->block_id(); } |
| 251 bool is_loop_header() const { return block()->IsLoopHeader(); } |
| 252 Label* label() { return &label_; } |
| 253 LLabel* replacement() const { return replacement_; } |
| 254 void set_replacement(LLabel* label) { replacement_ = label; } |
| 255 bool HasReplacement() const { return replacement_ != NULL; } |
182 | 256 |
183 private: | 257 private: |
184 Label label_; | 258 Label label_; |
185 LLabel* replacement_; | 259 LLabel* replacement_; |
186 }; | 260 }; |
187 | 261 |
188 | 262 |
189 class LOsrEntry: public LInstruction { | 263 class LOsrEntry: public LTemplateInstruction<0> { |
190 public: | 264 public: |
191 // Function could be generated by a macro as in lithium-ia32.h. | 265 LOsrEntry(); |
192 static LOsrEntry* cast(LInstruction* instr) { | |
193 UNIMPLEMENTED(); | |
194 return NULL; | |
195 } | |
196 | 266 |
197 LOperand** SpilledRegisterArray() { | 267 DECLARE_CONCRETE_INSTRUCTION(OsrEntry, "osr-entry") |
198 UNIMPLEMENTED(); | |
199 return NULL; | |
200 } | |
201 LOperand** SpilledDoubleRegisterArray() { | |
202 UNIMPLEMENTED(); | |
203 return NULL; | |
204 } | |
205 | 268 |
206 void MarkSpilledRegister(int allocation_index, LOperand* spill_operand) { | 269 LOperand** SpilledRegisterArray() { return register_spills_; } |
207 UNIMPLEMENTED(); | 270 LOperand** SpilledDoubleRegisterArray() { return double_register_spills_; } |
208 } | 271 |
| 272 void MarkSpilledRegister(int allocation_index, LOperand* spill_operand); |
209 void MarkSpilledDoubleRegister(int allocation_index, | 273 void MarkSpilledDoubleRegister(int allocation_index, |
210 LOperand* spill_operand) { | 274 LOperand* spill_operand); |
211 UNIMPLEMENTED(); | |
212 } | |
213 | 275 |
214 private: | 276 private: |
215 // Arrays of spill slot operands for registers with an assigned spill | 277 // Arrays of spill slot operands for registers with an assigned spill |
216 // slot, i.e., that must also be restored to the spill slot on OSR entry. | 278 // slot, i.e., that must also be restored to the spill slot on OSR entry. |
217 // NULL if the register has no assigned spill slot. Indexed by allocation | 279 // NULL if the register has no assigned spill slot. Indexed by allocation |
218 // index. | 280 // index. |
219 LOperand* register_spills_[Register::kNumAllocatableRegisters]; | 281 LOperand* register_spills_[Register::kNumAllocatableRegisters]; |
220 LOperand* double_register_spills_[DoubleRegister::kNumAllocatableRegisters]; | 282 LOperand* double_register_spills_[DoubleRegister::kNumAllocatableRegisters]; |
221 }; | 283 }; |
222 | 284 |
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
418 LInstruction* instructions_pending_deoptimization_environment_; | 480 LInstruction* instructions_pending_deoptimization_environment_; |
419 int pending_deoptimization_ast_id_; | 481 int pending_deoptimization_ast_id_; |
420 | 482 |
421 DISALLOW_COPY_AND_ASSIGN(LChunkBuilder); | 483 DISALLOW_COPY_AND_ASSIGN(LChunkBuilder); |
422 }; | 484 }; |
423 | 485 |
424 | 486 |
425 } } // namespace v8::internal | 487 } } // namespace v8::internal |
426 | 488 |
427 #endif // V8_X64_LITHIUM_X64_H_ | 489 #endif // V8_X64_LITHIUM_X64_H_ |
OLD | NEW |