WSL prepare() should cache the parsed standard library
authorfpizlo@apple.com <fpizlo@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 19 Sep 2017 03:19:22 +0000 (03:19 +0000)
committerfpizlo@apple.com <fpizlo@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 19 Sep 2017 03:19:22 +0000 (03:19 +0000)
https://bugs.webkit.org/show_bug.cgi?id=177118

Reviewed by Myles Maxfield.

The execution time of Test.js is too damn high!

So I made it 2x faster by caching the parsed standard library.

* WebGPUShadingLanguageRI/All.js:
* WebGPUShadingLanguageRI/CloneProgram.js: Added.
(cloneProgram):
* WebGPUShadingLanguageRI/Prepare.js:
(let.prepare):
(prepare): Deleted.
* WebGPUShadingLanguageRI/StatementCloner.js: Added.
(StatementCloner.prototype.visitFuncDef):
(StatementCloner.prototype.visitNativeFunc):
(StatementCloner.prototype.visitNativeType):
(StatementCloner.prototype.visitTypeDef):
(StatementCloner.prototype.visitStructType):
(StatementCloner.prototype.visitConstexprTypeParameter):
(StatementCloner.prototype.visitProtocolDecl):
* WebGPUShadingLanguageRI/Test.html:
* WebGPUShadingLanguageRI/Test.js:
(doTest):

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

Tools/ChangeLog
Tools/WebGPUShadingLanguageRI/All.js
Tools/WebGPUShadingLanguageRI/CloneProgram.js [new file with mode: 0644]
Tools/WebGPUShadingLanguageRI/Prepare.js
Tools/WebGPUShadingLanguageRI/StatementCloner.js [new file with mode: 0644]
Tools/WebGPUShadingLanguageRI/Test.html
Tools/WebGPUShadingLanguageRI/Test.js

index 29c7f89..0af8baa 100644 (file)
@@ -1,3 +1,32 @@
+2017-09-18  Filip Pizlo  <fpizlo@apple.com>
+
+        WSL prepare() should cache the parsed standard library
+        https://bugs.webkit.org/show_bug.cgi?id=177118
+
+        Reviewed by Myles Maxfield.
+        
+        The execution time of Test.js is too damn high!
+        
+        So I made it 2x faster by caching the parsed standard library.
+
+        * WebGPUShadingLanguageRI/All.js:
+        * WebGPUShadingLanguageRI/CloneProgram.js: Added.
+        (cloneProgram):
+        * WebGPUShadingLanguageRI/Prepare.js:
+        (let.prepare):
+        (prepare): Deleted.
+        * WebGPUShadingLanguageRI/StatementCloner.js: Added.
+        (StatementCloner.prototype.visitFuncDef):
+        (StatementCloner.prototype.visitNativeFunc):
+        (StatementCloner.prototype.visitNativeType):
+        (StatementCloner.prototype.visitTypeDef):
+        (StatementCloner.prototype.visitStructType):
+        (StatementCloner.prototype.visitConstexprTypeParameter):
+        (StatementCloner.prototype.visitProtocolDecl):
+        * WebGPUShadingLanguageRI/Test.html:
+        * WebGPUShadingLanguageRI/Test.js:
+        (doTest):
+
 2017-09-18  Michael Catanzaro  <mcatanzaro@igalia.com>
 
         [CMake] Rename WebKit target to WebKitLegacy and rename WebKit2 target to WebKit
index e1a5efb..0bf9100 100644 (file)
@@ -54,6 +54,7 @@ load("CheckReturns.js");
 load("CheckUnreachableCode.js");
 load("CheckWrapped.js");
 load("Checker.js");
+load("CloneProgram.js");
 load("CommaExpression.js");
 load("ConstexprTypeParameter.js");
 load("Continue.js");
@@ -129,6 +130,7 @@ load("Return.js");
 load("ReturnChecker.js");
 load("ReturnException.js");
 load("StandardLibrary.js");
+load("StatementCloner.js");
 load("StructLayoutBuilder.js");
 load("StructType.js");
 load("Substitution.js");
diff --git a/Tools/WebGPUShadingLanguageRI/CloneProgram.js b/Tools/WebGPUShadingLanguageRI/CloneProgram.js
new file mode 100644 (file)
index 0000000..b9eddad
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2017 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. ``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
+ * 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. 
+ */
+"use strict";
+
+// This is only currently used to clone programs just after parsing, so it doesn't really need to be
+// able to handle all aspects of what Rewriter would need to do.
+
+function cloneProgram(program)
+{
+    let result = new Program();
+    let cloner = new StatementCloner();
+    for (let statement of program.topLevelStatements)
+        result.add(statement.visit(cloner));
+    return result;
+}
+
index e0b8ed7..ec48bee 100644 (file)
  */
 "use strict";
 
