RFR: 8213486: SIGSEGV in CompiledMethod::cleanup_inline_caches_impl with AOT
Erik Österlund
erik.osterlund at oracle.com
Wed Nov 21 14:28:26 UTC 2018
Hi Dean,
On 2018-11-20 19:21, dean.long at oracle.com wrote:
> OK. I agree it makes sense to move the unloading from CompiledMethod
> to nmethod. I was just curious what problem you were running into
> with AOT,
> because the iterators look OK to me.
I am also curious!
> You probably ran into trouble here:
>
> // Clean inline caches pointing to both zombie and not_entrant methods
> *if* (clean_all
> <https://java.se.oracle.com/source/s?defs=clean_all&project=jdk-jdk>
> || !nm
> <https://java.se.oracle.com/source/s?defs=nm&project=jdk-jdk>->is_in_use
> <https://java.se.oracle.com/source/s?defs=is_in_use&project=jdk-jdk>()
> || nm
> <https://java.se.oracle.com/source/s?defs=nm&project=jdk-jdk>->is_unloading
> <https://java.se.oracle.com/source/s?defs=is_unloading&project=jdk-jdk>()
> || (nm
> <https://java.se.oracle.com/source/s?defs=nm&project=jdk-jdk>->method
> <https://java.se.oracle.com/source/s?defs=method&project=jdk-jdk>()->code
> <https://java.se.oracle.com/source/s?defs=code&project=jdk-jdk>() !=
> nm <https://java.se.oracle.com/source/s?defs=nm&project=jdk-jdk>)) {
> because !is_in_use() would be false for the not_used state.
No, if it is not_used, then !is_in_use() will return true, and therefore
nm->is_unloading() will not be called. In fact, upon crashing here, I
know that th AOT method is in fact in_use.
So now I am also trying to figure out how the iterators manage to miss
the AOT method. I just know with pretty high certainty that they do.
Thanks,
/Erik
> dl
>
> On 11/20/18 3:12 AM, Erik Österlund wrote:
>> Hi Dean,
>>
>> Yeah I think I misunderstood what I observed. So what I know is that
>> in the code cache unloading, I'm not getting all is_alive() AOT
>> methods into my iterator, which messes up the assumptions made by the
>> epoch based scheme for AOT methods.
>>
>> I noticed that in AOTCodeHeap::sweep_dependent_methods(int* indexes,
>> int methods_cnt) we make AOTCompiledMethods "invalid" in the AOT
>> heap, making it no longer observable from the iterators. Then it
>> calls the VM_Deoptimize vm operation after. Throughout all this, the
>> AOTCompiledMethod is alive(), yet when the iterators ask for all
>> is_alive() AOTCompiledMethods, it won't be visible. But I suppose IC
>> caches may still reference these methods and check if it
>> is_unloading, and then we blow up. There may possibly be multiple
>> ways for is_alive() AOTCompiledMethods to not be visible from
>> iterators yet be visible through IC caches using the "invalid" state
>> in the .
>>
>> Anyway, the fix is the same: stop doing the epoch state thingey for
>> is_unloading() on AOTCompiledMethod where it isn't needed, and
>> doesn't seem to play well with the rather different life cycle it
>> has, and just return false instead.
>>
>> Thanks,
>> /Erik
>>
>> On 2018-11-20 00:00, dean.long at oracle.com wrote:
>>> Hi Erik,
>>>
>>> On 11/19/18 12:42 PM, Erik Österlund wrote:
>>>> ...except it looks like for AOTCompiledMethods when running with
>>>> tiered compilation, may first be is_alive(), then become
>>>> !is_alive() for a while, and then get resurrected to is_alive()
>>>> using make_entrant().
>>>
>>> this doesn't sounds quite right. AOTCompiledMethods aren't allowed
>>> to transition to zombie (!alive), only not_used or not_entrant,
>>> which should still have is_alive() returning true. Maybe some code
>>> is using is_not_entrant() instead of !is_alive()?
>>>
>>> dl
>>
>
More information about the hotspot-dev
mailing list