changeset 8074:bbff923bf024

8169185: aarch32: fix native call site check Reviewed-by: enevill Contributed-by: yangyongyong <yangyongyong@huawei.com>, Anton Kozlov <akozlov@azul.com>
author enevill
date Thu, 03 Nov 2016 10:04:26 +0000
parents 4d49ebf4b433
children 1de174b764f9
files src/cpu/aarch32/vm/nativeInst_aarch32.cpp src/cpu/aarch32/vm/nativeInst_aarch32.hpp
diffstat 2 files changed, 33 insertions(+), 16 deletions(-) [+]
line wrap: on
line diff
--- a/src/cpu/aarch32/vm/nativeInst_aarch32.cpp	Thu Oct 27 18:42:29 2016 +0300
+++ b/src/cpu/aarch32/vm/nativeInst_aarch32.cpp	Thu Nov 03 10:04:26 2016 +0000
@@ -106,8 +106,16 @@
 }
 
 bool NativeCall::is_call_before(address return_address) {
-  return is_at(return_address - NativeImmCall::instruction_size) ||
-    is_at(return_address - NativeCall::instruction_size);
+  if (NativeTrampolineCall::is_at(return_address - NativeCall::instruction_size)) {
+    return true;
+  } else if (NativeMovConstReg::is_at(return_address - NativeCall::instruction_size)) {
+    NativeMovConstReg *nm = NativeMovConstReg::from(return_address - NativeCall::instruction_size);
+    address next_instr = nm->next_instruction_address();
+    return NativeRegCall::is_at(next_instr) && NativeRegCall::from(next_instr)->destination() == nm->destination();
+  } else if (NativeImmCall::is_at(return_address - NativeBranchType::instruction_size)) {
+    return true;
+  }
+  return false;
 }
 
 address NativeCall::next_instruction_address() const {
--- a/src/cpu/aarch32/vm/nativeInst_aarch32.hpp	Thu Oct 27 18:42:29 2016 +0300
+++ b/src/cpu/aarch32/vm/nativeInst_aarch32.hpp	Thu Nov 03 10:04:26 2016 +0000
@@ -304,20 +304,6 @@
   return NativeCall::from(address);
 }
 
-inline NativeCall* nativeCall_before(address return_address) {
-  address call_addr = NULL;
-  if (NativeCall::is_at(return_address - NativeBranchType::instruction_size)) {
-    call_addr = return_address - NativeBranchType::instruction_size;
-  } else if (NativeCall::is_at(return_address - NativeCall::instruction_size)) {
-    call_addr = return_address - NativeCall::instruction_size;
-  } else {
-    ShouldNotReachHere();
-  }
-
-  return NativeCall::from(call_addr);
-}
-
-
 // An interface for accessing/manipulating native moves of the form:
 //      mov[b/w/l/q] [reg + offset], reg   (instruction_code_reg2mem)
 //      mov[b/w/l/q] reg, [reg+offset]     (instruction_code_mem2reg
@@ -506,4 +492,27 @@
 inline bool NativeInstruction::is_imm_jump() const      { return NativeImmJump::is_at(addr()); }
 inline bool NativeInstruction::is_reg_jump() const      { return NativeRegJump::is_at(addr()); }
 
+inline NativeCall* nativeCall_before(address return_address) {
+  address call_addr = NULL;
+  if (NativeTrampolineCall::is_at(return_address - NativeCall::instruction_size)) {
+    call_addr = return_address - NativeCall::instruction_size;
+  } else if (NativeMovConstReg::is_at(return_address - NativeCall::instruction_size)) {
+    NativeMovConstReg *nm = NativeMovConstReg::from(return_address - NativeCall::instruction_size);
+    address next_instr = nm->next_instruction_address();
+    if (NativeRegCall::is_at(next_instr) &&
+            NativeRegCall::from(next_instr)->destination() == nm->destination()) {
+      call_addr = return_address - NativeCall::instruction_size;
+    }
+  }
+  if (!call_addr) {
+    if (NativeImmCall::is_at(return_address - NativeBranchType::instruction_size)) {
+      call_addr = return_address - NativeBranchType::instruction_size;
+    } else {
+      ShouldNotReachHere();
+    }
+  }
+
+  return NativeCall::from(call_addr);
+}
+
 #endif // CPU_AARCH32_VM_NATIVEINST_AARCH32_HPP