1 /*
2  * Copyright (c) 1998, 2017, 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_COMPILETASK_HPP
26 #define SHARE_VM_COMPILER_COMPILETASK_HPP
27 
28 #include "ci/ciMethod.hpp"
29 #include "code/nmethod.hpp"
30 #include "compiler/compileLog.hpp"
31 #include "memory/allocation.hpp"
32 #include "utilities/xmlstream.hpp"
33 
34 // CompileTask
35 //
36 // An entry in the compile queue.  It represents a pending or current
37 // compilation.
38 
39 class CompileTask : public CHeapObj<mtCompiler> {
40   friend class VMStructs;
41   friend class JVMCIVMStructs;
42 
43  public:
44   // Different reasons for a compilation
45   // The order is important - Reason_Whitebox and higher can not become
46   // stale, see CompileTask::can_become_stale()
47   // Also mapped to reason_names[]
48   enum CompileReason {
49       Reason_None,
50       Reason_InvocationCount,  // Simple/StackWalk-policy
51       Reason_BackedgeCount,    // Simple/StackWalk-policy
52       Reason_Tiered,           // Tiered-policy
53       Reason_CTW,              // Compile the world
54       Reason_Replay,           // ciReplay
55       Reason_Whitebox,         // Whitebox API
56       Reason_MustBeCompiled,   // Java callHelper, LinkResolver
57       Reason_Bootstrap,        // JVMCI bootstrap
58       Reason_Count
59   };
60 
reason_name(CompileTask::CompileReason compile_reason)61   static const char* reason_name(CompileTask::CompileReason compile_reason) {
62     static const char* reason_names[] = {
63       "no_reason",
64       "count",
65       "backedge_count",
66       "tiered",
67       "CTW",
68       "replay",
69       "whitebox",
70       "must_be_compiled",
71       "bootstrap"
72     };
73     return reason_names[compile_reason];
74   }
75 
76  private:
77   static CompileTask* _task_free_list;
78   Monitor*     _lock;
79   uint         _compile_id;
80   Method*      _method;
81   jobject      _method_holder;
82   int          _osr_bci;
83   bool         _is_complete;
84   bool         _is_success;
85   bool         _is_blocking;
86 #if INCLUDE_JVMCI
87   bool         _has_waiter;
88   // Compiler thread for a blocking JVMCI compilation
89   CompilerThread* _jvmci_compiler_thread;
90 #endif
91   int          _comp_level;
92   int          _num_inlined_bytecodes;
93   nmethodLocker* _code_handle;  // holder of eventual result
94   CompileTask* _next, *_prev;
95   bool         _is_free;
96   // Fields used for logging why the compilation was initiated:
97   jlong        _time_queued;  // time when task was enqueued
98   jlong        _time_started; // time when compilation started
99   Method*      _hot_method;   // which method actually triggered this task
100   jobject      _hot_method_holder;
101   int          _hot_count;    // information about its invocation counter
102   CompileReason _compile_reason;      // more info about the task
103   const char*  _failure_reason;
104 
105  public:
CompileTask()106   CompileTask() {
107     _lock = new Monitor(Mutex::nonleaf+2, "CompileTaskLock");
108   }
109 
110   void initialize(int compile_id, const methodHandle& method, int osr_bci, int comp_level,
111                   const methodHandle& hot_method, int hot_count,
112                   CompileTask::CompileReason compile_reason, bool is_blocking);
113 
114   static CompileTask* allocate();
115   static void         free(CompileTask* task);
116 
compile_id() const117   int          compile_id() const                { return _compile_id; }
method() const118   Method*      method() const                    { return _method; }
hot_method() const119   Method*      hot_method() const                { return _hot_method; }
osr_bci() const120   int          osr_bci() const                   { return _osr_bci; }
is_complete() const121   bool         is_complete() const               { return _is_complete; }
is_blocking() const122   bool         is_blocking() const               { return _is_blocking; }
is_success() const123   bool         is_success() const                { return _is_success; }
can_become_stale() const124   bool         can_become_stale() const          {
125     switch (_compile_reason) {
126       case Reason_BackedgeCount:
127       case Reason_InvocationCount:
128       case Reason_Tiered:
129         return !_is_blocking;
130       default:
131         return false;
132     }
133   }
134 #if INCLUDE_JVMCI
should_wait_for_compilation() const135   bool         should_wait_for_compilation() const {
136     // Wait for blocking compilation to finish.
137     switch (_compile_reason) {
138         case Reason_CTW:
139         case Reason_Replay:
140         case Reason_Whitebox:
141         case Reason_MustBeCompiled:
142         case Reason_Bootstrap:
143           return _is_blocking;
144         default:
145           return false;
146     }
147   }
148 
has_waiter() const149   bool         has_waiter() const                { return _has_waiter; }
clear_waiter()150   void         clear_waiter()                    { _has_waiter = false; }
jvmci_compiler_thread() const151   CompilerThread* jvmci_compiler_thread() const  { return _jvmci_compiler_thread; }
set_jvmci_compiler_thread(CompilerThread * t)152   void         set_jvmci_compiler_thread(CompilerThread* t) {
153     assert(is_blocking(), "must be");
154     assert((t == NULL) != (_jvmci_compiler_thread == NULL), "must be");
155     _jvmci_compiler_thread = t;
156   }
157 #endif
158 
code_handle() const159   nmethodLocker* code_handle() const             { return _code_handle; }
set_code_handle(nmethodLocker * l)160   void         set_code_handle(nmethodLocker* l) { _code_handle = l; }
161   nmethod*     code() const;                     // _code_handle->code()
162   void         set_code(nmethod* nm);            // _code_handle->set_code(nm)
163 
lock() const164   Monitor*     lock() const                      { return _lock; }
165 
mark_complete()166   void         mark_complete()                   { _is_complete = true; }
mark_success()167   void         mark_success()                    { _is_success = true; }
mark_started(jlong time)168   void         mark_started(jlong time)          { _time_started = time; }
169 
comp_level()170   int          comp_level()                      { return _comp_level;}
set_comp_level(int comp_level)171   void         set_comp_level(int comp_level)    { _comp_level = comp_level;}
172 
173   AbstractCompiler* compiler();
174   CompileTask*      select_for_compilation();
175 
num_inlined_bytecodes() const176   int          num_inlined_bytecodes() const     { return _num_inlined_bytecodes; }
set_num_inlined_bytecodes(int n)177   void         set_num_inlined_bytecodes(int n)  { _num_inlined_bytecodes = n; }
178 
next() const179   CompileTask* next() const                      { return _next; }
set_next(CompileTask * next)180   void         set_next(CompileTask* next)       { _next = next; }
prev() const181   CompileTask* prev() const                      { return _prev; }
set_prev(CompileTask * prev)182   void         set_prev(CompileTask* prev)       { _prev = prev; }
is_free() const183   bool         is_free() const                   { return _is_free; }
set_is_free(bool val)184   void         set_is_free(bool val)             { _is_free = val; }
185   bool         is_unloaded() const;
186 
187   // RedefineClasses support
188   void         metadata_do(void f(Metadata*));
189   void         mark_on_stack();
190 
191 private:
192   static void  print_impl(outputStream* st, Method* method, int compile_id, int comp_level,
193                                       bool is_osr_method = false, int osr_bci = -1, bool is_blocking = false,
194                                       const char* msg = NULL, bool short_form = false, bool cr = true,
195                                       jlong time_queued = 0, jlong time_started = 0);
196 
197 public:
198   void         print(outputStream* st = tty, const char* msg = NULL, bool short_form = false, bool cr = true);
199   void         print_ul(const char* msg = NULL);
print(outputStream * st,const nmethod * nm,const char * msg=NULL,bool short_form=false,bool cr=true)200   static void  print(outputStream* st, const nmethod* nm, const char* msg = NULL, bool short_form = false, bool cr = true) {
201     print_impl(st, nm->method(), nm->compile_id(), nm->comp_level(),
202                            nm->is_osr_method(), nm->is_osr_method() ? nm->osr_entry_bci() : -1, /*is_blocking*/ false,
203                            msg, short_form, cr);
204   }
205   static void  print_ul(const nmethod* nm, const char* msg = NULL);
206 
207   static void  print_inline_indent(int inline_level, outputStream* st = tty);
208 
209   void         print_tty();
210   void         print_line_on_error(outputStream* st, char* buf, int buflen);
211 
212   void         log_task(xmlStream* log);
213   void         log_task_queued();
214   void         log_task_start(CompileLog* log);
215   void         log_task_done(CompileLog* log);
216 
set_failure_reason(const char * reason)217   void         set_failure_reason(const char* reason) {
218     _failure_reason = reason;
219   }
220 
221   bool         check_break_at_flags();
222 
223   static void print_inlining_inner(outputStream* st, ciMethod* method, int inline_level, int bci, const char* msg = NULL);
print_inlining_tty(ciMethod * method,int inline_level,int bci,const char * msg=NULL)224   static void print_inlining_tty(ciMethod* method, int inline_level, int bci, const char* msg = NULL) {
225     print_inlining_inner(tty, method, inline_level, bci, msg);
226   }
227   static void print_inlining_ul(ciMethod* method, int inline_level, int bci, const char* msg = NULL);
228 };
229 
230 #endif // SHARE_VM_COMPILER_COMPILETASK_HPP
231