--- old/src/hotspot/share/gc/shenandoah/shenandoahCollectionSet.cpp 2020-05-21 12:06:06.035975204 +0200 +++ new/src/hotspot/share/gc/shenandoah/shenandoahCollectionSet.cpp 2020-05-21 12:06:05.567975366 +0200 @@ -33,10 +33,10 @@ #include "services/memTracker.hpp" #include "utilities/copy.hpp" -ShenandoahCollectionSet::ShenandoahCollectionSet(ShenandoahHeap* heap, char* heap_base, size_t size) : +ShenandoahCollectionSet::ShenandoahCollectionSet(ShenandoahHeap* heap, ReservedSpace space, char* heap_base) : _map_size(heap->num_regions()), _region_size_bytes_shift(ShenandoahHeapRegion::region_size_bytes_shift()), - _map_space(align_up(((uintx)heap_base + size) >> _region_size_bytes_shift, os::vm_allocation_granularity())), + _map_space(space), _cset_map(_map_space.base() + ((uintx)heap_base >> _region_size_bytes_shift)), _biased_cset_map(_map_space.base()), _heap(heap), --- old/src/hotspot/share/gc/shenandoah/shenandoahCollectionSet.hpp 2020-05-21 12:06:07.463974709 +0200 +++ new/src/hotspot/share/gc/shenandoah/shenandoahCollectionSet.hpp 2020-05-21 12:06:07.023974861 +0200 @@ -51,7 +51,7 @@ shenandoah_padding(1); public: - ShenandoahCollectionSet(ShenandoahHeap* heap, char* heap_base, size_t size); + ShenandoahCollectionSet(ShenandoahHeap* heap, ReservedSpace space, char* heap_base); // Add region to collection set void add_region(ShenandoahHeapRegion* r); --- old/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp 2020-05-21 12:06:08.883974216 +0200 +++ new/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp 2020-05-21 12:06:08.447974367 +0200 @@ -292,9 +292,35 @@ "Cannot commit region memory"); } + // Try to fit the collection set bitmap at lower addresses. This optimizes code generation for cset checks. + // Go up until a sensible limit (subject to encoding constraints) and try to reserve the space there. + // If not successful, bite a bullet and allocate at whatever address. + { + size_t cset_align = MAX2(os::vm_page_size(), os::vm_allocation_granularity()); + size_t cset_size = align_up(((size_t) sh_rs.base() + sh_rs.size()) >> ShenandoahHeapRegion::region_size_bytes_shift(), cset_align); + + uintptr_t min = round_up_power_of_2(cset_align); + uintptr_t max = (1u << 30u); + + for (uintptr_t addr = min; addr <= max; addr <<= 1u) { + char* req_addr = (char*)addr; + assert(is_aligned(req_addr, cset_align), "Should be aligned"); + ReservedSpace cset_rs(cset_size, os::vm_page_size(), false, req_addr); + if (cset_rs.is_reserved()) { + assert(cset_rs.base() == req_addr, "Allocated where requested: " PTR_FORMAT ", " PTR_FORMAT, p2i(cset_rs.base()), addr); + _collection_set = new ShenandoahCollectionSet(this, cset_rs, sh_rs.base()); + break; + } + } + + if (_collection_set == NULL) { + ReservedSpace cset_rs(cset_size, os::vm_page_size(), false); + _collection_set = new ShenandoahCollectionSet(this, cset_rs, sh_rs.base()); + } + } + _regions = NEW_C_HEAP_ARRAY(ShenandoahHeapRegion*, _num_regions, mtGC); _free_set = new ShenandoahFreeSet(this, _num_regions); - _collection_set = new ShenandoahCollectionSet(this, sh_rs.base(), sh_rs.size()); { ShenandoahHeapLocker locker(lock());