Mercurial > hg > truffle
annotate src/share/vm/compiler/compileBroker.hpp @ 1994:6cd6d394f280
7001033: assert(gch->gc_cause() == GCCause::_scavenge_alot || !gch->incremental_collection_failed())
7002546: regression on SpecJbb2005 on 7b118 comparing to 7b117 on small heaps
Summary: Relaxed assertion checking related to incremental_collection_failed flag to allow for ExplicitGCInvokesConcurrent behaviour where we do not want a failing scavenge to bail to a stop-world collection. Parameterized incremental_collection_will_fail() so we can selectively use, or not use, as appropriate, the statistical prediction at specific use sites. This essentially reverts the scavenge bail-out logic to what it was prior to some recent changes that had inadvertently started using the statistical prediction which can be noisy in the presence of bursty loads. Added some associated verbose non-product debugging messages.
Reviewed-by: johnc, tonyp
author | ysr |
---|---|
date | Tue, 07 Dec 2010 21:55:53 -0800 |
parents | f95d63e2154a |
children | 06f017f7daa7 3d58a4983660 |
rev | line source |
---|---|
0 | 1 /* |
1783 | 2 * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. |
0 | 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 * | |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1489
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1489
diff
changeset
|
20 * or visit www.oracle.com if you need additional information or have any |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1489
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
1972 | 25 #ifndef SHARE_VM_COMPILER_COMPILEBROKER_HPP |
26 #define SHARE_VM_COMPILER_COMPILEBROKER_HPP | |
27 | |
28 #include "ci/compilerInterface.hpp" | |
29 #include "compiler/abstractCompiler.hpp" | |
30 #include "runtime/perfData.hpp" | |
31 | |
0 | 32 class nmethod; |
33 class nmethodLocker; | |
34 | |
35 // CompileTask | |
36 // | |
37 // An entry in the compile queue. It represents a pending or current | |
38 // compilation. | |
39 class CompileTask : public CHeapObj { | |
40 private: | |
41 Monitor* _lock; | |
42 uint _compile_id; | |
43 jobject _method; | |
44 int _osr_bci; | |
45 bool _is_complete; | |
46 bool _is_success; | |
47 bool _is_blocking; | |
48 int _comp_level; | |
49 int _num_inlined_bytecodes; | |
50 nmethodLocker* _code_handle; // holder of eventual result | |
1783 | 51 CompileTask* _next, *_prev; |
0 | 52 |
53 // Fields used for logging why the compilation was initiated: | |
54 jlong _time_queued; // in units of os::elapsed_counter() | |
55 jobject _hot_method; // which method actually triggered this task | |
56 int _hot_count; // information about its invocation counter | |
57 const char* _comment; // more info about the task | |
58 | |
1783 | 59 void print_compilation(outputStream *st, methodOop method, char* method_name); |
0 | 60 public: |
61 CompileTask() { | |
62 _lock = new Monitor(Mutex::nonleaf+2, "CompileTaskLock"); | |
63 } | |
64 | |
65 void initialize(int compile_id, methodHandle method, int osr_bci, int comp_level, | |
66 methodHandle hot_method, int hot_count, const char* comment, | |
67 bool is_blocking); | |
68 | |
69 void free(); | |
70 | |
71 int compile_id() const { return _compile_id; } | |
72 jobject method_handle() const { return _method; } | |
73 int osr_bci() const { return _osr_bci; } | |
74 bool is_complete() const { return _is_complete; } | |
75 bool is_blocking() const { return _is_blocking; } | |
76 bool is_success() const { return _is_success; } | |
77 | |
78 nmethodLocker* code_handle() const { return _code_handle; } | |
79 void set_code_handle(nmethodLocker* l) { _code_handle = l; } | |
80 nmethod* code() const; // _code_handle->code() | |
81 void set_code(nmethod* nm); // _code_handle->set_code(nm) | |
82 | |
83 Monitor* lock() const { return _lock; } | |
84 | |
85 void mark_complete() { _is_complete = true; } | |
86 void mark_success() { _is_success = true; } | |
87 | |
88 int comp_level() { return _comp_level;} | |
89 void set_comp_level(int comp_level) { _comp_level = comp_level;} | |
90 | |
91 int num_inlined_bytecodes() const { return _num_inlined_bytecodes; } | |
92 void set_num_inlined_bytecodes(int n) { _num_inlined_bytecodes = n; } | |
93 | |
94 CompileTask* next() const { return _next; } | |
95 void set_next(CompileTask* next) { _next = next; } | |
1783 | 96 CompileTask* prev() const { return _prev; } |
97 void set_prev(CompileTask* prev) { _prev = prev; } | |
0 | 98 |
99 void print(); | |
100 void print_line(); | |
1783 | 101 |
0 | 102 void print_line_on_error(outputStream* st, char* buf, int buflen); |
103 void log_task(xmlStream* log); | |
104 void log_task_queued(); | |
105 void log_task_start(CompileLog* log); | |
106 void log_task_done(CompileLog* log); | |
107 }; | |
108 | |
109 // CompilerCounters | |
110 // | |
111 // Per Compiler Performance Counters. | |
112 // | |
113 class CompilerCounters : public CHeapObj { | |
114 | |
115 public: | |
116 enum { | |
117 cmname_buffer_length = 160 | |
118 }; | |
119 | |
120 private: | |
121 | |
122 char _current_method[cmname_buffer_length]; | |
123 PerfStringVariable* _perf_current_method; | |
124 | |
125 int _compile_type; | |
126 PerfVariable* _perf_compile_type; | |
127 | |
128 PerfCounter* _perf_time; | |
129 PerfCounter* _perf_compiles; | |
130 | |
131 public: | |
132 CompilerCounters(const char* name, int instance, TRAPS); | |
133 | |
134 // these methods should be called in a thread safe context | |
135 | |
136 void set_current_method(const char* method) { | |
137 strncpy(_current_method, method, (size_t)cmname_buffer_length); | |
138 if (UsePerfData) _perf_current_method->set_value(method); | |
139 } | |
140 | |
141 char* current_method() { return _current_method; } | |
142 | |
143 void set_compile_type(int compile_type) { | |
144 _compile_type = compile_type; | |
145 if (UsePerfData) _perf_compile_type->set_value((jlong)compile_type); | |
146 } | |
147 | |
148 int compile_type() { return _compile_type; } | |
149 | |
150 PerfCounter* time_counter() { return _perf_time; } | |
151 PerfCounter* compile_counter() { return _perf_compiles; } | |
152 }; | |
153 | |
154 // CompileQueue | |
155 // | |
156 // A list of CompileTasks. | |
157 class CompileQueue : public CHeapObj { | |
158 private: | |
159 const char* _name; | |
160 Monitor* _lock; | |
161 | |
162 CompileTask* _first; | |
163 CompileTask* _last; | |
164 | |
1783 | 165 int _size; |
0 | 166 public: |
167 CompileQueue(const char* name, Monitor* lock) { | |
168 _name = name; | |
169 _lock = lock; | |
170 _first = NULL; | |
171 _last = NULL; | |
1783 | 172 _size = 0; |
0 | 173 } |
174 | |
175 const char* name() const { return _name; } | |
176 Monitor* lock() const { return _lock; } | |
177 | |
178 void add(CompileTask* task); | |
1783 | 179 void remove(CompileTask* task); |
180 CompileTask* first() { return _first; } | |
181 CompileTask* last() { return _last; } | |
0 | 182 |
183 CompileTask* get(); | |
184 | |
185 bool is_empty() const { return _first == NULL; } | |
1783 | 186 int size() const { return _size; } |
0 | 187 |
188 void print(); | |
189 }; | |
190 | |
1783 | 191 // CompileTaskWrapper |
192 // | |
193 // Assign this task to the current thread. Deallocate the task | |
194 // when the compilation is complete. | |
195 class CompileTaskWrapper : StackObj { | |
196 public: | |
197 CompileTaskWrapper(CompileTask* task); | |
198 ~CompileTaskWrapper(); | |
199 }; | |
200 | |
0 | 201 |
202 // Compilation | |
203 // | |
204 // The broker for all compilation requests. | |
205 class CompileBroker: AllStatic { | |
206 friend class Threads; | |
207 friend class CompileTaskWrapper; | |
208 | |
209 public: | |
210 enum { | |
211 name_buffer_length = 100 | |
212 }; | |
213 | |
214 // Compile type Information for print_last_compile() and CompilerCounters | |
215 enum { no_compile, normal_compile, osr_compile, native_compile }; | |
216 | |
217 private: | |
218 static bool _initialized; | |
219 static volatile bool _should_block; | |
220 | |
1202 | 221 // This flag can be used to stop compilation or turn it back on |
222 static volatile jint _should_compile_new_jobs; | |
223 | |
0 | 224 // The installed compiler(s) |
225 static AbstractCompiler* _compilers[2]; | |
226 | |
227 // These counters are used for assigning id's to each compilation | |
228 static uint _compilation_id; | |
229 static uint _osr_compilation_id; | |
230 static uint _native_compilation_id; | |
231 | |
232 static int _last_compile_type; | |
233 static int _last_compile_level; | |
234 static char _last_method_compiled[name_buffer_length]; | |
235 | |
1783 | 236 static CompileQueue* _c2_method_queue; |
237 static CompileQueue* _c1_method_queue; | |
0 | 238 static CompileTask* _task_free_list; |
239 | |
240 static GrowableArray<CompilerThread*>* _method_threads; | |
241 | |
242 // performance counters | |
243 static PerfCounter* _perf_total_compilation; | |
244 static PerfCounter* _perf_native_compilation; | |
245 static PerfCounter* _perf_osr_compilation; | |
246 static PerfCounter* _perf_standard_compilation; | |
247 | |
248 static PerfCounter* _perf_total_bailout_count; | |
249 static PerfCounter* _perf_total_invalidated_count; | |
250 static PerfCounter* _perf_total_compile_count; | |
251 static PerfCounter* _perf_total_native_compile_count; | |
252 static PerfCounter* _perf_total_osr_compile_count; | |
253 static PerfCounter* _perf_total_standard_compile_count; | |
254 | |
255 static PerfCounter* _perf_sum_osr_bytes_compiled; | |
256 static PerfCounter* _perf_sum_standard_bytes_compiled; | |
257 static PerfCounter* _perf_sum_nmethod_size; | |
258 static PerfCounter* _perf_sum_nmethod_code_size; | |
259 | |
260 static PerfStringVariable* _perf_last_method; | |
261 static PerfStringVariable* _perf_last_failed_method; | |
262 static PerfStringVariable* _perf_last_invalidated_method; | |
263 static PerfVariable* _perf_last_compile_type; | |
264 static PerfVariable* _perf_last_compile_size; | |
265 static PerfVariable* _perf_last_failed_type; | |
266 static PerfVariable* _perf_last_invalidated_type; | |
267 | |
268 // Timers and counters for generating statistics | |
269 static elapsedTimer _t_total_compilation; | |
270 static elapsedTimer _t_osr_compilation; | |
271 static elapsedTimer _t_standard_compilation; | |
272 | |
273 static int _total_bailout_count; | |
274 static int _total_invalidated_count; | |
275 static int _total_compile_count; | |
276 static int _total_native_compile_count; | |
277 static int _total_osr_compile_count; | |
278 static int _total_standard_compile_count; | |
279 | |
280 static int _sum_osr_bytes_compiled; | |
281 static int _sum_standard_bytes_compiled; | |
282 static int _sum_nmethod_size; | |
283 static int _sum_nmethod_code_size; | |
284 | |
285 static CompilerThread* make_compiler_thread(const char* name, CompileQueue* queue, CompilerCounters* counters, TRAPS); | |
1783 | 286 static void init_compiler_threads(int c1_compiler_count, int c2_compiler_count); |
0 | 287 static bool compilation_is_complete (methodHandle method, int osr_bci, int comp_level); |
288 static bool compilation_is_prohibited(methodHandle method, int osr_bci, int comp_level); | |
289 static uint assign_compile_id (methodHandle method, int osr_bci); | |
290 static bool is_compile_blocking (methodHandle method, int osr_bci); | |
291 static void preload_classes (methodHandle method, TRAPS); | |
292 | |
293 static CompileTask* create_compile_task(CompileQueue* queue, | |
294 int compile_id, | |
295 methodHandle method, | |
296 int osr_bci, | |
297 int comp_level, | |
298 methodHandle hot_method, | |
299 int hot_count, | |
300 const char* comment, | |
301 bool blocking); | |
302 static CompileTask* allocate_task(); | |
303 static void free_task(CompileTask* task); | |
304 static void wait_for_completion(CompileTask* task); | |
305 | |
306 static void invoke_compiler_on_method(CompileTask* task); | |
307 static void set_last_compile(CompilerThread *thread, methodHandle method, bool is_osr, int comp_level); | |
308 static void push_jni_handle_block(); | |
309 static void pop_jni_handle_block(); | |
310 static bool check_break_at(methodHandle method, int compile_id, bool is_osr); | |
311 static void collect_statistics(CompilerThread* thread, elapsedTimer time, CompileTask* task); | |
312 | |
313 static void compile_method_base(methodHandle method, | |
314 int osr_bci, | |
315 int comp_level, | |
316 methodHandle hot_method, | |
317 int hot_count, | |
318 const char* comment, | |
319 TRAPS); | |
1783 | 320 static CompileQueue* compile_queue(int comp_level) { |
321 if (is_c2_compile(comp_level)) return _c2_method_queue; | |
322 if (is_c1_compile(comp_level)) return _c1_method_queue; | |
323 return NULL; | |
324 } | |
0 | 325 public: |
326 enum { | |
327 // The entry bci used for non-OSR compilations. | |
328 standard_entry_bci = InvocationEntryBci | |
329 }; | |
330 | |
1783 | 331 static AbstractCompiler* compiler(int comp_level) { |
332 if (is_c2_compile(comp_level)) return _compilers[1]; // C2 | |
333 if (is_c1_compile(comp_level)) return _compilers[0]; // C1 | |
334 return NULL; | |
0 | 335 } |
336 | |
1783 | 337 static bool compilation_is_in_queue(methodHandle method, int osr_bci); |
338 static int queue_size(int comp_level) { | |
339 CompileQueue *q = compile_queue(comp_level); | |
340 return q != NULL ? q->size() : 0; | |
341 } | |
0 | 342 static void compilation_init(); |
343 static void init_compiler_thread_log(); | |
1783 | 344 static nmethod* compile_method(methodHandle method, |
345 int osr_bci, | |
346 int comp_level, | |
347 methodHandle hot_method, | |
348 int hot_count, | |
0 | 349 const char* comment, TRAPS); |
350 | |
351 static void compiler_thread_loop(); | |
352 | |
1202 | 353 static uint get_compilation_id() { return _compilation_id; } |
0 | 354 static bool is_idle(); |
355 | |
356 // Set _should_block. | |
357 // Call this from the VM, with Threads_lock held and a safepoint requested. | |
358 static void set_should_block(); | |
359 | |
360 // Call this from the compiler at convenient points, to poll for _should_block. | |
361 static void maybe_block(); | |
362 | |
1202 | 363 enum { |
364 // Flags for toggling compiler activity | |
365 stop_compilation = 0, | |
366 run_compilation = 1 | |
367 }; | |
368 | |
369 static bool should_compile_new_jobs() { return UseCompiler && (_should_compile_new_jobs == run_compilation); } | |
370 static bool set_should_compile_new_jobs(jint new_state) { | |
371 // Return success if the current caller set it | |
372 jint old = Atomic::cmpxchg(new_state, &_should_compile_new_jobs, 1-new_state); | |
373 return (old == (1-new_state)); | |
374 } | |
375 static void handle_full_code_cache(); | |
376 | |
0 | 377 // Return total compilation ticks |
378 static jlong total_compilation_ticks() { | |
379 return _perf_total_compilation != NULL ? _perf_total_compilation->get_value() : 0; | |
380 } | |
381 | |
382 // Print a detailed accounting of compilation time | |
383 static void print_times(); | |
384 | |
385 // Debugging output for failure | |
386 static void print_last_compile(); | |
387 | |
388 static void print_compiler_threads_on(outputStream* st); | |
389 }; | |
1972 | 390 |
391 #endif // SHARE_VM_COMPILER_COMPILEBROKER_HPP |