Title: [123689] trunk/Source
Revision
123689
Author
[email protected]
Date
2012-07-25 18:05:23 -0700 (Wed, 25 Jul 2012)

Log Message

Initialize QualifiedName's strings from the read only data segment
https://bugs.webkit.org/show_bug.cgi?id=92226

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

Source/WebCore: 

Modify the initialization of static QualifiedName to initialize the AtomicString
with the data from the read only memory.

Overall, HTMLNames::init() gets 10% faster.

* dom/QualifiedName.cpp:
(WebCore::QualifiedName::QualifiedName):
* dom/QualifiedName.h:
(QualifiedName):
Remove the useless constructor taking a char* and get rid of the init() function.
The AtomicString representing the name should be constructed by the caller of QualifiedName.

Because the init() code is relatively large and is only executed once, it is important to
keep the AtomicString construction separate. The function createQualifiedName() was added
to improve the cache use. The short version let us reduce the code one more instruction per
call.

* dom/make_names.pl:
(printQualifiedNameMaker):
(printShortQualifiedNameMaker):
(printNamesCppFile):
(printDefinitions):

Source/WTF: 

Add constructors for StringImpl and AtomicString to be able to create
the strings from the literal in read only memory.

* wtf/text/AtomicString.cpp:
(HashTranslatorCharBuffer):
(WTF::LCharBufferFromLiteralDataTranslator::hash):
(LCharBufferFromLiteralDataTranslator):
(WTF::LCharBufferFromLiteralDataTranslator::equal):
(WTF::LCharBufferFromLiteralDataTranslator::translate):
(WTF::AtomicString::addFromLiteralData):
* wtf/text/AtomicString.h:
(WTF::AtomicString::AtomicString):
(AtomicString):
* wtf/text/StringImpl.cpp:
(WTF::StringImpl::createFromLiteral):
* wtf/text/StringImpl.h:
(WTF):
(StringImpl):
(WTF::StringImpl::createFromLiteral):

Modified Paths

Diff

Modified: trunk/Source/WTF/ChangeLog (123688 => 123689)


--- trunk/Source/WTF/ChangeLog	2012-07-26 01:01:24 UTC (rev 123688)
+++ trunk/Source/WTF/ChangeLog	2012-07-26 01:05:23 UTC (rev 123689)
@@ -1,3 +1,30 @@
+2012-07-25  Benjamin Poulain  <[email protected]>
+
+        Initialize QualifiedName's strings from the read only data segment
+        https://bugs.webkit.org/show_bug.cgi?id=92226
+
+        Reviewed by Anders Carlsson.
+
+        Add constructors for StringImpl and AtomicString to be able to create
+        the strings from the literal in read only memory.
+
+        * wtf/text/AtomicString.cpp:
+        (HashTranslatorCharBuffer):
+        (WTF::LCharBufferFromLiteralDataTranslator::hash):
+        (LCharBufferFromLiteralDataTranslator):
+        (WTF::LCharBufferFromLiteralDataTranslator::equal):
+        (WTF::LCharBufferFromLiteralDataTranslator::translate):
+        (WTF::AtomicString::addFromLiteralData):
+        * wtf/text/AtomicString.h:
+        (WTF::AtomicString::AtomicString):
+        (AtomicString):
+        * wtf/text/StringImpl.cpp:
+        (WTF::StringImpl::createFromLiteral):
+        * wtf/text/StringImpl.h:
+        (WTF):
+        (StringImpl):
+        (WTF::StringImpl::createFromLiteral):
+
 2012-07-25  Michael Saboff  <[email protected]>
 
         Convert HTML parser to handle 8-bit resources without converting to UChar*

Modified: trunk/Source/WTF/wtf/text/AtomicString.cpp (123688 => 123689)


--- trunk/Source/WTF/wtf/text/AtomicString.cpp	2012-07-26 01:01:24 UTC (rev 123688)
+++ trunk/Source/WTF/wtf/text/AtomicString.cpp	2012-07-26 01:05:23 UTC (rev 123689)
@@ -114,11 +114,13 @@
     return addToStringTable<const LChar*, CStringTranslator>(c);
 }
 
