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

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: Implemented 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 4044 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698