[9] RFR (M): 8139595: MethodHandles::remove_dependent_nmethod is not MT safe

Vladimir Ivanov vladimir.x.ivanov at oracle.com
Thu Nov 5 13:54:38 UTC 2015


Thanks, Aleksey!

>>> http://cr.openjdk.java.net/~vlivanov/8139595/webrev.00
>>> https://bugs.openjdk.java.net/browse/JDK-8139595
>
> Not a Reviewer. Piggybacking the cleanup on (locked) mutation is a
> standard way to deal with racing issues like that, so I like it.
>
> Some comments:
>
>   * I am confused why the cleanup logic spread out to methodHandles.cpp:
> it would seem a general functionality for DependencyContext, and as such
> it should be handled internally by add_dependent_methods? I think you
> can pass the "safe to purge" flag there.
Cleanup logic in methodHandles.cpp is special to j.l.i.CallSite's and 
call_site_target dependency type. GC doesn't remove stale entries in 
these contexts, so I decided to piggyback on regular operations to purge 
stale entries. That's the idea of the fix.

Regarding internal purging, add_dependent_methods doesn't iterate over 
the whole list, but looks for the relevant entry. It means that "purge" 
flag should force full iteration. I think that keeping them separately 
(add_dependent_methods() vs purge()) looks cleaner.

I could add "purge" flag and move the following code into 
add_dependent_methods:
void DependencyContext::add_dependent_nmethod(nmethod* nm, bool do_purge 
= false) {
    ...
    if (has_unloaded_dependent() && do_purge) {
      purge();
    }
}

Is it what you are suggesting?

>   * DependencyContext now has three methods: purge(), clear(), wipe(). I
> have trouble understanding which method does what!
I'll add comments describing the intended behavior. There are basically 
2 operations needed:
   * purge(): only remove stale entries; no additional work is performed;

   * clear(): invalidate all dependencies in the context: effectively 
removes all entries, deoptimizes and throws away all affected methods.

wipe() is only for unit-testing purposes (see TestNmethodBucket): it 
just deallocates all nmethodBucket entries without touching nmethods. It 
is necessary since nmethod pointers are faked by the test.

I could have added that code into TestNmethodBucket, but then I would 
need to declare TestNmethodBucket as a friend of DependencyContext to 
preserve incapsulation.

>   * Since there is a change in vmStructs, does this also need SA changes?
/agent/src/share/classes/sun/jvm/hotspot/oops/InstanceKlass.java refers 
neither to _dependencies nor _has_unloaded_dependent fields. So, it 
seems no changes are needed there.

Best regards,
Vladimir Ivanov



More information about the hotspot-dev mailing list