Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(359)

Side by Side Diff: src/arm/lithium-arm.h

Issue 6529032: Merge 6168:6800 from bleeding_edge to experimental/gc branch. (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/gc/
Patch Set: Created 9 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/arm/jump-target-arm.cc ('k') | src/arm/lithium-arm.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 11 matching lines...) Expand all
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 27
28 #ifndef V8_ARM_LITHIUM_ARM_H_ 28 #ifndef V8_ARM_LITHIUM_ARM_H_
29 #define V8_ARM_LITHIUM_ARM_H_ 29 #define V8_ARM_LITHIUM_ARM_H_
30 30
31 #include "hydrogen.h" 31 #include "hydrogen.h"
32 #include "lithium-allocator.h" 32 #include "lithium-allocator.h"
33 #include "lithium.h"
33 #include "safepoint-table.h" 34 #include "safepoint-table.h"
34 35
35 namespace v8 { 36 namespace v8 {
36 namespace internal { 37 namespace internal {
37 38
38 // Forward declarations. 39 // Forward declarations.
39 class LCodeGen; 40 class LCodeGen;
40 class LEnvironment;
41 class Translation;
42
43
44 // Type hierarchy:
45 //
46 // LInstruction
47 // LAccessArgumentsAt
48 // LArgumentsElements
49 // LArgumentsLength
50 // LBinaryOperation
51 // LAddI
52 // LApplyArguments
53 // LArithmeticD
54 // LArithmeticT
55 // LBitI
56 // LBoundsCheck
57 // LCmpID
58 // LCmpIDAndBranch
59 // LCmpJSObjectEq
60 // LCmpJSObjectEqAndBranch
61 // LCmpT
62 // LDivI
63 // LInstanceOf
64 // LInstanceOfAndBranch
65 // LLoadKeyedFastElement
66 // LLoadKeyedGeneric
67 // LModI
68 // LMulI
69 // LShiftI
70 // LSubI
71 // LCallConstantFunction
72 // LCallFunction
73 // LCallGlobal
74 // LCallKeyed
75 // LCallKnownGlobal
76 // LCallNamed
77 // LCallRuntime
78 // LCallStub
79 // LConstant
80 // LConstantD
81 // LConstantI
82 // LConstantT
83 // LDeoptimize
84 // LFunctionLiteral
85 // LGlobalObject
86 // LGlobalReceiver
87 // LLabel
88 // LLayzBailout
89 // LLoadGlobal
90 // LMaterializedLiteral
91 // LArrayLiteral
92 // LObjectLiteral
93 // LRegExpLiteral
94 // LOsrEntry
95 // LParameter
96 // LStackCheck
97 // LStoreKeyed
98 // LStoreKeyedFastElement
99 // LStoreKeyedGeneric
100 // LStoreNamed
101 // LStoreNamedField
102 // LStoreNamedGeneric
103 // LUnaryOperation
104 // LJSArrayLength
105 // LFixedArrayLength
106 // LBitNotI
107 // LBranch
108 // LCallNew
109 // LCheckFunction
110 // LCheckInstanceType
111 // LCheckMap
112 // LCheckPrototypeMaps
113 // LCheckSmi
114 // LClassOfTest
115 // LClassOfTestAndBranch
116 // LDeleteProperty
117 // LDoubleToI
118 // LHasCachedArrayIndex
119 // LHasCachedArrayIndexAndBranch
120 // LHasInstanceType
121 // LHasInstanceTypeAndBranch
122 // LInteger32ToDouble
123 // LIsNull
124 // LIsNullAndBranch
125 // LIsObject
126 // LIsObjectAndBranch
127 // LIsSmi
128 // LIsSmiAndBranch
129 // LLoadNamedField
130 // LLoadNamedGeneric
131 // LLoadFunctionPrototype
132 // LNumberTagD
133 // LNumberTagI
134 // LPushArgument
135 // LReturn
136 // LSmiTag
137 // LStoreGlobal
138 // LTaggedToI
139 // LThrow
140 // LTypeof
141 // LTypeofIs
142 // LTypeofIsAndBranch
143 // LUnaryMathOperation
144 // LValueOf
145 // LUnknownOSRValue
146 41
147 #define LITHIUM_ALL_INSTRUCTION_LIST(V) \ 42 #define LITHIUM_ALL_INSTRUCTION_LIST(V) \
148 V(BinaryOperation) \ 43 V(ControlInstruction) \
149 V(Constant) \
150 V(Call) \ 44 V(Call) \
151 V(MaterializedLiteral) \
152 V(StoreKeyed) \ 45 V(StoreKeyed) \
153 V(StoreNamed) \ 46 V(StoreNamed) \
154 V(UnaryOperation) \
155 LITHIUM_CONCRETE_INSTRUCTION_LIST(V) 47 LITHIUM_CONCRETE_INSTRUCTION_LIST(V)
156 48
157 49
158 #define LITHIUM_CONCRETE_INSTRUCTION_LIST(V) \ 50 #define LITHIUM_CONCRETE_INSTRUCTION_LIST(V) \
159 V(AccessArgumentsAt) \ 51 V(AccessArgumentsAt) \
160 V(AddI) \ 52 V(AddI) \
161 V(ApplyArguments) \ 53 V(ApplyArguments) \
162 V(ArgumentsElements) \ 54 V(ArgumentsElements) \
163 V(ArgumentsLength) \ 55 V(ArgumentsLength) \
164 V(ArithmeticD) \ 56 V(ArithmeticD) \
(...skipping 10 matching lines...) Expand all
175 V(CallKnownGlobal) \ 67 V(CallKnownGlobal) \
176 V(CallNamed) \ 68 V(CallNamed) \
177 V(CallNew) \ 69 V(CallNew) \
178 V(CallRuntime) \ 70 V(CallRuntime) \
179 V(CallStub) \ 71 V(CallStub) \
180 V(CheckFunction) \ 72 V(CheckFunction) \
181 V(CheckInstanceType) \ 73 V(CheckInstanceType) \
182 V(CheckMap) \ 74 V(CheckMap) \
183 V(CheckPrototypeMaps) \ 75 V(CheckPrototypeMaps) \
184 V(CheckSmi) \ 76 V(CheckSmi) \
77 V(ClassOfTest) \
78 V(ClassOfTestAndBranch) \
185 V(CmpID) \ 79 V(CmpID) \
186 V(CmpIDAndBranch) \ 80 V(CmpIDAndBranch) \
187 V(CmpJSObjectEq) \ 81 V(CmpJSObjectEq) \
188 V(CmpJSObjectEqAndBranch) \ 82 V(CmpJSObjectEqAndBranch) \
189 V(CmpMapAndBranch) \ 83 V(CmpMapAndBranch) \
190 V(CmpT) \ 84 V(CmpT) \
191 V(CmpTAndBranch) \ 85 V(CmpTAndBranch) \
192 V(ConstantD) \ 86 V(ConstantD) \
193 V(ConstantI) \ 87 V(ConstantI) \
194 V(ConstantT) \ 88 V(ConstantT) \
89 V(Context) \
195 V(DeleteProperty) \ 90 V(DeleteProperty) \
196 V(Deoptimize) \ 91 V(Deoptimize) \
197 V(DivI) \ 92 V(DivI) \
198 V(DoubleToI) \ 93 V(DoubleToI) \
199 V(FixedArrayLength) \ 94 V(FixedArrayLength) \
200 V(FunctionLiteral) \ 95 V(FunctionLiteral) \
201 V(Gap) \ 96 V(Gap) \
202 V(GlobalObject) \ 97 V(GlobalObject) \
203 V(GlobalReceiver) \ 98 V(GlobalReceiver) \
204 V(Goto) \ 99 V(Goto) \
100 V(HasCachedArrayIndex) \
101 V(HasCachedArrayIndexAndBranch) \
102 V(HasInstanceType) \
103 V(HasInstanceTypeAndBranch) \
205 V(InstanceOf) \ 104 V(InstanceOf) \
206 V(InstanceOfAndBranch) \ 105 V(InstanceOfAndBranch) \
106 V(InstanceOfKnownGlobal) \
207 V(Integer32ToDouble) \ 107 V(Integer32ToDouble) \
208 V(IsNull) \ 108 V(IsNull) \
209 V(IsNullAndBranch) \ 109 V(IsNullAndBranch) \
210 V(IsObject) \ 110 V(IsObject) \
211 V(IsObjectAndBranch) \ 111 V(IsObjectAndBranch) \
212 V(IsSmi) \ 112 V(IsSmi) \
213 V(IsSmiAndBranch) \ 113 V(IsSmiAndBranch) \
214 V(JSArrayLength) \ 114 V(JSArrayLength) \
215 V(HasInstanceType) \
216 V(HasInstanceTypeAndBranch) \
217 V(HasCachedArrayIndex) \
218 V(HasCachedArrayIndexAndBranch) \
219 V(ClassOfTest) \
220 V(ClassOfTestAndBranch) \
221 V(Label) \ 115 V(Label) \
222 V(LazyBailout) \ 116 V(LazyBailout) \
117 V(LoadContextSlot) \
223 V(LoadElements) \ 118 V(LoadElements) \
119 V(LoadFunctionPrototype) \
224 V(LoadGlobal) \ 120 V(LoadGlobal) \
225 V(LoadKeyedFastElement) \ 121 V(LoadKeyedFastElement) \
226 V(LoadKeyedGeneric) \ 122 V(LoadKeyedGeneric) \
227 V(LoadNamedField) \ 123 V(LoadNamedField) \
228 V(LoadNamedGeneric) \ 124 V(LoadNamedGeneric) \
229 V(LoadFunctionPrototype) \ 125 V(LoadPixelArrayElement) \
126 V(LoadPixelArrayExternalPointer) \
230 V(ModI) \ 127 V(ModI) \
231 V(MulI) \ 128 V(MulI) \
232 V(NumberTagD) \ 129 V(NumberTagD) \
233 V(NumberTagI) \ 130 V(NumberTagI) \
234 V(NumberUntagD) \ 131 V(NumberUntagD) \
235 V(ObjectLiteral) \ 132 V(ObjectLiteral) \
236 V(OsrEntry) \ 133 V(OsrEntry) \
134 V(OuterContext) \
237 V(Parameter) \ 135 V(Parameter) \
136 V(PixelArrayLength) \
238 V(PushArgument) \ 137 V(PushArgument) \
239 V(RegExpLiteral) \ 138 V(RegExpLiteral) \
240 V(Return) \ 139 V(Return) \
241 V(ShiftI) \ 140 V(ShiftI) \
242 V(SmiTag) \ 141 V(SmiTag) \
243 V(SmiUntag) \ 142 V(SmiUntag) \
244 V(StackCheck) \ 143 V(StackCheck) \
144 V(StoreContextSlot) \
245 V(StoreGlobal) \ 145 V(StoreGlobal) \
246 V(StoreKeyedFastElement) \ 146 V(StoreKeyedFastElement) \
247 V(StoreKeyedGeneric) \ 147 V(StoreKeyedGeneric) \
248 V(StoreNamedField) \ 148 V(StoreNamedField) \
249 V(StoreNamedGeneric) \ 149 V(StoreNamedGeneric) \
150 V(StringCharCodeAt) \
151 V(StringLength) \
250 V(SubI) \ 152 V(SubI) \
251 V(TaggedToI) \ 153 V(TaggedToI) \
252 V(Throw) \ 154 V(Throw) \
253 V(Typeof) \ 155 V(Typeof) \
254 V(TypeofIs) \ 156 V(TypeofIs) \
255 V(TypeofIsAndBranch) \ 157 V(TypeofIsAndBranch) \
158 V(IsConstructCall) \
159 V(IsConstructCallAndBranch) \
256 V(UnaryMathOperation) \ 160 V(UnaryMathOperation) \
257 V(UnknownOSRValue) \ 161 V(UnknownOSRValue) \
258 V(ValueOf) 162 V(ValueOf)
259 163
260 164
261 #define DECLARE_INSTRUCTION(type) \ 165 #define DECLARE_INSTRUCTION(type) \
262 virtual bool Is##type() const { return true; } \ 166 virtual bool Is##type() const { return true; } \
263 static L##type* cast(LInstruction* instr) { \ 167 static L##type* cast(LInstruction* instr) { \
264 ASSERT(instr->Is##type()); \ 168 ASSERT(instr->Is##type()); \
265 return reinterpret_cast<L##type*>(instr); \ 169 return reinterpret_cast<L##type*>(instr); \
266 } 170 }
267 171
268 172
269 #define DECLARE_CONCRETE_INSTRUCTION(type, mnemonic) \ 173 #define DECLARE_CONCRETE_INSTRUCTION(type, mnemonic) \
270 virtual void CompileToNative(LCodeGen* generator); \ 174 virtual void CompileToNative(LCodeGen* generator); \
271 virtual const char* Mnemonic() const { return mnemonic; } \ 175 virtual const char* Mnemonic() const { return mnemonic; } \
272 DECLARE_INSTRUCTION(type) 176 DECLARE_INSTRUCTION(type)
273 177
274 178
275 #define DECLARE_HYDROGEN_ACCESSOR(type) \ 179 #define DECLARE_HYDROGEN_ACCESSOR(type) \
276 H##type* hydrogen() const { \ 180 H##type* hydrogen() const { \
277 return H##type::cast(hydrogen_value()); \ 181 return H##type::cast(hydrogen_value()); \
278 } 182 }
279 183
280 184
281 class LInstruction: public ZoneObject { 185 class LInstruction: public ZoneObject {
282 public: 186 public:
283 LInstruction() 187 LInstruction()
284 : hydrogen_value_(NULL) { } 188 : environment_(NULL),
189 hydrogen_value_(NULL),
190 is_call_(false),
191 is_save_doubles_(false) { }
285 virtual ~LInstruction() { } 192 virtual ~LInstruction() { }
286 193
287 virtual void CompileToNative(LCodeGen* generator) = 0; 194 virtual void CompileToNative(LCodeGen* generator) = 0;
288 virtual const char* Mnemonic() const = 0; 195 virtual const char* Mnemonic() const = 0;
289 virtual void PrintTo(StringStream* stream) const; 196 virtual void PrintTo(StringStream* stream);
290 virtual void PrintDataTo(StringStream* stream) const { } 197 virtual void PrintDataTo(StringStream* stream) = 0;
198 virtual void PrintOutputOperandTo(StringStream* stream) = 0;
291 199
292 // Declare virtual type testers. 200 // Declare virtual type testers.
293 #define DECLARE_DO(type) virtual bool Is##type() const { return false; } 201 #define DECLARE_DO(type) virtual bool Is##type() const { return false; }
294 LITHIUM_ALL_INSTRUCTION_LIST(DECLARE_DO) 202 LITHIUM_ALL_INSTRUCTION_LIST(DECLARE_DO)
295 #undef DECLARE_DO 203 #undef DECLARE_DO
204
296 virtual bool IsControl() const { return false; } 205 virtual bool IsControl() const { return false; }
206 virtual void SetBranchTargets(int true_block_id, int false_block_id) { }
297 207
298 void set_environment(LEnvironment* env) { environment_.set(env); } 208 void set_environment(LEnvironment* env) { environment_ = env; }
299 LEnvironment* environment() const { return environment_.get(); } 209 LEnvironment* environment() const { return environment_; }
300 bool HasEnvironment() const { return environment_.is_set(); } 210 bool HasEnvironment() const { return environment_ != NULL; }
301 211
302 void set_pointer_map(LPointerMap* p) { pointer_map_.set(p); } 212 void set_pointer_map(LPointerMap* p) { pointer_map_.set(p); }
303 LPointerMap* pointer_map() const { return pointer_map_.get(); } 213 LPointerMap* pointer_map() const { return pointer_map_.get(); }
304 bool HasPointerMap() const { return pointer_map_.is_set(); } 214 bool HasPointerMap() const { return pointer_map_.is_set(); }
305 215
306 void set_result(LOperand* operand) { result_.set(operand); }
307 LOperand* result() const { return result_.get(); }
308 bool HasResult() const { return result_.is_set(); }
309
310 void set_hydrogen_value(HValue* value) { hydrogen_value_ = value; } 216 void set_hydrogen_value(HValue* value) { hydrogen_value_ = value; }
311 HValue* hydrogen_value() const { return hydrogen_value_; } 217 HValue* hydrogen_value() const { return hydrogen_value_; }
312 218
313 void set_deoptimization_environment(LEnvironment* env) { 219 void set_deoptimization_environment(LEnvironment* env) {
314 deoptimization_environment_.set(env); 220 deoptimization_environment_.set(env);
315 } 221 }
316 LEnvironment* deoptimization_environment() const { 222 LEnvironment* deoptimization_environment() const {
317 return deoptimization_environment_.get(); 223 return deoptimization_environment_.get();
318 } 224 }
319 bool HasDeoptimizationEnvironment() const { 225 bool HasDeoptimizationEnvironment() const {
320 return deoptimization_environment_.is_set(); 226 return deoptimization_environment_.is_set();
321 } 227 }
322 228
229 void MarkAsCall() { is_call_ = true; }
230 void MarkAsSaveDoubles() { is_save_doubles_ = true; }
231
232 // Interface to the register allocator and iterators.
233 bool IsMarkedAsCall() const { return is_call_; }
234 bool IsMarkedAsSaveDoubles() const { return is_save_doubles_; }
235
236 virtual bool HasResult() const = 0;
237 virtual LOperand* result() = 0;
238
239 virtual int InputCount() = 0;
240 virtual LOperand* InputAt(int i) = 0;
241 virtual int TempCount() = 0;
242 virtual LOperand* TempAt(int i) = 0;
243
244 LOperand* FirstInput() { return InputAt(0); }
245 LOperand* Output() { return HasResult() ? result() : NULL; }
246
247 #ifdef DEBUG
248 void VerifyCall();
249 #endif
250
323 private: 251 private:
324 SetOncePointer<LEnvironment> environment_; 252 LEnvironment* environment_;
325 SetOncePointer<LPointerMap> pointer_map_; 253 SetOncePointer<LPointerMap> pointer_map_;
326 SetOncePointer<LOperand> result_;
327 HValue* hydrogen_value_; 254 HValue* hydrogen_value_;
328 SetOncePointer<LEnvironment> deoptimization_environment_; 255 SetOncePointer<LEnvironment> deoptimization_environment_;
256 bool is_call_;
257 bool is_save_doubles_;
329 }; 258 };
330 259
331 260
332 class LGapNode; 261 template<typename ElementType, int NumElements>
333 262 class OperandContainer {
334
335 class LGapResolver BASE_EMBEDDED {
336 public: 263 public:
337 LGapResolver(const ZoneList<LMoveOperands>* moves, LOperand* marker_operand); 264 OperandContainer() {
338 const ZoneList<LMoveOperands>* ResolveInReverseOrder(); 265 for (int i = 0; i < NumElements; i++) elems_[i] = NULL;
266 }
267 int length() { return NumElements; }
268 ElementType& operator[](int i) {
269 ASSERT(i < length());
270 return elems_[i];
271 }
272 void PrintOperandsTo(StringStream* stream);
339 273
340 private: 274 private:
341 LGapNode* LookupNode(LOperand* operand); 275 ElementType elems_[NumElements];
342 bool CanReach(LGapNode* a, LGapNode* b, int visited_id);
343 bool CanReach(LGapNode* a, LGapNode* b);
344 void RegisterMove(LMoveOperands move);
345 void AddResultMove(LOperand* from, LOperand* to);
346 void AddResultMove(LGapNode* from, LGapNode* to);
347 void ResolveCycle(LGapNode* start);
348
349 ZoneList<LGapNode*> nodes_;
350 ZoneList<LGapNode*> identified_cycles_;
351 ZoneList<LMoveOperands> result_;
352 LOperand* marker_operand_;
353 int next_visited_id_;
354 int bailout_after_ast_id_;
355 }; 276 };
356 277
357 278
358 class LParallelMove : public ZoneObject { 279 template<typename ElementType>
280 class OperandContainer<ElementType, 0> {
359 public: 281 public:
360 LParallelMove() : move_operands_(4) { } 282 int length() { return 0; }
361 283 void PrintOperandsTo(StringStream* stream) { }
362 void AddMove(LOperand* from, LOperand* to) { 284 ElementType& operator[](int i) {
363 move_operands_.Add(LMoveOperands(from, to)); 285 UNREACHABLE();
286 static ElementType t = 0;
287 return t;
364 } 288 }
365
366 bool IsRedundant() const;
367
368 const ZoneList<LMoveOperands>* move_operands() const {
369 return &move_operands_;
370 }
371
372 void PrintDataTo(StringStream* stream) const;
373
374 private:
375 ZoneList<LMoveOperands> move_operands_;
376 }; 289 };
377 290
378 291
379 class LGap: public LInstruction { 292 // R = number of result operands (0 or 1).
293 // I = number of input operands.
294 // T = number of temporary operands.
295 template<int R, int I, int T>
296 class LTemplateInstruction: public LInstruction {
297 public:
298 // Allow 0 or 1 output operands.
299 STATIC_ASSERT(R == 0 || R == 1);
300 virtual bool HasResult() const { return R != 0; }
301 void set_result(LOperand* operand) { results_[0] = operand; }
302 LOperand* result() { return results_[0]; }
303
304 int InputCount() { return I; }
305 LOperand* InputAt(int i) { return inputs_[i]; }
306
307 int TempCount() { return T; }
308 LOperand* TempAt(int i) { return temps_[i]; }
309
310 virtual void PrintDataTo(StringStream* stream);
311 virtual void PrintOutputOperandTo(StringStream* stream);
312
313 protected:
314 OperandContainer<LOperand*, R> results_;
315 OperandContainer<LOperand*, I> inputs_;
316 OperandContainer<LOperand*, T> temps_;
317 };
318
319
320 class LGap: public LTemplateInstruction<0, 0, 0> {
380 public: 321 public:
381 explicit LGap(HBasicBlock* block) 322 explicit LGap(HBasicBlock* block)
382 : block_(block) { 323 : block_(block) {
383 parallel_moves_[BEFORE] = NULL; 324 parallel_moves_[BEFORE] = NULL;
384 parallel_moves_[START] = NULL; 325 parallel_moves_[START] = NULL;
385 parallel_moves_[END] = NULL; 326 parallel_moves_[END] = NULL;
386 parallel_moves_[AFTER] = NULL; 327 parallel_moves_[AFTER] = NULL;
387 } 328 }
388 329
389 DECLARE_CONCRETE_INSTRUCTION(Gap, "gap") 330 DECLARE_CONCRETE_INSTRUCTION(Gap, "gap")
(...skipping 20 matching lines...) Expand all
410 LParallelMove* GetParallelMove(InnerPosition pos) { 351 LParallelMove* GetParallelMove(InnerPosition pos) {
411 return parallel_moves_[pos]; 352 return parallel_moves_[pos];
412 } 353 }
413 354
414 private: 355 private:
415 LParallelMove* parallel_moves_[LAST_INNER_POSITION + 1]; 356 LParallelMove* parallel_moves_[LAST_INNER_POSITION + 1];
416 HBasicBlock* block_; 357 HBasicBlock* block_;
417 }; 358 };
418 359
419 360
420 class LGoto: public LInstruction { 361 class LGoto: public LTemplateInstruction<0, 0, 0> {
421 public: 362 public:
422 LGoto(int block_id, bool include_stack_check = false) 363 LGoto(int block_id, bool include_stack_check = false)
423 : block_id_(block_id), include_stack_check_(include_stack_check) { } 364 : block_id_(block_id), include_stack_check_(include_stack_check) { }
424 365
425 DECLARE_CONCRETE_INSTRUCTION(Goto, "goto") 366 DECLARE_CONCRETE_INSTRUCTION(Goto, "goto")
426 virtual void PrintDataTo(StringStream* stream) const; 367 virtual void PrintDataTo(StringStream* stream);
427 virtual bool IsControl() const { return true; } 368 virtual bool IsControl() const { return true; }
428 369
429 int block_id() const { return block_id_; } 370 int block_id() const { return block_id_; }
430 bool include_stack_check() const { return include_stack_check_; } 371 bool include_stack_check() const { return include_stack_check_; }
431 372
432 private: 373 private:
433 int block_id_; 374 int block_id_;
434 bool include_stack_check_; 375 bool include_stack_check_;
435 }; 376 };
436 377
437 378
438 class LLazyBailout: public LInstruction { 379 class LLazyBailout: public LTemplateInstruction<0, 0, 0> {
439 public: 380 public:
440 LLazyBailout() : gap_instructions_size_(0) { } 381 LLazyBailout() : gap_instructions_size_(0) { }
441 382
442 DECLARE_CONCRETE_INSTRUCTION(LazyBailout, "lazy-bailout") 383 DECLARE_CONCRETE_INSTRUCTION(LazyBailout, "lazy-bailout")
443 384
444 void set_gap_instructions_size(int gap_instructions_size) { 385 void set_gap_instructions_size(int gap_instructions_size) {
445 gap_instructions_size_ = gap_instructions_size; 386 gap_instructions_size_ = gap_instructions_size;
446 } 387 }
447 int gap_instructions_size() { return gap_instructions_size_; } 388 int gap_instructions_size() { return gap_instructions_size_; }
448 389
449 private: 390 private:
450 int gap_instructions_size_; 391 int gap_instructions_size_;
451 }; 392 };
452 393
453 394
454 class LDeoptimize: public LInstruction { 395 class LDeoptimize: public LTemplateInstruction<0, 0, 0> {
455 public: 396 public:
456 DECLARE_CONCRETE_INSTRUCTION(Deoptimize, "deoptimize") 397 DECLARE_CONCRETE_INSTRUCTION(Deoptimize, "deoptimize")
457 }; 398 };
458 399
459 400
460 class LLabel: public LGap { 401 class LLabel: public LGap {
461 public: 402 public:
462 explicit LLabel(HBasicBlock* block) 403 explicit LLabel(HBasicBlock* block)
463 : LGap(block), replacement_(NULL) { } 404 : LGap(block), replacement_(NULL) { }
464 405
465 DECLARE_CONCRETE_INSTRUCTION(Label, "label") 406 DECLARE_CONCRETE_INSTRUCTION(Label, "label")
466 407
467 virtual void PrintDataTo(StringStream* stream) const; 408 virtual void PrintDataTo(StringStream* stream);
468 409
469 int block_id() const { return block()->block_id(); } 410 int block_id() const { return block()->block_id(); }
470 bool is_loop_header() const { return block()->IsLoopHeader(); } 411 bool is_loop_header() const { return block()->IsLoopHeader(); }
471 Label* label() { return &label_; } 412 Label* label() { return &label_; }
472 LLabel* replacement() const { return replacement_; } 413 LLabel* replacement() const { return replacement_; }
473 void set_replacement(LLabel* label) { replacement_ = label; } 414 void set_replacement(LLabel* label) { replacement_ = label; }
474 bool HasReplacement() const { return replacement_ != NULL; } 415 bool HasReplacement() const { return replacement_ != NULL; }
475 416
476 private: 417 private:
477 Label label_; 418 Label label_;
478 LLabel* replacement_; 419 LLabel* replacement_;
479 }; 420 };
480 421
481 422
482 class LParameter: public LInstruction { 423 class LParameter: public LTemplateInstruction<1, 0, 0> {
483 public: 424 public:
484 DECLARE_CONCRETE_INSTRUCTION(Parameter, "parameter") 425 DECLARE_CONCRETE_INSTRUCTION(Parameter, "parameter")
485 }; 426 };
486 427
487 428
488 class LCallStub: public LInstruction { 429 class LCallStub: public LTemplateInstruction<1, 0, 0> {
489 public: 430 public:
490 DECLARE_CONCRETE_INSTRUCTION(CallStub, "call-stub") 431 DECLARE_CONCRETE_INSTRUCTION(CallStub, "call-stub")
491 DECLARE_HYDROGEN_ACCESSOR(CallStub) 432 DECLARE_HYDROGEN_ACCESSOR(CallStub)
433
434 TranscendentalCache::Type transcendental_type() {
435 return hydrogen()->transcendental_type();
436 }
492 }; 437 };
493 438
494 439
495 class LUnknownOSRValue: public LInstruction { 440 class LUnknownOSRValue: public LTemplateInstruction<1, 0, 0> {
496 public: 441 public:
497 DECLARE_CONCRETE_INSTRUCTION(UnknownOSRValue, "unknown-osr-value") 442 DECLARE_CONCRETE_INSTRUCTION(UnknownOSRValue, "unknown-osr-value")
498 }; 443 };
499 444
500 445
501 class LUnaryOperation: public LInstruction { 446 template<int I, int T>
447 class LControlInstruction: public LTemplateInstruction<0, I, T> {
502 public: 448 public:
503 explicit LUnaryOperation(LOperand* input) : input_(input) { } 449 DECLARE_INSTRUCTION(ControlInstruction)
450 virtual bool IsControl() const { return true; }
504 451
505 DECLARE_INSTRUCTION(UnaryOperation) 452 int true_block_id() const { return true_block_id_; }
506 453 int false_block_id() const { return false_block_id_; }
507 LOperand* input() const { return input_; } 454 void SetBranchTargets(int true_block_id, int false_block_id) {
508 455 true_block_id_ = true_block_id;
509 virtual void PrintDataTo(StringStream* stream) const; 456 false_block_id_ = false_block_id;
457 }
510 458
511 private: 459 private:
512 LOperand* input_; 460 int true_block_id_;
461 int false_block_id_;
513 }; 462 };
514 463
515 464
516 class LBinaryOperation: public LInstruction { 465 class LApplyArguments: public LTemplateInstruction<1, 4, 0> {
517 public:
518 LBinaryOperation(LOperand* left, LOperand* right)
519 : left_(left), right_(right) { }
520
521 DECLARE_INSTRUCTION(BinaryOperation)
522
523 LOperand* left() const { return left_; }
524 LOperand* right() const { return right_; }
525 virtual void PrintDataTo(StringStream* stream) const;
526
527 private:
528 LOperand* left_;
529 LOperand* right_;
530 };
531
532
533 class LApplyArguments: public LBinaryOperation {
534 public: 466 public:
535 LApplyArguments(LOperand* function, 467 LApplyArguments(LOperand* function,
536 LOperand* receiver, 468 LOperand* receiver,
537 LOperand* length, 469 LOperand* length,
538 LOperand* elements) 470 LOperand* elements) {
539 : LBinaryOperation(function, receiver), 471 inputs_[0] = function;
540 length_(length), 472 inputs_[1] = receiver;
541 elements_(elements) { } 473 inputs_[2] = length;
474 inputs_[3] = elements;
475 }
542 476
543 DECLARE_CONCRETE_INSTRUCTION(ApplyArguments, "apply-arguments") 477 DECLARE_CONCRETE_INSTRUCTION(ApplyArguments, "apply-arguments")
544 478
545 LOperand* function() const { return left(); } 479 LOperand* function() { return inputs_[0]; }
546 LOperand* receiver() const { return right(); } 480 LOperand* receiver() { return inputs_[1]; }
547 LOperand* length() const { return length_; } 481 LOperand* length() { return inputs_[2]; }
548 LOperand* elements() const { return elements_; } 482 LOperand* elements() { return inputs_[3]; }
549
550 private:
551 LOperand* length_;
552 LOperand* elements_;
553 }; 483 };
554 484
555 485
556 class LAccessArgumentsAt: public LInstruction { 486 class LAccessArgumentsAt: public LTemplateInstruction<1, 3, 0> {
557 public: 487 public:
558 LAccessArgumentsAt(LOperand* arguments, LOperand* length, LOperand* index) 488 LAccessArgumentsAt(LOperand* arguments, LOperand* length, LOperand* index) {
559 : arguments_(arguments), length_(length), index_(index) { } 489 inputs_[0] = arguments;
490 inputs_[1] = length;
491 inputs_[2] = index;
492 }
560 493
561 DECLARE_CONCRETE_INSTRUCTION(AccessArgumentsAt, "access-arguments-at") 494 DECLARE_CONCRETE_INSTRUCTION(AccessArgumentsAt, "access-arguments-at")
562 495
563 LOperand* arguments() const { return arguments_; } 496 LOperand* arguments() { return inputs_[0]; }
564 LOperand* length() const { return length_; } 497 LOperand* length() { return inputs_[1]; }
565 LOperand* index() const { return index_; } 498 LOperand* index() { return inputs_[2]; }
566 499
567 virtual void PrintDataTo(StringStream* stream) const; 500 virtual void PrintDataTo(StringStream* stream);
568
569 private:
570 LOperand* arguments_;
571 LOperand* length_;
572 LOperand* index_;
573 }; 501 };
574 502
575 503
576 class LArgumentsLength: public LUnaryOperation { 504 class LArgumentsLength: public LTemplateInstruction<1, 1, 0> {
577 public: 505 public:
578 explicit LArgumentsLength(LOperand* elements) : LUnaryOperation(elements) {} 506 explicit LArgumentsLength(LOperand* elements) {
507 inputs_[0] = elements;
508 }
579 509
580 DECLARE_CONCRETE_INSTRUCTION(ArgumentsLength, "arguments-length") 510 DECLARE_CONCRETE_INSTRUCTION(ArgumentsLength, "arguments-length")
581 }; 511 };
582 512
583 513
584 class LArgumentsElements: public LInstruction { 514 class LArgumentsElements: public LTemplateInstruction<1, 0, 0> {
585 public: 515 public:
586 LArgumentsElements() { } 516 LArgumentsElements() { }
587 517
588 DECLARE_CONCRETE_INSTRUCTION(ArgumentsElements, "arguments-elements") 518 DECLARE_CONCRETE_INSTRUCTION(ArgumentsElements, "arguments-elements")
589 }; 519 };
590 520
591 521
592 class LModI: public LBinaryOperation { 522 class LModI: public LTemplateInstruction<1, 2, 0> {
593 public: 523 public:
594 LModI(LOperand* left, LOperand* right) : LBinaryOperation(left, right) { } 524 LModI(LOperand* left, LOperand* right) {
525 inputs_[0] = left;
526 inputs_[1] = right;
527 }
595 528
596 DECLARE_CONCRETE_INSTRUCTION(ModI, "mod-i") 529 DECLARE_CONCRETE_INSTRUCTION(ModI, "mod-i")
597 DECLARE_HYDROGEN_ACCESSOR(Mod) 530 DECLARE_HYDROGEN_ACCESSOR(Mod)
598 }; 531 };
599 532
600 533
601 class LDivI: public LBinaryOperation { 534 class LDivI: public LTemplateInstruction<1, 2, 0> {
602 public: 535 public:
603 LDivI(LOperand* left, LOperand* right) 536 LDivI(LOperand* left, LOperand* right) {
604 : LBinaryOperation(left, right) { } 537 inputs_[0] = left;
538 inputs_[1] = right;
539 }
605 540
606 DECLARE_CONCRETE_INSTRUCTION(DivI, "div-i") 541 DECLARE_CONCRETE_INSTRUCTION(DivI, "div-i")
607 DECLARE_HYDROGEN_ACCESSOR(Div) 542 DECLARE_HYDROGEN_ACCESSOR(Div)
608 }; 543 };
609 544
610 545
611 class LMulI: public LBinaryOperation { 546 class LMulI: public LTemplateInstruction<1, 2, 1> {
612 public: 547 public:
613 LMulI(LOperand* left, LOperand* right, LOperand* temp) 548 LMulI(LOperand* left, LOperand* right, LOperand* temp) {
614 : LBinaryOperation(left, right), temp_(temp) { } 549 inputs_[0] = left;
550 inputs_[1] = right;
551 temps_[0] = temp;
552 }
615 553
616 DECLARE_CONCRETE_INSTRUCTION(MulI, "mul-i") 554 DECLARE_CONCRETE_INSTRUCTION(MulI, "mul-i")
617 DECLARE_HYDROGEN_ACCESSOR(Mul) 555 DECLARE_HYDROGEN_ACCESSOR(Mul)
618 556 };
619 LOperand* temp() const { return temp_; } 557
620 558
621 private: 559 class LCmpID: public LTemplateInstruction<1, 2, 0> {
622 LOperand* temp_; 560 public:
623 }; 561 LCmpID(LOperand* left, LOperand* right) {
624 562 inputs_[0] = left;
625 563 inputs_[1] = right;
626 class LCmpID: public LBinaryOperation { 564 }
627 public:
628 LCmpID(Token::Value op, LOperand* left, LOperand* right, bool is_double)
629 : LBinaryOperation(left, right), op_(op), is_double_(is_double) { }
630
631 Token::Value op() const { return op_; }
632 bool is_double() const { return is_double_; }
633 565
634 DECLARE_CONCRETE_INSTRUCTION(CmpID, "cmp-id") 566 DECLARE_CONCRETE_INSTRUCTION(CmpID, "cmp-id")
635 567 DECLARE_HYDROGEN_ACCESSOR(Compare)
636 private: 568
637 Token::Value op_; 569 Token::Value op() const { return hydrogen()->token(); }
638 bool is_double_; 570 bool is_double() const {
639 }; 571 return hydrogen()->GetInputRepresentation().IsDouble();
640 572 }
641 573 };
642 class LCmpIDAndBranch: public LCmpID { 574
643 public: 575
644 LCmpIDAndBranch(Token::Value op, 576 class LCmpIDAndBranch: public LControlInstruction<2, 0> {
645 LOperand* left, 577 public:
646 LOperand* right, 578 LCmpIDAndBranch(LOperand* left, LOperand* right) {
647 int true_block_id, 579 inputs_[0] = left;
648 int false_block_id, 580 inputs_[1] = right;
649 bool is_double) 581 }
650 : LCmpID(op, left, right, is_double),
651 true_block_id_(true_block_id),
652 false_block_id_(false_block_id) { }
653 582
654 DECLARE_CONCRETE_INSTRUCTION(CmpIDAndBranch, "cmp-id-and-branch") 583 DECLARE_CONCRETE_INSTRUCTION(CmpIDAndBranch, "cmp-id-and-branch")
655 virtual void PrintDataTo(StringStream* stream) const; 584 DECLARE_HYDROGEN_ACCESSOR(Compare)
656 virtual bool IsControl() const { return true; } 585
657 586 Token::Value op() const { return hydrogen()->token(); }
658 int true_block_id() const { return true_block_id_; } 587 bool is_double() const {
659 int false_block_id() const { return false_block_id_; } 588 return hydrogen()->GetInputRepresentation().IsDouble();
660 589 }
661 private: 590
662 int true_block_id_; 591 virtual void PrintDataTo(StringStream* stream);
663 int false_block_id_; 592 };
664 }; 593
665 594
666 595 class LUnaryMathOperation: public LTemplateInstruction<1, 1, 1> {
667 class LUnaryMathOperation: public LUnaryOperation { 596 public:
668 public: 597 LUnaryMathOperation(LOperand* value, LOperand* temp) {
669 explicit LUnaryMathOperation(LOperand* value) 598 inputs_[0] = value;
670 : LUnaryOperation(value) { } 599 temps_[0] = temp;
600 }
671 601
672 DECLARE_CONCRETE_INSTRUCTION(UnaryMathOperation, "unary-math-operation") 602 DECLARE_CONCRETE_INSTRUCTION(UnaryMathOperation, "unary-math-operation")
673 DECLARE_HYDROGEN_ACCESSOR(UnaryMathOperation) 603 DECLARE_HYDROGEN_ACCESSOR(UnaryMathOperation)
674 604
675 virtual void PrintDataTo(StringStream* stream) const; 605 virtual void PrintDataTo(StringStream* stream);
676 BuiltinFunctionId op() const { return hydrogen()->op(); } 606 BuiltinFunctionId op() const { return hydrogen()->op(); }
677 }; 607 };
678 608
679 609
680 class LCmpJSObjectEq: public LBinaryOperation { 610 class LCmpJSObjectEq: public LTemplateInstruction<1, 2, 0> {
681 public: 611 public:
682 LCmpJSObjectEq(LOperand* left, LOperand* right) 612 LCmpJSObjectEq(LOperand* left, LOperand* right) {
683 : LBinaryOperation(left, right) {} 613 inputs_[0] = left;
614 inputs_[1] = right;
615 }
684 616
685 DECLARE_CONCRETE_INSTRUCTION(CmpJSObjectEq, "cmp-jsobject-eq") 617 DECLARE_CONCRETE_INSTRUCTION(CmpJSObjectEq, "cmp-jsobject-eq")
686 }; 618 };
687 619
688 620
689 class LCmpJSObjectEqAndBranch: public LCmpJSObjectEq { 621 class LCmpJSObjectEqAndBranch: public LControlInstruction<2, 0> {
690 public: 622 public:
691 LCmpJSObjectEqAndBranch(LOperand* left, 623 LCmpJSObjectEqAndBranch(LOperand* left, LOperand* right) {
692 LOperand* right, 624 inputs_[0] = left;
693 int true_block_id, 625 inputs_[1] = right;
694 int false_block_id) 626 }
695 : LCmpJSObjectEq(left, right),
696 true_block_id_(true_block_id),
697 false_block_id_(false_block_id) { }
698 627
699 DECLARE_CONCRETE_INSTRUCTION(CmpJSObjectEqAndBranch, 628 DECLARE_CONCRETE_INSTRUCTION(CmpJSObjectEqAndBranch,
700 "cmp-jsobject-eq-and-branch") 629 "cmp-jsobject-eq-and-branch")
701 630 };
702 int true_block_id() const { return true_block_id_; } 631
703 int false_block_id() const { return false_block_id_; } 632
704 633 class LIsNull: public LTemplateInstruction<1, 1, 0> {
705 private: 634 public:
706 int true_block_id_; 635 explicit LIsNull(LOperand* value) {
707 int false_block_id_; 636 inputs_[0] = value;
708 }; 637 }
709
710
711 class LIsNull: public LUnaryOperation {
712 public:
713 LIsNull(LOperand* value, bool is_strict)
714 : LUnaryOperation(value), is_strict_(is_strict) {}
715 638
716 DECLARE_CONCRETE_INSTRUCTION(IsNull, "is-null") 639 DECLARE_CONCRETE_INSTRUCTION(IsNull, "is-null")
717 640 DECLARE_HYDROGEN_ACCESSOR(IsNull)
718 bool is_strict() const { return is_strict_; } 641
719 642 bool is_strict() const { return hydrogen()->is_strict(); }
720 private: 643 };
721 bool is_strict_; 644
722 }; 645 class LIsNullAndBranch: public LControlInstruction<1, 0> {
723 646 public:
724 647 explicit LIsNullAndBranch(LOperand* value) {
725 class LIsNullAndBranch: public LIsNull { 648 inputs_[0] = value;
726 public: 649 }
727 LIsNullAndBranch(LOperand* value,
728 bool is_strict,
729 int true_block_id,
730 int false_block_id)
731 : LIsNull(value, is_strict),
732 true_block_id_(true_block_id),
733 false_block_id_(false_block_id) { }
734 650
735 DECLARE_CONCRETE_INSTRUCTION(IsNullAndBranch, "is-null-and-branch") 651 DECLARE_CONCRETE_INSTRUCTION(IsNullAndBranch, "is-null-and-branch")
736 virtual void PrintDataTo(StringStream* stream) const; 652 DECLARE_HYDROGEN_ACCESSOR(IsNull)
737 virtual bool IsControl() const { return true; } 653
738 654 bool is_strict() const { return hydrogen()->is_strict(); }
739 int true_block_id() const { return true_block_id_; } 655
740 int false_block_id() const { return false_block_id_; } 656 virtual void PrintDataTo(StringStream* stream);
741 657 };
742 private: 658
743 int true_block_id_; 659
744 int false_block_id_; 660 class LIsObject: public LTemplateInstruction<1, 1, 1> {
745 }; 661 public:
746 662 explicit LIsObject(LOperand* value) {
747 663 inputs_[0] = value;
748 class LIsObject: public LUnaryOperation { 664 }
749 public:
750 LIsObject(LOperand* value, LOperand* temp)
751 : LUnaryOperation(value), temp_(temp) {}
752 665
753 DECLARE_CONCRETE_INSTRUCTION(IsObject, "is-object") 666 DECLARE_CONCRETE_INSTRUCTION(IsObject, "is-object")
754 667 };
755 LOperand* temp() const { return temp_; } 668
756 669
757 private: 670 class LIsObjectAndBranch: public LControlInstruction<1, 2> {
758 LOperand* temp_; 671 public:
759 }; 672 LIsObjectAndBranch(LOperand* value, LOperand* temp) {
760 673 inputs_[0] = value;
761 674 temps_[0] = temp;
762 class LIsObjectAndBranch: public LIsObject { 675 }
763 public:
764 LIsObjectAndBranch(LOperand* value,
765 LOperand* temp,
766 LOperand* temp2,
767 int true_block_id,
768 int false_block_id)
769 : LIsObject(value, temp),
770 temp2_(temp2),
771 true_block_id_(true_block_id),
772 false_block_id_(false_block_id) { }
773 676
774 DECLARE_CONCRETE_INSTRUCTION(IsObjectAndBranch, "is-object-and-branch") 677 DECLARE_CONCRETE_INSTRUCTION(IsObjectAndBranch, "is-object-and-branch")
775 virtual void PrintDataTo(StringStream* stream) const; 678
776 virtual bool IsControl() const { return true; } 679 virtual void PrintDataTo(StringStream* stream);
777 680 };
778 int true_block_id() const { return true_block_id_; } 681
779 int false_block_id() const { return false_block_id_; } 682
780 683 class LIsSmi: public LTemplateInstruction<1, 1, 0> {
781 LOperand* temp2() const { return temp2_; } 684 public:
782 685 explicit LIsSmi(LOperand* value) {
783 private: 686 inputs_[0] = value;
784 LOperand* temp2_; 687 }
785 int true_block_id_;
786 int false_block_id_;
787 };
788
789
790 class LIsSmi: public LUnaryOperation {
791 public:
792 explicit LIsSmi(LOperand* value) : LUnaryOperation(value) {}
793 688
794 DECLARE_CONCRETE_INSTRUCTION(IsSmi, "is-smi") 689 DECLARE_CONCRETE_INSTRUCTION(IsSmi, "is-smi")
795 DECLARE_HYDROGEN_ACCESSOR(IsSmi) 690 DECLARE_HYDROGEN_ACCESSOR(IsSmi)
796 }; 691 };
797 692
798 693
799 class LIsSmiAndBranch: public LIsSmi { 694 class LIsSmiAndBranch: public LControlInstruction<1, 0> {
800 public: 695 public:
801 LIsSmiAndBranch(LOperand* value, 696 explicit LIsSmiAndBranch(LOperand* value) {
802 int true_block_id, 697 inputs_[0] = value;
803 int false_block_id) 698 }
804 : LIsSmi(value),
805 true_block_id_(true_block_id),
806 false_block_id_(false_block_id) { }
807 699
808 DECLARE_CONCRETE_INSTRUCTION(IsSmiAndBranch, "is-smi-and-branch") 700 DECLARE_CONCRETE_INSTRUCTION(IsSmiAndBranch, "is-smi-and-branch")
809 virtual void PrintDataTo(StringStream* stream) const; 701
810 virtual bool IsControl() const { return true; } 702 virtual void PrintDataTo(StringStream* stream);
811 703 };
812 int true_block_id() const { return true_block_id_; } 704
813 int false_block_id() const { return false_block_id_; } 705
814 706 class LHasInstanceType: public LTemplateInstruction<1, 1, 0> {
815 private: 707 public:
816 int true_block_id_; 708 explicit LHasInstanceType(LOperand* value) {
817 int false_block_id_; 709 inputs_[0] = value;
818 }; 710 }
819
820
821 class LHasInstanceType: public LUnaryOperation {
822 public:
823 explicit LHasInstanceType(LOperand* value)
824 : LUnaryOperation(value) { }
825 711
826 DECLARE_CONCRETE_INSTRUCTION(HasInstanceType, "has-instance-type") 712 DECLARE_CONCRETE_INSTRUCTION(HasInstanceType, "has-instance-type")
827 DECLARE_HYDROGEN_ACCESSOR(HasInstanceType) 713 DECLARE_HYDROGEN_ACCESSOR(HasInstanceType)
828 714 };
829 InstanceType TestType(); // The type to test against when generating code. 715
830 Condition BranchCondition(); // The branch condition for 'true'. 716
831 }; 717 class LHasInstanceTypeAndBranch: public LControlInstruction<1, 0> {
832 718 public:
833 719 explicit LHasInstanceTypeAndBranch(LOperand* value) {
834 class LHasInstanceTypeAndBranch: public LHasInstanceType { 720 inputs_[0] = value;
835 public: 721 }
836 LHasInstanceTypeAndBranch(LOperand* value,
837 int true_block_id,
838 int false_block_id)
839 : LHasInstanceType(value),
840 true_block_id_(true_block_id),
841 false_block_id_(false_block_id) { }
842 722
843 DECLARE_CONCRETE_INSTRUCTION(HasInstanceTypeAndBranch, 723 DECLARE_CONCRETE_INSTRUCTION(HasInstanceTypeAndBranch,
844 "has-instance-type-and-branch") 724 "has-instance-type-and-branch")
845 virtual void PrintDataTo(StringStream* stream) const; 725 DECLARE_HYDROGEN_ACCESSOR(HasInstanceType)
846 virtual bool IsControl() const { return true; } 726
847 727 virtual void PrintDataTo(StringStream* stream);
848 int true_block_id() const { return true_block_id_; } 728 };
849 int false_block_id() const { return false_block_id_; } 729
850 730
851 private: 731 class LHasCachedArrayIndex: public LTemplateInstruction<1, 1, 0> {
852 int true_block_id_; 732 public:
853 int false_block_id_; 733 explicit LHasCachedArrayIndex(LOperand* value) {
854 }; 734 inputs_[0] = value;
855 735 }
856
857 class LHasCachedArrayIndex: public LUnaryOperation {
858 public:
859 explicit LHasCachedArrayIndex(LOperand* value) : LUnaryOperation(value) {}
860 736
861 DECLARE_CONCRETE_INSTRUCTION(HasCachedArrayIndex, "has-cached-array-index") 737 DECLARE_CONCRETE_INSTRUCTION(HasCachedArrayIndex, "has-cached-array-index")
862 DECLARE_HYDROGEN_ACCESSOR(HasCachedArrayIndex) 738 DECLARE_HYDROGEN_ACCESSOR(HasCachedArrayIndex)
863 }; 739 };
864 740
865 741
866 class LHasCachedArrayIndexAndBranch: public LHasCachedArrayIndex { 742 class LHasCachedArrayIndexAndBranch: public LControlInstruction<1, 0> {
867 public: 743 public:
868 LHasCachedArrayIndexAndBranch(LOperand* value, 744 explicit LHasCachedArrayIndexAndBranch(LOperand* value) {
869 int true_block_id, 745 inputs_[0] = value;
870 int false_block_id) 746 }
871 : LHasCachedArrayIndex(value),
872 true_block_id_(true_block_id),
873 false_block_id_(false_block_id) { }
874 747
875 DECLARE_CONCRETE_INSTRUCTION(HasCachedArrayIndexAndBranch, 748 DECLARE_CONCRETE_INSTRUCTION(HasCachedArrayIndexAndBranch,
876 "has-cached-array-index-and-branch") 749 "has-cached-array-index-and-branch")
877 virtual void PrintDataTo(StringStream* stream) const; 750 virtual void PrintDataTo(StringStream* stream);
878 virtual bool IsControl() const { return true; } 751 };
879 752
880 int true_block_id() const { return true_block_id_; } 753
881 int false_block_id() const { return false_block_id_; } 754 class LClassOfTest: public LTemplateInstruction<1, 1, 0> {
882 755 public:
883 private: 756 explicit LClassOfTest(LOperand* value) {
884 int true_block_id_; 757 inputs_[0] = value;
885 int false_block_id_; 758 }
886 };
887
888
889 class LClassOfTest: public LUnaryOperation {
890 public:
891 LClassOfTest(LOperand* value, LOperand* temp)
892 : LUnaryOperation(value), temporary_(temp) {}
893 759
894 DECLARE_CONCRETE_INSTRUCTION(ClassOfTest, "class-of-test") 760 DECLARE_CONCRETE_INSTRUCTION(ClassOfTest, "class-of-test")
895 DECLARE_HYDROGEN_ACCESSOR(ClassOfTest) 761 DECLARE_HYDROGEN_ACCESSOR(ClassOfTest)
896 762
897 virtual void PrintDataTo(StringStream* stream) const; 763 virtual void PrintDataTo(StringStream* stream);
898 764 };
899 LOperand* temporary() { return temporary_; } 765
900 766
901 private: 767 class LClassOfTestAndBranch: public LControlInstruction<1, 1> {
902 LOperand *temporary_; 768 public:
903 }; 769 LClassOfTestAndBranch(LOperand* value, LOperand* temp) {
904 770 inputs_[0] = value;
905 771 temps_[0] = temp;
906 class LClassOfTestAndBranch: public LClassOfTest { 772 }
907 public:
908 LClassOfTestAndBranch(LOperand* value,
909 LOperand* temporary,
910 LOperand* temporary2,
911 int true_block_id,
912 int false_block_id)
913 : LClassOfTest(value, temporary),
914 temporary2_(temporary2),
915 true_block_id_(true_block_id),
916 false_block_id_(false_block_id) { }
917 773
918 DECLARE_CONCRETE_INSTRUCTION(ClassOfTestAndBranch, 774 DECLARE_CONCRETE_INSTRUCTION(ClassOfTestAndBranch,
919 "class-of-test-and-branch") 775 "class-of-test-and-branch")
920 virtual void PrintDataTo(StringStream* stream) const; 776 DECLARE_HYDROGEN_ACCESSOR(ClassOfTest)
921 virtual bool IsControl() const { return true; } 777
922 778 virtual void PrintDataTo(StringStream* stream);
923 int true_block_id() const { return true_block_id_; } 779 };
924 int false_block_id() const { return false_block_id_; } 780
925 LOperand* temporary2() { return temporary2_; } 781
926 782 class LCmpT: public LTemplateInstruction<1, 2, 0> {
927 private: 783 public:
928 LOperand* temporary2_; 784 LCmpT(LOperand* left, LOperand* right) {
929 int true_block_id_; 785 inputs_[0] = left;
930 int false_block_id_; 786 inputs_[1] = right;
931 }; 787 }
932
933
934 class LCmpT: public LBinaryOperation {
935 public:
936 LCmpT(LOperand* left, LOperand* right) : LBinaryOperation(left, right) {}
937 788
938 DECLARE_CONCRETE_INSTRUCTION(CmpT, "cmp-t") 789 DECLARE_CONCRETE_INSTRUCTION(CmpT, "cmp-t")
939 DECLARE_HYDROGEN_ACCESSOR(Compare) 790 DECLARE_HYDROGEN_ACCESSOR(Compare)
940 791
941 Token::Value op() const { return hydrogen()->token(); } 792 Token::Value op() const { return hydrogen()->token(); }
942 }; 793 };
943 794
944 795
945 class LCmpTAndBranch: public LCmpT { 796 class LCmpTAndBranch: public LControlInstruction<2, 0> {
946 public: 797 public:
947 LCmpTAndBranch(LOperand* left, 798 LCmpTAndBranch(LOperand* left, LOperand* right) {
948 LOperand* right, 799 inputs_[0] = left;
949 int true_block_id, 800 inputs_[1] = right;
950 int false_block_id) 801 }
951 : LCmpT(left, right),
952 true_block_id_(true_block_id),
953 false_block_id_(false_block_id) { }
954 802
955 DECLARE_CONCRETE_INSTRUCTION(CmpTAndBranch, "cmp-t-and-branch") 803 DECLARE_CONCRETE_INSTRUCTION(CmpTAndBranch, "cmp-t-and-branch")
804 DECLARE_HYDROGEN_ACCESSOR(Compare)
956 805
957 int true_block_id() const { return true_block_id_; } 806 Token::Value op() const { return hydrogen()->token(); }
958 int false_block_id() const { return false_block_id_; }
959
960 private:
961 int true_block_id_;
962 int false_block_id_;
963 }; 807 };
964 808
965 809
966 class LInstanceOf: public LBinaryOperation { 810 class LInstanceOf: public LTemplateInstruction<1, 2, 0> {
967 public: 811 public:
968 LInstanceOf(LOperand* left, LOperand* right) 812 LInstanceOf(LOperand* left, LOperand* right) {
969 : LBinaryOperation(left, right) { } 813 inputs_[0] = left;
814 inputs_[1] = right;
815 }
970 816
971 DECLARE_CONCRETE_INSTRUCTION(InstanceOf, "instance-of") 817 DECLARE_CONCRETE_INSTRUCTION(InstanceOf, "instance-of")
972 }; 818 };
973 819
974 820
975 class LInstanceOfAndBranch: public LInstanceOf { 821 class LInstanceOfAndBranch: public LControlInstruction<2, 0> {
976 public: 822 public:
977 LInstanceOfAndBranch(LOperand* left, 823 LInstanceOfAndBranch(LOperand* left, LOperand* right) {
978 LOperand* right, 824 inputs_[0] = left;
979 int true_block_id, 825 inputs_[1] = right;
980 int false_block_id) 826 }
981 : LInstanceOf(left, right),
982 true_block_id_(true_block_id),
983 false_block_id_(false_block_id) { }
984 827
985 DECLARE_CONCRETE_INSTRUCTION(InstanceOfAndBranch, "instance-of-and-branch") 828 DECLARE_CONCRETE_INSTRUCTION(InstanceOfAndBranch, "instance-of-and-branch")
986
987 int true_block_id() const { return true_block_id_; }
988 int false_block_id() const { return false_block_id_; }
989
990 private:
991 int true_block_id_;
992 int false_block_id_;
993 }; 829 };
994 830
995 831
996 class LBoundsCheck: public LBinaryOperation { 832 class LInstanceOfKnownGlobal: public LTemplateInstruction<1, 1, 1> {
997 public: 833 public:
998 LBoundsCheck(LOperand* index, LOperand* length) 834 LInstanceOfKnownGlobal(LOperand* value, LOperand* temp) {
999 : LBinaryOperation(index, length) { } 835 inputs_[0] = value;
836 temps_[0] = temp;
837 }
1000 838
1001 LOperand* index() const { return left(); } 839 DECLARE_CONCRETE_INSTRUCTION(InstanceOfKnownGlobal,
1002 LOperand* length() const { return right(); } 840 "instance-of-known-global")
841 DECLARE_HYDROGEN_ACCESSOR(InstanceOfKnownGlobal)
842
843 Handle<JSFunction> function() const { return hydrogen()->function(); }
844 };
845
846
847 class LBoundsCheck: public LTemplateInstruction<0, 2, 0> {
848 public:
849 LBoundsCheck(LOperand* index, LOperand* length) {
850 inputs_[0] = index;
851 inputs_[1] = length;
852 }
853
854 LOperand* index() { return inputs_[0]; }
855 LOperand* length() { return inputs_[1]; }
1003 856
1004 DECLARE_CONCRETE_INSTRUCTION(BoundsCheck, "bounds-check") 857 DECLARE_CONCRETE_INSTRUCTION(BoundsCheck, "bounds-check")
1005 }; 858 };
1006 859
1007 860
1008 class LBitI: public LBinaryOperation { 861 class LBitI: public LTemplateInstruction<1, 2, 0> {
1009 public: 862 public:
1010 LBitI(Token::Value op, LOperand* left, LOperand* right) 863 LBitI(Token::Value op, LOperand* left, LOperand* right)
1011 : LBinaryOperation(left, right), op_(op) { } 864 : op_(op) {
865 inputs_[0] = left;
866 inputs_[1] = right;
867 }
1012 868
1013 Token::Value op() const { return op_; } 869 Token::Value op() const { return op_; }
1014 870
1015 DECLARE_CONCRETE_INSTRUCTION(BitI, "bit-i") 871 DECLARE_CONCRETE_INSTRUCTION(BitI, "bit-i")
1016 872
1017 private: 873 private:
1018 Token::Value op_; 874 Token::Value op_;
1019 }; 875 };
1020 876
1021 877
1022 class LShiftI: public LBinaryOperation { 878 class LShiftI: public LTemplateInstruction<1, 2, 0> {
1023 public: 879 public:
1024 LShiftI(Token::Value op, LOperand* left, LOperand* right, bool can_deopt) 880 LShiftI(Token::Value op, LOperand* left, LOperand* right, bool can_deopt)
1025 : LBinaryOperation(left, right), op_(op), can_deopt_(can_deopt) { } 881 : op_(op), can_deopt_(can_deopt) {
882 inputs_[0] = left;
883 inputs_[1] = right;
884 }
1026 885
1027 Token::Value op() const { return op_; } 886 Token::Value op() const { return op_; }
1028 887
1029 bool can_deopt() const { return can_deopt_; } 888 bool can_deopt() const { return can_deopt_; }
1030 889
1031 DECLARE_CONCRETE_INSTRUCTION(ShiftI, "shift-i") 890 DECLARE_CONCRETE_INSTRUCTION(ShiftI, "shift-i")
1032 891
1033 private: 892 private:
1034 Token::Value op_; 893 Token::Value op_;
1035 bool can_deopt_; 894 bool can_deopt_;
1036 }; 895 };
1037 896
1038 897
1039 class LSubI: public LBinaryOperation { 898 class LSubI: public LTemplateInstruction<1, 2, 0> {
1040 public: 899 public:
1041 LSubI(LOperand* left, LOperand* right) 900 LSubI(LOperand* left, LOperand* right) {
1042 : LBinaryOperation(left, right) { } 901 inputs_[0] = left;
902 inputs_[1] = right;
903 }
1043 904
1044 DECLARE_CONCRETE_INSTRUCTION(SubI, "sub-i") 905 DECLARE_CONCRETE_INSTRUCTION(SubI, "sub-i")
1045 DECLARE_HYDROGEN_ACCESSOR(Sub) 906 DECLARE_HYDROGEN_ACCESSOR(Sub)
1046 }; 907 };
1047 908
1048 909
1049 class LConstant: public LInstruction { 910 class LConstantI: public LTemplateInstruction<1, 0, 0> {
1050 DECLARE_INSTRUCTION(Constant) 911 public:
912 DECLARE_CONCRETE_INSTRUCTION(ConstantI, "constant-i")
913 DECLARE_HYDROGEN_ACCESSOR(Constant)
914
915 int32_t value() const { return hydrogen()->Integer32Value(); }
1051 }; 916 };
1052 917
1053 918
1054 class LConstantI: public LConstant { 919 class LConstantD: public LTemplateInstruction<1, 0, 0> {
1055 public: 920 public:
1056 explicit LConstantI(int32_t value) : value_(value) { } 921 DECLARE_CONCRETE_INSTRUCTION(ConstantD, "constant-d")
1057 int32_t value() const { return value_; } 922 DECLARE_HYDROGEN_ACCESSOR(Constant)
1058 923
1059 DECLARE_CONCRETE_INSTRUCTION(ConstantI, "constant-i") 924 double value() const { return hydrogen()->DoubleValue(); }
1060
1061 private:
1062 int32_t value_;
1063 }; 925 };
1064 926
1065 927
1066 class LConstantD: public LConstant { 928 class LConstantT: public LTemplateInstruction<1, 0, 0> {
1067 public: 929 public:
1068 explicit LConstantD(double value) : value_(value) { } 930 DECLARE_CONCRETE_INSTRUCTION(ConstantT, "constant-t")
1069 double value() const { return value_; } 931 DECLARE_HYDROGEN_ACCESSOR(Constant)
1070 932
1071 DECLARE_CONCRETE_INSTRUCTION(ConstantD, "constant-d") 933 Handle<Object> value() const { return hydrogen()->handle(); }
1072
1073 private:
1074 double value_;
1075 }; 934 };
1076 935
1077 936
1078 class LConstantT: public LConstant { 937 class LBranch: public LControlInstruction<1, 0> {
1079 public: 938 public:
1080 explicit LConstantT(Handle<Object> value) : value_(value) { } 939 explicit LBranch(LOperand* value) {
1081 Handle<Object> value() const { return value_; } 940 inputs_[0] = value;
1082 941 }
1083 DECLARE_CONCRETE_INSTRUCTION(ConstantT, "constant-t")
1084
1085 private:
1086 Handle<Object> value_;
1087 };
1088
1089
1090 class LBranch: public LUnaryOperation {
1091 public:
1092 LBranch(LOperand* input, int true_block_id, int false_block_id)
1093 : LUnaryOperation(input),
1094 true_block_id_(true_block_id),
1095 false_block_id_(false_block_id) { }
1096 942
1097 DECLARE_CONCRETE_INSTRUCTION(Branch, "branch") 943 DECLARE_CONCRETE_INSTRUCTION(Branch, "branch")
1098 DECLARE_HYDROGEN_ACCESSOR(Value) 944 DECLARE_HYDROGEN_ACCESSOR(Value)
1099 945
1100 virtual void PrintDataTo(StringStream* stream) const; 946 virtual void PrintDataTo(StringStream* stream);
1101 virtual bool IsControl() const { return true; }
1102
1103 int true_block_id() const { return true_block_id_; }
1104 int false_block_id() const { return false_block_id_; }
1105
1106 private:
1107 int true_block_id_;
1108 int false_block_id_;
1109 }; 947 };
1110 948
1111 949
1112 class LCmpMapAndBranch: public LUnaryOperation { 950 class LCmpMapAndBranch: public LTemplateInstruction<0, 1, 1> {
1113 public: 951 public:
1114 LCmpMapAndBranch(LOperand* value, LOperand* temp) 952 LCmpMapAndBranch(LOperand* value, LOperand* temp) {
1115 : LUnaryOperation(value), temp_(temp) { } 953 inputs_[0] = value;
954 temps_[0] = temp;
955 }
1116 956
1117 DECLARE_CONCRETE_INSTRUCTION(CmpMapAndBranch, "cmp-map-and-branch") 957 DECLARE_CONCRETE_INSTRUCTION(CmpMapAndBranch, "cmp-map-and-branch")
1118 DECLARE_HYDROGEN_ACCESSOR(CompareMapAndBranch) 958 DECLARE_HYDROGEN_ACCESSOR(CompareMap)
1119 959
1120 virtual bool IsControl() const { return true; } 960 virtual bool IsControl() const { return true; }
1121 961
1122 LOperand* temp() const { return temp_; }
1123 Handle<Map> map() const { return hydrogen()->map(); } 962 Handle<Map> map() const { return hydrogen()->map(); }
1124 int true_block_id() const { 963 int true_block_id() const {
1125 return hydrogen()->true_destination()->block_id(); 964 return hydrogen()->FirstSuccessor()->block_id();
1126 } 965 }
1127 int false_block_id() const { 966 int false_block_id() const {
1128 return hydrogen()->false_destination()->block_id(); 967 return hydrogen()->SecondSuccessor()->block_id();
1129 } 968 }
1130
1131 private:
1132 LOperand* temp_;
1133 }; 969 };
1134 970
1135 971
1136 class LJSArrayLength: public LUnaryOperation { 972 class LJSArrayLength: public LTemplateInstruction<1, 1, 0> {
1137 public: 973 public:
1138 explicit LJSArrayLength(LOperand* input) : LUnaryOperation(input) { } 974 explicit LJSArrayLength(LOperand* value) {
975 inputs_[0] = value;
976 }
1139 977
1140 DECLARE_CONCRETE_INSTRUCTION(JSArrayLength, "js-array-length") 978 DECLARE_CONCRETE_INSTRUCTION(JSArrayLength, "js-array-length")
1141 DECLARE_HYDROGEN_ACCESSOR(JSArrayLength) 979 DECLARE_HYDROGEN_ACCESSOR(JSArrayLength)
1142 }; 980 };
1143 981
1144 982
1145 class LFixedArrayLength: public LUnaryOperation { 983 class LPixelArrayLength: public LTemplateInstruction<1, 1, 0> {
1146 public: 984 public:
1147 explicit LFixedArrayLength(LOperand* input) : LUnaryOperation(input) { } 985 explicit LPixelArrayLength(LOperand* value) {
986 inputs_[0] = value;
987 }
988
989 DECLARE_CONCRETE_INSTRUCTION(PixelArrayLength, "pixel-array-length")
990 DECLARE_HYDROGEN_ACCESSOR(PixelArrayLength)
991 };
992
993
994 class LFixedArrayLength: public LTemplateInstruction<1, 1, 0> {
995 public:
996 explicit LFixedArrayLength(LOperand* value) {
997 inputs_[0] = value;
998 }
1148 999
1149 DECLARE_CONCRETE_INSTRUCTION(FixedArrayLength, "fixed-array-length") 1000 DECLARE_CONCRETE_INSTRUCTION(FixedArrayLength, "fixed-array-length")
1150 DECLARE_HYDROGEN_ACCESSOR(FixedArrayLength) 1001 DECLARE_HYDROGEN_ACCESSOR(FixedArrayLength)
1151 }; 1002 };
1152 1003
1153 1004
1154 class LValueOf: public LUnaryOperation { 1005 class LValueOf: public LTemplateInstruction<1, 1, 1> {
1155 public: 1006 public:
1156 LValueOf(LOperand* input, LOperand* temporary) 1007 LValueOf(LOperand* value, LOperand* temp) {
1157 : LUnaryOperation(input), temporary_(temporary) { } 1008 inputs_[0] = value;
1158 1009 temps_[0] = temp;
1159 LOperand* temporary() const { return temporary_; } 1010 }
1160 1011
1161 DECLARE_CONCRETE_INSTRUCTION(ValueOf, "value-of") 1012 DECLARE_CONCRETE_INSTRUCTION(ValueOf, "value-of")
1162 DECLARE_HYDROGEN_ACCESSOR(ValueOf) 1013 DECLARE_HYDROGEN_ACCESSOR(ValueOf)
1163
1164 private:
1165 LOperand* temporary_;
1166 }; 1014 };
1167 1015
1168 1016
1169 class LThrow: public LUnaryOperation { 1017 class LThrow: public LTemplateInstruction<0, 1, 0> {
1170 public: 1018 public:
1171 explicit LThrow(LOperand* value) : LUnaryOperation(value) { } 1019 explicit LThrow(LOperand* value) {
1020 inputs_[0] = value;
1021 }
1172 1022
1173 DECLARE_CONCRETE_INSTRUCTION(Throw, "throw") 1023 DECLARE_CONCRETE_INSTRUCTION(Throw, "throw")
1174 }; 1024 };
1175 1025
1176 1026
1177 class LBitNotI: public LUnaryOperation { 1027 class LBitNotI: public LTemplateInstruction<1, 1, 0> {
1178 public: 1028 public:
1179 explicit LBitNotI(LOperand* use) : LUnaryOperation(use) { } 1029 explicit LBitNotI(LOperand* value) {
1030 inputs_[0] = value;
1031 }
1180 1032
1181 DECLARE_CONCRETE_INSTRUCTION(BitNotI, "bit-not-i") 1033 DECLARE_CONCRETE_INSTRUCTION(BitNotI, "bit-not-i")
1182 }; 1034 };
1183 1035
1184 1036
1185 class LAddI: public LBinaryOperation { 1037 class LAddI: public LTemplateInstruction<1, 2, 0> {
1186 public: 1038 public:
1187 LAddI(LOperand* left, LOperand* right) 1039 LAddI(LOperand* left, LOperand* right) {
1188 : LBinaryOperation(left, right) { } 1040 inputs_[0] = left;
1041 inputs_[1] = right;
1042 }
1189 1043
1190 DECLARE_CONCRETE_INSTRUCTION(AddI, "add-i") 1044 DECLARE_CONCRETE_INSTRUCTION(AddI, "add-i")
1191 DECLARE_HYDROGEN_ACCESSOR(Add) 1045 DECLARE_HYDROGEN_ACCESSOR(Add)
1192 }; 1046 };
1193 1047
1194 1048
1195 class LArithmeticD: public LBinaryOperation { 1049 class LArithmeticD: public LTemplateInstruction<1, 2, 0> {
1196 public: 1050 public:
1197 LArithmeticD(Token::Value op, LOperand* left, LOperand* right) 1051 LArithmeticD(Token::Value op, LOperand* left, LOperand* right)
1198 : LBinaryOperation(left, right), op_(op) { } 1052 : op_(op) {
1053 inputs_[0] = left;
1054 inputs_[1] = right;
1055 }
1199 1056
1200 Token::Value op() const { return op_; } 1057 Token::Value op() const { return op_; }
1201 1058
1202 virtual void CompileToNative(LCodeGen* generator); 1059 virtual void CompileToNative(LCodeGen* generator);
1203 virtual const char* Mnemonic() const; 1060 virtual const char* Mnemonic() const;
1204 1061
1205 private: 1062 private:
1206 Token::Value op_; 1063 Token::Value op_;
1207 }; 1064 };
1208 1065
1209 1066
1210 class LArithmeticT: public LBinaryOperation { 1067 class LArithmeticT: public LTemplateInstruction<1, 2, 0> {
1211 public: 1068 public:
1212 LArithmeticT(Token::Value op, LOperand* left, LOperand* right) 1069 LArithmeticT(Token::Value op, LOperand* left, LOperand* right)
1213 : LBinaryOperation(left, right), op_(op) { } 1070 : op_(op) {
1071 inputs_[0] = left;
1072 inputs_[1] = right;
1073 }
1214 1074
1215 virtual void CompileToNative(LCodeGen* generator); 1075 virtual void CompileToNative(LCodeGen* generator);
1216 virtual const char* Mnemonic() const; 1076 virtual const char* Mnemonic() const;
1217 1077
1218 Token::Value op() const { return op_; } 1078 Token::Value op() const { return op_; }
1219 1079
1220 private: 1080 private:
1221 Token::Value op_; 1081 Token::Value op_;
1222 }; 1082 };
1223 1083
1224 1084
1225 class LReturn: public LUnaryOperation { 1085 class LReturn: public LTemplateInstruction<0, 1, 0> {
1226 public: 1086 public:
1227 explicit LReturn(LOperand* use) : LUnaryOperation(use) { } 1087 explicit LReturn(LOperand* value) {
1088 inputs_[0] = value;
1089 }
1228 1090
1229 DECLARE_CONCRETE_INSTRUCTION(Return, "return") 1091 DECLARE_CONCRETE_INSTRUCTION(Return, "return")
1230 }; 1092 };
1231 1093
1232 1094
1233 class LLoadNamedField: public LUnaryOperation { 1095 class LLoadNamedField: public LTemplateInstruction<1, 1, 0> {
1234 public: 1096 public:
1235 explicit LLoadNamedField(LOperand* object) : LUnaryOperation(object) { } 1097 explicit LLoadNamedField(LOperand* object) {
1098 inputs_[0] = object;
1099 }
1236 1100
1237 DECLARE_CONCRETE_INSTRUCTION(LoadNamedField, "load-named-field") 1101 DECLARE_CONCRETE_INSTRUCTION(LoadNamedField, "load-named-field")
1238 DECLARE_HYDROGEN_ACCESSOR(LoadNamedField) 1102 DECLARE_HYDROGEN_ACCESSOR(LoadNamedField)
1239 }; 1103 };
1240 1104
1241 1105
1242 class LLoadNamedGeneric: public LUnaryOperation { 1106 class LLoadNamedGeneric: public LTemplateInstruction<1, 1, 0> {
1243 public: 1107 public:
1244 explicit LLoadNamedGeneric(LOperand* object) : LUnaryOperation(object) { } 1108 explicit LLoadNamedGeneric(LOperand* object) {
1109 inputs_[0] = object;
1110 }
1245 1111
1246 DECLARE_CONCRETE_INSTRUCTION(LoadNamedGeneric, "load-named-generic") 1112 DECLARE_CONCRETE_INSTRUCTION(LoadNamedGeneric, "load-named-generic")
1247 DECLARE_HYDROGEN_ACCESSOR(LoadNamedGeneric) 1113 DECLARE_HYDROGEN_ACCESSOR(LoadNamedGeneric)
1248 1114
1249 LOperand* object() const { return input(); } 1115 LOperand* object() { return inputs_[0]; }
1250 Handle<Object> name() const { return hydrogen()->name(); } 1116 Handle<Object> name() const { return hydrogen()->name(); }
1251 }; 1117 };
1252 1118
1253 1119
1254 class LLoadFunctionPrototype: public LUnaryOperation { 1120 class LLoadFunctionPrototype: public LTemplateInstruction<1, 1, 0> {
1255 public: 1121 public:
1256 explicit LLoadFunctionPrototype(LOperand* function) 1122 explicit LLoadFunctionPrototype(LOperand* function) {
1257 : LUnaryOperation(function) { } 1123 inputs_[0] = function;
1124 }
1258 1125
1259 DECLARE_CONCRETE_INSTRUCTION(LoadFunctionPrototype, "load-function-prototype") 1126 DECLARE_CONCRETE_INSTRUCTION(LoadFunctionPrototype, "load-function-prototype")
1260 DECLARE_HYDROGEN_ACCESSOR(LoadFunctionPrototype) 1127 DECLARE_HYDROGEN_ACCESSOR(LoadFunctionPrototype)
1261 1128
1262 LOperand* function() const { return input(); } 1129 LOperand* function() { return inputs_[0]; }
1263 }; 1130 };
1264 1131
1265 1132
1266 class LLoadElements: public LUnaryOperation { 1133 class LLoadElements: public LTemplateInstruction<1, 1, 0> {
1267 public: 1134 public:
1268 explicit LLoadElements(LOperand* obj) : LUnaryOperation(obj) { } 1135 explicit LLoadElements(LOperand* object) {
1136 inputs_[0] = object;
1137 }
1269 1138
1270 DECLARE_CONCRETE_INSTRUCTION(LoadElements, "load-elements") 1139 DECLARE_CONCRETE_INSTRUCTION(LoadElements, "load-elements")
1271 }; 1140 };
1272 1141
1273 1142
1274 class LLoadKeyedFastElement: public LBinaryOperation { 1143 class LLoadPixelArrayExternalPointer: public LTemplateInstruction<1, 1, 0> {
1275 public: 1144 public:
1276 LLoadKeyedFastElement(LOperand* elements, 1145 explicit LLoadPixelArrayExternalPointer(LOperand* object) {
1277 LOperand* key, 1146 inputs_[0] = object;
1278 LOperand* load_result) 1147 }
1279 : LBinaryOperation(elements, key), 1148
1280 load_result_(load_result) { } 1149 DECLARE_CONCRETE_INSTRUCTION(LoadPixelArrayExternalPointer,
1150 "load-pixel-array-external-pointer")
1151 };
1152
1153
1154 class LLoadKeyedFastElement: public LTemplateInstruction<1, 2, 0> {
1155 public:
1156 LLoadKeyedFastElement(LOperand* elements, LOperand* key) {
1157 inputs_[0] = elements;
1158 inputs_[1] = key;
1159 }
1281 1160
1282 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedFastElement, "load-keyed-fast-element") 1161 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedFastElement, "load-keyed-fast-element")
1283 DECLARE_HYDROGEN_ACCESSOR(LoadKeyedFastElement) 1162 DECLARE_HYDROGEN_ACCESSOR(LoadKeyedFastElement)
1284 1163
1285 LOperand* elements() const { return left(); } 1164 LOperand* elements() { return inputs_[0]; }
1286 LOperand* key() const { return right(); } 1165 LOperand* key() { return inputs_[1]; }
1287 LOperand* load_result() const { return load_result_; } 1166 };
1288 1167
1289 private: 1168
1290 LOperand* load_result_; 1169 class LLoadPixelArrayElement: public LTemplateInstruction<1, 2, 0> {
1291 }; 1170 public:
1292 1171 LLoadPixelArrayElement(LOperand* external_pointer, LOperand* key) {
1293 1172 inputs_[0] = external_pointer;
1294 class LLoadKeyedGeneric: public LBinaryOperation { 1173 inputs_[1] = key;
1295 public: 1174 }
1296 LLoadKeyedGeneric(LOperand* obj, LOperand* key) 1175
1297 : LBinaryOperation(obj, key) { } 1176 DECLARE_CONCRETE_INSTRUCTION(LoadPixelArrayElement,
1177 "load-pixel-array-element")
1178 DECLARE_HYDROGEN_ACCESSOR(LoadPixelArrayElement)
1179
1180 LOperand* external_pointer() { return inputs_[0]; }
1181 LOperand* key() { return inputs_[1]; }
1182 };
1183
1184
1185 class LLoadKeyedGeneric: public LTemplateInstruction<1, 2, 0> {
1186 public:
1187 LLoadKeyedGeneric(LOperand* obj, LOperand* key) {
1188 inputs_[0] = obj;
1189 inputs_[1] = key;
1190 }
1298 1191
1299 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedGeneric, "load-keyed-generic") 1192 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedGeneric, "load-keyed-generic")
1300 1193
1301 LOperand* object() const { return left(); } 1194 LOperand* object() { return inputs_[0]; }
1302 LOperand* key() const { return right(); } 1195 LOperand* key() { return inputs_[1]; }
1303 }; 1196 };
1304 1197
1305 1198
1306 class LLoadGlobal: public LInstruction { 1199 class LLoadGlobal: public LTemplateInstruction<1, 0, 0> {
1307 public: 1200 public:
1308 DECLARE_CONCRETE_INSTRUCTION(LoadGlobal, "load-global") 1201 DECLARE_CONCRETE_INSTRUCTION(LoadGlobal, "load-global")
1309 DECLARE_HYDROGEN_ACCESSOR(LoadGlobal) 1202 DECLARE_HYDROGEN_ACCESSOR(LoadGlobal)
1310 }; 1203 };
1311 1204
1312 1205
1313 class LStoreGlobal: public LUnaryOperation { 1206 class LStoreGlobal: public LTemplateInstruction<0, 1, 1> {
1314 public: 1207 public:
1315 explicit LStoreGlobal(LOperand* value) : LUnaryOperation(value) {} 1208 LStoreGlobal(LOperand* value, LOperand* temp) {
1209 inputs_[0] = value;
1210 temps_[0] = temp;
1211 }
1316 1212
1317 DECLARE_CONCRETE_INSTRUCTION(StoreGlobal, "store-global") 1213 DECLARE_CONCRETE_INSTRUCTION(StoreGlobal, "store-global")
1318 DECLARE_HYDROGEN_ACCESSOR(StoreGlobal) 1214 DECLARE_HYDROGEN_ACCESSOR(StoreGlobal)
1319 }; 1215 };
1320 1216
1321 1217
1322 class LPushArgument: public LUnaryOperation { 1218 class LLoadContextSlot: public LTemplateInstruction<1, 1, 0> {
1323 public: 1219 public:
1324 explicit LPushArgument(LOperand* argument) : LUnaryOperation(argument) {} 1220 explicit LLoadContextSlot(LOperand* context) {
1221 inputs_[0] = context;
1222 }
1223
1224 DECLARE_CONCRETE_INSTRUCTION(LoadContextSlot, "load-context-slot")
1225 DECLARE_HYDROGEN_ACCESSOR(LoadContextSlot)
1226
1227 LOperand* context() { return InputAt(0); }
1228 int slot_index() { return hydrogen()->slot_index(); }
1229
1230 virtual void PrintDataTo(StringStream* stream);
1231 };
1232
1233
1234 class LStoreContextSlot: public LTemplateInstruction<0, 2, 0> {
1235 public:
1236 LStoreContextSlot(LOperand* context, LOperand* value) {
1237 inputs_[0] = context;
1238 inputs_[1] = value;
1239 }
1240
1241 DECLARE_CONCRETE_INSTRUCTION(StoreContextSlot, "store-context-slot")
1242 DECLARE_HYDROGEN_ACCESSOR(StoreContextSlot)
1243
1244 LOperand* context() { return InputAt(0); }
1245 LOperand* value() { return InputAt(1); }
1246 int slot_index() { return hydrogen()->slot_index(); }
1247 int needs_write_barrier() { return hydrogen()->NeedsWriteBarrier(); }
1248
1249 virtual void PrintDataTo(StringStream* stream);
1250 };
1251
1252
1253 class LPushArgument: public LTemplateInstruction<0, 1, 0> {
1254 public:
1255 explicit LPushArgument(LOperand* value) {
1256 inputs_[0] = value;
1257 }
1325 1258
1326 DECLARE_CONCRETE_INSTRUCTION(PushArgument, "push-argument") 1259 DECLARE_CONCRETE_INSTRUCTION(PushArgument, "push-argument")
1327 }; 1260 };
1328 1261
1329 1262
1330 class LGlobalObject: public LInstruction { 1263 class LContext: public LTemplateInstruction<1, 0, 0> {
1331 public: 1264 public:
1265 DECLARE_CONCRETE_INSTRUCTION(Context, "context")
1266 };
1267
1268
1269 class LOuterContext: public LTemplateInstruction<1, 1, 0> {
1270 public:
1271 explicit LOuterContext(LOperand* context) {
1272 inputs_[0] = context;
1273 }
1274
1275 DECLARE_CONCRETE_INSTRUCTION(OuterContext, "outer-context")
1276
1277 LOperand* context() { return InputAt(0); }
1278 };
1279
1280
1281 class LGlobalObject: public LTemplateInstruction<1, 1, 0> {
1282 public:
1283 explicit LGlobalObject(LOperand* context) {
1284 inputs_[0] = context;
1285 }
1286
1332 DECLARE_CONCRETE_INSTRUCTION(GlobalObject, "global-object") 1287 DECLARE_CONCRETE_INSTRUCTION(GlobalObject, "global-object")
1333 }; 1288
1334 1289 LOperand* context() { return InputAt(0); }
1335 1290 };
1336 class LGlobalReceiver: public LInstruction { 1291
1337 public: 1292
1293 class LGlobalReceiver: public LTemplateInstruction<1, 1, 0> {
1294 public:
1295 explicit LGlobalReceiver(LOperand* global_object) {
1296 inputs_[0] = global_object;
1297 }
1298
1338 DECLARE_CONCRETE_INSTRUCTION(GlobalReceiver, "global-receiver") 1299 DECLARE_CONCRETE_INSTRUCTION(GlobalReceiver, "global-receiver")
1339 }; 1300
1340 1301 LOperand* global() { return InputAt(0); }
1341 1302 };
1342 class LCallConstantFunction: public LInstruction { 1303
1304
1305 class LCallConstantFunction: public LTemplateInstruction<1, 0, 0> {
1343 public: 1306 public:
1344 DECLARE_CONCRETE_INSTRUCTION(CallConstantFunction, "call-constant-function") 1307 DECLARE_CONCRETE_INSTRUCTION(CallConstantFunction, "call-constant-function")
1345 DECLARE_HYDROGEN_ACCESSOR(CallConstantFunction) 1308 DECLARE_HYDROGEN_ACCESSOR(CallConstantFunction)
1346 1309
1347 virtual void PrintDataTo(StringStream* stream) const; 1310 virtual void PrintDataTo(StringStream* stream);
1348 1311
1349 Handle<JSFunction> function() const { return hydrogen()->function(); } 1312 Handle<JSFunction> function() { return hydrogen()->function(); }
1350 int arity() const { return hydrogen()->argument_count() - 1; } 1313 int arity() const { return hydrogen()->argument_count() - 1; }
1351 }; 1314 };
1352 1315
1353 1316
1354 class LCallKeyed: public LInstruction { 1317 class LCallKeyed: public LTemplateInstruction<1, 1, 0> {
1355 public: 1318 public:
1319 explicit LCallKeyed(LOperand* key) {
1320 inputs_[0] = key;
1321 }
1322
1356 DECLARE_CONCRETE_INSTRUCTION(CallKeyed, "call-keyed") 1323 DECLARE_CONCRETE_INSTRUCTION(CallKeyed, "call-keyed")
1357 DECLARE_HYDROGEN_ACCESSOR(CallKeyed) 1324 DECLARE_HYDROGEN_ACCESSOR(CallKeyed)
1358 1325
1359 virtual void PrintDataTo(StringStream* stream) const; 1326 virtual void PrintDataTo(StringStream* stream);
1360 1327
1361 int arity() const { return hydrogen()->argument_count() - 1; } 1328 int arity() const { return hydrogen()->argument_count() - 1; }
1362 }; 1329 };
1363 1330
1364 1331
1365 class LCallNamed: public LInstruction { 1332
1333 class LCallNamed: public LTemplateInstruction<1, 0, 0> {
1366 public: 1334 public:
1367 DECLARE_CONCRETE_INSTRUCTION(CallNamed, "call-named") 1335 DECLARE_CONCRETE_INSTRUCTION(CallNamed, "call-named")
1368 DECLARE_HYDROGEN_ACCESSOR(CallNamed) 1336 DECLARE_HYDROGEN_ACCESSOR(CallNamed)
1369 1337
1370 virtual void PrintDataTo(StringStream* stream) const; 1338 virtual void PrintDataTo(StringStream* stream);
1371 1339
1372 Handle<String> name() const { return hydrogen()->name(); } 1340 Handle<String> name() const { return hydrogen()->name(); }
1373 int arity() const { return hydrogen()->argument_count() - 1; } 1341 int arity() const { return hydrogen()->argument_count() - 1; }
1374 }; 1342 };
1375 1343
1376 1344
1377 class LCallFunction: public LInstruction { 1345 class LCallFunction: public LTemplateInstruction<1, 0, 0> {
1378 public: 1346 public:
1379 DECLARE_CONCRETE_INSTRUCTION(CallFunction, "call-function") 1347 DECLARE_CONCRETE_INSTRUCTION(CallFunction, "call-function")
1380 DECLARE_HYDROGEN_ACCESSOR(CallFunction) 1348 DECLARE_HYDROGEN_ACCESSOR(CallFunction)
1381 1349
1382 int arity() const { return hydrogen()->argument_count() - 2; } 1350 int arity() const { return hydrogen()->argument_count() - 2; }
1383 }; 1351 };
1384 1352
1385 1353
1386 class LCallGlobal: public LInstruction { 1354 class LCallGlobal: public LTemplateInstruction<1, 0, 0> {
1387 public: 1355 public:
1388 DECLARE_CONCRETE_INSTRUCTION(CallGlobal, "call-global") 1356 DECLARE_CONCRETE_INSTRUCTION(CallGlobal, "call-global")
1389 DECLARE_HYDROGEN_ACCESSOR(CallGlobal) 1357 DECLARE_HYDROGEN_ACCESSOR(CallGlobal)
1390 1358
1391 virtual void PrintDataTo(StringStream* stream) const; 1359 virtual void PrintDataTo(StringStream* stream);
1392 1360
1393 Handle<String> name() const {return hydrogen()->name(); } 1361 Handle<String> name() const {return hydrogen()->name(); }
1394 int arity() const { return hydrogen()->argument_count() - 1; } 1362 int arity() const { return hydrogen()->argument_count() - 1; }
1395 }; 1363 };
1396 1364
1397 1365
1398 class LCallKnownGlobal: public LInstruction { 1366 class LCallKnownGlobal: public LTemplateInstruction<1, 0, 0> {
1399 public: 1367 public:
1400 DECLARE_CONCRETE_INSTRUCTION(CallKnownGlobal, "call-known-global") 1368 DECLARE_CONCRETE_INSTRUCTION(CallKnownGlobal, "call-known-global")
1401 DECLARE_HYDROGEN_ACCESSOR(CallKnownGlobal) 1369 DECLARE_HYDROGEN_ACCESSOR(CallKnownGlobal)
1402 1370
1403 virtual void PrintDataTo(StringStream* stream) const; 1371 virtual void PrintDataTo(StringStream* stream);
1404 1372
1405 Handle<JSFunction> target() const { return hydrogen()->target(); } 1373 Handle<JSFunction> target() const { return hydrogen()->target(); }
1406 int arity() const { return hydrogen()->argument_count() - 1; } 1374 int arity() const { return hydrogen()->argument_count() - 1; }
1407 }; 1375 };
1408 1376
1409 1377
1410 class LCallNew: public LUnaryOperation { 1378 class LCallNew: public LTemplateInstruction<1, 1, 0> {
1411 public: 1379 public:
1412 explicit LCallNew(LOperand* constructor) : LUnaryOperation(constructor) { } 1380 explicit LCallNew(LOperand* constructor) {
1381 inputs_[0] = constructor;
1382 }
1413 1383
1414 DECLARE_CONCRETE_INSTRUCTION(CallNew, "call-new") 1384 DECLARE_CONCRETE_INSTRUCTION(CallNew, "call-new")
1415 DECLARE_HYDROGEN_ACCESSOR(CallNew) 1385 DECLARE_HYDROGEN_ACCESSOR(CallNew)
1416 1386
1417 virtual void PrintDataTo(StringStream* stream) const; 1387 virtual void PrintDataTo(StringStream* stream);
1418 1388
1419 int arity() const { return hydrogen()->argument_count() - 1; } 1389 int arity() const { return hydrogen()->argument_count() - 1; }
1420 }; 1390 };
1421 1391
1422 1392
1423 class LCallRuntime: public LInstruction { 1393 class LCallRuntime: public LTemplateInstruction<1, 0, 0> {
1424 public: 1394 public:
1425 DECLARE_CONCRETE_INSTRUCTION(CallRuntime, "call-runtime") 1395 DECLARE_CONCRETE_INSTRUCTION(CallRuntime, "call-runtime")
1426 DECLARE_HYDROGEN_ACCESSOR(CallRuntime) 1396 DECLARE_HYDROGEN_ACCESSOR(CallRuntime)
1427 1397
1428 Runtime::Function* function() const { return hydrogen()->function(); } 1398 Runtime::Function* function() const { return hydrogen()->function(); }
1429 int arity() const { return hydrogen()->argument_count(); } 1399 int arity() const { return hydrogen()->argument_count(); }
1430 }; 1400 };
1431 1401
1432 1402
1433 class LInteger32ToDouble: public LUnaryOperation { 1403 class LInteger32ToDouble: public LTemplateInstruction<1, 1, 0> {
1434 public: 1404 public:
1435 explicit LInteger32ToDouble(LOperand* use) : LUnaryOperation(use) { } 1405 explicit LInteger32ToDouble(LOperand* value) {
1406 inputs_[0] = value;
1407 }
1436 1408
1437 DECLARE_CONCRETE_INSTRUCTION(Integer32ToDouble, "int32-to-double") 1409 DECLARE_CONCRETE_INSTRUCTION(Integer32ToDouble, "int32-to-double")
1438 }; 1410 };
1439 1411
1440 1412
1441 class LNumberTagI: public LUnaryOperation { 1413 class LNumberTagI: public LTemplateInstruction<1, 1, 0> {
1442 public: 1414 public:
1443 explicit LNumberTagI(LOperand* use) : LUnaryOperation(use) { } 1415 explicit LNumberTagI(LOperand* value) {
1416 inputs_[0] = value;
1417 }
1444 1418
1445 DECLARE_CONCRETE_INSTRUCTION(NumberTagI, "number-tag-i") 1419 DECLARE_CONCRETE_INSTRUCTION(NumberTagI, "number-tag-i")
1446 }; 1420 };
1447 1421
1448 1422
1449 class LNumberTagD: public LUnaryOperation { 1423 class LNumberTagD: public LTemplateInstruction<1, 1, 2> {
1450 public: 1424 public:
1451 LNumberTagD(LOperand* value, LOperand* temp1, LOperand* temp2) 1425 LNumberTagD(LOperand* value, LOperand* temp1, LOperand* temp2) {
1452 : LUnaryOperation(value), temp1_(temp1), temp2_(temp2) { } 1426 inputs_[0] = value;
1427 temps_[0] = temp1;
1428 temps_[1] = temp2;
1429 }
1453 1430
1454 DECLARE_CONCRETE_INSTRUCTION(NumberTagD, "number-tag-d") 1431 DECLARE_CONCRETE_INSTRUCTION(NumberTagD, "number-tag-d")
1455
1456 LOperand* temp1() const { return temp1_; }
1457 LOperand* temp2() const { return temp2_; }
1458
1459 private:
1460 LOperand* temp1_;
1461 LOperand* temp2_;
1462 }; 1432 };
1463 1433
1464 1434
1465 // Sometimes truncating conversion from a tagged value to an int32. 1435 // Sometimes truncating conversion from a tagged value to an int32.
1466 class LDoubleToI: public LUnaryOperation { 1436 class LDoubleToI: public LTemplateInstruction<1, 1, 1> {
1467 public: 1437 public:
1468 explicit LDoubleToI(LOperand* value) : LUnaryOperation(value) { } 1438 explicit LDoubleToI(LOperand* value, LOperand* temp1) {
1439 inputs_[0] = value;
1440 temps_[0] = temp1;
1441 }
1469 1442
1470 DECLARE_CONCRETE_INSTRUCTION(DoubleToI, "double-to-i") 1443 DECLARE_CONCRETE_INSTRUCTION(DoubleToI, "double-to-i")
1471 DECLARE_HYDROGEN_ACCESSOR(Change) 1444 DECLARE_HYDROGEN_ACCESSOR(Change)
1472 1445
1473 bool truncating() { return hydrogen()->CanTruncateToInt32(); } 1446 bool truncating() { return hydrogen()->CanTruncateToInt32(); }
1474 }; 1447 };
1475 1448
1476 1449
1477 // Truncating conversion from a tagged value to an int32. 1450 // Truncating conversion from a tagged value to an int32.
1478 class LTaggedToI: public LUnaryOperation { 1451 class LTaggedToI: public LTemplateInstruction<1, 1, 1> {
1479 public: 1452 public:
1480 LTaggedToI(LOperand* value, LOperand* temp) 1453 LTaggedToI(LOperand* value, LOperand* temp) {
1481 : LUnaryOperation(value), temp_(temp) { } 1454 inputs_[0] = value;
1455 temps_[0] = temp;
1456 }
1482 1457
1483 DECLARE_CONCRETE_INSTRUCTION(TaggedToI, "tagged-to-i") 1458 DECLARE_CONCRETE_INSTRUCTION(TaggedToI, "tagged-to-i")
1484 DECLARE_HYDROGEN_ACCESSOR(Change) 1459 DECLARE_HYDROGEN_ACCESSOR(Change)
1485 1460
1486 bool truncating() { return hydrogen()->CanTruncateToInt32(); } 1461 bool truncating() { return hydrogen()->CanTruncateToInt32(); }
1487 LOperand* temp() const { return temp_; }
1488
1489 private:
1490 LOperand* temp_;
1491 }; 1462 };
1492 1463
1493 1464
1494 class LSmiTag: public LUnaryOperation { 1465 class LSmiTag: public LTemplateInstruction<1, 1, 0> {
1495 public: 1466 public:
1496 explicit LSmiTag(LOperand* use) : LUnaryOperation(use) { } 1467 explicit LSmiTag(LOperand* value) {
1468 inputs_[0] = value;
1469 }
1497 1470
1498 DECLARE_CONCRETE_INSTRUCTION(SmiTag, "smi-tag") 1471 DECLARE_CONCRETE_INSTRUCTION(SmiTag, "smi-tag")
1499 }; 1472 };
1500 1473
1501 1474
1502 class LNumberUntagD: public LUnaryOperation { 1475 class LNumberUntagD: public LTemplateInstruction<1, 1, 0> {
1503 public: 1476 public:
1504 explicit LNumberUntagD(LOperand* value) : LUnaryOperation(value) { } 1477 explicit LNumberUntagD(LOperand* value) {
1478 inputs_[0] = value;
1479 }
1505 1480
1506 DECLARE_CONCRETE_INSTRUCTION(NumberUntagD, "double-untag") 1481 DECLARE_CONCRETE_INSTRUCTION(NumberUntagD, "double-untag")
1507 }; 1482 };
1508 1483
1509 1484
1510 class LSmiUntag: public LUnaryOperation { 1485 class LSmiUntag: public LTemplateInstruction<1, 1, 0> {
1511 public: 1486 public:
1512 LSmiUntag(LOperand* use, bool needs_check) 1487 LSmiUntag(LOperand* value, bool needs_check)
1513 : LUnaryOperation(use), needs_check_(needs_check) { } 1488 : needs_check_(needs_check) {
1489 inputs_[0] = value;
1490 }
1514 1491
1515 DECLARE_CONCRETE_INSTRUCTION(SmiUntag, "smi-untag") 1492 DECLARE_CONCRETE_INSTRUCTION(SmiUntag, "smi-untag")
1516 1493
1517 bool needs_check() const { return needs_check_; } 1494 bool needs_check() const { return needs_check_; }
1518 1495
1519 private: 1496 private:
1520 bool needs_check_; 1497 bool needs_check_;
1521 }; 1498 };
1522 1499
1523 1500
1524 class LStoreNamed: public LInstruction { 1501 class LStoreNamed: public LTemplateInstruction<0, 2, 0> {
1525 public: 1502 public:
1526 LStoreNamed(LOperand* obj, Handle<Object> name, LOperand* val) 1503 LStoreNamed(LOperand* obj, LOperand* val) {
1527 : object_(obj), name_(name), value_(val) { } 1504 inputs_[0] = obj;
1505 inputs_[1] = val;
1506 }
1528 1507
1529 DECLARE_INSTRUCTION(StoreNamed) 1508 DECLARE_INSTRUCTION(StoreNamed)
1509 DECLARE_HYDROGEN_ACCESSOR(StoreNamed)
1530 1510
1531 virtual void PrintDataTo(StringStream* stream) const; 1511 virtual void PrintDataTo(StringStream* stream);
1532 1512
1533 LOperand* object() const { return object_; } 1513 LOperand* object() { return inputs_[0]; }
1534 Handle<Object> name() const { return name_; } 1514 LOperand* value() { return inputs_[1]; }
1535 LOperand* value() const { return value_; } 1515 Handle<Object> name() const { return hydrogen()->name(); }
1536
1537 private:
1538 LOperand* object_;
1539 Handle<Object> name_;
1540 LOperand* value_;
1541 }; 1516 };
1542 1517
1543 1518
1544 class LStoreNamedField: public LStoreNamed { 1519 class LStoreNamedField: public LStoreNamed {
1545 public: 1520 public:
1546 LStoreNamedField(LOperand* obj, 1521 LStoreNamedField(LOperand* obj, LOperand* val)
1547 Handle<Object> name, 1522 : LStoreNamed(obj, val) { }
1548 LOperand* val,
1549 bool in_object,
1550 int offset,
1551 LOperand* temp,
1552 bool needs_write_barrier,
1553 Handle<Map> transition)
1554 : LStoreNamed(obj, name, val),
1555 is_in_object_(in_object),
1556 offset_(offset),
1557 temp_(temp),
1558 needs_write_barrier_(needs_write_barrier),
1559 transition_(transition) { }
1560 1523
1561 DECLARE_CONCRETE_INSTRUCTION(StoreNamedField, "store-named-field") 1524 DECLARE_CONCRETE_INSTRUCTION(StoreNamedField, "store-named-field")
1525 DECLARE_HYDROGEN_ACCESSOR(StoreNamedField)
1562 1526
1563 bool is_in_object() { return is_in_object_; } 1527 bool is_in_object() { return hydrogen()->is_in_object(); }
1564 int offset() { return offset_; } 1528 int offset() { return hydrogen()->offset(); }
1565 LOperand* temp() { return temp_; } 1529 bool needs_write_barrier() { return hydrogen()->NeedsWriteBarrier(); }
1566 bool needs_write_barrier() { return needs_write_barrier_; } 1530 Handle<Map> transition() const { return hydrogen()->transition(); }
1567 Handle<Map> transition() const { return transition_; }
1568 void set_transition(Handle<Map> map) { transition_ = map; }
1569
1570 private:
1571 bool is_in_object_;
1572 int offset_;
1573 LOperand* temp_;
1574 bool needs_write_barrier_;
1575 Handle<Map> transition_;
1576 }; 1531 };
1577 1532
1578 1533
1579 class LStoreNamedGeneric: public LStoreNamed { 1534 class LStoreNamedGeneric: public LStoreNamed {
1580 public: 1535 public:
1581 LStoreNamedGeneric(LOperand* obj, 1536 LStoreNamedGeneric(LOperand* obj, LOperand* val)
1582 Handle<Object> name, 1537 : LStoreNamed(obj, val) { }
1583 LOperand* val)
1584 : LStoreNamed(obj, name, val) { }
1585 1538
1586 DECLARE_CONCRETE_INSTRUCTION(StoreNamedGeneric, "store-named-generic") 1539 DECLARE_CONCRETE_INSTRUCTION(StoreNamedGeneric, "store-named-generic")
1540 DECLARE_HYDROGEN_ACCESSOR(StoreNamedGeneric)
1587 }; 1541 };
1588 1542
1589 1543
1590 class LStoreKeyed: public LInstruction { 1544 class LStoreKeyed: public LTemplateInstruction<0, 3, 0> {
1591 public: 1545 public:
1592 LStoreKeyed(LOperand* obj, LOperand* key, LOperand* val) 1546 LStoreKeyed(LOperand* obj, LOperand* key, LOperand* val) {
1593 : object_(obj), key_(key), value_(val) { } 1547 inputs_[0] = obj;
1548 inputs_[1] = key;
1549 inputs_[2] = val;
1550 }
1594 1551
1595 DECLARE_INSTRUCTION(StoreKeyed) 1552 DECLARE_INSTRUCTION(StoreKeyed)
1596 1553
1597 virtual void PrintDataTo(StringStream* stream) const; 1554 virtual void PrintDataTo(StringStream* stream);
1598 1555
1599 LOperand* object() const { return object_; } 1556 LOperand* object() { return inputs_[0]; }
1600 LOperand* key() const { return key_; } 1557 LOperand* key() { return inputs_[1]; }
1601 LOperand* value() const { return value_; } 1558 LOperand* value() { return inputs_[2]; }
1602
1603 private:
1604 LOperand* object_;
1605 LOperand* key_;
1606 LOperand* value_;
1607 }; 1559 };
1608 1560
1609 1561
1610 class LStoreKeyedFastElement: public LStoreKeyed { 1562 class LStoreKeyedFastElement: public LStoreKeyed {
1611 public: 1563 public:
1612 LStoreKeyedFastElement(LOperand* obj, LOperand* key, LOperand* val) 1564 LStoreKeyedFastElement(LOperand* obj, LOperand* key, LOperand* val)
1613 : LStoreKeyed(obj, key, val) {} 1565 : LStoreKeyed(obj, key, val) {}
1614 1566
1615 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedFastElement, 1567 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedFastElement,
1616 "store-keyed-fast-element") 1568 "store-keyed-fast-element")
1617 DECLARE_HYDROGEN_ACCESSOR(StoreKeyedFastElement) 1569 DECLARE_HYDROGEN_ACCESSOR(StoreKeyedFastElement)
1618 }; 1570 };
1619 1571
1620 1572
1621 class LStoreKeyedGeneric: public LStoreKeyed { 1573 class LStoreKeyedGeneric: public LStoreKeyed {
1622 public: 1574 public:
1623 LStoreKeyedGeneric(LOperand* obj, LOperand* key, LOperand* val) 1575 LStoreKeyedGeneric(LOperand* obj, LOperand* key, LOperand* val)
1624 : LStoreKeyed(obj, key, val) { } 1576 : LStoreKeyed(obj, key, val) { }
1625 1577
1626 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedGeneric, "store-keyed-generic") 1578 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedGeneric, "store-keyed-generic")
1627 }; 1579 };
1628 1580
1629 1581
1630 class LCheckFunction: public LUnaryOperation { 1582 class LStringCharCodeAt: public LTemplateInstruction<1, 2, 0> {
1631 public: 1583 public:
1632 explicit LCheckFunction(LOperand* use) : LUnaryOperation(use) { } 1584 LStringCharCodeAt(LOperand* string, LOperand* index) {
1585 inputs_[0] = string;
1586 inputs_[1] = index;
1587 }
1588
1589 DECLARE_CONCRETE_INSTRUCTION(StringCharCodeAt, "string-char-code-at")
1590 DECLARE_HYDROGEN_ACCESSOR(StringCharCodeAt)
1591
1592 LOperand* string() { return inputs_[0]; }
1593 LOperand* index() { return inputs_[1]; }
1594 };
1595
1596
1597 class LStringLength: public LTemplateInstruction<1, 1, 0> {
1598 public:
1599 explicit LStringLength(LOperand* string) {
1600 inputs_[0] = string;
1601 }
1602
1603 DECLARE_CONCRETE_INSTRUCTION(StringLength, "string-length")
1604 DECLARE_HYDROGEN_ACCESSOR(StringLength)
1605
1606 LOperand* string() { return inputs_[0]; }
1607 };
1608
1609
1610 class LCheckFunction: public LTemplateInstruction<0, 1, 0> {
1611 public:
1612 explicit LCheckFunction(LOperand* value) {
1613 inputs_[0] = value;
1614 }
1633 1615
1634 DECLARE_CONCRETE_INSTRUCTION(CheckFunction, "check-function") 1616 DECLARE_CONCRETE_INSTRUCTION(CheckFunction, "check-function")
1635 DECLARE_HYDROGEN_ACCESSOR(CheckFunction) 1617 DECLARE_HYDROGEN_ACCESSOR(CheckFunction)
1636 }; 1618 };
1637 1619
1638 1620
1639 class LCheckInstanceType: public LUnaryOperation { 1621 class LCheckInstanceType: public LTemplateInstruction<0, 1, 0> {
1640 public: 1622 public:
1641 LCheckInstanceType(LOperand* use, LOperand* temp) 1623 explicit LCheckInstanceType(LOperand* value) {
1642 : LUnaryOperation(use), temp_(temp) { } 1624 inputs_[0] = value;
1625 }
1643 1626
1644 DECLARE_CONCRETE_INSTRUCTION(CheckInstanceType, "check-instance-type") 1627 DECLARE_CONCRETE_INSTRUCTION(CheckInstanceType, "check-instance-type")
1645 DECLARE_HYDROGEN_ACCESSOR(CheckInstanceType) 1628 DECLARE_HYDROGEN_ACCESSOR(CheckInstanceType)
1646
1647 LOperand* temp() const { return temp_; }
1648
1649 private:
1650 LOperand* temp_;
1651 }; 1629 };
1652 1630
1653 1631
1654 class LCheckMap: public LUnaryOperation { 1632 class LCheckMap: public LTemplateInstruction<0, 1, 0> {
1655 public: 1633 public:
1656 explicit LCheckMap(LOperand* use) : LUnaryOperation(use) { } 1634 explicit LCheckMap(LOperand* value) {
1635 inputs_[0] = value;
1636 }
1657 1637
1658 DECLARE_CONCRETE_INSTRUCTION(CheckMap, "check-map") 1638 DECLARE_CONCRETE_INSTRUCTION(CheckMap, "check-map")
1659 DECLARE_HYDROGEN_ACCESSOR(CheckMap) 1639 DECLARE_HYDROGEN_ACCESSOR(CheckMap)
1660 }; 1640 };
1661 1641
1662 1642
1663 class LCheckPrototypeMaps: public LInstruction { 1643 class LCheckPrototypeMaps: public LTemplateInstruction<0, 0, 2> {
1664 public: 1644 public:
1665 LCheckPrototypeMaps(LOperand* temp1, 1645 LCheckPrototypeMaps(LOperand* temp1, LOperand* temp2) {
1666 LOperand* temp2, 1646 temps_[0] = temp1;
1667 Handle<JSObject> holder, 1647 temps_[1] = temp2;
1668 Handle<Map> receiver_map) 1648 }
1669 : temp1_(temp1),
1670 temp2_(temp2),
1671 holder_(holder),
1672 receiver_map_(receiver_map) { }
1673 1649
1674 DECLARE_CONCRETE_INSTRUCTION(CheckPrototypeMaps, "check-prototype-maps") 1650 DECLARE_CONCRETE_INSTRUCTION(CheckPrototypeMaps, "check-prototype-maps")
1651 DECLARE_HYDROGEN_ACCESSOR(CheckPrototypeMaps)
1675 1652
1676 LOperand* temp1() const { return temp1_; } 1653 Handle<JSObject> prototype() const { return hydrogen()->prototype(); }
1677 LOperand* temp2() const { return temp2_; } 1654 Handle<JSObject> holder() const { return hydrogen()->holder(); }
1678 Handle<JSObject> holder() const { return holder_; }
1679 Handle<Map> receiver_map() const { return receiver_map_; }
1680
1681 private:
1682 LOperand* temp1_;
1683 LOperand* temp2_;
1684 Handle<JSObject> holder_;
1685 Handle<Map> receiver_map_;
1686 }; 1655 };
1687 1656
1688 1657
1689 class LCheckSmi: public LUnaryOperation { 1658 class LCheckSmi: public LTemplateInstruction<0, 1, 0> {
1690 public: 1659 public:
1691 LCheckSmi(LOperand* use, Condition condition) 1660 LCheckSmi(LOperand* value, Condition condition)
1692 : LUnaryOperation(use), condition_(condition) { } 1661 : condition_(condition) {
1662 inputs_[0] = value;
1663 }
1693 1664
1694 Condition condition() const { return condition_; } 1665 Condition condition() const { return condition_; }
1695 1666
1696 virtual void CompileToNative(LCodeGen* generator); 1667 virtual void CompileToNative(LCodeGen* generator);
1697 virtual const char* Mnemonic() const { 1668 virtual const char* Mnemonic() const {
1698 return (condition_ == eq) ? "check-non-smi" : "check-smi"; 1669 return (condition_ == eq) ? "check-non-smi" : "check-smi";
1699 } 1670 }
1700 1671
1701 private: 1672 private:
1702 Condition condition_; 1673 Condition condition_;
1703 }; 1674 };
1704 1675
1705 1676
1706 class LMaterializedLiteral: public LInstruction { 1677 class LArrayLiteral: public LTemplateInstruction<1, 0, 0> {
1707 public:
1708 DECLARE_INSTRUCTION(MaterializedLiteral)
1709 };
1710
1711
1712 class LArrayLiteral: public LMaterializedLiteral {
1713 public: 1678 public:
1714 DECLARE_CONCRETE_INSTRUCTION(ArrayLiteral, "array-literal") 1679 DECLARE_CONCRETE_INSTRUCTION(ArrayLiteral, "array-literal")
1715 DECLARE_HYDROGEN_ACCESSOR(ArrayLiteral) 1680 DECLARE_HYDROGEN_ACCESSOR(ArrayLiteral)
1716 }; 1681 };
1717 1682
1718 1683
1719 class LObjectLiteral: public LMaterializedLiteral { 1684 class LObjectLiteral: public LTemplateInstruction<1, 0, 0> {
1720 public: 1685 public:
1721 DECLARE_CONCRETE_INSTRUCTION(ObjectLiteral, "object-literal") 1686 DECLARE_CONCRETE_INSTRUCTION(ObjectLiteral, "object-literal")
1722 DECLARE_HYDROGEN_ACCESSOR(ObjectLiteral) 1687 DECLARE_HYDROGEN_ACCESSOR(ObjectLiteral)
1723 }; 1688 };
1724 1689
1725 1690
1726 class LRegExpLiteral: public LMaterializedLiteral { 1691 class LRegExpLiteral: public LTemplateInstruction<1, 0, 0> {
1727 public: 1692 public:
1728 DECLARE_CONCRETE_INSTRUCTION(RegExpLiteral, "regexp-literal") 1693 DECLARE_CONCRETE_INSTRUCTION(RegExpLiteral, "regexp-literal")
1729 DECLARE_HYDROGEN_ACCESSOR(RegExpLiteral) 1694 DECLARE_HYDROGEN_ACCESSOR(RegExpLiteral)
1730 }; 1695 };
1731 1696
1732 1697
1733 class LFunctionLiteral: public LInstruction { 1698 class LFunctionLiteral: public LTemplateInstruction<1, 0, 0> {
1734 public: 1699 public:
1735 DECLARE_CONCRETE_INSTRUCTION(FunctionLiteral, "function-literal") 1700 DECLARE_CONCRETE_INSTRUCTION(FunctionLiteral, "function-literal")
1736 DECLARE_HYDROGEN_ACCESSOR(FunctionLiteral) 1701 DECLARE_HYDROGEN_ACCESSOR(FunctionLiteral)
1737 1702
1738 Handle<SharedFunctionInfo> shared_info() { return hydrogen()->shared_info(); } 1703 Handle<SharedFunctionInfo> shared_info() { return hydrogen()->shared_info(); }
1739 }; 1704 };
1740 1705
1741 1706
1742 class LTypeof: public LUnaryOperation { 1707 class LTypeof: public LTemplateInstruction<1, 1, 0> {
1743 public: 1708 public:
1744 explicit LTypeof(LOperand* input) : LUnaryOperation(input) { } 1709 explicit LTypeof(LOperand* value) {
1710 inputs_[0] = value;
1711 }
1745 1712
1746 DECLARE_CONCRETE_INSTRUCTION(Typeof, "typeof") 1713 DECLARE_CONCRETE_INSTRUCTION(Typeof, "typeof")
1747 }; 1714 };
1748 1715
1749 1716
1750 class LTypeofIs: public LUnaryOperation { 1717 class LTypeofIs: public LTemplateInstruction<1, 1, 0> {
1751 public: 1718 public:
1752 explicit LTypeofIs(LOperand* input) : LUnaryOperation(input) { } 1719 explicit LTypeofIs(LOperand* value) {
1753 virtual void PrintDataTo(StringStream* stream) const; 1720 inputs_[0] = value;
1721 }
1754 1722
1755 DECLARE_CONCRETE_INSTRUCTION(TypeofIs, "typeof-is") 1723 DECLARE_CONCRETE_INSTRUCTION(TypeofIs, "typeof-is")
1756 DECLARE_HYDROGEN_ACCESSOR(TypeofIs) 1724 DECLARE_HYDROGEN_ACCESSOR(TypeofIs)
1757 1725
1758 Handle<String> type_literal() { return hydrogen()->type_literal(); } 1726 Handle<String> type_literal() { return hydrogen()->type_literal(); }
1727
1728 virtual void PrintDataTo(StringStream* stream);
1759 }; 1729 };
1760 1730
1761 1731
1762 class LTypeofIsAndBranch: public LTypeofIs { 1732 class LTypeofIsAndBranch: public LControlInstruction<1, 0> {
1763 public: 1733 public:
1764 LTypeofIsAndBranch(LOperand* value, 1734 explicit LTypeofIsAndBranch(LOperand* value) {
1765 int true_block_id, 1735 inputs_[0] = value;
1766 int false_block_id) 1736 }
1767 : LTypeofIs(value),
1768 true_block_id_(true_block_id),
1769 false_block_id_(false_block_id) { }
1770 1737
1771 DECLARE_CONCRETE_INSTRUCTION(TypeofIsAndBranch, "typeof-is-and-branch") 1738 DECLARE_CONCRETE_INSTRUCTION(TypeofIsAndBranch, "typeof-is-and-branch")
1739 DECLARE_HYDROGEN_ACCESSOR(TypeofIs)
1772 1740
1773 virtual void PrintDataTo(StringStream* stream) const; 1741 Handle<String> type_literal() { return hydrogen()->type_literal(); }
1774 virtual bool IsControl() const { return true; }
1775 1742
1776 int true_block_id() const { return true_block_id_; } 1743 virtual void PrintDataTo(StringStream* stream);
1777 int false_block_id() const { return false_block_id_; }
1778
1779 private:
1780 int true_block_id_;
1781 int false_block_id_;
1782 }; 1744 };
1783 1745
1784 1746
1785 class LDeleteProperty: public LBinaryOperation { 1747 class LIsConstructCall: public LTemplateInstruction<1, 0, 0> {
1786 public: 1748 public:
1787 LDeleteProperty(LOperand* obj, LOperand* key) : LBinaryOperation(obj, key) {} 1749 DECLARE_CONCRETE_INSTRUCTION(IsConstructCall, "is-construct-call")
1750 DECLARE_HYDROGEN_ACCESSOR(IsConstructCall)
1751 };
1752
1753
1754 class LIsConstructCallAndBranch: public LControlInstruction<0, 1> {
1755 public:
1756 explicit LIsConstructCallAndBranch(LOperand* temp) {
1757 temps_[0] = temp;
1758 }
1759
1760 DECLARE_CONCRETE_INSTRUCTION(IsConstructCallAndBranch,
1761 "is-construct-call-and-branch")
1762 };
1763
1764
1765 class LDeleteProperty: public LTemplateInstruction<1, 2, 0> {
1766 public:
1767 LDeleteProperty(LOperand* obj, LOperand* key) {
1768 inputs_[0] = obj;
1769 inputs_[1] = key;
1770 }
1788 1771
1789 DECLARE_CONCRETE_INSTRUCTION(DeleteProperty, "delete-property") 1772 DECLARE_CONCRETE_INSTRUCTION(DeleteProperty, "delete-property")
1790 1773
1791 LOperand* object() const { return left(); } 1774 LOperand* object() { return inputs_[0]; }
1792 LOperand* key() const { return right(); } 1775 LOperand* key() { return inputs_[1]; }
1793 }; 1776 };
1794 1777
1795 1778
1796 class LOsrEntry: public LInstruction { 1779 class LOsrEntry: public LTemplateInstruction<0, 0, 0> {
1797 public: 1780 public:
1798 LOsrEntry(); 1781 LOsrEntry();
1799 1782
1800 DECLARE_CONCRETE_INSTRUCTION(OsrEntry, "osr-entry") 1783 DECLARE_CONCRETE_INSTRUCTION(OsrEntry, "osr-entry")
1801 1784
1802 LOperand** SpilledRegisterArray() { return register_spills_; } 1785 LOperand** SpilledRegisterArray() { return register_spills_; }
1803 LOperand** SpilledDoubleRegisterArray() { return double_register_spills_; } 1786 LOperand** SpilledDoubleRegisterArray() { return double_register_spills_; }
1804 1787
1805 void MarkSpilledRegister(int allocation_index, LOperand* spill_operand); 1788 void MarkSpilledRegister(int allocation_index, LOperand* spill_operand);
1806 void MarkSpilledDoubleRegister(int allocation_index, 1789 void MarkSpilledDoubleRegister(int allocation_index,
1807 LOperand* spill_operand); 1790 LOperand* spill_operand);
1808 1791
1809 private: 1792 private:
1810 // Arrays of spill slot operands for registers with an assigned spill 1793 // Arrays of spill slot operands for registers with an assigned spill
1811 // slot, i.e., that must also be restored to the spill slot on OSR entry. 1794 // slot, i.e., that must also be restored to the spill slot on OSR entry.
1812 // NULL if the register has no assigned spill slot. Indexed by allocation 1795 // NULL if the register has no assigned spill slot. Indexed by allocation
1813 // index. 1796 // index.
1814 LOperand* register_spills_[Register::kNumAllocatableRegisters]; 1797 LOperand* register_spills_[Register::kNumAllocatableRegisters];
1815 LOperand* double_register_spills_[DoubleRegister::kNumAllocatableRegisters]; 1798 LOperand* double_register_spills_[DoubleRegister::kNumAllocatableRegisters];
1816 }; 1799 };
1817 1800
1818 1801
1819 class LStackCheck: public LInstruction { 1802 class LStackCheck: public LTemplateInstruction<0, 0, 0> {
1820 public: 1803 public:
1821 DECLARE_CONCRETE_INSTRUCTION(StackCheck, "stack-check") 1804 DECLARE_CONCRETE_INSTRUCTION(StackCheck, "stack-check")
1822 }; 1805 };
1823 1806
1824 1807
1825 class LPointerMap: public ZoneObject {
1826 public:
1827 explicit LPointerMap(int position)
1828 : pointer_operands_(8), position_(position), lithium_position_(-1) { }
1829
1830 const ZoneList<LOperand*>* operands() const { return &pointer_operands_; }
1831 int position() const { return position_; }
1832 int lithium_position() const { return lithium_position_; }
1833
1834 void set_lithium_position(int pos) {
1835 ASSERT(lithium_position_ == -1);
1836 lithium_position_ = pos;
1837 }
1838
1839 void RecordPointer(LOperand* op);
1840 void PrintTo(StringStream* stream) const;
1841
1842 private:
1843 ZoneList<LOperand*> pointer_operands_;
1844 int position_;
1845 int lithium_position_;
1846 };
1847
1848
1849 class LEnvironment: public ZoneObject {
1850 public:
1851 LEnvironment(Handle<JSFunction> closure,
1852 int ast_id,
1853 int parameter_count,
1854 int argument_count,
1855 int value_count,
1856 LEnvironment* outer)
1857 : closure_(closure),
1858 arguments_stack_height_(argument_count),
1859 deoptimization_index_(Safepoint::kNoDeoptimizationIndex),
1860 translation_index_(-1),
1861 ast_id_(ast_id),
1862 parameter_count_(parameter_count),
1863 values_(value_count),
1864 representations_(value_count),
1865 spilled_registers_(NULL),
1866 spilled_double_registers_(NULL),
1867 outer_(outer) {
1868 }
1869
1870 Handle<JSFunction> closure() const { return closure_; }
1871 int arguments_stack_height() const { return arguments_stack_height_; }
1872 int deoptimization_index() const { return deoptimization_index_; }
1873 int translation_index() const { return translation_index_; }
1874 int ast_id() const { return ast_id_; }
1875 int parameter_count() const { return parameter_count_; }
1876 const ZoneList<LOperand*>* values() const { return &values_; }
1877 LEnvironment* outer() const { return outer_; }
1878
1879 void AddValue(LOperand* operand, Representation representation) {
1880 values_.Add(operand);
1881 representations_.Add(representation);
1882 }
1883
1884 bool HasTaggedValueAt(int index) const {
1885 return representations_[index].IsTagged();
1886 }
1887
1888 void Register(int deoptimization_index, int translation_index) {
1889 ASSERT(!HasBeenRegistered());
1890 deoptimization_index_ = deoptimization_index;
1891 translation_index_ = translation_index;
1892 }
1893 bool HasBeenRegistered() const {
1894 return deoptimization_index_ != Safepoint::kNoDeoptimizationIndex;
1895 }
1896
1897 void SetSpilledRegisters(LOperand** registers,
1898 LOperand** double_registers) {
1899 spilled_registers_ = registers;
1900 spilled_double_registers_ = double_registers;
1901 }
1902
1903 // Emit frame translation commands for this environment.
1904 void WriteTranslation(LCodeGen* cgen, Translation* translation) const;
1905
1906 void PrintTo(StringStream* stream) const;
1907
1908 private:
1909 Handle<JSFunction> closure_;
1910 int arguments_stack_height_;
1911 int deoptimization_index_;
1912 int translation_index_;
1913 int ast_id_;
1914 int parameter_count_;
1915 ZoneList<LOperand*> values_;
1916 ZoneList<Representation> representations_;
1917
1918 // Allocation index indexed arrays of spill slot operands for registers
1919 // that are also in spill slots at an OSR entry. NULL for environments
1920 // that do not correspond to an OSR entry.
1921 LOperand** spilled_registers_;
1922 LOperand** spilled_double_registers_;
1923
1924 LEnvironment* outer_;
1925 };
1926
1927 class LChunkBuilder; 1808 class LChunkBuilder;
1928 class LChunk: public ZoneObject { 1809 class LChunk: public ZoneObject {
1929 public: 1810 public:
1930 explicit LChunk(HGraph* graph); 1811 explicit LChunk(HGraph* graph);
1931 1812
1932 int AddInstruction(LInstruction* instruction, HBasicBlock* block); 1813 void AddInstruction(LInstruction* instruction, HBasicBlock* block);
1933 LConstantOperand* DefineConstantOperand(HConstant* constant); 1814 LConstantOperand* DefineConstantOperand(HConstant* constant);
1934 Handle<Object> LookupLiteral(LConstantOperand* operand) const; 1815 Handle<Object> LookupLiteral(LConstantOperand* operand) const;
1935 Representation LookupLiteralRepresentation(LConstantOperand* operand) const; 1816 Representation LookupLiteralRepresentation(LConstantOperand* operand) const;
1936 1817
1937 int GetNextSpillIndex(bool is_double); 1818 int GetNextSpillIndex(bool is_double);
1938 LOperand* GetNextSpillSlot(bool is_double); 1819 LOperand* GetNextSpillSlot(bool is_double);
1939 1820
1940 int ParameterAt(int index); 1821 int ParameterAt(int index);
1941 int GetParameterStackSlot(int index) const; 1822 int GetParameterStackSlot(int index) const;
1942 int spill_slot_count() const { return spill_slot_count_; } 1823 int spill_slot_count() const { return spill_slot_count_; }
(...skipping 24 matching lines...) Expand all
1967 } 1848 }
1968 1849
1969 const ZoneList<Handle<JSFunction> >* inlined_closures() const { 1850 const ZoneList<Handle<JSFunction> >* inlined_closures() const {
1970 return &inlined_closures_; 1851 return &inlined_closures_;
1971 } 1852 }
1972 1853
1973 void AddInlinedClosure(Handle<JSFunction> closure) { 1854 void AddInlinedClosure(Handle<JSFunction> closure) {
1974 inlined_closures_.Add(closure); 1855 inlined_closures_.Add(closure);
1975 } 1856 }
1976 1857
1977 void Verify() const;
1978
1979 private: 1858 private:
1980 int spill_slot_count_; 1859 int spill_slot_count_;
1981 HGraph* const graph_; 1860 HGraph* const graph_;
1982 ZoneList<LInstruction*> instructions_; 1861 ZoneList<LInstruction*> instructions_;
1983 ZoneList<LPointerMap*> pointer_maps_; 1862 ZoneList<LPointerMap*> pointer_maps_;
1984 ZoneList<Handle<JSFunction> > inlined_closures_; 1863 ZoneList<Handle<JSFunction> > inlined_closures_;
1985 }; 1864 };
1986 1865
1987 1866
1988 class LChunkBuilder BASE_EMBEDDED { 1867 class LChunkBuilder BASE_EMBEDDED {
1989 public: 1868 public:
1990 LChunkBuilder(HGraph* graph, LAllocator* allocator) 1869 LChunkBuilder(HGraph* graph, LAllocator* allocator)
1991 : chunk_(NULL), 1870 : chunk_(NULL),
1992 graph_(graph), 1871 graph_(graph),
1993 status_(UNUSED), 1872 status_(UNUSED),
1994 current_instruction_(NULL), 1873 current_instruction_(NULL),
1995 current_block_(NULL), 1874 current_block_(NULL),
1996 next_block_(NULL), 1875 next_block_(NULL),
1997 argument_count_(0), 1876 argument_count_(0),
1998 allocator_(allocator), 1877 allocator_(allocator),
1999 position_(RelocInfo::kNoPosition), 1878 position_(RelocInfo::kNoPosition),
2000 instructions_pending_deoptimization_environment_(NULL), 1879 instruction_pending_deoptimization_environment_(NULL),
2001 pending_deoptimization_ast_id_(AstNode::kNoNumber) { } 1880 pending_deoptimization_ast_id_(AstNode::kNoNumber) { }
2002 1881
2003 // Build the sequence for the graph. 1882 // Build the sequence for the graph.
2004 LChunk* Build(); 1883 LChunk* Build();
2005 1884
2006 // Declare methods that deal with the individual node types. 1885 // Declare methods that deal with the individual node types.
2007 #define DECLARE_DO(type) LInstruction* Do##type(H##type* node); 1886 #define DECLARE_DO(type) LInstruction* Do##type(H##type* node);
2008 HYDROGEN_CONCRETE_INSTRUCTION_LIST(DECLARE_DO) 1887 HYDROGEN_CONCRETE_INSTRUCTION_LIST(DECLARE_DO)
2009 #undef DECLARE_DO 1888 #undef DECLARE_DO
2010 1889
(...skipping 14 matching lines...) Expand all
2025 bool is_aborted() const { return status_ == ABORTED; } 1904 bool is_aborted() const { return status_ == ABORTED; }
2026 1905
2027 void Abort(const char* format, ...); 1906 void Abort(const char* format, ...);
2028 1907
2029 // Methods for getting operands for Use / Define / Temp. 1908 // Methods for getting operands for Use / Define / Temp.
2030 LRegister* ToOperand(Register reg); 1909 LRegister* ToOperand(Register reg);
2031 LUnallocated* ToUnallocated(Register reg); 1910 LUnallocated* ToUnallocated(Register reg);
2032 LUnallocated* ToUnallocated(DoubleRegister reg); 1911 LUnallocated* ToUnallocated(DoubleRegister reg);
2033 1912
2034 // Methods for setting up define-use relationships. 1913 // Methods for setting up define-use relationships.
2035 LOperand* Use(HValue* value, LUnallocated* operand); 1914 MUST_USE_RESULT LOperand* Use(HValue* value, LUnallocated* operand);
2036 LOperand* UseFixed(HValue* value, Register fixed_register); 1915 MUST_USE_RESULT LOperand* UseFixed(HValue* value, Register fixed_register);
2037 LOperand* UseFixedDouble(HValue* value, DoubleRegister fixed_register); 1916 MUST_USE_RESULT LOperand* UseFixedDouble(HValue* value,
1917 DoubleRegister fixed_register);
2038 1918
2039 // A value that is guaranteed to be allocated to a register. 1919 // A value that is guaranteed to be allocated to a register.
2040 // Operand created by UseRegister is guaranteed to be live until the end of 1920 // Operand created by UseRegister is guaranteed to be live until the end of
2041 // instruction. This means that register allocator will not reuse it's 1921 // instruction. This means that register allocator will not reuse it's
2042 // register for any other operand inside instruction. 1922 // register for any other operand inside instruction.
2043 // Operand created by UseRegisterAtStart is guaranteed to be live only at 1923 // Operand created by UseRegisterAtStart is guaranteed to be live only at
2044 // instruction start. Register allocator is free to assign the same register 1924 // instruction start. Register allocator is free to assign the same register
2045 // to some other operand used inside instruction (i.e. temporary or 1925 // to some other operand used inside instruction (i.e. temporary or
2046 // output). 1926 // output).
2047 LOperand* UseRegister(HValue* value); 1927 MUST_USE_RESULT LOperand* UseRegister(HValue* value);
2048 LOperand* UseRegisterAtStart(HValue* value); 1928 MUST_USE_RESULT LOperand* UseRegisterAtStart(HValue* value);
2049 1929
2050 // A value in a register that may be trashed. 1930 // An input operand in a register that may be trashed.
2051 LOperand* UseTempRegister(HValue* value); 1931 MUST_USE_RESULT LOperand* UseTempRegister(HValue* value);
2052 LOperand* Use(HValue* value); 1932
2053 LOperand* UseAtStart(HValue* value); 1933 // An input operand in a register or stack slot.
2054 LOperand* UseOrConstant(HValue* value); 1934 MUST_USE_RESULT LOperand* Use(HValue* value);
2055 LOperand* UseOrConstantAtStart(HValue* value); 1935 MUST_USE_RESULT LOperand* UseAtStart(HValue* value);
2056 LOperand* UseRegisterOrConstant(HValue* value); 1936
2057 LOperand* UseRegisterOrConstantAtStart(HValue* value); 1937 // An input operand in a register, stack slot or a constant operand.
1938 MUST_USE_RESULT LOperand* UseOrConstant(HValue* value);
1939 MUST_USE_RESULT LOperand* UseOrConstantAtStart(HValue* value);
1940
1941 // An input operand in a register or a constant operand.
1942 MUST_USE_RESULT LOperand* UseRegisterOrConstant(HValue* value);
1943 MUST_USE_RESULT LOperand* UseRegisterOrConstantAtStart(HValue* value);
1944
1945 // An input operand in register, stack slot or a constant operand.
1946 // Will not be moved to a register even if one is freely available.
1947 MUST_USE_RESULT LOperand* UseAny(HValue* value);
1948
1949 // Temporary operand that must be in a register.
1950 MUST_USE_RESULT LUnallocated* TempRegister();
1951 MUST_USE_RESULT LOperand* FixedTemp(Register reg);
1952 MUST_USE_RESULT LOperand* FixedTemp(DoubleRegister reg);
2058 1953
2059 // Methods for setting up define-use relationships. 1954 // Methods for setting up define-use relationships.
2060 // Return the same instruction that they are passed. 1955 // Return the same instruction that they are passed.
2061 LInstruction* Define(LInstruction* instr, LUnallocated* result); 1956 template<int I, int T>
2062 LInstruction* Define(LInstruction* instr); 1957 LInstruction* Define(LTemplateInstruction<1, I, T>* instr,
2063 LInstruction* DefineAsRegister(LInstruction* instr); 1958 LUnallocated* result);
2064 LInstruction* DefineAsSpilled(LInstruction* instr, int index); 1959 template<int I, int T>
2065 LInstruction* DefineSameAsFirst(LInstruction* instr); 1960 LInstruction* Define(LTemplateInstruction<1, I, T>* instr);
2066 LInstruction* DefineFixed(LInstruction* instr, Register reg); 1961 template<int I, int T>
2067 LInstruction* DefineFixedDouble(LInstruction* instr, DoubleRegister reg); 1962 LInstruction* DefineAsRegister(LTemplateInstruction<1, I, T>* instr);
1963 template<int I, int T>
1964 LInstruction* DefineAsSpilled(LTemplateInstruction<1, I, T>* instr,
1965 int index);
1966 template<int I, int T>
1967 LInstruction* DefineSameAsFirst(LTemplateInstruction<1, I, T>* instr);
1968 template<int I, int T>
1969 LInstruction* DefineFixed(LTemplateInstruction<1, I, T>* instr,
1970 Register reg);
1971 template<int I, int T>
1972 LInstruction* DefineFixedDouble(LTemplateInstruction<1, I, T>* instr,
1973 DoubleRegister reg);
2068 LInstruction* AssignEnvironment(LInstruction* instr); 1974 LInstruction* AssignEnvironment(LInstruction* instr);
2069 LInstruction* AssignPointerMap(LInstruction* instr); 1975 LInstruction* AssignPointerMap(LInstruction* instr);
2070 1976
2071 enum CanDeoptimize { CAN_DEOPTIMIZE_EAGERLY, CANNOT_DEOPTIMIZE_EAGERLY }; 1977 enum CanDeoptimize { CAN_DEOPTIMIZE_EAGERLY, CANNOT_DEOPTIMIZE_EAGERLY };
2072 1978
2073 // By default we assume that instruction sequences generated for calls 1979 // By default we assume that instruction sequences generated for calls
2074 // cannot deoptimize eagerly and we do not attach environment to this 1980 // cannot deoptimize eagerly and we do not attach environment to this
2075 // instruction. 1981 // instruction.
2076 LInstruction* MarkAsCall( 1982 LInstruction* MarkAsCall(
2077 LInstruction* instr, 1983 LInstruction* instr,
2078 HInstruction* hinstr, 1984 HInstruction* hinstr,
2079 CanDeoptimize can_deoptimize = CANNOT_DEOPTIMIZE_EAGERLY); 1985 CanDeoptimize can_deoptimize = CANNOT_DEOPTIMIZE_EAGERLY);
1986 LInstruction* MarkAsSaveDoubles(LInstruction* instr);
2080 1987
2081 LInstruction* SetInstructionPendingDeoptimizationEnvironment( 1988 LInstruction* SetInstructionPendingDeoptimizationEnvironment(
2082 LInstruction* instr, int ast_id); 1989 LInstruction* instr, int ast_id);
2083 void ClearInstructionPendingDeoptimizationEnvironment(); 1990 void ClearInstructionPendingDeoptimizationEnvironment();
2084 1991
2085 LEnvironment* CreateEnvironment(HEnvironment* hydrogen_env); 1992 LEnvironment* CreateEnvironment(HEnvironment* hydrogen_env);
2086 1993
2087 // Temporary operand that may be a memory location.
2088 LOperand* Temp();
2089 // Temporary operand that must be in a register.
2090 LUnallocated* TempRegister();
2091 LOperand* FixedTemp(Register reg);
2092 LOperand* FixedTemp(DoubleRegister reg);
2093
2094 void VisitInstruction(HInstruction* current); 1994 void VisitInstruction(HInstruction* current);
2095 1995
2096 void DoBasicBlock(HBasicBlock* block, HBasicBlock* next_block); 1996 void DoBasicBlock(HBasicBlock* block, HBasicBlock* next_block);
2097 LInstruction* DoBit(Token::Value op, HBitwiseBinaryOperation* instr); 1997 LInstruction* DoBit(Token::Value op, HBitwiseBinaryOperation* instr);
2098 LInstruction* DoShift(Token::Value op, HBitwiseBinaryOperation* instr); 1998 LInstruction* DoShift(Token::Value op, HBitwiseBinaryOperation* instr);
2099 LInstruction* DoArithmeticD(Token::Value op, 1999 LInstruction* DoArithmeticD(Token::Value op,
2100 HArithmeticBinaryOperation* instr); 2000 HArithmeticBinaryOperation* instr);
2101 LInstruction* DoArithmeticT(Token::Value op, 2001 LInstruction* DoArithmeticT(Token::Value op,
2102 HArithmeticBinaryOperation* instr); 2002 HArithmeticBinaryOperation* instr);
2103 2003
2104 LChunk* chunk_; 2004 LChunk* chunk_;
2105 HGraph* const graph_; 2005 HGraph* const graph_;
2106 Status status_; 2006 Status status_;
2107 HInstruction* current_instruction_; 2007 HInstruction* current_instruction_;
2108 HBasicBlock* current_block_; 2008 HBasicBlock* current_block_;
2109 HBasicBlock* next_block_; 2009 HBasicBlock* next_block_;
2110 int argument_count_; 2010 int argument_count_;
2111 LAllocator* allocator_; 2011 LAllocator* allocator_;
2112 int position_; 2012 int position_;
2113 LInstruction* instructions_pending_deoptimization_environment_; 2013 LInstruction* instruction_pending_deoptimization_environment_;
2114 int pending_deoptimization_ast_id_; 2014 int pending_deoptimization_ast_id_;
2115 2015
2116 DISALLOW_COPY_AND_ASSIGN(LChunkBuilder); 2016 DISALLOW_COPY_AND_ASSIGN(LChunkBuilder);
2117 }; 2017 };
2118 2018
2119 #undef DECLARE_HYDROGEN_ACCESSOR 2019 #undef DECLARE_HYDROGEN_ACCESSOR
2120 #undef DECLARE_INSTRUCTION 2020 #undef DECLARE_INSTRUCTION
2121 #undef DECLARE_CONCRETE_INSTRUCTION 2021 #undef DECLARE_CONCRETE_INSTRUCTION
2122 2022
2123 } } // namespace v8::internal 2023 } } // namespace v8::internal
2124 2024
2125 #endif // V8_ARM_LITHIUM_ARM_H_ 2025 #endif // V8_ARM_LITHIUM_ARM_H_
OLDNEW
« no previous file with comments | « src/arm/jump-target-arm.cc ('k') | src/arm/lithium-arm.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698