Changeset 190882 in webkit
- Timestamp:
- Oct 12, 2015 12:44:52 PM (9 years ago)
- Location:
- trunk/Source
- Files:
-
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r190881 r190882 1 2015-10-12 Andreas Kling <akling@apple.com> 2 3 "A + B" with strings shouldn't copy if A or B is empty. 4 <https://webkit.org/b/150034> 5 6 Reviewed by Anders Carlsson. 7 8 * runtime/JSStringBuilder.h: 9 (JSC::jsMakeNontrivialString): 10 * runtime/Lookup.cpp: 11 (JSC::reifyStaticAccessor): 12 * runtime/ObjectPrototype.cpp: 13 (JSC::objectProtoFuncToString): 14 1 15 2015-10-12 Joseph Pecoraro <pecoraro@apple.com> 2 16 -
trunk/Source/JavaScriptCore/runtime/JSStringBuilder.h
r174219 r190882 128 128 inline JSValue jsMakeNontrivialString(ExecState* exec, const StringType& string, const StringTypes&... strings) 129 129 { 130 RefPtr<StringImpl>result = WTF::tryMakeString(string, strings...);130 String result = WTF::tryMakeString(string, strings...); 131 131 if (!result) 132 132 return throwOutOfMemoryError(exec); 133 return jsNontrivialString(exec, result .release());133 return jsNontrivialString(exec, result); 134 134 } 135 135 -
trunk/Source/JavaScriptCore/runtime/Lookup.cpp
r190305 r190882 33 33 GetterSetter* accessor = GetterSetter::create(vm, globalObject); 34 34 if (value.accessorGetter()) { 35 RefPtr<StringImpl>getterName = WTF::tryMakeString(ASCIILiteral("get "), String(*propertyName.publicName()));35 String getterName = WTF::tryMakeString(ASCIILiteral("get "), String(*propertyName.publicName())); 36 36 if (!getterName) 37 37 return; 38 38 accessor->setGetter(vm, globalObject, value.attributes() & Builtin 39 ? JSFunction::createBuiltinFunction(vm, value.builtinAccessorGetterGenerator()(vm), globalObject, *getterName)40 : JSFunction::create(vm, globalObject, 0, *getterName, value.accessorGetter()));39 ? JSFunction::createBuiltinFunction(vm, value.builtinAccessorGetterGenerator()(vm), globalObject, getterName) 40 : JSFunction::create(vm, globalObject, 0, getterName, value.accessorGetter())); 41 41 } 42 42 thisObj.putDirectNonIndexAccessor(vm, propertyName, accessor, attributesForStructure(value.attributes())); -
trunk/Source/JavaScriptCore/runtime/ObjectPrototype.cpp
r183535 r190882 246 246 JSString* result = thisObject->structure(vm)->objectToStringValue(); 247 247 if (!result) { 248 RefPtr<StringImpl>newString = WTF::tryMakeString("[object ", thisObject->methodTable(exec->vm())->className(thisObject), "]");248 String newString = WTF::tryMakeString("[object ", thisObject->methodTable(exec->vm())->className(thisObject), "]"); 249 249 if (!newString) 250 250 return JSValue::encode(throwOutOfMemoryError(exec)); 251 251 252 result = jsNontrivialString(&vm, newString .release());252 result = jsNontrivialString(&vm, newString); 253 253 thisObject->structure(vm)->setObjectToStringValue(vm, result); 254 254 } -
trunk/Source/WTF/ChangeLog
r190875 r190882 1 2015-10-12 Andreas Kling <akling@apple.com> 2 3 "A + B" with strings shouldn't copy if A or B is empty. 4 <https://webkit.org/b/150034> 5 6 Reviewed by Anders Carlsson. 7 8 Add a fast path to WTF's operator+ magic for concatenation of two strings where 9 one of them is empty. In that case, try to avoid allocation altogether by returning 10 the non-empty string. 11 12 Spotted this while analyzing memory peaks during page load; it turns out we were 13 duplicating whole text resources (JS, CSS) at the end of decoding, below 14 TextResourceDecoder::decodeAndFlush(). That function effectively does: 15 16 return decode() + flush(); 17 18 Very often, flush() returns an empty string, so due to the naive operator+, 19 we'd allocate a new StringImpl of length (decode().length() + flush().length()) 20 and copy the return value from decode() into it. So silly! 21 22 Had to make the tryMakeString() machinery use String as a return type instead of 23 RefPtr<StringImpl> to make all the right overloads gel. StringTypeAdapter templates 24 are now required to provide a toString() function. 25 26 * wtf/text/StringConcatenate.h: 27 (WTF::StringTypeAdapter<char>::toString): 28 (WTF::StringTypeAdapter<UChar>::toString): 29 (WTF::StringTypeAdapter<Vector<char>>::toString): 30 (WTF::StringTypeAdapter<String>::toString): 31 (WTF::tryMakeString): 32 (WTF::makeString): 33 * wtf/text/StringOperators.h: 34 (WTF::StringAppend::operator String): 35 * wtf/text/StringView.h: 36 (WTF::StringTypeAdapter<StringView>::toString): 37 1 38 2015-10-12 Filip Pizlo <fpizlo@apple.com> 2 39 -
trunk/Source/WTF/wtf/text/StringConcatenate.h
r187875 r190882 1 1 /* 2 * Copyright (C) 2010 Apple Inc. All rights reserved.2 * Copyright (C) 2010-2015 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 69 69 } 70 70 71 String toString() const { return String(&m_character, 1); } 72 71 73 private: 72 74 char m_character; … … 94 96 *destination = m_character; 95 97 } 98 99 String toString() const { return String(&m_character, 1); } 96 100 97 101 private: … … 121 125 } 122 126 127 String toString() const { return String(m_characters, 1); } 128 123 129 private: 124 130 const LChar* m_characters; … … 155 161 } 156 162 163 String toString() const { return String(m_characters, 1); } 164 157 165 private: 158 166 const UChar* m_characters; … … 208 216 } 209 217 218 String toString() const { return String(m_vector.data(), m_vector.size()); } 219 210 220 private: 211 221 const Vector<char>& m_vector; … … 234 244 WTF_STRINGTYPEADAPTER_COPIED_WTF_STRING(); 235 245 } 246 247 String toString() const { return m_string; } 236 248 237 249 private: … … 257 269 258 270 template<typename StringType1, typename StringType2> 259 RefPtr<StringImpl>tryMakeString(StringType1 string1, StringType2 string2)271 String tryMakeString(StringType1 string1, StringType2 string2) 260 272 { 261 273 StringTypeAdapter<StringType1> adapter1(string1); 262 274 StringTypeAdapter<StringType2> adapter2(string2); 275 276 if (adapter1.length() && !adapter2.length()) 277 return adapter1.toString(); 278 if (!adapter1.length() && adapter2.length()) 279 return adapter2.toString(); 263 280 264 281 bool overflow = false; … … 266 283 sumWithOverflow(length, adapter2.length(), overflow); 267 284 if (overflow) 268 return nullptr;285 return String(); 269 286 270 287 if (adapter1.is8Bit() && adapter2.is8Bit()) { … … 272 289 RefPtr<StringImpl> resultImpl = StringImpl::tryCreateUninitialized(length, buffer); 273 290 if (!resultImpl) 274 return nullptr;291 return String(); 275 292 276 293 LChar* result = buffer; … … 285 302 RefPtr<StringImpl> resultImpl = StringImpl::tryCreateUninitialized(length, buffer); 286 303 if (!resultImpl) 287 return nullptr;304 return String(); 288 305 289 306 UChar* result = buffer; … … 296 313 297 314 template<typename StringType1, typename StringType2, typename StringType3> 298 RefPtr<StringImpl>tryMakeString(StringType1 string1, StringType2 string2, StringType3 string3)315 String tryMakeString(StringType1 string1, StringType2 string2, StringType3 string3) 299 316 { 300 317 StringTypeAdapter<StringType1> adapter1(string1); … … 307 324 sumWithOverflow(length, adapter3.length(), overflow); 308 325 if (overflow) 309 return nullptr;326 return String(); 310 327 311 328 if (adapter1.is8Bit() && adapter2.is8Bit() && adapter3.is8Bit()) { … … 313 330 RefPtr<StringImpl> resultImpl = StringImpl::tryCreateUninitialized(length, buffer); 314 331 if (!resultImpl) 315 return nullptr;332 return String(); 316 333 317 334 LChar* result = buffer; … … 328 345 RefPtr<StringImpl> resultImpl = StringImpl::tryCreateUninitialized(length, buffer); 329 346 if (!resultImpl) 330 return nullptr;347 return String(); 331 348 332 349 UChar* result = buffer; … … 341 358 342 359 template<typename StringType1, typename StringType2, typename StringType3, typename StringType4> 343 RefPtr<StringImpl>tryMakeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4)360 String tryMakeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4) 344 361 { 345 362 StringTypeAdapter<StringType1> adapter1(string1); … … 354 371 sumWithOverflow(length, adapter4.length(), overflow); 355 372 if (overflow) 356 return nullptr;373 return String(); 357 374 358 375 if (adapter1.is8Bit() && adapter2.is8Bit() && adapter3.is8Bit() && adapter4.is8Bit()) { … … 360 377 RefPtr<StringImpl> resultImpl = StringImpl::tryCreateUninitialized(length, buffer); 361 378 if (!resultImpl) 362 return nullptr;379 return String(); 363 380 364 381 LChar* result = buffer; … … 377 394 RefPtr<StringImpl> resultImpl = StringImpl::tryCreateUninitialized(length, buffer); 378 395 if (!resultImpl) 379 return nullptr;396 return String(); 380 397 381 398 UChar* result = buffer; … … 392 409 393 410 template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5> 394 RefPtr<StringImpl>tryMakeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5)411 String tryMakeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5) 395 412 { 396 413 StringTypeAdapter<StringType1> adapter1(string1); … … 407 424 sumWithOverflow(length, adapter5.length(), overflow); 408 425 if (overflow) 409 return nullptr;426 return String(); 410 427 411 428 if (adapter1.is8Bit() && adapter2.is8Bit() && adapter3.is8Bit() && adapter4.is8Bit() && adapter5.is8Bit()) { … … 413 430 RefPtr<StringImpl> resultImpl = StringImpl::tryCreateUninitialized(length, buffer); 414 431 if (!resultImpl) 415 return nullptr;432 return String(); 416 433 417 434 LChar* result = buffer; … … 432 449 RefPtr<StringImpl> resultImpl = StringImpl::tryCreateUninitialized(length, buffer); 433 450 if (!resultImpl) 434 return nullptr;451 return String(); 435 452 436 453 UChar* result = buffer; … … 449 466 450 467 template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5, typename StringType6> 451 RefPtr<StringImpl>tryMakeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6)468 String tryMakeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6) 452 469 { 453 470 StringTypeAdapter<StringType1> adapter1(string1); … … 466 483 sumWithOverflow(length, adapter6.length(), overflow); 467 484 if (overflow) 468 return nullptr;485 return String(); 469 486 470 487 if (adapter1.is8Bit() && adapter2.is8Bit() && adapter3.is8Bit() && adapter4.is8Bit() && adapter5.is8Bit() && adapter6.is8Bit()) { … … 472 489 RefPtr<StringImpl> resultImpl = StringImpl::tryCreateUninitialized(length, buffer); 473 490 if (!resultImpl) 474 return nullptr;491 return String(); 475 492 476 493 LChar* result = buffer; … … 493 510 RefPtr<StringImpl> resultImpl = StringImpl::tryCreateUninitialized(length, buffer); 494 511 if (!resultImpl) 495 return nullptr;512 return String(); 496 513 497 514 UChar* result = buffer; … … 512 529 513 530 template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5, typename StringType6, typename StringType7> 514 RefPtr<StringImpl>tryMakeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6, StringType7 string7)531 String tryMakeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6, StringType7 string7) 515 532 { 516 533 StringTypeAdapter<StringType1> adapter1(string1); … … 531 548 sumWithOverflow(length, adapter7.length(), overflow); 532 549 if (overflow) 533 return nullptr;550 return String(); 534 551 535 552 if (adapter1.is8Bit() && adapter2.is8Bit() && adapter3.is8Bit() && adapter4.is8Bit() && adapter5.is8Bit() && adapter6.is8Bit() && adapter7.is8Bit()) { … … 537 554 RefPtr<StringImpl> resultImpl = StringImpl::tryCreateUninitialized(length, buffer); 538 555 if (!resultImpl) 539 return nullptr;556 return String(); 540 557 541 558 LChar* result = buffer; … … 560 577 RefPtr<StringImpl> resultImpl = StringImpl::tryCreateUninitialized(length, buffer); 561 578 if (!resultImpl) 562 return nullptr;579 return String(); 563 580 564 581 UChar* result = buffer; … … 581 598 582 599 template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5, typename StringType6, typename StringType7, typename StringType8> 583 RefPtr<StringImpl>tryMakeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6, StringType7 string7, StringType8 string8)600 String tryMakeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6, StringType7 string7, StringType8 string8) 584 601 { 585 602 StringTypeAdapter<StringType1> adapter1(string1); … … 602 619 sumWithOverflow(length, adapter8.length(), overflow); 603 620 if (overflow) 604 return nullptr;621 return String(); 605 622 606 623 if (adapter1.is8Bit() && adapter2.is8Bit() && adapter3.is8Bit() && adapter4.is8Bit() && adapter5.is8Bit() && adapter6.is8Bit() && adapter7.is8Bit() && adapter8.is8Bit()) { … … 608 625 RefPtr<StringImpl> resultImpl = StringImpl::tryCreateUninitialized(length, buffer); 609 626 if (!resultImpl) 610 return nullptr;627 return String(); 611 628 612 629 LChar* result = buffer; … … 633 650 RefPtr<StringImpl> resultImpl = StringImpl::tryCreateUninitialized(length, buffer); 634 651 if (!resultImpl) 635 return nullptr;652 return String(); 636 653 637 654 UChar* result = buffer; … … 656 673 657 674 template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5, typename StringType6, typename StringType7, typename StringType8, typename StringType9> 658 RefPtr<StringImpl>tryMakeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6, StringType7 string7, StringType8 string8, StringType9 string9)675 String tryMakeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6, StringType7 string7, StringType8 string8, StringType9 string9) 659 676 { 660 677 StringTypeAdapter<StringType1> adapter1(string1); … … 679 696 sumWithOverflow(length, adapter9.length(), overflow); 680 697 if (overflow) 681 return nullptr;698 return String(); 682 699 683 700 if (adapter1.is8Bit() && adapter2.is8Bit() && adapter3.is8Bit() && adapter4.is8Bit() && adapter5.is8Bit() && adapter6.is8Bit() && adapter7.is8Bit() && adapter8.is8Bit() && adapter9.is8Bit()) { … … 685 702 RefPtr<StringImpl> resultImpl = StringImpl::tryCreateUninitialized(length, buffer); 686 703 if (!resultImpl) 687 return nullptr;704 return String(); 688 705 689 706 LChar* result = buffer; … … 712 729 RefPtr<StringImpl> resultImpl = StringImpl::tryCreateUninitialized(length, buffer); 713 730 if (!resultImpl) 714 return nullptr;731 return String(); 715 732 716 733 UChar* result = buffer; … … 747 764 String makeString(StringType1 string1, StringType2 string2) 748 765 { 749 RefPtr<StringImpl> resultImpl= tryMakeString(string1, string2);750 if (!result Impl)766 String result = tryMakeString(string1, string2); 767 if (!result) 751 768 CRASH(); 752 return WTF::move(resultImpl);769 return result; 753 770 } 754 771 … … 756 773 String makeString(StringType1 string1, StringType2 string2, StringType3 string3) 757 774 { 758 RefPtr<StringImpl> resultImpl= tryMakeString(string1, string2, string3);759 if (!result Impl)775 String result = tryMakeString(string1, string2, string3); 776 if (!result) 760 777 CRASH(); 761 return WTF::move(resultImpl);778 return result; 762 779 } 763 780 … … 765 782 String makeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4) 766 783 { 767 RefPtr<StringImpl> resultImpl= tryMakeString(string1, string2, string3, string4);768 if (!result Impl)784 String result = tryMakeString(string1, string2, string3, string4); 785 if (!result) 769 786 CRASH(); 770 return WTF::move(resultImpl);787 return result; 771 788 } 772 789 … … 774 791 String makeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5) 775 792 { 776 RefPtr<StringImpl> resultImpl= tryMakeString(string1, string2, string3, string4, string5);777 if (!result Impl)793 String result = tryMakeString(string1, string2, string3, string4, string5); 794 if (!result) 778 795 CRASH(); 779 return WTF::move(resultImpl);796 return result; 780 797 } 781 798 … … 783 800 String makeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6) 784 801 { 785 RefPtr<StringImpl> resultImpl= tryMakeString(string1, string2, string3, string4, string5, string6);786 if (!result Impl)802 String result = tryMakeString(string1, string2, string3, string4, string5, string6); 803 if (!result) 787 804 CRASH(); 788 return WTF::move(resultImpl);805 return result; 789 806 } 790 807 … … 792 809 String makeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6, StringType7 string7) 793 810 { 794 RefPtr<StringImpl> resultImpl= tryMakeString(string1, string2, string3, string4, string5, string6, string7);795 if (!result Impl)811 String result = tryMakeString(string1, string2, string3, string4, string5, string6, string7); 812 if (!result) 796 813 CRASH(); 797 return WTF::move(resultImpl);814 return result; 798 815 } 799 816 … … 801 818 String makeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6, StringType7 string7, StringType8 string8) 802 819 { 803 RefPtr<StringImpl> resultImpl= tryMakeString(string1, string2, string3, string4, string5, string6, string7, string8);804 if (!result Impl)820 String result = tryMakeString(string1, string2, string3, string4, string5, string6, string7, string8); 821 if (!result) 805 822 CRASH(); 806 return WTF::move(resultImpl);823 return result; 807 824 } 808 825 … … 810 827 String makeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6, StringType7 string7, StringType8 string8, StringType9 string9) 811 828 { 812 RefPtr<StringImpl> resultImpl= tryMakeString(string1, string2, string3, string4, string5, string6, string7, string8, string9);813 if (!result Impl)829 String result = tryMakeString(string1, string2, string3, string4, string5, string6, string7, string8, string9); 830 if (!result) 814 831 CRASH(); 815 return WTF::move(resultImpl);832 return result; 816 833 } 817 834 -
trunk/Source/WTF/wtf/text/StringOperators.h
r187875 r190882 36 36 operator String() const 37 37 { 38 RefPtr<StringImpl> resultImpl= tryMakeString(m_string1, m_string2);39 if (!result Impl)38 String result = tryMakeString(m_string1, m_string2); 39 if (!result) 40 40 CRASH(); 41 return result Impl.release();41 return result; 42 42 } 43 43 … … 97 97 void writeTo(LChar* destination) { m_buffer.writeTo(destination); } 98 98 void writeTo(UChar* destination) { m_buffer.writeTo(destination); } 99 100 String toString() const { return m_buffer; } 99 101 100 102 private: -
trunk/Source/WTF/wtf/text/StringView.h
r185899 r190882 498 498 void writeTo(UChar* destination) { m_string.getCharactersWithUpconvert(destination); } 499 499 500 String toString() const { return m_string.toString(); } 501 500 502 private: 501 503 StringView m_string;
Note: See TracChangeset
for help on using the changeset viewer.