8014329: Slim down the label stack structure in CodeGenerator

Reviewed-by: attila, jlaskey
This commit is contained in:
Marcus Lagergren 2013-05-10 13:16:44 +02:00
parent 52d2511fed
commit 1fbc1cbc43
6 changed files with 96 additions and 53 deletions

View File

@ -8,6 +8,7 @@ private.xml
private.properties
webrev/*
webrev.zip
.classpath
*.class
*.clazz
*.log

View File

@ -539,9 +539,7 @@ final class Attr extends NodeOperatorVisitor {
}
addLocalUse(identNode.getName());
end(identNode);
return identNode.setSymbol(lc, symbol);
return end(identNode.setSymbol(lc, symbol));
}
/**

View File

@ -298,6 +298,8 @@ public final class Compiler {
}
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 @@ public final class Compiler {
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 @@ public final class Compiler {
USE_INT_ARITH = Options.getBooleanProperty("nashorn.compiler.intarithmetic");
assert !USE_INT_ARITH : "Integer arithmetic is not enabled";
}
}

View File

@ -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 @@ import jdk.nashorn.internal.runtime.Debug;
* 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 @@ public final class Label {
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 @@ public final class Label {
return name + '_' + Debug.id(this);
}
}

View File

@ -67,9 +67,7 @@ import static jdk.nashorn.internal.codegen.CompilerConstants.virtualCallNoLookup
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 @@ public class MethodEmitter implements Emitter {
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 @@ public class MethodEmitter implements Emitter {
}
private void newStack() {
stack = new ArrayDeque<>();
stack = new Label.Stack();
}
@Override
@ -293,11 +291,7 @@ public class MethodEmitter implements Emitter {
* @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 @@ public class MethodEmitter implements Emitter {
}
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 @@ public class MethodEmitter implements Emitter {
dup();
return this;
}
debug("load compiler constant ", symbol);
return load(symbol);
}
@ -1502,24 +1495,6 @@ public class MethodEmitter implements Emitter {
*
* @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 @@ public class MethodEmitter implements Emitter {
//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 @@ public class MethodEmitter implements Emitter {
* @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 @@ public class MethodEmitter implements Emitter {
* @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 @@ public class MethodEmitter implements Emitter {
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 @@ public class MethodEmitter implements Emitter {
sb.append(t.getDescriptor());
}
if (iter.hasNext()) {
if (pos + 1 < stack.size()) {
sb.append(' ');
}
}

View File

@ -63,6 +63,7 @@ public class BlockLexicalContext extends LexicalContext {
return sstack.pop();
}
@SuppressWarnings("unchecked")
@Override
public <T extends LexicalContextNode> T pop(final T node) {
T expected = node;