Chromium Code Reviews| 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 715 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 726 return true; // An MP3File, an M. | 726 return true; // An MP3File, an M. |
| 727 } | 727 } |
| 728 return false; | 728 return false; |
| 729 } | 729 } |
| 730 | 730 |
| 731 | 731 |
| 732 MaybeObject* String::SlowTryFlatten(PretenureFlag pretenure) { | 732 MaybeObject* String::SlowTryFlatten(PretenureFlag pretenure) { |
| 733 #ifdef DEBUG | 733 #ifdef DEBUG |
| 734 // Do not attempt to flatten in debug mode when allocation is not | 734 // Do not attempt to flatten in debug mode when allocation is not |
| 735 // allowed. This is to avoid an assertion failure when allocating. | 735 // allowed. This is to avoid an assertion failure when allocating. |
| 736 // Flattening strings is the only case where we always allow | 736 // Flattening and truncating strings are the only cases where we always |
| 737 // allocation because no GC is performed if the allocation fails. | 737 // allow allocation because no GC is performed if the allocation fails. |
| 738 if (!HEAP->IsAllocationAllowed()) return this; | 738 if (!HEAP->IsAllocationAllowed()) return this; |
| 739 #endif | 739 #endif |
| 740 | 740 |
| 741 ASSERT(StringShape(this).representation_tag() == kConsStringTag); | |
| 742 | |
| 741 Heap* heap = GetHeap(); | 743 Heap* heap = GetHeap(); |
| 742 switch (StringShape(this).representation_tag()) { | 744 ConsString* cs = ConsString::cast(this); |
|
Vitaly Repeshko
2011/08/17 19:20:23
If there are no intended semantic changes here, pl
| |
| 743 case kConsStringTag: { | 745 // There's little point in putting the flat string in new space if the |
| 744 ConsString* cs = ConsString::cast(this); | 746 // cons string is in old space. It can never get GCed until there is |
| 745 if (cs->second()->length() == 0) { | 747 // an old space GC. |
| 746 return cs->first(); | 748 PretenureFlag tenure = heap->InNewSpace(this) ? pretenure : TENURED; |
| 747 } | 749 int len = length(); |
| 748 // There's little point in putting the flat string in new space if the | 750 Object* object; |
| 749 // cons string is in old space. It can never get GCed until there is | 751 String* result; |
| 750 // an old space GC. | 752 if (IsAsciiRepresentation()) { |
| 751 PretenureFlag tenure = heap->InNewSpace(this) ? pretenure : TENURED; | 753 { MaybeObject* maybe_object = heap->AllocateRawAsciiString(len, tenure); |
| 752 int len = length(); | 754 if (!maybe_object->ToObject(&object)) return maybe_object; |
| 753 Object* object; | |
| 754 String* result; | |
| 755 if (IsAsciiRepresentation()) { | |
| 756 { MaybeObject* maybe_object = heap->AllocateRawAsciiString(len, tenure); | |
| 757 if (!maybe_object->ToObject(&object)) return maybe_object; | |
| 758 } | |
| 759 result = String::cast(object); | |
| 760 String* first = cs->first(); | |
| 761 int first_length = first->length(); | |
| 762 char* dest = SeqAsciiString::cast(result)->GetChars(); | |
| 763 WriteToFlat(first, dest, 0, first_length); | |
| 764 String* second = cs->second(); | |
| 765 WriteToFlat(second, | |
| 766 dest + first_length, | |
| 767 0, | |
| 768 len - first_length); | |
| 769 } else { | |
| 770 { MaybeObject* maybe_object = | |
| 771 heap->AllocateRawTwoByteString(len, tenure); | |
| 772 if (!maybe_object->ToObject(&object)) return maybe_object; | |
| 773 } | |
| 774 result = String::cast(object); | |
| 775 uc16* dest = SeqTwoByteString::cast(result)->GetChars(); | |
| 776 String* first = cs->first(); | |
| 777 int first_length = first->length(); | |
| 778 WriteToFlat(first, dest, 0, first_length); | |
| 779 String* second = cs->second(); | |
| 780 WriteToFlat(second, | |
| 781 dest + first_length, | |
| 782 0, | |
| 783 len - first_length); | |
| 784 } | |
| 785 cs->set_first(result); | |
| 786 cs->set_second(heap->empty_string()); | |
| 787 return result; | |
| 788 } | 755 } |
| 789 default: | 756 result = String::cast(object); |
| 790 return this; | 757 String* first = cs->first(); |
| 758 int first_length = first->length(); | |
| 759 char* dest = SeqAsciiString::cast(result)->GetChars(); | |
| 760 WriteToFlat(first, dest, 0, first_length); | |
| 761 String* second = cs->second(); | |
| 762 WriteToFlat(second, | |
| 763 dest + first_length, | |
| 764 0, | |
| 765 len - first_length); | |
| 766 } else { | |
| 767 { MaybeObject* maybe_object = | |
| 768 heap->AllocateRawTwoByteString(len, tenure); | |
| 769 if (!maybe_object->ToObject(&object)) return maybe_object; | |
| 770 } | |
| 771 result = String::cast(object); | |
| 772 uc16* dest = SeqTwoByteString::cast(result)->GetChars(); | |
| 773 String* first = cs->first(); | |
| 774 int first_length = first->length(); | |
| 775 WriteToFlat(first, dest, 0, first_length); | |
| 776 String* second = cs->second(); | |
| 777 WriteToFlat(second, | |
| 778 dest + first_length, | |
| 779 0, | |
| 780 len - first_length); | |
| 791 } | 781 } |
| 782 cs->set_first(result); | |
| 783 cs->set_second(heap->empty_string()); | |
| 784 ASSERT(this->IsFlat()); | |
| 785 return result; | |
| 792 } | 786 } |
| 793 | 787 |
| 794 | 788 |
| 795 bool String::MakeExternal(v8::String::ExternalStringResource* resource) { | 789 bool String::MakeExternal(v8::String::ExternalStringResource* resource) { |
| 796 // Externalizing twice leaks the external resource, so it's | 790 // Externalizing twice leaks the external resource, so it's |
| 797 // prohibited by the API. | 791 // prohibited by the API. |
| 798 ASSERT(!this->IsExternalString()); | 792 ASSERT(!this->IsExternalString()); |
| 799 #ifdef DEBUG | 793 #ifdef DEBUG |
| 800 if (FLAG_enable_slow_asserts) { | 794 if (FLAG_enable_slow_asserts) { |
| 801 // Assert that the resource and the string are equivalent. | 795 // Assert that the resource and the string are equivalent. |
| (...skipping 360 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1162 ObjectVisitor* v) { | 1156 ObjectVisitor* v) { |
| 1163 // Avoiding <Type>::cast(this) because it accesses the map pointer field. | 1157 // Avoiding <Type>::cast(this) because it accesses the map pointer field. |
| 1164 // During GC, the map pointer field is encoded. | 1158 // During GC, the map pointer field is encoded. |
| 1165 if (type < FIRST_NONSTRING_TYPE) { | 1159 if (type < FIRST_NONSTRING_TYPE) { |
| 1166 switch (type & kStringRepresentationMask) { | 1160 switch (type & kStringRepresentationMask) { |
| 1167 case kSeqStringTag: | 1161 case kSeqStringTag: |
| 1168 break; | 1162 break; |
| 1169 case kConsStringTag: | 1163 case kConsStringTag: |
| 1170 ConsString::BodyDescriptor::IterateBody(this, v); | 1164 ConsString::BodyDescriptor::IterateBody(this, v); |
| 1171 break; | 1165 break; |
| 1166 case kSlicedStringTag: | |
| 1167 SlicedString::BodyDescriptor::IterateBody(this, v); | |
| 1168 break; | |
| 1172 case kExternalStringTag: | 1169 case kExternalStringTag: |
| 1173 if ((type & kStringEncodingMask) == kAsciiStringTag) { | 1170 if ((type & kStringEncodingMask) == kAsciiStringTag) { |
| 1174 reinterpret_cast<ExternalAsciiString*>(this)-> | 1171 reinterpret_cast<ExternalAsciiString*>(this)-> |
| 1175 ExternalAsciiStringIterateBody(v); | 1172 ExternalAsciiStringIterateBody(v); |
| 1176 } else { | 1173 } else { |
| 1177 reinterpret_cast<ExternalTwoByteString*>(this)-> | 1174 reinterpret_cast<ExternalTwoByteString*>(this)-> |
| 1178 ExternalTwoByteStringIterateBody(v); | 1175 ExternalTwoByteStringIterateBody(v); |
| 1179 } | 1176 } |
| 1180 break; | 1177 break; |
| 1181 } | 1178 } |
| (...skipping 4056 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5238 | 5235 |
| 5239 int offset = 0; | 5236 int offset = 0; |
| 5240 int length = this->length(); | 5237 int length = this->length(); |
| 5241 StringRepresentationTag string_tag = StringShape(this).representation_tag(); | 5238 StringRepresentationTag string_tag = StringShape(this).representation_tag(); |
| 5242 String* string = this; | 5239 String* string = this; |
| 5243 if (string_tag == kConsStringTag) { | 5240 if (string_tag == kConsStringTag) { |
| 5244 ConsString* cons = ConsString::cast(string); | 5241 ConsString* cons = ConsString::cast(string); |
| 5245 ASSERT(cons->second()->length() == 0); | 5242 ASSERT(cons->second()->length() == 0); |
| 5246 string = cons->first(); | 5243 string = cons->first(); |
| 5247 string_tag = StringShape(string).representation_tag(); | 5244 string_tag = StringShape(string).representation_tag(); |
| 5245 ASSERT(string_tag != kConsStringTag); | |
| 5248 } | 5246 } |
| 5249 if (string_tag == kSeqStringTag) { | 5247 if (string_tag == kSlicedStringTag) { |
| 5250 SeqAsciiString* seq = SeqAsciiString::cast(string); | 5248 // Note that the parent of a slice cannot be a cons. |
|
Vitaly Repeshko
2011/08/17 19:20:23
... or a slice.
| |
| 5251 char* start = seq->GetChars(); | 5249 SlicedString* slice = SlicedString::cast(string); |
| 5250 offset = slice->offset(); | |
| 5251 string = slice->parent(); | |
|
Vitaly Repeshko
2011/08/17 19:20:23
string_tag also should be updated. Either add a TO
| |
| 5252 } | |
| 5253 if (string_tag == kExternalStringTag) { | |
| 5254 ExternalAsciiString* ext = ExternalAsciiString::cast(string); | |
| 5255 const char* start = ext->resource()->data(); | |
| 5252 return Vector<const char>(start + offset, length); | 5256 return Vector<const char>(start + offset, length); |
| 5253 } | 5257 } |
| 5254 ASSERT(string_tag == kExternalStringTag); | 5258 ASSERT(StringShape(string).representation_tag() == kSeqStringTag); |
| 5255 ExternalAsciiString* ext = ExternalAsciiString::cast(string); | 5259 SeqAsciiString* seq = SeqAsciiString::cast(string); |
| 5256 const char* start = ext->resource()->data(); | 5260 char* start = seq->GetChars(); |
| 5257 return Vector<const char>(start + offset, length); | 5261 return Vector<const char>(start + offset, length); |
| 5258 } | 5262 } |
| 5259 | 5263 |
| 5260 | 5264 |
| 5261 Vector<const uc16> String::ToUC16Vector() { | 5265 Vector<const uc16> String::ToUC16Vector() { |
| 5262 ASSERT(IsTwoByteRepresentation()); | 5266 ASSERT(IsTwoByteRepresentation()); |
| 5263 ASSERT(IsFlat()); | 5267 ASSERT(IsFlat()); |
| 5264 | 5268 |
| 5265 int offset = 0; | 5269 int offset = 0; |
| 5266 int length = this->length(); | 5270 int length = this->length(); |
| 5267 StringRepresentationTag string_tag = StringShape(this).representation_tag(); | 5271 StringRepresentationTag string_tag = StringShape(this).representation_tag(); |
| 5268 String* string = this; | 5272 String* string = this; |
| 5269 if (string_tag == kConsStringTag) { | 5273 if (string_tag == kConsStringTag) { |
| 5270 ConsString* cons = ConsString::cast(string); | 5274 ConsString* cons = ConsString::cast(string); |
| 5271 ASSERT(cons->second()->length() == 0); | 5275 ASSERT(cons->second()->length() == 0); |
| 5272 string = cons->first(); | 5276 string = cons->first(); |
| 5273 string_tag = StringShape(string).representation_tag(); | 5277 string_tag = StringShape(string).representation_tag(); |
| 5278 ASSERT(string_tag != kConsStringTag); | |
| 5274 } | 5279 } |
| 5275 if (string_tag == kSeqStringTag) { | 5280 if (string_tag == kSlicedStringTag) { |
| 5276 SeqTwoByteString* seq = SeqTwoByteString::cast(string); | 5281 // Note that the parent of a slice cannot be a cons. |
|
Vitaly Repeshko
2011/08/17 19:20:23
See above.
| |
| 5277 return Vector<const uc16>(seq->GetChars() + offset, length); | 5282 SlicedString* slice = SlicedString::cast(string); |
| 5283 offset = slice->offset(); | |
| 5284 string = slice->parent(); | |
| 5278 } | 5285 } |
| 5279 ASSERT(string_tag == kExternalStringTag); | 5286 if (string_tag == kExternalStringTag) { |
| 5280 ExternalTwoByteString* ext = ExternalTwoByteString::cast(string); | 5287 ExternalTwoByteString* ext = ExternalTwoByteString::cast(string); |
| 5281 const uc16* start = | 5288 const uc16* start = |
| 5282 reinterpret_cast<const uc16*>(ext->resource()->data()); | 5289 reinterpret_cast<const uc16*>(ext->resource()->data()); |
| 5283 return Vector<const uc16>(start + offset, length); | 5290 return Vector<const uc16>(start + offset, length); |
| 5291 } | |
| 5292 ASSERT(StringShape(string).representation_tag() == kSeqStringTag); | |
| 5293 SeqTwoByteString* seq = SeqTwoByteString::cast(string); | |
| 5294 return Vector<const uc16>(seq->GetChars() + offset, length); | |
| 5284 } | 5295 } |
| 5285 | 5296 |
| 5286 | 5297 |
| 5287 SmartPointer<char> String::ToCString(AllowNullsFlag allow_nulls, | 5298 SmartPointer<char> String::ToCString(AllowNullsFlag allow_nulls, |
| 5288 RobustnessFlag robust_flag, | 5299 RobustnessFlag robust_flag, |
| 5289 int offset, | 5300 int offset, |
| 5290 int length, | 5301 int length, |
| 5291 int* length_return) { | 5302 int* length_return) { |
| 5292 if (robust_flag == ROBUST_STRING_TRAVERSAL && !LooksValid()) { | 5303 if (robust_flag == ROBUST_STRING_TRAVERSAL && !LooksValid()) { |
| 5293 return SmartPointer<char>(NULL); | 5304 return SmartPointer<char>(NULL); |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5351 | 5362 |
| 5352 | 5363 |
| 5353 const uc16* String::GetTwoByteData(unsigned start) { | 5364 const uc16* String::GetTwoByteData(unsigned start) { |
| 5354 ASSERT(!IsAsciiRepresentation()); | 5365 ASSERT(!IsAsciiRepresentation()); |
| 5355 switch (StringShape(this).representation_tag()) { | 5366 switch (StringShape(this).representation_tag()) { |
| 5356 case kSeqStringTag: | 5367 case kSeqStringTag: |
| 5357 return SeqTwoByteString::cast(this)->SeqTwoByteStringGetData(start); | 5368 return SeqTwoByteString::cast(this)->SeqTwoByteStringGetData(start); |
| 5358 case kExternalStringTag: | 5369 case kExternalStringTag: |
| 5359 return ExternalTwoByteString::cast(this)-> | 5370 return ExternalTwoByteString::cast(this)-> |
| 5360 ExternalTwoByteStringGetData(start); | 5371 ExternalTwoByteStringGetData(start); |
| 5372 case kSlicedStringTag: { | |
| 5373 SlicedString* slice = SlicedString::cast(this); | |
| 5374 return slice->parent()->GetTwoByteData(start + slice->offset()); | |
| 5375 } | |
| 5361 case kConsStringTag: | 5376 case kConsStringTag: |
| 5362 UNREACHABLE(); | 5377 UNREACHABLE(); |
| 5363 return NULL; | 5378 return NULL; |
| 5364 } | 5379 } |
| 5365 UNREACHABLE(); | 5380 UNREACHABLE(); |
| 5366 return NULL; | 5381 return NULL; |
| 5367 } | 5382 } |
| 5368 | 5383 |
| 5369 | 5384 |
| 5370 SmartPointer<uc16> String::ToWideCString(RobustnessFlag robust_flag) { | 5385 SmartPointer<uc16> String::ToWideCString(RobustnessFlag robust_flag) { |
| (...skipping 270 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5641 &rbb->remaining, | 5656 &rbb->remaining, |
| 5642 offset_ptr, | 5657 offset_ptr, |
| 5643 max_chars); | 5658 max_chars); |
| 5644 } else { | 5659 } else { |
| 5645 ExternalTwoByteString::cast(input)-> | 5660 ExternalTwoByteString::cast(input)-> |
| 5646 ExternalTwoByteStringReadBlockIntoBuffer(rbb, | 5661 ExternalTwoByteStringReadBlockIntoBuffer(rbb, |
| 5647 offset_ptr, | 5662 offset_ptr, |
| 5648 max_chars); | 5663 max_chars); |
| 5649 return rbb->util_buffer; | 5664 return rbb->util_buffer; |
| 5650 } | 5665 } |
| 5666 case kSlicedStringTag: | |
| 5667 return SlicedString::cast(input)->SlicedStringReadBlock(rbb, | |
| 5668 offset_ptr, | |
| 5669 max_chars); | |
| 5651 default: | 5670 default: |
| 5652 break; | 5671 break; |
| 5653 } | 5672 } |
| 5654 | 5673 |
| 5655 UNREACHABLE(); | 5674 UNREACHABLE(); |
| 5656 return 0; | 5675 return 0; |
| 5657 } | 5676 } |
| 5658 | 5677 |
| 5659 | 5678 |
| 5660 void Relocatable::PostGarbageCollectionProcessing() { | 5679 void Relocatable::PostGarbageCollectionProcessing() { |
| (...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5782 if (input->IsAsciiRepresentation()) { | 5801 if (input->IsAsciiRepresentation()) { |
| 5783 ExternalAsciiString::cast(input)-> | 5802 ExternalAsciiString::cast(input)-> |
| 5784 ExternalAsciiStringReadBlockIntoBuffer(rbb, offset_ptr, max_chars); | 5803 ExternalAsciiStringReadBlockIntoBuffer(rbb, offset_ptr, max_chars); |
| 5785 } else { | 5804 } else { |
| 5786 ExternalTwoByteString::cast(input)-> | 5805 ExternalTwoByteString::cast(input)-> |
| 5787 ExternalTwoByteStringReadBlockIntoBuffer(rbb, | 5806 ExternalTwoByteStringReadBlockIntoBuffer(rbb, |
| 5788 offset_ptr, | 5807 offset_ptr, |
| 5789 max_chars); | 5808 max_chars); |
| 5790 } | 5809 } |
| 5791 return; | 5810 return; |
| 5811 case kSlicedStringTag: | |
| 5812 SlicedString::cast(input)->SlicedStringReadBlockIntoBuffer(rbb, | |
| 5813 offset_ptr, | |
| 5814 max_chars); | |
| 5815 return; | |
| 5792 default: | 5816 default: |
| 5793 break; | 5817 break; |
| 5794 } | 5818 } |
| 5795 | 5819 |
| 5796 UNREACHABLE(); | 5820 UNREACHABLE(); |
| 5797 return; | 5821 return; |
| 5798 } | 5822 } |
| 5799 | 5823 |
| 5800 | 5824 |
| 5801 const unibrow::byte* String::ReadBlock(String* input, | 5825 const unibrow::byte* String::ReadBlock(String* input, |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5916 } else { | 5940 } else { |
| 5917 return string->Get(index); | 5941 return string->Get(index); |
| 5918 } | 5942 } |
| 5919 } | 5943 } |
| 5920 | 5944 |
| 5921 UNREACHABLE(); | 5945 UNREACHABLE(); |
| 5922 return 0; | 5946 return 0; |
| 5923 } | 5947 } |
| 5924 | 5948 |
| 5925 | 5949 |
| 5950 uint16_t SlicedString::SlicedStringGet(int index) { | |
| 5951 return parent()->Get(offset() + index); | |
| 5952 } | |
| 5953 | |
| 5954 | |
| 5955 const unibrow::byte* SlicedString::SlicedStringReadBlock( | |
| 5956 ReadBlockBuffer* buffer, unsigned* offset_ptr, unsigned chars) { | |
| 5957 unsigned offset = this->offset(); | |
| 5958 *offset_ptr += offset; | |
| 5959 const unibrow::byte* answer = String::ReadBlock(String::cast(parent()), | |
| 5960 buffer, offset_ptr, chars); | |
| 5961 *offset_ptr -= offset; | |
| 5962 return answer; | |
| 5963 } | |
| 5964 | |
| 5965 | |
| 5966 void SlicedString::SlicedStringReadBlockIntoBuffer( | |
| 5967 ReadBlockBuffer* buffer, unsigned* offset_ptr, unsigned chars) { | |
| 5968 unsigned offset = this->offset(); | |
| 5969 *offset_ptr += offset; | |
| 5970 String::ReadBlockIntoBuffer(String::cast(parent()), | |
| 5971 buffer, offset_ptr, chars); | |
| 5972 *offset_ptr -= offset; | |
| 5973 } | |
| 5974 | |
| 5926 template <typename sinkchar> | 5975 template <typename sinkchar> |
| 5927 void String::WriteToFlat(String* src, | 5976 void String::WriteToFlat(String* src, |
| 5928 sinkchar* sink, | 5977 sinkchar* sink, |
| 5929 int f, | 5978 int f, |
| 5930 int t) { | 5979 int t) { |
| 5931 String* source = src; | 5980 String* source = src; |
| 5932 int from = f; | 5981 int from = f; |
| 5933 int to = t; | 5982 int to = t; |
| 5934 while (true) { | 5983 while (true) { |
| 5935 ASSERT(0 <= from && from <= to && to <= source->length()); | 5984 ASSERT(0 <= from && from <= to && to <= source->length()); |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5983 WriteToFlat(second, | 6032 WriteToFlat(second, |
| 5984 sink + boundary - from, | 6033 sink + boundary - from, |
| 5985 0, | 6034 0, |
| 5986 to - boundary); | 6035 to - boundary); |
| 5987 to = boundary; | 6036 to = boundary; |
| 5988 } | 6037 } |
| 5989 source = first; | 6038 source = first; |
| 5990 } | 6039 } |
| 5991 break; | 6040 break; |
| 5992 } | 6041 } |
| 6042 case kAsciiStringTag | kSlicedStringTag: | |
| 6043 case kTwoByteStringTag | kSlicedStringTag: { | |
| 6044 SlicedString* slice = SlicedString::cast(source); | |
| 6045 unsigned offset = slice->offset(); | |
| 6046 WriteToFlat(slice->parent(), sink, from + offset, to + offset); | |
| 6047 return; | |
| 6048 } | |
| 5993 } | 6049 } |
| 5994 } | 6050 } |
| 5995 } | 6051 } |
| 5996 | 6052 |
| 5997 | 6053 |
| 5998 template <typename IteratorA, typename IteratorB> | 6054 template <typename IteratorA, typename IteratorB> |
| 5999 static inline bool CompareStringContents(IteratorA* ia, IteratorB* ib) { | 6055 static inline bool CompareStringContents(IteratorA* ia, IteratorB* ib) { |
| 6000 // General slow case check. We know that the ia and ib iterators | 6056 // General slow case check. We know that the ia and ib iterators |
| 6001 // have the same length. | 6057 // have the same length. |
| 6002 while (ia->has_more()) { | 6058 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; | 11994 if (break_point_objects()->IsUndefined()) return 0; |
| 11939 // Single beak point. | 11995 // Single beak point. |
| 11940 if (!break_point_objects()->IsFixedArray()) return 1; | 11996 if (!break_point_objects()->IsFixedArray()) return 1; |
| 11941 // Multiple break points. | 11997 // Multiple break points. |
| 11942 return FixedArray::cast(break_point_objects())->length(); | 11998 return FixedArray::cast(break_point_objects())->length(); |
| 11943 } | 11999 } |
| 11944 #endif | 12000 #endif |
| 11945 | 12001 |
| 11946 | 12002 |
| 11947 } } // namespace v8::internal | 12003 } } // namespace v8::internal |
| OLD | NEW |