# HG changeset patch # User lagergren # Date 1368184604 -7200 # Node ID 6e45d9c2328cecb7cc252d6a17176f1e0f3f4500 # Parent 3194676cb5556e796f91e9ce124f0464b463bd3d 8014329: Slim down the label stack structure in CodeGenerator Reviewed-by: attila, jlaskey diff -r 3194676cb555 -r 6e45d9c2328c nashorn/.hgignore --- a/nashorn/.hgignore Wed May 08 16:48:33 2013 +0200 +++ b/nashorn/.hgignore Fri May 10 13:16:44 2013 +0200 @@ -8,6 +8,7 @@ private.properties webrev/* webrev.zip +.classpath *.class *.clazz *.log diff -r 3194676cb555 -r 6e45d9c2328c nashorn/src/jdk/nashorn/internal/codegen/Attr.java --- a/nashorn/src/jdk/nashorn/internal/codegen/Attr.java Wed May 08 16:48:33 2013 +0200 +++ b/nashorn/src/jdk/nashorn/internal/codegen/Attr.java Fri May 10 13:16:44 2013 +0200 @@ -539,9 +539,7 @@ } addLocalUse(identNode.getName()); - end(identNode); - - return identNode.setSymbol(lc, symbol); + return end(identNode.setSymbol(lc, symbol)); } /** diff -r 3194676cb555 -r 6e45d9c2328c nashorn/src/jdk/nashorn/internal/codegen/Compiler.java --- a/nashorn/src/jdk/nashorn/internal/codegen/Compiler.java Wed May 08 16:48:33 2013 +0200 +++ b/nashorn/src/jdk/nashorn/internal/codegen/Compiler.java Fri May 10 13:16:44 2013 +0200 @@ -298,6 +298,8 @@ } private static void printMemoryUsage(final String phaseName, final FunctionNode functionNode) { + LOG.info(phaseName + " finished. Doing IR size calculation..."); + final ObjectSizeCalculator osc = new ObjectSizeCalculator(ObjectSizeCalculator.getEffectiveMemoryLayoutSpecification()); osc.calculateObjectSize(functionNode); @@ -324,7 +326,7 @@ for (final ClassHistogramElement e : list) { final String line = String.format(" %-48s %10d bytes (%8d instances)", e.getClazz(), e.getBytes(), e.getInstances()); LOG.info(line); - if (e.getBytes() < totalSize / 20) { + if (e.getBytes() < totalSize / 200) { LOG.info(" ..."); break; // never mind, so little memory anyway } @@ -619,6 +621,4 @@ USE_INT_ARITH = Options.getBooleanProperty("nashorn.compiler.intarithmetic"); assert !USE_INT_ARITH : "Integer arithmetic is not enabled"; } - - } diff -r 3194676cb555 -r 6e45d9c2328c nashorn/src/jdk/nashorn/internal/codegen/Label.java --- a/nashorn/src/jdk/nashorn/internal/codegen/Label.java Wed May 08 16:48:33 2013 +0200 +++ b/nashorn/src/jdk/nashorn/internal/codegen/Label.java Fri May 10 13:16:44 2013 +0200 @@ -24,8 +24,6 @@ */ package jdk.nashorn.internal.codegen; -import java.util.ArrayDeque; - import jdk.nashorn.internal.codegen.types.Type; import jdk.nashorn.internal.runtime.Debug; @@ -37,11 +35,83 @@ * see -Dnashorn.codegen.debug, --log=codegen */ public final class Label { + //byte code generation evaluation type stack for consistency check + //and correct opcode selection. one per label as a label may be a + //join point + static final class Stack { + Type[] data = new Type[8]; + int sp = 0; + + Stack() { + } + + private Stack(final Type[] type, final int sp) { + this(); + this.data = new Type[type.length]; + this.sp = sp; + for (int i = 0; i < sp; i++) { + data[i] = type[i]; + } + } + + boolean isEmpty() { + return sp == 0; + } + + int size() { + return sp; + } + + boolean isEquivalentTo(final Stack other) { + if (sp != other.sp) { + return false; + } + for (int i = 0; i < sp; i++) { + if (!data[i].isEquivalentTo(other.data[i])) { + return false; + } + } + return true; + } + + void clear() { + sp = 0; + } + + void push(final Type type) { + if (data.length == sp) { + final Type[] newData = new Type[sp * 2]; + for (int i = 0; i < sp; i++) { + newData[i] = data[i]; + } + data = newData; + } + data[sp++] = type; + } + + Type peek() { + return peek(0); + } + + Type peek(final int n) { + int pos = sp - 1 - n; + return pos < 0 ? null : data[pos]; + } + + Type pop() { + return data[--sp]; + } + + Stack copy() { + return new Stack(data, sp); + } + } + /** Name of this label */ private final String name; /** Type stack at this label */ - private ArrayDeque<Type> stack; + private Label.Stack stack; /** ASM representation of this label */ private jdk.internal.org.objectweb.asm.Label label; @@ -74,11 +144,11 @@ return label; } - ArrayDeque<Type> getStack() { + Label.Stack getStack() { return stack; } - void setStack(final ArrayDeque<Type> stack) { + void setStack(final Label.Stack stack) { this.stack = stack; } @@ -87,4 +157,3 @@ return name + '_' + Debug.id(this); } } - diff -r 3194676cb555 -r 6e45d9c2328c nashorn/src/jdk/nashorn/internal/codegen/MethodEmitter.java --- a/nashorn/src/jdk/nashorn/internal/codegen/MethodEmitter.java Wed May 08 16:48:33 2013 +0200 +++ b/nashorn/src/jdk/nashorn/internal/codegen/MethodEmitter.java Fri May 10 13:16:44 2013 +0200 @@ -67,9 +67,7 @@ import java.io.PrintStream; import java.lang.reflect.Array; -import java.util.ArrayDeque; import java.util.EnumSet; -import java.util.Iterator; import java.util.List; import jdk.internal.dynalink.support.NameCodec; @@ -115,7 +113,7 @@ private final MethodVisitor method; /** Current type stack for current evaluation */ - private ArrayDeque<Type> stack; + private Label.Stack stack; /** Parent classEmitter representing the class of this method */ private final ClassEmitter classEmitter; @@ -207,7 +205,7 @@ } private void newStack() { - stack = new ArrayDeque<>(); + stack = new Label.Stack(); } @Override @@ -293,11 +291,7 @@ * @return the type at position "pos" on the stack */ final Type peekType(final int pos) { - final Iterator<Type> iter = stack.iterator(); - for (int i = 0; i < pos; i++) { - iter.next(); - } - return iter.next(); + return stack.peek(pos); } /** @@ -865,7 +859,7 @@ } private boolean isThisSlot(final int slot) { - if(functionNode == null) { + if (functionNode == null) { return slot == CompilerConstants.JAVA_THIS.slot(); } final int thisSlot = compilerConstant(THIS).getSlot(); @@ -909,7 +903,6 @@ dup(); return this; } - debug("load compiler constant ", symbol); return load(symbol); } @@ -1502,24 +1495,6 @@ * * @return true if stacks are equivalent, false otherwise */ - private boolean stacksEquivalent(final ArrayDeque<Type> s0, final ArrayDeque<Type> s1) { - if (s0.size() != s1.size()) { - debug("different stack sizes", s0, s1); - return false; - } - - final Type[] s0a = s0.toArray(new Type[s0.size()]); - final Type[] s1a = s1.toArray(new Type[s1.size()]); - for (int i = 0; i < s0.size(); i++) { - if (!s0a[i].isEquivalentTo(s1a[i])) { - debug("different stack element", s0a[i], s1a[i]); - return false; - } - } - - return true; - } - /** * A join in control flow - helper function that makes sure all entry stacks * discovered for the join point so far are equivalent @@ -1539,12 +1514,12 @@ //ATHROW sequences instead of no code being generated at all. This should now be fixed. assert stack != null : label + " entered with no stack. deadcode that remains?"; - final ArrayDeque<Type> labelStack = label.getStack(); + final Label.Stack labelStack = label.getStack(); if (labelStack == null) { - label.setStack(stack.clone()); + label.setStack(stack.copy()); return; } - assert stacksEquivalent(stack, labelStack) : "stacks " + stack + " is not equivalent with " + labelStack + " at join point"; + assert stack.isEquivalentTo(labelStack) : "stacks " + stack + " is not equivalent with " + labelStack + " at join point"; } /** @@ -1688,11 +1663,10 @@ * @return array of Types */ protected Type[] getTypesFromStack(final int count) { - final Iterator<Type> iter = stack.iterator(); - final Type[] types = new Type[count]; - + final Type[] types = new Type[count]; + int pos = 0; for (int i = count - 1; i >= 0; i--) { - types[i] = iter.next(); + types[i] = stack.peek(pos++); } return types; @@ -1708,11 +1682,11 @@ * @return function signature for stack contents */ private String getDynamicSignature(final Type returnType, final int argCount) { - final Iterator<Type> iter = stack.iterator(); final Type[] paramTypes = new Type[argCount]; + int pos = 0; for (int i = argCount - 1; i >= 0; i--) { - paramTypes[i] = iter.next(); + paramTypes[i] = stack.peek(pos++); } final String descriptor = Type.getMethodDescriptor(returnType, paramTypes); for (int i = 0; i < argCount; i++) { @@ -2138,8 +2112,8 @@ sb.append("{"); sb.append(stack.size()); sb.append(":"); - for (final Iterator<Type> iter = stack.iterator(); iter.hasNext();) { - final Type t = iter.next(); + for (int pos = 0; pos < stack.size(); pos++) { + final Type t = stack.peek(pos); if (t == Type.SCOPE) { sb.append("scope"); @@ -2165,7 +2139,7 @@ sb.append(t.getDescriptor()); } - if (iter.hasNext()) { + if (pos + 1 < stack.size()) { sb.append(' '); } } diff -r 3194676cb555 -r 6e45d9c2328c nashorn/src/jdk/nashorn/internal/ir/BlockLexicalContext.java --- a/nashorn/src/jdk/nashorn/internal/ir/BlockLexicalContext.java Wed May 08 16:48:33 2013 +0200 +++ b/nashorn/src/jdk/nashorn/internal/ir/BlockLexicalContext.java Fri May 10 13:16:44 2013 +0200 @@ -63,6 +63,7 @@ return sstack.pop(); } + @SuppressWarnings("unchecked") @Override public <T extends LexicalContextNode> T pop(final T node) { T expected = node;