Merge
authorlana
Mon, 23 Dec 2013 14:46:33 -0800
changeset 22400 35eadc466f62
parent 22395 2ff0cf7f52fb (current diff)
parent 22399 ee37863f4589 (diff)
child 22401 4c088dea0e5e
child 22402 8db9ff9fdd86
Merge
--- a/nashorn/make/build-benchmark.xml	Thu Dec 19 17:24:39 2013 -0800
+++ b/nashorn/make/build-benchmark.xml	Mon Dec 23 14:46:33 2013 -0800
@@ -239,7 +239,7 @@
     </antcall>
   </target>
 
-  <target name="octane-regexp-octane-v8" depends="jar">
+  <target name="octane-regexp-v8" depends="jar">
     <antcall target="run-octane-v8">
       <param name="octane-tests" value="regexp"/>
     </antcall>
@@ -291,17 +291,56 @@
     </antcall>
   </target>
 
+  <!-- splay -->
+  <target name="octane-typescript" depends="jar">
+    <antcall target="run-octane">
+      <param name="octane-tests" value="typescript"/>
+    </antcall>
+  </target>
+
+  <target name="octane-typescript-v8" depends="jar">
+    <antcall target="run-octane-v8">
+      <param name="octane-typescript" value="typescript"/>
+    </antcall>
+  </target>
+
+  <target name="octane-typescript-rhino" depends="jar">
+    <antcall target="run-octane-rhino">
+      <param name="octane-tests" value="typescript"/>
+    </antcall>
+  </target>
+
+  <!-- zlib -->
+  <target name="octane-zlib" depends="jar">
+    <antcall target="run-octane">
+      <param name="octane-tests" value="zlib"/>
+    </antcall>
+  </target>
+
+  <target name="octane-zlib-v8" depends="jar">
+    <antcall target="run-octane-v8">
+      <param name="octane-typescript" value="zlib"/>
+    </antcall>
+  </target>
+
+  <target name="octane-zlib-rhino" depends="jar">
+    <antcall target="run-octane-rhino">
+      <param name="octane-tests" value="zlib"/>
+    </antcall>
+  </target>
+
   <!-- run octane benchmarks in a single process  -->
   <target name="octane-single-process" depends="octane-init">
     <antcall target="run-octane"/>
   </target>
 
-  <!-- mandreel excluded due to OOM -->
+  <!-- zlib excluded due to missing implementation of 'read' -->
   <target name="octane-separate-process" depends=
      "octane-box2d, octane-code-load, octane-crypto, 
       octane-deltablue, octane-earley-boyer, octane-gbemu,
-      octane-navier-stokes, octane-pdfjs, octane-raytrace, 
-      octane-regexp, octane-richards, octane-splay"/>
+      octane-mandreel, octane-navier-stokes, octane-pdfjs, 
+      octane-raytrace, octane-regexp, octane-richards, 
+      octane-splay, octane-typescript"/>
 
   <target name="--single-process" unless="${octane-test-sys-prop.separate.process}">
     <antcall target="octane-single-process"/>
--- a/nashorn/src/jdk/nashorn/internal/codegen/Attr.java	Thu Dec 19 17:24:39 2013 -0800
+++ b/nashorn/src/jdk/nashorn/internal/codegen/Attr.java	Mon Dec 23 14:46:33 2013 -0800
@@ -766,7 +766,7 @@
                 symbol.setType(Type.OBJECT);
             }
 
-            returnType = Type.widest(returnTypes.pop(), symbol.getSymbolType());
+            returnType = widestReturnType(returnTypes.pop(), symbol.getSymbolType());
         } else {
             returnType = Type.OBJECT; //undefined
         }
@@ -1433,10 +1433,30 @@
         ensureTypeNotUnknown(trueExpr);
         ensureTypeNotUnknown(falseExpr);
 
-        final Type type = Type.widest(trueExpr.getType(), falseExpr.getType());
+        final Type type = widestReturnType(trueExpr.getType(), falseExpr.getType());
         return end(ensureSymbol(type, ternaryNode));
     }
 
