[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