Mercurial > people > rkennke > jdk9-shenandoah-final > nashorn
changeset 942:0787fe044ee6
8048869: Reduce compile time by about 5% by removing the Class.casts from the AST nodes
Summary: 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
line wrap: on
line diff
--- a/src/jdk/internal/dynalink/support/CompositeTypeBasedGuardingDynamicLinker.java Tue Jul 22 11:55:03 2014 -0700 +++ b/src/jdk/internal/dynalink/support/CompositeTypeBasedGuardingDynamicLinker.java Tue Jul 29 14:21:45 2014 -0700 @@ -111,7 +111,7 @@ 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 @@ case 1: { list = new LinkedList<>(list); } - //$FALL-THROUGH$ default: { list.add(linker); }
--- a/src/jdk/nashorn/api/scripting/NashornScriptEngine.java Tue Jul 22 11:55:03 2014 -0700 +++ b/src/jdk/nashorn/api/scripting/NashornScriptEngine.java Tue Jul 29 14:21:45 2014 -0700 @@ -40,6 +40,7 @@ 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.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 @@ 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 @@ } } - 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; }
--- a/src/jdk/nashorn/internal/codegen/CodeGenerator.java Tue Jul 22 11:55:03 2014 -0700 +++ b/src/jdk/nashorn/internal/codegen/CodeGenerator.java Tue Jul 29 14:21:45 2014 -0700 @@ -1097,7 +1097,11 @@ 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; }
--- a/src/jdk/nashorn/internal/codegen/CompilationPhase.java Tue Jul 22 11:55:03 2014 -0700 +++ b/src/jdk/nashorn/internal/codegen/CompilationPhase.java Tue Jul 29 14:21:45 2014 -0700 @@ -43,7 +43,6 @@ 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 @@ 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 @@ append(compiler.getCompileUnits().size()). append(" compile unit(s)]"); - log.info(sb.toString()); + log.fine(sb.toString()); } return setStates(fn.setRootClass(null, rootClass), BYTECODE_INSTALLED);
--- a/src/jdk/nashorn/internal/codegen/Compiler.java Tue Jul 22 11:55:03 2014 -0700 +++ b/src/jdk/nashorn/internal/codegen/Compiler.java Tue Jul 29 14:21:45 2014 -0700 @@ -50,6 +50,7 @@ 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 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 @@ time += (env.isTimingEnabled() ? phase.getEndTime() - phase.getStartTime() : 0L); } - if(typeInformationFile != null && !phases.isRestOfCompilation()) { + if (typeInformationFile != null && !phases.isRestOfCompilation()) { OptimisticTypesPersistence.store(typeInformationFile, invalidatedProgramPoints); }
--- a/src/jdk/nashorn/internal/codegen/Lower.java Tue Jul 22 11:55:03 2014 -0700 +++ b/src/jdk/nashorn/internal/codegen/Lower.java Tue Jul 29 14:21:45 2014 -0700 @@ -34,6 +34,7 @@ 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;
--- a/src/jdk/nashorn/internal/codegen/OptimisticTypesPersistence.java Tue Jul 22 11:55:03 2014 -0700 +++ b/src/jdk/nashorn/internal/codegen/OptimisticTypesPersistence.java Tue Jul 29 14:21:45 2014 -0700 @@ -41,6 +41,7 @@ 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 @@ return; } final File file = ((LocationDescriptor)locationDescriptor).file; + AccessController.doPrivileged(new PrivilegedAction<Void>() { @Override public Void run() { @@ -119,7 +121,7 @@ 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 @@ 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 @@ 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 @@ 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) {
--- a/src/jdk/nashorn/internal/ir/Block.java Tue Jul 22 11:55:03 2014 -0700 +++ b/src/jdk/nashorn/internal/ir/Block.java Tue Jul 29 14:21:45 2014 -0700 @@ -149,7 +149,7 @@ @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;
--- a/src/jdk/nashorn/internal/ir/CallNode.java Tue Jul 22 11:55:03 2014 -0700 +++ b/src/jdk/nashorn/internal/ir/CallNode.java Tue Jul 29 14:21:45 2014 -0700 @@ -30,6 +30,7 @@ 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 @@ 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) {
--- a/src/jdk/nashorn/internal/ir/FunctionNode.java Tue Jul 22 11:55:03 2014 -0700 +++ b/src/jdk/nashorn/internal/ir/FunctionNode.java Tue Jul 29 14:21:45 2014 -0700 @@ -359,7 +359,7 @@ * @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); } /**
--- a/src/jdk/nashorn/internal/ir/LexicalContext.java Tue Jul 22 11:55:03 2014 -0700 +++ b/src/jdk/nashorn/internal/ir/LexicalContext.java Tue Jul 29 14:21:45 2014 -0700 @@ -27,6 +27,7 @@ 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 @@ return lnext; } + @SuppressWarnings("unchecked") private T findNext() { for (int i = index; i >= 0; i--) { final Object node = stack[i]; @@ -660,7 +662,7 @@ } if (clazz.isAssignableFrom(node.getClass())) { index = i - 1; - return clazz.cast(node); + return (T)node; } } return null;
--- a/src/jdk/nashorn/internal/ir/LiteralNode.java Tue Jul 22 11:55:03 2014 -0700 +++ b/src/jdk/nashorn/internal/ir/LiteralNode.java Tue Jul 29 14:21:45 2014 -0700 @@ -934,7 +934,7 @@ 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;
--- a/src/jdk/nashorn/internal/ir/Node.java Tue Jul 22 11:55:03 2014 -0700 +++ b/src/jdk/nashorn/internal/ir/Node.java Tue Jul 29 14:21:45 2014 -0700 @@ -27,6 +27,7 @@ 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 @@ } //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) {
--- a/src/jdk/nashorn/internal/ir/ObjectNode.java Tue Jul 22 11:55:03 2014 -0700 +++ b/src/jdk/nashorn/internal/ir/ObjectNode.java Tue Jul 29 14:21:45 2014 -0700 @@ -61,7 +61,7 @@ @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;
--- a/src/jdk/nashorn/internal/ir/SwitchNode.java Tue Jul 22 11:55:03 2014 -0700 +++ b/src/jdk/nashorn/internal/ir/SwitchNode.java Tue Jul 29 14:21:45 2014 -0700 @@ -104,7 +104,7 @@ 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;
--- a/src/jdk/nashorn/internal/ir/TryNode.java Tue Jul 22 11:55:03 2014 -0700 +++ b/src/jdk/nashorn/internal/ir/TryNode.java Tue Jul 29 14:21:45 2014 -0700 @@ -112,7 +112,7 @@ return visitor.leaveTryNode( setBody(newBody). setFinallyBody(newFinallyBody). - setCatchBlocks(Node.accept(visitor, Block.class, catchBlocks)). + setCatchBlocks(Node.accept(visitor, catchBlocks)). setFinallyCatchAll(finallyCatchAll)); }
--- a/src/jdk/nashorn/internal/ir/debug/ClassHistogramElement.java Tue Jul 22 11:55:03 2014 -0700 +++ b/src/jdk/nashorn/internal/ir/debug/ClassHistogramElement.java Tue Jul 29 14:21:45 2014 -0700 @@ -30,7 +30,7 @@ /** * Class histogram element for IR / Java object instrumentation */ -public class ClassHistogramElement { +public final class ClassHistogramElement { /** * Instance comparator */
--- a/src/jdk/nashorn/internal/ir/debug/NashornTextifier.java Tue Jul 22 11:55:03 2014 -0700 +++ b/src/jdk/nashorn/internal/ir/debug/NashornTextifier.java Tue Jul 29 14:21:45 2014 -0700 @@ -39,6 +39,7 @@ 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 @@ 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");
--- a/src/jdk/nashorn/internal/ir/debug/ObjectSizeCalculator.java Tue Jul 22 11:55:03 2014 -0700 +++ b/src/jdk/nashorn/internal/ir/debug/ObjectSizeCalculator.java Tue Jul 29 14:21:45 2014 -0700 @@ -52,7 +52,7 @@ * 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.
--- a/src/jdk/nashorn/internal/lookup/MethodHandleFactory.java Tue Jul 22 11:55:03 2014 -0700 +++ b/src/jdk/nashorn/internal/lookup/MethodHandleFactory.java Tue Jul 29 14:21:45 2014 -0700 @@ -124,11 +124,13 @@ * @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; }
--- a/src/jdk/nashorn/internal/objects/Global.java Tue Jul 22 11:55:03 2014 -0700 +++ b/src/jdk/nashorn/internal/objects/Global.java Tue Jul 29 14:21:45 2014 -0700 @@ -46,8 +46,10 @@ 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 @@ * 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 @@ } 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.
--- a/src/jdk/nashorn/internal/objects/NativeDate.java Tue Jul 22 11:55:03 2014 -0700 +++ b/src/jdk/nashorn/internal/objects/NativeDate.java Tue Jul 29 14:21:45 2014 -0700 @@ -935,7 +935,6 @@ } sb.append(' '); - //$FALL-THROUGH$ case FORMAT_TIME: final TimeZone tz = nd.getTimeZone(); final double utcTime = nd.getTime();
--- a/src/jdk/nashorn/internal/objects/NativeObject.java Tue Jul 22 11:55:03 2014 -0700 +++ b/src/jdk/nashorn/internal/objects/NativeObject.java Tue Jul 29 14:21:45 2014 -0700 @@ -39,6 +39,7 @@ 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 @@ 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 @@ // 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);
--- a/src/jdk/nashorn/internal/runtime/ECMAErrors.java Tue Jul 22 11:55:03 2014 -0700 +++ b/src/jdk/nashorn/internal/runtime/ECMAErrors.java Tue Jul 29 14:21:45 2014 -0700 @@ -28,7 +28,7 @@ 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;
--- a/src/jdk/nashorn/internal/runtime/RecompilableScriptFunctionData.java Tue Jul 22 11:55:03 2014 -0700 +++ b/src/jdk/nashorn/internal/runtime/RecompilableScriptFunctionData.java Tue Jul 29 14:21:45 2014 -0700 @@ -36,6 +36,7 @@ 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 @@ /** * 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(); }
--- a/src/jdk/nashorn/internal/runtime/ScriptObject.java Tue Jul 22 11:55:03 2014 -0700 +++ b/src/jdk/nashorn/internal/runtime/ScriptObject.java Tue Jul 29 14:21:45 2014 -0700 @@ -3626,7 +3626,6 @@ 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++) {
--- a/src/jdk/nashorn/internal/runtime/ScriptRuntime.java Tue Jul 22 11:55:03 2014 -0700 +++ b/src/jdk/nashorn/internal/runtime/ScriptRuntime.java Tue Jul 29 14:21:45 2014 -0700 @@ -484,17 +484,16 @@ 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");
--- a/src/jdk/nashorn/internal/runtime/WithObject.java Tue Jul 22 11:55:03 2014 -0700 +++ b/src/jdk/nashorn/internal/runtime/WithObject.java Tue Jul 29 14:21:45 2014 -0700 @@ -31,12 +31,13 @@ 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 @@ // 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); }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/script/basic/compile-octane-normal.js Tue Jul 29 14:21:45 2014 -0700 @@ -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));
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/script/basic/compile-octane-normal.js.EXPECTED Tue Jul 29 14:21:45 2014 -0700 @@ -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.
--- a/test/script/basic/compile-octane-splitter.js Tue Jul 22 11:55:03 2014 -0700 +++ b/test/script/basic/compile-octane-splitter.js Tue Jul 29 14:21:45 2014 -0700 @@ -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));
--- a/test/script/basic/compile-octane-splitter.js.EXPECTED Tue Jul 22 11:55:03 2014 -0700 +++ b/test/script/basic/compile-octane-splitter.js.EXPECTED Tue Jul 29 14:21:45 2014 -0700 @@ -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.
--- a/test/script/basic/compile-octane.js Tue Jul 22 11:55:03 2014 -0700 +++ b/test/script/basic/compile-octane.js Tue Jul 29 14:21:45 2014 -0700 @@ -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"); +}
--- a/test/script/basic/compile-octane.js.EXPECTED Tue Jul 22 11:55:03 2014 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -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
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/script/basic/octane-payload.js Tue Jul 29 14:21:45 2014 -0700 @@ -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"; +
--- a/test/script/basic/run-octane.js Tue Jul 22 11:55:03 2014 -0700 +++ b/test/script/basic/run-octane.js Tue Jul 29 14:21:45 2014 -0700 @@ -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;