OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 5020 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5031 Access<StringInputBuffer> buffer( | 5031 Access<StringInputBuffer> buffer( |
5032 heap->isolate()->objects_string_input_buffer()); | 5032 heap->isolate()->objects_string_input_buffer()); |
5033 buffer->Reset(0, this); | 5033 buffer->Reset(0, this); |
5034 int result = 0; | 5034 int result = 0; |
5035 while (buffer->has_more()) | 5035 while (buffer->has_more()) |
5036 result += unibrow::Utf8::Length(buffer->GetNext()); | 5036 result += unibrow::Utf8::Length(buffer->GetNext()); |
5037 return result; | 5037 return result; |
5038 } | 5038 } |
5039 | 5039 |
5040 | 5040 |
5041 Vector<const char> String::ToAsciiVector() { | 5041 String::FlatContent String::GetFlatContent(const AssertNoAllocation& promise) { |
5042 ASSERT(IsAsciiRepresentation()); | 5042 // Argument isn't used, it's only there to ensure that the user is |
5043 ASSERT(IsFlat()); | 5043 // aware that the extracted vectors may not survive a GC. |
5044 | |
5045 int offset = 0; | |
5046 int length = this->length(); | 5044 int length = this->length(); |
5047 StringRepresentationTag string_tag = StringShape(this).representation_tag(); | 5045 StringShape shape(this); |
5048 String* string = this; | 5046 String* string = this; |
5049 if (string_tag == kConsStringTag) { | 5047 if (shape.representation_tag() == kConsStringTag) { |
5050 ConsString* cons = ConsString::cast(string); | 5048 ConsString* cons = ConsString::cast(string); |
5051 ASSERT(cons->second()->length() == 0); | 5049 if (cons->second()->length() != 0) { |
| 5050 return FlatContent(); |
| 5051 } |
5052 string = cons->first(); | 5052 string = cons->first(); |
5053 string_tag = StringShape(string).representation_tag(); | 5053 shape = StringShape(string); |
5054 } | 5054 } |
5055 if (string_tag == kSeqStringTag) { | 5055 if (shape.encoding_tag() == kAsciiStringTag) { |
5056 SeqAsciiString* seq = SeqAsciiString::cast(string); | 5056 const char* start; |
5057 char* start = seq->GetChars(); | 5057 if (shape.representation_tag() == kSeqStringTag) { |
5058 return Vector<const char>(start + offset, length); | 5058 start = SeqAsciiString::cast(string)->GetChars(); |
| 5059 } else { |
| 5060 start = ExternalAsciiString::cast(string)->resource()->data(); |
| 5061 } |
| 5062 return FlatContent(Vector<const char>(start, length)); |
| 5063 } else { |
| 5064 ASSERT(shape.encoding_tag() == kTwoByteStringTag); |
| 5065 const uc16* start; |
| 5066 if (shape.representation_tag() == kSeqStringTag) { |
| 5067 start = SeqTwoByteString::cast(string)->GetChars(); |
| 5068 } else { |
| 5069 start = ExternalTwoByteString::cast(string)->resource()->data(); |
| 5070 } |
| 5071 return FlatContent(Vector<const uc16>(start, length)); |
5059 } | 5072 } |
5060 ASSERT(string_tag == kExternalStringTag); | |
5061 ExternalAsciiString* ext = ExternalAsciiString::cast(string); | |
5062 const char* start = ext->resource()->data(); | |
5063 return Vector<const char>(start + offset, length); | |
5064 } | 5073 } |
5065 | 5074 |
5066 | 5075 |
5067 Vector<const uc16> String::ToUC16Vector() { | |
5068 ASSERT(IsTwoByteRepresentation()); | |
5069 ASSERT(IsFlat()); | |
5070 | |
5071 int offset = 0; | |
5072 int length = this->length(); | |
5073 StringRepresentationTag string_tag = StringShape(this).representation_tag(); | |
5074 String* string = this; | |
5075 if (string_tag == kConsStringTag) { | |
5076 ConsString* cons = ConsString::cast(string); | |
5077 ASSERT(cons->second()->length() == 0); | |
5078 string = cons->first(); | |
5079 string_tag = StringShape(string).representation_tag(); | |
5080 } | |
5081 if (string_tag == kSeqStringTag) { | |
5082 SeqTwoByteString* seq = SeqTwoByteString::cast(string); | |
5083 return Vector<const uc16>(seq->GetChars() + offset, length); | |
5084 } | |
5085 ASSERT(string_tag == kExternalStringTag); | |
5086 ExternalTwoByteString* ext = ExternalTwoByteString::cast(string); | |
5087 const uc16* start = | |
5088 reinterpret_cast<const uc16*>(ext->resource()->data()); | |
5089 return Vector<const uc16>(start + offset, length); | |
5090 } | |
5091 | |
5092 | |
5093 SmartPointer<char> String::ToCString(AllowNullsFlag allow_nulls, | 5076 SmartPointer<char> String::ToCString(AllowNullsFlag allow_nulls, |
5094 RobustnessFlag robust_flag, | 5077 RobustnessFlag robust_flag, |
5095 int offset, | 5078 int offset, |
5096 int length, | 5079 int length, |
5097 int* length_return) { | 5080 int* length_return) { |
5098 if (robust_flag == ROBUST_STRING_TRAVERSAL && !LooksValid()) { | 5081 if (robust_flag == ROBUST_STRING_TRAVERSAL && !LooksValid()) { |
5099 return SmartPointer<char>(NULL); | 5082 return SmartPointer<char>(NULL); |
5100 } | 5083 } |
5101 Heap* heap = GetHeap(); | 5084 Heap* heap = GetHeap(); |
5102 | 5085 |
(...skipping 426 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5529 str_(0), | 5512 str_(0), |
5530 is_ascii_(true), | 5513 is_ascii_(true), |
5531 length_(input.length()), | 5514 length_(input.length()), |
5532 start_(input.start()) { } | 5515 start_(input.start()) { } |
5533 | 5516 |
5534 | 5517 |
5535 void FlatStringReader::PostGarbageCollection() { | 5518 void FlatStringReader::PostGarbageCollection() { |
5536 if (str_ == NULL) return; | 5519 if (str_ == NULL) return; |
5537 Handle<String> str(str_); | 5520 Handle<String> str(str_); |
5538 ASSERT(str->IsFlat()); | 5521 ASSERT(str->IsFlat()); |
5539 is_ascii_ = str->IsAsciiRepresentation(); | 5522 AssertNoAllocation no_alloc; |
| 5523 String::FlatContent content = str->GetFlatContent(no_alloc); |
| 5524 ASSERT(content.is_flat()); |
| 5525 is_ascii_ = content.IsAscii(); |
5540 if (is_ascii_) { | 5526 if (is_ascii_) { |
5541 start_ = str->ToAsciiVector().start(); | 5527 start_ = content.ToAsciiVector().start(); |
5542 } else { | 5528 } else { |
5543 start_ = str->ToUC16Vector().start(); | 5529 start_ = content.ToUC16Vector().start(); |
5544 } | 5530 } |
5545 } | 5531 } |
5546 | 5532 |
5547 | 5533 |
5548 void StringInputBuffer::Seek(unsigned pos) { | 5534 void StringInputBuffer::Seek(unsigned pos) { |
5549 Reset(pos, input_); | 5535 Reset(pos, input_); |
5550 } | 5536 } |
5551 | 5537 |
5552 | 5538 |
5553 void SafeStringInputBuffer::Seek(unsigned pos) { | 5539 void SafeStringInputBuffer::Seek(unsigned pos) { |
(...skipping 299 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5853 } | 5839 } |
5854 } | 5840 } |
5855 return true; | 5841 return true; |
5856 } | 5842 } |
5857 | 5843 |
5858 | 5844 |
5859 template <typename IteratorA> | 5845 template <typename IteratorA> |
5860 static inline bool CompareStringContentsPartial(Isolate* isolate, | 5846 static inline bool CompareStringContentsPartial(Isolate* isolate, |
5861 IteratorA* ia, | 5847 IteratorA* ia, |
5862 String* b) { | 5848 String* b) { |
5863 if (b->IsFlat()) { | 5849 AssertNoAllocation no_alloc; |
5864 if (b->IsAsciiRepresentation()) { | 5850 String::FlatContent content = b->GetFlatContent(no_alloc); |
5865 VectorIterator<char> ib(b->ToAsciiVector()); | 5851 if (content.IsFlat()) { |
| 5852 if (content.IsAscii()) { |
| 5853 VectorIterator<char> ib(content.ToAsciiVector()); |
5866 return CompareStringContents(ia, &ib); | 5854 return CompareStringContents(ia, &ib); |
5867 } else { | 5855 } else { |
5868 VectorIterator<uc16> ib(b->ToUC16Vector()); | 5856 VectorIterator<uc16> ib(content.ToUC16Vector()); |
5869 return CompareStringContents(ia, &ib); | 5857 return CompareStringContents(ia, &ib); |
5870 } | 5858 } |
5871 } else { | 5859 } else { |
5872 isolate->objects_string_compare_buffer_b()->Reset(0, b); | 5860 isolate->objects_string_compare_buffer_b()->Reset(0, b); |
5873 return CompareStringContents(ia, | 5861 return CompareStringContents(ia, |
5874 isolate->objects_string_compare_buffer_b()); | 5862 isolate->objects_string_compare_buffer_b()); |
5875 } | 5863 } |
5876 } | 5864 } |
5877 | 5865 |
5878 | 5866 |
5879 bool String::SlowEquals(String* other) { | 5867 bool String::SlowEquals(String* other) { |
5880 // Fast check: negative check with lengths. | 5868 // Fast check: negative check with lengths. |
5881 int len = length(); | 5869 int len = length(); |
5882 if (len != other->length()) return false; | 5870 if (len != other->length()) return false; |
5883 if (len == 0) return true; | 5871 if (len == 0) return true; |
5884 | 5872 |
5885 // Fast check: if hash code is computed for both strings | 5873 // Fast check: if hash code is computed for both strings |
5886 // a fast negative check can be performed. | 5874 // a fast negative check can be performed. |
5887 if (HasHashCode() && other->HasHashCode()) { | 5875 if (HasHashCode() && other->HasHashCode()) { |
5888 if (Hash() != other->Hash()) return false; | 5876 if (Hash() != other->Hash()) return false; |
5889 } | 5877 } |
5890 | 5878 |
5891 // We know the strings are both non-empty. Compare the first chars | 5879 // We know the strings are both non-empty. Compare the first chars |
5892 // before we try to flatten the strings. | 5880 // before we try to flatten the strings. |
5893 if (this->Get(0) != other->Get(0)) return false; | 5881 if (this->Get(0) != other->Get(0)) return false; |
5894 | 5882 |
5895 String* lhs = this->TryFlattenGetString(); | 5883 String* lhs = this->TryFlattenGetString(); |
5896 String* rhs = other->TryFlattenGetString(); | 5884 String* rhs = other->TryFlattenGetString(); |
5897 | 5885 |
| 5886 AssertNoAllocation no_alloc; |
| 5887 |
5898 if (StringShape(lhs).IsSequentialAscii() && | 5888 if (StringShape(lhs).IsSequentialAscii() && |
5899 StringShape(rhs).IsSequentialAscii()) { | 5889 StringShape(rhs).IsSequentialAscii()) { |
5900 const char* str1 = SeqAsciiString::cast(lhs)->GetChars(); | 5890 const char* str1 = SeqAsciiString::cast(lhs)->GetChars(); |
5901 const char* str2 = SeqAsciiString::cast(rhs)->GetChars(); | 5891 const char* str2 = SeqAsciiString::cast(rhs)->GetChars(); |
5902 return CompareRawStringContents(Vector<const char>(str1, len), | 5892 return CompareRawStringContents(Vector<const char>(str1, len), |
5903 Vector<const char>(str2, len)); | 5893 Vector<const char>(str2, len)); |
5904 } | 5894 } |
5905 | 5895 |
5906 Isolate* isolate = GetIsolate(); | 5896 Isolate* isolate = GetIsolate(); |
5907 if (lhs->IsFlat()) { | 5897 String::FlatContent lhs_content = lhs->GetFlatContent(no_alloc); |
5908 if (lhs->IsAsciiRepresentation()) { | 5898 String::FlatContent rhs_content = rhs->GetFlatContent(no_alloc); |
5909 Vector<const char> vec1 = lhs->ToAsciiVector(); | 5899 if (lhs_content.IsFlat()) { |
5910 if (rhs->IsFlat()) { | 5900 if (lhs_content.IsAscii()) { |
5911 if (rhs->IsAsciiRepresentation()) { | 5901 Vector<const char> vec1 = lhs_content.ToAsciiVector(); |
5912 Vector<const char> vec2 = rhs->ToAsciiVector(); | 5902 if (rhs_content.IsFlat()) { |
| 5903 if (rhs_content.IsAscii()) { |
| 5904 Vector<const char> vec2 = rhs_content.ToAsciiVector(); |
5913 return CompareRawStringContents(vec1, vec2); | 5905 return CompareRawStringContents(vec1, vec2); |
5914 } else { | 5906 } else { |
5915 VectorIterator<char> buf1(vec1); | 5907 VectorIterator<char> buf1(vec1); |
5916 VectorIterator<uc16> ib(rhs->ToUC16Vector()); | 5908 VectorIterator<uc16> ib(rhs_content.ToUC16Vector()); |
5917 return CompareStringContents(&buf1, &ib); | 5909 return CompareStringContents(&buf1, &ib); |
5918 } | 5910 } |
5919 } else { | 5911 } else { |
5920 VectorIterator<char> buf1(vec1); | 5912 VectorIterator<char> buf1(vec1); |
5921 isolate->objects_string_compare_buffer_b()->Reset(0, rhs); | 5913 isolate->objects_string_compare_buffer_b()->Reset(0, rhs); |
5922 return CompareStringContents(&buf1, | 5914 return CompareStringContents(&buf1, |
5923 isolate->objects_string_compare_buffer_b()); | 5915 isolate->objects_string_compare_buffer_b()); |
5924 } | 5916 } |
5925 } else { | 5917 } else { |
5926 Vector<const uc16> vec1 = lhs->ToUC16Vector(); | 5918 Vector<const uc16> vec1 = lhs_content.ToUC16Vector(); |
5927 if (rhs->IsFlat()) { | 5919 if (rhs_content.IsFlat()) { |
5928 if (rhs->IsAsciiRepresentation()) { | 5920 if (rhs_content.IsAscii()) { |
5929 VectorIterator<uc16> buf1(vec1); | 5921 VectorIterator<uc16> buf1(vec1); |
5930 VectorIterator<char> ib(rhs->ToAsciiVector()); | 5922 VectorIterator<char> ib(rhs_content.ToAsciiVector()); |
5931 return CompareStringContents(&buf1, &ib); | 5923 return CompareStringContents(&buf1, &ib); |
5932 } else { | 5924 } else { |
5933 Vector<const uc16> vec2(rhs->ToUC16Vector()); | 5925 Vector<const uc16> vec2(rhs_content.ToUC16Vector()); |
5934 return CompareRawStringContents(vec1, vec2); | 5926 return CompareRawStringContents(vec1, vec2); |
5935 } | 5927 } |
5936 } else { | 5928 } else { |
5937 VectorIterator<uc16> buf1(vec1); | 5929 VectorIterator<uc16> buf1(vec1); |
5938 isolate->objects_string_compare_buffer_b()->Reset(0, rhs); | 5930 isolate->objects_string_compare_buffer_b()->Reset(0, rhs); |
5939 return CompareStringContents(&buf1, | 5931 return CompareStringContents(&buf1, |
5940 isolate->objects_string_compare_buffer_b()); | 5932 isolate->objects_string_compare_buffer_b()); |
5941 } | 5933 } |
5942 } | 5934 } |
5943 } else { | 5935 } else { |
(...skipping 30 matching lines...) Expand all Loading... |
5974 int i; | 5966 int i; |
5975 for (i = 0; i < slen && decoder->has_more(); i++) { | 5967 for (i = 0; i < slen && decoder->has_more(); i++) { |
5976 uc32 r = decoder->GetNext(); | 5968 uc32 r = decoder->GetNext(); |
5977 if (Get(i) != r) return false; | 5969 if (Get(i) != r) return false; |
5978 } | 5970 } |
5979 return i == slen && !decoder->has_more(); | 5971 return i == slen && !decoder->has_more(); |
5980 } | 5972 } |
5981 | 5973 |
5982 | 5974 |
5983 bool String::IsAsciiEqualTo(Vector<const char> str) { | 5975 bool String::IsAsciiEqualTo(Vector<const char> str) { |
| 5976 AssertNoAllocation no_alloc; |
5984 int slen = length(); | 5977 int slen = length(); |
5985 if (str.length() != slen) return false; | 5978 if (str.length() != slen) return false; |
5986 if (IsFlat() && IsAsciiRepresentation()) { | 5979 FlatContent content = GetFlatContent(no_alloc); |
5987 return CompareChars(ToAsciiVector().start(), str.start(), slen) == 0; | 5980 if (content.IsAscii()) { |
| 5981 return CompareChars(content.ToAsciiVector().start(), |
| 5982 str.start(), slen) == 0; |
5988 } | 5983 } |
5989 for (int i = 0; i < slen; i++) { | 5984 for (int i = 0; i < slen; i++) { |
5990 if (Get(i) != static_cast<uint16_t>(str[i])) return false; | 5985 if (Get(i) != static_cast<uint16_t>(str[i])) return false; |
5991 } | 5986 } |
5992 return true; | 5987 return true; |
5993 } | 5988 } |
5994 | 5989 |
5995 | 5990 |
5996 bool String::IsTwoByteEqualTo(Vector<const uc16> str) { | 5991 bool String::IsTwoByteEqualTo(Vector<const uc16> str) { |
| 5992 AssertNoAllocation no_alloc; |
5997 int slen = length(); | 5993 int slen = length(); |
5998 if (str.length() != slen) return false; | 5994 if (str.length() != slen) return false; |
5999 if (IsFlat() && IsTwoByteRepresentation()) { | 5995 FlatContent content = GetFlatContent(no_alloc); |
6000 return CompareChars(ToUC16Vector().start(), str.start(), slen) == 0; | 5996 if (content.IsTwoByte()) { |
| 5997 return CompareChars(content.ToUC16Vector().start(), str.start(), slen) == 0; |
6001 } | 5998 } |
6002 for (int i = 0; i < slen; i++) { | 5999 for (int i = 0; i < slen; i++) { |
6003 if (Get(i) != str[i]) return false; | 6000 if (Get(i) != str[i]) return false; |
6004 } | 6001 } |
6005 return true; | 6002 return true; |
6006 } | 6003 } |
6007 | 6004 |
6008 | 6005 |
6009 uint32_t String::ComputeAndSetHash() { | 6006 uint32_t String::ComputeAndSetHash() { |
6010 // Should only be called if hash code has not yet been computed. | 6007 // Should only be called if hash code has not yet been computed. |
(...skipping 5542 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11553 if (break_point_objects()->IsUndefined()) return 0; | 11550 if (break_point_objects()->IsUndefined()) return 0; |
11554 // Single break point. | 11551 // Single break point. |
11555 if (!break_point_objects()->IsFixedArray()) return 1; | 11552 if (!break_point_objects()->IsFixedArray()) return 1; |
11556 // Multiple break points. | 11553 // Multiple break points. |
11557 return FixedArray::cast(break_point_objects())->length(); | 11554 return FixedArray::cast(break_point_objects())->length(); |
11558 } | 11555 } |
11559 #endif | 11556 #endif |
11560 | 11557 |
11561 | 11558 |
11562 } } // namespace v8::internal | 11559 } } // namespace v8::internal |
OLD | NEW |