From 03abc5fe6f06c0da8c1bb64af3fc3393b47c6826 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johan=20Sj=C3=B6len?= Date: Mon, 24 Apr 2023 15:13:24 +0000 Subject: [PATCH 1/2] Backport --- src/hotspot/share/opto/chaitin.cpp | 47 +++++++++++++++++++++--------- 1 file changed, 33 insertions(+), 14 deletions(-) diff --git a/src/hotspot/share/opto/chaitin.cpp b/src/hotspot/share/opto/chaitin.cpp index 4a61e953d5c..69ce7c61b86 100644 --- a/src/hotspot/share/opto/chaitin.cpp +++ b/src/hotspot/share/opto/chaitin.cpp @@ -220,41 +220,60 @@ PhaseChaitin::PhaseChaitin(uint unique, PhaseCFG &cfg, Matcher &matcher, bool sc _high_frequency_lrg = MIN2(double(OPTO_LRG_HIGH_FREQ), _cfg.get_outer_loop_frequency()); // Build a list of basic blocks, sorted by frequency - _blks = NEW_RESOURCE_ARRAY(Block *, _cfg.number_of_blocks()); // Experiment with sorting strategies to speed compilation + uint nr_blocks = _cfg.number_of_blocks(); double cutoff = BLOCK_FREQUENCY(1.0); // Cutoff for high frequency bucket Block **buckets[NUMBUCKS]; // Array of buckets uint buckcnt[NUMBUCKS]; // Array of bucket counters double buckval[NUMBUCKS]; // Array of bucket value cutoffs + + // The space which our buckets point into. + Block** start = NEW_RESOURCE_ARRAY(Block *, nr_blocks*NUMBUCKS); + for (uint i = 0; i < NUMBUCKS; i++) { - buckets[i] = NEW_RESOURCE_ARRAY(Block *, _cfg.number_of_blocks()); + buckets[i] = &start[i*nr_blocks]; buckcnt[i] = 0; // Bump by three orders of magnitude each time cutoff *= 0.001; buckval[i] = cutoff; - for (uint j = 0; j < _cfg.number_of_blocks(); j++) { - buckets[i][j] = nullptr; - } } + // Sort blocks into buckets - for (uint i = 0; i < _cfg.number_of_blocks(); i++) { + for (uint i = 0; i < nr_blocks; i++) { for (uint j = 0; j < NUMBUCKS; j++) { - if ((j == NUMBUCKS - 1) || (_cfg.get_block(i)->_freq > buckval[j])) { + double bval = buckval[j]; + Block* blk = _cfg.get_block(i); + if (j == NUMBUCKS - 1 || blk->_freq > bval) { + uint cnt = buckcnt[j]; // Assign block to end of list for appropriate bucket - buckets[j][buckcnt[j]++] = _cfg.get_block(i); + buckets[j][cnt] = blk; + buckcnt[j] = cnt+1; break; // kick out of inner loop } } } - // Dump buckets into final block array + + // Squash the partially filled buckets together into the first one. + static_assert(NUMBUCKS >= 2, "must"); // If this isn't true then it'll mess up the squashing. + Block** offset = &buckets[0][buckcnt[0]]; + for (int i = 1; i < NUMBUCKS; i++) { + ::memmove(offset, buckets[i], buckcnt[i]*sizeof(Block*)); + offset += buckcnt[i]; + } + assert((&buckets[0][0] + nr_blocks) == offset, "should be"); + + // Free the now unused memory + FREE_RESOURCE_ARRAY(Block*, buckets[1], (NUMBUCKS-1)*nr_blocks); + // Finally, point the _blks to our memory + _blks = buckets[0]; + +#ifdef ASSERT uint blkcnt = 0; for (uint i = 0; i < NUMBUCKS; i++) { - for (uint j = 0; j < buckcnt[i]; j++) { - _blks[blkcnt++] = buckets[i][j]; - } + blkcnt += buckcnt[i]; } - - assert(blkcnt == _cfg.number_of_blocks(), "Block array not totally filled"); + assert(blkcnt == nr_blocks, "Block array not totally filled"); +#endif } // union 2 sets together. From ccb7e453842947130e9ae7e0d71b9285890a0ed1 Mon Sep 17 00:00:00 2001 From: Thomas Schatzl Date: Thu, 3 Mar 2022 09:26:41 +0000 Subject: [PATCH 2/2] Backport --- src/hotspot/share/gc/g1/g1Policy.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/hotspot/share/gc/g1/g1Policy.cpp b/src/hotspot/share/gc/g1/g1Policy.cpp index f41181060c5..48e842b3ac2 100644 --- a/src/hotspot/share/gc/g1/g1Policy.cpp +++ b/src/hotspot/share/gc/g1/g1Policy.cpp @@ -1299,7 +1299,6 @@ void G1Policy::calculate_old_collection_set_regions(G1CollectionSetCandidates* c num_optional_regions = 0; uint num_expensive_regions = 0; - double predicted_old_time_ms = 0.0; double predicted_initial_time_ms = 0.0; double predicted_optional_time_ms = 0.0; @@ -1330,7 +1329,7 @@ void G1Policy::calculate_old_collection_set_regions(G1CollectionSetCandidates* c time_remaining_ms = MAX2(time_remaining_ms - predicted_time_ms, 0.0); // Add regions to old set until we reach the minimum amount if (num_initial_regions < min_old_cset_length) { - predicted_old_time_ms += predicted_time_ms; + predicted_initial_time_ms += predicted_time_ms; num_initial_regions++; // Record the number of regions added with no time remaining if (time_remaining_ms == 0.0) { @@ -1344,7 +1343,7 @@ void G1Policy::calculate_old_collection_set_regions(G1CollectionSetCandidates* c } else { // Keep adding regions to old set until we reach the optional threshold if (time_remaining_ms > optional_threshold_ms) { - predicted_old_time_ms += predicted_time_ms; + predicted_initial_time_ms += predicted_time_ms; num_initial_regions++; } else if (time_remaining_ms > 0) { // Keep adding optional regions until time is up. @@ -1368,7 +1367,7 @@ void G1Policy::calculate_old_collection_set_regions(G1CollectionSetCandidates* c } log_debug(gc, ergo, cset)("Finish choosing collection set old regions. Initial: %u, optional: %u, " - "predicted old time: %1.2fms, predicted optional time: %1.2fms, time remaining: %1.2f", + "predicted initial time: %1.2fms, predicted optional time: %1.2fms, time remaining: %1.2f", num_initial_regions, num_optional_regions, predicted_initial_time_ms, predicted_optional_time_ms, time_remaining_ms); }