# HG changeset patch # User asaha # Date 1388705513 28800 # Node ID 4c088dea0e5e27de5d6dbd3e65bb633962cc361a # Parent 703a74c914fef4395679f28d2f2f48d12b432021# Parent 35eadc466f6290fd1e505d5527c0b8b682d8bd5d Merge diff -r 703a74c914fe -r 4c088dea0e5e nashorn/make/build-benchmark.xml --- a/nashorn/make/build-benchmark.xml Fri Dec 20 07:44:42 2013 -0800 +++ b/nashorn/make/build-benchmark.xml Thu Jan 02 15:31:53 2014 -0800 @@ -239,7 +239,7 @@ - + @@ -291,17 +291,56 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + octane-mandreel, octane-navier-stokes, octane-pdfjs, + octane-raytrace, octane-regexp, octane-richards, + octane-splay, octane-typescript"/> diff -r 703a74c914fe -r 4c088dea0e5e nashorn/src/jdk/nashorn/internal/codegen/Attr.java --- a/nashorn/src/jdk/nashorn/internal/codegen/Attr.java Fri Dec 20 07:44:42 2013 -0800 +++ b/nashorn/src/jdk/nashorn/internal/codegen/Attr.java Thu Jan 02 15:31:53 2014 -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. diff -r 703a74c914fe -r 4c088dea0e5e nashorn/src/jdk/nashorn/internal/objects/Global.java --- a/nashorn/src/jdk/nashorn/internal/objects/Global.java Fri Dec 20 07:44:42 2013 -0800 +++ b/nashorn/src/jdk/nashorn/internal/objects/Global.java Thu Jan 02 15:31:53 2014 -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(); diff -r 703a74c914fe -r 4c088dea0e5e nashorn/src/jdk/nashorn/internal/objects/NativeStrictArguments.java --- a/nashorn/src/jdk/nashorn/internal/objects/NativeStrictArguments.java Fri Dec 20 07:44:42 2013 -0800 +++ b/nashorn/src/jdk/nashorn/internal/objects/NativeStrictArguments.java Thu Jan 02 15:31:53 2014 -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); diff -r 703a74c914fe -r 4c088dea0e5e nashorn/src/jdk/nashorn/internal/objects/ScriptFunctionImpl.java --- a/nashorn/src/jdk/nashorn/internal/objects/ScriptFunctionImpl.java Fri Dec 20 07:44:42 2013 -0800 +++ b/nashorn/src/jdk/nashorn/internal/objects/ScriptFunctionImpl.java Thu Jan 02 15:31:53 2014 -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); } } } diff -r 703a74c914fe -r 4c088dea0e5e nashorn/test/script/basic/JDK-8029467.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/nashorn/test/script/basic/JDK-8029467.js Thu Jan 02 15:31:53 2014 -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") diff -r 703a74c914fe -r 4c088dea0e5e nashorn/test/script/basic/JDK-8029467.js.EXPECTED --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/nashorn/test/script/basic/JDK-8029467.js.EXPECTED Thu Jan 02 15:31:53 2014 -0800 @@ -0,0 +1,4 @@ +true +true +true +true diff -r 703a74c914fe -r 4c088dea0e5e nashorn/test/script/basic/compile-octane-splitter.js.EXPECTED --- a/nashorn/test/script/basic/compile-octane-splitter.js.EXPECTED Fri Dec 20 07:44:42 2013 -0800 +++ b/nashorn/test/script/basic/compile-octane-splitter.js.EXPECTED Thu Jan 02 15:31:53 2014 -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 diff -r 703a74c914fe -r 4c088dea0e5e nashorn/test/script/basic/compile-octane.js.EXPECTED --- a/nashorn/test/script/basic/compile-octane.js.EXPECTED Fri Dec 20 07:44:42 2013 -0800 +++ b/nashorn/test/script/basic/compile-octane.js.EXPECTED Thu Jan 02 15:31:53 2014 -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 diff -r 703a74c914fe -r 4c088dea0e5e nashorn/test/script/basic/run-octane.js --- a/nashorn/test/script/basic/run-octane.js Fri Dec 20 07:44:42 2013 -0800 +++ b/nashorn/test/script/basic/run-octane.js Thu Jan 02 15:31:53 2014 -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; }