-struct UCharBuffer {
-    const UChar* s;
+template<typename CharacterType>
+struct HashTranslatorCharBuffer {
+    const CharacterType* s;
     unsigned length;
 };
 
+typedef HashTranslatorCharBuffer<UChar> UCharBuffer;
 struct UCharBufferTranslator {
     static unsigned hash(const UCharBuffer& buf)
     {
@@ -295,6 +297,35 @@
     return addToStringTable<SubstringLocation, SubstringTranslator>(buffer);
 }
 
+typedef HashTranslatorCharBuffer<LChar> LCharBuffer;
+struct LCharBufferFromLiteralDataTranslator {
+    static unsigned hash(const LCharBuffer& buf)
+    {
+        return StringHasher::computeHash(buf.s, buf.length);
+    }
+
+    static bool equal(StringImpl* const& str, const LCharBuffer& buf)
+    {
+        return WTF::equal(str, buf.s, buf.length);
+    }
+
+    static void translate(StringImpl*& location, const LCharBuffer& buf, unsigned hash)
+    {
+        location = StringImpl::createFromLiteral(buf.s, buf.length).leakRef();
+        location->setHash(hash);
+        location->setIsAtomic(true);
+    }
+};
+
+PassRefPtr<StringImpl> AtomicString::addFromLiteralData(const LChar *characters, unsigned length)
+{
+    ASSERT(characters);
+    ASSERT(length);
+
+    LCharBuffer buffer = { characters, length };
+    return addToStringTable<LCharBuffer, LCharBufferFromLiteralDataTranslator>(buffer);
+}
+
 PassRefPtr<StringImpl> AtomicString::addSlowCase(StringImpl* r)
 {
     if (!r->length())

Modified: trunk/Source/WTF/wtf/text/AtomicString.h (123688 => 123689)


--- trunk/Source/WTF/wtf/text/AtomicString.h	2012-07-26 01:01:24 UTC (rev 123688)
+++ trunk/Source/WTF/wtf/text/AtomicString.h	2012-07-26 01:05:23 UTC (rev 123689)
@@ -51,6 +51,19 @@
     ATOMICSTRING_CONVERSION AtomicString(const String& s) : m_string(add(s.impl())) { }
     AtomicString(StringImpl* baseString, unsigned start, unsigned length) : m_string(add(baseString, start, length)) { }
 
+    enum ConstructFromLiteralTag { ConstructFromLiteral };
+    AtomicString(const char* characters, unsigned length, ConstructFromLiteralTag)
+        : m_string(addFromLiteralData(reinterpret_cast<const LChar*>(characters), length))
+    {
+    }
+    template<unsigned charactersCount>
+    ALWAYS_INLINE AtomicString(const char (&characters)[charactersCount], ConstructFromLiteralTag)
+        : m_string(addFromLiteralData(reinterpret_cast<const LChar*>(characters), charactersCount - 1))
+    {
+        COMPILE_ASSERT(charactersCount > 1, AtomicStringFromLiteralNotEmpty);
+        COMPILE_ASSERT((charactersCount - 1 <= ((unsigned(~0) - sizeof(StringImpl)) / sizeof(LChar))), AtomicStringFromLiteralCannotOverflow);
+    }
+
 #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.
@@ -156,6 +169,7 @@
             return r;
         return addSlowCase(r);
     }
+    WTF_EXPORT_PRIVATE static PassRefPtr<StringImpl> addFromLiteralData(const LChar *characters, unsigned length);
     WTF_EXPORT_PRIVATE static PassRefPtr<StringImpl> addSlowCase(StringImpl*);
     WTF_EXPORT_PRIVATE static AtomicString fromUTF8Internal(const char*, const char*);
 };

Modified: trunk/Source/WTF/wtf/text/StringImpl.cpp (123688 => 123689)


--- trunk/Source/WTF/wtf/text/StringImpl.cpp	2012-07-26 01:01:24 UTC (rev 123688)
+++ trunk/Source/WTF/wtf/text/StringImpl.cpp	2012-07-26 01:05:23 UTC (rev 123689)
@@ -82,6 +82,12 @@
     m_substringBuffer->deref();
 }
 
