1 /*
  2  * Copyright (c) 2017, 2023, Oracle and/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_G1_G1FULLCOLLECTOR_HPP
 26 #define SHARE_GC_G1_G1FULLCOLLECTOR_HPP
 27 
 28 #include "gc/g1/g1FullGCCompactionPoint.hpp"
 29 #include "gc/g1/g1FullGCHeapRegionAttr.hpp"
 30 #include "gc/g1/g1FullGCMarker.hpp"
 31 #include "gc/g1/g1FullGCOopClosures.hpp"
 32 #include "gc/g1/g1FullGCScope.hpp"
 33 #include "gc/g1/g1RegionMarkStatsCache.hpp"
 34 #include "gc/shared/gcId.hpp"
 35 #include "gc/shared/gcTraceTime.hpp"
 36 #include "gc/shared/preservedMarks.hpp"
 37 #include "gc/shared/referenceProcessor.hpp"
 38 #include "gc/shared/taskqueue.hpp"
 39 #include "memory/allocation.hpp"
 40 #include "oops/oopsHierarchy.hpp"
 41 
 42 class WorkerTask;
 43 class G1CMBitMap;
 44 class G1FullGCMarker;
 45 class G1FullGCScope;
 46 class G1FullGCCompactionPoint;
 47 class GCMemoryManager;
 48 class HeapRegion;
 49 class ReferenceProcessor;
 50 
 51 // Subject-to-discovery closure for reference processing during Full GC. During
 52 // Full GC the whole heap is subject to discovery.
 53 class G1FullGCSubjectToDiscoveryClosure: public BoolObjectClosure {
 54 public:
 55   bool do_object_b(oop p) {
 56     assert(p != nullptr, "must be");
 57     return true;
 58   }
 59 };
 60 
 61 // Full GC Mark that holds GC id and CPU time trace. Needs to be separate
 62 // from the G1FullCollector and G1FullGCScope to allow the Full GC logging
 63 // to have the same structure as the Young GC logging.
 64 class G1FullGCMark : StackObj {
 65   GCIdMark       _gc_id;
 66   G1FullGCTracer _tracer;
 67   GCTraceCPUTime _cpu_time;
 68 public:
 69   G1FullGCMark() : _gc_id(), _tracer(), _cpu_time(&_tracer) { }
 70   G1FullGCTracer* tracer() { return &_tracer; }
 71 };
 72 
 73 // The G1FullCollector holds data associated with the current Full GC.
 74 class G1FullCollector : StackObj {
 75   G1CollectedHeap*          _heap;
 76   G1FullGCScope             _scope;
 77   uint                      _num_workers;
 78   bool                      _has_compaction_targets;
 79   bool                      _has_humongous;
 80   G1FullGCMarker**          _markers;
 81   G1FullGCCompactionPoint** _compaction_points;
 82   OopQueueSet               _oop_queue_set;
 83   ObjArrayTaskQueueSet      _array_queue_set;
 84   PreservedMarksSet         _preserved_marks_set;
 85   G1FullGCCompactionPoint   _serial_compaction_point;
 86   G1FullGCCompactionPoint   _humongous_compaction_point;
 87   G1IsAliveClosure          _is_alive;
 88   ReferenceProcessorIsAliveMutator _is_alive_mutator;
 89   G1RegionMarkStats*        _live_stats;
 90   GrowableArrayCHeap<HeapRegion*, mtGC> _humongous_compaction_regions;
 91 
 92   static uint calc_active_workers();
 93 
 94   G1FullGCSubjectToDiscoveryClosure _always_subject_to_discovery;
 95   ReferenceProcessorSubjectToDiscoveryMutator _is_subject_mutator;
 96 
 97   G1FullGCHeapRegionAttr _region_attr_table;
 98 
 99   HeapWord* volatile* _compaction_tops;
100 
101 public:
102   G1FullCollector(G1CollectedHeap* heap,
103                   bool clear_soft_refs,
104                   bool do_maximal_compaction,
105                   G1FullGCTracer* tracer);
106   ~G1FullCollector();
107 
108   void prepare_collection();
109   void collect();
110   void complete_collection();
111 
112   G1FullGCScope*           scope() { return &_scope; }
113   uint                     workers() { return _num_workers; }
114   G1FullGCMarker*          marker(uint id) { return _markers[id]; }
115   G1FullGCCompactionPoint* compaction_point(uint id) { return _compaction_points[id]; }
116   OopQueueSet*             oop_queue_set() { return &_oop_queue_set; }
117   ObjArrayTaskQueueSet*    array_queue_set() { return &_array_queue_set; }
118   PreservedMarksSet*       preserved_mark_set() { return &_preserved_marks_set; }
119   G1FullGCCompactionPoint* serial_compaction_point() { return &_serial_compaction_point; }
120   G1FullGCCompactionPoint* humongous_compaction_point() { return &_humongous_compaction_point; }
121   G1CMBitMap*              mark_bitmap();
122   ReferenceProcessor*      reference_processor();
123   size_t live_words(uint region_index) const {
124     assert(region_index < _heap->max_regions(), "sanity");
125     return _live_stats[region_index]._live_words;
126   }
127 
128   void before_marking_update_attribute_table(HeapRegion* hr);
129 
130   inline bool is_compacting(oop obj) const;
131   inline bool is_skip_compacting(uint region_index) const;
132 
133   // Are we (potentially) going to compact into this region?
134   inline bool is_compaction_target(uint region_index) const;
135 
136   inline void set_free(uint region_idx);
137   inline bool is_free(uint region_idx) const;
138   inline void update_from_compacting_to_skip_compacting(uint region_idx);
139   inline void update_from_skip_compacting_to_compacting(uint region_idx);
140 
141   inline void set_compaction_top(HeapRegion* r, HeapWord* value);
142   inline HeapWord* compaction_top(HeapRegion* r) const;
143 
144   inline void set_has_compaction_targets();
145   inline bool has_compaction_targets() const;
146 
147   inline void add_humongous_region(HeapRegion* hr);
148   inline GrowableArrayCHeap<HeapRegion*, mtGC>& humongous_compaction_regions();
149 
150   uint truncate_parallel_cps();
151 
152   inline void set_has_humongous();
153   inline bool has_humongous();
154 
155 private:
156   void phase1_mark_live_objects();
157   void phase2_prepare_compaction();
158 
159   void phase2a_determine_worklists();
160   bool phase2b_forward_oops();
161   template <bool ALT_FWD>
162   void phase2c_prepare_serial_compaction_impl();
163   void phase2c_prepare_serial_compaction();
164   template <bool ALT_FWD>
165   void phase2d_prepare_humongous_compaction_impl();
166   void phase2d_prepare_humongous_compaction();
167 
168   void phase3_adjust_pointers();
169   void phase4_do_compaction();
170   void phase5_reset_metadata();
171 
172   void restore_marks();
173   void verify_after_marking();
174 
175   void run_task(WorkerTask* task);
176 };
177 
178 
179 #endif // SHARE_GC_G1_G1FULLCOLLECTOR_HPP