Fix generic jni issue in ArtMethod::GetQuickFrameInfo

The 64-bit host mode fails to start due to incorrect
detection of GetQuickGenericJniTrampoline.
The quick_code is 32-bit and taken from oat file, but
GetQuickGenericJniTrampoline returnf 0x7fffxx (64-bit)
address of trampoline and execution went to incorrect way.

Some clean-up.

Original Author: Dmitry Petrochenko <dmitry.petrochenko@intel.com>
Signed-off-by: Dmitry Petrochenko <dmitry.petrochenko@intel.com>
Signed-off-by: Serguei Katkov <serguei.i.katkov@intel.com>
Change-Id: I0952443b2a9f6833ad37ec373837ae208681fad7
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index 6b98da9..84a3c5d 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -191,6 +191,9 @@
   memset(find_array_class_cache_, 0, kFindArrayCacheSize * sizeof(mirror::Class*));
 }
 
+// To set a value for generic JNI. May be necessary in compiler tests.
+extern "C" void art_quick_generic_jni_trampoline(mirror::ArtMethod*);
+
 void ClassLinker::InitFromCompiler(const std::vector<const DexFile*>& boot_class_path) {
   VLOG(startup) << "ClassLinker::Init";
   CHECK(Runtime::Current()->IsCompiler());
@@ -343,6 +346,10 @@
   runtime->SetImtConflictMethod(runtime->CreateImtConflictMethod());
   runtime->SetDefaultImt(runtime->CreateDefaultImt(this));
 
+  // Set up GenericJNI entrypoint. That is mainly a hack for common_compiler_test.h so that
+  // we do not need friend classes or a publicly exposed setter.
+  quick_generic_jni_trampoline_ = reinterpret_cast<void*>(art_quick_generic_jni_trampoline);
+
   // Object, String and DexCache need to be rerun through FindSystemClass to finish init
   java_lang_Object->SetStatus(mirror::Class::kStatusNotReady, self);
   mirror::Class* Object_class = FindSystemClass(self, "Ljava/lang/Object;");
@@ -1776,9 +1783,10 @@
   // Ignore virtual methods on the iterator.
 }
 
-static void LinkCode(const Handle<mirror::ArtMethod>& method, const OatFile::OatClass* oat_class,
-                     const DexFile& dex_file, uint32_t dex_method_index, uint32_t method_index)
-    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+void ClassLinker::LinkCode(const Handle<mirror::ArtMethod>& method,
+                           const OatFile::OatClass* oat_class,
+                           const DexFile& dex_file, uint32_t dex_method_index,
+                           uint32_t method_index) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
   // Method shouldn't have already been linked.
   DCHECK(method->GetEntryPointFromQuickCompiledCode() == nullptr);
   DCHECK(method->GetEntryPointFromPortableCompiledCode() == nullptr);
@@ -1809,8 +1817,8 @@
     // For static methods excluding the class initializer, install the trampoline.
     // It will be replaced by the proper entry point by ClassLinker::FixupStaticTrampolines
     // after initializing class (see ClassLinker::InitializeClass method).
-    method->SetEntryPointFromQuickCompiledCode(GetQuickResolutionTrampoline(runtime->GetClassLinker()));
-    method->SetEntryPointFromPortableCompiledCode(GetPortableResolutionTrampoline(runtime->GetClassLinker()));
+    method->SetEntryPointFromQuickCompiledCode(GetQuickResolutionTrampoline());
+    method->SetEntryPointFromPortableCompiledCode(GetPortableResolutionTrampoline());
   } else if (enter_interpreter) {
     if (!method->IsNative()) {
       // Set entry point from compiled code if there's no code or in interpreter only mode.
@@ -1836,8 +1844,7 @@
     if (enter_interpreter) {
       // We have a native method here without code. Then it should have either the GenericJni
       // trampoline as entrypoint (non-static), or the Resolution trampoline (static).
-      DCHECK(method->GetEntryPointFromQuickCompiledCode() ==
-          GetQuickResolutionTrampoline(runtime->GetClassLinker())
+      DCHECK(method->GetEntryPointFromQuickCompiledCode() == GetQuickResolutionTrampoline()
           || method->GetEntryPointFromQuickCompiledCode() == GetQuickGenericJniTrampoline());
     }
   }