8059811: Turn off optimistic typing by default and add both ant test-pessimistic and ant test-optimistic sub-test suites.
authorlagergren
Thu, 09 Oct 2014 10:19:24 +0200
changeset 26982 ff5dd57a40f2
parent 26981 1576872e7046
child 26983 b5cd0f03efc4
8059811: Turn off optimistic typing by default and add both ant test-pessimistic and ant test-optimistic sub-test suites. Reviewed-by: attila, shade, hannesw
nashorn/bin/fixwhitespace.sh
nashorn/make/build.xml
nashorn/make/project.properties
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/Compiler.java
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/Context.java
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/resources/Options.properties
nashorn/test/src/jdk/nashorn/internal/runtime/ClassFilterTest.java
nashorn/test/src/jdk/nashorn/internal/test/framework/ScriptRunnable.java
nashorn/test/src/jdk/nashorn/internal/test/framework/TestFinder.java
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/bin/fixwhitespace.sh	Thu Oct 09 10:19:24 2014 +0200
@@ -0,0 +1,37 @@
+#!/bin/bash
+#
+# Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+# 
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+# 
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+# 
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+# 
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
+
+fix() {
+    #convert tabs to spaces
+    find . -name $1 -exec sed -i "" 's/	/    /g' {} \;
+    #remove trailing whitespace
+    find . -name $1 -exec sed -i "" 's/[ 	]*$//' \{} \;
+}
+
+if [ ! -z $1 ]; then 
+    fix $1;
+else
+    fix "*.java"
+    fix "*.js"
+fi
--- a/nashorn/make/build.xml	Wed Oct 08 17:20:29 2014 +0200
+++ b/nashorn/make/build.xml	Thu Oct 09 10:19:24 2014 +0200
@@ -78,7 +78,7 @@
       <istrue value="${jfr}"/>
     </condition>
   </target>
-
+  
   <target name="init" depends="init-conditions, init-cc">
     <!-- extends jvm args -->
     <property name="run.test.jvmargs" value="${run.test.jvmargs.main} ${run.test.cc.jvmargs} ${jfr.options}"/>
@@ -420,6 +420,7 @@
         <propertyref prefix="test-sys-prop-no-security."/>
         <mapper from="test-sys-prop-no-security.*" to="*" type="glob"/>
       </propertyset>
+      <sysproperty key="optimistic.override" value="${optimistic}"/>
       <classpath>
           <pathelement path="${run.test.classpath}"/>
       </classpath>
@@ -431,7 +432,7 @@
     <delete dir="${build.dir}/nashorn_code_cache"/>
     <property name="debug.test.jvmargs" value=""/>
     <testng outputdir="${build.test.results.dir}" classfilesetref="test.classes"
-       verbose="${testng.verbose}" haltonfailure="true" useDefaultListeners="false" listeners="${testng.listeners}" workingDir="${basedir}">
+	    verbose="${testng.verbose}" haltonfailure="true" useDefaultListeners="false" listeners="${testng.listeners}" workingDir="${basedir}">
       <jvmarg line="${ext.class.path}"/>
       <jvmarg line="${run.test.jvmargs} -Xmx${run.test.xmx} ${run.test.jvmsecurityargs} -Dbuild.dir=${build.dir}"/>
       <jvmarg line="${debug.test.jvmargs}"/>
@@ -442,6 +443,7 @@
         <propertyref prefix="test-sys-prop."/>
         <mapper from="test-sys-prop.*" to="*" type="glob"/>
       </propertyset>
+      <sysproperty key="optimistic.override" value="${optimistic}"/>
       <sysproperty key="test.js.excludes.file" value="${exclude.list}"/>
       <classpath>
           <pathelement path="${run.test.classpath}"/>
@@ -449,7 +451,27 @@
     </testng>
   </target>
 
