OSDN Git Service

[MIPS64] JNI Compiler: Sign-extend int function arguments
authorLazar Trsic <Lazar.Trsic@imgtec.com>
Wed, 24 Jun 2015 14:30:21 +0000 (16:30 +0200)
committerAndreas Gampe <agampe@google.com>
Thu, 25 Jun 2015 05:16:54 +0000 (22:16 -0700)
MIPS n64 ABI differs from arm64. Arguments smaller than the 8B stack
slot need to be sign-extended.

Use combination (lw,sd), instead of (lw,sw) for 4B values.

Change fixes software keyboard crash on mips64.

Bug: 21555893

(cherry picked from commit f652d605753f1387e7797461b47116c5dcdf928d)

Change-Id: I7574d37f6039e9e8c9e0047254be71d28d4c829a

compiler/jni/jni_compiler_test.cc
compiler/utils/mips64/assembler_mips64.cc
test/MyClassNatives/MyClassNatives.java

index e98e572..f3bda2f 100644 (file)
@@ -165,6 +165,7 @@ class JniCompilerTest : public CommonCompilerTest {
   void StackArgsIntsFirstImpl();
   void StackArgsFloatsFirstImpl();
   void StackArgsMixedImpl();
+  void StackArgsSignExtendedMips64Impl();
 
   JNIEnv* env_;
   jmethodID jmethod_;
@@ -1715,4 +1716,49 @@ void JniCompilerTest::StackArgsMixedImpl() {
 
 JNI_TEST(StackArgsMixed)
 
+void Java_MyClassNatives_stackArgsSignExtendedMips64(JNIEnv*, jclass, jint i1, jint i2, jint i3,
+                                                     jint i4, jint i5, jint i6, jint i7, jint i8) {
+  EXPECT_EQ(i1, 1);
+  EXPECT_EQ(i2, 2);
+  EXPECT_EQ(i3, 3);
+  EXPECT_EQ(i4, 4);
+  EXPECT_EQ(i5, 5);
+  EXPECT_EQ(i6, 6);
+  EXPECT_EQ(i7, 7);
+  EXPECT_EQ(i8, -8);
+
+#if defined(__mips__) && defined(__LP64__) && (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)
+  // Mips64 ABI requires that arguments passed through stack be sign-extended 8B slots.
+  // First 8 arguments are passed through registers, check i7 and i8.
+  uint32_t stack1_high = *(&i7 + 1);
+  uint32_t stack2_high = *(&i8 + 1);
+
+  EXPECT_EQ(stack1_high, static_cast<uint32_t>(0));
+  EXPECT_EQ(stack2_high, static_cast<uint32_t>(0xffffffff));
+#else
+  LOG(INFO) << "Skipping stackArgsSignExtendedMips64 as there is nothing to be done on "
+            << kRuntimeISA;
+  // Force-print to std::cout so it's also outside the logcat.
+  std::cout << "Skipping stackArgsSignExtendedMips64 as there is nothing to be done on "
+            << kRuntimeISA << std::endl;
+#endif
+}
+
+void JniCompilerTest::StackArgsSignExtendedMips64Impl() {
+  SetUpForTest(true, "stackArgsSignExtendedMips64", "(IIIIIIII)V",
+               reinterpret_cast<void*>(&Java_MyClassNatives_stackArgsSignExtendedMips64));
+  jint i1 = 1;
+  jint i2 = 2;
+  jint i3 = 3;
+  jint i4 = 4;
+  jint i5 = 5;
+  jint i6 = 6;
+  jint i7 = 7;
+  jint i8 = -8;
+
+  env_->CallStaticVoidMethod(jklass_, jmethod_, i1, i2, i3, i4, i5, i6, i7, i8);
+}
+
+JNI_TEST(StackArgsSignExtendedMips64)
+
 }  // namespace art
index a8b55d1..5e49b93 100644 (file)
@@ -839,7 +839,7 @@ void Mips64Assembler::Copy(FrameOffset dest, FrameOffset src,
   CHECK(size == 4 || size == 8) << size;
   if (size == 4) {
     LoadFromOffset(kLoadWord, scratch.AsGpuRegister(), SP, src.Int32Value());
-    StoreToOffset(kStoreWord, scratch.AsGpuRegister(), SP, dest.Int32Value());
+    StoreToOffset(kStoreDoubleword, scratch.AsGpuRegister(), SP, dest.Int32Value());
   } else if (size == 8) {
     LoadFromOffset(kLoadDoubleword, scratch.AsGpuRegister(), SP, src.Int32Value());
     StoreToOffset(kStoreDoubleword, scratch.AsGpuRegister(), SP, dest.Int32Value());
@@ -855,7 +855,7 @@ void Mips64Assembler::Copy(FrameOffset dest, ManagedRegister src_base, Offset sr
   if (size == 4) {
     LoadFromOffset(kLoadWord, scratch, src_base.AsMips64().AsGpuRegister(),
                    src_offset.Int32Value());
-    StoreToOffset(kStoreWord, scratch, SP, dest.Int32Value());
+    StoreToOffset(kStoreDoubleword, scratch, SP, dest.Int32Value());
   } else if (size == 8) {
     LoadFromOffset(kLoadDoubleword, scratch, src_base.AsMips64().AsGpuRegister(),
                    src_offset.Int32Value());
@@ -871,7 +871,7 @@ void Mips64Assembler::Copy(ManagedRegister dest_base, Offset dest_offset, FrameO
   CHECK(size == 4 || size == 8) << size;
   if (size == 4) {
     LoadFromOffset(kLoadWord, scratch, SP, src.Int32Value());
-    StoreToOffset(kStoreWord, scratch, dest_base.AsMips64().AsGpuRegister(),
+    StoreToOffset(kStoreDoubleword, scratch, dest_base.AsMips64().AsGpuRegister(),
                   dest_offset.Int32Value());
   } else if (size == 8) {
     LoadFromOffset(kLoadDoubleword, scratch, SP, src.Int32Value());
@@ -894,7 +894,7 @@ void Mips64Assembler::Copy(ManagedRegister dest, Offset dest_offset,
   CHECK(size == 4 || size == 8) << size;
   if (size == 4) {
     LoadFromOffset(kLoadWord, scratch, src.AsMips64().AsGpuRegister(), src_offset.Int32Value());
-    StoreToOffset(kStoreWord, scratch, dest.AsMips64().AsGpuRegister(), dest_offset.Int32Value());
+    StoreToOffset(kStoreDoubleword, scratch, dest.AsMips64().AsGpuRegister(), dest_offset.Int32Value());
   } else if (size == 8) {
     LoadFromOffset(kLoadDoubleword, scratch, src.AsMips64().AsGpuRegister(),
                    src_offset.Int32Value());
index 8b4a9a4..19c13f7 100644 (file)
@@ -94,6 +94,9 @@ class MyClassNatives {
         float f4, int i5, float f5, int i6, float f6, int i7, float f7, int i8, float f8, int i9,
         float f9, int i10, float f10);
 
+    native static void stackArgsSignExtendedMips64(int i1, int i2, int i3, int i4, int i5, int i6,
+        int i7, int i8);
+
     static native double logD(double d);
     static native float logF(float f);
     static native boolean returnTrue();