changeset 5684:93b1103ebb83

Call ICache::invalidate_range() from Relocation::pd_set_data_value(). also includes corrections supplied by Ed in 7818 dba43b2d5ad2
author adinn
date Fri, 21 Nov 2014 20:26:35 +0000
parents 4df02e5f0433
children 4868ef1912f1
files src/cpu/aarch64/vm/assembler_aarch64.cpp src/cpu/aarch64/vm/assembler_aarch64.hpp src/cpu/aarch64/vm/relocInfo_aarch64.cpp
diffstat 3 files changed, 42 insertions(+), 13 deletions(-) [+]
line wrap: on
line diff
--- a/src/cpu/aarch64/vm/assembler_aarch64.cpp	Fri Nov 21 19:18:22 2014 +0000
+++ b/src/cpu/aarch64/vm/assembler_aarch64.cpp	Fri Nov 21 20:26:35 2014 +0000
@@ -1573,7 +1573,8 @@
 
 // Implementation of MacroAssembler
 
-void MacroAssembler::pd_patch_instruction(address branch, address target) {
+int MacroAssembler::pd_patch_instruction_size(address branch, address target) {
+  int instructions = 1;
   assert((uint64_t)target < (1ul << 48), "48-bit overflow in address constant");
   long offset = (target - branch) >> 2;
   unsigned insn = *(unsigned*)branch;
@@ -1634,6 +1635,7 @@
 	Instruction_aarch64::patch(branch + sizeof (unsigned),
 				    21, 10, offset_lo >> size);
 	guarantee(((dest >> size) << size) == dest, "misaligned target");
+        instructions = 2;
       } else if (Instruction_aarch64::extract(insn2, 31, 22) == 0b1001000100 &&
 		Instruction_aarch64::extract(insn, 4, 0) ==
 			Instruction_aarch64::extract(insn2, 4, 0)) {
@@ -1643,6 +1645,7 @@
 		(offset_lo & 0x3FFl) == 0, "offset must be 0x400 aligned for crc_table");
 	Instruction_aarch64::patch(branch + sizeof (unsigned),
 				   21, 10, offset_lo);
+        instructions = 2;
       } else {
 	assert((jbyte *)target ==
 		((CardTableModRefBS*)(Universe::heap()->barrier_set()))->byte_map_base ||
@@ -1665,6 +1668,7 @@
     Instruction_aarch64::patch(branch+4, 20, 5, (dest >>= 16) & 0xffff);
     Instruction_aarch64::patch(branch+8, 20, 5, (dest >>= 16) & 0xffff);
     assert(pd_call_destination(branch) == target, "should be");
+    instructions = 2;
   } else if (Instruction_aarch64::extract(insn, 31, 22) == 0b1011100101 &&
              Instruction_aarch64::extract(insn, 4, 0) == 0b11111) {
     // nothing to do
@@ -1672,19 +1676,34 @@
   } else {
     ShouldNotReachHere();
   }
+  return instructions * NativeInstruction::instruction_size;
 }
 
-void MacroAssembler::patch_oop(address insn_addr, address o) {
+int MacroAssembler::patch_oop(address insn_addr, address o) {
+  int instructions;
   unsigned insn = *(unsigned*)insn_addr;
+  assert(nativeInstruction_at(insn_addr+4)->is_movk(), "wrong insns in patch");
+
+  // OOPs are either narrow (32 bits) or wide (48 bits).  We encode
+  // narrow OOPs by setting the upper 16 bits in the first
+  // instruction.
   if (Instruction_aarch64::extract(insn, 31, 21) == 0b11010010101) {
-      // Move narrow constant
-      assert(nativeInstruction_at(insn_addr+4)->is_movk(), "wrong insns in patch");
-      narrowOop n = oopDesc::encode_heap_oop((oop)o);
-      Instruction_aarch64::patch(insn_addr, 20, 5, n >> 16);
-      Instruction_aarch64::patch(insn_addr+4, 20, 5, n & 0xffff);
+    // Move narrow OOP
+    assert(nativeInstruction_at(insn_addr+4)->is_movk(), "wrong insns in patch");
+    narrowOop n = oopDesc::encode_heap_oop((oop)o);
+    Instruction_aarch64::patch(insn_addr, 20, 5, n >> 16);
+    Instruction_aarch64::patch(insn_addr+4, 20, 5, n & 0xffff);
+    instructions = 2;
   } else {
-    pd_patch_instruction(insn_addr, o);
+    // Move wide OOP
+    assert(nativeInstruction_at(insn_addr+8)->is_movk(), "wrong insns in patch");
+    uintptr_t dest = (uintptr_t)o;
+    Instruction_aarch64::patch(insn_addr, 20, 5, dest & 0xffff);
+    Instruction_aarch64::patch(insn_addr+4, 20, 5, (dest >>= 16) & 0xffff);
+    Instruction_aarch64::patch(insn_addr+8, 20, 5, (dest >>= 16) & 0xffff);
+    instructions = 3;
   }
+  return instructions * NativeInstruction::instruction_size;
 }
 
 address MacroAssembler::target_addr_for_insn(address insn_addr, unsigned insn) {
--- a/src/cpu/aarch64/vm/assembler_aarch64.hpp	Fri Nov 21 19:18:22 2014 +0000
+++ b/src/cpu/aarch64/vm/assembler_aarch64.hpp	Fri Nov 21 20:26:35 2014 +0000
@@ -2727,7 +2727,10 @@
 
   // Required platform-specific helpers for Label::patch_instructions.
   // They _shadow_ the declarations in AbstractAssembler, which are undefined.
-  static void pd_patch_instruction(address branch, address target);
+  static int pd_patch_instruction_size (address branch, address target);
+  static void pd_patch_instruction(address branch, address target) {
+    pd_patch_instruction_size (branch, target);
+  }
   static address pd_call_destination(address branch) {
     unsigned insn = *(unsigned*)branch;
     return target_addr_for_insn(branch, insn);
@@ -2736,7 +2739,7 @@
   static void pd_print_patched_instruction(address branch);
 #endif
 
-  static void patch_oop(address insn_addr, address o);
+  static int patch_oop(address insn_addr, address o);
 
   // The following 4 methods return the offset of the appropriate move instruction
 
--- a/src/cpu/aarch64/vm/relocInfo_aarch64.cpp	Fri Nov 21 19:18:22 2014 +0000
+++ b/src/cpu/aarch64/vm/relocInfo_aarch64.cpp	Fri Nov 21 20:26:35 2014 +0000
@@ -34,23 +34,30 @@
 
 
 void Relocation::pd_set_data_value(address x, intptr_t o, bool verify_only) {
+  if (verify_only) {
+    return;
+  }
+
+  int bytes;
+
   switch(type()) {
   case relocInfo::oop_type:
     {
       oop_Relocation *reloc = (oop_Relocation *)this;
       if (NativeInstruction::is_ldr_literal_at(addr())) {
 	address constptr = (address)code()->oop_addr_at(reloc->oop_index());
-	MacroAssembler::pd_patch_instruction(addr(), constptr);
+	bytes = MacroAssembler::pd_patch_instruction_size(addr(), constptr);
 	assert(*(address*)constptr == x, "error in oop relocation");
       } else{
-	MacroAssembler::patch_oop(addr(), x);
+	bytes = MacroAssembler::patch_oop(addr(), x);
       }
     }
     break;
   default:
-    MacroAssembler::pd_patch_instruction(addr(), x);
+    bytes = MacroAssembler::pd_patch_instruction_size(addr(), x);
     break;
   }
+  ICache::invalidate_range(addr(), bytes);
 }
 
 address Relocation::pd_call_destination(address orig_addr) {