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 | |
283 bool HeapObject::IsSlicedString() const { | 278 bool HeapObject::IsSlicedString() const { |
284 if (!IsString()) return false; | 279 if (!IsString()) return false; |
285 return StringShape(String::cast(this)).IsSliced(); | 280 return StringShape(String::cast(this)).IsSliced(); |
286 } | 281 } |
287 | 282 |
288 bool HeapObject::IsSeqString() const { | 283 bool HeapObject::IsSeqString() const { |
289 if (!IsString()) return false; | 284 if (!IsString()) return false; |
290 return StringShape(String::cast(this)).IsSequential(); | 285 return StringShape(String::cast(this)).IsSequential(); |
291 } | 286 } |
292 | 287 |
(...skipping 403 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
696 CAST_ACCESSOR(SharedFunctionInfo) | 691 CAST_ACCESSOR(SharedFunctionInfo) |
697 CAST_ACCESSOR(Simd128Value) | 692 CAST_ACCESSOR(Simd128Value) |
698 CAST_ACCESSOR(SlicedString) | 693 CAST_ACCESSOR(SlicedString) |
699 CAST_ACCESSOR(Smi) | 694 CAST_ACCESSOR(Smi) |
700 CAST_ACCESSOR(String) | 695 CAST_ACCESSOR(String) |
701 CAST_ACCESSOR(StringSet) | 696 CAST_ACCESSOR(StringSet) |
702 CAST_ACCESSOR(StringTable) | 697 CAST_ACCESSOR(StringTable) |
703 CAST_ACCESSOR(Struct) | 698 CAST_ACCESSOR(Struct) |
704 CAST_ACCESSOR(Symbol) | 699 CAST_ACCESSOR(Symbol) |
705 CAST_ACCESSOR(TemplateInfo) | 700 CAST_ACCESSOR(TemplateInfo) |
706 CAST_ACCESSOR(ThinString) | |
707 CAST_ACCESSOR(Uint16x8) | 701 CAST_ACCESSOR(Uint16x8) |
708 CAST_ACCESSOR(Uint32x4) | 702 CAST_ACCESSOR(Uint32x4) |
709 CAST_ACCESSOR(Uint8x16) | 703 CAST_ACCESSOR(Uint8x16) |
710 CAST_ACCESSOR(UnseededNumberDictionary) | 704 CAST_ACCESSOR(UnseededNumberDictionary) |
711 CAST_ACCESSOR(WeakCell) | 705 CAST_ACCESSOR(WeakCell) |
712 CAST_ACCESSOR(WeakFixedArray) | 706 CAST_ACCESSOR(WeakFixedArray) |
713 CAST_ACCESSOR(WeakHashTable) | 707 CAST_ACCESSOR(WeakHashTable) |
714 | 708 |
715 #define MAKE_STRUCT_CAST(NAME, Name, name) CAST_ACCESSOR(Name) | 709 #define MAKE_STRUCT_CAST(NAME, Name, name) CAST_ACCESSOR(Name) |
716 STRUCT_LIST(MAKE_STRUCT_CAST) | 710 STRUCT_LIST(MAKE_STRUCT_CAST) |
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
843 bool String::HasOnlyOneByteChars() { | 837 bool String::HasOnlyOneByteChars() { |
844 uint32_t type = map()->instance_type(); | 838 uint32_t type = map()->instance_type(); |
845 return (type & kOneByteDataHintMask) == kOneByteDataHintTag || | 839 return (type & kOneByteDataHintMask) == kOneByteDataHintTag || |
846 IsOneByteRepresentation(); | 840 IsOneByteRepresentation(); |
847 } | 841 } |
848 | 842 |
849 bool StringShape::IsCons() { | 843 bool StringShape::IsCons() { |
850 return (type_ & kStringRepresentationMask) == kConsStringTag; | 844 return (type_ & kStringRepresentationMask) == kConsStringTag; |
851 } | 845 } |
852 | 846 |
853 bool StringShape::IsThin() { | |
854 return (type_ & kStringRepresentationMask) == kThinStringTag; | |
855 } | |
856 | |
857 bool StringShape::IsSliced() { | 847 bool StringShape::IsSliced() { |
858 return (type_ & kStringRepresentationMask) == kSlicedStringTag; | 848 return (type_ & kStringRepresentationMask) == kSlicedStringTag; |
859 } | 849 } |
860 | 850 |
861 bool StringShape::IsIndirect() { | 851 bool StringShape::IsIndirect() { |
862 return (type_ & kIsIndirectStringMask) == kIsIndirectStringTag; | 852 return (type_ & kIsIndirectStringMask) == kIsIndirectStringTag; |
863 } | 853 } |
864 | 854 |
865 bool StringShape::IsExternal() { | 855 bool StringShape::IsExternal() { |
866 return (type_ & kStringRepresentationMask) == kExternalStringTag; | 856 return (type_ & kStringRepresentationMask) == kExternalStringTag; |
(...skipping 2840 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3707 bool String::Equals(Handle<String> one, Handle<String> two) { | 3697 bool String::Equals(Handle<String> one, Handle<String> two) { |
3708 if (one.is_identical_to(two)) return true; | 3698 if (one.is_identical_to(two)) return true; |
3709 if (one->IsInternalizedString() && two->IsInternalizedString()) { | 3699 if (one->IsInternalizedString() && two->IsInternalizedString()) { |
3710 return false; | 3700 return false; |
3711 } | 3701 } |
3712 return SlowEquals(one, two); | 3702 return SlowEquals(one, two); |
3713 } | 3703 } |
3714 | 3704 |
3715 | 3705 |
3716 Handle<String> String::Flatten(Handle<String> string, PretenureFlag pretenure) { | 3706 Handle<String> String::Flatten(Handle<String> string, PretenureFlag pretenure) { |
3717 if (string->IsConsString()) { | 3707 if (!string->IsConsString()) return string; |
3718 Handle<ConsString> cons = Handle<ConsString>::cast(string); | 3708 Handle<ConsString> cons = Handle<ConsString>::cast(string); |
3719 if (cons->IsFlat()) { | 3709 if (cons->IsFlat()) return handle(cons->first()); |
3720 string = handle(cons->first()); | 3710 return SlowFlatten(cons, pretenure); |
3721 } else { | |
3722 return SlowFlatten(cons, pretenure); | |
3723 } | |
3724 } | |
3725 if (string->IsThinString()) { | |
3726 string = handle(Handle<ThinString>::cast(string)->actual()); | |
3727 DCHECK(!string->IsConsString()); | |
3728 } | |
3729 return string; | |
3730 } | 3711 } |
3731 | 3712 |
3732 | 3713 |
3733 uint16_t String::Get(int index) { | 3714 uint16_t String::Get(int index) { |
3734 DCHECK(index >= 0 && index < length()); | 3715 DCHECK(index >= 0 && index < length()); |
3735 switch (StringShape(this).full_representation_tag()) { | 3716 switch (StringShape(this).full_representation_tag()) { |
3736 case kSeqStringTag | kOneByteStringTag: | 3717 case kSeqStringTag | kOneByteStringTag: |
3737 return SeqOneByteString::cast(this)->SeqOneByteStringGet(index); | 3718 return SeqOneByteString::cast(this)->SeqOneByteStringGet(index); |
3738 case kSeqStringTag | kTwoByteStringTag: | 3719 case kSeqStringTag | kTwoByteStringTag: |
3739 return SeqTwoByteString::cast(this)->SeqTwoByteStringGet(index); | 3720 return SeqTwoByteString::cast(this)->SeqTwoByteStringGet(index); |
3740 case kConsStringTag | kOneByteStringTag: | 3721 case kConsStringTag | kOneByteStringTag: |
3741 case kConsStringTag | kTwoByteStringTag: | 3722 case kConsStringTag | kTwoByteStringTag: |
3742 return ConsString::cast(this)->ConsStringGet(index); | 3723 return ConsString::cast(this)->ConsStringGet(index); |
3743 case kExternalStringTag | kOneByteStringTag: | 3724 case kExternalStringTag | kOneByteStringTag: |
3744 return ExternalOneByteString::cast(this)->ExternalOneByteStringGet(index); | 3725 return ExternalOneByteString::cast(this)->ExternalOneByteStringGet(index); |
3745 case kExternalStringTag | kTwoByteStringTag: | 3726 case kExternalStringTag | kTwoByteStringTag: |
3746 return ExternalTwoByteString::cast(this)->ExternalTwoByteStringGet(index); | 3727 return ExternalTwoByteString::cast(this)->ExternalTwoByteStringGet(index); |
3747 case kSlicedStringTag | kOneByteStringTag: | 3728 case kSlicedStringTag | kOneByteStringTag: |
3748 case kSlicedStringTag | kTwoByteStringTag: | 3729 case kSlicedStringTag | kTwoByteStringTag: |
3749 return SlicedString::cast(this)->SlicedStringGet(index); | 3730 return SlicedString::cast(this)->SlicedStringGet(index); |
3750 case kThinStringTag | kOneByteStringTag: | |
3751 case kThinStringTag | kTwoByteStringTag: | |
3752 return ThinString::cast(this)->ThinStringGet(index); | |
3753 default: | 3731 default: |
3754 break; | 3732 break; |
3755 } | 3733 } |
3756 | 3734 |
3757 UNREACHABLE(); | 3735 UNREACHABLE(); |
3758 return 0; | 3736 return 0; |
3759 } | 3737 } |
3760 | 3738 |
3761 | 3739 |
3762 void String::Set(int index, uint16_t value) { | 3740 void String::Set(int index, uint16_t value) { |
(...skipping 11 matching lines...) Expand all Loading... |
3774 return ConsString::cast(this)->second()->length() == 0; | 3752 return ConsString::cast(this)->second()->length() == 0; |
3775 } | 3753 } |
3776 | 3754 |
3777 | 3755 |
3778 String* String::GetUnderlying() { | 3756 String* String::GetUnderlying() { |
3779 // Giving direct access to underlying string only makes sense if the | 3757 // Giving direct access to underlying string only makes sense if the |
3780 // wrapping string is already flattened. | 3758 // wrapping string is already flattened. |
3781 DCHECK(this->IsFlat()); | 3759 DCHECK(this->IsFlat()); |
3782 DCHECK(StringShape(this).IsIndirect()); | 3760 DCHECK(StringShape(this).IsIndirect()); |
3783 STATIC_ASSERT(ConsString::kFirstOffset == SlicedString::kParentOffset); | 3761 STATIC_ASSERT(ConsString::kFirstOffset == SlicedString::kParentOffset); |
3784 STATIC_ASSERT(ConsString::kFirstOffset == ThinString::kActualOffset); | |
3785 const int kUnderlyingOffset = SlicedString::kParentOffset; | 3762 const int kUnderlyingOffset = SlicedString::kParentOffset; |
3786 return String::cast(READ_FIELD(this, kUnderlyingOffset)); | 3763 return String::cast(READ_FIELD(this, kUnderlyingOffset)); |
3787 } | 3764 } |
3788 | 3765 |
3789 | 3766 |
3790 template<class Visitor> | 3767 template<class Visitor> |
3791 ConsString* String::VisitFlat(Visitor* visitor, | 3768 ConsString* String::VisitFlat(Visitor* visitor, |
3792 String* string, | 3769 String* string, |
3793 const int offset) { | 3770 const int offset) { |
3794 int slice_offset = offset; | 3771 int slice_offset = offset; |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3826 SlicedString* slicedString = SlicedString::cast(string); | 3803 SlicedString* slicedString = SlicedString::cast(string); |
3827 slice_offset += slicedString->offset(); | 3804 slice_offset += slicedString->offset(); |
3828 string = slicedString->parent(); | 3805 string = slicedString->parent(); |
3829 continue; | 3806 continue; |
3830 } | 3807 } |
3831 | 3808 |
3832 case kConsStringTag | kOneByteStringTag: | 3809 case kConsStringTag | kOneByteStringTag: |
3833 case kConsStringTag | kTwoByteStringTag: | 3810 case kConsStringTag | kTwoByteStringTag: |
3834 return ConsString::cast(string); | 3811 return ConsString::cast(string); |
3835 | 3812 |
3836 case kThinStringTag | kOneByteStringTag: | |
3837 case kThinStringTag | kTwoByteStringTag: | |
3838 string = ThinString::cast(string)->actual(); | |
3839 continue; | |
3840 | |
3841 default: | 3813 default: |
3842 UNREACHABLE(); | 3814 UNREACHABLE(); |
3843 return NULL; | 3815 return NULL; |
3844 } | 3816 } |
3845 } | 3817 } |
3846 } | 3818 } |
3847 | 3819 |
3848 | 3820 |
3849 template <> | 3821 template <> |
3850 inline Vector<const uint8_t> String::GetCharVector() { | 3822 inline Vector<const uint8_t> String::GetCharVector() { |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3962 Object* ConsString::unchecked_second() { | 3934 Object* ConsString::unchecked_second() { |
3963 return READ_FIELD(this, kSecondOffset); | 3935 return READ_FIELD(this, kSecondOffset); |
3964 } | 3936 } |
3965 | 3937 |
3966 | 3938 |
3967 void ConsString::set_second(String* value, WriteBarrierMode mode) { | 3939 void ConsString::set_second(String* value, WriteBarrierMode mode) { |
3968 WRITE_FIELD(this, kSecondOffset, value); | 3940 WRITE_FIELD(this, kSecondOffset, value); |
3969 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kSecondOffset, value, mode); | 3941 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kSecondOffset, value, mode); |
3970 } | 3942 } |
3971 | 3943 |
3972 ACCESSORS(ThinString, actual, String, kActualOffset); | |
3973 | 3944 |
3974 bool ExternalString::is_short() { | 3945 bool ExternalString::is_short() { |
3975 InstanceType type = map()->instance_type(); | 3946 InstanceType type = map()->instance_type(); |
3976 return (type & kShortExternalStringMask) == kShortExternalStringTag; | 3947 return (type & kShortExternalStringMask) == kShortExternalStringTag; |
3977 } | 3948 } |
3978 | 3949 |
3979 | 3950 |
3980 const ExternalOneByteString::Resource* ExternalOneByteString::resource() { | 3951 const ExternalOneByteString::Resource* ExternalOneByteString::resource() { |
3981 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)); | 3952 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)); |
3982 } | 3953 } |
(...skipping 4485 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8468 #undef WRITE_INT64_FIELD | 8439 #undef WRITE_INT64_FIELD |
8469 #undef READ_BYTE_FIELD | 8440 #undef READ_BYTE_FIELD |
8470 #undef WRITE_BYTE_FIELD | 8441 #undef WRITE_BYTE_FIELD |
8471 #undef NOBARRIER_READ_BYTE_FIELD | 8442 #undef NOBARRIER_READ_BYTE_FIELD |
8472 #undef NOBARRIER_WRITE_BYTE_FIELD | 8443 #undef NOBARRIER_WRITE_BYTE_FIELD |
8473 | 8444 |
8474 } // namespace internal | 8445 } // namespace internal |
8475 } // namespace v8 | 8446 } // namespace v8 |
8476 | 8447 |
8477 #endif // V8_OBJECTS_INL_H_ | 8448 #endif // V8_OBJECTS_INL_H_ |
OLD | NEW |