Skip to content

Commit 21de67c

Browse files
author
Mikhael Bogdanov
committed
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
1 parent 387c91f commit 21de67c

File tree

5 files changed

+56
-23
lines changed

5 files changed

+56
-23
lines changed

compiler/backend/src/org/jetbrains/kotlin/codegen/inline/AnonymousObjectTransformer.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -141,12 +141,12 @@ public void visitEnd() {
141141
List<CapturedParamInfo> additionalFakeParams =
142142
extractParametersMappingAndPatchConstructor(constructor, allCapturedParamBuilder, constructorParamBuilder,
143143
transformationInfo, parentRemapper);
144-
List<MethodVisitor> deferringMethods = new ArrayList<MethodVisitor>();
144+
List<DeferredMethodVisitor> deferringMethods = new ArrayList<DeferredMethodVisitor>();
145145

146146
generateConstructorAndFields(classBuilder, allCapturedParamBuilder, constructorParamBuilder, parentRemapper, additionalFakeParams);
147147

148148
for (MethodNode next : methodsToTransform) {
149-
MethodVisitor deferringVisitor = newMethod(classBuilder, next);
149+
DeferredMethodVisitor deferringVisitor = newMethod(classBuilder, next);
150150
InlineResult funResult =
151151
inlineMethodAndUpdateGlobalResult(parentRemapper, deferringVisitor, next, allCapturedParamBuilder, false);
152152

@@ -161,7 +161,8 @@ public void visitEnd() {
161161
deferringMethods.add(deferringVisitor);
162162
}
163163

164-
for (MethodVisitor method : deferringMethods) {
164+
for (DeferredMethodVisitor method : deferringMethods) {
165+
InlineCodegenUtil.removeFinallyMarkers(method.getIntermediate());
165166
method.visitEnd();
166167
}
167168

@@ -313,6 +314,7 @@ private void generateConstructorAndFields(
313314
MethodNode intermediateMethodNode =
314315
new MethodNode(AsmUtil.NO_FLAG_PACKAGE_PRIVATE, "<init>", constructorDescriptor, null, ArrayUtil.EMPTY_STRING_ARRAY);
315316
inlineMethodAndUpdateGlobalResult(parentRemapper, intermediateMethodNode, constructor, constructorInlineBuilder, true);
317+
InlineCodegenUtil.removeFinallyMarkers(intermediateMethodNode);
316318

317319
AbstractInsnNode first = intermediateMethodNode.instructions.getFirst();
318320
final Label oldStartLabel = first instanceof LabelNode ? ((LabelNode) first).getLabel() : null;

compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InlineCodegen.java

Lines changed: 3 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -466,7 +466,9 @@ public boolean isMyLabel(@NotNull String name) {
466466
adapter, infos, ((StackValue.Local) remapper.remap(parameters.getArgsSizeOnStack() + 1).value).index
467467
);
468468
removeStaticInitializationTrigger(adapter);
469-
removeFinallyMarkers(adapter);
469+
if (!InlineCodegenUtil.isFinallyMarkerRequired(codegen.getContext())) {
470+
InlineCodegenUtil.removeFinallyMarkers(adapter);
471+
}
470472

471473
adapter.accept(new MethodBodyVisitor(codegen.v));
472474

@@ -1024,25 +1026,6 @@ private void generateAndInsertFinallyBlocks(
10241026
//processor.substituteLocalVarTable(intoNode);
10251027
}
10261028

1027-
private void removeFinallyMarkers(@NotNull MethodNode intoNode) {
1028-
if (InlineCodegenUtil.isFinallyMarkerRequired(codegen.getContext())) return;
1029-
1030-
InsnList instructions = intoNode.instructions;
1031-
AbstractInsnNode curInstr = instructions.getFirst();
1032-
while (curInstr != null) {
1033-
if (InlineCodegenUtil.isFinallyMarker(curInstr)) {
1034-
AbstractInsnNode marker = curInstr;
1035-
//just to assert
1036-
getConstant(marker.getPrevious());
1037-
curInstr = curInstr.getNext();
1038-
instructions.remove(marker.getPrevious());
1039-
instructions.remove(marker);
1040-
continue;
1041-
}
1042-
curInstr = curInstr.getNext();
1043-
}
1044-
}
1045-
10461029
@NotNull
10471030
public static SourceMapper createNestedSourceMapper(@NotNull SMAPAndMethodNode nodeAndSmap, @NotNull SourceMapper parent) {
10481031
return new NestedSourceMapper(parent, nodeAndSmap.getSortedRanges(), nodeAndSmap.getClassSMAP().getSourceInfo());

compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InlineCodegenUtil.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -466,6 +466,23 @@ else if (opcode == Opcodes.BIPUSH || opcode == Opcodes.SIPUSH) {
466466
}
467467
}
468468

469+
public static void removeFinallyMarkers(@NotNull MethodNode intoNode) {
470+
InsnList instructions = intoNode.instructions;
471+
AbstractInsnNode curInstr = instructions.getFirst();
472+
while (curInstr != null) {
473+
if (isFinallyMarker(curInstr)) {
474+
AbstractInsnNode marker = curInstr;
475+
//just to assert
476+
getConstant(marker.getPrevious());
477+
curInstr = curInstr.getNext();
478+
instructions.remove(marker.getPrevious());
479+
instructions.remove(marker);
480+
continue;
481+
}
482+
curInstr = curInstr.getNext();
483+
}
484+
}
485+
469486
public static void addInlineMarker(@NotNull InstructionAdapter v, boolean isStartNotEnd) {
470487
v.visitMethodInsn(
471488
Opcodes.INVOKESTATIC, INLINE_MARKER_CLASS_NAME,
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
inline fun test(crossinline l: () -> String) {
2+
{
3+
l()
4+
}()
5+
6+
object {
7+
val z = l() //constuctor
8+
}
9+
}
10+
11+
12+
fun box(): String {
13+
var z = "fail"
14+
test {
15+
synchronized("123") {
16+
z = "OK"
17+
z
18+
}
19+
}
20+
21+
return z
22+
}
23+
24+
// 0 finallyStart
25+
// 0 finallyEnd

compiler/tests/org/jetbrains/kotlin/codegen/BytecodeTextTestGenerated.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1247,6 +1247,12 @@ public void testAllFilesPresentInInline() throws Exception {
12471247
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/bytecodeText/inline"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true);
12481248
}
12491249

1250+
@TestMetadata("finallyMarkers.kt")
1251+
public void testFinallyMarkers() throws Exception {
1252+
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeText/inline/finallyMarkers.kt");
1253+
doTest(fileName);
1254+
}
1255+
12501256
@TestMetadata("inlineReturnsNothing1.kt")
12511257
public void testInlineReturnsNothing1() throws Exception {
12521258
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeText/inline/inlineReturnsNothing1.kt");

0 commit comments

Comments
 (0)