-  <target name="test" depends="jar, -test-classes-all,-test-classes-single, check-testng, check-external-tests, compile-test, generate-policy-file, -test-security, -test-nosecurity" if="testng.available"/>
+  <target name="test" depends="test-pessimistic, test-optimistic"/>
+
+  <target name="test-optimistic" depends="jar, -test-classes-all,-test-classes-single, check-testng, check-external-tests, compile-test, generate-policy-file" if="testng.available">
+    <echo message="Running test suite in OPTIMISTIC mode..."/>
+    <antcall target="-test-nosecurity" inheritRefs="true">
+      <param name="optimistic" value="true"/>
+    </antcall>    
+    <antcall target="-test-security" inheritRefs="true">
+      <param name="optimistic" value="true"/>
+    </antcall>
+  </target>
+
+  <target name="test-pessimistic" depends="jar, -test-classes-all,-test-classes-single, check-testng, check-external-tests, compile-test, generate-policy-file" if="testng.available">
+    <echo message="Running test suite in PESSIMISTIC mode..."/>
+    <antcall target="-test-nosecurity" inheritRefs="true">
+      <param name="optimistic" value="false"/>
+    </antcall>    
+    <antcall target="-test-security" inheritRefs="true">
+      <param name="optimistic" value="false"/>
+    </antcall>
+  </target>
 
   <target name="check-jemmy.jfx.testng" unless="jemmy.jfx.testng.available">
     <echo message="WARNING: Jemmy or JavaFX or TestNG not available, will not run tests. Please copy testng.jar, JemmyCore.jar, JemmyFX.jar, JemmyAWTInput.jar under test${file.separator}lib directory. And make sure you have jfxrt.jar in ${java.home}${file.separator}lib${file.separator}ext dir."/>
--- a/nashorn/make/project.properties	Wed Oct 08 17:20:29 2014 +0200
+++ b/nashorn/make/project.properties	Thu Oct 09 10:19:24 2014 +0200
@@ -286,7 +286,8 @@
 # turn on assertions for tests
 run.test.jvmargs.main=${run.test.jvmargs.common} -ea
 
-# extra jvmargs that might be useful for debugging
+# Extra jvmargs that might be useful for debugging
+# and performance improvements/monitoring
 #
 # -XX:+UnlockDiagnosticVMOptions 
 #
@@ -304,9 +305,25 @@
 #
 # print all compiled nmethods with oopmaps and lots of other info
 # -XX:+PrintNMethods
+#
+# activate the generic "UseNewCode" flag to test whatever functionality
+# lies behind it. This is the preferred way to test a, yet flagless,
+# feature in HotSpot - for example, the uncommon trap placement fix
+# was hidden behind this flag before it became the default
+#
+# -XX:+UnlockDiagnosticVMOptions -XX:+UseNewCode 
+#
+# Crank up the type profile level to 222, which has some warmup
+# penalties, but produces much better code for JavaScript, where better
+# and more intrusive type profiling is required to get rid of
+# a large amount of unnecessary guard code, that could not otherwise
+# be eliminated
+#
+# -XX:TypeProfileLevel=222
+#
 
 # Use best known performance options for octane
