Title: [225565] trunk/Source/WebCore
Revision
225565
Author
[email protected]
Date
2017-12-05 19:54:51 -0800 (Tue, 05 Dec 2017)

Log Message

Fast binding generation by batching several files at once
https://bugs.webkit.org/show_bug.cgi?id=179958

Patch by Basuke Suzuki <[email protected]> on 2017-12-05
Reviewed by Alex Christensen.

Passing several files to the sub process at once and reducing the total cost of
process generation. Especially Windows port has great speed improvement because
its implementation of fork/exec is terrible.

* bindings/scripts/generate-bindings-all.pl:
(spawnGenerateBindingsIfNeeded):
* bindings/scripts/generate-bindings.pl:
(generateBindings):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (225564 => 225565)


--- trunk/Source/WebCore/ChangeLog	2017-12-06 02:41:20 UTC (rev 225564)
+++ trunk/Source/WebCore/ChangeLog	2017-12-06 03:54:51 UTC (rev 225565)
@@ -1,3 +1,19 @@
+2017-12-05  Basuke Suzuki  <[email protected]>
+
+        Fast binding generation by batching several files at once
+        https://bugs.webkit.org/show_bug.cgi?id=179958
+
+        Reviewed by Alex Christensen.
+
+        Passing several files to the sub process at once and reducing the total cost of
+        process generation. Especially Windows port has great speed improvement because
+        its implementation of fork/exec is terrible.
+
+        * bindings/scripts/generate-bindings-all.pl:
+        (spawnGenerateBindingsIfNeeded):
+        * bindings/scripts/generate-bindings.pl:
+        (generateBindings):
+
 2017-12-05  David Quesada  <[email protected]>
 
         [Web App Manifest] Support fetching the app manifest 

Modified: trunk/Source/WebCore/bindings/scripts/generate-bindings-all.pl (225564 => 225565)


--- trunk/Source/WebCore/bindings/scripts/generate-bindings-all.pl	2017-12-06 02:41:20 UTC (rev 225564)
+++ trunk/Source/WebCore/bindings/scripts/generate-bindings-all.pl	2017-12-06 03:54:51 UTC (rev 225565)
@@ -163,11 +163,15 @@
 {
     return if $abort;
     return unless @idlFilesToUpdate;
-    my $file = shift @idlFilesToUpdate;
-    $currentCount++;
-    my $basename = basename($file);
-    printProgress("[$currentCount/$totalCount] $basename");
-    my $pid = spawnCommand($perl, @args, $file);
+    my $batchCount = 30;
+    # my $batchCount = int(($totalCount - $currentCount) / $numOfJobs) || 1;
+    my @files = splice(@idlFilesToUpdate, 0, $batchCount);
+    for (@files) {
+        $currentCount++;
+        my $basename = basename($_);
+        printProgress("[$currentCount/$totalCount] $basename");
+    }
+    my $pid = spawnCommand($perl, @args, @files);
     $abort = 1 unless defined $pid;
 }
 

Modified: trunk/Source/WebCore/bindings/scripts/generate-bindings.pl (225564 => 225565)


--- trunk/Source/WebCore/bindings/scripts/generate-bindings.pl	2017-12-06 02:41:20 UTC (rev 225564)
+++ trunk/Source/WebCore/bindings/scripts/generate-bindings.pl	2017-12-06 03:54:51 UTC (rev 225565)
@@ -71,9 +71,7 @@
            'additionalIdlFiles=s' => \$additionalIdlFiles,
            'idlAttributesFile=s' => \$idlAttributesFile);
 
-my $targetIdlFile = $ARGV[0];
-
-die('Must specify input file.') unless defined($targetIdlFile);
+die('Must specify input file.') unless @ARGV;
 die('Must specify generator') unless defined($generator);
 die('Must specify output directory.') unless defined($outputDirectory);
 die('Must specify IDL attributes file.') unless defined($idlAttributesFile);
@@ -81,141 +79,149 @@
 if (!$outputHeadersDirectory) {
     $outputHeadersDirectory = $outputDirectory;
 }
-$targetIdlFile = Cwd::realpath($targetIdlFile);
-if ($verbose) {
-    print "$generator: $targetIdlFile\n";
-}
-my $targetInterfaceName = fileparse($targetIdlFile, ".idl");
 
