1 /* 2 * Copyright (c) 2021, 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_COMPILER_COMPILERTHREAD_HPP 26 #define SHARE_COMPILER_COMPILERTHREAD_HPP 27 28 #include "runtime/thread.hpp" 29 30 class BufferBlob; 31 class AbstractCompiler; 32 class ciEnv; 33 class CompileThread; 34 class CompileLog; 35 class CompileTask; 36 class CompileQueue; 37 class CompilerCounters; 38 class IdealGraphPrinter; 39 class JVMCIEnv; 40 class JVMCIPrimitiveArray; 41 42 // A thread used for Compilation. 43 class CompilerThread : public JavaThread { 44 friend class VMStructs; 45 private: 46 CompilerCounters* _counters; 47 48 ciEnv* _env; 49 CompileLog* _log; 50 CompileTask* volatile _task; // print_threads_compiling can read this concurrently. 51 CompileQueue* _queue; 52 BufferBlob* _buffer_blob; 53 54 AbstractCompiler* _compiler; 55 TimeStamp _idle_time; 56 57 public: 58 current()59 static CompilerThread* current() { 60 return CompilerThread::cast(JavaThread::current()); 61 } 62 cast(Thread * t)63 static CompilerThread* cast(Thread* t) { 64 assert(t->is_Compiler_thread(), "incorrect cast to CompilerThread"); 65 return static_cast<CompilerThread*>(t); 66 } 67 68 CompilerThread(CompileQueue* queue, CompilerCounters* counters); 69 ~CompilerThread(); 70 is_Compiler_thread() const71 bool is_Compiler_thread() const { return true; } 72 73 virtual bool can_call_java() const; 74 75 // Hide native compiler threads from external view. is_hidden_from_external_view() const76 bool is_hidden_from_external_view() const { return !can_call_java(); } 77 set_compiler(AbstractCompiler * c)78 void set_compiler(AbstractCompiler* c) { _compiler = c; } compiler() const79 AbstractCompiler* compiler() const { return _compiler; } 80 queue() const81 CompileQueue* queue() const { return _queue; } counters() const82 CompilerCounters* counters() const { return _counters; } 83 84 // Get/set the thread's compilation environment. env()85 ciEnv* env() { return _env; } set_env(ciEnv * env)86 void set_env(ciEnv* env) { _env = env; } 87 get_buffer_blob() const88 BufferBlob* get_buffer_blob() const { return _buffer_blob; } set_buffer_blob(BufferBlob * b)89 void set_buffer_blob(BufferBlob* b) { _buffer_blob = b; } 90 91 // Get/set the thread's logging information log()92 CompileLog* log() { return _log; } init_log(CompileLog * log)93 void init_log(CompileLog* log) { 94 // Set once, for good. 95 assert(_log == NULL, "set only once"); 96 _log = log; 97 } 98 start_idle_timer()99 void start_idle_timer() { _idle_time.update(); } idle_time_millis()100 jlong idle_time_millis() { 101 return TimeHelper::counter_to_millis(_idle_time.ticks_since_update()); 102 } 103 104 #ifndef PRODUCT 105 private: 106 IdealGraphPrinter *_ideal_graph_printer; 107 public: ideal_graph_printer()108 IdealGraphPrinter *ideal_graph_printer() { return _ideal_graph_printer; } set_ideal_graph_printer(IdealGraphPrinter * n)109 void set_ideal_graph_printer(IdealGraphPrinter *n) { _ideal_graph_printer = n; } 110 #endif 111 112 // Get/set the thread's current task task()113 CompileTask* task() { return _task; } set_task(CompileTask * task)114 void set_task(CompileTask* task) { _task = task; } 115 116 static void thread_entry(JavaThread* thread, TRAPS); 117 }; 118 119 // Dedicated thread to sweep the code cache 120 class CodeCacheSweeperThread : public JavaThread { 121 CompiledMethod* _scanned_compiled_method; // nmethod being scanned by the sweeper 122 123 static void thread_entry(JavaThread* thread, TRAPS); 124 125 public: 126 CodeCacheSweeperThread(); 127 // Track the nmethod currently being scanned by the sweeper set_scanned_compiled_method(CompiledMethod * cm)128 void set_scanned_compiled_method(CompiledMethod* cm) { 129 assert(_scanned_compiled_method == NULL || cm == NULL, "should reset to NULL before writing a new value"); 130 _scanned_compiled_method = cm; 131 } 132 133 // Hide sweeper thread from external view. is_hidden_from_external_view() const134 bool is_hidden_from_external_view() const { return true; } 135 is_Code_cache_sweeper_thread() const136 bool is_Code_cache_sweeper_thread() const { return true; } 137 138 // Prevent GC from unloading _scanned_compiled_method 139 void oops_do_no_frames(OopClosure* f, CodeBlobClosure* cf); 140 void nmethods_do(CodeBlobClosure* cf); 141 }; 142 143 144 #endif // SHARE_COMPILER_COMPILERTHREAD_HPP 145