Added unsafe opcodes check for boxed values

This commit is contained in:
Denis Zharkov
2014-07-01 14:33:39 +04:00
committed by Alexander Udalov
parent 485ac3f809
commit b2eaac4468
2 changed files with 37 additions and 7 deletions
@@ -100,14 +100,16 @@ public class BoxingInterpreter extends OptimizationBasicInterpreter {
}
return boxingPlaces.get(index);
} else if (isUnboxing(insn) &&
values.get(0) instanceof BoxedBasicValue &&
value.getType().equals(((BoxedBasicValue) values.get(0)).getPrimitiveType())) {
}
else if (isUnboxing(insn) &&
values.get(0) instanceof BoxedBasicValue &&
value.getType().equals(((BoxedBasicValue) values.get(0)).getPrimitiveType())) {
BoxedBasicValue boxedBasicValue = (BoxedBasicValue) values.get(0);
boxedBasicValue.addInsn(insn);
boxedBasicValue.setWasUnboxed(true);
} else {
}
else {
for (BasicValue arg : values) {
if (arg instanceof BoxedBasicValue) {
onMethodCallWithBoxedValue((BoxedBasicValue) arg);
@@ -16,7 +16,9 @@
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.org.objectweb.asm.Opcodes;
import org.jetbrains.org.objectweb.asm.tree.AbstractInsnNode;
import org.jetbrains.org.objectweb.asm.tree.InsnList;
@@ -29,12 +31,29 @@ import java.util.List;
import java.util.Set;
class RedundantBoxingInterpreter extends BoxingInterpreter {
private static final ImmutableSet<Integer> unsafeOperationsOpcodes;
static {
ImmutableSet.Builder<Integer> unsafeOperationsOpcodesBuilder = ImmutableSet.builder();
unsafeOperationsOpcodesBuilder.add(
Opcodes.AASTORE, Opcodes.PUTFIELD, Opcodes.PUTSTATIC, Opcodes.ARETURN
);
unsafeOperationsOpcodes = unsafeOperationsOpcodesBuilder.build();
}
private final Set<BoxedBasicValue> candidatesBoxedValues = new HashSet<BoxedBasicValue>();
RedundantBoxingInterpreter(InsnList insnList) {
super(insnList);
}
private void checkIfUnsafeOperationWithBoxed(@Nullable BasicValue value, @NotNull AbstractInsnNode insnNode) {
if (value instanceof BoxedBasicValue && unsafeOperationsOpcodes.contains(insnNode.getOpcode())) {
markAsDirty((BoxedBasicValue) value);
}
}
@Override
public BasicValue binaryOperation(
@NotNull AbstractInsnNode insn,
@@ -42,13 +61,22 @@ class RedundantBoxingInterpreter extends BoxingInterpreter {
@NotNull BasicValue value2
) throws AnalyzerException {
if (insn.getOpcode() == Opcodes.PUTFIELD && value2 instanceof BoxedBasicValue) {
markAsDirty((BoxedBasicValue) value2);
}
checkIfUnsafeOperationWithBoxed(value2, insn);
return super.binaryOperation(insn, value1, value2);
}
@Override
public BasicValue ternaryOperation(
@NotNull AbstractInsnNode insn,
@NotNull BasicValue value1, @NotNull BasicValue value2, @NotNull BasicValue value3
) throws AnalyzerException {
checkIfUnsafeOperationWithBoxed(value3, insn);
return super.ternaryOperation(insn, value1, value2, value3);
}
@Override
protected boolean isAllowedUnaryOperationWithBoxed(int opcode) {
return opcode == Opcodes.CHECKCAST;