Split nterp frame alignment.

Make sure the dex PC pointer and caller FP are stored at
a pointer-aligned address.

Test: testrunner.py --host --interpreter
Change-Id: I7fe1be01b46558d871db24ce6cc08e35b68ec3fa
diff --git a/runtime/interpreter/mterp/x86_64ng/main.S b/runtime/interpreter/mterp/x86_64ng/main.S
index aeacec4..a890245 100644
--- a/runtime/interpreter/mterp/x86_64ng/main.S
+++ b/runtime/interpreter/mterp/x86_64ng/main.S
@@ -288,10 +288,13 @@
     leaq -24(%rsp), %r10
     subq %r11, %r10
     // Alignment
+    // Note: There may be two pieces of alignment but there is no need to align
+    // out args to `kPointerSize` separately before aligning to kStackAlignment.
     andq $$-16, %r10
 
-    // Set reference and dex registers.
-    leaq 24(%r10, \refs, 4), \refs
+    // Set reference and dex registers, align to pointer size for previous frame and dex pc.
+    leaq 24 + 4(%r10, \refs, 4), \refs
+    andq LITERAL(-__SIZEOF_POINTER__), \refs
     leaq (\refs, %rbx, 4), \fp
 
     // Now setup the stack pointer.
diff --git a/runtime/nterp_helpers.cc b/runtime/nterp_helpers.cc
index a2ec882..d622241 100644
--- a/runtime/nterp_helpers.cc
+++ b/runtime/nterp_helpers.cc
@@ -59,6 +59,8 @@
  *    ----------------      registers array for easy access from nterp when returning.
  *    |  dex_pc_ptr  |      Pointer to the dex instruction being executed.
  *    ----------------      Stored whenever nterp goes into the runtime.
+ *    |  alignment   |      Pointer aligment for dex_pc_ptr and caller_fp.
+ *    ----------------
  *    |              |      In case nterp calls compiled code, we reserve space
  *    |     out      |      for out registers. This space will be used for
  *    |   registers  |      arguments passed on stack.
@@ -97,6 +99,11 @@
   const uint16_t num_regs = accessor.RegistersSize();
   const uint16_t out_regs = accessor.OutsSize();
 
+  // Note: There may be two pieces of alignment but there is no need to align
+  // out args to `kPointerSize` separately before aligning to kStackAlignment.
+  static_assert(IsAligned<kPointerSize>(kStackAlignment));
+  static_assert(IsAligned<kPointerSize>(NterpGetFrameEntrySize()));
+  static_assert(IsAligned<kPointerSize>(kVRegSize * 2));
   size_t frame_size =
       NterpGetFrameEntrySize() +
       (num_regs * kVRegSize) * 2 +  // dex registers and reference registers
@@ -128,7 +135,7 @@
   // The references array is just above the saved frame pointer.
   return reinterpret_cast<uintptr_t>(frame) +
       kPointerSize +  // method
-      (out_regs * kVRegSize) +  // out arguments
+      RoundUp(out_regs * kVRegSize, kPointerSize) +  // out arguments and pointer alignment
       kPointerSize +  // saved dex pc
       kPointerSize;  // previous frame.
 }
@@ -138,7 +145,7 @@
   const uint16_t out_regs = accessor.OutsSize();
   uintptr_t dex_pc_ptr = reinterpret_cast<uintptr_t>(frame) +
       kPointerSize +  // method
-      (out_regs * kVRegSize);  // out arguments
+      RoundUp(out_regs * kVRegSize, kPointerSize);  // out arguments and pointer alignment
   CodeItemInstructionAccessor instructions((*frame)->DexInstructions());
   return *reinterpret_cast<const uint16_t**>(dex_pc_ptr) - instructions.Insns();
 }