RFR: 8247470: Fix CHeap GrowableArray NMT accounting
Stefan Karlsson
stefan.karlsson at oracle.com
Mon Jun 15 18:05:50 UTC 2020
Hi all,
Updated webrevs:
https://cr.openjdk.java.net/~stefank/8247470/webrev.02.delta/
https://cr.openjdk.java.net/~stefank/8247470/webrev.02/
Testing showed that the previous patch was incomplete. I changed the
signature and expected the compiler to show all places I needed to
update. The intention was that the compiler should see that true/false
wasn't a MEMFLAGS and complain. Unfortunately, there was a problem with
the following pattern:
new (ResourceObj::C_HEAP, mtCode)GrowableArray<const char*>(0, true);
which matches the following constructor:
// Resource allocation
GrowableArray(Thread* thread, int initial_size) :
GenericGrowableArray(initial_size, 0, mtNone) {
and yields thread == NULL (0) and initial_size == 1 (true).
There were only two places that used the Thread* parameter. This special
constructor seems to have been a performance optimization at some point.
But we've made Thread::current() much cheaper, and neither of the
affected call sites seems to be performance sensitive. I opted to
simplify the code and removed that constructor.
The systemDictionaryShared.cpp was needed after I rebased the patch.
Thanks,
StefanK
On 2020-06-12 11:33, Stefan Karlsson wrote:
> Hi all,
>
> Please review this patch to fix the NMT accounting of CHeap
> GrowableArray allocations.
>
> https://cr.openjdk.java.net/~stefank/8247470/webrev.01/
> https://bugs.openjdk.java.net/browse/JDK-8247470
>
> The initial reason why I started fixing this was that I found code
> like this:
>
> src/hotspot/share/classfile/javaClasses.cpp:
> new (ResourceObj::C_HEAP, mtModule) GrowableArray<Klass*>(500, true);
>
> Before this patch, the GrowableArray constructor looked like this:
>
> GrowableArray(int initial_size, bool C_heap = false, MEMFLAGS F =
> mtInternal)
> : GenericGrowableArray(initial_size, 0, C_heap, F) {
> _data = (E*)raw_allocate(sizeof(E));
>
> and:
>
> GenericGrowableArray(int initial_size, int initial_len, bool c_heap,
> MEMFLAGS flags = mtNone) { _len = initial_len; _max = initial_size;
> _memflags = flags;
>
> and:
> void* GenericGrowableArray::raw_allocate(int elementSize) {
> ...
> return (void*)AllocateHeap(byte_size, _memflags);
>
> This means that the GrowableArray instance was accounted to mtModule,
> but the backing memory for the array was accounted to mtInternal.
>
> My proposal for fixing this is to fuse the (c_heap, flags) duality
> into one parameter (flags). The call sites are then changed like this:
>
> For resource allocations:
> GrowableArray(...) -> GrowableArray(...)
> GrowableArray(... /* c_heap */ false) -> GrowableArray(...)
> GrowableArray(... /* c_heap */ false, /* flags */ mtXX) ->
> GrowableArray(...)
>
> For CHeap allocations:
> GrowableArray(... /* c_heap */ true, /* flags */ mtXX) ->
> GrowableArray(..., mtXX)
> GrowableArray(... /* c_heap */ true) -> GrowableArray(..., mtInternal)
>
> That is, if you specify a "valid" mtXX tag it invokes the CHeap
> allocation path. If you don't specify a mtXX tag, then 'flags' get the
> mtNone default value. This is a marker for the code that no CHeap
> allocation should be done.
>
> While properly tagging all GrowableArray allocations, I went ahead and
> changed most GrowableArray mtInternal tags to the appropriate values.
> I also introduced a new mtServiceability tag, since a lot of the
> mtInternal tags were in areas dealing with serviceability code. I
> could split this out into a separate patch, if necessary.
>
> This hasn't been fully tested yet, because I'd like to get some early
> feedback.
>
> Thanks,
> StefanK
More information about the hotspot-dev
mailing list