-
Notifications
You must be signed in to change notification settings - Fork 6.4k
Expand file tree
/
Copy pathshenandoahController.hpp
More file actions
145 lines (116 loc) · 5.3 KB
/
Copy pathshenandoahController.hpp
File metadata and controls
145 lines (116 loc) · 5.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
/*
* Copyright Amazon.com Inc. or its affiliates. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#ifndef SHARE_GC_SHENANDOAH_SHENANDOAHCONTROLLER_HPP
#define SHARE_GC_SHENANDOAH_SHENANDOAHCONTROLLER_HPP
#include "gc/shared/concurrentGCThread.hpp"
#include "gc/shared/gcCause.hpp"
#include "gc/shenandoah/shenandoahAllocRequest.hpp"
#include "gc/shenandoah/shenandoahPadding.hpp"
#include "runtime/atomic.hpp"
class ShenandoahGeneration;
/**
* This interface exposes methods necessary for the heap to interact
* with the threads responsible for driving the collection cycle.
*/
class ShenandoahController: public ConcurrentGCThread {
public:
enum ShenandoahCollectorPhase {
UNSET,
INITIALIZING,
ROOTS,
MARK,
EVAC,
UPDATE_REFS,
PHASE_LIMIT
};
private:
shenandoah_padding(0);
// A monotonically increasing GC count.
Atomic<size_t> _gc_id;
shenandoah_padding(1);
// Written by control thread, read by mutators
Atomic<ShenandoahCollectorPhase> _phase;
protected:
const Mutex::Rank WAITERS_LOCK_RANK = Mutex::safepoint - 5;
const Mutex::Rank CONTROL_LOCK_RANK = Mutex::nosafepoint - 2;
// Threads waiting for a complete gc cycle (full gc or concurrent global) will wait here.
Monitor _gc_waiters_lock;
// Threads waiting for the gc to free memory will wait here. Note that immediate garabge may be reclaimed
// midcycle during final mark, so we want to notify alloc waiters independently of cycle waiters. Similarly,
// no threads should be notified when a concurrent old mark increment is interrupted.
Monitor _alloc_waiters_lock;
// The number of stalls experienced during the cycle. Incremented by mutators, reset by control thread.
shenandoah_padding(2);
Atomic<size_t> _alloc_stall_count;
shenandoah_padding(3);
// Written by control thread and mutators, clamped between ConcGCThreads and ParallelGCThreads.
Atomic<size_t> _concurrent_worker_count;
// Increments the internal GC count.
void update_gc_id();
// Increase worker count when a stall is reported. Called from mutator thread.
void increase_concurrent_worker_count();
// Decrease worker count if no stalls were detected in a cycle. Called from control thread.
void decrease_concurrent_worker_count();
// Returns the total number of allocation stalls during a cycle
size_t alloc_stall_count() const {
return _alloc_stall_count.load_relaxed();
}
// Notify the control thread to run a cycle for the given generation
virtual void notify_control_thread(GCCause::Cause cause, ShenandoahGeneration* generation) = 0;
// Notify the control thread about an allocation stall specifically. Implementation
// will decide which generation to use and any other mode specific work that must be done.
virtual void notify_alloc_stall(GCCause::Cause cause) = 0;
public:
ShenandoahController();
// Request a collection cycle. This handles "explicit" gc requests
// like System.gc and "implicit" gc requests, like metaspace oom.
virtual void request_gc(GCCause::Cause cause);
// Notify threads that the gc has completed a cycle, or it's exiting.
void notify_gc_waiters();
// Notify threads that the gc has recovered memory, or it's exiting.
void notify_alloc_waiters();
// Inform the control thread that this allocation request failed. Caller will block until memory is reclaimed.
void handle_alloc_failure(const ShenandoahAllocRequest &req);
// Run a full GC, callers will block until at least one full GC cycle is completed.
void handle_alloc_failure_full();
// Return suggested number of concurrent worker threads
size_t concurrent_worker_count() const {
return _concurrent_worker_count.load_relaxed();
}
// Return the value of a monotonic increasing GC count, maintained by the control thread.
size_t get_gc_id() const;
ShenandoahCollectorPhase get_phase() const {
return _phase.load_relaxed();
}
// Record the current phase for the cycle. Used to track where allocation stalls occur.
void set_phase(ShenandoahCollectorPhase phase) {
assert(ShenandoahCollectorPhase::UNSET <= phase, "Phase out of bounds: %d", phase);
assert(phase < ShenandoahCollectorPhase::PHASE_LIMIT, "Phase out of bounds %d", phase);
_phase.store_relaxed(phase);
}
static const char* collector_phase_to_string(ShenandoahCollectorPhase phase);
protected:
void handle_requested_gc(GCCause::Cause cause);
};
#endif // SHARE_GC_SHENANDOAH_SHENANDOAHCONTROLLER_HPP