changeset 11826:2d3d3d36ab3c

AMD64HotSpot: use conditional jump for IC_MISS_HANDLER
author Bernhard Urban <bernhard.urban@jku.at>
date Mon, 30 Sep 2013 11:16:36 +0200
parents 463f51256c86
children ff1d8605f354
files graal/com.oracle.graal.asm.amd64/src/com/oracle/graal/asm/amd64/AMD64Assembler.java graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackend.java graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Call.java src/cpu/x86/vm/graalCodeInstaller_x86.hpp
diffstat 4 files changed, 24 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- 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();
--- 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);
--- 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);
--- 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);
 }