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(SpecializedArrayElements) | 214 V(ExternalMemory) |
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 static HType Tagged() { return HType(kTagged); } | 354 static HType Tagged() { return HType(kTagged); } |
354 static HType TaggedPrimitive() { return HType(kTaggedPrimitive); } | 355 static HType TaggedPrimitive() { return HType(kTaggedPrimitive); } |
355 static HType TaggedNumber() { return HType(kTaggedNumber); } | 356 static HType TaggedNumber() { return HType(kTaggedNumber); } |
356 static HType Smi() { return HType(kSmi); } | 357 static HType Smi() { return HType(kSmi); } |
357 static HType HeapNumber() { return HType(kHeapNumber); } | 358 static HType HeapNumber() { return HType(kHeapNumber); } |
358 static HType String() { return HType(kString); } | 359 static HType String() { return HType(kString); } |
359 static HType Boolean() { return HType(kBoolean); } | 360 static HType Boolean() { return HType(kBoolean); } |
360 static HType NonPrimitive() { return HType(kNonPrimitive); } | 361 static HType NonPrimitive() { return HType(kNonPrimitive); } |
361 static HType JSArray() { return HType(kJSArray); } | 362 static HType JSArray() { return HType(kJSArray); } |
362 static HType JSObject() { return HType(kJSObject); } | 363 static HType JSObject() { return HType(kJSObject); } |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
440 } | 441 } |
441 return !representation.IsSmiOrInteger32() && !representation.IsDouble(); | 442 return !representation.IsSmiOrInteger32() && !representation.IsDouble(); |
442 } | 443 } |
443 | 444 |
444 static HType TypeFromValue(Handle<Object> value); | 445 static HType TypeFromValue(Handle<Object> value); |
445 | 446 |
446 const char* ToString(); | 447 const char* ToString(); |
447 | 448 |
448 private: | 449 private: |
449 enum Type { | 450 enum Type { |
| 451 kNone = 0x0, // 0000 0000 0000 0000 |
450 kTagged = 0x1, // 0000 0000 0000 0001 | 452 kTagged = 0x1, // 0000 0000 0000 0001 |
451 kTaggedPrimitive = 0x5, // 0000 0000 0000 0101 | 453 kTaggedPrimitive = 0x5, // 0000 0000 0000 0101 |
452 kTaggedNumber = 0xd, // 0000 0000 0000 1101 | 454 kTaggedNumber = 0xd, // 0000 0000 0000 1101 |
453 kSmi = 0x1d, // 0000 0000 0001 1101 | 455 kSmi = 0x1d, // 0000 0000 0001 1101 |
454 kHeapNumber = 0x2d, // 0000 0000 0010 1101 | 456 kHeapNumber = 0x2d, // 0000 0000 0010 1101 |
455 kString = 0x45, // 0000 0000 0100 0101 | 457 kString = 0x45, // 0000 0000 0100 0101 |
456 kBoolean = 0x85, // 0000 0000 1000 0101 | 458 kBoolean = 0x85, // 0000 0000 1000 0101 |
457 kNonPrimitive = 0x101, // 0000 0001 0000 0001 | 459 kNonPrimitive = 0x101, // 0000 0001 0000 0001 |
458 kJSObject = 0x301, // 0000 0011 0000 0001 | 460 kJSObject = 0x301, // 0000 0011 0000 0001 |
459 kJSArray = 0x701 // 0000 0111 0000 0001 | 461 kJSArray = 0x701 // 0000 0111 0000 0001 |
(...skipping 2226 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2686 // change. The external array of a specialized array elements object cannot | 2688 // change. The external array of a specialized array elements object cannot |
2687 // change once set, so it's no necessary to introduce any additional | 2689 // change once set, so it's no necessary to introduce any additional |
2688 // dependencies on top of the inputs. | 2690 // dependencies on top of the inputs. |
2689 SetFlag(kUseGVN); | 2691 SetFlag(kUseGVN); |
2690 } | 2692 } |
2691 | 2693 |
2692 virtual Representation RequiredInputRepresentation(int index) { | 2694 virtual Representation RequiredInputRepresentation(int index) { |
2693 return Representation::Tagged(); | 2695 return Representation::Tagged(); |
2694 } | 2696 } |
2695 | 2697 |
| 2698 virtual HType CalculateInferredType() { |
| 2699 return HType::None(); |
| 2700 } |
| 2701 |
2696 DECLARE_CONCRETE_INSTRUCTION(LoadExternalArrayPointer) | 2702 DECLARE_CONCRETE_INSTRUCTION(LoadExternalArrayPointer) |
2697 | 2703 |
2698 protected: | 2704 protected: |
2699 virtual bool DataEquals(HValue* other) { return true; } | 2705 virtual bool DataEquals(HValue* other) { return true; } |
2700 | 2706 |
2701 private: | 2707 private: |
2702 virtual bool IsDeletable() const { return true; } | 2708 virtual bool IsDeletable() const { return true; } |
2703 }; | 2709 }; |
2704 | 2710 |
2705 | 2711 |
(...skipping 765 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3471 bool is_not_in_new_space = true, | 3477 bool is_not_in_new_space = true, |
3472 Handle<Object> optional_handle = Handle<Object>::null()); | 3478 Handle<Object> optional_handle = Handle<Object>::null()); |
3473 HConstant(Handle<Object> handle, | 3479 HConstant(Handle<Object> handle, |
3474 UniqueValueId unique_id, | 3480 UniqueValueId unique_id, |
3475 Representation r, | 3481 Representation r, |
3476 HType type, | 3482 HType type, |
3477 bool is_internalized_string, | 3483 bool is_internalized_string, |
3478 bool is_not_in_new_space, | 3484 bool is_not_in_new_space, |
3479 bool is_cell, | 3485 bool is_cell, |
3480 bool boolean_value); | 3486 bool boolean_value); |
| 3487 explicit HConstant(ExternalReference reference); |
3481 | 3488 |
3482 Handle<Object> handle() { | 3489 Handle<Object> handle() { |
3483 if (handle_.is_null()) { | 3490 if (handle_.is_null()) { |
3484 Factory* factory = Isolate::Current()->factory(); | 3491 Factory* factory = Isolate::Current()->factory(); |
3485 // Default arguments to is_not_in_new_space depend on this heap number | 3492 // Default arguments to is_not_in_new_space depend on this heap number |
3486 // to be tenured so that it's guaranteed not be be located in new space. | 3493 // to be tenured so that it's guaranteed not be be located in new space. |
3487 handle_ = factory->NewNumber(double_value_, TENURED); | 3494 handle_ = factory->NewNumber(double_value_, TENURED); |
3488 } | 3495 } |
3489 AllowDeferredHandleDereference smi_check; | 3496 AllowDeferredHandleDereference smi_check; |
3490 ASSERT(has_int32_value_ || !handle_->IsSmi()); | 3497 ASSERT(has_int32_value_ || !handle_->IsSmi()); |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3535 } | 3542 } |
3536 | 3543 |
3537 virtual Representation RequiredInputRepresentation(int index) { | 3544 virtual Representation RequiredInputRepresentation(int index) { |
3538 return Representation::None(); | 3545 return Representation::None(); |
3539 } | 3546 } |
3540 | 3547 |
3541 virtual Representation KnownOptimalRepresentation() { | 3548 virtual Representation KnownOptimalRepresentation() { |
3542 if (HasSmiValue() && kSmiValueSize == 31) return Representation::Smi(); | 3549 if (HasSmiValue() && kSmiValueSize == 31) return Representation::Smi(); |
3543 if (HasInteger32Value()) return Representation::Integer32(); | 3550 if (HasInteger32Value()) return Representation::Integer32(); |
3544 if (HasNumberValue()) return Representation::Double(); | 3551 if (HasNumberValue()) return Representation::Double(); |
| 3552 if (HasExternalReferenceValue()) return Representation::External(); |
3545 return Representation::Tagged(); | 3553 return Representation::Tagged(); |
3546 } | 3554 } |
3547 | 3555 |
3548 virtual bool EmitAtUses(); | 3556 virtual bool EmitAtUses(); |
3549 virtual void PrintDataTo(StringStream* stream); | 3557 virtual void PrintDataTo(StringStream* stream); |
3550 bool IsInteger() { return handle()->IsSmi(); } | 3558 bool IsInteger() { return handle()->IsSmi(); } |
3551 HConstant* CopyToRepresentation(Representation r, Zone* zone) const; | 3559 HConstant* CopyToRepresentation(Representation r, Zone* zone) const; |
3552 Maybe<HConstant*> CopyToTruncatedInt32(Zone* zone); | 3560 Maybe<HConstant*> CopyToTruncatedInt32(Zone* zone); |
3553 Maybe<HConstant*> CopyToTruncatedNumber(Zone* zone); | 3561 Maybe<HConstant*> CopyToTruncatedNumber(Zone* zone); |
3554 bool HasInteger32Value() const { return has_int32_value_; } | 3562 bool HasInteger32Value() const { return has_int32_value_; } |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3586 return type_.IsString(); | 3594 return type_.IsString(); |
3587 } | 3595 } |
3588 Handle<String> StringValue() const { | 3596 Handle<String> StringValue() const { |
3589 ASSERT(HasStringValue()); | 3597 ASSERT(HasStringValue()); |
3590 return Handle<String>::cast(handle_); | 3598 return Handle<String>::cast(handle_); |
3591 } | 3599 } |
3592 bool HasInternalizedStringValue() const { | 3600 bool HasInternalizedStringValue() const { |
3593 return HasStringValue() && is_internalized_string_; | 3601 return HasStringValue() && is_internalized_string_; |
3594 } | 3602 } |
3595 | 3603 |
| 3604 bool HasExternalReferenceValue() const { |
| 3605 return has_external_reference_value_; |
| 3606 } |
| 3607 ExternalReference ExternalReferenceValue() const { |
| 3608 return external_reference_value_; |
| 3609 } |
| 3610 |
3596 bool BooleanValue() const { return boolean_value_; } | 3611 bool BooleanValue() const { return boolean_value_; } |
3597 | 3612 |
3598 virtual intptr_t Hashcode() { | 3613 virtual intptr_t Hashcode() { |
3599 if (has_int32_value_) { | 3614 if (has_int32_value_) { |
3600 return static_cast<intptr_t>(int32_value_); | 3615 return static_cast<intptr_t>(int32_value_); |
3601 } else if (has_double_value_) { | 3616 } else if (has_double_value_) { |
3602 return static_cast<intptr_t>(BitCast<int64_t>(double_value_)); | 3617 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()); |
3603 } else { | 3620 } else { |
3604 ASSERT(!handle_.is_null()); | 3621 ASSERT(!handle_.is_null()); |
3605 return unique_id_.Hashcode(); | 3622 return unique_id_.Hashcode(); |
3606 } | 3623 } |
3607 } | 3624 } |
3608 | 3625 |
3609 virtual void FinalizeUniqueValueId() { | 3626 virtual void FinalizeUniqueValueId() { |
3610 if (!has_double_value_) { | 3627 if (!has_double_value_ && !has_external_reference_value_) { |
3611 ASSERT(!handle_.is_null()); | 3628 ASSERT(!handle_.is_null()); |
3612 unique_id_ = UniqueValueId(handle_); | 3629 unique_id_ = UniqueValueId(handle_); |
3613 } | 3630 } |
3614 } | 3631 } |
3615 | 3632 |
3616 bool UniqueValueIdsMatch(UniqueValueId other) { | 3633 bool UniqueValueIdsMatch(UniqueValueId other) { |
3617 return !has_double_value_ && unique_id_ == other; | 3634 return !has_double_value_ && !has_external_reference_value_ && |
| 3635 unique_id_ == other; |
3618 } | 3636 } |
3619 | 3637 |
3620 #ifdef DEBUG | 3638 #ifdef DEBUG |
3621 virtual void Verify() { } | 3639 virtual void Verify() { } |
3622 #endif | 3640 #endif |
3623 | 3641 |
3624 DECLARE_CONCRETE_INSTRUCTION(Constant) | 3642 DECLARE_CONCRETE_INSTRUCTION(Constant) |
3625 | 3643 |
3626 protected: | 3644 protected: |
3627 virtual Range* InferRange(Zone* zone); | 3645 virtual Range* InferRange(Zone* zone); |
3628 | 3646 |
3629 virtual bool DataEquals(HValue* other) { | 3647 virtual bool DataEquals(HValue* other) { |
3630 HConstant* other_constant = HConstant::cast(other); | 3648 HConstant* other_constant = HConstant::cast(other); |
3631 if (has_int32_value_) { | 3649 if (has_int32_value_) { |
3632 return other_constant->has_int32_value_ && | 3650 return other_constant->has_int32_value_ && |
3633 int32_value_ == other_constant->int32_value_; | 3651 int32_value_ == other_constant->int32_value_; |
3634 } else if (has_double_value_) { | 3652 } else if (has_double_value_) { |
3635 return other_constant->has_double_value_ && | 3653 return other_constant->has_double_value_ && |
3636 BitCast<int64_t>(double_value_) == | 3654 BitCast<int64_t>(double_value_) == |
3637 BitCast<int64_t>(other_constant->double_value_); | 3655 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_; |
3638 } else { | 3660 } else { |
3639 ASSERT(!handle_.is_null()); | 3661 ASSERT(!handle_.is_null()); |
3640 return !other_constant->handle_.is_null() && | 3662 return !other_constant->handle_.is_null() && |
3641 unique_id_ == other_constant->unique_id_; | 3663 unique_id_ == other_constant->unique_id_; |
3642 } | 3664 } |
3643 } | 3665 } |
3644 | 3666 |
3645 private: | 3667 private: |
3646 void Initialize(Representation r); | 3668 void Initialize(Representation r); |
3647 | 3669 |
3648 virtual bool IsDeletable() const { return true; } | 3670 virtual bool IsDeletable() const { return true; } |
3649 | 3671 |
3650 // If this is a numerical constant, handle_ either points to to the | 3672 // If this is a numerical constant, handle_ either points to to the |
3651 // HeapObject the constant originated from or is null. If the | 3673 // HeapObject the constant originated from or is null. If the |
3652 // constant is non-numeric, handle_ always points to a valid | 3674 // constant is non-numeric, handle_ always points to a valid |
3653 // constant HeapObject. | 3675 // constant HeapObject. |
3654 Handle<Object> handle_; | 3676 Handle<Object> handle_; |
3655 UniqueValueId unique_id_; | 3677 UniqueValueId unique_id_; |
3656 | 3678 |
3657 // We store the HConstant in the most specific form safely possible. | 3679 // We store the HConstant in the most specific form safely possible. |
3658 // The two flags, has_int32_value_ and has_double_value_ tell us if | 3680 // The two flags, has_int32_value_ and has_double_value_ tell us if |
3659 // int32_value_ and double_value_ hold valid, safe representations | 3681 // int32_value_ and double_value_ hold valid, safe representations |
3660 // of the constant. has_int32_value_ implies has_double_value_ but | 3682 // of the constant. has_int32_value_ implies has_double_value_ but |
3661 // not the converse. | 3683 // not the converse. |
3662 bool has_smi_value_ : 1; | 3684 bool has_smi_value_ : 1; |
3663 bool has_int32_value_ : 1; | 3685 bool has_int32_value_ : 1; |
3664 bool has_double_value_ : 1; | 3686 bool has_double_value_ : 1; |
| 3687 bool has_external_reference_value_ : 1; |
3665 bool is_internalized_string_ : 1; // TODO(yangguo): make this part of HType. | 3688 bool is_internalized_string_ : 1; // TODO(yangguo): make this part of HType. |
3666 bool is_not_in_new_space_ : 1; | 3689 bool is_not_in_new_space_ : 1; |
3667 bool is_cell_ : 1; | 3690 bool is_cell_ : 1; |
3668 bool boolean_value_ : 1; | 3691 bool boolean_value_ : 1; |
3669 int32_t int32_value_; | 3692 int32_t int32_value_; |
3670 double double_value_; | 3693 double double_value_; |
| 3694 ExternalReference external_reference_value_; |
3671 }; | 3695 }; |
3672 | 3696 |
3673 | 3697 |
3674 class HBinaryOperation: public HTemplateInstruction<3> { | 3698 class HBinaryOperation: public HTemplateInstruction<3> { |
3675 public: | 3699 public: |
3676 HBinaryOperation(HValue* context, HValue* left, HValue* right) | 3700 HBinaryOperation(HValue* context, HValue* left, HValue* right) |
3677 : observed_output_representation_(Representation::None()) { | 3701 : observed_output_representation_(Representation::None()) { |
3678 ASSERT(left != NULL && right != NULL); | 3702 ASSERT(left != NULL && right != NULL); |
3679 SetOperandAt(0, context); | 3703 SetOperandAt(0, context); |
3680 SetOperandAt(1, left); | 3704 SetOperandAt(1, left); |
(...skipping 1876 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5557 int slot_index_; | 5581 int slot_index_; |
5558 Mode mode_; | 5582 Mode mode_; |
5559 }; | 5583 }; |
5560 | 5584 |
5561 | 5585 |
5562 // Represents an access to a portion of an object, such as the map pointer, | 5586 // Represents an access to a portion of an object, such as the map pointer, |
5563 // array elements pointer, etc, but not accesses to array elements themselves. | 5587 // array elements pointer, etc, but not accesses to array elements themselves. |
5564 class HObjectAccess { | 5588 class HObjectAccess { |
5565 public: | 5589 public: |
5566 inline bool IsInobject() const { | 5590 inline bool IsInobject() const { |
5567 return portion() != kBackingStore; | 5591 return portion() != kBackingStore && portion() != kExternalMemory; |
| 5592 } |
| 5593 |
| 5594 inline bool IsExternalMemory() const { |
| 5595 return portion() == kExternalMemory; |
5568 } | 5596 } |
5569 | 5597 |
5570 inline int offset() const { | 5598 inline int offset() const { |
5571 return OffsetField::decode(value_); | 5599 return OffsetField::decode(value_); |
5572 } | 5600 } |
5573 | 5601 |
5574 inline Representation representation() const { | 5602 inline Representation representation() const { |
5575 return Representation::FromKind(RepresentationField::decode(value_)); | 5603 return Representation::FromKind(RepresentationField::decode(value_)); |
5576 } | 5604 } |
5577 | 5605 |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5633 } | 5661 } |
5634 | 5662 |
5635 static HObjectAccess ForCellValue() { | 5663 static HObjectAccess ForCellValue() { |
5636 return HObjectAccess(kInobject, Cell::kValueOffset); | 5664 return HObjectAccess(kInobject, Cell::kValueOffset); |
5637 } | 5665 } |
5638 | 5666 |
5639 static HObjectAccess ForAllocationMementoSite() { | 5667 static HObjectAccess ForAllocationMementoSite() { |
5640 return HObjectAccess(kInobject, AllocationMemento::kAllocationSiteOffset); | 5668 return HObjectAccess(kInobject, AllocationMemento::kAllocationSiteOffset); |
5641 } | 5669 } |
5642 | 5670 |
| 5671 static HObjectAccess ForCounter() { |
| 5672 return HObjectAccess(kExternalMemory, 0, Representation::Integer32()); |
| 5673 } |
| 5674 |
5643 // Create an access to an offset in a fixed array header. | 5675 // Create an access to an offset in a fixed array header. |
5644 static HObjectAccess ForFixedArrayHeader(int offset); | 5676 static HObjectAccess ForFixedArrayHeader(int offset); |
5645 | 5677 |
5646 // Create an access to an in-object property in a JSObject. | 5678 // Create an access to an in-object property in a JSObject. |
5647 static HObjectAccess ForJSObjectOffset(int offset, | 5679 static HObjectAccess ForJSObjectOffset(int offset, |
5648 Representation representation = Representation::Tagged()); | 5680 Representation representation = Representation::Tagged()); |
5649 | 5681 |
5650 // Create an access to an in-object property in a JSArray. | 5682 // Create an access to an in-object property in a JSArray. |
5651 static HObjectAccess ForJSArrayOffset(int offset); | 5683 static HObjectAccess ForJSArrayOffset(int offset); |
5652 | 5684 |
(...skipping 18 matching lines...) Expand all Loading... |
5671 void SetGVNFlags(HValue *instr, bool is_store); | 5703 void SetGVNFlags(HValue *instr, bool is_store); |
5672 | 5704 |
5673 private: | 5705 private: |
5674 // internal use only; different parts of an object or array | 5706 // internal use only; different parts of an object or array |
5675 enum Portion { | 5707 enum Portion { |
5676 kMaps, // map of an object | 5708 kMaps, // map of an object |
5677 kArrayLengths, // the length of an array | 5709 kArrayLengths, // the length of an array |
5678 kElementsPointer, // elements pointer | 5710 kElementsPointer, // elements pointer |
5679 kBackingStore, // some field in the backing store | 5711 kBackingStore, // some field in the backing store |
5680 kDouble, // some double field | 5712 kDouble, // some double field |
5681 kInobject // some other in-object field | 5713 kInobject, // some other in-object field |
| 5714 kExternalMemory // some field in external memory |
5682 }; | 5715 }; |
5683 | 5716 |
5684 HObjectAccess(Portion portion, int offset, | 5717 HObjectAccess(Portion portion, int offset, |
5685 Representation representation = Representation::Tagged(), | 5718 Representation representation = Representation::Tagged(), |
5686 Handle<String> name = Handle<String>::null()) | 5719 Handle<String> name = Handle<String>::null()) |
5687 : value_(PortionField::encode(portion) | | 5720 : value_(PortionField::encode(portion) | |
5688 RepresentationField::encode(representation.kind()) | | 5721 RepresentationField::encode(representation.kind()) | |
5689 OffsetField::encode(offset)), | 5722 OffsetField::encode(offset)), |
5690 name_(name) { | 5723 name_(name) { |
5691 // assert that the fields decode correctly | 5724 // assert that the fields decode correctly |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5749 HValue* typecheck = NULL) | 5782 HValue* typecheck = NULL) |
5750 : access_(access) { | 5783 : access_(access) { |
5751 ASSERT(object != NULL); | 5784 ASSERT(object != NULL); |
5752 SetOperandAt(0, object); | 5785 SetOperandAt(0, object); |
5753 SetOperandAt(1, typecheck != NULL ? typecheck : object); | 5786 SetOperandAt(1, typecheck != NULL ? typecheck : object); |
5754 | 5787 |
5755 Representation representation = access.representation(); | 5788 Representation representation = access.representation(); |
5756 if (representation.IsSmi()) { | 5789 if (representation.IsSmi()) { |
5757 set_type(HType::Smi()); | 5790 set_type(HType::Smi()); |
5758 set_representation(representation); | 5791 set_representation(representation); |
5759 } else if (representation.IsDouble()) { | 5792 } else if (representation.IsDouble() || |
| 5793 representation.IsExternal() || |
| 5794 representation.IsInteger32()) { |
5760 set_representation(representation); | 5795 set_representation(representation); |
5761 } else if (FLAG_track_heap_object_fields && | 5796 } else if (FLAG_track_heap_object_fields && |
5762 representation.IsHeapObject()) { | 5797 representation.IsHeapObject()) { |
5763 set_type(HType::NonPrimitive()); | 5798 set_type(HType::NonPrimitive()); |
5764 set_representation(Representation::Tagged()); | 5799 set_representation(Representation::Tagged()); |
5765 } else { | 5800 } else { |
5766 set_representation(Representation::Tagged()); | 5801 set_representation(Representation::Tagged()); |
5767 } | 5802 } |
5768 access.SetGVNFlags(this, false); | 5803 access.SetGVNFlags(this, false); |
5769 } | 5804 } |
5770 | 5805 |
5771 HValue* object() { return OperandAt(0); } | 5806 HValue* object() { return OperandAt(0); } |
5772 HValue* typecheck() { | 5807 HValue* typecheck() { |
5773 ASSERT(HasTypeCheck()); | 5808 ASSERT(HasTypeCheck()); |
5774 return OperandAt(1); | 5809 return OperandAt(1); |
5775 } | 5810 } |
5776 | 5811 |
5777 bool HasTypeCheck() const { return OperandAt(0) != OperandAt(1); } | 5812 bool HasTypeCheck() const { return OperandAt(0) != OperandAt(1); } |
5778 HObjectAccess access() const { return access_; } | 5813 HObjectAccess access() const { return access_; } |
5779 Representation field_representation() const { | 5814 Representation field_representation() const { |
5780 return access_.representation(); | 5815 return access_.representation(); |
5781 } | 5816 } |
5782 | 5817 |
5783 virtual bool HasEscapingOperandAt(int index) { return false; } | 5818 virtual bool HasEscapingOperandAt(int index) { return false; } |
5784 virtual Representation RequiredInputRepresentation(int index) { | 5819 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 } |
5785 return Representation::Tagged(); | 5824 return Representation::Tagged(); |
5786 } | 5825 } |
5787 virtual void PrintDataTo(StringStream* stream); | 5826 virtual void PrintDataTo(StringStream* stream); |
5788 | 5827 |
5789 DECLARE_CONCRETE_INSTRUCTION(LoadNamedField) | 5828 DECLARE_CONCRETE_INSTRUCTION(LoadNamedField) |
5790 | 5829 |
5791 protected: | 5830 protected: |
5792 virtual bool DataEquals(HValue* other) { | 5831 virtual bool DataEquals(HValue* other) { |
5793 HLoadNamedField* b = HLoadNamedField::cast(other); | 5832 HLoadNamedField* b = HLoadNamedField::cast(other); |
5794 return access_.Equals(b->access_); | 5833 return access_.Equals(b->access_); |
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5948 SetGVNFlag(kDependsOnDoubleArrayElements); | 5987 SetGVNFlag(kDependsOnDoubleArrayElements); |
5949 } | 5988 } |
5950 } else { | 5989 } else { |
5951 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS || | 5990 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS || |
5952 elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { | 5991 elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { |
5953 set_representation(Representation::Double()); | 5992 set_representation(Representation::Double()); |
5954 } else { | 5993 } else { |
5955 set_representation(Representation::Integer32()); | 5994 set_representation(Representation::Integer32()); |
5956 } | 5995 } |
5957 | 5996 |
5958 SetGVNFlag(kDependsOnSpecializedArrayElements); | 5997 SetGVNFlag(kDependsOnExternalMemory); |
5959 // Native code could change the specialized array. | 5998 // Native code could change the specialized array. |
5960 SetGVNFlag(kDependsOnCalls); | 5999 SetGVNFlag(kDependsOnCalls); |
5961 } | 6000 } |
5962 | 6001 |
5963 SetFlag(kUseGVN); | 6002 SetFlag(kUseGVN); |
5964 } | 6003 } |
5965 | 6004 |
5966 bool is_external() const { | 6005 bool is_external() const { |
5967 return IsExternalArrayElementsKind(elements_kind()); | 6006 return IsExternalArrayElementsKind(elements_kind()); |
5968 } | 6007 } |
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6105 write_barrier_mode_(UPDATE_WRITE_BARRIER) { | 6144 write_barrier_mode_(UPDATE_WRITE_BARRIER) { |
6106 SetOperandAt(0, obj); | 6145 SetOperandAt(0, obj); |
6107 SetOperandAt(1, val); | 6146 SetOperandAt(1, val); |
6108 access.SetGVNFlags(this, true); | 6147 access.SetGVNFlags(this, true); |
6109 } | 6148 } |
6110 | 6149 |
6111 DECLARE_CONCRETE_INSTRUCTION(StoreNamedField) | 6150 DECLARE_CONCRETE_INSTRUCTION(StoreNamedField) |
6112 | 6151 |
6113 virtual bool HasEscapingOperandAt(int index) { return index == 1; } | 6152 virtual bool HasEscapingOperandAt(int index) { return index == 1; } |
6114 virtual Representation RequiredInputRepresentation(int index) { | 6153 virtual Representation RequiredInputRepresentation(int index) { |
6115 if (index == 1 && field_representation().IsDouble()) { | 6154 if (index == 0 && access().IsExternalMemory()) { |
6116 return field_representation(); | 6155 // object must be external in case of external memory access |
6117 } else if (index == 1 && field_representation().IsSmi()) { | 6156 return Representation::External(); |
| 6157 } else if (index == 1 && |
| 6158 (field_representation().IsDouble() || |
| 6159 field_representation().IsSmi() || |
| 6160 field_representation().IsInteger32())) { |
6118 return field_representation(); | 6161 return field_representation(); |
6119 } | 6162 } |
6120 return Representation::Tagged(); | 6163 return Representation::Tagged(); |
6121 } | 6164 } |
6122 virtual void HandleSideEffectDominator(GVNFlag side_effect, | 6165 virtual void HandleSideEffectDominator(GVNFlag side_effect, |
6123 HValue* dominator) { | 6166 HValue* dominator) { |
6124 ASSERT(side_effect == kChangesNewSpacePromotion); | 6167 ASSERT(side_effect == kChangesNewSpacePromotion); |
6125 new_space_dominator_ = dominator; | 6168 new_space_dominator_ = dominator; |
6126 } | 6169 } |
6127 virtual void PrintDataTo(StringStream* stream); | 6170 virtual void PrintDataTo(StringStream* stream); |
(...skipping 17 matching lines...) Expand all Loading... |
6145 transition_ = map; | 6188 transition_ = map; |
6146 } | 6189 } |
6147 HValue* new_space_dominator() const { return new_space_dominator_; } | 6190 HValue* new_space_dominator() const { return new_space_dominator_; } |
6148 | 6191 |
6149 bool NeedsWriteBarrier() { | 6192 bool NeedsWriteBarrier() { |
6150 ASSERT(!(FLAG_track_double_fields && field_representation().IsDouble()) || | 6193 ASSERT(!(FLAG_track_double_fields && field_representation().IsDouble()) || |
6151 transition_.is_null()); | 6194 transition_.is_null()); |
6152 if (IsSkipWriteBarrier()) return false; | 6195 if (IsSkipWriteBarrier()) return false; |
6153 if (field_representation().IsDouble()) return false; | 6196 if (field_representation().IsDouble()) return false; |
6154 if (field_representation().IsSmi()) return false; | 6197 if (field_representation().IsSmi()) return false; |
| 6198 if (field_representation().IsInteger32()) return false; |
6155 return StoringValueNeedsWriteBarrier(value()) && | 6199 return StoringValueNeedsWriteBarrier(value()) && |
6156 ReceiverObjectNeedsWriteBarrier(object(), new_space_dominator()); | 6200 ReceiverObjectNeedsWriteBarrier(object(), new_space_dominator()); |
6157 } | 6201 } |
6158 | 6202 |
6159 bool NeedsWriteBarrierForMap() { | 6203 bool NeedsWriteBarrierForMap() { |
6160 if (IsSkipWriteBarrier()) return false; | 6204 if (IsSkipWriteBarrier()) return false; |
6161 return ReceiverObjectNeedsWriteBarrier(object(), new_space_dominator()); | 6205 return ReceiverObjectNeedsWriteBarrier(object(), new_space_dominator()); |
6162 } | 6206 } |
6163 | 6207 |
6164 virtual void FinalizeUniqueValueId() { | 6208 virtual void FinalizeUniqueValueId() { |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6225 new_space_dominator_(NULL) { | 6269 new_space_dominator_(NULL) { |
6226 SetOperandAt(0, obj); | 6270 SetOperandAt(0, obj); |
6227 SetOperandAt(1, key); | 6271 SetOperandAt(1, key); |
6228 SetOperandAt(2, val); | 6272 SetOperandAt(2, val); |
6229 | 6273 |
6230 if (IsFastObjectElementsKind(elements_kind)) { | 6274 if (IsFastObjectElementsKind(elements_kind)) { |
6231 SetFlag(kTrackSideEffectDominators); | 6275 SetFlag(kTrackSideEffectDominators); |
6232 SetGVNFlag(kDependsOnNewSpacePromotion); | 6276 SetGVNFlag(kDependsOnNewSpacePromotion); |
6233 } | 6277 } |
6234 if (is_external()) { | 6278 if (is_external()) { |
6235 SetGVNFlag(kChangesSpecializedArrayElements); | 6279 SetGVNFlag(kChangesExternalMemory); |
6236 SetFlag(kAllowUndefinedAsNaN); | 6280 SetFlag(kAllowUndefinedAsNaN); |
6237 } else if (IsFastDoubleElementsKind(elements_kind)) { | 6281 } else if (IsFastDoubleElementsKind(elements_kind)) { |
6238 SetGVNFlag(kChangesDoubleArrayElements); | 6282 SetGVNFlag(kChangesDoubleArrayElements); |
6239 } else if (IsFastSmiElementsKind(elements_kind)) { | 6283 } else if (IsFastSmiElementsKind(elements_kind)) { |
6240 SetGVNFlag(kChangesArrayElements); | 6284 SetGVNFlag(kChangesArrayElements); |
6241 } else { | 6285 } else { |
6242 SetGVNFlag(kChangesArrayElements); | 6286 SetGVNFlag(kChangesArrayElements); |
6243 } | 6287 } |
6244 | 6288 |
6245 // EXTERNAL_{UNSIGNED_,}{BYTE,SHORT,INT}_ELEMENTS are truncating. | 6289 // EXTERNAL_{UNSIGNED_,}{BYTE,SHORT,INT}_ELEMENTS are truncating. |
(...skipping 716 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6962 virtual bool IsDeletable() const { return true; } | 7006 virtual bool IsDeletable() const { return true; } |
6963 }; | 7007 }; |
6964 | 7008 |
6965 | 7009 |
6966 #undef DECLARE_INSTRUCTION | 7010 #undef DECLARE_INSTRUCTION |
6967 #undef DECLARE_CONCRETE_INSTRUCTION | 7011 #undef DECLARE_CONCRETE_INSTRUCTION |
6968 | 7012 |
6969 } } // namespace v8::internal | 7013 } } // namespace v8::internal |
6970 | 7014 |
6971 #endif // V8_HYDROGEN_INSTRUCTIONS_H_ | 7015 #endif // V8_HYDROGEN_INSTRUCTIONS_H_ |
OLD | NEW |