src/hotspot/share/memory/iterator.hpp
changeset 47216 71c04702a3d5
parent 46445 825b002e05ae
child 47580 96392e113a0a
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/memory/iterator.hpp	Tue Sep 12 19:03:39 2017 +0200
@@ -0,0 +1,427 @@
+/*
+ * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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.
+ *
+ * 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.
+ *
+ */
+
+#ifndef SHARE_VM_MEMORY_ITERATOR_HPP
+#define SHARE_VM_MEMORY_ITERATOR_HPP
+
+#include "memory/allocation.hpp"
+#include "memory/memRegion.hpp"
+#include "oops/oopsHierarchy.hpp"
+
+class CodeBlob;
+class nmethod;
+class ReferenceProcessor;
+class DataLayout;
+class KlassClosure;
+class ClassLoaderData;
+class Symbol;
+
+// The following classes are C++ `closures` for iterating over objects, roots and spaces
+
+class Closure : public StackObj { };
+
+// OopClosure is used for iterating through references to Java objects.
+class OopClosure : public Closure {
+ public:
+  virtual void do_oop(oop* o) = 0;
+  virtual void do_oop(narrowOop* o) = 0;
+};
+
+// 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 {
+ private:
+  ReferenceProcessor* _ref_processor;
+
+ protected:
+  ExtendedOopClosure(ReferenceProcessor* rp) : _ref_processor(rp) { }
+  ExtendedOopClosure() : _ref_processor(NULL) { }
+  ~ExtendedOopClosure() { }
+
+  void set_ref_processor_internal(ReferenceProcessor* rp) { _ref_processor = rp; }
+
+ public:
+  ReferenceProcessor* ref_processor() const { return _ref_processor; }
+
+  // Iteration of InstanceRefKlasses differ depending on the closure,
+  // the below enum describes the different alternatives.
+  enum ReferenceIterationMode {
+    DO_DISCOVERY,                // Apply closure and discover references
+    DO_DISCOVERED_AND_DISCOVERY, // Apply closure to discovered field and do discovery
+    DO_FIELDS                    // Apply closure to all fields
+  };
+
+  // The default iteration mode is to do discovery.
+  virtual ReferenceIterationMode reference_iteration_mode() { return DO_DISCOVERY; }
+
+  // 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_cld   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
+  // ExtendedOopClosures that don't need to walk the metadata.
+  // Currently, only CMS and G1 need these.
+
+  bool do_metadata_nv()      { return false; }
+  virtual bool do_metadata() { return do_metadata_nv(); }
+
+  void do_klass_nv(Klass* k)      { ShouldNotReachHere(); }
+  virtual void do_klass(Klass* k) { do_klass_nv(k); }
+
+  void do_cld_nv(ClassLoaderData* cld)      { ShouldNotReachHere(); }
+  virtual void do_cld(ClassLoaderData* cld) { do_cld_nv(cld); }
+
+  // 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; }
+
+#ifdef ASSERT
+  // Default verification of each visited oop field.
+  template <typename T> void verify(T* p);
+
+  // Can be used by subclasses to turn off the default verification of oop fields.
+  virtual bool should_verify_oops() { return true; }
+#endif
+};
+
+// 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;
+};
+
+class CLDClosure : public Closure {
+ public:
+  virtual void do_cld(ClassLoaderData* cld) = 0;
+};
+
+class KlassToOopClosure : public KlassClosure {
+  friend class MetadataAwareOopClosure;
+  friend class MetadataAwareOopsInGenClosure;
+
+  OopClosure* _oop_closure;
+
+  // 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;
+  }
+
+ public:
+  KlassToOopClosure(OopClosure* oop_closure = NULL) : _oop_closure(oop_closure) {}
+
+  virtual void do_klass(Klass* k);
+};
+
+class CLDToOopClosure : public CLDClosure {
+  OopClosure*       _oop_closure;
+  KlassToOopClosure _klass_closure;
+  bool              _must_claim_cld;
+
+ 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);
+};
+
+class CLDToKlassAndOopClosure : public CLDClosure {
+  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);
+};
+
+// 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);
+  }
+
+  bool do_metadata_nv()      { return true; }
+  virtual bool do_metadata() { return do_metadata_nv(); }
+
+  void do_klass_nv(Klass* k);
+  virtual void do_klass(Klass* k) { do_klass_nv(k); }
+
+  void do_cld_nv(ClassLoaderData* cld);
+  virtual void do_cld(ClassLoaderData* cld) { do_cld_nv(cld); }
+};
+
+// ObjectClosure is used for iterating through an object space
+
+class ObjectClosure : public Closure {
+ public:
+  // Called for each object.
+  virtual void do_object(oop obj) = 0;
+};
+
+
+class BoolObjectClosure : public Closure {
+ public:
+  virtual bool do_object_b(oop obj) = 0;
+};
+
+class AlwaysTrueClosure: public BoolObjectClosure {
+ public:
+  bool do_object_b(oop p) { return true; }
+};
+
+class AlwaysFalseClosure : public BoolObjectClosure {
+ public:
+  bool do_object_b(oop p) { return false; }
+};
+
+// Applies an oop closure to all ref fields in objects iterated over in an
+// object iteration.
+class ObjectToOopClosure: public ObjectClosure {
+  ExtendedOopClosure* _cl;
+public:
+  void do_object(oop obj);
+  ObjectToOopClosure(ExtendedOopClosure* cl) : _cl(cl) {}
+};
+
+// 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;
+};
+
+
+// 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;
+};
+
+// 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:
+  // If fix_relocations(), then cl must copy objects to their new location immediately to avoid
+  // patching nmethods with the old locations.
+  CodeBlobToOopClosure(OopClosure* cl, bool fix_relocations) : _cl(cl), _fix_relocations(fix_relocations) {}
+  virtual void do_code_blob(CodeBlob* cb);
+
+  bool fix_relocations() const { return _fix_relocations; }
+  const static bool FixRelocations = true;
+};
+
+class MarkingCodeBlobClosure : public CodeBlobToOopClosure {
+ public:
+  MarkingCodeBlobClosure(OopClosure* cl, bool fix_relocations) : CodeBlobToOopClosure(cl, fix_relocations) {}
+  // Called for each code blob, but at most once per unique blob.
+
+  virtual void do_code_blob(CodeBlob* cb);
+};
+
+// 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).
+
+class SerializeClosure : public Closure {
+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 32-bit unsigned integer pointed to by p.
+  virtual void do_u4(u4* 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;
+
+  bool writing() {
+    return !reading();
+  }
+};
+
+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));
+  }
+};
+
+// The two class template specializations are used to dispatch calls
+// to the ExtendedOopClosure functions. If use_non_virtual_call is true,
+// the non-virtual versions are called (E.g. do_oop_nv), otherwise the
+// virtual versions are called (E.g. do_oop).
+
+template <bool use_non_virtual_call>
+class Devirtualizer {};
+
+// Dispatches to the non-virtual functions.
+template <> class Devirtualizer<true> {
+ public:
+  template <class OopClosureType, typename T> static void do_oop(OopClosureType* closure, T* p);
+  template <class OopClosureType>             static void do_klass(OopClosureType* closure, Klass* k);
+  template <class OopClosureType>             static void do_cld(OopClosureType* closure, ClassLoaderData* cld);
+  template <class OopClosureType>             static bool do_metadata(OopClosureType* closure);
+};
+
+// Dispatches to the virtual functions.
+template <> class Devirtualizer<false> {
+ public:
+  template <class OopClosureType, typename T> static void do_oop(OopClosureType* closure, T* p);
+  template <class OopClosureType>             static void do_klass(OopClosureType* closure, Klass* k);
+  template <class OopClosureType>             static void do_cld(OopClosureType* closure, ClassLoaderData* cld);
+  template <class OopClosureType>             static bool do_metadata(OopClosureType* closure);
+};
+
+#endif // SHARE_VM_MEMORY_ITERATOR_HPP