RFR: 8203885: ConcurrentLocksDump::dump_at_safepoint() should not allocate array in resource area

Daniel D. Daugherty daniel.daugherty at oracle.com
Thu Jun 7 19:16:27 UTC 2018


On 5/29/18 7:48 AM, coleen.phillimore at oracle.com wrote:
>
>
> On 5/29/18 2:20 AM, Per Liden wrote:
>> Hi Kim,
>>
>> On 05/29/2018 08:09 AM, Kim Barrett wrote:
>>>> On May 28, 2018, at 8:16 AM, Per Liden <per.liden at oracle.com> wrote:
>>>>
>>>> ConcurrentLocksDump::dump_at_safepoint() creates a GrowableArray, 
>>>> which gets allocated in a resource area. This array is than passed 
>>>> down a call chain, where it can't control that another ResourceMark 
>>>> isn't created. In the leaf of this call chain, a closure 
>>>> (FindInstanceClosure) is executed, which appends to the array, 
>>>> which means it might need to be resized. This doesn't work if a new 
>>>> ResourceMark has been created, since the array resize will happen 
>>>> in a nested ResourceArea context. As a result, the append operation 
>>>> fails in GenericGrowableArray::check_nesting().
>>>>
>>>> This has so far gone unnoticed because 
>>>> CollectedHeap::object_iterate() in existing collectors typically 
>>>> don't create new ResourceMarks. This is not true for ZGC (and 
>>>> potentially other concurrent collectors), which needs to walk 
>>>> thread stacks, which in turn requires a ResourceMark.
>>>>
>>>> The proposed fix is to make this array C Heap allocated.
>>>>
>>>> Bug: https://bugs.openjdk.java.net/browse/JDK-8203885
>>>> Webrev: http://cr.openjdk.java.net/~pliden/8203885/webrev.0
>>>>
>>>> Testing: hs-tier{1,3}
>>>>
>>>> /Per
>>>
>>> Looks good.
>>
>> Thanks for reviewing!
>>
>>>
>>> I was going to ask why the GrowableArray needs to be heap allocated?
>>> Why not just
>>>
>>>    GrowableArray<oop> aos_objects(INITIAL_ARRAY_SIZE, true);
>>>    ... s/aos_objects/&aos_objects/ ...
>>>    // delete aos_objects no longer needed
>>>
>>> After some digging, probably because of this, from growableArray.hpp:
>>>
>>> 119    assert(!on_C_heap() || allocated_on_C_heap(), "growable array 
>>> must be on C heap if elements are");
>>
>> I had the same reaction and initially made it stack allocated, but 
>> noticed that GrowableArray doesn't allow that :(
>>
>>>
>>> Conflating the allocation of the GrowableArray object with the
>>> allocation of the underlying array.  That seems wrong, but not a
>>> problem to be solved as part of this change.
>>>
>>
>> I agree. I suspect someone wanted to protect against potential 
>> problems with having different life cycles of the GrowableArray and 
>> the backing array. But this seems overly strict.
>
> Yes, this is exactly the reason, and we did have bugs.  That's why we 
> have this check.

If I remember the history correctly, you could have a GrowableArray
object that was stack allocated and elements that were C-heap allocated.
When the stack allocated GrowableArray object was freed, we lost track
of the C-heap allocated elements...

Yes, we could have changed the stack allocated GrowableArray object to
free the C-heap allocated elements, but then the life-cycle started to
get confusing... As in: why was my C-heap allocated data freed without
my permission? Oh... I didn't C-heap allocate my GrowableArray object
so my C-heap allocated data was freed... stuff like that...

Dan


Dan


>
> Coleen
>
>>
>> /Per
>



More information about the hotspot-dev mailing list