1.1 --- a/src/share/vm/gc_implementation/g1/heapRegionSet.cpp Fri Mar 14 10:15:46 2014 +0100 1.2 +++ b/src/share/vm/gc_implementation/g1/heapRegionSet.cpp Mon Mar 17 13:42:16 2014 +0100 1.3 @@ -272,3 +272,108 @@ 1.4 } 1.5 } 1.6 } 1.7 + 1.8 +void FreeRegionList::verify_list() { 1.9 + HeapRegion* curr = head(); 1.10 + HeapRegion* prev1 = NULL; 1.11 + HeapRegion* prev0 = NULL; 1.12 + uint count = 0; 1.13 + size_t capacity = 0; 1.14 + while (curr != NULL) { 1.15 + verify_region(curr); 1.16 + 1.17 + count++; 1.18 + guarantee(count < _unrealistically_long_length, 1.19 + hrs_err_msg("[%s] the calculated length: %u seems very long, is there maybe a cycle? curr: "PTR_FORMAT" prev0: "PTR_FORMAT" " "prev1: "PTR_FORMAT" length: %u", name(), count, curr, prev0, prev1, length())); 1.20 + 1.21 + capacity += curr->capacity(); 1.22 + 1.23 + prev1 = prev0; 1.24 + prev0 = curr; 1.25 + curr = curr->next(); 1.26 + } 1.27 + 1.28 + guarantee(tail() == prev0, err_msg("Expected %s to end with %u but it ended with %u.", name(), tail()->hrs_index(), prev0->hrs_index())); 1.29 + 1.30 + guarantee(length() == count, err_msg("%s count mismatch. Expected %u, actual %u.", name(), length(), count)); 1.31 + guarantee(total_capacity_bytes() == capacity, err_msg("%s capacity mismatch. Expected " SIZE_FORMAT ", actual " SIZE_FORMAT, 1.32 + name(), total_capacity_bytes(), capacity)); 1.33 +} 1.34 + 1.35 +// Note on the check_mt_safety() methods below: 1.36 +// 1.37 +// Verification of the "master" heap region sets / lists that are 1.38 +// maintained by G1CollectedHeap is always done during a STW pause and 1.39 +// by the VM thread at the start / end of the pause. The standard 1.40 +// verification methods all assert check_mt_safety(). This is 1.41 +// important as it ensures that verification is done without 1.42 +// concurrent updates taking place at the same time. It follows, that, 1.43 +// for the "master" heap region sets / lists, the check_mt_safety() 1.44 +// method should include the VM thread / STW case. 1.45 + 1.46 +void MasterFreeRegionListMtSafeChecker::check() { 1.47 + // Master Free List MT safety protocol: 1.48 + // (a) If we're at a safepoint, operations on the master free list 1.49 + // should be invoked by either the VM thread (which will serialize 1.50 + // them) or by the GC workers while holding the 1.51 + // FreeList_lock. 1.52 + // (b) If we're not at a safepoint, operations on the master free 1.53 + // list should be invoked while holding the Heap_lock. 1.54 + 1.55 + if (SafepointSynchronize::is_at_safepoint()) { 1.56 + guarantee(Thread::current()->is_VM_thread() || 1.57 + FreeList_lock->owned_by_self(), "master free list MT safety protocol at a safepoint"); 1.58 + } else { 1.59 + guarantee(Heap_lock->owned_by_self(), "master free list MT safety protocol outside a safepoint"); 1.60 + } 1.61 +} 1.62 + 1.63 +void SecondaryFreeRegionListMtSafeChecker::check() { 1.64 + // Secondary Free List MT safety protocol: 1.65 + // Operations on the secondary free list should always be invoked 1.66 + // while holding the SecondaryFreeList_lock. 1.67 + 1.68 + guarantee(SecondaryFreeList_lock->owned_by_self(), "secondary free list MT safety protocol"); 1.69 +} 1.70 + 1.71 +void OldRegionSetMtSafeChecker::check() { 1.72 + // Master Old Set MT safety protocol: 1.73 + // (a) If we're at a safepoint, operations on the master old set 1.74 + // should be invoked: 1.75 + // - by the VM thread (which will serialize them), or 1.76 + // - by the GC workers while holding the FreeList_lock, if we're 1.77 + // at a safepoint for an evacuation pause (this lock is taken 1.78 + // anyway when an GC alloc region is retired so that a new one 1.79 + // is allocated from the free list), or 1.80 + // - by the GC workers while holding the OldSets_lock, if we're at a 1.81 + // safepoint for a cleanup pause. 1.82 + // (b) If we're not at a safepoint, operations on the master old set 1.83 + // should be invoked while holding the Heap_lock. 1.84 + 1.85 + if (SafepointSynchronize::is_at_safepoint()) { 1.86 + guarantee(Thread::current()->is_VM_thread() 1.87 + || FreeList_lock->owned_by_self() || OldSets_lock->owned_by_self(), 1.88 + "master old set MT safety protocol at a safepoint"); 1.89 + } else { 1.90 + guarantee(Heap_lock->owned_by_self(), "master old set MT safety protocol outside a safepoint"); 1.91 + } 1.92 +} 1.93 + 1.94 +void HumongousRegionSetMtSafeChecker::check() { 1.95 + // Humongous Set MT safety protocol: 1.96 + // (a) If we're at a safepoint, operations on the master humongous 1.97 + // set should be invoked by either the VM thread (which will 1.98 + // serialize them) or by the GC workers while holding the 1.99 + // OldSets_lock. 1.100 + // (b) If we're not at a safepoint, operations on the master 1.101 + // humongous set should be invoked while holding the Heap_lock. 1.102 + 1.103 + if (SafepointSynchronize::is_at_safepoint()) { 1.104 + guarantee(Thread::current()->is_VM_thread() || 1.105 + OldSets_lock->owned_by_self(), 1.106 + "master humongous set MT safety protocol at a safepoint"); 1.107 + } else { 1.108 + guarantee(Heap_lock->owned_by_self(), 1.109 + "master humongous set MT safety protocol outside a safepoint"); 1.110 + } 1.111 +}