diff --git a/src/hotspot/share/gc/shenandoah/shenandoahAllocRequest.hpp b/src/hotspot/share/gc/shenandoah/shenandoahAllocRequest.hpp index 78ae78f4c24..05ecfb254a2 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahAllocRequest.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahAllocRequest.hpp @@ -31,15 +31,37 @@ class ShenandoahAllocRequest : StackObj { public: - enum Type { - _alloc_shared, // Allocate common, outside of TLAB - _alloc_shared_gc, // Allocate common, outside of GCLAB/PLAB - _alloc_cds, // Allocate for CDS - _alloc_tlab, // Allocate TLAB - _alloc_gclab, // Allocate GCLAB - _alloc_plab, // Allocate PLAB - _ALLOC_LIMIT - }; + // Alloc type is an int value with encoded bits in scheme as: + // [x|xx|xx|xx] + // ^---- Requester: + // 00 -- mutator + // 10 -- mutator (CDS) + // 01 -- GC + // ^------- Purpose: + // 00 -- shared + // 01 -- TLAB/GCLAB + // 11 -- PLAB + // ^---------- Affiliation: + // 00 -- YOUNG + // 01 -- OLD + // 11 -- OLD, promotion + typedef int Type; + + static constexpr int bit_gc_alloc = 1 << 0; + static constexpr int bit_cds_alloc = 1 << 1; + static constexpr int bit_lab_alloc = 1 << 2; + static constexpr int bit_plab_alloc = 1 << 3; + static constexpr int bit_old_alloc = 1 << 4; + static constexpr int bit_promotion_alloc = 1 << 5; + + static constexpr Type _alloc_shared = 0; + static constexpr Type _alloc_tlab = bit_lab_alloc; + static constexpr Type _alloc_cds = bit_cds_alloc; + static constexpr Type _alloc_shared_gc = bit_gc_alloc; + static constexpr Type _alloc_shared_gc_old = bit_gc_alloc | bit_old_alloc; + static constexpr Type _alloc_shared_gc_promotion = bit_gc_alloc | bit_old_alloc | bit_promotion_alloc; + static constexpr Type _alloc_gclab = bit_gc_alloc | bit_lab_alloc; + static constexpr Type _alloc_plab = bit_gc_alloc | bit_lab_alloc | bit_plab_alloc | bit_old_alloc; static const char* alloc_type_to_string(Type type) { switch (type) { @@ -47,6 +69,10 @@ public: return "Shared"; case _alloc_shared_gc: return "Shared GC"; + case _alloc_shared_gc_old: + return "Shared GC Old"; + case _alloc_shared_gc_promotion: + return "Shared GC Promotion"; case _alloc_cds: return "CDS"; case _alloc_tlab: @@ -80,20 +106,14 @@ private: // This is the type of the request. Type _alloc_type; - // This is the generation which the request is targeting. - ShenandoahAffiliation const _affiliation; - - // True if this request is trying to copy any object from young to old (promote). - bool _is_promotion; - #ifdef ASSERT // Check that this is set before being read. bool _actual_size_set; #endif - ShenandoahAllocRequest(size_t _min_size, size_t _requested_size, Type _alloc_type, ShenandoahAffiliation affiliation, bool is_promotion = false) : + ShenandoahAllocRequest(size_t _min_size, size_t _requested_size, Type _alloc_type) : _min_size(_min_size), _requested_size(_requested_size), - _actual_size(0), _waste(0), _alloc_type(_alloc_type), _affiliation(affiliation), _is_promotion(is_promotion) + _actual_size(0), _waste(0), _alloc_type(_alloc_type) #ifdef ASSERT , _actual_size_set(false) #endif @@ -101,31 +121,34 @@ private: public: static inline ShenandoahAllocRequest for_tlab(size_t min_size, size_t requested_size) { - return ShenandoahAllocRequest(min_size, requested_size, _alloc_tlab, ShenandoahAffiliation::YOUNG_GENERATION); + return ShenandoahAllocRequest(min_size, requested_size, _alloc_tlab); } static inline ShenandoahAllocRequest for_gclab(size_t min_size, size_t requested_size) { - return ShenandoahAllocRequest(min_size, requested_size, _alloc_gclab, ShenandoahAffiliation::YOUNG_GENERATION); + return ShenandoahAllocRequest(min_size, requested_size, _alloc_gclab); } static inline ShenandoahAllocRequest for_plab(size_t min_size, size_t requested_size) { - return ShenandoahAllocRequest(min_size, requested_size, _alloc_plab, ShenandoahAffiliation::OLD_GENERATION); + return ShenandoahAllocRequest(min_size, requested_size, _alloc_plab); } static inline ShenandoahAllocRequest for_shared_gc(size_t requested_size, ShenandoahAffiliation affiliation, bool is_promotion = false) { if (is_promotion) { - assert(affiliation == ShenandoahAffiliation::OLD_GENERATION, "Should only promote to old generation"); - return ShenandoahAllocRequest(0, requested_size, _alloc_shared_gc, affiliation, true); + assert(affiliation == OLD_GENERATION, "Should only promote to old generation"); + return ShenandoahAllocRequest(0, requested_size, _alloc_shared_gc_promotion); } - return ShenandoahAllocRequest(0, requested_size, _alloc_shared_gc, affiliation); + if (affiliation == OLD_GENERATION) { + return ShenandoahAllocRequest(0, requested_size, _alloc_shared_gc_old); + } + return ShenandoahAllocRequest(0, requested_size, _alloc_shared_gc); } static inline ShenandoahAllocRequest for_shared(size_t requested_size) { - return ShenandoahAllocRequest(0, requested_size, _alloc_shared, ShenandoahAffiliation::YOUNG_GENERATION); + return ShenandoahAllocRequest(0, requested_size, _alloc_shared); } static inline ShenandoahAllocRequest for_cds(size_t requested_size) { - return ShenandoahAllocRequest(0, requested_size, _alloc_cds, ShenandoahAffiliation::YOUNG_GENERATION); + return ShenandoahAllocRequest(0, requested_size, _alloc_cds); } inline size_t size() const { @@ -167,71 +190,35 @@ public: } inline bool is_mutator_alloc() const { - switch (_alloc_type) { - case _alloc_tlab: - case _alloc_shared: - case _alloc_cds: - return true; - case _alloc_gclab: - case _alloc_plab: - case _alloc_shared_gc: - return false; - default: - ShouldNotReachHere(); - return false; - } + return (_alloc_type & bit_gc_alloc) == 0; } inline bool is_gc_alloc() const { - switch (_alloc_type) { - case _alloc_tlab: - case _alloc_shared: - case _alloc_cds: - return false; - case _alloc_gclab: - case _alloc_plab: - case _alloc_shared_gc: - return true; - default: - ShouldNotReachHere(); - return false; - } + return (_alloc_type & bit_gc_alloc) != 0; } inline bool is_lab_alloc() const { - switch (_alloc_type) { - case _alloc_tlab: - case _alloc_gclab: - case _alloc_plab: - return true; - case _alloc_shared: - case _alloc_shared_gc: - case _alloc_cds: - return false; - default: - ShouldNotReachHere(); - return false; - } + return (_alloc_type & bit_lab_alloc) != 0; } - bool is_old() const { - return _affiliation == OLD_GENERATION; + inline bool is_old() const { + return (_alloc_type & bit_old_alloc) != 0; } - bool is_young() const { - return _affiliation == YOUNG_GENERATION; + inline bool is_young() const { + return (_alloc_type & bit_old_alloc) == 0; } - ShenandoahAffiliation affiliation() const { - return _affiliation; + inline ShenandoahAffiliation affiliation() const { + return (_alloc_type & bit_old_alloc) == 0 ? YOUNG_GENERATION : OLD_GENERATION ; } const char* affiliation_name() const { - return shenandoah_affiliation_name(_affiliation); + return shenandoah_affiliation_name(affiliation()); } - bool is_promotion() const { - return _is_promotion; + inline bool is_promotion() const { + return (_alloc_type & bit_promotion_alloc) != 0; } }; diff --git a/src/hotspot/share/gc/shenandoah/shenandoahFreeSet.cpp b/src/hotspot/share/gc/shenandoah/shenandoahFreeSet.cpp index 0deb3b5ba4c..ab7985b3d34 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahFreeSet.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahFreeSet.cpp @@ -1311,19 +1311,11 @@ HeapWord* ShenandoahFreeSet::allocate_single(ShenandoahAllocRequest& req, bool& // Overwrite with non-zero (non-null) values only if necessary for allocation bookkeeping. - switch (req.type()) { - case ShenandoahAllocRequest::_alloc_tlab: - case ShenandoahAllocRequest::_alloc_shared: - case ShenandoahAllocRequest::_alloc_cds: - return allocate_for_mutator(req, in_new_region); - case ShenandoahAllocRequest::_alloc_gclab: - case ShenandoahAllocRequest::_alloc_plab: - case ShenandoahAllocRequest::_alloc_shared_gc: - return allocate_for_collector(req, in_new_region); - default: - ShouldNotReachHere(); + if (req.is_mutator_alloc()) { + return allocate_for_mutator(req, in_new_region); + } else { + return allocate_for_collector(req, in_new_region); } - return nullptr; } HeapWord* ShenandoahFreeSet::allocate_for_mutator(ShenandoahAllocRequest &req, bool &in_new_region) { @@ -1619,21 +1611,13 @@ HeapWord* ShenandoahFreeSet::try_allocate_in(ShenandoahHeapRegion* r, Shenandoah if (req.is_mutator_alloc()) { request_generation = _heap->mode()->is_generational()? _heap->young_generation(): _heap->global_generation(); orig_partition = ShenandoahFreeSetPartitionId::Mutator; - } else if (req.type() == ShenandoahAllocRequest::_alloc_gclab) { - request_generation = _heap->mode()->is_generational()? _heap->young_generation(): _heap->global_generation(); - orig_partition = ShenandoahFreeSetPartitionId::Collector; - } else if (req.type() == ShenandoahAllocRequest::_alloc_plab) { + } else if (req.is_old()) { request_generation = _heap->old_generation(); orig_partition = ShenandoahFreeSetPartitionId::OldCollector; } else { - assert(req.type() == ShenandoahAllocRequest::_alloc_shared_gc, "Unexpected allocation type"); - if (req.is_old()) { - request_generation = _heap->old_generation(); - orig_partition = ShenandoahFreeSetPartitionId::OldCollector; - } else { - request_generation = _heap->mode()->is_generational()? _heap->young_generation(): _heap->global_generation(); - orig_partition = ShenandoahFreeSetPartitionId::Collector; - } + // Not old collector alloc, so this is a young collector gclab or shared allocation + request_generation = _heap->mode()->is_generational()? _heap->young_generation(): _heap->global_generation(); + orig_partition = ShenandoahFreeSetPartitionId::Collector; } if (alloc_capacity(r) < PLAB::min_size() * HeapWordSize) { // Regardless of whether this allocation succeeded, if the remaining memory is less than PLAB:min_size(), retire this region. diff --git a/src/hotspot/share/gc/shenandoah/shenandoahHeapRegion.inline.hpp b/src/hotspot/share/gc/shenandoah/shenandoahHeapRegion.inline.hpp index cad9dc0e932..636f65e2553 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahHeapRegion.inline.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahHeapRegion.inline.hpp @@ -129,6 +129,8 @@ inline void ShenandoahHeapRegion::adjust_alloc_metadata(ShenandoahAllocRequest:: switch (type) { case ShenandoahAllocRequest::_alloc_shared: case ShenandoahAllocRequest::_alloc_shared_gc: + case ShenandoahAllocRequest::_alloc_shared_gc_old: + case ShenandoahAllocRequest::_alloc_shared_gc_promotion: case ShenandoahAllocRequest::_alloc_cds: // Counted implicitly by tlab/gclab allocs break;