Added unsafe opcodes check for boxed values
This commit is contained in:
committed by
Alexander Udalov
parent
485ac3f809
commit
b2eaac4468
+6
-4
@@ -100,14 +100,16 @@ public class BoxingInterpreter extends OptimizationBasicInterpreter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return boxingPlaces.get(index);
|
return boxingPlaces.get(index);
|
||||||
} else if (isUnboxing(insn) &&
|
}
|
||||||
values.get(0) instanceof BoxedBasicValue &&
|
else if (isUnboxing(insn) &&
|
||||||
value.getType().equals(((BoxedBasicValue) values.get(0)).getPrimitiveType())) {
|
values.get(0) instanceof BoxedBasicValue &&
|
||||||
|
value.getType().equals(((BoxedBasicValue) values.get(0)).getPrimitiveType())) {
|
||||||
|
|
||||||
BoxedBasicValue boxedBasicValue = (BoxedBasicValue) values.get(0);
|
BoxedBasicValue boxedBasicValue = (BoxedBasicValue) values.get(0);
|
||||||
boxedBasicValue.addInsn(insn);
|
boxedBasicValue.addInsn(insn);
|
||||||
boxedBasicValue.setWasUnboxed(true);
|
boxedBasicValue.setWasUnboxed(true);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
for (BasicValue arg : values) {
|
for (BasicValue arg : values) {
|
||||||
if (arg instanceof BoxedBasicValue) {
|
if (arg instanceof BoxedBasicValue) {
|
||||||
onMethodCallWithBoxedValue((BoxedBasicValue) arg);
|
onMethodCallWithBoxedValue((BoxedBasicValue) arg);
|
||||||
|
|||||||
+31
-3
@@ -16,7 +16,9 @@
|
|||||||
|
|
||||||
package org.jetbrains.jet.codegen.optimization.boxing;
|
package org.jetbrains.jet.codegen.optimization.boxing;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableSet;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.org.objectweb.asm.Opcodes;
|
import org.jetbrains.org.objectweb.asm.Opcodes;
|
||||||
import org.jetbrains.org.objectweb.asm.tree.AbstractInsnNode;
|
import org.jetbrains.org.objectweb.asm.tree.AbstractInsnNode;
|
||||||
import org.jetbrains.org.objectweb.asm.tree.InsnList;
|
import org.jetbrains.org.objectweb.asm.tree.InsnList;
|
||||||
@@ -29,12 +31,29 @@ import java.util.List;
|
|||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
class RedundantBoxingInterpreter extends BoxingInterpreter {
|
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>();
|
private final Set<BoxedBasicValue> candidatesBoxedValues = new HashSet<BoxedBasicValue>();
|
||||||
|
|
||||||
RedundantBoxingInterpreter(InsnList insnList) {
|
RedundantBoxingInterpreter(InsnList insnList) {
|
||||||
super(insnList);
|
super(insnList);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void checkIfUnsafeOperationWithBoxed(@Nullable BasicValue value, @NotNull AbstractInsnNode insnNode) {
|
||||||
|
if (value instanceof BoxedBasicValue && unsafeOperationsOpcodes.contains(insnNode.getOpcode())) {
|
||||||
|
markAsDirty((BoxedBasicValue) value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BasicValue binaryOperation(
|
public BasicValue binaryOperation(
|
||||||
@NotNull AbstractInsnNode insn,
|
@NotNull AbstractInsnNode insn,
|
||||||
@@ -42,13 +61,22 @@ class RedundantBoxingInterpreter extends BoxingInterpreter {
|
|||||||
@NotNull BasicValue value2
|
@NotNull BasicValue value2
|
||||||
) throws AnalyzerException {
|
) throws AnalyzerException {
|
||||||
|
|
||||||
if (insn.getOpcode() == Opcodes.PUTFIELD && value2 instanceof BoxedBasicValue) {
|
checkIfUnsafeOperationWithBoxed(value2, insn);
|
||||||
markAsDirty((BoxedBasicValue) value2);
|
|
||||||
}
|
|
||||||
|
|
||||||
return super.binaryOperation(insn, value1, value2);
|
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
|
@Override
|
||||||
protected boolean isAllowedUnaryOperationWithBoxed(int opcode) {
|
protected boolean isAllowedUnaryOperationWithBoxed(int opcode) {
|
||||||
return opcode == Opcodes.CHECKCAST;
|
return opcode == Opcodes.CHECKCAST;
|
||||||
|
|||||||
Reference in New Issue
Block a user