1 /* 2 * Copyright (c) 2018, 2019, Red Hat, Inc. All rights reserved. 3 * 4 * This code is free software; you can redistribute it and/or modify it 5 * under the terms of the GNU General Public License version 2 only, as 6 * published by the Free Software Foundation. 7 * 8 * This code is distributed in the hope that it will be useful, but WITHOUT 9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 11 * version 2 for more details (a copy is included in the LICENSE file that 12 * accompanied this code). 13 * 14 * You should have received a copy of the GNU General Public License version 15 * 2 along with this work; if not, write to the Free Software Foundation, 16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 17 * 18 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 19 * or visit www.oracle.com if you need additional information or have any 20 * questions. 21 * 22 */ 23 24 #include "precompiled.hpp" 25 26 #include "gc/shenandoah/heuristics/shenandoahTraversalAggressiveHeuristics.hpp" 27 #include "gc/shenandoah/shenandoahCollectionSet.hpp" 28 #include "gc/shenandoah/shenandoahFreeSet.hpp" 29 #include "gc/shenandoah/shenandoahHeap.inline.hpp" 30 #include "gc/shenandoah/shenandoahHeuristics.hpp" 31 #include "gc/shenandoah/shenandoahTraversalGC.hpp" 32 #include "logging/log.hpp" 33 #include "logging/logTag.hpp" 34 #include "utilities/quickSort.hpp" 35 36 ShenandoahTraversalAggressiveHeuristics::ShenandoahTraversalAggressiveHeuristics() : ShenandoahHeuristics(), 37 _last_cset_select(0) { 38 // Do not shortcut evacuation 39 SHENANDOAH_ERGO_OVERRIDE_DEFAULT(ShenandoahImmediateThreshold, 100); 40 41 // Aggressive runs with max speed for allocation, to capture races against mutator 42 SHENANDOAH_ERGO_DISABLE_FLAG(ShenandoahPacing); 43 44 // Aggressive evacuates everything, so it needs as much evac space as it can get 45 SHENANDOAH_ERGO_ENABLE_FLAG(ShenandoahEvacReserveOverflow); 46 47 // If class unloading is globally enabled, aggressive does unloading even with 48 // concurrent cycles. 49 if (ClassUnloading) { 50 SHENANDOAH_ERGO_OVERRIDE_DEFAULT(ShenandoahUnloadClassesFrequency, 1); 51 } 52 53 } 54 55 bool ShenandoahTraversalAggressiveHeuristics::is_experimental() { 56 return false; 57 } 58 59 bool ShenandoahTraversalAggressiveHeuristics::is_diagnostic() { 60 return true; 61 } 62 63 const char* ShenandoahTraversalAggressiveHeuristics::name() { 64 return "traversal-aggressive"; 65 } 66 67 void ShenandoahTraversalAggressiveHeuristics::choose_collection_set(ShenandoahCollectionSet* collection_set) { 68 ShenandoahHeap* heap = ShenandoahHeap::heap(); 69 70 ShenandoahTraversalGC* traversal_gc = heap->traversal_gc(); 71 72 ShenandoahHeapRegionSet* traversal_set = traversal_gc->traversal_set(); 73 traversal_set->clear(); 74 75 RegionData *data = get_region_data_cache(heap->num_regions()); 76 size_t cnt = 0; 77 78 // About to choose the collection set, make sure we have pinned regions in correct state 79 heap->assert_pinned_region_status(); 80 81 // Step 0. Prepare all regions 82 for (size_t i = 0; i < heap->num_regions(); i++) { 83 ShenandoahHeapRegion* r = heap->get_region(i); 84 if (r->used() > 0) { 85 if (r->is_regular()) { 86 data[cnt]._region = r; 87 data[cnt]._garbage = r->garbage(); 88 data[cnt]._seqnum_last_alloc = r->seqnum_last_alloc_mutator(); 89 cnt++; 90 } 91 traversal_set->add_region(r); 92 } 93 } 94 95 for (size_t i = 0; i < cnt; i++) { 96 if (data[i]._seqnum_last_alloc > _last_cset_select) continue; 97 98 ShenandoahHeapRegion* r = data[i]._region; 99 assert (r->is_regular(), "should have been filtered before"); 100 101 if (r->garbage() > 0) { 102 assert(!collection_set->is_in(r), "must not yet be in cset"); 103 collection_set->add_region(r); 104 } 105 } 106 107 // Clear liveness data 108 // TODO: Merge it with step 0, but save live data in RegionData before. 109 for (size_t i = 0; i < heap->num_regions(); i++) { 110 ShenandoahHeapRegion* r = heap->get_region(i); 111 if (r->used() > 0) { 112 r->clear_live_data(); 113 } 114 } 115 116 collection_set->update_region_status(); 117 118 _last_cset_select = ShenandoahHeapRegion::seqnum_current_alloc(); 119 } 120 121 void ShenandoahTraversalAggressiveHeuristics::choose_collection_set_from_regiondata(ShenandoahCollectionSet* set, 122 RegionData* data, size_t data_size, 123 size_t free) { 124 ShouldNotReachHere(); 125 } 126 127 bool ShenandoahTraversalAggressiveHeuristics::should_start_gc() const { 128 log_info(gc)("Trigger: Start next cycle immediately"); 129 return true; 130 }