Eliminate unnecessary String temporaries by using StringConcatenateNumbers
authordarin@apple.com <darin@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 9 Feb 2019 21:00:05 +0000 (21:00 +0000)
committerdarin@apple.com <darin@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 9 Feb 2019 21:00:05 +0000 (21:00 +0000)
https://bugs.webkit.org/show_bug.cgi?id=194021

Reviewed by Geoffrey Garen.

Source/JavaScriptCore:

* inspector/agents/InspectorConsoleAgent.cpp:
(Inspector::InspectorConsoleAgent::count): Remove String::number and let
makeString do the conversion without allocating/destroying a String.
* inspector/agents/InspectorDebuggerAgent.cpp:
(Inspector::objectGroupForBreakpointAction): Ditto.
(Inspector::InspectorDebuggerAgent::setBreakpointByUrl): Ditto.
(Inspector::InspectorDebuggerAgent::setBreakpoint): Ditto.
* runtime/JSGenericTypedArrayViewInlines.h:
(JSC::JSGenericTypedArrayView<Adaptor>::defineOwnProperty): Ditto.
* runtime/NumberPrototype.cpp:
(JSC::numberProtoFuncToFixed): Use String::numberToStringFixedWidth instead
of calling numberToFixedWidthString to do the same thing.
(JSC::numberProtoFuncToPrecision): Use String::number instead of calling
numberToFixedPrecisionString to do the same thing.
* runtime/SamplingProfiler.cpp:
(JSC::SamplingProfiler::reportTopFunctions): Ditto.

Source/WebCore:

For floating point numbers, String::number gives a fixed precision result,
stripping trailing zeroes. When possible, I changed the code to instead use the
equivalent of String::numberToStringECMAScript, which is what makeString does by
default for floating point, gives the same results for many cases, and gives
better results in many others. However, for floats, we do not yet have a good
implementation, so instead I used FormattedNumber::fixedPrecision to match
the old behavior.

* Modules/indexeddb/shared/IDBTransactionInfo.cpp:
(WebCore::IDBTransactionInfo::loggingString const): Remove String::number and let
makeString do the conversion without allocating/destroying a String.
* Modules/websockets/ThreadableWebSocketChannel.cpp:
(WebCore::ThreadableWebSocketChannel::create): Ditto.
* Modules/websockets/WebSocket.cpp:
(WebCore::WebSocket::connect): Ditto. Added a cast to "unsigned" to sidestep the
ambiguity with 16-bit unsigned types that are sometimes used for numbers (uint16_t)
and sometimes used for UTF-16 code units (UChar) and can be the same type.

* Modules/websockets/WebSocketChannel.cpp:
(WebCore::WebSocketChannel::didFailSocketStream): Use ASCIILiteral when intializing
a string instead of just a normal C literal. Switched to makeString so we could
remove String::number and do the conversion without allocating/destroying a String.
(WebCore::WebSocketChannel::didFail): Ditto.
(WebCore::WebSocketChannel::processFrame): Ditto.
* Modules/websockets/WebSocketFrame.cpp:
(WebCore::WebSocketFrame::parseFrame): Ditto.
* Modules/websockets/WebSocketHandshake.cpp:
(WebCore::WebSocketHandshake::readServerHandshake): Ditto.
* accessibility/AccessibilityRenderObject.cpp:
(WebCore::AccessibilityRenderObject::positionalDescriptionForMSAA const): Ditto.
* bindings/js/JSDOMConvertNumbers.cpp:
(WebCore::rangeErrorString): Ditto.
* css/CSSAspectRatioValue.cpp:
(WebCore::CSSAspectRatioValue::customCSSText const): Ditto. Used
FormattedNumber::fixedPrecision since these are floats.

* css/DOMMatrixReadOnly.cpp:
(WebCore::DOMMatrixReadOnly::toString const): Use
StringBuilder::builder.appendECMAScriptNumber instead of
String::numberToStringECMAScript so we can do it without allocating/destroying
a String.
* css/WebKitCSSMatrix.cpp:
(WebCore::WebKitCSSMatrix::toString const): Ditto.

* dom/MessagePortIdentifier.h:
(WebCore::MessagePortIdentifier::logString const): Remove String::number and let
makeString do the conversion without allocating/destroying a String.

* editing/cocoa/DataDetection.mm:
(WebCore::dataDetectorStringForPath): Remove unnecessary type casts on values
passed to String::number and to StringBuilder::appendNumber. These could do
harm if the values were out of range, and should not be necessary.

* history/BackForwardItemIdentifier.h:
(WebCore::BackForwardItemIdentifier::logString const): Remove String::number
and let makeString do the conversion without allocating/destroying a String.
* html/FTPDirectoryDocument.cpp:
(WebCore::processFileDateString): Ditto.
* html/canvas/WebGLRenderingContextBase.cpp:
(WebCore::WebGLRenderingContextBase::getUniformLocation): Ditto.
(WebCore::WebGLRenderingContextBase::checkTextureCompleteness): Ditto.
* inspector/agents/WebConsoleAgent.cpp:
(WebCore::WebConsoleAgent::didReceiveResponse): Ditto.
* loader/WorkerThreadableLoader.cpp:
(WebCore::WorkerThreadableLoader::loadResourceSynchronously): Ditto.
* loader/appcache/ApplicationCacheGroup.cpp:
(WebCore::ApplicationCacheGroup::didFailLoadingManifest): Ditto.
* page/PageSerializer.cpp:
(WebCore::PageSerializer::urlForBlankFrame): Ditto.
* page/PrintContext.cpp:
(WebCore::PrintContext::pageProperty): Ditto.
(WebCore::PrintContext::pageSizeAndMarginsInPixels): Ditto.

* page/WheelEventTestTrigger.cpp:
(WebCore::dumpState): Use StringBuilder::appendNumber instead of
String::number so we can do it without allocating/destroying a String.
Also use StringBuilder::appendLiteral on a literal.

* page/cocoa/ResourceUsageOverlayCocoa.mm:
(WebCore::ResourceUsageOverlay::platformDraw): Pass explicit
KeepTrailingZeros to FormattedNumber::fixedPrecision to preserve behavior,
since default is now to truncate trailing zeros.

* platform/graphics/Color.cpp:
(WebCore::Color::cssText): Use StringBuilder::appendNumber instead of
calling numberToFixedPrecisionString to do the same thing.
* platform/graphics/ExtendedColor.cpp:
(WebCore::ExtendedColor::cssText): Ditto.

* platform/graphics/ca/GraphicsLayerCA.cpp:
(WebCore::animationIdentifier): Remove String::number and let makeString
do the conversion without allocating/destroying a String. Had to add
a typecast to convert the enumeration into an integer.
* platform/graphics/ca/cocoa/PlatformCAFiltersCocoa.mm:
(WebCore::PlatformCAFilters::setFiltersOnLayer): Ditto.
* platform/graphics/cocoa/FontPlatformDataCocoa.mm:
(WebCore::FontPlatformData::description const): Ditto.

* platform/mock/mediasource/MockSourceBufferPrivate.cpp:
(WebCore::MockMediaSample::MockMediaSample): Use AtomicString::number
instead of String::number to avoid unneccessarily allocating an additional
temporary String when an AtomicString already exists.

* platform/network/cf/SocketStreamHandleImplCFNet.cpp:
(WebCore::SocketStreamHandleImpl::reportErrorToClient): Remove String::number
and let makeString do the conversion without allocating/destroying a String.
* platform/sql/SQLiteDatabase.cpp:
(WebCore::SQLiteDatabase::setMaximumSize): Ditto.
(WebCore::SQLiteDatabase::setSynchronous): Ditto. Had to add a typecast to
convert the enumeration into an integer.
* svg/SVGAngleValue.cpp:
(WebCore::SVGAngleValue::valueAsString const): Ditto.
* svg/SVGLengthValue.cpp:
(WebCore::SVGLengthValue::valueAsString const): Ditto.
* testing/Internals.cpp:
(WebCore::Internals::configurationForViewport): Ditto. Used
FormattedNumber::fixedPrecision since these are floats.
(WebCore::Internals::getCurrentCursorInfo): Use StringBuilder::appendNumber
instead of calling numberToFixedPrecisionString to do the same thing.
(WebCore::Internals::queueMicroTask): Remove String::number and let makeString
do the conversion without allocating/destroying a String.
(WebCore::appendOffsets): Use StringBuilder::appendNumber instead of
String::number so we can do it without allocating/destroying a String.

* workers/service/ServiceWorkerClientIdentifier.h:
(WebCore::ServiceWorkerClientIdentifier::toString const): Remove String::number
and let makeString do the conversion without allocating/destroying a String.
* workers/service/server/RegistrationDatabase.cpp:
(WebCore::databaseFilenameFromVersion): Ditto.

Source/WebKit:

* NetworkProcess/NetworkResourceLoader.cpp:
(WebKit::escapeIDForJSON): Use an ASCIILiteral to create a String.

* NetworkProcess/cache/NetworkCacheStorage.cpp:
(WebKit::NetworkCache::makeVersionedDirectoryPath): Remove String::number and let
makeString do the conversion without allocating/destroying a String.

* NetworkProcess/mac/RemoteNetworkingContext.mm: Removed "using namespace WebCore".
(WebKit::RemoteNetworkingContext::ensureWebsiteDataStoreSession): Remove String::number
and let makeString do the conversion without allocating/destroying a String.

* NetworkProcess/webrtc/NetworkMDNSRegister.cpp: Removed "using namespace WebCore".
(WebKit::registerMDNSNameCallback): Added explicit WebCore prefix as needed.
(WebKit::NetworkMDNSRegister::registerMDNSName): Ditto. Also remove String::number
and let makeString do the conversion without allocating/destroying a String.

* UIProcess/WebPageGroup.cpp:
(WebKit::pageGroupData): Remove String::number and let makeString do the conversion
without allocating/destroying a String.
* UIProcess/WebPageProxy.cpp:
(WebKit::WebPageProxy::createInspectorTargets): Ditto.
* UIProcess/ios/WKLegacyPDFView.mm:
(-[WKLegacyPDFView _URLForLinkAnnotation:]): Ditto.
* WebProcess/InjectedBundle/InjectedBundleScriptWorld.cpp:
(WebKit::uniqueWorldName): Ditto.
* WebProcess/WebPage/WebPageInspectorTarget.cpp:
(WebKit::WebPageInspectorTarget::identifier const): Ditto.

Source/WTF:

* wtf/URL.cpp:
(WTF::URL::setPort): Remove String::number and let makeString do the conversion
without allocating/destroying a String. Added a cast to "unsigned" to sidestep the
ambiguity with 16-bit unsigned types that are sometimes used for numbers (uint16_t)
and sometimes used for UTF-16 code units (UChar) and can be the same type.

* wtf/text/StringConcatenateNumbers.h:
Changed FormattedNumber::fixedPrecision to more closely match String::number and
StringBuilder::appendNumber by defaulting to truncating trailing zeros and using
a named enumeration for the truncation policy rather than a boolean.

Tools:

* TestWebKitAPI/Tests/WTF/StringConcatenate.cpp:
(TestWebKitAPI::TEST): Change tests to use EXPECT_STREQ so failure messages are easier
to understand. Updated tests for changes to FormattedNumber::fixedPrecision.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@241244 268f45cc-cd09-0410-ab3c-d52691b4dbfc

58 files changed:
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/inspector/agents/InspectorConsoleAgent.cpp
Source/JavaScriptCore/inspector/agents/InspectorDebuggerAgent.cpp
Source/JavaScriptCore/runtime/JSGenericTypedArrayViewInlines.h
Source/JavaScriptCore/runtime/NumberPrototype.cpp
Source/JavaScriptCore/runtime/SamplingProfiler.cpp
Source/WTF/ChangeLog
Source/WTF/wtf/URL.cpp
Source/WTF/wtf/text/StringConcatenateNumbers.h
Source/WebCore/ChangeLog
Source/WebCore/Modules/indexeddb/shared/IDBTransactionInfo.cpp
Source/WebCore/Modules/websockets/ThreadableWebSocketChannel.cpp
Source/WebCore/Modules/websockets/WebSocket.cpp
Source/WebCore/Modules/websockets/WebSocketChannel.cpp
Source/WebCore/Modules/websockets/WebSocketFrame.cpp
Source/WebCore/Modules/websockets/WebSocketHandshake.cpp
Source/WebCore/accessibility/AccessibilityRenderObject.cpp
Source/WebCore/bindings/js/JSDOMConvertNumbers.cpp
Source/WebCore/css/CSSAspectRatioValue.cpp
Source/WebCore/css/DOMMatrixReadOnly.cpp
Source/WebCore/css/WebKitCSSMatrix.cpp
Source/WebCore/dom/MessagePortIdentifier.h
Source/WebCore/editing/cocoa/DataDetection.mm
Source/WebCore/history/BackForwardItemIdentifier.h
Source/WebCore/html/FTPDirectoryDocument.cpp
Source/WebCore/html/canvas/WebGLRenderingContextBase.cpp
Source/WebCore/inspector/agents/WebConsoleAgent.cpp
Source/WebCore/loader/WorkerThreadableLoader.cpp
Source/WebCore/loader/appcache/ApplicationCacheGroup.cpp
Source/WebCore/page/PageSerializer.cpp
Source/WebCore/page/PrintContext.cpp
Source/WebCore/page/WheelEventTestTrigger.cpp
Source/WebCore/page/cocoa/ResourceUsageOverlayCocoa.mm
Source/WebCore/platform/graphics/Color.cpp
Source/WebCore/platform/graphics/ExtendedColor.cpp
Source/WebCore/platform/graphics/ca/GraphicsLayerCA.cpp
Source/WebCore/platform/graphics/ca/cocoa/PlatformCAFiltersCocoa.mm
Source/WebCore/platform/graphics/cocoa/FontPlatformDataCocoa.mm
Source/WebCore/platform/mock/mediasource/MockSourceBufferPrivate.cpp
Source/WebCore/platform/network/cf/SocketStreamHandleImplCFNet.cpp
Source/WebCore/platform/sql/SQLiteDatabase.cpp
Source/WebCore/svg/SVGAngleValue.cpp
Source/WebCore/svg/SVGLengthValue.cpp
Source/WebCore/testing/Internals.cpp
Source/WebCore/workers/service/ServiceWorkerClientIdentifier.h
Source/WebCore/workers/service/server/RegistrationDatabase.cpp
Source/WebKit/ChangeLog
Source/WebKit/NetworkProcess/NetworkResourceLoader.cpp
Source/WebKit/NetworkProcess/cache/NetworkCacheStorage.cpp
Source/WebKit/NetworkProcess/mac/RemoteNetworkingContext.mm
Source/WebKit/NetworkProcess/webrtc/NetworkMDNSRegister.cpp
Source/WebKit/UIProcess/WebPageGroup.cpp
Source/WebKit/UIProcess/WebPageProxy.cpp
Source/WebKit/UIProcess/ios/WKLegacyPDFView.mm
Source/WebKit/WebProcess/InjectedBundle/InjectedBundleScriptWorld.cpp
Source/WebKit/WebProcess/WebPage/WebPageInspectorTarget.cpp
Tools/ChangeLog
Tools/TestWebKitAPI/Tests/WTF/StringConcatenate.cpp

