8014329: Slim down the label stack structure in CodeGenerator
Reviewed-by: attila, jlaskey
This commit is contained in:
parent
52d2511fed
commit
1fbc1cbc43
@ -8,6 +8,7 @@ private.xml
|
||||
private.properties
|
||||
webrev/*
|
||||
webrev.zip
|
||||
.classpath
|
||||
*.class
|
||||
*.clazz
|
||||
*.log
|
||||
|
@ -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));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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";
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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(' ');
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user