OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 // | 4 // |
5 // Review notes: | 5 // Review notes: |
6 // | 6 // |
7 // - The use of macros in these inline functions may seem superfluous | 7 // - The use of macros in these inline functions may seem superfluous |
8 // but it is absolutely needed to make sure gcc generates optimal | 8 // but it is absolutely needed to make sure gcc generates optimal |
9 // code. gcc is not happy when attempting to inline too deep. | 9 // code. gcc is not happy when attempting to inline too deep. |
10 // | 10 // |
(...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
268 STATIC_ASSERT(kNotInternalizedTag != 0); | 268 STATIC_ASSERT(kNotInternalizedTag != 0); |
269 return (type & (kIsNotStringMask | kIsNotInternalizedMask)) == | 269 return (type & (kIsNotStringMask | kIsNotInternalizedMask)) == |
270 (kStringTag | kInternalizedTag); | 270 (kStringTag | kInternalizedTag); |
271 } | 271 } |
272 | 272 |
273 bool HeapObject::IsConsString() const { | 273 bool HeapObject::IsConsString() const { |
274 if (!IsString()) return false; | 274 if (!IsString()) return false; |
275 return StringShape(String::cast(this)).IsCons(); | 275 return StringShape(String::cast(this)).IsCons(); |
276 } | 276 } |
277 | 277 |
| 278 bool HeapObject::IsThinString() const { |
| 279 if (!IsString()) return false; |
| 280 return StringShape(String::cast(this)).IsThin(); |
| 281 } |
| 282 |
278 bool HeapObject::IsSlicedString() const { | 283 bool HeapObject::IsSlicedString() const { |
279 if (!IsString()) return false; | 284 if (!IsString()) return false; |
280 return StringShape(String::cast(this)).IsSliced(); | 285 return StringShape(String::cast(this)).IsSliced(); |
281 } | 286 } |
282 | 287 |
283 bool HeapObject::IsSeqString() const { | 288 bool HeapObject::IsSeqString() const { |
284 if (!IsString()) return false; | 289 if (!IsString()) return false; |
285 return StringShape(String::cast(this)).IsSequential(); | 290 return StringShape(String::cast(this)).IsSequential(); |
286 } | 291 } |
287 | 292 |
(...skipping 403 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
691 CAST_ACCESSOR(SharedFunctionInfo) | 696 CAST_ACCESSOR(SharedFunctionInfo) |
692 CAST_ACCESSOR(Simd128Value) | 697 CAST_ACCESSOR(Simd128Value) |
693 CAST_ACCESSOR(SlicedString) | 698 CAST_ACCESSOR(SlicedString) |
694 CAST_ACCESSOR(Smi) | 699 CAST_ACCESSOR(Smi) |
695 CAST_ACCESSOR(String) | 700 CAST_ACCESSOR(String) |
696 CAST_ACCESSOR(StringSet) | 701 CAST_ACCESSOR(StringSet) |
697 CAST_ACCESSOR(StringTable) | 702 CAST_ACCESSOR(StringTable) |
698 CAST_ACCESSOR(Struct) | 703 CAST_ACCESSOR(Struct) |
699 CAST_ACCESSOR(Symbol) | 704 CAST_ACCESSOR(Symbol) |
700 CAST_ACCESSOR(TemplateInfo) | 705 CAST_ACCESSOR(TemplateInfo) |
| 706 CAST_ACCESSOR(ThinString) |
701 CAST_ACCESSOR(Uint16x8) | 707 CAST_ACCESSOR(Uint16x8) |
702 CAST_ACCESSOR(Uint32x4) | 708 CAST_ACCESSOR(Uint32x4) |
703 CAST_ACCESSOR(Uint8x16) | 709 CAST_ACCESSOR(Uint8x16) |
704 CAST_ACCESSOR(UnseededNumberDictionary) | 710 CAST_ACCESSOR(UnseededNumberDictionary) |
705 CAST_ACCESSOR(WeakCell) | 711 CAST_ACCESSOR(WeakCell) |
706 CAST_ACCESSOR(WeakFixedArray) | 712 CAST_ACCESSOR(WeakFixedArray) |
707 CAST_ACCESSOR(WeakHashTable) | 713 CAST_ACCESSOR(WeakHashTable) |
708 | 714 |
709 #define MAKE_STRUCT_CAST(NAME, Name, name) CAST_ACCESSOR(Name) | 715 #define MAKE_STRUCT_CAST(NAME, Name, name) CAST_ACCESSOR(Name) |
710 STRUCT_LIST(MAKE_STRUCT_CAST) | 716 STRUCT_LIST(MAKE_STRUCT_CAST) |
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
834 bool String::HasOnlyOneByteChars() { | 840 bool String::HasOnlyOneByteChars() { |
835 uint32_t type = map()->instance_type(); | 841 uint32_t type = map()->instance_type(); |
836 return (type & kOneByteDataHintMask) == kOneByteDataHintTag || | 842 return (type & kOneByteDataHintMask) == kOneByteDataHintTag || |
837 IsOneByteRepresentation(); | 843 IsOneByteRepresentation(); |
838 } | 844 } |
839 | 845 |
840 bool StringShape::IsCons() { | 846 bool StringShape::IsCons() { |
841 return (type_ & kStringRepresentationMask) == kConsStringTag; | 847 return (type_ & kStringRepresentationMask) == kConsStringTag; |
842 } | 848 } |
843 | 849 |
| 850 bool StringShape::IsThin() { |
| 851 return (type_ & kStringRepresentationMask) == kThinStringTag; |
| 852 } |
| 853 |
844 bool StringShape::IsSliced() { | 854 bool StringShape::IsSliced() { |
845 return (type_ & kStringRepresentationMask) == kSlicedStringTag; | 855 return (type_ & kStringRepresentationMask) == kSlicedStringTag; |
846 } | 856 } |
847 | 857 |
848 bool StringShape::IsIndirect() { | 858 bool StringShape::IsIndirect() { |
849 return (type_ & kIsIndirectStringMask) == kIsIndirectStringTag; | 859 return (type_ & kIsIndirectStringMask) == kIsIndirectStringTag; |
850 } | 860 } |
851 | 861 |
852 bool StringShape::IsExternal() { | 862 bool StringShape::IsExternal() { |
853 return (type_ & kStringRepresentationMask) == kExternalStringTag; | 863 return (type_ & kStringRepresentationMask) == kExternalStringTag; |
(...skipping 2801 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3655 bool String::Equals(Handle<String> one, Handle<String> two) { | 3665 bool String::Equals(Handle<String> one, Handle<String> two) { |
3656 if (one.is_identical_to(two)) return true; | 3666 if (one.is_identical_to(two)) return true; |
3657 if (one->IsInternalizedString() && two->IsInternalizedString()) { | 3667 if (one->IsInternalizedString() && two->IsInternalizedString()) { |
3658 return false; | 3668 return false; |
3659 } | 3669 } |
3660 return SlowEquals(one, two); | 3670 return SlowEquals(one, two); |
3661 } | 3671 } |
3662 | 3672 |
3663 | 3673 |
3664 Handle<String> String::Flatten(Handle<String> string, PretenureFlag pretenure) { | 3674 Handle<String> String::Flatten(Handle<String> string, PretenureFlag pretenure) { |
3665 if (!string->IsConsString()) return string; | 3675 if (string->IsConsString()) { |
3666 Handle<ConsString> cons = Handle<ConsString>::cast(string); | 3676 Handle<ConsString> cons = Handle<ConsString>::cast(string); |
3667 if (cons->IsFlat()) return handle(cons->first()); | 3677 if (cons->IsFlat()) { |
3668 return SlowFlatten(cons, pretenure); | 3678 string = handle(cons->first()); |
| 3679 } else { |
| 3680 return SlowFlatten(cons, pretenure); |
| 3681 } |
| 3682 } |
| 3683 if (string->IsThinString()) { |
| 3684 string = handle(Handle<ThinString>::cast(string)->actual()); |
| 3685 DCHECK(!string->IsConsString()); |
| 3686 } |
| 3687 return string; |
3669 } | 3688 } |
3670 | 3689 |
3671 | 3690 |
3672 uint16_t String::Get(int index) { | 3691 uint16_t String::Get(int index) { |
3673 DCHECK(index >= 0 && index < length()); | 3692 DCHECK(index >= 0 && index < length()); |
3674 switch (StringShape(this).full_representation_tag()) { | 3693 switch (StringShape(this).full_representation_tag()) { |
3675 case kSeqStringTag | kOneByteStringTag: | 3694 case kSeqStringTag | kOneByteStringTag: |
3676 return SeqOneByteString::cast(this)->SeqOneByteStringGet(index); | 3695 return SeqOneByteString::cast(this)->SeqOneByteStringGet(index); |
3677 case kSeqStringTag | kTwoByteStringTag: | 3696 case kSeqStringTag | kTwoByteStringTag: |
3678 return SeqTwoByteString::cast(this)->SeqTwoByteStringGet(index); | 3697 return SeqTwoByteString::cast(this)->SeqTwoByteStringGet(index); |
3679 case kConsStringTag | kOneByteStringTag: | 3698 case kConsStringTag | kOneByteStringTag: |
3680 case kConsStringTag | kTwoByteStringTag: | 3699 case kConsStringTag | kTwoByteStringTag: |
3681 return ConsString::cast(this)->ConsStringGet(index); | 3700 return ConsString::cast(this)->ConsStringGet(index); |
3682 case kExternalStringTag | kOneByteStringTag: | 3701 case kExternalStringTag | kOneByteStringTag: |
3683 return ExternalOneByteString::cast(this)->ExternalOneByteStringGet(index); | 3702 return ExternalOneByteString::cast(this)->ExternalOneByteStringGet(index); |
3684 case kExternalStringTag | kTwoByteStringTag: | 3703 case kExternalStringTag | kTwoByteStringTag: |
3685 return ExternalTwoByteString::cast(this)->ExternalTwoByteStringGet(index); | 3704 return ExternalTwoByteString::cast(this)->ExternalTwoByteStringGet(index); |
3686 case kSlicedStringTag | kOneByteStringTag: | 3705 case kSlicedStringTag | kOneByteStringTag: |
3687 case kSlicedStringTag | kTwoByteStringTag: | 3706 case kSlicedStringTag | kTwoByteStringTag: |
3688 return SlicedString::cast(this)->SlicedStringGet(index); | 3707 return SlicedString::cast(this)->SlicedStringGet(index); |
| 3708 case kThinStringTag | kOneByteStringTag: |
| 3709 case kThinStringTag | kTwoByteStringTag: |
| 3710 return ThinString::cast(this)->ThinStringGet(index); |
3689 default: | 3711 default: |
3690 break; | 3712 break; |
3691 } | 3713 } |
3692 | 3714 |
3693 UNREACHABLE(); | 3715 UNREACHABLE(); |
3694 return 0; | 3716 return 0; |
3695 } | 3717 } |
3696 | 3718 |
3697 | 3719 |
3698 void String::Set(int index, uint16_t value) { | 3720 void String::Set(int index, uint16_t value) { |
(...skipping 11 matching lines...) Expand all Loading... |
3710 return ConsString::cast(this)->second()->length() == 0; | 3732 return ConsString::cast(this)->second()->length() == 0; |
3711 } | 3733 } |
3712 | 3734 |
3713 | 3735 |
3714 String* String::GetUnderlying() { | 3736 String* String::GetUnderlying() { |
3715 // Giving direct access to underlying string only makes sense if the | 3737 // Giving direct access to underlying string only makes sense if the |
3716 // wrapping string is already flattened. | 3738 // wrapping string is already flattened. |
3717 DCHECK(this->IsFlat()); | 3739 DCHECK(this->IsFlat()); |
3718 DCHECK(StringShape(this).IsIndirect()); | 3740 DCHECK(StringShape(this).IsIndirect()); |
3719 STATIC_ASSERT(ConsString::kFirstOffset == SlicedString::kParentOffset); | 3741 STATIC_ASSERT(ConsString::kFirstOffset == SlicedString::kParentOffset); |
| 3742 STATIC_ASSERT(ConsString::kFirstOffset == ThinString::kActualOffset); |
3720 const int kUnderlyingOffset = SlicedString::kParentOffset; | 3743 const int kUnderlyingOffset = SlicedString::kParentOffset; |
3721 return String::cast(READ_FIELD(this, kUnderlyingOffset)); | 3744 return String::cast(READ_FIELD(this, kUnderlyingOffset)); |
3722 } | 3745 } |
3723 | 3746 |
3724 | 3747 |
3725 template<class Visitor> | 3748 template<class Visitor> |
3726 ConsString* String::VisitFlat(Visitor* visitor, | 3749 ConsString* String::VisitFlat(Visitor* visitor, |
3727 String* string, | 3750 String* string, |
3728 const int offset) { | 3751 const int offset) { |
3729 int slice_offset = offset; | 3752 int slice_offset = offset; |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3761 SlicedString* slicedString = SlicedString::cast(string); | 3784 SlicedString* slicedString = SlicedString::cast(string); |
3762 slice_offset += slicedString->offset(); | 3785 slice_offset += slicedString->offset(); |
3763 string = slicedString->parent(); | 3786 string = slicedString->parent(); |
3764 continue; | 3787 continue; |
3765 } | 3788 } |
3766 | 3789 |
3767 case kConsStringTag | kOneByteStringTag: | 3790 case kConsStringTag | kOneByteStringTag: |
3768 case kConsStringTag | kTwoByteStringTag: | 3791 case kConsStringTag | kTwoByteStringTag: |
3769 return ConsString::cast(string); | 3792 return ConsString::cast(string); |
3770 | 3793 |
| 3794 case kThinStringTag | kOneByteStringTag: |
| 3795 case kThinStringTag | kTwoByteStringTag: |
| 3796 string = ThinString::cast(string)->actual(); |
| 3797 continue; |
| 3798 |
3771 default: | 3799 default: |
3772 UNREACHABLE(); | 3800 UNREACHABLE(); |
3773 return NULL; | 3801 return NULL; |
3774 } | 3802 } |
3775 } | 3803 } |
3776 } | 3804 } |
3777 | 3805 |
3778 | 3806 |
3779 template <> | 3807 template <> |
3780 inline Vector<const uint8_t> String::GetCharVector() { | 3808 inline Vector<const uint8_t> String::GetCharVector() { |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3892 Object* ConsString::unchecked_second() { | 3920 Object* ConsString::unchecked_second() { |
3893 return READ_FIELD(this, kSecondOffset); | 3921 return READ_FIELD(this, kSecondOffset); |
3894 } | 3922 } |
3895 | 3923 |
3896 | 3924 |
3897 void ConsString::set_second(String* value, WriteBarrierMode mode) { | 3925 void ConsString::set_second(String* value, WriteBarrierMode mode) { |
3898 WRITE_FIELD(this, kSecondOffset, value); | 3926 WRITE_FIELD(this, kSecondOffset, value); |
3899 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kSecondOffset, value, mode); | 3927 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kSecondOffset, value, mode); |
3900 } | 3928 } |
3901 | 3929 |
| 3930 ACCESSORS(ThinString, actual, String, kActualOffset); |
3902 | 3931 |
3903 bool ExternalString::is_short() { | 3932 bool ExternalString::is_short() { |
3904 InstanceType type = map()->instance_type(); | 3933 InstanceType type = map()->instance_type(); |
3905 return (type & kShortExternalStringMask) == kShortExternalStringTag; | 3934 return (type & kShortExternalStringMask) == kShortExternalStringTag; |
3906 } | 3935 } |
3907 | 3936 |
3908 | 3937 |
3909 const ExternalOneByteString::Resource* ExternalOneByteString::resource() { | 3938 const ExternalOneByteString::Resource* ExternalOneByteString::resource() { |
3910 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)); | 3939 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)); |
3911 } | 3940 } |
(...skipping 4489 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8401 #undef WRITE_INT64_FIELD | 8430 #undef WRITE_INT64_FIELD |
8402 #undef READ_BYTE_FIELD | 8431 #undef READ_BYTE_FIELD |
8403 #undef WRITE_BYTE_FIELD | 8432 #undef WRITE_BYTE_FIELD |
8404 #undef NOBARRIER_READ_BYTE_FIELD | 8433 #undef NOBARRIER_READ_BYTE_FIELD |
8405 #undef NOBARRIER_WRITE_BYTE_FIELD | 8434 #undef NOBARRIER_WRITE_BYTE_FIELD |
8406 | 8435 |
8407 } // namespace internal | 8436 } // namespace internal |
8408 } // namespace v8 | 8437 } // namespace v8 |
8409 | 8438 |
8410 #endif // V8_OBJECTS_INL_H_ | 8439 #endif // V8_OBJECTS_INL_H_ |
OLD | NEW |