index 567a28f..1483a48 100644 (file)
@@ -1,3 +1,27 @@
+2019-01-30  Darin Adler  <darin@apple.com>
+
+        Eliminate unnecessary String temporaries by using StringConcatenateNumbers
+        https://bugs.webkit.org/show_bug.cgi?id=194021
+
+        Reviewed by Geoffrey Garen.
+
+        * inspector/agents/InspectorConsoleAgent.cpp:
+        (Inspector::InspectorConsoleAgent::count): Remove String::number and let
+        makeString do the conversion without allocating/destroying a String.
+        * inspector/agents/InspectorDebuggerAgent.cpp:
+        (Inspector::objectGroupForBreakpointAction): Ditto.
+        (Inspector::InspectorDebuggerAgent::setBreakpointByUrl): Ditto.
+        (Inspector::InspectorDebuggerAgent::setBreakpoint): Ditto.
+        * runtime/JSGenericTypedArrayViewInlines.h:
+        (JSC::JSGenericTypedArrayView<Adaptor>::defineOwnProperty): Ditto.
+        * runtime/NumberPrototype.cpp:
+        (JSC::numberProtoFuncToFixed): Use String::numberToStringFixedWidth instead
+        of calling numberToFixedWidthString to do the same thing.
+        (JSC::numberProtoFuncToPrecision): Use String::number instead of calling
+        numberToFixedPrecisionString to do the same thing.
+        * runtime/SamplingProfiler.cpp:
+        (JSC::SamplingProfiler::reportTopFunctions): Ditto.
+
 2019-02-09  Yusuke Suzuki  <ysuzuki@apple.com>
 
         Unreviewed, rolling in r241237 again
index 8a874a7..85bdb81 100644 (file)
@@ -203,7 +203,7 @@ void InspectorConsoleAgent::count(JSC::ExecState* state, Ref<ScriptArguments>&&
 
     // FIXME: Web Inspector should have a better UI for counters, but for now we just log an updated counter value.
 
-    String message = makeString(title, ": ", String::number(result.iterator->value));
+    String message = makeString(title, ": ", result.iterator->value);
     addMessageToConsole(std::make_unique<ConsoleMessage>(MessageSource::ConsoleAPI, MessageType::Log, MessageLevel::Debug, message, WTFMove(callStack)));
 }
 
index ece5647..5631672 100644 (file)
@@ -57,8 +57,7 @@ const char* InspectorDebuggerAgent::backtraceObjectGroup = "backtrace";
 // create objects in the same group.
 static String objectGroupForBreakpointAction(const ScriptBreakpointAction& action)
 {
-    static NeverDestroyed<String> objectGroup(MAKE_STATIC_STRING_IMPL("breakpoint-action-"));
-    return makeString(objectGroup.get(), String::number(action.identifier));
+    return makeString("breakpoint-action-", action.identifier);
 }
 
 InspectorDebuggerAgent::InspectorDebuggerAgent(AgentContext& context)
