How does synchronized work?


#1

It is defined as:

@kotlin.internal.InlineOnly
public inline fun <R> synchronized(lock: Any, block: () -> R): R {
    @Suppress("NON_PUBLIC_CALL_FROM_PUBLIC_INLINE")
    monitorEnter(lock)
    try {
        return block()
    }
    finally {
        @Suppress("NON_PUBLIC_CALL_FROM_PUBLIC_INLINE")
        monitorExit(lock)
    }
}

Am I correct that there is some compiler magic going on for monitorEnter() and monitorExit()?

What does @kotlin.internal.InlineOnly do in this context? As the function is specified as inline, are there any ways that call may not be inlined?


#2

monitorEnter and monitorExit are intrinsics, compiler do the corresponding JVM instructions.

InlineOnly means that the Java method corresponding to this Kotlin function is marked private so that Java code can not access it (which is the only way to call an inline function without actually inlining it).


#3

Thanks! Why haven’t those two methods just been marked as external?

How does inlining actually work? I suppose this must be something that is done on a bytecode level? Otherwise it wouldn’t work for library functions, would it?

Also, I am wondering if the annotation should be open to everyone. Preventing java code from calling such an inlined method sounds like a reasonable request for user code as well.


#4

Yes, roughly speaking inlining takes the bytecode of the function being inlined and inserts it at the call site applying some required transformations. Thus the inline function declaration has not to be visible (in terms of JVM visibility) at a call site.

This annotation was added in the last moment before release, so we hadn’t time to validate the design and decided to keep it internal for a while. There are good chances we make it public later.