diff options
29 files changed, 486 insertions, 491 deletions
diff --git a/compiler/driver/compiler_driver.cc b/compiler/driver/compiler_driver.cc index b48be587d6..93feb2934e 100644 --- a/compiler/driver/compiler_driver.cc +++ b/compiler/driver/compiler_driver.cc @@ -685,7 +685,7 @@ static bool RecordImageClassesVisitor(mirror::Class* klass, void* arg) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { CompilerDriver::DescriptorSet* image_classes = reinterpret_cast<CompilerDriver::DescriptorSet*>(arg); - image_classes->insert(ClassHelper(klass).GetDescriptor()); + image_classes->insert(klass->GetDescriptor()); return true; } @@ -755,11 +755,15 @@ void CompilerDriver::LoadImageClasses(TimingLogger* timings) CHECK_NE(image_classes_->size(), 0U); } -static void MaybeAddToImageClasses(mirror::Class* klass, CompilerDriver::DescriptorSet* image_classes) +static void MaybeAddToImageClasses(Handle<mirror::Class> c, + CompilerDriver::DescriptorSet* image_classes) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { + Thread* self = Thread::Current(); + StackHandleScope<1> hs(self); + // Make a copy of the handle so that we don't clobber it doing Assign. + Handle<mirror::Class> klass(hs.NewHandle(c.Get())); while (!klass->IsObjectClass()) { - ClassHelper kh(klass); - const char* descriptor = kh.GetDescriptor(); + std::string descriptor(klass->GetDescriptor()); std::pair<CompilerDriver::DescriptorSet::iterator, bool> result = image_classes->insert(descriptor); if (result.second) { @@ -767,13 +771,16 @@ static void MaybeAddToImageClasses(mirror::Class* klass, CompilerDriver::Descrip } else { return; } - for (size_t i = 0; i < kh.NumDirectInterfaces(); ++i) { - MaybeAddToImageClasses(kh.GetDirectInterface(i), image_classes); + for (size_t i = 0; i < klass->NumDirectInterfaces(); ++i) { + StackHandleScope<1> hs(self); + MaybeAddToImageClasses(hs.NewHandle(mirror::Class::GetDirectInterface(self, klass, i)), + image_classes); } if (klass->IsArrayClass()) { - MaybeAddToImageClasses(klass->GetComponentType(), image_classes); + StackHandleScope<1> hs(self); + MaybeAddToImageClasses(hs.NewHandle(klass->GetComponentType()), image_classes); } - klass = klass->GetSuperClass(); + klass.Assign(klass->GetSuperClass()); } } @@ -781,7 +788,8 @@ void CompilerDriver::FindClinitImageClassesCallback(mirror::Object* object, void DCHECK(object != NULL); DCHECK(arg != NULL); CompilerDriver* compiler_driver = reinterpret_cast<CompilerDriver*>(arg); - MaybeAddToImageClasses(object->GetClass(), compiler_driver->image_classes_.get()); + StackHandleScope<1> hs(Thread::Current()); + MaybeAddToImageClasses(hs.NewHandle(object->GetClass()), compiler_driver->image_classes_.get()); } void CompilerDriver::UpdateImageClasses(TimingLogger* timings) { @@ -1582,8 +1590,7 @@ static void ResolveType(const ParallelCompilationManager* manager, size_t type_i CHECK(soa.Self()->IsExceptionPending()); mirror::Throwable* exception = soa.Self()->GetException(NULL); VLOG(compiler) << "Exception during type resolution: " << exception->Dump(); - if (strcmp("Ljava/lang/OutOfMemoryError;", - ClassHelper(exception->GetClass()).GetDescriptor()) == 0) { + if (exception->GetClass()->DescriptorEquals("Ljava/lang/OutOfMemoryError;")) { // There's little point continuing compilation if the heap is exhausted. LOG(FATAL) << "Out of memory during type resolution for compilation"; } diff --git a/compiler/image_writer.cc b/compiler/image_writer.cc index eb1c5811c7..e261ee6cfc 100644 --- a/compiler/image_writer.cc +++ b/compiler/image_writer.cc @@ -251,7 +251,9 @@ void ImageWriter::ComputeLazyFieldsForImageClasses() { } bool ImageWriter::ComputeLazyFieldsForClassesVisitor(Class* c, void* /*arg*/) { - c->ComputeName(); + Thread* self = Thread::Current(); + StackHandleScope<1> hs(self); + mirror::Class::ComputeName(hs.NewHandle(c)); return true; } @@ -285,7 +287,7 @@ void ImageWriter::ComputeEagerResolvedStrings() SHARED_LOCKS_REQUIRED(Locks::mut } bool ImageWriter::IsImageClass(Class* klass) { - return compiler_driver_.IsImageClass(ClassHelper(klass).GetDescriptor()); + return compiler_driver_.IsImageClass(klass->GetDescriptor().c_str()); } struct NonImageClasses { @@ -339,7 +341,7 @@ void ImageWriter::PruneNonImageClasses() { bool ImageWriter::NonImageClassesVisitor(Class* klass, void* arg) { NonImageClasses* context = reinterpret_cast<NonImageClasses*>(arg); if (!context->image_writer->IsImageClass(klass)) { - context->non_image_classes->insert(ClassHelper(klass).GetDescriptor()); + context->non_image_classes->insert(klass->GetDescriptor()); } return true; } @@ -359,7 +361,7 @@ void ImageWriter::CheckNonImageClassesRemovedCallback(Object* obj, void* arg) { Class* klass = obj->AsClass(); if (!image_writer->IsImageClass(klass)) { image_writer->DumpImageClasses(); - CHECK(image_writer->IsImageClass(klass)) << ClassHelper(klass).GetDescriptor() + CHECK(image_writer->IsImageClass(klass)) << klass->GetDescriptor() << " " << PrettyDescriptor(klass); } } diff --git a/oatdump/oatdump.cc b/oatdump/oatdump.cc index fef25e0dd6..aaf9ed5b12 100644 --- a/oatdump/oatdump.cc +++ b/oatdump/oatdump.cc @@ -1147,7 +1147,7 @@ class ImageDumper { state->stats_.ComputeOutliers(total_size, expansion, method); } } - state->stats_.Update(ClassHelper(obj_class).GetDescriptor(), object_bytes); + state->stats_.Update(obj_class->GetDescriptor().c_str(), object_bytes); } std::set<const void*> already_seen_; diff --git a/runtime/class_linker-inl.h b/runtime/class_linker-inl.h index ce634e0ff8..ac86014545 100644 --- a/runtime/class_linker-inl.h +++ b/runtime/class_linker-inl.h @@ -49,7 +49,7 @@ inline mirror::Class* ClassLinker::FindArrayClass(Thread* self, mirror::Class* e } 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 84a3c5da25..363e8b2925 100644 --- a/runtime/class_linker.cc +++ b/runtime/class_linker.cc @@ -96,8 +96,8 @@ static void ThrowEarlierClassFailure(mirror::Class* c) 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 @@ void ClassLinker::InitFromCompiler(const std::vector<const DexFile*>& boot_class 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 @@ void ClassLinker::FixupStaticTrampolines(mirror::Class* klass) { 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 @@ mirror::ArtMethod* ClassLinker::LoadMethod(Thread* self, const DexFile& dex_file 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 @@ bool ClassLinker::RemoveClass(const char* descriptor, const mirror::ClassLoader* 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 @@ mirror::Class* ClassLinker::LookupClassFromTableLocked(const char* descriptor, 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 @@ void ClassLinker::MoveImageClassesToClassTable() { 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 @@ void ClassLinker::LookupClasses(const char* descriptor, std::vector<mirror::Clas 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 @@ bool ClassLinker::VerifyClassUsingOatFile(const DexFile& dex_file, mirror::Class } 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 @@ static bool CanWeInitializeClass(mirror::Class* klass, bool can_init_statics, } // 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 @@ bool ClassLinker::InitializeClass(const Handle<mirror::Class>& klass, bool can_i } 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 @@ bool ClassLinker::InitializeClass(const Handle<mirror::Class>& klass, bool can_i // 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::LinkVirtualMethods(const Handle<mirror::Class>& klass) { 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 @@ bool ClassLinker::LinkInterfaceMethods(const Handle<mirror::Class>& klass, } 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 @@ bool ClassLinker::LinkInterfaceMethods(const Handle<mirror::Class>& klass, 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 @@ bool ClassLinker::LinkInterfaceMethods(const Handle<mirror::Class>& klass, // 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 @@ bool ClassLinker::LinkFields(const Handle<mirror::Class>& klass, bool is_static) } // 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 @@ bool ClassLinker::LinkFields(const Handle<mirror::Class>& klass, bool is_static) 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 @@ bool ClassLinker::LinkFields(const Handle<mirror::Class>& klass, bool is_static) } 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 @@ mirror::ArtField* ClassLinker::ResolveField(const DexFile& dex_file, uint32_t fi 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 @@ mirror::ArtField* ClassLinker::ResolveField(const DexFile& dex_file, uint32_t fi 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 @@ mirror::ArtField* ClassLinker::ResolveFieldJLS(const DexFile& dex_file, 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 @@ mirror::ArtField* ClassLinker::ResolveFieldJLS(const DexFile& dex_file, 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 9970dd5081..ff90f415ba 100644 --- a/runtime/class_linker_test.cc +++ b/runtime/class_linker_test.cc @@ -60,12 +60,11 @@ class ClassLinkerTest : public CommonRuntimeTest { 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 @@ class ClassLinkerTest : public CommonRuntimeTest { 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 @@ class ClassLinkerTest : public CommonRuntimeTest { 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 @@ class ClassLinkerTest : public CommonRuntimeTest { 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 @@ class ClassLinkerTest : public CommonRuntimeTest { 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 @@ class ClassLinkerTest : public CommonRuntimeTest { 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 @@ class ClassLinkerTest : public CommonRuntimeTest { 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 @@ class ClassLinkerTest : public CommonRuntimeTest { 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_Primitives) { 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 @@ TEST_F(ClassLinkerTest, FindClass) { } 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 @@ TEST_F(ClassLinkerTest, FindClass) { 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 @@ TEST_F(ClassLinkerTest, StaticFields) { 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, StaticFields) { 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 @@ TEST_F(ClassLinkerTest, Interfaces) { 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 @@ TEST_F(ClassLinkerTest, ClassRootDescriptors) { 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 315f274788..a3e3cfad7e 100644 --- a/runtime/common_throws.cc +++ b/runtime/common_throws.cc @@ -36,8 +36,7 @@ namespace art { 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 ThrowNegativeArraySizeException(const char* msg) { 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 ThrowNoSuchFieldError(const StringPiece& scope, mirror::Class* c, 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 f6b4891af5..2cbff79cc8 100644 --- a/runtime/debugger.cc +++ b/runtime/debugger.cc @@ -756,7 +756,7 @@ std::string Dbg::GetClassName(JDWP::RefTypeId class_id) { 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 @@ JDWP::JdwpError Dbg::GetClassInfo(JDWP::RefTypeId class_id, JDWP::JdwpTypeTag* p } if (pDescriptor != NULL) { - *pDescriptor = ClassHelper(c).GetDescriptor(); + *pDescriptor = c->GetDescriptor(); } return JDWP::ERR_NONE; } @@ -1124,7 +1124,7 @@ JDWP::JdwpError Dbg::GetSignature(JDWP::RefTypeId class_id, std::string* signatu if (c == NULL) { return status; } - *signature = ClassHelper(c).GetDescriptor(); + *signature = c->GetDescriptor(); return JDWP::ERR_NONE; } @@ -1137,7 +1137,7 @@ JDWP::JdwpError Dbg::GetSourceFile(JDWP::RefTypeId class_id, std::string& result if (c->IsProxyClass()) { return JDWP::ERR_ABSENT_INFORMATION; } - result = ClassHelper(c).GetSourceFile(); + result = c->GetSourceFile(); return JDWP::ERR_NONE; } @@ -1202,7 +1202,7 @@ JDWP::JdwpError Dbg::OutputArray(JDWP::ObjectId array_id, int offset, int count, 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 @@ JDWP::JdwpError Dbg::SetArrayElements(JDWP::ObjectId array_id, int offset, int c 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::OutputDeclaredMethods(JDWP::RefTypeId class_id, bool with_g 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 @@ void Dbg::PostClassPrepare(mirror::Class* c) { // 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 @@ jbyteArray Dbg::GetRecentAllocations() { 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 @@ jbyteArray Dbg::GetRecentAllocations() { // (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 b4c2d14f49..ef31be3fdc 100644 --- a/runtime/gc/heap.cc +++ b/runtime/gc/heap.cc @@ -2765,7 +2765,7 @@ void Heap::AddModUnionTable(accounting::ModUnionTable* mod_union_table) { 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 20e2b8da19..478c74cd25 100644 --- a/runtime/interpreter/interpreter.cc +++ b/runtime/interpreter/interpreter.cc @@ -49,7 +49,8 @@ static void UnstartedRuntimeJni(Thread* self, ArtMethod* method, 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 c5fb0d84cd..418aff51dc 100644 --- a/runtime/interpreter/interpreter_common.cc +++ b/runtime/interpreter/interpreter_common.cc @@ -117,8 +117,8 @@ bool DoCall(ArtMethod* method, Thread* self, ShadowFrame& shadow_frame, "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 9b03334b62..0c7c8a9fce 100644 --- a/runtime/interpreter/interpreter_common.h +++ b/runtime/interpreter/interpreter_common.h @@ -345,9 +345,9 @@ static inline bool DoFieldPut(Thread* self, const ShadowFrame& shadow_frame, 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 5b7dee1df4..e0f9e5f958 100644 --- a/runtime/interpreter/interpreter_goto_table_impl.cc +++ b/runtime/interpreter/interpreter_goto_table_impl.cc @@ -342,8 +342,8 @@ JValue ExecuteGotoImpl(Thread* self, MethodHelper& mh, const DexFile::CodeItem* 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 @@ JValue ExecuteGotoImpl(Thread* self, MethodHelper& mh, const DexFile::CodeItem* 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 859cfc47c9..c1d24f5a5f 100644 --- a/runtime/interpreter/interpreter_switch_impl.cc +++ b/runtime/interpreter/interpreter_switch_impl.cc @@ -258,8 +258,8 @@ JValue ExecuteSwitchImpl(Thread* self, MethodHelper& mh, const DexFile::CodeItem 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 @@ JValue ExecuteSwitchImpl(Thread* self, MethodHelper& mh, const DexFile::CodeItem 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 3afb149fa3..17a3de48ea 100644 --- a/runtime/jni_internal.cc +++ b/runtime/jni_internal.cc @@ -109,7 +109,7 @@ static void ThrowNoSuchMethodError(ScopedObjectAccess& soa, mirror::Class* c, 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 @@ static jfieldID FindFieldID(const ScopedObjectAccess& soa, jclass jni_class, con 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 d454ae8469..b2d8288828 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 @@ inline void Class::VisitReferences(mirror::Class* klass, const Visitor& visitor) } 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 @@ bool Class::IsArtFieldClass() { } template<ReadBarrierOption kReadBarrierOption> -bool Class::IsArtMethodClass() { +inline bool Class::IsArtMethodClass() { return this == ArtMethod::GetJavaLangReflectArtMethod<kReadBarrierOption>(); } @@ -527,6 +529,24 @@ inline bool Class::IsClassClass() { 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 15b69f378b..4869b454fe 100644 --- a/runtime/mirror/class.cc +++ b/runtime/mirror/class.cc @@ -136,15 +136,13 @@ void Class::SetClassSize(uint32_t new_class_size) { // 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 @@ String* Class::ComputeName() { 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 @@ void Class::DumpClass(std::ostream& os, int flags) { 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 << " direct methods (" << NumDirectMethods() << " entries):\n"; - for (size_t i = 0; i < NumDirectMethods(); ++i) { - os << StringPrintf(" %2zd: %s\n", i, PrettyMethod(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()); + os << StringPrintf(" %2zd: %s\n", i, + PrettyMethod(h_this->GetVirtualMethodDuringLinking(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 (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 @@ bool Class::IsInSamePackage(Class* that) { 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 @@ ArtField* Class::FindDeclaredStaticField(const DexCache* dex_cache, uint32_t dex 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 @@ void Class::SetPreverifiedFlagOnAllMethods() { 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 92b999e051..a283f601af 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 @@ class MANAGED Class : public Object { 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 @@ class MANAGED Class : public Object { 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 @@ class MANAGED Class : public Object { 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 @@ class MANAGED Class : public Object { 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 e0fd6a229e..e24602abec 100644 --- a/runtime/mirror/object_test.cc +++ b/runtime/mirror/object_test.cc @@ -104,7 +104,7 @@ TEST_F(ObjectTest, IsInSamePackage) { 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, Clone) { 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 @@ TEST_F(ObjectTest, AllocObjectArray) { 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, FindInstanceField) { 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 8d183dad8b..69b05f41c4 100644 --- a/runtime/native/dalvik_system_VMRuntime.cc +++ b/runtime/native/dalvik_system_VMRuntime.cc @@ -262,12 +262,14 @@ static void PreloadDexCachesResolveField(Handle<mirror::DexCache>& dex_cache, } 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 b6cf7d830f..e619dda133 100644 --- a/runtime/native/java_lang_Class.cc +++ b/runtime/native/java_lang_Class.cc @@ -84,8 +84,9 @@ static jclass Class_classForName(JNIEnv* env, jclass, jstring javaName, jboolean 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 7c6f2f38cd..db77437db4 100644 --- a/runtime/native/java_lang_reflect_Array.cc +++ b/runtime/native/java_lang_reflect_Array.cc @@ -35,7 +35,7 @@ static jobject Array_createMultiArray(JNIEnv* env, jclass, jclass javaElementCla 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 b1e8c099b7..664ac897cb 100644 --- a/runtime/object_utils.h +++ b/runtime/object_utils.h @@ -66,171 +66,6 @@ class ObjectLock { 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 @@ class FieldHelper { 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 @@ class MethodHelper { } 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 8517e34969..f38fb2155b 100644 --- a/runtime/proxy_test.cc +++ b/runtime/proxy_test.cc @@ -107,30 +107,33 @@ class ProxyTest : public CommonCompilerTest { 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 98310e68f4..cbd66a6a51 100644 --- a/runtime/reflection.cc +++ b/runtime/reflection.cc @@ -242,22 +242,21 @@ class ArgArray { } #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 @@ static bool UnboxPrimitive(const ThrowLocation* throw_location, mirror::Object* } 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 @@ static bool UnboxPrimitive(const ThrowLocation* throw_location, mirror::Object* 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 f26b59896b..ad0175a920 100644 --- a/runtime/utils.cc +++ b/runtime/utils.cc @@ -230,7 +230,7 @@ std::string PrettyDescriptor(mirror::Class* klass) { 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 @@ std::string PrettyTypeOf(mirror::Object* obj) { 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 9dd366dcc2..0a31f63b74 100644 --- a/runtime/verifier/method_verifier.cc +++ b/runtime/verifier/method_verifier.cc @@ -93,11 +93,10 @@ MethodVerifier::FailureKind MethodVerifier::VerifyClass(mirror::Class* klass, } 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 @@ MethodVerifier::FailureKind MethodVerifier::VerifyClass(mirror::Class* klass, 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 @@ mirror::ArtMethod* MethodVerifier::VerifyInvocationArgs(const Instruction* inst, 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 @@ mirror::ArtMethod* MethodVerifier::VerifyInvokeVirtualQuickArgs(const Instructio 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 c6f3e5c5f4..8df1e5d6dc 100644 --- a/runtime/verifier/reg_type.cc +++ b/runtime/verifier/reg_type.cc @@ -621,7 +621,7 @@ const RegType& RegType::GetSuperClass(RegTypeCache* cache) const { 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 @@ const RegType& RegType::Merge(const RegType& incoming_type, RegTypeCache* reg_ty } 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 689a33e258..ff9edbbeaf 100644 --- a/runtime/verifier/reg_type_cache.cc +++ b/runtime/verifier/reg_type_cache.cc @@ -567,7 +567,7 @@ const RegType& RegTypeCache::GetComponentType(const RegType& array, mirror::Clas 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()); } } |