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

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

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

Powered by Google App Engine
This is Rietveld 408576698