Class clean-up.
Move Class code out of native and into Java.
Remove ClassLinker::FindDexFile.
Change-Id: Idd9c4563d2c32e76690675242ff491276ace9848
diff --git a/src/class_linker.cc b/src/class_linker.cc
index 9ce641f..8a655bd 100644
--- a/src/class_linker.cc
+++ b/src/class_linker.cc
@@ -176,8 +176,9 @@
"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 @@
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 @@
java_lang_reflect_Field->SetStatus(Class::kStatusResolved);
Field::SetClass(java_lang_reflect_Field.get());
- 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));
- 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);
+
+ 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);
+
AbstractMethod::SetClasses(java_lang_reflect_Constructor.get(), java_lang_reflect_Method.get());
// Set up array classes for string, field, method
@@ -350,13 +354,17 @@
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 @@
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 @@
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 @@
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 @@
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 @@
// 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 @@
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 @@
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 @@
}
// 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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 38b402f..fd404c1 100644
--- a/src/class_linker.h
+++ b/src/class_linker.h
@@ -104,7 +104,7 @@
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* 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* 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* 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* 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 @@
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 @@
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 @@
kJavaLangReflectMethod,
kJavaLangReflectProxy,
kJavaLangStringArrayClass,
- kJavaLangReflectFieldArrayClass,
kJavaLangReflectAbstractMethodArrayClass,
+ kJavaLangReflectFieldArrayClass,
+ kJavaLangReflectMethodArrayClass,
kJavaLangClassLoader,
kJavaLangThrowable,
kJavaLangClassNotFoundException,
diff --git a/src/common_test.h b/src/common_test.h
index 6994ac3..62ff907 100644
--- a/src/common_test.h
+++ b/src/common_test.h
@@ -229,7 +229,7 @@
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 7ab5614..9fb686a 100644
--- a/src/common_throws.cc
+++ b/src/common_throws.cc
@@ -61,7 +61,7 @@
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 @@
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(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 3899ce9..8909c36 100644
--- a/src/compiler.cc
+++ b/src/compiler.cc
@@ -510,7 +510,7 @@
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 @@
// 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 @@
// 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 @@
// 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 c8e7381..6f0ec58 100644
--- a/src/debugger.cc
+++ b/src/debugger.cc
@@ -2167,7 +2167,7 @@
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 c35572d..58e6533 100644
--- a/src/exception_test.cc
+++ b/src/exception_test.cc
@@ -38,7 +38,7 @@
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 fe12baf..0b9c8c0 100644
--- a/src/image_writer.cc
+++ b/src/image_writer.cc
@@ -172,11 +172,10 @@
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 488df80..59c9bef 100644
--- a/src/native/java_lang_Class.cc
+++ b/src/native/java_lang_Class.cc
@@ -88,147 +88,6 @@
}
}
-// 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 @@
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 @@
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 baa7313..1af30ea 100644
--- a/src/object.h
+++ b/src/object.h
@@ -1536,10 +1536,10 @@
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 297035f..1bbb7bc 100644
--- a/src/object_utils.h
+++ b/src/object_utils.h
@@ -654,8 +654,7 @@
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 54baa42..7ee1960 100644
--- a/src/runtime_support.cc
+++ b/src/runtime_support.cc
@@ -162,7 +162,7 @@
// 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 @@
// 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 a63a5aa..6e4a633 100644
--- a/src/thread.cc
+++ b/src/thread.cc
@@ -802,11 +802,10 @@
}
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 @@
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 << ")";
}