8014329: Slim down the label stack structure in CodeGenerator

Fri, 10 May 2013 13:16:44 +0200

author
lagergren
date
Fri, 10 May 2013 13:16:44 +0200
changeset 256
9073bcc4307b
parent 255
18ce1cd3026c
child 257
098a4cedcaf2

8014329: Slim down the label stack structure in CodeGenerator
Reviewed-by: attila, jlaskey

.hgignore file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/codegen/Attr.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/codegen/Compiler.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/codegen/Label.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/codegen/MethodEmitter.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/ir/BlockLexicalContext.java file | annotate | diff | comparison | revisions
     1.1 --- a/.hgignore	Wed May 08 16:48:33 2013 +0200
     1.2 +++ b/.hgignore	Fri May 10 13:16:44 2013 +0200
     1.3 @@ -8,6 +8,7 @@
     1.4  private.properties
     1.5  webrev/*
     1.6  webrev.zip
     1.7 +.classpath
     1.8  *.class
     1.9  *.clazz
    1.10  *.log
     2.1 --- a/src/jdk/nashorn/internal/codegen/Attr.java	Wed May 08 16:48:33 2013 +0200
     2.2 +++ b/src/jdk/nashorn/internal/codegen/Attr.java	Fri May 10 13:16:44 2013 +0200
     2.3 @@ -539,9 +539,7 @@
     2.4          }
     2.5          addLocalUse(identNode.getName());
     2.6  
     2.7 -        end(identNode);
     2.8 -
     2.9 -        return identNode.setSymbol(lc, symbol);
    2.10 +        return end(identNode.setSymbol(lc, symbol));
    2.11      }
    2.12  
    2.13      /**
     3.1 --- a/src/jdk/nashorn/internal/codegen/Compiler.java	Wed May 08 16:48:33 2013 +0200
     3.2 +++ b/src/jdk/nashorn/internal/codegen/Compiler.java	Fri May 10 13:16:44 2013 +0200
     3.3 @@ -298,6 +298,8 @@
     3.4      }
     3.5  
     3.6      private static void printMemoryUsage(final String phaseName, final FunctionNode functionNode) {
     3.7 +        LOG.info(phaseName + " finished. Doing IR size calculation...");
     3.8 +
     3.9          final ObjectSizeCalculator osc = new ObjectSizeCalculator(ObjectSizeCalculator.getEffectiveMemoryLayoutSpecification());
    3.10          osc.calculateObjectSize(functionNode);
    3.11  
    3.12 @@ -324,7 +326,7 @@
    3.13          for (final ClassHistogramElement e : list) {
    3.14              final String line = String.format("    %-48s %10d bytes (%8d instances)", e.getClazz(), e.getBytes(), e.getInstances());
    3.15              LOG.info(line);
    3.16 -            if (e.getBytes() < totalSize / 20) {
    3.17 +            if (e.getBytes() < totalSize / 200) {
    3.18                  LOG.info("    ...");
    3.19                  break; // never mind, so little memory anyway
    3.20              }
    3.21 @@ -619,6 +621,4 @@
    3.22          USE_INT_ARITH  =  Options.getBooleanProperty("nashorn.compiler.intarithmetic");
    3.23          assert !USE_INT_ARITH : "Integer arithmetic is not enabled";
    3.24      }
    3.25 -
    3.26 -
    3.27  }
     4.1 --- a/src/jdk/nashorn/internal/codegen/Label.java	Wed May 08 16:48:33 2013 +0200
     4.2 +++ b/src/jdk/nashorn/internal/codegen/Label.java	Fri May 10 13:16:44 2013 +0200
     4.3 @@ -24,8 +24,6 @@
     4.4   */
     4.5  package jdk.nashorn.internal.codegen;
     4.6  
     4.7 -import java.util.ArrayDeque;
     4.8 -
     4.9  import jdk.nashorn.internal.codegen.types.Type;
    4.10  import jdk.nashorn.internal.runtime.Debug;
    4.11  
    4.12 @@ -37,11 +35,83 @@
    4.13   * see -Dnashorn.codegen.debug, --log=codegen
    4.14   */
    4.15  public final class Label {
    4.16 +    //byte code generation evaluation type stack for consistency check
    4.17 +    //and correct opcode selection. one per label as a label may be a
    4.18 +    //join point
    4.19 +    static final class Stack {
    4.20 +        Type[] data = new Type[8];
    4.21 +        int sp = 0;
    4.22 +
    4.23 +        Stack() {
    4.24 +        }
    4.25 +
    4.26 +        private Stack(final Type[] type, final int sp) {
    4.27 +            this();
    4.28 +            this.data = new Type[type.length];
    4.29 +            this.sp   = sp;
    4.30 +            for (int i = 0; i < sp; i++) {
    4.31 +                data[i] = type[i];
    4.32 +            }
    4.33 +        }
    4.34 +
    4.35 +        boolean isEmpty() {
    4.36 +            return sp == 0;
    4.37 +        }
    4.38 +
    4.39 +        int size() {
    4.40 +            return sp;
    4.41 +        }
    4.42 +
    4.43 +        boolean isEquivalentTo(final Stack other) {
    4.44 +            if (sp != other.sp) {
    4.45 +                return false;
    4.46 +            }
    4.47 +            for (int i = 0; i < sp; i++) {
    4.48 +                if (!data[i].isEquivalentTo(other.data[i])) {
    4.49 +                    return false;
    4.50 +                }
    4.51 +            }
    4.52 +            return true;
    4.53 +        }
    4.54 +
    4.55 +        void clear() {
    4.56 +            sp = 0;
    4.57 +        }
    4.58 +
    4.59 +        void push(final Type type) {
    4.60 +            if (data.length == sp) {
    4.61 +                final Type[] newData = new Type[sp * 2];
    4.62 +                for (int i = 0; i < sp; i++) {
    4.63 +                    newData[i] = data[i];
    4.64 +                }
    4.65 +                data = newData;
    4.66 +            }
    4.67 +            data[sp++] = type;
    4.68 +        }
    4.69 +
    4.70 +        Type peek() {
    4.71 +            return peek(0);
    4.72 +        }
    4.73 +
    4.74 +        Type peek(final int n) {
    4.75 +            int pos = sp - 1 - n;
    4.76 +            return pos < 0 ? null : data[pos];
    4.77 +        }
    4.78 +
    4.79 +        Type pop() {
    4.80 +            return data[--sp];
    4.81 +        }
    4.82 +
    4.83 +        Stack copy() {
    4.84 +            return new Stack(data, sp);
    4.85 +        }
    4.86 +    }
    4.87 +
    4.88      /** Name of this label */
    4.89      private final String name;
    4.90  
    4.91      /** Type stack at this label */
    4.92 -    private ArrayDeque<Type> stack;
    4.93 +    private Label.Stack stack;
    4.94  
    4.95      /** ASM representation of this label */
    4.96      private jdk.internal.org.objectweb.asm.Label label;
    4.97 @@ -74,11 +144,11 @@
    4.98          return label;
    4.99      }
   4.100  
   4.101 -    ArrayDeque<Type> getStack() {
   4.102 +    Label.Stack getStack() {
   4.103          return stack;
   4.104      }
   4.105  
   4.106 -    void setStack(final ArrayDeque<Type> stack) {
   4.107 +    void setStack(final Label.Stack stack) {
   4.108          this.stack = stack;
   4.109      }
   4.110  
   4.111 @@ -87,4 +157,3 @@
   4.112          return name + '_' + Debug.id(this);
   4.113      }
   4.114  }
   4.115 -
     5.1 --- a/src/jdk/nashorn/internal/codegen/MethodEmitter.java	Wed May 08 16:48:33 2013 +0200
     5.2 +++ b/src/jdk/nashorn/internal/codegen/MethodEmitter.java	Fri May 10 13:16:44 2013 +0200
     5.3 @@ -67,9 +67,7 @@
     5.4  
     5.5  import java.io.PrintStream;
     5.6  import java.lang.reflect.Array;
     5.7 -import java.util.ArrayDeque;
     5.8  import java.util.EnumSet;
     5.9 -import java.util.Iterator;
    5.10  import java.util.List;
    5.11  
    5.12  import jdk.internal.dynalink.support.NameCodec;
    5.13 @@ -115,7 +113,7 @@
    5.14      private final MethodVisitor method;
    5.15  
    5.16      /** Current type stack for current evaluation */
    5.17 -    private ArrayDeque<Type> stack;
    5.18 +    private Label.Stack stack;
    5.19  
    5.20      /** Parent classEmitter representing the class of this method */
    5.21      private final ClassEmitter classEmitter;
    5.22 @@ -207,7 +205,7 @@
    5.23      }
    5.24  
    5.25      private void newStack() {
    5.26 -        stack = new ArrayDeque<>();
    5.27 +        stack = new Label.Stack();
    5.28      }
    5.29  
    5.30      @Override
    5.31 @@ -293,11 +291,7 @@
    5.32       * @return the type at position "pos" on the stack
    5.33       */
    5.34      final Type peekType(final int pos) {
    5.35 -        final Iterator<Type> iter = stack.iterator();
    5.36 -        for (int i = 0; i < pos; i++) {
    5.37 -            iter.next();
    5.38 -        }
    5.39 -        return iter.next();
    5.40 +        return stack.peek(pos);
    5.41      }
    5.42  
    5.43      /**
    5.44 @@ -865,7 +859,7 @@
    5.45      }
    5.46  
    5.47      private boolean isThisSlot(final int slot) {
    5.48 -        if(functionNode == null) {
    5.49 +        if (functionNode == null) {
    5.50              return slot == CompilerConstants.JAVA_THIS.slot();
    5.51          }
    5.52          final int thisSlot = compilerConstant(THIS).getSlot();
    5.53 @@ -909,7 +903,6 @@
    5.54              dup();
    5.55              return this;
    5.56          }
    5.57 -        debug("load compiler constant ", symbol);
    5.58          return load(symbol);
    5.59      }
    5.60  
    5.61 @@ -1502,24 +1495,6 @@
    5.62       *
    5.63       * @return true if stacks are equivalent, false otherwise
    5.64       */
    5.65 -    private boolean stacksEquivalent(final ArrayDeque<Type> s0, final ArrayDeque<Type> s1) {
    5.66 -        if (s0.size() != s1.size()) {
    5.67 -            debug("different stack sizes", s0, s1);
    5.68 -            return false;
    5.69 -        }
    5.70 -
    5.71 -        final Type[] s0a = s0.toArray(new Type[s0.size()]);
    5.72 -        final Type[] s1a = s1.toArray(new Type[s1.size()]);
    5.73 -        for (int i = 0; i < s0.size(); i++) {
    5.74 -            if (!s0a[i].isEquivalentTo(s1a[i])) {
    5.75 -                debug("different stack element", s0a[i], s1a[i]);
    5.76 -                return false;
    5.77 -            }
    5.78 -        }
    5.79 -
    5.80 -        return true;
    5.81 -    }
    5.82 -
    5.83      /**
    5.84       * A join in control flow - helper function that makes sure all entry stacks
    5.85       * discovered for the join point so far are equivalent
    5.86 @@ -1539,12 +1514,12 @@
    5.87          //ATHROW sequences instead of no code being generated at all. This should now be fixed.
    5.88          assert stack != null : label + " entered with no stack. deadcode that remains?";
    5.89  
    5.90 -        final ArrayDeque<Type> labelStack = label.getStack();
    5.91 +        final Label.Stack labelStack = label.getStack();
    5.92          if (labelStack == null) {
    5.93 -            label.setStack(stack.clone());
    5.94 +            label.setStack(stack.copy());
    5.95              return;
    5.96          }
    5.97 -        assert stacksEquivalent(stack, labelStack) : "stacks " + stack + " is not equivalent with " + labelStack + " at join point";
    5.98 +        assert stack.isEquivalentTo(labelStack) : "stacks " + stack + " is not equivalent with " + labelStack + " at join point";
    5.99      }
   5.100  
   5.101      /**
   5.102 @@ -1688,11 +1663,10 @@
   5.103       * @return array of Types
   5.104       */
   5.105      protected Type[] getTypesFromStack(final int count) {
   5.106 -        final Iterator<Type> iter  = stack.iterator();
   5.107 -        final Type[]         types = new Type[count];
   5.108 -
   5.109 +        final Type[] types = new Type[count];
   5.110 +        int pos = 0;
   5.111          for (int i = count - 1; i >= 0; i--) {
   5.112 -            types[i] = iter.next();
   5.113 +            types[i] = stack.peek(pos++);
   5.114          }
   5.115  
   5.116          return types;
   5.117 @@ -1708,11 +1682,11 @@
   5.118       * @return function signature for stack contents
   5.119       */
   5.120      private String getDynamicSignature(final Type returnType, final int argCount) {
   5.121 -        final Iterator<Type> iter       = stack.iterator();
   5.122          final Type[]         paramTypes = new Type[argCount];
   5.123  
   5.124 +        int pos = 0;
   5.125          for (int i = argCount - 1; i >= 0; i--) {
   5.126 -            paramTypes[i] = iter.next();
   5.127 +            paramTypes[i] = stack.peek(pos++);
   5.128          }
   5.129          final String descriptor = Type.getMethodDescriptor(returnType, paramTypes);
   5.130          for (int i = 0; i < argCount; i++) {
   5.131 @@ -2138,8 +2112,8 @@
   5.132                  sb.append("{");
   5.133                  sb.append(stack.size());
   5.134                  sb.append(":");
   5.135 -                for (final Iterator<Type> iter = stack.iterator(); iter.hasNext();) {
   5.136 -                    final Type t = iter.next();
   5.137 +                for (int pos = 0; pos < stack.size(); pos++) {
   5.138 +                    final Type t = stack.peek(pos);
   5.139  
   5.140                      if (t == Type.SCOPE) {
   5.141                          sb.append("scope");
   5.142 @@ -2165,7 +2139,7 @@
   5.143                          sb.append(t.getDescriptor());
   5.144                      }
   5.145  
   5.146 -                    if (iter.hasNext()) {
   5.147 +                    if (pos + 1 < stack.size()) {
   5.148                          sb.append(' ');
   5.149                      }
   5.150                  }
     6.1 --- a/src/jdk/nashorn/internal/ir/BlockLexicalContext.java	Wed May 08 16:48:33 2013 +0200
     6.2 +++ b/src/jdk/nashorn/internal/ir/BlockLexicalContext.java	Fri May 10 13:16:44 2013 +0200
     6.3 @@ -63,6 +63,7 @@
     6.4          return sstack.pop();
     6.5      }
     6.6  
     6.7 +    @SuppressWarnings("unchecked")
     6.8      @Override
     6.9      public <T extends LexicalContextNode> T pop(final T node) {
    6.10          T expected = node;

mercurial