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 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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 HType() : type_(kUninitialized) { } | 353 HType() : type_(kUninitialized) { } |
354 | 354 |
| 355 static HType None() { return HType(kNone); } |
355 static HType Tagged() { return HType(kTagged); } | 356 static HType Tagged() { return HType(kTagged); } |
356 static HType TaggedPrimitive() { return HType(kTaggedPrimitive); } | 357 static HType TaggedPrimitive() { return HType(kTaggedPrimitive); } |
357 static HType TaggedNumber() { return HType(kTaggedNumber); } | 358 static HType TaggedNumber() { return HType(kTaggedNumber); } |
358 static HType Smi() { return HType(kSmi); } | 359 static HType Smi() { return HType(kSmi); } |
359 static HType HeapNumber() { return HType(kHeapNumber); } | 360 static HType HeapNumber() { return HType(kHeapNumber); } |
360 static HType String() { return HType(kString); } | 361 static HType String() { return HType(kString); } |
361 static HType Boolean() { return HType(kBoolean); } | 362 static HType Boolean() { return HType(kBoolean); } |
362 static HType NonPrimitive() { return HType(kNonPrimitive); } | 363 static HType NonPrimitive() { return HType(kNonPrimitive); } |
363 static HType JSArray() { return HType(kJSArray); } | 364 static HType JSArray() { return HType(kJSArray); } |
364 static HType JSObject() { return HType(kJSObject); } | 365 static HType JSObject() { return HType(kJSObject); } |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
440 ASSERT(type_ != kUninitialized); | 441 ASSERT(type_ != kUninitialized); |
441 return IsHeapNumber() || IsString() || IsBoolean() || IsNonPrimitive(); | 442 return IsHeapNumber() || IsString() || IsBoolean() || IsNonPrimitive(); |
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 2215 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2675 // change. The external array of a specialized array elements object cannot | 2677 // change. The external array of a specialized array elements object cannot |
2676 // change once set, so it's no necessary to introduce any additional | 2678 // change once set, so it's no necessary to introduce any additional |
2677 // dependencies on top of the inputs. | 2679 // dependencies on top of the inputs. |
2678 SetFlag(kUseGVN); | 2680 SetFlag(kUseGVN); |
2679 } | 2681 } |
2680 | 2682 |
2681 virtual Representation RequiredInputRepresentation(int index) { | 2683 virtual Representation RequiredInputRepresentation(int index) { |
2682 return Representation::Tagged(); | 2684 return Representation::Tagged(); |
2683 } | 2685 } |
2684 | 2686 |
| 2687 virtual HType CalculateInferredType() { |
| 2688 return HType::None(); |
| 2689 } |
| 2690 |
2685 DECLARE_CONCRETE_INSTRUCTION(LoadExternalArrayPointer) | 2691 DECLARE_CONCRETE_INSTRUCTION(LoadExternalArrayPointer) |
2686 | 2692 |
2687 protected: | 2693 protected: |
2688 virtual bool DataEquals(HValue* other) { return true; } | 2694 virtual bool DataEquals(HValue* other) { return true; } |
2689 | 2695 |
2690 private: | 2696 private: |
2691 virtual bool IsDeletable() const { return true; } | 2697 virtual bool IsDeletable() const { return true; } |
2692 }; | 2698 }; |
2693 | 2699 |
2694 | 2700 |
(...skipping 769 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3464 bool is_not_in_new_space = true, | 3470 bool is_not_in_new_space = true, |
3465 Handle<Object> optional_handle = Handle<Object>::null()); | 3471 Handle<Object> optional_handle = Handle<Object>::null()); |
3466 HConstant(Handle<Object> handle, | 3472 HConstant(Handle<Object> handle, |
3467 UniqueValueId unique_id, | 3473 UniqueValueId unique_id, |
3468 Representation r, | 3474 Representation r, |
3469 HType type, | 3475 HType type, |
3470 bool is_internalized_string, | 3476 bool is_internalized_string, |
3471 bool is_not_in_new_space, | 3477 bool is_not_in_new_space, |
3472 bool is_cell, | 3478 bool is_cell, |
3473 bool boolean_value); | 3479 bool boolean_value); |
| 3480 explicit HConstant(ExternalReference reference); |
3474 | 3481 |
3475 Handle<Object> handle() { | 3482 Handle<Object> handle() { |
3476 if (handle_.is_null()) { | 3483 if (handle_.is_null()) { |
3477 Factory* factory = Isolate::Current()->factory(); | 3484 Factory* factory = Isolate::Current()->factory(); |
3478 // Default arguments to is_not_in_new_space depend on this heap number | 3485 // Default arguments to is_not_in_new_space depend on this heap number |
3479 // to be tenured so that it's guaranteed not be be located in new space. | 3486 // to be tenured so that it's guaranteed not be be located in new space. |
3480 handle_ = factory->NewNumber(double_value_, TENURED); | 3487 handle_ = factory->NewNumber(double_value_, TENURED); |
3481 } | 3488 } |
3482 AllowDeferredHandleDereference smi_check; | 3489 AllowDeferredHandleDereference smi_check; |
3483 ASSERT(has_int32_value_ || !handle_->IsSmi()); | 3490 ASSERT(has_int32_value_ || !handle_->IsSmi()); |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3528 } | 3535 } |
3529 | 3536 |
3530 virtual Representation RequiredInputRepresentation(int index) { | 3537 virtual Representation RequiredInputRepresentation(int index) { |
3531 return Representation::None(); | 3538 return Representation::None(); |
3532 } | 3539 } |
3533 | 3540 |
3534 virtual Representation KnownOptimalRepresentation() { | 3541 virtual Representation KnownOptimalRepresentation() { |
3535 if (HasSmiValue() && kSmiValueSize == 31) return Representation::Smi(); | 3542 if (HasSmiValue() && kSmiValueSize == 31) return Representation::Smi(); |
3536 if (HasInteger32Value()) return Representation::Integer32(); | 3543 if (HasInteger32Value()) return Representation::Integer32(); |
3537 if (HasNumberValue()) return Representation::Double(); | 3544 if (HasNumberValue()) return Representation::Double(); |
| 3545 if (HasExternalReferenceValue()) return Representation::External(); |
3538 return Representation::Tagged(); | 3546 return Representation::Tagged(); |
3539 } | 3547 } |
3540 | 3548 |
3541 virtual bool EmitAtUses(); | 3549 virtual bool EmitAtUses(); |
3542 virtual void PrintDataTo(StringStream* stream); | 3550 virtual void PrintDataTo(StringStream* stream); |
3543 virtual HType CalculateInferredType(); | 3551 virtual HType CalculateInferredType(); |
3544 bool IsInteger() { return handle()->IsSmi(); } | 3552 bool IsInteger() { return handle()->IsSmi(); } |
3545 HConstant* CopyToRepresentation(Representation r, Zone* zone) const; | 3553 HConstant* CopyToRepresentation(Representation r, Zone* zone) const; |
3546 Maybe<HConstant*> CopyToTruncatedInt32(Zone* zone); | 3554 Maybe<HConstant*> CopyToTruncatedInt32(Zone* zone); |
3547 Maybe<HConstant*> CopyToTruncatedNumber(Zone* zone); | 3555 Maybe<HConstant*> CopyToTruncatedNumber(Zone* zone); |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3580 return type_from_value_.IsString(); | 3588 return type_from_value_.IsString(); |
3581 } | 3589 } |
3582 Handle<String> StringValue() const { | 3590 Handle<String> StringValue() const { |
3583 ASSERT(HasStringValue()); | 3591 ASSERT(HasStringValue()); |
3584 return Handle<String>::cast(handle_); | 3592 return Handle<String>::cast(handle_); |
3585 } | 3593 } |
3586 bool HasInternalizedStringValue() const { | 3594 bool HasInternalizedStringValue() const { |
3587 return HasStringValue() && is_internalized_string_; | 3595 return HasStringValue() && is_internalized_string_; |
3588 } | 3596 } |
3589 | 3597 |
| 3598 bool HasExternalReferenceValue() const { |
| 3599 return has_external_reference_value_; |
| 3600 } |
| 3601 ExternalReference ExternalReferenceValue() const { |
| 3602 return external_reference_value_; |
| 3603 } |
| 3604 |
3590 bool BooleanValue() const { return boolean_value_; } | 3605 bool BooleanValue() const { return boolean_value_; } |
3591 | 3606 |
3592 virtual intptr_t Hashcode() { | 3607 virtual intptr_t Hashcode() { |
3593 if (has_int32_value_) { | 3608 if (has_int32_value_) { |
3594 return static_cast<intptr_t>(int32_value_); | 3609 return static_cast<intptr_t>(int32_value_); |
3595 } else if (has_double_value_) { | 3610 } else if (has_double_value_) { |
3596 return static_cast<intptr_t>(BitCast<int64_t>(double_value_)); | 3611 return static_cast<intptr_t>(BitCast<int64_t>(double_value_)); |
| 3612 } else if (has_external_reference_value_) { |
| 3613 return reinterpret_cast<intptr_t>(external_reference_value_.address()); |
3597 } else { | 3614 } else { |
3598 ASSERT(!handle_.is_null()); | 3615 ASSERT(!handle_.is_null()); |
3599 return unique_id_.Hashcode(); | 3616 return unique_id_.Hashcode(); |
3600 } | 3617 } |
3601 } | 3618 } |
3602 | 3619 |
3603 virtual void FinalizeUniqueValueId() { | 3620 virtual void FinalizeUniqueValueId() { |
3604 if (!has_double_value_) { | 3621 if (!has_double_value_ && !has_external_reference_value_) { |
3605 ASSERT(!handle_.is_null()); | 3622 ASSERT(!handle_.is_null()); |
3606 unique_id_ = UniqueValueId(handle_); | 3623 unique_id_ = UniqueValueId(handle_); |
3607 } | 3624 } |
3608 } | 3625 } |
3609 | 3626 |
3610 bool UniqueValueIdsMatch(UniqueValueId other) { | 3627 bool UniqueValueIdsMatch(UniqueValueId other) { |
3611 return !has_double_value_ && unique_id_ == other; | 3628 return !has_double_value_ && !has_external_reference_value_ && |
| 3629 unique_id_ == other; |
3612 } | 3630 } |
3613 | 3631 |
3614 #ifdef DEBUG | 3632 #ifdef DEBUG |
3615 virtual void Verify() { } | 3633 virtual void Verify() { } |
3616 #endif | 3634 #endif |
3617 | 3635 |
3618 DECLARE_CONCRETE_INSTRUCTION(Constant) | 3636 DECLARE_CONCRETE_INSTRUCTION(Constant) |
3619 | 3637 |
3620 protected: | 3638 protected: |
3621 virtual Range* InferRange(Zone* zone); | 3639 virtual Range* InferRange(Zone* zone); |
3622 | 3640 |
3623 virtual bool DataEquals(HValue* other) { | 3641 virtual bool DataEquals(HValue* other) { |
3624 HConstant* other_constant = HConstant::cast(other); | 3642 HConstant* other_constant = HConstant::cast(other); |
3625 if (has_int32_value_) { | 3643 if (has_int32_value_) { |
3626 return other_constant->has_int32_value_ && | 3644 return other_constant->has_int32_value_ && |
3627 int32_value_ == other_constant->int32_value_; | 3645 int32_value_ == other_constant->int32_value_; |
3628 } else if (has_double_value_) { | 3646 } else if (has_double_value_) { |
3629 return other_constant->has_double_value_ && | 3647 return other_constant->has_double_value_ && |
3630 BitCast<int64_t>(double_value_) == | 3648 BitCast<int64_t>(double_value_) == |
3631 BitCast<int64_t>(other_constant->double_value_); | 3649 BitCast<int64_t>(other_constant->double_value_); |
| 3650 } else if (has_external_reference_value_) { |
| 3651 return other_constant->has_external_reference_value_ && |
| 3652 external_reference_value_ == |
| 3653 other_constant->external_reference_value_; |
3632 } else { | 3654 } else { |
3633 ASSERT(!handle_.is_null()); | 3655 ASSERT(!handle_.is_null()); |
3634 return !other_constant->handle_.is_null() && | 3656 return !other_constant->handle_.is_null() && |
3635 unique_id_ == other_constant->unique_id_; | 3657 unique_id_ == other_constant->unique_id_; |
3636 } | 3658 } |
3637 } | 3659 } |
3638 | 3660 |
3639 private: | 3661 private: |
3640 void Initialize(Representation r); | 3662 void Initialize(Representation r); |
3641 | 3663 |
3642 virtual bool IsDeletable() const { return true; } | 3664 virtual bool IsDeletable() const { return true; } |
3643 | 3665 |
3644 // If this is a numerical constant, handle_ either points to to the | 3666 // If this is a numerical constant, handle_ either points to to the |
3645 // HeapObject the constant originated from or is null. If the | 3667 // HeapObject the constant originated from or is null. If the |
3646 // constant is non-numeric, handle_ always points to a valid | 3668 // constant is non-numeric, handle_ always points to a valid |
3647 // constant HeapObject. | 3669 // constant HeapObject. |
3648 Handle<Object> handle_; | 3670 Handle<Object> handle_; |
3649 UniqueValueId unique_id_; | 3671 UniqueValueId unique_id_; |
3650 | 3672 |
3651 // We store the HConstant in the most specific form safely possible. | 3673 // We store the HConstant in the most specific form safely possible. |
3652 // The two flags, has_int32_value_ and has_double_value_ tell us if | 3674 // The two flags, has_int32_value_ and has_double_value_ tell us if |
3653 // int32_value_ and double_value_ hold valid, safe representations | 3675 // int32_value_ and double_value_ hold valid, safe representations |
3654 // of the constant. has_int32_value_ implies has_double_value_ but | 3676 // of the constant. has_int32_value_ implies has_double_value_ but |
3655 // not the converse. | 3677 // not the converse. |
3656 bool has_smi_value_ : 1; | 3678 bool has_smi_value_ : 1; |
3657 bool has_int32_value_ : 1; | 3679 bool has_int32_value_ : 1; |
3658 bool has_double_value_ : 1; | 3680 bool has_double_value_ : 1; |
| 3681 bool has_external_reference_value_ : 1; |
3659 bool is_internalized_string_ : 1; // TODO(yangguo): make this part of HType. | 3682 bool is_internalized_string_ : 1; // TODO(yangguo): make this part of HType. |
3660 bool is_not_in_new_space_ : 1; | 3683 bool is_not_in_new_space_ : 1; |
3661 bool is_cell_ : 1; | 3684 bool is_cell_ : 1; |
3662 bool boolean_value_ : 1; | 3685 bool boolean_value_ : 1; |
3663 int32_t int32_value_; | 3686 int32_t int32_value_; |
3664 double double_value_; | 3687 double double_value_; |
| 3688 ExternalReference external_reference_value_; |
3665 HType type_from_value_; | 3689 HType type_from_value_; |
3666 }; | 3690 }; |
3667 | 3691 |
3668 | 3692 |
3669 class HBinaryOperation: public HTemplateInstruction<3> { | 3693 class HBinaryOperation: public HTemplateInstruction<3> { |
3670 public: | 3694 public: |
3671 HBinaryOperation(HValue* context, HValue* left, HValue* right) | 3695 HBinaryOperation(HValue* context, HValue* left, HValue* right) |
3672 : observed_output_representation_(Representation::None()) { | 3696 : observed_output_representation_(Representation::None()) { |
3673 ASSERT(left != NULL && right != NULL); | 3697 ASSERT(left != NULL && right != NULL); |
3674 SetOperandAt(0, context); | 3698 SetOperandAt(0, context); |
(...skipping 1871 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5546 int slot_index_; | 5570 int slot_index_; |
5547 Mode mode_; | 5571 Mode mode_; |
5548 }; | 5572 }; |
5549 | 5573 |
5550 | 5574 |
5551 // Represents an access to a portion of an object, such as the map pointer, | 5575 // Represents an access to a portion of an object, such as the map pointer, |
5552 // array elements pointer, etc, but not accesses to array elements themselves. | 5576 // array elements pointer, etc, but not accesses to array elements themselves. |
5553 class HObjectAccess { | 5577 class HObjectAccess { |
5554 public: | 5578 public: |
5555 inline bool IsInobject() const { | 5579 inline bool IsInobject() const { |
5556 return portion() != kBackingStore; | 5580 return portion() != kBackingStore && portion() != kExternalMemory; |
| 5581 } |
| 5582 |
| 5583 inline bool IsExternalMemory() const { |
| 5584 return portion() == kExternalMemory; |
5557 } | 5585 } |
5558 | 5586 |
5559 inline int offset() const { | 5587 inline int offset() const { |
5560 return OffsetField::decode(value_); | 5588 return OffsetField::decode(value_); |
5561 } | 5589 } |
5562 | 5590 |
5563 inline Representation representation() const { | 5591 inline Representation representation() const { |
5564 return Representation::FromKind(RepresentationField::decode(value_)); | 5592 return Representation::FromKind(RepresentationField::decode(value_)); |
5565 } | 5593 } |
5566 | 5594 |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5620 } | 5648 } |
5621 | 5649 |
5622 static HObjectAccess ForCellValue() { | 5650 static HObjectAccess ForCellValue() { |
5623 return HObjectAccess(kInobject, Cell::kValueOffset); | 5651 return HObjectAccess(kInobject, Cell::kValueOffset); |
5624 } | 5652 } |
5625 | 5653 |
5626 static HObjectAccess ForAllocationMementoSite() { | 5654 static HObjectAccess ForAllocationMementoSite() { |
5627 return HObjectAccess(kInobject, AllocationMemento::kAllocationSiteOffset); | 5655 return HObjectAccess(kInobject, AllocationMemento::kAllocationSiteOffset); |
5628 } | 5656 } |
5629 | 5657 |
| 5658 static HObjectAccess ForCounter() { |
| 5659 return HObjectAccess(kExternalMemory, 0, Representation::Integer32()); |
| 5660 } |
| 5661 |
5630 // Create an access to an offset in a fixed array header. | 5662 // Create an access to an offset in a fixed array header. |
5631 static HObjectAccess ForFixedArrayHeader(int offset); | 5663 static HObjectAccess ForFixedArrayHeader(int offset); |
5632 | 5664 |
5633 // Create an access to an in-object property in a JSObject. | 5665 // Create an access to an in-object property in a JSObject. |
5634 static HObjectAccess ForJSObjectOffset(int offset, | 5666 static HObjectAccess ForJSObjectOffset(int offset, |
5635 Representation representation = Representation::Tagged()); | 5667 Representation representation = Representation::Tagged()); |
5636 | 5668 |
5637 // Create an access to an in-object property in a JSArray. | 5669 // Create an access to an in-object property in a JSArray. |
5638 static HObjectAccess ForJSArrayOffset(int offset); | 5670 static HObjectAccess ForJSArrayOffset(int offset); |
5639 | 5671 |
(...skipping 18 matching lines...) Expand all Loading... |
5658 void SetGVNFlags(HValue *instr, bool is_store); | 5690 void SetGVNFlags(HValue *instr, bool is_store); |
5659 | 5691 |
5660 private: | 5692 private: |
5661 // internal use only; different parts of an object or array | 5693 // internal use only; different parts of an object or array |
5662 enum Portion { | 5694 enum Portion { |
5663 kMaps, // map of an object | 5695 kMaps, // map of an object |
5664 kArrayLengths, // the length of an array | 5696 kArrayLengths, // the length of an array |
5665 kElementsPointer, // elements pointer | 5697 kElementsPointer, // elements pointer |
5666 kBackingStore, // some field in the backing store | 5698 kBackingStore, // some field in the backing store |
5667 kDouble, // some double field | 5699 kDouble, // some double field |
5668 kInobject // some other in-object field | 5700 kInobject, // some other in-object field |
| 5701 kExternalMemory // some field in external memory |
5669 }; | 5702 }; |
5670 | 5703 |
5671 HObjectAccess(Portion portion, int offset, | 5704 HObjectAccess(Portion portion, int offset, |
5672 Representation representation = Representation::Tagged(), | 5705 Representation representation = Representation::Tagged(), |
5673 Handle<String> name = Handle<String>::null()) | 5706 Handle<String> name = Handle<String>::null()) |
5674 : value_(PortionField::encode(portion) | | 5707 : value_(PortionField::encode(portion) | |
5675 RepresentationField::encode(representation.kind()) | | 5708 RepresentationField::encode(representation.kind()) | |
5676 OffsetField::encode(offset)), | 5709 OffsetField::encode(offset)), |
5677 name_(name) { | 5710 name_(name) { |
5678 // assert that the fields decode correctly | 5711 // assert that the fields decode correctly |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5736 HValue* typecheck = NULL) | 5769 HValue* typecheck = NULL) |
5737 : access_(access) { | 5770 : access_(access) { |
5738 ASSERT(object != NULL); | 5771 ASSERT(object != NULL); |
5739 SetOperandAt(0, object); | 5772 SetOperandAt(0, object); |
5740 SetOperandAt(1, typecheck != NULL ? typecheck : object); | 5773 SetOperandAt(1, typecheck != NULL ? typecheck : object); |
5741 | 5774 |
5742 Representation representation = access.representation(); | 5775 Representation representation = access.representation(); |
5743 if (representation.IsSmi()) { | 5776 if (representation.IsSmi()) { |
5744 set_type(HType::Smi()); | 5777 set_type(HType::Smi()); |
5745 set_representation(representation); | 5778 set_representation(representation); |
5746 } else if (representation.IsDouble()) { | 5779 } else if (representation.IsDouble() || |
| 5780 representation.IsExternal() || |
| 5781 representation.IsInteger32()) { |
5747 set_representation(representation); | 5782 set_representation(representation); |
5748 } else if (FLAG_track_heap_object_fields && | 5783 } else if (FLAG_track_heap_object_fields && |
5749 representation.IsHeapObject()) { | 5784 representation.IsHeapObject()) { |
5750 set_type(HType::NonPrimitive()); | 5785 set_type(HType::NonPrimitive()); |
5751 set_representation(Representation::Tagged()); | 5786 set_representation(Representation::Tagged()); |
5752 } else { | 5787 } else { |
5753 set_representation(Representation::Tagged()); | 5788 set_representation(Representation::Tagged()); |
5754 } | 5789 } |
5755 access.SetGVNFlags(this, false); | 5790 access.SetGVNFlags(this, false); |
5756 } | 5791 } |
5757 | 5792 |
5758 HValue* object() { return OperandAt(0); } | 5793 HValue* object() { return OperandAt(0); } |
5759 HValue* typecheck() { | 5794 HValue* typecheck() { |
5760 ASSERT(HasTypeCheck()); | 5795 ASSERT(HasTypeCheck()); |
5761 return OperandAt(1); | 5796 return OperandAt(1); |
5762 } | 5797 } |
5763 | 5798 |
5764 bool HasTypeCheck() const { return OperandAt(0) != OperandAt(1); } | 5799 bool HasTypeCheck() const { return OperandAt(0) != OperandAt(1); } |
5765 HObjectAccess access() const { return access_; } | 5800 HObjectAccess access() const { return access_; } |
5766 Representation field_representation() const { | 5801 Representation field_representation() const { |
5767 return access_.representation(); | 5802 return access_.representation(); |
5768 } | 5803 } |
5769 | 5804 |
5770 virtual bool HasEscapingOperandAt(int index) { return false; } | 5805 virtual bool HasEscapingOperandAt(int index) { return false; } |
5771 virtual Representation RequiredInputRepresentation(int index) { | 5806 virtual Representation RequiredInputRepresentation(int index) { |
| 5807 if (index == 0 && access().IsExternalMemory()) { |
| 5808 // object must be external in case of external memory access |
| 5809 return Representation::External(); |
| 5810 } |
5772 return Representation::Tagged(); | 5811 return Representation::Tagged(); |
5773 } | 5812 } |
5774 virtual void PrintDataTo(StringStream* stream); | 5813 virtual void PrintDataTo(StringStream* stream); |
5775 | 5814 |
5776 DECLARE_CONCRETE_INSTRUCTION(LoadNamedField) | 5815 DECLARE_CONCRETE_INSTRUCTION(LoadNamedField) |
5777 | 5816 |
5778 protected: | 5817 protected: |
5779 virtual bool DataEquals(HValue* other) { | 5818 virtual bool DataEquals(HValue* other) { |
5780 HLoadNamedField* b = HLoadNamedField::cast(other); | 5819 HLoadNamedField* b = HLoadNamedField::cast(other); |
5781 return access_.Equals(b->access_); | 5820 return access_.Equals(b->access_); |
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5935 SetGVNFlag(kDependsOnDoubleArrayElements); | 5974 SetGVNFlag(kDependsOnDoubleArrayElements); |
5936 } | 5975 } |
5937 } else { | 5976 } else { |
5938 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS || | 5977 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS || |
5939 elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { | 5978 elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { |
5940 set_representation(Representation::Double()); | 5979 set_representation(Representation::Double()); |
5941 } else { | 5980 } else { |
5942 set_representation(Representation::Integer32()); | 5981 set_representation(Representation::Integer32()); |
5943 } | 5982 } |
5944 | 5983 |
5945 SetGVNFlag(kDependsOnSpecializedArrayElements); | 5984 SetGVNFlag(kDependsOnExternalMemory); |
5946 // Native code could change the specialized array. | 5985 // Native code could change the specialized array. |
5947 SetGVNFlag(kDependsOnCalls); | 5986 SetGVNFlag(kDependsOnCalls); |
5948 } | 5987 } |
5949 | 5988 |
5950 SetFlag(kUseGVN); | 5989 SetFlag(kUseGVN); |
5951 } | 5990 } |
5952 | 5991 |
5953 bool is_external() const { | 5992 bool is_external() const { |
5954 return IsExternalArrayElementsKind(elements_kind()); | 5993 return IsExternalArrayElementsKind(elements_kind()); |
5955 } | 5994 } |
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6092 write_barrier_mode_(UPDATE_WRITE_BARRIER) { | 6131 write_barrier_mode_(UPDATE_WRITE_BARRIER) { |
6093 SetOperandAt(0, obj); | 6132 SetOperandAt(0, obj); |
6094 SetOperandAt(1, val); | 6133 SetOperandAt(1, val); |
6095 access.SetGVNFlags(this, true); | 6134 access.SetGVNFlags(this, true); |
6096 } | 6135 } |
6097 | 6136 |
6098 DECLARE_CONCRETE_INSTRUCTION(StoreNamedField) | 6137 DECLARE_CONCRETE_INSTRUCTION(StoreNamedField) |
6099 | 6138 |
6100 virtual bool HasEscapingOperandAt(int index) { return index == 1; } | 6139 virtual bool HasEscapingOperandAt(int index) { return index == 1; } |
6101 virtual Representation RequiredInputRepresentation(int index) { | 6140 virtual Representation RequiredInputRepresentation(int index) { |
6102 if (index == 1 && field_representation().IsDouble()) { | 6141 if (index == 0 && access().IsExternalMemory()) { |
6103 return field_representation(); | 6142 // object must be external in case of external memory access |
6104 } else if (index == 1 && field_representation().IsSmi()) { | 6143 return Representation::External(); |
| 6144 } else if (index == 1 && |
| 6145 (field_representation().IsDouble() || |
| 6146 field_representation().IsSmi() || |
| 6147 field_representation().IsInteger32())) { |
6105 return field_representation(); | 6148 return field_representation(); |
6106 } | 6149 } |
6107 return Representation::Tagged(); | 6150 return Representation::Tagged(); |
6108 } | 6151 } |
6109 virtual void HandleSideEffectDominator(GVNFlag side_effect, | 6152 virtual void HandleSideEffectDominator(GVNFlag side_effect, |
6110 HValue* dominator) { | 6153 HValue* dominator) { |
6111 ASSERT(side_effect == kChangesNewSpacePromotion); | 6154 ASSERT(side_effect == kChangesNewSpacePromotion); |
6112 new_space_dominator_ = dominator; | 6155 new_space_dominator_ = dominator; |
6113 } | 6156 } |
6114 virtual void PrintDataTo(StringStream* stream); | 6157 virtual void PrintDataTo(StringStream* stream); |
(...skipping 17 matching lines...) Expand all Loading... |
6132 transition_ = map; | 6175 transition_ = map; |
6133 } | 6176 } |
6134 HValue* new_space_dominator() const { return new_space_dominator_; } | 6177 HValue* new_space_dominator() const { return new_space_dominator_; } |
6135 | 6178 |
6136 bool NeedsWriteBarrier() { | 6179 bool NeedsWriteBarrier() { |
6137 ASSERT(!(FLAG_track_double_fields && field_representation().IsDouble()) || | 6180 ASSERT(!(FLAG_track_double_fields && field_representation().IsDouble()) || |
6138 transition_.is_null()); | 6181 transition_.is_null()); |
6139 if (IsSkipWriteBarrier()) return false; | 6182 if (IsSkipWriteBarrier()) return false; |
6140 if (field_representation().IsDouble()) return false; | 6183 if (field_representation().IsDouble()) return false; |
6141 if (field_representation().IsSmi()) return false; | 6184 if (field_representation().IsSmi()) return false; |
| 6185 if (field_representation().IsInteger32()) return false; |
6142 return StoringValueNeedsWriteBarrier(value()) && | 6186 return StoringValueNeedsWriteBarrier(value()) && |
6143 ReceiverObjectNeedsWriteBarrier(object(), new_space_dominator()); | 6187 ReceiverObjectNeedsWriteBarrier(object(), new_space_dominator()); |
6144 } | 6188 } |
6145 | 6189 |
6146 bool NeedsWriteBarrierForMap() { | 6190 bool NeedsWriteBarrierForMap() { |
6147 if (IsSkipWriteBarrier()) return false; | 6191 if (IsSkipWriteBarrier()) return false; |
6148 return ReceiverObjectNeedsWriteBarrier(object(), new_space_dominator()); | 6192 return ReceiverObjectNeedsWriteBarrier(object(), new_space_dominator()); |
6149 } | 6193 } |
6150 | 6194 |
6151 virtual void FinalizeUniqueValueId() { | 6195 virtual void FinalizeUniqueValueId() { |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6212 new_space_dominator_(NULL) { | 6256 new_space_dominator_(NULL) { |
6213 SetOperandAt(0, obj); | 6257 SetOperandAt(0, obj); |
6214 SetOperandAt(1, key); | 6258 SetOperandAt(1, key); |
6215 SetOperandAt(2, val); | 6259 SetOperandAt(2, val); |
6216 | 6260 |
6217 if (IsFastObjectElementsKind(elements_kind)) { | 6261 if (IsFastObjectElementsKind(elements_kind)) { |
6218 SetFlag(kTrackSideEffectDominators); | 6262 SetFlag(kTrackSideEffectDominators); |
6219 SetGVNFlag(kDependsOnNewSpacePromotion); | 6263 SetGVNFlag(kDependsOnNewSpacePromotion); |
6220 } | 6264 } |
6221 if (is_external()) { | 6265 if (is_external()) { |
6222 SetGVNFlag(kChangesSpecializedArrayElements); | 6266 SetGVNFlag(kChangesExternalMemory); |
6223 SetFlag(kAllowUndefinedAsNaN); | 6267 SetFlag(kAllowUndefinedAsNaN); |
6224 } else if (IsFastDoubleElementsKind(elements_kind)) { | 6268 } else if (IsFastDoubleElementsKind(elements_kind)) { |
6225 SetGVNFlag(kChangesDoubleArrayElements); | 6269 SetGVNFlag(kChangesDoubleArrayElements); |
6226 } else if (IsFastSmiElementsKind(elements_kind)) { | 6270 } else if (IsFastSmiElementsKind(elements_kind)) { |
6227 SetGVNFlag(kChangesArrayElements); | 6271 SetGVNFlag(kChangesArrayElements); |
6228 } else { | 6272 } else { |
6229 SetGVNFlag(kChangesArrayElements); | 6273 SetGVNFlag(kChangesArrayElements); |
6230 } | 6274 } |
6231 | 6275 |
6232 // EXTERNAL_{UNSIGNED_,}{BYTE,SHORT,INT}_ELEMENTS are truncating. | 6276 // EXTERNAL_{UNSIGNED_,}{BYTE,SHORT,INT}_ELEMENTS are truncating. |
(...skipping 714 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6947 virtual bool IsDeletable() const { return true; } | 6991 virtual bool IsDeletable() const { return true; } |
6948 }; | 6992 }; |
6949 | 6993 |
6950 | 6994 |
6951 #undef DECLARE_INSTRUCTION | 6995 #undef DECLARE_INSTRUCTION |
6952 #undef DECLARE_CONCRETE_INSTRUCTION | 6996 #undef DECLARE_CONCRETE_INSTRUCTION |
6953 | 6997 |
6954 } } // namespace v8::internal | 6998 } } // namespace v8::internal |
6955 | 6999 |
6956 #endif // V8_HYDROGEN_INSTRUCTIONS_H_ | 7000 #endif // V8_HYDROGEN_INSTRUCTIONS_H_ |
OLD | NEW |