iterator.hpp 12.7 KB
Newer Older
D
duke 已提交
1
/*
2
 * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
D
duke 已提交
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
19 20 21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
D
duke 已提交
22 23 24
 *
 */

25 26 27 28 29 30 31 32
#ifndef SHARE_VM_MEMORY_ITERATOR_HPP
#define SHARE_VM_MEMORY_ITERATOR_HPP

#include "memory/allocation.hpp"
#include "memory/memRegion.hpp"
#include "runtime/prefetch.hpp"
#include "utilities/top.hpp"

D
duke 已提交
33 34
// The following classes are C++ `closures` for iterating over objects, roots and spaces

35
class CodeBlob;
36
class nmethod;
D
duke 已提交
37
class ReferenceProcessor;
Y
ysr 已提交
38
class DataLayout;
39 40
class KlassClosure;
class ClassLoaderData;
D
duke 已提交
41

42 43 44 45 46 47 48 49 50 51 52 53 54 55
// Closure provides abortability.

class Closure : public StackObj {
 protected:
  bool _abort;
  void set_abort() { _abort = true; }
 public:
  Closure() : _abort(false) {}
  // A subtype can use this mechanism to indicate to some iterator mapping
  // functions that the iteration should cease.
  bool abort() { return _abort; }
  void clear_abort() { _abort = false; }
};

56
// OopClosure is used for iterating through references to Java objects.
D
duke 已提交
57

58
class OopClosure : public Closure {
D
duke 已提交
59 60 61
 public:
  virtual void do_oop(oop* o) = 0;
  virtual void do_oop_v(oop* o) { do_oop(o); }
62 63
  virtual void do_oop(narrowOop* o) = 0;
  virtual void do_oop_v(narrowOop* o) { do_oop(o); }
64
};
D
duke 已提交
65

66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86
// ExtendedOopClosure adds extra code to be run during oop iterations.
// This is needed by the GC and is extracted to a separate type to not
// pollute the OopClosure interface.
class ExtendedOopClosure : public OopClosure {
 public:
  ReferenceProcessor* _ref_processor;
  ExtendedOopClosure(ReferenceProcessor* rp) : _ref_processor(rp) { }
  ExtendedOopClosure() : OopClosure(), _ref_processor(NULL) { }

  // If the do_metadata functions return "true",
  // we invoke the following when running oop_iterate():
  //
  // 1) do_klass on the header klass pointer.
  // 2) do_klass on the klass pointer in the mirrors.
  // 3) do_class_loader_data on the class loader data in class loaders.
  //
  // The virtual (without suffix) and the non-virtual (with _nv suffix) need
  // to be updated together, or else the devirtualization will break.
  //
  // Providing default implementations of the _nv functions unfortunately
  // removes the compile-time safeness, but reduces the clutter for the
87 88
  // ExtendedOopClosures that don't need to walk the metadata.
  // Currently, only CMS and G1 need these.
89 90 91 92 93 94 95 96 97 98

  virtual bool do_metadata() { return do_metadata_nv(); }
  bool do_metadata_v()       { return do_metadata(); }
  bool do_metadata_nv()      { return false; }

  virtual void do_klass(Klass* k)   { do_klass_nv(k); }
  void do_klass_v(Klass* k)         { do_klass(k); }
  void do_klass_nv(Klass* k)        { ShouldNotReachHere(); }

  virtual void do_class_loader_data(ClassLoaderData* cld) { ShouldNotReachHere(); }
D
duke 已提交
99 100 101 102 103

  // Controls how prefetching is done for invocations of this closure.
  Prefetch::style prefetch_style() { // Note that this is non-virtual.
    return Prefetch::do_none;
  }
104 105 106 107 108

  // True iff this closure may be safely applied more than once to an oop
  // location without an intervening "major reset" (like the end of a GC).
  virtual bool idempotent() { return false; }
  virtual bool apply_to_weak_ref_discovered_field() { return false; }
109
};
110

111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128
// Wrapper closure only used to implement oop_iterate_no_header().
class NoHeaderExtendedOopClosure : public ExtendedOopClosure {
  OopClosure* _wrapped_closure;
 public:
  NoHeaderExtendedOopClosure(OopClosure* cl) : _wrapped_closure(cl) {}
  // Warning: this calls the virtual version do_oop in the the wrapped closure.
  void do_oop_nv(oop* p)       { _wrapped_closure->do_oop(p); }
  void do_oop_nv(narrowOop* p) { _wrapped_closure->do_oop(p); }

  void do_oop(oop* p)          { assert(false, "Only the _nv versions should be used");
                                 _wrapped_closure->do_oop(p); }
  void do_oop(narrowOop* p)    { assert(false, "Only the _nv versions should be used");
                                 _wrapped_closure->do_oop(p);}
};

