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/
Best,
Tobias
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