diff options
author | 2011-10-14 03:29:56 -0700 | |
---|---|---|
committer | 2011-10-14 21:45:27 -0700 | |
commit | 466bb25416b88fabd5d4387b7c7e5cc1ece78b8c (patch) | |
tree | 8d0952cbd850f1d0ac2e43a8372ce571fb4982d1 /src/object.cc | |
parent | a10cd94bb77ed66fa0a8b66141c4504045c92d30 (diff) |
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
Diffstat (limited to 'src/object.cc')
-rw-r--r-- | src/object.cc | 95 |
1 files changed, 82 insertions, 13 deletions
diff --git a/src/object.cc b/src/object.cc index aeaa19b24d..e8aeecdaff 100644 --- a/src/object.cc +++ b/src/object.cc @@ -201,12 +201,12 @@ void Field::SetChar(Object* object, uint16_t c) const { 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 @@ size_t Method::ReturnSize() const { 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 @@ Method* Class::FindVirtualMethodForInterface(Method* method) { 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 @@ Method* Class::FindInterfaceMethod(const StringPiece& name, 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::FindDirectMethod(const StringPiece& name, } 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<int32_t>; // IntArray 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 @@ std::string String::ToModifiedUtf8() const { 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) { |