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_implementation/shenandoah/heuristics/shenandoahTraversalAggressiveHeuristics.hpp" 27 #include "gc_implementation/shenandoah/shenandoahCollectionSet.hpp" 28 #include "gc_implementation/shenandoah/shenandoahFreeSet.hpp" 29 #include "gc_implementation/shenandoah/shenandoahHeap.inline.hpp" 30 #include "gc_implementation/shenandoah/shenandoahHeuristics.hpp" 31 #include "gc_implementation/shenandoah/shenandoahTraversalGC.hpp" 32 #include "gc_implementation/shenandoah/shenandoahLogging.hpp" 33 #include "utilities/quickSort.hpp" 34 35 ShenandoahTraversalAggressiveHeuristics::ShenandoahTraversalAggressiveHeuristics() : ShenandoahHeuristics(), 36 _last_cset_select(0) { 37 // Do not shortcut evacuation 38 SHENANDOAH_ERGO_OVERRIDE_DEFAULT(ShenandoahImmediateThreshold, 100); 39 40 // Aggressive runs with max speed for allocation, to capture races against mutator 41 SHENANDOAH_ERGO_DISABLE_FLAG(ShenandoahPacing); 42 43 // Aggressive evacuates everything, so it needs as much evac space as it can get 44 SHENANDOAH_ERGO_ENABLE_FLAG(ShenandoahEvacReserveOverflow); 45 46 // If class unloading is globally enabled, aggressive does unloading even with 47 // concurrent cycles. 48 if (ClassUnloading) { 49 SHENANDOAH_ERGO_OVERRIDE_DEFAULT(ShenandoahUnloadClassesFrequency, 1); 50 } 51 52 } 53 54 bool ShenandoahTraversalAggressiveHeuristics::is_experimental() { 55 return false; 56 } 57 58 bool ShenandoahTraversalAggressiveHeuristics::is_diagnostic() { 59 return true; 60 } 61 62 const char* ShenandoahTraversalAggressiveHeuristics::name() { 63 return "traversal-aggressive"; 64 } 65 66 void ShenandoahTraversalAggressiveHeuristics::choose_collection_set(ShenandoahCollectionSet* collection_set) { 67 ShenandoahHeap* heap = ShenandoahHeap::heap(); 68 69 ShenandoahTraversalGC* traversal_gc = heap->traversal_gc(); 70 71 ShenandoahHeapRegionSet* traversal_set = traversal_gc->traversal_set(); 72 traversal_set->clear(); 73 74 RegionData *data = get_region_data_cache(heap->num_regions()); 75 size_t cnt = 0; 76 77 // Step 0. Prepare all regions 78 for (size_t i = 0; i < heap->num_regions(); i++) { 79 ShenandoahHeapRegion* r = heap->get_region(i); 80 if (r->used() > 0) { 81 if (r->is_regular()) { 82 data[cnt]._region = r; 83 data[cnt]._garbage = r->garbage(); 84 data[cnt]._seqnum_last_alloc = r->seqnum_last_alloc_mutator(); 85 cnt++; 86 } 87 traversal_set->add_region(r); 88 } 89 } 90 91 for (size_t i = 0; i < cnt; i++) { 92 if (data[i]._seqnum_last_alloc > _last_cset_select) continue; 93 94 ShenandoahHeapRegion* r = data[i]._region; 95 assert (r->is_regular(), "should have been filtered before"); 96 97 if (r->garbage() > 0) { 98 assert(!collection_set->is_in(r), "must not yet be in cset"); 99 collection_set->add_region(r); 100 } 101 } 102 103 // Clear liveness data 104 // TODO: Merge it with step 0, but save live data in RegionData before. 105 for (size_t i = 0; i < heap->num_regions(); i++) { 106 ShenandoahHeapRegion* r = heap->get_region(i); 107 if (r->used() > 0) { 108 r->clear_live_data(); 109 } 110 } 111 112 collection_set->update_region_status(); 113 114 _last_cset_select = ShenandoahHeapRegion::seqnum_current_alloc(); 115 } 116 117 void ShenandoahTraversalAggressiveHeuristics::choose_collection_set_from_regiondata(ShenandoahCollectionSet* set, 118 RegionData* data, size_t data_size, 119 size_t free) { 120 ShouldNotReachHere(); 121 } 122 123 bool ShenandoahTraversalAggressiveHeuristics::should_start_gc() const { 124 log_info(gc)("Trigger: Start next cycle immediately"); 125 return true; 126 }