V8 Project
lithium-mips64.h
Go to the documentation of this file.
1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef V8_MIPS_LITHIUM_MIPS_H_
6 #define V8_MIPS_LITHIUM_MIPS_H_
7 
8 #include "src/hydrogen.h"
9 #include "src/lithium.h"
10 #include "src/lithium-allocator.h"
11 #include "src/safepoint-table.h"
12 #include "src/utils.h"
13 
14 namespace v8 {
15 namespace internal {
16 
17 // Forward declarations.
18 class LCodeGen;
19 
20 #define LITHIUM_CONCRETE_INSTRUCTION_LIST(V) \
21  V(AccessArgumentsAt) \
22  V(AddI) \
23  V(Allocate) \
24  V(AllocateBlockContext) \
25  V(ApplyArguments) \
26  V(ArgumentsElements) \
27  V(ArgumentsLength) \
28  V(ArithmeticD) \
29  V(ArithmeticT) \
30  V(BitI) \
31  V(BoundsCheck) \
32  V(Branch) \
33  V(CallJSFunction) \
34  V(CallWithDescriptor) \
35  V(CallFunction) \
36  V(CallNew) \
37  V(CallNewArray) \
38  V(CallRuntime) \
39  V(CallStub) \
40  V(CheckInstanceType) \
41  V(CheckMaps) \
42  V(CheckMapValue) \
43  V(CheckNonSmi) \
44  V(CheckSmi) \
45  V(CheckValue) \
46  V(ClampDToUint8) \
47  V(ClampIToUint8) \
48  V(ClampTToUint8) \
49  V(ClassOfTestAndBranch) \
50  V(CompareMinusZeroAndBranch) \
51  V(CompareNumericAndBranch) \
52  V(CmpObjectEqAndBranch) \
53  V(CmpHoleAndBranch) \
54  V(CmpMapAndBranch) \
55  V(CmpT) \
56  V(ConstantD) \
57  V(ConstantE) \
58  V(ConstantI) \
59  V(ConstantS) \
60  V(ConstantT) \
61  V(ConstructDouble) \
62  V(Context) \
63  V(DateField) \
64  V(DebugBreak) \
65  V(DeclareGlobals) \
66  V(Deoptimize) \
67  V(DivByConstI) \
68  V(DivByPowerOf2I) \
69  V(DivI) \
70  V(DoubleToI) \
71  V(DoubleBits) \
72  V(DoubleToSmi) \
73  V(Drop) \
74  V(Dummy) \
75  V(DummyUse) \
76  V(FlooringDivByConstI) \
77  V(FlooringDivByPowerOf2I) \
78  V(FlooringDivI) \
79  V(ForInCacheArray) \
80  V(ForInPrepareMap) \
81  V(FunctionLiteral) \
82  V(GetCachedArrayIndex) \
83  V(Goto) \
84  V(HasCachedArrayIndexAndBranch) \
85  V(HasInstanceTypeAndBranch) \
86  V(InnerAllocatedObject) \
87  V(InstanceOf) \
88  V(InstanceOfKnownGlobal) \
89  V(InstructionGap) \
90  V(Integer32ToDouble) \
91  V(InvokeFunction) \
92  V(IsConstructCallAndBranch) \
93  V(IsObjectAndBranch) \
94  V(IsStringAndBranch) \
95  V(IsSmiAndBranch) \
96  V(IsUndetectableAndBranch) \
97  V(Label) \
98  V(LazyBailout) \
99  V(LoadContextSlot) \
100  V(LoadRoot) \
101  V(LoadFieldByIndex) \
102  V(LoadFunctionPrototype) \
103  V(LoadGlobalCell) \
104  V(LoadGlobalGeneric) \
105  V(LoadKeyed) \
106  V(LoadKeyedGeneric) \
107  V(LoadNamedField) \
108  V(LoadNamedGeneric) \
109  V(MapEnumLength) \
110  V(MathAbs) \
111  V(MathExp) \
112  V(MathClz32) \
113  V(MathFloor) \
114  V(MathFround) \
115  V(MathLog) \
116  V(MathMinMax) \
117  V(MathPowHalf) \
118  V(MathRound) \
119  V(MathSqrt) \
120  V(ModByConstI) \
121  V(ModByPowerOf2I) \
122  V(ModI) \
123  V(MulI) \
124  V(MultiplyAddD) \
125  V(NumberTagD) \
126  V(NumberTagU) \
127  V(NumberUntagD) \
128  V(OsrEntry) \
129  V(Parameter) \
130  V(Power) \
131  V(PushArgument) \
132  V(RegExpLiteral) \
133  V(Return) \
134  V(SeqStringGetChar) \
135  V(SeqStringSetChar) \
136  V(ShiftI) \
137  V(SmiTag) \
138  V(SmiUntag) \
139  V(StackCheck) \
140  V(StoreCodeEntry) \
141  V(StoreContextSlot) \
142  V(StoreFrameContext) \
143  V(StoreGlobalCell) \
144  V(StoreKeyed) \
145  V(StoreKeyedGeneric) \
146  V(StoreNamedField) \
147  V(StoreNamedGeneric) \
148  V(StringAdd) \
149  V(StringCharCodeAt) \
150  V(StringCharFromCode) \
151  V(StringCompareAndBranch) \
152  V(SubI) \
153  V(TaggedToI) \
154  V(TailCallThroughMegamorphicCache) \
155  V(ThisFunction) \
156  V(ToFastProperties) \
157  V(TransitionElementsKind) \
158  V(TrapAllocationMemento) \
159  V(Typeof) \
160  V(TypeofIsAndBranch) \
161  V(Uint32ToDouble) \
162  V(UnknownOSRValue) \
163  V(WrapReceiver)
164 
165 #define DECLARE_CONCRETE_INSTRUCTION(type, mnemonic) \
166  virtual Opcode opcode() const FINAL OVERRIDE { \
167  return LInstruction::k##type; \
168  } \
169  virtual void CompileToNative(LCodeGen* generator) FINAL OVERRIDE; \
170  virtual const char* Mnemonic() const FINAL OVERRIDE { \
171  return mnemonic; \
172  } \
173  static L##type* cast(LInstruction* instr) { \
174  DCHECK(instr->Is##type()); \
175  return reinterpret_cast<L##type*>(instr); \
176  }
177 
178 
179 #define DECLARE_HYDROGEN_ACCESSOR(type) \
180  H##type* hydrogen() const { \
181  return H##type::cast(hydrogen_value()); \
182  }
183 
184 
185 class LInstruction : public ZoneObject {
186  public:
188  : environment_(NULL),
190  bit_field_(IsCallBits::encode(false)) {
191  }
192 
193  virtual ~LInstruction() {}
194 
195  virtual void CompileToNative(LCodeGen* generator) = 0;
196  virtual const char* Mnemonic() const = 0;
197  virtual void PrintTo(StringStream* stream);
198  virtual void PrintDataTo(StringStream* stream);
199  virtual void PrintOutputOperandTo(StringStream* stream);
200 
201  enum Opcode {
202  // Declare a unique enum value for each instruction.
203 #define DECLARE_OPCODE(type) k##type,
206 #undef DECLARE_OPCODE
207  };
208 
209  virtual Opcode opcode() const = 0;
210 
211  // Declare non-virtual type testers for all leaf IR classes.
212 #define DECLARE_PREDICATE(type) \
213  bool Is##type() const { return opcode() == k##type; }
215 #undef DECLARE_PREDICATE
216 
217  // Declare virtual predicates for instructions that don't have
218  // an opcode.
219  virtual bool IsGap() const { return false; }
220 
221  virtual bool IsControl() const { return false; }
222 
223  // Try deleting this instruction if possible.
224  virtual bool TryDelete() { return false; }
225 
226  void set_environment(LEnvironment* env) { environment_ = env; }
227  LEnvironment* environment() const { return environment_; }
228  bool HasEnvironment() const { return environment_ != NULL; }
229 
230  void set_pointer_map(LPointerMap* p) { pointer_map_.set(p); }
231  LPointerMap* pointer_map() const { return pointer_map_.get(); }
232  bool HasPointerMap() const { return pointer_map_.is_set(); }
233 
234  void set_hydrogen_value(HValue* value) { hydrogen_value_ = value; }
235  HValue* hydrogen_value() const { return hydrogen_value_; }
236 
237  virtual void SetDeferredLazyDeoptimizationEnvironment(LEnvironment* env) { }
238 
240  bool IsCall() const { return IsCallBits::decode(bit_field_); }
241 
242  // Interface to the register allocator and iterators.
243  bool ClobbersTemps() const { return IsCall(); }
244  bool ClobbersRegisters() const { return IsCall(); }
245  virtual bool ClobbersDoubleRegisters(Isolate* isolate) const {
246  return IsCall();
247  }
248 
249  // Interface to the register allocator and iterators.
250  bool IsMarkedAsCall() const { return IsCall(); }
251 
252  virtual bool HasResult() const = 0;
253  virtual LOperand* result() const = 0;
254 
255  LOperand* FirstInput() { return InputAt(0); }
256  LOperand* Output() { return HasResult() ? result() : NULL; }
257 
258  virtual bool HasInterestingComment(LCodeGen* gen) const { return true; }
259 
260 #ifdef DEBUG
261  void VerifyCall();
262 #endif
263 
264  virtual int InputCount() = 0;
265  virtual LOperand* InputAt(int i) = 0;
266 
267  private:
268  // Iterator interface.
269  friend class InputIterator;
270 
271  friend class TempIterator;
272  virtual int TempCount() = 0;
273  virtual LOperand* TempAt(int i) = 0;
274 
275  class IsCallBits: public BitField<bool, 0, 1> {};
276 
277  LEnvironment* environment_;
280  int bit_field_;
281 };
282 
283 
284 // R = number of result operands (0 or 1).
285 template<int R>
286 class LTemplateResultInstruction : public LInstruction {
287  public:
288  // Allow 0 or 1 output operands.
289  STATIC_ASSERT(R == 0 || R == 1);
290  virtual bool HasResult() const FINAL OVERRIDE {
291  return R != 0 && result() != NULL;
292  }
293  void set_result(LOperand* operand) { results_[0] = operand; }
294  LOperand* result() const { return results_[0]; }
295 
296  protected:
298 };
299 
300 
301 // R = number of result operands (0 or 1).
302 // I = number of input operands.
303 // T = number of temporary operands.
304 template<int R, int I, int T>
305 class LTemplateInstruction : public LTemplateResultInstruction<R> {
306  protected:
307  EmbeddedContainer<LOperand*, I> inputs_;
308  EmbeddedContainer<LOperand*, T> temps_;
309 
310  private:
311  // Iterator support.
312  virtual int InputCount() FINAL OVERRIDE { return I; }
313  virtual LOperand* InputAt(int i) FINAL OVERRIDE { return inputs_[i]; }
314 
315  virtual int TempCount() FINAL OVERRIDE { return T; }
316  virtual LOperand* TempAt(int i) FINAL OVERRIDE { return temps_[i]; }
317 };
318 
319 
320 class LGap : public LTemplateInstruction<0, 0, 0> {
321  public:
322  explicit LGap(HBasicBlock* block)
323  : block_(block) {
328  }
329 
330  // Can't use the DECLARE-macro here because of sub-classes.
331  virtual bool IsGap() const FINAL OVERRIDE { return true; }
332  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
333  static LGap* cast(LInstruction* instr) {
334  DCHECK(instr->IsGap());
335  return reinterpret_cast<LGap*>(instr);
336  }
337 
338  bool IsRedundant() const;
339 
340  HBasicBlock* block() const { return block_; }
341 
343  BEFORE,
344  START,
345  END,
346  AFTER,
349  };
350 
351  LParallelMove* GetOrCreateParallelMove(InnerPosition pos, Zone* zone) {
352  if (parallel_moves_[pos] == NULL) {
353  parallel_moves_[pos] = new(zone) LParallelMove(zone);
354  }
355  return parallel_moves_[pos];
356  }
357 
358  LParallelMove* GetParallelMove(InnerPosition pos) {
359  return parallel_moves_[pos];
360  }
361 
362  private:
363  LParallelMove* parallel_moves_[LAST_INNER_POSITION + 1];
364  HBasicBlock* block_;
365 };
366 
367 
368 class LInstructionGap FINAL : public LGap {
369  public:
370  explicit LInstructionGap(HBasicBlock* block) : LGap(block) { }
371 
372  virtual bool HasInterestingComment(LCodeGen* gen) const OVERRIDE {
373  return !IsRedundant();
374  }
375 
376  DECLARE_CONCRETE_INSTRUCTION(InstructionGap, "gap")
377 };
378 
379 
380 class LGoto FINAL : public LTemplateInstruction<0, 0, 0> {
381  public:
382  explicit LGoto(HBasicBlock* block) : block_(block) { }
383 
384  virtual bool HasInterestingComment(LCodeGen* gen) const OVERRIDE;
385  DECLARE_CONCRETE_INSTRUCTION(Goto, "goto")
386  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
387  virtual bool IsControl() const OVERRIDE { return true; }
388 
389  int block_id() const { return block_->block_id(); }
390 
391  private:
392  HBasicBlock* block_;
393 };
394 
395 
396 class LLazyBailout FINAL : public LTemplateInstruction<0, 0, 0> {
397  public:
398  LLazyBailout() : gap_instructions_size_(0) { }
399 
400  DECLARE_CONCRETE_INSTRUCTION(LazyBailout, "lazy-bailout")
401 
402  void set_gap_instructions_size(int gap_instructions_size) {
403  gap_instructions_size_ = gap_instructions_size;
404  }
405  int gap_instructions_size() { return gap_instructions_size_; }
406 
407  private:
408  int gap_instructions_size_;
409 };
410 
411 
412 class LDummy FINAL : public LTemplateInstruction<1, 0, 0> {
413  public:
414  LDummy() {}
415  DECLARE_CONCRETE_INSTRUCTION(Dummy, "dummy")
416 };
417 
418 
419 class LDummyUse FINAL : public LTemplateInstruction<1, 1, 0> {
420  public:
421  explicit LDummyUse(LOperand* value) {
422  inputs_[0] = value;
423  }
424  DECLARE_CONCRETE_INSTRUCTION(DummyUse, "dummy-use")
425 };
426 
427 
428 class LDeoptimize FINAL : public LTemplateInstruction<0, 0, 0> {
429  public:
430  virtual bool IsControl() const OVERRIDE { return true; }
431  DECLARE_CONCRETE_INSTRUCTION(Deoptimize, "deoptimize")
432  DECLARE_HYDROGEN_ACCESSOR(Deoptimize)
433 };
434 
435 
436 class LLabel FINAL : public LGap {
437  public:
438  explicit LLabel(HBasicBlock* block)
439  : LGap(block), replacement_(NULL) { }
440 
441  virtual bool HasInterestingComment(LCodeGen* gen) const OVERRIDE {
442  return false;
443  }
444  DECLARE_CONCRETE_INSTRUCTION(Label, "label")
445 
446  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
447 
448  int block_id() const { return block()->block_id(); }
449  bool is_loop_header() const { return block()->IsLoopHeader(); }
450  bool is_osr_entry() const { return block()->is_osr_entry(); }
451  Label* label() { return &label_; }
452  LLabel* replacement() const { return replacement_; }
453  void set_replacement(LLabel* label) { replacement_ = label; }
454  bool HasReplacement() const { return replacement_ != NULL; }
455 
456  private:
457  Label label_;
458  LLabel* replacement_;
459 };
460 
461 
462 class LParameter FINAL : public LTemplateInstruction<1, 0, 0> {
463  public:
464  virtual bool HasInterestingComment(LCodeGen* gen) const OVERRIDE {
465  return false;
466  }
467  DECLARE_CONCRETE_INSTRUCTION(Parameter, "parameter")
468 };
469 
470 
471 class LCallStub FINAL : public LTemplateInstruction<1, 1, 0> {
472  public:
473  explicit LCallStub(LOperand* context) {
474  inputs_[0] = context;
475  }
476 
477  LOperand* context() { return inputs_[0]; }
478 
479  DECLARE_CONCRETE_INSTRUCTION(CallStub, "call-stub")
480  DECLARE_HYDROGEN_ACCESSOR(CallStub)
481 };
482 
483 
484 class LTailCallThroughMegamorphicCache FINAL
485  : public LTemplateInstruction<0, 3, 0> {
486  public:
488  LOperand* receiver,
489  LOperand* name) {
490  inputs_[0] = context;
491  inputs_[1] = receiver;
492  inputs_[2] = name;
493  }
494 
495  LOperand* context() { return inputs_[0]; }
496  LOperand* receiver() { return inputs_[1]; }
497  LOperand* name() { return inputs_[2]; }
498 
499  DECLARE_CONCRETE_INSTRUCTION(TailCallThroughMegamorphicCache,
500  "tail-call-through-megamorphic-cache")
501  DECLARE_HYDROGEN_ACCESSOR(TailCallThroughMegamorphicCache)
502 };
503 
504 
505 class LUnknownOSRValue FINAL : public LTemplateInstruction<1, 0, 0> {
506  public:
507  virtual bool HasInterestingComment(LCodeGen* gen) const OVERRIDE {
508  return false;
509  }
510  DECLARE_CONCRETE_INSTRUCTION(UnknownOSRValue, "unknown-osr-value")
511 };
512 
513 
514 template<int I, int T>
515 class LControlInstruction : public LTemplateInstruction<0, I, T> {
516  public:
517  LControlInstruction() : false_label_(NULL), true_label_(NULL) { }
518 
519  virtual bool IsControl() const FINAL OVERRIDE { return true; }
520 
521  int SuccessorCount() { return hydrogen()->SuccessorCount(); }
522  HBasicBlock* SuccessorAt(int i) { return hydrogen()->SuccessorAt(i); }
523 
524  int TrueDestination(LChunk* chunk) {
525  return chunk->LookupDestination(true_block_id());
526  }
527  int FalseDestination(LChunk* chunk) {
528  return chunk->LookupDestination(false_block_id());
529  }
530 
531  Label* TrueLabel(LChunk* chunk) {
532  if (true_label_ == NULL) {
533  true_label_ = chunk->GetAssemblyLabel(TrueDestination(chunk));
534  }
535  return true_label_;
536  }
537  Label* FalseLabel(LChunk* chunk) {
538  if (false_label_ == NULL) {
539  false_label_ = chunk->GetAssemblyLabel(FalseDestination(chunk));
540  }
541  return false_label_;
542  }
543 
544  protected:
545  int true_block_id() { return SuccessorAt(0)->block_id(); }
546  int false_block_id() { return SuccessorAt(1)->block_id(); }
547 
548  private:
550  return HControlInstruction::cast(this->hydrogen_value());
551  }
552 
553  Label* false_label_;
554  Label* true_label_;
555 };
556 
557 
558 class LWrapReceiver FINAL : public LTemplateInstruction<1, 2, 0> {
559  public:
560  LWrapReceiver(LOperand* receiver, LOperand* function) {
561  inputs_[0] = receiver;
562  inputs_[1] = function;
563  }
564 
565  DECLARE_CONCRETE_INSTRUCTION(WrapReceiver, "wrap-receiver")
566  DECLARE_HYDROGEN_ACCESSOR(WrapReceiver)
567 
568  LOperand* receiver() { return inputs_[0]; }
569  LOperand* function() { return inputs_[1]; }
570 };
571 
572 
573 class LApplyArguments FINAL : public LTemplateInstruction<1, 4, 0> {
574  public:
576  LOperand* receiver,
577  LOperand* length,
578  LOperand* elements) {
579  inputs_[0] = function;
580  inputs_[1] = receiver;
581  inputs_[2] = length;
582  inputs_[3] = elements;
583  }
584 
585  DECLARE_CONCRETE_INSTRUCTION(ApplyArguments, "apply-arguments")
586 
587  LOperand* function() { return inputs_[0]; }
588  LOperand* receiver() { return inputs_[1]; }
589  LOperand* length() { return inputs_[2]; }
590  LOperand* elements() { return inputs_[3]; }
591 };
592 
593 
594 class LAccessArgumentsAt FINAL : public LTemplateInstruction<1, 3, 0> {
595  public:
596  LAccessArgumentsAt(LOperand* arguments, LOperand* length, LOperand* index) {
597  inputs_[0] = arguments;
598  inputs_[1] = length;
599  inputs_[2] = index;
600  }
601 
602  DECLARE_CONCRETE_INSTRUCTION(AccessArgumentsAt, "access-arguments-at")
603 
604  LOperand* arguments() { return inputs_[0]; }
605  LOperand* length() { return inputs_[1]; }
606  LOperand* index() { return inputs_[2]; }
607 
608  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
609 };
610 
611 
612 class LArgumentsLength FINAL : public LTemplateInstruction<1, 1, 0> {
613  public:
614  explicit LArgumentsLength(LOperand* elements) {
615  inputs_[0] = elements;
616  }
617 
618  LOperand* elements() { return inputs_[0]; }
619 
620  DECLARE_CONCRETE_INSTRUCTION(ArgumentsLength, "arguments-length")
621 };
622 
623 
624 class LArgumentsElements FINAL : public LTemplateInstruction<1, 0, 0> {
625  public:
626  DECLARE_CONCRETE_INSTRUCTION(ArgumentsElements, "arguments-elements")
627  DECLARE_HYDROGEN_ACCESSOR(ArgumentsElements)
628 };
629 
630 
631 class LModByPowerOf2I FINAL : public LTemplateInstruction<1, 1, 0> {
632  public:
633  LModByPowerOf2I(LOperand* dividend, int32_t divisor) {
634  inputs_[0] = dividend;
635  divisor_ = divisor;
636  }
637 
638  LOperand* dividend() { return inputs_[0]; }
639  int32_t divisor() const { return divisor_; }
640 
641  DECLARE_CONCRETE_INSTRUCTION(ModByPowerOf2I, "mod-by-power-of-2-i")
643 
644  private:
645  int32_t divisor_;
646 };
647 
648 
649 class LModByConstI FINAL : public LTemplateInstruction<1, 1, 0> {
650  public:
651  LModByConstI(LOperand* dividend, int32_t divisor) {
652  inputs_[0] = dividend;
653  divisor_ = divisor;
654  }
655 
656  LOperand* dividend() { return inputs_[0]; }
657  int32_t divisor() const { return divisor_; }
658 
659  DECLARE_CONCRETE_INSTRUCTION(ModByConstI, "mod-by-const-i")
661 
662  private:
663  int32_t divisor_;
664 };
665 
666 
667 class LModI FINAL : public LTemplateInstruction<1, 2, 3> {
668  public:
670  LOperand* right) {
671  inputs_[0] = left;
672  inputs_[1] = right;
673  }
674 
675  LOperand* left() { return inputs_[0]; }
676  LOperand* right() { return inputs_[1]; }
677 
678  DECLARE_CONCRETE_INSTRUCTION(ModI, "mod-i")
680 };
681 
682 
683 class LDivByPowerOf2I FINAL : public LTemplateInstruction<1, 1, 0> {
684  public:
685  LDivByPowerOf2I(LOperand* dividend, int32_t divisor) {
686  inputs_[0] = dividend;
687  divisor_ = divisor;
688  }
689 
690  LOperand* dividend() { return inputs_[0]; }
691  int32_t divisor() const { return divisor_; }
692 
693  DECLARE_CONCRETE_INSTRUCTION(DivByPowerOf2I, "div-by-power-of-2-i")
695 
696  private:
697  int32_t divisor_;
698 };
699 
700 
701 class LDivByConstI FINAL : public LTemplateInstruction<1, 1, 0> {
702  public:
703  LDivByConstI(LOperand* dividend, int32_t divisor) {
704  inputs_[0] = dividend;
705  divisor_ = divisor;
706  }
707 
708  LOperand* dividend() { return inputs_[0]; }
709  int32_t divisor() const { return divisor_; }
710 
711  DECLARE_CONCRETE_INSTRUCTION(DivByConstI, "div-by-const-i")
713 
714  private:
715  int32_t divisor_;
716 };
717 
718 
719 class LDivI FINAL : public LTemplateInstruction<1, 2, 1> {
720  public:
721  LDivI(LOperand* dividend, LOperand* divisor, LOperand* temp) {
722  inputs_[0] = dividend;
723  inputs_[1] = divisor;
724  temps_[0] = temp;
725  }
726 
727  LOperand* dividend() { return inputs_[0]; }
728  LOperand* divisor() { return inputs_[1]; }
729  LOperand* temp() { return temps_[0]; }
730 
731  DECLARE_CONCRETE_INSTRUCTION(DivI, "div-i")
732  DECLARE_HYDROGEN_ACCESSOR(BinaryOperation)
733 };
734 
735 
736 class LFlooringDivByPowerOf2I FINAL : public LTemplateInstruction<1, 1, 0> {
737  public:
739  inputs_[0] = dividend;
740  divisor_ = divisor;
741  }
742 
743  LOperand* dividend() { return inputs_[0]; }
744  int32_t divisor() { return divisor_; }
745 
746  DECLARE_CONCRETE_INSTRUCTION(FlooringDivByPowerOf2I,
747  "flooring-div-by-power-of-2-i")
748  DECLARE_HYDROGEN_ACCESSOR(MathFloorOfDiv)
749 
750  private:
751  int32_t divisor_;
752 };
753 
754 
755 class LFlooringDivByConstI FINAL : public LTemplateInstruction<1, 1, 2> {
756  public:
757  LFlooringDivByConstI(LOperand* dividend, int32_t divisor, LOperand* temp) {
758  inputs_[0] = dividend;
759  divisor_ = divisor;
760  temps_[0] = temp;
761  }
762 
763  LOperand* dividend() { return inputs_[0]; }
764  int32_t divisor() const { return divisor_; }
765  LOperand* temp() { return temps_[0]; }
766 
767  DECLARE_CONCRETE_INSTRUCTION(FlooringDivByConstI, "flooring-div-by-const-i")
768  DECLARE_HYDROGEN_ACCESSOR(MathFloorOfDiv)
769 
770  private:
771  int32_t divisor_;
772 };
773 
774 
775 class LFlooringDivI FINAL : public LTemplateInstruction<1, 2, 0> {
776  public:
777  LFlooringDivI(LOperand* dividend, LOperand* divisor) {
778  inputs_[0] = dividend;
779  inputs_[1] = divisor;
780  }
781 
782  LOperand* dividend() { return inputs_[0]; }
783  LOperand* divisor() { return inputs_[1]; }
784 
785  DECLARE_CONCRETE_INSTRUCTION(FlooringDivI, "flooring-div-i")
786  DECLARE_HYDROGEN_ACCESSOR(MathFloorOfDiv)
787 };
788 
789 
790 class LMulI FINAL : public LTemplateInstruction<1, 2, 0> {
791  public:
792  LMulI(LOperand* left, LOperand* right) {
793  inputs_[0] = left;
794  inputs_[1] = right;
795  }
796 
797  LOperand* left() { return inputs_[0]; }
798  LOperand* right() { return inputs_[1]; }
799 
800  DECLARE_CONCRETE_INSTRUCTION(MulI, "mul-i")
802 };
803 
804 
805 // Instruction for computing multiplier * multiplicand + addend.
806 class LMultiplyAddD FINAL : public LTemplateInstruction<1, 3, 0> {
807  public:
808  LMultiplyAddD(LOperand* addend, LOperand* multiplier,
809  LOperand* multiplicand) {
810  inputs_[0] = addend;
811  inputs_[1] = multiplier;
812  inputs_[2] = multiplicand;
813  }
814 
815  LOperand* addend() { return inputs_[0]; }
816  LOperand* multiplier() { return inputs_[1]; }
817  LOperand* multiplicand() { return inputs_[2]; }
818 
819  DECLARE_CONCRETE_INSTRUCTION(MultiplyAddD, "multiply-add-d")
820 };
821 
822 
823 class LDebugBreak FINAL : public LTemplateInstruction<0, 0, 0> {
824  public:
825  DECLARE_CONCRETE_INSTRUCTION(DebugBreak, "break")
826 };
827 
828 
829 class LCompareNumericAndBranch FINAL : public LControlInstruction<2, 0> {
830  public:
832  inputs_[0] = left;
833  inputs_[1] = right;
834  }
835 
836  LOperand* left() { return inputs_[0]; }
837  LOperand* right() { return inputs_[1]; }
838 
839  DECLARE_CONCRETE_INSTRUCTION(CompareNumericAndBranch,
840  "compare-numeric-and-branch")
841  DECLARE_HYDROGEN_ACCESSOR(CompareNumericAndBranch)
842 
843  Token::Value op() const { return hydrogen()->token(); }
844  bool is_double() const {
845  return hydrogen()->representation().IsDouble();
846  }
847 
848  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
849 };
850 
851 
852 class LMathFloor FINAL : public LTemplateInstruction<1, 1, 1> {
853  public:
854  LMathFloor(LOperand* value, LOperand* temp) {
855  inputs_[0] = value;
856  temps_[0] = temp;
857  }
858 
859  LOperand* value() { return inputs_[0]; }
860  LOperand* temp() { return temps_[0]; }
861 
862  DECLARE_CONCRETE_INSTRUCTION(MathFloor, "math-floor")
863  DECLARE_HYDROGEN_ACCESSOR(UnaryMathOperation)
864 };
865 
866 
867 class LMathRound FINAL : public LTemplateInstruction<1, 1, 1> {
868  public:
869  LMathRound(LOperand* value, LOperand* temp) {
870  inputs_[0] = value;
871  temps_[0] = temp;
872  }
873 
874  LOperand* value() { return inputs_[0]; }
875  LOperand* temp() { return temps_[0]; }
876 
877  DECLARE_CONCRETE_INSTRUCTION(MathRound, "math-round")
878  DECLARE_HYDROGEN_ACCESSOR(UnaryMathOperation)
879 };
880 
881 
882 class LMathFround FINAL : public LTemplateInstruction<1, 1, 0> {
883  public:
884  explicit LMathFround(LOperand* value) { inputs_[0] = value; }
885 
886  LOperand* value() { return inputs_[0]; }
887 
888  DECLARE_CONCRETE_INSTRUCTION(MathFround, "math-fround")
889 };
890 
891 
892 class LMathAbs FINAL : public LTemplateInstruction<1, 2, 0> {
893  public:
894  LMathAbs(LOperand* context, LOperand* value) {
895  inputs_[1] = context;
896  inputs_[0] = value;
897  }
898 
899  LOperand* context() { return inputs_[1]; }
900  LOperand* value() { return inputs_[0]; }
901 
902  DECLARE_CONCRETE_INSTRUCTION(MathAbs, "math-abs")
903  DECLARE_HYDROGEN_ACCESSOR(UnaryMathOperation)
904 };
905 
906 
907 class LMathLog FINAL : public LTemplateInstruction<1, 1, 0> {
908  public:
909  explicit LMathLog(LOperand* value) {
910  inputs_[0] = value;
911  }
912 
913  LOperand* value() { return inputs_[0]; }
914 
915  DECLARE_CONCRETE_INSTRUCTION(MathLog, "math-log")
916 };
917 
918 
919 class LMathClz32 FINAL : public LTemplateInstruction<1, 1, 0> {
920  public:
921  explicit LMathClz32(LOperand* value) {
922  inputs_[0] = value;
923  }
924 
925  LOperand* value() { return inputs_[0]; }
926 
927  DECLARE_CONCRETE_INSTRUCTION(MathClz32, "math-clz32")
928 };
929 
930 
931 class LMathExp FINAL : public LTemplateInstruction<1, 1, 3> {
932  public:
934  LOperand* double_temp,
935  LOperand* temp1,
936  LOperand* temp2) {
937  inputs_[0] = value;
938  temps_[0] = temp1;
939  temps_[1] = temp2;
940  temps_[2] = double_temp;
941  ExternalReference::InitializeMathExpData();
942  }
943 
944  LOperand* value() { return inputs_[0]; }
945  LOperand* temp1() { return temps_[0]; }
946  LOperand* temp2() { return temps_[1]; }
947  LOperand* double_temp() { return temps_[2]; }
948 
949  DECLARE_CONCRETE_INSTRUCTION(MathExp, "math-exp")
950 };
951 
952 
953 class LMathSqrt FINAL : public LTemplateInstruction<1, 1, 0> {
954  public:
955  explicit LMathSqrt(LOperand* value) {
956  inputs_[0] = value;
957  }
958 
959  LOperand* value() { return inputs_[0]; }
960 
961  DECLARE_CONCRETE_INSTRUCTION(MathSqrt, "math-sqrt")
962 };
963 
964 
965 class LMathPowHalf FINAL : public LTemplateInstruction<1, 1, 1> {
966  public:
967  LMathPowHalf(LOperand* value, LOperand* temp) {
968  inputs_[0] = value;
969  temps_[0] = temp;
970  }
971 
972  LOperand* value() { return inputs_[0]; }
973  LOperand* temp() { return temps_[0]; }
974 
975  DECLARE_CONCRETE_INSTRUCTION(MathPowHalf, "math-pow-half")
976 };
977 
978 
979 class LCmpObjectEqAndBranch FINAL : public LControlInstruction<2, 0> {
980  public:
982  inputs_[0] = left;
983  inputs_[1] = right;
984  }
985 
986  LOperand* left() { return inputs_[0]; }
987  LOperand* right() { return inputs_[1]; }
988 
989  DECLARE_CONCRETE_INSTRUCTION(CmpObjectEqAndBranch, "cmp-object-eq-and-branch")
990  DECLARE_HYDROGEN_ACCESSOR(CompareObjectEqAndBranch)
991 };
992 
993 
994 class LCmpHoleAndBranch FINAL : public LControlInstruction<1, 0> {
995  public:
996  explicit LCmpHoleAndBranch(LOperand* object) {
997  inputs_[0] = object;
998  }
999 
1000  LOperand* object() { return inputs_[0]; }
1001 
1002  DECLARE_CONCRETE_INSTRUCTION(CmpHoleAndBranch, "cmp-hole-and-branch")
1003  DECLARE_HYDROGEN_ACCESSOR(CompareHoleAndBranch)
1004 };
1005 
1006 
1007 class LCompareMinusZeroAndBranch FINAL : public LControlInstruction<1, 1> {
1008  public:
1010  inputs_[0] = value;
1011  temps_[0] = temp;
1012  }
1013 
1014  LOperand* value() { return inputs_[0]; }
1015  LOperand* temp() { return temps_[0]; }
1016 
1017  DECLARE_CONCRETE_INSTRUCTION(CompareMinusZeroAndBranch,
1018  "cmp-minus-zero-and-branch")
1019  DECLARE_HYDROGEN_ACCESSOR(CompareMinusZeroAndBranch)
1020 };
1021 
1022 
1023 class LIsObjectAndBranch FINAL : public LControlInstruction<1, 1> {
1024  public:
1026  inputs_[0] = value;
1027  temps_[0] = temp;
1028  }
1029 
1030  LOperand* value() { return inputs_[0]; }
1031  LOperand* temp() { return temps_[0]; }
1032 
1033  DECLARE_CONCRETE_INSTRUCTION(IsObjectAndBranch, "is-object-and-branch")
1034  DECLARE_HYDROGEN_ACCESSOR(IsObjectAndBranch)
1035 
1036  virtual void PrintDataTo(StringStream* stream);
1037 };
1038 
1039 
1040 class LIsStringAndBranch FINAL : public LControlInstruction<1, 1> {
1041  public:
1043  inputs_[0] = value;
1044  temps_[0] = temp;
1045  }
1046 
1047  LOperand* value() { return inputs_[0]; }
1048  LOperand* temp() { return temps_[0]; }
1049 
1050  DECLARE_CONCRETE_INSTRUCTION(IsStringAndBranch, "is-string-and-branch")
1051  DECLARE_HYDROGEN_ACCESSOR(IsStringAndBranch)
1052 
1053  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
1054 };
1055 
1056 
1057 class LIsSmiAndBranch FINAL : public LControlInstruction<1, 0> {
1058  public:
1059  explicit LIsSmiAndBranch(LOperand* value) {
1060  inputs_[0] = value;
1061  }
1062 
1063  LOperand* value() { return inputs_[0]; }
1064 
1065  DECLARE_CONCRETE_INSTRUCTION(IsSmiAndBranch, "is-smi-and-branch")
1066  DECLARE_HYDROGEN_ACCESSOR(IsSmiAndBranch)
1067 
1068  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
1069 };
1070 
1071 
1072 class LIsUndetectableAndBranch FINAL : public LControlInstruction<1, 1> {
1073  public:
1074  explicit LIsUndetectableAndBranch(LOperand* value, LOperand* temp) {
1075  inputs_[0] = value;
1076  temps_[0] = temp;
1077  }
1078 
1079  LOperand* value() { return inputs_[0]; }
1080  LOperand* temp() { return temps_[0]; }
1081 
1082  DECLARE_CONCRETE_INSTRUCTION(IsUndetectableAndBranch,
1083  "is-undetectable-and-branch")
1084  DECLARE_HYDROGEN_ACCESSOR(IsUndetectableAndBranch)
1085 
1086  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
1087 };
1088 
1089 
1090 class LStringCompareAndBranch FINAL : public LControlInstruction<3, 0> {
1091  public:
1093  inputs_[0] = context;
1094  inputs_[1] = left;
1095  inputs_[2] = right;
1096  }
1097 
1098  LOperand* context() { return inputs_[0]; }
1099  LOperand* left() { return inputs_[1]; }
1100  LOperand* right() { return inputs_[2]; }
1101 
1102  DECLARE_CONCRETE_INSTRUCTION(StringCompareAndBranch,
1103  "string-compare-and-branch")
1104  DECLARE_HYDROGEN_ACCESSOR(StringCompareAndBranch)
1105 
1106  Token::Value op() const { return hydrogen()->token(); }
1107 
1108  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
1109 };
1110 
1111 
1112 class LHasInstanceTypeAndBranch FINAL : public LControlInstruction<1, 0> {
1113  public:
1115  inputs_[0] = value;
1116  }
1117 
1118  LOperand* value() { return inputs_[0]; }
1119 
1120  DECLARE_CONCRETE_INSTRUCTION(HasInstanceTypeAndBranch,
1121  "has-instance-type-and-branch")
1122  DECLARE_HYDROGEN_ACCESSOR(HasInstanceTypeAndBranch)
1123 
1124  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
1125 };
1126 
1127 
1128 class LGetCachedArrayIndex FINAL : public LTemplateInstruction<1, 1, 0> {
1129  public:
1130  explicit LGetCachedArrayIndex(LOperand* value) {
1131  inputs_[0] = value;
1132  }
1133 
1134  LOperand* value() { return inputs_[0]; }
1135 
1136  DECLARE_CONCRETE_INSTRUCTION(GetCachedArrayIndex, "get-cached-array-index")
1137  DECLARE_HYDROGEN_ACCESSOR(GetCachedArrayIndex)
1138 };
1139 
1140 
1141 class LHasCachedArrayIndexAndBranch FINAL
1142  : public LControlInstruction<1, 0> {
1143  public:
1145  inputs_[0] = value;
1146  }
1147 
1148  LOperand* value() { return inputs_[0]; }
1149 
1150  DECLARE_CONCRETE_INSTRUCTION(HasCachedArrayIndexAndBranch,
1151  "has-cached-array-index-and-branch")
1152  DECLARE_HYDROGEN_ACCESSOR(HasCachedArrayIndexAndBranch)
1153 
1154  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
1155 };
1156 
1157 
1158 class LClassOfTestAndBranch FINAL : public LControlInstruction<1, 1> {
1159  public:
1161  inputs_[0] = value;
1162  temps_[0] = temp;
1163  }
1164 
1165  LOperand* value() { return inputs_[0]; }
1166  LOperand* temp() { return temps_[0]; }
1167 
1168  DECLARE_CONCRETE_INSTRUCTION(ClassOfTestAndBranch,
1169  "class-of-test-and-branch")
1170  DECLARE_HYDROGEN_ACCESSOR(ClassOfTestAndBranch)
1171 
1172  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
1173 };
1174 
1175 
1176 class LCmpT FINAL : public LTemplateInstruction<1, 3, 0> {
1177  public:
1178  LCmpT(LOperand* context, LOperand* left, LOperand* right) {
1179  inputs_[0] = context;
1180  inputs_[1] = left;
1181  inputs_[2] = right;
1182  }
1183 
1184  LOperand* context() { return inputs_[0]; }
1185  LOperand* left() { return inputs_[1]; }
1186  LOperand* right() { return inputs_[2]; }
1187 
1188  DECLARE_CONCRETE_INSTRUCTION(CmpT, "cmp-t")
1189  DECLARE_HYDROGEN_ACCESSOR(CompareGeneric)
1190 
1191  Token::Value op() const { return hydrogen()->token(); }
1192 };
1193 
1194 
1195 class LInstanceOf FINAL : public LTemplateInstruction<1, 3, 0> {
1196  public:
1197  LInstanceOf(LOperand* context, LOperand* left, LOperand* right) {
1198  inputs_[0] = context;
1199  inputs_[1] = left;
1200  inputs_[2] = right;
1201  }
1202 
1203  LOperand* context() { return inputs_[0]; }
1204  LOperand* left() { return inputs_[1]; }
1205  LOperand* right() { return inputs_[2]; }
1206 
1207  DECLARE_CONCRETE_INSTRUCTION(InstanceOf, "instance-of")
1208 };
1209 
1210 
1211 class LInstanceOfKnownGlobal FINAL : public LTemplateInstruction<1, 2, 1> {
1212  public:
1214  inputs_[0] = context;
1215  inputs_[1] = value;
1216  temps_[0] = temp;
1217  }
1218 
1219  LOperand* context() { return inputs_[0]; }
1220  LOperand* value() { return inputs_[1]; }
1221  LOperand* temp() { return temps_[0]; }
1222 
1223  DECLARE_CONCRETE_INSTRUCTION(InstanceOfKnownGlobal,
1224  "instance-of-known-global")
1225  DECLARE_HYDROGEN_ACCESSOR(InstanceOfKnownGlobal)
1226 
1227  Handle<JSFunction> function() const { return hydrogen()->function(); }
1229  return lazy_deopt_env_;
1230  }
1232  LEnvironment* env) OVERRIDE {
1233  lazy_deopt_env_ = env;
1234  }
1235 
1236  private:
1237  LEnvironment* lazy_deopt_env_;
1238 };
1239 
1240 
1241 class LBoundsCheck FINAL : public LTemplateInstruction<0, 2, 0> {
1242  public:
1243  LBoundsCheck(LOperand* index, LOperand* length) {
1244  inputs_[0] = index;
1245  inputs_[1] = length;
1246  }
1247 
1248  LOperand* index() { return inputs_[0]; }
1249  LOperand* length() { return inputs_[1]; }
1250 
1251  DECLARE_CONCRETE_INSTRUCTION(BoundsCheck, "bounds-check")
1252  DECLARE_HYDROGEN_ACCESSOR(BoundsCheck)
1253 };
1254 
1255 
1256 class LBitI FINAL : public LTemplateInstruction<1, 2, 0> {
1257  public:
1258  LBitI(LOperand* left, LOperand* right) {
1259  inputs_[0] = left;
1260  inputs_[1] = right;
1261  }
1262 
1263  LOperand* left() { return inputs_[0]; }
1264  LOperand* right() { return inputs_[1]; }
1265 
1266  Token::Value op() const { return hydrogen()->op(); }
1267 
1268  DECLARE_CONCRETE_INSTRUCTION(BitI, "bit-i")
1269  DECLARE_HYDROGEN_ACCESSOR(Bitwise)
1270 };
1271 
1272 
1273 class LShiftI FINAL : public LTemplateInstruction<1, 2, 0> {
1274  public:
1275  LShiftI(Token::Value op, LOperand* left, LOperand* right, bool can_deopt)
1276  : op_(op), can_deopt_(can_deopt) {
1277  inputs_[0] = left;
1278  inputs_[1] = right;
1279  }
1280 
1281  Token::Value op() const { return op_; }
1282  LOperand* left() { return inputs_[0]; }
1283  LOperand* right() { return inputs_[1]; }
1284  bool can_deopt() const { return can_deopt_; }
1285 
1286  DECLARE_CONCRETE_INSTRUCTION(ShiftI, "shift-i")
1287 
1288  private:
1289  Token::Value op_;
1290  bool can_deopt_;
1291 };
1292 
1293 
1294 class LSubI FINAL : public LTemplateInstruction<1, 2, 0> {
1295  public:
1296  LSubI(LOperand* left, LOperand* right) {
1297  inputs_[0] = left;
1298  inputs_[1] = right;
1299  }
1300 
1301  LOperand* left() { return inputs_[0]; }
1302  LOperand* right() { return inputs_[1]; }
1303 
1304  DECLARE_CONCRETE_INSTRUCTION(SubI, "sub-i")
1306 };
1307 
1308 
1309 class LConstantI FINAL : public LTemplateInstruction<1, 0, 0> {
1310  public:
1311  DECLARE_CONCRETE_INSTRUCTION(ConstantI, "constant-i")
1312  DECLARE_HYDROGEN_ACCESSOR(Constant)
1313 
1314  int32_t value() const { return hydrogen()->Integer32Value(); }
1315 };
1316 
1317 
1318 class LConstantS FINAL : public LTemplateInstruction<1, 0, 0> {
1319  public:
1320  DECLARE_CONCRETE_INSTRUCTION(ConstantS, "constant-s")
1321  DECLARE_HYDROGEN_ACCESSOR(Constant)
1322 
1323  Smi* value() const { return Smi::FromInt(hydrogen()->Integer32Value()); }
1324 };
1325 
1326 
1327 class LConstantD FINAL : public LTemplateInstruction<1, 0, 0> {
1328  public:
1329  DECLARE_CONCRETE_INSTRUCTION(ConstantD, "constant-d")
1330  DECLARE_HYDROGEN_ACCESSOR(Constant)
1331 
1332  double value() const { return hydrogen()->DoubleValue(); }
1333 };
1334 
1335 
1336 class LConstantE FINAL : public LTemplateInstruction<1, 0, 0> {
1337  public:
1338  DECLARE_CONCRETE_INSTRUCTION(ConstantE, "constant-e")
1339  DECLARE_HYDROGEN_ACCESSOR(Constant)
1340 
1341  ExternalReference value() const {
1342  return hydrogen()->ExternalReferenceValue();
1343  }
1344 };
1345 
1346 
1347 class LConstantT FINAL : public LTemplateInstruction<1, 0, 0> {
1348  public:
1349  DECLARE_CONCRETE_INSTRUCTION(ConstantT, "constant-t")
1350  DECLARE_HYDROGEN_ACCESSOR(Constant)
1351 
1352  Handle<Object> value(Isolate* isolate) const {
1353  return hydrogen()->handle(isolate);
1354  }
1355 };
1356 
1357 
1358 class LBranch FINAL : public LControlInstruction<1, 0> {
1359  public:
1360  explicit LBranch(LOperand* value) {
1361  inputs_[0] = value;
1362  }
1363 
1364  LOperand* value() { return inputs_[0]; }
1365 
1366  DECLARE_CONCRETE_INSTRUCTION(Branch, "branch")
1368 
1369  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
1370 };
1371 
1372 
1373 class LCmpMapAndBranch FINAL : public LControlInstruction<1, 1> {
1374  public:
1376  inputs_[0] = value;
1377  temps_[0] = temp;
1378  }
1379 
1380  LOperand* value() { return inputs_[0]; }
1381  LOperand* temp() { return temps_[0]; }
1382 
1383  DECLARE_CONCRETE_INSTRUCTION(CmpMapAndBranch, "cmp-map-and-branch")
1384  DECLARE_HYDROGEN_ACCESSOR(CompareMap)
1385 
1386  Handle<Map> map() const { return hydrogen()->map().handle(); }
1387 };
1388 
1389 
1390 class LMapEnumLength FINAL : public LTemplateInstruction<1, 1, 0> {
1391  public:
1392  explicit LMapEnumLength(LOperand* value) {
1393  inputs_[0] = value;
1394  }
1395 
1396  LOperand* value() { return inputs_[0]; }
1397 
1398  DECLARE_CONCRETE_INSTRUCTION(MapEnumLength, "map-enum-length")
1399 };
1400 
1401 
1402 class LDateField FINAL : public LTemplateInstruction<1, 1, 1> {
1403  public:
1404  LDateField(LOperand* date, LOperand* temp, Smi* index) : index_(index) {
1405  inputs_[0] = date;
1406  temps_[0] = temp;
1407  }
1408 
1409  LOperand* date() { return inputs_[0]; }
1410  LOperand* temp() { return temps_[0]; }
1411  Smi* index() const { return index_; }
1412 
1413  DECLARE_CONCRETE_INSTRUCTION(DateField, "date-field")
1414  DECLARE_HYDROGEN_ACCESSOR(DateField)
1415 
1416  private:
1417  Smi* index_;
1418 };
1419 
1420 
1421 class LSeqStringGetChar FINAL : public LTemplateInstruction<1, 2, 0> {
1422  public:
1424  inputs_[0] = string;
1425  inputs_[1] = index;
1426  }
1427 
1428  LOperand* string() const { return inputs_[0]; }
1429  LOperand* index() const { return inputs_[1]; }
1430 
1431  DECLARE_CONCRETE_INSTRUCTION(SeqStringGetChar, "seq-string-get-char")
1432  DECLARE_HYDROGEN_ACCESSOR(SeqStringGetChar)
1433 };
1434 
1435 
1436 class LSeqStringSetChar FINAL : public LTemplateInstruction<1, 4, 0> {
1437  public:
1439  LOperand* string,
1440  LOperand* index,
1441  LOperand* value) {
1442  inputs_[0] = context;
1443  inputs_[1] = string;
1444  inputs_[2] = index;
1445  inputs_[3] = value;
1446  }
1447 
1448  LOperand* string() { return inputs_[1]; }
1449  LOperand* index() { return inputs_[2]; }
1450  LOperand* value() { return inputs_[3]; }
1451 
1452  DECLARE_CONCRETE_INSTRUCTION(SeqStringSetChar, "seq-string-set-char")
1453  DECLARE_HYDROGEN_ACCESSOR(SeqStringSetChar)
1454 };
1455 
1456 
1457 class LAddI FINAL : public LTemplateInstruction<1, 2, 0> {
1458  public:
1459  LAddI(LOperand* left, LOperand* right) {
1460  inputs_[0] = left;
1461  inputs_[1] = right;
1462  }
1463 
1464  LOperand* left() { return inputs_[0]; }
1465  LOperand* right() { return inputs_[1]; }
1466 
1467  DECLARE_CONCRETE_INSTRUCTION(AddI, "add-i")
1469 };
1470 
1471 
1472 class LMathMinMax FINAL : public LTemplateInstruction<1, 2, 0> {
1473  public:
1474  LMathMinMax(LOperand* left, LOperand* right) {
1475  inputs_[0] = left;
1476  inputs_[1] = right;
1477  }
1478 
1479  LOperand* left() { return inputs_[0]; }
1480  LOperand* right() { return inputs_[1]; }
1481 
1482  DECLARE_CONCRETE_INSTRUCTION(MathMinMax, "math-min-max")
1483  DECLARE_HYDROGEN_ACCESSOR(MathMinMax)
1484 };
1485 
1486 
1487 class LPower FINAL : public LTemplateInstruction<1, 2, 0> {
1488  public:
1489  LPower(LOperand* left, LOperand* right) {
1490  inputs_[0] = left;
1491  inputs_[1] = right;
1492  }
1493 
1494  LOperand* left() { return inputs_[0]; }
1495  LOperand* right() { return inputs_[1]; }
1496 
1497  DECLARE_CONCRETE_INSTRUCTION(Power, "power")
1499 };
1500 
1501 
1502 class LArithmeticD FINAL : public LTemplateInstruction<1, 2, 0> {
1503  public:
1505  : op_(op) {
1506  inputs_[0] = left;
1507  inputs_[1] = right;
1508  }
1509 
1510  Token::Value op() const { return op_; }
1511  LOperand* left() { return inputs_[0]; }
1512  LOperand* right() { return inputs_[1]; }
1513 
1514  virtual Opcode opcode() const OVERRIDE {
1515  return LInstruction::kArithmeticD;
1516  }
1517  virtual void CompileToNative(LCodeGen* generator) OVERRIDE;
1518  virtual const char* Mnemonic() const OVERRIDE;
1519 
1520  private:
1521  Token::Value op_;
1522 };
1523 
1524 
1525 class LArithmeticT FINAL : public LTemplateInstruction<1, 3, 0> {
1526  public:
1528  LOperand* context,
1529  LOperand* left,
1530  LOperand* right)
1531  : op_(op) {
1532  inputs_[0] = context;
1533  inputs_[1] = left;
1534  inputs_[2] = right;
1535  }
1536 
1537  LOperand* context() { return inputs_[0]; }
1538  LOperand* left() { return inputs_[1]; }
1539  LOperand* right() { return inputs_[2]; }
1540  Token::Value op() const { return op_; }
1541 
1542  virtual Opcode opcode() const FINAL { return LInstruction::kArithmeticT; }
1543  virtual void CompileToNative(LCodeGen* generator) OVERRIDE;
1544  virtual const char* Mnemonic() const OVERRIDE;
1545 
1546  private:
1547  Token::Value op_;
1548 };
1549 
1550 
1551 class LReturn FINAL : public LTemplateInstruction<0, 3, 0> {
1552  public:
1553  LReturn(LOperand* value, LOperand* context, LOperand* parameter_count) {
1554  inputs_[0] = value;
1555  inputs_[1] = context;
1556  inputs_[2] = parameter_count;
1557  }
1558 
1559  LOperand* value() { return inputs_[0]; }
1560 
1562  return parameter_count()->IsConstantOperand();
1563  }
1564  LConstantOperand* constant_parameter_count() {
1565  DCHECK(has_constant_parameter_count());
1566  return LConstantOperand::cast(parameter_count());
1567  }
1568  LOperand* parameter_count() { return inputs_[2]; }
1569 
1570  DECLARE_CONCRETE_INSTRUCTION(Return, "return")
1571 };
1572 
1573 
1574 class LLoadNamedField FINAL : public LTemplateInstruction<1, 1, 0> {
1575  public:
1576  explicit LLoadNamedField(LOperand* object) {
1577  inputs_[0] = object;
1578  }
1579 
1580  LOperand* object() { return inputs_[0]; }
1581 
1582  DECLARE_CONCRETE_INSTRUCTION(LoadNamedField, "load-named-field")
1583  DECLARE_HYDROGEN_ACCESSOR(LoadNamedField)
1584 };
1585 
1586 
1587 class LLoadNamedGeneric FINAL : public LTemplateInstruction<1, 2, 1> {
1588  public:
1589  LLoadNamedGeneric(LOperand* context, LOperand* object, LOperand* vector) {
1590  inputs_[0] = context;
1591  inputs_[1] = object;
1592  temps_[0] = vector;
1593  }
1594 
1595  LOperand* context() { return inputs_[0]; }
1596  LOperand* object() { return inputs_[1]; }
1597  LOperand* temp_vector() { return temps_[0]; }
1598 
1599  DECLARE_CONCRETE_INSTRUCTION(LoadNamedGeneric, "load-named-generic")
1600  DECLARE_HYDROGEN_ACCESSOR(LoadNamedGeneric)
1601 
1602  Handle<Object> name() const { return hydrogen()->name(); }
1603 };
1604 
1605 
1606 class LLoadFunctionPrototype FINAL : public LTemplateInstruction<1, 1, 0> {
1607  public:
1608  explicit LLoadFunctionPrototype(LOperand* function) {
1609  inputs_[0] = function;
1610  }
1611 
1612  LOperand* function() { return inputs_[0]; }
1613 
1614  DECLARE_CONCRETE_INSTRUCTION(LoadFunctionPrototype, "load-function-prototype")
1615  DECLARE_HYDROGEN_ACCESSOR(LoadFunctionPrototype)
1616 };
1617 
1618 
1619 class LLoadRoot FINAL : public LTemplateInstruction<1, 0, 0> {
1620  public:
1621  DECLARE_CONCRETE_INSTRUCTION(LoadRoot, "load-root")
1622  DECLARE_HYDROGEN_ACCESSOR(LoadRoot)
1623 
1624  Heap::RootListIndex index() const { return hydrogen()->index(); }
1625 };
1626 
1627 
1628 class LLoadKeyed FINAL : public LTemplateInstruction<1, 2, 0> {
1629  public:
1630  LLoadKeyed(LOperand* elements, LOperand* key) {
1631  inputs_[0] = elements;
1632  inputs_[1] = key;
1633  }
1634 
1635  LOperand* elements() { return inputs_[0]; }
1636  LOperand* key() { return inputs_[1]; }
1638  return hydrogen()->elements_kind();
1639  }
1640  bool is_external() const {
1641  return hydrogen()->is_external();
1642  }
1643  bool is_fixed_typed_array() const {
1644  return hydrogen()->is_fixed_typed_array();
1645  }
1646  bool is_typed_elements() const {
1647  return is_external() || is_fixed_typed_array();
1648  }
1649 
1650  DECLARE_CONCRETE_INSTRUCTION(LoadKeyed, "load-keyed")
1651  DECLARE_HYDROGEN_ACCESSOR(LoadKeyed)
1652 
1653  virtual void PrintDataTo(StringStream* stream);
1654  uint32_t base_offset() const { return hydrogen()->base_offset(); }
1655 };
1656 
1657 
1658 class LLoadKeyedGeneric FINAL : public LTemplateInstruction<1, 3, 1> {
1659  public:
1660  LLoadKeyedGeneric(LOperand* context, LOperand* object, LOperand* key,
1661  LOperand* vector) {
1662  inputs_[0] = context;
1663  inputs_[1] = object;
1664  inputs_[2] = key;
1665  temps_[0] = vector;
1666  }
1667 
1668  LOperand* context() { return inputs_[0]; }
1669  LOperand* object() { return inputs_[1]; }
1670  LOperand* key() { return inputs_[2]; }
1671  LOperand* temp_vector() { return temps_[0]; }
1672 
1673  DECLARE_CONCRETE_INSTRUCTION(LoadKeyedGeneric, "load-keyed-generic")
1674  DECLARE_HYDROGEN_ACCESSOR(LoadKeyedGeneric)
1675 };
1676 
1677 
1678 class LLoadGlobalCell FINAL : public LTemplateInstruction<1, 0, 0> {
1679  public:
1680  DECLARE_CONCRETE_INSTRUCTION(LoadGlobalCell, "load-global-cell")
1681  DECLARE_HYDROGEN_ACCESSOR(LoadGlobalCell)
1682 };
1683 
1684 
1685 class LLoadGlobalGeneric FINAL : public LTemplateInstruction<1, 2, 1> {
1686  public:
1687  LLoadGlobalGeneric(LOperand* context, LOperand* global_object,
1688  LOperand* vector) {
1689  inputs_[0] = context;
1690  inputs_[1] = global_object;
1691  temps_[0] = vector;
1692  }
1693 
1694  LOperand* context() { return inputs_[0]; }
1695  LOperand* global_object() { return inputs_[1]; }
1696  LOperand* temp_vector() { return temps_[0]; }
1697 
1698  DECLARE_CONCRETE_INSTRUCTION(LoadGlobalGeneric, "load-global-generic")
1699  DECLARE_HYDROGEN_ACCESSOR(LoadGlobalGeneric)
1700 
1701  Handle<Object> name() const { return hydrogen()->name(); }
1702  bool for_typeof() const { return hydrogen()->for_typeof(); }
1703 };
1704 
1705 
1706 class LStoreGlobalCell FINAL : public LTemplateInstruction<0, 1, 1> {
1707  public:
1709  inputs_[0] = value;
1710  temps_[0] = temp;
1711  }
1712 
1713  LOperand* value() { return inputs_[0]; }
1714  LOperand* temp() { return temps_[0]; }
1715 
1716  DECLARE_CONCRETE_INSTRUCTION(StoreGlobalCell, "store-global-cell")
1717  DECLARE_HYDROGEN_ACCESSOR(StoreGlobalCell)
1718 };
1719 
1720 
1721 class LLoadContextSlot FINAL : public LTemplateInstruction<1, 1, 0> {
1722  public:
1723  explicit LLoadContextSlot(LOperand* context) {
1724  inputs_[0] = context;
1725  }
1726 
1727  LOperand* context() { return inputs_[0]; }
1728 
1729  DECLARE_CONCRETE_INSTRUCTION(LoadContextSlot, "load-context-slot")
1730  DECLARE_HYDROGEN_ACCESSOR(LoadContextSlot)
1731 
1732  int slot_index() { return hydrogen()->slot_index(); }
1733 
1734  virtual void PrintDataTo(StringStream* stream);
1735 };
1736 
1737 
1738 class LStoreContextSlot FINAL : public LTemplateInstruction<0, 2, 0> {
1739  public:
1741  inputs_[0] = context;
1742  inputs_[1] = value;
1743  }
1744 
1745  LOperand* context() { return inputs_[0]; }
1746  LOperand* value() { return inputs_[1]; }
1747 
1748  DECLARE_CONCRETE_INSTRUCTION(StoreContextSlot, "store-context-slot")
1749  DECLARE_HYDROGEN_ACCESSOR(StoreContextSlot)
1750 
1751  int slot_index() { return hydrogen()->slot_index(); }
1752 
1753  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
1754 };
1755 
1756 
1757 class LPushArgument FINAL : public LTemplateInstruction<0, 1, 0> {
1758  public:
1759  explicit LPushArgument(LOperand* value) {
1760  inputs_[0] = value;
1761  }
1762 
1763  LOperand* value() { return inputs_[0]; }
1764 
1765  DECLARE_CONCRETE_INSTRUCTION(PushArgument, "push-argument")
1766 };
1767 
1768 
1769 class LDrop FINAL : public LTemplateInstruction<0, 0, 0> {
1770  public:
1771  explicit LDrop(int count) : count_(count) { }
1772 
1773  int count() const { return count_; }
1774 
1775  DECLARE_CONCRETE_INSTRUCTION(Drop, "drop")
1776 
1777  private:
1778  int count_;
1779 };
1780 
1781 
1782 class LStoreCodeEntry FINAL: public LTemplateInstruction<0, 2, 0> {
1783  public:
1784  LStoreCodeEntry(LOperand* function, LOperand* code_object) {
1785  inputs_[0] = function;
1786  inputs_[1] = code_object;
1787  }
1788 
1789  LOperand* function() { return inputs_[0]; }
1790  LOperand* code_object() { return inputs_[1]; }
1791 
1792  virtual void PrintDataTo(StringStream* stream);
1793 
1794  DECLARE_CONCRETE_INSTRUCTION(StoreCodeEntry, "store-code-entry")
1795  DECLARE_HYDROGEN_ACCESSOR(StoreCodeEntry)
1796 };
1797 
1798 
1799 class LInnerAllocatedObject FINAL: public LTemplateInstruction<1, 2, 0> {
1800  public:
1801  LInnerAllocatedObject(LOperand* base_object, LOperand* offset) {
1802  inputs_[0] = base_object;
1803  inputs_[1] = offset;
1804  }
1805 
1806  LOperand* base_object() const { return inputs_[0]; }
1807  LOperand* offset() const { return inputs_[1]; }
1808 
1809  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
1810 
1811  DECLARE_CONCRETE_INSTRUCTION(InnerAllocatedObject, "inner-allocated-object")
1812 };
1813 
1814 
1815 class LThisFunction FINAL : public LTemplateInstruction<1, 0, 0> {
1816  public:
1817  DECLARE_CONCRETE_INSTRUCTION(ThisFunction, "this-function")
1818  DECLARE_HYDROGEN_ACCESSOR(ThisFunction)
1819 };
1820 
1821 
1822 class LContext FINAL : public LTemplateInstruction<1, 0, 0> {
1823  public:
1826 };
1827 
1828 
1829 class LDeclareGlobals FINAL : public LTemplateInstruction<0, 1, 0> {
1830  public:
1831  explicit LDeclareGlobals(LOperand* context) {
1832  inputs_[0] = context;
1833  }
1834 
1835  LOperand* context() { return inputs_[0]; }
1836 
1837  DECLARE_CONCRETE_INSTRUCTION(DeclareGlobals, "declare-globals")
1839 };
1840 
1841 
1842 class LCallJSFunction FINAL : public LTemplateInstruction<1, 1, 0> {
1843  public:
1844  explicit LCallJSFunction(LOperand* function) {
1845  inputs_[0] = function;
1846  }
1847 
1848  LOperand* function() { return inputs_[0]; }
1849 
1850  DECLARE_CONCRETE_INSTRUCTION(CallJSFunction, "call-js-function")
1851  DECLARE_HYDROGEN_ACCESSOR(CallJSFunction)
1852 
1853  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
1854 
1855  int arity() const { return hydrogen()->argument_count() - 1; }
1856 };
1857 
1858 
1859 class LCallWithDescriptor FINAL : public LTemplateResultInstruction<1> {
1860  public:
1862  const ZoneList<LOperand*>& operands, Zone* zone)
1863  : descriptor_(descriptor),
1864  inputs_(descriptor.GetRegisterParameterCount() + 1, zone) {
1865  DCHECK(descriptor.GetRegisterParameterCount() + 1 == operands.length());
1866  inputs_.AddAll(operands, zone);
1867  }
1868 
1869  LOperand* target() const { return inputs_[0]; }
1870 
1871  const CallInterfaceDescriptor descriptor() { return descriptor_; }
1872 
1873  private:
1874  DECLARE_CONCRETE_INSTRUCTION(CallWithDescriptor, "call-with-descriptor")
1875  DECLARE_HYDROGEN_ACCESSOR(CallWithDescriptor)
1876 
1877  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
1878 
1879  int arity() const { return hydrogen()->argument_count() - 1; }
1880 
1881  CallInterfaceDescriptor descriptor_;
1882  ZoneList<LOperand*> inputs_;
1883 
1884  // Iterator support.
1885  virtual int InputCount() FINAL OVERRIDE { return inputs_.length(); }
1886  virtual LOperand* InputAt(int i) FINAL OVERRIDE { return inputs_[i]; }
1887 
1888  virtual int TempCount() FINAL OVERRIDE { return 0; }
1889  virtual LOperand* TempAt(int i) FINAL OVERRIDE { return NULL; }
1890 };
1891 
1892 
1893 
1894 class LInvokeFunction FINAL : public LTemplateInstruction<1, 2, 0> {
1895  public:
1896  LInvokeFunction(LOperand* context, LOperand* function) {
1897  inputs_[0] = context;
1898  inputs_[1] = function;
1899  }
1900 
1901  LOperand* context() { return inputs_[0]; }
1902  LOperand* function() { return inputs_[1]; }
1903 
1904  DECLARE_CONCRETE_INSTRUCTION(InvokeFunction, "invoke-function")
1905  DECLARE_HYDROGEN_ACCESSOR(InvokeFunction)
1906 
1907  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
1908 
1909  int arity() const { return hydrogen()->argument_count() - 1; }
1910 };
1911 
1912 
1913 class LCallFunction FINAL : public LTemplateInstruction<1, 2, 0> {
1914  public:
1915  LCallFunction(LOperand* context, LOperand* function) {
1916  inputs_[0] = context;
1917  inputs_[1] = function;
1918  }
1919 
1920  LOperand* context() { return inputs_[0]; }
1921  LOperand* function() { return inputs_[1]; }
1922 
1923  DECLARE_CONCRETE_INSTRUCTION(CallFunction, "call-function")
1924  DECLARE_HYDROGEN_ACCESSOR(CallFunction)
1925 
1926  int arity() const { return hydrogen()->argument_count() - 1; }
1927 };
1928 
1929 
1930 class LCallNew FINAL : public LTemplateInstruction<1, 2, 0> {
1931  public:
1932  LCallNew(LOperand* context, LOperand* constructor) {
1933  inputs_[0] = context;
1934  inputs_[1] = constructor;
1935  }
1936 
1937  LOperand* context() { return inputs_[0]; }
1938  LOperand* constructor() { return inputs_[1]; }
1939 
1940  DECLARE_CONCRETE_INSTRUCTION(CallNew, "call-new")
1941  DECLARE_HYDROGEN_ACCESSOR(CallNew)
1942 
1943  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
1944 
1945  int arity() const { return hydrogen()->argument_count() - 1; }
1946 };
1947 
1948 
1949 class LCallNewArray FINAL : public LTemplateInstruction<1, 2, 0> {
1950  public:
1951  LCallNewArray(LOperand* context, LOperand* constructor) {
1952  inputs_[0] = context;
1953  inputs_[1] = constructor;
1954  }
1955 
1956  LOperand* context() { return inputs_[0]; }
1957  LOperand* constructor() { return inputs_[1]; }
1958 
1959  DECLARE_CONCRETE_INSTRUCTION(CallNewArray, "call-new-array")
1960  DECLARE_HYDROGEN_ACCESSOR(CallNewArray)
1961 
1962  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
1963 
1964  int arity() const { return hydrogen()->argument_count() - 1; }
1965 };
1966 
1967 
1968 class LCallRuntime FINAL : public LTemplateInstruction<1, 1, 0> {
1969  public:
1970  explicit LCallRuntime(LOperand* context) {
1971  inputs_[0] = context;
1972  }
1973 
1974  LOperand* context() { return inputs_[0]; }
1975 
1976  DECLARE_CONCRETE_INSTRUCTION(CallRuntime, "call-runtime")
1977  DECLARE_HYDROGEN_ACCESSOR(CallRuntime)
1978 
1979  virtual bool ClobbersDoubleRegisters(Isolate* isolate) const OVERRIDE {
1980  return save_doubles() == kDontSaveFPRegs;
1981  }
1982 
1983  const Runtime::Function* function() const { return hydrogen()->function(); }
1984  int arity() const { return hydrogen()->argument_count(); }
1985  SaveFPRegsMode save_doubles() const { return hydrogen()->save_doubles(); }
1986 };
1987 
1988 
1989 class LInteger32ToDouble FINAL : public LTemplateInstruction<1, 1, 0> {
1990  public:
1991  explicit LInteger32ToDouble(LOperand* value) {
1992  inputs_[0] = value;
1993  }
1994 
1995  LOperand* value() { return inputs_[0]; }
1996 
1997  DECLARE_CONCRETE_INSTRUCTION(Integer32ToDouble, "int32-to-double")
1998 };
1999 
2000 
2001 class LUint32ToDouble FINAL : public LTemplateInstruction<1, 1, 0> {
2002  public:
2003  explicit LUint32ToDouble(LOperand* value) {
2004  inputs_[0] = value;
2005  }
2006 
2007  LOperand* value() { return inputs_[0]; }
2008 
2009  DECLARE_CONCRETE_INSTRUCTION(Uint32ToDouble, "uint32-to-double")
2010 };
2011 
2012 
2013 class LNumberTagU FINAL : public LTemplateInstruction<1, 1, 2> {
2014  public:
2015  LNumberTagU(LOperand* value, LOperand* temp1, LOperand* temp2) {
2016  inputs_[0] = value;
2017  temps_[0] = temp1;
2018  temps_[1] = temp2;
2019  }
2020 
2021  LOperand* value() { return inputs_[0]; }
2022  LOperand* temp1() { return temps_[0]; }
2023  LOperand* temp2() { return temps_[1]; }
2024 
2025  DECLARE_CONCRETE_INSTRUCTION(NumberTagU, "number-tag-u")
2026 };
2027 
2028 
2029 class LNumberTagD FINAL : public LTemplateInstruction<1, 1, 2> {
2030  public:
2031  LNumberTagD(LOperand* value, LOperand* temp, LOperand* temp2) {
2032  inputs_[0] = value;
2033  temps_[0] = temp;
2034  temps_[1] = temp2;
2035  }
2036 
2037  LOperand* value() { return inputs_[0]; }
2038  LOperand* temp() { return temps_[0]; }
2039  LOperand* temp2() { return temps_[1]; }
2040 
2041  DECLARE_CONCRETE_INSTRUCTION(NumberTagD, "number-tag-d")
2043 };
2044 
2045 
2046 class LDoubleToSmi FINAL : public LTemplateInstruction<1, 1, 0> {
2047  public:
2048  explicit LDoubleToSmi(LOperand* value) {
2049  inputs_[0] = value;
2050  }
2051 
2052  LOperand* value() { return inputs_[0]; }
2053 
2054  DECLARE_CONCRETE_INSTRUCTION(DoubleToSmi, "double-to-smi")
2055  DECLARE_HYDROGEN_ACCESSOR(UnaryOperation)
2056 
2057  bool truncating() { return hydrogen()->CanTruncateToInt32(); }
2058 };
2059 
2060 
2061 // Sometimes truncating conversion from a tagged value to an int32.
2062 class LDoubleToI FINAL : public LTemplateInstruction<1, 1, 0> {
2063  public:
2064  explicit LDoubleToI(LOperand* value) {
2065  inputs_[0] = value;
2066  }
2067 
2068  LOperand* value() { return inputs_[0]; }
2069 
2070  DECLARE_CONCRETE_INSTRUCTION(DoubleToI, "double-to-i")
2071  DECLARE_HYDROGEN_ACCESSOR(UnaryOperation)
2072 
2073  bool truncating() { return hydrogen()->CanTruncateToInt32(); }
2074 };
2075 
2076 
2077 // Truncating conversion from a tagged value to an int32.
2078 class LTaggedToI FINAL : public LTemplateInstruction<1, 1, 2> {
2079  public:
2081  LOperand* temp,
2082  LOperand* temp2) {
2083  inputs_[0] = value;
2084  temps_[0] = temp;
2085  temps_[1] = temp2;
2086  }
2087 
2088  LOperand* value() { return inputs_[0]; }
2089  LOperand* temp() { return temps_[0]; }
2090  LOperand* temp2() { return temps_[1]; }
2091 
2092  DECLARE_CONCRETE_INSTRUCTION(TaggedToI, "tagged-to-i")
2094 
2095  bool truncating() { return hydrogen()->CanTruncateToInt32(); }
2096 };
2097 
2098 
2099 class LSmiTag FINAL : public LTemplateInstruction<1, 1, 0> {
2100  public:
2101  explicit LSmiTag(LOperand* value) {
2102  inputs_[0] = value;
2103  }
2104 
2105  LOperand* value() { return inputs_[0]; }
2106 
2107  DECLARE_CONCRETE_INSTRUCTION(SmiTag, "smi-tag")
2109 };
2110 
2111 
2112 class LNumberUntagD FINAL : public LTemplateInstruction<1, 1, 0> {
2113  public:
2114  explicit LNumberUntagD(LOperand* value) {
2115  inputs_[0] = value;
2116  }
2117 
2118  LOperand* value() { return inputs_[0]; }
2119 
2120  DECLARE_CONCRETE_INSTRUCTION(NumberUntagD, "double-untag")
2122 };
2123 
2124 
2125 class LSmiUntag FINAL : public LTemplateInstruction<1, 1, 0> {
2126  public:
2127  LSmiUntag(LOperand* value, bool needs_check)
2128  : needs_check_(needs_check) {
2129  inputs_[0] = value;
2130  }
2131 
2132  LOperand* value() { return inputs_[0]; }
2133  bool needs_check() const { return needs_check_; }
2134 
2135  DECLARE_CONCRETE_INSTRUCTION(SmiUntag, "smi-untag")
2136 
2137  private:
2138  bool needs_check_;
2139 };
2140 
2141 
2142 class LStoreNamedField FINAL : public LTemplateInstruction<0, 2, 1> {
2143  public:
2144  LStoreNamedField(LOperand* object, LOperand* value, LOperand* temp) {
2145  inputs_[0] = object;
2146  inputs_[1] = value;
2147  temps_[0] = temp;
2148  }
2149 
2150  LOperand* object() { return inputs_[0]; }
2151  LOperand* value() { return inputs_[1]; }
2152  LOperand* temp() { return temps_[0]; }
2153 
2154  DECLARE_CONCRETE_INSTRUCTION(StoreNamedField, "store-named-field")
2155  DECLARE_HYDROGEN_ACCESSOR(StoreNamedField)
2156 
2157  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
2158 
2159  Representation representation() const {
2160  return hydrogen()->field_representation();
2161  }
2162 };
2163 
2164 
2165 class LStoreNamedGeneric FINAL : public LTemplateInstruction<0, 3, 0> {
2166  public:
2167  LStoreNamedGeneric(LOperand* context, LOperand* object, LOperand* value) {
2168  inputs_[0] = context;
2169  inputs_[1] = object;
2170  inputs_[2] = value;
2171  }
2172 
2173  LOperand* context() { return inputs_[0]; }
2174  LOperand* object() { return inputs_[1]; }
2175  LOperand* value() { return inputs_[2]; }
2176 
2177  DECLARE_CONCRETE_INSTRUCTION(StoreNamedGeneric, "store-named-generic")
2178  DECLARE_HYDROGEN_ACCESSOR(StoreNamedGeneric)
2179 
2180  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
2181 
2182  Handle<Object> name() const { return hydrogen()->name(); }
2183  StrictMode strict_mode() { return hydrogen()->strict_mode(); }
2184 };
2185 
2186 
2187 class LStoreKeyed FINAL : public LTemplateInstruction<0, 3, 0> {
2188  public:
2189  LStoreKeyed(LOperand* object, LOperand* key, LOperand* value) {
2190  inputs_[0] = object;
2191  inputs_[1] = key;
2192  inputs_[2] = value;
2193  }
2194 
2195  bool is_external() const { return hydrogen()->is_external(); }
2196  bool is_fixed_typed_array() const {
2197  return hydrogen()->is_fixed_typed_array();
2198  }
2199  bool is_typed_elements() const {
2200  return is_external() || is_fixed_typed_array();
2201  }
2202  LOperand* elements() { return inputs_[0]; }
2203  LOperand* key() { return inputs_[1]; }
2204  LOperand* value() { return inputs_[2]; }
2206  return hydrogen()->elements_kind();
2207  }
2208 
2209  DECLARE_CONCRETE_INSTRUCTION(StoreKeyed, "store-keyed")
2210  DECLARE_HYDROGEN_ACCESSOR(StoreKeyed)
2211 
2212  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
2213  bool NeedsCanonicalization() { return hydrogen()->NeedsCanonicalization(); }
2214  uint32_t base_offset() const { return hydrogen()->base_offset(); }
2215 };
2216 
2217 
2218 class LStoreKeyedGeneric FINAL : public LTemplateInstruction<0, 4, 0> {
2219  public:
2221  LOperand* obj,
2222  LOperand* key,
2223  LOperand* value) {
2224  inputs_[0] = context;
2225  inputs_[1] = obj;
2226  inputs_[2] = key;
2227  inputs_[3] = value;
2228  }
2229 
2230  LOperand* context() { return inputs_[0]; }
2231  LOperand* object() { return inputs_[1]; }
2232  LOperand* key() { return inputs_[2]; }
2233  LOperand* value() { return inputs_[3]; }
2234 
2235  DECLARE_CONCRETE_INSTRUCTION(StoreKeyedGeneric, "store-keyed-generic")
2236  DECLARE_HYDROGEN_ACCESSOR(StoreKeyedGeneric)
2237 
2238  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
2239 
2240  StrictMode strict_mode() { return hydrogen()->strict_mode(); }
2241 };
2242 
2243 
2244 class LTransitionElementsKind FINAL : public LTemplateInstruction<0, 2, 1> {
2245  public:
2247  LOperand* context,
2248  LOperand* new_map_temp) {
2249  inputs_[0] = object;
2250  inputs_[1] = context;
2251  temps_[0] = new_map_temp;
2252  }
2253 
2254  LOperand* context() { return inputs_[1]; }
2255  LOperand* object() { return inputs_[0]; }
2256  LOperand* new_map_temp() { return temps_[0]; }
2257 
2258  DECLARE_CONCRETE_INSTRUCTION(TransitionElementsKind,
2259  "transition-elements-kind")
2260  DECLARE_HYDROGEN_ACCESSOR(TransitionElementsKind)
2261 
2262  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
2263 
2264  Handle<Map> original_map() { return hydrogen()->original_map().handle(); }
2266  return hydrogen()->transitioned_map().handle();
2267  }
2268  ElementsKind from_kind() { return hydrogen()->from_kind(); }
2269  ElementsKind to_kind() { return hydrogen()->to_kind(); }
2270 };
2271 
2272 
2273 class LTrapAllocationMemento FINAL : public LTemplateInstruction<0, 1, 1> {
2274  public:
2276  LOperand* temp) {
2277  inputs_[0] = object;
2278  temps_[0] = temp;
2279  }
2280 
2281  LOperand* object() { return inputs_[0]; }
2282  LOperand* temp() { return temps_[0]; }
2283 
2284  DECLARE_CONCRETE_INSTRUCTION(TrapAllocationMemento,
2285  "trap-allocation-memento")
2286 };
2287 
2288 
2289 class LStringAdd FINAL : public LTemplateInstruction<1, 3, 0> {
2290  public:
2291  LStringAdd(LOperand* context, LOperand* left, LOperand* right) {
2292  inputs_[0] = context;
2293  inputs_[1] = left;
2294  inputs_[2] = right;
2295  }
2296 
2297  LOperand* context() { return inputs_[0]; }
2298  LOperand* left() { return inputs_[1]; }
2299  LOperand* right() { return inputs_[2]; }
2300 
2301  DECLARE_CONCRETE_INSTRUCTION(StringAdd, "string-add")
2302  DECLARE_HYDROGEN_ACCESSOR(StringAdd)
2303 };
2304 
2305 
2306 
2307 class LStringCharCodeAt FINAL : public LTemplateInstruction<1, 3, 0> {
2308  public:
2309  LStringCharCodeAt(LOperand* context, LOperand* string, LOperand* index) {
2310  inputs_[0] = context;
2311  inputs_[1] = string;
2312  inputs_[2] = index;
2313  }
2314 
2315  LOperand* context() { return inputs_[0]; }
2316  LOperand* string() { return inputs_[1]; }
2317  LOperand* index() { return inputs_[2]; }
2318 
2319  DECLARE_CONCRETE_INSTRUCTION(StringCharCodeAt, "string-char-code-at")
2320  DECLARE_HYDROGEN_ACCESSOR(StringCharCodeAt)
2321 };
2322 
2323 
2324 class LStringCharFromCode FINAL : public LTemplateInstruction<1, 2, 0> {
2325  public:
2326  explicit LStringCharFromCode(LOperand* context, LOperand* char_code) {
2327  inputs_[0] = context;
2328  inputs_[1] = char_code;
2329  }
2330 
2331  LOperand* context() { return inputs_[0]; }
2332  LOperand* char_code() { return inputs_[1]; }
2333 
2334  DECLARE_CONCRETE_INSTRUCTION(StringCharFromCode, "string-char-from-code")
2335  DECLARE_HYDROGEN_ACCESSOR(StringCharFromCode)
2336 };
2337 
2338 
2339 class LCheckValue FINAL : public LTemplateInstruction<0, 1, 0> {
2340  public:
2341  explicit LCheckValue(LOperand* value) {
2342  inputs_[0] = value;
2343  }
2344 
2345  LOperand* value() { return inputs_[0]; }
2346 
2347  DECLARE_CONCRETE_INSTRUCTION(CheckValue, "check-value")
2348  DECLARE_HYDROGEN_ACCESSOR(CheckValue)
2349 };
2350 
2351 
2352 class LCheckInstanceType FINAL : public LTemplateInstruction<0, 1, 0> {
2353  public:
2354  explicit LCheckInstanceType(LOperand* value) {
2355  inputs_[0] = value;
2356  }
2357 
2358  LOperand* value() { return inputs_[0]; }
2359 
2360  DECLARE_CONCRETE_INSTRUCTION(CheckInstanceType, "check-instance-type")
2361  DECLARE_HYDROGEN_ACCESSOR(CheckInstanceType)
2362 };
2363 
2364 
2365 class LCheckMaps FINAL : public LTemplateInstruction<0, 1, 0> {
2366  public:
2367  explicit LCheckMaps(LOperand* value = NULL) {
2368  inputs_[0] = value;
2369  }
2370 
2371  LOperand* value() { return inputs_[0]; }
2372 
2373  DECLARE_CONCRETE_INSTRUCTION(CheckMaps, "check-maps")
2374  DECLARE_HYDROGEN_ACCESSOR(CheckMaps)
2375 };
2376 
2377 
2378 class LCheckSmi FINAL : public LTemplateInstruction<1, 1, 0> {
2379  public:
2380  explicit LCheckSmi(LOperand* value) {
2381  inputs_[0] = value;
2382  }
2383 
2384  LOperand* value() { return inputs_[0]; }
2385 
2386  DECLARE_CONCRETE_INSTRUCTION(CheckSmi, "check-smi")
2387 };
2388 
2389 
2390 class LCheckNonSmi FINAL : public LTemplateInstruction<0, 1, 0> {
2391  public:
2392  explicit LCheckNonSmi(LOperand* value) {
2393  inputs_[0] = value;
2394  }
2395 
2396  LOperand* value() { return inputs_[0]; }
2397 
2398  DECLARE_CONCRETE_INSTRUCTION(CheckNonSmi, "check-non-smi")
2399  DECLARE_HYDROGEN_ACCESSOR(CheckHeapObject)
2400 };
2401 
2402 
2403 class LClampDToUint8 FINAL : public LTemplateInstruction<1, 1, 1> {
2404  public:
2405  LClampDToUint8(LOperand* unclamped, LOperand* temp) {
2406  inputs_[0] = unclamped;
2407  temps_[0] = temp;
2408  }
2409 
2410  LOperand* unclamped() { return inputs_[0]; }
2411  LOperand* temp() { return temps_[0]; }
2412 
2413  DECLARE_CONCRETE_INSTRUCTION(ClampDToUint8, "clamp-d-to-uint8")
2414 };
2415 
2416 
2417 class LClampIToUint8 FINAL : public LTemplateInstruction<1, 1, 0> {
2418  public:
2419  explicit LClampIToUint8(LOperand* unclamped) {
2420  inputs_[0] = unclamped;
2421  }
2422 
2423  LOperand* unclamped() { return inputs_[0]; }
2424 
2425  DECLARE_CONCRETE_INSTRUCTION(ClampIToUint8, "clamp-i-to-uint8")
2426 };
2427 
2428 
2429 class LClampTToUint8 FINAL : public LTemplateInstruction<1, 1, 1> {
2430  public:
2431  LClampTToUint8(LOperand* unclamped, LOperand* temp) {
2432  inputs_[0] = unclamped;
2433  temps_[0] = temp;
2434  }
2435 
2436  LOperand* unclamped() { return inputs_[0]; }
2437  LOperand* temp() { return temps_[0]; }
2438 
2439  DECLARE_CONCRETE_INSTRUCTION(ClampTToUint8, "clamp-t-to-uint8")
2440 };
2441 
2442 
2443 class LDoubleBits FINAL : public LTemplateInstruction<1, 1, 0> {
2444  public:
2445  explicit LDoubleBits(LOperand* value) {
2446  inputs_[0] = value;
2447  }
2448 
2449  LOperand* value() { return inputs_[0]; }
2450 
2451  DECLARE_CONCRETE_INSTRUCTION(DoubleBits, "double-bits")
2452  DECLARE_HYDROGEN_ACCESSOR(DoubleBits)
2453 };
2454 
2455 
2456 class LConstructDouble FINAL : public LTemplateInstruction<1, 2, 0> {
2457  public:
2459  inputs_[0] = hi;
2460  inputs_[1] = lo;
2461  }
2462 
2463  LOperand* hi() { return inputs_[0]; }
2464  LOperand* lo() { return inputs_[1]; }
2465 
2466  DECLARE_CONCRETE_INSTRUCTION(ConstructDouble, "construct-double")
2467 };
2468 
2469 
2470 class LAllocate FINAL : public LTemplateInstruction<1, 2, 2> {
2471  public:
2473  LOperand* size,
2474  LOperand* temp1,
2475  LOperand* temp2) {
2476  inputs_[0] = context;
2477  inputs_[1] = size;
2478  temps_[0] = temp1;
2479  temps_[1] = temp2;
2480  }
2481 
2482  LOperand* context() { return inputs_[0]; }
2483  LOperand* size() { return inputs_[1]; }
2484  LOperand* temp1() { return temps_[0]; }
2485  LOperand* temp2() { return temps_[1]; }
2486 
2487  DECLARE_CONCRETE_INSTRUCTION(Allocate, "allocate")
2488  DECLARE_HYDROGEN_ACCESSOR(Allocate)
2489 };
2490 
2491 
2492 class LRegExpLiteral FINAL : public LTemplateInstruction<1, 1, 0> {
2493  public:
2494  explicit LRegExpLiteral(LOperand* context) {
2495  inputs_[0] = context;
2496  }
2497 
2498  LOperand* context() { return inputs_[0]; }
2499 
2500  DECLARE_CONCRETE_INSTRUCTION(RegExpLiteral, "regexp-literal")
2501  DECLARE_HYDROGEN_ACCESSOR(RegExpLiteral)
2502 };
2503 
2504 
2505 class LFunctionLiteral FINAL : public LTemplateInstruction<1, 1, 0> {
2506  public:
2507  explicit LFunctionLiteral(LOperand* context) {
2508  inputs_[0] = context;
2509  }
2510 
2511  LOperand* context() { return inputs_[0]; }
2512 
2513  DECLARE_CONCRETE_INSTRUCTION(FunctionLiteral, "function-literal")
2514  DECLARE_HYDROGEN_ACCESSOR(FunctionLiteral)
2515 };
2516 
2517 
2518 class LToFastProperties FINAL : public LTemplateInstruction<1, 1, 0> {
2519  public:
2520  explicit LToFastProperties(LOperand* value) {
2521  inputs_[0] = value;
2522  }
2523 
2524  LOperand* value() { return inputs_[0]; }
2525 
2526  DECLARE_CONCRETE_INSTRUCTION(ToFastProperties, "to-fast-properties")
2527  DECLARE_HYDROGEN_ACCESSOR(ToFastProperties)
2528 };
2529 
2530 
2531 class LTypeof FINAL : public LTemplateInstruction<1, 2, 0> {
2532  public:
2533  LTypeof(LOperand* context, LOperand* value) {
2534  inputs_[0] = context;
2535  inputs_[1] = value;
2536  }
2537 
2538  LOperand* context() { return inputs_[0]; }
2539  LOperand* value() { return inputs_[1]; }
2540 
2541  DECLARE_CONCRETE_INSTRUCTION(Typeof, "typeof")
2542 };
2543 
2544 
2545 class LTypeofIsAndBranch FINAL : public LControlInstruction<1, 0> {
2546  public:
2547  explicit LTypeofIsAndBranch(LOperand* value) {
2548  inputs_[0] = value;
2549  }
2550 
2551  LOperand* value() { return inputs_[0]; }
2552 
2553  DECLARE_CONCRETE_INSTRUCTION(TypeofIsAndBranch, "typeof-is-and-branch")
2554  DECLARE_HYDROGEN_ACCESSOR(TypeofIsAndBranch)
2555 
2556  Handle<String> type_literal() { return hydrogen()->type_literal(); }
2557 
2558  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
2559 };
2560 
2561 
2562 class LIsConstructCallAndBranch FINAL : public LControlInstruction<0, 1> {
2563  public:
2565  temps_[0] = temp;
2566  }
2567 
2568  LOperand* temp() { return temps_[0]; }
2569 
2570  DECLARE_CONCRETE_INSTRUCTION(IsConstructCallAndBranch,
2571  "is-construct-call-and-branch")
2572 };
2573 
2574 
2575 class LOsrEntry FINAL : public LTemplateInstruction<0, 0, 0> {
2576  public:
2578 
2579  virtual bool HasInterestingComment(LCodeGen* gen) const OVERRIDE {
2580  return false;
2581  }
2582  DECLARE_CONCRETE_INSTRUCTION(OsrEntry, "osr-entry")
2583 };
2584 
2585 
2586 class LStackCheck FINAL : public LTemplateInstruction<0, 1, 0> {
2587  public:
2588  explicit LStackCheck(LOperand* context) {
2589  inputs_[0] = context;
2590  }
2591 
2592  LOperand* context() { return inputs_[0]; }
2593 
2594  DECLARE_CONCRETE_INSTRUCTION(StackCheck, "stack-check")
2595  DECLARE_HYDROGEN_ACCESSOR(StackCheck)
2596 
2597  Label* done_label() { return &done_label_; }
2598 
2599  private:
2600  Label done_label_;
2601 };
2602 
2603 
2604 class LForInPrepareMap FINAL : public LTemplateInstruction<1, 2, 0> {
2605  public:
2606  LForInPrepareMap(LOperand* context, LOperand* object) {
2607  inputs_[0] = context;
2608  inputs_[1] = object;
2609  }
2610 
2611  LOperand* context() { return inputs_[0]; }
2612  LOperand* object() { return inputs_[1]; }
2613 
2614  DECLARE_CONCRETE_INSTRUCTION(ForInPrepareMap, "for-in-prepare-map")
2615 };
2616 
2617 
2618 class LForInCacheArray FINAL : public LTemplateInstruction<1, 1, 0> {
2619  public:
2621  inputs_[0] = map;
2622  }
2623 
2624  LOperand* map() { return inputs_[0]; }
2625 
2626  DECLARE_CONCRETE_INSTRUCTION(ForInCacheArray, "for-in-cache-array")
2627 
2628  int idx() {
2629  return HForInCacheArray::cast(this->hydrogen_value())->idx();
2630  }
2631 };
2632 
2633 
2634 class LCheckMapValue FINAL : public LTemplateInstruction<0, 2, 0> {
2635  public:
2637  inputs_[0] = value;
2638  inputs_[1] = map;
2639  }
2640 
2641  LOperand* value() { return inputs_[0]; }
2642  LOperand* map() { return inputs_[1]; }
2643 
2644  DECLARE_CONCRETE_INSTRUCTION(CheckMapValue, "check-map-value")
2645 };
2646 
2647 
2648 class LLoadFieldByIndex FINAL : public LTemplateInstruction<1, 2, 0> {
2649  public:
2651  inputs_[0] = object;
2652  inputs_[1] = index;
2653  }
2654 
2655  LOperand* object() { return inputs_[0]; }
2656  LOperand* index() { return inputs_[1]; }
2657 
2658  DECLARE_CONCRETE_INSTRUCTION(LoadFieldByIndex, "load-field-by-index")
2659 };
2660 
2661 
2662 class LStoreFrameContext: public LTemplateInstruction<0, 1, 0> {
2663  public:
2664  explicit LStoreFrameContext(LOperand* context) {
2665  inputs_[0] = context;
2666  }
2667 
2668  LOperand* context() { return inputs_[0]; }
2669 
2670  DECLARE_CONCRETE_INSTRUCTION(StoreFrameContext, "store-frame-context")
2671 };
2672 
2673 
2674 class LAllocateBlockContext: public LTemplateInstruction<1, 2, 0> {
2675  public:
2676  LAllocateBlockContext(LOperand* context, LOperand* function) {
2677  inputs_[0] = context;
2678  inputs_[1] = function;
2679  }
2680 
2681  LOperand* context() { return inputs_[0]; }
2682  LOperand* function() { return inputs_[1]; }
2683 
2684  Handle<ScopeInfo> scope_info() { return hydrogen()->scope_info(); }
2685 
2686  DECLARE_CONCRETE_INSTRUCTION(AllocateBlockContext, "allocate-block-context")
2687  DECLARE_HYDROGEN_ACCESSOR(AllocateBlockContext)
2688 };
2689 
2690 
2691 class LChunkBuilder;
2692 class LPlatformChunk FINAL : public LChunk {
2693  public:
2694  LPlatformChunk(CompilationInfo* info, HGraph* graph)
2695  : LChunk(info, graph) { }
2696 
2699 };
2700 
2701 
2702 class LChunkBuilder FINAL : public LChunkBuilderBase {
2703  public:
2704  LChunkBuilder(CompilationInfo* info, HGraph* graph, LAllocator* allocator)
2705  : LChunkBuilderBase(info, graph),
2706  current_instruction_(NULL),
2707  current_block_(NULL),
2708  next_block_(NULL),
2709  allocator_(allocator) {}
2710 
2711  // Build the sequence for the graph.
2712  LPlatformChunk* Build();
2713 
2714  // Declare methods that deal with the individual node types.
2715 #define DECLARE_DO(type) LInstruction* Do##type(H##type* node);
2717 #undef DECLARE_DO
2718 
2719  LInstruction* DoMultiplyAdd(HMul* mul, HValue* addend);
2720 
2721  static bool HasMagicNumberForDivisor(int32_t divisor);
2722 
2723  LInstruction* DoMathFloor(HUnaryMathOperation* instr);
2724  LInstruction* DoMathRound(HUnaryMathOperation* instr);
2725  LInstruction* DoMathFround(HUnaryMathOperation* instr);
2726  LInstruction* DoMathAbs(HUnaryMathOperation* instr);
2727  LInstruction* DoMathLog(HUnaryMathOperation* instr);
2728  LInstruction* DoMathExp(HUnaryMathOperation* instr);
2729  LInstruction* DoMathSqrt(HUnaryMathOperation* instr);
2730  LInstruction* DoMathPowHalf(HUnaryMathOperation* instr);
2731  LInstruction* DoMathClz32(HUnaryMathOperation* instr);
2734  LInstruction* DoDivI(HDiv* instr);
2737  LInstruction* DoModI(HMod* instr);
2738  LInstruction* DoFlooringDivByPowerOf2I(HMathFloorOfDiv* instr);
2739  LInstruction* DoFlooringDivByConstI(HMathFloorOfDiv* instr);
2740  LInstruction* DoFlooringDivI(HMathFloorOfDiv* instr);
2741 
2742  private:
2743  // Methods for getting operands for Use / Define / Temp.
2746 
2747  // Methods for setting up define-use relationships.
2751  DoubleRegister fixed_register);
2752 
2753  // A value that is guaranteed to be allocated to a register.
2754  // Operand created by UseRegister is guaranteed to be live until the end of
2755  // instruction. This means that register allocator will not reuse it's
2756  // register for any other operand inside instruction.
2757  // Operand created by UseRegisterAtStart is guaranteed to be live only at
2758  // instruction start. Register allocator is free to assign the same register
2759  // to some other operand used inside instruction (i.e. temporary or
2760  // output).
2763 
2764  // An input operand in a register that may be trashed.
2766 
2767  // An input operand in a register or stack slot.
2770 
2771  // An input operand in a register, stack slot or a constant operand.
2774 
2775  // An input operand in a register or a constant operand.
2778 
2779  // An input operand in a constant operand.
2781 
2782  // An input operand in register, stack slot or a constant operand.
2783  // Will not be moved to a register even if one is freely available.
2785 
2786  // Temporary operand that must be in a register.
2791 
2792  // Methods for setting up define-use relationships.
2793  // Return the same instruction that they are passed.
2795  LUnallocated* result);
2798  int index);
2801  Register reg);
2803  DoubleRegister reg);
2806 
2807  enum CanDeoptimize { CAN_DEOPTIMIZE_EAGERLY, CANNOT_DEOPTIMIZE_EAGERLY };
2808 
2809  // By default we assume that instruction sequences generated for calls
2810  // cannot deoptimize eagerly and we do not attach environment to this
2811  // instruction.
2813  LInstruction* instr,
2814  HInstruction* hinstr,
2815  CanDeoptimize can_deoptimize = CANNOT_DEOPTIMIZE_EAGERLY);
2816 
2818  void AddInstruction(LInstruction* instr, HInstruction* current);
2819 
2820  void DoBasicBlock(HBasicBlock* block, HBasicBlock* next_block);
2826  HBinaryOperation* instr);
2827 
2828  HInstruction* current_instruction_;
2829  HBasicBlock* current_block_;
2830  HBasicBlock* next_block_;
2831  LAllocator* allocator_;
2832 
2834 };
2835 
2836 #undef DECLARE_HYDROGEN_ACCESSOR
2837 #undef DECLARE_CONCRETE_INSTRUCTION
2838 
2839 } } // namespace v8::internal
2840 
2841 #endif // V8_MIPS_LITHIUM_MIPS_H_
A sandboxed execution context with its own set of built-in objects and functions.
Definition: v8.h:5443
The superclass of all JavaScript values and objects.
Definition: v8.h:1440
static U update(U previous, T value)
Definition: utils.h:223
static T decode(U value)
Definition: utils.h:228
Source to read snapshot and builtins files from.
Definition: lithium-arm.h:372
LInstructionGap(HBasicBlock *block)
LLoadFunctionPrototype(LOperand *function)
LCallJSFunction(LOperand *function)
LDivByConstI(LOperand *dividend, int32_t divisor)
LOperand * double_temp()
LSmiUntag(LOperand *value, bool needs_check)
LInstruction * DoDivByPowerOf2I(HDiv *instr)
LCheckSmi(LOperand *value)
LOperand * temp_vector()
LTypeofIsAndBranch(LOperand *value)
LBoundsCheck(LOperand *index, LOperand *length)
DECLARE_CONCRETE_INSTRUCTION(IsUndetectableAndBranch, "is-undetectable-and-branch") virtual void PrintDataTo(StringStream *stream) OVERRIDE
virtual LOperand * TempAt(int i) FINAL OVERRIDE
MUST_USE_RESULT LUnallocated * TempRegister()
LTrapAllocationMemento(LOperand *object, LOperand *temp)
LIsSmiAndBranch(LOperand *value)
LDivByPowerOf2I(LOperand *dividend, int32_t divisor)
LStoreKeyed(LOperand *object, LOperand *key, LOperand *value)
LOperand * unclamped()
LUint32ToDouble(LOperand *value)
LModByPowerOf2I(LOperand *dividend, int32_t divisor)
const CallInterfaceDescriptor descriptor()
LStringCharCodeAt(LOperand *context, LOperand *string, LOperand *index)
LInstruction * DoArithmeticT(Token::Value op, HBinaryOperation *instr)
LStoreNamedField(LOperand *object, LOperand *value, LOperand *temp)
LPower(LOperand *left, LOperand *right)
ElementsKind to_kind()
LStringCompareAndBranch(LOperand *context, LOperand *left, LOperand *right)
MUST_USE_RESULT LUnallocated * TempDoubleRegister()
LBranch(LOperand *value)
LInnerAllocatedObject(LOperand *base_object, LOperand *offset)
LCmpObjectEqAndBranch(LOperand *left, LOperand *right)
uint32_t base_offset() const
LInstruction * DoFlooringDivByPowerOf2I(HMathFloorOfDiv *instr)
virtual Opcode opcode() const OVERRIDE
LOperand * index() const
LStoreNamedGeneric(LOperand *context, LOperand *object, LOperand *value)
ElementsKind from_kind()
LMathClz32(LOperand *value)
LMathMinMax(LOperand *left, LOperand *right)
LConstructDouble(LOperand *hi, LOperand *lo)
LMathPowHalf(LOperand *value, LOperand *temp)
LShiftI(Token::Value op, LOperand *left, LOperand *right, bool can_deopt)
LLoadContextSlot(LOperand *context)
virtual void PrintDataTo(StringStream *stream) OVERRIDE
LInstruction * DefineSameAsFirst(LTemplateResultInstruction< 1 > *instr)
LBitI(LOperand *left, LOperand *right)
LDoubleBits(LOperand *value)
LSmiTag(LOperand *value)
LDeclareGlobals(LOperand *context)
LIsUndetectableAndBranch(LOperand *value, LOperand *temp)
virtual void CompileToNative(LCodeGen *generator) OVERRIDE
LWrapReceiver(LOperand *receiver, LOperand *function)
LNumberTagD(LOperand *value, LOperand *temp, LOperand *temp2)
LApplyArguments(LOperand *function, LOperand *receiver, LOperand *length, LOperand *elements)
LStringAdd(LOperand *context, LOperand *left, LOperand *right)
MUST_USE_RESULT LOperand * Use(HValue *value)
MUST_USE_RESULT LOperand * UseAtStart(HValue *value)
MUST_USE_RESULT LOperand * UseConstant(HValue *value)
LInstruction * DoBit(Token::Value op, HBitwiseBinaryOperation *instr)
bool has_constant_parameter_count()
MUST_USE_RESULT LOperand * UseOrConstantAtStart(HValue *value)
SaveFPRegsMode save_doubles() const
LInteger32ToDouble(LOperand *value)
virtual int TempCount() FINAL OVERRIDE
LForInCacheArray(LOperand *map)
LCmpT(LOperand *context, LOperand *left, LOperand *right)
LInstruction * DoMathAbs(HUnaryMathOperation *instr)
LLabel * replacement() const
LCompareMinusZeroAndBranch(LOperand *value, LOperand *temp)
LStoreContextSlot(LOperand *context, LOperand *value)
LMathExp(LOperand *value, LOperand *double_temp, LOperand *temp1, LOperand *temp2)
LCmpMapAndBranch(LOperand *value, LOperand *temp)
LDummyUse(LOperand *value)
LInstruction * DoMathExp(HUnaryMathOperation *instr)
MUST_USE_RESULT LOperand * UseTempRegister(HValue *value)
LInstruction * DefineFixedDouble(LTemplateResultInstruction< 1 > *instr, DoubleRegister reg)
DECLARE_CONCRETE_INSTRUCTION(HasInstanceTypeAndBranch, "has-instance-type-and-branch") virtual void PrintDataTo(StringStream *stream) OVERRIDE
LInstruction * DoModByPowerOf2I(HMod *instr)
LInstruction * AssignEnvironment(LInstruction *instr)
bool is_fixed_typed_array() const
LLoadNamedField(LOperand *object)
LUnallocated * ToUnallocated(DoubleRegister reg)
LDateField(LOperand *date, LOperand *temp, Smi *index)
LAddI(LOperand *left, LOperand *right)
LMathRound(LOperand *value, LOperand *temp)
LInstruction * Define(LTemplateResultInstruction< 1 > *instr, LUnallocated *result)
LDoubleToSmi(LOperand *value)
LCmpHoleAndBranch(LOperand *object)
LOperand * elements()
LInstruction * AssignPointerMap(LInstruction *instr)
LInstruction * DoMathFloor(HUnaryMathOperation *instr)
LIsStringAndBranch(LOperand *value, LOperand *temp)
LInstruction * DoMathRound(HUnaryMathOperation *instr)
LGoto(HBasicBlock *block)
LCallNew(LOperand *context, LOperand *constructor)
LStackCheck(LOperand *context)
LOperand * char_code()
LLoadFieldByIndex(LOperand *object, LOperand *index)
virtual LOperand * InputAt(int i) FINAL OVERRIDE
virtual bool IsControl() const OVERRIDE
void DoBasicBlock(HBasicBlock *block, HBasicBlock *next_block)
LClampTToUint8(LOperand *unclamped, LOperand *temp)
LArgumentsLength(LOperand *elements)
LModI(LOperand *left, LOperand *right)
LIsConstructCallAndBranch(LOperand *temp)
LMathFround(LOperand *value)
LLoadNamedGeneric(LOperand *context, LOperand *object, LOperand *vector)
MUST_USE_RESULT LOperand * UseFixedDouble(HValue *value, DoubleRegister fixed_register)
LCheckMapValue(LOperand *value, LOperand *map)
LOperand * receiver()
LArithmeticT(Token::Value op, LOperand *context, LOperand *left, LOperand *right)
LLoadKeyedGeneric(LOperand *context, LOperand *object, LOperand *key, LOperand *vector)
LGetCachedArrayIndex(LOperand *value)
int32_t divisor() const
LDoubleToI(LOperand *value)
LOperand * GetNextSpillSlot(RegisterKind kind)
LConstantOperand * constant_parameter_count()
LCallNewArray(LOperand *context, LOperand *constructor)
DECLARE_CONCRETE_INSTRUCTION(ClassOfTestAndBranch, "class-of-test-and-branch") virtual void PrintDataTo(StringStream *stream) OVERRIDE
LOperand * context()
virtual Opcode opcode() const FINAL
LOperand * dividend()
bool can_deopt() const
LOperand * new_map_temp()
LForInPrepareMap(LOperand *context, LOperand *object)
LMapEnumLength(LOperand *value)
LInstruction * DefineAsSpilled(LTemplateResultInstruction< 1 > *instr, int index)
LStoreCodeEntry(LOperand *function, LOperand *code_object)
Token::Value op() const
LOperand * offset() const
LSeqStringGetChar(LOperand *string, LOperand *index)
LInstruction * DoMultiplyAdd(HMul *mul, HValue *addend)
LClampDToUint8(LOperand *unclamped, LOperand *temp)
bool is_external() const
MUST_USE_RESULT LOperand * UseRegisterAtStart(HValue *value)
LInstruction * DoMathPowHalf(HUnaryMathOperation *instr)
LInvokeFunction(LOperand *context, LOperand *function)
LSubI(LOperand *left, LOperand *right)
LMathFloor(LOperand *value, LOperand *temp)
LCheckMaps(LOperand *value=NULL)
LInstruction * DoFlooringDivByConstI(HMathFloorOfDiv *instr)
LMulI(LOperand *left, LOperand *right)
bool is_typed_elements() const
LLabel(HBasicBlock *block)
bool HasReplacement() const
LInstruction * DoModByConstI(HMod *instr)
MUST_USE_RESULT LOperand * Use(HValue *value, LUnallocated *operand)
LCheckValue(LOperand *value)
LStringCharFromCode(LOperand *context, LOperand *char_code)
LInstruction * DoShift(Token::Value op, HBitwiseBinaryOperation *instr)
LCheckInstanceType(LOperand *value)
LInstruction * DoArithmeticD(Token::Value op, HArithmeticBinaryOperation *instr)
LStoreKeyedGeneric(LOperand *context, LOperand *obj, LOperand *key, LOperand *value)
LSeqStringSetChar(LOperand *context, LOperand *string, LOperand *index, LOperand *value)
virtual int InputCount() FINAL OVERRIDE
DISALLOW_COPY_AND_ASSIGN(LChunkBuilder)
LInstruction * DoMathClz32(HUnaryMathOperation *instr)
LInstruction * DoMathSqrt(HUnaryMathOperation *instr)
ElementsKind elements_kind() const
DECLARE_CONCRETE_INSTRUCTION(TransitionElementsKind, "transition-elements-kind") virtual void PrintDataTo(StringStream *stream) OVERRIDE
LCallWithDescriptor(CallInterfaceDescriptor descriptor, const ZoneList< LOperand * > &operands, Zone *zone)
LOperand * global_object()
LCallRuntime(LOperand *context)
LOperand * constructor()
StrictMode strict_mode()
LLoadGlobalGeneric(LOperand *context, LOperand *global_object, LOperand *vector)
LAllocate(LOperand *context, LOperand *size, LOperand *temp1, LOperand *temp2)
LPlatformChunk * Build()
MUST_USE_RESULT LOperand * UseFixed(HValue *value, Register fixed_register)
LOperand * base_object() const
LInstanceOfKnownGlobal(LOperand *context, LOperand *value, LOperand *temp)
LPlatformChunk(CompilationInfo *info, HGraph *graph)
LRegExpLiteral(LOperand *context)
virtual bool HasInterestingComment(LCodeGen *gen) const OVERRIDE
bool needs_check() const
LOperand * string() const
LInstruction * DoMathLog(HUnaryMathOperation *instr)
LInstruction * DoDivByConstI(HDiv *instr)
LOperand * multiplier()
bool for_typeof() const
void VisitInstruction(HInstruction *current)
LOperand * multiplicand()
LPushArgument(LOperand *value)
DECLARE_CONCRETE_INSTRUCTION(HasCachedArrayIndexAndBranch, "has-cached-array-index-and-branch") virtual void PrintDataTo(StringStream *stream) OVERRIDE
MUST_USE_RESULT LOperand * UseRegister(HValue *value)
LClassOfTestAndBranch(LOperand *value, LOperand *temp)
bool is_osr_entry() const
static bool HasMagicNumberForDivisor(int32_t divisor)
LMultiplyAddD(LOperand *addend, LOperand *multiplier, LOperand *multiplicand)
virtual const char * Mnemonic() const OVERRIDE
LFlooringDivByConstI(LOperand *dividend, int32_t divisor, LOperand *temp)
LDivI(LOperand *dividend, LOperand *divisor, LOperand *temp)
MUST_USE_RESULT LOperand * UseOrConstant(HValue *value)
LCallStub(LOperand *context)
LInstruction * DoFlooringDivI(HMathFloorOfDiv *instr)
LMathAbs(LOperand *context, LOperand *value)
LInstruction * DefineFixed(LTemplateResultInstruction< 1 > *instr, Register reg)
LCompareNumericAndBranch(LOperand *left, LOperand *right)
LInstruction * DoDivI(HDiv *instr)
LFunctionLiteral(LOperand *context)
virtual MUST_USE_RESULT LOperand * UseAny(HValue *value) OVERRIDE
LMathSqrt(LOperand *value)
MUST_USE_RESULT LOperand * FixedTemp(Register reg)
virtual void PrintDataTo(StringStream *stream)
Handle< Map > transitioned_map()
LMathLog(LOperand *value)
LLoadKeyed(LOperand *elements, LOperand *key)
LOperand * parameter_count()
LReturn(LOperand *value, LOperand *context, LOperand *parameter_count)
LCallFunction(LOperand *context, LOperand *function)
LTaggedToI(LOperand *value, LOperand *temp, LOperand *temp2)
MUST_USE_RESULT LOperand * FixedTemp(DoubleRegister reg)
LHasCachedArrayIndexAndBranch(LOperand *value)
LInstruction * DoModI(HMod *instr)
MUST_USE_RESULT LOperand * UseRegisterOrConstantAtStart(HValue *value)
void AddInstruction(LInstruction *instr, HInstruction *current)
LStoreGlobalCell(LOperand *value, LOperand *temp)
void set_replacement(LLabel *label)
bool is_loop_header() const
LInstanceOf(LOperand *context, LOperand *left, LOperand *right)
LFlooringDivByPowerOf2I(LOperand *dividend, int32_t divisor)
LCheckNonSmi(LOperand *value)
LAccessArgumentsAt(LOperand *arguments, LOperand *length, LOperand *index)
LNumberUntagD(LOperand *value)
LUnallocated * ToUnallocated(Register reg)
LOperand * target() const
LIsObjectAndBranch(LOperand *value, LOperand *temp)
LTypeof(LOperand *context, LOperand *value)
MUST_USE_RESULT LOperand * UseRegisterOrConstant(HValue *value)
LChunkBuilder(CompilationInfo *info, HGraph *graph, LAllocator *allocator)
LArithmeticD(Token::Value op, LOperand *left, LOperand *right)
virtual void SetDeferredLazyDeoptimizationEnvironment(LEnvironment *env) OVERRIDE
LOperand * code_object()
LEnvironment * GetDeferredLazyDeoptimizationEnvironment()
LClampIToUint8(LOperand *unclamped)
LOperand * divisor()
LFlooringDivI(LOperand *dividend, LOperand *divisor)
LHasInstanceTypeAndBranch(LOperand *value)
LNumberTagU(LOperand *value, LOperand *temp1, LOperand *temp2)
LInstruction * DefineAsRegister(LTemplateResultInstruction< 1 > *instr)
DECLARE_CONCRETE_INSTRUCTION(InstanceOfKnownGlobal, "instance-of-known-global") Handle< JSFunction > function() const
LModByConstI(LOperand *dividend, int32_t divisor)
LTransitionElementsKind(LOperand *object, LOperand *context, LOperand *new_map_temp)
LToFastProperties(LOperand *value)
LTailCallThroughMegamorphicCache(LOperand *context, LOperand *receiver, LOperand *name)
LInstruction * MarkAsCall(LInstruction *instr, HInstruction *hinstr, CanDeoptimize can_deoptimize=CANNOT_DEOPTIMIZE_EAGERLY)
LInstruction * DoMathFround(HUnaryMathOperation *instr)
int GetNextSpillIndex(RegisterKind kind)
static HValue * cast(HValue *value)
LAllocateBlockContext(LOperand *context, LOperand *function)
int LookupDestination(int block_id) const
Definition: lithium.cc:285
Label * GetAssemblyLabel(int block_id) const
Definition: lithium.cc:293
HControlInstruction * hydrogen()
virtual bool IsControl() const FINAL OVERRIDE
HBasicBlock * SuccessorAt(int i)
Label * FalseLabel(LChunk *chunk)
Label * TrueLabel(LChunk *chunk)
LGap(HBasicBlock *block)
virtual void PrintDataTo(StringStream *stream) OVERRIDE
virtual bool IsGap() const FINAL OVERRIDE
static LGap * cast(LInstruction *instr)
LParallelMove * GetParallelMove(InnerPosition pos)
bool IsRedundant() const
HBasicBlock * block() const
Definition: lithium-arm.h:344
LParallelMove * parallel_moves_[LAST_INNER_POSITION+1]
Definition: lithium-arm.h:367
HBasicBlock * block_
Definition: lithium-arm.h:368
LParallelMove * GetOrCreateParallelMove(InnerPosition pos, Zone *zone)
SetOncePointer< LPointerMap > pointer_map_
Definition: lithium-arm.h:282
virtual int InputCount()=0
void set_environment(LEnvironment *env)
virtual bool HasResult() const =0
virtual void PrintDataTo(StringStream *stream)
virtual int TempCount()=0
virtual const char * Mnemonic() const =0
virtual LOperand * TempAt(int i)=0
LEnvironment * environment() const
virtual LOperand * InputAt(int i)=0
void set_hydrogen_value(HValue *value)
virtual LOperand * result() const =0
virtual void PrintTo(StringStream *stream)
virtual void SetDeferredLazyDeoptimizationEnvironment(LEnvironment *env)
HValue * hydrogen_value() const
void set_pointer_map(LPointerMap *p)
LEnvironment * environment_
Definition: lithium-arm.h:281
virtual Opcode opcode() const =0
virtual bool ClobbersDoubleRegisters(Isolate *isolate) const
virtual bool HasInterestingComment(LCodeGen *gen) const
virtual void CompileToNative(LCodeGen *generator)=0
virtual bool IsControl() const
LPointerMap * pointer_map() const
virtual bool IsGap() const
virtual void PrintOutputOperandTo(StringStream *stream)
LStoreFrameContext(LOperand *context)
EmbeddedContainer< LOperand *, I > inputs_
Definition: lithium-arm.h:311
virtual LOperand * TempAt(int i) FINAL OVERRIDE
virtual int TempCount() FINAL OVERRIDE
EmbeddedContainer< LOperand *, T > temps_
Definition: lithium-arm.h:312
virtual LOperand * InputAt(int i) FINAL OVERRIDE
virtual int InputCount() FINAL OVERRIDE
virtual bool HasResult() const FINAL OVERRIDE
EmbeddedContainer< LOperand *, R > results_
Definition: lithium-arm.h:301
void set(T *value)
Definition: utils.h:417
static Smi * FromInt(int value)
Definition: objects-inl.h:1321
#define OVERRIDE
#define FINAL
enable harmony numeric enable harmony object literal extensions Optimize object Array DOM strings and string trace pretenuring decisions of HAllocate instructions Enables optimizations which favor memory size over execution speed maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining trace the tracking of allocation sites deoptimize every n garbage collections perform array bounds checks elimination analyze liveness of environment slots and zap dead values flushes the cache of optimized code for closures on every GC allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms do not emit check maps for constant values that have a leaf map
enable harmony numeric enable harmony object literal extensions Optimize object size
enable harmony numeric enable harmony object literal extensions Optimize object Array DOM strings and string trace pretenuring decisions of HAllocate instructions Enables optimizations which favor memory size over execution speed maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining trace the tracking of allocation sites deoptimize every n garbage collections perform array bounds checks elimination analyze liveness of environment slots and zap dead values flushes the cache of optimized code for closures on every GC allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms do not emit check maps for constant values that have a leaf deoptimize the optimized code if the layout of the maps changes enable context specialization in TurboFan execution budget before interrupt is triggered max percentage of megamorphic generic ICs to allow optimization enable use of SAHF instruction if enable use of VFP3 instructions if available enable use of NEON instructions if enable use of SDIV and UDIV instructions if enable use of MLS instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of d16 d31 registers on ARM this requires VFP3 force all emitted branches to be in long enable alignment of csp to bytes on platforms which prefer the register to always be expose gc extension under the specified name show built in functions in stack traces use random jit cookie to mask large constants minimum length for automatic enable preparsing CPU profiler sampling interval in microseconds trace out of bounds accesses to external arrays default size of stack region v8 is allowed to maximum length of function source code printed in a stack trace min size of a semi the new space consists of two semi spaces print one trace line following each garbage collection do not print trace line after scavenger collection print cumulative GC statistics in name
enable harmony numeric enable harmony object literal extensions Optimize object Array DOM strings and string trace pretenuring decisions of HAllocate instructions Enables optimizations which favor memory size over execution speed maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining trace the tracking of allocation sites deoptimize every n garbage collections perform array bounds checks elimination analyze liveness of environment slots and zap dead values flushes the cache of optimized code for closures on every GC allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms do not emit check maps for constant values that have a leaf deoptimize the optimized code if the layout of the maps changes enable context specialization in TurboFan execution budget before interrupt is triggered max percentage of megamorphic generic ICs to allow optimization enable use of SAHF instruction if enable use of VFP3 instructions if available enable use of NEON instructions if enable use of SDIV and UDIV instructions if enable use of MLS instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of d16 d31 registers on ARM this requires VFP3 force all emitted branches to be in long enable alignment of csp to bytes on platforms which prefer the register to always be NULL
#define HYDROGEN_CONCRETE_INSTRUCTION_LIST(V)
#define DECLARE_CONCRETE_INSTRUCTION(type, mnemonic)
#define DECLARE_DO(type)
#define DECLARE_PREDICATE(type)
#define DECLARE_OPCODE(type)
#define DECLARE_HYDROGEN_ACCESSOR(type)
#define DCHECK(condition)
Definition: logging.h:205
#define MUST_USE_RESULT
Definition: macros.h:266
int int32_t
Definition: unicode.cc:24
static Object * DeclareGlobals(Isolate *isolate, Handle< GlobalObject > global, Handle< String > name, Handle< Object > value, PropertyAttributes attr, bool is_var, bool is_const, bool is_function)
Definition: runtime.cc:1038
Debugger support for the V8 JavaScript engine.
Definition: accessors.cc:20
#define T(name, string, precedence)
Definition: token.cc:25