src/share/vm/gc_implementation/g1/g1MarkSweep.cpp

Sat, 06 Oct 2012 01:17:44 -0700

author
johnc
date
Sat, 06 Oct 2012 01:17:44 -0700
changeset 4173
8a5ea0a9ccc4
parent 4098
8966c2d65d96
child 4384
b735136e0d82
permissions
-rw-r--r--

7127708: G1: change task num types from int to uint in concurrent mark
Summary: Change the type of various task num fields, parameters etc to unsigned and rename them to be more consistent with the other collectors. Code changes were also reviewed by Vitaly Davidovich.
Reviewed-by: johnc
Contributed-by: Kaushik Srenevasan <kaushik@twitter.com>

ysr@777 1 /*
never@3499 2 * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
ysr@777 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
ysr@777 4 *
ysr@777 5 * This code is free software; you can redistribute it and/or modify it
ysr@777 6 * under the terms of the GNU General Public License version 2 only, as
ysr@777 7 * published by the Free Software Foundation.
ysr@777 8 *
ysr@777 9 * This code is distributed in the hope that it will be useful, but WITHOUT
ysr@777 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
ysr@777 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
ysr@777 12 * version 2 for more details (a copy is included in the LICENSE file that
ysr@777 13 * accompanied this code).
ysr@777 14 *
ysr@777 15 * You should have received a copy of the GNU General Public License version
ysr@777 16 * 2 along with this work; if not, write to the Free Software Foundation,
ysr@777 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
ysr@777 18 *
trims@1907 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
trims@1907 20 * or visit www.oracle.com if you need additional information or have any
trims@1907 21 * questions.
ysr@777 22 *
ysr@777 23 */
ysr@777 24
stefank@2314 25 #include "precompiled.hpp"
stefank@2314 26 #include "classfile/javaClasses.hpp"
stefank@2314 27 #include "classfile/symbolTable.hpp"
stefank@2314 28 #include "classfile/systemDictionary.hpp"
stefank@2314 29 #include "classfile/vmSymbols.hpp"
stefank@2314 30 #include "code/codeCache.hpp"
stefank@2314 31 #include "code/icBuffer.hpp"
brutisso@3710 32 #include "gc_implementation/g1/g1Log.hpp"
stefank@2314 33 #include "gc_implementation/g1/g1MarkSweep.hpp"
stefank@2314 34 #include "memory/gcLocker.hpp"
stefank@2314 35 #include "memory/genCollectedHeap.hpp"
stefank@2314 36 #include "memory/modRefBarrierSet.hpp"
stefank@2314 37 #include "memory/referencePolicy.hpp"
stefank@2314 38 #include "memory/space.hpp"
stefank@2314 39 #include "oops/instanceRefKlass.hpp"
stefank@2314 40 #include "oops/oop.inline.hpp"
stefank@2314 41 #include "prims/jvmtiExport.hpp"
stefank@2314 42 #include "runtime/aprofiler.hpp"
stefank@2314 43 #include "runtime/biasedLocking.hpp"
stefank@2314 44 #include "runtime/fprofiler.hpp"
stefank@2314 45 #include "runtime/synchronizer.hpp"
stefank@2314 46 #include "runtime/thread.hpp"
stefank@2314 47 #include "runtime/vmThread.hpp"
stefank@2314 48 #include "utilities/copy.hpp"
stefank@2314 49 #include "utilities/events.hpp"
ysr@777 50
ysr@777 51 class HeapRegion;
ysr@777 52
ysr@777 53 void G1MarkSweep::invoke_at_safepoint(ReferenceProcessor* rp,
ysr@777 54 bool clear_all_softrefs) {
ysr@777 55 assert(SafepointSynchronize::is_at_safepoint(), "must be at a safepoint");
ysr@777 56
jmasa@1822 57 SharedHeap* sh = SharedHeap::heap();
jmasa@1822 58 #ifdef ASSERT
jmasa@1822 59 if (sh->collector_policy()->should_clear_all_soft_refs()) {
jmasa@1822 60 assert(clear_all_softrefs, "Policy should have been checked earler");
jmasa@1822 61 }
jmasa@1822 62 #endif
ysr@777 63 // hook up weak ref data so it can be used during Mark-Sweep
ysr@777 64 assert(GenMarkSweep::ref_processor() == NULL, "no stomping");
ysr@888 65 assert(rp != NULL, "should be non-NULL");
johnc@3175 66 assert(rp == G1CollectedHeap::heap()->ref_processor_stw(), "Precondition");
johnc@3175 67
ysr@777 68 GenMarkSweep::_ref_processor = rp;
ysr@892 69 rp->setup_policy(clear_all_softrefs);
ysr@777 70
coleenp@4037 71 // When collecting the permanent generation Method*s may be moving,
ysr@777 72 // so we either have to flush all bcp data or convert it into bci.
ysr@777 73 CodeCache::gc_prologue();
ysr@777 74 Threads::gc_prologue();
ysr@777 75
ysr@777 76 bool marked_for_unloading = false;
ysr@777 77
ysr@777 78 allocate_stacks();
ysr@777 79
iveresov@793 80 // We should save the marks of the currently locked biased monitors.
iveresov@793 81 // The marking doesn't preserve the marks of biased objects.
iveresov@793 82 BiasedLocking::preserve_marks();
iveresov@793 83
ysr@777 84 mark_sweep_phase1(marked_for_unloading, clear_all_softrefs);
ysr@777 85
ysr@777 86 mark_sweep_phase2();
ysr@777 87
ysr@777 88 // Don't add any more derived pointers during phase3
ysr@777 89 COMPILER2_PRESENT(DerivedPointerTable::set_active(false));
ysr@777 90
ysr@777 91 mark_sweep_phase3();
ysr@777 92
ysr@777 93 mark_sweep_phase4();
ysr@777 94
ysr@777 95 GenMarkSweep::restore_marks();
iveresov@793 96 BiasedLocking::restore_marks();
ysr@777 97 GenMarkSweep::deallocate_stacks();
ysr@777 98
ysr@777 99 // "free at last gc" is calculated from these.
ysr@777 100 // CHF: cheating for now!!!
ysr@777 101 // Universe::set_heap_capacity_at_last_gc(Universe::heap()->capacity());
ysr@777 102 // Universe::set_heap_used_at_last_gc(Universe::heap()->used());
ysr@777 103
ysr@777 104 Threads::gc_epilogue();
ysr@777 105 CodeCache::gc_epilogue();
kamg@2467 106 JvmtiExport::gc_epilogue();
ysr@777 107
ysr@777 108 // refs processing: clean slate
ysr@777 109 GenMarkSweep::_ref_processor = NULL;
ysr@777 110 }
ysr@777 111
ysr@777 112
ysr@777 113 void G1MarkSweep::allocate_stacks() {
ysr@777 114 GenMarkSweep::_preserved_count_max = 0;
ysr@777 115 GenMarkSweep::_preserved_marks = NULL;
ysr@777 116 GenMarkSweep::_preserved_count = 0;
ysr@777 117 }
ysr@777 118
ysr@777 119 void G1MarkSweep::mark_sweep_phase1(bool& marked_for_unloading,
ysr@777 120 bool clear_all_softrefs) {
ysr@777 121 // Recursively traverse all live objects and mark them
brutisso@3710 122 TraceTime tm("phase 1", G1Log::fine() && Verbose, true, gclog_or_tty);
ysr@777 123 GenMarkSweep::trace(" 1");
ysr@777 124
ysr@777 125 SharedHeap* sh = SharedHeap::heap();
ysr@777 126
coleenp@4037 127 // Need cleared claim bits for the strong roots processing
coleenp@4037 128 ClassLoaderDataGraph::clear_claimed_marks();
coleenp@4037 129
coleenp@4037 130 sh->process_strong_roots(true, // activate StrongRootsScope
coleenp@4037 131 false, // not scavenging.
ysr@777 132 SharedHeap::SO_SystemClasses,
ysr@777 133 &GenMarkSweep::follow_root_closure,
jrose@1424 134 &GenMarkSweep::follow_code_root_closure,
coleenp@4037 135 &GenMarkSweep::follow_klass_closure);
ysr@777 136
ysr@777 137 // Process reference objects found during marking
ysr@888 138 ReferenceProcessor* rp = GenMarkSweep::ref_processor();
johnc@3175 139 assert(rp == G1CollectedHeap::heap()->ref_processor_stw(), "Sanity");
johnc@3175 140
ysr@892 141 rp->setup_policy(clear_all_softrefs);
ysr@888 142 rp->process_discovered_references(&GenMarkSweep::is_alive,
ysr@888 143 &GenMarkSweep::keep_alive,
ysr@888 144 &GenMarkSweep::follow_stack_closure,
ysr@888 145 NULL);
ysr@777 146
ysr@777 147 // Follow system dictionary roots and unload classes
ysr@777 148 bool purged_class = SystemDictionary::do_unloading(&GenMarkSweep::is_alive);
jcoomes@2191 149 assert(GenMarkSweep::_marking_stack.is_empty(),
ysr@777 150 "stack should be empty by now");
ysr@777 151
ysr@777 152 // Follow code cache roots (has to be done after system dictionary,
ysr@777 153 // assumes all live klasses are marked)
brutisso@4098 154 CodeCache::do_unloading(&GenMarkSweep::is_alive, purged_class);
ysr@1376 155 GenMarkSweep::follow_stack();
ysr@777 156
ysr@777 157 // Update subklass/sibling/implementor links of live klasses
coleenp@4037 158 Klass::clean_weak_klass_links(&GenMarkSweep::is_alive);
jcoomes@2191 159 assert(GenMarkSweep::_marking_stack.is_empty(),
ysr@777 160 "stack should be empty by now");
ysr@777 161
coleenp@2497 162 // Visit interned string tables and delete unmarked oops
ysr@777 163 StringTable::unlink(&GenMarkSweep::is_alive);
coleenp@2497 164 // Clean up unreferenced symbols in symbol table.
coleenp@2497 165 SymbolTable::unlink();
ysr@777 166
jcoomes@2191 167 assert(GenMarkSweep::_marking_stack.is_empty(),
ysr@777 168 "stack should be empty by now");
johnc@2969 169
johnc@2969 170 if (VerifyDuringGC) {
johnc@2969 171 HandleMark hm; // handle scope
johnc@2969 172 COMPILER2_PRESENT(DerivedPointerTableDeactivate dpt_deact);
johnc@2969 173 gclog_or_tty->print(" VerifyDuringGC:(full)[Verifying ");
johnc@2969 174 Universe::heap()->prepare_for_verify();
johnc@2969 175 // Note: we can verify only the heap here. When an object is
johnc@2969 176 // marked, the previous value of the mark word (including
johnc@2969 177 // identity hash values, ages, etc) is preserved, and the mark
johnc@2969 178 // word is set to markOop::marked_value - effectively removing
johnc@2969 179 // any hash values from the mark word. These hash values are
johnc@2969 180 // used when verifying the dictionaries and so removing them
johnc@2969 181 // from the mark word can make verification of the dictionaries
johnc@2969 182 // fail. At the end of the GC, the orginal mark word values
johnc@2969 183 // (including hash values) are restored to the appropriate
johnc@2969 184 // objects.
brutisso@3711 185 Universe::heap()->verify(/* silent */ false,
johnc@2969 186 /* option */ VerifyOption_G1UseMarkWord);
johnc@2969 187
johnc@2969 188 G1CollectedHeap* g1h = G1CollectedHeap::heap();
johnc@2969 189 gclog_or_tty->print_cr("]");
johnc@2969 190 }
ysr@777 191 }
ysr@777 192
ysr@777 193 class G1PrepareCompactClosure: public HeapRegionClosure {
tonyp@2472 194 G1CollectedHeap* _g1h;
ysr@777 195 ModRefBarrierSet* _mrbs;
ysr@777 196 CompactPoint _cp;
tonyp@2472 197 HumongousRegionSet _humongous_proxy_set;
ysr@777 198
ysr@777 199 void free_humongous_region(HeapRegion* hr) {
ysr@777 200 HeapWord* end = hr->end();
tonyp@2643 201 size_t dummy_pre_used;
tonyp@2643 202 FreeRegionList dummy_free_list("Dummy Free List for G1MarkSweep");
tonyp@2643 203
ysr@777 204 assert(hr->startsHumongous(),
ysr@777 205 "Only the start of a humongous region should be freed.");
tonyp@2643 206 _g1h->free_humongous_region(hr, &dummy_pre_used, &dummy_free_list,
tonyp@2472 207 &_humongous_proxy_set, false /* par */);
ysr@777 208 hr->prepare_for_compaction(&_cp);
ysr@777 209 // Also clear the part of the card table that will be unused after
ysr@777 210 // compaction.
tonyp@2472 211 _mrbs->clear(MemRegion(hr->compaction_top(), end));
tonyp@2643 212 dummy_free_list.remove_all();
ysr@777 213 }
ysr@777 214
ysr@777 215 public:
tonyp@2472 216 G1PrepareCompactClosure(CompactibleSpace* cs)
tonyp@2472 217 : _g1h(G1CollectedHeap::heap()),
tonyp@2472 218 _mrbs(G1CollectedHeap::heap()->mr_bs()),
ysr@777 219 _cp(NULL, cs, cs->initialize_threshold()),
tonyp@2472 220 _humongous_proxy_set("G1MarkSweep Humongous Proxy Set") { }
tonyp@2472 221
tonyp@2472 222 void update_sets() {
tonyp@2472 223 // We'll recalculate total used bytes and recreate the free list
tonyp@2472 224 // at the end of the GC, so no point in updating those values here.
tonyp@2472 225 _g1h->update_sets_after_freeing_regions(0, /* pre_used */
tonyp@2472 226 NULL, /* free_list */
tonyp@3268 227 NULL, /* old_proxy_set */
tonyp@2472 228 &_humongous_proxy_set,
tonyp@2472 229 false /* par */);
tonyp@2472 230 }
tonyp@2472 231
ysr@777 232 bool doHeapRegion(HeapRegion* hr) {
ysr@777 233 if (hr->isHumongous()) {
ysr@777 234 if (hr->startsHumongous()) {
ysr@777 235 oop obj = oop(hr->bottom());
ysr@777 236 if (obj->is_gc_marked()) {
ysr@777 237 obj->forward_to(obj);
ysr@777 238 } else {
ysr@777 239 free_humongous_region(hr);
ysr@777 240 }
ysr@777 241 } else {
ysr@777 242 assert(hr->continuesHumongous(), "Invalid humongous.");
ysr@777 243 }
ysr@777 244 } else {
ysr@777 245 hr->prepare_for_compaction(&_cp);
ysr@777 246 // Also clear the part of the card table that will be unused after
ysr@777 247 // compaction.
ysr@777 248 _mrbs->clear(MemRegion(hr->compaction_top(), hr->end()));
ysr@777 249 }
ysr@777 250 return false;
ysr@777 251 }
ysr@777 252 };
apetrusenko@1112 253
ysr@777 254 void G1MarkSweep::mark_sweep_phase2() {
ysr@777 255 // Now all live objects are marked, compute the new object addresses.
ysr@777 256
ysr@777 257 // It is not required that we traverse spaces in the same order in
ysr@777 258 // phase2, phase3 and phase4, but the ValidateMarkSweep live oops
ysr@777 259 // tracking expects us to do so. See comment under phase4.
ysr@777 260
ysr@777 261 G1CollectedHeap* g1h = G1CollectedHeap::heap();
ysr@777 262
brutisso@3710 263 TraceTime tm("phase 2", G1Log::fine() && Verbose, true, gclog_or_tty);
ysr@777 264 GenMarkSweep::trace("2");
ysr@777 265
tonyp@3957 266 // find the first region
tonyp@3957 267 HeapRegion* r = g1h->region_at(0);
ysr@777 268 CompactibleSpace* sp = r;
ysr@777 269 if (r->isHumongous() && oop(r->bottom())->is_gc_marked()) {
ysr@777 270 sp = r->next_compaction_space();
ysr@777 271 }
ysr@777 272
apetrusenko@1112 273 G1PrepareCompactClosure blk(sp);
ysr@777 274 g1h->heap_region_iterate(&blk);
tonyp@2472 275 blk.update_sets();
ysr@777 276 }
ysr@777 277
ysr@777 278 class G1AdjustPointersClosure: public HeapRegionClosure {
ysr@777 279 public:
ysr@777 280 bool doHeapRegion(HeapRegion* r) {
ysr@777 281 if (r->isHumongous()) {
ysr@777 282 if (r->startsHumongous()) {
ysr@777 283 // We must adjust the pointers on the single H object.
ysr@777 284 oop obj = oop(r->bottom());
ysr@777 285 debug_only(GenMarkSweep::track_interior_pointers(obj));
ysr@777 286 // point all the oops to the new location
ysr@777 287 obj->adjust_pointers();
ysr@777 288 debug_only(GenMarkSweep::check_interior_pointers());
ysr@777 289 }
ysr@777 290 } else {
ysr@777 291 // This really ought to be "as_CompactibleSpace"...
ysr@777 292 r->adjust_pointers();
ysr@777 293 }
ysr@777 294 return false;
ysr@777 295 }
ysr@777 296 };
ysr@777 297
ysr@777 298 void G1MarkSweep::mark_sweep_phase3() {
ysr@777 299 G1CollectedHeap* g1h = G1CollectedHeap::heap();
ysr@777 300
ysr@777 301 // Adjust the pointers to reflect the new locations
brutisso@3710 302 TraceTime tm("phase 3", G1Log::fine() && Verbose, true, gclog_or_tty);
ysr@777 303 GenMarkSweep::trace("3");
ysr@777 304
ysr@777 305 SharedHeap* sh = SharedHeap::heap();
ysr@777 306
coleenp@4037 307 // Need cleared claim bits for the strong roots processing
coleenp@4037 308 ClassLoaderDataGraph::clear_claimed_marks();
coleenp@4037 309
jrose@1424 310 sh->process_strong_roots(true, // activate StrongRootsScope
coleenp@4037 311 false, // not scavenging.
ysr@777 312 SharedHeap::SO_AllClasses,
ysr@777 313 &GenMarkSweep::adjust_root_pointer_closure,
jrose@1424 314 NULL, // do not touch code cache here
coleenp@4037 315 &GenMarkSweep::adjust_klass_closure);
ysr@777 316
johnc@3175 317 assert(GenMarkSweep::ref_processor() == g1h->ref_processor_stw(), "Sanity");
johnc@3175 318 g1h->ref_processor_stw()->weak_oops_do(&GenMarkSweep::adjust_root_pointer_closure);
ysr@777 319
ysr@777 320 // Now adjust pointers in remaining weak roots. (All of which should
ysr@777 321 // have been cleared if they pointed to non-surviving objects.)
ysr@777 322 g1h->g1_process_weak_roots(&GenMarkSweep::adjust_root_pointer_closure,
ysr@777 323 &GenMarkSweep::adjust_pointer_closure);
ysr@777 324
ysr@777 325 GenMarkSweep::adjust_marks();
ysr@777 326
ysr@777 327 G1AdjustPointersClosure blk;
ysr@777 328 g1h->heap_region_iterate(&blk);
ysr@777 329 }
ysr@777 330
ysr@777 331 class G1SpaceCompactClosure: public HeapRegionClosure {
ysr@777 332 public:
ysr@777 333 G1SpaceCompactClosure() {}
ysr@777 334
ysr@777 335 bool doHeapRegion(HeapRegion* hr) {
ysr@777 336 if (hr->isHumongous()) {
ysr@777 337 if (hr->startsHumongous()) {
ysr@777 338 oop obj = oop(hr->bottom());
ysr@777 339 if (obj->is_gc_marked()) {
ysr@777 340 obj->init_mark();
ysr@777 341 } else {
ysr@777 342 assert(hr->is_empty(), "Should have been cleared in phase 2.");
ysr@777 343 }
ysr@777 344 hr->reset_during_compaction();
ysr@777 345 }
ysr@777 346 } else {
ysr@777 347 hr->compact();
ysr@777 348 }
ysr@777 349 return false;
ysr@777 350 }
ysr@777 351 };
ysr@777 352
ysr@777 353 void G1MarkSweep::mark_sweep_phase4() {
ysr@777 354 // All pointers are now adjusted, move objects accordingly
ysr@777 355
ysr@777 356 // The ValidateMarkSweep live oops tracking expects us to traverse spaces
ysr@777 357 // in the same order in phase2, phase3 and phase4. We don't quite do that
coleenp@4037 358 // here (code and comment not fixed for perm removal), so we tell the validate code
ysr@777 359 // to use a higher index (saved from phase2) when verifying perm_gen.
ysr@777 360 G1CollectedHeap* g1h = G1CollectedHeap::heap();
ysr@777 361
brutisso@3710 362 TraceTime tm("phase 4", G1Log::fine() && Verbose, true, gclog_or_tty);
ysr@777 363 GenMarkSweep::trace("4");
ysr@777 364
ysr@777 365 G1SpaceCompactClosure blk;
ysr@777 366 g1h->heap_region_iterate(&blk);
ysr@777 367
ysr@777 368 }

mercurial