cmsOopClosures.hpp 14.3 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
/*
 * Copyright (c) 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.
 *
 */

/////////////////////////////////////////////////////////////////
// Closures used by ConcurrentMarkSweepGeneration's collector
/////////////////////////////////////////////////////////////////
class ConcurrentMarkSweepGeneration;
class CMSBitMap;
class CMSMarkStack;
class CMSCollector;
class MarkFromRootsClosure;
class Par_MarkFromRootsClosure;

35 36 37 38 39 40 41 42 43 44 45
// Decode the oop and call do_oop on it.
#define DO_OOP_WORK_DEFN \
  void do_oop(oop obj);                                   \
  template <class T> inline void do_oop_work(T* p) {      \
    T heap_oop = oopDesc::load_heap_oop(p);               \
    if (!oopDesc::is_null(heap_oop)) {                    \
      oop obj = oopDesc::decode_heap_oop_not_null(heap_oop);       \
      do_oop(obj);                                        \
    }                                                     \
  }

D
duke 已提交
46
class MarkRefsIntoClosure: public OopsInGenClosure {
47 48 49 50 51 52
 private:
  const MemRegion _span;
  CMSBitMap*      _bitMap;
  const bool      _should_do_nmethods;
 protected:
  DO_OOP_WORK_DEFN
D
duke 已提交
53 54 55
 public:
  MarkRefsIntoClosure(MemRegion span, CMSBitMap* bitMap,
                      bool should_do_nmethods);
56 57 58 59
  virtual void do_oop(oop* p);
  virtual void do_oop(narrowOop* p);
  inline void do_oop_nv(oop* p)       { MarkRefsIntoClosure::do_oop_work(p); }
  inline void do_oop_nv(narrowOop* p) { MarkRefsIntoClosure::do_oop_work(p); }
D
duke 已提交
60 61 62 63 64 65 66 67 68 69 70 71
  bool do_header() { return true; }
  virtual const bool do_nmethods() const {
    return _should_do_nmethods;
  }
  Prefetch::style prefetch_style() {
    return Prefetch::do_read;
  }
};

// A variant of the above used in certain kinds of CMS
// marking verification.
class MarkRefsIntoVerifyClosure: public OopsInGenClosure {
72 73 74 75 76 77 78
 private:
  const MemRegion _span;
  CMSBitMap*      _verification_bm;
  CMSBitMap*      _cms_bm;
  const bool      _should_do_nmethods;
 protected:
  DO_OOP_WORK_DEFN
D
duke 已提交
79 80 81
 public:
  MarkRefsIntoVerifyClosure(MemRegion span, CMSBitMap* verification_bm,
                            CMSBitMap* cms_bm, bool should_do_nmethods);
82 83 84 85
  virtual void do_oop(oop* p);
  virtual void do_oop(narrowOop* p);
  inline void do_oop_nv(oop* p)       { MarkRefsIntoVerifyClosure::do_oop_work(p); }
  inline void do_oop_nv(narrowOop* p) { MarkRefsIntoVerifyClosure::do_oop_work(p); }
D
duke 已提交
86 87 88 89 90 91 92 93 94 95 96
  bool do_header() { return true; }
  virtual const bool do_nmethods() const {
    return _should_do_nmethods;
  }
  Prefetch::style prefetch_style() {
    return Prefetch::do_read;
  }
};

// The non-parallel version (the parallel version appears further below).
class PushAndMarkClosure: public OopClosure {
97 98 99 100 101 102 103 104 105 106 107
 private:
  CMSCollector* _collector;
  MemRegion     _span;
  CMSBitMap*    _bit_map;
  CMSBitMap*    _mod_union_table;
  CMSMarkStack* _mark_stack;
  CMSMarkStack* _revisit_stack;
  bool          _concurrent_precleaning;
  bool const    _should_remember_klasses;
 protected:
  DO_OOP_WORK_DEFN
D
duke 已提交
108 109 110 111 112 113
 public:
  PushAndMarkClosure(CMSCollector* collector,
                     MemRegion span,
                     ReferenceProcessor* rp,
                     CMSBitMap* bit_map,
                     CMSBitMap* mod_union_table,
114 115 116 117 118 119 120
                     CMSMarkStack* mark_stack,
                     CMSMarkStack* revisit_stack,
                     bool concurrent_precleaning);
  virtual void do_oop(oop* p);
  virtual void do_oop(narrowOop* p);
  inline void do_oop_nv(oop* p)       { PushAndMarkClosure::do_oop_work(p); }
  inline void do_oop_nv(narrowOop* p) { PushAndMarkClosure::do_oop_work(p); }
D
duke 已提交
121 122 123 124
  bool do_header() { return true; }
  Prefetch::style prefetch_style() {
    return Prefetch::do_read;
  }
125
  virtual const bool should_remember_klasses() const {
D
duke 已提交
126 127
    return _should_remember_klasses;
  }
128
  virtual void remember_klass(Klass* k);
D
duke 已提交
129 130 131 132 133 134 135 136 137
};

