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

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

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

Powered by Google App Engine
This is Rietveld 408576698