OSDN Git Service

Trampoline and assembly fixes for ARM64
authorAndreas Gampe <agampe@google.com>
Mon, 24 Mar 2014 23:45:44 +0000 (16:45 -0700)
committerAndreas Gampe <agampe@google.com>
Mon, 24 Mar 2014 23:45:44 +0000 (16:45 -0700)
Trampolines need a jump, not a call. Expose br in the ARM64
assembler to allow this.

The resolution trampoline is called with the Quick ABI, and will
continue to a Quick ABI function. Then the method pointer must be
in x0.

Change-Id: I4e383b59d6c40a659d324a7faef3fadf0c890178

compiler/trampolines/trampoline_compiler.cc
compiler/utils/arm64/assembler_arm64.cc
compiler/utils/arm64/assembler_arm64.h
runtime/arch/arm64/quick_entrypoints_arm64.S

index 4dffef9..32980cb 100644 (file)
@@ -62,7 +62,7 @@ static const std::vector<uint8_t>* CreateTrampoline(EntryPointCallingConvention
   switch (abi) {
     case kInterpreterAbi:  // Thread* is first argument (X0) in interpreter ABI.
       // FIXME IPx used by VIXL - this is unsafe.
-      __ Call(Arm64ManagedRegister::FromCoreRegister(X0), Offset(offset.Int32Value()),
+      __ JumpTo(Arm64ManagedRegister::FromCoreRegister(X0), Offset(offset.Int32Value()),
           Arm64ManagedRegister::FromCoreRegister(IP1));
 
       break;
@@ -73,13 +73,13 @@ static const std::vector<uint8_t>* CreateTrampoline(EntryPointCallingConvention
                       Offset(JNIEnvExt::SelfOffset().Int32Value()));
 
       // FIXME IPx used by VIXL - this is unsafe.
-      __ Call(Arm64ManagedRegister::FromCoreRegister(IP1), Offset(offset.Int32Value()),
+      __ JumpTo(Arm64ManagedRegister::FromCoreRegister(IP1), Offset(offset.Int32Value()),
                 Arm64ManagedRegister::FromCoreRegister(IP0));
 
       break;
     case kPortableAbi:  // X18 holds Thread*.
     case kQuickAbi:  // Fall-through.
-      __ Call(Arm64ManagedRegister::FromCoreRegister(TR), Offset(offset.Int32Value()),
+      __ JumpTo(Arm64ManagedRegister::FromCoreRegister(TR), Offset(offset.Int32Value()),
                 Arm64ManagedRegister::FromCoreRegister(IP0));
 
       break;
index b364ba0..00ce923 100644 (file)
@@ -468,6 +468,15 @@ void Arm64Assembler::Call(ManagedRegister m_base, Offset offs, ManagedRegister m
   ___ Blr(reg_x(scratch.AsCoreRegister()));
 }
 
+void Arm64Assembler::JumpTo(ManagedRegister m_base, Offset offs, ManagedRegister m_scratch) {
+  Arm64ManagedRegister base = m_base.AsArm64();
+  Arm64ManagedRegister scratch = m_scratch.AsArm64();
+  CHECK(base.IsCoreRegister()) << base;
+  CHECK(scratch.IsCoreRegister()) << scratch;
+  LoadFromOffset(scratch.AsCoreRegister(), base.AsCoreRegister(), offs.Int32Value());
+  ___ Br(reg_x(scratch.AsCoreRegister()));
+}
+
 void Arm64Assembler::Call(FrameOffset base, Offset offs, ManagedRegister m_scratch) {
   Arm64ManagedRegister scratch = m_scratch.AsArm64();
   CHECK(scratch.IsCoreRegister()) << scratch;
index 2bada3f..1c47e77 100644 (file)
@@ -204,6 +204,9 @@ class Arm64Assembler : public Assembler {
   void Call(FrameOffset base, Offset offset, ManagedRegister scratch);
   void Call(ThreadOffset offset, ManagedRegister scratch);
 
+  // Jump to address (not setting link register)
+  void JumpTo(ManagedRegister m_base, Offset offs, ManagedRegister m_scratch);
+
   // Generate code to check if Thread::Current()->exception_ is non-null
   // and branch to a ExceptionSlowPath if it is.
   void ExceptionPoll(ManagedRegister scratch, size_t stack_adjust);
index 9db07f8..447854f 100644 (file)
@@ -887,13 +887,15 @@ UNIMPLEMENTED art_quick_imt_conflict_trampoline
 
 ENTRY art_quick_resolution_trampoline
     SETUP_REF_AND_ARGS_CALLEE_SAVE_FRAME
+    mov x19, x0           // save the called method
     mov x2, xSELF
     mov x3, sp
     bl artQuickResolutionTrampoline  // (called, receiver, Thread*, SP)
-    mov x9, x0           // Remember returned code pointer in x9.
+    mov x9, x0            // Remember returned code pointer in x9.
+    mov x0, x19           // Restore the method, before x19 is restored to on-call value
     RESTORE_REF_AND_ARGS_CALLEE_SAVE_FRAME
     cbz x9, 1f
-    br x0
+    br x9
 1:
     RESTORE_REF_AND_ARGS_CALLEE_SAVE_FRAME
     DELIVER_PENDING_EXCEPTION