class KlassClosure : public Closure {
 public:
  virtual void do_klass(Klass* k) = 0;
D
duke 已提交
129 130
};

131 132 133 134 135
class CLDClosure : public Closure {
 public:
  virtual void do_cld(ClassLoaderData* cld) = 0;
};

136
class KlassToOopClosure : public KlassClosure {
137 138 139
  friend class MetadataAwareOopClosure;
  friend class MetadataAwareOopsInGenClosure;

140
  OopClosure* _oop_closure;
141 142 143 144 145 146 147

  // Used when _oop_closure couldn't be set in an initialization list.
  void initialize(OopClosure* oop_closure) {
    assert(_oop_closure == NULL, "Should only be called once");
    _oop_closure = oop_closure;
  }

148
 public:
149
  KlassToOopClosure(OopClosure* oop_closure = NULL) : _oop_closure(oop_closure) {}
150

151 152 153
  virtual void do_klass(Klass* k);
};

154
class CLDToOopClosure : public CLDClosure {
155
  OopClosure*       _oop_closure;
156
  KlassToOopClosure _klass_closure;
157
  bool              _must_claim_cld;
158 159 160 161 162 163 164 165 166 167

 public:
  CLDToOopClosure(OopClosure* oop_closure, bool must_claim_cld = true) :
      _oop_closure(oop_closure),
      _klass_closure(oop_closure),
      _must_claim_cld(must_claim_cld) {}

  void do_cld(ClassLoaderData* cld);
};

168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184
class CLDToKlassAndOopClosure : public CLDClosure {
  friend class SharedHeap;
  friend class G1CollectedHeap;
 protected:
  OopClosure*   _oop_closure;
  KlassClosure* _klass_closure;
  bool          _must_claim_cld;
 public:
  CLDToKlassAndOopClosure(KlassClosure* klass_closure,
                          OopClosure* oop_closure,
                          bool must_claim_cld) :
                              _oop_closure(oop_closure),
                              _klass_closure(klass_closure),
                              _must_claim_cld(must_claim_cld) {}
  void do_cld(ClassLoaderData* cld);
};

185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207
// The base class for all concurrent marking closures,
// that participates in class unloading.
// It's used to proxy through the metadata to the oops defined in them.
class MetadataAwareOopClosure: public ExtendedOopClosure {
  KlassToOopClosure _klass_closure;

 public:
  MetadataAwareOopClosure() : ExtendedOopClosure() {
    _klass_closure.initialize(this);
  }
  MetadataAwareOopClosure(ReferenceProcessor* rp) : ExtendedOopClosure(rp) {
    _klass_closure.initialize(this);
  }

  virtual bool do_metadata()    { return do_metadata_nv(); }
  inline  bool do_metadata_nv() { return true; }

  virtual void do_klass(Klass* k);
  void do_klass_nv(Klass* k);

  virtual void do_class_loader_data(ClassLoaderData* cld);
};

D
duke 已提交
208 209
// ObjectClosure is used for iterating through an object space

210
class ObjectClosure : public Closure {
D
duke 已提交
211 212 213 214 215 216
 public:
  // Called for each object.
  virtual void do_object(oop obj) = 0;
};


217
class BoolObjectClosure : public Closure {
D
duke 已提交
218 219 220 221 222 223 224
 public:
  virtual bool do_object_b(oop obj) = 0;
};

// Applies an oop closure to all ref fields in objects iterated over in an
// object iteration.
class ObjectToOopClosure: public ObjectClosure {
225
  ExtendedOopClosure* _cl;
D
duke 已提交
226 227
public:
  void do_object(oop obj);
228
  ObjectToOopClosure(ExtendedOopClosure* cl) : _cl(cl) {}
D
duke 已提交
229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276
};

// A version of ObjectClosure that is expected to be robust
// in the face of possibly uninitialized objects.
class ObjectClosureCareful : public ObjectClosure {
 public:
  virtual size_t do_object_careful_m(oop p, MemRegion mr) = 0;
  virtual size_t do_object_careful(oop p) = 0;
};

// The following are used in CompactibleFreeListSpace and
// ConcurrentMarkSweepGeneration.

// Blk closure (abstract class)
class BlkClosure : public StackObj {
 public:
  virtual size_t do_blk(HeapWord* addr) = 0;
};

// A version of BlkClosure that is expected to be robust
// in the face of possibly uninitialized objects.
class BlkClosureCareful : public BlkClosure {
 public:
  size_t do_blk(HeapWord* addr) {
    guarantee(false, "call do_blk_careful instead");
    return 0;
  }
  virtual size_t do_blk_careful(HeapWord* addr) = 0;
};

// SpaceClosure is used for iterating over spaces

class Space;
class CompactibleSpace;

