RFR: Parallelize safepoint cleanup

Roman Kennke rkennke at redhat.com
Thu Jul 6 16:53:48 UTC 2017


Am 06.07.2017 um 18:47 schrieb Igor Veresov:
>
>> On Jul 6, 2017, at 3:14 AM, Tobias Hartmann
>> <tobias.hartmann at oracle.com <mailto:tobias.hartmann at oracle.com>> wrote:
>>
>> Hi,
>>
>> On 05.07.2017 20:30, Daniel D. Daugherty wrote:
>>> JDK-8132849 is assigned to Tobias; it would be good to get Tobias'
>>> review of this fix also.
>>
>> Thanks for the notification. The sweeper/safepoint changes look good
>> to me!
>>
>>> src/share/vm/runtime/sweeper.cpp
>>>    L205:     // TODO: Is this really needed?
>>>    L206:     OrderAccess::storestore();
>>>        That's a good question. Looks like that storestore() was
>>>        added by this changeset:
>>>
>>>        $ hg log -r 5357 src/share/vm/runtime/sweeper.cpp
>>>        changeset:   5357:510fbd28919c
>>>        user:        anoll
>>>        date:        Fri Sep 27 10:50:55 2013 +0200
>>>        summary:     8020151: PSR:PERF Large performance regressions
>>> when code cache is filled
>>>
>>>        The changeset is not small and it looks like two
>>>        OrderAccess::storestore() calls were added (and one
>>>        load_ptr_acquire() was deleted):
>>>
>>>        $ hg diff -r 5356 -r 5357 | grep OrderAccess
>>>        +      OrderAccess::storestore();
>>>        -  nmethod *code = (nmethod
>>> *)OrderAccess::load_ptr_acquire(&_code);
>>>        +  OrderAccess::storestore();
>>>
>>>        It could be that the storestore() is matching an existing
>>>        OrderAccess operation or it could have been added in an
>>>        abundance of caution. We definitely need a Compiler team
>>>        person to take a look here.
>>
>> Unfortunately, I'm also not sure if that barrier is required. Looking
>> at the old RFR thread:
>> http://mail.openjdk.java.net/pipermail/hotspot-compiler-dev/2013-September/011588.html
>>
>> It seems that Igor V. suggested this:
>> "You definitely need a store-store barrier for non-TSO architectures
>> after the mark_as_seen_on_stack() call on line 1360. Otherwise it
>> still can be reordered by the CPU with respect to the following state
>> assignment. Also neither of these state variables are volatile in
>> nmethod, so even the compiler may reorder the stores."
>> http://mail.openjdk.java.net/pipermail/hotspot-compiler-dev/2013-September/011729.html
>>
>> The requested OrderAccess::storestore() was added to
>> nmethod::make_not_entrant_or_zombie() but seems like Albert also
>> added one to NMethodSweeper::mark_active_nmethods().
>>
>> I'll ping Igor, maybe he knows more.
>
>
> I think the reason is explained in the comment:
>
>     // Must happen before state change. Otherwise we have a race
> condition in
>     // nmethod::can_not_entrant_be_converted(). I.e., a method can
> immediately
>     // transition its state from 'not_entrant' to 'zombie' without
> having to wait
>     // for stack scanning.
>     if (state == not_entrant) {
>       mark_as_seen_on_stack();
>       OrderAccess::storestore();
>     }
>
>     // Change state
>     _state = state;
>
> Although can_not_entrant_be_converted() is now called
> can_convert_to_zombie(). The scenario can so like this:
> 1. We’re setting the state to not_entrant. But the _state assignment
> happens before setting the traversal count in mark_as_seen_on_stack().
> 2. While we’re doing this, the sweeper scans nmethods and is in
> process_compiled_method():
>
>   } else if (cm->is_not_entrant()) {
>     // If there are no current activations of this method on the
>     // stack we can safely convert it to a zombie method
>     if (cm->can_convert_to_zombie()) {
>       // Clear ICStubs to prevent back patching stubs of zombie or flushed
>       // nmethods during the next safepoint (see ICStub::finalize).
>       {
>         MutexLocker cl(CompiledIC_lock);
>         cm->clear_ic_stubs();
>       }
>       // Code cache state change is tracked in make_zombie()
>       cm->make_zombie();
>
>
> So if state change happens before setting the traversal mark, the
> sweeper can go ahead and make it a zombie.
>
>
> Makes sense? Or am I missing something?

I have probably not fully digged the code. As far as I can see:
- sweeper thread runs outside safepoint
- VMThread (which is doing the nmethod marking in the case that I'm
looking at) runs while all other threads (incl. the sweeper) is holding
still.

In between we have a guaranteed fence().

There should be no need for a storestore() (at least in sweeper.cpp...
in nmethod.cpp it seems to actually make sense as you pointed out
above). *However* it doesn't really hurt to OrderAccess::storestore()
there... so play it conservative and leave it in, as RFR'd in my last patch?

Roman

>
> igor
>
>
>>
>> Thanks,
>> Tobias
>

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/hotspot-gc-dev/attachments/20170706/b5fbc422/attachment.htm>


More information about the hotspot-gc-dev mailing list