+    /**
+     * When doing widening for return types of a function or a ternary operator, it is not valid to widen a boolean to
+     * anything other than Object. Also, widening a numeric type to an object type must widen to Object proper and not
+     * any more specific subclass (e.g. widest of int/long/double and String is Object).
+     * @param t1 type 1
+     * @param t2 type 2
+     * @return wider of t1 and t2, except if one is boolean and the other is neither boolean nor unknown, or if one is
+     * numeric and the other is neither numeric nor unknown in which case {@code Type.OBJECT} is returned.
+     */
+    private static Type widestReturnType(final Type t1, final Type t2) {
+        if (t1.isUnknown()) {
+            return t2;
+        } else if (t2.isUnknown()) {
+            return t1;
+        } else if (t1.isBoolean() != t2.isBoolean() || t1.isNumeric() != t2.isNumeric()) {
+            return Type.OBJECT;
+        }
+        return Type.widest(t1, t2);
+    }
+
     private void initCompileConstant(final CompilerConstants cc, final Block block, final int flags) {
         final Class<?> type = cc.type();
         // Must not call this method for constants with no explicit types; use the one with (..., Type) signature instead.
--- a/nashorn/src/jdk/nashorn/internal/objects/Global.java	Thu Dec 19 17:24:39 2013 -0800
+++ b/nashorn/src/jdk/nashorn/internal/objects/Global.java	Mon Dec 23 14:46:33 2013 -0800
@@ -44,6 +44,7 @@
 import java.util.concurrent.ConcurrentHashMap;
 import jdk.internal.dynalink.linker.GuardedInvocation;
 import jdk.internal.dynalink.linker.LinkRequest;
+import jdk.nashorn.internal.lookup.Lookup;
 import jdk.nashorn.internal.objects.annotations.Attribute;
 import jdk.nashorn.internal.objects.annotations.Property;
 import jdk.nashorn.internal.objects.annotations.ScriptClass;
@@ -364,6 +365,11 @@
     private ScriptObject   builtinFloat32Array;
     private ScriptObject   builtinFloat64Array;
 
+    /*
+     * ECMA section 13.2.3 The [[ThrowTypeError]] Function Object
+     */
+    private ScriptFunction typeErrorThrower;
+
     private PropertyMap    accessorPropertyDescriptorMap;
     private PropertyMap    arrayBufferViewMap;
     private PropertyMap    dataPropertyDescriptorMap;
@@ -1114,6 +1120,10 @@
         return builtinArray;
     }
 
