答复: HotSpot and IBM's J9 behave quite differently when processing monitorenters and monitorexits

陈雨亭 chenyt at cs.sjtu.edu.cn
Wed May 17 22:12:22 UTC 2017


Thank you, David. I have seen from the specification that structured locking
enforcement is optional. The second and the third ones are cases of
structured/nested lockings. Will non-nested locking sequences raise
deadlocks? Of course it is a different topic, while it might be better if it
can be kicked out earlier from the specification/JVM.

The first example is still a problem. It seems that HotSpot allows to
monitor a pure object reference without initialized (Is it true? How can
this checking be omitted?). J9 reports a verifyerror as follows.

Exception in thread "main" java.lang.VerifyError: JVMVRFY012 stack shape
inconsistent; class=Search, method=main([Ljava/lang/String;)V, pc=6
Exception Details:
  Location:
    Search.main([Ljava/lang/String;)V @6: JBmonitorenter
  Reason:
    Type 'uninitialized' (current frame, stack[1]) is not assignable to
'java/lang/Object'
  Current Frame:
    bci: @6
    flags: { }
    locals: { 'Search', '[Ljava/lang/String;' }
    stack: { 'uninitialized', 'uninitialized' }
	at T.main(T.java:4)



-----邮件原件-----
发件人: David Holmes [mailto:david.holmes at oracle.com] 
发送时间: 2017年5月17日 14:41
收件人: 陈雨亭 <chenyt at cs.sjtu.edu.cn>; hotspot-runtime-dev at openjdk.java.net
主题: Re: HotSpot and IBM's J9 behave quite differently when processing
monitorenters and monitorexits

Hi,
On 18/05/2017 7:23 AM, 陈雨亭 wrote:
> Am I wrong?

I will look at each situation in detail when I get a chance but structured
locking enforcement is optional. Also balancing the number of locks and
unlocks in a frame does not mean they can't be locked and unlocked in a
non-nested fashion - just that by the end the number of unlocks matches the
number of locks.

BTW the way you respond to these emails, as if having a conversation with
yourself, makes it difficult to respond as we can't readily see what is the
new email and what is the original.

Cheers,
David

> The byte code for main() in case 1 is as follows. The strange thing is 
> that NullPointerException is also not thrown at runtime.
>
> public void main(java.lang.String[]) throws java.lang.Exception;
>     descriptor: ([Ljava/lang/String;)V
>     flags: ACC_PUBLIC
>     Code:
>       stack=3, locals=2, args_size=2
>          0: new           #2                  // class Search
>          3: dup
>          4: aload_0
>          5: monitorenter
>          6: monitorenter
>          7: monitorexit
>          8: aload_0
>          9: monitorexit
>         10: return
>     Exceptions:
>       throws java.lang.Exception
>
> 主题: HotSpot and IBM's J9 behave quite differently when processing 
> monitorenters and monitorexits
>
> I have tested several programs (in Jimple) and found that HotSpot and 
> J9 match monitorenters and monitorexits quite differently. Verifiers 
> should play more important roles here.
>
> (1) Test the next program (r2 is not initizlied) on HotSpot and J9.
> J9 throw out a verifier error, while HotSpot does not. It seems that 
> HotSpot's verifier forgets to check whether a monitored object is 
> initialized.
>
> public class Search extends java.lang.Object { public void <init>()
>     {
>         Search r0;
>         r0 := @this: Search;
>         specialinvoke r0.<java.lang.Object: void <init>()>();
>         return;
>     }
> public void main(java.lang.String[]) throws java.lang.Exception
>     {
>         Search r0;
>         Search r2;
>         java.lang.String[] r1;
>         r0 := @this: Search;
>         r1 := @parameter0: java.lang.String[];
>         r2 = new Search;
>
>         entermonitor r2;
>         entermonitor r0;
>         exitmonitor r2;
>         exitmonitor r0;
>         return;
>     }
> }
>
> (2) Test the next program on HotSpot and J9, and both do not report 
> any errors. However, I guess the order in the program (entermonitor 
> r2; => entermonitor r0; =>  exitmonitor r2; => exitmonitor r0;) 
> violates the situation of "structured locking" (Structured locking is 
> the situation when, during a method invocation, every exit on a given 
> monitor matches a preceding entry on that monitor, see the 
> specification
> https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-2.html#jvms-2.
> 11.10)
> ?
> Actually, the words (every exit on a given monitor matches a preceding 
> entry on that monitor) are not quite clear as for me. Otherwise the 
> first rule (The number of monitor entries performed by T on M during a 
> method invocation must equal the number of monitor exits performed by 
> T on M during the method invocation whether the method  invocation 
> completes normally or
> abruptly.) is sufficient.
>
> public class Search extends java.lang.Object {
>
> public void <init>()
>     {
>         Search r0;
>         r0 := @this: Search;
>         specialinvoke r0.<java.lang.Object: void <init>()>();
>         return;
>     }
>
> public void main(java.lang.String[]) throws java.lang.Exception
>     {
>         Search r0;
>         Search r2;
>         java.lang.String[] r1;
>         r0 := @this: Search;
>         r1 := @parameter0: java.lang.String[];
>         r2 = new Search;
>         specialinvoke r2.<Search: void <init>()>();
>         entermonitor r2;
>         entermonitor r0;
>         exitmonitor r2;
>         exitmonitor r0;
>         return;
>     }
> }
>
> (3) The next program enters monitor in <init> and exits it in main().
> HotSpot throws a runtime exception, while J9 does not. Should this  
> program be rejected by the verifiers?
>
> public class Search extends java.lang.Object {
>
> public void <init>()
>     {
>         Search r0;
>         r0 := @this: Search;
>         specialinvoke r0.<java.lang.Object: void <init>()>();
>         entermonitor r0;
>         return;
>     }
>
> public void main(java.lang.String[]) throws java.lang.Exception
>     {
>         Search r0;
>         Search r2;
>         java.lang.String[] r1;
>         r0 := @this: Search;
>         r1 := @parameter0: java.lang.String[];
>         r2 = new Search;
>         specialinvoke r2.<Search: void <init>()>();
>         exitmonitor r2;
>         exitmonitor r0;
>         return;
>     }
> }
>
>



More information about the hotspot-runtime-dev mailing list