OSDN Git Service

JNI dlsym lookup fixes.
authorIan Rogers <irogers@google.com>
Tue, 8 Jul 2014 04:44:06 +0000 (21:44 -0700)
committerIan Rogers <irogers@google.com>
Tue, 8 Jul 2014 04:44:06 +0000 (21:44 -0700)
Thread* self is passed on all architectures apart from ARM and ARM64.
On x86 restore ebx correctly. Pass self in correct register on x86-64.
Ensure methods are compiled in jni_compiler_test even if the generic JNI
trampoline is present.

Change-Id: If5fdb1de97b78ac5a5cf8d0915c5b82311f23eb9

compiler/jni/jni_compiler_test.cc
runtime/arch/x86/jni_entrypoints_x86.S
runtime/arch/x86_64/jni_entrypoints_x86_64.S
runtime/entrypoints/jni/jni_entrypoints.cc
runtime/entrypoints/quick/quick_trampoline_entrypoints.cc

index 25b489b..b4d863b 100644 (file)
@@ -61,8 +61,8 @@ class JniCompilerTest : public CommonCompilerTest {
       method = c->FindVirtualMethod(method_name, method_sig);
     }
     ASSERT_TRUE(method != nullptr) << method_name << " " << method_sig;
-    if (method->GetEntryPointFromQuickCompiledCode() == nullptr) {
-      ASSERT_TRUE(method->GetEntryPointFromPortableCompiledCode() == nullptr);
+    if (method->GetEntryPointFromQuickCompiledCode() == nullptr ||
+        method->GetEntryPointFromQuickCompiledCode() == class_linker_->GetQuickGenericJniTrampoline()) {
       CompileMethod(method);
       ASSERT_TRUE(method->GetEntryPointFromQuickCompiledCode() != nullptr)
           << method_name << " " << method_sig;
index 45d7356..997a259 100644 (file)
@@ -26,9 +26,11 @@ DEFINE_FUNCTION art_jni_dlsym_lookup_stub
     pushl %fs:THREAD_SELF_OFFSET  // pass Thread::Current()
     CFI_ADJUST_CFA_OFFSET(4)
     call PLT_SYMBOL(artFindNativeMethod)  // (Thread*)
-    UNDO_SETUP_GOT
-    addl LITERAL(8), %esp         // restore the stack
-    CFI_ADJUST_CFA_OFFSET(-12)
+    addl LITERAL(4), %esp         // remove argument
+    CFI_ADJUST_CFA_OFFSET(-4)
+    UNDO_SETUP_GOT                // pop ebx
+    addl LITERAL(4), %esp         // remove padding
+    CFI_ADJUST_CFA_OFFSET(-4)
     testl %eax, %eax         // check if returned method code is null
     jz .Lno_native_code_found     // if null, jump to return to handle
     jmp *%eax                     // otherwise, tail call to intended method
index 10f39b7..d668797 100644 (file)
@@ -23,7 +23,7 @@ DEFINE_FUNCTION art_jni_dlsym_lookup_stub
     // Save callee and GPR args, mixed together to agree with core spills bitmap.
     PUSH r9   // Arg.
     PUSH r8   // Arg.
-    PUSH rdi  //
+    PUSH rdi  // JniEnv.
     PUSH rsi  // Arg.
     PUSH rdx  // Arg.
     PUSH rcx  // Arg.
@@ -40,7 +40,7 @@ DEFINE_FUNCTION art_jni_dlsym_lookup_stub
     movq %xmm6, 48(%rsp)
     movq %xmm7, 56(%rsp)
     // prepare call
-    movq %gs:THREAD_SELF_OFFSET, %rsi      // RSI := Thread::Current()
+    movq %gs:THREAD_SELF_OFFSET, %rdi      // RDI := Thread::Current()
     // call
     call PLT_SYMBOL(artFindNativeMethod)  // (Thread*)
     // restore arguments
@@ -57,7 +57,7 @@ DEFINE_FUNCTION art_jni_dlsym_lookup_stub
     POP rcx  // Arg.
     POP rdx  // Arg.
     POP rsi  // Arg.
-    POP rdi  //
+    POP rdi  // JniEnv.
     POP r8   // Arg.
     POP r9   // Arg.
     testq %rax, %rax         // check if returned method code is null
index bea7d96..bae4023 100644 (file)
 namespace art {
 
 // Used by the JNI dlsym stub to find the native method to invoke if none is registered.
+#if defined(__arm__) || defined(__aarch64__)
 extern "C" void* artFindNativeMethod() {
   Thread* self = Thread::Current();
+#else
+extern "C" void* artFindNativeMethod(Thread* self) {
+  DCHECK_EQ(self, Thread::Current());
+#endif
   Locks::mutator_lock_->AssertNotHeld(self);  // We come here as Native.
   ScopedObjectAccess soa(self);
 
index 6fb9624..95cb85e 100644 (file)
@@ -1565,7 +1565,11 @@ void BuildGenericJniFrameVisitor::FinalizeHandleScope(Thread* self) {
   self->PushHandleScope(handle_scope_);
 }
 
+#if defined(__arm__) || defined(__aarch64__)
 extern "C" void* artFindNativeMethod();
+#else
+extern "C" void* artFindNativeMethod(Thread* self);
+#endif
 
 uint64_t artQuickGenericJniEndJNIRef(Thread* self, uint32_t cookie, jobject l, jobject lock) {
   if (lock != nullptr) {
@@ -1638,7 +1642,11 @@ extern "C" TwoWordReturn artQuickGenericJniTrampoline(Thread* self,
   // pointer.
   DCHECK(nativeCode != nullptr);
   if (nativeCode == GetJniDlsymLookupStub()) {
+#if defined(__arm__) || defined(__aarch64__)
     nativeCode = artFindNativeMethod();
+#else
+    nativeCode = artFindNativeMethod(self);
+#endif
 
     if (nativeCode == nullptr) {
       DCHECK(self->IsExceptionPending());    // There should be an exception pending now.