RFR: 8218974: Free GC native structures in nmethod::flush

Erik Österlund erik.osterlund at oracle.com
Thu Feb 21 12:20:28 UTC 2019


Hi Per,

Thanks for the review.

/Erik

On 2019-02-21 13:18, Per Liden wrote:
> On 2/18/19 9:11 AM, Erik Österlund wrote:
>> Hi Per,
>>
>> On 2019-02-18 07:44, Per Liden wrote:
>>> Hi Erik,
>>>
>>> On 02/14/2019 12:55 PM, Erik Österlund wrote:
>>>> Hi,
>>>>
>>>> An nmethod goes from being is_alive() to being !is_alive() and 
>>>> eventually being freed in nmethod::flush. Native structures for 
>>>> nmethods are freed in nmethod::flush when we free the nmethod. 
>>>> Except for a few things, including GC data. This enhancement 
>>>> proposes to fix that to make the life cycle of nmethods and their 
>>>> native data more intuitive.
>>>>
>>>> In particular ZGC has per-nmethod data. The data is removed when 
>>>> unlinking nmethods, as opposed to when they are deleted. This is a 
>>>> bit awkward and makes things more difficult than they need to be. 
>>>> This patch adds a new CollectedHeap::flush_nmethod() function. In 
>>>> there ZGC deletes its attached GC data.
>>>>
>>>> Bug:
>>>> https://bugs.openjdk.java.net/browse/JDK-8218974
>>>>
>>>> Webrev:
>>>> http://cr.openjdk.java.net/~eosterlund/8218974/webrev.00/
>>>
>>> Do we need to introduce a new flush_nmethod()? Would it instead be 
>>> possible to move/adjust where unregister_nmethod() is called to get 
>>> the same effect? When just looking at the API, the relationship 
>>> between unregister and flush is not super obvious. Determining which 
>>> one will be called first and what a GC allowed/supposed to do in 
>>> each of them kind of requires you to inspect the call-sites.
>>
>> I think of it this way: unregister_nmethod is tied to the lifecycle 
>> of the nmethod oops, and flush_nmethod is for the nmethod itself.
>> In particular, we call unregister_nmethod when an nmethod dies 
>> (becomes !is_alive()). When an nmethod has died, the oops should not 
>> be retained. In fact, when the nmethod becomes unloaded, it dies 
>> specifically because the oops are dead, forcing us to kill the 
>> nmethod. Then we unregister to tell the GC not to look at those oops 
>> again.
>>
>> If we moved unregister_nmethod to nmethod::flush, we would keep 
>> around nmethods with broken oops in GC data structures, and the GC 
>> could no longer trust those data structures, unless we rewrote them 
>> to take into consideration that the oops they maintain could be dead 
>> if the host nmethod has silently died. But I don't think that would 
>> be an improvement.
>>
>> Because of this, I think it is wise to separate between GC events for 
>> the nmethod dying, and being deleted, because they have different 
>> implications.
>
> I hear you. I like how this simplifies the nmethod data life cycle. 
> Just one minor thing, ZNMethodTable::lock_for_nmethod() could now be 
> just:
>
>   return gc_data(nm)->lock();
>
> Other than that, look good.
>
> We might want to think about how/if this relates to the 
> BarrierSet::on_* functions, with regards to naming and where they 
> live. But that's a separate patch.
>
> cheers,
> Per



More information about the hotspot-gc-dev mailing list