Mercurial > hg > truffle
annotate src/share/vm/compiler/compileBroker.hpp @ 8733:9def4075da6d
8008079: G1: Add nextObject routine to CMBitMapRO and replace nextWord
Summary: Update the task local finger to the start of the next object when marking aborts, in order to avoid the redundant scanning of all 0's when the marking task restarts, if otherwise updating to the next word. In addition, reuse the routine nextObject() in routine iterate().
Reviewed-by: johnc, ysr
Contributed-by: tamao <tao.mao@oracle.com>
author | tamao |
---|---|
date | Tue, 05 Mar 2013 15:36:56 -0800 |
parents | 90273fc0a981 |
children | 291ffc492eb6 75a28f465a12 |
rev | line source |
---|---|
0 | 1 /* |
4872
aa3d708d67c4
7141200: log some interesting information in ring buffers for crashes
never
parents:
4825
diff
changeset
|
2 * Copyright (c) 1999, 2012, 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. | |
6197 | 39 class CompileTask : public CHeapObj<mtCompiler> { |
3939 | 40 friend class VMStructs; |
41 | |
0 | 42 private: |
43 Monitor* _lock; | |
44 uint _compile_id; | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
45 Method* _method; |
7185
90273fc0a981
8000662: NPG: nashorn ant clean test262 out-of-memory with Java heap
coleenp
parents:
6800
diff
changeset
|
46 jobject _method_holder; |
0 | 47 int _osr_bci; |
48 bool _is_complete; | |
49 bool _is_success; | |
50 bool _is_blocking; | |
51 int _comp_level; | |
52 int _num_inlined_bytecodes; | |
53 nmethodLocker* _code_handle; // holder of eventual result | |
1783 | 54 CompileTask* _next, *_prev; |
0 | 55 |
56 // Fields used for logging why the compilation was initiated: | |
57 jlong _time_queued; // in units of os::elapsed_counter() | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
58 Method* _hot_method; // which method actually triggered this task |
7185
90273fc0a981
8000662: NPG: nashorn ant clean test262 out-of-memory with Java heap
coleenp
parents:
6800
diff
changeset
|
59 jobject _hot_method_holder; |
0 | 60 int _hot_count; // information about its invocation counter |
61 const char* _comment; // more info about the task | |
62 | |
63 public: | |
64 CompileTask() { | |
65 _lock = new Monitor(Mutex::nonleaf+2, "CompileTaskLock"); | |
66 } | |
67 | |
68 void initialize(int compile_id, methodHandle method, int osr_bci, int comp_level, | |
69 methodHandle hot_method, int hot_count, const char* comment, | |
70 bool is_blocking); | |
71 | |
72 void free(); | |
73 | |
74 int compile_id() const { return _compile_id; } | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
75 Method* method() const { return _method; } |
0 | 76 int osr_bci() const { return _osr_bci; } |
77 bool is_complete() const { return _is_complete; } | |
78 bool is_blocking() const { return _is_blocking; } | |
79 bool is_success() const { return _is_success; } | |
80 | |
81 nmethodLocker* code_handle() const { return _code_handle; } | |
82 void set_code_handle(nmethodLocker* l) { _code_handle = l; } | |
83 nmethod* code() const; // _code_handle->code() | |
84 void set_code(nmethod* nm); // _code_handle->set_code(nm) | |
85 | |
86 Monitor* lock() const { return _lock; } | |
87 | |
88 void mark_complete() { _is_complete = true; } | |
89 void mark_success() { _is_success = true; } | |
90 | |
91 int comp_level() { return _comp_level;} | |
92 void set_comp_level(int comp_level) { _comp_level = comp_level;} | |
93 | |
94 int num_inlined_bytecodes() const { return _num_inlined_bytecodes; } | |
95 void set_num_inlined_bytecodes(int n) { _num_inlined_bytecodes = n; } | |
96 | |
97 CompileTask* next() const { return _next; } | |
98 void set_next(CompileTask* next) { _next = next; } | |
1783 | 99 CompileTask* prev() const { return _prev; } |
100 void set_prev(CompileTask* prev) { _prev = prev; } | |
0 | 101 |
2405
3d58a4983660
7022998: JSR 292 recursive method handle calls inline themselves infinitely
twisti
parents:
1972
diff
changeset
|
102 private: |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
103 static void print_compilation_impl(outputStream* st, Method* method, int compile_id, int comp_level, |
4872
aa3d708d67c4
7141200: log some interesting information in ring buffers for crashes
never
parents:
4825
diff
changeset
|
104 bool is_osr_method = false, int osr_bci = -1, bool is_blocking = false, |
aa3d708d67c4
7141200: log some interesting information in ring buffers for crashes
never
parents:
4825
diff
changeset
|
105 const char* msg = NULL, bool short_form = false); |
2405
3d58a4983660
7022998: JSR 292 recursive method handle calls inline themselves infinitely
twisti
parents:
1972
diff
changeset
|
106 |
3d58a4983660
7022998: JSR 292 recursive method handle calls inline themselves infinitely
twisti
parents:
1972
diff
changeset
|
107 public: |
6800
9191895df19d
7200001: failed C1 OSR compile doesn't get recompiled with C2
twisti
parents:
6725
diff
changeset
|
108 void print_compilation(outputStream* st = tty, const char* msg = NULL, bool short_form = false); |
6266
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
6197
diff
changeset
|
109 static void print_compilation(outputStream* st, const nmethod* nm, const char* msg = NULL, bool short_form = false) { |
4872
aa3d708d67c4
7141200: log some interesting information in ring buffers for crashes
never
parents:
4825
diff
changeset
|
110 print_compilation_impl(st, nm->method(), nm->compile_id(), nm->comp_level(), |
aa3d708d67c4
7141200: log some interesting information in ring buffers for crashes
never
parents:
4825
diff
changeset
|
111 nm->is_osr_method(), nm->is_osr_method() ? nm->osr_entry_bci() : -1, /*is_blocking*/ false, |
6266
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
6197
diff
changeset
|
112 msg, short_form); |
2405
3d58a4983660
7022998: JSR 292 recursive method handle calls inline themselves infinitely
twisti
parents:
1972
diff
changeset
|
113 } |
3d58a4983660
7022998: JSR 292 recursive method handle calls inline themselves infinitely
twisti
parents:
1972
diff
changeset
|
114 |
3d58a4983660
7022998: JSR 292 recursive method handle calls inline themselves infinitely
twisti
parents:
1972
diff
changeset
|
115 static void print_inlining(outputStream* st, ciMethod* method, int inline_level, int bci, const char* msg = NULL); |
3d58a4983660
7022998: JSR 292 recursive method handle calls inline themselves infinitely
twisti
parents:
1972
diff
changeset
|
116 static void print_inlining(ciMethod* method, int inline_level, int bci, const char* msg = NULL) { |
3d58a4983660
7022998: JSR 292 recursive method handle calls inline themselves infinitely
twisti
parents:
1972
diff
changeset
|
117 print_inlining(tty, method, inline_level, bci, msg); |
3d58a4983660
7022998: JSR 292 recursive method handle calls inline themselves infinitely
twisti
parents:
1972
diff
changeset
|
118 } |
3d58a4983660
7022998: JSR 292 recursive method handle calls inline themselves infinitely
twisti
parents:
1972
diff
changeset
|
119 |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
120 // Redefine Classes support |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
121 void mark_on_stack(); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
122 |
2405
3d58a4983660
7022998: JSR 292 recursive method handle calls inline themselves infinitely
twisti
parents:
1972
diff
changeset
|
123 static void print_inline_indent(int inline_level, outputStream* st = tty); |
3d58a4983660
7022998: JSR 292 recursive method handle calls inline themselves infinitely
twisti
parents:
1972
diff
changeset
|
124 |
0 | 125 void print(); |
126 void print_line(); | |
2405
3d58a4983660
7022998: JSR 292 recursive method handle calls inline themselves infinitely
twisti
parents:
1972
diff
changeset
|
127 void print_line_on_error(outputStream* st, char* buf, int buflen); |
1783 | 128 |
0 | 129 void log_task(xmlStream* log); |
130 void log_task_queued(); | |
131 void log_task_start(CompileLog* log); | |
132 void log_task_done(CompileLog* log); | |
133 }; | |
134 | |
135 // CompilerCounters | |
136 // | |
137 // Per Compiler Performance Counters. | |
138 // | |
6197 | 139 class CompilerCounters : public CHeapObj<mtCompiler> { |
0 | 140 |
141 public: | |
142 enum { | |
143 cmname_buffer_length = 160 | |
144 }; | |
145 | |
146 private: | |
147 | |
148 char _current_method[cmname_buffer_length]; | |
149 PerfStringVariable* _perf_current_method; | |
150 | |
151 int _compile_type; | |
152 PerfVariable* _perf_compile_type; | |
153 | |
154 PerfCounter* _perf_time; | |
155 PerfCounter* _perf_compiles; | |
156 | |
157 public: | |
158 CompilerCounters(const char* name, int instance, TRAPS); | |
159 | |
160 // these methods should be called in a thread safe context | |
161 | |
162 void set_current_method(const char* method) { | |
163 strncpy(_current_method, method, (size_t)cmname_buffer_length); | |
164 if (UsePerfData) _perf_current_method->set_value(method); | |
165 } | |
166 | |
167 char* current_method() { return _current_method; } | |
168 | |
169 void set_compile_type(int compile_type) { | |
170 _compile_type = compile_type; | |
171 if (UsePerfData) _perf_compile_type->set_value((jlong)compile_type); | |
172 } | |
173 | |
174 int compile_type() { return _compile_type; } | |
175 | |
176 PerfCounter* time_counter() { return _perf_time; } | |
177 PerfCounter* compile_counter() { return _perf_compiles; } | |
178 }; | |
179 | |
180 // CompileQueue | |
181 // | |
182 // A list of CompileTasks. | |
6197 | 183 class CompileQueue : public CHeapObj<mtCompiler> { |
0 | 184 private: |
185 const char* _name; | |
186 Monitor* _lock; | |
187 | |
188 CompileTask* _first; | |
189 CompileTask* _last; | |
190 | |
1783 | 191 int _size; |
0 | 192 public: |
193 CompileQueue(const char* name, Monitor* lock) { | |
194 _name = name; | |
195 _lock = lock; | |
196 _first = NULL; | |
197 _last = NULL; | |
1783 | 198 _size = 0; |
0 | 199 } |
200 | |
201 const char* name() const { return _name; } | |
202 Monitor* lock() const { return _lock; } | |
203 | |
204 void add(CompileTask* task); | |
1783 | 205 void remove(CompileTask* task); |
206 CompileTask* first() { return _first; } | |
207 CompileTask* last() { return _last; } | |
0 | 208 |
209 CompileTask* get(); | |
210 | |
211 bool is_empty() const { return _first == NULL; } | |
1783 | 212 int size() const { return _size; } |
0 | 213 |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
214 // Redefine Classes support |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
215 void mark_on_stack(); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
216 |
0 | 217 void print(); |
218 }; | |
219 | |
1783 | 220 // CompileTaskWrapper |
221 // | |
222 // Assign this task to the current thread. Deallocate the task | |
223 // when the compilation is complete. | |
224 class CompileTaskWrapper : StackObj { | |
225 public: | |
226 CompileTaskWrapper(CompileTask* task); | |
227 ~CompileTaskWrapper(); | |
228 }; | |
229 | |
0 | 230 |
231 // Compilation | |
232 // | |
233 // The broker for all compilation requests. | |
234 class CompileBroker: AllStatic { | |
235 friend class Threads; | |
236 friend class CompileTaskWrapper; | |
237 | |
238 public: | |
239 enum { | |
240 name_buffer_length = 100 | |
241 }; | |
242 | |
243 // Compile type Information for print_last_compile() and CompilerCounters | |
244 enum { no_compile, normal_compile, osr_compile, native_compile }; | |
245 | |
246 private: | |
247 static bool _initialized; | |
248 static volatile bool _should_block; | |
249 | |
1202 | 250 // This flag can be used to stop compilation or turn it back on |
251 static volatile jint _should_compile_new_jobs; | |
252 | |
0 | 253 // The installed compiler(s) |
254 static AbstractCompiler* _compilers[2]; | |
255 | |
256 // These counters are used for assigning id's to each compilation | |
257 static uint _compilation_id; | |
258 static uint _osr_compilation_id; | |
259 static uint _native_compilation_id; | |
260 | |
261 static int _last_compile_type; | |
262 static int _last_compile_level; | |
263 static char _last_method_compiled[name_buffer_length]; | |
264 | |
1783 | 265 static CompileQueue* _c2_method_queue; |
266 static CompileQueue* _c1_method_queue; | |
0 | 267 static CompileTask* _task_free_list; |
268 | |
269 static GrowableArray<CompilerThread*>* _method_threads; | |
270 | |
271 // performance counters | |
272 static PerfCounter* _perf_total_compilation; | |
273 static PerfCounter* _perf_native_compilation; | |
274 static PerfCounter* _perf_osr_compilation; | |
275 static PerfCounter* _perf_standard_compilation; | |
276 | |
277 static PerfCounter* _perf_total_bailout_count; | |
278 static PerfCounter* _perf_total_invalidated_count; | |
279 static PerfCounter* _perf_total_compile_count; | |
280 static PerfCounter* _perf_total_native_compile_count; | |
281 static PerfCounter* _perf_total_osr_compile_count; | |
282 static PerfCounter* _perf_total_standard_compile_count; | |
283 | |
284 static PerfCounter* _perf_sum_osr_bytes_compiled; | |
285 static PerfCounter* _perf_sum_standard_bytes_compiled; | |
286 static PerfCounter* _perf_sum_nmethod_size; | |
287 static PerfCounter* _perf_sum_nmethod_code_size; | |
288 | |
289 static PerfStringVariable* _perf_last_method; | |
290 static PerfStringVariable* _perf_last_failed_method; | |
291 static PerfStringVariable* _perf_last_invalidated_method; | |
292 static PerfVariable* _perf_last_compile_type; | |
293 static PerfVariable* _perf_last_compile_size; | |
294 static PerfVariable* _perf_last_failed_type; | |
295 static PerfVariable* _perf_last_invalidated_type; | |
296 | |
297 // Timers and counters for generating statistics | |
298 static elapsedTimer _t_total_compilation; | |
299 static elapsedTimer _t_osr_compilation; | |
300 static elapsedTimer _t_standard_compilation; | |
301 | |
302 static int _total_bailout_count; | |
303 static int _total_invalidated_count; | |
304 static int _total_compile_count; | |
305 static int _total_native_compile_count; | |
306 static int _total_osr_compile_count; | |
307 static int _total_standard_compile_count; | |
308 | |
309 static int _sum_osr_bytes_compiled; | |
310 static int _sum_standard_bytes_compiled; | |
311 static int _sum_nmethod_size; | |
312 static int _sum_nmethod_code_size; | |
313 | |
314 static CompilerThread* make_compiler_thread(const char* name, CompileQueue* queue, CompilerCounters* counters, TRAPS); | |
1783 | 315 static void init_compiler_threads(int c1_compiler_count, int c2_compiler_count); |
0 | 316 static bool compilation_is_complete (methodHandle method, int osr_bci, int comp_level); |
317 static bool compilation_is_prohibited(methodHandle method, int osr_bci, int comp_level); | |
318 static uint assign_compile_id (methodHandle method, int osr_bci); | |
319 static bool is_compile_blocking (methodHandle method, int osr_bci); | |
320 static void preload_classes (methodHandle method, TRAPS); | |
321 | |
322 static CompileTask* create_compile_task(CompileQueue* queue, | |
323 int compile_id, | |
324 methodHandle method, | |
325 int osr_bci, | |
326 int comp_level, | |
327 methodHandle hot_method, | |
328 int hot_count, | |
329 const char* comment, | |
330 bool blocking); | |
331 static CompileTask* allocate_task(); | |
332 static void free_task(CompileTask* task); | |
333 static void wait_for_completion(CompileTask* task); | |
334 | |
335 static void invoke_compiler_on_method(CompileTask* task); | |
336 static void set_last_compile(CompilerThread *thread, methodHandle method, bool is_osr, int comp_level); | |
337 static void push_jni_handle_block(); | |
338 static void pop_jni_handle_block(); | |
339 static bool check_break_at(methodHandle method, int compile_id, bool is_osr); | |
340 static void collect_statistics(CompilerThread* thread, elapsedTimer time, CompileTask* task); | |
341 | |
342 static void compile_method_base(methodHandle method, | |
343 int osr_bci, | |
344 int comp_level, | |
345 methodHandle hot_method, | |
346 int hot_count, | |
347 const char* comment, | |
4825
20334ed5ed3c
7131259: compile_method and CompilationPolicy::event shouldn't be declared TRAPS
iveresov
parents:
3939
diff
changeset
|
348 Thread* thread); |
1783 | 349 static CompileQueue* compile_queue(int comp_level) { |
350 if (is_c2_compile(comp_level)) return _c2_method_queue; | |
351 if (is_c1_compile(comp_level)) return _c1_method_queue; | |
352 return NULL; | |
353 } | |
0 | 354 public: |
355 enum { | |
356 // The entry bci used for non-OSR compilations. | |
357 standard_entry_bci = InvocationEntryBci | |
358 }; | |
359 | |
1783 | 360 static AbstractCompiler* compiler(int comp_level) { |
361 if (is_c2_compile(comp_level)) return _compilers[1]; // C2 | |
362 if (is_c1_compile(comp_level)) return _compilers[0]; // C1 | |
363 return NULL; | |
0 | 364 } |
365 | |
1783 | 366 static bool compilation_is_in_queue(methodHandle method, int osr_bci); |
367 static int queue_size(int comp_level) { | |
368 CompileQueue *q = compile_queue(comp_level); | |
369 return q != NULL ? q->size() : 0; | |
370 } | |
0 | 371 static void compilation_init(); |
372 static void init_compiler_thread_log(); | |
1783 | 373 static nmethod* compile_method(methodHandle method, |
374 int osr_bci, | |
375 int comp_level, | |
376 methodHandle hot_method, | |
377 int hot_count, | |
4825
20334ed5ed3c
7131259: compile_method and CompilationPolicy::event shouldn't be declared TRAPS
iveresov
parents:
3939
diff
changeset
|
378 const char* comment, Thread* thread); |
0 | 379 |
380 static void compiler_thread_loop(); | |
381 | |
1202 | 382 static uint get_compilation_id() { return _compilation_id; } |
0 | 383 static bool is_idle(); |
384 | |
385 // Set _should_block. | |
386 // Call this from the VM, with Threads_lock held and a safepoint requested. | |
387 static void set_should_block(); | |
388 | |
389 // Call this from the compiler at convenient points, to poll for _should_block. | |
390 static void maybe_block(); | |
391 | |
1202 | 392 enum { |
393 // Flags for toggling compiler activity | |
394 stop_compilation = 0, | |
395 run_compilation = 1 | |
396 }; | |
397 | |
398 static bool should_compile_new_jobs() { return UseCompiler && (_should_compile_new_jobs == run_compilation); } | |
399 static bool set_should_compile_new_jobs(jint new_state) { | |
400 // Return success if the current caller set it | |
401 jint old = Atomic::cmpxchg(new_state, &_should_compile_new_jobs, 1-new_state); | |
402 return (old == (1-new_state)); | |
403 } | |
404 static void handle_full_code_cache(); | |
405 | |
0 | 406 // Return total compilation ticks |
407 static jlong total_compilation_ticks() { | |
408 return _perf_total_compilation != NULL ? _perf_total_compilation->get_value() : 0; | |
409 } | |
410 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
411 // Redefine Classes support |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
412 static void mark_on_stack(); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
413 |
0 | 414 // Print a detailed accounting of compilation time |
415 static void print_times(); | |
416 | |
417 // Debugging output for failure | |
418 static void print_last_compile(); | |
419 | |
420 static void print_compiler_threads_on(outputStream* st); | |
421 }; | |
1972 | 422 |
423 #endif // SHARE_VM_COMPILER_COMPILEBROKER_HPP |