This commit is contained in:
Lana Steuck 2013-12-23 14:46:33 -08:00
commit 31bf8f42d3
10 changed files with 210 additions and 93 deletions

View File

@ -239,7 +239,7 @@
</antcall> </antcall>
</target> </target>
<target name="octane-regexp-octane-v8" depends="jar"> <target name="octane-regexp-v8" depends="jar">
<antcall target="run-octane-v8"> <antcall target="run-octane-v8">
<param name="octane-tests" value="regexp"/> <param name="octane-tests" value="regexp"/>
</antcall> </antcall>
@ -291,17 +291,56 @@
</antcall> </antcall>
</target> </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 --> <!-- run octane benchmarks in a single process -->
<target name="octane-single-process" depends="octane-init"> <target name="octane-single-process" depends="octane-init">
<antcall target="run-octane"/> <antcall target="run-octane"/>
</target> </target>
<!-- mandreel excluded due to OOM --> <!-- zlib excluded due to missing implementation of 'read' -->
<target name="octane-separate-process" depends= <target name="octane-separate-process" depends=
"octane-box2d, octane-code-load, octane-crypto, "octane-box2d, octane-code-load, octane-crypto,
octane-deltablue, octane-earley-boyer, octane-gbemu, octane-deltablue, octane-earley-boyer, octane-gbemu,
octane-navier-stokes, octane-pdfjs, octane-raytrace, octane-mandreel, octane-navier-stokes, octane-pdfjs,
octane-regexp, octane-richards, octane-splay"/> octane-raytrace, octane-regexp, octane-richards,
octane-splay, octane-typescript"/>
<target name="--single-process" unless="${octane-test-sys-prop.separate.process}"> <target name="--single-process" unless="${octane-test-sys-prop.separate.process}">
<antcall target="octane-single-process"/> <antcall target="octane-single-process"/>

View File