-my $idlFound = 0;
-my @supplementedIdlFiles;
-if ($supplementalDependencyFile) {
-    # The format of a supplemental dependency file:
-    #
-    # DOMWindow.idl P.idl Q.idl R.idl
-    # Document.idl S.idl
-    # Event.idl
-    # ...
-    #
-    # The above indicates that DOMWindow.idl is supplemented by P.idl, Q.idl and R.idl,
-    # Document.idl is supplemented by S.idl, and Event.idl is supplemented by no IDLs.
-    # The IDL that supplements another IDL (e.g. P.idl) never appears in the dependency file.
-    open FH, "< $supplementalDependencyFile" or die "Cannot open $supplementalDependencyFile\n";
-    while (my $line = <FH>) {
-        my ($idlFile, @followingIdlFiles) = split(/\s+/, $line);
-        if ($idlFile and fileparse($idlFile) eq fileparse($targetIdlFile)) {
-            $idlFound = 1;
-            @supplementedIdlFiles = sort @followingIdlFiles;
-        }
-    }
-    close FH;
+generateBindings($_) for (@ARGV);
 
-    # $additionalIdlFiles is list of IDL files which should not be included in
-    # DerivedSources*.cpp (i.e. they are not described in the supplemental
-    # dependency file) but should generate .h and .cpp files.
-    if (!$idlFound and $additionalIdlFiles) {
-        my @idlFiles = shellwords($additionalIdlFiles);
-        $idlFound = grep { $_ and fileparse($_) eq fileparse($targetIdlFile) } @idlFiles;
+sub generateBindings
+{
+    my ($targetIdlFile) = @_;
+
+    $targetIdlFile = Cwd::realpath($targetIdlFile);
+    if ($verbose) {
+        print "$generator: $targetIdlFile\n";
     }
+    my $targetInterfaceName = fileparse($targetIdlFile, ".idl");
 
-    if (!$idlFound) {
-        my $codeGen = CodeGenerator->new(\@idlDirectories, $generator, $outputDirectory, $outputHeadersDirectory, $preprocessor, $writeDependencies, $verbose);
+    my $idlFound = 0;
+    my @supplementedIdlFiles;
+    if ($supplementalDependencyFile) {
+        # The format of a supplemental dependency file:
+        #
+        # DOMWindow.idl P.idl Q.idl R.idl
+        # Document.idl S.idl
+        # Event.idl
+        # ...
+        #
+        # The above indicates that DOMWindow.idl is supplemented by P.idl, Q.idl and R.idl,
+        # Document.idl is supplemented by S.idl, and Event.idl is supplemented by no IDLs.
+        # The IDL that supplements another IDL (e.g. P.idl) never appears in the dependency file.
+        open FH, "< $supplementalDependencyFile" or die "Cannot open $supplementalDependencyFile\n";
+        while (my $line = <FH>) {
+            my ($idlFile, @followingIdlFiles) = split(/\s+/, $line);
+            if ($idlFile and fileparse($idlFile) eq fileparse($targetIdlFile)) {
+                $idlFound = 1;
+                @supplementedIdlFiles = sort @followingIdlFiles;
+            }
+        }
+        close FH;
 
-        # We generate empty .h and .cpp files just to tell build scripts that .h and .cpp files are created.
-        generateEmptyHeaderAndCpp($codeGen->FileNamePrefix(), $targetInterfaceName, $outputHeadersDirectory, $outputDirectory);
-        exit 0;
+        # $additionalIdlFiles is list of IDL files which should not be included in
+        # DerivedSources*.cpp (i.e. they are not described in the supplemental
+        # dependency file) but should generate .h and .cpp files.
+        if (!$idlFound and $additionalIdlFiles) {
+            my @idlFiles = shellwords($additionalIdlFiles);
+            $idlFound = grep { $_ and fileparse($_) eq fileparse($targetIdlFile) } @idlFiles;
+        }
+
+        if (!$idlFound) {
+            my $codeGen = CodeGenerator->new(\@idlDirectories, $generator, $outputDirectory, $outputHeadersDirectory, $preprocessor, $writeDependencies, $verbose);
+
+            # We generate empty .h and .cpp files just to tell build scripts that .h and .cpp files are created.
+            generateEmptyHeaderAndCpp($codeGen->FileNamePrefix(), $targetInterfaceName, $outputHeadersDirectory, $outputDirectory);
+            return;
+        }
     }
-}
 
-my $input;
-{
-    local $INPUT_RECORD_SEPARATOR;
-    open(JSON, "<", $idlAttributesFile) or die "Couldn't open $idlAttributesFile: $!";
-    $input = <JSON>;
-    close(JSON);
-}
+    my $input;
+    {
+        local $INPUT_RECORD_SEPARATOR;
+        open(JSON, "<", $idlAttributesFile) or die "Couldn't open $idlAttributesFile: $!";
+        $input = <JSON>;
+        close(JSON);
+    }
 
-my $jsonDecoder = JSON::PP->new->utf8;
-my $jsonHashRef = $jsonDecoder->decode($input);
-my $idlAttributes = $jsonHashRef->{attributes};
+    my $jsonDecoder = JSON::PP->new->utf8;
+    my $jsonHashRef = $jsonDecoder->decode($input);
+    my $idlAttributes = $jsonHashRef->{attributes};
 
-# Parse the target IDL file.
-my $targetParser = IDLParser->new(!$verbose);
-my $targetDocument = $targetParser->Parse($targetIdlFile, $defines, $preprocessor, $idlAttributes);
+    # Parse the target IDL file.
+    my $targetParser = IDLParser->new(!$verbose);
+    my $targetDocument = $targetParser->Parse($targetIdlFile, $defines, $preprocessor, $idlAttributes);
 
-foreach my $idlFile (@supplementedIdlFiles) {
-    next if $idlFile eq $targetIdlFile;
+    foreach my $idlFile (@supplementedIdlFiles) {
+        next if $idlFile eq $targetIdlFile;
 
-    my $interfaceName = fileparse($idlFile, ".idl");
-    my $parser = IDLParser->new(!$verbose);
-    my $document = $parser->Parse($idlFile, $defines, $preprocessor, $idlAttributes);
+        my $interfaceName = fileparse($idlFile, ".idl");
+        my $parser = IDLParser->new(!$verbose);
+        my $document = $parser->Parse($idlFile, $defines, $preprocessor, $idlAttributes);
 
-    foreach my $interface (@{$document->interfaces}) {
-        if (!$interface->isPartial || $interface->type->name eq $targetInterfaceName) {
-            my $targetDataNode;
-            my @targetGlobalContexts;
-            foreach my $interface (@{$targetDocument->interfaces}) {
-                if ($interface->type->name eq $targetInterfaceName) {
-                    $targetDataNode = $interface;
-                    my $exposedAttribute = $targetDataNode->extendedAttributes->{"Exposed"} || "Window";
-                    $exposedAttribute = substr($exposedAttribute, 1, -1) if substr($exposedAttribute, 0, 1) eq "(";
-                    @targetGlobalContexts = split(",", $exposedAttribute);
-                    last;
+        foreach my $interface (@{$document->interfaces}) {
+            if (!$interface->isPartial || $interface->type->name eq $targetInterfaceName) {
+                my $targetDataNode;
+                my @targetGlobalContexts;
+                foreach my $interface (@{$targetDocument->interfaces}) {
+                    if ($interface->type->name eq $targetInterfaceName) {
+                        $targetDataNode = $interface;
+                        my $exposedAttribute = $targetDataNode->extendedAttributes->{"Exposed"} || "Window";
+                        $exposedAttribute = substr($exposedAttribute, 1, -1) if substr($exposedAttribute, 0, 1) eq "(";
+                        @targetGlobalContexts = split(",", $exposedAttribute);
+                        last;
+                    }
                 }
-            }
-            die "Not found an interface ${targetInterfaceName} in ${targetInterfaceName}.idl." unless defined $targetDataNode;
+                die "Not found an interface ${targetInterfaceName} in ${targetInterfaceName}.idl." unless defined $targetDataNode;
 
-            # Support for attributes of partial interfaces.
-            foreach my $attribute (@{$interface->attributes}) {
-                next unless shouldPropertyBeExposed($attribute, \@targetGlobalContexts);
+                # Support for attributes of partial interfaces.
+                foreach my $attribute (@{$interface->attributes}) {
+                    next unless shouldPropertyBeExposed($attribute, \@targetGlobalContexts);
 
-                # Record that this attribute is implemented by $interfaceName.
-                $attribute->extendedAttributes->{"ImplementedBy"} = $interfaceName if $interface->isPartial && !$attribute->extendedAttributes->{Reflect};
+                    # Record that this attribute is implemented by $interfaceName.
+                    $attribute->extendedAttributes->{"ImplementedBy"} = $interfaceName if $interface->isPartial && !$attribute->extendedAttributes->{Reflect};
 
-                # Add interface-wide extended attributes to each attribute.
-                foreach my $extendedAttributeName (keys %{$interface->extendedAttributes}) {
-                    $attribute->extendedAttributes->{$extendedAttributeName} = $interface->extendedAttributes->{$extendedAttributeName};
+                    # Add interface-wide extended attributes to each attribute.
+                    foreach my $extendedAttributeName (keys %{$interface->extendedAttributes}) {
+                        $attribute->extendedAttributes->{$extendedAttributeName} = $interface->extendedAttributes->{$extendedAttributeName};
+                    }
+                    push(@{$targetDataNode->attributes}, $attribute);
                 }
-                push(@{$targetDataNode->attributes}, $attribute);
-            }
 
-            # Support for methods of partial interfaces.
-            foreach my $operation (@{$interface->operations}) {
-                next unless shouldPropertyBeExposed($operation, \@targetGlobalContexts);
+                # Support for methods of partial interfaces.
+                foreach my $operation (@{$interface->operations}) {
+                    next unless shouldPropertyBeExposed($operation, \@targetGlobalContexts);
 
-                # Record that this method is implemented by $interfaceName.
-                $operation->extendedAttributes->{"ImplementedBy"} = $interfaceName if $interface->isPartial;
+                    # Record that this method is implemented by $interfaceName.
+                    $operation->extendedAttributes->{"ImplementedBy"} = $interfaceName if $interface->isPartial;
 
-                # Add interface-wide extended attributes to each method.
-                foreach my $extendedAttributeName (keys %{$interface->extendedAttributes}) {
-                    $operation->extendedAttributes->{$extendedAttributeName} = $interface->extendedAttributes->{$extendedAttributeName};
+                    # Add interface-wide extended attributes to each method.
+                    foreach my $extendedAttributeName (keys %{$interface->extendedAttributes}) {
+                        $operation->extendedAttributes->{$extendedAttributeName} = $interface->extendedAttributes->{$extendedAttributeName};
+                    }
+                    push(@{$targetDataNode->operations}, $operation);
                 }
-                push(@{$targetDataNode->operations}, $operation);
-            }
 
-            # Support for constants of partial interfaces.
-            foreach my $constant (@{$interface->constants}) {
-                next unless shouldPropertyBeExposed($constant, \@targetGlobalContexts);
+                # Support for constants of partial interfaces.
+                foreach my $constant (@{$interface->constants}) {
+                    next unless shouldPropertyBeExposed($constant, \@targetGlobalContexts);
 
-                # Record that this constant is implemented by $interfaceName.
-                $constant->extendedAttributes->{"ImplementedBy"} = $interfaceName if $interface->isPartial;
+                    # Record that this constant is implemented by $interfaceName.
+                    $constant->extendedAttributes->{"ImplementedBy"} = $interfaceName if $interface->isPartial;
 
-                # Add interface-wide extended attributes to each constant.
-                foreach my $extendedAttributeName (keys %{$interface->extendedAttributes}) {
-                    $constant->extendedAttributes->{$extendedAttributeName} = $interface->extendedAttributes->{$extendedAttributeName};
+                    # Add interface-wide extended attributes to each constant.
+                    foreach my $extendedAttributeName (keys %{$interface->extendedAttributes}) {
+                        $constant->extendedAttributes->{$extendedAttributeName} = $interface->extendedAttributes->{$extendedAttributeName};
+                    }
+                    push(@{$targetDataNode->constants}, $constant);
                 }
-                push(@{$targetDataNode->constants}, $constant);
+            } else {
+                die "$idlFile is not a supplemental dependency of $targetIdlFile. There maybe a bug in the supplemental dependency generator (preprocess-idls.pl).\n";
             }
-        } else {
-            die "$idlFile is not a supplemental dependency of $targetIdlFile. There maybe a bug in the supplemental dependency generator (preprocess-idls.pl).\n";
         }
     }
+
+    # Generate desired output for the target IDL file.
+    my $codeGen = CodeGenerator->new(\@idlDirectories, $generator, $outputDirectory, $outputHeadersDirectory, $preprocessor, $writeDependencies, $verbose, $targetIdlFile, $idlAttributes);
+    $codeGen->ProcessDocument($targetDocument, $defines);
 }
 
-# Generate desired output for the target IDL file.
-my $codeGen = CodeGenerator->new(\@idlDirectories, $generator, $outputDirectory, $outputHeadersDirectory, $preprocessor, $writeDependencies, $verbose, $targetIdlFile, $idlAttributes);
-$codeGen->ProcessDocument($targetDocument, $defines);
-
 # Attributes / Operations / Constants of supplemental interfaces can have an [Exposed=XX] attribute which restricts
 # on which global contexts they should be exposed.
 sub shouldPropertyBeExposed
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to