Changeset 241233 in webkit
- Timestamp:
- Feb 8, 2019 8:40:22 PM (5 years ago)
- Location:
- trunk
- Files:
-
- 1 added
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JSTests/ChangeLog
r241228 r241233 1 2019-02-08 Yusuke Suzuki <ysuzuki@apple.com> 2 3 [JSC] String.fromCharCode's slow path always generates 16bit string 4 https://bugs.webkit.org/show_bug.cgi?id=194466 5 6 Reviewed by Keith Miller. 7 8 * stress/string-from-char-code-slow-path.js: Added. 9 (shouldBe): 10 (testWithLength): 11 1 12 2019-02-08 Saam barati <sbarati@apple.com> 2 13 -
trunk/Source/JavaScriptCore/ChangeLog
r241230 r241233 1 2019-02-08 Yusuke Suzuki <ysuzuki@apple.com> 2 3 [JSC] String.fromCharCode's slow path always generates 16bit string 4 https://bugs.webkit.org/show_bug.cgi?id=194466 5 6 Reviewed by Keith Miller. 7 8 String.fromCharCode(a1) has a fast path and the most frequently used. And String.fromCharCode(a1, a2, ...) 9 goes to the slow path. However, in the slow path, we always create 16bit string. 16bit string takes 2x memory, 10 and even worse, taints ropes 16bit if 16bit string is included in the given rope. We find that acorn-wtb 11 creates very large strings multiple times with String.fromCharCode, and String.fromCharCode always produces 12 16bit string. However, only few strings are actually 16bit strings. This patch attempts to make 8bit string 13 as much as possible. 14 15 It improves non JIT acorn-wtb's peak and current memory footprint by 6% and 3% respectively. 16 17 * runtime/StringConstructor.cpp: 18 (JSC::stringFromCharCode): 19 1 20 2019-02-08 Keith Miller <keith_miller@apple.com> 2 21 -
trunk/Source/JavaScriptCore/runtime/StringConstructor.cpp
r236697 r241233 84 84 } 85 85 86 UChar* buf;87 auto impl = StringImpl::createUninitialized(length, buf);86 LChar* buf8Bit; 87 auto impl8Bit = StringImpl::createUninitialized(length, buf8Bit); 88 88 for (unsigned i = 0; i < length; ++i) { 89 buf[i]= static_cast<UChar>(exec->uncheckedArgument(i).toUInt32(exec));89 UChar character = static_cast<UChar>(exec->uncheckedArgument(i).toUInt32(exec)); 90 90 RETURN_IF_EXCEPTION(scope, encodedJSValue()); 91 if (UNLIKELY(!isLatin1(character))) { 92 UChar* buf16Bit; 93 auto impl16Bit = StringImpl::createUninitialized(length, buf16Bit); 94 StringImpl::copyCharacters(buf16Bit, buf8Bit, i); 95 buf16Bit[i] = character; 96 ++i; 97 for (; i < length; ++i) { 98 buf16Bit[i] = static_cast<UChar>(exec->uncheckedArgument(i).toUInt32(exec)); 99 RETURN_IF_EXCEPTION(scope, encodedJSValue()); 100 } 101 RELEASE_AND_RETURN(scope, JSValue::encode(jsString(exec, WTFMove(impl16Bit)))); 102 } 103 buf8Bit[i] = static_cast<LChar>(character); 91 104 } 92 RELEASE_AND_RETURN(scope, JSValue::encode(jsString(exec, WTFMove(impl ))));105 RELEASE_AND_RETURN(scope, JSValue::encode(jsString(exec, WTFMove(impl8Bit)))); 93 106 } 94 107 -
trunk/Source/WTF/wtf/text/StringImpl.cpp
r239439 r241233 290 290 291 291 for (size_t i = 0; i < length; ++i) { 292 if ( characters[i] & 0xFF00)292 if (!isLatin1(characters[i])) 293 293 return create(characters, length); 294 294 data[i] = static_cast<LChar>(characters[i]); … … 415 415 data8[i] = toASCIILower(character); 416 416 else { 417 ASSERT( u_tolower(character) <= 0xFF);417 ASSERT(isLatin1(u_tolower(character))); 418 418 data8[i] = static_cast<LChar>(u_tolower(character)); 419 419 } … … 460 460 ASSERT(u_toupper(character) <= 0xFFFF); 461 461 UChar upper = u_toupper(character); 462 if (UNLIKELY( upper > 0xFF)) {462 if (UNLIKELY(!isLatin1(upper))) { 463 463 // Since this upper-cased character does not fit in an 8-bit string, we need to take the 16-bit path. 464 464 goto upconvert; … … 481 481 *dest++ = 'S'; 482 482 } else { 483 ASSERT( u_toupper(character) <= 0xFF);483 ASSERT(isLatin1(u_toupper(character))); 484 484 *dest++ = static_cast<LChar>(u_toupper(character)); 485 485 } … … 629 629 data8[i] = toASCIILower(character); 630 630 else { 631 ASSERT( u_foldCase(character, U_FOLD_CASE_DEFAULT) <= 0xFF);631 ASSERT(isLatin1(u_foldCase(character, U_FOLD_CASE_DEFAULT))); 632 632 data8[i] = static_cast<LChar>(u_foldCase(character, U_FOLD_CASE_DEFAULT)); 633 633 } … … 1254 1254 1255 1255 if (is8Bit()) { 1256 if ( target > 0xFF) {1256 if (!isLatin1(target)) { 1257 1257 // Looking for a 16-bit character in an 8-bit string, so we're done. 1258 1258 return *this; 1259 1259 } 1260 1260 1261 if ( replacement <= 0xFF) {1261 if (isLatin1(replacement)) { 1262 1262 LChar* data; 1263 1263 LChar oldChar = static_cast<LChar>(target); -
trunk/Source/WTF/wtf/text/StringImpl.h
r239439 r241233 127 127 128 128 #endif 129 130 template<typename CharacterType> inline bool isLatin1(CharacterType character) 131 { 132 using UnsignedCharacterType = typename std::make_unsigned<CharacterType>::type; 133 return static_cast<UnsignedCharacterType>(character) <= static_cast<UnsignedCharacterType>(0xFF); 134 } 129 135 130 136 class StringImplShape { … … 1227 1233 using WTF::StringImpl; 1228 1234 using WTF::equal; 1235 using WTF::isLatin1; -
trunk/Source/WTF/wtf/text/WTFString.cpp
r239439 r241233 147 147 return; 148 148 } 149 if ( character <= 0xFF&& is8Bit()) {149 if (isLatin1(character) && is8Bit()) { 150 150 append(static_cast<LChar>(character)); 151 151 return; … … 830 830 for (unsigned i = 0; i < length; ++i) { 831 831 UChar ch = characters[i]; 832 characterBuffer[i] = ch > 0xff? '?' : ch;832 characterBuffer[i] = !isLatin1(ch) ? '?' : ch; 833 833 } 834 834
Note: See TracChangeset
for help on using the changeset viewer.