1.1 --- a/src/share/vm/gc_implementation/g1/heapRegionSets.cpp Wed Nov 02 08:04:23 2011 +0100 1.2 +++ b/src/share/vm/gc_implementation/g1/heapRegionSets.cpp Mon Nov 07 22:11:12 2011 -0500 1.3 @@ -26,6 +26,17 @@ 1.4 #include "gc_implementation/g1/heapRegionRemSet.hpp" 1.5 #include "gc_implementation/g1/heapRegionSets.hpp" 1.6 1.7 +// Note on the check_mt_safety() methods below: 1.8 +// 1.9 +// Verification of the "master" heap region sets / lists that are 1.10 +// maintained by G1CollectedHeap is always done during a STW pause and 1.11 +// by the VM thread at the start / end of the pause. The standard 1.12 +// verification methods all assert check_mt_safety(). This is 1.13 +// important as it ensures that verification is done without 1.14 +// concurrent updates taking place at the same time. It follows, that, 1.15 +// for the "master" heap region sets / lists, the check_mt_safety() 1.16 +// method should include the VM thread / STW case. 1.17 + 1.18 //////////////////// FreeRegionList //////////////////// 1.19 1.20 const char* FreeRegionList::verify_region_extra(HeapRegion* hr) { 1.21 @@ -33,7 +44,7 @@ 1.22 return "the region should not be young"; 1.23 } 1.24 // The superclass will check that the region is empty and 1.25 - // not-humongous. 1.26 + // not humongous. 1.27 return HeapRegionLinkedList::verify_region_extra(hr); 1.28 } 1.29 1.30 @@ -58,12 +69,16 @@ 1.31 // (b) If we're not at a safepoint, operations on the master free 1.32 // list should be invoked while holding the Heap_lock. 1.33 1.34 - guarantee((SafepointSynchronize::is_at_safepoint() && 1.35 - (Thread::current()->is_VM_thread() || 1.36 - FreeList_lock->owned_by_self())) || 1.37 - (!SafepointSynchronize::is_at_safepoint() && 1.38 - Heap_lock->owned_by_self()), 1.39 - hrs_ext_msg(this, "master free list MT safety protocol")); 1.40 + if (SafepointSynchronize::is_at_safepoint()) { 1.41 + guarantee(Thread::current()->is_VM_thread() || 1.42 + FreeList_lock->owned_by_self(), 1.43 + hrs_ext_msg(this, "master free list MT safety protocol " 1.44 + "at a safepoint")); 1.45 + } else { 1.46 + guarantee(Heap_lock->owned_by_self(), 1.47 + hrs_ext_msg(this, "master free list MT safety protocol " 1.48 + "outside a safepoint")); 1.49 + } 1.50 1.51 return FreeRegionList::check_mt_safety(); 1.52 } 1.53 @@ -81,6 +96,48 @@ 1.54 return FreeRegionList::check_mt_safety(); 1.55 } 1.56 1.57 +//////////////////// OldRegionSet //////////////////// 1.58 + 1.59 +const char* OldRegionSet::verify_region_extra(HeapRegion* hr) { 1.60 + if (hr->is_young()) { 1.61 + return "the region should not be young"; 1.62 + } 1.63 + // The superclass will check that the region is not empty and not 1.64 + // humongous. 1.65 + return HeapRegionSet::verify_region_extra(hr); 1.66 +} 1.67 + 1.68 +//////////////////// MasterOldRegionSet //////////////////// 1.69 + 1.70 +bool MasterOldRegionSet::check_mt_safety() { 1.71 + // Master Old Set MT safety protocol: 1.72 + // (a) If we're at a safepoint, operations on the master old set 1.73 + // should be invoked: 1.74 + // - by the VM thread (which will serialize them), or 1.75 + // - by the GC workers while holding the FreeList_lock, if we're 1.76 + // at a safepoint for an evacuation pause (this lock is taken 1.77 + // anyway when an GC alloc region is retired so that a new one 1.78 + // is allocated from the free list), or 1.79 + // - by the GC workers while holding the OldSets_lock, if we're at a 1.80 + // safepoint for a cleanup pause. 1.81 + // (b) If we're not at a safepoint, operations on the master old set 1.82 + // should be invoked while holding the Heap_lock. 1.83 + 1.84 + if (SafepointSynchronize::is_at_safepoint()) { 1.85 + guarantee(Thread::current()->is_VM_thread() || 1.86 + _phase == HRSPhaseEvacuation && FreeList_lock->owned_by_self() || 1.87 + _phase == HRSPhaseCleanup && OldSets_lock->owned_by_self(), 1.88 + hrs_ext_msg(this, "master old set MT safety protocol " 1.89 + "at a safepoint")); 1.90 + } else { 1.91 + guarantee(Heap_lock->owned_by_self(), 1.92 + hrs_ext_msg(this, "master old set MT safety protocol " 1.93 + "outside a safepoint")); 1.94 + } 1.95 + 1.96 + return OldRegionSet::check_mt_safety(); 1.97 +} 1.98 + 1.99 //////////////////// HumongousRegionSet //////////////////// 1.100 1.101 const char* HumongousRegionSet::verify_region_extra(HeapRegion* hr) { 1.102 @@ -103,11 +160,16 @@ 1.103 // (b) If we're not at a safepoint, operations on the master 1.104 // humongous set should be invoked while holding the Heap_lock. 1.105 1.106 - guarantee((SafepointSynchronize::is_at_safepoint() && 1.107 - (Thread::current()->is_VM_thread() || 1.108 - OldSets_lock->owned_by_self())) || 1.109 - (!SafepointSynchronize::is_at_safepoint() && 1.110 - Heap_lock->owned_by_self()), 1.111 - hrs_ext_msg(this, "master humongous set MT safety protocol")); 1.112 + if (SafepointSynchronize::is_at_safepoint()) { 1.113 + guarantee(Thread::current()->is_VM_thread() || 1.114 + OldSets_lock->owned_by_self(), 1.115 + hrs_ext_msg(this, "master humongous set MT safety protocol " 1.116 + "at a safepoint")); 1.117 + } else { 1.118 + guarantee(Heap_lock->owned_by_self(), 1.119 + hrs_ext_msg(this, "master humongous set MT safety protocol " 1.120 + "outside a safepoint")); 1.121 + } 1.122 + 1.123 return HumongousRegionSet::check_mt_safety(); 1.124 }