v8  3.11.10(node0.8.26)
V8 is Google's open source JavaScript engine
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
hydrogen-instructions.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_HYDROGEN_INSTRUCTIONS_H_
29 #define V8_HYDROGEN_INSTRUCTIONS_H_
30 
31 #include "v8.h"
32 
33 #include "allocation.h"
34 #include "code-stubs.h"
35 #include "data-flow.h"
36 #include "small-pointer-list.h"
37 #include "string-stream.h"
38 #include "v8conversions.h"
39 #include "v8utils.h"
40 #include "zone.h"
41 
42 namespace v8 {
43 namespace internal {
44 
45 // Forward declarations.
46 class HBasicBlock;
47 class HEnvironment;
48 class HInstruction;
49 class HLoopInformation;
50 class HValue;
51 class LInstruction;
52 class LChunkBuilder;
53 
54 
55 #define HYDROGEN_ABSTRACT_INSTRUCTION_LIST(V) \
56  V(BitwiseBinaryOperation) \
57  V(ControlInstruction) \
58  V(Instruction) \
59 
60 
61 #define HYDROGEN_CONCRETE_INSTRUCTION_LIST(V) \
62  V(AbnormalExit) \
63  V(AccessArgumentsAt) \
64  V(Add) \
65  V(AllocateObject) \
66  V(ApplyArguments) \
67  V(ArgumentsElements) \
68  V(ArgumentsLength) \
69  V(ArgumentsObject) \
70  V(ArrayLiteral) \
71  V(Bitwise) \
72  V(BitNot) \
73  V(BlockEntry) \
74  V(BoundsCheck) \
75  V(Branch) \
76  V(CallConstantFunction) \
77  V(CallFunction) \
78  V(CallGlobal) \
79  V(CallKeyed) \
80  V(CallKnownGlobal) \
81  V(CallNamed) \
82  V(CallNew) \
83  V(CallRuntime) \
84  V(CallStub) \
85  V(Change) \
86  V(CheckFunction) \
87  V(CheckInstanceType) \
88  V(CheckMaps) \
89  V(CheckNonSmi) \
90  V(CheckPrototypeMaps) \
91  V(CheckSmi) \
92  V(ClampToUint8) \
93  V(ClassOfTestAndBranch) \
94  V(CompareIDAndBranch) \
95  V(CompareGeneric) \
96  V(CompareObjectEqAndBranch) \
97  V(CompareMap) \
98  V(CompareConstantEqAndBranch) \
99  V(Constant) \
100  V(Context) \
101  V(DeclareGlobals) \
102  V(DeleteProperty) \
103  V(Deoptimize) \
104  V(Div) \
105  V(ElementsKind) \
106  V(EnterInlined) \
107  V(FastLiteral) \
108  V(FixedArrayBaseLength) \
109  V(ForceRepresentation) \
110  V(FunctionLiteral) \
111  V(GetCachedArrayIndex) \
112  V(GlobalObject) \
113  V(GlobalReceiver) \
114  V(Goto) \
115  V(HasCachedArrayIndexAndBranch) \
116  V(HasInstanceTypeAndBranch) \
117  V(In) \
118  V(InstanceOf) \
119  V(InstanceOfKnownGlobal) \
120  V(InvokeFunction) \
121  V(IsConstructCallAndBranch) \
122  V(IsNilAndBranch) \
123  V(IsObjectAndBranch) \
124  V(IsStringAndBranch) \
125  V(IsSmiAndBranch) \
126  V(IsUndetectableAndBranch) \
127  V(StringCompareAndBranch) \
128  V(JSArrayLength) \
129  V(LeaveInlined) \
130  V(LoadContextSlot) \
131  V(LoadElements) \
132  V(LoadExternalArrayPointer) \
133  V(LoadFunctionPrototype) \
134  V(LoadGlobalCell) \
135  V(LoadGlobalGeneric) \
136  V(LoadKeyedFastDoubleElement) \
137  V(LoadKeyedFastElement) \
138  V(LoadKeyedGeneric) \
139  V(LoadKeyedSpecializedArrayElement) \
140  V(LoadNamedField) \
141  V(LoadNamedFieldPolymorphic) \
142  V(LoadNamedGeneric) \
143  V(MathFloorOfDiv) \
144  V(Mod) \
145  V(Mul) \
146  V(ObjectLiteral) \
147  V(OsrEntry) \
148  V(OuterContext) \
149  V(Parameter) \
150  V(Power) \
151  V(PushArgument) \
152  V(Random) \
153  V(RegExpLiteral) \
154  V(Return) \
155  V(Sar) \
156  V(Shl) \
157  V(Shr) \
158  V(Simulate) \
159  V(SoftDeoptimize) \
160  V(StackCheck) \
161  V(StoreContextSlot) \
162  V(StoreGlobalCell) \
163  V(StoreGlobalGeneric) \
164  V(StoreKeyedFastDoubleElement) \
165  V(StoreKeyedFastElement) \
166  V(StoreKeyedGeneric) \
167  V(StoreKeyedSpecializedArrayElement) \
168  V(StoreNamedField) \
169  V(StoreNamedGeneric) \
170  V(StringAdd) \
171  V(StringCharCodeAt) \
172  V(StringCharFromCode) \
173  V(StringLength) \
174  V(Sub) \
175  V(ThisFunction) \
176  V(Throw) \
177  V(ToFastProperties) \
178  V(TransitionElementsKind) \
179  V(Typeof) \
180  V(TypeofIsAndBranch) \
181  V(UnaryMathOperation) \
182  V(UnknownOSRValue) \
183  V(UseConst) \
184  V(ValueOf) \
185  V(ForInPrepareMap) \
186  V(ForInCacheArray) \
187  V(CheckMapValue) \
188  V(LoadFieldByIndex) \
189  V(DateField) \
190  V(WrapReceiver)
191 
192 #define GVN_TRACKED_FLAG_LIST(V) \
193  V(NewSpacePromotion)
194 
195 #define GVN_UNTRACKED_FLAG_LIST(V) \
196  V(Calls) \
197  V(InobjectFields) \
198  V(BackingStoreFields) \
199  V(ElementsKind) \
200  V(ElementsPointer) \
201  V(ArrayElements) \
202  V(DoubleArrayElements) \
203  V(SpecializedArrayElements) \
204  V(GlobalVars) \
205  V(Maps) \
206  V(ArrayLengths) \
207  V(ContextSlots) \
208  V(OsrEntries)
209 
210 #define DECLARE_ABSTRACT_INSTRUCTION(type) \
211  virtual bool Is##type() const { return true; } \
212  static H##type* cast(HValue* value) { \
213  ASSERT(value->Is##type()); \
214  return reinterpret_cast<H##type*>(value); \
215  }
216 
217 
218 #define DECLARE_CONCRETE_INSTRUCTION(type) \
219  virtual LInstruction* CompileToLithium(LChunkBuilder* builder); \
220  static H##type* cast(HValue* value) { \
221  ASSERT(value->Is##type()); \
222  return reinterpret_cast<H##type*>(value); \
223  } \
224  virtual Opcode opcode() const { return HValue::k##type; }
225 
226 
227 class Range: public ZoneObject {
228  public:
230  : lower_(kMinInt),
231  upper_(kMaxInt),
232  next_(NULL),
233  can_be_minus_zero_(false) { }
234 
236  : lower_(lower),
237  upper_(upper),
238  next_(NULL),
239  can_be_minus_zero_(false) { }
240 
241  int32_t upper() const { return upper_; }
242  int32_t lower() const { return lower_; }
243  Range* next() const { return next_; }
244  Range* CopyClearLower(Zone* zone) const {
245  return new(zone) Range(kMinInt, upper_);
246  }
247  Range* CopyClearUpper(Zone* zone) const {
248  return new(zone) Range(lower_, kMaxInt);
249  }
250  Range* Copy(Zone* zone) const {
251  Range* result = new(zone) Range(lower_, upper_);
253  return result;
254  }
255  int32_t Mask() const;
256  void set_can_be_minus_zero(bool b) { can_be_minus_zero_ = b; }
257  bool CanBeMinusZero() const { return CanBeZero() && can_be_minus_zero_; }
258  bool CanBeZero() const { return upper_ >= 0 && lower_ <= 0; }
259  bool CanBeNegative() const { return lower_ < 0; }
260  bool Includes(int value) const { return lower_ <= value && upper_ >= value; }
261  bool IsMostGeneric() const {
262  return lower_ == kMinInt && upper_ == kMaxInt && CanBeMinusZero();
263  }
264  bool IsInSmiRange() const {
265  return lower_ >= Smi::kMinValue && upper_ <= Smi::kMaxValue;
266  }
267  void KeepOrder();
268 #ifdef DEBUG
269  void Verify() const;
270 #endif
271 
272  void StackUpon(Range* other) {
273  Intersect(other);
274  next_ = other;
275  }
276 
277  void Intersect(Range* other);
278  void Union(Range* other);
279 
280  void AddConstant(int32_t value);
281  void Sar(int32_t value);
282  void Shl(int32_t value);
283  bool AddAndCheckOverflow(Range* other);
284  bool SubAndCheckOverflow(Range* other);
285  bool MulAndCheckOverflow(Range* other);
286 
287  private:
288  int32_t lower_;
289  int32_t upper_;
290  Range* next_;
291  bool can_be_minus_zero_;
292 };
293 
294 
296  public:
297  enum Kind {
304  };
305 
306  Representation() : kind_(kNone) { }
307 
308  static Representation None() { return Representation(kNone); }
313 
314  bool Equals(const Representation& other) {
315  return kind_ == other.kind_;
316  }
317 
318  Kind kind() const { return static_cast<Kind>(kind_); }
319  bool IsNone() const { return kind_ == kNone; }
320  bool IsTagged() const { return kind_ == kTagged; }
321  bool IsInteger32() const { return kind_ == kInteger32; }
322  bool IsDouble() const { return kind_ == kDouble; }
323  bool IsExternal() const { return kind_ == kExternal; }
324  bool IsSpecialization() const {
325  return kind_ == kInteger32 || kind_ == kDouble;
326  }
327  const char* Mnemonic() const;
328 
329  private:
330  explicit Representation(Kind k) : kind_(k) { }
331 
332  // Make sure kind fits in int8.
333  STATIC_ASSERT(kNumRepresentations <= (1 << kBitsPerByte));
334 
335  int8_t kind_;
336 };
337 
338 
339 class HType {
340  public:
341  HType() : type_(kUninitialized) { }
342 
343  static HType Tagged() { return HType(kTagged); }
344  static HType TaggedPrimitive() { return HType(kTaggedPrimitive); }
345  static HType TaggedNumber() { return HType(kTaggedNumber); }
346  static HType Smi() { return HType(kSmi); }
347  static HType HeapNumber() { return HType(kHeapNumber); }
348  static HType String() { return HType(kString); }
349  static HType Boolean() { return HType(kBoolean); }
350  static HType NonPrimitive() { return HType(kNonPrimitive); }
351  static HType JSArray() { return HType(kJSArray); }
352  static HType JSObject() { return HType(kJSObject); }
353  static HType Uninitialized() { return HType(kUninitialized); }
354 
355  // Return the weakest (least precise) common type.
356  HType Combine(HType other) {
357  return HType(static_cast<Type>(type_ & other.type_));
358  }
359 
360  bool Equals(const HType& other) {
361  return type_ == other.type_;
362  }
363 
364  bool IsSubtypeOf(const HType& other) {
365  return Combine(other).Equals(other);
366  }
367 
368  bool IsTagged() {
369  ASSERT(type_ != kUninitialized);
370  return ((type_ & kTagged) == kTagged);
371  }
372 
374  ASSERT(type_ != kUninitialized);
375  return ((type_ & kTaggedPrimitive) == kTaggedPrimitive);
376  }
377 
378  bool IsTaggedNumber() {
379  ASSERT(type_ != kUninitialized);
380  return ((type_ & kTaggedNumber) == kTaggedNumber);
381  }
382 
383  bool IsSmi() {
384  ASSERT(type_ != kUninitialized);
385  return ((type_ & kSmi) == kSmi);
386  }
387 
388  bool IsHeapNumber() {
389  ASSERT(type_ != kUninitialized);
390  return ((type_ & kHeapNumber) == kHeapNumber);
391  }
392 
393  bool IsString() {
394  ASSERT(type_ != kUninitialized);
395  return ((type_ & kString) == kString);
396  }
397 
398  bool IsBoolean() {
399  ASSERT(type_ != kUninitialized);
400  return ((type_ & kBoolean) == kBoolean);
401  }
402 
403  bool IsNonPrimitive() {
404  ASSERT(type_ != kUninitialized);
405  return ((type_ & kNonPrimitive) == kNonPrimitive);
406  }
407 
408  bool IsJSArray() {
409  ASSERT(type_ != kUninitialized);
410  return ((type_ & kJSArray) == kJSArray);
411  }
412 
413  bool IsJSObject() {
414  ASSERT(type_ != kUninitialized);
415  return ((type_ & kJSObject) == kJSObject);
416  }
417 
419  return type_ == kUninitialized;
420  }
421 
422  bool IsHeapObject() {
423  ASSERT(type_ != kUninitialized);
424  return IsHeapNumber() || IsString() || IsNonPrimitive();
425  }
426 
427  static HType TypeFromValue(Handle<Object> value);
428 
429  const char* ToString();
430 
431  private:
432  enum Type {
433  kTagged = 0x1, // 0000 0000 0000 0001
434  kTaggedPrimitive = 0x5, // 0000 0000 0000 0101
435  kTaggedNumber = 0xd, // 0000 0000 0000 1101
436  kSmi = 0x1d, // 0000 0000 0001 1101
437  kHeapNumber = 0x2d, // 0000 0000 0010 1101
438  kString = 0x45, // 0000 0000 0100 0101
439  kBoolean = 0x85, // 0000 0000 1000 0101
440  kNonPrimitive = 0x101, // 0000 0001 0000 0001
441  kJSObject = 0x301, // 0000 0011 0000 0001
442  kJSArray = 0x701, // 0000 0111 0000 0001
443  kUninitialized = 0x1fff // 0001 1111 1111 1111
444  };
445 
446  // Make sure type fits in int16.
447  STATIC_ASSERT(kUninitialized < (1 << (2 * kBitsPerByte)));
448 
449  explicit HType(Type t) : type_(t) { }
450 
451  int16_t type_;
452 };
453 
454 
455 class HUseListNode: public ZoneObject {
456  public:
458  : tail_(tail), value_(value), index_(index) {
459  }
460 
461  HUseListNode* tail();
462  HValue* value() const { return value_; }
463  int index() const { return index_; }
464 
465  void set_tail(HUseListNode* list) { tail_ = list; }
466 
467 #ifdef DEBUG
468  void Zap() {
469  tail_ = reinterpret_cast<HUseListNode*>(1);
470  value_ = NULL;
471  index_ = -1;
472  }
473 #endif
474 
475  private:
476  HUseListNode* tail_;
477  HValue* value_;
478  int index_;
479 };
480 
481 
482 // We reuse use list nodes behind the scenes as uses are added and deleted.
483 // This class is the safe way to iterate uses while deleting them.
484 class HUseIterator BASE_EMBEDDED {
485  public:
486  bool Done() { return current_ == NULL; }
487  void Advance();
488 
490  ASSERT(!Done());
491  return value_;
492  }
493 
494  int index() {
495  ASSERT(!Done());
496  return index_;
497  }
498 
499  private:
500  explicit HUseIterator(HUseListNode* head);
501 
503  HUseListNode* next_;
504  HValue* value_;
505  int index_;
506 
507  friend class HValue;
508 };
509 
510 
511 // There must be one corresponding kDepends flag for every kChanges flag and
512 // the order of the kChanges flags must be exactly the same as of the kDepends
513 // flags. All tracked flags should appear before untracked ones.
514 enum GVNFlag {
515  // Declare global value numbering flags.
516 #define DECLARE_FLAG(type) kChanges##type, kDependsOn##type,
519 #undef DECLARE_FLAG
522 #define COUNT_FLAG(type) + 1
524 #undef COUNT_FLAG
525 };
526 
528 
529 
530 class HValue: public ZoneObject {
531  public:
532  static const int kNoNumber = -1;
533 
534  enum Flag {
536  // Participate in Global Value Numbering, i.e. elimination of
537  // unnecessary recomputations. If an instruction sets this flag, it must
538  // implement DataEquals(), which will be used to determine if other
539  // occurrences of the instruction are indeed the same.
541  // Track instructions that are dominating side effects. If an instruction
542  // sets this flag, it must implement SetSideEffectDominator() and should
543  // indicate which side effects to track by setting GVN flags.
553  };
554 
556 
557  static const int kChangesToDependsFlagsLeftShift = 1;
558 
559  static GVNFlag ChangesFlagFromInt(int x) {
560  return static_cast<GVNFlag>(x * 2);
561  }
563  return static_cast<GVNFlag>(x * 2 + 1);
564  }
567  }
568 
569  static HValue* cast(HValue* value) { return value; }
570 
571  enum Opcode {
572  // Declare a unique enum value for each hydrogen instruction.
573  #define DECLARE_OPCODE(type) k##type,
576  #undef DECLARE_OPCODE
577  };
578  virtual Opcode opcode() const = 0;
579 
580  // Declare a non-virtual predicates for each concrete HInstruction or HValue.
581  #define DECLARE_PREDICATE(type) \
582  bool Is##type() const { return opcode() == k##type; }
584  #undef DECLARE_PREDICATE
585  bool IsPhi() const { return opcode() == kPhi; }
586 
587  // Declare virtual predicates for abstract HInstruction or HValue
588  #define DECLARE_PREDICATE(type) \
589  virtual bool Is##type() const { return false; }
591  #undef DECLARE_PREDICATE
592 
594  id_(kNoNumber),
595  type_(HType::Tagged()),
596  use_list_(NULL),
597  range_(NULL),
598  flags_(0) {}
599  virtual ~HValue() {}
600 
601  HBasicBlock* block() const { return block_; }
602  void SetBlock(HBasicBlock* block);
603  int LoopWeight() const;
604 
605  int id() const { return id_; }
606  void set_id(int id) { id_ = id; }
607 
608  HUseIterator uses() const { return HUseIterator(use_list_); }
609 
610  virtual bool EmitAtUses() { return false; }
613  // Representation was already set and is allowed to be changed.
614  ASSERT(!r.IsNone());
617  representation_ = r;
618  }
620 
621  virtual bool IsConvertibleToInteger() const { return true; }
622 
623  HType type() const { return type_; }
624  void set_type(HType new_type) {
625  ASSERT(new_type.IsSubtypeOf(type_));
626  type_ = new_type;
627  }
628 
629  // An operation needs to override this function iff:
630  // 1) it can produce an int32 output.
631  // 2) the true value of its output can potentially be minus zero.
632  // The implementation must set a flag so that it bails out in the case where
633  // it would otherwise output what should be a minus zero as an int32 zero.
634  // If the operation also exists in a form that takes int32 and outputs int32
635  // then the operation should return its input value so that we can propagate
636  // back. There are three operations that need to propagate back to more than
637  // one input. They are phi and binary div and mul. They always return NULL
638  // and expect the caller to take care of things.
640  visited->Add(id());
641  return NULL;
642  }
643 
644  bool IsDefinedAfter(HBasicBlock* other) const;
645 
646  // Operands.
647  virtual int OperandCount() = 0;
648  virtual HValue* OperandAt(int index) = 0;
649  void SetOperandAt(int index, HValue* value);
650 
651  void DeleteAndReplaceWith(HValue* other);
652  void ReplaceAllUsesWith(HValue* other);
653  bool HasNoUses() const { return use_list_ == NULL; }
654  bool HasMultipleUses() const {
655  return use_list_ != NULL && use_list_->tail() != NULL;
656  }
657  int UseCount() const;
658 
659  // Mark this HValue as dead and to be removed from other HValues' use lists.
660  void Kill();
661 
662  int flags() const { return flags_; }
663  void SetFlag(Flag f) { flags_ |= (1 << f); }
664  void ClearFlag(Flag f) { flags_ &= ~(1 << f); }
665  bool CheckFlag(Flag f) const { return (flags_ & (1 << f)) != 0; }
666 
667  // Returns true if the flag specified is set for all uses, false otherwise.
668  bool CheckUsesForFlag(Flag f);
669 
670  GVNFlagSet gvn_flags() const { return gvn_flags_; }
673  bool CheckGVNFlag(GVNFlag f) const { return gvn_flags_.Contains(f); }
677  }
678  bool HasSideEffects() const {
680  }
683  }
684 
686  GVNFlagSet result = gvn_flags_;
687  result.Intersect(AllDependsOnFlagSet());
688  return result;
689  }
690 
692  GVNFlagSet result = gvn_flags_;
694  return result;
695  }
696 
698  GVNFlagSet result = gvn_flags_;
699  result.Intersect(AllChangesFlagSet());
700  return result;
701  }
702 
704  GVNFlagSet result = gvn_flags_;
705  result.Intersect(AllChangesFlagSet());
707  return result;
708  }
709 
710  Range* range() const { return range_; }
711  bool HasRange() const { return range_ != NULL; }
712  void AddNewRange(Range* r, Zone* zone);
713  void RemoveLastAddedRange();
714  void ComputeInitialRange(Zone* zone);
715 
716  // Representation helpers.
717  virtual Representation RequiredInputRepresentation(int index) = 0;
718 
720  return representation();
721  }
722 
723  // Type feedback access.
725  return RequiredInputRepresentation(index);
726  }
727 
728  // This gives the instruction an opportunity to replace itself with an
729  // instruction that does the same in some better way. To replace an
730  // instruction with a new one, first add the new instruction to the graph,
731  // then return it. Return NULL to have the instruction deleted.
732  virtual HValue* Canonicalize() { return this; }
733 
734  bool Equals(HValue* other);
735  virtual intptr_t Hashcode();
736 
737  // Printing support.
738  virtual void PrintTo(StringStream* stream) = 0;
739  void PrintNameTo(StringStream* stream);
740  void PrintTypeTo(StringStream* stream);
741  void PrintRangeTo(StringStream* stream);
742  void PrintChangesTo(StringStream* stream);
743 
744  const char* Mnemonic() const;
745 
746  // Updated the inferred type of this instruction and returns true if
747  // it has changed.
748  bool UpdateInferredType();
749 
750  virtual HType CalculateInferredType();
751 
752  // This function must be overridden for instructions which have the
753  // kTrackSideEffectDominators flag set, to track instructions that are
754  // dominating side effects.
755  virtual void SetSideEffectDominator(GVNFlag side_effect, HValue* dominator) {
756  UNREACHABLE();
757  }
758 
759 #ifdef DEBUG
760  virtual void Verify() = 0;
761 #endif
762 
763  protected:
764  // This function must be overridden for instructions with flag kUseGVN, to
765  // compare the non-Operand parts of the instruction.
766  virtual bool DataEquals(HValue* other) {
767  UNREACHABLE();
768  return false;
769  }
771  virtual Range* InferRange(Zone* zone);
772  virtual void DeleteFromGraph() = 0;
773  virtual void InternalSetOperandAt(int index, HValue* value) = 0;
774  void clear_block() {
775  ASSERT(block_ != NULL);
776  block_ = NULL;
777  }
778 
780  // Representation is set-once.
781  ASSERT(representation_.IsNone() && !r.IsNone());
782  representation_ = r;
783  }
784 
786  GVNFlagSet result;
787  // Create changes mask.
788 #define ADD_FLAG(type) result.Add(kDependsOn##type);
791 #undef ADD_FLAG
792  return result;
793  }
794 
796  GVNFlagSet result;
797  // Create changes mask.
798 #define ADD_FLAG(type) result.Add(kChanges##type);
801 #undef ADD_FLAG
802  return result;
803  }
804 
805  // A flag mask to mark an instruction as having arbitrary side effects.
807  GVNFlagSet result = AllChangesFlagSet();
808  result.Remove(kChangesOsrEntries);
809  return result;
810  }
811 
812  // A flag mask of all side effects that can make observable changes in
813  // an executing program (i.e. are not safe to repeat, move or remove);
815  GVNFlagSet result = AllChangesFlagSet();
816  result.Remove(kChangesNewSpacePromotion);
817  result.Remove(kChangesElementsKind);
818  result.Remove(kChangesElementsPointer);
819  result.Remove(kChangesMaps);
820  return result;
821  }
822 
823  // Remove the matching use from the use list if present. Returns the
824  // removed list node or NULL.
825  HUseListNode* RemoveUse(HValue* value, int index);
826 
827  void RegisterUse(int index, HValue* new_value);
828 
830 
831  // The id of this instruction in the hydrogen graph, assigned when first
832  // added to the graph. Reflects creation order.
833  int id_;
834 
839  int flags_;
841 
842  private:
843  DISALLOW_COPY_AND_ASSIGN(HValue);
844 };
845 
846 
847 class HInstruction: public HValue {
848  public:
849  HInstruction* next() const { return next_; }
850  HInstruction* previous() const { return previous_; }
851 
852  virtual void PrintTo(StringStream* stream);
853  virtual void PrintDataTo(StringStream* stream) { }
854 
855  bool IsLinked() const { return block() != NULL; }
856  void Unlink();
859 
860  int position() const { return position_; }
861  bool has_position() const { return position_ != RelocInfo::kNoPosition; }
862  void set_position(int position) { position_ = position; }
863 
865 
866  virtual LInstruction* CompileToLithium(LChunkBuilder* builder) = 0;
867 
868 #ifdef DEBUG
869  virtual void Verify();
870 #endif
871 
872  virtual bool IsCall() { return false; }
873 
875 
876  protected:
878  : next_(NULL),
879  previous_(NULL),
880  position_(RelocInfo::kNoPosition) {
881  SetGVNFlag(kDependsOnOsrEntries);
882  }
883 
884  virtual void DeleteFromGraph() { Unlink(); }
885 
886  private:
887  void InitializeAsFirst(HBasicBlock* block) {
888  ASSERT(!IsLinked());
889  SetBlock(block);
890  }
891 
892  void PrintMnemonicTo(StringStream* stream);
893 
894  HInstruction* next_;
895  HInstruction* previous_;
896  int position_;
897 
898  friend class HBasicBlock;
899 };
900 
901 
902 template<int V>
904  public:
905  int OperandCount() { return V; }
906  HValue* OperandAt(int i) { return inputs_[i]; }
907 
908  protected:
909  void InternalSetOperandAt(int i, HValue* value) { inputs_[i] = value; }
910 
911  private:
913 };
914 
915 
917  public:
918  virtual HBasicBlock* SuccessorAt(int i) = 0;
919  virtual int SuccessorCount() = 0;
920  virtual void SetSuccessorAt(int i, HBasicBlock* block) = 0;
921 
922  virtual void PrintDataTo(StringStream* stream);
923 
925  return SuccessorCount() > 0 ? SuccessorAt(0) : NULL;
926  }
928  return SuccessorCount() > 1 ? SuccessorAt(1) : NULL;
929  }
930 
931  DECLARE_ABSTRACT_INSTRUCTION(ControlInstruction)
932 };
933 
934 
935 class HSuccessorIterator BASE_EMBEDDED {
936  public:
938  : instr_(instr), current_(0) { }
939 
940  bool Done() { return current_ >= instr_->SuccessorCount(); }
941  HBasicBlock* Current() { return instr_->SuccessorAt(current_); }
942  void Advance() { current_++; }
943 
944  private:
945  HControlInstruction* instr_;
946  int current_;
947 };
948 
949 
950 template<int S, int V>
952  public:
953  int SuccessorCount() { return S; }
954  HBasicBlock* SuccessorAt(int i) { return successors_[i]; }
955  void SetSuccessorAt(int i, HBasicBlock* block) { successors_[i] = block; }
956 
957  int OperandCount() { return V; }
958  HValue* OperandAt(int i) { return inputs_[i]; }
959 
960 
961  protected:
962  void InternalSetOperandAt(int i, HValue* value) { inputs_[i] = value; }
963 
964  private:
967 };
968 
969 
971  public:
973  return Representation::None();
974  }
975 
976  DECLARE_CONCRETE_INSTRUCTION(BlockEntry)
977 };
978 
979 
980 // We insert soft-deoptimize when we hit code with unknown typefeedback,
981 // so that we get a chance of re-optimizing with useful typefeedback.
982 // HSoftDeoptimize does not end a basic block as opposed to HDeoptimize.
984  public:
986  return Representation::None();
987  }
988 
989  DECLARE_CONCRETE_INSTRUCTION(SoftDeoptimize)
990 };
991 
992 
994  public:
995  HDeoptimize(int environment_length, Zone* zone)
996  : values_(environment_length, zone) { }
997 
999  return Representation::None();
1000  }
1001 
1002  virtual int OperandCount() { return values_.length(); }
1003  virtual HValue* OperandAt(int index) { return values_[index]; }
1004  virtual void PrintDataTo(StringStream* stream);
1005 
1006  virtual int SuccessorCount() { return 0; }
1007  virtual HBasicBlock* SuccessorAt(int i) {
1008  UNREACHABLE();
1009  return NULL;
1010  }
1011  virtual void SetSuccessorAt(int i, HBasicBlock* block) {
1012  UNREACHABLE();
1013  }
1014 
1015  void AddEnvironmentValue(HValue* value, Zone* zone) {
1016  values_.Add(NULL, zone);
1017  SetOperandAt(values_.length() - 1, value);
1018  }
1019 
1020  DECLARE_CONCRETE_INSTRUCTION(Deoptimize)
1021 
1025  };
1026 
1027  protected:
1028  virtual void InternalSetOperandAt(int index, HValue* value) {
1029  values_[index] = value;
1030  }
1031 
1032  private:
1033  ZoneList<HValue*> values_;
1034 };
1035 
1036 
1037 class HGoto: public HTemplateControlInstruction<1, 0> {
1038  public:
1039  explicit HGoto(HBasicBlock* target) {
1040  SetSuccessorAt(0, target);
1041  }
1042 
1044  return Representation::None();
1045  }
1046 
1047  virtual void PrintDataTo(StringStream* stream);
1048 
1050 };
1051 
1052 
1054  public:
1056  HBasicBlock* true_target,
1057  HBasicBlock* false_target) {
1058  SetOperandAt(0, value);
1059  SetSuccessorAt(0, true_target);
1060  SetSuccessorAt(1, false_target);
1061  }
1062 
1063  virtual void PrintDataTo(StringStream* stream);
1064 
1065  HValue* value() { return OperandAt(0); }
1066 };
1067 
1068 
1070  public:
1072  HBasicBlock* true_target,
1073  HBasicBlock* false_target,
1075  : HUnaryControlInstruction(value, true_target, false_target),
1076  expected_input_types_(expected_input_types) {
1077  ASSERT(true_target != NULL && false_target != NULL);
1078  }
1079  explicit HBranch(HValue* value)
1080  : HUnaryControlInstruction(value, NULL, NULL) { }
1081 
1082 
1084  return Representation::None();
1085  }
1086 
1088  return expected_input_types_;
1089  }
1090 
1092 
1093  private:
1094  ToBooleanStub::Types expected_input_types_;
1095 };
1096 
1097 
1099  public:
1101  Handle<Map> map,
1102  HBasicBlock* true_target,
1103  HBasicBlock* false_target)
1104  : HUnaryControlInstruction(value, true_target, false_target),
1105  map_(map) {
1106  ASSERT(true_target != NULL);
1107  ASSERT(false_target != NULL);
1108  ASSERT(!map.is_null());
1109  }
1110 
1111  virtual void PrintDataTo(StringStream* stream);
1112 
1113  Handle<Map> map() const { return map_; }
1114 
1116  return Representation::Tagged();
1117  }
1118 
1119  DECLARE_CONCRETE_INSTRUCTION(CompareMap)
1120 
1121  private:
1122  Handle<Map> map_;
1123 };
1124 
1125 
1127  public:
1128  explicit HReturn(HValue* value) {
1129  SetOperandAt(0, value);
1130  }
1131 
1133  return Representation::Tagged();
1134  }
1135 
1136  virtual void PrintDataTo(StringStream* stream);
1137 
1138  HValue* value() { return OperandAt(0); }
1139 
1141 };
1142 
1143 
1145  public:
1147  return Representation::None();
1148  }
1149 
1150  DECLARE_CONCRETE_INSTRUCTION(AbnormalExit)
1151 };
1152 
1153 
1155  public:
1156  explicit HUnaryOperation(HValue* value) {
1157  SetOperandAt(0, value);
1158  }
1159 
1160  static HUnaryOperation* cast(HValue* value) {
1161  return reinterpret_cast<HUnaryOperation*>(value);
1162  }
1163 
1164  HValue* value() { return OperandAt(0); }
1165  virtual void PrintDataTo(StringStream* stream);
1166 };
1167 
1168 
1169 class HThrow: public HTemplateInstruction<2> {
1170  public:
1171  HThrow(HValue* context, HValue* value) {
1172  SetOperandAt(0, context);
1173  SetOperandAt(1, value);
1175  }
1176 
1178  return Representation::Tagged();
1179  }
1180 
1181  HValue* context() { return OperandAt(0); }
1182  HValue* value() { return OperandAt(1); }
1183 
1185 };
1186 
1187 
1189  public:
1190  explicit HUseConst(HValue* old_value) : HUnaryOperation(old_value) { }
1191 
1193  return Representation::None();
1194  }
1195 
1197 };
1198 
1199 
1201  public:
1202  HForceRepresentation(HValue* value, Representation required_representation) {
1203  SetOperandAt(0, value);
1204  set_representation(required_representation);
1205  }
1206 
1207  HValue* value() { return OperandAt(0); }
1208 
1209  virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
1210 
1212  return representation(); // Same as the output representation.
1213  }
1214 
1215  DECLARE_CONCRETE_INSTRUCTION(ForceRepresentation)
1216 };
1217 
1218 
1219 class HChange: public HUnaryOperation {
1220  public:
1221  HChange(HValue* value,
1222  Representation to,
1223  bool is_truncating,
1224  bool deoptimize_on_undefined)
1225  : HUnaryOperation(value) {
1226  ASSERT(!value->representation().IsNone() && !to.IsNone());
1227  ASSERT(!value->representation().Equals(to));
1228  set_representation(to);
1230  SetFlag(kUseGVN);
1231  if (deoptimize_on_undefined) SetFlag(kDeoptimizeOnUndefined);
1232  if (is_truncating) SetFlag(kTruncatingToInt32);
1233  if (to.IsTagged()) SetGVNFlag(kChangesNewSpacePromotion);
1234  }
1235 
1236  virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
1237  virtual HType CalculateInferredType();
1238  virtual HValue* Canonicalize();
1239 
1244  }
1247  }
1249  return from();
1250  }
1251 
1252  virtual Range* InferRange(Zone* zone);
1253 
1254  virtual void PrintDataTo(StringStream* stream);
1255 
1257 
1258  protected:
1259  virtual bool DataEquals(HValue* other) { return true; }
1260 };
1261 
1262 
1264  public:
1265  explicit HClampToUint8(HValue* value)
1266  : HUnaryOperation(value) {
1268  SetFlag(kUseGVN);
1269  }
1270 
1272  return Representation::None();
1273  }
1274 
1275  DECLARE_CONCRETE_INSTRUCTION(ClampToUint8)
1276 
1277  protected:
1278  virtual bool DataEquals(HValue* other) { return true; }
1279 };
1280 
1281 
1282 class HSimulate: public HInstruction {
1283  public:
1284  HSimulate(int ast_id, int pop_count, Zone* zone)
1285  : ast_id_(ast_id),
1286  pop_count_(pop_count),
1287  values_(2, zone),
1288  assigned_indexes_(2, zone),
1289  zone_(zone) {}
1290  virtual ~HSimulate() {}
1291 
1292  virtual void PrintDataTo(StringStream* stream);
1293 
1294  bool HasAstId() const { return ast_id_ != AstNode::kNoNumber; }
1295  int ast_id() const { return ast_id_; }
1296  void set_ast_id(int id) {
1297  ASSERT(!HasAstId());
1298  ast_id_ = id;
1299  }
1300 
1301  int pop_count() const { return pop_count_; }
1302  const ZoneList<HValue*>* values() const { return &values_; }
1303  int GetAssignedIndexAt(int index) const {
1304  ASSERT(HasAssignedIndexAt(index));
1305  return assigned_indexes_[index];
1306  }
1307  bool HasAssignedIndexAt(int index) const {
1308  return assigned_indexes_[index] != kNoIndex;
1309  }
1310  void AddAssignedValue(int index, HValue* value) {
1311  AddValue(index, value);
1312  }
1313  void AddPushedValue(HValue* value) {
1314  AddValue(kNoIndex, value);
1315  }
1316  virtual int OperandCount() { return values_.length(); }
1317  virtual HValue* OperandAt(int index) { return values_[index]; }
1318 
1320  return Representation::None();
1321  }
1322 
1324 
1325 #ifdef DEBUG
1326  virtual void Verify();
1327 #endif
1328 
1329  protected:
1330  virtual void InternalSetOperandAt(int index, HValue* value) {
1331  values_[index] = value;
1332  }
1333 
1334  private:
1335  static const int kNoIndex = -1;
1336  void AddValue(int index, HValue* value) {
1337  assigned_indexes_.Add(index, zone_);
1338  // Resize the list of pushed values.
1339  values_.Add(NULL, zone_);
1340  // Set the operand through the base method in HValue to make sure that the
1341  // use lists are correctly updated.
1342  SetOperandAt(values_.length() - 1, value);
1343  }
1344  int ast_id_;
1345  int pop_count_;
1346  ZoneList<HValue*> values_;
1347  ZoneList<int> assigned_indexes_;
1348  Zone* zone_;
1349 };
1350 
1351 
1353  public:
1354  enum Type {
1356  kBackwardsBranch
1357  };
1358 
1359  HStackCheck(HValue* context, Type type) : type_(type) {
1360  SetOperandAt(0, context);
1361  SetGVNFlag(kChangesNewSpacePromotion);
1362  }
1363 
1364  HValue* context() { return OperandAt(0); }
1365 
1367  return Representation::Tagged();
1368  }
1369 
1370  void Eliminate() {
1371  // The stack check eliminator might try to eliminate the same stack
1372  // check instruction multiple times.
1373  if (IsLinked()) {
1374  DeleteFromGraph();
1375  }
1376  }
1377 
1378  bool is_function_entry() { return type_ == kFunctionEntry; }
1379  bool is_backwards_branch() { return type_ == kBackwardsBranch; }
1380 
1381  DECLARE_CONCRETE_INSTRUCTION(StackCheck)
1382 
1383  private:
1384  Type type_;
1385 };
1386 
1387 
1389  public:
1391  int arguments_count,
1392  FunctionLiteral* function,
1393  CallKind call_kind,
1394  bool is_construct,
1395  Variable* arguments_var,
1396  ZoneList<HValue*>* arguments_values)
1397  : closure_(closure),
1398  arguments_count_(arguments_count),
1399  function_(function),
1400  call_kind_(call_kind),
1401  is_construct_(is_construct),
1402  arguments_var_(arguments_var),
1403  arguments_values_(arguments_values) {
1404  }
1405 
1406  virtual void PrintDataTo(StringStream* stream);
1407 
1408  Handle<JSFunction> closure() const { return closure_; }
1409  int arguments_count() const { return arguments_count_; }
1410  FunctionLiteral* function() const { return function_; }
1411  CallKind call_kind() const { return call_kind_; }
1412  bool is_construct() const { return is_construct_; }
1413 
1415  return Representation::None();
1416  }
1417 
1418  Variable* arguments_var() { return arguments_var_; }
1419  ZoneList<HValue*>* arguments_values() { return arguments_values_; }
1420 
1421  DECLARE_CONCRETE_INSTRUCTION(EnterInlined)
1422 
1423  private:
1424  Handle<JSFunction> closure_;
1425  int arguments_count_;
1426  FunctionLiteral* function_;
1427  CallKind call_kind_;
1428  bool is_construct_;
1429  Variable* arguments_var_;
1430  ZoneList<HValue*>* arguments_values_;
1431 };
1432 
1433 
1434 class HLeaveInlined: public HTemplateInstruction<0> {
1435  public:
1436  explicit HLeaveInlined(bool arguments_pushed)
1437  : arguments_pushed_(arguments_pushed) { }
1438 
1440  return Representation::None();
1441  }
1442 
1444  return arguments_pushed_;
1445  }
1446 
1447  DECLARE_CONCRETE_INSTRUCTION(LeaveInlined)
1448 
1449  private:
1450  bool arguments_pushed_;
1451 };
1452 
1453 
1455  public:
1456  explicit HPushArgument(HValue* value) : HUnaryOperation(value) {
1458  }
1459 
1461  return Representation::Tagged();
1462  }
1463 
1464  HValue* argument() { return OperandAt(0); }
1465 
1466  DECLARE_CONCRETE_INSTRUCTION(PushArgument)
1467 };
1468 
1469 
1470 class HThisFunction: public HTemplateInstruction<0> {
1471  public:
1472  explicit HThisFunction(Handle<JSFunction> closure) : closure_(closure) {
1474  SetFlag(kUseGVN);
1475  }
1476 
1478  return Representation::None();
1479  }
1480 
1481  Handle<JSFunction> closure() const { return closure_; }
1482 
1484 
1485  protected:
1486  virtual bool DataEquals(HValue* other) {
1487  HThisFunction* b = HThisFunction::cast(other);
1488  return *closure() == *b->closure();
1489  }
1490 
1491  private:
1492  Handle<JSFunction> closure_;
1493 };
1494 
1495 
1496 class HContext: public HTemplateInstruction<0> {
1497  public:
1500  SetFlag(kUseGVN);
1501  }
1502 
1504  return Representation::None();
1505  }
1506 
1508 
1509  protected:
1510  virtual bool DataEquals(HValue* other) { return true; }
1511 };
1512 
1513 
1515  public:
1516  explicit HOuterContext(HValue* inner) : HUnaryOperation(inner) {
1518  SetFlag(kUseGVN);
1519  }
1520 
1521  DECLARE_CONCRETE_INSTRUCTION(OuterContext);
1522 
1524  return Representation::Tagged();
1525  }
1526 
1527  protected:
1528  virtual bool DataEquals(HValue* other) { return true; }
1529 };
1530 
1531 
1533  public:
1535  Handle<FixedArray> pairs,
1536  int flags)
1537  : HUnaryOperation(context),
1538  pairs_(pairs),
1539  flags_(flags) {
1542  }
1543 
1544  HValue* context() { return OperandAt(0); }
1545  Handle<FixedArray> pairs() const { return pairs_; }
1546  int flags() const { return flags_; }
1547 
1548  DECLARE_CONCRETE_INSTRUCTION(DeclareGlobals)
1549 
1551  return Representation::Tagged();
1552  }
1553  private:
1554  Handle<FixedArray> pairs_;
1555  int flags_;
1556 };
1557 
1558 
1560  public:
1561  explicit HGlobalObject(HValue* context) : HUnaryOperation(context) {
1563  SetFlag(kUseGVN);
1564  }
1565 
1567 
1569  return Representation::Tagged();
1570  }
1571 
1572  protected:
1573  virtual bool DataEquals(HValue* other) { return true; }
1574 };
1575 
1576 
1578  public:
1579  explicit HGlobalReceiver(HValue* global_object)
1580  : HUnaryOperation(global_object) {
1582  SetFlag(kUseGVN);
1583  }
1584 
1585  DECLARE_CONCRETE_INSTRUCTION(GlobalReceiver)
1586 
1588  return Representation::Tagged();
1589  }
1590 
1591  protected:
1592  virtual bool DataEquals(HValue* other) { return true; }
1593 };
1594 
1595 
1596 template <int V>
1597 class HCall: public HTemplateInstruction<V> {
1598  public:
1599  // The argument count includes the receiver.
1600  explicit HCall<V>(int argument_count) : argument_count_(argument_count) {
1602  this->SetAllSideEffects();
1603  }
1604 
1606 
1607  virtual int argument_count() const { return argument_count_; }
1608 
1609  virtual bool IsCall() { return true; }
1610 
1611  private:
1612  int argument_count_;
1613 };
1614 
1615 
1616 class HUnaryCall: public HCall<1> {
1617  public:
1618  HUnaryCall(HValue* value, int argument_count)
1619  : HCall<1>(argument_count) {
1620  SetOperandAt(0, value);
1621  }
1622 
1624  return Representation::Tagged();
1625  }
1626 
1627  virtual void PrintDataTo(StringStream* stream);
1628 
1629  HValue* value() { return OperandAt(0); }
1630 };
1631 
1632 
1633 class HBinaryCall: public HCall<2> {
1634  public:
1635  HBinaryCall(HValue* first, HValue* second, int argument_count)
1636  : HCall<2>(argument_count) {
1637  SetOperandAt(0, first);
1638  SetOperandAt(1, second);
1639  }
1640 
1641  virtual void PrintDataTo(StringStream* stream);
1642 
1644  return Representation::Tagged();
1645  }
1646 
1647  HValue* first() { return OperandAt(0); }
1648  HValue* second() { return OperandAt(1); }
1649 };
1650 
1651 
1653  public:
1654  HInvokeFunction(HValue* context, HValue* function, int argument_count)
1655  : HBinaryCall(context, function, argument_count) {
1656  }
1657 
1659  HValue* function,
1660  Handle<JSFunction> known_function,
1661  int argument_count)
1662  : HBinaryCall(context, function, argument_count),
1663  known_function_(known_function) {
1664  }
1665 
1667  return Representation::Tagged();
1668  }
1669 
1670  HValue* context() { return first(); }
1671  HValue* function() { return second(); }
1672  Handle<JSFunction> known_function() { return known_function_; }
1673 
1674  DECLARE_CONCRETE_INSTRUCTION(InvokeFunction)
1675 
1676  private:
1677  Handle<JSFunction> known_function_;
1678 };
1679 
1680 
1681 class HCallConstantFunction: public HCall<0> {
1682  public:
1683  HCallConstantFunction(Handle<JSFunction> function, int argument_count)
1684  : HCall<0>(argument_count), function_(function) { }
1685 
1686  Handle<JSFunction> function() const { return function_; }
1687 
1688  bool IsApplyFunction() const {
1689  return function_->code() ==
1690  Isolate::Current()->builtins()->builtin(Builtins::kFunctionApply);
1691  }
1692 
1693  virtual void PrintDataTo(StringStream* stream);
1694 
1696  return Representation::None();
1697  }
1698 
1699  DECLARE_CONCRETE_INSTRUCTION(CallConstantFunction)
1700 
1701  private:
1702  Handle<JSFunction> function_;
1703 };
1704 
1705 
1706 class HCallKeyed: public HBinaryCall {
1707  public:
1708  HCallKeyed(HValue* context, HValue* key, int argument_count)
1709  : HBinaryCall(context, key, argument_count) {
1710  }
1711 
1713  return Representation::Tagged();
1714  }
1715 
1716  HValue* context() { return first(); }
1717  HValue* key() { return second(); }
1718 
1719  DECLARE_CONCRETE_INSTRUCTION(CallKeyed)
1720 };
1721 
1722 
1723 class HCallNamed: public HUnaryCall {
1724  public:
1725  HCallNamed(HValue* context, Handle<String> name, int argument_count)
1726  : HUnaryCall(context, argument_count), name_(name) {
1727  }
1728 
1729  virtual void PrintDataTo(StringStream* stream);
1730 
1731  HValue* context() { return value(); }
1732  Handle<String> name() const { return name_; }
1733 
1734  DECLARE_CONCRETE_INSTRUCTION(CallNamed)
1735 
1737  return Representation::Tagged();
1738  }
1739 
1740  private:
1742 };
1743 
1744 
1746  public:
1747  HCallFunction(HValue* context, HValue* function, int argument_count)
1748  : HBinaryCall(context, function, argument_count) {
1749  }
1750 
1751  HValue* context() { return first(); }
1752  HValue* function() { return second(); }
1753 
1755  return Representation::Tagged();
1756  }
1757 
1758  DECLARE_CONCRETE_INSTRUCTION(CallFunction)
1759 };
1760 
1761 
1762 class HCallGlobal: public HUnaryCall {
1763  public:
1764  HCallGlobal(HValue* context, Handle<String> name, int argument_count)
1765  : HUnaryCall(context, argument_count), name_(name) {
1766  }
1767 
1768  virtual void PrintDataTo(StringStream* stream);
1769 
1770  HValue* context() { return value(); }
1771  Handle<String> name() const { return name_; }
1772 
1774  return Representation::Tagged();
1775  }
1776 
1777  DECLARE_CONCRETE_INSTRUCTION(CallGlobal)
1778 
1779  private:
1780  Handle<String> name_;
1781 };
1782 
1783 
1784 class HCallKnownGlobal: public HCall<0> {
1785  public:
1786  HCallKnownGlobal(Handle<JSFunction> target, int argument_count)
1787  : HCall<0>(argument_count), target_(target) { }
1788 
1789  virtual void PrintDataTo(StringStream* stream);
1790 
1791  Handle<JSFunction> target() const { return target_; }
1792 
1794  return Representation::None();
1795  }
1796 
1797  DECLARE_CONCRETE_INSTRUCTION(CallKnownGlobal)
1798 
1799  private:
1800  Handle<JSFunction> target_;
1801 };
1802 
1803 
1804 class HCallNew: public HBinaryCall {
1805  public:
1806  HCallNew(HValue* context, HValue* constructor, int argument_count)
1807  : HBinaryCall(context, constructor, argument_count) {
1808  }
1809 
1811  return Representation::Tagged();
1812  }
1813 
1814  HValue* context() { return first(); }
1815  HValue* constructor() { return second(); }
1816 
1818 };
1819 
1820 
1821 class HCallRuntime: public HCall<1> {
1822  public:
1825  const Runtime::Function* c_function,
1826  int argument_count)
1827  : HCall<1>(argument_count), c_function_(c_function), name_(name) {
1828  SetOperandAt(0, context);
1829  }
1830 
1831  virtual void PrintDataTo(StringStream* stream);
1832 
1833  HValue* context() { return OperandAt(0); }
1834  const Runtime::Function* function() const { return c_function_; }
1835  Handle<String> name() const { return name_; }
1836 
1838  return Representation::Tagged();
1839  }
1840 
1842 
1843  private:
1844  const Runtime::Function* c_function_;
1845  Handle<String> name_;
1846 };
1847 
1848 
1849 class HJSArrayLength: public HTemplateInstruction<2> {
1850  public:
1851  HJSArrayLength(HValue* value, HValue* typecheck,
1852  HType type = HType::Tagged()) {
1853  set_type(type);
1854  // The length of an array is stored as a tagged value in the array
1855  // object. It is guaranteed to be 32 bit integer, but it can be
1856  // represented as either a smi or heap number.
1857  SetOperandAt(0, value);
1858  SetOperandAt(1, typecheck);
1860  SetFlag(kUseGVN);
1861  SetGVNFlag(kDependsOnArrayLengths);
1862  SetGVNFlag(kDependsOnMaps);
1863  }
1864 
1866  return Representation::Tagged();
1867  }
1868 
1869  virtual void PrintDataTo(StringStream* stream);
1870 
1871  HValue* value() { return OperandAt(0); }
1872  HValue* typecheck() { return OperandAt(1); }
1873 
1874  DECLARE_CONCRETE_INSTRUCTION(JSArrayLength)
1875 
1876  protected:
1877  virtual bool DataEquals(HValue* other_raw) { return true; }
1878 };
1879 
1880 
1882  public:
1883  explicit HFixedArrayBaseLength(HValue* value) : HUnaryOperation(value) {
1885  SetFlag(kUseGVN);
1886  SetGVNFlag(kDependsOnArrayLengths);
1887  }
1888 
1890  return Representation::Tagged();
1891  }
1892 
1893  DECLARE_CONCRETE_INSTRUCTION(FixedArrayBaseLength)
1894 
1895  protected:
1896  virtual bool DataEquals(HValue* other) { return true; }
1897 };
1898 
1899 
1901  public:
1902  explicit HElementsKind(HValue* value) : HUnaryOperation(value) {
1904  SetFlag(kUseGVN);
1905  SetGVNFlag(kDependsOnElementsKind);
1906  }
1907 
1909  return Representation::Tagged();
1910  }
1911 
1913 
1914  protected:
1915  virtual bool DataEquals(HValue* other) { return true; }
1916 };
1917 
1918 
1919 class HBitNot: public HUnaryOperation {
1920  public:
1921  explicit HBitNot(HValue* value) : HUnaryOperation(value) {
1923  SetFlag(kUseGVN);
1925  }
1926 
1928  return Representation::Integer32();
1929  }
1930  virtual HType CalculateInferredType();
1931 
1932  virtual HValue* Canonicalize();
1933 
1935 
1936  protected:
1937  virtual bool DataEquals(HValue* other) { return true; }
1938 };
1939 
1940 
1941 class HUnaryMathOperation: public HTemplateInstruction<2> {
1942  public:
1944  : op_(op) {
1945  SetOperandAt(0, context);
1946  SetOperandAt(1, value);
1947  switch (op) {
1948  case kMathFloor:
1949  case kMathRound:
1950  case kMathCeil:
1952  break;
1953  case kMathAbs:
1956  SetGVNFlag(kChangesNewSpacePromotion);
1957  break;
1958  case kMathSqrt:
1959  case kMathPowHalf:
1960  case kMathLog:
1961  case kMathSin:
1962  case kMathCos:
1963  case kMathTan:
1965  SetGVNFlag(kChangesNewSpacePromotion);
1966  break;
1967  default:
1968  UNREACHABLE();
1969  }
1970  SetFlag(kUseGVN);
1971  }
1972 
1973  HValue* context() { return OperandAt(0); }
1974  HValue* value() { return OperandAt(1); }
1975 
1976  virtual void PrintDataTo(StringStream* stream);
1977 
1978  virtual HType CalculateInferredType();
1979 
1980  virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
1981 
1983  if (index == 0) {
1984  return Representation::Tagged();
1985  } else {
1986  switch (op_) {
1987  case kMathFloor:
1988  case kMathRound:
1989  case kMathCeil:
1990  case kMathSqrt:
1991  case kMathPowHalf:
1992  case kMathLog:
1993  case kMathSin:
1994  case kMathCos:
1995  case kMathTan:
1996  return Representation::Double();
1997  case kMathAbs:
1998  return representation();
1999  default:
2000  UNREACHABLE();
2001  return Representation::None();
2002  }
2003  }
2004  }
2005 
2006  virtual HValue* Canonicalize();
2007 
2008  BuiltinFunctionId op() const { return op_; }
2009  const char* OpName() const;
2010 
2011  DECLARE_CONCRETE_INSTRUCTION(UnaryMathOperation)
2012 
2013  protected:
2014  virtual bool DataEquals(HValue* other) {
2016  return op_ == b->op();
2017  }
2018 
2019  private:
2020  BuiltinFunctionId op_;
2021 };
2022 
2023 
2025  public:
2026  explicit HLoadElements(HValue* value) : HUnaryOperation(value) {
2028  SetFlag(kUseGVN);
2029  SetGVNFlag(kDependsOnElementsPointer);
2030  }
2031 
2033  return Representation::Tagged();
2034  }
2035 
2036  DECLARE_CONCRETE_INSTRUCTION(LoadElements)
2037 
2038  protected:
2039  virtual bool DataEquals(HValue* other) { return true; }
2040 };
2041 
2042 
2044  public:
2046  : HUnaryOperation(value) {
2048  // The result of this instruction is idempotent as long as its inputs don't
2049  // change. The external array of a specialized array elements object cannot
2050  // change once set, so it's no necessary to introduce any additional
2051  // dependencies on top of the inputs.
2052  SetFlag(kUseGVN);
2053  }
2054 
2056  return Representation::Tagged();
2057  }
2058 
2059  DECLARE_CONCRETE_INSTRUCTION(LoadExternalArrayPointer)
2060 
2061  protected:
2062  virtual bool DataEquals(HValue* other) { return true; }
2063 };
2064 
2065 
2066 class HCheckMaps: public HTemplateInstruction<2> {
2067  public:
2068  HCheckMaps(HValue* value, Handle<Map> map, Zone* zone,
2069  HValue* typecheck = NULL) {
2070  SetOperandAt(0, value);
2071  // If callers don't depend on a typecheck, they can pass in NULL. In that
2072  // case we use a copy of the |value| argument as a dummy value.
2073  SetOperandAt(1, typecheck != NULL ? typecheck : value);
2075  SetFlag(kUseGVN);
2076  SetGVNFlag(kDependsOnMaps);
2077  SetGVNFlag(kDependsOnElementsKind);
2078  map_set()->Add(map, zone);
2079  }
2080  HCheckMaps(HValue* value, SmallMapList* maps, Zone* zone) {
2081  SetOperandAt(0, value);
2082  SetOperandAt(1, value);
2084  SetFlag(kUseGVN);
2085  SetGVNFlag(kDependsOnMaps);
2086  SetGVNFlag(kDependsOnElementsKind);
2087  for (int i = 0; i < maps->length(); i++) {
2088  map_set()->Add(maps->at(i), zone);
2089  }
2090  map_set()->Sort();
2091  }
2092 
2094  Zone* zone) {
2095  HCheckMaps* check_map = new(zone) HCheckMaps(object, map, zone);
2096  SmallMapList* map_set = check_map->map_set();
2097 
2098  // Since transitioned elements maps of the initial map don't fail the map
2099  // check, the CheckMaps instruction doesn't need to depend on ElementsKinds.
2100  check_map->ClearGVNFlag(kDependsOnElementsKind);
2101 
2102  ElementsKind kind = map->elements_kind();
2103  bool packed = IsFastPackedElementsKind(kind);
2104  while (CanTransitionToMoreGeneralFastElementsKind(kind, packed)) {
2105  kind = GetNextMoreGeneralFastElementsKind(kind, packed);
2106  Map* transitioned_map =
2107  map->LookupElementsTransitionMap(kind);
2108  if (transitioned_map) {
2109  map_set->Add(Handle<Map>(transitioned_map), zone);
2110  }
2111  };
2112  map_set->Sort();
2113  return check_map;
2114  }
2115 
2117  return Representation::Tagged();
2118  }
2119  virtual void PrintDataTo(StringStream* stream);
2120  virtual HType CalculateInferredType();
2121 
2122  HValue* value() { return OperandAt(0); }
2123  SmallMapList* map_set() { return &map_set_; }
2124 
2125  DECLARE_CONCRETE_INSTRUCTION(CheckMaps)
2126 
2127  protected:
2128  virtual bool DataEquals(HValue* other) {
2129  HCheckMaps* b = HCheckMaps::cast(other);
2130  // Relies on the fact that map_set has been sorted before.
2131  if (map_set()->length() != b->map_set()->length()) return false;
2132  for (int i = 0; i < map_set()->length(); i++) {
2133  if (!map_set()->at(i).is_identical_to(b->map_set()->at(i))) return false;
2134  }
2135  return true;
2136  }
2137 
2138  private:
2139  SmallMapList map_set_;
2140 };
2141 
2142 
2144  public:
2146  : HUnaryOperation(value), target_(function) {
2148  SetFlag(kUseGVN);
2149  }
2150 
2152  return Representation::Tagged();
2153  }
2154  virtual void PrintDataTo(StringStream* stream);
2155  virtual HType CalculateInferredType();
2156 
2157 #ifdef DEBUG
2158  virtual void Verify();
2159 #endif
2160 
2161  Handle<JSFunction> target() const { return target_; }
2162 
2163  DECLARE_CONCRETE_INSTRUCTION(CheckFunction)
2164 
2165  protected:
2166  virtual bool DataEquals(HValue* other) {
2168  return target_.is_identical_to(b->target());
2169  }
2170 
2171  private:
2172  Handle<JSFunction> target_;
2173 };
2174 
2175 
2177  public:
2179  return new(zone) HCheckInstanceType(value, IS_SPEC_OBJECT);
2180  }
2181  static HCheckInstanceType* NewIsJSArray(HValue* value, Zone* zone) {
2182  return new(zone) HCheckInstanceType(value, IS_JS_ARRAY);
2183  }
2184  static HCheckInstanceType* NewIsString(HValue* value, Zone* zone) {
2185  return new(zone) HCheckInstanceType(value, IS_STRING);
2186  }
2187  static HCheckInstanceType* NewIsSymbol(HValue* value, Zone* zone) {
2188  return new(zone) HCheckInstanceType(value, IS_SYMBOL);
2189  }
2190 
2191  virtual void PrintDataTo(StringStream* stream);
2192 
2194  return Representation::Tagged();
2195  }
2196 
2197  virtual HValue* Canonicalize();
2198 
2199  bool is_interval_check() const { return check_ <= LAST_INTERVAL_CHECK; }
2200  void GetCheckInterval(InstanceType* first, InstanceType* last);
2201  void GetCheckMaskAndTag(uint8_t* mask, uint8_t* tag);
2202 
2203  DECLARE_CONCRETE_INSTRUCTION(CheckInstanceType)
2204 
2205  protected:
2206  // TODO(ager): It could be nice to allow the ommision of instance
2207  // type checks if we have already performed an instance type check
2208  // with a larger range.
2209  virtual bool DataEquals(HValue* other) {
2211  return check_ == b->check_;
2212  }
2213 
2214  private:
2215  enum Check {
2216  IS_SPEC_OBJECT,
2217  IS_JS_ARRAY,
2218  IS_STRING,
2219  IS_SYMBOL,
2220  LAST_INTERVAL_CHECK = IS_JS_ARRAY
2221  };
2222 
2223  const char* GetCheckName();
2224 
2225  HCheckInstanceType(HValue* value, Check check)
2226  : HUnaryOperation(value), check_(check) {
2228  SetFlag(kUseGVN);
2229  }
2230 
2231  const Check check_;
2232 };
2233 
2234 
2236  public:
2237  explicit HCheckNonSmi(HValue* value) : HUnaryOperation(value) {
2239  SetFlag(kUseGVN);
2240  }
2241 
2243  return Representation::Tagged();
2244  }
2245 
2246  virtual HType CalculateInferredType();
2247 
2248 #ifdef DEBUG
2249  virtual void Verify();
2250 #endif
2251 
2252  virtual HValue* Canonicalize() {
2253  HType value_type = value()->type();
2254  if (!value_type.IsUninitialized() &&
2255  (value_type.IsHeapNumber() ||
2256  value_type.IsString() ||
2257  value_type.IsBoolean() ||
2258  value_type.IsNonPrimitive())) {
2259  return NULL;
2260  }
2261  return this;
2262  }
2263 
2264  DECLARE_CONCRETE_INSTRUCTION(CheckNonSmi)
2265 
2266  protected:
2267  virtual bool DataEquals(HValue* other) { return true; }
2268 };
2269 
2270 
2271 class HCheckPrototypeMaps: public HTemplateInstruction<0> {
2272  public:
2274  : prototype_(prototype), holder_(holder) {
2275  SetFlag(kUseGVN);
2276  SetGVNFlag(kDependsOnMaps);
2277  }
2278 
2279 #ifdef DEBUG
2280  virtual void Verify();
2281 #endif
2282 
2283  Handle<JSObject> prototype() const { return prototype_; }
2284  Handle<JSObject> holder() const { return holder_; }
2285 
2286  DECLARE_CONCRETE_INSTRUCTION(CheckPrototypeMaps)
2287 
2289  return Representation::None();
2290  }
2291 
2292  virtual intptr_t Hashcode() {
2293  ASSERT(!HEAP->IsAllocationAllowed());
2294  intptr_t hash = reinterpret_cast<intptr_t>(*prototype());
2295  hash = 17 * hash + reinterpret_cast<intptr_t>(*holder());
2296  return hash;
2297  }
2298 
2299  protected:
2300  virtual bool DataEquals(HValue* other) {
2302  return prototype_.is_identical_to(b->prototype()) &&
2303  holder_.is_identical_to(b->holder());
2304  }
2305 
2306  private:
2307  Handle<JSObject> prototype_;
2308  Handle<JSObject> holder_;
2309 };
2310 
2311 
2313  public:
2314  explicit HCheckSmi(HValue* value) : HUnaryOperation(value) {
2316  SetFlag(kUseGVN);
2317  }
2318 
2320  return Representation::Tagged();
2321  }
2322  virtual HType CalculateInferredType();
2323 
2324 #ifdef DEBUG
2325  virtual void Verify();
2326 #endif
2327 
2329 
2330  protected:
2331  virtual bool DataEquals(HValue* other) { return true; }
2332 };
2333 
2334 
2335 class HPhi: public HValue {
2336  public:
2337  HPhi(int merged_index, Zone* zone)
2338  : inputs_(2, zone),
2339  merged_index_(merged_index),
2340  phi_id_(-1),
2341  is_live_(false),
2342  is_convertible_to_integer_(true) {
2343  for (int i = 0; i < Representation::kNumRepresentations; i++) {
2344  non_phi_uses_[i] = 0;
2345  indirect_uses_[i] = 0;
2346  }
2347  ASSERT(merged_index >= 0);
2350  }
2351 
2353 
2354  virtual Range* InferRange(Zone* zone);
2356  return representation();
2357  }
2358  virtual HType CalculateInferredType();
2359  virtual int OperandCount() { return inputs_.length(); }
2360  virtual HValue* OperandAt(int index) { return inputs_[index]; }
2361  HValue* GetRedundantReplacement();
2362  void AddInput(HValue* value);
2363  bool HasRealUses();
2364 
2365  bool IsReceiver() { return merged_index_ == 0; }
2366 
2367  int merged_index() const { return merged_index_; }
2368 
2369  virtual void PrintTo(StringStream* stream);
2370 
2371 #ifdef DEBUG
2372  virtual void Verify();
2373 #endif
2374 
2375  void InitRealUses(int id);
2376  void AddNonPhiUsesFrom(HPhi* other);
2377  void AddIndirectUsesTo(int* use_count);
2378 
2379  int tagged_non_phi_uses() const {
2380  return non_phi_uses_[Representation::kTagged];
2381  }
2382  int int32_non_phi_uses() const {
2383  return non_phi_uses_[Representation::kInteger32];
2384  }
2385  int double_non_phi_uses() const {
2386  return non_phi_uses_[Representation::kDouble];
2387  }
2388  int tagged_indirect_uses() const {
2389  return indirect_uses_[Representation::kTagged];
2390  }
2391  int int32_indirect_uses() const {
2392  return indirect_uses_[Representation::kInteger32];
2393  }
2394  int double_indirect_uses() const {
2395  return indirect_uses_[Representation::kDouble];
2396  }
2397  int phi_id() { return phi_id_; }
2398  bool is_live() { return is_live_; }
2399  void set_is_live(bool b) { is_live_ = b; }
2400 
2401  static HPhi* cast(HValue* value) {
2402  ASSERT(value->IsPhi());
2403  return reinterpret_cast<HPhi*>(value);
2404  }
2405  virtual Opcode opcode() const { return HValue::kPhi; }
2406 
2407  virtual bool IsConvertibleToInteger() const {
2408  return is_convertible_to_integer_;
2409  }
2410 
2412  is_convertible_to_integer_ = b;
2413  }
2414 
2416  for (int i = 0; i < OperandCount(); ++i) {
2417  if (!OperandAt(i)->IsConvertibleToInteger()) {
2418  return false;
2419  }
2420  }
2421  return true;
2422  }
2423 
2424  void ResetInteger32Uses();
2425 
2426  protected:
2427  virtual void DeleteFromGraph();
2428  virtual void InternalSetOperandAt(int index, HValue* value) {
2429  inputs_[index] = value;
2430  }
2431 
2432  private:
2433  ZoneList<HValue*> inputs_;
2434  int merged_index_;
2435 
2436  int non_phi_uses_[Representation::kNumRepresentations];
2437  int indirect_uses_[Representation::kNumRepresentations];
2438  int phi_id_;
2439  bool is_live_;
2440  bool is_convertible_to_integer_;
2441 };
2442 
2443 
2444 class HArgumentsObject: public HTemplateInstruction<0> {
2445  public:
2449  }
2450 
2452  return Representation::None();
2453  }
2454 
2455  DECLARE_CONCRETE_INSTRUCTION(ArgumentsObject)
2456 };
2457 
2458 
2459 class HConstant: public HTemplateInstruction<0> {
2460  public:
2462 
2463  Handle<Object> handle() const { return handle_; }
2464 
2465  bool InOldSpace() const { return !HEAP->InNewSpace(*handle_); }
2466 
2467  bool ImmortalImmovable() const {
2468  Heap* heap = HEAP;
2469  if (*handle_ == heap->undefined_value()) return true;
2470  if (*handle_ == heap->null_value()) return true;
2471  if (*handle_ == heap->true_value()) return true;
2472  if (*handle_ == heap->false_value()) return true;
2473  if (*handle_ == heap->the_hole_value()) return true;
2474  if (*handle_ == heap->minus_zero_value()) return true;
2475  if (*handle_ == heap->nan_value()) return true;
2476  if (*handle_ == heap->empty_string()) return true;
2477  return false;
2478  }
2479 
2481  return Representation::None();
2482  }
2483 
2484  virtual bool IsConvertibleToInteger() const {
2485  if (handle_->IsSmi()) return true;
2486  if (handle_->IsHeapNumber() &&
2487  (HeapNumber::cast(*handle_)->value() ==
2488  static_cast<double>(NumberToInt32(*handle_)))) return true;
2489  return false;
2490  }
2491 
2492  virtual bool EmitAtUses() { return !representation().IsDouble(); }
2493  virtual HValue* Canonicalize();
2494  virtual void PrintDataTo(StringStream* stream);
2495  virtual HType CalculateInferredType();
2496  bool IsInteger() const { return handle_->IsSmi(); }
2497  HConstant* CopyToRepresentation(Representation r, Zone* zone) const;
2498  HConstant* CopyToTruncatedInt32(Zone* zone) const;
2499  bool HasInteger32Value() const { return has_int32_value_; }
2501  ASSERT(HasInteger32Value());
2502  return int32_value_;
2503  }
2504  bool HasDoubleValue() const { return has_double_value_; }
2505  double DoubleValue() const {
2506  ASSERT(HasDoubleValue());
2507  return double_value_;
2508  }
2509  bool HasNumberValue() const { return has_int32_value_ || has_double_value_; }
2511  ASSERT(HasNumberValue());
2512  if (has_int32_value_) return int32_value_;
2513  return DoubleToInt32(double_value_);
2514  }
2515  bool HasStringValue() const { return handle_->IsString(); }
2516 
2517  bool ToBoolean() const;
2518 
2519  virtual intptr_t Hashcode() {
2520  ASSERT(!HEAP->allow_allocation(false));
2521  intptr_t hash = reinterpret_cast<intptr_t>(*handle());
2522  // Prevent smis from having fewer hash values when truncated to
2523  // the least significant bits.
2524  const int kShiftSize = kSmiShiftSize + kSmiTagSize;
2525  STATIC_ASSERT(kShiftSize != 0);
2526  return hash ^ (hash >> kShiftSize);
2527  }
2528 
2529 #ifdef DEBUG
2530  virtual void Verify() { }
2531 #endif
2532 
2534 
2535  protected:
2536  virtual Range* InferRange(Zone* zone);
2537 
2538  virtual bool DataEquals(HValue* other) {
2539  HConstant* other_constant = HConstant::cast(other);
2540  return handle().is_identical_to(other_constant->handle());
2541  }
2542 
2543  private:
2544  Handle<Object> handle_;
2545 
2546  // The following two values represent the int32 and the double value of the
2547  // given constant if there is a lossless conversion between the constant
2548  // and the specific representation.
2549  bool has_int32_value_ : 1;
2550  bool has_double_value_ : 1;
2551  int32_t int32_value_;
2552  double double_value_;
2553 };
2554 
2555 
2556 class HBinaryOperation: public HTemplateInstruction<3> {
2557  public:
2558  HBinaryOperation(HValue* context, HValue* left, HValue* right) {
2559  ASSERT(left != NULL && right != NULL);
2560  SetOperandAt(0, context);
2561  SetOperandAt(1, left);
2562  SetOperandAt(2, right);
2563  }
2564 
2565  HValue* context() { return OperandAt(0); }
2566  HValue* left() { return OperandAt(1); }
2567  HValue* right() { return OperandAt(2); }
2568 
2569  // TODO(kasperl): Move these helpers to the IA-32 Lithium
2570  // instruction sequence builder.
2572  if (IsCommutative() && left()->IsConstant()) return right();
2573  return left();
2574  }
2575 
2577  if (IsCommutative() && left()->IsConstant()) return left();
2578  return right();
2579  }
2580 
2581  virtual bool IsCommutative() const { return false; }
2582 
2583  virtual void PrintDataTo(StringStream* stream);
2584 };
2585 
2586 
2587 class HWrapReceiver: public HTemplateInstruction<2> {
2588  public:
2589  HWrapReceiver(HValue* receiver, HValue* function) {
2591  SetOperandAt(0, receiver);
2592  SetOperandAt(1, function);
2593  }
2594 
2596  return Representation::Tagged();
2597  }
2598 
2599  HValue* receiver() { return OperandAt(0); }
2600  HValue* function() { return OperandAt(1); }
2601 
2602  virtual HValue* Canonicalize();
2603 
2604  DECLARE_CONCRETE_INSTRUCTION(WrapReceiver)
2605 };
2606 
2607 
2608 class HApplyArguments: public HTemplateInstruction<4> {
2609  public:
2611  HValue* receiver,
2612  HValue* length,
2613  HValue* elements) {
2615  SetOperandAt(0, function);
2616  SetOperandAt(1, receiver);
2617  SetOperandAt(2, length);
2618  SetOperandAt(3, elements);
2620  }
2621 
2623  // The length is untagged, all other inputs are tagged.
2624  return (index == 2)
2627  }
2628 
2629  HValue* function() { return OperandAt(0); }
2630  HValue* receiver() { return OperandAt(1); }
2631  HValue* length() { return OperandAt(2); }
2632  HValue* elements() { return OperandAt(3); }
2633 
2634  DECLARE_CONCRETE_INSTRUCTION(ApplyArguments)
2635 };
2636 
2637 
2638 class HArgumentsElements: public HTemplateInstruction<0> {
2639  public:
2640  explicit HArgumentsElements(bool from_inlined) : from_inlined_(from_inlined) {
2641  // The value produced by this instruction is a pointer into the stack
2642  // that looks as if it was a smi because of alignment.
2644  SetFlag(kUseGVN);
2645  }
2646 
2647  DECLARE_CONCRETE_INSTRUCTION(ArgumentsElements)
2648 
2650  return Representation::None();
2651  }
2652 
2653  bool from_inlined() const { return from_inlined_; }
2654 
2655  protected:
2656  virtual bool DataEquals(HValue* other) { return true; }
2657 
2659 };
2660 
2661 
2663  public:
2664  explicit HArgumentsLength(HValue* value) : HUnaryOperation(value) {
2666  SetFlag(kUseGVN);
2667  }
2668 
2670  return Representation::Tagged();
2671  }
2672 
2673  DECLARE_CONCRETE_INSTRUCTION(ArgumentsLength)
2674 
2675  protected:
2676  virtual bool DataEquals(HValue* other) { return true; }
2677 };
2678 
2679 
2680 class HAccessArgumentsAt: public HTemplateInstruction<3> {
2681  public:
2682  HAccessArgumentsAt(HValue* arguments, HValue* length, HValue* index) {
2684  SetFlag(kUseGVN);
2685  SetOperandAt(0, arguments);
2686  SetOperandAt(1, length);
2687  SetOperandAt(2, index);
2688  }
2689 
2690  virtual void PrintDataTo(StringStream* stream);
2691 
2693  // The arguments elements is considered tagged.
2694  return index == 0
2697  }
2698 
2699  HValue* arguments() { return OperandAt(0); }
2700  HValue* length() { return OperandAt(1); }
2701  HValue* index() { return OperandAt(2); }
2702 
2703  DECLARE_CONCRETE_INSTRUCTION(AccessArgumentsAt)
2704 
2705  virtual bool DataEquals(HValue* other) { return true; }
2706 };
2707 
2708 
2709 class HBoundsCheck: public HTemplateInstruction<2> {
2710  public:
2711  HBoundsCheck(HValue* index, HValue* length) {
2712  SetOperandAt(0, index);
2713  SetOperandAt(1, length);
2715  SetFlag(kUseGVN);
2716  }
2717 
2719  return Representation::Integer32();
2720  }
2721 
2722  virtual void PrintDataTo(StringStream* stream);
2723 
2724  HValue* index() { return OperandAt(0); }
2725  HValue* length() { return OperandAt(1); }
2726 
2727  DECLARE_CONCRETE_INSTRUCTION(BoundsCheck)
2728 
2729  protected:
2730  virtual bool DataEquals(HValue* other) { return true; }
2731 };
2732 
2733 
2735  public:
2736  HBitwiseBinaryOperation(HValue* context, HValue* left, HValue* right)
2737  : HBinaryOperation(context, left, right) {
2741  observed_input_representation_[0] = Representation::Tagged();
2742  observed_input_representation_[1] = Representation::None();
2743  observed_input_representation_[2] = Representation::None();
2744  }
2745 
2747  return index == 0
2749  : representation();
2750  }
2751 
2753  if (!to.IsTagged()) {
2754  ASSERT(to.IsInteger32());
2757  SetFlag(kUseGVN);
2758  }
2759  }
2760 
2761  virtual HType CalculateInferredType();
2762 
2764  return observed_input_representation_[index];
2765  }
2766 
2768  observed_input_representation_[1] = r;
2769  observed_input_representation_[2] = r;
2770  }
2771 
2772  DECLARE_ABSTRACT_INSTRUCTION(BitwiseBinaryOperation)
2773 
2774  private:
2775  Representation observed_input_representation_[3];
2776 };
2777 
2778 
2780  public:
2781  HMathFloorOfDiv(HValue* context, HValue* left, HValue* right)
2782  : HBinaryOperation(context, left, right) {
2784  SetFlag(kUseGVN);
2785  }
2786 
2788  return Representation::Integer32();
2789  }
2790 
2791  DECLARE_CONCRETE_INSTRUCTION(MathFloorOfDiv)
2792 
2793  protected:
2794  virtual bool DataEquals(HValue* other) { return true; }
2795 };
2796 
2797 
2799  public:
2801  : HBinaryOperation(context, left, right) {
2805  }
2806 
2808  if (!to.IsTagged()) {
2810  SetFlag(kUseGVN);
2811  }
2812  }
2813 
2814  virtual HType CalculateInferredType();
2816  return index == 0
2818  : representation();
2819  }
2820 
2822  if (left()->representation().Equals(right()->representation())) {
2823  return left()->representation();
2824  }
2826  }
2827 };
2828 
2829 
2831  public:
2833  HValue* left,
2834  HValue* right,
2835  Token::Value token)
2836  : HBinaryOperation(context, left, right), token_(token) {
2837  ASSERT(Token::IsCompareOp(token));
2840  }
2841 
2843  return Representation::Tagged();
2844  }
2845 
2847  return Representation::Tagged();
2848  }
2849 
2850  Token::Value token() const { return token_; }
2851  virtual void PrintDataTo(StringStream* stream);
2852 
2853  virtual HType CalculateInferredType();
2854 
2855  DECLARE_CONCRETE_INSTRUCTION(CompareGeneric)
2856 
2857  private:
2858  Token::Value token_;
2859 };
2860 
2861 
2863  public:
2865  : token_(token) {
2866  ASSERT(Token::IsCompareOp(token));
2867  SetOperandAt(0, left);
2868  SetOperandAt(1, right);
2869  }
2870 
2871  HValue* left() { return OperandAt(0); }
2872  HValue* right() { return OperandAt(1); }
2873  Token::Value token() const { return token_; }
2874 
2875  void SetInputRepresentation(Representation r);
2877  return input_representation_;
2878  }
2879 
2881  return input_representation_;
2882  }
2883  virtual void PrintDataTo(StringStream* stream);
2884 
2885  DECLARE_CONCRETE_INSTRUCTION(CompareIDAndBranch)
2886 
2887  private:
2888  Representation input_representation_;
2889  Token::Value token_;
2890 };
2891 
2892 
2893 class HCompareObjectEqAndBranch: public HTemplateControlInstruction<2, 2> {
2894  public:
2896  SetOperandAt(0, left);
2897  SetOperandAt(1, right);
2898  }
2899 
2900  HValue* left() { return OperandAt(0); }
2901  HValue* right() { return OperandAt(1); }
2902 
2903  virtual void PrintDataTo(StringStream* stream);
2904 
2906  return Representation::Tagged();
2907  }
2908 
2909  DECLARE_CONCRETE_INSTRUCTION(CompareObjectEqAndBranch)
2910 };
2911 
2912 
2913 class HCompareConstantEqAndBranch: public HUnaryControlInstruction {
2914  public:
2916  : HUnaryControlInstruction(left, NULL, NULL), op_(op), right_(right) {
2917  ASSERT(op == Token::EQ_STRICT);
2918  }
2919 
2920  Token::Value op() const { return op_; }
2921  HValue* left() { return value(); }
2922  int right() const { return right_; }
2923 
2925  return Representation::Integer32();
2926  }
2927 
2928  DECLARE_CONCRETE_INSTRUCTION(CompareConstantEqAndBranch);
2929 
2930  private:
2931  const Token::Value op_;
2932  const int right_;
2933 };
2934 
2935 
2936 class HIsNilAndBranch: public HUnaryControlInstruction {
2937  public:
2939  : HUnaryControlInstruction(value, NULL, NULL), kind_(kind), nil_(nil) { }
2940 
2941  EqualityKind kind() const { return kind_; }
2942  NilValue nil() const { return nil_; }
2943 
2944  virtual void PrintDataTo(StringStream* stream);
2945 
2947  return Representation::Tagged();
2948  }
2949 
2950  DECLARE_CONCRETE_INSTRUCTION(IsNilAndBranch)
2951 
2952  private:
2953  EqualityKind kind_;
2954  NilValue nil_;
2955 };
2956 
2957 
2958 class HIsObjectAndBranch: public HUnaryControlInstruction {
2959  public:
2960  explicit HIsObjectAndBranch(HValue* value)
2961  : HUnaryControlInstruction(value, NULL, NULL) { }
2962 
2964  return Representation::Tagged();
2965  }
2966 
2967  DECLARE_CONCRETE_INSTRUCTION(IsObjectAndBranch)
2968 };
2969 
2970 class HIsStringAndBranch: public HUnaryControlInstruction {
2971  public:
2972  explicit HIsStringAndBranch(HValue* value)
2973  : HUnaryControlInstruction(value, NULL, NULL) { }
2974 
2976  return Representation::Tagged();
2977  }
2978 
2979  DECLARE_CONCRETE_INSTRUCTION(IsStringAndBranch)
2980 };
2981 
2982 
2983 class HIsSmiAndBranch: public HUnaryControlInstruction {
2984  public:
2985  explicit HIsSmiAndBranch(HValue* value)
2986  : HUnaryControlInstruction(value, NULL, NULL) { }
2987 
2988  DECLARE_CONCRETE_INSTRUCTION(IsSmiAndBranch)
2989 
2991  return Representation::Tagged();
2992  }
2993 
2994  protected:
2995  virtual bool DataEquals(HValue* other) { return true; }
2996 };
2997 
2998 
2999 class HIsUndetectableAndBranch: public HUnaryControlInstruction {
3000  public:
3002  : HUnaryControlInstruction(value, NULL, NULL) { }
3003 
3005  return Representation::Tagged();
3006  }
3007 
3008  DECLARE_CONCRETE_INSTRUCTION(IsUndetectableAndBranch)
3009 };
3010 
3011 
3012 class HStringCompareAndBranch: public HTemplateControlInstruction<2, 3> {
3013  public:
3015  HValue* left,
3016  HValue* right,
3017  Token::Value token)
3018  : token_(token) {
3019  ASSERT(Token::IsCompareOp(token));
3020  SetOperandAt(0, context);
3021  SetOperandAt(1, left);
3022  SetOperandAt(2, right);
3024  }
3025 
3026  HValue* context() { return OperandAt(0); }
3027  HValue* left() { return OperandAt(1); }
3028  HValue* right() { return OperandAt(2); }
3029  Token::Value token() const { return token_; }
3030 
3031  virtual void PrintDataTo(StringStream* stream);
3032 
3034  return Representation::Tagged();
3035  }
3036 
3038  return Representation::Tagged();
3039  }
3040 
3041  DECLARE_CONCRETE_INSTRUCTION(StringCompareAndBranch)
3042 
3043  private:
3044  Token::Value token_;
3045 };
3046 
3047 
3048 class HIsConstructCallAndBranch: public HTemplateControlInstruction<2, 0> {
3049  public:
3051  return Representation::None();
3052  }
3053 
3054  DECLARE_CONCRETE_INSTRUCTION(IsConstructCallAndBranch)
3055 };
3056 
3057 
3058 class HHasInstanceTypeAndBranch: public HUnaryControlInstruction {
3059  public:
3061  : HUnaryControlInstruction(value, NULL, NULL), from_(type), to_(type) { }
3063  : HUnaryControlInstruction(value, NULL, NULL), from_(from), to_(to) {
3064  ASSERT(to == LAST_TYPE); // Others not implemented yet in backend.
3065  }
3066 
3067  InstanceType from() { return from_; }
3068  InstanceType to() { return to_; }
3069 
3070  virtual void PrintDataTo(StringStream* stream);
3071 
3073  return Representation::Tagged();
3074  }
3075 
3076  DECLARE_CONCRETE_INSTRUCTION(HasInstanceTypeAndBranch)
3077 
3078  private:
3079  InstanceType from_;
3080  InstanceType to_; // Inclusive range, not all combinations work.
3081 };
3082 
3083 
3084 class HHasCachedArrayIndexAndBranch: public HUnaryControlInstruction {
3085  public:
3087  : HUnaryControlInstruction(value, NULL, NULL) { }
3088 
3090  return Representation::Tagged();
3091  }
3092 
3093  DECLARE_CONCRETE_INSTRUCTION(HasCachedArrayIndexAndBranch)
3094 };
3095 
3096 
3098  public:
3099  explicit HGetCachedArrayIndex(HValue* value) : HUnaryOperation(value) {
3101  SetFlag(kUseGVN);
3102  }
3103 
3105  return Representation::Tagged();
3106  }
3107 
3108  DECLARE_CONCRETE_INSTRUCTION(GetCachedArrayIndex)
3109 
3110  protected:
3111  virtual bool DataEquals(HValue* other) { return true; }
3112 };
3113 
3114 
3115 class HClassOfTestAndBranch: public HUnaryControlInstruction {
3116  public:
3118  : HUnaryControlInstruction(value, NULL, NULL),
3119  class_name_(class_name) { }
3120 
3121  DECLARE_CONCRETE_INSTRUCTION(ClassOfTestAndBranch)
3122 
3124  return Representation::Tagged();
3125  }
3126 
3127  virtual void PrintDataTo(StringStream* stream);
3128 
3129  Handle<String> class_name() const { return class_name_; }
3130 
3131  private:
3132  Handle<String> class_name_;
3133 };
3134 
3135 
3136 class HTypeofIsAndBranch: public HUnaryControlInstruction {
3137  public:
3139  : HUnaryControlInstruction(value, NULL, NULL),
3140  type_literal_(type_literal) { }
3141 
3142  Handle<String> type_literal() { return type_literal_; }
3143  virtual void PrintDataTo(StringStream* stream);
3144 
3145  DECLARE_CONCRETE_INSTRUCTION(TypeofIsAndBranch)
3146 
3148  return Representation::Tagged();
3149  }
3150 
3151  private:
3152  Handle<String> type_literal_;
3153 };
3154 
3155 
3157  public:
3158  HInstanceOf(HValue* context, HValue* left, HValue* right)
3159  : HBinaryOperation(context, left, right) {
3162  }
3163 
3165  return Representation::Tagged();
3166  }
3167 
3168  virtual HType CalculateInferredType();
3169 
3170  virtual void PrintDataTo(StringStream* stream);
3171 
3172  DECLARE_CONCRETE_INSTRUCTION(InstanceOf)
3173 };
3174 
3175 
3176 class HInstanceOfKnownGlobal: public HTemplateInstruction<2> {
3177  public:
3179  HValue* left,
3180  Handle<JSFunction> right)
3181  : function_(right) {
3182  SetOperandAt(0, context);
3183  SetOperandAt(1, left);
3186  }
3187 
3188  HValue* context() { return OperandAt(0); }
3189  HValue* left() { return OperandAt(1); }
3190  Handle<JSFunction> function() { return function_; }
3191 
3193  return Representation::Tagged();
3194  }
3195 
3196  virtual HType CalculateInferredType();
3197 
3198  DECLARE_CONCRETE_INSTRUCTION(InstanceOfKnownGlobal)
3199 
3200  private:
3201  Handle<JSFunction> function_;
3202 };
3203 
3204 
3205 class HPower: public HTemplateInstruction<2> {
3206  public:
3207  HPower(HValue* left, HValue* right) {
3208  SetOperandAt(0, left);
3209  SetOperandAt(1, right);
3211  SetFlag(kUseGVN);
3212  SetGVNFlag(kChangesNewSpacePromotion);
3213  }
3214 
3215  HValue* left() { return OperandAt(0); }
3216  HValue* right() { return OperandAt(1); }
3217 
3219  return index == 0
3222  }
3223 
3225 
3226  protected:
3227  virtual bool DataEquals(HValue* other) { return true; }
3228 };
3229 
3230 
3231 class HRandom: public HTemplateInstruction<1> {
3232  public:
3233  explicit HRandom(HValue* global_object) {
3234  SetOperandAt(0, global_object);
3236  }
3237 
3238  HValue* global_object() { return OperandAt(0); }
3239 
3241  return Representation::Tagged();
3242  }
3243 
3245 };
3246 
3247 
3249  public:
3250  HAdd(HValue* context, HValue* left, HValue* right)
3251  : HArithmeticBinaryOperation(context, left, right) {
3253  }
3254 
3255  // Add is only commutative if two integer values are added and not if two
3256  // tagged values are added (because it might be a String concatenation).
3257  virtual bool IsCommutative() const {
3258  return !representation().IsTagged();
3259  }
3260 
3261  virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
3262 
3263  static HInstruction* NewHAdd(Zone* zone,
3264  HValue* context,
3265  HValue* left,
3266  HValue* right);
3267 
3268  virtual HType CalculateInferredType();
3269 
3270  virtual HValue* Canonicalize();
3271 
3273 
3274  protected:
3275  virtual bool DataEquals(HValue* other) { return true; }
3276 
3277  virtual Range* InferRange(Zone* zone);
3278 };
3279 
3280 
3282  public:
3283  HSub(HValue* context, HValue* left, HValue* right)
3284  : HArithmeticBinaryOperation(context, left, right) {
3286  }
3287 
3288  virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
3289 
3290  virtual HValue* Canonicalize();
3291 
3292  static HInstruction* NewHSub(Zone* zone,
3293  HValue* context,
3294  HValue* left,
3295  HValue* right);
3296 
3298 
3299  protected:
3300  virtual bool DataEquals(HValue* other) { return true; }
3301 
3302  virtual Range* InferRange(Zone* zone);
3303 };
3304 
3305 
3307  public:
3308  HMul(HValue* context, HValue* left, HValue* right)
3309  : HArithmeticBinaryOperation(context, left, right) {
3311  }
3312 
3313  virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
3314 
3315  // Only commutative if it is certain that not two objects are multiplicated.
3316  virtual bool IsCommutative() const {
3317  return !representation().IsTagged();
3318  }
3319 
3320  static HInstruction* NewHMul(Zone* zone,
3321  HValue* context,
3322  HValue* left,
3323  HValue* right);
3324 
3326 
3327  protected:
3328  virtual bool DataEquals(HValue* other) { return true; }
3329 
3330  virtual Range* InferRange(Zone* zone);
3331 };
3332 
3333 
3335  public:
3336  HMod(HValue* context, HValue* left, HValue* right)
3337  : HArithmeticBinaryOperation(context, left, right) {
3339  }
3340 
3342  if (right()->IsConstant() &&
3343  HConstant::cast(right())->HasInteger32Value()) {
3344  int32_t value = HConstant::cast(right())->Integer32Value();
3345  return value != 0 && (IsPowerOf2(value) || IsPowerOf2(-value));
3346  }
3347 
3348  return false;
3349  }
3350 
3351  virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
3352 
3353  static HInstruction* NewHMod(Zone* zone,
3354  HValue* context,
3355  HValue* left,
3356  HValue* right);
3357 
3359 
3360  protected:
3361  virtual bool DataEquals(HValue* other) { return true; }
3362 
3363  virtual Range* InferRange(Zone* zone);
3364 };
3365 
3366 
3368  public:
3369  HDiv(HValue* context, HValue* left, HValue* right)
3370  : HArithmeticBinaryOperation(context, left, right) {
3373  }
3374 
3375  virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
3376 
3377  static HInstruction* NewHDiv(Zone* zone,
3378  HValue* context,
3379  HValue* left,
3380  HValue* right);
3381 
3383 
3384  protected:
3385  virtual bool DataEquals(HValue* other) { return true; }
3386 
3387  virtual Range* InferRange(Zone* zone);
3388 };
3389 
3390 
3392  public:
3393  HBitwise(Token::Value op, HValue* context, HValue* left, HValue* right)
3394  : HBitwiseBinaryOperation(context, left, right), op_(op) {
3395  ASSERT(op == Token::BIT_AND ||
3396  op == Token::BIT_OR ||
3397  op == Token::BIT_XOR);
3398  }
3399 
3400  Token::Value op() const { return op_; }
3401 
3402  virtual bool IsCommutative() const { return true; }
3403 
3404  virtual HValue* Canonicalize();
3405 
3406  static HInstruction* NewHBitwise(Zone* zone,
3407  Token::Value op,
3408  HValue* context,
3409  HValue* left,
3410  HValue* right);
3411 
3412  virtual void PrintDataTo(StringStream* stream);
3413 
3415 
3416  protected:
3417  virtual bool DataEquals(HValue* other) {
3418  return op() == HBitwise::cast(other)->op();
3419  }
3420 
3421  virtual Range* InferRange(Zone* zone);
3422 
3423  private:
3424  Token::Value op_;
3425 };
3426 
3427 
3429  public:
3430  HShl(HValue* context, HValue* left, HValue* right)
3431  : HBitwiseBinaryOperation(context, left, right) { }
3432 
3433  virtual Range* InferRange(Zone* zone);
3434 
3435  static HInstruction* NewHShl(Zone* zone,
3436  HValue* context,
3437  HValue* left,
3438  HValue* right);
3439 
3441 
3442  protected:
3443  virtual bool DataEquals(HValue* other) { return true; }
3444 };
3445 
3446 
3448  public:
3449  HShr(HValue* context, HValue* left, HValue* right)
3450  : HBitwiseBinaryOperation(context, left, right) { }
3451 
3452  virtual Range* InferRange(Zone* zone);
3453 
3454  static HInstruction* NewHShr(Zone* zone,
3455  HValue* context,
3456  HValue* left,
3457  HValue* right);
3458 
3460 
3461  protected:
3462  virtual bool DataEquals(HValue* other) { return true; }
3463 };
3464 
3465 
3467  public:
3468  HSar(HValue* context, HValue* left, HValue* right)
3469  : HBitwiseBinaryOperation(context, left, right) { }
3470 
3471  virtual Range* InferRange(Zone* zone);
3472 
3473  static HInstruction* NewHSar(Zone* zone,
3474  HValue* context,
3475  HValue* left,
3476  HValue* right);
3477 
3479 
3480  protected:
3481  virtual bool DataEquals(HValue* other) { return true; }
3482 };
3483 
3484 
3485 class HOsrEntry: public HTemplateInstruction<0> {
3486  public:
3487  explicit HOsrEntry(int ast_id) : ast_id_(ast_id) {
3488  SetGVNFlag(kChangesOsrEntries);
3489  }
3490 
3491  int ast_id() const { return ast_id_; }
3492 
3494  return Representation::None();
3495  }
3496 
3498 
3499  private:
3500  int ast_id_;
3501 };
3502 
3503 
3504 class HParameter: public HTemplateInstruction<0> {
3505  public:
3506  explicit HParameter(unsigned index) : index_(index) {
3508  }
3509 
3510  unsigned index() const { return index_; }
3511 
3512  virtual void PrintDataTo(StringStream* stream);
3513 
3515  return Representation::None();
3516  }
3517 
3518  DECLARE_CONCRETE_INSTRUCTION(Parameter)
3519 
3520  private:
3521  unsigned index_;
3522 };
3523 
3524 
3525 class HCallStub: public HUnaryCall {
3526  public:
3527  HCallStub(HValue* context, CodeStub::Major major_key, int argument_count)
3528  : HUnaryCall(context, argument_count),
3529  major_key_(major_key),
3530  transcendental_type_(TranscendentalCache::kNumberOfCaches) {
3531  }
3532 
3533  CodeStub::Major major_key() { return major_key_; }
3534 
3535  HValue* context() { return value(); }
3536 
3538  transcendental_type_ = transcendental_type;
3539  }
3541  return transcendental_type_;
3542  }
3543 
3544  virtual void PrintDataTo(StringStream* stream);
3545 
3547  return Representation::Tagged();
3548  }
3549 
3551 
3552  private:
3553  CodeStub::Major major_key_;
3554  TranscendentalCache::Type transcendental_type_;
3555 };
3556 
3557 
3558 class HUnknownOSRValue: public HTemplateInstruction<0> {
3559  public:
3561  : incoming_value_(NULL) {
3563  }
3564 
3566  return Representation::None();
3567  }
3568 
3569  void set_incoming_value(HPhi* value) {
3570  incoming_value_ = value;
3571  }
3572 
3574  return incoming_value_;
3575  }
3576 
3577  DECLARE_CONCRETE_INSTRUCTION(UnknownOSRValue)
3578 
3579  private:
3580  HPhi* incoming_value_;
3581 };
3582 
3583 
3584 class HLoadGlobalCell: public HTemplateInstruction<0> {
3585  public:
3586  HLoadGlobalCell(Handle<JSGlobalPropertyCell> cell, PropertyDetails details)
3587  : cell_(cell), details_(details) {
3589  SetFlag(kUseGVN);
3590  SetGVNFlag(kDependsOnGlobalVars);
3591  }
3592 
3593  Handle<JSGlobalPropertyCell> cell() const { return cell_; }
3594  bool RequiresHoleCheck();
3595 
3596  virtual void PrintDataTo(StringStream* stream);
3597 
3598  virtual intptr_t Hashcode() {
3599  ASSERT(!HEAP->allow_allocation(false));
3600  return reinterpret_cast<intptr_t>(*cell_);
3601  }
3602 
3604  return Representation::None();
3605  }
3606 
3607  DECLARE_CONCRETE_INSTRUCTION(LoadGlobalCell)
3608 
3609  protected:
3610  virtual bool DataEquals(HValue* other) {
3612  return cell_.is_identical_to(b->cell());
3613  }
3614 
3615  private:
3617  PropertyDetails details_;
3618 };
3619 
3620 
3621 class HLoadGlobalGeneric: public HTemplateInstruction<2> {
3622  public:
3624  HValue* global_object,
3626  bool for_typeof)
3627  : name_(name),
3628  for_typeof_(for_typeof) {
3629  SetOperandAt(0, context);
3630  SetOperandAt(1, global_object);
3633  }
3634 
3635  HValue* context() { return OperandAt(0); }
3636  HValue* global_object() { return OperandAt(1); }
3637  Handle<Object> name() const { return name_; }
3638  bool for_typeof() const { return for_typeof_; }
3639 
3640  virtual void PrintDataTo(StringStream* stream);
3641 
3643  return Representation::Tagged();
3644  }
3645 
3646  DECLARE_CONCRETE_INSTRUCTION(LoadGlobalGeneric)
3647 
3648  private:
3649  Handle<Object> name_;
3650  bool for_typeof_;
3651 };
3652 
3653 
3655  return !value->type().IsBoolean()
3656  && !value->type().IsSmi()
3657  && !(value->IsConstant() && HConstant::cast(value)->ImmortalImmovable());
3658 }
3659 
3660 
3662  HValue* new_space_dominator) {
3663  return !object->IsAllocateObject() || (object != new_space_dominator);
3664 }
3665 
3666 
3668  public:
3671  PropertyDetails details)
3672  : HUnaryOperation(value),
3673  cell_(cell),
3674  details_(details) {
3675  SetGVNFlag(kChangesGlobalVars);
3676  }
3677 
3678  Handle<JSGlobalPropertyCell> cell() const { return cell_; }
3680  return !details_.IsDontDelete() || details_.IsReadOnly();
3681  }
3684  }
3685 
3687  return Representation::Tagged();
3688  }
3689  virtual void PrintDataTo(StringStream* stream);
3690 
3691  DECLARE_CONCRETE_INSTRUCTION(StoreGlobalCell)
3692 
3693  private:
3695  PropertyDetails details_;
3696 };
3697 
3698 
3699 class HStoreGlobalGeneric: public HTemplateInstruction<3> {
3700  public:
3702  HValue* global_object,
3704  HValue* value,
3705  StrictModeFlag strict_mode_flag)
3706  : name_(name),
3707  strict_mode_flag_(strict_mode_flag) {
3708  SetOperandAt(0, context);
3709  SetOperandAt(1, global_object);
3710  SetOperandAt(2, value);
3713  }
3714 
3715  HValue* context() { return OperandAt(0); }
3716  HValue* global_object() { return OperandAt(1); }
3717  Handle<Object> name() const { return name_; }
3718  HValue* value() { return OperandAt(2); }
3719  StrictModeFlag strict_mode_flag() { return strict_mode_flag_; }
3720 
3721  virtual void PrintDataTo(StringStream* stream);
3722 
3724  return Representation::Tagged();
3725  }
3726 
3727  DECLARE_CONCRETE_INSTRUCTION(StoreGlobalGeneric)
3728 
3729  private:
3730  Handle<Object> name_;
3731  StrictModeFlag strict_mode_flag_;
3732 };
3733 
3734 
3736  public:
3737  enum Mode {
3738  // Perform a normal load of the context slot without checking its value.
3740  // Load and check the value of the context slot. Deoptimize if it's the
3741  // hole value. This is used for checking for loading of uninitialized
3742  // harmony bindings where we deoptimize into full-codegen generated code
3743  // which will subsequently throw a reference error.
3745  // Load and check the value of the context slot. Return undefined if it's
3746  // the hole value. This is used for non-harmony const assignments
3747  kCheckReturnUndefined
3748  };
3749 
3751  : HUnaryOperation(context), slot_index_(var->index()) {
3752  ASSERT(var->IsContextSlot());
3753  switch (var->mode()) {
3754  case LET:
3755  case CONST_HARMONY:
3756  mode_ = kCheckDeoptimize;
3757  break;
3758  case CONST:
3759  mode_ = kCheckReturnUndefined;
3760  break;
3761  default:
3762  mode_ = kNoCheck;
3763  }
3765  SetFlag(kUseGVN);
3766  SetGVNFlag(kDependsOnContextSlots);
3767  }
3768 
3769  int slot_index() const { return slot_index_; }
3770  Mode mode() const { return mode_; }
3771 
3773  return mode_ == kCheckDeoptimize;
3774  }
3775 
3777  return mode_ != kNoCheck;
3778  }
3779 
3781  return Representation::Tagged();
3782  }
3783 
3784  virtual void PrintDataTo(StringStream* stream);
3785 
3786  DECLARE_CONCRETE_INSTRUCTION(LoadContextSlot)
3787 
3788  protected:
3789  virtual bool DataEquals(HValue* other) {
3791  return (slot_index() == b->slot_index());
3792  }
3793 
3794  private:
3795  int slot_index_;
3796  Mode mode_;
3797 };
3798 
3799 
3800 class HStoreContextSlot: public HTemplateInstruction<2> {
3801  public:
3802  enum Mode {
3803  // Perform a normal store to the context slot without checking its previous
3804  // value.
3806  // Check the previous value of the context slot and deoptimize if it's the
3807  // hole value. This is used for checking for assignments to uninitialized
3808  // harmony bindings where we deoptimize into full-codegen generated code
3809  // which will subsequently throw a reference error.
3811  // Check the previous value and ignore assignment if it isn't a hole value
3812  kCheckIgnoreAssignment
3813  };
3814 
3815  HStoreContextSlot(HValue* context, int slot_index, Mode mode, HValue* value)
3816  : slot_index_(slot_index), mode_(mode) {
3817  SetOperandAt(0, context);
3818  SetOperandAt(1, value);
3819  SetGVNFlag(kChangesContextSlots);
3820  }
3821 
3822  HValue* context() { return OperandAt(0); }
3823  HValue* value() { return OperandAt(1); }
3824  int slot_index() const { return slot_index_; }
3825  Mode mode() const { return mode_; }
3826 
3829  }
3830 
3832  return mode_ == kCheckDeoptimize;
3833  }
3834 
3836  return mode_ != kNoCheck;
3837  }
3838 
3840  return Representation::Tagged();
3841  }
3842 
3843  virtual void PrintDataTo(StringStream* stream);
3844 
3845  DECLARE_CONCRETE_INSTRUCTION(StoreContextSlot)
3846 
3847  private:
3848  int slot_index_;
3849  Mode mode_;
3850 };
3851 
3852 
3854  public:
3855  HLoadNamedField(HValue* object, bool is_in_object, int offset)
3856  : HUnaryOperation(object),
3857  is_in_object_(is_in_object),
3858  offset_(offset) {
3860  SetFlag(kUseGVN);
3861  SetGVNFlag(kDependsOnMaps);
3862  if (is_in_object) {
3863  SetGVNFlag(kDependsOnInobjectFields);
3864  } else {
3865  SetGVNFlag(kDependsOnBackingStoreFields);
3866  }
3867  }
3868 
3869  HValue* object() { return OperandAt(0); }
3870  bool is_in_object() const { return is_in_object_; }
3871  int offset() const { return offset_; }
3872 
3874  return Representation::Tagged();
3875  }
3876  virtual void PrintDataTo(StringStream* stream);
3877 
3878  DECLARE_CONCRETE_INSTRUCTION(LoadNamedField)
3879 
3880  protected:
3881  virtual bool DataEquals(HValue* other) {
3883  return is_in_object_ == b->is_in_object_ && offset_ == b->offset_;
3884  }
3885 
3886  private:
3887  bool is_in_object_;
3888  int offset_;
3889 };
3890 
3891 
3892 class HLoadNamedFieldPolymorphic: public HTemplateInstruction<2> {
3893  public:
3895  HValue* object,
3896  SmallMapList* types,
3898  Zone* zone);
3899 
3900  HValue* context() { return OperandAt(0); }
3901  HValue* object() { return OperandAt(1); }
3902  SmallMapList* types() { return &types_; }
3903  Handle<String> name() { return name_; }
3904  bool need_generic() { return need_generic_; }
3905 
3907  return Representation::Tagged();
3908  }
3909 
3910  virtual void PrintDataTo(StringStream* stream);
3911 
3912  DECLARE_CONCRETE_INSTRUCTION(LoadNamedFieldPolymorphic)
3913 
3914  static const int kMaxLoadPolymorphism = 4;
3915 
3916  protected:
3917  virtual bool DataEquals(HValue* value);
3918 
3919  private:
3920  SmallMapList types_;
3921  Handle<String> name_;
3922  bool need_generic_;
3923 };
3924 
3925 
3926 
3927 class HLoadNamedGeneric: public HTemplateInstruction<2> {
3928  public:
3930  : name_(name) {
3931  SetOperandAt(0, context);
3932  SetOperandAt(1, object);
3935  }
3936 
3937  HValue* context() { return OperandAt(0); }
3938  HValue* object() { return OperandAt(1); }
3939  Handle<Object> name() const { return name_; }
3940 
3942  return Representation::Tagged();
3943  }
3944 
3945  virtual void PrintDataTo(StringStream* stream);
3946 
3947  DECLARE_CONCRETE_INSTRUCTION(LoadNamedGeneric)
3948 
3949  private:
3950  Handle<Object> name_;
3951 };
3952 
3953 
3955  public:
3956  explicit HLoadFunctionPrototype(HValue* function)
3957  : HUnaryOperation(function) {
3959  SetFlag(kUseGVN);
3960  SetGVNFlag(kDependsOnCalls);
3961  }
3962 
3963  HValue* function() { return OperandAt(0); }
3964 
3966  return Representation::Tagged();
3967  }
3968 
3969  DECLARE_CONCRETE_INSTRUCTION(LoadFunctionPrototype)
3970 
3971  protected:
3972  virtual bool DataEquals(HValue* other) { return true; }
3973 };
3974 
3976  public:
3977  virtual HValue* GetKey() = 0;
3978  virtual void SetKey(HValue* key) = 0;
3979  virtual void SetIndexOffset(uint32_t index_offset) = 0;
3980  virtual bool IsDehoisted() = 0;
3981  virtual void SetDehoisted(bool is_dehoisted) = 0;
3983 };
3984 
3986  : public HTemplateInstruction<2>, public ArrayInstructionInterface {
3987  public:
3989  HValue* key,
3990  ElementsKind elements_kind = FAST_ELEMENTS)
3991  : bit_field_(0) {
3992  ASSERT(IsFastSmiOrObjectElementsKind(elements_kind));
3993  bit_field_ = ElementsKindField::encode(elements_kind);
3994  if (IsFastSmiElementsKind(elements_kind) &&
3995  IsFastPackedElementsKind(elements_kind)) {
3996  set_type(HType::Smi());
3997  }
3998  SetOperandAt(0, obj);
3999  SetOperandAt(1, key);
4001  SetGVNFlag(kDependsOnArrayElements);
4002  SetFlag(kUseGVN);
4003  }
4004 
4005  HValue* object() { return OperandAt(0); }
4006  HValue* key() { return OperandAt(1); }
4007  uint32_t index_offset() { return IndexOffsetField::decode(bit_field_); }
4008  void SetIndexOffset(uint32_t index_offset) {
4009  bit_field_ = IndexOffsetField::update(bit_field_, index_offset);
4010  }
4011  HValue* GetKey() { return key(); }
4012  void SetKey(HValue* key) { SetOperandAt(1, key); }
4013  bool IsDehoisted() { return IsDehoistedField::decode(bit_field_); }
4014  void SetDehoisted(bool is_dehoisted) {
4015  bit_field_ = IsDehoistedField::update(bit_field_, is_dehoisted);
4016  }
4018  return ElementsKindField::decode(bit_field_);
4019  }
4020 
4022  // The key is supposed to be Integer32.
4023  return index == 0
4026  }
4027 
4028  virtual void PrintDataTo(StringStream* stream);
4029 
4030  bool RequiresHoleCheck();
4031 
4032  DECLARE_CONCRETE_INSTRUCTION(LoadKeyedFastElement)
4033 
4034  protected:
4035  virtual bool DataEquals(HValue* other) {
4036  if (!other->IsLoadKeyedFastElement()) return false;
4038  if (IsDehoisted() && index_offset() != other_load->index_offset())
4039  return false;
4040  return elements_kind() == other_load->elements_kind();
4041  }
4042 
4043  private:
4044  class ElementsKindField: public BitField<ElementsKind, 0, 4> {};
4045  class IndexOffsetField: public BitField<uint32_t, 4, 27> {};
4046  class IsDehoistedField: public BitField<bool, 31, 1> {};
4047  uint32_t bit_field_;
4048 };
4049 
4050 
4052 
4053 
4055  : public HTemplateInstruction<2>, public ArrayInstructionInterface {
4056  public:
4058  HValue* elements,
4059  HValue* key,
4060  HoleCheckMode hole_check_mode = PERFORM_HOLE_CHECK)
4061  : index_offset_(0),
4062  is_dehoisted_(false),
4063  hole_check_mode_(hole_check_mode) {
4064  SetOperandAt(0, elements);
4065  SetOperandAt(1, key);
4067  SetGVNFlag(kDependsOnDoubleArrayElements);
4068  SetFlag(kUseGVN);
4069  }
4070 
4071  HValue* elements() { return OperandAt(0); }
4072  HValue* key() { return OperandAt(1); }
4073  uint32_t index_offset() { return index_offset_; }
4074  void SetIndexOffset(uint32_t index_offset) { index_offset_ = index_offset; }
4075  HValue* GetKey() { return key(); }
4076  void SetKey(HValue* key) { SetOperandAt(1, key); }
4077  bool IsDehoisted() { return is_dehoisted_; }
4078  void SetDehoisted(bool is_dehoisted) { is_dehoisted_ = is_dehoisted; }
4079 
4081  // The key is supposed to be Integer32.
4082  return index == 0
4085  }
4086 
4088  return hole_check_mode_ == PERFORM_HOLE_CHECK;
4089  }
4090 
4091  virtual void PrintDataTo(StringStream* stream);
4092 
4093  DECLARE_CONCRETE_INSTRUCTION(LoadKeyedFastDoubleElement)
4094 
4095  protected:
4096  virtual bool DataEquals(HValue* other) {
4097  if (!other->IsLoadKeyedFastDoubleElement()) return false;
4098  HLoadKeyedFastDoubleElement* other_load =
4100  return hole_check_mode_ == other_load->hole_check_mode_;
4101  }
4102 
4103  private:
4104  uint32_t index_offset_;
4105  bool is_dehoisted_;
4106  HoleCheckMode hole_check_mode_;
4107 };
4108 
4109 
4111  : public HTemplateInstruction<2>, public ArrayInstructionInterface {
4112  public:
4114  HValue* key,
4115  ElementsKind elements_kind)
4116  : elements_kind_(elements_kind),
4117  index_offset_(0),
4118  is_dehoisted_(false) {
4119  SetOperandAt(0, external_elements);
4120  SetOperandAt(1, key);
4121  if (elements_kind == EXTERNAL_FLOAT_ELEMENTS ||
4122  elements_kind == EXTERNAL_DOUBLE_ELEMENTS) {
4124  } else {
4126  }
4127  SetGVNFlag(kDependsOnSpecializedArrayElements);
4128  // Native code could change the specialized array.
4129  SetGVNFlag(kDependsOnCalls);
4130  SetFlag(kUseGVN);
4131  }
4132 
4133  virtual void PrintDataTo(StringStream* stream);
4134 
4136  // The key is supposed to be Integer32, but the base pointer
4137  // for the element load is a naked pointer.
4138  return index == 0
4141  }
4142 
4144  HValue* key() { return OperandAt(1); }
4145  ElementsKind elements_kind() const { return elements_kind_; }
4146  uint32_t index_offset() { return index_offset_; }
4147  void SetIndexOffset(uint32_t index_offset) { index_offset_ = index_offset; }
4148  HValue* GetKey() { return key(); }
4149  void SetKey(HValue* key) { SetOperandAt(1, key); }
4150  bool IsDehoisted() { return is_dehoisted_; }
4151  void SetDehoisted(bool is_dehoisted) { is_dehoisted_ = is_dehoisted; }
4152 
4153  virtual Range* InferRange(Zone* zone);
4154 
4155  DECLARE_CONCRETE_INSTRUCTION(LoadKeyedSpecializedArrayElement)
4156 
4157  protected:
4158  virtual bool DataEquals(HValue* other) {
4159  if (!other->IsLoadKeyedSpecializedArrayElement()) return false;
4160  HLoadKeyedSpecializedArrayElement* cast_other =
4162  return elements_kind_ == cast_other->elements_kind();
4163  }
4164 
4165  private:
4166  ElementsKind elements_kind_;
4167  uint32_t index_offset_;
4168  bool is_dehoisted_;
4169 };
4170 
4171 
4172 class HLoadKeyedGeneric: public HTemplateInstruction<3> {
4173  public:
4174  HLoadKeyedGeneric(HValue* context, HValue* obj, HValue* key) {
4176  SetOperandAt(0, obj);
4177  SetOperandAt(1, key);
4178  SetOperandAt(2, context);
4180  }
4181 
4182  HValue* object() { return OperandAt(0); }
4183  HValue* key() { return OperandAt(1); }
4184  HValue* context() { return OperandAt(2); }
4185 
4186  virtual void PrintDataTo(StringStream* stream);
4187 
4189  return Representation::Tagged();
4190  }
4191 
4192  virtual HValue* Canonicalize();
4193 
4194  DECLARE_CONCRETE_INSTRUCTION(LoadKeyedGeneric)
4195 };
4196 
4197 
4198 class HStoreNamedField: public HTemplateInstruction<2> {
4199  public:
4201  Handle<String> name,
4202  HValue* val,
4203  bool in_object,
4204  int offset)
4205  : name_(name),
4206  is_in_object_(in_object),
4207  offset_(offset),
4208  new_space_dominator_(NULL) {
4209  SetOperandAt(0, obj);
4210  SetOperandAt(1, val);
4212  SetGVNFlag(kDependsOnNewSpacePromotion);
4213  if (is_in_object_) {
4214  SetGVNFlag(kChangesInobjectFields);
4215  } else {
4216  SetGVNFlag(kChangesBackingStoreFields);
4217  }
4218  }
4219 
4220  DECLARE_CONCRETE_INSTRUCTION(StoreNamedField)
4221 
4223  return Representation::Tagged();
4224  }
4225  virtual void SetSideEffectDominator(GVNFlag side_effect, HValue* dominator) {
4226  ASSERT(side_effect == kChangesNewSpacePromotion);
4227  new_space_dominator_ = dominator;
4228  }
4229  virtual void PrintDataTo(StringStream* stream);
4230 
4231  HValue* object() { return OperandAt(0); }
4232  HValue* value() { return OperandAt(1); }
4233 
4234  Handle<String> name() const { return name_; }
4235  bool is_in_object() const { return is_in_object_; }
4236  int offset() const { return offset_; }
4237  Handle<Map> transition() const { return transition_; }
4238  void set_transition(Handle<Map> map) { transition_ = map; }
4239  HValue* new_space_dominator() const { return new_space_dominator_; }
4240 
4243  ReceiverObjectNeedsWriteBarrier(object(), new_space_dominator());
4244  }
4245 
4247  return ReceiverObjectNeedsWriteBarrier(object(), new_space_dominator());
4248  }
4249 
4250  private:
4252  bool is_in_object_;
4253  int offset_;
4254  Handle<Map> transition_;
4255  HValue* new_space_dominator_;
4256 };
4257 
4258 
4259 class HStoreNamedGeneric: public HTemplateInstruction<3> {
4260  public:
4262  HValue* object,
4263  Handle<String> name,
4264  HValue* value,
4265  StrictModeFlag strict_mode_flag)
4266  : name_(name),
4267  strict_mode_flag_(strict_mode_flag) {
4268  SetOperandAt(0, object);
4269  SetOperandAt(1, value);
4270  SetOperandAt(2, context);
4272  }
4273 
4274  HValue* object() { return OperandAt(0); }
4275  HValue* value() { return OperandAt(1); }
4276  HValue* context() { return OperandAt(2); }
4277  Handle<String> name() { return name_; }
4278  StrictModeFlag strict_mode_flag() { return strict_mode_flag_; }
4279 
4280  virtual void PrintDataTo(StringStream* stream);
4281 
4283  return Representation::Tagged();
4284  }
4285 
4286  DECLARE_CONCRETE_INSTRUCTION(StoreNamedGeneric)
4287 
4288  private:
4289  Handle<String> name_;
4290  StrictModeFlag strict_mode_flag_;
4291 };
4292 
4293 
4295  : public HTemplateInstruction<3>, public ArrayInstructionInterface {
4296  public:
4298  ElementsKind elements_kind = FAST_ELEMENTS)
4299  : elements_kind_(elements_kind), index_offset_(0), is_dehoisted_(false) {
4300  SetOperandAt(0, obj);
4301  SetOperandAt(1, key);
4302  SetOperandAt(2, val);
4303  SetGVNFlag(kChangesArrayElements);
4304  }
4305 
4307  // The key is supposed to be Integer32.
4308  return index == 1
4311  }
4312 
4313  HValue* object() { return OperandAt(0); }
4314  HValue* key() { return OperandAt(1); }
4315  HValue* value() { return OperandAt(2); }
4316  bool value_is_smi() {
4317  return IsFastSmiElementsKind(elements_kind_);
4318  }
4319  uint32_t index_offset() { return index_offset_; }
4320  void SetIndexOffset(uint32_t index_offset) { index_offset_ = index_offset; }
4321  HValue* GetKey() { return key(); }
4322  void SetKey(HValue* key) { SetOperandAt(1, key); }
4323  bool IsDehoisted() { return is_dehoisted_; }
4324  void SetDehoisted(bool is_dehoisted) { is_dehoisted_ = is_dehoisted; }
4325 
4327  if (value_is_smi()) {
4328  return false;
4329  } else {
4331  }
4332  }
4333 
4334  virtual void PrintDataTo(StringStream* stream);
4335 
4336  DECLARE_CONCRETE_INSTRUCTION(StoreKeyedFastElement)
4337 
4338  private:
4339  ElementsKind elements_kind_;
4340  uint32_t index_offset_;
4341  bool is_dehoisted_;
4342 };
4343 
4344 
4346  : public HTemplateInstruction<3>, public ArrayInstructionInterface {
4347  public:
4349  HValue* key,
4350  HValue* val)
4351  : index_offset_(0), is_dehoisted_(false) {
4352  SetOperandAt(0, elements);
4353  SetOperandAt(1, key);
4354  SetOperandAt(2, val);
4355  SetGVNFlag(kChangesDoubleArrayElements);
4356  }
4357 
4359  if (index == 1) {
4360  return Representation::Integer32();
4361  } else if (index == 2) {
4362  return Representation::Double();
4363  } else {
4364  return Representation::Tagged();
4365  }
4366  }
4367 
4368  HValue* elements() { return OperandAt(0); }
4369  HValue* key() { return OperandAt(1); }
4370  HValue* value() { return OperandAt(2); }
4371  uint32_t index_offset() { return index_offset_; }
4372  void SetIndexOffset(uint32_t index_offset) { index_offset_ = index_offset; }
4373  HValue* GetKey() { return key(); }
4374  void SetKey(HValue* key) { SetOperandAt(1, key); }
4375  bool IsDehoisted() { return is_dehoisted_; }
4376  void SetDehoisted(bool is_dehoisted) { is_dehoisted_ = is_dehoisted; }
4377 
4380  }
4381 
4382  bool NeedsCanonicalization();
4383 
4384  virtual void PrintDataTo(StringStream* stream);
4385 
4386  DECLARE_CONCRETE_INSTRUCTION(StoreKeyedFastDoubleElement)
4387 
4388  private:
4389  uint32_t index_offset_;
4390  bool is_dehoisted_;
4391 };
4392 
4393 
4395  : public HTemplateInstruction<3>, public ArrayInstructionInterface {
4396  public:
4398  HValue* key,
4399  HValue* val,
4400  ElementsKind elements_kind)
4401  : elements_kind_(elements_kind), index_offset_(0), is_dehoisted_(false) {
4402  SetGVNFlag(kChangesSpecializedArrayElements);
4403  SetOperandAt(0, external_elements);
4404  SetOperandAt(1, key);
4405  SetOperandAt(2, val);
4406  }
4407 
4408  virtual void PrintDataTo(StringStream* stream);
4409 
4411  if (index == 0) {
4412  return Representation::External();
4413  } else {
4414  bool float_or_double_elements =
4415  elements_kind() == EXTERNAL_FLOAT_ELEMENTS ||
4416  elements_kind() == EXTERNAL_DOUBLE_ELEMENTS;
4417  if (index == 2 && float_or_double_elements) {
4418  return Representation::Double();
4419  } else {
4420  return Representation::Integer32();
4421  }
4422  }
4423  }
4424 
4426  HValue* key() { return OperandAt(1); }
4427  HValue* value() { return OperandAt(2); }
4428  ElementsKind elements_kind() const { return elements_kind_; }
4429  uint32_t index_offset() { return index_offset_; }
4430  void SetIndexOffset(uint32_t index_offset) { index_offset_ = index_offset; }
4431  HValue* GetKey() { return key(); }
4432  void SetKey(HValue* key) { SetOperandAt(1, key); }
4433  bool IsDehoisted() { return is_dehoisted_; }
4434  void SetDehoisted(bool is_dehoisted) { is_dehoisted_ = is_dehoisted; }
4435 
4436  DECLARE_CONCRETE_INSTRUCTION(StoreKeyedSpecializedArrayElement)
4437 
4438  private:
4439  ElementsKind elements_kind_;
4440  uint32_t index_offset_;
4441  bool is_dehoisted_;
4442 };
4443 
4444 
4445 class HStoreKeyedGeneric: public HTemplateInstruction<4> {
4446  public:
4448  HValue* object,
4449  HValue* key,
4450  HValue* value,
4451  StrictModeFlag strict_mode_flag)
4452  : strict_mode_flag_(strict_mode_flag) {
4453  SetOperandAt(0, object);
4454  SetOperandAt(1, key);
4455  SetOperandAt(2, value);
4456  SetOperandAt(3, context);
4458  }
4459 
4460  HValue* object() { return OperandAt(0); }
4461  HValue* key() { return OperandAt(1); }
4462  HValue* value() { return OperandAt(2); }
4463  HValue* context() { return OperandAt(3); }
4464  StrictModeFlag strict_mode_flag() { return strict_mode_flag_; }
4465 
4467  return Representation::Tagged();
4468  }
4469 
4470  virtual void PrintDataTo(StringStream* stream);
4471 
4472  DECLARE_CONCRETE_INSTRUCTION(StoreKeyedGeneric)
4473 
4474  private:
4475  StrictModeFlag strict_mode_flag_;
4476 };
4477 
4478 
4479 class HTransitionElementsKind: public HTemplateInstruction<1> {
4480  public:
4482  Handle<Map> original_map,
4483  Handle<Map> transitioned_map)
4484  : original_map_(original_map),
4485  transitioned_map_(transitioned_map) {
4486  SetOperandAt(0, object);
4487  SetFlag(kUseGVN);
4488  // Don't set GVN DependOn flags here. That would defeat GVN's detection of
4489  // congruent HTransitionElementsKind instructions. Instruction hoisting
4490  // handles HTransitionElementsKind instruction specially, explicitly adding
4491  // DependsOn flags during its dependency calculations.
4492  SetGVNFlag(kChangesElementsKind);
4493  if (original_map->has_fast_double_elements()) {
4494  SetGVNFlag(kChangesElementsPointer);
4495  SetGVNFlag(kChangesNewSpacePromotion);
4496  }
4497  if (transitioned_map->has_fast_double_elements()) {
4498  SetGVNFlag(kChangesElementsPointer);
4499  SetGVNFlag(kChangesNewSpacePromotion);
4500  }
4502  }
4503 
4505  return Representation::Tagged();
4506  }
4507 
4508  HValue* object() { return OperandAt(0); }
4509  Handle<Map> original_map() { return original_map_; }
4510  Handle<Map> transitioned_map() { return transitioned_map_; }
4511 
4512  virtual void PrintDataTo(StringStream* stream);
4513 
4514  DECLARE_CONCRETE_INSTRUCTION(TransitionElementsKind)
4515 
4516  protected:
4517  virtual bool DataEquals(HValue* other) {
4519  return original_map_.is_identical_to(instr->original_map()) &&
4520  transitioned_map_.is_identical_to(instr->transitioned_map());
4521  }
4522 
4523  private:
4524  Handle<Map> original_map_;
4525  Handle<Map> transitioned_map_;
4526 };
4527 
4528 
4530  public:
4531  HStringAdd(HValue* context, HValue* left, HValue* right)
4532  : HBinaryOperation(context, left, right) {
4534  SetFlag(kUseGVN);
4535  SetGVNFlag(kDependsOnMaps);
4536  }
4537 
4539  return Representation::Tagged();
4540  }
4541 
4543  return HType::String();
4544  }
4545 
4546  DECLARE_CONCRETE_INSTRUCTION(StringAdd)
4547 
4548  protected:
4549  virtual bool DataEquals(HValue* other) { return true; }
4550 };
4551 
4552 
4553 class HStringCharCodeAt: public HTemplateInstruction<3> {
4554  public:
4555  HStringCharCodeAt(HValue* context, HValue* string, HValue* index) {
4556  SetOperandAt(0, context);
4557  SetOperandAt(1, string);
4558  SetOperandAt(2, index);
4560  SetFlag(kUseGVN);
4561  SetGVNFlag(kDependsOnMaps);
4562  SetGVNFlag(kChangesNewSpacePromotion);
4563  }
4564 
4566  // The index is supposed to be Integer32.
4567  return index == 2
4570  }
4571 
4572  HValue* context() { return OperandAt(0); }
4573  HValue* string() { return OperandAt(1); }
4574  HValue* index() { return OperandAt(2); }
4575 
4576  DECLARE_CONCRETE_INSTRUCTION(StringCharCodeAt)
4577 
4578  protected:
4579  virtual bool DataEquals(HValue* other) { return true; }
4580 
4581  virtual Range* InferRange(Zone* zone) {
4582  return new(zone) Range(0, String::kMaxUtf16CodeUnit);
4583  }
4584 };
4585 
4586 
4587 class HStringCharFromCode: public HTemplateInstruction<2> {
4588  public:
4589  HStringCharFromCode(HValue* context, HValue* char_code) {
4590  SetOperandAt(0, context);
4591  SetOperandAt(1, char_code);
4593  SetFlag(kUseGVN);
4594  SetGVNFlag(kChangesNewSpacePromotion);
4595  }
4596 
4598  return index == 0
4601  }
4602  virtual HType CalculateInferredType();
4603 
4604  HValue* context() { return OperandAt(0); }
4605  HValue* value() { return OperandAt(1); }
4606 
4607  virtual bool DataEquals(HValue* other) { return true; }
4608 
4609  DECLARE_CONCRETE_INSTRUCTION(StringCharFromCode)
4610 };
4611 
4612 
4614  public:
4615  explicit HStringLength(HValue* string) : HUnaryOperation(string) {
4617  SetFlag(kUseGVN);
4618  SetGVNFlag(kDependsOnMaps);
4619  }
4620 
4622  return Representation::Tagged();
4623  }
4624 
4627  return HType::Smi();
4628  }
4629 
4630  DECLARE_CONCRETE_INSTRUCTION(StringLength)
4631 
4632  protected:
4633  virtual bool DataEquals(HValue* other) { return true; }
4634 
4635  virtual Range* InferRange(Zone* zone) {
4636  return new(zone) Range(0, String::kMaxLength);
4637  }
4638 };
4639 
4640 
4641 class HAllocateObject: public HTemplateInstruction<1> {
4642  public:
4644  : constructor_(constructor) {
4645  SetOperandAt(0, context);
4647  SetGVNFlag(kChangesNewSpacePromotion);
4648  }
4649 
4650  // Maximum instance size for which allocations will be inlined.
4651  static const int kMaxSize = 64 * kPointerSize;
4652 
4653  HValue* context() { return OperandAt(0); }
4654  Handle<JSFunction> constructor() { return constructor_; }
4655 
4657  return Representation::Tagged();
4658  }
4659  virtual HType CalculateInferredType();
4660 
4661  DECLARE_CONCRETE_INSTRUCTION(AllocateObject)
4662 
4663  private:
4664  Handle<JSFunction> constructor_;
4665 };
4666 
4667 
4668 template <int V>
4669 class HMaterializedLiteral: public HTemplateInstruction<V> {
4670  public:
4671  HMaterializedLiteral<V>(int index, int depth)
4672  : literal_index_(index), depth_(depth) {
4674  }
4675 
4676  int literal_index() const { return literal_index_; }
4677  int depth() const { return depth_; }
4678 
4679  private:
4680  int literal_index_;
4681  int depth_;
4682 };
4683 
4684 
4686  public:
4688  Handle<JSObject> boilerplate,
4689  int total_size,
4690  int literal_index,
4691  int depth)
4692  : HMaterializedLiteral<1>(literal_index, depth),
4693  boilerplate_(boilerplate),
4694  total_size_(total_size) {
4695  SetOperandAt(0, context);
4696  SetGVNFlag(kChangesNewSpacePromotion);
4697  }
4698 
4699  // Maximum depth and total number of elements and properties for literal
4700  // graphs to be considered for fast deep-copying.
4701  static const int kMaxLiteralDepth = 3;
4702  static const int kMaxLiteralProperties = 8;
4703 
4704  HValue* context() { return OperandAt(0); }
4705  Handle<JSObject> boilerplate() const { return boilerplate_; }
4706  int total_size() const { return total_size_; }
4707 
4709  return Representation::Tagged();
4710  }
4711  virtual HType CalculateInferredType();
4712 
4713  DECLARE_CONCRETE_INSTRUCTION(FastLiteral)
4714 
4715  private:
4716  Handle<JSObject> boilerplate_;
4717  int total_size_;
4718 };
4719 
4720 
4722  public:
4724  Handle<HeapObject> boilerplate_object,
4725  int length,
4726  int literal_index,
4727  int depth)
4728  : HMaterializedLiteral<1>(literal_index, depth),
4729  length_(length),
4730  boilerplate_object_(boilerplate_object) {
4731  SetOperandAt(0, context);
4732  SetGVNFlag(kChangesNewSpacePromotion);
4733  }
4734 
4735  HValue* context() { return OperandAt(0); }
4737  if (!boilerplate_object_->IsJSObject()) {
4739  }
4740  return Handle<JSObject>::cast(boilerplate_object_)->GetElementsKind();
4741  }
4742  Handle<HeapObject> boilerplate_object() const { return boilerplate_object_; }
4743  int length() const { return length_; }
4744 
4745  bool IsCopyOnWrite() const;
4746 
4748  return Representation::Tagged();
4749  }
4750  virtual HType CalculateInferredType();
4751 
4753 
4754  private:
4755  int length_;
4756  Handle<HeapObject> boilerplate_object_;
4757 };
4758 
4759 
4760 class HObjectLiteral: public HMaterializedLiteral<1> {
4761  public:
4763  Handle<FixedArray> constant_properties,
4764  bool fast_elements,
4765  int literal_index,
4766  int depth,
4767  bool has_function)
4768  : HMaterializedLiteral<1>(literal_index, depth),
4769  constant_properties_(constant_properties),
4770  fast_elements_(fast_elements),
4771  has_function_(has_function) {
4772  SetOperandAt(0, context);
4773  SetGVNFlag(kChangesNewSpacePromotion);
4774  }
4775 
4776  HValue* context() { return OperandAt(0); }
4778  return constant_properties_;
4779  }
4780  bool fast_elements() const { return fast_elements_; }
4781  bool has_function() const { return has_function_; }
4782 
4784  return Representation::Tagged();
4785  }
4786  virtual HType CalculateInferredType();
4787 
4789 
4790  private:
4791  Handle<FixedArray> constant_properties_;
4792  bool fast_elements_;
4793  bool has_function_;
4794 };
4795 
4796 
4797 class HRegExpLiteral: public HMaterializedLiteral<1> {
4798  public:
4800  Handle<String> pattern,
4802  int literal_index)
4803  : HMaterializedLiteral<1>(literal_index, 0),
4804  pattern_(pattern),
4805  flags_(flags) {
4806  SetOperandAt(0, context);
4808  }
4809 
4810  HValue* context() { return OperandAt(0); }
4811  Handle<String> pattern() { return pattern_; }
4813 
4815  return Representation::Tagged();
4816  }
4817  virtual HType CalculateInferredType();
4818 
4820 
4821  private:
4822  Handle<String> pattern_;
4823  Handle<String> flags_;
4824 };
4825 
4826 
4827 class HFunctionLiteral: public HTemplateInstruction<1> {
4828  public:
4831  bool pretenure)
4832  : shared_info_(shared), pretenure_(pretenure) {
4833  SetOperandAt(0, context);
4835  SetGVNFlag(kChangesNewSpacePromotion);
4836  }
4837 
4838  HValue* context() { return OperandAt(0); }
4839 
4841  return Representation::Tagged();
4842  }
4843  virtual HType CalculateInferredType();
4844 
4846 
4847  Handle<SharedFunctionInfo> shared_info() const { return shared_info_; }
4848  bool pretenure() const { return pretenure_; }
4849 
4850  private:
4851  Handle<SharedFunctionInfo> shared_info_;
4852  bool pretenure_;
4853 };
4854 
4855 
4856 class HTypeof: public HTemplateInstruction<2> {
4857  public:
4858  explicit HTypeof(HValue* context, HValue* value) {
4859  SetOperandAt(0, context);
4860  SetOperandAt(1, value);
4862  }
4863 
4864  HValue* context() { return OperandAt(0); }
4865  HValue* value() { return OperandAt(1); }
4866 
4867  virtual HValue* Canonicalize();
4868  virtual void PrintDataTo(StringStream* stream);
4869 
4871  return Representation::Tagged();
4872  }
4873 
4875 };
4876 
4877 
4879  public:
4880  explicit HToFastProperties(HValue* value) : HUnaryOperation(value) {
4881  // This instruction is not marked as having side effects, but
4882  // changes the map of the input operand. Use it only when creating
4883  // object literals.
4884  ASSERT(value->IsObjectLiteral() || value->IsFastLiteral());
4886  }
4887 
4889  return Representation::Tagged();
4890  }
4891 
4892  DECLARE_CONCRETE_INSTRUCTION(ToFastProperties)
4893 };
4894 
4895 
4896 class HValueOf: public HUnaryOperation {
4897  public:
4898  explicit HValueOf(HValue* value) : HUnaryOperation(value) {
4900  }
4901 
4903  return Representation::Tagged();
4904  }
4905 
4907 };
4908 
4909 
4911  public:
4912  HDateField(HValue* date, Smi* index)
4913  : HUnaryOperation(date), index_(index) {
4915  }
4916 
4917  Smi* index() const { return index_; }
4918 
4920  return Representation::Tagged();
4921  }
4922 
4923  DECLARE_CONCRETE_INSTRUCTION(DateField)
4924 
4925  private:
4926  Smi* index_;
4927 };
4928 
4929 
4931  public:
4932  HDeleteProperty(HValue* context, HValue* obj, HValue* key)
4933  : HBinaryOperation(context, obj, key) {
4936  }
4937 
4939  return Representation::Tagged();
4940  }
4941 
4942  virtual HType CalculateInferredType();
4943 
4944  DECLARE_CONCRETE_INSTRUCTION(DeleteProperty)
4945 
4946  HValue* object() { return left(); }
4947  HValue* key() { return right(); }
4948 };
4949 
4950 
4951 class HIn: public HTemplateInstruction<3> {
4952  public:
4953  HIn(HValue* context, HValue* key, HValue* object) {
4954  SetOperandAt(0, context);
4955  SetOperandAt(1, key);
4956  SetOperandAt(2, object);
4959  }
4960 
4961  HValue* context() { return OperandAt(0); }
4962  HValue* key() { return OperandAt(1); }
4963  HValue* object() { return OperandAt(2); }
4964 
4966  return Representation::Tagged();
4967  }
4968 
4970  return HType::Boolean();
4971  }
4972 
4973  virtual void PrintDataTo(StringStream* stream);
4974 
4976 };
4977 
4978 
4979 class HCheckMapValue: public HTemplateInstruction<2> {
4980  public:
4982  HValue* map) {
4983  SetOperandAt(0, value);
4984  SetOperandAt(1, map);
4986  SetFlag(kUseGVN);
4987  SetGVNFlag(kDependsOnMaps);
4988  SetGVNFlag(kDependsOnElementsKind);
4989  }
4990 
4992  return Representation::Tagged();
4993  }
4994 
4995  virtual void PrintDataTo(StringStream* stream);
4996 
4998  return HType::Tagged();
4999  }
5000 
5001  HValue* value() { return OperandAt(0); }
5002  HValue* map() { return OperandAt(1); }
5003 
5004  DECLARE_CONCRETE_INSTRUCTION(CheckMapValue)
5005 
5006  protected:
5007  virtual bool DataEquals(HValue* other) {
5008  return true;
5009  }
5010 };
5011 
5012 
5013 class HForInPrepareMap : public HTemplateInstruction<2> {
5014  public:
5016  HValue* object) {
5017  SetOperandAt(0, context);
5018  SetOperandAt(1, object);
5021  }
5022 
5024  return Representation::Tagged();
5025  }
5026 
5027  HValue* context() { return OperandAt(0); }
5028  HValue* enumerable() { return OperandAt(1); }
5029 
5030  virtual void PrintDataTo(StringStream* stream);
5031 
5033  return HType::Tagged();
5034  }
5035 
5036  DECLARE_CONCRETE_INSTRUCTION(ForInPrepareMap);
5037 };
5038 
5039 
5040 class HForInCacheArray : public HTemplateInstruction<2> {
5041  public:
5043  HValue* keys,
5044  int idx) : idx_(idx) {
5045  SetOperandAt(0, enumerable);
5046  SetOperandAt(1, keys);
5048  }
5049 
5051  return Representation::Tagged();
5052  }
5053 
5054  HValue* enumerable() { return OperandAt(0); }
5055  HValue* map() { return OperandAt(1); }
5056  int idx() { return idx_; }
5057 
5059  return index_cache_;
5060  }
5061 
5062  void set_index_cache(HForInCacheArray* index_cache) {
5063  index_cache_ = index_cache;
5064  }
5065 
5066  virtual void PrintDataTo(StringStream* stream);
5067 
5069  return HType::Tagged();
5070  }
5071 
5072  DECLARE_CONCRETE_INSTRUCTION(ForInCacheArray);
5073 
5074  private:
5075  int idx_;
5076  HForInCacheArray* index_cache_;
5077 };
5078 
5079 
5080 class HLoadFieldByIndex : public HTemplateInstruction<2> {
5081  public:
5083  HValue* index) {
5084  SetOperandAt(0, object);
5085  SetOperandAt(1, index);
5087  }
5088 
5090  return Representation::Tagged();
5091  }
5092 
5093  HValue* object() { return OperandAt(0); }
5094  HValue* index() { return OperandAt(1); }
5095 
5096  virtual void PrintDataTo(StringStream* stream);
5097 
5099  return HType::Tagged();
5100  }
5101 
5102  DECLARE_CONCRETE_INSTRUCTION(LoadFieldByIndex);
5103 };
5104 
5105 
5106 #undef DECLARE_INSTRUCTION
5107 #undef DECLARE_CONCRETE_INSTRUCTION
5108 
5109 } } // namespace v8::internal
5110 
5111 #endif // V8_HYDROGEN_INSTRUCTIONS_H_
static HPhi * cast(HValue *value)
void SetIndexOffset(uint32_t index_offset)
virtual Representation RequiredInputRepresentation(int index)
HChange(HValue *value, Representation to, bool is_truncating, bool deoptimize_on_undefined)
virtual bool DataEquals(HValue *other)
bool HasObservableSideEffects() const
void set_can_be_minus_zero(bool b)
bool deoptimize_on_minus_zero() const
const int kMinInt
Definition: globals.h:225
bool IsSubtypeOf(const HType &other)
virtual Representation RequiredInputRepresentation(int index)
virtual bool IsConvertibleToInteger() const
virtual Representation InferredRepresentation()
Handle< String > name() const
Representation GetInputRepresentation() const
HDateField(HValue *date, Smi *index)
Handle< Map > at(int i) const
Definition: ast.h:282
virtual Representation RequiredInputRepresentation(int index)
virtual Range * InferRange(Zone *zone)
Representation GetInputRepresentation() const
GVNFlagSet gvn_flags() const
virtual Representation RequiredInputRepresentation(int index)
HCallKeyed(HValue *context, HValue *key, int argument_count)
HOsrEntry(int ast_id)
HLoadKeyedFastDoubleElement(HValue *elements, HValue *key, HoleCheckMode hole_check_mode=PERFORM_HOLE_CHECK)
HType Combine(HType other)
virtual Representation RequiredInputRepresentation(int index)
virtual Representation RequiredInputRepresentation(int index)
HUnaryMathOperation(HValue *context, HValue *value, BuiltinFunctionId op)
virtual Representation RequiredInputRepresentation(int index)
virtual Representation RequiredInputRepresentation(int index)
HCallFunction(HValue *context, HValue *function, int argument_count)
virtual Representation RequiredInputRepresentation(int index)
void InternalSetOperandAt(int i, HValue *value)
HDiv(HValue *context, HValue *left, HValue *right)
Handle< Object > handle() const
virtual bool DataEquals(HValue *other)
void InitializeObservedInputRepresentation(Representation r)
virtual bool IsCommutative() const
static const int kMaxUtf16CodeUnit
Definition: objects.h:7109
virtual Representation RequiredInputRepresentation(int index)
HLoadFieldByIndex(HValue *object, HValue *index)
bool Equals(const HType &other)
virtual HValue * Canonicalize()
virtual Representation RequiredInputRepresentation(int index)
virtual Representation RequiredInputRepresentation(int index)
virtual void SetSideEffectDominator(GVNFlag side_effect, HValue *dominator)
Definition: v8.h:863
HIsNilAndBranch(HValue *value, EqualityKind kind, NilValue nil)
virtual bool DataEquals(HValue *other)
HUseListNode * RemoveUse(HValue *value, int index)
Handle< FixedArray > pairs() const
virtual void SetSideEffectDominator(GVNFlag side_effect, HValue *dominator)
HInstruction * previous() const
virtual Representation RequiredInputRepresentation(int index)
HSuccessorIterator(HControlInstruction *instr)
virtual Representation RequiredInputRepresentation(int index)
HMathFloorOfDiv(HValue *context, HValue *left, HValue *right)
HTypeofIsAndBranch(HValue *value, Handle< String > type_literal)
HBinaryOperation(HValue *context, HValue *left, HValue *right)
virtual Representation RequiredInputRepresentation(int index)
int current_
HInvokeFunction(HValue *context, HValue *function, int argument_count)
HSar(HValue *context, HValue *left, HValue *right)
void Intersect(Range *other)
virtual Representation RequiredInputRepresentation(int index)
value format" "after each garbage collection") DEFINE_bool(print_cumulative_gc_stat, false, "print cumulative GC statistics in name=value format on exit") DEFINE_bool(trace_gc_verbose, false, "print more details following each garbage collection") DEFINE_bool(trace_fragmentation, false, "report fragmentation for old pointer and data pages") DEFINE_bool(collect_maps, true, "garbage collect maps from which no objects can be reached") DEFINE_bool(flush_code, true, "flush code that we expect not to use again before full gc") DEFINE_bool(incremental_marking, true, "use incremental marking") DEFINE_bool(incremental_marking_steps, true, "do incremental marking steps") DEFINE_bool(trace_incremental_marking, false, "trace progress of the incremental marking") DEFINE_bool(use_idle_notification, true, "Use idle notification to reduce memory footprint.") DEFINE_bool(send_idle_notification, false, "Send idle notifcation between stress runs.") DEFINE_bool(use_ic, true, "use inline caching") DEFINE_bool(native_code_counters, false, "generate extra code for manipulating stats counters") DEFINE_bool(always_compact, false, "Perform compaction on every full GC") DEFINE_bool(lazy_sweeping, true, "Use lazy sweeping for old pointer and data spaces") DEFINE_bool(never_compact, false, "Never perform compaction on full GC-testing only") DEFINE_bool(compact_code_space, true, "Compact code space on full non-incremental collections") DEFINE_bool(cleanup_code_caches_at_gc, true, "Flush inline caches prior to mark compact collection and" "flush code caches in maps during mark compact cycle.") DEFINE_int(random_seed, 0, "Default seed for initializing random generator" "(0, the default, means to use system random).") DEFINE_bool(use_verbose_printer, true, "allows verbose printing") DEFINE_bool(allow_natives_syntax, false, "allow natives syntax") DEFINE_bool(trace_sim, false, "Trace simulator execution") DEFINE_bool(check_icache, false, "Check icache flushes in ARM and MIPS simulator") DEFINE_int(stop_sim_at, 0, "Simulator stop after x number of instructions") DEFINE_int(sim_stack_alignment, 8, "Stack alingment in bytes in simulator(4 or 8, 8 is default)") DEFINE_bool(trace_exception, false, "print stack trace when throwing exceptions") DEFINE_bool(preallocate_message_memory, false, "preallocate some memory to build stack traces.") DEFINE_bool(randomize_hashes, true, "randomize hashes to avoid predictable hash collisions" "(with snapshots this option cannot override the baked-in seed)") DEFINE_int(hash_seed, 0, "Fixed seed to use to hash property keys(0 means random)" "(with snapshots this option cannot override the baked-in seed)") DEFINE_bool(preemption, false, "activate a 100ms timer that switches between V8 threads") DEFINE_bool(regexp_optimization, true, "generate optimized regexp code") DEFINE_bool(testing_bool_flag, true, "testing_bool_flag") DEFINE_int(testing_int_flag, 13, "testing_int_flag") DEFINE_float(testing_float_flag, 2.5, "float-flag") DEFINE_string(testing_string_flag, "Hello, world!", "string-flag") DEFINE_int(testing_prng_seed, 42, "Seed used for threading test randomness") DEFINE_string(testing_serialization_file, "/tmp/serdes", "file in which to serialize heap") DEFINE_bool(help, false, "Print usage message, including flags, on console") DEFINE_bool(dump_counters, false, "Dump counters on exit") DEFINE_string(map_counters, "", "Map counters to a file") DEFINE_args(js_arguments, JSARGUMENTS_INIT, "Pass all remaining arguments to the script.Alias for\"--\".") DEFINE_bool(debug_compile_events, true,"Enable debugger compile events") DEFINE_bool(debug_script_collected_events, true,"Enable debugger script collected events") DEFINE_bool(gdbjit, false,"enable GDBJIT interface (disables compacting GC)") DEFINE_bool(gdbjit_full, false,"enable GDBJIT interface for all code objects") DEFINE_bool(gdbjit_dump, false,"dump elf objects with debug info to disk") DEFINE_string(gdbjit_dump_filter,"","dump only objects containing this substring") DEFINE_bool(force_marking_deque_overflows, false,"force overflows of marking deque by reducing it's size ""to 64 words") DEFINE_bool(stress_compaction, false,"stress the GC compactor to flush out bugs (implies ""--force_marking_deque_overflows)")#define FLAG DEFINE_bool(enable_slow_asserts, false,"enable asserts that are slow to execute") DEFINE_bool(trace_codegen, false,"print name of functions for which code is generated") DEFINE_bool(print_source, false,"pretty print source code") DEFINE_bool(print_builtin_source, false,"pretty print source code for builtins") DEFINE_bool(print_ast, false,"print source AST") DEFINE_bool(print_builtin_ast, false,"print source AST for builtins") DEFINE_string(stop_at,"","function name where to insert a breakpoint") DEFINE_bool(print_builtin_scopes, false,"print scopes for builtins") DEFINE_bool(print_scopes, false,"print scopes") DEFINE_bool(trace_contexts, false,"trace contexts operations") DEFINE_bool(gc_greedy, false,"perform GC prior to some allocations") DEFINE_bool(gc_verbose, false,"print stuff during garbage collection") DEFINE_bool(heap_stats, false,"report heap statistics before and after GC") DEFINE_bool(code_stats, false,"report code statistics after GC") DEFINE_bool(verify_heap, false,"verify heap pointers before and after GC") DEFINE_bool(print_handles, false,"report handles after GC") DEFINE_bool(print_global_handles, false,"report global handles after GC") DEFINE_bool(trace_ic, false,"trace inline cache state transitions") DEFINE_bool(print_interfaces, false,"print interfaces") DEFINE_bool(print_interface_details, false,"print interface inference details") DEFINE_int(print_interface_depth, 5,"depth for printing interfaces") DEFINE_bool(trace_normalization, false,"prints when objects are turned into dictionaries.") DEFINE_bool(trace_lazy, false,"trace lazy compilation") DEFINE_bool(collect_heap_spill_statistics, false,"report heap spill statistics along with heap_stats ""(requires heap_stats)") DEFINE_bool(trace_isolates, false,"trace isolate state changes") DEFINE_bool(log_state_changes, false,"Log state changes.") DEFINE_bool(regexp_possessive_quantifier, false,"enable possessive quantifier syntax for testing") DEFINE_bool(trace_regexp_bytecodes, false,"trace regexp bytecode execution") DEFINE_bool(trace_regexp_assembler, false,"trace regexp macro assembler calls.")#define FLAG DEFINE_bool(log, false,"Minimal logging (no API, code, GC, suspect, or handles samples).") DEFINE_bool(log_all, false,"Log all events to the log file.") DEFINE_bool(log_runtime, false,"Activate runtime system %Log call.") DEFINE_bool(log_api, false,"Log API events to the log file.") DEFINE_bool(log_code, false,"Log code events to the log file without profiling.") DEFINE_bool(log_gc, false,"Log heap samples on garbage collection for the hp2ps tool.") DEFINE_bool(log_handles, false,"Log global handle events.") DEFINE_bool(log_snapshot_positions, false,"log positions of (de)serialized objects in the snapshot.") DEFINE_bool(log_suspect, false,"Log suspect operations.") DEFINE_bool(prof, false,"Log statistical profiling information (implies --log-code).") DEFINE_bool(prof_auto, true,"Used with --prof, starts profiling automatically") DEFINE_bool(prof_lazy, false,"Used with --prof, only does sampling and logging"" when profiler is active (implies --noprof_auto).") DEFINE_bool(prof_browser_mode, true,"Used with --prof, turns on browser-compatible mode for profiling.") DEFINE_bool(log_regexp, false,"Log regular expression execution.") DEFINE_bool(sliding_state_window, false,"Update sliding state window counters.") DEFINE_string(logfile,"v8.log","Specify the name of the log file.") DEFINE_bool(ll_prof, false,"Enable low-level linux profiler.")#define FLAG DEFINE_bool(trace_elements_transitions, false,"trace elements transitions") DEFINE_bool(print_code_stubs, false,"print code stubs") DEFINE_bool(test_secondary_stub_cache, false,"test secondary stub cache by disabling the primary one") DEFINE_bool(test_primary_stub_cache, false,"test primary stub cache by disabling the secondary one") DEFINE_bool(print_code, false,"print generated code") DEFINE_bool(print_opt_code, false,"print optimized code") DEFINE_bool(print_unopt_code, false,"print unoptimized code before ""printing optimized code based on it") DEFINE_bool(print_code_verbose, false,"print more information for code") DEFINE_bool(print_builtin_code, false,"print generated code for builtins")#43"/Users/thlorenz/dev/dx/v8-perf/build/v8/src/flags.cc"2#define FLAG_MODE_DEFINE_DEFAULTS#1"/Users/thlorenz/dev/dx/v8-perf/build/v8/src/flag-definitions.h"1#define FLAG_FULL(ftype, ctype, nam, def, cmt)#define FLAG_READONLY(ftype, ctype, nam, def, cmt)#define DEFINE_implication(whenflag, thenflag)#define DEFINE_bool(nam, def, cmt)#define DEFINE_int(nam, def, cmt)#define DEFINE_float(nam, def, cmt)#define DEFINE_string(nam, def, cmt)#define DEFINE_args(nam, def, cmt)#define FLAG DEFINE_bool(use_strict, false,"enforce strict mode") DEFINE_bool(es5_readonly, false,"activate correct semantics for inheriting readonliness") DEFINE_bool(es52_globals, false,"activate new semantics for global var declarations") DEFINE_bool(harmony_typeof, false,"enable harmony semantics for typeof") DEFINE_bool(harmony_scoping, false,"enable harmony block scoping") DEFINE_bool(harmony_modules, false,"enable harmony modules (implies block scoping)") DEFINE_bool(harmony_proxies, false,"enable harmony proxies") DEFINE_bool(harmony_collections, false,"enable harmony collections (sets, maps, and weak maps)") DEFINE_bool(harmony, false,"enable all harmony features (except typeof)") DEFINE_implication(harmony, harmony_scoping) DEFINE_implication(harmony, harmony_modules) DEFINE_implication(harmony, harmony_proxies) DEFINE_implication(harmony, harmony_collections) DEFINE_implication(harmony_modules, harmony_scoping) DEFINE_bool(packed_arrays, false,"optimizes arrays that have no holes") DEFINE_bool(smi_only_arrays, true,"tracks arrays with only smi values") DEFINE_bool(clever_optimizations, true,"Optimize object size, Array shift, DOM strings and string +") DEFINE_bool(unbox_double_arrays, true,"automatically unbox arrays of doubles") DEFINE_bool(string_slices, true,"use string slices") DEFINE_bool(crankshaft, true,"use crankshaft") DEFINE_string(hydrogen_filter,"","optimization filter") DEFINE_bool(use_range, true,"use hydrogen range analysis") DEFINE_bool(eliminate_dead_phis, true,"eliminate dead phis") DEFINE_bool(use_gvn, true,"use hydrogen global value numbering") DEFINE_bool(use_canonicalizing, true,"use hydrogen instruction canonicalizing") DEFINE_bool(use_inlining, true,"use function inlining") DEFINE_int(max_inlined_source_size, 600,"maximum source size in bytes considered for a single inlining") DEFINE_int(max_inlined_nodes, 196,"maximum number of AST nodes considered for a single inlining") DEFINE_int(max_inlined_nodes_cumulative, 196,"maximum cumulative number of AST nodes considered for inlining") DEFINE_bool(loop_invariant_code_motion, true,"loop invariant code motion") DEFINE_bool(collect_megamorphic_maps_from_stub_cache, true,"crankshaft harvests type feedback from stub cache") DEFINE_bool(hydrogen_stats, false,"print statistics for hydrogen") DEFINE_bool(trace_hydrogen, false,"trace generated hydrogen to file") DEFINE_string(trace_phase,"Z","trace generated IR for specified phases") DEFINE_bool(trace_inlining, false,"trace inlining decisions") DEFINE_bool(trace_alloc, false,"trace register allocator") DEFINE_bool(trace_all_uses, false,"trace all use positions") DEFINE_bool(trace_range, false,"trace range analysis") DEFINE_bool(trace_gvn, false,"trace global value numbering") DEFINE_bool(trace_representation, false,"trace representation types") DEFINE_bool(stress_pointer_maps, false,"pointer map for every instruction") DEFINE_bool(stress_environments, false,"environment for every instruction") DEFINE_int(deopt_every_n_times, 0,"deoptimize every n times a deopt point is passed") DEFINE_bool(trap_on_deopt, false,"put a break point before deoptimizing") DEFINE_bool(deoptimize_uncommon_cases, true,"deoptimize uncommon cases") DEFINE_bool(polymorphic_inlining, true,"polymorphic inlining") DEFINE_bool(use_osr, true,"use on-stack replacement") DEFINE_bool(array_bounds_checks_elimination, false,"perform array bounds checks elimination") DEFINE_bool(array_index_dehoisting, false,"perform array index dehoisting") DEFINE_bool(trace_osr, false,"trace on-stack replacement") DEFINE_int(stress_runs, 0,"number of stress runs") DEFINE_bool(optimize_closures, true,"optimize closures") DEFINE_bool(inline_construct, true,"inline constructor calls") DEFINE_bool(inline_arguments, true,"inline functions with arguments object") DEFINE_int(loop_weight, 1,"loop weight for representation inference") DEFINE_bool(optimize_for_in, true,"optimize functions containing for-in loops") DEFINE_bool(experimental_profiler, true,"enable all profiler experiments") DEFINE_bool(watch_ic_patching, false,"profiler considers IC stability") DEFINE_int(frame_count, 1,"number of stack frames inspected by the profiler") DEFINE_bool(self_optimization, false,"primitive functions trigger their own optimization") DEFINE_bool(direct_self_opt, false,"call recompile stub directly when self-optimizing") DEFINE_bool(retry_self_opt, false,"re-try self-optimization if it failed") DEFINE_bool(count_based_interrupts, false,"trigger profiler ticks based on counting instead of timing") DEFINE_bool(interrupt_at_exit, false,"insert an interrupt check at function exit") DEFINE_bool(weighted_back_edges, false,"weight back edges by jump distance for interrupt triggering") DEFINE_int(interrupt_budget, 5900,"execution budget before interrupt is triggered") DEFINE_int(type_info_threshold, 15,"percentage of ICs that must have type info to allow optimization") DEFINE_int(self_opt_count, 130,"call count before self-optimization") DEFINE_implication(experimental_profiler, watch_ic_patching) DEFINE_implication(experimental_profiler, self_optimization) DEFINE_implication(experimental_profiler, retry_self_opt) DEFINE_implication(experimental_profiler, count_based_interrupts) DEFINE_implication(experimental_profiler, interrupt_at_exit) DEFINE_implication(experimental_profiler, weighted_back_edges) DEFINE_bool(trace_opt_verbose, false,"extra verbose compilation tracing") DEFINE_implication(trace_opt_verbose, trace_opt) DEFINE_bool(debug_code, false,"generate extra code (assertions) for debugging") DEFINE_bool(code_comments, false,"emit comments in code disassembly") DEFINE_bool(enable_sse2, true,"enable use of SSE2 instructions if available") DEFINE_bool(enable_sse3, true,"enable use of SSE3 instructions if available") DEFINE_bool(enable_sse4_1, true,"enable use of SSE4.1 instructions if available") DEFINE_bool(enable_cmov, true,"enable use of CMOV instruction if available") DEFINE_bool(enable_rdtsc, true,"enable use of RDTSC instruction if available") DEFINE_bool(enable_sahf, true,"enable use of SAHF instruction if available (X64 only)") DEFINE_bool(enable_vfp3, true,"enable use of VFP3 instructions if available - this implies ""enabling ARMv7 instructions (ARM only)") DEFINE_bool(enable_armv7, true,"enable use of ARMv7 instructions if available (ARM only)") DEFINE_bool(enable_fpu, true,"enable use of MIPS FPU instructions if available (MIPS only)") DEFINE_string(expose_natives_as, NULL,"expose natives in global object") DEFINE_string(expose_debug_as, NULL,"expose debug in global object") DEFINE_bool(expose_gc, false,"expose gc extension") DEFINE_bool(expose_externalize_string, false,"expose externalize string extension") DEFINE_int(stack_trace_limit, 10,"number of stack frames to capture") DEFINE_bool(builtins_in_stack_traces, false,"show built-in functions in stack traces") DEFINE_bool(disable_native_files, false,"disable builtin natives files") DEFINE_bool(inline_new, true,"use fast inline allocation") DEFINE_bool(stack_trace_on_abort, true,"print a stack trace if an assertion failure occurs") DEFINE_bool(trace, false,"trace function calls") DEFINE_bool(mask_constants_with_cookie, true,"use random jit cookie to mask large constants") DEFINE_bool(lazy, true,"use lazy compilation") DEFINE_bool(trace_opt, false,"trace lazy optimization") DEFINE_bool(trace_opt_stats, false,"trace lazy optimization statistics") DEFINE_bool(opt, true,"use adaptive optimizations") DEFINE_bool(always_opt, false,"always try to optimize functions") DEFINE_bool(prepare_always_opt, false,"prepare for turning on always opt") DEFINE_bool(trace_deopt, false,"trace deoptimization") DEFINE_int(min_preparse_length, 1024,"minimum length for automatic enable preparsing") DEFINE_bool(always_full_compiler, false,"try to use the dedicated run-once backend for all code") DEFINE_bool(trace_bailout, false,"print reasons for falling back to using the classic V8 backend") DEFINE_bool(compilation_cache, true,"enable compilation cache") DEFINE_bool(cache_prototype_transitions, true,"cache prototype transitions") DEFINE_bool(trace_debug_json, false,"trace debugging JSON request/response") DEFINE_bool(debugger_auto_break, true,"automatically set the debug break flag when debugger commands are ""in the queue") DEFINE_bool(enable_liveedit, true,"enable liveedit experimental feature") DEFINE_bool(break_on_abort, true,"always cause a debug break before aborting") DEFINE_int(stack_size, kPointerSize *123,"default size of stack region v8 is allowed to use (in kBytes)") DEFINE_int(max_stack_trace_source_length, 300,"maximum length of function source code printed in a stack trace.") DEFINE_bool(always_inline_smi_code, false,"always inline smi code in non-opt code") DEFINE_int(max_new_space_size, 0,"max size of the new generation (in kBytes)") DEFINE_int(max_old_space_size, 0,"max size of the old generation (in Mbytes)") DEFINE_int(max_executable_size, 0,"max size of executable memory (in Mbytes)") DEFINE_bool(gc_global, false,"always perform global GCs") DEFINE_int(gc_interval,-1,"garbage collect after <n> allocations") DEFINE_bool(trace_gc, false,"print one trace line following each garbage collection") DEFINE_bool(trace_gc_nvp, false,"print one detailed trace line in name=value format ""after each garbage collection") DEFINE_bool(print_cumulative_gc_stat, false,"print cumulative GC statistics in name=value format on exit") DEFINE_bool(trace_gc_verbose, false,"print more details following each garbage collection") DEFINE_bool(trace_fragmentation, false,"report fragmentation for old pointer and data pages") DEFINE_bool(collect_maps, true,"garbage collect maps from which no objects can be reached") DEFINE_bool(flush_code, true,"flush code that we expect not to use again before full gc") DEFINE_bool(incremental_marking, true,"use incremental marking") DEFINE_bool(incremental_marking_steps, true,"do incremental marking steps") DEFINE_bool(trace_incremental_marking, false,"trace progress of the incremental marking") DEFINE_bool(use_idle_notification, true,"Use idle notification to reduce memory footprint.") DEFINE_bool(send_idle_notification, false,"Send idle notifcation between stress runs.") DEFINE_bool(use_ic, true,"use inline caching") DEFINE_bool(native_code_counters, false,"generate extra code for manipulating stats counters") DEFINE_bool(always_compact, false,"Perform compaction on every full GC") DEFINE_bool(lazy_sweeping, true,"Use lazy sweeping for old pointer and data spaces") DEFINE_bool(never_compact, false,"Never perform compaction on full GC - testing only") DEFINE_bool(compact_code_space, true,"Compact code space on full non-incremental collections") DEFINE_bool(cleanup_code_caches_at_gc, true,"Flush inline caches prior to mark compact collection and ""flush code caches in maps during mark compact cycle.") DEFINE_int(random_seed, 0,"Default seed for initializing random generator ""(0, the default, means to use system random).") DEFINE_bool(use_verbose_printer, true,"allows verbose printing") DEFINE_bool(allow_natives_syntax, false,"allow natives syntax") DEFINE_bool(trace_sim, false,"Trace simulator execution") DEFINE_bool(check_icache, false,"Check icache flushes in ARM and MIPS simulator") DEFINE_int(stop_sim_at, 0,"Simulator stop after x number of instructions") DEFINE_int(sim_stack_alignment, 8,"Stack alingment in bytes in simulator (4 or 8, 8 is default)") DEFINE_bool(trace_exception, false,"print stack trace when throwing exceptions") DEFINE_bool(preallocate_message_memory, false,"preallocate some memory to build stack traces.") DEFINE_bool(randomize_hashes, true,"randomize hashes to avoid predictable hash collisions ""(with snapshots this option cannot override the baked-in seed)") DEFINE_int(hash_seed, 0,"Fixed seed to use to hash property keys (0 means random)""(with snapshots this option cannot override the baked-in seed)") DEFINE_bool(preemption, false,"activate a 100ms timer that switches between V8 threads") DEFINE_bool(regexp_optimization, true,"generate optimized regexp code") DEFINE_bool(testing_bool_flag, true,"testing_bool_flag") DEFINE_int(testing_int_flag, 13,"testing_int_flag") DEFINE_float(testing_float_flag, 2.5,"float-flag") DEFINE_string(testing_string_flag,"Hello, world!","string-flag") DEFINE_int(testing_prng_seed, 42,"Seed used for threading test randomness") DEFINE_string(testing_serialization_file,"/tmp/serdes","file in which to serialize heap") DEFINE_bool(help, false,"Print usage message, including flags, on console") DEFINE_bool(dump_counters, false,"Dump counters on exit") DEFINE_string(map_counters,"","Map counters to a file") DEFINE_args(js_arguments, JSARGUMENTS_INIT,"Pass all remaining arguments to the script. Alias for \"--\".") DEFINE_bool(debug_compile_events, true,"Enable debugger compile events") DEFINE_bool(debug_script_collected_events, true,"Enable debugger script collected events") DEFINE_bool(gdbjit, false,"enable GDBJIT interface (disables compacting GC)") DEFINE_bool(gdbjit_full, false,"enable GDBJIT interface for all code objects") DEFINE_bool(gdbjit_dump, false,"dump elf objects with debug info to disk") DEFINE_string(gdbjit_dump_filter,"","dump only objects containing this substring") DEFINE_bool(force_marking_deque_overflows, false,"force overflows of marking deque by reducing it's size ""to 64 words") DEFINE_bool(stress_compaction, false,"stress the GC compactor to flush out bugs (implies ""--force_marking_deque_overflows)")#define FLAG DEFINE_bool(enable_slow_asserts, false,"enable asserts that are slow to execute") DEFINE_bool(trace_codegen, false,"print name of functions for which code is generated") DEFINE_bool(print_source, false,"pretty print source code") DEFINE_bool(print_builtin_source, false,"pretty print source code for builtins") DEFINE_bool(print_ast, false,"print source AST") DEFINE_bool(print_builtin_ast, false,"print source AST for builtins") DEFINE_string(stop_at,"","function name where to insert a breakpoint") DEFINE_bool(print_builtin_scopes, false,"print scopes for builtins") DEFINE_bool(print_scopes, false,"print scopes") DEFINE_bool(trace_contexts, false,"trace contexts operations") DEFINE_bool(gc_greedy, false,"perform GC prior to some allocations") DEFINE_bool(gc_verbose, false,"print stuff during garbage collection") DEFINE_bool(heap_stats, false,"report heap statistics before and after GC") DEFINE_bool(code_stats, false,"report code statistics after GC") DEFINE_bool(verify_heap, false,"verify heap pointers before and after GC") DEFINE_bool(print_handles, false,"report handles after GC") DEFINE_bool(print_global_handles, false,"report global handles after GC") DEFINE_bool(trace_ic, false,"trace inline cache state transitions") DEFINE_bool(print_interfaces, false,"print interfaces") DEFINE_bool(print_interface_details, false,"print interface inference details") DEFINE_int(print_interface_depth, 5,"depth for printing interfaces") DEFINE_bool(trace_normalization, false,"prints when objects are turned into dictionaries.") DEFINE_bool(trace_lazy, false,"trace lazy compilation") DEFINE_bool(collect_heap_spill_statistics, false,"report heap spill statistics along with heap_stats ""(requires heap_stats)") DEFINE_bool(trace_isolates, false,"trace isolate state changes") DEFINE_bool(log_state_changes, false,"Log state changes.") DEFINE_bool(regexp_possessive_quantifier, false,"enable possessive quantifier syntax for testing") DEFINE_bool(trace_regexp_bytecodes, false,"trace regexp bytecode execution") DEFINE_bool(trace_regexp_assembler, false,"trace regexp macro assembler calls.")#define FLAG DEFINE_bool(log, false,"Minimal logging (no API, code, GC, suspect, or handles samples).") DEFINE_bool(log_all, false,"Log all events to the log file.") DEFINE_bool(log_runtime, false,"Activate runtime system %Log call.") DEFINE_bool(log_api, false,"Log API events to the log file.") DEFINE_bool(log_code, false,"Log code events to the log file without profiling.") DEFINE_bool(log_gc, false,"Log heap samples on garbage collection for the hp2ps tool.") DEFINE_bool(log_handles, false,"Log global handle events.") DEFINE_bool(log_snapshot_positions, false,"log positions of (de)serialized objects in the snapshot.") DEFINE_bool(log_suspect, false,"Log suspect operations.") DEFINE_bool(prof, false,"Log statistical profiling information (implies --log-code).") DEFINE_bool(prof_auto, true,"Used with --prof, starts profiling automatically") DEFINE_bool(prof_lazy, false,"Used with --prof, only does sampling and logging"" when profiler is active (implies --noprof_auto).") DEFINE_bool(prof_browser_mode, true,"Used with --prof, turns on browser-compatible mode for profiling.") DEFINE_bool(log_regexp, false,"Log regular expression execution.") DEFINE_bool(sliding_state_window, false,"Update sliding state window counters.") DEFINE_string(logfile,"v8.log","Specify the name of the log file.") DEFINE_bool(ll_prof, false,"Enable low-level linux profiler.")#define FLAG DEFINE_bool(trace_elements_transitions, false,"trace elements transitions") DEFINE_bool(print_code_stubs, false,"print code stubs") DEFINE_bool(test_secondary_stub_cache, false,"test secondary stub cache by disabling the primary one") DEFINE_bool(test_primary_stub_cache, false,"test primary stub cache by disabling the secondary one") DEFINE_bool(print_code, false,"print generated code") DEFINE_bool(print_opt_code, false,"print optimized code") DEFINE_bool(print_unopt_code, false,"print unoptimized code before ""printing optimized code based on it") DEFINE_bool(print_code_verbose, false,"print more information for code") DEFINE_bool(print_builtin_code, false,"print generated code for builtins")#47"/Users/thlorenz/dev/dx/v8-perf/build/v8/src/flags.cc"2 namespace{struct Flag{enum FlagType{TYPE_BOOL, TYPE_INT, TYPE_FLOAT, TYPE_STRING, TYPE_ARGS} name
Definition: flags.cc:1349
HBitwise(Token::Value op, HValue *context, HValue *left, HValue *right)
virtual Representation RequiredInputRepresentation(int index)
HBasicBlock * block() const
static bool IsCompareOp(Value op)
Definition: token.h:214
static Handle< T > cast(Handle< S > that)
Definition: handles.h:81
virtual Representation RequiredInputRepresentation(int index)
HCompareMap(HValue *value, Handle< Map > map, HBasicBlock *true_target, HBasicBlock *false_target)
static Representation Integer32()
Handle< JSGlobalPropertyCell > cell() const
HForInPrepareMap(HValue *context, HValue *object)
virtual Representation RequiredInputRepresentation(int index)
HTransitionElementsKind(HValue *object, Handle< Map > original_map, Handle< Map > transitioned_map)
virtual Representation RequiredInputRepresentation(int index)
bool is_identical_to(const Handle< T > other) const
Definition: handles.h:67
virtual Representation RequiredInputRepresentation(int index)
Handle< String > name() const
ElementsKind boilerplate_elements_kind() const
virtual LInstruction * CompileToLithium(LChunkBuilder *builder)=0
static HCheckInstanceType * NewIsString(HValue *value, Zone *zone)
virtual Representation RequiredInputRepresentation(int index)
HHasInstanceTypeAndBranch(HValue *value, InstanceType type)
virtual Representation RequiredInputRepresentation(int index)
HUseListNode(HValue *value, int index, HUseListNode *tail)
virtual Representation RequiredInputRepresentation(int index)
virtual Representation RequiredInputRepresentation(int index)
static GVNFlagSet AllChangesFlagSet()
HStringCharCodeAt(HValue *context, HValue *string, HValue *index)
bool ReceiverObjectNeedsWriteBarrier(HValue *object, HValue *new_space_dominator)
static const int kNoNumber
Definition: ast.h:197
int int32_t
Definition: unicode.cc:47
#define DECLARE_FLAG(type)
Token::Value op() const
void AssumeRepresentation(Representation r)
virtual Representation RequiredInputRepresentation(int index)
const int kMaxInt
Definition: globals.h:224
HCallGlobal(HValue *context, Handle< String > name, int argument_count)
EqualityKind
Definition: v8.h:145
virtual bool IsCommutative() const
virtual Representation ObservedInputRepresentation(int index)
static GVNFlagSet ConvertChangesToDependsFlags(GVNFlagSet flags)
virtual void PrintDataTo(StringStream *stream)
virtual HBasicBlock * SuccessorAt(int i)=0
HCallKnownGlobal(Handle< JSFunction > target, int argument_count)
virtual Representation RequiredInputRepresentation(int index)
static HCheckMaps * NewWithTransitions(HValue *object, Handle< Map > map, Zone *zone)
void AddConstant(int32_t value)
#define ASSERT(condition)
Definition: checks.h:270
Handle< JSObject > prototype() const
bool CanTransitionToMoreGeneralFastElementsKind(ElementsKind elements_kind, bool allow_only_packed)
ToBooleanStub::Types expected_input_types() const
static GVNFlagSet AllDependsOnFlagSet()
HTypeof(HValue *context, HValue *value)
virtual Representation RequiredInputRepresentation(int index)
virtual Representation RequiredInputRepresentation(int index)
virtual Representation RequiredInputRepresentation(int index)
bool Includes(int value) const
virtual void PrintDataTo(StringStream *stream)
HCheckFunction(HValue *value, Handle< JSFunction > function)
HFunctionLiteral(HValue *context, Handle< SharedFunctionInfo > shared, bool pretenure)
HRandom(HValue *global_object)
Range * CopyClearLower(Zone *zone) const
virtual Representation RequiredInputRepresentation(int index)
virtual Representation RequiredInputRepresentation(int index)
HInvokeFunction(HValue *context, HValue *function, Handle< JSFunction > known_function, int argument_count)
virtual bool DataEquals(HValue *other)
static Representation Double()
virtual Representation RequiredInputRepresentation(int index)
HLeaveInlined(bool arguments_pushed)
bool Equals(const Representation &other)
virtual Representation RequiredInputRepresentation(int index)
bool ContainsAnyOf(const EnumSet &set) const
Definition: utils.h:960
HLoadNamedGeneric(HValue *context, HValue *object, Handle< Object > name)
HStoreKeyedFastElement(HValue *obj, HValue *key, HValue *val, ElementsKind elements_kind=FAST_ELEMENTS)
virtual Representation RequiredInputRepresentation(int index)
HStoreKeyedSpecializedArrayElement(HValue *external_elements, HValue *key, HValue *val, ElementsKind elements_kind)
virtual void SetSuccessorAt(int i, HBasicBlock *block)
Representation representation() const
GVNFlagSet DependsOnFlags() const
virtual Representation RequiredInputRepresentation(int index)
HFastLiteral(HValue *context, Handle< JSObject > boilerplate, int total_size, int literal_index, int depth)
virtual Opcode opcode() const
void set_representation(Representation r)
virtual int argument_count() const
#define DECLARE_OPCODE(type)
virtual Representation RequiredInputRepresentation(int index)
void SetIndexOffset(uint32_t index_offset)
virtual Representation RequiredInputRepresentation(int index)
virtual HType CalculateInferredType()
virtual Representation RequiredInputRepresentation(int index)
static HCheckInstanceType * NewIsJSArray(HValue *value, Zone *zone)
HLoadContextSlot(HValue *context, Variable *var)
virtual Representation RequiredInputRepresentation(int index)
HBinaryCall(HValue *first, HValue *second, int argument_count)
GVNFlagSet ObservableChangesFlags() const
HStoreKeyedFastDoubleElement(HValue *elements, HValue *key, HValue *val)
Handle< JSFunction > target() const
#define DECLARE_ABSTRACT_INSTRUCTION(type)
virtual Representation RequiredInputRepresentation(int index)
HInstanceOfKnownGlobal(HValue *context, HValue *left, Handle< JSFunction > right)
HStringAdd(HValue *context, HValue *left, HValue *right)
HDeoptimize(int environment_length, Zone *zone)
static HCheckInstanceType * NewIsSpecObject(HValue *value, Zone *zone)
HAllocateObject(HValue *context, Handle< JSFunction > constructor)
Handle< JSFunction > target() const
#define ADD_FLAG(type)
#define HYDROGEN_CONCRETE_INSTRUCTION_LIST(V)
virtual HType CalculateInferredType()
virtual Representation RequiredInputRepresentation(int index)
HStringCharFromCode(HValue *context, HValue *char_code)
void AddNewRange(Range *r, Zone *zone)
virtual int OperandCount()=0
#define UNREACHABLE()
Definition: checks.h:50
virtual Representation RequiredInputRepresentation(int index)
HLoadNamedField(HValue *object, bool is_in_object, int offset)
bool Equals(HValue *other)
virtual void InternalSetOperandAt(int index, HValue *value)
HLoadKeyedFastElement(HValue *obj, HValue *key, ElementsKind elements_kind=FAST_ELEMENTS)
virtual Representation RequiredInputRepresentation(int index)
virtual Representation RequiredInputRepresentation(int index)
virtual Representation RequiredInputRepresentation(int index)
void PrintRangeTo(StringStream *stream)
HAccessArgumentsAt(HValue *arguments, HValue *length, HValue *index)
EnumSet< GVNFlag > GVNFlagSet
static GVNFlagSet AllSideEffectsFlagSet()
HMod(HValue *context, HValue *left, HValue *right)
virtual Representation RequiredInputRepresentation(int index)
VariableMode mode() const
Definition: variables.h:97
virtual Representation RequiredInputRepresentation(int index)
virtual Representation RequiredInputRepresentation(int index)
virtual Representation RequiredInputRepresentation(int index)
bool IsFastPackedElementsKind(ElementsKind kind)
HInstanceOf(HValue *context, HValue *left, HValue *right)
virtual Representation RequiredInputRepresentation(int index)
void PrintChangesTo(StringStream *stream)
virtual Representation RequiredInputRepresentation(int index)
virtual void RepresentationChanged(Representation to)
virtual Representation RequiredInputRepresentation(int index)
static HUnaryOperation * cast(HValue *value)
virtual Representation RequiredInputRepresentation(int index)
virtual Representation RequiredInputRepresentation(int index)
Handle< HeapObject > boilerplate_object() const
Handle< String > name() const
NilValue
Definition: v8.h:141
static const int kMinValue
Definition: objects.h:1004
virtual Representation RequiredInputRepresentation(int index)
Range * Copy(Zone *zone) const
HArithmeticBinaryOperation(HValue *context, HValue *left, HValue *right)
virtual Representation RequiredInputRepresentation(int index)
virtual bool IsConvertibleToInteger() const
const int kPointerSize
Definition: globals.h:234
int length() const
Definition: ast.h:276
bool StoringValueNeedsWriteBarrier(HValue *value)
HForceRepresentation(HValue *value, Representation required_representation)
#define DECLARE_PREDICATE(type)
bool IsDefinedAfter(HBasicBlock *other) const
int GetAssignedIndexAt(int index) const
virtual Representation RequiredInputRepresentation(int index)
void ComputeInitialRange(Zone *zone)
HClassOfTestAndBranch(HValue *value, Handle< String > class_name)
HSub(HValue *context, HValue *left, HValue *right)
HCallNamed(HValue *context, Handle< String > name, int argument_count)
static GVNFlagSet AllObservableSideEffectsFlagSet()
HBoundsCheck(HValue *index, HValue *length)
#define GVN_TRACKED_FLAG_LIST(V)
Range * CopyClearUpper(Zone *zone) const
ZoneList< HValue * > * arguments_values()
virtual HValue * OperandAt(int index)
virtual void PrintDataTo(StringStream *stream)
HArrayLiteral(HValue *context, Handle< HeapObject > boilerplate_object, int length, int literal_index, int depth)
HLoadKeyedSpecializedArrayElement(HValue *external_elements, HValue *key, ElementsKind elements_kind)
GVNFlagSet ChangesFlags() const
HRegExpLiteral(HValue *context, Handle< String > pattern, Handle< String > flags, int literal_index)
virtual Representation RequiredInputRepresentation(int index)
virtual Representation RequiredInputRepresentation(int index)
virtual bool IsCommutative() const
Handle< JSObject > boilerplate() const
virtual Representation RequiredInputRepresentation(int index)
HSimulate(int ast_id, int pop_count, Zone *zone)
virtual bool DataEquals(HValue *other)
HEnterInlined(Handle< JSFunction > closure, int arguments_count, FunctionLiteral *function, CallKind call_kind, bool is_construct, Variable *arguments_var, ZoneList< HValue * > *arguments_values)
HInstruction * next() const
void Intersect(const EnumSet &set)
Definition: utils.h:968
virtual bool IsConvertibleToInteger() const
Handle< JSFunction > closure() const
HBranch(HValue *value, HBasicBlock *true_target, HBasicBlock *false_target, ToBooleanStub::Types expected_input_types=ToBooleanStub::no_types())
virtual Representation RequiredInputRepresentation(int index)
bool IsContextSlot() const
Definition: variables.h:119
virtual Representation RequiredInputRepresentation(int index)
HStackCheck(HValue *context, Type type)
static GVNFlag DependsOnFlagFromInt(int x)
virtual Representation RequiredInputRepresentation(int index)
virtual Representation RequiredInputRepresentation(int index)
virtual Representation RequiredInputRepresentation(int index)
TranscendentalCache::Type transcendental_type()
bool IsFastSmiElementsKind(ElementsKind kind)
virtual Representation RequiredInputRepresentation(int index)
virtual Representation RequiredInputRepresentation(int index)
void set_type(HType new_type)
virtual HType CalculateInferredType()
const int kBitsPerByte
Definition: globals.h:251
virtual Representation RequiredInputRepresentation(int index)
bool IsPowerOf2(T x)
Definition: utils.h:50
HCheckMaps(HValue *value, SmallMapList *maps, Zone *zone)
virtual Representation RequiredInputRepresentation(int index)
virtual Representation RequiredInputRepresentation(int index)
static Representation External()
#define BASE_EMBEDDED
Definition: allocation.h:68
virtual Representation RequiredInputRepresentation(int index)
HJSArrayLength(HValue *value, HValue *typecheck, HType type=HType::Tagged())
virtual void PrintTo(StringStream *stream)
virtual Representation RequiredInputRepresentation(int index)
const int kBitsPerInt
Definition: globals.h:254
virtual Representation RequiredInputRepresentation(int index)
HStoreKeyedGeneric(HValue *context, HValue *object, HValue *key, HValue *value, StrictModeFlag strict_mode_flag)
void DeleteAndReplaceWith(HValue *other)
virtual void PrintDataTo(StringStream *stream)
virtual void PrintDataTo(StringStream *stream)
#define GVN_UNTRACKED_FLAG_LIST(V)
void AddEnvironmentValue(HValue *value, Zone *zone)
HGlobalReceiver(HValue *global_object)
virtual intptr_t Hashcode()
HLoadGlobalCell(Handle< JSGlobalPropertyCell > cell, PropertyDetails details)
HThrow(HValue *context, HValue *value)
bool SubAndCheckOverflow(Range *other)
virtual Representation RequiredInputRepresentation(int index)
virtual Representation RequiredInputRepresentation(int index)
bool IsFastSmiOrObjectElementsKind(ElementsKind kind)
HStoreNamedField(HValue *obj, Handle< String > name, HValue *val, bool in_object, int offset)
virtual HValue * OperandAt(int index)=0
virtual HValue * EnsureAndPropagateNotMinusZero(BitVector *visited)
virtual Representation ObservedInputRepresentation(int index)
void PrintNameTo(StringStream *stream)
void set_transcendental_type(TranscendentalCache::Type transcendental_type)
void InsertAfter(HInstruction *previous)
virtual Representation RequiredInputRepresentation(int index)
virtual Opcode opcode() const =0
virtual void DeleteFromGraph()=0
virtual Representation RequiredInputRepresentation(int index)
HDeleteProperty(HValue *context, HValue *obj, HValue *key)
HStringCompareAndBranch(HValue *context, HValue *left, HValue *right, Token::Value token)
virtual void SetSuccessorAt(int i, HBasicBlock *block)=0
int32_t DoubleToInt32(double x)
virtual Representation RequiredInputRepresentation(int index)
virtual Representation RequiredInputRepresentation(int index)=0
void set_transition(Handle< Map > map)
virtual Representation RequiredInputRepresentation(int index)
static HeapNumber * cast(Object *obj)
HIn(HValue *context, HValue *key, HValue *object)
HApplyArguments(HValue *function, HValue *receiver, HValue *length, HValue *elements)
void ChangeRepresentation(Representation r)
void SetSuccessorAt(int i, HBasicBlock *block)
HCheckMapValue(HValue *value, HValue *map)
virtual Representation RequiredInputRepresentation(int index)
bool is_null() const
Definition: handles.h:87
virtual Representation RequiredInputRepresentation(int index)
HShr(HValue *context, HValue *left, HValue *right)
bool Contains(E element) const
Definition: utils.h:959
HMul(HValue *context, HValue *left, HValue *right)
HDeclareGlobals(HValue *context, Handle< FixedArray > pairs, int flags)
HCallConstantFunction(Handle< JSFunction > function, int argument_count)
HStoreNamedGeneric(HValue *context, HValue *object, Handle< String > name, HValue *value, StrictModeFlag strict_mode_flag)
void SetOperandAt(int index, HValue *value)
virtual Range * InferRange(Zone *zone)
bool CheckFlag(Flag f) const
HStoreContextSlot(HValue *context, int slot_index, Mode mode, HValue *value)
virtual Representation RequiredInputRepresentation(int index)
HUnaryCall(HValue *value, int argument_count)
Handle< JSFunction > known_function()
int32_t NumberValueAsInteger32() const
#define HYDROGEN_ABSTRACT_INSTRUCTION_LIST(V)
virtual void InternalSetOperandAt(int index, HValue *value)
T ToIntegral() const
Definition: utils.h:969
void InsertBefore(HInstruction *next)
virtual bool DataEquals(HValue *other)
virtual Representation RequiredInputRepresentation(int index)
void set_index_cache(HForInCacheArray *index_cache)
const int kSmiShiftSize
Definition: v8.h:3899
virtual Representation RequiredInputRepresentation(int index)
ElementsKind GetNextMoreGeneralFastElementsKind(ElementsKind elements_kind, bool allow_only_packed)
const int kSmiTagSize
Definition: v8.h:3854
static HType TypeFromValue(Handle< Object > value)
virtual Representation RequiredInputRepresentation(int index)
HObjectLiteral(HValue *context, Handle< FixedArray > constant_properties, bool fast_elements, int literal_index, int depth, bool has_function)
Range(int32_t lower, int32_t upper)
virtual bool DataEquals(HValue *other)
GVNFlagSet SideEffectFlags() const
virtual Representation RequiredInputRepresentation(int index)
virtual Representation RequiredInputRepresentation(int index)
#define HEAP
Definition: isolate.h:1408
virtual Representation RequiredInputRepresentation(int index)
void AddPushedValue(HValue *value)
virtual Representation RequiredInputRepresentation(int index)
virtual Representation RequiredInputRepresentation(int index)
virtual Representation RequiredInputRepresentation(int index)
activate correct semantics for inheriting readonliness enable harmony semantics for typeof enable harmony enable harmony proxies enable all harmony harmony_scoping harmony_proxies harmony_scoping tracks arrays with only smi values automatically unbox arrays of doubles use crankshaft use hydrogen range analysis use hydrogen global value numbering use function inlining maximum number of AST nodes considered for a single inlining loop invariant code motion print statistics for hydrogen trace generated IR for specified phases trace register allocator trace range analysis trace representation types environment for every instruction put a break point before deoptimizing polymorphic inlining perform array bounds checks elimination trace on stack replacement optimize closures functions with arguments object optimize functions containing for in loops profiler considers IC stability primitive functions trigger their own optimization re try self optimization if it failed insert an interrupt check at function exit execution budget before interrupt is triggered call count before self optimization self_optimization count_based_interrupts weighted_back_edges trace_opt emit comments in code disassembly enable use of SSE3 instructions if available enable use of CMOV instruction if available enable use of SAHF instruction if enable use of VFP3 instructions if available this implies enabling ARMv7 enable use of ARMv7 instructions if enable use of MIPS FPU instructions if NULL
Definition: flags.cc:274
virtual Representation RequiredInputRepresentation(int index)
void SetBlock(HBasicBlock *block)
static const int kChangesToDependsFlagsLeftShift
HPhi(int merged_index, Zone *zone)
HStoreGlobalGeneric(HValue *context, HValue *global_object, Handle< Object > name, HValue *value, StrictModeFlag strict_mode_flag)
HCompareIDAndBranch(HValue *left, HValue *right, Token::Value token)
int32_t NumberToInt32(Object *number)
Definition: v8conversions.h:37
virtual Representation RequiredInputRepresentation(int index)
HCompareConstantEqAndBranch(HValue *left, int right, Token::Value op)
HLoadKeyedGeneric(HValue *context, HValue *obj, HValue *key)
HLoadGlobalGeneric(HValue *context, HValue *global_object, Handle< Object > name, bool for_typeof)
void Sar(int32_t value)
virtual Representation RequiredInputRepresentation(int index)
virtual Representation RequiredInputRepresentation(int index)
activate correct semantics for inheriting readonliness enable harmony semantics for typeof enable harmony enable harmony proxies enable all harmony harmony_scoping harmony_proxies harmony_scoping true
Definition: flags.cc:157
#define DECLARE_CONCRETE_INSTRUCTION(type)
virtual Representation RequiredInputRepresentation(int index)
virtual void InternalSetOperandAt(int index, HValue *value)
virtual Representation RequiredInputRepresentation(int index)
#define COUNT_FLAG(type)
virtual Representation RequiredInputRepresentation(int index)
virtual Representation RequiredInputRepresentation(int index)
virtual Representation RequiredInputRepresentation(int index)
virtual Representation RequiredInputRepresentation(int index)
virtual Representation RequiredInputRepresentation(int index)
virtual HValue * OperandAt(int index)
void set_is_convertible_to_integer(bool b)
HShl(HValue *context, HValue *left, HValue *right)
void Shl(int32_t value)
virtual void RepresentationChanged(Representation to)
virtual Representation RequiredInputRepresentation(int index)
static GVNFlag ChangesFlagFromInt(int x)
bool CheckGVNFlag(GVNFlag f) const
virtual Representation RequiredInputRepresentation(int index)
const char * Mnemonic() const
HUnaryControlInstruction(HValue *value, HBasicBlock *true_target, HBasicBlock *false_target)
Handle< JSObject > holder() const
HGoto(HBasicBlock *target)
virtual HBasicBlock * SuccessorAt(int i)
const char * name_
Definition: flags.cc:1352
int ast_id() const
HCheckPrototypeMaps(Handle< JSObject > prototype, Handle< JSObject > holder)
virtual void PrintTo(StringStream *stream)=0
virtual void InternalSetOperandAt(int index, HValue *value)=0
static const int kMaxLength
Definition: objects.h:7166
void set_tail(HUseListNode *list)
virtual void RepresentationChanged(Representation to)
static Representation Tagged()
virtual Representation RequiredInputRepresentation(int index)
virtual Representation RequiredInputRepresentation(int index)
void PrintTypeTo(StringStream *stream)
Handle< JSGlobalPropertyCell > cell() const
void StackUpon(Range *other)
HBitwiseBinaryOperation(HValue *context, HValue *left, HValue *right)
Handle< FixedArray > constant_properties() const
HStoreGlobalCell(HValue *value, Handle< JSGlobalPropertyCell > cell, PropertyDetails details)
HCompareGeneric(HValue *context, HValue *left, HValue *right, Token::Value token)
static HCheckInstanceType * NewIsSymbol(HValue *value, Zone *zone)
virtual Range * InferRange(Zone *zone)
void Add(Handle< Map > handle, Zone *zone)
Definition: ast.h:278
signed short int16_t
Definition: unicode.cc:45
void Remove(E element)
Definition: utils.h:965
STATIC_ASSERT(kLastFlag< kBitsPerInt)
void AddAssignedValue(int index, HValue *value)
HCheckMaps(HValue *value, Handle< Map > map, Zone *zone, HValue *typecheck=NULL)
HForInCacheArray(HValue *enumerable, HValue *keys, int idx)
void RegisterUse(int index, HValue *new_value)
bool HasAssignedIndexAt(int index) const
virtual Representation RequiredInputRepresentation(int index)
void Union(Range *other)
virtual Representation RequiredInputRepresentation(int index)
void Add(E element)
Definition: utils.h:963
HThisFunction(Handle< JSFunction > closure)
static const int kMaxValue
Definition: objects.h:1006
virtual Representation RequiredInputRepresentation(int index)
virtual Representation RequiredInputRepresentation(int index)
static HValue * cast(HValue *value)
void ReplaceAllUsesWith(HValue *other)
const ZoneList< HValue * > * values() const
void check(i::Vector< const char > string)
Handle< JSFunction > closure() const
virtual Representation RequiredInputRepresentation(int index)
virtual Representation RequiredInputRepresentation(int index)
HHasInstanceTypeAndBranch(HValue *value, InstanceType from, InstanceType to)
virtual bool DataEquals(HValue *other)
bool AddAndCheckOverflow(Range *other)
HWrapReceiver(HValue *receiver, HValue *function)
HCallNew(HValue *context, HValue *constructor, int argument_count)
virtual Representation RequiredInputRepresentation(int index)
bool MulAndCheckOverflow(Range *other)
HAdd(HValue *context, HValue *left, HValue *right)
virtual HValue * OperandAt(int index)
HCompareObjectEqAndBranch(HValue *left, HValue *right)
HCallStub(HValue *context, CodeStub::Major major_key, int argument_count)
HUseIterator uses() const
static HType TaggedPrimitive()
HCallRuntime(HValue *context, Handle< String > name, const Runtime::Function *c_function, int argument_count)
virtual Representation RequiredInputRepresentation(int index)
HPower(HValue *left, HValue *right)