Refactoring: reordering methods to usage places

This commit is contained in:
Denis Zharkov
2014-07-09 11:41:20 +04:00
committed by Alexander Udalov
parent ebfd257408
commit 69d8d07a05
3 changed files with 116 additions and 114 deletions
@@ -47,80 +47,6 @@ public class BoxingInterpreter extends OptimizationBasicInterpreter {
}
private static boolean isProgressionClass(String internalClassName) {
return RangeCodegenUtil.isRangeOrProgression(buildFqNameByInternal(internalClassName));
}
/**
* e.g. for "kotlin/IntRange" it returns "Int"
*
* @param progressionClassInternalName
* @return
* @throws java.lang.AssertionError if progressionClassInternalName is not progression class internal name
*/
@NotNull
private static String getValuesTypeOfProgressionClass(String progressionClassInternalName) {
PrimitiveType type = RangeCodegenUtil.getPrimitiveRangeOrProgressionElementType(
buildFqNameByInternal(progressionClassInternalName)
);
assert type != null : "type should be not null";
return type.getTypeName().asString();
}
private static boolean isWrapperClassName(@NotNull String internalClassName) {
return JvmPrimitiveType.isWrapperClassName(
buildFqNameByInternal(internalClassName)
);
}
@NotNull
private static FqName buildFqNameByInternal(@NotNull String internalClassName) {
return new FqName(Type.getObjectType(internalClassName).getClassName());
}
private static boolean isWrapperClassNameOrNumber(@NotNull String internalClassName) {
return isWrapperClassName(internalClassName) || internalClassName.equals(Type.getInternalName(Number.class));
}
private static boolean isUnboxingMethodName(@NotNull String name) {
return UNBOXING_METHOD_NAMES.contains(name);
}
private static boolean isUnboxing(@NotNull AbstractInsnNode insn) {
if (insn.getOpcode() != Opcodes.INVOKEVIRTUAL) return false;
MethodInsnNode methodInsn = (MethodInsnNode) insn;
return isWrapperClassNameOrNumber(methodInsn.owner) && isUnboxingMethodName(methodInsn.name);
}
private static boolean isBoxing(@NotNull AbstractInsnNode insn) {
if (insn.getOpcode() != Opcodes.INVOKESTATIC) return false;
MethodInsnNode methodInsnNode = (MethodInsnNode) insn;
return isWrapperClassName(methodInsnNode.owner) && "valueOf".equals(methodInsnNode.name);
}
private static boolean isIteratorMethodCallOfProgression(
@NotNull AbstractInsnNode insn, @NotNull List<? extends BasicValue> values
) {
return (insn.getOpcode() == Opcodes.INVOKEINTERFACE &&
values.get(0).getType() != null &&
isProgressionClass(values.get(0).getType().getInternalName()) &&
"iterator".equals(((MethodInsnNode) insn).name));
}
private static boolean isNextMethodCallOfProgressionIterator(
@NotNull AbstractInsnNode insn, @NotNull List<? extends BasicValue> values
) {
return (insn.getOpcode() == Opcodes.INVOKEINTERFACE &&
values.get(0) instanceof ProgressionIteratorBasicValue &&
"next".equals(((MethodInsnNode) insn).name));
}
private final Map<Integer, BoxedBasicValue> boxingPlaces = new HashMap<Integer, BoxedBasicValue>();
private final InsnList insnList;
@@ -188,10 +114,78 @@ public class BoxingInterpreter extends OptimizationBasicInterpreter {
return value;
}
private static boolean isExactValue(@NotNull BasicValue value) {
return value instanceof ProgressionIteratorBasicValue ||
value instanceof BoxedBasicValue ||
(value.getType() != null && isProgressionClass(value.getType().getInternalName()));
private static boolean isWrapperClassNameOrNumber(@NotNull String internalClassName) {
return isWrapperClassName(internalClassName) || internalClassName.equals(Type.getInternalName(Number.class));
}
private static boolean isWrapperClassName(@NotNull String internalClassName) {
return JvmPrimitiveType.isWrapperClassName(
buildFqNameByInternal(internalClassName)
);
}
@NotNull
private static FqName buildFqNameByInternal(@NotNull String internalClassName) {
return new FqName(Type.getObjectType(internalClassName).getClassName());
}
private static boolean isUnboxing(@NotNull AbstractInsnNode insn) {
if (insn.getOpcode() != Opcodes.INVOKEVIRTUAL) return false;
MethodInsnNode methodInsn = (MethodInsnNode) insn;
return isWrapperClassNameOrNumber(methodInsn.owner) && isUnboxingMethodName(methodInsn.name);
}
private static boolean isUnboxingMethodName(@NotNull String name) {
return UNBOXING_METHOD_NAMES.contains(name);
}
private static boolean isBoxing(@NotNull AbstractInsnNode insn) {
if (insn.getOpcode() != Opcodes.INVOKESTATIC) return false;
MethodInsnNode methodInsnNode = (MethodInsnNode) insn;
return isWrapperClassName(methodInsnNode.owner) && "valueOf".equals(methodInsnNode.name);
}
private static boolean isNextMethodCallOfProgressionIterator(
@NotNull AbstractInsnNode insn, @NotNull List<? extends BasicValue> values
) {
return (insn.getOpcode() == Opcodes.INVOKEINTERFACE &&
values.get(0) instanceof ProgressionIteratorBasicValue &&
"next".equals(((MethodInsnNode) insn).name));
}
private static boolean isIteratorMethodCallOfProgression(
@NotNull AbstractInsnNode insn, @NotNull List<? extends BasicValue> values
) {
return (insn.getOpcode() == Opcodes.INVOKEINTERFACE &&
values.get(0).getType() != null &&
isProgressionClass(values.get(0).getType().getInternalName()) &&
"iterator".equals(((MethodInsnNode) insn).name));
}
private static boolean isProgressionClass(String internalClassName) {
return RangeCodegenUtil.isRangeOrProgression(buildFqNameByInternal(internalClassName));
}
/**
* e.g. for "kotlin/IntRange" it returns "Int"
*
* @param progressionClassInternalName
* @return
* @throws java.lang.AssertionError if progressionClassInternalName is not progression class internal name
*/
@NotNull
private static String getValuesTypeOfProgressionClass(String progressionClassInternalName) {
PrimitiveType type = RangeCodegenUtil.getPrimitiveRangeOrProgressionElementType(
buildFqNameByInternal(progressionClassInternalName)
);
assert type != null : "type should be not null";
return type.getTypeName().asString();
}
@Override
@@ -203,6 +197,12 @@ public class BoxingInterpreter extends OptimizationBasicInterpreter {
return super.unaryOperation(insn, value);
}
private static boolean isExactValue(@NotNull BasicValue value) {
return value instanceof ProgressionIteratorBasicValue ||
value instanceof BoxedBasicValue ||
(value.getType() != null && isProgressionClass(value.getType().getInternalName()));
}
@Override
@NotNull
public BasicValue merge(@NotNull BasicValue v, @NotNull BasicValue w) {
@@ -47,27 +47,6 @@ class RedundantBoxingInterpreter extends BoxingInterpreter {
super(insnList);
}
private void markValueAsDirty(@NotNull BoxedBasicValue value) {
values.remove(value);
}
private static void addAssociatedInsn(@NotNull BoxedBasicValue value, @NotNull AbstractInsnNode insn) {
if (value.isSafeToRemove()) {
value.addInsn(insn);
}
}
private void processOperationWithBoxedValue(@Nullable BasicValue value, @NotNull AbstractInsnNode insnNode) {
if (value instanceof BoxedBasicValue) {
if (UNSAFE_OPERATIONS_OPCODES.contains(insnNode.getOpcode())) {
markValueAsDirty((BoxedBasicValue) value);
}
else {
addAssociatedInsn((BoxedBasicValue) value, insnNode);
}
}
}
@Override
public BasicValue binaryOperation(
@NotNull AbstractInsnNode insn,
@@ -170,6 +149,27 @@ class RedundantBoxingInterpreter extends BoxingInterpreter {
values.merge(v, w);
}
private void processOperationWithBoxedValue(@Nullable BasicValue value, @NotNull AbstractInsnNode insnNode) {
if (value instanceof BoxedBasicValue) {
if (UNSAFE_OPERATIONS_OPCODES.contains(insnNode.getOpcode())) {
markValueAsDirty((BoxedBasicValue) value);
}
else {
addAssociatedInsn((BoxedBasicValue) value, insnNode);
}
}
}
private void markValueAsDirty(@NotNull BoxedBasicValue value) {
values.remove(value);
}
private static void addAssociatedInsn(@NotNull BoxedBasicValue value, @NotNull AbstractInsnNode insn) {
if (value.isSafeToRemove()) {
value.addInsn(insn);
}
}
@NotNull
public RedundantBoxedValuesCollection getCandidatesBoxedValues() {
return values;
@@ -40,9 +40,11 @@ public class RedundantBoxingMethodTransformer extends MethodTransformer {
@Override
public void transform(@NotNull String internalClassName, @NotNull MethodNode node) {
RedundantBoxingInterpreter interpreter = new RedundantBoxingInterpreter(node.instructions);
Analyzer<BasicValue> analyzer = new Analyzer<BasicValue>(interpreter);
Frame<BasicValue>[] frames = runAnalyzer(
new Analyzer<BasicValue>(interpreter),
internalClassName, node
);
Frame<BasicValue>[] frames = runAnalyzer(analyzer, internalClassName, node);
RedundantBoxedValuesCollection valuesToOptimize = interpreter.getCandidatesBoxedValues();
if (!valuesToOptimize.isEmpty()) {
@@ -59,19 +61,6 @@ public class RedundantBoxingMethodTransformer extends MethodTransformer {
super.transform(internalClassName, node);
}
private static void adaptLocalVariableTableForBoxedValues(@NotNull MethodNode node, @NotNull Frame<BasicValue>[] frames) {
for (LocalVariableNode localVariableNode : node.localVariables) {
if (Type.getType(localVariableNode.desc).getSort() != Type.OBJECT) {
continue;
}
for (BasicValue value : getValuesStoredOrLoadedToVariable(localVariableNode, node, frames)) {
if (value == null || !(value instanceof BoxedBasicValue) || !((BoxedBasicValue) value).isSafeToRemove()) continue;
localVariableNode.desc = ((BoxedBasicValue) value).getPrimitiveType().getDescriptor();
}
}
}
private static void removeValuesClashingWithVariables(
@NotNull RedundantBoxedValuesCollection values,
@NotNull MethodNode node,
@@ -128,6 +117,19 @@ public class RedundantBoxingMethodTransformer extends MethodTransformer {
return needToRepeat;
}
private static void adaptLocalVariableTableForBoxedValues(@NotNull MethodNode node, @NotNull Frame<BasicValue>[] frames) {
for (LocalVariableNode localVariableNode : node.localVariables) {
if (Type.getType(localVariableNode.desc).getSort() != Type.OBJECT) {
continue;
}
for (BasicValue value : getValuesStoredOrLoadedToVariable(localVariableNode, node, frames)) {
if (value == null || !(value instanceof BoxedBasicValue) || !((BoxedBasicValue) value).isSafeToRemove()) continue;
localVariableNode.desc = ((BoxedBasicValue) value).getPrimitiveType().getDescriptor();
}
}
}
@NotNull
private static List<BasicValue> getValuesStoredOrLoadedToVariable(
@NotNull LocalVariableNode localVariableNode,