Title: [125320] trunk
Revision
125320
Author
[email protected]
Date
2012-08-10 13:18:15 -0700 (Fri, 10 Aug 2012)

Log Message

Add support for String initialization from literal to WTFString
https://bugs.webkit.org/show_bug.cgi?id=93426

Patch by Benjamin Poulain <[email protected]> on 2012-08-10
Reviewed by Anders Carlsson.

Source/WTF: 

This patch adds two constructor to WTF::String in order to support fast initialization from literal:
-String(ASCIILiteral): Constructor similar to String(const char*) while being faster. This constructor
 does not incur any overhead over String(const char*).
-String(char[], ConstructFromLiteralTag): Template constructor that encode explicitely the size of the
 string.

String(ASCIILiteral) is expected to be used in most cases to avoid regressions. This constructor was
added because of what we have learned from r124922: inlining the string length in the code causes a code bloat
that is not always welcome.

Regarding performance of string initialization, the constructors performance are (6 characters string):
-String(ASCIILiteral): 16% faster.
-String(char[], ConstructFromLiteralTag): 33% faster (the delta increases with the string length).

In addition, no memory is allocated for the characters.

* wtf/text/StringImpl.cpp:
* wtf/text/StringImpl.h:
(WTF::StringImpl::createFromLiteral): Extend StringImpl::createFromLiteral to have a version
with strlen() which avoids loading one extra argument.
* wtf/text/WTFString.cpp:
(WTF::String::String):
* wtf/text/WTFString.h:
(WTF::String::String):
(ASCIILiteral): This class is aimed at making the construction of WTFString from a literal very easy.
By using the explicit constructor ASCIILiteral(char *), one can expect the implicit conversion to String
when needed.
(WTF::ASCIILiteral::ASCIILiteral):
(WTF::ASCIILiteral::operator const char*):

Tools: 

* TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
* TestWebKitAPI/Tests/WTF/StringImpl.cpp:
(TestWebKitAPI::TEST):
* TestWebKitAPI/Tests/WTF/WTFString.cpp: Copied from Tools/TestWebKitAPI/Tests/WTF/StringImpl.cpp.
(TestWebKitAPI):
(TestWebKitAPI::TEST):

Modified Paths

Added Paths

Diff

Modified: trunk/Source/WTF/ChangeLog (125319 => 125320)


--- trunk/Source/WTF/ChangeLog	2012-08-10 20:16:45 UTC (rev 125319)
+++ trunk/Source/WTF/ChangeLog	2012-08-10 20:18:15 UTC (rev 125320)
@@ -1,3 +1,40 @@
+2012-08-10  Benjamin Poulain  <[email protected]>
+
+        Add support for String initialization from literal to WTFString
+        https://bugs.webkit.org/show_bug.cgi?id=93426
+
+        Reviewed by Anders Carlsson.
+
+        This patch adds two constructor to WTF::String in order to support fast initialization from literal:
+        -String(ASCIILiteral): Constructor similar to String(const char*) while being faster. This constructor
+         does not incur any overhead over String(const char*).
+        -String(char[], ConstructFromLiteralTag): Template constructor that encode explicitely the size of the
+         string.
+
+        String(ASCIILiteral) is expected to be used in most cases to avoid regressions. This constructor was
+        added because of what we have learned from r124922: inlining the string length in the code causes a code bloat
+        that is not always welcome.
+
+        Regarding performance of string initialization, the constructors performance are (6 characters string):
+        -String(ASCIILiteral): 16% faster.
+        -String(char[], ConstructFromLiteralTag): 33% faster (the delta increases with the string length).
+
+        In addition, no memory is allocated for the characters.
+
+        * wtf/text/StringImpl.cpp:
+        * wtf/text/StringImpl.h:
+        (WTF::StringImpl::createFromLiteral): Extend StringImpl::createFromLiteral to have a version
+        with strlen() which avoids loading one extra argument.
+        * wtf/text/WTFString.cpp:
+        (WTF::String::String):
+        * wtf/text/WTFString.h:
+        (WTF::String::String):
+        (ASCIILiteral): This class is aimed at making the construction of WTFString from a literal very easy.
+        By using the explicit constructor ASCIILiteral(char *), one can expect the implicit conversion to String
+        when needed.
+        (WTF::ASCIILiteral::ASCIILiteral):
+        (WTF::ASCIILiteral::operator const char*):
+
 2012-08-08  Benjamin Poulain  <[email protected]>
 
         Use char* instead of LChar* for the public interface of String construction from literals

Modified: trunk/Source/WTF/wtf/text/StringImpl.cpp (125319 => 125320)


