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 2645 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2656 } | 2656 } |
2657 | 2657 |
2658 ZoneList<ReplacementPart> parts_; | 2658 ZoneList<ReplacementPart> parts_; |
2659 ZoneList<Handle<String> > replacement_substrings_; | 2659 ZoneList<Handle<String> > replacement_substrings_; |
2660 }; | 2660 }; |
2661 | 2661 |
2662 | 2662 |
2663 void CompiledReplacement::Compile(Handle<String> replacement, | 2663 void CompiledReplacement::Compile(Handle<String> replacement, |
2664 int capture_count, | 2664 int capture_count, |
2665 int subject_length) { | 2665 int subject_length) { |
2666 ASSERT(replacement->IsFlat()); | 2666 { |
2667 if (replacement->IsAsciiRepresentation()) { | |
2668 AssertNoAllocation no_alloc; | 2667 AssertNoAllocation no_alloc; |
2669 ParseReplacementPattern(&parts_, | 2668 String::FlatContent content = replacement->GetFlatContent(no_alloc); |
2670 replacement->ToAsciiVector(), | 2669 ASSERT(content.IsFlat()); |
2671 capture_count, | 2670 if (content.IsAscii()) { |
2672 subject_length); | 2671 ParseReplacementPattern(&parts_, |
2673 } else { | 2672 content.ToAsciiVector(), |
2674 ASSERT(replacement->IsTwoByteRepresentation()); | 2673 capture_count, |
2675 AssertNoAllocation no_alloc; | 2674 subject_length); |
2676 | 2675 } else { |
2677 ParseReplacementPattern(&parts_, | 2676 ASSERT(content.IsTwoByte()); |
2678 replacement->ToUC16Vector(), | 2677 ParseReplacementPattern(&parts_, |
2679 capture_count, | 2678 content.ToUC16Vector(), |
2680 subject_length); | 2679 capture_count, |
| 2680 subject_length); |
| 2681 } |
2681 } | 2682 } |
2682 Isolate* isolate = replacement->GetIsolate(); | 2683 Isolate* isolate = replacement->GetIsolate(); |
2683 // Find substrings of replacement string and create them as String objects. | 2684 // Find substrings of replacement string and create them as String objects. |
2684 int substring_index = 0; | 2685 int substring_index = 0; |
2685 for (int i = 0, n = parts_.length(); i < n; i++) { | 2686 for (int i = 0, n = parts_.length(); i < n; i++) { |
2686 int tag = parts_[i].tag; | 2687 int tag = parts_[i].tag; |
2687 if (tag <= 0) { // A replacement string slice. | 2688 if (tag <= 0) { // A replacement string slice. |
2688 int from = -tag; | 2689 int from = -tag; |
2689 int to = parts_[i].data; | 2690 int to = parts_[i].data; |
2690 replacement_substrings_.Add( | 2691 replacement_substrings_.Add( |
(...skipping 351 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3042 if (pattern_length == 0) return start_index; | 3043 if (pattern_length == 0) return start_index; |
3043 | 3044 |
3044 int subject_length = sub->length(); | 3045 int subject_length = sub->length(); |
3045 if (start_index + pattern_length > subject_length) return -1; | 3046 if (start_index + pattern_length > subject_length) return -1; |
3046 | 3047 |
3047 if (!sub->IsFlat()) FlattenString(sub); | 3048 if (!sub->IsFlat()) FlattenString(sub); |
3048 if (!pat->IsFlat()) FlattenString(pat); | 3049 if (!pat->IsFlat()) FlattenString(pat); |
3049 | 3050 |
3050 AssertNoAllocation no_heap_allocation; // ensure vectors stay valid | 3051 AssertNoAllocation no_heap_allocation; // ensure vectors stay valid |
3051 // Extract flattened substrings of cons strings before determining asciiness. | 3052 // Extract flattened substrings of cons strings before determining asciiness. |
3052 String* seq_sub = *sub; | 3053 String::FlatContent seq_sub = sub->GetFlatContent(no_heap_allocation); |
3053 if (seq_sub->IsConsString()) seq_sub = ConsString::cast(seq_sub)->first(); | 3054 String::FlatContent seq_pat = pat->GetFlatContent(no_heap_allocation); |
3054 String* seq_pat = *pat; | |
3055 if (seq_pat->IsConsString()) seq_pat = ConsString::cast(seq_pat)->first(); | |
3056 | 3055 |
3057 // dispatch on type of strings | 3056 // dispatch on type of strings |
3058 if (seq_pat->IsAsciiRepresentation()) { | 3057 if (seq_pat.IsAscii()) { |
3059 Vector<const char> pat_vector = seq_pat->ToAsciiVector(); | 3058 Vector<const char> pat_vector = seq_pat.ToAsciiVector(); |
3060 if (seq_sub->IsAsciiRepresentation()) { | 3059 if (seq_sub.IsAscii()) { |
3061 return SearchString(isolate, | 3060 return SearchString(isolate, |
3062 seq_sub->ToAsciiVector(), | 3061 seq_sub.ToAsciiVector(), |
3063 pat_vector, | 3062 pat_vector, |
3064 start_index); | 3063 start_index); |
3065 } | 3064 } |
3066 return SearchString(isolate, | 3065 return SearchString(isolate, |
3067 seq_sub->ToUC16Vector(), | 3066 seq_sub.ToUC16Vector(), |
3068 pat_vector, | 3067 pat_vector, |
3069 start_index); | 3068 start_index); |
3070 } | 3069 } |
3071 Vector<const uc16> pat_vector = seq_pat->ToUC16Vector(); | 3070 Vector<const uc16> pat_vector = seq_pat.ToUC16Vector(); |
3072 if (seq_sub->IsAsciiRepresentation()) { | 3071 if (seq_sub.IsAscii()) { |
3073 return SearchString(isolate, | 3072 return SearchString(isolate, |
3074 seq_sub->ToAsciiVector(), | 3073 seq_sub.ToAsciiVector(), |
3075 pat_vector, | 3074 pat_vector, |
3076 start_index); | 3075 start_index); |
3077 } | 3076 } |
3078 return SearchString(isolate, | 3077 return SearchString(isolate, |
3079 seq_sub->ToUC16Vector(), | 3078 seq_sub.ToUC16Vector(), |
3080 pat_vector, | 3079 pat_vector, |
3081 start_index); | 3080 start_index); |
3082 } | 3081 } |
3083 | 3082 |
3084 | 3083 |
3085 RUNTIME_FUNCTION(MaybeObject*, Runtime_StringIndexOf) { | 3084 RUNTIME_FUNCTION(MaybeObject*, Runtime_StringIndexOf) { |
3086 HandleScope scope(isolate); // create a new handle scope | 3085 HandleScope scope(isolate); // create a new handle scope |
3087 ASSERT(args.length() == 3); | 3086 ASSERT(args.length() == 3); |
3088 | 3087 |
3089 CONVERT_ARG_CHECKED(String, sub, 0); | 3088 CONVERT_ARG_CHECKED(String, sub, 0); |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3154 | 3153 |
3155 if (pat_length == 0) { | 3154 if (pat_length == 0) { |
3156 return Smi::FromInt(start_index); | 3155 return Smi::FromInt(start_index); |
3157 } | 3156 } |
3158 | 3157 |
3159 if (!sub->IsFlat()) FlattenString(sub); | 3158 if (!sub->IsFlat()) FlattenString(sub); |
3160 if (!pat->IsFlat()) FlattenString(pat); | 3159 if (!pat->IsFlat()) FlattenString(pat); |
3161 | 3160 |
3162 int position = -1; | 3161 int position = -1; |
3163 AssertNoAllocation no_heap_allocation; // ensure vectors stay valid | 3162 AssertNoAllocation no_heap_allocation; // ensure vectors stay valid |
3164 // Extract flattened substrings of cons strings before determining asciiness. | |
3165 String* seq_sub = *sub; | |
3166 if (seq_sub->IsConsString()) seq_sub = ConsString::cast(seq_sub)->first(); | |
3167 String* seq_pat = *pat; | |
3168 if (seq_pat->IsConsString()) seq_pat = ConsString::cast(seq_pat)->first(); | |
3169 | 3163 |
3170 if (seq_pat->IsAsciiRepresentation()) { | 3164 String::FlatContent sub_content = sub->GetFlatContent(no_heap_allocation); |
3171 Vector<const char> pat_vector = seq_pat->ToAsciiVector(); | 3165 String::FlatContent pat_content = pat->GetFlatContent(no_heap_allocation); |
3172 if (seq_sub->IsAsciiRepresentation()) { | 3166 |
3173 position = StringMatchBackwards(seq_sub->ToAsciiVector(), | 3167 if (pat_content.IsAscii()) { |
| 3168 Vector<const char> pat_vector = pat_content.ToAsciiVector(); |
| 3169 if (sub_content.IsAscii()) { |
| 3170 position = StringMatchBackwards(sub_content.ToAsciiVector(), |
3174 pat_vector, | 3171 pat_vector, |
3175 start_index); | 3172 start_index); |
3176 } else { | 3173 } else { |
3177 position = StringMatchBackwards(seq_sub->ToUC16Vector(), | 3174 position = StringMatchBackwards(sub_content.ToUC16Vector(), |
3178 pat_vector, | 3175 pat_vector, |
3179 start_index); | 3176 start_index); |
3180 } | 3177 } |
3181 } else { | 3178 } else { |
3182 Vector<const uc16> pat_vector = seq_pat->ToUC16Vector(); | 3179 Vector<const uc16> pat_vector = pat_content.ToUC16Vector(); |
3183 if (seq_sub->IsAsciiRepresentation()) { | 3180 if (sub_content.IsAscii()) { |
3184 position = StringMatchBackwards(seq_sub->ToAsciiVector(), | 3181 position = StringMatchBackwards(sub_content.ToAsciiVector(), |
3185 pat_vector, | 3182 pat_vector, |
3186 start_index); | 3183 start_index); |
3187 } else { | 3184 } else { |
3188 position = StringMatchBackwards(seq_sub->ToUC16Vector(), | 3185 position = StringMatchBackwards(sub_content.ToUC16Vector(), |
3189 pat_vector, | 3186 pat_vector, |
3190 start_index); | 3187 start_index); |
3191 } | 3188 } |
3192 } | 3189 } |
3193 | 3190 |
3194 return Smi::FromInt(position); | 3191 return Smi::FromInt(position); |
3195 } | 3192 } |
3196 | 3193 |
3197 | 3194 |
3198 RUNTIME_FUNCTION(MaybeObject*, Runtime_StringLocaleCompare) { | 3195 RUNTIME_FUNCTION(MaybeObject*, Runtime_StringLocaleCompare) { |
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3396 FixedArrayBuilder* builder) { | 3393 FixedArrayBuilder* builder) { |
3397 ASSERT(subject->IsFlat()); | 3394 ASSERT(subject->IsFlat()); |
3398 ASSERT(pattern->IsFlat()); | 3395 ASSERT(pattern->IsFlat()); |
3399 | 3396 |
3400 // Treating as if a previous match was before first character. | 3397 // Treating as if a previous match was before first character. |
3401 int match_pos = -pattern->length(); | 3398 int match_pos = -pattern->length(); |
3402 | 3399 |
3403 for (;;) { // Break when search complete. | 3400 for (;;) { // Break when search complete. |
3404 builder->EnsureCapacity(kMaxBuilderEntriesPerRegExpMatch); | 3401 builder->EnsureCapacity(kMaxBuilderEntriesPerRegExpMatch); |
3405 AssertNoAllocation no_gc; | 3402 AssertNoAllocation no_gc; |
3406 if (subject->IsAsciiRepresentation()) { | 3403 String::FlatContent subject_content = subject->GetFlatContent(no_gc); |
3407 Vector<const char> subject_vector = subject->ToAsciiVector(); | 3404 String::FlatContent pattern_content = pattern->GetFlatContent(no_gc); |
3408 if (pattern->IsAsciiRepresentation()) { | 3405 if (subject_content.IsAscii()) { |
| 3406 Vector<const char> subject_vector = subject_content.ToAsciiVector(); |
| 3407 if (pattern_content.IsAscii()) { |
3409 if (SearchStringMultiple(isolate, | 3408 if (SearchStringMultiple(isolate, |
3410 subject_vector, | 3409 subject_vector, |
3411 pattern->ToAsciiVector(), | 3410 pattern_content.ToAsciiVector(), |
3412 *pattern, | 3411 *pattern, |
3413 builder, | 3412 builder, |
3414 &match_pos)) break; | 3413 &match_pos)) break; |
3415 } else { | 3414 } else { |
3416 if (SearchStringMultiple(isolate, | 3415 if (SearchStringMultiple(isolate, |
3417 subject_vector, | 3416 subject_vector, |
3418 pattern->ToUC16Vector(), | 3417 pattern_content.ToUC16Vector(), |
3419 *pattern, | 3418 *pattern, |
3420 builder, | 3419 builder, |
3421 &match_pos)) break; | 3420 &match_pos)) break; |
3422 } | 3421 } |
3423 } else { | 3422 } else { |
3424 Vector<const uc16> subject_vector = subject->ToUC16Vector(); | 3423 Vector<const uc16> subject_vector = subject_content.ToUC16Vector(); |
3425 if (pattern->IsAsciiRepresentation()) { | 3424 if (pattern_content.IsAscii()) { |
3426 if (SearchStringMultiple(isolate, | 3425 if (SearchStringMultiple(isolate, |
3427 subject_vector, | 3426 subject_vector, |
3428 pattern->ToAsciiVector(), | 3427 pattern_content.ToAsciiVector(), |
3429 *pattern, | 3428 *pattern, |
3430 builder, | 3429 builder, |
3431 &match_pos)) break; | 3430 &match_pos)) break; |
3432 } else { | 3431 } else { |
3433 if (SearchStringMultiple(isolate, | 3432 if (SearchStringMultiple(isolate, |
3434 subject_vector, | 3433 subject_vector, |
3435 pattern->ToUC16Vector(), | 3434 pattern_content.ToUC16Vector(), |
3436 *pattern, | 3435 *pattern, |
3437 builder, | 3436 builder, |
3438 &match_pos)) break; | 3437 &match_pos)) break; |
3439 } | 3438 } |
3440 } | 3439 } |
3441 } | 3440 } |
3442 | 3441 |
3443 if (match_pos >= 0) { | 3442 if (match_pos >= 0) { |
3444 SetLastMatchInfoNoCaptures(subject, | 3443 SetLastMatchInfoNoCaptures(subject, |
3445 last_match_info, | 3444 last_match_info, |
(...skipping 1967 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5413 CONVERT_CHECKED(String, str, args[0]); | 5412 CONVERT_CHECKED(String, str, args[0]); |
5414 if (!str->IsFlat()) { | 5413 if (!str->IsFlat()) { |
5415 MaybeObject* try_flatten = str->TryFlatten(); | 5414 MaybeObject* try_flatten = str->TryFlatten(); |
5416 Object* flat; | 5415 Object* flat; |
5417 if (!try_flatten->ToObject(&flat)) { | 5416 if (!try_flatten->ToObject(&flat)) { |
5418 return try_flatten; | 5417 return try_flatten; |
5419 } | 5418 } |
5420 str = String::cast(flat); | 5419 str = String::cast(flat); |
5421 ASSERT(str->IsFlat()); | 5420 ASSERT(str->IsFlat()); |
5422 } | 5421 } |
5423 if (str->IsTwoByteRepresentation()) { | 5422 AssertNoAllocation no_alloc; |
| 5423 String::FlatContent flat = str->GetFlatContent(no_alloc); |
| 5424 ASSERT(flat.IsFlat()); |
| 5425 if (flat.IsTwoByte()) { |
5424 return QuoteJsonString<uc16, SeqTwoByteString, false>(isolate, | 5426 return QuoteJsonString<uc16, SeqTwoByteString, false>(isolate, |
5425 str->ToUC16Vector()); | 5427 flat.ToUC16Vector()); |
5426 } else { | 5428 } else { |
5427 return QuoteJsonString<char, SeqAsciiString, false>(isolate, | 5429 return QuoteJsonString<char, SeqAsciiString, false>(isolate, |
5428 str->ToAsciiVector()); | 5430 flat.ToAsciiVector()); |
5429 } | 5431 } |
5430 } | 5432 } |
5431 | 5433 |
5432 | 5434 |
5433 RUNTIME_FUNCTION(MaybeObject*, Runtime_QuoteJSONStringComma) { | 5435 RUNTIME_FUNCTION(MaybeObject*, Runtime_QuoteJSONStringComma) { |
5434 NoHandleAllocation ha; | 5436 NoHandleAllocation ha; |
5435 CONVERT_CHECKED(String, str, args[0]); | 5437 CONVERT_CHECKED(String, str, args[0]); |
5436 if (!str->IsFlat()) { | 5438 if (!str->IsFlat()) { |
5437 MaybeObject* try_flatten = str->TryFlatten(); | 5439 MaybeObject* try_flatten = str->TryFlatten(); |
5438 Object* flat; | 5440 Object* flat; |
5439 if (!try_flatten->ToObject(&flat)) { | 5441 if (!try_flatten->ToObject(&flat)) { |
5440 return try_flatten; | 5442 return try_flatten; |
5441 } | 5443 } |
5442 str = String::cast(flat); | 5444 str = String::cast(flat); |
5443 ASSERT(str->IsFlat()); | 5445 ASSERT(str->IsFlat()); |
5444 } | 5446 } |
5445 if (str->IsTwoByteRepresentation()) { | 5447 AssertNoAllocation no_alloc; |
| 5448 String::FlatContent flat = str->GetFlatContent(no_alloc); |
| 5449 if (flat.IsTwoByte()) { |
5446 return QuoteJsonString<uc16, SeqTwoByteString, true>(isolate, | 5450 return QuoteJsonString<uc16, SeqTwoByteString, true>(isolate, |
5447 str->ToUC16Vector()); | 5451 flat.ToUC16Vector()); |
5448 } else { | 5452 } else { |
5449 return QuoteJsonString<char, SeqAsciiString, true>(isolate, | 5453 return QuoteJsonString<char, SeqAsciiString, true>(isolate, |
5450 str->ToAsciiVector()); | 5454 flat.ToAsciiVector()); |
5451 } | 5455 } |
5452 } | 5456 } |
5453 | 5457 |
5454 | 5458 |
5455 template <typename Char, typename StringType> | 5459 template <typename Char, typename StringType> |
5456 static MaybeObject* QuoteJsonStringArray(Isolate* isolate, | 5460 static MaybeObject* QuoteJsonStringArray(Isolate* isolate, |
5457 FixedArray* array, | 5461 FixedArray* array, |
5458 int worst_case_length) { | 5462 int worst_case_length) { |
5459 int length = array->length(); | 5463 int length = array->length(); |
5460 | 5464 |
(...skipping 14 matching lines...) Expand all Loading... |
5475 StringType* new_string = StringType::cast(new_object); | 5479 StringType* new_string = StringType::cast(new_object); |
5476 ASSERT(isolate->heap()->new_space()->Contains(new_string)); | 5480 ASSERT(isolate->heap()->new_space()->Contains(new_string)); |
5477 | 5481 |
5478 STATIC_ASSERT(SeqTwoByteString::kHeaderSize == SeqAsciiString::kHeaderSize); | 5482 STATIC_ASSERT(SeqTwoByteString::kHeaderSize == SeqAsciiString::kHeaderSize); |
5479 Char* write_cursor = reinterpret_cast<Char*>( | 5483 Char* write_cursor = reinterpret_cast<Char*>( |
5480 new_string->address() + SeqAsciiString::kHeaderSize); | 5484 new_string->address() + SeqAsciiString::kHeaderSize); |
5481 *(write_cursor++) = '['; | 5485 *(write_cursor++) = '['; |
5482 for (int i = 0; i < length; i++) { | 5486 for (int i = 0; i < length; i++) { |
5483 if (i != 0) *(write_cursor++) = ','; | 5487 if (i != 0) *(write_cursor++) = ','; |
5484 String* str = String::cast(array->get(i)); | 5488 String* str = String::cast(array->get(i)); |
5485 if (str->IsTwoByteRepresentation()) { | 5489 String::FlatContent content = str->GetFlatContent(no_gc); |
| 5490 ASSERT(content.IsFlat()); |
| 5491 if (content.IsTwoByte()) { |
5486 write_cursor = WriteQuoteJsonString<Char, uc16>(isolate, | 5492 write_cursor = WriteQuoteJsonString<Char, uc16>(isolate, |
5487 write_cursor, | 5493 write_cursor, |
5488 str->ToUC16Vector()); | 5494 content.ToUC16Vector()); |
5489 } else { | 5495 } else { |
5490 write_cursor = WriteQuoteJsonString<Char, char>(isolate, | 5496 write_cursor = WriteQuoteJsonString<Char, char>(isolate, |
5491 write_cursor, | 5497 write_cursor, |
5492 str->ToAsciiVector()); | 5498 content.ToAsciiVector()); |
5493 } | 5499 } |
5494 } | 5500 } |
5495 *(write_cursor++) = ']'; | 5501 *(write_cursor++) = ']'; |
5496 | 5502 |
5497 int final_length = static_cast<int>( | 5503 int final_length = static_cast<int>( |
5498 write_cursor - reinterpret_cast<Char*>( | 5504 write_cursor - reinterpret_cast<Char*>( |
5499 new_string->address() + SeqAsciiString::kHeaderSize)); | 5505 new_string->address() + SeqAsciiString::kHeaderSize)); |
5500 isolate->heap()->new_space()-> | 5506 isolate->heap()->new_space()-> |
5501 template ShrinkStringAtAllocationBoundary<StringType>( | 5507 template ShrinkStringAtAllocationBoundary<StringType>( |
5502 new_string, final_length); | 5508 new_string, final_length); |
(...skipping 458 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5961 | 5967 |
5962 ZoneScope scope(isolate, DELETE_ON_EXIT); | 5968 ZoneScope scope(isolate, DELETE_ON_EXIT); |
5963 | 5969 |
5964 // Find (up to limit) indices of separator and end-of-string in subject | 5970 // Find (up to limit) indices of separator and end-of-string in subject |
5965 int initial_capacity = Min<uint32_t>(kMaxInitialListCapacity, limit); | 5971 int initial_capacity = Min<uint32_t>(kMaxInitialListCapacity, limit); |
5966 ZoneList<int> indices(initial_capacity); | 5972 ZoneList<int> indices(initial_capacity); |
5967 if (!pattern->IsFlat()) FlattenString(pattern); | 5973 if (!pattern->IsFlat()) FlattenString(pattern); |
5968 | 5974 |
5969 // No allocation block. | 5975 // No allocation block. |
5970 { | 5976 { |
5971 AssertNoAllocation nogc; | 5977 AssertNoAllocation no_gc; |
5972 if (subject->IsAsciiRepresentation()) { | 5978 String::FlatContent subject_content = subject->GetFlatContent(no_gc); |
5973 Vector<const char> subject_vector = subject->ToAsciiVector(); | 5979 String::FlatContent pattern_content = pattern->GetFlatContent(no_gc); |
5974 if (pattern->IsAsciiRepresentation()) { | 5980 ASSERT(subject_content.IsFlat()); |
5975 Vector<const char> pattern_vector = pattern->ToAsciiVector(); | 5981 ASSERT(pattern_content.IsFlat()); |
| 5982 if (subject_content.IsAscii()) { |
| 5983 Vector<const char> subject_vector = subject_content.ToAsciiVector(); |
| 5984 if (pattern_content.IsAscii()) { |
| 5985 Vector<const char> pattern_vector = pattern_content.ToAsciiVector(); |
5976 if (pattern_vector.length() == 1) { | 5986 if (pattern_vector.length() == 1) { |
5977 FindAsciiStringIndices(subject_vector, | 5987 FindAsciiStringIndices(subject_vector, |
5978 pattern_vector[0], | 5988 pattern_vector[0], |
5979 &indices, | 5989 &indices, |
5980 limit); | 5990 limit); |
5981 } else { | 5991 } else { |
5982 FindStringIndices(isolate, | 5992 FindStringIndices(isolate, |
5983 subject_vector, | 5993 subject_vector, |
5984 pattern_vector, | 5994 pattern_vector, |
5985 &indices, | 5995 &indices, |
5986 limit); | 5996 limit); |
5987 } | 5997 } |
5988 } else { | 5998 } else { |
5989 FindStringIndices(isolate, | 5999 FindStringIndices(isolate, |
5990 subject_vector, | 6000 subject_vector, |
5991 pattern->ToUC16Vector(), | 6001 pattern_content.ToUC16Vector(), |
5992 &indices, | 6002 &indices, |
5993 limit); | 6003 limit); |
5994 } | 6004 } |
5995 } else { | 6005 } else { |
5996 Vector<const uc16> subject_vector = subject->ToUC16Vector(); | 6006 Vector<const uc16> subject_vector = subject_content.ToUC16Vector(); |
5997 if (pattern->IsAsciiRepresentation()) { | 6007 if (pattern->IsAsciiRepresentation()) { |
5998 FindStringIndices(isolate, | 6008 FindStringIndices(isolate, |
5999 subject_vector, | 6009 subject_vector, |
6000 pattern->ToAsciiVector(), | 6010 pattern_content.ToAsciiVector(), |
6001 &indices, | 6011 &indices, |
6002 limit); | 6012 limit); |
6003 } else { | 6013 } else { |
6004 FindStringIndices(isolate, | 6014 FindStringIndices(isolate, |
6005 subject_vector, | 6015 subject_vector, |
6006 pattern->ToUC16Vector(), | 6016 pattern_content.ToUC16Vector(), |
6007 &indices, | 6017 &indices, |
6008 limit); | 6018 limit); |
6009 } | 6019 } |
6010 } | 6020 } |
6011 } | 6021 } |
6012 | 6022 |
6013 if (static_cast<uint32_t>(indices.length()) < limit) { | 6023 if (static_cast<uint32_t>(indices.length()) < limit) { |
6014 indices.Add(subject_length); | 6024 indices.Add(subject_length); |
6015 } | 6025 } |
6016 | 6026 |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6078 | 6088 |
6079 | 6089 |
6080 // Converts a String to JSArray. | 6090 // Converts a String to JSArray. |
6081 // For example, "foo" => ["f", "o", "o"]. | 6091 // For example, "foo" => ["f", "o", "o"]. |
6082 RUNTIME_FUNCTION(MaybeObject*, Runtime_StringToArray) { | 6092 RUNTIME_FUNCTION(MaybeObject*, Runtime_StringToArray) { |
6083 HandleScope scope(isolate); | 6093 HandleScope scope(isolate); |
6084 ASSERT(args.length() == 2); | 6094 ASSERT(args.length() == 2); |
6085 CONVERT_ARG_CHECKED(String, s, 0); | 6095 CONVERT_ARG_CHECKED(String, s, 0); |
6086 CONVERT_NUMBER_CHECKED(uint32_t, limit, Uint32, args[1]); | 6096 CONVERT_NUMBER_CHECKED(uint32_t, limit, Uint32, args[1]); |
6087 | 6097 |
6088 s->TryFlatten(); | 6098 s = FlattenGetString(s); |
6089 const int length = static_cast<int>(Min<uint32_t>(s->length(), limit)); | 6099 const int length = static_cast<int>(Min<uint32_t>(s->length(), limit)); |
6090 | 6100 |
6091 Handle<FixedArray> elements; | 6101 Handle<FixedArray> elements; |
| 6102 int position = 0; |
6092 if (s->IsFlat() && s->IsAsciiRepresentation()) { | 6103 if (s->IsFlat() && s->IsAsciiRepresentation()) { |
| 6104 // Try using cached chars where possible. |
6093 Object* obj; | 6105 Object* obj; |
6094 { MaybeObject* maybe_obj = | 6106 { MaybeObject* maybe_obj = |
6095 isolate->heap()->AllocateUninitializedFixedArray(length); | 6107 isolate->heap()->AllocateUninitializedFixedArray(length); |
6096 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 6108 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
6097 } | 6109 } |
| 6110 AssertNoAllocation no_alloc; |
6098 elements = Handle<FixedArray>(FixedArray::cast(obj), isolate); | 6111 elements = Handle<FixedArray>(FixedArray::cast(obj), isolate); |
6099 | 6112 String::FlatContent content = s->GetFlatContent(no_alloc); |
6100 Vector<const char> chars = s->ToAsciiVector(); | 6113 if (content.IsAscii()) { |
6101 // Note, this will initialize all elements (not only the prefix) | 6114 Vector<const char> chars = content.ToAsciiVector(); |
6102 // to prevent GC from seeing partially initialized array. | 6115 // Note, this will initialize all elements (not only the prefix) |
6103 int num_copied_from_cache = CopyCachedAsciiCharsToArray(isolate->heap(), | 6116 // to prevent GC from seeing partially initialized array. |
6104 chars.start(), | 6117 position = CopyCachedAsciiCharsToArray(isolate->heap(), |
6105 *elements, | 6118 chars.start(), |
6106 length); | 6119 *elements, |
6107 | 6120 length); |
6108 for (int i = num_copied_from_cache; i < length; ++i) { | 6121 } else { |
6109 Handle<Object> str = LookupSingleCharacterStringFromCode(chars[i]); | 6122 MemsetPointer(elements->data_start(), |
6110 elements->set(i, *str); | 6123 isolate->heap()->undefined_value(), |
| 6124 length); |
6111 } | 6125 } |
6112 } else { | 6126 } else { |
6113 elements = isolate->factory()->NewFixedArray(length); | 6127 elements = isolate->factory()->NewFixedArray(length); |
6114 for (int i = 0; i < length; ++i) { | 6128 } |
6115 Handle<Object> str = LookupSingleCharacterStringFromCode(s->Get(i)); | 6129 for (int i = position; i < length; ++i) { |
6116 elements->set(i, *str); | 6130 Handle<Object> str = LookupSingleCharacterStringFromCode(s->Get(i)); |
6117 } | 6131 elements->set(i, *str); |
6118 } | 6132 } |
6119 | 6133 |
6120 #ifdef DEBUG | 6134 #ifdef DEBUG |
6121 for (int i = 0; i < length; ++i) { | 6135 for (int i = 0; i < length; ++i) { |
6122 ASSERT(String::cast(elements->get(i))->length() == 1); | 6136 ASSERT(String::cast(elements->get(i))->length() == 1); |
6123 } | 6137 } |
6124 #endif | 6138 #endif |
6125 | 6139 |
6126 return *isolate->factory()->NewJSArrayWithElements(elements); | 6140 return *isolate->factory()->NewJSArrayWithElements(elements); |
6127 } | 6141 } |
(...skipping 781 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6909 // x is (non-trivial) prefix of y: | 6923 // x is (non-trivial) prefix of y: |
6910 if (bufy.has_more()) return Smi::FromInt(LESS); | 6924 if (bufy.has_more()) return Smi::FromInt(LESS); |
6911 // y is prefix of x: | 6925 // y is prefix of x: |
6912 return Smi::FromInt(bufx.has_more() ? GREATER : EQUAL); | 6926 return Smi::FromInt(bufx.has_more() ? GREATER : EQUAL); |
6913 } | 6927 } |
6914 | 6928 |
6915 | 6929 |
6916 static Object* FlatStringCompare(String* x, String* y) { | 6930 static Object* FlatStringCompare(String* x, String* y) { |
6917 ASSERT(x->IsFlat()); | 6931 ASSERT(x->IsFlat()); |
6918 ASSERT(y->IsFlat()); | 6932 ASSERT(y->IsFlat()); |
| 6933 AssertNoAllocation no_alloc; |
6919 Object* equal_prefix_result = Smi::FromInt(EQUAL); | 6934 Object* equal_prefix_result = Smi::FromInt(EQUAL); |
6920 int prefix_length = x->length(); | 6935 int prefix_length = x->length(); |
6921 if (y->length() < prefix_length) { | 6936 if (y->length() < prefix_length) { |
6922 prefix_length = y->length(); | 6937 prefix_length = y->length(); |
6923 equal_prefix_result = Smi::FromInt(GREATER); | 6938 equal_prefix_result = Smi::FromInt(GREATER); |
6924 } else if (y->length() > prefix_length) { | 6939 } else if (y->length() > prefix_length) { |
6925 equal_prefix_result = Smi::FromInt(LESS); | 6940 equal_prefix_result = Smi::FromInt(LESS); |
6926 } | 6941 } |
6927 int r; | 6942 int r; |
6928 if (x->IsAsciiRepresentation()) { | 6943 String::FlatContent x_content = x->GetFlatContent(no_alloc); |
6929 Vector<const char> x_chars = x->ToAsciiVector(); | 6944 String::FlatContent y_content = y->GetFlatContent(no_alloc); |
6930 if (y->IsAsciiRepresentation()) { | 6945 if (x_content.IsAscii()) { |
6931 Vector<const char> y_chars = y->ToAsciiVector(); | 6946 Vector<const char> x_chars = x_content.ToAsciiVector(); |
| 6947 if (y_content.IsAscii()) { |
| 6948 Vector<const char> y_chars = y_content.ToAsciiVector(); |
6932 r = CompareChars(x_chars.start(), y_chars.start(), prefix_length); | 6949 r = CompareChars(x_chars.start(), y_chars.start(), prefix_length); |
6933 } else { | 6950 } else { |
6934 Vector<const uc16> y_chars = y->ToUC16Vector(); | 6951 Vector<const uc16> y_chars = y_content.ToUC16Vector(); |
6935 r = CompareChars(x_chars.start(), y_chars.start(), prefix_length); | 6952 r = CompareChars(x_chars.start(), y_chars.start(), prefix_length); |
6936 } | 6953 } |
6937 } else { | 6954 } else { |
6938 Vector<const uc16> x_chars = x->ToUC16Vector(); | 6955 Vector<const uc16> x_chars = x_content.ToUC16Vector(); |
6939 if (y->IsAsciiRepresentation()) { | 6956 if (y_content.IsAscii()) { |
6940 Vector<const char> y_chars = y->ToAsciiVector(); | 6957 Vector<const char> y_chars = y_content.ToAsciiVector(); |
6941 r = CompareChars(x_chars.start(), y_chars.start(), prefix_length); | 6958 r = CompareChars(x_chars.start(), y_chars.start(), prefix_length); |
6942 } else { | 6959 } else { |
6943 Vector<const uc16> y_chars = y->ToUC16Vector(); | 6960 Vector<const uc16> y_chars = y_content.ToUC16Vector(); |
6944 r = CompareChars(x_chars.start(), y_chars.start(), prefix_length); | 6961 r = CompareChars(x_chars.start(), y_chars.start(), prefix_length); |
6945 } | 6962 } |
6946 } | 6963 } |
6947 Object* result; | 6964 Object* result; |
6948 if (r == 0) { | 6965 if (r == 0) { |
6949 result = equal_prefix_result; | 6966 result = equal_prefix_result; |
6950 } else { | 6967 } else { |
6951 result = (r < 0) ? Smi::FromInt(LESS) : Smi::FromInt(GREATER); | 6968 result = (r < 0) ? Smi::FromInt(LESS) : Smi::FromInt(GREATER); |
6952 } | 6969 } |
6953 ASSERT(result == | 6970 ASSERT(result == |
(...skipping 1860 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8814 FlattenString(str); | 8831 FlattenString(str); |
8815 | 8832 |
8816 CONVERT_ARG_CHECKED(JSArray, output, 1); | 8833 CONVERT_ARG_CHECKED(JSArray, output, 1); |
8817 RUNTIME_ASSERT(output->HasFastElements()); | 8834 RUNTIME_ASSERT(output->HasFastElements()); |
8818 | 8835 |
8819 AssertNoAllocation no_allocation; | 8836 AssertNoAllocation no_allocation; |
8820 | 8837 |
8821 FixedArray* output_array = FixedArray::cast(output->elements()); | 8838 FixedArray* output_array = FixedArray::cast(output->elements()); |
8822 RUNTIME_ASSERT(output_array->length() >= DateParser::OUTPUT_SIZE); | 8839 RUNTIME_ASSERT(output_array->length() >= DateParser::OUTPUT_SIZE); |
8823 bool result; | 8840 bool result; |
8824 if (str->IsAsciiRepresentation()) { | 8841 String::FlatContent str_content = str->GetFlatContent(no_allocation); |
8825 result = DateParser::Parse(str->ToAsciiVector(), | 8842 if (str_content.IsAscii()) { |
| 8843 result = DateParser::Parse(str_content.ToAsciiVector(), |
8826 output_array, | 8844 output_array, |
8827 isolate->unicode_cache()); | 8845 isolate->unicode_cache()); |
8828 } else { | 8846 } else { |
8829 ASSERT(str->IsTwoByteRepresentation()); | 8847 ASSERT(str_content.IsTwoByte()); |
8830 result = DateParser::Parse(str->ToUC16Vector(), | 8848 result = DateParser::Parse(str_content.ToUC16Vector(), |
8831 output_array, | 8849 output_array, |
8832 isolate->unicode_cache()); | 8850 isolate->unicode_cache()); |
8833 } | 8851 } |
8834 | 8852 |
8835 if (result) { | 8853 if (result) { |
8836 return *output; | 8854 return *output; |
8837 } else { | 8855 } else { |
8838 return isolate->heap()->null_value(); | 8856 return isolate->heap()->null_value(); |
8839 } | 8857 } |
8840 } | 8858 } |
(...skipping 3957 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12798 #undef ADD_ENTRY | 12816 #undef ADD_ENTRY |
12799 ASSERT_EQ(index, entry_count); | 12817 ASSERT_EQ(index, entry_count); |
12800 Handle<JSArray> result = factory->NewJSArrayWithElements(elements); | 12818 Handle<JSArray> result = factory->NewJSArrayWithElements(elements); |
12801 return *result; | 12819 return *result; |
12802 } | 12820 } |
12803 #endif | 12821 #endif |
12804 | 12822 |
12805 | 12823 |
12806 RUNTIME_FUNCTION(MaybeObject*, Runtime_Log) { | 12824 RUNTIME_FUNCTION(MaybeObject*, Runtime_Log) { |
12807 ASSERT(args.length() == 2); | 12825 ASSERT(args.length() == 2); |
| 12826 AssertNoAllocation no_alloc; |
12808 CONVERT_CHECKED(String, format, args[0]); | 12827 CONVERT_CHECKED(String, format, args[0]); |
12809 CONVERT_CHECKED(JSArray, elms, args[1]); | 12828 CONVERT_CHECKED(JSArray, elms, args[1]); |
12810 Vector<const char> chars = format->ToAsciiVector(); | 12829 String::FlatContent format_content = format->GetFlatContent(no_alloc); |
| 12830 RUNTIME_ASSERT(format_content.IsAscii()); |
| 12831 Vector<const char> chars = format_content.ToAsciiVector(); |
12811 LOGGER->LogRuntime(chars, elms); | 12832 LOGGER->LogRuntime(chars, elms); |
12812 return isolate->heap()->undefined_value(); | 12833 return isolate->heap()->undefined_value(); |
12813 } | 12834 } |
12814 | 12835 |
12815 | 12836 |
12816 RUNTIME_FUNCTION(MaybeObject*, Runtime_IS_VAR) { | 12837 RUNTIME_FUNCTION(MaybeObject*, Runtime_IS_VAR) { |
12817 UNREACHABLE(); // implemented as macro in the parser | 12838 UNREACHABLE(); // implemented as macro in the parser |
12818 return NULL; | 12839 return NULL; |
12819 } | 12840 } |
12820 | 12841 |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12914 } else { | 12935 } else { |
12915 // Handle last resort GC and make sure to allow future allocations | 12936 // Handle last resort GC and make sure to allow future allocations |
12916 // to grow the heap without causing GCs (if possible). | 12937 // to grow the heap without causing GCs (if possible). |
12917 isolate->counters()->gc_last_resort_from_js()->Increment(); | 12938 isolate->counters()->gc_last_resort_from_js()->Increment(); |
12918 isolate->heap()->CollectAllGarbage(false); | 12939 isolate->heap()->CollectAllGarbage(false); |
12919 } | 12940 } |
12920 } | 12941 } |
12921 | 12942 |
12922 | 12943 |
12923 } } // namespace v8::internal | 12944 } } // namespace v8::internal |
OLD | NEW |