+PassRefPtr<StringImpl> StringImpl::createFromLiteral(const LChar* characters, unsigned length)
+{
+    ASSERT(charactersAreAllASCII<LChar>(characters, length));
+    return adoptRef(new StringImpl(characters, length));
+}
+
 PassRefPtr<StringImpl> StringImpl::createUninitialized(unsigned length, LChar*& data)
 {
     if (!length) {

Modified: trunk/Source/WTF/wtf/text/StringImpl.h (123688 => 123689)


--- trunk/Source/WTF/wtf/text/StringImpl.h	2012-07-26 01:01:24 UTC (rev 123688)
+++ trunk/Source/WTF/wtf/text/StringImpl.h	2012-07-26 01:05:23 UTC (rev 123689)
@@ -58,6 +58,7 @@
 struct CStringTranslator;
 struct HashAndCharactersTranslator;
 struct HashAndUTF8CharactersTranslator;
+struct LCharBufferFromLiteralDataTranslator;
 struct SubstringTranslator;
 struct UCharBufferTranslator;
 
@@ -75,6 +76,7 @@
     friend struct WTF::CStringTranslator;
     friend struct WTF::HashAndCharactersTranslator;
     friend struct WTF::HashAndUTF8CharactersTranslator;
+    friend struct WTF::LCharBufferFromLiteralDataTranslator;
     friend struct WTF::SubstringTranslator;
     friend struct WTF::UCharBufferTranslator;
     friend class AtomicStringImpl;
@@ -282,6 +284,16 @@
         return adoptRef(new StringImpl(rep->m_data16 + offset, length, ownerRep));
     }
 
+    WTF_EXPORT_PRIVATE static PassRefPtr<StringImpl> createFromLiteral(const LChar* characters, unsigned length);
+    template<unsigned charactersCount>
+    ALWAYS_INLINE static PassRefPtr<StringImpl> createFromLiteral(const char (&characters)[charactersCount])
+    {
+        COMPILE_ASSERT(charactersCount > 1, StringImplFromLiteralNotEmpty);
+        COMPILE_ASSERT((charactersCount - 1 <= ((unsigned(~0) - sizeof(StringImpl)) / sizeof(LChar))), StringImplFromLiteralCannotOverflow);
+
+        return createFromLiteral(reinterpret_cast<const LChar*>(characters), charactersCount - 1);
+    }
+
     WTF_EXPORT_PRIVATE static PassRefPtr<StringImpl> createUninitialized(unsigned length, LChar*& data);
     WTF_EXPORT_PRIVATE static PassRefPtr<StringImpl> createUninitialized(unsigned length, UChar*& data);
     template <typename T> static ALWAYS_INLINE PassRefPtr<StringImpl> tryCreateUninitialized(unsigned length, T*& output)

Modified: trunk/Source/WebCore/ChangeLog (123688 => 123689)


--- trunk/Source/WebCore/ChangeLog	2012-07-26 01:01:24 UTC (rev 123688)
+++ trunk/Source/WebCore/ChangeLog	2012-07-26 01:05:23 UTC (rev 123689)
@@ -1,3 +1,33 @@
+2012-07-25  Benjamin Poulain  <[email protected]>
+
+        Initialize QualifiedName's strings from the read only data segment
+        https://bugs.webkit.org/show_bug.cgi?id=92226
+
+        Reviewed by Anders Carlsson.
+
+        Modify the initialization of static QualifiedName to initialize the AtomicString
+        with the data from the read only memory.
+
+        Overall, HTMLNames::init() gets 10% faster.
+
+        * dom/QualifiedName.cpp:
+        (WebCore::QualifiedName::QualifiedName):
+        * dom/QualifiedName.h:
+        (QualifiedName):
+        Remove the useless constructor taking a char* and get rid of the init() function.
+        The AtomicString representing the name should be constructed by the caller of QualifiedName.
+
+        Because the init() code is relatively large and is only executed once, it is important to
+        keep the AtomicString construction separate. The function createQualifiedName() was added
+        to improve the cache use. The short version let us reduce the code one more instruction per
+        call.
+
+        * dom/make_names.pl:
+        (printQualifiedNameMaker):
+        (printShortQualifiedNameMaker):
+        (printNamesCppFile):
+        (printDefinitions):
+
 2012-07-25  Yoshifumi Inoue  <[email protected]>
 
         [Forms] Move HTMLInputElement::updateInnerTextValue to InputType class

Modified: trunk/Source/WebCore/dom/QualifiedName.cpp (123688 => 123689)


--- trunk/Source/WebCore/dom/QualifiedName.cpp	2012-07-26 01:01:24 UTC (rev 123688)
+++ trunk/Source/WebCore/dom/QualifiedName.cpp	2012-07-26 01:05:23 UTC (rev 123689)
@@ -78,7 +78,7 @@
 
 static QNameSet* gNameCache;
 
-void QualifiedName::init(const AtomicString& p, const AtomicString& l, const AtomicString& n)
+QualifiedName::QualifiedName(const AtomicString& p, const AtomicString& l, const AtomicString& n)
 {
     if (!gNameCache)
         gNameCache = new QNameSet;
@@ -89,16 +89,6 @@
         m_impl->ref();
 }
 
-QualifiedName::QualifiedName(const AtomicString& p, const AtomicString& l, const AtomicString& n)
-{
-    init(p, l, n);
-}
-
-QualifiedName::QualifiedName(const AtomicString& p, const char* l, const AtomicString& n)
-{
-    init(p, AtomicString(l), n);
-}
-
 QualifiedName::~QualifiedName()
 {
     deref();
@@ -151,4 +141,16 @@
     return m_impl->m_localNameUpper;
 }
 
+void createQualifiedName(void* targetAddress, const char* name, unsigned nameLength, const AtomicString& nameNamespace)
+{
+    AtomicString atomicName(name, nameLength, AtomicString::ConstructFromLiteral);
+    new (reinterpret_cast<void*>(targetAddress)) QualifiedName(nullAtom, atomicName, nameNamespace);
 }
+
+void createQualifiedName(void* targetAddress, const char* name, unsigned nameLength)
+{
+    AtomicString atomicName(name, nameLength, AtomicString::ConstructFromLiteral);
+    new (reinterpret_cast<void*>(targetAddress)) QualifiedName(nullAtom, atomicName, nullAtom);
+}
+
+}

