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 1151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1162 ObjectVisitor* v) { | 1162 ObjectVisitor* v) { |
1163 // Avoiding <Type>::cast(this) because it accesses the map pointer field. | 1163 // Avoiding <Type>::cast(this) because it accesses the map pointer field. |
1164 // During GC, the map pointer field is encoded. | 1164 // During GC, the map pointer field is encoded. |
1165 if (type < FIRST_NONSTRING_TYPE) { | 1165 if (type < FIRST_NONSTRING_TYPE) { |
1166 switch (type & kStringRepresentationMask) { | 1166 switch (type & kStringRepresentationMask) { |
1167 case kSeqStringTag: | 1167 case kSeqStringTag: |
1168 break; | 1168 break; |
1169 case kConsStringTag: | 1169 case kConsStringTag: |
1170 ConsString::BodyDescriptor::IterateBody(this, v); | 1170 ConsString::BodyDescriptor::IterateBody(this, v); |
1171 break; | 1171 break; |
| 1172 case kSlicedStringTag: |
| 1173 SlicedString::BodyDescriptor::IterateBody(this, v); |
| 1174 break; |
1172 case kExternalStringTag: | 1175 case kExternalStringTag: |
1173 if ((type & kStringEncodingMask) == kAsciiStringTag) { | 1176 if ((type & kStringEncodingMask) == kAsciiStringTag) { |
1174 reinterpret_cast<ExternalAsciiString*>(this)-> | 1177 reinterpret_cast<ExternalAsciiString*>(this)-> |
1175 ExternalAsciiStringIterateBody(v); | 1178 ExternalAsciiStringIterateBody(v); |
1176 } else { | 1179 } else { |
1177 reinterpret_cast<ExternalTwoByteString*>(this)-> | 1180 reinterpret_cast<ExternalTwoByteString*>(this)-> |
1178 ExternalTwoByteStringIterateBody(v); | 1181 ExternalTwoByteStringIterateBody(v); |
1179 } | 1182 } |
1180 break; | 1183 break; |
1181 } | 1184 } |
(...skipping 4041 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5223 heap->isolate()->objects_string_input_buffer()); | 5226 heap->isolate()->objects_string_input_buffer()); |
5224 buffer->Reset(0, this); | 5227 buffer->Reset(0, this); |
5225 int result = 0; | 5228 int result = 0; |
5226 while (buffer->has_more()) | 5229 while (buffer->has_more()) |
5227 result += unibrow::Utf8::Length(buffer->GetNext()); | 5230 result += unibrow::Utf8::Length(buffer->GetNext()); |
5228 return result; | 5231 return result; |
5229 } | 5232 } |
5230 | 5233 |
5231 | 5234 |
5232 Vector<const char> String::ToAsciiVector() { | 5235 Vector<const char> String::ToAsciiVector() { |
5233 ASSERT(IsAsciiRepresentation()); | 5236 // Either the string is sequential or external, in which case the encoding |
| 5237 // needs to be ASCII, or the string is a cons or a slice, in which case the |
| 5238 // encoding of the underlying string needs to be ASCII. |
| 5239 ASSERT(IsAsciiRepresentationUnderneath()); |
5234 ASSERT(IsFlat()); | 5240 ASSERT(IsFlat()); |
5235 | 5241 |
5236 int offset = 0; | 5242 int offset = 0; |
5237 int length = this->length(); | 5243 int length = this->length(); |
5238 StringRepresentationTag string_tag = StringShape(this).representation_tag(); | 5244 StringRepresentationTag string_tag = StringShape(this).representation_tag(); |
5239 String* string = this; | 5245 String* string = this; |
5240 if (string_tag == kConsStringTag) { | 5246 if (string_tag == kConsStringTag) { |
5241 ConsString* cons = ConsString::cast(string); | 5247 ConsString* cons = ConsString::cast(string); |
5242 ASSERT(cons->second()->length() == 0); | 5248 ASSERT(cons->second()->length() == 0); |
5243 string = cons->first(); | 5249 string = cons->first(); |
5244 string_tag = StringShape(string).representation_tag(); | 5250 string_tag = StringShape(string).representation_tag(); |
| 5251 ASSERT(string_tag != kConsStringTag); |
5245 } | 5252 } |
5246 if (string_tag == kSeqStringTag) { | 5253 if (string_tag == kSlicedStringTag) { |
5247 SeqAsciiString* seq = SeqAsciiString::cast(string); | 5254 // Note that the parent of a slice cannot be a cons or a slice. |
5248 char* start = seq->GetChars(); | 5255 SlicedString* slice = SlicedString::cast(string); |
| 5256 offset = slice->offset(); |
| 5257 string = slice->parent(); |
| 5258 string_tag = StringShape(string).representation_tag(); |
| 5259 ASSERT(string_tag != kConsStringTag && string_tag != kSlicedStringTag); |
| 5260 } |
| 5261 if (string_tag == kExternalStringTag) { |
| 5262 ExternalAsciiString* ext = ExternalAsciiString::cast(string); |
| 5263 const char* start = ext->resource()->data(); |
5249 return Vector<const char>(start + offset, length); | 5264 return Vector<const char>(start + offset, length); |
5250 } | 5265 } |
5251 ASSERT(string_tag == kExternalStringTag); | 5266 ASSERT(StringShape(string).representation_tag() == kSeqStringTag); |
5252 ExternalAsciiString* ext = ExternalAsciiString::cast(string); | 5267 SeqAsciiString* seq = SeqAsciiString::cast(string); |
5253 const char* start = ext->resource()->data(); | 5268 char* start = seq->GetChars(); |
5254 return Vector<const char>(start + offset, length); | 5269 return Vector<const char>(start + offset, length); |
5255 } | 5270 } |
5256 | 5271 |
5257 | 5272 |
5258 Vector<const uc16> String::ToUC16Vector() { | 5273 Vector<const uc16> String::ToUC16Vector() { |
5259 ASSERT(IsTwoByteRepresentation()); | 5274 // Either the string is sequential or external, in which case the encoding |
| 5275 // needs to be two-byte, or the string is a cons or a slice, in which case |
| 5276 // the encoding of the underlying string needs to be two-byte. |
| 5277 ASSERT(IsTwoByteRepresentationUnderneath()); |
5260 ASSERT(IsFlat()); | 5278 ASSERT(IsFlat()); |
5261 | 5279 |
5262 int offset = 0; | 5280 int offset = 0; |
5263 int length = this->length(); | 5281 int length = this->length(); |
5264 StringRepresentationTag string_tag = StringShape(this).representation_tag(); | 5282 StringRepresentationTag string_tag = StringShape(this).representation_tag(); |
5265 String* string = this; | 5283 String* string = this; |
5266 if (string_tag == kConsStringTag) { | 5284 if (string_tag == kConsStringTag) { |
5267 ConsString* cons = ConsString::cast(string); | 5285 ConsString* cons = ConsString::cast(string); |
5268 ASSERT(cons->second()->length() == 0); | 5286 ASSERT(cons->second()->length() == 0); |
5269 string = cons->first(); | 5287 string = cons->first(); |
5270 string_tag = StringShape(string).representation_tag(); | 5288 string_tag = StringShape(string).representation_tag(); |
| 5289 ASSERT(string_tag != kConsStringTag); |
5271 } | 5290 } |
5272 if (string_tag == kSeqStringTag) { | 5291 if (string_tag == kSlicedStringTag) { |
5273 SeqTwoByteString* seq = SeqTwoByteString::cast(string); | 5292 // Note that the parent of a slice cannot be a cons or a slice. |
5274 return Vector<const uc16>(seq->GetChars() + offset, length); | 5293 SlicedString* slice = SlicedString::cast(string); |
| 5294 offset = slice->offset(); |
| 5295 string = slice->parent(); |
| 5296 string_tag = StringShape(string).representation_tag(); |
| 5297 ASSERT(string_tag != kConsStringTag && string_tag != kSlicedStringTag); |
5275 } | 5298 } |
5276 ASSERT(string_tag == kExternalStringTag); | 5299 if (string_tag == kExternalStringTag) { |
5277 ExternalTwoByteString* ext = ExternalTwoByteString::cast(string); | 5300 ExternalTwoByteString* ext = ExternalTwoByteString::cast(string); |
5278 const uc16* start = | 5301 const uc16* start = |
5279 reinterpret_cast<const uc16*>(ext->resource()->data()); | 5302 reinterpret_cast<const uc16*>(ext->resource()->data()); |
5280 return Vector<const uc16>(start + offset, length); | 5303 return Vector<const uc16>(start + offset, length); |
| 5304 } |
| 5305 ASSERT(StringShape(string).representation_tag() == kSeqStringTag); |
| 5306 SeqTwoByteString* seq = SeqTwoByteString::cast(string); |
| 5307 return Vector<const uc16>(seq->GetChars() + offset, length); |
5281 } | 5308 } |
5282 | 5309 |
5283 | 5310 |
5284 SmartPointer<char> String::ToCString(AllowNullsFlag allow_nulls, | 5311 SmartPointer<char> String::ToCString(AllowNullsFlag allow_nulls, |
5285 RobustnessFlag robust_flag, | 5312 RobustnessFlag robust_flag, |
5286 int offset, | 5313 int offset, |
5287 int length, | 5314 int length, |
5288 int* length_return) { | 5315 int* length_return) { |
5289 if (robust_flag == ROBUST_STRING_TRAVERSAL && !LooksValid()) { | 5316 if (robust_flag == ROBUST_STRING_TRAVERSAL && !LooksValid()) { |
5290 return SmartPointer<char>(NULL); | 5317 return SmartPointer<char>(NULL); |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5341 return ToCString(allow_nulls, robust_flag, 0, -1, length_return); | 5368 return ToCString(allow_nulls, robust_flag, 0, -1, length_return); |
5342 } | 5369 } |
5343 | 5370 |
5344 | 5371 |
5345 const uc16* String::GetTwoByteData() { | 5372 const uc16* String::GetTwoByteData() { |
5346 return GetTwoByteData(0); | 5373 return GetTwoByteData(0); |
5347 } | 5374 } |
5348 | 5375 |
5349 | 5376 |
5350 const uc16* String::GetTwoByteData(unsigned start) { | 5377 const uc16* String::GetTwoByteData(unsigned start) { |
5351 ASSERT(!IsAsciiRepresentation()); | 5378 ASSERT(!IsAsciiRepresentationUnderneath()); |
5352 switch (StringShape(this).representation_tag()) { | 5379 switch (StringShape(this).representation_tag()) { |
5353 case kSeqStringTag: | 5380 case kSeqStringTag: |
5354 return SeqTwoByteString::cast(this)->SeqTwoByteStringGetData(start); | 5381 return SeqTwoByteString::cast(this)->SeqTwoByteStringGetData(start); |
5355 case kExternalStringTag: | 5382 case kExternalStringTag: |
5356 return ExternalTwoByteString::cast(this)-> | 5383 return ExternalTwoByteString::cast(this)-> |
5357 ExternalTwoByteStringGetData(start); | 5384 ExternalTwoByteStringGetData(start); |
| 5385 case kSlicedStringTag: { |
| 5386 SlicedString* slice = SlicedString::cast(this); |
| 5387 return slice->parent()->GetTwoByteData(start + slice->offset()); |
| 5388 } |
5358 case kConsStringTag: | 5389 case kConsStringTag: |
5359 UNREACHABLE(); | 5390 UNREACHABLE(); |
5360 return NULL; | 5391 return NULL; |
5361 } | 5392 } |
5362 UNREACHABLE(); | 5393 UNREACHABLE(); |
5363 return NULL; | 5394 return NULL; |
5364 } | 5395 } |
5365 | 5396 |
5366 | 5397 |
5367 SmartPointer<uc16> String::ToWideCString(RobustnessFlag robust_flag) { | 5398 SmartPointer<uc16> String::ToWideCString(RobustnessFlag robust_flag) { |
(...skipping 270 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5638 &rbb->remaining, | 5669 &rbb->remaining, |
5639 offset_ptr, | 5670 offset_ptr, |
5640 max_chars); | 5671 max_chars); |
5641 } else { | 5672 } else { |
5642 ExternalTwoByteString::cast(input)-> | 5673 ExternalTwoByteString::cast(input)-> |
5643 ExternalTwoByteStringReadBlockIntoBuffer(rbb, | 5674 ExternalTwoByteStringReadBlockIntoBuffer(rbb, |
5644 offset_ptr, | 5675 offset_ptr, |
5645 max_chars); | 5676 max_chars); |
5646 return rbb->util_buffer; | 5677 return rbb->util_buffer; |
5647 } | 5678 } |
| 5679 case kSlicedStringTag: |
| 5680 return SlicedString::cast(input)->SlicedStringReadBlock(rbb, |
| 5681 offset_ptr, |
| 5682 max_chars); |
5648 default: | 5683 default: |
5649 break; | 5684 break; |
5650 } | 5685 } |
5651 | 5686 |
5652 UNREACHABLE(); | 5687 UNREACHABLE(); |
5653 return 0; | 5688 return 0; |
5654 } | 5689 } |
5655 | 5690 |
5656 | 5691 |
5657 void Relocatable::PostGarbageCollectionProcessing() { | 5692 void Relocatable::PostGarbageCollectionProcessing() { |
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5779 if (input->IsAsciiRepresentation()) { | 5814 if (input->IsAsciiRepresentation()) { |
5780 ExternalAsciiString::cast(input)-> | 5815 ExternalAsciiString::cast(input)-> |
5781 ExternalAsciiStringReadBlockIntoBuffer(rbb, offset_ptr, max_chars); | 5816 ExternalAsciiStringReadBlockIntoBuffer(rbb, offset_ptr, max_chars); |
5782 } else { | 5817 } else { |
5783 ExternalTwoByteString::cast(input)-> | 5818 ExternalTwoByteString::cast(input)-> |
5784 ExternalTwoByteStringReadBlockIntoBuffer(rbb, | 5819 ExternalTwoByteStringReadBlockIntoBuffer(rbb, |
5785 offset_ptr, | 5820 offset_ptr, |
5786 max_chars); | 5821 max_chars); |
5787 } | 5822 } |
5788 return; | 5823 return; |
| 5824 case kSlicedStringTag: |
| 5825 SlicedString::cast(input)->SlicedStringReadBlockIntoBuffer(rbb, |
| 5826 offset_ptr, |
| 5827 max_chars); |
| 5828 return; |
5789 default: | 5829 default: |
5790 break; | 5830 break; |
5791 } | 5831 } |
5792 | 5832 |
5793 UNREACHABLE(); | 5833 UNREACHABLE(); |
5794 return; | 5834 return; |
5795 } | 5835 } |
5796 | 5836 |
5797 | 5837 |
5798 const unibrow::byte* String::ReadBlock(String* input, | 5838 const unibrow::byte* String::ReadBlock(String* input, |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5913 } else { | 5953 } else { |
5914 return string->Get(index); | 5954 return string->Get(index); |
5915 } | 5955 } |
5916 } | 5956 } |
5917 | 5957 |
5918 UNREACHABLE(); | 5958 UNREACHABLE(); |
5919 return 0; | 5959 return 0; |
5920 } | 5960 } |
5921 | 5961 |
5922 | 5962 |
| 5963 uint16_t SlicedString::SlicedStringGet(int index) { |
| 5964 return parent()->Get(offset() + index); |
| 5965 } |
| 5966 |
| 5967 |
| 5968 const unibrow::byte* SlicedString::SlicedStringReadBlock( |
| 5969 ReadBlockBuffer* buffer, unsigned* offset_ptr, unsigned chars) { |
| 5970 unsigned offset = this->offset(); |
| 5971 *offset_ptr += offset; |
| 5972 const unibrow::byte* answer = String::ReadBlock(String::cast(parent()), |
| 5973 buffer, offset_ptr, chars); |
| 5974 *offset_ptr -= offset; |
| 5975 return answer; |
| 5976 } |
| 5977 |
| 5978 |
| 5979 void SlicedString::SlicedStringReadBlockIntoBuffer( |
| 5980 ReadBlockBuffer* buffer, unsigned* offset_ptr, unsigned chars) { |
| 5981 unsigned offset = this->offset(); |
| 5982 *offset_ptr += offset; |
| 5983 String::ReadBlockIntoBuffer(String::cast(parent()), |
| 5984 buffer, offset_ptr, chars); |
| 5985 *offset_ptr -= offset; |
| 5986 } |
| 5987 |
5923 template <typename sinkchar> | 5988 template <typename sinkchar> |
5924 void String::WriteToFlat(String* src, | 5989 void String::WriteToFlat(String* src, |
5925 sinkchar* sink, | 5990 sinkchar* sink, |
5926 int f, | 5991 int f, |
5927 int t) { | 5992 int t) { |
5928 String* source = src; | 5993 String* source = src; |
5929 int from = f; | 5994 int from = f; |
5930 int to = t; | 5995 int to = t; |
5931 while (true) { | 5996 while (true) { |
5932 ASSERT(0 <= from && from <= to && to <= source->length()); | 5997 ASSERT(0 <= from && from <= to && to <= source->length()); |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5980 WriteToFlat(second, | 6045 WriteToFlat(second, |
5981 sink + boundary - from, | 6046 sink + boundary - from, |
5982 0, | 6047 0, |
5983 to - boundary); | 6048 to - boundary); |
5984 to = boundary; | 6049 to = boundary; |
5985 } | 6050 } |
5986 source = first; | 6051 source = first; |
5987 } | 6052 } |
5988 break; | 6053 break; |
5989 } | 6054 } |
| 6055 case kAsciiStringTag | kSlicedStringTag: |
| 6056 case kTwoByteStringTag | kSlicedStringTag: { |
| 6057 SlicedString* slice = SlicedString::cast(source); |
| 6058 unsigned offset = slice->offset(); |
| 6059 WriteToFlat(slice->parent(), sink, from + offset, to + offset); |
| 6060 return; |
| 6061 } |
5990 } | 6062 } |
5991 } | 6063 } |
5992 } | 6064 } |
5993 | 6065 |
5994 | 6066 |
5995 template <typename IteratorA, typename IteratorB> | 6067 template <typename IteratorA, typename IteratorB> |
5996 static inline bool CompareStringContents(IteratorA* ia, IteratorB* ib) { | 6068 static inline bool CompareStringContents(IteratorA* ia, IteratorB* ib) { |
5997 // General slow case check. We know that the ia and ib iterators | 6069 // General slow case check. We know that the ia and ib iterators |
5998 // have the same length. | 6070 // have the same length. |
5999 while (ia->has_more()) { | 6071 while (ia->has_more()) { |
(...skipping 5927 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11927 if (break_point_objects()->IsUndefined()) return 0; | 11999 if (break_point_objects()->IsUndefined()) return 0; |
11928 // Single beak point. | 12000 // Single beak point. |
11929 if (!break_point_objects()->IsFixedArray()) return 1; | 12001 if (!break_point_objects()->IsFixedArray()) return 1; |
11930 // Multiple break points. | 12002 // Multiple break points. |
11931 return FixedArray::cast(break_point_objects())->length(); | 12003 return FixedArray::cast(break_point_objects())->length(); |
11932 } | 12004 } |
11933 #endif | 12005 #endif |
11934 | 12006 |
11935 | 12007 |
11936 } } // namespace v8::internal | 12008 } } // namespace v8::internal |
OLD | NEW |