// In the parallel case, the revisit stack, the bit map and the
// reference processor are currently all shared. Access to
// these shared mutable structures must use appropriate
// synchronization (for instance, via CAS). The marking stack
// used in the non-parallel case above is here replaced with
// an OopTaskQueue structure to allow efficient work stealing.
class Par_PushAndMarkClosure: public OopClosure {
138 139 140 141 142 143 144 145 146
 private:
  CMSCollector* _collector;
  MemRegion     _span;
  CMSBitMap*    _bit_map;
  OopTaskQueue* _work_queue;
  CMSMarkStack* _revisit_stack;
  bool const    _should_remember_klasses;
 protected:
  DO_OOP_WORK_DEFN
D
duke 已提交
147 148 149 150 151 152 153
 public:
  Par_PushAndMarkClosure(CMSCollector* collector,
                         MemRegion span,
                         ReferenceProcessor* rp,
                         CMSBitMap* bit_map,
                         OopTaskQueue* work_queue,
                         CMSMarkStack* revisit_stack);
154 155 156 157
  virtual void do_oop(oop* p);
  virtual void do_oop(narrowOop* p);
  inline void do_oop_nv(oop* p)       { Par_PushAndMarkClosure::do_oop_work(p); }
  inline void do_oop_nv(narrowOop* p) { Par_PushAndMarkClosure::do_oop_work(p); }
D
duke 已提交
158 159 160 161
  bool do_header() { return true; }
  Prefetch::style prefetch_style() {
    return Prefetch::do_read;
  }
162
  virtual const bool should_remember_klasses() const {
D
duke 已提交
163 164
    return _should_remember_klasses;
  }
165
  virtual void remember_klass(Klass* k);
D
duke 已提交
166 167 168 169
};

// The non-parallel version (the parallel version appears further below).
class MarkRefsIntoAndScanClosure: public OopsInGenClosure {
170 171 172 173 174 175 176 177
 private:
  MemRegion          _span;
  CMSBitMap*         _bit_map;
  CMSMarkStack*      _mark_stack;
  PushAndMarkClosure _pushAndMarkClosure;
  CMSCollector*      _collector;
  Mutex*             _freelistLock;
  bool               _yield;
D
duke 已提交
178
  // Whether closure is being used for concurrent precleaning
179 180 181
  bool               _concurrent_precleaning;
 protected:
  DO_OOP_WORK_DEFN
D
duke 已提交
182 183 184 185 186
 public:
  MarkRefsIntoAndScanClosure(MemRegion span,
                             ReferenceProcessor* rp,
                             CMSBitMap* bit_map,
                             CMSBitMap* mod_union_table,
187 188
                             CMSMarkStack* mark_stack,
                             CMSMarkStack* revisit_stack,
D
duke 已提交
189 190 191
                             CMSCollector* collector,
                             bool should_yield,
                             bool concurrent_precleaning);
192 193 194 195
  virtual void do_oop(oop* p);
  virtual void do_oop(narrowOop* p);
  inline void do_oop_nv(oop* p)       { MarkRefsIntoAndScanClosure::do_oop_work(p); }
  inline void do_oop_nv(narrowOop* p) { MarkRefsIntoAndScanClosure::do_oop_work(p); }
D
duke 已提交
196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215
  bool do_header() { return true; }
  virtual const bool do_nmethods() const { return true; }
  Prefetch::style prefetch_style() {
    return Prefetch::do_read;
  }
  void set_freelistLock(Mutex* m) {
    _freelistLock = m;
  }

 private:
  inline void do_yield_check();
  void do_yield_work();
  bool take_from_overflow_list();
};

