Path: blob/aarch64-shenandoah-jdk8u272-b10/hotspot/src/share/vm/compiler/compileBroker.hpp
32285 views
/*1* Copyright (c) 1999, 2019, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*22*/2324#ifndef SHARE_VM_COMPILER_COMPILEBROKER_HPP25#define SHARE_VM_COMPILER_COMPILEBROKER_HPP2627#include "ci/compilerInterface.hpp"28#include "compiler/abstractCompiler.hpp"29#include "runtime/perfData.hpp"3031class nmethod;32class nmethodLocker;3334// CompileTask35//36// An entry in the compile queue. It represents a pending or current37// compilation.38class CompileTask : public CHeapObj<mtCompiler> {39friend class VMStructs;4041private:42static CompileTask* _task_free_list;43#ifdef ASSERT44static int _num_allocated_tasks;45#endif4647Monitor* _lock;48uint _compile_id;49Method* _method;50jobject _method_holder;51int _osr_bci;52bool _is_complete;53bool _is_success;54bool _is_blocking;55int _comp_level;56int _num_inlined_bytecodes;57nmethodLocker* _code_handle; // holder of eventual result58CompileTask* _next, *_prev;59bool _is_free;60// Fields used for logging why the compilation was initiated:61jlong _time_queued; // in units of os::elapsed_counter()62Method* _hot_method; // which method actually triggered this task63jobject _hot_method_holder;64int _hot_count; // information about its invocation counter65const char* _comment; // more info about the task66const char* _failure_reason;6768public:69CompileTask() {70_lock = new Monitor(Mutex::nonleaf+2, "CompileTaskLock");71}7273void initialize(int compile_id, methodHandle method, int osr_bci, int comp_level,74methodHandle hot_method, int hot_count, const char* comment,75bool is_blocking);7677static CompileTask* allocate();78static void free(CompileTask* task);7980int compile_id() const { return _compile_id; }81Method* method() const { return _method; }82int osr_bci() const { return _osr_bci; }83bool is_complete() const { return _is_complete; }84bool is_blocking() const { return _is_blocking; }85bool is_success() const { return _is_success; }8687nmethodLocker* code_handle() const { return _code_handle; }88void set_code_handle(nmethodLocker* l) { _code_handle = l; }89nmethod* code() const; // _code_handle->code()90void set_code(nmethod* nm); // _code_handle->set_code(nm)9192Monitor* lock() const { return _lock; }9394void mark_complete() { _is_complete = true; }95void mark_success() { _is_success = true; }9697int comp_level() { return _comp_level;}98void set_comp_level(int comp_level) { _comp_level = comp_level;}99100int num_inlined_bytecodes() const { return _num_inlined_bytecodes; }101void set_num_inlined_bytecodes(int n) { _num_inlined_bytecodes = n; }102103CompileTask* next() const { return _next; }104void set_next(CompileTask* next) { _next = next; }105CompileTask* prev() const { return _prev; }106void set_prev(CompileTask* prev) { _prev = prev; }107bool is_free() const { return _is_free; }108void set_is_free(bool val) { _is_free = val; }109110private:111static void print_compilation_impl(outputStream* st, Method* method, int compile_id, int comp_level,112bool is_osr_method = false, int osr_bci = -1, bool is_blocking = false,113const char* msg = NULL, bool short_form = false);114115public:116void print_compilation(outputStream* st = tty, const char* msg = NULL, bool short_form = false);117static void print_compilation(outputStream* st, const nmethod* nm, const char* msg = NULL, bool short_form = false) {118print_compilation_impl(st, nm->method(), nm->compile_id(), nm->comp_level(),119nm->is_osr_method(), nm->is_osr_method() ? nm->osr_entry_bci() : -1, /*is_blocking*/ false,120msg, short_form);121}122123static void print_inlining(outputStream* st, ciMethod* method, int inline_level, int bci, const char* msg = NULL);124static void print_inlining(ciMethod* method, int inline_level, int bci, const char* msg = NULL) {125print_inlining(tty, method, inline_level, bci, msg);126}127128// Redefine Classes support129void mark_on_stack();130131static void print_inline_indent(int inline_level, outputStream* st = tty);132133void print();134void print_line();135void print_line_on_error(outputStream* st, char* buf, int buflen);136137void log_task(xmlStream* log);138void log_task_queued();139void log_task_start(CompileLog* log);140void log_task_done(CompileLog* log);141142void set_failure_reason(const char* reason) {143_failure_reason = reason;144}145};146147// CompilerCounters148//149// Per Compiler Performance Counters.150//151class CompilerCounters : public CHeapObj<mtCompiler> {152153public:154enum {155cmname_buffer_length = 160156};157158private:159160char _current_method[cmname_buffer_length];161PerfStringVariable* _perf_current_method;162163int _compile_type;164PerfVariable* _perf_compile_type;165166PerfCounter* _perf_time;167PerfCounter* _perf_compiles;168169public:170CompilerCounters(const char* name, int instance, TRAPS);171172// these methods should be called in a thread safe context173174void set_current_method(const char* method) {175strncpy(_current_method, method, (size_t)cmname_buffer_length-1);176_current_method[cmname_buffer_length-1] = '\0';177if (UsePerfData) _perf_current_method->set_value(method);178}179180char* current_method() { return _current_method; }181182void set_compile_type(int compile_type) {183_compile_type = compile_type;184if (UsePerfData) _perf_compile_type->set_value((jlong)compile_type);185}186187int compile_type() { return _compile_type; }188189PerfCounter* time_counter() { return _perf_time; }190PerfCounter* compile_counter() { return _perf_compiles; }191};192193// CompileQueue194//195// A list of CompileTasks.196class CompileQueue : public CHeapObj<mtCompiler> {197private:198const char* _name;199Monitor* _lock;200201CompileTask* _first;202CompileTask* _last;203204CompileTask* _first_stale;205206int _size;207208void purge_stale_tasks();209public:210CompileQueue(const char* name, Monitor* lock) {211_name = name;212_lock = lock;213_first = NULL;214_last = NULL;215_size = 0;216_first_stale = NULL;217}218219const char* name() const { return _name; }220Monitor* lock() const { return _lock; }221222void add(CompileTask* task);223void remove(CompileTask* task);224void remove_and_mark_stale(CompileTask* task);225CompileTask* first() { return _first; }226CompileTask* last() { return _last; }227228CompileTask* get();229230bool is_empty() const { return _first == NULL; }231int size() const { return _size; }232233234// Redefine Classes support235void mark_on_stack();236void free_all();237NOT_PRODUCT (void print();)238239~CompileQueue() {240assert (is_empty(), " Compile Queue must be empty");241}242};243244// CompileTaskWrapper245//246// Assign this task to the current thread. Deallocate the task247// when the compilation is complete.248class CompileTaskWrapper : StackObj {249public:250CompileTaskWrapper(CompileTask* task);251~CompileTaskWrapper();252};253254255// Compilation256//257// The broker for all compilation requests.258class CompileBroker: AllStatic {259friend class Threads;260friend class CompileTaskWrapper;261262public:263enum {264name_buffer_length = 100265};266267// Compile type Information for print_last_compile() and CompilerCounters268enum { no_compile, normal_compile, osr_compile, native_compile };269static int assign_compile_id (methodHandle method, int osr_bci);270271272private:273static bool _initialized;274static volatile bool _should_block;275276// This flag can be used to stop compilation or turn it back on277static volatile jint _should_compile_new_jobs;278279// The installed compiler(s)280static AbstractCompiler* _compilers[2];281282// These counters are used for assigning id's to each compilation283static volatile jint _compilation_id;284static volatile jint _osr_compilation_id;285286static int _last_compile_type;287static int _last_compile_level;288static char _last_method_compiled[name_buffer_length];289290static CompileQueue* _c2_compile_queue;291static CompileQueue* _c1_compile_queue;292293static GrowableArray<CompilerThread*>* _compiler_threads;294295// performance counters296static PerfCounter* _perf_total_compilation;297static PerfCounter* _perf_native_compilation;298static PerfCounter* _perf_osr_compilation;299static PerfCounter* _perf_standard_compilation;300301static PerfCounter* _perf_total_bailout_count;302static PerfCounter* _perf_total_invalidated_count;303static PerfCounter* _perf_total_compile_count;304static PerfCounter* _perf_total_native_compile_count;305static PerfCounter* _perf_total_osr_compile_count;306static PerfCounter* _perf_total_standard_compile_count;307308static PerfCounter* _perf_sum_osr_bytes_compiled;309static PerfCounter* _perf_sum_standard_bytes_compiled;310static PerfCounter* _perf_sum_nmethod_size;311static PerfCounter* _perf_sum_nmethod_code_size;312313static PerfStringVariable* _perf_last_method;314static PerfStringVariable* _perf_last_failed_method;315static PerfStringVariable* _perf_last_invalidated_method;316static PerfVariable* _perf_last_compile_type;317static PerfVariable* _perf_last_compile_size;318static PerfVariable* _perf_last_failed_type;319static PerfVariable* _perf_last_invalidated_type;320321// Timers and counters for generating statistics322static elapsedTimer _t_total_compilation;323static elapsedTimer _t_osr_compilation;324static elapsedTimer _t_standard_compilation;325326static int _total_compile_count;327static int _total_bailout_count;328static int _total_invalidated_count;329static int _total_native_compile_count;330static int _total_osr_compile_count;331static int _total_standard_compile_count;332static int _sum_osr_bytes_compiled;333static int _sum_standard_bytes_compiled;334static int _sum_nmethod_size;335static int _sum_nmethod_code_size;336static long _peak_compilation_time;337338static volatile jint _print_compilation_warning;339340static CompilerThread* make_compiler_thread(const char* name, CompileQueue* queue, CompilerCounters* counters, AbstractCompiler* comp, TRAPS);341static void init_compiler_threads(int c1_compiler_count, int c2_compiler_count);342static bool compilation_is_prohibited(methodHandle method, int osr_bci, int comp_level);343static bool is_compile_blocking ();344static void preload_classes (methodHandle method, TRAPS);345346static CompileTask* create_compile_task(CompileQueue* queue,347int compile_id,348methodHandle method,349int osr_bci,350int comp_level,351methodHandle hot_method,352int hot_count,353const char* comment,354bool blocking);355static void wait_for_completion(CompileTask* task);356357static void invoke_compiler_on_method(CompileTask* task);358static void set_last_compile(CompilerThread *thread, methodHandle method, bool is_osr, int comp_level);359static void push_jni_handle_block();360static void pop_jni_handle_block();361static bool check_break_at(methodHandle method, int compile_id, bool is_osr);362static void collect_statistics(CompilerThread* thread, elapsedTimer time, CompileTask* task);363364static void compile_method_base(methodHandle method,365int osr_bci,366int comp_level,367methodHandle hot_method,368int hot_count,369const char* comment,370Thread* thread);371static CompileQueue* compile_queue(int comp_level) {372if (is_c2_compile(comp_level)) return _c2_compile_queue;373if (is_c1_compile(comp_level)) return _c1_compile_queue;374return NULL;375}376static bool init_compiler_runtime();377static void shutdown_compiler_runtime(AbstractCompiler* comp, CompilerThread* thread);378379public:380enum {381// The entry bci used for non-OSR compilations.382standard_entry_bci = InvocationEntryBci383};384385static AbstractCompiler* compiler(int comp_level) {386if (is_c2_compile(comp_level)) return _compilers[1]; // C2387if (is_c1_compile(comp_level)) return _compilers[0]; // C1388return NULL;389}390391static bool compilation_is_complete(methodHandle method, int osr_bci, int comp_level);392static bool compilation_is_in_queue(methodHandle method);393static int queue_size(int comp_level) {394CompileQueue *q = compile_queue(comp_level);395return q != NULL ? q->size() : 0;396}397static void compilation_init();398static void init_compiler_thread_log();399static nmethod* compile_method(methodHandle method,400int osr_bci,401int comp_level,402methodHandle hot_method,403int hot_count,404const char* comment, Thread* thread);405406static void compiler_thread_loop();407static uint get_compilation_id() { return _compilation_id; }408409// Set _should_block.410// Call this from the VM, with Threads_lock held and a safepoint requested.411static void set_should_block();412413// Call this from the compiler at convenient points, to poll for _should_block.414static void maybe_block();415416enum {417// Flags for toggling compiler activity418stop_compilation = 0,419run_compilation = 1,420shutdown_compilaton = 2421};422423static bool should_compile_new_jobs() { return UseCompiler && (_should_compile_new_jobs == run_compilation); }424static bool set_should_compile_new_jobs(jint new_state) {425// Return success if the current caller set it426jint old = Atomic::cmpxchg(new_state, &_should_compile_new_jobs, 1-new_state);427return (old == (1-new_state));428}429430static void disable_compilation_forever() {431UseCompiler = false;432AlwaysCompileLoopMethods = false;433Atomic::xchg(shutdown_compilaton, &_should_compile_new_jobs);434}435436static bool is_compilation_disabled_forever() {437return _should_compile_new_jobs == shutdown_compilaton;438}439static void handle_full_code_cache();440// Ensures that warning is only printed once.441static bool should_print_compiler_warning() {442jint old = Atomic::cmpxchg(1, &_print_compilation_warning, 0);443return old == 0;444}445// Return total compilation ticks446static jlong total_compilation_ticks() {447return _perf_total_compilation != NULL ? _perf_total_compilation->get_value() : 0;448}449450// Redefine Classes support451static void mark_on_stack();452453// Print a detailed accounting of compilation time454static void print_times();455456// Debugging output for failure457static void print_last_compile();458459static void print_compiler_threads_on(outputStream* st);460461// compiler name for debugging462static const char* compiler_name(int comp_level);463464static int get_total_compile_count() { return _total_compile_count; }465static int get_total_bailout_count() { return _total_bailout_count; }466static int get_total_invalidated_count() { return _total_invalidated_count; }467static int get_total_native_compile_count() { return _total_native_compile_count; }468static int get_total_osr_compile_count() { return _total_osr_compile_count; }469static int get_total_standard_compile_count() { return _total_standard_compile_count; }470static int get_sum_osr_bytes_compiled() { return _sum_osr_bytes_compiled; }471static int get_sum_standard_bytes_compiled() { return _sum_standard_bytes_compiled; }472static int get_sum_nmethod_size() { return _sum_nmethod_size;}473static int get_sum_nmethod_code_size() { return _sum_nmethod_code_size; }474static long get_peak_compilation_time() { return _peak_compilation_time; }475static long get_total_compilation_time() { return _t_total_compilation.milliseconds(); }476};477478#endif // SHARE_VM_COMPILER_COMPILEBROKER_HPP479480481