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

Side by Side Diff: src/runtime.cc

Issue 3276004: Simplify code by removing special-casing for single-character patterns (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 10 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2006-2009 the V8 project authors. All rights reserved. 1 // Copyright 2006-2009 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 2797 matching lines...) Expand 10 before | Expand all | Expand 10 after
2808 shift = gs_shift; 2808 shift = gs_shift;
2809 } 2809 }
2810 idx += shift; 2810 idx += shift;
2811 } 2811 }
2812 } 2812 }
2813 2813
2814 return -1; 2814 return -1;
2815 } 2815 }
2816 2816
2817 2817
2818 template <typename schar>
2819 static inline int SingleCharIndexOf(Vector<const schar> string,
2820 schar pattern_char,
2821 int start_index) {
2822 if (sizeof(schar) == 1) {
2823 const schar* pos = reinterpret_cast<const schar*>(
2824 memchr(string.start() + start_index,
2825 pattern_char,
2826 string.length() - start_index));
2827 if (pos == NULL) return -1;
2828 return static_cast<int>(pos - string.start());
2829 }
2830 for (int i = start_index, n = string.length(); i < n; i++) {
2831 if (pattern_char == string[i]) {
2832 return i;
2833 }
2834 }
2835 return -1;
2836 }
2837
2838
2839 template <typename schar>
2840 static int SingleCharLastIndexOf(Vector<const schar> string,
2841 schar pattern_char,
2842 int start_index) {
2843 for (int i = start_index; i >= 0; i--) {
2844 if (pattern_char == string[i]) {
2845 return i;
2846 }
2847 }
2848 return -1;
2849 }
2850
2851
2852 // Trivial string search for shorter strings. 2818 // Trivial string search for shorter strings.
2853 // On return, if "complete" is set to true, the return value is the 2819 // On return, if "complete" is set to true, the return value is the
2854 // final result of searching for the patter in the subject. 2820 // final result of searching for the patter in the subject.
2855 // If "complete" is set to false, the return value is the index where 2821 // If "complete" is set to false, the return value is the index where
2856 // further checking should start, i.e., it's guaranteed that the pattern 2822 // further checking should start, i.e., it's guaranteed that the pattern
2857 // does not occur at a position prior to the returned index. 2823 // does not occur at a position prior to the returned index.
2858 template <typename pchar, typename schar> 2824 template <typename pchar, typename schar>
2859 static int SimpleIndexOf(Vector<const schar> subject, 2825 static int SimpleIndexOf(Vector<const schar> subject,
2860 Vector<const pchar> pattern, 2826 Vector<const pchar> pattern,
2861 int idx, 2827 int idx,
2862 bool* complete) { 2828 bool* complete) {
2829 ASSERT(pattern.length() > 1);
2863 // Badness is a count of how much work we have done. When we have 2830 // Badness is a count of how much work we have done. When we have
2864 // done enough work we decide it's probably worth switching to a better 2831 // done enough work we decide it's probably worth switching to a better
2865 // algorithm. 2832 // algorithm.
2866 int badness = -10 - (pattern.length() << 2); 2833 int badness = -10 - (pattern.length() << 2);
2867 2834
2868 // We know our pattern is at least 2 characters, we cache the first so 2835 // We know our pattern is at least 2 characters, we cache the first so
2869 // the common case of the first character not matching is faster. 2836 // the common case of the first character not matching is faster.
2870 pchar pattern_first_char = pattern[0]; 2837 pchar pattern_first_char = pattern[0];
2871 for (int i = idx, n = subject.length() - pattern.length(); i <= n; i++) { 2838 for (int i = idx, n = subject.length() - pattern.length(); i <= n; i++) {
2872 badness++; 2839 badness++;
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
2915 const schar* pos = reinterpret_cast<const schar*>( 2882 const schar* pos = reinterpret_cast<const schar*>(
2916 memchr(subject.start() + i, 2883 memchr(subject.start() + i,
2917 pattern_first_char, 2884 pattern_first_char,
2918 n - i + 1)); 2885 n - i + 1));
2919 if (pos == NULL) return -1; 2886 if (pos == NULL) return -1;
2920 i = static_cast<int>(pos - subject.start()); 2887 i = static_cast<int>(pos - subject.start());
2921 } else { 2888 } else {
2922 if (subject[i] != pattern_first_char) continue; 2889 if (subject[i] != pattern_first_char) continue;
2923 } 2890 }
2924 int j = 1; 2891 int j = 1;
2925 do { 2892 while (j < pattern.length()) {
2926 if (pattern[j] != subject[i+j]) { 2893 if (pattern[j] != subject[i+j]) {
2927 break; 2894 break;
2928 } 2895 }
2929 j++; 2896 j++;
2930 } while (j < pattern.length()); 2897 }
2931 if (j == pattern.length()) { 2898 if (j == pattern.length()) {
2932 return i; 2899 return i;
2933 } 2900 }
2934 } 2901 }
2935 return -1; 2902 return -1;
2936 } 2903 }
2937 2904
2938 2905
2939 // Strategy for searching for a string in another string. 2906 // Strategy for searching for a string in another string.
2940 enum StringSearchStrategy { SEARCH_FAIL, SEARCH_SHORT, SEARCH_LONG }; 2907 enum StringSearchStrategy { SEARCH_FAIL, SEARCH_SHORT, SEARCH_LONG };
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
3022 int start_index) { 2989 int start_index) {
3023 ASSERT(0 <= start_index); 2990 ASSERT(0 <= start_index);
3024 ASSERT(start_index <= sub->length()); 2991 ASSERT(start_index <= sub->length());
3025 2992
3026 int pattern_length = pat->length(); 2993 int pattern_length = pat->length();
3027 if (pattern_length == 0) return start_index; 2994 if (pattern_length == 0) return start_index;
3028 2995
3029 int subject_length = sub->length(); 2996 int subject_length = sub->length();
3030 if (start_index + pattern_length > subject_length) return -1; 2997 if (start_index + pattern_length > subject_length) return -1;
3031 2998
3032 if (!sub->IsFlat()) { 2999 if (!sub->IsFlat()) FlattenString(sub);
3033 FlattenString(sub); 3000 if (!pat->IsFlat()) FlattenString(pat);
3034 }
3035
3036 // Searching for one specific character is common. For one
3037 // character patterns linear search is necessary, so any smart
3038 // algorithm is unnecessary overhead.
3039 if (pattern_length == 1) {
3040 AssertNoAllocation no_heap_allocation; // ensure vectors stay valid
3041 String* seq_sub = *sub;
3042 if (seq_sub->IsConsString()) {
3043 seq_sub = ConsString::cast(seq_sub)->first();
3044 }
3045 if (seq_sub->IsAsciiRepresentation()) {
3046 uc16 pchar = pat->Get(0);
3047 if (pchar > String::kMaxAsciiCharCode) {
3048 return -1;
3049 }
3050 Vector<const char> ascii_vector =
3051 seq_sub->ToAsciiVector().SubVector(start_index, subject_length);
3052 const void* pos = memchr(ascii_vector.start(),
3053 static_cast<const char>(pchar),
3054 static_cast<size_t>(ascii_vector.length()));
3055 if (pos == NULL) {
3056 return -1;
3057 }
3058 return static_cast<int>(reinterpret_cast<const char*>(pos)
3059 - ascii_vector.start() + start_index);
3060 }
3061 return SingleCharIndexOf(seq_sub->ToUC16Vector(),
3062 pat->Get(0),
3063 start_index);
3064 }
3065
3066 if (!pat->IsFlat()) {
3067 FlattenString(pat);
3068 }
3069 3001
3070 AssertNoAllocation no_heap_allocation; // ensure vectors stay valid 3002 AssertNoAllocation no_heap_allocation; // ensure vectors stay valid
3071 // Extract flattened substrings of cons strings before determining asciiness. 3003 // Extract flattened substrings of cons strings before determining asciiness.
3072 String* seq_sub = *sub; 3004 String* seq_sub = *sub;
3073 if (seq_sub->IsConsString()) { 3005 if (seq_sub->IsConsString()) seq_sub = ConsString::cast(seq_sub)->first();
3074 seq_sub = ConsString::cast(seq_sub)->first();
3075 }
3076 String* seq_pat = *pat; 3006 String* seq_pat = *pat;
3077 if (seq_pat->IsConsString()) { 3007 if (seq_pat->IsConsString()) seq_pat = ConsString::cast(seq_pat)->first();
3078 seq_pat = ConsString::cast(seq_pat)->first();
3079 }
3080 3008
3081 // dispatch on type of strings 3009 // dispatch on type of strings
3082 if (seq_pat->IsAsciiRepresentation()) { 3010 if (seq_pat->IsAsciiRepresentation()) {
3083 Vector<const char> pat_vector = seq_pat->ToAsciiVector(); 3011 Vector<const char> pat_vector = seq_pat->ToAsciiVector();
3084 if (seq_sub->IsAsciiRepresentation()) { 3012 if (seq_sub->IsAsciiRepresentation()) {
3085 return StringSearch(seq_sub->ToAsciiVector(), pat_vector, start_index); 3013 return StringSearch(seq_sub->ToAsciiVector(), pat_vector, start_index);
3086 } 3014 }
3087 return StringSearch(seq_sub->ToUC16Vector(), pat_vector, start_index); 3015 return StringSearch(seq_sub->ToUC16Vector(), pat_vector, start_index);
3088 } 3016 }
3089 Vector<const uc16> pat_vector = seq_pat->ToUC16Vector(); 3017 Vector<const uc16> pat_vector = seq_pat->ToUC16Vector();
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
3159 uint32_t sub_length = sub->length(); 3087 uint32_t sub_length = sub->length();
3160 3088
3161 if (start_index + pat_length > sub_length) { 3089 if (start_index + pat_length > sub_length) {
3162 start_index = sub_length - pat_length; 3090 start_index = sub_length - pat_length;
3163 } 3091 }
3164 3092
3165 if (pat_length == 0) { 3093 if (pat_length == 0) {
3166 return Smi::FromInt(start_index); 3094 return Smi::FromInt(start_index);
3167 } 3095 }
3168 3096
3169 if (!sub->IsFlat()) { 3097 if (!sub->IsFlat()) FlattenString(sub);
3170 FlattenString(sub); 3098 if (!pat->IsFlat()) FlattenString(pat);
3171 }
3172
3173 if (pat_length == 1) {
3174 AssertNoAllocation no_heap_allocation; // ensure vectors stay valid
3175 if (sub->IsAsciiRepresentation()) {
3176 uc16 pchar = pat->Get(0);
3177 if (pchar > String::kMaxAsciiCharCode) {
3178 return Smi::FromInt(-1);
3179 }
3180 return Smi::FromInt(SingleCharLastIndexOf(sub->ToAsciiVector(),
3181 static_cast<char>(pat->Get(0)),
3182 start_index));
3183 } else {
3184 return Smi::FromInt(SingleCharLastIndexOf(sub->ToUC16Vector(),
3185 pat->Get(0),
3186 start_index));
3187 }
3188 }
3189
3190 if (!pat->IsFlat()) {
3191 FlattenString(pat);
3192 }
3193 3099
3194 AssertNoAllocation no_heap_allocation; // ensure vectors stay valid 3100 AssertNoAllocation no_heap_allocation; // ensure vectors stay valid
3195 3101
3196 int position = -1; 3102 int position = -1;
3197 3103
3198 if (pat->IsAsciiRepresentation()) { 3104 if (pat->IsAsciiRepresentation()) {
3199 Vector<const char> pat_vector = pat->ToAsciiVector(); 3105 Vector<const char> pat_vector = pat->ToAsciiVector();
3200 if (sub->IsAsciiRepresentation()) { 3106 if (sub->IsAsciiRepresentation()) {
3201 position = StringMatchBackwards(sub->ToAsciiVector(), 3107 position = StringMatchBackwards(sub->ToAsciiVector(),
3202 pat_vector, 3108 pat_vector,
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after
3360 AssertNoAllocation no_gc; 3266 AssertNoAllocation no_gc;
3361 FixedArray* elements = FixedArray::cast(last_match_info->elements()); 3267 FixedArray* elements = FixedArray::cast(last_match_info->elements());
3362 RegExpImpl::SetLastCaptureCount(elements, 2); 3268 RegExpImpl::SetLastCaptureCount(elements, 2);
3363 RegExpImpl::SetLastInput(elements, *subject); 3269 RegExpImpl::SetLastInput(elements, *subject);
3364 RegExpImpl::SetLastSubject(elements, *subject); 3270 RegExpImpl::SetLastSubject(elements, *subject);
3365 RegExpImpl::SetCapture(elements, 0, match_start); 3271 RegExpImpl::SetCapture(elements, 0, match_start);
3366 RegExpImpl::SetCapture(elements, 1, match_end); 3272 RegExpImpl::SetCapture(elements, 1, match_end);
3367 } 3273 }
3368 3274
3369 3275
3370 template <typename schar>
3371 static bool SearchCharMultiple(Vector<schar> subject,
3372 String* pattern,
3373 schar pattern_char,
3374 FixedArrayBuilder* builder,
3375 int* match_pos) {
3376 // Position of last match.
3377 int pos = *match_pos;
3378 int subject_length = subject.length();
3379 while (pos < subject_length) {
3380 int match_end = pos + 1;
3381 if (!builder->HasCapacity(kMaxBuilderEntriesPerRegExpMatch)) {
3382 *match_pos = pos;
3383 return false;
3384 }
3385 int new_pos = SingleCharIndexOf(subject, pattern_char, match_end);
3386 if (new_pos >= 0) {
3387 // Match has been found.
3388 if (new_pos > match_end) {
3389 ReplacementStringBuilder::AddSubjectSlice(builder, match_end, new_pos);
3390 }
3391 pos = new_pos;
3392 builder->Add(pattern);
3393 } else {
3394 break;
3395 }
3396 }
3397 if (pos + 1 < subject_length) {
3398 ReplacementStringBuilder::AddSubjectSlice(builder, pos + 1, subject_length);
3399 }
3400 *match_pos = pos;
3401 return true;
3402 }
3403
3404
3405 static bool SearchCharMultiple(Handle<String> subject,
3406 Handle<String> pattern,
3407 Handle<JSArray> last_match_info,
3408 FixedArrayBuilder* builder) {
3409 ASSERT(subject->IsFlat());
3410 ASSERT_EQ(1, pattern->length());
3411 uc16 pattern_char = pattern->Get(0);
3412 // Treating position before first as initial "previous match position".
3413 int match_pos = -1;
3414
3415 for (;;) { // Break when search complete.
3416 builder->EnsureCapacity(kMaxBuilderEntriesPerRegExpMatch);
3417 AssertNoAllocation no_gc;
3418 if (subject->IsAsciiRepresentation()) {
3419 if (pattern_char > String::kMaxAsciiCharCode) {
3420 break;
3421 }
3422 Vector<const char> subject_vector = subject->ToAsciiVector();
3423 char pattern_ascii_char = static_cast<char>(pattern_char);
3424 bool complete = SearchCharMultiple<const char>(subject_vector,
3425 *pattern,
3426 pattern_ascii_char,
3427 builder,
3428 &match_pos);
3429 if (complete) break;
3430 } else {
3431 Vector<const uc16> subject_vector = subject->ToUC16Vector();
3432 bool complete = SearchCharMultiple<const uc16>(subject_vector,
3433 *pattern,
3434 pattern_char,
3435 builder,
3436 &match_pos);
3437 if (complete) break;
3438 }
3439 }
3440
3441 if (match_pos >= 0) {
3442 SetLastMatchInfoNoCaptures(subject,
3443 last_match_info,
3444 match_pos,
3445 match_pos + 1);
3446 return true;
3447 }
3448 return false; // No matches at all.
3449 }
3450
3451
3452 template <typename schar, typename pchar> 3276 template <typename schar, typename pchar>
3453 static bool SearchStringMultiple(Vector<schar> subject, 3277 static bool SearchStringMultiple(Vector<schar> subject,
3454 String* pattern, 3278 String* pattern,
3455 Vector<pchar> pattern_string, 3279 Vector<pchar> pattern_string,
3456 FixedArrayBuilder* builder, 3280 FixedArrayBuilder* builder,
3457 int* match_pos) { 3281 int* match_pos) {
3458 int pos = *match_pos; 3282 int pos = *match_pos;
3459 int subject_length = subject.length(); 3283 int subject_length = subject.length();
3460 int pattern_length = pattern_string.length(); 3284 int pattern_length = pattern_string.length();
3461 int max_search_start = subject_length - pattern_length; 3285 int max_search_start = subject_length - pattern_length;
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
3519 return true; 3343 return true;
3520 } 3344 }
3521 3345
3522 3346
3523 static bool SearchStringMultiple(Handle<String> subject, 3347 static bool SearchStringMultiple(Handle<String> subject,
3524 Handle<String> pattern, 3348 Handle<String> pattern,
3525 Handle<JSArray> last_match_info, 3349 Handle<JSArray> last_match_info,
3526 FixedArrayBuilder* builder) { 3350 FixedArrayBuilder* builder) {
3527 ASSERT(subject->IsFlat()); 3351 ASSERT(subject->IsFlat());
3528 ASSERT(pattern->IsFlat()); 3352 ASSERT(pattern->IsFlat());
3529 ASSERT(pattern->length() > 1);
3530 3353
3531 // Treating as if a previous match was before first character. 3354 // Treating as if a previous match was before first character.
3532 int match_pos = -pattern->length(); 3355 int match_pos = -pattern->length();
3533 3356
3534 for (;;) { // Break when search complete. 3357 for (;;) { // Break when search complete.
3535 builder->EnsureCapacity(kMaxBuilderEntriesPerRegExpMatch); 3358 builder->EnsureCapacity(kMaxBuilderEntriesPerRegExpMatch);
3536 AssertNoAllocation no_gc; 3359 AssertNoAllocation no_gc;
3537 if (subject->IsAsciiRepresentation()) { 3360 if (subject->IsAsciiRepresentation()) {
3538 Vector<const char> subject_vector = subject->ToAsciiVector(); 3361 Vector<const char> subject_vector = subject->ToAsciiVector();
3539 if (pattern->IsAsciiRepresentation()) { 3362 if (pattern->IsAsciiRepresentation()) {
(...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after
3777 result_elements = 3600 result_elements =
3778 Handle<FixedArray>(FixedArray::cast(result_array->elements())); 3601 Handle<FixedArray>(FixedArray::cast(result_array->elements()));
3779 } else { 3602 } else {
3780 result_elements = Factory::NewFixedArrayWithHoles(16); 3603 result_elements = Factory::NewFixedArrayWithHoles(16);
3781 } 3604 }
3782 FixedArrayBuilder builder(result_elements); 3605 FixedArrayBuilder builder(result_elements);
3783 3606
3784 if (regexp->TypeTag() == JSRegExp::ATOM) { 3607 if (regexp->TypeTag() == JSRegExp::ATOM) {
3785 Handle<String> pattern( 3608 Handle<String> pattern(
3786 String::cast(regexp->DataAt(JSRegExp::kAtomPatternIndex))); 3609 String::cast(regexp->DataAt(JSRegExp::kAtomPatternIndex)));
3787 int pattern_length = pattern->length();
3788 if (pattern_length == 1) {
3789 if (SearchCharMultiple(subject, pattern, last_match_info, &builder)) {
3790 return *builder.ToJSArray(result_array);
3791 }
3792 return Heap::null_value();
3793 }
3794
3795 if (!pattern->IsFlat()) FlattenString(pattern); 3610 if (!pattern->IsFlat()) FlattenString(pattern);
3796 if (SearchStringMultiple(subject, pattern, last_match_info, &builder)) { 3611 if (SearchStringMultiple(subject, pattern, last_match_info, &builder)) {
3797 return *builder.ToJSArray(result_array); 3612 return *builder.ToJSArray(result_array);
3798 } 3613 }
3799 return Heap::null_value(); 3614 return Heap::null_value();
3800 } 3615 }
3801 3616
3802 ASSERT_EQ(regexp->TypeTag(), JSRegExp::IRREGEXP); 3617 ASSERT_EQ(regexp->TypeTag(), JSRegExp::IRREGEXP);
3803 3618
3804 RegExpImpl::IrregexpResult result; 3619 RegExpImpl::IrregexpResult result;
(...skipping 1580 matching lines...) Expand 10 before | Expand all | Expand 10 after
5385 limit--; 5200 limit--;
5386 } 5201 }
5387 return; 5202 return;
5388 } 5203 }
5389 default: 5204 default:
5390 UNREACHABLE(); 5205 UNREACHABLE();
5391 return; 5206 return;
5392 } 5207 }
5393 } 5208 }
5394 5209
5395 template <typename schar>
5396 inline void FindCharIndices(Vector<const schar> subject,
5397 const schar pattern_char,
5398 ZoneList<int>* indices,
5399 unsigned int limit) {
5400 // Collect indices of pattern_char in subject, and the end-of-string index.
5401 // Stop after finding at most limit values.
5402 int index = 0;
5403 while (limit > 0) {
5404 index = SingleCharIndexOf(subject, pattern_char, index);
5405 if (index < 0) return;
5406 indices->Add(index);
5407 index++;
5408 limit--;
5409 }
5410 }
5411
5412 5210
5413 static Object* Runtime_StringSplit(Arguments args) { 5211 static Object* Runtime_StringSplit(Arguments args) {
5414 ASSERT(args.length() == 3); 5212 ASSERT(args.length() == 3);
5415 HandleScope handle_scope; 5213 HandleScope handle_scope;
5416 CONVERT_ARG_CHECKED(String, subject, 0); 5214 CONVERT_ARG_CHECKED(String, subject, 0);
5417 CONVERT_ARG_CHECKED(String, pattern, 1); 5215 CONVERT_ARG_CHECKED(String, pattern, 1);
5418 CONVERT_NUMBER_CHECKED(uint32_t, limit, Uint32, args[2]); 5216 CONVERT_NUMBER_CHECKED(uint32_t, limit, Uint32, args[2]);
5419 5217
5420 int subject_length = subject->length(); 5218 int subject_length = subject->length();
5421 int pattern_length = pattern->length(); 5219 int pattern_length = pattern->length();
5422 RUNTIME_ASSERT(pattern_length > 0); 5220 RUNTIME_ASSERT(pattern_length > 0);
5423 5221
5424 // The limit can be very large (0xffffffffu), but since the pattern 5222 // The limit can be very large (0xffffffffu), but since the pattern
5425 // isn't empty, we can never create more parts than ~half the length 5223 // isn't empty, we can never create more parts than ~half the length
5426 // of the subject. 5224 // of the subject.
5427 5225
5428 if (!subject->IsFlat()) FlattenString(subject); 5226 if (!subject->IsFlat()) FlattenString(subject);
5429 5227
5430 static const int kMaxInitialListCapacity = 16; 5228 static const int kMaxInitialListCapacity = 16;
5431 5229
5432 ZoneScope scope(DELETE_ON_EXIT); 5230 ZoneScope scope(DELETE_ON_EXIT);
5433 5231
5434 // Find (up to limit) indices of separator and end-of-string in subject 5232 // Find (up to limit) indices of separator and end-of-string in subject
5435 int initial_capacity = Min<uint32_t>(kMaxInitialListCapacity, limit); 5233 int initial_capacity = Min<uint32_t>(kMaxInitialListCapacity, limit);
5436 ZoneList<int> indices(initial_capacity); 5234 ZoneList<int> indices(initial_capacity);
5437 if (pattern_length == 1) { 5235 if (!pattern->IsFlat()) FlattenString(pattern);
5438 // Special case, go directly to fast single-character split. 5236 AssertNoAllocation nogc;
5439 AssertNoAllocation nogc; 5237 if (subject->IsAsciiRepresentation()) {
5440 uc16 pattern_char = pattern->Get(0); 5238 Vector<const char> subject_vector = subject->ToAsciiVector();
5441 if (subject->IsTwoByteRepresentation()) { 5239 if (pattern->IsAsciiRepresentation()) {
5442 FindCharIndices(subject->ToUC16Vector(), pattern_char, 5240 FindStringIndices(subject_vector,
5443 &indices, 5241 pattern->ToAsciiVector(),
5444 limit); 5242 &indices,
5445 } else if (pattern_char <= String::kMaxAsciiCharCode) { 5243 limit);
5446 FindCharIndices(subject->ToAsciiVector(), 5244 } else {
5447 static_cast<char>(pattern_char), 5245 FindStringIndices(subject_vector,
5448 &indices, 5246 pattern->ToUC16Vector(),
5449 limit); 5247 &indices,
5248 limit);
5450 } 5249 }
5451 } else { 5250 } else {
5452 if (!pattern->IsFlat()) FlattenString(pattern); 5251 Vector<const uc16> subject_vector = subject->ToUC16Vector();
5453 AssertNoAllocation nogc; 5252 if (pattern->IsAsciiRepresentation()) {
5454 if (subject->IsAsciiRepresentation()) { 5253 FindStringIndices(subject_vector,
5455 Vector<const char> subject_vector = subject->ToAsciiVector(); 5254 pattern->ToAsciiVector(),
5456 if (pattern->IsAsciiRepresentation()) { 5255 &indices,
5457 FindStringIndices(subject_vector, 5256 limit);
5458 pattern->ToAsciiVector(),
5459 &indices,
5460 limit);
5461 } else {
5462 FindStringIndices(subject_vector,
5463 pattern->ToUC16Vector(),
5464 &indices,
5465 limit);
5466 }
5467 } else { 5257 } else {
5468 Vector<const uc16> subject_vector = subject->ToUC16Vector(); 5258 FindStringIndices(subject_vector,
5469 if (pattern->IsAsciiRepresentation()) { 5259 pattern->ToUC16Vector(),
5470 FindStringIndices(subject_vector, 5260 &indices,
5471 pattern->ToAsciiVector(), 5261 limit);
5472 &indices,
5473 limit);
5474 } else {
5475 FindStringIndices(subject_vector,
5476 pattern->ToUC16Vector(),
5477 &indices,
5478 limit);
5479 }
5480 } 5262 }
5481 } 5263 }
5482 if (static_cast<uint32_t>(indices.length()) < limit) { 5264 if (static_cast<uint32_t>(indices.length()) < limit) {
5483 indices.Add(subject_length); 5265 indices.Add(subject_length);
5484 } 5266 }
5485 // The list indices now contains the end of each part to create. 5267 // The list indices now contains the end of each part to create.
5486 5268
5487 5269
5488 // Create JSArray of substrings separated by separator. 5270 // Create JSArray of substrings separated by separator.
5489 int part_count = indices.length(); 5271 int part_count = indices.length();
(...skipping 5249 matching lines...) Expand 10 before | Expand all | Expand 10 after
10739 } else { 10521 } else {
10740 // Handle last resort GC and make sure to allow future allocations 10522 // Handle last resort GC and make sure to allow future allocations
10741 // to grow the heap without causing GCs (if possible). 10523 // to grow the heap without causing GCs (if possible).
10742 Counters::gc_last_resort_from_js.Increment(); 10524 Counters::gc_last_resort_from_js.Increment();
10743 Heap::CollectAllGarbage(false); 10525 Heap::CollectAllGarbage(false);
10744 } 10526 }
10745 } 10527 }
10746 10528
10747 10529
10748 } } // namespace v8::internal 10530 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698