RFR (L): 8015774: Add support for multiple code heaps

Tobias Hartmann tobias.hartmann at oracle.com
Mon Jun 2 11:10:11 UTC 2014

Hi Igor,

I added the flag SegmentedCodeCache to enable/disable the code cache 
segmentation. Per default it is only enabled with TieredCompilation and 
a ReservedCodeCacheSize >= 240 MB.

New webrev: http://cr.openjdk.java.net/~thartmann/8015774/webrev.00/


On 22.04.2014 23:02, Igor Veresov wrote:
> Right, we could do something like you describe as a temporary measure. 
> All I’m saying that going forward we probably need to think about a 
> solution that is more memory efficient.
> igor
> On Apr 22, 2014, at 2:22 AM, Albert <albert.noll at oracle.com 
> <mailto:albert.noll at oracle.com>> wrote:
>> Hi Igor,
>> thanks for your ideas. Please see comment inline:
>> On 04/18/2014 12:10 AM, Igor Veresov wrote:
>>> Hi Tobias,
>>> See replies inline.
>>> On Apr 15, 2014, at 2:11 AM, Tobias Hartmann 
>>> <tobias.hartmann at oracle.com <mailto:tobias.hartmann at oracle.com>> wrote:
>>>> Hi Igor,
>>>> On 04/15/2014 12:15 AM, Igor Veresov wrote:
>>>>> codeCache.hpp:
>>>>> I guess CodeCache::_save_nmethods is not longer necessary since we 
>>>>> ripped out the speculative disconnect?
>>>> Yes, seems like this reappeared during merging. I removed it.
>>>>> codeCache.cpp:
>>>>> Why are these necessary?
>>>>>   51 #ifdef COMPILER1
>>>>>   52 #include "c1/c1_Compilation.hpp"
>>>>>   53 #endif
>>>>>   54 #ifdef COMPILER2
>>>>>   55 #include "opto/compile.hpp"
>>>>>   56 #endif
>>>> Because in CodeCache::initialize_heaps() the size of the C1 and C2 
>>>> code buffers have to be determined (see lines 156 and 165) to set 
>>>> the size of the non-method code heap.
>>> Alright, it feels like it should be abstracted away somehow but I 
>>> don’t see a good way of doing it that early in initialization.
>>>>> arguments.cpp:
>>>>> I know you’re working on the adaptive resizing solution. How are 
>>>>> you planning to implement it?
>>>>> Since it would be expensive to do compaction, the degree of 
>>>>> resizing possible will be hampered by fragmentation. Perhaps there 
>>>>> should be another allocation layer that gives preference to for 
>>>>> certain allocation type to be allocated in specific areas, but 
>>>>> does not preclude allocation in other areas? For example if we’re 
>>>>> out of space for C2 methods we would be allowed to allocate in the 
>>>>> C1 space. Is it something like that?
>>>> While working for my masters thesis, I already implemented a fully 
>>>> working patch. The dynamic resizing of the code heaps works by 
>>>> placing the profiled and the non-profiled code heaps adjacent to 
>>>> each other in memory. Both heaps grow towards the shared boundary 
>>>> (one towards the higher and one towards the lower addresses). Like 
>>>> this it is possible to move the boundary and therefore resize the 
>>>> code heaps, as long as there is enough free space around.
>>>> One problem is that there may be a lot of free space in one code 
>>>> heap, but as long as there is no free space at the boundary we are 
>>>> not able to resize. One solution would be to modify the sweeper 
>>>> such that it tends to remove more methods at the boundary.
>>>> However, measurements showed that the dynamic resizing does not 
>>>> improve performance. This is partly due to an increased amount of 
>>>> sweeping. Further, a lot of code had to be changed to support 
>>>> downwards growing code heaps and the resizing of virtual spaces, 
>>>> leading to an increased complexity.
>>> Could you please measure how much space to we waste for typical 
>>> workloads without the resizing? Perhaps turn the flusher off and see 
>>> what’s the minimum code cache size is required before and after the 
>>> change? Obviously we can tune it for a particular workload, but is 
>>> there a good average solution?
>>> Simply wasting potentially a large amount of space is not good. 
>>> Perhaps the allocation strategy should be more flexible (boundary 
>>> moving without compaction will likely get stuck because of the 
>>> fragmentation). For example it can work as follows:
>>> - Each code cache has a free list from which it allocates. We 
>>> populate these at startup according to the initial boundaries that 
>>> you determined.
>>> - There are n lists per heap to track allocated blobs. Lets call 
>>> those “allocated lists”. One list is for local allocations, and then 
>>> there is a list for each other heap we may try allocating from.
>>> - When allocating you first try to allocate locally. If succeeded 
>>> you splice the block from the local free list and put it on local 
>>> allocated list.
>>> - If there are no fitting local blocks, you consider the free lists 
>>> of other heaps. If you can successfully allocate from there, you 
>>> splice the block from the free list, and transfer it to the 
>>> corresponding allocated list of the heap you allocated for.
>>> - When you free a block you return it to the free list of the heap 
>>> it was allocated from.
>>> - Iterating over blobs for a particular heap is done by iterating 
>>> over all its allocated lists.
>>> - Optionally, may be the free lists should be sorted in address 
>>> order to get nicer clustering (may be use skip lists for that?)
>>> Or may be there is some other solution with less coding... But I 
>>> think we should keep using the space as efficiently as before or 
>>> close to that.
>> I discussed your suggestions with Tobias. Here is what we came up with:
>> Using memory as efficient as possible is important. However, if we 
>> allow to allocate all types of code into all
>> heaps (segments) we do not need a segmented code cache. A simpler 
>> solution to get a potentially better code
>> locality is to define 'logical' memory regions - within a single code 
>> heap - into which different code types are
>> preferably allocated. If there is free space,  we allocate into the 
>> preferred memory region and if there is no free
>> space left, we allocate somewhere else.
>> Would it be a solution to provide an implementation where we can 
>> disable/enable code cache segmentation at JVM startup?
>> I.e., we could enable the segmented code cache with 
>> -XX:+TieredCompilation -XX:ReservedCodeCacheSize=265m and
>> disable it otherwise. Tiered compilation + 256mb code cache never 
>> resulted in performance regression for the application
>> we tested. However, we still might not use memory as efficient as in 
>> the old version.
>> Best,
>> Albert
>>>>> I think if we want to push the current solution we have to bump 
>>>>> the code cache size temporarily up until we have an allocation 
>>>>> strategy that doesn’t waste space so much. Otherwise there’re 
>>>>> might be regressions for applications that work fine with the 
>>>>> current setup.
>>>> Yes, I agree.
>>>>> sweeper.cpp:
>>>>> I agree with Vladimir, I’d be nice to make code cache iteration 
>>>>> more abstract and not expose nmethod types when doing it.
>>>> Yes, I will have a look at it.
>>>>> globals.hpp:
>>>>> We probably don’t need all of those spaces for the 
>>>>> interpreter-only configuration:
>>>>>  190 define_pd_global(intx, NonProfiledCodeHeapSize,      14*M);
>>>>>  191 define_pd_global(intx, ProfiledCodeHeapSize,         15*M );
>>>>>  192 define_pd_global(intx, NonMethodCodeHeapSize,        3*M );
>>>> Indeed. I think in this case we only need the non-method code heap. 
>>>> I tried to build an interpreter only VM with "make 
>>>> all_fastdebugcore" but apparently this is not supported anymore 
>>>> ("No (fastdebugcore) for x86"). Are there platforms where this is 
>>>> still supported? Or is it enough to decide according to the -Xint 
>>>> option?
>>> Hm.. no sure, I wan’t aware we don’t do core builds anymore. Could 
>>> you use all the space for NonMethodCodeHeap in this case and for 
>>> Xint ? Will setting all other guys to 0 work?
>>> igor
>>>> Thanks,
>>>> Tobias
>>>>> igor
>>>>>  On Apr 14, 2014, at 6:05 AM, Tobias Hartmann 
>>>>> <tobias.hartmann at oracle.com <mailto:tobias.hartmann at oracle.com>> 
>>>>> wrote:
>>>>>> Hi Volker,
>>>>>> please see comments inline.
>>>>>> On 04/14/2014 02:54 PM, Volker Simonis wrote:
>>>>>>> Hi Tobias,
>>>>>>> is this change intended for jdk8 or 9?
>>>>>> the change is intended for JDK 9. The webrev is based on the JDK 
>>>>>> 9 repository (http://hg.openjdk.java.net/jdk9/hs-comp/hotspot) 
>>>>>> changeset 6280.
>>>>>>>  In any case, I saw that your
>>>>>>> webrev is based on the hsx repository which I thought should not be
>>>>>>> used any more.
>>>>>> Why do you think that it is based on hsx? The earlier versions 00 
>>>>>> - 03 actually were, because I already started developing the 
>>>>>> patch last year, but the newest one is based on the JDK 9 repository.
>>>>>> As Roland noticed, the default code heap sizes for arm/ppc were 
>>>>>> wrong (because tiered compilation is supported). The updated 
>>>>>> webrev can be found at:
>>>>>> http://cr.openjdk.java.net/~anoll/8015774/webrev.05/ 
>>>>>> <http://cr.openjdk.java.net/%7Eanoll/8015774/webrev.05/>
>>>>>> Thanks,
>>>>>> Tobias
>>>>>>> Could you please rebase your patch on jdk9 and also
>>>>>>> update the corresponding ppc64 files in the webrev (as far as I can
>>>>>>> see, that's only src/cpu/ppc/vm/c2_globals_ppc.hpp). I'd like to 
>>>>>>> test
>>>>>>> this on Linux/PPC64 and AIX as well.
>>>>>>> Thank you and best regards,
>>>>>>> Volker
>>>>>>> On Mon, Apr 14, 2014 at 1:56 PM, Tobias Hartmann
>>>>>>> <Tobias.Hartmann at oracle.com>
>>>>>>>  wrote:
>>>>>>>> Hi,
>>>>>>>> please review the new version of the following patch that adds 
>>>>>>>> support for
>>>>>>>> multiple code heaps to the code cache.
>>>>>>>> Bug:
>>>>>>>> https://bugs.openjdk.java.net/browse/JDK-8015774
>>>>>>>> Webrev:
>>>>>>>> http://cr.openjdk.java.net/~anoll/8015774/webrev.04/
>>>>>>>> Short description:
>>>>>>>> This change implements support for multiple code heaps in the 
>>>>>>>> code cache.
>>>>>>>> The interface of the code cache was changed accordingly and 
>>>>>>>> references from
>>>>>>>> other components of the VM were adapted. This includes the indirect
>>>>>>>> references from:
>>>>>>>> - the Serviceability Agent: vmStructs and the Java code cache 
>>>>>>>> interface
>>>>>>>> (sun.jvm.hotspot.code.CodeCache)
>>>>>>>> - the dtrace ustack helper script (jhelper.d)
>>>>>>>> - the pstack support library libjvm_db.c
>>>>>>>> Currently the code cache contains the following three code 
>>>>>>>> heaps each of
>>>>>>>> which contains CodeBlobs of a specific type:
>>>>>>>> - Non-Profiled methods: nmethods that are not profiled and 
>>>>>>>> native methods
>>>>>>>> - Profiled methods: nmethods that are profiled
>>>>>>>> - Non-methods: Non-methods like buffers and adapters
>>>>>>>> By default the non-method code heap uses 3 MB plus additional 
>>>>>>>> space for the
>>>>>>>> compiler buffers that is dependent on the number of compiler 
>>>>>>>> threads (see
>>>>>>>> CodeCache::initialize_heaps). The remaining code cache space is 
>>>>>>>> distributed
>>>>>>>> equally among the non-profiled and the profiled code heaps.
>>>>>>>> Tested:
>>>>>>>> JPRT, SPECjvm2008, SPECjbb2005, SPECjbb2013, Octane + Nashorn
>>>>>>>> Thanks,
>>>>>>>> Tobias
>>>>>>>> -------- Original Message --------
>>>>>>>> Subject: Re: RFR (L): 8015774: Add support for multiple code heaps
>>>>>>>> Date: Mon, 21 Oct 2013 17:47:48 +0200
>>>>>>>> From: Albert Noll
>>>>>>>> <albert.noll at oracle.com>
>>>>>>>> To: Azeem Jiva
>>>>>>>> <azeem.jiva at oracle.com>
>>>>>>>> That is fine. As we realized the last two weeks, there is more 
>>>>>>>> work to be
>>>>>>>> done to make multiple code heaps work effectively.
>>>>>>>> Albert
>>>>>>>> Von meinem iPhone gesendet
>>>>>>>> Am 21.10.2013 um 17:36 schrieb Azeem Jiva
>>>>>>>> <azeem.jiva at oracle.com>
>>>>>>>> :
>>>>>>>> I still think we should hold off for JDK8u20
>>>>>>>> --
>>>>>>>> Azeem Jiva
>>>>>>>> @javawithjiva
>>>>>>>> On Oct 21, 2013, at 8:33 AM, Albert Noll
>>>>>>>> <albert.noll at oracle.com>
>>>>>>>>  wrote:
>>>>>>>> Von meinem iPhone gesendet
>>>>>>>> Anfang der weitergeleiteten E‑Mail:
>>>>>>>> Von: Vladimir Kozlov
>>>>>>>> <vladimir.kozlov at oracle.com>
>>>>>>>> Datum: 11. Oktober 2013 19:38:07 MESZ
>>>>>>>> An:
>>>>>>>> hotspot-compiler-dev at openjdk.java.net
>>>>>>>> Betreff: Re: RFR (L): 8015774: Add support for multiple code heaps
>>>>>>>> This looks acceptable.
>>>>>>>> Thanks,
>>>>>>>> Vladimir

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.openjdk.java.net/pipermail/hotspot-compiler-dev/attachments/20140602/4ed6e9a4/attachment-0001.html>

More information about the hotspot-compiler-dev mailing list