-function prepare(origin, lineNumberOffset, text)
-{
-    let program = new Program();
-    
-    parse(program, "/internal/stdlib", "native", 27, standardLibrary);
-    parse(program, origin, "user", lineNumberOffset, text);
-    
-    let nameResolver = createNameResolver(program);
-    resolveNamesInTypes(program, nameResolver);
-    resolveNamesInProtocols(program, nameResolver);
-    resolveTypeDefsInTypes(program);
-    resolveTypeDefsInProtocols(program);
-    // FIXME: Need to verify that structre are not cyclic.
-    // https://bugs.webkit.org/show_bug.cgi?id=177044
-    synthesizeStructAccessors(program);
-    resolveNamesInFunctions(program, nameResolver);
-    resolveTypeDefsInFunctions(program);
-    
-    flattenProtocolExtends(program);
-    check(program);
-    checkLiteralTypes(program);
-    resolveProperties(program);
-    findHighZombies(program);
-    checkLiteralTypes(program);
-    checkProgramWrapped(program);
-    checkReturns(program);
-    checkUnreachableCode(program);
-    checkLoops(program);
-    checkRecursion(program);
-    checkProgramWrapped(program);
-    findHighZombies(program);
-    inline(program);
-    
-    return program;
-}
+let prepare = (() => {
+    let standardProgram;
+    return (origin, lineNumberOffset, text) => {
+        if (!standardProgram) {
+            standardProgram = new Program();
+            parse(standardProgram, "/internal/stdlib", "native", 27, standardLibrary);
+        }
+        
+        let program = cloneProgram(standardProgram);
+        parse(program, origin, "user", lineNumberOffset, text);
+        
+        let nameResolver = createNameResolver(program);
+        resolveNamesInTypes(program, nameResolver);
+        resolveNamesInProtocols(program, nameResolver);
+        resolveTypeDefsInTypes(program);
+        resolveTypeDefsInProtocols(program);
+        // FIXME: Need to verify that structre are not cyclic.
+        // https://bugs.webkit.org/show_bug.cgi?id=177044
+        synthesizeStructAccessors(program);
+        resolveNamesInFunctions(program, nameResolver);
+        resolveTypeDefsInFunctions(program);
+        
+        flattenProtocolExtends(program);
+        check(program);
+        checkLiteralTypes(program);
+        resolveProperties(program);
+        findHighZombies(program);
+        checkLiteralTypes(program);
+        checkProgramWrapped(program);
+        checkReturns(program);
+        checkUnreachableCode(program);
+        checkLoops(program);
+        checkRecursion(program);
+        checkProgramWrapped(program);
+        findHighZombies(program);
+        inline(program);
+        
+        return program;
+    };
+})();
 
diff --git a/Tools/WebGPUShadingLanguageRI/StatementCloner.js b/Tools/WebGPUShadingLanguageRI/StatementCloner.js
new file mode 100644 (file)
index 0000000..e860789
--- /dev/null
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2017 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. ``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
+ * 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. 
+ */
+"use strict";
+
+class StatementCloner extends Rewriter {
+    visitFuncDef(node)
+    {
+        let result = new FuncDef(
+            node.origin, node.name,
+            node.returnType.visit(this),
+            node.typeParameters.map(typeParameter => typeParameter.visit(this)),
+            node.parameters.map(parameter => parameter.visit(this)),
+            node.body.visit(this),
+            node.isCast, node.shaderType);
+        result.isRestricted = node.isRestricted;
+        return result;
+    }
+    
+    visitNativeFunc(node)
+    {
+        let result = new NativeFunc(
+            node.origin, node.name,
+            node.returnType.visit(this),
+            node.typeParameters.map(typeParameter => typeParameter.visit(this)),
+            node.parameters.map(parameter => parameter.visit(this)),
+            node.isCast, node.shaderType);
+        result.isRestricted = node.isRestricted;
+        return result;
+    }
+    
+    visitNativeType(node)
+    {
+        return new NativeType(
+            node.origin, node.name, node.isPrimitive,
+            node.typeParameters.map(typeParameter => typeParameter.visit(this)));
+    }
+    
+    visitTypeDef(node)
+    {
+        return new TypeDef(
+            node.origin, node.name,
+            node.typeParameters.map(typeParameter => typeParameter.visit(this)),
+            node.type.visit(this));
+    }
+    
+    visitStructType(node)
+    {
+        let result = new StructType(
+            node.origin, node.name,
+            node.typeParameters.map(typeParameter => typeParameter.visit(this)));
+        for (let field of node.fields)
+            result.add(field.visit(this));
+        return result;
+    }
+    
+    visitConstexprTypeParameter(node)
+    {
+        return new ConstexprTypeParameter(node.origin, node.name, node.type.visit(this));
+    }
+    
+    visitProtocolDecl(node)
+    {
+        let result = new ProtocolDecl(node.origin, node.name);
+        for (let protocol of node.extends)
+            result.addExtends(protocol.visit(this));
+        for (let signature of node.signatures)
+            result.add(signature.visit(this));
+        return result;
+    }
+
+    visitTypeVariable(node)
+    {
+        return new TypeVariable(node.origin, node.name, Node.visit(node.protocol, this));
+    }
+    
+    visitProtocolRef(node)
+    {
+        return new ProtocolRef(node.origin, node.name);
+    }
+    
+    visitBoolLiteral(node)
+    {
+        return new BoolLiteral(node.origin, node.value);
+    }
+    
+    visitTypeOrVariableRef(node)
+    {
+        return new TypeOrVariableRef(node.origin, node.name);
+    }
+}
+
index 84bae5f..e632acd 100644 (file)
@@ -31,6 +31,7 @@
 <script src="CheckUnreachableCode.js"></script>
 <script src="CheckWrapped.js"></script>
 <script src="Checker.js"></script>
+<script src="CloneProgram.js"></script>
 <script src="CommaExpression.js"></script>
 <script src="ConstexprTypeParameter.js"></script>
 <script src="Continue.js"></script>
 <script src="ReturnChecker.js"></script>
 <script src="ReturnException.js"></script>
 <script src="StandardLibrary.js"></script>
+<script src="StatementCloner.js"></script>
 <script src="StructLayoutBuilder.js"></script>
 <script src="StructType.js"></script>
 <script src="Substitution.js"></script>
index df614ee..e21bd8c 100644 (file)
@@ -3914,9 +3914,9 @@ function* doTest(object)
     for (let s in object) {
         if (s.startsWith("TEST_") && s.match(filter)) {
             print(s + "...");
+            yield;
             object[s]();
             print("    OK!");
-            yield;
         }
     }