| 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 |