| 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 |