- Notifications
You must be signed in to change notification settings - Fork 5.8k
/
Copy pathcompileTask.hpp
272 lines (236 loc) · 11.3 KB
/
compileTask.hpp
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
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
/*
* Copyright (c) 1998, 2024, Oracle and/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_COMPILER_COMPILETASK_HPP
#defineSHARE_COMPILER_COMPILETASK_HPP
#include"ci/ciMethod.hpp"
#include"code/nmethod.hpp"
#include"compiler/compileLog.hpp"
#include"memory/allocation.hpp"
#include"utilities/xmlstream.hpp"
classDirectiveSet;
JVMCI_ONLY(classJVMCICompileState;)
enum class InliningResult { SUCCESS, FAILURE };
inline InliningResult inlining_result_of(bool success) {
return success ? InliningResult::SUCCESS : InliningResult::FAILURE;
}
// CompileTask
//
// An entry in the compile queue. It represents a pending or current
// compilation.
classCompileTask : publicCHeapObj<mtCompiler> {
friendclassVMStructs;
friendclassJVMCIVMStructs;
public:
// Different reasons for a compilation
// The order is important - mapped to reason_names[]
enum CompileReason {
Reason_None,
Reason_InvocationCount, // Simple/StackWalk-policy
Reason_BackedgeCount, // Simple/StackWalk-policy
Reason_Tiered, // Tiered-policy
Reason_Replay, // ciReplay
Reason_Whitebox, // Whitebox API
Reason_MustBeCompiled, // Used for -Xcomp or AlwaysCompileLoopMethods (see CompilationPolicy::must_be_compiled())
Reason_Bootstrap, // JVMCI bootstrap
Reason_Count
};
staticconstchar* reason_name(CompileTask::CompileReason compile_reason) {
staticconstchar* reason_names[] = {
"no_reason",
"count",
"backedge_count",
"tiered",
"replay",
"whitebox",
"must_be_compiled",
"bootstrap"
};
return reason_names[compile_reason];
}
private:
static CompileTask* _task_free_list;
Monitor* _lock;
int _compile_id;
Method* _method;
jobject _method_holder;
int _osr_bci;
bool _is_complete;
bool _is_success;
bool _is_blocking;
CodeSection::csize_t _nm_content_size;
CodeSection::csize_t _nm_total_size;
CodeSection::csize_t _nm_insts_size;
DirectiveSet* _directive;
#if INCLUDE_JVMCI
bool _has_waiter;
// Compilation state for a blocking JVMCI compilation
JVMCICompileState* _blocking_jvmci_compile_state;
#endif
int _waiting_count; // See waiting_for_completion_count()
int _comp_level;
int _num_inlined_bytecodes;
CompileTask* _next, *_prev;
bool _is_free;
// Fields used for logging why the compilation was initiated:
jlong _time_queued; // time when task was enqueued
jlong _time_started; // time when compilation started
Method* _hot_method; // which method actually triggered this task
jobject _hot_method_holder;
int _hot_count; // information about its invocation counter
CompileReason _compile_reason; // more info about the task
constchar* _failure_reason;
// Specifies if _failure_reason is on the C heap.
bool _failure_reason_on_C_heap;
size_t _arena_bytes; // peak size of temporary memory during compilation (e.g. node arenas)
public:
CompileTask() : _failure_reason(nullptr), _failure_reason_on_C_heap(false) {
// May hold MethodCompileQueue_lock
_lock = newMonitor(Mutex::safepoint-1, "CompileTask_lock");
}
voidinitialize(int compile_id, const methodHandle& method, int osr_bci, int comp_level,
const methodHandle& hot_method, int hot_count,
CompileTask::CompileReason compile_reason, bool is_blocking);
static CompileTask* allocate();
staticvoidfree(CompileTask* task);
intcompile_id() const { return _compile_id; }
Method* method() const { return _method; }
Method* hot_method() const { return _hot_method; }
intosr_bci() const { return _osr_bci; }
boolis_complete() const { return _is_complete; }
boolis_blocking() const { return _is_blocking; }
boolis_success() const { return _is_success; }
DirectiveSet* directive() const { return _directive; }
CodeSection::csize_tnm_content_size() { return _nm_content_size; }
voidset_nm_content_size(CodeSection::csize_t size) { _nm_content_size = size; }
CodeSection::csize_tnm_insts_size() { return _nm_insts_size; }
voidset_nm_insts_size(CodeSection::csize_t size) { _nm_insts_size = size; }
CodeSection::csize_tnm_total_size() { return _nm_total_size; }
voidset_nm_total_size(CodeSection::csize_t size) { _nm_total_size = size; }
boolcan_become_stale() const {
switch (_compile_reason) {
case Reason_BackedgeCount:
case Reason_InvocationCount:
case Reason_Tiered:
return !_is_blocking;
default:
returnfalse;
}
}
#if INCLUDE_JVMCI
boolshould_wait_for_compilation() const {
// Wait for blocking compilation to finish.
switch (_compile_reason) {
case Reason_Replay:
case Reason_Whitebox:
case Reason_Bootstrap:
return _is_blocking;
default:
returnfalse;
}
}
boolhas_waiter() const { return _has_waiter; }
voidclear_waiter() { _has_waiter = false; }
JVMCICompileState* blocking_jvmci_compile_state() const { return _blocking_jvmci_compile_state; }
voidset_blocking_jvmci_compile_state(JVMCICompileState* state) {
_blocking_jvmci_compile_state = state;
}
#endif
Monitor* lock() const { return _lock; }
// See how many threads are waiting for this task. Must have lock to read this.
intwaiting_for_completion_count() {
assert(_lock->owned_by_self(), "must have lock to use waiting_for_completion_count()");
return _waiting_count;
}
// Indicates that a thread is waiting for this task to complete. Must have lock to use this.
voidinc_waiting_for_completion() {
assert(_lock->owned_by_self(), "must have lock to use inc_waiting_for_completion()");
_waiting_count++;
}
// Indicates that a thread stopped waiting for this task to complete. Must have lock to use this.
voiddec_waiting_for_completion() {
assert(_lock->owned_by_self(), "must have lock to use dec_waiting_for_completion()");
assert(_waiting_count > 0, "waiting count is not positive");
_waiting_count--;
}
voidmark_complete() { _is_complete = true; }
voidmark_success() { _is_success = true; }
voidmark_started(jlong time) { _time_started = time; }
intcomp_level() { return _comp_level;}
voidset_comp_level(int comp_level) { _comp_level = comp_level;}
CompileReason compile_reason() { return _compile_reason; }
AbstractCompiler* compiler() const;
CompileTask* select_for_compilation();
intnum_inlined_bytecodes() const { return _num_inlined_bytecodes; }
voidset_num_inlined_bytecodes(int n) { _num_inlined_bytecodes = n; }
CompileTask* next() const { return _next; }
voidset_next(CompileTask* next) { _next = next; }
CompileTask* prev() const { return _prev; }
voidset_prev(CompileTask* prev) { _prev = prev; }
boolis_free() const { return _is_free; }
voidset_is_free(bool val) { _is_free = val; }
boolis_unloaded() const;
// RedefineClasses support
voidmetadata_do(MetadataClosure* f);
voidmark_on_stack();
voidset_arena_bytes(size_t s) { _arena_bytes = s; }
size_tarena_bytes() const { return _arena_bytes; }
private:
staticvoidprint_impl(outputStream* st, Method* method, int compile_id, int comp_level,
bool is_osr_method = false, int osr_bci = -1, bool is_blocking = false,
constchar* msg = nullptr, bool short_form = false, bool cr = true,
jlong time_queued = 0, jlong time_started = 0);
public:
voidprint(outputStream* st = tty, constchar* msg = nullptr, bool short_form = false, bool cr = true);
voidprint_ul(constchar* msg = nullptr);
staticvoidprint(outputStream* st, const nmethod* nm, constchar* msg = nullptr, bool short_form = false, bool cr = true) {
print_impl(st, nm->method(), nm->compile_id(), nm->comp_level(),
nm->is_osr_method(), nm->is_osr_method() ? nm->osr_entry_bci() : -1, /*is_blocking*/false,
msg, short_form, cr);
}
staticvoidprint_ul(const nmethod* nm, constchar* msg = nullptr);
/**
* @deprecated Please rely on Compile::inline_printer. Do not directly write inlining information to tty.
*/
staticvoidprint_inline_indent(int inline_level, outputStream* st = tty);
voidprint_tty();
voidprint_line_on_error(outputStream* st, char* buf, int buflen);
voidlog_task(xmlStream* log);
voidlog_task_queued();
voidlog_task_start(CompileLog* log);
voidlog_task_done(CompileLog* log);
voidset_failure_reason(constchar* reason, bool on_C_heap = false) {
_failure_reason = reason;
_failure_reason_on_C_heap = on_C_heap;
}
boolcheck_break_at_flags();
staticvoidprint_inlining_header(outputStream* st, ciMethod* method, int inline_level, int bci);
staticvoidprint_inlining_inner(outputStream* st, ciMethod* method, int inline_level, int bci, InliningResult result, constchar* msg = nullptr);
staticvoidprint_inline_inner_method_info(outputStream* st, ciMethod* method);
staticvoidprint_inlining_inner_message(outputStream* st, InliningResult result, constchar* msg);
staticvoidprint_inlining_tty(ciMethod* method, int inline_level, int bci, InliningResult result, constchar* msg = nullptr) {
print_inlining_inner(tty, method, inline_level, bci, result, msg);
}
staticvoidprint_inlining_ul(ciMethod* method, int inline_level, int bci, InliningResult result, constchar* msg = nullptr);
};
#endif// SHARE_COMPILER_COMPILETASK_HPP