Mercurial > hg > graal-jvmci-8
changeset 10684:6ff467cdb105
Code installer changes for SPARC.
author | twisti |
---|---|
date | Tue, 09 Jul 2013 14:39:34 -0700 |
parents | ae4c79ee71d1 |
children | 431eca622358 |
files | src/cpu/sparc/vm/graalCodeInstaller_sparc.hpp src/cpu/sparc/vm/sharedRuntime_sparc.cpp src/cpu/x86/vm/graalCodeInstaller_x86.hpp src/share/vm/graal/graalCodeInstaller.cpp src/share/vm/graal/graalCodeInstaller.hpp src/share/vm/prims/methodHandles.cpp |
diffstat | 6 files changed, 211 insertions(+), 37 deletions(-) [+] |
line wrap: on
line diff
--- a/src/cpu/sparc/vm/graalCodeInstaller_sparc.hpp Tue Jul 09 22:05:40 2013 +0200 +++ b/src/cpu/sparc/vm/graalCodeInstaller_sparc.hpp Tue Jul 09 14:39:34 2013 -0700 @@ -20,17 +20,82 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ + #ifndef CPU_SPARC_VM_CODEINSTALLER_SPARC_HPP #define CPU_SPARC_VM_CODEINSTALLER_SPARC_HPP +#include "graal/graalCompiler.hpp" +#include "graal/graalCompilerToVM.hpp" +#include "graal/graalJavaAccess.hpp" + inline jint CodeInstaller::pd_next_offset(NativeInstruction* inst, jint pc_offset, oop method) { - fatal("CodeInstaller::pd_next_offset - sparc unimp"); - return 0; + assert(inst->is_call() || inst->is_jump(), "sanity"); + return pc_offset + NativeCall::instruction_size; } -inline void CodeInstaller::pd_site_DataPatch(oop constant, oop kind, bool inlined, - address instruction, int alignment, char typeChar) { - fatal("CodeInstaller::pd_site_DataPatch - sparc unimp"); +inline void CodeInstaller::pd_site_DataPatch(int pc_offset, oop site) { + oop constant = CompilationResult_DataPatch::constant(site); + int alignment = CompilationResult_DataPatch::alignment(site); + bool inlined = CompilationResult_DataPatch::inlined(site) == JNI_TRUE; + + oop kind = Constant::kind(constant); + char typeChar = Kind::typeChar(kind); + + address pc = _instructions->start() + pc_offset; + + tty->print_cr("CodeInstaller::pd_site_DataPatch: typeChar=%c, inlined=%d", typeChar, inlined); + + switch (typeChar) { + case 'z': + case 'b': + case 's': + case 'c': + case 'i': + fatal("int-sized values not expected in DataPatch"); + break; + case 'f': + case 'j': + case 'd': { + if (inlined) { + fatal(err_msg("inlined: type=%c, constant=%lx", inlined, Constant::primitive(constant))); + } else { + int size = _constants->size(); + if (alignment > 0) { + guarantee(alignment <= _constants->alignment(), "Alignment inside constants section is restricted by alignment of section begin"); + size = align_size_up(size, alignment); + } + // we don't care if this is a long/double/etc., the primitive field contains the right bits + address dest = _constants->start() + size; + _constants->set_end(dest); + uint64_t value = Constant::primitive(constant); + _constants->emit_int64(value); + + NativeMovRegMem* load = nativeMovRegMem_at(pc); + int disp = _constants_size + pc_offset - size - BytesPerInstWord; + load->set_offset(-disp); + +// assert(disp == (jint) disp, "disp doesn't fit in 32 bits"); +// *((jint*) operand) = (jint) disp; + +// _instructions->relocate(instruction, section_word_Relocation::spec((address) dest, CodeBuffer::SECT_CONSTS) /*, Assembler::disp32_operand*/); +// TRACE_graal_3("relocating (%c) at %p/%p with destination at %p (%d)", typeChar, instruction, operand, dest, size); + } + break; + } + case 'a': { +// address operand = Assembler::locate_operand(instruction, Assembler::imm_operand); +// Handle obj = Constant::object(constant); +// +// jobject value = JNIHandles::make_local(obj()); +// *((jobject*) operand) = value; +// _instructions->relocate(instruction, oop_Relocation::spec_for_immediate(), Assembler::imm_operand); +// TRACE_graal_3("relocating (oop constant) at %p/%p", instruction, operand); + break; + } + default: + fatal(err_msg("unexpected Kind (%d) in DataPatch", typeChar)); + break; + } } inline void CodeInstaller::pd_relocate_CodeBlob(CodeBlob* cb, NativeInstruction* inst) { @@ -41,8 +106,49 @@ fatal("CodeInstaller::pd_relocate_ForeignCall - sparc unimp"); } -inline void CodeInstaller::pd_relocate_JavaMethod(oop method, jint pc_offset) { - fatal("CodeInstaller::pd_relocate_JavaMethod - sparc unimp"); +inline void CodeInstaller::pd_relocate_JavaMethod(oop hotspot_method, jint pc_offset) { +#ifdef ASSERT + Method* method = NULL; + // we need to check, this might also be an unresolved method + if (hotspot_method->is_a(HotSpotResolvedJavaMethod::klass())) { + method = getMethodFromHotSpotMethod(hotspot_method); + } +#endif + switch (_next_call_type) { + case MARK_INLINE_INVOKE: + break; + case MARK_INVOKEVIRTUAL: + case MARK_INVOKEINTERFACE: { + assert(method == NULL || !method->is_static(), "cannot call static method with invokeinterface"); + NativeCall* call = nativeCall_at(_instructions->start() + pc_offset); + call->set_destination(SharedRuntime::get_resolve_virtual_call_stub()); +// _instructions->relocate(call->instruction_address(), +// virtual_call_Relocation::spec(_invoke_mark_pc), +// Assembler::call32_operand); + fatal("NYI"); + break; + } + case MARK_INVOKESTATIC: { + assert(method == NULL || method->is_static(), "cannot call non-static method with invokestatic"); + NativeCall* call = nativeCall_at(_instructions->start() + pc_offset); + call->set_destination(SharedRuntime::get_resolve_static_call_stub()); + _instructions->relocate(call->instruction_address(), + relocInfo::static_call_type /*, Assembler::call32_operand*/); + break; + } + case MARK_INVOKESPECIAL: { + assert(method == NULL || !method->is_static(), "cannot call static method with invokespecial"); + NativeCall* call = nativeCall_at(_instructions->start() + pc_offset); + call->set_destination(SharedRuntime::get_resolve_opt_virtual_call_stub()); +// _instructions->relocate(call->instruction_address(), +// relocInfo::opt_virtual_call_type, Assembler::call32_operand); + fatal("NYI"); + break; + } + default: + fatal("invalid _next_call_type value"); + break; + } } inline int32_t* CodeInstaller::pd_locate_operand(address instruction) {
--- a/src/cpu/sparc/vm/sharedRuntime_sparc.cpp Tue Jul 09 22:05:40 2013 +0200 +++ b/src/cpu/sparc/vm/sharedRuntime_sparc.cpp Tue Jul 09 14:39:34 2013 -0700 @@ -1826,6 +1826,31 @@ 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 pointer to the HotSpotInstalledCode object. + + // Load the nmethod pointer from the HotSpotInstalledCode object +// __ movq(j_rarg3, Address(j_rarg3, sizeof(oopDesc))); + + // Check whether the nmethod was invalidated +// __ testq(j_rarg3, j_rarg3); +// Label invalid_nmethod; +// __ jcc(Assembler::zero, invalid_nmethod); + + // Perform a tail call to the verified entry point of the nmethod. +// __ jmp(Address(j_rarg3, nmethod::verified_entry_point_offset())); + +// __ bind(invalid_nmethod); + +// __ jump(RuntimeAddress(StubRoutines::throw_InvalidInstalledCodeException_entry())); + __ stop("_CompilerToVMImpl_executeCompiledMethod not implemented"); + return; + } +#endif + // Now write the args into the outgoing interpreter space bool has_receiver = false; Register receiver_reg = noreg;
--- a/src/cpu/x86/vm/graalCodeInstaller_x86.hpp Tue Jul 09 22:05:40 2013 +0200 +++ b/src/cpu/x86/vm/graalCodeInstaller_x86.hpp Tue Jul 09 14:39:34 2013 -0700 @@ -56,8 +56,16 @@ } } -inline void CodeInstaller::pd_site_DataPatch(oop constant, oop kind, bool inlined, - address instruction, int alignment, char typeChar) { +inline void CodeInstaller::pd_site_DataPatch(int pc_offset, oop site) { + oop constant = CompilationResult_DataPatch::constant(site); + int alignment = CompilationResult_DataPatch::alignment(site); + bool inlined = CompilationResult_DataPatch::inlined(site) == JNI_TRUE; + + oop kind = Constant::kind(constant); + char typeChar = Kind::typeChar(kind); + + address pc = _instructions->start() + pc_offset; + switch (typeChar) { case 'z': case 'b': @@ -70,11 +78,11 @@ case 'j': case 'd': { if (inlined) { - address operand = Assembler::locate_operand(instruction, Assembler::imm_operand); + address operand = Assembler::locate_operand(pc, Assembler::imm_operand); *((jlong*) operand) = Constant::primitive(constant); } else { - address operand = Assembler::locate_operand(instruction, Assembler::disp32_operand); - address next_instruction = Assembler::locate_next_instruction(instruction); + address operand = Assembler::locate_operand(pc, Assembler::disp32_operand); + address next_instruction = Assembler::locate_next_instruction(pc); int size = _constants->size(); if (alignment > 0) { guarantee(alignment <= _constants->alignment(), "Alignment inside constants section is restricted by alignment of section begin"); @@ -82,26 +90,27 @@ } // we don't care if this is a long/double/etc., the primitive field contains the right bits address dest = _constants->start() + size; - _constants->set_end(dest + BytesPerLong); - *(jlong*) dest = Constant::primitive(constant); + _constants->set_end(dest); + uint64_t value = Constant::primitive(constant); + _constants->emit_int64(value); long disp = dest - next_instruction; assert(disp == (jint) disp, "disp doesn't fit in 32 bits"); *((jint*) operand) = (jint) disp; - _instructions->relocate(instruction, section_word_Relocation::spec((address) dest, CodeBuffer::SECT_CONSTS), Assembler::disp32_operand); - TRACE_graal_3("relocating (%c) at %p/%p with destination at %p (%d)", typeChar, instruction, operand, dest, size); + _instructions->relocate(pc, section_word_Relocation::spec((address) dest, CodeBuffer::SECT_CONSTS), Assembler::disp32_operand); + TRACE_graal_3("relocating (%c) at %p/%p with destination at %p (%d)", typeChar, pc, operand, dest, size); } break; } case 'a': { - address operand = Assembler::locate_operand(instruction, Assembler::imm_operand); + address operand = Assembler::locate_operand(pc, Assembler::imm_operand); Handle obj = Constant::object(constant); jobject value = JNIHandles::make_local(obj()); *((jobject*) operand) = value; - _instructions->relocate(instruction, oop_Relocation::spec_for_immediate(), Assembler::imm_operand); - TRACE_graal_3("relocating (oop constant) at %p/%p", instruction, operand); + _instructions->relocate(pc, oop_Relocation::spec_for_immediate(), Assembler::imm_operand); + TRACE_graal_3("relocating (oop constant) at %p/%p", pc, operand); break; } default:
--- a/src/share/vm/graal/graalCodeInstaller.cpp Tue Jul 09 22:05:40 2013 +0200 +++ b/src/share/vm/graal/graalCodeInstaller.cpp Tue Jul 09 14:39:34 2013 -0700 @@ -171,7 +171,7 @@ if (value->is_a(RegisterValue::klass())) { jint number = code_Register::number(RegisterValue::reg(value)); - if (number < 16) { + if (number < RegisterImpl::number_of_registers) { if (type == T_INT || type == T_FLOAT || type == T_SHORT || type == T_CHAR || type == T_BOOLEAN || type == T_BYTE || type == T_ADDRESS) { locationType = Location::int_in_long; } else if (type == T_LONG) { @@ -366,6 +366,10 @@ jobject compiled_code_obj = JNIHandles::make_local(compiled_code()); initialize_assumptions(JNIHandles::resolve(compiled_code_obj)); + // Get instructions and constants CodeSections early because we need it. + _instructions = buffer.insts(); + _constants = buffer.consts(); + { No_Safepoint_Verifier no_safepoint; initialize_fields(JNIHandles::resolve(compiled_code_obj)); @@ -397,6 +401,11 @@ GraalCompiler::instance(), _debug_recorder, _dependencies, NULL, -1, false, leaf_graph_ids, installed_code, triggered_deoptimizations); cb = nm; } + + if (cb != NULL) { + // Make sure the pre-calculated constants section size was correct. + guarantee((cb->code_begin() - cb->content_begin()) == _constants_size, err_msg("%d != %d", cb->code_begin() - cb->content_begin(), _constants_size)); + } } void CodeInstaller::initialize_fields(oop compiled_code) { @@ -417,11 +426,12 @@ _code = (arrayOop) CompilationResult::targetCode(comp_result); _code_size = CompilationResult::targetCodeSize(comp_result); // The frame size we get from the target method does not include the return address, so add one word for it here. - _total_frame_size = CompilationResult::frameSize(comp_result) + HeapWordSize; + _total_frame_size = CompilationResult::frameSize(comp_result) + HeapWordSize; // FIXME this is an x86-ism _custom_stack_area_offset = CompilationResult::customStackAreaOffset(comp_result); - // (very) conservative estimate: each site needs a constant section entry - _constants_size = _sites->length() * (BytesPerLong*2); + // Pre-calculate the constants section size. This is required for PC-relative addressing. + _constants_size = calculate_constants_size(); + #ifndef PRODUCT _comments = (arrayOop) HotSpotCompiledCode::comments(compiled_code); #endif @@ -442,9 +452,6 @@ buffer.initialize_oop_recorder(_oop_recorder); - _instructions = buffer.insts(); - _constants = buffer.consts(); - // copy the code into the newly created CodeBuffer address end_pc = _instructions->start() + _code_size; if (!_instructions->allocates2(end_pc)) { @@ -454,7 +461,7 @@ _instructions->set_end(end_pc); for (int i = 0; i < _sites->length(); i++) { - oop site=((objArrayOop) (_sites))->obj_at(i); + oop site = ((objArrayOop) (_sites))->obj_at(i); jint pc_offset = CompilationResult_Site::pcOffset(site); if (site->is_a(CompilationResult_Call::klass())) { @@ -485,7 +492,7 @@ #ifndef PRODUCT if (_comments != NULL) { for (int i = 0; i < _comments->length(); i++) { - oop comment=((objArrayOop) (_comments))->obj_at(i); + oop comment = ((objArrayOop) (_comments))->obj_at(i); assert(comment->is_a(HotSpotCompiledCode_Comment::klass()), "cce"); jint offset = HotSpotCompiledCode_Comment::pcOffset(comment); char* text = java_lang_String::as_utf8_string(HotSpotCompiledCode_Comment::text(comment)); @@ -496,6 +503,35 @@ return true; } +/** + * Calculate the constants section size by iterating over all DataPatches. + * Knowing the size of the constants section before patching instructions + * is necessary for PC-relative addressing. + */ +int CodeInstaller::calculate_constants_size() { + int size = 0; + + for (int i = 0; i < _sites->length(); i++) { + oop site = ((objArrayOop) (_sites))->obj_at(i); + jint pc_offset = CompilationResult_Site::pcOffset(site); + + if (site->is_a(CompilationResult_DataPatch::klass())) { + oop constant = CompilationResult_DataPatch::constant(site); + int alignment = CompilationResult_DataPatch::alignment(site); + bool inlined = CompilationResult_DataPatch::inlined(site) == JNI_TRUE; + + if (!inlined) { + if (alignment > 0) { + guarantee(alignment <= _constants->alignment(), "Alignment inside constants section is restricted by alignment of section begin"); + size = align_size_up(size, alignment); + } + size = size + sizeof(int64_t); + } + } + } + return size == 0 ? 0 : align_size_up(size, _constants->alignment()); +} + void CodeInstaller::assumption_MethodContents(Handle assumption) { Handle method_handle = Assumptions_MethodContents::method(assumption()); methodHandle method = getMethodFromHotSpotMethod(method_handle()); @@ -732,11 +768,7 @@ void CodeInstaller::site_DataPatch(CodeBuffer& buffer, jint pc_offset, oop site) { oop constant = CompilationResult_DataPatch::constant(site); - int alignment = CompilationResult_DataPatch::alignment(site); - bool inlined = CompilationResult_DataPatch::inlined(site) == JNI_TRUE; oop kind = Constant::kind(constant); - - address instruction = _instructions->start() + pc_offset; char typeChar = Kind::typeChar(kind); switch (typeChar) { case 'f': @@ -745,7 +777,7 @@ record_metadata_in_constant(constant, _oop_recorder); break; } - CodeInstaller::pd_site_DataPatch(constant, kind, inlined, instruction, alignment, typeChar); + CodeInstaller::pd_site_DataPatch(pc_offset, site); } void CodeInstaller::site_Mark(CodeBuffer& buffer, jint pc_offset, oop site) {
--- a/src/share/vm/graal/graalCodeInstaller.hpp Tue Jul 09 22:05:40 2013 +0200 +++ b/src/share/vm/graal/graalCodeInstaller.hpp Tue Jul 09 14:39:34 2013 -0700 @@ -76,7 +76,7 @@ ExceptionHandlerTable _exception_handler_table; jint pd_next_offset(NativeInstruction* inst, jint pc_offset, oop method); - void pd_site_DataPatch(oop constant, oop kind, bool inlined, address instruction, int alignment, char typeChar); + void pd_site_DataPatch(int pc_offset, oop site); void pd_relocate_CodeBlob(CodeBlob* cb, NativeInstruction* inst); void pd_relocate_ForeignCall(NativeInstruction* inst, jlong foreign_call_destination); void pd_relocate_JavaMethod(oop method, jint pc_offset); @@ -96,6 +96,8 @@ // perform data and call relocation on the CodeBuffer bool initialize_buffer(CodeBuffer& buffer); + int calculate_constants_size(); + void assumption_MethodContents(Handle assumption); void assumption_NoFinalizableSubclass(Handle assumption); void assumption_ConcreteSubtype(Handle assumption);
--- a/src/share/vm/prims/methodHandles.cpp Tue Jul 09 22:05:40 2013 +0200 +++ b/src/share/vm/prims/methodHandles.cpp Tue Jul 09 14:39:34 2013 -0700 @@ -342,7 +342,7 @@ Symbol* MethodHandles::signature_polymorphic_intrinsic_name(vmIntrinsics::ID iid) { - assert(is_signature_polymorphic_intrinsic(iid), err_msg("iid=%d", iid)); + assert(is_signature_polymorphic_intrinsic(iid), err_msg("%d %s", iid, vmIntrinsics::name_at(iid))); switch (iid) { case vmIntrinsics::_invokeBasic: return vmSymbols::invokeBasic_name(); case vmIntrinsics::_linkToVirtual: return vmSymbols::linkToVirtual_name(); @@ -350,7 +350,7 @@ case vmIntrinsics::_linkToSpecial: return vmSymbols::linkToSpecial_name(); case vmIntrinsics::_linkToInterface: return vmSymbols::linkToInterface_name(); } - assert(false, ""); + fatal(err_msg("unknown intrinsic id: %d %s", iid, vmIntrinsics::name_at(iid))); return 0; } @@ -362,7 +362,7 @@ case vmIntrinsics::_linkToSpecial: return JVM_REF_invokeSpecial; case vmIntrinsics::_linkToInterface: return JVM_REF_invokeInterface; } - assert(false, err_msg("iid=%d", iid)); + fatal(err_msg("unknown intrinsic id: %d %s", iid, vmIntrinsics::name_at(iid))); return 0; }