[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:
committed by
Alexander Udalov
parent
9fd777cb7d
commit
a12b22c04d
@@ -19,13 +19,18 @@ public actual inline fun <R> synchronized(lock: Any, block: () -> R): R {
|
||||
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
|
||||
}
|
||||
|
||||
// Force the lock object into a local and use that local for monitor enter/exit.
|
||||
// This ensures that the JVM can prove that locking is balanced which is a
|
||||
// prerequisite for using fast locking implementations. See KT-48367 for details.
|
||||
val lockLocal = lock
|
||||
|
||||
@Suppress("NON_PUBLIC_CALL_FROM_PUBLIC_INLINE", "INVISIBLE_MEMBER")
|
||||
monitorEnter(lock)
|
||||
monitorEnter(lockLocal)
|
||||
try {
|
||||
return block()
|
||||
}
|
||||
finally {
|
||||
@Suppress("NON_PUBLIC_CALL_FROM_PUBLIC_INLINE", "INVISIBLE_MEMBER")
|
||||
monitorExit(lock)
|
||||
monitorExit(lockLocal)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user