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

Tue, 15 Sep 2009 21:53:47 -0700

author
jrose
date
Tue, 15 Sep 2009 21:53:47 -0700
changeset 1424
148e5441d916
parent 887
00b023ae2d78
child 1428
54b3b351d6f9
permissions
-rw-r--r--

6863023: need non-perm oops in code cache for JSR 292
Summary: Make a special root-list for those few nmethods which might contain non-perm oops.
Reviewed-by: twisti, kvn, never, jmasa, ysr

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

mercurial