src/share/vm/gc_implementation/concurrentMarkSweep/cmsOopClosures.hpp

changeset 0
f90c822e73f8
child 6876
710a3c8b516e
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/src/share/vm/gc_implementation/concurrentMarkSweep/cmsOopClosures.hpp	Wed Apr 27 01:25:04 2016 +0800
     1.3 @@ -0,0 +1,426 @@
     1.4 +/*
     1.5 + * Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved.
     1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     1.7 + *
     1.8 + * This code is free software; you can redistribute it and/or modify it
     1.9 + * under the terms of the GNU General Public License version 2 only, as
    1.10 + * published by the Free Software Foundation.
    1.11 + *
    1.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
    1.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    1.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    1.15 + * version 2 for more details (a copy is included in the LICENSE file that
    1.16 + * accompanied this code).
    1.17 + *
    1.18 + * You should have received a copy of the GNU General Public License version
    1.19 + * 2 along with this work; if not, write to the Free Software Foundation,
    1.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    1.21 + *
    1.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    1.23 + * or visit www.oracle.com if you need additional information or have any
    1.24 + * questions.
    1.25 + *
    1.26 + */
    1.27 +
    1.28 +#ifndef SHARE_VM_GC_IMPLEMENTATION_CONCURRENTMARKSWEEP_CMSOOPCLOSURES_HPP
    1.29 +#define SHARE_VM_GC_IMPLEMENTATION_CONCURRENTMARKSWEEP_CMSOOPCLOSURES_HPP
    1.30 +
    1.31 +#include "memory/genOopClosures.hpp"
    1.32 +
    1.33 +/////////////////////////////////////////////////////////////////
    1.34 +// Closures used by ConcurrentMarkSweepGeneration's collector
    1.35 +/////////////////////////////////////////////////////////////////
    1.36 +class ConcurrentMarkSweepGeneration;
    1.37 +class CMSBitMap;
    1.38 +class CMSMarkStack;
    1.39 +class CMSCollector;
    1.40 +class MarkFromRootsClosure;
    1.41 +class Par_MarkFromRootsClosure;
    1.42 +
    1.43 +// Decode the oop and call do_oop on it.
    1.44 +#define DO_OOP_WORK_DEFN \
    1.45 +  void do_oop(oop obj);                                   \
    1.46 +  template <class T> inline void do_oop_work(T* p) {      \
    1.47 +    T heap_oop = oopDesc::load_heap_oop(p);               \
    1.48 +    if (!oopDesc::is_null(heap_oop)) {                    \
    1.49 +      oop obj = oopDesc::decode_heap_oop_not_null(heap_oop);       \
    1.50 +      do_oop(obj);                                        \
    1.51 +    }                                                     \
    1.52 +  }
    1.53 +
    1.54 +// Applies the given oop closure to all oops in all klasses visited.
    1.55 +class CMKlassClosure : public KlassClosure {
    1.56 +  friend class CMSOopClosure;
    1.57 +  friend class CMSOopsInGenClosure;
    1.58 +
    1.59 +  OopClosure* _oop_closure;
    1.60 +
    1.61 +  // Used when _oop_closure couldn't be set in an initialization list.
    1.62 +  void initialize(OopClosure* oop_closure) {
    1.63 +    assert(_oop_closure == NULL, "Should only be called once");
    1.64 +    _oop_closure = oop_closure;
    1.65 +  }
    1.66 + public:
    1.67 +  CMKlassClosure(OopClosure* oop_closure = NULL) : _oop_closure(oop_closure) { }
    1.68 +
    1.69 +  void do_klass(Klass* k);
    1.70 +};
    1.71 +
    1.72 +// The base class for all CMS marking closures.
    1.73 +// It's used to proxy through the metadata to the oops defined in them.
    1.74 +class CMSOopClosure: public ExtendedOopClosure {
    1.75 +  CMKlassClosure      _klass_closure;
    1.76 + public:
    1.77 +  CMSOopClosure() : ExtendedOopClosure() {
    1.78 +    _klass_closure.initialize(this);
    1.79 +  }
    1.80 +  CMSOopClosure(ReferenceProcessor* rp) : ExtendedOopClosure(rp) {
    1.81 +    _klass_closure.initialize(this);
    1.82 +  }
    1.83 +
    1.84 +  virtual bool do_metadata()    { return do_metadata_nv(); }
    1.85 +  inline  bool do_metadata_nv() { return true; }
    1.86 +
    1.87 +  virtual void do_klass(Klass* k);
    1.88 +  void do_klass_nv(Klass* k);
    1.89 +
    1.90 +  virtual void do_class_loader_data(ClassLoaderData* cld);
    1.91 +};
    1.92 +
    1.93 +// TODO: This duplication of the CMSOopClosure class is only needed because
    1.94 +//       some CMS OopClosures derive from OopsInGenClosure. It would be good
    1.95 +//       to get rid of them completely.
    1.96 +class CMSOopsInGenClosure: public OopsInGenClosure {
    1.97 +  CMKlassClosure _klass_closure;
    1.98 + public:
    1.99 +  CMSOopsInGenClosure() {
   1.100 +    _klass_closure.initialize(this);
   1.101 +  }
   1.102 +
   1.103 +  virtual bool do_metadata()    { return do_metadata_nv(); }
   1.104 +  inline  bool do_metadata_nv() { return true; }
   1.105 +
   1.106 +  virtual void do_klass(Klass* k);
   1.107 +  void do_klass_nv(Klass* k);
   1.108 +
   1.109 +  virtual void do_class_loader_data(ClassLoaderData* cld);
   1.110 +};
   1.111 +
   1.112 +class MarkRefsIntoClosure: public CMSOopsInGenClosure {
   1.113 + private:
   1.114 +  const MemRegion _span;
   1.115 +  CMSBitMap*      _bitMap;
   1.116 + protected:
   1.117 +  DO_OOP_WORK_DEFN
   1.118 + public:
   1.119 +  MarkRefsIntoClosure(MemRegion span, CMSBitMap* bitMap);
   1.120 +  virtual void do_oop(oop* p);
   1.121 +  virtual void do_oop(narrowOop* p);
   1.122 +
   1.123 +  Prefetch::style prefetch_style() {
   1.124 +    return Prefetch::do_read;
   1.125 +  }
   1.126 +};
   1.127 +
   1.128 +class Par_MarkRefsIntoClosure: public CMSOopsInGenClosure {
   1.129 + private:
   1.130 +  const MemRegion _span;
   1.131 +  CMSBitMap*      _bitMap;
   1.132 + protected:
   1.133 +  DO_OOP_WORK_DEFN
   1.134 + public:
   1.135 +  Par_MarkRefsIntoClosure(MemRegion span, CMSBitMap* bitMap);
   1.136 +  virtual void do_oop(oop* p);
   1.137 +  virtual void do_oop(narrowOop* p);
   1.138 +
   1.139 +  Prefetch::style prefetch_style() {
   1.140 +    return Prefetch::do_read;
   1.141 +  }
   1.142 +};
   1.143 +
   1.144 +// A variant of the above used in certain kinds of CMS
   1.145 +// marking verification.
   1.146 +class MarkRefsIntoVerifyClosure: public CMSOopsInGenClosure {
   1.147 + private:
   1.148 +  const MemRegion _span;
   1.149 +  CMSBitMap*      _verification_bm;
   1.150 +  CMSBitMap*      _cms_bm;
   1.151 + protected:
   1.152 +  DO_OOP_WORK_DEFN
   1.153 + public:
   1.154 +  MarkRefsIntoVerifyClosure(MemRegion span, CMSBitMap* verification_bm,
   1.155 +                            CMSBitMap* cms_bm);
   1.156 +  virtual void do_oop(oop* p);
   1.157 +  virtual void do_oop(narrowOop* p);
   1.158 +
   1.159 +  Prefetch::style prefetch_style() {
   1.160 +    return Prefetch::do_read;
   1.161 +  }
   1.162 +};
   1.163 +
   1.164 +// The non-parallel version (the parallel version appears further below).
   1.165 +class PushAndMarkClosure: public CMSOopClosure {
   1.166 + private:
   1.167 +  CMSCollector* _collector;
   1.168 +  MemRegion     _span;
   1.169 +  CMSBitMap*    _bit_map;
   1.170 +  CMSBitMap*    _mod_union_table;
   1.171 +  CMSMarkStack* _mark_stack;
   1.172 +  bool          _concurrent_precleaning;
   1.173 + protected:
   1.174 +  DO_OOP_WORK_DEFN
   1.175 + public:
   1.176 +  PushAndMarkClosure(CMSCollector* collector,
   1.177 +                     MemRegion span,
   1.178 +                     ReferenceProcessor* rp,
   1.179 +                     CMSBitMap* bit_map,
   1.180 +                     CMSBitMap* mod_union_table,
   1.181 +                     CMSMarkStack* mark_stack,
   1.182 +                     bool concurrent_precleaning);
   1.183 +  virtual void do_oop(oop* p);
   1.184 +  virtual void do_oop(narrowOop* p);
   1.185 +  inline void do_oop_nv(oop* p)       { PushAndMarkClosure::do_oop_work(p); }
   1.186 +  inline void do_oop_nv(narrowOop* p) { PushAndMarkClosure::do_oop_work(p); }
   1.187 +
   1.188 +  Prefetch::style prefetch_style() {
   1.189 +    return Prefetch::do_read;
   1.190 +  }
   1.191 +};
   1.192 +
   1.193 +// In the parallel case, the bit map and the
   1.194 +// reference processor are currently all shared. Access to
   1.195 +// these shared mutable structures must use appropriate
   1.196 +// synchronization (for instance, via CAS). The marking stack
   1.197 +// used in the non-parallel case above is here replaced with
   1.198 +// an OopTaskQueue structure to allow efficient work stealing.
   1.199 +class Par_PushAndMarkClosure: public CMSOopClosure {
   1.200 + private:
   1.201 +  CMSCollector* _collector;
   1.202 +  MemRegion     _span;
   1.203 +  CMSBitMap*    _bit_map;
   1.204 +  OopTaskQueue* _work_queue;
   1.205 + protected:
   1.206 +  DO_OOP_WORK_DEFN
   1.207 + public:
   1.208 +  Par_PushAndMarkClosure(CMSCollector* collector,
   1.209 +                         MemRegion span,
   1.210 +                         ReferenceProcessor* rp,
   1.211 +                         CMSBitMap* bit_map,
   1.212 +                         OopTaskQueue* work_queue);
   1.213 +  virtual void do_oop(oop* p);
   1.214 +  virtual void do_oop(narrowOop* p);
   1.215 +  inline void do_oop_nv(oop* p)       { Par_PushAndMarkClosure::do_oop_work(p); }
   1.216 +  inline void do_oop_nv(narrowOop* p) { Par_PushAndMarkClosure::do_oop_work(p); }
   1.217 +
   1.218 +  Prefetch::style prefetch_style() {
   1.219 +    return Prefetch::do_read;
   1.220 +  }
   1.221 +};
   1.222 +
   1.223 +// The non-parallel version (the parallel version appears further below).
   1.224 +class MarkRefsIntoAndScanClosure: public CMSOopsInGenClosure {
   1.225 + private:
   1.226 +  MemRegion          _span;
   1.227 +  CMSBitMap*         _bit_map;
   1.228 +  CMSMarkStack*      _mark_stack;
   1.229 +  PushAndMarkClosure _pushAndMarkClosure;
   1.230 +  CMSCollector*      _collector;
   1.231 +  Mutex*             _freelistLock;
   1.232 +  bool               _yield;
   1.233 +  // Whether closure is being used for concurrent precleaning
   1.234 +  bool               _concurrent_precleaning;
   1.235 + protected:
   1.236 +  DO_OOP_WORK_DEFN
   1.237 + public:
   1.238 +  MarkRefsIntoAndScanClosure(MemRegion span,
   1.239 +                             ReferenceProcessor* rp,
   1.240 +                             CMSBitMap* bit_map,
   1.241 +                             CMSBitMap* mod_union_table,
   1.242 +                             CMSMarkStack* mark_stack,
   1.243 +                             CMSCollector* collector,
   1.244 +                             bool should_yield,
   1.245 +                             bool concurrent_precleaning);
   1.246 +  virtual void do_oop(oop* p);
   1.247 +  virtual void do_oop(narrowOop* p);
   1.248 +  inline void do_oop_nv(oop* p)       { MarkRefsIntoAndScanClosure::do_oop_work(p); }
   1.249 +  inline void do_oop_nv(narrowOop* p) { MarkRefsIntoAndScanClosure::do_oop_work(p); }
   1.250 +
   1.251 +  Prefetch::style prefetch_style() {
   1.252 +    return Prefetch::do_read;
   1.253 +  }
   1.254 +  void set_freelistLock(Mutex* m) {
   1.255 +    _freelistLock = m;
   1.256 +  }
   1.257 +
   1.258 + private:
   1.259 +  inline void do_yield_check();
   1.260 +  void do_yield_work();
   1.261 +  bool take_from_overflow_list();
   1.262 +};
   1.263 +
   1.264 +// Tn this, the parallel avatar of MarkRefsIntoAndScanClosure, the revisit
   1.265 +// stack and the bitMap are shared, so access needs to be suitably
   1.266 +// sycnhronized. An OopTaskQueue structure, supporting efficient
   1.267 +// workstealing, replaces a CMSMarkStack for storing grey objects.
   1.268 +class Par_MarkRefsIntoAndScanClosure: public CMSOopsInGenClosure {
   1.269 + private:
   1.270 +  MemRegion              _span;
   1.271 +  CMSBitMap*             _bit_map;
   1.272 +  OopTaskQueue*          _work_queue;
   1.273 +  const uint             _low_water_mark;
   1.274 +  Par_PushAndMarkClosure _par_pushAndMarkClosure;
   1.275 + protected:
   1.276 +  DO_OOP_WORK_DEFN
   1.277 + public:
   1.278 +  Par_MarkRefsIntoAndScanClosure(CMSCollector* collector,
   1.279 +                                 MemRegion span,
   1.280 +                                 ReferenceProcessor* rp,
   1.281 +                                 CMSBitMap* bit_map,
   1.282 +                                 OopTaskQueue* work_queue);
   1.283 +  virtual void do_oop(oop* p);
   1.284 +  virtual void do_oop(narrowOop* p);
   1.285 +  inline void do_oop_nv(oop* p)       { Par_MarkRefsIntoAndScanClosure::do_oop_work(p); }
   1.286 +  inline void do_oop_nv(narrowOop* p) { Par_MarkRefsIntoAndScanClosure::do_oop_work(p); }
   1.287 +
   1.288 +  Prefetch::style prefetch_style() {
   1.289 +    return Prefetch::do_read;
   1.290 +  }
   1.291 +  void trim_queue(uint size);
   1.292 +};
   1.293 +
   1.294 +// This closure is used during the concurrent marking phase
   1.295 +// following the first checkpoint. Its use is buried in
   1.296 +// the closure MarkFromRootsClosure.
   1.297 +class PushOrMarkClosure: public CMSOopClosure {
   1.298 + private:
   1.299 +  CMSCollector*   _collector;
   1.300 +  MemRegion       _span;
   1.301 +  CMSBitMap*      _bitMap;
   1.302 +  CMSMarkStack*   _markStack;
   1.303 +  HeapWord* const _finger;
   1.304 +  MarkFromRootsClosure* const
   1.305 +                  _parent;
   1.306 + protected:
   1.307 +  DO_OOP_WORK_DEFN
   1.308 + public:
   1.309 +  PushOrMarkClosure(CMSCollector* cms_collector,
   1.310 +                    MemRegion span,
   1.311 +                    CMSBitMap* bitMap,
   1.312 +                    CMSMarkStack* markStack,
   1.313 +                    HeapWord* finger,
   1.314 +                    MarkFromRootsClosure* parent);
   1.315 +  virtual void do_oop(oop* p);
   1.316 +  virtual void do_oop(narrowOop* p);
   1.317 +  inline void do_oop_nv(oop* p)       { PushOrMarkClosure::do_oop_work(p); }
   1.318 +  inline void do_oop_nv(narrowOop* p) { PushOrMarkClosure::do_oop_work(p); }
   1.319 +
   1.320 +  // Deal with a stack overflow condition
   1.321 +  void handle_stack_overflow(HeapWord* lost);
   1.322 + private:
   1.323 +  inline void do_yield_check();
   1.324 +};
   1.325 +
   1.326 +// A parallel (MT) version of the above.
   1.327 +// This closure is used during the concurrent marking phase
   1.328 +// following the first checkpoint. Its use is buried in
   1.329 +// the closure Par_MarkFromRootsClosure.
   1.330 +class Par_PushOrMarkClosure: public CMSOopClosure {
   1.331 + private:
   1.332 +  CMSCollector*    _collector;
   1.333 +  MemRegion        _whole_span;
   1.334 +  MemRegion        _span;        // local chunk
   1.335 +  CMSBitMap*       _bit_map;
   1.336 +  OopTaskQueue*    _work_queue;
   1.337 +  CMSMarkStack*    _overflow_stack;
   1.338 +  HeapWord*  const _finger;
   1.339 +  HeapWord** const _global_finger_addr;
   1.340 +  Par_MarkFromRootsClosure* const
   1.341 +                   _parent;
   1.342 + protected:
   1.343 +  DO_OOP_WORK_DEFN
   1.344 + public:
   1.345 +  Par_PushOrMarkClosure(CMSCollector* cms_collector,
   1.346 +                        MemRegion span,
   1.347 +                        CMSBitMap* bit_map,
   1.348 +                        OopTaskQueue* work_queue,
   1.349 +                        CMSMarkStack* mark_stack,
   1.350 +                        HeapWord* finger,
   1.351 +                        HeapWord** global_finger_addr,
   1.352 +                        Par_MarkFromRootsClosure* parent);
   1.353 +  virtual void do_oop(oop* p);
   1.354 +  virtual void do_oop(narrowOop* p);
   1.355 +  inline void do_oop_nv(oop* p)       { Par_PushOrMarkClosure::do_oop_work(p); }
   1.356 +  inline void do_oop_nv(narrowOop* p) { Par_PushOrMarkClosure::do_oop_work(p); }
   1.357 +
   1.358 +  // Deal with a stack overflow condition
   1.359 +  void handle_stack_overflow(HeapWord* lost);
   1.360 + private:
   1.361 +  inline void do_yield_check();
   1.362 +};
   1.363 +
   1.364 +// For objects in CMS generation, this closure marks
   1.365 +// given objects (transitively) as being reachable/live.
   1.366 +// This is currently used during the (weak) reference object
   1.367 +// processing phase of the CMS final checkpoint step, as
   1.368 +// well as during the concurrent precleaning of the discovered
   1.369 +// reference lists.
   1.370 +class CMSKeepAliveClosure: public CMSOopClosure {
   1.371 + private:
   1.372 +  CMSCollector* _collector;
   1.373 +  const MemRegion _span;
   1.374 +  CMSMarkStack* _mark_stack;
   1.375 +  CMSBitMap*    _bit_map;
   1.376 +  bool          _concurrent_precleaning;
   1.377 + protected:
   1.378 +  DO_OOP_WORK_DEFN
   1.379 + public:
   1.380 +  CMSKeepAliveClosure(CMSCollector* collector, MemRegion span,
   1.381 +                      CMSBitMap* bit_map, CMSMarkStack* mark_stack,
   1.382 +                      bool cpc);
   1.383 +  bool    concurrent_precleaning() const { return _concurrent_precleaning; }
   1.384 +  virtual void do_oop(oop* p);
   1.385 +  virtual void do_oop(narrowOop* p);
   1.386 +  inline void do_oop_nv(oop* p)       { CMSKeepAliveClosure::do_oop_work(p); }
   1.387 +  inline void do_oop_nv(narrowOop* p) { CMSKeepAliveClosure::do_oop_work(p); }
   1.388 +};
   1.389 +
   1.390 +class CMSInnerParMarkAndPushClosure: public CMSOopClosure {
   1.391 + private:
   1.392 +  CMSCollector* _collector;
   1.393 +  MemRegion     _span;
   1.394 +  OopTaskQueue* _work_queue;
   1.395 +  CMSBitMap*    _bit_map;
   1.396 + protected:
   1.397 +  DO_OOP_WORK_DEFN
   1.398 + public:
   1.399 +  CMSInnerParMarkAndPushClosure(CMSCollector* collector,
   1.400 +                                MemRegion span, CMSBitMap* bit_map,
   1.401 +                                OopTaskQueue* work_queue);
   1.402 +  virtual void do_oop(oop* p);
   1.403 +  virtual void do_oop(narrowOop* p);
   1.404 +  inline void do_oop_nv(oop* p)       { CMSInnerParMarkAndPushClosure::do_oop_work(p); }
   1.405 +  inline void do_oop_nv(narrowOop* p) { CMSInnerParMarkAndPushClosure::do_oop_work(p); }
   1.406 +};
   1.407 +
   1.408 +// A parallel (MT) version of the above, used when
   1.409 +// reference processing is parallel; the only difference
   1.410 +// is in the do_oop method.
   1.411 +class CMSParKeepAliveClosure: public CMSOopClosure {
   1.412 + private:
   1.413 +  MemRegion     _span;
   1.414 +  OopTaskQueue* _work_queue;
   1.415 +  CMSBitMap*    _bit_map;
   1.416 +  CMSInnerParMarkAndPushClosure
   1.417 +                _mark_and_push;
   1.418 +  const uint    _low_water_mark;
   1.419 +  void trim_queue(uint max);
   1.420 + protected:
   1.421 +  DO_OOP_WORK_DEFN
   1.422 + public:
   1.423 +  CMSParKeepAliveClosure(CMSCollector* collector, MemRegion span,
   1.424 +                         CMSBitMap* bit_map, OopTaskQueue* work_queue);
   1.425 +  virtual void do_oop(oop* p);
   1.426 +  virtual void do_oop(narrowOop* p);
   1.427 +};
   1.428 +
   1.429 +#endif // SHARE_VM_GC_IMPLEMENTATION_CONCURRENTMARKSWEEP_CMSOOPCLOSURES_HPP

mercurial