Implement Interface Method Tables (IMT).

Change-Id: Idf7fe85e1293453a8ad862ff2380dcd5db4e3a39
diff --git a/compiler/driver/compiler_driver.cc b/compiler/driver/compiler_driver.cc
index 91b0188..053ea16 100644
--- a/compiler/driver/compiler_driver.cc
+++ b/compiler/driver/compiler_driver.cc
@@ -469,6 +469,11 @@
   return CreateTrampoline(instruction_set_, kJniAbi, JNI_ENTRYPOINT_OFFSET(pDlsymLookup));
 }
 
+const std::vector<uint8_t>* CompilerDriver::CreatePortableImtConflictTrampoline() const {
+  return CreateTrampoline(instruction_set_, kPortableAbi,
+                          PORTABLE_ENTRYPOINT_OFFSET(pPortableImtConflictTrampoline));
+}
+
 const std::vector<uint8_t>* CompilerDriver::CreatePortableResolutionTrampoline() const {
   return CreateTrampoline(instruction_set_, kPortableAbi,
                           PORTABLE_ENTRYPOINT_OFFSET(pPortableResolutionTrampoline));
@@ -479,6 +484,11 @@
                           PORTABLE_ENTRYPOINT_OFFSET(pPortableToInterpreterBridge));
 }
 
+const std::vector<uint8_t>* CompilerDriver::CreateQuickImtConflictTrampoline() const {
+  return CreateTrampoline(instruction_set_, kQuickAbi,
+                          QUICK_ENTRYPOINT_OFFSET(pQuickImtConflictTrampoline));
+}
+
 const std::vector<uint8_t>* CompilerDriver::CreateQuickResolutionTrampoline() const {
   return CreateTrampoline(instruction_set_, kQuickAbi,
                           QUICK_ENTRYPOINT_OFFSET(pQuickResolutionTrampoline));
@@ -1080,7 +1090,7 @@
     }
     use_dex_cache = true;
   } else {
-    if (sharp_type != kStatic && sharp_type != kDirect && sharp_type != kInterface) {
+    if (sharp_type != kStatic && sharp_type != kDirect) {
       return;
     }
     // TODO: support patching on all architectures.
@@ -1101,9 +1111,7 @@
     }
   }
   if (update_stats && method_code_in_boot) {
-    if (sharp_type != kInterface) {  // Interfaces always go via a trampoline until we get IMTs.
-      stats_->DirectCallsToBoot(*type);
-    }
+    stats_->DirectCallsToBoot(*type);
     stats_->DirectMethodsToBoot(*type);
   }
   if (!use_dex_cache && compiling_boot) {
@@ -1145,19 +1153,15 @@
     if (compiling_boot) {
       *type = sharp_type;
       *direct_method = -1;
-      if (sharp_type != kInterface) {
-        *direct_code = -1;
-      }
+      *direct_code = -1;
     } else {
       bool method_in_image =
           Runtime::Current()->GetHeap()->FindSpaceFromObject(method, false)->IsImageSpace();
       if (method_in_image) {
-        CHECK_EQ(method->IsAbstract(), sharp_type == kInterface);
+        CHECK(!method->IsAbstract());
         *type = sharp_type;
         *direct_method = reinterpret_cast<uintptr_t>(method);
-        if (*type != kInterface) {
-          *direct_code = reinterpret_cast<uintptr_t>(method->GetEntryPointFromCompiledCode());
-        }
+        *direct_code = reinterpret_cast<uintptr_t>(method->GetEntryPointFromCompiledCode());
         target_method->dex_file = method->GetDeclaringClass()->GetDexCache()->GetDexFile();
         target_method->dex_method_index = method->GetDexMethodIndex();
       } else if (!must_use_direct_pointers) {
@@ -1187,6 +1191,8 @@
   if (resolved_method != NULL) {
     if (*invoke_type == kVirtual || *invoke_type == kSuper) {
       *vtable_idx = resolved_method->GetMethodIndex();
+    } else if (*invoke_type == kInterface) {
+      *vtable_idx = resolved_method->GetDexMethodIndex();
     }
     // Don't try to fast-path if we don't understand the caller's class or this appears to be an
     // Incompatible Class Change Error.