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

Side by Side Diff: src/objects.cc

Issue 7477045: Tentative implementation of string slices (hidden under the flag --string-slices). (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Some more suggested changes. Created 9 years, 4 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 | Annotate | Revision Log
OLDNEW
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
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
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
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
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
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
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
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
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
OLDNEW
« src/ia32/code-stubs-ia32.cc ('K') | « src/objects.h ('k') | src/objects-debug.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698