initial
This commit is contained in:
committed by
Alexander Udalov
parent
2cb2b05b38
commit
1ecca9f40b
+54
@@ -0,0 +1,54 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2014 JetBrains s.r.o.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.jet.codegen.optimization;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
import org.jetbrains.jet.codegen.ClassBuilder;
|
||||||
|
import org.jetbrains.jet.codegen.DelegatingClassBuilder;
|
||||||
|
import org.jetbrains.jet.lang.resolve.java.diagnostics.JvmDeclarationOrigin;
|
||||||
|
import org.jetbrains.org.objectweb.asm.MethodVisitor;
|
||||||
|
|
||||||
|
public class OptimizationClassBuilder extends DelegatingClassBuilder {
|
||||||
|
private final ClassBuilder delegate;
|
||||||
|
|
||||||
|
public OptimizationClassBuilder(@NotNull ClassBuilder delegate) {
|
||||||
|
this.delegate = delegate;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public ClassBuilder getDelegate() {
|
||||||
|
return delegate;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public MethodVisitor newMethod(
|
||||||
|
@NotNull JvmDeclarationOrigin origin,
|
||||||
|
int access,
|
||||||
|
@NotNull String name,
|
||||||
|
@NotNull String desc,
|
||||||
|
@Nullable String signature,
|
||||||
|
@Nullable String[] exceptions
|
||||||
|
) {
|
||||||
|
return new OptimizationMethodVisitor(
|
||||||
|
super.newMethod(origin, access, name, desc, signature, exceptions),
|
||||||
|
access, name, desc, signature, exceptions
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
+53
@@ -0,0 +1,53 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2014 JetBrains s.r.o.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.jet.codegen.optimization;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.jet.codegen.ClassBuilder;
|
||||||
|
import org.jetbrains.jet.codegen.ClassBuilderFactory;
|
||||||
|
import org.jetbrains.jet.codegen.ClassBuilderMode;
|
||||||
|
import org.jetbrains.jet.lang.resolve.java.diagnostics.JvmDeclarationOrigin;
|
||||||
|
|
||||||
|
public class OptimizationClassBuilderFactory implements ClassBuilderFactory {
|
||||||
|
private final ClassBuilderFactory delegate;
|
||||||
|
|
||||||
|
public OptimizationClassBuilderFactory(ClassBuilderFactory delegate) {
|
||||||
|
this.delegate = delegate;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public ClassBuilderMode getClassBuilderMode() {
|
||||||
|
return delegate.getClassBuilderMode();
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public ClassBuilder newClassBuilder(@NotNull JvmDeclarationOrigin origin) {
|
||||||
|
return new OptimizationClassBuilder(delegate.newClassBuilder(origin));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String asText(ClassBuilder builder) {
|
||||||
|
return delegate.asText(((OptimizationClassBuilder) builder).getDelegate());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public byte[] asBytes(ClassBuilder builder) {
|
||||||
|
return delegate.asBytes(((OptimizationClassBuilder) builder).getDelegate());
|
||||||
|
}
|
||||||
|
}
|
||||||
+62
@@ -0,0 +1,62 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2014 JetBrains s.r.o.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.jet.codegen.optimization;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
import org.jetbrains.jet.codegen.inline.InlineCodegenUtil;
|
||||||
|
import org.jetbrains.jet.codegen.optimization.boxing.RedundantBoxingMethodTransformer;
|
||||||
|
import org.jetbrains.jet.codegen.optimization.transformer.MethodTransformer;
|
||||||
|
import org.jetbrains.org.objectweb.asm.MethodVisitor;
|
||||||
|
import org.jetbrains.org.objectweb.asm.tree.LocalVariableNode;
|
||||||
|
import org.jetbrains.org.objectweb.asm.tree.MethodNode;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
public class OptimizationMethodVisitor extends MethodVisitor {
|
||||||
|
private final MethodTransformer methodTransformer = new RedundantBoxingMethodTransformer(null);
|
||||||
|
private final MethodNode methodNode;
|
||||||
|
private final MethodVisitor delegate;
|
||||||
|
|
||||||
|
public OptimizationMethodVisitor(
|
||||||
|
@NotNull MethodVisitor delegate,
|
||||||
|
int access,
|
||||||
|
@NotNull String name,
|
||||||
|
@NotNull String desc,
|
||||||
|
@Nullable String signature,
|
||||||
|
@Nullable String[] exceptions
|
||||||
|
) {
|
||||||
|
super(OptimizationUtils.API);
|
||||||
|
this.delegate = delegate;
|
||||||
|
this.methodNode = new MethodNode(access, name, desc, signature, exceptions);
|
||||||
|
this.methodNode.localVariables = new ArrayList<LocalVariableNode>(5);
|
||||||
|
this.mv = InlineCodegenUtil.wrapWithMaxLocalCalc(methodNode);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitEnd() {
|
||||||
|
if (methodNode.maxLocals <= 0 || methodNode.maxStack <= 0) {
|
||||||
|
mv.visitMaxs(-1, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
super.visitEnd();
|
||||||
|
|
||||||
|
methodTransformer.transform("fake", methodNode);
|
||||||
|
|
||||||
|
methodNode.accept(delegate);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2014 JetBrains s.r.o.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.jet.codegen.optimization;
|
||||||
|
|
||||||
|
import org.jetbrains.org.objectweb.asm.Opcodes;
|
||||||
|
|
||||||
|
public class OptimizationUtils {
|
||||||
|
public final static int API = Opcodes.ASM5;
|
||||||
|
}
|
||||||
+72
@@ -0,0 +1,72 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2014 JetBrains s.r.o.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.jet.codegen.optimization.boxing;
|
||||||
|
|
||||||
|
import org.jetbrains.org.objectweb.asm.Type;
|
||||||
|
import org.jetbrains.org.objectweb.asm.tree.AbstractInsnNode;
|
||||||
|
import org.jetbrains.org.objectweb.asm.tree.analysis.BasicValue;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
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 boolean wasUnboxed = false;
|
||||||
|
|
||||||
|
public BoxedBasicValue(Type type, Type boxedType, AbstractInsnNode insnNode) {
|
||||||
|
super(type);
|
||||||
|
this.boxedType = boxedType;
|
||||||
|
associatedInsns.add(insnNode);
|
||||||
|
boxingInsn = insnNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
|
||||||
|
BoxedBasicValue that = (BoxedBasicValue) o;
|
||||||
|
|
||||||
|
if (!getType().equals(that.getType())) return false;
|
||||||
|
|
||||||
|
return (boxingInsn == ((BoxedBasicValue) o).boxingInsn);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<AbstractInsnNode> getAssociatedInsns() {
|
||||||
|
return new ArrayList<AbstractInsnNode>(associatedInsns);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addInsn(AbstractInsnNode insnNode) {
|
||||||
|
associatedInsns.add(insnNode);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Type getBoxedType() {
|
||||||
|
return boxedType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean wasUnboxed() {
|
||||||
|
return wasUnboxed;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setWasUnboxed(boolean wasUnboxed) {
|
||||||
|
this.wasUnboxed = wasUnboxed;
|
||||||
|
}
|
||||||
|
}
|
||||||
+162
@@ -0,0 +1,162 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2014 JetBrains s.r.o.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.jet.codegen.optimization.boxing;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
import org.jetbrains.jet.codegen.optimization.common.OptimizationBasicInterpreter;
|
||||||
|
import org.jetbrains.org.objectweb.asm.Opcodes;
|
||||||
|
import org.jetbrains.org.objectweb.asm.tree.AbstractInsnNode;
|
||||||
|
import org.jetbrains.org.objectweb.asm.tree.InsnList;
|
||||||
|
import org.jetbrains.org.objectweb.asm.tree.MethodInsnNode;
|
||||||
|
import org.jetbrains.org.objectweb.asm.tree.analysis.AnalyzerException;
|
||||||
|
import org.jetbrains.org.objectweb.asm.tree.analysis.BasicValue;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
class RedundantBoxingInterpreter extends OptimizationBasicInterpreter {
|
||||||
|
private final Map<Integer, BoxedBasicValue> boxingPlaces = new HashMap<Integer, BoxedBasicValue>();
|
||||||
|
private final Set<BoxedBasicValue> candidatesBoxedValues = new HashSet<BoxedBasicValue>();
|
||||||
|
private final InsnList insnList;
|
||||||
|
|
||||||
|
RedundantBoxingInterpreter(InsnList insnList) {
|
||||||
|
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 isUnboxingMethod(@NotNull String name) {
|
||||||
|
return name.endsWith("Value");
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean isUnboxing(@NotNull AbstractInsnNode insn) {
|
||||||
|
if (insn.getOpcode() != Opcodes.INVOKEVIRTUAL) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
MethodInsnNode methodInsn = (MethodInsnNode) insn;
|
||||||
|
|
||||||
|
return isClassBox(methodInsn.owner) && isUnboxingMethod(methodInsn.name);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean isBoxing(@NotNull AbstractInsnNode insn) {
|
||||||
|
if (insn.getOpcode() != Opcodes.INVOKESTATIC) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
MethodInsnNode methodInsnNode = (MethodInsnNode) insn;
|
||||||
|
|
||||||
|
return isClassBox(methodInsnNode.owner) && methodInsnNode.name.equals("valueOf");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Nullable
|
||||||
|
public BasicValue naryOperation(@NotNull AbstractInsnNode insn, @NotNull List<? extends BasicValue> values) throws AnalyzerException {
|
||||||
|
BasicValue value = super.naryOperation(insn, values);
|
||||||
|
|
||||||
|
if (isBoxing(insn)) {
|
||||||
|
int index = insnList.indexOf(insn);
|
||||||
|
if (!boxingPlaces.containsKey(index)) {
|
||||||
|
BoxedBasicValue boxedBasicValue = new BoxedBasicValue(value.getType(), values.get(0).getType(), insn);
|
||||||
|
candidatesBoxedValues.add(boxedBasicValue);
|
||||||
|
boxingPlaces.put(index, boxedBasicValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
return boxingPlaces.get(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isUnboxing(insn) &&
|
||||||
|
values.get(0) instanceof BoxedBasicValue &&
|
||||||
|
value.getType().equals(((BoxedBasicValue) values.get(0)).getBoxedType())) {
|
||||||
|
BoxedBasicValue boxedBasicValue = (BoxedBasicValue) values.get(0);
|
||||||
|
boxedBasicValue.addInsn(insn);
|
||||||
|
boxedBasicValue.setWasUnboxed(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Nullable
|
||||||
|
public BasicValue unaryOperation(@NotNull AbstractInsnNode insn, @NotNull BasicValue value) throws AnalyzerException {
|
||||||
|
if (insn.getOpcode() == Opcodes.CHECKCAST && value instanceof BoxedBasicValue) {
|
||||||
|
((BoxedBasicValue) value).addInsn(insn);
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
return super.unaryOperation(insn, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@NotNull
|
||||||
|
public BasicValue copyOperation(@NotNull AbstractInsnNode insn, @NotNull BasicValue value) throws AnalyzerException {
|
||||||
|
if (value instanceof BoxedBasicValue) {
|
||||||
|
candidatesBoxedValues.remove(value);
|
||||||
|
return new BasicValue(value.getType());
|
||||||
|
}
|
||||||
|
|
||||||
|
return super.copyOperation(insn, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@NotNull
|
||||||
|
public BasicValue merge(@NotNull BasicValue v, @NotNull BasicValue w) {
|
||||||
|
if (v instanceof BoxedBasicValue && w instanceof BoxedBasicValue && v == w) {
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (v instanceof BoxedBasicValue) {
|
||||||
|
candidatesBoxedValues.remove(v);
|
||||||
|
v = new BasicValue(v.getType());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (w instanceof BoxedBasicValue) {
|
||||||
|
candidatesBoxedValues.remove(w);
|
||||||
|
w = new BasicValue(w.getType());
|
||||||
|
}
|
||||||
|
|
||||||
|
return super.merge(v, w);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public List<BoxedBasicValue> getCandidatesBoxedValues() {
|
||||||
|
List<BoxedBasicValue> result = new ArrayList<BoxedBasicValue>();
|
||||||
|
|
||||||
|
for (BoxedBasicValue value : candidatesBoxedValues) {
|
||||||
|
if (value.wasUnboxed()) {
|
||||||
|
result.add(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
+52
@@ -0,0 +1,52 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2014 JetBrains s.r.o.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.jet.codegen.optimization.boxing;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.jet.codegen.optimization.transformer.MethodTransformer;
|
||||||
|
import org.jetbrains.org.objectweb.asm.tree.AbstractInsnNode;
|
||||||
|
import org.jetbrains.org.objectweb.asm.tree.MethodNode;
|
||||||
|
import org.jetbrains.org.objectweb.asm.tree.analysis.Analyzer;
|
||||||
|
import org.jetbrains.org.objectweb.asm.tree.analysis.BasicValue;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class RedundantBoxingMethodTransformer extends MethodTransformer {
|
||||||
|
public RedundantBoxingMethodTransformer(MethodTransformer methodTransformer) {
|
||||||
|
super(methodTransformer);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void transform(@NotNull String owner, @NotNull MethodNode node) {
|
||||||
|
for (BoxedBasicValue value : analyze(owner, node)) {
|
||||||
|
for (AbstractInsnNode insnNode : value.getAssociatedInsns()) {
|
||||||
|
node.instructions.remove(insnNode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
super.transform(owner, node);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static List<BoxedBasicValue> analyze(@NotNull String owner, @NotNull MethodNode node) {
|
||||||
|
RedundantBoxingInterpreter interpreter = new RedundantBoxingInterpreter(node.instructions);
|
||||||
|
Analyzer<BasicValue> analyzer = new Analyzer<BasicValue>(interpreter);
|
||||||
|
|
||||||
|
runAnalyzer(analyzer, owner, node);
|
||||||
|
|
||||||
|
return interpreter.getCandidatesBoxedValues();
|
||||||
|
}
|
||||||
|
}
|
||||||
+84
@@ -0,0 +1,84 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2014 JetBrains s.r.o.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.jet.codegen.optimization.common;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
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.LdcInsnNode;
|
||||||
|
import org.jetbrains.org.objectweb.asm.tree.analysis.AnalyzerException;
|
||||||
|
import org.jetbrains.org.objectweb.asm.tree.analysis.BasicInterpreter;
|
||||||
|
import org.jetbrains.org.objectweb.asm.tree.analysis.BasicValue;
|
||||||
|
|
||||||
|
public class OptimizationBasicInterpreter extends BasicInterpreter {
|
||||||
|
private static final BasicValue MIXED_VALUE = new BasicValue(Type.getObjectType("#"));
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Nullable
|
||||||
|
public BasicValue newValue(@Nullable Type type) {
|
||||||
|
if (type == null) {
|
||||||
|
return super.newValue(null);
|
||||||
|
}
|
||||||
|
if (type.getSort() == Type.OBJECT) {
|
||||||
|
return new BasicValue(type);
|
||||||
|
}
|
||||||
|
|
||||||
|
return super.newValue(type);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BasicValue newOperation(@NotNull AbstractInsnNode insn) throws AnalyzerException {
|
||||||
|
if (insn.getOpcode() == Opcodes.LDC) {
|
||||||
|
Object cst = ((LdcInsnNode) insn).cst;
|
||||||
|
|
||||||
|
if (cst instanceof Long) {
|
||||||
|
return BasicValue.LONG_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cst instanceof Boolean ||
|
||||||
|
cst instanceof Integer ||
|
||||||
|
cst instanceof Short ||
|
||||||
|
cst instanceof Byte ||
|
||||||
|
cst instanceof Character) {
|
||||||
|
return BasicValue.INT_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cst instanceof Float) {
|
||||||
|
return BasicValue.FLOAT_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cst instanceof Double) {
|
||||||
|
return BasicValue.DOUBLE_VALUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return super.newOperation(insn);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public BasicValue merge(
|
||||||
|
@NotNull BasicValue v, @NotNull BasicValue w
|
||||||
|
) {
|
||||||
|
if (!v.equals(w)) {
|
||||||
|
return MIXED_VALUE;
|
||||||
|
}
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
}
|
||||||
+51
@@ -0,0 +1,51 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2014 JetBrains s.r.o.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.jet.codegen.optimization.transformer;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.org.objectweb.asm.tree.MethodNode;
|
||||||
|
import org.jetbrains.org.objectweb.asm.tree.analysis.Analyzer;
|
||||||
|
import org.jetbrains.org.objectweb.asm.tree.analysis.AnalyzerException;
|
||||||
|
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;
|
||||||
|
|
||||||
|
protected MethodTransformer(MethodTransformer methodTransformer) {
|
||||||
|
this.methodTransformer = methodTransformer;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static <V extends Value> Frame<V>[] runAnalyzer(
|
||||||
|
@NotNull Analyzer<V> analyzer,
|
||||||
|
@NotNull String owner,
|
||||||
|
@NotNull MethodNode node
|
||||||
|
) {
|
||||||
|
try {
|
||||||
|
return analyzer.analyze(owner, node);
|
||||||
|
}
|
||||||
|
catch (AnalyzerException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void transform(@NotNull String owner, @NotNull MethodNode methodNode) {
|
||||||
|
if (methodTransformer != null) {
|
||||||
|
methodTransformer.transform(owner, methodNode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user