Improve the source code generated by make_names.pl
authorzandobersek@gmail.com <zandobersek@gmail.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 24 Jun 2015 12:19:19 +0000 (12:19 +0000)
committerzandobersek@gmail.com <zandobersek@gmail.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 24 Jun 2015 12:19:19 +0000 (12:19 +0000)
https://bugs.webkit.org/show_bug.cgi?id=146208

Reviewed by Darin Adler.

Source/WebCore:

Clean up and optimize the output that's generated by the make_names.pl script
when generating large sets of DOM names for attributes and tags.

The GenerateStrings() function in the StaticString.pm module is split into
GenerateStringData() and GenerateASCIILiteral() so that the two new functions
can be used independently, with the original function still being called when
generating font names.

Tags and attributes have the corresponding static QualifiedName globals defined
as before. After that, two static const std::array<> objects are defined for
both types -- the first is an ordered array of addresses of the QualifiedName
objects (corresponding to the C array that was defined in getHTMLTags(),
getSVGAttrs() etc.), and the second is an ordered array of StringImpl::StaticASCIILiteral
objects that replaces separately defined StringImpl::StaticASCIILiteral objects
and the additional tables that contained pairs of QualifiedName object addresses
and the corresponding StaticASCIILiteral object references in the init() function.
This is all generated by the printStaticData() function in make_names.pl.

The printQualifiedNameCreation() function generates a static_assert() that ensures
that the corresponding std::array<QualifiedName*> and std::array<StaticASCIILiteral>
objects have the same amount of items, and then sets up a loop that walks through
the two arrays and properly constructs the QualifiedName objects from the static
literal data.

On the GTK port, this shaves off ~54kB from the final stripped shared library
on a 64-bit build, and ~21kB on a 32-bit build.

* bindings/scripts/StaticString.pm:
(GenerateStringData):
(GenerateASCIILiteral):
(GenerateStrings):
* dom/make_names.pl:
(printCppHead):
(printNamesCppFile):
(printStaticData):
(printQualifiedNameCreation):
(printInit): Deleted.
(printDefinitions): Deleted.

Source/WTF:

* wtf/text/StringImpl.h:
(WTF::StringImpl::assertHashIsCorrect): Make this method const-qualified.

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

Source/WTF/ChangeLog
Source/WTF/wtf/text/StringImpl.h
Source/WebCore/ChangeLog
Source/WebCore/bindings/scripts/StaticString.pm
Source/WebCore/dom/make_names.pl

index 7cd9f7c..4d7aa40 100644 (file)
@@ -1,3 +1,13 @@
+2015-06-24  Zan Dobersek  <zdobersek@igalia.com>
+
+        Improve the source code generated by make_names.pl
+        https://bugs.webkit.org/show_bug.cgi?id=146208
+
+        Reviewed by Darin Adler.
+
+        * wtf/text/StringImpl.h:
+        (WTF::StringImpl::assertHashIsCorrect): Make this method const-qualified.
+
 2015-06-22  Darin Adler  <darin@apple.com>
 
         Make Array.join work directly on substrings without reifying them
index 0223c96..669393d 100644 (file)
@@ -901,7 +901,7 @@ public:
     };
 
 #ifndef NDEBUG
