1 /*
  2  * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved.
  3  * Copyright Amazon.com Inc. or its affiliates. All Rights Reserved.
  4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  5  *
  6  * This code is free software; you can redistribute it and/or modify it
  7  * under the terms of the GNU General Public License version 2 only, as
  8  * published by the Free Software Foundation.
  9  *
 10  * This code is distributed in the hope that it will be useful, but WITHOUT
 11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 12  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 13  * version 2 for more details (a copy is included in the LICENSE file that
 14  * accompanied this code).
 15  *
 16  * You should have received a copy of the GNU General Public License version
 17  * 2 along with this work; if not, write to the Free Software Foundation,
 18  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 19  *
 20  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 21  * or visit www.oracle.com if you need additional information or have any
 22  * questions.
 23  *
 24  */
 25 
 26 #ifndef SHARE_GC_PARALLEL_PSCOMPACTIONMANAGERNEW_HPP
 27 #define SHARE_GC_PARALLEL_PSCOMPACTIONMANAGERNEW_HPP
 28 
 29 #include "classfile/classLoaderData.hpp"
 30 #include "gc/parallel/psParallelCompactNew.hpp"
 31 #include "gc/shared/partialArraySplitter.hpp"
 32 #include "gc/shared/partialArrayTaskStats.hpp"
 33 #include "gc/shared/partialArrayState.hpp"
 34 #include "gc/shared/preservedMarks.hpp"
 35 #include "gc/shared/stringdedup/stringDedup.hpp"
 36 #include "gc/shared/taskqueue.hpp"
 37 #include "gc/shared/taskTerminator.hpp"
 38 #include "memory/allocation.hpp"
 39 #include "utilities/stack.hpp"
 40 
 41 class MutableSpace;
 42 class PSOldGen;
 43 class ParCompactionManagerNew;
 44 class ObjectStartArray;
 45 class ParMarkBitMap;
 46 
 47 class PCMarkAndPushClosureNew: public ClaimMetadataVisitingOopIterateClosure {
 48   ParCompactionManagerNew* _compaction_manager;
 49 
 50   template <typename T> void do_oop_work(T* p);
 51 public:
 52   PCMarkAndPushClosureNew(ParCompactionManagerNew* cm, ReferenceProcessor* rp) :
 53     ClaimMetadataVisitingOopIterateClosure(ClassLoaderData::_claim_stw_fullgc_mark, rp),
 54     _compaction_manager(cm) { }
 55 
 56   void do_oop(oop* p) final               { do_oop_work(p); }
 57   void do_oop(narrowOop* p) final         { do_oop_work(p); }
 58 };
 59 
 60 class ParCompactionManagerNew : public CHeapObj<mtGC> {
 61   friend class MarkFromRootsTaskNew;
 62   friend class ParallelCompactRefProcProxyTaskNew;
 63   friend class ParallelScavengeRefProcProxyTask;
 64   friend class ParMarkBitMap;
 65   friend class PSParallelCompactNew;
 66   friend class PCAddThreadRootsMarkingTaskClosureNew;
 67 
 68  private:
 69   typedef OverflowTaskQueue<ScannerTask, mtGC>           PSMarkTaskQueue;
 70   typedef GenericTaskQueueSet<PSMarkTaskQueue, mtGC>     PSMarkTasksQueueSet;
 71 
 72   static ParCompactionManagerNew** _manager_array;
 73   static PSMarkTasksQueueSet*   _marking_stacks;
 74   static ObjectStartArray*      _start_array;
 75   static PSOldGen*              _old_gen;
 76 
 77   static PartialArrayStateManager*  _partial_array_state_manager;
 78   PartialArraySplitter              _partial_array_splitter;
 79 
 80   PSMarkTaskQueue               _marking_stack;
 81 
 82   PCMarkAndPushClosureNew _mark_and_push_closure;
 83 
 84   static PreservedMarksSet* _preserved_marks_set;
 85   PreservedMarks* _preserved_marks;
 86 
 87   static ParMarkBitMap* _mark_bitmap;
 88 
 89   StringDedup::Requests _string_dedup_requests;
 90 
 91   static PSOldGen* old_gen()             { return _old_gen; }
 92   static ObjectStartArray* start_array() { return _start_array; }
 93   static PSMarkTasksQueueSet* marking_stacks()  { return _marking_stacks; }
 94 
 95   static void initialize(ParMarkBitMap* mbm);
 96 
 97   ParCompactionManagerNew(PreservedMarks* preserved_marks,
 98                        ReferenceProcessor* ref_processor,
 99                        uint parallel_gc_threads);
100 
101   inline PSMarkTaskQueue*  marking_stack() { return &_marking_stack; }
102   inline void push(PartialArrayState* stat);
103   void push_objArray(oop obj);
104 
105 #if TASKQUEUE_STATS
106   static void print_and_reset_taskqueue_stats();
107   PartialArrayTaskStats* partial_array_task_stats();
108 #endif // TASKQUEUE_STATS
109 
110 public:
111   void flush_string_dedup_requests() {
112     _string_dedup_requests.flush();
113   }
114 
115   static void flush_all_string_dedup_requests();
116 
117   // Get the compaction manager when doing evacuation work from the VM thread.
118   // Simply use the first compaction manager here.
119   static ParCompactionManagerNew* get_vmthread_cm() { return _manager_array[0]; }
120 
121   PreservedMarks* preserved_marks() const {
122     return _preserved_marks;
123   }
124 
125   static ParMarkBitMap* mark_bitmap() { return _mark_bitmap; }
126 
127   // Save for later processing.  Must not fail.
128   inline void push(oop obj);
129 
130   // Check mark and maybe push on marking stack.
131   template <typename T> inline void mark_and_push(T* p);
132 
133   // Access function for compaction managers
134   static ParCompactionManagerNew* gc_thread_compaction_manager(uint index);
135 
136   static bool steal(uint queue_num, ScannerTask& t);
137 
138   // Process tasks remaining on marking stack
139   void follow_marking_stacks();
140   inline bool marking_stack_empty() const;
141 
142   inline void follow_contents(const ScannerTask& task, bool stolen);
143   inline void follow_array(objArrayOop array, size_t start, size_t end);
144   void process_array_chunk(PartialArrayState* state, bool stolen);
145 
146   class FollowStackClosure: public VoidClosure {
147    private:
148     ParCompactionManagerNew* _compaction_manager;
149     TaskTerminator* _terminator;
150     uint _worker_id;
151    public:
152     FollowStackClosure(ParCompactionManagerNew* cm, TaskTerminator* terminator, uint worker_id)
153       : _compaction_manager(cm), _terminator(terminator), _worker_id(worker_id) { }
154     void do_void() final;
155   };
156 
157   // Called after marking.
158   static void verify_all_marking_stack_empty() NOT_DEBUG_RETURN;
159 };
160 
161 bool ParCompactionManagerNew::marking_stack_empty() const {
162   return _marking_stack.is_empty();
163 }
164 
165 #endif // SHARE_GC_PARALLEL_PSCOMPACTIONMANAGERNEW_HPP