@@ -447,7 +446,7 @@ void InspectorDebuggerAgent::setBreakpointByUrl(ErrorString& errorString, int li
     int columnNumber = optionalColumnNumber ? *optionalColumnNumber : 0;
     bool isRegex = optionalURLRegex;
 
-    String breakpointIdentifier = (isRegex ? "/" + url + "/" : url) + ':' + String::number(lineNumber) + ':' + String::number(columnNumber);
+    String breakpointIdentifier = makeString(isRegex ? "/" : "", url, isRegex ? "/:" : ":", lineNumber, ':', columnNumber);
     if (m_javaScriptBreakpoints.contains(breakpointIdentifier)) {
         errorString = "Breakpoint at specified location already exists."_s;
         return;
@@ -540,7 +539,7 @@ void InspectorDebuggerAgent::setBreakpoint(ErrorString& errorString, const JSON:
         return;
     }
 
-    String breakpointIdentifier = String::number(sourceID) + ':' + String::number(breakpoint.line) + ':' + String::number(breakpoint.column);
+    String breakpointIdentifier = makeString(sourceID, ':', breakpoint.line, ':', breakpoint.column);
     ScriptBreakpoint scriptBreakpoint(breakpoint.line, breakpoint.column, condition, breakpointActions, autoContinue, ignoreCount);
     didSetBreakpoint(breakpoint, breakpointIdentifier, scriptBreakpoint);
 
index f3c0d39..1c5d573 100644 (file)
@@ -33,6 +33,7 @@
 #include "JSGenericTypedArrayView.h"
 #include "TypeError.h"
 #include "TypedArrays.h"
+#include <wtf/text/StringConcatenateNumbers.h>
 
 namespace JSC {
 
@@ -390,7 +391,7 @@ bool JSGenericTypedArrayView<Adaptor>::defineOwnProperty(
     if (Optional<uint32_t> index = parseIndex(propertyName)) {
         auto throwTypeErrorIfNeeded = [&] (const char* errorMessage) -> bool {
             if (shouldThrow)
-                throwTypeError(exec, scope, makeString(errorMessage, String::number(*index)));
+                throwTypeError(exec, scope, makeString(errorMessage, *index));
             return false;
         };
 
index b46f8ac..c83783a 100644 (file)
@@ -465,8 +465,7 @@ EncodedJSValue JSC_HOST_CALL numberProtoFuncToFixed(ExecState* exec)
     // handled by numberToString.
     ASSERT(std::isfinite(x));
 
-    NumberToStringBuffer buffer;
-    return JSValue::encode(jsString(exec, String(numberToFixedWidthString(x, decimalPlaces, buffer))));
+    return JSValue::encode(jsString(exec, String::numberToStringFixedWidth(x, decimalPlaces)));
 }
 
 // toPrecision converts a number to a string, taking an argument specifying a
@@ -502,8 +501,7 @@ EncodedJSValue JSC_HOST_CALL numberProtoFuncToPrecision(ExecState* exec)
     if (!inRange)
         return throwVMError(exec, scope, createRangeError(exec, "toPrecision() argument must be between 1 and 21"_s));
 
-    NumberToStringBuffer buffer;
-    return JSValue::encode(jsString(exec, String(numberToFixedPrecisionString(x, significantFigures, buffer))));
+    return JSValue::encode(jsString(exec, String::number(x, significantFigures, KeepTrailingZeros)));
 }
 
 static ALWAYS_INLINE JSString* int32ToStringInternal(VM& vm, int32_t value, int32_t radix)
index 07df966..6307303 100644 (file)
@@ -54,6 +54,7 @@
 #include <wtf/RefPtr.h>
 #include <wtf/StackTrace.h>
 #include <wtf/text/StringBuilder.h>
+#include <wtf/text/StringConcatenateNumbers.h>
 
 namespace JSC {
 
@@ -974,7 +975,7 @@ void SamplingProfiler::reportTopFunctions(PrintStream& out)
             continue;
 
         StackFrame& frame = stackTrace.frames.first();
-        String frameDescription = makeString(frame.displayName(m_vm), ":", String::number(frame.sourceID()));
+        String frameDescription = makeString(frame.displayName(m_vm), ':', frame.sourceID());
         functionCounts.add(frameDescription, 0).iterator->value++;
     }
 
index 552aa27..bbe64dc 100644 (file)
@@ -1,3 +1,22 @@
+2019-01-30  Darin Adler  <darin@apple.com>
+
+        Eliminate unnecessary String temporaries by using StringConcatenateNumbers
+        https://bugs.webkit.org/show_bug.cgi?id=194021
+
+        Reviewed by Geoffrey Garen.
+
+        * wtf/URL.cpp:
+        (WTF::URL::setPort): Remove String::number and let makeString do the conversion
+        without allocating/destroying a String. Added a cast to "unsigned" to sidestep the
+        ambiguity with 16-bit unsigned types that are sometimes used for numbers (uint16_t)
+        and sometimes used for UTF-16 code units (UChar) and can be the same type.
+
+        * wtf/text/StringConcatenateNumbers.h:
+        Changed FormattedNumber::fixedPrecision to more closely match String::number and
+        StringBuilder::appendNumber by defaulting to truncating trailing zeros and using
+        a named enumeration for the truncation policy rather than a boolean.
+
+
 2019-02-09  Yusuke Suzuki  <ysuzuki@apple.com>
 
         Unreviewed, rolling in r241237 again
index 64b4a0b..b78db9f 100644 (file)
@@ -470,7 +470,7 @@ void URL::setPort(unsigned short i)
     bool colonNeeded = !m_portLength;
     unsigned portStart = (colonNeeded ? m_hostEnd : m_hostEnd + 1);
 
-    URLParser parser(makeString(StringView(m_string).left(portStart), (colonNeeded ? ":" : ""), String::number(i), StringView(m_string).substring(m_hostEnd + m_portLength)));
+    URLParser parser(makeString(StringView(m_string).left(portStart), (colonNeeded ? ":" : ""), static_cast<unsigned>(i), StringView(m_string).substring(m_hostEnd + m_portLength)));
     *this = parser.result();
 }
 
index 8c8465a..6ce7278 100644 (file)
@@ -104,10 +104,10 @@ private:
 
 class FormattedNumber {
 public:
-    static FormattedNumber fixedPrecision(double number, unsigned significantFigures = 6, bool truncateTrailingZeros = false)
+    static FormattedNumber fixedPrecision(double number, unsigned significantFigures = 6, TrailingZerosTruncatingPolicy trailingZerosTruncatingPolicy = TruncateTrailingZeros)
     {
         FormattedNumber numberFormatter;
-        numberToFixedPrecisionString(number, significantFigures, numberFormatter.m_buffer, truncateTrailingZeros);
+        numberToFixedPrecisionString(number, significantFigures, numberFormatter.m_buffer, trailingZerosTruncatingPolicy == TruncateTrailingZeros);
         numberFormatter.m_length = strlen(numberFormatter.m_buffer);
         return numberFormatter;
     }
index 8efacff..f573302 100644 (file)
@@ -1,3 +1,140 @@
+2019-01-30  Darin Adler  <darin@apple.com>
+
+        Eliminate unnecessary String temporaries by using StringConcatenateNumbers
+        https://bugs.webkit.org/show_bug.cgi?id=194021
+
+        Reviewed by Geoffrey Garen.
+
+        For floating point numbers, String::number gives a fixed precision result,
+        stripping trailing zeroes. When possible, I changed the code to instead use the
+        equivalent of String::numberToStringECMAScript, which is what makeString does by
+        default for floating point, gives the same results for many cases, and gives
+        better results in many others. However, for floats, we do not yet have a good
+        implementation, so instead I used FormattedNumber::fixedPrecision to match
+        the old behavior.
+
+        * Modules/indexeddb/shared/IDBTransactionInfo.cpp:
+        (WebCore::IDBTransactionInfo::loggingString const): Remove String::number and let
+        makeString do the conversion without allocating/destroying a String.
+        * Modules/websockets/ThreadableWebSocketChannel.cpp:
+        (WebCore::ThreadableWebSocketChannel::create): Ditto.
+        * Modules/websockets/WebSocket.cpp:
+        (WebCore::WebSocket::connect): Ditto. Added a cast to "unsigned" to sidestep the
+        ambiguity with 16-bit unsigned types that are sometimes used for numbers (uint16_t)
+        and sometimes used for UTF-16 code units (UChar) and can be the same type.
+
+        * Modules/websockets/WebSocketChannel.cpp:
+        (WebCore::WebSocketChannel::didFailSocketStream): Use ASCIILiteral when intializing
+        a string instead of just a normal C literal. Switched to makeString so we could
+        remove String::number and do the conversion without allocating/destroying a String.
+        (WebCore::WebSocketChannel::didFail): Ditto.
+        (WebCore::WebSocketChannel::processFrame): Ditto.
+        * Modules/websockets/WebSocketFrame.cpp:
+        (WebCore::WebSocketFrame::parseFrame): Ditto.
+        * Modules/websockets/WebSocketHandshake.cpp:
+        (WebCore::WebSocketHandshake::readServerHandshake): Ditto.
+        * accessibility/AccessibilityRenderObject.cpp:
+        (WebCore::AccessibilityRenderObject::positionalDescriptionForMSAA const): Ditto.
+        * bindings/js/JSDOMConvertNumbers.cpp:
+        (WebCore::rangeErrorString): Ditto.
+        * css/CSSAspectRatioValue.cpp:
+        (WebCore::CSSAspectRatioValue::customCSSText const): Ditto. Used
+        FormattedNumber::fixedPrecision since these are floats.
+
+        * css/DOMMatrixReadOnly.cpp:
+        (WebCore::DOMMatrixReadOnly::toString const): Use
+        StringBuilder::builder.appendECMAScriptNumber instead of
+        String::numberToStringECMAScript so we can do it without allocating/destroying
+        a String.
+        * css/WebKitCSSMatrix.cpp:
+        (WebCore::WebKitCSSMatrix::toString const): Ditto.
+
+        * dom/MessagePortIdentifier.h:
+        (WebCore::MessagePortIdentifier::logString const): Remove String::number and let
+        makeString do the conversion without allocating/destroying a String.
+
+        * editing/cocoa/DataDetection.mm:
+        (WebCore::dataDetectorStringForPath): Remove unnecessary type casts on values
+        passed to String::number and to StringBuilder::appendNumber. These could do
+        harm if the values were out of range, and should not be necessary.
+
+        * history/BackForwardItemIdentifier.h:
+        (WebCore::BackForwardItemIdentifier::logString const): Remove String::number
+        and let makeString do the conversion without allocating/destroying a String.
+        * html/FTPDirectoryDocument.cpp:
+        (WebCore::processFileDateString): Ditto.
+        * html/canvas/WebGLRenderingContextBase.cpp:
+        (WebCore::WebGLRenderingContextBase::getUniformLocation): Ditto.
+        (WebCore::WebGLRenderingContextBase::checkTextureCompleteness): Ditto.
+        * inspector/agents/WebConsoleAgent.cpp:
+        (WebCore::WebConsoleAgent::didReceiveResponse): Ditto.
+        * loader/WorkerThreadableLoader.cpp:
+        (WebCore::WorkerThreadableLoader::loadResourceSynchronously): Ditto.
+        * loader/appcache/ApplicationCacheGroup.cpp:
+        (WebCore::ApplicationCacheGroup::didFailLoadingManifest): Ditto.
+        * page/PageSerializer.cpp:
+        (WebCore::PageSerializer::urlForBlankFrame): Ditto.
+        * page/PrintContext.cpp:
+        (WebCore::PrintContext::pageProperty): Ditto.
+        (WebCore::PrintContext::pageSizeAndMarginsInPixels): Ditto.
+
+        * page/WheelEventTestTrigger.cpp:
+        (WebCore::dumpState): Use StringBuilder::appendNumber instead of
+        String::number so we can do it without allocating/destroying a String.
+        Also use StringBuilder::appendLiteral on a literal.
+
+        * page/cocoa/ResourceUsageOverlayCocoa.mm:
+        (WebCore::ResourceUsageOverlay::platformDraw): Pass explicit
+        KeepTrailingZeros to FormattedNumber::fixedPrecision to preserve behavior,
+        since default is now to truncate trailing zeros.
+
+        * platform/graphics/Color.cpp:
+        (WebCore::Color::cssText): Use StringBuilder::appendNumber instead of
+        calling numberToFixedPrecisionString to do the same thing.
+        * platform/graphics/ExtendedColor.cpp:
+        (WebCore::ExtendedColor::cssText): Ditto.
+
+        * platform/graphics/ca/GraphicsLayerCA.cpp:
+        (WebCore::animationIdentifier): Remove String::number and let makeString
+        do the conversion without allocating/destroying a String. Had to add
+        a typecast to convert the enumeration into an integer.
+        * platform/graphics/ca/cocoa/PlatformCAFiltersCocoa.mm:
+        (WebCore::PlatformCAFilters::setFiltersOnLayer): Ditto.
+        * platform/graphics/cocoa/FontPlatformDataCocoa.mm:
+        (WebCore::FontPlatformData::description const): Ditto.
+
+        * platform/mock/mediasource/MockSourceBufferPrivate.cpp:
+        (WebCore::MockMediaSample::MockMediaSample): Use AtomicString::number
+        instead of String::number to avoid unneccessarily allocating an additional
+        temporary String when an AtomicString already exists.
+
+        * platform/network/cf/SocketStreamHandleImplCFNet.cpp:
+        (WebCore::SocketStreamHandleImpl::reportErrorToClient): Remove String::number
+        and let makeString do the conversion without allocating/destroying a String.
+        * platform/sql/SQLiteDatabase.cpp:
+        (WebCore::SQLiteDatabase::setMaximumSize): Ditto.
+        (WebCore::SQLiteDatabase::setSynchronous): Ditto. Had to add a typecast to
+        convert the enumeration into an integer.
+        * svg/SVGAngleValue.cpp:
+        (WebCore::SVGAngleValue::valueAsString const): Ditto.
+        * svg/SVGLengthValue.cpp:
+        (WebCore::SVGLengthValue::valueAsString const): Ditto.
+        * testing/Internals.cpp:
+        (WebCore::Internals::configurationForViewport): Ditto. Used
+        FormattedNumber::fixedPrecision since these are floats.
+        (WebCore::Internals::getCurrentCursorInfo): Use StringBuilder::appendNumber
+        instead of calling numberToFixedPrecisionString to do the same thing.
+        (WebCore::Internals::queueMicroTask): Remove String::number and let makeString
+        do the conversion without allocating/destroying a String.
+        (WebCore::appendOffsets): Use StringBuilder::appendNumber instead of
+        String::number so we can do it without allocating/destroying a String.
+
+        * workers/service/ServiceWorkerClientIdentifier.h:
+        (WebCore::ServiceWorkerClientIdentifier::toString const): Remove String::number
+        and let makeString do the conversion without allocating/destroying a String.
+        * workers/service/server/RegistrationDatabase.cpp:
+        (WebCore::databaseFilenameFromVersion): Ditto.
+
 2019-02-09  Zalan Bujtas  <zalan@apple.com>
 
         [LFC][IFC] Add intrinsic width support for basic inline containers
index 29ea779..983c1c1 100644 (file)
@@ -95,6 +95,7 @@ void IDBTransactionInfo::isolatedCopy(const IDBTransactionInfo& source, IDBTrans
 }
 
 #if !LOG_DISABLED
+
 String IDBTransactionInfo::loggingString() const
 {
     String modeString;
@@ -112,8 +113,9 @@ String IDBTransactionInfo::loggingString() const
         ASSERT_NOT_REACHED();
     }
     
-    return makeString("Transaction: ", m_identifier.loggingString(), " mode ", modeString, " newVersion ", String::number(m_newVersion));
+    return makeString("Transaction: ", m_identifier.loggingString(), " mode ", modeString, " newVersion ", m_newVersion);
 }
+
 #endif
 
 } // namespace WebCore
index 93c0fd7..8299bb9 100644 (file)
@@ -48,7 +48,7 @@ Ref<ThreadableWebSocketChannel> ThreadableWebSocketChannel::create(ScriptExecuti
     if (is<WorkerGlobalScope>(context)) {
         WorkerGlobalScope& workerGlobalScope = downcast<WorkerGlobalScope>(context);
         WorkerRunLoop& runLoop = workerGlobalScope.thread().runLoop();
-        return WorkerThreadableWebSocketChannel::create(workerGlobalScope, client, makeString("webSocketChannelMode", String::number(runLoop.createUniqueId())), provider);
+        return WorkerThreadableWebSocketChannel::create(workerGlobalScope, client, makeString("webSocketChannelMode", runLoop.createUniqueId()), provider);
     }
 
     return WebSocketChannel::create(downcast<Document>(context), client, provider);
index ac9cf79..c85a035 100644 (file)
@@ -234,7 +234,7 @@ ExceptionOr<void> WebSocket::connect(const String& url, const Vector<String>& pr
     if (!portAllowed(m_url)) {
         String message;
         if (m_url.port())
-            message = makeString("WebSocket port ", String::number(m_url.port().value()), " blocked");
+            message = makeString("WebSocket port ", static_cast<unsigned>(m_url.port().value()), " blocked");
         else
             message = "WebSocket without port blocked"_s;
         context.addConsoleMessage(MessageSource::JS, MessageLevel::Error, message);
index 24aea60..7fca5f0 100644 (file)
@@ -57,7 +57,6 @@
 #include <wtf/HashMap.h>
 #include <wtf/text/CString.h>
 #include <wtf/text/StringHash.h>
-#include <wtf/text/WTFString.h>
 
 namespace WebCore {
 
@@ -359,9 +358,9 @@ void WebSocketChannel::didFailSocketStream(SocketStreamHandle& handle, const Soc
     if (m_document) {
         String message;
         if (error.isNull())
-            message = "WebSocket network error";
+            message = "WebSocket network error"_s;
         else if (error.localizedDescription().isNull())
-            message = "WebSocket network error: error code " + String::number(error.errorCode());
+            message = makeString("WebSocket network error: error code ", error.errorCode());
         else
             message = "WebSocket network error: " + error.localizedDescription();
         InspectorInstrumentation::didReceiveWebSocketFrameError(m_document, m_identifier, message);
@@ -404,7 +403,7 @@ void WebSocketChannel::didFail(int errorCode)
     ASSERT(m_blobLoaderStatus == BlobLoaderStarted);
     m_blobLoader = nullptr;
     m_blobLoaderStatus = BlobLoaderFailed;
-    fail("Failed to load Blob: error code = " + String::number(errorCode)); // FIXME: Generate human-friendly reason message.
+    fail(makeString("Failed to load Blob: error code = ", errorCode)); // FIXME: Generate human-friendly reason message.
     deref();
 }
 
@@ -549,12 +548,12 @@ bool WebSocketChannel::processFrame()
 
     // Validate the frame data.
     if (WebSocketFrame::isReservedOpCode(frame.opCode)) {
-        fail("Unrecognized frame opcode: " + String::number(frame.opCode));
+        fail(makeString("Unrecognized frame opcode: ", static_cast<unsigned>(frame.opCode)));
         return false;
     }
 
     if (frame.reserved2 || frame.reserved3) {
-        fail("One or more reserved bits are on: reserved2 = " + String::number(frame.reserved2) + ", reserved3 = " + String::number(frame.reserved3));
+        fail(makeString("One or more reserved bits are on: reserved2 = ", static_cast<unsigned>(frame.reserved2), ", reserved3 = ", static_cast<unsigned>(frame.reserved3)));
         return false;
     }
 
@@ -565,14 +564,14 @@ bool WebSocketChannel::processFrame()
 
     // All control frames must not be fragmented.
     if (WebSocketFrame::isControlOpCode(frame.opCode) && !frame.final) {
-        fail("Received fragmented control frame: opcode = " + String::number(frame.opCode));
+        fail(makeString("Received fragmented control frame: opcode = ", static_cast<unsigned>(frame.opCode)));
         return false;
     }
 
     // All control frames must have a payload of 125 bytes or less, which means the frame must not contain
     // the "extended payload length" field.
     if (WebSocketFrame::isControlOpCode(frame.opCode) && WebSocketFrame::needsExtendedLengthField(frame.payloadLength)) {
-        fail("Received control frame having too long payload: " + String::number(frame.payloadLength) + " bytes");
+        fail(makeString("Received control frame having too long payload: ", frame.payloadLength, " bytes"));
         return false;
     }
 
index 0b52ecc..5a6e005 100644 (file)
@@ -93,7 +93,7 @@ WebSocketFrame::ParseFrameResult WebSocketFrame::parseFrame(char* data, size_t d
     static const uint64_t maxPayloadLength = UINT64_C(0x7FFFFFFFFFFFFFFF);
     size_t maskingKeyLength = masked ? maskingKeyWidthInBytes : 0;
     if (payloadLength64 > maxPayloadLength || payloadLength64 + maskingKeyLength > std::numeric_limits<size_t>::max()) {
-        errorString = "WebSocket frame length too large: " + String::number(payloadLength64) + " bytes";
+        errorString = makeString("WebSocket frame length too large: ", payloadLength64, " bytes");
         return FrameError;
     }
     size_t payloadLength = static_cast<size_t>(payloadLength64);
index d51cc32..141757c 100644 (file)
@@ -302,7 +302,7 @@ int WebSocketHandshake::readServerHandshake(const char* header, size_t len)
 
     if (statusCode != 101) {
         m_mode = Failed;
-        m_failureReason = makeString("Unexpected response code: ", String::number(statusCode));
+        m_failureReason = makeString("Unexpected response code: ", statusCode);
         return len;
     }
     m_mode = Normal;
index 78ad959..94233f0 100644 (file)
@@ -3676,7 +3676,7 @@ String AccessibilityRenderObject::positionalDescriptionForMSAA() const
     // See "positional descriptions",
     // https://wiki.mozilla.org/Accessibility/AT-Windows-API
     if (isHeading())
-        return "L" + String::number(headingLevel());
+        return makeString('L', headingLevel());
 
     // FIXME: Add positional descriptions for other elements.
     return String();
index cff39ab..f8b640d 100644 (file)
@@ -41,7 +41,7 @@ static const int64_t kJSMaxInteger = 0x20000000000000LL - 1; // 2^53 - 1, larges
 
 static String rangeErrorString(double value, double min, double max)
 {
-    return makeString("Value ", String::numberToStringECMAScript(value), " is outside the range [", String::numberToStringECMAScript(min), ", ", String::numberToStringECMAScript(max), "]");
+    return makeString("Value ", value, " is outside the range [", min, ", ", max, ']');
 }
 
 static double enforceRange(ExecState& state, double x, double minimum, double maximum)
index 5c414ab..7856097 100644 (file)
 #include "config.h"
 #include "CSSAspectRatioValue.h"
 
+#include <wtf/text/StringConcatenateNumbers.h>
+
 namespace WebCore {
 
 String CSSAspectRatioValue::customCSSText() const
 {
-    return String::number(m_numeratorValue) + '/' + String::number(m_denominatorValue);
+    return makeString(FormattedNumber::fixedPrecision(m_numeratorValue), '/', FormattedNumber::fixedPrecision(m_denominatorValue));
 }
 
 bool CSSAspectRatioValue::equals(const CSSAspectRatioValue& other) const
index 13996fb..260c7b4 100644 (file)
@@ -404,50 +404,50 @@ ExceptionOr<String> DOMMatrixReadOnly::toString() const
     StringBuilder builder;
     if (is2D()) {
         builder.appendLiteral("matrix(");
-        builder.append(String::numberToStringECMAScript(m_matrix.a()));
+        builder.appendECMAScriptNumber(m_matrix.a());
         builder.appendLiteral(", ");
-        builder.append(String::numberToStringECMAScript(m_matrix.b()));
+        builder.appendECMAScriptNumber(m_matrix.b());
         builder.appendLiteral(", ");
-        builder.append(String::numberToStringECMAScript(m_matrix.c()));
+        builder.appendECMAScriptNumber(m_matrix.c());
         builder.appendLiteral(", ");
-        builder.append(String::numberToStringECMAScript(m_matrix.d()));
+        builder.appendECMAScriptNumber(m_matrix.d());
         builder.appendLiteral(", ");
-        builder.append(String::numberToStringECMAScript(m_matrix.e()));
+        builder.appendECMAScriptNumber(m_matrix.e());
         builder.appendLiteral(", ");
-        builder.append(String::numberToStringECMAScript(m_matrix.f()));
+        builder.appendECMAScriptNumber(m_matrix.f());
     } else {
         builder.appendLiteral("matrix3d(");
-        builder.append(String::numberToStringECMAScript(m_matrix.m11()));
+        builder.appendECMAScriptNumber(m_matrix.m11());
         builder.appendLiteral(", ");
-        builder.append(String::numberToStringECMAScript(m_matrix.m12()));
+        builder.appendECMAScriptNumber(m_matrix.m12());
         builder.appendLiteral(", ");
-        builder.append(String::numberToStringECMAScript(m_matrix.m13()));
+        builder.appendECMAScriptNumber(m_matrix.m13());
         builder.appendLiteral(", ");
-        builder.append(String::numberToStringECMAScript(m_matrix.m14()));
+        builder.appendECMAScriptNumber(m_matrix.m14());
         builder.appendLiteral(", ");
-        builder.append(String::numberToStringECMAScript(m_matrix.m21()));
+        builder.appendECMAScriptNumber(m_matrix.m21());
         builder.appendLiteral(", ");
-        builder.append(String::numberToStringECMAScript(m_matrix.m22()));
+        builder.appendECMAScriptNumber(m_matrix.m22());
         builder.appendLiteral(", ");
-        builder.append(String::numberToStringECMAScript(m_matrix.m23()));
+        builder.appendECMAScriptNumber(m_matrix.m23());
         builder.appendLiteral(", ");
-        builder.append(String::numberToStringECMAScript(m_matrix.m24()));
+        builder.appendECMAScriptNumber(m_matrix.m24());
         builder.appendLiteral(", ");
-        builder.append(String::numberToStringECMAScript(m_matrix.m31()));
+        builder.appendECMAScriptNumber(m_matrix.m31());
         builder.appendLiteral(", ");
-        builder.append(String::numberToStringECMAScript(m_matrix.m32()));
+        builder.appendECMAScriptNumber(m_matrix.m32());
         builder.appendLiteral(", ");
-        builder.append(String::numberToStringECMAScript(m_matrix.m33()));
+        builder.appendECMAScriptNumber(m_matrix.m33());
         builder.appendLiteral(", ");
-        builder.append(String::numberToStringECMAScript(m_matrix.m34()));
+        builder.appendECMAScriptNumber(m_matrix.m34());
         builder.appendLiteral(", ");
-        builder.append(String::numberToStringECMAScript(m_matrix.m41()));
+        builder.appendECMAScriptNumber(m_matrix.m41());
         builder.appendLiteral(", ");
-        builder.append(String::numberToStringECMAScript(m_matrix.m42()));
+        builder.appendECMAScriptNumber(m_matrix.m42());
         builder.appendLiteral(", ");
-        builder.append(String::numberToStringECMAScript(m_matrix.m43()));
+        builder.appendECMAScriptNumber(m_matrix.m43());
         builder.appendLiteral(", ");
-        builder.append(String::numberToStringECMAScript(m_matrix.m44()));
+        builder.appendECMAScriptNumber(m_matrix.m44());
     }
     builder.append(')');
     return builder.toString();
index 1a88fea..69afc40 100644 (file)
@@ -203,50 +203,50 @@ ExceptionOr<String> WebKitCSSMatrix::toString() const
     StringBuilder builder;
     if (m_matrix.isAffine()) {
         builder.appendLiteral("matrix(");
-        builder.append(String::numberToStringECMAScript(m_matrix.a()));
+        builder.appendECMAScriptNumber(m_matrix.a());
         builder.appendLiteral(", ");
-        builder.append(String::numberToStringECMAScript(m_matrix.b()));
+        builder.appendECMAScriptNumber(m_matrix.b());
         builder.appendLiteral(", ");
-        builder.append(String::numberToStringECMAScript(m_matrix.c()));
+        builder.appendECMAScriptNumber(m_matrix.c());
         builder.appendLiteral(", ");
-        builder.append(String::numberToStringECMAScript(m_matrix.d()));
+        builder.appendECMAScriptNumber(m_matrix.d());
         builder.appendLiteral(", ");
-        builder.append(String::numberToStringECMAScript(m_matrix.e()));
+        builder.appendECMAScriptNumber(m_matrix.e());
         builder.appendLiteral(", ");
-        builder.append(String::numberToStringECMAScript(m_matrix.f()));
+        builder.appendECMAScriptNumber(m_matrix.f());
     } else {
         builder.appendLiteral("matrix3d(");
-        builder.append(String::numberToStringECMAScript(m_matrix.m11()));
+        builder.appendECMAScriptNumber(m_matrix.m11());
         builder.appendLiteral(", ");
-        builder.append(String::numberToStringECMAScript(m_matrix.m12()));
+        builder.appendECMAScriptNumber(m_matrix.m12());
         builder.appendLiteral(", ");
-        builder.append(String::numberToStringECMAScript(m_matrix.m13()));
+        builder.appendECMAScriptNumber(m_matrix.m13());
         builder.appendLiteral(", ");
-        builder.append(String::numberToStringECMAScript(m_matrix.m14()));
+        builder.appendECMAScriptNumber(m_matrix.m14());
         builder.appendLiteral(", ");
-        builder.append(String::numberToStringECMAScript(m_matrix.m21()));
+        builder.appendECMAScriptNumber(m_matrix.m21());
         builder.appendLiteral(", ");
-        builder.append(String::numberToStringECMAScript(m_matrix.m22()));
+        builder.appendECMAScriptNumber(m_matrix.m22());
         builder.appendLiteral(", ");
-        builder.append(String::numberToStringECMAScript(m_matrix.m23()));
+        builder.appendECMAScriptNumber(m_matrix.m23());
         builder.appendLiteral(", ");
-        builder.append(String::numberToStringECMAScript(m_matrix.m24()));
+        builder.appendECMAScriptNumber(m_matrix.m24());
         builder.appendLiteral(", ");
-        builder.append(String::numberToStringECMAScript(m_matrix.m31()));
+        builder.appendECMAScriptNumber(m_matrix.m31());
         builder.appendLiteral(", ");
-        builder.append(String::numberToStringECMAScript(m_matrix.m32()));
+        builder.appendECMAScriptNumber(m_matrix.m32());
         builder.appendLiteral(", ");
-        builder.append(String::numberToStringECMAScript(m_matrix.m33()));
+        builder.appendECMAScriptNumber(m_matrix.m33());
         builder.appendLiteral(", ");
-        builder.append(String::numberToStringECMAScript(m_matrix.m34()));
+        builder.appendECMAScriptNumber(m_matrix.m34());
         builder.appendLiteral(", ");
-        builder.append(String::numberToStringECMAScript(m_matrix.m41()));
+        builder.appendECMAScriptNumber(m_matrix.m41());
         builder.appendLiteral(", ");
-        builder.append(String::numberToStringECMAScript(m_matrix.m42()));
+        builder.appendECMAScriptNumber(m_matrix.m42());
         builder.appendLiteral(", ");
-        builder.append(String::numberToStringECMAScript(m_matrix.m43()));
+        builder.appendECMAScriptNumber(m_matrix.m43());
         builder.appendLiteral(", ");
-        builder.append(String::numberToStringECMAScript(m_matrix.m44()));
+        builder.appendECMAScriptNumber(m_matrix.m44());
     }
     builder.append(')');
     return builder.toString();
index d578a97..c08752c 100644 (file)
@@ -27,7 +27,7 @@
 
 #include "ProcessIdentifier.h"
 #include <wtf/Hasher.h>
-#include <wtf/text/WTFString.h>
+#include <wtf/text/StringConcatenateNumbers.h>
 
 namespace WebCore {
 
@@ -79,10 +79,12 @@ inline unsigned MessagePortIdentifier::hash() const
 }
 
 #if !LOG_DISABLED
+
 inline String MessagePortIdentifier::logString() const
 {
-    return makeString(String::number(processIdentifier.toUInt64()), "-", String::number(portIdentifier.toUInt64()));
+    return makeString(processIdentifier.toUInt64(), '-', portIdentifier.toUInt64());
 }
+
 #endif
 
 } // namespace WebCore
index 3a02181..ebe4bdc 100644 (file)
@@ -323,20 +323,20 @@ static String dataDetectorStringForPath(NSIndexPath *path)
     case 0:
         return { };
     case 1:
-        return String::number((unsigned long)[path indexAtPosition:0]);
+        return String::number([path indexAtPosition:0]);
     case 2: {
         StringBuilder stringBuilder;
-        stringBuilder.appendNumber((unsigned long)[path indexAtPosition:0]);
+        stringBuilder.appendNumber([path indexAtPosition:0]);
         stringBuilder.append('/');
-        stringBuilder.appendNumber((unsigned long)[path indexAtPosition:1]);
+        stringBuilder.appendNumber([path indexAtPosition:1]);
         return stringBuilder.toString();
     }
     default: {
         StringBuilder stringBuilder;
-        stringBuilder.appendNumber((unsigned long)[path indexAtPosition:0]);
+        stringBuilder.appendNumber([path indexAtPosition:0]);
         for (NSUInteger i = 1 ; i < length ; i++) {
             stringBuilder.append('/');
-            stringBuilder.appendNumber((unsigned long)[path indexAtPosition:i]);
+            stringBuilder.appendNumber([path indexAtPosition:i]);
         }
 
         return stringBuilder.toString();
index a4ee440..2dae52c 100644 (file)
@@ -28,7 +28,7 @@
 #include "ProcessIdentifier.h"
 #include <wtf/DebugUtilities.h>
 #include <wtf/Hasher.h>
-#include <wtf/text/WTFString.h>
+#include <wtf/text/StringConcatenateNumbers.h>
 
 namespace WebCore {
 
@@ -48,10 +48,12 @@ struct BackForwardItemIdentifier {
 };
 
 #if !LOG_DISABLED
+
 inline const char* BackForwardItemIdentifier::logString() const
 {
-    return debugString(String::number(processIdentifier.toUInt64()), "-", String::number(itemIdentifier.toUInt64()));
+    return debugString(makeString(processIdentifier.toUInt64(), '-', itemIdentifier.toUInt64()));
 }
+
 #endif
 
 inline bool operator==(const BackForwardItemIdentifier& a, const BackForwardItemIdentifier& b)
index 933f387..6a89c79 100644 (file)
@@ -248,9 +248,9 @@ static String processFileDateString(const FTPTime& fileTime)
     String dateString;
 
     if (fileTime.tm_year > -1)
-        dateString = makeString(months[month], ' ', String::number(fileTime.tm_mday), ", ", String::number(fileTime.tm_year));
+        dateString = makeString(months[month], ' ', fileTime.tm_mday, ", ", fileTime.tm_year);
     else
-        dateString = makeString(months[month], ' ', String::number(fileTime.tm_mday), ", ", String::number(now.year()));
+        dateString = makeString(months[month], ' ', fileTime.tm_mday, ", ", now.year());
 
     return dateString + timeOfDay;
 }
index 7b9c1c3..b0109b7 100644 (file)
@@ -2986,7 +2986,7 @@ RefPtr<WebGLUniformLocation> WebGLRenderingContextBase::getUniformLocation(WebGL
             info.name = info.name.left(info.name.length() - 3);
         // If it's an array, we need to iterate through each element, appending "[index]" to the name.
         for (GC3Dint index = 0; index < info.size; ++index) {
-            String uniformName = info.name + "[" + String::number(index) + "]";
+            String uniformName = makeString(info.name, '[', index, ']');
 
             if (name == uniformName || name == info.name)
                 return WebGLUniformLocation::create(program, uniformLocation, info.type);
@@ -5287,10 +5287,9 @@ bool WebGLRenderingContextBase::checkTextureCompleteness(const char* functionNam
         RefPtr<WebGLTexture> tex2D;
         RefPtr<WebGLTexture> texCubeMap;
         if (prepareToDraw) {
-            String msg(String("texture bound to texture unit ") + String::number(badTexture)
-                + " is not renderable. It maybe non-power-of-2 and have incompatible texture filtering or is not 'texture complete',"
-                + " or it is a float/half-float type with linear filtering and without the relevant float/half-float linear extension enabled.");
-            printToConsole(MessageLevel::Error, "WebGL: " + String(functionName) + ": " + msg);
+            printToConsole(MessageLevel::Error, makeString("WebGL: ", functionName, ": texture bound to texture unit ", badTexture,
+                " is not renderable. It maybe non-power-of-2 and have incompatible texture filtering or is not 'texture complete',"
+                " or it is a float/half-float type with linear filtering and without the relevant float/half-float linear extension enabled."));
             tex2D = m_blackTexture2D.get();
             texCubeMap = m_blackTextureCubeMap.get();
         } else {
index d3d43b6..1359fa6 100644 (file)
@@ -148,7 +148,7 @@ void WebConsoleAgent::didReceiveResponse(unsigned long requestIdentifier, const
         return;
 
     if (response.httpStatusCode() >= 400) {
-        String message = "Failed to load resource: the server responded with a status of " + String::number(response.httpStatusCode()) + " (" + response.httpStatusText() + ')';
+        String message = makeString("Failed to load resource: the server responded with a status of ", response.httpStatusCode(), " (", response.httpStatusText(), ')');
         addMessageToConsole(std::make_unique<ConsoleMessage>(MessageSource::Network, MessageType::Log, MessageLevel::Error, message, response.url().string(), 0, 0, nullptr, requestIdentifier));
     }
 }
index 66d3834..a1263e2 100644 (file)
@@ -52,8 +52,6 @@
 
 namespace WebCore {
 
-static const char loadResourceSynchronouslyMode[] = "loadResourceSynchronouslyMode";
-
 WorkerThreadableLoader::WorkerThreadableLoader(WorkerGlobalScope& workerGlobalScope, ThreadableLoaderClient& client, const String& taskMode, ResourceRequest&& request, const ThreadableLoaderOptions& options, const String& referrer)
     : m_workerGlobalScope(workerGlobalScope)
     , m_workerClientWrapper(ThreadableLoaderClientWrapper::create(client, options.initiator))
@@ -71,8 +69,7 @@ void WorkerThreadableLoader::loadResourceSynchronously(WorkerGlobalScope& worker
     WorkerRunLoop& runLoop = workerGlobalScope.thread().runLoop();
 
     // Create a unique mode just for this synchronous resource load.
-    String mode = loadResourceSynchronouslyMode;
-    mode.append(String::number(runLoop.createUniqueId()));
+    String mode = makeString("loadResourceSynchronouslyMode", runLoop.createUniqueId());
 
     auto loader = WorkerThreadableLoader::create(workerGlobalScope, client, mode, WTFMove(request), options, String());
     MessageQueueWaitResult result = MessageQueueMessageReceived;
index ecf43cb..8e38469 100644 (file)
@@ -664,17 +664,17 @@ void ApplicationCacheGroup::didFailLoadingManifest(ApplicationCacheResourceLoade
         break;
     case ApplicationCacheResourceLoader::Error::NotFound:
         InspectorInstrumentation::didFailLoading(m_frame, m_frame->loader().documentLoader(), m_currentResourceIdentifier, m_frame->loader().cancelledError(m_manifestLoader->resource()->resourceRequest()));
-        m_frame->document()->addConsoleMessage(MessageSource::AppCache, MessageLevel::Error, makeString("Application Cache manifest could not be fetched, because the manifest had a ", String::number(m_manifestLoader->resource()->response().httpStatusCode()), " response."));
+        m_frame->document()->addConsoleMessage(MessageSource::AppCache, MessageLevel::Error, makeString("Application Cache manifest could not be fetched, because the manifest had a ", m_manifestLoader->resource()->response().httpStatusCode(), " response."));
         manifestNotFound();
         break;
     case ApplicationCacheResourceLoader::Error::NotOK:
         InspectorInstrumentation::didFailLoading(m_frame, m_frame->loader().documentLoader(), m_currentResourceIdentifier, m_frame->loader().cancelledError(m_manifestLoader->resource()->resourceRequest()));
-        m_frame->document()->addConsoleMessage(MessageSource::AppCache, MessageLevel::Error, makeString("Application Cache manifest could not be fetched, because the manifest had a ", String::number(m_manifestLoader->resource()->response().httpStatusCode()), " response."));
+        m_frame->document()->addConsoleMessage(MessageSource::AppCache, MessageLevel::Error, makeString("Application Cache manifest could not be fetched, because the manifest had a ", m_manifestLoader->resource()->response().httpStatusCode(), " response."));
         cacheUpdateFailed();
         break;
     case ApplicationCacheResourceLoader::Error::RedirectForbidden:
         InspectorInstrumentation::didFailLoading(m_frame, m_frame->loader().documentLoader(), m_currentResourceIdentifier, m_frame->loader().cancelledError(m_manifestLoader->resource()->resourceRequest()));
-        m_frame->document()->addConsoleMessage(MessageSource::AppCache, MessageLevel::Error, makeString("Application Cache manifest could not be fetched, because a redirection was attempted."));
+        m_frame->document()->addConsoleMessage(MessageSource::AppCache, MessageLevel::Error, "Application Cache manifest could not be fetched, because a redirection was attempted."_s);
         cacheUpdateFailed();
         break;
     case ApplicationCacheResourceLoader::Error::CannotCreateResource:
index 6711603..6c1359b 100644 (file)
@@ -321,7 +321,7 @@ URL PageSerializer::urlForBlankFrame(Frame* frame)
     auto iter = m_blankFrameURLs.find(frame);
     if (iter != m_blankFrameURLs.end())
         return iter->value;
-    String url = "wyciwyg://frame/" + String::number(m_blankFrameCounter++);
+    String url = makeString("wyciwyg://frame/", m_blankFrameCounter++);
     URL fakeURL({ }, url);
     m_blankFrameURLs.add(frame, fakeURL);
     return fakeURL;
index 6d2b7fc..2c0be46 100644 (file)
@@ -29,7 +29,7 @@
 #include "StyleInheritedData.h"
 #include "StyleResolver.h"
 #include "StyleScope.h"
-#include <wtf/text/WTFString.h>
+#include <wtf/text/StringConcatenateNumbers.h>
 
 namespace WebCore {
 
@@ -335,7 +335,7 @@ String PrintContext::pageProperty(Frame* frame, const char* propertyName, int pa
     if (!strcmp(propertyName, "font-family"))
         return style->fontDescription().firstFamily();
     if (!strcmp(propertyName, "size"))
-        return String::number(style->pageSize().width.value()) + ' ' + String::number(style->pageSize().height.value());
+        return makeString(FormattedNumber::fixedPrecision(style->pageSize().width.value()), ' ', FormattedNumber::fixedPrecision(style->pageSize().height.value()));
 
     return makeString("pageProperty() unimplemented for: ", propertyName);
 }
@@ -350,8 +350,7 @@ String PrintContext::pageSizeAndMarginsInPixels(Frame* frame, int pageNumber, in
     IntSize pageSize(width, height);
     frame->document()->pageSizeAndMarginsInPixels(pageNumber, pageSize, marginTop, marginRight, marginBottom, marginLeft);
 
-    return "(" + String::number(pageSize.width()) + ", " + String::number(pageSize.height()) + ") " +
-           String::number(marginTop) + ' ' + String::number(marginRight) + ' ' + String::number(marginBottom) + ' ' + String::number(marginLeft);
+    return makeString('(', pageSize.width(), ", ", pageSize.height(), ") ", marginTop, ' ', marginRight, ' ', marginBottom, ' ', marginLeft);
 }
 
 bool PrintContext::beginAndComputePageRectsWithPageSize(Frame& frame, const FloatSize& pageSizeInPixels)
index ed549cf..a5c225e 100644 (file)
@@ -89,6 +89,7 @@ void WheelEventTestTrigger::removeTestDeferralForReason(ScrollableAreaIdentifier
 }
 
 #if !LOG_DISABLED
+
 static void dumpState(WTF::HashMap<WheelEventTestTrigger::ScrollableAreaIdentifier, WheelEventTestTrigger::DeferTestTriggerReasonSet> reasons)
 {
     LOG(WheelEventTestTriggers, "   WheelEventTestTrigger::dumpState:");
@@ -97,12 +98,13 @@ static void dumpState(WTF::HashMap<WheelEventTestTrigger::ScrollableAreaIdentifi
         StringBuilder reasons;
         for (const auto& reason : scrollRegion.value) {
             if (!reasons.isEmpty())
-                reasons.append(", ");
-            reasons.append(String::number(reason));
+                reasons.appendLiteral(", ");
+            reasons.appendNumber(static_cast<unsigned>(reason));
         }
         LOG(WheelEventTestTriggers, "     Reasons: %s", reasons.toString().utf8().data());
     }
 }
+
 #endif
     
 void WheelEventTestTrigger::triggerTestTimerFired()
index 3b274f8..198b298 100644 (file)
@@ -458,7 +458,7 @@ void ResourceUsageOverlay::platformDraw(CGContextRef context)
     CGContextClearRect(context, viewBounds);
 
     static CGColorRef colorForLabels = createColor(0.9, 0.9, 0.9, 1);
-    showText(context, 10, 20, colorForLabels, makeString("        CPU: ", FormattedNumber::fixedPrecision(data.cpu.last())));
+    showText(context, 10, 20, colorForLabels, makeString("        CPU: ", FormattedNumber::fixedPrecision(data.cpu.last(), 6, KeepTrailingZeros)));
     showText(context, 10, 30, colorForLabels, "  Footprint: " + formatByteNumber(memoryFootprint()));
     showText(context, 10, 40, colorForLabels, "   External: " + formatByteNumber(data.totalExternalSize.last()));
 
index 8b10a72..9532c91 100644 (file)
@@ -378,10 +378,7 @@ String Color::cssText() const
     builder.appendNumber(static_cast<unsigned char>(blue()));
     if (colorHasAlpha) {
         builder.appendLiteral(", ");
-
-        NumberToStringBuffer buffer;
-        bool shouldTruncateTrailingZeros = true;
-        builder.append(numberToFixedPrecisionString(alpha() / 255.0f, 6, buffer, shouldTruncateTrailingZeros));
+        builder.appendNumber(alpha() / 255.0f);
     }
         
     builder.append(')');
index 50e3c5c..fc27c08 100644 (file)
@@ -56,19 +56,16 @@ String ExtendedColor::cssText() const
         return WTF::emptyString();
     }
 
-    NumberToStringBuffer buffer;
-    bool shouldTruncateTrailingZeros = true;
-
-    builder.append(numberToFixedPrecisionString(red(), 6, buffer, shouldTruncateTrailingZeros));
+    builder.appendNumber(red());
     builder.append(' ');
 
-    builder.append(numberToFixedPrecisionString(green(), 6, buffer, shouldTruncateTrailingZeros));
+    builder.appendNumber(green());
     builder.append(' ');
 
-    builder.append(numberToFixedPrecisionString(blue(), 6, buffer, shouldTruncateTrailingZeros));
+    builder.appendNumber(blue());
     if (!WTF::areEssentiallyEqual(alpha(), 1.0f)) {
         builder.appendLiteral(" / ");
-        builder.append(numberToFixedPrecisionString(alpha(), 6, buffer, shouldTruncateTrailingZeros));
+        builder.appendNumber(alpha());
     }
     builder.append(')');
 
index 1818683..c60b770 100644 (file)
@@ -268,7 +268,7 @@ static ASCIILiteral propertyIdToString(AnimatedPropertyID property)
 
 static String animationIdentifier(const String& animationName, AnimatedPropertyID property, int index, int subIndex)
 {
-    return animationName + '_' + String::number(property) + '_' + String::number(index) + '_' + String::number(subIndex);
+    return makeString(animationName, '_', static_cast<unsigned>(property), '_', index, '_', subIndex);
 }
 
 static bool animationHasStepsTimingFunction(const KeyframeValueList& valueList, const Animation* anim)
index 2aac155..e1ae5d9 100644 (file)
@@ -23,7 +23,7 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
  */
 
-#include "config.h"
+#import "config.h"
 #import "PlatformCAFilters.h"
 
 #import "FloatConversion.h"
@@ -32,6 +32,7 @@
 #import <QuartzCore/QuartzCore.h>
 #import <pal/spi/cocoa/QuartzCoreSPI.h>
 #import <wtf/BlockObjCExceptions.h>
+#import <wtf/text/StringConcatenateNumbers.h>
 
 namespace WebCore {
 
@@ -68,10 +69,9 @@ void PlatformCAFilters::setFiltersOnLayer(PlatformLayer* layer, const FilterOper
     BEGIN_BLOCK_OBJC_EXCEPTIONS
     
     RetainPtr<NSMutableArray> array = adoptNS([[NSMutableArray alloc] init]);
-    static NeverDestroyed<String> filterNamePrefix(MAKE_STATIC_STRING_IMPL("filter_"));
 
     for (unsigned i = 0; i < filters.size(); ++i) {
-        String filterName = filterNamePrefix.get() + String::number(i);
+        String filterName = makeString("filter_", i);
         const FilterOperation& filterOperation = *filters.at(i);
         switch (filterOperation.type()) {
         case FilterOperation::DEFAULT:
index c5e2740..76e0928 100644 (file)
@@ -26,7 +26,7 @@
 
 #import "SharedBuffer.h"
 #import <pal/spi/cocoa/CoreTextSPI.h>
-#import <wtf/text/WTFString.h>
+#import <wtf/text/StringConcatenateNumbers.h>
 
 #if PLATFORM(IOS_FAMILY)
 #import <CoreText/CoreText.h>
@@ -197,12 +197,16 @@ RefPtr<SharedBuffer> FontPlatformData::openTypeTable(uint32_t table) const
 }
 
 #if !LOG_DISABLED
+
 String FontPlatformData::description() const
 {
-    auto fontDescription = adoptCF(CFCopyDescription(font()));
-    return String(fontDescription.get()) + " " + String::number(m_size)
-        + (m_syntheticBold ? " synthetic bold" : "") + (m_syntheticOblique ? " synthetic oblique" : "") + (m_orientation == FontOrientation::Vertical ? " vertical orientation" : "");
+    String fontDescription { adoptCF(CFCopyDescription(font())).get() };
+    return makeString(fontDescription, ' ', m_size,
+        (m_syntheticBold ? " synthetic bold" : ""),
+        (m_syntheticOblique ? " synthetic oblique" : ""),
+        (m_orientation == FontOrientation::Vertical ? " vertical orientation" : ""));
 }
+
 #endif
 
 } // namespace WebCore
index 593430c..434fb3f 100644 (file)
@@ -49,7 +49,7 @@ public:
 private:
     MockMediaSample(const MockSampleBox& box)
         : m_box(box)
-        , m_id(String::number(box.trackID()))
+        , m_id(AtomicString::number(box.trackID()))
     {
     }
 
index b703b64..148e272 100644 (file)
@@ -673,7 +673,7 @@ void SocketStreamHandleImpl::reportErrorToClient(CFErrorRef error)
     if (CFEqual(CFErrorGetDomain(error), kCFErrorDomainOSStatus)) {
         const char* descriptionOSStatus = GetMacOSStatusCommentString(static_cast<OSStatus>(errorCode));
         if (descriptionOSStatus && descriptionOSStatus[0] != '\0')
-            description = "OSStatus Error " + String::number(errorCode) + ": " + descriptionOSStatus;
+            description = makeString("OSStatus Error ", errorCode, ": ", descriptionOSStatus);
     }
 
     ALLOW_DEPRECATED_DECLARATIONS_END
index d7bc613..70ac0b7 100644 (file)
@@ -37,7 +37,7 @@
 #include <thread>
 #include <wtf/Threading.h>
 #include <wtf/text/CString.h>
-#include <wtf/text/WTFString.h>
+#include <wtf/text/StringConcatenateNumbers.h>
 
 namespace WebCore {
 
@@ -205,7 +205,7 @@ void SQLiteDatabase::setMaximumSize(int64_t size)
     LockHolder locker(m_authorizerLock);
     enableAuthorizer(false);
 
-    SQLiteStatement statement(*this, "PRAGMA max_page_count = " + String::number(newMaxPageCount));
+    SQLiteStatement statement(*this, makeString("PRAGMA max_page_count = ", newMaxPageCount));
     statement.prepare();
     if (statement.step() != SQLITE_ROW)
         LOG_ERROR("Failed to set maximum size of database to %lli bytes", static_cast<long long>(size));
@@ -264,7 +264,7 @@ int64_t SQLiteDatabase::totalSize()
 
 void SQLiteDatabase::setSynchronous(SynchronousPragma sync)
 {
-    executeCommand("PRAGMA synchronous = " + String::number(sync));
+    executeCommand(makeString("PRAGMA synchronous = ", static_cast<unsigned>(sync)));
 }
 
 void SQLiteDatabase::setBusyTimeout(int ms)
index 59cd769..91f15f6 100644 (file)
@@ -24,7 +24,7 @@
 
 #include "SVGParserUtilities.h"
 #include <wtf/MathExtras.h>
-#include <wtf/text/StringView.h>
+#include <wtf/text/StringConcatenateNumbers.h>
 
 namespace WebCore {
 
@@ -66,11 +66,11 @@ String SVGAngleValue::valueAsString() const
 {
     switch (m_unitType) {
     case SVG_ANGLETYPE_DEG:
-        return String::number(m_valueInSpecifiedUnits) + "deg";
+        return makeString(FormattedNumber::fixedPrecision(m_valueInSpecifiedUnits), "deg");
     case SVG_ANGLETYPE_RAD:
-        return String::number(m_valueInSpecifiedUnits) + "rad";
+        return makeString(FormattedNumber::fixedPrecision(m_valueInSpecifiedUnits), "rad");
     case SVG_ANGLETYPE_GRAD:
-        return String::number(m_valueInSpecifiedUnits) + "grad";
+        return makeString(FormattedNumber::fixedPrecision(m_valueInSpecifiedUnits), "grad");
     case SVG_ANGLETYPE_UNSPECIFIED:
     case SVG_ANGLETYPE_UNKNOWN:
         return String::number(m_valueInSpecifiedUnits);
index ae63396..dd2ede1 100644 (file)
@@ -29,7 +29,7 @@
 #include "SVGParserUtilities.h"
 #include <wtf/MathExtras.h>
 #include <wtf/NeverDestroyed.h>
-#include <wtf/text/StringView.h>
+#include <wtf/text/StringConcatenateNumbers.h>
 #include <wtf/text/TextStream.h>
 
 namespace WebCore {
@@ -232,7 +232,7 @@ ExceptionOr<void> SVGLengthValue::setValueAsString(const String& string)
 
 String SVGLengthValue::valueAsString() const
 {
-    return String::number(m_valueInSpecifiedUnits) + lengthTypeToString(extractType(m_unit));
+    return makeString(FormattedNumber::fixedPrecision(m_valueInSpecifiedUnits), lengthTypeToString(extractType(m_unit)));
 }
 
 ExceptionOr<void> SVGLengthValue::newValueSpecifiedUnits(unsigned short type, float value)
index fd3f10f..729e9cf 100644 (file)
@@ -1799,7 +1799,7 @@ ExceptionOr<String> Internals::configurationForViewport(float devicePixelRatio,
     restrictMinimumScaleFactorToViewportSize(attributes, IntSize(availableWidth, availableHeight), devicePixelRatio);
     restrictScaleFactorToInitialScaleIfNotUserScalable(attributes);
 
-    return String { "viewport size " + String::number(attributes.layoutSize.width()) + "x" + String::number(attributes.layoutSize.height()) + " scale " + String::number(attributes.initialScale) + " with limits [" + String::number(attributes.minimumScale) + ", " + String::number(attributes.maximumScale) + "] and userScalable " + (attributes.userScalable ? "true" : "false") };
+    return makeString("viewport size ", FormattedNumber::fixedPrecision(attributes.layoutSize.width()), 'x', FormattedNumber::fixedPrecision(attributes.layoutSize.height()), " scale ", FormattedNumber::fixedPrecision(attributes.initialScale), " with limits [", FormattedNumber::fixedPrecision(attributes.minimumScale), ", ", FormattedNumber::fixedPrecision(attributes.maximumScale), "] and userScalable ", (attributes.userScalable ? "true" : "false"));
 }
 
 ExceptionOr<bool> Internals::wasLastChangeUserEdit(Element& textField)
@@ -3332,8 +3332,7 @@ ExceptionOr<String> Internals::getCurrentCursorInfo()
 #if ENABLE(MOUSE_CURSOR_SCALE)
     if (cursor.imageScaleFactor() != 1) {
         result.appendLiteral(" scale=");
-        NumberToStringBuffer buffer;
-        result.append(numberToFixedPrecisionString(cursor.imageScaleFactor(), 8, buffer, true));
+        result.appendNumber(cursor.imageScaleFactor(), 8);
     }
 #endif
     return result.toString();
@@ -4149,7 +4148,7 @@ void Internals::queueMicroTask(int testNumber)
         return;
 
     auto microtask = std::make_unique<ActiveDOMCallbackMicrotask>(MicrotaskQueue::mainThreadQueue(), *document, [document, testNumber]() {
-        document->addConsoleMessage(MessageSource::JS, MessageLevel::Debug, makeString("MicroTask #", String::number(testNumber), " has run."));
+        document->addConsoleMessage(MessageSource::JS, MessageLevel::Debug, makeString("MicroTask #", testNumber, " has run."));
     });
 
     MicrotaskQueue::mainThreadQueue().append(WTFMove(microtask));
@@ -4177,7 +4176,7 @@ static void appendOffsets(StringBuilder& builder, const Vector<LayoutUnit>& snap
         else
             justStarting = false;
 
-        builder.append(String::number(coordinate.toUnsigned()));
+        builder.appendNumber(coordinate.toUnsigned());
     }
     builder.appendLiteral(" }");
 }
index b8170f5..6003a6d 100644 (file)
@@ -29,7 +29,7 @@
 
 #include "DocumentIdentifier.h"
 #include "ServiceWorkerTypes.h"
-#include <wtf/text/WTFString.h>
+#include <wtf/text/StringConcatenateNumbers.h>
 
 namespace WebCore {
 
@@ -39,7 +39,7 @@ struct ServiceWorkerClientIdentifier {
 
     unsigned hash() const;
 
-    String toString() const { return String::number(serverConnectionIdentifier.toUInt64()) + "-" +  String::number(contextIdentifier.toUInt64()); }
+    String toString() const { return makeString(serverConnectionIdentifier.toUInt64(), '-', contextIdentifier.toUInt64()); }
     static Optional<ServiceWorkerClientIdentifier> fromString(StringView);
 
     template<class Encoder> void encode(Encoder&) const;
index b629f43..55c8fce 100644 (file)
@@ -72,7 +72,7 @@ static const String recordsTableSchemaAlternate()
 
 static inline String databaseFilenameFromVersion(uint64_t version)
 {
-    return makeString("ServiceWorkerRegistrations-", String::number(version), ".sqlite3");
+    return makeString("ServiceWorkerRegistrations-", version, ".sqlite3");
 }
 
 static const String& databaseFilename()
index fa7baa5..ba2d066 100644 (file)
@@ -1,3 +1,38 @@
+2019-01-30  Darin Adler  <darin@apple.com>
+
+        Eliminate unnecessary String temporaries by using StringConcatenateNumbers
+        https://bugs.webkit.org/show_bug.cgi?id=194021
+
+        Reviewed by Geoffrey Garen.
+
+        * NetworkProcess/NetworkResourceLoader.cpp:
+        (WebKit::escapeIDForJSON): Use an ASCIILiteral to create a String.
+
+        * NetworkProcess/cache/NetworkCacheStorage.cpp:
+        (WebKit::NetworkCache::makeVersionedDirectoryPath): Remove String::number and let
+        makeString do the conversion without allocating/destroying a String.
+
+        * NetworkProcess/mac/RemoteNetworkingContext.mm: Removed "using namespace WebCore".
+        (WebKit::RemoteNetworkingContext::ensureWebsiteDataStoreSession): Remove String::number
+        and let makeString do the conversion without allocating/destroying a String.
+
+        * NetworkProcess/webrtc/NetworkMDNSRegister.cpp: Removed "using namespace WebCore".
+        (WebKit::registerMDNSNameCallback): Added explicit WebCore prefix as needed.
+        (WebKit::NetworkMDNSRegister::registerMDNSName): Ditto. Also remove String::number
+        and let makeString do the conversion without allocating/destroying a String.
+
+        * UIProcess/WebPageGroup.cpp:
+        (WebKit::pageGroupData): Remove String::number and let makeString do the conversion
+        without allocating/destroying a String.
+        * UIProcess/WebPageProxy.cpp:
+        (WebKit::WebPageProxy::createInspectorTargets): Ditto.
+        * UIProcess/ios/WKLegacyPDFView.mm:
+        (-[WKLegacyPDFView _URLForLinkAnnotation:]): Ditto.
+        * WebProcess/InjectedBundle/InjectedBundleScriptWorld.cpp:
+        (WebKit::uniqueWorldName): Ditto.
+        * WebProcess/WebPage/WebPageInspectorTarget.cpp:
+        (WebKit::WebPageInspectorTarget::identifier const): Ditto.
+
 2019-02-09  Alexander Mikhaylenko  <exalm7659@gmail.com>
 
         [GTK] Fix typo in the newly added API
index ee88695..fe8dca2 100644 (file)
@@ -959,7 +959,7 @@ static String escapeForJSON(String s)
 
 static String escapeIDForJSON(const Optional<uint64_t>& value)
 {
-    return value ? String::number(value.value()) : String("None");
+    return value ? String::number(value.value()) : String("None"_s);
 };
 
 void NetworkResourceLoader::logCookieInformation() const
index 2560eb3..8f4d61c 100644 (file)
@@ -37,6 +37,7 @@
 #include <wtf/RandomNumber.h>
 #include <wtf/RunLoop.h>
 #include <wtf/text/CString.h>
+#include <wtf/text/StringConcatenateNumbers.h>
 
 namespace WebKit {
 namespace NetworkCache {
@@ -144,7 +145,7 @@ public:
 
 static String makeVersionedDirectoryPath(const String& baseDirectoryPath)
 {
-    String versionSubdirectory = versionDirectoryPrefix + String::number(Storage::version);
+    String versionSubdirectory = makeString(versionDirectoryPrefix, Storage::version);
     return FileSystem::pathByAppendingComponent(baseDirectoryPath, versionSubdirectory);
 }
 
index f6d6dec..7129751 100644 (file)
@@ -37,9 +37,9 @@
 #import <WebCore/ResourceError.h>
 #import <pal/SessionID.h>
 #import <wtf/MainThread.h>
+#import <wtf/text/StringConcatenateNumbers.h>
 
 namespace WebKit {
-using namespace WebCore;
 
 void RemoteNetworkingContext::ensureWebsiteDataStoreSession(NetworkProcess& networkProcess, WebsiteDataStoreParameters&& parameters)
 {
@@ -58,7 +58,7 @@ void RemoteNetworkingContext::ensureWebsiteDataStoreSession(NetworkProcess& netw
     if (!sessionID.isEphemeral() && !parameters.uiProcessCookieStorageIdentifier.isEmpty())
         uiProcessCookieStorage = cookieStorageFromIdentifyingData(parameters.uiProcessCookieStorageIdentifier);
 
-    networkProcess.ensureSession(sessionID, base + '.' + String::number(sessionID.sessionID()), WTFMove(uiProcessCookieStorage));
+    networkProcess.ensureSession(sessionID, makeString(base, '.', sessionID.sessionID()), WTFMove(uiProcessCookieStorage));
 
     auto* session = networkProcess.storageSession(sessionID);
     for (const auto& cookie : parameters.pendingCookies)
index 9fd0df8..04de3dd 100644 (file)
@@ -33,9 +33,9 @@
 #include "WebMDNSRegisterMessages.h"
 #include <pal/SessionID.h>
 #include <wtf/UUID.h>
+#include <wtf/text/StringConcatenateNumbers.h>
 
 namespace WebKit {
-using namespace WebCore;
 
 #define RELEASE_LOG_IF_ALLOWED(sessionID, fmt, ...) RELEASE_LOG_IF(sessionID.isAlwaysOnLoggingAllowed(), Network, "%p - NetworkMDNSRegister::" fmt, this, ##__VA_ARGS__)
 #define RELEASE_LOG_IF_ALLOWED_IN_CALLBACK(sessionID, fmt, ...) RELEASE_LOG_IF(sessionID.isAlwaysOnLoggingAllowed(), Network, "NetworkMDNSRegister callback - " fmt, ##__VA_ARGS__)
@@ -97,13 +97,13 @@ static void registerMDNSNameCallback(DNSServiceRef, DNSRecordRef record, DNSServ
     RELEASE_LOG_IF_ALLOWED_IN_CALLBACK(request->sessionID, "registerMDNSNameCallback with error %d", errorCode);
 
     if (errorCode) {
-        request->connection->send(Messages::WebMDNSRegister::FinishedRegisteringMDNSName { request->requestIdentifier, makeUnexpected(MDNSRegisterError::DNSSD) }, 0);
+        request->connection->send(Messages::WebMDNSRegister::FinishedRegisteringMDNSName { request->requestIdentifier, makeUnexpected(WebCore::MDNSRegisterError::DNSSD) }, 0);
         return;
     }
     request->connection->send(Messages::WebMDNSRegister::FinishedRegisteringMDNSName { request->requestIdentifier, request->name }, 0);
 }
 
-void NetworkMDNSRegister::registerMDNSName(uint64_t requestIdentifier, PAL::SessionID sessionID, DocumentIdentifier documentIdentifier, const String& ipAddress)
+void NetworkMDNSRegister::registerMDNSName(uint64_t requestIdentifier, PAL::SessionID sessionID, WebCore::DocumentIdentifier documentIdentifier, const String& ipAddress)
 {
     DNSServiceRef service;
     auto iterator = m_services.find(documentIdentifier);
@@ -111,13 +111,13 @@ void NetworkMDNSRegister::registerMDNSName(uint64_t requestIdentifier, PAL::Sess
         auto error = DNSServiceCreateConnection(&service);
         if (error) {
             RELEASE_LOG_IF_ALLOWED(sessionID, "registerMDNSName DNSServiceCreateConnection error %d", error);
-            m_connection.connection().send(Messages::WebMDNSRegister::FinishedRegisteringMDNSName { requestIdentifier, makeUnexpected(MDNSRegisterError::DNSSD) }, 0);
+            m_connection.connection().send(Messages::WebMDNSRegister::FinishedRegisteringMDNSName { requestIdentifier, makeUnexpected(WebCore::MDNSRegisterError::DNSSD) }, 0);
             return;
         }
         error = DNSServiceSetDispatchQueue(service, dispatch_get_main_queue());
         if (error) {
             RELEASE_LOG_IF_ALLOWED(sessionID, "registerMDNSName DNSServiceCreateConnection error %d", error);
-            m_connection.connection().send(Messages::WebMDNSRegister::FinishedRegisteringMDNSName { requestIdentifier, makeUnexpected(MDNSRegisterError::DNSSD) }, 0);
+            m_connection.connection().send(Messages::WebMDNSRegister::FinishedRegisteringMDNSName { requestIdentifier, makeUnexpected(WebCore::MDNSRegisterError::DNSSD) }, 0);
             return;
         }
         ASSERT(service);
@@ -125,14 +125,13 @@ void NetworkMDNSRegister::registerMDNSName(uint64_t requestIdentifier, PAL::Sess
     } else
         service = iterator->value;
 
-    String baseName = createCanonicalUUIDString();
-    String name = makeString(baseName, String::number(pendingRegistrationRequestCount), ".local");
+    String name = makeString(createCanonicalUUIDString(), pendingRegistrationRequestCount, ".local");
 
     auto ip = inet_addr(ipAddress.utf8().data());
 
     if (ip == ( in_addr_t)(-1)) {
         RELEASE_LOG_IF_ALLOWED(sessionID, "registerMDNSName inet_addr error");
-        m_connection.connection().send(Messages::WebMDNSRegister::FinishedRegisteringMDNSName { requestIdentifier, makeUnexpected(MDNSRegisterError::BadParameter) }, 0);
+        m_connection.connection().send(Messages::WebMDNSRegister::FinishedRegisteringMDNSName { requestIdentifier, makeUnexpected(WebCore::MDNSRegisterError::BadParameter) }, 0);
         return;
     }
 
@@ -152,20 +151,22 @@ void NetworkMDNSRegister::registerMDNSName(uint64_t requestIdentifier, PAL::Sess
         reinterpret_cast<void*>(pendingRegistrationRequestCount));
     if (error) {
         RELEASE_LOG_IF_ALLOWED(sessionID, "registerMDNSName DNSServiceRegisterRecord error %d", error);
-        m_connection.connection().send(Messages::WebMDNSRegister::FinishedRegisteringMDNSName { requestIdentifier, makeUnexpected(MDNSRegisterError::DNSSD) }, 0);
+        m_connection.connection().send(Messages::WebMDNSRegister::FinishedRegisteringMDNSName { requestIdentifier, makeUnexpected(WebCore::MDNSRegisterError::DNSSD) }, 0);
         return;
     }
     pendingRegistrationRequests().add(pendingRegistrationRequestCount++, WTFMove(pendingRequest));
 }
+
 #else
+
 void NetworkMDNSRegister::unregisterMDNSNames(WebCore::DocumentIdentifier)
 {
 }
 
-void NetworkMDNSRegister::registerMDNSName(uint64_t requestIdentifier, PAL::SessionID sessionID, DocumentIdentifier documentIdentifier, const String& ipAddress)
+void NetworkMDNSRegister::registerMDNSName(uint64_t requestIdentifier, PAL::SessionID sessionID, WebCore::DocumentIdentifier documentIdentifier, const String& ipAddress)
 {
     RELEASE_LOG_IF_ALLOWED(sessionID, "registerMDNSName not implemented");
-    m_connection.connection().send(Messages::WebMDNSRegister::FinishedRegisteringMDNSName { requestIdentifier, makeUnexpected(MDNSRegisterError::NotImplemented) }, 0);
+    m_connection.connection().send(Messages::WebMDNSRegister::FinishedRegisteringMDNSName { requestIdentifier, makeUnexpected(WebCore::MDNSRegisterError::NotImplemented) }, 0);
 }
 
 #endif
index 6f5ef07..08bf54b 100644 (file)
@@ -73,7 +73,7 @@ static WebPageGroupData pageGroupData(const String& identifier)
     if (!identifier.isEmpty())
         data.identifier = identifier;
     else
-        data.identifier = makeString("__uniquePageGroupID-", String::number(data.pageGroupID));
+        data.identifier = makeString("__uniquePageGroupID-", data.pageGroupID);
 
     return data;
 }
index b5151c7..8cbe391 100644 (file)
@@ -1535,7 +1535,7 @@ void WebPageProxy::clearInspectorTargets()
 
 void WebPageProxy::createInspectorTargets()
 {
-    String pageTargetId = makeString("page-", String::number(m_pageID));
+    String pageTargetId = makeString("page-", m_pageID);
     m_inspectorController->createInspectorTarget(pageTargetId, Inspector::InspectorTargetType::Page);
 }
 
index 551ec32..8312084 100644 (file)
@@ -486,8 +486,7 @@ static void detachViewForPage(PDFPageInfo& page)
         return [NSURL URLWithString:url.relativeString relativeToURL:documentURL];
 
     if (NSUInteger pageNumber = linkAnnotation.pageNumber) {
-        String anchorString = "#page"_s;
-        anchorString.append(String::number(pageNumber));
+        String anchorString = makeString("#page", pageNumber);
         return [NSURL URLWithString:anchorString relativeToURL:documentURL];
     }
 
index 49a79b2..9cd3a4a 100644 (file)
@@ -47,7 +47,7 @@ static WorldMap& allWorlds()
 static String uniqueWorldName()
 {
     static uint64_t uniqueWorldNameNumber = 0;
-    return makeString("UniqueWorld_"_s, String::number(uniqueWorldNameNumber++));
+    return makeString("UniqueWorld_", uniqueWorldNameNumber++);
 }
 
 Ref<InjectedBundleScriptWorld> InjectedBundleScriptWorld::create()
index f1bea50..d96a7d7 100644 (file)
@@ -41,7 +41,7 @@ WebPageInspectorTarget::WebPageInspectorTarget(WebPage& page)
 
 String WebPageInspectorTarget::identifier() const
 {
-    return makeString("page-", String::number(m_page.pageID()));
+    return makeString("page-", m_page.pageID());
 }
 
 void WebPageInspectorTarget::connect(Inspector::FrontendChannel& channel)
index aad018d..9f0404d 100644 (file)
@@ -1,3 +1,14 @@
+2019-02-04  Darin Adler  <darin@apple.com>
+
+        Eliminate unnecessary String temporaries by using StringConcatenateNumbers
+        https://bugs.webkit.org/show_bug.cgi?id=194021
+
+        Reviewed by Geoffrey Garen.
+
+        * TestWebKitAPI/Tests/WTF/StringConcatenate.cpp:
+        (TestWebKitAPI::TEST): Change tests to use EXPECT_STREQ so failure messages are easier
+        to understand. Updated tests for changes to FormattedNumber::fixedPrecision.
+
 2019-02-09  Zalan Bujtas  <zalan@apple.com>
 
         [LFC][IFC] Add intrinsic width support for basic inline containers
index aa231fc..1d2ee17 100644 (file)
@@ -42,115 +42,118 @@ struct S {
 
 TEST(WTF, StringConcatenate)
 {
-    EXPECT_EQ("hello world", makeString("hello", " ", "world"));
+    EXPECT_STREQ("hello world", makeString("hello", " ", "world").utf8().data());
 }
 
 TEST(WTF, StringConcatenate_Int)
 {
     EXPECT_EQ(5u, WTF::lengthOfNumberAsStringSigned(17890));
-    EXPECT_EQ("hello 17890 world", makeString("hello ", 17890 , " world"));
-    EXPECT_EQ("hello 17890 world", makeString("hello ", 17890l , " world"));
-    EXPECT_EQ("hello 17890 world", makeString("hello ", 17890ll , " world"));
-    EXPECT_EQ("hello 17890 world", makeString("hello ", static_cast<int64_t>(17890) , " world"));
-    EXPECT_EQ("hello 17890 world", makeString("hello ", static_cast<int64_t>(17890) , " world"));
+    EXPECT_STREQ("hello 17890 world", makeString("hello ", 17890 , " world").utf8().data());
+    EXPECT_STREQ("hello 17890 world", makeString("hello ", 17890l , " world").utf8().data());
+    EXPECT_STREQ("hello 17890 world", makeString("hello ", 17890ll , " world").utf8().data());
+    EXPECT_STREQ("hello 17890 world", makeString("hello ", static_cast<int64_t>(17890) , " world").utf8().data());
+    EXPECT_STREQ("hello 17890 world", makeString("hello ", static_cast<int64_t>(17890) , " world").utf8().data());
 
     EXPECT_EQ(6u, WTF::lengthOfNumberAsStringSigned(-17890));
-    EXPECT_EQ("hello -17890 world", makeString("hello ", -17890 , " world"));
-    EXPECT_EQ("hello -17890 world", makeString("hello ", -17890l , " world"));
-    EXPECT_EQ("hello -17890 world", makeString("hello ", -17890ll , " world"));
-    EXPECT_EQ("hello -17890 world", makeString("hello ", static_cast<int64_t>(-17890) , " world"));
-    EXPECT_EQ("hello -17890 world", makeString("hello ", static_cast<int64_t>(-17890) , " world"));
+    EXPECT_STREQ("hello -17890 world", makeString("hello ", -17890 , " world").utf8().data());
+    EXPECT_STREQ("hello -17890 world", makeString("hello ", -17890l , " world").utf8().data());
+    EXPECT_STREQ("hello -17890 world", makeString("hello ", -17890ll , " world").utf8().data());
+    EXPECT_STREQ("hello -17890 world", makeString("hello ", static_cast<int64_t>(-17890) , " world").utf8().data());
+    EXPECT_STREQ("hello -17890 world", makeString("hello ", static_cast<int64_t>(-17890) , " world").utf8().data());
 
     EXPECT_EQ(1u, WTF::lengthOfNumberAsStringSigned(0));
-    EXPECT_EQ("hello 0 world", makeString("hello ", 0 , " world"));
+    EXPECT_STREQ("hello 0 world", makeString("hello ", 0 , " world").utf8().data());
 
-    EXPECT_EQ("hello 42 world", makeString("hello ", static_cast<signed char>(42) , " world"));
-    EXPECT_EQ("hello 42 world", makeString("hello ", static_cast<short>(42) , " world"));
-    EXPECT_EQ("hello 1 world", makeString("hello ", &arr[1] - &arr[0] , " world"));
+    EXPECT_STREQ("hello 42 world", makeString("hello ", static_cast<signed char>(42) , " world").utf8().data());
+    EXPECT_STREQ("hello 42 world", makeString("hello ", static_cast<short>(42) , " world").utf8().data());
+    EXPECT_STREQ("hello 1 world", makeString("hello ", &arr[1] - &arr[0] , " world").utf8().data());
 }
 
 TEST(WTF, StringConcatenate_Unsigned)
 {
     EXPECT_EQ(5u, WTF::lengthOfNumberAsStringUnsigned(17890u));
-    EXPECT_EQ("hello 17890 world", makeString("hello ", 17890u , " world"));
-    EXPECT_EQ("hello 17890 world", makeString("hello ", 17890ul , " world"));
-    EXPECT_EQ("hello 17890 world", makeString("hello ", 17890ull , " world"));
-    EXPECT_EQ("hello 17890 world", makeString("hello ", static_cast<uint64_t>(17890) , " world"));
-    EXPECT_EQ("hello 17890 world", makeString("hello ", static_cast<uint64_t>(17890) , " world"));
+    EXPECT_STREQ("hello 17890 world", makeString("hello ", 17890u , " world").utf8().data());
+    EXPECT_STREQ("hello 17890 world", makeString("hello ", 17890ul , " world").utf8().data());
+    EXPECT_STREQ("hello 17890 world", makeString("hello ", 17890ull , " world").utf8().data());
+    EXPECT_STREQ("hello 17890 world", makeString("hello ", static_cast<uint64_t>(17890) , " world").utf8().data());
+    EXPECT_STREQ("hello 17890 world", makeString("hello ", static_cast<uint64_t>(17890) , " world").utf8().data());
 
     EXPECT_EQ(1u, WTF::lengthOfNumberAsStringSigned(0u));
-    EXPECT_EQ("hello 0 world", makeString("hello ", 0u , " world"));
+    EXPECT_STREQ("hello 0 world", makeString("hello ", 0u , " world").utf8().data());
 
-    EXPECT_EQ("hello 42 world", makeString("hello ", static_cast<unsigned char>(42) , " world"));
+    EXPECT_STREQ("hello 42 world", makeString("hello ", static_cast<unsigned char>(42) , " world").utf8().data());
 #if PLATFORM(WIN) || (U_ICU_VERSION_MAJOR_NUM >= 59 && !PLATFORM(COCOA))
-    EXPECT_EQ("hello 42 world", makeString("hello ", static_cast<unsigned short>(42) , " world"));
+    EXPECT_STREQ("hello 42 world", makeString("hello ", static_cast<unsigned short>(42) , " world").utf8().data());
 #else
-    EXPECT_EQ("hello * world", makeString("hello ", static_cast<unsigned short>(42) , " world")); // Treated as a character.
+    EXPECT_STREQ("hello * world", makeString("hello ", static_cast<unsigned short>(42) , " world").utf8().data()); // Treated as a character.
 #endif
-    EXPECT_EQ("hello 4 world", makeString("hello ", sizeof(int) , " world")); // size_t
-    EXPECT_EQ("hello 4 world", makeString("hello ", offsetof(S, i) , " world")); // size_t
-    EXPECT_EQ("hello 3235839742 world", makeString("hello ", static_cast<size_t>(0xc0defefe), " world"));
+    EXPECT_STREQ("hello 4 world", makeString("hello ", sizeof(int) , " world").utf8().data()); // size_t
+    EXPECT_STREQ("hello 4 world", makeString("hello ", offsetof(S, i) , " world").utf8().data()); // size_t
+    EXPECT_STREQ("hello 3235839742 world", makeString("hello ", static_cast<size_t>(0xc0defefe), " world").utf8().data());
 }
 
 TEST(WTF, StringConcatenate_Float)
 {
-    EXPECT_EQ("hello 17890 world", makeString("hello ", 17890.0f , " world"));
-    EXPECT_EQ("hello 17890.5 world", makeString("hello ", 17890.5f , " world"));
+    EXPECT_STREQ("hello 17890 world", makeString("hello ", 17890.0f , " world").utf8().data());
+    EXPECT_STREQ("hello 17890.5 world", makeString("hello ", 17890.5f , " world").utf8().data());
 
-    EXPECT_EQ("hello -17890 world", makeString("hello ", -17890.0f , " world"));
-    EXPECT_EQ("hello -17890.5 world", makeString("hello ", -17890.5f , " world"));
+    EXPECT_STREQ("hello -17890 world", makeString("hello ", -17890.0f , " world").utf8().data());
+    EXPECT_STREQ("hello -17890.5 world", makeString("hello ", -17890.5f , " world").utf8().data());
 
-    EXPECT_EQ("hello 0 world", makeString("hello ", 0.0f , " world"));
+    EXPECT_STREQ("hello 0 world", makeString("hello ", 0.0f , " world").utf8().data());
 }
 
 TEST(WTF, StringConcatenate_Double)
 {
-    EXPECT_EQ("hello 17890 world", makeString("hello ", 17890.0 , " world"));
-    EXPECT_EQ("hello 17890.5 world", makeString("hello ", 17890.5 , " world"));
+    EXPECT_STREQ("hello 17890 world", makeString("hello ", 17890.0 , " world").utf8().data());
+    EXPECT_STREQ("hello 17890.5 world", makeString("hello ", 17890.5 , " world").utf8().data());
 
-    EXPECT_EQ("hello -17890 world", makeString("hello ", -17890.0 , " world"));
-    EXPECT_EQ("hello -17890.5 world", makeString("hello ", -17890.5 , " world"));
+    EXPECT_STREQ("hello -17890 world", makeString("hello ", -17890.0 , " world").utf8().data());
+    EXPECT_STREQ("hello -17890.5 world", makeString("hello ", -17890.5 , " world").utf8().data());
 
-    EXPECT_EQ("hello 0 world", makeString("hello ", 0.0 , " world"));
+    EXPECT_STREQ("hello 0 world", makeString("hello ", 0.0 , " world").utf8().data());
 }
 
 TEST(WTF, StringConcatenate_FormattedDoubleFixedPrecision)
 {
-    EXPECT_EQ("hello 17890.0 world", makeString("hello ", FormattedNumber::fixedPrecision(17890.0) , " world"));
-    EXPECT_EQ("hello 1.79e+4 world", makeString("hello ", FormattedNumber::fixedPrecision(17890.0, 3) , " world"));
-    EXPECT_EQ("hello 17890.000 world", makeString("hello ", FormattedNumber::fixedPrecision(17890.0, 8) , " world"));
-    EXPECT_EQ("hello 17890 world", makeString("hello ", FormattedNumber::fixedPrecision(17890.0, 8, true) , " world"));
-
-    EXPECT_EQ("hello 17890.5 world", makeString("hello ", FormattedNumber::fixedPrecision(17890.5) , " world"));
-    EXPECT_EQ("hello 1.79e+4 world", makeString("hello ", FormattedNumber::fixedPrecision(17890.5, 3) , " world"));
-    EXPECT_EQ("hello 17890.500 world", makeString("hello ", FormattedNumber::fixedPrecision(17890.5, 8) , " world"));
-    EXPECT_EQ("hello 17890.5 world", makeString("hello ", FormattedNumber::fixedPrecision(17890.5, 8, true) , " world"));
-
-    EXPECT_EQ("hello -17890.0 world", makeString("hello ", FormattedNumber::fixedPrecision(-17890.0) , " world"));
-    EXPECT_EQ("hello -1.79e+4 world", makeString("hello ", FormattedNumber::fixedPrecision(-17890.0, 3) , " world"));
-    EXPECT_EQ("hello -17890.000 world", makeString("hello ", FormattedNumber::fixedPrecision(-17890.0, 8) , " world"));
-    EXPECT_EQ("hello -17890 world", makeString("hello ", FormattedNumber::fixedPrecision(-17890.0, 8, true) , " world"));
-
-    EXPECT_EQ("hello -17890.5 world", makeString("hello ", FormattedNumber::fixedPrecision(-17890.5) , " world"));
-    EXPECT_EQ("hello -1.79e+4 world", makeString("hello ", FormattedNumber::fixedPrecision(-17890.5, 3) , " world"));
-    EXPECT_EQ("hello -17890.500 world", makeString("hello ", FormattedNumber::fixedPrecision(-17890.5, 8) , " world"));
-    EXPECT_EQ("hello -17890.5 world", makeString("hello ", FormattedNumber::fixedPrecision(-17890.5, 8, true) , " world"));
-
-    EXPECT_EQ("hello 0.00000 world", makeString("hello ", FormattedNumber::fixedPrecision(0.0) , " world"));
-    EXPECT_EQ("hello 0.00 world", makeString("hello ", FormattedNumber::fixedPrecision(0.0, 3) , " world"));
-    EXPECT_EQ("hello 0.0000000 world", makeString("hello ", FormattedNumber::fixedPrecision(0.0, 8) , " world"));
-    EXPECT_EQ("hello 0 world", makeString("hello ", FormattedNumber::fixedPrecision(0.0, 8, true) , " world"));
+    EXPECT_STREQ("hello 17890 world", makeString("hello ", FormattedNumber::fixedPrecision(17890.0) , " world").utf8().data());
+    EXPECT_STREQ("hello 17890.0 world", makeString("hello ", FormattedNumber::fixedPrecision(17890.0, 6, KeepTrailingZeros) , " world").utf8().data());
+    EXPECT_STREQ("hello 1.79e+4 world", makeString("hello ", FormattedNumber::fixedPrecision(17890.0, 3, KeepTrailingZeros) , " world").utf8().data());
+    EXPECT_STREQ("hello 17890.000 world", makeString("hello ", FormattedNumber::fixedPrecision(17890.0, 8, KeepTrailingZeros) , " world").utf8().data());
+    EXPECT_STREQ("hello 17890 world", makeString("hello ", FormattedNumber::fixedPrecision(17890.0, 8) , " world").utf8().data());
+
+    EXPECT_STREQ("hello 17890.5 world", makeString("hello ", FormattedNumber::fixedPrecision(17890.5) , " world").utf8().data());
+    EXPECT_STREQ("hello 1.79e+4 world", makeString("hello ", FormattedNumber::fixedPrecision(17890.5, 3, KeepTrailingZeros) , " world").utf8().data());
+    EXPECT_STREQ("hello 17890.500 world", makeString("hello ", FormattedNumber::fixedPrecision(17890.5, 8, KeepTrailingZeros) , " world").utf8().data());
+    EXPECT_STREQ("hello 17890.5 world", makeString("hello ", FormattedNumber::fixedPrecision(17890.5, 8) , " world").utf8().data());
+
+    EXPECT_STREQ("hello -17890 world", makeString("hello ", FormattedNumber::fixedPrecision(-17890.0) , " world").utf8().data());
+    EXPECT_STREQ("hello -17890.0 world", makeString("hello ", FormattedNumber::fixedPrecision(-17890.0, 6, KeepTrailingZeros) , " world").utf8().data());
+    EXPECT_STREQ("hello -1.79e+4 world", makeString("hello ", FormattedNumber::fixedPrecision(-17890.0, 3, KeepTrailingZeros) , " world").utf8().data());
+    EXPECT_STREQ("hello -17890.000 world", makeString("hello ", FormattedNumber::fixedPrecision(-17890.0, 8, KeepTrailingZeros) , " world").utf8().data());
+    EXPECT_STREQ("hello -17890 world", makeString("hello ", FormattedNumber::fixedPrecision(-17890.0, 8) , " world").utf8().data());
+
+    EXPECT_STREQ("hello -17890.5 world", makeString("hello ", FormattedNumber::fixedPrecision(-17890.5) , " world").utf8().data());
+    EXPECT_STREQ("hello -1.79e+4 world", makeString("hello ", FormattedNumber::fixedPrecision(-17890.5, 3, KeepTrailingZeros) , " world").utf8().data());
+    EXPECT_STREQ("hello -17890.500 world", makeString("hello ", FormattedNumber::fixedPrecision(-17890.5, 8, KeepTrailingZeros) , " world").utf8().data());
+    EXPECT_STREQ("hello -17890.5 world", makeString("hello ", FormattedNumber::fixedPrecision(-17890.5, 8) , " world").utf8().data());
+
+    EXPECT_STREQ("hello 0 world", makeString("hello ", FormattedNumber::fixedPrecision(0.0) , " world").utf8().data());
+    EXPECT_STREQ("hello 0.00000 world", makeString("hello ", FormattedNumber::fixedPrecision(0.0, 6, KeepTrailingZeros) , " world").utf8().data());
+    EXPECT_STREQ("hello 0.00 world", makeString("hello ", FormattedNumber::fixedPrecision(0.0, 3, KeepTrailingZeros) , " world").utf8().data());
+    EXPECT_STREQ("hello 0.0000000 world", makeString("hello ", FormattedNumber::fixedPrecision(0.0, 8, KeepTrailingZeros) , " world").utf8().data());
+    EXPECT_STREQ("hello 0 world", makeString("hello ", FormattedNumber::fixedPrecision(0.0, 8) , " world").utf8().data());
 }
 
 TEST(WTF, StringConcatenate_FormattedDoubleFixedWidth)
 {
-    EXPECT_EQ("hello 17890.000 world", makeString("hello ", FormattedNumber::fixedWidth(17890.0, 3) , " world"));
-    EXPECT_EQ("hello 17890.500 world", makeString("hello ", FormattedNumber::fixedWidth(17890.5, 3) , " world"));
+    EXPECT_STREQ("hello 17890.000 world", makeString("hello ", FormattedNumber::fixedWidth(17890.0, 3) , " world").utf8().data());
+    EXPECT_STREQ("hello 17890.500 world", makeString("hello ", FormattedNumber::fixedWidth(17890.5, 3) , " world").utf8().data());
 
-    EXPECT_EQ("hello -17890.000 world", makeString("hello ", FormattedNumber::fixedWidth(-17890.0, 3) , " world"));
-    EXPECT_EQ("hello -17890.500 world", makeString("hello ", FormattedNumber::fixedWidth(-17890.5, 3) , " world"));
+    EXPECT_STREQ("hello -17890.000 world", makeString("hello ", FormattedNumber::fixedWidth(-17890.0, 3) , " world").utf8().data());
+    EXPECT_STREQ("hello -17890.500 world", makeString("hello ", FormattedNumber::fixedWidth(-17890.5, 3) , " world").utf8().data());
 
-    EXPECT_EQ("hello 0.000 world", makeString("hello ", FormattedNumber::fixedWidth(0.0, 3) , " world"));
+    EXPECT_STREQ("hello 0.000 world", makeString("hello ", FormattedNumber::fixedWidth(0.0, 3) , " world").utf8().data());
 }
 
 }