-run.test.jvmargs.octane.main=${run.test.jvmargs.common} -XX:+UnlockDiagnosticVMOptions -XX:+UseNewCode -XX:TypeProfileLevel=222
+run.test.jvmargs.octane.main=${run.test.jvmargs.common} -XX:TypeProfileLevel=222
 
 # Security manager args - make sure that we run with the nashorn.policy that the build creates
 run.test.jvmsecurityargs=-Xverify:all -Djava.security.manager -Djava.security.policy=${build.dir}/nashorn.policy
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/Compiler.java	Wed Oct 08 17:20:29 2014 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/Compiler.java	Thu Oct 09 10:19:24 2014 +0200
@@ -458,11 +458,13 @@
 
     @Override
     public DebugLogger initLogger(final Context ctxt) {
-        final boolean optimisticTypes = ctxt.getEnv()._optimistic_types;
+        final boolean optimisticTypes = env._optimistic_types;
+        final boolean lazyCompilation = env._lazy_compilation;
+
         return ctxt.getLogger(this.getClass(), new Consumer<DebugLogger>() {
             @Override
             public void accept(final DebugLogger newLogger) {
-                if (!Compiler.this.getScriptEnvironment()._lazy_compilation) {
+                if (!lazyCompilation) {
                     newLogger.warning("WARNING: Running with lazy compilation switched off. This is not a default setting.");
                 }
                 newLogger.warning("Optimistic types are ", optimisticTypes ? "ENABLED." : "DISABLED.");
@@ -544,7 +546,7 @@
      */
     public FunctionNode compile(final FunctionNode functionNode, final CompilationPhases phases) throws CompilationException {
         if (log.isEnabled()) {
-            log.info("Starting compile job for ", DebugLogger.quote(functionNode.getName()), " phases=", quote(phases.getDesc()));
+            log.info(">> Starting compile job for ", DebugLogger.quote(functionNode.getName()), " phases=", quote(phases.getDesc()));
             log.indent();
         }
 
@@ -591,7 +593,7 @@
         log.unindent();
 
         if (info) {
-            final StringBuilder sb = new StringBuilder("Finished compile job for ");
+            final StringBuilder sb = new StringBuilder("<< Finished compile job for ");
             sb.append(newFunctionNode.getSource()).
                 append(':').
                 append(quote(newFunctionNode.getName()));
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/Context.java	Wed Oct 08 17:20:29 2014 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/Context.java	Thu Oct 09 10:19:24 2014 +0200
@@ -33,7 +33,6 @@
 import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
 import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
 import static jdk.nashorn.internal.runtime.Source.sourceFor;
-
 import java.io.File;
 import java.io.IOException;
 import java.io.PrintWriter;
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/resources/Options.properties	Wed Oct 08 17:20:29 2014 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/resources/Options.properties	Thu Oct 09 10:19:24 2014 +0200
@@ -204,9 +204,8 @@
 nashorn.option.optimistic.types = {                                                                      \
     name="--optimistic-types",                                                                           \
     short_name="-ot",                                                                                    \
-    is_undocumented=true,                                                                                \
-    desc="Use optimistic type assumptions with deoptimizing recompilation.", \
-    default=true                                   \
+    desc="Use optimistic type assumptions with deoptimizing recompilation. This makes the compiler try, for any program symbol whose type cannot be proven at compile time, to type it as narrow and primitive as possible. If the runtime encounters an error because symbol type is too narrow, a wider method will be generated until steady stage is reached. While this produces as optimal Java Bytecode as possible, erroneous type guesses will lead to longer warmup. Optimistic typing is currently enabled by default, but can be disabled for faster startup performance.",                     \
+    default=true                                                                                         \
 }
 
 nashorn.option.loader.per.compile = {              \
--- a/nashorn/test/src/jdk/nashorn/internal/runtime/ClassFilterTest.java	Wed Oct 08 17:20:29 2014 +0200
+++ b/nashorn/test/src/jdk/nashorn/internal/runtime/ClassFilterTest.java	Thu Oct 09 10:19:24 2014 +0200
@@ -25,10 +25,10 @@
 
 package jdk.nashorn.internal.runtime;
 
-
 import jdk.nashorn.api.scripting.ClassFilter;
 import jdk.nashorn.api.scripting.NashornScriptEngineFactory;
 import jdk.nashorn.api.scripting.URLReader;
+import jdk.nashorn.internal.test.framework.TestFinder;
 import org.testng.annotations.Test;
 
 import javax.script.ScriptEngine;
@@ -126,9 +126,9 @@
     private void persistentCacheTestImpl() {
         NashornScriptEngineFactory factory = new NashornScriptEngineFactory();
         ScriptEngine engine = factory.getScriptEngine(
-                new String[]{"--persistent-code-cache"},
-                getClass().getClassLoader(),
-                getClassFilter()
+              TestFinder.addExplicitOptimisticTypes(new String[]{"--persistent-code-cache", "--optimistic-types=true"}),
+                  getClass().getClassLoader(),
+                  getClassFilter()
         );
         String testScript = "var a = Java.type('java.lang.String');" + generateCodeForPersistentStore();
         try {
@@ -137,7 +137,7 @@
             fail(exc.getMessage());
         }
         ScriptEngine engineSafe = factory.getScriptEngine(
-                new String[]{"--persistent-code-cache"},
+                TestFinder.addExplicitOptimisticTypes(new String[]{"--persistent-code-cache", "--optimistic-types=true"}),
                 getClass().getClassLoader(),
                 new ClassFilter() {
                     @Override
@@ -151,7 +151,7 @@
             fail("ClassNotFoundException should have been thrown");
         } catch (final Exception exc) {
             if (!(exc.getCause() instanceof ClassNotFoundException)) {
-                fail("ClassNotFoundException expected");
+                fail("ClassNotFoundException expected, got " + exc.getClass());
             }
         }
     }
--- a/nashorn/test/src/jdk/nashorn/internal/test/framework/ScriptRunnable.java	Wed Oct 08 17:20:29 2014 +0200
+++ b/nashorn/test/src/jdk/nashorn/internal/test/framework/ScriptRunnable.java	Thu Oct 09 10:19:24 2014 +0200
@@ -179,7 +179,7 @@
         for (final String str : forkJVMOptions) {
             if(!str.isEmpty()) {
                 cmd.add(str);
-            }
+        }
         }
         cmd.add(Shell.class.getName());
         // now add the rest of the "in process" runtime arguments
--- a/nashorn/test/src/jdk/nashorn/internal/test/framework/TestFinder.java	Wed Oct 08 17:20:29 2014 +0200
+++ b/nashorn/test/src/jdk/nashorn/internal/test/framework/TestFinder.java	Thu Oct 09 10:19:24 2014 +0200
@@ -56,6 +56,7 @@
 import java.nio.file.SimpleFileVisitor;
 import java.nio.file.attribute.BasicFileAttributes;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collections;
 import java.util.EnumSet;
 import java.util.HashMap;
@@ -75,7 +76,7 @@
  * Utility class to find/parse script test files and to create 'test' instances.
  * Actual 'test' object type is decided by clients of this class.
  */
-final class TestFinder {
+public final class TestFinder {
     private TestFinder() {}
 
     interface TestFactory<T> {
@@ -215,6 +216,8 @@
         final List<String> scriptArguments = new ArrayList<>();
         boolean inComment = false;
 
+        boolean explicitOptimistic = false;
+
         try (Scanner scanner = new Scanner(testFile)) {
             while (scanner.hasNext()) {
                 // TODO: Scan for /ref=file qualifiers, etc, to determine run
@@ -287,7 +290,11 @@
                     scriptArguments.add(scanner.next());
                     break;
                 case "@option":
-                    engineOptions.add(scanner.next());
+                    final String next = scanner.next();
+                    engineOptions.add(next);
+                    if (next.startsWith("--optimistic-types")) {
+                        explicitOptimistic = true;
+                    }
                     break;
                 case "@fork":
                     fork = true;
@@ -336,12 +343,61 @@
                 testOptions.put(OPTIONS_FORK, "true");
             }
 
+            //if there are explicit optimistic type settings, use those - do not override
+            //the test might only work with optimistic types on or off.
+            if (!explicitOptimistic) {
+                addExplicitOptimisticTypes(engineOptions);
+            }
+
             tests.add(factory.createTest(framework, testFile.toFile(), engineOptions, testOptions, scriptArguments));
         } else if (!isNotTest) {
             orphans.add(name);
         }
     }
 
+    //the reverse of the default setting for optimistic types, if enabled, false, otherwise true
+    //thus, true for 8u40, false for 9
+    private static final boolean OPTIMISTIC_OVERRIDE = false;
+
+    /**
+     * Check if there is an optimistic override, that disables the default
+     * false optimistic types and sets them to true, for testing purposes
+     *
+     * @return true if optimistic type override has been set by test suite
+     */
+    public static boolean hasOptimisticOverride() {
+        return Boolean.valueOf(OPTIMISTIC_OVERRIDE).toString().equals(System.getProperty("optimistic.override"));
+    }
+
+    /**
+     * Add an optimistic-types=true option to an argument list if this
+     * is set to override the default false. Add an optimistic-types=true
+     * options to an argument list if this is set to override the default
+     * true
+     *
+     * @args new argument list array
+     */
+    public static String[] addExplicitOptimisticTypes(String[] args) {
+        if (hasOptimisticOverride()) {
+            final List<String> newList = new ArrayList<>(Arrays.asList(args));
+            newList.add("--optimistic-types=" + Boolean.valueOf(OPTIMISTIC_OVERRIDE));
+            return newList.toArray(new String[0]);
+        }
+        return args;
+    }
+
+    /**
+     * Add an optimistic-types=true option to an argument list if this
+     * is set to override the default false
+     *
+     * @args argument list
+     */
+    public static void addExplicitOptimisticTypes(List<String> args) {
+        if (hasOptimisticOverride()) {
+            args.add("--optimistic-types=" + Boolean.valueOf(OPTIMISTIC_OVERRIDE));
+        }
+    }
+
     private static boolean strictModeEnabled() {
         return Boolean.getBoolean(TEST_JS_ENABLE_STRICT_MODE);
     }