Invoke static/direct dispatch change.

There was a subtle race in static/direct dispatch via the code and methods
table. This patch removes the table in preparation of architectures like
x86 which will more aggressively sink loads.

Removes unused fields, code.. Brings back resolved methods table
short-cut and associated fast paths to use this (such as in Proxy). Adds
a resolution method that is used as the trampoline for static and direct
methods.

Add source file and line number to Throwable::Dump.

MethodHelper knowledge of runtime methods.

Change-Id: Ieae1b74c24072e6327a5bb2cad466f04e3c46c4d
diff --git a/src/object.cc b/src/object.cc
index cf15a64..7217549 100644
--- a/src/object.cc
+++ b/src/object.cc
@@ -351,6 +351,16 @@
                  new_dex_cache_strings, false);
 }
 
+ObjectArray<Method>* Method::GetDexCacheResolvedMethods() const {
+  return GetFieldObject<ObjectArray<Method>*>(
+      OFFSET_OF_OBJECT_MEMBER(Method, dex_cache_resolved_methods_), false);
+}
+
+void Method::SetDexCacheResolvedMethods(ObjectArray<Method>* new_dex_cache_methods) {
+  SetFieldObject(OFFSET_OF_OBJECT_MEMBER(Method, dex_cache_resolved_methods_),
+                 new_dex_cache_methods, false);
+}
+
 ObjectArray<Class>* Method::GetDexCacheResolvedTypes() const {
   return GetFieldObject<ObjectArray<Class>*>(
       OFFSET_OF_OBJECT_MEMBER(Method, dex_cache_resolved_types_), false);
@@ -361,18 +371,6 @@
                  new_dex_cache_classes, false);
 }
 
-CodeAndDirectMethods* Method::GetDexCacheCodeAndDirectMethods() const {
-  return GetFieldPtr<CodeAndDirectMethods*>(
-      OFFSET_OF_OBJECT_MEMBER(Method, dex_cache_code_and_direct_methods_),
-      false);
-}
-
-void Method::SetDexCacheCodeAndDirectMethods(CodeAndDirectMethods* new_value) {
-  SetFieldPtr<CodeAndDirectMethods*>(
-      OFFSET_OF_OBJECT_MEMBER(Method, dex_cache_code_and_direct_methods_),
-      new_value, false);
-}
-
 ObjectArray<StaticStorageBase>* Method::GetDexCacheInitializedStaticStorage() const {
   return GetFieldObject<ObjectArray<StaticStorageBase>*>(
       OFFSET_OF_OBJECT_MEMBER(Method, dex_cache_initialized_static_storage_),
@@ -447,7 +445,9 @@
   } else {
     // Method didn't override superclass method so search interfaces
     if (IsProxyMethod()) {
-      result = Runtime::Current()->GetClassLinker()->FindMethodForProxy(GetDeclaringClass(), this);
+      result = GetDexCacheResolvedMethods()->Get(GetDexMethodIndex());
+      CHECK_EQ(result,
+               Runtime::Current()->GetClassLinker()->FindMethodForProxy(GetDeclaringClass(), this));
     } else {
       MethodHelper mh(this);
       MethodHelper interface_mh;
@@ -481,12 +481,17 @@
   }
   size_t mapping_table_length = GetMappingTableLength();
   const void* code_offset;
-  if (Runtime::Current()->IsMethodTracingActive() &&
-      Runtime::Current()->GetTracer()->GetSavedCodeFromMap(this) != NULL) {
-    code_offset = Runtime::Current()->GetTracer()->GetSavedCodeFromMap(this);
+  Runtime* runtime = Runtime::Current();
+  if (runtime->IsMethodTracingActive() &&
+      runtime->GetTracer()->GetSavedCodeFromMap(this) != NULL) {
+    code_offset = runtime->GetTracer()->GetSavedCodeFromMap(this);
   } else {
     code_offset = GetCode();
   }
+  if (code_offset == runtime->GetResolutionStubArray(Runtime::kStaticMethod)->GetData() ||
+      code_offset == runtime->GetResolutionStubArray(Runtime::kInstanceMethod)->GetData()) {
+    code_offset = runtime->GetClassLinker()->GetOatCodeFor(this);
+  }
   uint32_t sought_offset = pc - reinterpret_cast<uintptr_t>(code_offset);
   uint32_t best_offset = 0;
   uint32_t best_dex_offset = 0;
@@ -595,6 +600,7 @@
 
 bool Method::IsRegistered() const {
   void* native_method = GetFieldPtr<void*>(OFFSET_OF_OBJECT_MEMBER(Method, native_method_), false);
+  CHECK(native_method != NULL);
   void* jni_stub = Runtime::Current()->GetJniDlsymLookupStub()->GetData();
   return native_method != jni_stub;
 }
@@ -622,11 +628,10 @@
   }
 }
 
-void Method::UnregisterNative() {
+void Method::UnregisterNative(Thread* self) {
   CHECK(IsNative()) << PrettyMethod(this);
   // restore stub to lookup native pointer via dlsym
-  SetFieldPtr<const void*>(OFFSET_OF_OBJECT_MEMBER(Method, native_method_),
-      Runtime::Current()->GetJniDlsymLookupStub()->GetData(), false);
+  RegisterNative(self, Runtime::Current()->GetJniDlsymLookupStub()->GetData());
 }
 
 void Class::SetStatus(Status new_status) {
@@ -1516,11 +1521,16 @@
     // Decode the internal stack trace into the depth and method trace
     ObjectArray<Object>* method_trace = down_cast<ObjectArray<Object>*>(stack_state);
     int32_t depth = method_trace->GetLength() - 1;
+    IntArray* pc_trace = down_cast<IntArray*>(method_trace->Get(depth));
+    MethodHelper mh;
     for (int32_t i = 0; i < depth; ++i) {
       Method* method = down_cast<Method*>(method_trace->Get(i));
-      result += "  at ";
-      result += PrettyMethod(method, true);
-      result += "\n";
+      mh.ChangeMethod(method);
+      uint32_t native_pc = pc_trace->Get(i);
+      int32_t line_number = mh.GetLineNumFromNativePC(native_pc);
+      const char* source_file = mh.GetDeclaringClassSourceFile();
+      result += StringPrintf("  at %s (%s:%d)\n", PrettyMethod(method, true).c_str(),
+                             source_file, line_number);
     }
   }
   Throwable* cause = GetFieldObject<Throwable*>(OFFSET_OF_OBJECT_MEMBER(Throwable, cause_), false);