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

Side by Side Diff: src/runtime/runtime-regexp.cc

Issue 1418703003: RegExp: remove last match info override. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: fix Created 5 years, 1 month 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
« no previous file with comments | « src/regexp/jsregexp.cc ('k') | test/mjsunit/regexp-static.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 the V8 project authors. All rights reserved. 1 // Copyright 2014 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/runtime/runtime-utils.h" 5 #include "src/runtime/runtime-utils.h"
6 6
7 #include "src/arguments.h" 7 #include "src/arguments.h"
8 #include "src/conversions-inl.h" 8 #include "src/conversions-inl.h"
9 #include "src/isolate-inl.h" 9 #include "src/isolate-inl.h"
10 #include "src/messages.h" 10 #include "src/messages.h"
(...skipping 675 matching lines...) Expand 10 before | Expand all | Expand 10 after
686 CONVERT_ARG_HANDLE_CHECKED(String, subject, 0); 686 CONVERT_ARG_HANDLE_CHECKED(String, subject, 0);
687 CONVERT_ARG_HANDLE_CHECKED(String, pattern, 1); 687 CONVERT_ARG_HANDLE_CHECKED(String, pattern, 1);
688 CONVERT_NUMBER_CHECKED(uint32_t, limit, Uint32, args[2]); 688 CONVERT_NUMBER_CHECKED(uint32_t, limit, Uint32, args[2]);
689 RUNTIME_ASSERT(limit > 0); 689 RUNTIME_ASSERT(limit > 0);
690 690
691 int subject_length = subject->length(); 691 int subject_length = subject->length();
692 int pattern_length = pattern->length(); 692 int pattern_length = pattern->length();
693 RUNTIME_ASSERT(pattern_length > 0); 693 RUNTIME_ASSERT(pattern_length > 0);
694 694
695 if (limit == 0xffffffffu) { 695 if (limit == 0xffffffffu) {
696 FixedArray* last_match_cache_unused;
696 Handle<Object> cached_answer( 697 Handle<Object> cached_answer(
697 RegExpResultsCache::Lookup(isolate->heap(), *subject, *pattern, 698 RegExpResultsCache::Lookup(isolate->heap(), *subject, *pattern,
699 &last_match_cache_unused,
698 RegExpResultsCache::STRING_SPLIT_SUBSTRINGS), 700 RegExpResultsCache::STRING_SPLIT_SUBSTRINGS),
699 isolate); 701 isolate);
700 if (*cached_answer != Smi::FromInt(0)) { 702 if (*cached_answer != Smi::FromInt(0)) {
701 // The cache FixedArray is a COW-array and can therefore be reused. 703 // The cache FixedArray is a COW-array and can therefore be reused.
702 Handle<JSArray> result = isolate->factory()->NewJSArrayWithElements( 704 Handle<JSArray> result = isolate->factory()->NewJSArrayWithElements(
703 Handle<FixedArray>::cast(cached_answer)); 705 Handle<FixedArray>::cast(cached_answer));
704 return *result; 706 return *result;
705 } 707 }
706 } 708 }
707 709
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
750 Handle<String> substring = 752 Handle<String> substring =
751 isolate->factory()->NewProperSubString(subject, part_start, part_end); 753 isolate->factory()->NewProperSubString(subject, part_start, part_end);
752 elements->set(i, *substring); 754 elements->set(i, *substring);
753 part_start = part_end + pattern_length; 755 part_start = part_end + pattern_length;
754 } 756 }
755 } 757 }
756 758
757 if (limit == 0xffffffffu) { 759 if (limit == 0xffffffffu) {
758 if (result->HasFastObjectElements()) { 760 if (result->HasFastObjectElements()) {
759 RegExpResultsCache::Enter(isolate, subject, pattern, elements, 761 RegExpResultsCache::Enter(isolate, subject, pattern, elements,
762 isolate->factory()->empty_fixed_array(),
760 RegExpResultsCache::STRING_SPLIT_SUBSTRINGS); 763 RegExpResultsCache::STRING_SPLIT_SUBSTRINGS);
761 } 764 }
762 } 765 }
763 766
764 return *result; 767 return *result;
765 } 768 }
766 769
767 770
768 RUNTIME_FUNCTION(Runtime_RegExpExec) { 771 RUNTIME_FUNCTION(Runtime_RegExpExec) {
769 HandleScope scope(isolate); 772 HandleScope scope(isolate);
(...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after
1010 Handle<JSArray> result_array) { 1013 Handle<JSArray> result_array) {
1011 DCHECK(subject->IsFlat()); 1014 DCHECK(subject->IsFlat());
1012 DCHECK_NE(has_capture, regexp->CaptureCount() == 0); 1015 DCHECK_NE(has_capture, regexp->CaptureCount() == 0);
1013 1016
1014 int capture_count = regexp->CaptureCount(); 1017 int capture_count = regexp->CaptureCount();
1015 int subject_length = subject->length(); 1018 int subject_length = subject->length();
1016 1019
1017 static const int kMinLengthToCache = 0x1000; 1020 static const int kMinLengthToCache = 0x1000;
1018 1021
1019 if (subject_length > kMinLengthToCache) { 1022 if (subject_length > kMinLengthToCache) {
1020 Handle<Object> cached_answer( 1023 FixedArray* last_match_cache;
1021 RegExpResultsCache::Lookup(isolate->heap(), *subject, regexp->data(), 1024 Object* cached_answer = RegExpResultsCache::Lookup(
1022 RegExpResultsCache::REGEXP_MULTIPLE_INDICES), 1025 isolate->heap(), *subject, regexp->data(), &last_match_cache,
1023 isolate); 1026 RegExpResultsCache::REGEXP_MULTIPLE_INDICES);
1024 if (*cached_answer != Smi::FromInt(0)) { 1027 if (cached_answer->IsFixedArray()) {
1028 int capture_registers = (capture_count + 1) * 2;
1029 int32_t* last_match = NewArray<int32_t>(capture_registers);
1030 for (int i = 0; i < capture_registers; i++) {
1031 last_match[i] = Smi::cast(last_match_cache->get(i))->value();
1032 }
1025 Handle<FixedArray> cached_fixed_array = 1033 Handle<FixedArray> cached_fixed_array =
1026 Handle<FixedArray>(FixedArray::cast(*cached_answer)); 1034 Handle<FixedArray>(FixedArray::cast(cached_answer));
1027 // The cache FixedArray is a COW-array and can therefore be reused. 1035 // The cache FixedArray is a COW-array and can therefore be reused.
1028 JSArray::SetContent(result_array, cached_fixed_array); 1036 JSArray::SetContent(result_array, cached_fixed_array);
1029 // The actual length of the result array is stored in the last element of
1030 // the backing store (the backing FixedArray may have a larger capacity).
1031 Object* cached_fixed_array_last_element =
1032 cached_fixed_array->get(cached_fixed_array->length() - 1);
1033 Smi* js_array_length = Smi::cast(cached_fixed_array_last_element);
1034 result_array->set_length(js_array_length);
1035 RegExpImpl::SetLastMatchInfo(last_match_array, subject, capture_count, 1037 RegExpImpl::SetLastMatchInfo(last_match_array, subject, capture_count,
1036 NULL); 1038 last_match);
1039 DeleteArray(last_match);
1037 return *result_array; 1040 return *result_array;
1038 } 1041 }
1039 } 1042 }
1040 1043
1041 RegExpImpl::GlobalCache global_cache(regexp, subject, true, isolate); 1044 RegExpImpl::GlobalCache global_cache(regexp, subject, true, isolate);
1042 if (global_cache.HasException()) return isolate->heap()->exception(); 1045 if (global_cache.HasException()) return isolate->heap()->exception();
1043 1046
1044 // Ensured in Runtime_RegExpExecMultiple. 1047 // Ensured in Runtime_RegExpExecMultiple.
1045 DCHECK(result_array->HasFastObjectElements()); 1048 DCHECK(result_array->HasFastObjectElements());
1046 Handle<FixedArray> result_elements( 1049 Handle<FixedArray> result_elements(
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
1114 if (global_cache.HasException()) return isolate->heap()->exception(); 1117 if (global_cache.HasException()) return isolate->heap()->exception();
1115 1118
1116 if (match_start >= 0) { 1119 if (match_start >= 0) {
1117 // Finished matching, with at least one match. 1120 // Finished matching, with at least one match.
1118 if (match_end < subject_length) { 1121 if (match_end < subject_length) {
1119 ReplacementStringBuilder::AddSubjectSlice(&builder, match_end, 1122 ReplacementStringBuilder::AddSubjectSlice(&builder, match_end,
1120 subject_length); 1123 subject_length);
1121 } 1124 }
1122 1125
1123 RegExpImpl::SetLastMatchInfo(last_match_array, subject, capture_count, 1126 RegExpImpl::SetLastMatchInfo(last_match_array, subject, capture_count,
1124 NULL); 1127 global_cache.LastSuccessfulMatch());
1125 1128
1126 if (subject_length > kMinLengthToCache) { 1129 if (subject_length > kMinLengthToCache) {
1127 // Store the length of the result array into the last element of the 1130 // Store the last successful match into the array for caching.
1128 // backing FixedArray. 1131 // TODO(yangguo): do not expose last match to JS and simplify caching.
1129 builder.EnsureCapacity(1); 1132 int capture_registers = (capture_count + 1) * 2;
1130 Handle<FixedArray> fixed_array = builder.array(); 1133 Handle<FixedArray> last_match_cache =
1131 fixed_array->set(fixed_array->length() - 1, 1134 isolate->factory()->NewFixedArray(capture_registers);
1132 Smi::FromInt(builder.length())); 1135 int32_t* last_match = global_cache.LastSuccessfulMatch();
1136 for (int i = 0; i < capture_registers; i++) {
1137 last_match_cache->set(i, Smi::FromInt(last_match[i]));
1138 }
1139 Handle<FixedArray> result_array = builder.array();
brucedawson 2015/10/28 17:19:36 I'm worried about this variable declaration. The r
Yang 2015/10/29 12:55:27 Thanks. See https://codereview.chromium.org/140721
1140 result_array->Shrink(builder.length());
1133 // Cache the result and turn the FixedArray into a COW array. 1141 // Cache the result and turn the FixedArray into a COW array.
1134 RegExpResultsCache::Enter(isolate, subject, 1142 RegExpResultsCache::Enter(
1135 handle(regexp->data(), isolate), fixed_array, 1143 isolate, subject, handle(regexp->data(), isolate), result_array,
1136 RegExpResultsCache::REGEXP_MULTIPLE_INDICES); 1144 last_match_cache, RegExpResultsCache::REGEXP_MULTIPLE_INDICES);
1137 } 1145 }
1138 return *builder.ToJSArray(result_array); 1146 return *builder.ToJSArray(result_array);
1139 } else { 1147 } else {
1140 return isolate->heap()->null_value(); // No matches at all. 1148 return isolate->heap()->null_value(); // No matches at all.
1141 } 1149 }
1142 } 1150 }
1143 1151
1144 1152
1145 // This is only called for StringReplaceGlobalRegExpWithFunction. This sets 1153 // This is only called for StringReplaceGlobalRegExpWithFunction. This sets
1146 // lastMatchInfoOverride to maintain the last match info, so we don't need to 1154 // lastMatchInfoOverride to maintain the last match info, so we don't need to
1147 // set any other last match array info. 1155 // set any other last match array info.
1148 RUNTIME_FUNCTION(Runtime_RegExpExecMultiple) { 1156 RUNTIME_FUNCTION(Runtime_RegExpExecMultiple) {
1149 HandleScope handles(isolate); 1157 HandleScope handles(isolate);
1150 DCHECK(args.length() == 4); 1158 DCHECK(args.length() == 4);
1151 1159
1160 CONVERT_ARG_HANDLE_CHECKED(JSRegExp, regexp, 0);
1152 CONVERT_ARG_HANDLE_CHECKED(String, subject, 1); 1161 CONVERT_ARG_HANDLE_CHECKED(String, subject, 1);
1153 CONVERT_ARG_HANDLE_CHECKED(JSRegExp, regexp, 0);
1154 CONVERT_ARG_HANDLE_CHECKED(JSArray, last_match_info, 2); 1162 CONVERT_ARG_HANDLE_CHECKED(JSArray, last_match_info, 2);
1155 CONVERT_ARG_HANDLE_CHECKED(JSArray, result_array, 3); 1163 CONVERT_ARG_HANDLE_CHECKED(JSArray, result_array, 3);
1156 RUNTIME_ASSERT(last_match_info->HasFastObjectElements()); 1164 RUNTIME_ASSERT(last_match_info->HasFastObjectElements());
1157 RUNTIME_ASSERT(result_array->HasFastObjectElements()); 1165 RUNTIME_ASSERT(result_array->HasFastObjectElements());
1158 1166
1159 subject = String::Flatten(subject); 1167 subject = String::Flatten(subject);
1160 RUNTIME_ASSERT(regexp->GetFlags().is_global()); 1168 RUNTIME_ASSERT(regexp->GetFlags().is_global());
1161 1169
1162 if (regexp->CaptureCount() == 0) { 1170 if (regexp->CaptureCount() == 0) {
1163 return SearchRegExpMultiple<false>(isolate, subject, regexp, 1171 return SearchRegExpMultiple<false>(isolate, subject, regexp,
(...skipping 15 matching lines...) Expand all
1179 1187
1180 1188
1181 RUNTIME_FUNCTION(Runtime_IsRegExp) { 1189 RUNTIME_FUNCTION(Runtime_IsRegExp) {
1182 SealHandleScope shs(isolate); 1190 SealHandleScope shs(isolate);
1183 DCHECK(args.length() == 1); 1191 DCHECK(args.length() == 1);
1184 CONVERT_ARG_CHECKED(Object, obj, 0); 1192 CONVERT_ARG_CHECKED(Object, obj, 0);
1185 return isolate->heap()->ToBoolean(obj->IsJSRegExp()); 1193 return isolate->heap()->ToBoolean(obj->IsJSRegExp());
1186 } 1194 }
1187 } // namespace internal 1195 } // namespace internal
1188 } // namespace v8 1196 } // namespace v8
OLDNEW
« no previous file with comments | « src/regexp/jsregexp.cc ('k') | test/mjsunit/regexp-static.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698