Static and direct resolution stub.

Ensure that invoke static and direct go through a stub that causes
resolution and initialization.

Change-Id: I872900560322817d8f4378b04ac410d9ea0b3b17
diff --git a/src/compiler.cc b/src/compiler.cc
index af5cdd6..c6705a6 100644
--- a/src/compiler.cc
+++ b/src/compiler.cc
@@ -18,23 +18,13 @@
 
 namespace arm {
   ByteArray* CreateAbstractMethodErrorStub();
+  void ArmCreateInvokeStub(Method* method);
+  ByteArray* ArmCreateResolutionTrampoline(bool is_static);
 }
-
 namespace x86 {
   ByteArray* CreateAbstractMethodErrorStub();
-}
-
-ByteArray* Compiler::CreateAbstractMethodErrorStub(InstructionSet instruction_set) {
-  switch (instruction_set) {
-    case kArm:
-    case kThumb2:
-      return arm::CreateAbstractMethodErrorStub();
-    case kX86:
-      return x86::CreateAbstractMethodErrorStub();
-    default:
-      LOG(FATAL) << "Unknown InstructionSet " << (int) instruction_set;
-      return NULL;
-  }
+  void X86CreateInvokeStub(Method* method);
+  ByteArray* X86CreateResolutionTrampoline(bool is_static);
 }
 
 Compiler::Compiler(InstructionSet insns) : instruction_set_(insns), jni_compiler_(insns),
@@ -42,6 +32,26 @@
   CHECK(!Runtime::Current()->IsStarted());
 }
 
+ByteArray* Compiler::CreateResolutionStub(InstructionSet instruction_set, bool is_static) {
+  if (instruction_set == kX86) {
+    return x86::X86CreateResolutionTrampoline(is_static);
+  } else {
+    CHECK(instruction_set == kArm || instruction_set == kThumb2);
+    // Generates resolution stub using ARM instruction set
+    return arm::ArmCreateResolutionTrampoline(is_static);
+  }
+}
+
+ByteArray* Compiler::CreateAbstractMethodErrorStub(InstructionSet instruction_set) {
+  if (instruction_set == kX86) {
+    return x86::CreateAbstractMethodErrorStub();
+  } else {
+    CHECK(instruction_set == kArm || instruction_set == kThumb2);
+    // Generates resolution stub using ARM instruction set
+    return arm::CreateAbstractMethodErrorStub();
+  }
+}
+
 void Compiler::CompileAll(const ClassLoader* class_loader) {
   DCHECK(!Runtime::Current()->IsStarted());
   Resolve(class_loader);
@@ -265,13 +275,6 @@
   }
 }
 
-namespace arm {
-  void ArmCreateInvokeStub(Method* method);
-}
-namespace x86 {
-  void X86CreateInvokeStub(Method* method);
-}
-
 void Compiler::CompileMethod(Method* method) {
   if (method->IsNative()) {
     jni_compiler_.Compile(method);
@@ -313,13 +316,20 @@
 }
 
 void Compiler::SetCodeAndDirectMethodsDexFile(const DexFile& dex_file) {
-  ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
+  Runtime* runtime = Runtime::Current();
+  ClassLinker* class_linker = runtime->GetClassLinker();
   DexCache* dex_cache = class_linker->FindDexCache(dex_file);
   CodeAndDirectMethods* code_and_direct_methods = dex_cache->GetCodeAndDirectMethods();
   for (size_t i = 0; i < dex_cache->NumResolvedMethods(); i++) {
     Method* method = dex_cache->GetResolvedMethod(i);
-    if (method == NULL) {
-      code_and_direct_methods->SetResolvedDirectMethodTrampoline(i);
+    if ((method == NULL) || (method->IsStatic() && !method->GetDeclaringClass()->IsInitialized())) {
+      ByteArray* res_trampoline = runtime->GetResolutionStubArray(method->IsStatic());
+      if (instruction_set_ == kX86) {
+        code_and_direct_methods->SetResolvedDirectMethodTrampoline(i, res_trampoline, kX86);
+      } else {
+        CHECK(instruction_set_ == kArm || instruction_set_ == kThumb2);
+        code_and_direct_methods->SetResolvedDirectMethodTrampoline(i, res_trampoline, kArm);
+      }
     } else if (method->IsDirect()) {
       code_and_direct_methods->SetResolvedDirectMethod(i, method);
     } else {