@ -766,7 +766,7 @@ final class Attr extends NodeOperatorVisitor<LexicalContext> {
symbol.setType(Type.OBJECT); symbol.setType(Type.OBJECT);
} }
returnType = Type.widest(returnTypes.pop(), symbol.getSymbolType()); returnType = widestReturnType(returnTypes.pop(), symbol.getSymbolType());
} else { } else {
returnType = Type.OBJECT; //undefined returnType = Type.OBJECT; //undefined
} }
@ -1433,10 +1433,30 @@ final class Attr extends NodeOperatorVisitor<LexicalContext> {
ensureTypeNotUnknown(trueExpr); ensureTypeNotUnknown(trueExpr);
ensureTypeNotUnknown(falseExpr); ensureTypeNotUnknown(falseExpr);
final Type type = Type.widest(trueExpr.getType(), falseExpr.getType()); final Type type = widestReturnType(trueExpr.getType(), falseExpr.getType());
return end(ensureSymbol(type, ternaryNode)); 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) { private void initCompileConstant(final CompilerConstants cc, final Block block, final int flags) {
final Class<?> type = cc.type(); final Class<?> type = cc.type();
// Must not call this method for constants with no explicit types; use the one with (..., Type) signature instead. // Must not call this method for constants with no explicit types; use the one with (..., Type) signature instead.

View File

@ -44,6 +44,7 @@ import java.util.concurrent.Callable;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import jdk.internal.dynalink.linker.GuardedInvocation; import jdk.internal.dynalink.linker.GuardedInvocation;
import jdk.internal.dynalink.linker.LinkRequest; 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.Attribute;
import jdk.nashorn.internal.objects.annotations.Property; import jdk.nashorn.internal.objects.annotations.Property;
import jdk.nashorn.internal.objects.annotations.ScriptClass; import jdk.nashorn.internal.objects.annotations.ScriptClass;
@ -364,6 +365,11 @@ public final class Global extends ScriptObject implements GlobalObject, Scope {
private ScriptObject builtinFloat32Array; private ScriptObject builtinFloat32Array;
private ScriptObject builtinFloat64Array; private ScriptObject builtinFloat64Array;
/*
* ECMA section 13.2.3 The [[ThrowTypeError]] Function Object
*/
private ScriptFunction typeErrorThrower;
private PropertyMap accessorPropertyDescriptorMap; private PropertyMap accessorPropertyDescriptorMap;
private PropertyMap arrayBufferViewMap; private PropertyMap arrayBufferViewMap;
private PropertyMap dataPropertyDescriptorMap; private PropertyMap dataPropertyDescriptorMap;
@ -1114,6 +1120,10 @@ public final class Global extends ScriptObject implements GlobalObject, Scope {
return builtinArray; return builtinArray;
} }
ScriptFunction getTypeErrorThrower() {
return typeErrorThrower;
}
/** /**
* Called from compiled script code to test if builtin has been overridden * Called from compiled script code to test if builtin has been overridden
* *
@ -2000,6 +2010,13 @@ public final class Global extends ScriptObject implements GlobalObject, Scope {
anon.set("constructor", builtinFunction, false); anon.set("constructor", builtinFunction, false);
anon.deleteOwnProperty(anon.getMap().findProperty("prototype")); 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 // now initialize Object
this.builtinObject = (ScriptFunction)initConstructor("Object"); this.builtinObject = (ScriptFunction)initConstructor("Object");
final ScriptObject ObjectPrototype = getObjectPrototype(); final ScriptObject ObjectPrototype = getObjectPrototype();

View File

@ -76,7 +76,7 @@ public final class NativeStrictArguments extends ScriptObject {
super(proto, map); super(proto, map);
setIsArguments(); setIsArguments();
final ScriptFunction func = ScriptFunctionImpl.getTypeErrorThrower(); final ScriptFunction func = Global.instance().getTypeErrorThrower();
// We have to fill user accessor functions late as these are stored // We have to fill user accessor functions late as these are stored
// in this object rather than in the PropertyMap of this object. // in this object rather than in the PropertyMap of this object.
setUserAccessors("caller", func, func); setUserAccessors("caller", func, func);

View File

@ -170,26 +170,6 @@ public class ScriptFunctionImpl extends ScriptFunction {
boundfunctionmap$.setIsShared(); 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) { private static PropertyMap createStrictModeMap(final PropertyMap map) {
final int flags = Property.NOT_ENUMERABLE | Property.NOT_CONFIGURABLE; final int flags = Property.NOT_ENUMERABLE | Property.NOT_CONFIGURABLE;
PropertyMap newMap = map; PropertyMap newMap = map;
@ -313,12 +293,13 @@ public class ScriptFunctionImpl extends ScriptFunction {
// We have to fill user accessor functions late as these are stored // We have to fill user accessor functions late as these are stored
// in this object rather than in the PropertyMap of this object. // in this object rather than in the PropertyMap of this object.
final ScriptFunction errorThrower = global.getTypeErrorThrower();
if (findProperty("arguments", true) != null) { if (findProperty("arguments", true) != null) {
setUserAccessors("arguments", getTypeErrorThrower(), getTypeErrorThrower()); setUserAccessors("arguments", errorThrower, errorThrower);
} }
if (findProperty("caller", true) != null) { if (findProperty("caller", true) != null) {
setUserAccessors("caller", getTypeErrorThrower(), getTypeErrorThrower()); setUserAccessors("caller", errorThrower, errorThrower);
} }
} }
} }

View File

@ -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")

View File

@ -0,0 +1,4 @@
true
true
true
true

View File

@ -1,13 +1,14 @@
Compiled OK: box2d [box2d] Compiled OK
Compiled OK: code-load [code-load] Compiled OK
Compiled OK: crypto [crypto] Compiled OK
Compiled OK: deltablue [deltablue] Compiled OK
Compiled OK: earley-boyer [earley-boyer] Compiled OK
Compiled OK: gbemu [gbemu] Compiled OK
Compiled OK: mandreel [mandreel] Compiled OK
Compiled OK: navier-stokes [navier-stokes] Compiled OK
Compiled OK: pdfjs [pdfjs] Compiled OK
Compiled OK: raytrace [raytrace] Compiled OK
Compiled OK: regexp [regexp] Compiled OK
Compiled OK: richards [richards] Compiled OK
Compiled OK: splay [splay] Compiled OK
[typescript] Compiled OK

View File

@ -1,13 +1,14 @@
Compiled OK: box2d [box2d] Compiled OK
Compiled OK: code-load [code-load] Compiled OK
Compiled OK: crypto [crypto] Compiled OK
Compiled OK: deltablue [deltablue] Compiled OK
Compiled OK: earley-boyer [earley-boyer] Compiled OK
Compiled OK: gbemu [gbemu] Compiled OK
Compiled OK: mandreel [mandreel] Compiled OK
Compiled OK: navier-stokes [navier-stokes] Compiled OK
Compiled OK: pdfjs [pdfjs] Compiled OK
Compiled OK: raytrace [raytrace] Compiled OK
Compiled OK: regexp [regexp] Compiled OK
Compiled OK: richards [richards] Compiled OK
Compiled OK: splay [splay] Compiled OK
[typescript] Compiled OK

View File

@ -26,19 +26,22 @@
*/ */
var tests = [ var tests = [
{file:"box2d",suite:"Box2DBenchmark"}, {name:"box2d", files:["box2d.js"], suite:"Box2DBenchmark"},
{file:"code-load",suite:"CodeLoad"}, {name:"code-load", files:["code-load.js"], suite:"CodeLoad"},
{file:"crypto",suite:"Crypto"}, {name:"crypto", files:["crypto.js"], suite:"Crypto"},
{file:"deltablue",suite:"DeltaBlue"}, {name:"deltablue", files:["deltablue.js"], suite:"DeltaBlue"},
{file:"earley-boyer", suite:"EarleyBoyer"}, {name:"earley-boyer", files:["earley-boyer.js"], suite:"EarleyBoyer"},
{file:"gbemu", suite:"GameboyBenchmark"}, {name:"gbemu", files:["gbemu-part1.js", "gbemu-part2.js"], suite:"GameboyBenchmark"},
{file:"mandreel", suite:"MandreelBenchmark"}, {name:"mandreel", files:["mandreel.js"], suite:"MandreelBenchmark"},
{file:"navier-stokes", suite:"NavierStokes"}, {name:"navier-stokes", files:["navier-stokes.js"], suite:"NavierStokes"},
{file:"pdfjs", suite:"PdfJS"}, {name:"pdfjs", files:["pdfjs.js"], suite:"PdfJS"},
{file:"raytrace", suite:"RayTrace"}, {name:"raytrace", files:["raytrace.js"], suite:"RayTrace"},
{file:"regexp", suite:"RegExpSuite"}, {name:"regexp", files:["regexp.js"], suite:"RegExpSuite"},
{file:"richards", suite:"Richards"}, {name:"richards", files:["richards.js"], suite:"Richards"},
{file:"splay", suite:"Splay"} {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__; var dir = (typeof(__DIR__) == 'undefined') ? "test/script/basic/" : __DIR__;
@ -58,26 +61,36 @@ function should_compile_only(name) {
return (typeof compile_only !== 'undefined') return (typeof compile_only !== 'undefined')
} }
function run_one_benchmark(arg, iters) { function load_bench(arg) {
var file_name;
var file = (arg.file + ".js").split('/'); 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);
if (compile_and_return) {
var compile_and_return = should_compile_only(file_name); if (typeof compile_only === 'undefined') { //for a run, skip compile onlies, don't even compile them
if (compile_and_return) { return true;
if (typeof compile_only === 'undefined') { //for a run, skip compile onlies, don't even compile them }
return;
} }
print_verbose(arg, "loading '" + arg.name + "' [" + f + "]...");
load(file_name);
} }
print_verbose("Loading... " + file_name);
load(file_name);
if (compile_and_return) { if (compile_and_return) {
print_always("Compiled OK: " + arg.file); print_always(arg, "Compiled OK");
return;
} }
return !compile_and_return;
}
function run_one_benchmark(arg, iters) {
if (!load_bench(arg)) {
return;
}
var success = true; var success = true;
var current_name; var current_name;
@ -95,9 +108,13 @@ function run_one_benchmark(arg, iters) {
try { try {
for (var x = 0; x < benchmarks.length ; x++) { 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(); 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 = []; var scores = [];
@ -112,6 +129,9 @@ function run_one_benchmark(arg, iters) {
do { do {
for (var i = 0; i < len; i++) { for (var i = 0; i < len; i++) {
benchmarks[i].run(); 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; ops += len;
elapsed = new Date - start; elapsed = new Date - start;
@ -120,7 +140,7 @@ function run_one_benchmark(arg, iters) {
var score = ops / elapsed * 1000 * 60; var score = ops / elapsed * 1000 * 60;
scores.push(score); scores.push(score);
var name = it == 0 ? "warmup" : "iteration " + it; 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++) { for (var x = 0; x < benchmarks.length ; x++) {
@ -140,20 +160,20 @@ function run_one_benchmark(arg, iters) {
scores = [0]; scores = [0];
} }
var res = "[" + arg.file + "] " + mean_score.toFixed(0); var res = mean_score.toFixed(0);
if (verbose) { if (verbose) {
res += " ops/minute (" + min_score.toFixed(0) + "-" + max_score.toFixed(0) + "), warmup=" + scores[0].toFixed(0); 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) { function print_always(arg, x) {
print(x); print("[" + arg.name + "] " + x);
} }
function print_verbose(x) { function print_verbose(arg, x) {
if (verbose) { if (verbose) {
print(x); print_always(arg, x)
} }
} }
@ -209,7 +229,7 @@ for (var i = 0; i < args.length; i++) {
} else { } else {
var found = false; var found = false;
for (j in tests) { for (j in tests) {
if (tests[j].file === arg) { if (tests[j].name === arg) {
tests_found.push(tests[j]); tests_found.push(tests[j]);
found = true; found = true;
break; break;
@ -221,7 +241,7 @@ for (var i = 0; i < args.length; i++) {
if (j != 0) { if (j != 0) {
str += ", "; str += ", ";
} }
str += "'" + tests[j].file + "'"; str += "'" + tests[j].name + "'";
} }
throw str; throw str;
} }