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

Side by Side Diff: src/runtime.cc

Issue 6076: Added special case for atomic regular expressions. (Closed)
Patch Set: Created 12 years, 2 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
« no previous file with comments | « src/runtime.h ('k') | src/unicode.h » ('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 2006-2008 the V8 project authors. All rights reserved. 1 // Copyright 2006-2008 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 233 matching lines...) Expand 10 before | Expand all | Expand 10 after
244 244
245 static Object* Runtime_RegExpCompile(Arguments args) { 245 static Object* Runtime_RegExpCompile(Arguments args) {
246 HandleScope scope; // create a new handle scope 246 HandleScope scope; // create a new handle scope
247 ASSERT(args.length() == 3); 247 ASSERT(args.length() == 3);
248 CONVERT_CHECKED(JSRegExp, raw_re, args[0]); 248 CONVERT_CHECKED(JSRegExp, raw_re, args[0]);
249 Handle<JSRegExp> re(raw_re); 249 Handle<JSRegExp> re(raw_re);
250 CONVERT_CHECKED(String, raw_pattern, args[1]); 250 CONVERT_CHECKED(String, raw_pattern, args[1]);
251 Handle<String> pattern(raw_pattern); 251 Handle<String> pattern(raw_pattern);
252 CONVERT_CHECKED(String, raw_flags, args[2]); 252 CONVERT_CHECKED(String, raw_flags, args[2]);
253 Handle<String> flags(raw_flags); 253 Handle<String> flags(raw_flags);
254 return *RegExpImpl::JsreCompile(re, pattern, flags); 254 return *RegExpImpl::Compile(re, pattern, flags);
255 } 255 }
256 256
257 257
258 static Object* Runtime_CreateApiFunction(Arguments args) { 258 static Object* Runtime_CreateApiFunction(Arguments args) {
259 HandleScope scope; 259 HandleScope scope;
260 ASSERT(args.length() == 1); 260 ASSERT(args.length() == 1);
261 CONVERT_CHECKED(FunctionTemplateInfo, raw_data, args[0]); 261 CONVERT_CHECKED(FunctionTemplateInfo, raw_data, args[0]);
262 Handle<FunctionTemplateInfo> data(raw_data); 262 Handle<FunctionTemplateInfo> data(raw_data);
263 return *Factory::CreateApiFunction(data); 263 return *Factory::CreateApiFunction(data);
264 } 264 }
(...skipping 432 matching lines...) Expand 10 before | Expand all | Expand 10 after
697 697
698 static Object* Runtime_RegExpExec(Arguments args) { 698 static Object* Runtime_RegExpExec(Arguments args) {
699 HandleScope scope; 699 HandleScope scope;
700 ASSERT(args.length() == 3); 700 ASSERT(args.length() == 3);
701 CONVERT_CHECKED(JSRegExp, raw_regexp, args[0]); 701 CONVERT_CHECKED(JSRegExp, raw_regexp, args[0]);
702 Handle<JSRegExp> regexp(raw_regexp); 702 Handle<JSRegExp> regexp(raw_regexp);
703 CONVERT_CHECKED(String, raw_subject, args[1]); 703 CONVERT_CHECKED(String, raw_subject, args[1]);
704 Handle<String> subject(raw_subject); 704 Handle<String> subject(raw_subject);
705 Handle<Object> index(args[2]); 705 Handle<Object> index(args[2]);
706 ASSERT(index->IsNumber()); 706 ASSERT(index->IsNumber());
707 return *RegExpImpl::JsreExec(regexp, subject, index); 707 return *RegExpImpl::Exec(regexp, subject, index);
708 } 708 }
709 709
710 710
711 static Object* Runtime_RegExpExecGlobal(Arguments args) { 711 static Object* Runtime_RegExpExecGlobal(Arguments args) {
712 HandleScope scope; 712 HandleScope scope;
713 ASSERT(args.length() == 2); 713 ASSERT(args.length() == 2);
714 CONVERT_CHECKED(JSRegExp, raw_regexp, args[0]); 714 CONVERT_CHECKED(JSRegExp, raw_regexp, args[0]);
715 Handle<JSRegExp> regexp(raw_regexp); 715 Handle<JSRegExp> regexp(raw_regexp);
716 CONVERT_CHECKED(String, raw_subject, args[1]); 716 CONVERT_CHECKED(String, raw_subject, args[1]);
717 Handle<String> subject(raw_subject); 717 Handle<String> subject(raw_subject);
718 return *RegExpImpl::JsreExecGlobal(regexp, subject); 718 return *RegExpImpl::ExecGlobal(regexp, subject);
719 } 719 }
720 720
721 721
722 static Object* Runtime_MaterializeRegExpLiteral(Arguments args) { 722 static Object* Runtime_MaterializeRegExpLiteral(Arguments args) {
723 HandleScope scope; 723 HandleScope scope;
724 ASSERT(args.length() == 4); 724 ASSERT(args.length() == 4);
725 CONVERT_ARG_CHECKED(FixedArray, literals, 0); 725 CONVERT_ARG_CHECKED(FixedArray, literals, 0);
726 int index = Smi::cast(args[1])->value(); 726 int index = Smi::cast(args[1])->value();
727 Handle<String> pattern = args.at<String>(2); 727 Handle<String> pattern = args.at<String>(2);
728 Handle<String> flags = args.at<String>(3); 728 Handle<String> flags = args.at<String>(3);
(...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after
935 p = buffer->GetNext(); 935 p = buffer->GetNext();
936 if (p == pattern->Get(j)) { 936 if (p == pattern->Get(j)) {
937 next_table[i] = next_table[j]; 937 next_table[i] = next_table[j];
938 } else { 938 } else {
939 next_table[i] = j; 939 next_table[i] = j;
940 } 940 }
941 } 941 }
942 } 942 }
943 943
944 944
945 static Object* Runtime_StringIndexOf(Arguments args) { 945 int Runtime::StringMatchKmp(String* sub, String* pat, int start_index) {
946 NoHandleAllocation ha;
947 ASSERT(args.length() == 3);
948
949 CONVERT_CHECKED(String, sub, args[0]);
950 CONVERT_CHECKED(String, pat, args[1]);
951 Object* index = args[2];
952
953 sub->TryFlatten(); 946 sub->TryFlatten();
954 pat->TryFlatten(); 947 pat->TryFlatten();
955 948
956 int subject_length = sub->length(); 949 int subject_length = sub->length();
957 int pattern_length = pat->length(); 950 int pattern_length = pat->length();
958 951
959 uint32_t start_index; 952 if (start_index > subject_length) return -1;
960 if (!Array::IndexFromObject(index, &start_index)) return Smi::FromInt(-1); 953 if (pattern_length == 0) return start_index;
961 if (pattern_length == 0) return Smi::FromInt(start_index);
962 954
963 // Searching for one specific character is common. For one 955 // Searching for one specific character is common. For one
964 // character patterns the KMP algorithm is guaranteed to slow down 956 // character patterns the KMP algorithm is guaranteed to slow down
965 // the search, so we just run through the subject string. 957 // the search, so we just run through the subject string.
966 if (pattern_length == 1) { 958 if (pattern_length == 1) {
967 uint16_t pattern_char = pat->Get(0); 959 uint16_t pattern_char = pat->Get(0);
968 for (int i = start_index; i < subject_length; i++) { 960 for (int i = start_index; i < subject_length; i++) {
969 if (sub->Get(i) == pattern_char) { 961 if (sub->Get(i) == pattern_char) {
970 return Smi::FromInt(i); 962 return i;
971 } 963 }
972 } 964 }
973 return Smi::FromInt(-1); 965 return -1;
974 } 966 }
975 967
976 // For small searches, KMP is not worth the setup overhead. 968 // For small searches, KMP is not worth the setup overhead.
977 if (subject_length < 100) { 969 if (subject_length < 100) {
978 // We know our pattern is at least 2 characters, we cache the first so 970 // We know our pattern is at least 2 characters, we cache the first so
979 // the common case of the first character not matching is faster. 971 // the common case of the first character not matching is faster.
980 uint16_t pattern_first_char = pat->Get(0); 972 uint16_t pattern_first_char = pat->Get(0);
981 for (int i = start_index; i + pattern_length <= subject_length; i++) { 973 for (int i = start_index; i + pattern_length <= subject_length; i++) {
982 if (sub->Get(i) != pattern_first_char) continue; 974 if (sub->Get(i) != pattern_first_char) continue;
983 975
984 for (int j = 1; j < pattern_length; j++) { 976 for (int j = 1; j < pattern_length; j++) {
985 if (pat->Get(j) != sub->Get(j + i)) break; 977 if (pat->Get(j) != sub->Get(j + i)) break;
986 if (j == pattern_length - 1) return Smi::FromInt(i); 978 if (j == pattern_length - 1) return i;
987 } 979 }
988 } 980 }
989 return Smi::FromInt(-1); 981 return -1;
990 } 982 }
991 983
992 // For patterns with a larger length we use the KMP algorithm. 984 // For patterns with a larger length we use the KMP algorithm.
993 // 985 //
994 // Compute the 'next' table. 986 // Compute the 'next' table.
995 int* next_table = NewArray<int>(pattern_length); 987 int* next_table = NewArray<int>(pattern_length);
996 ComputeKMPNextTable(pat, next_table); 988 ComputeKMPNextTable(pat, next_table);
997 // Search using the 'next' table. 989 // Search using the 'next' table.
998 int pattern_index = 0; 990 int pattern_index = 0;
999 // We would like to use StringInputBuffer here, but it does not have 991 // We would like to use StringInputBuffer here, but it does not have
1000 // the ability to start anywhere but the first character of a 992 // the ability to start anywhere but the first character of a
1001 // string. It would be nice to have efficient forward-seeking 993 // string. It would be nice to have efficient forward-seeking
1002 // support on StringInputBuffers. 994 // support on StringInputBuffers.
1003 int subject_index = start_index; 995 int subject_index = start_index;
1004 while (subject_index < subject_length) { 996 while (subject_index < subject_length) {
1005 uint16_t subject_char = sub->Get(subject_index); 997 uint16_t subject_char = sub->Get(subject_index);
1006 while (pattern_index > -1 && pat->Get(pattern_index) != subject_char) { 998 while (pattern_index > -1 && pat->Get(pattern_index) != subject_char) {
1007 pattern_index = next_table[pattern_index]; 999 pattern_index = next_table[pattern_index];
1008 } 1000 }
1009 pattern_index++; 1001 pattern_index++;
1010 subject_index++; 1002 subject_index++;
1011 if (pattern_index >= pattern_length) { 1003 if (pattern_index >= pattern_length) {
1012 DeleteArray(next_table); 1004 DeleteArray(next_table);
1013 return Smi::FromInt(subject_index - pattern_index); 1005 return subject_index - pattern_index;
1014 } 1006 }
1015 } 1007 }
1016 DeleteArray(next_table); 1008 DeleteArray(next_table);
1017 return Smi::FromInt(-1); 1009 return -1;
1018 } 1010 }
1019 1011
1020 1012
1013 static Object* Runtime_StringIndexOf(Arguments args) {
1014 NoHandleAllocation ha;
1015 ASSERT(args.length() == 3);
1016
1017 CONVERT_CHECKED(String, sub, args[0]);
1018 CONVERT_CHECKED(String, pat, args[1]);
1019 Object* index = args[2];
1020 uint32_t start_index;
1021 if (!Array::IndexFromObject(index, &start_index)) return Smi::FromInt(-1);
1022
1023 return Smi::FromInt(Runtime::StringMatchKmp(sub, pat, start_index));
1024 }
1025
1026
1021 static Object* Runtime_StringLastIndexOf(Arguments args) { 1027 static Object* Runtime_StringLastIndexOf(Arguments args) {
1022 NoHandleAllocation ha; 1028 NoHandleAllocation ha;
1023 ASSERT(args.length() == 3); 1029 ASSERT(args.length() == 3);
1024 1030
1025 CONVERT_CHECKED(String, sub, args[0]); 1031 CONVERT_CHECKED(String, sub, args[0]);
1026 CONVERT_CHECKED(String, pat, args[1]); 1032 CONVERT_CHECKED(String, pat, args[1]);
1027 Object* index = args[2]; 1033 Object* index = args[2];
1028 1034
1029 sub->TryFlatten(); 1035 sub->TryFlatten();
1030 pat->TryFlatten(); 1036 pat->TryFlatten();
(...skipping 3985 matching lines...) Expand 10 before | Expand all | Expand 10 after
5016 5022
5017 void Runtime::PerformGC(Object* result) { 5023 void Runtime::PerformGC(Object* result) {
5018 Failure* failure = Failure::cast(result); 5024 Failure* failure = Failure::cast(result);
5019 // Try to do a garbage collection; ignore it if it fails. The C 5025 // Try to do a garbage collection; ignore it if it fails. The C
5020 // entry stub will throw an out-of-memory exception in that case. 5026 // entry stub will throw an out-of-memory exception in that case.
5021 Heap::CollectGarbage(failure->requested(), failure->allocation_space()); 5027 Heap::CollectGarbage(failure->requested(), failure->allocation_space());
5022 } 5028 }
5023 5029
5024 5030
5025 } } // namespace v8::internal 5031 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/runtime.h ('k') | src/unicode.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698