# HG changeset patch # User Bernhard Urban # Date 1380532596 -7200 # Node ID 2d3d3d36ab3c2436bb3b0c7208a2f5bf1318aaeb # Parent 463f51256c86ce1511ec05ea292226ccdcd06a78 AMD64HotSpot: use conditional jump for IC_MISS_HANDLER diff -r 463f51256c86 -r 2d3d3d36ab3c graal/com.oracle.graal.asm.amd64/src/com/oracle/graal/asm/amd64/AMD64Assembler.java --- a/graal/com.oracle.graal.asm.amd64/src/com/oracle/graal/asm/amd64/AMD64Assembler.java Mon Sep 30 09:32:18 2013 +0200 +++ b/graal/com.oracle.graal.asm.amd64/src/com/oracle/graal/asm/amd64/AMD64Assembler.java Mon Sep 30 11:16:36 2013 +0200 @@ -747,7 +747,7 @@ emitOperandHelper(0, dst); } - private void jcc(ConditionFlag cc, int jumpTarget, boolean forceDisp32) { + public void jcc(ConditionFlag cc, int jumpTarget, boolean forceDisp32) { int shortSize = 2; int longSize = 6; long disp = jumpTarget - codeBuffer.position(); diff -r 463f51256c86 -r 2d3d3d36ab3c graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackend.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackend.java Mon Sep 30 09:32:18 2013 +0200 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackend.java Mon Sep 30 11:16:36 2013 +0200 @@ -256,8 +256,7 @@ } else { asm.cmpq(inlineCacheKlass, src); } - asm.jcc(ConditionFlag.Equal, verifiedStub); - AMD64Call.directJmp(tasm, asm, runtime().lookupForeignCall(IC_MISS_HANDLER)); + AMD64Call.directConditionalJmp(tasm, asm, runtime().lookupForeignCall(IC_MISS_HANDLER), ConditionFlag.NotEqual); } asm.align(config.codeEntryAlignment); diff -r 463f51256c86 -r 2d3d3d36ab3c graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Call.java --- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Call.java Mon Sep 30 09:32:18 2013 +0200 +++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Call.java Mon Sep 30 11:16:36 2013 +0200 @@ -28,6 +28,7 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.asm.amd64.*; +import com.oracle.graal.asm.amd64.AMD64Assembler.*; import com.oracle.graal.lir.*; import com.oracle.graal.lir.asm.*; import com.oracle.graal.nodes.spi.*; @@ -182,6 +183,14 @@ masm.ensureUniquePC(); } + public static void directConditionalJmp(TargetMethodAssembler tasm, AMD64MacroAssembler masm, InvokeTarget target, ConditionFlag cond) { + int before = masm.codeBuffer.position(); + masm.jcc(cond, 0, true); + int after = masm.codeBuffer.position(); + tasm.recordDirectCall(before, after, target, null); + masm.ensureUniquePC(); + } + public static void indirectCall(TargetMethodAssembler tasm, AMD64MacroAssembler masm, Register dst, InvokeTarget callTarget, LIRFrameState info) { int before = masm.codeBuffer.position(); masm.call(dst); diff -r 463f51256c86 -r 2d3d3d36ab3c src/cpu/x86/vm/graalCodeInstaller_x86.hpp --- a/src/cpu/x86/vm/graalCodeInstaller_x86.hpp Mon Sep 30 09:32:18 2013 +0200 +++ b/src/cpu/x86/vm/graalCodeInstaller_x86.hpp Mon Sep 30 11:16:36 2013 +0200 @@ -50,6 +50,9 @@ // the inlined vtable stub contains a "call register" instruction assert(method != NULL, "only valid for virtual calls"); return (pc_offset + ((NativeCallReg *) inst)->next_instruction_offset()); + } else if (inst->is_cond_jump()) { + address pc = (address) (inst); + return pc_offset + (jint) (Assembler::locate_next_instruction(pc) - pc); } else { fatal("unsupported type of instruction for call site"); return 0; @@ -155,11 +158,19 @@ NativeMovConstReg* mov = nativeMovConstReg_at((address) (inst)); mov->set_data((intptr_t) foreign_call_destination); _instructions->relocate(mov->instruction_address(), runtime_call_Relocation::spec(), Assembler::imm_operand); - } else { + } else if (inst->is_jump()) { NativeJump* jump = nativeJump_at((address) (inst)); jump->set_jump_destination((address) foreign_call_destination); - _instructions->relocate((address)inst, runtime_call_Relocation::spec(), Assembler::call32_operand); + _instructions->relocate(jump->instruction_address(), runtime_call_Relocation::spec(), Assembler::call32_operand); + } else if (inst->is_cond_jump()) { + address old_dest = nativeGeneralJump_at((address) (inst))->jump_destination(); + address disp = Assembler::locate_operand((address) (inst), Assembler::call32_operand); + *(jint*) disp += ((address) foreign_call_destination) - old_dest; + _instructions->relocate((address) (inst), runtime_call_Relocation::spec(), Assembler::call32_operand); + } else { + fatal("unsupported relocation for foreign call"); } + TRACE_graal_3("relocating (foreign call) at %p", inst); }