1 /* 2 * Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 * 23 */ 24 25 #ifndef SHARE_GC_SHENANDOAH_HEURISTICS_SHENANDOAHOLDHEURISTICS_HPP 26 #define SHARE_GC_SHENANDOAH_HEURISTICS_SHENANDOAHOLDHEURISTICS_HPP 27 28 29 #include "gc/shenandoah/heuristics/shenandoahHeuristics.hpp" 30 31 class ShenandoahCollectionSet; 32 class ShenandoahHeapRegion; 33 class ShenandoahOldGeneration; 34 35 /* 36 * This heuristic is responsible for choosing a set of candidates for inclusion 37 * in mixed collections. These candidates are chosen when marking of the old 38 * generation is complete. Note that this list of candidates may live through 39 * several mixed collections. 40 * 41 * This heuristic is also responsible for triggering old collections. It has its 42 * own collection of triggers to decide whether to start an old collection. It does 43 * _not_ use any of the functionality from the adaptive heuristics for triggers. 44 * It also does not use any of the functionality from the heuristics base classes 45 * to choose the collection set. For these reasons, it does not extend from 46 * ShenandoahGenerationalHeuristics. 47 */ 48 class ShenandoahOldHeuristics : public ShenandoahHeuristics { 49 50 private: 51 52 static uint NOT_FOUND; 53 54 // After final marking of the old generation, this heuristic will select 55 // a set of candidate regions to be included in subsequent mixed collections. 56 // The regions are sorted into a `_region_data` array (declared in base 57 // class) in decreasing order of garbage. The heuristic will give priority 58 // to regions containing more garbage. 59 60 // The following members are used to keep track of which candidate regions 61 // have yet to be added to a mixed collection. There is also some special 62 // handling for pinned regions, described further below. 63 64 // Pinned regions may not be included in the collection set. Any old regions 65 // which were pinned at the time when old regions were added to the mixed 66 // collection will have been skipped. These regions are still contain garbage, 67 // so we want to include them at the start of the list of candidates for the 68 // _next_ mixed collection cycle. This variable is the index of the _first_ 69 // old region which is pinned when the mixed collection set is formed. 70 uint _first_pinned_candidate; 71 72 // This is the index of the last region which is above the garbage threshold. 73 // No regions after this will be considered for inclusion in a mixed collection 74 // set. 75 uint _last_old_collection_candidate; 76 77 // This index points to the first candidate in line to be added to the mixed 78 // collection set. It is updated as regions are added to the collection set. 79 uint _next_old_collection_candidate; 80 81 // This is the last index in the array of old regions which were active at 82 // the end of old final mark. 83 uint _last_old_region; 84 85 // How much live data must be evacuated from within the unprocessed mixed evacuation candidates? 86 size_t _live_bytes_in_unprocessed_candidates; 87 88 // Keep a pointer to our generation that we can use without down casting a protected member from the base class. 89 ShenandoahOldGeneration* _old_generation; 90 91 // Flags are set when promotion failure is detected (by gc thread), and cleared when 92 // old generation collection begins (by control thread). Flags are set and cleared at safepoints. 93 bool _cannot_expand_trigger; 94 bool _fragmentation_trigger; 95 bool _growth_trigger; 96 97 // Compare by live is used to prioritize compaction of old-gen regions. With old-gen compaction, the goal is 98 // to tightly pack long-lived objects into available regions. In most cases, there has not been an accumulation 99 // of garbage within old-gen regions. The more likely opportunity will be to combine multiple sparsely populated 100 // old-gen regions which may have been promoted in place into a smaller number of densely packed old-gen regions. 101 // This improves subsequent allocation efficiency and reduces the likelihood of allocation failure (including 102 // humongous allocation failure) due to fragmentation of the available old-gen allocation pool 103 static int compare_by_live(RegionData a, RegionData b); 104 105 protected: 106 virtual void choose_collection_set_from_regiondata(ShenandoahCollectionSet* set, RegionData* data, size_t data_size, 107 size_t free) override; 108 109 public: 110 ShenandoahOldHeuristics(ShenandoahOldGeneration* generation); 111 112 // Prepare for evacuation of old-gen regions by capturing the mark results of a recently completed concurrent mark pass. 113 void prepare_for_old_collections(); 114 115 // Return true iff the collection set is primed with at least one old-gen region. 116 bool prime_collection_set(ShenandoahCollectionSet* set); 117 118 // How many old-collection candidates have not yet been processed? 119 uint unprocessed_old_collection_candidates() const; 120 121 // How much live memory must be evacuated from within old-collection candidates that have not yet been processed? 122 size_t unprocessed_old_collection_candidates_live_memory() const; 123 124 void set_unprocessed_old_collection_candidates_live_memory(size_t initial_live); 125 126 void decrease_unprocessed_old_collection_candidates_live_memory(size_t evacuated_live); 127 128 // How many old or hidden collection candidates have not yet been processed? 129 uint last_old_collection_candidate_index() const; 130 131 // Return the next old-collection candidate in order of decreasing amounts of garbage. (We process most-garbage regions 132 // first.) This does not consume the candidate. If the candidate is selected for inclusion in a collection set, then 133 // the candidate is consumed by invoking consume_old_collection_candidate(). 134 ShenandoahHeapRegion* next_old_collection_candidate(); 135 136 // Adjust internal state to reflect that one fewer old-collection candidate remains to be processed. 137 void consume_old_collection_candidate(); 138 139 // Fill in buffer with all the old-collection regions that were identified at the end of the most recent old-gen 140 // mark to require their unmarked objects to be coalesced and filled. The buffer array must have at least 141 // last_old_region_index() entries, or memory may be corrupted when this function overwrites the 142 // end of the array. 143 unsigned int get_coalesce_and_fill_candidates(ShenandoahHeapRegion** buffer); 144 145 // True if there are old regions that need to be filled. 146 bool has_coalesce_and_fill_candidates() const { return coalesce_and_fill_candidates_count() > 0; } 147 148 // Return the number of old regions that need to be filled. 149 size_t coalesce_and_fill_candidates_count() const { return _last_old_region - _next_old_collection_candidate; } 150 151 // If a GLOBAL gc occurs, it will collect the entire heap which invalidates any collection candidates being 152 // held by this heuristic for supplying mixed collections. 153 void abandon_collection_candidates(); 154 155 void trigger_cannot_expand() { _cannot_expand_trigger = true; }; 156 void trigger_old_is_fragmented() { _fragmentation_trigger = true; } 157 void trigger_old_has_grown(); 158 159 void clear_triggers(); 160 161 void record_cycle_end() override; 162 163 bool should_start_gc() override; 164 165 void record_success_concurrent(bool abbreviated) override; 166 167 void record_success_degenerated() override; 168 169 void record_success_full() override; 170 171 const char* name() override; 172 173 bool is_diagnostic() override; 174 175 bool is_experimental() override; 176 177 private: 178 void slide_pinned_regions_to_front(); 179 bool all_candidates_are_pinned(); 180 }; 181 182 #endif // SHARE_GC_SHENANDOAH_HEURISTICS_SHENANDOAHOLDHEURISTICS_HPP