diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/class_linker.cc | 19 | ||||
| -rw-r--r-- | src/compiler.cc | 56 | ||||
| -rw-r--r-- | src/dex_verifier.cc | 11 | ||||
| -rw-r--r-- | src/object.cc | 36 | ||||
| -rw-r--r-- | src/object.h | 4 | ||||
| -rw-r--r-- | src/thread.cc | 8 |
6 files changed, 91 insertions, 43 deletions
diff --git a/src/class_linker.cc b/src/class_linker.cc index 1c25f61cc5..fb47c4806b 100644 --- a/src/class_linker.cc +++ b/src/class_linker.cc @@ -39,6 +39,7 @@ void ThrowVirtualMachineError(const char* fmt, ...) __attribute__((__format__ (_ void ThrowVirtualMachineError(const char* fmt, ...) { va_list args; va_start(args, fmt); + UNIMPLEMENTED(FATAL) << "VirtualMachineError is abstract, throw something else"; Thread::Current()->ThrowNewExceptionV("Ljava/lang/VirtualMachineError;", fmt, args); va_end(args); } @@ -1649,8 +1650,10 @@ bool ClassLinker::LoadSuperAndInterfaces(Class* klass, const DexFile& dex_file) if (klass->GetSuperClassTypeIdx() != DexFile::kDexNoIndex) { Class* super_class = ResolveType(dex_file, klass->GetSuperClassTypeIdx(), klass); if (super_class == NULL) { - ThrowVirtualMachineError("Failed to resolve superclass with type index %d for class %s", - klass->GetSuperClassTypeIdx(), PrettyDescriptor(klass->GetDescriptor()).c_str()); + DCHECK(Thread::Current()->IsExceptionPending()); + // TODO: can't ThrowVirtualMachineError, its abstract + // ThrowVirtualMachineError("Failed to resolve superclass with type index %d for class %s", + // klass->GetSuperClassTypeIdx(), PrettyDescriptor(klass->GetDescriptor()).c_str()); return false; } klass->SetSuperClass(super_class); @@ -2062,8 +2065,8 @@ bool ClassLinker::LinkFields(Class* klass, bool instance) { Field* field = fields->Get(i); if (false) { // enable to debug field layout LOG(INFO) << "LinkFields: " << (instance ? "instance" : "static") - << " class=" << klass->GetDescriptor()->ToModifiedUtf8() - << " field=" << field->GetName()->ToModifiedUtf8() + << " class=" << PrettyClass(klass) + << " field=" << PrettyField(field) << " offset=" << field->GetField32(MemberOffset(Field::OffsetOffset()), false); } const Class* type = field->GetTypeDuringLinking(); @@ -2242,8 +2245,12 @@ Field* ClassLinker::ResolveField(const DexFile& dex_file, const char* name = dex_file.dexStringById(field_id.name_idx_); Class* field_type = ResolveType(dex_file, field_id.type_idx_, dex_cache, class_loader); - // TODO: LinkageError? - CHECK(field_type != NULL); + if (field_type == NULL) { + // TODO: LinkageError? + UNIMPLEMENTED(WARNING) << "Failed to resolve type of field " << name + << " in " << PrettyClass(klass); + return NULL; +} if (is_static) { resolved = klass->FindStaticField(name, field_type); } else { diff --git a/src/compiler.cc b/src/compiler.cc index 54793bad65..d29e8cab06 100644 --- a/src/compiler.cc +++ b/src/compiler.cc @@ -105,7 +105,13 @@ void Compiler::ResolveDexFile(const ClassLoader* class_loader, const DexFile& de for (size_t i = 0; i < num_static_fields; ++i) { DexFile::Field dex_field; dex_file.dexReadClassDataField(&class_data, &dex_field, &last_idx); - class_linker->ResolveField(dex_file, dex_field.field_idx_, dex_cache, class_loader, true); + Field* field = class_linker->ResolveField(dex_file, dex_field.field_idx_, dex_cache, + class_loader, true); + if (field == NULL) { + Thread* self = Thread::Current(); + CHECK(self->IsExceptionPending()); + self->ClearException(); + } } } if (num_instance_fields != 0) { @@ -113,7 +119,13 @@ void Compiler::ResolveDexFile(const ClassLoader* class_loader, const DexFile& de for (size_t i = 0; i < num_instance_fields; ++i) { DexFile::Field dex_field; dex_file.dexReadClassDataField(&class_data, &dex_field, &last_idx); - class_linker->ResolveField(dex_file, dex_field.field_idx_, dex_cache, class_loader, false); + Field* field = class_linker->ResolveField(dex_file, dex_field.field_idx_, dex_cache, + class_loader, false); + if (field == NULL) { + Thread* self = Thread::Current(); + CHECK(self->IsExceptionPending()); + self->ClearException(); + } } } if (num_direct_methods != 0) { @@ -121,8 +133,13 @@ void Compiler::ResolveDexFile(const ClassLoader* class_loader, const DexFile& de for (size_t i = 0; i < num_direct_methods; ++i) { DexFile::Method dex_method; dex_file.dexReadClassDataMethod(&class_data, &dex_method, &last_idx); - class_linker->ResolveMethod(dex_file, dex_method.method_idx_, dex_cache, class_loader, - true); + Method* method = class_linker->ResolveMethod(dex_file, dex_method.method_idx_, dex_cache, + class_loader, true); + if (method == NULL) { + Thread* self = Thread::Current(); + CHECK(self->IsExceptionPending()); + self->ClearException(); + } } } if (num_virtual_methods != 0) { @@ -130,8 +147,13 @@ void Compiler::ResolveDexFile(const ClassLoader* class_loader, const DexFile& de for (size_t i = 0; i < num_virtual_methods; ++i) { DexFile::Method dex_method; dex_file.dexReadClassDataMethod(&class_data, &dex_method, &last_idx); - class_linker->ResolveMethod(dex_file, dex_method.method_idx_, dex_cache, class_loader, - false); + Method* method = class_linker->ResolveMethod(dex_file, dex_method.method_idx_, dex_cache, + class_loader, false); + if (method == NULL) { + Thread* self = Thread::Current(); + CHECK(self->IsExceptionPending()); + self->ClearException(); + } } } } @@ -153,10 +175,23 @@ void Compiler::VerifyDexFile(const ClassLoader* class_loader, const DexFile& dex const DexFile::ClassDef& class_def = dex_file.GetClassDef(class_def_index); const char* descriptor = dex_file.GetClassDescriptor(class_def); Class* klass = class_linker->FindClass(descriptor, class_loader); - CHECK(klass->IsResolved()); - CHECK(klass != NULL); + if (klass == NULL) { + Thread* self = Thread::Current(); + CHECK(self->IsExceptionPending()); + self->ClearException(); + continue; + } + CHECK(klass->IsResolved()) << PrettyClass(klass); class_linker->VerifyClass(klass); - CHECK(klass->IsVerified() || klass->IsErroneous()); + CHECK(klass->IsVerified() || klass->IsErroneous()) << PrettyClass(klass); + //CHECK(!Thread::Current()->IsExceptionPending()); + if (klass->IsErroneous()) { + Thread* self = Thread::Current(); + if (self->IsExceptionPending()) { + UNIMPLEMENTED(WARNING) << "Verifier failed to cleanup exceptions internally"; + self->ClearException(); + } + } } dex_file.ChangePermissions(PROT_READ); } @@ -212,8 +247,7 @@ void Compiler::CompileDexFile(const ClassLoader* class_loader, const DexFile& de if (klass == NULL) { // previous verification error will cause FindClass to throw Thread* self = Thread::Current(); - // CHECK(self->IsExceptionPending()); - UNIMPLEMENTED(WARNING) << "CHECK for verification error after FindClass " << descriptor; + CHECK(self->IsExceptionPending()); self->ClearException(); } else { CompileClass(klass); diff --git a/src/dex_verifier.cc b/src/dex_verifier.cc index 6ea276f4e6..ee815434f4 100644 --- a/src/dex_verifier.cc +++ b/src/dex_verifier.cc @@ -2548,6 +2548,7 @@ iput_1nr_common: inst_field = GetInstField(vdata, obj_type, dec_insn.vC_, &failure); if (failure != VERIFY_ERROR_NONE) break; + DCHECK(inst_field != NULL); CheckFinalFieldAccess(method, inst_field, &failure); if (failure != VERIFY_ERROR_NONE) break; @@ -3802,6 +3803,7 @@ Field* DexVerifier::GetInstField(VerifierData* vdata, RegType obj_type, method->GetDeclaringClass(), failure, false); if (field == NULL) { LOG(ERROR) << "VFY: unable to resolve instance field " << field_idx; + *failure = VERIFY_ERROR_GENERIC; return field; } @@ -4436,13 +4438,14 @@ Field* DexVerifier::ResolveFieldAndCheckAccess(const DexFile* dex_file, const DexFile::FieldId& field_id = dex_file->GetFieldId(field_idx); Class* klass = ResolveClassAndCheckAccess(dex_file, field_id.class_idx_, referrer, failure); if (klass == NULL) { - DCHECK(*failure != VERIFY_ERROR_NONE); + DCHECK(*failure != VERIFY_ERROR_NONE) << PrettyClass(referrer); return NULL; } Class* field_type = ResolveClassAndCheckAccess(dex_file, field_id.type_idx_, referrer, failure); if (field_type == NULL) { - DCHECK(*failure != VERIFY_ERROR_NONE); + // TODO: restore this assert? + // DCHECK(*failure != VERIFY_ERROR_NONE) << PrettyClass(referrer) << " " << PrettyClass(klass); return NULL; } @@ -4692,8 +4695,10 @@ char DexVerifier::DetermineCat1Const(int32_t value) { void DexVerifier::CheckFinalFieldAccess(const Method* method, const Field* field, VerifyError* failure) { - if (!field->IsFinal()) + DCHECK(field != NULL); + if (!field->IsFinal()) { return; + } /* make sure we're in the same class */ if (method->GetDeclaringClass() != field->GetDeclaringClass()) { diff --git a/src/object.cc b/src/object.cc index f47f16edfc..ff49ad3ac6 100644 --- a/src/object.cc +++ b/src/object.cc @@ -751,7 +751,9 @@ void Method::Invoke(Thread* self, Object* receiver, byte* args, JValue* result) (*stub)(this, receiver, self, args, result); LOG(INFO) << "returned " << PrettyMethod(this) << " code=" << (void*) GetCode() << " stub=" << (void*) stub; } else { - LOG(WARNING) << "Not invoking method with no associated code: " << PrettyMethod(this); + if (Runtime::Current()->IsStarted()) { + LOG(WARNING) << "Not invoking method with no associated code: " << PrettyMethod(this); + } if (result != NULL) { result->j = 0; } @@ -782,8 +784,8 @@ void Method::UnregisterNative() { void Class::SetStatus(Status new_status) { CHECK(new_status > GetStatus() || new_status == kStatusError || - !Runtime::Current()->IsStarted()) << GetDescriptor()->ToModifiedUtf8(); - CHECK(sizeof(Status) == sizeof(uint32_t)); + !Runtime::Current()->IsStarted()) << PrettyClass(this); + CHECK(sizeof(Status) == sizeof(uint32_t)) << PrettyClass(this); return SetField32(OFFSET_OF_OBJECT_MEMBER(Class, status_), new_status, false); } @@ -799,9 +801,9 @@ void Class::SetDexCache(DexCache* new_dex_cache) { } Object* Class::AllocObject() { - DCHECK(!IsAbstract()); - DCHECK(!IsInterface()); - DCHECK(!IsPrimitive()); + DCHECK(!IsAbstract()) << PrettyClass(this); + DCHECK(!IsInterface()) << PrettyClass(this); + DCHECK(!IsPrimitive()) << PrettyClass(this); return Heap::AllocObject(this, this->object_size_); } @@ -927,7 +929,7 @@ size_t Class::GetTypeSize(const String* descriptor) { bool Class::Implements(const Class* klass) const { DCHECK(klass != NULL); - DCHECK(klass->IsInterface()); + DCHECK(klass->IsInterface()) << PrettyClass(this); // All interfaces implemented directly and by our superclass, and // recursively all super-interfaces of those interfaces, are listed // in iftable_, so we can just do a linear scan through that. @@ -961,28 +963,28 @@ bool Class::Implements(const Class* klass) const { // Object[] = int[] --> false // bool Class::IsArrayAssignableFromArray(const Class* src) const { - DCHECK(IsArrayClass()); - DCHECK(src->IsArrayClass()); + DCHECK(IsArrayClass()) << PrettyClass(this); + DCHECK(src->IsArrayClass()) << PrettyClass(src); return GetComponentType()->IsAssignableFrom(src->GetComponentType()); } bool Class::IsAssignableFromArray(const Class* src) const { - DCHECK(!IsInterface()); // handled first in IsAssignableFrom - DCHECK(src->IsArrayClass()); + DCHECK(!IsInterface()) << PrettyClass(this); // handled first in IsAssignableFrom + DCHECK(src->IsArrayClass()) << PrettyClass(src); if (!IsArrayClass()) { // If "this" is not also an array, it must be Object. // src's super should be java_lang_Object, since it is an array. Class* java_lang_Object = src->GetSuperClass(); - DCHECK(java_lang_Object != NULL); - DCHECK(java_lang_Object->GetSuperClass() == NULL); + DCHECK(java_lang_Object != NULL) << PrettyClass(src); + DCHECK(java_lang_Object->GetSuperClass() == NULL) << PrettyClass(src); return this == java_lang_Object; } return IsArrayAssignableFromArray(src); } bool Class::IsSubClass(const Class* klass) const { - DCHECK(!IsInterface()); - DCHECK(!IsArrayClass()); + DCHECK(!IsInterface()) << PrettyClass(this); + DCHECK(!IsArrayClass()) << PrettyClass(this); const Class* current = this; do { if (current == klass) { @@ -1055,8 +1057,8 @@ void Class::SetClassLoader(const ClassLoader* new_cl) { Method* Class::FindVirtualMethodForInterface(Method* method) { Class* declaring_class = method->GetDeclaringClass(); - DCHECK(declaring_class != NULL); - DCHECK(declaring_class->IsInterface()); + DCHECK(declaring_class != NULL) << PrettyClass(this); + DCHECK(declaring_class->IsInterface()) << PrettyMethod(method); // TODO cache to improve lookup speed int32_t iftable_count = GetIfTableCount(); ObjectArray<InterfaceEntry>* iftable = GetIfTable(); diff --git a/src/object.h b/src/object.h index ba8aaa93c4..e94671ba1e 100644 --- a/src/object.h +++ b/src/object.h @@ -2177,7 +2177,7 @@ inline Class* Method::GetDeclaringClass() const { GetFieldObject<Class*>( OFFSET_OF_OBJECT_MEMBER(Method, declaring_class_), false); DCHECK(result != NULL); - DCHECK(result->IsLoaded() || result->IsErroneous()); + DCHECK(result->IsIdxLoaded() || result->IsErroneous()); return result; } @@ -2607,7 +2607,7 @@ inline void Class::SetSourceFile(String* new_source_file) { } inline uint32_t Method::GetAccessFlags() const { - DCHECK(GetDeclaringClass()->IsLoaded() || GetDeclaringClass()->IsErroneous()); + DCHECK(GetDeclaringClass()->IsIdxLoaded() || GetDeclaringClass()->IsErroneous()); return GetField32(OFFSET_OF_OBJECT_MEMBER(Method, access_flags_), false); } diff --git a/src/thread.cc b/src/thread.cc index 71b90909c8..004eaae3db 100644 --- a/src/thread.cc +++ b/src/thread.cc @@ -233,7 +233,7 @@ extern "C" Array* artCheckAndArrayAllocFromCode(uint32_t type_idx, Method* metho } return NULL; // Failure } else { - CHECK(klass->IsArrayClass()); + CHECK(klass->IsArrayClass()) << PrettyClass(klass); return Array::Alloc(klass, component_count); } } @@ -253,15 +253,15 @@ extern "C" Array* artArrayAllocFromCode(uint32_t type_idx, Method* method, int32 DCHECK(Thread::Current()->IsExceptionPending()); return NULL; // Failure } - CHECK(klass->IsArrayClass()); + CHECK(klass->IsArrayClass()) << PrettyClass(klass); } return Array::Alloc(klass, component_count); } // Check whether it is safe to cast one class to the other, throw exception and return -1 on failure extern "C" int artCheckCastFromCode(const Class* a, const Class* b) { - DCHECK(a->IsClass()); - DCHECK(b->IsClass()); + DCHECK(a->IsClass()) << PrettyClass(a); + DCHECK(b->IsClass()) << PrettyClass(b); if (b->IsAssignableFrom(a)) { return 0; // Success } else { |