1 /*
  2  * Copyright (c) 2021, 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 #include "gc/shenandoah/shenandoahCollectionSet.inline.hpp"
 29 #include "gc/shenandoah/shenandoahGeneration.hpp"
 30 #include "gc/shenandoah/shenandoahHeap.inline.hpp"
 31 #include "gc/shenandoah/shenandoahHeapRegion.inline.hpp"
 32 #include "gc/shenandoah/heuristics/shenandoahHeuristics.hpp"
 33 
 34 class ShenandoahOldHeuristics : public ShenandoahHeuristics {
 35 
 36 private:
 37 
 38   // if (_generation->generation_mode() == OLD) _old_collection_candidates
 39   //  represent the number of regions selected for collection following the
 40   //  most recently completed old-gen mark that have not yet been selected
 41   //  for evacuation and _next_collection_candidate is the index within
 42   //  _region_data of the next candidate region to be selected for evacuation.
 43   // if (_generation->generation_mode() != OLD) these two variables are
 44   //  not used.
 45   uint _old_collection_candidates;
 46   uint _next_old_collection_candidate;
 47 
 48   // At the time we select the old-gen collection set, _hidden_old_collection_candidates
 49   // and _hidden_next_old_collection_candidates are set to remember the intended old-gen
 50   // collection set.  After all old-gen regions not in the old-gen collection set have been
 51   // coalesced and filled, the content of these variables is copied to _old_collection_candidates
 52   // and _next_old_collection_candidates so that evacuations can begin evacuating these regions.
 53   uint _hidden_old_collection_candidates;
 54   uint _hidden_next_old_collection_candidate;
 55 
 56   // if (_generation->generation_mode() == OLD)
 57   //  _old_coalesce_and_fill_candidates represents the number of regions
 58   //  that were chosen for the garbage contained therein to be coalesced
 59   //  and filled and _first_coalesce_and_fill_candidate represents the
 60   //  the index of the first such region within the _region_data array.
 61   // if (_generation->generation_mode() != OLD) these two variables are
 62   //  not used.
 63   uint _old_coalesce_and_fill_candidates;
 64   uint _first_coalesce_and_fill_candidate;
 65 
 66   // This can be the 'static' or 'adaptive' heuristic.
 67   ShenandoahHeuristics* _trigger_heuristic;
 68 
 69   // Flag is set when promotion failure is detected (by gc thread), cleared when old generation collection begins (by control thread)
 70   volatile bool _promotion_failed;
 71 
 72   // Prepare for evacuation of old-gen regions by capturing the mark results of a recently completed concurrent mark pass.
 73   void prepare_for_old_collections();
 74 
 75  protected:
 76   virtual void choose_collection_set_from_regiondata(ShenandoahCollectionSet* set, RegionData* data, size_t data_size,
 77                                                      size_t free) override;
 78 
 79 public:
 80   ShenandoahOldHeuristics(ShenandoahGeneration* generation, ShenandoahHeuristics* trigger_heuristic);
 81 
 82   // Return true iff chosen collection set includes at least one old-gen HeapRegion.
 83   virtual bool choose_collection_set(ShenandoahCollectionSet* collection_set, ShenandoahOldHeuristics* old_heuristics) override;
 84 
 85   // Return true iff the collection set is primed with at least one old-gen region.
 86   bool prime_collection_set(ShenandoahCollectionSet* set);
 87 
 88   // Having coalesced and filled all old-gen heap regions that are not part of the old-gen collection set, begin
 89   // evacuating the collection set.
 90   void start_old_evacuations();
 91 
 92   // How many old-collection candidates have not yet been processed?
 93   uint unprocessed_old_collection_candidates();
 94 
 95   // How many old or hidden collection candidates have not yet been processed?
 96   uint unprocessed_old_or_hidden_collection_candidates();
 97 
 98   // Return the next old-collection candidate in order of decreasing amounts of garbage.  (We process most-garbage regions
 99   // first.)  This does not consume the candidate.  If the candidate is selected for inclusion in a collection set, then
100   // the candidate is consumed by invoking consume_old_collection_candidate().
101   ShenandoahHeapRegion* next_old_collection_candidate();
102 
103   // Adjust internal state to reflect that one fewer old-collection candidate remains to be processed.
104   void consume_old_collection_candidate();
105 
106   // How many old-collection regions were identified at the end of the most recent old-gen mark to require their
107   // unmarked objects to be coalesced and filled?
108   uint old_coalesce_and_fill_candidates();
109 
110   // Fill in buffer with all of the old-collection regions that were identified at the end of the most recent old-gen
111   // mark to require their unmarked objects to be coalesced and filled.  The buffer array must have at least
112   // old_coalesce_and_fill_candidates() entries, or memory may be corrupted when this function overwrites the
113   // end of the array.
114   void get_coalesce_and_fill_candidates(ShenandoahHeapRegion** buffer);
115 
116   // If a GLOBAL gc occurs, it will collect the entire heap which invalidates any collection candidates being
117   // held by this heuristic for supplying mixed collections.
118   void abandon_collection_candidates();
119 
120   // Notify the heuristic of promotion failures. The promotion attempt will be skipped and the object will
121   // be evacuated into the young generation. The collection should complete normally, but we want to schedule
122   // an old collection as soon as possible.
123   void handle_promotion_failure();
124 
125   virtual void record_cycle_start() override;
126 
127   virtual void record_cycle_end() override;
128 
129   virtual bool should_start_gc() override;
130 
131   virtual bool should_degenerate_cycle() override;
132 
133   virtual void record_success_concurrent() override;
134 
135   virtual void record_success_degenerated() override;
136 
137   virtual void record_success_full() override;
138 
139   virtual void record_allocation_failure_gc() override;
140 
141   virtual void record_requested_gc() override;
142 
143   virtual bool can_unload_classes() override;
144 
145   virtual bool can_unload_classes_normal() override;
146 
147   virtual bool should_unload_classes() override;
148 
149   virtual const char* name() override;
150 
151   virtual bool is_diagnostic() override;
152 
153   virtual bool is_experimental() override;
154 
155 };
156 
157 #endif // SHARE_GC_SHENANDOAH_HEURISTICS_SHENANDOAHOLDHEURISTICS_HPP