可以将同步块简化为字节码级别的Try-Finally块吗?

Cla*_*oft 4 java bytecode synchronized try-finally jvm-bytecode

编写我自己的编译器用于类似Java的语言,我在编译时遇到了问题synchronized blocks.我提出了以下想法,将它们简化为try-finally块:

synchonized (obj) {
     statements...
}
Run Code Online (Sandbox Code Playgroud)

可以替换

Object _lock = obj
_monitorEnter(lock)
try {
    statements...
}
finally {
    _monitorExit(lock)
}
Run Code Online (Sandbox Code Playgroud)

在哪里_monitorEnter_monitorExit代表MONITORENTERMONITOREXIT说明.

我对这个如何synchronized编译的假设是正确的,还是我错过了什么?

编辑

我以前的实现对机构内部的一些特殊处理returnthrow声明.基本上,它会在每个或指令之前手动加载所有lock变量.这是由块处理,还是我还需要这些检查?MONITOREXIT*RETURNTHROWfinally

Ada*_*ker 5

你的假设是正确的.在synchronizedJava语言块与实施monitorentermonitorexit指导.您可以在此处查看JVM规范详细信息.

Java虚拟机中的同步由监视器进入和退出实现,显式地(通过使用monitorenter和monitorexit指令)或隐式地(通过方法调用和返回指令).

编译器生成的字节码将处理synchronized正文中抛出的所有异常,因此您的try-finally方法在这里可以正常工作.

规范finally语句不告诉释放监视器东西.第一个链接中提供的示例显示了包含在synchronized块中的简单方法的字节码.如您所见,处理任何可能的异常以确保monitorexit指令执行.您应该在编译器中实现相同的行为(编写将在finally语句中释放monitor的代码).

void onlyMe(Foo f) {
    synchronized(f) {
        doSomething();
    }
}

Method void onlyMe(Foo)
0   aload_1             // Push f
1   dup                 // Duplicate it on the stack
2   astore_2            // Store duplicate in local variable 2
3   monitorenter        // Enter the monitor associated with f
4   aload_0             // Holding the monitor, pass this and...
5   invokevirtual #5    // ...call Example.doSomething()V
8   aload_2             // Push local variable 2 (f)
9   monitorexit         // Exit the monitor associated with f
10  goto 18             // Complete the method normally
13  astore_3            // In case of any throw, end up here
14  aload_2             // Push local variable 2 (f)
15  monitorexit         // Be sure to exit the monitor!
16  aload_3             // Push thrown value...
17  athrow              // ...and rethrow value to the invoker
18  return              // Return in the normal case
Exception table:
From    To      Target      Type
4       10      13          any
13      16      13          any
Run Code Online (Sandbox Code Playgroud)