Changeset 183988 in webkit
- Timestamp:
- May 8, 2015, 1:44:23 AM (11 years ago)
- Location:
- trunk/Source
- Files:
-
- 9 edited
-
JavaScriptCore/ChangeLog (modified) (1 diff)
-
JavaScriptCore/bytecompiler/NodesCodegen.cpp (modified) (1 diff)
-
JavaScriptCore/runtime/JSONObject.cpp (modified) (4 diffs)
-
JavaScriptCore/runtime/JSONObject.h (modified) (1 diff)
-
WTF/ChangeLog (modified) (1 diff)
-
WTF/wtf/text/StringBuilder.cpp (modified) (2 diffs)
-
WTF/wtf/text/StringBuilder.h (modified) (1 diff)
-
WebKit2/ChangeLog (modified) (1 diff)
-
WebKit2/NetworkProcess/cache/NetworkCacheEntry.cpp (modified) (5 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r183977 r183988 1 2015-05-08 Andreas Kling <akling@apple.com> 2 3 Optimize serialization of quoted JSON strings. 4 <https://webkit.org/b/144754> 5 6 Reviewed by Darin Adler. 7 8 Optimized the serialization of quoted strings into JSON by moving the logic into 9 StringBuilder so it can make smarter decisions about buffering. 10 11 12% progression on Kraken/json-stringify-tinderbox (on my Mac Pro.) 12 13 * bytecompiler/NodesCodegen.cpp: 14 (JSC::ObjectPatternNode::toString): Use the new StringBuilder API. 15 16 * runtime/JSONObject.h: 17 * runtime/JSONObject.cpp: 18 (JSC::Stringifier::Holder::appendNextProperty): 19 (JSC::appendStringToStringBuilder): Deleted. 20 (JSC::appendQuotedJSONStringToBuilder): Deleted. 21 (JSC::Stringifier::appendQuotedString): Deleted. 22 (JSC::Stringifier::appendStringifiedValue): Moved the bulk of this logic 23 to StringBuilder and call that from here. 24 1 25 2015-05-07 Commit Queue <commit-queue@webkit.org> 2 26 -
trunk/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp
r183977 r183988 3088 3088 for (size_t i = 0; i < m_targetPatterns.size(); i++) { 3089 3089 if (m_targetPatterns[i].wasString) 3090 appendQuotedJSONStringToBuilder(builder,m_targetPatterns[i].propertyName.string());3090 builder.appendQuotedJSONString(m_targetPatterns[i].propertyName.string()); 3091 3091 else 3092 3092 builder.append(m_targetPatterns[i].propertyName.string()); -
trunk/Source/JavaScriptCore/runtime/JSONObject.cpp
r183977 r183988 108 108 friend class Holder; 109 109 110 static void appendQuotedString(StringBuilder&, const String&);111 112 110 JSValue toJSON(JSValue, const PropertyNameForFunctionCall&); 113 111 … … 256 254 } 257 255 258 template <typename CharType>259 static void appendStringToStringBuilder(StringBuilder& builder, const CharType* data, int length)260 {261 for (int i = 0; i < length; ++i) {262 int start = i;263 while (i < length && (data[i] > 0x1F && data[i] != '"' && data[i] != '\\'))264 ++i;265 builder.append(data + start, i - start);266 if (i >= length)267 break;268 switch (data[i]) {269 case '\t':270 builder.append('\\');271 builder.append('t');272 break;273 case '\r':274 builder.append('\\');275 builder.append('r');276 break;277 case '\n':278 builder.append('\\');279 builder.append('n');280 break;281 case '\f':282 builder.append('\\');283 builder.append('f');284 break;285 case '\b':286 builder.append('\\');287 builder.append('b');288 break;289 case '"':290 builder.append('\\');291 builder.append('"');292 break;293 case '\\':294 builder.append('\\');295 builder.append('\\');296 break;297 default:298 static const char hexDigits[] = "0123456789abcdef";299 UChar ch = data[i];300 LChar hex[] = { '\\', 'u', static_cast<LChar>(hexDigits[(ch >> 12) & 0xF]), static_cast<LChar>(hexDigits[(ch >> 8) & 0xF]), static_cast<LChar>(hexDigits[(ch >> 4) & 0xF]), static_cast<LChar>(hexDigits[ch & 0xF]) };301 builder.append(hex, WTF_ARRAY_LENGTH(hex));302 break;303 }304 }305 }306 307 void appendQuotedJSONStringToBuilder(StringBuilder& builder, const String& message)308 {309 builder.append('"');310 311 if (message.is8Bit())312 appendStringToStringBuilder(builder, message.characters8(), message.length());313 else314 appendStringToStringBuilder(builder, message.characters16(), message.length());315 316 builder.append('"');317 }318 319 void Stringifier::appendQuotedString(StringBuilder& builder, const String& value)320 {321 appendQuotedJSONStringToBuilder(builder, value);322 }323 324 256 inline JSValue Stringifier::toJSON(JSValue value, const PropertyNameForFunctionCall& propertyName) 325 257 { … … 386 318 String stringValue; 387 319 if (value.getString(m_exec, stringValue)) { 388 appendQuotedString(builder,stringValue);320 builder.appendQuotedJSONString(stringValue); 389 321 return StringifySucceeded; 390 322 } … … 557 489 558 490 // Append the property name. 559 appendQuotedString(builder,propertyName.string());491 builder.appendQuotedJSONString(propertyName.string()); 560 492 builder.append(':'); 561 493 if (stringifier.willIndent()) -
trunk/Source/JavaScriptCore/runtime/JSONObject.h
r183977 r183988 63 63 JS_EXPORT_PRIVATE String JSONStringify(ExecState*, JSValue, unsigned indent); 64 64 65 JS_EXPORT_PRIVATE void appendQuotedJSONStringToBuilder(StringBuilder&, const String&);66 67 65 68 66 } // namespace JSC -
trunk/Source/WTF/ChangeLog
r183977 r183988 1 2015-05-08 Andreas Kling <akling@apple.com> 2 3 Optimize serialization of quoted JSON strings. 4 <https://webkit.org/b/144754> 5 6 Reviewed by Darin Adler. 7 8 Add a StringBuilder API for appending a quoted JSON string. This is used by 9 JSON.stringify() to implement efficient appending of strings while escaping 10 quotes, control characters and \uNNNN-style characters. 11 12 The main benefit comes from only doing a single buffer expansion up front, 13 instead of doing it every time we append something. The fudge factor is pretty 14 large, since the maximum number of output characters per input character is 6. 15 16 The first landing of this patch had two bugs in it: 17 18 - Made \uNNNN escapes uppercase hexadecimal instead of lowercase. 19 - Didn't preallocate enough space for 8-bit input strings. 20 21 Both were caught by existing tests on our bots, and both were due to last-minute 22 changes before landing. :/ 23 24 * wtf/text/StringBuilder.cpp: 25 (WTF::appendQuotedJSONStringInternal): 26 (WTF::StringBuilder::appendQuotedJSONString): 27 * wtf/text/StringBuilder.h: 28 1 29 2015-05-07 Commit Queue <commit-queue@webkit.org> 2 30 -
trunk/Source/WTF/wtf/text/StringBuilder.cpp
r183977 r183988 29 29 30 30 #include "IntegerToStringConversion.h" 31 #include "MathExtras.h" 31 32 #include "WTFString.h" 32 33 #include <wtf/dtoa.h> … … 361 362 } 362 363 364 template <typename OutputCharacterType, typename InputCharacterType> 365 static void appendQuotedJSONStringInternal(OutputCharacterType*& output, const InputCharacterType* input, unsigned length) 366 { 367 for (const InputCharacterType* end = input + length; input != end; ++input) { 368 if (*input > 0x1F && *input != '"' && *input != '\\') { 369 *output++ = *input; 370 continue; 371 } 372 switch (*input) { 373 case '\t': 374 *output++ = '\\'; 375 *output++ = 't'; 376 break; 377 case '\r': 378 *output++ = '\\'; 379 *output++ = 'r'; 380 break; 381 case '\n': 382 *output++ = '\\'; 383 *output++ = 'n'; 384 break; 385 case '\f': 386 *output++ = '\\'; 387 *output++ = 'f'; 388 break; 389 case '\b': 390 *output++ = '\\'; 391 *output++ = 'b'; 392 break; 393 case '"': 394 *output++ = '\\'; 395 *output++ = '"'; 396 break; 397 case '\\': 398 *output++ = '\\'; 399 *output++ = '\\'; 400 break; 401 default: 402 ASSERT((*input & 0xFF00) == 0); 403 static const char hexDigits[] = "0123456789abcdef"; 404 *output++ = '\\'; 405 *output++ = 'u'; 406 *output++ = '0'; 407 *output++ = '0'; 408 *output++ = static_cast<LChar>(hexDigits[(*input >> 4) & 0xF]); 409 *output++ = static_cast<LChar>(hexDigits[*input & 0xF]); 410 break; 411 } 412 } 413 } 414 415 void StringBuilder::appendQuotedJSONString(const String& string) 416 { 417 // Make sure we have enough buffer space to append this string without having 418 // to worry about reallocating in the middle. 419 // The 2 is for the '"' quotes on each end. 420 // The 6 is for characters that need to be \uNNNN encoded. 421 size_t maximumCapacityRequired = length() + 2 + string.length() * 6; 422 RELEASE_ASSERT(maximumCapacityRequired < std::numeric_limits<unsigned>::max()); 423 424 if (is8Bit() && !string.is8Bit()) 425 allocateBufferUpConvert(m_bufferCharacters8, roundUpToPowerOfTwo(maximumCapacityRequired)); 426 else 427 reserveCapacity(roundUpToPowerOfTwo(maximumCapacityRequired)); 428 429 if (is8Bit()) { 430 ASSERT(string.is8Bit()); 431 LChar* output = m_bufferCharacters8 + m_length; 432 *output++ = '"'; 433 appendQuotedJSONStringInternal(output, string.characters8(), string.length()); 434 *output++ = '"'; 435 m_length = output - m_bufferCharacters8; 436 } else { 437 UChar* output = m_bufferCharacters16 + m_length; 438 *output++ = '"'; 439 if (string.is8Bit()) 440 appendQuotedJSONStringInternal(output, string.characters8(), string.length()); 441 else 442 appendQuotedJSONStringInternal(output, string.characters16(), string.length()); 443 *output++ = '"'; 444 m_length = output - m_bufferCharacters16; 445 } 446 } 447 363 448 } // namespace WTF -
trunk/Source/WTF/wtf/text/StringBuilder.h
r183977 r183988 160 160 } 161 161 162 WTF_EXPORT_PRIVATE void appendQuotedJSONString(const String&); 163 162 164 template<unsigned charactersCount> 163 165 ALWAYS_INLINE void appendLiteral(const char (&characters)[charactersCount]) { append(characters, charactersCount - 1); } -
trunk/Source/WebKit2/ChangeLog
r183986 r183988 1 2015-05-08 Andreas Kling <akling@apple.com> 2 3 Optimize serialization of quoted JSON strings. 4 <https://webkit.org/b/144754> 5 6 Reviewed by Darin Adler. 7 8 * NetworkProcess/cache/NetworkCacheEntry.cpp: 9 (WebKit::NetworkCache::Entry::asJSON): Use the new StringBuilder API. 10 1 11 2015-05-08 Commit Queue <commit-queue@webkit.org> 2 12 -
trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheEntry.cpp
r183977 r183988 31 31 #include "NetworkCacheDecoder.h" 32 32 #include "NetworkCacheEncoder.h" 33 #include <JavaScriptCore/JSONObject.h>34 33 #include <WebCore/ResourceRequest.h> 35 34 #include <WebCore/SharedBuffer.h> … … 160 159 json.appendLiteral("{\n"); 161 160 json.appendLiteral("\"hash\": "); 162 JSC::appendQuotedJSONStringToBuilder(json,m_key.hashAsString());161 json.appendQuotedJSONString(m_key.hashAsString()); 163 162 json.appendLiteral(",\n"); 164 163 json.appendLiteral("\"bodySize\": "); … … 169 168 json.appendLiteral(",\n"); 170 169 json.appendLiteral("\"partition\": "); 171 JSC::appendQuotedJSONStringToBuilder(json,m_key.partition());170 json.appendQuotedJSONString(m_key.partition()); 172 171 json.appendLiteral(",\n"); 173 172 json.appendLiteral("\"timestamp\": "); … … 175 174 json.appendLiteral(",\n"); 176 175 json.appendLiteral("\"URL\": "); 177 JSC::appendQuotedJSONStringToBuilder(json,m_response.url().string());176 json.appendQuotedJSONString(m_response.url().string()); 178 177 json.appendLiteral(",\n"); 179 178 json.appendLiteral("\"bodyHash\": "); 180 JSC::appendQuotedJSONStringToBuilder(json,info.bodyHash);179 json.appendQuotedJSONString(info.bodyHash); 181 180 json.appendLiteral(",\n"); 182 181 json.appendLiteral("\"bodyShareCount\": "); … … 190 189 firstHeader = false; 191 190 json.appendLiteral(" "); 192 JSC::appendQuotedJSONStringToBuilder(json,header.key);191 json.appendQuotedJSONString(header.key); 193 192 json.appendLiteral(": "); 194 JSC::appendQuotedJSONStringToBuilder(json,header.value);193 json.appendQuotedJSONString(header.value); 195 194 } 196 195 json.appendLiteral("\n}\n");
Note:
See TracChangeset
for help on using the changeset viewer.