1 /*
2 * Copyright (c) 2018, 2019, Red Hat, Inc. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 #ifndef SHARE_GC_SHENANDOAH_HEURISTICS_SHENANDOAHHEURISTICS_HPP
26 #define SHARE_GC_SHENANDOAH_HEURISTICS_SHENANDOAHHEURISTICS_HPP
27
28 #include "gc/shenandoah/shenandoahHeap.hpp"
29 #include "gc/shenandoah/shenandoahPhaseTimings.hpp"
30 #include "gc/shenandoah/shenandoahSharedVariables.hpp"
31 #include "memory/allocation.hpp"
32 #include "runtime/globals_extension.hpp"
33
34 #define SHENANDOAH_ERGO_DISABLE_FLAG(name) \
35 do { \
36 if (FLAG_IS_DEFAULT(name) && (name)) { \
37 log_info(gc)("Heuristics ergonomically sets -XX:-" #name); \
38 FLAG_SET_DEFAULT(name, false); \
39 } \
40 } while (0)
41
42 #define SHENANDOAH_ERGO_ENABLE_FLAG(name) \
43 do { \
44 if (FLAG_IS_DEFAULT(name) && !(name)) { \
45 log_info(gc)("Heuristics ergonomically sets -XX:+" #name); \
46 FLAG_SET_DEFAULT(name, true); \
47 } \
48 } while (0)
49
50 #define SHENANDOAH_ERGO_OVERRIDE_DEFAULT(name, value) \
51 do { \
52 if (FLAG_IS_DEFAULT(name)) { \
53 log_info(gc)("Heuristics ergonomically sets -XX:" #name "=" #value); \
54 FLAG_SET_DEFAULT(name, value); \
55 } \
56 } while (0)
57
58 class ShenandoahCollectionSet;
59 class ShenandoahHeapRegion;
60
61 class ShenandoahHeuristics : public CHeapObj<mtGC> {
62 static const intx Concurrent_Adjust = -1; // recover from penalties
63 static const intx Degenerated_Penalty = 10; // how much to penalize average GC duration history on Degenerated GC
64 static const intx Full_Penalty = 20; // how much to penalize average GC duration history on Full GC
65
66 protected:
67 typedef struct {
68 ShenandoahHeapRegion* _region;
69 size_t _garbage;
70 } RegionData;
71
72 RegionData* _region_data;
73
74 uint _degenerated_cycles_in_a_row;
75 uint _successful_cycles_in_a_row;
76
77 double _cycle_start;
78 double _last_cycle_end;
79
80 size_t _gc_times_learned;
81 intx _gc_time_penalties;
82 TruncatedSeq* _gc_time_history;
83
84 // There may be many threads that contend to set this flag
85 ShenandoahSharedFlag _metaspace_oom;
86
87 static int compare_by_garbage(RegionData a, RegionData b);
88
89 virtual void choose_collection_set_from_regiondata(ShenandoahCollectionSet* set,
90 RegionData* data, size_t data_size,
91 size_t free) = 0;
92
93 void adjust_penalty(intx step);
94
95 public:
96 ShenandoahHeuristics();
97 virtual ~ShenandoahHeuristics();
98
99 void record_metaspace_oom() { _metaspace_oom.set(); }
100 void clear_metaspace_oom() { _metaspace_oom.unset(); }
101 bool has_metaspace_oom() const { return _metaspace_oom.is_set(); }
102
103 virtual void record_cycle_start();
104
105 virtual void record_cycle_end();
106
107 virtual bool should_start_gc();
108
109 virtual bool should_degenerate_cycle();
110
111 virtual void record_success_concurrent();
112
113 virtual void record_success_degenerated();
114
115 virtual void record_success_full();
116
117 virtual void record_allocation_failure_gc();
118
119 virtual void record_requested_gc();
120
121 virtual void choose_collection_set(ShenandoahCollectionSet* collection_set);
122
123 virtual bool can_unload_classes();
124 virtual bool should_unload_classes();
125
126 virtual const char* name() = 0;
127 virtual bool is_diagnostic() = 0;
128 virtual bool is_experimental() = 0;
129 virtual void initialize();
130
131 double time_since_last_gc() const;
132 };
133
134 #endif // SHARE_GC_SHENANDOAH_HEURISTICS_SHENANDOAHHEURISTICS_HPP