src/share/vm/compiler/compileBroker.hpp

changeset 0
f90c822e73f8
child 1
2d8a650513c2
     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

mercurial