Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 2489 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2500 FixedArrayBuilder array_builder_; | 2500 FixedArrayBuilder array_builder_; |
| 2501 Handle<String> subject_; | 2501 Handle<String> subject_; |
| 2502 int character_count_; | 2502 int character_count_; |
| 2503 bool is_ascii_; | 2503 bool is_ascii_; |
| 2504 }; | 2504 }; |
| 2505 | 2505 |
| 2506 | 2506 |
| 2507 class CompiledReplacement { | 2507 class CompiledReplacement { |
| 2508 public: | 2508 public: |
| 2509 CompiledReplacement() | 2509 CompiledReplacement() |
| 2510 : parts_(1), replacement_substrings_(0) {} | 2510 : parts_(1), replacement_substrings_(0), simple_hint(false) {} |
| 2511 | 2511 |
| 2512 void Compile(Handle<String> replacement, | 2512 void Compile(Handle<String> replacement, |
| 2513 int capture_count, | 2513 int capture_count, |
| 2514 int subject_length); | 2514 int subject_length); |
| 2515 | 2515 |
| 2516 void Apply(ReplacementStringBuilder* builder, | 2516 void Apply(ReplacementStringBuilder* builder, |
| 2517 int match_from, | 2517 int match_from, |
| 2518 int match_to, | 2518 int match_to, |
| 2519 Handle<JSArray> last_match_info); | 2519 Handle<JSArray> last_match_info); |
| 2520 | 2520 |
| 2521 // Number of distinct parts of the replacement pattern. | 2521 // Number of distinct parts of the replacement pattern. |
| 2522 int parts() { | 2522 int parts() { |
| 2523 return parts_.length(); | 2523 return parts_.length(); |
| 2524 } | 2524 } |
| 2525 | 2525 |
| 2526 int IsSimple() { | |
|
Jakob Kummerow
2011/09/07 16:11:24
nit 1: This is C++. We have bools.
nit 2: A simple
| |
| 2527 return simple_hint; | |
| 2528 } | |
| 2529 | |
| 2526 private: | 2530 private: |
| 2527 enum PartType { | 2531 enum PartType { |
| 2528 SUBJECT_PREFIX = 1, | 2532 SUBJECT_PREFIX = 1, |
| 2529 SUBJECT_SUFFIX, | 2533 SUBJECT_SUFFIX, |
| 2530 SUBJECT_CAPTURE, | 2534 SUBJECT_CAPTURE, |
| 2531 REPLACEMENT_SUBSTRING, | 2535 REPLACEMENT_SUBSTRING, |
| 2532 REPLACEMENT_STRING, | 2536 REPLACEMENT_STRING, |
| 2533 | 2537 |
| 2534 NUMBER_OF_PART_TYPES | 2538 NUMBER_OF_PART_TYPES |
| 2535 }; | 2539 }; |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2571 // tag == SUBJECT_SUFFIX: data is unused. | 2575 // tag == SUBJECT_SUFFIX: data is unused. |
| 2572 // tag == SUBJECT_CAPTURE: data is the number of the capture. | 2576 // tag == SUBJECT_CAPTURE: data is the number of the capture. |
| 2573 // tag == REPLACEMENT_SUBSTRING || | 2577 // tag == REPLACEMENT_SUBSTRING || |
| 2574 // tag == REPLACEMENT_STRING: data is index into array of substrings | 2578 // tag == REPLACEMENT_STRING: data is index into array of substrings |
| 2575 // of the replacement string. | 2579 // of the replacement string. |
| 2576 // tag <= 0: Temporary representation of the substring of the replacement | 2580 // tag <= 0: Temporary representation of the substring of the replacement |
| 2577 // string ranging over -tag .. data. | 2581 // string ranging over -tag .. data. |
| 2578 // Is replaced by REPLACEMENT_{SUB,}STRING when we create the | 2582 // Is replaced by REPLACEMENT_{SUB,}STRING when we create the |
| 2579 // substring objects. | 2583 // substring objects. |
| 2580 int data; | 2584 int data; |
| 2585 | |
| 2581 }; | 2586 }; |
| 2582 | 2587 |
| 2583 template<typename Char> | 2588 template<typename Char> |
| 2584 static void ParseReplacementPattern(ZoneList<ReplacementPart>* parts, | 2589 static bool ParseReplacementPattern(ZoneList<ReplacementPart>* parts, |
| 2585 Vector<Char> characters, | 2590 Vector<Char> characters, |
| 2586 int capture_count, | 2591 int capture_count, |
| 2587 int subject_length) { | 2592 int subject_length) { |
| 2588 int length = characters.length(); | 2593 int length = characters.length(); |
| 2589 int last = 0; | 2594 int last = 0; |
| 2595 bool simple = true; | |
| 2590 for (int i = 0; i < length; i++) { | 2596 for (int i = 0; i < length; i++) { |
| 2591 Char c = characters[i]; | 2597 Char c = characters[i]; |
| 2592 if (c == '$') { | 2598 if (c == '$') { |
| 2599 simple = false; | |
| 2593 int next_index = i + 1; | 2600 int next_index = i + 1; |
| 2594 if (next_index == length) { // No next character! | 2601 if (next_index == length) { // No next character! |
| 2595 break; | 2602 break; |
| 2596 } | 2603 } |
| 2597 Char c2 = characters[next_index]; | 2604 Char c2 = characters[next_index]; |
| 2598 switch (c2) { | 2605 switch (c2) { |
| 2599 case '$': | 2606 case '$': |
| 2600 if (i > last) { | 2607 if (i > last) { |
| 2601 // There is a substring before. Include the first "$". | 2608 // There is a substring before. Include the first "$". |
| 2602 parts->Add(ReplacementPart::ReplacementSubString(last, next_index)); | 2609 parts->Add(ReplacementPart::ReplacementSubString(last, next_index)); |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2675 } | 2682 } |
| 2676 } | 2683 } |
| 2677 } | 2684 } |
| 2678 if (length > last) { | 2685 if (length > last) { |
| 2679 if (last == 0) { | 2686 if (last == 0) { |
| 2680 parts->Add(ReplacementPart::ReplacementString()); | 2687 parts->Add(ReplacementPart::ReplacementString()); |
| 2681 } else { | 2688 } else { |
| 2682 parts->Add(ReplacementPart::ReplacementSubString(last, length)); | 2689 parts->Add(ReplacementPart::ReplacementSubString(last, length)); |
| 2683 } | 2690 } |
| 2684 } | 2691 } |
| 2692 return simple; | |
| 2685 } | 2693 } |
| 2686 | 2694 |
| 2687 ZoneList<ReplacementPart> parts_; | 2695 ZoneList<ReplacementPart> parts_; |
| 2688 ZoneList<Handle<String> > replacement_substrings_; | 2696 ZoneList<Handle<String> > replacement_substrings_; |
| 2697 bool simple_hint; | |
|
Jakob Kummerow
2011/09/07 16:11:24
nit: trailing underscore please
| |
| 2689 }; | 2698 }; |
| 2690 | 2699 |
| 2691 | 2700 |
| 2692 void CompiledReplacement::Compile(Handle<String> replacement, | 2701 void CompiledReplacement::Compile(Handle<String> replacement, |
| 2693 int capture_count, | 2702 int capture_count, |
| 2694 int subject_length) { | 2703 int subject_length) { |
| 2695 { | 2704 { |
| 2696 AssertNoAllocation no_alloc; | 2705 AssertNoAllocation no_alloc; |
| 2697 String::FlatContent content = replacement->GetFlatContent(); | 2706 String::FlatContent content = replacement->GetFlatContent(); |
| 2698 ASSERT(content.IsFlat()); | 2707 ASSERT(content.IsFlat()); |
| 2699 if (content.IsAscii()) { | 2708 if (content.IsAscii()) { |
| 2700 ParseReplacementPattern(&parts_, | 2709 simple_hint = ParseReplacementPattern(&parts_, |
| 2701 content.ToAsciiVector(), | 2710 content.ToAsciiVector(), |
| 2702 capture_count, | 2711 capture_count, |
| 2703 subject_length); | 2712 subject_length); |
| 2704 } else { | 2713 } else { |
| 2705 ASSERT(content.IsTwoByte()); | 2714 ASSERT(content.IsTwoByte()); |
| 2706 ParseReplacementPattern(&parts_, | 2715 simple_hint = ParseReplacementPattern(&parts_, |
| 2707 content.ToUC16Vector(), | 2716 content.ToUC16Vector(), |
| 2708 capture_count, | 2717 capture_count, |
| 2709 subject_length); | 2718 subject_length); |
| 2710 } | 2719 } |
| 2711 } | 2720 } |
| 2712 Isolate* isolate = replacement->GetIsolate(); | 2721 Isolate* isolate = replacement->GetIsolate(); |
| 2713 // Find substrings of replacement string and create them as String objects. | 2722 // Find substrings of replacement string and create them as String objects. |
| 2714 int substring_index = 0; | 2723 int substring_index = 0; |
| 2715 for (int i = 0, n = parts_.length(); i < n; i++) { | 2724 for (int i = 0, n = parts_.length(); i < n; i++) { |
| 2716 int tag = parts_[i].tag; | 2725 int tag = parts_[i].tag; |
| 2717 if (tag <= 0) { // A replacement string slice. | 2726 if (tag <= 0) { // A replacement string slice. |
| 2718 int from = -tag; | 2727 int from = -tag; |
| 2719 int to = parts_[i].data; | 2728 int to = parts_[i].data; |
| (...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2894 | 2903 |
| 2895 Handle<ResultSeqString> result; | 2904 Handle<ResultSeqString> result; |
| 2896 if (ResultSeqString::kHasAsciiEncoding) { | 2905 if (ResultSeqString::kHasAsciiEncoding) { |
| 2897 result = Handle<ResultSeqString>::cast( | 2906 result = Handle<ResultSeqString>::cast( |
| 2898 isolate->factory()->NewRawAsciiString(result_len)); | 2907 isolate->factory()->NewRawAsciiString(result_len)); |
| 2899 } else { | 2908 } else { |
| 2900 result = Handle<ResultSeqString>::cast( | 2909 result = Handle<ResultSeqString>::cast( |
| 2901 isolate->factory()->NewRawTwoByteString(result_len)); | 2910 isolate->factory()->NewRawTwoByteString(result_len)); |
| 2902 } | 2911 } |
| 2903 | 2912 |
| 2904 for(int i = 0; i < matches; i++) { | 2913 for (int i = 0; i < matches; i++) { |
| 2905 // Copy non-matched subject content. | 2914 // Copy non-matched subject content. |
| 2906 String::WriteToFlat(*subject, | 2915 String::WriteToFlat(*subject, |
| 2907 result->GetChars() + result_pos, | 2916 result->GetChars() + result_pos, |
| 2908 subject_pos, | 2917 subject_pos, |
| 2909 indices.at(i)); | 2918 indices.at(i)); |
| 2910 result_pos += indices.at(i) - subject_pos; | 2919 result_pos += indices.at(i) - subject_pos; |
| 2911 // Replace match. | 2920 // Replace match. |
| 2912 | 2921 |
| 2913 if (replacement_len > 0) { | 2922 if (replacement_len > 0) { |
| 2914 String::WriteToFlat(*replacement, | 2923 String::WriteToFlat(*replacement, |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2962 CompiledReplacement compiled_replacement; | 2971 CompiledReplacement compiled_replacement; |
| 2963 compiled_replacement.Compile(replacement_handle, | 2972 compiled_replacement.Compile(replacement_handle, |
| 2964 capture_count, | 2973 capture_count, |
| 2965 length); | 2974 length); |
| 2966 | 2975 |
| 2967 bool is_global = regexp_handle->GetFlags().is_global(); | 2976 bool is_global = regexp_handle->GetFlags().is_global(); |
| 2968 | 2977 |
| 2969 // Shortcut for simple non-regexp global replacements | 2978 // Shortcut for simple non-regexp global replacements |
| 2970 if (is_global && | 2979 if (is_global && |
| 2971 regexp->TypeTag() == JSRegExp::ATOM && | 2980 regexp->TypeTag() == JSRegExp::ATOM && |
| 2972 compiled_replacement.parts() == 1) { | 2981 compiled_replacement.IsSimple()) { |
| 2973 if (subject_handle->HasOnlyAsciiChars() && | 2982 if (subject_handle->HasOnlyAsciiChars() && |
| 2974 replacement_handle->HasOnlyAsciiChars()) { | 2983 replacement_handle->HasOnlyAsciiChars()) { |
| 2975 return StringReplaceStringWithString<SeqAsciiString>( | 2984 return StringReplaceStringWithString<SeqAsciiString>( |
| 2976 isolate, subject_handle, regexp_handle, replacement_handle); | 2985 isolate, subject_handle, regexp_handle, replacement_handle); |
| 2977 } else { | 2986 } else { |
| 2978 return StringReplaceStringWithString<SeqTwoByteString>( | 2987 return StringReplaceStringWithString<SeqTwoByteString>( |
| 2979 isolate, subject_handle, regexp_handle, replacement_handle); | 2988 isolate, subject_handle, regexp_handle, replacement_handle); |
| 2980 } | 2989 } |
| 2981 } | 2990 } |
| 2982 | 2991 |
| (...skipping 10135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 13118 } else { | 13127 } else { |
| 13119 // Handle last resort GC and make sure to allow future allocations | 13128 // Handle last resort GC and make sure to allow future allocations |
| 13120 // to grow the heap without causing GCs (if possible). | 13129 // to grow the heap without causing GCs (if possible). |
| 13121 isolate->counters()->gc_last_resort_from_js()->Increment(); | 13130 isolate->counters()->gc_last_resort_from_js()->Increment(); |
| 13122 isolate->heap()->CollectAllGarbage(false); | 13131 isolate->heap()->CollectAllGarbage(false); |
| 13123 } | 13132 } |
| 13124 } | 13133 } |
| 13125 | 13134 |
| 13126 | 13135 |
| 13127 } } // namespace v8::internal | 13136 } } // namespace v8::internal |
| OLD | NEW |