[JVM] Force lock object in JVM synchronized implementation into local.

This fixes a performance problem in the case where the lock object
is a capture and the monitor enter/exit happens directly on
field loads. When the locking happens on field loads instead of a
local, the JVM cannot prove that locking is balanced. That has
the consequence that the code is runs very slow (always in the
interpreter).

^KT-48367 Fixed.
This commit is contained in:
Mads Ager
2021-08-24 09:46:55 +02:00
committed by Alexander Udalov
parent 9fd777cb7d
commit a12b22c04d
5 changed files with 45 additions and 2 deletions
@@ -307,6 +307,12 @@ public class FirBytecodeTextTestGenerated extends AbstractFirBytecodeTextTest {
runTest("compiler/testData/codegen/bytecodeText/kt46615.kt");
}
@Test
@TestMetadata("kt48367.kt")
public void testKt48367() throws Exception {
runTest("compiler/testData/codegen/bytecodeText/kt48367.kt");
}
@Test
@TestMetadata("kt5016.kt")
public void testKt5016() throws Exception {
+20
View File
@@ -0,0 +1,20 @@
fun foo(block: () -> String): String = block()
inline fun bar(crossinline f: () -> String) = foo { f() }
fun flaf() {
val revoked = "A"
bar {
synchronized (revoked) {
"B"
}
}
}
// The field $revoked$inlined should be loaded only once and stored in a local
// that is used for the monitor enter/exit instructions. Locking and unlocking
// directly on a field load makes it hard for the JVM to prove that locking is
// balanced which causes the code to be interpreted. See KT-48367 for details.
// 1 GETFIELD Kt48367Kt\$flaf\$\$inlined\$bar\$1.\$revoked\$inlined : Ljava/lang/String;
// 1 MONITORENTER
// 2 MONITOREXIT
@@ -295,6 +295,12 @@ public class BytecodeTextTestGenerated extends AbstractBytecodeTextTest {
runTest("compiler/testData/codegen/bytecodeText/kt3845.kt");
}
@Test
@TestMetadata("kt48367.kt")
public void testKt48367() throws Exception {
runTest("compiler/testData/codegen/bytecodeText/kt48367.kt");
}
@Test
@TestMetadata("kt5016.kt")
public void testKt5016() throws Exception {
@@ -307,6 +307,12 @@ public class IrBytecodeTextTestGenerated extends AbstractIrBytecodeTextTest {
runTest("compiler/testData/codegen/bytecodeText/kt46615.kt");
}
@Test
@TestMetadata("kt48367.kt")
public void testKt48367() throws Exception {
runTest("compiler/testData/codegen/bytecodeText/kt48367.kt");
}
@Test
@TestMetadata("kt5016.kt")
public void testKt5016() throws Exception {