The JIT fails to account for native threads when optimizing.
Remi Forax
forax at univ-mlv.fr
Fri Jun 14 00:28:08 PDT 2013
On 06/14/2013 08:27 AM, Guilherme Espada wrote:
> The JIT optimizes away a code block because it thinks a value cannot be
> changed. But the JIT fails to account for native threads.
>
> Here is some sample code that demonstrates the issue (This example uses
> the JNativeHook (https://code.google.com/p/jnativehook/) library):
>
> import org.jnativehook.GlobalScreen;
> import org.jnativehook.NativeHookException;
> import org.jnativehook.keyboard.NativeKeyEvent;
> import org.jnativehook.keyboard.NativeKeyListener;
>
> public class BugTest {
>
> public static void main(String[] args) {
> try {
> new BugTest().maiin();
> } catch (NativeHookException e) {
> throw new RuntimeException(e);
> }
> }
> class Hook implements NativeKeyListener {
> @Override
> public void nativeKeyPressed(NativeKeyEvent nativeKeyEvent) {
> dirty=true;
> System.out.println("Dirty was set: " + dirty);
> }
> @Override
> public void nativeKeyReleased(NativeKeyEvent nativeKeyEvent) {
> }
> @Override
> public void nativeKeyTyped(NativeKeyEvent nativeKeyEvent) {
> }
> }
>
> private boolean dirty;
>
> private void maiin() throws NativeHookException{
> GlobalScreen.registerNativeHook();
> GlobalScreen.getInstance().addNativeKeyListener(new Hook());
> while (true) {
> if(dirty){
> System.out.println("GUIpsp");
> }
> }
> }
> }
>
> Expected:
> The program should output "GUIpsp" continuously after pressing any key.
>
> Actual:
> The program outputs nothing.
>
>
> This was tested on the following systems:
>
> Linux Satellite-Pro-L500 3.2.0-45-generic #70-Ubuntu SMP x86_64 x86_64
> x86_64 GNU/Linux
>
> Windows 7 x64
>
> With the following java -version
>
> java version "1.7.0_21"
> OpenJDK Runtime Environment (IcedTea 2.3.9) (7u21-2.3.9-0ubuntu0.12.04.1)
> OpenJDK 64-Bit Server VM (build 23.7-b01, mixed mode)
>
> java version "1.7.0_21"
> Java(TM) SE Runtime Environment (build 1.7.0_21-b11)
> Java HotSpot(TM) 64-Bit Server VM (build 23.21-b01, mixed mode)
>
>
> As a workaround, adding any activity in the while block prevents the JIT
> from optimizing away the block. For example:
>
> while (true) {
> System.out.toString();
> if(dirty){
> System.out.println("GUIpsp");
> }
> }
>
> Disabling the JIT with -Xint fixes this issue.
It has nothing to do with the fact that the thread is native or not,
you will see the same issue with a Java thread.
see section 17 of the JLS,
http://docs.oracle.com/javase/specs/jls/se7/html/jls-17.html
Practically, the way to solve the issue, is to declare dirty as volatile.
Rémi
More information about the hotspot-compiler-dev
mailing list