Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(245)

Side by Side Diff: src/objects-inl.h

Issue 2549773002: Internalize strings in-place (Closed)
Patch Set: rebased Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/objects-debug.cc ('k') | src/objects-printer.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
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_
OLDNEW
« no previous file with comments | « src/objects-debug.cc ('k') | src/objects-printer.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698