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 2836 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3703 bool String::Equals(Handle<String> one, Handle<String> two) { | 3693 bool String::Equals(Handle<String> one, Handle<String> two) { |
3704 if (one.is_identical_to(two)) return true; | 3694 if (one.is_identical_to(two)) return true; |
3705 if (one->IsInternalizedString() && two->IsInternalizedString()) { | 3695 if (one->IsInternalizedString() && two->IsInternalizedString()) { |
3706 return false; | 3696 return false; |
3707 } | 3697 } |
3708 return SlowEquals(one, two); | 3698 return SlowEquals(one, two); |
3709 } | 3699 } |
3710 | 3700 |
3711 | 3701 |
3712 Handle<String> String::Flatten(Handle<String> string, PretenureFlag pretenure) { | 3702 Handle<String> String::Flatten(Handle<String> string, PretenureFlag pretenure) { |
3713 if (string->IsConsString()) { | 3703 if (!string->IsConsString()) return string; |
3714 Handle<ConsString> cons = Handle<ConsString>::cast(string); | 3704 Handle<ConsString> cons = Handle<ConsString>::cast(string); |
3715 if (cons->IsFlat()) { | 3705 if (cons->IsFlat()) return handle(cons->first()); |
3716 string = handle(cons->first()); | 3706 return SlowFlatten(cons, pretenure); |
3717 } else { | |
3718 return SlowFlatten(cons, pretenure); | |
3719 } | |
3720 } | |
3721 if (string->IsThinString()) { | |
3722 string = handle(Handle<ThinString>::cast(string)->actual()); | |
3723 DCHECK(!string->IsConsString()); | |
3724 } | |
3725 return string; | |
3726 } | 3707 } |
3727 | 3708 |
3728 | 3709 |
3729 uint16_t String::Get(int index) { | 3710 uint16_t String::Get(int index) { |
3730 DCHECK(index >= 0 && index < length()); | 3711 DCHECK(index >= 0 && index < length()); |
3731 switch (StringShape(this).full_representation_tag()) { | 3712 switch (StringShape(this).full_representation_tag()) { |
3732 case kSeqStringTag | kOneByteStringTag: | 3713 case kSeqStringTag | kOneByteStringTag: |
3733 return SeqOneByteString::cast(this)->SeqOneByteStringGet(index); | 3714 return SeqOneByteString::cast(this)->SeqOneByteStringGet(index); |
3734 case kSeqStringTag | kTwoByteStringTag: | 3715 case kSeqStringTag | kTwoByteStringTag: |
3735 return SeqTwoByteString::cast(this)->SeqTwoByteStringGet(index); | 3716 return SeqTwoByteString::cast(this)->SeqTwoByteStringGet(index); |
3736 case kConsStringTag | kOneByteStringTag: | 3717 case kConsStringTag | kOneByteStringTag: |
3737 case kConsStringTag | kTwoByteStringTag: | 3718 case kConsStringTag | kTwoByteStringTag: |
3738 return ConsString::cast(this)->ConsStringGet(index); | 3719 return ConsString::cast(this)->ConsStringGet(index); |
3739 case kExternalStringTag | kOneByteStringTag: | 3720 case kExternalStringTag | kOneByteStringTag: |
3740 return ExternalOneByteString::cast(this)->ExternalOneByteStringGet(index); | 3721 return ExternalOneByteString::cast(this)->ExternalOneByteStringGet(index); |
3741 case kExternalStringTag | kTwoByteStringTag: | 3722 case kExternalStringTag | kTwoByteStringTag: |
3742 return ExternalTwoByteString::cast(this)->ExternalTwoByteStringGet(index); | 3723 return ExternalTwoByteString::cast(this)->ExternalTwoByteStringGet(index); |
3743 case kSlicedStringTag | kOneByteStringTag: | 3724 case kSlicedStringTag | kOneByteStringTag: |
3744 case kSlicedStringTag | kTwoByteStringTag: | 3725 case kSlicedStringTag | kTwoByteStringTag: |
3745 return SlicedString::cast(this)->SlicedStringGet(index); | 3726 return SlicedString::cast(this)->SlicedStringGet(index); |
3746 case kThinStringTag | kOneByteStringTag: | |
3747 case kThinStringTag | kTwoByteStringTag: | |
3748 return ThinString::cast(this)->ThinStringGet(index); | |
3749 default: | 3727 default: |
3750 break; | 3728 break; |
3751 } | 3729 } |
3752 | 3730 |
3753 UNREACHABLE(); | 3731 UNREACHABLE(); |
3754 return 0; | 3732 return 0; |
3755 } | 3733 } |
3756 | 3734 |
3757 | 3735 |
3758 void String::Set(int index, uint16_t value) { | 3736 void String::Set(int index, uint16_t value) { |
(...skipping 11 matching lines...) Expand all Loading... |
3770 return ConsString::cast(this)->second()->length() == 0; | 3748 return ConsString::cast(this)->second()->length() == 0; |
3771 } | 3749 } |
3772 | 3750 |
3773 | 3751 |
3774 String* String::GetUnderlying() { | 3752 String* String::GetUnderlying() { |
3775 // Giving direct access to underlying string only makes sense if the | 3753 // Giving direct access to underlying string only makes sense if the |
3776 // wrapping string is already flattened. | 3754 // wrapping string is already flattened. |
3777 DCHECK(this->IsFlat()); | 3755 DCHECK(this->IsFlat()); |
3778 DCHECK(StringShape(this).IsIndirect()); | 3756 DCHECK(StringShape(this).IsIndirect()); |
3779 STATIC_ASSERT(ConsString::kFirstOffset == SlicedString::kParentOffset); | 3757 STATIC_ASSERT(ConsString::kFirstOffset == SlicedString::kParentOffset); |
3780 STATIC_ASSERT(ConsString::kFirstOffset == ThinString::kActualOffset); | |
3781 const int kUnderlyingOffset = SlicedString::kParentOffset; | 3758 const int kUnderlyingOffset = SlicedString::kParentOffset; |
3782 return String::cast(READ_FIELD(this, kUnderlyingOffset)); | 3759 return String::cast(READ_FIELD(this, kUnderlyingOffset)); |
3783 } | 3760 } |
3784 | 3761 |
3785 | 3762 |
3786 template<class Visitor> | 3763 template<class Visitor> |
3787 ConsString* String::VisitFlat(Visitor* visitor, | 3764 ConsString* String::VisitFlat(Visitor* visitor, |
3788 String* string, | 3765 String* string, |
3789 const int offset) { | 3766 const int offset) { |
3790 int slice_offset = offset; | 3767 int slice_offset = offset; |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3822 SlicedString* slicedString = SlicedString::cast(string); | 3799 SlicedString* slicedString = SlicedString::cast(string); |
3823 slice_offset += slicedString->offset(); | 3800 slice_offset += slicedString->offset(); |
3824 string = slicedString->parent(); | 3801 string = slicedString->parent(); |
3825 continue; | 3802 continue; |
3826 } | 3803 } |
3827 | 3804 |
3828 case kConsStringTag | kOneByteStringTag: | 3805 case kConsStringTag | kOneByteStringTag: |
3829 case kConsStringTag | kTwoByteStringTag: | 3806 case kConsStringTag | kTwoByteStringTag: |
3830 return ConsString::cast(string); | 3807 return ConsString::cast(string); |
3831 | 3808 |
3832 case kThinStringTag | kOneByteStringTag: | |
3833 case kThinStringTag | kTwoByteStringTag: | |
3834 string = ThinString::cast(string)->actual(); | |
3835 continue; | |
3836 | |
3837 default: | 3809 default: |
3838 UNREACHABLE(); | 3810 UNREACHABLE(); |
3839 return NULL; | 3811 return NULL; |
3840 } | 3812 } |
3841 } | 3813 } |
3842 } | 3814 } |
3843 | 3815 |
3844 | 3816 |
3845 template <> | 3817 template <> |
3846 inline Vector<const uint8_t> String::GetCharVector() { | 3818 inline Vector<const uint8_t> String::GetCharVector() { |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3958 Object* ConsString::unchecked_second() { | 3930 Object* ConsString::unchecked_second() { |
3959 return READ_FIELD(this, kSecondOffset); | 3931 return READ_FIELD(this, kSecondOffset); |
3960 } | 3932 } |
3961 | 3933 |
3962 | 3934 |
3963 void ConsString::set_second(String* value, WriteBarrierMode mode) { | 3935 void ConsString::set_second(String* value, WriteBarrierMode mode) { |
3964 WRITE_FIELD(this, kSecondOffset, value); | 3936 WRITE_FIELD(this, kSecondOffset, value); |
3965 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kSecondOffset, value, mode); | 3937 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kSecondOffset, value, mode); |
3966 } | 3938 } |
3967 | 3939 |
3968 ACCESSORS(ThinString, actual, String, kActualOffset); | |
3969 | 3940 |
3970 bool ExternalString::is_short() { | 3941 bool ExternalString::is_short() { |
3971 InstanceType type = map()->instance_type(); | 3942 InstanceType type = map()->instance_type(); |
3972 return (type & kShortExternalStringMask) == kShortExternalStringTag; | 3943 return (type & kShortExternalStringMask) == kShortExternalStringTag; |
3973 } | 3944 } |
3974 | 3945 |
3975 | 3946 |
3976 const ExternalOneByteString::Resource* ExternalOneByteString::resource() { | 3947 const ExternalOneByteString::Resource* ExternalOneByteString::resource() { |
3977 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)); | 3948 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)); |
3978 } | 3949 } |
(...skipping 4474 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8453 #undef WRITE_INT64_FIELD | 8424 #undef WRITE_INT64_FIELD |
8454 #undef READ_BYTE_FIELD | 8425 #undef READ_BYTE_FIELD |
8455 #undef WRITE_BYTE_FIELD | 8426 #undef WRITE_BYTE_FIELD |
8456 #undef NOBARRIER_READ_BYTE_FIELD | 8427 #undef NOBARRIER_READ_BYTE_FIELD |
8457 #undef NOBARRIER_WRITE_BYTE_FIELD | 8428 #undef NOBARRIER_WRITE_BYTE_FIELD |
8458 | 8429 |
8459 } // namespace internal | 8430 } // namespace internal |
8460 } // namespace v8 | 8431 } // namespace v8 |
8461 | 8432 |
8462 #endif // V8_OBJECTS_INL_H_ | 8433 #endif // V8_OBJECTS_INL_H_ |
OLD | NEW |