RFR: 8204540: Automatic oop closure devirtualization
Erik Osterlund
erik.osterlund at oracle.com
Thu Jun 21 16:33:09 UTC 2018
Hi Stefan,
Looks amazing. I have wanted this to happen in one way or another for years. Thank you for doing this.
Thanks,
/Erik
> On 21 Jun 2018, at 11:44, Stefan Karlsson <stefan.karlsson at oracle.com> wrote:
>
> Hi Kim,
>
> Thanks for reviewing this!
>
> Updated webrevs:
> http://cr.openjdk.java.net/~stefank/8204540/webrev.02.delta
> http://cr.openjdk.java.net/~stefank/8204540/webrev.02
>
> Comments below:
>
> On 2018-06-21 03:52, Kim Barrett wrote:
>>> On Jun 20, 2018, at 6:50 AM, Stefan Karlsson <stefan.karlsson at oracle.com> wrote:
>>>
>>> Hi all,
>>>
>>> Please review this patch to get rid of the macro based oop_iterate devirtualization layer, and replace it with a new implementation based on templates that automatically determines when the closure function calls can be devirtualized.
>>>
>>> http://cr.openjdk.java.net/~stefank/8204540/webrev.01/
>>> https://bugs.openjdk.java.net/browse/JDK-8204540
>> Generally looks good, just a few minor comments and nits.
>> ------------------------------------------------------------------------------
>> Any libjvm.so size comparison? We ought to get some benefit from not
>> generating code we don't use. OTOH, it's possible this change might
>> result in more inlining than previously.
>
> Before patch: 22833008 bytes
> After patch: 22790160 bytes
>
>> Any performance comparisons? My guess would be perhaps a small
>> improvement, as we might get some inlining we weren't previously
>> getting, in some (supposedly) not performance critical places.
>
> I did runs on our internal perf system, and the scores were the same. I looked at pause times for some of the runs and couldn't find a difference. I'll run more runs over the weekend.
>
>> ------------------------------------------------------------------------------
>> src/hotspot/share/gc/cms/cmsOopClosures.inline.hpp
>> 60 inline void cls::do_oop(oop* p) { cls::do_oop_work(p); } \
>> 61 inline void cls::do_oop(narrowOop* p) { cls::do_oop_work(p); }
>> [pre-existing]
>> I think the "cls::" qualifiers in the body should be unnecessary.
>
> Removed.
>
>> ------------------------------------------------------------------------------
>> 58 #define DO_OOP_WORK_NV_IMPL(cls) \
>> This is no longer defining "_nv" functions, so the "_NV" in the name
>> seems odd.
>
> OK. I merged DO_OOP_WORK_NV_IMPL and DO_OOP_WORK_IMPL.
>
>> ------------------------------------------------------------------------------
>> src/hotspot/share/gc/cms/concurrentMarkSweepGeneration.cpp
>> 3321 MetadataVisitingOopIterateClosure(collector->ref_processor()),
>> Indentation messed up.
>
> Fixed.
>
>> ------------------------------------------------------------------------------
>> src/hotspot/share/memory/iterator.hpp
>> 370 class OopClosureDispatch {
>> OopIterateClosureDispatch?
>
> Yes. Fixed.
>
>> ------------------------------------------------------------------------------
>> src/hotspot/share/gc/shared/genOopClosures.inline.hpp
>> I think it might be better to put the trivial forwarding do_oop
>> definitions that have been moved to here instead directly into the
>> class declarations. I think doing so gives better / earlier error
>> messages when forgetting to include the associated .inline.hpp file by
>> callers.
>
> I tried your proposal. It has the unfortunate effect that whenever you include genOopClosures.hpp you get a compile error, even when the functions are not used.
>
> I think we can get what you are looking for by changing 'virtual void do_oop(oop* p)' to 'inline virtual void do_oop(oop* p)'. I'm not sure this should be done for this RFE, though?
>
>> ------------------------------------------------------------------------------
>> src/hotspot/share/oops/instanceMirrorKlass.hpp
>> 111 public:
>> Unnecessary, we're already in public section.
>
> Removed.
>
>> ------------------------------------------------------------------------------
>> src/hotspot/share/memory/iterator.inline.hpp
>> 231 static const int NUM_KLASSES = 6;
>> The value 6 is derived from the number of entries in enum KlassId,
>> which is far away. How about defining KLASS_ID_COUNT with that enum?
>> It might be that the enum and that constant need to be somewhere other
>> than in klass.hpp though, to avoid include circularities. But see
>> next comment too.
>
> I was thinking about that as well.
>
>> ------------------------------------------------------------------------------
>> src/hotspot/share/memory/iterator.inline.hpp
>> 106 const int _id;
>> Maybe this should be of type KlassId? And similarly the accessor.
>> Similarly the static const ID members in the various klass types.
>
>
> Done.
>
>
>> I'm surprised it can be const, because of the no-arg constructor.
>
> A dummy value is set in the non-arg Klass constructor. Klasses generated with this constructor is only used in CDS to copy the vtables.
>
>> ------------------------------------------------------------------------------
>> src/hotspot/share/oops/typeArrayKlass.inline.hpp
>> 38 // Performance tweak: We skip iterating over the klass pointer since we
>> 39 // know that Universe::TypeArrayKlass never moves.
>> [pre-existing]
>> The wording of this comment seems like it might be left-over from
>> permgen, and ought to be re-worded.
>
> OK. Updated the text.
>
>> ------------------------------------------------------------------------------
>> src/hotspot/share/memory/iterator.inline.hpp
>> 77 // - If &OopClosureType::do_oop is resolved to &Base::do_oop, then there are no
>> 78 // implementation of do_oop between Base and OopClosureType. However, there
>> Either "is no implementation of" or "are no implementations of"
>
> Updated.
>
> Thanks,
> StefanK
>
>> ------------------------------------------------------------------------------
More information about the hotspot-dev
mailing list