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

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

Issue 6201006: X64 Crankshaft: Ported lots of boilerplate code. (Closed)
Patch Set: Addressed review comments. Updated to match newest ia32 version. 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
« no previous file with comments | « src/x64/lithium-codegen-x64.cc ('k') | src/x64/lithium-x64.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 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 // LCheckPrototypeMaps
81 // LConstant
82 // LConstantD
83 // LConstantI
84 // LConstantT
46 // LDeoptimize 85 // LDeoptimize
86 // LFunctionLiteral
47 // LGap 87 // LGap
48 // LLabel 88 // LLabel
89 // LGlobalObject
90 // LGlobalReceiver
49 // LGoto 91 // LGoto
50 // LLazyBailout 92 // LLazyBailout
93 // LLoadGlobal
94 // LMaterializedLiteral
95 // LArrayLiteral
96 // LObjectLiteral
97 // LRegExpLiteral
51 // LOsrEntry 98 // LOsrEntry
99 // LParameter
100 // LRegExpConstructResult
101 // LStackCheck
102 // LStoreKeyed
103 // LStoreKeyedFastElement
104 // LStoreKeyedGeneric
105 // LStoreNamed
106 // LStoreNamedField
107 // LStoreNamedGeneric
108 // LUnaryOperation
109 // LBitNotI
110 // LBranch
111 // LCallNew
112 // LCheckFunction
113 // LCheckInstanceType
114 // LCheckMap
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(LOperand* left, LOperand* right)
637 : LBinaryOperation<1>(left, right) { }
638
639 Token::Value op() const { return hydrogen()->token(); }
640 bool is_double() const {
641 return hydrogen()->GetInputRepresentation().IsDouble();
642 }
643
644 DECLARE_CONCRETE_INSTRUCTION(CmpID, "cmp-id")
645 DECLARE_HYDROGEN_ACCESSOR(Compare)
646 };
647
648
649 class LCmpIDAndBranch: public LCmpID {
650 public:
651 LCmpIDAndBranch(LOperand* left,
652 LOperand* right,
653 int true_block_id,
654 int false_block_id)
655 : LCmpID(left, right),
656 true_block_id_(true_block_id),
657 false_block_id_(false_block_id) { }
658
659 DECLARE_CONCRETE_INSTRUCTION(CmpIDAndBranch, "cmp-id-and-branch")
660 virtual void PrintDataTo(StringStream* stream);
661 virtual bool IsControl() const { return true; }
662
663 int true_block_id() const { return true_block_id_; }
664 int false_block_id() const { return false_block_id_; }
665
666 private:
667 int true_block_id_;
668 int false_block_id_;
669 };
670
671
672 class LUnaryMathOperation: public LUnaryOperation<1> {
673 public:
674 explicit LUnaryMathOperation(LOperand* value)
675 : LUnaryOperation<1>(value) { }
676
677 DECLARE_CONCRETE_INSTRUCTION(UnaryMathOperation, "unary-math-operation")
678 DECLARE_HYDROGEN_ACCESSOR(UnaryMathOperation)
679
680 virtual void PrintDataTo(StringStream* stream);
681 BuiltinFunctionId op() const { return hydrogen()->op(); }
682 };
683
684
685 class LCmpJSObjectEq: public LBinaryOperation<1> {
686 public:
687 LCmpJSObjectEq(LOperand* left, LOperand* right)
688 : LBinaryOperation<1>(left, right) {}
689
690 DECLARE_CONCRETE_INSTRUCTION(CmpJSObjectEq, "cmp-jsobject-eq")
691 };
692
693
694 class LCmpJSObjectEqAndBranch: public LCmpJSObjectEq {
695 public:
696 LCmpJSObjectEqAndBranch(LOperand* left,
697 LOperand* right,
698 int true_block_id,
699 int false_block_id)
700 : LCmpJSObjectEq(left, right),
701 true_block_id_(true_block_id),
702 false_block_id_(false_block_id) { }
703
704 DECLARE_CONCRETE_INSTRUCTION(CmpJSObjectEqAndBranch,
705 "cmp-jsobject-eq-and-branch")
706
707 int true_block_id() const { return true_block_id_; }
708 int false_block_id() const { return false_block_id_; }
709
710 private:
711 int true_block_id_;
712 int false_block_id_;
713 };
714
715
716 class LIsNull: public LUnaryOperation<1> {
717 public:
718 explicit LIsNull(LOperand* value) : LUnaryOperation<1>(value) { }
719
720 DECLARE_CONCRETE_INSTRUCTION(IsNull, "is-null")
721 DECLARE_HYDROGEN_ACCESSOR(IsNull)
722
723 bool is_strict() const { return hydrogen()->is_strict(); }
724 };
725
726
727 class LIsNullAndBranch: public LIsNull {
728 public:
729 LIsNullAndBranch(LOperand* value,
730 LOperand* temp,
731 int true_block_id,
732 int false_block_id)
733 : LIsNull(value),
734 temp_(temp),
735 true_block_id_(true_block_id),
736 false_block_id_(false_block_id) { }
737
738 DECLARE_CONCRETE_INSTRUCTION(IsNullAndBranch, "is-null-and-branch")
739 virtual void PrintDataTo(StringStream* stream);
740 virtual bool IsControl() const { return true; }
741
742 int true_block_id() const { return true_block_id_; }
743 int false_block_id() const { return false_block_id_; }
744
745 LOperand* temp() const { return temp_; }
746
747 private:
748 LOperand* temp_;
749 int true_block_id_;
750 int false_block_id_;
751 };
752
753
754 class LIsObject: public LUnaryOperation<1> {
755 public:
756 LIsObject(LOperand* value, LOperand* temp)
757 : LUnaryOperation<1>(value), temp_(temp) {}
758
759 DECLARE_CONCRETE_INSTRUCTION(IsObject, "is-object")
760
761 LOperand* temp() const { return temp_; }
762
763 private:
764 LOperand* temp_;
765 };
766
767
768 class LIsObjectAndBranch: public LIsObject {
769 public:
770 LIsObjectAndBranch(LOperand* value,
771 LOperand* temp,
772 LOperand* temp2,
773 int true_block_id,
774 int false_block_id)
775 : LIsObject(value, temp),
776 temp2_(temp2),
777 true_block_id_(true_block_id),
778 false_block_id_(false_block_id) { }
779
780 DECLARE_CONCRETE_INSTRUCTION(IsObjectAndBranch, "is-object-and-branch")
781 virtual void PrintDataTo(StringStream* stream);
782 virtual bool IsControl() const { return true; }
783
784 int true_block_id() const { return true_block_id_; }
785 int false_block_id() const { return false_block_id_; }
786
787 LOperand* temp2() const { return temp2_; }
788
789 private:
790 LOperand* temp2_;
791 int true_block_id_;
792 int false_block_id_;
793 };
794
795
796 class LIsSmi: public LUnaryOperation<1> {
797 public:
798 explicit LIsSmi(LOperand* value) : LUnaryOperation<1>(value) {}
799
800 DECLARE_CONCRETE_INSTRUCTION(IsSmi, "is-smi")
801 DECLARE_HYDROGEN_ACCESSOR(IsSmi)
802 };
803
804
805 class LIsSmiAndBranch: public LIsSmi {
806 public:
807 LIsSmiAndBranch(LOperand* value,
808 int true_block_id,
809 int false_block_id)
810 : LIsSmi(value),
811 true_block_id_(true_block_id),
812 false_block_id_(false_block_id) { }
813
814 DECLARE_CONCRETE_INSTRUCTION(IsSmiAndBranch, "is-smi-and-branch")
815 virtual void PrintDataTo(StringStream* stream);
816 virtual bool IsControl() const { return true; }
817
818 int true_block_id() const { return true_block_id_; }
819 int false_block_id() const { return false_block_id_; }
820
821 private:
822 int true_block_id_;
823 int false_block_id_;
824 };
825
826
827 class LHasInstanceType: public LUnaryOperation<1> {
828 public:
829 explicit LHasInstanceType(LOperand* value)
830 : LUnaryOperation<1>(value) { }
831
832 DECLARE_CONCRETE_INSTRUCTION(HasInstanceType, "has-instance-type")
833 DECLARE_HYDROGEN_ACCESSOR(HasInstanceType)
834
835 InstanceType TestType(); // The type to test against when generating code.
836 Condition BranchCondition(); // The branch condition for 'true'.
837 };
838
839
840 class LHasInstanceTypeAndBranch: public LHasInstanceType {
841 public:
842 LHasInstanceTypeAndBranch(LOperand* value,
843 LOperand* temporary,
844 int true_block_id,
845 int false_block_id)
846 : LHasInstanceType(value),
847 temp_(temporary),
848 true_block_id_(true_block_id),
849 false_block_id_(false_block_id) { }
850
851 DECLARE_CONCRETE_INSTRUCTION(HasInstanceTypeAndBranch,
852 "has-instance-type-and-branch")
853 virtual void PrintDataTo(StringStream* stream);
854 virtual bool IsControl() const { return true; }
855
856 int true_block_id() const { return true_block_id_; }
857 int false_block_id() const { return false_block_id_; }
858
859 LOperand* temp() { return temp_; }
860
861 private:
862 LOperand* temp_;
863 int true_block_id_;
864 int false_block_id_;
865 };
866
867
868 class LHasCachedArrayIndex: public LUnaryOperation<1> {
869 public:
870 explicit LHasCachedArrayIndex(LOperand* value) : LUnaryOperation<1>(value) {}
871
872 DECLARE_CONCRETE_INSTRUCTION(HasCachedArrayIndex, "has-cached-array-index")
873 DECLARE_HYDROGEN_ACCESSOR(HasCachedArrayIndex)
874 };
875
876
877 class LHasCachedArrayIndexAndBranch: public LHasCachedArrayIndex {
878 public:
879 LHasCachedArrayIndexAndBranch(LOperand* value,
880 int true_block_id,
881 int false_block_id)
882 : LHasCachedArrayIndex(value),
883 true_block_id_(true_block_id),
884 false_block_id_(false_block_id) { }
885
886 DECLARE_CONCRETE_INSTRUCTION(HasCachedArrayIndexAndBranch,
887 "has-cached-array-index-and-branch")
888 virtual void PrintDataTo(StringStream* stream);
889 virtual bool IsControl() const { return true; }
890
891 int true_block_id() const { return true_block_id_; }
892 int false_block_id() const { return false_block_id_; }
893
894 private:
895 int true_block_id_;
896 int false_block_id_;
897 };
898
899
900 class LClassOfTest: public LUnaryOperation<1> {
901 public:
902 LClassOfTest(LOperand* value, LOperand* temp)
903 : LUnaryOperation<1>(value), temporary_(temp) {}
904
905 DECLARE_CONCRETE_INSTRUCTION(ClassOfTest, "class-of-test")
906 DECLARE_HYDROGEN_ACCESSOR(ClassOfTest)
907
908 virtual void PrintDataTo(StringStream* stream);
909
910 LOperand* temporary() { return temporary_; }
911
912 private:
913 LOperand* temporary_;
914 };
915
916
917 class LClassOfTestAndBranch: public LClassOfTest {
918 public:
919 LClassOfTestAndBranch(LOperand* value,
920 LOperand* temporary,
921 LOperand* temporary2,
922 int true_block_id,
923 int false_block_id)
924 : LClassOfTest(value, temporary),
925 temporary2_(temporary2),
926 true_block_id_(true_block_id),
927 false_block_id_(false_block_id) { }
928
929 DECLARE_CONCRETE_INSTRUCTION(ClassOfTestAndBranch,
930 "class-of-test-and-branch")
931 virtual void PrintDataTo(StringStream* stream);
932 virtual bool IsControl() const { return true; }
933
934 int true_block_id() const { return true_block_id_; }
935 int false_block_id() const { return false_block_id_; }
936 LOperand* temporary2() { return temporary2_; }
937
938 private:
939 LOperand* temporary2_;
940 int true_block_id_;
941 int false_block_id_;
942 };
943
944
945 class LCmpT: public LBinaryOperation<1> {
946 public:
947 LCmpT(LOperand* left, LOperand* right) : LBinaryOperation<1>(left, right) {}
948
949 DECLARE_CONCRETE_INSTRUCTION(CmpT, "cmp-t")
950 DECLARE_HYDROGEN_ACCESSOR(Compare)
951
952 Token::Value op() const { return hydrogen()->token(); }
953 };
954
955
956 class LCmpTAndBranch: public LCmpT {
957 public:
958 LCmpTAndBranch(LOperand* left,
959 LOperand* right,
960 int true_block_id,
961 int false_block_id)
962 : LCmpT(left, right),
963 true_block_id_(true_block_id),
964 false_block_id_(false_block_id) { }
965
966 DECLARE_CONCRETE_INSTRUCTION(CmpTAndBranch, "cmp-t-and-branch")
967
968 int true_block_id() const { return true_block_id_; }
969 int false_block_id() const { return false_block_id_; }
970
971 private:
972 int true_block_id_;
973 int false_block_id_;
974 };
975
976
977 class LInstanceOf: public LBinaryOperation<1> {
978 public:
979 LInstanceOf(LOperand* left, LOperand* right)
980 : LBinaryOperation<1>(left, right) { }
981
982 DECLARE_CONCRETE_INSTRUCTION(InstanceOf, "instance-of")
983 };
984
985
986 class LInstanceOfAndBranch: public LInstanceOf {
987 public:
988 LInstanceOfAndBranch(LOperand* left,
989 LOperand* right,
990 int true_block_id,
991 int false_block_id)
992 : LInstanceOf(left, right),
993 true_block_id_(true_block_id),
994 false_block_id_(false_block_id) { }
995
996 DECLARE_CONCRETE_INSTRUCTION(InstanceOfAndBranch, "instance-of-and-branch")
997
998 int true_block_id() const { return true_block_id_; }
999 int false_block_id() const { return false_block_id_; }
1000
1001 private:
1002 int true_block_id_;
1003 int false_block_id_;
1004 };
1005
1006
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> {
1025 public:
1026 LBoundsCheck(LOperand* index, LOperand* length)
1027 : LBinaryOperation<0>(index, length) { }
1028
1029 LOperand* index() const { return left(); }
1030 LOperand* length() const { return right(); }
1031
1032 DECLARE_CONCRETE_INSTRUCTION(BoundsCheck, "bounds-check")
1033 };
1034
1035
1036 class LBitI: public LBinaryOperation<1> {
1037 public:
1038 LBitI(Token::Value op, LOperand* left, LOperand* right)
1039 : LBinaryOperation<1>(left, right), op_(op) { }
1040
1041 Token::Value op() const { return op_; }
1042
1043 DECLARE_CONCRETE_INSTRUCTION(BitI, "bit-i")
1044
1045 private:
1046 Token::Value op_;
1047 };
1048
1049
1050 class LShiftI: public LBinaryOperation<1> {
1051 public:
1052 LShiftI(Token::Value op, LOperand* left, LOperand* right, bool can_deopt)
1053 : LBinaryOperation<1>(left, right), op_(op), can_deopt_(can_deopt) { }
1054
1055 Token::Value op() const { return op_; }
1056
1057 bool can_deopt() const { return can_deopt_; }
1058
1059 DECLARE_CONCRETE_INSTRUCTION(ShiftI, "shift-i")
1060
1061 private:
1062 Token::Value op_;
1063 bool can_deopt_;
1064 };
1065
1066
1067 class LSubI: public LBinaryOperation<1> {
1068 public:
1069 LSubI(LOperand* left, LOperand* right)
1070 : LBinaryOperation<1>(left, right) { }
1071
1072 DECLARE_CONCRETE_INSTRUCTION(SubI, "sub-i")
1073 DECLARE_HYDROGEN_ACCESSOR(Sub)
1074 };
1075
1076
1077 class LConstant: public LTemplateInstruction<1, 0, 0> {
1078 DECLARE_INSTRUCTION(Constant)
1079 };
1080
1081
1082 class LConstantI: public LConstant {
1083 public:
1084 explicit LConstantI(int32_t value) : value_(value) { }
1085 int32_t value() const { return value_; }
1086
1087 DECLARE_CONCRETE_INSTRUCTION(ConstantI, "constant-i")
1088
1089 private:
1090 int32_t value_;
1091 };
1092
1093
1094 class LConstantD: public LConstant {
1095 public:
1096 explicit LConstantD(double value) : value_(value) { }
1097 double value() const { return value_; }
1098
1099 DECLARE_CONCRETE_INSTRUCTION(ConstantD, "constant-d")
1100
1101 private:
1102 double value_;
1103 };
1104
1105
1106 class LConstantT: public LConstant {
1107 public:
1108 explicit LConstantT(Handle<Object> value) : value_(value) { }
1109 Handle<Object> value() const { return value_; }
1110
1111 DECLARE_CONCRETE_INSTRUCTION(ConstantT, "constant-t")
1112
1113 private:
1114 Handle<Object> value_;
1115 };
1116
1117
1118 class LBranch: public LUnaryOperation<0> {
1119 public:
1120 LBranch(LOperand* input, int true_block_id, int false_block_id)
1121 : LUnaryOperation<0>(input),
1122 true_block_id_(true_block_id),
1123 false_block_id_(false_block_id) { }
1124
1125 DECLARE_CONCRETE_INSTRUCTION(Branch, "branch")
1126 DECLARE_HYDROGEN_ACCESSOR(Value)
1127
1128 virtual void PrintDataTo(StringStream* stream);
1129 virtual bool IsControl() const { return true; }
1130
1131 int true_block_id() const { return true_block_id_; }
1132 int false_block_id() const { return false_block_id_; }
1133
1134 private:
1135 int true_block_id_;
1136 int false_block_id_;
1137 };
1138
1139
1140 class LCmpMapAndBranch: public LUnaryOperation<0> {
1141 public:
1142 explicit LCmpMapAndBranch(LOperand* value) : LUnaryOperation<0>(value) { }
1143
1144 DECLARE_CONCRETE_INSTRUCTION(CmpMapAndBranch, "cmp-map-and-branch")
1145 DECLARE_HYDROGEN_ACCESSOR(CompareMapAndBranch)
1146
1147 virtual bool IsControl() const { return true; }
1148
1149 Handle<Map> map() const { return hydrogen()->map(); }
1150 int true_block_id() const {
1151 return hydrogen()->true_destination()->block_id();
1152 }
1153 int false_block_id() const {
1154 return hydrogen()->false_destination()->block_id();
1155 }
1156 };
1157
1158
1159 class LJSArrayLength: public LUnaryOperation<1> {
1160 public:
1161 explicit LJSArrayLength(LOperand* input) : LUnaryOperation<1>(input) { }
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) { }
1181
1182 LOperand* temporary() const { return temporary_; }
1183
1184 DECLARE_CONCRETE_INSTRUCTION(ValueOf, "value-of")
1185 DECLARE_HYDROGEN_ACCESSOR(ValueOf)
1186
1187 private:
1188 LOperand* temporary_;
1189 };
1190
1191
1192 class LThrow: public LUnaryOperation<1> {
1193 public:
1194 explicit LThrow(LOperand* value) : LUnaryOperation<1>(value) { }
1195
1196 DECLARE_CONCRETE_INSTRUCTION(Throw, "throw")
1197 };
1198
1199
1200 class LBitNotI: public LUnaryOperation<1> {
1201 public:
1202 explicit LBitNotI(LOperand* input) : LUnaryOperation<1>(input) { }
1203
1204 DECLARE_CONCRETE_INSTRUCTION(BitNotI, "bit-not-i")
1205 };
1206
1207
1208 class LAddI: public LBinaryOperation<1> {
1209 public:
1210 LAddI(LOperand* left, LOperand* right)
1211 : LBinaryOperation<1>(left, right) { }
1212
1213 DECLARE_CONCRETE_INSTRUCTION(AddI, "add-i")
1214 DECLARE_HYDROGEN_ACCESSOR(Add)
1215 };
1216
1217
1218 class LPower: public LBinaryOperation<1> {
1219 public:
1220 LPower(LOperand* left, LOperand* right)
1221 : LBinaryOperation<1>(left, right) { }
1222
1223 DECLARE_CONCRETE_INSTRUCTION(Power, "power")
1224 DECLARE_HYDROGEN_ACCESSOR(Power)
1225 };
1226
1227
1228 class LArithmeticD: public LBinaryOperation<1> {
1229 public:
1230 LArithmeticD(Token::Value op, LOperand* left, LOperand* right)
1231 : LBinaryOperation<1>(left, right), op_(op) { }
1232
1233 Token::Value op() const { return op_; }
1234
1235 virtual void CompileToNative(LCodeGen* generator);
1236 virtual const char* Mnemonic() const;
1237
1238 private:
1239 Token::Value op_;
1240 };
1241
1242
1243 class LArithmeticT: public LBinaryOperation<1> {
1244 public:
1245 LArithmeticT(Token::Value op, LOperand* left, LOperand* right)
1246 : LBinaryOperation<1>(left, right), op_(op) { }
1247
1248 virtual void CompileToNative(LCodeGen* generator);
1249 virtual const char* Mnemonic() const;
1250
1251 Token::Value op() const { return op_; }
1252
1253 private:
1254 Token::Value op_;
1255 };
1256
1257
1258 class LReturn: public LUnaryOperation<0> {
1259 public:
1260 explicit LReturn(LOperand* use) : LUnaryOperation<0>(use) { }
1261
1262 DECLARE_CONCRETE_INSTRUCTION(Return, "return")
1263 };
1264
1265
1266 class LLoadNamedField: public LUnaryOperation<1> {
1267 public:
1268 explicit LLoadNamedField(LOperand* object) : LUnaryOperation<1>(object) { }
1269
1270 DECLARE_CONCRETE_INSTRUCTION(LoadNamedField, "load-named-field")
1271 DECLARE_HYDROGEN_ACCESSOR(LoadNamedField)
1272 };
1273
1274
1275 class LLoadNamedGeneric: public LUnaryOperation<1> {
1276 public:
1277 explicit LLoadNamedGeneric(LOperand* object) : LUnaryOperation<1>(object) { }
1278
1279 DECLARE_CONCRETE_INSTRUCTION(LoadNamedGeneric, "load-named-generic")
1280 DECLARE_HYDROGEN_ACCESSOR(LoadNamedGeneric)
1281
1282 LOperand* object() const { return input(); }
1283 Handle<Object> name() const { return hydrogen()->name(); }
1284 };
1285
1286
1287 class LLoadFunctionPrototype: public LUnaryOperation<1> {
1288 public:
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) { }
1306
1307 DECLARE_CONCRETE_INSTRUCTION(LoadElements, "load-elements")
1308 };
1309
1310
1311 class LLoadKeyedFastElement: public LBinaryOperation<1> {
1312 public:
1313 LLoadKeyedFastElement(LOperand* elements, LOperand* key)
1314 : LBinaryOperation<1>(elements, key) { }
1315
1316 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedFastElement, "load-keyed-fast-element")
1317 DECLARE_HYDROGEN_ACCESSOR(LoadKeyedFastElement)
1318
1319 LOperand* elements() const { return left(); }
1320 LOperand* key() const { return right(); }
1321 };
1322
1323
1324 class LLoadKeyedGeneric: public LBinaryOperation<1> {
1325 public:
1326 LLoadKeyedGeneric(LOperand* obj, LOperand* key)
1327 : LBinaryOperation<1>(obj, key) { }
1328
1329 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedGeneric, "load-keyed-generic")
1330
1331 LOperand* object() const { return left(); }
1332 LOperand* key() const { return right(); }
1333 };
1334
1335
1336 class LLoadGlobal: public LTemplateInstruction<1, 0, 0> {
1337 public:
1338 DECLARE_CONCRETE_INSTRUCTION(LoadGlobal, "load-global")
1339 DECLARE_HYDROGEN_ACCESSOR(LoadGlobal)
1340 };
1341
1342
1343 class LStoreGlobal: public LUnaryOperation<0> {
1344 public:
1345 explicit LStoreGlobal(LOperand* value) : LUnaryOperation<0>(value) {}
1346
1347 DECLARE_CONCRETE_INSTRUCTION(StoreGlobal, "store-global")
1348 DECLARE_HYDROGEN_ACCESSOR(StoreGlobal)
1349 };
1350
1351
1352 class LPushArgument: public LUnaryOperation<0> {
1353 public:
1354 explicit LPushArgument(LOperand* argument) : LUnaryOperation<0>(argument) {}
1355
1356 DECLARE_CONCRETE_INSTRUCTION(PushArgument, "push-argument")
1357 };
1358
1359
1360 class LGlobalObject: public LTemplateInstruction<1, 0, 0> {
1361 public:
1362 DECLARE_CONCRETE_INSTRUCTION(GlobalObject, "global-object")
1363 };
1364
1365
1366 class LGlobalReceiver: public LTemplateInstruction<1, 0, 0> {
1367 public:
1368 DECLARE_CONCRETE_INSTRUCTION(GlobalReceiver, "global-receiver")
1369 };
1370
1371
1372 class LCallConstantFunction: public LTemplateInstruction<1, 0, 0> {
1373 public:
1374 DECLARE_CONCRETE_INSTRUCTION(CallConstantFunction, "call-constant-function")
1375 DECLARE_HYDROGEN_ACCESSOR(CallConstantFunction)
1376
1377 virtual void PrintDataTo(StringStream* stream);
1378
1379 Handle<JSFunction> function() { return hydrogen()->function(); }
1380 int arity() const { return hydrogen()->argument_count() - 1; }
1381 };
1382
1383
1384 class LCallKeyed: public LTemplateInstruction<1, 0, 0> {
1385 public:
1386 DECLARE_CONCRETE_INSTRUCTION(CallKeyed, "call-keyed")
1387 DECLARE_HYDROGEN_ACCESSOR(CallKeyed)
1388
1389 virtual void PrintDataTo(StringStream* stream);
1390
1391 int arity() const { return hydrogen()->argument_count() - 1; }
1392 };
1393
1394
1395 class LCallNamed: public LTemplateInstruction<1, 0, 0> {
1396 public:
1397 DECLARE_CONCRETE_INSTRUCTION(CallNamed, "call-named")
1398 DECLARE_HYDROGEN_ACCESSOR(CallNamed)
1399
1400 virtual void PrintDataTo(StringStream* stream);
1401
1402 Handle<String> name() const { return hydrogen()->name(); }
1403 int arity() const { return hydrogen()->argument_count() - 1; }
1404 };
1405
1406
1407 class LCallFunction: public LTemplateInstruction<1, 0, 0> {
1408 public:
1409 DECLARE_CONCRETE_INSTRUCTION(CallFunction, "call-function")
1410 DECLARE_HYDROGEN_ACCESSOR(CallFunction)
1411
1412 int arity() const { return hydrogen()->argument_count() - 2; }
1413 };
1414
1415
1416 class LCallGlobal: public LTemplateInstruction<1, 0, 0> {
1417 public:
1418 DECLARE_CONCRETE_INSTRUCTION(CallGlobal, "call-global")
1419 DECLARE_HYDROGEN_ACCESSOR(CallGlobal)
1420
1421 virtual void PrintDataTo(StringStream* stream);
1422
1423 Handle<String> name() const {return hydrogen()->name(); }
1424 int arity() const { return hydrogen()->argument_count() - 1; }
1425 };
1426
1427
1428 class LCallKnownGlobal: public LTemplateInstruction<1, 0, 0> {
1429 public:
1430 DECLARE_CONCRETE_INSTRUCTION(CallKnownGlobal, "call-known-global")
1431 DECLARE_HYDROGEN_ACCESSOR(CallKnownGlobal)
1432
1433 virtual void PrintDataTo(StringStream* stream);
1434
1435 Handle<JSFunction> target() const { return hydrogen()->target(); }
1436 int arity() const { return hydrogen()->argument_count() - 1; }
1437 };
1438
1439
1440 class LCallNew: public LUnaryOperation<1> {
1441 public:
1442 explicit LCallNew(LOperand* constructor) : LUnaryOperation<1>(constructor) { }
1443
1444 DECLARE_CONCRETE_INSTRUCTION(CallNew, "call-new")
1445 DECLARE_HYDROGEN_ACCESSOR(CallNew)
1446
1447 virtual void PrintDataTo(StringStream* stream);
1448
1449 int arity() const { return hydrogen()->argument_count() - 1; }
1450 };
1451
1452
1453 class LCallRuntime: public LTemplateInstruction<1, 0, 0> {
1454 public:
1455 DECLARE_CONCRETE_INSTRUCTION(CallRuntime, "call-runtime")
1456 DECLARE_HYDROGEN_ACCESSOR(CallRuntime)
1457
1458 Runtime::Function* function() const { return hydrogen()->function(); }
1459 int arity() const { return hydrogen()->argument_count(); }
1460 };
1461
1462
1463 class LInteger32ToDouble: public LUnaryOperation<1> {
1464 public:
1465 explicit LInteger32ToDouble(LOperand* use) : LUnaryOperation<1>(use) { }
1466
1467 DECLARE_CONCRETE_INSTRUCTION(Integer32ToDouble, "int32-to-double")
1468 };
1469
1470
1471 class LNumberTagI: public LUnaryOperation<1> {
1472 public:
1473 explicit LNumberTagI(LOperand* use) : LUnaryOperation<1>(use) { }
1474
1475 DECLARE_CONCRETE_INSTRUCTION(NumberTagI, "number-tag-i")
1476 };
1477
1478
1479 class LNumberTagD: public LUnaryOperation<1> {
1480 public:
1481 explicit LNumberTagD(LOperand* value, LOperand* temp)
1482 : LUnaryOperation<1>(value), temp_(temp) { }
1483
1484 DECLARE_CONCRETE_INSTRUCTION(NumberTagD, "number-tag-d")
1485
1486 LOperand* temp() const { return temp_; }
1487
1488 private:
1489 LOperand* temp_;
1490 };
1491
1492
1493 // Sometimes truncating conversion from a tagged value to an int32.
1494 class LDoubleToI: public LUnaryOperation<1> {
1495 public:
1496 LDoubleToI(LOperand* value, LOperand* temporary)
1497 : LUnaryOperation<1>(value), temporary_(temporary) { }
1498
1499 DECLARE_CONCRETE_INSTRUCTION(DoubleToI, "double-to-i")
1500 DECLARE_HYDROGEN_ACCESSOR(Change)
1501
1502 bool truncating() { return hydrogen()->CanTruncateToInt32(); }
1503 LOperand* temporary() const { return temporary_; }
1504
1505 private:
1506 LOperand* temporary_;
1507 };
1508
1509
1510 // Truncating conversion from a tagged value to an int32.
1511 class LTaggedToI: public LUnaryOperation<1> {
1512 public:
1513 LTaggedToI(LOperand* value, LOperand* temp)
1514 : LUnaryOperation<1>(value), temp_(temp) { }
1515
1516 DECLARE_CONCRETE_INSTRUCTION(TaggedToI, "tagged-to-i")
1517 DECLARE_HYDROGEN_ACCESSOR(Change)
1518
1519 bool truncating() { return hydrogen()->CanTruncateToInt32(); }
1520 LOperand* temp() const { return temp_; }
1521
1522 private:
1523 LOperand* temp_;
1524 };
1525
1526
1527 class LSmiTag: public LUnaryOperation<1> {
1528 public:
1529 explicit LSmiTag(LOperand* use) : LUnaryOperation<1>(use) { }
1530
1531 DECLARE_CONCRETE_INSTRUCTION(SmiTag, "smi-tag")
1532 };
1533
1534
1535 class LNumberUntagD: public LUnaryOperation<1> {
1536 public:
1537 explicit LNumberUntagD(LOperand* value) : LUnaryOperation<1>(value) { }
1538
1539 DECLARE_CONCRETE_INSTRUCTION(NumberUntagD, "double-untag")
1540 };
1541
1542
1543 class LSmiUntag: public LUnaryOperation<1> {
1544 public:
1545 LSmiUntag(LOperand* use, bool needs_check)
1546 : LUnaryOperation<1>(use), needs_check_(needs_check) { }
1547
1548 DECLARE_CONCRETE_INSTRUCTION(SmiUntag, "smi-untag")
1549
1550 bool needs_check() const { return needs_check_; }
1551
1552 private:
1553 bool needs_check_;
1554 };
1555
1556
1557 class LStoreNamed: public LTemplateInstruction<0, 2, 0> {
1558 public:
1559 LStoreNamed(LOperand* obj, LOperand* val) {
1560 this->SetInputAt(0, obj);
1561 this->SetInputAt(1, val);
1562 }
1563
1564 DECLARE_INSTRUCTION(StoreNamed)
1565 DECLARE_HYDROGEN_ACCESSOR(StoreNamed)
1566
1567 virtual void PrintDataTo(StringStream* stream);
1568
1569 LOperand* object() const { return this->InputAt(0); }
1570 LOperand* value() const { return this->InputAt(1); }
1571 Handle<Object> name() const { return hydrogen()->name(); }
1572 };
1573
1574
1575 class LStoreNamedField: public LStoreNamed {
1576 public:
1577 LStoreNamedField(LOperand* obj, LOperand* val, LOperand* temp)
1578 : LStoreNamed(obj, val), temp_(temp) { }
1579
1580 DECLARE_CONCRETE_INSTRUCTION(StoreNamedField, "store-named-field")
1581 DECLARE_HYDROGEN_ACCESSOR(StoreNamedField)
1582
1583 bool is_in_object() { return hydrogen()->is_in_object(); }
1584 int offset() { return hydrogen()->offset(); }
1585 bool needs_write_barrier() { return hydrogen()->NeedsWriteBarrier(); }
1586 Handle<Map> transition() const { return hydrogen()->transition(); }
1587
1588 LOperand* temp() { return temp_; }
1589
1590 private:
1591 LOperand* temp_;
1592 };
1593
1594
1595 class LStoreNamedGeneric: public LStoreNamed {
1596 public:
1597 LStoreNamedGeneric(LOperand* obj, LOperand* val)
1598 : LStoreNamed(obj, val) { }
1599
1600 DECLARE_CONCRETE_INSTRUCTION(StoreNamedGeneric, "store-named-generic")
1601 DECLARE_HYDROGEN_ACCESSOR(StoreNamedGeneric)
1602 };
1603
1604
1605 class LStoreKeyed: public LTemplateInstruction<0, 3, 0> {
1606 public:
1607 LStoreKeyed(LOperand* obj, LOperand* key, LOperand* val) {
1608 this->SetInputAt(0, obj);
1609 this->SetInputAt(1, key);
1610 this->SetInputAt(2, val);
1611 }
1612
1613 DECLARE_INSTRUCTION(StoreKeyed)
1614
1615 virtual void PrintDataTo(StringStream* stream);
1616
1617 LOperand* object() const { return this->InputAt(0); }
1618 LOperand* key() const { return this->InputAt(1); }
1619 LOperand* value() const { return this->InputAt(2); }
1620 };
1621
1622
1623 class LStoreKeyedFastElement: public LStoreKeyed {
1624 public:
1625 LStoreKeyedFastElement(LOperand* obj, LOperand* key, LOperand* val)
1626 : LStoreKeyed(obj, key, val) {}
1627
1628 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedFastElement,
1629 "store-keyed-fast-element")
1630 DECLARE_HYDROGEN_ACCESSOR(StoreKeyedFastElement)
1631 };
1632
1633
1634 class LStoreKeyedGeneric: public LStoreKeyed {
1635 public:
1636 LStoreKeyedGeneric(LOperand* obj, LOperand* key, LOperand* val)
1637 : LStoreKeyed(obj, key, val) { }
1638
1639 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedGeneric, "store-keyed-generic")
1640 };
1641
1642
1643 class LCheckFunction: public LUnaryOperation<0> {
1644 public:
1645 explicit LCheckFunction(LOperand* use) : LUnaryOperation<0>(use) { }
1646
1647 DECLARE_CONCRETE_INSTRUCTION(CheckFunction, "check-function")
1648 DECLARE_HYDROGEN_ACCESSOR(CheckFunction)
1649 };
1650
1651
1652 class LCheckInstanceType: public LUnaryOperation<0> {
1653 public:
1654 LCheckInstanceType(LOperand* use, LOperand* temp)
1655 : LUnaryOperation<0>(use), temp_(temp) { }
1656
1657 DECLARE_CONCRETE_INSTRUCTION(CheckInstanceType, "check-instance-type")
1658 DECLARE_HYDROGEN_ACCESSOR(CheckInstanceType)
1659
1660 LOperand* temp() const { return temp_; }
1661
1662 private:
1663 LOperand* temp_;
1664 };
1665
1666
1667 class LCheckMap: public LUnaryOperation<0> {
1668 public:
1669 explicit LCheckMap(LOperand* use) : LUnaryOperation<0>(use) { }
1670
1671 DECLARE_CONCRETE_INSTRUCTION(CheckMap, "check-map")
1672 DECLARE_HYDROGEN_ACCESSOR(CheckMap)
1673 };
1674
1675
1676 class LCheckPrototypeMaps: public LTemplateInstruction<0, 0, 0> {
1677 public:
1678 explicit LCheckPrototypeMaps(LOperand* temp) : temp_(temp) { }
1679
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(); }
1685
1686 LOperand* temp() const { return temp_; }
1687
1688 private:
1689 LOperand* temp_;
1690 };
1691
1692
1693 class LCheckSmi: public LUnaryOperation<0> {
1694 public:
1695 LCheckSmi(LOperand* use, Condition condition)
1696 : LUnaryOperation<0>(use), condition_(condition) { }
1697
1698 Condition condition() const { return condition_; }
1699
1700 virtual void CompileToNative(LCodeGen* generator);
1701 virtual const char* Mnemonic() const {
1702 return (condition_ == zero) ? "check-non-smi" : "check-smi";
1703 }
1704
1705 private:
1706 Condition condition_;
1707 };
1708
1709
1710 class LMaterializedLiteral: public LTemplateInstruction<1, 0, 0> {
1711 public:
1712 DECLARE_INSTRUCTION(MaterializedLiteral)
1713 };
1714
1715
1716 class LArrayLiteral: public LMaterializedLiteral {
1717 public:
1718 DECLARE_CONCRETE_INSTRUCTION(ArrayLiteral, "array-literal")
1719 DECLARE_HYDROGEN_ACCESSOR(ArrayLiteral)
1720 };
1721
1722
1723 class LObjectLiteral: public LMaterializedLiteral {
1724 public:
1725 DECLARE_CONCRETE_INSTRUCTION(ObjectLiteral, "object-literal")
1726 DECLARE_HYDROGEN_ACCESSOR(ObjectLiteral)
1727 };
1728
1729
1730 class LRegExpLiteral: public LMaterializedLiteral {
1731 public:
1732 DECLARE_CONCRETE_INSTRUCTION(RegExpLiteral, "regexp-literal")
1733 DECLARE_HYDROGEN_ACCESSOR(RegExpLiteral)
1734 };
1735
1736
1737 class LFunctionLiteral: public LTemplateInstruction<1, 0, 0> {
1738 public:
1739 DECLARE_CONCRETE_INSTRUCTION(FunctionLiteral, "function-literal")
1740 DECLARE_HYDROGEN_ACCESSOR(FunctionLiteral)
1741
1742 Handle<SharedFunctionInfo> shared_info() { return hydrogen()->shared_info(); }
1743 };
1744
1745
1746 class LTypeof: public LUnaryOperation<1> {
1747 public:
1748 explicit LTypeof(LOperand* input) : LUnaryOperation<1>(input) { }
1749
1750 DECLARE_CONCRETE_INSTRUCTION(Typeof, "typeof")
1751 };
1752
1753
1754 class LTypeofIs: public LUnaryOperation<1> {
1755 public:
1756 explicit LTypeofIs(LOperand* input) : LUnaryOperation<1>(input) { }
1757 virtual void PrintDataTo(StringStream* stream);
1758
1759 DECLARE_CONCRETE_INSTRUCTION(TypeofIs, "typeof-is")
1760 DECLARE_HYDROGEN_ACCESSOR(TypeofIs)
1761
1762 Handle<String> type_literal() { return hydrogen()->type_literal(); }
1763 };
1764
1765
1766 class LTypeofIsAndBranch: public LTypeofIs {
1767 public:
1768 LTypeofIsAndBranch(LOperand* value,
1769 int true_block_id,
1770 int false_block_id)
1771 : LTypeofIs(value),
1772 true_block_id_(true_block_id),
1773 false_block_id_(false_block_id) { }
1774
1775 DECLARE_CONCRETE_INSTRUCTION(TypeofIsAndBranch, "typeof-is-and-branch")
1776
1777 virtual void PrintDataTo(StringStream* stream);
1778 virtual bool IsControl() const { return true; }
1779
1780 int true_block_id() const { return true_block_id_; }
1781 int false_block_id() const { return false_block_id_; }
1782
1783 private:
1784 int true_block_id_;
1785 int false_block_id_;
1786 };
1787
1788
1789 class LDeleteProperty: public LBinaryOperation<1> {
1790 public:
1791 LDeleteProperty(LOperand* obj, LOperand* key)
1792 : LBinaryOperation<1>(obj, key) { }
1793
1794 DECLARE_CONCRETE_INSTRUCTION(DeleteProperty, "delete-property")
1795
1796 LOperand* object() const { return left(); }
1797 LOperand* key() const { return right(); }
1798 };
1799
1800
1801 class LOsrEntry: public LTemplateInstruction<0, 0, 0> {
262 public: 1802 public:
263 LOsrEntry(); 1803 LOsrEntry();
264 1804
265 DECLARE_CONCRETE_INSTRUCTION(OsrEntry, "osr-entry") 1805 DECLARE_CONCRETE_INSTRUCTION(OsrEntry, "osr-entry")
266 1806
267 LOperand** SpilledRegisterArray() { return register_spills_; } 1807 LOperand** SpilledRegisterArray() { return register_spills_; }
268 LOperand** SpilledDoubleRegisterArray() { return double_register_spills_; } 1808 LOperand** SpilledDoubleRegisterArray() { return double_register_spills_; }
269 1809
270 void MarkSpilledRegister(int allocation_index, LOperand* spill_operand); 1810 void MarkSpilledRegister(int allocation_index, LOperand* spill_operand);
271 void MarkSpilledDoubleRegister(int allocation_index, 1811 void MarkSpilledDoubleRegister(int allocation_index,
272 LOperand* spill_operand); 1812 LOperand* spill_operand);
273 1813
274 private: 1814 private:
275 // Arrays of spill slot operands for registers with an assigned spill 1815 // 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. 1816 // 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 1817 // NULL if the register has no assigned spill slot. Indexed by allocation
278 // index. 1818 // index.
279 LOperand* register_spills_[Register::kNumAllocatableRegisters]; 1819 LOperand* register_spills_[Register::kNumAllocatableRegisters];
280 LOperand* double_register_spills_[DoubleRegister::kNumAllocatableRegisters]; 1820 LOperand* double_register_spills_[DoubleRegister::kNumAllocatableRegisters];
281 }; 1821 };
282 1822
283 1823
1824 class LStackCheck: public LTemplateInstruction<0, 0, 0> {
1825 public:
1826 DECLARE_CONCRETE_INSTRUCTION(StackCheck, "stack-check")
1827 };
1828
1829
284 class LChunkBuilder; 1830 class LChunkBuilder;
285 class LChunk: public ZoneObject { 1831 class LChunk: public ZoneObject {
286 public: 1832 public:
287 explicit LChunk(HGraph* graph) 1833 explicit LChunk(HGraph* graph)
288 : spill_slot_count_(0), 1834 : spill_slot_count_(0),
289 graph_(graph), 1835 graph_(graph),
290 instructions_(32), 1836 instructions_(32),
291 pointer_maps_(8), 1837 pointer_maps_(8),
292 inlined_closures_(1) { } 1838 inlined_closures_(1) { }
293 1839
1840 int AddInstruction(LInstruction* instruction, HBasicBlock* block);
1841 LConstantOperand* DefineConstantOperand(HConstant* constant);
1842 Handle<Object> LookupLiteral(LConstantOperand* operand) const;
1843 Representation LookupLiteralRepresentation(LConstantOperand* operand) const;
1844
1845 int GetNextSpillIndex(bool is_double);
1846 LOperand* GetNextSpillSlot(bool is_double);
1847
1848 int ParameterAt(int index);
1849 int GetParameterStackSlot(int index) const;
294 int spill_slot_count() const { return spill_slot_count_; } 1850 int spill_slot_count() const { return spill_slot_count_; }
295 HGraph* graph() const { return graph_; } 1851 HGraph* graph() const { return graph_; }
296 const ZoneList<LInstruction*>* instructions() const { return &instructions_; } 1852 const ZoneList<LInstruction*>* instructions() const { return &instructions_; }
1853 void AddGapMove(int index, LOperand* from, LOperand* to);
1854 LGap* GetGapAt(int index) const;
1855 bool IsGapAt(int index) const;
1856 int NearestGapPos(int index) const;
1857 void MarkEmptyBlocks();
297 const ZoneList<LPointerMap*>* pointer_maps() const { return &pointer_maps_; } 1858 const ZoneList<LPointerMap*>* pointer_maps() const { return &pointer_maps_; }
1859 LLabel* GetLabel(int block_id) const {
1860 HBasicBlock* block = graph_->blocks()->at(block_id);
1861 int first_instruction = block->first_instruction_index();
1862 return LLabel::cast(instructions_[first_instruction]);
1863 }
1864 int LookupDestination(int block_id) const {
1865 LLabel* cur = GetLabel(block_id);
1866 while (cur->replacement() != NULL) {
1867 cur = cur->replacement();
1868 }
1869 return cur->block_id();
1870 }
1871 Label* GetAssemblyLabel(int block_id) const {
1872 LLabel* label = GetLabel(block_id);
1873 ASSERT(!label->HasReplacement());
1874 return label->label();
1875 }
1876
298 const ZoneList<Handle<JSFunction> >* inlined_closures() const { 1877 const ZoneList<Handle<JSFunction> >* inlined_closures() const {
299 return &inlined_closures_; 1878 return &inlined_closures_;
300 } 1879 }
301 1880
302 LOperand* GetNextSpillSlot(bool double_slot) { 1881 void AddInlinedClosure(Handle<JSFunction> closure) {
303 UNIMPLEMENTED(); 1882 inlined_closures_.Add(closure);
304 return NULL;
305 } 1883 }
306 1884
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: 1885 private:
346 int spill_slot_count_; 1886 int spill_slot_count_;
347 HGraph* const graph_; 1887 HGraph* const graph_;
348 ZoneList<LInstruction*> instructions_; 1888 ZoneList<LInstruction*> instructions_;
349 ZoneList<LPointerMap*> pointer_maps_; 1889 ZoneList<LPointerMap*> pointer_maps_;
350 ZoneList<Handle<JSFunction> > inlined_closures_; 1890 ZoneList<Handle<JSFunction> > inlined_closures_;
351 }; 1891 };
352 1892
353 1893
354 class LChunkBuilder BASE_EMBEDDED { 1894 class LChunkBuilder BASE_EMBEDDED {
355 public: 1895 public:
356 LChunkBuilder(HGraph* graph, LAllocator* allocator) 1896 LChunkBuilder(HGraph* graph, LAllocator* allocator)
357 : chunk_(NULL), 1897 : chunk_(NULL),
358 graph_(graph), 1898 graph_(graph),
359 status_(UNUSED), 1899 status_(UNUSED),
360 current_instruction_(NULL), 1900 current_instruction_(NULL),
361 current_block_(NULL), 1901 current_block_(NULL),
362 next_block_(NULL), 1902 next_block_(NULL),
363 argument_count_(0), 1903 argument_count_(0),
364 allocator_(allocator), 1904 allocator_(allocator),
365 position_(RelocInfo::kNoPosition), 1905 position_(RelocInfo::kNoPosition),
366 instructions_pending_deoptimization_environment_(NULL), 1906 instructions_pending_deoptimization_environment_(NULL),
367 pending_deoptimization_ast_id_(AstNode::kNoNumber) { } 1907 pending_deoptimization_ast_id_(AstNode::kNoNumber) { }
368 1908
369 // Build the sequence for the graph. 1909 // Build the sequence for the graph.
370 LChunk* Build(); 1910 LChunk* Build();
371 1911
372 // Declare methods that deal with the individual node types. 1912 // Declare methods that deal with the individual node types.
373 #define DECLARE_DO(type) LInstruction* Do##type(H##type* node) { \ 1913 #define DECLARE_DO(type) LInstruction* Do##type(H##type* node);
374 UNIMPLEMENTED(); \
375 return NULL; \
376 }
377 HYDROGEN_CONCRETE_INSTRUCTION_LIST(DECLARE_DO) 1914 HYDROGEN_CONCRETE_INSTRUCTION_LIST(DECLARE_DO)
378 #undef DECLARE_DO 1915 #undef DECLARE_DO
379 1916
380 private: 1917 private:
381 enum Status { 1918 enum Status {
382 UNUSED, 1919 UNUSED,
383 BUILDING, 1920 BUILDING,
384 DONE, 1921 DONE,
385 ABORTED 1922 ABORTED
386 }; 1923 };
387 1924
388 LChunk* chunk() const { return chunk_; } 1925 LChunk* chunk() const { return chunk_; }
389 HGraph* graph() const { return graph_; } 1926 HGraph* graph() const { return graph_; }
390 1927
391 bool is_unused() const { return status_ == UNUSED; } 1928 bool is_unused() const { return status_ == UNUSED; }
392 bool is_building() const { return status_ == BUILDING; } 1929 bool is_building() const { return status_ == BUILDING; }
393 bool is_done() const { return status_ == DONE; } 1930 bool is_done() const { return status_ == DONE; }
394 bool is_aborted() const { return status_ == ABORTED; } 1931 bool is_aborted() const { return status_ == ABORTED; }
395 1932
396 void Abort(const char* format, ...); 1933 void Abort(const char* format, ...);
397 1934
1935 // Methods for getting operands for Use / Define / Temp.
1936 LRegister* ToOperand(Register reg);
1937 LUnallocated* ToUnallocated(Register reg);
1938 LUnallocated* ToUnallocated(XMMRegister reg);
1939
1940 // Methods for setting up define-use relationships.
1941 LOperand* Use(HValue* value, LUnallocated* operand);
1942 LOperand* UseFixed(HValue* value, Register fixed_register);
1943 LOperand* UseFixedDouble(HValue* value, XMMRegister fixed_register);
1944
1945 // A value that is guaranteed to be allocated to a register.
1946 // Operand created by UseRegister is guaranteed to be live until the end of
1947 // instruction. This means that register allocator will not reuse it's
1948 // register for any other operand inside instruction.
1949 // Operand created by UseRegisterAtStart is guaranteed to be live only at
1950 // instruction start. Register allocator is free to assign the same register
1951 // to some other operand used inside instruction (i.e. temporary or
1952 // output).
1953 LOperand* UseRegister(HValue* value);
1954 LOperand* UseRegisterAtStart(HValue* value);
1955
1956 // A value in a register that may be trashed.
1957 LOperand* UseTempRegister(HValue* value);
1958 LOperand* Use(HValue* value);
1959 LOperand* UseAtStart(HValue* value);
1960 LOperand* UseOrConstant(HValue* value);
1961 LOperand* UseOrConstantAtStart(HValue* value);
1962 LOperand* UseRegisterOrConstant(HValue* value);
1963 LOperand* UseRegisterOrConstantAtStart(HValue* value);
1964
1965 // Methods for setting up define-use relationships.
1966 // Return the same instruction that they are passed.
1967 template<int I, int T>
1968 LInstruction* Define(LTemplateInstruction<1, I, T>* instr,
1969 LUnallocated* result);
1970 template<int I, int T>
1971 LInstruction* Define(LTemplateInstruction<1, I, T>* instr);
1972 template<int I, int T>
1973 LInstruction* DefineAsRegister(LTemplateInstruction<1, I, T>* instr);
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);
1985 LInstruction* AssignEnvironment(LInstruction* instr);
1986 LInstruction* AssignPointerMap(LInstruction* instr);
1987
1988 enum CanDeoptimize { CAN_DEOPTIMIZE_EAGERLY, CANNOT_DEOPTIMIZE_EAGERLY };
1989
1990 // By default we assume that instruction sequences generated for calls
1991 // cannot deoptimize eagerly and we do not attach environment to this
1992 // instruction.
1993 LInstruction* MarkAsCall(
1994 LInstruction* instr,
1995 HInstruction* hinstr,
1996 CanDeoptimize can_deoptimize = CANNOT_DEOPTIMIZE_EAGERLY);
1997 LInstruction* MarkAsSaveDoubles(LInstruction* instr);
1998
1999 LInstruction* SetInstructionPendingDeoptimizationEnvironment(
2000 LInstruction* instr, int ast_id);
2001 void ClearInstructionPendingDeoptimizationEnvironment();
2002
2003 LEnvironment* CreateEnvironment(HEnvironment* hydrogen_env);
2004
2005 // Temporary operand that must be in a register.
2006 LUnallocated* TempRegister();
2007 LOperand* FixedTemp(Register reg);
2008 LOperand* FixedTemp(XMMRegister reg);
2009
2010 void VisitInstruction(HInstruction* current);
2011
398 void DoBasicBlock(HBasicBlock* block, HBasicBlock* next_block); 2012 void DoBasicBlock(HBasicBlock* block, HBasicBlock* next_block);
2013 LInstruction* DoBit(Token::Value op, HBitwiseBinaryOperation* instr);
2014 LInstruction* DoShift(Token::Value op, HBitwiseBinaryOperation* instr);
2015 LInstruction* DoArithmeticD(Token::Value op,
2016 HArithmeticBinaryOperation* instr);
2017 LInstruction* DoArithmeticT(Token::Value op,
2018 HArithmeticBinaryOperation* instr);
399 2019
400 LChunk* chunk_; 2020 LChunk* chunk_;
401 HGraph* const graph_; 2021 HGraph* const graph_;
402 Status status_; 2022 Status status_;
403 HInstruction* current_instruction_; 2023 HInstruction* current_instruction_;
404 HBasicBlock* current_block_; 2024 HBasicBlock* current_block_;
405 HBasicBlock* next_block_; 2025 HBasicBlock* next_block_;
406 int argument_count_; 2026 int argument_count_;
407 LAllocator* allocator_; 2027 LAllocator* allocator_;
408 int position_; 2028 int position_;
409 LInstruction* instructions_pending_deoptimization_environment_; 2029 LInstruction* instructions_pending_deoptimization_environment_;
410 int pending_deoptimization_ast_id_; 2030 int pending_deoptimization_ast_id_;
411 2031
412 DISALLOW_COPY_AND_ASSIGN(LChunkBuilder); 2032 DISALLOW_COPY_AND_ASSIGN(LChunkBuilder);
413 }; 2033 };
414 2034
2035 #undef DECLARE_HYDROGEN_ACCESSOR
2036 #undef DECLARE_INSTRUCTION
2037 #undef DECLARE_CONCRETE_INSTRUCTION
415 2038
416 } } // namespace v8::internal 2039 } } // namespace v8::internal
417 2040
418 #endif // V8_X64_LITHIUM_X64_H_ 2041 #endif // V8_X64_LITHIUM_X64_H_
OLDNEW
« no previous file with comments | « src/x64/lithium-codegen-x64.cc ('k') | src/x64/lithium-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698