Refactoring: reordering methods to usage places
This commit is contained in:
committed by
Alexander Udalov
parent
ebfd257408
commit
69d8d07a05
+78
-78
@@ -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) {
|
||||
|
||||
+21
-21
@@ -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;
|
||||
|
||||
+17
-15
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user