1 /* 2 * Copyright (c) 1997, 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_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_DISCOVERED_AND_DISCOVERY, // Apply closure to discovered field and do discovery 90 DO_FIELDS, // Apply closure to all fields 91 DO_FIELDS_EXCEPT_REFERENT // Apply closure to all fields except the referent field 92 }; 93 94 // The default iteration mode is to do discovery. 95 virtual ReferenceIterationMode reference_iteration_mode() { return DO_DISCOVERY; } 96 97 // If the do_metadata functions return "true", 98 // we invoke the following when running oop_iterate(): 99 // 100 // 1) do_klass on the header klass pointer. 101 // 2) do_klass on the klass pointer in the mirrors. 102 // 3) do_cld on the class loader data in class loaders. 103 // 104 // Used to determine metadata liveness for class unloading GCs. 105 106 virtual bool do_metadata() = 0; 107 virtual void do_klass(Klass* k) = 0; 108 virtual void do_cld(ClassLoaderData* cld) = 0; 109 110 // Class redefinition needs to get notified about methods from stackChunkOops 111 virtual void do_method(Method* m) = 0; 112 // The code cache unloading needs to get notified about methods from stackChunkOops 113 virtual void do_nmethod(nmethod* nm) = 0; 114 }; 115 116 // An OopIterateClosure that can be used when there's no need to visit the Metadata. 117 class BasicOopIterateClosure : public OopIterateClosure { 118 public: 119 BasicOopIterateClosure(ReferenceDiscoverer* rd = nullptr) : OopIterateClosure(rd) {} 120 121 virtual bool do_metadata() { return false; } 122 virtual void do_klass(Klass* k) { ShouldNotReachHere(); } 123 virtual void do_cld(ClassLoaderData* cld) { ShouldNotReachHere(); } 124 virtual void do_method(Method* m) { ShouldNotReachHere(); } 125 virtual void do_nmethod(nmethod* nm) { ShouldNotReachHere(); } 126 }; 127 128 // Interface for applying an OopClosure to a set of oops. 129 class OopIterator { 130 public: 131 virtual void oops_do(OopClosure* cl) = 0; 132 }; 133 134 enum class derived_base : intptr_t; 135 enum class derived_pointer : intptr_t; 136 class DerivedOopClosure : public Closure { 137 public: 138 enum { SkipNull = true }; 139 virtual void do_derived_oop(derived_base* base, derived_pointer* derived) = 0; 140 }; 141 142 class BufferedValueClosure : public Closure { 143 public: 144 virtual void do_buffered_value(oop* p) = 0; 145 }; 146 147 class KlassClosure : public Closure { 148 public: 149 virtual void do_klass(Klass* k) = 0; 150 }; 151 152 class CLDClosure : public Closure { 153 public: 154 virtual void do_cld(ClassLoaderData* cld) = 0; 155 }; 156 157 class MetadataClosure : public Closure { 158 public: 159 virtual void do_metadata(Metadata* md) = 0; 160 }; 161 162 163 class CLDToOopClosure : public CLDClosure { 164 OopClosure* _oop_closure; 165 int _cld_claim; 166 167 public: 168 CLDToOopClosure(OopClosure* oop_closure, 169 int cld_claim) : 170 _oop_closure(oop_closure), 171 _cld_claim(cld_claim) {} 172 173 void do_cld(ClassLoaderData* cld); 174 }; 175 176 template <int claim> 177 class ClaimingCLDToOopClosure : public CLDToOopClosure { 178 public: 179 ClaimingCLDToOopClosure(OopClosure* cl) : CLDToOopClosure(cl, claim) {} 180 }; 181 182 class ClaimMetadataVisitingOopIterateClosure : public OopIterateClosure { 183 protected: 184 const int _claim; 185 186 public: 187 ClaimMetadataVisitingOopIterateClosure(int claim, ReferenceDiscoverer* rd = nullptr) : 188 OopIterateClosure(rd), 189 _claim(claim) { } 190 191 virtual bool do_metadata() { return true; } 192 virtual void do_klass(Klass* k); 193 virtual void do_cld(ClassLoaderData* cld); 194 virtual void do_method(Method* m); 195 virtual void do_nmethod(nmethod* nm); 196 }; 197 198 // The base class for all concurrent marking closures, 199 // that participates in class unloading. 200 // It's used to proxy through the metadata to the oops defined in them. 201 class MetadataVisitingOopIterateClosure: public ClaimMetadataVisitingOopIterateClosure { 202 public: 203 MetadataVisitingOopIterateClosure(ReferenceDiscoverer* rd = nullptr); 204 }; 205 206 // ObjectClosure is used for iterating through an object space 207 208 class ObjectClosure : public Closure { 209 public: 210 // Called for each object. 211 virtual void do_object(oop obj) = 0; 212 }; 213 214 class BoolObjectClosure : public Closure { 215 public: 216 virtual bool do_object_b(oop obj) = 0; 217 }; 218 219 class OopFieldClosure { 220 public: 221 virtual void do_field(oop base, oop* p) = 0; 222 }; 223 224 class AlwaysTrueClosure: public BoolObjectClosure { 225 public: 226 bool do_object_b(oop p) { return true; } 227 }; 228 229 class AlwaysFalseClosure : public BoolObjectClosure { 230 public: 231 bool do_object_b(oop p) { return false; } 232 }; 233 234 // Applies an oop closure to all ref fields in objects iterated over in an 235 // object iteration. 236 class ObjectToOopClosure: public ObjectClosure { 237 OopIterateClosure* _cl; 238 public: 239 void do_object(oop obj); 240 ObjectToOopClosure(OopIterateClosure* cl) : _cl(cl) {} 241 }; 242 243 // SpaceClosure is used for iterating over spaces 244 245 class Space; 246 247 class SpaceClosure : public StackObj { 248 public: 249 // Called for each space 250 virtual void do_space(Space* s) = 0; 251 }; 252 253 // CodeBlobClosure is used for iterating through code blobs 254 // in the code cache or on thread stacks 255 256 class CodeBlobClosure : public Closure { 257 public: 258 // Called for each code blob. 259 virtual void do_code_blob(CodeBlob* cb) = 0; 260 }; 261 262 // Applies an oop closure to all ref fields in code blobs 263 // iterated over in an object iteration. 264 class CodeBlobToOopClosure : public CodeBlobClosure { 265 protected: 266 OopClosure* _cl; 267 bool _fix_relocations; 268 void do_nmethod(nmethod* nm); 269 public: 270 // If fix_relocations(), then cl must copy objects to their new location immediately to avoid 271 // patching nmethods with the old locations. 272 CodeBlobToOopClosure(OopClosure* cl, bool fix_relocations) : _cl(cl), _fix_relocations(fix_relocations) {} 273 virtual void do_code_blob(CodeBlob* cb); 274 275 bool fix_relocations() const { return _fix_relocations; } 276 const static bool FixRelocations = true; 277 }; 278 279 class MarkingCodeBlobClosure : public CodeBlobToOopClosure { 280 bool _keepalive_nmethods; 281 282 public: 283 MarkingCodeBlobClosure(OopClosure* cl, bool fix_relocations, bool keepalive_nmethods) : 284 CodeBlobToOopClosure(cl, fix_relocations), 285 _keepalive_nmethods(keepalive_nmethods) {} 286 287 // Called for each code blob, but at most once per unique blob. 288 virtual void do_code_blob(CodeBlob* cb); 289 }; 290 291 class NMethodClosure : public Closure { 292 public: 293 virtual void do_nmethod(nmethod* n) = 0; 294 }; 295 296 class CodeBlobToNMethodClosure : public CodeBlobClosure { 297 NMethodClosure* const _nm_cl; 298 299 public: 300 CodeBlobToNMethodClosure(NMethodClosure* nm_cl) : _nm_cl(nm_cl) {} 301 302 virtual void do_code_blob(CodeBlob* cb); 303 }; 304 305 // MonitorClosure is used for iterating over monitors in the monitors cache 306 307 class ObjectMonitor; 308 309 class MonitorClosure : public StackObj { 310 public: 311 // called for each monitor in cache 312 virtual void do_monitor(ObjectMonitor* m) = 0; 313 }; 314 315 // A closure that is applied without any arguments. 316 class VoidClosure : public StackObj { 317 public: 318 virtual void do_void() = 0; 319 }; 320 321 322 // YieldClosure is intended for use by iteration loops 323 // to incrementalize their work, allowing interleaving 324 // of an interruptible task so as to allow other 325 // threads to run (which may not otherwise be able to access 326 // exclusive resources, for instance). Additionally, the 327 // closure also allows for aborting an ongoing iteration 328 // by means of checking the return value from the polling 329 // call. 330 class YieldClosure : public StackObj { 331 public: 332 virtual bool should_return() = 0; 333 334 // Yield on a fine-grain level. The check in case of not yielding should be very fast. 335 virtual bool should_return_fine_grain() { return false; } 336 }; 337 338 class SymbolClosure : public StackObj { 339 public: 340 virtual void do_symbol(Symbol**) = 0; 341 }; 342 343 template <typename E> 344 class CompareClosure : public Closure { 345 public: 346 virtual int do_compare(const E&, const E&) = 0; 347 }; 348 349 class OopIteratorClosureDispatch { 350 public: 351 template <typename OopClosureType> static void oop_oop_iterate(OopClosureType* cl, oop obj, Klass* klass); 352 template <typename OopClosureType> static void oop_oop_iterate(OopClosureType* cl, oop obj, Klass* klass, MemRegion mr); 353 template <typename OopClosureType> static void oop_oop_iterate_backwards(OopClosureType* cl, oop obj, Klass* klass); 354 }; 355 356 #endif // SHARE_MEMORY_ITERATOR_HPP