class SpaceClosure : public StackObj {
 public:
  // Called for each space
  virtual void do_space(Space* s) = 0;
};

class CompactibleSpaceClosure : public StackObj {
 public:
  // Called for each compactible space
  virtual void do_space(CompactibleSpace* s) = 0;
};


277 278 279 280 281 282 283 284 285
// CodeBlobClosure is used for iterating through code blobs
// in the code cache or on thread stacks

class CodeBlobClosure : public Closure {
 public:
  // Called for each code blob.
  virtual void do_code_blob(CodeBlob* cb) = 0;
};

286 287 288 289 290 291 292 293 294 295 296 297 298
// Applies an oop closure to all ref fields in code blobs
// iterated over in an object iteration.
class CodeBlobToOopClosure : public CodeBlobClosure {
  OopClosure* _cl;
  bool _fix_relocations;
 protected:
  void do_nmethod(nmethod* nm);
 public:
  CodeBlobToOopClosure(OopClosure* cl, bool fix_relocations) : _cl(cl), _fix_relocations(fix_relocations) {}
  virtual void do_code_blob(CodeBlob* cb);

  const static bool FixRelocations = true;
};
299

300
class MarkingCodeBlobClosure : public CodeBlobToOopClosure {
301
 public:
302
  MarkingCodeBlobClosure(OopClosure* cl, bool fix_relocations) : CodeBlobToOopClosure(cl, fix_relocations) {}
303 304 305 306 307 308 309 310 311 312 313 314 315 316 317
  // Called for each code blob, but at most once per unique blob.

  virtual void do_code_blob(CodeBlob* cb);

  class MarkScope : public StackObj {
  protected:
    bool _active;
  public:
    MarkScope(bool activate = true);
      // = { if (active) nmethod::oops_do_marking_prologue(); }
    ~MarkScope();
      // = { if (active) nmethod::oops_do_marking_epilogue(); }
  };
};

D
duke 已提交
318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351
// MonitorClosure is used for iterating over monitors in the monitors cache

class ObjectMonitor;

class MonitorClosure : public StackObj {
 public:
  // called for each monitor in cache
  virtual void do_monitor(ObjectMonitor* m) = 0;
};

// A closure that is applied without any arguments.
class VoidClosure : public StackObj {
 public:
  // I would have liked to declare this a pure virtual, but that breaks
  // in mysterious ways, for unknown reasons.
  virtual void do_void();
};


// YieldClosure is intended for use by iteration loops
// to incrementalize their work, allowing interleaving
// of an interruptable task so as to allow other
// threads to run (which may not otherwise be able to access
// exclusive resources, for instance). Additionally, the
// closure also allows for aborting an ongoing iteration
// by means of checking the return value from the polling
// call.
class YieldClosure : public StackObj {
  public:
   virtual bool should_return() = 0;
};

// Abstract closure for serializing data (read or write).

352
class SerializeClosure : public Closure {
D
duke 已提交
353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368
public:
  // Return bool indicating whether closure implements read or write.
  virtual bool reading() const = 0;

  // Read/write the void pointer pointed to by p.
  virtual void do_ptr(void** p) = 0;

  // Read/write the region specified.
  virtual void do_region(u_char* start, size_t size) = 0;

  // Check/write the tag.  If reading, then compare the tag against
  // the passed in value and fail is they don't match.  This allows
  // for verification that sections of the serialized data are of the
  // correct length.
  virtual void do_tag(int tag) = 0;
};
369

370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385
class SymbolClosure : public StackObj {
 public:
  virtual void do_symbol(Symbol**) = 0;

  // Clear LSB in symbol address; it can be set by CPSlot.
  static Symbol* load_symbol(Symbol** p) {
    return (Symbol*)(intptr_t(*p) & ~1);
  }

  // Store symbol, adjusting new pointer if the original pointer was adjusted
  // (symbol references in constant pool slots have their LSB set to 1).
  static void store_symbol(Symbol** p, Symbol* sym) {
    *p = (Symbol*)(intptr_t(sym) | (intptr_t(*p) & 1));
  }
};

386 387 388 389 390 391 392 393 394 395 396 397

// Helper defines for ExtendOopClosure

#define if_do_metadata_checked(closure, nv_suffix)       \
  /* Make sure the non-virtual and the virtual versions match. */     \
  assert(closure->do_metadata##nv_suffix() == closure->do_metadata(), \
      "Inconsistency in do_metadata");                                \
  if (closure->do_metadata##nv_suffix())

#define assert_should_ignore_metadata(closure, nv_suffix)                                  \
  assert(!closure->do_metadata##nv_suffix(), "Code to handle metadata is not implemented")

398
#endif // SHARE_VM_MEMORY_ITERATOR_HPP