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

Side by Side Diff: src/harmony-string.js

Issue 401783003: Optimize algorithm for String.prototype.repeat(), fix value caching in others (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 5 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
« AUTHORS ('K') | « AUTHORS ('k') | src/string.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 'use strict'; 5 'use strict';
6 6
7 // This file relies on the fact that the following declaration has been made 7 // This file relies on the fact that the following declaration has been made
8 // in runtime.js: 8 // in runtime.js:
9 // var $String = global.String; 9 // var $String = global.String;
10 // var $Array = global.Array; 10 // var $Array = global.Array;
11 11
12 // ------------------------------------------------------------------- 12 // -------------------------------------------------------------------
13 13
14 // ES6 draft 01-20-14, section 21.1.3.13 14 // ES6 draft 01-20-14, section 21.1.3.13
15 function StringRepeat(count) { 15 function StringRepeat(count) {
16 CHECK_OBJECT_COERCIBLE(this, "String.prototype.repeat"); 16 CHECK_OBJECT_COERCIBLE(this, "String.prototype.repeat");
17 17
18 var s = TO_STRING_INLINE(this); 18 var s = TO_STRING_INLINE(this);
19 var n = ToInteger(count); 19 var n = ToInteger(count);
20 if (n < 0 || !NUMBER_IS_FINITE(n)) { 20 if (n < 0 || !NUMBER_IS_FINITE(n)) {
21 throw MakeRangeError("invalid_count_value", []); 21 throw MakeRangeError("invalid_count_value", []);
22 } 22 }
23 23
24 var elements = new InternalArray(n); 24 if (n < 1) return '';
Michael Starzinger 2014/07/28 11:13:52 This special case is not needed if comment below i
25 for (var i = 0; i < n; i++) { 25
26 elements[i] = s; 26 // Optimized O(log N) algorithm, without the added overhead of an extra array
Michael Starzinger 2014/07/28 11:13:51 nit: Let's drop (at least) the second half of the
27 var res = '';
28
29 while (n > 1) {
Michael Starzinger 2014/07/28 11:13:51 If we change the predicate to be "n > 0" most spec
30 if (n & 1) res += s;
31 n >>= 1;
32 s += s;
27 } 33 }
28 34 return res + s;
Michael Starzinger 2014/07/28 11:13:51 This addition is not needed if comment above is ad
29 return %StringBuilderConcat(elements, n, "");
30 } 35 }
31 36
32 37
33 // ES6 draft 04-05-14, section 21.1.3.18 38 // ES6 draft 04-05-14, section 21.1.3.18
34 function StringStartsWith(searchString /* position */) { // length == 1 39 function StringStartsWith(searchString /* position */) { // length == 1
35 CHECK_OBJECT_COERCIBLE(this, "String.prototype.startsWith"); 40 CHECK_OBJECT_COERCIBLE(this, "String.prototype.startsWith");
36 41
37 var s = TO_STRING_INLINE(this); 42 var s = TO_STRING_INLINE(this);
38 43
39 if (IS_REGEXP(searchString)) { 44 if (IS_REGEXP(searchString)) {
40 throw MakeTypeError("first_argument_not_regexp", 45 throw MakeTypeError("first_argument_not_regexp",
41 ["String.prototype.startsWith"]); 46 ["String.prototype.startsWith"]);
42 } 47 }
43 48
44 var ss = TO_STRING_INLINE(searchString); 49 var ss = TO_STRING_INLINE(searchString);
45 var pos = 0; 50 var pos = 0;
46 if (%_ArgumentsLength() > 1) { 51 if (%_ArgumentsLength() > 1) {
47 pos = %_Arguments(1); // position 52 pos = %_Arguments(1); // position
48 pos = ToInteger(pos); 53 pos = ToInteger(pos);
49 } 54 }
50 55
51 var s_len = s.length; 56 var s_len = s.length;
52 var start = MathMin(MathMax(pos, 0), s_len); 57 var start = MathMin(MathMax(pos, 0), s_len);
53 var ss_len = ss.length; 58 if (ss.length + start > s_len) {
54 if (ss_len + start > s_len) {
55 return false; 59 return false;
56 } 60 }
57 61
58 return %StringIndexOf(s, ss, start) === start; 62 return %StringIndexOf(s, ss, start) === start;
59 } 63 }
60 64
61 65
62 // ES6 draft 04-05-14, section 21.1.3.7 66 // ES6 draft 04-05-14, section 21.1.3.7
63 function StringEndsWith(searchString /* position */) { // length == 1 67 function StringEndsWith(searchString /* position */) { // length == 1
64 CHECK_OBJECT_COERCIBLE(this, "String.prototype.endsWith"); 68 CHECK_OBJECT_COERCIBLE(this, "String.prototype.endsWith");
65 69
66 var s = TO_STRING_INLINE(this); 70 var s = TO_STRING_INLINE(this);
67 71
68 if (IS_REGEXP(searchString)) { 72 if (IS_REGEXP(searchString)) {
69 throw MakeTypeError("first_argument_not_regexp", 73 throw MakeTypeError("first_argument_not_regexp",
70 ["String.prototype.endsWith"]); 74 ["String.prototype.endsWith"]);
71 } 75 }
72 76
73 var ss = TO_STRING_INLINE(searchString); 77 var ss = TO_STRING_INLINE(searchString);
74 var s_len = s.length; 78 var s_len = s.length;
75 var pos = s_len; 79 var pos = s_len;
76 if (%_ArgumentsLength() > 1) { 80 if (%_ArgumentsLength() > 1) {
77 var arg = %_Arguments(1); // position 81 var arg = %_Arguments(1); // position
78 if (!IS_UNDEFINED(arg)) { 82 if (!IS_UNDEFINED(arg)) {
79 pos = ToInteger(arg); 83 pos = ToInteger(arg);
80 } 84 }
81 } 85 }
82 86
83 var end = MathMin(MathMax(pos, 0), s_len); 87 var end = MathMin(MathMax(pos, 0), s_len);
84 var ss_len = ss.length; 88 var start = end - ss.length;
85 var start = end - ss_len;
86 if (start < 0) { 89 if (start < 0) {
87 return false; 90 return false;
88 } 91 }
89 92
90 return %StringLastIndexOf(s, ss, start) === start; 93 return %StringLastIndexOf(s, ss, start) === start;
91 } 94 }
92 95
93 96
94 // ES6 draft 04-05-14, section 21.1.3.6 97 // ES6 draft 04-05-14, section 21.1.3.6
95 function StringContains(searchString /* position */) { // length == 1 98 function StringContains(searchString /* position */) { // length == 1
96 CHECK_OBJECT_COERCIBLE(this, "String.prototype.contains"); 99 CHECK_OBJECT_COERCIBLE(this, "String.prototype.contains");
97 100
98 var s = TO_STRING_INLINE(this); 101 var s = TO_STRING_INLINE(this);
99 102
100 if (IS_REGEXP(searchString)) { 103 if (IS_REGEXP(searchString)) {
101 throw MakeTypeError("first_argument_not_regexp", 104 throw MakeTypeError("first_argument_not_regexp",
102 ["String.prototype.contains"]); 105 ["String.prototype.contains"]);
103 } 106 }
104 107
105 var ss = TO_STRING_INLINE(searchString); 108 var ss = TO_STRING_INLINE(searchString);
106 var pos = 0; 109 var pos = 0;
107 if (%_ArgumentsLength() > 1) { 110 if (%_ArgumentsLength() > 1) {
108 pos = %_Arguments(1); // position 111 pos = %_Arguments(1); // position
109 pos = ToInteger(pos); 112 pos = ToInteger(pos);
110 } 113 }
111 114
112 var s_len = s.length; 115 var s_len = s.length;
113 var start = MathMin(MathMax(pos, 0), s_len); 116 var start = MathMin(MathMax(pos, 0), s_len);
114 var ss_len = ss.length; 117 if (ss.length + start > s_len) {
115 if (ss_len + start > s_len) {
116 return false; 118 return false;
117 } 119 }
118 120
119 return %StringIndexOf(s, ss, start) !== -1; 121 return %StringIndexOf(s, ss, start) !== -1;
120 } 122 }
121 123
122 124
123 // ------------------------------------------------------------------- 125 // -------------------------------------------------------------------
124 126
125 function ExtendStringPrototype() { 127 function ExtendStringPrototype() {
126 %CheckIsBootstrapping(); 128 %CheckIsBootstrapping();
127 129
128 // Set up the non-enumerable functions on the String prototype object. 130 // Set up the non-enumerable functions on the String prototype object.
129 InstallFunctions($String.prototype, DONT_ENUM, $Array( 131 InstallFunctions($String.prototype, DONT_ENUM, $Array(
130 "repeat", StringRepeat, 132 "repeat", StringRepeat,
131 "startsWith", StringStartsWith, 133 "startsWith", StringStartsWith,
132 "endsWith", StringEndsWith, 134 "endsWith", StringEndsWith,
133 "contains", StringContains 135 "contains", StringContains
134 )); 136 ));
135 } 137 }
136 138
137 ExtendStringPrototype(); 139 ExtendStringPrototype();
OLDNEW
« AUTHORS ('K') | « AUTHORS ('k') | src/string.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698