Mercurial > hg > graal-jvmci-8
diff src/share/vm/compiler/compileBroker.cpp @ 7066:7d815d842ee0
Merge.
author | Christian Haeubl <haeubl@ssw.jku.at> |
---|---|
date | Fri, 23 Nov 2012 11:50:27 +0100 |
parents | e522a00b91aa |
children | 1baf7f1e3f23 |
line wrap: on
line diff
--- a/src/share/vm/compiler/compileBroker.cpp Fri Nov 23 11:40:17 2012 +0100 +++ b/src/share/vm/compiler/compileBroker.cpp Fri Nov 23 11:50:27 2012 +0100 @@ -31,8 +31,8 @@ #include "compiler/compilerOracle.hpp" #include "interpreter/linkResolver.hpp" #include "memory/allocation.inline.hpp" -#include "oops/methodDataOop.hpp" -#include "oops/methodOop.hpp" +#include "oops/methodData.hpp" +#include "oops/method.hpp" #include "oops/oop.inline.hpp" #include "prims/nativeLookup.hpp" #include "runtime/arguments.hpp" @@ -200,9 +200,9 @@ void log_compile(JavaThread* thread, CompileTask* task) { StringLogMessage lm; - stringStream msg = lm.stream(); + stringStream sstr = lm.stream(); // msg.time_stamp().update_to(tty->time_stamp().ticks()); - task->print_compilation(&msg, true); + task->print_compilation(&sstr, NULL, true); log(thread, "%s", (const char*)lm); } @@ -245,7 +245,7 @@ if (log != NULL) task->log_task_done(log); thread->set_task(NULL); task->set_code_handle(NULL); - DEBUG_ONLY(thread->set_env((ciEnv*)badAddress)); + thread->set_env(NULL); if (task->is_blocking()) { MutexLocker notifier(task->lock(), thread); task->mark_complete(); @@ -274,7 +274,8 @@ assert(!_lock->is_locked(), "bad locking"); _compile_id = compile_id; - _method = JNIHandles::make_global(method); + _method = method(); + _method_loader = JNIHandles::make_global(_method->method_holder()->class_loader()); _osr_bci = osr_bci; _is_blocking = is_blocking; _comp_level = comp_level; @@ -285,6 +286,7 @@ _code_handle = NULL; _hot_method = NULL; + _hot_method_loader = NULL; _hot_count = hot_count; _time_queued = 0; // tidy _comment = comment; @@ -295,8 +297,9 @@ if (hot_method == method) { _hot_method = _method; } else { - _hot_method = JNIHandles::make_global(hot_method); + _hot_method = hot_method(); } + _hot_method_loader = JNIHandles::make_global(_hot_method->method_holder()->class_loader()); } } @@ -321,19 +324,25 @@ void CompileTask::free() { set_code(NULL); assert(!_lock->is_locked(), "Should not be locked when freed"); - if (_hot_method != NULL && _hot_method != _method) { - JNIHandles::destroy_global(_hot_method); - } - JNIHandles::destroy_global(_method); + JNIHandles::destroy_global(_method_loader); + JNIHandles::destroy_global(_hot_method_loader); } +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); + } +} + // ------------------------------------------------------------------ // CompileTask::print void CompileTask::print() { tty->print("<CompileTask compile_id=%d ", _compile_id); tty->print("method="); - ((methodOop)JNIHandles::resolve(_method))->print_name(tty); + _method->print_name(tty); tty->print_cr(" osr_bci=%d is_blocking=%s is_complete=%s is_success=%s>", _osr_bci, bool_to_str(_is_blocking), bool_to_str(_is_complete), bool_to_str(_is_success)); @@ -368,7 +377,7 @@ // ------------------------------------------------------------------ // CompileTask::print_compilation_impl -void CompileTask::print_compilation_impl(outputStream* st, methodOop method, int compile_id, int comp_level, +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) { if (!short_form) { @@ -485,20 +494,16 @@ // ------------------------------------------------------------------ // CompileTask::print_compilation -void CompileTask::print_compilation(outputStream* st, bool short_form) { - oop rem = JNIHandles::resolve(method_handle()); - assert(rem != NULL && rem->is_method(), "must be"); - methodOop method = (methodOop) rem; +void CompileTask::print_compilation(outputStream* st, const char* msg, bool short_form) { bool is_osr_method = osr_bci() != InvocationEntryBci; - print_compilation_impl(st, method, compile_id(), comp_level(), is_osr_method, osr_bci(), is_blocking(), NULL, short_form); + print_compilation_impl(st, method(), compile_id(), comp_level(), is_osr_method, osr_bci(), is_blocking(), msg, short_form); } // ------------------------------------------------------------------ // CompileTask::log_task void CompileTask::log_task(xmlStream* log) { Thread* thread = Thread::current(); - methodHandle method(thread, - (methodOop)JNIHandles::resolve(method_handle())); + methodHandle method(thread, this->method()); ResourceMark rm(thread); // <task id='9' method='M' osr_bci='X' level='1' blocking='1' stamp='1.234'> @@ -533,10 +538,8 @@ xtty->print(" comment='%s'", _comment); } if (_hot_method != NULL) { - methodHandle hot(thread, - (methodOop)JNIHandles::resolve(_hot_method)); - methodHandle method(thread, - (methodOop)JNIHandles::resolve(_method)); + methodHandle hot(thread, _hot_method); + methodHandle method(thread, _method); if (hot() != method()) { xtty->method(hot); } @@ -561,8 +564,7 @@ // CompileTask::log_task_done void CompileTask::log_task_done(CompileLog* log) { Thread* thread = Thread::current(); - methodHandle method(thread, - (methodOop)JNIHandles::resolve(method_handle())); + methodHandle method(thread, this->method()); ResourceMark rm(thread); // <task_done ... stamp='1.234'> </task> @@ -613,7 +615,7 @@ ++_size; // Mark the method as being in the compile queue. - ((methodOop)JNIHandles::resolve(task->method_handle()))->set_queued_for_compilation(); + task->method()->set_queued_for_compilation(); if (CIPrintCompileQueue) { print(); @@ -677,6 +679,16 @@ --_size; } +// methods in the compile queue need to be marked as used on the stack +// so that they don't get reclaimed by Redefine Classes +void CompileQueue::mark_on_stack() { + CompileTask* task = _first; + while (task != NULL) { + task->mark_on_stack(); + task = task->next(); + } +} + // ------------------------------------------------------------------ // CompileQueue::print void CompileQueue::print() { @@ -875,7 +887,7 @@ CompilerThread* CompileBroker::make_compiler_thread(const char* name, CompileQueue* queue, CompilerCounters* counters, TRAPS) { CompilerThread* compiler_thread = NULL; - klassOop k = + Klass* k = SystemDictionary::resolve_or_fail(vmSymbols::java_lang_Thread(), true, CHECK_0); instanceKlassHandle klass (THREAD, k); @@ -994,6 +1006,18 @@ } } + +// Set the methods on the stack as on_stack so that redefine classes doesn't +// reclaim them +void CompileBroker::mark_on_stack() { + if (_c2_method_queue != NULL) { + _c2_method_queue->mark_on_stack(); + } + if (_c1_method_queue != NULL) { + _c1_method_queue->mark_on_stack(); + } +} + // ------------------------------------------------------------------ // CompileBroker::is_idle bool CompileBroker::is_idle() { @@ -1033,9 +1057,9 @@ } guarantee(!method->is_abstract(), "cannot compile abstract methods"); - assert(method->method_holder()->klass_part()->oop_is_instance(), + assert(method->method_holder()->oop_is_instance(), "sanity check"); - assert(!instanceKlass::cast(method->method_holder())->is_not_initialized(), + assert(!method->method_holder()->is_not_initialized(), "method holder must be initialized"); assert(!method->is_method_handle_intrinsic(), "do not enqueue these guys"); @@ -1092,7 +1116,7 @@ // the pending list lock or a 3-way deadlock may occur // between the reference handler thread, a GC (instigated // by a compiler thread), and compiled method registration. - if (instanceRefKlass::owns_pending_list_lock(JavaThread::current())) { + if (InstanceRefKlass::owns_pending_list_lock(JavaThread::current())) { return; } #ifdef GRAAL @@ -1196,10 +1220,10 @@ methodHandle hot_method, int hot_count, const char* comment, Thread* THREAD) { // make sure arguments make sense - assert(method->method_holder()->klass_part()->oop_is_instance(), "not an instance method"); + assert(method->method_holder()->oop_is_instance(), "not an instance method"); assert(osr_bci == InvocationEntryBci || (0 <= osr_bci && osr_bci < method->code_size()), "bci out of range"); assert(!method->is_abstract() && (osr_bci == InvocationEntryBci || !method->is_native()), "cannot compile abstract/native methods"); - assert(!instanceKlass::cast(method->method_holder())->is_not_initialized(), "method holder must be initialized"); + assert(!method->method_holder()->is_not_initialized(), "method holder must be initialized"); if (!TieredCompilation) { comp_level = CompLevel_highest_tier; @@ -1242,7 +1266,7 @@ // We accept a higher level osr method nmethod* nm = method->lookup_osr_nmethod_for(osr_bci, comp_level, false); if (nm != NULL) return nm; - if (method->is_not_osr_compilable()) return NULL; + if (method->is_not_osr_compilable(comp_level)) return NULL; } assert(!HAS_PENDING_EXCEPTION, "No exception should be present"); @@ -1251,7 +1275,7 @@ method->constants()->resolve_string_constants(CHECK_AND_CLEAR_NULL); // Resolve all classes seen in the signature of the method // we are compiling. - methodOopDesc::load_signature_classes(method, CHECK_AND_CLEAR_NULL); + Method::load_signature_classes(method, CHECK_AND_CLEAR_NULL); } // If the method is native, do the lookup in the thread requesting @@ -1323,7 +1347,7 @@ int comp_level) { bool is_osr = (osr_bci != standard_entry_bci); if (is_osr) { - if (method->is_not_osr_compilable()) { + if (method->is_not_osr_compilable(comp_level)) { return true; } else { nmethod* result = method->lookup_osr_nmethod_for(osr_bci, comp_level, true); @@ -1374,7 +1398,7 @@ // Some compilers may not support on stack replacement. if (is_osr && (!CICompileOSR || !compiler(comp_level)->supports_osr())) { - method->set_not_osr_compilable(); + method->set_not_osr_compilable(comp_level); return true; } @@ -1433,7 +1457,7 @@ // Should the current thread be blocked until this compilation request // has been fulfilled? bool CompileBroker::is_compile_blocking(methodHandle method, int osr_bci) { - assert(!instanceRefKlass::owns_pending_list_lock(JavaThread::current()), "possible deadlock"); + assert(!InstanceRefKlass::owns_pending_list_lock(JavaThread::current()), "possible deadlock"); return !BackgroundCompilation; } @@ -1514,8 +1538,7 @@ JavaThread *thread = JavaThread::current(); thread->set_blocked_on_compilation(true); - methodHandle method(thread, - (methodOop)JNIHandles::resolve(task->method_handle())); + methodHandle method(thread, task->method()); { MutexLocker waiter(task->lock(), thread); @@ -1564,7 +1587,8 @@ } CompileLog* log = thread->log(); if (log != NULL) { - log->begin_elem("start_compile_thread thread='" UINTX_FORMAT "' process='%d'", + log->begin_elem("start_compile_thread name='%s' thread='" UINTX_FORMAT "' process='%d'", + thread->name(), os::current_thread_id(), os::current_process_id()); log->stamp(); @@ -1600,8 +1624,7 @@ CompileTaskWrapper ctw(task); nmethodLocker result_handle; // (handle for the nmethod produced by this task) task->set_code_handle(&result_handle); - methodHandle method(thread, - (methodOop)JNIHandles::resolve(task->method_handle())); + methodHandle method(thread, task->method()); // Never compile a method if breakpoints are present in it if (method()->number_of_breakpoints() == 0) { @@ -1707,7 +1730,6 @@ } } - // ------------------------------------------------------------------ // CompileBroker::invoke_compiler_on_method // @@ -1738,8 +1760,7 @@ // accidentally be referenced once the thread transitions to // native. The NoHandleMark before the transition should catch // any cases where this occurs in the future. - methodHandle method(thread, - (methodOop)JNIHandles::resolve(task->method_handle())); + methodHandle method(thread, task->method()); should_break = check_break_at(method, compile_id, is_osr); if (should_log && !CompilerOracle::should_log(method)) { should_log = false; @@ -1754,7 +1775,7 @@ // Allocate a new set of JNI handles. push_jni_handle_block(); - jobject target_handle = JNIHandles::make_local(thread, JNIHandles::resolve(task->method_handle())); + Method* target_handle = task->method(); int compilable = ciEnv::MethodCompilable; { int system_dictionary_modification_counter; @@ -1804,11 +1825,10 @@ _compilation_log->log_failure(thread, task, ci_env.failure_reason(), retry_message); } if (PrintCompilation) { - tty->print("%4d COMPILE SKIPPED: %s", compile_id, ci_env.failure_reason()); - if (retry_message != NULL) { - tty->print(" (%s)", retry_message); - } - tty->cr(); + 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); } } else { task->mark_success(); @@ -1823,8 +1843,7 @@ } pop_jni_handle_block(); - methodHandle method(thread, - (methodOop)JNIHandles::resolve(task->method_handle())); + methodHandle method(thread, task->method()); DTRACE_METHOD_COMPILE_END_PROBE(compiler(task->comp_level()), method, task->is_success()); @@ -1838,14 +1857,20 @@ tty->print_cr("size: %d time: %d inlined: %d bytes", code_size, (int)time.milliseconds(), task->num_inlined_bytecodes()); } - if (compilable == ciEnv::MethodCompilable_never) { - if (is_osr) { - method->set_not_osr_compilable(); - } else { + // Disable compilation, if required. + switch (compilable) { + case ciEnv::MethodCompilable_never: + if (is_osr) + method->set_not_osr_compilable_quietly(); + else method->set_not_compilable_quietly(); - } - } else if (compilable == ciEnv::MethodCompilable_not_at_tier) { - method->set_not_compilable_quietly(task->comp_level()); + break; + case ciEnv::MethodCompilable_not_at_tier: + if (is_osr) + method->set_not_osr_compilable_quietly(task->comp_level()); + else + method->set_not_compilable_quietly(task->comp_level()); + break; } // Note that the queued_for_compilation bits are cleared without @@ -1918,7 +1943,7 @@ size_t maxLen = CompilerCounters::cmname_buffer_length; if (UsePerfData) { - const char* class_name = method->method_holder()->klass_part()->name()->as_C_string(); + const char* class_name = method->method_holder()->name()->as_C_string(); size_t s1len = strlen(class_name); size_t s2len = strlen(method_name); @@ -2012,7 +2037,7 @@ void CompileBroker::collect_statistics(CompilerThread* thread, elapsedTimer time, CompileTask* task) { bool success = task->is_success(); - methodHandle method (thread, (methodOop)JNIHandles::resolve(task->method_handle())); + methodHandle method (thread, task->method()); uint compile_id = task->compile_id(); bool is_osr = (task->osr_bci() != standard_entry_bci); nmethod* code = task->code();