--- trunk/Source/WTF/wtf/text/StringImpl.cpp	2012-08-10 20:16:45 UTC (rev 125319)
+++ trunk/Source/WTF/wtf/text/StringImpl.cpp	2012-08-10 20:18:15 UTC (rev 125320)
@@ -88,6 +88,13 @@
     return adoptRef(new StringImpl(characters, length, ConstructFromLiteral));
 }
 
+PassRefPtr<StringImpl> StringImpl::createFromLiteral(const char* characters)
+{
+    size_t length = strlen(characters);
+    ASSERT(charactersAreAllASCII<LChar>(reinterpret_cast<const LChar*>(characters), length));
+    return adoptRef(new StringImpl(characters, length, ConstructFromLiteral));
+}
+
 PassRefPtr<StringImpl> StringImpl::createUninitialized(unsigned length, LChar*& data)
 {
     if (!length) {

Modified: trunk/Source/WTF/wtf/text/StringImpl.h (125319 => 125320)


--- trunk/Source/WTF/wtf/text/StringImpl.h	2012-08-10 20:16:45 UTC (rev 125319)
+++ trunk/Source/WTF/wtf/text/StringImpl.h	2012-08-10 20:18:15 UTC (rev 125320)
@@ -306,6 +306,7 @@
 
         return createFromLiteral(characters, charactersCount - 1);
     }
+    WTF_EXPORT_STRING_API static PassRefPtr<StringImpl> createFromLiteral(const char* characters);
 
     WTF_EXPORT_STRING_API static PassRefPtr<StringImpl> createUninitialized(unsigned length, LChar*& data);
     WTF_EXPORT_STRING_API static PassRefPtr<StringImpl> createUninitialized(unsigned length, UChar*& data);

Modified: trunk/Source/WTF/wtf/text/WTFString.cpp (125319 => 125320)


--- trunk/Source/WTF/wtf/text/WTFString.cpp	2012-08-10 20:16:45 UTC (rev 125319)
+++ trunk/Source/WTF/wtf/text/WTFString.cpp	2012-08-10 20:18:15 UTC (rev 125320)
@@ -84,6 +84,11 @@
 {
 }
 
+String::String(ASCIILiteral characters)
+    : m_impl(StringImpl::createFromLiteral(characters))
+{
+}
+
 void String::append(const String& str)
 {
     if (str.isEmpty())

Modified: trunk/Source/WTF/wtf/text/WTFString.h (125319 => 125320)


--- trunk/Source/WTF/wtf/text/WTFString.h	2012-08-10 20:16:45 UTC (rev 125319)
+++ trunk/Source/WTF/wtf/text/WTFString.h	2012-08-10 20:18:15 UTC (rev 125320)
@@ -94,6 +94,8 @@
 WTF_EXPORT_STRING_API float charactersToFloat(const LChar*, size_t, size_t& parsedLength);
 WTF_EXPORT_STRING_API float charactersToFloat(const UChar*, size_t, size_t& parsedLength);
 
+class ASCIILiteral;
+
 enum FloatConversionFlags {
     ShouldRoundSignificantFigures = 1 << 0,
     ShouldRoundDecimalPlaces = 1 << 1,
@@ -131,6 +133,15 @@
     String(PassRefPtr<StringImpl> impl) : m_impl(impl) { }
     String(RefPtr<StringImpl> impl) : m_impl(impl) { }
 
+    // Construct a string from a constant string literal.
+    WTF_EXPORT_STRING_API String(ASCIILiteral characters);
+
+    // Construct a string from a constant string literal.
+    // This constructor is the "big" version, as it put the length in the function call and generate bigger code.
+    enum ConstructFromLiteralTag { ConstructFromLiteral };
+    template<unsigned charactersCount>
+    String(const char (&characters)[charactersCount], ConstructFromLiteralTag) : m_impl(StringImpl::createFromLiteral<charactersCount>(characters)) { }
+
 #if COMPILER_SUPPORTS(CXX_RVALUE_REFERENCES)
     // We have to declare the copy constructor and copy assignment operator as well, otherwise
     // they'll be implicitly deleted by adding the move constructor and move assignment operator.
@@ -588,6 +599,15 @@
 
 template <> struct VectorTraits<String> : SimpleClassVectorTraits { };
 
+class ASCIILiteral {
+public:
+    explicit ASCIILiteral(const char* characters) : m_characters(characters) { }
+    operator const char*() { return m_characters; }
+
+private:
+    const char* m_characters;
+};
+
 // Shared global empty string.
 WTF_EXPORT_STRING_API const String& emptyString();
 
@@ -618,6 +638,7 @@
 using WTF::isSpaceOrNewline;
 using WTF::reverseFind;
 using WTF::ShouldRoundDecimalPlaces;
+using WTF::ASCIILiteral;
 
 #include <wtf/text/AtomicString.h>
 #endif

Modified: trunk/Tools/ChangeLog (125319 => 125320)


--- trunk/Tools/ChangeLog	2012-08-10 20:16:45 UTC (rev 125319)
+++ trunk/Tools/ChangeLog	2012-08-10 20:18:15 UTC (rev 125320)
@@ -1,3 +1,17 @@
+2012-08-10  Benjamin Poulain  <[email protected]>
+
+        Add support for String initialization from literal to WTFString
+        https://bugs.webkit.org/show_bug.cgi?id=93426
+
+        Reviewed by Anders Carlsson.
+
+        * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
+        * TestWebKitAPI/Tests/WTF/StringImpl.cpp:
+        (TestWebKitAPI::TEST):
+        * TestWebKitAPI/Tests/WTF/WTFString.cpp: Copied from Tools/TestWebKitAPI/Tests/WTF/StringImpl.cpp.
+        (TestWebKitAPI):
+        (TestWebKitAPI::TEST):
+
 2012-08-10  Xianzhu Wang  <[email protected]>
 
         NRWT crashes when DRT with --encode-binary crashes just before it dumps pixels

Modified: trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj (125319 => 125320)


--- trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj	2012-08-10 20:16:45 UTC (rev 125319)
+++ trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj	2012-08-10 20:18:15 UTC (rev 125320)
@@ -22,6 +22,7 @@
 		1ADBEFE3130C6AA100D61D19 /* simple-accelerated-compositing.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 1ADBEFBC130C6A0100D61D19 /* simple-accelerated-compositing.html */; };
 		1AEDE22613E5E7E700E62FE8 /* InjectedBundleControllerMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1AEDE22413E5E7A000E62FE8 /* InjectedBundleControllerMac.mm */; };
 		261516D615B0E60500A2C201 /* SetAndUpdateCacheModel.mm in Sources */ = {isa = PBXBuildFile; fileRef = 261516D515B0E60500A2C201 /* SetAndUpdateCacheModel.mm */; };
+		265AF55015D1E48A00B0CB4A /* WTFString.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 265AF54F15D1E48A00B0CB4A /* WTFString.cpp */; };
 		26B2DFF915BDE599004F691D /* HashSet.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26B2DFF815BDE599004F691D /* HashSet.cpp */; };
 		26DF5A5E15A29BAA003689C2 /* CancelLoadFromResourceLoadDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = 26DF5A5D15A29BAA003689C2 /* CancelLoadFromResourceLoadDelegate.mm */; };
 		26DF5A6315A2A27E003689C2 /* CancelLoadFromResourceLoadDelegate.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 26DF5A6115A2A22B003689C2 /* CancelLoadFromResourceLoadDelegate.html */; };
