8135067: Preparatory refactorings for compiler control
Summary: Extract CompileTask and clean up
Reviewed-by: roland
--- a/hotspot/src/share/vm/c1/c1_Compiler.cpp Thu Sep 03 15:03:12 2015 -0700
+++ b/hotspot/src/share/vm/c1/c1_Compiler.cpp Fri Sep 04 12:47:57 2015 +0200
@@ -32,7 +32,6 @@
#include "c1/c1_Runtime1.hpp"
#include "c1/c1_ValueType.hpp"
#include "compiler/compileBroker.hpp"
-#include "compiler/compilerOracle.hpp"
#include "interpreter/linkResolver.hpp"
#include "memory/allocation.hpp"
#include "memory/allocation.inline.hpp"
--- a/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp Thu Sep 03 15:03:12 2015 -0700
+++ b/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp Fri Sep 04 12:47:57 2015 +0200
@@ -4212,7 +4212,7 @@
if (!PrintInlining && !compilation()->method()->has_option("PrintInlining")) {
return;
}
- CompileTask::print_inlining(callee, scope()->level(), bci(), msg);
+ CompileTask::print_inlining_tty(callee, scope()->level(), bci(), msg);
if (success && CIPrintMethodCodes) {
callee->print_codes();
}
--- a/hotspot/src/share/vm/ci/bcEscapeAnalyzer.cpp Thu Sep 03 15:03:12 2015 -0700
+++ b/hotspot/src/share/vm/ci/bcEscapeAnalyzer.cpp Fri Sep 04 12:47:57 2015 +0200
@@ -1447,7 +1447,6 @@
if (methodData() == NULL)
return;
- bool printit = _method->should_print_assembly();
if (methodData()->has_escape_info()) {
TRACE_BCEA(2, tty->print_cr("[EA] Reading previous results for %s.%s",
method->holder()->name()->as_utf8(),
--- a/hotspot/src/share/vm/classfile/javaClasses.cpp Thu Sep 03 15:03:12 2015 -0700
+++ b/hotspot/src/share/vm/classfile/javaClasses.cpp Fri Sep 04 12:47:57 2015 +0200
@@ -29,7 +29,6 @@
#include "classfile/vmSymbols.hpp"
#include "code/debugInfo.hpp"
#include "code/pcDesc.hpp"
-#include "compiler/compilerOracle.hpp"
#include "interpreter/interpreter.hpp"
#include "memory/oopFactory.hpp"
#include "memory/resourceArea.hpp"
--- a/hotspot/src/share/vm/code/nmethod.cpp Thu Sep 03 15:03:12 2015 -0700
+++ b/hotspot/src/share/vm/code/nmethod.cpp Fri Sep 04 12:47:57 2015 +0200
@@ -848,10 +848,10 @@
if (st != NULL) {
ttyLocker ttyl;
if (WizardMode) {
- CompileTask::print_compilation(st, this, msg, /*short_form:*/ true);
+ CompileTask::print(st, this, msg, /*short_form:*/ true);
st->print_cr(" (" INTPTR_FORMAT ")", this);
} else {
- CompileTask::print_compilation(st, this, msg, /*short_form:*/ false);
+ CompileTask::print(st, this, msg, /*short_form:*/ false);
}
}
}
--- a/hotspot/src/share/vm/compiler/compileBroker.cpp Thu Sep 03 15:03:12 2015 -0700
+++ b/hotspot/src/share/vm/compiler/compileBroker.cpp Fri Sep 04 12:47:57 2015 +0200
@@ -157,7 +157,6 @@
CompileQueue* CompileBroker::_c2_compile_queue = NULL;
CompileQueue* CompileBroker::_c1_compile_queue = NULL;
-
class CompilationLog : public StringEventLog {
public:
CompilationLog() : StringEventLog("Compilation events") {
@@ -167,7 +166,7 @@
StringLogMessage lm;
stringStream sstr = lm.stream();
// msg.time_stamp().update_to(tty->time_stamp().ticks());
- task->print_compilation(&sstr, NULL, true, false);
+ task->print(&sstr, NULL, true, false);
log(thread, "%s", (const char*)lm);
}
@@ -233,371 +232,6 @@
}
}
-
-CompileTask* CompileTask::_task_free_list = NULL;
-#ifdef ASSERT
-int CompileTask::_num_allocated_tasks = 0;
-#endif
-/**
- * Allocate a CompileTask, from the free list if possible.
- */
-CompileTask* CompileTask::allocate() {
- MutexLocker locker(CompileTaskAlloc_lock);
- CompileTask* task = NULL;
-
- if (_task_free_list != NULL) {
- task = _task_free_list;
- _task_free_list = task->next();
- task->set_next(NULL);
- } else {
- task = new CompileTask();
- DEBUG_ONLY(_num_allocated_tasks++;)
- assert (WhiteBoxAPI || _num_allocated_tasks < 10000, "Leaking compilation tasks?");
- task->set_next(NULL);
- task->set_is_free(true);
- }
- assert(task->is_free(), "Task must be free.");
- task->set_is_free(false);
- return task;
-}
-
-
-/**
- * Add a task to the free list.
- */
-void CompileTask::free(CompileTask* task) {
- MutexLocker locker(CompileTaskAlloc_lock);
- if (!task->is_free()) {
- task->set_code(NULL);
- assert(!task->lock()->is_locked(), "Should not be locked when freed");
- JNIHandles::destroy_global(task->_method_holder);
- JNIHandles::destroy_global(task->_hot_method_holder);
-
- task->set_is_free(true);
- task->set_next(_task_free_list);
- _task_free_list = task;
- }
-}
-
-void CompileTask::initialize(int compile_id,
- methodHandle method,
- int osr_bci,
- int comp_level,
- methodHandle hot_method,
- int hot_count,
- const char* comment,
- bool is_blocking) {
- assert(!_lock->is_locked(), "bad locking");
-
- _compile_id = compile_id;
- _method = method();
- _method_holder = JNIHandles::make_global(method->method_holder()->klass_holder());
- _osr_bci = osr_bci;
- _is_blocking = is_blocking;
- _comp_level = comp_level;
- _num_inlined_bytecodes = 0;
-
- _is_complete = false;
- _is_success = false;
- _code_handle = NULL;
-
- _hot_method = NULL;
- _hot_method_holder = NULL;
- _hot_count = hot_count;
- _time_queued = 0; // tidy
- _comment = comment;
- _failure_reason = NULL;
-
- if (LogCompilation) {
- _time_queued = os::elapsed_counter();
- if (hot_method.not_null()) {
- if (hot_method == method) {
- _hot_method = _method;
- } else {
- _hot_method = hot_method();
- // only add loader or mirror if different from _method_holder
- _hot_method_holder = JNIHandles::make_global(hot_method->method_holder()->klass_holder());
- }
- }
- }
-
- _next = NULL;
-}
-
-// ------------------------------------------------------------------
-// CompileTask::code/set_code
-nmethod* CompileTask::code() const {
- if (_code_handle == NULL) return NULL;
- return _code_handle->code();
-}
-void CompileTask::set_code(nmethod* nm) {
- if (_code_handle == NULL && nm == NULL) return;
- guarantee(_code_handle != NULL, "");
- _code_handle->set_code(nm);
- if (nm == NULL) _code_handle = NULL; // drop the handle also
-}
-
-void CompileTask::mark_on_stack() {
- // Mark these methods as something redefine classes cannot remove.
- _method->set_on_stack(true);
- if (_hot_method != NULL) {
- _hot_method->set_on_stack(true);
- }
-}
-
-// RedefineClasses support
-void CompileTask::metadata_do(void f(Metadata*)) {
- f(method());
- if (hot_method() != NULL && hot_method() != method()) {
- f(hot_method());
- }
-}
-
-// ------------------------------------------------------------------
-// CompileTask::print_line_on_error
-//
-// This function is called by fatal error handler when the thread
-// causing troubles is a compiler thread.
-//
-// Do not grab any lock, do not allocate memory.
-//
-// Otherwise it's the same as CompileTask::print_line()
-//
-void CompileTask::print_line_on_error(outputStream* st, char* buf, int buflen) {
- // print compiler name
- st->print("%s:", CompileBroker::compiler_name(comp_level()));
- print_compilation(st);
-}
-
-// ------------------------------------------------------------------
-// CompileTask::print_line
-void CompileTask::print_tty() {
- ttyLocker ttyl; // keep the following output all in one block
- // print compiler name if requested
- if (CIPrintCompilerName) tty->print("%s:", CompileBroker::compiler_name(comp_level()));
- print_compilation(tty);
-}
-
-// ------------------------------------------------------------------
-// CompileTask::print_compilation_impl
-void CompileTask::print_compilation_impl(outputStream* st, Method* method, int compile_id, int comp_level,
- bool is_osr_method, int osr_bci, bool is_blocking,
- const char* msg, bool short_form, bool cr) {
- if (!short_form) {
- st->print("%7d ", (int) st->time_stamp().milliseconds()); // print timestamp
- }
- st->print("%4d ", compile_id); // print compilation number
-
- // For unloaded methods the transition to zombie occurs after the
- // method is cleared so it's impossible to report accurate
- // information for that case.
- bool is_synchronized = false;
- bool has_exception_handler = false;
- bool is_native = false;
- if (method != NULL) {
- is_synchronized = method->is_synchronized();
- has_exception_handler = method->has_exception_handler();
- is_native = method->is_native();
- }
- // method attributes
- const char compile_type = is_osr_method ? '%' : ' ';
- const char sync_char = is_synchronized ? 's' : ' ';
- const char exception_char = has_exception_handler ? '!' : ' ';
- const char blocking_char = is_blocking ? 'b' : ' ';
- const char native_char = is_native ? 'n' : ' ';
-
- // print method attributes
- st->print("%c%c%c%c%c ", compile_type, sync_char, exception_char, blocking_char, native_char);
-
- if (TieredCompilation) {
- if (comp_level != -1) st->print("%d ", comp_level);
- else st->print("- ");
- }
- st->print(" "); // more indent
-
- if (method == NULL) {
- st->print("(method)");
- } else {
- method->print_short_name(st);
- if (is_osr_method) {
- st->print(" @ %d", osr_bci);
- }
- if (method->is_native())
- st->print(" (native)");
- else
- st->print(" (%d bytes)", method->code_size());
- }
-
- if (msg != NULL) {
- st->print(" %s", msg);
- }
- if (cr) {
- st->cr();
- }
-}
-
-// ------------------------------------------------------------------
-// CompileTask::print_inlining
-void CompileTask::print_inlining(outputStream* st, ciMethod* method, int inline_level, int bci, const char* msg) {
- // 1234567
- st->print(" "); // print timestamp
- // 1234
- st->print(" "); // print compilation number
-
- // method attributes
- if (method->is_loaded()) {
- const char sync_char = method->is_synchronized() ? 's' : ' ';
- const char exception_char = method->has_exception_handlers() ? '!' : ' ';
- const char monitors_char = method->has_monitor_bytecodes() ? 'm' : ' ';
-
- // print method attributes
- st->print(" %c%c%c ", sync_char, exception_char, monitors_char);
- } else {
- // %s!bn
- st->print(" "); // print method attributes
- }
-
- if (TieredCompilation) {
- st->print(" ");
- }
- st->print(" "); // more indent
- st->print(" "); // initial inlining indent
-
- for (int i = 0; i < inline_level; i++) st->print(" ");
-
- st->print("@ %d ", bci); // print bci
- method->print_short_name(st);
- if (method->is_loaded())
- st->print(" (%d bytes)", method->code_size());
- else
- st->print(" (not loaded)");
-
- if (msg != NULL) {
- st->print(" %s", msg);
- }
- st->cr();
-}
-
-// ------------------------------------------------------------------
-// CompileTask::print_inline_indent
-void CompileTask::print_inline_indent(int inline_level, outputStream* st) {
- // 1234567
- st->print(" "); // print timestamp
- // 1234
- st->print(" "); // print compilation number
- // %s!bn
- st->print(" "); // print method attributes
- if (TieredCompilation) {
- st->print(" ");
- }
- st->print(" "); // more indent
- st->print(" "); // initial inlining indent
- for (int i = 0; i < inline_level; i++) st->print(" ");
-}
-
-// ------------------------------------------------------------------
-// CompileTask::print_compilation
-void CompileTask::print_compilation(outputStream* st, const char* msg, bool short_form, bool cr) {
- bool is_osr_method = osr_bci() != InvocationEntryBci;
- print_compilation_impl(st, method(), compile_id(), comp_level(), is_osr_method, osr_bci(), is_blocking(), msg, short_form, cr);
-}
-
-// ------------------------------------------------------------------
-// CompileTask::log_task
-void CompileTask::log_task(xmlStream* log) {
- Thread* thread = Thread::current();
- methodHandle method(thread, this->method());
- ResourceMark rm(thread);
-
- // <task compiler='Cx' id='9' method='M' osr_bci='X' level='1' blocking='1' stamp='1.234'>
- log->print(" compiler='%s' compile_id='%d'", _comp_level <= CompLevel_full_profile ? "C1" : "C2", _compile_id);
- if (_osr_bci != CompileBroker::standard_entry_bci) {
- log->print(" compile_kind='osr'"); // same as nmethod::compile_kind
- } // else compile_kind='c2c'
- if (!method.is_null()) log->method(method);
- if (_osr_bci != CompileBroker::standard_entry_bci) {
- log->print(" osr_bci='%d'", _osr_bci);
- }
- if (_comp_level != CompLevel_highest_tier) {
- log->print(" level='%d'", _comp_level);
- }
- if (_is_blocking) {
- log->print(" blocking='1'");
- }
- log->stamp();
-}
-
-
-// ------------------------------------------------------------------
-// CompileTask::log_task_queued
-void CompileTask::log_task_queued() {
- Thread* thread = Thread::current();
- ttyLocker ttyl;
- ResourceMark rm(thread);
-
- xtty->begin_elem("task_queued");
- log_task(xtty);
- if (_comment != NULL) {
- xtty->print(" comment='%s'", _comment);
- }
- if (_hot_method != NULL) {
- methodHandle hot(thread, _hot_method);
- methodHandle method(thread, _method);
- if (hot() != method()) {
- xtty->method(hot);
- }
- }
- if (_hot_count != 0) {
- xtty->print(" hot_count='%d'", _hot_count);
- }
- xtty->end_elem();
-}
-
-
-// ------------------------------------------------------------------
-// CompileTask::log_task_start
-void CompileTask::log_task_start(CompileLog* log) {
- log->begin_head("task");
- log_task(log);
- log->end_head();
-}
-
-
-// ------------------------------------------------------------------
-// CompileTask::log_task_done
-void CompileTask::log_task_done(CompileLog* log) {
- Thread* thread = Thread::current();
- methodHandle method(thread, this->method());
- ResourceMark rm(thread);
-
- if (!_is_success) {
- const char* reason = _failure_reason != NULL ? _failure_reason : "unknown";
- log->elem("failure reason='%s'", reason);
- }
-
- // <task_done ... stamp='1.234'> </task>
- nmethod* nm = code();
- log->begin_elem("task_done success='%d' nmsize='%d' count='%d'",
- _is_success, nm == NULL ? 0 : nm->content_size(),
- method->invocation_count());
- int bec = method->backedge_count();
- if (bec != 0) log->print(" backedge_count='%d'", bec);
- // Note: "_is_complete" is about to be set, but is not.
- if (_num_inlined_bytecodes != 0) {
- log->print(" inlined_bytes='%d'", _num_inlined_bytecodes);
- }
- log->stamp();
- log->end_elem();
- log->tail("task");
- log->clear_identities(); // next task will have different CI
- if (log->unflushed_count() > 2000) {
- log->flush();
- }
- log->mark_file_end();
-}
-
-
-
/**
* Add a CompileTask to a CompileQueue.
*/
@@ -807,7 +441,7 @@
st->print_cr("Empty");
} else {
while (task != NULL) {
- task->print_compilation(st, NULL, true, true);
+ task->print(st, NULL, true, true);
task = task->next();
}
}
@@ -1349,7 +983,7 @@
#ifndef TIERED
// seems like an assert of dubious value
assert(comp_level == CompLevel_highest_tier,
- "all OSR compiles are assumed to be at a single compilation lavel");
+ "all OSR compiles are assumed to be at a single compilation level");
#endif // TIERED
// We accept a higher level osr method
nmethod* nm = method->lookup_osr_nmethod_for(osr_bci, comp_level, false);
@@ -2037,7 +1671,7 @@
FormatBufferResource msg = retry_message != NULL ?
err_msg_res("COMPILE SKIPPED: %s (%s)", ci_env.failure_reason(), retry_message) :
err_msg_res("COMPILE SKIPPED: %s", ci_env.failure_reason());
- task->print_compilation(tty, msg);
+ task->print(tty, msg);
}
} else {
task->mark_success();
--- a/hotspot/src/share/vm/compiler/compileBroker.hpp Thu Sep 03 15:03:12 2015 -0700
+++ b/hotspot/src/share/vm/compiler/compileBroker.hpp Fri Sep 04 12:47:57 2015 +0200
@@ -27,127 +27,12 @@
#include "ci/compilerInterface.hpp"
#include "compiler/abstractCompiler.hpp"
+#include "compiler/compileTask.hpp"
#include "runtime/perfData.hpp"
class nmethod;
class nmethodLocker;
-// CompileTask
-//
-// An entry in the compile queue. It represents a pending or current
-// compilation.
-class CompileTask : public CHeapObj<mtCompiler> {
- friend class VMStructs;
-
- private:
- static CompileTask* _task_free_list;
-#ifdef ASSERT
- static int _num_allocated_tasks;
-#endif
-
- Monitor* _lock;
- uint _compile_id;
- Method* _method;
- jobject _method_holder;
- int _osr_bci;
- bool _is_complete;
- bool _is_success;
- bool _is_blocking;
- int _comp_level;
- int _num_inlined_bytecodes;
- nmethodLocker* _code_handle; // holder of eventual result
- CompileTask* _next, *_prev;
- bool _is_free;
- // Fields used for logging why the compilation was initiated:
- jlong _time_queued; // in units of os::elapsed_counter()
- Method* _hot_method; // which method actually triggered this task
- jobject _hot_method_holder;
- int _hot_count; // information about its invocation counter
- const char* _comment; // more info about the task
- const char* _failure_reason;
-
- public:
- CompileTask() {
- _lock = new Monitor(Mutex::nonleaf+2, "CompileTaskLock");
- }
-
- void initialize(int compile_id, methodHandle method, int osr_bci, int comp_level,
- methodHandle hot_method, int hot_count, const char* comment,
- bool is_blocking);
-
- static CompileTask* allocate();
- static void free(CompileTask* task);
-
- int compile_id() const { return _compile_id; }
- Method* method() const { return _method; }
- Method* hot_method() const { return _hot_method; }
- int osr_bci() const { return _osr_bci; }
- bool is_complete() const { return _is_complete; }
- bool is_blocking() const { return _is_blocking; }
- bool is_success() const { return _is_success; }
-
- nmethodLocker* code_handle() const { return _code_handle; }
- void set_code_handle(nmethodLocker* l) { _code_handle = l; }
- nmethod* code() const; // _code_handle->code()
- void set_code(nmethod* nm); // _code_handle->set_code(nm)
-
- Monitor* lock() const { return _lock; }
-
- void mark_complete() { _is_complete = true; }
- void mark_success() { _is_success = true; }
-
- int comp_level() { return _comp_level;}
- void set_comp_level(int comp_level) { _comp_level = comp_level;}
-
- int num_inlined_bytecodes() const { return _num_inlined_bytecodes; }
- void set_num_inlined_bytecodes(int n) { _num_inlined_bytecodes = n; }
-
- CompileTask* next() const { return _next; }
- void set_next(CompileTask* next) { _next = next; }
- CompileTask* prev() const { return _prev; }
- void set_prev(CompileTask* prev) { _prev = prev; }
- bool is_free() const { return _is_free; }
- void set_is_free(bool val) { _is_free = val; }
-
- // RedefineClasses support
- void metadata_do(void f(Metadata*));
-
-private:
- static void print_compilation_impl(outputStream* st, Method* method, int compile_id, int comp_level,
- bool is_osr_method = false, int osr_bci = -1, bool is_blocking = false,
- const char* msg = NULL, bool short_form = false, bool cr = true);
-
-public:
- void print_compilation(outputStream* st = tty, const char* msg = NULL, bool short_form = false, bool cr = true);
- static void print_compilation(outputStream* st, const nmethod* nm, const char* msg = NULL, bool short_form = false, bool cr = true) {
- print_compilation_impl(st, nm->method(), nm->compile_id(), nm->comp_level(),
- nm->is_osr_method(), nm->is_osr_method() ? nm->osr_entry_bci() : -1, /*is_blocking*/ false,
- msg, short_form, cr);
- }
-
- static void print_inlining(outputStream* st, ciMethod* method, int inline_level, int bci, const char* msg = NULL);
- static void print_inlining(ciMethod* method, int inline_level, int bci, const char* msg = NULL) {
- print_inlining(tty, method, inline_level, bci, msg);
- }
-
- // Redefine Classes support
- void mark_on_stack();
-
- static void print_inline_indent(int inline_level, outputStream* st = tty);
-
- void print_tty();
- void print_line_on_error(outputStream* st, char* buf, int buflen);
-
- void log_task(xmlStream* log);
- void log_task_queued();
- void log_task_start(CompileLog* log);
- void log_task_done(CompileLog* log);
-
- void set_failure_reason(const char* reason) {
- _failure_reason = reason;
- }
-};
-
// CompilerCounters
//
// Per Compiler Performance Counters.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/compiler/compileTask.cpp Fri Sep 04 12:47:57 2015 +0200
@@ -0,0 +1,391 @@
+/*
+ * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#include "precompiled.hpp"
+#include "compiler/compileTask.hpp"
+#include "compiler/compileLog.hpp"
+#include "compiler/compileBroker.hpp"
+
+CompileTask* CompileTask::_task_free_list = NULL;
+#ifdef ASSERT
+int CompileTask::_num_allocated_tasks = 0;
+#endif
+
+/**
+ * Allocate a CompileTask, from the free list if possible.
+ */
+CompileTask* CompileTask::allocate() {
+ MutexLocker locker(CompileTaskAlloc_lock);
+ CompileTask* task = NULL;
+
+ if (_task_free_list != NULL) {
+ task = _task_free_list;
+ _task_free_list = task->next();
+ task->set_next(NULL);
+ } else {
+ task = new CompileTask();
+ DEBUG_ONLY(_num_allocated_tasks++;)
+ assert (WhiteBoxAPI || _num_allocated_tasks < 10000, "Leaking compilation tasks?");
+ task->set_next(NULL);
+ task->set_is_free(true);
+ }
+ assert(task->is_free(), "Task must be free.");
+ task->set_is_free(false);
+ return task;
+}
+
+/**
+* Add a task to the free list.
+*/
+
+void CompileTask::free(CompileTask* task) {
+ MutexLocker locker(CompileTaskAlloc_lock);
+ if (!task->is_free()) {
+ task->set_code(NULL);
+ assert(!task->lock()->is_locked(), "Should not be locked when freed");
+ JNIHandles::destroy_global(task->_method_holder);
+ JNIHandles::destroy_global(task->_hot_method_holder);
+
+ task->set_is_free(true);
+ task->set_next(_task_free_list);
+ _task_free_list = task;
+ }
+}
+
+
+void CompileTask::initialize(int compile_id,
+ methodHandle method,
+ int osr_bci,
+ int comp_level,
+ methodHandle hot_method,
+ int hot_count,
+ const char* comment,
+ bool is_blocking) {
+ assert(!_lock->is_locked(), "bad locking");
+
+ _compile_id = compile_id;
+ _method = method();
+ _method_holder = JNIHandles::make_global(method->method_holder()->klass_holder());
+ _osr_bci = osr_bci;
+ _is_blocking = is_blocking;
+ _comp_level = comp_level;
+ _num_inlined_bytecodes = 0;
+
+ _is_complete = false;
+ _is_success = false;
+ _code_handle = NULL;
+
+ _hot_method = NULL;
+ _hot_method_holder = NULL;
+ _hot_count = hot_count;
+ _time_queued = 0; // tidy
+ _comment = comment;
+ _failure_reason = NULL;
+
+ if (LogCompilation) {
+ _time_queued = os::elapsed_counter();
+ if (hot_method.not_null()) {
+ if (hot_method == method) {
+ _hot_method = _method;
+ } else {
+ _hot_method = hot_method();
+ // only add loader or mirror if different from _method_holder
+ _hot_method_holder = JNIHandles::make_global(hot_method->method_holder()->klass_holder());
+ }
+ }
+ }
+
+ _next = NULL;
+}
+
+// ------------------------------------------------------------------
+// CompileTask::code/set_code
+//
+nmethod* CompileTask::code() const {
+ if (_code_handle == NULL) return NULL;
+ return _code_handle->code();
+}
+
+void CompileTask::set_code(nmethod* nm) {
+ if (_code_handle == NULL && nm == NULL) return;
+ guarantee(_code_handle != NULL, "");
+ _code_handle->set_code(nm);
+ if (nm == NULL) _code_handle = NULL; // drop the handle also
+}
+
+void CompileTask::mark_on_stack() {
+ // Mark these methods as something redefine classes cannot remove.
+ _method->set_on_stack(true);
+ if (_hot_method != NULL) {
+ _hot_method->set_on_stack(true);
+ }
+}
+
+// RedefineClasses support
+void CompileTask::metadata_do(void f(Metadata*)) {
+ f(method());
+ if (hot_method() != NULL && hot_method() != method()) {
+ f(hot_method());
+ }
+}
+
+// ------------------------------------------------------------------
+// CompileTask::print_line_on_error
+//
+// This function is called by fatal error handler when the thread
+// causing troubles is a compiler thread.
+//
+// Do not grab any lock, do not allocate memory.
+//
+// Otherwise it's the same as CompileTask::print_line()
+//
+void CompileTask::print_line_on_error(outputStream* st, char* buf, int buflen) {
+ // print compiler name
+ st->print("%s:", CompileBroker::compiler_name(comp_level()));
+ print(st);
+}
+
+// ------------------------------------------------------------------
+// CompileTask::print_tty
+void CompileTask::print_tty() {
+ ttyLocker ttyl; // keep the following output all in one block
+ // print compiler name if requested
+ if (CIPrintCompilerName) tty->print("%s:", CompileBroker::compiler_name(comp_level()));
+ print(tty);
+}
+
+// ------------------------------------------------------------------
+// CompileTask::print_impl
+void CompileTask::print_impl(outputStream* st, Method* method, int compile_id, int comp_level,
+ bool is_osr_method, int osr_bci, bool is_blocking,
+ const char* msg, bool short_form, bool cr) {
+ if (!short_form) {
+ st->print("%7d ", (int) st->time_stamp().milliseconds()); // print timestamp
+ }
+ st->print("%4d ", compile_id); // print compilation number
+
+ // For unloaded methods the transition to zombie occurs after the
+ // method is cleared so it's impossible to report accurate
+ // information for that case.
+ bool is_synchronized = false;
+ bool has_exception_handler = false;
+ bool is_native = false;
+ if (method != NULL) {
+ is_synchronized = method->is_synchronized();
+ has_exception_handler = method->has_exception_handler();
+ is_native = method->is_native();
+ }
+ // method attributes
+ const char compile_type = is_osr_method ? '%' : ' ';
+ const char sync_char = is_synchronized ? 's' : ' ';
+ const char exception_char = has_exception_handler ? '!' : ' ';
+ const char blocking_char = is_blocking ? 'b' : ' ';
+ const char native_char = is_native ? 'n' : ' ';
+
+ // print method attributes
+ st->print("%c%c%c%c%c ", compile_type, sync_char, exception_char, blocking_char, native_char);
+
+ if (TieredCompilation) {
+ if (comp_level != -1) st->print("%d ", comp_level);
+ else st->print("- ");
+ }
+ st->print(" "); // more indent
+
+ if (method == NULL) {
+ st->print("(method)");
+ } else {
+ method->print_short_name(st);
+ if (is_osr_method) {
+ st->print(" @ %d", osr_bci);
+ }
+ if (method->is_native())
+ st->print(" (native)");
+ else
+ st->print(" (%d bytes)", method->code_size());
+ }
+
+ if (msg != NULL) {
+ st->print(" %s", msg);
+ }
+ if (cr) {
+ st->cr();
+ }
+}
+
+void CompileTask::print_inline_indent(int inline_level, outputStream* st) {
+ // 1234567
+ st->print(" "); // print timestamp
+ // 1234
+ st->print(" "); // print compilation number
+ // %s!bn
+ st->print(" "); // print method attributes
+ if (TieredCompilation) {
+ st->print(" ");
+ }
+ st->print(" "); // more indent
+ st->print(" "); // initial inlining indent
+ for (int i = 0; i < inline_level; i++) st->print(" ");
+}
+
+// ------------------------------------------------------------------
+// CompileTask::print_compilation
+void CompileTask::print(outputStream* st, const char* msg, bool short_form, bool cr) {
+ bool is_osr_method = osr_bci() != InvocationEntryBci;
+ print_impl(st, method(), compile_id(), comp_level(), is_osr_method, osr_bci(), is_blocking(), msg, short_form, cr);
+}
+
+// ------------------------------------------------------------------
+// CompileTask::log_task
+void CompileTask::log_task(xmlStream* log) {
+ Thread* thread = Thread::current();
+ methodHandle method(thread, this->method());
+ ResourceMark rm(thread);
+
+ // <task id='9' method='M' osr_bci='X' level='1' blocking='1' stamp='1.234'>
+ log->print(" compile_id='%d'", _compile_id);
+ if (_osr_bci != CompileBroker::standard_entry_bci) {
+ log->print(" compile_kind='osr'"); // same as nmethod::compile_kind
+ } // else compile_kind='c2c'
+ if (!method.is_null()) log->method(method);
+ if (_osr_bci != CompileBroker::standard_entry_bci) {
+ log->print(" osr_bci='%d'", _osr_bci);
+ }
+ if (_comp_level != CompLevel_highest_tier) {
+ log->print(" level='%d'", _comp_level);
+ }
+ if (_is_blocking) {
+ log->print(" blocking='1'");
+ }
+ log->stamp();
+}
+
+// ------------------------------------------------------------------
+// CompileTask::log_task_queued
+void CompileTask::log_task_queued() {
+ Thread* thread = Thread::current();
+ ttyLocker ttyl;
+ ResourceMark rm(thread);
+
+ xtty->begin_elem("task_queued");
+ log_task(xtty);
+ if (_comment != NULL) {
+ xtty->print(" comment='%s'", _comment);
+ }
+ if (_hot_method != NULL) {
+ methodHandle hot(thread, _hot_method);
+ methodHandle method(thread, _method);
+ if (hot() != method()) {
+ xtty->method(hot);
+ }
+ }
+ if (_hot_count != 0) {
+ xtty->print(" hot_count='%d'", _hot_count);
+ }
+ xtty->end_elem();
+}
+
+
+// ------------------------------------------------------------------
+// CompileTask::log_task_start
+void CompileTask::log_task_start(CompileLog* log) {
+ log->begin_head("task");
+ log_task(log);
+ log->end_head();
+}
+
+
+// ------------------------------------------------------------------
+// CompileTask::log_task_done
+void CompileTask::log_task_done(CompileLog* log) {
+ Thread* thread = Thread::current();
+ methodHandle method(thread, this->method());
+ ResourceMark rm(thread);
+
+ if (!_is_success) {
+ const char* reason = _failure_reason != NULL ? _failure_reason : "unknown";
+ log->elem("failure reason='%s'", reason);
+ }
+
+ // <task_done ... stamp='1.234'> </task>
+ nmethod* nm = code();
+ log->begin_elem("task_done success='%d' nmsize='%d' count='%d'",
+ _is_success, nm == NULL ? 0 : nm->content_size(),
+ method->invocation_count());
+ int bec = method->backedge_count();
+ if (bec != 0) log->print(" backedge_count='%d'", bec);
+ // Note: "_is_complete" is about to be set, but is not.
+ if (_num_inlined_bytecodes != 0) {
+ log->print(" inlined_bytes='%d'", _num_inlined_bytecodes);
+ }
+ log->stamp();
+ log->end_elem();
+ log->clear_identities(); // next task will have different CI
+ log->tail("task");
+ if (log->unflushed_count() > 2000) {
+ log->flush();
+ }
+ log->mark_file_end();
+}
+
+// ------------------------------------------------------------------
+// CompileTask::print_inlining
+void CompileTask::print_inlining_inner(outputStream* st, ciMethod* method, int inline_level, int bci, const char* msg) {
+ // 1234567
+ st->print(" "); // print timestamp
+ // 1234
+ st->print(" "); // print compilation number
+
+ // method attributes
+ if (method->is_loaded()) {
+ const char sync_char = method->is_synchronized() ? 's' : ' ';
+ const char exception_char = method->has_exception_handlers() ? '!' : ' ';
+ const char monitors_char = method->has_monitor_bytecodes() ? 'm' : ' ';
+
+ // print method attributes
+ st->print(" %c%c%c ", sync_char, exception_char, monitors_char);
+ } else {
+ // %s!bn
+ st->print(" "); // print method attributes
+ }
+
+ if (TieredCompilation) {
+ st->print(" ");
+ }
+ st->print(" "); // more indent
+ st->print(" "); // initial inlining indent
+
+ for (int i = 0; i < inline_level; i++) st->print(" ");
+
+ st->print("@ %d ", bci); // print bci
+ method->print_short_name(st);
+ if (method->is_loaded())
+ st->print(" (%d bytes)", method->code_size());
+ else
+ st->print(" (not loaded)");
+
+ if (msg != NULL) {
+ st->print(" %s", msg);
+ }
+ st->cr();
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/compiler/compileTask.hpp Fri Sep 04 12:47:57 2015 +0200
@@ -0,0 +1,151 @@
+/*
+ * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef SHARE_VM_COMPILER_COMPILETASK_HPP
+#define SHARE_VM_COMPILER_COMPILETASK_HPP
+
+#include "code/nmethod.hpp"
+#include "ci/ciMethod.hpp"
+#include "compiler/compileLog.hpp"
+#include "memory/allocation.inline.hpp"
+#include "utilities/xmlstream.hpp"
+
+// CompileTask
+//
+// An entry in the compile queue. It represents a pending or current
+// compilation.
+
+class CompileTask : public CHeapObj<mtCompiler> {
+ friend class VMStructs;
+
+ private:
+ static CompileTask* _task_free_list;
+#ifdef ASSERT
+ static int _num_allocated_tasks;
+#endif
+
+ Monitor* _lock;
+ uint _compile_id;
+ Method* _method;
+ jobject _method_holder;
+ int _osr_bci;
+ bool _is_complete;
+ bool _is_success;
+ bool _is_blocking;
+ int _comp_level;
+ int _num_inlined_bytecodes;
+ nmethodLocker* _code_handle; // holder of eventual result
+ CompileTask* _next, *_prev;
+ bool _is_free;
+ // Fields used for logging why the compilation was initiated:
+ jlong _time_queued; // in units of os::elapsed_counter()
+ Method* _hot_method; // which method actually triggered this task
+ jobject _hot_method_holder;
+ int _hot_count; // information about its invocation counter
+ const char* _comment; // more info about the task
+ const char* _failure_reason;
+
+ public:
+ CompileTask() {
+ _lock = new Monitor(Mutex::nonleaf+2, "CompileTaskLock");
+ }
+
+ void initialize(int compile_id, methodHandle method, int osr_bci, int comp_level,
+ methodHandle hot_method, int hot_count, const char* comment,
+ bool is_blocking);
+
+ static CompileTask* allocate();
+ static void free(CompileTask* task);
+
+ int compile_id() const { return _compile_id; }
+ Method* method() const { return _method; }
+ Method* hot_method() const { return _hot_method; }
+ int osr_bci() const { return _osr_bci; }
+ bool is_complete() const { return _is_complete; }
+ bool is_blocking() const { return _is_blocking; }
+ bool is_success() const { return _is_success; }
+
+ nmethodLocker* code_handle() const { return _code_handle; }
+ void set_code_handle(nmethodLocker* l) { _code_handle = l; }
+ nmethod* code() const; // _code_handle->code()
+ void set_code(nmethod* nm); // _code_handle->set_code(nm)
+
+ Monitor* lock() const { return _lock; }
+
+ void mark_complete() { _is_complete = true; }
+ void mark_success() { _is_success = true; }
+
+ int comp_level() { return _comp_level;}
+ void set_comp_level(int comp_level) { _comp_level = comp_level;}
+
+ int num_inlined_bytecodes() const { return _num_inlined_bytecodes; }
+ void set_num_inlined_bytecodes(int n) { _num_inlined_bytecodes = n; }
+
+ CompileTask* next() const { return _next; }
+ void set_next(CompileTask* next) { _next = next; }
+ CompileTask* prev() const { return _prev; }
+ void set_prev(CompileTask* prev) { _prev = prev; }
+ bool is_free() const { return _is_free; }
+ void set_is_free(bool val) { _is_free = val; }
+
+ // RedefineClasses support
+ void metadata_do(void f(Metadata*));
+ void mark_on_stack();
+
+private:
+ static void print_impl(outputStream* st, Method* method, int compile_id, int comp_level,
+ bool is_osr_method = false, int osr_bci = -1, bool is_blocking = false,
+ const char* msg = NULL, bool short_form = false, bool cr = true);
+
+public:
+ void print(outputStream* st = tty, const char* msg = NULL, bool short_form = false, bool cr = true);
+ static void print(outputStream* st, const nmethod* nm, const char* msg = NULL, bool short_form = false, bool cr = true) {
+ print_impl(st, nm->method(), nm->compile_id(), nm->comp_level(),
+ nm->is_osr_method(), nm->is_osr_method() ? nm->osr_entry_bci() : -1, /*is_blocking*/ false,
+ msg, short_form, cr);
+ }
+
+ static void print_inline_indent(int inline_level, outputStream* st = tty);
+
+ void print_tty();
+ void print_line_on_error(outputStream* st, char* buf, int buflen);
+
+ void log_task(xmlStream* log);
+ void log_task_queued();
+ void log_task_start(CompileLog* log);
+ void log_task_done(CompileLog* log);
+
+ void set_failure_reason(const char* reason) {
+ _failure_reason = reason;
+ }
+
+ bool check_break_at_flags();
+
+ static void print_inlining_inner(outputStream* st, ciMethod* method, int inline_level, int bci, const char* msg = NULL);
+ static void print_inlining_tty(ciMethod* method, int inline_level, int bci, const char* msg = NULL) {
+ print_inlining_inner(tty, method, inline_level, bci, msg);
+ }
+};
+
+#endif // SHARE_VM_COMPILER_COMPILETASK_HPP
--- a/hotspot/src/share/vm/opto/compile.hpp Thu Sep 03 15:03:12 2015 -0700
+++ b/hotspot/src/share/vm/opto/compile.hpp Fri Sep 04 12:47:57 2015 +0200
@@ -523,7 +523,7 @@
void print_inlining(ciMethod* method, int inline_level, int bci, const char* msg = NULL) {
stringStream ss;
- CompileTask::print_inlining(&ss, method, inline_level, bci, msg);
+ CompileTask::print_inlining_inner(&ss, method, inline_level, bci, msg);
print_inlining_stream()->print("%s", ss.as_string());
}
--- a/hotspot/src/share/vm/opto/doCall.cpp Thu Sep 03 15:03:12 2015 -0700
+++ b/hotspot/src/share/vm/opto/doCall.cpp Fri Sep 04 12:47:57 2015 +0200
@@ -49,7 +49,7 @@
method->print_short_name();
tty->cr();
}
- CompileTask::print_inlining(prof_method, depth, bci);
+ CompileTask::print_inlining_tty(prof_method, depth, bci);
} else {
out = C->print_inlining_stream();
}
--- a/hotspot/src/share/vm/opto/runtime.cpp Thu Sep 03 15:03:12 2015 -0700
+++ b/hotspot/src/share/vm/opto/runtime.cpp Fri Sep 04 12:47:57 2015 +0200
@@ -33,7 +33,6 @@
#include "code/scopeDesc.hpp"
#include "code/vtableStubs.hpp"
#include "compiler/compileBroker.hpp"
-#include "compiler/compilerOracle.hpp"
#include "compiler/oopMap.hpp"
#include "gc/g1/g1SATBCardTableModRefBS.hpp"
#include "gc/g1/heapRegion.hpp"
--- a/hotspot/src/share/vm/runtime/arguments.cpp Thu Sep 03 15:03:12 2015 -0700
+++ b/hotspot/src/share/vm/runtime/arguments.cpp Fri Sep 04 12:47:57 2015 +0200
@@ -28,7 +28,6 @@
#include "classfile/stringTable.hpp"
#include "classfile/symbolTable.hpp"
#include "code/codeCacheExtensions.hpp"
-#include "compiler/compilerOracle.hpp"
#include "gc/shared/cardTableRS.hpp"
#include "gc/shared/genCollectedHeap.hpp"
#include "gc/shared/referenceProcessor.hpp"
--- a/hotspot/src/share/vm/runtime/compilationPolicy.cpp Thu Sep 03 15:03:12 2015 -0700
+++ b/hotspot/src/share/vm/runtime/compilationPolicy.cpp Fri Sep 04 12:47:57 2015 +0200
@@ -26,7 +26,6 @@
#include "code/compiledIC.hpp"
#include "code/nmethod.hpp"
#include "code/scopeDesc.hpp"
-#include "compiler/compilerOracle.hpp"
#include "interpreter/interpreter.hpp"
#include "oops/methodData.hpp"
#include "oops/method.hpp"
--- a/hotspot/src/share/vm/runtime/sharedRuntime.cpp Thu Sep 03 15:03:12 2015 -0700
+++ b/hotspot/src/share/vm/runtime/sharedRuntime.cpp Fri Sep 04 12:47:57 2015 +0200
@@ -32,7 +32,6 @@
#include "code/vtableStubs.hpp"
#include "compiler/abstractCompiler.hpp"
#include "compiler/compileBroker.hpp"
-#include "compiler/compilerOracle.hpp"
#include "compiler/disassembler.hpp"
#include "gc/shared/gcLocker.inline.hpp"
#include "interpreter/interpreter.hpp"
@@ -2622,7 +2621,7 @@
if (nm != NULL) {
if (PrintCompilation) {
ttyLocker ttyl;
- CompileTask::print_compilation(tty, nm, method->is_static() ? "(static)" : "");
+ CompileTask::print(tty, nm, method->is_static() ? "(static)" : "");
}
nm->post_compiled_method_load_event();
}