RFR: 8255384: Remove special_runtime_exit_condition() check from SS::block() [v5]
Robbin Ehn
rehn at openjdk.java.net
Mon Nov 9 08:31:05 UTC 2020
On Fri, 6 Nov 2020 08:36:36 GMT, Robbin Ehn <rehn at openjdk.org> wrote:
>>> Thanks for the updates! All LGTM.
>>>
>>> David
>> Great, thanks David!
>>
>> Patricio
>
>> {
>> ThreadInVMfromJava tivm;
>> }
>>
>> which transitions from Java to VM and back, for absolutely no reason
>> other than to get the side-effects of doing those transitions.
>
> As I see it, if you have an oop map and are executing in VM, you are technically in VM.
> But here we skip going to VM since SS:block used to need to know where you are going back to due to suspend flag is handle inside SS:block().
> And the safepoint synchronizer will treat java/vm the same thus we can cheat.
>
> If the thread is in Java it is not guaranteed that it will have an oop map and it's not certain that it can be made walkable.
> Being blocked requires you to be walkable, thus going from java->blocked cannot be done as general rule.
> Instead of having a ton of special rules which no one can remember, the rule is you can only block in VM where we know you can be made walkable.
>
> Polling page exception handling can thus been seen as a cheat avoiding setting in vm since it will actually have no effect on the safepoint synchronizer.
>
> So no we are not looking for side-effects, we need to be in VM (at minimum technically) to become blocked.
> Thus the rules for going from VM to Java applies, and we should deliver e.g. async exceptions.
>
> {
> ThreadInVMfromJava tivm;
> SS:block()
> }
>
> Would be the preferred way of doing it.
>
>>
>> David
>> -----
Hi David,
> > And the safepoint synchronizer will treat java/vm the same thus we can cheat.
> > If the thread is in Java it is not guaranteed that it will have an oop map and it's not certain that it can be made walkable.
> > Being blocked requires you to be walkable, thus going from java->blocked cannot be done as general rule.
> > Instead of having a ton of special rules which no one can remember, the rule is you can only block in VM where we know you can be made walkable.
>
> Sorry but I don't understand the point you are making here. The
> transition from Java to VM does nothing except change the thread-state
> and so has no affect on whether a thread can be made walkable or not.
> And SS:block() makes the thread walkable in any case.
We have many such transition which only sets correct thread state.
> > Polling page exception handling can thus been seen as a cheat avoiding setting in vm since it will actually have no effect on the safepoint synchronizer.
> > So no we are not looking for side-effects, we need to be in VM (at minimum technically) to become blocked.
>
Either you can look this as set of rules that we can follow.
Where at some places we have choose to optimize away some parts.
Or everything in the code is just ad-hoc and special cases.
> But that is simply not true - we end up being blocked for
> safepoints/handshakes from a wide-range of thread states.
>
> > Thus the rules for going from VM to Java applies, and we should deliver e.g. async exceptions.
> > {
> > ThreadInVMfromJava tivm;
> > SS:block()
> > }
> > Would be the preferred way of doing it.
>
> ??? Why would you call SS::block explicitly there - the transition back
> to VM would do that.
The point being that we should be in VM when entering SS:block().
The rules for being in VM from applies:
~ You must be walkable, no _suspend_flag check is needed.
And the same when going back from VM back to java:
~ Deliver all _suspend_flag events.
So you can either see this "special code".
Or, we have just removed redundant code, other than that this
follows the 'generic rules'.
It is much easier to read/review the code as:
Java->VM, oopmap, no front edge polling/_suspend_flag, no fence
VM->Blocked, walkable, no front edge polling/_suspend, no fence
*blocked*
Blocked->VM, back edges polling, no suspend_flag, fence
VM->Java, back edges polling, all suspend_flag big, no fence
When setting thread state without fence we may skip it, front edge of going Java->VM->Blocked can be optimized to:
- walkable
- set blocked
Back edge can be optimized to:
- set any unsafe state (e.g. vm/block_trans) + fence
- check poll, check suspend_flag
- set thread state to Java
This is what we do, but it is distributed several methods ~3-4 methods.
So the reason for ending-up in SS:block with all kinds of state is that in some-cases the first part of the transition is in another methods e.g. the native wrapper.
That case can be seen as native->vm->blocked->vm->java:
Native->VM, oopmap, front edge polling/_suspend_flag, fence (safe>unsafe)
VM->Blocked, walkable, no front edge polling/_suspend, no fence, unsafe->safe
*blocked*
Blocked->VM, back edges polling, no suspend_flag, fence
VM->Java, back edges polling, all suspend_flag big, no fence
The native wrapper does the front edge polling safe->unsafe + fence
Since native_trans is also an unsafe state and going to another unsafe state does not require a fence, we can just optimize that away and just set blocked directly, so optimized it looks like:
- native wrapper
- walkable
- set blocked
When going back it looks the other case of blocked->vm->java, but native wrapper sets the final thread state of thread in Java.
- set any unsafe state (e.g. any _trans state) + fence
- check poll, check suspend_flag
- set thread state to Java done by wrapper in this case
You don't have to think of it like this, but it certainly helps me when writing/reviewing the code.
Thanks, Robbin
>
> David
> -----
# #
-------------
PR: https://git.openjdk.java.net/jdk/pull/913
More information about the hotspot-runtime-dev
mailing list