--- old/src/hotspot/share/gc/shenandoah/shenandoahCollectionSet.cpp 2020-05-20 15:10:46.537806467 +0200 +++ new/src/hotspot/share/gc/shenandoah/shenandoahCollectionSet.cpp 2020-05-20 15:10:46.233804357 +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-20 15:10:47.305811788 +0200 +++ new/src/hotspot/share/gc/shenandoah/shenandoahCollectionSet.hpp 2020-05-20 15:10:46.997809657 +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-20 15:10:48.081817159 +0200 +++ new/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp 2020-05-20 15:10:47.769815001 +0200 @@ -292,9 +292,31 @@ "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 and try to reserve the space there. + // If not successful, bite a bullet and allocate at whatever address. + { + int cset_align = MAX2(os::vm_page_size(), os::vm_allocation_granularity()); + uintx cset_size = align_up(((uintx) 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 << 31u); + for (uintptr_t cset_base = min; cset_base <= max; cset_base <<= 1u) { + ReservedSpace cset_rs(cset_size, os::vm_page_size(), false, (char*) cset_base); + if (cset_rs.is_reserved()) { + assert((char*)cset_base == cset_rs.base(), "Addresses should agree: " PTR_FORMAT ", " PTR_FORMAT, cset_base, p2i(cset_rs.base())); + _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());