@@ -251,6 +252,7 @@
 		1ADBEFBC130C6A0100D61D19 /* simple-accelerated-compositing.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "simple-accelerated-compositing.html"; sourceTree = "<group>"; };
 		1AEDE22413E5E7A000E62FE8 /* InjectedBundleControllerMac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = InjectedBundleControllerMac.mm; sourceTree = "<group>"; };
 		261516D515B0E60500A2C201 /* SetAndUpdateCacheModel.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = SetAndUpdateCacheModel.mm; sourceTree = "<group>"; };
+		265AF54F15D1E48A00B0CB4A /* WTFString.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = WTFString.cpp; path = WTF/WTFString.cpp; sourceTree = "<group>"; };
 		26B2DFF815BDE599004F691D /* HashSet.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = HashSet.cpp; path = WTF/HashSet.cpp; sourceTree = "<group>"; };
 		26DF5A5D15A29BAA003689C2 /* CancelLoadFromResourceLoadDelegate.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = CancelLoadFromResourceLoadDelegate.mm; sourceTree = "<group>"; };
 		26DF5A6115A2A22B003689C2 /* CancelLoadFromResourceLoadDelegate.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = CancelLoadFromResourceLoadDelegate.html; sourceTree = "<group>"; };
@@ -640,6 +642,7 @@
 				BC55F5F814AD78EE00484BE1 /* Vector.cpp */,
 				BC90964B125561BF00083756 /* VectorBasic.cpp */,
 				37200B9113A16230007A4FAD /* VectorReverse.cpp */,
+				265AF54F15D1E48A00B0CB4A /* WTFString.cpp */,
 			);
 			name = WTF;
 			sourceTree = "<group>";
