RFR(M/L): 7145569: G1: optimize nmethods scanning

Mikael Gerdin mikael.gerdin at oracle.com
Tue Jun 18 08:03:03 UTC 2013


John,

On 2013-06-17 19:37, John Rose wrote:
> On Jun 16, 2013, at 10:42 PM, Mikael Gerdin
> <mikael.gerdin at oracle.com> wrote:
>
>> On 2013-06-16 22:30, Igor Veresov wrote:
>>>
>>> On Jun 14, 2013, at 5:27 AM, Mikael Gerdin
>>> <mikael.gerdin at oracle.com> wrote:
>>>
>>>>
>>>> Just to make sure I understand this change, for the G1 class
>>>> unloading work I don't want the nmethods to act as strong
>>>> roots. So I guess I'll need to remove the call to
>>>> mark_strong_code_roots. In the class unloading case only
>>>> nmethods on the execution stack should be treated as strong
>>>> roots and they are taken care of by
>>>> Threads::possibly_parallel_oops_do (from
>>>> process_strong_roots).
>>>>
>>>
>>> I think references to the _objects_ from nmethod must be strong,
>>> otherwise these objects will be only weakly referenced most of
>>> the time and will be collected (since they are usually only
>>> referenced by that particular nmethod) and you'll be forced to
>>> kill nmethod pretty much every collection to stay consistent.
>>> References to _classes_ on the other hand should be weak, I
>>> think.. Right?
>>
>> How do you mean? I'm not entirely clear on when an object is _only_
>> reachable from an nmethod. Is that a common case? I don't see how
>> this is different in G1 than in any of the other collectors.
>>
>> Anyway we are unable to make the distinction between objects and
>> classes referenced from nmethods now since we use the ClassLoader
>> java object to reference the Klass*/Method* from an nmethod.
>
> See the comment in nmethod.cpp for nmethod::oops_do.  There may be a
> mix of strong and weak roots in nmethods (as one might expect).

I've read that comment. Unfortunately I've not found the code which is 
supposed to handle the weak roots. The use of the do_strong_roots_only 
flag seems to have been removed when perm gen disappeared.
In hsx24 I can see that exception cache oops are treated as weak oops.

>
> Roots for random constants compiled by the JIT into machine code are
> usually strong not weak.  The cost of putting a weak root in an
> nmethod is that the nmethod has to be recompiled if the object goes
> away (or there is a bug when the code uses a null pointer left
> behind).  The cost of a strong root is retaining an object that
> should have been GCed or (worse) a class that could have been
> unloaded.

I agree.
Currently the GC treats all nmethods and all their oops as strong roots 
for young collections.
For full collections we treat on-stack nmethods and all their oops as 
strong roots and all other nmethods are treated as weak roots, 
potentially forcing them to be unloaded after we've gathered all the 
liveness information for all java objects.

>
> For example, if code has an interned string constant there is no
> benefit for flushing the code if nobody else uses the string.  Same
> point for invokedynamic call sites.  But these examples do not
> strictly require nmethod strong roots, though, since the oops are
> already rooted in the constant pool for the method.
>
> More subtle examples are oops which the JIT has constant-folded by
> loading from objects present at compile time.  The rule for these is
> if the original object should be a strong root then the inlined field
> value should be a strong root, if the field is final or otherwise
> "stable".  If it is mutable, then the JIT may be doing an optimistic
> optimization that needs a weak root.
>
> Some pointers in code ought to be weak roots, although that does not
> appear to be the case currently.  Any optimistic optimization based
> on class might want to unload the optimistically guessed class.
> These optimizations include monomorphic inline caches and
> profile-driven type narrowing.  They might also include user-defined
> optimizations based on (JSR 292) switchpoints or mutable call sites.
>
> There are lots of "mights" and "shoulds" in the account above.
> Making nmethod oops weak, but backed up by constant pool strong
> roots, "should" work, but it is likely to cause unexpected
> performance regressions in very dynamic code, due to nmethod
> invalidation after aggressive deletion of optimistically used data
> structures.

I'm not suggesting we make any changes to how we treat nmethod oops. I 
was just attempting to describe how to modify G1 to treat nmethods like 
all the other collectors do.

/Mikael

>
> — John
>



More information about the hotspot-gc-dev mailing list