diff --git a/src/hotspot/share/runtime/flags/jvmFlag.cpp b/src/hotspot/share/runtime/flags/jvmFlag.cpp index 1917cd4b198..c465a942e5c 100644 --- a/src/hotspot/share/runtime/flags/jvmFlag.cpp +++ b/src/hotspot/share/runtime/flags/jvmFlag.cpp @@ -31,6 +31,7 @@ #include "runtime/flags/jvmFlagAccess.hpp" #include "runtime/flags/jvmFlagLookup.hpp" #include "runtime/globals_extension.hpp" +#include "utilities/bitMap.hpp" #include "utilities/defaultStream.hpp" #include "utilities/stringUtils.hpp" @@ -692,7 +693,7 @@ void JVMFlag::printFlags(outputStream* out, bool withComments, bool printRanges, // called as part of error reporting, so handle native OOMs gracefully. // The last entry is the null entry. - const size_t length = JVMFlag::numFlags - 1; + constexpr size_t length = (sizeof(flagTable) / sizeof(JVMFlag)) - 1; // Print if (!printRanges) { @@ -701,26 +702,26 @@ void JVMFlag::printFlags(outputStream* out, bool withComments, bool printRanges, out->print_cr("[Global flags ranges]"); } - // Sort - JVMFlag** array = NEW_C_HEAP_ARRAY_RETURN_NULL(JVMFlag*, length, mtArguments); - if (array != nullptr) { + BitMap::bm_word_t iteratorArray[BitMap::calc_size_in_words(length)]; + BitMapView iteratorMarkers(iteratorArray, length); + iteratorMarkers.clear_range(0, length); + // Print the flag with best sort value, then mark it. + for (size_t j = 0; j < length; j++) { + JVMFlag* bestFlag = nullptr; + size_t bestFlagIndex = 0; for (size_t i = 0; i < length; i++) { - array[i] = &flagTable[i]; - } - qsort(array, length, sizeof(JVMFlag*), compare_flags); - - for (size_t i = 0; i < length; i++) { - if (array[i]->is_unlocked() && !(skipDefaults && array[i]->is_default())) { - array[i]->print_on(out, withComments, printRanges); + const bool skip = (skipDefaults && flagTable[i].is_default()); + const bool visited = iteratorMarkers.at(i); + if (!visited && flagTable[i].is_unlocked() && !skip) { + if ((bestFlag == nullptr) || (strcmp(bestFlag->name(), flagTable[i].name()) > 0)) { + bestFlag = &flagTable[i]; + bestFlagIndex = i; + } } } - FREE_C_HEAP_ARRAY(JVMFlag*, array); - } else { - // OOM? Print unsorted. - for (size_t i = 0; i < length; i++) { - if (flagTable[i].is_unlocked() && !(skipDefaults && flagTable[i].is_default())) { - flagTable[i].print_on(out, withComments, printRanges); - } + if (bestFlag != nullptr) { + bestFlag->print_on(out, withComments, printRanges); + iteratorMarkers.at_put(bestFlagIndex, true); } } } diff --git a/src/hotspot/share/utilities/bitMap.cpp b/src/hotspot/share/utilities/bitMap.cpp index 9bd5c8e0006..a0780707091 100644 --- a/src/hotspot/share/utilities/bitMap.cpp +++ b/src/hotspot/share/utilities/bitMap.cpp @@ -197,11 +197,6 @@ bm_word_t* CHeapBitMap::reallocate(bm_word_t* map, size_t old_size_in_words, siz } #ifdef ASSERT -void BitMap::verify_size(idx_t size_in_bits) { - assert(size_in_bits <= max_size_in_bits(), - "out of bounds: " SIZE_FORMAT, size_in_bits); -} - void BitMap::verify_index(idx_t bit) const { assert(bit < _size, "BitMap index out of bounds: " SIZE_FORMAT " >= " SIZE_FORMAT, diff --git a/src/hotspot/share/utilities/bitMap.hpp b/src/hotspot/share/utilities/bitMap.hpp index 0d592de7cd0..5db12badbc9 100644 --- a/src/hotspot/share/utilities/bitMap.hpp +++ b/src/hotspot/share/utilities/bitMap.hpp @@ -67,16 +67,16 @@ class BitMap { protected: // The maximum allowable size of a bitmap, in words or bits. // Limit max_size_in_bits so aligning up to a word boundary never overflows. - static idx_t max_size_in_words() { return raw_to_words_align_down(~idx_t(0)); } - static idx_t max_size_in_bits() { return max_size_in_words() * BitsPerWord; } + constexpr static idx_t max_size_in_words() { return raw_to_words_align_down(~idx_t(0)); } + constexpr static idx_t max_size_in_bits() { return max_size_in_words() * BitsPerWord; } // Assumes relevant validity checking for bit has already been done. - static idx_t raw_to_words_align_up(idx_t bit) { + constexpr static idx_t raw_to_words_align_up(idx_t bit) { return raw_to_words_align_down(bit + (BitsPerWord - 1)); } // Assumes relevant validity checking for bit has already been done. - static idx_t raw_to_words_align_down(idx_t bit) { + constexpr static idx_t raw_to_words_align_down(idx_t bit) { return bit >> LogBitsPerWord; } @@ -195,7 +195,7 @@ class BitMap { void pretouch(); // Accessing - static idx_t calc_size_in_words(size_t size_in_bits) { + constexpr static idx_t calc_size_in_words(size_t size_in_bits) { verify_size(size_in_bits); return raw_to_words_align_up(size_in_bits); } @@ -257,7 +257,13 @@ class BitMap { // Verification. // Verify size_in_bits does not exceed max_size_in_bits(). - static void verify_size(idx_t size_in_bits) NOT_DEBUG_RETURN; + constexpr static void verify_size(idx_t size_in_bits) { +#ifdef ASSERT + assert(size_in_bits <= max_size_in_bits(), + "out of bounds: " SIZE_FORMAT, size_in_bits); +#endif + } + // Verify bit is less than size(). void verify_index(idx_t bit) const NOT_DEBUG_RETURN; // Verify bit is not greater than size(). diff --git a/src/hotspot/share/utilities/globalDefinitions.hpp b/src/hotspot/share/utilities/globalDefinitions.hpp index 74817a35e77..b7be6dc04bf 100644 --- a/src/hotspot/share/utilities/globalDefinitions.hpp +++ b/src/hotspot/share/utilities/globalDefinitions.hpp @@ -222,9 +222,9 @@ FORBID_C_FUNCTION(void* reallocf(void *ptr, size_t size), "don't use"); const int LogBytesPerShort = 1; const int LogBytesPerInt = 2; #ifdef _LP64 -const int LogBytesPerWord = 3; +constexpr int LogBytesPerWord = 3; #else -const int LogBytesPerWord = 2; +constexpr int LogBytesPerWord = 2; #endif const int LogBytesPerLong = 3; @@ -233,16 +233,16 @@ const int BytesPerInt = 1 << LogBytesPerInt; const int BytesPerWord = 1 << LogBytesPerWord; const int BytesPerLong = 1 << LogBytesPerLong; -const int LogBitsPerByte = 3; +constexpr int LogBitsPerByte = 3; const int LogBitsPerShort = LogBitsPerByte + LogBytesPerShort; const int LogBitsPerInt = LogBitsPerByte + LogBytesPerInt; -const int LogBitsPerWord = LogBitsPerByte + LogBytesPerWord; +constexpr int LogBitsPerWord = LogBitsPerByte + LogBytesPerWord; const int LogBitsPerLong = LogBitsPerByte + LogBytesPerLong; const int BitsPerByte = 1 << LogBitsPerByte; const int BitsPerShort = 1 << LogBitsPerShort; const int BitsPerInt = 1 << LogBitsPerInt; -const int BitsPerWord = 1 << LogBitsPerWord; +constexpr int BitsPerWord = 1 << LogBitsPerWord; const int BitsPerLong = 1 << LogBitsPerLong; const int WordAlignmentMask = (1 << LogBytesPerWord) - 1;