1 /* 2 * Copyright (c) 1997, 2024, 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_MEMORY_ITERATOR_HPP 26 #define SHARE_MEMORY_ITERATOR_HPP 27 28 #include "memory/allocation.hpp" 29 #include "memory/memRegion.hpp" 30 #include "oops/oopsHierarchy.hpp" 31 32 class CodeBlob; 33 class nmethod; 34 class ReferenceDiscoverer; 35 class DataLayout; 36 class KlassClosure; 37 class ClassLoaderData; 38 class Symbol; 39 class Metadata; 40 class Thread; 41 42 // The following classes are C++ `closures` for iterating over objects, roots and spaces 43 44 class Closure : public StackObj { }; 45 46 // Thread iterator 47 class ThreadClosure { 48 public: 49 virtual void do_thread(Thread* thread) = 0; 50 }; 51 52 // OopClosure is used for iterating through references to Java objects. 53 class OopClosure : public Closure { 54 public: 55 virtual void do_oop(oop* o) = 0; 56 virtual void do_oop(narrowOop* o) = 0; 57 virtual void do_oop_no_buffering(oop* o) { do_oop(o); } 58 virtual void do_oop_no_buffering(narrowOop* o) { do_oop(o); } 59 }; 60 61 class DoNothingClosure : public OopClosure { 62 public: 63 virtual void do_oop(oop* p) {} 64 virtual void do_oop(narrowOop* p) {} 65 }; 66 extern DoNothingClosure do_nothing_cl; 67 68 // OopIterateClosure adds extra code to be run during oop iterations. 69 // This is needed by the GC and is extracted to a separate type to not 70 // pollute the OopClosure interface. 71 class OopIterateClosure : public OopClosure { 72 private: 73 ReferenceDiscoverer* _ref_discoverer; 74 75 protected: 76 OopIterateClosure(ReferenceDiscoverer* rd) : _ref_discoverer(rd) { } 77 OopIterateClosure() : _ref_discoverer(nullptr) { } 78 ~OopIterateClosure() { } 79 80 void set_ref_discoverer_internal(ReferenceDiscoverer* rd) { _ref_discoverer = rd; } 81 82 public: 83 ReferenceDiscoverer* ref_discoverer() const { return _ref_discoverer; } 84 85 // Iteration of InstanceRefKlasses differ depending on the closure, 86 // the below enum describes the different alternatives. 87 enum ReferenceIterationMode { 88 DO_DISCOVERY, // Apply closure and discover references 89 DO_FIELDS, // Apply closure to all fields 90 DO_FIELDS_EXCEPT_REFERENT // Apply closure to all fields except the referent field 91 }; 92 93 // The default iteration mode is to do discovery. 94 virtual ReferenceIterationMode reference_iteration_mode() { return DO_DISCOVERY; } 95 96 // If the do_metadata functions return "true", 97 // we invoke the following when running oop_iterate(): 98 // 99 // 1) do_klass on the header klass pointer. 100 // 2) do_klass on the klass pointer in the mirrors. 101 // 3) do_cld on the class loader data in class loaders. 102 // 103 // Used to determine metadata liveness for class unloading GCs. 104 105 virtual bool do_metadata() = 0; 106 virtual void do_klass(Klass* k) = 0; 107 virtual void do_cld(ClassLoaderData* cld) = 0; 108 109 // Class redefinition needs to get notified about methods from stackChunkOops 110 virtual void do_method(Method* m) = 0; 111 // The code cache unloading needs to get notified about methods from stackChunkOops 112 virtual void do_nmethod(nmethod* nm) = 0; 113 }; 114 115 // An OopIterateClosure that can be used when there's no need to visit the Metadata. 116 class BasicOopIterateClosure : public OopIterateClosure { 117 public: 118 BasicOopIterateClosure(ReferenceDiscoverer* rd = nullptr) : OopIterateClosure(rd) {} 119 120 virtual bool do_metadata() { return false; } 121 virtual void do_klass(Klass* k) { ShouldNotReachHere(); } 122 virtual void do_cld(ClassLoaderData* cld) { ShouldNotReachHere(); } 123 virtual void do_method(Method* m) { ShouldNotReachHere(); } 124 virtual void do_nmethod(nmethod* nm) { ShouldNotReachHere(); } 125 }; 126 127 // Interface for applying an OopClosure to a set of oops. 128 class OopIterator { 129 public: 130 virtual void oops_do(OopClosure* cl) = 0; 131 }; 132 133 enum class derived_base : intptr_t; 134 enum class derived_pointer : intptr_t; 135 class DerivedOopClosure : public Closure { 136 public: 137 enum { SkipNull = true }; 138 virtual void do_derived_oop(derived_base* base, derived_pointer* derived) = 0; 139 }; 140 141 class BufferedValueClosure : public Closure { 142 public: 143 virtual void do_buffered_value(oop* p) = 0; 144 }; 145 146 class KlassClosure : public Closure { 147 public: 148 virtual void do_klass(Klass* k) = 0; 149 }; 150 151 class CLDClosure : public Closure { 152 public: 153 virtual void do_cld(ClassLoaderData* cld) = 0; 154 }; 155 156 class MetadataClosure : public Closure { 157 public: 158 virtual void do_metadata(Metadata* md) = 0; 159 }; 160 161 162 class CLDToOopClosure : public CLDClosure { 163 OopClosure* _oop_closure; 164 int _cld_claim; 165 166 public: 167 CLDToOopClosure(OopClosure* oop_closure, 168 int cld_claim) : 169 _oop_closure(oop_closure), 170 _cld_claim(cld_claim) {} 171 172 void do_cld(ClassLoaderData* cld); 173 }; 174 175 template <int claim> 176 class ClaimingCLDToOopClosure : public CLDToOopClosure { 177 public: 178 ClaimingCLDToOopClosure(OopClosure* cl) : CLDToOopClosure(cl, claim) {} 179 }; 180 181 class ClaimMetadataVisitingOopIterateClosure : public OopIterateClosure { 182 protected: 183 const int _claim; 184 185 public: 186 ClaimMetadataVisitingOopIterateClosure(int claim, ReferenceDiscoverer* rd = nullptr) : 187 OopIterateClosure(rd), 188 _claim(claim) { } 189 190 virtual bool do_metadata() { return true; } 191 virtual void do_klass(Klass* k); 192 virtual void do_cld(ClassLoaderData* cld); 193 virtual void do_method(Method* m); 194 virtual void do_nmethod(nmethod* nm); 195 }; 196 197 // The base class for all concurrent marking closures, 198 // that participates in class unloading. 199 // It's used to proxy through the metadata to the oops defined in them. 200 class MetadataVisitingOopIterateClosure: public ClaimMetadataVisitingOopIterateClosure { 201 public: 202 MetadataVisitingOopIterateClosure(ReferenceDiscoverer* rd = nullptr); 203 }; 204 205 // ObjectClosure is used for iterating through an object space 206 207 class ObjectClosure : public Closure { 208 public: 209 // Called for each object. 210 virtual void do_object(oop obj) = 0; 211 }; 212 213 class BoolObjectClosure : public Closure { 214 public: 215 virtual bool do_object_b(oop obj) = 0; 216 }; 217 218 class OopFieldClosure { 219 public: 220 virtual void do_field(oop base, oop* p) = 0; 221 }; 222 223 class AlwaysTrueClosure: public BoolObjectClosure { 224 public: 225 bool do_object_b(oop p) { return true; } 226 }; 227 228 class AlwaysFalseClosure : public BoolObjectClosure { 229 public: 230 bool do_object_b(oop p) { return false; } 231 }; 232 233 // Applies an oop closure to all ref fields in objects iterated over in an 234 // object iteration. 235 class ObjectToOopClosure: public ObjectClosure { 236 OopIterateClosure* _cl; 237 public: 238 void do_object(oop obj); 239 ObjectToOopClosure(OopIterateClosure* cl) : _cl(cl) {} 240 }; 241 242 // NMethodClosure is used for iterating through nmethods 243 // in the code cache or on thread stacks 244 245 class NMethodClosure : public Closure { 246 public: 247 virtual void do_nmethod(nmethod* n) = 0; 248 }; 249 250 // Applies an oop closure to all ref fields in nmethods 251 // iterated over in an object iteration. 252 class NMethodToOopClosure : public NMethodClosure { 253 protected: 254 OopClosure* _cl; 255 bool _fix_relocations; 256 public: 257 // If fix_relocations(), then cl must copy objects to their new location immediately to avoid 258 // patching nmethods with the old locations. 259 NMethodToOopClosure(OopClosure* cl, bool fix_relocations) : _cl(cl), _fix_relocations(fix_relocations) {} 260 void do_nmethod(nmethod* nm) override; 261 262 bool fix_relocations() const { return _fix_relocations; } 263 const static bool FixRelocations = true; 264 }; 265 266 class MarkingNMethodClosure : public NMethodToOopClosure { 267 bool _keepalive_nmethods; 268 269 public: 270 MarkingNMethodClosure(OopClosure* cl, bool fix_relocations, bool keepalive_nmethods) : 271 NMethodToOopClosure(cl, fix_relocations), 272 _keepalive_nmethods(keepalive_nmethods) {} 273 274 // Called for each nmethod. 275 virtual void do_nmethod(nmethod* nm); 276 }; 277 278 // MonitorClosure is used for iterating over monitors in the monitors cache 279 280 class ObjectMonitor; 281 282 class MonitorClosure : public StackObj { 283 public: 284 // called for each monitor in cache 285 virtual void do_monitor(ObjectMonitor* m) = 0; 286 }; 287 288 // A closure that is applied without any arguments. 289 class VoidClosure : public StackObj { 290 public: 291 virtual void do_void() = 0; 292 }; 293 294 295 // YieldClosure is intended for use by iteration loops 296 // to incrementalize their work, allowing interleaving 297 // of an interruptible task so as to allow other 298 // threads to run (which may not otherwise be able to access 299 // exclusive resources, for instance). Additionally, the 300 // closure also allows for aborting an ongoing iteration 301 // by means of checking the return value from the polling 302 // call. 303 class YieldClosure : public StackObj { 304 public: 305 virtual bool should_return() = 0; 306 307 // Yield on a fine-grain level. The check in case of not yielding should be very fast. 308 virtual bool should_return_fine_grain() { return false; } 309 }; 310 311 class SymbolClosure : public StackObj { 312 public: 313 virtual void do_symbol(Symbol**) = 0; 314 }; 315 316 template <typename E> 317 class CompareClosure : public Closure { 318 public: 319 virtual int do_compare(const E&, const E&) = 0; 320 }; 321 322 class OopIteratorClosureDispatch { 323 public: 324 template <typename OopClosureType> static void oop_oop_iterate(OopClosureType* cl, oop obj, Klass* klass); 325 template <typename OopClosureType> static void oop_oop_iterate(OopClosureType* cl, oop obj, Klass* klass, MemRegion mr); 326 template <typename OopClosureType> static void oop_oop_iterate_backwards(OopClosureType* cl, oop obj, Klass* klass); 327 }; 328 329 #endif // SHARE_MEMORY_ITERATOR_HPP