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 209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
220 STATIC_ASSERT(kNotInternalizedTag != 0); | 220 STATIC_ASSERT(kNotInternalizedTag != 0); |
221 return (type & (kIsNotStringMask | kIsNotInternalizedMask)) == | 221 return (type & (kIsNotStringMask | kIsNotInternalizedMask)) == |
222 (kStringTag | kInternalizedTag); | 222 (kStringTag | kInternalizedTag); |
223 } | 223 } |
224 | 224 |
225 bool HeapObject::IsConsString() const { | 225 bool HeapObject::IsConsString() const { |
226 if (!IsString()) return false; | 226 if (!IsString()) return false; |
227 return StringShape(String::cast(this)).IsCons(); | 227 return StringShape(String::cast(this)).IsCons(); |
228 } | 228 } |
229 | 229 |
| 230 bool HeapObject::IsThinString() const { |
| 231 if (!IsString()) return false; |
| 232 return StringShape(String::cast(this)).IsThin(); |
| 233 } |
| 234 |
230 bool HeapObject::IsSlicedString() const { | 235 bool HeapObject::IsSlicedString() const { |
231 if (!IsString()) return false; | 236 if (!IsString()) return false; |
232 return StringShape(String::cast(this)).IsSliced(); | 237 return StringShape(String::cast(this)).IsSliced(); |
233 } | 238 } |
234 | 239 |
235 bool HeapObject::IsSeqString() const { | 240 bool HeapObject::IsSeqString() const { |
236 if (!IsString()) return false; | 241 if (!IsString()) return false; |
237 return StringShape(String::cast(this)).IsSequential(); | 242 return StringShape(String::cast(this)).IsSequential(); |
238 } | 243 } |
239 | 244 |
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
414 | 419 |
415 bool StringShape::IsCons() { | 420 bool StringShape::IsCons() { |
416 return (type_ & kStringRepresentationMask) == kConsStringTag; | 421 return (type_ & kStringRepresentationMask) == kConsStringTag; |
417 } | 422 } |
418 | 423 |
419 | 424 |
420 bool StringShape::IsSliced() { | 425 bool StringShape::IsSliced() { |
421 return (type_ & kStringRepresentationMask) == kSlicedStringTag; | 426 return (type_ & kStringRepresentationMask) == kSlicedStringTag; |
422 } | 427 } |
423 | 428 |
| 429 bool StringShape::IsThin() { |
| 430 return (type_ & kStringRepresentationMask) == kThinStringTag; |
| 431 } |
424 | 432 |
425 bool StringShape::IsIndirect() { | 433 bool StringShape::IsIndirect() { |
426 return (type_ & kIsIndirectStringMask) == kIsIndirectStringTag; | 434 return (type_ & kIsIndirectStringMask) == kIsIndirectStringTag; |
427 } | 435 } |
428 | 436 |
429 | 437 |
430 bool StringShape::IsExternal() { | 438 bool StringShape::IsExternal() { |
431 return (type_ & kStringRepresentationMask) == kExternalStringTag; | 439 return (type_ & kStringRepresentationMask) == kExternalStringTag; |
432 } | 440 } |
433 | 441 |
(...skipping 2948 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3382 CAST_ACCESSOR(SharedFunctionInfo) | 3390 CAST_ACCESSOR(SharedFunctionInfo) |
3383 CAST_ACCESSOR(Simd128Value) | 3391 CAST_ACCESSOR(Simd128Value) |
3384 CAST_ACCESSOR(SlicedString) | 3392 CAST_ACCESSOR(SlicedString) |
3385 CAST_ACCESSOR(Smi) | 3393 CAST_ACCESSOR(Smi) |
3386 CAST_ACCESSOR(String) | 3394 CAST_ACCESSOR(String) |
3387 CAST_ACCESSOR(StringSet) | 3395 CAST_ACCESSOR(StringSet) |
3388 CAST_ACCESSOR(StringTable) | 3396 CAST_ACCESSOR(StringTable) |
3389 CAST_ACCESSOR(Struct) | 3397 CAST_ACCESSOR(Struct) |
3390 CAST_ACCESSOR(Symbol) | 3398 CAST_ACCESSOR(Symbol) |
3391 CAST_ACCESSOR(TemplateInfo) | 3399 CAST_ACCESSOR(TemplateInfo) |
| 3400 CAST_ACCESSOR(ThinString) |
3392 CAST_ACCESSOR(Uint16x8) | 3401 CAST_ACCESSOR(Uint16x8) |
3393 CAST_ACCESSOR(Uint32x4) | 3402 CAST_ACCESSOR(Uint32x4) |
3394 CAST_ACCESSOR(Uint8x16) | 3403 CAST_ACCESSOR(Uint8x16) |
3395 CAST_ACCESSOR(UnseededNumberDictionary) | 3404 CAST_ACCESSOR(UnseededNumberDictionary) |
3396 CAST_ACCESSOR(WeakCell) | 3405 CAST_ACCESSOR(WeakCell) |
3397 CAST_ACCESSOR(WeakFixedArray) | 3406 CAST_ACCESSOR(WeakFixedArray) |
3398 CAST_ACCESSOR(WeakHashTable) | 3407 CAST_ACCESSOR(WeakHashTable) |
3399 | 3408 |
3400 template <class T> | 3409 template <class T> |
3401 PodArray<T>* PodArray<T>::cast(Object* object) { | 3410 PodArray<T>* PodArray<T>::cast(Object* object) { |
(...skipping 340 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3742 bool String::Equals(Handle<String> one, Handle<String> two) { | 3751 bool String::Equals(Handle<String> one, Handle<String> two) { |
3743 if (one.is_identical_to(two)) return true; | 3752 if (one.is_identical_to(two)) return true; |
3744 if (one->IsInternalizedString() && two->IsInternalizedString()) { | 3753 if (one->IsInternalizedString() && two->IsInternalizedString()) { |
3745 return false; | 3754 return false; |
3746 } | 3755 } |
3747 return SlowEquals(one, two); | 3756 return SlowEquals(one, two); |
3748 } | 3757 } |
3749 | 3758 |
3750 | 3759 |
3751 Handle<String> String::Flatten(Handle<String> string, PretenureFlag pretenure) { | 3760 Handle<String> String::Flatten(Handle<String> string, PretenureFlag pretenure) { |
| 3761 if (string->IsThinString()) { |
| 3762 return handle(Handle<ThinString>::cast(string)->actual()); |
| 3763 } |
3752 if (!string->IsConsString()) return string; | 3764 if (!string->IsConsString()) return string; |
3753 Handle<ConsString> cons = Handle<ConsString>::cast(string); | 3765 Handle<ConsString> cons = Handle<ConsString>::cast(string); |
3754 if (cons->IsFlat()) return handle(cons->first()); | 3766 if (cons->IsFlat()) return handle(cons->first()); |
3755 return SlowFlatten(cons, pretenure); | 3767 return SlowFlatten(cons, pretenure); |
3756 } | 3768 } |
3757 | 3769 |
3758 | 3770 |
3759 uint16_t String::Get(int index) { | 3771 uint16_t String::Get(int index) { |
3760 DCHECK(index >= 0 && index < length()); | 3772 DCHECK(index >= 0 && index < length()); |
3761 switch (StringShape(this).full_representation_tag()) { | 3773 switch (StringShape(this).full_representation_tag()) { |
3762 case kSeqStringTag | kOneByteStringTag: | 3774 case kSeqStringTag | kOneByteStringTag: |
3763 return SeqOneByteString::cast(this)->SeqOneByteStringGet(index); | 3775 return SeqOneByteString::cast(this)->SeqOneByteStringGet(index); |
3764 case kSeqStringTag | kTwoByteStringTag: | 3776 case kSeqStringTag | kTwoByteStringTag: |
3765 return SeqTwoByteString::cast(this)->SeqTwoByteStringGet(index); | 3777 return SeqTwoByteString::cast(this)->SeqTwoByteStringGet(index); |
3766 case kConsStringTag | kOneByteStringTag: | 3778 case kConsStringTag | kOneByteStringTag: |
3767 case kConsStringTag | kTwoByteStringTag: | 3779 case kConsStringTag | kTwoByteStringTag: |
3768 return ConsString::cast(this)->ConsStringGet(index); | 3780 return ConsString::cast(this)->ConsStringGet(index); |
3769 case kExternalStringTag | kOneByteStringTag: | 3781 case kExternalStringTag | kOneByteStringTag: |
3770 return ExternalOneByteString::cast(this)->ExternalOneByteStringGet(index); | 3782 return ExternalOneByteString::cast(this)->ExternalOneByteStringGet(index); |
3771 case kExternalStringTag | kTwoByteStringTag: | 3783 case kExternalStringTag | kTwoByteStringTag: |
3772 return ExternalTwoByteString::cast(this)->ExternalTwoByteStringGet(index); | 3784 return ExternalTwoByteString::cast(this)->ExternalTwoByteStringGet(index); |
3773 case kSlicedStringTag | kOneByteStringTag: | 3785 case kSlicedStringTag | kOneByteStringTag: |
3774 case kSlicedStringTag | kTwoByteStringTag: | 3786 case kSlicedStringTag | kTwoByteStringTag: |
3775 return SlicedString::cast(this)->SlicedStringGet(index); | 3787 return SlicedString::cast(this)->SlicedStringGet(index); |
| 3788 case kThinStringTag | kOneByteStringTag: |
| 3789 case kThinStringTag | kTwoByteStringTag: |
| 3790 return ThinString::cast(this)->ThinStringGet(index); |
3776 default: | 3791 default: |
3777 break; | 3792 break; |
3778 } | 3793 } |
3779 | 3794 |
3780 UNREACHABLE(); | 3795 UNREACHABLE(); |
3781 return 0; | 3796 return 0; |
3782 } | 3797 } |
3783 | 3798 |
3784 | 3799 |
3785 void String::Set(int index, uint16_t value) { | 3800 void String::Set(int index, uint16_t value) { |
(...skipping 11 matching lines...) Expand all Loading... |
3797 return ConsString::cast(this)->second()->length() == 0; | 3812 return ConsString::cast(this)->second()->length() == 0; |
3798 } | 3813 } |
3799 | 3814 |
3800 | 3815 |
3801 String* String::GetUnderlying() { | 3816 String* String::GetUnderlying() { |
3802 // Giving direct access to underlying string only makes sense if the | 3817 // Giving direct access to underlying string only makes sense if the |
3803 // wrapping string is already flattened. | 3818 // wrapping string is already flattened. |
3804 DCHECK(this->IsFlat()); | 3819 DCHECK(this->IsFlat()); |
3805 DCHECK(StringShape(this).IsIndirect()); | 3820 DCHECK(StringShape(this).IsIndirect()); |
3806 STATIC_ASSERT(ConsString::kFirstOffset == SlicedString::kParentOffset); | 3821 STATIC_ASSERT(ConsString::kFirstOffset == SlicedString::kParentOffset); |
| 3822 STATIC_ASSERT(ConsString::kFirstOffset == ThinString::kActualOffset); |
3807 const int kUnderlyingOffset = SlicedString::kParentOffset; | 3823 const int kUnderlyingOffset = SlicedString::kParentOffset; |
3808 return String::cast(READ_FIELD(this, kUnderlyingOffset)); | 3824 return String::cast(READ_FIELD(this, kUnderlyingOffset)); |
3809 } | 3825 } |
3810 | 3826 |
3811 | 3827 |
3812 template<class Visitor> | 3828 template<class Visitor> |
3813 ConsString* String::VisitFlat(Visitor* visitor, | 3829 ConsString* String::VisitFlat(Visitor* visitor, |
3814 String* string, | 3830 String* string, |
3815 const int offset) { | 3831 const int offset) { |
3816 int slice_offset = offset; | 3832 int slice_offset = offset; |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3848 SlicedString* slicedString = SlicedString::cast(string); | 3864 SlicedString* slicedString = SlicedString::cast(string); |
3849 slice_offset += slicedString->offset(); | 3865 slice_offset += slicedString->offset(); |
3850 string = slicedString->parent(); | 3866 string = slicedString->parent(); |
3851 continue; | 3867 continue; |
3852 } | 3868 } |
3853 | 3869 |
3854 case kConsStringTag | kOneByteStringTag: | 3870 case kConsStringTag | kOneByteStringTag: |
3855 case kConsStringTag | kTwoByteStringTag: | 3871 case kConsStringTag | kTwoByteStringTag: |
3856 return ConsString::cast(string); | 3872 return ConsString::cast(string); |
3857 | 3873 |
| 3874 case kThinStringTag | kOneByteStringTag: |
| 3875 case kThinStringTag | kTwoByteStringTag: |
| 3876 string = ThinString::cast(string)->actual(); |
| 3877 continue; |
| 3878 |
3858 default: | 3879 default: |
3859 UNREACHABLE(); | 3880 UNREACHABLE(); |
3860 return NULL; | 3881 return NULL; |
3861 } | 3882 } |
3862 } | 3883 } |
3863 } | 3884 } |
3864 | 3885 |
3865 | 3886 |
3866 template <> | 3887 template <> |
3867 inline Vector<const uint8_t> String::GetCharVector() { | 3888 inline Vector<const uint8_t> String::GetCharVector() { |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3973 Object* ConsString::unchecked_second() { | 3994 Object* ConsString::unchecked_second() { |
3974 return READ_FIELD(this, kSecondOffset); | 3995 return READ_FIELD(this, kSecondOffset); |
3975 } | 3996 } |
3976 | 3997 |
3977 | 3998 |
3978 void ConsString::set_second(String* value, WriteBarrierMode mode) { | 3999 void ConsString::set_second(String* value, WriteBarrierMode mode) { |
3979 WRITE_FIELD(this, kSecondOffset, value); | 4000 WRITE_FIELD(this, kSecondOffset, value); |
3980 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kSecondOffset, value, mode); | 4001 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kSecondOffset, value, mode); |
3981 } | 4002 } |
3982 | 4003 |
| 4004 ACCESSORS(ThinString, actual, String, kActualOffset); |
3983 | 4005 |
3984 bool ExternalString::is_short() { | 4006 bool ExternalString::is_short() { |
3985 InstanceType type = map()->instance_type(); | 4007 InstanceType type = map()->instance_type(); |
3986 return (type & kShortExternalStringMask) == kShortExternalStringTag; | 4008 return (type & kShortExternalStringMask) == kShortExternalStringTag; |
3987 } | 4009 } |
3988 | 4010 |
3989 | 4011 |
3990 const ExternalOneByteString::Resource* ExternalOneByteString::resource() { | 4012 const ExternalOneByteString::Resource* ExternalOneByteString::resource() { |
3991 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)); | 4013 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)); |
3992 } | 4014 } |
(...skipping 4514 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8507 #undef WRITE_INT64_FIELD | 8529 #undef WRITE_INT64_FIELD |
8508 #undef READ_BYTE_FIELD | 8530 #undef READ_BYTE_FIELD |
8509 #undef WRITE_BYTE_FIELD | 8531 #undef WRITE_BYTE_FIELD |
8510 #undef NOBARRIER_READ_BYTE_FIELD | 8532 #undef NOBARRIER_READ_BYTE_FIELD |
8511 #undef NOBARRIER_WRITE_BYTE_FIELD | 8533 #undef NOBARRIER_WRITE_BYTE_FIELD |
8512 | 8534 |
8513 } // namespace internal | 8535 } // namespace internal |
8514 } // namespace v8 | 8536 } // namespace v8 |
8515 | 8537 |
8516 #endif // V8_OBJECTS_INL_H_ | 8538 #endif // V8_OBJECTS_INL_H_ |
OLD | NEW |