OLD | NEW |
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 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
128 V(InstanceOfKnownGlobal) \ | 128 V(InstanceOfKnownGlobal) \ |
129 V(InstanceSize) \ | 129 V(InstanceSize) \ |
130 V(InvokeFunction) \ | 130 V(InvokeFunction) \ |
131 V(IsConstructCallAndBranch) \ | 131 V(IsConstructCallAndBranch) \ |
132 V(IsObjectAndBranch) \ | 132 V(IsObjectAndBranch) \ |
133 V(IsNumberAndBranch) \ | 133 V(IsNumberAndBranch) \ |
134 V(IsStringAndBranch) \ | 134 V(IsStringAndBranch) \ |
135 V(IsSmiAndBranch) \ | 135 V(IsSmiAndBranch) \ |
136 V(IsUndetectableAndBranch) \ | 136 V(IsUndetectableAndBranch) \ |
137 V(LeaveInlined) \ | 137 V(LeaveInlined) \ |
138 V(LinkObjectInList) \ | |
139 V(LoadContextSlot) \ | 138 V(LoadContextSlot) \ |
140 V(LoadExternalArrayPointer) \ | 139 V(LoadExternalArrayPointer) \ |
141 V(LoadFieldByIndex) \ | 140 V(LoadFieldByIndex) \ |
142 V(LoadFunctionPrototype) \ | 141 V(LoadFunctionPrototype) \ |
143 V(LoadGlobalCell) \ | 142 V(LoadGlobalCell) \ |
144 V(LoadGlobalGeneric) \ | 143 V(LoadGlobalGeneric) \ |
145 V(LoadKeyed) \ | 144 V(LoadKeyed) \ |
146 V(LoadKeyedGeneric) \ | 145 V(LoadKeyedGeneric) \ |
147 V(LoadNamedField) \ | 146 V(LoadNamedField) \ |
148 V(LoadNamedFieldPolymorphic) \ | 147 V(LoadNamedFieldPolymorphic) \ |
(...skipping 23 matching lines...) Expand all Loading... |
172 V(StoreGlobalCell) \ | 171 V(StoreGlobalCell) \ |
173 V(StoreGlobalGeneric) \ | 172 V(StoreGlobalGeneric) \ |
174 V(StoreKeyed) \ | 173 V(StoreKeyed) \ |
175 V(StoreKeyedGeneric) \ | 174 V(StoreKeyedGeneric) \ |
176 V(StoreNamedField) \ | 175 V(StoreNamedField) \ |
177 V(StoreNamedGeneric) \ | 176 V(StoreNamedGeneric) \ |
178 V(StringAdd) \ | 177 V(StringAdd) \ |
179 V(StringCharCodeAt) \ | 178 V(StringCharCodeAt) \ |
180 V(StringCharFromCode) \ | 179 V(StringCharFromCode) \ |
181 V(StringCompareAndBranch) \ | 180 V(StringCompareAndBranch) \ |
182 V(StringLength) \ | |
183 V(Sub) \ | 181 V(Sub) \ |
184 V(ThisFunction) \ | 182 V(ThisFunction) \ |
185 V(Throw) \ | 183 V(Throw) \ |
186 V(ToFastProperties) \ | 184 V(ToFastProperties) \ |
187 V(TransitionElementsKind) \ | 185 V(TransitionElementsKind) \ |
188 V(TrapAllocationMemento) \ | 186 V(TrapAllocationMemento) \ |
189 V(Typeof) \ | 187 V(Typeof) \ |
190 V(TypeofIsAndBranch) \ | 188 V(TypeofIsAndBranch) \ |
191 V(UnaryMathOperation) \ | 189 V(UnaryMathOperation) \ |
192 V(UnknownOSRValue) \ | 190 V(UnknownOSRValue) \ |
193 V(UseConst) \ | 191 V(UseConst) \ |
194 V(ValueOf) \ | 192 V(ValueOf) \ |
195 V(WrapReceiver) | 193 V(WrapReceiver) |
196 | 194 |
197 #define GVN_TRACKED_FLAG_LIST(V) \ | 195 #define GVN_TRACKED_FLAG_LIST(V) \ |
198 V(Maps) \ | 196 V(Maps) \ |
199 V(NewSpacePromotion) | 197 V(NewSpacePromotion) |
200 | 198 |
201 #define GVN_UNTRACKED_FLAG_LIST(V) \ | 199 #define GVN_UNTRACKED_FLAG_LIST(V) \ |
202 V(ArrayElements) \ | 200 V(ArrayElements) \ |
203 V(ArrayLengths) \ | 201 V(ArrayLengths) \ |
| 202 V(StringLengths) \ |
204 V(BackingStoreFields) \ | 203 V(BackingStoreFields) \ |
205 V(Calls) \ | 204 V(Calls) \ |
206 V(ContextSlots) \ | 205 V(ContextSlots) \ |
207 V(DoubleArrayElements) \ | 206 V(DoubleArrayElements) \ |
208 V(DoubleFields) \ | 207 V(DoubleFields) \ |
209 V(ElementsKind) \ | 208 V(ElementsKind) \ |
210 V(ElementsPointer) \ | 209 V(ElementsPointer) \ |
211 V(GlobalVars) \ | 210 V(GlobalVars) \ |
212 V(InobjectFields) \ | 211 V(InobjectFields) \ |
213 V(OsrEntries) \ | 212 V(OsrEntries) \ |
214 V(SpecializedArrayElements) | 213 V(ExternalMemory) |
215 | 214 |
216 | 215 |
217 #define DECLARE_ABSTRACT_INSTRUCTION(type) \ | 216 #define DECLARE_ABSTRACT_INSTRUCTION(type) \ |
218 virtual bool Is##type() const { return true; } \ | 217 virtual bool Is##type() const { return true; } \ |
219 static H##type* cast(HValue* value) { \ | 218 static H##type* cast(HValue* value) { \ |
220 ASSERT(value->Is##type()); \ | 219 ASSERT(value->Is##type()); \ |
221 return reinterpret_cast<H##type*>(value); \ | 220 return reinterpret_cast<H##type*>(value); \ |
222 } | 221 } |
223 | 222 |
224 | 223 |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
343 return reinterpret_cast<intptr_t>(raw_address_); | 342 return reinterpret_cast<intptr_t>(raw_address_); |
344 } | 343 } |
345 | 344 |
346 private: | 345 private: |
347 Address raw_address_; | 346 Address raw_address_; |
348 }; | 347 }; |
349 | 348 |
350 | 349 |
351 class HType { | 350 class HType { |
352 public: | 351 public: |
353 HType() : type_(kUninitialized) { } | 352 static HType None() { return HType(kNone); } |
354 | |
355 static HType Tagged() { return HType(kTagged); } | 353 static HType Tagged() { return HType(kTagged); } |
356 static HType TaggedPrimitive() { return HType(kTaggedPrimitive); } | 354 static HType TaggedPrimitive() { return HType(kTaggedPrimitive); } |
357 static HType TaggedNumber() { return HType(kTaggedNumber); } | 355 static HType TaggedNumber() { return HType(kTaggedNumber); } |
358 static HType Smi() { return HType(kSmi); } | 356 static HType Smi() { return HType(kSmi); } |
359 static HType HeapNumber() { return HType(kHeapNumber); } | 357 static HType HeapNumber() { return HType(kHeapNumber); } |
360 static HType String() { return HType(kString); } | 358 static HType String() { return HType(kString); } |
361 static HType Boolean() { return HType(kBoolean); } | 359 static HType Boolean() { return HType(kBoolean); } |
362 static HType NonPrimitive() { return HType(kNonPrimitive); } | 360 static HType NonPrimitive() { return HType(kNonPrimitive); } |
363 static HType JSArray() { return HType(kJSArray); } | 361 static HType JSArray() { return HType(kJSArray); } |
364 static HType JSObject() { return HType(kJSObject); } | 362 static HType JSObject() { return HType(kJSObject); } |
365 static HType Uninitialized() { return HType(kUninitialized); } | |
366 | 363 |
367 // Return the weakest (least precise) common type. | 364 // Return the weakest (least precise) common type. |
368 HType Combine(HType other) { | 365 HType Combine(HType other) { |
369 return HType(static_cast<Type>(type_ & other.type_)); | 366 return HType(static_cast<Type>(type_ & other.type_)); |
370 } | 367 } |
371 | 368 |
372 bool Equals(const HType& other) const { | 369 bool Equals(const HType& other) const { |
373 return type_ == other.type_; | 370 return type_ == other.type_; |
374 } | 371 } |
375 | 372 |
376 bool IsSubtypeOf(const HType& other) { | 373 bool IsSubtypeOf(const HType& other) { |
377 return Combine(other).Equals(other); | 374 return Combine(other).Equals(other); |
378 } | 375 } |
379 | 376 |
380 bool IsTagged() const { | 377 bool IsTagged() const { |
381 ASSERT(type_ != kUninitialized); | |
382 return ((type_ & kTagged) == kTagged); | 378 return ((type_ & kTagged) == kTagged); |
383 } | 379 } |
384 | 380 |
385 bool IsTaggedPrimitive() const { | 381 bool IsTaggedPrimitive() const { |
386 ASSERT(type_ != kUninitialized); | |
387 return ((type_ & kTaggedPrimitive) == kTaggedPrimitive); | 382 return ((type_ & kTaggedPrimitive) == kTaggedPrimitive); |
388 } | 383 } |
389 | 384 |
390 bool IsTaggedNumber() const { | 385 bool IsTaggedNumber() const { |
391 ASSERT(type_ != kUninitialized); | |
392 return ((type_ & kTaggedNumber) == kTaggedNumber); | 386 return ((type_ & kTaggedNumber) == kTaggedNumber); |
393 } | 387 } |
394 | 388 |
395 bool IsSmi() const { | 389 bool IsSmi() const { |
396 ASSERT(type_ != kUninitialized); | |
397 return ((type_ & kSmi) == kSmi); | 390 return ((type_ & kSmi) == kSmi); |
398 } | 391 } |
399 | 392 |
400 bool IsHeapNumber() const { | 393 bool IsHeapNumber() const { |
401 ASSERT(type_ != kUninitialized); | |
402 return ((type_ & kHeapNumber) == kHeapNumber); | 394 return ((type_ & kHeapNumber) == kHeapNumber); |
403 } | 395 } |
404 | 396 |
405 bool IsString() const { | 397 bool IsString() const { |
406 ASSERT(type_ != kUninitialized); | |
407 return ((type_ & kString) == kString); | 398 return ((type_ & kString) == kString); |
408 } | 399 } |
409 | 400 |
410 bool IsNonString() const { | 401 bool IsNonString() const { |
411 return IsTaggedPrimitive() || IsSmi() || IsHeapNumber() || | 402 return IsTaggedPrimitive() || IsSmi() || IsHeapNumber() || |
412 IsBoolean() || IsJSArray(); | 403 IsBoolean() || IsJSArray(); |
413 } | 404 } |
414 | 405 |
415 bool IsBoolean() const { | 406 bool IsBoolean() const { |
416 ASSERT(type_ != kUninitialized); | |
417 return ((type_ & kBoolean) == kBoolean); | 407 return ((type_ & kBoolean) == kBoolean); |
418 } | 408 } |
419 | 409 |
420 bool IsNonPrimitive() const { | 410 bool IsNonPrimitive() const { |
421 ASSERT(type_ != kUninitialized); | |
422 return ((type_ & kNonPrimitive) == kNonPrimitive); | 411 return ((type_ & kNonPrimitive) == kNonPrimitive); |
423 } | 412 } |
424 | 413 |
425 bool IsJSArray() const { | 414 bool IsJSArray() const { |
426 ASSERT(type_ != kUninitialized); | |
427 return ((type_ & kJSArray) == kJSArray); | 415 return ((type_ & kJSArray) == kJSArray); |
428 } | 416 } |
429 | 417 |
430 bool IsJSObject() const { | 418 bool IsJSObject() const { |
431 ASSERT(type_ != kUninitialized); | |
432 return ((type_ & kJSObject) == kJSObject); | 419 return ((type_ & kJSObject) == kJSObject); |
433 } | 420 } |
434 | 421 |
435 bool IsUninitialized() const { | 422 bool IsHeapObject() const { |
436 return type_ == kUninitialized; | 423 return IsHeapNumber() || IsString() || IsBoolean() || IsNonPrimitive(); |
437 } | 424 } |
438 | 425 |
439 bool IsHeapObject() const { | 426 bool ToStringOrToNumberCanBeObserved(Representation representation) { |
440 ASSERT(type_ != kUninitialized); | 427 switch (type_) { |
441 return IsHeapNumber() || IsString() || IsBoolean() || IsNonPrimitive(); | 428 case kTaggedPrimitive: // fallthru |
| 429 case kTaggedNumber: // fallthru |
| 430 case kSmi: // fallthru |
| 431 case kHeapNumber: // fallthru |
| 432 case kString: // fallthru |
| 433 case kBoolean: |
| 434 return false; |
| 435 case kJSArray: // fallthru |
| 436 case kJSObject: |
| 437 return true; |
| 438 case kTagged: |
| 439 break; |
| 440 } |
| 441 return !representation.IsSmiOrInteger32() && !representation.IsDouble(); |
442 } | 442 } |
443 | 443 |
444 static HType TypeFromValue(Handle<Object> value); | 444 static HType TypeFromValue(Handle<Object> value); |
445 | 445 |
446 const char* ToString(); | 446 const char* ToString(); |
447 | 447 |
448 private: | 448 private: |
449 enum Type { | 449 enum Type { |
| 450 kNone = 0x0, // 0000 0000 0000 0000 |
450 kTagged = 0x1, // 0000 0000 0000 0001 | 451 kTagged = 0x1, // 0000 0000 0000 0001 |
451 kTaggedPrimitive = 0x5, // 0000 0000 0000 0101 | 452 kTaggedPrimitive = 0x5, // 0000 0000 0000 0101 |
452 kTaggedNumber = 0xd, // 0000 0000 0000 1101 | 453 kTaggedNumber = 0xd, // 0000 0000 0000 1101 |
453 kSmi = 0x1d, // 0000 0000 0001 1101 | 454 kSmi = 0x1d, // 0000 0000 0001 1101 |
454 kHeapNumber = 0x2d, // 0000 0000 0010 1101 | 455 kHeapNumber = 0x2d, // 0000 0000 0010 1101 |
455 kString = 0x45, // 0000 0000 0100 0101 | 456 kString = 0x45, // 0000 0000 0100 0101 |
456 kBoolean = 0x85, // 0000 0000 1000 0101 | 457 kBoolean = 0x85, // 0000 0000 1000 0101 |
457 kNonPrimitive = 0x101, // 0000 0001 0000 0001 | 458 kNonPrimitive = 0x101, // 0000 0001 0000 0001 |
458 kJSObject = 0x301, // 0000 0011 0000 0001 | 459 kJSObject = 0x301, // 0000 0011 0000 0001 |
459 kJSArray = 0x701, // 0000 0111 0000 0001 | 460 kJSArray = 0x701 // 0000 0111 0000 0001 |
460 kUninitialized = 0x1fff // 0001 1111 1111 1111 | |
461 }; | 461 }; |
462 | 462 |
463 // Make sure type fits in int16. | 463 // Make sure type fits in int16. |
464 STATIC_ASSERT(kUninitialized < (1 << (2 * kBitsPerByte))); | 464 STATIC_ASSERT(kJSArray < (1 << (2 * kBitsPerByte))); |
465 | 465 |
466 explicit HType(Type t) : type_(t) { } | 466 explicit HType(Type t) : type_(t) { } |
467 | 467 |
468 int16_t type_; | 468 int16_t type_; |
469 }; | 469 }; |
470 | 470 |
471 | 471 |
472 class HUseListNode: public ZoneObject { | 472 class HUseListNode: public ZoneObject { |
473 public: | 473 public: |
474 HUseListNode(HValue* value, int index, HUseListNode* tail) | 474 HUseListNode(HValue* value, int index, HUseListNode* tail) |
(...skipping 390 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
865 HYDROGEN_CONCRETE_INSTRUCTION_LIST(DECLARE_PREDICATE) | 865 HYDROGEN_CONCRETE_INSTRUCTION_LIST(DECLARE_PREDICATE) |
866 #undef DECLARE_PREDICATE | 866 #undef DECLARE_PREDICATE |
867 bool IsPhi() const { return opcode() == kPhi; } | 867 bool IsPhi() const { return opcode() == kPhi; } |
868 | 868 |
869 // Declare virtual predicates for abstract HInstruction or HValue | 869 // Declare virtual predicates for abstract HInstruction or HValue |
870 #define DECLARE_PREDICATE(type) \ | 870 #define DECLARE_PREDICATE(type) \ |
871 virtual bool Is##type() const { return false; } | 871 virtual bool Is##type() const { return false; } |
872 HYDROGEN_ABSTRACT_INSTRUCTION_LIST(DECLARE_PREDICATE) | 872 HYDROGEN_ABSTRACT_INSTRUCTION_LIST(DECLARE_PREDICATE) |
873 #undef DECLARE_PREDICATE | 873 #undef DECLARE_PREDICATE |
874 | 874 |
875 HValue() : block_(NULL), | 875 HValue(HType type = HType::Tagged()) |
876 id_(kNoNumber), | 876 : block_(NULL), |
877 type_(HType::Tagged()), | 877 id_(kNoNumber), |
878 use_list_(NULL), | 878 type_(type), |
879 range_(NULL), | 879 use_list_(NULL), |
880 flags_(0) {} | 880 range_(NULL), |
| 881 flags_(0) {} |
881 virtual ~HValue() {} | 882 virtual ~HValue() {} |
882 | 883 |
883 HBasicBlock* block() const { return block_; } | 884 HBasicBlock* block() const { return block_; } |
884 void SetBlock(HBasicBlock* block); | 885 void SetBlock(HBasicBlock* block); |
885 int LoopWeight() const; | 886 int LoopWeight() const; |
886 | 887 |
887 // Note: Never call this method for an unlinked value. | 888 // Note: Never call this method for an unlinked value. |
888 Isolate* isolate() const; | 889 Isolate* isolate() const; |
889 | 890 |
890 int id() const { return id_; } | 891 int id() const { return id_; } |
(...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1138 | 1139 |
1139 bool TryGuaranteeRange(HValue* upper_bound); | 1140 bool TryGuaranteeRange(HValue* upper_bound); |
1140 virtual bool TryDecompose(DecompositionResult* decomposition) { | 1141 virtual bool TryDecompose(DecompositionResult* decomposition) { |
1141 if (RedefinedOperand() != NULL) { | 1142 if (RedefinedOperand() != NULL) { |
1142 return RedefinedOperand()->TryDecompose(decomposition); | 1143 return RedefinedOperand()->TryDecompose(decomposition); |
1143 } else { | 1144 } else { |
1144 return false; | 1145 return false; |
1145 } | 1146 } |
1146 } | 1147 } |
1147 | 1148 |
| 1149 // Returns true conservatively if the program might be able to observe a |
| 1150 // ToString() operation on this value. |
| 1151 bool ToStringCanBeObserved() const { |
| 1152 return type().ToStringOrToNumberCanBeObserved(representation()); |
| 1153 } |
| 1154 |
| 1155 // Returns true conservatively if the program might be able to observe a |
| 1156 // ToNumber() operation on this value. |
| 1157 bool ToNumberCanBeObserved() const { |
| 1158 return type().ToStringOrToNumberCanBeObserved(representation()); |
| 1159 } |
| 1160 |
1148 protected: | 1161 protected: |
1149 void TryGuaranteeRangeRecursive(RangeEvaluationContext* context); | 1162 void TryGuaranteeRangeRecursive(RangeEvaluationContext* context); |
1150 | 1163 |
1151 enum RangeGuaranteeDirection { | 1164 enum RangeGuaranteeDirection { |
1152 DIRECTION_NONE = 0, | 1165 DIRECTION_NONE = 0, |
1153 DIRECTION_UPPER = 1, | 1166 DIRECTION_UPPER = 1, |
1154 DIRECTION_LOWER = 2, | 1167 DIRECTION_LOWER = 2, |
1155 DIRECTION_BOTH = DIRECTION_UPPER | DIRECTION_LOWER | 1168 DIRECTION_BOTH = DIRECTION_UPPER | DIRECTION_LOWER |
1156 }; | 1169 }; |
1157 virtual void SetResponsibilityForRange(RangeGuaranteeDirection direction) {} | 1170 virtual void SetResponsibilityForRange(RangeGuaranteeDirection direction) {} |
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1288 int flags_; | 1301 int flags_; |
1289 GVNFlagSet gvn_flags_; | 1302 GVNFlagSet gvn_flags_; |
1290 | 1303 |
1291 private: | 1304 private: |
1292 virtual bool IsDeletable() const { return false; } | 1305 virtual bool IsDeletable() const { return false; } |
1293 | 1306 |
1294 DISALLOW_COPY_AND_ASSIGN(HValue); | 1307 DISALLOW_COPY_AND_ASSIGN(HValue); |
1295 }; | 1308 }; |
1296 | 1309 |
1297 | 1310 |
| 1311 #define DECLARE_INSTRUCTION_FACTORY_P0(I) \ |
| 1312 static I* New(Zone* zone, HValue* context) { \ |
| 1313 return new(zone) I(); \ |
| 1314 } |
| 1315 |
| 1316 #define DECLARE_INSTRUCTION_FACTORY_P1(I, P1) \ |
| 1317 static I* New(Zone* zone, HValue* context, P1 p1) { \ |
| 1318 return new(zone) I(p1); \ |
| 1319 } |
| 1320 |
| 1321 #define DECLARE_INSTRUCTION_FACTORY_P2(I, P1, P2) \ |
| 1322 static I* New(Zone* zone, HValue* context, P1 p1, P2 p2) { \ |
| 1323 return new(zone) I(p1, p2); \ |
| 1324 } |
| 1325 |
| 1326 #define DECLARE_INSTRUCTION_FACTORY_P3(I, P1, P2, P3) \ |
| 1327 static I* New(Zone* zone, HValue* context, P1 p1, P2 p2, P3 p3) { \ |
| 1328 return new(zone) I(p1, p2, p3); \ |
| 1329 } |
| 1330 |
| 1331 #define DECLARE_INSTRUCTION_FACTORY_P4(I, P1, P2, P3, P4) \ |
| 1332 static I* New(Zone* zone, \ |
| 1333 HValue* context, \ |
| 1334 P1 p1, \ |
| 1335 P2 p2, \ |
| 1336 P3 p3, \ |
| 1337 P4 p4) { \ |
| 1338 return new(zone) I(p1, p2, p3, p4); \ |
| 1339 } |
| 1340 |
| 1341 #define DECLARE_INSTRUCTION_FACTORY_P5(I, P1, P2, P3, P4, P5) \ |
| 1342 static I* New(Zone* zone, \ |
| 1343 HValue* context, \ |
| 1344 P1 p1, \ |
| 1345 P2 p2, \ |
| 1346 P3 p3, \ |
| 1347 P4 p4, \ |
| 1348 P5 p5) { \ |
| 1349 return new(zone) I(p1, p2, p3, p4, p5); \ |
| 1350 } |
| 1351 |
| 1352 |
1298 class HInstruction: public HValue { | 1353 class HInstruction: public HValue { |
1299 public: | 1354 public: |
1300 HInstruction* next() const { return next_; } | 1355 HInstruction* next() const { return next_; } |
1301 HInstruction* previous() const { return previous_; } | 1356 HInstruction* previous() const { return previous_; } |
1302 | 1357 |
1303 virtual void PrintTo(StringStream* stream); | 1358 virtual void PrintTo(StringStream* stream); |
1304 virtual void PrintDataTo(StringStream* stream); | 1359 virtual void PrintDataTo(StringStream* stream); |
1305 | 1360 |
1306 bool IsLinked() const { return block() != NULL; } | 1361 bool IsLinked() const { return block() != NULL; } |
1307 void Unlink(); | 1362 void Unlink(); |
(...skipping 15 matching lines...) Expand all Loading... |
1323 | 1378 |
1324 #ifdef DEBUG | 1379 #ifdef DEBUG |
1325 virtual void Verify(); | 1380 virtual void Verify(); |
1326 #endif | 1381 #endif |
1327 | 1382 |
1328 virtual bool IsCall() { return false; } | 1383 virtual bool IsCall() { return false; } |
1329 | 1384 |
1330 DECLARE_ABSTRACT_INSTRUCTION(Instruction) | 1385 DECLARE_ABSTRACT_INSTRUCTION(Instruction) |
1331 | 1386 |
1332 protected: | 1387 protected: |
1333 HInstruction() | 1388 HInstruction(HType type = HType::Tagged()) |
1334 : next_(NULL), | 1389 : HValue(type), |
| 1390 next_(NULL), |
1335 previous_(NULL), | 1391 previous_(NULL), |
1336 position_(RelocInfo::kNoPosition) { | 1392 position_(RelocInfo::kNoPosition) { |
1337 SetGVNFlag(kDependsOnOsrEntries); | 1393 SetGVNFlag(kDependsOnOsrEntries); |
1338 } | 1394 } |
1339 | 1395 |
1340 virtual void DeleteFromGraph() { Unlink(); } | 1396 virtual void DeleteFromGraph() { Unlink(); } |
1341 | 1397 |
1342 private: | 1398 private: |
1343 void InitializeAsFirst(HBasicBlock* block) { | 1399 void InitializeAsFirst(HBasicBlock* block) { |
1344 ASSERT(!IsLinked()); | 1400 ASSERT(!IsLinked()); |
(...skipping 10 matching lines...) Expand all Loading... |
1355 }; | 1411 }; |
1356 | 1412 |
1357 | 1413 |
1358 template<int V> | 1414 template<int V> |
1359 class HTemplateInstruction : public HInstruction { | 1415 class HTemplateInstruction : public HInstruction { |
1360 public: | 1416 public: |
1361 int OperandCount() { return V; } | 1417 int OperandCount() { return V; } |
1362 HValue* OperandAt(int i) const { return inputs_[i]; } | 1418 HValue* OperandAt(int i) const { return inputs_[i]; } |
1363 | 1419 |
1364 protected: | 1420 protected: |
| 1421 HTemplateInstruction(HType type = HType::Tagged()) : HInstruction(type) {} |
| 1422 |
1365 void InternalSetOperandAt(int i, HValue* value) { inputs_[i] = value; } | 1423 void InternalSetOperandAt(int i, HValue* value) { inputs_[i] = value; } |
1366 | 1424 |
1367 private: | 1425 private: |
1368 EmbeddedContainer<HValue*, V> inputs_; | 1426 EmbeddedContainer<HValue*, V> inputs_; |
1369 }; | 1427 }; |
1370 | 1428 |
1371 | 1429 |
1372 class HControlInstruction: public HInstruction { | 1430 class HControlInstruction: public HInstruction { |
1373 public: | 1431 public: |
1374 virtual HBasicBlock* SuccessorAt(int i) = 0; | 1432 virtual HBasicBlock* SuccessorAt(int i) = 0; |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1428 virtual Representation RequiredInputRepresentation(int index) { | 1486 virtual Representation RequiredInputRepresentation(int index) { |
1429 return Representation::None(); | 1487 return Representation::None(); |
1430 } | 1488 } |
1431 | 1489 |
1432 DECLARE_CONCRETE_INSTRUCTION(BlockEntry) | 1490 DECLARE_CONCRETE_INSTRUCTION(BlockEntry) |
1433 }; | 1491 }; |
1434 | 1492 |
1435 | 1493 |
1436 class HDummyUse: public HTemplateInstruction<1> { | 1494 class HDummyUse: public HTemplateInstruction<1> { |
1437 public: | 1495 public: |
1438 explicit HDummyUse(HValue* value) { | 1496 explicit HDummyUse(HValue* value) |
| 1497 : HTemplateInstruction<1>(HType::Smi()) { |
1439 SetOperandAt(0, value); | 1498 SetOperandAt(0, value); |
1440 // Pretend to be a Smi so that the HChange instructions inserted | 1499 // Pretend to be a Smi so that the HChange instructions inserted |
1441 // before any use generate as little code as possible. | 1500 // before any use generate as little code as possible. |
1442 set_representation(Representation::Tagged()); | 1501 set_representation(Representation::Tagged()); |
1443 set_type(HType::Smi()); | |
1444 } | 1502 } |
1445 | 1503 |
1446 HValue* value() { return OperandAt(0); } | 1504 HValue* value() { return OperandAt(0); } |
1447 | 1505 |
1448 virtual bool HasEscapingOperandAt(int index) { return false; } | 1506 virtual bool HasEscapingOperandAt(int index) { return false; } |
1449 virtual Representation RequiredInputRepresentation(int index) { | 1507 virtual Representation RequiredInputRepresentation(int index) { |
1450 return Representation::None(); | 1508 return Representation::None(); |
1451 } | 1509 } |
1452 | 1510 |
1453 virtual void PrintDataTo(StringStream* stream); | 1511 virtual void PrintDataTo(StringStream* stream); |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1497 SetOperandAt(0, constrained_value); | 1555 SetOperandAt(0, constrained_value); |
1498 SetOperandAt(1, related_value); | 1556 SetOperandAt(1, related_value); |
1499 } | 1557 } |
1500 | 1558 |
1501 NumericRelation relation_; | 1559 NumericRelation relation_; |
1502 }; | 1560 }; |
1503 | 1561 |
1504 | 1562 |
1505 class HDeoptimize: public HTemplateInstruction<0> { | 1563 class HDeoptimize: public HTemplateInstruction<0> { |
1506 public: | 1564 public: |
1507 explicit HDeoptimize(Deoptimizer::BailoutType type) : type_(type) {} | 1565 DECLARE_INSTRUCTION_FACTORY_P1(HDeoptimize, Deoptimizer::BailoutType); |
1508 | 1566 |
1509 virtual Representation RequiredInputRepresentation(int index) { | 1567 virtual Representation RequiredInputRepresentation(int index) { |
1510 return Representation::None(); | 1568 return Representation::None(); |
1511 } | 1569 } |
1512 | 1570 |
1513 Deoptimizer::BailoutType type() { return type_; } | 1571 Deoptimizer::BailoutType type() { return type_; } |
1514 | 1572 |
1515 DECLARE_CONCRETE_INSTRUCTION(Deoptimize) | 1573 DECLARE_CONCRETE_INSTRUCTION(Deoptimize) |
1516 | 1574 |
1517 private: | 1575 private: |
| 1576 explicit HDeoptimize(Deoptimizer::BailoutType type) : type_(type) {} |
| 1577 |
1518 Deoptimizer::BailoutType type_; | 1578 Deoptimizer::BailoutType type_; |
1519 }; | 1579 }; |
1520 | 1580 |
1521 | 1581 |
1522 // Inserts an int3/stop break instruction for debugging purposes. | 1582 // Inserts an int3/stop break instruction for debugging purposes. |
1523 class HDebugBreak: public HTemplateInstruction<0> { | 1583 class HDebugBreak: public HTemplateInstruction<0> { |
1524 public: | 1584 public: |
1525 virtual Representation RequiredInputRepresentation(int index) { | 1585 virtual Representation RequiredInputRepresentation(int index) { |
1526 return Representation::None(); | 1586 return Representation::None(); |
1527 } | 1587 } |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1608 return Representation::Tagged(); | 1668 return Representation::Tagged(); |
1609 } | 1669 } |
1610 | 1670 |
1611 DECLARE_CONCRETE_INSTRUCTION(CompareMap) | 1671 DECLARE_CONCRETE_INSTRUCTION(CompareMap) |
1612 | 1672 |
1613 private: | 1673 private: |
1614 Handle<Map> map_; | 1674 Handle<Map> map_; |
1615 }; | 1675 }; |
1616 | 1676 |
1617 | 1677 |
| 1678 class HContext: public HTemplateInstruction<0> { |
| 1679 public: |
| 1680 static HContext* New(Zone* zone) { |
| 1681 return new(zone) HContext(); |
| 1682 } |
| 1683 |
| 1684 virtual Representation RequiredInputRepresentation(int index) { |
| 1685 return Representation::None(); |
| 1686 } |
| 1687 |
| 1688 DECLARE_CONCRETE_INSTRUCTION(Context) |
| 1689 |
| 1690 protected: |
| 1691 virtual bool DataEquals(HValue* other) { return true; } |
| 1692 |
| 1693 private: |
| 1694 HContext() { |
| 1695 set_representation(Representation::Tagged()); |
| 1696 SetFlag(kUseGVN); |
| 1697 } |
| 1698 |
| 1699 virtual bool IsDeletable() const { return true; } |
| 1700 }; |
| 1701 |
| 1702 |
1618 class HReturn: public HTemplateControlInstruction<0, 3> { | 1703 class HReturn: public HTemplateControlInstruction<0, 3> { |
1619 public: | 1704 public: |
1620 HReturn(HValue* value, HValue* context, HValue* parameter_count) { | 1705 static HInstruction* New(Zone* zone, |
1621 SetOperandAt(0, value); | 1706 HValue* context, |
1622 SetOperandAt(1, context); | 1707 HValue* value, |
1623 SetOperandAt(2, parameter_count); | 1708 HValue* parameter_count) { |
| 1709 return new(zone) HReturn(value, context, parameter_count); |
| 1710 } |
| 1711 |
| 1712 static HInstruction* New(Zone* zone, |
| 1713 HValue* context, |
| 1714 HValue* value) { |
| 1715 return new(zone) HReturn(value, context, 0); |
1624 } | 1716 } |
1625 | 1717 |
1626 virtual Representation RequiredInputRepresentation(int index) { | 1718 virtual Representation RequiredInputRepresentation(int index) { |
1627 return Representation::Tagged(); | 1719 return Representation::Tagged(); |
1628 } | 1720 } |
1629 | 1721 |
1630 virtual void PrintDataTo(StringStream* stream); | 1722 virtual void PrintDataTo(StringStream* stream); |
1631 | 1723 |
1632 HValue* value() { return OperandAt(0); } | 1724 HValue* value() { return OperandAt(0); } |
1633 HValue* context() { return OperandAt(1); } | 1725 HValue* context() { return OperandAt(1); } |
1634 HValue* parameter_count() { return OperandAt(2); } | 1726 HValue* parameter_count() { return OperandAt(2); } |
1635 | 1727 |
1636 DECLARE_CONCRETE_INSTRUCTION(Return) | 1728 DECLARE_CONCRETE_INSTRUCTION(Return) |
| 1729 |
| 1730 private: |
| 1731 HReturn(HValue* value, HValue* context, HValue* parameter_count) { |
| 1732 SetOperandAt(0, value); |
| 1733 SetOperandAt(1, context); |
| 1734 SetOperandAt(2, parameter_count); |
| 1735 } |
1637 }; | 1736 }; |
1638 | 1737 |
1639 | 1738 |
1640 class HAbnormalExit: public HTemplateControlInstruction<0, 0> { | 1739 class HAbnormalExit: public HTemplateControlInstruction<0, 0> { |
1641 public: | 1740 public: |
1642 virtual Representation RequiredInputRepresentation(int index) { | 1741 virtual Representation RequiredInputRepresentation(int index) { |
1643 return Representation::None(); | 1742 return Representation::None(); |
1644 } | 1743 } |
1645 | 1744 |
1646 DECLARE_CONCRETE_INSTRUCTION(AbnormalExit) | 1745 DECLARE_CONCRETE_INSTRUCTION(AbnormalExit) |
1647 }; | 1746 }; |
1648 | 1747 |
1649 | 1748 |
1650 class HUnaryOperation: public HTemplateInstruction<1> { | 1749 class HUnaryOperation: public HTemplateInstruction<1> { |
1651 public: | 1750 public: |
1652 explicit HUnaryOperation(HValue* value) { | 1751 HUnaryOperation(HValue* value, HType type = HType::Tagged()) |
| 1752 : HTemplateInstruction<1>(type) { |
1653 SetOperandAt(0, value); | 1753 SetOperandAt(0, value); |
1654 } | 1754 } |
1655 | 1755 |
1656 static HUnaryOperation* cast(HValue* value) { | 1756 static HUnaryOperation* cast(HValue* value) { |
1657 return reinterpret_cast<HUnaryOperation*>(value); | 1757 return reinterpret_cast<HUnaryOperation*>(value); |
1658 } | 1758 } |
1659 | 1759 |
1660 HValue* value() const { return OperandAt(0); } | 1760 HValue* value() const { return OperandAt(0); } |
1661 virtual void PrintDataTo(StringStream* stream); | 1761 virtual void PrintDataTo(StringStream* stream); |
1662 }; | 1762 }; |
1663 | 1763 |
1664 | 1764 |
1665 class HThrow: public HTemplateInstruction<2> { | 1765 class HThrow: public HTemplateInstruction<2> { |
1666 public: | 1766 public: |
1667 HThrow(HValue* context, HValue* value) { | 1767 static HThrow* New(Zone* zone, |
1668 SetOperandAt(0, context); | 1768 HValue* context, |
1669 SetOperandAt(1, value); | 1769 HValue* value) { |
1670 SetAllSideEffects(); | 1770 return new(zone) HThrow(context, value); |
1671 } | 1771 } |
1672 | 1772 |
1673 virtual Representation RequiredInputRepresentation(int index) { | 1773 virtual Representation RequiredInputRepresentation(int index) { |
1674 return Representation::Tagged(); | 1774 return Representation::Tagged(); |
1675 } | 1775 } |
1676 | 1776 |
1677 HValue* context() { return OperandAt(0); } | 1777 HValue* context() { return OperandAt(0); } |
1678 HValue* value() { return OperandAt(1); } | 1778 HValue* value() { return OperandAt(1); } |
1679 | 1779 |
1680 DECLARE_CONCRETE_INSTRUCTION(Throw) | 1780 DECLARE_CONCRETE_INSTRUCTION(Throw) |
| 1781 |
| 1782 private: |
| 1783 HThrow(HValue* context, HValue* value) { |
| 1784 SetOperandAt(0, context); |
| 1785 SetOperandAt(1, value); |
| 1786 SetAllSideEffects(); |
| 1787 } |
1681 }; | 1788 }; |
1682 | 1789 |
1683 | 1790 |
1684 class HUseConst: public HUnaryOperation { | 1791 class HUseConst: public HUnaryOperation { |
1685 public: | 1792 public: |
1686 explicit HUseConst(HValue* old_value) : HUnaryOperation(old_value) { } | 1793 DECLARE_INSTRUCTION_FACTORY_P1(HUseConst, HValue*); |
1687 | 1794 |
1688 virtual Representation RequiredInputRepresentation(int index) { | 1795 virtual Representation RequiredInputRepresentation(int index) { |
1689 return Representation::None(); | 1796 return Representation::None(); |
1690 } | 1797 } |
1691 | 1798 |
1692 DECLARE_CONCRETE_INSTRUCTION(UseConst) | 1799 DECLARE_CONCRETE_INSTRUCTION(UseConst) |
| 1800 |
| 1801 private: |
| 1802 explicit HUseConst(HValue* old_value) : HUnaryOperation(old_value) { } |
1693 }; | 1803 }; |
1694 | 1804 |
1695 | 1805 |
1696 class HForceRepresentation: public HTemplateInstruction<1> { | 1806 class HForceRepresentation: public HTemplateInstruction<1> { |
1697 public: | 1807 public: |
1698 HForceRepresentation(HValue* value, Representation required_representation) { | 1808 DECLARE_INSTRUCTION_FACTORY_P2(HForceRepresentation, HValue*, Representation); |
1699 SetOperandAt(0, value); | |
1700 set_representation(required_representation); | |
1701 } | |
1702 | 1809 |
1703 HValue* value() { return OperandAt(0); } | 1810 HValue* value() { return OperandAt(0); } |
1704 | 1811 |
1705 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited); | 1812 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited); |
1706 | 1813 |
1707 virtual Representation RequiredInputRepresentation(int index) { | 1814 virtual Representation RequiredInputRepresentation(int index) { |
1708 return representation(); // Same as the output representation. | 1815 return representation(); // Same as the output representation. |
1709 } | 1816 } |
1710 | 1817 |
1711 virtual void PrintDataTo(StringStream* stream); | 1818 virtual void PrintDataTo(StringStream* stream); |
1712 | 1819 |
1713 DECLARE_CONCRETE_INSTRUCTION(ForceRepresentation) | 1820 DECLARE_CONCRETE_INSTRUCTION(ForceRepresentation) |
| 1821 |
| 1822 private: |
| 1823 HForceRepresentation(HValue* value, Representation required_representation) { |
| 1824 SetOperandAt(0, value); |
| 1825 set_representation(required_representation); |
| 1826 } |
1714 }; | 1827 }; |
1715 | 1828 |
1716 | 1829 |
1717 class HChange: public HUnaryOperation { | 1830 class HChange: public HUnaryOperation { |
1718 public: | 1831 public: |
1719 HChange(HValue* value, | 1832 HChange(HValue* value, |
1720 Representation to, | 1833 Representation to, |
1721 bool is_truncating_to_smi, | 1834 bool is_truncating_to_smi, |
1722 bool is_truncating_to_int32, | 1835 bool is_truncating_to_int32, |
1723 bool allow_undefined_as_nan) | 1836 bool allow_undefined_as_nan) |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1765 | 1878 |
1766 private: | 1879 private: |
1767 virtual bool IsDeletable() const { | 1880 virtual bool IsDeletable() const { |
1768 return !from().IsTagged() || value()->type().IsSmi(); | 1881 return !from().IsTagged() || value()->type().IsSmi(); |
1769 } | 1882 } |
1770 }; | 1883 }; |
1771 | 1884 |
1772 | 1885 |
1773 class HClampToUint8: public HUnaryOperation { | 1886 class HClampToUint8: public HUnaryOperation { |
1774 public: | 1887 public: |
1775 explicit HClampToUint8(HValue* value) | 1888 DECLARE_INSTRUCTION_FACTORY_P1(HClampToUint8, HValue*); |
1776 : HUnaryOperation(value) { | |
1777 set_representation(Representation::Integer32()); | |
1778 SetFlag(kAllowUndefinedAsNaN); | |
1779 SetFlag(kUseGVN); | |
1780 } | |
1781 | 1889 |
1782 virtual Representation RequiredInputRepresentation(int index) { | 1890 virtual Representation RequiredInputRepresentation(int index) { |
1783 return Representation::None(); | 1891 return Representation::None(); |
1784 } | 1892 } |
1785 | 1893 |
1786 DECLARE_CONCRETE_INSTRUCTION(ClampToUint8) | 1894 DECLARE_CONCRETE_INSTRUCTION(ClampToUint8) |
1787 | 1895 |
1788 protected: | 1896 protected: |
1789 virtual bool DataEquals(HValue* other) { return true; } | 1897 virtual bool DataEquals(HValue* other) { return true; } |
1790 | 1898 |
1791 private: | 1899 private: |
| 1900 explicit HClampToUint8(HValue* value) |
| 1901 : HUnaryOperation(value) { |
| 1902 set_representation(Representation::Integer32()); |
| 1903 SetFlag(kAllowUndefinedAsNaN); |
| 1904 SetFlag(kUseGVN); |
| 1905 } |
| 1906 |
1792 virtual bool IsDeletable() const { return true; } | 1907 virtual bool IsDeletable() const { return true; } |
1793 }; | 1908 }; |
1794 | 1909 |
1795 | 1910 |
1796 enum RemovableSimulate { | 1911 enum RemovableSimulate { |
1797 REMOVABLE_SIMULATE, | 1912 REMOVABLE_SIMULATE, |
1798 FIXED_SIMULATE | 1913 FIXED_SIMULATE |
1799 }; | 1914 }; |
1800 | 1915 |
1801 | 1916 |
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1938 }; | 2053 }; |
1939 | 2054 |
1940 | 2055 |
1941 class HStackCheck: public HTemplateInstruction<1> { | 2056 class HStackCheck: public HTemplateInstruction<1> { |
1942 public: | 2057 public: |
1943 enum Type { | 2058 enum Type { |
1944 kFunctionEntry, | 2059 kFunctionEntry, |
1945 kBackwardsBranch | 2060 kBackwardsBranch |
1946 }; | 2061 }; |
1947 | 2062 |
1948 HStackCheck(HValue* context, Type type) : type_(type) { | 2063 DECLARE_INSTRUCTION_FACTORY_P2(HStackCheck, HValue*, Type); |
1949 SetOperandAt(0, context); | |
1950 SetGVNFlag(kChangesNewSpacePromotion); | |
1951 } | |
1952 | 2064 |
1953 HValue* context() { return OperandAt(0); } | 2065 HValue* context() { return OperandAt(0); } |
1954 | 2066 |
1955 virtual Representation RequiredInputRepresentation(int index) { | 2067 virtual Representation RequiredInputRepresentation(int index) { |
1956 return Representation::Tagged(); | 2068 return Representation::Tagged(); |
1957 } | 2069 } |
1958 | 2070 |
1959 void Eliminate() { | 2071 void Eliminate() { |
1960 // The stack check eliminator might try to eliminate the same stack | 2072 // The stack check eliminator might try to eliminate the same stack |
1961 // check instruction multiple times. | 2073 // check instruction multiple times. |
1962 if (IsLinked()) { | 2074 if (IsLinked()) { |
1963 DeleteAndReplaceWith(NULL); | 2075 DeleteAndReplaceWith(NULL); |
1964 } | 2076 } |
1965 } | 2077 } |
1966 | 2078 |
1967 bool is_function_entry() { return type_ == kFunctionEntry; } | 2079 bool is_function_entry() { return type_ == kFunctionEntry; } |
1968 bool is_backwards_branch() { return type_ == kBackwardsBranch; } | 2080 bool is_backwards_branch() { return type_ == kBackwardsBranch; } |
1969 | 2081 |
1970 DECLARE_CONCRETE_INSTRUCTION(StackCheck) | 2082 DECLARE_CONCRETE_INSTRUCTION(StackCheck) |
1971 | 2083 |
1972 private: | 2084 private: |
| 2085 HStackCheck(HValue* context, Type type) : type_(type) { |
| 2086 SetOperandAt(0, context); |
| 2087 SetGVNFlag(kChangesNewSpacePromotion); |
| 2088 } |
| 2089 |
1973 Type type_; | 2090 Type type_; |
1974 }; | 2091 }; |
1975 | 2092 |
1976 | 2093 |
1977 enum InliningKind { | 2094 enum InliningKind { |
1978 NORMAL_RETURN, // Normal function/method call and return. | 2095 NORMAL_RETURN, // Normal function/method call and return. |
1979 DROP_EXTRA_ON_RETURN, // Drop an extra value from the environment on return. | 2096 DROP_EXTRA_ON_RETURN, // Drop an extra value from the environment on return. |
1980 CONSTRUCT_CALL_RETURN, // Either use allocated receiver or return value. | 2097 CONSTRUCT_CALL_RETURN, // Either use allocated receiver or return value. |
1981 GETTER_CALL_RETURN, // Returning from a getter, need to restore context. | 2098 GETTER_CALL_RETURN, // Returning from a getter, need to restore context. |
1982 SETTER_CALL_RETURN // Use the RHS of the assignment as the return value. | 2099 SETTER_CALL_RETURN // Use the RHS of the assignment as the return value. |
1983 }; | 2100 }; |
1984 | 2101 |
1985 | 2102 |
1986 class HArgumentsObject; | 2103 class HArgumentsObject; |
1987 | 2104 |
1988 | 2105 |
1989 class HEnterInlined: public HTemplateInstruction<0> { | 2106 class HEnterInlined: public HTemplateInstruction<0> { |
1990 public: | 2107 public: |
1991 HEnterInlined(Handle<JSFunction> closure, | 2108 static HEnterInlined* New(Zone* zone, |
1992 int arguments_count, | 2109 HValue* context, |
1993 FunctionLiteral* function, | 2110 Handle<JSFunction> closure, |
1994 InliningKind inlining_kind, | 2111 int arguments_count, |
1995 Variable* arguments_var, | 2112 FunctionLiteral* function, |
1996 HArgumentsObject* arguments_object, | 2113 InliningKind inlining_kind, |
1997 bool undefined_receiver, | 2114 Variable* arguments_var, |
1998 Zone* zone) | 2115 HArgumentsObject* arguments_object, |
1999 : closure_(closure), | 2116 bool undefined_receiver) { |
2000 arguments_count_(arguments_count), | 2117 return new(zone) HEnterInlined(closure, arguments_count, function, |
2001 arguments_pushed_(false), | 2118 inlining_kind, arguments_var, |
2002 function_(function), | 2119 arguments_object, undefined_receiver, zone); |
2003 inlining_kind_(inlining_kind), | |
2004 arguments_var_(arguments_var), | |
2005 arguments_object_(arguments_object), | |
2006 undefined_receiver_(undefined_receiver), | |
2007 return_targets_(2, zone) { | |
2008 } | 2120 } |
2009 | 2121 |
2010 void RegisterReturnTarget(HBasicBlock* return_target, Zone* zone); | 2122 void RegisterReturnTarget(HBasicBlock* return_target, Zone* zone); |
2011 ZoneList<HBasicBlock*>* return_targets() { return &return_targets_; } | 2123 ZoneList<HBasicBlock*>* return_targets() { return &return_targets_; } |
2012 | 2124 |
2013 virtual void PrintDataTo(StringStream* stream); | 2125 virtual void PrintDataTo(StringStream* stream); |
2014 | 2126 |
2015 Handle<JSFunction> closure() const { return closure_; } | 2127 Handle<JSFunction> closure() const { return closure_; } |
2016 int arguments_count() const { return arguments_count_; } | 2128 int arguments_count() const { return arguments_count_; } |
2017 bool arguments_pushed() const { return arguments_pushed_; } | 2129 bool arguments_pushed() const { return arguments_pushed_; } |
2018 void set_arguments_pushed() { arguments_pushed_ = true; } | 2130 void set_arguments_pushed() { arguments_pushed_ = true; } |
2019 FunctionLiteral* function() const { return function_; } | 2131 FunctionLiteral* function() const { return function_; } |
2020 InliningKind inlining_kind() const { return inlining_kind_; } | 2132 InliningKind inlining_kind() const { return inlining_kind_; } |
2021 bool undefined_receiver() const { return undefined_receiver_; } | 2133 bool undefined_receiver() const { return undefined_receiver_; } |
2022 | 2134 |
2023 virtual Representation RequiredInputRepresentation(int index) { | 2135 virtual Representation RequiredInputRepresentation(int index) { |
2024 return Representation::None(); | 2136 return Representation::None(); |
2025 } | 2137 } |
2026 | 2138 |
2027 Variable* arguments_var() { return arguments_var_; } | 2139 Variable* arguments_var() { return arguments_var_; } |
2028 HArgumentsObject* arguments_object() { return arguments_object_; } | 2140 HArgumentsObject* arguments_object() { return arguments_object_; } |
2029 | 2141 |
2030 DECLARE_CONCRETE_INSTRUCTION(EnterInlined) | 2142 DECLARE_CONCRETE_INSTRUCTION(EnterInlined) |
2031 | 2143 |
2032 private: | 2144 private: |
| 2145 HEnterInlined(Handle<JSFunction> closure, |
| 2146 int arguments_count, |
| 2147 FunctionLiteral* function, |
| 2148 InliningKind inlining_kind, |
| 2149 Variable* arguments_var, |
| 2150 HArgumentsObject* arguments_object, |
| 2151 bool undefined_receiver, |
| 2152 Zone* zone) |
| 2153 : closure_(closure), |
| 2154 arguments_count_(arguments_count), |
| 2155 arguments_pushed_(false), |
| 2156 function_(function), |
| 2157 inlining_kind_(inlining_kind), |
| 2158 arguments_var_(arguments_var), |
| 2159 arguments_object_(arguments_object), |
| 2160 undefined_receiver_(undefined_receiver), |
| 2161 return_targets_(2, zone) { |
| 2162 } |
| 2163 |
2033 Handle<JSFunction> closure_; | 2164 Handle<JSFunction> closure_; |
2034 int arguments_count_; | 2165 int arguments_count_; |
2035 bool arguments_pushed_; | 2166 bool arguments_pushed_; |
2036 FunctionLiteral* function_; | 2167 FunctionLiteral* function_; |
2037 InliningKind inlining_kind_; | 2168 InliningKind inlining_kind_; |
2038 Variable* arguments_var_; | 2169 Variable* arguments_var_; |
2039 HArgumentsObject* arguments_object_; | 2170 HArgumentsObject* arguments_object_; |
2040 bool undefined_receiver_; | 2171 bool undefined_receiver_; |
2041 ZoneList<HBasicBlock*> return_targets_; | 2172 ZoneList<HBasicBlock*> return_targets_; |
2042 }; | 2173 }; |
2043 | 2174 |
2044 | 2175 |
2045 class HLeaveInlined: public HTemplateInstruction<0> { | 2176 class HLeaveInlined: public HTemplateInstruction<0> { |
2046 public: | 2177 public: |
2047 HLeaveInlined() { } | 2178 HLeaveInlined() { } |
2048 | 2179 |
2049 virtual Representation RequiredInputRepresentation(int index) { | 2180 virtual Representation RequiredInputRepresentation(int index) { |
2050 return Representation::None(); | 2181 return Representation::None(); |
2051 } | 2182 } |
2052 | 2183 |
2053 DECLARE_CONCRETE_INSTRUCTION(LeaveInlined) | 2184 DECLARE_CONCRETE_INSTRUCTION(LeaveInlined) |
2054 }; | 2185 }; |
2055 | 2186 |
2056 | 2187 |
2057 class HPushArgument: public HUnaryOperation { | 2188 class HPushArgument: public HUnaryOperation { |
2058 public: | 2189 public: |
2059 explicit HPushArgument(HValue* value) : HUnaryOperation(value) { | 2190 DECLARE_INSTRUCTION_FACTORY_P1(HPushArgument, HValue*); |
2060 set_representation(Representation::Tagged()); | |
2061 } | |
2062 | 2191 |
2063 virtual Representation RequiredInputRepresentation(int index) { | 2192 virtual Representation RequiredInputRepresentation(int index) { |
2064 return Representation::Tagged(); | 2193 return Representation::Tagged(); |
2065 } | 2194 } |
2066 | 2195 |
2067 HValue* argument() { return OperandAt(0); } | 2196 HValue* argument() { return OperandAt(0); } |
2068 | 2197 |
2069 DECLARE_CONCRETE_INSTRUCTION(PushArgument) | 2198 DECLARE_CONCRETE_INSTRUCTION(PushArgument) |
| 2199 |
| 2200 private: |
| 2201 explicit HPushArgument(HValue* value) : HUnaryOperation(value) { |
| 2202 set_representation(Representation::Tagged()); |
| 2203 } |
2070 }; | 2204 }; |
2071 | 2205 |
2072 | 2206 |
2073 class HThisFunction: public HTemplateInstruction<0> { | 2207 class HThisFunction: public HTemplateInstruction<0> { |
2074 public: | 2208 public: |
2075 HThisFunction() { | 2209 HThisFunction() { |
2076 set_representation(Representation::Tagged()); | 2210 set_representation(Representation::Tagged()); |
2077 SetFlag(kUseGVN); | 2211 SetFlag(kUseGVN); |
2078 } | 2212 } |
2079 | 2213 |
2080 virtual Representation RequiredInputRepresentation(int index) { | 2214 virtual Representation RequiredInputRepresentation(int index) { |
2081 return Representation::None(); | 2215 return Representation::None(); |
2082 } | 2216 } |
2083 | 2217 |
2084 DECLARE_CONCRETE_INSTRUCTION(ThisFunction) | 2218 DECLARE_CONCRETE_INSTRUCTION(ThisFunction) |
2085 | 2219 |
2086 protected: | 2220 protected: |
2087 virtual bool DataEquals(HValue* other) { return true; } | 2221 virtual bool DataEquals(HValue* other) { return true; } |
2088 | 2222 |
2089 private: | 2223 private: |
2090 virtual bool IsDeletable() const { return true; } | 2224 virtual bool IsDeletable() const { return true; } |
2091 }; | 2225 }; |
2092 | 2226 |
2093 | 2227 |
2094 class HContext: public HTemplateInstruction<0> { | |
2095 public: | |
2096 HContext() { | |
2097 set_representation(Representation::Tagged()); | |
2098 SetFlag(kUseGVN); | |
2099 } | |
2100 | |
2101 virtual Representation RequiredInputRepresentation(int index) { | |
2102 return Representation::None(); | |
2103 } | |
2104 | |
2105 DECLARE_CONCRETE_INSTRUCTION(Context) | |
2106 | |
2107 protected: | |
2108 virtual bool DataEquals(HValue* other) { return true; } | |
2109 | |
2110 private: | |
2111 virtual bool IsDeletable() const { return true; } | |
2112 }; | |
2113 | |
2114 | |
2115 class HOuterContext: public HUnaryOperation { | 2228 class HOuterContext: public HUnaryOperation { |
2116 public: | 2229 public: |
2117 explicit HOuterContext(HValue* inner) : HUnaryOperation(inner) { | 2230 DECLARE_INSTRUCTION_FACTORY_P1(HOuterContext, HValue*); |
2118 set_representation(Representation::Tagged()); | |
2119 SetFlag(kUseGVN); | |
2120 } | |
2121 | 2231 |
2122 DECLARE_CONCRETE_INSTRUCTION(OuterContext); | 2232 DECLARE_CONCRETE_INSTRUCTION(OuterContext); |
2123 | 2233 |
2124 virtual Representation RequiredInputRepresentation(int index) { | 2234 virtual Representation RequiredInputRepresentation(int index) { |
2125 return Representation::Tagged(); | 2235 return Representation::Tagged(); |
2126 } | 2236 } |
2127 | 2237 |
2128 protected: | 2238 protected: |
2129 virtual bool DataEquals(HValue* other) { return true; } | 2239 virtual bool DataEquals(HValue* other) { return true; } |
2130 | 2240 |
2131 private: | 2241 private: |
| 2242 explicit HOuterContext(HValue* inner) : HUnaryOperation(inner) { |
| 2243 set_representation(Representation::Tagged()); |
| 2244 SetFlag(kUseGVN); |
| 2245 } |
| 2246 |
2132 virtual bool IsDeletable() const { return true; } | 2247 virtual bool IsDeletable() const { return true; } |
2133 }; | 2248 }; |
2134 | 2249 |
2135 | 2250 |
2136 class HDeclareGlobals: public HUnaryOperation { | 2251 class HDeclareGlobals: public HUnaryOperation { |
2137 public: | 2252 public: |
2138 HDeclareGlobals(HValue* context, | 2253 HDeclareGlobals(HValue* context, |
2139 Handle<FixedArray> pairs, | 2254 Handle<FixedArray> pairs, |
2140 int flags) | 2255 int flags) |
2141 : HUnaryOperation(context), | 2256 : HUnaryOperation(context), |
2142 pairs_(pairs), | 2257 pairs_(pairs), |
2143 flags_(flags) { | 2258 flags_(flags) { |
2144 set_representation(Representation::Tagged()); | 2259 set_representation(Representation::Tagged()); |
2145 SetAllSideEffects(); | 2260 SetAllSideEffects(); |
2146 } | 2261 } |
2147 | 2262 |
| 2263 static HDeclareGlobals* New(Zone* zone, |
| 2264 HValue* context, |
| 2265 Handle<FixedArray> pairs, |
| 2266 int flags) { |
| 2267 return new(zone) HDeclareGlobals(context, pairs, flags); |
| 2268 } |
| 2269 |
2148 HValue* context() { return OperandAt(0); } | 2270 HValue* context() { return OperandAt(0); } |
2149 Handle<FixedArray> pairs() const { return pairs_; } | 2271 Handle<FixedArray> pairs() const { return pairs_; } |
2150 int flags() const { return flags_; } | 2272 int flags() const { return flags_; } |
2151 | 2273 |
2152 DECLARE_CONCRETE_INSTRUCTION(DeclareGlobals) | 2274 DECLARE_CONCRETE_INSTRUCTION(DeclareGlobals) |
2153 | 2275 |
2154 virtual Representation RequiredInputRepresentation(int index) { | 2276 virtual Representation RequiredInputRepresentation(int index) { |
2155 return Representation::Tagged(); | 2277 return Representation::Tagged(); |
2156 } | 2278 } |
| 2279 |
2157 private: | 2280 private: |
2158 Handle<FixedArray> pairs_; | 2281 Handle<FixedArray> pairs_; |
2159 int flags_; | 2282 int flags_; |
2160 }; | 2283 }; |
2161 | 2284 |
2162 | 2285 |
2163 class HGlobalObject: public HUnaryOperation { | 2286 class HGlobalObject: public HUnaryOperation { |
2164 public: | 2287 public: |
2165 explicit HGlobalObject(HValue* context) : HUnaryOperation(context) { | 2288 explicit HGlobalObject(HValue* context) : HUnaryOperation(context) { |
2166 set_representation(Representation::Tagged()); | 2289 set_representation(Representation::Tagged()); |
2167 SetFlag(kUseGVN); | 2290 SetFlag(kUseGVN); |
2168 } | 2291 } |
2169 | 2292 |
| 2293 static HGlobalObject* New(Zone* zone, HValue* context) { |
| 2294 return new(zone) HGlobalObject(context); |
| 2295 } |
| 2296 |
2170 DECLARE_CONCRETE_INSTRUCTION(GlobalObject) | 2297 DECLARE_CONCRETE_INSTRUCTION(GlobalObject) |
2171 | 2298 |
2172 virtual Representation RequiredInputRepresentation(int index) { | 2299 virtual Representation RequiredInputRepresentation(int index) { |
2173 return Representation::Tagged(); | 2300 return Representation::Tagged(); |
2174 } | 2301 } |
2175 | 2302 |
2176 protected: | 2303 protected: |
2177 virtual bool DataEquals(HValue* other) { return true; } | 2304 virtual bool DataEquals(HValue* other) { return true; } |
2178 | 2305 |
2179 private: | 2306 private: |
2180 virtual bool IsDeletable() const { return true; } | 2307 virtual bool IsDeletable() const { return true; } |
2181 }; | 2308 }; |
2182 | 2309 |
2183 | 2310 |
2184 class HGlobalReceiver: public HUnaryOperation { | 2311 class HGlobalReceiver: public HUnaryOperation { |
2185 public: | 2312 public: |
2186 explicit HGlobalReceiver(HValue* global_object) | 2313 DECLARE_INSTRUCTION_FACTORY_P1(HGlobalReceiver, HValue*); |
2187 : HUnaryOperation(global_object) { | |
2188 set_representation(Representation::Tagged()); | |
2189 SetFlag(kUseGVN); | |
2190 } | |
2191 | 2314 |
2192 DECLARE_CONCRETE_INSTRUCTION(GlobalReceiver) | 2315 DECLARE_CONCRETE_INSTRUCTION(GlobalReceiver) |
2193 | 2316 |
2194 virtual Representation RequiredInputRepresentation(int index) { | 2317 virtual Representation RequiredInputRepresentation(int index) { |
2195 return Representation::Tagged(); | 2318 return Representation::Tagged(); |
2196 } | 2319 } |
2197 | 2320 |
2198 protected: | 2321 protected: |
2199 virtual bool DataEquals(HValue* other) { return true; } | 2322 virtual bool DataEquals(HValue* other) { return true; } |
2200 | 2323 |
2201 private: | 2324 private: |
| 2325 explicit HGlobalReceiver(HValue* global_object) |
| 2326 : HUnaryOperation(global_object) { |
| 2327 set_representation(Representation::Tagged()); |
| 2328 SetFlag(kUseGVN); |
| 2329 } |
| 2330 |
2202 virtual bool IsDeletable() const { return true; } | 2331 virtual bool IsDeletable() const { return true; } |
2203 }; | 2332 }; |
2204 | 2333 |
2205 | 2334 |
2206 template <int V> | 2335 template <int V> |
2207 class HCall: public HTemplateInstruction<V> { | 2336 class HCall: public HTemplateInstruction<V> { |
2208 public: | 2337 public: |
2209 // The argument count includes the receiver. | 2338 // The argument count includes the receiver. |
2210 explicit HCall<V>(int argument_count) : argument_count_(argument_count) { | 2339 explicit HCall<V>(int argument_count) : argument_count_(argument_count) { |
2211 this->set_representation(Representation::Tagged()); | 2340 this->set_representation(Representation::Tagged()); |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2258 HValue* second() { return OperandAt(1); } | 2387 HValue* second() { return OperandAt(1); } |
2259 }; | 2388 }; |
2260 | 2389 |
2261 | 2390 |
2262 class HInvokeFunction: public HBinaryCall { | 2391 class HInvokeFunction: public HBinaryCall { |
2263 public: | 2392 public: |
2264 HInvokeFunction(HValue* context, HValue* function, int argument_count) | 2393 HInvokeFunction(HValue* context, HValue* function, int argument_count) |
2265 : HBinaryCall(context, function, argument_count) { | 2394 : HBinaryCall(context, function, argument_count) { |
2266 } | 2395 } |
2267 | 2396 |
| 2397 static HInvokeFunction* New(Zone* zone, |
| 2398 HValue* context, |
| 2399 HValue* function, |
| 2400 int argument_count) { |
| 2401 return new(zone) HInvokeFunction(context, function, argument_count); |
| 2402 } |
| 2403 |
2268 HInvokeFunction(HValue* context, | 2404 HInvokeFunction(HValue* context, |
2269 HValue* function, | 2405 HValue* function, |
2270 Handle<JSFunction> known_function, | 2406 Handle<JSFunction> known_function, |
2271 int argument_count) | 2407 int argument_count) |
2272 : HBinaryCall(context, function, argument_count), | 2408 : HBinaryCall(context, function, argument_count), |
2273 known_function_(known_function) { | 2409 known_function_(known_function) { |
2274 formal_parameter_count_ = known_function.is_null() | 2410 formal_parameter_count_ = known_function.is_null() |
2275 ? 0 : known_function->shared()->formal_parameter_count(); | 2411 ? 0 : known_function->shared()->formal_parameter_count(); |
2276 } | 2412 } |
2277 | 2413 |
| 2414 static HInvokeFunction* New(Zone* zone, |
| 2415 HValue* context, |
| 2416 HValue* function, |
| 2417 Handle<JSFunction> known_function, |
| 2418 int argument_count) { |
| 2419 return new(zone) HInvokeFunction(context, function, |
| 2420 known_function, argument_count); |
| 2421 } |
| 2422 |
2278 virtual Representation RequiredInputRepresentation(int index) { | 2423 virtual Representation RequiredInputRepresentation(int index) { |
2279 return Representation::Tagged(); | 2424 return Representation::Tagged(); |
2280 } | 2425 } |
2281 | 2426 |
2282 HValue* context() { return first(); } | 2427 HValue* context() { return first(); } |
2283 HValue* function() { return second(); } | 2428 HValue* function() { return second(); } |
2284 Handle<JSFunction> known_function() { return known_function_; } | 2429 Handle<JSFunction> known_function() { return known_function_; } |
2285 int formal_parameter_count() const { return formal_parameter_count_; } | 2430 int formal_parameter_count() const { return formal_parameter_count_; } |
2286 | 2431 |
2287 DECLARE_CONCRETE_INSTRUCTION(InvokeFunction) | 2432 DECLARE_CONCRETE_INSTRUCTION(InvokeFunction) |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2359 Handle<String> name_; | 2504 Handle<String> name_; |
2360 }; | 2505 }; |
2361 | 2506 |
2362 | 2507 |
2363 class HCallFunction: public HBinaryCall { | 2508 class HCallFunction: public HBinaryCall { |
2364 public: | 2509 public: |
2365 HCallFunction(HValue* context, HValue* function, int argument_count) | 2510 HCallFunction(HValue* context, HValue* function, int argument_count) |
2366 : HBinaryCall(context, function, argument_count) { | 2511 : HBinaryCall(context, function, argument_count) { |
2367 } | 2512 } |
2368 | 2513 |
| 2514 static HCallFunction* New(Zone* zone, |
| 2515 HValue* context, |
| 2516 HValue* function, |
| 2517 int argument_count) { |
| 2518 return new(zone) HCallFunction(context, function, argument_count); |
| 2519 } |
| 2520 |
2369 HValue* context() { return first(); } | 2521 HValue* context() { return first(); } |
2370 HValue* function() { return second(); } | 2522 HValue* function() { return second(); } |
2371 | 2523 |
2372 virtual Representation RequiredInputRepresentation(int index) { | 2524 virtual Representation RequiredInputRepresentation(int index) { |
2373 return Representation::Tagged(); | 2525 return Representation::Tagged(); |
2374 } | 2526 } |
2375 | 2527 |
2376 DECLARE_CONCRETE_INSTRUCTION(CallFunction) | 2528 DECLARE_CONCRETE_INSTRUCTION(CallFunction) |
2377 }; | 2529 }; |
2378 | 2530 |
2379 | 2531 |
2380 class HCallGlobal: public HUnaryCall { | 2532 class HCallGlobal: public HUnaryCall { |
2381 public: | 2533 public: |
2382 HCallGlobal(HValue* context, Handle<String> name, int argument_count) | 2534 HCallGlobal(HValue* context, Handle<String> name, int argument_count) |
2383 : HUnaryCall(context, argument_count), name_(name) { | 2535 : HUnaryCall(context, argument_count), name_(name) { |
2384 } | 2536 } |
2385 | 2537 |
| 2538 static HCallGlobal* New(Zone* zone, |
| 2539 HValue* context, |
| 2540 Handle<String> name, |
| 2541 int argument_count) { |
| 2542 return new(zone) HCallGlobal(context, name, argument_count); |
| 2543 } |
| 2544 |
2386 virtual void PrintDataTo(StringStream* stream); | 2545 virtual void PrintDataTo(StringStream* stream); |
2387 | 2546 |
2388 HValue* context() { return value(); } | 2547 HValue* context() { return value(); } |
2389 Handle<String> name() const { return name_; } | 2548 Handle<String> name() const { return name_; } |
2390 | 2549 |
2391 virtual Representation RequiredInputRepresentation(int index) { | 2550 virtual Representation RequiredInputRepresentation(int index) { |
2392 return Representation::Tagged(); | 2551 return Representation::Tagged(); |
2393 } | 2552 } |
2394 | 2553 |
2395 DECLARE_CONCRETE_INSTRUCTION(CallGlobal) | 2554 DECLARE_CONCRETE_INSTRUCTION(CallGlobal) |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2459 DECLARE_CONCRETE_INSTRUCTION(CallNewArray) | 2618 DECLARE_CONCRETE_INSTRUCTION(CallNewArray) |
2460 | 2619 |
2461 private: | 2620 private: |
2462 ElementsKind elements_kind_; | 2621 ElementsKind elements_kind_; |
2463 Handle<Cell> type_cell_; | 2622 Handle<Cell> type_cell_; |
2464 }; | 2623 }; |
2465 | 2624 |
2466 | 2625 |
2467 class HCallRuntime: public HCall<1> { | 2626 class HCallRuntime: public HCall<1> { |
2468 public: | 2627 public: |
2469 HCallRuntime(HValue* context, | 2628 static HCallRuntime* New(Zone* zone, |
2470 Handle<String> name, | 2629 HValue* context, |
2471 const Runtime::Function* c_function, | 2630 Handle<String> name, |
2472 int argument_count) | 2631 const Runtime::Function* c_function, |
2473 : HCall<1>(argument_count), c_function_(c_function), name_(name) { | 2632 int argument_count) { |
2474 SetOperandAt(0, context); | 2633 return new(zone) HCallRuntime(context, name, c_function, argument_count); |
2475 } | 2634 } |
2476 | 2635 |
2477 virtual void PrintDataTo(StringStream* stream); | 2636 virtual void PrintDataTo(StringStream* stream); |
2478 | 2637 |
2479 HValue* context() { return OperandAt(0); } | 2638 HValue* context() { return OperandAt(0); } |
2480 const Runtime::Function* function() const { return c_function_; } | 2639 const Runtime::Function* function() const { return c_function_; } |
2481 Handle<String> name() const { return name_; } | 2640 Handle<String> name() const { return name_; } |
2482 | 2641 |
2483 virtual Representation RequiredInputRepresentation(int index) { | 2642 virtual Representation RequiredInputRepresentation(int index) { |
2484 return Representation::Tagged(); | 2643 return Representation::Tagged(); |
2485 } | 2644 } |
2486 | 2645 |
2487 DECLARE_CONCRETE_INSTRUCTION(CallRuntime) | 2646 DECLARE_CONCRETE_INSTRUCTION(CallRuntime) |
2488 | 2647 |
2489 private: | 2648 private: |
| 2649 HCallRuntime(HValue* context, |
| 2650 Handle<String> name, |
| 2651 const Runtime::Function* c_function, |
| 2652 int argument_count) |
| 2653 : HCall<1>(argument_count), c_function_(c_function), name_(name) { |
| 2654 SetOperandAt(0, context); |
| 2655 } |
| 2656 |
2490 const Runtime::Function* c_function_; | 2657 const Runtime::Function* c_function_; |
2491 Handle<String> name_; | 2658 Handle<String> name_; |
2492 }; | 2659 }; |
2493 | 2660 |
2494 | 2661 |
2495 class HMapEnumLength: public HUnaryOperation { | 2662 class HMapEnumLength: public HUnaryOperation { |
2496 public: | 2663 public: |
2497 explicit HMapEnumLength(HValue* value) : HUnaryOperation(value) { | 2664 DECLARE_INSTRUCTION_FACTORY_P1(HMapEnumLength, HValue*); |
2498 set_type(HType::Smi()); | |
2499 set_representation(Representation::Smi()); | |
2500 SetFlag(kUseGVN); | |
2501 SetGVNFlag(kDependsOnMaps); | |
2502 } | |
2503 | 2665 |
2504 virtual Representation RequiredInputRepresentation(int index) { | 2666 virtual Representation RequiredInputRepresentation(int index) { |
2505 return Representation::Tagged(); | 2667 return Representation::Tagged(); |
2506 } | 2668 } |
2507 | 2669 |
2508 DECLARE_CONCRETE_INSTRUCTION(MapEnumLength) | 2670 DECLARE_CONCRETE_INSTRUCTION(MapEnumLength) |
2509 | 2671 |
2510 protected: | 2672 protected: |
2511 virtual bool DataEquals(HValue* other) { return true; } | 2673 virtual bool DataEquals(HValue* other) { return true; } |
2512 | 2674 |
2513 private: | 2675 private: |
| 2676 explicit HMapEnumLength(HValue* value) |
| 2677 : HUnaryOperation(value, HType::Smi()) { |
| 2678 set_representation(Representation::Smi()); |
| 2679 SetFlag(kUseGVN); |
| 2680 SetGVNFlag(kDependsOnMaps); |
| 2681 } |
| 2682 |
2514 virtual bool IsDeletable() const { return true; } | 2683 virtual bool IsDeletable() const { return true; } |
2515 }; | 2684 }; |
2516 | 2685 |
2517 | 2686 |
2518 class HElementsKind: public HUnaryOperation { | 2687 class HElementsKind: public HUnaryOperation { |
2519 public: | 2688 public: |
2520 explicit HElementsKind(HValue* value) : HUnaryOperation(value) { | 2689 explicit HElementsKind(HValue* value) : HUnaryOperation(value) { |
2521 set_representation(Representation::Integer32()); | 2690 set_representation(Representation::Integer32()); |
2522 SetFlag(kUseGVN); | 2691 SetFlag(kUseGVN); |
2523 SetGVNFlag(kDependsOnElementsKind); | 2692 SetGVNFlag(kDependsOnElementsKind); |
2524 } | 2693 } |
2525 | 2694 |
2526 virtual Representation RequiredInputRepresentation(int index) { | 2695 virtual Representation RequiredInputRepresentation(int index) { |
2527 return Representation::Tagged(); | 2696 return Representation::Tagged(); |
2528 } | 2697 } |
2529 | 2698 |
2530 DECLARE_CONCRETE_INSTRUCTION(ElementsKind) | 2699 DECLARE_CONCRETE_INSTRUCTION(ElementsKind) |
2531 | 2700 |
2532 protected: | 2701 protected: |
2533 virtual bool DataEquals(HValue* other) { return true; } | 2702 virtual bool DataEquals(HValue* other) { return true; } |
2534 | 2703 |
2535 private: | 2704 private: |
2536 virtual bool IsDeletable() const { return true; } | 2705 virtual bool IsDeletable() const { return true; } |
2537 }; | 2706 }; |
2538 | 2707 |
2539 | 2708 |
2540 class HBitNot: public HUnaryOperation { | 2709 class HBitNot: public HUnaryOperation { |
2541 public: | 2710 public: |
2542 explicit HBitNot(HValue* value) : HUnaryOperation(value) { | 2711 DECLARE_INSTRUCTION_FACTORY_P1(HBitNot, HValue*); |
2543 set_representation(Representation::Integer32()); | |
2544 SetFlag(kUseGVN); | |
2545 SetFlag(kTruncatingToInt32); | |
2546 SetFlag(kAllowUndefinedAsNaN); | |
2547 } | |
2548 | 2712 |
2549 virtual Representation RequiredInputRepresentation(int index) { | 2713 virtual Representation RequiredInputRepresentation(int index) { |
2550 return Representation::Integer32(); | 2714 return Representation::Integer32(); |
2551 } | 2715 } |
2552 virtual Representation observed_input_representation(int index) { | 2716 virtual Representation observed_input_representation(int index) { |
2553 return Representation::Integer32(); | 2717 return Representation::Integer32(); |
2554 } | 2718 } |
2555 virtual HType CalculateInferredType(); | |
2556 | 2719 |
2557 virtual HValue* Canonicalize(); | 2720 virtual HValue* Canonicalize(); |
2558 | 2721 |
2559 DECLARE_CONCRETE_INSTRUCTION(BitNot) | 2722 DECLARE_CONCRETE_INSTRUCTION(BitNot) |
2560 | 2723 |
2561 protected: | 2724 protected: |
2562 virtual bool DataEquals(HValue* other) { return true; } | 2725 virtual bool DataEquals(HValue* other) { return true; } |
2563 | 2726 |
2564 private: | 2727 private: |
| 2728 explicit HBitNot(HValue* value) |
| 2729 : HUnaryOperation(value, HType::TaggedNumber()) { |
| 2730 set_representation(Representation::Integer32()); |
| 2731 SetFlag(kUseGVN); |
| 2732 SetFlag(kTruncatingToInt32); |
| 2733 SetFlag(kAllowUndefinedAsNaN); |
| 2734 } |
| 2735 |
2565 virtual bool IsDeletable() const { return true; } | 2736 virtual bool IsDeletable() const { return true; } |
2566 }; | 2737 }; |
2567 | 2738 |
2568 | 2739 |
2569 class HUnaryMathOperation: public HTemplateInstruction<2> { | 2740 class HUnaryMathOperation: public HTemplateInstruction<2> { |
2570 public: | 2741 public: |
2571 static HInstruction* New(Zone* zone, | 2742 static HInstruction* New(Zone* zone, |
2572 HValue* context, | 2743 HValue* context, |
2573 HValue* value, | 2744 HValue* value, |
2574 BuiltinFunctionId op); | 2745 BuiltinFunctionId op); |
2575 | 2746 |
2576 HValue* context() { return OperandAt(0); } | 2747 HValue* context() { return OperandAt(0); } |
2577 HValue* value() { return OperandAt(1); } | 2748 HValue* value() { return OperandAt(1); } |
2578 | 2749 |
2579 virtual void PrintDataTo(StringStream* stream); | 2750 virtual void PrintDataTo(StringStream* stream); |
2580 | 2751 |
2581 virtual HType CalculateInferredType(); | |
2582 | |
2583 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited); | 2752 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited); |
2584 | 2753 |
2585 virtual Representation RequiredInputRepresentation(int index) { | 2754 virtual Representation RequiredInputRepresentation(int index) { |
2586 if (index == 0) { | 2755 if (index == 0) { |
2587 return Representation::Tagged(); | 2756 return Representation::Tagged(); |
2588 } else { | 2757 } else { |
2589 switch (op_) { | 2758 switch (op_) { |
2590 case kMathFloor: | 2759 case kMathFloor: |
2591 case kMathRound: | 2760 case kMathRound: |
2592 case kMathSqrt: | 2761 case kMathSqrt: |
(...skipping 24 matching lines...) Expand all Loading... |
2617 DECLARE_CONCRETE_INSTRUCTION(UnaryMathOperation) | 2786 DECLARE_CONCRETE_INSTRUCTION(UnaryMathOperation) |
2618 | 2787 |
2619 protected: | 2788 protected: |
2620 virtual bool DataEquals(HValue* other) { | 2789 virtual bool DataEquals(HValue* other) { |
2621 HUnaryMathOperation* b = HUnaryMathOperation::cast(other); | 2790 HUnaryMathOperation* b = HUnaryMathOperation::cast(other); |
2622 return op_ == b->op(); | 2791 return op_ == b->op(); |
2623 } | 2792 } |
2624 | 2793 |
2625 private: | 2794 private: |
2626 HUnaryMathOperation(HValue* context, HValue* value, BuiltinFunctionId op) | 2795 HUnaryMathOperation(HValue* context, HValue* value, BuiltinFunctionId op) |
2627 : op_(op) { | 2796 : HTemplateInstruction<2>(HType::TaggedNumber()), op_(op) { |
2628 SetOperandAt(0, context); | 2797 SetOperandAt(0, context); |
2629 SetOperandAt(1, value); | 2798 SetOperandAt(1, value); |
2630 switch (op) { | 2799 switch (op) { |
2631 case kMathFloor: | 2800 case kMathFloor: |
2632 case kMathRound: | 2801 case kMathRound: |
2633 // TODO(verwaest): Set representation to flexible int starting as smi. | 2802 // TODO(verwaest): Set representation to flexible int starting as smi. |
2634 set_representation(Representation::Integer32()); | 2803 set_representation(Representation::Integer32()); |
2635 break; | 2804 break; |
2636 case kMathAbs: | 2805 case kMathAbs: |
2637 // Not setting representation here: it is None intentionally. | 2806 // Not setting representation here: it is None intentionally. |
(...skipping 23 matching lines...) Expand all Loading... |
2661 } | 2830 } |
2662 | 2831 |
2663 virtual bool IsDeletable() const { return true; } | 2832 virtual bool IsDeletable() const { return true; } |
2664 | 2833 |
2665 BuiltinFunctionId op_; | 2834 BuiltinFunctionId op_; |
2666 }; | 2835 }; |
2667 | 2836 |
2668 | 2837 |
2669 class HLoadExternalArrayPointer: public HUnaryOperation { | 2838 class HLoadExternalArrayPointer: public HUnaryOperation { |
2670 public: | 2839 public: |
| 2840 DECLARE_INSTRUCTION_FACTORY_P1(HLoadExternalArrayPointer, HValue*); |
| 2841 |
| 2842 virtual Representation RequiredInputRepresentation(int index) { |
| 2843 return Representation::Tagged(); |
| 2844 } |
| 2845 |
| 2846 virtual HType CalculateInferredType() { |
| 2847 return HType::None(); |
| 2848 } |
| 2849 |
| 2850 DECLARE_CONCRETE_INSTRUCTION(LoadExternalArrayPointer) |
| 2851 |
| 2852 protected: |
| 2853 virtual bool DataEquals(HValue* other) { return true; } |
| 2854 |
| 2855 private: |
2671 explicit HLoadExternalArrayPointer(HValue* value) | 2856 explicit HLoadExternalArrayPointer(HValue* value) |
2672 : HUnaryOperation(value) { | 2857 : HUnaryOperation(value) { |
2673 set_representation(Representation::External()); | 2858 set_representation(Representation::External()); |
2674 // The result of this instruction is idempotent as long as its inputs don't | 2859 // The result of this instruction is idempotent as long as its inputs don't |
2675 // change. The external array of a specialized array elements object cannot | 2860 // change. The external array of a specialized array elements object cannot |
2676 // change once set, so it's no necessary to introduce any additional | 2861 // change once set, so it's no necessary to introduce any additional |
2677 // dependencies on top of the inputs. | 2862 // dependencies on top of the inputs. |
2678 SetFlag(kUseGVN); | 2863 SetFlag(kUseGVN); |
2679 } | 2864 } |
2680 | 2865 |
2681 virtual Representation RequiredInputRepresentation(int index) { | |
2682 return Representation::Tagged(); | |
2683 } | |
2684 | |
2685 DECLARE_CONCRETE_INSTRUCTION(LoadExternalArrayPointer) | |
2686 | |
2687 protected: | |
2688 virtual bool DataEquals(HValue* other) { return true; } | |
2689 | |
2690 private: | |
2691 virtual bool IsDeletable() const { return true; } | 2866 virtual bool IsDeletable() const { return true; } |
2692 }; | 2867 }; |
2693 | 2868 |
2694 | 2869 |
2695 class HCheckMaps: public HTemplateInstruction<2> { | 2870 class HCheckMaps: public HTemplateInstruction<2> { |
2696 public: | 2871 public: |
2697 static HCheckMaps* New(HValue* value, Handle<Map> map, Zone* zone, | 2872 static HCheckMaps* New(Zone* zone, HValue* context, HValue* value, |
2698 CompilationInfo* info, HValue *typecheck = NULL); | 2873 Handle<Map> map, CompilationInfo* info, |
2699 static HCheckMaps* New(HValue* value, SmallMapList* maps, Zone* zone, | 2874 HValue *typecheck = NULL); |
| 2875 static HCheckMaps* New(Zone* zone, HValue* context, |
| 2876 HValue* value, SmallMapList* maps, |
2700 HValue *typecheck = NULL) { | 2877 HValue *typecheck = NULL) { |
2701 HCheckMaps* check_map = new(zone) HCheckMaps(value, zone, typecheck); | 2878 HCheckMaps* check_map = new(zone) HCheckMaps(value, zone, typecheck); |
2702 for (int i = 0; i < maps->length(); i++) { | 2879 for (int i = 0; i < maps->length(); i++) { |
2703 check_map->map_set_.Add(maps->at(i), zone); | 2880 check_map->map_set_.Add(maps->at(i), zone); |
2704 } | 2881 } |
2705 check_map->map_set_.Sort(); | 2882 check_map->map_set_.Sort(); |
2706 return check_map; | 2883 return check_map; |
2707 } | 2884 } |
2708 | 2885 |
2709 static HCheckMaps* NewWithTransitions(HValue* value, Handle<Map> map, | |
2710 Zone* zone, CompilationInfo* info); | |
2711 | |
2712 bool CanOmitMapChecks() { return omit_; } | 2886 bool CanOmitMapChecks() { return omit_; } |
2713 | 2887 |
2714 virtual bool HasEscapingOperandAt(int index) { return false; } | 2888 virtual bool HasEscapingOperandAt(int index) { return false; } |
2715 virtual Representation RequiredInputRepresentation(int index) { | 2889 virtual Representation RequiredInputRepresentation(int index) { |
2716 return Representation::Tagged(); | 2890 return Representation::Tagged(); |
2717 } | 2891 } |
2718 virtual void HandleSideEffectDominator(GVNFlag side_effect, | 2892 virtual void HandleSideEffectDominator(GVNFlag side_effect, |
2719 HValue* dominator); | 2893 HValue* dominator); |
2720 virtual void PrintDataTo(StringStream* stream); | 2894 virtual void PrintDataTo(StringStream* stream); |
2721 virtual HType CalculateInferredType(); | |
2722 | 2895 |
2723 HValue* value() { return OperandAt(0); } | 2896 HValue* value() { return OperandAt(0); } |
2724 SmallMapList* map_set() { return &map_set_; } | 2897 SmallMapList* map_set() { return &map_set_; } |
2725 | 2898 |
2726 virtual void FinalizeUniqueValueId(); | 2899 virtual void FinalizeUniqueValueId(); |
2727 | 2900 |
2728 DECLARE_CONCRETE_INSTRUCTION(CheckMaps) | 2901 DECLARE_CONCRETE_INSTRUCTION(CheckMaps) |
2729 | 2902 |
2730 protected: | 2903 protected: |
2731 virtual bool DataEquals(HValue* other) { | 2904 virtual bool DataEquals(HValue* other) { |
2732 ASSERT_EQ(map_set_.length(), map_unique_ids_.length()); | 2905 ASSERT_EQ(map_set_.length(), map_unique_ids_.length()); |
2733 HCheckMaps* b = HCheckMaps::cast(other); | 2906 HCheckMaps* b = HCheckMaps::cast(other); |
2734 // Relies on the fact that map_set has been sorted before. | 2907 // Relies on the fact that map_set has been sorted before. |
2735 if (map_unique_ids_.length() != b->map_unique_ids_.length()) { | 2908 if (map_unique_ids_.length() != b->map_unique_ids_.length()) { |
2736 return false; | 2909 return false; |
2737 } | 2910 } |
2738 for (int i = 0; i < map_unique_ids_.length(); i++) { | 2911 for (int i = 0; i < map_unique_ids_.length(); i++) { |
2739 if (map_unique_ids_.at(i) != b->map_unique_ids_.at(i)) { | 2912 if (map_unique_ids_.at(i) != b->map_unique_ids_.at(i)) { |
2740 return false; | 2913 return false; |
2741 } | 2914 } |
2742 } | 2915 } |
2743 return true; | 2916 return true; |
2744 } | 2917 } |
2745 | 2918 |
2746 private: | 2919 private: |
2747 // Clients should use one of the static New* methods above. | 2920 // Clients should use one of the static New* methods above. |
2748 HCheckMaps(HValue* value, Zone *zone, HValue* typecheck) | 2921 HCheckMaps(HValue* value, Zone *zone, HValue* typecheck) |
2749 : omit_(false), map_unique_ids_(0, zone) { | 2922 : HTemplateInstruction<2>(value->type()), |
| 2923 omit_(false), map_unique_ids_(0, zone) { |
2750 SetOperandAt(0, value); | 2924 SetOperandAt(0, value); |
2751 // Use the object value for the dependency if NULL is passed. | 2925 // Use the object value for the dependency if NULL is passed. |
2752 // TODO(titzer): do GVN flags already express this dependency? | 2926 // TODO(titzer): do GVN flags already express this dependency? |
2753 SetOperandAt(1, typecheck != NULL ? typecheck : value); | 2927 SetOperandAt(1, typecheck != NULL ? typecheck : value); |
2754 set_representation(Representation::Tagged()); | 2928 set_representation(Representation::Tagged()); |
2755 SetFlag(kUseGVN); | 2929 SetFlag(kUseGVN); |
2756 SetFlag(kTrackSideEffectDominators); | 2930 SetFlag(kTrackSideEffectDominators); |
2757 SetGVNFlag(kDependsOnMaps); | 2931 SetGVNFlag(kDependsOnMaps); |
2758 SetGVNFlag(kDependsOnElementsKind); | 2932 SetGVNFlag(kDependsOnElementsKind); |
2759 } | 2933 } |
2760 | 2934 |
2761 void omit(CompilationInfo* info) { | 2935 void omit(CompilationInfo* info) { |
2762 omit_ = true; | 2936 omit_ = true; |
2763 for (int i = 0; i < map_set_.length(); i++) { | 2937 for (int i = 0; i < map_set_.length(); i++) { |
2764 Handle<Map> map = map_set_.at(i); | 2938 Handle<Map> map = map_set_.at(i); |
2765 map->AddDependentCompilationInfo(DependentCode::kPrototypeCheckGroup, | 2939 map->AddDependentCompilationInfo(DependentCode::kPrototypeCheckGroup, |
2766 info); | 2940 info); |
2767 } | 2941 } |
2768 } | 2942 } |
2769 | 2943 |
2770 bool omit_; | 2944 bool omit_; |
2771 SmallMapList map_set_; | 2945 SmallMapList map_set_; |
2772 ZoneList<UniqueValueId> map_unique_ids_; | 2946 ZoneList<UniqueValueId> map_unique_ids_; |
2773 }; | 2947 }; |
2774 | 2948 |
2775 | 2949 |
2776 class HCheckFunction: public HUnaryOperation { | 2950 class HCheckFunction: public HUnaryOperation { |
2777 public: | 2951 public: |
2778 HCheckFunction(HValue* value, Handle<JSFunction> function) | 2952 DECLARE_INSTRUCTION_FACTORY_P2(HCheckFunction, HValue*, Handle<JSFunction>); |
2779 : HUnaryOperation(value), target_(function), target_unique_id_() { | |
2780 set_representation(Representation::Tagged()); | |
2781 SetFlag(kUseGVN); | |
2782 target_in_new_space_ = Isolate::Current()->heap()->InNewSpace(*function); | |
2783 } | |
2784 | 2953 |
2785 virtual Representation RequiredInputRepresentation(int index) { | 2954 virtual Representation RequiredInputRepresentation(int index) { |
2786 return Representation::Tagged(); | 2955 return Representation::Tagged(); |
2787 } | 2956 } |
2788 virtual void PrintDataTo(StringStream* stream); | 2957 virtual void PrintDataTo(StringStream* stream); |
2789 virtual HType CalculateInferredType(); | |
2790 | 2958 |
2791 virtual HValue* Canonicalize(); | 2959 virtual HValue* Canonicalize(); |
2792 | 2960 |
2793 #ifdef DEBUG | 2961 #ifdef DEBUG |
2794 virtual void Verify(); | 2962 virtual void Verify(); |
2795 #endif | 2963 #endif |
2796 | 2964 |
2797 virtual void FinalizeUniqueValueId() { | 2965 virtual void FinalizeUniqueValueId() { |
2798 target_unique_id_ = UniqueValueId(target_); | 2966 target_unique_id_ = UniqueValueId(target_); |
2799 } | 2967 } |
2800 | 2968 |
2801 Handle<JSFunction> target() const { return target_; } | 2969 Handle<JSFunction> target() const { return target_; } |
2802 bool target_in_new_space() const { return target_in_new_space_; } | 2970 bool target_in_new_space() const { return target_in_new_space_; } |
2803 | 2971 |
2804 DECLARE_CONCRETE_INSTRUCTION(CheckFunction) | 2972 DECLARE_CONCRETE_INSTRUCTION(CheckFunction) |
2805 | 2973 |
2806 protected: | 2974 protected: |
2807 virtual bool DataEquals(HValue* other) { | 2975 virtual bool DataEquals(HValue* other) { |
2808 HCheckFunction* b = HCheckFunction::cast(other); | 2976 HCheckFunction* b = HCheckFunction::cast(other); |
2809 return target_unique_id_ == b->target_unique_id_; | 2977 return target_unique_id_ == b->target_unique_id_; |
2810 } | 2978 } |
2811 | 2979 |
2812 private: | 2980 private: |
| 2981 HCheckFunction(HValue* value, Handle<JSFunction> function) |
| 2982 : HUnaryOperation(value, value->type()), |
| 2983 target_(function), target_unique_id_() { |
| 2984 set_representation(Representation::Tagged()); |
| 2985 SetFlag(kUseGVN); |
| 2986 target_in_new_space_ = Isolate::Current()->heap()->InNewSpace(*function); |
| 2987 } |
| 2988 |
2813 Handle<JSFunction> target_; | 2989 Handle<JSFunction> target_; |
2814 UniqueValueId target_unique_id_; | 2990 UniqueValueId target_unique_id_; |
2815 bool target_in_new_space_; | 2991 bool target_in_new_space_; |
2816 }; | 2992 }; |
2817 | 2993 |
2818 | 2994 |
2819 class HCheckInstanceType: public HUnaryOperation { | 2995 class HCheckInstanceType: public HUnaryOperation { |
2820 public: | 2996 public: |
2821 static HCheckInstanceType* NewIsSpecObject(HValue* value, Zone* zone) { | 2997 static HCheckInstanceType* NewIsSpecObject(HValue* value, Zone* zone) { |
2822 return new(zone) HCheckInstanceType(value, IS_SPEC_OBJECT); | 2998 return new(zone) HCheckInstanceType(value, IS_SPEC_OBJECT); |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2871 set_representation(Representation::Tagged()); | 3047 set_representation(Representation::Tagged()); |
2872 SetFlag(kUseGVN); | 3048 SetFlag(kUseGVN); |
2873 } | 3049 } |
2874 | 3050 |
2875 const Check check_; | 3051 const Check check_; |
2876 }; | 3052 }; |
2877 | 3053 |
2878 | 3054 |
2879 class HCheckSmi: public HUnaryOperation { | 3055 class HCheckSmi: public HUnaryOperation { |
2880 public: | 3056 public: |
2881 explicit HCheckSmi(HValue* value) : HUnaryOperation(value) { | 3057 DECLARE_INSTRUCTION_FACTORY_P1(HCheckSmi, HValue*); |
2882 set_representation(Representation::Smi()); | |
2883 SetFlag(kUseGVN); | |
2884 } | |
2885 | 3058 |
2886 virtual Representation RequiredInputRepresentation(int index) { | 3059 virtual Representation RequiredInputRepresentation(int index) { |
2887 return Representation::Tagged(); | 3060 return Representation::Tagged(); |
2888 } | 3061 } |
2889 | 3062 |
2890 virtual HType CalculateInferredType(); | |
2891 | |
2892 virtual HValue* Canonicalize() { | 3063 virtual HValue* Canonicalize() { |
2893 HType value_type = value()->type(); | 3064 HType value_type = value()->type(); |
2894 if (value_type.IsSmi()) { | 3065 if (value_type.IsSmi()) { |
2895 return NULL; | 3066 return NULL; |
2896 } | 3067 } |
2897 return this; | 3068 return this; |
2898 } | 3069 } |
2899 | 3070 |
2900 DECLARE_CONCRETE_INSTRUCTION(CheckSmi) | 3071 DECLARE_CONCRETE_INSTRUCTION(CheckSmi) |
2901 | 3072 |
2902 protected: | 3073 protected: |
2903 virtual bool DataEquals(HValue* other) { return true; } | 3074 virtual bool DataEquals(HValue* other) { return true; } |
| 3075 |
| 3076 private: |
| 3077 explicit HCheckSmi(HValue* value) : HUnaryOperation(value, HType::Smi()) { |
| 3078 set_representation(Representation::Smi()); |
| 3079 SetFlag(kUseGVN); |
| 3080 } |
2904 }; | 3081 }; |
2905 | 3082 |
2906 | 3083 |
2907 class HIsNumberAndBranch: public HUnaryControlInstruction { | 3084 class HIsNumberAndBranch: public HUnaryControlInstruction { |
2908 public: | 3085 public: |
2909 explicit HIsNumberAndBranch(HValue* value) | 3086 explicit HIsNumberAndBranch(HValue* value) |
2910 : HUnaryControlInstruction(value, NULL, NULL) { | 3087 : HUnaryControlInstruction(value, NULL, NULL) { |
2911 SetFlag(kFlexibleRepresentation); | 3088 SetFlag(kFlexibleRepresentation); |
2912 } | 3089 } |
2913 | 3090 |
2914 virtual Representation RequiredInputRepresentation(int index) { | 3091 virtual Representation RequiredInputRepresentation(int index) { |
2915 return Representation::None(); | 3092 return Representation::None(); |
2916 } | 3093 } |
2917 | 3094 |
2918 DECLARE_CONCRETE_INSTRUCTION(IsNumberAndBranch) | 3095 DECLARE_CONCRETE_INSTRUCTION(IsNumberAndBranch) |
2919 }; | 3096 }; |
2920 | 3097 |
2921 | 3098 |
2922 class HCheckHeapObject: public HUnaryOperation { | 3099 class HCheckHeapObject: public HUnaryOperation { |
2923 public: | 3100 public: |
2924 explicit HCheckHeapObject(HValue* value) : HUnaryOperation(value) { | 3101 DECLARE_INSTRUCTION_FACTORY_P1(HCheckHeapObject, HValue*); |
2925 set_representation(Representation::Tagged()); | |
2926 SetFlag(kUseGVN); | |
2927 } | |
2928 | 3102 |
2929 virtual Representation RequiredInputRepresentation(int index) { | 3103 virtual Representation RequiredInputRepresentation(int index) { |
2930 return Representation::Tagged(); | 3104 return Representation::Tagged(); |
2931 } | 3105 } |
2932 | 3106 |
2933 virtual HType CalculateInferredType(); | |
2934 | |
2935 #ifdef DEBUG | 3107 #ifdef DEBUG |
2936 virtual void Verify(); | 3108 virtual void Verify(); |
2937 #endif | 3109 #endif |
2938 | 3110 |
2939 virtual HValue* Canonicalize() { | 3111 virtual HValue* Canonicalize() { |
2940 HType value_type = value()->type(); | 3112 return value()->type().IsHeapObject() ? NULL : this; |
2941 if (!value_type.IsUninitialized() && value_type.IsHeapObject()) { | |
2942 return NULL; | |
2943 } | |
2944 return this; | |
2945 } | 3113 } |
2946 | 3114 |
2947 DECLARE_CONCRETE_INSTRUCTION(CheckHeapObject) | 3115 DECLARE_CONCRETE_INSTRUCTION(CheckHeapObject) |
2948 | 3116 |
2949 protected: | 3117 protected: |
2950 virtual bool DataEquals(HValue* other) { return true; } | 3118 virtual bool DataEquals(HValue* other) { return true; } |
| 3119 |
| 3120 private: |
| 3121 explicit HCheckHeapObject(HValue* value) |
| 3122 : HUnaryOperation(value, HType::NonPrimitive()) { |
| 3123 set_representation(Representation::Tagged()); |
| 3124 SetFlag(kUseGVN); |
| 3125 } |
2951 }; | 3126 }; |
2952 | 3127 |
2953 | 3128 |
2954 class HCheckPrototypeMaps: public HTemplateInstruction<0> { | 3129 class HCheckPrototypeMaps: public HTemplateInstruction<0> { |
2955 public: | 3130 public: |
2956 HCheckPrototypeMaps(Handle<JSObject> prototype, | 3131 static HCheckPrototypeMaps* New(Zone* zone, |
2957 Handle<JSObject> holder, | 3132 HValue* context, |
2958 Zone* zone, | 3133 Handle<JSObject> prototype, |
2959 CompilationInfo* info) | 3134 Handle<JSObject> holder, |
2960 : prototypes_(2, zone), | 3135 CompilationInfo* info) { |
2961 maps_(2, zone), | 3136 return new(zone) HCheckPrototypeMaps(prototype, holder, zone, info); |
2962 first_prototype_unique_id_(), | |
2963 last_prototype_unique_id_(), | |
2964 can_omit_prototype_maps_(true) { | |
2965 SetFlag(kUseGVN); | |
2966 SetGVNFlag(kDependsOnMaps); | |
2967 // Keep a list of all objects on the prototype chain up to the holder | |
2968 // and the expected maps. | |
2969 while (true) { | |
2970 prototypes_.Add(prototype, zone); | |
2971 Handle<Map> map(prototype->map()); | |
2972 maps_.Add(map, zone); | |
2973 can_omit_prototype_maps_ &= map->CanOmitPrototypeChecks(); | |
2974 if (prototype.is_identical_to(holder)) break; | |
2975 prototype = Handle<JSObject>(JSObject::cast(prototype->GetPrototype())); | |
2976 } | |
2977 if (can_omit_prototype_maps_) { | |
2978 // Mark in-flight compilation as dependent on those maps. | |
2979 for (int i = 0; i < maps()->length(); i++) { | |
2980 Handle<Map> map = maps()->at(i); | |
2981 map->AddDependentCompilationInfo(DependentCode::kPrototypeCheckGroup, | |
2982 info); | |
2983 } | |
2984 } | |
2985 } | 3137 } |
2986 | 3138 |
2987 ZoneList<Handle<JSObject> >* prototypes() { return &prototypes_; } | 3139 ZoneList<Handle<JSObject> >* prototypes() { return &prototypes_; } |
2988 | 3140 |
2989 ZoneList<Handle<Map> >* maps() { return &maps_; } | 3141 ZoneList<Handle<Map> >* maps() { return &maps_; } |
2990 | 3142 |
2991 DECLARE_CONCRETE_INSTRUCTION(CheckPrototypeMaps) | 3143 DECLARE_CONCRETE_INSTRUCTION(CheckPrototypeMaps) |
2992 | 3144 |
2993 virtual Representation RequiredInputRepresentation(int index) { | 3145 virtual Representation RequiredInputRepresentation(int index) { |
2994 return Representation::None(); | 3146 return Representation::None(); |
(...skipping 14 matching lines...) Expand all Loading... |
3009 bool CanOmitPrototypeChecks() { return can_omit_prototype_maps_; } | 3161 bool CanOmitPrototypeChecks() { return can_omit_prototype_maps_; } |
3010 | 3162 |
3011 protected: | 3163 protected: |
3012 virtual bool DataEquals(HValue* other) { | 3164 virtual bool DataEquals(HValue* other) { |
3013 HCheckPrototypeMaps* b = HCheckPrototypeMaps::cast(other); | 3165 HCheckPrototypeMaps* b = HCheckPrototypeMaps::cast(other); |
3014 return first_prototype_unique_id_ == b->first_prototype_unique_id_ && | 3166 return first_prototype_unique_id_ == b->first_prototype_unique_id_ && |
3015 last_prototype_unique_id_ == b->last_prototype_unique_id_; | 3167 last_prototype_unique_id_ == b->last_prototype_unique_id_; |
3016 } | 3168 } |
3017 | 3169 |
3018 private: | 3170 private: |
| 3171 HCheckPrototypeMaps(Handle<JSObject> prototype, |
| 3172 Handle<JSObject> holder, |
| 3173 Zone* zone, |
| 3174 CompilationInfo* info) |
| 3175 : prototypes_(2, zone), |
| 3176 maps_(2, zone), |
| 3177 first_prototype_unique_id_(), |
| 3178 last_prototype_unique_id_(), |
| 3179 can_omit_prototype_maps_(true) { |
| 3180 SetFlag(kUseGVN); |
| 3181 SetGVNFlag(kDependsOnMaps); |
| 3182 // Keep a list of all objects on the prototype chain up to the holder |
| 3183 // and the expected maps. |
| 3184 while (true) { |
| 3185 prototypes_.Add(prototype, zone); |
| 3186 Handle<Map> map(prototype->map()); |
| 3187 maps_.Add(map, zone); |
| 3188 can_omit_prototype_maps_ &= map->CanOmitPrototypeChecks(); |
| 3189 if (prototype.is_identical_to(holder)) break; |
| 3190 prototype = Handle<JSObject>(JSObject::cast(prototype->GetPrototype())); |
| 3191 } |
| 3192 if (can_omit_prototype_maps_) { |
| 3193 // Mark in-flight compilation as dependent on those maps. |
| 3194 for (int i = 0; i < maps()->length(); i++) { |
| 3195 Handle<Map> map = maps()->at(i); |
| 3196 map->AddDependentCompilationInfo(DependentCode::kPrototypeCheckGroup, |
| 3197 info); |
| 3198 } |
| 3199 } |
| 3200 } |
| 3201 |
3019 ZoneList<Handle<JSObject> > prototypes_; | 3202 ZoneList<Handle<JSObject> > prototypes_; |
3020 ZoneList<Handle<Map> > maps_; | 3203 ZoneList<Handle<Map> > maps_; |
3021 UniqueValueId first_prototype_unique_id_; | 3204 UniqueValueId first_prototype_unique_id_; |
3022 UniqueValueId last_prototype_unique_id_; | 3205 UniqueValueId last_prototype_unique_id_; |
3023 bool can_omit_prototype_maps_; | 3206 bool can_omit_prototype_maps_; |
3024 }; | 3207 }; |
3025 | 3208 |
3026 | 3209 |
3027 class InductionVariableData; | 3210 class InductionVariableData; |
3028 | 3211 |
(...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3336 int phi_id() { return phi_id_; } | 3519 int phi_id() { return phi_id_; } |
3337 | 3520 |
3338 static HPhi* cast(HValue* value) { | 3521 static HPhi* cast(HValue* value) { |
3339 ASSERT(value->IsPhi()); | 3522 ASSERT(value->IsPhi()); |
3340 return reinterpret_cast<HPhi*>(value); | 3523 return reinterpret_cast<HPhi*>(value); |
3341 } | 3524 } |
3342 virtual Opcode opcode() const { return HValue::kPhi; } | 3525 virtual Opcode opcode() const { return HValue::kPhi; } |
3343 | 3526 |
3344 void SimplifyConstantInputs(); | 3527 void SimplifyConstantInputs(); |
3345 | 3528 |
3346 // TODO(titzer): we can't eliminate the receiver for generating backtraces | |
3347 virtual bool IsDeletable() const { return !IsReceiver(); } | |
3348 | |
3349 protected: | 3529 protected: |
3350 virtual void DeleteFromGraph(); | 3530 virtual void DeleteFromGraph(); |
3351 virtual void InternalSetOperandAt(int index, HValue* value) { | 3531 virtual void InternalSetOperandAt(int index, HValue* value) { |
3352 inputs_[index] = value; | 3532 inputs_[index] = value; |
3353 } | 3533 } |
3354 | 3534 |
3355 virtual bool IsRelationTrueInternal(NumericRelation relation, | 3535 virtual bool IsRelationTrueInternal(NumericRelation relation, |
3356 HValue* other, | 3536 HValue* other, |
3357 int offset = 0, | 3537 int offset = 0, |
3358 int scale = 0); | 3538 int scale = 0); |
3359 | 3539 |
3360 private: | 3540 private: |
3361 ZoneList<HValue*> inputs_; | 3541 ZoneList<HValue*> inputs_; |
3362 int merged_index_; | 3542 int merged_index_; |
3363 | 3543 |
3364 int non_phi_uses_[Representation::kNumRepresentations]; | 3544 int non_phi_uses_[Representation::kNumRepresentations]; |
3365 int indirect_uses_[Representation::kNumRepresentations]; | 3545 int indirect_uses_[Representation::kNumRepresentations]; |
3366 int phi_id_; | 3546 int phi_id_; |
3367 InductionVariableData* induction_variable_data_; | 3547 InductionVariableData* induction_variable_data_; |
| 3548 |
| 3549 // TODO(titzer): we can't eliminate the receiver for generating backtraces |
| 3550 virtual bool IsDeletable() const { return !IsReceiver(); } |
3368 }; | 3551 }; |
3369 | 3552 |
3370 | 3553 |
3371 class HInductionVariableAnnotation : public HUnaryOperation { | 3554 class HInductionVariableAnnotation : public HUnaryOperation { |
3372 public: | 3555 public: |
3373 static HInductionVariableAnnotation* AddToGraph(HPhi* phi, | 3556 static HInductionVariableAnnotation* AddToGraph(HPhi* phi, |
3374 NumericRelation relation, | 3557 NumericRelation relation, |
3375 int operand_index); | 3558 int operand_index); |
3376 | 3559 |
3377 NumericRelation relation() { return relation_; } | 3560 NumericRelation relation() { return relation_; } |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3410 // the operand can change if a new idef of the phi is added between the phi | 3593 // the operand can change if a new idef of the phi is added between the phi |
3411 // and this instruction (inserting an idef updates every use). | 3594 // and this instruction (inserting an idef updates every use). |
3412 HPhi* phi_; | 3595 HPhi* phi_; |
3413 NumericRelation relation_; | 3596 NumericRelation relation_; |
3414 int operand_index_; | 3597 int operand_index_; |
3415 }; | 3598 }; |
3416 | 3599 |
3417 | 3600 |
3418 class HArgumentsObject: public HTemplateInstruction<0> { | 3601 class HArgumentsObject: public HTemplateInstruction<0> { |
3419 public: | 3602 public: |
3420 HArgumentsObject(int count, Zone* zone) : values_(count, zone) { | 3603 static HArgumentsObject* New(Zone* zone, |
3421 set_representation(Representation::Tagged()); | 3604 HValue* context, |
3422 SetFlag(kIsArguments); | 3605 int count) { |
| 3606 return new(zone) HArgumentsObject(count, zone); |
3423 } | 3607 } |
3424 | 3608 |
3425 const ZoneList<HValue*>* arguments_values() const { return &values_; } | 3609 const ZoneList<HValue*>* arguments_values() const { return &values_; } |
3426 int arguments_count() const { return values_.length(); } | 3610 int arguments_count() const { return values_.length(); } |
3427 | 3611 |
3428 void AddArgument(HValue* argument, Zone* zone) { | 3612 void AddArgument(HValue* argument, Zone* zone) { |
3429 values_.Add(NULL, zone); // Resize list. | 3613 values_.Add(NULL, zone); // Resize list. |
3430 SetOperandAt(values_.length() - 1, argument); | 3614 SetOperandAt(values_.length() - 1, argument); |
3431 } | 3615 } |
3432 | 3616 |
3433 virtual int OperandCount() { return values_.length(); } | 3617 virtual int OperandCount() { return values_.length(); } |
3434 virtual HValue* OperandAt(int index) const { return values_[index]; } | 3618 virtual HValue* OperandAt(int index) const { return values_[index]; } |
3435 | 3619 |
3436 virtual bool HasEscapingOperandAt(int index) { return false; } | 3620 virtual bool HasEscapingOperandAt(int index) { return false; } |
3437 virtual Representation RequiredInputRepresentation(int index) { | 3621 virtual Representation RequiredInputRepresentation(int index) { |
3438 return Representation::None(); | 3622 return Representation::None(); |
3439 } | 3623 } |
3440 | 3624 |
3441 DECLARE_CONCRETE_INSTRUCTION(ArgumentsObject) | 3625 DECLARE_CONCRETE_INSTRUCTION(ArgumentsObject) |
3442 | 3626 |
3443 protected: | 3627 protected: |
3444 virtual void InternalSetOperandAt(int index, HValue* value) { | 3628 virtual void InternalSetOperandAt(int index, HValue* value) { |
3445 values_[index] = value; | 3629 values_[index] = value; |
3446 } | 3630 } |
3447 | 3631 |
3448 private: | 3632 private: |
| 3633 HArgumentsObject(int count, Zone* zone) : values_(count, zone) { |
| 3634 set_representation(Representation::Tagged()); |
| 3635 SetFlag(kIsArguments); |
| 3636 } |
| 3637 |
3449 virtual bool IsDeletable() const { return true; } | 3638 virtual bool IsDeletable() const { return true; } |
3450 | 3639 |
3451 ZoneList<HValue*> values_; | 3640 ZoneList<HValue*> values_; |
3452 }; | 3641 }; |
3453 | 3642 |
3454 | 3643 |
3455 class HConstant: public HTemplateInstruction<0> { | 3644 class HConstant: public HTemplateInstruction<0> { |
3456 public: | 3645 public: |
3457 HConstant(Handle<Object> handle, Representation r = Representation::None()); | 3646 DECLARE_INSTRUCTION_FACTORY_P1(HConstant, int32_t); |
3458 HConstant(int32_t value, | 3647 DECLARE_INSTRUCTION_FACTORY_P2(HConstant, int32_t, Representation); |
3459 Representation r = Representation::None(), | 3648 DECLARE_INSTRUCTION_FACTORY_P1(HConstant, double); |
3460 bool is_not_in_new_space = true, | 3649 DECLARE_INSTRUCTION_FACTORY_P1(HConstant, Handle<Object>); |
3461 Handle<Object> optional_handle = Handle<Object>::null()); | 3650 DECLARE_INSTRUCTION_FACTORY_P1(HConstant, ExternalReference); |
3462 HConstant(double value, | |
3463 Representation r = Representation::None(), | |
3464 bool is_not_in_new_space = true, | |
3465 Handle<Object> optional_handle = Handle<Object>::null()); | |
3466 HConstant(Handle<Object> handle, | |
3467 UniqueValueId unique_id, | |
3468 Representation r, | |
3469 HType type, | |
3470 bool is_internalized_string, | |
3471 bool is_not_in_new_space, | |
3472 bool is_cell, | |
3473 bool boolean_value); | |
3474 | 3651 |
3475 Handle<Object> handle() { | 3652 Handle<Object> handle() { |
3476 if (handle_.is_null()) { | 3653 if (handle_.is_null()) { |
3477 Factory* factory = Isolate::Current()->factory(); | 3654 Factory* factory = Isolate::Current()->factory(); |
3478 // Default arguments to is_not_in_new_space depend on this heap number | 3655 // Default arguments to is_not_in_new_space depend on this heap number |
3479 // to be tenured so that it's guaranteed not be be located in new space. | 3656 // to be tenured so that it's guaranteed not be be located in new space. |
3480 handle_ = factory->NewNumber(double_value_, TENURED); | 3657 handle_ = factory->NewNumber(double_value_, TENURED); |
3481 } | 3658 } |
3482 AllowDeferredHandleDereference smi_check; | 3659 AllowDeferredHandleDereference smi_check; |
3483 ASSERT(has_int32_value_ || !handle_->IsSmi()); | 3660 ASSERT(has_int32_value_ || !handle_->IsSmi()); |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3528 } | 3705 } |
3529 | 3706 |
3530 virtual Representation RequiredInputRepresentation(int index) { | 3707 virtual Representation RequiredInputRepresentation(int index) { |
3531 return Representation::None(); | 3708 return Representation::None(); |
3532 } | 3709 } |
3533 | 3710 |
3534 virtual Representation KnownOptimalRepresentation() { | 3711 virtual Representation KnownOptimalRepresentation() { |
3535 if (HasSmiValue() && kSmiValueSize == 31) return Representation::Smi(); | 3712 if (HasSmiValue() && kSmiValueSize == 31) return Representation::Smi(); |
3536 if (HasInteger32Value()) return Representation::Integer32(); | 3713 if (HasInteger32Value()) return Representation::Integer32(); |
3537 if (HasNumberValue()) return Representation::Double(); | 3714 if (HasNumberValue()) return Representation::Double(); |
| 3715 if (HasExternalReferenceValue()) return Representation::External(); |
3538 return Representation::Tagged(); | 3716 return Representation::Tagged(); |
3539 } | 3717 } |
3540 | 3718 |
3541 virtual bool EmitAtUses(); | 3719 virtual bool EmitAtUses(); |
3542 virtual void PrintDataTo(StringStream* stream); | 3720 virtual void PrintDataTo(StringStream* stream); |
3543 virtual HType CalculateInferredType(); | |
3544 bool IsInteger() { return handle()->IsSmi(); } | 3721 bool IsInteger() { return handle()->IsSmi(); } |
3545 HConstant* CopyToRepresentation(Representation r, Zone* zone) const; | 3722 HConstant* CopyToRepresentation(Representation r, Zone* zone) const; |
3546 Maybe<HConstant*> CopyToTruncatedInt32(Zone* zone); | 3723 Maybe<HConstant*> CopyToTruncatedInt32(Zone* zone); |
3547 Maybe<HConstant*> CopyToTruncatedNumber(Zone* zone); | 3724 Maybe<HConstant*> CopyToTruncatedNumber(Zone* zone); |
3548 bool HasInteger32Value() const { return has_int32_value_; } | 3725 bool HasInteger32Value() const { return has_int32_value_; } |
3549 int32_t Integer32Value() const { | 3726 int32_t Integer32Value() const { |
3550 ASSERT(HasInteger32Value()); | 3727 ASSERT(HasInteger32Value()); |
3551 return int32_value_; | 3728 return int32_value_; |
3552 } | 3729 } |
3553 bool HasSmiValue() const { return has_smi_value_; } | 3730 bool HasSmiValue() const { return has_smi_value_; } |
(...skipping 16 matching lines...) Expand all Loading... |
3570 int32_t NumberValueAsInteger32() const { | 3747 int32_t NumberValueAsInteger32() const { |
3571 ASSERT(HasNumberValue()); | 3748 ASSERT(HasNumberValue()); |
3572 // Irrespective of whether a numeric HConstant can be safely | 3749 // Irrespective of whether a numeric HConstant can be safely |
3573 // represented as an int32, we store the (in some cases lossy) | 3750 // represented as an int32, we store the (in some cases lossy) |
3574 // representation of the number in int32_value_. | 3751 // representation of the number in int32_value_. |
3575 return int32_value_; | 3752 return int32_value_; |
3576 } | 3753 } |
3577 bool HasStringValue() const { | 3754 bool HasStringValue() const { |
3578 if (has_double_value_ || has_int32_value_) return false; | 3755 if (has_double_value_ || has_int32_value_) return false; |
3579 ASSERT(!handle_.is_null()); | 3756 ASSERT(!handle_.is_null()); |
3580 return type_from_value_.IsString(); | 3757 return type_.IsString(); |
3581 } | 3758 } |
3582 Handle<String> StringValue() const { | 3759 Handle<String> StringValue() const { |
3583 ASSERT(HasStringValue()); | 3760 ASSERT(HasStringValue()); |
3584 return Handle<String>::cast(handle_); | 3761 return Handle<String>::cast(handle_); |
3585 } | 3762 } |
3586 bool HasInternalizedStringValue() const { | 3763 bool HasInternalizedStringValue() const { |
3587 return HasStringValue() && is_internalized_string_; | 3764 return HasStringValue() && is_internalized_string_; |
3588 } | 3765 } |
3589 | 3766 |
| 3767 bool HasExternalReferenceValue() const { |
| 3768 return has_external_reference_value_; |
| 3769 } |
| 3770 ExternalReference ExternalReferenceValue() const { |
| 3771 return external_reference_value_; |
| 3772 } |
| 3773 |
3590 bool BooleanValue() const { return boolean_value_; } | 3774 bool BooleanValue() const { return boolean_value_; } |
3591 | 3775 |
3592 virtual intptr_t Hashcode() { | 3776 virtual intptr_t Hashcode() { |
3593 if (has_int32_value_) { | 3777 if (has_int32_value_) { |
3594 return static_cast<intptr_t>(int32_value_); | 3778 return static_cast<intptr_t>(int32_value_); |
3595 } else if (has_double_value_) { | 3779 } else if (has_double_value_) { |
3596 return static_cast<intptr_t>(BitCast<int64_t>(double_value_)); | 3780 return static_cast<intptr_t>(BitCast<int64_t>(double_value_)); |
| 3781 } else if (has_external_reference_value_) { |
| 3782 return reinterpret_cast<intptr_t>(external_reference_value_.address()); |
3597 } else { | 3783 } else { |
3598 ASSERT(!handle_.is_null()); | 3784 ASSERT(!handle_.is_null()); |
3599 return unique_id_.Hashcode(); | 3785 return unique_id_.Hashcode(); |
3600 } | 3786 } |
3601 } | 3787 } |
3602 | 3788 |
3603 virtual void FinalizeUniqueValueId() { | 3789 virtual void FinalizeUniqueValueId() { |
3604 if (!has_double_value_) { | 3790 if (!has_double_value_ && !has_external_reference_value_) { |
3605 ASSERT(!handle_.is_null()); | 3791 ASSERT(!handle_.is_null()); |
3606 unique_id_ = UniqueValueId(handle_); | 3792 unique_id_ = UniqueValueId(handle_); |
3607 } | 3793 } |
3608 } | 3794 } |
3609 | 3795 |
3610 bool UniqueValueIdsMatch(UniqueValueId other) { | 3796 bool UniqueValueIdsMatch(UniqueValueId other) { |
3611 return !has_double_value_ && unique_id_ == other; | 3797 return !has_double_value_ && !has_external_reference_value_ && |
| 3798 unique_id_ == other; |
3612 } | 3799 } |
3613 | 3800 |
3614 #ifdef DEBUG | 3801 #ifdef DEBUG |
3615 virtual void Verify() { } | 3802 virtual void Verify() { } |
3616 #endif | 3803 #endif |
3617 | 3804 |
3618 DECLARE_CONCRETE_INSTRUCTION(Constant) | 3805 DECLARE_CONCRETE_INSTRUCTION(Constant) |
3619 | 3806 |
3620 protected: | 3807 protected: |
3621 virtual Range* InferRange(Zone* zone); | 3808 virtual Range* InferRange(Zone* zone); |
3622 | 3809 |
3623 virtual bool DataEquals(HValue* other) { | 3810 virtual bool DataEquals(HValue* other) { |
3624 HConstant* other_constant = HConstant::cast(other); | 3811 HConstant* other_constant = HConstant::cast(other); |
3625 if (has_int32_value_) { | 3812 if (has_int32_value_) { |
3626 return other_constant->has_int32_value_ && | 3813 return other_constant->has_int32_value_ && |
3627 int32_value_ == other_constant->int32_value_; | 3814 int32_value_ == other_constant->int32_value_; |
3628 } else if (has_double_value_) { | 3815 } else if (has_double_value_) { |
3629 return other_constant->has_double_value_ && | 3816 return other_constant->has_double_value_ && |
3630 BitCast<int64_t>(double_value_) == | 3817 BitCast<int64_t>(double_value_) == |
3631 BitCast<int64_t>(other_constant->double_value_); | 3818 BitCast<int64_t>(other_constant->double_value_); |
| 3819 } else if (has_external_reference_value_) { |
| 3820 return other_constant->has_external_reference_value_ && |
| 3821 external_reference_value_ == |
| 3822 other_constant->external_reference_value_; |
3632 } else { | 3823 } else { |
3633 ASSERT(!handle_.is_null()); | 3824 ASSERT(!handle_.is_null()); |
3634 return !other_constant->handle_.is_null() && | 3825 return !other_constant->handle_.is_null() && |
3635 unique_id_ == other_constant->unique_id_; | 3826 unique_id_ == other_constant->unique_id_; |
3636 } | 3827 } |
3637 } | 3828 } |
3638 | 3829 |
3639 private: | 3830 private: |
| 3831 friend class HGraph; |
| 3832 HConstant(Handle<Object> handle, Representation r = Representation::None()); |
| 3833 HConstant(int32_t value, |
| 3834 Representation r = Representation::None(), |
| 3835 bool is_not_in_new_space = true, |
| 3836 Handle<Object> optional_handle = Handle<Object>::null()); |
| 3837 HConstant(double value, |
| 3838 Representation r = Representation::None(), |
| 3839 bool is_not_in_new_space = true, |
| 3840 Handle<Object> optional_handle = Handle<Object>::null()); |
| 3841 HConstant(Handle<Object> handle, |
| 3842 UniqueValueId unique_id, |
| 3843 Representation r, |
| 3844 HType type, |
| 3845 bool is_internalized_string, |
| 3846 bool is_not_in_new_space, |
| 3847 bool is_cell, |
| 3848 bool boolean_value); |
| 3849 explicit HConstant(ExternalReference reference); |
| 3850 |
3640 void Initialize(Representation r); | 3851 void Initialize(Representation r); |
3641 | 3852 |
3642 virtual bool IsDeletable() const { return true; } | 3853 virtual bool IsDeletable() const { return true; } |
3643 | 3854 |
3644 // If this is a numerical constant, handle_ either points to to the | 3855 // If this is a numerical constant, handle_ either points to to the |
3645 // HeapObject the constant originated from or is null. If the | 3856 // HeapObject the constant originated from or is null. If the |
3646 // constant is non-numeric, handle_ always points to a valid | 3857 // constant is non-numeric, handle_ always points to a valid |
3647 // constant HeapObject. | 3858 // constant HeapObject. |
3648 Handle<Object> handle_; | 3859 Handle<Object> handle_; |
3649 UniqueValueId unique_id_; | 3860 UniqueValueId unique_id_; |
3650 | 3861 |
3651 // We store the HConstant in the most specific form safely possible. | 3862 // We store the HConstant in the most specific form safely possible. |
3652 // The two flags, has_int32_value_ and has_double_value_ tell us if | 3863 // The two flags, has_int32_value_ and has_double_value_ tell us if |
3653 // int32_value_ and double_value_ hold valid, safe representations | 3864 // int32_value_ and double_value_ hold valid, safe representations |
3654 // of the constant. has_int32_value_ implies has_double_value_ but | 3865 // of the constant. has_int32_value_ implies has_double_value_ but |
3655 // not the converse. | 3866 // not the converse. |
3656 bool has_smi_value_ : 1; | 3867 bool has_smi_value_ : 1; |
3657 bool has_int32_value_ : 1; | 3868 bool has_int32_value_ : 1; |
3658 bool has_double_value_ : 1; | 3869 bool has_double_value_ : 1; |
| 3870 bool has_external_reference_value_ : 1; |
3659 bool is_internalized_string_ : 1; // TODO(yangguo): make this part of HType. | 3871 bool is_internalized_string_ : 1; // TODO(yangguo): make this part of HType. |
3660 bool is_not_in_new_space_ : 1; | 3872 bool is_not_in_new_space_ : 1; |
3661 bool is_cell_ : 1; | 3873 bool is_cell_ : 1; |
3662 bool boolean_value_ : 1; | 3874 bool boolean_value_ : 1; |
3663 int32_t int32_value_; | 3875 int32_t int32_value_; |
3664 double double_value_; | 3876 double double_value_; |
3665 HType type_from_value_; | 3877 ExternalReference external_reference_value_; |
3666 }; | 3878 }; |
3667 | 3879 |
3668 | 3880 |
3669 class HBinaryOperation: public HTemplateInstruction<3> { | 3881 class HBinaryOperation: public HTemplateInstruction<3> { |
3670 public: | 3882 public: |
3671 HBinaryOperation(HValue* context, HValue* left, HValue* right) | 3883 HBinaryOperation(HValue* context, HValue* left, HValue* right, |
3672 : observed_output_representation_(Representation::None()) { | 3884 HType type = HType::Tagged()) |
| 3885 : HTemplateInstruction<3>(type), |
| 3886 observed_output_representation_(Representation::None()) { |
3673 ASSERT(left != NULL && right != NULL); | 3887 ASSERT(left != NULL && right != NULL); |
3674 SetOperandAt(0, context); | 3888 SetOperandAt(0, context); |
3675 SetOperandAt(1, left); | 3889 SetOperandAt(1, left); |
3676 SetOperandAt(2, right); | 3890 SetOperandAt(2, right); |
3677 observed_input_representation_[0] = Representation::None(); | 3891 observed_input_representation_[0] = Representation::None(); |
3678 observed_input_representation_[1] = Representation::None(); | 3892 observed_input_representation_[1] = Representation::None(); |
3679 } | 3893 } |
3680 | 3894 |
3681 HValue* context() { return OperandAt(0); } | 3895 HValue* context() const { return OperandAt(0); } |
3682 HValue* left() { return OperandAt(1); } | 3896 HValue* left() const { return OperandAt(1); } |
3683 HValue* right() { return OperandAt(2); } | 3897 HValue* right() const { return OperandAt(2); } |
3684 | 3898 |
3685 // True if switching left and right operands likely generates better code. | 3899 // True if switching left and right operands likely generates better code. |
3686 bool AreOperandsBetterSwitched() { | 3900 bool AreOperandsBetterSwitched() { |
3687 if (!IsCommutative()) return false; | 3901 if (!IsCommutative()) return false; |
3688 | 3902 |
3689 // Constant operands are better off on the right, they can be inlined in | 3903 // Constant operands are better off on the right, they can be inlined in |
3690 // many situations on most platforms. | 3904 // many situations on most platforms. |
3691 if (left()->IsConstant()) return true; | 3905 if (left()->IsConstant()) return true; |
3692 if (right()->IsConstant()) return false; | 3906 if (right()->IsConstant()) return false; |
3693 | 3907 |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3746 private: | 3960 private: |
3747 bool IgnoreObservedOutputRepresentation(Representation current_rep); | 3961 bool IgnoreObservedOutputRepresentation(Representation current_rep); |
3748 | 3962 |
3749 Representation observed_input_representation_[2]; | 3963 Representation observed_input_representation_[2]; |
3750 Representation observed_output_representation_; | 3964 Representation observed_output_representation_; |
3751 }; | 3965 }; |
3752 | 3966 |
3753 | 3967 |
3754 class HWrapReceiver: public HTemplateInstruction<2> { | 3968 class HWrapReceiver: public HTemplateInstruction<2> { |
3755 public: | 3969 public: |
3756 HWrapReceiver(HValue* receiver, HValue* function) { | 3970 DECLARE_INSTRUCTION_FACTORY_P2(HWrapReceiver, HValue*, HValue*); |
3757 set_representation(Representation::Tagged()); | |
3758 SetOperandAt(0, receiver); | |
3759 SetOperandAt(1, function); | |
3760 } | |
3761 | 3971 |
3762 virtual Representation RequiredInputRepresentation(int index) { | 3972 virtual Representation RequiredInputRepresentation(int index) { |
3763 return Representation::Tagged(); | 3973 return Representation::Tagged(); |
3764 } | 3974 } |
3765 | 3975 |
3766 HValue* receiver() { return OperandAt(0); } | 3976 HValue* receiver() { return OperandAt(0); } |
3767 HValue* function() { return OperandAt(1); } | 3977 HValue* function() { return OperandAt(1); } |
3768 | 3978 |
3769 virtual HValue* Canonicalize(); | 3979 virtual HValue* Canonicalize(); |
3770 | 3980 |
3771 virtual void PrintDataTo(StringStream* stream); | 3981 virtual void PrintDataTo(StringStream* stream); |
3772 | 3982 |
3773 DECLARE_CONCRETE_INSTRUCTION(WrapReceiver) | 3983 DECLARE_CONCRETE_INSTRUCTION(WrapReceiver) |
| 3984 |
| 3985 private: |
| 3986 HWrapReceiver(HValue* receiver, HValue* function) { |
| 3987 set_representation(Representation::Tagged()); |
| 3988 SetOperandAt(0, receiver); |
| 3989 SetOperandAt(1, function); |
| 3990 } |
3774 }; | 3991 }; |
3775 | 3992 |
3776 | 3993 |
3777 class HApplyArguments: public HTemplateInstruction<4> { | 3994 class HApplyArguments: public HTemplateInstruction<4> { |
3778 public: | 3995 public: |
3779 HApplyArguments(HValue* function, | 3996 HApplyArguments(HValue* function, |
3780 HValue* receiver, | 3997 HValue* receiver, |
3781 HValue* length, | 3998 HValue* length, |
3782 HValue* elements) { | 3999 HValue* elements) { |
3783 set_representation(Representation::Tagged()); | 4000 set_representation(Representation::Tagged()); |
(...skipping 15 matching lines...) Expand all Loading... |
3799 HValue* receiver() { return OperandAt(1); } | 4016 HValue* receiver() { return OperandAt(1); } |
3800 HValue* length() { return OperandAt(2); } | 4017 HValue* length() { return OperandAt(2); } |
3801 HValue* elements() { return OperandAt(3); } | 4018 HValue* elements() { return OperandAt(3); } |
3802 | 4019 |
3803 DECLARE_CONCRETE_INSTRUCTION(ApplyArguments) | 4020 DECLARE_CONCRETE_INSTRUCTION(ApplyArguments) |
3804 }; | 4021 }; |
3805 | 4022 |
3806 | 4023 |
3807 class HArgumentsElements: public HTemplateInstruction<0> { | 4024 class HArgumentsElements: public HTemplateInstruction<0> { |
3808 public: | 4025 public: |
3809 explicit HArgumentsElements(bool from_inlined) : from_inlined_(from_inlined) { | 4026 DECLARE_INSTRUCTION_FACTORY_P1(HArgumentsElements, bool); |
3810 // The value produced by this instruction is a pointer into the stack | |
3811 // that looks as if it was a smi because of alignment. | |
3812 set_representation(Representation::Tagged()); | |
3813 SetFlag(kUseGVN); | |
3814 } | |
3815 | 4027 |
3816 DECLARE_CONCRETE_INSTRUCTION(ArgumentsElements) | 4028 DECLARE_CONCRETE_INSTRUCTION(ArgumentsElements) |
3817 | 4029 |
3818 virtual Representation RequiredInputRepresentation(int index) { | 4030 virtual Representation RequiredInputRepresentation(int index) { |
3819 return Representation::None(); | 4031 return Representation::None(); |
3820 } | 4032 } |
3821 | 4033 |
3822 bool from_inlined() const { return from_inlined_; } | 4034 bool from_inlined() const { return from_inlined_; } |
3823 | 4035 |
3824 protected: | 4036 protected: |
3825 virtual bool DataEquals(HValue* other) { return true; } | 4037 virtual bool DataEquals(HValue* other) { return true; } |
3826 | 4038 |
3827 private: | 4039 private: |
| 4040 explicit HArgumentsElements(bool from_inlined) : from_inlined_(from_inlined) { |
| 4041 // The value produced by this instruction is a pointer into the stack |
| 4042 // that looks as if it was a smi because of alignment. |
| 4043 set_representation(Representation::Tagged()); |
| 4044 SetFlag(kUseGVN); |
| 4045 } |
| 4046 |
3828 virtual bool IsDeletable() const { return true; } | 4047 virtual bool IsDeletable() const { return true; } |
3829 | 4048 |
3830 bool from_inlined_; | 4049 bool from_inlined_; |
3831 }; | 4050 }; |
3832 | 4051 |
3833 | 4052 |
3834 class HArgumentsLength: public HUnaryOperation { | 4053 class HArgumentsLength: public HUnaryOperation { |
3835 public: | 4054 public: |
3836 explicit HArgumentsLength(HValue* value) : HUnaryOperation(value) { | 4055 DECLARE_INSTRUCTION_FACTORY_P1(HArgumentsLength, HValue*); |
3837 set_representation(Representation::Integer32()); | |
3838 SetFlag(kUseGVN); | |
3839 } | |
3840 | 4056 |
3841 virtual Representation RequiredInputRepresentation(int index) { | 4057 virtual Representation RequiredInputRepresentation(int index) { |
3842 return Representation::Tagged(); | 4058 return Representation::Tagged(); |
3843 } | 4059 } |
3844 | 4060 |
3845 DECLARE_CONCRETE_INSTRUCTION(ArgumentsLength) | 4061 DECLARE_CONCRETE_INSTRUCTION(ArgumentsLength) |
3846 | 4062 |
3847 protected: | 4063 protected: |
3848 virtual bool DataEquals(HValue* other) { return true; } | 4064 virtual bool DataEquals(HValue* other) { return true; } |
3849 | 4065 |
3850 private: | 4066 private: |
| 4067 explicit HArgumentsLength(HValue* value) : HUnaryOperation(value) { |
| 4068 set_representation(Representation::Integer32()); |
| 4069 SetFlag(kUseGVN); |
| 4070 } |
| 4071 |
3851 virtual bool IsDeletable() const { return true; } | 4072 virtual bool IsDeletable() const { return true; } |
3852 }; | 4073 }; |
3853 | 4074 |
3854 | 4075 |
3855 class HAccessArgumentsAt: public HTemplateInstruction<3> { | 4076 class HAccessArgumentsAt: public HTemplateInstruction<3> { |
3856 public: | 4077 public: |
3857 HAccessArgumentsAt(HValue* arguments, HValue* length, HValue* index) { | 4078 HAccessArgumentsAt(HValue* arguments, HValue* length, HValue* index) { |
3858 set_representation(Representation::Tagged()); | 4079 set_representation(Representation::Tagged()); |
3859 SetFlag(kUseGVN); | 4080 SetFlag(kUseGVN); |
3860 SetOperandAt(0, arguments); | 4081 SetOperandAt(0, arguments); |
(...skipping 18 matching lines...) Expand all Loading... |
3879 | 4100 |
3880 virtual bool DataEquals(HValue* other) { return true; } | 4101 virtual bool DataEquals(HValue* other) { return true; } |
3881 }; | 4102 }; |
3882 | 4103 |
3883 | 4104 |
3884 class HBoundsCheckBaseIndexInformation; | 4105 class HBoundsCheckBaseIndexInformation; |
3885 | 4106 |
3886 | 4107 |
3887 class HBoundsCheck: public HTemplateInstruction<2> { | 4108 class HBoundsCheck: public HTemplateInstruction<2> { |
3888 public: | 4109 public: |
3889 // Normally HBoundsCheck should be created using the | 4110 DECLARE_INSTRUCTION_FACTORY_P2(HBoundsCheck, HValue*, HValue*); |
3890 // HGraphBuilder::AddBoundsCheck() helper. | |
3891 // However when building stubs, where we know that the arguments are Int32, | |
3892 // it makes sense to invoke this constructor directly. | |
3893 HBoundsCheck(HValue* index, HValue* length) | |
3894 : skip_check_(false), | |
3895 base_(NULL), offset_(0), scale_(0), | |
3896 responsibility_direction_(DIRECTION_NONE), | |
3897 allow_equality_(false) { | |
3898 SetOperandAt(0, index); | |
3899 SetOperandAt(1, length); | |
3900 SetFlag(kFlexibleRepresentation); | |
3901 SetFlag(kUseGVN); | |
3902 } | |
3903 | 4111 |
3904 bool skip_check() const { return skip_check_; } | 4112 bool skip_check() const { return skip_check_; } |
3905 void set_skip_check() { skip_check_ = true; } | 4113 void set_skip_check() { skip_check_ = true; } |
| 4114 |
3906 HValue* base() { return base_; } | 4115 HValue* base() { return base_; } |
3907 int offset() { return offset_; } | 4116 int offset() { return offset_; } |
3908 int scale() { return scale_; } | 4117 int scale() { return scale_; } |
3909 bool index_can_increase() { | 4118 bool index_can_increase() { |
3910 return (responsibility_direction_ & DIRECTION_LOWER) == 0; | 4119 return (responsibility_direction_ & DIRECTION_LOWER) == 0; |
3911 } | 4120 } |
3912 bool index_can_decrease() { | 4121 bool index_can_decrease() { |
3913 return (responsibility_direction_ & DIRECTION_UPPER) == 0; | 4122 return (responsibility_direction_ & DIRECTION_UPPER) == 0; |
3914 } | 4123 } |
3915 | 4124 |
(...skipping 11 matching lines...) Expand all Loading... |
3927 base_ = index(); | 4136 base_ = index(); |
3928 offset_ = 0; | 4137 offset_ = 0; |
3929 scale_ = 0; | 4138 scale_ = 0; |
3930 return false; | 4139 return false; |
3931 } | 4140 } |
3932 } | 4141 } |
3933 | 4142 |
3934 virtual Representation RequiredInputRepresentation(int arg_index) { | 4143 virtual Representation RequiredInputRepresentation(int arg_index) { |
3935 return representation(); | 4144 return representation(); |
3936 } | 4145 } |
3937 virtual bool IsDeletable() const { | |
3938 return skip_check() && !FLAG_debug_code; | |
3939 } | |
3940 | 4146 |
3941 virtual bool IsRelationTrueInternal(NumericRelation relation, | 4147 virtual bool IsRelationTrueInternal(NumericRelation relation, |
3942 HValue* related_value, | 4148 HValue* related_value, |
3943 int offset = 0, | 4149 int offset = 0, |
3944 int scale = 0); | 4150 int scale = 0); |
3945 | 4151 |
3946 virtual void PrintDataTo(StringStream* stream); | 4152 virtual void PrintDataTo(StringStream* stream); |
3947 virtual void InferRepresentation(HInferRepresentationPhase* h_infer); | 4153 virtual void InferRepresentation(HInferRepresentationPhase* h_infer); |
3948 | 4154 |
3949 HValue* index() { return OperandAt(0); } | 4155 HValue* index() { return OperandAt(0); } |
(...skipping 16 matching lines...) Expand all Loading... |
3966 } | 4172 } |
3967 | 4173 |
3968 virtual bool DataEquals(HValue* other) { return true; } | 4174 virtual bool DataEquals(HValue* other) { return true; } |
3969 virtual void TryGuaranteeRangeChanging(RangeEvaluationContext* context); | 4175 virtual void TryGuaranteeRangeChanging(RangeEvaluationContext* context); |
3970 bool skip_check_; | 4176 bool skip_check_; |
3971 HValue* base_; | 4177 HValue* base_; |
3972 int offset_; | 4178 int offset_; |
3973 int scale_; | 4179 int scale_; |
3974 RangeGuaranteeDirection responsibility_direction_; | 4180 RangeGuaranteeDirection responsibility_direction_; |
3975 bool allow_equality_; | 4181 bool allow_equality_; |
| 4182 |
| 4183 private: |
| 4184 // Normally HBoundsCheck should be created using the |
| 4185 // HGraphBuilder::AddBoundsCheck() helper. |
| 4186 // However when building stubs, where we know that the arguments are Int32, |
| 4187 // it makes sense to invoke this constructor directly. |
| 4188 HBoundsCheck(HValue* index, HValue* length) |
| 4189 : skip_check_(false), |
| 4190 base_(NULL), offset_(0), scale_(0), |
| 4191 responsibility_direction_(DIRECTION_NONE), |
| 4192 allow_equality_(false) { |
| 4193 SetOperandAt(0, index); |
| 4194 SetOperandAt(1, length); |
| 4195 SetFlag(kFlexibleRepresentation); |
| 4196 SetFlag(kUseGVN); |
| 4197 } |
| 4198 |
| 4199 virtual bool IsDeletable() const { |
| 4200 return skip_check() && !FLAG_debug_code; |
| 4201 } |
3976 }; | 4202 }; |
3977 | 4203 |
3978 | 4204 |
3979 class HBoundsCheckBaseIndexInformation: public HTemplateInstruction<2> { | 4205 class HBoundsCheckBaseIndexInformation: public HTemplateInstruction<2> { |
3980 public: | 4206 public: |
3981 explicit HBoundsCheckBaseIndexInformation(HBoundsCheck* check) { | 4207 explicit HBoundsCheckBaseIndexInformation(HBoundsCheck* check) { |
3982 DecompositionResult decomposition; | 4208 DecompositionResult decomposition; |
3983 if (check->index()->TryDecompose(&decomposition)) { | 4209 if (check->index()->TryDecompose(&decomposition)) { |
3984 SetOperandAt(0, decomposition.base()); | 4210 SetOperandAt(0, decomposition.base()); |
3985 SetOperandAt(1, check); | 4211 SetOperandAt(1, check); |
(...skipping 25 matching lines...) Expand all Loading... |
4011 bounds_check()->SetResponsibilityForRange(direction); | 4237 bounds_check()->SetResponsibilityForRange(direction); |
4012 } | 4238 } |
4013 virtual void TryGuaranteeRangeChanging(RangeEvaluationContext* context) { | 4239 virtual void TryGuaranteeRangeChanging(RangeEvaluationContext* context) { |
4014 bounds_check()->TryGuaranteeRangeChanging(context); | 4240 bounds_check()->TryGuaranteeRangeChanging(context); |
4015 } | 4241 } |
4016 }; | 4242 }; |
4017 | 4243 |
4018 | 4244 |
4019 class HBitwiseBinaryOperation: public HBinaryOperation { | 4245 class HBitwiseBinaryOperation: public HBinaryOperation { |
4020 public: | 4246 public: |
4021 HBitwiseBinaryOperation(HValue* context, HValue* left, HValue* right) | 4247 HBitwiseBinaryOperation(HValue* context, HValue* left, HValue* right, |
4022 : HBinaryOperation(context, left, right) { | 4248 HType type = HType::Tagged()) |
| 4249 : HBinaryOperation(context, left, right, type) { |
4023 SetFlag(kFlexibleRepresentation); | 4250 SetFlag(kFlexibleRepresentation); |
4024 SetFlag(kTruncatingToInt32); | 4251 SetFlag(kTruncatingToInt32); |
4025 SetFlag(kAllowUndefinedAsNaN); | 4252 SetFlag(kAllowUndefinedAsNaN); |
4026 SetAllSideEffects(); | 4253 SetAllSideEffects(); |
4027 } | 4254 } |
4028 | 4255 |
4029 virtual void RepresentationChanged(Representation to) { | 4256 virtual void RepresentationChanged(Representation to) { |
4030 if (!to.IsTagged()) { | 4257 if (!to.IsTagged()) { |
4031 ASSERT(to.IsSmiOrInteger32()); | 4258 ASSERT(to.IsSmiOrInteger32()); |
4032 ClearAllSideEffects(); | 4259 ClearAllSideEffects(); |
(...skipping 16 matching lines...) Expand all Loading... |
4049 Representation r = HBinaryOperation::observed_input_representation(index); | 4276 Representation r = HBinaryOperation::observed_input_representation(index); |
4050 if (r.IsDouble()) return Representation::Integer32(); | 4277 if (r.IsDouble()) return Representation::Integer32(); |
4051 return r; | 4278 return r; |
4052 } | 4279 } |
4053 | 4280 |
4054 virtual void initialize_output_representation(Representation observed) { | 4281 virtual void initialize_output_representation(Representation observed) { |
4055 if (observed.IsDouble()) observed = Representation::Integer32(); | 4282 if (observed.IsDouble()) observed = Representation::Integer32(); |
4056 HBinaryOperation::initialize_output_representation(observed); | 4283 HBinaryOperation::initialize_output_representation(observed); |
4057 } | 4284 } |
4058 | 4285 |
4059 virtual HType CalculateInferredType(); | |
4060 | |
4061 DECLARE_ABSTRACT_INSTRUCTION(BitwiseBinaryOperation) | 4286 DECLARE_ABSTRACT_INSTRUCTION(BitwiseBinaryOperation) |
4062 | 4287 |
4063 private: | 4288 private: |
4064 virtual bool IsDeletable() const { return true; } | 4289 virtual bool IsDeletable() const { return true; } |
4065 }; | 4290 }; |
4066 | 4291 |
4067 | 4292 |
4068 class HMathFloorOfDiv: public HBinaryOperation { | 4293 class HMathFloorOfDiv: public HBinaryOperation { |
4069 public: | 4294 public: |
4070 HMathFloorOfDiv(HValue* context, HValue* left, HValue* right) | 4295 static HMathFloorOfDiv* New(Zone* zone, |
4071 : HBinaryOperation(context, left, right) { | 4296 HValue* context, |
4072 set_representation(Representation::Integer32()); | 4297 HValue* left, |
4073 SetFlag(kUseGVN); | 4298 HValue* right) { |
4074 SetFlag(kCanOverflow); | 4299 return new(zone) HMathFloorOfDiv(context, left, right); |
4075 if (!right->IsConstant()) { | |
4076 SetFlag(kCanBeDivByZero); | |
4077 } | |
4078 SetFlag(kAllowUndefinedAsNaN); | |
4079 } | 4300 } |
4080 | 4301 |
4081 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited); | 4302 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited); |
4082 | 4303 |
4083 virtual Representation RequiredInputRepresentation(int index) { | 4304 virtual Representation RequiredInputRepresentation(int index) { |
4084 return Representation::Integer32(); | 4305 return Representation::Integer32(); |
4085 } | 4306 } |
4086 | 4307 |
4087 DECLARE_CONCRETE_INSTRUCTION(MathFloorOfDiv) | 4308 DECLARE_CONCRETE_INSTRUCTION(MathFloorOfDiv) |
4088 | 4309 |
4089 protected: | 4310 protected: |
4090 virtual bool DataEquals(HValue* other) { return true; } | 4311 virtual bool DataEquals(HValue* other) { return true; } |
4091 | 4312 |
4092 private: | 4313 private: |
| 4314 HMathFloorOfDiv(HValue* context, HValue* left, HValue* right) |
| 4315 : HBinaryOperation(context, left, right) { |
| 4316 set_representation(Representation::Integer32()); |
| 4317 SetFlag(kUseGVN); |
| 4318 SetFlag(kCanOverflow); |
| 4319 if (!right->IsConstant()) { |
| 4320 SetFlag(kCanBeDivByZero); |
| 4321 } |
| 4322 SetFlag(kAllowUndefinedAsNaN); |
| 4323 } |
| 4324 |
4093 virtual bool IsDeletable() const { return true; } | 4325 virtual bool IsDeletable() const { return true; } |
4094 }; | 4326 }; |
4095 | 4327 |
4096 | 4328 |
4097 class HArithmeticBinaryOperation: public HBinaryOperation { | 4329 class HArithmeticBinaryOperation: public HBinaryOperation { |
4098 public: | 4330 public: |
4099 HArithmeticBinaryOperation(HValue* context, HValue* left, HValue* right) | 4331 HArithmeticBinaryOperation(HValue* context, HValue* left, HValue* right) |
4100 : HBinaryOperation(context, left, right) { | 4332 : HBinaryOperation(context, left, right, HType::TaggedNumber()) { |
4101 SetAllSideEffects(); | 4333 SetAllSideEffects(); |
4102 SetFlag(kFlexibleRepresentation); | 4334 SetFlag(kFlexibleRepresentation); |
4103 SetFlag(kAllowUndefinedAsNaN); | 4335 SetFlag(kAllowUndefinedAsNaN); |
4104 } | 4336 } |
4105 | 4337 |
4106 virtual void RepresentationChanged(Representation to) { | 4338 virtual void RepresentationChanged(Representation to) { |
4107 if (to.IsTagged()) { | 4339 if (to.IsTagged()) { |
4108 SetAllSideEffects(); | 4340 SetAllSideEffects(); |
4109 ClearFlag(kUseGVN); | 4341 ClearFlag(kUseGVN); |
4110 } else { | 4342 } else { |
4111 ClearAllSideEffects(); | 4343 ClearAllSideEffects(); |
4112 SetFlag(kUseGVN); | 4344 SetFlag(kUseGVN); |
4113 } | 4345 } |
4114 } | 4346 } |
4115 | 4347 |
4116 virtual HType CalculateInferredType(); | |
4117 | |
4118 DECLARE_ABSTRACT_INSTRUCTION(ArithmeticBinaryOperation) | 4348 DECLARE_ABSTRACT_INSTRUCTION(ArithmeticBinaryOperation) |
4119 | 4349 |
4120 private: | 4350 private: |
4121 virtual bool IsDeletable() const { return true; } | 4351 virtual bool IsDeletable() const { return true; } |
4122 }; | 4352 }; |
4123 | 4353 |
4124 | 4354 |
4125 class HCompareGeneric: public HBinaryOperation { | 4355 class HCompareGeneric: public HBinaryOperation { |
4126 public: | 4356 public: |
4127 HCompareGeneric(HValue* context, | 4357 HCompareGeneric(HValue* context, |
4128 HValue* left, | 4358 HValue* left, |
4129 HValue* right, | 4359 HValue* right, |
4130 Token::Value token) | 4360 Token::Value token) |
4131 : HBinaryOperation(context, left, right), token_(token) { | 4361 : HBinaryOperation(context, left, right, HType::Boolean()), |
| 4362 token_(token) { |
4132 ASSERT(Token::IsCompareOp(token)); | 4363 ASSERT(Token::IsCompareOp(token)); |
4133 set_representation(Representation::Tagged()); | 4364 set_representation(Representation::Tagged()); |
4134 SetAllSideEffects(); | 4365 SetAllSideEffects(); |
4135 } | 4366 } |
4136 | 4367 |
4137 virtual Representation RequiredInputRepresentation(int index) { | 4368 virtual Representation RequiredInputRepresentation(int index) { |
4138 return index == 0 | 4369 return index == 0 |
4139 ? Representation::Tagged() | 4370 ? Representation::Tagged() |
4140 : representation(); | 4371 : representation(); |
4141 } | 4372 } |
4142 | 4373 |
4143 Token::Value token() const { return token_; } | 4374 Token::Value token() const { return token_; } |
4144 virtual void PrintDataTo(StringStream* stream); | 4375 virtual void PrintDataTo(StringStream* stream); |
4145 | 4376 |
4146 virtual HType CalculateInferredType(); | |
4147 | |
4148 DECLARE_CONCRETE_INSTRUCTION(CompareGeneric) | 4377 DECLARE_CONCRETE_INSTRUCTION(CompareGeneric) |
4149 | 4378 |
4150 private: | 4379 private: |
4151 Token::Value token_; | 4380 Token::Value token_; |
4152 }; | 4381 }; |
4153 | 4382 |
4154 | 4383 |
4155 class HCompareNumericAndBranch: public HTemplateControlInstruction<2, 2> { | 4384 class HCompareNumericAndBranch: public HTemplateControlInstruction<2, 2> { |
4156 public: | 4385 public: |
4157 HCompareNumericAndBranch(HValue* left, HValue* right, Token::Value token) | 4386 HCompareNumericAndBranch(HValue* left, HValue* right, Token::Value token) |
(...skipping 29 matching lines...) Expand all Loading... |
4187 DECLARE_CONCRETE_INSTRUCTION(CompareNumericAndBranch) | 4416 DECLARE_CONCRETE_INSTRUCTION(CompareNumericAndBranch) |
4188 | 4417 |
4189 private: | 4418 private: |
4190 Representation observed_input_representation_[2]; | 4419 Representation observed_input_representation_[2]; |
4191 Token::Value token_; | 4420 Token::Value token_; |
4192 }; | 4421 }; |
4193 | 4422 |
4194 | 4423 |
4195 class HCompareObjectEqAndBranch: public HTemplateControlInstruction<2, 2> { | 4424 class HCompareObjectEqAndBranch: public HTemplateControlInstruction<2, 2> { |
4196 public: | 4425 public: |
4197 HCompareObjectEqAndBranch(HValue* left, HValue* right) { | 4426 // TODO(danno): make this private when the IfBuilder properly constructs |
| 4427 // control flow instructions. |
| 4428 HCompareObjectEqAndBranch(HValue* left, |
| 4429 HValue* right) { |
4198 SetOperandAt(0, left); | 4430 SetOperandAt(0, left); |
4199 SetOperandAt(1, right); | 4431 SetOperandAt(1, right); |
4200 } | 4432 } |
4201 | 4433 |
| 4434 DECLARE_INSTRUCTION_FACTORY_P2(HCompareObjectEqAndBranch, HValue*, HValue*); |
| 4435 |
4202 HValue* left() { return OperandAt(0); } | 4436 HValue* left() { return OperandAt(0); } |
4203 HValue* right() { return OperandAt(1); } | 4437 HValue* right() { return OperandAt(1); } |
4204 | 4438 |
4205 virtual void PrintDataTo(StringStream* stream); | 4439 virtual void PrintDataTo(StringStream* stream); |
4206 | 4440 |
4207 virtual Representation RequiredInputRepresentation(int index) { | 4441 virtual Representation RequiredInputRepresentation(int index) { |
4208 return Representation::Tagged(); | 4442 return Representation::Tagged(); |
4209 } | 4443 } |
4210 | 4444 |
4211 virtual Representation observed_input_representation(int index) { | 4445 virtual Representation observed_input_representation(int index) { |
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4413 } | 4647 } |
4414 | 4648 |
4415 private: | 4649 private: |
4416 Handle<String> type_literal_; | 4650 Handle<String> type_literal_; |
4417 }; | 4651 }; |
4418 | 4652 |
4419 | 4653 |
4420 class HInstanceOf: public HBinaryOperation { | 4654 class HInstanceOf: public HBinaryOperation { |
4421 public: | 4655 public: |
4422 HInstanceOf(HValue* context, HValue* left, HValue* right) | 4656 HInstanceOf(HValue* context, HValue* left, HValue* right) |
4423 : HBinaryOperation(context, left, right) { | 4657 : HBinaryOperation(context, left, right, HType::Boolean()) { |
4424 set_representation(Representation::Tagged()); | 4658 set_representation(Representation::Tagged()); |
4425 SetAllSideEffects(); | 4659 SetAllSideEffects(); |
4426 } | 4660 } |
4427 | 4661 |
4428 virtual Representation RequiredInputRepresentation(int index) { | 4662 virtual Representation RequiredInputRepresentation(int index) { |
4429 return Representation::Tagged(); | 4663 return Representation::Tagged(); |
4430 } | 4664 } |
4431 | 4665 |
4432 virtual HType CalculateInferredType(); | |
4433 | |
4434 virtual void PrintDataTo(StringStream* stream); | 4666 virtual void PrintDataTo(StringStream* stream); |
4435 | 4667 |
4436 DECLARE_CONCRETE_INSTRUCTION(InstanceOf) | 4668 DECLARE_CONCRETE_INSTRUCTION(InstanceOf) |
4437 }; | 4669 }; |
4438 | 4670 |
4439 | 4671 |
4440 class HInstanceOfKnownGlobal: public HTemplateInstruction<2> { | 4672 class HInstanceOfKnownGlobal: public HTemplateInstruction<2> { |
4441 public: | 4673 public: |
4442 HInstanceOfKnownGlobal(HValue* context, | 4674 HInstanceOfKnownGlobal(HValue* context, |
4443 HValue* left, | 4675 HValue* left, |
4444 Handle<JSFunction> right) | 4676 Handle<JSFunction> right) |
4445 : function_(right) { | 4677 : HTemplateInstruction<2>(HType::Boolean()), function_(right) { |
4446 SetOperandAt(0, context); | 4678 SetOperandAt(0, context); |
4447 SetOperandAt(1, left); | 4679 SetOperandAt(1, left); |
4448 set_representation(Representation::Tagged()); | 4680 set_representation(Representation::Tagged()); |
4449 SetAllSideEffects(); | 4681 SetAllSideEffects(); |
4450 } | 4682 } |
4451 | 4683 |
4452 HValue* context() { return OperandAt(0); } | 4684 HValue* context() { return OperandAt(0); } |
4453 HValue* left() { return OperandAt(1); } | 4685 HValue* left() { return OperandAt(1); } |
4454 Handle<JSFunction> function() { return function_; } | 4686 Handle<JSFunction> function() { return function_; } |
4455 | 4687 |
4456 virtual Representation RequiredInputRepresentation(int index) { | 4688 virtual Representation RequiredInputRepresentation(int index) { |
4457 return Representation::Tagged(); | 4689 return Representation::Tagged(); |
4458 } | 4690 } |
4459 | 4691 |
4460 virtual HType CalculateInferredType(); | |
4461 | |
4462 DECLARE_CONCRETE_INSTRUCTION(InstanceOfKnownGlobal) | 4692 DECLARE_CONCRETE_INSTRUCTION(InstanceOfKnownGlobal) |
4463 | 4693 |
4464 private: | 4694 private: |
4465 Handle<JSFunction> function_; | 4695 Handle<JSFunction> function_; |
4466 }; | 4696 }; |
4467 | 4697 |
4468 | 4698 |
4469 // TODO(mstarzinger): This instruction should be modeled as a load of the map | 4699 // TODO(mstarzinger): This instruction should be modeled as a load of the map |
4470 // field followed by a load of the instance size field once HLoadNamedField is | 4700 // field followed by a load of the instance size field once HLoadNamedField is |
4471 // flexible enough to accommodate byte-field loads. | 4701 // flexible enough to accommodate byte-field loads. |
4472 class HInstanceSize: public HTemplateInstruction<1> { | 4702 class HInstanceSize: public HTemplateInstruction<1> { |
4473 public: | 4703 public: |
4474 explicit HInstanceSize(HValue* object) { | 4704 explicit HInstanceSize(HValue* object) { |
4475 SetOperandAt(0, object); | 4705 SetOperandAt(0, object); |
4476 set_representation(Representation::Integer32()); | 4706 set_representation(Representation::Integer32()); |
4477 } | 4707 } |
4478 | 4708 |
4479 HValue* object() { return OperandAt(0); } | 4709 HValue* object() { return OperandAt(0); } |
4480 | 4710 |
4481 virtual Representation RequiredInputRepresentation(int index) { | 4711 virtual Representation RequiredInputRepresentation(int index) { |
4482 return Representation::Tagged(); | 4712 return Representation::Tagged(); |
4483 } | 4713 } |
4484 | 4714 |
4485 DECLARE_CONCRETE_INSTRUCTION(InstanceSize) | 4715 DECLARE_CONCRETE_INSTRUCTION(InstanceSize) |
4486 }; | 4716 }; |
4487 | 4717 |
4488 | 4718 |
4489 class HPower: public HTemplateInstruction<2> { | 4719 class HPower: public HTemplateInstruction<2> { |
4490 public: | 4720 public: |
4491 static HInstruction* New(Zone* zone, HValue* left, HValue* right); | 4721 static HInstruction* New(Zone* zone, |
| 4722 HValue* context, |
| 4723 HValue* left, |
| 4724 HValue* right); |
4492 | 4725 |
4493 HValue* left() { return OperandAt(0); } | 4726 HValue* left() { return OperandAt(0); } |
4494 HValue* right() const { return OperandAt(1); } | 4727 HValue* right() const { return OperandAt(1); } |
4495 | 4728 |
4496 virtual Representation RequiredInputRepresentation(int index) { | 4729 virtual Representation RequiredInputRepresentation(int index) { |
4497 return index == 0 | 4730 return index == 0 |
4498 ? Representation::Double() | 4731 ? Representation::Double() |
4499 : Representation::None(); | 4732 : Representation::None(); |
4500 } | 4733 } |
4501 virtual Representation observed_input_representation(int index) { | 4734 virtual Representation observed_input_representation(int index) { |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4550 HValue* right); | 4783 HValue* right); |
4551 | 4784 |
4552 // Add is only commutative if two integer values are added and not if two | 4785 // Add is only commutative if two integer values are added and not if two |
4553 // tagged values are added (because it might be a String concatenation). | 4786 // tagged values are added (because it might be a String concatenation). |
4554 virtual bool IsCommutative() const { | 4787 virtual bool IsCommutative() const { |
4555 return !representation().IsTagged(); | 4788 return !representation().IsTagged(); |
4556 } | 4789 } |
4557 | 4790 |
4558 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited); | 4791 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited); |
4559 | 4792 |
4560 virtual HType CalculateInferredType(); | |
4561 | |
4562 virtual HValue* Canonicalize(); | 4793 virtual HValue* Canonicalize(); |
4563 | 4794 |
4564 virtual bool TryDecompose(DecompositionResult* decomposition) { | 4795 virtual bool TryDecompose(DecompositionResult* decomposition) { |
4565 if (left()->IsInteger32Constant()) { | 4796 if (left()->IsInteger32Constant()) { |
4566 decomposition->Apply(right(), left()->GetInteger32Constant()); | 4797 decomposition->Apply(right(), left()->GetInteger32Constant()); |
4567 return true; | 4798 return true; |
4568 } else if (right()->IsInteger32Constant()) { | 4799 } else if (right()->IsInteger32Constant()) { |
4569 decomposition->Apply(left(), right()->GetInteger32Constant()); | 4800 decomposition->Apply(left(), right()->GetInteger32Constant()); |
4570 return true; | 4801 return true; |
4571 } else { | 4802 } else { |
(...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4818 : HArithmeticBinaryOperation(context, left, right), | 5049 : HArithmeticBinaryOperation(context, left, right), |
4819 operation_(op) { } | 5050 operation_(op) { } |
4820 | 5051 |
4821 Operation operation_; | 5052 Operation operation_; |
4822 }; | 5053 }; |
4823 | 5054 |
4824 | 5055 |
4825 class HBitwise: public HBitwiseBinaryOperation { | 5056 class HBitwise: public HBitwiseBinaryOperation { |
4826 public: | 5057 public: |
4827 static HInstruction* New(Zone* zone, | 5058 static HInstruction* New(Zone* zone, |
| 5059 HValue* context, |
4828 Token::Value op, | 5060 Token::Value op, |
4829 HValue* context, | |
4830 HValue* left, | 5061 HValue* left, |
4831 HValue* right); | 5062 HValue* right); |
4832 | 5063 |
4833 Token::Value op() const { return op_; } | 5064 Token::Value op() const { return op_; } |
4834 | 5065 |
4835 virtual bool IsCommutative() const { return true; } | 5066 virtual bool IsCommutative() const { return true; } |
4836 | 5067 |
4837 virtual HValue* Canonicalize(); | 5068 virtual HValue* Canonicalize(); |
4838 | 5069 |
4839 virtual void PrintDataTo(StringStream* stream); | 5070 virtual void PrintDataTo(StringStream* stream); |
4840 | 5071 |
4841 DECLARE_CONCRETE_INSTRUCTION(Bitwise) | 5072 DECLARE_CONCRETE_INSTRUCTION(Bitwise) |
4842 | 5073 |
4843 protected: | 5074 protected: |
4844 virtual bool DataEquals(HValue* other) { | 5075 virtual bool DataEquals(HValue* other) { |
4845 return op() == HBitwise::cast(other)->op(); | 5076 return op() == HBitwise::cast(other)->op(); |
4846 } | 5077 } |
4847 | 5078 |
4848 virtual Range* InferRange(Zone* zone); | 5079 virtual Range* InferRange(Zone* zone); |
4849 | 5080 |
4850 private: | 5081 private: |
4851 HBitwise(Token::Value op, HValue* context, HValue* left, HValue* right) | 5082 HBitwise(HValue* context, |
4852 : HBitwiseBinaryOperation(context, left, right), op_(op) { | 5083 Token::Value op, |
| 5084 HValue* left, |
| 5085 HValue* right) |
| 5086 : HBitwiseBinaryOperation(context, left, right, HType::TaggedNumber()), |
| 5087 op_(op) { |
4853 ASSERT(op == Token::BIT_AND || op == Token::BIT_OR || op == Token::BIT_XOR); | 5088 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 | 5089 // BIT_AND with a smi-range positive value will always unset the |
4855 // entire sign-extension of the smi-sign. | 5090 // entire sign-extension of the smi-sign. |
4856 if (op == Token::BIT_AND && | 5091 if (op == Token::BIT_AND && |
4857 ((left->IsConstant() && | 5092 ((left->IsConstant() && |
4858 left->representation().IsSmi() && | 5093 left->representation().IsSmi() && |
4859 HConstant::cast(left)->Integer32Value() >= 0) || | 5094 HConstant::cast(left)->Integer32Value() >= 0) || |
4860 (right->IsConstant() && | 5095 (right->IsConstant() && |
4861 right->representation().IsSmi() && | 5096 right->representation().IsSmi() && |
4862 HConstant::cast(right)->Integer32Value() >= 0))) { | 5097 HConstant::cast(right)->Integer32Value() >= 0))) { |
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5003 | 5238 |
5004 DECLARE_CONCRETE_INSTRUCTION(Ror) | 5239 DECLARE_CONCRETE_INSTRUCTION(Ror) |
5005 | 5240 |
5006 protected: | 5241 protected: |
5007 virtual bool DataEquals(HValue* other) { return true; } | 5242 virtual bool DataEquals(HValue* other) { return true; } |
5008 }; | 5243 }; |
5009 | 5244 |
5010 | 5245 |
5011 class HOsrEntry: public HTemplateInstruction<0> { | 5246 class HOsrEntry: public HTemplateInstruction<0> { |
5012 public: | 5247 public: |
5013 explicit HOsrEntry(BailoutId ast_id) : ast_id_(ast_id) { | 5248 DECLARE_INSTRUCTION_FACTORY_P1(HOsrEntry, BailoutId); |
5014 SetGVNFlag(kChangesOsrEntries); | |
5015 SetGVNFlag(kChangesNewSpacePromotion); | |
5016 } | |
5017 | 5249 |
5018 BailoutId ast_id() const { return ast_id_; } | 5250 BailoutId ast_id() const { return ast_id_; } |
5019 | 5251 |
5020 virtual Representation RequiredInputRepresentation(int index) { | 5252 virtual Representation RequiredInputRepresentation(int index) { |
5021 return Representation::None(); | 5253 return Representation::None(); |
5022 } | 5254 } |
5023 | 5255 |
5024 DECLARE_CONCRETE_INSTRUCTION(OsrEntry) | 5256 DECLARE_CONCRETE_INSTRUCTION(OsrEntry) |
5025 | 5257 |
5026 private: | 5258 private: |
| 5259 explicit HOsrEntry(BailoutId ast_id) : ast_id_(ast_id) { |
| 5260 SetGVNFlag(kChangesOsrEntries); |
| 5261 SetGVNFlag(kChangesNewSpacePromotion); |
| 5262 } |
| 5263 |
5027 BailoutId ast_id_; | 5264 BailoutId ast_id_; |
5028 }; | 5265 }; |
5029 | 5266 |
5030 | 5267 |
5031 class HParameter: public HTemplateInstruction<0> { | 5268 class HParameter: public HTemplateInstruction<0> { |
5032 public: | 5269 public: |
5033 enum ParameterKind { | 5270 enum ParameterKind { |
5034 STACK_PARAMETER, | 5271 STACK_PARAMETER, |
5035 REGISTER_PARAMETER | 5272 REGISTER_PARAMETER |
5036 }; | 5273 }; |
5037 | 5274 |
| 5275 DECLARE_INSTRUCTION_FACTORY_P1(HParameter, unsigned); |
| 5276 DECLARE_INSTRUCTION_FACTORY_P2(HParameter, unsigned, ParameterKind); |
| 5277 DECLARE_INSTRUCTION_FACTORY_P3(HParameter, unsigned, ParameterKind, |
| 5278 Representation); |
| 5279 |
| 5280 unsigned index() const { return index_; } |
| 5281 ParameterKind kind() const { return kind_; } |
| 5282 |
| 5283 virtual void PrintDataTo(StringStream* stream); |
| 5284 |
| 5285 virtual Representation RequiredInputRepresentation(int index) { |
| 5286 return Representation::None(); |
| 5287 } |
| 5288 |
| 5289 DECLARE_CONCRETE_INSTRUCTION(Parameter) |
| 5290 |
| 5291 private: |
5038 explicit HParameter(unsigned index, | 5292 explicit HParameter(unsigned index, |
5039 ParameterKind kind = STACK_PARAMETER) | 5293 ParameterKind kind = STACK_PARAMETER) |
5040 : index_(index), | 5294 : index_(index), |
5041 kind_(kind) { | 5295 kind_(kind) { |
5042 set_representation(Representation::Tagged()); | 5296 set_representation(Representation::Tagged()); |
5043 } | 5297 } |
5044 | 5298 |
5045 explicit HParameter(unsigned index, | 5299 explicit HParameter(unsigned index, |
5046 ParameterKind kind, | 5300 ParameterKind kind, |
5047 Representation r) | 5301 Representation r) |
5048 : index_(index), | 5302 : index_(index), |
5049 kind_(kind) { | 5303 kind_(kind) { |
5050 set_representation(r); | 5304 set_representation(r); |
5051 } | 5305 } |
5052 | 5306 |
5053 unsigned index() const { return index_; } | |
5054 ParameterKind kind() const { return kind_; } | |
5055 | |
5056 virtual void PrintDataTo(StringStream* stream); | |
5057 | |
5058 virtual Representation RequiredInputRepresentation(int index) { | |
5059 return Representation::None(); | |
5060 } | |
5061 | |
5062 DECLARE_CONCRETE_INSTRUCTION(Parameter) | |
5063 | |
5064 private: | |
5065 unsigned index_; | 5307 unsigned index_; |
5066 ParameterKind kind_; | 5308 ParameterKind kind_; |
5067 }; | 5309 }; |
5068 | 5310 |
5069 | 5311 |
5070 class HCallStub: public HUnaryCall { | 5312 class HCallStub: public HUnaryCall { |
5071 public: | 5313 public: |
5072 HCallStub(HValue* context, CodeStub::Major major_key, int argument_count) | 5314 HCallStub(HValue* context, CodeStub::Major major_key, int argument_count) |
5073 : HUnaryCall(context, argument_count), | 5315 : HUnaryCall(context, argument_count), |
5074 major_key_(major_key), | 5316 major_key_(major_key), |
(...skipping 20 matching lines...) Expand all Loading... |
5095 DECLARE_CONCRETE_INSTRUCTION(CallStub) | 5337 DECLARE_CONCRETE_INSTRUCTION(CallStub) |
5096 | 5338 |
5097 private: | 5339 private: |
5098 CodeStub::Major major_key_; | 5340 CodeStub::Major major_key_; |
5099 TranscendentalCache::Type transcendental_type_; | 5341 TranscendentalCache::Type transcendental_type_; |
5100 }; | 5342 }; |
5101 | 5343 |
5102 | 5344 |
5103 class HUnknownOSRValue: public HTemplateInstruction<0> { | 5345 class HUnknownOSRValue: public HTemplateInstruction<0> { |
5104 public: | 5346 public: |
5105 HUnknownOSRValue() | 5347 DECLARE_INSTRUCTION_FACTORY_P0(HUnknownOSRValue) |
5106 : incoming_value_(NULL) { | |
5107 set_representation(Representation::Tagged()); | |
5108 } | |
5109 | 5348 |
5110 virtual Representation RequiredInputRepresentation(int index) { | 5349 virtual Representation RequiredInputRepresentation(int index) { |
5111 return Representation::None(); | 5350 return Representation::None(); |
5112 } | 5351 } |
5113 | 5352 |
5114 void set_incoming_value(HPhi* value) { | 5353 void set_incoming_value(HPhi* value) { |
5115 incoming_value_ = value; | 5354 incoming_value_ = value; |
5116 } | 5355 } |
5117 | 5356 |
5118 HPhi* incoming_value() { | 5357 HPhi* incoming_value() { |
5119 return incoming_value_; | 5358 return incoming_value_; |
5120 } | 5359 } |
5121 | 5360 |
5122 virtual Representation KnownOptimalRepresentation() { | 5361 virtual Representation KnownOptimalRepresentation() { |
5123 if (incoming_value_ == NULL) return Representation::None(); | 5362 if (incoming_value_ == NULL) return Representation::None(); |
5124 return incoming_value_->KnownOptimalRepresentation(); | 5363 return incoming_value_->KnownOptimalRepresentation(); |
5125 } | 5364 } |
5126 | 5365 |
5127 DECLARE_CONCRETE_INSTRUCTION(UnknownOSRValue) | 5366 DECLARE_CONCRETE_INSTRUCTION(UnknownOSRValue) |
5128 | 5367 |
5129 private: | 5368 private: |
| 5369 HUnknownOSRValue() |
| 5370 : incoming_value_(NULL) { |
| 5371 set_representation(Representation::Tagged()); |
| 5372 } |
| 5373 |
5130 HPhi* incoming_value_; | 5374 HPhi* incoming_value_; |
5131 }; | 5375 }; |
5132 | 5376 |
5133 | 5377 |
5134 class HLoadGlobalCell: public HTemplateInstruction<0> { | 5378 class HLoadGlobalCell: public HTemplateInstruction<0> { |
5135 public: | 5379 public: |
5136 HLoadGlobalCell(Handle<Cell> cell, PropertyDetails details) | 5380 HLoadGlobalCell(Handle<Cell> cell, PropertyDetails details) |
5137 : cell_(cell), details_(details), unique_id_() { | 5381 : cell_(cell), details_(details), unique_id_() { |
5138 set_representation(Representation::Tagged()); | 5382 set_representation(Representation::Tagged()); |
5139 SetFlag(kUseGVN); | 5383 SetFlag(kUseGVN); |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5202 DECLARE_CONCRETE_INSTRUCTION(LoadGlobalGeneric) | 5446 DECLARE_CONCRETE_INSTRUCTION(LoadGlobalGeneric) |
5203 | 5447 |
5204 private: | 5448 private: |
5205 Handle<Object> name_; | 5449 Handle<Object> name_; |
5206 bool for_typeof_; | 5450 bool for_typeof_; |
5207 }; | 5451 }; |
5208 | 5452 |
5209 | 5453 |
5210 class HAllocate: public HTemplateInstruction<2> { | 5454 class HAllocate: public HTemplateInstruction<2> { |
5211 public: | 5455 public: |
5212 enum Flags { | 5456 static HAllocate* New(Zone* zone, |
5213 CAN_ALLOCATE_IN_NEW_SPACE = 1 << 0, | 5457 HValue* context, |
5214 CAN_ALLOCATE_IN_OLD_DATA_SPACE = 1 << 1, | 5458 HValue* size, |
5215 CAN_ALLOCATE_IN_OLD_POINTER_SPACE = 1 << 2, | 5459 HType type, |
5216 ALLOCATE_DOUBLE_ALIGNED = 1 << 3, | 5460 PretenureFlag pretenure_flag, |
5217 PREFILL_WITH_FILLER = 1 << 4 | 5461 InstanceType instance_type) { |
5218 }; | 5462 return new(zone) HAllocate(context, size, type, pretenure_flag, |
5219 | 5463 instance_type); |
5220 HAllocate(HValue* context, HValue* size, HType type, Flags flags) | |
5221 : flags_(flags) { | |
5222 SetOperandAt(0, context); | |
5223 SetOperandAt(1, size); | |
5224 set_type(type); | |
5225 set_representation(Representation::Tagged()); | |
5226 SetFlag(kTrackSideEffectDominators); | |
5227 SetGVNFlag(kChangesNewSpacePromotion); | |
5228 SetGVNFlag(kDependsOnNewSpacePromotion); | |
5229 } | 5464 } |
5230 | 5465 |
5231 // Maximum instance size for which allocations will be inlined. | 5466 // Maximum instance size for which allocations will be inlined. |
5232 static const int kMaxInlineSize = 64 * kPointerSize; | 5467 static const int kMaxInlineSize = 64 * kPointerSize; |
5233 | 5468 |
5234 static Flags DefaultFlags() { | |
5235 return CAN_ALLOCATE_IN_NEW_SPACE; | |
5236 } | |
5237 | |
5238 static Flags DefaultFlags(ElementsKind kind) { | |
5239 Flags flags = CAN_ALLOCATE_IN_NEW_SPACE; | |
5240 if (IsFastDoubleElementsKind(kind)) { | |
5241 flags = static_cast<HAllocate::Flags>( | |
5242 flags | HAllocate::ALLOCATE_DOUBLE_ALIGNED); | |
5243 } | |
5244 return flags; | |
5245 } | |
5246 | |
5247 HValue* context() { return OperandAt(0); } | 5469 HValue* context() { return OperandAt(0); } |
5248 HValue* size() { return OperandAt(1); } | 5470 HValue* size() { return OperandAt(1); } |
5249 | 5471 |
5250 virtual Representation RequiredInputRepresentation(int index) { | 5472 virtual Representation RequiredInputRepresentation(int index) { |
5251 if (index == 0) { | 5473 if (index == 0) { |
5252 return Representation::Tagged(); | 5474 return Representation::Tagged(); |
5253 } else { | 5475 } else { |
5254 return Representation::Integer32(); | 5476 return Representation::Integer32(); |
5255 } | 5477 } |
5256 } | 5478 } |
5257 | 5479 |
5258 virtual Handle<Map> GetMonomorphicJSObjectMap() { | 5480 virtual Handle<Map> GetMonomorphicJSObjectMap() { |
5259 return known_initial_map_; | 5481 return known_initial_map_; |
5260 } | 5482 } |
5261 | 5483 |
5262 void set_known_initial_map(Handle<Map> known_initial_map) { | 5484 void set_known_initial_map(Handle<Map> known_initial_map) { |
5263 known_initial_map_ = known_initial_map; | 5485 known_initial_map_ = known_initial_map; |
5264 } | 5486 } |
5265 | 5487 |
5266 bool CanAllocateInNewSpace() const { | 5488 bool IsNewSpaceAllocation() const { |
5267 return (flags_ & CAN_ALLOCATE_IN_NEW_SPACE) != 0; | 5489 return (flags_ & ALLOCATE_IN_NEW_SPACE) != 0; |
5268 } | 5490 } |
5269 | 5491 |
5270 bool CanAllocateInOldDataSpace() const { | 5492 bool IsOldDataSpaceAllocation() const { |
5271 return (flags_ & CAN_ALLOCATE_IN_OLD_DATA_SPACE) != 0; | 5493 return (flags_ & ALLOCATE_IN_OLD_DATA_SPACE) != 0; |
5272 } | 5494 } |
5273 | 5495 |
5274 bool CanAllocateInOldPointerSpace() const { | 5496 bool IsOldPointerSpaceAllocation() const { |
5275 return (flags_ & CAN_ALLOCATE_IN_OLD_POINTER_SPACE) != 0; | 5497 return (flags_ & ALLOCATE_IN_OLD_POINTER_SPACE) != 0; |
5276 } | |
5277 | |
5278 bool CanAllocateInOldSpace() const { | |
5279 return CanAllocateInOldDataSpace() || | |
5280 CanAllocateInOldPointerSpace(); | |
5281 } | |
5282 | |
5283 bool GuaranteedInNewSpace() const { | |
5284 return CanAllocateInNewSpace() && !CanAllocateInOldSpace(); | |
5285 } | 5498 } |
5286 | 5499 |
5287 bool MustAllocateDoubleAligned() const { | 5500 bool MustAllocateDoubleAligned() const { |
5288 return (flags_ & ALLOCATE_DOUBLE_ALIGNED) != 0; | 5501 return (flags_ & ALLOCATE_DOUBLE_ALIGNED) != 0; |
5289 } | 5502 } |
5290 | 5503 |
5291 bool MustPrefillWithFiller() const { | 5504 bool MustPrefillWithFiller() const { |
5292 return (flags_ & PREFILL_WITH_FILLER) != 0; | 5505 return (flags_ & PREFILL_WITH_FILLER) != 0; |
5293 } | 5506 } |
5294 | 5507 |
5295 void SetFlags(Flags flags) { | 5508 void MakePrefillWithFiller() { |
5296 flags_ = static_cast<HAllocate::Flags>(flags_ | flags); | 5509 flags_ = static_cast<HAllocate::Flags>(flags_ | PREFILL_WITH_FILLER); |
| 5510 } |
| 5511 |
| 5512 void MakeDoubleAligned() { |
| 5513 flags_ = static_cast<HAllocate::Flags>(flags_ | ALLOCATE_DOUBLE_ALIGNED); |
5297 } | 5514 } |
5298 | 5515 |
5299 void UpdateSize(HValue* size) { | 5516 void UpdateSize(HValue* size) { |
5300 SetOperandAt(1, size); | 5517 SetOperandAt(1, size); |
5301 } | 5518 } |
5302 | 5519 |
5303 virtual void HandleSideEffectDominator(GVNFlag side_effect, | 5520 virtual void HandleSideEffectDominator(GVNFlag side_effect, |
5304 HValue* dominator); | 5521 HValue* dominator); |
5305 | 5522 |
5306 virtual void PrintDataTo(StringStream* stream); | 5523 virtual void PrintDataTo(StringStream* stream); |
5307 | 5524 |
5308 DECLARE_CONCRETE_INSTRUCTION(Allocate) | 5525 DECLARE_CONCRETE_INSTRUCTION(Allocate) |
5309 | 5526 |
5310 private: | 5527 private: |
| 5528 enum Flags { |
| 5529 ALLOCATE_IN_NEW_SPACE = 1 << 0, |
| 5530 ALLOCATE_IN_OLD_DATA_SPACE = 1 << 1, |
| 5531 ALLOCATE_IN_OLD_POINTER_SPACE = 1 << 2, |
| 5532 ALLOCATE_DOUBLE_ALIGNED = 1 << 3, |
| 5533 PREFILL_WITH_FILLER = 1 << 4 |
| 5534 }; |
| 5535 |
| 5536 HAllocate(HValue* context, |
| 5537 HValue* size, |
| 5538 HType type, |
| 5539 PretenureFlag pretenure_flag, |
| 5540 InstanceType instance_type) |
| 5541 : HTemplateInstruction<2>(type) { |
| 5542 SetOperandAt(0, context); |
| 5543 SetOperandAt(1, size); |
| 5544 set_representation(Representation::Tagged()); |
| 5545 SetFlag(kTrackSideEffectDominators); |
| 5546 SetGVNFlag(kChangesNewSpacePromotion); |
| 5547 SetGVNFlag(kDependsOnNewSpacePromotion); |
| 5548 flags_ = pretenure_flag == TENURED |
| 5549 ? (Heap::TargetSpaceId(instance_type) == OLD_POINTER_SPACE |
| 5550 ? ALLOCATE_IN_OLD_POINTER_SPACE : ALLOCATE_IN_OLD_DATA_SPACE) |
| 5551 : ALLOCATE_IN_NEW_SPACE; |
| 5552 if (instance_type == FIXED_DOUBLE_ARRAY_TYPE) { |
| 5553 flags_ = static_cast<HAllocate::Flags>(flags_ | |
| 5554 ALLOCATE_DOUBLE_ALIGNED); |
| 5555 } |
| 5556 } |
| 5557 |
5311 Flags flags_; | 5558 Flags flags_; |
5312 Handle<Map> known_initial_map_; | 5559 Handle<Map> known_initial_map_; |
5313 }; | 5560 }; |
5314 | 5561 |
5315 | 5562 |
5316 class HInnerAllocatedObject: public HTemplateInstruction<1> { | 5563 class HInnerAllocatedObject: public HTemplateInstruction<1> { |
5317 public: | 5564 public: |
5318 HInnerAllocatedObject(HValue* value, int offset, HType type = HType::Tagged()) | 5565 static HInnerAllocatedObject* New(Zone* zone, |
5319 : offset_(offset) { | 5566 HValue* context, |
5320 ASSERT(value->IsAllocate()); | 5567 HValue* value, |
5321 SetOperandAt(0, value); | 5568 int offset, |
5322 set_type(type); | 5569 HType type = HType::Tagged()) { |
5323 set_representation(Representation::Tagged()); | 5570 return new(zone) HInnerAllocatedObject(value, offset, type); |
5324 } | 5571 } |
5325 | 5572 |
5326 HValue* base_object() { return OperandAt(0); } | 5573 HValue* base_object() { return OperandAt(0); } |
5327 int offset() { return offset_; } | 5574 int offset() { return offset_; } |
5328 | 5575 |
5329 virtual Representation RequiredInputRepresentation(int index) { | 5576 virtual Representation RequiredInputRepresentation(int index) { |
5330 return Representation::Tagged(); | 5577 return Representation::Tagged(); |
5331 } | 5578 } |
5332 | 5579 |
5333 virtual void PrintDataTo(StringStream* stream); | 5580 virtual void PrintDataTo(StringStream* stream); |
5334 | 5581 |
5335 DECLARE_CONCRETE_INSTRUCTION(InnerAllocatedObject) | 5582 DECLARE_CONCRETE_INSTRUCTION(InnerAllocatedObject) |
5336 | 5583 |
5337 private: | 5584 private: |
| 5585 HInnerAllocatedObject(HValue* value, int offset, HType type = HType::Tagged()) |
| 5586 : HTemplateInstruction<1>(type), offset_(offset) { |
| 5587 ASSERT(value->IsAllocate()); |
| 5588 SetOperandAt(0, value); |
| 5589 set_type(type); |
| 5590 set_representation(Representation::Tagged()); |
| 5591 } |
| 5592 |
5338 int offset_; | 5593 int offset_; |
5339 }; | 5594 }; |
5340 | 5595 |
5341 | 5596 |
5342 inline bool StoringValueNeedsWriteBarrier(HValue* value) { | 5597 inline bool StoringValueNeedsWriteBarrier(HValue* value) { |
5343 return !value->type().IsBoolean() | 5598 return !value->type().IsBoolean() |
5344 && !value->type().IsSmi() | 5599 && !value->type().IsSmi() |
5345 && !(value->IsConstant() && HConstant::cast(value)->ImmortalImmovable()); | 5600 && !(value->IsConstant() && HConstant::cast(value)->ImmortalImmovable()); |
5346 } | 5601 } |
5347 | 5602 |
5348 | 5603 |
5349 inline bool ReceiverObjectNeedsWriteBarrier(HValue* object, | 5604 inline bool ReceiverObjectNeedsWriteBarrier(HValue* object, |
5350 HValue* new_space_dominator) { | 5605 HValue* new_space_dominator) { |
5351 if (object->IsInnerAllocatedObject()) { | 5606 if (object->IsInnerAllocatedObject()) { |
5352 return ReceiverObjectNeedsWriteBarrier( | 5607 return ReceiverObjectNeedsWriteBarrier( |
5353 HInnerAllocatedObject::cast(object)->base_object(), | 5608 HInnerAllocatedObject::cast(object)->base_object(), |
5354 new_space_dominator); | 5609 new_space_dominator); |
5355 } | 5610 } |
5356 if (object->IsConstant() && HConstant::cast(object)->IsCell()) { | 5611 if (object->IsConstant() && HConstant::cast(object)->IsCell()) { |
5357 return false; | 5612 return false; |
5358 } | 5613 } |
| 5614 if (object->IsConstant() && |
| 5615 HConstant::cast(object)->HasExternalReferenceValue()) { |
| 5616 // Stores to external references require no write barriers |
| 5617 return false; |
| 5618 } |
5359 if (object != new_space_dominator) return true; | 5619 if (object != new_space_dominator) return true; |
5360 if (object->IsAllocate()) { | 5620 if (object->IsAllocate()) { |
5361 return !HAllocate::cast(object)->GuaranteedInNewSpace(); | 5621 return !HAllocate::cast(object)->IsNewSpaceAllocation(); |
5362 } | 5622 } |
5363 return true; | 5623 return true; |
5364 } | 5624 } |
5365 | 5625 |
5366 | 5626 |
5367 class HStoreGlobalCell: public HUnaryOperation { | 5627 class HStoreGlobalCell: public HUnaryOperation { |
5368 public: | 5628 public: |
5369 HStoreGlobalCell(HValue* value, | 5629 DECLARE_INSTRUCTION_FACTORY_P3(HStoreGlobalCell, HValue*, |
5370 Handle<PropertyCell> cell, | 5630 Handle<PropertyCell>, PropertyDetails); |
5371 PropertyDetails details) | |
5372 : HUnaryOperation(value), | |
5373 cell_(cell), | |
5374 details_(details) { | |
5375 SetGVNFlag(kChangesGlobalVars); | |
5376 } | |
5377 | 5631 |
5378 Handle<PropertyCell> cell() const { return cell_; } | 5632 Handle<PropertyCell> cell() const { return cell_; } |
5379 bool RequiresHoleCheck() { | 5633 bool RequiresHoleCheck() { |
5380 return !details_.IsDontDelete() || details_.IsReadOnly(); | 5634 return !details_.IsDontDelete() || details_.IsReadOnly(); |
5381 } | 5635 } |
5382 bool NeedsWriteBarrier() { | 5636 bool NeedsWriteBarrier() { |
5383 return StoringValueNeedsWriteBarrier(value()); | 5637 return StoringValueNeedsWriteBarrier(value()); |
5384 } | 5638 } |
5385 | 5639 |
5386 virtual Representation RequiredInputRepresentation(int index) { | 5640 virtual Representation RequiredInputRepresentation(int index) { |
5387 return Representation::Tagged(); | 5641 return Representation::Tagged(); |
5388 } | 5642 } |
5389 virtual void PrintDataTo(StringStream* stream); | 5643 virtual void PrintDataTo(StringStream* stream); |
5390 | 5644 |
5391 DECLARE_CONCRETE_INSTRUCTION(StoreGlobalCell) | 5645 DECLARE_CONCRETE_INSTRUCTION(StoreGlobalCell) |
5392 | 5646 |
5393 private: | 5647 private: |
| 5648 HStoreGlobalCell(HValue* value, |
| 5649 Handle<PropertyCell> cell, |
| 5650 PropertyDetails details) |
| 5651 : HUnaryOperation(value), |
| 5652 cell_(cell), |
| 5653 details_(details) { |
| 5654 SetGVNFlag(kChangesGlobalVars); |
| 5655 } |
| 5656 |
5394 Handle<PropertyCell> cell_; | 5657 Handle<PropertyCell> cell_; |
5395 PropertyDetails details_; | 5658 PropertyDetails details_; |
5396 }; | 5659 }; |
5397 | 5660 |
5398 | 5661 |
5399 class HStoreGlobalGeneric: public HTemplateInstruction<3> { | 5662 class HStoreGlobalGeneric: public HTemplateInstruction<3> { |
5400 public: | 5663 public: |
5401 HStoreGlobalGeneric(HValue* context, | 5664 inline static HStoreGlobalGeneric* New(Zone* zone, |
5402 HValue* global_object, | 5665 HValue* context, |
5403 Handle<Object> name, | 5666 HValue* global_object, |
5404 HValue* value, | 5667 Handle<Object> name, |
5405 StrictModeFlag strict_mode_flag) | 5668 HValue* value, |
5406 : name_(name), | 5669 StrictModeFlag strict_mode_flag) { |
5407 strict_mode_flag_(strict_mode_flag) { | 5670 return new(zone) HStoreGlobalGeneric(context, global_object, |
5408 SetOperandAt(0, context); | 5671 name, value, strict_mode_flag); |
5409 SetOperandAt(1, global_object); | |
5410 SetOperandAt(2, value); | |
5411 set_representation(Representation::Tagged()); | |
5412 SetAllSideEffects(); | |
5413 } | 5672 } |
5414 | 5673 |
5415 HValue* context() { return OperandAt(0); } | 5674 HValue* context() { return OperandAt(0); } |
5416 HValue* global_object() { return OperandAt(1); } | 5675 HValue* global_object() { return OperandAt(1); } |
5417 Handle<Object> name() const { return name_; } | 5676 Handle<Object> name() const { return name_; } |
5418 HValue* value() { return OperandAt(2); } | 5677 HValue* value() { return OperandAt(2); } |
5419 StrictModeFlag strict_mode_flag() { return strict_mode_flag_; } | 5678 StrictModeFlag strict_mode_flag() { return strict_mode_flag_; } |
5420 | 5679 |
5421 virtual void PrintDataTo(StringStream* stream); | 5680 virtual void PrintDataTo(StringStream* stream); |
5422 | 5681 |
5423 virtual Representation RequiredInputRepresentation(int index) { | 5682 virtual Representation RequiredInputRepresentation(int index) { |
5424 return Representation::Tagged(); | 5683 return Representation::Tagged(); |
5425 } | 5684 } |
5426 | 5685 |
5427 DECLARE_CONCRETE_INSTRUCTION(StoreGlobalGeneric) | 5686 DECLARE_CONCRETE_INSTRUCTION(StoreGlobalGeneric) |
5428 | 5687 |
5429 private: | 5688 private: |
| 5689 HStoreGlobalGeneric(HValue* context, |
| 5690 HValue* global_object, |
| 5691 Handle<Object> name, |
| 5692 HValue* value, |
| 5693 StrictModeFlag strict_mode_flag) |
| 5694 : name_(name), |
| 5695 strict_mode_flag_(strict_mode_flag) { |
| 5696 SetOperandAt(0, context); |
| 5697 SetOperandAt(1, global_object); |
| 5698 SetOperandAt(2, value); |
| 5699 set_representation(Representation::Tagged()); |
| 5700 SetAllSideEffects(); |
| 5701 } |
| 5702 |
5430 Handle<Object> name_; | 5703 Handle<Object> name_; |
5431 StrictModeFlag strict_mode_flag_; | 5704 StrictModeFlag strict_mode_flag_; |
5432 }; | 5705 }; |
5433 | 5706 |
5434 | 5707 |
5435 class HLoadContextSlot: public HUnaryOperation { | 5708 class HLoadContextSlot: public HUnaryOperation { |
5436 public: | 5709 public: |
5437 enum Mode { | 5710 enum Mode { |
5438 // Perform a normal load of the context slot without checking its value. | 5711 // Perform a normal load of the context slot without checking its value. |
5439 kNoCheck, | 5712 kNoCheck, |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5507 kNoCheck, | 5780 kNoCheck, |
5508 // Check the previous value of the context slot and deoptimize if it's the | 5781 // Check the previous value of the context slot and deoptimize if it's the |
5509 // hole value. This is used for checking for assignments to uninitialized | 5782 // hole value. This is used for checking for assignments to uninitialized |
5510 // harmony bindings where we deoptimize into full-codegen generated code | 5783 // harmony bindings where we deoptimize into full-codegen generated code |
5511 // which will subsequently throw a reference error. | 5784 // which will subsequently throw a reference error. |
5512 kCheckDeoptimize, | 5785 kCheckDeoptimize, |
5513 // Check the previous value and ignore assignment if it isn't a hole value | 5786 // Check the previous value and ignore assignment if it isn't a hole value |
5514 kCheckIgnoreAssignment | 5787 kCheckIgnoreAssignment |
5515 }; | 5788 }; |
5516 | 5789 |
5517 HStoreContextSlot(HValue* context, int slot_index, Mode mode, HValue* value) | 5790 DECLARE_INSTRUCTION_FACTORY_P4(HStoreContextSlot, HValue*, int, |
5518 : slot_index_(slot_index), mode_(mode) { | 5791 Mode, HValue*); |
5519 SetOperandAt(0, context); | |
5520 SetOperandAt(1, value); | |
5521 SetGVNFlag(kChangesContextSlots); | |
5522 } | |
5523 | 5792 |
5524 HValue* context() { return OperandAt(0); } | 5793 HValue* context() { return OperandAt(0); } |
5525 HValue* value() { return OperandAt(1); } | 5794 HValue* value() { return OperandAt(1); } |
5526 int slot_index() const { return slot_index_; } | 5795 int slot_index() const { return slot_index_; } |
5527 Mode mode() const { return mode_; } | 5796 Mode mode() const { return mode_; } |
5528 | 5797 |
5529 bool NeedsWriteBarrier() { | 5798 bool NeedsWriteBarrier() { |
5530 return StoringValueNeedsWriteBarrier(value()); | 5799 return StoringValueNeedsWriteBarrier(value()); |
5531 } | 5800 } |
5532 | 5801 |
5533 bool DeoptimizesOnHole() { | 5802 bool DeoptimizesOnHole() { |
5534 return mode_ == kCheckDeoptimize; | 5803 return mode_ == kCheckDeoptimize; |
5535 } | 5804 } |
5536 | 5805 |
5537 bool RequiresHoleCheck() { | 5806 bool RequiresHoleCheck() { |
5538 return mode_ != kNoCheck; | 5807 return mode_ != kNoCheck; |
5539 } | 5808 } |
5540 | 5809 |
5541 virtual Representation RequiredInputRepresentation(int index) { | 5810 virtual Representation RequiredInputRepresentation(int index) { |
5542 return Representation::Tagged(); | 5811 return Representation::Tagged(); |
5543 } | 5812 } |
5544 | 5813 |
5545 virtual void PrintDataTo(StringStream* stream); | 5814 virtual void PrintDataTo(StringStream* stream); |
5546 | 5815 |
5547 DECLARE_CONCRETE_INSTRUCTION(StoreContextSlot) | 5816 DECLARE_CONCRETE_INSTRUCTION(StoreContextSlot) |
5548 | 5817 |
5549 private: | 5818 private: |
| 5819 HStoreContextSlot(HValue* context, int slot_index, Mode mode, HValue* value) |
| 5820 : slot_index_(slot_index), mode_(mode) { |
| 5821 SetOperandAt(0, context); |
| 5822 SetOperandAt(1, value); |
| 5823 SetGVNFlag(kChangesContextSlots); |
| 5824 } |
| 5825 |
5550 int slot_index_; | 5826 int slot_index_; |
5551 Mode mode_; | 5827 Mode mode_; |
5552 }; | 5828 }; |
5553 | 5829 |
5554 | 5830 |
5555 // Represents an access to a portion of an object, such as the map pointer, | 5831 // Represents an access to a portion of an object, such as the map pointer, |
5556 // array elements pointer, etc, but not accesses to array elements themselves. | 5832 // array elements pointer, etc, but not accesses to array elements themselves. |
5557 class HObjectAccess { | 5833 class HObjectAccess { |
5558 public: | 5834 public: |
5559 inline bool IsInobject() const { | 5835 inline bool IsInobject() const { |
5560 return portion() != kBackingStore; | 5836 return portion() != kBackingStore && portion() != kExternalMemory; |
| 5837 } |
| 5838 |
| 5839 inline bool IsExternalMemory() const { |
| 5840 return portion() == kExternalMemory; |
| 5841 } |
| 5842 |
| 5843 inline bool IsStringLength() const { |
| 5844 return portion() == kStringLengths; |
5561 } | 5845 } |
5562 | 5846 |
5563 inline int offset() const { | 5847 inline int offset() const { |
5564 return OffsetField::decode(value_); | 5848 return OffsetField::decode(value_); |
5565 } | 5849 } |
5566 | 5850 |
5567 inline Representation representation() const { | 5851 inline Representation representation() const { |
5568 return Representation::FromKind(RepresentationField::decode(value_)); | 5852 return Representation::FromKind(RepresentationField::decode(value_)); |
5569 } | 5853 } |
5570 | 5854 |
5571 inline Handle<String> name() const { | 5855 inline Handle<String> name() const { |
5572 return name_; | 5856 return name_; |
5573 } | 5857 } |
5574 | 5858 |
5575 inline HObjectAccess WithRepresentation(Representation representation) { | 5859 inline HObjectAccess WithRepresentation(Representation representation) { |
5576 return HObjectAccess(portion(), offset(), representation, name()); | 5860 return HObjectAccess(portion(), offset(), representation, name()); |
5577 } | 5861 } |
5578 | 5862 |
5579 static HObjectAccess ForHeapNumberValue() { | 5863 static HObjectAccess ForHeapNumberValue() { |
5580 return HObjectAccess( | 5864 return HObjectAccess( |
5581 kDouble, HeapNumber::kValueOffset, Representation::Double()); | 5865 kDouble, HeapNumber::kValueOffset, Representation::Double()); |
5582 } | 5866 } |
5583 | 5867 |
5584 static HObjectAccess ForElementsPointer() { | 5868 static HObjectAccess ForElementsPointer() { |
5585 return HObjectAccess(kElementsPointer, JSObject::kElementsOffset); | 5869 return HObjectAccess(kElementsPointer, JSObject::kElementsOffset); |
5586 } | 5870 } |
5587 | 5871 |
5588 static HObjectAccess ForArrayLength(ElementsKind elements_kind) { | 5872 static HObjectAccess ForArrayLength(ElementsKind elements_kind) { |
5589 return HObjectAccess( | 5873 return HObjectAccess( |
5590 kArrayLengths, JSArray::kLengthOffset, | 5874 kArrayLengths, |
5591 IsFastElementsKind(elements_kind) && FLAG_track_fields ? | 5875 JSArray::kLengthOffset, |
5592 Representation::Smi() : Representation::Tagged()); | 5876 IsFastElementsKind(elements_kind) && |
| 5877 FLAG_track_fields |
| 5878 ? Representation::Smi() : Representation::Tagged()); |
5593 } | 5879 } |
5594 | 5880 |
5595 static HObjectAccess ForAllocationSiteTransitionInfo() { | 5881 static HObjectAccess ForAllocationSiteTransitionInfo() { |
5596 return HObjectAccess(kInobject, AllocationSite::kTransitionInfoOffset); | 5882 return HObjectAccess(kInobject, AllocationSite::kTransitionInfoOffset); |
5597 } | 5883 } |
5598 | 5884 |
5599 static HObjectAccess ForAllocationSiteWeakNext() { | 5885 static HObjectAccess ForAllocationSiteWeakNext() { |
5600 return HObjectAccess(kInobject, AllocationSite::kWeakNextOffset); | 5886 return HObjectAccess(kInobject, AllocationSite::kWeakNextOffset); |
5601 } | 5887 } |
5602 | 5888 |
| 5889 static HObjectAccess ForAllocationSiteList() { |
| 5890 return HObjectAccess(kExternalMemory, 0, Representation::Tagged()); |
| 5891 } |
| 5892 |
5603 static HObjectAccess ForFixedArrayLength() { | 5893 static HObjectAccess ForFixedArrayLength() { |
5604 return HObjectAccess( | 5894 return HObjectAccess( |
5605 kArrayLengths, FixedArray::kLengthOffset, | 5895 kArrayLengths, |
5606 FLAG_track_fields ? | 5896 FixedArray::kLengthOffset, |
5607 Representation::Smi() : Representation::Tagged()); | 5897 FLAG_track_fields ? Representation::Smi() : Representation::Tagged()); |
| 5898 } |
| 5899 |
| 5900 static HObjectAccess ForStringLength() { |
| 5901 STATIC_ASSERT(String::kMaxLength <= Smi::kMaxValue); |
| 5902 return HObjectAccess( |
| 5903 kStringLengths, |
| 5904 String::kLengthOffset, |
| 5905 FLAG_track_fields ? Representation::Smi() : Representation::Tagged()); |
5608 } | 5906 } |
5609 | 5907 |
5610 static HObjectAccess ForPropertiesPointer() { | 5908 static HObjectAccess ForPropertiesPointer() { |
5611 return HObjectAccess(kInobject, JSObject::kPropertiesOffset); | 5909 return HObjectAccess(kInobject, JSObject::kPropertiesOffset); |
5612 } | 5910 } |
5613 | 5911 |
5614 static HObjectAccess ForPrototypeOrInitialMap() { | 5912 static HObjectAccess ForPrototypeOrInitialMap() { |
5615 return HObjectAccess(kInobject, JSFunction::kPrototypeOrInitialMapOffset); | 5913 return HObjectAccess(kInobject, JSFunction::kPrototypeOrInitialMapOffset); |
5616 } | 5914 } |
5617 | 5915 |
5618 static HObjectAccess ForMap() { | 5916 static HObjectAccess ForMap() { |
5619 return HObjectAccess(kMaps, JSObject::kMapOffset); | 5917 return HObjectAccess(kMaps, JSObject::kMapOffset); |
5620 } | 5918 } |
5621 | 5919 |
5622 static HObjectAccess ForPropertyCellValue() { | 5920 static HObjectAccess ForPropertyCellValue() { |
5623 return HObjectAccess(kInobject, PropertyCell::kValueOffset); | 5921 return HObjectAccess(kInobject, PropertyCell::kValueOffset); |
5624 } | 5922 } |
5625 | 5923 |
5626 static HObjectAccess ForCellValue() { | 5924 static HObjectAccess ForCellValue() { |
5627 return HObjectAccess(kInobject, Cell::kValueOffset); | 5925 return HObjectAccess(kInobject, Cell::kValueOffset); |
5628 } | 5926 } |
5629 | 5927 |
5630 static HObjectAccess ForAllocationMementoSite() { | 5928 static HObjectAccess ForAllocationMementoSite() { |
5631 return HObjectAccess(kInobject, AllocationMemento::kAllocationSiteOffset); | 5929 return HObjectAccess(kInobject, AllocationMemento::kAllocationSiteOffset); |
5632 } | 5930 } |
5633 | 5931 |
| 5932 static HObjectAccess ForCounter() { |
| 5933 return HObjectAccess(kExternalMemory, 0, Representation::Integer32()); |
| 5934 } |
| 5935 |
5634 // Create an access to an offset in a fixed array header. | 5936 // Create an access to an offset in a fixed array header. |
5635 static HObjectAccess ForFixedArrayHeader(int offset); | 5937 static HObjectAccess ForFixedArrayHeader(int offset); |
5636 | 5938 |
5637 // Create an access to an in-object property in a JSObject. | 5939 // Create an access to an in-object property in a JSObject. |
5638 static HObjectAccess ForJSObjectOffset(int offset, | 5940 static HObjectAccess ForJSObjectOffset(int offset, |
5639 Representation representation = Representation::Tagged()); | 5941 Representation representation = Representation::Tagged()); |
5640 | 5942 |
5641 // Create an access to an in-object property in a JSArray. | 5943 // Create an access to an in-object property in a JSArray. |
5642 static HObjectAccess ForJSArrayOffset(int offset); | 5944 static HObjectAccess ForJSArrayOffset(int offset); |
5643 | 5945 |
(...skipping 15 matching lines...) Expand all Loading... |
5659 } | 5961 } |
5660 | 5962 |
5661 protected: | 5963 protected: |
5662 void SetGVNFlags(HValue *instr, bool is_store); | 5964 void SetGVNFlags(HValue *instr, bool is_store); |
5663 | 5965 |
5664 private: | 5966 private: |
5665 // internal use only; different parts of an object or array | 5967 // internal use only; different parts of an object or array |
5666 enum Portion { | 5968 enum Portion { |
5667 kMaps, // map of an object | 5969 kMaps, // map of an object |
5668 kArrayLengths, // the length of an array | 5970 kArrayLengths, // the length of an array |
| 5971 kStringLengths, // the length of a string |
5669 kElementsPointer, // elements pointer | 5972 kElementsPointer, // elements pointer |
5670 kBackingStore, // some field in the backing store | 5973 kBackingStore, // some field in the backing store |
5671 kDouble, // some double field | 5974 kDouble, // some double field |
5672 kInobject // some other in-object field | 5975 kInobject, // some other in-object field |
| 5976 kExternalMemory // some field in external memory |
5673 }; | 5977 }; |
5674 | 5978 |
5675 HObjectAccess(Portion portion, int offset, | 5979 HObjectAccess(Portion portion, int offset, |
5676 Representation representation = Representation::Tagged(), | 5980 Representation representation = Representation::Tagged(), |
5677 Handle<String> name = Handle<String>::null()) | 5981 Handle<String> name = Handle<String>::null()) |
5678 : value_(PortionField::encode(portion) | | 5982 : value_(PortionField::encode(portion) | |
5679 RepresentationField::encode(representation.kind()) | | 5983 RepresentationField::encode(representation.kind()) | |
5680 OffsetField::encode(offset)), | 5984 OffsetField::encode(offset)), |
5681 name_(name) { | 5985 name_(name) { |
5682 // assert that the fields decode correctly | 5986 // assert that the fields decode correctly |
(...skipping 11 matching lines...) Expand all Loading... |
5694 | 5998 |
5695 friend class HLoadNamedField; | 5999 friend class HLoadNamedField; |
5696 friend class HStoreNamedField; | 6000 friend class HStoreNamedField; |
5697 | 6001 |
5698 inline Portion portion() const { | 6002 inline Portion portion() const { |
5699 return PortionField::decode(value_); | 6003 return PortionField::decode(value_); |
5700 } | 6004 } |
5701 }; | 6005 }; |
5702 | 6006 |
5703 | 6007 |
5704 class HLinkObjectInList: public HUnaryOperation { | |
5705 public: | |
5706 // There needs to be a mapping from every KnownList to an external reference | |
5707 enum KnownList { | |
5708 ALLOCATION_SITE_LIST | |
5709 }; | |
5710 | |
5711 HLinkObjectInList(HValue* object, HObjectAccess store_field, | |
5712 KnownList known_list) | |
5713 : HUnaryOperation(object), | |
5714 store_field_(store_field), | |
5715 known_list_(known_list) { | |
5716 set_representation(Representation::Tagged()); | |
5717 } | |
5718 | |
5719 HObjectAccess store_field() const { return store_field_; } | |
5720 KnownList known_list() const { return known_list_; } | |
5721 | |
5722 virtual Representation RequiredInputRepresentation(int index) { | |
5723 return Representation::Tagged(); | |
5724 } | |
5725 | |
5726 virtual void PrintDataTo(StringStream* stream); | |
5727 | |
5728 DECLARE_CONCRETE_INSTRUCTION(LinkObjectInList) | |
5729 | |
5730 private: | |
5731 HObjectAccess store_field_; | |
5732 KnownList known_list_; | |
5733 }; | |
5734 | |
5735 | |
5736 class HLoadNamedField: public HTemplateInstruction<2> { | 6008 class HLoadNamedField: public HTemplateInstruction<2> { |
5737 public: | 6009 public: |
| 6010 DECLARE_INSTRUCTION_FACTORY_P2(HLoadNamedField, HValue*, HObjectAccess); |
| 6011 DECLARE_INSTRUCTION_FACTORY_P3(HLoadNamedField, HValue*, HObjectAccess, |
| 6012 HValue*); |
| 6013 |
| 6014 HValue* object() { return OperandAt(0); } |
| 6015 HValue* typecheck() { |
| 6016 ASSERT(HasTypeCheck()); |
| 6017 return OperandAt(1); |
| 6018 } |
| 6019 |
| 6020 bool HasTypeCheck() const { return OperandAt(0) != OperandAt(1); } |
| 6021 HObjectAccess access() const { return access_; } |
| 6022 Representation field_representation() const { |
| 6023 return access_.representation(); |
| 6024 } |
| 6025 |
| 6026 virtual bool HasEscapingOperandAt(int index) { return false; } |
| 6027 virtual Representation RequiredInputRepresentation(int index) { |
| 6028 if (index == 0 && access().IsExternalMemory()) { |
| 6029 // object must be external in case of external memory access |
| 6030 return Representation::External(); |
| 6031 } |
| 6032 return Representation::Tagged(); |
| 6033 } |
| 6034 virtual Range* InferRange(Zone* zone); |
| 6035 virtual void PrintDataTo(StringStream* stream); |
| 6036 |
| 6037 DECLARE_CONCRETE_INSTRUCTION(LoadNamedField) |
| 6038 |
| 6039 protected: |
| 6040 virtual bool DataEquals(HValue* other) { |
| 6041 HLoadNamedField* b = HLoadNamedField::cast(other); |
| 6042 return access_.Equals(b->access_); |
| 6043 } |
| 6044 |
| 6045 private: |
5738 HLoadNamedField(HValue* object, | 6046 HLoadNamedField(HValue* object, |
5739 HObjectAccess access, | 6047 HObjectAccess access, |
5740 HValue* typecheck = NULL) | 6048 HValue* typecheck = NULL) |
5741 : access_(access) { | 6049 : access_(access) { |
5742 ASSERT(object != NULL); | 6050 ASSERT(object != NULL); |
5743 SetOperandAt(0, object); | 6051 SetOperandAt(0, object); |
5744 SetOperandAt(1, typecheck != NULL ? typecheck : object); | 6052 SetOperandAt(1, typecheck != NULL ? typecheck : object); |
5745 | 6053 |
5746 Representation representation = access.representation(); | 6054 Representation representation = access.representation(); |
5747 if (representation.IsSmi()) { | 6055 if (representation.IsSmi()) { |
5748 set_type(HType::Smi()); | 6056 set_type(HType::Smi()); |
5749 set_representation(representation); | 6057 set_representation(representation); |
5750 } else if (representation.IsDouble()) { | 6058 } else if (representation.IsDouble() || |
| 6059 representation.IsExternal() || |
| 6060 representation.IsInteger32()) { |
5751 set_representation(representation); | 6061 set_representation(representation); |
5752 } else if (FLAG_track_heap_object_fields && | 6062 } else if (FLAG_track_heap_object_fields && |
5753 representation.IsHeapObject()) { | 6063 representation.IsHeapObject()) { |
5754 set_type(HType::NonPrimitive()); | 6064 set_type(HType::NonPrimitive()); |
5755 set_representation(Representation::Tagged()); | 6065 set_representation(Representation::Tagged()); |
5756 } else { | 6066 } else { |
5757 set_representation(Representation::Tagged()); | 6067 set_representation(Representation::Tagged()); |
5758 } | 6068 } |
5759 access.SetGVNFlags(this, false); | 6069 access.SetGVNFlags(this, false); |
5760 } | 6070 } |
5761 | 6071 |
5762 HValue* object() { return OperandAt(0); } | |
5763 HValue* typecheck() { | |
5764 ASSERT(HasTypeCheck()); | |
5765 return OperandAt(1); | |
5766 } | |
5767 | |
5768 bool HasTypeCheck() const { return OperandAt(0) != OperandAt(1); } | |
5769 HObjectAccess access() const { return access_; } | |
5770 Representation field_representation() const { | |
5771 return access_.representation(); | |
5772 } | |
5773 | |
5774 virtual bool HasEscapingOperandAt(int index) { return false; } | |
5775 virtual Representation RequiredInputRepresentation(int index) { | |
5776 return Representation::Tagged(); | |
5777 } | |
5778 virtual void PrintDataTo(StringStream* stream); | |
5779 | |
5780 DECLARE_CONCRETE_INSTRUCTION(LoadNamedField) | |
5781 | |
5782 protected: | |
5783 virtual bool DataEquals(HValue* other) { | |
5784 HLoadNamedField* b = HLoadNamedField::cast(other); | |
5785 return access_.Equals(b->access_); | |
5786 } | |
5787 | |
5788 private: | |
5789 virtual bool IsDeletable() const { return true; } | 6072 virtual bool IsDeletable() const { return true; } |
5790 | 6073 |
5791 HObjectAccess access_; | 6074 HObjectAccess access_; |
5792 }; | 6075 }; |
5793 | 6076 |
5794 | 6077 |
5795 class HLoadNamedFieldPolymorphic: public HTemplateInstruction<2> { | 6078 class HLoadNamedFieldPolymorphic: public HTemplateInstruction<2> { |
5796 public: | 6079 public: |
5797 HLoadNamedFieldPolymorphic(HValue* context, | 6080 HLoadNamedFieldPolymorphic(HValue* context, |
5798 HValue* object, | 6081 HValue* object, |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5897 | 6180 |
5898 enum LoadKeyedHoleMode { | 6181 enum LoadKeyedHoleMode { |
5899 NEVER_RETURN_HOLE, | 6182 NEVER_RETURN_HOLE, |
5900 ALLOW_RETURN_HOLE | 6183 ALLOW_RETURN_HOLE |
5901 }; | 6184 }; |
5902 | 6185 |
5903 | 6186 |
5904 class HLoadKeyed | 6187 class HLoadKeyed |
5905 : public HTemplateInstruction<3>, public ArrayInstructionInterface { | 6188 : public HTemplateInstruction<3>, public ArrayInstructionInterface { |
5906 public: | 6189 public: |
5907 HLoadKeyed(HValue* obj, | 6190 DECLARE_INSTRUCTION_FACTORY_P4(HLoadKeyed, HValue*, HValue*, HValue*, |
5908 HValue* key, | 6191 ElementsKind); |
5909 HValue* dependency, | 6192 DECLARE_INSTRUCTION_FACTORY_P5(HLoadKeyed, HValue*, HValue*, HValue*, |
5910 ElementsKind elements_kind, | 6193 ElementsKind, LoadKeyedHoleMode); |
5911 LoadKeyedHoleMode mode = NEVER_RETURN_HOLE) | |
5912 : bit_field_(0) { | |
5913 bit_field_ = ElementsKindField::encode(elements_kind) | | |
5914 HoleModeField::encode(mode); | |
5915 | |
5916 SetOperandAt(0, obj); | |
5917 SetOperandAt(1, key); | |
5918 SetOperandAt(2, dependency != NULL ? dependency : obj); | |
5919 | |
5920 if (!is_external()) { | |
5921 // I can detect the case between storing double (holey and fast) and | |
5922 // smi/object by looking at elements_kind_. | |
5923 ASSERT(IsFastSmiOrObjectElementsKind(elements_kind) || | |
5924 IsFastDoubleElementsKind(elements_kind)); | |
5925 | |
5926 if (IsFastSmiOrObjectElementsKind(elements_kind)) { | |
5927 if (IsFastSmiElementsKind(elements_kind) && | |
5928 (!IsHoleyElementsKind(elements_kind) || | |
5929 mode == NEVER_RETURN_HOLE)) { | |
5930 set_type(HType::Smi()); | |
5931 set_representation(Representation::Smi()); | |
5932 } else { | |
5933 set_representation(Representation::Tagged()); | |
5934 } | |
5935 | |
5936 SetGVNFlag(kDependsOnArrayElements); | |
5937 } else { | |
5938 set_representation(Representation::Double()); | |
5939 SetGVNFlag(kDependsOnDoubleArrayElements); | |
5940 } | |
5941 } else { | |
5942 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS || | |
5943 elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { | |
5944 set_representation(Representation::Double()); | |
5945 } else { | |
5946 set_representation(Representation::Integer32()); | |
5947 } | |
5948 | |
5949 SetGVNFlag(kDependsOnSpecializedArrayElements); | |
5950 // Native code could change the specialized array. | |
5951 SetGVNFlag(kDependsOnCalls); | |
5952 } | |
5953 | |
5954 SetFlag(kUseGVN); | |
5955 } | |
5956 | 6194 |
5957 bool is_external() const { | 6195 bool is_external() const { |
5958 return IsExternalArrayElementsKind(elements_kind()); | 6196 return IsExternalArrayElementsKind(elements_kind()); |
5959 } | 6197 } |
5960 HValue* elements() { return OperandAt(0); } | 6198 HValue* elements() { return OperandAt(0); } |
5961 HValue* key() { return OperandAt(1); } | 6199 HValue* key() { return OperandAt(1); } |
5962 HValue* dependency() { | 6200 HValue* dependency() { |
5963 ASSERT(HasDependency()); | 6201 ASSERT(HasDependency()); |
5964 return OperandAt(2); | 6202 return OperandAt(2); |
5965 } | 6203 } |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6014 virtual bool DataEquals(HValue* other) { | 6252 virtual bool DataEquals(HValue* other) { |
6015 if (!other->IsLoadKeyed()) return false; | 6253 if (!other->IsLoadKeyed()) return false; |
6016 HLoadKeyed* other_load = HLoadKeyed::cast(other); | 6254 HLoadKeyed* other_load = HLoadKeyed::cast(other); |
6017 | 6255 |
6018 if (IsDehoisted() && index_offset() != other_load->index_offset()) | 6256 if (IsDehoisted() && index_offset() != other_load->index_offset()) |
6019 return false; | 6257 return false; |
6020 return elements_kind() == other_load->elements_kind(); | 6258 return elements_kind() == other_load->elements_kind(); |
6021 } | 6259 } |
6022 | 6260 |
6023 private: | 6261 private: |
| 6262 HLoadKeyed(HValue* obj, |
| 6263 HValue* key, |
| 6264 HValue* dependency, |
| 6265 ElementsKind elements_kind, |
| 6266 LoadKeyedHoleMode mode = NEVER_RETURN_HOLE) |
| 6267 : bit_field_(0) { |
| 6268 bit_field_ = ElementsKindField::encode(elements_kind) | |
| 6269 HoleModeField::encode(mode); |
| 6270 |
| 6271 SetOperandAt(0, obj); |
| 6272 SetOperandAt(1, key); |
| 6273 SetOperandAt(2, dependency != NULL ? dependency : obj); |
| 6274 |
| 6275 if (!is_external()) { |
| 6276 // I can detect the case between storing double (holey and fast) and |
| 6277 // smi/object by looking at elements_kind_. |
| 6278 ASSERT(IsFastSmiOrObjectElementsKind(elements_kind) || |
| 6279 IsFastDoubleElementsKind(elements_kind)); |
| 6280 |
| 6281 if (IsFastSmiOrObjectElementsKind(elements_kind)) { |
| 6282 if (IsFastSmiElementsKind(elements_kind) && |
| 6283 (!IsHoleyElementsKind(elements_kind) || |
| 6284 mode == NEVER_RETURN_HOLE)) { |
| 6285 set_type(HType::Smi()); |
| 6286 set_representation(Representation::Smi()); |
| 6287 } else { |
| 6288 set_representation(Representation::Tagged()); |
| 6289 } |
| 6290 |
| 6291 SetGVNFlag(kDependsOnArrayElements); |
| 6292 } else { |
| 6293 set_representation(Representation::Double()); |
| 6294 SetGVNFlag(kDependsOnDoubleArrayElements); |
| 6295 } |
| 6296 } else { |
| 6297 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS || |
| 6298 elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { |
| 6299 set_representation(Representation::Double()); |
| 6300 } else { |
| 6301 set_representation(Representation::Integer32()); |
| 6302 } |
| 6303 |
| 6304 SetGVNFlag(kDependsOnExternalMemory); |
| 6305 // Native code could change the specialized array. |
| 6306 SetGVNFlag(kDependsOnCalls); |
| 6307 } |
| 6308 |
| 6309 SetFlag(kUseGVN); |
| 6310 } |
| 6311 |
6024 virtual bool IsDeletable() const { | 6312 virtual bool IsDeletable() const { |
6025 return !RequiresHoleCheck(); | 6313 return !RequiresHoleCheck(); |
6026 } | 6314 } |
6027 | 6315 |
6028 // Establish some checks around our packed fields | 6316 // Establish some checks around our packed fields |
6029 enum LoadKeyedBits { | 6317 enum LoadKeyedBits { |
6030 kBitsForElementsKind = 5, | 6318 kBitsForElementsKind = 5, |
6031 kBitsForHoleMode = 1, | 6319 kBitsForHoleMode = 1, |
6032 kBitsForIndexOffset = 25, | 6320 kBitsForIndexOffset = 25, |
6033 kBitsForIsDehoisted = 1, | 6321 kBitsForIsDehoisted = 1, |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6079 } | 6367 } |
6080 | 6368 |
6081 virtual HValue* Canonicalize(); | 6369 virtual HValue* Canonicalize(); |
6082 | 6370 |
6083 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedGeneric) | 6371 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedGeneric) |
6084 }; | 6372 }; |
6085 | 6373 |
6086 | 6374 |
6087 class HStoreNamedField: public HTemplateInstruction<2> { | 6375 class HStoreNamedField: public HTemplateInstruction<2> { |
6088 public: | 6376 public: |
6089 HStoreNamedField(HValue* obj, | 6377 DECLARE_INSTRUCTION_FACTORY_P3(HStoreNamedField, HValue*, |
6090 HObjectAccess access, | 6378 HObjectAccess, HValue*); |
6091 HValue* val) | |
6092 : access_(access), | |
6093 transition_(), | |
6094 transition_unique_id_(), | |
6095 new_space_dominator_(NULL), | |
6096 write_barrier_mode_(UPDATE_WRITE_BARRIER) { | |
6097 SetOperandAt(0, obj); | |
6098 SetOperandAt(1, val); | |
6099 access.SetGVNFlags(this, true); | |
6100 } | |
6101 | 6379 |
6102 DECLARE_CONCRETE_INSTRUCTION(StoreNamedField) | 6380 DECLARE_CONCRETE_INSTRUCTION(StoreNamedField) |
6103 | 6381 |
6104 virtual bool HasEscapingOperandAt(int index) { return index == 1; } | 6382 virtual bool HasEscapingOperandAt(int index) { return index == 1; } |
6105 virtual Representation RequiredInputRepresentation(int index) { | 6383 virtual Representation RequiredInputRepresentation(int index) { |
6106 if (index == 1 && field_representation().IsDouble()) { | 6384 if (index == 0 && access().IsExternalMemory()) { |
6107 return field_representation(); | 6385 // object must be external in case of external memory access |
6108 } else if (index == 1 && field_representation().IsSmi()) { | 6386 return Representation::External(); |
| 6387 } else if (index == 1 && |
| 6388 (field_representation().IsDouble() || |
| 6389 field_representation().IsSmi() || |
| 6390 field_representation().IsInteger32())) { |
6109 return field_representation(); | 6391 return field_representation(); |
6110 } | 6392 } |
6111 return Representation::Tagged(); | 6393 return Representation::Tagged(); |
6112 } | 6394 } |
6113 virtual void HandleSideEffectDominator(GVNFlag side_effect, | 6395 virtual void HandleSideEffectDominator(GVNFlag side_effect, |
6114 HValue* dominator) { | 6396 HValue* dominator) { |
6115 ASSERT(side_effect == kChangesNewSpacePromotion); | 6397 ASSERT(side_effect == kChangesNewSpacePromotion); |
6116 new_space_dominator_ = dominator; | 6398 new_space_dominator_ = dominator; |
6117 } | 6399 } |
6118 virtual void PrintDataTo(StringStream* stream); | 6400 virtual void PrintDataTo(StringStream* stream); |
(...skipping 17 matching lines...) Expand all Loading... |
6136 transition_ = map; | 6418 transition_ = map; |
6137 } | 6419 } |
6138 HValue* new_space_dominator() const { return new_space_dominator_; } | 6420 HValue* new_space_dominator() const { return new_space_dominator_; } |
6139 | 6421 |
6140 bool NeedsWriteBarrier() { | 6422 bool NeedsWriteBarrier() { |
6141 ASSERT(!(FLAG_track_double_fields && field_representation().IsDouble()) || | 6423 ASSERT(!(FLAG_track_double_fields && field_representation().IsDouble()) || |
6142 transition_.is_null()); | 6424 transition_.is_null()); |
6143 if (IsSkipWriteBarrier()) return false; | 6425 if (IsSkipWriteBarrier()) return false; |
6144 if (field_representation().IsDouble()) return false; | 6426 if (field_representation().IsDouble()) return false; |
6145 if (field_representation().IsSmi()) return false; | 6427 if (field_representation().IsSmi()) return false; |
| 6428 if (field_representation().IsInteger32()) return false; |
| 6429 if (field_representation().IsExternal()) return false; |
6146 return StoringValueNeedsWriteBarrier(value()) && | 6430 return StoringValueNeedsWriteBarrier(value()) && |
6147 ReceiverObjectNeedsWriteBarrier(object(), new_space_dominator()); | 6431 ReceiverObjectNeedsWriteBarrier(object(), new_space_dominator()); |
6148 } | 6432 } |
6149 | 6433 |
6150 bool NeedsWriteBarrierForMap() { | 6434 bool NeedsWriteBarrierForMap() { |
6151 if (IsSkipWriteBarrier()) return false; | 6435 if (IsSkipWriteBarrier()) return false; |
6152 return ReceiverObjectNeedsWriteBarrier(object(), new_space_dominator()); | 6436 return ReceiverObjectNeedsWriteBarrier(object(), new_space_dominator()); |
6153 } | 6437 } |
6154 | 6438 |
6155 virtual void FinalizeUniqueValueId() { | 6439 virtual void FinalizeUniqueValueId() { |
6156 transition_unique_id_ = UniqueValueId(transition_); | 6440 transition_unique_id_ = UniqueValueId(transition_); |
6157 } | 6441 } |
6158 | 6442 |
6159 Representation field_representation() const { | 6443 Representation field_representation() const { |
6160 return access_.representation(); | 6444 return access_.representation(); |
6161 } | 6445 } |
6162 | 6446 |
6163 private: | 6447 private: |
| 6448 HStoreNamedField(HValue* obj, |
| 6449 HObjectAccess access, |
| 6450 HValue* val) |
| 6451 : access_(access), |
| 6452 transition_(), |
| 6453 transition_unique_id_(), |
| 6454 new_space_dominator_(NULL), |
| 6455 write_barrier_mode_(UPDATE_WRITE_BARRIER) { |
| 6456 SetOperandAt(0, obj); |
| 6457 SetOperandAt(1, val); |
| 6458 access.SetGVNFlags(this, true); |
| 6459 } |
| 6460 |
6164 HObjectAccess access_; | 6461 HObjectAccess access_; |
6165 Handle<Map> transition_; | 6462 Handle<Map> transition_; |
6166 UniqueValueId transition_unique_id_; | 6463 UniqueValueId transition_unique_id_; |
6167 HValue* new_space_dominator_; | 6464 HValue* new_space_dominator_; |
6168 WriteBarrierMode write_barrier_mode_; | 6465 WriteBarrierMode write_barrier_mode_; |
6169 }; | 6466 }; |
6170 | 6467 |
6171 | 6468 |
6172 class HStoreNamedGeneric: public HTemplateInstruction<3> { | 6469 class HStoreNamedGeneric: public HTemplateInstruction<3> { |
6173 public: | 6470 public: |
(...skipping 26 matching lines...) Expand all Loading... |
6200 | 6497 |
6201 private: | 6498 private: |
6202 Handle<String> name_; | 6499 Handle<String> name_; |
6203 StrictModeFlag strict_mode_flag_; | 6500 StrictModeFlag strict_mode_flag_; |
6204 }; | 6501 }; |
6205 | 6502 |
6206 | 6503 |
6207 class HStoreKeyed | 6504 class HStoreKeyed |
6208 : public HTemplateInstruction<3>, public ArrayInstructionInterface { | 6505 : public HTemplateInstruction<3>, public ArrayInstructionInterface { |
6209 public: | 6506 public: |
6210 HStoreKeyed(HValue* obj, HValue* key, HValue* val, | 6507 DECLARE_INSTRUCTION_FACTORY_P4(HStoreKeyed, HValue*, HValue*, HValue*, |
6211 ElementsKind elements_kind) | 6508 ElementsKind); |
6212 : elements_kind_(elements_kind), | |
6213 index_offset_(0), | |
6214 is_dehoisted_(false), | |
6215 is_uninitialized_(false), | |
6216 new_space_dominator_(NULL) { | |
6217 SetOperandAt(0, obj); | |
6218 SetOperandAt(1, key); | |
6219 SetOperandAt(2, val); | |
6220 | |
6221 if (IsFastObjectElementsKind(elements_kind)) { | |
6222 SetFlag(kTrackSideEffectDominators); | |
6223 SetGVNFlag(kDependsOnNewSpacePromotion); | |
6224 } | |
6225 if (is_external()) { | |
6226 SetGVNFlag(kChangesSpecializedArrayElements); | |
6227 SetFlag(kAllowUndefinedAsNaN); | |
6228 } else if (IsFastDoubleElementsKind(elements_kind)) { | |
6229 SetGVNFlag(kChangesDoubleArrayElements); | |
6230 } else if (IsFastSmiElementsKind(elements_kind)) { | |
6231 SetGVNFlag(kChangesArrayElements); | |
6232 } else { | |
6233 SetGVNFlag(kChangesArrayElements); | |
6234 } | |
6235 | |
6236 // EXTERNAL_{UNSIGNED_,}{BYTE,SHORT,INT}_ELEMENTS are truncating. | |
6237 if (elements_kind >= EXTERNAL_BYTE_ELEMENTS && | |
6238 elements_kind <= EXTERNAL_UNSIGNED_INT_ELEMENTS) { | |
6239 SetFlag(kTruncatingToInt32); | |
6240 } | |
6241 } | |
6242 | 6509 |
6243 virtual bool HasEscapingOperandAt(int index) { return index != 0; } | 6510 virtual bool HasEscapingOperandAt(int index) { return index != 0; } |
6244 virtual Representation RequiredInputRepresentation(int index) { | 6511 virtual Representation RequiredInputRepresentation(int index) { |
6245 // kind_fast: tagged[int32] = tagged | 6512 // kind_fast: tagged[int32] = tagged |
6246 // kind_double: tagged[int32] = double | 6513 // kind_double: tagged[int32] = double |
6247 // kind_smi : tagged[int32] = smi | 6514 // kind_smi : tagged[int32] = smi |
6248 // kind_external: external[int32] = (double | int32) | 6515 // kind_external: external[int32] = (double | int32) |
6249 if (index == 0) { | 6516 if (index == 0) { |
6250 return is_external() ? Representation::External() | 6517 return is_external() ? Representation::External() |
6251 : Representation::Tagged(); | 6518 : Representation::Tagged(); |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6328 } | 6595 } |
6329 } | 6596 } |
6330 | 6597 |
6331 bool NeedsCanonicalization(); | 6598 bool NeedsCanonicalization(); |
6332 | 6599 |
6333 virtual void PrintDataTo(StringStream* stream); | 6600 virtual void PrintDataTo(StringStream* stream); |
6334 | 6601 |
6335 DECLARE_CONCRETE_INSTRUCTION(StoreKeyed) | 6602 DECLARE_CONCRETE_INSTRUCTION(StoreKeyed) |
6336 | 6603 |
6337 private: | 6604 private: |
| 6605 HStoreKeyed(HValue* obj, HValue* key, HValue* val, |
| 6606 ElementsKind elements_kind) |
| 6607 : elements_kind_(elements_kind), |
| 6608 index_offset_(0), |
| 6609 is_dehoisted_(false), |
| 6610 is_uninitialized_(false), |
| 6611 new_space_dominator_(NULL) { |
| 6612 SetOperandAt(0, obj); |
| 6613 SetOperandAt(1, key); |
| 6614 SetOperandAt(2, val); |
| 6615 |
| 6616 if (IsFastObjectElementsKind(elements_kind)) { |
| 6617 SetFlag(kTrackSideEffectDominators); |
| 6618 SetGVNFlag(kDependsOnNewSpacePromotion); |
| 6619 } |
| 6620 if (is_external()) { |
| 6621 SetGVNFlag(kChangesExternalMemory); |
| 6622 SetFlag(kAllowUndefinedAsNaN); |
| 6623 } else if (IsFastDoubleElementsKind(elements_kind)) { |
| 6624 SetGVNFlag(kChangesDoubleArrayElements); |
| 6625 } else if (IsFastSmiElementsKind(elements_kind)) { |
| 6626 SetGVNFlag(kChangesArrayElements); |
| 6627 } else { |
| 6628 SetGVNFlag(kChangesArrayElements); |
| 6629 } |
| 6630 |
| 6631 // EXTERNAL_{UNSIGNED_,}{BYTE,SHORT,INT}_ELEMENTS are truncating. |
| 6632 if (elements_kind >= EXTERNAL_BYTE_ELEMENTS && |
| 6633 elements_kind <= EXTERNAL_UNSIGNED_INT_ELEMENTS) { |
| 6634 SetFlag(kTruncatingToInt32); |
| 6635 } |
| 6636 } |
| 6637 |
6338 ElementsKind elements_kind_; | 6638 ElementsKind elements_kind_; |
6339 uint32_t index_offset_; | 6639 uint32_t index_offset_; |
6340 bool is_dehoisted_ : 1; | 6640 bool is_dehoisted_ : 1; |
6341 bool is_uninitialized_ : 1; | 6641 bool is_uninitialized_ : 1; |
6342 HValue* new_space_dominator_; | 6642 HValue* new_space_dominator_; |
6343 }; | 6643 }; |
6344 | 6644 |
6345 | 6645 |
6346 class HStoreKeyedGeneric: public HTemplateInstruction<4> { | 6646 class HStoreKeyedGeneric: public HTemplateInstruction<4> { |
6347 public: | 6647 public: |
(...skipping 25 matching lines...) Expand all Loading... |
6373 | 6673 |
6374 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedGeneric) | 6674 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedGeneric) |
6375 | 6675 |
6376 private: | 6676 private: |
6377 StrictModeFlag strict_mode_flag_; | 6677 StrictModeFlag strict_mode_flag_; |
6378 }; | 6678 }; |
6379 | 6679 |
6380 | 6680 |
6381 class HTransitionElementsKind: public HTemplateInstruction<2> { | 6681 class HTransitionElementsKind: public HTemplateInstruction<2> { |
6382 public: | 6682 public: |
6383 HTransitionElementsKind(HValue* context, | 6683 inline static HTransitionElementsKind* New(Zone* zone, |
6384 HValue* object, | 6684 HValue* context, |
6385 Handle<Map> original_map, | 6685 HValue* object, |
6386 Handle<Map> transitioned_map) | 6686 Handle<Map> original_map, |
6387 : original_map_(original_map), | 6687 Handle<Map> transitioned_map) { |
6388 transitioned_map_(transitioned_map), | 6688 return new(zone) HTransitionElementsKind(context, object, |
6389 original_map_unique_id_(), | 6689 original_map, transitioned_map); |
6390 transitioned_map_unique_id_(), | |
6391 from_kind_(original_map->elements_kind()), | |
6392 to_kind_(transitioned_map->elements_kind()) { | |
6393 SetOperandAt(0, object); | |
6394 SetOperandAt(1, context); | |
6395 SetFlag(kUseGVN); | |
6396 SetGVNFlag(kChangesElementsKind); | |
6397 if (original_map->has_fast_double_elements()) { | |
6398 SetGVNFlag(kChangesElementsPointer); | |
6399 SetGVNFlag(kChangesNewSpacePromotion); | |
6400 } | |
6401 if (transitioned_map->has_fast_double_elements()) { | |
6402 SetGVNFlag(kChangesElementsPointer); | |
6403 SetGVNFlag(kChangesNewSpacePromotion); | |
6404 } | |
6405 set_representation(Representation::Tagged()); | |
6406 } | 6690 } |
6407 | 6691 |
6408 virtual Representation RequiredInputRepresentation(int index) { | 6692 virtual Representation RequiredInputRepresentation(int index) { |
6409 return Representation::Tagged(); | 6693 return Representation::Tagged(); |
6410 } | 6694 } |
6411 | 6695 |
6412 HValue* object() { return OperandAt(0); } | 6696 HValue* object() { return OperandAt(0); } |
6413 HValue* context() { return OperandAt(1); } | 6697 HValue* context() { return OperandAt(1); } |
6414 Handle<Map> original_map() { return original_map_; } | 6698 Handle<Map> original_map() { return original_map_; } |
6415 Handle<Map> transitioned_map() { return transitioned_map_; } | 6699 Handle<Map> transitioned_map() { return transitioned_map_; } |
(...skipping 10 matching lines...) Expand all Loading... |
6426 DECLARE_CONCRETE_INSTRUCTION(TransitionElementsKind) | 6710 DECLARE_CONCRETE_INSTRUCTION(TransitionElementsKind) |
6427 | 6711 |
6428 protected: | 6712 protected: |
6429 virtual bool DataEquals(HValue* other) { | 6713 virtual bool DataEquals(HValue* other) { |
6430 HTransitionElementsKind* instr = HTransitionElementsKind::cast(other); | 6714 HTransitionElementsKind* instr = HTransitionElementsKind::cast(other); |
6431 return original_map_unique_id_ == instr->original_map_unique_id_ && | 6715 return original_map_unique_id_ == instr->original_map_unique_id_ && |
6432 transitioned_map_unique_id_ == instr->transitioned_map_unique_id_; | 6716 transitioned_map_unique_id_ == instr->transitioned_map_unique_id_; |
6433 } | 6717 } |
6434 | 6718 |
6435 private: | 6719 private: |
| 6720 HTransitionElementsKind(HValue* context, |
| 6721 HValue* object, |
| 6722 Handle<Map> original_map, |
| 6723 Handle<Map> transitioned_map) |
| 6724 : original_map_(original_map), |
| 6725 transitioned_map_(transitioned_map), |
| 6726 original_map_unique_id_(), |
| 6727 transitioned_map_unique_id_(), |
| 6728 from_kind_(original_map->elements_kind()), |
| 6729 to_kind_(transitioned_map->elements_kind()) { |
| 6730 SetOperandAt(0, object); |
| 6731 SetOperandAt(1, context); |
| 6732 SetFlag(kUseGVN); |
| 6733 SetGVNFlag(kChangesElementsKind); |
| 6734 if (original_map->has_fast_double_elements()) { |
| 6735 SetGVNFlag(kChangesElementsPointer); |
| 6736 SetGVNFlag(kChangesNewSpacePromotion); |
| 6737 } |
| 6738 if (transitioned_map->has_fast_double_elements()) { |
| 6739 SetGVNFlag(kChangesElementsPointer); |
| 6740 SetGVNFlag(kChangesNewSpacePromotion); |
| 6741 } |
| 6742 set_representation(Representation::Tagged()); |
| 6743 } |
| 6744 |
6436 Handle<Map> original_map_; | 6745 Handle<Map> original_map_; |
6437 Handle<Map> transitioned_map_; | 6746 Handle<Map> transitioned_map_; |
6438 UniqueValueId original_map_unique_id_; | 6747 UniqueValueId original_map_unique_id_; |
6439 UniqueValueId transitioned_map_unique_id_; | 6748 UniqueValueId transitioned_map_unique_id_; |
6440 ElementsKind from_kind_; | 6749 ElementsKind from_kind_; |
6441 ElementsKind to_kind_; | 6750 ElementsKind to_kind_; |
6442 }; | 6751 }; |
6443 | 6752 |
6444 | 6753 |
6445 class HStringAdd: public HBinaryOperation { | 6754 class HStringAdd: public HBinaryOperation { |
6446 public: | 6755 public: |
6447 static HInstruction* New(Zone* zone, | 6756 static HInstruction* New(Zone* zone, |
6448 HValue* context, | 6757 HValue* context, |
6449 HValue* left, | 6758 HValue* left, |
6450 HValue* right, | 6759 HValue* right, |
6451 StringAddFlags flags = STRING_ADD_CHECK_NONE); | 6760 StringAddFlags flags = STRING_ADD_CHECK_NONE); |
6452 | 6761 |
6453 StringAddFlags flags() const { return flags_; } | 6762 StringAddFlags flags() const { return flags_; } |
6454 | 6763 |
6455 virtual Representation RequiredInputRepresentation(int index) { | 6764 virtual Representation RequiredInputRepresentation(int index) { |
6456 return Representation::Tagged(); | 6765 return Representation::Tagged(); |
6457 } | 6766 } |
6458 | 6767 |
6459 virtual HType CalculateInferredType() { | |
6460 return HType::String(); | |
6461 } | |
6462 | |
6463 DECLARE_CONCRETE_INSTRUCTION(StringAdd) | 6768 DECLARE_CONCRETE_INSTRUCTION(StringAdd) |
6464 | 6769 |
6465 protected: | 6770 protected: |
6466 virtual bool DataEquals(HValue* other) { return true; } | 6771 virtual bool DataEquals(HValue* other) { return true; } |
6467 | 6772 |
6468 private: | 6773 private: |
6469 HStringAdd(HValue* context, HValue* left, HValue* right, StringAddFlags flags) | 6774 HStringAdd(HValue* context, HValue* left, HValue* right, StringAddFlags flags) |
6470 : HBinaryOperation(context, left, right), flags_(flags) { | 6775 : HBinaryOperation(context, left, right, HType::String()), flags_(flags) { |
6471 set_representation(Representation::Tagged()); | 6776 set_representation(Representation::Tagged()); |
6472 SetFlag(kUseGVN); | 6777 SetFlag(kUseGVN); |
6473 SetGVNFlag(kDependsOnMaps); | 6778 SetGVNFlag(kDependsOnMaps); |
6474 SetGVNFlag(kChangesNewSpacePromotion); | 6779 SetGVNFlag(kChangesNewSpacePromotion); |
6475 } | 6780 } |
6476 | 6781 |
6477 // TODO(svenpanne) Might be safe, but leave it out until we know for sure. | 6782 // No side-effects except possible allocation. |
6478 // virtual bool IsDeletable() const { return true; } | 6783 // NOTE: this instruction _does not_ call ToString() on its inputs. |
| 6784 virtual bool IsDeletable() const { return true; } |
6479 | 6785 |
6480 const StringAddFlags flags_; | 6786 const StringAddFlags flags_; |
6481 }; | 6787 }; |
6482 | 6788 |
6483 | 6789 |
6484 class HStringCharCodeAt: public HTemplateInstruction<3> { | 6790 class HStringCharCodeAt: public HTemplateInstruction<3> { |
6485 public: | 6791 public: |
6486 HStringCharCodeAt(HValue* context, HValue* string, HValue* index) { | 6792 static HStringCharCodeAt* New(Zone* zone, |
6487 SetOperandAt(0, context); | 6793 HValue* context, |
6488 SetOperandAt(1, string); | 6794 HValue* string, |
6489 SetOperandAt(2, index); | 6795 HValue* index) { |
6490 set_representation(Representation::Integer32()); | 6796 return new(zone) HStringCharCodeAt(context, string, index); |
6491 SetFlag(kUseGVN); | |
6492 SetGVNFlag(kDependsOnMaps); | |
6493 SetGVNFlag(kChangesNewSpacePromotion); | |
6494 } | 6797 } |
6495 | 6798 |
6496 virtual Representation RequiredInputRepresentation(int index) { | 6799 virtual Representation RequiredInputRepresentation(int index) { |
6497 // The index is supposed to be Integer32. | 6800 // The index is supposed to be Integer32. |
6498 return index == 2 | 6801 return index == 2 |
6499 ? Representation::Integer32() | 6802 ? Representation::Integer32() |
6500 : Representation::Tagged(); | 6803 : Representation::Tagged(); |
6501 } | 6804 } |
6502 | 6805 |
6503 HValue* context() { return OperandAt(0); } | 6806 HValue* context() const { return OperandAt(0); } |
6504 HValue* string() { return OperandAt(1); } | 6807 HValue* string() const { return OperandAt(1); } |
6505 HValue* index() { return OperandAt(2); } | 6808 HValue* index() const { return OperandAt(2); } |
6506 | 6809 |
6507 DECLARE_CONCRETE_INSTRUCTION(StringCharCodeAt) | 6810 DECLARE_CONCRETE_INSTRUCTION(StringCharCodeAt) |
6508 | 6811 |
6509 protected: | 6812 protected: |
6510 virtual bool DataEquals(HValue* other) { return true; } | 6813 virtual bool DataEquals(HValue* other) { return true; } |
6511 | 6814 |
6512 virtual Range* InferRange(Zone* zone) { | 6815 virtual Range* InferRange(Zone* zone) { |
6513 return new(zone) Range(0, String::kMaxUtf16CodeUnit); | 6816 return new(zone) Range(0, String::kMaxUtf16CodeUnit); |
6514 } | 6817 } |
6515 | 6818 |
6516 // TODO(svenpanne) Might be safe, but leave it out until we know for sure. | 6819 private: |
6517 // private: | 6820 HStringCharCodeAt(HValue* context, HValue* string, HValue* index) { |
6518 // virtual bool IsDeletable() const { return true; } | 6821 SetOperandAt(0, context); |
| 6822 SetOperandAt(1, string); |
| 6823 SetOperandAt(2, index); |
| 6824 set_representation(Representation::Integer32()); |
| 6825 SetFlag(kUseGVN); |
| 6826 SetGVNFlag(kDependsOnMaps); |
| 6827 SetGVNFlag(kChangesNewSpacePromotion); |
| 6828 } |
| 6829 |
| 6830 // No side effects: runtime function assumes string + number inputs. |
| 6831 virtual bool IsDeletable() const { return true; } |
6519 }; | 6832 }; |
6520 | 6833 |
6521 | 6834 |
6522 class HStringCharFromCode: public HTemplateInstruction<2> { | 6835 class HStringCharFromCode: public HTemplateInstruction<2> { |
6523 public: | 6836 public: |
6524 static HInstruction* New(Zone* zone, | 6837 static HInstruction* New(Zone* zone, |
6525 HValue* context, | 6838 HValue* context, |
6526 HValue* char_code); | 6839 HValue* char_code); |
6527 | 6840 |
6528 virtual Representation RequiredInputRepresentation(int index) { | 6841 virtual Representation RequiredInputRepresentation(int index) { |
6529 return index == 0 | 6842 return index == 0 |
6530 ? Representation::Tagged() | 6843 ? Representation::Tagged() |
6531 : Representation::Integer32(); | 6844 : Representation::Integer32(); |
6532 } | 6845 } |
6533 virtual HType CalculateInferredType(); | |
6534 | 6846 |
6535 HValue* context() { return OperandAt(0); } | 6847 HValue* context() const { return OperandAt(0); } |
6536 HValue* value() { return OperandAt(1); } | 6848 HValue* value() const { return OperandAt(1); } |
6537 | 6849 |
6538 virtual bool DataEquals(HValue* other) { return true; } | 6850 virtual bool DataEquals(HValue* other) { return true; } |
6539 | 6851 |
6540 DECLARE_CONCRETE_INSTRUCTION(StringCharFromCode) | 6852 DECLARE_CONCRETE_INSTRUCTION(StringCharFromCode) |
6541 | 6853 |
6542 private: | 6854 private: |
6543 HStringCharFromCode(HValue* context, HValue* char_code) { | 6855 HStringCharFromCode(HValue* context, HValue* char_code) |
| 6856 : HTemplateInstruction<2>(HType::String()) { |
6544 SetOperandAt(0, context); | 6857 SetOperandAt(0, context); |
6545 SetOperandAt(1, char_code); | 6858 SetOperandAt(1, char_code); |
6546 set_representation(Representation::Tagged()); | 6859 set_representation(Representation::Tagged()); |
6547 SetFlag(kUseGVN); | 6860 SetFlag(kUseGVN); |
6548 SetGVNFlag(kChangesNewSpacePromotion); | 6861 SetGVNFlag(kChangesNewSpacePromotion); |
6549 } | 6862 } |
6550 | 6863 |
6551 // TODO(svenpanne) Might be safe, but leave it out until we know for sure. | 6864 virtual bool IsDeletable() const { |
6552 // virtual bool IsDeletable() const { return true; } | 6865 return !value()->ToNumberCanBeObserved(); |
| 6866 } |
6553 }; | 6867 }; |
6554 | 6868 |
6555 | 6869 |
6556 class HStringLength: public HUnaryOperation { | |
6557 public: | |
6558 static HInstruction* New(Zone* zone, HValue* string); | |
6559 | |
6560 virtual Representation RequiredInputRepresentation(int index) { | |
6561 return Representation::Tagged(); | |
6562 } | |
6563 | |
6564 virtual HType CalculateInferredType() { | |
6565 STATIC_ASSERT(String::kMaxLength <= Smi::kMaxValue); | |
6566 return HType::Smi(); | |
6567 } | |
6568 | |
6569 DECLARE_CONCRETE_INSTRUCTION(StringLength) | |
6570 | |
6571 protected: | |
6572 virtual bool DataEquals(HValue* other) { return true; } | |
6573 | |
6574 virtual Range* InferRange(Zone* zone) { | |
6575 return new(zone) Range(0, String::kMaxLength); | |
6576 } | |
6577 | |
6578 private: | |
6579 explicit HStringLength(HValue* string) : HUnaryOperation(string) { | |
6580 set_representation(Representation::Tagged()); | |
6581 SetFlag(kUseGVN); | |
6582 SetGVNFlag(kDependsOnMaps); | |
6583 } | |
6584 | |
6585 virtual bool IsDeletable() const { return true; } | |
6586 }; | |
6587 | |
6588 | |
6589 template <int V> | 6870 template <int V> |
6590 class HMaterializedLiteral: public HTemplateInstruction<V> { | 6871 class HMaterializedLiteral: public HTemplateInstruction<V> { |
6591 public: | 6872 public: |
6592 HMaterializedLiteral<V>(int index, int depth, AllocationSiteMode mode) | 6873 HMaterializedLiteral<V>(int index, int depth, AllocationSiteMode mode) |
6593 : literal_index_(index), depth_(depth), allocation_site_mode_(mode) { | 6874 : literal_index_(index), depth_(depth), allocation_site_mode_(mode) { |
6594 this->set_representation(Representation::Tagged()); | 6875 this->set_representation(Representation::Tagged()); |
6595 } | 6876 } |
6596 | 6877 |
6597 HMaterializedLiteral<V>(int index, int depth) | 6878 HMaterializedLiteral<V>(int index, int depth) |
6598 : literal_index_(index), depth_(depth), | 6879 : literal_index_(index), depth_(depth), |
(...skipping 22 matching lines...) Expand all Loading... |
6621 Handle<FixedArray> literals, | 6902 Handle<FixedArray> literals, |
6622 Handle<String> pattern, | 6903 Handle<String> pattern, |
6623 Handle<String> flags, | 6904 Handle<String> flags, |
6624 int literal_index) | 6905 int literal_index) |
6625 : HMaterializedLiteral<1>(literal_index, 0), | 6906 : HMaterializedLiteral<1>(literal_index, 0), |
6626 literals_(literals), | 6907 literals_(literals), |
6627 pattern_(pattern), | 6908 pattern_(pattern), |
6628 flags_(flags) { | 6909 flags_(flags) { |
6629 SetOperandAt(0, context); | 6910 SetOperandAt(0, context); |
6630 SetAllSideEffects(); | 6911 SetAllSideEffects(); |
| 6912 set_type(HType::JSObject()); |
6631 } | 6913 } |
6632 | 6914 |
6633 HValue* context() { return OperandAt(0); } | 6915 HValue* context() { return OperandAt(0); } |
6634 Handle<FixedArray> literals() { return literals_; } | 6916 Handle<FixedArray> literals() { return literals_; } |
6635 Handle<String> pattern() { return pattern_; } | 6917 Handle<String> pattern() { return pattern_; } |
6636 Handle<String> flags() { return flags_; } | 6918 Handle<String> flags() { return flags_; } |
6637 | 6919 |
6638 virtual Representation RequiredInputRepresentation(int index) { | 6920 virtual Representation RequiredInputRepresentation(int index) { |
6639 return Representation::Tagged(); | 6921 return Representation::Tagged(); |
6640 } | 6922 } |
6641 virtual HType CalculateInferredType(); | |
6642 | 6923 |
6643 DECLARE_CONCRETE_INSTRUCTION(RegExpLiteral) | 6924 DECLARE_CONCRETE_INSTRUCTION(RegExpLiteral) |
6644 | 6925 |
6645 private: | 6926 private: |
6646 Handle<FixedArray> literals_; | 6927 Handle<FixedArray> literals_; |
6647 Handle<String> pattern_; | 6928 Handle<String> pattern_; |
6648 Handle<String> flags_; | 6929 Handle<String> flags_; |
6649 }; | 6930 }; |
6650 | 6931 |
6651 | 6932 |
6652 class HFunctionLiteral: public HTemplateInstruction<1> { | 6933 class HFunctionLiteral: public HTemplateInstruction<1> { |
6653 public: | 6934 public: |
6654 HFunctionLiteral(HValue* context, | 6935 HFunctionLiteral(HValue* context, |
6655 Handle<SharedFunctionInfo> shared, | 6936 Handle<SharedFunctionInfo> shared, |
6656 bool pretenure) | 6937 bool pretenure) |
6657 : shared_info_(shared), | 6938 : HTemplateInstruction<1>(HType::JSObject()), |
| 6939 shared_info_(shared), |
6658 pretenure_(pretenure), | 6940 pretenure_(pretenure), |
6659 has_no_literals_(shared->num_literals() == 0), | 6941 has_no_literals_(shared->num_literals() == 0), |
6660 is_generator_(shared->is_generator()), | 6942 is_generator_(shared->is_generator()), |
6661 language_mode_(shared->language_mode()) { | 6943 language_mode_(shared->language_mode()) { |
6662 SetOperandAt(0, context); | 6944 SetOperandAt(0, context); |
6663 set_representation(Representation::Tagged()); | 6945 set_representation(Representation::Tagged()); |
6664 SetGVNFlag(kChangesNewSpacePromotion); | 6946 SetGVNFlag(kChangesNewSpacePromotion); |
6665 } | 6947 } |
6666 | 6948 |
6667 HValue* context() { return OperandAt(0); } | 6949 HValue* context() { return OperandAt(0); } |
6668 | 6950 |
6669 virtual Representation RequiredInputRepresentation(int index) { | 6951 virtual Representation RequiredInputRepresentation(int index) { |
6670 return Representation::Tagged(); | 6952 return Representation::Tagged(); |
6671 } | 6953 } |
6672 virtual HType CalculateInferredType(); | |
6673 | 6954 |
6674 DECLARE_CONCRETE_INSTRUCTION(FunctionLiteral) | 6955 DECLARE_CONCRETE_INSTRUCTION(FunctionLiteral) |
6675 | 6956 |
6676 Handle<SharedFunctionInfo> shared_info() const { return shared_info_; } | 6957 Handle<SharedFunctionInfo> shared_info() const { return shared_info_; } |
6677 bool pretenure() const { return pretenure_; } | 6958 bool pretenure() const { return pretenure_; } |
6678 bool has_no_literals() const { return has_no_literals_; } | 6959 bool has_no_literals() const { return has_no_literals_; } |
6679 bool is_generator() const { return is_generator_; } | 6960 bool is_generator() const { return is_generator_; } |
6680 LanguageMode language_mode() const { return language_mode_; } | 6961 LanguageMode language_mode() const { return language_mode_; } |
6681 | 6962 |
6682 private: | 6963 private: |
(...skipping 26 matching lines...) Expand all Loading... |
6709 | 6990 |
6710 DECLARE_CONCRETE_INSTRUCTION(Typeof) | 6991 DECLARE_CONCRETE_INSTRUCTION(Typeof) |
6711 | 6992 |
6712 private: | 6993 private: |
6713 virtual bool IsDeletable() const { return true; } | 6994 virtual bool IsDeletable() const { return true; } |
6714 }; | 6995 }; |
6715 | 6996 |
6716 | 6997 |
6717 class HTrapAllocationMemento : public HTemplateInstruction<1> { | 6998 class HTrapAllocationMemento : public HTemplateInstruction<1> { |
6718 public: | 6999 public: |
6719 explicit HTrapAllocationMemento(HValue* obj) { | 7000 DECLARE_INSTRUCTION_FACTORY_P1(HTrapAllocationMemento, HValue*); |
6720 SetOperandAt(0, obj); | |
6721 } | |
6722 | 7001 |
6723 virtual Representation RequiredInputRepresentation(int index) { | 7002 virtual Representation RequiredInputRepresentation(int index) { |
6724 return Representation::Tagged(); | 7003 return Representation::Tagged(); |
6725 } | 7004 } |
6726 | 7005 |
6727 HValue* object() { return OperandAt(0); } | 7006 HValue* object() { return OperandAt(0); } |
6728 | 7007 |
6729 DECLARE_CONCRETE_INSTRUCTION(TrapAllocationMemento) | 7008 DECLARE_CONCRETE_INSTRUCTION(TrapAllocationMemento) |
| 7009 |
| 7010 private: |
| 7011 explicit HTrapAllocationMemento(HValue* obj) { |
| 7012 SetOperandAt(0, obj); |
| 7013 } |
6730 }; | 7014 }; |
6731 | 7015 |
6732 | 7016 |
6733 class HToFastProperties: public HUnaryOperation { | 7017 class HToFastProperties: public HUnaryOperation { |
6734 public: | 7018 public: |
| 7019 DECLARE_INSTRUCTION_FACTORY_P1(HToFastProperties, HValue*); |
| 7020 |
| 7021 virtual Representation RequiredInputRepresentation(int index) { |
| 7022 return Representation::Tagged(); |
| 7023 } |
| 7024 |
| 7025 DECLARE_CONCRETE_INSTRUCTION(ToFastProperties) |
| 7026 |
| 7027 private: |
6735 explicit HToFastProperties(HValue* value) : HUnaryOperation(value) { | 7028 explicit HToFastProperties(HValue* value) : HUnaryOperation(value) { |
6736 // This instruction is not marked as having side effects, but | 7029 // This instruction is not marked as having side effects, but |
6737 // changes the map of the input operand. Use it only when creating | 7030 // changes the map of the input operand. Use it only when creating |
6738 // object literals via a runtime call. | 7031 // object literals via a runtime call. |
6739 ASSERT(value->IsCallRuntime()); | 7032 ASSERT(value->IsCallRuntime()); |
6740 #ifdef DEBUG | 7033 #ifdef DEBUG |
6741 const Runtime::Function* function = HCallRuntime::cast(value)->function(); | 7034 const Runtime::Function* function = HCallRuntime::cast(value)->function(); |
6742 ASSERT(function->function_id == Runtime::kCreateObjectLiteral || | 7035 ASSERT(function->function_id == Runtime::kCreateObjectLiteral || |
6743 function->function_id == Runtime::kCreateObjectLiteralShallow); | 7036 function->function_id == Runtime::kCreateObjectLiteralShallow); |
6744 #endif | 7037 #endif |
6745 set_representation(Representation::Tagged()); | 7038 set_representation(Representation::Tagged()); |
6746 } | 7039 } |
6747 | 7040 |
6748 virtual Representation RequiredInputRepresentation(int index) { | |
6749 return Representation::Tagged(); | |
6750 } | |
6751 | |
6752 DECLARE_CONCRETE_INSTRUCTION(ToFastProperties) | |
6753 | |
6754 private: | |
6755 virtual bool IsDeletable() const { return true; } | 7041 virtual bool IsDeletable() const { return true; } |
6756 }; | 7042 }; |
6757 | 7043 |
6758 | 7044 |
6759 class HValueOf: public HUnaryOperation { | 7045 class HValueOf: public HUnaryOperation { |
6760 public: | 7046 public: |
6761 explicit HValueOf(HValue* value) : HUnaryOperation(value) { | 7047 explicit HValueOf(HValue* value) : HUnaryOperation(value) { |
6762 set_representation(Representation::Tagged()); | 7048 set_representation(Representation::Tagged()); |
6763 } | 7049 } |
6764 | 7050 |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6817 | 7103 |
6818 DECLARE_CONCRETE_INSTRUCTION(SeqStringSetChar) | 7104 DECLARE_CONCRETE_INSTRUCTION(SeqStringSetChar) |
6819 | 7105 |
6820 private: | 7106 private: |
6821 String::Encoding encoding_; | 7107 String::Encoding encoding_; |
6822 }; | 7108 }; |
6823 | 7109 |
6824 | 7110 |
6825 class HCheckMapValue: public HTemplateInstruction<2> { | 7111 class HCheckMapValue: public HTemplateInstruction<2> { |
6826 public: | 7112 public: |
6827 HCheckMapValue(HValue* value, | 7113 DECLARE_INSTRUCTION_FACTORY_P2(HCheckMapValue, HValue*, HValue*); |
6828 HValue* map) { | |
6829 SetOperandAt(0, value); | |
6830 SetOperandAt(1, map); | |
6831 set_representation(Representation::Tagged()); | |
6832 SetFlag(kUseGVN); | |
6833 SetGVNFlag(kDependsOnMaps); | |
6834 SetGVNFlag(kDependsOnElementsKind); | |
6835 } | |
6836 | 7114 |
6837 virtual Representation RequiredInputRepresentation(int index) { | 7115 virtual Representation RequiredInputRepresentation(int index) { |
6838 return Representation::Tagged(); | 7116 return Representation::Tagged(); |
6839 } | 7117 } |
6840 | 7118 |
6841 virtual void PrintDataTo(StringStream* stream); | 7119 virtual void PrintDataTo(StringStream* stream); |
6842 | 7120 |
6843 virtual HType CalculateInferredType() { | 7121 virtual HType CalculateInferredType() { |
6844 return HType::Tagged(); | 7122 return HType::Tagged(); |
6845 } | 7123 } |
6846 | 7124 |
6847 HValue* value() { return OperandAt(0); } | 7125 HValue* value() { return OperandAt(0); } |
6848 HValue* map() { return OperandAt(1); } | 7126 HValue* map() { return OperandAt(1); } |
6849 | 7127 |
6850 DECLARE_CONCRETE_INSTRUCTION(CheckMapValue) | 7128 DECLARE_CONCRETE_INSTRUCTION(CheckMapValue) |
6851 | 7129 |
6852 protected: | 7130 protected: |
6853 virtual bool DataEquals(HValue* other) { | 7131 virtual bool DataEquals(HValue* other) { |
6854 return true; | 7132 return true; |
6855 } | 7133 } |
| 7134 |
| 7135 private: |
| 7136 HCheckMapValue(HValue* value, |
| 7137 HValue* map) { |
| 7138 SetOperandAt(0, value); |
| 7139 SetOperandAt(1, map); |
| 7140 set_representation(Representation::Tagged()); |
| 7141 SetFlag(kUseGVN); |
| 7142 SetGVNFlag(kDependsOnMaps); |
| 7143 SetGVNFlag(kDependsOnElementsKind); |
| 7144 } |
6856 }; | 7145 }; |
6857 | 7146 |
6858 | 7147 |
6859 class HForInPrepareMap : public HTemplateInstruction<2> { | 7148 class HForInPrepareMap : public HTemplateInstruction<2> { |
6860 public: | 7149 public: |
6861 HForInPrepareMap(HValue* context, | 7150 static HForInPrepareMap* New(Zone* zone, |
6862 HValue* object) { | 7151 HValue* context, |
6863 SetOperandAt(0, context); | 7152 HValue* object) { |
6864 SetOperandAt(1, object); | 7153 return new(zone) HForInPrepareMap(context, object); |
6865 set_representation(Representation::Tagged()); | |
6866 SetAllSideEffects(); | |
6867 } | 7154 } |
6868 | 7155 |
6869 virtual Representation RequiredInputRepresentation(int index) { | 7156 virtual Representation RequiredInputRepresentation(int index) { |
6870 return Representation::Tagged(); | 7157 return Representation::Tagged(); |
6871 } | 7158 } |
6872 | 7159 |
6873 HValue* context() { return OperandAt(0); } | 7160 HValue* context() { return OperandAt(0); } |
6874 HValue* enumerable() { return OperandAt(1); } | 7161 HValue* enumerable() { return OperandAt(1); } |
6875 | 7162 |
6876 virtual void PrintDataTo(StringStream* stream); | 7163 virtual void PrintDataTo(StringStream* stream); |
6877 | 7164 |
6878 virtual HType CalculateInferredType() { | 7165 virtual HType CalculateInferredType() { |
6879 return HType::Tagged(); | 7166 return HType::Tagged(); |
6880 } | 7167 } |
6881 | 7168 |
6882 DECLARE_CONCRETE_INSTRUCTION(ForInPrepareMap); | 7169 DECLARE_CONCRETE_INSTRUCTION(ForInPrepareMap); |
| 7170 |
| 7171 private: |
| 7172 HForInPrepareMap(HValue* context, |
| 7173 HValue* object) { |
| 7174 SetOperandAt(0, context); |
| 7175 SetOperandAt(1, object); |
| 7176 set_representation(Representation::Tagged()); |
| 7177 SetAllSideEffects(); |
| 7178 } |
6883 }; | 7179 }; |
6884 | 7180 |
6885 | 7181 |
6886 class HForInCacheArray : public HTemplateInstruction<2> { | 7182 class HForInCacheArray : public HTemplateInstruction<2> { |
6887 public: | 7183 public: |
6888 HForInCacheArray(HValue* enumerable, | 7184 DECLARE_INSTRUCTION_FACTORY_P3(HForInCacheArray, HValue*, HValue*, int); |
6889 HValue* keys, | |
6890 int idx) : idx_(idx) { | |
6891 SetOperandAt(0, enumerable); | |
6892 SetOperandAt(1, keys); | |
6893 set_representation(Representation::Tagged()); | |
6894 } | |
6895 | 7185 |
6896 virtual Representation RequiredInputRepresentation(int index) { | 7186 virtual Representation RequiredInputRepresentation(int index) { |
6897 return Representation::Tagged(); | 7187 return Representation::Tagged(); |
6898 } | 7188 } |
6899 | 7189 |
6900 HValue* enumerable() { return OperandAt(0); } | 7190 HValue* enumerable() { return OperandAt(0); } |
6901 HValue* map() { return OperandAt(1); } | 7191 HValue* map() { return OperandAt(1); } |
6902 int idx() { return idx_; } | 7192 int idx() { return idx_; } |
6903 | 7193 |
6904 HForInCacheArray* index_cache() { | 7194 HForInCacheArray* index_cache() { |
6905 return index_cache_; | 7195 return index_cache_; |
6906 } | 7196 } |
6907 | 7197 |
6908 void set_index_cache(HForInCacheArray* index_cache) { | 7198 void set_index_cache(HForInCacheArray* index_cache) { |
6909 index_cache_ = index_cache; | 7199 index_cache_ = index_cache; |
6910 } | 7200 } |
6911 | 7201 |
6912 virtual void PrintDataTo(StringStream* stream); | 7202 virtual void PrintDataTo(StringStream* stream); |
6913 | 7203 |
6914 virtual HType CalculateInferredType() { | 7204 virtual HType CalculateInferredType() { |
6915 return HType::Tagged(); | 7205 return HType::Tagged(); |
6916 } | 7206 } |
6917 | 7207 |
6918 DECLARE_CONCRETE_INSTRUCTION(ForInCacheArray); | 7208 DECLARE_CONCRETE_INSTRUCTION(ForInCacheArray); |
6919 | 7209 |
6920 private: | 7210 private: |
| 7211 HForInCacheArray(HValue* enumerable, |
| 7212 HValue* keys, |
| 7213 int idx) : idx_(idx) { |
| 7214 SetOperandAt(0, enumerable); |
| 7215 SetOperandAt(1, keys); |
| 7216 set_representation(Representation::Tagged()); |
| 7217 } |
| 7218 |
6921 int idx_; | 7219 int idx_; |
6922 HForInCacheArray* index_cache_; | 7220 HForInCacheArray* index_cache_; |
6923 }; | 7221 }; |
6924 | 7222 |
6925 | 7223 |
6926 class HLoadFieldByIndex : public HTemplateInstruction<2> { | 7224 class HLoadFieldByIndex : public HTemplateInstruction<2> { |
6927 public: | 7225 public: |
6928 HLoadFieldByIndex(HValue* object, | 7226 HLoadFieldByIndex(HValue* object, |
6929 HValue* index) { | 7227 HValue* index) { |
6930 SetOperandAt(0, object); | 7228 SetOperandAt(0, object); |
(...skipping 20 matching lines...) Expand all Loading... |
6951 virtual bool IsDeletable() const { return true; } | 7249 virtual bool IsDeletable() const { return true; } |
6952 }; | 7250 }; |
6953 | 7251 |
6954 | 7252 |
6955 #undef DECLARE_INSTRUCTION | 7253 #undef DECLARE_INSTRUCTION |
6956 #undef DECLARE_CONCRETE_INSTRUCTION | 7254 #undef DECLARE_CONCRETE_INSTRUCTION |
6957 | 7255 |
6958 } } // namespace v8::internal | 7256 } } // namespace v8::internal |
6959 | 7257 |
6960 #endif // V8_HYDROGEN_INSTRUCTIONS_H_ | 7258 #endif // V8_HYDROGEN_INSTRUCTIONS_H_ |
OLD | NEW |