narrow_klass_shift is nonzero on jdk9...

Lindenmaier, Goetz goetz.lindenmaier at
Fri Jan 23 17:52:27 UTC 2015

Hi Andrew,

that's right, I reworked finding a position for the heap with Coleens help:

To find the heap, we now
  - search from 4G down to HeapBaseMinAddress for an unscaled heap, then
  - search from 31G (1G for classes) down for a zerobased heap, then
  - try some addresses that are 32G aligned, called disjoint base
    (useful on PPC, you can do (base | (cOop<<3))),
  - then, a last, desperate and arbitrary try.
See also the bug for some documentation.

This new algorithm makes the following heap placements possible.
 - zerobased mode possible on solaris 11
 - disjoint mode on PPC
 - zerobased and unscaled modes on AIX

The change only indirectly affects the compressed class space placement.
I didn't do any changes to that code.
But heaps on x86 etc should be placed at the same location as before, except
that heapbased can now be disjoint base.

I proposed to place the compressed class space in the lower 4G for 
big heaps, but that violates other constraints to it's placement.
(This should e.g. be possible for 8G heap which should be placed at 
23G in general, etc)

If I understand correctly, HeapBaseMinAddress is meant as a lower
bound to protect the space needed for the system, not as the address where 
the heap should be placed.  Actually, the code misuses it if it's set on the
command line to enforce heapbased mode, e.g., for tests.

Best regards,

-----Original Message-----
From: hotspot-dev [mailto:hotspot-dev-bounces at] On Behalf Of Coleen Phillimore
Sent: Friday, January 23, 2015 6:08 PM
To: hotspot-dev at
Subject: Re: narrow_klass_shift is nonzero on jdk9...

Hi Andrew,

Allocating this compressed class space is unfortunately complicated.  I 
think you're looking at an old version of the code though, Goetz has 
changed this and moved it to virtualspace.cpp.

The compressed class space is allocated above the heap because we want 
the java heap to have the most favorable compression algorithm.

The code also has a special case so that for zero-based compressed oops; 
it saves space for the compressed class space to also get zero-based 
compressed class pointers.  Decoding klasses without a base is better 
than decoding without a shift.   The code doesn't try to fit both 
compressed oops and compressed class pointers in the lower 4G.  It's 
generally improbable since the compressed class space is 1G size 
(because growing it is not supported atm)  and doing so generally pushes 
the java heap over the 4*G size.  Although I have to admit that 
HeapBaseMinAddress still mystifies me (for linux).


On 1/23/15, 11:48 AM, Andrew Haley wrote:
> ... when it doesn't need to be.
> The reason for this is that we allocate the heap at the end of the
> lower 4*G region and we allocate the metaspace immediately after the
> heap, so we always need a nonzero narrow_klass_shift because
> narrow_klass_base is not less than 32 bits.
> If I set HeapBaseMinAddress=2g it's fine.
> The code which puts the heap right at the end of the lower 4*G region
> is quite deliberate:
>      // Return specified base for the first request.
>      if (!FLAG_IS_DEFAULT(HeapBaseMinAddress) && (mode == UnscaledNarrowOop)) {
>        base = heap_base_min_address_aligned;
>      // If the total size is small enough to allow UnscaledNarrowOop then
>      // just use UnscaledNarrowOop.
>      } else if ((total_size <= OopEncodingHeapMax) && (mode != HeapBasedNarrowOop)) {
>        if ((total_size <= UnscaledOopHeapMax) && (mode == UnscaledNarrowOop) &&
>            (Universe::narrow_oop_shift() == 0)) {
>          // Use 32-bits oops without encoding and
>          // place heap's top on the 4Gb boundary
>          base = (UnscaledOopHeapMax - heap_size);
> Why do we do this?  I carefully set HeapBaseMinAddress in the AArch64
> back end to a sensible value which would in many cases get me a zero
> narrow_klass_shift, but this code ignores the default.
> Thanks,
> Andrew.

More information about the hotspot-dev mailing list