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