| 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 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 204 V(BackingStoreFields) \ | 204 V(BackingStoreFields) \ |
| 205 V(Calls) \ | 205 V(Calls) \ |
| 206 V(ContextSlots) \ | 206 V(ContextSlots) \ |
| 207 V(DoubleArrayElements) \ | 207 V(DoubleArrayElements) \ |
| 208 V(DoubleFields) \ | 208 V(DoubleFields) \ |
| 209 V(ElementsKind) \ | 209 V(ElementsKind) \ |
| 210 V(ElementsPointer) \ | 210 V(ElementsPointer) \ |
| 211 V(GlobalVars) \ | 211 V(GlobalVars) \ |
| 212 V(InobjectFields) \ | 212 V(InobjectFields) \ |
| 213 V(OsrEntries) \ | 213 V(OsrEntries) \ |
| 214 V(ExternalMemory) | 214 V(SpecializedArrayElements) |
| 215 | 215 |
| 216 | 216 |
| 217 #define DECLARE_ABSTRACT_INSTRUCTION(type) \ | 217 #define DECLARE_ABSTRACT_INSTRUCTION(type) \ |
| 218 virtual bool Is##type() const { return true; } \ | 218 virtual bool Is##type() const { return true; } \ |
| 219 static H##type* cast(HValue* value) { \ | 219 static H##type* cast(HValue* value) { \ |
| 220 ASSERT(value->Is##type()); \ | 220 ASSERT(value->Is##type()); \ |
| 221 return reinterpret_cast<H##type*>(value); \ | 221 return reinterpret_cast<H##type*>(value); \ |
| 222 } | 222 } |
| 223 | 223 |
| 224 | 224 |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 343 return reinterpret_cast<intptr_t>(raw_address_); | 343 return reinterpret_cast<intptr_t>(raw_address_); |
| 344 } | 344 } |
| 345 | 345 |
| 346 private: | 346 private: |
| 347 Address raw_address_; | 347 Address raw_address_; |
| 348 }; | 348 }; |
| 349 | 349 |
| 350 | 350 |
| 351 class HType { | 351 class HType { |
| 352 public: | 352 public: |
| 353 static HType None() { return HType(kNone); } | 353 HType() : type_(kUninitialized) { } |
| 354 |
| 354 static HType Tagged() { return HType(kTagged); } | 355 static HType Tagged() { return HType(kTagged); } |
| 355 static HType TaggedPrimitive() { return HType(kTaggedPrimitive); } | 356 static HType TaggedPrimitive() { return HType(kTaggedPrimitive); } |
| 356 static HType TaggedNumber() { return HType(kTaggedNumber); } | 357 static HType TaggedNumber() { return HType(kTaggedNumber); } |
| 357 static HType Smi() { return HType(kSmi); } | 358 static HType Smi() { return HType(kSmi); } |
| 358 static HType HeapNumber() { return HType(kHeapNumber); } | 359 static HType HeapNumber() { return HType(kHeapNumber); } |
| 359 static HType String() { return HType(kString); } | 360 static HType String() { return HType(kString); } |
| 360 static HType Boolean() { return HType(kBoolean); } | 361 static HType Boolean() { return HType(kBoolean); } |
| 361 static HType NonPrimitive() { return HType(kNonPrimitive); } | 362 static HType NonPrimitive() { return HType(kNonPrimitive); } |
| 362 static HType JSArray() { return HType(kJSArray); } | 363 static HType JSArray() { return HType(kJSArray); } |
| 363 static HType JSObject() { return HType(kJSObject); } | 364 static HType JSObject() { return HType(kJSObject); } |
| 365 static HType Uninitialized() { return HType(kUninitialized); } |
| 364 | 366 |
| 365 // Return the weakest (least precise) common type. | 367 // Return the weakest (least precise) common type. |
| 366 HType Combine(HType other) { | 368 HType Combine(HType other) { |
| 367 return HType(static_cast<Type>(type_ & other.type_)); | 369 return HType(static_cast<Type>(type_ & other.type_)); |
| 368 } | 370 } |
| 369 | 371 |
| 370 bool Equals(const HType& other) const { | 372 bool Equals(const HType& other) const { |
| 371 return type_ == other.type_; | 373 return type_ == other.type_; |
| 372 } | 374 } |
| 373 | 375 |
| 374 bool IsSubtypeOf(const HType& other) { | 376 bool IsSubtypeOf(const HType& other) { |
| 375 return Combine(other).Equals(other); | 377 return Combine(other).Equals(other); |
| 376 } | 378 } |
| 377 | 379 |
| 378 bool IsTagged() const { | 380 bool IsTagged() const { |
| 381 ASSERT(type_ != kUninitialized); |
| 379 return ((type_ & kTagged) == kTagged); | 382 return ((type_ & kTagged) == kTagged); |
| 380 } | 383 } |
| 381 | 384 |
| 382 bool IsTaggedPrimitive() const { | 385 bool IsTaggedPrimitive() const { |
| 386 ASSERT(type_ != kUninitialized); |
| 383 return ((type_ & kTaggedPrimitive) == kTaggedPrimitive); | 387 return ((type_ & kTaggedPrimitive) == kTaggedPrimitive); |
| 384 } | 388 } |
| 385 | 389 |
| 386 bool IsTaggedNumber() const { | 390 bool IsTaggedNumber() const { |
| 391 ASSERT(type_ != kUninitialized); |
| 387 return ((type_ & kTaggedNumber) == kTaggedNumber); | 392 return ((type_ & kTaggedNumber) == kTaggedNumber); |
| 388 } | 393 } |
| 389 | 394 |
| 390 bool IsSmi() const { | 395 bool IsSmi() const { |
| 396 ASSERT(type_ != kUninitialized); |
| 391 return ((type_ & kSmi) == kSmi); | 397 return ((type_ & kSmi) == kSmi); |
| 392 } | 398 } |
| 393 | 399 |
| 394 bool IsHeapNumber() const { | 400 bool IsHeapNumber() const { |
| 401 ASSERT(type_ != kUninitialized); |
| 395 return ((type_ & kHeapNumber) == kHeapNumber); | 402 return ((type_ & kHeapNumber) == kHeapNumber); |
| 396 } | 403 } |
| 397 | 404 |
| 398 bool IsString() const { | 405 bool IsString() const { |
| 406 ASSERT(type_ != kUninitialized); |
| 399 return ((type_ & kString) == kString); | 407 return ((type_ & kString) == kString); |
| 400 } | 408 } |
| 401 | 409 |
| 402 bool IsNonString() const { | 410 bool IsNonString() const { |
| 403 return IsTaggedPrimitive() || IsSmi() || IsHeapNumber() || | 411 return IsTaggedPrimitive() || IsSmi() || IsHeapNumber() || |
| 404 IsBoolean() || IsJSArray(); | 412 IsBoolean() || IsJSArray(); |
| 405 } | 413 } |
| 406 | 414 |
| 407 bool IsBoolean() const { | 415 bool IsBoolean() const { |
| 416 ASSERT(type_ != kUninitialized); |
| 408 return ((type_ & kBoolean) == kBoolean); | 417 return ((type_ & kBoolean) == kBoolean); |
| 409 } | 418 } |
| 410 | 419 |
| 411 bool IsNonPrimitive() const { | 420 bool IsNonPrimitive() const { |
| 421 ASSERT(type_ != kUninitialized); |
| 412 return ((type_ & kNonPrimitive) == kNonPrimitive); | 422 return ((type_ & kNonPrimitive) == kNonPrimitive); |
| 413 } | 423 } |
| 414 | 424 |
| 415 bool IsJSArray() const { | 425 bool IsJSArray() const { |
| 426 ASSERT(type_ != kUninitialized); |
| 416 return ((type_ & kJSArray) == kJSArray); | 427 return ((type_ & kJSArray) == kJSArray); |
| 417 } | 428 } |
| 418 | 429 |
| 419 bool IsJSObject() const { | 430 bool IsJSObject() const { |
| 431 ASSERT(type_ != kUninitialized); |
| 420 return ((type_ & kJSObject) == kJSObject); | 432 return ((type_ & kJSObject) == kJSObject); |
| 421 } | 433 } |
| 422 | 434 |
| 435 bool IsUninitialized() const { |
| 436 return type_ == kUninitialized; |
| 437 } |
| 438 |
| 423 bool IsHeapObject() const { | 439 bool IsHeapObject() const { |
| 440 ASSERT(type_ != kUninitialized); |
| 424 return IsHeapNumber() || IsString() || IsBoolean() || IsNonPrimitive(); | 441 return IsHeapNumber() || IsString() || IsBoolean() || IsNonPrimitive(); |
| 425 } | 442 } |
| 426 | 443 |
| 427 bool ToStringOrToNumberCanBeObserved(Representation representation) { | |
| 428 switch (type_) { | |
| 429 case kTaggedPrimitive: // fallthru | |
| 430 case kTaggedNumber: // fallthru | |
| 431 case kSmi: // fallthru | |
| 432 case kHeapNumber: // fallthru | |
| 433 case kString: // fallthru | |
| 434 case kBoolean: | |
| 435 return false; | |
| 436 case kJSArray: // fallthru | |
| 437 case kJSObject: | |
| 438 return true; | |
| 439 case kTagged: | |
| 440 break; | |
| 441 } | |
| 442 return !representation.IsSmiOrInteger32() && !representation.IsDouble(); | |
| 443 } | |
| 444 | |
| 445 static HType TypeFromValue(Handle<Object> value); | 444 static HType TypeFromValue(Handle<Object> value); |
| 446 | 445 |
| 447 const char* ToString(); | 446 const char* ToString(); |
| 448 | 447 |
| 449 private: | 448 private: |
| 450 enum Type { | 449 enum Type { |
| 451 kNone = 0x0, // 0000 0000 0000 0000 | |
| 452 kTagged = 0x1, // 0000 0000 0000 0001 | 450 kTagged = 0x1, // 0000 0000 0000 0001 |
| 453 kTaggedPrimitive = 0x5, // 0000 0000 0000 0101 | 451 kTaggedPrimitive = 0x5, // 0000 0000 0000 0101 |
| 454 kTaggedNumber = 0xd, // 0000 0000 0000 1101 | 452 kTaggedNumber = 0xd, // 0000 0000 0000 1101 |
| 455 kSmi = 0x1d, // 0000 0000 0001 1101 | 453 kSmi = 0x1d, // 0000 0000 0001 1101 |
| 456 kHeapNumber = 0x2d, // 0000 0000 0010 1101 | 454 kHeapNumber = 0x2d, // 0000 0000 0010 1101 |
| 457 kString = 0x45, // 0000 0000 0100 0101 | 455 kString = 0x45, // 0000 0000 0100 0101 |
| 458 kBoolean = 0x85, // 0000 0000 1000 0101 | 456 kBoolean = 0x85, // 0000 0000 1000 0101 |
| 459 kNonPrimitive = 0x101, // 0000 0001 0000 0001 | 457 kNonPrimitive = 0x101, // 0000 0001 0000 0001 |
| 460 kJSObject = 0x301, // 0000 0011 0000 0001 | 458 kJSObject = 0x301, // 0000 0011 0000 0001 |
| 461 kJSArray = 0x701 // 0000 0111 0000 0001 | 459 kJSArray = 0x701, // 0000 0111 0000 0001 |
| 460 kUninitialized = 0x1fff // 0001 1111 1111 1111 |
| 462 }; | 461 }; |
| 463 | 462 |
| 464 // Make sure type fits in int16. | 463 // Make sure type fits in int16. |
| 465 STATIC_ASSERT(kJSArray < (1 << (2 * kBitsPerByte))); | 464 STATIC_ASSERT(kUninitialized < (1 << (2 * kBitsPerByte))); |
| 466 | 465 |
| 467 explicit HType(Type t) : type_(t) { } | 466 explicit HType(Type t) : type_(t) { } |
| 468 | 467 |
| 469 int16_t type_; | 468 int16_t type_; |
| 470 }; | 469 }; |
| 471 | 470 |
| 472 | 471 |
| 473 class HUseListNode: public ZoneObject { | 472 class HUseListNode: public ZoneObject { |
| 474 public: | 473 public: |
| 475 HUseListNode(HValue* value, int index, HUseListNode* tail) | 474 HUseListNode(HValue* value, int index, HUseListNode* tail) |
| (...skipping 663 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1139 | 1138 |
| 1140 bool TryGuaranteeRange(HValue* upper_bound); | 1139 bool TryGuaranteeRange(HValue* upper_bound); |
| 1141 virtual bool TryDecompose(DecompositionResult* decomposition) { | 1140 virtual bool TryDecompose(DecompositionResult* decomposition) { |
| 1142 if (RedefinedOperand() != NULL) { | 1141 if (RedefinedOperand() != NULL) { |
| 1143 return RedefinedOperand()->TryDecompose(decomposition); | 1142 return RedefinedOperand()->TryDecompose(decomposition); |
| 1144 } else { | 1143 } else { |
| 1145 return false; | 1144 return false; |
| 1146 } | 1145 } |
| 1147 } | 1146 } |
| 1148 | 1147 |
| 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 | |
| 1161 protected: | 1148 protected: |
| 1162 void TryGuaranteeRangeRecursive(RangeEvaluationContext* context); | 1149 void TryGuaranteeRangeRecursive(RangeEvaluationContext* context); |
| 1163 | 1150 |
| 1164 enum RangeGuaranteeDirection { | 1151 enum RangeGuaranteeDirection { |
| 1165 DIRECTION_NONE = 0, | 1152 DIRECTION_NONE = 0, |
| 1166 DIRECTION_UPPER = 1, | 1153 DIRECTION_UPPER = 1, |
| 1167 DIRECTION_LOWER = 2, | 1154 DIRECTION_LOWER = 2, |
| 1168 DIRECTION_BOTH = DIRECTION_UPPER | DIRECTION_LOWER | 1155 DIRECTION_BOTH = DIRECTION_UPPER | DIRECTION_LOWER |
| 1169 }; | 1156 }; |
| 1170 virtual void SetResponsibilityForRange(RangeGuaranteeDirection direction) {} | 1157 virtual void SetResponsibilityForRange(RangeGuaranteeDirection direction) {} |
| (...skipping 1517 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2688 // change. The external array of a specialized array elements object cannot | 2675 // change. The external array of a specialized array elements object cannot |
| 2689 // change once set, so it's no necessary to introduce any additional | 2676 // change once set, so it's no necessary to introduce any additional |
| 2690 // dependencies on top of the inputs. | 2677 // dependencies on top of the inputs. |
| 2691 SetFlag(kUseGVN); | 2678 SetFlag(kUseGVN); |
| 2692 } | 2679 } |
| 2693 | 2680 |
| 2694 virtual Representation RequiredInputRepresentation(int index) { | 2681 virtual Representation RequiredInputRepresentation(int index) { |
| 2695 return Representation::Tagged(); | 2682 return Representation::Tagged(); |
| 2696 } | 2683 } |
| 2697 | 2684 |
| 2698 virtual HType CalculateInferredType() { | |
| 2699 return HType::None(); | |
| 2700 } | |
| 2701 | |
| 2702 DECLARE_CONCRETE_INSTRUCTION(LoadExternalArrayPointer) | 2685 DECLARE_CONCRETE_INSTRUCTION(LoadExternalArrayPointer) |
| 2703 | 2686 |
| 2704 protected: | 2687 protected: |
| 2705 virtual bool DataEquals(HValue* other) { return true; } | 2688 virtual bool DataEquals(HValue* other) { return true; } |
| 2706 | 2689 |
| 2707 private: | 2690 private: |
| 2708 virtual bool IsDeletable() const { return true; } | 2691 virtual bool IsDeletable() const { return true; } |
| 2709 }; | 2692 }; |
| 2710 | 2693 |
| 2711 | 2694 |
| (...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2947 return Representation::Tagged(); | 2930 return Representation::Tagged(); |
| 2948 } | 2931 } |
| 2949 | 2932 |
| 2950 virtual HType CalculateInferredType(); | 2933 virtual HType CalculateInferredType(); |
| 2951 | 2934 |
| 2952 #ifdef DEBUG | 2935 #ifdef DEBUG |
| 2953 virtual void Verify(); | 2936 virtual void Verify(); |
| 2954 #endif | 2937 #endif |
| 2955 | 2938 |
| 2956 virtual HValue* Canonicalize() { | 2939 virtual HValue* Canonicalize() { |
| 2957 return value()->type().IsHeapObject() ? NULL : this; | 2940 HType value_type = value()->type(); |
| 2941 if (!value_type.IsUninitialized() && value_type.IsHeapObject()) { |
| 2942 return NULL; |
| 2943 } |
| 2944 return this; |
| 2958 } | 2945 } |
| 2959 | 2946 |
| 2960 DECLARE_CONCRETE_INSTRUCTION(CheckHeapObject) | 2947 DECLARE_CONCRETE_INSTRUCTION(CheckHeapObject) |
| 2961 | 2948 |
| 2962 protected: | 2949 protected: |
| 2963 virtual bool DataEquals(HValue* other) { return true; } | 2950 virtual bool DataEquals(HValue* other) { return true; } |
| 2964 }; | 2951 }; |
| 2965 | 2952 |
| 2966 | 2953 |
| 2967 class HCheckPrototypeMaps: public HTemplateInstruction<0> { | 2954 class HCheckPrototypeMaps: public HTemplateInstruction<0> { |
| (...skipping 381 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3349 int phi_id() { return phi_id_; } | 3336 int phi_id() { return phi_id_; } |
| 3350 | 3337 |
| 3351 static HPhi* cast(HValue* value) { | 3338 static HPhi* cast(HValue* value) { |
| 3352 ASSERT(value->IsPhi()); | 3339 ASSERT(value->IsPhi()); |
| 3353 return reinterpret_cast<HPhi*>(value); | 3340 return reinterpret_cast<HPhi*>(value); |
| 3354 } | 3341 } |
| 3355 virtual Opcode opcode() const { return HValue::kPhi; } | 3342 virtual Opcode opcode() const { return HValue::kPhi; } |
| 3356 | 3343 |
| 3357 void SimplifyConstantInputs(); | 3344 void SimplifyConstantInputs(); |
| 3358 | 3345 |
| 3346 // TODO(titzer): we can't eliminate the receiver for generating backtraces |
| 3347 virtual bool IsDeletable() const { return !IsReceiver(); } |
| 3348 |
| 3359 protected: | 3349 protected: |
| 3360 virtual void DeleteFromGraph(); | 3350 virtual void DeleteFromGraph(); |
| 3361 virtual void InternalSetOperandAt(int index, HValue* value) { | 3351 virtual void InternalSetOperandAt(int index, HValue* value) { |
| 3362 inputs_[index] = value; | 3352 inputs_[index] = value; |
| 3363 } | 3353 } |
| 3364 | 3354 |
| 3365 virtual bool IsRelationTrueInternal(NumericRelation relation, | 3355 virtual bool IsRelationTrueInternal(NumericRelation relation, |
| 3366 HValue* other, | 3356 HValue* other, |
| 3367 int offset = 0, | 3357 int offset = 0, |
| 3368 int scale = 0); | 3358 int scale = 0); |
| 3369 | 3359 |
| 3370 private: | 3360 private: |
| 3371 ZoneList<HValue*> inputs_; | 3361 ZoneList<HValue*> inputs_; |
| 3372 int merged_index_; | 3362 int merged_index_; |
| 3373 | 3363 |
| 3374 int non_phi_uses_[Representation::kNumRepresentations]; | 3364 int non_phi_uses_[Representation::kNumRepresentations]; |
| 3375 int indirect_uses_[Representation::kNumRepresentations]; | 3365 int indirect_uses_[Representation::kNumRepresentations]; |
| 3376 int phi_id_; | 3366 int phi_id_; |
| 3377 InductionVariableData* induction_variable_data_; | 3367 InductionVariableData* induction_variable_data_; |
| 3378 | |
| 3379 // TODO(titzer): we can't eliminate the receiver for generating backtraces | |
| 3380 virtual bool IsDeletable() const { return !IsReceiver(); } | |
| 3381 }; | 3368 }; |
| 3382 | 3369 |
| 3383 | 3370 |
| 3384 class HInductionVariableAnnotation : public HUnaryOperation { | 3371 class HInductionVariableAnnotation : public HUnaryOperation { |
| 3385 public: | 3372 public: |
| 3386 static HInductionVariableAnnotation* AddToGraph(HPhi* phi, | 3373 static HInductionVariableAnnotation* AddToGraph(HPhi* phi, |
| 3387 NumericRelation relation, | 3374 NumericRelation relation, |
| 3388 int operand_index); | 3375 int operand_index); |
| 3389 | 3376 |
| 3390 NumericRelation relation() { return relation_; } | 3377 NumericRelation relation() { return relation_; } |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3477 bool is_not_in_new_space = true, | 3464 bool is_not_in_new_space = true, |
| 3478 Handle<Object> optional_handle = Handle<Object>::null()); | 3465 Handle<Object> optional_handle = Handle<Object>::null()); |
| 3479 HConstant(Handle<Object> handle, | 3466 HConstant(Handle<Object> handle, |
| 3480 UniqueValueId unique_id, | 3467 UniqueValueId unique_id, |
| 3481 Representation r, | 3468 Representation r, |
| 3482 HType type, | 3469 HType type, |
| 3483 bool is_internalized_string, | 3470 bool is_internalized_string, |
| 3484 bool is_not_in_new_space, | 3471 bool is_not_in_new_space, |
| 3485 bool is_cell, | 3472 bool is_cell, |
| 3486 bool boolean_value); | 3473 bool boolean_value); |
| 3487 explicit HConstant(ExternalReference reference); | |
| 3488 | 3474 |
| 3489 Handle<Object> handle() { | 3475 Handle<Object> handle() { |
| 3490 if (handle_.is_null()) { | 3476 if (handle_.is_null()) { |
| 3491 Factory* factory = Isolate::Current()->factory(); | 3477 Factory* factory = Isolate::Current()->factory(); |
| 3492 // Default arguments to is_not_in_new_space depend on this heap number | 3478 // Default arguments to is_not_in_new_space depend on this heap number |
| 3493 // to be tenured so that it's guaranteed not be be located in new space. | 3479 // to be tenured so that it's guaranteed not be be located in new space. |
| 3494 handle_ = factory->NewNumber(double_value_, TENURED); | 3480 handle_ = factory->NewNumber(double_value_, TENURED); |
| 3495 } | 3481 } |
| 3496 AllowDeferredHandleDereference smi_check; | 3482 AllowDeferredHandleDereference smi_check; |
| 3497 ASSERT(has_int32_value_ || !handle_->IsSmi()); | 3483 ASSERT(has_int32_value_ || !handle_->IsSmi()); |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3542 } | 3528 } |
| 3543 | 3529 |
| 3544 virtual Representation RequiredInputRepresentation(int index) { | 3530 virtual Representation RequiredInputRepresentation(int index) { |
| 3545 return Representation::None(); | 3531 return Representation::None(); |
| 3546 } | 3532 } |
| 3547 | 3533 |
| 3548 virtual Representation KnownOptimalRepresentation() { | 3534 virtual Representation KnownOptimalRepresentation() { |
| 3549 if (HasSmiValue() && kSmiValueSize == 31) return Representation::Smi(); | 3535 if (HasSmiValue() && kSmiValueSize == 31) return Representation::Smi(); |
| 3550 if (HasInteger32Value()) return Representation::Integer32(); | 3536 if (HasInteger32Value()) return Representation::Integer32(); |
| 3551 if (HasNumberValue()) return Representation::Double(); | 3537 if (HasNumberValue()) return Representation::Double(); |
| 3552 if (HasExternalReferenceValue()) return Representation::External(); | |
| 3553 return Representation::Tagged(); | 3538 return Representation::Tagged(); |
| 3554 } | 3539 } |
| 3555 | 3540 |
| 3556 virtual bool EmitAtUses(); | 3541 virtual bool EmitAtUses(); |
| 3557 virtual void PrintDataTo(StringStream* stream); | 3542 virtual void PrintDataTo(StringStream* stream); |
| 3543 virtual HType CalculateInferredType(); |
| 3558 bool IsInteger() { return handle()->IsSmi(); } | 3544 bool IsInteger() { return handle()->IsSmi(); } |
| 3559 HConstant* CopyToRepresentation(Representation r, Zone* zone) const; | 3545 HConstant* CopyToRepresentation(Representation r, Zone* zone) const; |
| 3560 Maybe<HConstant*> CopyToTruncatedInt32(Zone* zone); | 3546 Maybe<HConstant*> CopyToTruncatedInt32(Zone* zone); |
| 3561 Maybe<HConstant*> CopyToTruncatedNumber(Zone* zone); | 3547 Maybe<HConstant*> CopyToTruncatedNumber(Zone* zone); |
| 3562 bool HasInteger32Value() const { return has_int32_value_; } | 3548 bool HasInteger32Value() const { return has_int32_value_; } |
| 3563 int32_t Integer32Value() const { | 3549 int32_t Integer32Value() const { |
| 3564 ASSERT(HasInteger32Value()); | 3550 ASSERT(HasInteger32Value()); |
| 3565 return int32_value_; | 3551 return int32_value_; |
| 3566 } | 3552 } |
| 3567 bool HasSmiValue() const { return has_smi_value_; } | 3553 bool HasSmiValue() const { return has_smi_value_; } |
| (...skipping 16 matching lines...) Expand all Loading... |
| 3584 int32_t NumberValueAsInteger32() const { | 3570 int32_t NumberValueAsInteger32() const { |
| 3585 ASSERT(HasNumberValue()); | 3571 ASSERT(HasNumberValue()); |
| 3586 // Irrespective of whether a numeric HConstant can be safely | 3572 // Irrespective of whether a numeric HConstant can be safely |
| 3587 // represented as an int32, we store the (in some cases lossy) | 3573 // represented as an int32, we store the (in some cases lossy) |
| 3588 // representation of the number in int32_value_. | 3574 // representation of the number in int32_value_. |
| 3589 return int32_value_; | 3575 return int32_value_; |
| 3590 } | 3576 } |
| 3591 bool HasStringValue() const { | 3577 bool HasStringValue() const { |
| 3592 if (has_double_value_ || has_int32_value_) return false; | 3578 if (has_double_value_ || has_int32_value_) return false; |
| 3593 ASSERT(!handle_.is_null()); | 3579 ASSERT(!handle_.is_null()); |
| 3594 return type_.IsString(); | 3580 return type_from_value_.IsString(); |
| 3595 } | 3581 } |
| 3596 Handle<String> StringValue() const { | 3582 Handle<String> StringValue() const { |
| 3597 ASSERT(HasStringValue()); | 3583 ASSERT(HasStringValue()); |
| 3598 return Handle<String>::cast(handle_); | 3584 return Handle<String>::cast(handle_); |
| 3599 } | 3585 } |
| 3600 bool HasInternalizedStringValue() const { | 3586 bool HasInternalizedStringValue() const { |
| 3601 return HasStringValue() && is_internalized_string_; | 3587 return HasStringValue() && is_internalized_string_; |
| 3602 } | 3588 } |
| 3603 | 3589 |
| 3604 bool HasExternalReferenceValue() const { | |
| 3605 return has_external_reference_value_; | |
| 3606 } | |
| 3607 ExternalReference ExternalReferenceValue() const { | |
| 3608 return external_reference_value_; | |
| 3609 } | |
| 3610 | |
| 3611 bool BooleanValue() const { return boolean_value_; } | 3590 bool BooleanValue() const { return boolean_value_; } |
| 3612 | 3591 |
| 3613 virtual intptr_t Hashcode() { | 3592 virtual intptr_t Hashcode() { |
| 3614 if (has_int32_value_) { | 3593 if (has_int32_value_) { |
| 3615 return static_cast<intptr_t>(int32_value_); | 3594 return static_cast<intptr_t>(int32_value_); |
| 3616 } else if (has_double_value_) { | 3595 } else if (has_double_value_) { |
| 3617 return static_cast<intptr_t>(BitCast<int64_t>(double_value_)); | 3596 return static_cast<intptr_t>(BitCast<int64_t>(double_value_)); |
| 3618 } else if (has_external_reference_value_) { | |
| 3619 return reinterpret_cast<intptr_t>(external_reference_value_.address()); | |
| 3620 } else { | 3597 } else { |
| 3621 ASSERT(!handle_.is_null()); | 3598 ASSERT(!handle_.is_null()); |
| 3622 return unique_id_.Hashcode(); | 3599 return unique_id_.Hashcode(); |
| 3623 } | 3600 } |
| 3624 } | 3601 } |
| 3625 | 3602 |
| 3626 virtual void FinalizeUniqueValueId() { | 3603 virtual void FinalizeUniqueValueId() { |
| 3627 if (!has_double_value_ && !has_external_reference_value_) { | 3604 if (!has_double_value_) { |
| 3628 ASSERT(!handle_.is_null()); | 3605 ASSERT(!handle_.is_null()); |
| 3629 unique_id_ = UniqueValueId(handle_); | 3606 unique_id_ = UniqueValueId(handle_); |
| 3630 } | 3607 } |
| 3631 } | 3608 } |
| 3632 | 3609 |
| 3633 bool UniqueValueIdsMatch(UniqueValueId other) { | 3610 bool UniqueValueIdsMatch(UniqueValueId other) { |
| 3634 return !has_double_value_ && !has_external_reference_value_ && | 3611 return !has_double_value_ && unique_id_ == other; |
| 3635 unique_id_ == other; | |
| 3636 } | 3612 } |
| 3637 | 3613 |
| 3638 #ifdef DEBUG | 3614 #ifdef DEBUG |
| 3639 virtual void Verify() { } | 3615 virtual void Verify() { } |
| 3640 #endif | 3616 #endif |
| 3641 | 3617 |
| 3642 DECLARE_CONCRETE_INSTRUCTION(Constant) | 3618 DECLARE_CONCRETE_INSTRUCTION(Constant) |
| 3643 | 3619 |
| 3644 protected: | 3620 protected: |
| 3645 virtual Range* InferRange(Zone* zone); | 3621 virtual Range* InferRange(Zone* zone); |
| 3646 | 3622 |
| 3647 virtual bool DataEquals(HValue* other) { | 3623 virtual bool DataEquals(HValue* other) { |
| 3648 HConstant* other_constant = HConstant::cast(other); | 3624 HConstant* other_constant = HConstant::cast(other); |
| 3649 if (has_int32_value_) { | 3625 if (has_int32_value_) { |
| 3650 return other_constant->has_int32_value_ && | 3626 return other_constant->has_int32_value_ && |
| 3651 int32_value_ == other_constant->int32_value_; | 3627 int32_value_ == other_constant->int32_value_; |
| 3652 } else if (has_double_value_) { | 3628 } else if (has_double_value_) { |
| 3653 return other_constant->has_double_value_ && | 3629 return other_constant->has_double_value_ && |
| 3654 BitCast<int64_t>(double_value_) == | 3630 BitCast<int64_t>(double_value_) == |
| 3655 BitCast<int64_t>(other_constant->double_value_); | 3631 BitCast<int64_t>(other_constant->double_value_); |
| 3656 } else if (has_external_reference_value_) { | |
| 3657 return other_constant->has_external_reference_value_ && | |
| 3658 external_reference_value_ == | |
| 3659 other_constant->external_reference_value_; | |
| 3660 } else { | 3632 } else { |
| 3661 ASSERT(!handle_.is_null()); | 3633 ASSERT(!handle_.is_null()); |
| 3662 return !other_constant->handle_.is_null() && | 3634 return !other_constant->handle_.is_null() && |
| 3663 unique_id_ == other_constant->unique_id_; | 3635 unique_id_ == other_constant->unique_id_; |
| 3664 } | 3636 } |
| 3665 } | 3637 } |
| 3666 | 3638 |
| 3667 private: | 3639 private: |
| 3668 void Initialize(Representation r); | 3640 void Initialize(Representation r); |
| 3669 | 3641 |
| 3670 virtual bool IsDeletable() const { return true; } | 3642 virtual bool IsDeletable() const { return true; } |
| 3671 | 3643 |
| 3672 // If this is a numerical constant, handle_ either points to to the | 3644 // If this is a numerical constant, handle_ either points to to the |
| 3673 // HeapObject the constant originated from or is null. If the | 3645 // HeapObject the constant originated from or is null. If the |
| 3674 // constant is non-numeric, handle_ always points to a valid | 3646 // constant is non-numeric, handle_ always points to a valid |
| 3675 // constant HeapObject. | 3647 // constant HeapObject. |
| 3676 Handle<Object> handle_; | 3648 Handle<Object> handle_; |
| 3677 UniqueValueId unique_id_; | 3649 UniqueValueId unique_id_; |
| 3678 | 3650 |
| 3679 // We store the HConstant in the most specific form safely possible. | 3651 // We store the HConstant in the most specific form safely possible. |
| 3680 // The two flags, has_int32_value_ and has_double_value_ tell us if | 3652 // The two flags, has_int32_value_ and has_double_value_ tell us if |
| 3681 // int32_value_ and double_value_ hold valid, safe representations | 3653 // int32_value_ and double_value_ hold valid, safe representations |
| 3682 // of the constant. has_int32_value_ implies has_double_value_ but | 3654 // of the constant. has_int32_value_ implies has_double_value_ but |
| 3683 // not the converse. | 3655 // not the converse. |
| 3684 bool has_smi_value_ : 1; | 3656 bool has_smi_value_ : 1; |
| 3685 bool has_int32_value_ : 1; | 3657 bool has_int32_value_ : 1; |
| 3686 bool has_double_value_ : 1; | 3658 bool has_double_value_ : 1; |
| 3687 bool has_external_reference_value_ : 1; | |
| 3688 bool is_internalized_string_ : 1; // TODO(yangguo): make this part of HType. | 3659 bool is_internalized_string_ : 1; // TODO(yangguo): make this part of HType. |
| 3689 bool is_not_in_new_space_ : 1; | 3660 bool is_not_in_new_space_ : 1; |
| 3690 bool is_cell_ : 1; | 3661 bool is_cell_ : 1; |
| 3691 bool boolean_value_ : 1; | 3662 bool boolean_value_ : 1; |
| 3692 int32_t int32_value_; | 3663 int32_t int32_value_; |
| 3693 double double_value_; | 3664 double double_value_; |
| 3694 ExternalReference external_reference_value_; | 3665 HType type_from_value_; |
| 3695 }; | 3666 }; |
| 3696 | 3667 |
| 3697 | 3668 |
| 3698 class HBinaryOperation: public HTemplateInstruction<3> { | 3669 class HBinaryOperation: public HTemplateInstruction<3> { |
| 3699 public: | 3670 public: |
| 3700 HBinaryOperation(HValue* context, HValue* left, HValue* right) | 3671 HBinaryOperation(HValue* context, HValue* left, HValue* right) |
| 3701 : observed_output_representation_(Representation::None()) { | 3672 : observed_output_representation_(Representation::None()) { |
| 3702 ASSERT(left != NULL && right != NULL); | 3673 ASSERT(left != NULL && right != NULL); |
| 3703 SetOperandAt(0, context); | 3674 SetOperandAt(0, context); |
| 3704 SetOperandAt(1, left); | 3675 SetOperandAt(1, left); |
| 3705 SetOperandAt(2, right); | 3676 SetOperandAt(2, right); |
| 3706 observed_input_representation_[0] = Representation::None(); | 3677 observed_input_representation_[0] = Representation::None(); |
| 3707 observed_input_representation_[1] = Representation::None(); | 3678 observed_input_representation_[1] = Representation::None(); |
| 3708 } | 3679 } |
| 3709 | 3680 |
| 3710 HValue* context() const { return OperandAt(0); } | 3681 HValue* context() { return OperandAt(0); } |
| 3711 HValue* left() const { return OperandAt(1); } | 3682 HValue* left() { return OperandAt(1); } |
| 3712 HValue* right() const { return OperandAt(2); } | 3683 HValue* right() { return OperandAt(2); } |
| 3713 | 3684 |
| 3714 // True if switching left and right operands likely generates better code. | 3685 // True if switching left and right operands likely generates better code. |
| 3715 bool AreOperandsBetterSwitched() { | 3686 bool AreOperandsBetterSwitched() { |
| 3716 if (!IsCommutative()) return false; | 3687 if (!IsCommutative()) return false; |
| 3717 | 3688 |
| 3718 // Constant operands are better off on the right, they can be inlined in | 3689 // Constant operands are better off on the right, they can be inlined in |
| 3719 // many situations on most platforms. | 3690 // many situations on most platforms. |
| 3720 if (left()->IsConstant()) return true; | 3691 if (left()->IsConstant()) return true; |
| 3721 if (right()->IsConstant()) return false; | 3692 if (right()->IsConstant()) return false; |
| 3722 | 3693 |
| (...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3956 base_ = index(); | 3927 base_ = index(); |
| 3957 offset_ = 0; | 3928 offset_ = 0; |
| 3958 scale_ = 0; | 3929 scale_ = 0; |
| 3959 return false; | 3930 return false; |
| 3960 } | 3931 } |
| 3961 } | 3932 } |
| 3962 | 3933 |
| 3963 virtual Representation RequiredInputRepresentation(int arg_index) { | 3934 virtual Representation RequiredInputRepresentation(int arg_index) { |
| 3964 return representation(); | 3935 return representation(); |
| 3965 } | 3936 } |
| 3937 virtual bool IsDeletable() const { |
| 3938 return skip_check() && !FLAG_debug_code; |
| 3939 } |
| 3966 | 3940 |
| 3967 virtual bool IsRelationTrueInternal(NumericRelation relation, | 3941 virtual bool IsRelationTrueInternal(NumericRelation relation, |
| 3968 HValue* related_value, | 3942 HValue* related_value, |
| 3969 int offset = 0, | 3943 int offset = 0, |
| 3970 int scale = 0); | 3944 int scale = 0); |
| 3971 | 3945 |
| 3972 virtual void PrintDataTo(StringStream* stream); | 3946 virtual void PrintDataTo(StringStream* stream); |
| 3973 virtual void InferRepresentation(HInferRepresentationPhase* h_infer); | 3947 virtual void InferRepresentation(HInferRepresentationPhase* h_infer); |
| 3974 | 3948 |
| 3975 HValue* index() { return OperandAt(0); } | 3949 HValue* index() { return OperandAt(0); } |
| (...skipping 16 matching lines...) Expand all Loading... |
| 3992 } | 3966 } |
| 3993 | 3967 |
| 3994 virtual bool DataEquals(HValue* other) { return true; } | 3968 virtual bool DataEquals(HValue* other) { return true; } |
| 3995 virtual void TryGuaranteeRangeChanging(RangeEvaluationContext* context); | 3969 virtual void TryGuaranteeRangeChanging(RangeEvaluationContext* context); |
| 3996 bool skip_check_; | 3970 bool skip_check_; |
| 3997 HValue* base_; | 3971 HValue* base_; |
| 3998 int offset_; | 3972 int offset_; |
| 3999 int scale_; | 3973 int scale_; |
| 4000 RangeGuaranteeDirection responsibility_direction_; | 3974 RangeGuaranteeDirection responsibility_direction_; |
| 4001 bool allow_equality_; | 3975 bool allow_equality_; |
| 4002 | |
| 4003 private: | |
| 4004 virtual bool IsDeletable() const { | |
| 4005 return skip_check() && !FLAG_debug_code; | |
| 4006 } | |
| 4007 }; | 3976 }; |
| 4008 | 3977 |
| 4009 | 3978 |
| 4010 class HBoundsCheckBaseIndexInformation: public HTemplateInstruction<2> { | 3979 class HBoundsCheckBaseIndexInformation: public HTemplateInstruction<2> { |
| 4011 public: | 3980 public: |
| 4012 explicit HBoundsCheckBaseIndexInformation(HBoundsCheck* check) { | 3981 explicit HBoundsCheckBaseIndexInformation(HBoundsCheck* check) { |
| 4013 DecompositionResult decomposition; | 3982 DecompositionResult decomposition; |
| 4014 if (check->index()->TryDecompose(&decomposition)) { | 3983 if (check->index()->TryDecompose(&decomposition)) { |
| 4015 SetOperandAt(0, decomposition.base()); | 3984 SetOperandAt(0, decomposition.base()); |
| 4016 SetOperandAt(1, check); | 3985 SetOperandAt(1, check); |
| (...skipping 799 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4816 | 4785 |
| 4817 virtual Representation observed_input_representation(int index) { | 4786 virtual Representation observed_input_representation(int index) { |
| 4818 return RequiredInputRepresentation(index); | 4787 return RequiredInputRepresentation(index); |
| 4819 } | 4788 } |
| 4820 | 4789 |
| 4821 virtual void InferRepresentation(HInferRepresentationPhase* h_infer); | 4790 virtual void InferRepresentation(HInferRepresentationPhase* h_infer); |
| 4822 | 4791 |
| 4823 virtual Representation RepresentationFromInputs() { | 4792 virtual Representation RepresentationFromInputs() { |
| 4824 Representation left_rep = left()->representation(); | 4793 Representation left_rep = left()->representation(); |
| 4825 Representation right_rep = right()->representation(); | 4794 Representation right_rep = right()->representation(); |
| 4826 Representation result = Representation::Smi(); | 4795 // TODO(verwaest): Initialize to Smi once lithium-codegen has been fixed. |
| 4796 Representation result = Representation::Integer32(); |
| 4827 result = result.generalize(left_rep); | 4797 result = result.generalize(left_rep); |
| 4828 result = result.generalize(right_rep); | 4798 result = result.generalize(right_rep); |
| 4829 if (result.IsTagged()) return Representation::Double(); | 4799 if (result.IsTagged()) return Representation::Double(); |
| 4830 return result; | 4800 return result; |
| 4831 } | 4801 } |
| 4832 | 4802 |
| 4833 virtual bool IsCommutative() const { return true; } | 4803 virtual bool IsCommutative() const { return true; } |
| 4834 | 4804 |
| 4835 Operation operation() { return operation_; } | 4805 Operation operation() { return operation_; } |
| 4836 | 4806 |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4914 static HInstruction* New(Zone* zone, | 4884 static HInstruction* New(Zone* zone, |
| 4915 HValue* context, | 4885 HValue* context, |
| 4916 HValue* left, | 4886 HValue* left, |
| 4917 HValue* right); | 4887 HValue* right); |
| 4918 | 4888 |
| 4919 virtual Range* InferRange(Zone* zone); | 4889 virtual Range* InferRange(Zone* zone); |
| 4920 | 4890 |
| 4921 virtual void UpdateRepresentation(Representation new_rep, | 4891 virtual void UpdateRepresentation(Representation new_rep, |
| 4922 HInferRepresentationPhase* h_infer, | 4892 HInferRepresentationPhase* h_infer, |
| 4923 const char* reason) { | 4893 const char* reason) { |
| 4924 if (new_rep.IsSmi() && | 4894 if (new_rep.IsSmi()) new_rep = Representation::Integer32(); |
| 4925 !(right()->IsInteger32Constant() && | |
| 4926 right()->GetInteger32Constant() >= 0)) { | |
| 4927 new_rep = Representation::Integer32(); | |
| 4928 } | |
| 4929 HBitwiseBinaryOperation::UpdateRepresentation(new_rep, h_infer, reason); | 4895 HBitwiseBinaryOperation::UpdateRepresentation(new_rep, h_infer, reason); |
| 4930 } | 4896 } |
| 4931 | 4897 |
| 4932 DECLARE_CONCRETE_INSTRUCTION(Shl) | 4898 DECLARE_CONCRETE_INSTRUCTION(Shl) |
| 4933 | 4899 |
| 4934 protected: | 4900 protected: |
| 4935 virtual bool DataEquals(HValue* other) { return true; } | 4901 virtual bool DataEquals(HValue* other) { return true; } |
| 4936 | 4902 |
| 4937 private: | 4903 private: |
| 4938 HShl(HValue* context, HValue* left, HValue* right) | 4904 HShl(HValue* context, HValue* left, HValue* right) |
| (...skipping 642 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5581 int slot_index_; | 5547 int slot_index_; |
| 5582 Mode mode_; | 5548 Mode mode_; |
| 5583 }; | 5549 }; |
| 5584 | 5550 |
| 5585 | 5551 |
| 5586 // Represents an access to a portion of an object, such as the map pointer, | 5552 // Represents an access to a portion of an object, such as the map pointer, |
| 5587 // array elements pointer, etc, but not accesses to array elements themselves. | 5553 // array elements pointer, etc, but not accesses to array elements themselves. |
| 5588 class HObjectAccess { | 5554 class HObjectAccess { |
| 5589 public: | 5555 public: |
| 5590 inline bool IsInobject() const { | 5556 inline bool IsInobject() const { |
| 5591 return portion() != kBackingStore && portion() != kExternalMemory; | 5557 return portion() != kBackingStore; |
| 5592 } | |
| 5593 | |
| 5594 inline bool IsExternalMemory() const { | |
| 5595 return portion() == kExternalMemory; | |
| 5596 } | 5558 } |
| 5597 | 5559 |
| 5598 inline int offset() const { | 5560 inline int offset() const { |
| 5599 return OffsetField::decode(value_); | 5561 return OffsetField::decode(value_); |
| 5600 } | 5562 } |
| 5601 | 5563 |
| 5602 inline Representation representation() const { | 5564 inline Representation representation() const { |
| 5603 return Representation::FromKind(RepresentationField::decode(value_)); | 5565 return Representation::FromKind(RepresentationField::decode(value_)); |
| 5604 } | 5566 } |
| 5605 | 5567 |
| 5606 inline Handle<String> name() const { | 5568 inline Handle<String> name() const { |
| 5607 return name_; | 5569 return name_; |
| 5608 } | 5570 } |
| 5609 | 5571 |
| 5610 inline HObjectAccess WithRepresentation(Representation representation) { | 5572 inline HObjectAccess WithRepresentation(Representation representation) { |
| 5611 return HObjectAccess(portion(), offset(), representation, name()); | 5573 return HObjectAccess(portion(), offset(), representation, name()); |
| 5612 } | 5574 } |
| 5613 | 5575 |
| 5614 static HObjectAccess ForHeapNumberValue() { | 5576 static HObjectAccess ForHeapNumberValue() { |
| 5615 return HObjectAccess( | 5577 return HObjectAccess( |
| 5616 kDouble, HeapNumber::kValueOffset, Representation::Double()); | 5578 kDouble, HeapNumber::kValueOffset, Representation::Double()); |
| 5617 } | 5579 } |
| 5618 | 5580 |
| 5619 static HObjectAccess ForElementsPointer() { | 5581 static HObjectAccess ForElementsPointer() { |
| 5620 return HObjectAccess(kElementsPointer, JSObject::kElementsOffset); | 5582 return HObjectAccess(kElementsPointer, JSObject::kElementsOffset); |
| 5621 } | 5583 } |
| 5622 | 5584 |
| 5623 static HObjectAccess ForArrayLength(ElementsKind elements_kind) { | 5585 static HObjectAccess ForArrayLength(ElementsKind elements_kind) { |
| 5624 return HObjectAccess( | 5586 return HObjectAccess( |
| 5625 kArrayLengths, | 5587 kArrayLengths, JSArray::kLengthOffset, |
| 5626 JSArray::kLengthOffset, | 5588 IsFastElementsKind(elements_kind) && FLAG_track_fields ? |
| 5627 IsFastElementsKind(elements_kind) && | 5589 Representation::Smi() : Representation::Tagged()); |
| 5628 FLAG_track_fields | |
| 5629 ? Representation::Smi() : Representation::Tagged()); | |
| 5630 } | 5590 } |
| 5631 | 5591 |
| 5632 static HObjectAccess ForAllocationSiteTransitionInfo() { | 5592 static HObjectAccess ForAllocationSiteTransitionInfo() { |
| 5633 return HObjectAccess(kInobject, AllocationSite::kTransitionInfoOffset); | 5593 return HObjectAccess(kInobject, AllocationSite::kTransitionInfoOffset); |
| 5634 } | 5594 } |
| 5635 | 5595 |
| 5636 static HObjectAccess ForAllocationSiteWeakNext() { | 5596 static HObjectAccess ForAllocationSiteWeakNext() { |
| 5637 return HObjectAccess(kInobject, AllocationSite::kWeakNextOffset); | 5597 return HObjectAccess(kInobject, AllocationSite::kWeakNextOffset); |
| 5638 } | 5598 } |
| 5639 | 5599 |
| 5640 static HObjectAccess ForFixedArrayLength() { | 5600 static HObjectAccess ForFixedArrayLength() { |
| 5641 return HObjectAccess( | 5601 return HObjectAccess( |
| 5642 kArrayLengths, | 5602 kArrayLengths, FixedArray::kLengthOffset, |
| 5643 FixedArray::kLengthOffset, | 5603 FLAG_track_fields ? |
| 5644 FLAG_track_fields ? Representation::Smi() : Representation::Tagged()); | 5604 Representation::Smi() : Representation::Tagged()); |
| 5645 } | 5605 } |
| 5646 | 5606 |
| 5647 static HObjectAccess ForPropertiesPointer() { | 5607 static HObjectAccess ForPropertiesPointer() { |
| 5648 return HObjectAccess(kInobject, JSObject::kPropertiesOffset); | 5608 return HObjectAccess(kInobject, JSObject::kPropertiesOffset); |
| 5649 } | 5609 } |
| 5650 | 5610 |
| 5651 static HObjectAccess ForPrototypeOrInitialMap() { | 5611 static HObjectAccess ForPrototypeOrInitialMap() { |
| 5652 return HObjectAccess(kInobject, JSFunction::kPrototypeOrInitialMapOffset); | 5612 return HObjectAccess(kInobject, JSFunction::kPrototypeOrInitialMapOffset); |
| 5653 } | 5613 } |
| 5654 | 5614 |
| 5655 static HObjectAccess ForMap() { | 5615 static HObjectAccess ForMap() { |
| 5656 return HObjectAccess(kMaps, JSObject::kMapOffset); | 5616 return HObjectAccess(kMaps, JSObject::kMapOffset); |
| 5657 } | 5617 } |
| 5658 | 5618 |
| 5659 static HObjectAccess ForPropertyCellValue() { | 5619 static HObjectAccess ForPropertyCellValue() { |
| 5660 return HObjectAccess(kInobject, PropertyCell::kValueOffset); | 5620 return HObjectAccess(kInobject, PropertyCell::kValueOffset); |
| 5661 } | 5621 } |
| 5662 | 5622 |
| 5663 static HObjectAccess ForCellValue() { | 5623 static HObjectAccess ForCellValue() { |
| 5664 return HObjectAccess(kInobject, Cell::kValueOffset); | 5624 return HObjectAccess(kInobject, Cell::kValueOffset); |
| 5665 } | 5625 } |
| 5666 | 5626 |
| 5667 static HObjectAccess ForAllocationMementoSite() { | 5627 static HObjectAccess ForAllocationMementoSite() { |
| 5668 return HObjectAccess(kInobject, AllocationMemento::kAllocationSiteOffset); | 5628 return HObjectAccess(kInobject, AllocationMemento::kAllocationSiteOffset); |
| 5669 } | 5629 } |
| 5670 | 5630 |
| 5671 static HObjectAccess ForCounter() { | |
| 5672 return HObjectAccess(kExternalMemory, 0, Representation::Integer32()); | |
| 5673 } | |
| 5674 | |
| 5675 // Create an access to an offset in a fixed array header. | 5631 // Create an access to an offset in a fixed array header. |
| 5676 static HObjectAccess ForFixedArrayHeader(int offset); | 5632 static HObjectAccess ForFixedArrayHeader(int offset); |
| 5677 | 5633 |
| 5678 // Create an access to an in-object property in a JSObject. | 5634 // Create an access to an in-object property in a JSObject. |
| 5679 static HObjectAccess ForJSObjectOffset(int offset, | 5635 static HObjectAccess ForJSObjectOffset(int offset, |
| 5680 Representation representation = Representation::Tagged()); | 5636 Representation representation = Representation::Tagged()); |
| 5681 | 5637 |
| 5682 // Create an access to an in-object property in a JSArray. | 5638 // Create an access to an in-object property in a JSArray. |
| 5683 static HObjectAccess ForJSArrayOffset(int offset); | 5639 static HObjectAccess ForJSArrayOffset(int offset); |
| 5684 | 5640 |
| (...skipping 18 matching lines...) Expand all Loading... |
| 5703 void SetGVNFlags(HValue *instr, bool is_store); | 5659 void SetGVNFlags(HValue *instr, bool is_store); |
| 5704 | 5660 |
| 5705 private: | 5661 private: |
| 5706 // internal use only; different parts of an object or array | 5662 // internal use only; different parts of an object or array |
| 5707 enum Portion { | 5663 enum Portion { |
| 5708 kMaps, // map of an object | 5664 kMaps, // map of an object |
| 5709 kArrayLengths, // the length of an array | 5665 kArrayLengths, // the length of an array |
| 5710 kElementsPointer, // elements pointer | 5666 kElementsPointer, // elements pointer |
| 5711 kBackingStore, // some field in the backing store | 5667 kBackingStore, // some field in the backing store |
| 5712 kDouble, // some double field | 5668 kDouble, // some double field |
| 5713 kInobject, // some other in-object field | 5669 kInobject // some other in-object field |
| 5714 kExternalMemory // some field in external memory | |
| 5715 }; | 5670 }; |
| 5716 | 5671 |
| 5717 HObjectAccess(Portion portion, int offset, | 5672 HObjectAccess(Portion portion, int offset, |
| 5718 Representation representation = Representation::Tagged(), | 5673 Representation representation = Representation::Tagged(), |
| 5719 Handle<String> name = Handle<String>::null()) | 5674 Handle<String> name = Handle<String>::null()) |
| 5720 : value_(PortionField::encode(portion) | | 5675 : value_(PortionField::encode(portion) | |
| 5721 RepresentationField::encode(representation.kind()) | | 5676 RepresentationField::encode(representation.kind()) | |
| 5722 OffsetField::encode(offset)), | 5677 OffsetField::encode(offset)), |
| 5723 name_(name) { | 5678 name_(name) { |
| 5724 // assert that the fields decode correctly | 5679 // assert that the fields decode correctly |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5782 HValue* typecheck = NULL) | 5737 HValue* typecheck = NULL) |
| 5783 : access_(access) { | 5738 : access_(access) { |
| 5784 ASSERT(object != NULL); | 5739 ASSERT(object != NULL); |
| 5785 SetOperandAt(0, object); | 5740 SetOperandAt(0, object); |
| 5786 SetOperandAt(1, typecheck != NULL ? typecheck : object); | 5741 SetOperandAt(1, typecheck != NULL ? typecheck : object); |
| 5787 | 5742 |
| 5788 Representation representation = access.representation(); | 5743 Representation representation = access.representation(); |
| 5789 if (representation.IsSmi()) { | 5744 if (representation.IsSmi()) { |
| 5790 set_type(HType::Smi()); | 5745 set_type(HType::Smi()); |
| 5791 set_representation(representation); | 5746 set_representation(representation); |
| 5792 } else if (representation.IsDouble() || | 5747 } else if (representation.IsDouble()) { |
| 5793 representation.IsExternal() || | |
| 5794 representation.IsInteger32()) { | |
| 5795 set_representation(representation); | 5748 set_representation(representation); |
| 5796 } else if (FLAG_track_heap_object_fields && | 5749 } else if (FLAG_track_heap_object_fields && |
| 5797 representation.IsHeapObject()) { | 5750 representation.IsHeapObject()) { |
| 5798 set_type(HType::NonPrimitive()); | 5751 set_type(HType::NonPrimitive()); |
| 5799 set_representation(Representation::Tagged()); | 5752 set_representation(Representation::Tagged()); |
| 5800 } else { | 5753 } else { |
| 5801 set_representation(Representation::Tagged()); | 5754 set_representation(Representation::Tagged()); |
| 5802 } | 5755 } |
| 5803 access.SetGVNFlags(this, false); | 5756 access.SetGVNFlags(this, false); |
| 5804 } | 5757 } |
| 5805 | 5758 |
| 5806 HValue* object() { return OperandAt(0); } | 5759 HValue* object() { return OperandAt(0); } |
| 5807 HValue* typecheck() { | 5760 HValue* typecheck() { |
| 5808 ASSERT(HasTypeCheck()); | 5761 ASSERT(HasTypeCheck()); |
| 5809 return OperandAt(1); | 5762 return OperandAt(1); |
| 5810 } | 5763 } |
| 5811 | 5764 |
| 5812 bool HasTypeCheck() const { return OperandAt(0) != OperandAt(1); } | 5765 bool HasTypeCheck() const { return OperandAt(0) != OperandAt(1); } |
| 5813 HObjectAccess access() const { return access_; } | 5766 HObjectAccess access() const { return access_; } |
| 5814 Representation field_representation() const { | 5767 Representation field_representation() const { |
| 5815 return access_.representation(); | 5768 return access_.representation(); |
| 5816 } | 5769 } |
| 5817 | 5770 |
| 5818 virtual bool HasEscapingOperandAt(int index) { return false; } | 5771 virtual bool HasEscapingOperandAt(int index) { return false; } |
| 5819 virtual Representation RequiredInputRepresentation(int index) { | 5772 virtual Representation RequiredInputRepresentation(int index) { |
| 5820 if (index == 0 && access().IsExternalMemory()) { | |
| 5821 // object must be external in case of external memory access | |
| 5822 return Representation::External(); | |
| 5823 } | |
| 5824 return Representation::Tagged(); | 5773 return Representation::Tagged(); |
| 5825 } | 5774 } |
| 5826 virtual void PrintDataTo(StringStream* stream); | 5775 virtual void PrintDataTo(StringStream* stream); |
| 5827 | 5776 |
| 5828 DECLARE_CONCRETE_INSTRUCTION(LoadNamedField) | 5777 DECLARE_CONCRETE_INSTRUCTION(LoadNamedField) |
| 5829 | 5778 |
| 5830 protected: | 5779 protected: |
| 5831 virtual bool DataEquals(HValue* other) { | 5780 virtual bool DataEquals(HValue* other) { |
| 5832 HLoadNamedField* b = HLoadNamedField::cast(other); | 5781 HLoadNamedField* b = HLoadNamedField::cast(other); |
| 5833 return access_.Equals(b->access_); | 5782 return access_.Equals(b->access_); |
| (...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5987 SetGVNFlag(kDependsOnDoubleArrayElements); | 5936 SetGVNFlag(kDependsOnDoubleArrayElements); |
| 5988 } | 5937 } |
| 5989 } else { | 5938 } else { |
| 5990 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS || | 5939 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS || |
| 5991 elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { | 5940 elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { |
| 5992 set_representation(Representation::Double()); | 5941 set_representation(Representation::Double()); |
| 5993 } else { | 5942 } else { |
| 5994 set_representation(Representation::Integer32()); | 5943 set_representation(Representation::Integer32()); |
| 5995 } | 5944 } |
| 5996 | 5945 |
| 5997 SetGVNFlag(kDependsOnExternalMemory); | 5946 SetGVNFlag(kDependsOnSpecializedArrayElements); |
| 5998 // Native code could change the specialized array. | 5947 // Native code could change the specialized array. |
| 5999 SetGVNFlag(kDependsOnCalls); | 5948 SetGVNFlag(kDependsOnCalls); |
| 6000 } | 5949 } |
| 6001 | 5950 |
| 6002 SetFlag(kUseGVN); | 5951 SetFlag(kUseGVN); |
| 6003 } | 5952 } |
| 6004 | 5953 |
| 6005 bool is_external() const { | 5954 bool is_external() const { |
| 6006 return IsExternalArrayElementsKind(elements_kind()); | 5955 return IsExternalArrayElementsKind(elements_kind()); |
| 6007 } | 5956 } |
| (...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6144 write_barrier_mode_(UPDATE_WRITE_BARRIER) { | 6093 write_barrier_mode_(UPDATE_WRITE_BARRIER) { |
| 6145 SetOperandAt(0, obj); | 6094 SetOperandAt(0, obj); |
| 6146 SetOperandAt(1, val); | 6095 SetOperandAt(1, val); |
| 6147 access.SetGVNFlags(this, true); | 6096 access.SetGVNFlags(this, true); |
| 6148 } | 6097 } |
| 6149 | 6098 |
| 6150 DECLARE_CONCRETE_INSTRUCTION(StoreNamedField) | 6099 DECLARE_CONCRETE_INSTRUCTION(StoreNamedField) |
| 6151 | 6100 |
| 6152 virtual bool HasEscapingOperandAt(int index) { return index == 1; } | 6101 virtual bool HasEscapingOperandAt(int index) { return index == 1; } |
| 6153 virtual Representation RequiredInputRepresentation(int index) { | 6102 virtual Representation RequiredInputRepresentation(int index) { |
| 6154 if (index == 0 && access().IsExternalMemory()) { | 6103 if (index == 1 && field_representation().IsDouble()) { |
| 6155 // object must be external in case of external memory access | 6104 return field_representation(); |
| 6156 return Representation::External(); | 6105 } else if (index == 1 && field_representation().IsSmi()) { |
| 6157 } else if (index == 1 && | |
| 6158 (field_representation().IsDouble() || | |
| 6159 field_representation().IsSmi() || | |
| 6160 field_representation().IsInteger32())) { | |
| 6161 return field_representation(); | 6106 return field_representation(); |
| 6162 } | 6107 } |
| 6163 return Representation::Tagged(); | 6108 return Representation::Tagged(); |
| 6164 } | 6109 } |
| 6165 virtual void HandleSideEffectDominator(GVNFlag side_effect, | 6110 virtual void HandleSideEffectDominator(GVNFlag side_effect, |
| 6166 HValue* dominator) { | 6111 HValue* dominator) { |
| 6167 ASSERT(side_effect == kChangesNewSpacePromotion); | 6112 ASSERT(side_effect == kChangesNewSpacePromotion); |
| 6168 new_space_dominator_ = dominator; | 6113 new_space_dominator_ = dominator; |
| 6169 } | 6114 } |
| 6170 virtual void PrintDataTo(StringStream* stream); | 6115 virtual void PrintDataTo(StringStream* stream); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 6188 transition_ = map; | 6133 transition_ = map; |
| 6189 } | 6134 } |
| 6190 HValue* new_space_dominator() const { return new_space_dominator_; } | 6135 HValue* new_space_dominator() const { return new_space_dominator_; } |
| 6191 | 6136 |
| 6192 bool NeedsWriteBarrier() { | 6137 bool NeedsWriteBarrier() { |
| 6193 ASSERT(!(FLAG_track_double_fields && field_representation().IsDouble()) || | 6138 ASSERT(!(FLAG_track_double_fields && field_representation().IsDouble()) || |
| 6194 transition_.is_null()); | 6139 transition_.is_null()); |
| 6195 if (IsSkipWriteBarrier()) return false; | 6140 if (IsSkipWriteBarrier()) return false; |
| 6196 if (field_representation().IsDouble()) return false; | 6141 if (field_representation().IsDouble()) return false; |
| 6197 if (field_representation().IsSmi()) return false; | 6142 if (field_representation().IsSmi()) return false; |
| 6198 if (field_representation().IsInteger32()) return false; | |
| 6199 return StoringValueNeedsWriteBarrier(value()) && | 6143 return StoringValueNeedsWriteBarrier(value()) && |
| 6200 ReceiverObjectNeedsWriteBarrier(object(), new_space_dominator()); | 6144 ReceiverObjectNeedsWriteBarrier(object(), new_space_dominator()); |
| 6201 } | 6145 } |
| 6202 | 6146 |
| 6203 bool NeedsWriteBarrierForMap() { | 6147 bool NeedsWriteBarrierForMap() { |
| 6204 if (IsSkipWriteBarrier()) return false; | 6148 if (IsSkipWriteBarrier()) return false; |
| 6205 return ReceiverObjectNeedsWriteBarrier(object(), new_space_dominator()); | 6149 return ReceiverObjectNeedsWriteBarrier(object(), new_space_dominator()); |
| 6206 } | 6150 } |
| 6207 | 6151 |
| 6208 virtual void FinalizeUniqueValueId() { | 6152 virtual void FinalizeUniqueValueId() { |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6269 new_space_dominator_(NULL) { | 6213 new_space_dominator_(NULL) { |
| 6270 SetOperandAt(0, obj); | 6214 SetOperandAt(0, obj); |
| 6271 SetOperandAt(1, key); | 6215 SetOperandAt(1, key); |
| 6272 SetOperandAt(2, val); | 6216 SetOperandAt(2, val); |
| 6273 | 6217 |
| 6274 if (IsFastObjectElementsKind(elements_kind)) { | 6218 if (IsFastObjectElementsKind(elements_kind)) { |
| 6275 SetFlag(kTrackSideEffectDominators); | 6219 SetFlag(kTrackSideEffectDominators); |
| 6276 SetGVNFlag(kDependsOnNewSpacePromotion); | 6220 SetGVNFlag(kDependsOnNewSpacePromotion); |
| 6277 } | 6221 } |
| 6278 if (is_external()) { | 6222 if (is_external()) { |
| 6279 SetGVNFlag(kChangesExternalMemory); | 6223 SetGVNFlag(kChangesSpecializedArrayElements); |
| 6280 SetFlag(kAllowUndefinedAsNaN); | 6224 SetFlag(kAllowUndefinedAsNaN); |
| 6281 } else if (IsFastDoubleElementsKind(elements_kind)) { | 6225 } else if (IsFastDoubleElementsKind(elements_kind)) { |
| 6282 SetGVNFlag(kChangesDoubleArrayElements); | 6226 SetGVNFlag(kChangesDoubleArrayElements); |
| 6283 } else if (IsFastSmiElementsKind(elements_kind)) { | 6227 } else if (IsFastSmiElementsKind(elements_kind)) { |
| 6284 SetGVNFlag(kChangesArrayElements); | 6228 SetGVNFlag(kChangesArrayElements); |
| 6285 } else { | 6229 } else { |
| 6286 SetGVNFlag(kChangesArrayElements); | 6230 SetGVNFlag(kChangesArrayElements); |
| 6287 } | 6231 } |
| 6288 | 6232 |
| 6289 // EXTERNAL_{UNSIGNED_,}{BYTE,SHORT,INT}_ELEMENTS are truncating. | 6233 // EXTERNAL_{UNSIGNED_,}{BYTE,SHORT,INT}_ELEMENTS are truncating. |
| (...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6520 | 6464 |
| 6521 private: | 6465 private: |
| 6522 HStringAdd(HValue* context, HValue* left, HValue* right, StringAddFlags flags) | 6466 HStringAdd(HValue* context, HValue* left, HValue* right, StringAddFlags flags) |
| 6523 : HBinaryOperation(context, left, right), flags_(flags) { | 6467 : HBinaryOperation(context, left, right), flags_(flags) { |
| 6524 set_representation(Representation::Tagged()); | 6468 set_representation(Representation::Tagged()); |
| 6525 SetFlag(kUseGVN); | 6469 SetFlag(kUseGVN); |
| 6526 SetGVNFlag(kDependsOnMaps); | 6470 SetGVNFlag(kDependsOnMaps); |
| 6527 SetGVNFlag(kChangesNewSpacePromotion); | 6471 SetGVNFlag(kChangesNewSpacePromotion); |
| 6528 } | 6472 } |
| 6529 | 6473 |
| 6530 // No side-effects except possible allocation. | 6474 // TODO(svenpanne) Might be safe, but leave it out until we know for sure. |
| 6531 // NOTE: this instruction _does not_ call ToString() on its inputs. | 6475 // virtual bool IsDeletable() const { return true; } |
| 6532 virtual bool IsDeletable() const { return true; } | |
| 6533 | 6476 |
| 6534 const StringAddFlags flags_; | 6477 const StringAddFlags flags_; |
| 6535 }; | 6478 }; |
| 6536 | 6479 |
| 6537 | 6480 |
| 6538 class HStringCharCodeAt: public HTemplateInstruction<3> { | 6481 class HStringCharCodeAt: public HTemplateInstruction<3> { |
| 6539 public: | 6482 public: |
| 6540 HStringCharCodeAt(HValue* context, HValue* string, HValue* index) { | 6483 HStringCharCodeAt(HValue* context, HValue* string, HValue* index) { |
| 6541 SetOperandAt(0, context); | 6484 SetOperandAt(0, context); |
| 6542 SetOperandAt(1, string); | 6485 SetOperandAt(1, string); |
| 6543 SetOperandAt(2, index); | 6486 SetOperandAt(2, index); |
| 6544 set_representation(Representation::Integer32()); | 6487 set_representation(Representation::Integer32()); |
| 6545 SetFlag(kUseGVN); | 6488 SetFlag(kUseGVN); |
| 6546 SetGVNFlag(kDependsOnMaps); | 6489 SetGVNFlag(kDependsOnMaps); |
| 6547 SetGVNFlag(kChangesNewSpacePromotion); | 6490 SetGVNFlag(kChangesNewSpacePromotion); |
| 6548 } | 6491 } |
| 6549 | 6492 |
| 6550 virtual Representation RequiredInputRepresentation(int index) { | 6493 virtual Representation RequiredInputRepresentation(int index) { |
| 6551 // The index is supposed to be Integer32. | 6494 // The index is supposed to be Integer32. |
| 6552 return index == 2 | 6495 return index == 2 |
| 6553 ? Representation::Integer32() | 6496 ? Representation::Integer32() |
| 6554 : Representation::Tagged(); | 6497 : Representation::Tagged(); |
| 6555 } | 6498 } |
| 6556 | 6499 |
| 6557 HValue* context() const { return OperandAt(0); } | 6500 HValue* context() { return OperandAt(0); } |
| 6558 HValue* string() const { return OperandAt(1); } | 6501 HValue* string() { return OperandAt(1); } |
| 6559 HValue* index() const { return OperandAt(2); } | 6502 HValue* index() { return OperandAt(2); } |
| 6560 | 6503 |
| 6561 DECLARE_CONCRETE_INSTRUCTION(StringCharCodeAt) | 6504 DECLARE_CONCRETE_INSTRUCTION(StringCharCodeAt) |
| 6562 | 6505 |
| 6563 protected: | 6506 protected: |
| 6564 virtual bool DataEquals(HValue* other) { return true; } | 6507 virtual bool DataEquals(HValue* other) { return true; } |
| 6565 | 6508 |
| 6566 virtual Range* InferRange(Zone* zone) { | 6509 virtual Range* InferRange(Zone* zone) { |
| 6567 return new(zone) Range(0, String::kMaxUtf16CodeUnit); | 6510 return new(zone) Range(0, String::kMaxUtf16CodeUnit); |
| 6568 } | 6511 } |
| 6569 | 6512 |
| 6570 private: | 6513 // TODO(svenpanne) Might be safe, but leave it out until we know for sure. |
| 6571 // No side effects: runtime function assumes string + number inputs. | 6514 // private: |
| 6572 virtual bool IsDeletable() const { return true; } | 6515 // virtual bool IsDeletable() const { return true; } |
| 6573 }; | 6516 }; |
| 6574 | 6517 |
| 6575 | 6518 |
| 6576 class HStringCharFromCode: public HTemplateInstruction<2> { | 6519 class HStringCharFromCode: public HTemplateInstruction<2> { |
| 6577 public: | 6520 public: |
| 6578 static HInstruction* New(Zone* zone, | 6521 static HInstruction* New(Zone* zone, |
| 6579 HValue* context, | 6522 HValue* context, |
| 6580 HValue* char_code); | 6523 HValue* char_code); |
| 6581 | 6524 |
| 6582 virtual Representation RequiredInputRepresentation(int index) { | 6525 virtual Representation RequiredInputRepresentation(int index) { |
| 6583 return index == 0 | 6526 return index == 0 |
| 6584 ? Representation::Tagged() | 6527 ? Representation::Tagged() |
| 6585 : Representation::Integer32(); | 6528 : Representation::Integer32(); |
| 6586 } | 6529 } |
| 6587 virtual HType CalculateInferredType() { return HType::String(); } | 6530 virtual HType CalculateInferredType(); |
| 6588 | 6531 |
| 6589 HValue* context() const { return OperandAt(0); } | 6532 HValue* context() { return OperandAt(0); } |
| 6590 HValue* value() const { return OperandAt(1); } | 6533 HValue* value() { return OperandAt(1); } |
| 6591 | 6534 |
| 6592 virtual bool DataEquals(HValue* other) { return true; } | 6535 virtual bool DataEquals(HValue* other) { return true; } |
| 6593 | 6536 |
| 6594 DECLARE_CONCRETE_INSTRUCTION(StringCharFromCode) | 6537 DECLARE_CONCRETE_INSTRUCTION(StringCharFromCode) |
| 6595 | 6538 |
| 6596 private: | 6539 private: |
| 6597 HStringCharFromCode(HValue* context, HValue* char_code) { | 6540 HStringCharFromCode(HValue* context, HValue* char_code) { |
| 6598 SetOperandAt(0, context); | 6541 SetOperandAt(0, context); |
| 6599 SetOperandAt(1, char_code); | 6542 SetOperandAt(1, char_code); |
| 6600 set_representation(Representation::Tagged()); | 6543 set_representation(Representation::Tagged()); |
| 6601 SetFlag(kUseGVN); | 6544 SetFlag(kUseGVN); |
| 6602 SetGVNFlag(kChangesNewSpacePromotion); | 6545 SetGVNFlag(kChangesNewSpacePromotion); |
| 6603 } | 6546 } |
| 6604 | 6547 |
| 6605 virtual bool IsDeletable() const { | 6548 // TODO(svenpanne) Might be safe, but leave it out until we know for sure. |
| 6606 return !value()->ToNumberCanBeObserved(); | 6549 // virtual bool IsDeletable() const { return true; } |
| 6607 } | |
| 6608 }; | 6550 }; |
| 6609 | 6551 |
| 6610 | 6552 |
| 6611 class HStringLength: public HUnaryOperation { | 6553 class HStringLength: public HUnaryOperation { |
| 6612 public: | 6554 public: |
| 6613 static HInstruction* New(Zone* zone, HValue* string); | 6555 static HInstruction* New(Zone* zone, HValue* string); |
| 6614 | 6556 |
| 6615 virtual Representation RequiredInputRepresentation(int index) { | 6557 virtual Representation RequiredInputRepresentation(int index) { |
| 6616 return Representation::Tagged(); | 6558 return Representation::Tagged(); |
| 6617 } | 6559 } |
| (...skipping 388 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7006 virtual bool IsDeletable() const { return true; } | 6948 virtual bool IsDeletable() const { return true; } |
| 7007 }; | 6949 }; |
| 7008 | 6950 |
| 7009 | 6951 |
| 7010 #undef DECLARE_INSTRUCTION | 6952 #undef DECLARE_INSTRUCTION |
| 7011 #undef DECLARE_CONCRETE_INSTRUCTION | 6953 #undef DECLARE_CONCRETE_INSTRUCTION |
| 7012 | 6954 |
| 7013 } } // namespace v8::internal | 6955 } } // namespace v8::internal |
| 7014 | 6956 |
| 7015 #endif // V8_HYDROGEN_INSTRUCTIONS_H_ | 6957 #endif // V8_HYDROGEN_INSTRUCTIONS_H_ |
| OLD | NEW |