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

Side by Side Diff: src/string.js

Issue 1556019: Avoid unnecessary cloning of regexp answer (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 10 years, 8 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
« src/regexp.js ('K') | « src/regexp.js ('k') | 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 152 matching lines...) Expand 10 before | Expand all | Expand 10 after
163 163
164 164
165 // ECMA-262 section 15.5.4.10 165 // ECMA-262 section 15.5.4.10
166 function StringMatch(regexp) { 166 function StringMatch(regexp) {
167 if (!IS_REGEXP(regexp)) regexp = new $RegExp(regexp); 167 if (!IS_REGEXP(regexp)) regexp = new $RegExp(regexp);
168 var subject = TO_STRING_INLINE(this); 168 var subject = TO_STRING_INLINE(this);
169 169
170 if (!regexp.global) return regexp.exec(subject); 170 if (!regexp.global) return regexp.exec(subject);
171 171
172 var cache = regExpCache; 172 var cache = regExpCache;
173 var saveAnswer = false;
173 174
174 if (%_ObjectEquals(cache.type, 'match') && 175 if (%_ObjectEquals(cache.type, 'match') &&
175 %_ObjectEquals(cache.regExp, regexp) && 176 %_ObjectEquals(cache.regExp, regexp) &&
176 %_ObjectEquals(cache.subject, subject)) { 177 %_ObjectEquals(cache.subject, subject)) {
177 var last = cache.answer; 178 if (cache.answerSaved) {
178 if (last == null) { 179 return CloneRegexpAnswer(cache.answer);
179 return last;
180 } else { 180 } else {
181 return CloneRegexpAnswer(last); 181 saveAnswer = true;
182 } 182 }
183 } 183 }
184 184
185 %_Log('regexp', 'regexp-match,%0S,%1r', [subject, regexp]); 185 %_Log('regexp', 'regexp-match,%0S,%1r', [subject, regexp]);
186 // lastMatchInfo is defined in regexp.js. 186 // lastMatchInfo is defined in regexp.js.
187 var result = %StringMatch(subject, regexp, lastMatchInfo); 187 var result = %StringMatch(subject, regexp, lastMatchInfo);
188 cache.type = 'match'; 188 cache.type = 'match';
189 cache.regExp = regexp; 189 cache.regExp = regexp;
190 cache.subject = subject; 190 cache.subject = subject;
191 cache.answer = result; 191 if (saveAnswer) cache.answer = CloneRegexpAnswer(result);
192 if (result == null) { 192 cache.answerSaved = saveAnswer;
193 return result; 193 return result;
194 } else {
195 return CloneRegexpAnswer(result);
196 }
197 } 194 }
198 195
199 196
200 // SubString is an internal function that returns the sub string of 'string'. 197 // SubString is an internal function that returns the sub string of 'string'.
201 // If resulting string is of length 1, we use the one character cache 198 // If resulting string is of length 1, we use the one character cache
202 // otherwise we call the runtime system. 199 // otherwise we call the runtime system.
203 function SubString(string, start, end) { 200 function SubString(string, start, end) {
204 // Use the one character string cache. 201 // Use the one character string cache.
205 if (start + 1 == end) { 202 if (start + 1 == end) {
206 var char_code = %_FastCharCodeAt(string, start); 203 var char_code = %_FastCharCodeAt(string, start);
(...skipping 382 matching lines...) Expand 10 before | Expand all | Expand 10 after
589 586
590 // If the separator string is empty then return the elements in the subject. 587 // If the separator string is empty then return the elements in the subject.
591 if (separator_length === 0) return %StringToArray(subject); 588 if (separator_length === 0) return %StringToArray(subject);
592 589
593 var result = %StringSplit(subject, separator, limit); 590 var result = %StringSplit(subject, separator, limit);
594 591
595 return result; 592 return result;
596 } 593 }
597 594
598 var cache = regExpCache; 595 var cache = regExpCache;
596 var saveAnswer = false;
599 597
600 if (%_ObjectEquals(cache.type, 'split') && 598 if (%_ObjectEquals(cache.type, 'split') &&
601 %_ObjectEquals(cache.regExp, separator) && 599 %_ObjectEquals(cache.regExp, separator) &&
602 %_ObjectEquals(cache.subject, subject)) { 600 %_ObjectEquals(cache.subject, subject)) {
603 return CloneRegexpAnswer(cache.answer); 601 if (cache.answerSaved) {
602 return CloneRegexpAnswer(cache.answer);
603 } else {
604 saveAnswer = true;
605 }
604 } 606 }
605 607
606 cache.type = 'split'; 608 cache.type = 'split';
607 cache.regExp = separator; 609 cache.regExp = separator;
608 cache.subject = subject; 610 cache.subject = subject;
609 611
610 %_Log('regexp', 'regexp-split,%0S,%1r', [subject, separator]); 612 %_Log('regexp', 'regexp-split,%0S,%1r', [subject, separator]);
611 613
612 if (length === 0) { 614 if (length === 0) {
615 cache.answerSaved = true;
613 if (splitMatch(separator, subject, 0, 0) != null) { 616 if (splitMatch(separator, subject, 0, 0) != null) {
614 cache.answer = []; 617 cache.answer = [];
615 return []; 618 return [];
616 } 619 }
617 cache.answer = [subject]; 620 cache.answer = [subject];
618 return [subject]; 621 return [subject];
619 } 622 }
620 623
621 var currentIndex = 0; 624 var currentIndex = 0;
622 var startIndex = 0; 625 var startIndex = 0;
623 var result = []; 626 var result = [];
624 627
628 outer_loop:
625 while (true) { 629 while (true) {
626 630
627 if (startIndex === length) { 631 if (startIndex === length) {
628 result[result.length] = subject.slice(currentIndex, length); 632 result[result.length] = subject.slice(currentIndex, length);
629 cache.answer = result; 633 break;
630 return CloneRegexpAnswer(result);
631 } 634 }
632 635
633 var matchInfo = splitMatch(separator, subject, currentIndex, startIndex); 636 var matchInfo = splitMatch(separator, subject, currentIndex, startIndex);
634 637
635 if (IS_NULL(matchInfo)) { 638 if (IS_NULL(matchInfo)) {
636 result[result.length] = subject.slice(currentIndex, length); 639 result[result.length] = subject.slice(currentIndex, length);
637 cache.answer = result; 640 break;
638 return CloneRegexpAnswer(result);
639 } 641 }
640 642
641 var endIndex = matchInfo[CAPTURE1]; 643 var endIndex = matchInfo[CAPTURE1];
642 644
643 // We ignore a zero-length match at the currentIndex. 645 // We ignore a zero-length match at the currentIndex.
644 if (startIndex === endIndex && endIndex === currentIndex) { 646 if (startIndex === endIndex && endIndex === currentIndex) {
645 startIndex++; 647 startIndex++;
646 continue; 648 continue;
647 } 649 }
648 650
649 result[result.length] = SubString(subject, currentIndex, matchInfo[CAPTURE0] ); 651 result[result.length] = SubString(subject, currentIndex, matchInfo[CAPTURE0] );
650 if (result.length === limit) { 652 if (result.length === limit) break;
651 cache.answer = result;
652 return CloneRegexpAnswer(result);
653 }
654 653
655 var num_captures = NUMBER_OF_CAPTURES(matchInfo); 654 var num_captures = NUMBER_OF_CAPTURES(matchInfo);
656 for (var i = 2; i < num_captures; i += 2) { 655 for (var i = 2; i < num_captures; i += 2) {
657 var start = matchInfo[CAPTURE(i)]; 656 var start = matchInfo[CAPTURE(i)];
658 var end = matchInfo[CAPTURE(i + 1)]; 657 var end = matchInfo[CAPTURE(i + 1)];
659 if (start != -1 && end != -1) { 658 if (start != -1 && end != -1) {
660 result[result.length] = SubString(subject, start, end); 659 result[result.length] = SubString(subject, start, end);
661 } else { 660 } else {
662 result[result.length] = void 0; 661 result[result.length] = void 0;
663 } 662 }
664 if (result.length === limit) { 663 if (result.length === limit) break outer_loop;
665 cache.answer = result;
666 return CloneRegexpAnswer(result);
667 }
668 } 664 }
669 665
670 startIndex = currentIndex = endIndex; 666 startIndex = currentIndex = endIndex;
671 } 667 }
668 if (saveAnswer) cache.answer = CloneRegexpAnswer(result);
669 cache.answerSaved = saveAnswer;
670 return result;
671
672 } 672 }
673 673
674 674
675 // ECMA-262 section 15.5.4.14 675 // ECMA-262 section 15.5.4.14
676 // Helper function used by split. This version returns the matchInfo 676 // Helper function used by split. This version returns the matchInfo
677 // instead of allocating a new array with basically the same information. 677 // instead of allocating a new array with basically the same information.
678 function splitMatch(separator, subject, current_index, start_index) { 678 function splitMatch(separator, subject, current_index, start_index) {
679 var matchInfo = DoRegExpExec(separator, subject, start_index); 679 var matchInfo = DoRegExpExec(separator, subject, start_index);
680 if (matchInfo == null) return null; 680 if (matchInfo == null) return null;
681 // Section 15.5.4.14 paragraph two says that we do not allow zero length 681 // Section 15.5.4.14 paragraph two says that we do not allow zero length
(...skipping 303 matching lines...) Expand 10 before | Expand all | Expand 10 after
985 "small", StringSmall, 985 "small", StringSmall,
986 "strike", StringStrike, 986 "strike", StringStrike,
987 "sub", StringSub, 987 "sub", StringSub,
988 "sup", StringSup, 988 "sup", StringSup,
989 "toJSON", StringToJSON 989 "toJSON", StringToJSON
990 )); 990 ));
991 } 991 }
992 992
993 993
994 SetupString(); 994 SetupString();
OLDNEW
« src/regexp.js ('K') | « src/regexp.js ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698