Proxy implementation

This rounds out the proxy implementation by adding missing pieces to the
class linker, extending tests and fixing issues in the runtime support.
There are also some tweaks for performance and to clean up Method/Object
a little.
A unit test of the functionality is "art/test/run-test 044"

Change-Id: Id94102d10b81cd9b12b95ba8618f6187490204c4
diff --git a/src/object.cc b/src/object.cc
index aeaa19b..e8aeecd 100644
--- a/src/object.cc
+++ b/src/object.cc
@@ -201,12 +201,12 @@
   Set32(object, c);
 }
 
-uint16_t Field::GetShort(const Object* object) const {
+int16_t Field::GetShort(const Object* object) const {
   DCHECK(GetType()->IsPrimitiveShort());
   return Get32(object);
 }
 
-void Field::SetShort(Object* object, uint16_t s) const {
+void Field::SetShort(Object* object, int16_t s) const {
   DCHECK(GetType()->IsPrimitiveShort());
   Set32(object, s);
 }
@@ -560,9 +560,28 @@
   return ShortyCharToSize(GetShorty()->CharAt(0));
 }
 
-bool Method::HasSameNameAndDescriptor(const Method* that) const {
-  return (this->GetName()->Equals(that->GetName()) &&
-          this->GetSignature()->Equals(that->GetSignature()));
+Method* Method::FindOverriddenMethod() const {
+  if (IsStatic()) {
+    return NULL;
+  }
+  Class* declaring_class = GetDeclaringClass();
+  Class* super_class = declaring_class->GetSuperClass();
+  uint16_t method_index = GetMethodIndex();
+  ObjectArray<Method>* super_class_vtable = super_class->GetVTable();
+  Method* result = NULL;
+  if (super_class_vtable != NULL && method_index < super_class_vtable->GetLength()) {
+    result = super_class_vtable->Get(method_index);
+  } else {
+    ObjectArray<Class>* interfaces = declaring_class->GetInterfaces();
+    String* name = GetName();
+    String* signature = GetSignature();
+    for (int32_t i = 0; i < interfaces->GetLength() && result == NULL; i++) {
+      Class* interface = interfaces->Get(i);
+      result = interface->FindInterfaceMethod(name, signature);
+    }
+  }
+  DCHECK (result == NULL || HasSameNameAndSignature(result));
+  return result;
 }
 
 uint32_t Method::ToDexPC(const uintptr_t pc) const {
@@ -990,8 +1009,7 @@
   return NULL;
 }
 
-Method* Class::FindInterfaceMethod(const StringPiece& name,
-                                   const StringPiece& signature) {
+Method* Class::FindInterfaceMethod(const StringPiece& name,  const StringPiece& signature) const {
   // Check the current class before checking the interfaces.
   Method* method = FindVirtualMethod(name, signature);
   if (method != NULL) {
@@ -1009,6 +1027,24 @@
   return NULL;
 }
 
+Method* Class::FindInterfaceMethod(String* name,  String* signature) const {
+  // Check the current class before checking the interfaces.
+  Method* method = FindVirtualMethod(name, signature);
+  if (method != NULL) {
+    return method;
+  }
+  int32_t iftable_count = GetIfTableCount();
+  ObjectArray<InterfaceEntry>* iftable = GetIfTable();
+  for (int32_t i = 0; i < iftable_count; i++) {
+    Class* interface = iftable->Get(i)->GetInterface();
+    method = interface->FindVirtualMethod(name, signature);
+    if (method != NULL) {
+      return method;
+    }
+  }
+  return NULL;
+}
+
 Method* Class::FindDeclaredDirectMethod(const StringPiece& name,
                                         const StringPiece& signature) {
   for (size_t i = 0; i < NumDirectMethods(); ++i) {
@@ -1033,20 +1069,41 @@
 }
 
 Method* Class::FindDeclaredVirtualMethod(const StringPiece& name,
-                                         const StringPiece& signature) {
+                                         const StringPiece& signature) const {
   for (size_t i = 0; i < NumVirtualMethods(); ++i) {
     Method* method = GetVirtualMethod(i);
-    if (method->GetName()->Equals(name) &&
-        method->GetSignature()->Equals(signature)) {
+    if (method->GetName()->Equals(name) && method->GetSignature()->Equals(signature)) {
       return method;
     }
   }
   return NULL;
 }
 
-Method* Class::FindVirtualMethod(const StringPiece& name,
-                                 const StringPiece& signature) {
-  for (Class* klass = this; klass != NULL; klass = klass->GetSuperClass()) {
+Method* Class::FindDeclaredVirtualMethod(String* name, String* signature) const {
+  for (size_t i = 0; i < NumVirtualMethods(); ++i) {
+    Method* method = GetVirtualMethod(i);
+    if (method->GetName() == name && method->GetSignature() == signature) {
+      return method;
+    } else {
+      LOG(INFO) << "Find (" << name->ToModifiedUtf8() << ", " << signature->ToModifiedUtf8()
+          << ") != " << PrettyMethod(method);
+    }
+  }
+  return NULL;
+}
+
+Method* Class::FindVirtualMethod(const StringPiece& name, const StringPiece& signature) const {
+  for (const Class* klass = this; klass != NULL; klass = klass->GetSuperClass()) {
+    Method* method = klass->FindDeclaredVirtualMethod(name, signature);
+    if (method != NULL) {
+      return method;
+    }
+  }
+  return NULL;
+}
+
+Method* Class::FindVirtualMethod(String* name, String* signature) const {
+  for (const Class* klass = this; klass != NULL; klass = klass->GetSuperClass()) {
     Method* method = klass->FindDeclaredVirtualMethod(name, signature);
     if (method != NULL) {
       return method;
@@ -1175,6 +1232,9 @@
 template class PrimitiveArray<int64_t>;   // LongArray
 template class PrimitiveArray<int16_t>;   // ShortArray
 
+// Explicitly instantiate Class[][]
+template class ObjectArray<ObjectArray<Class> >;
+
 // TODO: get global references for these
 Class* String::java_lang_String_ = NULL;
 
@@ -1350,6 +1410,15 @@
   return result;
 }
 
+bool Throwable::IsCheckedException() const {
+  Class* error = Runtime::Current()->GetClassLinker()->FindSystemClass("Ljava/lang/Error;");
+  if (InstanceOf(error)) {
+    return false;
+  }
+  Class* jlre = Runtime::Current()->GetClassLinker()->FindSystemClass("Ljava/lang/RuntimeException;");
+  return !InstanceOf(jlre);
+}
+
 Class* StackTraceElement::java_lang_StackTraceElement_ = NULL;
 
 void StackTraceElement::SetClass(Class* java_lang_StackTraceElement) {