Delete ClassHelper and fix compaction bug in GetDirectInterface
Cleanup helps to prevent compaction bugs. Fixed a fairly serious
compaction error caused by calling ClassHelper::GetDirectInterface
without handling the case where it causes thread suspension due to
ResolveType.
Bug: 8981901
Change-Id: I82b3bb6dd48d21eb6ece7aae0733c4a23c2bc408
diff --git a/runtime/class_linker-inl.h b/runtime/class_linker-inl.h
index ce634e0..ac86014 100644
--- a/runtime/class_linker-inl.h
+++ b/runtime/class_linker-inl.h
@@ -49,7 +49,7 @@
}
DCHECK(!element_class->IsPrimitiveVoid());
std::string descriptor("[");
- descriptor += ClassHelper(element_class).GetDescriptor();
+ descriptor += element_class->GetDescriptor();
StackHandleScope<1> hs(Thread::Current());
Handle<mirror::ClassLoader> class_loader(hs.NewHandle(element_class->GetClassLoader()));
mirror::Class* array_class = FindClass(self, descriptor.c_str(), class_loader);
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index 84a3c5d..363e8b2 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -96,8 +96,8 @@
ThrowLocation throw_location = self->GetCurrentLocationForThrow();
if (c->GetVerifyErrorClass() != NULL) {
// TODO: change the verifier to store an _instance_, with a useful detail message?
- ClassHelper ve_ch(c->GetVerifyErrorClass());
- self->ThrowNewException(throw_location, ve_ch.GetDescriptor(), PrettyDescriptor(c).c_str());
+ self->ThrowNewException(throw_location, c->GetVerifyErrorClass()->GetDescriptor().c_str(),
+ PrettyDescriptor(c).c_str());
} else {
self->ThrowNewException(throw_location, "Ljava/lang/NoClassDefFoundError;",
PrettyDescriptor(c).c_str());
@@ -407,12 +407,10 @@
array_iftable_->SetInterface(1, java_io_Serializable);
// Sanity check Class[] and Object[]'s interfaces.
- ClassHelper kh(class_array_class.Get());
- CHECK_EQ(java_lang_Cloneable, kh.GetDirectInterface(0));
- CHECK_EQ(java_io_Serializable, kh.GetDirectInterface(1));
- kh.ChangeClass(object_array_class.Get());
- CHECK_EQ(java_lang_Cloneable, kh.GetDirectInterface(0));
- CHECK_EQ(java_io_Serializable, kh.GetDirectInterface(1));
+ CHECK_EQ(java_lang_Cloneable, mirror::Class::GetDirectInterface(self, class_array_class, 0));
+ CHECK_EQ(java_io_Serializable, mirror::Class::GetDirectInterface(self, class_array_class, 1));
+ CHECK_EQ(java_lang_Cloneable, mirror::Class::GetDirectInterface(self, object_array_class, 0));
+ CHECK_EQ(java_io_Serializable, mirror::Class::GetDirectInterface(self, object_array_class, 1));
// Run Class, ArtField, and ArtMethod through FindSystemClass. This initializes their
// dex_cache_ fields and register them in class_table_.
mirror::Class* Class_class = FindSystemClass(self, "Ljava/lang/Class;");
@@ -1730,9 +1728,8 @@
if (!runtime->IsStarted() || runtime->UseCompileTimeClassPath()) {
return; // OAT file unavailable.
}
- ClassHelper kh(klass);
- const DexFile& dex_file = kh.GetDexFile();
- const DexFile::ClassDef* dex_class_def = kh.GetClassDef();
+ const DexFile& dex_file = klass->GetDexFile();
+ const DexFile::ClassDef* dex_class_def = klass->GetClassDef();
CHECK(dex_class_def != nullptr);
const byte* class_data = dex_file.GetClassData(*dex_class_def);
// There should always be class data if there were direct methods.
@@ -2034,15 +2031,14 @@
if (klass->GetClassLoader() != NULL) { // All non-boot finalizer methods are flagged
klass->SetFinalizable();
} else {
- ClassHelper kh(klass.Get());
- const char* klass_descriptor = kh.GetDescriptor();
+ std::string klass_descriptor = klass->GetDescriptor();
// The Enum class declares a "final" finalize() method to prevent subclasses from
// introducing a finalizer. We don't want to set the finalizable flag for Enum or its
// subclasses, so we exclude it here.
// We also want to avoid setting the flag on Object, where we know that finalize() is
// empty.
- if ((strcmp("Ljava/lang/Object;", klass_descriptor) != 0) &&
- (strcmp("Ljava/lang/Enum;", klass_descriptor) != 0)) {
+ if (klass_descriptor.compare("Ljava/lang/Object;") != 0 &&
+ klass_descriptor.compare("Ljava/lang/Enum;") != 0) {
klass->SetFinalizable();
}
}
@@ -2403,9 +2399,7 @@
for (auto it = class_table_.lower_bound(hash), end = class_table_.end(); it != end && it->first == hash;
++it) {
mirror::Class* klass = it->second;
- ClassHelper kh(klass);
- if ((klass->GetClassLoader() == class_loader) &&
- (strcmp(descriptor, kh.GetDescriptor()) == 0)) {
+ if (klass->GetClassLoader() == class_loader && descriptor == klass->GetDescriptor()) {
class_table_.erase(it);
return true;
}
@@ -2449,16 +2443,13 @@
auto end = class_table_.end();
for (auto it = class_table_.lower_bound(hash); it != end && it->first == hash; ++it) {
mirror::Class* klass = it->second;
- ClassHelper kh(klass);
- if ((klass->GetClassLoader() == class_loader) &&
- (strcmp(descriptor, kh.GetDescriptor()) == 0)) {
+ if (klass->GetClassLoader() == class_loader && descriptor == klass->GetDescriptor()) {
if (kIsDebugBuild) {
// Check for duplicates in the table.
for (++it; it != end && it->first == hash; ++it) {
mirror::Class* klass2 = it->second;
- ClassHelper kh(klass2);
CHECK(!((klass2->GetClassLoader() == class_loader) &&
- (strcmp(descriptor, kh.GetDescriptor()) == 0)))
+ descriptor == klass2->GetDescriptor()))
<< PrettyClass(klass) << " " << klass << " " << klass->GetClassLoader() << " "
<< PrettyClass(klass2) << " " << klass2 << " " << klass2->GetClassLoader();
}
@@ -2492,11 +2483,10 @@
for (int32_t j = 0; j < types->GetLength(); j++) {
mirror::Class* klass = types->Get(j);
if (klass != NULL) {
- ClassHelper kh(klass);
DCHECK(klass->GetClassLoader() == NULL);
- const char* descriptor = kh.GetDescriptor();
- size_t hash = Hash(descriptor);
- mirror::Class* existing = LookupClassFromTableLocked(descriptor, NULL, hash);
+ std::string descriptor = klass->GetDescriptor();
+ size_t hash = Hash(descriptor.c_str());
+ mirror::Class* existing = LookupClassFromTableLocked(descriptor.c_str(), NULL, hash);
if (existing != NULL) {
CHECK(existing == klass) << PrettyClassAndClassLoader(existing) << " != "
<< PrettyClassAndClassLoader(klass);
@@ -2550,8 +2540,7 @@
for (auto it = class_table_.lower_bound(hash), end = class_table_.end();
it != end && it->first == hash; ++it) {
mirror::Class* klass = it->second;
- ClassHelper kh(klass);
- if (strcmp(descriptor, kh.GetDescriptor()) == 0) {
+ if (descriptor == klass->GetDescriptor()) {
result.push_back(klass);
}
}
@@ -2763,7 +2752,7 @@
}
LOG(FATAL) << "Unexpected class status: " << oat_file_class_status
<< " " << dex_file.GetLocation() << " " << PrettyClass(klass) << " "
- << ClassHelper(klass).GetDescriptor();
+ << klass->GetDescriptor();
return false;
}
@@ -3083,8 +3072,7 @@
}
// Check if there are encoded static values needing initialization.
if (klass->NumStaticFields() != 0) {
- ClassHelper kh(klass);
- const DexFile::ClassDef* dex_class_def = kh.GetClassDef();
+ const DexFile::ClassDef* dex_class_def = klass->GetClassDef();
DCHECK(dex_class_def != NULL);
if (dex_class_def->static_values_off_ != 0) {
return false;
@@ -3213,13 +3201,12 @@
}
if (klass->NumStaticFields() > 0) {
- ClassHelper kh(klass.Get());
- const DexFile::ClassDef* dex_class_def = kh.GetClassDef();
+ const DexFile::ClassDef* dex_class_def = klass->GetClassDef();
CHECK(dex_class_def != NULL);
- const DexFile& dex_file = kh.GetDexFile();
+ const DexFile& dex_file = klass->GetDexFile();
StackHandleScope<2> hs(self);
Handle<mirror::ClassLoader> class_loader(hs.NewHandle(klass->GetClassLoader()));
- Handle<mirror::DexCache> dex_cache(hs.NewHandle(kh.GetDexCache()));
+ Handle<mirror::DexCache> dex_cache(hs.NewHandle(klass->GetDexCache()));
EncodedStaticFieldValueIterator it(dex_file, &dex_cache, &class_loader,
this, *dex_class_def);
if (it.HasNext()) {
@@ -3264,8 +3251,8 @@
// Set the class as initialized except if failed to initialize static fields.
klass->SetStatus(mirror::Class::kStatusInitialized, self);
if (VLOG_IS_ON(class_linker)) {
- ClassHelper kh(klass.Get());
- LOG(INFO) << "Initialized class " << kh.GetDescriptor() << " from " << kh.GetLocation();
+ LOG(INFO) << "Initialized class " << klass->GetDescriptor() << " from " <<
+ klass->GetLocation();
}
// Opportunistically set static method trampolines to their destination.
FixupStaticTrampolines(klass.Get());
@@ -3619,6 +3606,7 @@
bool ClassLinker::LinkInterfaceMethods(const Handle<mirror::Class>& klass,
const Handle<mirror::ObjectArray<mirror::Class> >& interfaces) {
+ Thread* const self = Thread::Current();
// Set the imt table to be all conflicts by default.
klass->SetImTable(Runtime::Current()->GetDefaultImt());
size_t super_ifcount;
@@ -3627,18 +3615,14 @@
} else {
super_ifcount = 0;
}
- size_t ifcount = super_ifcount;
- uint32_t num_interfaces;
- {
- ClassHelper kh(klass.Get());
- num_interfaces =
- interfaces.Get() == nullptr ? kh.NumDirectInterfaces() : interfaces->GetLength();
- ifcount += num_interfaces;
- for (size_t i = 0; i < num_interfaces; i++) {
- mirror::Class* interface =
- interfaces.Get() == nullptr ? kh.GetDirectInterface(i) : interfaces->Get(i);
- ifcount += interface->GetIfTableCount();
- }
+ uint32_t num_interfaces =
+ interfaces.Get() == nullptr ? klass->NumDirectInterfaces() : interfaces->GetLength();
+ size_t ifcount = super_ifcount + num_interfaces;
+ for (size_t i = 0; i < num_interfaces; i++) {
+ mirror::Class* interface =
+ interfaces.Get() == nullptr ? mirror::Class::GetDirectInterface(self, klass, i) :
+ interfaces->Get(i);
+ ifcount += interface->GetIfTableCount();
}
if (ifcount == 0) {
// Class implements no interfaces.
@@ -3662,7 +3646,6 @@
return true;
}
}
- Thread* self = Thread::Current();
StackHandleScope<2> hs(self);
Handle<mirror::IfTable> iftable(hs.NewHandle(AllocIfTable(self, ifcount)));
if (UNLIKELY(iftable.Get() == NULL)) {
@@ -3679,15 +3662,14 @@
// Flatten the interface inheritance hierarchy.
size_t idx = super_ifcount;
for (size_t i = 0; i < num_interfaces; i++) {
- ClassHelper kh(klass.Get());
mirror::Class* interface =
- interfaces.Get() == nullptr ? kh.GetDirectInterface(i) : interfaces->Get(i);
+ interfaces.Get() == nullptr ? mirror::Class::GetDirectInterface(self, klass, i) :
+ interfaces->Get(i);
DCHECK(interface != NULL);
if (!interface->IsInterface()) {
- ClassHelper ih(interface);
ThrowIncompatibleClassChangeError(klass.Get(), "Class %s implements non-interface class %s",
PrettyDescriptor(klass.Get()).c_str(),
- PrettyDescriptor(ih.GetDescriptor()).c_str());
+ PrettyDescriptor(interface->GetDescriptor()).c_str());
return false;
}
// Check if interface is already in iftable
@@ -4013,8 +3995,7 @@
}
// We lie to the GC about the java.lang.ref.Reference.referent field, so it doesn't scan it.
- if (!is_static &&
- (strcmp("Ljava/lang/ref/Reference;", ClassHelper(klass.Get()).GetDescriptor()) == 0)) {
+ if (!is_static && "Ljava/lang/ref/Reference;" == klass->GetDescriptor()) {
// We know there are no non-reference fields in the Reference classes, and we know
// that 'referent' is alphabetically last, so this is easy...
CHECK_EQ(num_reference_fields, num_fields);
@@ -4039,8 +4020,8 @@
FieldHelper fh(field);
Primitive::Type type = fh.GetTypeAsPrimitiveType();
bool is_primitive = type != Primitive::kPrimNot;
- if ((strcmp("Ljava/lang/ref/Reference;", ClassHelper(klass.Get()).GetDescriptor()) == 0)
- && (strcmp("referent", fh.GetName()) == 0)) {
+ if ("Ljava/lang/ref/Reference;" == klass->GetDescriptor() &&
+ strcmp("referent", fh.GetName()) == 0) {
is_primitive = true; // We lied above, so we have to expect a lie here.
}
if (is_primitive) {
@@ -4064,7 +4045,7 @@
} else {
klass->SetNumReferenceInstanceFields(num_reference_fields);
if (!klass->IsVariableSize()) {
- DCHECK_GE(size, sizeof(mirror::Object)) << ClassHelper(klass.Get()).GetDescriptor();
+ DCHECK_GE(size, sizeof(mirror::Object)) << klass->GetDescriptor();
size_t previous_size = klass->GetObjectSize();
if (previous_size != 0) {
// Make sure that we didn't originally have an incorrect size.
@@ -4340,14 +4321,17 @@
return resolved;
}
const DexFile::FieldId& field_id = dex_file.GetFieldId(field_idx);
- mirror::Class* klass = ResolveType(dex_file, field_id.class_idx_, dex_cache, class_loader);
- if (klass == NULL) {
+ Thread* const self = Thread::Current();
+ StackHandleScope<1> hs(self);
+ Handle<mirror::Class> klass(
+ hs.NewHandle(ResolveType(dex_file, field_id.class_idx_, dex_cache, class_loader)));
+ if (klass.Get() == NULL) {
DCHECK(Thread::Current()->IsExceptionPending());
return NULL;
}
if (is_static) {
- resolved = klass->FindStaticField(dex_cache.Get(), field_idx);
+ resolved = mirror::Class::FindStaticField(self, klass, dex_cache.Get(), field_idx);
} else {
resolved = klass->FindInstanceField(dex_cache.Get(), field_idx);
}
@@ -4356,12 +4340,12 @@
const char* name = dex_file.GetFieldName(field_id);
const char* type = dex_file.GetFieldTypeDescriptor(field_id);
if (is_static) {
- resolved = klass->FindStaticField(name, type);
+ resolved = mirror::Class::FindStaticField(self, klass, name, type);
} else {
resolved = klass->FindInstanceField(name, type);
}
if (resolved == NULL) {
- ThrowNoSuchFieldError(is_static ? "static " : "instance ", klass, type, name);
+ ThrowNoSuchFieldError(is_static ? "static " : "instance ", klass.Get(), type, name);
return NULL;
}
}
@@ -4379,8 +4363,11 @@
return resolved;
}
const DexFile::FieldId& field_id = dex_file.GetFieldId(field_idx);
- mirror::Class* klass = ResolveType(dex_file, field_id.class_idx_, dex_cache, class_loader);
- if (klass == NULL) {
+ Thread* self = Thread::Current();
+ StackHandleScope<1> hs(self);
+ Handle<mirror::Class> klass(
+ hs.NewHandle(ResolveType(dex_file, field_id.class_idx_, dex_cache, class_loader)));
+ if (klass.Get() == NULL) {
DCHECK(Thread::Current()->IsExceptionPending());
return NULL;
}
@@ -4388,11 +4375,11 @@
StringPiece name(dex_file.StringDataByIdx(field_id.name_idx_));
StringPiece type(dex_file.StringDataByIdx(
dex_file.GetTypeId(field_id.type_idx_).descriptor_idx_));
- resolved = klass->FindField(name, type);
+ resolved = mirror::Class::FindField(self, klass, name, type);
if (resolved != NULL) {
dex_cache->SetResolvedField(field_idx, resolved);
} else {
- ThrowNoSuchFieldError("", klass, type, name);
+ ThrowNoSuchFieldError("", klass.Get(), type, name);
}
return resolved;
}
diff --git a/runtime/class_linker_test.cc b/runtime/class_linker_test.cc
index 9970dd5..ff90f41 100644
--- a/runtime/class_linker_test.cc
+++ b/runtime/class_linker_test.cc
@@ -60,12 +60,11 @@
void AssertPrimitiveClass(const std::string& descriptor, mirror::Class* primitive)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- ClassHelper primitive_ch(primitive);
ASSERT_TRUE(primitive != NULL);
ASSERT_TRUE(primitive->GetClass() != NULL);
ASSERT_EQ(primitive->GetClass(), primitive->GetClass()->GetClass());
EXPECT_TRUE(primitive->GetClass()->GetSuperClass() != NULL);
- ASSERT_STREQ(descriptor.c_str(), primitive_ch.GetDescriptor());
+ ASSERT_STREQ(descriptor.c_str(), primitive->GetDescriptor().c_str());
EXPECT_TRUE(primitive->GetSuperClass() == NULL);
EXPECT_FALSE(primitive->HasSuperClass());
EXPECT_TRUE(primitive->GetClassLoader() == NULL);
@@ -87,7 +86,7 @@
EXPECT_EQ(0U, primitive->NumVirtualMethods());
EXPECT_EQ(0U, primitive->NumInstanceFields());
EXPECT_EQ(0U, primitive->NumStaticFields());
- EXPECT_EQ(0U, primitive_ch.NumDirectInterfaces());
+ EXPECT_EQ(0U, primitive->NumDirectInterfaces());
EXPECT_TRUE(primitive->GetVTable() == NULL);
EXPECT_EQ(0, primitive->GetIfTableCount());
EXPECT_TRUE(primitive->GetIfTable() == NULL);
@@ -103,8 +102,7 @@
Handle<mirror::ClassLoader> loader(hs.NewHandle(class_loader));
Handle<mirror::Class> array(
hs.NewHandle(class_linker_->FindClass(self, array_descriptor.c_str(), loader)));
- ClassHelper array_component_ch(array->GetComponentType());
- EXPECT_STREQ(component_type.c_str(), array_component_ch.GetDescriptor());
+ EXPECT_STREQ(component_type.c_str(), array->GetComponentType()->GetDescriptor().c_str());
EXPECT_EQ(class_loader, array->GetClassLoader());
EXPECT_EQ(kAccFinal | kAccAbstract, (array->GetAccessFlags() & (kAccFinal | kAccAbstract)));
AssertArrayClass(array_descriptor, array);
@@ -112,19 +110,17 @@
void AssertArrayClass(const std::string& array_descriptor, const Handle<mirror::Class>& array)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- ClassHelper kh(array.Get());
ASSERT_TRUE(array.Get() != NULL);
ASSERT_TRUE(array->GetClass() != NULL);
ASSERT_EQ(array->GetClass(), array->GetClass()->GetClass());
EXPECT_TRUE(array->GetClass()->GetSuperClass() != NULL);
- ASSERT_STREQ(array_descriptor.c_str(), kh.GetDescriptor());
+ ASSERT_STREQ(array_descriptor.c_str(), array->GetDescriptor().c_str());
EXPECT_TRUE(array->GetSuperClass() != NULL);
Thread* self = Thread::Current();
EXPECT_EQ(class_linker_->FindSystemClass(self, "Ljava/lang/Object;"), array->GetSuperClass());
EXPECT_TRUE(array->HasSuperClass());
ASSERT_TRUE(array->GetComponentType() != NULL);
- kh.ChangeClass(array->GetComponentType());
- ASSERT_TRUE(kh.GetDescriptor() != NULL);
+ ASSERT_TRUE(!array->GetComponentType()->GetDescriptor().empty());
EXPECT_EQ(mirror::Class::kStatusInitialized, array->GetStatus());
EXPECT_FALSE(array->IsErroneous());
EXPECT_TRUE(array->IsLoaded());
@@ -142,16 +138,15 @@
EXPECT_EQ(0U, array->NumVirtualMethods());
EXPECT_EQ(0U, array->NumInstanceFields());
EXPECT_EQ(0U, array->NumStaticFields());
- kh.ChangeClass(array.Get());
- EXPECT_EQ(2U, kh.NumDirectInterfaces());
+ EXPECT_EQ(2U, array->NumDirectInterfaces());
EXPECT_TRUE(array->GetVTable() != NULL);
EXPECT_EQ(2, array->GetIfTableCount());
ASSERT_TRUE(array->GetIfTable() != NULL);
- kh.ChangeClass(kh.GetDirectInterface(0));
- EXPECT_STREQ(kh.GetDescriptor(), "Ljava/lang/Cloneable;");
- kh.ChangeClass(array.Get());
- kh.ChangeClass(kh.GetDirectInterface(1));
- EXPECT_STREQ(kh.GetDescriptor(), "Ljava/io/Serializable;");
+ mirror::Class* direct_interface0 = mirror::Class::GetDirectInterface(self, array, 0);
+ EXPECT_TRUE(direct_interface0 != nullptr);
+ EXPECT_STREQ(direct_interface0->GetDescriptor().c_str(), "Ljava/lang/Cloneable;");
+ mirror::Class* direct_interface1 = mirror::Class::GetDirectInterface(self, array, 1);
+ EXPECT_STREQ(direct_interface1->GetDescriptor().c_str(), "Ljava/io/Serializable;");
EXPECT_EQ(class_linker_->FindArrayClass(self, array->GetComponentType()), array.Get());
}
@@ -185,8 +180,7 @@
void AssertClass(const std::string& descriptor, const Handle<mirror::Class>& klass)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- ClassHelper kh(klass.Get());
- EXPECT_STREQ(descriptor.c_str(), kh.GetDescriptor());
+ EXPECT_STREQ(descriptor.c_str(), klass->GetDescriptor().c_str());
if (descriptor == "Ljava/lang/Object;") {
EXPECT_FALSE(klass->HasSuperClass());
} else {
@@ -202,7 +196,8 @@
EXPECT_FALSE(klass->IsArrayClass());
EXPECT_TRUE(klass->GetComponentType() == NULL);
EXPECT_TRUE(klass->IsInSamePackage(klass.Get()));
- EXPECT_TRUE(mirror::Class::IsInSamePackage(kh.GetDescriptor(), kh.GetDescriptor()));
+ EXPECT_TRUE(mirror::Class::IsInSamePackage(klass->GetDescriptor().c_str(),
+ klass->GetDescriptor().c_str()));
if (klass->IsInterface()) {
EXPECT_TRUE(klass->IsAbstract());
if (klass->NumDirectMethods() == 1) {
@@ -311,7 +306,7 @@
Handle<mirror::Class> klass(
hs.NewHandle(class_linker_->FindSystemClass(self, descriptor.c_str())));
ASSERT_TRUE(klass.Get() != nullptr);
- EXPECT_STREQ(descriptor.c_str(), ClassHelper(klass.Get()).GetDescriptor());
+ EXPECT_STREQ(descriptor.c_str(), klass.Get()->GetDescriptor().c_str());
EXPECT_EQ(class_loader, klass->GetClassLoader());
if (klass->IsPrimitive()) {
AssertPrimitiveClass(descriptor, klass.Get());
@@ -706,12 +701,11 @@
TEST_F(ClassLinkerTest, FindClass) {
ScopedObjectAccess soa(Thread::Current());
mirror::Class* JavaLangObject = class_linker_->FindSystemClass(soa.Self(), "Ljava/lang/Object;");
- ClassHelper kh(JavaLangObject);
ASSERT_TRUE(JavaLangObject != NULL);
ASSERT_TRUE(JavaLangObject->GetClass() != NULL);
ASSERT_EQ(JavaLangObject->GetClass(), JavaLangObject->GetClass()->GetClass());
EXPECT_EQ(JavaLangObject, JavaLangObject->GetClass()->GetSuperClass());
- ASSERT_STREQ(kh.GetDescriptor(), "Ljava/lang/Object;");
+ ASSERT_STREQ(JavaLangObject->GetDescriptor().c_str(), "Ljava/lang/Object;");
EXPECT_TRUE(JavaLangObject->GetSuperClass() == NULL);
EXPECT_FALSE(JavaLangObject->HasSuperClass());
EXPECT_TRUE(JavaLangObject->GetClassLoader() == NULL);
@@ -748,19 +742,18 @@
}
EXPECT_EQ(0U, JavaLangObject->NumStaticFields());
- EXPECT_EQ(0U, kh.NumDirectInterfaces());
+ EXPECT_EQ(0U, JavaLangObject->NumDirectInterfaces());
StackHandleScope<1> hs(soa.Self());
Handle<mirror::ClassLoader> class_loader(
hs.NewHandle(soa.Decode<mirror::ClassLoader*>(LoadDex("MyClass"))));
AssertNonExistentClass("LMyClass;");
mirror::Class* MyClass = class_linker_->FindClass(soa.Self(), "LMyClass;", class_loader);
- kh.ChangeClass(MyClass);
ASSERT_TRUE(MyClass != NULL);
ASSERT_TRUE(MyClass->GetClass() != NULL);
ASSERT_EQ(MyClass->GetClass(), MyClass->GetClass()->GetClass());
EXPECT_EQ(JavaLangObject, MyClass->GetClass()->GetSuperClass());
- ASSERT_STREQ(kh.GetDescriptor(), "LMyClass;");
+ ASSERT_STREQ(MyClass->GetDescriptor().c_str(), "LMyClass;");
EXPECT_TRUE(MyClass->GetSuperClass() == JavaLangObject);
EXPECT_TRUE(MyClass->HasSuperClass());
EXPECT_EQ(class_loader.Get(), MyClass->GetClassLoader());
@@ -782,7 +775,7 @@
EXPECT_EQ(0U, MyClass->NumVirtualMethods());
EXPECT_EQ(0U, MyClass->NumInstanceFields());
EXPECT_EQ(0U, MyClass->NumStaticFields());
- EXPECT_EQ(0U, kh.NumDirectInterfaces());
+ EXPECT_EQ(0U, MyClass->NumDirectInterfaces());
EXPECT_EQ(JavaLangObject->GetClass()->GetClass(), MyClass->GetClass()->GetClass());
@@ -913,56 +906,57 @@
EXPECT_EQ(9U, statics->NumStaticFields());
- mirror::ArtField* s0 = statics->FindStaticField("s0", "Z");
+ mirror::ArtField* s0 = mirror::Class::FindStaticField(soa.Self(), statics, "s0", "Z");
FieldHelper fh(s0);
- EXPECT_STREQ(ClassHelper(s0->GetClass()).GetDescriptor(), "Ljava/lang/reflect/ArtField;");
+ EXPECT_STREQ(s0->GetClass()->GetDescriptor().c_str(), "Ljava/lang/reflect/ArtField;");
EXPECT_TRUE(fh.GetTypeAsPrimitiveType() == Primitive::kPrimBoolean);
EXPECT_EQ(true, s0->GetBoolean(statics.Get()));
s0->SetBoolean<false>(statics.Get(), false);
- mirror::ArtField* s1 = statics->FindStaticField("s1", "B");
+ mirror::ArtField* s1 = mirror::Class::FindStaticField(soa.Self(), statics, "s1", "B");
fh.ChangeField(s1);
EXPECT_TRUE(fh.GetTypeAsPrimitiveType() == Primitive::kPrimByte);
EXPECT_EQ(5, s1->GetByte(statics.Get()));
s1->SetByte<false>(statics.Get(), 6);
- mirror::ArtField* s2 = statics->FindStaticField("s2", "C");
+ mirror::ArtField* s2 = mirror::Class::FindStaticField(soa.Self(), statics, "s2", "C");
fh.ChangeField(s2);
EXPECT_TRUE(fh.GetTypeAsPrimitiveType() == Primitive::kPrimChar);
EXPECT_EQ('a', s2->GetChar(statics.Get()));
s2->SetChar<false>(statics.Get(), 'b');
- mirror::ArtField* s3 = statics->FindStaticField("s3", "S");
+ mirror::ArtField* s3 = mirror::Class::FindStaticField(soa.Self(), statics, "s3", "S");
fh.ChangeField(s3);
EXPECT_TRUE(fh.GetTypeAsPrimitiveType() == Primitive::kPrimShort);
EXPECT_EQ(-536, s3->GetShort(statics.Get()));
s3->SetShort<false>(statics.Get(), -535);
- mirror::ArtField* s4 = statics->FindStaticField("s4", "I");
+ mirror::ArtField* s4 = mirror::Class::FindStaticField(soa.Self(), statics, "s4", "I");
fh.ChangeField(s4);
EXPECT_TRUE(fh.GetTypeAsPrimitiveType() == Primitive::kPrimInt);
EXPECT_EQ(2000000000, s4->GetInt(statics.Get()));
s4->SetInt<false>(statics.Get(), 2000000001);
- mirror::ArtField* s5 = statics->FindStaticField("s5", "J");
+ mirror::ArtField* s5 = mirror::Class::FindStaticField(soa.Self(), statics, "s5", "J");
fh.ChangeField(s5);
EXPECT_TRUE(fh.GetTypeAsPrimitiveType() == Primitive::kPrimLong);
EXPECT_EQ(0x1234567890abcdefLL, s5->GetLong(statics.Get()));
s5->SetLong<false>(statics.Get(), INT64_C(0x34567890abcdef12));
- mirror::ArtField* s6 = statics->FindStaticField("s6", "F");
+ mirror::ArtField* s6 = mirror::Class::FindStaticField(soa.Self(), statics, "s6", "F");
fh.ChangeField(s6);
EXPECT_TRUE(fh.GetTypeAsPrimitiveType() == Primitive::kPrimFloat);
EXPECT_EQ(0.5, s6->GetFloat(statics.Get()));
s6->SetFloat<false>(statics.Get(), 0.75);
- mirror::ArtField* s7 = statics->FindStaticField("s7", "D");
+ mirror::ArtField* s7 = mirror::Class::FindStaticField(soa.Self(), statics, "s7", "D");
fh.ChangeField(s7);
EXPECT_TRUE(fh.GetTypeAsPrimitiveType() == Primitive::kPrimDouble);
EXPECT_EQ(16777217, s7->GetDouble(statics.Get()));
s7->SetDouble<false>(statics.Get(), 16777219);
- mirror::ArtField* s8 = statics->FindStaticField("s8", "Ljava/lang/String;");
+ mirror::ArtField* s8 = mirror::Class::FindStaticField(soa.Self(), statics, "s8",
+ "Ljava/lang/String;");
fh.ChangeField(s8);
EXPECT_TRUE(fh.GetTypeAsPrimitiveType() == Primitive::kPrimNot);
EXPECT_TRUE(s8->GetObject(statics.Get())->AsString()->Equals("android"));
@@ -984,19 +978,24 @@
TEST_F(ClassLinkerTest, Interfaces) {
ScopedObjectAccess soa(Thread::Current());
- StackHandleScope<1> hs(soa.Self());
+ StackHandleScope<6> hs(soa.Self());
Handle<mirror::ClassLoader> class_loader(
hs.NewHandle(soa.Decode<mirror::ClassLoader*>(LoadDex("Interfaces"))));
- mirror::Class* I = class_linker_->FindClass(soa.Self(), "LInterfaces$I;", class_loader);
- mirror::Class* J = class_linker_->FindClass(soa.Self(), "LInterfaces$J;", class_loader);
- mirror::Class* K = class_linker_->FindClass(soa.Self(), "LInterfaces$K;", class_loader);
- mirror::Class* A = class_linker_->FindClass(soa.Self(), "LInterfaces$A;", class_loader);
- mirror::Class* B = class_linker_->FindClass(soa.Self(), "LInterfaces$B;", class_loader);
- EXPECT_TRUE(I->IsAssignableFrom(A));
- EXPECT_TRUE(J->IsAssignableFrom(A));
- EXPECT_TRUE(J->IsAssignableFrom(K));
- EXPECT_TRUE(K->IsAssignableFrom(B));
- EXPECT_TRUE(J->IsAssignableFrom(B));
+ Handle<mirror::Class> I(
+ hs.NewHandle(class_linker_->FindClass(soa.Self(), "LInterfaces$I;", class_loader)));
+ Handle<mirror::Class> J(
+ hs.NewHandle(class_linker_->FindClass(soa.Self(), "LInterfaces$J;", class_loader)));
+ Handle<mirror::Class> K(
+ hs.NewHandle(class_linker_->FindClass(soa.Self(), "LInterfaces$K;", class_loader)));
+ Handle<mirror::Class> A(
+ hs.NewHandle(class_linker_->FindClass(soa.Self(), "LInterfaces$A;", class_loader)));
+ Handle<mirror::Class> B(
+ hs.NewHandle(class_linker_->FindClass(soa.Self(), "LInterfaces$B;", class_loader)));
+ EXPECT_TRUE(I->IsAssignableFrom(A.Get()));
+ EXPECT_TRUE(J->IsAssignableFrom(A.Get()));
+ EXPECT_TRUE(J->IsAssignableFrom(K.Get()));
+ EXPECT_TRUE(K->IsAssignableFrom(B.Get()));
+ EXPECT_TRUE(J->IsAssignableFrom(B.Get()));
const Signature void_sig = I->GetDexCache()->GetDexFile()->CreateSignature("()V");
mirror::ArtMethod* Ii = I->FindVirtualMethod("i", void_sig);
@@ -1029,10 +1028,14 @@
EXPECT_EQ(Aj1, A->FindVirtualMethodForVirtualOrInterface(Jj1));
EXPECT_EQ(Aj2, A->FindVirtualMethodForVirtualOrInterface(Jj2));
- mirror::ArtField* Afoo = A->FindStaticField("foo", "Ljava/lang/String;");
- mirror::ArtField* Bfoo = B->FindStaticField("foo", "Ljava/lang/String;");
- mirror::ArtField* Jfoo = J->FindStaticField("foo", "Ljava/lang/String;");
- mirror::ArtField* Kfoo = K->FindStaticField("foo", "Ljava/lang/String;");
+ mirror::ArtField* Afoo = mirror::Class::FindStaticField(soa.Self(), A, "foo",
+ "Ljava/lang/String;");
+ mirror::ArtField* Bfoo = mirror::Class::FindStaticField(soa.Self(), B, "foo",
+ "Ljava/lang/String;");
+ mirror::ArtField* Jfoo = mirror::Class::FindStaticField(soa.Self(), J, "foo",
+ "Ljava/lang/String;");
+ mirror::ArtField* Kfoo = mirror::Class::FindStaticField(soa.Self(), K, "foo",
+ "Ljava/lang/String;");
ASSERT_TRUE(Afoo != NULL);
EXPECT_EQ(Afoo, Bfoo);
EXPECT_EQ(Afoo, Jfoo);
@@ -1106,9 +1109,8 @@
ScopedObjectAccess soa(Thread::Current());
for (int i = 0; i < ClassLinker::kClassRootsMax; i++) {
mirror::Class* klass = class_linker_->GetClassRoot(ClassLinker::ClassRoot(i));
- ClassHelper kh(klass);
- EXPECT_TRUE(kh.GetDescriptor() != NULL);
- EXPECT_STREQ(kh.GetDescriptor(),
+ EXPECT_TRUE(!klass->GetDescriptor().empty());
+ EXPECT_STREQ(klass->GetDescriptor().c_str(),
class_linker_->GetClassRootDescriptor(ClassLinker::ClassRoot(i))) << " i = " << i;
}
}
diff --git a/runtime/common_throws.cc b/runtime/common_throws.cc
index 315f274..a3e3cfa 100644
--- a/runtime/common_throws.cc
+++ b/runtime/common_throws.cc
@@ -36,8 +36,7 @@
static void AddReferrerLocation(std::ostream& os, mirror::Class* referrer)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
if (referrer != NULL) {
- ClassHelper kh(referrer);
- std::string location(kh.GetLocation());
+ std::string location(referrer->GetLocation());
if (!location.empty()) {
os << " (declaration of '" << PrettyDescriptor(referrer)
<< "' appears in " << location << ")";
@@ -297,10 +296,9 @@
void ThrowNoSuchFieldError(const StringPiece& scope, mirror::Class* c,
const StringPiece& type, const StringPiece& name)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- ClassHelper kh(c);
std::ostringstream msg;
msg << "No " << scope << "field " << name << " of type " << type
- << " in class " << kh.GetDescriptor() << " or its superclasses";
+ << " in class " << c->GetDescriptor() << " or its superclasses";
ThrowException(NULL, "Ljava/lang/NoSuchFieldError;", c, msg.str().c_str());
}
@@ -309,9 +307,8 @@
void ThrowNoSuchMethodError(InvokeType type, mirror::Class* c, const StringPiece& name,
const Signature& signature) {
std::ostringstream msg;
- ClassHelper kh(c);
msg << "No " << type << " method " << name << signature
- << " in class " << kh.GetDescriptor() << " or its super classes";
+ << " in class " << c->GetDescriptor() << " or its super classes";
ThrowException(NULL, "Ljava/lang/NoSuchMethodError;", c, msg.str().c_str());
}
diff --git a/runtime/debugger.cc b/runtime/debugger.cc
index f6b4891..2cbff79 100644
--- a/runtime/debugger.cc
+++ b/runtime/debugger.cc
@@ -756,7 +756,7 @@
if (!o->IsClass()) {
return StringPrintf("non-class %p", o); // This is only used for debugging output anyway.
}
- return DescriptorToName(ClassHelper(o->AsClass()).GetDescriptor());
+ return DescriptorToName(o->AsClass()->GetDescriptor().c_str());
}
JDWP::JdwpError Dbg::GetClassObject(JDWP::RefTypeId id, JDWP::ObjectId& class_object_id) {
@@ -1088,7 +1088,7 @@
}
if (pDescriptor != NULL) {
- *pDescriptor = ClassHelper(c).GetDescriptor();
+ *pDescriptor = c->GetDescriptor();
}
return JDWP::ERR_NONE;
}
@@ -1124,7 +1124,7 @@
if (c == NULL) {
return status;
}
- *signature = ClassHelper(c).GetDescriptor();
+ *signature = c->GetDescriptor();
return JDWP::ERR_NONE;
}
@@ -1137,7 +1137,7 @@
if (c->IsProxyClass()) {
return JDWP::ERR_ABSENT_INFORMATION;
}
- result = ClassHelper(c).GetSourceFile();
+ result = c->GetSourceFile();
return JDWP::ERR_NONE;
}
@@ -1202,7 +1202,7 @@
LOG(WARNING) << __FUNCTION__ << " access out of bounds: offset=" << offset << "; count=" << count;
return JDWP::ERR_INVALID_LENGTH;
}
- std::string descriptor(ClassHelper(a->GetClass()).GetDescriptor());
+ std::string descriptor(a->GetClass()->GetDescriptor());
JDWP::JdwpTag tag = BasicTagFromDescriptor(descriptor.c_str() + 1);
expandBufAdd1(pReply, tag);
@@ -1264,9 +1264,8 @@
LOG(WARNING) << __FUNCTION__ << " access out of bounds: offset=" << offset << "; count=" << count;
return JDWP::ERR_INVALID_LENGTH;
}
- ClassHelper ch(dst->GetClass());
- const char* descriptor = ch.GetDescriptor();
- JDWP::JdwpTag tag = BasicTagFromDescriptor(descriptor + 1);
+ std::string descriptor = dst->GetClass()->GetDescriptor();
+ JDWP::JdwpTag tag = BasicTagFromDescriptor(descriptor.c_str() + 1);
if (IsPrimitiveTag(tag)) {
size_t width = GetTagWidth(tag);
@@ -1497,16 +1496,17 @@
JDWP::JdwpError Dbg::OutputDeclaredInterfaces(JDWP::RefTypeId class_id, JDWP::ExpandBuf* pReply) {
JDWP::JdwpError status;
- mirror::Class* c = DecodeClass(class_id, status);
- if (c == NULL) {
+ Thread* self = Thread::Current();
+ StackHandleScope<1> hs(self);
+ Handle<mirror::Class> c(hs.NewHandle(DecodeClass(class_id, status)));
+ if (c.Get() == nullptr) {
return status;
}
-
- ClassHelper kh(c);
- size_t interface_count = kh.NumDirectInterfaces();
+ size_t interface_count = c->NumDirectInterfaces();
expandBufAdd4BE(pReply, interface_count);
for (size_t i = 0; i < interface_count; ++i) {
- expandBufAddRefTypeId(pReply, gRegistry->AddRefType(kh.GetDirectInterface(i)));
+ expandBufAddRefTypeId(pReply,
+ gRegistry->AddRefType(mirror::Class::GetDirectInterface(self, c, i)));
}
return JDWP::ERR_NONE;
}
@@ -2592,8 +2592,7 @@
// since the class may not yet be verified.
int state = JDWP::CS_VERIFIED | JDWP::CS_PREPARED;
JDWP::JdwpTypeTag tag = GetTypeTag(c);
- gJdwpState->PostClassPrepare(tag, gRegistry->Add(c),
- ClassHelper(c).GetDescriptor(), state);
+ gJdwpState->PostClassPrepare(tag, gRegistry->Add(c), c->GetDescriptor(), state);
}
void Dbg::UpdateDebugger(Thread* thread, mirror::Object* this_object,
@@ -4357,7 +4356,7 @@
while (count--) {
AllocRecord* record = &recent_allocation_records_[idx];
- class_names.Add(ClassHelper(record->type).GetDescriptor());
+ class_names.Add(record->type->GetDescriptor().c_str());
MethodHelper mh;
for (size_t i = 0; i < kMaxAllocRecordStackDepth; i++) {
@@ -4411,8 +4410,8 @@
// (1b) stack depth
AllocRecord* record = &recent_allocation_records_[idx];
size_t stack_depth = record->GetDepth();
- ClassHelper kh(record->type);
- size_t allocated_object_class_name_index = class_names.IndexOf(kh.GetDescriptor());
+ size_t allocated_object_class_name_index =
+ class_names.IndexOf(record->type->GetDescriptor().c_str());
JDWP::Append4BE(bytes, record->byte_count);
JDWP::Append2BE(bytes, record->thin_lock_id);
JDWP::Append2BE(bytes, allocated_object_class_name_index);
diff --git a/runtime/gc/heap.cc b/runtime/gc/heap.cc
index b4c2d14..ef31be3 100644
--- a/runtime/gc/heap.cc
+++ b/runtime/gc/heap.cc
@@ -2765,7 +2765,7 @@
void Heap::CheckPreconditionsForAllocObject(mirror::Class* c, size_t byte_count) {
CHECK(c == NULL || (c->IsClassClass() && byte_count >= sizeof(mirror::Class)) ||
(c->IsVariableSize() || c->GetObjectSize() == byte_count) ||
- strlen(ClassHelper(c).GetDescriptor()) == 0);
+ c->GetDescriptor().empty());
CHECK_GE(byte_count, sizeof(mirror::Object));
}
diff --git a/runtime/interpreter/interpreter.cc b/runtime/interpreter/interpreter.cc
index 20e2b8d..478c74c 100644
--- a/runtime/interpreter/interpreter.cc
+++ b/runtime/interpreter/interpreter.cc
@@ -49,7 +49,8 @@
value.SetJ((static_cast<uint64_t>(args[1]) << 32) | args[0]);
result->SetD(log(value.GetD()));
} else if (name == "java.lang.String java.lang.Class.getNameNative()") {
- result->SetL(receiver->AsClass()->ComputeName());
+ StackHandleScope<1> hs(self);
+ result->SetL(mirror::Class::ComputeName(hs.NewHandle(receiver->AsClass())));
} else if (name == "int java.lang.Float.floatToRawIntBits(float)") {
result->SetI(args[0]);
} else if (name == "float java.lang.Float.intBitsToFloat(int)") {
diff --git a/runtime/interpreter/interpreter_common.cc b/runtime/interpreter/interpreter_common.cc
index c5fb0d8..418aff5 100644
--- a/runtime/interpreter/interpreter_common.cc
+++ b/runtime/interpreter/interpreter_common.cc
@@ -117,8 +117,8 @@
"Ljava/lang/VirtualMachineError;",
"Invoking %s with bad arg %d, type '%s' not instance of '%s'",
mh.GetName(), shorty_pos,
- ClassHelper(o->GetClass()).GetDescriptor(),
- ClassHelper(arg_type).GetDescriptor());
+ o->GetClass()->GetDescriptor().c_str(),
+ arg_type->GetDescriptor().c_str());
return false;
}
}
diff --git a/runtime/interpreter/interpreter_common.h b/runtime/interpreter/interpreter_common.h
index 9b03334..0c7c8a9 100644
--- a/runtime/interpreter/interpreter_common.h
+++ b/runtime/interpreter/interpreter_common.h
@@ -345,9 +345,9 @@
self->ThrowNewExceptionF(self->GetCurrentLocationForThrow(),
"Ljava/lang/VirtualMachineError;",
"Put '%s' that is not instance of field '%s' in '%s'",
- ClassHelper(reg->GetClass()).GetDescriptor(),
- ClassHelper(field_class).GetDescriptor(),
- ClassHelper(f->GetDeclaringClass()).GetDescriptor());
+ reg->GetClass()->GetDescriptor().c_str(),
+ field_class->GetDescriptor().c_str(),
+ f->GetDeclaringClass()->GetDescriptor().c_str());
return false;
}
}
diff --git a/runtime/interpreter/interpreter_goto_table_impl.cc b/runtime/interpreter/interpreter_goto_table_impl.cc
index 5b7dee1d..e0f9e5f 100644
--- a/runtime/interpreter/interpreter_goto_table_impl.cc
+++ b/runtime/interpreter/interpreter_goto_table_impl.cc
@@ -342,8 +342,8 @@
self->ThrowNewExceptionF(self->GetCurrentLocationForThrow(),
"Ljava/lang/VirtualMachineError;",
"Returning '%s' that is not instance of return type '%s'",
- ClassHelper(obj_result->GetClass()).GetDescriptor(),
- ClassHelper(return_type).GetDescriptor());
+ obj_result->GetClass()->GetDescriptor().c_str(),
+ return_type->GetDescriptor().c_str());
HANDLE_PENDING_EXCEPTION();
}
}
@@ -614,7 +614,7 @@
self->ThrowNewExceptionF(self->GetCurrentLocationForThrow(),
"Ljava/lang/VirtualMachineError;",
"Throwing '%s' that is not instance of Throwable",
- ClassHelper(exception->GetClass()).GetDescriptor());
+ exception->GetClass()->GetDescriptor().c_str());
} else {
self->SetException(shadow_frame.GetCurrentLocationForThrow(), exception->AsThrowable());
}
diff --git a/runtime/interpreter/interpreter_switch_impl.cc b/runtime/interpreter/interpreter_switch_impl.cc
index 859cfc4..c1d24f5 100644
--- a/runtime/interpreter/interpreter_switch_impl.cc
+++ b/runtime/interpreter/interpreter_switch_impl.cc
@@ -258,8 +258,8 @@
self->ThrowNewExceptionF(self->GetCurrentLocationForThrow(),
"Ljava/lang/VirtualMachineError;",
"Returning '%s' that is not instance of return type '%s'",
- ClassHelper(obj_result->GetClass()).GetDescriptor(),
- ClassHelper(return_type).GetDescriptor());
+ obj_result->GetClass()->GetDescriptor().c_str(),
+ return_type->GetDescriptor().c_str());
HANDLE_PENDING_EXCEPTION();
}
}
@@ -528,7 +528,7 @@
self->ThrowNewExceptionF(self->GetCurrentLocationForThrow(),
"Ljava/lang/VirtualMachineError;",
"Throwing '%s' that is not instance of Throwable",
- ClassHelper(exception->GetClass()).GetDescriptor());
+ exception->GetClass()->GetDescriptor().c_str());
} else {
self->SetException(shadow_frame.GetCurrentLocationForThrow(), exception->AsThrowable());
}
diff --git a/runtime/jni_internal.cc b/runtime/jni_internal.cc
index 3afb149..17a3de4 100644
--- a/runtime/jni_internal.cc
+++ b/runtime/jni_internal.cc
@@ -109,7 +109,7 @@
ThrowLocation throw_location = soa.Self()->GetCurrentLocationForThrow();
soa.Self()->ThrowNewExceptionF(throw_location, "Ljava/lang/NoSuchMethodError;",
"no %s method \"%s.%s%s\"",
- kind, ClassHelper(c).GetDescriptor(), name, sig);
+ kind, c->GetDescriptor().c_str(), name, sig);
}
static mirror::Class* EnsureInitialized(Thread* self, mirror::Class* klass)
@@ -206,20 +206,21 @@
soa.Self()->ThrowNewExceptionF(throw_location, "Ljava/lang/NoSuchFieldError;",
"no type \"%s\" found and so no field \"%s\" "
"could be found in class \"%s\" or its superclasses", sig, name,
- ClassHelper(c.Get()).GetDescriptor());
+ c->GetDescriptor().c_str());
soa.Self()->GetException(nullptr)->SetCause(cause.Get());
return nullptr;
}
if (is_static) {
- field = c->FindStaticField(name, ClassHelper(field_type).GetDescriptor());
+ field = mirror::Class::FindStaticField(soa.Self(), c, name,
+ field_type->GetDescriptor().c_str());
} else {
- field = c->FindInstanceField(name, ClassHelper(field_type).GetDescriptor());
+ field = c->FindInstanceField(name, field_type->GetDescriptor().c_str());
}
if (field == nullptr) {
ThrowLocation throw_location = soa.Self()->GetCurrentLocationForThrow();
soa.Self()->ThrowNewExceptionF(throw_location, "Ljava/lang/NoSuchFieldError;",
"no \"%s\" field \"%s\" in class \"%s\" or its superclasses",
- sig, name, ClassHelper(c.Get()).GetDescriptor());
+ sig, name, c->GetDescriptor().c_str());
return nullptr;
}
return soa.EncodeField(field);
diff --git a/runtime/mirror/class-inl.h b/runtime/mirror/class-inl.h
index d454ae8..b2d8288 100644
--- a/runtime/mirror/class-inl.h
+++ b/runtime/mirror/class-inl.h
@@ -21,9 +21,11 @@
#include "art_field.h"
#include "art_method.h"
+#include "class_linker-inl.h"
#include "class_loader.h"
#include "common_throws.h"
#include "dex_cache.h"
+#include "dex_file.h"
#include "gc/heap-inl.h"
#include "iftable.h"
#include "object_array-inl.h"
@@ -508,7 +510,7 @@
}
template<ReadBarrierOption kReadBarrierOption>
-bool Class::IsArtFieldClass() {
+inline bool Class::IsArtFieldClass() {
Class* java_lang_Class = GetClass<kVerifyNone, kReadBarrierOption>();
Class* java_lang_reflect_ArtField =
java_lang_Class->GetInstanceField(0)->GetClass<kVerifyNone, kReadBarrierOption>();
@@ -516,7 +518,7 @@
}
template<ReadBarrierOption kReadBarrierOption>
-bool Class::IsArtMethodClass() {
+inline bool Class::IsArtMethodClass() {
return this == ArtMethod::GetJavaLangReflectArtMethod<kReadBarrierOption>();
}
@@ -527,6 +529,24 @@
return this == java_lang_Class;
}
+inline const DexFile& Class::GetDexFile() {
+ return *GetDexCache()->GetDexFile();
+}
+
+inline bool Class::DescriptorEquals(const char* match) {
+ if (UNLIKELY(IsArrayClass())) {
+ return match[0] == '[' && GetComponentType()->DescriptorEquals(match + 1);
+ } else if (UNLIKELY(IsPrimitive())) {
+ return strcmp(Primitive::Descriptor(GetPrimitiveType()), match) == 0;
+ } else if (UNLIKELY(IsProxyClass())) {
+ return Runtime::Current()->GetClassLinker()->GetDescriptorForProxy(this) == match;
+ } else {
+ const DexFile& dex_file = GetDexFile();
+ const DexFile::TypeId& type_id = dex_file.GetTypeId(GetClassDef()->class_idx_);
+ return strcmp(dex_file.GetTypeDescriptor(type_id), match) == 0;
+ }
+}
+
} // namespace mirror
} // namespace art
diff --git a/runtime/mirror/class.cc b/runtime/mirror/class.cc
index 15b69f3..4869b45 100644
--- a/runtime/mirror/class.cc
+++ b/runtime/mirror/class.cc
@@ -136,15 +136,13 @@
// Class.getName: keywords for primitive types, regular "[I" form for primitive arrays (so "int"
// but "[I"), and arrays of reference types written between "L" and ";" but with dots rather than
// slashes (so "java.lang.String" but "[Ljava.lang.String;"). Madness.
-String* Class::ComputeName() {
- String* name = GetName();
+String* Class::ComputeName(Handle<Class> h_this) {
+ String* name = h_this->GetName();
if (name != nullptr) {
return name;
}
+ std::string descriptor(h_this->GetDescriptor());
Thread* self = Thread::Current();
- StackHandleScope<1> hs(self);
- Handle<mirror::Class> handle_c(hs.NewHandle(this));
- std::string descriptor(ClassHelper(this).GetDescriptor());
if ((descriptor[0] != 'L') && (descriptor[0] != '[')) {
// The descriptor indicates that this is the class for
// a primitive type; special-case the return value.
@@ -173,7 +171,7 @@
std::replace(descriptor.begin(), descriptor.end(), '/', '.');
name = String::AllocFromModifiedUtf8(self, descriptor.c_str());
}
- handle_c->SetName(name);
+ h_this->SetName(name);
return name;
}
@@ -190,52 +188,59 @@
return;
}
- Class* super = GetSuperClass();
- ClassHelper kh(this);
+ Thread* self = Thread::Current();
+ StackHandleScope<2> hs(self);
+ Handle<mirror::Class> h_this(hs.NewHandle(this));
+ Handle<mirror::Class> h_super(hs.NewHandle(GetSuperClass()));
+
os << "----- " << (IsInterface() ? "interface" : "class") << " "
- << "'" << kh.GetDescriptor() << "' cl=" << GetClassLoader() << " -----\n",
+ << "'" << GetDescriptor() << "' cl=" << GetClassLoader() << " -----\n",
os << " objectSize=" << SizeOf() << " "
- << "(" << (super != NULL ? super->SizeOf() : -1) << " from super)\n",
+ << "(" << (h_super.Get() != NULL ? h_super->SizeOf() : -1) << " from super)\n",
os << StringPrintf(" access=0x%04x.%04x\n",
GetAccessFlags() >> 16, GetAccessFlags() & kAccJavaFlagsMask);
- if (super != NULL) {
- os << " super='" << PrettyClass(super) << "' (cl=" << super->GetClassLoader() << ")\n";
+ if (h_super.Get() != NULL) {
+ os << " super='" << PrettyClass(h_super.Get()) << "' (cl=" << h_super->GetClassLoader()
+ << ")\n";
}
if (IsArrayClass()) {
os << " componentType=" << PrettyClass(GetComponentType()) << "\n";
}
- if (kh.NumDirectInterfaces() > 0) {
- os << " interfaces (" << kh.NumDirectInterfaces() << "):\n";
- for (size_t i = 0; i < kh.NumDirectInterfaces(); ++i) {
- Class* interface = kh.GetDirectInterface(i);
+ const size_t num_direct_interfaces = NumDirectInterfaces();
+ if (num_direct_interfaces > 0) {
+ os << " interfaces (" << num_direct_interfaces << "):\n";
+ for (size_t i = 0; i < num_direct_interfaces; ++i) {
+ Class* interface = GetDirectInterface(self, h_this, i);
const ClassLoader* cl = interface->GetClassLoader();
os << StringPrintf(" %2zd: %s (cl=%p)\n", i, PrettyClass(interface).c_str(), cl);
}
}
- os << " vtable (" << NumVirtualMethods() << " entries, "
- << (super != NULL ? super->NumVirtualMethods() : 0) << " in super):\n";
+ // After this point, this may have moved due to GetDirectInterface.
+ os << " vtable (" << h_this->NumVirtualMethods() << " entries, "
+ << (h_super.Get() != NULL ? h_super->NumVirtualMethods() : 0) << " in super):\n";
for (size_t i = 0; i < NumVirtualMethods(); ++i) {
- os << StringPrintf(" %2zd: %s\n", i, PrettyMethod(GetVirtualMethodDuringLinking(i)).c_str());
+ os << StringPrintf(" %2zd: %s\n", i,
+ PrettyMethod(h_this->GetVirtualMethodDuringLinking(i)).c_str());
}
- os << " direct methods (" << NumDirectMethods() << " entries):\n";
- for (size_t i = 0; i < NumDirectMethods(); ++i) {
- os << StringPrintf(" %2zd: %s\n", i, PrettyMethod(GetDirectMethod(i)).c_str());
+ os << " direct methods (" << h_this->NumDirectMethods() << " entries):\n";
+ for (size_t i = 0; i < h_this->NumDirectMethods(); ++i) {
+ os << StringPrintf(" %2zd: %s\n", i, PrettyMethod(h_this->GetDirectMethod(i)).c_str());
}
- if (NumStaticFields() > 0) {
- os << " static fields (" << NumStaticFields() << " entries):\n";
- if (IsResolved() || IsErroneous()) {
- for (size_t i = 0; i < NumStaticFields(); ++i) {
- os << StringPrintf(" %2zd: %s\n", i, PrettyField(GetStaticField(i)).c_str());
+ if (h_this->NumStaticFields() > 0) {
+ os << " static fields (" << h_this->NumStaticFields() << " entries):\n";
+ if (h_this->IsResolved() || h_this->IsErroneous()) {
+ for (size_t i = 0; i < h_this->NumStaticFields(); ++i) {
+ os << StringPrintf(" %2zd: %s\n", i, PrettyField(h_this->GetStaticField(i)).c_str());
}
} else {
os << " <not yet available>";
}
}
- if (NumInstanceFields() > 0) {
- os << " instance fields (" << NumInstanceFields() << " entries):\n";
- if (IsResolved() || IsErroneous()) {
- for (size_t i = 0; i < NumInstanceFields(); ++i) {
- os << StringPrintf(" %2zd: %s\n", i, PrettyField(GetInstanceField(i)).c_str());
+ if (h_this->NumInstanceFields() > 0) {
+ os << " instance fields (" << h_this->NumInstanceFields() << " entries):\n";
+ if (h_this->IsResolved() || h_this->IsErroneous()) {
+ for (size_t i = 0; i < h_this->NumInstanceFields(); ++i) {
+ os << StringPrintf(" %2zd: %s\n", i, PrettyField(h_this->GetInstanceField(i)).c_str());
}
} else {
os << " <not yet available>";
@@ -305,8 +310,7 @@
return true;
}
// Compare the package part of the descriptor string.
- return IsInSamePackage(ClassHelper(klass1).GetDescriptor(),
- ClassHelper(klass2).GetDescriptor());
+ return IsInSamePackage(klass1->GetDescriptor().c_str(), klass2->GetDescriptor().c_str());
}
bool Class::IsStringClass() const {
@@ -585,71 +589,82 @@
return NULL;
}
-ArtField* Class::FindStaticField(const StringPiece& name, const StringPiece& type) {
+ArtField* Class::FindStaticField(Thread* self, Handle<Class> klass, const StringPiece& name,
+ const StringPiece& type) {
// Is the field in this class (or its interfaces), or any of its
// superclasses (or their interfaces)?
- for (Class* k = this; k != NULL; k = k->GetSuperClass()) {
+ for (Class* k = klass.Get(); k != nullptr; k = k->GetSuperClass()) {
// Is the field in this class?
ArtField* f = k->FindDeclaredStaticField(name, type);
- if (f != NULL) {
+ if (f != nullptr) {
return f;
}
+ // Wrap k incase it moves during GetDirectInterface.
+ StackHandleScope<1> hs(self);
+ HandleWrapper<mirror::Class> h_k(hs.NewHandleWrapper(&k));
// Is this field in any of this class' interfaces?
- ClassHelper kh(k);
- for (uint32_t i = 0; i < kh.NumDirectInterfaces(); ++i) {
- Class* interface = kh.GetDirectInterface(i);
- f = interface->FindStaticField(name, type);
- if (f != NULL) {
+ for (uint32_t i = 0; i < h_k->NumDirectInterfaces(); ++i) {
+ StackHandleScope<1> hs(self);
+ Handle<mirror::Class> interface(hs.NewHandle(GetDirectInterface(self, h_k, i)));
+ f = FindStaticField(self, interface, name, type);
+ if (f != nullptr) {
return f;
}
}
}
- return NULL;
+ return nullptr;
}
-ArtField* Class::FindStaticField(const DexCache* dex_cache, uint32_t dex_field_idx) {
- for (Class* k = this; k != NULL; k = k->GetSuperClass()) {
+ArtField* Class::FindStaticField(Thread* self, Handle<Class> klass, const DexCache* dex_cache,
+ uint32_t dex_field_idx) {
+ for (Class* k = klass.Get(); k != nullptr; k = k->GetSuperClass()) {
// Is the field in this class?
ArtField* f = k->FindDeclaredStaticField(dex_cache, dex_field_idx);
if (f != NULL) {
return f;
}
+ // Wrap k incase it moves during GetDirectInterface.
+ StackHandleScope<1> hs(self);
+ HandleWrapper<mirror::Class> h_k(hs.NewHandleWrapper(&k));
// Is this field in any of this class' interfaces?
- ClassHelper kh(k);
- for (uint32_t i = 0; i < kh.NumDirectInterfaces(); ++i) {
- Class* interface = kh.GetDirectInterface(i);
- f = interface->FindStaticField(dex_cache, dex_field_idx);
- if (f != NULL) {
+ for (uint32_t i = 0; i < h_k->NumDirectInterfaces(); ++i) {
+ StackHandleScope<1> hs(self);
+ Handle<mirror::Class> interface(hs.NewHandle(GetDirectInterface(self, h_k, i)));
+ f = FindStaticField(self, interface, dex_cache, dex_field_idx);
+ if (f != nullptr) {
return f;
}
}
}
- return NULL;
+ return nullptr;
}
-ArtField* Class::FindField(const StringPiece& name, const StringPiece& type) {
+ArtField* Class::FindField(Thread* self, Handle<Class> klass, const StringPiece& name,
+ const StringPiece& type) {
// Find a field using the JLS field resolution order
- for (Class* k = this; k != NULL; k = k->GetSuperClass()) {
+ for (Class* k = klass.Get(); k != NULL; k = k->GetSuperClass()) {
// Is the field in this class?
ArtField* f = k->FindDeclaredInstanceField(name, type);
- if (f != NULL) {
+ if (f != nullptr) {
return f;
}
f = k->FindDeclaredStaticField(name, type);
- if (f != NULL) {
+ if (f != nullptr) {
return f;
}
// Is this field in any of this class' interfaces?
- ClassHelper kh(k);
- for (uint32_t i = 0; i < kh.NumDirectInterfaces(); ++i) {
- Class* interface = kh.GetDirectInterface(i);
- f = interface->FindStaticField(name, type);
- if (f != NULL) {
+ StackHandleScope<1> hs(self);
+ HandleWrapper<mirror::Class> h_k(hs.NewHandleWrapper(&k));
+ for (uint32_t i = 0; i < h_k->NumDirectInterfaces(); ++i) {
+ StackHandleScope<1> hs(self);
+ Handle<mirror::Class> interface(hs.NewHandle(GetDirectInterface(self, h_k, i)));
+ f = interface->FindStaticField(self, interface, name, type);
+ if (f != nullptr) {
return f;
}
}
}
- return NULL;
+ return nullptr;
}
static void SetPreverifiedFlagOnMethods(mirror::ObjectArray<mirror::ArtMethod>* methods)
@@ -671,5 +686,111 @@
SetPreverifiedFlagOnMethods(GetVirtualMethods());
}
+std::string Class::GetDescriptor() {
+ if (UNLIKELY(IsArrayClass())) {
+ return GetArrayDescriptor();
+ } else if (UNLIKELY(IsPrimitive())) {
+ return Primitive::Descriptor(GetPrimitiveType());
+ } else if (UNLIKELY(IsProxyClass())) {
+ return Runtime::Current()->GetClassLinker()->GetDescriptorForProxy(this);
+ } else {
+ const DexFile& dex_file = GetDexFile();
+ const DexFile::TypeId& type_id = dex_file.GetTypeId(GetClassDef()->class_idx_);
+ return dex_file.GetTypeDescriptor(type_id);
+ }
+}
+
+std::string Class::GetArrayDescriptor() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+ return "[" + GetComponentType()->GetDescriptor();
+}
+
+const DexFile::ClassDef* Class::GetClassDef() {
+ uint16_t class_def_idx = GetDexClassDefIndex();
+ if (class_def_idx == DexFile::kDexNoIndex16) {
+ return nullptr;
+ }
+ return &GetDexFile().GetClassDef(class_def_idx);
+}
+
+uint32_t Class::NumDirectInterfaces() {
+ if (IsPrimitive()) {
+ return 0;
+ } else if (IsArrayClass()) {
+ return 2;
+ } else if (IsProxyClass()) {
+ mirror::SynthesizedProxyClass* proxy_class=
+ reinterpret_cast<mirror::SynthesizedProxyClass*>(this);
+ mirror::ObjectArray<mirror::Class>* interfaces = proxy_class->GetInterfaces();
+ return interfaces != nullptr ? interfaces->GetLength() : 0;
+ } else {
+ const DexFile::TypeList* interfaces = GetInterfaceTypeList();
+ if (interfaces == nullptr) {
+ return 0;
+ } else {
+ return interfaces->Size();
+ }
+ }
+}
+
+uint16_t Class::GetDirectInterfaceTypeIdx(uint32_t idx) {
+ DCHECK(!IsPrimitive());
+ DCHECK(!IsArrayClass());
+ return GetInterfaceTypeList()->GetTypeItem(idx).type_idx_;
+}
+
+mirror::Class* Class::GetDirectInterface(Thread* self, Handle<mirror::Class> klass, uint32_t idx) {
+ DCHECK(klass.Get() != nullptr);
+ DCHECK(!klass->IsPrimitive());
+ if (klass->IsArrayClass()) {
+ ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
+ if (idx == 0) {
+ return class_linker->FindSystemClass(self, "Ljava/lang/Cloneable;");
+ } else {
+ DCHECK_EQ(1U, idx);
+ return class_linker->FindSystemClass(self, "Ljava/io/Serializable;");
+ }
+ } else if (klass->IsProxyClass()) {
+ mirror::SynthesizedProxyClass* proxy_class =
+ reinterpret_cast<mirror::SynthesizedProxyClass*>(klass.Get());
+ mirror::ObjectArray<mirror::Class>* interfaces = proxy_class->GetInterfaces();
+ DCHECK(interfaces != nullptr);
+ return interfaces->Get(idx);
+ } else {
+ uint16_t type_idx = klass->GetDirectInterfaceTypeIdx(idx);
+ mirror::Class* interface = klass->GetDexCache()->GetResolvedType(type_idx);
+ if (interface == nullptr) {
+ interface = Runtime::Current()->GetClassLinker()->ResolveType(klass->GetDexFile(), type_idx,
+ klass.Get());
+ CHECK(interface != nullptr || self->IsExceptionPending());
+ }
+ return interface;
+ }
+}
+
+const char* Class::GetSourceFile() {
+ std::string descriptor(GetDescriptor());
+ const DexFile& dex_file = GetDexFile();
+ const DexFile::ClassDef* dex_class_def = GetClassDef();
+ CHECK(dex_class_def != nullptr) << "No class def for class " << PrettyClass(this);
+ return dex_file.GetSourceFile(*dex_class_def);
+}
+
+std::string Class::GetLocation() {
+ mirror::DexCache* dex_cache = GetDexCache();
+ if (dex_cache != nullptr && !IsProxyClass()) {
+ return dex_cache->GetLocation()->ToModifiedUtf8();
+ }
+ // Arrays and proxies are generated and have no corresponding dex file location.
+ return "generated class";
+}
+
+const DexFile::TypeList* Class::GetInterfaceTypeList() {
+ const DexFile::ClassDef* class_def = GetClassDef();
+ if (class_def == nullptr) {
+ return nullptr;
+ }
+ return GetDexFile().GetInterfacesList(*class_def);
+}
+
} // namespace mirror
} // namespace art
diff --git a/runtime/mirror/class.h b/runtime/mirror/class.h
index 92b999e..a283f60 100644
--- a/runtime/mirror/class.h
+++ b/runtime/mirror/class.h
@@ -17,6 +17,7 @@
#ifndef ART_RUNTIME_MIRROR_CLASS_H_
#define ART_RUNTIME_MIRROR_CLASS_H_
+#include "dex_file.h"
#include "gc/allocator_type.h"
#include "invoke_type.h"
#include "modifiers.h"
@@ -274,7 +275,7 @@
String* GetName() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); // Returns the cached name.
void SetName(String* name) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); // Sets the cached name.
// Computes the name, then sets the cached value.
- String* ComputeName() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ static String* ComputeName(Handle<Class> h_this) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
bool IsProxyClass() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
@@ -776,7 +777,8 @@
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
// Find a static or instance field using the JLS resolution order
- ArtField* FindField(const StringPiece& name, const StringPiece& type)
+ static ArtField* FindField(Thread* self, Handle<Class> klass, const StringPiece& name,
+ const StringPiece& type)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
// Finds the given instance field in this class or a superclass.
@@ -795,12 +797,14 @@
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
// Finds the given static field in this class or a superclass.
- ArtField* FindStaticField(const StringPiece& name, const StringPiece& type)
+ static ArtField* FindStaticField(Thread* self, Handle<Class> klass, const StringPiece& name,
+ const StringPiece& type)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
// Finds the given static field in this class or superclass, only searches classes that
// have the same dex cache.
- ArtField* FindStaticField(const DexCache* dex_cache, uint32_t dex_field_idx)
+ static ArtField* FindStaticField(Thread* self, Handle<Class> klass, const DexCache* dex_cache,
+ uint32_t dex_field_idx)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
ArtField* FindDeclaredStaticField(const StringPiece& name, const StringPiece& type)
@@ -857,6 +861,19 @@
void VisitReferences(mirror::Class* klass, const Visitor& visitor)
NO_THREAD_SAFETY_ANALYSIS;
+ std::string GetDescriptor() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ bool DescriptorEquals(const char* match) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ std::string GetArrayDescriptor() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ const DexFile::ClassDef* GetClassDef() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ uint32_t NumDirectInterfaces() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ uint16_t GetDirectInterfaceTypeIdx(uint32_t idx) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ static mirror::Class* GetDirectInterface(Thread* self, Handle<mirror::Class> klass, uint32_t idx)
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ const char* GetSourceFile() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ std::string GetLocation() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ const DexFile& GetDexFile() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ const DexFile::TypeList* GetInterfaceTypeList() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
private:
void SetVerifyErrorClass(Class* klass) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
diff --git a/runtime/mirror/object_test.cc b/runtime/mirror/object_test.cc
index e0fd6a2..e24602a 100644
--- a/runtime/mirror/object_test.cc
+++ b/runtime/mirror/object_test.cc
@@ -104,7 +104,7 @@
TEST_F(ObjectTest, Clone) {
ScopedObjectAccess soa(Thread::Current());
- StackHandleScope<1> hs(soa.Self());
+ StackHandleScope<2> hs(soa.Self());
Handle<ObjectArray<Object>> a1(
hs.NewHandle(class_linker_->AllocObjectArray<Object>(soa.Self(), 256)));
size_t s1 = a1->SizeOf();
@@ -115,7 +115,7 @@
TEST_F(ObjectTest, AllocObjectArray) {
ScopedObjectAccess soa(Thread::Current());
- StackHandleScope<1> hs(soa.Self());
+ StackHandleScope<2> hs(soa.Self());
Handle<ObjectArray<Object> > oa(
hs.NewHandle(class_linker_->AllocObjectArray<Object>(soa.Self(), 2)));
EXPECT_EQ(2, oa->GetLength());
@@ -142,12 +142,12 @@
soa.Self()->ClearException();
ASSERT_TRUE(oa->GetClass() != NULL);
- ClassHelper oa_ch(oa->GetClass());
- ASSERT_EQ(2U, oa_ch.NumDirectInterfaces());
+ Handle<mirror::Class> klass(hs.NewHandle(oa->GetClass()));
+ ASSERT_EQ(2U, klass->NumDirectInterfaces());
EXPECT_EQ(class_linker_->FindSystemClass(soa.Self(), "Ljava/lang/Cloneable;"),
- oa_ch.GetDirectInterface(0));
+ mirror::Class::GetDirectInterface(soa.Self(), klass, 0));
EXPECT_EQ(class_linker_->FindSystemClass(soa.Self(), "Ljava/io/Serializable;"),
- oa_ch.GetDirectInterface(1));
+ mirror::Class::GetDirectInterface(soa.Self(), klass, 1));
}
TEST_F(ObjectTest, AllocArray) {
@@ -682,26 +682,31 @@
TEST_F(ObjectTest, FindStaticField) {
ScopedObjectAccess soa(Thread::Current());
- StackHandleScope<1> hs(soa.Self());
+ StackHandleScope<4> hs(soa.Self());
Handle<String> s(hs.NewHandle(String::AllocFromModifiedUtf8(soa.Self(), "ABC")));
ASSERT_TRUE(s.Get() != NULL);
- Class* c = s->GetClass();
- ASSERT_TRUE(c != NULL);
+ Handle<Class> c(hs.NewHandle(s->GetClass()));
+ ASSERT_TRUE(c.Get() != NULL);
// Wrong type.
EXPECT_TRUE(c->FindDeclaredStaticField("CASE_INSENSITIVE_ORDER", "I") == NULL);
- EXPECT_TRUE(c->FindStaticField("CASE_INSENSITIVE_ORDER", "I") == NULL);
+ EXPECT_TRUE(mirror::Class::FindStaticField(soa.Self(), c, "CASE_INSENSITIVE_ORDER", "I") == NULL);
// Wrong name.
EXPECT_TRUE(c->FindDeclaredStaticField("cASE_INSENSITIVE_ORDER", "Ljava/util/Comparator;") == NULL);
- EXPECT_TRUE(c->FindStaticField("cASE_INSENSITIVE_ORDER", "Ljava/util/Comparator;") == NULL);
+ EXPECT_TRUE(
+ mirror::Class::FindStaticField(soa.Self(), c, "cASE_INSENSITIVE_ORDER",
+ "Ljava/util/Comparator;") == NULL);
// Right name and type.
- ArtField* f1 = c->FindDeclaredStaticField("CASE_INSENSITIVE_ORDER", "Ljava/util/Comparator;");
- ArtField* f2 = c->FindStaticField("CASE_INSENSITIVE_ORDER", "Ljava/util/Comparator;");
- EXPECT_TRUE(f1 != NULL);
- EXPECT_TRUE(f2 != NULL);
- EXPECT_EQ(f1, f2);
+ Handle<ArtField> f1(hs.NewHandle(
+ c->FindDeclaredStaticField("CASE_INSENSITIVE_ORDER", "Ljava/util/Comparator;")));
+ Handle<ArtField> f2(hs.NewHandle(
+ mirror::Class::FindStaticField(soa.Self(), c, "CASE_INSENSITIVE_ORDER",
+ "Ljava/util/Comparator;")));
+ EXPECT_TRUE(f1.Get() != NULL);
+ EXPECT_TRUE(f2.Get() != NULL);
+ EXPECT_EQ(f1.Get(), f2.Get());
// TODO: test static fields via superclasses.
// TODO: test static fields via interfaces.
diff --git a/runtime/native/dalvik_system_VMRuntime.cc b/runtime/native/dalvik_system_VMRuntime.cc
index 8d183da..69b05f4 100644
--- a/runtime/native/dalvik_system_VMRuntime.cc
+++ b/runtime/native/dalvik_system_VMRuntime.cc
@@ -262,12 +262,14 @@
}
const DexFile* dex_file = dex_cache->GetDexFile();
const DexFile::FieldId& field_id = dex_file->GetFieldId(field_idx);
- mirror::Class* klass = dex_cache->GetResolvedType(field_id.class_idx_);
- if (klass == NULL) {
+ Thread* const self = Thread::Current();
+ StackHandleScope<1> hs(self);
+ Handle<mirror::Class> klass(hs.NewHandle(dex_cache->GetResolvedType(field_id.class_idx_)));
+ if (klass.Get() == NULL) {
return;
}
if (is_static) {
- field = klass->FindStaticField(dex_cache.Get(), field_idx);
+ field = mirror::Class::FindStaticField(self, klass, dex_cache.Get(), field_idx);
} else {
field = klass->FindInstanceField(dex_cache.Get(), field_idx);
}
diff --git a/runtime/native/java_lang_Class.cc b/runtime/native/java_lang_Class.cc
index b6cf7d8..e619dda 100644
--- a/runtime/native/java_lang_Class.cc
+++ b/runtime/native/java_lang_Class.cc
@@ -84,8 +84,9 @@
static jstring Class_getNameNative(JNIEnv* env, jobject javaThis) {
ScopedFastNativeObjectAccess soa(env);
- mirror::Class* c = DecodeClass(soa, javaThis);
- return soa.AddLocalReference<jstring>(c->ComputeName());
+ StackHandleScope<1> hs(soa.Self());
+ mirror::Class* const c = DecodeClass(soa, javaThis);
+ return soa.AddLocalReference<jstring>(mirror::Class::ComputeName(hs.NewHandle(c)));
}
static jobjectArray Class_getProxyInterfaces(JNIEnv* env, jobject javaThis) {
diff --git a/runtime/native/java_lang_reflect_Array.cc b/runtime/native/java_lang_reflect_Array.cc
index 7c6f2f3..db77437 100644
--- a/runtime/native/java_lang_reflect_Array.cc
+++ b/runtime/native/java_lang_reflect_Array.cc
@@ -35,7 +35,7 @@
DCHECK(javaDimArray != NULL);
mirror::Object* dimensions_obj = soa.Decode<mirror::Object*>(javaDimArray);
DCHECK(dimensions_obj->IsArrayInstance());
- DCHECK_STREQ(ClassHelper(dimensions_obj->GetClass()).GetDescriptor(), "[I");
+ DCHECK_STREQ(dimensions_obj->GetClass()->GetDescriptor().c_str(), "[I");
Handle<mirror::IntArray> dimensions_array(
hs.NewHandle(down_cast<mirror::IntArray*>(dimensions_obj)));
mirror::Array* new_array = mirror::Array::CreateMultiArray(soa.Self(), element_class,
diff --git a/runtime/object_utils.h b/runtime/object_utils.h
index b1e8c09..664ac89 100644
--- a/runtime/object_utils.h
+++ b/runtime/object_utils.h
@@ -66,171 +66,6 @@
DISALLOW_COPY_AND_ASSIGN(ObjectLock);
};
-class ClassHelper {
- public:
- explicit ClassHelper(mirror::Class* c )
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
- : interface_type_list_(nullptr), klass_(nullptr) {
- if (c != nullptr) {
- ChangeClass(c);
- }
- }
-
- void ChangeClass(mirror::Class* new_c)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- CHECK(new_c != nullptr) << "klass_=" << klass_; // Log what we were changing from if any
- if (!new_c->IsClass()) {
- LOG(FATAL) << "new_c=" << new_c << " cc " << new_c->GetClass() << " ccc "
- << ((new_c->GetClass() != nullptr) ? new_c->GetClass()->GetClass() : nullptr);
- }
- klass_ = new_c;
- interface_type_list_ = nullptr;
- }
-
- // The returned const char* is only guaranteed to be valid for the lifetime of the ClassHelper.
- // If you need it longer, copy it into a std::string.
- const char* GetDescriptor() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- CHECK(klass_ != nullptr);
- if (UNLIKELY(klass_->IsArrayClass())) {
- return GetArrayDescriptor();
- } else if (UNLIKELY(klass_->IsPrimitive())) {
- return Primitive::Descriptor(klass_->GetPrimitiveType());
- } else if (UNLIKELY(klass_->IsProxyClass())) {
- descriptor_ = GetClassLinker()->GetDescriptorForProxy(klass_);
- return descriptor_.c_str();
- } else {
- const DexFile& dex_file = GetDexFile();
- const DexFile::TypeId& type_id = dex_file.GetTypeId(GetClassDef()->class_idx_);
- return dex_file.GetTypeDescriptor(type_id);
- }
- }
-
- const char* GetArrayDescriptor() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- std::string result("[");
- mirror::Class* saved_klass = klass_;
- CHECK(saved_klass != nullptr);
- ChangeClass(klass_->GetComponentType());
- result += GetDescriptor();
- ChangeClass(saved_klass);
- descriptor_ = result;
- return descriptor_.c_str();
- }
-
- const DexFile::ClassDef* GetClassDef() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- DCHECK(klass_ != nullptr);
- uint16_t class_def_idx = klass_->GetDexClassDefIndex();
- if (class_def_idx == DexFile::kDexNoIndex16) {
- return nullptr;
- }
- return &GetDexFile().GetClassDef(class_def_idx);
- }
-
- uint32_t NumDirectInterfaces() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- DCHECK(klass_ != nullptr);
- if (klass_->IsPrimitive()) {
- return 0;
- } else if (klass_->IsArrayClass()) {
- return 2;
- } else if (klass_->IsProxyClass()) {
- mirror::SynthesizedProxyClass* proxyClass = reinterpret_cast<mirror::SynthesizedProxyClass*>(klass_);
- mirror::ObjectArray<mirror::Class>* interfaces = proxyClass->GetInterfaces();
- return interfaces != nullptr ? interfaces->GetLength() : 0;
- } else {
- const DexFile::TypeList* interfaces = GetInterfaceTypeList();
- if (interfaces == nullptr) {
- return 0;
- } else {
- return interfaces->Size();
- }
- }
- }
-
- uint16_t GetDirectInterfaceTypeIdx(uint32_t idx)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- DCHECK(klass_ != nullptr);
- DCHECK(!klass_->IsPrimitive());
- DCHECK(!klass_->IsArrayClass());
- return GetInterfaceTypeList()->GetTypeItem(idx).type_idx_;
- }
-
- mirror::Class* GetDirectInterface(uint32_t idx)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- DCHECK(klass_ != nullptr);
- DCHECK(!klass_->IsPrimitive());
- if (klass_->IsArrayClass()) {
- if (idx == 0) {
- return GetClassLinker()->FindSystemClass(Thread::Current(), "Ljava/lang/Cloneable;");
- } else {
- DCHECK_EQ(1U, idx);
- return GetClassLinker()->FindSystemClass(Thread::Current(), "Ljava/io/Serializable;");
- }
- } else if (klass_->IsProxyClass()) {
- mirror::SynthesizedProxyClass* proxyClass = reinterpret_cast<mirror::SynthesizedProxyClass*>(klass_);
- mirror::ObjectArray<mirror::Class>* interfaces = proxyClass->GetInterfaces();
- DCHECK(interfaces != nullptr);
- return interfaces->Get(idx);
- } else {
- uint16_t type_idx = GetDirectInterfaceTypeIdx(idx);
- mirror::Class* interface = GetDexCache()->GetResolvedType(type_idx);
- if (interface == nullptr) {
- interface = GetClassLinker()->ResolveType(GetDexFile(), type_idx, klass_);
- CHECK(interface != nullptr || Thread::Current()->IsExceptionPending());
- }
- return interface;
- }
- }
-
- const char* GetSourceFile() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- std::string descriptor(GetDescriptor());
- const DexFile& dex_file = GetDexFile();
- const DexFile::ClassDef* dex_class_def = GetClassDef();
- CHECK(dex_class_def != nullptr) << "No class def for class " << PrettyClass(klass_);
- return dex_file.GetSourceFile(*dex_class_def);
- }
-
- std::string GetLocation() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- mirror::DexCache* dex_cache = GetDexCache();
- if (dex_cache != nullptr && !klass_->IsProxyClass()) {
- return dex_cache->GetLocation()->ToModifiedUtf8();
- } else {
- // Arrays and proxies are generated and have no corresponding dex file location.
- return "generated class";
- }
- }
-
- const DexFile& GetDexFile() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- return *GetDexCache()->GetDexFile();
- }
-
- mirror::DexCache* GetDexCache() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- return klass_->GetDexCache();
- }
-
- private:
- const DexFile::TypeList* GetInterfaceTypeList()
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- const DexFile::TypeList* result = interface_type_list_;
- if (result == nullptr) {
- const DexFile::ClassDef* class_def = GetClassDef();
- if (class_def != nullptr) {
- result = GetDexFile().GetInterfacesList(*class_def);
- interface_type_list_ = result;
- }
- }
- return result;
- }
-
- ClassLinker* GetClassLinker() ALWAYS_INLINE {
- return Runtime::Current()->GetClassLinker();
- }
-
- const DexFile::TypeList* interface_type_list_;
- mirror::Class* klass_;
- std::string descriptor_;
-
- DISALLOW_COPY_AND_ASSIGN(ClassHelper);
-};
-
class FieldHelper {
public:
FieldHelper() : field_(nullptr) {}
@@ -304,8 +139,7 @@
DCHECK(field_->IsStatic());
DCHECK_LT(field_index, 2U);
// 0 == Class[] interfaces; 1 == Class[][] throws;
- ClassHelper kh(field_->GetDeclaringClass());
- declaring_class_descriptor_ = kh.GetDescriptor();
+ declaring_class_descriptor_ = field_->GetDeclaringClass()->GetDescriptor();
return declaring_class_descriptor_.c_str();
}
const DexFile& dex_file = GetDexFile();
@@ -468,7 +302,7 @@
}
const char* GetDeclaringClassSourceFile() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- return ClassHelper(method_->GetDeclaringClass()).GetSourceFile();
+ return method_->GetDeclaringClass()->GetSourceFile();
}
uint16_t GetClassDefIndex() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
diff --git a/runtime/proxy_test.cc b/runtime/proxy_test.cc
index 8517e34..f38fb21 100644
--- a/runtime/proxy_test.cc
+++ b/runtime/proxy_test.cc
@@ -107,30 +107,33 @@
TEST_F(ProxyTest, ProxyClassHelper) {
ScopedObjectAccess soa(Thread::Current());
jobject jclass_loader = LoadDex("Interfaces");
- StackHandleScope<1> hs(soa.Self());
+ StackHandleScope<4> hs(soa.Self());
Handle<mirror::ClassLoader> class_loader(
hs.NewHandle(soa.Decode<mirror::ClassLoader*>(jclass_loader)));
- mirror::Class* I = class_linker_->FindClass(soa.Self(), "LInterfaces$I;", class_loader);
- mirror::Class* J = class_linker_->FindClass(soa.Self(), "LInterfaces$J;", class_loader);
- ASSERT_TRUE(I != nullptr);
- ASSERT_TRUE(J != nullptr);
- std::vector<mirror::Class*> interfaces;
- interfaces.push_back(I);
- interfaces.push_back(J);
+ Handle<mirror::Class> I(hs.NewHandle(
+ class_linker_->FindClass(soa.Self(), "LInterfaces$I;", class_loader)));
+ Handle<mirror::Class> J(hs.NewHandle(
+ class_linker_->FindClass(soa.Self(), "LInterfaces$J;", class_loader)));
+ ASSERT_TRUE(I.Get() != nullptr);
+ ASSERT_TRUE(J.Get() != nullptr);
- mirror::Class* proxyClass = GenerateProxyClass(soa, jclass_loader, "$Proxy1234", interfaces);
- ASSERT_TRUE(proxyClass != nullptr);
- ASSERT_TRUE(proxyClass->IsProxyClass());
- ASSERT_TRUE(proxyClass->IsInitialized());
+ std::vector<mirror::Class*> interfaces;
+ interfaces.push_back(I.Get());
+ interfaces.push_back(J.Get());
+ Handle<mirror::Class> proxy_class(hs.NewHandle(
+ GenerateProxyClass(soa, jclass_loader, "$Proxy1234", interfaces)));
+ interfaces.clear(); // Don't least possibly stale objects in the array as good practice.
+ ASSERT_TRUE(proxy_class.Get() != nullptr);
+ ASSERT_TRUE(proxy_class->IsProxyClass());
+ ASSERT_TRUE(proxy_class->IsInitialized());
// Check ClassHelper for proxy.
- ClassHelper kh(proxyClass);
- EXPECT_EQ(kh.NumDirectInterfaces(), 2U); // Interfaces$I and Interfaces$J.
- EXPECT_EQ(I, kh.GetDirectInterface(0));
- EXPECT_EQ(J, kh.GetDirectInterface(1));
- std::string proxyClassDescriptor(kh.GetDescriptor());
- EXPECT_EQ("L$Proxy1234;", proxyClassDescriptor);
+ EXPECT_EQ(proxy_class->NumDirectInterfaces(), 2U); // Interfaces$I and Interfaces$J.
+ EXPECT_EQ(I.Get(), mirror::Class::GetDirectInterface(soa.Self(), proxy_class, 0));
+ EXPECT_EQ(J.Get(), mirror::Class::GetDirectInterface(soa.Self(), proxy_class, 1));
+ std::string proxy_class_descriptor(proxy_class->GetDescriptor());
+ EXPECT_STREQ("L$Proxy1234;", proxy_class_descriptor.c_str());
}
// Creates a proxy class and check FieldHelper works correctly.
diff --git a/runtime/reflection.cc b/runtime/reflection.cc
index 98310e6..cbd66a6 100644
--- a/runtime/reflection.cc
+++ b/runtime/reflection.cc
@@ -242,22 +242,21 @@
}
#define DO_FIRST_ARG(match_descriptor, get_fn, append) { \
- const StringPiece src_descriptor(arg != nullptr \
- ? ClassHelper(arg->GetClass<>()).GetDescriptor() \
- : "null"); \
- if (LIKELY(src_descriptor == match_descriptor)) { \
+ if (LIKELY(arg != nullptr && arg->GetClass<>()->DescriptorEquals(match_descriptor))) { \
mirror::ArtField* primitive_field = arg->GetClass()->GetIFields()->Get(0); \
append(primitive_field-> get_fn(arg));
#define DO_ARG(match_descriptor, get_fn, append) \
- } else if (LIKELY(src_descriptor == match_descriptor)) { \
+ } else if (LIKELY(arg != nullptr && \
+ arg->GetClass<>()->DescriptorEquals(match_descriptor))) { \
mirror::ArtField* primitive_field = arg->GetClass()->GetIFields()->Get(0); \
append(primitive_field-> get_fn(arg));
#define DO_FAIL(expected) \
} else { \
if (arg->GetClass<>()->IsPrimitive()) { \
- ThrowIllegalPrimitiveArgumentException(expected, src_descriptor); \
+ ThrowIllegalPrimitiveArgumentException(expected, \
+ arg->GetClass<>()->GetDescriptor().c_str()); \
} else { \
ThrowIllegalArgumentException(nullptr, \
StringPrintf("method %s argument %zd has type %s, got %s", \
@@ -742,32 +741,32 @@
}
JValue boxed_value;
- const StringPiece src_descriptor(ClassHelper(o->GetClass()).GetDescriptor());
+ mirror::Class* klass = o->GetClass();
mirror::Class* src_class = nullptr;
ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
mirror::ArtField* primitive_field = o->GetClass()->GetIFields()->Get(0);
- if (src_descriptor == "Ljava/lang/Boolean;") {
+ if (klass->DescriptorEquals("Ljava/lang/Boolean;")) {
src_class = class_linker->FindPrimitiveClass('Z');
boxed_value.SetZ(primitive_field->GetBoolean(o));
- } else if (src_descriptor == "Ljava/lang/Byte;") {
+ } else if (klass->DescriptorEquals("Ljava/lang/Byte;")) {
src_class = class_linker->FindPrimitiveClass('B');
boxed_value.SetB(primitive_field->GetByte(o));
- } else if (src_descriptor == "Ljava/lang/Character;") {
+ } else if (klass->DescriptorEquals("Ljava/lang/Character;")) {
src_class = class_linker->FindPrimitiveClass('C');
boxed_value.SetC(primitive_field->GetChar(o));
- } else if (src_descriptor == "Ljava/lang/Float;") {
+ } else if (klass->DescriptorEquals("Ljava/lang/Float;")) {
src_class = class_linker->FindPrimitiveClass('F');
boxed_value.SetF(primitive_field->GetFloat(o));
- } else if (src_descriptor == "Ljava/lang/Double;") {
+ } else if (klass->DescriptorEquals("Ljava/lang/Double;")) {
src_class = class_linker->FindPrimitiveClass('D');
boxed_value.SetD(primitive_field->GetDouble(o));
- } else if (src_descriptor == "Ljava/lang/Integer;") {
+ } else if (klass->DescriptorEquals("Ljava/lang/Integer;")) {
src_class = class_linker->FindPrimitiveClass('I');
boxed_value.SetI(primitive_field->GetInt(o));
- } else if (src_descriptor == "Ljava/lang/Long;") {
+ } else if (klass->DescriptorEquals("Ljava/lang/Long;")) {
src_class = class_linker->FindPrimitiveClass('J');
boxed_value.SetJ(primitive_field->GetLong(o));
- } else if (src_descriptor == "Ljava/lang/Short;") {
+ } else if (klass->DescriptorEquals("Ljava/lang/Short;")) {
src_class = class_linker->FindPrimitiveClass('S');
boxed_value.SetS(primitive_field->GetShort(o));
} else {
@@ -775,7 +774,7 @@
StringPrintf("%s has type %s, got %s",
UnboxingFailureKind(f).c_str(),
PrettyDescriptor(dst_class).c_str(),
- PrettyDescriptor(src_descriptor.data()).c_str()).c_str());
+ PrettyDescriptor(o->GetClass()->GetDescriptor()).c_str()).c_str());
return false;
}
diff --git a/runtime/utils.cc b/runtime/utils.cc
index f26b598..ad0175a 100644
--- a/runtime/utils.cc
+++ b/runtime/utils.cc
@@ -230,7 +230,7 @@
if (klass == NULL) {
return "null";
}
- return PrettyDescriptor(ClassHelper(klass).GetDescriptor());
+ return PrettyDescriptor(klass->GetDescriptor());
}
std::string PrettyDescriptor(const std::string& descriptor) {
@@ -412,11 +412,9 @@
if (obj->GetClass() == NULL) {
return "(raw)";
}
- ClassHelper kh(obj->GetClass());
- std::string result(PrettyDescriptor(kh.GetDescriptor()));
+ std::string result(PrettyDescriptor(obj->GetClass()->GetDescriptor()));
if (obj->IsClass()) {
- kh.ChangeClass(obj->AsClass());
- result += "<" + PrettyDescriptor(kh.GetDescriptor()) + ">";
+ result += "<" + PrettyDescriptor(obj->AsClass()->GetDescriptor()) + ">";
}
return result;
}
diff --git a/runtime/verifier/method_verifier.cc b/runtime/verifier/method_verifier.cc
index 9dd366d..0a31f63 100644
--- a/runtime/verifier/method_verifier.cc
+++ b/runtime/verifier/method_verifier.cc
@@ -93,11 +93,10 @@
}
bool early_failure = false;
std::string failure_message;
- ClassHelper kh(klass);
- const DexFile& dex_file = kh.GetDexFile();
- const DexFile::ClassDef* class_def = kh.GetClassDef();
+ const DexFile& dex_file = klass->GetDexFile();
+ const DexFile::ClassDef* class_def = klass->GetClassDef();
mirror::Class* super = klass->GetSuperClass();
- if (super == NULL && strcmp("Ljava/lang/Object;", kh.GetDescriptor()) != 0) {
+ if (super == NULL && "Ljava/lang/Object;" != klass->GetDescriptor()) {
early_failure = true;
failure_message = " that has no super class";
} else if (super != NULL && super->IsFinal()) {
@@ -116,7 +115,7 @@
return kHardFailure;
}
StackHandleScope<2> hs(Thread::Current());
- Handle<mirror::DexCache> dex_cache(hs.NewHandle(kh.GetDexCache()));
+ Handle<mirror::DexCache> dex_cache(hs.NewHandle(klass->GetDexCache()));
Handle<mirror::ClassLoader> class_loader(hs.NewHandle(klass->GetClassLoader()));
return VerifyClass(&dex_file, dex_cache, class_loader, class_def, allow_soft_failures, error);
}
@@ -3057,7 +3056,7 @@
if (method_type != METHOD_INTERFACE && !actual_arg_type.IsZero()) {
mirror::Class* klass = res_method->GetDeclaringClass();
const RegType& res_method_class =
- reg_types_.FromClass(ClassHelper(klass).GetDescriptor(), klass,
+ reg_types_.FromClass(klass->GetDescriptor().c_str(), klass,
klass->CannotBeAssignedFromOtherTypes());
if (!res_method_class.IsAssignableFrom(actual_arg_type)) {
Fail(actual_arg_type.IsUnresolvedTypes() ? VERIFY_ERROR_NO_CLASS:
@@ -3182,7 +3181,7 @@
if (!actual_arg_type.IsZero()) {
mirror::Class* klass = res_method->GetDeclaringClass();
const RegType& res_method_class =
- reg_types_.FromClass(ClassHelper(klass).GetDescriptor(), klass,
+ reg_types_.FromClass(klass->GetDescriptor().c_str(), klass,
klass->CannotBeAssignedFromOtherTypes());
if (!res_method_class.IsAssignableFrom(actual_arg_type)) {
Fail(actual_arg_type.IsUnresolvedTypes() ? VERIFY_ERROR_NO_CLASS :
diff --git a/runtime/verifier/reg_type.cc b/runtime/verifier/reg_type.cc
index c6f3e5c..8df1e5d 100644
--- a/runtime/verifier/reg_type.cc
+++ b/runtime/verifier/reg_type.cc
@@ -621,7 +621,7 @@
if (super_klass != NULL) {
// A super class of a precise type isn't precise as a precise type indicates the register
// holds exactly that type.
- return cache->FromClass(ClassHelper(super_klass).GetDescriptor(), super_klass, false);
+ return cache->FromClass(super_klass->GetDescriptor().c_str(), super_klass, false);
} else {
return cache->Zero();
}
@@ -899,7 +899,7 @@
} else if (c2 == join_class && !incoming_type.IsPreciseReference()) {
return incoming_type;
} else {
- return reg_types->FromClass(ClassHelper(join_class).GetDescriptor(), join_class, false);
+ return reg_types->FromClass(join_class->GetDescriptor().c_str(), join_class, false);
}
}
} else {
diff --git a/runtime/verifier/reg_type_cache.cc b/runtime/verifier/reg_type_cache.cc
index 689a33e..ff9edbb 100644
--- a/runtime/verifier/reg_type_cache.cc
+++ b/runtime/verifier/reg_type_cache.cc
@@ -567,7 +567,7 @@
return FromDescriptor(loader, component.c_str(), false);
} else {
mirror::Class* klass = array.GetClass()->GetComponentType();
- return FromClass(ClassHelper(klass).GetDescriptor(), klass,
+ return FromClass(klass->GetDescriptor().c_str(), klass,
klass->CannotBeAssignedFromOtherTypes());
}
}