@@ -965,6 +968,7 @@
 				26B2DFF915BDE599004F691D /* HashSet.cpp in Sources */,
 				00CD9F6315BE312C002DA2CE /* BackForwardList.mm in Sources */,
 				CD5497B415857F0C00B5BC30 /* MediaTime.cpp in Sources */,
+				265AF55015D1E48A00B0CB4A /* WTFString.cpp in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};

Modified: trunk/Tools/TestWebKitAPI/Tests/WTF/StringImpl.cpp (125319 => 125320)


--- trunk/Tools/TestWebKitAPI/Tests/WTF/StringImpl.cpp	2012-08-10 20:16:45 UTC (rev 125319)
+++ trunk/Tools/TestWebKitAPI/Tests/WTF/StringImpl.cpp	2012-08-10 20:18:15 UTC (rev 125320)
@@ -31,12 +31,14 @@
 
 TEST(WTF, StringImplCreationFromLiteral)
 {
+    // Constructor using the template to determine the size.
     RefPtr<StringImpl> stringWithTemplate = StringImpl::createFromLiteral("Template Literal");
     ASSERT_EQ(strlen("Template Literal"), stringWithTemplate->length());
     ASSERT_TRUE(equal(stringWithTemplate.get(), "Template Literal"));
     ASSERT_TRUE(stringWithTemplate->is8Bit());
     ASSERT_TRUE(stringWithTemplate->hasTerminatingNullCharacter());
 
+    // Constructor taking the size explicitely.
     const char* programmaticStringData = "Explicit Size Literal";
     RefPtr<StringImpl> programmaticString = StringImpl::createFromLiteral(programmaticStringData, strlen(programmaticStringData));
     ASSERT_EQ(strlen(programmaticStringData), programmaticString->length());
@@ -44,6 +46,15 @@
     ASSERT_EQ(programmaticStringData, reinterpret_cast<const char*>(programmaticString->characters8()));
     ASSERT_TRUE(programmaticString->is8Bit());
     ASSERT_TRUE(programmaticString->hasTerminatingNullCharacter());
+
+    // Constructor without explicit size.
+    const char* stringWithoutLengthLiteral = "No Size Literal";
+    RefPtr<StringImpl> programmaticStringNoLength = StringImpl::createFromLiteral(stringWithoutLengthLiteral);
+    ASSERT_EQ(strlen(stringWithoutLengthLiteral), programmaticStringNoLength->length());
+    ASSERT_TRUE(equal(programmaticStringNoLength.get(), stringWithoutLengthLiteral));
+    ASSERT_EQ(stringWithoutLengthLiteral, reinterpret_cast<const char*>(programmaticStringNoLength->characters8()));
+    ASSERT_TRUE(programmaticStringNoLength->is8Bit());
+    ASSERT_TRUE(programmaticStringNoLength->hasTerminatingNullCharacter());
 }
 
 TEST(WTF, StringImplFromLiteralLoop16BitConversion)

Added: trunk/Tools/TestWebKitAPI/Tests/WTF/WTFString.cpp (0 => 125320)


--- trunk/Tools/TestWebKitAPI/Tests/WTF/WTFString.cpp	                        (rev 0)
+++ trunk/Tools/TestWebKitAPI/Tests/WTF/WTFString.cpp	2012-08-10 20:18:15 UTC (rev 125320)
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2012 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include <wtf/text/WTFString.h>
+
+namespace TestWebKitAPI {
+
+TEST(WTF, StringCreationFromLiteral)
+{
+    String stringFromLiteral(ASCIILiteral("Explicit construction syntax"));
+    ASSERT_EQ(strlen("Explicit construction syntax"), stringFromLiteral.length());
+    ASSERT_TRUE(stringFromLiteral == "Explicit construction syntax");
+    ASSERT_TRUE(stringFromLiteral.is8Bit());
+    ASSERT_TRUE(stringFromLiteral.impl()->hasTerminatingNullCharacter());
+    ASSERT_TRUE(String("Explicit construction syntax") == stringFromLiteral);
+
+    String stringWithTemplate("Template Literal", String::ConstructFromLiteral);
+    ASSERT_EQ(strlen("Template Literal"), stringWithTemplate.length());
+    ASSERT_TRUE(stringWithTemplate == "Template Literal");
+    ASSERT_TRUE(stringWithTemplate.is8Bit());
+    ASSERT_TRUE(stringWithTemplate.impl()->hasTerminatingNullCharacter());
+    ASSERT_TRUE(String("Template Literal") == stringWithTemplate);
+}
+
+} // namespace TestWebKitAPI
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to