markSweep.hpp 8.6 KB
Newer Older
D
duke 已提交
1 2 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 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 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 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 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 238 239 240 241 242 243 244 245
/*
 * Copyright 1997-2007 Sun Microsystems, Inc.  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 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 {
  //
  // In line closure decls
  //

  class FollowRootClosure: public OopsInGenClosure{
   public:
    void do_oop(oop* p) { follow_root(p); }
    virtual const bool do_nmethods() const { return true; }
  };

  class MarkAndPushClosure: public OopClosure {
   public:
    void do_oop(oop* p) { mark_and_push(p); }
    virtual const bool do_nmethods() const { return true; }
  };

  class FollowStackClosure: public VoidClosure {
   public:
    void do_void() { follow_stack(); }
  };

  class AdjustPointerClosure: public OopsInGenClosure {
    bool _is_root;
   public:
    AdjustPointerClosure(bool is_root) : _is_root(is_root) {}
    void do_oop(oop* p) { _adjust_pointer(p, _is_root); }
  };

  // Used for java/lang/ref handling
  class IsAliveClosure: public BoolObjectClosure {
   public:
    void do_object(oop p) { assert(false, "don't call"); }
    bool do_object_b(oop p) { return p->is_gc_marked(); }
  };

  class KeepAliveClosure: public OopClosure {
   public:
    void do_oop(oop* p);
  };

  //
  // 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
  static GrowableArray<oop*>*            _root_refs_stack;
  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;
  static GrowableArray<oop*>*            _other_refs_stack;
  static GrowableArray<oop*>*            _adjusted_pointers;
  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
  static IsAliveClosure is_alive;
  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
  static FollowRootClosure follow_root_closure;
  static MarkAndPushClosure mark_and_push_closure;
  static FollowStackClosure follow_stack_closure;
  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);
  static void follow_root(oop* p);        // Mark pointer and follow contents. Empty marking

                                          // stack afterwards.

  static void mark_and_follow(oop* p);    // Mark pointer and follow contents.
  static void _mark_and_push(oop* p);     // Mark pointer and push obj on
                                          // marking stack.


  static void mark_and_push(oop* p) {     // Check mark and maybe push on
                                          // marking stack
    // assert(Universe::is_reserved_heap((oop)p), "we should only be traversing objects here");
    oop m = *p;
    if (m != NULL && !m->mark()->is_marked()) {
      _mark_and_push(p);
    }
  }

  static void follow_stack();             // Empty marking stack.


  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

  static void _adjust_pointer(oop* p, bool isroot);

  static void adjust_root_pointer(oop* p) { _adjust_pointer(p, true); }
  static void adjust_pointer(oop* p)      { _adjust_pointer(p, false); }

#ifdef VALIDATE_MARK_SWEEP
  static void track_adjusted_pointer(oop* p, oop newobj, bool isroot);
  static void check_adjust_pointer(oop* p);     // Adjust this pointer
  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);
  }
};