Changeset 184346 in webkit
- Timestamp:
- May 14, 2015 12:07:30 PM (9 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r184344 r184346 1 2015-05-14 Andreas Kling <akling@apple.com> 2 3 String.prototype.split() should create efficient substrings. 4 <https://webkit.org/b/144985> 5 <rdar://problem/20949344> 6 7 Reviewed by Geoffrey Garen. 8 9 Teach split() how to make substring JSStrings instead of relying on StringImpl's 10 substring sharing mechanism. The optimization works by deferring the construction 11 of a StringImpl until the substring's value is actually needed. 12 13 This knocks ~2MB off of theverge.com by avoiding the extra StringImpl allocations. 14 Out of ~70000 substrings created by split(), only ~2000 of them get reified. 15 16 * runtime/StringPrototype.cpp: 17 (JSC::jsSubstring): 18 (JSC::splitStringByOneCharacterImpl): 19 (JSC::stringProtoFuncSplit): 20 1 21 2015-05-14 Yusuke Suzuki <utatane.tea@gmail.com> 2 22 -
trunk/Source/JavaScriptCore/runtime/StringPrototype.cpp
r183694 r184346 176 176 } 177 177 178 // Helper that tries to use the JSString substring sharing mechanism if 'originalValue' is a JSString. 179 static inline JSString* jsSubstring(ExecState* exec, JSValue originalValue, const String& string, unsigned offset, unsigned length) 180 { 181 if (originalValue.isString()) { 182 ASSERT(asString(originalValue)->value(exec) == string); 183 return jsSubstring(exec, asString(originalValue), offset, length); 184 } 185 return jsSubstring(exec, string, offset, length); 186 } 187 178 188 static NEVER_INLINE String substituteBackreferencesSlow(StringView replacement, StringView source, const int* ovector, RegExp* reg, size_t i) 179 189 { … … 1054 1064 // Return true in case of early return (resultLength got to limitLength). 1055 1065 template<typename CharacterType> 1056 static ALWAYS_INLINE bool splitStringByOneCharacterImpl(ExecState* exec, JSArray* result, const String& input, StringImpl* string, UChar separatorCharacter, size_t& position, unsigned& resultLength, unsigned limitLength)1066 static ALWAYS_INLINE bool splitStringByOneCharacterImpl(ExecState* exec, JSArray* result, JSValue originalValue, const String& input, StringImpl* string, UChar separatorCharacter, size_t& position, unsigned& resultLength, unsigned limitLength) 1057 1067 { 1058 1068 // 12. Let q = p. … … 1068 1078 // 2. Call the [[DefineOwnProperty]] internal method of A with arguments ToString(lengthA), 1069 1079 // Property Descriptor {[[Value]]: T, [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: true}, and false. 1070 result->putDirectIndex(exec, resultLength, jsSubstring(exec, input, position, matchPosition - position));1080 result->putDirectIndex(exec, resultLength, jsSubstring(exec, originalValue, input, position, matchPosition - position)); 1071 1081 // 3. Increment lengthA by 1. 1072 1082 // 4. If lengthA == lim, return A. … … 1174 1184 // 2. Call the [[DefineOwnProperty]] internal method of A with arguments ToString(lengthA), 1175 1185 // Property Descriptor {[[Value]]: T, [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: true}, and false. 1176 result->putDirectIndex(exec, resultLength, jsSubstring(exec, input, position, matchPosition - position));1186 result->putDirectIndex(exec, resultLength, jsSubstring(exec, thisValue, input, position, matchPosition - position)); 1177 1187 1178 1188 // 3. Increment lengthA by 1. … … 1194 1204 // true, [[Enumerable]]: true, [[Configurable]]: true}, and false. 1195 1205 int sub = ovector[i * 2]; 1196 result->putDirectIndex(exec, resultLength, sub < 0 ? jsUndefined() : jsSubstring(exec, input, sub, ovector[i * 2 + 1] - sub));1206 result->putDirectIndex(exec, resultLength, sub < 0 ? jsUndefined() : jsSubstring(exec, thisValue, input, sub, ovector[i * 2 + 1] - sub)); 1197 1207 // c Increment lengthA by 1. 1198 1208 // d If lengthA == lim, return A. … … 1259 1269 1260 1270 if (stringImpl->is8Bit()) { 1261 if (splitStringByOneCharacterImpl<LChar>(exec, result, input, stringImpl, separatorCharacter, position, resultLength, limit))1271 if (splitStringByOneCharacterImpl<LChar>(exec, result, thisValue, input, stringImpl, separatorCharacter, position, resultLength, limit)) 1262 1272 return JSValue::encode(result); 1263 1273 } else { 1264 if (splitStringByOneCharacterImpl<UChar>(exec, result, input, stringImpl, separatorCharacter, position, resultLength, limit))1274 if (splitStringByOneCharacterImpl<UChar>(exec, result, thisValue, input, stringImpl, separatorCharacter, position, resultLength, limit)) 1265 1275 return JSValue::encode(result); 1266 1276 } … … 1277 1287 // 2. Call the [[DefineOwnProperty]] internal method of A with arguments ToString(lengthA), 1278 1288 // Property Descriptor {[[Value]]: T, [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: true}, and false. 1279 result->putDirectIndex(exec, resultLength, jsSubstring(exec, input, position, matchPosition - position));1289 result->putDirectIndex(exec, resultLength, jsSubstring(exec, thisValue, input, position, matchPosition - position)); 1280 1290 // 3. Increment lengthA by 1. 1281 1291 // 4. If lengthA == lim, return A. … … 1294 1304 // 15. Call the [[DefineOwnProperty]] internal method of A with arguments ToString(lengthA), Property Descriptor 1295 1305 // {[[Value]]: T, [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: true}, and false. 1296 result->putDirectIndex(exec, resultLength++, jsSubstring(exec, input, position, input.length() - position));1306 result->putDirectIndex(exec, resultLength++, jsSubstring(exec, thisValue, input, position, input.length() - position)); 1297 1307 1298 1308 // 16. Return A.
Note: See TracChangeset
for help on using the changeset viewer.