mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-22 08:14:09 -08:00
Store AST cash in binary format. Introduce more compact
AST serialization format. Reduce memory consumption of incremental compilation on dev server
This commit is contained in:
parent
573c5f6064
commit
3c9a3bb359
386
core/src/main/java/org/teavm/cache/AstIO.java
vendored
386
core/src/main/java/org/teavm/cache/AstIO.java
vendored
|
@ -15,8 +15,6 @@
|
||||||
*/
|
*/
|
||||||
package org.teavm.cache;
|
package org.teavm.cache;
|
||||||
|
|
||||||
import java.io.DataInput;
|
|
||||||
import java.io.DataOutput;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.EnumSet;
|
import java.util.EnumSet;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
@ -73,6 +71,7 @@ import org.teavm.model.ElementModifier;
|
||||||
import org.teavm.model.FieldReference;
|
import org.teavm.model.FieldReference;
|
||||||
import org.teavm.model.MethodDescriptor;
|
import org.teavm.model.MethodDescriptor;
|
||||||
import org.teavm.model.MethodReference;
|
import org.teavm.model.MethodReference;
|
||||||
|
import org.teavm.model.ReferenceCache;
|
||||||
import org.teavm.model.TextLocation;
|
import org.teavm.model.TextLocation;
|
||||||
import org.teavm.model.ValueType;
|
import org.teavm.model.ValueType;
|
||||||
import org.teavm.model.util.VariableType;
|
import org.teavm.model.util.VariableType;
|
||||||
|
@ -84,34 +83,27 @@ public class AstIO {
|
||||||
private final SymbolTable symbolTable;
|
private final SymbolTable symbolTable;
|
||||||
private final SymbolTable fileTable;
|
private final SymbolTable fileTable;
|
||||||
private final Map<String, IdentifiedStatement> statementMap = new HashMap<>();
|
private final Map<String, IdentifiedStatement> statementMap = new HashMap<>();
|
||||||
private Map<String, MethodDescriptor> methodDescriptorCache = new HashMap<>();
|
private ReferenceCache referenceCache = new ReferenceCache();
|
||||||
private Map<String, Map<MethodDescriptor, MethodReference>> methodReferenceCache = new HashMap<>();
|
|
||||||
|
|
||||||
public AstIO(SymbolTable symbolTable, SymbolTable fileTable) {
|
public AstIO(SymbolTable symbolTable, SymbolTable fileTable) {
|
||||||
this.symbolTable = symbolTable;
|
this.symbolTable = symbolTable;
|
||||||
this.fileTable = fileTable;
|
this.fileTable = fileTable;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void write(DataOutput output, ControlFlowEntry[] cfg) throws IOException {
|
public void write(VarDataOutput output, ControlFlowEntry[] cfg) throws IOException {
|
||||||
output.writeShort(cfg.length);
|
output.writeUnsigned(cfg.length);
|
||||||
for (ControlFlowEntry entry : cfg) {
|
for (ControlFlowEntry entry : cfg) {
|
||||||
writeLocation(output, entry.from);
|
writeLocation(output, entry.from);
|
||||||
output.writeShort(entry.to.length);
|
output.writeUnsigned(entry.to.length);
|
||||||
for (TextLocation loc : entry.to) {
|
for (TextLocation loc : entry.to) {
|
||||||
if (loc != null) {
|
writeLocation(output, loc);
|
||||||
output.writeByte(1);
|
|
||||||
writeLocation(output, loc);
|
|
||||||
} else {
|
|
||||||
output.writeByte(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void write(DataOutput output, RegularMethodNode method) throws IOException {
|
public void write(VarDataOutput output, RegularMethodNode method) throws IOException {
|
||||||
output.writeInt(ElementModifier.pack(method.getModifiers()));
|
output.writeUnsigned(ElementModifier.pack(method.getModifiers()));
|
||||||
output.writeShort(method.getVariables().size());
|
output.writeUnsigned(method.getVariables().size());
|
||||||
for (VariableNode var : method.getVariables()) {
|
for (VariableNode var : method.getVariables()) {
|
||||||
write(output, var);
|
write(output, var);
|
||||||
}
|
}
|
||||||
|
@ -122,33 +114,31 @@ public class AstIO {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void write(DataOutput output, VariableNode variable) throws IOException {
|
private void write(VarDataOutput output, VariableNode variable) throws IOException {
|
||||||
output.writeShort(variable.getIndex());
|
output.writeUnsigned(variable.getIndex());
|
||||||
output.writeByte(variable.getType().ordinal());
|
output.writeUnsigned(variable.getType().ordinal());
|
||||||
output.writeUTF(variable.getName() != null ? variable.getName() : "");
|
output.write(variable.getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
public ControlFlowEntry[] readControlFlow(DataInput input) throws IOException {
|
public ControlFlowEntry[] readControlFlow(VarDataInput input) throws IOException {
|
||||||
short size = input.readShort();
|
int size = input.readUnsigned();
|
||||||
ControlFlowEntry[] result = new ControlFlowEntry[size];
|
ControlFlowEntry[] result = new ControlFlowEntry[size];
|
||||||
for (int i = 0; i < size; ++i) {
|
for (int i = 0; i < size; ++i) {
|
||||||
TextLocation from = readLocation(input);
|
TextLocation from = readLocation(input);
|
||||||
int toSize = input.readShort();
|
int toSize = input.readUnsigned();
|
||||||
TextLocation[] to = new TextLocation[toSize];
|
TextLocation[] to = new TextLocation[toSize];
|
||||||
for (int j = 0; j < toSize; ++j) {
|
for (int j = 0; j < toSize; ++j) {
|
||||||
if (input.readByte() != 0) {
|
to[j] = readLocation(input);
|
||||||
to[j] = readLocation(input);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
result[i] = new ControlFlowEntry(from, to);
|
result[i] = new ControlFlowEntry(from, to);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public RegularMethodNode read(DataInput input, MethodReference method) throws IOException {
|
public RegularMethodNode read(VarDataInput input, MethodReference method) throws IOException {
|
||||||
RegularMethodNode node = new RegularMethodNode(method);
|
RegularMethodNode node = new RegularMethodNode(method);
|
||||||
node.getModifiers().addAll(unpackModifiers(input.readInt()));
|
node.getModifiers().addAll(unpackModifiers(input.readUnsigned()));
|
||||||
int varCount = input.readShort();
|
int varCount = input.readUnsigned();
|
||||||
for (int i = 0; i < varCount; ++i) {
|
for (int i = 0; i < varCount; ++i) {
|
||||||
node.getVariables().add(readVariable(input));
|
node.getVariables().add(readVariable(input));
|
||||||
}
|
}
|
||||||
|
@ -156,28 +146,22 @@ public class AstIO {
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
private VariableNode readVariable(DataInput input) throws IOException {
|
private VariableNode readVariable(VarDataInput input) throws IOException {
|
||||||
int index = input.readShort();
|
int index = input.readUnsigned();
|
||||||
VariableType type = VariableType.values()[input.readByte()];
|
VariableType type = VariableType.values()[input.readUnsigned()];
|
||||||
VariableNode variable = new VariableNode(index, type);
|
VariableNode variable = new VariableNode(index, type);
|
||||||
int nameCount = input.readByte();
|
variable.setName(input.read());
|
||||||
for (int i = 0; i < nameCount; ++i) {
|
|
||||||
variable.setName(input.readUTF());
|
|
||||||
if (variable.getName().isEmpty()) {
|
|
||||||
variable.setName(null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return variable;
|
return variable;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void writeAsync(DataOutput output, AsyncMethodNode method) throws IOException {
|
public void writeAsync(VarDataOutput output, AsyncMethodNode method) throws IOException {
|
||||||
output.writeInt(ElementModifier.pack(method.getModifiers()));
|
output.writeUnsigned(ElementModifier.pack(method.getModifiers()));
|
||||||
output.writeShort(method.getVariables().size());
|
output.writeUnsigned(method.getVariables().size());
|
||||||
for (VariableNode var : method.getVariables()) {
|
for (VariableNode var : method.getVariables()) {
|
||||||
write(output, var);
|
write(output, var);
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
output.writeShort(method.getBody().size());
|
output.writeUnsigned(method.getBody().size());
|
||||||
for (int i = 0; i < method.getBody().size(); ++i) {
|
for (int i = 0; i < method.getBody().size(); ++i) {
|
||||||
method.getBody().get(i).getStatement().acceptVisitor(new NodeWriter(output));
|
method.getBody().get(i).getStatement().acceptVisitor(new NodeWriter(output));
|
||||||
}
|
}
|
||||||
|
@ -186,14 +170,14 @@ public class AstIO {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public AsyncMethodNode readAsync(DataInput input, MethodReference method) throws IOException {
|
public AsyncMethodNode readAsync(VarDataInput input, MethodReference method) throws IOException {
|
||||||
AsyncMethodNode node = new AsyncMethodNode(method);
|
AsyncMethodNode node = new AsyncMethodNode(method);
|
||||||
node.getModifiers().addAll(unpackModifiers(input.readInt()));
|
node.getModifiers().addAll(unpackModifiers(input.readUnsigned()));
|
||||||
int varCount = input.readShort();
|
int varCount = input.readUnsigned();
|
||||||
for (int i = 0; i < varCount; ++i) {
|
for (int i = 0; i < varCount; ++i) {
|
||||||
node.getVariables().add(readVariable(input));
|
node.getVariables().add(readVariable(input));
|
||||||
}
|
}
|
||||||
int partCount = input.readShort();
|
int partCount = input.readUnsigned();
|
||||||
for (int i = 0; i < partCount; ++i) {
|
for (int i = 0; i < partCount; ++i) {
|
||||||
AsyncMethodPart part = new AsyncMethodPart();
|
AsyncMethodPart part = new AsyncMethodPart();
|
||||||
part.setStatement(readStatement(input));
|
part.setStatement(readStatement(input));
|
||||||
|
@ -212,19 +196,19 @@ public class AstIO {
|
||||||
return modifiers;
|
return modifiers;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void writeLocation(DataOutput output, TextLocation location) throws IOException {
|
private void writeLocation(VarDataOutput output, TextLocation location) throws IOException {
|
||||||
if (location == null || location.getFileName() == null) {
|
if (location == null || location.getFileName() == null) {
|
||||||
output.writeShort(-1);
|
output.writeUnsigned(0);
|
||||||
} else {
|
} else {
|
||||||
output.writeShort(fileTable.lookup(location.getFileName()));
|
output.writeUnsigned(fileTable.lookup(location.getFileName()) + 1);
|
||||||
output.writeShort(location.getLine());
|
output.writeUnsigned(location.getLine());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class NodeWriter implements ExprVisitor, StatementVisitor {
|
private class NodeWriter implements ExprVisitor, StatementVisitor {
|
||||||
private final DataOutput output;
|
private final VarDataOutput output;
|
||||||
|
|
||||||
NodeWriter(DataOutput output) {
|
NodeWriter(VarDataOutput output) {
|
||||||
super();
|
super();
|
||||||
this.output = output;
|
this.output = output;
|
||||||
}
|
}
|
||||||
|
@ -239,31 +223,22 @@ public class AstIO {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void writeSequence(List<Statement> sequence) throws IOException {
|
private void writeSequence(List<Statement> sequence) throws IOException {
|
||||||
output.writeShort(sequence.size());
|
output.writeUnsigned(sequence.size());
|
||||||
for (Statement part : sequence) {
|
for (Statement part : sequence) {
|
||||||
part.acceptVisitor(this);
|
part.acceptVisitor(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void writeNullableString(String str) throws IOException {
|
|
||||||
if (str == null) {
|
|
||||||
output.writeBoolean(false);
|
|
||||||
} else {
|
|
||||||
output.writeBoolean(true);
|
|
||||||
output.writeUTF(str);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(AssignmentStatement statement) {
|
public void visit(AssignmentStatement statement) {
|
||||||
try {
|
try {
|
||||||
output.writeByte(statement.getLeftValue() != null ? 0 : 1);
|
output.writeUnsigned(statement.getLeftValue() != null ? 0 : 1);
|
||||||
writeLocation(statement.getLocation());
|
writeLocation(statement.getLocation());
|
||||||
if (statement.getLeftValue() != null) {
|
if (statement.getLeftValue() != null) {
|
||||||
writeExpr(statement.getLeftValue());
|
writeExpr(statement.getLeftValue());
|
||||||
}
|
}
|
||||||
writeExpr(statement.getRightValue());
|
writeExpr(statement.getRightValue());
|
||||||
output.writeBoolean(statement.isAsync());
|
output.writeUnsigned(statement.isAsync() ? 1 : 0);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new IOExceptionWrapper(e);
|
throw new IOExceptionWrapper(e);
|
||||||
}
|
}
|
||||||
|
@ -272,7 +247,7 @@ public class AstIO {
|
||||||
@Override
|
@Override
|
||||||
public void visit(SequentialStatement statement) {
|
public void visit(SequentialStatement statement) {
|
||||||
try {
|
try {
|
||||||
output.writeByte(2);
|
output.writeUnsigned(2);
|
||||||
writeSequence(statement.getSequence());
|
writeSequence(statement.getSequence());
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new IOExceptionWrapper(e);
|
throw new IOExceptionWrapper(e);
|
||||||
|
@ -282,7 +257,7 @@ public class AstIO {
|
||||||
@Override
|
@Override
|
||||||
public void visit(ConditionalStatement statement) {
|
public void visit(ConditionalStatement statement) {
|
||||||
try {
|
try {
|
||||||
output.writeByte(3);
|
output.writeUnsigned(3);
|
||||||
writeExpr(statement.getCondition());
|
writeExpr(statement.getCondition());
|
||||||
writeSequence(statement.getConsequent());
|
writeSequence(statement.getConsequent());
|
||||||
writeSequence(statement.getAlternative());
|
writeSequence(statement.getAlternative());
|
||||||
|
@ -294,15 +269,15 @@ public class AstIO {
|
||||||
@Override
|
@Override
|
||||||
public void visit(SwitchStatement statement) {
|
public void visit(SwitchStatement statement) {
|
||||||
try {
|
try {
|
||||||
output.writeByte(4);
|
output.writeUnsigned(4);
|
||||||
writeNullableString(statement.getId());
|
output.write(statement.getId());
|
||||||
writeExpr(statement.getValue());
|
writeExpr(statement.getValue());
|
||||||
output.writeShort(statement.getClauses().size());
|
output.writeUnsigned(statement.getClauses().size());
|
||||||
for (SwitchClause clause : statement.getClauses()) {
|
for (SwitchClause clause : statement.getClauses()) {
|
||||||
int[] conditions = clause.getConditions();
|
int[] conditions = clause.getConditions();
|
||||||
output.writeShort(conditions.length);
|
output.writeUnsigned(conditions.length);
|
||||||
for (int condition : conditions) {
|
for (int condition : conditions) {
|
||||||
output.writeInt(condition);
|
output.writeSigned(condition);
|
||||||
}
|
}
|
||||||
writeSequence(clause.getBody());
|
writeSequence(clause.getBody());
|
||||||
}
|
}
|
||||||
|
@ -315,8 +290,8 @@ public class AstIO {
|
||||||
@Override
|
@Override
|
||||||
public void visit(WhileStatement statement) {
|
public void visit(WhileStatement statement) {
|
||||||
try {
|
try {
|
||||||
output.writeByte(statement.getCondition() != null ? 5 : 6);
|
output.writeUnsigned(statement.getCondition() != null ? 5 : 6);
|
||||||
writeNullableString(statement.getId());
|
output.write(statement.getId());
|
||||||
if (statement.getCondition() != null) {
|
if (statement.getCondition() != null) {
|
||||||
writeExpr(statement.getCondition());
|
writeExpr(statement.getCondition());
|
||||||
}
|
}
|
||||||
|
@ -329,8 +304,8 @@ public class AstIO {
|
||||||
@Override
|
@Override
|
||||||
public void visit(BlockStatement statement) {
|
public void visit(BlockStatement statement) {
|
||||||
try {
|
try {
|
||||||
output.writeByte(7);
|
output.writeUnsigned(7);
|
||||||
writeNullableString(statement.getId());
|
output.write(statement.getId());
|
||||||
writeSequence(statement.getBody());
|
writeSequence(statement.getBody());
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new IOExceptionWrapper(e);
|
throw new IOExceptionWrapper(e);
|
||||||
|
@ -340,10 +315,10 @@ public class AstIO {
|
||||||
@Override
|
@Override
|
||||||
public void visit(BreakStatement statement) {
|
public void visit(BreakStatement statement) {
|
||||||
try {
|
try {
|
||||||
output.writeByte(statement.getTarget() != null && statement.getTarget().getId() != null ? 8 : 9);
|
output.writeUnsigned(statement.getTarget() != null && statement.getTarget().getId() != null ? 8 : 9);
|
||||||
writeLocation(statement.getLocation());
|
writeLocation(statement.getLocation());
|
||||||
if (statement.getTarget() != null && statement.getTarget().getId() != null) {
|
if (statement.getTarget() != null && statement.getTarget().getId() != null) {
|
||||||
output.writeUTF(statement.getTarget().getId());
|
output.write(statement.getTarget().getId());
|
||||||
}
|
}
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new IOExceptionWrapper(e);
|
throw new IOExceptionWrapper(e);
|
||||||
|
@ -353,10 +328,10 @@ public class AstIO {
|
||||||
@Override
|
@Override
|
||||||
public void visit(ContinueStatement statement) {
|
public void visit(ContinueStatement statement) {
|
||||||
try {
|
try {
|
||||||
output.writeByte(statement.getTarget() != null && statement.getTarget().getId() != null ? 10 : 11);
|
output.writeUnsigned(statement.getTarget() != null && statement.getTarget().getId() != null ? 10 : 11);
|
||||||
writeLocation(statement.getLocation());
|
writeLocation(statement.getLocation());
|
||||||
if (statement.getTarget() != null && statement.getTarget().getId() != null) {
|
if (statement.getTarget() != null && statement.getTarget().getId() != null) {
|
||||||
output.writeUTF(statement.getTarget().getId());
|
output.write(statement.getTarget().getId());
|
||||||
}
|
}
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new IOExceptionWrapper(e);
|
throw new IOExceptionWrapper(e);
|
||||||
|
@ -366,7 +341,7 @@ public class AstIO {
|
||||||
@Override
|
@Override
|
||||||
public void visit(ReturnStatement statement) {
|
public void visit(ReturnStatement statement) {
|
||||||
try {
|
try {
|
||||||
output.writeByte(statement.getResult() != null ? 12 : 13);
|
output.writeUnsigned(statement.getResult() != null ? 12 : 13);
|
||||||
writeLocation(statement.getLocation());
|
writeLocation(statement.getLocation());
|
||||||
if (statement.getResult() != null) {
|
if (statement.getResult() != null) {
|
||||||
writeExpr(statement.getResult());
|
writeExpr(statement.getResult());
|
||||||
|
@ -379,7 +354,7 @@ public class AstIO {
|
||||||
@Override
|
@Override
|
||||||
public void visit(ThrowStatement statement) {
|
public void visit(ThrowStatement statement) {
|
||||||
try {
|
try {
|
||||||
output.writeByte(14);
|
output.writeUnsigned(14);
|
||||||
writeLocation(statement.getLocation());
|
writeLocation(statement.getLocation());
|
||||||
writeExpr(statement.getException());
|
writeExpr(statement.getException());
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
|
@ -390,9 +365,9 @@ public class AstIO {
|
||||||
@Override
|
@Override
|
||||||
public void visit(InitClassStatement statement) {
|
public void visit(InitClassStatement statement) {
|
||||||
try {
|
try {
|
||||||
output.writeByte(15);
|
output.writeUnsigned(15);
|
||||||
writeLocation(statement.getLocation());
|
writeLocation(statement.getLocation());
|
||||||
output.writeInt(symbolTable.lookup(statement.getClassName()));
|
output.writeUnsigned(symbolTable.lookup(statement.getClassName()));
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new IOExceptionWrapper(e);
|
throw new IOExceptionWrapper(e);
|
||||||
}
|
}
|
||||||
|
@ -401,12 +376,12 @@ public class AstIO {
|
||||||
@Override
|
@Override
|
||||||
public void visit(TryCatchStatement statement) {
|
public void visit(TryCatchStatement statement) {
|
||||||
try {
|
try {
|
||||||
output.writeByte(16);
|
output.writeUnsigned(16);
|
||||||
writeSequence(statement.getProtectedBody());
|
writeSequence(statement.getProtectedBody());
|
||||||
output.writeInt(statement.getExceptionType() != null
|
output.writeUnsigned(statement.getExceptionType() != null
|
||||||
? symbolTable.lookup(statement.getExceptionType()) : -1);
|
? symbolTable.lookup(statement.getExceptionType()) + 1 : 0);
|
||||||
output.writeShort(statement.getExceptionVariable() != null
|
output.writeUnsigned(statement.getExceptionVariable() != null
|
||||||
? statement.getExceptionVariable() : -1);
|
? statement.getExceptionVariable() + 1 : 0);
|
||||||
writeSequence(statement.getHandler());
|
writeSequence(statement.getHandler());
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new IOExceptionWrapper(e);
|
throw new IOExceptionWrapper(e);
|
||||||
|
@ -416,8 +391,8 @@ public class AstIO {
|
||||||
@Override
|
@Override
|
||||||
public void visit(GotoPartStatement statement) {
|
public void visit(GotoPartStatement statement) {
|
||||||
try {
|
try {
|
||||||
output.writeByte(17);
|
output.writeUnsigned(17);
|
||||||
output.writeShort(statement.getPart());
|
output.writeUnsigned(statement.getPart());
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new IOExceptionWrapper(e);
|
throw new IOExceptionWrapper(e);
|
||||||
}
|
}
|
||||||
|
@ -426,7 +401,7 @@ public class AstIO {
|
||||||
@Override
|
@Override
|
||||||
public void visit(MonitorEnterStatement statement) {
|
public void visit(MonitorEnterStatement statement) {
|
||||||
try {
|
try {
|
||||||
output.writeByte(18);
|
output.writeUnsigned(18);
|
||||||
writeLocation(statement.getLocation());
|
writeLocation(statement.getLocation());
|
||||||
writeExpr(statement.getObjectRef());
|
writeExpr(statement.getObjectRef());
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
|
@ -437,7 +412,7 @@ public class AstIO {
|
||||||
@Override
|
@Override
|
||||||
public void visit(MonitorExitStatement statement) {
|
public void visit(MonitorExitStatement statement) {
|
||||||
try {
|
try {
|
||||||
output.writeByte(19);
|
output.writeUnsigned(19);
|
||||||
writeLocation(statement.getLocation());
|
writeLocation(statement.getLocation());
|
||||||
writeExpr(statement.getObjectRef());
|
writeExpr(statement.getObjectRef());
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
|
@ -448,9 +423,9 @@ public class AstIO {
|
||||||
@Override
|
@Override
|
||||||
public void visit(BinaryExpr expr) {
|
public void visit(BinaryExpr expr) {
|
||||||
try {
|
try {
|
||||||
output.writeByte(0);
|
output.writeUnsigned(0);
|
||||||
output.writeByte(expr.getOperation().ordinal());
|
output.writeUnsigned(expr.getOperation().ordinal());
|
||||||
output.writeByte(expr.getType() != null ? expr.getType().ordinal() + 1 : 0);
|
output.writeUnsigned(expr.getType() != null ? expr.getType().ordinal() + 1 : 0);
|
||||||
writeExpr(expr.getFirstOperand());
|
writeExpr(expr.getFirstOperand());
|
||||||
writeExpr(expr.getSecondOperand());
|
writeExpr(expr.getSecondOperand());
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
|
@ -461,9 +436,9 @@ public class AstIO {
|
||||||
@Override
|
@Override
|
||||||
public void visit(UnaryExpr expr) {
|
public void visit(UnaryExpr expr) {
|
||||||
try {
|
try {
|
||||||
output.writeByte(1);
|
output.writeUnsigned(1);
|
||||||
output.writeByte(expr.getOperation().ordinal());
|
output.writeUnsigned(expr.getOperation().ordinal());
|
||||||
output.writeByte(expr.getType() != null ? expr.getType().ordinal() + 1 : 0);
|
output.writeUnsigned(expr.getType() != null ? expr.getType().ordinal() + 1 : 0);
|
||||||
writeExpr(expr.getOperand());
|
writeExpr(expr.getOperand());
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new IOExceptionWrapper(e);
|
throw new IOExceptionWrapper(e);
|
||||||
|
@ -473,7 +448,7 @@ public class AstIO {
|
||||||
@Override
|
@Override
|
||||||
public void visit(ConditionalExpr expr) {
|
public void visit(ConditionalExpr expr) {
|
||||||
try {
|
try {
|
||||||
output.writeByte(2);
|
output.writeUnsigned(2);
|
||||||
writeExpr(expr.getCondition());
|
writeExpr(expr.getCondition());
|
||||||
writeExpr(expr.getConsequent());
|
writeExpr(expr.getConsequent());
|
||||||
writeExpr(expr.getAlternative());
|
writeExpr(expr.getAlternative());
|
||||||
|
@ -487,25 +462,25 @@ public class AstIO {
|
||||||
try {
|
try {
|
||||||
Object value = expr.getValue();
|
Object value = expr.getValue();
|
||||||
if (value == null) {
|
if (value == null) {
|
||||||
output.writeByte(3);
|
output.writeUnsigned(3);
|
||||||
} else if (value instanceof Integer) {
|
} else if (value instanceof Integer) {
|
||||||
output.writeByte(4);
|
output.writeUnsigned(4);
|
||||||
output.writeInt((Integer) value);
|
output.writeSigned((Integer) value);
|
||||||
} else if (value instanceof Long) {
|
} else if (value instanceof Long) {
|
||||||
output.writeByte(5);
|
output.writeUnsigned(5);
|
||||||
output.writeLong((Long) value);
|
output.writeSigned((Long) value);
|
||||||
} else if (value instanceof Float) {
|
} else if (value instanceof Float) {
|
||||||
output.writeByte(6);
|
output.writeUnsigned(6);
|
||||||
output.writeFloat((Float) value);
|
output.writeFloat((Float) value);
|
||||||
} else if (value instanceof Double) {
|
} else if (value instanceof Double) {
|
||||||
output.writeByte(7);
|
output.writeUnsigned(7);
|
||||||
output.writeDouble((Double) value);
|
output.writeDouble((Double) value);
|
||||||
} else if (value instanceof String) {
|
} else if (value instanceof String) {
|
||||||
output.writeByte(8);
|
output.writeUnsigned(8);
|
||||||
output.writeUTF((String) value);
|
output.write((String) value);
|
||||||
} else if (value instanceof ValueType) {
|
} else if (value instanceof ValueType) {
|
||||||
output.writeByte(9);
|
output.writeUnsigned(9);
|
||||||
output.writeInt(symbolTable.lookup(value.toString()));
|
output.writeUnsigned(symbolTable.lookup(value.toString()));
|
||||||
}
|
}
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new IOExceptionWrapper(e);
|
throw new IOExceptionWrapper(e);
|
||||||
|
@ -515,8 +490,8 @@ public class AstIO {
|
||||||
@Override
|
@Override
|
||||||
public void visit(VariableExpr expr) {
|
public void visit(VariableExpr expr) {
|
||||||
try {
|
try {
|
||||||
output.writeByte(10);
|
output.writeUnsigned(10);
|
||||||
output.writeShort(expr.getIndex());
|
output.writeUnsigned(expr.getIndex());
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new IOExceptionWrapper(e);
|
throw new IOExceptionWrapper(e);
|
||||||
}
|
}
|
||||||
|
@ -525,10 +500,10 @@ public class AstIO {
|
||||||
@Override
|
@Override
|
||||||
public void visit(SubscriptExpr expr) {
|
public void visit(SubscriptExpr expr) {
|
||||||
try {
|
try {
|
||||||
output.writeByte(11);
|
output.writeUnsigned(11);
|
||||||
writeExpr(expr.getArray());
|
writeExpr(expr.getArray());
|
||||||
writeExpr(expr.getIndex());
|
writeExpr(expr.getIndex());
|
||||||
output.writeByte(expr.getType().ordinal());
|
output.writeUnsigned(expr.getType().ordinal());
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new IOExceptionWrapper(e);
|
throw new IOExceptionWrapper(e);
|
||||||
}
|
}
|
||||||
|
@ -537,8 +512,8 @@ public class AstIO {
|
||||||
@Override
|
@Override
|
||||||
public void visit(UnwrapArrayExpr expr) {
|
public void visit(UnwrapArrayExpr expr) {
|
||||||
try {
|
try {
|
||||||
output.writeByte(12);
|
output.writeUnsigned(12);
|
||||||
output.writeByte(expr.getElementType().ordinal());
|
output.writeUnsigned(expr.getElementType().ordinal());
|
||||||
writeExpr(expr.getArray());
|
writeExpr(expr.getArray());
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new IOExceptionWrapper(e);
|
throw new IOExceptionWrapper(e);
|
||||||
|
@ -550,21 +525,21 @@ public class AstIO {
|
||||||
try {
|
try {
|
||||||
switch (expr.getType()) {
|
switch (expr.getType()) {
|
||||||
case CONSTRUCTOR:
|
case CONSTRUCTOR:
|
||||||
output.writeByte(13);
|
output.writeUnsigned(13);
|
||||||
break;
|
break;
|
||||||
case STATIC:
|
case STATIC:
|
||||||
output.writeByte(14);
|
output.writeUnsigned(14);
|
||||||
break;
|
break;
|
||||||
case SPECIAL:
|
case SPECIAL:
|
||||||
output.writeByte(15);
|
output.writeUnsigned(15);
|
||||||
break;
|
break;
|
||||||
case DYNAMIC:
|
case DYNAMIC:
|
||||||
output.writeByte(16);
|
output.writeUnsigned(16);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
output.writeInt(symbolTable.lookup(expr.getMethod().getClassName()));
|
output.writeUnsigned(symbolTable.lookup(expr.getMethod().getClassName()));
|
||||||
output.writeInt(symbolTable.lookup(expr.getMethod().getDescriptor().toString()));
|
output.writeUnsigned(symbolTable.lookup(expr.getMethod().getDescriptor().toString()));
|
||||||
output.writeShort(expr.getArguments().size());
|
output.writeUnsigned(expr.getArguments().size());
|
||||||
for (int i = 0; i < expr.getArguments().size(); ++i) {
|
for (int i = 0; i < expr.getArguments().size(); ++i) {
|
||||||
writeExpr(expr.getArguments().get(i));
|
writeExpr(expr.getArguments().get(i));
|
||||||
}
|
}
|
||||||
|
@ -576,12 +551,12 @@ public class AstIO {
|
||||||
@Override
|
@Override
|
||||||
public void visit(QualificationExpr expr) {
|
public void visit(QualificationExpr expr) {
|
||||||
try {
|
try {
|
||||||
output.writeByte(expr.getQualified() != null ? 17 : 18);
|
output.writeUnsigned(expr.getQualified() == null ? 17 : 18);
|
||||||
if (expr.getQualified() != null) {
|
if (expr.getQualified() != null) {
|
||||||
writeExpr(expr.getQualified());
|
writeExpr(expr.getQualified());
|
||||||
}
|
}
|
||||||
output.writeInt(symbolTable.lookup(expr.getField().getClassName()));
|
output.writeUnsigned(symbolTable.lookup(expr.getField().getClassName()));
|
||||||
output.writeInt(symbolTable.lookup(expr.getField().getFieldName()));
|
output.writeUnsigned(symbolTable.lookup(expr.getField().getFieldName()));
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new IOExceptionWrapper(e);
|
throw new IOExceptionWrapper(e);
|
||||||
}
|
}
|
||||||
|
@ -590,8 +565,8 @@ public class AstIO {
|
||||||
@Override
|
@Override
|
||||||
public void visit(NewExpr expr) {
|
public void visit(NewExpr expr) {
|
||||||
try {
|
try {
|
||||||
output.writeByte(19);
|
output.writeUnsigned(19);
|
||||||
output.writeInt(symbolTable.lookup(expr.getConstructedClass()));
|
output.writeUnsigned(symbolTable.lookup(expr.getConstructedClass()));
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new IOExceptionWrapper(e);
|
throw new IOExceptionWrapper(e);
|
||||||
}
|
}
|
||||||
|
@ -600,9 +575,9 @@ public class AstIO {
|
||||||
@Override
|
@Override
|
||||||
public void visit(NewArrayExpr expr) {
|
public void visit(NewArrayExpr expr) {
|
||||||
try {
|
try {
|
||||||
output.writeByte(20);
|
output.writeUnsigned(20);
|
||||||
writeExpr(expr.getLength());
|
writeExpr(expr.getLength());
|
||||||
output.writeInt(symbolTable.lookup(expr.getType().toString()));
|
output.writeUnsigned(symbolTable.lookup(expr.getType().toString()));
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new IOExceptionWrapper(e);
|
throw new IOExceptionWrapper(e);
|
||||||
}
|
}
|
||||||
|
@ -611,12 +586,12 @@ public class AstIO {
|
||||||
@Override
|
@Override
|
||||||
public void visit(NewMultiArrayExpr expr) {
|
public void visit(NewMultiArrayExpr expr) {
|
||||||
try {
|
try {
|
||||||
output.writeByte(21);
|
output.writeUnsigned(21);
|
||||||
output.writeByte(expr.getDimensions().size());
|
output.writeUnsigned(expr.getDimensions().size());
|
||||||
for (Expr dimension : expr.getDimensions()) {
|
for (Expr dimension : expr.getDimensions()) {
|
||||||
writeExpr(dimension);
|
writeExpr(dimension);
|
||||||
}
|
}
|
||||||
output.writeInt(symbolTable.lookup(expr.getType().toString()));
|
output.writeUnsigned(symbolTable.lookup(expr.getType().toString()));
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new IOExceptionWrapper(e);
|
throw new IOExceptionWrapper(e);
|
||||||
}
|
}
|
||||||
|
@ -625,9 +600,9 @@ public class AstIO {
|
||||||
@Override
|
@Override
|
||||||
public void visit(InstanceOfExpr expr) {
|
public void visit(InstanceOfExpr expr) {
|
||||||
try {
|
try {
|
||||||
output.writeByte(22);
|
output.writeUnsigned(22);
|
||||||
writeExpr(expr.getExpr());
|
writeExpr(expr.getExpr());
|
||||||
output.writeInt(symbolTable.lookup(expr.getType().toString()));
|
output.writeUnsigned(symbolTable.lookup(expr.getType().toString()));
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new IOExceptionWrapper(e);
|
throw new IOExceptionWrapper(e);
|
||||||
}
|
}
|
||||||
|
@ -636,8 +611,8 @@ public class AstIO {
|
||||||
@Override
|
@Override
|
||||||
public void visit(CastExpr expr) {
|
public void visit(CastExpr expr) {
|
||||||
try {
|
try {
|
||||||
output.writeByte(23);
|
output.writeUnsigned(23);
|
||||||
output.writeInt(symbolTable.lookup(expr.getTarget().toString()));
|
output.writeUnsigned(symbolTable.lookup(expr.getTarget().toString()));
|
||||||
writeExpr(expr.getValue());
|
writeExpr(expr.getValue());
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new IOExceptionWrapper(e);
|
throw new IOExceptionWrapper(e);
|
||||||
|
@ -647,9 +622,9 @@ public class AstIO {
|
||||||
@Override
|
@Override
|
||||||
public void visit(PrimitiveCastExpr expr) {
|
public void visit(PrimitiveCastExpr expr) {
|
||||||
try {
|
try {
|
||||||
output.writeByte(24);
|
output.writeUnsigned(24);
|
||||||
output.writeByte(expr.getSource().ordinal());
|
output.writeUnsigned(expr.getSource().ordinal());
|
||||||
output.writeByte(expr.getTarget().ordinal());
|
output.writeUnsigned(expr.getTarget().ordinal());
|
||||||
writeExpr(expr.getValue());
|
writeExpr(expr.getValue());
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new IOExceptionWrapper(e);
|
throw new IOExceptionWrapper(e);
|
||||||
|
@ -657,31 +632,31 @@ public class AstIO {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private TextLocation readLocation(DataInput input) throws IOException {
|
private TextLocation readLocation(VarDataInput input) throws IOException {
|
||||||
int fileIndex = input.readShort();
|
int fileIndex = input.readUnsigned();
|
||||||
if (fileIndex == -1) {
|
if (fileIndex == 0) {
|
||||||
return null;
|
return null;
|
||||||
} else {
|
} else {
|
||||||
return new TextLocation(fileTable.at(fileIndex), input.readShort());
|
return new TextLocation(fileTable.at(fileIndex - 1), input.readUnsigned());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Statement readStatement(DataInput input) throws IOException {
|
private Statement readStatement(VarDataInput input) throws IOException {
|
||||||
byte type = input.readByte();
|
int type = input.readUnsigned();
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case 0: {
|
case 0: {
|
||||||
AssignmentStatement stmt = new AssignmentStatement();
|
AssignmentStatement stmt = new AssignmentStatement();
|
||||||
stmt.setLocation(readLocation(input));
|
stmt.setLocation(readLocation(input));
|
||||||
stmt.setLeftValue(readExpr(input));
|
stmt.setLeftValue(readExpr(input));
|
||||||
stmt.setRightValue(readExpr(input));
|
stmt.setRightValue(readExpr(input));
|
||||||
stmt.setAsync(input.readBoolean());
|
stmt.setAsync(input.readUnsigned() != 0);
|
||||||
return stmt;
|
return stmt;
|
||||||
}
|
}
|
||||||
case 1: {
|
case 1: {
|
||||||
AssignmentStatement stmt = new AssignmentStatement();
|
AssignmentStatement stmt = new AssignmentStatement();
|
||||||
stmt.setLocation(readLocation(input));
|
stmt.setLocation(readLocation(input));
|
||||||
stmt.setRightValue(readExpr(input));
|
stmt.setRightValue(readExpr(input));
|
||||||
stmt.setAsync(input.readBoolean());
|
stmt.setAsync(input.readUnsigned() != 0);
|
||||||
return stmt;
|
return stmt;
|
||||||
}
|
}
|
||||||
case 2: {
|
case 2: {
|
||||||
|
@ -698,15 +673,15 @@ public class AstIO {
|
||||||
}
|
}
|
||||||
case 4: {
|
case 4: {
|
||||||
SwitchStatement stmt = new SwitchStatement();
|
SwitchStatement stmt = new SwitchStatement();
|
||||||
stmt.setId(readNullableString(input));
|
stmt.setId(input.read());
|
||||||
stmt.setValue(readExpr(input));
|
stmt.setValue(readExpr(input));
|
||||||
int clauseCount = input.readShort();
|
int clauseCount = input.readUnsigned();
|
||||||
for (int i = 0; i < clauseCount; ++i) {
|
for (int i = 0; i < clauseCount; ++i) {
|
||||||
SwitchClause clause = new SwitchClause();
|
SwitchClause clause = new SwitchClause();
|
||||||
int conditionCount = input.readShort();
|
int conditionCount = input.readUnsigned();
|
||||||
int[] conditions = new int[conditionCount];
|
int[] conditions = new int[conditionCount];
|
||||||
for (int j = 0; j < conditionCount; ++j) {
|
for (int j = 0; j < conditionCount; ++j) {
|
||||||
conditions[j] = input.readInt();
|
conditions[j] = input.readSigned();
|
||||||
}
|
}
|
||||||
clause.setConditions(conditions);
|
clause.setConditions(conditions);
|
||||||
readSequence(input, clause.getBody());
|
readSequence(input, clause.getBody());
|
||||||
|
@ -717,7 +692,7 @@ public class AstIO {
|
||||||
}
|
}
|
||||||
case 5: {
|
case 5: {
|
||||||
WhileStatement stmt = new WhileStatement();
|
WhileStatement stmt = new WhileStatement();
|
||||||
stmt.setId(readNullableString(input));
|
stmt.setId(input.read());
|
||||||
stmt.setCondition(readExpr(input));
|
stmt.setCondition(readExpr(input));
|
||||||
if (stmt.getId() != null) {
|
if (stmt.getId() != null) {
|
||||||
statementMap.put(stmt.getId(), stmt);
|
statementMap.put(stmt.getId(), stmt);
|
||||||
|
@ -727,7 +702,7 @@ public class AstIO {
|
||||||
}
|
}
|
||||||
case 6: {
|
case 6: {
|
||||||
WhileStatement stmt = new WhileStatement();
|
WhileStatement stmt = new WhileStatement();
|
||||||
stmt.setId(readNullableString(input));
|
stmt.setId(input.read());
|
||||||
if (stmt.getId() != null) {
|
if (stmt.getId() != null) {
|
||||||
statementMap.put(stmt.getId(), stmt);
|
statementMap.put(stmt.getId(), stmt);
|
||||||
}
|
}
|
||||||
|
@ -736,7 +711,7 @@ public class AstIO {
|
||||||
}
|
}
|
||||||
case 7: {
|
case 7: {
|
||||||
BlockStatement stmt = new BlockStatement();
|
BlockStatement stmt = new BlockStatement();
|
||||||
stmt.setId(readNullableString(input));
|
stmt.setId(input.read());
|
||||||
if (stmt.getId() != null) {
|
if (stmt.getId() != null) {
|
||||||
statementMap.put(stmt.getId(), stmt);
|
statementMap.put(stmt.getId(), stmt);
|
||||||
}
|
}
|
||||||
|
@ -746,7 +721,7 @@ public class AstIO {
|
||||||
case 8: {
|
case 8: {
|
||||||
BreakStatement stmt = new BreakStatement();
|
BreakStatement stmt = new BreakStatement();
|
||||||
stmt.setLocation(readLocation(input));
|
stmt.setLocation(readLocation(input));
|
||||||
stmt.setTarget(statementMap.get(input.readUTF()));
|
stmt.setTarget(statementMap.get(input.read()));
|
||||||
return stmt;
|
return stmt;
|
||||||
}
|
}
|
||||||
case 9: {
|
case 9: {
|
||||||
|
@ -757,7 +732,7 @@ public class AstIO {
|
||||||
case 10: {
|
case 10: {
|
||||||
ContinueStatement stmt = new ContinueStatement();
|
ContinueStatement stmt = new ContinueStatement();
|
||||||
stmt.setLocation(readLocation(input));
|
stmt.setLocation(readLocation(input));
|
||||||
stmt.setTarget(statementMap.get(input.readUTF()));
|
stmt.setTarget(statementMap.get(input.read()));
|
||||||
return stmt;
|
return stmt;
|
||||||
}
|
}
|
||||||
case 11: {
|
case 11: {
|
||||||
|
@ -785,26 +760,26 @@ public class AstIO {
|
||||||
case 15: {
|
case 15: {
|
||||||
InitClassStatement stmt = new InitClassStatement();
|
InitClassStatement stmt = new InitClassStatement();
|
||||||
stmt.setLocation(readLocation(input));
|
stmt.setLocation(readLocation(input));
|
||||||
stmt.setClassName(symbolTable.at(input.readInt()));
|
stmt.setClassName(symbolTable.at(input.readUnsigned()));
|
||||||
return stmt;
|
return stmt;
|
||||||
}
|
}
|
||||||
case 16: {
|
case 16: {
|
||||||
TryCatchStatement stmt = new TryCatchStatement();
|
TryCatchStatement stmt = new TryCatchStatement();
|
||||||
readSequence(input, stmt.getProtectedBody());
|
readSequence(input, stmt.getProtectedBody());
|
||||||
int exceptionTypeIndex = input.readInt();
|
int exceptionTypeIndex = input.readUnsigned();
|
||||||
if (exceptionTypeIndex >= 0) {
|
if (exceptionTypeIndex > 0) {
|
||||||
stmt.setExceptionType(symbolTable.at(exceptionTypeIndex));
|
stmt.setExceptionType(symbolTable.at(exceptionTypeIndex - 1));
|
||||||
}
|
}
|
||||||
int exceptionVarIndex = input.readShort();
|
int exceptionVarIndex = input.readUnsigned();
|
||||||
if (exceptionVarIndex >= 0) {
|
if (exceptionVarIndex > 0) {
|
||||||
stmt.setExceptionVariable(exceptionVarIndex);
|
stmt.setExceptionVariable(exceptionVarIndex - 1);
|
||||||
}
|
}
|
||||||
readSequence(input, stmt.getHandler());
|
readSequence(input, stmt.getHandler());
|
||||||
return stmt;
|
return stmt;
|
||||||
}
|
}
|
||||||
case 17: {
|
case 17: {
|
||||||
GotoPartStatement stmt = new GotoPartStatement();
|
GotoPartStatement stmt = new GotoPartStatement();
|
||||||
stmt.setPart(input.readShort());
|
stmt.setPart(input.readUnsigned());
|
||||||
return stmt;
|
return stmt;
|
||||||
}
|
}
|
||||||
case 18: {
|
case 18: {
|
||||||
|
@ -824,41 +799,37 @@ public class AstIO {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void readSequence(DataInput input, List<Statement> statements) throws IOException {
|
private void readSequence(VarDataInput input, List<Statement> statements) throws IOException {
|
||||||
int count = input.readShort();
|
int count = input.readUnsigned();
|
||||||
for (int i = 0; i < count; ++i) {
|
for (int i = 0; i < count; ++i) {
|
||||||
statements.add(readStatement(input));
|
statements.add(readStatement(input));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private String readNullableString(DataInput input) throws IOException {
|
private Expr readExpr(VarDataInput input) throws IOException {
|
||||||
return input.readBoolean() ? input.readUTF() : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Expr readExpr(DataInput input) throws IOException {
|
|
||||||
TextLocation location = readLocation(input);
|
TextLocation location = readLocation(input);
|
||||||
Expr expr = readExprWithoutLocation(input);
|
Expr expr = readExprWithoutLocation(input);
|
||||||
expr.setLocation(location);
|
expr.setLocation(location);
|
||||||
return expr;
|
return expr;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Expr readExprWithoutLocation(DataInput input) throws IOException {
|
private Expr readExprWithoutLocation(VarDataInput input) throws IOException {
|
||||||
byte type = input.readByte();
|
int type = input.readUnsigned();
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case 0: {
|
case 0: {
|
||||||
BinaryExpr expr = new BinaryExpr();
|
BinaryExpr expr = new BinaryExpr();
|
||||||
expr.setOperation(binaryOperations[input.readByte()]);
|
expr.setOperation(binaryOperations[input.readUnsigned()]);
|
||||||
byte valueType = input.readByte();
|
int valueType = input.readUnsigned();
|
||||||
expr.setType(valueType > 0 ? OperationType.values()[valueType] : null);
|
expr.setType(valueType > 0 ? OperationType.values()[valueType - 1] : null);
|
||||||
expr.setFirstOperand(readExpr(input));
|
expr.setFirstOperand(readExpr(input));
|
||||||
expr.setSecondOperand(readExpr(input));
|
expr.setSecondOperand(readExpr(input));
|
||||||
return expr;
|
return expr;
|
||||||
}
|
}
|
||||||
case 1: {
|
case 1: {
|
||||||
UnaryExpr expr = new UnaryExpr();
|
UnaryExpr expr = new UnaryExpr();
|
||||||
expr.setOperation(unaryOperations[input.readByte()]);
|
expr.setOperation(unaryOperations[input.readUnsigned()]);
|
||||||
byte valueType = input.readByte();
|
int valueType = input.readUnsigned();
|
||||||
expr.setType(valueType > 0 ? OperationType.values()[valueType] : null);
|
expr.setType(valueType > 0 ? OperationType.values()[valueType - 1] : null);
|
||||||
expr.setOperand(readExpr(input));
|
expr.setOperand(readExpr(input));
|
||||||
return expr;
|
return expr;
|
||||||
}
|
}
|
||||||
|
@ -874,12 +845,12 @@ public class AstIO {
|
||||||
}
|
}
|
||||||
case 4: {
|
case 4: {
|
||||||
ConstantExpr expr = new ConstantExpr();
|
ConstantExpr expr = new ConstantExpr();
|
||||||
expr.setValue(input.readInt());
|
expr.setValue(input.readSigned());
|
||||||
return expr;
|
return expr;
|
||||||
}
|
}
|
||||||
case 5: {
|
case 5: {
|
||||||
ConstantExpr expr = new ConstantExpr();
|
ConstantExpr expr = new ConstantExpr();
|
||||||
expr.setValue(input.readLong());
|
expr.setValue(input.readSignedLong());
|
||||||
return expr;
|
return expr;
|
||||||
}
|
}
|
||||||
case 6: {
|
case 6: {
|
||||||
|
@ -894,28 +865,28 @@ public class AstIO {
|
||||||
}
|
}
|
||||||
case 8: {
|
case 8: {
|
||||||
ConstantExpr expr = new ConstantExpr();
|
ConstantExpr expr = new ConstantExpr();
|
||||||
expr.setValue(input.readUTF());
|
expr.setValue(input.read());
|
||||||
return expr;
|
return expr;
|
||||||
}
|
}
|
||||||
case 9: {
|
case 9: {
|
||||||
ConstantExpr expr = new ConstantExpr();
|
ConstantExpr expr = new ConstantExpr();
|
||||||
expr.setValue(ValueType.parse(symbolTable.at(input.readInt())));
|
expr.setValue(ValueType.parse(symbolTable.at(input.readUnsigned())));
|
||||||
return expr;
|
return expr;
|
||||||
}
|
}
|
||||||
case 10: {
|
case 10: {
|
||||||
VariableExpr expr = new VariableExpr();
|
VariableExpr expr = new VariableExpr();
|
||||||
expr.setIndex(input.readShort());
|
expr.setIndex(input.readUnsigned());
|
||||||
return expr;
|
return expr;
|
||||||
}
|
}
|
||||||
case 11: {
|
case 11: {
|
||||||
SubscriptExpr expr = new SubscriptExpr();
|
SubscriptExpr expr = new SubscriptExpr();
|
||||||
expr.setArray(readExpr(input));
|
expr.setArray(readExpr(input));
|
||||||
expr.setIndex(readExpr(input));
|
expr.setIndex(readExpr(input));
|
||||||
expr.setType(ArrayType.values()[input.readByte()]);
|
expr.setType(ArrayType.values()[input.readUnsigned()]);
|
||||||
return expr;
|
return expr;
|
||||||
}
|
}
|
||||||
case 12: {
|
case 12: {
|
||||||
UnwrapArrayExpr expr = new UnwrapArrayExpr(ArrayType.values()[input.readByte()]);
|
UnwrapArrayExpr expr = new UnwrapArrayExpr(ArrayType.values()[input.readUnsigned()]);
|
||||||
expr.setArray(readExpr(input));
|
expr.setArray(readExpr(input));
|
||||||
return expr;
|
return expr;
|
||||||
}
|
}
|
||||||
|
@ -929,55 +900,55 @@ public class AstIO {
|
||||||
return parseInvocationExpr(InvocationType.DYNAMIC, input);
|
return parseInvocationExpr(InvocationType.DYNAMIC, input);
|
||||||
case 17: {
|
case 17: {
|
||||||
QualificationExpr expr = new QualificationExpr();
|
QualificationExpr expr = new QualificationExpr();
|
||||||
String className = symbolTable.at(input.readInt());
|
String className = symbolTable.at(input.readUnsigned());
|
||||||
String fieldName = symbolTable.at(input.readInt());
|
String fieldName = symbolTable.at(input.readUnsigned());
|
||||||
expr.setField(new FieldReference(className, fieldName));
|
expr.setField(new FieldReference(className, fieldName));
|
||||||
return expr;
|
return expr;
|
||||||
}
|
}
|
||||||
case 18: {
|
case 18: {
|
||||||
QualificationExpr expr = new QualificationExpr();
|
QualificationExpr expr = new QualificationExpr();
|
||||||
expr.setQualified(readExpr(input));
|
expr.setQualified(readExpr(input));
|
||||||
String className = symbolTable.at(input.readInt());
|
String className = symbolTable.at(input.readUnsigned());
|
||||||
String fieldName = symbolTable.at(input.readInt());
|
String fieldName = symbolTable.at(input.readUnsigned());
|
||||||
expr.setField(new FieldReference(className, fieldName));
|
expr.setField(new FieldReference(className, fieldName));
|
||||||
return expr;
|
return expr;
|
||||||
}
|
}
|
||||||
case 19: {
|
case 19: {
|
||||||
NewExpr expr = new NewExpr();
|
NewExpr expr = new NewExpr();
|
||||||
expr.setConstructedClass(symbolTable.at(input.readInt()));
|
expr.setConstructedClass(symbolTable.at(input.readUnsigned()));
|
||||||
return expr;
|
return expr;
|
||||||
}
|
}
|
||||||
case 20: {
|
case 20: {
|
||||||
NewArrayExpr expr = new NewArrayExpr();
|
NewArrayExpr expr = new NewArrayExpr();
|
||||||
expr.setLength(readExpr(input));
|
expr.setLength(readExpr(input));
|
||||||
expr.setType(ValueType.parse(symbolTable.at(input.readInt())));
|
expr.setType(ValueType.parse(symbolTable.at(input.readUnsigned())));
|
||||||
return expr;
|
return expr;
|
||||||
}
|
}
|
||||||
case 21: {
|
case 21: {
|
||||||
NewMultiArrayExpr expr = new NewMultiArrayExpr();
|
NewMultiArrayExpr expr = new NewMultiArrayExpr();
|
||||||
int dimensionCount = input.readByte();
|
int dimensionCount = input.readUnsigned();
|
||||||
for (int i = 0; i < dimensionCount; ++i) {
|
for (int i = 0; i < dimensionCount; ++i) {
|
||||||
expr.getDimensions().add(readExpr(input));
|
expr.getDimensions().add(readExpr(input));
|
||||||
}
|
}
|
||||||
expr.setType(ValueType.parse(symbolTable.at(input.readInt())));
|
expr.setType(ValueType.parse(symbolTable.at(input.readUnsigned())));
|
||||||
return expr;
|
return expr;
|
||||||
}
|
}
|
||||||
case 22: {
|
case 22: {
|
||||||
InstanceOfExpr expr = new InstanceOfExpr();
|
InstanceOfExpr expr = new InstanceOfExpr();
|
||||||
expr.setExpr(readExpr(input));
|
expr.setExpr(readExpr(input));
|
||||||
expr.setType(ValueType.parse(symbolTable.at(input.readInt())));
|
expr.setType(ValueType.parse(symbolTable.at(input.readUnsigned())));
|
||||||
return expr;
|
return expr;
|
||||||
}
|
}
|
||||||
case 23: {
|
case 23: {
|
||||||
CastExpr expr = new CastExpr();
|
CastExpr expr = new CastExpr();
|
||||||
expr.setTarget(ValueType.parse(symbolTable.at(input.readInt())));
|
expr.setTarget(ValueType.parse(symbolTable.at(input.readUnsigned())));
|
||||||
expr.setValue(readExpr(input));
|
expr.setValue(readExpr(input));
|
||||||
return expr;
|
return expr;
|
||||||
}
|
}
|
||||||
case 24: {
|
case 24: {
|
||||||
PrimitiveCastExpr expr = new PrimitiveCastExpr();
|
PrimitiveCastExpr expr = new PrimitiveCastExpr();
|
||||||
expr.setSource(OperationType.values()[input.readByte()]);
|
expr.setSource(OperationType.values()[input.readUnsigned()]);
|
||||||
expr.setTarget(OperationType.values()[input.readByte()]);
|
expr.setTarget(OperationType.values()[input.readUnsigned()]);
|
||||||
expr.setValue(readExpr(input));
|
expr.setValue(readExpr(input));
|
||||||
return expr;
|
return expr;
|
||||||
}
|
}
|
||||||
|
@ -986,17 +957,14 @@ public class AstIO {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private InvocationExpr parseInvocationExpr(InvocationType invocationType, DataInput input) throws IOException {
|
private InvocationExpr parseInvocationExpr(InvocationType invocationType, VarDataInput input) throws IOException {
|
||||||
InvocationExpr expr = new InvocationExpr();
|
InvocationExpr expr = new InvocationExpr();
|
||||||
expr.setType(invocationType);
|
expr.setType(invocationType);
|
||||||
String className = symbolTable.at(input.readInt());
|
String className = symbolTable.at(input.readUnsigned());
|
||||||
MethodDescriptor method = methodDescriptorCache.computeIfAbsent(symbolTable.at(input.readInt()),
|
String signature = symbolTable.at(input.readUnsigned());
|
||||||
MethodDescriptor::parse);
|
MethodReference methodRef = referenceCache.getCached(className, MethodDescriptor.parse(signature));
|
||||||
MethodReference methodRef = methodReferenceCache
|
|
||||||
.computeIfAbsent(className, k -> new HashMap<>())
|
|
||||||
.computeIfAbsent(method, k -> new MethodReference(className, k));
|
|
||||||
expr.setMethod(methodRef);
|
expr.setMethod(methodRef);
|
||||||
int argCount = input.readShort();
|
int argCount = input.readUnsigned();
|
||||||
for (int i = 0; i < argCount; ++i) {
|
for (int i = 0; i < argCount; ++i) {
|
||||||
expr.getArguments().add(readExpr(input));
|
expr.getArguments().add(readExpr(input));
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,9 +17,6 @@ package org.teavm.cache;
|
||||||
|
|
||||||
import java.io.BufferedInputStream;
|
import java.io.BufferedInputStream;
|
||||||
import java.io.BufferedOutputStream;
|
import java.io.BufferedOutputStream;
|
||||||
import java.io.DataInput;
|
|
||||||
import java.io.DataInputStream;
|
|
||||||
import java.io.DataOutputStream;
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
|
@ -57,7 +54,7 @@ public class DiskMethodNodeCache implements MethodNodeCache {
|
||||||
File file = getMethodFile(methodReference, false);
|
File file = getMethodFile(methodReference, false);
|
||||||
if (file.exists()) {
|
if (file.exists()) {
|
||||||
try (InputStream stream = new BufferedInputStream(new FileInputStream(file))) {
|
try (InputStream stream = new BufferedInputStream(new FileInputStream(file))) {
|
||||||
DataInput input = new DataInputStream(stream);
|
VarDataInput input = new VarDataInput(stream);
|
||||||
if (!checkIfDependenciesChanged(input, cacheStatus)) {
|
if (!checkIfDependenciesChanged(input, cacheStatus)) {
|
||||||
RegularMethodNode node = astIO.read(input, methodReference);
|
RegularMethodNode node = astIO.read(input, methodReference);
|
||||||
ControlFlowEntry[] cfg = astIO.readControlFlow(input);
|
ControlFlowEntry[] cfg = astIO.readControlFlow(input);
|
||||||
|
@ -89,7 +86,7 @@ public class DiskMethodNodeCache implements MethodNodeCache {
|
||||||
File file = getMethodFile(methodReference, true);
|
File file = getMethodFile(methodReference, true);
|
||||||
if (file.exists()) {
|
if (file.exists()) {
|
||||||
try (InputStream stream = new BufferedInputStream(new FileInputStream(file))) {
|
try (InputStream stream = new BufferedInputStream(new FileInputStream(file))) {
|
||||||
DataInput input = new DataInputStream(stream);
|
VarDataInput input = new VarDataInput(stream);
|
||||||
if (!checkIfDependenciesChanged(input, cacheStatus)) {
|
if (!checkIfDependenciesChanged(input, cacheStatus)) {
|
||||||
item.node = astIO.readAsync(input, methodReference);
|
item.node = astIO.readAsync(input, methodReference);
|
||||||
}
|
}
|
||||||
|
@ -101,10 +98,10 @@ public class DiskMethodNodeCache implements MethodNodeCache {
|
||||||
return item.node;
|
return item.node;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean checkIfDependenciesChanged(DataInput input, CacheStatus cacheStatus) throws IOException {
|
private boolean checkIfDependenciesChanged(VarDataInput input, CacheStatus cacheStatus) throws IOException {
|
||||||
int depCount = input.readShort();
|
int depCount = input.readUnsigned();
|
||||||
for (int i = 0; i < depCount; ++i) {
|
for (int i = 0; i < depCount; ++i) {
|
||||||
String depClass = input.readUTF();
|
String depClass = input.read();
|
||||||
if (cacheStatus.isStaleClass(depClass)) {
|
if (cacheStatus.isStaleClass(depClass)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -125,10 +122,10 @@ public class DiskMethodNodeCache implements MethodNodeCache {
|
||||||
for (MethodReference method : newMethods) {
|
for (MethodReference method : newMethods) {
|
||||||
File file = getMethodFile(method, true);
|
File file = getMethodFile(method, true);
|
||||||
Item item = cache.get(method);
|
Item item = cache.get(method);
|
||||||
try (DataOutputStream output = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(file)))) {
|
try (VarDataOutput output = new VarDataOutput(new BufferedOutputStream(new FileOutputStream(file)))) {
|
||||||
output.writeShort(item.dependencies.length);
|
output.writeUnsigned(item.dependencies.length);
|
||||||
for (String dependency : item.dependencies) {
|
for (String dependency : item.dependencies) {
|
||||||
output.writeUTF(dependency);
|
output.write(dependency);
|
||||||
}
|
}
|
||||||
astIO.write(output, item.entry.method);
|
astIO.write(output, item.entry.method);
|
||||||
astIO.write(output, item.entry.cfg);
|
astIO.write(output, item.entry.cfg);
|
||||||
|
@ -137,10 +134,10 @@ public class DiskMethodNodeCache implements MethodNodeCache {
|
||||||
for (MethodReference method : newAsyncMethods) {
|
for (MethodReference method : newAsyncMethods) {
|
||||||
File file = getMethodFile(method, true);
|
File file = getMethodFile(method, true);
|
||||||
AsyncItem item = asyncCache.get(method);
|
AsyncItem item = asyncCache.get(method);
|
||||||
try (DataOutputStream output = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(file)))) {
|
try (VarDataOutput output = new VarDataOutput(new BufferedOutputStream(new FileOutputStream(file)))) {
|
||||||
output.writeShort(item.dependencies.length);
|
output.writeUnsigned(item.dependencies.length);
|
||||||
for (String dependency : item.dependencies) {
|
for (String dependency : item.dependencies) {
|
||||||
output.writeUTF(dependency);
|
output.write(dependency);
|
||||||
}
|
}
|
||||||
astIO.writeAsync(output, item.node);
|
astIO.writeAsync(output, item.node);
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,11 +15,16 @@
|
||||||
*/
|
*/
|
||||||
package org.teavm.cache;
|
package org.teavm.cache;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
import org.teavm.ast.AsyncMethodNode;
|
import org.teavm.ast.AsyncMethodNode;
|
||||||
|
import org.teavm.ast.ControlFlowEntry;
|
||||||
|
import org.teavm.ast.RegularMethodNode;
|
||||||
import org.teavm.model.MethodReference;
|
import org.teavm.model.MethodReference;
|
||||||
|
|
||||||
public class InMemoryMethodNodeCache implements MethodNodeCache {
|
public class InMemoryMethodNodeCache implements MethodNodeCache {
|
||||||
|
@ -27,6 +32,11 @@ public class InMemoryMethodNodeCache implements MethodNodeCache {
|
||||||
private Map<MethodReference, RegularItem> newItems = new HashMap<>();
|
private Map<MethodReference, RegularItem> newItems = new HashMap<>();
|
||||||
private Map<MethodReference, AsyncItem> asyncCache = new HashMap<>();
|
private Map<MethodReference, AsyncItem> asyncCache = new HashMap<>();
|
||||||
private Map<MethodReference, AsyncItem> newAsyncItems = new HashMap<>();
|
private Map<MethodReference, AsyncItem> newAsyncItems = new HashMap<>();
|
||||||
|
private AstIO io;
|
||||||
|
|
||||||
|
public InMemoryMethodNodeCache(InMemorySymbolTable symbolTable, InMemorySymbolTable fileSymbolTable) {
|
||||||
|
io = new AstIO(symbolTable, fileSymbolTable);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AstCacheEntry get(MethodReference methodReference, CacheStatus cacheStatus) {
|
public AstCacheEntry get(MethodReference methodReference, CacheStatus cacheStatus) {
|
||||||
|
@ -39,7 +49,14 @@ public class InMemoryMethodNodeCache implements MethodNodeCache {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return item.entry;
|
VarDataInput input = new VarDataInput(new ByteArrayInputStream(item.entry));
|
||||||
|
try {
|
||||||
|
ControlFlowEntry[] cfg = io.readControlFlow(input);
|
||||||
|
RegularMethodNode ast = io.read(input, methodReference);
|
||||||
|
return new AstCacheEntry(ast, cfg);
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -58,7 +75,12 @@ public class InMemoryMethodNodeCache implements MethodNodeCache {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return item.node;
|
VarDataInput input = new VarDataInput(new ByteArrayInputStream(item.node));
|
||||||
|
try {
|
||||||
|
return io.readAsync(input, methodReference);
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -85,22 +107,37 @@ public class InMemoryMethodNodeCache implements MethodNodeCache {
|
||||||
newAsyncItems.clear();
|
newAsyncItems.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
static final class RegularItem {
|
final class RegularItem {
|
||||||
final AstCacheEntry entry;
|
final byte[] entry;
|
||||||
final String[] dependencies;
|
final String[] dependencies;
|
||||||
|
|
||||||
RegularItem(AstCacheEntry entry, String[] dependencies) {
|
RegularItem(AstCacheEntry entry, String[] dependencies) {
|
||||||
this.entry = entry;
|
try {
|
||||||
|
ByteArrayOutputStream output = new ByteArrayOutputStream();
|
||||||
|
VarDataOutput data = new VarDataOutput(output);
|
||||||
|
io.write(data, entry.cfg);
|
||||||
|
io.write(data, entry.method);
|
||||||
|
this.entry = output.toByteArray();
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
this.dependencies = dependencies;
|
this.dependencies = dependencies;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static final class AsyncItem {
|
final class AsyncItem {
|
||||||
final AsyncMethodNode node;
|
final byte[] node;
|
||||||
final String[] dependencies;
|
final String[] dependencies;
|
||||||
|
|
||||||
AsyncItem(AsyncMethodNode node, String[] dependencies) {
|
AsyncItem(AsyncMethodNode node, String[] dependencies) {
|
||||||
this.node = node;
|
try {
|
||||||
|
ByteArrayOutputStream output = new ByteArrayOutputStream();
|
||||||
|
VarDataOutput data = new VarDataOutput(output);
|
||||||
|
io.writeAsync(data, node);
|
||||||
|
this.node = output.toByteArray();
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
this.dependencies = dependencies;
|
this.dependencies = dependencies;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,9 +29,11 @@ import org.teavm.model.ProgramCache;
|
||||||
public class InMemoryProgramCache implements ProgramCache {
|
public class InMemoryProgramCache implements ProgramCache {
|
||||||
private Map<MethodReference, Item> cache = new HashMap<>();
|
private Map<MethodReference, Item> cache = new HashMap<>();
|
||||||
private Map<MethodReference, Item> newItems = new HashMap<>();
|
private Map<MethodReference, Item> newItems = new HashMap<>();
|
||||||
private InMemorySymbolTable symbolTable = new InMemorySymbolTable();
|
private ProgramIO io;
|
||||||
private InMemorySymbolTable fileSymbolTable = new InMemorySymbolTable();
|
|
||||||
private ProgramIO io = new ProgramIO(new InMemorySymbolTable(), new InMemorySymbolTable());
|
public InMemoryProgramCache(InMemorySymbolTable symbolTable, InMemorySymbolTable fileSymbolTable) {
|
||||||
|
io = new ProgramIO(symbolTable, fileSymbolTable);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Program get(MethodReference method, CacheStatus cacheStatus) {
|
public Program get(MethodReference method, CacheStatus cacheStatus) {
|
||||||
|
@ -78,8 +80,6 @@ public class InMemoryProgramCache implements ProgramCache {
|
||||||
public void invalidate() {
|
public void invalidate() {
|
||||||
cache.clear();
|
cache.clear();
|
||||||
newItems.clear();
|
newItems.clear();
|
||||||
symbolTable.invalidate();
|
|
||||||
fileSymbolTable.invalidate();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static final class Item {
|
static final class Item {
|
||||||
|
|
|
@ -20,7 +20,7 @@ import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
class InMemorySymbolTable implements SymbolTable {
|
public class InMemorySymbolTable implements SymbolTable {
|
||||||
private List<String> symbols = new ArrayList<>();
|
private List<String> symbols = new ArrayList<>();
|
||||||
private Map<String, Integer> indexes = new HashMap<>();
|
private Map<String, Integer> indexes = new HashMap<>();
|
||||||
|
|
||||||
|
|
|
@ -106,7 +106,7 @@ public class ProgramIO {
|
||||||
for (int i = 0; i < program.variableCount(); ++i) {
|
for (int i = 0; i < program.variableCount(); ++i) {
|
||||||
Variable var = program.variableAt(i);
|
Variable var = program.variableAt(i);
|
||||||
data.writeUnsigned(var.getRegister());
|
data.writeUnsigned(var.getRegister());
|
||||||
data.write(var.getDebugName() != null ? var.getDebugName() : "");
|
data.write(var.getDebugName());
|
||||||
}
|
}
|
||||||
for (int i = 0; i < program.basicBlockCount(); ++i) {
|
for (int i = 0; i < program.basicBlockCount(); ++i) {
|
||||||
BasicBlock basicBlock = program.basicBlockAt(i);
|
BasicBlock basicBlock = program.basicBlockAt(i);
|
||||||
|
@ -159,9 +159,6 @@ public class ProgramIO {
|
||||||
Variable var = program.createVariable();
|
Variable var = program.createVariable();
|
||||||
var.setRegister(data.readUnsigned());
|
var.setRegister(data.readUnsigned());
|
||||||
var.setDebugName(referenceCache.getCached(data.read()));
|
var.setDebugName(referenceCache.getCached(data.read()));
|
||||||
if (var.getDebugName().isEmpty()) {
|
|
||||||
var.setDebugName(null);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
for (int i = 0; i < basicBlockCount; ++i) {
|
for (int i = 0; i < basicBlockCount; ++i) {
|
||||||
program.createBasicBlock();
|
program.createBasicBlock();
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
*/
|
*/
|
||||||
package org.teavm.cache;
|
package org.teavm.cache;
|
||||||
|
|
||||||
|
import java.io.EOFException;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
|
||||||
|
@ -33,6 +34,9 @@ public class VarDataInput {
|
||||||
int b;
|
int b;
|
||||||
do {
|
do {
|
||||||
b = input.read();
|
b = input.read();
|
||||||
|
if (b < 0) {
|
||||||
|
throw new EOFException();
|
||||||
|
}
|
||||||
value |= (b & DATA) << pos;
|
value |= (b & DATA) << pos;
|
||||||
pos += 7;
|
pos += 7;
|
||||||
} while ((b & NEXT) != 0);
|
} while ((b & NEXT) != 0);
|
||||||
|
@ -41,7 +45,7 @@ public class VarDataInput {
|
||||||
|
|
||||||
public int readSigned() throws IOException {
|
public int readSigned() throws IOException {
|
||||||
int value = readUnsigned();
|
int value = readUnsigned();
|
||||||
return (value & 1) == 0 ? (value >> 1) : -(value >> 1);
|
return (value & 1) == 0 ? (value >>> 1) : -(value >>> 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
public long readUnsignedLong() throws IOException {
|
public long readUnsignedLong() throws IOException {
|
||||||
|
@ -50,6 +54,9 @@ public class VarDataInput {
|
||||||
int b;
|
int b;
|
||||||
do {
|
do {
|
||||||
b = input.read();
|
b = input.read();
|
||||||
|
if (b < 0) {
|
||||||
|
throw new EOFException();
|
||||||
|
}
|
||||||
value |= ((long) b & DATA) << pos;
|
value |= ((long) b & DATA) << pos;
|
||||||
pos += 7;
|
pos += 7;
|
||||||
} while ((b & NEXT) != 0);
|
} while ((b & NEXT) != 0);
|
||||||
|
@ -91,6 +98,10 @@ public class VarDataInput {
|
||||||
|
|
||||||
public String read() throws IOException {
|
public String read() throws IOException {
|
||||||
int sz = readUnsigned();
|
int sz = readUnsigned();
|
||||||
|
if (sz == 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
sz--;
|
||||||
char[] chars = new char[sz];
|
char[] chars = new char[sz];
|
||||||
for (int i = 0; i < sz; ++i) {
|
for (int i = 0; i < sz; ++i) {
|
||||||
chars[i] = (char) readUnsigned();
|
chars[i] = (char) readUnsigned();
|
||||||
|
|
|
@ -15,10 +15,11 @@
|
||||||
*/
|
*/
|
||||||
package org.teavm.cache;
|
package org.teavm.cache;
|
||||||
|
|
||||||
|
import java.io.Closeable;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
|
|
||||||
public class VarDataOutput {
|
public class VarDataOutput implements Closeable {
|
||||||
private static final int DATA = 0x7F;
|
private static final int DATA = 0x7F;
|
||||||
private static final int NEXT = 0x80;
|
private static final int NEXT = 0x80;
|
||||||
private OutputStream output;
|
private OutputStream output;
|
||||||
|
@ -76,9 +77,18 @@ public class VarDataOutput {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void write(String s) throws IOException {
|
public void write(String s) throws IOException {
|
||||||
writeUnsigned(s.length());
|
if (s == null) {
|
||||||
|
writeUnsigned(0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
writeUnsigned(s.length() + 1);
|
||||||
for (int i = 0; i < s.length(); ++i) {
|
for (int i = 0; i < s.length(); ++i) {
|
||||||
writeUnsigned(s.charAt(i));
|
writeUnsigned(s.charAt(i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close() throws IOException {
|
||||||
|
output.close();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,6 +48,7 @@ import org.teavm.cache.AstCacheEntry;
|
||||||
import org.teavm.cache.CacheStatus;
|
import org.teavm.cache.CacheStatus;
|
||||||
import org.teavm.cache.InMemoryMethodNodeCache;
|
import org.teavm.cache.InMemoryMethodNodeCache;
|
||||||
import org.teavm.cache.InMemoryProgramCache;
|
import org.teavm.cache.InMemoryProgramCache;
|
||||||
|
import org.teavm.cache.InMemorySymbolTable;
|
||||||
import org.teavm.callgraph.CallGraph;
|
import org.teavm.callgraph.CallGraph;
|
||||||
import org.teavm.dependency.FastDependencyAnalyzer;
|
import org.teavm.dependency.FastDependencyAnalyzer;
|
||||||
import org.teavm.diagnostics.DefaultProblemTextConsumer;
|
import org.teavm.diagnostics.DefaultProblemTextConsumer;
|
||||||
|
@ -236,6 +237,10 @@ public class IncrementalTest {
|
||||||
final Set<MethodReference> updatedMethods = new HashSet<>();
|
final Set<MethodReference> updatedMethods = new HashSet<>();
|
||||||
boolean capturing;
|
boolean capturing;
|
||||||
|
|
||||||
|
CapturingMethodNodeCache() {
|
||||||
|
super(new InMemorySymbolTable(), new InMemorySymbolTable());
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void store(MethodReference methodReference, AstCacheEntry node, Supplier<String[]> dependencies) {
|
public void store(MethodReference methodReference, AstCacheEntry node, Supplier<String[]> dependencies) {
|
||||||
super.store(methodReference, node, dependencies);
|
super.store(methodReference, node, dependencies);
|
||||||
|
@ -257,6 +262,10 @@ public class IncrementalTest {
|
||||||
final Set<MethodReference> updatedMethods = new HashSet<>();
|
final Set<MethodReference> updatedMethods = new HashSet<>();
|
||||||
boolean capturing;
|
boolean capturing;
|
||||||
|
|
||||||
|
CapturingProgramCache() {
|
||||||
|
super(new InMemorySymbolTable(), new InMemorySymbolTable());
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void store(MethodReference method, Program program, Supplier<String[]> dependencies) {
|
public void store(MethodReference method, Program program, Supplier<String[]> dependencies) {
|
||||||
super.store(method, program, dependencies);
|
super.store(method, program, dependencies);
|
||||||
|
|
|
@ -69,6 +69,7 @@ import org.eclipse.jetty.websocket.servlet.WebSocketServletFactory;
|
||||||
import org.teavm.backend.javascript.JavaScriptTarget;
|
import org.teavm.backend.javascript.JavaScriptTarget;
|
||||||
import org.teavm.cache.InMemoryMethodNodeCache;
|
import org.teavm.cache.InMemoryMethodNodeCache;
|
||||||
import org.teavm.cache.InMemoryProgramCache;
|
import org.teavm.cache.InMemoryProgramCache;
|
||||||
|
import org.teavm.cache.InMemorySymbolTable;
|
||||||
import org.teavm.cache.MemoryCachedClassReaderSource;
|
import org.teavm.cache.MemoryCachedClassReaderSource;
|
||||||
import org.teavm.debugging.information.DebugInformation;
|
import org.teavm.debugging.information.DebugInformation;
|
||||||
import org.teavm.debugging.information.DebugInformationBuilder;
|
import org.teavm.debugging.information.DebugInformationBuilder;
|
||||||
|
@ -136,6 +137,8 @@ public class CodeServlet extends HttpServlet {
|
||||||
private List<DevServerListener> listeners = new ArrayList<>();
|
private List<DevServerListener> listeners = new ArrayList<>();
|
||||||
private HttpClient httpClient;
|
private HttpClient httpClient;
|
||||||
private WebSocketClient wsClient = new WebSocketClient();
|
private WebSocketClient wsClient = new WebSocketClient();
|
||||||
|
private InMemorySymbolTable symbolTable = new InMemorySymbolTable();
|
||||||
|
private InMemorySymbolTable fileSymbolTable = new InMemorySymbolTable();
|
||||||
|
|
||||||
public CodeServlet(String mainClass, String[] classPath) {
|
public CodeServlet(String mainClass, String[] classPath) {
|
||||||
this.mainClass = mainClass;
|
this.mainClass = mainClass;
|
||||||
|
@ -223,6 +226,8 @@ public class CodeServlet extends HttpServlet {
|
||||||
astCache.invalidate();
|
astCache.invalidate();
|
||||||
programCache.invalidate();
|
programCache.invalidate();
|
||||||
classSource.invalidate();
|
classSource.invalidate();
|
||||||
|
symbolTable.invalidate();
|
||||||
|
fileSymbolTable.invalidate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -702,8 +707,8 @@ public class CodeServlet extends HttpServlet {
|
||||||
watcher = new FileSystemWatcher(classPath);
|
watcher = new FileSystemWatcher(classPath);
|
||||||
|
|
||||||
classSource = new MemoryCachedClassReaderSource();
|
classSource = new MemoryCachedClassReaderSource();
|
||||||
astCache = new InMemoryMethodNodeCache();
|
astCache = new InMemoryMethodNodeCache(symbolTable, fileSymbolTable);
|
||||||
programCache = new InMemoryProgramCache();
|
programCache = new InMemoryProgramCache(symbolTable, fileSymbolTable);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void shutdownBuilder() {
|
private void shutdownBuilder() {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user