RFR (M): 8006952: Slow VM due to excessive code cache freelist iteration

Vladimir Kozlov vladimir.kozlov at oracle.com
Thu Jan 31 12:57:50 PST 2013


New checks in compileBroker.cpp and in needs_flushing() will never be 
true if you keep the end of CodeCache for adapters 
((size(_free_segments)+ CodeCacheMinimumFreeSpace) > 
CodeCacheMinimumFreeSpace).
As result compilation will not be switched off and we will continue 
compile but will not able to allocate resulting nmethod.

unallocated_heap_capacity() code could be simpler instead of duplicating 
allocated_capacity() code:

return unallocated_capacity() - size(_free_segments);

And I would also rename it to unused_capacity().

You missed Compile::init_scratch_buffer_blob() which allocates temp 
buffer on CodeCache. And all places in output.cpp which allocate/resize 
buffer for emitting instructions.

Note, C2 uses 3 buffers: scratch buffer to calculate instruction size, 
buffer for code generation and final buffer for resulting nmethod into 
which we copy generated code from second buffer. Based on your approach 
all of them should not be critical.

On 1/31/13 10:40 AM, Nils Eliasson wrote:
> http://cr.openjdk.java.net/~neliasso/8006952/webrev.04/
>
> //N
>
> Vladimir Kozlov skrev 2013-01-30 21:16:
>> Nils, you sent webrev for other bug fix.
>>
>> Vladimir
>>
>> On 1/30/13 7:43 AM, Nils Eliasson wrote:
>>> Thanks for the link, interesting background.
>>>
>>> Even if finding the largest block on the freelist is free, we would
>>> still have a misbehavior when the free heap block is less than 1,5M and
>>> the flushing begins to create a 1,5M freelist block.
>>>
>>> Unallocated memory is a good measurement if have some continuous memory
>>> in reserve for critical blobs. I am thinking of using the thresholds
>>> against unallocated memory, but forbidding nmethods from using the last
>>> 0,5M (MinimumFreeSpace) from the heap block. That would prevent the VM
>>> from fragmenting the last continuous memory space, and allow the VM to
>>> use all of the freelist.
>>>
>>> Like this:
>>> http://cr.openjdk.java.net/~neliasso/8002364/webrev.03
>>>
>>> //Nils
>>>
>>> Vladimir Kozlov skrev 2013-01-29 20:35:
>>>> Nils,
>>>>
>>>> You are reversing 7025742 fix. I would prefer to keep track of a
>>>> largest free block during allocation in CodeCache (by using ordered
>>>> list or other technique) to avoid scanning the list.
>>>>
>>>> Vladimir
>>>>
>>>> On 1/29/13 2:56 AM, Nils Eliasson wrote:
>>>>> Remove continuous free block requirement for code cache flushing and
>>>>> minimum free space.
>>>>>
>>>>> This causes a degenerate behavior when the VM are repeatedly flushing
>>>>> the code cache trying to free up a continuous 1,5M block. Since the
>>>>> freelist is fragmented a significant part of the code cache is kept
>>>>> unallocated. A significant amount of time is spent traversing the
>>>>> freelist holding the code cache lock or waiting for other threads
>>>>> doing
>>>>> the same.
>>>>>
>>>>> I don't see any reason for why a continuous block is required. Code
>>>>> cache flushing threshold (CodeCacheFlushingMinimumFreeSpace) is
>>>>> default
>>>>> 1,5M and code cache minimum threshold (CodeCacheMinimumFreeSpace) is
>>>>> 0,5M. Finding such a block on the freelist is often unrealistic,
>>>>> and has
>>>>> not any purpose. The largest nmethods are in the order of 250k, and
>>>>> they
>>>>> are not allocated when code cache is starting to run out. All critical
>>>>> adapters are small and will fit easily in the freelist or in the
>>>>> remaining heap space.
>>>>>
>>>>> http://cr.openjdk.java.net/~neliasso/8006952/webrev.02/
>>>>>
>>>>> Thanks,
>>>>> Nils Eliasson
>>>
>


More information about the hotspot-compiler-dev mailing list