OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 2508 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2519 Heap* heap_; | 2519 Heap* heap_; |
2520 FixedArrayBuilder array_builder_; | 2520 FixedArrayBuilder array_builder_; |
2521 Handle<String> subject_; | 2521 Handle<String> subject_; |
2522 int character_count_; | 2522 int character_count_; |
2523 bool is_ascii_; | 2523 bool is_ascii_; |
2524 }; | 2524 }; |
2525 | 2525 |
2526 | 2526 |
2527 class CompiledReplacement { | 2527 class CompiledReplacement { |
2528 public: | 2528 public: |
2529 CompiledReplacement() | 2529 explicit CompiledReplacement(Zone* zone) |
2530 : parts_(1), replacement_substrings_(0), simple_hint_(false) {} | 2530 : parts_(1, zone), replacement_substrings_(0, zone), |
| 2531 simple_hint_(false), |
| 2532 zone_(zone) {} |
2531 | 2533 |
2532 void Compile(Handle<String> replacement, | 2534 void Compile(Handle<String> replacement, |
2533 int capture_count, | 2535 int capture_count, |
2534 int subject_length); | 2536 int subject_length); |
2535 | 2537 |
2536 void Apply(ReplacementStringBuilder* builder, | 2538 void Apply(ReplacementStringBuilder* builder, |
2537 int match_from, | 2539 int match_from, |
2538 int match_to, | 2540 int match_to, |
2539 Handle<JSArray> last_match_info); | 2541 Handle<JSArray> last_match_info); |
2540 | 2542 |
2541 // Number of distinct parts of the replacement pattern. | 2543 // Number of distinct parts of the replacement pattern. |
2542 int parts() { | 2544 int parts() { |
2543 return parts_.length(); | 2545 return parts_.length(); |
2544 } | 2546 } |
2545 | 2547 |
2546 bool simple_hint() { | 2548 bool simple_hint() { |
2547 return simple_hint_; | 2549 return simple_hint_; |
2548 } | 2550 } |
2549 | 2551 |
| 2552 Zone* zone() const { return zone_; } |
| 2553 |
2550 private: | 2554 private: |
2551 enum PartType { | 2555 enum PartType { |
2552 SUBJECT_PREFIX = 1, | 2556 SUBJECT_PREFIX = 1, |
2553 SUBJECT_SUFFIX, | 2557 SUBJECT_SUFFIX, |
2554 SUBJECT_CAPTURE, | 2558 SUBJECT_CAPTURE, |
2555 REPLACEMENT_SUBSTRING, | 2559 REPLACEMENT_SUBSTRING, |
2556 REPLACEMENT_STRING, | 2560 REPLACEMENT_STRING, |
2557 | 2561 |
2558 NUMBER_OF_PART_TYPES | 2562 NUMBER_OF_PART_TYPES |
2559 }; | 2563 }; |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2601 // string ranging over -tag .. data. | 2605 // string ranging over -tag .. data. |
2602 // Is replaced by REPLACEMENT_{SUB,}STRING when we create the | 2606 // Is replaced by REPLACEMENT_{SUB,}STRING when we create the |
2603 // substring objects. | 2607 // substring objects. |
2604 int data; | 2608 int data; |
2605 }; | 2609 }; |
2606 | 2610 |
2607 template<typename Char> | 2611 template<typename Char> |
2608 static bool ParseReplacementPattern(ZoneList<ReplacementPart>* parts, | 2612 static bool ParseReplacementPattern(ZoneList<ReplacementPart>* parts, |
2609 Vector<Char> characters, | 2613 Vector<Char> characters, |
2610 int capture_count, | 2614 int capture_count, |
2611 int subject_length) { | 2615 int subject_length, |
| 2616 Zone* zone) { |
2612 int length = characters.length(); | 2617 int length = characters.length(); |
2613 int last = 0; | 2618 int last = 0; |
2614 for (int i = 0; i < length; i++) { | 2619 for (int i = 0; i < length; i++) { |
2615 Char c = characters[i]; | 2620 Char c = characters[i]; |
2616 if (c == '$') { | 2621 if (c == '$') { |
2617 int next_index = i + 1; | 2622 int next_index = i + 1; |
2618 if (next_index == length) { // No next character! | 2623 if (next_index == length) { // No next character! |
2619 break; | 2624 break; |
2620 } | 2625 } |
2621 Char c2 = characters[next_index]; | 2626 Char c2 = characters[next_index]; |
2622 switch (c2) { | 2627 switch (c2) { |
2623 case '$': | 2628 case '$': |
2624 if (i > last) { | 2629 if (i > last) { |
2625 // There is a substring before. Include the first "$". | 2630 // There is a substring before. Include the first "$". |
2626 parts->Add(ReplacementPart::ReplacementSubString(last, next_index)); | 2631 parts->Add(ReplacementPart::ReplacementSubString(last, next_index), |
| 2632 zone); |
2627 last = next_index + 1; // Continue after the second "$". | 2633 last = next_index + 1; // Continue after the second "$". |
2628 } else { | 2634 } else { |
2629 // Let the next substring start with the second "$". | 2635 // Let the next substring start with the second "$". |
2630 last = next_index; | 2636 last = next_index; |
2631 } | 2637 } |
2632 i = next_index; | 2638 i = next_index; |
2633 break; | 2639 break; |
2634 case '`': | 2640 case '`': |
2635 if (i > last) { | 2641 if (i > last) { |
2636 parts->Add(ReplacementPart::ReplacementSubString(last, i)); | 2642 parts->Add(ReplacementPart::ReplacementSubString(last, i), zone); |
2637 } | 2643 } |
2638 parts->Add(ReplacementPart::SubjectPrefix()); | 2644 parts->Add(ReplacementPart::SubjectPrefix(), zone); |
2639 i = next_index; | 2645 i = next_index; |
2640 last = i + 1; | 2646 last = i + 1; |
2641 break; | 2647 break; |
2642 case '\'': | 2648 case '\'': |
2643 if (i > last) { | 2649 if (i > last) { |
2644 parts->Add(ReplacementPart::ReplacementSubString(last, i)); | 2650 parts->Add(ReplacementPart::ReplacementSubString(last, i), zone); |
2645 } | 2651 } |
2646 parts->Add(ReplacementPart::SubjectSuffix(subject_length)); | 2652 parts->Add(ReplacementPart::SubjectSuffix(subject_length), zone); |
2647 i = next_index; | 2653 i = next_index; |
2648 last = i + 1; | 2654 last = i + 1; |
2649 break; | 2655 break; |
2650 case '&': | 2656 case '&': |
2651 if (i > last) { | 2657 if (i > last) { |
2652 parts->Add(ReplacementPart::ReplacementSubString(last, i)); | 2658 parts->Add(ReplacementPart::ReplacementSubString(last, i), zone); |
2653 } | 2659 } |
2654 parts->Add(ReplacementPart::SubjectMatch()); | 2660 parts->Add(ReplacementPart::SubjectMatch(), zone); |
2655 i = next_index; | 2661 i = next_index; |
2656 last = i + 1; | 2662 last = i + 1; |
2657 break; | 2663 break; |
2658 case '0': | 2664 case '0': |
2659 case '1': | 2665 case '1': |
2660 case '2': | 2666 case '2': |
2661 case '3': | 2667 case '3': |
2662 case '4': | 2668 case '4': |
2663 case '5': | 2669 case '5': |
2664 case '6': | 2670 case '6': |
(...skipping 12 matching lines...) Expand all Loading... |
2677 if ('0' <= c3 && c3 <= '9') { // Double digits. | 2683 if ('0' <= c3 && c3 <= '9') { // Double digits. |
2678 int double_digit_ref = capture_ref * 10 + c3 - '0'; | 2684 int double_digit_ref = capture_ref * 10 + c3 - '0'; |
2679 if (double_digit_ref <= capture_count) { | 2685 if (double_digit_ref <= capture_count) { |
2680 next_index = second_digit_index; | 2686 next_index = second_digit_index; |
2681 capture_ref = double_digit_ref; | 2687 capture_ref = double_digit_ref; |
2682 } | 2688 } |
2683 } | 2689 } |
2684 } | 2690 } |
2685 if (capture_ref > 0) { | 2691 if (capture_ref > 0) { |
2686 if (i > last) { | 2692 if (i > last) { |
2687 parts->Add(ReplacementPart::ReplacementSubString(last, i)); | 2693 parts->Add(ReplacementPart::ReplacementSubString(last, i), zone); |
2688 } | 2694 } |
2689 ASSERT(capture_ref <= capture_count); | 2695 ASSERT(capture_ref <= capture_count); |
2690 parts->Add(ReplacementPart::SubjectCapture(capture_ref)); | 2696 parts->Add(ReplacementPart::SubjectCapture(capture_ref), zone); |
2691 last = next_index + 1; | 2697 last = next_index + 1; |
2692 } | 2698 } |
2693 i = next_index; | 2699 i = next_index; |
2694 break; | 2700 break; |
2695 } | 2701 } |
2696 default: | 2702 default: |
2697 i = next_index; | 2703 i = next_index; |
2698 break; | 2704 break; |
2699 } | 2705 } |
2700 } | 2706 } |
2701 } | 2707 } |
2702 if (length > last) { | 2708 if (length > last) { |
2703 if (last == 0) { | 2709 if (last == 0) { |
2704 parts->Add(ReplacementPart::ReplacementString()); | 2710 parts->Add(ReplacementPart::ReplacementString(), zone); |
2705 return true; | 2711 return true; |
2706 } else { | 2712 } else { |
2707 parts->Add(ReplacementPart::ReplacementSubString(last, length)); | 2713 parts->Add(ReplacementPart::ReplacementSubString(last, length), zone); |
2708 } | 2714 } |
2709 } | 2715 } |
2710 return false; | 2716 return false; |
2711 } | 2717 } |
2712 | 2718 |
2713 ZoneList<ReplacementPart> parts_; | 2719 ZoneList<ReplacementPart> parts_; |
2714 ZoneList<Handle<String> > replacement_substrings_; | 2720 ZoneList<Handle<String> > replacement_substrings_; |
2715 bool simple_hint_; | 2721 bool simple_hint_; |
| 2722 Zone* zone_; |
2716 }; | 2723 }; |
2717 | 2724 |
2718 | 2725 |
2719 void CompiledReplacement::Compile(Handle<String> replacement, | 2726 void CompiledReplacement::Compile(Handle<String> replacement, |
2720 int capture_count, | 2727 int capture_count, |
2721 int subject_length) { | 2728 int subject_length) { |
2722 { | 2729 { |
2723 AssertNoAllocation no_alloc; | 2730 AssertNoAllocation no_alloc; |
2724 String::FlatContent content = replacement->GetFlatContent(); | 2731 String::FlatContent content = replacement->GetFlatContent(); |
2725 ASSERT(content.IsFlat()); | 2732 ASSERT(content.IsFlat()); |
2726 if (content.IsAscii()) { | 2733 if (content.IsAscii()) { |
2727 simple_hint_ = ParseReplacementPattern(&parts_, | 2734 simple_hint_ = ParseReplacementPattern(&parts_, |
2728 content.ToAsciiVector(), | 2735 content.ToAsciiVector(), |
2729 capture_count, | 2736 capture_count, |
2730 subject_length); | 2737 subject_length, |
| 2738 zone()); |
2731 } else { | 2739 } else { |
2732 ASSERT(content.IsTwoByte()); | 2740 ASSERT(content.IsTwoByte()); |
2733 simple_hint_ = ParseReplacementPattern(&parts_, | 2741 simple_hint_ = ParseReplacementPattern(&parts_, |
2734 content.ToUC16Vector(), | 2742 content.ToUC16Vector(), |
2735 capture_count, | 2743 capture_count, |
2736 subject_length); | 2744 subject_length, |
| 2745 zone()); |
2737 } | 2746 } |
2738 } | 2747 } |
2739 Isolate* isolate = replacement->GetIsolate(); | 2748 Isolate* isolate = replacement->GetIsolate(); |
2740 // Find substrings of replacement string and create them as String objects. | 2749 // Find substrings of replacement string and create them as String objects. |
2741 int substring_index = 0; | 2750 int substring_index = 0; |
2742 for (int i = 0, n = parts_.length(); i < n; i++) { | 2751 for (int i = 0, n = parts_.length(); i < n; i++) { |
2743 int tag = parts_[i].tag; | 2752 int tag = parts_[i].tag; |
2744 if (tag <= 0) { // A replacement string slice. | 2753 if (tag <= 0) { // A replacement string slice. |
2745 int from = -tag; | 2754 int from = -tag; |
2746 int to = parts_[i].data; | 2755 int to = parts_[i].data; |
2747 replacement_substrings_.Add( | 2756 replacement_substrings_.Add( |
2748 isolate->factory()->NewSubString(replacement, from, to)); | 2757 isolate->factory()->NewSubString(replacement, from, to), zone()); |
2749 parts_[i].tag = REPLACEMENT_SUBSTRING; | 2758 parts_[i].tag = REPLACEMENT_SUBSTRING; |
2750 parts_[i].data = substring_index; | 2759 parts_[i].data = substring_index; |
2751 substring_index++; | 2760 substring_index++; |
2752 } else if (tag == REPLACEMENT_STRING) { | 2761 } else if (tag == REPLACEMENT_STRING) { |
2753 replacement_substrings_.Add(replacement); | 2762 replacement_substrings_.Add(replacement, zone()); |
2754 parts_[i].data = substring_index; | 2763 parts_[i].data = substring_index; |
2755 substring_index++; | 2764 substring_index++; |
2756 } | 2765 } |
2757 } | 2766 } |
2758 } | 2767 } |
2759 | 2768 |
2760 | 2769 |
2761 void CompiledReplacement::Apply(ReplacementStringBuilder* builder, | 2770 void CompiledReplacement::Apply(ReplacementStringBuilder* builder, |
2762 int match_from, | 2771 int match_from, |
2763 int match_to, | 2772 int match_to, |
(...skipping 28 matching lines...) Expand all Loading... |
2792 default: | 2801 default: |
2793 UNREACHABLE(); | 2802 UNREACHABLE(); |
2794 } | 2803 } |
2795 } | 2804 } |
2796 } | 2805 } |
2797 | 2806 |
2798 | 2807 |
2799 void FindAsciiStringIndices(Vector<const char> subject, | 2808 void FindAsciiStringIndices(Vector<const char> subject, |
2800 char pattern, | 2809 char pattern, |
2801 ZoneList<int>* indices, | 2810 ZoneList<int>* indices, |
2802 unsigned int limit) { | 2811 unsigned int limit, |
| 2812 Zone* zone) { |
2803 ASSERT(limit > 0); | 2813 ASSERT(limit > 0); |
2804 // Collect indices of pattern in subject using memchr. | 2814 // Collect indices of pattern in subject using memchr. |
2805 // Stop after finding at most limit values. | 2815 // Stop after finding at most limit values. |
2806 const char* subject_start = reinterpret_cast<const char*>(subject.start()); | 2816 const char* subject_start = reinterpret_cast<const char*>(subject.start()); |
2807 const char* subject_end = subject_start + subject.length(); | 2817 const char* subject_end = subject_start + subject.length(); |
2808 const char* pos = subject_start; | 2818 const char* pos = subject_start; |
2809 while (limit > 0) { | 2819 while (limit > 0) { |
2810 pos = reinterpret_cast<const char*>( | 2820 pos = reinterpret_cast<const char*>( |
2811 memchr(pos, pattern, subject_end - pos)); | 2821 memchr(pos, pattern, subject_end - pos)); |
2812 if (pos == NULL) return; | 2822 if (pos == NULL) return; |
2813 indices->Add(static_cast<int>(pos - subject_start)); | 2823 indices->Add(static_cast<int>(pos - subject_start), zone); |
2814 pos++; | 2824 pos++; |
2815 limit--; | 2825 limit--; |
2816 } | 2826 } |
2817 } | 2827 } |
2818 | 2828 |
2819 | 2829 |
2820 template <typename SubjectChar, typename PatternChar> | 2830 template <typename SubjectChar, typename PatternChar> |
2821 void FindStringIndices(Isolate* isolate, | 2831 void FindStringIndices(Isolate* isolate, |
2822 Vector<const SubjectChar> subject, | 2832 Vector<const SubjectChar> subject, |
2823 Vector<const PatternChar> pattern, | 2833 Vector<const PatternChar> pattern, |
2824 ZoneList<int>* indices, | 2834 ZoneList<int>* indices, |
2825 unsigned int limit) { | 2835 unsigned int limit, |
| 2836 Zone* zone) { |
2826 ASSERT(limit > 0); | 2837 ASSERT(limit > 0); |
2827 // Collect indices of pattern in subject. | 2838 // Collect indices of pattern in subject. |
2828 // Stop after finding at most limit values. | 2839 // Stop after finding at most limit values. |
2829 int pattern_length = pattern.length(); | 2840 int pattern_length = pattern.length(); |
2830 int index = 0; | 2841 int index = 0; |
2831 StringSearch<PatternChar, SubjectChar> search(isolate, pattern); | 2842 StringSearch<PatternChar, SubjectChar> search(isolate, pattern); |
2832 while (limit > 0) { | 2843 while (limit > 0) { |
2833 index = search.Search(subject, index); | 2844 index = search.Search(subject, index); |
2834 if (index < 0) return; | 2845 if (index < 0) return; |
2835 indices->Add(index); | 2846 indices->Add(index, zone); |
2836 index += pattern_length; | 2847 index += pattern_length; |
2837 limit--; | 2848 limit--; |
2838 } | 2849 } |
2839 } | 2850 } |
2840 | 2851 |
2841 | 2852 |
2842 void FindStringIndicesDispatch(Isolate* isolate, | 2853 void FindStringIndicesDispatch(Isolate* isolate, |
2843 String* subject, | 2854 String* subject, |
2844 String* pattern, | 2855 String* pattern, |
2845 ZoneList<int>* indices, | 2856 ZoneList<int>* indices, |
2846 unsigned int limit) { | 2857 unsigned int limit, |
| 2858 Zone* zone) { |
2847 { | 2859 { |
2848 AssertNoAllocation no_gc; | 2860 AssertNoAllocation no_gc; |
2849 String::FlatContent subject_content = subject->GetFlatContent(); | 2861 String::FlatContent subject_content = subject->GetFlatContent(); |
2850 String::FlatContent pattern_content = pattern->GetFlatContent(); | 2862 String::FlatContent pattern_content = pattern->GetFlatContent(); |
2851 ASSERT(subject_content.IsFlat()); | 2863 ASSERT(subject_content.IsFlat()); |
2852 ASSERT(pattern_content.IsFlat()); | 2864 ASSERT(pattern_content.IsFlat()); |
2853 if (subject_content.IsAscii()) { | 2865 if (subject_content.IsAscii()) { |
2854 Vector<const char> subject_vector = subject_content.ToAsciiVector(); | 2866 Vector<const char> subject_vector = subject_content.ToAsciiVector(); |
2855 if (pattern_content.IsAscii()) { | 2867 if (pattern_content.IsAscii()) { |
2856 Vector<const char> pattern_vector = pattern_content.ToAsciiVector(); | 2868 Vector<const char> pattern_vector = pattern_content.ToAsciiVector(); |
2857 if (pattern_vector.length() == 1) { | 2869 if (pattern_vector.length() == 1) { |
2858 FindAsciiStringIndices(subject_vector, | 2870 FindAsciiStringIndices(subject_vector, |
2859 pattern_vector[0], | 2871 pattern_vector[0], |
2860 indices, | 2872 indices, |
2861 limit); | 2873 limit, |
| 2874 zone); |
2862 } else { | 2875 } else { |
2863 FindStringIndices(isolate, | 2876 FindStringIndices(isolate, |
2864 subject_vector, | 2877 subject_vector, |
2865 pattern_vector, | 2878 pattern_vector, |
2866 indices, | 2879 indices, |
2867 limit); | 2880 limit, |
| 2881 zone); |
2868 } | 2882 } |
2869 } else { | 2883 } else { |
2870 FindStringIndices(isolate, | 2884 FindStringIndices(isolate, |
2871 subject_vector, | 2885 subject_vector, |
2872 pattern_content.ToUC16Vector(), | 2886 pattern_content.ToUC16Vector(), |
2873 indices, | 2887 indices, |
2874 limit); | 2888 limit, |
| 2889 zone); |
2875 } | 2890 } |
2876 } else { | 2891 } else { |
2877 Vector<const uc16> subject_vector = subject_content.ToUC16Vector(); | 2892 Vector<const uc16> subject_vector = subject_content.ToUC16Vector(); |
2878 if (pattern_content.IsAscii()) { | 2893 if (pattern_content.IsAscii()) { |
2879 FindStringIndices(isolate, | 2894 FindStringIndices(isolate, |
2880 subject_vector, | 2895 subject_vector, |
2881 pattern_content.ToAsciiVector(), | 2896 pattern_content.ToAsciiVector(), |
2882 indices, | 2897 indices, |
2883 limit); | 2898 limit, |
| 2899 zone); |
2884 } else { | 2900 } else { |
2885 FindStringIndices(isolate, | 2901 FindStringIndices(isolate, |
2886 subject_vector, | 2902 subject_vector, |
2887 pattern_content.ToUC16Vector(), | 2903 pattern_content.ToUC16Vector(), |
2888 indices, | 2904 indices, |
2889 limit); | 2905 limit, |
| 2906 zone); |
2890 } | 2907 } |
2891 } | 2908 } |
2892 } | 2909 } |
2893 } | 2910 } |
2894 | 2911 |
2895 | 2912 |
2896 // Two smis before and after the match, for very long strings. | 2913 // Two smis before and after the match, for very long strings. |
2897 const int kMaxBuilderEntriesPerRegExpMatch = 5; | 2914 const int kMaxBuilderEntriesPerRegExpMatch = 5; |
2898 | 2915 |
2899 | 2916 |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2958 | 2975 |
2959 | 2976 |
2960 | 2977 |
2961 | 2978 |
2962 template<typename ResultSeqString> | 2979 template<typename ResultSeqString> |
2963 MUST_USE_RESULT static MaybeObject* StringReplaceAtomRegExpWithString( | 2980 MUST_USE_RESULT static MaybeObject* StringReplaceAtomRegExpWithString( |
2964 Isolate* isolate, | 2981 Isolate* isolate, |
2965 Handle<String> subject, | 2982 Handle<String> subject, |
2966 Handle<JSRegExp> pattern_regexp, | 2983 Handle<JSRegExp> pattern_regexp, |
2967 Handle<String> replacement, | 2984 Handle<String> replacement, |
2968 Handle<JSArray> last_match_info) { | 2985 Handle<JSArray> last_match_info, |
| 2986 Zone* zone) { |
2969 ASSERT(subject->IsFlat()); | 2987 ASSERT(subject->IsFlat()); |
2970 ASSERT(replacement->IsFlat()); | 2988 ASSERT(replacement->IsFlat()); |
2971 | 2989 |
2972 ZoneScope zone_space(isolate, DELETE_ON_EXIT); | 2990 ZoneScope zone_space(isolate, DELETE_ON_EXIT); |
2973 ZoneList<int> indices(8); | 2991 ZoneList<int> indices(8, isolate->zone()); |
2974 ASSERT_EQ(JSRegExp::ATOM, pattern_regexp->TypeTag()); | 2992 ASSERT_EQ(JSRegExp::ATOM, pattern_regexp->TypeTag()); |
2975 String* pattern = | 2993 String* pattern = |
2976 String::cast(pattern_regexp->DataAt(JSRegExp::kAtomPatternIndex)); | 2994 String::cast(pattern_regexp->DataAt(JSRegExp::kAtomPatternIndex)); |
2977 int subject_len = subject->length(); | 2995 int subject_len = subject->length(); |
2978 int pattern_len = pattern->length(); | 2996 int pattern_len = pattern->length(); |
2979 int replacement_len = replacement->length(); | 2997 int replacement_len = replacement->length(); |
2980 | 2998 |
2981 FindStringIndicesDispatch(isolate, *subject, pattern, &indices, 0xffffffff); | 2999 FindStringIndicesDispatch(isolate, *subject, pattern, &indices, 0xffffffff, |
| 3000 zone); |
2982 | 3001 |
2983 int matches = indices.length(); | 3002 int matches = indices.length(); |
2984 if (matches == 0) return *subject; | 3003 if (matches == 0) return *subject; |
2985 | 3004 |
2986 // Detect integer overflow. | 3005 // Detect integer overflow. |
2987 int64_t result_len_64 = | 3006 int64_t result_len_64 = |
2988 (static_cast<int64_t>(replacement_len) - | 3007 (static_cast<int64_t>(replacement_len) - |
2989 static_cast<int64_t>(pattern_len)) * | 3008 static_cast<int64_t>(pattern_len)) * |
2990 static_cast<int64_t>(matches) + | 3009 static_cast<int64_t>(matches) + |
2991 static_cast<int64_t>(subject_len); | 3010 static_cast<int64_t>(subject_len); |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3040 | 3059 |
3041 return *result; | 3060 return *result; |
3042 } | 3061 } |
3043 | 3062 |
3044 | 3063 |
3045 MUST_USE_RESULT static MaybeObject* StringReplaceRegExpWithString( | 3064 MUST_USE_RESULT static MaybeObject* StringReplaceRegExpWithString( |
3046 Isolate* isolate, | 3065 Isolate* isolate, |
3047 String* subject, | 3066 String* subject, |
3048 JSRegExp* regexp, | 3067 JSRegExp* regexp, |
3049 String* replacement, | 3068 String* replacement, |
3050 JSArray* last_match_info) { | 3069 JSArray* last_match_info, |
| 3070 Zone* zone) { |
3051 ASSERT(subject->IsFlat()); | 3071 ASSERT(subject->IsFlat()); |
3052 ASSERT(replacement->IsFlat()); | 3072 ASSERT(replacement->IsFlat()); |
3053 | 3073 |
3054 HandleScope handles(isolate); | 3074 HandleScope handles(isolate); |
3055 | 3075 |
3056 int length = subject->length(); | 3076 int length = subject->length(); |
3057 Handle<String> subject_handle(subject); | 3077 Handle<String> subject_handle(subject); |
3058 Handle<JSRegExp> regexp_handle(regexp); | 3078 Handle<JSRegExp> regexp_handle(regexp); |
3059 Handle<String> replacement_handle(replacement); | 3079 Handle<String> replacement_handle(replacement); |
3060 Handle<JSArray> last_match_info_handle(last_match_info); | 3080 Handle<JSArray> last_match_info_handle(last_match_info); |
3061 Handle<Object> match = RegExpImpl::Exec(regexp_handle, | 3081 Handle<Object> match = RegExpImpl::Exec(regexp_handle, |
3062 subject_handle, | 3082 subject_handle, |
3063 0, | 3083 0, |
3064 last_match_info_handle, | 3084 last_match_info_handle, |
3065 isolate->zone()); | 3085 isolate->zone()); |
3066 if (match.is_null()) { | 3086 if (match.is_null()) { |
3067 return Failure::Exception(); | 3087 return Failure::Exception(); |
3068 } | 3088 } |
3069 if (match->IsNull()) { | 3089 if (match->IsNull()) { |
3070 return *subject_handle; | 3090 return *subject_handle; |
3071 } | 3091 } |
3072 | 3092 |
3073 int capture_count = regexp_handle->CaptureCount(); | 3093 int capture_count = regexp_handle->CaptureCount(); |
3074 | 3094 |
3075 // CompiledReplacement uses zone allocation. | 3095 // CompiledReplacement uses zone allocation. |
3076 ZoneScope zone(isolate, DELETE_ON_EXIT); | 3096 ZoneScope zonescope(isolate, DELETE_ON_EXIT); |
3077 CompiledReplacement compiled_replacement; | 3097 CompiledReplacement compiled_replacement(isolate->zone()); |
3078 compiled_replacement.Compile(replacement_handle, | 3098 compiled_replacement.Compile(replacement_handle, |
3079 capture_count, | 3099 capture_count, |
3080 length); | 3100 length); |
3081 | 3101 |
3082 bool is_global = regexp_handle->GetFlags().is_global(); | 3102 bool is_global = regexp_handle->GetFlags().is_global(); |
3083 | 3103 |
3084 // Shortcut for simple non-regexp global replacements | 3104 // Shortcut for simple non-regexp global replacements |
3085 if (is_global && | 3105 if (is_global && |
3086 regexp_handle->TypeTag() == JSRegExp::ATOM && | 3106 regexp_handle->TypeTag() == JSRegExp::ATOM && |
3087 compiled_replacement.simple_hint()) { | 3107 compiled_replacement.simple_hint()) { |
3088 if (subject_handle->HasOnlyAsciiChars() && | 3108 if (subject_handle->HasOnlyAsciiChars() && |
3089 replacement_handle->HasOnlyAsciiChars()) { | 3109 replacement_handle->HasOnlyAsciiChars()) { |
3090 return StringReplaceAtomRegExpWithString<SeqAsciiString>( | 3110 return StringReplaceAtomRegExpWithString<SeqAsciiString>( |
3091 isolate, | 3111 isolate, |
3092 subject_handle, | 3112 subject_handle, |
3093 regexp_handle, | 3113 regexp_handle, |
3094 replacement_handle, | 3114 replacement_handle, |
3095 last_match_info_handle); | 3115 last_match_info_handle, |
| 3116 zone); |
3096 } else { | 3117 } else { |
3097 return StringReplaceAtomRegExpWithString<SeqTwoByteString>( | 3118 return StringReplaceAtomRegExpWithString<SeqTwoByteString>( |
3098 isolate, | 3119 isolate, |
3099 subject_handle, | 3120 subject_handle, |
3100 regexp_handle, | 3121 regexp_handle, |
3101 replacement_handle, | 3122 replacement_handle, |
3102 last_match_info_handle); | 3123 last_match_info_handle, |
| 3124 zone); |
3103 } | 3125 } |
3104 } | 3126 } |
3105 | 3127 |
3106 // Guessing the number of parts that the final result string is built | 3128 // Guessing the number of parts that the final result string is built |
3107 // from. Global regexps can match any number of times, so we guess | 3129 // from. Global regexps can match any number of times, so we guess |
3108 // conservatively. | 3130 // conservatively. |
3109 int expected_parts = | 3131 int expected_parts = |
3110 (compiled_replacement.parts() + 1) * (is_global ? 4 : 1) + 1; | 3132 (compiled_replacement.parts() + 1) * (is_global ? 4 : 1) + 1; |
3111 ReplacementStringBuilder builder(isolate->heap(), | 3133 ReplacementStringBuilder builder(isolate->heap(), |
3112 subject_handle, | 3134 subject_handle, |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3175 | 3197 |
3176 return *(builder.ToString()); | 3198 return *(builder.ToString()); |
3177 } | 3199 } |
3178 | 3200 |
3179 | 3201 |
3180 template <typename ResultSeqString> | 3202 template <typename ResultSeqString> |
3181 MUST_USE_RESULT static MaybeObject* StringReplaceRegExpWithEmptyString( | 3203 MUST_USE_RESULT static MaybeObject* StringReplaceRegExpWithEmptyString( |
3182 Isolate* isolate, | 3204 Isolate* isolate, |
3183 String* subject, | 3205 String* subject, |
3184 JSRegExp* regexp, | 3206 JSRegExp* regexp, |
3185 JSArray* last_match_info) { | 3207 JSArray* last_match_info, |
| 3208 Zone* zone) { |
3186 ASSERT(subject->IsFlat()); | 3209 ASSERT(subject->IsFlat()); |
3187 | 3210 |
3188 HandleScope handles(isolate); | 3211 HandleScope handles(isolate); |
3189 | 3212 |
3190 Handle<String> subject_handle(subject); | 3213 Handle<String> subject_handle(subject); |
3191 Handle<JSRegExp> regexp_handle(regexp); | 3214 Handle<JSRegExp> regexp_handle(regexp); |
3192 Handle<JSArray> last_match_info_handle(last_match_info); | 3215 Handle<JSArray> last_match_info_handle(last_match_info); |
3193 | 3216 |
3194 // Shortcut for simple non-regexp global replacements | 3217 // Shortcut for simple non-regexp global replacements |
3195 if (regexp_handle->GetFlags().is_global() && | 3218 if (regexp_handle->GetFlags().is_global() && |
3196 regexp_handle->TypeTag() == JSRegExp::ATOM) { | 3219 regexp_handle->TypeTag() == JSRegExp::ATOM) { |
3197 Handle<String> empty_string_handle(HEAP->empty_string()); | 3220 Handle<String> empty_string_handle(HEAP->empty_string()); |
3198 if (subject_handle->HasOnlyAsciiChars()) { | 3221 if (subject_handle->HasOnlyAsciiChars()) { |
3199 return StringReplaceAtomRegExpWithString<SeqAsciiString>( | 3222 return StringReplaceAtomRegExpWithString<SeqAsciiString>( |
3200 isolate, | 3223 isolate, |
3201 subject_handle, | 3224 subject_handle, |
3202 regexp_handle, | 3225 regexp_handle, |
3203 empty_string_handle, | 3226 empty_string_handle, |
3204 last_match_info_handle); | 3227 last_match_info_handle, |
| 3228 zone); |
3205 } else { | 3229 } else { |
3206 return StringReplaceAtomRegExpWithString<SeqTwoByteString>( | 3230 return StringReplaceAtomRegExpWithString<SeqTwoByteString>( |
3207 isolate, | 3231 isolate, |
3208 subject_handle, | 3232 subject_handle, |
3209 regexp_handle, | 3233 regexp_handle, |
3210 empty_string_handle, | 3234 empty_string_handle, |
3211 last_match_info_handle); | 3235 last_match_info_handle, |
| 3236 zone); |
3212 } | 3237 } |
3213 } | 3238 } |
3214 | 3239 |
3215 Handle<Object> match = RegExpImpl::Exec(regexp_handle, | 3240 Handle<Object> match = RegExpImpl::Exec(regexp_handle, |
3216 subject_handle, | 3241 subject_handle, |
3217 0, | 3242 0, |
3218 last_match_info_handle, | 3243 last_match_info_handle, |
3219 isolate->zone()); | 3244 isolate->zone()); |
3220 if (match.is_null()) return Failure::Exception(); | 3245 if (match.is_null()) return Failure::Exception(); |
3221 if (match->IsNull()) return *subject_handle; | 3246 if (match->IsNull()) return *subject_handle; |
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3360 } | 3385 } |
3361 } | 3386 } |
3362 replacement = String::cast(flat_replacement); | 3387 replacement = String::cast(flat_replacement); |
3363 } | 3388 } |
3364 | 3389 |
3365 CONVERT_ARG_CHECKED(JSRegExp, regexp, 1); | 3390 CONVERT_ARG_CHECKED(JSRegExp, regexp, 1); |
3366 CONVERT_ARG_CHECKED(JSArray, last_match_info, 3); | 3391 CONVERT_ARG_CHECKED(JSArray, last_match_info, 3); |
3367 | 3392 |
3368 ASSERT(last_match_info->HasFastObjectElements()); | 3393 ASSERT(last_match_info->HasFastObjectElements()); |
3369 | 3394 |
| 3395 Zone* zone = isolate->zone(); |
3370 if (replacement->length() == 0) { | 3396 if (replacement->length() == 0) { |
3371 if (subject->HasOnlyAsciiChars()) { | 3397 if (subject->HasOnlyAsciiChars()) { |
3372 return StringReplaceRegExpWithEmptyString<SeqAsciiString>( | 3398 return StringReplaceRegExpWithEmptyString<SeqAsciiString>( |
3373 isolate, subject, regexp, last_match_info); | 3399 isolate, subject, regexp, last_match_info, zone); |
3374 } else { | 3400 } else { |
3375 return StringReplaceRegExpWithEmptyString<SeqTwoByteString>( | 3401 return StringReplaceRegExpWithEmptyString<SeqTwoByteString>( |
3376 isolate, subject, regexp, last_match_info); | 3402 isolate, subject, regexp, last_match_info, zone); |
3377 } | 3403 } |
3378 } | 3404 } |
3379 | 3405 |
3380 return StringReplaceRegExpWithString(isolate, | 3406 return StringReplaceRegExpWithString(isolate, |
3381 subject, | 3407 subject, |
3382 regexp, | 3408 regexp, |
3383 replacement, | 3409 replacement, |
3384 last_match_info); | 3410 last_match_info, |
| 3411 zone); |
3385 } | 3412 } |
3386 | 3413 |
3387 | 3414 |
3388 Handle<String> Runtime::StringReplaceOneCharWithString(Isolate* isolate, | 3415 Handle<String> Runtime::StringReplaceOneCharWithString(Isolate* isolate, |
3389 Handle<String> subject, | 3416 Handle<String> subject, |
3390 Handle<String> search, | 3417 Handle<String> search, |
3391 Handle<String> replace, | 3418 Handle<String> replace, |
3392 bool* found, | 3419 bool* found, |
3393 int recursion_limit) { | 3420 int recursion_limit) { |
3394 if (recursion_limit == 0) return Handle<String>::null(); | 3421 if (recursion_limit == 0) return Handle<String>::null(); |
(...skipping 313 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3708 isolate->zone()); | 3735 isolate->zone()); |
3709 | 3736 |
3710 if (match.is_null()) { | 3737 if (match.is_null()) { |
3711 return Failure::Exception(); | 3738 return Failure::Exception(); |
3712 } | 3739 } |
3713 if (match->IsNull()) { | 3740 if (match->IsNull()) { |
3714 return isolate->heap()->null_value(); | 3741 return isolate->heap()->null_value(); |
3715 } | 3742 } |
3716 int length = subject->length(); | 3743 int length = subject->length(); |
3717 | 3744 |
| 3745 Zone* zone = isolate->zone(); |
3718 ZoneScope zone_space(isolate, DELETE_ON_EXIT); | 3746 ZoneScope zone_space(isolate, DELETE_ON_EXIT); |
3719 ZoneList<int> offsets(8); | 3747 ZoneList<int> offsets(8, zone); |
3720 int start; | 3748 int start; |
3721 int end; | 3749 int end; |
3722 do { | 3750 do { |
3723 { | 3751 { |
3724 AssertNoAllocation no_alloc; | 3752 AssertNoAllocation no_alloc; |
3725 FixedArray* elements = FixedArray::cast(regexp_info->elements()); | 3753 FixedArray* elements = FixedArray::cast(regexp_info->elements()); |
3726 start = Smi::cast(elements->get(RegExpImpl::kFirstCapture))->value(); | 3754 start = Smi::cast(elements->get(RegExpImpl::kFirstCapture))->value(); |
3727 end = Smi::cast(elements->get(RegExpImpl::kFirstCapture + 1))->value(); | 3755 end = Smi::cast(elements->get(RegExpImpl::kFirstCapture + 1))->value(); |
3728 } | 3756 } |
3729 offsets.Add(start); | 3757 offsets.Add(start, zone); |
3730 offsets.Add(end); | 3758 offsets.Add(end, zone); |
3731 if (start == end) if (++end > length) break; | 3759 if (start == end) if (++end > length) break; |
3732 match = RegExpImpl::Exec(regexp, subject, end, regexp_info, | 3760 match = RegExpImpl::Exec(regexp, subject, end, regexp_info, |
3733 isolate->zone()); | 3761 isolate->zone()); |
3734 if (match.is_null()) { | 3762 if (match.is_null()) { |
3735 return Failure::Exception(); | 3763 return Failure::Exception(); |
3736 } | 3764 } |
3737 } while (!match->IsNull()); | 3765 } while (!match->IsNull()); |
3738 int matches = offsets.length() / 2; | 3766 int matches = offsets.length() / 2; |
3739 Handle<FixedArray> elements = isolate->factory()->NewFixedArray(matches); | 3767 Handle<FixedArray> elements = isolate->factory()->NewFixedArray(matches); |
3740 Handle<String> substring = isolate->factory()-> | 3768 Handle<String> substring = isolate->factory()-> |
(...skipping 2685 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6426 } | 6454 } |
6427 | 6455 |
6428 // The limit can be very large (0xffffffffu), but since the pattern | 6456 // The limit can be very large (0xffffffffu), but since the pattern |
6429 // isn't empty, we can never create more parts than ~half the length | 6457 // isn't empty, we can never create more parts than ~half the length |
6430 // of the subject. | 6458 // of the subject. |
6431 | 6459 |
6432 if (!subject->IsFlat()) FlattenString(subject); | 6460 if (!subject->IsFlat()) FlattenString(subject); |
6433 | 6461 |
6434 static const int kMaxInitialListCapacity = 16; | 6462 static const int kMaxInitialListCapacity = 16; |
6435 | 6463 |
| 6464 Zone* zone = isolate->zone(); |
6436 ZoneScope scope(isolate, DELETE_ON_EXIT); | 6465 ZoneScope scope(isolate, DELETE_ON_EXIT); |
6437 | 6466 |
6438 // Find (up to limit) indices of separator and end-of-string in subject | 6467 // Find (up to limit) indices of separator and end-of-string in subject |
6439 int initial_capacity = Min<uint32_t>(kMaxInitialListCapacity, limit); | 6468 int initial_capacity = Min<uint32_t>(kMaxInitialListCapacity, limit); |
6440 ZoneList<int> indices(initial_capacity); | 6469 ZoneList<int> indices(initial_capacity, zone); |
6441 if (!pattern->IsFlat()) FlattenString(pattern); | 6470 if (!pattern->IsFlat()) FlattenString(pattern); |
6442 | 6471 |
6443 FindStringIndicesDispatch(isolate, *subject, *pattern, &indices, limit); | 6472 FindStringIndicesDispatch(isolate, *subject, *pattern, &indices, limit, zone); |
6444 | 6473 |
6445 if (static_cast<uint32_t>(indices.length()) < limit) { | 6474 if (static_cast<uint32_t>(indices.length()) < limit) { |
6446 indices.Add(subject_length); | 6475 indices.Add(subject_length, zone); |
6447 } | 6476 } |
6448 | 6477 |
6449 // The list indices now contains the end of each part to create. | 6478 // The list indices now contains the end of each part to create. |
6450 | 6479 |
6451 // Create JSArray of substrings separated by separator. | 6480 // Create JSArray of substrings separated by separator. |
6452 int part_count = indices.length(); | 6481 int part_count = indices.length(); |
6453 | 6482 |
6454 Handle<JSArray> result = isolate->factory()->NewJSArray(part_count); | 6483 Handle<JSArray> result = isolate->factory()->NewJSArray(part_count); |
6455 MaybeObject* maybe_result = result->EnsureCanContainHeapObjectElements(); | 6484 MaybeObject* maybe_result = result->EnsureCanContainHeapObjectElements(); |
6456 if (maybe_result->IsFailure()) return maybe_result; | 6485 if (maybe_result->IsFailure()) return maybe_result; |
(...skipping 2818 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9275 if (!global->IsJSGlobalObject()) return isolate->heap()->null_value(); | 9304 if (!global->IsJSGlobalObject()) return isolate->heap()->null_value(); |
9276 return JSGlobalObject::cast(global)->global_receiver(); | 9305 return JSGlobalObject::cast(global)->global_receiver(); |
9277 } | 9306 } |
9278 | 9307 |
9279 | 9308 |
9280 RUNTIME_FUNCTION(MaybeObject*, Runtime_ParseJson) { | 9309 RUNTIME_FUNCTION(MaybeObject*, Runtime_ParseJson) { |
9281 HandleScope scope(isolate); | 9310 HandleScope scope(isolate); |
9282 ASSERT_EQ(1, args.length()); | 9311 ASSERT_EQ(1, args.length()); |
9283 CONVERT_ARG_HANDLE_CHECKED(String, source, 0); | 9312 CONVERT_ARG_HANDLE_CHECKED(String, source, 0); |
9284 | 9313 |
| 9314 Zone* zone = isolate->zone(); |
9285 source = Handle<String>(source->TryFlattenGetString()); | 9315 source = Handle<String>(source->TryFlattenGetString()); |
9286 // Optimized fast case where we only have ASCII characters. | 9316 // Optimized fast case where we only have ASCII characters. |
9287 Handle<Object> result; | 9317 Handle<Object> result; |
9288 if (source->IsSeqAsciiString()) { | 9318 if (source->IsSeqAsciiString()) { |
9289 result = JsonParser<true>::Parse(source); | 9319 result = JsonParser<true>::Parse(source, zone); |
9290 } else { | 9320 } else { |
9291 result = JsonParser<false>::Parse(source); | 9321 result = JsonParser<false>::Parse(source, zone); |
9292 } | 9322 } |
9293 if (result.is_null()) { | 9323 if (result.is_null()) { |
9294 // Syntax error or stack overflow in scanner. | 9324 // Syntax error or stack overflow in scanner. |
9295 ASSERT(isolate->has_pending_exception()); | 9325 ASSERT(isolate->has_pending_exception()); |
9296 return Failure::Exception(); | 9326 return Failure::Exception(); |
9297 } | 9327 } |
9298 return *result; | 9328 return *result; |
9299 } | 9329 } |
9300 | 9330 |
9301 | 9331 |
(...skipping 3435 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12737 // For array of SharedFunctionInfo's (each wrapped in JSValue) | 12767 // For array of SharedFunctionInfo's (each wrapped in JSValue) |
12738 // checks that none of them have activations on stacks (of any thread). | 12768 // checks that none of them have activations on stacks (of any thread). |
12739 // Returns array of the same length with corresponding results of | 12769 // Returns array of the same length with corresponding results of |
12740 // LiveEdit::FunctionPatchabilityStatus type. | 12770 // LiveEdit::FunctionPatchabilityStatus type. |
12741 RUNTIME_FUNCTION(MaybeObject*, Runtime_LiveEditCheckAndDropActivations) { | 12771 RUNTIME_FUNCTION(MaybeObject*, Runtime_LiveEditCheckAndDropActivations) { |
12742 ASSERT(args.length() == 2); | 12772 ASSERT(args.length() == 2); |
12743 HandleScope scope(isolate); | 12773 HandleScope scope(isolate); |
12744 CONVERT_ARG_HANDLE_CHECKED(JSArray, shared_array, 0); | 12774 CONVERT_ARG_HANDLE_CHECKED(JSArray, shared_array, 0); |
12745 CONVERT_BOOLEAN_ARG_CHECKED(do_drop, 1); | 12775 CONVERT_BOOLEAN_ARG_CHECKED(do_drop, 1); |
12746 | 12776 |
12747 return *LiveEdit::CheckAndDropActivations(shared_array, do_drop); | 12777 return *LiveEdit::CheckAndDropActivations(shared_array, do_drop, |
| 12778 isolate->zone()); |
12748 } | 12779 } |
12749 | 12780 |
12750 // Compares 2 strings line-by-line, then token-wise and returns diff in form | 12781 // Compares 2 strings line-by-line, then token-wise and returns diff in form |
12751 // of JSArray of triplets (pos1, pos1_end, pos2_end) describing list | 12782 // of JSArray of triplets (pos1, pos1_end, pos2_end) describing list |
12752 // of diff chunks. | 12783 // of diff chunks. |
12753 RUNTIME_FUNCTION(MaybeObject*, Runtime_LiveEditCompareStrings) { | 12784 RUNTIME_FUNCTION(MaybeObject*, Runtime_LiveEditCompareStrings) { |
12754 ASSERT(args.length() == 2); | 12785 ASSERT(args.length() == 2); |
12755 HandleScope scope(isolate); | 12786 HandleScope scope(isolate); |
12756 CONVERT_ARG_HANDLE_CHECKED(String, s1, 0); | 12787 CONVERT_ARG_HANDLE_CHECKED(String, s1, 0); |
12757 CONVERT_ARG_HANDLE_CHECKED(String, s2, 1); | 12788 CONVERT_ARG_HANDLE_CHECKED(String, s2, 1); |
(...skipping 805 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13563 // Handle last resort GC and make sure to allow future allocations | 13594 // Handle last resort GC and make sure to allow future allocations |
13564 // to grow the heap without causing GCs (if possible). | 13595 // to grow the heap without causing GCs (if possible). |
13565 isolate->counters()->gc_last_resort_from_js()->Increment(); | 13596 isolate->counters()->gc_last_resort_from_js()->Increment(); |
13566 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, | 13597 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, |
13567 "Runtime::PerformGC"); | 13598 "Runtime::PerformGC"); |
13568 } | 13599 } |
13569 } | 13600 } |
13570 | 13601 |
13571 | 13602 |
13572 } } // namespace v8::internal | 13603 } } // namespace v8::internal |
OLD | NEW |