1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/share/vm/compiler/compileBroker.hpp Wed Apr 27 01:25:04 2016 +0800 1.3 @@ -0,0 +1,461 @@ 1.4 +/* 1.5 + * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. 1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.7 + * 1.8 + * This code is free software; you can redistribute it and/or modify it 1.9 + * under the terms of the GNU General Public License version 2 only, as 1.10 + * published by the Free Software Foundation. 1.11 + * 1.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 1.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1.15 + * version 2 for more details (a copy is included in the LICENSE file that 1.16 + * accompanied this code). 1.17 + * 1.18 + * You should have received a copy of the GNU General Public License version 1.19 + * 2 along with this work; if not, write to the Free Software Foundation, 1.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1.21 + * 1.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 1.23 + * or visit www.oracle.com if you need additional information or have any 1.24 + * questions. 1.25 + * 1.26 + */ 1.27 + 1.28 +#ifndef SHARE_VM_COMPILER_COMPILEBROKER_HPP 1.29 +#define SHARE_VM_COMPILER_COMPILEBROKER_HPP 1.30 + 1.31 +#include "ci/compilerInterface.hpp" 1.32 +#include "compiler/abstractCompiler.hpp" 1.33 +#include "runtime/perfData.hpp" 1.34 + 1.35 +class nmethod; 1.36 +class nmethodLocker; 1.37 + 1.38 +// CompileTask 1.39 +// 1.40 +// An entry in the compile queue. It represents a pending or current 1.41 +// compilation. 1.42 +class CompileTask : public CHeapObj<mtCompiler> { 1.43 + friend class VMStructs; 1.44 + 1.45 + private: 1.46 + Monitor* _lock; 1.47 + uint _compile_id; 1.48 + Method* _method; 1.49 + jobject _method_holder; 1.50 + int _osr_bci; 1.51 + bool _is_complete; 1.52 + bool _is_success; 1.53 + bool _is_blocking; 1.54 + int _comp_level; 1.55 + int _num_inlined_bytecodes; 1.56 + nmethodLocker* _code_handle; // holder of eventual result 1.57 + CompileTask* _next, *_prev; 1.58 + 1.59 + // Fields used for logging why the compilation was initiated: 1.60 + jlong _time_queued; // in units of os::elapsed_counter() 1.61 + Method* _hot_method; // which method actually triggered this task 1.62 + jobject _hot_method_holder; 1.63 + int _hot_count; // information about its invocation counter 1.64 + const char* _comment; // more info about the task 1.65 + 1.66 + public: 1.67 + CompileTask() { 1.68 + _lock = new Monitor(Mutex::nonleaf+2, "CompileTaskLock"); 1.69 + } 1.70 + 1.71 + void initialize(int compile_id, methodHandle method, int osr_bci, int comp_level, 1.72 + methodHandle hot_method, int hot_count, const char* comment, 1.73 + bool is_blocking); 1.74 + 1.75 + void free(); 1.76 + 1.77 + int compile_id() const { return _compile_id; } 1.78 + Method* method() const { return _method; } 1.79 + int osr_bci() const { return _osr_bci; } 1.80 + bool is_complete() const { return _is_complete; } 1.81 + bool is_blocking() const { return _is_blocking; } 1.82 + bool is_success() const { return _is_success; } 1.83 + 1.84 + nmethodLocker* code_handle() const { return _code_handle; } 1.85 + void set_code_handle(nmethodLocker* l) { _code_handle = l; } 1.86 + nmethod* code() const; // _code_handle->code() 1.87 + void set_code(nmethod* nm); // _code_handle->set_code(nm) 1.88 + 1.89 + Monitor* lock() const { return _lock; } 1.90 + 1.91 + void mark_complete() { _is_complete = true; } 1.92 + void mark_success() { _is_success = true; } 1.93 + 1.94 + int comp_level() { return _comp_level;} 1.95 + void set_comp_level(int comp_level) { _comp_level = comp_level;} 1.96 + 1.97 + int num_inlined_bytecodes() const { return _num_inlined_bytecodes; } 1.98 + void set_num_inlined_bytecodes(int n) { _num_inlined_bytecodes = n; } 1.99 + 1.100 + CompileTask* next() const { return _next; } 1.101 + void set_next(CompileTask* next) { _next = next; } 1.102 + CompileTask* prev() const { return _prev; } 1.103 + void set_prev(CompileTask* prev) { _prev = prev; } 1.104 + 1.105 +private: 1.106 + static void print_compilation_impl(outputStream* st, Method* method, int compile_id, int comp_level, 1.107 + bool is_osr_method = false, int osr_bci = -1, bool is_blocking = false, 1.108 + const char* msg = NULL, bool short_form = false); 1.109 + 1.110 +public: 1.111 + void print_compilation(outputStream* st = tty, const char* msg = NULL, bool short_form = false); 1.112 + static void print_compilation(outputStream* st, const nmethod* nm, const char* msg = NULL, bool short_form = false) { 1.113 + print_compilation_impl(st, nm->method(), nm->compile_id(), nm->comp_level(), 1.114 + nm->is_osr_method(), nm->is_osr_method() ? nm->osr_entry_bci() : -1, /*is_blocking*/ false, 1.115 + msg, short_form); 1.116 + } 1.117 + 1.118 + static void print_inlining(outputStream* st, ciMethod* method, int inline_level, int bci, const char* msg = NULL); 1.119 + static void print_inlining(ciMethod* method, int inline_level, int bci, const char* msg = NULL) { 1.120 + print_inlining(tty, method, inline_level, bci, msg); 1.121 + } 1.122 + 1.123 + // Redefine Classes support 1.124 + void mark_on_stack(); 1.125 + 1.126 + static void print_inline_indent(int inline_level, outputStream* st = tty); 1.127 + 1.128 + void print(); 1.129 + void print_line(); 1.130 + void print_line_on_error(outputStream* st, char* buf, int buflen); 1.131 + 1.132 + void log_task(xmlStream* log); 1.133 + void log_task_queued(); 1.134 + void log_task_start(CompileLog* log); 1.135 + void log_task_done(CompileLog* log); 1.136 +}; 1.137 + 1.138 +// CompilerCounters 1.139 +// 1.140 +// Per Compiler Performance Counters. 1.141 +// 1.142 +class CompilerCounters : public CHeapObj<mtCompiler> { 1.143 + 1.144 + public: 1.145 + enum { 1.146 + cmname_buffer_length = 160 1.147 + }; 1.148 + 1.149 + private: 1.150 + 1.151 + char _current_method[cmname_buffer_length]; 1.152 + PerfStringVariable* _perf_current_method; 1.153 + 1.154 + int _compile_type; 1.155 + PerfVariable* _perf_compile_type; 1.156 + 1.157 + PerfCounter* _perf_time; 1.158 + PerfCounter* _perf_compiles; 1.159 + 1.160 + public: 1.161 + CompilerCounters(const char* name, int instance, TRAPS); 1.162 + 1.163 + // these methods should be called in a thread safe context 1.164 + 1.165 + void set_current_method(const char* method) { 1.166 + strncpy(_current_method, method, (size_t)cmname_buffer_length); 1.167 + if (UsePerfData) _perf_current_method->set_value(method); 1.168 + } 1.169 + 1.170 + char* current_method() { return _current_method; } 1.171 + 1.172 + void set_compile_type(int compile_type) { 1.173 + _compile_type = compile_type; 1.174 + if (UsePerfData) _perf_compile_type->set_value((jlong)compile_type); 1.175 + } 1.176 + 1.177 + int compile_type() { return _compile_type; } 1.178 + 1.179 + PerfCounter* time_counter() { return _perf_time; } 1.180 + PerfCounter* compile_counter() { return _perf_compiles; } 1.181 +}; 1.182 + 1.183 +// CompileQueue 1.184 +// 1.185 +// A list of CompileTasks. 1.186 +class CompileQueue : public CHeapObj<mtCompiler> { 1.187 + private: 1.188 + const char* _name; 1.189 + Monitor* _lock; 1.190 + 1.191 + CompileTask* _first; 1.192 + CompileTask* _last; 1.193 + 1.194 + int _size; 1.195 + public: 1.196 + CompileQueue(const char* name, Monitor* lock) { 1.197 + _name = name; 1.198 + _lock = lock; 1.199 + _first = NULL; 1.200 + _last = NULL; 1.201 + _size = 0; 1.202 + } 1.203 + 1.204 + const char* name() const { return _name; } 1.205 + Monitor* lock() const { return _lock; } 1.206 + 1.207 + void add(CompileTask* task); 1.208 + void remove(CompileTask* task); 1.209 + CompileTask* first() { return _first; } 1.210 + CompileTask* last() { return _last; } 1.211 + 1.212 + CompileTask* get(); 1.213 + 1.214 + bool is_empty() const { return _first == NULL; } 1.215 + int size() const { return _size; } 1.216 + 1.217 + // Redefine Classes support 1.218 + void mark_on_stack(); 1.219 + void delete_all(); 1.220 + void print(); 1.221 + 1.222 + ~CompileQueue() { 1.223 + assert (is_empty(), " Compile Queue must be empty"); 1.224 + } 1.225 +}; 1.226 + 1.227 +// CompileTaskWrapper 1.228 +// 1.229 +// Assign this task to the current thread. Deallocate the task 1.230 +// when the compilation is complete. 1.231 +class CompileTaskWrapper : StackObj { 1.232 +public: 1.233 + CompileTaskWrapper(CompileTask* task); 1.234 + ~CompileTaskWrapper(); 1.235 +}; 1.236 + 1.237 + 1.238 +// Compilation 1.239 +// 1.240 +// The broker for all compilation requests. 1.241 +class CompileBroker: AllStatic { 1.242 + friend class Threads; 1.243 + friend class CompileTaskWrapper; 1.244 + 1.245 + public: 1.246 + enum { 1.247 + name_buffer_length = 100 1.248 + }; 1.249 + 1.250 + // Compile type Information for print_last_compile() and CompilerCounters 1.251 + enum { no_compile, normal_compile, osr_compile, native_compile }; 1.252 + static int assign_compile_id (methodHandle method, int osr_bci); 1.253 + 1.254 + 1.255 + private: 1.256 + static bool _initialized; 1.257 + static volatile bool _should_block; 1.258 + 1.259 + // This flag can be used to stop compilation or turn it back on 1.260 + static volatile jint _should_compile_new_jobs; 1.261 + 1.262 + // The installed compiler(s) 1.263 + static AbstractCompiler* _compilers[2]; 1.264 + 1.265 + // These counters are used for assigning id's to each compilation 1.266 + static volatile jint _compilation_id; 1.267 + static volatile jint _osr_compilation_id; 1.268 + 1.269 + static int _last_compile_type; 1.270 + static int _last_compile_level; 1.271 + static char _last_method_compiled[name_buffer_length]; 1.272 + 1.273 + static CompileQueue* _c2_method_queue; 1.274 + static CompileQueue* _c1_method_queue; 1.275 + static CompileTask* _task_free_list; 1.276 + 1.277 + static GrowableArray<CompilerThread*>* _compiler_threads; 1.278 + 1.279 + // performance counters 1.280 + static PerfCounter* _perf_total_compilation; 1.281 + static PerfCounter* _perf_native_compilation; 1.282 + static PerfCounter* _perf_osr_compilation; 1.283 + static PerfCounter* _perf_standard_compilation; 1.284 + 1.285 + static PerfCounter* _perf_total_bailout_count; 1.286 + static PerfCounter* _perf_total_invalidated_count; 1.287 + static PerfCounter* _perf_total_compile_count; 1.288 + static PerfCounter* _perf_total_native_compile_count; 1.289 + static PerfCounter* _perf_total_osr_compile_count; 1.290 + static PerfCounter* _perf_total_standard_compile_count; 1.291 + 1.292 + static PerfCounter* _perf_sum_osr_bytes_compiled; 1.293 + static PerfCounter* _perf_sum_standard_bytes_compiled; 1.294 + static PerfCounter* _perf_sum_nmethod_size; 1.295 + static PerfCounter* _perf_sum_nmethod_code_size; 1.296 + 1.297 + static PerfStringVariable* _perf_last_method; 1.298 + static PerfStringVariable* _perf_last_failed_method; 1.299 + static PerfStringVariable* _perf_last_invalidated_method; 1.300 + static PerfVariable* _perf_last_compile_type; 1.301 + static PerfVariable* _perf_last_compile_size; 1.302 + static PerfVariable* _perf_last_failed_type; 1.303 + static PerfVariable* _perf_last_invalidated_type; 1.304 + 1.305 + // Timers and counters for generating statistics 1.306 + static elapsedTimer _t_total_compilation; 1.307 + static elapsedTimer _t_osr_compilation; 1.308 + static elapsedTimer _t_standard_compilation; 1.309 + 1.310 + static int _total_compile_count; 1.311 + static int _total_bailout_count; 1.312 + static int _total_invalidated_count; 1.313 + static int _total_native_compile_count; 1.314 + static int _total_osr_compile_count; 1.315 + static int _total_standard_compile_count; 1.316 + static int _sum_osr_bytes_compiled; 1.317 + static int _sum_standard_bytes_compiled; 1.318 + static int _sum_nmethod_size; 1.319 + static int _sum_nmethod_code_size; 1.320 + static long _peak_compilation_time; 1.321 + 1.322 + static volatile jint _print_compilation_warning; 1.323 + 1.324 + static CompilerThread* make_compiler_thread(const char* name, CompileQueue* queue, CompilerCounters* counters, AbstractCompiler* comp, TRAPS); 1.325 + static void init_compiler_threads(int c1_compiler_count, int c2_compiler_count); 1.326 + static bool compilation_is_complete (methodHandle method, int osr_bci, int comp_level); 1.327 + static bool compilation_is_prohibited(methodHandle method, int osr_bci, int comp_level); 1.328 + static bool is_compile_blocking (methodHandle method, int osr_bci); 1.329 + static void preload_classes (methodHandle method, TRAPS); 1.330 + 1.331 + static CompileTask* create_compile_task(CompileQueue* queue, 1.332 + int compile_id, 1.333 + methodHandle method, 1.334 + int osr_bci, 1.335 + int comp_level, 1.336 + methodHandle hot_method, 1.337 + int hot_count, 1.338 + const char* comment, 1.339 + bool blocking); 1.340 + static CompileTask* allocate_task(); 1.341 + static void free_task(CompileTask* task); 1.342 + static void wait_for_completion(CompileTask* task); 1.343 + 1.344 + static void invoke_compiler_on_method(CompileTask* task); 1.345 + static void set_last_compile(CompilerThread *thread, methodHandle method, bool is_osr, int comp_level); 1.346 + static void push_jni_handle_block(); 1.347 + static void pop_jni_handle_block(); 1.348 + static bool check_break_at(methodHandle method, int compile_id, bool is_osr); 1.349 + static void collect_statistics(CompilerThread* thread, elapsedTimer time, CompileTask* task); 1.350 + 1.351 + static void compile_method_base(methodHandle method, 1.352 + int osr_bci, 1.353 + int comp_level, 1.354 + methodHandle hot_method, 1.355 + int hot_count, 1.356 + const char* comment, 1.357 + Thread* thread); 1.358 + static CompileQueue* compile_queue(int comp_level) { 1.359 + if (is_c2_compile(comp_level)) return _c2_method_queue; 1.360 + if (is_c1_compile(comp_level)) return _c1_method_queue; 1.361 + return NULL; 1.362 + } 1.363 + static bool init_compiler_runtime(); 1.364 + static void shutdown_compiler_runtime(AbstractCompiler* comp, CompilerThread* thread); 1.365 + 1.366 + public: 1.367 + enum { 1.368 + // The entry bci used for non-OSR compilations. 1.369 + standard_entry_bci = InvocationEntryBci 1.370 + }; 1.371 + 1.372 + static AbstractCompiler* compiler(int comp_level) { 1.373 + if (is_c2_compile(comp_level)) return _compilers[1]; // C2 1.374 + if (is_c1_compile(comp_level)) return _compilers[0]; // C1 1.375 + return NULL; 1.376 + } 1.377 + 1.378 + static bool compilation_is_in_queue(methodHandle method, int osr_bci); 1.379 + static int queue_size(int comp_level) { 1.380 + CompileQueue *q = compile_queue(comp_level); 1.381 + return q != NULL ? q->size() : 0; 1.382 + } 1.383 + static void compilation_init(); 1.384 + static void init_compiler_thread_log(); 1.385 + static nmethod* compile_method(methodHandle method, 1.386 + int osr_bci, 1.387 + int comp_level, 1.388 + methodHandle hot_method, 1.389 + int hot_count, 1.390 + const char* comment, Thread* thread); 1.391 + 1.392 + static void compiler_thread_loop(); 1.393 + static uint get_compilation_id() { return _compilation_id; } 1.394 + 1.395 + // Set _should_block. 1.396 + // Call this from the VM, with Threads_lock held and a safepoint requested. 1.397 + static void set_should_block(); 1.398 + 1.399 + // Call this from the compiler at convenient points, to poll for _should_block. 1.400 + static void maybe_block(); 1.401 + 1.402 + enum { 1.403 + // Flags for toggling compiler activity 1.404 + stop_compilation = 0, 1.405 + run_compilation = 1, 1.406 + shutdown_compilaton = 2 1.407 + }; 1.408 + 1.409 + static bool should_compile_new_jobs() { return UseCompiler && (_should_compile_new_jobs == run_compilation); } 1.410 + static bool set_should_compile_new_jobs(jint new_state) { 1.411 + // Return success if the current caller set it 1.412 + jint old = Atomic::cmpxchg(new_state, &_should_compile_new_jobs, 1-new_state); 1.413 + return (old == (1-new_state)); 1.414 + } 1.415 + 1.416 + static void disable_compilation_forever() { 1.417 + UseCompiler = false; 1.418 + AlwaysCompileLoopMethods = false; 1.419 + Atomic::xchg(shutdown_compilaton, &_should_compile_new_jobs); 1.420 + } 1.421 + 1.422 + static bool is_compilation_disabled_forever() { 1.423 + return _should_compile_new_jobs == shutdown_compilaton; 1.424 + } 1.425 + static void handle_full_code_cache(); 1.426 + // Ensures that warning is only printed once. 1.427 + static bool should_print_compiler_warning() { 1.428 + jint old = Atomic::cmpxchg(1, &_print_compilation_warning, 0); 1.429 + return old == 0; 1.430 + } 1.431 + // Return total compilation ticks 1.432 + static jlong total_compilation_ticks() { 1.433 + return _perf_total_compilation != NULL ? _perf_total_compilation->get_value() : 0; 1.434 + } 1.435 + 1.436 + // Redefine Classes support 1.437 + static void mark_on_stack(); 1.438 + 1.439 + // Print a detailed accounting of compilation time 1.440 + static void print_times(); 1.441 + 1.442 + // Debugging output for failure 1.443 + static void print_last_compile(); 1.444 + 1.445 + static void print_compiler_threads_on(outputStream* st); 1.446 + 1.447 + // compiler name for debugging 1.448 + static const char* compiler_name(int comp_level); 1.449 + 1.450 + static int get_total_compile_count() { return _total_compile_count; } 1.451 + static int get_total_bailout_count() { return _total_bailout_count; } 1.452 + static int get_total_invalidated_count() { return _total_invalidated_count; } 1.453 + static int get_total_native_compile_count() { return _total_native_compile_count; } 1.454 + static int get_total_osr_compile_count() { return _total_osr_compile_count; } 1.455 + static int get_total_standard_compile_count() { return _total_standard_compile_count; } 1.456 + static int get_sum_osr_bytes_compiled() { return _sum_osr_bytes_compiled; } 1.457 + static int get_sum_standard_bytes_compiled() { return _sum_standard_bytes_compiled; } 1.458 + static int get_sum_nmethod_size() { return _sum_nmethod_size;} 1.459 + static int get_sum_nmethod_code_size() { return _sum_nmethod_code_size; } 1.460 + static long get_peak_compilation_time() { return _peak_compilation_time; } 1.461 + static long get_total_compilation_time() { return _t_total_compilation.milliseconds(); } 1.462 +}; 1.463 + 1.464 +#endif // SHARE_VM_COMPILER_COMPILEBROKER_HPP