-    void assertHashIsCorrect()
+    void assertHashIsCorrect() const
     {
         ASSERT(hasHash());
         ASSERT(existingHash() == StringHasher::computeHashAndMaskTop8Bits(characters8(), length()));
index 5d705e9..92fabc1 100644 (file)
@@ -1,3 +1,49 @@
+2015-06-24  Zan Dobersek  <zdobersek@igalia.com>
+
+        Improve the source code generated by make_names.pl
+        https://bugs.webkit.org/show_bug.cgi?id=146208
+
+        Reviewed by Darin Adler.
+
+        Clean up and optimize the output that's generated by the make_names.pl script
+        when generating large sets of DOM names for attributes and tags.
+
+        The GenerateStrings() function in the StaticString.pm module is split into
+        GenerateStringData() and GenerateASCIILiteral() so that the two new functions
+        can be used independently, with the original function still being called when
+        generating font names.
+
+        Tags and attributes have the corresponding static QualifiedName globals defined
+        as before. After that, two static const std::array<> objects are defined for
+        both types -- the first is an ordered array of addresses of the QualifiedName
+        objects (corresponding to the C array that was defined in getHTMLTags(),
+        getSVGAttrs() etc.), and the second is an ordered array of StringImpl::StaticASCIILiteral
+        objects that replaces separately defined StringImpl::StaticASCIILiteral objects
+        and the additional tables that contained pairs of QualifiedName object addresses
+        and the corresponding StaticASCIILiteral object references in the init() function.
+        This is all generated by the printStaticData() function in make_names.pl.
+
+        The printQualifiedNameCreation() function generates a static_assert() that ensures
+        that the corresponding std::array<QualifiedName*> and std::array<StaticASCIILiteral>
+        objects have the same amount of items, and then sets up a loop that walks through
+        the two arrays and properly constructs the QualifiedName objects from the static
+        literal data.
+
+        On the GTK port, this shaves off ~54kB from the final stripped shared library
+        on a 64-bit build, and ~21kB on a 32-bit build.
+
+        * bindings/scripts/StaticString.pm:
+        (GenerateStringData):
+        (GenerateASCIILiteral):
+        (GenerateStrings):
+        * dom/make_names.pl:
+        (printCppHead):
+        (printNamesCppFile):
+        (printStaticData):
+        (printQualifiedNameCreation):
+        (printInit): Deleted.
+        (printDefinitions): Deleted.
+
 2015-06-24  Youenn Fablet  <youenn.fablet@crf.canon.fr>
 
         Refactor UserMediaRequest to share more codes between MediaDevices.getUserMedia and legacy webkitGetUserMedia
index 6da10eb..6162666 100644 (file)
@@ -26,7 +26,7 @@ package StaticString;
 use strict;
 use Hasher;
 
-sub GenerateStrings($)
+sub GenerateStringData($)
 {
     my $stringsRef = shift;
     my %strings = %$stringsRef;
@@ -37,20 +37,34 @@ sub GenerateStrings($)
         push(@result, "static const LChar ${name}String8[] = \"$strings{$name}\";\n");
     }
 
+    return join "", @result;
+}
+
+sub GenerateASCIILiteral($$)
+{
+    my $name = shift;
+    my $value = shift;
+
+    my $length = length($value);
+    my $hash = Hasher::GenerateHashValue($value);
+    return "{ StaticASCIILiteral::s_initialRefCount, $length, ${name}String8, StaticASCIILiteral::s_initialFlags | (${hash} << StaticASCIILiteral::s_hashShift) }";
+}
+
+sub GenerateStrings($)
+{
+    my $stringsRef = shift;
+    my %strings = %$stringsRef;
+
+    my @result = ();
+
+    push(@result, GenerateStringData($stringsRef));
     push(@result, "\n");
 
     for my $name (sort keys %strings) {
         my $value = $strings{$name};
-        my $length = length($value);
-        my $hash = Hasher::GenerateHashValue($value);
-        push(@result, <<END);
-static StringImpl::StaticASCIILiteral ${name}Data = {
-    StringImpl::StaticASCIILiteral::s_initialRefCount,
-    $length,
-    ${name}String8,
-    StringImpl::StaticASCIILiteral::s_initialFlags | (${hash} << StringImpl::StaticASCIILiteral::s_hashShift)
-};
-END
+        push(@result, "static StaticASCIILiteral ${name}Data = ");
+        push(@result, GenerateASCIILiteral($name, $strings{$name}));
+        push(@result, ";\n");
     }
 
     push(@result, "\n");
index 0d7a36f..d653dfb 100755 (executable)
@@ -573,11 +573,13 @@ sub printCppHead
     print F "#endif\n\n";
 
     print F "#include \"${namespace}Names.h\"\n\n";
-    print F "#include <wtf/StaticConstructors.h>\n";
+    print F "#include <array>\n";
+    print F "#include <wtf/StaticConstructors.h>\n\n";
 
     print F "namespace WebCore {\n\n";
     print F "namespace ${namespace}Names {\n\n";
-    print F "using namespace $usedNamespace;\n\n";
+    print F "using namespace $usedNamespace;\n";
+    print F "using StaticASCIILiteral = StringImpl::StaticASCIILiteral;\n\n";
 }
 
 sub printInit
