# HG changeset patch # User Lukas Stadler # Date 1320834458 -3600 # Node ID 5e9645341ec3b753440a27db76ec5a4113188a38 # Parent 3822c5969a8b154f821f39e85e9ab1bf91ab2b60 support for new RiRuntime features: add code without making it the default for the method, executing Java tasks on the compile thread, communicate nmethod reference to Java code as HotSpotCompiledMethod diff -r 3822c5969a8b -r 5e9645341ec3 src/share/vm/ci/ciEnv.cpp --- a/src/share/vm/ci/ciEnv.cpp Tue Oct 25 14:44:32 2011 +0200 +++ b/src/share/vm/ci/ciEnv.cpp Wed Nov 09 11:27:38 2011 +0100 @@ -928,19 +928,20 @@ // ------------------------------------------------------------------ // ciEnv::register_method -void ciEnv::register_method(ciMethod* target, - int entry_bci, - CodeOffsets* offsets, - int orig_pc_offset, - CodeBuffer* code_buffer, - int frame_words, - OopMapSet* oop_map_set, - ExceptionHandlerTable* handler_table, - ImplicitExceptionTable* inc_table, - AbstractCompiler* compiler, - int comp_level, - bool has_debug_info, - bool has_unsafe_access) { +nmethod* ciEnv::register_method(ciMethod* target, + int entry_bci, + CodeOffsets* offsets, + int orig_pc_offset, + CodeBuffer* code_buffer, + int frame_words, + OopMapSet* oop_map_set, + ExceptionHandlerTable* handler_table, + ImplicitExceptionTable* inc_table, + AbstractCompiler* compiler, + int comp_level, + bool has_debug_info, + bool has_unsafe_access, + bool install_code) { VM_ENTRY_MARK; nmethod* nm = NULL; { @@ -996,7 +997,7 @@ // If the code buffer is created on each compile attempt // as in C2, then it must be freed. code_buffer->free_blob(); - return; + return NULL; } assert(offsets->value(CodeOffsets::Deopt) != -1, "must have deopt entry"); @@ -1041,41 +1042,43 @@ // (Put nm into the task handle *before* publishing to the Java heap.) if (task() != NULL) task()->set_code(nm); - if (entry_bci == InvocationEntryBci) { - if (TieredCompilation) { - // If there is an old version we're done with it - nmethod* old = method->code(); - if (TraceMethodReplacement && old != NULL) { + if (install_code) { + if (entry_bci == InvocationEntryBci) { + if (TieredCompilation) { + // If there is an old version we're done with it + nmethod* old = method->code(); + if (TraceMethodReplacement && old != NULL) { + ResourceMark rm; + char *method_name = method->name_and_sig_as_C_string(); + tty->print_cr("Replacing method %s", method_name); + } + if (old != NULL ) { + old->make_not_entrant(); + } + } + if (TraceNMethodInstalls ) { ResourceMark rm; char *method_name = method->name_and_sig_as_C_string(); - tty->print_cr("Replacing method %s", method_name); - } - if (old != NULL ) { - old->make_not_entrant(); + ttyLocker ttyl; + tty->print_cr("Installing method (%d) %s ", + comp_level, + method_name); } - } - if (TraceNMethodInstalls ) { - ResourceMark rm; - char *method_name = method->name_and_sig_as_C_string(); - ttyLocker ttyl; - tty->print_cr("Installing method (%d) %s ", - comp_level, - method_name); + // Allow the code to be executed + method->set_code(method, nm); + } else { + if (TraceNMethodInstalls ) { + ResourceMark rm; + char *method_name = method->name_and_sig_as_C_string(); + ttyLocker ttyl; + tty->print_cr("Installing osr method (%d) %s @ %d", + comp_level, + method_name, + entry_bci); + } + instanceKlass::cast(method->method_holder())->add_osr_nmethod(nm); + } - // Allow the code to be executed - method->set_code(method, nm); - } else { - if (TraceNMethodInstalls ) { - ResourceMark rm; - char *method_name = method->name_and_sig_as_C_string(); - ttyLocker ttyl; - tty->print_cr("Installing osr method (%d) %s @ %d", - comp_level, - method_name, - entry_bci); - } - instanceKlass::cast(method->method_holder())->add_osr_nmethod(nm); - } } } @@ -1084,6 +1087,7 @@ nm->post_compiled_method_load_event(); } + return nm; } diff -r 3822c5969a8b -r 5e9645341ec3 src/share/vm/ci/ciEnv.hpp --- a/src/share/vm/ci/ciEnv.hpp Tue Oct 25 14:44:32 2011 +0200 +++ b/src/share/vm/ci/ciEnv.hpp Wed Nov 09 11:27:38 2011 +0100 @@ -312,7 +312,7 @@ uint compile_id(); // task()->compile_id() // Register the result of a compilation. - void register_method(ciMethod* target, + nmethod* register_method(ciMethod* target, int entry_bci, CodeOffsets* offsets, int orig_pc_offset, @@ -324,7 +324,8 @@ AbstractCompiler* compiler, int comp_level, bool has_debug_info = true, - bool has_unsafe_access = false); + bool has_unsafe_access = false, + bool install_code = true); // Access to certain well known ciObjects. diff -r 3822c5969a8b -r 5e9645341ec3 src/share/vm/classfile/systemDictionary.hpp --- a/src/share/vm/classfile/systemDictionary.hpp Tue Oct 25 14:44:32 2011 +0200 +++ b/src/share/vm/classfile/systemDictionary.hpp Wed Nov 09 11:27:38 2011 +0100 @@ -187,6 +187,7 @@ template(HotSpotTypeResolved_klass, com_sun_hotspot_graal_HotSpotTypeResolved, Opt) \ template(HotSpotType_klass, com_sun_hotspot_graal_HotSpotType, Opt) \ template(HotSpotField_klass, com_sun_hotspot_graal_HotSpotField, Opt) \ + template(HotSpotCompiledMethod_klass, com_sun_hotspot_graal_HotSpotCompiledMethod, Opt) \ template(HotSpotMethodResolved_klass, com_sun_hotspot_graal_HotSpotMethodResolved, Opt) \ template(HotSpotTargetMethod_klass, com_sun_hotspot_graal_HotSpotTargetMethod, Opt) \ template(HotSpotExceptionHandler_klass,com_sun_hotspot_graal_HotSpotExceptionHandler, Opt) \ diff -r 3822c5969a8b -r 5e9645341ec3 src/share/vm/classfile/vmSymbols.hpp --- a/src/share/vm/classfile/vmSymbols.hpp Tue Oct 25 14:44:32 2011 +0200 +++ b/src/share/vm/classfile/vmSymbols.hpp Wed Nov 09 11:27:38 2011 +0100 @@ -263,6 +263,7 @@ template(com_sun_hotspot_graal_HotSpotMethodResolved, "com/oracle/max/graal/hotspot/HotSpotMethodResolvedImpl") \ template(com_sun_hotspot_graal_HotSpotTargetMethod, "com/oracle/max/graal/hotspot/HotSpotTargetMethod") \ template(com_sun_hotspot_graal_HotSpotField, "com/oracle/max/graal/hotspot/HotSpotField") \ + template(com_sun_hotspot_graal_HotSpotCompiledMethod, "com/oracle/max/graal/hotspot/HotSpotCompiledMethod") \ template(com_sun_graal_graalOptions, "com/sun/graal/graalOptions") \ template(com_sun_hotspot_graal_HotSpotOptions, "com/oracle/max/graal/hotspot/HotSpotOptions") \ template(com_sun_hotspot_graal_HotSpotTypeResolved, "com/oracle/max/graal/hotspot/HotSpotTypeResolvedImpl") \ @@ -303,6 +304,7 @@ template(startCompiler_name, "startCompiler") \ template(shutdownCompiler_name, "shutdownCompiler") \ template(compileMethod_name, "compileMethod") \ + template(pollJavaQueue_name, "pollJavaQueue") \ template(compileMethod_signature, "(Lcom/oracle/max/graal/hotspot/HotSpotMethodResolved;I)V") \ template(setOption_name, "setOption") \ template(setDefaultOptions_name, "setDefaultOptions") \ diff -r 3822c5969a8b -r 5e9645341ec3 src/share/vm/compiler/compileBroker.cpp --- a/src/share/vm/compiler/compileBroker.cpp Tue Oct 25 14:44:32 2011 +0200 +++ b/src/share/vm/compiler/compileBroker.cpp Wed Nov 09 11:27:38 2011 +0100 @@ -159,6 +159,7 @@ GrowableArray* CompileBroker::_method_threads = NULL; +bool CompileBroker::_poll_java_queue = false; CompileTaskWrapper::CompileTaskWrapper(CompileTask* task) { CompilerThread* thread = CompilerThread::current(); @@ -543,12 +544,15 @@ // CompileQueue::get // // Get the next CompileTask from a CompileQueue -CompileTask* CompileQueue::get() { +CompileTask* CompileQueue::get(bool& interrupt) { NMethodSweeper::possibly_sweep(); MutexLocker locker(lock()); // Wait for an available CompileTask. while (_first == NULL) { + if (interrupt) { + return NULL; + } // There is no work to be done right now. Wait. if (UseCodeCacheFlushing && (!CompileBroker::should_compile_new_jobs() || CodeCache::needs_flushing())) { // During the emergency sweeping periods, wake up and sweep occasionally @@ -717,6 +721,20 @@ } +void CompileBroker::notify_java_queue() { + HandleMark hm; + ResourceMark rm; + + _poll_java_queue = true; + { + ThreadInVMfromNative tivm(JavaThread::current()); + MutexLocker locker(_c1_method_queue->lock(), Thread::current()); + + _c1_method_queue->lock()->notify_all(); + } +} + + // ------------------------------------------------------------------ // CompileBroker::compilation_init // @@ -1579,49 +1597,58 @@ NMethodSweeper::handle_full_code_cache(false); } - CompileTask* task = queue->get(); + CompileTask* task = queue->get(_poll_java_queue); - // Give compiler threads an extra quanta. They tend to be bursty and - // this helps the compiler to finish up the job. - if( CompilerThreadHintNoPreempt ) - os::hint_no_preempt(); + if (task != NULL) { + // Give compiler threads an extra quanta. They tend to be bursty and + // this helps the compiler to finish up the job. + if( CompilerThreadHintNoPreempt ) + os::hint_no_preempt(); - // trace per thread time and compile statistics - CompilerCounters* counters = ((CompilerThread*)thread)->counters(); - PerfTraceTimedEvent(counters->time_counter(), counters->compile_counter()); + // trace per thread time and compile statistics + CompilerCounters* counters = ((CompilerThread*)thread)->counters(); + PerfTraceTimedEvent(counters->time_counter(), counters->compile_counter()); - // Assign the task to the current thread. Mark this compilation - // thread as active for the profiler. - 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())); + // Assign the task to the current thread. Mark this compilation + // thread as active for the profiler. + 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())); - // Never compile a method if breakpoints are present in it - if (method()->number_of_breakpoints() == 0) { - // Compile the method. - if ((UseCompiler || AlwaysCompileLoopMethods) && CompileBroker::should_compile_new_jobs()) { -#ifdef COMPILER1 - // Allow repeating compilations for the purpose of benchmarking - // compile speed. This is not useful for customers. - if (CompilationRepeat != 0) { - int compile_count = CompilationRepeat; - while (compile_count > 0) { - invoke_compiler_on_method(task); - nmethod* nm = method->code(); - if (nm != NULL) { - nm->make_zombie(); - method->clear_code(); + // Never compile a method if breakpoints are present in it + if (method()->number_of_breakpoints() == 0) { + // Compile the method. + if ((UseCompiler || AlwaysCompileLoopMethods) && CompileBroker::should_compile_new_jobs()) { + #ifdef COMPILER1 + // Allow repeating compilations for the purpose of benchmarking + // compile speed. This is not useful for customers. + if (CompilationRepeat != 0) { + int compile_count = CompilationRepeat; + while (compile_count > 0) { + invoke_compiler_on_method(task); + nmethod* nm = method->code(); + if (nm != NULL) { + nm->make_zombie(); + method->clear_code(); + } + compile_count--; } - compile_count--; } + #endif /* COMPILER1 */ + invoke_compiler_on_method(task); + } else { + // After compilation is disabled, remove remaining methods from queue + method->clear_queued_for_compilation(); } -#endif /* COMPILER1 */ - invoke_compiler_on_method(task); - } else { - // After compilation is disabled, remove remaining methods from queue - method->clear_queued_for_compilation(); + } + } + + if (_poll_java_queue) { + _poll_java_queue = false; + if (UseGraal) { + GraalCompiler::instance()->poll_java_queue(); } } } diff -r 3822c5969a8b -r 5e9645341ec3 src/share/vm/compiler/compileBroker.hpp --- a/src/share/vm/compiler/compileBroker.hpp Tue Oct 25 14:44:32 2011 +0200 +++ b/src/share/vm/compiler/compileBroker.hpp Wed Nov 09 11:27:38 2011 +0100 @@ -195,7 +195,7 @@ CompileTask* first() { return _first; } CompileTask* last() { return _last; } - CompileTask* get(); + CompileTask* get(bool& interrupt); bool is_empty() const { return _first == NULL; } int size() const { return _size; } @@ -297,6 +297,8 @@ static int _sum_nmethod_size; static int _sum_nmethod_code_size; + static bool _poll_java_queue; + static CompilerThread* make_compiler_thread(const char* name, CompileQueue* queue, CompilerCounters* counters, TRAPS); static void init_compiler_threads(int c1_compiler_count, int c2_compiler_count); static bool compilation_is_complete (methodHandle method, int osr_bci, int comp_level); @@ -404,6 +406,8 @@ static void bootstrap_graal(); static void add_method_to_queue(klassOop k, Symbol* name, Symbol* signature); + + static void notify_java_queue(); }; #endif // SHARE_VM_COMPILER_COMPILEBROKER_HPP diff -r 3822c5969a8b -r 5e9645341ec3 src/share/vm/graal/graalCodeInstaller.cpp --- a/src/share/vm/graal/graalCodeInstaller.cpp Tue Oct 25 14:44:32 2011 +0200 +++ b/src/share/vm/graal/graalCodeInstaller.cpp Wed Nov 09 11:27:38 2011 +0100 @@ -230,7 +230,7 @@ } // constructor used to create a method -CodeInstaller::CodeInstaller(Handle target_method) { +CodeInstaller::CodeInstaller(Handle target_method, nmethod*& nm, bool install_code) { _env = CURRENT_ENV; ciMethod *ciMethodObject = NULL; { @@ -255,9 +255,8 @@ int stack_slots = (_frame_size / HeapWordSize) + 2; // conversion to words, need to add two slots for ret address and frame pointer ThreadToNativeFromVM t((JavaThread*) Thread::current()); - _env->register_method(ciMethodObject, -1, &_offsets, _custom_stack_area_offset, &buffer, stack_slots, _debug_recorder->_oopmaps, &_exception_handler_table, - &_implicit_exception_table, GraalCompiler::instance(), _env->comp_level(), false, false); - + nm = _env->register_method(ciMethodObject, -1, &_offsets, _custom_stack_area_offset, &buffer, stack_slots, _debug_recorder->_oopmaps, &_exception_handler_table, + &_implicit_exception_table, GraalCompiler::instance(), _env->comp_level(), false, false, install_code); } // constructor used to create a stub @@ -654,6 +653,16 @@ fatal("unsupported type of instruction for call site"); } + if (target->is_a(SystemDictionary::HotSpotCompiledMethod_klass())) { + assert(inst->is_jump(), "jump expected"); + + nmethod* nm = (nmethod*) HotSpotCompiledMethod::nmethod(target); + nativeJump_at((address)inst)->set_jump_destination(nm->verified_entry_point()); + _instructions->relocate((address)inst, runtime_call_Relocation::spec(), Assembler::call32_operand); + + return; + } + if (debug_info != NULL) { _debug_recorder->add_safepoint(next_pc_offset, create_oop_map(_frame_size, _parameter_count, debug_info)); oop code_pos = CiDebugInfo::codePos(debug_info); diff -r 3822c5969a8b -r 5e9645341ec3 src/share/vm/graal/graalCodeInstaller.hpp --- a/src/share/vm/graal/graalCodeInstaller.hpp Tue Oct 25 14:44:32 2011 +0200 +++ b/src/share/vm/graal/graalCodeInstaller.hpp Wed Nov 09 11:27:38 2011 +0100 @@ -83,7 +83,7 @@ public: // constructor used to create a method - CodeInstaller(Handle target_method); + CodeInstaller(Handle target_method, nmethod*& nm, bool install_code); // constructor used to create a stub CodeInstaller(Handle target_method, jlong& id); diff -r 3822c5969a8b -r 5e9645341ec3 src/share/vm/graal/graalCompiler.cpp --- a/src/share/vm/graal/graalCompiler.cpp Tue Oct 25 14:44:32 2011 +0200 +++ b/src/share/vm/graal/graalCompiler.cpp Wed Nov 09 11:27:38 2011 +0100 @@ -264,3 +264,22 @@ return T_ILLEGAL; } +void GraalCompiler::poll_java_queue() { + int system_dictionary_modification_counter; + { + MutexLocker locker(Compile_lock, Thread::current()); + system_dictionary_modification_counter = SystemDictionary::number_of_modifications(); + } + + { + ThreadToNativeFromVM ttn(JavaThread::current()); + ciEnv ci_env(NULL, system_dictionary_modification_counter); + { + VM_ENTRY_MARK; + ResourceMark rm; + HandleMark hm; + + VMExits::pollJavaQueue(); + } + } +} diff -r 3822c5969a8b -r 5e9645341ec3 src/share/vm/graal/graalCompiler.hpp --- a/src/share/vm/graal/graalCompiler.hpp Tue Oct 25 14:44:32 2011 +0200 +++ b/src/share/vm/graal/graalCompiler.hpp Wed Nov 09 11:27:38 2011 +0100 @@ -79,6 +79,8 @@ } static void initialize_buffer_blob(); + + void poll_java_queue(); }; // Tracing macros diff -r 3822c5969a8b -r 5e9645341ec3 src/share/vm/graal/graalJavaAccess.hpp --- a/src/share/vm/graal/graalJavaAccess.hpp Tue Oct 25 14:44:32 2011 +0200 +++ b/src/share/vm/graal/graalJavaAccess.hpp Wed Nov 09 11:27:38 2011 +0100 @@ -73,6 +73,11 @@ end_class \ start_class(HotSpotField) \ oop_field(HotSpotField, constant, "Lcom/sun/cri/ci/CiConstant;") \ + int_field(HotSpotField, offset) \ + int_field(HotSpotField, accessFlags) \ + end_class \ + start_class(HotSpotCompiledMethod) \ + long_field(HotSpotCompiledMethod, nmethod) \ end_class \ start_class(HotSpotProxy) \ static_oop_field(HotSpotProxy, DUMMY_CONSTANT_OBJ, "Ljava/lang/Long;") \ diff -r 3822c5969a8b -r 5e9645341ec3 src/share/vm/graal/graalVMEntries.cpp --- a/src/share/vm/graal/graalVMEntries.cpp Tue Oct 25 14:44:32 2011 +0200 +++ b/src/share/vm/graal/graalVMEntries.cpp Wed Nov 09 11:27:38 2011 +0100 @@ -24,6 +24,7 @@ #include "precompiled.hpp" #include "c1/c1_Runtime1.hpp" #include "ci/ciMethodData.hpp" +#include "compiler/compileBroker.hpp" #include "graal/graalVMEntries.hpp" #include "graal/graalCompiler.hpp" #include "graal/graalJavaAccess.hpp" @@ -986,18 +987,20 @@ return config; } -// public void installMethod(HotSpotTargetMethod targetMethod); -JNIEXPORT void JNICALL Java_com_oracle_graal_hotspot_VMEntries_installMethod(JNIEnv *jniEnv, jobject, jobject targetMethod) { +// public long installMethod(HotSpotTargetMethod targetMethod, boolean installCode); +JNIEXPORT jlong JNICALL Java_com_oracle_graal_hotspot_VMEntries_installMethod(JNIEnv *jniEnv, jobject, jobject targetMethod, jboolean install_code) { VM_ENTRY_MARK; + nmethod* nm = NULL; if (CURRENT_ENV == NULL) { Arena arena; ciEnv env(&arena); ResourceMark rm; - CodeInstaller installer(JNIHandles::resolve(targetMethod)); + CodeInstaller installer(JNIHandles::resolve(targetMethod), nm, install_code); } else { ResourceMark rm; - CodeInstaller installer(JNIHandles::resolve(targetMethod)); + CodeInstaller installer(JNIHandles::resolve(targetMethod), nm, install_code); } + return (jlong) nm; } // public HotSpotProxy installStub(HotSpotTargetMethod targetMethod, String name); @@ -1027,6 +1030,11 @@ } } +// public void notifyJavaQueue(); +JNIEXPORT void JNICALL Java_com_oracle_graal_hotspot_VMEntries_notifyJavaQueue(JNIEnv *jniEnv, jobject) { + CompileBroker::notify_java_queue(); +} + @@ -1088,9 +1096,10 @@ {CC"getMaxCallTargetOffset", CC"("CI_RUNTIME_CALL")J", FN_PTR(Java_com_oracle_graal_hotspot_VMEntries_getMaxCallTargetOffset)}, {CC"getType", CC"("CLASS")"TYPE, FN_PTR(Java_com_oracle_graal_hotspot_VMEntries_getType)}, {CC"getConfiguration", CC"()"CONFIG, FN_PTR(Java_com_oracle_graal_hotspot_VMEntries_getConfiguration)}, - {CC"installMethod", CC"("TARGET_METHOD")V", FN_PTR(Java_com_oracle_graal_hotspot_VMEntries_installMethod)}, + {CC"installMethod", CC"("TARGET_METHOD"Z)J", FN_PTR(Java_com_oracle_graal_hotspot_VMEntries_installMethod)}, {CC"installStub", CC"("TARGET_METHOD")"PROXY, FN_PTR(Java_com_oracle_graal_hotspot_VMEntries_installStub)}, - {CC"recordBailout", CC"("STRING")V", FN_PTR(Java_com_oracle_graal_hotspot_VMEntries_recordBailout)} + {CC"recordBailout", CC"("STRING")V", FN_PTR(Java_com_oracle_graal_hotspot_VMEntries_recordBailout)}, + {CC"notifyJavaQueue", CC"()V", FN_PTR(Java_com_oracle_graal_hotspot_VMEntries_notifyJavaQueue)} }; int VMEntries_methods_count() { diff -r 3822c5969a8b -r 5e9645341ec3 src/share/vm/graal/graalVMExits.cpp --- a/src/share/vm/graal/graalVMExits.cpp Tue Oct 25 14:44:32 2011 +0200 +++ b/src/share/vm/graal/graalVMExits.cpp Wed Nov 09 11:27:38 2011 +0100 @@ -140,6 +140,15 @@ check_pending_exception("Error while calling startCompiler"); } +void VMExits::pollJavaQueue() { + JavaThread* THREAD = JavaThread::current(); + JavaValue result(T_VOID); + JavaCallArguments args; + args.push_oop(instance()); + JavaCalls::call_interface(&result, vmExitsKlass(), vmSymbols::pollJavaQueue_name(), vmSymbols::void_method_signature(), &args, THREAD); + check_pending_exception("Error while calling pollJavaQueue"); +} + oop VMExits::createRiMethodResolved(jlong vmId, Handle name, TRAPS) { assert(!name.is_null(), "just checking"); JavaValue result(T_OBJECT); diff -r 3822c5969a8b -r 5e9645341ec3 src/share/vm/graal/graalVMExits.hpp --- a/src/share/vm/graal/graalVMExits.hpp Tue Oct 25 14:44:32 2011 +0200 +++ b/src/share/vm/graal/graalVMExits.hpp Wed Nov 09 11:27:38 2011 +0100 @@ -59,6 +59,9 @@ // public abstract void startCompiler(); static void startCompiler(); + // public abstract void pollJavaQueue(); + static void pollJavaQueue(); + // public abstract RiMethod createRiMethodResolved(long vmId, String name); static oop createRiMethodResolved(jlong vmId, Handle name, TRAPS);