8014329: Slim down the label stack structure in CodeGenerator
Reviewed-by: attila, jlaskey
--- 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
--- 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));
}
/**
--- 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";
}
-
-
}
--- 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);
}
}
-
--- 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(' ');
}
}
--- 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;