@@ -598,8 +600,6 @@ print F "\nvoid init()
         return;
     initialized = true;
 
-    // Use placement new to initialize the globals.
-
     AtomicString::init();
 ";
 }
@@ -762,37 +762,15 @@ sub printNamesCppFile
 
     print F "WEBCORE_EXPORT DEFINE_GLOBAL(AtomicString, ${lowercaseNamespacePrefix}NamespaceURI)\n\n";
 
-    print F StaticString::GenerateStrings(\%allStrings);
+    print F StaticString::GenerateStringData(\%allStrings);
+    print F "\n";
 
     if (keys %allTags) {
-        print F "// Tags\n";
-        for my $name (sort keys %allTags) {
-            print F "WEBCORE_EXPORT DEFINE_GLOBAL($parameters{namespace}QualifiedName, ", $name, "Tag)\n";
-        }
-        
-        print F "\n\nconst WebCore::$parameters{namespace}QualifiedName* const* get$parameters{namespace}Tags()\n";
-        print F "{\n    static const WebCore::$parameters{namespace}QualifiedName* const $parameters{namespace}Tags[] = {\n";
-        for my $name (sort keys %allTags) {
-            print F "        reinterpret_cast<const WebCore::$parameters{namespace}QualifiedName*>(&${name}Tag),\n";
-        }
-        print F "    };\n";
-        print F "    return $parameters{namespace}Tags;\n";
-        print F "}\n";
+        printStaticData($F, \%allTags, "Tag", $parameters{namespace}, "$parameters{namespace}QualifiedName");
     }
 
     if (keys %allAttrs) {
-        print F "\n// Attributes\n";
-        for my $name (sort keys %allAttrs) {
-            print F "WEBCORE_EXPORT DEFINE_GLOBAL(QualifiedName, ", $name, "Attr)\n";
-        }
-        print F "\n\nconst WebCore::QualifiedName* const* get$parameters{namespace}Attrs()\n";
-        print F "{\n    static const WebCore::QualifiedName* const $parameters{namespace}Attrs[] = {\n";
-        for my $name (sort keys %allAttrs) {
-            print F "        reinterpret_cast<const WebCore::QualifiedName*>(&${name}Attr),\n";
-        }
-        print F "    };\n";
-        print F "    return $parameters{namespace}Attrs;\n";
-        print F "}\n";
+        printStaticData($F, \%allAttrs, "Attr", $parameters{namespace}, "QualifiedName");
     }
 
     printInit($F, 0);
@@ -801,16 +779,15 @@ sub printNamesCppFile
 
     print(F "    // Namespace\n");
     print(F "    new (NotNull, (void*)&${lowercaseNamespacePrefix}NamespaceURI) AtomicString(${lowercaseNamespacePrefix}NS);\n");
-    print(F "\n");
-    print F StaticString::GenerateStringAsserts(\%allStrings);
 
     if (keys %allTags) {
         my $tagsNamespace = $parameters{tagsNullNamespace} ? "nullAtom" : "${lowercaseNamespacePrefix}NS";
-        printDefinitions($F, \%allTags, "tags", $tagsNamespace);
+        printQualifiedNameCreation($F, "Tags", $parameters{namespace}, "$parameters{namespace}QualifiedName", $tagsNamespace);
     }
+
     if (keys %allAttrs) {
         my $attrsNamespace = $parameters{attrsNullNamespace} ? "nullAtom" : "${lowercaseNamespacePrefix}NS";
-        printDefinitions($F, \%allAttrs, "attributes", $attrsNamespace);
+        printQualifiedNameCreation($F, "Attrs", $parameters{namespace}, "QualifiedName", $attrsNamespace);
     }
 
     print F "}\n\n} }\n\n";