Modified: trunk/Source/WebCore/dom/QualifiedName.h (123688 => 123689)


--- trunk/Source/WebCore/dom/QualifiedName.h	2012-07-26 01:01:24 UTC (rev 123688)
+++ trunk/Source/WebCore/dom/QualifiedName.h	2012-07-26 01:05:23 UTC (rev 123689)
@@ -69,7 +69,6 @@
     };
 
     QualifiedName(const AtomicString& prefix, const AtomicString& localName, const AtomicString& namespaceURI);
-    QualifiedName(const AtomicString& prefix, const char* localName, const AtomicString& namespaceURI);
     QualifiedName(WTF::HashTableDeletedValueType) : m_impl(hashTableDeletedValue()) { }
     bool isHashTableDeletedValue() const { return m_impl == hashTableDeletedValue(); }
     ~QualifiedName();
@@ -108,7 +107,6 @@
         info.addInstrumentedMember(m_impl);
     }
 private:
-    void init(const AtomicString& prefix, const AtomicString& localName, const AtomicString& namespaceURI);
     void ref() const { m_impl->ref(); }
     void deref();
 
@@ -147,6 +145,9 @@
     static const bool safeToCompareToEmptyOrDeleted = false;
 };
 
+void createQualifiedName(void* targetAddress, const char* name, unsigned nameLength);
+void createQualifiedName(void* targetAddress, const char* name, unsigned nameLength, const AtomicString& nameNamespace);
+
 }
 
 namespace WTF {

Modified: trunk/Source/WebCore/dom/make_names.pl (123688 => 123689)


--- trunk/Source/WebCore/dom/make_names.pl	2012-07-26 01:01:24 UTC (rev 123688)
+++ trunk/Source/WebCore/dom/make_names.pl	2012-07-26 01:05:23 UTC (rev 123689)
@@ -116,7 +116,7 @@
     printCppHead($F, "CSS", $familyNamesFileBase, "WTF");
 
     while ( my ($name, $identifier) = each %parameters ) {
-        print F "DEFINE_GLOBAL(AtomicString, $name, \"$identifier\")\n";
+        print F "DEFINE_GLOBAL(AtomicString, $name)\n";
     }
 
     printInit($F, 0);
@@ -624,12 +624,12 @@
     
     my $lowerNamespace = lc($parameters{namespacePrefix});
 
-    print F "DEFINE_GLOBAL(AtomicString, ${lowerNamespace}NamespaceURI, \"$parameters{namespaceURI}\")\n\n";
+    print F "DEFINE_GLOBAL(AtomicString, ${lowerNamespace}NamespaceURI)\n\n";
 
     if (keys %allTags) {
         print F "// Tags\n";
         for my $name (sort keys %allTags) {
-            print F "DEFINE_GLOBAL(QualifiedName, ", $name, "Tag, nullAtom, \"$name\", ${lowerNamespace}NamespaceURI)\n";
+            print F "DEFINE_GLOBAL(QualifiedName, ", $name, "Tag)\n";
         }
         
         print F "\n\nWebCore::QualifiedName** get$parameters{namespace}Tags(size_t* size)\n";
@@ -646,7 +646,7 @@
     if (keys %allAttrs) {
         print F "\n// Attributes\n";
         for my $name (sort keys %allAttrs) {
-            print F "DEFINE_GLOBAL(QualifiedName, ", $name, "Attr, nullAtom, \"$name\", ${lowerNamespace}NamespaceURI)\n";
+            print F "DEFINE_GLOBAL(QualifiedName, ", $name, "Attr)\n";
         }
         print F "\n\nWebCore::QualifiedName** get$parameters{namespace}Attrs(size_t* size)\n";
         print F "{\n    static WebCore::QualifiedName* $parameters{namespace}Attr[] = {\n";
@@ -660,9 +660,9 @@
     }
 
     printInit($F, 0);
-    
-    print(F "    AtomicString ${lowerNamespace}NS(\"$parameters{namespaceURI}\");\n\n");
 
+    print(F "    AtomicString ${lowerNamespace}NS(\"$parameters{namespaceURI}\", AtomicString::ConstructFromLiteral);\n\n");
+
     print(F "    // Namespace\n");
     print(F "    new ((void*)&${lowerNamespace}NamespaceURI) AtomicString(${lowerNamespace}NS);\n\n");
     if (keys %allTags) {
@@ -771,7 +771,13 @@
             $realName = $name;
             $realName =~ s/_/-/g;
         }
-        print F "    new ((void*)&$name","${shortCamelType}) QualifiedName(nullAtom, \"$realName\", $namespaceURI);\n";
+
+        # To generate less code in init(), the common case of nullAtom for the namespace, we call createQualifiedName() without passing $namespaceURI.
+        if ($namespaceURI eq "nullAtom") {
+            print F "    createQualifiedName((void*)&$name","${shortCamelType}, \"$realName\", ", length $realName ,");\n";
+        } else {
+            print F "    createQualifiedName((void*)&$name","${shortCamelType}, \"$realName\", ", length $realName ,", $namespaceURI);\n";
+        }
     }
 }
 
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to