Minor, fixes after review

This commit is contained in:
Denis Zharkov
2014-06-30 17:40:47 +04:00
committed by Alexander Udalov
parent 3dea4bc07d
commit 485ac3f809
5 changed files with 109 additions and 64 deletions
@@ -2601,7 +2601,9 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
}
private void generateExpressionWithNullFallback(@NotNull JetExpression expression, @NotNull Label ifnull) {
expression = JetPsiUtil.deparenthesize(expression);
Type type = expressionType(expression);
if (expression instanceof JetSafeQualifiedExpression && !isPrimitive(type)) {
StackValue value = generateSafeQualifiedExpression((JetSafeQualifiedExpression) expression, ifnull);
value.put(type, v);
@@ -2612,11 +2614,10 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
}
private StackValue generateSafeQualifiedExpression(@NotNull JetSafeQualifiedExpression expression, @NotNull Label ifnull) {
JetExpression receiver = JetPsiUtil.deparenthesize(expression.getReceiverExpression());
JetExpression receiver = expression.getReceiverExpression();
JetExpression selector = expression.getSelectorExpression();
Type receiverType = expressionType(receiver);
assert receiver != null : "receiver should be not null: " + expression.getText();
generateExpressionWithNullFallback(receiver, ifnull);
if (isPrimitive(receiverType)) {
@@ -2631,13 +2632,14 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
@Override
public StackValue visitSafeQualifiedExpression(@NotNull JetSafeQualifiedExpression expression, StackValue unused) {
Label ifnull = new Label();
Label end = new Label();
Type type = boxType(expressionType(expression));
StackValue value = generateSafeQualifiedExpression(expression, ifnull);
value.put(type, v);
if (!isPrimitive(expressionType(expression.getReceiverExpression()))) {
Label end = new Label();
v.goTo(end);
v.mark(ifnull);
v.pop();
@@ -2845,13 +2847,13 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
}
private StackValue generateElvis(JetBinaryExpression expression) {
JetExpression left = JetPsiUtil.deparenthesize(expression.getLeft());
JetExpression left = expression.getLeft();
Type exprType = expressionType(expression);
Type leftType = expressionType(left);
Label ifNull = new Label();
Label end = new Label();
assert left != null : "left expression in elvis should be not null: " + expression.getText();
generateExpressionWithNullFallback(left, ifNull);
@@ -2864,6 +2866,8 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
v.ifnull(ifNull);
StackValue.onStack(leftType).put(exprType, v);
Label end = new Label();
v.goTo(end);
v.mark(ifNull);
@@ -16,6 +16,7 @@
package org.jetbrains.jet.codegen.optimization.boxing;
import org.jetbrains.jet.codegen.AsmUtil;
import org.jetbrains.org.objectweb.asm.Type;
import org.jetbrains.org.objectweb.asm.tree.AbstractInsnNode;
import org.jetbrains.org.objectweb.asm.tree.analysis.BasicValue;
@@ -28,12 +29,12 @@ import java.util.Set;
public class BoxedBasicValue extends BasicValue {
private final Set<AbstractInsnNode> associatedInsns = new HashSet<AbstractInsnNode>();
private final AbstractInsnNode boxingInsn;
private final Type boxedType;
private final Type primitiveType;
private boolean wasUnboxed = false;
public BoxedBasicValue(Type type, Type boxedType, AbstractInsnNode insnNode) {
super(type);
this.boxedType = boxedType;
public BoxedBasicValue(Type primitiveType, AbstractInsnNode insnNode) {
super(AsmUtil.boxType(primitiveType));
this.primitiveType = primitiveType;
associatedInsns.add(insnNode);
boxingInsn = insnNode;
}
@@ -58,8 +59,8 @@ public class BoxedBasicValue extends BasicValue {
associatedInsns.add(insnNode);
}
public Type getBoxedType() {
return boxedType;
public Type getPrimitiveType() {
return primitiveType;
}
public boolean wasUnboxed() {
@@ -16,10 +16,14 @@
package org.jetbrains.jet.codegen.optimization.boxing;
import com.google.common.collect.ImmutableSet;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.codegen.AsmUtil;
import org.jetbrains.jet.codegen.optimization.common.OptimizationBasicInterpreter;
import org.jetbrains.jet.lang.resolve.java.JvmPrimitiveType;
import org.jetbrains.org.objectweb.asm.Opcodes;
import org.jetbrains.org.objectweb.asm.Type;
import org.jetbrains.org.objectweb.asm.tree.AbstractInsnNode;
import org.jetbrains.org.objectweb.asm.tree.InsnList;
import org.jetbrains.org.objectweb.asm.tree.MethodInsnNode;
@@ -31,6 +35,18 @@ import java.util.List;
import java.util.Map;
public class BoxingInterpreter extends OptimizationBasicInterpreter {
private static final ImmutableSet<String> wrappersClassNames;
static {
ImmutableSet.Builder<String> wrappersClassesBuilder = ImmutableSet.builder();
for (JvmPrimitiveType primitiveType : JvmPrimitiveType.values()) {
wrappersClassesBuilder.add(AsmUtil.internalNameByFqNameWithoutInnerClasses(primitiveType.getWrapperFqName()));
}
wrappersClassNames = wrappersClassesBuilder.build();
}
private final Map<Integer, BoxedBasicValue> boxingPlaces = new HashMap<Integer, BoxedBasicValue>();
private final InsnList insnList;
@@ -38,24 +54,15 @@ public class BoxingInterpreter extends OptimizationBasicInterpreter {
this.insnList = insnList;
}
private static boolean isClassBox(@NotNull String owner) {
if (!owner.startsWith("java/lang/")) {
return false;
}
String className = owner.substring("java/lang/".length());
return (className.equals("Integer") ||
className.equals("Double") ||
className.equals("Long") ||
className.equals("Char") ||
className.equals("Byte") ||
className.equals("Boolean")) ||
className.endsWith("Number");
private static boolean isWrapperClassName(@NotNull String owner) {
return wrappersClassNames.contains(owner);
}
private static boolean isUnboxingMethod(@NotNull String name) {
private static boolean isWrapperClassNameOrNumber(@NotNull String owner) {
return isWrapperClassName(owner) || owner.equals(Type.getInternalName(Number.class));
}
private static boolean isUnboxingMethodName(@NotNull String name) {
return name.endsWith("Value");
}
@@ -66,7 +73,7 @@ public class BoxingInterpreter extends OptimizationBasicInterpreter {
MethodInsnNode methodInsn = (MethodInsnNode) insn;
return isClassBox(methodInsn.owner) && isUnboxingMethod(methodInsn.name);
return isWrapperClassNameOrNumber(methodInsn.owner) && isUnboxingMethodName(methodInsn.name);
}
private static boolean isBoxing(@NotNull AbstractInsnNode insn) {
@@ -76,7 +83,7 @@ public class BoxingInterpreter extends OptimizationBasicInterpreter {
MethodInsnNode methodInsnNode = (MethodInsnNode) insn;
return isClassBox(methodInsnNode.owner) && methodInsnNode.name.equals("valueOf");
return isWrapperClassName(methodInsnNode.owner) && methodInsnNode.name.equals("valueOf");
}
@Override
@@ -87,32 +94,30 @@ public class BoxingInterpreter extends OptimizationBasicInterpreter {
if (isBoxing(insn)) {
int index = insnList.indexOf(insn);
if (!boxingPlaces.containsKey(index)) {
BoxedBasicValue boxedBasicValue = new BoxedBasicValue(value.getType(), values.get(0).getType(), insn);
BoxedBasicValue boxedBasicValue = new BoxedBasicValue(values.get(0).getType(), insn);
onNewBoxedValue(boxedBasicValue);
boxingPlaces.put(index, boxedBasicValue);
}
return boxingPlaces.get(index);
}
if (isUnboxing(insn) &&
} else if (isUnboxing(insn) &&
values.get(0) instanceof BoxedBasicValue &&
value.getType().equals(((BoxedBasicValue) values.get(0)).getBoxedType())) {
value.getType().equals(((BoxedBasicValue) values.get(0)).getPrimitiveType())) {
BoxedBasicValue boxedBasicValue = (BoxedBasicValue) values.get(0);
boxedBasicValue.addInsn(insn);
boxedBasicValue.setWasUnboxed(true);
} else {
for (BasicValue arg : values) {
if (arg instanceof BoxedBasicValue) {
onMethodCallWithBoxedValue((BoxedBasicValue) arg);
}
}
}
return value;
}
protected void onNewBoxedValue(BoxedBasicValue value) {
}
protected boolean isAllowedUnaryOperationWithBoxed(int opcode) {
return opcode == Opcodes.CHECKCAST || opcode == Opcodes.IFNULL;
}
@Override
@Nullable
@@ -128,10 +133,37 @@ public class BoxingInterpreter extends OptimizationBasicInterpreter {
@Override
@NotNull
public BasicValue merge(@NotNull BasicValue v, @NotNull BasicValue w) {
if (v instanceof BoxedBasicValue && w instanceof BoxedBasicValue && v.equals(w)) {
if (v instanceof BoxedBasicValue && v.equals(w)) {
return v;
}
if (v instanceof BoxedBasicValue) {
onMergeFail((BoxedBasicValue) v);
v = new BasicValue(v.getType());
}
if (w instanceof BoxedBasicValue) {
onMergeFail((BoxedBasicValue) w);
w = new BasicValue(w.getType());
}
return super.merge(v, w);
}
protected void onNewBoxedValue(BoxedBasicValue value) {
}
protected void onMethodCallWithBoxedValue(BoxedBasicValue value) {
}
protected void onMergeFail(BoxedBasicValue value) {
}
protected boolean isAllowedUnaryOperationWithBoxed(int opcode) {
return opcode == Opcodes.CHECKCAST || opcode == Opcodes.IFNULL;
}
}
@@ -36,8 +36,17 @@ class RedundantBoxingInterpreter extends BoxingInterpreter {
}
@Override
protected void onNewBoxedValue(BoxedBasicValue value) {
candidatesBoxedValues.add(value);
public BasicValue binaryOperation(
@NotNull AbstractInsnNode insn,
@NotNull BasicValue value1,
@NotNull BasicValue value2
) throws AnalyzerException {
if (insn.getOpcode() == Opcodes.PUTFIELD && value2 instanceof BoxedBasicValue) {
markAsDirty((BoxedBasicValue) value2);
}
return super.binaryOperation(insn, value1, value2);
}
@Override
@@ -50,7 +59,7 @@ class RedundantBoxingInterpreter extends BoxingInterpreter {
public BasicValue copyOperation(@NotNull AbstractInsnNode insn, @NotNull BasicValue value) throws AnalyzerException {
// currently we don't allow any copy operations with boxed values
if (value instanceof BoxedBasicValue) {
candidatesBoxedValues.remove(value);
markAsDirty((BoxedBasicValue) value);
return new BasicValue(value.getType());
}
@@ -58,23 +67,22 @@ class RedundantBoxingInterpreter extends BoxingInterpreter {
}
@Override
@NotNull
public BasicValue merge(@NotNull BasicValue v, @NotNull BasicValue w) {
if (v instanceof BoxedBasicValue && w instanceof BoxedBasicValue && v == w) {
return v;
}
protected void onNewBoxedValue(BoxedBasicValue value) {
candidatesBoxedValues.add(value);
}
if (v instanceof BoxedBasicValue) {
candidatesBoxedValues.remove(v);
v = new BasicValue(v.getType());
}
private void markAsDirty(BoxedBasicValue value) {
candidatesBoxedValues.remove(value);
}
if (w instanceof BoxedBasicValue) {
candidatesBoxedValues.remove(w);
w = new BasicValue(w.getType());
}
@Override
protected void onMethodCallWithBoxedValue(BoxedBasicValue value) {
markAsDirty(value);
}
return super.merge(v, w);
@Override
protected void onMergeFail(BoxedBasicValue v) {
markAsDirty(v);
}
@NotNull
@@ -24,10 +24,10 @@ import org.jetbrains.org.objectweb.asm.tree.analysis.Frame;
import org.jetbrains.org.objectweb.asm.tree.analysis.Value;
public abstract class MethodTransformer {
private final MethodTransformer methodTransformer;
private final MethodTransformer delegate;
protected MethodTransformer(MethodTransformer methodTransformer) {
this.methodTransformer = methodTransformer;
protected MethodTransformer(MethodTransformer delegate) {
this.delegate = delegate;
}
protected static <V extends Value> Frame<V>[] runAnalyzer(
@@ -44,8 +44,8 @@ public abstract class MethodTransformer {
}
public void transform(@NotNull String owner, @NotNull MethodNode methodNode) {
if (methodTransformer != null) {
methodTransformer.transform(owner, methodNode);
if (delegate != null) {
delegate.transform(owner, methodNode);
}
}
}