markSweep.hpp 8.4 KB
Newer Older
D
duke 已提交
1
/*
X
xdono 已提交
2
 * Copyright 1997-2008 Sun Microsystems, Inc.  All Rights Reserved.
D
duke 已提交
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
 * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.com if you need additional information or
 * have any questions.
 *
 */

class ReferenceProcessor;

// MarkSweep takes care of global mark-compact garbage collection for a
// GenCollectedHeap using a four-phase pointer forwarding algorithm.  All
// generations are assumed to support marking; those that can also support
// compaction.
//
// Class unloading will only occur when a full gc is invoked.

// If VALIDATE_MARK_SWEEP is defined, the -XX:+ValidateMarkSweep flag will
// be operational, and will provide slow but comprehensive self-checks within
// the GC.  This is not enabled by default in product or release builds,
// since the extra call to track_adjusted_pointer() in _adjust_pointer()
// would be too much overhead, and would disturb performance measurement.
// However, debug builds are sometimes way too slow to run GC tests!
#ifdef ASSERT
#define VALIDATE_MARK_SWEEP 1
#endif
#ifdef VALIDATE_MARK_SWEEP
#define VALIDATE_MARK_SWEEP_ONLY(code) code
#else
#define VALIDATE_MARK_SWEEP_ONLY(code)
#endif

// declared at end
class PreservedMark;

class MarkSweep : AllStatic {
  //
54
  // Inline closure decls
D
duke 已提交
55
  //
56
  class FollowRootClosure: public OopsInGenClosure {
D
duke 已提交
57
   public:
58 59
    virtual void do_oop(oop* p);
    virtual void do_oop(narrowOop* p);
D
duke 已提交
60 61 62 63 64
    virtual const bool do_nmethods() const { return true; }
  };

  class MarkAndPushClosure: public OopClosure {
   public:
65 66
    virtual void do_oop(oop* p);
    virtual void do_oop(narrowOop* p);
D
duke 已提交
67 68 69 70 71
    virtual const bool do_nmethods() const { return true; }
  };

  class FollowStackClosure: public VoidClosure {
   public:
72
    virtual void do_void();
D
duke 已提交
73 74 75
  };

  class AdjustPointerClosure: public OopsInGenClosure {
76
   private:
D
duke 已提交
77 78 79
    bool _is_root;
   public:
    AdjustPointerClosure(bool is_root) : _is_root(is_root) {}
80 81
    virtual void do_oop(oop* p);
    virtual void do_oop(narrowOop* p);
D
duke 已提交
82 83 84 85 86
  };

  // Used for java/lang/ref handling
  class IsAliveClosure: public BoolObjectClosure {
   public:
87 88
    virtual void do_object(oop p);
    virtual bool do_object_b(oop p);
D
duke 已提交
89 90 91
  };

  class KeepAliveClosure: public OopClosure {
92 93
   protected:
    template <class T> void do_oop_work(T* p);
D
duke 已提交
94
   public:
95 96
    virtual void do_oop(oop* p);
    virtual void do_oop(narrowOop* p);
D
duke 已提交
97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126
  };

  //
  // Friend decls
  //
  friend class AdjustPointerClosure;
  friend class KeepAliveClosure;
  friend class VM_MarkSweep;
  friend void marksweep_init();

  //
  // Vars
  //
 protected:
  // Traversal stack used during phase1
  static GrowableArray<oop>*             _marking_stack;
  // Stack for live klasses to revisit at end of marking phase
  static GrowableArray<Klass*>*          _revisit_klass_stack;

  // Space for storing/restoring mark word
  static GrowableArray<markOop>*         _preserved_mark_stack;
  static GrowableArray<oop>*             _preserved_oop_stack;
  static size_t                          _preserved_count;
  static size_t                          _preserved_count_max;
  static PreservedMark*                  _preserved_marks;

  // Reference processing (used in ...follow_contents)
  static ReferenceProcessor*             _ref_processor;

#ifdef VALIDATE_MARK_SWEEP
127
  static GrowableArray<void*>*           _root_refs_stack;
D
duke 已提交
128 129 130 131 132
  static GrowableArray<oop> *            _live_oops;
  static GrowableArray<oop> *            _live_oops_moved_to;
  static GrowableArray<size_t>*          _live_oops_size;
  static size_t                          _live_oops_index;
  static size_t                          _live_oops_index_at_perm;
133 134
  static GrowableArray<void*>*           _other_refs_stack;
  static GrowableArray<void*>*           _adjusted_pointers;
D
duke 已提交
135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153
  static bool                            _pointer_tracking;
  static bool                            _root_tracking;