+    ScriptFunction getTypeErrorThrower() {
+        return typeErrorThrower;
+    }
+
     /**
      * Called from compiled script code to test if builtin has been overridden
      *
@@ -2000,6 +2010,13 @@
         anon.set("constructor", builtinFunction, false);
         anon.deleteOwnProperty(anon.getMap().findProperty("prototype"));
 
+        // use "getter" so that [[ThrowTypeError]] function's arity is 0 - as specified in step 10 of section 13.2.3
+        this.typeErrorThrower = new ScriptFunctionImpl("TypeErrorThrower", Lookup.TYPE_ERROR_THROWER_GETTER, null, null, false, false, false);
+        typeErrorThrower.setPrototype(UNDEFINED);
+        // Non-constructor built-in functions do not have "prototype" property
+        typeErrorThrower.deleteOwnProperty(typeErrorThrower.getMap().findProperty("prototype"));
+        typeErrorThrower.preventExtensions();
+
         // now initialize Object
         this.builtinObject = (ScriptFunction)initConstructor("Object");
         final ScriptObject ObjectPrototype = getObjectPrototype();
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeStrictArguments.java	Thu Dec 19 17:24:39 2013 -0800
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeStrictArguments.java	Mon Dec 23 14:46:33 2013 -0800
@@ -76,7 +76,7 @@
         super(proto, map);
         setIsArguments();
 
-        final ScriptFunction func = ScriptFunctionImpl.getTypeErrorThrower();
+        final ScriptFunction func = Global.instance().getTypeErrorThrower();
         // We have to fill user accessor functions late as these are stored
         // in this object rather than in the PropertyMap of this object.
         setUserAccessors("caller", func, func);
--- a/nashorn/src/jdk/nashorn/internal/objects/ScriptFunctionImpl.java	Thu Dec 19 17:24:39 2013 -0800
+++ b/nashorn/src/jdk/nashorn/internal/objects/ScriptFunctionImpl.java	Mon Dec 23 14:46:33 2013 -0800
@@ -170,26 +170,6 @@
         boundfunctionmap$.setIsShared();
     }
 
-    // function object representing TypeErrorThrower
-    private static ScriptFunction typeErrorThrower;
-
-    /*
-     * ECMA section 13.2.3 The [[ThrowTypeError]] Function Object
-     */
-    static synchronized ScriptFunction getTypeErrorThrower() {
-        if (typeErrorThrower == null) {
-            // use "getter" so that [[ThrowTypeError]] function's arity is 0 - as specified in step 10 of section 13.2.3
-            final ScriptFunctionImpl func = new ScriptFunctionImpl("TypeErrorThrower", Lookup.TYPE_ERROR_THROWER_GETTER, null, null, false, false, false);
-            func.setPrototype(UNDEFINED);
-            // Non-constructor built-in functions do not have "prototype" property
-            func.deleteOwnProperty(func.getMap().findProperty("prototype"));
-            func.preventExtensions();
-            typeErrorThrower = func;
-        }
-
-        return typeErrorThrower;
-    }
-
     private static PropertyMap createStrictModeMap(final PropertyMap map) {
         final int flags = Property.NOT_ENUMERABLE | Property.NOT_CONFIGURABLE;
         PropertyMap newMap = map;
@@ -313,12 +293,13 @@
         // We have to fill user accessor functions late as these are stored
         // in this object rather than in the PropertyMap of this object.
 
+        final ScriptFunction errorThrower = global.getTypeErrorThrower();
         if (findProperty("arguments", true) != null) {
-            setUserAccessors("arguments", getTypeErrorThrower(), getTypeErrorThrower());
+            setUserAccessors("arguments", errorThrower, errorThrower);
         }
 
         if (findProperty("caller", true) != null) {
-            setUserAccessors("caller", getTypeErrorThrower(), getTypeErrorThrower());
+            setUserAccessors("caller", errorThrower, errorThrower);
         }
     }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/JDK-8029467.js	Mon Dec 23 14:46:33 2013 -0800
