compileBroker.hpp revision 3602:da91efe96a93
1/*
2 * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
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 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
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
32class nmethod;
33class nmethodLocker;
34
35// CompileTask
36//
37// An entry in the compile queue.  It represents a pending or current
38// compilation.
39class CompileTask : public CHeapObj<mtCompiler> {
40  friend class VMStructs;
41
42 private:
43  Monitor*     _lock;
44  uint         _compile_id;
45  Method*      _method;
46  jobject      _method_loader;
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
54  CompileTask* _next, *_prev;
55
56  // Fields used for logging why the compilation was initiated:
57  jlong        _time_queued;  // in units of os::elapsed_counter()
58  Method*      _hot_method;   // which method actually triggered this task
59  jobject      _hot_method_loader;
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; }
75  Method*      method() const                    { return _method; }
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; }
99  CompileTask* prev() const                      { return _prev; }
100  void         set_prev(CompileTask* prev)       { _prev = prev; }
101
102private:
103  static void  print_compilation_impl(outputStream* st, Method* method, int compile_id, int comp_level,
104                                      bool is_osr_method = false, int osr_bci = -1, bool is_blocking = false,
105                                      const char* msg = NULL, bool short_form = false);
106
107public:
108  void         print_compilation(outputStream* st = tty, bool short_form = false);
109  static void  print_compilation(outputStream* st, const nmethod* nm, const char* msg = NULL, bool short_form = false) {
110    print_compilation_impl(st, nm->method(), nm->compile_id(), nm->comp_level(),
111                           nm->is_osr_method(), nm->is_osr_method() ? nm->osr_entry_bci() : -1, /*is_blocking*/ false,
112                           msg, short_form);
113  }
114
115  static void  print_inlining(outputStream* st, ciMethod* method, int inline_level, int bci, const char* msg = NULL);
116  static void  print_inlining(ciMethod* method, int inline_level, int bci, const char* msg = NULL) {
117    print_inlining(tty, method, inline_level, bci, msg);
118  }
119
120  // Redefine Classes support
121  void mark_on_stack();
122
123  static void  print_inline_indent(int inline_level, outputStream* st = tty);
124
125  void         print();
126  void         print_line();
127  void         print_line_on_error(outputStream* st, char* buf, int buflen);
128
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//
139class CompilerCounters : public CHeapObj<mtCompiler> {
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.
183class CompileQueue : public CHeapObj<mtCompiler> {
184 private:
185  const char* _name;
186  Monitor*    _lock;
187
188  CompileTask* _first;
189  CompileTask* _last;
190
191  int _size;
192 public:
193  CompileQueue(const char* name, Monitor* lock) {
194    _name = name;
195    _lock = lock;
196    _first = NULL;
197    _last = NULL;
198    _size = 0;
199  }
200
201  const char*  name() const                      { return _name; }
202  Monitor*     lock() const                      { return _lock; }
203
204  void         add(CompileTask* task);
205  void         remove(CompileTask* task);
206  CompileTask* first()                           { return _first; }
207  CompileTask* last()                            { return _last;  }
208
209  CompileTask* get();
210
211  bool         is_empty() const                  { return _first == NULL; }
212  int          size()     const                  { return _size;          }
213
214  // Redefine Classes support
215  void mark_on_stack();
216
217  void         print();
218};
219
220// CompileTaskWrapper
221//
222// Assign this task to the current thread.  Deallocate the task
223// when the compilation is complete.
224class CompileTaskWrapper : StackObj {
225public:
226  CompileTaskWrapper(CompileTask* task);
227  ~CompileTaskWrapper();
228};
229
230
231// Compilation
232//
233// The broker for all compilation requests.
234class 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
250  // This flag can be used to stop compilation or turn it back on
251  static volatile jint _should_compile_new_jobs;
252
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
265  static CompileQueue* _c2_method_queue;
266  static CompileQueue* _c1_method_queue;
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);
315  static void init_compiler_threads(int c1_compiler_count, int c2_compiler_count);
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,
348                                  Thread* thread);
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  }
354 public:
355  enum {
356    // The entry bci used for non-OSR compilations.
357    standard_entry_bci = InvocationEntryBci
358  };
359
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;
364  }
365
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  }
371  static void compilation_init();
372  static void init_compiler_thread_log();
373  static nmethod* compile_method(methodHandle method,
374                                 int osr_bci,
375                                 int comp_level,
376                                 methodHandle hot_method,
377                                 int hot_count,
378                                 const char* comment, Thread* thread);
379
380  static void compiler_thread_loop();
381
382  static uint get_compilation_id() { return _compilation_id; }
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
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
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
411  // Redefine Classes support
412  static void mark_on_stack();
413
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};
422
423#endif // SHARE_VM_COMPILER_COMPILEBROKER_HPP
424