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

Side by Side Diff: src/hydrogen-instructions.h

Issue 131363008: A64: Synchronize with r15922. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/a64
Patch Set: Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/hydrogen-gvn.cc ('k') | src/hydrogen-instructions.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 15 matching lines...) Expand all
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 27
28 #ifndef V8_HYDROGEN_INSTRUCTIONS_H_ 28 #ifndef V8_HYDROGEN_INSTRUCTIONS_H_
29 #define V8_HYDROGEN_INSTRUCTIONS_H_ 29 #define V8_HYDROGEN_INSTRUCTIONS_H_
30 30
31 #include "v8.h" 31 #include "v8.h"
32 32
33 #include "allocation.h" 33 #include "allocation.h"
34 #include "code-stubs.h" 34 #include "code-stubs.h"
35 #include "data-flow.h" 35 #include "data-flow.h"
36 #include "deoptimizer.h"
36 #include "small-pointer-list.h" 37 #include "small-pointer-list.h"
37 #include "string-stream.h" 38 #include "string-stream.h"
38 #include "v8conversions.h" 39 #include "v8conversions.h"
39 #include "v8utils.h" 40 #include "v8utils.h"
40 #include "zone.h" 41 #include "zone.h"
41 42
42 namespace v8 { 43 namespace v8 {
43 namespace internal { 44 namespace internal {
44 45
45 // Forward declarations. 46 // Forward declarations.
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
84 V(CallNamed) \ 85 V(CallNamed) \
85 V(CallNew) \ 86 V(CallNew) \
86 V(CallNewArray) \ 87 V(CallNewArray) \
87 V(CallRuntime) \ 88 V(CallRuntime) \
88 V(CallStub) \ 89 V(CallStub) \
89 V(Change) \ 90 V(Change) \
90 V(CheckFunction) \ 91 V(CheckFunction) \
91 V(CheckHeapObject) \ 92 V(CheckHeapObject) \
92 V(CheckInstanceType) \ 93 V(CheckInstanceType) \
93 V(CheckMaps) \ 94 V(CheckMaps) \
95 V(CheckMapValue) \
96 V(CheckPrototypeMaps) \
94 V(CheckSmi) \ 97 V(CheckSmi) \
95 V(CheckPrototypeMaps) \
96 V(ClampToUint8) \ 98 V(ClampToUint8) \
97 V(ClassOfTestAndBranch) \ 99 V(ClassOfTestAndBranch) \
98 V(CompareNumericAndBranch) \ 100 V(CompareNumericAndBranch) \
99 V(CompareGeneric) \ 101 V(CompareGeneric) \
100 V(CompareObjectEqAndBranch) \ 102 V(CompareObjectEqAndBranch) \
101 V(CompareMap) \ 103 V(CompareMap) \
102 V(CompareConstantEqAndBranch) \
103 V(Constant) \ 104 V(Constant) \
104 V(Context) \ 105 V(Context) \
106 V(DateField) \
105 V(DebugBreak) \ 107 V(DebugBreak) \
106 V(DeclareGlobals) \ 108 V(DeclareGlobals) \
107 V(Deoptimize) \ 109 V(Deoptimize) \
108 V(Div) \ 110 V(Div) \
109 V(DummyUse) \ 111 V(DummyUse) \
110 V(ElementsKind) \ 112 V(ElementsKind) \
111 V(EnterInlined) \ 113 V(EnterInlined) \
112 V(EnvironmentMarker) \ 114 V(EnvironmentMarker) \
113 V(ForceRepresentation) \ 115 V(ForceRepresentation) \
116 V(ForInCacheArray) \
117 V(ForInPrepareMap) \
114 V(FunctionLiteral) \ 118 V(FunctionLiteral) \
115 V(GetCachedArrayIndex) \ 119 V(GetCachedArrayIndex) \
116 V(GlobalObject) \ 120 V(GlobalObject) \
117 V(GlobalReceiver) \ 121 V(GlobalReceiver) \
118 V(Goto) \ 122 V(Goto) \
119 V(HasCachedArrayIndexAndBranch) \ 123 V(HasCachedArrayIndexAndBranch) \
120 V(HasInstanceTypeAndBranch) \ 124 V(HasInstanceTypeAndBranch) \
121 V(InductionVariableAnnotation) \ 125 V(InductionVariableAnnotation) \
122 V(InnerAllocatedObject) \ 126 V(InnerAllocatedObject) \
123 V(InstanceOf) \ 127 V(InstanceOf) \
124 V(InstanceOfKnownGlobal) \ 128 V(InstanceOfKnownGlobal) \
125 V(InstanceSize) \ 129 V(InstanceSize) \
126 V(InvokeFunction) \ 130 V(InvokeFunction) \
127 V(IsConstructCallAndBranch) \ 131 V(IsConstructCallAndBranch) \
128 V(IsObjectAndBranch) \ 132 V(IsObjectAndBranch) \
129 V(IsNumberAndBranch) \ 133 V(IsNumberAndBranch) \
130 V(IsStringAndBranch) \ 134 V(IsStringAndBranch) \
131 V(IsSmiAndBranch) \ 135 V(IsSmiAndBranch) \
132 V(IsUndetectableAndBranch) \ 136 V(IsUndetectableAndBranch) \
133 V(LeaveInlined) \ 137 V(LeaveInlined) \
134 V(LinkObjectInList) \ 138 V(LinkObjectInList) \
135 V(LoadContextSlot) \ 139 V(LoadContextSlot) \
136 V(LoadExternalArrayPointer) \ 140 V(LoadExternalArrayPointer) \
141 V(LoadFieldByIndex) \
137 V(LoadFunctionPrototype) \ 142 V(LoadFunctionPrototype) \
138 V(LoadGlobalCell) \ 143 V(LoadGlobalCell) \
139 V(LoadGlobalGeneric) \ 144 V(LoadGlobalGeneric) \
140 V(LoadKeyed) \ 145 V(LoadKeyed) \
141 V(LoadKeyedGeneric) \ 146 V(LoadKeyedGeneric) \
142 V(LoadNamedField) \ 147 V(LoadNamedField) \
143 V(LoadNamedFieldPolymorphic) \ 148 V(LoadNamedFieldPolymorphic) \
144 V(LoadNamedGeneric) \ 149 V(LoadNamedGeneric) \
145 V(MapEnumLength) \ 150 V(MapEnumLength) \
146 V(MathFloorOfDiv) \ 151 V(MathFloorOfDiv) \
147 V(MathMinMax) \ 152 V(MathMinMax) \
148 V(Mod) \ 153 V(Mod) \
149 V(Mul) \ 154 V(Mul) \
150 V(NumericConstraint) \ 155 V(NumericConstraint) \
151 V(OsrEntry) \ 156 V(OsrEntry) \
152 V(OuterContext) \ 157 V(OuterContext) \
153 V(Parameter) \ 158 V(Parameter) \
154 V(Power) \ 159 V(Power) \
155 V(PushArgument) \ 160 V(PushArgument) \
156 V(Random) \ 161 V(Random) \
157 V(RegExpLiteral) \ 162 V(RegExpLiteral) \
158 V(Return) \ 163 V(Return) \
159 V(Ror) \ 164 V(Ror) \
160 V(Sar) \ 165 V(Sar) \
161 V(SeqStringSetChar) \ 166 V(SeqStringSetChar) \
162 V(Shl) \ 167 V(Shl) \
163 V(Shr) \ 168 V(Shr) \
164 V(Simulate) \ 169 V(Simulate) \
165 V(SoftDeoptimize) \
166 V(StackCheck) \ 170 V(StackCheck) \
167 V(StoreContextSlot) \ 171 V(StoreContextSlot) \
168 V(StoreGlobalCell) \ 172 V(StoreGlobalCell) \
169 V(StoreGlobalGeneric) \ 173 V(StoreGlobalGeneric) \
170 V(StoreKeyed) \ 174 V(StoreKeyed) \
171 V(StoreKeyedGeneric) \ 175 V(StoreKeyedGeneric) \
172 V(StoreNamedField) \ 176 V(StoreNamedField) \
173 V(StoreNamedGeneric) \ 177 V(StoreNamedGeneric) \
174 V(StringAdd) \ 178 V(StringAdd) \
175 V(StringCharCodeAt) \ 179 V(StringCharCodeAt) \
176 V(StringCharFromCode) \ 180 V(StringCharFromCode) \
177 V(StringCompareAndBranch) \ 181 V(StringCompareAndBranch) \
178 V(StringLength) \ 182 V(StringLength) \
179 V(Sub) \ 183 V(Sub) \
180 V(ThisFunction) \ 184 V(ThisFunction) \
181 V(Throw) \ 185 V(Throw) \
182 V(ToFastProperties) \ 186 V(ToFastProperties) \
183 V(TransitionElementsKind) \ 187 V(TransitionElementsKind) \
184 V(TrapAllocationMemento) \ 188 V(TrapAllocationMemento) \
185 V(Typeof) \ 189 V(Typeof) \
186 V(TypeofIsAndBranch) \ 190 V(TypeofIsAndBranch) \
187 V(UnaryMathOperation) \ 191 V(UnaryMathOperation) \
188 V(UnknownOSRValue) \ 192 V(UnknownOSRValue) \
189 V(UseConst) \ 193 V(UseConst) \
190 V(ValueOf) \ 194 V(ValueOf) \
191 V(ForInPrepareMap) \
192 V(ForInCacheArray) \
193 V(CheckMapValue) \
194 V(LoadFieldByIndex) \
195 V(DateField) \
196 V(WrapReceiver) 195 V(WrapReceiver)
197 196
198 #define GVN_TRACKED_FLAG_LIST(V) \ 197 #define GVN_TRACKED_FLAG_LIST(V) \
199 V(Maps) \ 198 V(Maps) \
200 V(NewSpacePromotion) 199 V(NewSpacePromotion)
201 200
202 #define GVN_UNTRACKED_FLAG_LIST(V) \ 201 #define GVN_UNTRACKED_FLAG_LIST(V) \
202 V(ArrayElements) \
203 V(ArrayLengths) \
204 V(BackingStoreFields) \
203 V(Calls) \ 205 V(Calls) \
204 V(InobjectFields) \ 206 V(ContextSlots) \
205 V(BackingStoreFields) \ 207 V(DoubleArrayElements) \
206 V(DoubleFields) \ 208 V(DoubleFields) \
207 V(ElementsKind) \ 209 V(ElementsKind) \
208 V(ElementsPointer) \ 210 V(ElementsPointer) \
209 V(ArrayElements) \
210 V(DoubleArrayElements) \
211 V(SpecializedArrayElements) \
212 V(GlobalVars) \ 211 V(GlobalVars) \
213 V(ArrayLengths) \ 212 V(InobjectFields) \
214 V(ContextSlots) \ 213 V(OsrEntries) \
215 V(OsrEntries) 214 V(SpecializedArrayElements)
215
216 216
217 #define DECLARE_ABSTRACT_INSTRUCTION(type) \ 217 #define DECLARE_ABSTRACT_INSTRUCTION(type) \
218 virtual bool Is##type() const { return true; } \ 218 virtual bool Is##type() const { return true; } \
219 static H##type* cast(HValue* value) { \ 219 static H##type* cast(HValue* value) { \
220 ASSERT(value->Is##type()); \ 220 ASSERT(value->Is##type()); \
221 return reinterpret_cast<H##type*>(value); \ 221 return reinterpret_cast<H##type*>(value); \
222 } 222 }
223 223
224 224
225 #define DECLARE_CONCRETE_INSTRUCTION(type) \ 225 #define DECLARE_CONCRETE_INSTRUCTION(type) \
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
287 } 287 }
288 288
289 void Intersect(Range* other); 289 void Intersect(Range* other);
290 void Union(Range* other); 290 void Union(Range* other);
291 void CombinedMax(Range* other); 291 void CombinedMax(Range* other);
292 void CombinedMin(Range* other); 292 void CombinedMin(Range* other);
293 293
294 void AddConstant(int32_t value); 294 void AddConstant(int32_t value);
295 void Sar(int32_t value); 295 void Sar(int32_t value);
296 void Shl(int32_t value); 296 void Shl(int32_t value);
297 bool AddAndCheckOverflow(Range* other); 297 bool AddAndCheckOverflow(const Representation& r, Range* other);
298 bool SubAndCheckOverflow(Range* other); 298 bool SubAndCheckOverflow(const Representation& r, Range* other);
299 bool MulAndCheckOverflow(Range* other); 299 bool MulAndCheckOverflow(const Representation& r, Range* other);
300 300
301 private: 301 private:
302 int32_t lower_; 302 int32_t lower_;
303 int32_t upper_; 303 int32_t upper_;
304 Range* next_; 304 Range* next_;
305 bool can_be_minus_zero_; 305 bool can_be_minus_zero_;
306 }; 306 };
307 307
308 308
309 class UniqueValueId { 309 class UniqueValueId {
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
400 bool IsHeapNumber() const { 400 bool IsHeapNumber() const {
401 ASSERT(type_ != kUninitialized); 401 ASSERT(type_ != kUninitialized);
402 return ((type_ & kHeapNumber) == kHeapNumber); 402 return ((type_ & kHeapNumber) == kHeapNumber);
403 } 403 }
404 404
405 bool IsString() const { 405 bool IsString() const {
406 ASSERT(type_ != kUninitialized); 406 ASSERT(type_ != kUninitialized);
407 return ((type_ & kString) == kString); 407 return ((type_ & kString) == kString);
408 } 408 }
409 409
410 bool IsNonString() const {
411 return IsTaggedPrimitive() || IsSmi() || IsHeapNumber() ||
412 IsBoolean() || IsJSArray();
413 }
414
410 bool IsBoolean() const { 415 bool IsBoolean() const {
411 ASSERT(type_ != kUninitialized); 416 ASSERT(type_ != kUninitialized);
412 return ((type_ & kBoolean) == kBoolean); 417 return ((type_ & kBoolean) == kBoolean);
413 } 418 }
414 419
415 bool IsNonPrimitive() const { 420 bool IsNonPrimitive() const {
416 ASSERT(type_ != kUninitialized); 421 ASSERT(type_ != kUninitialized);
417 return ((type_ & kNonPrimitive) == kNonPrimitive); 422 return ((type_ & kNonPrimitive) == kNonPrimitive);
418 } 423 }
419 424
(...skipping 373 matching lines...) Expand 10 before | Expand all | Expand 10 after
793 // sets this flag, it must implement HandleSideEffectDominator() and should 798 // sets this flag, it must implement HandleSideEffectDominator() and should
794 // indicate which side effects to track by setting GVN flags. 799 // indicate which side effects to track by setting GVN flags.
795 kTrackSideEffectDominators, 800 kTrackSideEffectDominators,
796 kCanOverflow, 801 kCanOverflow,
797 kBailoutOnMinusZero, 802 kBailoutOnMinusZero,
798 kCanBeDivByZero, 803 kCanBeDivByZero,
799 kAllowUndefinedAsNaN, 804 kAllowUndefinedAsNaN,
800 kIsArguments, 805 kIsArguments,
801 kTruncatingToInt32, 806 kTruncatingToInt32,
802 kAllUsesTruncatingToInt32, 807 kAllUsesTruncatingToInt32,
808 kTruncatingToSmi,
809 kAllUsesTruncatingToSmi,
803 // Set after an instruction is killed. 810 // Set after an instruction is killed.
804 kIsDead, 811 kIsDead,
805 // Instructions that are allowed to produce full range unsigned integer 812 // Instructions that are allowed to produce full range unsigned integer
806 // values are marked with kUint32 flag. If arithmetic shift or a load from 813 // values are marked with kUint32 flag. If arithmetic shift or a load from
807 // EXTERNAL_UNSIGNED_INT_ELEMENTS array is not marked with this flag 814 // EXTERNAL_UNSIGNED_INT_ELEMENTS array is not marked with this flag
808 // it will deoptimize if result does not fit into signed integer range. 815 // it will deoptimize if result does not fit into signed integer range.
809 // HGraph::ComputeSafeUint32Operations is responsible for setting this 816 // HGraph::ComputeSafeUint32Operations is responsible for setting this
810 // flag. 817 // flag.
811 kUint32, 818 kUint32,
812 // If a phi is involved in the evaluation of a numeric constraint the 819 // If a phi is involved in the evaluation of a numeric constraint the
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
879 886
880 // Note: Never call this method for an unlinked value. 887 // Note: Never call this method for an unlinked value.
881 Isolate* isolate() const; 888 Isolate* isolate() const;
882 889
883 int id() const { return id_; } 890 int id() const { return id_; }
884 void set_id(int id) { id_ = id; } 891 void set_id(int id) { id_ = id; }
885 892
886 HUseIterator uses() const { return HUseIterator(use_list_); } 893 HUseIterator uses() const { return HUseIterator(use_list_); }
887 894
888 virtual bool EmitAtUses() { return false; } 895 virtual bool EmitAtUses() { return false; }
896
889 Representation representation() const { return representation_; } 897 Representation representation() const { return representation_; }
890 void ChangeRepresentation(Representation r) { 898 void ChangeRepresentation(Representation r) {
891 ASSERT(CheckFlag(kFlexibleRepresentation)); 899 ASSERT(CheckFlag(kFlexibleRepresentation));
892 ASSERT(!CheckFlag(kCannotBeTagged) || !r.IsTagged()); 900 ASSERT(!CheckFlag(kCannotBeTagged) || !r.IsTagged());
893 RepresentationChanged(r); 901 RepresentationChanged(r);
894 representation_ = r; 902 representation_ = r;
895 if (r.IsTagged()) { 903 if (r.IsTagged()) {
896 // Tagged is the bottom of the lattice, don't go any further. 904 // Tagged is the bottom of the lattice, don't go any further.
897 ClearFlag(kFlexibleRepresentation); 905 ClearFlag(kFlexibleRepresentation);
898 } 906 }
(...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after
1154 virtual bool DataEquals(HValue* other) { 1162 virtual bool DataEquals(HValue* other) {
1155 UNREACHABLE(); 1163 UNREACHABLE();
1156 return false; 1164 return false;
1157 } 1165 }
1158 1166
1159 virtual Representation RepresentationFromInputs() { 1167 virtual Representation RepresentationFromInputs() {
1160 return representation(); 1168 return representation();
1161 } 1169 }
1162 Representation RepresentationFromUses(); 1170 Representation RepresentationFromUses();
1163 Representation RepresentationFromUseRequirements(); 1171 Representation RepresentationFromUseRequirements();
1172 bool HasNonSmiUse();
1164 virtual void UpdateRepresentation(Representation new_rep, 1173 virtual void UpdateRepresentation(Representation new_rep,
1165 HInferRepresentationPhase* h_infer, 1174 HInferRepresentationPhase* h_infer,
1166 const char* reason); 1175 const char* reason);
1167 void AddDependantsToWorklist(HInferRepresentationPhase* h_infer); 1176 void AddDependantsToWorklist(HInferRepresentationPhase* h_infer);
1168 1177
1169 virtual void RepresentationChanged(Representation to) { } 1178 virtual void RepresentationChanged(Representation to) { }
1170 1179
1171 virtual Range* InferRange(Zone* zone); 1180 virtual Range* InferRange(Zone* zone);
1172 virtual void DeleteFromGraph() = 0; 1181 virtual void DeleteFromGraph() = 0;
1173 virtual void InternalSetOperandAt(int index, HValue* value) = 0; 1182 virtual void InternalSetOperandAt(int index, HValue* value) = 0;
(...skipping 312 matching lines...) Expand 10 before | Expand all | Expand 10 after
1486 HValue* related_value) 1495 HValue* related_value)
1487 : relation_(relation) { 1496 : relation_(relation) {
1488 SetOperandAt(0, constrained_value); 1497 SetOperandAt(0, constrained_value);
1489 SetOperandAt(1, related_value); 1498 SetOperandAt(1, related_value);
1490 } 1499 }
1491 1500
1492 NumericRelation relation_; 1501 NumericRelation relation_;
1493 }; 1502 };
1494 1503
1495 1504
1496 // We insert soft-deoptimize when we hit code with unknown typefeedback, 1505 class HDeoptimize: public HTemplateInstruction<0> {
1497 // so that we get a chance of re-optimizing with useful typefeedback.
1498 // HSoftDeoptimize does not end a basic block as opposed to HDeoptimize.
1499 class HSoftDeoptimize: public HTemplateInstruction<0> {
1500 public: 1506 public:
1507 explicit HDeoptimize(Deoptimizer::BailoutType type) : type_(type) {}
1508
1501 virtual Representation RequiredInputRepresentation(int index) { 1509 virtual Representation RequiredInputRepresentation(int index) {
1502 return Representation::None(); 1510 return Representation::None();
1503 } 1511 }
1504 1512
1505 DECLARE_CONCRETE_INSTRUCTION(SoftDeoptimize) 1513 Deoptimizer::BailoutType type() { return type_; }
1514
1515 DECLARE_CONCRETE_INSTRUCTION(Deoptimize)
1516
1517 private:
1518 Deoptimizer::BailoutType type_;
1506 }; 1519 };
1507 1520
1508 1521
1509 // Inserts an int3/stop break instruction for debugging purposes. 1522 // Inserts an int3/stop break instruction for debugging purposes.
1510 class HDebugBreak: public HTemplateInstruction<0> { 1523 class HDebugBreak: public HTemplateInstruction<0> {
1511 public: 1524 public:
1512 virtual Representation RequiredInputRepresentation(int index) { 1525 virtual Representation RequiredInputRepresentation(int index) {
1513 return Representation::None(); 1526 return Representation::None();
1514 } 1527 }
1515 1528
1516 DECLARE_CONCRETE_INSTRUCTION(DebugBreak) 1529 DECLARE_CONCRETE_INSTRUCTION(DebugBreak)
1517 }; 1530 };
1518 1531
1519 1532
1520 class HDeoptimize: public HControlInstruction {
1521 public:
1522 HDeoptimize(int environment_length,
1523 int first_local_index,
1524 int first_expression_index,
1525 Zone* zone)
1526 : values_(environment_length, zone),
1527 first_local_index_(first_local_index),
1528 first_expression_index_(first_expression_index) { }
1529
1530 virtual Representation RequiredInputRepresentation(int index) {
1531 return Representation::None();
1532 }
1533
1534 virtual int OperandCount() { return values_.length(); }
1535 virtual HValue* OperandAt(int index) const { return values_[index]; }
1536 virtual void PrintDataTo(StringStream* stream);
1537
1538 virtual int SuccessorCount() { return 0; }
1539 virtual HBasicBlock* SuccessorAt(int i) {
1540 UNREACHABLE();
1541 return NULL;
1542 }
1543 virtual void SetSuccessorAt(int i, HBasicBlock* block) {
1544 UNREACHABLE();
1545 }
1546
1547 void AddEnvironmentValue(HValue* value, Zone* zone) {
1548 values_.Add(NULL, zone);
1549 SetOperandAt(values_.length() - 1, value);
1550 }
1551 int first_local_index() { return first_local_index_; }
1552 int first_expression_index() { return first_expression_index_; }
1553
1554 DECLARE_CONCRETE_INSTRUCTION(Deoptimize)
1555
1556 enum UseEnvironment {
1557 kNoUses,
1558 kUseAll
1559 };
1560
1561 protected:
1562 virtual void InternalSetOperandAt(int index, HValue* value) {
1563 values_[index] = value;
1564 }
1565
1566 private:
1567 ZoneList<HValue*> values_;
1568 int first_local_index_;
1569 int first_expression_index_;
1570 };
1571
1572
1573 class HGoto: public HTemplateControlInstruction<1, 0> { 1533 class HGoto: public HTemplateControlInstruction<1, 0> {
1574 public: 1534 public:
1575 explicit HGoto(HBasicBlock* target) { 1535 explicit HGoto(HBasicBlock* target) {
1576 SetSuccessorAt(0, target); 1536 SetSuccessorAt(0, target);
1577 } 1537 }
1578 1538
1579 virtual Representation RequiredInputRepresentation(int index) { 1539 virtual Representation RequiredInputRepresentation(int index) {
1580 return Representation::None(); 1540 return Representation::None();
1581 } 1541 }
1582 1542
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after
1751 virtual void PrintDataTo(StringStream* stream); 1711 virtual void PrintDataTo(StringStream* stream);
1752 1712
1753 DECLARE_CONCRETE_INSTRUCTION(ForceRepresentation) 1713 DECLARE_CONCRETE_INSTRUCTION(ForceRepresentation)
1754 }; 1714 };
1755 1715
1756 1716
1757 class HChange: public HUnaryOperation { 1717 class HChange: public HUnaryOperation {
1758 public: 1718 public:
1759 HChange(HValue* value, 1719 HChange(HValue* value,
1760 Representation to, 1720 Representation to,
1761 bool is_truncating, 1721 bool is_truncating_to_smi,
1722 bool is_truncating_to_int32,
1762 bool allow_undefined_as_nan) 1723 bool allow_undefined_as_nan)
1763 : HUnaryOperation(value) { 1724 : HUnaryOperation(value) {
1764 ASSERT(!value->representation().IsNone()); 1725 ASSERT(!value->representation().IsNone());
1765 ASSERT(!to.IsNone()); 1726 ASSERT(!to.IsNone());
1766 ASSERT(!value->representation().Equals(to)); 1727 ASSERT(!value->representation().Equals(to));
1767 set_representation(to); 1728 set_representation(to);
1768 SetFlag(kUseGVN); 1729 SetFlag(kUseGVN);
1769 if (allow_undefined_as_nan) SetFlag(kAllowUndefinedAsNaN); 1730 if (allow_undefined_as_nan) SetFlag(kAllowUndefinedAsNaN);
1770 if (is_truncating) SetFlag(kTruncatingToInt32); 1731 if (is_truncating_to_smi) SetFlag(kTruncatingToSmi);
1732 if (is_truncating_to_int32) SetFlag(kTruncatingToInt32);
1771 if (value->representation().IsSmi() || value->type().IsSmi()) { 1733 if (value->representation().IsSmi() || value->type().IsSmi()) {
1772 set_type(HType::Smi()); 1734 set_type(HType::Smi());
1773 } else { 1735 } else {
1774 set_type(HType::TaggedNumber()); 1736 set_type(HType::TaggedNumber());
1775 if (to.IsTagged()) SetGVNFlag(kChangesNewSpacePromotion); 1737 if (to.IsTagged()) SetGVNFlag(kChangesNewSpacePromotion);
1776 } 1738 }
1777 } 1739 }
1778 1740
1779 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited); 1741 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
1780 virtual HType CalculateInferredType(); 1742 virtual HType CalculateInferredType();
(...skipping 880 matching lines...) Expand 10 before | Expand all | Expand 10 after
2661 } 2623 }
2662 2624
2663 private: 2625 private:
2664 HUnaryMathOperation(HValue* context, HValue* value, BuiltinFunctionId op) 2626 HUnaryMathOperation(HValue* context, HValue* value, BuiltinFunctionId op)
2665 : op_(op) { 2627 : op_(op) {
2666 SetOperandAt(0, context); 2628 SetOperandAt(0, context);
2667 SetOperandAt(1, value); 2629 SetOperandAt(1, value);
2668 switch (op) { 2630 switch (op) {
2669 case kMathFloor: 2631 case kMathFloor:
2670 case kMathRound: 2632 case kMathRound:
2633 // TODO(verwaest): Set representation to flexible int starting as smi.
2671 set_representation(Representation::Integer32()); 2634 set_representation(Representation::Integer32());
2672 break; 2635 break;
2673 case kMathAbs: 2636 case kMathAbs:
2674 // Not setting representation here: it is None intentionally. 2637 // Not setting representation here: it is None intentionally.
2675 SetFlag(kFlexibleRepresentation); 2638 SetFlag(kFlexibleRepresentation);
2676 // TODO(svenpanne) This flag is actually only needed if representation() 2639 // TODO(svenpanne) This flag is actually only needed if representation()
2677 // is tagged, and not when it is an unboxed double or unboxed integer. 2640 // is tagged, and not when it is an unboxed double or unboxed integer.
2678 SetGVNFlag(kChangesNewSpacePromotion); 2641 SetGVNFlag(kChangesNewSpacePromotion);
2679 break; 2642 break;
2680 case kMathLog: 2643 case kMathLog:
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
2725 virtual bool DataEquals(HValue* other) { return true; } 2688 virtual bool DataEquals(HValue* other) { return true; }
2726 2689
2727 private: 2690 private:
2728 virtual bool IsDeletable() const { return true; } 2691 virtual bool IsDeletable() const { return true; }
2729 }; 2692 };
2730 2693
2731 2694
2732 class HCheckMaps: public HTemplateInstruction<2> { 2695 class HCheckMaps: public HTemplateInstruction<2> {
2733 public: 2696 public:
2734 static HCheckMaps* New(HValue* value, Handle<Map> map, Zone* zone, 2697 static HCheckMaps* New(HValue* value, Handle<Map> map, Zone* zone,
2735 HValue *typecheck = NULL) { 2698 CompilationInfo* info, HValue *typecheck = NULL);
2736 HCheckMaps* check_map = new(zone) HCheckMaps(value, zone, typecheck);
2737 check_map->map_set_.Add(map, zone);
2738 return check_map;
2739 }
2740
2741 static HCheckMaps* New(HValue* value, SmallMapList* maps, Zone* zone, 2699 static HCheckMaps* New(HValue* value, SmallMapList* maps, Zone* zone,
2742 HValue *typecheck = NULL) { 2700 HValue *typecheck = NULL) {
2743 HCheckMaps* check_map = new(zone) HCheckMaps(value, zone, typecheck); 2701 HCheckMaps* check_map = new(zone) HCheckMaps(value, zone, typecheck);
2744 for (int i = 0; i < maps->length(); i++) { 2702 for (int i = 0; i < maps->length(); i++) {
2745 check_map->map_set_.Add(maps->at(i), zone); 2703 check_map->map_set_.Add(maps->at(i), zone);
2746 } 2704 }
2747 check_map->map_set_.Sort(); 2705 check_map->map_set_.Sort();
2748 return check_map; 2706 return check_map;
2749 } 2707 }
2750 2708
2751 static HCheckMaps* NewWithTransitions(HValue* value, Handle<Map> map, 2709 static HCheckMaps* NewWithTransitions(HValue* value, Handle<Map> map,
2752 Zone* zone) { 2710 Zone* zone, CompilationInfo* info);
2753 HCheckMaps* check_map = new(zone) HCheckMaps(value, zone, value);
2754 check_map->map_set_.Add(map, zone);
2755 2711
2756 // Since transitioned elements maps of the initial map don't fail the map 2712 bool CanOmitMapChecks() { return omit_; }
2757 // check, the CheckMaps instruction doesn't need to depend on ElementsKinds.
2758 check_map->ClearGVNFlag(kDependsOnElementsKind);
2759
2760 ElementsKind kind = map->elements_kind();
2761 bool packed = IsFastPackedElementsKind(kind);
2762 while (CanTransitionToMoreGeneralFastElementsKind(kind, packed)) {
2763 kind = GetNextMoreGeneralFastElementsKind(kind, packed);
2764 Map* transitioned_map =
2765 map->LookupElementsTransitionMap(kind);
2766 if (transitioned_map) {
2767 check_map->map_set_.Add(Handle<Map>(transitioned_map), zone);
2768 }
2769 };
2770 check_map->map_set_.Sort();
2771 return check_map;
2772 }
2773 2713
2774 virtual bool HasEscapingOperandAt(int index) { return false; } 2714 virtual bool HasEscapingOperandAt(int index) { return false; }
2775 virtual Representation RequiredInputRepresentation(int index) { 2715 virtual Representation RequiredInputRepresentation(int index) {
2776 return Representation::Tagged(); 2716 return Representation::Tagged();
2777 } 2717 }
2778 virtual void HandleSideEffectDominator(GVNFlag side_effect, 2718 virtual void HandleSideEffectDominator(GVNFlag side_effect,
2779 HValue* dominator); 2719 HValue* dominator);
2780 virtual void PrintDataTo(StringStream* stream); 2720 virtual void PrintDataTo(StringStream* stream);
2781 virtual HType CalculateInferredType(); 2721 virtual HType CalculateInferredType();
2782 2722
(...skipping 16 matching lines...) Expand all
2799 if (map_unique_ids_.at(i) != b->map_unique_ids_.at(i)) { 2739 if (map_unique_ids_.at(i) != b->map_unique_ids_.at(i)) {
2800 return false; 2740 return false;
2801 } 2741 }
2802 } 2742 }
2803 return true; 2743 return true;
2804 } 2744 }
2805 2745
2806 private: 2746 private:
2807 // Clients should use one of the static New* methods above. 2747 // Clients should use one of the static New* methods above.
2808 HCheckMaps(HValue* value, Zone *zone, HValue* typecheck) 2748 HCheckMaps(HValue* value, Zone *zone, HValue* typecheck)
2809 : map_unique_ids_(0, zone) { 2749 : omit_(false), map_unique_ids_(0, zone) {
2810 SetOperandAt(0, value); 2750 SetOperandAt(0, value);
2811 // Use the object value for the dependency if NULL is passed. 2751 // Use the object value for the dependency if NULL is passed.
2812 // TODO(titzer): do GVN flags already express this dependency? 2752 // TODO(titzer): do GVN flags already express this dependency?
2813 SetOperandAt(1, typecheck != NULL ? typecheck : value); 2753 SetOperandAt(1, typecheck != NULL ? typecheck : value);
2814 set_representation(Representation::Tagged()); 2754 set_representation(Representation::Tagged());
2815 SetFlag(kUseGVN); 2755 SetFlag(kUseGVN);
2816 SetFlag(kTrackSideEffectDominators); 2756 SetFlag(kTrackSideEffectDominators);
2817 SetGVNFlag(kDependsOnMaps); 2757 SetGVNFlag(kDependsOnMaps);
2818 SetGVNFlag(kDependsOnElementsKind); 2758 SetGVNFlag(kDependsOnElementsKind);
2819 } 2759 }
2820 2760
2761 void omit(CompilationInfo* info) {
2762 omit_ = true;
2763 for (int i = 0; i < map_set_.length(); i++) {
2764 Handle<Map> map = map_set_.at(i);
2765 map->AddDependentCompilationInfo(DependentCode::kPrototypeCheckGroup,
2766 info);
2767 }
2768 }
2769
2770 bool omit_;
2821 SmallMapList map_set_; 2771 SmallMapList map_set_;
2822 ZoneList<UniqueValueId> map_unique_ids_; 2772 ZoneList<UniqueValueId> map_unique_ids_;
2823 }; 2773 };
2824 2774
2825 2775
2826 class HCheckFunction: public HUnaryOperation { 2776 class HCheckFunction: public HUnaryOperation {
2827 public: 2777 public:
2828 HCheckFunction(HValue* value, Handle<JSFunction> function) 2778 HCheckFunction(HValue* value, Handle<JSFunction> function)
2829 : HUnaryOperation(value), target_(function), target_unique_id_() { 2779 : HUnaryOperation(value), target_(function), target_unique_id_() {
2830 set_representation(Representation::Tagged()); 2780 set_representation(Representation::Tagged());
(...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after
3067 3017
3068 private: 3018 private:
3069 ZoneList<Handle<JSObject> > prototypes_; 3019 ZoneList<Handle<JSObject> > prototypes_;
3070 ZoneList<Handle<Map> > maps_; 3020 ZoneList<Handle<Map> > maps_;
3071 UniqueValueId first_prototype_unique_id_; 3021 UniqueValueId first_prototype_unique_id_;
3072 UniqueValueId last_prototype_unique_id_; 3022 UniqueValueId last_prototype_unique_id_;
3073 bool can_omit_prototype_maps_; 3023 bool can_omit_prototype_maps_;
3074 }; 3024 };
3075 3025
3076 3026
3027 class InductionVariableData;
3028
3029
3030 struct InductionVariableLimitUpdate {
3031 InductionVariableData* updated_variable;
3032 HValue* limit;
3033 bool limit_is_upper;
3034 bool limit_is_included;
3035
3036 InductionVariableLimitUpdate()
3037 : updated_variable(NULL), limit(NULL),
3038 limit_is_upper(false), limit_is_included(false) {}
3039 };
3040
3041
3042 class HBoundsCheck;
3043 class HPhi;
3044 class HConstant;
3045 class HBitwise;
3046
3047
3048 class InductionVariableData : public ZoneObject {
3049 public:
3050 class InductionVariableCheck : public ZoneObject {
3051 public:
3052 HBoundsCheck* check() { return check_; }
3053 InductionVariableCheck* next() { return next_; }
3054 bool HasUpperLimit() { return upper_limit_ >= 0; }
3055 int32_t upper_limit() {
3056 ASSERT(HasUpperLimit());
3057 return upper_limit_;
3058 }
3059 void set_upper_limit(int32_t upper_limit) {
3060 upper_limit_ = upper_limit;
3061 }
3062
3063 bool processed() { return processed_; }
3064 void set_processed() { processed_ = true; }
3065
3066 InductionVariableCheck(HBoundsCheck* check,
3067 InductionVariableCheck* next,
3068 int32_t upper_limit = kNoLimit)
3069 : check_(check), next_(next), upper_limit_(upper_limit),
3070 processed_(false) {}
3071
3072 private:
3073 HBoundsCheck* check_;
3074 InductionVariableCheck* next_;
3075 int32_t upper_limit_;
3076 bool processed_;
3077 };
3078
3079 class ChecksRelatedToLength : public ZoneObject {
3080 public:
3081 HValue* length() { return length_; }
3082 ChecksRelatedToLength* next() { return next_; }
3083 InductionVariableCheck* checks() { return checks_; }
3084
3085 void AddCheck(HBoundsCheck* check, int32_t upper_limit = kNoLimit);
3086 void CloseCurrentBlock();
3087
3088 ChecksRelatedToLength(HValue* length, ChecksRelatedToLength* next)
3089 : length_(length), next_(next), checks_(NULL),
3090 first_check_in_block_(NULL),
3091 added_index_(NULL),
3092 added_constant_(NULL),
3093 current_and_mask_in_block_(0),
3094 current_or_mask_in_block_(0) {}
3095
3096 private:
3097 void UseNewIndexInCurrentBlock(Token::Value token,
3098 int32_t mask,
3099 HValue* index_base,
3100 HValue* context);
3101
3102 HBoundsCheck* first_check_in_block() { return first_check_in_block_; }
3103 HBitwise* added_index() { return added_index_; }
3104 void set_added_index(HBitwise* index) { added_index_ = index; }
3105 HConstant* added_constant() { return added_constant_; }
3106 void set_added_constant(HConstant* constant) { added_constant_ = constant; }
3107 int32_t current_and_mask_in_block() { return current_and_mask_in_block_; }
3108 int32_t current_or_mask_in_block() { return current_or_mask_in_block_; }
3109 int32_t current_upper_limit() { return current_upper_limit_; }
3110
3111 HValue* length_;
3112 ChecksRelatedToLength* next_;
3113 InductionVariableCheck* checks_;
3114
3115 HBoundsCheck* first_check_in_block_;
3116 HBitwise* added_index_;
3117 HConstant* added_constant_;
3118 int32_t current_and_mask_in_block_;
3119 int32_t current_or_mask_in_block_;
3120 int32_t current_upper_limit_;
3121 };
3122
3123 struct LimitFromPredecessorBlock {
3124 InductionVariableData* variable;
3125 Token::Value token;
3126 HValue* limit;
3127 HBasicBlock* other_target;
3128
3129 bool LimitIsValid() { return token != Token::ILLEGAL; }
3130
3131 bool LimitIsIncluded() {
3132 return Token::IsEqualityOp(token) ||
3133 token == Token::GTE || token == Token::LTE;
3134 }
3135 bool LimitIsUpper() {
3136 return token == Token::LTE || token == Token::LT || token == Token::NE;
3137 }
3138
3139 LimitFromPredecessorBlock()
3140 : variable(NULL),
3141 token(Token::ILLEGAL),
3142 limit(NULL),
3143 other_target(NULL) {}
3144 };
3145
3146 static const int32_t kNoLimit = -1;
3147
3148 static InductionVariableData* ExaminePhi(HPhi* phi);
3149 static void ComputeLimitFromPredecessorBlock(
3150 HBasicBlock* block,
3151 LimitFromPredecessorBlock* result);
3152 static bool ComputeInductionVariableLimit(
3153 HBasicBlock* block,
3154 InductionVariableLimitUpdate* additional_limit);
3155
3156 struct BitwiseDecompositionResult {
3157 HValue* base;
3158 int32_t and_mask;
3159 int32_t or_mask;
3160 HValue* context;
3161
3162 BitwiseDecompositionResult()
3163 : base(NULL), and_mask(0), or_mask(0), context(NULL) {}
3164 };
3165 static void DecomposeBitwise(HValue* value,
3166 BitwiseDecompositionResult* result);
3167
3168 void AddCheck(HBoundsCheck* check, int32_t upper_limit = kNoLimit);
3169
3170 bool CheckIfBranchIsLoopGuard(Token::Value token,
3171 HBasicBlock* current_branch,
3172 HBasicBlock* other_branch);
3173
3174 void UpdateAdditionalLimit(InductionVariableLimitUpdate* update);
3175
3176 HPhi* phi() { return phi_; }
3177 HValue* base() { return base_; }
3178 int32_t increment() { return increment_; }
3179 HValue* limit() { return limit_; }
3180 bool limit_included() { return limit_included_; }
3181 HBasicBlock* limit_validity() { return limit_validity_; }
3182 HBasicBlock* induction_exit_block() { return induction_exit_block_; }
3183 HBasicBlock* induction_exit_target() { return induction_exit_target_; }
3184 ChecksRelatedToLength* checks() { return checks_; }
3185 HValue* additional_upper_limit() { return additional_upper_limit_; }
3186 bool additional_upper_limit_is_included() {
3187 return additional_upper_limit_is_included_;
3188 }
3189 HValue* additional_lower_limit() { return additional_lower_limit_; }
3190 bool additional_lower_limit_is_included() {
3191 return additional_lower_limit_is_included_;
3192 }
3193
3194 bool LowerLimitIsNonNegativeConstant() {
3195 if (base()->IsInteger32Constant() && base()->GetInteger32Constant() >= 0) {
3196 return true;
3197 }
3198 if (additional_lower_limit() != NULL &&
3199 additional_lower_limit()->IsInteger32Constant() &&
3200 additional_lower_limit()->GetInteger32Constant() >= 0) {
3201 // Ignoring the corner case of !additional_lower_limit_is_included()
3202 // is safe, handling it adds unneeded complexity.
3203 return true;
3204 }
3205 return false;
3206 }
3207
3208 int32_t ComputeUpperLimit(int32_t and_mask, int32_t or_mask);
3209
3210 private:
3211 template <class T> void swap(T* a, T* b) {
3212 T c(*a);
3213 *a = *b;
3214 *b = c;
3215 }
3216
3217 InductionVariableData(HPhi* phi, HValue* base, int32_t increment)
3218 : phi_(phi), base_(IgnoreOsrValue(base)), increment_(increment),
3219 limit_(NULL), limit_included_(false), limit_validity_(NULL),
3220 induction_exit_block_(NULL), induction_exit_target_(NULL),
3221 checks_(NULL),
3222 additional_upper_limit_(NULL),
3223 additional_upper_limit_is_included_(false),
3224 additional_lower_limit_(NULL),
3225 additional_lower_limit_is_included_(false) {}
3226
3227 static int32_t ComputeIncrement(HPhi* phi, HValue* phi_operand);
3228
3229 static HValue* IgnoreOsrValue(HValue* v);
3230 static InductionVariableData* GetInductionVariableData(HValue* v);
3231
3232 HPhi* phi_;
3233 HValue* base_;
3234 int32_t increment_;
3235 HValue* limit_;
3236 bool limit_included_;
3237 HBasicBlock* limit_validity_;
3238 HBasicBlock* induction_exit_block_;
3239 HBasicBlock* induction_exit_target_;
3240 ChecksRelatedToLength* checks_;
3241 HValue* additional_upper_limit_;
3242 bool additional_upper_limit_is_included_;
3243 HValue* additional_lower_limit_;
3244 bool additional_lower_limit_is_included_;
3245 };
3246
3247
3077 class HPhi: public HValue { 3248 class HPhi: public HValue {
3078 public: 3249 public:
3079 HPhi(int merged_index, Zone* zone) 3250 HPhi(int merged_index, Zone* zone)
3080 : inputs_(2, zone), 3251 : inputs_(2, zone),
3081 merged_index_(merged_index), 3252 merged_index_(merged_index),
3082 phi_id_(-1) { 3253 phi_id_(-1),
3254 induction_variable_data_(NULL) {
3083 for (int i = 0; i < Representation::kNumRepresentations; i++) { 3255 for (int i = 0; i < Representation::kNumRepresentations; i++) {
3084 non_phi_uses_[i] = 0; 3256 non_phi_uses_[i] = 0;
3085 indirect_uses_[i] = 0; 3257 indirect_uses_[i] = 0;
3086 } 3258 }
3087 ASSERT(merged_index >= 0); 3259 ASSERT(merged_index >= 0);
3088 SetFlag(kFlexibleRepresentation); 3260 SetFlag(kFlexibleRepresentation);
3089 SetFlag(kAllowUndefinedAsNaN); 3261 SetFlag(kAllowUndefinedAsNaN);
3090 } 3262 }
3091 3263
3092 virtual Representation RepresentationFromInputs(); 3264 virtual Representation RepresentationFromInputs();
(...skipping 10 matching lines...) Expand all
3103 virtual int OperandCount() { return inputs_.length(); } 3275 virtual int OperandCount() { return inputs_.length(); }
3104 virtual HValue* OperandAt(int index) const { return inputs_[index]; } 3276 virtual HValue* OperandAt(int index) const { return inputs_[index]; }
3105 HValue* GetRedundantReplacement(); 3277 HValue* GetRedundantReplacement();
3106 void AddInput(HValue* value); 3278 void AddInput(HValue* value);
3107 bool HasRealUses(); 3279 bool HasRealUses();
3108 3280
3109 bool IsReceiver() const { return merged_index_ == 0; } 3281 bool IsReceiver() const { return merged_index_ == 0; }
3110 3282
3111 int merged_index() const { return merged_index_; } 3283 int merged_index() const { return merged_index_; }
3112 3284
3285 InductionVariableData* induction_variable_data() {
3286 return induction_variable_data_;
3287 }
3288 bool IsInductionVariable() {
3289 return induction_variable_data_ != NULL;
3290 }
3291 bool IsLimitedInductionVariable() {
3292 return IsInductionVariable() &&
3293 induction_variable_data_->limit() != NULL;
3294 }
3295 void DetectInductionVariable() {
3296 ASSERT(induction_variable_data_ == NULL);
3297 induction_variable_data_ = InductionVariableData::ExaminePhi(this);
3298 }
3299
3113 virtual void AddInformativeDefinitions(); 3300 virtual void AddInformativeDefinitions();
3114 3301
3115 virtual void PrintTo(StringStream* stream); 3302 virtual void PrintTo(StringStream* stream);
3116 3303
3117 #ifdef DEBUG 3304 #ifdef DEBUG
3118 virtual void Verify(); 3305 virtual void Verify();
3119 #endif 3306 #endif
3120 3307
3121 void InitRealUses(int id); 3308 void InitRealUses(int id);
3122 void AddNonPhiUsesFrom(HPhi* other); 3309 void AddNonPhiUsesFrom(HPhi* other);
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
3170 int offset = 0, 3357 int offset = 0,
3171 int scale = 0); 3358 int scale = 0);
3172 3359
3173 private: 3360 private:
3174 ZoneList<HValue*> inputs_; 3361 ZoneList<HValue*> inputs_;
3175 int merged_index_; 3362 int merged_index_;
3176 3363
3177 int non_phi_uses_[Representation::kNumRepresentations]; 3364 int non_phi_uses_[Representation::kNumRepresentations];
3178 int indirect_uses_[Representation::kNumRepresentations]; 3365 int indirect_uses_[Representation::kNumRepresentations];
3179 int phi_id_; 3366 int phi_id_;
3367 InductionVariableData* induction_variable_data_;
3180 }; 3368 };
3181 3369
3182 3370
3183 class HInductionVariableAnnotation : public HUnaryOperation { 3371 class HInductionVariableAnnotation : public HUnaryOperation {
3184 public: 3372 public:
3185 static HInductionVariableAnnotation* AddToGraph(HPhi* phi, 3373 static HInductionVariableAnnotation* AddToGraph(HPhi* phi,
3186 NumericRelation relation, 3374 NumericRelation relation,
3187 int operand_index); 3375 int operand_index);
3188 3376
3189 NumericRelation relation() { return relation_; } 3377 NumericRelation relation() { return relation_; }
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
3289 Factory* factory = Isolate::Current()->factory(); 3477 Factory* factory = Isolate::Current()->factory();
3290 // Default arguments to is_not_in_new_space depend on this heap number 3478 // Default arguments to is_not_in_new_space depend on this heap number
3291 // to be tenured so that it's guaranteed not be be located in new space. 3479 // to be tenured so that it's guaranteed not be be located in new space.
3292 handle_ = factory->NewNumber(double_value_, TENURED); 3480 handle_ = factory->NewNumber(double_value_, TENURED);
3293 } 3481 }
3294 AllowDeferredHandleDereference smi_check; 3482 AllowDeferredHandleDereference smi_check;
3295 ASSERT(has_int32_value_ || !handle_->IsSmi()); 3483 ASSERT(has_int32_value_ || !handle_->IsSmi());
3296 return handle_; 3484 return handle_;
3297 } 3485 }
3298 3486
3487 bool InstanceOf(Handle<Map> map) {
3488 return handle_->IsJSObject() &&
3489 Handle<JSObject>::cast(handle_)->map() == *map;
3490 }
3491
3299 bool IsSpecialDouble() const { 3492 bool IsSpecialDouble() const {
3300 return has_double_value_ && 3493 return has_double_value_ &&
3301 (BitCast<int64_t>(double_value_) == BitCast<int64_t>(-0.0) || 3494 (BitCast<int64_t>(double_value_) == BitCast<int64_t>(-0.0) ||
3302 FixedDoubleArray::is_the_hole_nan(double_value_) || 3495 FixedDoubleArray::is_the_hole_nan(double_value_) ||
3303 std::isnan(double_value_)); 3496 std::isnan(double_value_));
3304 } 3497 }
3305 3498
3306 bool NotInNewSpace() const { 3499 bool NotInNewSpace() const {
3307 return is_not_in_new_space_; 3500 return is_not_in_new_space_;
3308 } 3501 }
(...skipping 23 matching lines...) Expand all
3332 3525
3333 bool IsCell() const { 3526 bool IsCell() const {
3334 return is_cell_; 3527 return is_cell_;
3335 } 3528 }
3336 3529
3337 virtual Representation RequiredInputRepresentation(int index) { 3530 virtual Representation RequiredInputRepresentation(int index) {
3338 return Representation::None(); 3531 return Representation::None();
3339 } 3532 }
3340 3533
3341 virtual Representation KnownOptimalRepresentation() { 3534 virtual Representation KnownOptimalRepresentation() {
3342 if (HasSmiValue()) return Representation::Smi(); 3535 if (HasSmiValue() && kSmiValueSize == 31) return Representation::Smi();
3343 if (HasInteger32Value()) return Representation::Integer32(); 3536 if (HasInteger32Value()) return Representation::Integer32();
3344 if (HasNumberValue()) return Representation::Double(); 3537 if (HasNumberValue()) return Representation::Double();
3345 return Representation::Tagged(); 3538 return Representation::Tagged();
3346 } 3539 }
3347 3540
3348 virtual bool EmitAtUses(); 3541 virtual bool EmitAtUses();
3349 virtual void PrintDataTo(StringStream* stream); 3542 virtual void PrintDataTo(StringStream* stream);
3350 virtual HType CalculateInferredType(); 3543 virtual HType CalculateInferredType();
3351 bool IsInteger() { return handle()->IsSmi(); } 3544 bool IsInteger() { return handle()->IsSmi(); }
3352 HConstant* CopyToRepresentation(Representation r, Zone* zone) const; 3545 HConstant* CopyToRepresentation(Representation r, Zone* zone) const;
3353 HConstant* CopyToTruncatedInt32(Zone* zone) const; 3546 Maybe<HConstant*> CopyToTruncatedInt32(Zone* zone);
3547 Maybe<HConstant*> CopyToTruncatedNumber(Zone* zone);
3354 bool HasInteger32Value() const { return has_int32_value_; } 3548 bool HasInteger32Value() const { return has_int32_value_; }
3355 int32_t Integer32Value() const { 3549 int32_t Integer32Value() const {
3356 ASSERT(HasInteger32Value()); 3550 ASSERT(HasInteger32Value());
3357 return int32_value_; 3551 return int32_value_;
3358 } 3552 }
3359 bool HasSmiValue() const { return has_smi_value_; } 3553 bool HasSmiValue() const { return has_smi_value_; }
3360 bool HasDoubleValue() const { return has_double_value_; } 3554 bool HasDoubleValue() const { return has_double_value_; }
3361 double DoubleValue() const { 3555 double DoubleValue() const {
3362 ASSERT(HasDoubleValue()); 3556 ASSERT(HasDoubleValue());
3363 return double_value_; 3557 return double_value_;
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
3493 if (!IsCommutative()) return false; 3687 if (!IsCommutative()) return false;
3494 3688
3495 // Constant operands are better off on the right, they can be inlined in 3689 // Constant operands are better off on the right, they can be inlined in
3496 // many situations on most platforms. 3690 // many situations on most platforms.
3497 if (left()->IsConstant()) return true; 3691 if (left()->IsConstant()) return true;
3498 if (right()->IsConstant()) return false; 3692 if (right()->IsConstant()) return false;
3499 3693
3500 // Otherwise, if there is only one use of the right operand, it would be 3694 // Otherwise, if there is only one use of the right operand, it would be
3501 // better off on the left for platforms that only have 2-arg arithmetic 3695 // better off on the left for platforms that only have 2-arg arithmetic
3502 // ops (e.g ia32, x64) that clobber the left operand. 3696 // ops (e.g ia32, x64) that clobber the left operand.
3503 return (right()->UseCount() == 1); 3697 return right()->UseCount() == 1;
3504 } 3698 }
3505 3699
3506 HValue* BetterLeftOperand() { 3700 HValue* BetterLeftOperand() {
3507 return AreOperandsBetterSwitched() ? right() : left(); 3701 return AreOperandsBetterSwitched() ? right() : left();
3508 } 3702 }
3509 3703
3510 HValue* BetterRightOperand() { 3704 HValue* BetterRightOperand() {
3511 return AreOperandsBetterSwitched() ? left() : right(); 3705 return AreOperandsBetterSwitched() ? left() : right();
3512 } 3706 }
3513 3707
3514 void set_observed_input_representation(int index, Representation rep) { 3708 void set_observed_input_representation(int index, Representation rep) {
3515 ASSERT(index >= 1 && index <= 2); 3709 ASSERT(index >= 1 && index <= 2);
3516 observed_input_representation_[index - 1] = rep; 3710 observed_input_representation_[index - 1] = rep;
3517 } 3711 }
3518 3712
3519 virtual void initialize_output_representation(Representation observed) { 3713 virtual void initialize_output_representation(Representation observed) {
3520 observed_output_representation_ = observed; 3714 observed_output_representation_ = observed;
3521 } 3715 }
3522 3716
3523 virtual Representation observed_input_representation(int index) { 3717 virtual Representation observed_input_representation(int index) {
3524 if (index == 0) return Representation::Tagged(); 3718 if (index == 0) return Representation::Tagged();
3525 return observed_input_representation_[index - 1]; 3719 return observed_input_representation_[index - 1];
3526 } 3720 }
3527 3721
3722 virtual void UpdateRepresentation(Representation new_rep,
3723 HInferRepresentationPhase* h_infer,
3724 const char* reason) {
3725 Representation rep = !FLAG_smi_binop && new_rep.IsSmi()
3726 ? Representation::Integer32() : new_rep;
3727 HValue::UpdateRepresentation(rep, h_infer, reason);
3728 }
3729
3528 virtual void InferRepresentation(HInferRepresentationPhase* h_infer); 3730 virtual void InferRepresentation(HInferRepresentationPhase* h_infer);
3529 virtual Representation RepresentationFromInputs(); 3731 virtual Representation RepresentationFromInputs();
3732 Representation RepresentationFromOutput();
3530 virtual void AssumeRepresentation(Representation r); 3733 virtual void AssumeRepresentation(Representation r);
3531 3734
3532 virtual void UpdateRepresentation(Representation new_rep,
3533 HInferRepresentationPhase* h_infer,
3534 const char* reason) {
3535 // By default, binary operations don't handle Smis.
3536 if (new_rep.IsSmi()) {
3537 new_rep = Representation::Integer32();
3538 }
3539 HValue::UpdateRepresentation(new_rep, h_infer, reason);
3540 }
3541
3542 virtual bool IsCommutative() const { return false; } 3735 virtual bool IsCommutative() const { return false; }
3543 3736
3544 virtual void PrintDataTo(StringStream* stream); 3737 virtual void PrintDataTo(StringStream* stream);
3545 3738
3739 virtual Representation RequiredInputRepresentation(int index) {
3740 if (index == 0) return Representation::Tagged();
3741 return representation();
3742 }
3743
3546 DECLARE_ABSTRACT_INSTRUCTION(BinaryOperation) 3744 DECLARE_ABSTRACT_INSTRUCTION(BinaryOperation)
3547 3745
3548 private: 3746 private:
3549 bool IgnoreObservedOutputRepresentation(Representation current_rep); 3747 bool IgnoreObservedOutputRepresentation(Representation current_rep);
3550 3748
3551 Representation observed_input_representation_[2]; 3749 Representation observed_input_representation_[2];
3552 Representation observed_output_representation_; 3750 Representation observed_output_representation_;
3553 }; 3751 };
3554 3752
3555 3753
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
3688 3886
3689 class HBoundsCheck: public HTemplateInstruction<2> { 3887 class HBoundsCheck: public HTemplateInstruction<2> {
3690 public: 3888 public:
3691 // Normally HBoundsCheck should be created using the 3889 // Normally HBoundsCheck should be created using the
3692 // HGraphBuilder::AddBoundsCheck() helper. 3890 // HGraphBuilder::AddBoundsCheck() helper.
3693 // However when building stubs, where we know that the arguments are Int32, 3891 // However when building stubs, where we know that the arguments are Int32,
3694 // it makes sense to invoke this constructor directly. 3892 // it makes sense to invoke this constructor directly.
3695 HBoundsCheck(HValue* index, HValue* length) 3893 HBoundsCheck(HValue* index, HValue* length)
3696 : skip_check_(false), 3894 : skip_check_(false),
3697 base_(NULL), offset_(0), scale_(0), 3895 base_(NULL), offset_(0), scale_(0),
3698 responsibility_direction_(DIRECTION_NONE) { 3896 responsibility_direction_(DIRECTION_NONE),
3897 allow_equality_(false) {
3699 SetOperandAt(0, index); 3898 SetOperandAt(0, index);
3700 SetOperandAt(1, length); 3899 SetOperandAt(1, length);
3701 SetFlag(kFlexibleRepresentation); 3900 SetFlag(kFlexibleRepresentation);
3702 SetFlag(kUseGVN); 3901 SetFlag(kUseGVN);
3703 } 3902 }
3704 3903
3705 bool skip_check() { return skip_check_; } 3904 bool skip_check() const { return skip_check_; }
3706 void set_skip_check(bool skip_check) { skip_check_ = skip_check; } 3905 void set_skip_check() { skip_check_ = true; }
3707 HValue* base() { return base_; } 3906 HValue* base() { return base_; }
3708 int offset() { return offset_; } 3907 int offset() { return offset_; }
3709 int scale() { return scale_; } 3908 int scale() { return scale_; }
3710 bool index_can_increase() { 3909 bool index_can_increase() {
3711 return (responsibility_direction_ & DIRECTION_LOWER) == 0; 3910 return (responsibility_direction_ & DIRECTION_LOWER) == 0;
3712 } 3911 }
3713 bool index_can_decrease() { 3912 bool index_can_decrease() {
3714 return (responsibility_direction_ & DIRECTION_UPPER) == 0; 3913 return (responsibility_direction_ & DIRECTION_UPPER) == 0;
3715 } 3914 }
3716 3915
(...skipping 11 matching lines...) Expand all
3728 base_ = index(); 3927 base_ = index();
3729 offset_ = 0; 3928 offset_ = 0;
3730 scale_ = 0; 3929 scale_ = 0;
3731 return false; 3930 return false;
3732 } 3931 }
3733 } 3932 }
3734 3933
3735 virtual Representation RequiredInputRepresentation(int arg_index) { 3934 virtual Representation RequiredInputRepresentation(int arg_index) {
3736 return representation(); 3935 return representation();
3737 } 3936 }
3937 virtual bool IsDeletable() const {
3938 return skip_check() && !FLAG_debug_code;
3939 }
3738 3940
3739 virtual bool IsRelationTrueInternal(NumericRelation relation, 3941 virtual bool IsRelationTrueInternal(NumericRelation relation,
3740 HValue* related_value, 3942 HValue* related_value,
3741 int offset = 0, 3943 int offset = 0,
3742 int scale = 0); 3944 int scale = 0);
3743 3945
3744 virtual void PrintDataTo(StringStream* stream); 3946 virtual void PrintDataTo(StringStream* stream);
3745 virtual void InferRepresentation(HInferRepresentationPhase* h_infer); 3947 virtual void InferRepresentation(HInferRepresentationPhase* h_infer);
3746 3948
3747 HValue* index() { return OperandAt(0); } 3949 HValue* index() { return OperandAt(0); }
3748 HValue* length() { return OperandAt(1); } 3950 HValue* length() { return OperandAt(1); }
3951 bool allow_equality() { return allow_equality_; }
3952 void set_allow_equality(bool v) { allow_equality_ = v; }
3749 3953
3750 virtual int RedefinedOperandIndex() { return 0; } 3954 virtual int RedefinedOperandIndex() { return 0; }
3751 virtual bool IsPurelyInformativeDefinition() { return skip_check(); } 3955 virtual bool IsPurelyInformativeDefinition() { return skip_check(); }
3752 virtual void AddInformativeDefinitions(); 3956 virtual void AddInformativeDefinitions();
3753 3957
3754 DECLARE_CONCRETE_INSTRUCTION(BoundsCheck) 3958 DECLARE_CONCRETE_INSTRUCTION(BoundsCheck)
3755 3959
3756 protected: 3960 protected:
3757 friend class HBoundsCheckBaseIndexInformation; 3961 friend class HBoundsCheckBaseIndexInformation;
3758 3962
3759 virtual void SetResponsibilityForRange(RangeGuaranteeDirection direction) { 3963 virtual void SetResponsibilityForRange(RangeGuaranteeDirection direction) {
3760 responsibility_direction_ = static_cast<RangeGuaranteeDirection>( 3964 responsibility_direction_ = static_cast<RangeGuaranteeDirection>(
3761 responsibility_direction_ | direction); 3965 responsibility_direction_ | direction);
3762 } 3966 }
3763 3967
3764 virtual bool DataEquals(HValue* other) { return true; } 3968 virtual bool DataEquals(HValue* other) { return true; }
3765 virtual void TryGuaranteeRangeChanging(RangeEvaluationContext* context); 3969 virtual void TryGuaranteeRangeChanging(RangeEvaluationContext* context);
3766 bool skip_check_; 3970 bool skip_check_;
3767 HValue* base_; 3971 HValue* base_;
3768 int offset_; 3972 int offset_;
3769 int scale_; 3973 int scale_;
3770 RangeGuaranteeDirection responsibility_direction_; 3974 RangeGuaranteeDirection responsibility_direction_;
3975 bool allow_equality_;
3771 }; 3976 };
3772 3977
3773 3978
3774 class HBoundsCheckBaseIndexInformation: public HTemplateInstruction<2> { 3979 class HBoundsCheckBaseIndexInformation: public HTemplateInstruction<2> {
3775 public: 3980 public:
3776 explicit HBoundsCheckBaseIndexInformation(HBoundsCheck* check) { 3981 explicit HBoundsCheckBaseIndexInformation(HBoundsCheck* check) {
3777 DecompositionResult decomposition; 3982 DecompositionResult decomposition;
3778 if (check->index()->TryDecompose(&decomposition)) { 3983 if (check->index()->TryDecompose(&decomposition)) {
3779 SetOperandAt(0, decomposition.base()); 3984 SetOperandAt(0, decomposition.base());
3780 SetOperandAt(1, check); 3985 SetOperandAt(1, check);
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
3814 class HBitwiseBinaryOperation: public HBinaryOperation { 4019 class HBitwiseBinaryOperation: public HBinaryOperation {
3815 public: 4020 public:
3816 HBitwiseBinaryOperation(HValue* context, HValue* left, HValue* right) 4021 HBitwiseBinaryOperation(HValue* context, HValue* left, HValue* right)
3817 : HBinaryOperation(context, left, right) { 4022 : HBinaryOperation(context, left, right) {
3818 SetFlag(kFlexibleRepresentation); 4023 SetFlag(kFlexibleRepresentation);
3819 SetFlag(kTruncatingToInt32); 4024 SetFlag(kTruncatingToInt32);
3820 SetFlag(kAllowUndefinedAsNaN); 4025 SetFlag(kAllowUndefinedAsNaN);
3821 SetAllSideEffects(); 4026 SetAllSideEffects();
3822 } 4027 }
3823 4028
3824 virtual Representation RequiredInputRepresentation(int index) {
3825 return index == 0
3826 ? Representation::Tagged()
3827 : representation();
3828 }
3829
3830 virtual void RepresentationChanged(Representation to) { 4029 virtual void RepresentationChanged(Representation to) {
3831 if (!to.IsTagged()) { 4030 if (!to.IsTagged()) {
3832 ASSERT(to.IsInteger32()); 4031 ASSERT(to.IsSmiOrInteger32());
3833 ClearAllSideEffects(); 4032 ClearAllSideEffects();
3834 SetFlag(kUseGVN); 4033 SetFlag(kUseGVN);
3835 } else { 4034 } else {
3836 SetAllSideEffects(); 4035 SetAllSideEffects();
3837 ClearFlag(kUseGVN); 4036 ClearFlag(kUseGVN);
3838 } 4037 }
3839 } 4038 }
3840 4039
3841 virtual void UpdateRepresentation(Representation new_rep, 4040 virtual void UpdateRepresentation(Representation new_rep,
3842 HInferRepresentationPhase* h_infer, 4041 HInferRepresentationPhase* h_infer,
3843 const char* reason) { 4042 const char* reason) {
3844 // We only generate either int32 or generic tagged bitwise operations. 4043 // We only generate either int32 or generic tagged bitwise operations.
3845 if (new_rep.IsSmi() || new_rep.IsDouble()) { 4044 if (new_rep.IsDouble()) new_rep = Representation::Integer32();
3846 new_rep = Representation::Integer32(); 4045 HBinaryOperation::UpdateRepresentation(new_rep, h_infer, reason);
3847 } 4046 }
3848 HValue::UpdateRepresentation(new_rep, h_infer, reason); 4047
4048 virtual Representation observed_input_representation(int index) {
4049 Representation r = HBinaryOperation::observed_input_representation(index);
4050 if (r.IsDouble()) return Representation::Integer32();
4051 return r;
3849 } 4052 }
3850 4053
3851 virtual void initialize_output_representation(Representation observed) { 4054 virtual void initialize_output_representation(Representation observed) {
3852 if (observed.IsDouble()) observed = Representation::Integer32(); 4055 if (observed.IsDouble()) observed = Representation::Integer32();
3853 HBinaryOperation::initialize_output_representation(observed); 4056 HBinaryOperation::initialize_output_representation(observed);
3854 } 4057 }
3855 4058
3856 virtual HType CalculateInferredType(); 4059 virtual HType CalculateInferredType();
3857 4060
3858 DECLARE_ABSTRACT_INSTRUCTION(BitwiseBinaryOperation) 4061 DECLARE_ABSTRACT_INSTRUCTION(BitwiseBinaryOperation)
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
3904 if (to.IsTagged()) { 4107 if (to.IsTagged()) {
3905 SetAllSideEffects(); 4108 SetAllSideEffects();
3906 ClearFlag(kUseGVN); 4109 ClearFlag(kUseGVN);
3907 } else { 4110 } else {
3908 ClearAllSideEffects(); 4111 ClearAllSideEffects();
3909 SetFlag(kUseGVN); 4112 SetFlag(kUseGVN);
3910 } 4113 }
3911 } 4114 }
3912 4115
3913 virtual HType CalculateInferredType(); 4116 virtual HType CalculateInferredType();
3914 virtual Representation RequiredInputRepresentation(int index) {
3915 return index == 0
3916 ? Representation::Tagged()
3917 : representation();
3918 }
3919 4117
3920 DECLARE_ABSTRACT_INSTRUCTION(ArithmeticBinaryOperation) 4118 DECLARE_ABSTRACT_INSTRUCTION(ArithmeticBinaryOperation)
3921 4119
3922 private: 4120 private:
3923 virtual bool IsDeletable() const { return true; } 4121 virtual bool IsDeletable() const { return true; }
3924 }; 4122 };
3925 4123
3926 4124
3927 class HCompareGeneric: public HBinaryOperation { 4125 class HCompareGeneric: public HBinaryOperation {
3928 public: 4126 public:
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
4011 } 4209 }
4012 4210
4013 virtual Representation observed_input_representation(int index) { 4211 virtual Representation observed_input_representation(int index) {
4014 return Representation::Tagged(); 4212 return Representation::Tagged();
4015 } 4213 }
4016 4214
4017 DECLARE_CONCRETE_INSTRUCTION(CompareObjectEqAndBranch) 4215 DECLARE_CONCRETE_INSTRUCTION(CompareObjectEqAndBranch)
4018 }; 4216 };
4019 4217
4020 4218
4021 class HCompareConstantEqAndBranch: public HUnaryControlInstruction {
4022 public:
4023 HCompareConstantEqAndBranch(HValue* left, int right, Token::Value op)
4024 : HUnaryControlInstruction(left, NULL, NULL), op_(op), right_(right) {
4025 ASSERT(op == Token::EQ_STRICT);
4026 }
4027
4028 Token::Value op() const { return op_; }
4029 HValue* left() { return value(); }
4030 int right() const { return right_; }
4031
4032 virtual Representation RequiredInputRepresentation(int index) {
4033 return Representation::Integer32();
4034 }
4035
4036 DECLARE_CONCRETE_INSTRUCTION(CompareConstantEqAndBranch);
4037
4038 private:
4039 const Token::Value op_;
4040 const int right_;
4041 };
4042
4043
4044 class HIsObjectAndBranch: public HUnaryControlInstruction { 4219 class HIsObjectAndBranch: public HUnaryControlInstruction {
4045 public: 4220 public:
4046 explicit HIsObjectAndBranch(HValue* value) 4221 explicit HIsObjectAndBranch(HValue* value)
4047 : HUnaryControlInstruction(value, NULL, NULL) { } 4222 : HUnaryControlInstruction(value, NULL, NULL) { }
4048 4223
4049 virtual Representation RequiredInputRepresentation(int index) { 4224 virtual Representation RequiredInputRepresentation(int index) {
4050 return Representation::Tagged(); 4225 return Representation::Tagged();
4051 } 4226 }
4052 4227
4053 DECLARE_CONCRETE_INSTRUCTION(IsObjectAndBranch) 4228 DECLARE_CONCRETE_INSTRUCTION(IsObjectAndBranch)
(...skipping 414 matching lines...) Expand 10 before | Expand all | Expand 10 after
4468 4643
4469 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited); 4644 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
4470 4645
4471 virtual HValue* Canonicalize(); 4646 virtual HValue* Canonicalize();
4472 4647
4473 // Only commutative if it is certain that not two objects are multiplicated. 4648 // Only commutative if it is certain that not two objects are multiplicated.
4474 virtual bool IsCommutative() const { 4649 virtual bool IsCommutative() const {
4475 return !representation().IsTagged(); 4650 return !representation().IsTagged();
4476 } 4651 }
4477 4652
4653 virtual void UpdateRepresentation(Representation new_rep,
4654 HInferRepresentationPhase* h_infer,
4655 const char* reason) {
4656 if (new_rep.IsSmi()) new_rep = Representation::Integer32();
4657 HArithmeticBinaryOperation::UpdateRepresentation(new_rep, h_infer, reason);
4658 }
4659
4478 DECLARE_CONCRETE_INSTRUCTION(Mul) 4660 DECLARE_CONCRETE_INSTRUCTION(Mul)
4479 4661
4480 protected: 4662 protected:
4481 virtual bool DataEquals(HValue* other) { return true; } 4663 virtual bool DataEquals(HValue* other) { return true; }
4482 4664
4483 virtual Range* InferRange(Zone* zone); 4665 virtual Range* InferRange(Zone* zone);
4484 4666
4485 private: 4667 private:
4486 HMul(HValue* context, HValue* left, HValue* right) 4668 HMul(HValue* context, HValue* left, HValue* right)
4487 : HArithmeticBinaryOperation(context, left, right) { 4669 : HArithmeticBinaryOperation(context, left, right) {
(...skipping 19 matching lines...) Expand all
4507 return value != 0 && (IsPowerOf2(value) || IsPowerOf2(-value)); 4689 return value != 0 && (IsPowerOf2(value) || IsPowerOf2(-value));
4508 } 4690 }
4509 4691
4510 return false; 4692 return false;
4511 } 4693 }
4512 4694
4513 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited); 4695 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
4514 4696
4515 virtual HValue* Canonicalize(); 4697 virtual HValue* Canonicalize();
4516 4698
4699 virtual void UpdateRepresentation(Representation new_rep,
4700 HInferRepresentationPhase* h_infer,
4701 const char* reason) {
4702 if (new_rep.IsSmi()) new_rep = Representation::Integer32();
4703 HArithmeticBinaryOperation::UpdateRepresentation(new_rep, h_infer, reason);
4704 }
4705
4517 DECLARE_CONCRETE_INSTRUCTION(Mod) 4706 DECLARE_CONCRETE_INSTRUCTION(Mod)
4518 4707
4519 protected: 4708 protected:
4520 virtual bool DataEquals(HValue* other) { return true; } 4709 virtual bool DataEquals(HValue* other) { return true; }
4521 4710
4522 virtual Range* InferRange(Zone* zone); 4711 virtual Range* InferRange(Zone* zone);
4523 4712
4524 private: 4713 private:
4525 HMod(HValue* context, 4714 HMod(HValue* context,
4526 HValue* left, 4715 HValue* left,
(...skipping 22 matching lines...) Expand all
4549 return value != 0 && (IsPowerOf2(value) || IsPowerOf2(-value)); 4738 return value != 0 && (IsPowerOf2(value) || IsPowerOf2(-value));
4550 } 4739 }
4551 4740
4552 return false; 4741 return false;
4553 } 4742 }
4554 4743
4555 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited); 4744 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
4556 4745
4557 virtual HValue* Canonicalize(); 4746 virtual HValue* Canonicalize();
4558 4747
4748 virtual void UpdateRepresentation(Representation new_rep,
4749 HInferRepresentationPhase* h_infer,
4750 const char* reason) {
4751 if (new_rep.IsSmi()) new_rep = Representation::Integer32();
4752 HArithmeticBinaryOperation::UpdateRepresentation(new_rep, h_infer, reason);
4753 }
4754
4559 DECLARE_CONCRETE_INSTRUCTION(Div) 4755 DECLARE_CONCRETE_INSTRUCTION(Div)
4560 4756
4561 protected: 4757 protected:
4562 virtual bool DataEquals(HValue* other) { return true; } 4758 virtual bool DataEquals(HValue* other) { return true; }
4563 4759
4564 virtual Range* InferRange(Zone* zone); 4760 virtual Range* InferRange(Zone* zone);
4565 4761
4566 private: 4762 private:
4567 HDiv(HValue* context, HValue* left, HValue* right) 4763 HDiv(HValue* context, HValue* left, HValue* right)
4568 : HArithmeticBinaryOperation(context, left, right) { 4764 : HArithmeticBinaryOperation(context, left, right) {
(...skipping 20 matching lines...) Expand all
4589 4785
4590 virtual Representation observed_input_representation(int index) { 4786 virtual Representation observed_input_representation(int index) {
4591 return RequiredInputRepresentation(index); 4787 return RequiredInputRepresentation(index);
4592 } 4788 }
4593 4789
4594 virtual void InferRepresentation(HInferRepresentationPhase* h_infer); 4790 virtual void InferRepresentation(HInferRepresentationPhase* h_infer);
4595 4791
4596 virtual Representation RepresentationFromInputs() { 4792 virtual Representation RepresentationFromInputs() {
4597 Representation left_rep = left()->representation(); 4793 Representation left_rep = left()->representation();
4598 Representation right_rep = right()->representation(); 4794 Representation right_rep = right()->representation();
4599 if ((left_rep.IsNone() || left_rep.IsInteger32()) && 4795 Representation result = Representation::Smi();
4600 (right_rep.IsNone() || right_rep.IsInteger32())) { 4796 result = result.generalize(left_rep);
4601 return Representation::Integer32(); 4797 result = result.generalize(right_rep);
4602 } 4798 if (result.IsTagged()) return Representation::Double();
4603 return Representation::Double(); 4799 return result;
4604 } 4800 }
4605 4801
4606 virtual bool IsCommutative() const { return true; } 4802 virtual bool IsCommutative() const { return true; }
4607 4803
4608 Operation operation() { return operation_; } 4804 Operation operation() { return operation_; }
4609 4805
4610 DECLARE_CONCRETE_INSTRUCTION(MathMinMax) 4806 DECLARE_CONCRETE_INSTRUCTION(MathMinMax)
4611 4807
4612 protected: 4808 protected:
4613 virtual bool DataEquals(HValue* other) { 4809 virtual bool DataEquals(HValue* other) {
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
4648 virtual bool DataEquals(HValue* other) { 4844 virtual bool DataEquals(HValue* other) {
4649 return op() == HBitwise::cast(other)->op(); 4845 return op() == HBitwise::cast(other)->op();
4650 } 4846 }
4651 4847
4652 virtual Range* InferRange(Zone* zone); 4848 virtual Range* InferRange(Zone* zone);
4653 4849
4654 private: 4850 private:
4655 HBitwise(Token::Value op, HValue* context, HValue* left, HValue* right) 4851 HBitwise(Token::Value op, HValue* context, HValue* left, HValue* right)
4656 : HBitwiseBinaryOperation(context, left, right), op_(op) { 4852 : HBitwiseBinaryOperation(context, left, right), op_(op) {
4657 ASSERT(op == Token::BIT_AND || op == Token::BIT_OR || op == Token::BIT_XOR); 4853 ASSERT(op == Token::BIT_AND || op == Token::BIT_OR || op == Token::BIT_XOR);
4854 // BIT_AND with a smi-range positive value will always unset the
4855 // entire sign-extension of the smi-sign.
4856 if (op == Token::BIT_AND &&
4857 ((left->IsConstant() &&
4858 left->representation().IsSmi() &&
4859 HConstant::cast(left)->Integer32Value() >= 0) ||
4860 (right->IsConstant() &&
4861 right->representation().IsSmi() &&
4862 HConstant::cast(right)->Integer32Value() >= 0))) {
4863 SetFlag(kTruncatingToSmi);
4864 // BIT_OR with a smi-range negative value will always set the entire
4865 // sign-extension of the smi-sign.
4866 } else if (op == Token::BIT_OR &&
4867 ((left->IsConstant() &&
4868 left->representation().IsSmi() &&
4869 HConstant::cast(left)->Integer32Value() < 0) ||
4870 (right->IsConstant() &&
4871 right->representation().IsSmi() &&
4872 HConstant::cast(right)->Integer32Value() < 0))) {
4873 SetFlag(kTruncatingToSmi);
4874 }
4658 } 4875 }
4659 4876
4660 Token::Value op_; 4877 Token::Value op_;
4661 }; 4878 };
4662 4879
4663 4880
4664 class HShl: public HBitwiseBinaryOperation { 4881 class HShl: public HBitwiseBinaryOperation {
4665 public: 4882 public:
4666 static HInstruction* New(Zone* zone, 4883 static HInstruction* New(Zone* zone,
4667 HValue* context, 4884 HValue* context,
4668 HValue* left, 4885 HValue* left,
4669 HValue* right); 4886 HValue* right);
4670 4887
4671 virtual Range* InferRange(Zone* zone); 4888 virtual Range* InferRange(Zone* zone);
4672 4889
4890 virtual void UpdateRepresentation(Representation new_rep,
4891 HInferRepresentationPhase* h_infer,
4892 const char* reason) {
4893 if (new_rep.IsSmi() &&
4894 !(right()->IsInteger32Constant() &&
4895 right()->GetInteger32Constant() >= 0)) {
4896 new_rep = Representation::Integer32();
4897 }
4898 HBitwiseBinaryOperation::UpdateRepresentation(new_rep, h_infer, reason);
4899 }
4900
4673 DECLARE_CONCRETE_INSTRUCTION(Shl) 4901 DECLARE_CONCRETE_INSTRUCTION(Shl)
4674 4902
4675 protected: 4903 protected:
4676 virtual bool DataEquals(HValue* other) { return true; } 4904 virtual bool DataEquals(HValue* other) { return true; }
4677 4905
4678 private: 4906 private:
4679 HShl(HValue* context, HValue* left, HValue* right) 4907 HShl(HValue* context, HValue* left, HValue* right)
4680 : HBitwiseBinaryOperation(context, left, right) { } 4908 : HBitwiseBinaryOperation(context, left, right) { }
4681 }; 4909 };
4682 4910
(...skipping 12 matching lines...) Expand all
4695 // like ((base + offset) >> scale) with one single decomposition. 4923 // like ((base + offset) >> scale) with one single decomposition.
4696 left()->TryDecompose(decomposition); 4924 left()->TryDecompose(decomposition);
4697 return true; 4925 return true;
4698 } 4926 }
4699 } 4927 }
4700 return false; 4928 return false;
4701 } 4929 }
4702 4930
4703 virtual Range* InferRange(Zone* zone); 4931 virtual Range* InferRange(Zone* zone);
4704 4932
4933 virtual void UpdateRepresentation(Representation new_rep,
4934 HInferRepresentationPhase* h_infer,
4935 const char* reason) {
4936 if (new_rep.IsSmi()) new_rep = Representation::Integer32();
4937 HBitwiseBinaryOperation::UpdateRepresentation(new_rep, h_infer, reason);
4938 }
4939
4705 DECLARE_CONCRETE_INSTRUCTION(Shr) 4940 DECLARE_CONCRETE_INSTRUCTION(Shr)
4706 4941
4707 protected: 4942 protected:
4708 virtual bool DataEquals(HValue* other) { return true; } 4943 virtual bool DataEquals(HValue* other) { return true; }
4709 4944
4710 private: 4945 private:
4711 HShr(HValue* context, HValue* left, HValue* right) 4946 HShr(HValue* context, HValue* left, HValue* right)
4712 : HBitwiseBinaryOperation(context, left, right) { } 4947 : HBitwiseBinaryOperation(context, left, right) { }
4713 }; 4948 };
4714 4949
(...skipping 12 matching lines...) Expand all
4727 // like ((base + offset) >> scale) with one single decomposition. 4962 // like ((base + offset) >> scale) with one single decomposition.
4728 left()->TryDecompose(decomposition); 4963 left()->TryDecompose(decomposition);
4729 return true; 4964 return true;
4730 } 4965 }
4731 } 4966 }
4732 return false; 4967 return false;
4733 } 4968 }
4734 4969
4735 virtual Range* InferRange(Zone* zone); 4970 virtual Range* InferRange(Zone* zone);
4736 4971
4972 virtual void UpdateRepresentation(Representation new_rep,
4973 HInferRepresentationPhase* h_infer,
4974 const char* reason) {
4975 if (new_rep.IsSmi()) new_rep = Representation::Integer32();
4976 HBitwiseBinaryOperation::UpdateRepresentation(new_rep, h_infer, reason);
4977 }
4978
4737 DECLARE_CONCRETE_INSTRUCTION(Sar) 4979 DECLARE_CONCRETE_INSTRUCTION(Sar)
4738 4980
4739 protected: 4981 protected:
4740 virtual bool DataEquals(HValue* other) { return true; } 4982 virtual bool DataEquals(HValue* other) { return true; }
4741 4983
4742 private: 4984 private:
4743 HSar(HValue* context, HValue* left, HValue* right) 4985 HSar(HValue* context, HValue* left, HValue* right)
4744 : HBitwiseBinaryOperation(context, left, right) { } 4986 : HBitwiseBinaryOperation(context, left, right) { }
4745 }; 4987 };
4746 4988
4747 4989
4748 class HRor: public HBitwiseBinaryOperation { 4990 class HRor: public HBitwiseBinaryOperation {
4749 public: 4991 public:
4750 HRor(HValue* context, HValue* left, HValue* right) 4992 HRor(HValue* context, HValue* left, HValue* right)
4751 : HBitwiseBinaryOperation(context, left, right) { 4993 : HBitwiseBinaryOperation(context, left, right) {
4752 ChangeRepresentation(Representation::Integer32()); 4994 ChangeRepresentation(Representation::Integer32());
4753 } 4995 }
4754 4996
4997 virtual void UpdateRepresentation(Representation new_rep,
4998 HInferRepresentationPhase* h_infer,
4999 const char* reason) {
5000 if (new_rep.IsSmi()) new_rep = Representation::Integer32();
5001 HBitwiseBinaryOperation::UpdateRepresentation(new_rep, h_infer, reason);
5002 }
5003
4755 DECLARE_CONCRETE_INSTRUCTION(Ror) 5004 DECLARE_CONCRETE_INSTRUCTION(Ror)
4756 5005
4757 protected: 5006 protected:
4758 virtual bool DataEquals(HValue* other) { return true; } 5007 virtual bool DataEquals(HValue* other) { return true; }
4759 }; 5008 };
4760 5009
4761 5010
4762 class HOsrEntry: public HTemplateInstruction<0> { 5011 class HOsrEntry: public HTemplateInstruction<0> {
4763 public: 5012 public:
4764 explicit HOsrEntry(BailoutId ast_id) : ast_id_(ast_id) { 5013 explicit HOsrEntry(BailoutId ast_id) : ast_id_(ast_id) {
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after
4962 public: 5211 public:
4963 enum Flags { 5212 enum Flags {
4964 CAN_ALLOCATE_IN_NEW_SPACE = 1 << 0, 5213 CAN_ALLOCATE_IN_NEW_SPACE = 1 << 0,
4965 CAN_ALLOCATE_IN_OLD_DATA_SPACE = 1 << 1, 5214 CAN_ALLOCATE_IN_OLD_DATA_SPACE = 1 << 1,
4966 CAN_ALLOCATE_IN_OLD_POINTER_SPACE = 1 << 2, 5215 CAN_ALLOCATE_IN_OLD_POINTER_SPACE = 1 << 2,
4967 ALLOCATE_DOUBLE_ALIGNED = 1 << 3, 5216 ALLOCATE_DOUBLE_ALIGNED = 1 << 3,
4968 PREFILL_WITH_FILLER = 1 << 4 5217 PREFILL_WITH_FILLER = 1 << 4
4969 }; 5218 };
4970 5219
4971 HAllocate(HValue* context, HValue* size, HType type, Flags flags) 5220 HAllocate(HValue* context, HValue* size, HType type, Flags flags)
4972 : type_(type), 5221 : flags_(flags) {
4973 flags_(flags) {
4974 SetOperandAt(0, context); 5222 SetOperandAt(0, context);
4975 SetOperandAt(1, size); 5223 SetOperandAt(1, size);
5224 set_type(type);
4976 set_representation(Representation::Tagged()); 5225 set_representation(Representation::Tagged());
4977 SetFlag(kTrackSideEffectDominators); 5226 SetFlag(kTrackSideEffectDominators);
4978 SetGVNFlag(kChangesNewSpacePromotion); 5227 SetGVNFlag(kChangesNewSpacePromotion);
4979 SetGVNFlag(kDependsOnNewSpacePromotion); 5228 SetGVNFlag(kDependsOnNewSpacePromotion);
4980 } 5229 }
4981 5230
4982 // Maximum instance size for which allocations will be inlined. 5231 // Maximum instance size for which allocations will be inlined.
4983 static const int kMaxInlineSize = 64 * kPointerSize; 5232 static const int kMaxInlineSize = 64 * kPointerSize;
4984 5233
4985 static Flags DefaultFlags() { 5234 static Flags DefaultFlags() {
4986 return CAN_ALLOCATE_IN_NEW_SPACE; 5235 return CAN_ALLOCATE_IN_NEW_SPACE;
4987 } 5236 }
4988 5237
4989 static Flags DefaultFlags(ElementsKind kind) { 5238 static Flags DefaultFlags(ElementsKind kind) {
4990 Flags flags = CAN_ALLOCATE_IN_NEW_SPACE; 5239 Flags flags = CAN_ALLOCATE_IN_NEW_SPACE;
4991 if (IsFastDoubleElementsKind(kind)) { 5240 if (IsFastDoubleElementsKind(kind)) {
4992 flags = static_cast<HAllocate::Flags>( 5241 flags = static_cast<HAllocate::Flags>(
4993 flags | HAllocate::ALLOCATE_DOUBLE_ALIGNED); 5242 flags | HAllocate::ALLOCATE_DOUBLE_ALIGNED);
4994 } 5243 }
4995 return flags; 5244 return flags;
4996 } 5245 }
4997 5246
4998 HValue* context() { return OperandAt(0); } 5247 HValue* context() { return OperandAt(0); }
4999 HValue* size() { return OperandAt(1); } 5248 HValue* size() { return OperandAt(1); }
5000 HType type() { return type_; }
5001 5249
5002 virtual Representation RequiredInputRepresentation(int index) { 5250 virtual Representation RequiredInputRepresentation(int index) {
5003 if (index == 0) { 5251 if (index == 0) {
5004 return Representation::Tagged(); 5252 return Representation::Tagged();
5005 } else { 5253 } else {
5006 return Representation::Integer32(); 5254 return Representation::Integer32();
5007 } 5255 }
5008 } 5256 }
5009 5257
5010 virtual Handle<Map> GetMonomorphicJSObjectMap() { 5258 virtual Handle<Map> GetMonomorphicJSObjectMap() {
5011 return known_initial_map_; 5259 return known_initial_map_;
5012 } 5260 }
5013 5261
5014 void set_known_initial_map(Handle<Map> known_initial_map) { 5262 void set_known_initial_map(Handle<Map> known_initial_map) {
5015 known_initial_map_ = known_initial_map; 5263 known_initial_map_ = known_initial_map;
5016 } 5264 }
5017 5265
5018 virtual HType CalculateInferredType();
5019
5020 bool CanAllocateInNewSpace() const { 5266 bool CanAllocateInNewSpace() const {
5021 return (flags_ & CAN_ALLOCATE_IN_NEW_SPACE) != 0; 5267 return (flags_ & CAN_ALLOCATE_IN_NEW_SPACE) != 0;
5022 } 5268 }
5023 5269
5024 bool CanAllocateInOldDataSpace() const { 5270 bool CanAllocateInOldDataSpace() const {
5025 return (flags_ & CAN_ALLOCATE_IN_OLD_DATA_SPACE) != 0; 5271 return (flags_ & CAN_ALLOCATE_IN_OLD_DATA_SPACE) != 0;
5026 } 5272 }
5027 5273
5028 bool CanAllocateInOldPointerSpace() const { 5274 bool CanAllocateInOldPointerSpace() const {
5029 return (flags_ & CAN_ALLOCATE_IN_OLD_POINTER_SPACE) != 0; 5275 return (flags_ & CAN_ALLOCATE_IN_OLD_POINTER_SPACE) != 0;
(...skipping 25 matching lines...) Expand all
5055 } 5301 }
5056 5302
5057 virtual void HandleSideEffectDominator(GVNFlag side_effect, 5303 virtual void HandleSideEffectDominator(GVNFlag side_effect,
5058 HValue* dominator); 5304 HValue* dominator);
5059 5305
5060 virtual void PrintDataTo(StringStream* stream); 5306 virtual void PrintDataTo(StringStream* stream);
5061 5307
5062 DECLARE_CONCRETE_INSTRUCTION(Allocate) 5308 DECLARE_CONCRETE_INSTRUCTION(Allocate)
5063 5309
5064 private: 5310 private:
5065 HType type_;
5066 Flags flags_; 5311 Flags flags_;
5067 Handle<Map> known_initial_map_; 5312 Handle<Map> known_initial_map_;
5068 }; 5313 };
5069 5314
5070 5315
5071 class HInnerAllocatedObject: public HTemplateInstruction<1> { 5316 class HInnerAllocatedObject: public HTemplateInstruction<1> {
5072 public: 5317 public:
5073 HInnerAllocatedObject(HValue* value, int offset, HType type = HType::Tagged()) 5318 HInnerAllocatedObject(HValue* value, int offset, HType type = HType::Tagged())
5074 : offset_(offset), 5319 : offset_(offset) {
5075 type_(type) {
5076 ASSERT(value->IsAllocate()); 5320 ASSERT(value->IsAllocate());
5077 SetOperandAt(0, value); 5321 SetOperandAt(0, value);
5322 set_type(type);
5078 set_representation(Representation::Tagged()); 5323 set_representation(Representation::Tagged());
5079 } 5324 }
5080 5325
5081 HValue* base_object() { return OperandAt(0); } 5326 HValue* base_object() { return OperandAt(0); }
5082 int offset() { return offset_; } 5327 int offset() { return offset_; }
5083 5328
5084 virtual Representation RequiredInputRepresentation(int index) { 5329 virtual Representation RequiredInputRepresentation(int index) {
5085 return Representation::Tagged(); 5330 return Representation::Tagged();
5086 } 5331 }
5087 5332
5088 virtual HType CalculateInferredType() { return type_; }
5089
5090 virtual void PrintDataTo(StringStream* stream); 5333 virtual void PrintDataTo(StringStream* stream);
5091 5334
5092 DECLARE_CONCRETE_INSTRUCTION(InnerAllocatedObject) 5335 DECLARE_CONCRETE_INSTRUCTION(InnerAllocatedObject)
5093 5336
5094 private: 5337 private:
5095 int offset_; 5338 int offset_;
5096 HType type_;
5097 }; 5339 };
5098 5340
5099 5341
5100 inline bool StoringValueNeedsWriteBarrier(HValue* value) { 5342 inline bool StoringValueNeedsWriteBarrier(HValue* value) {
5101 return !value->type().IsBoolean() 5343 return !value->type().IsBoolean()
5102 && !value->type().IsSmi() 5344 && !value->type().IsSmi()
5103 && !(value->IsConstant() && HConstant::cast(value)->ImmortalImmovable()); 5345 && !(value->IsConstant() && HConstant::cast(value)->ImmortalImmovable());
5104 } 5346 }
5105 5347
5106 5348
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after
5315 class HObjectAccess { 5557 class HObjectAccess {
5316 public: 5558 public:
5317 inline bool IsInobject() const { 5559 inline bool IsInobject() const {
5318 return portion() != kBackingStore; 5560 return portion() != kBackingStore;
5319 } 5561 }
5320 5562
5321 inline int offset() const { 5563 inline int offset() const {
5322 return OffsetField::decode(value_); 5564 return OffsetField::decode(value_);
5323 } 5565 }
5324 5566
5567 inline Representation representation() const {
5568 return Representation::FromKind(RepresentationField::decode(value_));
5569 }
5570
5325 inline Handle<String> name() const { 5571 inline Handle<String> name() const {
5326 return name_; 5572 return name_;
5327 } 5573 }
5328 5574
5575 inline HObjectAccess WithRepresentation(Representation representation) {
5576 return HObjectAccess(portion(), offset(), representation, name());
5577 }
5578
5329 static HObjectAccess ForHeapNumberValue() { 5579 static HObjectAccess ForHeapNumberValue() {
5330 return HObjectAccess(kDouble, HeapNumber::kValueOffset); 5580 return HObjectAccess(
5581 kDouble, HeapNumber::kValueOffset, Representation::Double());
5331 } 5582 }
5332 5583
5333 static HObjectAccess ForElementsPointer() { 5584 static HObjectAccess ForElementsPointer() {
5334 return HObjectAccess(kElementsPointer, JSObject::kElementsOffset); 5585 return HObjectAccess(kElementsPointer, JSObject::kElementsOffset);
5335 } 5586 }
5336 5587
5337 static HObjectAccess ForArrayLength() { 5588 static HObjectAccess ForArrayLength(ElementsKind elements_kind) {
5338 return HObjectAccess(kArrayLengths, JSArray::kLengthOffset); 5589 return HObjectAccess(
5590 kArrayLengths, JSArray::kLengthOffset,
5591 IsFastElementsKind(elements_kind) && FLAG_track_fields ?
5592 Representation::Smi() : Representation::Tagged());
5339 } 5593 }
5340 5594
5341 static HObjectAccess ForAllocationSiteTransitionInfo() { 5595 static HObjectAccess ForAllocationSiteTransitionInfo() {
5342 return HObjectAccess(kInobject, AllocationSite::kTransitionInfoOffset); 5596 return HObjectAccess(kInobject, AllocationSite::kTransitionInfoOffset);
5343 } 5597 }
5344 5598
5345 static HObjectAccess ForAllocationSiteWeakNext() { 5599 static HObjectAccess ForAllocationSiteWeakNext() {
5346 return HObjectAccess(kInobject, AllocationSite::kWeakNextOffset); 5600 return HObjectAccess(kInobject, AllocationSite::kWeakNextOffset);
5347 } 5601 }
5348 5602
5349 static HObjectAccess ForFixedArrayLength() { 5603 static HObjectAccess ForFixedArrayLength() {
5350 return HObjectAccess(kArrayLengths, FixedArray::kLengthOffset); 5604 return HObjectAccess(
5605 kArrayLengths, FixedArray::kLengthOffset,
5606 FLAG_track_fields ?
5607 Representation::Smi() : Representation::Tagged());
5351 } 5608 }
5352 5609
5353 static HObjectAccess ForPropertiesPointer() { 5610 static HObjectAccess ForPropertiesPointer() {
5354 return HObjectAccess(kInobject, JSObject::kPropertiesOffset); 5611 return HObjectAccess(kInobject, JSObject::kPropertiesOffset);
5355 } 5612 }
5356 5613
5357 static HObjectAccess ForPrototypeOrInitialMap() { 5614 static HObjectAccess ForPrototypeOrInitialMap() {
5358 return HObjectAccess(kInobject, JSFunction::kPrototypeOrInitialMapOffset); 5615 return HObjectAccess(kInobject, JSFunction::kPrototypeOrInitialMapOffset);
5359 } 5616 }
5360 5617
(...skipping 10 matching lines...) Expand all
5371 } 5628 }
5372 5629
5373 static HObjectAccess ForAllocationMementoSite() { 5630 static HObjectAccess ForAllocationMementoSite() {
5374 return HObjectAccess(kInobject, AllocationMemento::kAllocationSiteOffset); 5631 return HObjectAccess(kInobject, AllocationMemento::kAllocationSiteOffset);
5375 } 5632 }
5376 5633
5377 // Create an access to an offset in a fixed array header. 5634 // Create an access to an offset in a fixed array header.
5378 static HObjectAccess ForFixedArrayHeader(int offset); 5635 static HObjectAccess ForFixedArrayHeader(int offset);
5379 5636
5380 // Create an access to an in-object property in a JSObject. 5637 // Create an access to an in-object property in a JSObject.
5381 static HObjectAccess ForJSObjectOffset(int offset); 5638 static HObjectAccess ForJSObjectOffset(int offset,
5639 Representation representation = Representation::Tagged());
5382 5640
5383 // Create an access to an in-object property in a JSArray. 5641 // Create an access to an in-object property in a JSArray.
5384 static HObjectAccess ForJSArrayOffset(int offset); 5642 static HObjectAccess ForJSArrayOffset(int offset);
5385 5643
5386 // Create an access to the backing store of an object. 5644 // Create an access to the backing store of an object.
5387 static HObjectAccess ForBackingStoreOffset(int offset); 5645 static HObjectAccess ForBackingStoreOffset(int offset,
5646 Representation representation = Representation::Tagged());
5388 5647
5389 // Create an access to a resolved field (in-object or backing store). 5648 // Create an access to a resolved field (in-object or backing store).
5390 static HObjectAccess ForField(Handle<Map> map, 5649 static HObjectAccess ForField(Handle<Map> map,
5391 LookupResult *lookup, Handle<String> name = Handle<String>::null()); 5650 LookupResult *lookup, Handle<String> name = Handle<String>::null());
5392 5651
5393 // Create an access for the payload of a Cell or JSGlobalPropertyCell. 5652 // Create an access for the payload of a Cell or JSGlobalPropertyCell.
5394 static HObjectAccess ForCellPayload(Isolate* isolate); 5653 static HObjectAccess ForCellPayload(Isolate* isolate);
5395 5654
5396 void PrintTo(StringStream* stream); 5655 void PrintTo(StringStream* stream);
5397 5656
5398 inline bool Equals(HObjectAccess that) const { 5657 inline bool Equals(HObjectAccess that) const {
5399 return value_ == that.value_; // portion and offset must match 5658 return value_ == that.value_; // portion and offset must match
5400 } 5659 }
5401 5660
5402 protected: 5661 protected:
5403 void SetGVNFlags(HValue *instr, bool is_store); 5662 void SetGVNFlags(HValue *instr, bool is_store);
5404 5663
5405 private: 5664 private:
5406 // internal use only; different parts of an object or array 5665 // internal use only; different parts of an object or array
5407 enum Portion { 5666 enum Portion {
5408 kMaps, // map of an object 5667 kMaps, // map of an object
5409 kArrayLengths, // the length of an array 5668 kArrayLengths, // the length of an array
5410 kElementsPointer, // elements pointer 5669 kElementsPointer, // elements pointer
5411 kBackingStore, // some field in the backing store 5670 kBackingStore, // some field in the backing store
5412 kDouble, // some double field 5671 kDouble, // some double field
5413 kInobject // some other in-object field 5672 kInobject // some other in-object field
5414 }; 5673 };
5415 5674
5416 HObjectAccess(Portion portion, int offset, 5675 HObjectAccess(Portion portion, int offset,
5417 Handle<String> name = Handle<String>::null()) 5676 Representation representation = Representation::Tagged(),
5418 : value_(PortionField::encode(portion) | OffsetField::encode(offset)), 5677 Handle<String> name = Handle<String>::null())
5678 : value_(PortionField::encode(portion) |
5679 RepresentationField::encode(representation.kind()) |
5680 OffsetField::encode(offset)),
5419 name_(name) { 5681 name_(name) {
5420 ASSERT(this->offset() == offset); // offset should decode correctly 5682 // assert that the fields decode correctly
5421 ASSERT(this->portion() == portion); // portion should decode correctly 5683 ASSERT(this->offset() == offset);
5684 ASSERT(this->portion() == portion);
5685 ASSERT(RepresentationField::decode(value_) == representation.kind());
5422 } 5686 }
5423 5687
5424 class PortionField : public BitField<Portion, 0, 3> {}; 5688 class PortionField : public BitField<Portion, 0, 3> {};
5425 class OffsetField : public BitField<int, 3, 29> {}; 5689 class RepresentationField : public BitField<Representation::Kind, 3, 3> {};
5690 class OffsetField : public BitField<int, 6, 26> {};
5426 5691
5427 uint32_t value_; // encodes both portion and offset 5692 uint32_t value_; // encodes portion, representation, and offset
5428 Handle<String> name_; 5693 Handle<String> name_;
5429 5694
5430 friend class HLoadNamedField; 5695 friend class HLoadNamedField;
5431 friend class HStoreNamedField; 5696 friend class HStoreNamedField;
5432 5697
5433 inline Portion portion() const { 5698 inline Portion portion() const {
5434 return PortionField::decode(value_); 5699 return PortionField::decode(value_);
5435 } 5700 }
5436 }; 5701 };
5437 5702
(...skipping 27 matching lines...) Expand all
5465 private: 5730 private:
5466 HObjectAccess store_field_; 5731 HObjectAccess store_field_;
5467 KnownList known_list_; 5732 KnownList known_list_;
5468 }; 5733 };
5469 5734
5470 5735
5471 class HLoadNamedField: public HTemplateInstruction<2> { 5736 class HLoadNamedField: public HTemplateInstruction<2> {
5472 public: 5737 public:
5473 HLoadNamedField(HValue* object, 5738 HLoadNamedField(HValue* object,
5474 HObjectAccess access, 5739 HObjectAccess access,
5475 HValue* typecheck = NULL, 5740 HValue* typecheck = NULL)
5476 Representation field_representation 5741 : access_(access) {
5477 = Representation::Tagged())
5478 : access_(access),
5479 field_representation_(field_representation) {
5480 ASSERT(object != NULL); 5742 ASSERT(object != NULL);
5481 SetOperandAt(0, object); 5743 SetOperandAt(0, object);
5482 SetOperandAt(1, typecheck != NULL ? typecheck : object); 5744 SetOperandAt(1, typecheck != NULL ? typecheck : object);
5483 5745
5484 if (FLAG_track_fields && field_representation.IsSmi()) { 5746 Representation representation = access.representation();
5747 if (representation.IsSmi()) {
5485 set_type(HType::Smi()); 5748 set_type(HType::Smi());
5486 set_representation(field_representation); 5749 set_representation(representation);
5487 } else if (FLAG_track_double_fields && field_representation.IsDouble()) { 5750 } else if (representation.IsDouble()) {
5488 set_representation(field_representation); 5751 set_representation(representation);
5489 } else if (FLAG_track_heap_object_fields && 5752 } else if (FLAG_track_heap_object_fields &&
5490 field_representation.IsHeapObject()) { 5753 representation.IsHeapObject()) {
5491 set_type(HType::NonPrimitive()); 5754 set_type(HType::NonPrimitive());
5492 set_representation(Representation::Tagged()); 5755 set_representation(Representation::Tagged());
5493 } else { 5756 } else {
5494 set_representation(Representation::Tagged()); 5757 set_representation(Representation::Tagged());
5495 } 5758 }
5496 access.SetGVNFlags(this, false); 5759 access.SetGVNFlags(this, false);
5497 } 5760 }
5498 5761
5499 HValue* object() { return OperandAt(0); } 5762 HValue* object() { return OperandAt(0); }
5500 HValue* typecheck() { 5763 HValue* typecheck() {
5501 ASSERT(HasTypeCheck()); 5764 ASSERT(HasTypeCheck());
5502 return OperandAt(1); 5765 return OperandAt(1);
5503 } 5766 }
5504 5767
5505 bool HasTypeCheck() const { return OperandAt(0) != OperandAt(1); } 5768 bool HasTypeCheck() const { return OperandAt(0) != OperandAt(1); }
5506 HObjectAccess access() const { return access_; } 5769 HObjectAccess access() const { return access_; }
5507 Representation field_representation() const { return representation_; } 5770 Representation field_representation() const {
5771 return access_.representation();
5772 }
5508 5773
5509 virtual bool HasEscapingOperandAt(int index) { return false; } 5774 virtual bool HasEscapingOperandAt(int index) { return false; }
5510 virtual Representation RequiredInputRepresentation(int index) { 5775 virtual Representation RequiredInputRepresentation(int index) {
5511 return Representation::Tagged(); 5776 return Representation::Tagged();
5512 } 5777 }
5513 virtual void PrintDataTo(StringStream* stream); 5778 virtual void PrintDataTo(StringStream* stream);
5514 5779
5515 DECLARE_CONCRETE_INSTRUCTION(LoadNamedField) 5780 DECLARE_CONCRETE_INSTRUCTION(LoadNamedField)
5516 5781
5517 protected: 5782 protected:
5518 virtual bool DataEquals(HValue* other) { 5783 virtual bool DataEquals(HValue* other) {
5519 HLoadNamedField* b = HLoadNamedField::cast(other); 5784 HLoadNamedField* b = HLoadNamedField::cast(other);
5520 return access_.Equals(b->access_); 5785 return access_.Equals(b->access_);
5521 } 5786 }
5522 5787
5523 private: 5788 private:
5524 virtual bool IsDeletable() const { return true; } 5789 virtual bool IsDeletable() const { return true; }
5525 5790
5526 HObjectAccess access_; 5791 HObjectAccess access_;
5527 Representation field_representation_;
5528 }; 5792 };
5529 5793
5530 5794
5531 class HLoadNamedFieldPolymorphic: public HTemplateInstruction<2> { 5795 class HLoadNamedFieldPolymorphic: public HTemplateInstruction<2> {
5532 public: 5796 public:
5533 HLoadNamedFieldPolymorphic(HValue* context, 5797 HLoadNamedFieldPolymorphic(HValue* context,
5534 HValue* object, 5798 HValue* object,
5535 SmallMapList* types, 5799 SmallMapList* types,
5536 Handle<String> name, 5800 Handle<String> name,
5537 Zone* zone); 5801 Zone* zone);
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
5618 class ArrayInstructionInterface { 5882 class ArrayInstructionInterface {
5619 public: 5883 public:
5620 virtual HValue* GetKey() = 0; 5884 virtual HValue* GetKey() = 0;
5621 virtual void SetKey(HValue* key) = 0; 5885 virtual void SetKey(HValue* key) = 0;
5622 virtual void SetIndexOffset(uint32_t index_offset) = 0; 5886 virtual void SetIndexOffset(uint32_t index_offset) = 0;
5623 virtual bool IsDehoisted() = 0; 5887 virtual bool IsDehoisted() = 0;
5624 virtual void SetDehoisted(bool is_dehoisted) = 0; 5888 virtual void SetDehoisted(bool is_dehoisted) = 0;
5625 virtual ~ArrayInstructionInterface() { }; 5889 virtual ~ArrayInstructionInterface() { };
5626 5890
5627 static Representation KeyedAccessIndexRequirement(Representation r) { 5891 static Representation KeyedAccessIndexRequirement(Representation r) {
5628 return r.IsInteger32() ? Representation::Integer32() 5892 return r.IsInteger32() || kSmiValueSize != 31
5629 : Representation::Smi(); 5893 ? Representation::Integer32() : Representation::Smi();
5630 } 5894 }
5631 }; 5895 };
5632 5896
5633 5897
5634 enum LoadKeyedHoleMode { 5898 enum LoadKeyedHoleMode {
5635 NEVER_RETURN_HOLE, 5899 NEVER_RETURN_HOLE,
5636 ALLOW_RETURN_HOLE 5900 ALLOW_RETURN_HOLE
5637 }; 5901 };
5638 5902
5639 5903
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after
5817 virtual HValue* Canonicalize(); 6081 virtual HValue* Canonicalize();
5818 6082
5819 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedGeneric) 6083 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedGeneric)
5820 }; 6084 };
5821 6085
5822 6086
5823 class HStoreNamedField: public HTemplateInstruction<2> { 6087 class HStoreNamedField: public HTemplateInstruction<2> {
5824 public: 6088 public:
5825 HStoreNamedField(HValue* obj, 6089 HStoreNamedField(HValue* obj,
5826 HObjectAccess access, 6090 HObjectAccess access,
5827 HValue* val, 6091 HValue* val)
5828 Representation field_representation
5829 = Representation::Tagged())
5830 : access_(access), 6092 : access_(access),
5831 field_representation_(field_representation),
5832 transition_(), 6093 transition_(),
5833 transition_unique_id_(), 6094 transition_unique_id_(),
5834 new_space_dominator_(NULL), 6095 new_space_dominator_(NULL),
5835 write_barrier_mode_(UPDATE_WRITE_BARRIER) { 6096 write_barrier_mode_(UPDATE_WRITE_BARRIER) {
5836 SetOperandAt(0, obj); 6097 SetOperandAt(0, obj);
5837 SetOperandAt(1, val); 6098 SetOperandAt(1, val);
5838 access.SetGVNFlags(this, true); 6099 access.SetGVNFlags(this, true);
5839 } 6100 }
5840 6101
5841 DECLARE_CONCRETE_INSTRUCTION(StoreNamedField) 6102 DECLARE_CONCRETE_INSTRUCTION(StoreNamedField)
5842 6103
5843 virtual bool HasEscapingOperandAt(int index) { return index == 1; } 6104 virtual bool HasEscapingOperandAt(int index) { return index == 1; }
5844 virtual Representation RequiredInputRepresentation(int index) { 6105 virtual Representation RequiredInputRepresentation(int index) {
5845 if (FLAG_track_double_fields && 6106 if (index == 1 && field_representation().IsDouble()) {
5846 index == 1 && field_representation_.IsDouble()) { 6107 return field_representation();
5847 return field_representation_; 6108 } else if (index == 1 && field_representation().IsSmi()) {
5848 } else if (FLAG_track_fields && 6109 return field_representation();
5849 index == 1 && field_representation_.IsSmi()) {
5850 return field_representation_;
5851 } 6110 }
5852 return Representation::Tagged(); 6111 return Representation::Tagged();
5853 } 6112 }
5854 virtual void HandleSideEffectDominator(GVNFlag side_effect, 6113 virtual void HandleSideEffectDominator(GVNFlag side_effect,
5855 HValue* dominator) { 6114 HValue* dominator) {
5856 ASSERT(side_effect == kChangesNewSpacePromotion); 6115 ASSERT(side_effect == kChangesNewSpacePromotion);
5857 new_space_dominator_ = dominator; 6116 new_space_dominator_ = dominator;
5858 } 6117 }
5859 virtual void PrintDataTo(StringStream* stream); 6118 virtual void PrintDataTo(StringStream* stream);
5860 6119
(...skipping 11 matching lines...) Expand all
5872 void SetTransition(Handle<Map> map, CompilationInfo* info) { 6131 void SetTransition(Handle<Map> map, CompilationInfo* info) {
5873 ASSERT(transition_.is_null()); // Only set once. 6132 ASSERT(transition_.is_null()); // Only set once.
5874 if (map->CanBeDeprecated()) { 6133 if (map->CanBeDeprecated()) {
5875 map->AddDependentCompilationInfo(DependentCode::kTransitionGroup, info); 6134 map->AddDependentCompilationInfo(DependentCode::kTransitionGroup, info);
5876 } 6135 }
5877 transition_ = map; 6136 transition_ = map;
5878 } 6137 }
5879 HValue* new_space_dominator() const { return new_space_dominator_; } 6138 HValue* new_space_dominator() const { return new_space_dominator_; }
5880 6139
5881 bool NeedsWriteBarrier() { 6140 bool NeedsWriteBarrier() {
5882 ASSERT(!(FLAG_track_double_fields && field_representation_.IsDouble()) || 6141 ASSERT(!(FLAG_track_double_fields && field_representation().IsDouble()) ||
5883 transition_.is_null()); 6142 transition_.is_null());
5884 if (IsSkipWriteBarrier()) return false; 6143 if (IsSkipWriteBarrier()) return false;
5885 return (!FLAG_track_fields || !field_representation_.IsSmi()) && 6144 if (field_representation().IsDouble()) return false;
5886 // If there is a transition, a new storage object needs to be allocated. 6145 if (field_representation().IsSmi()) return false;
5887 !(FLAG_track_double_fields && field_representation_.IsDouble()) && 6146 return StoringValueNeedsWriteBarrier(value()) &&
5888 StoringValueNeedsWriteBarrier(value()) &&
5889 ReceiverObjectNeedsWriteBarrier(object(), new_space_dominator()); 6147 ReceiverObjectNeedsWriteBarrier(object(), new_space_dominator());
5890 } 6148 }
5891 6149
5892 bool NeedsWriteBarrierForMap() { 6150 bool NeedsWriteBarrierForMap() {
5893 if (IsSkipWriteBarrier()) return false; 6151 if (IsSkipWriteBarrier()) return false;
5894 return ReceiverObjectNeedsWriteBarrier(object(), new_space_dominator()); 6152 return ReceiverObjectNeedsWriteBarrier(object(), new_space_dominator());
5895 } 6153 }
5896 6154
5897 virtual void FinalizeUniqueValueId() { 6155 virtual void FinalizeUniqueValueId() {
5898 transition_unique_id_ = UniqueValueId(transition_); 6156 transition_unique_id_ = UniqueValueId(transition_);
5899 } 6157 }
5900 6158
5901 Representation field_representation() const { 6159 Representation field_representation() const {
5902 return field_representation_; 6160 return access_.representation();
5903 } 6161 }
5904 6162
5905 private: 6163 private:
5906 HObjectAccess access_; 6164 HObjectAccess access_;
5907 Representation field_representation_;
5908 Handle<Map> transition_; 6165 Handle<Map> transition_;
5909 UniqueValueId transition_unique_id_; 6166 UniqueValueId transition_unique_id_;
5910 HValue* new_space_dominator_; 6167 HValue* new_space_dominator_;
5911 WriteBarrierMode write_barrier_mode_; 6168 WriteBarrierMode write_barrier_mode_;
5912 }; 6169 };
5913 6170
5914 6171
5915 class HStoreNamedGeneric: public HTemplateInstruction<3> { 6172 class HStoreNamedGeneric: public HTemplateInstruction<3> {
5916 public: 6173 public:
5917 HStoreNamedGeneric(HValue* context, 6174 HStoreNamedGeneric(HValue* context,
(...skipping 776 matching lines...) Expand 10 before | Expand all | Expand 10 after
6694 virtual bool IsDeletable() const { return true; } 6951 virtual bool IsDeletable() const { return true; }
6695 }; 6952 };
6696 6953
6697 6954
6698 #undef DECLARE_INSTRUCTION 6955 #undef DECLARE_INSTRUCTION
6699 #undef DECLARE_CONCRETE_INSTRUCTION 6956 #undef DECLARE_CONCRETE_INSTRUCTION
6700 6957
6701 } } // namespace v8::internal 6958 } } // namespace v8::internal
6702 6959
6703 #endif // V8_HYDROGEN_INSTRUCTIONS_H_ 6960 #endif // V8_HYDROGEN_INSTRUCTIONS_H_
OLDNEW
« no previous file with comments | « src/hydrogen-gvn.cc ('k') | src/hydrogen-instructions.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698