@@ -0,0 +1,34 @@
+/*
+ * 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.
+ */
+
+/**
+ * JDK-8029467: Widening of booleans causes bad results
+ *
+ * @test
+ * @run
+ */
+
+print((function (x) { return x ? true : 0 })(true))
+print((function (x) { if(x) { return true } else { return 0 } })(true))
+print(typeof (function (x) { return x ? 1 : "123" })(true) === "number")
+print(typeof (function (x) { if(x) { return 1 } else { return "123" } })(true) === "number")
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/JDK-8029467.js.EXPECTED	Mon Dec 23 14:46:33 2013 -0800
@@ -0,0 +1,4 @@
+true
+true
+true
+true
--- a/nashorn/test/script/basic/compile-octane-splitter.js.EXPECTED	Thu Dec 19 17:24:39 2013 -0800
+++ b/nashorn/test/script/basic/compile-octane-splitter.js.EXPECTED	Mon Dec 23 14:46:33 2013 -0800
@@ -1,13 +1,14 @@
-Compiled OK: box2d
-Compiled OK: code-load
-Compiled OK: crypto
-Compiled OK: deltablue
-Compiled OK: earley-boyer
-Compiled OK: gbemu
-Compiled OK: mandreel
-Compiled OK: navier-stokes
-Compiled OK: pdfjs
-Compiled OK: raytrace
-Compiled OK: regexp
-Compiled OK: richards
-Compiled OK: splay
+[box2d] Compiled OK
+[code-load] Compiled OK
+[crypto] Compiled OK
+[deltablue] Compiled OK
+[earley-boyer] Compiled OK
+[gbemu] Compiled OK
+[mandreel] Compiled OK
+[navier-stokes] Compiled OK
+[pdfjs] Compiled OK
+[raytrace] Compiled OK
+[regexp] Compiled OK
+[richards] Compiled OK
+[splay] Compiled OK
+[typescript] Compiled OK
--- a/nashorn/test/script/basic/compile-octane.js.EXPECTED	Thu Dec 19 17:24:39 2013 -0800
+++ b/nashorn/test/script/basic/compile-octane.js.EXPECTED	Mon Dec 23 14:46:33 2013 -0800
@@ -1,13 +1,14 @@
-Compiled OK: box2d
-Compiled OK: code-load
-Compiled OK: crypto
-Compiled OK: deltablue
-Compiled OK: earley-boyer
-Compiled OK: gbemu
-Compiled OK: mandreel
-Compiled OK: navier-stokes
-Compiled OK: pdfjs
-Compiled OK: raytrace
-Compiled OK: regexp
-Compiled OK: richards
-Compiled OK: splay
+[box2d] Compiled OK
+[code-load] Compiled OK
+[crypto] Compiled OK
+[deltablue] Compiled OK
+[earley-boyer] Compiled OK
+[gbemu] Compiled OK
+[mandreel] Compiled OK
+[navier-stokes] Compiled OK
+[pdfjs] Compiled OK
+[raytrace] Compiled OK
+[regexp] Compiled OK
+[richards] Compiled OK
+[splay] Compiled OK
+[typescript] Compiled OK
--- a/nashorn/test/script/basic/run-octane.js	Thu Dec 19 17:24:39 2013 -0800
+++ b/nashorn/test/script/basic/run-octane.js	Mon Dec 23 14:46:33 2013 -0800
@@ -26,19 +26,22 @@
  */
 
 var tests = [
-    {file:"box2d",suite:"Box2DBenchmark"},
-    {file:"code-load",suite:"CodeLoad"},
-    {file:"crypto",suite:"Crypto"},
-    {file:"deltablue",suite:"DeltaBlue"},
-    {file:"earley-boyer", suite:"EarleyBoyer"},
-    {file:"gbemu", suite:"GameboyBenchmark"},
-    {file:"mandreel", suite:"MandreelBenchmark"},
-    {file:"navier-stokes", suite:"NavierStokes"},
-    {file:"pdfjs", suite:"PdfJS"},
-    {file:"raytrace", suite:"RayTrace"},
-    {file:"regexp", suite:"RegExpSuite"},
-    {file:"richards", suite:"Richards"},
-    {file:"splay", suite:"Splay"}
+    {name:"box2d",         files:["box2d.js"],                         suite:"Box2DBenchmark"},
+    {name:"code-load",     files:["code-load.js"],                     suite:"CodeLoad"},
+    {name:"crypto",        files:["crypto.js"],                        suite:"Crypto"},
+    {name:"deltablue",     files:["deltablue.js"],                     suite:"DeltaBlue"},
+    {name:"earley-boyer",  files:["earley-boyer.js"],                  suite:"EarleyBoyer"},
+    {name:"gbemu",         files:["gbemu-part1.js", "gbemu-part2.js"], suite:"GameboyBenchmark"},
+    {name:"mandreel",      files:["mandreel.js"],                      suite:"MandreelBenchmark"},
+    {name:"navier-stokes", files:["navier-stokes.js"],                 suite:"NavierStokes"},
+    {name:"pdfjs",         files:["pdfjs.js"],                         suite:"PdfJS"},
+    {name:"raytrace",      files:["raytrace.js"],                      suite:"RayTrace"},
+    {name:"regexp",        files:["regexp.js"],                        suite:"RegExpSuite"},
+    {name:"richards",      files:["richards.js"],                      suite:"Richards"},
+    {name:"splay",         files:["splay.js"],                         suite:"Splay"},
+    {name:"typescript",    files:["typescript.js", "typescript-input.js", "typescript-compiler.js"], suite:"typescript"}
+    //zlib currently disabled - requires read
+    //    {name:"zlib",          files:["zlib.js", "zlib-data.js"], suite:"zlib"},
 ];
 var dir = (typeof(__DIR__) == 'undefined') ? "test/script/basic/" : __DIR__;
 
@@ -58,26 +61,36 @@
     return (typeof compile_only !== 'undefined')
 }
 
