Fix for KT-16532: Kotlin 1.1 RC - Android cross-inline synchronized won't run

Finnaly markers are used only for non-local return processing and are removed after inlining  to non-inline functions, same deletion should be performed on inlining to anonymous objects

 #KT-16532 Fixed
This commit is contained in:
Mikhael Bogdanov
2017-02-28 11:58:29 +01:00
parent 387c91f957
commit 21de67cac1
5 changed files with 56 additions and 23 deletions
@@ -141,12 +141,12 @@ public class AnonymousObjectTransformer extends ObjectTransformer<AnonymousObjec
List<CapturedParamInfo> additionalFakeParams =
extractParametersMappingAndPatchConstructor(constructor, allCapturedParamBuilder, constructorParamBuilder,
transformationInfo, parentRemapper);
List<MethodVisitor> deferringMethods = new ArrayList<MethodVisitor>();
List<DeferredMethodVisitor> deferringMethods = new ArrayList<DeferredMethodVisitor>();
generateConstructorAndFields(classBuilder, allCapturedParamBuilder, constructorParamBuilder, parentRemapper, additionalFakeParams);
for (MethodNode next : methodsToTransform) {
MethodVisitor deferringVisitor = newMethod(classBuilder, next);
DeferredMethodVisitor deferringVisitor = newMethod(classBuilder, next);
InlineResult funResult =
inlineMethodAndUpdateGlobalResult(parentRemapper, deferringVisitor, next, allCapturedParamBuilder, false);
@@ -161,7 +161,8 @@ public class AnonymousObjectTransformer extends ObjectTransformer<AnonymousObjec
deferringMethods.add(deferringVisitor);
}
for (MethodVisitor method : deferringMethods) {
for (DeferredMethodVisitor method : deferringMethods) {
InlineCodegenUtil.removeFinallyMarkers(method.getIntermediate());
method.visitEnd();
}
@@ -313,6 +314,7 @@ public class AnonymousObjectTransformer extends ObjectTransformer<AnonymousObjec
MethodNode intermediateMethodNode =
new MethodNode(AsmUtil.NO_FLAG_PACKAGE_PRIVATE, "<init>", constructorDescriptor, null, ArrayUtil.EMPTY_STRING_ARRAY);
inlineMethodAndUpdateGlobalResult(parentRemapper, intermediateMethodNode, constructor, constructorInlineBuilder, true);
InlineCodegenUtil.removeFinallyMarkers(intermediateMethodNode);
AbstractInsnNode first = intermediateMethodNode.instructions.getFirst();
final Label oldStartLabel = first instanceof LabelNode ? ((LabelNode) first).getLabel() : null;
@@ -466,7 +466,9 @@ public class InlineCodegen extends CallGenerator {
adapter, infos, ((StackValue.Local) remapper.remap(parameters.getArgsSizeOnStack() + 1).value).index
);
removeStaticInitializationTrigger(adapter);
removeFinallyMarkers(adapter);
if (!InlineCodegenUtil.isFinallyMarkerRequired(codegen.getContext())) {
InlineCodegenUtil.removeFinallyMarkers(adapter);
}
adapter.accept(new MethodBodyVisitor(codegen.v));
@@ -1024,25 +1026,6 @@ public class InlineCodegen extends CallGenerator {
//processor.substituteLocalVarTable(intoNode);
}
private void removeFinallyMarkers(@NotNull MethodNode intoNode) {
if (InlineCodegenUtil.isFinallyMarkerRequired(codegen.getContext())) return;
InsnList instructions = intoNode.instructions;
AbstractInsnNode curInstr = instructions.getFirst();
while (curInstr != null) {
if (InlineCodegenUtil.isFinallyMarker(curInstr)) {
AbstractInsnNode marker = curInstr;
//just to assert
getConstant(marker.getPrevious());
curInstr = curInstr.getNext();
instructions.remove(marker.getPrevious());
instructions.remove(marker);
continue;
}
curInstr = curInstr.getNext();
}
}
@NotNull
public static SourceMapper createNestedSourceMapper(@NotNull SMAPAndMethodNode nodeAndSmap, @NotNull SourceMapper parent) {
return new NestedSourceMapper(parent, nodeAndSmap.getSortedRanges(), nodeAndSmap.getClassSMAP().getSourceInfo());
@@ -466,6 +466,23 @@ public class InlineCodegenUtil {
}
}
public static void removeFinallyMarkers(@NotNull MethodNode intoNode) {
InsnList instructions = intoNode.instructions;
AbstractInsnNode curInstr = instructions.getFirst();
while (curInstr != null) {
if (isFinallyMarker(curInstr)) {
AbstractInsnNode marker = curInstr;
//just to assert
getConstant(marker.getPrevious());
curInstr = curInstr.getNext();
instructions.remove(marker.getPrevious());
instructions.remove(marker);
continue;
}
curInstr = curInstr.getNext();
}
}
public static void addInlineMarker(@NotNull InstructionAdapter v, boolean isStartNotEnd) {
v.visitMethodInsn(
Opcodes.INVOKESTATIC, INLINE_MARKER_CLASS_NAME,