Instructions, that have separate class name and field/method name now

use FieldReference and MethodReference instead
This commit is contained in:
Alexey Andreev 2013-11-17 16:45:35 +04:00
parent 91a50605bc
commit 6efbb75783
15 changed files with 95 additions and 141 deletions

View File

@ -17,10 +17,7 @@ package org.teavm.dependency;
import java.util.Collection;
import java.util.HashSet;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.*;
import org.teavm.codegen.ConcurrentCachedMapper;
import org.teavm.codegen.ConcurrentCachedMapper.KeyListener;
import org.teavm.codegen.Mapper;
@ -48,6 +45,13 @@ public class DependencyChecker {
public DependencyChecker(ClassHolderSource classSource, int numThreads) {
this.classSource = classSource;
executor = new ScheduledThreadPoolExecutor(numThreads);
executor.setThreadFactory(new ThreadFactory() {
@Override public Thread newThread(Runnable r) {
Thread thread = new Thread(r);
thread.setDaemon(true);
return thread;
}
});
methodCache = new ConcurrentCachedMapper<>(new Mapper<MethodReference, MethodGraph>() {
@Override public MethodGraph map(MethodReference preimage) {
return createMethodGraph(preimage);

View File

@ -129,8 +129,7 @@ class DependencyGraphBuilder {
}
private void invokeSpecial(InvokeInstruction insn) {
MethodReference method = new MethodReference(insn.getClassName(), insn.getMethod());
MethodGraph targetGraph = dependencyChecker.attachMethodGraph(method);
MethodGraph targetGraph = dependencyChecker.attachMethodGraph(insn.getMethod());
DependencyNode[] targetParams = targetGraph.getVariableNodes();
List<Variable> arguments = insn.getArguments();
for (int i = 0; i < arguments.size(); ++i) {
@ -152,7 +151,7 @@ class DependencyGraphBuilder {
}
actualArgs[0] = nodes[insn.getInstance().getIndex()];
DependencyConsumer listener = new VirtualCallPropagationListener(nodes[insn.getInstance().getIndex()],
insn.getMethod(), dependencyChecker, actualArgs,
insn.getMethod().getDescriptor(), dependencyChecker, actualArgs,
insn.getReceiver() != null ? nodes[insn.getReceiver().getIndex()] : null);
nodes[insn.getInstance().getIndex()].addConsumer(listener);
}
@ -190,16 +189,14 @@ class DependencyGraphBuilder {
@Override
public void visit(PutFieldInstruction insn) {
DependencyNode fieldNode = dependencyChecker.getFieldNode(new FieldReference(insn.getClassName(),
insn.getField()));
DependencyNode fieldNode = dependencyChecker.getFieldNode(insn.getField());
DependencyNode valueNode = nodes[insn.getValue().getIndex()];
valueNode.connect(fieldNode);
}
@Override
public void visit(GetFieldInstruction insn) {
DependencyNode fieldNode = dependencyChecker.getFieldNode(new FieldReference(insn.getClassName(),
insn.getField()));
DependencyNode fieldNode = dependencyChecker.getFieldNode(insn.getField());
DependencyNode receiverNode = nodes[insn.getReceiver().getIndex()];
fieldNode.connect(receiverNode);
}

View File

@ -156,18 +156,16 @@ class OptimizingVisitor implements StatementVisitor, ExprVisitor {
}
switch (expr.getType()) {
case STATIC:
resultExpr = Expr.invokeStatic(expr.getClassName(), expr.getMethod(), args);
resultExpr = Expr.invokeStatic(expr.getMethod(), args);
break;
case DYNAMIC:
resultExpr = Expr.invoke(expr.getClassName(), expr.getMethod(), args[0], Arrays.copyOfRange(
args, 1, args.length));
resultExpr = Expr.invoke(expr.getMethod(), args[0], Arrays.copyOfRange(args, 1, args.length));
break;
case SPECIAL:
resultExpr = Expr.invokeSpecial(expr.getClassName(), expr.getMethod(), args[0], Arrays.copyOfRange(
args, 1, args.length));
resultExpr = Expr.invokeSpecial(expr.getMethod(), args[0], Arrays.copyOfRange(args, 1, args.length));
break;
case CONSTRUCTOR:
resultExpr = Expr.constructObject(expr.getClassName(), expr.getMethod(), args);
resultExpr = Expr.constructObject(expr.getMethod(), args);
break;
}
}
@ -199,12 +197,12 @@ class OptimizingVisitor implements StatementVisitor, ExprVisitor {
return false;
}
NewExpr constructed = (NewExpr)assignment.getRightValue();
if (!constructed.getConstructedClass().equals(expr.getClassName())) {
if (!constructed.getConstructedClass().equals(expr.getMethod().getClassName())) {
return false;
}
Expr[] args = expr.getArguments().toArray(new Expr[0]);
args = Arrays.copyOfRange(args, 1, args.length);
assignment.setRightValue(Expr.constructObject(expr.getClassName(), expr.getMethod(), args));
assignment.setRightValue(Expr.constructObject(expr.getMethod(), args));
stats.reads[var.getIndex()]--;
return true;
}
@ -213,7 +211,7 @@ class OptimizingVisitor implements StatementVisitor, ExprVisitor {
public void visit(QualificationExpr expr) {
expr.getQualified().acceptVisitor(this);
Expr qualified = resultExpr;
resultExpr = Expr.qualify(qualified, expr.getClassName(), expr.getField());
resultExpr = Expr.qualify(qualified, expr.getField());
}
@Override

View File

@ -689,8 +689,8 @@ public class Renderer implements ExprVisitor, StatementVisitor {
@Override
public void visit(InvocationExpr expr) {
String className = naming.getNameFor(expr.getClassName());
String name = naming.getNameFor(new MethodReference(expr.getClassName(), expr.getMethod()));
String className = naming.getNameFor(expr.getMethod().getClassName());
String name = naming.getNameFor(expr.getMethod());
switch (expr.getType()) {
case STATIC:
writer.append(className).append("_").append(name).append("(");
@ -738,7 +738,7 @@ public class Renderer implements ExprVisitor, StatementVisitor {
@Override
public void visit(QualificationExpr expr) {
expr.getQualified().acceptVisitor(this);
writer.append('.').appendField(new FieldReference(expr.getClassName(), expr.getField()));
writer.append('.').appendField(expr.getField());
}
@Override

View File

@ -412,10 +412,10 @@ public class StatementGenerator implements InstructionVisitor {
public void visit(GetFieldInstruction insn) {
if (insn.getInstance() != null) {
statements.add(Statement.assign(Expr.var(insn.getReceiver().getIndex()),
Expr.qualify(Expr.var(insn.getInstance().getIndex()), insn.getClassName(), insn.getField())));
Expr.qualify(Expr.var(insn.getInstance().getIndex()), insn.getField())));
} else {
Expr fieldExpr = Expr.qualify(Expr.staticClass(ValueType.object(insn.getClassName())),
insn.getClassName(), insn.getField());
Expr fieldExpr = Expr.qualify(Expr.staticClass(ValueType.object(insn.getField().getClassName())),
insn.getField());
statements.add(Statement.assign(Expr.var(insn.getReceiver().getIndex()), fieldExpr));
}
}
@ -423,11 +423,11 @@ public class StatementGenerator implements InstructionVisitor {
@Override
public void visit(PutFieldInstruction insn) {
if (insn.getInstance() != null) {
statements.add(Statement.assign(Expr.qualify(Expr.var(insn.getInstance().getIndex()),
insn.getClassName(), insn.getField()), Expr.var(insn.getValue().getIndex())));
statements.add(Statement.assign(Expr.qualify(Expr.var(insn.getInstance().getIndex()), insn.getField()),
Expr.var(insn.getValue().getIndex())));
} else {
Expr fieldExpr = Expr.qualify(Expr.staticClass(ValueType.object(insn.getClassName())),
insn.getClassName(), insn.getField());
Expr fieldExpr = Expr.qualify(Expr.staticClass(ValueType.object(insn.getField().getClassName())),
insn.getField());
statements.add(Statement.assign(fieldExpr, Expr.var(insn.getValue().getIndex())));
}
}
@ -439,8 +439,9 @@ public class StatementGenerator implements InstructionVisitor {
@Override
public void visit(CloneArrayInstruction insn) {
MethodDescriptor cloneMethod = new MethodDescriptor("clone", ValueType.object("java.lang.Object"));
assign(Expr.invoke("java.lang.Object", cloneMethod, Expr.var(insn.getArray().getIndex()), new Expr[0]),
MethodDescriptor cloneMethodDesc = new MethodDescriptor("clone", ValueType.object("java.lang.Object"));
MethodReference cloneMethod = new MethodReference("java.lang.Object", cloneMethodDesc);
assign(Expr.invoke(cloneMethod, Expr.var(insn.getArray().getIndex()), new Expr[0]),
insn.getReceiver().getIndex());
}
@ -458,10 +459,9 @@ public class StatementGenerator implements InstructionVisitor {
@Override
public void visit(InvokeInstruction insn) {
String declaringClass = findDeclaringClass(insn.getClassName(), insn.getMethod());
if (declaringClass == null) {
throw new IllegalArgumentException("Method not found: " + insn.getClassName() + "." +
insn.getMethod());
MethodReference method = findDeclaringClass(insn.getMethod());
if (method == null) {
throw new IllegalArgumentException("Method not found: " + insn.getMethod());
}
Expr[] exprArgs = new Expr[insn.getMethod().getParameterTypes().length];
for (int i = 0; i < insn.getArguments().size(); ++i) {
@ -470,14 +470,12 @@ public class StatementGenerator implements InstructionVisitor {
Expr invocationExpr;
if (insn.getInstance() != null) {
if (insn.getType() == InvocationType.VIRTUAL) {
invocationExpr = Expr.invoke(declaringClass, insn.getMethod(),
Expr.var(insn.getInstance().getIndex()), exprArgs);
invocationExpr = Expr.invoke(insn.getMethod(), Expr.var(insn.getInstance().getIndex()), exprArgs);
} else {
invocationExpr = Expr.invokeSpecial(declaringClass, insn.getMethod(),
Expr.var(insn.getInstance().getIndex()), exprArgs);
invocationExpr = Expr.invokeSpecial(method, Expr.var(insn.getInstance().getIndex()), exprArgs);
}
} else {
invocationExpr = Expr.invokeStatic(declaringClass, insn.getMethod(), exprArgs);
invocationExpr = Expr.invokeStatic(method, exprArgs);
}
if (insn.getReceiver() != null) {
assign(invocationExpr, insn.getReceiver().getIndex());
@ -486,12 +484,12 @@ public class StatementGenerator implements InstructionVisitor {
}
}
public String findDeclaringClass(String className, MethodDescriptor method) {
ClassHolder cls = classSource.getClassHolder(className);
while (cls != null && cls.getMethod(method) == null) {
public MethodReference findDeclaringClass(MethodReference method) {
ClassHolder cls = classSource.getClassHolder(method.getClassName());
while (cls != null && cls.getMethod(method.getDescriptor()) == null) {
cls = cls.getParent() != null ? classSource.getClassHolder(cls.getParent()) : null;
}
return cls != null ? cls.getName() : null;
return cls != null ? new MethodReference(cls.getName(), method.getDescriptor()) : null;
}
@Override

View File

@ -95,26 +95,23 @@ public abstract class Expr implements Cloneable {
return expr;
}
public static Expr constructObject(String cls, MethodDescriptor method, Expr[] arguments) {
public static Expr constructObject(MethodReference method, Expr[] arguments) {
InvocationExpr expr = new InvocationExpr();
expr.setClassName(cls);
expr.setMethod(method);
expr.setType(InvocationType.CONSTRUCTOR);
expr.getArguments().addAll(Arrays.asList(arguments));
return expr;
}
public static Expr qualify(Expr target, String className, String field) {
public static Expr qualify(Expr target, FieldReference field) {
QualificationExpr expr = new QualificationExpr();
expr.setQualified(target);
expr.setClassName(className);
expr.setField(field);
return expr;
}
public static Expr invoke(String cls, MethodDescriptor method, Expr target, Expr[] arguments) {
public static Expr invoke(MethodReference method, Expr target, Expr[] arguments) {
InvocationExpr expr = new InvocationExpr();
expr.setClassName(cls);
expr.setMethod(method);
expr.setType(InvocationType.DYNAMIC);
expr.getArguments().add(target);
@ -122,10 +119,8 @@ public abstract class Expr implements Cloneable {
return expr;
}
public static Expr invokeSpecial(String cls, MethodDescriptor method,
Expr target, Expr[] arguments) {
public static Expr invokeSpecial(MethodReference method, Expr target, Expr[] arguments) {
InvocationExpr expr = new InvocationExpr();
expr.setClassName(cls);
expr.setMethod(method);
expr.setType(InvocationType.SPECIAL);
expr.getArguments().add(target);
@ -133,9 +128,8 @@ public abstract class Expr implements Cloneable {
return expr;
}
public static Expr invokeStatic(String cls, MethodDescriptor method, Expr[] arguments) {
public static Expr invokeStatic(MethodReference method, Expr[] arguments) {
InvocationExpr expr = new InvocationExpr();
expr.setClassName(cls);
expr.setMethod(method);
expr.setType(InvocationType.STATIC);
expr.getArguments().addAll(Arrays.asList(arguments));

View File

@ -18,31 +18,22 @@ package org.teavm.javascript.ast;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.teavm.model.MethodDescriptor;
import org.teavm.model.MethodReference;
/**
*
* @author Alexey Andreev
*/
public class InvocationExpr extends Expr {
private String className;
private MethodDescriptor method;
private MethodReference method;
private InvocationType type;
private List<Expr> arguments = new ArrayList<>();
public String getClassName() {
return className;
}
public void setClassName(String className) {
this.className = className;
}
public MethodDescriptor getMethod() {
public MethodReference getMethod() {
return method;
}
public void setMethod(MethodDescriptor method) {
public void setMethod(MethodReference method) {
this.method = method;
}
@ -72,7 +63,6 @@ public class InvocationExpr extends Expr {
InvocationExpr copy = new InvocationExpr();
cache.put(this, copy);
copy.setMethod(method);
copy.setClassName(className);
for (Expr arg : arguments) {
copy.getArguments().add(arg.clone(cache));
}

View File

@ -16,6 +16,7 @@
package org.teavm.javascript.ast;
import java.util.Map;
import org.teavm.model.FieldReference;
/**
*
@ -23,8 +24,7 @@ import java.util.Map;
*/
public class QualificationExpr extends Expr {
private Expr qualified;
private String className;
private String field;
private FieldReference field;
public Expr getQualified() {
return qualified;
@ -34,19 +34,11 @@ public class QualificationExpr extends Expr {
this.qualified = qualified;
}
public String getClassName() {
return className;
}
public void setClassName(String className) {
this.className = className;
}
public String getField() {
public FieldReference getField() {
return field;
}
public void setField(String field) {
public void setField(FieldReference field) {
this.field = field;
}
@ -63,7 +55,6 @@ public class QualificationExpr extends Expr {
}
QualificationExpr copy = new QualificationExpr();
cache.put(this, copy);
copy.setClassName(className);
copy.setField(field);
copy.setQualified(qualified != null ? qualified.clone(cache) : null);
return copy;

View File

@ -22,7 +22,19 @@ public class MethodReference {
}
public int parameterCount() {
return descriptor.getParameterTypes().length;
return descriptor.parameterCount();
}
public ValueType[] getParameterTypes() {
return descriptor.getParameterTypes();
}
public ValueType[] getSignature() {
return descriptor.getSignature();
}
public String getName() {
return descriptor.getName();
}
@Override

View File

@ -1,5 +1,6 @@
package org.teavm.model.instructions;
import org.teavm.model.FieldReference;
import org.teavm.model.Instruction;
import org.teavm.model.ValueType;
import org.teavm.model.Variable;
@ -10,8 +11,7 @@ import org.teavm.model.Variable;
*/
public class GetFieldInstruction extends Instruction {
private Variable instance;
private String className;
private String field;
private FieldReference field;
private ValueType fieldType;
private Variable receiver;
@ -23,19 +23,11 @@ public class GetFieldInstruction extends Instruction {
this.instance = instance;
}
public String getClassName() {
return className;
}
public void setClassName(String className) {
this.className = className;
}
public String getField() {
public FieldReference getField() {
return field;
}
public void setField(String field) {
public void setField(FieldReference field) {
this.field = field;
}

View File

@ -10,8 +10,7 @@ import org.teavm.model.*;
*/
public class InvokeInstruction extends Instruction {
private InvocationType type;
private String className;
private MethodDescriptor method;
private MethodReference method;
private Variable instance;
private List<Variable> arguments = new ArrayList<>();
private Variable receiver;
@ -36,19 +35,11 @@ public class InvokeInstruction extends Instruction {
return arguments;
}
public String getClassName() {
return className;
}
public void setClassName(String className) {
this.className = className;
}
public MethodDescriptor getMethod() {
public MethodReference getMethod() {
return method;
}
public void setMethod(MethodDescriptor method) {
public void setMethod(MethodReference method) {
this.method = method;
}

View File

@ -1,5 +1,6 @@
package org.teavm.model.instructions;
import org.teavm.model.FieldReference;
import org.teavm.model.Instruction;
import org.teavm.model.Variable;
@ -9,8 +10,7 @@ import org.teavm.model.Variable;
*/
public class PutFieldInstruction extends Instruction {
private Variable instance;
private String className;
private String field;
private FieldReference field;
private Variable value;
public Variable getInstance() {
@ -21,19 +21,11 @@ public class PutFieldInstruction extends Instruction {
this.instance = instance;
}
public String getClassName() {
return className;
}
public void setClassName(String className) {
this.className = className;
}
public String getField() {
public FieldReference getField() {
return field;
}
public void setField(String field) {
public void setField(FieldReference field) {
this.field = field;
}

View File

@ -197,12 +197,14 @@ class ClassRefsRenamer implements InstructionVisitor {
@Override
public void visit(GetFieldInstruction insn) {
insn.setClassName(classNameMapper.map(insn.getClassName()));
String className = classNameMapper.map(insn.getField().getClassName());
insn.setField(new FieldReference(className, insn.getField().getFieldName()));
}
@Override
public void visit(PutFieldInstruction insn) {
insn.setClassName(classNameMapper.map(insn.getClassName()));
String className = classNameMapper.map(insn.getField().getClassName());
insn.setField(new FieldReference(className, insn.getField().getFieldName()));
}
@Override
@ -223,12 +225,12 @@ class ClassRefsRenamer implements InstructionVisitor {
@Override
public void visit(InvokeInstruction insn) {
insn.setClassName(classNameMapper.map(insn.getClassName()));
String className = classNameMapper.map(insn.getMethod().getClassName());
ValueType[] signature = insn.getMethod().getSignature();
for (int i = 0; i < signature.length; ++i) {
signature[i] = rename(signature[i]);
}
insn.setMethod(new MethodDescriptor(insn.getMethod().getName(), signature));
insn.setMethod(new MethodReference(className, new MethodDescriptor(insn.getMethod().getName(), signature)));
}
@Override

View File

@ -236,7 +236,7 @@ public class InstructionStringifier implements InstructionVisitor {
if (insn.getInstance() != null) {
sb.append("@").append(insn.getInstance().getIndex());
} else {
sb.append(insn.getClassName());
sb.append(insn.getField().getClassName());
}
sb.append(".").append(insn.getField());
}
@ -246,7 +246,7 @@ public class InstructionStringifier implements InstructionVisitor {
if (insn.getInstance() != null) {
sb.append("@").append(insn.getInstance().getIndex());
} else {
sb.append(insn.getClassName());
sb.append(insn.getField().getClassName());
}
sb.append(".").append(insn.getField()).append(" := @").append(insn.getValue().getIndex());
}
@ -273,7 +273,7 @@ public class InstructionStringifier implements InstructionVisitor {
if (insn.getInstance() != null) {
sb.append("@").append(insn.getInstance().getIndex());
} else {
sb.append(insn.getClassName());
sb.append(insn.getMethod().getClassName());
}
sb.append(".").append(insn.getMethod().getName()).append("(");
List<Variable> arguments = insn.getArguments();

View File

@ -357,8 +357,7 @@ public class ProgramParser {
}
args[--j] = getVariable(--currentDepth);
}
MethodDescriptor method = new MethodDescriptor(name,
MethodDescriptor.parseSignature(desc));
MethodDescriptor method = new MethodDescriptor(name, MethodDescriptor.parseSignature(desc));
int instance = -1;
if (opcode != Opcodes.INVOKESTATIC) {
instance = --currentDepth;
@ -374,8 +373,7 @@ public class ProgramParser {
}
if (instance == -1) {
InvokeInstruction insn = new InvokeInstruction();
insn.setClassName(ownerCls);
insn.setMethod(method);
insn.setMethod(new MethodReference(ownerCls, method));
if (result >= 0) {
insn.setReceiver(getVariable(result));
}
@ -388,8 +386,7 @@ public class ProgramParser {
} else {
insn.setType(InvocationType.VIRTUAL);
}
insn.setClassName(ownerCls);
insn.setMethod(method);
insn.setMethod(new MethodReference(ownerCls, method));
if (result >= 0) {
insn.setReceiver(getVariable(result));
}
@ -1292,8 +1289,7 @@ public class ProgramParser {
}
GetFieldInstruction insn = new GetFieldInstruction();
insn.setInstance(getVariable(instance));
insn.setClassName(ownerCls);
insn.setField(name);
insn.setField(new FieldReference(ownerCls, name));
insn.setFieldType(type);
insn.setReceiver(getVariable(value));
builder.add(insn);
@ -1309,8 +1305,7 @@ public class ProgramParser {
int instance = --currentDepth;
PutFieldInstruction insn = new PutFieldInstruction();
insn.setInstance(getVariable(instance));
insn.setClassName(ownerCls);
insn.setField(name);
insn.setField(new FieldReference(ownerCls, name));
insn.setValue(getVariable(value));
builder.add(insn);
break;
@ -1322,8 +1317,7 @@ public class ProgramParser {
currentDepth++;
}
GetFieldInstruction insn = new GetFieldInstruction();
insn.setClassName(ownerCls);
insn.setField(name);
insn.setField(new FieldReference(ownerCls, name));
insn.setFieldType(type);
insn.setReceiver(getVariable(value));
builder.add(insn);
@ -1335,8 +1329,7 @@ public class ProgramParser {
}
int value = --currentDepth;
PutFieldInstruction insn = new PutFieldInstruction();
insn.setClassName(ownerCls);
insn.setField(name);
insn.setField(new FieldReference(ownerCls, name));
insn.setValue(getVariable(value));
builder.add(insn);
break;