// Tn this, the parallel avatar of MarkRefsIntoAndScanClosure, the revisit
// stack and the bitMap are shared, so access needs to be suitably
// sycnhronized. An OopTaskQueue structure, supporting efficient
// workstealing, replaces a CMSMarkStack for storing grey objects.
class Par_MarkRefsIntoAndScanClosure: public OopsInGenClosure {
216 217 218 219 220 221 222 223
 private:
  MemRegion              _span;
  CMSBitMap*             _bit_map;
  OopTaskQueue*          _work_queue;
  const uint             _low_water_mark;
  Par_PushAndMarkClosure _par_pushAndMarkClosure;
 protected:
  DO_OOP_WORK_DEFN
D
duke 已提交
224 225 226 227 228 229 230
 public:
  Par_MarkRefsIntoAndScanClosure(CMSCollector* collector,
                                 MemRegion span,
                                 ReferenceProcessor* rp,
                                 CMSBitMap* bit_map,
                                 OopTaskQueue* work_queue,
                                 CMSMarkStack*  revisit_stack);
231 232 233 234
  virtual void do_oop(oop* p);
  virtual void do_oop(narrowOop* p);
  inline void do_oop_nv(oop* p)       { Par_MarkRefsIntoAndScanClosure::do_oop_work(p); }
  inline void do_oop_nv(narrowOop* p) { Par_MarkRefsIntoAndScanClosure::do_oop_work(p); }
D
duke 已提交
235 236 237 238 239 240 241 242 243 244 245 246
  bool do_header() { return true; }
  virtual const bool do_nmethods() const { return true; }
  Prefetch::style prefetch_style() {
    return Prefetch::do_read;
  }
  void trim_queue(uint size);
};

// This closure is used during the concurrent marking phase
// following the first checkpoint. Its use is buried in
// the closure MarkFromRootsClosure.
class PushOrMarkClosure: public OopClosure {
247 248 249 250 251 252 253 254 255 256 257 258
 private:
  CMSCollector*   _collector;
  MemRegion       _span;
  CMSBitMap*      _bitMap;
  CMSMarkStack*   _markStack;
  CMSMarkStack*   _revisitStack;
  HeapWord* const _finger;
  MarkFromRootsClosure* const
                  _parent;
  bool const      _should_remember_klasses;
 protected:
  DO_OOP_WORK_DEFN
D
duke 已提交
259 260 261 262
 public:
  PushOrMarkClosure(CMSCollector* cms_collector,
                    MemRegion span,
                    CMSBitMap* bitMap,
263 264 265
                    CMSMarkStack* markStack,
                    CMSMarkStack* revisitStack,
                    HeapWord* finger,
D
duke 已提交
266
                    MarkFromRootsClosure* parent);
267 268 269 270 271
  virtual void do_oop(oop* p);
  virtual void do_oop(narrowOop* p);
  inline void do_oop_nv(oop* p)       { PushOrMarkClosure::do_oop_work(p); }
  inline void do_oop_nv(narrowOop* p) { PushOrMarkClosure::do_oop_work(p); }
  virtual const bool should_remember_klasses() const {
D
duke 已提交
272 273
    return _should_remember_klasses;
  }
274
  virtual void remember_klass(Klass* k);
D
duke 已提交
275 276 277 278 279 280 281 282 283 284 285
  // Deal with a stack overflow condition
  void handle_stack_overflow(HeapWord* lost);
 private:
  inline void do_yield_check();
};

// A parallel (MT) version of the above.
// This closure is used during the concurrent marking phase
// following the first checkpoint. Its use is buried in
// the closure Par_MarkFromRootsClosure.
class Par_PushOrMarkClosure: public OopClosure {
286
 private:
D
duke 已提交
287 288 289 290 291 292 293 294 295
  CMSCollector*    _collector;
  MemRegion        _whole_span;
  MemRegion        _span;        // local chunk
  CMSBitMap*       _bit_map;
  OopTaskQueue*    _work_queue;
  CMSMarkStack*    _overflow_stack;
  CMSMarkStack*    _revisit_stack;
  HeapWord*  const _finger;
  HeapWord** const _global_finger_addr;
296 297 298 299 300
  Par_MarkFromRootsClosure* const
                   _parent;
  bool const       _should_remember_klasses;
 protected:
  DO_OOP_WORK_DEFN
D
duke 已提交
301 302
 public:
  Par_PushOrMarkClosure(CMSCollector* cms_collector,
303 304 305 306 307 308 309 310 311 312 313 314 315
                        MemRegion span,
                        CMSBitMap* bit_map,
                        OopTaskQueue* work_queue,
                        CMSMarkStack* mark_stack,
                        CMSMarkStack* revisit_stack,
                        HeapWord* finger,
                        HeapWord** global_finger_addr,
                        Par_MarkFromRootsClosure* parent);
  virtual void do_oop(oop* p);
  virtual void do_oop(narrowOop* p);
  inline void do_oop_nv(oop* p)       { Par_PushOrMarkClosure::do_oop_work(p); }
  inline void do_oop_nv(narrowOop* p) { Par_PushOrMarkClosure::do_oop_work(p); }
  virtual const bool should_remember_klasses() const {
D
duke 已提交
316 317
    return _should_remember_klasses;
  }
318
  virtual void remember_klass(Klass* k);
D
duke 已提交
319 320 321 322 323 324 325 326 327 328 329
  // Deal with a stack overflow condition
  void handle_stack_overflow(HeapWord* lost);
 private:
  inline void do_yield_check();
};

