diff options
author | 2012-10-05 17:19:13 -0700 | |
---|---|---|
committer | 2012-10-06 09:48:02 -0700 | |
commit | 4445a7e3398a6143939168097a3aa275b734504d (patch) | |
tree | 9eda34219b4a840125694a86ddba49077e15b944 | |
parent | 50b35e2fd1a68cd1240e4a9d9f363e11764957d1 (diff) |
Class clean-up.
Move Class code out of native and into Java.
Remove ClassLinker::FindDexFile.
Change-Id: Idd9c4563d2c32e76690675242ff491276ace9848
-rw-r--r-- | src/class_linker.cc | 98 | ||||
-rw-r--r-- | src/class_linker.h | 24 | ||||
-rw-r--r-- | src/common_test.h | 2 | ||||
-rw-r--r-- | src/common_throws.cc | 7 | ||||
-rw-r--r-- | src/compiler.cc | 8 | ||||
-rw-r--r-- | src/debugger.cc | 2 | ||||
-rw-r--r-- | src/exception_test.cc | 2 | ||||
-rw-r--r-- | src/image_writer.cc | 3 | ||||
-rw-r--r-- | src/native/java_lang_Class.cc | 324 | ||||
-rw-r--r-- | src/object.h | 4 | ||||
-rw-r--r-- | src/object_utils.h | 3 | ||||
-rw-r--r-- | src/runtime_support.cc | 4 | ||||
-rw-r--r-- | src/thread.cc | 7 |
13 files changed, 86 insertions, 402 deletions
diff --git a/src/class_linker.cc b/src/class_linker.cc index 9ce641febf..8a655bde1c 100644 --- a/src/class_linker.cc +++ b/src/class_linker.cc @@ -176,8 +176,9 @@ const char* ClassLinker::class_roots_descriptors_[] = { "Ljava/lang/reflect/Method;", "Ljava/lang/reflect/Proxy;", "[Ljava/lang/String;", - "[Ljava/lang/reflect/Field;", "[Ljava/lang/reflect/AbstractMethod;", + "[Ljava/lang/reflect/Field;", + "[Ljava/lang/reflect/Method;", "Ljava/lang/ClassLoader;", "Ljava/lang/Throwable;", "Ljava/lang/ClassNotFoundException;", @@ -315,13 +316,6 @@ void ClassLinker::InitFromCompiler(const std::vector<const DexFile*>& boot_class java_lang_DexCache->SetStatus(Class::kStatusResolved); // Constructor, Field, Method, and AbstractMethod are necessary so that FindClass can link members. - SirtRef<Class> java_lang_reflect_Constructor(self, AllocClass(self, java_lang_Class.get(), - sizeof(MethodClass))); - CHECK(java_lang_reflect_Constructor.get() != NULL); - java_lang_reflect_Constructor->SetObjectSize(sizeof(Constructor)); - SetClassRoot(kJavaLangReflectConstructor, java_lang_reflect_Constructor.get()); - java_lang_reflect_Constructor->SetStatus(Class::kStatusResolved); - SirtRef<Class> java_lang_reflect_Field(self, AllocClass(self, java_lang_Class.get(), sizeof(FieldClass))); CHECK(java_lang_reflect_Field.get() != NULL); @@ -330,19 +324,29 @@ void ClassLinker::InitFromCompiler(const std::vector<const DexFile*>& boot_class java_lang_reflect_Field->SetStatus(Class::kStatusResolved); Field::SetClass(java_lang_reflect_Field.get()); + SirtRef<Class> java_lang_reflect_AbstractMethod(self, AllocClass(self, java_lang_Class.get(), + sizeof(MethodClass))); + CHECK(java_lang_reflect_AbstractMethod.get() != NULL); + java_lang_reflect_AbstractMethod->SetObjectSize(sizeof(AbstractMethod)); + SetClassRoot(kJavaLangReflectAbstractMethod, java_lang_reflect_AbstractMethod.get()); + java_lang_reflect_AbstractMethod->SetStatus(Class::kStatusResolved); + + SirtRef<Class> java_lang_reflect_Constructor(self, AllocClass(self, java_lang_Class.get(), + sizeof(MethodClass))); + CHECK(java_lang_reflect_Constructor.get() != NULL); + java_lang_reflect_Constructor->SetObjectSize(sizeof(Constructor)); + java_lang_reflect_Constructor->SetSuperClass(java_lang_reflect_AbstractMethod.get()); + SetClassRoot(kJavaLangReflectConstructor, java_lang_reflect_Constructor.get()); + java_lang_reflect_Constructor->SetStatus(Class::kStatusResolved); + SirtRef<Class> java_lang_reflect_Method(self, AllocClass(self, java_lang_Class.get(), sizeof(MethodClass))); CHECK(java_lang_reflect_Method.get() != NULL); java_lang_reflect_Method->SetObjectSize(sizeof(Method)); + java_lang_reflect_Method->SetSuperClass(java_lang_reflect_AbstractMethod.get()); SetClassRoot(kJavaLangReflectMethod, java_lang_reflect_Method.get()); java_lang_reflect_Method->SetStatus(Class::kStatusResolved); - SirtRef<Class> java_lang_reflect_AbstractMethod(self, AllocClass(self, java_lang_Class.get(), - sizeof(MethodClass))); - CHECK(java_lang_reflect_AbstractMethod.get() != NULL); - java_lang_reflect_AbstractMethod->SetObjectSize(sizeof(AbstractMethod)); - SetClassRoot(kJavaLangReflectAbstractMethod, java_lang_reflect_AbstractMethod.get()); - java_lang_reflect_AbstractMethod->SetStatus(Class::kStatusResolved); AbstractMethod::SetClasses(java_lang_reflect_Constructor.get(), java_lang_reflect_Method.get()); // Set up array classes for string, field, method @@ -350,13 +354,17 @@ void ClassLinker::InitFromCompiler(const std::vector<const DexFile*>& boot_class object_array_string->SetComponentType(java_lang_String.get()); SetClassRoot(kJavaLangStringArrayClass, object_array_string.get()); + SirtRef<Class> object_array_abstract_method(self, AllocClass(self, java_lang_Class.get(), sizeof(Class))); + object_array_abstract_method->SetComponentType(java_lang_reflect_AbstractMethod.get()); + SetClassRoot(kJavaLangReflectAbstractMethodArrayClass, object_array_abstract_method.get()); + SirtRef<Class> object_array_field(self, AllocClass(self, java_lang_Class.get(), sizeof(Class))); object_array_field->SetComponentType(java_lang_reflect_Field.get()); SetClassRoot(kJavaLangReflectFieldArrayClass, object_array_field.get()); - SirtRef<Class> object_array_abstract_method(self, AllocClass(self, java_lang_Class.get(), sizeof(Class))); - object_array_abstract_method->SetComponentType(java_lang_reflect_AbstractMethod.get()); - SetClassRoot(kJavaLangReflectAbstractMethodArrayClass, object_array_abstract_method.get()); + SirtRef<Class> object_array_method(self, AllocClass(self, java_lang_Class.get(), sizeof(Class))); + object_array_method->SetComponentType(java_lang_reflect_Method.get()); + SetClassRoot(kJavaLangReflectMethodArrayClass, object_array_method.get()); // Setup boot_class_path_ and register class_path now that we can use AllocObjectArray to create // DexCache instances. Needs to be after String, Field, Method arrays since AllocDexCache uses @@ -466,13 +474,17 @@ void ClassLinker::InitFromCompiler(const std::vector<const DexFile*>& boot_class Class* String_array_class = FindSystemClass(class_roots_descriptors_[kJavaLangStringArrayClass]); CHECK_EQ(object_array_string.get(), String_array_class); - Class* Field_array_class = FindSystemClass(class_roots_descriptors_[kJavaLangReflectFieldArrayClass]); - CHECK_EQ(object_array_field.get(), Field_array_class); - Class* Abstract_method_array_class = FindSystemClass(class_roots_descriptors_[kJavaLangReflectAbstractMethodArrayClass]); CHECK_EQ(object_array_abstract_method.get(), Abstract_method_array_class); + Class* Field_array_class = FindSystemClass(class_roots_descriptors_[kJavaLangReflectFieldArrayClass]); + CHECK_EQ(object_array_field.get(), Field_array_class); + + Class* Method_array_class = + FindSystemClass(class_roots_descriptors_[kJavaLangReflectMethodArrayClass]); + CHECK_EQ(object_array_method.get(), Method_array_class); + // End of special init trickery, subsequent classes may be loaded via FindSystemClass. // Create java.lang.reflect.Proxy root. @@ -528,7 +540,7 @@ void ClassLinker::FinishInit() { Class* java_lang_ref_ReferenceQueue = FindSystemClass("Ljava/lang/ref/ReferenceQueue;"); Class* java_lang_ref_FinalizerReference = FindSystemClass("Ljava/lang/ref/FinalizerReference;"); - const DexFile& java_lang_dex = FindDexFile(java_lang_ref_Reference->GetDexCache()); + const DexFile& java_lang_dex = *java_lang_ref_Reference->GetDexCache()->GetDexFile(); Field* pendingNext = java_lang_ref_Reference->GetInstanceField(0); FieldHelper fh(pendingNext, this); @@ -1136,7 +1148,7 @@ DexCache* ClassLinker::AllocDexCache(Thread* self, const DexFile& dex_file) { return NULL; } SirtRef<ObjectArray<AbstractMethod> > - methods(self, AllocMethodArray(self, dex_file.NumMethodIds())); + methods(self, AllocAbstractMethodArray(self, dex_file.NumMethodIds())); if (methods.get() == NULL) { return NULL; } @@ -1594,10 +1606,10 @@ void ClassLinker::LoadClass(const DexFile& dex_file, ClassDataItemIterator it(dex_file, class_data); Thread* self = Thread::Current(); if (it.NumStaticFields() != 0) { - klass->SetSFields(AllocObjectArray<Field>(self, it.NumStaticFields())); + klass->SetSFields(AllocFieldArray(self, it.NumStaticFields())); } if (it.NumInstanceFields() != 0) { - klass->SetIFields(AllocObjectArray<Field>(self, it.NumInstanceFields())); + klass->SetIFields(AllocFieldArray(self, it.NumInstanceFields())); } for (size_t i = 0; it.HasNextStaticField(); i++, it.Next()) { SirtRef<Field> sfield(self, AllocField(self)); @@ -1618,11 +1630,11 @@ void ClassLinker::LoadClass(const DexFile& dex_file, // Load methods. if (it.NumDirectMethods() != 0) { // TODO: append direct methods to class object - klass->SetDirectMethods(AllocObjectArray<AbstractMethod>(self, it.NumDirectMethods())); + klass->SetDirectMethods(AllocAbstractMethodArray(self, it.NumDirectMethods())); } if (it.NumVirtualMethods() != 0) { // TODO: append direct methods to class object - klass->SetVirtualMethods(AllocObjectArray<AbstractMethod>(self, it.NumVirtualMethods())); + klass->SetVirtualMethods(AllocMethodArray(self, it.NumVirtualMethods())); } size_t class_def_method_index = 0; for (size_t i = 0; it.HasNextDirectMethod(); i++, it.Next()) { @@ -1778,16 +1790,6 @@ void ClassLinker::RegisterDexFile(const DexFile& dex_file, SirtRef<DexCache>& de RegisterDexFileLocked(dex_file, dex_cache); } -// TODO: Remove. -const DexFile& ClassLinker::FindDexFile(const DexCache* dex_cache) const { - CHECK(dex_cache != NULL); - const DexFile* dex_file = dex_cache->GetDexFile(); - if (dex_file == NULL) { - LOG(FATAL) << "DexCache has no DexFile " << dex_cache->GetLocation()->ToModifiedUtf8(); - } - return *dex_file; -} - DexCache* ClassLinker::FindDexCache(const DexFile& dex_file) const { MutexLock mu(Thread::Current(), dex_lock_); for (size_t i = 0; i != dex_caches_.size(); ++i) { @@ -1886,10 +1888,12 @@ Class* ClassLinker::CreateArrayClass(const std::string& descriptor, ClassLoader* new_class.reset(GetClassRoot(kObjectArrayArrayClass)); } else if (descriptor == class_roots_descriptors_[kJavaLangStringArrayClass]) { new_class.reset(GetClassRoot(kJavaLangStringArrayClass)); - } else if (descriptor == class_roots_descriptors_[kJavaLangReflectFieldArrayClass]) { - new_class.reset(GetClassRoot(kJavaLangReflectFieldArrayClass)); } else if (descriptor == class_roots_descriptors_[kJavaLangReflectAbstractMethodArrayClass]) { new_class.reset(GetClassRoot(kJavaLangReflectAbstractMethodArrayClass)); + } else if (descriptor == class_roots_descriptors_[kJavaLangReflectFieldArrayClass]) { + new_class.reset(GetClassRoot(kJavaLangReflectFieldArrayClass)); + } else if (descriptor == class_roots_descriptors_[kJavaLangReflectMethodArrayClass]) { + new_class.reset(GetClassRoot(kJavaLangReflectMethodArrayClass)); } else if (descriptor == "[C") { new_class.reset(GetClassRoot(kCharArrayClass)); } else if (descriptor == "[I") { @@ -2145,7 +2149,7 @@ void ClassLinker::VerifyClass(Class* klass) { } // Try to use verification information from the oat file, otherwise do runtime verification. - const DexFile& dex_file = FindDexFile(klass->GetDexCache()); + const DexFile& dex_file = *klass->GetDexCache()->GetDexFile(); Class::Status oat_file_class_status(Class::kStatusNotReady); bool preverified = VerifyClassUsingOatFile(dex_file, klass, oat_file_class_status); verifier::MethodVerifier::FailureKind verifier_failure = verifier::MethodVerifier::kNoFailure; @@ -2318,7 +2322,7 @@ Class* ClassLinker::CreateProxyClass(String* name, ObjectArray<Class>* interface klass->SetDexTypeIndex(DexFile::kDexNoIndex16); // Instance fields are inherited, but we add a couple of static fields... - klass->SetSFields(AllocObjectArray<Field>(self, 2)); + klass->SetSFields(AllocFieldArray(self, 2)); // 1. Create a static field 'interfaces' that holds the _declared_ interfaces implemented by // our proxy, so Class.getInterfaces doesn't return the flattened set. SirtRef<Field> interfaces_sfield(self, AllocField(self)); @@ -2334,12 +2338,12 @@ Class* ClassLinker::CreateProxyClass(String* name, ObjectArray<Class>* interface throws_sfield->SetAccessFlags(kAccStatic | kAccPublic | kAccFinal); // Proxies have 1 direct method, the constructor - klass->SetDirectMethods(AllocObjectArray<AbstractMethod>(self, 1)); + klass->SetDirectMethods(AllocAbstractMethodArray(self, 1)); klass->SetDirectMethod(0, CreateProxyConstructor(self, klass, proxy_class)); // Create virtual method using specified prototypes size_t num_virtual_methods = methods->GetLength(); - klass->SetVirtualMethods(AllocObjectArray<AbstractMethod>(self, num_virtual_methods)); + klass->SetVirtualMethods(AllocMethodArray(self, num_virtual_methods)); for (size_t i = 0; i < num_virtual_methods; ++i) { SirtRef<AbstractMethod> prototype(self, methods->Get(i)); klass->SetVirtualMethod(i, CreateProxyMethod(self, klass, prototype)); @@ -2706,7 +2710,7 @@ bool ClassLinker::IsSameMethodSignatureInDifferentClassContexts(const AbstractMe if (klass1 == klass2) { return true; } - const DexFile& dex_file = FindDexFile(method->GetDeclaringClass()->GetDexCache()); + const DexFile& dex_file = *method->GetDeclaringClass()->GetDexCache()->GetDexFile(); const DexFile::ProtoId& proto_id = dex_file.GetMethodPrototype(dex_file.GetMethodId(method->GetDexMethodIndex())); for (DexFileParameterIterator it(dex_file, proto_id); it.HasNext(); it.Next()) { @@ -3042,7 +3046,7 @@ bool ClassLinker::LinkVirtualMethods(SirtRef<Class>& klass) { return false; } SirtRef<ObjectArray<AbstractMethod> > - vtable(self, AllocObjectArray<AbstractMethod>(self, num_virtual_methods)); + vtable(self, AllocMethodArray(self, num_virtual_methods)); for (size_t i = 0; i < num_virtual_methods; ++i) { AbstractMethod* virtual_method = klass->GetVirtualMethodDuringLinking(i); vtable->Set(i, virtual_method); @@ -3145,7 +3149,7 @@ bool ClassLinker::LinkInterfaceMethods(SirtRef<Class>& klass, ObjectArray<Class> InterfaceEntry* interface_entry = iftable->Get(i); Class* interface = interface_entry->GetInterface(); ObjectArray<AbstractMethod>* method_array = - AllocObjectArray<AbstractMethod>(self, interface->NumVirtualMethods()); + AllocMethodArray(self, interface->NumVirtualMethods()); interface_entry->SetMethodArray(method_array); ObjectArray<AbstractMethod>* vtable = klass->GetVTableDuringLinking(); for (size_t j = 0; j < interface->NumVirtualMethods(); ++j) { @@ -3196,7 +3200,7 @@ bool ClassLinker::LinkInterfaceMethods(SirtRef<Class>& klass, ObjectArray<Class> int old_method_count = klass->NumVirtualMethods(); int new_method_count = old_method_count + miranda_list.size(); klass->SetVirtualMethods((old_method_count == 0) - ? AllocObjectArray<AbstractMethod>(self, new_method_count) + ? AllocMethodArray(self, new_method_count) : klass->GetVirtualMethods()->CopyOf(self, new_method_count)); SirtRef<ObjectArray<AbstractMethod> > vtable(self, klass->GetVTableDuringLinking()); @@ -3729,7 +3733,7 @@ Field* ClassLinker::ResolveFieldJLS(const DexFile& dex_file, const char* ClassLinker::MethodShorty(uint32_t method_idx, AbstractMethod* referrer, uint32_t* length) { Class* declaring_class = referrer->GetDeclaringClass(); DexCache* dex_cache = declaring_class->GetDexCache(); - const DexFile& dex_file = FindDexFile(dex_cache); + const DexFile& dex_file = *dex_cache->GetDexFile(); const DexFile::MethodId& method_id = dex_file.GetMethodId(method_idx); return dex_file.GetMethodShorty(method_id, length); } diff --git a/src/class_linker.h b/src/class_linker.h index 38b402f294..fd404c1411 100644 --- a/src/class_linker.h +++ b/src/class_linker.h @@ -104,7 +104,7 @@ class ClassLinker { if (UNLIKELY(resolved_string == NULL)) { Class* declaring_class = referrer->GetDeclaringClass(); DexCache* dex_cache = declaring_class->GetDexCache(); - const DexFile& dex_file = FindDexFile(dex_cache); + const DexFile& dex_file = *dex_cache->GetDexFile(); resolved_string = ResolveString(dex_file, string_idx, dex_cache); } return resolved_string; @@ -136,7 +136,7 @@ class ClassLinker { Class* declaring_class = referrer->GetDeclaringClass(); DexCache* dex_cache = declaring_class->GetDexCache(); ClassLoader* class_loader = declaring_class->GetClassLoader(); - const DexFile& dex_file = FindDexFile(dex_cache); + const DexFile& dex_file = *dex_cache->GetDexFile(); resolved_type = ResolveType(dex_file, type_idx, dex_cache, class_loader); } return resolved_type; @@ -149,7 +149,7 @@ class ClassLinker { Class* resolved_type = dex_cache->GetResolvedType(type_idx); if (UNLIKELY(resolved_type == NULL)) { ClassLoader* class_loader = declaring_class->GetClassLoader(); - const DexFile& dex_file = FindDexFile(dex_cache); + const DexFile& dex_file = *dex_cache->GetDexFile(); resolved_type = ResolveType(dex_file, type_idx, dex_cache, class_loader); } return resolved_type; @@ -185,7 +185,7 @@ class ClassLinker { Class* declaring_class = referrer->GetDeclaringClass(); DexCache* dex_cache = declaring_class->GetDexCache(); ClassLoader* class_loader = declaring_class->GetClassLoader(); - const DexFile& dex_file = FindDexFile(dex_cache); + const DexFile& dex_file = *dex_cache->GetDexFile(); resolved_method = ResolveMethod(dex_file, method_idx, dex_cache, class_loader, referrer, type); } return resolved_method; @@ -199,7 +199,7 @@ class ClassLinker { Class* declaring_class = referrer->GetDeclaringClass(); DexCache* dex_cache = declaring_class->GetDexCache(); ClassLoader* class_loader = declaring_class->GetClassLoader(); - const DexFile& dex_file = FindDexFile(dex_cache); + const DexFile& dex_file = *dex_cache->GetDexFile(); resolved_field = ResolveField(dex_file, field_idx, dex_cache, class_loader, is_static); } return resolved_field; @@ -265,9 +265,6 @@ class ClassLinker { void VisitRoots(Heap::RootVisitor* visitor, void* arg) const LOCKS_EXCLUDED(Locks::classlinker_classes_lock_, dex_lock_); - const DexFile& FindDexFile(const DexCache* dex_cache) const - LOCKS_EXCLUDED(dex_lock_) - SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); DexCache* FindDexCache(const DexFile& dex_file) const LOCKS_EXCLUDED(dex_lock_) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); @@ -328,12 +325,18 @@ class ClassLinker { return ObjectArray<String>::Alloc(self, GetClassRoot(kJavaLangStringArrayClass), length); } - ObjectArray<AbstractMethod>* AllocMethodArray(Thread* self, size_t length) + ObjectArray<AbstractMethod>* AllocAbstractMethodArray(Thread* self, size_t length) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { return ObjectArray<AbstractMethod>::Alloc(self, GetClassRoot(kJavaLangReflectAbstractMethodArrayClass), length); } + ObjectArray<AbstractMethod>* AllocMethodArray(Thread* self, size_t length) + SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { + return ObjectArray<AbstractMethod>::Alloc(self, + GetClassRoot(kJavaLangReflectMethodArrayClass), length); + } + ObjectArray<InterfaceEntry>* AllocIfTable(Thread* self, size_t length) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { return ObjectArray<InterfaceEntry>::Alloc(self, GetClassRoot(kObjectArrayArrayClass), length); @@ -581,8 +584,9 @@ class ClassLinker { kJavaLangReflectMethod, kJavaLangReflectProxy, kJavaLangStringArrayClass, - kJavaLangReflectFieldArrayClass, kJavaLangReflectAbstractMethodArrayClass, + kJavaLangReflectFieldArrayClass, + kJavaLangReflectMethodArrayClass, kJavaLangClassLoader, kJavaLangThrowable, kJavaLangClassNotFoundException, diff --git a/src/common_test.h b/src/common_test.h index 6994ac3c18..62ff9074a2 100644 --- a/src/common_test.h +++ b/src/common_test.h @@ -229,7 +229,7 @@ class CommonTest : public testing::Test { if (!method->IsAbstract()) { const DexCache* dex_cache = method->GetDeclaringClass()->GetDexCache(); - const DexFile& dex_file = Runtime::Current()->GetClassLinker()->FindDexFile(dex_cache); + const DexFile& dex_file = *dex_cache->GetDexFile(); const CompiledMethod* compiled_method = compiler_->GetCompiledMethod(Compiler::MethodReference(&dex_file, method->GetDexMethodIndex())); diff --git a/src/common_throws.cc b/src/common_throws.cc index 7ab5614d04..9fb686a26a 100644 --- a/src/common_throws.cc +++ b/src/common_throws.cc @@ -61,7 +61,7 @@ void ThrowNullPointerExceptionForFieldAccess(Field* field, bool is_read) { void ThrowNullPointerExceptionForMethodAccess(AbstractMethod* caller, uint32_t method_idx, InvokeType type) { DexCache* dex_cache = caller->GetDeclaringClass()->GetDexCache(); - const DexFile& dex_file = Runtime::Current()->GetClassLinker()->FindDexFile(dex_cache); + const DexFile& dex_file = *dex_cache->GetDexFile(); std::ostringstream msg; msg << "Attempt to invoke " << type << " method '" << PrettyMethod(method_idx, dex_file, true) << "' on a null object reference"; @@ -133,8 +133,7 @@ void ThrowNullPointerExceptionFromDexPC(AbstractMethod* throw_method, uint32_t d default: { // TODO: We should have covered all the cases where we expect a NPE above, this // message/logging is so we can improve any cases we've missed in the future. - const DexFile& dex_file = Runtime::Current()->GetClassLinker() - ->FindDexFile(throw_method->GetDeclaringClass()->GetDexCache()); + const DexFile& dex_file = *throw_method->GetDeclaringClass()->GetDexCache()->GetDexFile(); std::string message("Null pointer exception during instruction '"); message += instr->DumpString(&dex_file); message += "'"; @@ -243,7 +242,7 @@ void ThrowNoSuchMethodError(InvokeType type, Class* c, const StringPiece& name, void ThrowNoSuchMethodError(uint32_t method_idx, const AbstractMethod* referrer) { DexCache* dex_cache = referrer->GetDeclaringClass()->GetDexCache(); - const DexFile& dex_file = Runtime::Current()->GetClassLinker()->FindDexFile(dex_cache); + const DexFile& dex_file = *dex_cache->GetDexFile(); std::ostringstream msg; msg << "No method '" << PrettyMethod(method_idx, dex_file, true) << "'"; AddReferrerLocation(msg, referrer); diff --git a/src/compiler.cc b/src/compiler.cc index 3899ce9ed6..8909c36f12 100644 --- a/src/compiler.cc +++ b/src/compiler.cc @@ -510,7 +510,7 @@ void Compiler::CompileOne(const AbstractMethod* method) { class_loader = soa.Env()->NewGlobalRef(local_class_loader.get()); // Find the dex_file dex_cache = method->GetDeclaringClass()->GetDexCache(); - dex_file = &Runtime::Current()->GetClassLinker()->FindDexFile(dex_cache); + dex_file = dex_cache->GetDexFile(); } self->TransitionFromRunnableToSuspended(kNative); @@ -708,7 +708,7 @@ bool Compiler::ComputeInstanceFieldInfo(uint32_t field_idx, OatCompilationUnit* // The referring class can't access the resolved field, this may occur as a result of a // protected field being made public by a sub-class. Resort to the dex file to determine // the correct class for the access check. - const DexFile& dex_file = mUnit->class_linker_->FindDexFile(referrer_class->GetDexCache()); + const DexFile& dex_file = *referrer_class->GetDexCache()->GetDexFile(); Class* dex_fields_class = mUnit->class_linker_->ResolveType(dex_file, dex_file.GetFieldId(field_idx).class_idx_, referrer_class); @@ -764,7 +764,7 @@ bool Compiler::ComputeStaticFieldInfo(uint32_t field_idx, OatCompilationUnit* mU // protected field being made public by a sub-class. Resort to the dex file to determine // the correct class for the access check. Don't change the field's class as that is // used to identify the SSB. - const DexFile& dex_file = mUnit->class_linker_->FindDexFile(referrer_class->GetDexCache()); + const DexFile& dex_file = *referrer_class->GetDexCache()->GetDexFile(); Class* dex_fields_class = mUnit->class_linker_->ResolveType(dex_file, dex_file.GetFieldId(field_idx).class_idx_, @@ -878,7 +878,7 @@ bool Compiler::ComputeInvokeInfo(uint32_t method_idx, OatCompilationUnit* mUnit, // protected method being made public by implementing an interface that re-declares the // method public. Resort to the dex file to determine the correct class for the access // check. - const DexFile& dex_file = mUnit->class_linker_->FindDexFile(referrer_class->GetDexCache()); + const DexFile& dex_file = *referrer_class->GetDexCache()->GetDexFile(); methods_class = mUnit->class_linker_->ResolveType(dex_file, dex_file.GetMethodId(method_idx).class_idx_, diff --git a/src/debugger.cc b/src/debugger.cc index c8e7381c6b..6f0ec5871f 100644 --- a/src/debugger.cc +++ b/src/debugger.cc @@ -2167,7 +2167,7 @@ JDWP::JdwpError Dbg::ConfigureStep(JDWP::ObjectId threadId, JDWP::JdwpStepSize s gSingleStepControl.method = m; gSingleStepControl.line_number = -1; if (dex_cache != NULL) { - const DexFile& dex_file = Runtime::Current()->GetClassLinker()->FindDexFile(dex_cache); + const DexFile& dex_file = *dex_cache->GetDexFile(); gSingleStepControl.line_number = dex_file.GetLineNumFromPC(m, GetDexPc()); } } diff --git a/src/exception_test.cc b/src/exception_test.cc index c35572d51e..58e6533058 100644 --- a/src/exception_test.cc +++ b/src/exception_test.cc @@ -38,7 +38,7 @@ class ExceptionTest : public CommonTest { ASSERT_TRUE(my_klass_ != NULL); class_linker_->EnsureInitialized(my_klass_, false, true); - dex_ = &Runtime::Current()->GetClassLinker()->FindDexFile(my_klass_->GetDexCache()); + dex_ = my_klass_->GetDexCache()->GetDexFile(); uint32_t code_size = 12; fake_code_.push_back((code_size >> 24) & 0xFF); diff --git a/src/image_writer.cc b/src/image_writer.cc index fe12baf2da..0b9c8c0ae9 100644 --- a/src/image_writer.cc +++ b/src/image_writer.cc @@ -172,11 +172,10 @@ void ImageWriter::ComputeEagerResolvedStringsCallback(Object* obj, void* arg) { String* string = obj->AsString(); std::string utf8_string(string->ToModifiedUtf8()); ImageWriter* writer = reinterpret_cast<ImageWriter*>(arg); - ClassLinker* linker = Runtime::Current()->GetClassLinker(); typedef Set::const_iterator CacheIt; // TODO: C++0x auto for (CacheIt it = writer->dex_caches_.begin(), end = writer->dex_caches_.end(); it != end; ++it) { DexCache* dex_cache = *it; - const DexFile& dex_file = linker->FindDexFile(dex_cache); + const DexFile& dex_file = *dex_cache->GetDexFile(); const DexFile::StringId* string_id = dex_file.FindStringId(utf8_string); if (string_id != NULL) { // This string occurs in this dex file, assign the dex cache entry. diff --git a/src/native/java_lang_Class.cc b/src/native/java_lang_Class.cc index 488df80e65..59c9bef0f1 100644 --- a/src/native/java_lang_Class.cc +++ b/src/native/java_lang_Class.cc @@ -88,147 +88,6 @@ static jint Class_getAnnotationDirectoryOffset(JNIEnv* env, jclass javaClass) { } } -// TODO: Remove this redundant struct when GCC annotalysis works correctly on top-level functions. -struct WorkAroundGccAnnotalysisBug { -template<typename T> -static jobjectArray ToArray(const ScopedObjectAccessUnchecked& soa, const char* array_class_name, - const std::vector<T*>& objects) - SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { - ScopedLocalRef<jclass> array_class(soa.Env(), soa.Env()->FindClass(array_class_name)); - jobjectArray result = soa.Env()->NewObjectArray(objects.size(), array_class.get(), NULL); - for (size_t i = 0; i < objects.size(); ++i) { - ScopedLocalRef<jobject> object(soa.Env(), soa.AddLocalReference<jobject>(objects[i])); - soa.Env()->SetObjectArrayElement(result, i, object.get()); - } - return result; -} -}; -#define ToArray(a, b, c) WorkAroundGccAnnotalysisBug::ToArray(a, b, c) - -static bool IsVisibleConstructor(AbstractMethod* m, bool public_only) { - if (public_only && !m->IsPublic()) { - return false; - } - if (m->IsStatic()) { - return false; - } - return m->IsConstructor(); -} - -static jobjectArray Class_getDeclaredConstructors(JNIEnv* env, jclass javaClass, jboolean publicOnly) { - ScopedObjectAccess soa(env); - Class* c = DecodeClass(soa, javaClass); - std::vector<AbstractMethod*> constructors; // TODO: Use Constructor instead of AbstractMethod - for (size_t i = 0; i < c->NumDirectMethods(); ++i) { - AbstractMethod* m = c->GetDirectMethod(i); - if (IsVisibleConstructor(m, publicOnly)) { - constructors.push_back(m); - } - } - - return ToArray(soa, "java/lang/reflect/Constructor", constructors); -} - -static bool IsVisibleField(Field* f, bool public_only) { - if (public_only && !f->IsPublic()) { - return false; - } - return true; -} - -static jobjectArray Class_getDeclaredFields(JNIEnv* env, jclass javaClass, jboolean publicOnly) { - ScopedObjectAccess soa(env); - Class* c = DecodeClass(soa, javaClass); - std::vector<Field*> fields; - FieldHelper fh; - for (size_t i = 0; i < c->NumInstanceFields(); ++i) { - Field* f = c->GetInstanceField(i); - fh.ChangeField(f); - if (IsVisibleField(f, publicOnly)) { - if (fh.GetType() == NULL) { - DCHECK(env->ExceptionOccurred()); - return NULL; - } - fields.push_back(f); - } - if (env->ExceptionOccurred()) { - return NULL; - } - } - for (size_t i = 0; i < c->NumStaticFields(); ++i) { - Field* f = c->GetStaticField(i); - fh.ChangeField(f); - if (IsVisibleField(f, publicOnly)) { - if (fh.GetType() == NULL) { - DCHECK(env->ExceptionOccurred()); - return NULL; - } - fields.push_back(f); - } - if (env->ExceptionOccurred()) { - return NULL; - } - } - - return ToArray(soa, "java/lang/reflect/Field", fields); -} - -static bool IsVisibleMethod(AbstractMethod* m, bool public_only) { - if (public_only && !m->IsPublic()) { - return false; - } - if (m->IsConstructor()) { - return false; - } - if (m->IsMiranda()) { - return false; - } - return true; -} - -static jobjectArray Class_getDeclaredMethods(JNIEnv* env, jclass javaClass, jboolean publicOnly) { - ScopedObjectAccess soa(env); - Class* c = DecodeClass(soa, javaClass); - if (c == NULL) { - return NULL; - } - - std::vector<AbstractMethod*> methods; - MethodHelper mh; - for (size_t i = 0; i < c->NumVirtualMethods(); ++i) { - AbstractMethod* m = c->GetVirtualMethod(i); - mh.ChangeMethod(m); - if (IsVisibleMethod(m, publicOnly)) { - // TODO: the use of GetParameterTypes creates an unused array here. - if (mh.GetReturnType() == NULL || mh.GetParameterTypes(soa.Self()) == NULL) { - DCHECK(env->ExceptionOccurred()); - return NULL; - } - methods.push_back(m); - } - if (env->ExceptionOccurred()) { - return NULL; - } - } - for (size_t i = 0; i < c->NumDirectMethods(); ++i) { - AbstractMethod* m = c->GetDirectMethod(i); - mh.ChangeMethod(m); - if (IsVisibleMethod(m, publicOnly)) { - // TODO: the use of GetParameterTypes creates an unused array here. - if (mh.GetReturnType() == NULL || mh.GetParameterTypes(soa.Self()) == NULL) { - DCHECK(env->ExceptionOccurred()); - return NULL; - } - methods.push_back(m); - } - if (env->ExceptionOccurred()) { - return NULL; - } - } - - return ToArray(soa, "java/lang/reflect/Method", methods); -} - static jobject Class_getDex(JNIEnv* env, jobject javaClass) { ScopedObjectAccess soa(env); Class* c = DecodeClass(soa, javaClass); @@ -237,109 +96,11 @@ static jobject Class_getDex(JNIEnv* env, jobject javaClass) { if (dex_cache == NULL) { return NULL; } - - return Runtime::Current()->GetClassLinker()->FindDexFile(dex_cache).GetDexObject(env); -} - -static bool MethodMatches(MethodHelper* mh, const std::string& name, ObjectArray<Class>* arg_array) - SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { - if (name != mh->GetName()) { - return false; - } - const DexFile::TypeList* m_type_list = mh->GetParameterTypeList(); - uint32_t m_type_list_size = m_type_list == NULL ? 0 : m_type_list->Size(); - uint32_t sig_length = arg_array->GetLength(); - - if (m_type_list_size != sig_length) { - return false; - } - - for (uint32_t i = 0; i < sig_length; i++) { - if (mh->GetClassFromTypeIdx(m_type_list->GetTypeItem(i).type_idx_) != arg_array->Get(i)) { - return false; - } - } - return true; -} - -static AbstractMethod* FindConstructorOrMethodInArray(ObjectArray<AbstractMethod>* methods, - const std::string& name, - ObjectArray<Class>* arg_array) - SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { - if (methods == NULL) { + const DexFile* dex_file = dex_cache->GetDexFile(); + if (dex_file == NULL) { return NULL; } - AbstractMethod* result = NULL; - MethodHelper mh; - for (int32_t i = 0; i < methods->GetLength(); ++i) { - AbstractMethod* method = methods->Get(i); - mh.ChangeMethod(method); - if (method->IsMiranda() || !MethodMatches(&mh, name, arg_array)) { - continue; - } - - result = method; - - // Covariant return types permit the class to define multiple - // methods with the same name and parameter types. Prefer to return - // a non-synthetic method in such situations. We may still return - // a synthetic method to handle situations like escalated visibility. - if (!method->IsSynthetic()) { - break; - } - } - return result; -} - -static jobject Class_getDeclaredConstructorOrMethod(JNIEnv* env, jclass javaClass, jstring javaName, - jobjectArray javaArgs) { - ScopedObjectAccess soa(env); - Class* c = DecodeClass(soa, javaClass); - std::string name(soa.Decode<String*>(javaName)->ToModifiedUtf8()); - ObjectArray<Class>* arg_array = soa.Decode<ObjectArray<Class>*>(javaArgs); - - AbstractMethod* m = FindConstructorOrMethodInArray(c->GetDirectMethods(), name, arg_array); - if (m == NULL) { - m = FindConstructorOrMethodInArray(c->GetVirtualMethods(), name, arg_array); - } - - if (m != NULL) { - return soa.AddLocalReference<jobject>(m); - } else { - return NULL; - } -} - -static jobject Class_getDeclaredFieldNative(JNIEnv* env, jclass java_class, jobject jname) { - ScopedObjectAccess soa(env); - Class* c = DecodeClass(soa, java_class); - String* name = soa.Decode<String*>(jname); - DCHECK(name->GetClass()->IsStringClass()); - - FieldHelper fh; - for (size_t i = 0; i < c->NumInstanceFields(); ++i) { - Field* f = c->GetInstanceField(i); - fh.ChangeField(f); - if (name->Equals(fh.GetName())) { - if (fh.GetType() == NULL) { - DCHECK(env->ExceptionOccurred()); - return NULL; - } - return soa.AddLocalReference<jclass>(f); - } - } - for (size_t i = 0; i < c->NumStaticFields(); ++i) { - Field* f = c->GetStaticField(i); - fh.ChangeField(f); - if (name->Equals(fh.GetName())) { - if (fh.GetType() == NULL) { - DCHECK(env->ExceptionOccurred()); - return NULL; - } - return soa.AddLocalReference<jclass>(f); - } - } - return NULL; + return dex_file->GetDexObject(env); } static jstring Class_getNameNative(JNIEnv* env, jobject javaThis) { @@ -354,91 +115,12 @@ static jobjectArray Class_getProxyInterfaces(JNIEnv* env, jobject javaThis) { return soa.AddLocalReference<jobjectArray>(c->GetInterfaces()->Clone(soa.Self())); } -static jboolean Class_isAssignableFrom(JNIEnv* env, jobject javaLhs, jclass javaRhs) { - ScopedObjectAccess soa(env); - Class* lhs = DecodeClass(soa, javaLhs); - Class* rhs = soa.Decode<Class*>(javaRhs); // Can be null. - if (rhs == NULL) { - soa.Self()->ThrowNewException("Ljava/lang/NullPointerException;", "class == null"); - return JNI_FALSE; - } - return lhs->IsAssignableFrom(rhs) ? JNI_TRUE : JNI_FALSE; -} - -static jobject Class_newInstanceImpl(JNIEnv* env, jobject javaThis) { - ScopedObjectAccess soa(env); - Class* c = DecodeClass(soa, javaThis); - if (c->IsPrimitive() || c->IsInterface() || c->IsArrayClass() || c->IsAbstract()) { - soa.Self()->ThrowNewExceptionF("Ljava/lang/InstantiationException;", - "Class %s can not be instantiated", PrettyDescriptor(ClassHelper(c).GetDescriptor()).c_str()); - return NULL; - } - - if (!Runtime::Current()->GetClassLinker()->EnsureInitialized(c, true, true)) { - return NULL; - } - - AbstractMethod* init = c->FindDeclaredDirectMethod("<init>", "()V"); - if (init == NULL) { - soa.Self()->ThrowNewExceptionF("Ljava/lang/InstantiationException;", - "Class %s has no default <init>()V constructor", PrettyDescriptor(ClassHelper(c).GetDescriptor()).c_str()); - return NULL; - } - - // Verify access from the call site. - // - // First, make sure the method invoking Class.newInstance() has permission - // to access the class. - // - // Second, make sure it has permission to invoke the constructor. The - // constructor must be public or, if the caller is in the same package, - // have package scope. - - NthCallerVisitor visitor(soa.Self()->GetManagedStack(), soa.Self()->GetTraceStack(), 2); - visitor.WalkStack(); - Class* caller_class = visitor.caller->GetDeclaringClass(); - - ClassHelper caller_ch(caller_class); - if (!caller_class->CanAccess(c)) { - soa.Self()->ThrowNewExceptionF("Ljava/lang/IllegalAccessException;", - "Class %s is not accessible from class %s", - PrettyDescriptor(ClassHelper(c).GetDescriptor()).c_str(), - PrettyDescriptor(caller_ch.GetDescriptor()).c_str()); - return NULL; - } - if (!caller_class->CanAccessMember(init->GetDeclaringClass(), init->GetAccessFlags())) { - soa.Self()->ThrowNewExceptionF("Ljava/lang/IllegalAccessException;", - "%s is not accessible from class %s", - PrettyMethod(init).c_str(), - PrettyDescriptor(caller_ch.GetDescriptor()).c_str()); - return NULL; - } - - Object* new_obj = c->AllocObject(soa.Self()); - if (new_obj == NULL) { - DCHECK(soa.Self()->IsExceptionPending()); - return NULL; - } - - // invoke constructor; unlike reflection calls, we don't wrap exceptions - jclass java_class = soa.AddLocalReference<jclass>(c); - jmethodID mid = soa.EncodeMethod(init); - return env->NewObject(java_class, mid); -} - static JNINativeMethod gMethods[] = { NATIVE_METHOD(Class, classForName, "(Ljava/lang/String;ZLjava/lang/ClassLoader;)Ljava/lang/Class;"), NATIVE_METHOD(Class, getAnnotationDirectoryOffset, "()I"), - NATIVE_METHOD(Class, getDeclaredConstructorOrMethod, "(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Member;"), - NATIVE_METHOD(Class, getDeclaredConstructors, "(Z)[Ljava/lang/reflect/Constructor;"), - NATIVE_METHOD(Class, getDeclaredFieldNative, "(Ljava/lang/String;)Ljava/lang/reflect/Field;"), - NATIVE_METHOD(Class, getDeclaredFields, "(Z)[Ljava/lang/reflect/Field;"), - NATIVE_METHOD(Class, getDeclaredMethods, "(Z)[Ljava/lang/reflect/Method;"), NATIVE_METHOD(Class, getDex, "()Lcom/android/dex/Dex;"), NATIVE_METHOD(Class, getNameNative, "()Ljava/lang/String;"), NATIVE_METHOD(Class, getProxyInterfaces, "()[Ljava/lang/Class;"), - NATIVE_METHOD(Class, isAssignableFrom, "(Ljava/lang/Class;)Z"), - NATIVE_METHOD(Class, newInstanceImpl, "()Ljava/lang/Object;"), }; void register_java_lang_Class(JNIEnv* env) { diff --git a/src/object.h b/src/object.h index baa7313bb2..1af30ea7a0 100644 --- a/src/object.h +++ b/src/object.h @@ -1536,10 +1536,10 @@ class MANAGED Class : public StaticStorageBase { SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { DCHECK(src != NULL); if (this == src) { - // Can always assign to things of the same type + // Can always assign to things of the same type. return true; } else if (IsObjectClass()) { - // Can assign any reference to java.lang.Object + // Can assign any reference to java.lang.Object. return !src->IsPrimitive(); } else if (IsInterface()) { return src->Implements(this); diff --git a/src/object_utils.h b/src/object_utils.h index 297035f1a0..1bbb7bc187 100644 --- a/src/object_utils.h +++ b/src/object_utils.h @@ -654,8 +654,7 @@ class MethodHelper { const DexFile* result = dex_file_; if (result == NULL) { const DexCache* dex_cache = GetDexCache(); - result = &GetClassLinker()->FindDexFile(dex_cache); - dex_file_ = result; + result = dex_file_ = dex_cache->GetDexFile(); } return *result; } diff --git a/src/runtime_support.cc b/src/runtime_support.cc index 54baa42747..7ee1960213 100644 --- a/src/runtime_support.cc +++ b/src/runtime_support.cc @@ -162,7 +162,7 @@ Field* FindFieldFromCode(uint32_t field_idx, const AbstractMethod* referrer, Thr // The referring class can't access the resolved field, this may occur as a result of a // protected field being made public by a sub-class. Resort to the dex file to determine // the correct class for the access check. - const DexFile& dex_file = class_linker->FindDexFile(referring_class->GetDexCache()); + const DexFile& dex_file = *referring_class->GetDexCache()->GetDexFile(); fields_class = class_linker->ResolveType(dex_file, dex_file.GetFieldId(field_idx).class_idx_, referring_class); @@ -256,7 +256,7 @@ AbstractMethod* FindMethodFromCode(uint32_t method_idx, Object* this_object, con // The referring class can't access the resolved method, this may occur as a result of a // protected method being made public by implementing an interface that re-declares the // method public. Resort to the dex file to determine the correct class for the access check - const DexFile& dex_file = class_linker->FindDexFile(referring_class->GetDexCache()); + const DexFile& dex_file = *referring_class->GetDexCache()->GetDexFile(); methods_class = class_linker->ResolveType(dex_file, dex_file.GetMethodId(method_idx).class_idx_, referring_class); diff --git a/src/thread.cc b/src/thread.cc index a63a5aa5b8..6e4a6335e9 100644 --- a/src/thread.cc +++ b/src/thread.cc @@ -802,11 +802,10 @@ struct StackDumpVisitor : public StackVisitor { } const int kMaxRepetition = 3; Class* c = m->GetDeclaringClass(); - ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); const DexCache* dex_cache = c->GetDexCache(); int line_number = -1; if (dex_cache != NULL) { // be tolerant of bad input - const DexFile& dex_file = class_linker->FindDexFile(dex_cache); + const DexFile& dex_file = *dex_cache->GetDexFile(); line_number = dex_file.GetLineNumFromPC(m, GetDexPc()); } if (line_number == last_line_number && last_method == m) { @@ -1701,9 +1700,7 @@ class CatchBlockStackVisitor : public StackVisitor { if (catch_method == NULL) { LOG(INFO) << "Handler is upcall"; } else { - ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); - const DexFile& dex_file = - class_linker->FindDexFile(catch_method->GetDeclaringClass()->GetDexCache()); + const DexFile& dex_file = *catch_method->GetDeclaringClass()->GetDexCache()->GetDexFile(); int line_number = dex_file.GetLineNumFromPC(catch_method, handler_dex_pc_); LOG(INFO) << "Handler: " << PrettyMethod(catch_method) << " (line: " << line_number << ")"; } |