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代表MONITORENTER和MONITOREXIT说明.
我对这个如何synchronized编译的假设是正确的,还是我错过了什么?
编辑
我以前的实现对机构内部的一些特殊处理return和throw声明.基本上,它会在每个或指令之前手动加载所有lock变量.这是由块处理,还是我还需要这些检查?MONITOREXIT*RETURNTHROWfinally
你的假设是正确的.在synchronizedJava语言块与实施monitorenter和monitorexit指导.您可以在此处查看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)
| 归档时间: |
|
| 查看次数: |
359 次 |
| 最近记录: |