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 4044 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5226 heap->isolate()->objects_string_input_buffer()); | 5229 heap->isolate()->objects_string_input_buffer()); |
5227 buffer->Reset(0, this); | 5230 buffer->Reset(0, this); |
5228 int result = 0; | 5231 int result = 0; |
5229 while (buffer->has_more()) | 5232 while (buffer->has_more()) |
5230 result += unibrow::Utf8::Length(buffer->GetNext()); | 5233 result += unibrow::Utf8::Length(buffer->GetNext()); |
5231 return result; | 5234 return result; |
5232 } | 5235 } |
5233 | 5236 |
5234 | 5237 |
5235 Vector<const char> String::ToAsciiVector() { | 5238 Vector<const char> String::ToAsciiVector() { |
5236 ASSERT(IsAsciiRepresentation()); | 5239 // Either the string is sequential of external, in which case the encoding |
Vitaly Repeshko
2011/08/19 16:27:40
of -> or
| |
5240 // needs to be ASCII, or the string is a cons or a slice, in which case the | |
5241 // encoding of the underlying string needs to be ASCII. | |
5242 ASSERT(IsAsciiRepresentationUnderneath()); | |
5237 ASSERT(IsFlat()); | 5243 ASSERT(IsFlat()); |
5238 | 5244 |
5239 int offset = 0; | 5245 int offset = 0; |
5240 int length = this->length(); | 5246 int length = this->length(); |
5241 StringRepresentationTag string_tag = StringShape(this).representation_tag(); | 5247 StringRepresentationTag string_tag = StringShape(this).representation_tag(); |
5242 String* string = this; | 5248 String* string = this; |
5243 if (string_tag == kConsStringTag) { | 5249 if (string_tag == kConsStringTag) { |
5244 ConsString* cons = ConsString::cast(string); | 5250 ConsString* cons = ConsString::cast(string); |
5245 ASSERT(cons->second()->length() == 0); | 5251 ASSERT(cons->second()->length() == 0); |
5246 string = cons->first(); | 5252 string = cons->first(); |
5247 string_tag = StringShape(string).representation_tag(); | 5253 string_tag = StringShape(string).representation_tag(); |
5254 ASSERT(string_tag != kConsStringTag); | |
5248 } | 5255 } |
5249 if (string_tag == kSeqStringTag) { | 5256 if (string_tag == kSlicedStringTag) { |
5250 SeqAsciiString* seq = SeqAsciiString::cast(string); | 5257 // Note that the parent of a slice cannot be a cons or a slice. |
5251 char* start = seq->GetChars(); | 5258 SlicedString* slice = SlicedString::cast(string); |
5259 offset = slice->offset(); | |
5260 string = slice->parent(); | |
5261 string_tag = StringShape(string).representation_tag(); | |
5262 ASSERT(string_tag != kConsStringTag && string_tag != kSlicedStringTag); | |
5263 } | |
5264 if (string_tag == kExternalStringTag) { | |
5265 ExternalAsciiString* ext = ExternalAsciiString::cast(string); | |
5266 const char* start = ext->resource()->data(); | |
5252 return Vector<const char>(start + offset, length); | 5267 return Vector<const char>(start + offset, length); |
5253 } | 5268 } |
5254 ASSERT(string_tag == kExternalStringTag); | 5269 ASSERT(StringShape(string).representation_tag() == kSeqStringTag); |
5255 ExternalAsciiString* ext = ExternalAsciiString::cast(string); | 5270 SeqAsciiString* seq = SeqAsciiString::cast(string); |
5256 const char* start = ext->resource()->data(); | 5271 char* start = seq->GetChars(); |
5257 return Vector<const char>(start + offset, length); | 5272 return Vector<const char>(start + offset, length); |
5258 } | 5273 } |
5259 | 5274 |
5260 | 5275 |
5261 Vector<const uc16> String::ToUC16Vector() { | 5276 Vector<const uc16> String::ToUC16Vector() { |
5262 ASSERT(IsTwoByteRepresentation()); | 5277 // Either the string is sequential of external, in which case the encoding |
Vitaly Repeshko
2011/08/19 16:27:40
of -> or
| |
5278 // needs to be two-byte, or the string is a cons or a slice, in which case | |
5279 // the encoding of the underlying string needs to be two-byte. | |
5280 ASSERT(IsTwoByteRepresentationUnderneath()); | |
5263 ASSERT(IsFlat()); | 5281 ASSERT(IsFlat()); |
5264 | 5282 |
5265 int offset = 0; | 5283 int offset = 0; |
5266 int length = this->length(); | 5284 int length = this->length(); |
5267 StringRepresentationTag string_tag = StringShape(this).representation_tag(); | 5285 StringRepresentationTag string_tag = StringShape(this).representation_tag(); |
5268 String* string = this; | 5286 String* string = this; |
5269 if (string_tag == kConsStringTag) { | 5287 if (string_tag == kConsStringTag) { |
5270 ConsString* cons = ConsString::cast(string); | 5288 ConsString* cons = ConsString::cast(string); |
5271 ASSERT(cons->second()->length() == 0); | 5289 ASSERT(cons->second()->length() == 0); |
5272 string = cons->first(); | 5290 string = cons->first(); |
5273 string_tag = StringShape(string).representation_tag(); | 5291 string_tag = StringShape(string).representation_tag(); |
5292 ASSERT(string_tag != kConsStringTag); | |
5274 } | 5293 } |
5275 if (string_tag == kSeqStringTag) { | 5294 if (string_tag == kSlicedStringTag) { |
5276 SeqTwoByteString* seq = SeqTwoByteString::cast(string); | 5295 // Note that the parent of a slice cannot be a cons or a slice. |
5277 return Vector<const uc16>(seq->GetChars() + offset, length); | 5296 SlicedString* slice = SlicedString::cast(string); |
5297 offset = slice->offset(); | |
5298 string = slice->parent(); | |
5299 string_tag = StringShape(string).representation_tag(); | |
5300 ASSERT(string_tag != kConsStringTag && string_tag != kSlicedStringTag); | |
5278 } | 5301 } |
5279 ASSERT(string_tag == kExternalStringTag); | 5302 if (string_tag == kExternalStringTag) { |
5280 ExternalTwoByteString* ext = ExternalTwoByteString::cast(string); | 5303 ExternalTwoByteString* ext = ExternalTwoByteString::cast(string); |
5281 const uc16* start = | 5304 const uc16* start = |
5282 reinterpret_cast<const uc16*>(ext->resource()->data()); | 5305 reinterpret_cast<const uc16*>(ext->resource()->data()); |
5283 return Vector<const uc16>(start + offset, length); | 5306 return Vector<const uc16>(start + offset, length); |
5307 } | |
5308 ASSERT(StringShape(string).representation_tag() == kSeqStringTag); | |
5309 SeqTwoByteString* seq = SeqTwoByteString::cast(string); | |
5310 return Vector<const uc16>(seq->GetChars() + offset, length); | |
5284 } | 5311 } |
5285 | 5312 |
5286 | 5313 |
5287 SmartPointer<char> String::ToCString(AllowNullsFlag allow_nulls, | 5314 SmartPointer<char> String::ToCString(AllowNullsFlag allow_nulls, |
5288 RobustnessFlag robust_flag, | 5315 RobustnessFlag robust_flag, |
5289 int offset, | 5316 int offset, |
5290 int length, | 5317 int length, |
5291 int* length_return) { | 5318 int* length_return) { |
5292 if (robust_flag == ROBUST_STRING_TRAVERSAL && !LooksValid()) { | 5319 if (robust_flag == ROBUST_STRING_TRAVERSAL && !LooksValid()) { |
5293 return SmartPointer<char>(NULL); | 5320 return SmartPointer<char>(NULL); |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5344 return ToCString(allow_nulls, robust_flag, 0, -1, length_return); | 5371 return ToCString(allow_nulls, robust_flag, 0, -1, length_return); |
5345 } | 5372 } |
5346 | 5373 |
5347 | 5374 |
5348 const uc16* String::GetTwoByteData() { | 5375 const uc16* String::GetTwoByteData() { |
5349 return GetTwoByteData(0); | 5376 return GetTwoByteData(0); |
5350 } | 5377 } |
5351 | 5378 |
5352 | 5379 |
5353 const uc16* String::GetTwoByteData(unsigned start) { | 5380 const uc16* String::GetTwoByteData(unsigned start) { |
5354 ASSERT(!IsAsciiRepresentation()); | 5381 ASSERT(!IsAsciiRepresentationUnderneath()); |
5355 switch (StringShape(this).representation_tag()) { | 5382 switch (StringShape(this).representation_tag()) { |
5356 case kSeqStringTag: | 5383 case kSeqStringTag: |
5357 return SeqTwoByteString::cast(this)->SeqTwoByteStringGetData(start); | 5384 return SeqTwoByteString::cast(this)->SeqTwoByteStringGetData(start); |
5358 case kExternalStringTag: | 5385 case kExternalStringTag: |
5359 return ExternalTwoByteString::cast(this)-> | 5386 return ExternalTwoByteString::cast(this)-> |
5360 ExternalTwoByteStringGetData(start); | 5387 ExternalTwoByteStringGetData(start); |
5388 case kSlicedStringTag: { | |
5389 SlicedString* slice = SlicedString::cast(this); | |
5390 return slice->parent()->GetTwoByteData(start + slice->offset()); | |
5391 } | |
5361 case kConsStringTag: | 5392 case kConsStringTag: |
5362 UNREACHABLE(); | 5393 UNREACHABLE(); |
5363 return NULL; | 5394 return NULL; |
5364 } | 5395 } |
5365 UNREACHABLE(); | 5396 UNREACHABLE(); |
5366 return NULL; | 5397 return NULL; |
5367 } | 5398 } |
5368 | 5399 |
5369 | 5400 |
5370 SmartPointer<uc16> String::ToWideCString(RobustnessFlag robust_flag) { | 5401 SmartPointer<uc16> String::ToWideCString(RobustnessFlag robust_flag) { |
(...skipping 270 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5641 &rbb->remaining, | 5672 &rbb->remaining, |
5642 offset_ptr, | 5673 offset_ptr, |
5643 max_chars); | 5674 max_chars); |
5644 } else { | 5675 } else { |
5645 ExternalTwoByteString::cast(input)-> | 5676 ExternalTwoByteString::cast(input)-> |
5646 ExternalTwoByteStringReadBlockIntoBuffer(rbb, | 5677 ExternalTwoByteStringReadBlockIntoBuffer(rbb, |
5647 offset_ptr, | 5678 offset_ptr, |
5648 max_chars); | 5679 max_chars); |
5649 return rbb->util_buffer; | 5680 return rbb->util_buffer; |
5650 } | 5681 } |
5682 case kSlicedStringTag: | |
5683 return SlicedString::cast(input)->SlicedStringReadBlock(rbb, | |
5684 offset_ptr, | |
5685 max_chars); | |
5651 default: | 5686 default: |
5652 break; | 5687 break; |
5653 } | 5688 } |
5654 | 5689 |
5655 UNREACHABLE(); | 5690 UNREACHABLE(); |
5656 return 0; | 5691 return 0; |
5657 } | 5692 } |
5658 | 5693 |
5659 | 5694 |
5660 void Relocatable::PostGarbageCollectionProcessing() { | 5695 void Relocatable::PostGarbageCollectionProcessing() { |
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5782 if (input->IsAsciiRepresentation()) { | 5817 if (input->IsAsciiRepresentation()) { |
5783 ExternalAsciiString::cast(input)-> | 5818 ExternalAsciiString::cast(input)-> |
5784 ExternalAsciiStringReadBlockIntoBuffer(rbb, offset_ptr, max_chars); | 5819 ExternalAsciiStringReadBlockIntoBuffer(rbb, offset_ptr, max_chars); |
5785 } else { | 5820 } else { |
5786 ExternalTwoByteString::cast(input)-> | 5821 ExternalTwoByteString::cast(input)-> |
5787 ExternalTwoByteStringReadBlockIntoBuffer(rbb, | 5822 ExternalTwoByteStringReadBlockIntoBuffer(rbb, |
5788 offset_ptr, | 5823 offset_ptr, |
5789 max_chars); | 5824 max_chars); |
5790 } | 5825 } |
5791 return; | 5826 return; |
5827 case kSlicedStringTag: | |
5828 SlicedString::cast(input)->SlicedStringReadBlockIntoBuffer(rbb, | |
5829 offset_ptr, | |
5830 max_chars); | |
5831 return; | |
5792 default: | 5832 default: |
5793 break; | 5833 break; |
5794 } | 5834 } |
5795 | 5835 |
5796 UNREACHABLE(); | 5836 UNREACHABLE(); |
5797 return; | 5837 return; |
5798 } | 5838 } |
5799 | 5839 |
5800 | 5840 |
5801 const unibrow::byte* String::ReadBlock(String* input, | 5841 const unibrow::byte* String::ReadBlock(String* input, |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5916 } else { | 5956 } else { |
5917 return string->Get(index); | 5957 return string->Get(index); |
5918 } | 5958 } |
5919 } | 5959 } |
5920 | 5960 |
5921 UNREACHABLE(); | 5961 UNREACHABLE(); |
5922 return 0; | 5962 return 0; |
5923 } | 5963 } |
5924 | 5964 |
5925 | 5965 |
5966 uint16_t SlicedString::SlicedStringGet(int index) { | |
5967 return parent()->Get(offset() + index); | |
5968 } | |
5969 | |
5970 | |
5971 const unibrow::byte* SlicedString::SlicedStringReadBlock( | |
5972 ReadBlockBuffer* buffer, unsigned* offset_ptr, unsigned chars) { | |
5973 unsigned offset = this->offset(); | |
5974 *offset_ptr += offset; | |
5975 const unibrow::byte* answer = String::ReadBlock(String::cast(parent()), | |
5976 buffer, offset_ptr, chars); | |
5977 *offset_ptr -= offset; | |
5978 return answer; | |
5979 } | |
5980 | |
5981 | |
5982 void SlicedString::SlicedStringReadBlockIntoBuffer( | |
5983 ReadBlockBuffer* buffer, unsigned* offset_ptr, unsigned chars) { | |
5984 unsigned offset = this->offset(); | |
5985 *offset_ptr += offset; | |
5986 String::ReadBlockIntoBuffer(String::cast(parent()), | |
5987 buffer, offset_ptr, chars); | |
5988 *offset_ptr -= offset; | |
5989 } | |
5990 | |
5926 template <typename sinkchar> | 5991 template <typename sinkchar> |
5927 void String::WriteToFlat(String* src, | 5992 void String::WriteToFlat(String* src, |
5928 sinkchar* sink, | 5993 sinkchar* sink, |
5929 int f, | 5994 int f, |
5930 int t) { | 5995 int t) { |
5931 String* source = src; | 5996 String* source = src; |
5932 int from = f; | 5997 int from = f; |
5933 int to = t; | 5998 int to = t; |
5934 while (true) { | 5999 while (true) { |
5935 ASSERT(0 <= from && from <= to && to <= source->length()); | 6000 ASSERT(0 <= from && from <= to && to <= source->length()); |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5983 WriteToFlat(second, | 6048 WriteToFlat(second, |
5984 sink + boundary - from, | 6049 sink + boundary - from, |
5985 0, | 6050 0, |
5986 to - boundary); | 6051 to - boundary); |
5987 to = boundary; | 6052 to = boundary; |
5988 } | 6053 } |
5989 source = first; | 6054 source = first; |
5990 } | 6055 } |
5991 break; | 6056 break; |
5992 } | 6057 } |
6058 case kAsciiStringTag | kSlicedStringTag: | |
6059 case kTwoByteStringTag | kSlicedStringTag: { | |
6060 SlicedString* slice = SlicedString::cast(source); | |
6061 unsigned offset = slice->offset(); | |
6062 WriteToFlat(slice->parent(), sink, from + offset, to + offset); | |
6063 return; | |
6064 } | |
5993 } | 6065 } |
5994 } | 6066 } |
5995 } | 6067 } |
5996 | 6068 |
5997 | 6069 |
5998 template <typename IteratorA, typename IteratorB> | 6070 template <typename IteratorA, typename IteratorB> |
5999 static inline bool CompareStringContents(IteratorA* ia, IteratorB* ib) { | 6071 static inline bool CompareStringContents(IteratorA* ia, IteratorB* ib) { |
6000 // General slow case check. We know that the ia and ib iterators | 6072 // General slow case check. We know that the ia and ib iterators |
6001 // have the same length. | 6073 // have the same length. |
6002 while (ia->has_more()) { | 6074 while (ia->has_more()) { |
(...skipping 5935 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
11938 if (break_point_objects()->IsUndefined()) return 0; | 12010 if (break_point_objects()->IsUndefined()) return 0; |
11939 // Single beak point. | 12011 // Single beak point. |
11940 if (!break_point_objects()->IsFixedArray()) return 1; | 12012 if (!break_point_objects()->IsFixedArray()) return 1; |
11941 // Multiple break points. | 12013 // Multiple break points. |
11942 return FixedArray::cast(break_point_objects())->length(); | 12014 return FixedArray::cast(break_point_objects())->length(); |
11943 } | 12015 } |
11944 #endif | 12016 #endif |
11945 | 12017 |
11946 | 12018 |
11947 } } // namespace v8::internal | 12019 } } // namespace v8::internal |
OLD | NEW |