-function run_one_benchmark(arg, iters) {
-    var file_name;
-    var file = (arg.file + ".js").split('/');
+function load_bench(arg) {
+
+    for (var idx = 0; idx < arg.files.length; idx++) {
+	var f = arg.files[idx];
+	var file = f.split('/');
+	var file_name = path + file[file.length - 1];
     
-    file_name = path + file[file.length - 1];
-    
-    var compile_and_return = should_compile_only(file_name);
+	var compile_and_return = should_compile_only(file_name);
+	if (compile_and_return) {
+	    if (typeof compile_only === 'undefined') { //for a run, skip compile onlies, don't even compile them
+		return true;
+	    }
+	}
+	
+	print_verbose(arg, "loading '" + arg.name + "' [" + f + "]...");
+	load(file_name); 
+    }
+
     if (compile_and_return) {
-	if (typeof compile_only === 'undefined') { //for a run, skip compile onlies, don't even compile them
-	    return;
-	}
+	print_always(arg, "Compiled OK");
     }
-    
-    print_verbose("Loading... " + file_name);
-    load(file_name);
-    
-    if (compile_and_return) {
-	print_always("Compiled OK: " + arg.file);
+    return !compile_and_return;
+
+}
+
+function run_one_benchmark(arg, iters) {
+
+    if (!load_bench(arg)) {
 	return;
-    }
+    }    
     
     var success = true;
     var current_name;
@@ -95,9 +108,13 @@
 
     try {
 	for (var x = 0; x < benchmarks.length ; x++) { 
+	    //do warmup run
+	    //reset random number generator needed as of octane 9 before each run
+	    BenchmarkSuite.ResetRNG();
 	    benchmarks[x].Setup();
 	}
-	print_verbose("Running '" + arg.file + "' for " + iters + " iterations of no less than " + min_time + " seconds (" + runtime + ")");
+	BenchmarkSuite.ResetRNG();
+	print_verbose(arg, "running '" + arg.name + "' for " + iters + " iterations of no less than " + min_time + " seconds (" + runtime + ")");
 	
 	var scores = [];
 	
@@ -112,6 +129,9 @@
 	    do {
 		for (var i = 0; i < len; i++) {
 		    benchmarks[i].run();
+		    //important - no timing here like elapsed = new Date() - start, as in the 
+		    //original harness. This will make timing very non-deterministic.
+		    //NOTHING else must live in this loop
 		}	    
 		ops += len;
 		elapsed = new Date - start;
@@ -120,7 +140,7 @@
 	    var score = ops / elapsed * 1000 * 60;
 	    scores.push(score);
 	    var name = it == 0 ? "warmup" : "iteration " + it;   
-	    print_verbose("[" + arg.file + "] " + name + " finished " + score.toFixed(0) + " ops/minute");
+	    print_verbose(arg, name + " finished " + score.toFixed(0) + " ops/minute");
 	}
 
 	for (var x = 0; x < benchmarks.length ; x++) { 
@@ -140,20 +160,20 @@
 	scores = [0];
     }
 
-    var res = "[" + arg.file + "] " + mean_score.toFixed(0);
+    var res = mean_score.toFixed(0);
     if (verbose) {
 	res += " ops/minute (" + min_score.toFixed(0) + "-" + max_score.toFixed(0) + "), warmup=" + scores[0].toFixed(0);
     }
-    print_always(res);
+    print_always(arg, res);
 }
 
-function print_always(x) {
-    print(x);
+function print_always(arg, x) {
+    print("[" + arg.name + "] " + x);
 }
 
-function print_verbose(x) {
+function print_verbose(arg, x) {
     if (verbose) {
-	print(x);
+	print_always(arg, x)
     }
 }
 
@@ -209,7 +229,7 @@
     } else {
 	var found = false;
 	for (j in tests) {
-	    if (tests[j].file === arg) {
+	    if (tests[j].name === arg) {
 		tests_found.push(tests[j]);
 		found = true;
 		break;
@@ -221,7 +241,7 @@
 		if (j != 0) {
 		    str += ", ";
 		}
-		str += "'" + tests[j].file + "'";
+		str += "'" + tests[j].name + "'";
 	    }
 	    throw str;
 	}