8048869: Reduce compile time by about 5% by removing the Class.casts from the AST nodes

Removed the native casts that slow down the compiler unnecessarily. I also modified the compile-octane harness so that it can run with --verbose and --iterations flags so that you can run the compiler for an arbitrary time, gathering a mission control executing profile.

Reviewed-by: attila, jlaskey
This commit is contained in:
Marcus Lagergren 2014-07-29 14:21:45 -07:00
parent ad9ca4fb43
commit 5c93b19922
36 changed files with 398 additions and 136 deletions

@ -111,7 +111,7 @@ public class CompositeTypeBasedGuardingDynamicLinker implements TypeBasedGuardin
private final TypeBasedGuardingDynamicLinker[] linkers;
private final List<TypeBasedGuardingDynamicLinker>[] singletonLinkers;
@SuppressWarnings(value={"unchecked", "rawtypes"})
@SuppressWarnings("unchecked")
ClassToLinker(final TypeBasedGuardingDynamicLinker[] linkers) {
this.linkers = linkers;
singletonLinkers = new List[linkers.length];
@ -135,7 +135,6 @@ public class CompositeTypeBasedGuardingDynamicLinker implements TypeBasedGuardin
case 1: {
list = new LinkedList<>(list);
}
//$FALL-THROUGH$
default: {
list.add(linker);
}

@ -40,6 +40,7 @@ import java.security.ProtectionDomain;
import java.text.MessageFormat;
import java.util.Locale;
import java.util.ResourceBundle;
import javax.script.AbstractScriptEngine;
import javax.script.Bindings;
import javax.script.Compilable;
@ -50,6 +51,7 @@ import javax.script.ScriptEngine;
import javax.script.ScriptEngineFactory;
import javax.script.ScriptException;
import javax.script.SimpleBindings;
import jdk.nashorn.internal.objects.Global;
import jdk.nashorn.internal.runtime.Context;
import jdk.nashorn.internal.runtime.ErrorManager;
@ -429,7 +431,7 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C
return evalImpl(script, ctxt, getNashornGlobalFrom(ctxt));
}
private Object evalImpl(final Context.MultiGlobalCompiledScript mgcs, final ScriptContext ctxt, final Global ctxtGlobal) throws ScriptException {
private static Object evalImpl(final Context.MultiGlobalCompiledScript mgcs, final ScriptContext ctxt, final Global ctxtGlobal) throws ScriptException {
final Global oldGlobal = Context.getGlobal();
final boolean globalChanged = (oldGlobal != ctxtGlobal);
try {
@ -450,7 +452,7 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C
}
}
private Object evalImpl(final ScriptFunction script, final ScriptContext ctxt, final Global ctxtGlobal) throws ScriptException {
private static Object evalImpl(final ScriptFunction script, final ScriptContext ctxt, final Global ctxtGlobal) throws ScriptException {
if (script == null) {
return null;
}

@ -1097,7 +1097,11 @@ final class CodeGenerator extends NodeOperatorVisitor<CodeGeneratorLexicalContex
closeBlockVariables(block);
lc.releaseSlots();
assert !method.isReachable() || (lc.isFunctionBody() ? 0 : lc.getUsedSlotCount()) == method.getFirstTemp();
assert !method.isReachable() || (lc.isFunctionBody() ? 0 : lc.getUsedSlotCount()) == method.getFirstTemp() :
"reachable="+method.isReachable() +
" isFunctionBody=" + lc.isFunctionBody() +
" usedSlotCount=" + lc.getUsedSlotCount() +
" firstTemp=" + method.getFirstTemp();
return block;
}

@ -43,7 +43,6 @@ import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.IdentityHashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
@ -334,15 +333,15 @@ enum CompilationPhase {
sb.append("$restOf");
}
newUnit = compiler.createCompileUnit(sb.toString(), oldUnit.getWeight());
log.info("Creating new compile unit ", oldUnit, " => ", newUnit);
log.fine("Creating new compile unit ", oldUnit, " => ", newUnit);
map.put(oldUnit, newUnit);
assert newUnit != null;
newUnits.add(newUnit);
}
log.info("Replacing compile units in Compiler...");
log.fine("Replacing compile units in Compiler...");
compiler.replaceCompileUnits(newUnits);
log.info("Done");
log.fine("Done");
//replace old compile units in function nodes, if any are assigned,
//for example by running the splitter on this function node in a previous
@ -564,7 +563,7 @@ enum CompilationPhase {
append(compiler.getCompileUnits().size()).
append(" compile unit(s)]");
log.info(sb.toString());
log.fine(sb.toString());
}
return setStates(fn.setRootClass(null, rootClass), BYTECODE_INSTALLED);

@ -50,6 +50,7 @@ import java.util.TreeMap;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Consumer;
import java.util.logging.Level;
import jdk.internal.dynalink.support.NameCodec;
import jdk.nashorn.internal.codegen.ClassEmitter.Flag;
import jdk.nashorn.internal.codegen.types.Type;
@ -502,7 +503,7 @@ public final class Compiler implements Loggable {
*/
public FunctionNode compile(final FunctionNode functionNode, final CompilationPhases phases) throws CompilationException {
log.info("Starting compile job for ", DebugLogger.quote(functionNode.getName()), " phases=", quote(phases.getDesc()));
log.finest("Starting compile job for ", DebugLogger.quote(functionNode.getName()), " phases=", quote(phases.getDesc()));
log.indent();
final String name = DebugLogger.quote(functionNode.getName());
@ -531,7 +532,7 @@ public final class Compiler implements Loggable {
time += (env.isTimingEnabled() ? phase.getEndTime() - phase.getStartTime() : 0L);
}
if(typeInformationFile != null && !phases.isRestOfCompilation()) {
if (typeInformationFile != null && !phases.isRestOfCompilation()) {
OptimisticTypesPersistence.store(typeInformationFile, invalidatedProgramPoints);
}

@ -34,6 +34,7 @@ import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.ListIterator;
import jdk.nashorn.internal.ir.BaseNode;
import jdk.nashorn.internal.ir.BinaryNode;
import jdk.nashorn.internal.ir.Block;

@ -41,6 +41,7 @@ import java.util.Base64;
import java.util.Date;
import java.util.Map;
import java.util.TreeMap;
import jdk.nashorn.internal.codegen.types.Type;
import jdk.nashorn.internal.runtime.Context;
import jdk.nashorn.internal.runtime.RecompilableScriptFunctionData;
@ -111,6 +112,7 @@ public final class OptimisticTypesPersistence {
return;
}
final File file = ((LocationDescriptor)locationDescriptor).file;
AccessController.doPrivileged(new PrivilegedAction<Void>() {
@Override
public Void run() {
@ -119,7 +121,7 @@ public final class OptimisticTypesPersistence {
out.getChannel().lock(); // lock exclusive
final DataOutputStream dout = new DataOutputStream(new BufferedOutputStream(out));
dout.writeInt(optimisticTypes.size());
for(Map.Entry<Integer, Type> e: optimisticTypes.entrySet()) {
for(final Map.Entry<Integer, Type> e: optimisticTypes.entrySet()) {
dout.writeInt(e.getKey());
final byte typeChar;
final Type type = e.getValue();
@ -156,7 +158,6 @@ public final class OptimisticTypesPersistence {
return null;
}
final File file = ((LocationDescriptor)locationDescriptor).file;
return AccessController.doPrivileged(new PrivilegedAction<Map<Integer, Type>>() {
@Override
public Map<Integer, Type> run() {
@ -229,7 +230,7 @@ public final class OptimisticTypesPersistence {
final String versionDirName;
try {
versionDirName = getVersionDirName();
} catch(Exception e) {
} catch(final Exception e) {
getLogger().warning("Failed to calculate version dir name", e);
return null;
}
@ -306,7 +307,7 @@ public final class OptimisticTypesPersistence {
private static long getLastModifiedClassFile(final File dir, final long max) {
long currentMax = max;
for(File f: dir.listFiles()) {
for(final File f: dir.listFiles()) {
if(f.getName().endsWith(".class")) {
final long lastModified = f.lastModified();
if(lastModified > currentMax) {

@ -149,7 +149,7 @@ public class Block extends Node implements BreakableNode, Terminal, Flags<Block>
@Override
public Node accept(final LexicalContext lc, final NodeVisitor<? extends LexicalContext> visitor) {
if (visitor.enterBlock(this)) {
return visitor.leaveBlock(setStatements(lc, Node.accept(visitor, Statement.class, statements)));
return visitor.leaveBlock(setStatements(lc, Node.accept(visitor, statements)));
}
return this;

@ -30,6 +30,7 @@ import static jdk.nashorn.internal.runtime.UnwarrantedOptimismException.INVALID_
import java.util.Collections;
import java.util.List;
import java.util.function.Function;
import jdk.nashorn.internal.codegen.types.Type;
import jdk.nashorn.internal.ir.annotations.Ignore;
import jdk.nashorn.internal.ir.annotations.Immutable;
@ -175,10 +176,10 @@ public final class CallNode extends LexicalContextExpression implements Optimist
if (visitor.enterCallNode(this)) {
final CallNode newCallNode = (CallNode)visitor.leaveCallNode(
setFunction((Expression)function.accept(visitor)).
setArgs(Node.accept(visitor, Expression.class, args)).
setArgs(Node.accept(visitor, args)).
setEvalArgs(evalArgs == null ?
null :
evalArgs.setArgs(Node.accept(visitor, Expression.class, evalArgs.getArgs()))));
evalArgs.setArgs(Node.accept(visitor, evalArgs.getArgs()))));
// Theoretically, we'd need to instead pass lc to every setter and do a replacement on each. In practice,
// setType from TypeOverride can't accept a lc, and we don't necessarily want to go there now.
if (this != newCallNode) {

@ -359,7 +359,7 @@ public final class FunctionNode extends LexicalContextExpression implements Flag
* @return a list of parameter nodes, potentially modified from original ones by the visitor.
*/
public List<IdentNode> visitParameters(final NodeVisitor<? extends LexicalContext> visitor) {
return Node.accept(visitor, IdentNode.class, parameters);
return Node.accept(visitor, parameters);
}
/**

@ -27,6 +27,7 @@ package jdk.nashorn.internal.ir;
import java.io.File;
import java.util.Iterator;
import java.util.NoSuchElementException;
import jdk.nashorn.internal.runtime.Debug;
import jdk.nashorn.internal.runtime.Source;
@ -652,6 +653,7 @@ public class LexicalContext {
return lnext;
}
@SuppressWarnings("unchecked")
private T findNext() {
for (int i = index; i >= 0; i--) {
final Object node = stack[i];
@ -660,7 +662,7 @@ public class LexicalContext {
}
if (clazz.isAssignableFrom(node.getClass())) {
index = i - 1;
return clazz.cast(node);
return (T)node;
}
}
return null;

@ -934,7 +934,7 @@ public abstract class LiteralNode<T> extends Expression implements PropertyKey {
public Node accept(final LexicalContext lc, final NodeVisitor<? extends LexicalContext> visitor) {
if (visitor.enterLiteralNode(this)) {
final List<Expression> oldValue = Arrays.asList(value);
final List<Expression> newValue = Node.accept(visitor, Expression.class, oldValue);
final List<Expression> newValue = Node.accept(visitor, oldValue);
return visitor.leaveLiteralNode(oldValue != newValue ? setValue(lc, newValue) : this);
}
return this;

@ -27,6 +27,7 @@ package jdk.nashorn.internal.ir;
import java.util.ArrayList;
import java.util.List;
import jdk.nashorn.internal.ir.visitor.NodeVisitor;
import jdk.nashorn.internal.parser.Token;
import jdk.nashorn.internal.parser.TokenType;
@ -232,19 +233,34 @@ public abstract class Node implements Cloneable {
}
//on change, we have to replace the entire list, that's we can't simple do ListIterator.set
static <T extends Node> List<T> accept(final NodeVisitor<? extends LexicalContext> visitor, final Class<T> clazz, final List<T> list) {
boolean changed = false;
final List<T> newList = new ArrayList<>();
for (final Node node : list) {
final T newNode = node == null ? null : clazz.cast(node.accept(visitor));
if (newNode != node) {
changed = true;
}
newList.add(newNode);
static <T extends Node> List<T> accept(final NodeVisitor<? extends LexicalContext> visitor, final List<T> list) {
final int size = list.size();
if (size == 0) {
return list;
}
return changed ? newList : list;
List<T> newList = null;
for (int i = 0; i < size; i++) {
final T node = list.get(i);
@SuppressWarnings("unchecked")
final T newNode = node == null ? null : (T)node.accept(visitor);
if (newNode != node) {
if (newList == null) {
newList = new ArrayList<>(size);
for (int j = 0; j < i; j++) {
newList.add(list.get(j));
}
}
newList.add(newNode);
} else {
if (newList != null) {
newList.add(node);
}
}
}
return newList == null ? list : newList;
}
static <T extends LexicalContextNode> T replaceInLexicalContext(final LexicalContext lc, final T oldNode, final T newNode) {

@ -61,7 +61,7 @@ public final class ObjectNode extends Expression {
@Override
public Node accept(final NodeVisitor<? extends LexicalContext> visitor) {
if (visitor.enterObjectNode(this)) {
return visitor.leaveObjectNode(setElements(Node.accept(visitor, PropertyNode.class, elements)));
return visitor.leaveObjectNode(setElements(Node.accept(visitor, elements)));
}
return this;

@ -104,7 +104,7 @@ public final class SwitchNode extends BreakableStatement {
if (visitor.enterSwitchNode(this)) {
return visitor.leaveSwitchNode(
setExpression(lc, (Expression)expression.accept(visitor)).
setCases(lc, Node.accept(visitor, CaseNode.class, cases), defaultCaseIndex));
setCases(lc, Node.accept(visitor, cases), defaultCaseIndex));
}
return this;

@ -112,7 +112,7 @@ public final class TryNode extends Statement implements JoinPredecessor {
return visitor.leaveTryNode(
setBody(newBody).
setFinallyBody(newFinallyBody).
setCatchBlocks(Node.accept(visitor, Block.class, catchBlocks)).
setCatchBlocks(Node.accept(visitor, catchBlocks)).
setFinallyCatchAll(finallyCatchAll));
}

@ -30,7 +30,7 @@ import java.util.Comparator;
/**
* Class histogram element for IR / Java object instrumentation
*/
public class ClassHistogramElement {
public final class ClassHistogramElement {
/**
* Instance comparator
*/

@ -39,6 +39,7 @@ import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import jdk.internal.org.objectweb.asm.Attribute;
import jdk.internal.org.objectweb.asm.Handle;
import jdk.internal.org.objectweb.asm.Label;
@ -1082,11 +1083,15 @@ public final class NashornTextifier extends Printer {
contents.put(node, sb);
}
private static String dottyFriendly(final String name) {
return name.replace(':', '_');
}
@Override
public String toString() {
final StringBuilder sb = new StringBuilder();
sb.append("digraph " + name + " {");
sb.append("digraph " + dottyFriendly(name) + " {");
sb.append("\n");
sb.append("\tgraph [fontname=courier]\n");
sb.append("\tnode [style=filled,color="+COLOR_DEFAULT+",fontname=courier]\n");

@ -52,7 +52,7 @@ import java.util.Map;
* this fact and will report incorrect sizes, as it will presume the default JVM
* behavior.
*/
public class ObjectSizeCalculator {
public final class ObjectSizeCalculator {
/**
* Describes constant memory overheads for various constructs in a JVM implementation.

@ -124,11 +124,13 @@ public final class MethodHandleFactory {
* @return return value unmodified
*/
static Object traceReturn(final DebugLogger logger, final Object value) {
final String str = " return" +
(VOID_TAG.equals(value) ?
";" :
" " + stripName(value) + "; // [type=" + (value == null ? "null]" : stripName(value.getClass()) + ']'));
logger.log(TRACE_LEVEL, str);
if (logger.isEnabled()) {
final String str = " return" +
(VOID_TAG.equals(value) ?
";" :
" " + stripName(value) + "; // [type=" + (value == null ? "null]" : stripName(value.getClass()) + ']'));
logger.log(TRACE_LEVEL, str);
}
return value;
}

@ -46,8 +46,10 @@ import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicReference;
import javax.script.ScriptContext;
import javax.script.ScriptEngine;
import jdk.internal.dynalink.linker.GuardedInvocation;
import jdk.internal.dynalink.linker.LinkRequest;
import jdk.nashorn.api.scripting.ScriptObjectMirror;
@ -563,6 +565,8 @@ public final class Global extends ScriptObject implements Scope {
* Initialize standard builtin objects like "Object", "Array", "Function" etc.
* as well as our extension builtin objects like "Java", "JSAdapter" as properties
* of the global scope object.
*
* @param engine ScriptEngine to initialize
*/
public void initBuiltinObjects(final ScriptEngine engine) {
if (this.builtinObject != null) {
@ -1936,15 +1940,16 @@ public final class Global extends ScriptObject implements Scope {
}
private Object printImpl(final boolean newLine, final Object... objects) {
@SuppressWarnings("resource")
final PrintWriter out = scontext != null? new PrintWriter(scontext.getWriter()) : getContext().getEnv().getOut();
final StringBuilder sb = new StringBuilder();
for (final Object object : objects) {
for (final Object obj : objects) {
if (sb.length() != 0) {
sb.append(' ');
}
sb.append(JSType.toString(object));
sb.append(JSType.toString(obj));
}
// Print all at once to ensure thread friendly result.

@ -935,7 +935,6 @@ public final class NativeDate extends ScriptObject {
}
sb.append(' ');
//$FALL-THROUGH$
case FORMAT_TIME:
final TimeZone tz = nd.getTimeZone();
final double utcTime = nd.getTime();

@ -39,6 +39,7 @@ import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.Callable;
import jdk.internal.dynalink.beans.BeansLinker;
import jdk.internal.dynalink.beans.StaticClass;
import jdk.internal.dynalink.linker.GuardedInvocation;
@ -716,7 +717,7 @@ public final class NativeObject {
return target;
}
/*
/**
* Binds the source mirror object's properties to the target object. Binding
* properties allows two-way read/write for the properties of the source object.
* All inherited, enumerable properties are also bound. This method is used to
@ -731,7 +732,7 @@ public final class NativeObject {
// make accessor properties using dynamic invoker getters and setters
final AccessorProperty[] props = new AccessorProperty[keys.size()];
int idx = 0;
for (String name : keys) {
for (final String name : keys) {
final MethodHandle getter = Bootstrap.createDynamicInvoker("dyn:getMethod|getProp|getElem:" + name, MIRROR_GETTER_TYPE);
final MethodHandle setter = Bootstrap.createDynamicInvoker("dyn:setProp|setElem:" + name, MIRROR_SETTER_TYPE);
props[idx] = AccessorProperty.create(name, 0, getter, setter);

@ -28,7 +28,7 @@ package jdk.nashorn.internal.runtime;
import java.text.MessageFormat;
import java.util.Locale;
import java.util.ResourceBundle;
import jdk.nashorn.api.scripting.NashornException;
import jdk.nashorn.internal.codegen.CompilerConstants;
import jdk.nashorn.internal.objects.Global;
import jdk.nashorn.internal.scripts.JS;

@ -36,6 +36,7 @@ import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import jdk.internal.dynalink.support.NameCodec;
import jdk.nashorn.internal.codegen.CompileUnit;
import jdk.nashorn.internal.codegen.Compiler;
@ -236,14 +237,14 @@ public final class RecompilableScriptFunctionData extends ScriptFunctionData imp
/**
* Initialize transient fields on deserialized instances
*
* @param source source
* @param installer code installer
* @param src source
* @param inst code installer
*/
public void initTransients(final Source source, final CodeInstaller<ScriptEnvironment> installer) {
public void initTransients(final Source src, final CodeInstaller<ScriptEnvironment> inst) {
if (this.source == null && this.installer == null) {
this.source = source;
this.installer = installer;
} else if (this.source != source || this.installer != installer) {
this.source = src;
this.installer = inst;
} else if (this.source != src || this.installer != inst) {
// Existing values must be same as those passed as parameters
throw new IllegalArgumentException();
}

@ -3626,7 +3626,6 @@ public abstract class ScriptObject implements PropertyAccess {
return MH.insertArguments(KNOWNFUNCPROPGUARDPROTO, 1, map, getter, depth, func);
}
@SuppressWarnings("unused")
private static ScriptObject getProto(final ScriptObject self, final int depth) {
ScriptObject proto = self;
for (int d = 0; d < depth; d++) {

@ -484,17 +484,16 @@ public final class ScriptRuntime {
final Object unwrapped = ScriptObjectMirror.unwrap(expression, global);
if (unwrapped instanceof ScriptObject) {
return new WithObject(scope, (ScriptObject)unwrapped);
} else {
// foreign ScriptObjectMirror
ScriptObject exprObj = global.newObject();
NativeObject.bindAllProperties(exprObj, (ScriptObjectMirror)expression);
return new WithObject(scope, exprObj);
}
} else {
final Object wrappedExpr = JSType.toScriptObject(global, expression);
if (wrappedExpr instanceof ScriptObject) {
return new WithObject(scope, (ScriptObject)wrappedExpr);
}
// foreign ScriptObjectMirror
final ScriptObject exprObj = global.newObject();
NativeObject.bindAllProperties(exprObj, (ScriptObjectMirror)expression);
return new WithObject(scope, exprObj);
}
final Object wrappedExpr = JSType.toScriptObject(global, expression);
if (wrappedExpr instanceof ScriptObject) {
return new WithObject(scope, (ScriptObject)wrappedExpr);
}
throw typeError(global, "cant.apply.with.to.non.scriptobject");

@ -31,12 +31,13 @@ import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
import java.lang.invoke.SwitchPoint;
import jdk.nashorn.api.scripting.AbstractJSObject;
import jdk.nashorn.api.scripting.ScriptObjectMirror;
import jdk.internal.dynalink.CallSiteDescriptor;
import jdk.internal.dynalink.linker.GuardedInvocation;
import jdk.internal.dynalink.linker.LinkRequest;
import jdk.internal.dynalink.support.CallSiteDescriptorFactory;
import jdk.nashorn.api.scripting.AbstractJSObject;
import jdk.nashorn.api.scripting.ScriptObjectMirror;
import jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor;
import jdk.nashorn.internal.runtime.linker.NashornGuards;
@ -322,6 +323,7 @@ public final class WithObject extends ScriptObject implements Scope {
// We need to make sure correct 'this' is used for calls with Ident call
// expressions. We do so here using an AbstractJSObject instance.
return new AbstractJSObject() {
@Override
public Object call(final Object thiz, final Object... args) {
return mirror.call(withFilterExpression(receiver), args);
}

@ -0,0 +1,41 @@
/*
* 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.
*/
/**
* Make sure that we run with the class cache off to so that every
* run produces compile time and with optimistic type info caching
* and persistent code store off, for the same reasons. These last two
* are currently default, but this is not guaranteed to be the case
* forever, so make this test future safe, we specify them explicitly
*
* @test
* @runif external.octane
* @option -scripting
* @option -Dnashorn.typeInfo.disabled=true
* @option --class-cache-size=0
* @option --persistent-code-cache=false
*/
var fn = __DIR__ + 'compile-octane.js';
var url = "file://" + fn;
loadWithNewGlobal(new java.net.URL(url));

@ -0,0 +1,30 @@
Compiling 'box2d'...
Done.
Compiling 'code-load'...
Done.
Compiling 'crypto'...
Done.
Compiling 'deltablue'...
Done.
Compiling 'earley-boyer'...
Done.
Compiling 'gbemu'... (2 files)
Done.
Compiling 'mandreel'...
Done.
Compiling 'navier-stokes'...
Done.
Compiling 'pdfjs'...
Done.
Compiling 'raytrace'...
Done.
Compiling 'regexp'...
Done.
Compiling 'richards'...
Done.
Compiling 'splay'...
Done.
Compiling 'typescript'... (3 files)
Done.
Compiling 'zlib'... (2 files)
Done.

@ -22,12 +22,22 @@
*/
/**
* Make sure that we run with the class cache off to so that every
* run produces compile time and with optimistic type info caching
* and persistent code store off, for the same reasons. These last two
* are currently default, but this is not guaranteed to be the case
* forever, so make this test future safe, we specify them explicitly
*
* @test
* @option -Dnashorn.compiler.splitter.threshold=1000
* @fork
* @runif external.octane
* @option -scripting
* @option -Dnashorn.typeInfo.disabled=true
* @option --class-cache-size=0
* @option --persistent-code-cache=false
*/
compile_only = true;
load(__DIR__ + 'run-octane.js');
var fn = __DIR__ + 'compile-octane.js';
var url = "file://" + fn;
loadWithNewGlobal(new java.net.URL(url));

@ -1,15 +1,30 @@
[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
[zlib] Compiled OK
Compiling 'box2d'...
Done.
Compiling 'code-load'...
Done.
Compiling 'crypto'...
Done.
Compiling 'deltablue'...
Done.
Compiling 'earley-boyer'...
Done.
Compiling 'gbemu'... (2 files)
Done.
Compiling 'mandreel'...
Done.
Compiling 'navier-stokes'...
Done.
Compiling 'pdfjs'...
Done.
Compiling 'raytrace'...
Done.
Compiling 'regexp'...
Done.
Compiling 'richards'...
Done.
Compiling 'splay'...
Done.
Compiling 'typescript'... (3 files)
Done.
Compiling 'zlib'... (2 files)
Done.

@ -22,10 +22,122 @@
*/
/**
* @test
* @runif external.octane
* @option -scripting
* Make sure that we run with the class cache off to so that every
* run produces compile time and with optimistic type info caching
* and persistent code store off, for the same reasons. These last two
* are currently default, but this is not guaranteed to be the case
* forever, so make this test future safe, we specify them explicitly
*
* This means that if you use this subtest as a compilation test
* harness, pass the arguments:
*
* -scripting -Dnashorn.typeInfo.disabled=true --class-cache-size=0
* --persistent-code-cache=false
*
* @subtest
*/
compile_only = true;
load(__DIR__ + 'run-octane.js');
load(__DIR__ + 'octane-payload.js');
var DEFAULT_ITERS = 1; //default is one iteration through each benchmark
var iters = DEFAULT_ITERS;
var args = [];
if (typeof $ARGS !== 'undefined') {
args = $ARGS;
} else if (typeof arguments !== 'undefined' && arguments.length != 0) {
args = arguments;
}
var onlyTheseTests = [];
var verbose = false;
for (var i = 0; i < args.length; ) {
var arg = args[i];
if (arg === '--iterations') {
iters = +args[++i];
} else if (arg === '--verbose') {
verbose = true;
} else {
onlyTheseTests.push(arg);
}
i++;
}
if (isNaN(iters)) {
iters = DEFAULT_ITERS;
}
if (iters != DEFAULT_ITERS) {
print("Running " + iters + " iterations of each compilation.");
}
function print_if_verbose(x) {
if (verbose) {
print(x);
}
}
function contains(a, obj) {
for (var i = 0; i < a.length; i++) {
if (a[i] === obj) {
return true;
}
}
return false;
}
var testsCompiled = [];
for (var j in tests) {
var test_name = tests[j].name;
var files = tests[j].files;
if (onlyTheseTests.length > 0 && !contains(onlyTheseTests, test_name)) {
print_if_verbose("Skipping " + test_name);
continue;
}
if (!contains(testsCompiled, test_name)) {
testsCompiled.push(test_name);
}
var str = "Compiling '" + test_name + "'...";
if (files.length > 1) {
str += " (" + files.length + " files)";
}
if (iters != 1) {
str += " (" + iters + " times)";
}
str + "...";
print(str);
for (var iteration = 0; iteration < iters; iteration++) {
//get a new global to avoid symbol pollution and reloads of base
//in the same namespace
var newGlobal = loadWithNewGlobal({script:'this', name:'test'});
//load base into the new global so we get BenchmarkSuite etc
newGlobal.load(base);
//load all files in the single benchmark
for (var k in files) {
var file = files[k];
if (iteration >= 0) { //only display message on first iteration
var str2 = "\t";
if (iters > 1) {
str2 += " [iteration " + (iteration + 1) + "]";
}
str2 += " processing file: " + file + "...";
print_if_verbose(str2);
}
newGlobal.load("file://" + path + file);
}
}
print("Done.");
}
if (testsCompiled.length == 0) {
print("Error: no tests given to compile");
}

@ -1,15 +0,0 @@
[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
[zlib] Compiled OK

@ -0,0 +1,58 @@
/*
* Copyright (c) 2010, 2014, 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.
*/
/**
* @subtest
*/
function initZlib() {
zlib = new BenchmarkSuite('zlib', [152815148], [
new Benchmark('zlib', false, true, 10,
runZlib, undefined, tearDownZlib, null, 3)]);
}
var tests = [
{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", before:initZlib}
];
var dir = (typeof(__DIR__) == 'undefined') ? "test/script/basic/" : __DIR__;
// TODO: why is this path hard coded when it's defined in project properties?
var path = dir + "../external/octane/";
var base = path + "base.js";

@ -24,36 +24,8 @@
/**
* @subtest
*/
function initZlib() {
zlib = new BenchmarkSuite('zlib', [152815148], [
new Benchmark('zlib', false, true, 10,
runZlib, undefined, tearDownZlib, null, 3)]);
}
var tests = [
{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", before:initZlib}
];
var dir = (typeof(__DIR__) == 'undefined') ? "test/script/basic/" : __DIR__;
// TODO: why is this path hard coded when it's defined in project properties?
var path = dir + "../external/octane/";
var payload = __DIR__ + "octane-payload.js";
load(payload);
var runtime = undefined;
var verbose = false;