1/*
2 * Copyright (c) 2018, 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/shenandoahAggressiveHeuristics.hpp"
27#include "gc/shenandoah/shenandoahCollectionSet.hpp"
28#include "gc/shenandoah/shenandoahHeapRegion.hpp"
29#include "logging/log.hpp"
30#include "logging/logTag.hpp"
31#include "runtime/os.hpp"
32
33ShenandoahAggressiveHeuristics::ShenandoahAggressiveHeuristics() : ShenandoahHeuristics() {
34 // Do not shortcut evacuation
35 SHENANDOAH_ERGO_OVERRIDE_DEFAULT(ShenandoahImmediateThreshold, 100);
36
37 // Aggressive runs with max speed for allocation, to capture races against mutator
38 SHENANDOAH_ERGO_DISABLE_FLAG(ShenandoahPacing);
39
40 // Aggressive evacuates everything, so it needs as much evac space as it can get
41 SHENANDOAH_ERGO_ENABLE_FLAG(ShenandoahEvacReserveOverflow);
42
43 // If class unloading is globally enabled, aggressive does unloading even with
44 // concurrent cycles.
45 if (ClassUnloading) {
46 SHENANDOAH_ERGO_OVERRIDE_DEFAULT(ShenandoahUnloadClassesFrequency, 1);
47 }
48
49 // Final configuration checks
50 SHENANDOAH_CHECK_FLAG_SET(ShenandoahLoadRefBarrier);
51 SHENANDOAH_CHECK_FLAG_SET(ShenandoahSATBBarrier);
52 SHENANDOAH_CHECK_FLAG_SET(ShenandoahKeepAliveBarrier);
53 SHENANDOAH_CHECK_FLAG_SET(ShenandoahCASBarrier);
54 SHENANDOAH_CHECK_FLAG_SET(ShenandoahCloneBarrier);
55}
56
57void ShenandoahAggressiveHeuristics::choose_collection_set_from_regiondata(ShenandoahCollectionSet* cset,
58 RegionData* data, size_t size,
59 size_t free) {
60 for (size_t idx = 0; idx < size; idx++) {
61 ShenandoahHeapRegion* r = data[idx]._region;
62 if (r->garbage() > 0) {
63 cset->add_region(r);
64 }
65 }
66}
67
68bool ShenandoahAggressiveHeuristics::should_start_normal_gc() const {
69 log_info(gc)("Trigger: Start next cycle immediately");
70 return true;
71}
72
73bool ShenandoahAggressiveHeuristics::should_process_references() {
74 if (!can_process_references()) return false;
75 // Randomly process refs with 50% chance.
76 return (os::random() & 1) == 1;
77}
78
79bool ShenandoahAggressiveHeuristics::should_unload_classes() {
80 if (!can_unload_classes_normal()) return false;
81 if (has_metaspace_oom()) return true;
82 // Randomly unload classes with 50% chance.
83 return (os::random() & 1) == 1;
84}
85
86const char* ShenandoahAggressiveHeuristics::name() {
87 return "aggressive";
88}
89
90bool ShenandoahAggressiveHeuristics::is_diagnostic() {
91 return true;
92}
93
94bool ShenandoahAggressiveHeuristics::is_experimental() {
95 return false;
96}
97