  // The following arrays are saved since the time of the last GC and
  // assist in tracking down problems where someone has done an errant
  // store into the heap, usually to an oop that wasn't properly
  // handleized across a GC. If we crash or otherwise fail before the
  // next GC, we can query these arrays to find out the object we had
  // intended to do the store to (assuming it is still alive) and the
  // offset within that object. Covered under RecordMarkSweepCompaction.
  static GrowableArray<HeapWord*> *      _cur_gc_live_oops;
  static GrowableArray<HeapWord*> *      _cur_gc_live_oops_moved_to;
  static GrowableArray<size_t>*          _cur_gc_live_oops_size;
  static GrowableArray<HeapWord*> *      _last_gc_live_oops;
  static GrowableArray<HeapWord*> *      _last_gc_live_oops_moved_to;
  static GrowableArray<size_t>*          _last_gc_live_oops_size;
#endif

  // Non public closures
154
  static IsAliveClosure   is_alive;
D
duke 已提交
155 156 157 158 159 160 161 162 163 164
  static KeepAliveClosure keep_alive;

  // Class unloading. Update subklass/sibling/implementor links at end of marking phase.
  static void follow_weak_klass_links();

  // Debugging
  static void trace(const char* msg) PRODUCT_RETURN;

 public:
  // Public closures
165 166 167
  static FollowRootClosure    follow_root_closure;
  static MarkAndPushClosure   mark_and_push_closure;
  static FollowStackClosure   follow_stack_closure;
D
duke 已提交
168 169 170 171 172 173 174 175
  static AdjustPointerClosure adjust_root_pointer_closure;
  static AdjustPointerClosure adjust_pointer_closure;

  // Reference Processing
  static ReferenceProcessor* const ref_processor() { return _ref_processor; }

  // Call backs for marking
  static void mark_object(oop obj);
176 177 178 179 180 181
  // Mark pointer and follow contents.  Empty marking stack afterwards.
  template <class T> static inline void follow_root(T* p);
  // Mark pointer and follow contents.
  template <class T> static inline void mark_and_follow(T* p);
  // Check mark and maybe push on marking stack
  template <class T> static inline void mark_and_push(T* p);
D
duke 已提交
182

183
  static void follow_stack();   // Empty marking stack.
D
duke 已提交
184

185 186 187 188
  static void preserve_mark(oop p, markOop mark);
                                // Save the mark word so it can be restored later
  static void adjust_marks();   // Adjust the pointers in the preserved marks table
  static void restore_marks();  // Restore the marks that we saved in preserve_mark
D
duke 已提交
189

190
  template <class T> static inline void adjust_pointer(T* p, bool isroot);
D
duke 已提交
191

192 193 194
  static void adjust_root_pointer(oop* p)  { adjust_pointer(p, true); }
  static void adjust_pointer(oop* p)       { adjust_pointer(p, false); }
  static void adjust_pointer(narrowOop* p) { adjust_pointer(p, false); }
D
duke 已提交
195 196

#ifdef VALIDATE_MARK_SWEEP
197 198
  static void track_adjusted_pointer(void* p, bool isroot);
  static void check_adjust_pointer(void* p);
D
duke 已提交
199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237
  static void track_interior_pointers(oop obj);
  static void check_interior_pointers();

  static void reset_live_oop_tracking(bool at_perm);
  static void register_live_oop(oop p, size_t size);
  static void validate_live_oop(oop p, size_t size);
  static void live_oop_moved_to(HeapWord* q, size_t size, HeapWord* compaction_top);
  static void compaction_complete();

  // Querying operation of RecordMarkSweepCompaction results.
  // Finds and prints the current base oop and offset for a word
  // within an oop that was live during the last GC. Helpful for
  // tracking down heap stomps.
  static void print_new_location_of_heap_address(HeapWord* q);
#endif

  // Call backs for class unloading
  static void revisit_weak_klass_link(Klass* k);  // Update subklass/sibling/implementor links at end of marking.
};

class PreservedMark VALUE_OBJ_CLASS_SPEC {
private:
  oop _obj;
  markOop _mark;

public:
  void init(oop obj, markOop mark) {
    _obj = obj;
    _mark = mark;
  }

  void adjust_pointer() {
    MarkSweep::adjust_pointer(&_obj);
  }

  void restore() {
    _obj->set_mark(_mark);
  }
};