[prev in list] [next in list] [prev in thread] [next in thread] 

List:       openjdk-hotspot-runtime-dev
Subject:    Re: =?UTF-8?Q?=E7=AD=94=E5=A4=8D=3A=20=E7=AD=94=E5=A4=8D=3A=20Hot?= =?UTF-8?Q?Spot=20and=20IBM=27s=2
From:       chenyt <chenyt () cs ! sjtu ! edu ! cn>
Date:       2017-05-18 5:15:20
Message-ID: 9a93ed9268233cf5847156fc7ceef5d5 () cs ! sjtu ! edu ! cn
[Download RAW message or body]

 Hi, David,

 I tested the next Jimple programs (let one object under monitoring be 
 null) using J9 and HotSpot. I did not see NullPointerException here (the 
 specification does tell me so). Am I wrong again? Hope the next two 
 cases will help check.

 (1) case 1: HotSpot: IllegalMonitorStateException J9: 
 NullPointerException
         r0 := @this: Search;
         r1 := @parameter0: java.lang.String[];
         r2 = null;
         entermonitor r0;
         entermonitor r2;
         exitmonitor r2;
         exitmonitor r0;
  (2) case 2: HotSpot: IllegalMonitorStateException J9: VerifyError
         r1 := @parameter0: java.lang.String[];
         r2 = new Search;
         entermonitor r0;
         entermonitor r2;
         r2=null;
         exitmonitor r2;
         exitmonitor r0;
 It is very interesting that I can still find some unexpected behaviors 
 here.

 Wishes,
 Yuting


 On Thu, 18 May 2017 14:57:03 +1000, David Holmes wrote:
> On 18/05/2017 2:18 PM, 陈雨亭 wrote:
>> Hi, David,
>>
>> I still did not catch why it happens... I just read the 
>> specification and
>> wrote some tests in order to understand some paragraphs better, and 
>> then had
>> questions.
>>
>> Will the HotSpot's verifier detect such kind of uninitialized 
>> monitored
>> objects in future?
>
> I have filed a bug so this can be examined more closely.
>
> https://bugs.openjdk.java.net/browse/JDK-8180581
>
> Thanks,
> David
>
>> Regards,
>> Yuting
>>
>> -----邮件原件-----
>> 发件人: David Holmes [mailto:david.holmes@oracle.com]
>> 发送时间: 2017年5月17日 20:23
>> 收件人: 陈雨亭 <chenyt@cs.sjtu.edu.cn>; 
>> hotspot-runtime-dev@openjdk.java.net
>> 主题: Re: 答复: HotSpot and IBM's J9 behave quite differently when
>> processing monitorenters and monitorexits
>>
>> One correction ...
>>
>> On 18/05/2017 10:29 AM, David Holmes wrote:
>>> On 18/05/2017 8:12 AM, 陈雨亭 wrote:
>>>> 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.
>>>
>>> Non-nested locking doesn't necessarily lead to deadlocks - you just
>>> need a different locking order for that (even if properly nested).
>>> There are locking patterns that rely on the ability to lock and 
>>> unlock
>>> in different order ie chained-locking for walking linked-lists 
>>> A->B->C->D:
>>> - lock A, lock B, unlock A, lock C, unlock B, lock D, unlock C ...
>>>
>>> The VM spec allows a little flexibility in how the monitor 
>>> bytecodes
>>> can be used compared to the Java programming language. That's not
>>> something that will change.
>>>
>>>> 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)
>>>
>>> Yes I think this may be a bug in hotspot. The type-checking for the
>>> monitor bytecodes requires a matching type of reference on the 
>>> operand
>>> stack - but "uninitialized" does not match Object, as J9 reports. 
>>> But
>>> I'm not an expert on this aspect of verification so I may not be
>>> interpreting it correctly.
>>>
>>> More below ...
>>>
>>>> -----邮件原件-----
>>>> 发件人: David Holmes [mailto:david.holmes@oracle.com]
>>>> 发送时间: 2017年5月17日 14:41
>>>> 收件人: 陈雨亭 <chenyt@cs.sjtu.edu.cn>;
>>>> hotspot-runtime-dev@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.
>>>
>>> That is strange as it does for the normal obvious case of using
>>> synchronized(o) when o is null.
>>
>> Ah - it isn't null it just an object for which the constructor has 
>> not been
>> run. The runtime can't tell the difference between a pointer to a 
>> valid
>> initialized object, and a pointer to an uninitialized chunk of 
>> memory.
>>
>>>>>
>>>>> 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
>>
>> This allocated an object - hence no null reference. But this is what
>> verification should have complained about.
>>
>> David
>> -----
>>
>>>>>          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.
>>>
>>> The job of the verifier is to establish some basic guarantees for 
>>> the
>>> JVM to then operate under. The verifier plays no role in checking 
>>> how
>>> monitorenter/exit are used in combination, only that each 
>>> individual
>>> bytecode meets some basic type constraints.
>>>
>>>>>
>>>>> (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;
>>>>>     }
>>>>> }
>>>
>>> Verification was covered above.
>>>
>>>>>
>>>>> (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)
>>>>> ?
>>>
>>> No it doesn't violate structured locking as the number of enters 
>>> and
>>> exits match, and there is always an enter before an exit.
>>>
>>>>> 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.
>>>
>>> The number of enters and exits must not only match/balance, but 
>>> there
>>> must be an enter before a corresponding exit.
>>>
>>>>>
>>>>> 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?
>>>
>>> No this does not violate any verification rules. The runtime 
>>> behaviour
>>> depends on whether structured locking is enforced or not.(Even in
>>> hotspot there can be differences between interpreted and jitted 
>>> code).
>>>
>>> Hope that helps clarify things.
>>>
>>> David
>>> -----
>>>
>>>>>
>>>>> public class Search extends java.lang.Object {
>>>>>
>>>>> public void <init>()
>>>>>     {
>>>>>         Search r0;
>>>>>         r0 := @this: Search;
>>>>>         specialinvoke r0.<java.lang.Object: void <init>()>();
>>>>>         entermonitor r0;
>>>
[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic