[aarch64-port-dev ] Call ICache::invalidate_range()

Andrew Haley aph at redhat.com
Thu Nov 6 15:00:32 UTC 2014


I'm sorry, that patch was very borked.  That should teach me not to do
three things at the same time.  Fixed thusly.  I did a bit of
refactoring and added a few comments, which should help.

Andrew.


# HG changeset patch
# User aph
# Date 1415285779 18000
#      Thu Nov 06 09:56:19 2014 -0500
# Node ID dba43b2d5ad23ab6ec6f5a4eebe34198a3ff7afc
# Parent  0d41be9874391a7394192c34c266f281211be4ea
Fix bugs found in the review of 58cfaeeb1c86.

diff -r 0d41be987439 -r dba43b2d5ad2 src/cpu/aarch64/vm/macroAssembler_aarch64.cpp
--- a/src/cpu/aarch64/vm/macroAssembler_aarch64.cpp	Wed Nov 05 09:14:16 2014 -0500
+++ b/src/cpu/aarch64/vm/macroAssembler_aarch64.cpp	Thu Nov 06 09:56:19 2014 -0500
@@ -65,8 +65,10 @@

 #define BIND(label) bind(label); BLOCK_COMMENT(#label ":")

+// Patch any kind of instruction; there may be several instructions.
+// Return the total length (in bytes) of the instructions.
 int MacroAssembler::pd_patch_instruction_size(address branch, address target) {
-  int size = 1;
+  int instructions = 1;
   assert((uint64_t)target < (1ul << 48), "48-bit overflow in address constant");
   long offset = (target - branch) >> 2;
   unsigned insn = *(unsigned*)branch;
@@ -120,14 +122,14 @@
 	Instruction_aarch64::patch(branch + sizeof (unsigned),
 				    21, 10, offset_lo >> size);
 	guarantee(((dest >> size) << size) == dest, "misaligned target");
-	size = 2;
+	instructions = 2;
       } else if (Instruction_aarch64::extract(insn2, 31, 22) == 0b1001000100 &&
 		Instruction_aarch64::extract(insn, 4, 0) ==
 			Instruction_aarch64::extract(insn2, 4, 0)) {
 	// add (immediate)
 	Instruction_aarch64::patch(branch + sizeof (unsigned),
 				   21, 10, offset_lo);
-	size = 2;
+	instructions = 2;
       } else {
 	assert((jbyte *)target ==
 		((CardTableModRefBS*)(Universe::heap()->barrier_set()))->byte_map_base ||
@@ -150,7 +152,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");
-    size = 3;
+    instructions = 3;
   } else if (Instruction_aarch64::extract(insn, 31, 22) == 0b1011100101 &&
              Instruction_aarch64::extract(insn, 4, 0) == 0b11111) {
     // nothing to do
@@ -158,20 +160,33 @@
   } else {
     ShouldNotReachHere();
   }
-  return size;
+  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
+    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) {
diff -r 0d41be987439 -r dba43b2d5ad2 src/cpu/aarch64/vm/macroAssembler_aarch64.hpp
--- a/src/cpu/aarch64/vm/macroAssembler_aarch64.hpp	Wed Nov 05 09:14:16 2014 -0500
+++ b/src/cpu/aarch64/vm/macroAssembler_aarch64.hpp	Thu Nov 06 09:56:19 2014 -0500
@@ -509,7 +509,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

diff -r 0d41be987439 -r dba43b2d5ad2 src/cpu/aarch64/vm/relocInfo_aarch64.cpp
--- a/src/cpu/aarch64/vm/relocInfo_aarch64.cpp	Wed Nov 05 09:14:16 2014 -0500
+++ b/src/cpu/aarch64/vm/relocInfo_aarch64.cpp	Thu Nov 06 09:56:19 2014 -0500
@@ -36,7 +36,7 @@
   if (verify_only)
     return;

-  int size;
+  int bytes;

   switch(type()) {
   case relocInfo::oop_type:
@@ -44,19 +44,18 @@
       oop_Relocation *reloc = (oop_Relocation *)this;
       if (NativeInstruction::is_ldr_literal_at(addr())) {
 	address constptr = (address)code()->oop_addr_at(reloc->oop_index());
-	size = MacroAssembler::pd_patch_instruction_size(addr(), constptr);
+	bytes = MacroAssembler::pd_patch_instruction_size(addr(), constptr);
 	assert(*(address*)constptr == x, "error in oop relocation");
       } else{
-	MacroAssembler::patch_oop(addr(), x);
-	size = NativeMovConstReg::instruction_size;
+	bytes = MacroAssembler::patch_oop(addr(), x);
       }
     }
     break;
   default:
-    int size = MacroAssembler::pd_patch_instruction_size(addr(), x);
+    bytes = MacroAssembler::pd_patch_instruction_size(addr(), x);
     break;
   }
-  ICache::invalidate_range(addr(), size);
+  ICache::invalidate_range(addr(), bytes);
 }

 address Relocation::pd_call_destination(address orig_addr) {


More information about the aarch64-port-dev mailing list