On Jan 26, 2007, at 8:08 AM, Xiao-Feng Li wrote:
On 1/26/07, Geir Magnusson Jr. <[EMAIL PROTECTED]> wrote:
I think we have a choice here. The VM spec seems to hint at what we
should do, but not require it :
The VM spec 8.13 :
"Normally, a compiler for the Java programming language ensures that
the lock operation implemented by a monitorenter instruction executed
prior to the execution of the body of the synchronized statement is
matched by an unlock operation implemented by a monitorexit
instruction whenever the synchronized statement completes, whether
completion is normal or abrupt."
Notice "normally", which means, we can't expect it.
It goes further :
"Although a compiler for the Java programming language normally
guarantees structured use of locks (see Section 7.14,
"Synchronization"), there is no assurance that all code submitted to
the Java virtual machine will obey this property. Implementations of
the Java virtual machine are permitted but not required to enforce
both of the following two rules guaranteeing structured locking.
Let T be a thread and L be a lock. Then:
1. The number of lock operations performed by T on L during a
method invocation must equal the number of unlock operations
performed by T on L during the method invocation whether the method
invocation completes normally or abruptly.
2. At no point during a method invocation may the number of
unlock operations performed by T on L since the method invocation
exceed the number of lock operations performed by T on L since the
method invocation.
In less formal terms, during a method invocation every unlock
operation on L must match some preceding lock operation on L."
My read is that we can enforce this if we want to, but my sense is
that this would be a nice to have - a bit of polish - not a must
have, as we can depend upon compilers to do the right thing.
However, it would be cute if we could detect such a thing and in a
debug mode, emit a message to help people figure out why their code
doesn't run right :)
A VM thread should unlock all the held locks before it exits. The
example code given above is incomplete, because the exeception need
certain handling in JVM that it doesn't show. If the exception is
uncaught by any frames on the stack, the thread will pop all the
frames and release all its held locks before exiting. Otherwise, the
exception catch or finally handler should take care of the held locks.
Right - the assumption there is that there are catch/finally blocks
to do that. The VM spec assumes that "normally" such code is placed
there by the compiler.
However, it also discusses what a VM can do if the code isn't there.
However, it doesn't seem to require it, because it seem to be relying
on having good code.
If the exception is uncaught and the lock's owning thread exits, the
waiting thread for the same lock can acquire it without deadlock. If
the owning thread doesn't exit, no one knows when it will release this
lock. It can hold this lock again since the lock supports recursion. I
guess we can't say a deadlock happens for this situation. We can say
the waiting thread looks like starved for it, but it might be intended
behavior.
So probably this example code doesn't expose a real issue.
yes, that was my conclusion, if you read what I wrote.
geir
Thanks,
xiaofeng
geir
On Jan 26, 2007, at 5:02 AM, Shipilov, Alexander D wrote:
> Thank you for the answer.
> Not, sure not reject the method :).
> I think that it will be nice if VM release all locks entered by
> thread
> that threw exception.
> But if it's impossible, I nothing can be say against closing this
> JIRA.
>
> Thanks,
> Alexander Shipilov
>
>> -----Original Message-----
>> From: Rana Dasgupta [mailto:[EMAIL PROTECTED]
>> Sent: Friday, January 26, 2007 1:35 AM
>> To: [email protected]
>> Subject: Re: [drlvm] If method throws exception after
>> monitorenter, JIT
>> does not release the lock
>>
>> I am not sure if this is a problem. Would you expect the jit to
> generate
>> the
>> finally code, reject the method, or what?
>>
>> On 1/25/07, Shipilov, Alexander D <[EMAIL PROTECTED]>
> wrote:
>>>
>>> Hello, folks,
>>>
>>> Could you, please clarify one issue.
>>> The problem has described in JIRA
>>> https://issues.apache.org/jira/browse/HARMONY-2504.
>>>
>>> Thread makes monitorenter, and throws exception (NPE) to the
output.
>>> JASMIN code:
>>> .method public run()V
>>> .limit stack 3
>>> .limit locals 3
>>>
>>> getstatic Test/testField Ljava/lang/Object;
>>> monitorenter
>>>
>>> new java/lang/NullPointerException
>>> dup
>>> invokespecial java/lang/NullPointerException/<init>()V
>>> athrow
>>>
>>> getstatic Test/testField Ljava/lang/Object;
>>> monitorexit
>>>
>>> return
>>> .end method
>>>
>>> Then other thread tries to get a lock. Deadlock occurs on
Harmony.
>>> Does this behavior is correct?
>>>
>>> Thanks,
>>> Alexander Shipilov
>>>