/* * Copyright (c) 1998, 2022, 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. *
*/
/** * 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();
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()) {
assert(!task->lock()->is_locked(), "Should not be locked when freed"); if ((task->_method_holder != NULL && JNIHandles::is_weak_global_handle(task->_method_holder)) ||
(task->_hot_method_holder != NULL && JNIHandles::is_weak_global_handle(task->_hot_method_holder))) {
JNIHandles::destroy_weak_global(task->_method_holder);
JNIHandles::destroy_weak_global(task->_hot_method_holder);
} else {
JNIHandles::destroy_global(task->_method_holder);
JNIHandles::destroy_global(task->_hot_method_holder);
} if (task->_failure_reason_on_C_heap && task->_failure_reason != NULL) {
os::free((void*) task->_failure_reason);
}
task->_failure_reason = NULL;
task->_failure_reason_on_C_heap = false;
if (LogCompilation) { 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_weak_global(Handle(thread, hot_method->method_holder()->klass_holder()));
}
}
}
_next = NULL;
}
/** * Returns the compiler for this task.
*/
AbstractCompiler* CompileTask::compiler() { return CompileBroker::compiler(_comp_level);
}
// Replace weak handles by strong handles to avoid unloading during compilation.
CompileTask* CompileTask::select_for_compilation() { if (is_unloaded()) { // Guard against concurrent class unloading return NULL;
}
Thread* thread = Thread::current();
assert(_method->method_holder()->is_loader_alive(), "should be alive");
Handle method_holder(thread, _method->method_holder()->klass_holder());
JNIHandles::destroy_weak_global(_method_holder);
JNIHandles::destroy_weak_global(_hot_method_holder);
_method_holder = JNIHandles::make_global(method_holder); if (_hot_method != NULL) {
_hot_method_holder = JNIHandles::make_global(Handle(thread, _hot_method->method_holder()->klass_holder()));
} returnthis;
}
void CompileTask::mark_on_stack() { if (is_unloaded()) { return;
} // 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(MetadataClosure* f) { if (is_unloaded()) { return;
}
f->do_metadata(method()); if (hot_method() != NULL && hot_method() != method()) {
f->do_metadata(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, constchar* msg, bool short_form, bool cr,
jlong time_queued, jlong time_started) { if (!short_form) { // Print current time
st->print("%7d ", (int)tty->time_stamp().milliseconds()); if (Verbose && time_queued != 0) { // Print time in queue and time being processed by compiler thread
jlong now = os::elapsed_counter();
st->print("%d ", (int)TimeHelper::counter_to_millis(now-time_queued)); if (time_started != 0) {
st->print("%d ", (int)TimeHelper::counter_to_millis(now-time_started));
}
}
} // print compiler name if requested if (CIPrintCompilerName) {
st->print("%s:", CompileBroker::compiler_name(comp_level));
}
st->print("%4d ", compile_id); // print compilation number
// <task_done ... stamp='1.234'> </task>
log->begin_elem("task_done success='%d' nmsize='%d' count='%d'",
_is_success, _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");
log->flush();
log->mark_file_end();
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.