@@ -893,38 +870,56 @@ sub printConditionalElementIncludes
     }
 }
 
-sub printDefinitions
+sub printStaticData
 {
-    my ($F, $namesRef, $type, $namespaceURI) = @_;
+    my ($F, $namesRef, $type, $namespace, $qualifiedNameType) = @_;
 
-    my $shortCamelType = ucfirst(substr(substr($type, 0, -1), 0, 4));
-    my $capitalizedType = ucfirst($type);
-    
-print F <<END
+    my $nameCount = scalar(keys %$namesRef);
 
-    struct ${capitalizedType}TableEntry {
-        void* targetAddress;
-        StringImpl& name;
-    };
+    print F "// $type\n";
+    for my $name (sort keys %$namesRef) {
+        print F "WEBCORE_EXPORT DEFINE_GLOBAL($qualifiedNameType, ${name}${type})\n";
+    }
 
-    static const ${capitalizedType}TableEntry ${type}Table[] = {
-END
-;
+    print F "\n";
+    print F "static const std::array<const $qualifiedNameType*, $nameCount> ${namespace}${type}s = { {\n";
     for my $name (sort keys %$namesRef) {
-        print F "        { (void*)&$name$shortCamelType, *reinterpret_cast<StringImpl*>(&${name}Data) },\n";
+        print F "    reinterpret_cast<const $qualifiedNameType*>(&${name}${type}),\n";
     }
+    print F "} };\n\n";
 
-print F <<END
-    };
+    print F "static const std::array<StaticASCIILiteral, $nameCount> ${namespace}${type}sLiterals = { {\n";
+    for my $name (sort keys %$namesRef) {
+        print F "    ", StaticString::GenerateASCIILiteral($name, valueForName($name)), ",\n";
+    }
+    print F "} };\n\n";
+
+    print F "const $qualifiedNameType* const* get${namespace}${type}s()\n";
+    print F "{\n";
+    print F "    return ${namespace}${type}s.data();\n";
+    print F "}\n";
+}
+
+sub printQualifiedNameCreation
+{
+    my ($F, $type, $namespace, $qualifiedNameType, $namespaceURI) = @_;
+
+    print F "\n";
+    print F "    static_assert(${namespace}${type}.size() == ${namespace}${type}Literals.size(), \"Arrays match in size\");\n";
+    print F "    for (size_t i = 0; i < ${namespace}${type}.size(); ++i) {\n";
+    print F "#ifndef NDEBUG\n";
+    print F "        reinterpret_cast<const StringImpl&>(${namespace}${type}Literals[i]).assertHashIsCorrect();\n";
+    print F "#endif\n";
 
-    for (unsigned i = 0; i < WTF_ARRAY_LENGTH(${type}Table); ++i)
-END
-;
     if ($namespaceURI eq "nullAtom") {
-        print F "        createQualifiedName(${type}Table[i].targetAddress, &${type}Table[i].name);\n";
+        print F "        createQualifiedName(reinterpret_cast<void*>(const_cast<$qualifiedNameType*>(${namespace}${type}\[i\])),\n";
+        print F "            reinterpret_cast<StringImpl*>(const_cast<StaticASCIILiteral*>(&${namespace}${type}Literals\[i\])));\n";
     } else {
-        print F "        createQualifiedName(${type}Table[i].targetAddress, &${type}Table[i].name, $namespaceURI);\n";
+        print F "        createQualifiedName(reinterpret_cast<void*>(const_cast<$qualifiedNameType*>(${namespace}${type}\[i\])),\n";
+        print F "            reinterpret_cast<StringImpl*>(const_cast<StaticASCIILiteral*>(&${namespace}${type}Literals\[i\])), $namespaceURI);\n";
     }
+
+    print F "    }\n";
 }
 
 ## ElementFactory routines