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

Thu, 12 Oct 2017 21:27:07 +0800

author
aoqi
date
Thu, 12 Oct 2017 21:27:07 +0800
changeset 7535
7ae4e26cb1e0
parent 6982
4c1b88a53c74
parent 6876
710a3c8b516e
permissions
-rw-r--r--

merge

aoqi@0 1 /*
aoqi@0 2 * Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved.
aoqi@0 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
aoqi@0 4 *
aoqi@0 5 * This code is free software; you can redistribute it and/or modify it
aoqi@0 6 * under the terms of the GNU General Public License version 2 only, as
aoqi@0 7 * published by the Free Software Foundation.
aoqi@0 8 *
aoqi@0 9 * This code is distributed in the hope that it will be useful, but WITHOUT
aoqi@0 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
aoqi@0 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
aoqi@0 12 * version 2 for more details (a copy is included in the LICENSE file that
aoqi@0 13 * accompanied this code).
aoqi@0 14 *
aoqi@0 15 * You should have received a copy of the GNU General Public License version
aoqi@0 16 * 2 along with this work; if not, write to the Free Software Foundation,
aoqi@0 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
aoqi@0 18 *
aoqi@0 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
aoqi@0 20 * or visit www.oracle.com if you need additional information or have any
aoqi@0 21 * questions.
aoqi@0 22 *
aoqi@0 23 */
aoqi@0 24
aoqi@0 25 #ifndef SHARE_VM_GC_IMPLEMENTATION_CONCURRENTMARKSWEEP_CMSOOPCLOSURES_HPP
aoqi@0 26 #define SHARE_VM_GC_IMPLEMENTATION_CONCURRENTMARKSWEEP_CMSOOPCLOSURES_HPP
aoqi@0 27
aoqi@0 28 #include "memory/genOopClosures.hpp"
stefank@6982 29 #include "memory/iterator.hpp"
aoqi@0 30
aoqi@0 31 /////////////////////////////////////////////////////////////////
aoqi@0 32 // Closures used by ConcurrentMarkSweepGeneration's collector
aoqi@0 33 /////////////////////////////////////////////////////////////////
aoqi@0 34 class ConcurrentMarkSweepGeneration;
aoqi@0 35 class CMSBitMap;
aoqi@0 36 class CMSMarkStack;
aoqi@0 37 class CMSCollector;
aoqi@0 38 class MarkFromRootsClosure;
aoqi@0 39 class Par_MarkFromRootsClosure;
aoqi@0 40
aoqi@0 41 // Decode the oop and call do_oop on it.
aoqi@0 42 #define DO_OOP_WORK_DEFN \
aoqi@0 43 void do_oop(oop obj); \
aoqi@0 44 template <class T> inline void do_oop_work(T* p) { \
aoqi@0 45 T heap_oop = oopDesc::load_heap_oop(p); \
aoqi@0 46 if (!oopDesc::is_null(heap_oop)) { \
aoqi@0 47 oop obj = oopDesc::decode_heap_oop_not_null(heap_oop); \
aoqi@0 48 do_oop(obj); \
aoqi@0 49 } \
aoqi@0 50 }
aoqi@0 51
stefank@6982 52 // TODO: This duplication of the MetadataAwareOopClosure class is only needed
stefank@6982 53 // because some CMS OopClosures derive from OopsInGenClosure. It would be
stefank@6982 54 // good to get rid of them completely.
stefank@6982 55 class MetadataAwareOopsInGenClosure: public OopsInGenClosure {
stefank@6982 56 KlassToOopClosure _klass_closure;
aoqi@0 57 public:
stefank@6982 58 MetadataAwareOopsInGenClosure() {
aoqi@0 59 _klass_closure.initialize(this);
aoqi@0 60 }
aoqi@0 61
aoqi@0 62 virtual bool do_metadata() { return do_metadata_nv(); }
aoqi@0 63 inline bool do_metadata_nv() { return true; }
aoqi@0 64
aoqi@0 65 virtual void do_klass(Klass* k);
aoqi@0 66 void do_klass_nv(Klass* k);
aoqi@0 67
aoqi@0 68 virtual void do_class_loader_data(ClassLoaderData* cld);
aoqi@0 69 };
aoqi@0 70
stefank@6982 71 class MarkRefsIntoClosure: public MetadataAwareOopsInGenClosure {
aoqi@0 72 private:
aoqi@0 73 const MemRegion _span;
aoqi@0 74 CMSBitMap* _bitMap;
aoqi@0 75 protected:
aoqi@0 76 DO_OOP_WORK_DEFN
aoqi@0 77 public:
aoqi@0 78 MarkRefsIntoClosure(MemRegion span, CMSBitMap* bitMap);
aoqi@0 79 virtual void do_oop(oop* p);
aoqi@0 80 virtual void do_oop(narrowOop* p);
aoqi@0 81
aoqi@0 82 Prefetch::style prefetch_style() {
aoqi@0 83 return Prefetch::do_read;
aoqi@0 84 }
aoqi@0 85 };
aoqi@0 86
stefank@6982 87 class Par_MarkRefsIntoClosure: public MetadataAwareOopsInGenClosure {
aoqi@0 88 private:
aoqi@0 89 const MemRegion _span;
aoqi@0 90 CMSBitMap* _bitMap;
aoqi@0 91 protected:
aoqi@0 92 DO_OOP_WORK_DEFN
aoqi@0 93 public:
aoqi@0 94 Par_MarkRefsIntoClosure(MemRegion span, CMSBitMap* bitMap);
aoqi@0 95 virtual void do_oop(oop* p);
aoqi@0 96 virtual void do_oop(narrowOop* p);
aoqi@0 97
aoqi@0 98 Prefetch::style prefetch_style() {
aoqi@0 99 return Prefetch::do_read;
aoqi@0 100 }
aoqi@0 101 };
aoqi@0 102
aoqi@0 103 // A variant of the above used in certain kinds of CMS
aoqi@0 104 // marking verification.
stefank@6982 105 class MarkRefsIntoVerifyClosure: public MetadataAwareOopsInGenClosure {
aoqi@0 106 private:
aoqi@0 107 const MemRegion _span;
aoqi@0 108 CMSBitMap* _verification_bm;
aoqi@0 109 CMSBitMap* _cms_bm;
aoqi@0 110 protected:
aoqi@0 111 DO_OOP_WORK_DEFN
aoqi@0 112 public:
aoqi@0 113 MarkRefsIntoVerifyClosure(MemRegion span, CMSBitMap* verification_bm,
aoqi@0 114 CMSBitMap* cms_bm);
aoqi@0 115 virtual void do_oop(oop* p);
aoqi@0 116 virtual void do_oop(narrowOop* p);
aoqi@0 117
aoqi@0 118 Prefetch::style prefetch_style() {
aoqi@0 119 return Prefetch::do_read;
aoqi@0 120 }
aoqi@0 121 };
aoqi@0 122
aoqi@0 123 // The non-parallel version (the parallel version appears further below).
stefank@6982 124 class PushAndMarkClosure: public MetadataAwareOopClosure {
aoqi@0 125 private:
aoqi@0 126 CMSCollector* _collector;
aoqi@0 127 MemRegion _span;
aoqi@0 128 CMSBitMap* _bit_map;
aoqi@0 129 CMSBitMap* _mod_union_table;
aoqi@0 130 CMSMarkStack* _mark_stack;
aoqi@0 131 bool _concurrent_precleaning;
aoqi@0 132 protected:
aoqi@0 133 DO_OOP_WORK_DEFN
aoqi@0 134 public:
aoqi@0 135 PushAndMarkClosure(CMSCollector* collector,
aoqi@0 136 MemRegion span,
aoqi@0 137 ReferenceProcessor* rp,
aoqi@0 138 CMSBitMap* bit_map,
aoqi@0 139 CMSBitMap* mod_union_table,
aoqi@0 140 CMSMarkStack* mark_stack,
aoqi@0 141 bool concurrent_precleaning);
aoqi@0 142 virtual void do_oop(oop* p);
aoqi@0 143 virtual void do_oop(narrowOop* p);
aoqi@0 144 inline void do_oop_nv(oop* p) { PushAndMarkClosure::do_oop_work(p); }
aoqi@0 145 inline void do_oop_nv(narrowOop* p) { PushAndMarkClosure::do_oop_work(p); }
aoqi@0 146
aoqi@0 147 Prefetch::style prefetch_style() {
aoqi@0 148 return Prefetch::do_read;
aoqi@0 149 }
aoqi@0 150 };
aoqi@0 151
aoqi@0 152 // In the parallel case, the bit map and the
aoqi@0 153 // reference processor are currently all shared. Access to
aoqi@0 154 // these shared mutable structures must use appropriate
aoqi@0 155 // synchronization (for instance, via CAS). The marking stack
aoqi@0 156 // used in the non-parallel case above is here replaced with
aoqi@0 157 // an OopTaskQueue structure to allow efficient work stealing.
stefank@6982 158 class Par_PushAndMarkClosure: public MetadataAwareOopClosure {
aoqi@0 159 private:
aoqi@0 160 CMSCollector* _collector;
aoqi@0 161 MemRegion _span;
aoqi@0 162 CMSBitMap* _bit_map;
aoqi@0 163 OopTaskQueue* _work_queue;
aoqi@0 164 protected:
aoqi@0 165 DO_OOP_WORK_DEFN
aoqi@0 166 public:
aoqi@0 167 Par_PushAndMarkClosure(CMSCollector* collector,
aoqi@0 168 MemRegion span,
aoqi@0 169 ReferenceProcessor* rp,
aoqi@0 170 CMSBitMap* bit_map,
aoqi@0 171 OopTaskQueue* work_queue);
aoqi@0 172 virtual void do_oop(oop* p);
aoqi@0 173 virtual void do_oop(narrowOop* p);
aoqi@0 174 inline void do_oop_nv(oop* p) { Par_PushAndMarkClosure::do_oop_work(p); }
aoqi@0 175 inline void do_oop_nv(narrowOop* p) { Par_PushAndMarkClosure::do_oop_work(p); }
aoqi@0 176
aoqi@0 177 Prefetch::style prefetch_style() {
aoqi@0 178 return Prefetch::do_read;
aoqi@0 179 }
aoqi@0 180 };
aoqi@0 181
aoqi@0 182 // The non-parallel version (the parallel version appears further below).
stefank@6982 183 class MarkRefsIntoAndScanClosure: public MetadataAwareOopsInGenClosure {
aoqi@0 184 private:
aoqi@0 185 MemRegion _span;
aoqi@0 186 CMSBitMap* _bit_map;
aoqi@0 187 CMSMarkStack* _mark_stack;
aoqi@0 188 PushAndMarkClosure _pushAndMarkClosure;
aoqi@0 189 CMSCollector* _collector;
aoqi@0 190 Mutex* _freelistLock;
aoqi@0 191 bool _yield;
aoqi@0 192 // Whether closure is being used for concurrent precleaning
aoqi@0 193 bool _concurrent_precleaning;
aoqi@0 194 protected:
aoqi@0 195 DO_OOP_WORK_DEFN
aoqi@0 196 public:
aoqi@0 197 MarkRefsIntoAndScanClosure(MemRegion span,
aoqi@0 198 ReferenceProcessor* rp,
aoqi@0 199 CMSBitMap* bit_map,
aoqi@0 200 CMSBitMap* mod_union_table,
aoqi@0 201 CMSMarkStack* mark_stack,
aoqi@0 202 CMSCollector* collector,
aoqi@0 203 bool should_yield,
aoqi@0 204 bool concurrent_precleaning);
aoqi@0 205 virtual void do_oop(oop* p);
aoqi@0 206 virtual void do_oop(narrowOop* p);
aoqi@0 207 inline void do_oop_nv(oop* p) { MarkRefsIntoAndScanClosure::do_oop_work(p); }
aoqi@0 208 inline void do_oop_nv(narrowOop* p) { MarkRefsIntoAndScanClosure::do_oop_work(p); }
aoqi@0 209
aoqi@0 210 Prefetch::style prefetch_style() {
aoqi@0 211 return Prefetch::do_read;
aoqi@0 212 }
aoqi@0 213 void set_freelistLock(Mutex* m) {
aoqi@0 214 _freelistLock = m;
aoqi@0 215 }
aoqi@0 216
aoqi@0 217 private:
aoqi@0 218 inline void do_yield_check();
aoqi@0 219 void do_yield_work();
aoqi@0 220 bool take_from_overflow_list();
aoqi@0 221 };
aoqi@0 222
aoqi@0 223 // Tn this, the parallel avatar of MarkRefsIntoAndScanClosure, the revisit
aoqi@0 224 // stack and the bitMap are shared, so access needs to be suitably
aoqi@0 225 // sycnhronized. An OopTaskQueue structure, supporting efficient
aoqi@0 226 // workstealing, replaces a CMSMarkStack for storing grey objects.
stefank@6982 227 class Par_MarkRefsIntoAndScanClosure: public MetadataAwareOopsInGenClosure {
aoqi@0 228 private:
aoqi@0 229 MemRegion _span;
aoqi@0 230 CMSBitMap* _bit_map;
aoqi@0 231 OopTaskQueue* _work_queue;
aoqi@0 232 const uint _low_water_mark;
aoqi@0 233 Par_PushAndMarkClosure _par_pushAndMarkClosure;
aoqi@0 234 protected:
aoqi@0 235 DO_OOP_WORK_DEFN
aoqi@0 236 public:
aoqi@0 237 Par_MarkRefsIntoAndScanClosure(CMSCollector* collector,
aoqi@0 238 MemRegion span,
aoqi@0 239 ReferenceProcessor* rp,
aoqi@0 240 CMSBitMap* bit_map,
aoqi@0 241 OopTaskQueue* work_queue);
aoqi@0 242 virtual void do_oop(oop* p);
aoqi@0 243 virtual void do_oop(narrowOop* p);
aoqi@0 244 inline void do_oop_nv(oop* p) { Par_MarkRefsIntoAndScanClosure::do_oop_work(p); }
aoqi@0 245 inline void do_oop_nv(narrowOop* p) { Par_MarkRefsIntoAndScanClosure::do_oop_work(p); }
aoqi@0 246
aoqi@0 247 Prefetch::style prefetch_style() {
aoqi@0 248 return Prefetch::do_read;
aoqi@0 249 }
aoqi@0 250 void trim_queue(uint size);
aoqi@0 251 };
aoqi@0 252
aoqi@0 253 // This closure is used during the concurrent marking phase
aoqi@0 254 // following the first checkpoint. Its use is buried in
aoqi@0 255 // the closure MarkFromRootsClosure.
stefank@6982 256 class PushOrMarkClosure: public MetadataAwareOopClosure {
aoqi@0 257 private:
aoqi@0 258 CMSCollector* _collector;
aoqi@0 259 MemRegion _span;
aoqi@0 260 CMSBitMap* _bitMap;
aoqi@0 261 CMSMarkStack* _markStack;
aoqi@0 262 HeapWord* const _finger;
aoqi@0 263 MarkFromRootsClosure* const
aoqi@0 264 _parent;
aoqi@0 265 protected:
aoqi@0 266 DO_OOP_WORK_DEFN
aoqi@0 267 public:
aoqi@0 268 PushOrMarkClosure(CMSCollector* cms_collector,
aoqi@0 269 MemRegion span,
aoqi@0 270 CMSBitMap* bitMap,
aoqi@0 271 CMSMarkStack* markStack,
aoqi@0 272 HeapWord* finger,
aoqi@0 273 MarkFromRootsClosure* parent);
aoqi@0 274 virtual void do_oop(oop* p);
aoqi@0 275 virtual void do_oop(narrowOop* p);
aoqi@0 276 inline void do_oop_nv(oop* p) { PushOrMarkClosure::do_oop_work(p); }
aoqi@0 277 inline void do_oop_nv(narrowOop* p) { PushOrMarkClosure::do_oop_work(p); }
aoqi@0 278
aoqi@0 279 // Deal with a stack overflow condition
aoqi@0 280 void handle_stack_overflow(HeapWord* lost);
aoqi@0 281 private:
aoqi@0 282 inline void do_yield_check();
aoqi@0 283 };
aoqi@0 284
aoqi@0 285 // A parallel (MT) version of the above.
aoqi@0 286 // This closure is used during the concurrent marking phase
aoqi@0 287 // following the first checkpoint. Its use is buried in
aoqi@0 288 // the closure Par_MarkFromRootsClosure.
stefank@6982 289 class Par_PushOrMarkClosure: public MetadataAwareOopClosure {
aoqi@0 290 private:
aoqi@0 291 CMSCollector* _collector;
aoqi@0 292 MemRegion _whole_span;
aoqi@0 293 MemRegion _span; // local chunk
aoqi@0 294 CMSBitMap* _bit_map;
aoqi@0 295 OopTaskQueue* _work_queue;
aoqi@0 296 CMSMarkStack* _overflow_stack;
aoqi@0 297 HeapWord* const _finger;
aoqi@0 298 HeapWord** const _global_finger_addr;
aoqi@0 299 Par_MarkFromRootsClosure* const
aoqi@0 300 _parent;
aoqi@0 301 protected:
aoqi@0 302 DO_OOP_WORK_DEFN
aoqi@0 303 public:
aoqi@0 304 Par_PushOrMarkClosure(CMSCollector* cms_collector,
aoqi@0 305 MemRegion span,
aoqi@0 306 CMSBitMap* bit_map,
aoqi@0 307 OopTaskQueue* work_queue,
aoqi@0 308 CMSMarkStack* mark_stack,
aoqi@0 309 HeapWord* finger,
aoqi@0 310 HeapWord** global_finger_addr,
aoqi@0 311 Par_MarkFromRootsClosure* parent);
aoqi@0 312 virtual void do_oop(oop* p);
aoqi@0 313 virtual void do_oop(narrowOop* p);
aoqi@0 314 inline void do_oop_nv(oop* p) { Par_PushOrMarkClosure::do_oop_work(p); }
aoqi@0 315 inline void do_oop_nv(narrowOop* p) { Par_PushOrMarkClosure::do_oop_work(p); }
aoqi@0 316
aoqi@0 317 // Deal with a stack overflow condition
aoqi@0 318 void handle_stack_overflow(HeapWord* lost);
aoqi@0 319 private:
aoqi@0 320 inline void do_yield_check();
aoqi@0 321 };
aoqi@0 322
aoqi@0 323 // For objects in CMS generation, this closure marks
aoqi@0 324 // given objects (transitively) as being reachable/live.
aoqi@0 325 // This is currently used during the (weak) reference object
aoqi@0 326 // processing phase of the CMS final checkpoint step, as
aoqi@0 327 // well as during the concurrent precleaning of the discovered
aoqi@0 328 // reference lists.
stefank@6982 329 class CMSKeepAliveClosure: public MetadataAwareOopClosure {
aoqi@0 330 private:
aoqi@0 331 CMSCollector* _collector;
aoqi@0 332 const MemRegion _span;
aoqi@0 333 CMSMarkStack* _mark_stack;
aoqi@0 334 CMSBitMap* _bit_map;
aoqi@0 335 bool _concurrent_precleaning;
aoqi@0 336 protected:
aoqi@0 337 DO_OOP_WORK_DEFN
aoqi@0 338 public:
aoqi@0 339 CMSKeepAliveClosure(CMSCollector* collector, MemRegion span,
aoqi@0 340 CMSBitMap* bit_map, CMSMarkStack* mark_stack,
aoqi@0 341 bool cpc);
aoqi@0 342 bool concurrent_precleaning() const { return _concurrent_precleaning; }
aoqi@0 343 virtual void do_oop(oop* p);
aoqi@0 344 virtual void do_oop(narrowOop* p);
aoqi@0 345 inline void do_oop_nv(oop* p) { CMSKeepAliveClosure::do_oop_work(p); }
aoqi@0 346 inline void do_oop_nv(narrowOop* p) { CMSKeepAliveClosure::do_oop_work(p); }
aoqi@0 347 };
aoqi@0 348
stefank@6982 349 class CMSInnerParMarkAndPushClosure: public MetadataAwareOopClosure {
aoqi@0 350 private:
aoqi@0 351 CMSCollector* _collector;
aoqi@0 352 MemRegion _span;
aoqi@0 353 OopTaskQueue* _work_queue;
aoqi@0 354 CMSBitMap* _bit_map;
aoqi@0 355 protected:
aoqi@0 356 DO_OOP_WORK_DEFN
aoqi@0 357 public:
aoqi@0 358 CMSInnerParMarkAndPushClosure(CMSCollector* collector,
aoqi@0 359 MemRegion span, CMSBitMap* bit_map,
aoqi@0 360 OopTaskQueue* work_queue);
aoqi@0 361 virtual void do_oop(oop* p);
aoqi@0 362 virtual void do_oop(narrowOop* p);
aoqi@0 363 inline void do_oop_nv(oop* p) { CMSInnerParMarkAndPushClosure::do_oop_work(p); }
aoqi@0 364 inline void do_oop_nv(narrowOop* p) { CMSInnerParMarkAndPushClosure::do_oop_work(p); }
aoqi@0 365 };
aoqi@0 366
aoqi@0 367 // A parallel (MT) version of the above, used when
aoqi@0 368 // reference processing is parallel; the only difference
aoqi@0 369 // is in the do_oop method.
stefank@6982 370 class CMSParKeepAliveClosure: public MetadataAwareOopClosure {
aoqi@0 371 private:
aoqi@0 372 MemRegion _span;
aoqi@0 373 OopTaskQueue* _work_queue;
aoqi@0 374 CMSBitMap* _bit_map;
aoqi@0 375 CMSInnerParMarkAndPushClosure
aoqi@0 376 _mark_and_push;
aoqi@0 377 const uint _low_water_mark;
aoqi@0 378 void trim_queue(uint max);
aoqi@0 379 protected:
aoqi@0 380 DO_OOP_WORK_DEFN
aoqi@0 381 public:
aoqi@0 382 CMSParKeepAliveClosure(CMSCollector* collector, MemRegion span,
aoqi@0 383 CMSBitMap* bit_map, OopTaskQueue* work_queue);
aoqi@0 384 virtual void do_oop(oop* p);
aoqi@0 385 virtual void do_oop(narrowOop* p);
aoqi@0 386 };
aoqi@0 387
aoqi@0 388 #endif // SHARE_VM_GC_IMPLEMENTATION_CONCURRENTMARKSWEEP_CMSOOPCLOSURES_HPP

mercurial