// For objects in CMS generation, this closure marks
// given objects (transitively) as being reachable/live.
// This is currently used during the (weak) reference object
// processing phase of the CMS final checkpoint step.
class CMSKeepAliveClosure: public OopClosure {
330
 private:
D
duke 已提交
331 332 333 334
  CMSCollector* _collector;
  MemRegion     _span;
  CMSMarkStack* _mark_stack;
  CMSBitMap*    _bit_map;
335 336
 protected:
  DO_OOP_WORK_DEFN
D
duke 已提交
337 338 339 340 341 342 343
 public:
  CMSKeepAliveClosure(CMSCollector* collector, MemRegion span,
                      CMSBitMap* bit_map, CMSMarkStack* mark_stack):
    _collector(collector),
    _span(span),
    _bit_map(bit_map),
    _mark_stack(mark_stack) { }
344 345 346 347
  virtual void do_oop(oop* p);
  virtual void do_oop(narrowOop* p);
  inline void do_oop_nv(oop* p)       { CMSKeepAliveClosure::do_oop_work(p); }
  inline void do_oop_nv(narrowOop* p) { CMSKeepAliveClosure::do_oop_work(p); }
D
duke 已提交
348 349 350
};

class CMSInnerParMarkAndPushClosure: public OopClosure {
351
 private:
D
duke 已提交
352 353 354 355
  CMSCollector* _collector;
  MemRegion     _span;
  OopTaskQueue* _work_queue;
  CMSBitMap*    _bit_map;
356 357
 protected:
  DO_OOP_WORK_DEFN
D
duke 已提交
358 359 360 361 362 363 364 365
 public:
  CMSInnerParMarkAndPushClosure(CMSCollector* collector,
                                MemRegion span, CMSBitMap* bit_map,
                                OopTaskQueue* work_queue):
    _collector(collector),
    _span(span),
    _bit_map(bit_map),
    _work_queue(work_queue) { }
366 367 368 369
  virtual void do_oop(oop* p);
  virtual void do_oop(narrowOop* p);
  inline void do_oop_nv(oop* p)       { CMSInnerParMarkAndPushClosure::do_oop_work(p); }
  inline void do_oop_nv(narrowOop* p) { CMSInnerParMarkAndPushClosure::do_oop_work(p); }
D
duke 已提交
370 371 372 373 374 375
};

// A parallel (MT) version of the above, used when
// reference processing is parallel; the only difference
// is in the do_oop method.
class CMSParKeepAliveClosure: public OopClosure {
376
 private:
D
duke 已提交
377 378 379 380
  CMSCollector* _collector;
  MemRegion     _span;
  OopTaskQueue* _work_queue;
  CMSBitMap*    _bit_map;
381 382
  CMSInnerParMarkAndPushClosure
                _mark_and_push;
D
duke 已提交
383 384
  const uint    _low_water_mark;
  void trim_queue(uint max);
385 386
 protected:
  DO_OOP_WORK_DEFN
D
duke 已提交
387 388 389
 public:
  CMSParKeepAliveClosure(CMSCollector* collector, MemRegion span,
                         CMSBitMap* bit_map, OopTaskQueue* work_queue);
390 391 392 393
  virtual void do_oop(oop* p);
  virtual void do_oop(narrowOop* p);
  inline void do_oop_nv(oop* p)       { CMSParKeepAliveClosure::do_oop_work(p); }
  inline void do_oop_nv(narrowOop* p) { CMSParKeepAliveClosure::do_oop_work(p); }
D
duke 已提交
394
};