Mercurial > hg > graal-compiler
changeset 9046:c6a1ffc707ff
Comments and #ifdef GRAAL for recent changes to C++ code for calling nmethods directly.
author | Thomas Wuerthinger <thomas.wuerthinger@oracle.com> |
---|---|
date | Fri, 12 Apr 2013 17:22:54 +0200 |
parents | 9a3e25e270a0 |
children | 1946c86f8842 |
files | graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVMImpl.java src/cpu/sparc/vm/interpreter_sparc.cpp src/cpu/sparc/vm/sharedRuntime_sparc.cpp src/cpu/x86/vm/interpreterGenerator_x86.hpp src/cpu/x86/vm/sharedRuntime_x86_64.cpp src/cpu/x86/vm/templateInterpreter_x86_64.cpp src/share/vm/code/nmethod.cpp src/share/vm/interpreter/abstractInterpreter.hpp src/share/vm/interpreter/interpreter.cpp src/share/vm/interpreter/templateInterpreter.cpp src/share/vm/oops/method.cpp |
diffstat | 11 files changed, 60 insertions(+), 9 deletions(-) [+] |
line wrap: on
line diff
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVMImpl.java Fri Apr 12 06:19:35 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVMImpl.java Fri Apr 12 17:22:54 2013 +0200 @@ -170,5 +170,12 @@ return executeCompiledMethodIntrinsic(arg1, arg2, arg3, nativeMethod); } + /** + * Direct call to the given nativeMethod with three object arguments and an object return value. + * This method does not have an implementation on the C++ side, but its entry points (from + * interpreter and from compiled code) are directly pointing to a manually generated assembly + * stub that does the necessary argument shuffling and a tail call via an indirect jump to the + * verified entry point of the given native method. + */ private static native Object executeCompiledMethodIntrinsic(Object arg1, Object arg2, Object arg3, long nativeMethod); }
--- a/src/cpu/sparc/vm/interpreter_sparc.cpp Fri Apr 12 06:19:35 2013 +0200 +++ b/src/cpu/sparc/vm/interpreter_sparc.cpp Fri Apr 12 17:22:54 2013 +0200 @@ -381,7 +381,9 @@ case Interpreter::zerolocals_synchronized: synchronized = true; break; case Interpreter::native : entry_point = ((InterpreterGenerator*)this)->generate_native_entry(false); break; case Interpreter::native_synchronized : entry_point = ((InterpreterGenerator*)this)->generate_native_entry(true); break; +#ifdef GRAAL case Interpreter::execute_compiled_method: entry_point = ((InterpreterGenerator*)this)->generate_execute_compiled_method_entry(); break; +#endif case Interpreter::empty : entry_point = ((InterpreterGenerator*)this)->generate_empty_entry(); break; case Interpreter::accessor : entry_point = ((InterpreterGenerator*)this)->generate_accessor_entry(); break; case Interpreter::abstract : entry_point = ((InterpreterGenerator*)this)->generate_abstract_entry(); break;
--- a/src/cpu/sparc/vm/sharedRuntime_sparc.cpp Fri Apr 12 06:19:35 2013 +0200 +++ b/src/cpu/sparc/vm/sharedRuntime_sparc.cpp Fri Apr 12 17:22:54 2013 +0200 @@ -1917,7 +1917,6 @@ BasicType* in_sig_bt, VMRegPair* in_regs, BasicType ret_type) { - assert (method->intrinsic_id() != vmIntrinsics::_CompilerToVMImpl_executeCompiledMethod, "not yet ported"); if (method->is_method_handle_intrinsic()) { vmIntrinsics::ID iid = method->intrinsic_id(); intptr_t start = (intptr_t)__ pc();
--- a/src/cpu/x86/vm/interpreterGenerator_x86.hpp Fri Apr 12 06:19:35 2013 +0200 +++ b/src/cpu/x86/vm/interpreterGenerator_x86.hpp Fri Apr 12 17:22:54 2013 +0200 @@ -36,7 +36,9 @@ address generate_normal_entry(bool synchronized); address generate_native_entry(bool synchronized); +#ifdef GRAAL address generate_execute_compiled_method_entry(); +#endif address generate_abstract_entry(void); address generate_math_entry(AbstractInterpreter::MethodKind kind); address generate_empty_entry(void);
--- a/src/cpu/x86/vm/sharedRuntime_x86_64.cpp Fri Apr 12 06:19:35 2013 +0200 +++ b/src/cpu/x86/vm/sharedRuntime_x86_64.cpp Fri Apr 12 17:22:54 2013 +0200 @@ -1670,10 +1670,16 @@ verify_oop_args(masm, method, sig_bt, regs); vmIntrinsics::ID iid = method->intrinsic_id(); +#ifdef GRAAL if (iid == vmIntrinsics::_CompilerToVMImpl_executeCompiledMethod) { + // We are called from compiled code here. The three object arguments + // are already in the correct registers (j_rarg0, jrarg1, jrarg2). The + // fourth argument (j_rarg3) is a raw pointer to the nmethod. Make a tail + // call to its verified entry point. __ jmp(Address(j_rarg3, nmethod::verified_entry_point_offset())); return; } +#endif // Now write the args into the outgoing interpreter space bool has_receiver = false;
--- a/src/cpu/x86/vm/templateInterpreter_x86_64.cpp Fri Apr 12 06:19:35 2013 +0200 +++ b/src/cpu/x86/vm/templateInterpreter_x86_64.cpp Fri Apr 12 17:22:54 2013 +0200 @@ -873,6 +873,8 @@ return generate_accessor_entry(); } +#ifdef GRAAL + // Interpreter stub for calling a compiled method with 3 object arguments address InterpreterGenerator::generate_execute_compiled_method_entry() { address entry_point = __ pc(); @@ -891,14 +893,27 @@ // as far as the placement of the call instruction __ push(rax); + // Move first object argument from interpreter calling convention to compiled + // code calling convention. __ movq(j_rarg0, Address(r11, Interpreter::stackElementSize*5)); + + // Move second object argument. __ movq(j_rarg1, Address(r11, Interpreter::stackElementSize*4)); + + // Move third object argument. __ movq(j_rarg2, Address(r11, Interpreter::stackElementSize*3)); + + // Load the raw pointer to the nmethod. __ movq(j_rarg3, Address(r11, Interpreter::stackElementSize)); + + // Perform a tail call to the verified entry point of the nmethod. __ jmp(Address(j_rarg3, nmethod::verified_entry_point_offset())); + return entry_point; } +#endif + // Interpreter stub for calling a native method. (asm interpreter) // This sets up a somewhat different looking stack for calling the // native method than the typical interpreter frame setup. @@ -1586,7 +1601,9 @@ switch (kind) { case Interpreter::zerolocals : break; case Interpreter::zerolocals_synchronized: synchronized = true; break; +#ifdef GRAAL case Interpreter::execute_compiled_method: entry_point = ((InterpreterGenerator*)this)->generate_execute_compiled_method_entry(); break; +#endif case Interpreter::native : entry_point = ((InterpreterGenerator*)this)->generate_native_entry(false); break; case Interpreter::native_synchronized : entry_point = ((InterpreterGenerator*)this)->generate_native_entry(true); break; case Interpreter::empty : entry_point = ((InterpreterGenerator*)this)->generate_empty_entry(); break;
--- a/src/share/vm/code/nmethod.cpp Fri Apr 12 06:19:35 2013 +0200 +++ b/src/share/vm/code/nmethod.cpp Fri Apr 12 17:22:54 2013 +0200 @@ -1307,9 +1307,12 @@ } #ifdef GRAAL - if (_graal_installed_code != NULL) { - _graal_installed_code = NULL; - } + // The method can only be unloaded after the pointer to the installed code + // Java wrapper is no longer alive. Here we need to clear out this weak + // reference to the dead object. + if (_graal_installed_code != NULL) { + _graal_installed_code = NULL; + } #endif // Make the class unloaded - i.e., change state and notify sweeper @@ -1396,14 +1399,14 @@ // The caller can be calling the method statically or through an inline // cache call. if (!is_osr_method() && !is_not_entrant()) { + address stub = SharedRuntime::get_handle_wrong_method_stub(); +#ifdef GRAAL if (_graal_installed_code != NULL && !HotSpotInstalledCode::isDefault(_graal_installed_code)) { // This was manually installed machine code. Patch entry with stub that throws an exception. - NativeJump::patch_verified_entry(entry_point(), verified_entry_point(), - SharedRuntime::get_deoptimized_installed_code_stub()); - } else { - NativeJump::patch_verified_entry(entry_point(), verified_entry_point(), - SharedRuntime::get_handle_wrong_method_stub()); + stub = SharedRuntime::get_deoptimized_installed_code_stub(); } +#endif + NativeJump::patch_verified_entry(entry_point(), verified_entry_point(), stub); } if (is_in_use()) {
--- a/src/share/vm/interpreter/abstractInterpreter.hpp Fri Apr 12 06:19:35 2013 +0200 +++ b/src/share/vm/interpreter/abstractInterpreter.hpp Fri Apr 12 17:22:54 2013 +0200 @@ -85,7 +85,9 @@ zerolocals_synchronized, // method needs locals initialization & is synchronized native, // native method native_synchronized, // native method & is synchronized +#ifdef GRAAL execute_compiled_method, // direct call to compiled method address +#endif empty, // empty method (code: _return) accessor, // accessor method (code: _aload_0, _getfield, _(a|i)return) abstract, // abstract method (throws an AbstractMethodException)
--- a/src/share/vm/interpreter/interpreter.cpp Fri Apr 12 06:19:35 2013 +0200 +++ b/src/share/vm/interpreter/interpreter.cpp Fri Apr 12 17:22:54 2013 +0200 @@ -188,9 +188,13 @@ // Method handle primitive? if (m->is_method_handle_intrinsic()) { vmIntrinsics::ID id = m->intrinsic_id(); +#ifdef GRAAL if (id == vmIntrinsics::_CompilerToVMImpl_executeCompiledMethod) { + // Special method kind for directly executing the verified entry point + // of a given nmethod. return AbstractInterpreter::execute_compiled_method; } +#endif assert(MethodHandles::is_signature_polymorphic(id), "must match an intrinsic"); MethodKind kind = (MethodKind)( method_handle_invoke_FIRST + ((int)id - vmIntrinsics::FIRST_MH_SIG_POLY) ); @@ -290,7 +294,9 @@ case zerolocals_synchronized: tty->print("zerolocals_synchronized"); break; case native : tty->print("native" ); break; case native_synchronized : tty->print("native_synchronized" ); break; +#ifdef GRAAL case execute_compiled_method: tty->print("execute_compiled_method"); break; +#endif case empty : tty->print("empty" ); break; case accessor : tty->print("accessor" ); break; case abstract : tty->print("abstract" ); break;
--- a/src/share/vm/interpreter/templateInterpreter.cpp Fri Apr 12 06:19:35 2013 +0200 +++ b/src/share/vm/interpreter/templateInterpreter.cpp Fri Apr 12 17:22:54 2013 +0200 @@ -360,7 +360,9 @@ method_entry(zerolocals) method_entry(zerolocals_synchronized) method_entry(empty) +#ifdef GRAAL method_entry(execute_compiled_method) +#endif method_entry(accessor) method_entry(abstract) method_entry(java_lang_math_sin )
--- a/src/share/vm/oops/method.cpp Fri Apr 12 06:19:35 2013 +0200 +++ b/src/share/vm/oops/method.cpp Fri Apr 12 17:22:54 2013 +0200 @@ -850,10 +850,15 @@ (void) make_adapters(h_method, CHECK); // ONLY USE the h_method now as make_adapter may have blocked + +#ifdef GRAAL + // Check for special intrinsic that executes a compiled method. if (h_method->intrinsic_id() == vmIntrinsics::_CompilerToVMImpl_executeCompiledMethod) { + // Actively install the stub for calling the intrinsic from compiled code. CompileBroker::compile_method(h_method, InvocationEntryBci, CompLevel_highest_tier, methodHandle(), CompileThreshold, "executeCompiledMethod", CHECK); } +#endif } address Method::make_adapters(methodHandle mh, TRAPS) {