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

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

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

Powered by Google App Engine
This is Rietveld 408576698