Keep typeRemapper in inlining context instead of hashMap for transformed types

This commit is contained in:
Michael Bogdanov
2015-12-10 15:22:23 +03:00
parent 6fb871a088
commit 9452c200a0
6 changed files with 51 additions and 31 deletions
@@ -27,10 +27,7 @@ import org.jetbrains.kotlin.codegen.state.GenerationState;
import org.jetbrains.kotlin.codegen.state.JetTypeMapper;
import org.jetbrains.org.objectweb.asm.*;
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter;
import org.jetbrains.org.objectweb.asm.tree.AbstractInsnNode;
import org.jetbrains.org.objectweb.asm.tree.FieldInsnNode;
import org.jetbrains.org.objectweb.asm.tree.MethodNode;
import org.jetbrains.org.objectweb.asm.tree.VarInsnNode;
import org.jetbrains.org.objectweb.asm.tree.*;
import java.util.*;
@@ -65,8 +62,6 @@ public class AnonymousObjectTransformer {
private final Map<String, List<String>> fieldNames = new HashMap<String, List<String>>();
private final TypeRemapper typeRemapper;
public AnonymousObjectTransformer(
@NotNull String objectInternalName,
@NotNull InliningContext inliningContext,
@@ -81,7 +76,6 @@ public class AnonymousObjectTransformer {
this.newLambdaType = newLambdaType;
reader = InlineCodegenUtil.buildClassReaderByInternalName(state, objectInternalName);
typeRemapper = new TypeRemapper(inliningContext.typeMapping);
transformationResult = InlineResult.create();
}
@@ -192,7 +186,7 @@ public class AnonymousObjectTransformer {
String oldFunReturnType = returnType.getInternalName();
String newFunReturnType = funResult.getChangedTypes().get(oldFunReturnType);
if (newFunReturnType != null) {
typeRemapper.addAdditionalMappings(oldFunReturnType, newFunReturnType);
inliningContext.typeRemapper.addAdditionalMappings(oldFunReturnType, newFunReturnType);
}
}
deferringMethods.add(deferringVisitor);
@@ -344,7 +338,7 @@ public class AnonymousObjectTransformer {
@NotNull
private ClassBuilder createClassBuilder() {
ClassBuilder classBuilder = state.getFactory().newVisitor(NO_ORIGIN, newLambdaType, inliningContext.getRoot().callElement.getContainingFile());
return new RemappingClassBuilder(classBuilder, typeRemapper);
return new RemappingClassBuilder(classBuilder, inliningContext.typeRemapper);
}
@NotNull
@@ -35,7 +35,7 @@ public class InliningContext {
public final NameGenerator nameGenerator;
public final Map<String, String> typeMapping;
public final TypeRemapper typeRemapper;
public final ReifiedTypeInliner reifedTypeInliner;
@@ -48,7 +48,7 @@ public class InliningContext {
@NotNull Map<Integer, LambdaInfo> map,
@NotNull GenerationState state,
@NotNull NameGenerator nameGenerator,
@NotNull Map<String, String> typeMapping,
@NotNull TypeRemapper typeRemapper,
@NotNull ReifiedTypeInliner reifedTypeInliner,
boolean isInliningLambda,
boolean classRegeneration
@@ -57,7 +57,7 @@ public class InliningContext {
expressionMap = map;
this.state = state;
this.nameGenerator = nameGenerator;
this.typeMapping = typeMapping;
this.typeRemapper = typeRemapper;
this.reifedTypeInliner = reifedTypeInliner;
this.isInliningLambda = isInliningLambda;
this.classRegeneration = classRegeneration;
@@ -78,13 +78,12 @@ public class InliningContext {
}
public InliningContext subInlineWithClassRegeneration(@NotNull NameGenerator generator,
@NotNull Map<String, String> additionalTypeMappings,
@NotNull Map<String, String> newTypeMappings,
@NotNull AnonymousObjectGeneration anonymousObjectGeneration
) {
Map<String, String> newTypeMappings = new HashMap<String, String>(typeMapping);
newTypeMappings.putAll(additionalTypeMappings);
return new RegeneratedClassContext(this, expressionMap, state, generator,
newTypeMappings, reifedTypeInliner, isInliningLambda, anonymousObjectGeneration);
new TypeRemapper(typeRemapper, newTypeMappings),
reifedTypeInliner, isInliningLambda, anonymousObjectGeneration);
}
public InliningContext subInline(NameGenerator generator, Map<String, String> additionalTypeMappings, boolean isInliningLambda) {
@@ -97,10 +96,8 @@ public class InliningContext {
boolean isInliningLambda,
boolean isRegeneration
) {
Map<String, String> newTypeMappings = new HashMap<String, String>(typeMapping);
newTypeMappings.putAll(additionalTypeMappings);
return new InliningContext(this, expressionMap, state, generator,
newTypeMappings, reifedTypeInliner, isInliningLambda, isRegeneration);
new TypeRemapper(typeRemapper, additionalTypeMappings), reifedTypeInliner, isInliningLambda, isRegeneration);
}
public boolean isRoot() {
@@ -78,7 +78,7 @@ public class MethodInliner {
public MethodInliner(
@NotNull MethodNode node,
@NotNull Parameters parameters,
@NotNull InliningContext parent,
@NotNull InliningContext inliningContext,
@NotNull FieldRemapper nodeRemapper,
boolean isSameModule,
@NotNull String errorPrefix,
@@ -86,12 +86,12 @@ public class MethodInliner {
) {
this.node = node;
this.parameters = parameters;
this.inliningContext = parent;
this.inliningContext = inliningContext;
this.nodeRemapper = nodeRemapper;
this.isSameModule = isSameModule;
this.errorPrefix = errorPrefix;
this.sourceMapper = sourceMapper;
this.typeMapper = parent.state.getTypeMapper();
this.typeMapper = inliningContext.state.getTypeMapper();
this.result = InlineResult.create();
}
@@ -153,8 +153,9 @@ public class MethodInliner {
final Iterator<AnonymousObjectGeneration> iterator = anonymousObjectGenerations.iterator();
final TypeRemapper remapper = TypeRemapper.createFrom(currentTypeMapping);
RemappingMethodAdapter remappingMethodAdapter = new RemappingMethodAdapter(resultNode.access, resultNode.desc, resultNode,
new TypeRemapper(currentTypeMapping));
remapper);
final int markerShift = InlineCodegenUtil.calcMarkerShift(parameters, node);
InlineAdapter lambdaInliner = new InlineAdapter(remappingMethodAdapter, parameters.getArgsSizeOnStack(), sourceMapper) {
@@ -167,7 +168,7 @@ public class MethodInliner {
//TODO: need poping of type but what to do with local funs???
String oldClassName = anonymousObjectGen.getOwnerInternalName();
String newClassName = inliningContext.nameGenerator.genLambdaClassName();
currentTypeMapping.put(oldClassName, newClassName);
remapper.addMapping(oldClassName, newClassName);
AnonymousObjectTransformer transformer =
new AnonymousObjectTransformer(oldClassName,
inliningContext
@@ -551,7 +552,7 @@ public class MethodInliner {
}
private boolean isAlreadyRegenerated(@NotNull String owner) {
return inliningContext.typeMapping.containsKey(owner);
return inliningContext.typeRemapper.hasNoAdditionalMapping(owner);
}
@Nullable
@@ -30,12 +30,12 @@ public class RegeneratedClassContext extends InliningContext {
@NotNull Map<Integer, LambdaInfo> map,
@NotNull GenerationState state,
@NotNull NameGenerator nameGenerator,
@NotNull Map<String, String> typeMapping,
@NotNull TypeRemapper typeRemapper,
@NotNull ReifiedTypeInliner reifiedTypeInliner,
boolean isInliningLambda,
@NotNull AnonymousObjectGeneration anonymousObjectGeneration
) {
super(parent, map, state, nameGenerator, typeMapping, reifiedTypeInliner, isInliningLambda, true);
super(parent, map, state, nameGenerator, typeRemapper, reifiedTypeInliner, isInliningLambda, true);
this.anonymousObjectGeneration = anonymousObjectGeneration;
}
@@ -21,7 +21,6 @@ import org.jetbrains.kotlin.codegen.context.CodegenContext;
import org.jetbrains.kotlin.codegen.state.GenerationState;
import org.jetbrains.kotlin.psi.KtElement;
import java.util.Collections;
import java.util.Map;
public class RootInliningContext extends InliningContext {
@@ -38,7 +37,7 @@ public class RootInliningContext extends InliningContext {
@NotNull String classNameToInline,
@NotNull ReifiedTypeInliner inliner
) {
super(null, map, state, nameGenerator, Collections.<String, String>emptyMap(), inliner, false, false);
super(null, map, state, nameGenerator, TypeRemapper.createEmpty(), inliner, false, false);
this.callElement = callElement;
this.startContext = startContext;
this.classNameToInline = classNameToInline;
@@ -23,14 +23,43 @@ import java.util.HashMap;
import java.util.Map;
public class TypeRemapper extends Remapper {
//typeMapping field could be changed outside through method processing
private final Map<String, String> typeMapping;
private Map<String, String> additionalMappings;
//typeMapping could be changed outside through method processing
public TypeRemapper(@NotNull Map<String, String> typeMapping) {
//typeMapping field could be changed outside through method processing
private TypeRemapper(@NotNull Map<String, String> typeMapping) {
this.typeMapping = typeMapping;
}
public TypeRemapper(@NotNull TypeRemapper remapper, @NotNull Map<String, String> newTypeMappings) {
this(createNewAndMerge(remapper, newTypeMappings));
}
public static TypeRemapper createEmpty() {
return new TypeRemapper(new HashMap<String, String>());
}
public static TypeRemapper createFrom(Map<String, String> mappings) {
return new TypeRemapper(mappings);
}
@NotNull
private static Map<String, String> createNewAndMerge(@NotNull TypeRemapper remapper, @NotNull Map<String, String> additionalTypeMappings) {
Map<String, String> map = new HashMap<String, String>(remapper.typeMapping);
map.putAll(additionalTypeMappings);
return map;
}
public void addMapping(String type, String newType) {
typeMapping.put(type, newType);
}
public boolean hasNoAdditionalMapping(String type) {
return typeMapping.containsKey(type);
}
@Override
public String map(String type) {
String newType = typeMapping.get(type);