summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--compiler/compiler_reflection_test.cc2
-rw-r--r--compiler/exception_test.cc2
-rw-r--r--compiler/jni/jni_compiler_test.cc3
-rw-r--r--compiler/oat/jni_stub_hash_map_test.cc3
-rw-r--r--compiler/optimizing/inliner.cc7
-rw-r--r--dex2oat/driver/compiler_driver.cc39
-rw-r--r--dex2oat/driver/compiler_driver_test.cc6
-rw-r--r--dex2oat/interpreter/unstarted_runtime_transaction_test.cc10
-rw-r--r--dex2oat/linker/oat_writer_test.cc4
-rw-r--r--dex2oat/transaction_test.cc50
-rw-r--r--dex2oat/verifier_deps_test.cc20
-rw-r--r--libdexfile/dex/dex_file-inl.h11
-rw-r--r--libdexfile/dex/dex_file.h1
-rw-r--r--libprofile/profile/profile_compilation_info.h20
-rw-r--r--oatdump/oatdump.cc11
-rw-r--r--openjdkjvmti/ti_method.cc3
-rw-r--r--profman/profile_assistant_test.cc2
-rw-r--r--runtime/art_field-inl.h4
-rw-r--r--runtime/art_field.cc2
-rw-r--r--runtime/art_field.h2
-rw-r--r--runtime/class_linker-inl.h5
-rw-r--r--runtime/class_linker.cc84
-rw-r--r--runtime/class_linker.h14
-rw-r--r--runtime/class_linker_test.cc91
-rw-r--r--runtime/class_table_test.cc6
-rw-r--r--runtime/common_runtime_test.cc6
-rw-r--r--runtime/common_runtime_test.h6
-rw-r--r--runtime/fuzzer_corpus_test.cc4
-rw-r--r--runtime/gc/reference_queue_test.cc9
-rw-r--r--runtime/hidden_api_test.cc4
-rw-r--r--runtime/imtable_test.cc6
-rw-r--r--runtime/instrumentation_test.cc14
-rw-r--r--runtime/interpreter/unstarted_runtime.cc19
-rw-r--r--runtime/interpreter/unstarted_runtime_test.cc31
-rw-r--r--runtime/interpreter/unstarted_runtime_test.h4
-rw-r--r--runtime/jit/jit.cc8
-rw-r--r--runtime/jit/profiling_info_test.cc5
-rw-r--r--runtime/jni/jni_internal.cc15
-rw-r--r--runtime/jni/jni_internal_test.cc2
-rw-r--r--runtime/mirror/class_ext.cc4
-rw-r--r--runtime/mirror/dex_cache_test.cc9
-rw-r--r--runtime/mirror/method_type_test.cc33
-rw-r--r--runtime/mirror/object_test.cc33
-rw-r--r--runtime/mirror/var_handle_test.cc48
-rw-r--r--runtime/native/java_lang_Class.cc4
-rw-r--r--runtime/native/java_lang_VMClassLoader.cc4
-rw-r--r--runtime/oat/oat_file_manager.cc6
-rw-r--r--runtime/proxy_test.cc12
-rw-r--r--runtime/reference_table_test.cc10
-rw-r--r--runtime/reflection_test.cc4
-rw-r--r--runtime/runtime_callbacks_test.cc3
-rw-r--r--runtime/thread.cc3
-rw-r--r--runtime/vdex_file.cc59
-rw-r--r--runtime/verifier/reg_type_cache.cc10
-rw-r--r--runtime/verifier/reg_type_cache.h2
-rw-r--r--runtime/verifier/reg_type_test.cc6
-rw-r--r--runtime/verifier/verifier_deps.cc52
-rw-r--r--runtime/verifier/verifier_deps.h6
-rw-r--r--test/692-vdex-inmem-loader/vdex_inmem_loader.cc12
-rw-r--r--tools/art_verifier/art_verifier.cc8
-rw-r--r--tools/fuzzer/libart_verify_classes_fuzzer.cc4
61 files changed, 450 insertions, 417 deletions
diff --git a/compiler/compiler_reflection_test.cc b/compiler/compiler_reflection_test.cc
index f3c07db136..f9cc02f16e 100644
--- a/compiler/compiler_reflection_test.cc
+++ b/compiler/compiler_reflection_test.cc
@@ -35,7 +35,7 @@ TEST_F(CompilerReflectionTest, StaticMainMethod) {
Handle<mirror::ClassLoader> class_loader(
hs.NewHandle(soa.Decode<mirror::ClassLoader>(jclass_loader)));
- ObjPtr<mirror::Class> klass = class_linker_->FindClass(soa.Self(), "LMain;", class_loader);
+ ObjPtr<mirror::Class> klass = FindClass("LMain;", class_loader);
ASSERT_TRUE(klass != nullptr);
ArtMethod* method = klass->FindClassMethod("main",
diff --git a/compiler/exception_test.cc b/compiler/exception_test.cc
index 0e289353c7..4eae96158e 100644
--- a/compiler/exception_test.cc
+++ b/compiler/exception_test.cc
@@ -61,7 +61,7 @@ class ExceptionTest : public CommonRuntimeTest {
StackHandleScope<2> hs(soa.Self());
Handle<mirror::ClassLoader> class_loader(
hs.NewHandle(soa.Decode<mirror::ClassLoader>(LoadDex("ExceptionHandle"))));
- my_klass_ = class_linker_->FindClass(soa.Self(), "LExceptionHandle;", class_loader);
+ my_klass_ = FindClass("LExceptionHandle;", class_loader);
ASSERT_TRUE(my_klass_ != nullptr);
Handle<mirror::Class> klass(hs.NewHandle(my_klass_));
class_linker_->EnsureInitialized(soa.Self(), klass, true, true);
diff --git a/compiler/jni/jni_compiler_test.cc b/compiler/jni/jni_compiler_test.cc
index 2f4a1b5f44..35ee1edafd 100644
--- a/compiler/jni/jni_compiler_test.cc
+++ b/compiler/jni/jni_compiler_test.cc
@@ -243,8 +243,7 @@ class JniCompilerTest : public CommonCompilerTest {
Handle<mirror::ClassLoader> loader(
hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader)));
// Compile the native method before starting the runtime
- Handle<mirror::Class> c =
- hs.NewHandle(class_linker_->FindClass(self, "LMyClassNatives;", loader));
+ Handle<mirror::Class> c = hs.NewHandle(FindClass("LMyClassNatives;", loader));
const auto pointer_size = class_linker_->GetImagePointerSize();
ArtMethod* method = c->FindClassMethod(method_name, method_sig, pointer_size);
ASSERT_TRUE(method != nullptr) << method_name << " " << method_sig;
diff --git a/compiler/oat/jni_stub_hash_map_test.cc b/compiler/oat/jni_stub_hash_map_test.cc
index 2a26bcfae6..170381d988 100644
--- a/compiler/oat/jni_stub_hash_map_test.cc
+++ b/compiler/oat/jni_stub_hash_map_test.cc
@@ -88,8 +88,7 @@ class JniStubHashMapTest : public CommonCompilerTest {
Handle<mirror::ClassLoader> class_loader(
hs.NewHandle(soa.Decode<mirror::ClassLoader>(jclass_loader)));
pointer_size_ = class_linker_->GetImagePointerSize();
- ObjPtr<mirror::Class> klass =
- class_linker_->FindClass(soa.Self(), "LMyClassNatives;", class_loader);
+ ObjPtr<mirror::Class> klass = FindClass("LMyClassNatives;", class_loader);
ASSERT_TRUE(klass != nullptr);
jklass_ = soa.AddLocalReference<jclass>(klass);
}
diff --git a/compiler/optimizing/inliner.cc b/compiler/optimizing/inliner.cc
index 1375c36643..44af0d6b66 100644
--- a/compiler/optimizing/inliner.cc
+++ b/compiler/optimizing/inliner.cc
@@ -782,9 +782,10 @@ HInliner::InlineCacheType HInliner::GetInlineCacheAOT(
Thread* self = Thread::Current();
for (const dex::TypeIndex& type_index : dex_pc_data.classes) {
const DexFile* dex_file = caller_compilation_unit_.GetDexFile();
- const char* descriptor = pci->GetTypeDescriptor(dex_file, type_index);
- ObjPtr<mirror::Class> clazz =
- class_linker->FindClass(self, descriptor, caller_compilation_unit_.GetClassLoader());
+ size_t descriptor_length;
+ const char* descriptor = pci->GetTypeDescriptor(dex_file, type_index, &descriptor_length);
+ ObjPtr<mirror::Class> clazz = class_linker->FindClass(
+ self, descriptor, descriptor_length, caller_compilation_unit_.GetClassLoader());
if (clazz == nullptr) {
self->ClearException(); // Clean up the exception left by type resolution.
VLOG(compiler) << "Could not find class from inline cache in AOT mode "
diff --git a/dex2oat/driver/compiler_driver.cc b/dex2oat/driver/compiler_driver.cc
index 0491b2b797..bbb70e4ef1 100644
--- a/dex2oat/driver/compiler_driver.cc
+++ b/dex2oat/driver/compiler_driver.cc
@@ -750,7 +750,8 @@ static void EnsureVerifiedOrVerifyAtRuntime(jobject jclass_loader,
for (const DexFile* dex_file : dex_files) {
for (ClassAccessor accessor : dex_file->GetClasses()) {
- cls.Assign(class_linker->FindClass(soa.Self(), accessor.GetDescriptor(), class_loader));
+ cls.Assign(
+ class_linker->FindClass(soa.Self(), *dex_file, accessor.GetClassIdx(), class_loader));
if (cls == nullptr) {
soa.Self()->ClearException();
} else if (&cls->GetDexFile() == dex_file) {
@@ -1253,7 +1254,8 @@ void CompilerDriver::LoadImageClasses(TimingLogger* timings,
CHECK(image_classes != nullptr);
for (auto it = image_classes->begin(), end = image_classes->end(); it != end;) {
const std::string& descriptor(*it);
- ObjPtr<mirror::Class> klass = class_linker->FindClass(self, descriptor.c_str(), loader);
+ ObjPtr<mirror::Class> klass =
+ class_linker->FindClass(self, descriptor.c_str(), descriptor.length(), loader);
if (klass == nullptr) {
VLOG(compiler) << "Failed to find class " << descriptor;
it = image_classes->erase(it); // May cause some descriptors to be revisited.
@@ -1739,9 +1741,7 @@ class ResolveTypeVisitor : public CompilationVisitor {
}
// Check that the current class is not a subclass of java.lang.ClassLoader.
if (!hklass->IsInterface() &&
- hklass->IsSubClass(class_linker->FindClass(soa.Self(),
- "Ljava/lang/ClassLoader;",
- defining_class_loader))) {
+ hklass->IsSubClass(GetClassRoot<mirror::ClassLoader>(class_linker))) {
// Subclassing of java.lang.ClassLoader.
// This OptStat stuff is to enable logging from the APK scanner.
if (is_fatal) {
@@ -1806,16 +1806,15 @@ static void LoadAndUpdateStatus(const ClassAccessor& accessor,
Thread* self)
REQUIRES_SHARED(Locks::mutator_lock_) {
StackHandleScope<1> hs(self);
- const char* descriptor = accessor.GetDescriptor();
ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
Handle<mirror::Class> cls(hs.NewHandle<mirror::Class>(
- class_linker->FindClass(self, descriptor, class_loader)));
+ class_linker->FindClass(self, accessor.GetDexFile(), accessor.GetClassIdx(), class_loader)));
if (cls != nullptr) {
// Check that the class is resolved with the current dex file. We might get
// a boot image class, or a class in a different dex file for multidex, and
// we should not update the status in that case.
if (&cls->GetDexFile() == &accessor.GetDexFile()) {
- VLOG(compiler) << "Updating class status of " << std::string(descriptor) << " to " << status;
+ VLOG(compiler) << "Updating class status of " << accessor.GetDescriptor() << " to " << status;
ObjectLock<mirror::Class> lock(self, cls);
mirror::Class::SetStatus(cls, status, self);
}
@@ -1971,14 +1970,13 @@ class VerifyClassVisitor : public CompilationVisitor {
ScopedObjectAccess soa(Thread::Current());
const DexFile& dex_file = *manager_->GetDexFile();
const dex::ClassDef& class_def = dex_file.GetClassDef(class_def_index);
- const char* descriptor = dex_file.GetClassDescriptor(class_def);
ClassLinker* class_linker = manager_->GetClassLinker();
jobject jclass_loader = manager_->GetClassLoader();
StackHandleScope<3> hs(soa.Self());
Handle<mirror::ClassLoader> class_loader(
hs.NewHandle(soa.Decode<mirror::ClassLoader>(jclass_loader)));
- Handle<mirror::Class> klass(
- hs.NewHandle(class_linker->FindClass(soa.Self(), descriptor, class_loader)));
+ Handle<mirror::Class> klass = hs.NewHandle(
+ class_linker->FindClass(soa.Self(), dex_file, class_def.class_idx_, class_loader));
ClassReference ref(manager_->GetDexFile(), class_def_index);
verifier::FailureKind failure_kind;
if (klass == nullptr) {
@@ -2135,14 +2133,13 @@ class SetVerifiedClassVisitor : public CompilationVisitor {
ScopedObjectAccess soa(Thread::Current());
const DexFile& dex_file = *manager_->GetDexFile();
const dex::ClassDef& class_def = dex_file.GetClassDef(class_def_index);
- const char* descriptor = dex_file.GetClassDescriptor(class_def);
ClassLinker* class_linker = manager_->GetClassLinker();
jobject jclass_loader = manager_->GetClassLoader();
StackHandleScope<3> hs(soa.Self());
Handle<mirror::ClassLoader> class_loader(
hs.NewHandle(soa.Decode<mirror::ClassLoader>(jclass_loader)));
- Handle<mirror::Class> klass(
- hs.NewHandle(class_linker->FindClass(soa.Self(), descriptor, class_loader)));
+ Handle<mirror::Class> klass = hs.NewHandle(
+ class_linker->FindClass(soa.Self(), dex_file, class_def.class_idx_, class_loader));
// Class might have failed resolution. Then don't set it to verified.
if (klass != nullptr) {
// Only do this if the class is resolved. If even resolution fails, quickening will go very,
@@ -2197,15 +2194,13 @@ class InitializeClassVisitor : public CompilationVisitor {
jobject jclass_loader = manager_->GetClassLoader();
const DexFile& dex_file = *manager_->GetDexFile();
const dex::ClassDef& class_def = dex_file.GetClassDef(class_def_index);
- const dex::TypeId& class_type_id = dex_file.GetTypeId(class_def.class_idx_);
- const char* descriptor = dex_file.GetStringData(class_type_id.descriptor_idx_);
ScopedObjectAccess soa(Thread::Current());
StackHandleScope<3> hs(soa.Self());
Handle<mirror::ClassLoader> class_loader(
hs.NewHandle(soa.Decode<mirror::ClassLoader>(jclass_loader)));
- Handle<mirror::Class> klass(
- hs.NewHandle(manager_->GetClassLinker()->FindClass(soa.Self(), descriptor, class_loader)));
+ Handle<mirror::Class> klass = hs.NewHandle(manager_->GetClassLinker()->FindClass(
+ soa.Self(), dex_file, class_def.class_idx_, class_loader));
if (klass != nullptr) {
if (!SkipClass(manager_->GetClassLoader(), dex_file, klass.Get())) {
@@ -2329,8 +2324,8 @@ class InitializeClassVisitor : public CompilationVisitor {
// the transaction aborts and cannot resolve the type.
// TransactionAbortError is not initialized ant not in boot image, needed only by
// compiler and will be pruned by ImageWriter.
- Handle<mirror::Class> exception_class = hs.NewHandle(
- class_linker->FindClass(self, kTransactionAbortErrorDescriptor, class_loader));
+ Handle<mirror::Class> exception_class =
+ hs.NewHandle(class_linker->FindSystemClass(self, kTransactionAbortErrorDescriptor));
bool exception_initialized =
class_linker->EnsureInitialized(self, exception_class, true, true);
DCHECK(exception_initialized);
@@ -2695,8 +2690,8 @@ static void CompileDexFile(CompilerDriver* driver,
StackHandleScope<3> hs(soa.Self());
Handle<mirror::ClassLoader> class_loader(
hs.NewHandle(soa.Decode<mirror::ClassLoader>(jclass_loader)));
- Handle<mirror::Class> klass(
- hs.NewHandle(class_linker->FindClass(soa.Self(), accessor.GetDescriptor(), class_loader)));
+ Handle<mirror::Class> klass = hs.NewHandle(
+ class_linker->FindClass(soa.Self(), dex_file, class_def.class_idx_, class_loader));
Handle<mirror::DexCache> dex_cache;
if (klass == nullptr) {
soa.Self()->AssertPendingException();
diff --git a/dex2oat/driver/compiler_driver_test.cc b/dex2oat/driver/compiler_driver_test.cc
index 759426a1d3..7d4c32b25c 100644
--- a/dex2oat/driver/compiler_driver_test.cc
+++ b/dex2oat/driver/compiler_driver_test.cc
@@ -105,7 +105,7 @@ class CompilerDriverTest : public CommonCompilerDriverTest {
StackHandleScope<1> hs(soa.Self());
Handle<mirror::ClassLoader> loader(
hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader)));
- ObjPtr<mirror::Class> c = class_linker->FindClass(soa.Self(), descriptor, loader);
+ ObjPtr<mirror::Class> c = FindClass(descriptor, loader);
CHECK(c != nullptr);
const auto pointer_size = class_linker->GetImagePointerSize();
for (auto& m : c->GetMethods(pointer_size)) {
@@ -237,7 +237,7 @@ class CompilerDriverProfileTest : public CompilerDriverTest {
StackHandleScope<1> hs(self);
Handle<mirror::ClassLoader> h_loader(
hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader)));
- ObjPtr<mirror::Class> klass = class_linker->FindClass(self, clazz.c_str(), h_loader);
+ ObjPtr<mirror::Class> klass = FindClass(clazz.c_str(), h_loader);
ASSERT_NE(klass, nullptr);
const auto pointer_size = class_linker->GetImagePointerSize();
@@ -298,7 +298,7 @@ class CompilerDriverVerifyTest : public CompilerDriverTest {
StackHandleScope<1> hs(self);
Handle<mirror::ClassLoader> h_loader(
hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader)));
- ObjPtr<mirror::Class> klass = class_linker->FindClass(self, clazz.c_str(), h_loader);
+ ObjPtr<mirror::Class> klass = FindClass(clazz.c_str(), h_loader);
ASSERT_NE(klass, nullptr);
EXPECT_TRUE(klass->IsVerified());
diff --git a/dex2oat/interpreter/unstarted_runtime_transaction_test.cc b/dex2oat/interpreter/unstarted_runtime_transaction_test.cc
index ec308c2c18..a60da0657f 100644
--- a/dex2oat/interpreter/unstarted_runtime_transaction_test.cc
+++ b/dex2oat/interpreter/unstarted_runtime_transaction_test.cc
@@ -32,10 +32,8 @@ class UnstartedRuntimeTransactionTest : public CommonTransactionTestBase<Unstart
// Prepare for aborts. Aborts assume that the exception class is already resolved, as the
// loading code doesn't work under transactions.
void PrepareForAborts() REQUIRES_SHARED(Locks::mutator_lock_) {
- ObjPtr<mirror::Object> result = Runtime::Current()->GetClassLinker()->FindClass(
- Thread::Current(),
- kTransactionAbortErrorDescriptor,
- ScopedNullHandle<mirror::ClassLoader>());
+ ObjPtr<mirror::Object> result =
+ FindClass(kTransactionAbortErrorDescriptor, ScopedNullHandle<mirror::ClassLoader>());
CHECK(result != nullptr);
}
};
@@ -152,9 +150,7 @@ class UnstartedClassForNameTransactionTest : public UnstartedRuntimeTransactionT
// For transaction mode, we cannot load any classes, as the pre-fence initialization of
// classes isn't transactional. Load them ahead of time.
for (const char* name : kTestCases) {
- class_linker_->FindClass(self,
- DotToDescriptor(name).c_str(),
- ScopedNullHandle<mirror::ClassLoader>());
+ FindClass(DotToDescriptor(name).c_str(), ScopedNullHandle<mirror::ClassLoader>());
CHECK(!self->IsExceptionPending()) << self->GetException()->Dump();
}
diff --git a/dex2oat/linker/oat_writer_test.cc b/dex2oat/linker/oat_writer_test.cc
index a905294360..0a585edb53 100644
--- a/dex2oat/linker/oat_writer_test.cc
+++ b/dex2oat/linker/oat_writer_test.cc
@@ -460,9 +460,7 @@ TEST_F(OatTest, WriteRead) {
size_t num_virtual_methods = accessor.NumVirtualMethods();
const char* descriptor = accessor.GetDescriptor();
- ObjPtr<mirror::Class> klass = class_linker->FindClass(soa.Self(),
- descriptor,
- ScopedNullHandle<mirror::ClassLoader>());
+ ObjPtr<mirror::Class> klass = FindClass(descriptor, ScopedNullHandle<mirror::ClassLoader>());
const OatFile::OatClass oat_class = oat_dex_file->GetOatClass(accessor.GetClassDefIndex());
CHECK_EQ(ClassStatus::kNotReady, oat_class.GetStatus()) << descriptor;
diff --git a/dex2oat/transaction_test.cc b/dex2oat/transaction_test.cc
index 17a78ad6af..03ee7e98fa 100644
--- a/dex2oat/transaction_test.cc
+++ b/dex2oat/transaction_test.cc
@@ -59,14 +59,13 @@ class TransactionTest : public CommonTransactionTest {
ASSERT_TRUE(h_klass->IsInitialized());
// Load and verify utility class.
- h_klass.Assign(class_linker_->FindClass(soa.Self(), "LTransaction$AbortHelperClass;",
- class_loader));
+ h_klass.Assign(FindClass("LTransaction$AbortHelperClass;", class_loader));
ASSERT_TRUE(h_klass != nullptr);
class_linker_->VerifyClass(soa.Self(), /* verifier_deps= */ nullptr, h_klass);
ASSERT_TRUE(h_klass->IsVerified());
// Load and verify tested class.
- h_klass.Assign(class_linker_->FindClass(soa.Self(), tested_class_signature, class_loader));
+ h_klass.Assign(FindClass(tested_class_signature, class_loader));
ASSERT_TRUE(h_klass != nullptr);
class_linker_->VerifyClass(soa.Self(), /* verifier_deps= */ nullptr, h_klass);
ASSERT_TRUE(h_klass->IsVerified());
@@ -171,8 +170,7 @@ TEST_F(TransactionTest, StaticFieldsTest) {
hs.NewHandle(soa.Decode<mirror::ClassLoader>(LoadDex("Transaction"))));
ASSERT_TRUE(class_loader != nullptr);
- Handle<mirror::Class> h_klass(
- hs.NewHandle(class_linker_->FindClass(soa.Self(), "LStaticFieldsTest;", class_loader)));
+ Handle<mirror::Class> h_klass = hs.NewHandle(FindClass("LStaticFieldsTest;", class_loader));
ASSERT_TRUE(h_klass != nullptr);
bool success = class_linker_->EnsureInitialized(soa.Self(), h_klass, true, true);
ASSERT_TRUE(success);
@@ -267,8 +265,7 @@ TEST_F(TransactionTest, InstanceFieldsTest) {
hs.NewHandle(soa.Decode<mirror::ClassLoader>(LoadDex("Transaction"))));
ASSERT_TRUE(class_loader != nullptr);
- Handle<mirror::Class> h_klass(
- hs.NewHandle(class_linker_->FindClass(soa.Self(), "LInstanceFieldsTest;", class_loader)));
+ Handle<mirror::Class> h_klass = hs.NewHandle(FindClass("LInstanceFieldsTest;", class_loader));
ASSERT_TRUE(h_klass != nullptr);
bool success = class_linker_->EnsureInitialized(soa.Self(), h_klass, true, true);
ASSERT_TRUE(success);
@@ -419,8 +416,7 @@ TEST_F(TransactionTest, StaticArrayFieldsTest) {
hs.NewHandle(soa.Decode<mirror::ClassLoader>(LoadDex("Transaction"))));
ASSERT_TRUE(class_loader != nullptr);
- Handle<mirror::Class> h_klass(
- hs.NewHandle(class_linker_->FindClass(soa.Self(), "LStaticArrayFieldsTest;", class_loader)));
+ Handle<mirror::Class> h_klass = hs.NewHandle(FindClass("LStaticArrayFieldsTest;", class_loader));
ASSERT_TRUE(h_klass != nullptr);
bool success = class_linker_->EnsureInitialized(soa.Self(), h_klass, true, true);
ASSERT_TRUE(success);
@@ -542,9 +538,8 @@ TEST_F(TransactionTest, ResolveString) {
hs.NewHandle(soa.Decode<mirror::ClassLoader>(LoadDex("Transaction"))));
ASSERT_TRUE(class_loader != nullptr);
- Handle<mirror::Class> h_klass(
- hs.NewHandle(class_linker_->FindClass(soa.Self(), "LTransaction$ResolveString;",
- class_loader)));
+ Handle<mirror::Class> h_klass =
+ hs.NewHandle(FindClass("LTransaction$ResolveString;", class_loader));
ASSERT_TRUE(h_klass != nullptr);
Handle<mirror::DexCache> h_dex_cache(hs.NewHandle(h_klass->GetDexCache()));
@@ -608,7 +603,7 @@ TEST_F(MethodTypeTransactionTest, ResolveMethodType) {
class_linker_->EnsureInitialized(soa.Self(), h_klass, true, true);
ASSERT_TRUE(h_klass->IsInitialized());
- h_klass.Assign(class_linker_->FindClass(soa.Self(), "LTransaction;", class_loader));
+ h_klass.Assign(FindClass("LTransaction;", class_loader));
ASSERT_TRUE(h_klass != nullptr);
Handle<mirror::DexCache> h_dex_cache(hs.NewHandle(h_klass->GetDexCache()));
@@ -640,9 +635,8 @@ TEST_F(TransactionTest, EmptyClass) {
hs.NewHandle(soa.Decode<mirror::ClassLoader>(LoadDex("Transaction"))));
ASSERT_TRUE(class_loader != nullptr);
- Handle<mirror::Class> h_klass(
- hs.NewHandle(class_linker_->FindClass(soa.Self(), "LTransaction$EmptyStatic;",
- class_loader)));
+ Handle<mirror::Class> h_klass =
+ hs.NewHandle(FindClass("LTransaction$EmptyStatic;", class_loader));
ASSERT_TRUE(h_klass != nullptr);
class_linker_->VerifyClass(soa.Self(), /* verifier_deps= */ nullptr, h_klass);
ASSERT_TRUE(h_klass->IsVerified());
@@ -663,9 +657,8 @@ TEST_F(TransactionTest, StaticFieldClass) {
hs.NewHandle(soa.Decode<mirror::ClassLoader>(LoadDex("Transaction"))));
ASSERT_TRUE(class_loader != nullptr);
- Handle<mirror::Class> h_klass(
- hs.NewHandle(class_linker_->FindClass(soa.Self(), "LTransaction$StaticFieldClass;",
- class_loader)));
+ Handle<mirror::Class> h_klass =
+ hs.NewHandle(FindClass("LTransaction$StaticFieldClass;", class_loader));
ASSERT_TRUE(h_klass != nullptr);
class_linker_->VerifyClass(soa.Self(), /* verifier_deps= */ nullptr, h_klass);
ASSERT_TRUE(h_klass->IsVerified());
@@ -724,8 +717,8 @@ TEST_F(TransactionTest, Constraints) {
hs.NewHandle(soa.Decode<mirror::ClassLoader>(LoadDex("Transaction"))));
gc::Heap* heap = Runtime::Current()->GetHeap();
- Handle<mirror::Class> boolean_class = hs.NewHandle(
- class_linker_->FindClass(soa.Self(), "Ljava/lang/Boolean;", class_loader));
+ Handle<mirror::Class> boolean_class =
+ hs.NewHandle(FindClass("Ljava/lang/Boolean;", class_loader));
ASSERT_TRUE(boolean_class != nullptr);
ASSERT_TRUE(heap->ObjectIsInBootImageSpace(boolean_class.Get()));
ArtField* true_field = boolean_class->FindDeclaredStaticField("TRUE", "Ljava/lang/Boolean;");
@@ -738,23 +731,23 @@ TEST_F(TransactionTest, Constraints) {
ASSERT_TRUE(value_field != nullptr);
ASSERT_FALSE(value_field->IsStatic());
- Handle<mirror::Class> static_field_class(hs.NewHandle(
- class_linker_->FindClass(soa.Self(), "LTransaction$StaticFieldClass;", class_loader)));
+ Handle<mirror::Class> static_field_class =
+ hs.NewHandle(FindClass("LTransaction$StaticFieldClass;", class_loader));
ASSERT_TRUE(static_field_class != nullptr);
ASSERT_FALSE(heap->ObjectIsInBootImageSpace(static_field_class.Get()));
ArtField* int_field = static_field_class->FindDeclaredStaticField("intField", "I");
ASSERT_TRUE(int_field != nullptr);
- Handle<mirror::Class> static_fields_test_class(hs.NewHandle(
- class_linker_->FindClass(soa.Self(), "LStaticFieldsTest;", class_loader)));
+ Handle<mirror::Class> static_fields_test_class =
+ hs.NewHandle(FindClass("LStaticFieldsTest;", class_loader));
ASSERT_TRUE(static_fields_test_class != nullptr);
ASSERT_FALSE(heap->ObjectIsInBootImageSpace(static_fields_test_class.Get()));
ArtField* static_fields_test_int_field =
static_fields_test_class->FindDeclaredStaticField("intField", "I");
ASSERT_TRUE(static_fields_test_int_field != nullptr);
- Handle<mirror::Class> instance_fields_test_class(hs.NewHandle(
- class_linker_->FindClass(soa.Self(), "LInstanceFieldsTest;", class_loader)));
+ Handle<mirror::Class> instance_fields_test_class =
+ hs.NewHandle(FindClass("LInstanceFieldsTest;", class_loader));
ASSERT_TRUE(instance_fields_test_class != nullptr);
ASSERT_FALSE(heap->ObjectIsInBootImageSpace(instance_fields_test_class.Get()));
ArtField* instance_fields_test_int_field =
@@ -768,8 +761,7 @@ TEST_F(TransactionTest, Constraints) {
// The `long[].class` should be in the boot image but `long[][][].class` should not.
// (We have seen `long[][].class` both present and missing from the boot image,
// depending on the libcore code, so we do not use it for this test.)
- Handle<mirror::Class> long_array_dim3_class = hs.NewHandle(
- class_linker_->FindClass(soa.Self(), "[[[J", class_loader));
+ Handle<mirror::Class> long_array_dim3_class = hs.NewHandle(FindClass("[[[J", class_loader));
ASSERT_TRUE(long_array_dim3_class != nullptr);
ASSERT_FALSE(heap->ObjectIsInBootImageSpace(long_array_dim3_class.Get()));
ASSERT_TRUE(heap->ObjectIsInBootImageSpace(
diff --git a/dex2oat/verifier_deps_test.cc b/dex2oat/verifier_deps_test.cc
index a79bad2944..828691d3e2 100644
--- a/dex2oat/verifier_deps_test.cc
+++ b/dex2oat/verifier_deps_test.cc
@@ -80,7 +80,7 @@ class VerifierDepsTest : public CommonCompilerDriverTest {
Handle<mirror::ClassLoader> class_loader_handle(
hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader_)));
ObjPtr<mirror::Class> klass =
- class_linker_->FindClass(soa.Self(), name.c_str(), class_loader_handle);
+ class_linker_->FindClass(soa.Self(), name.c_str(), name.length(), class_loader_handle);
if (klass == nullptr) {
DCHECK(soa.Self()->IsExceptionPending());
soa.Self()->ClearException();
@@ -220,9 +220,8 @@ class VerifierDepsTest : public CommonCompilerDriverTest {
const std::vector<bool>& verified_classes = deps.GetVerifiedClasses(*dex_file);
ASSERT_EQ(verified_classes.size(), dex_file->NumClassDefs());
for (uint32_t i = 0; i < dex_file->NumClassDefs(); ++i) {
- const dex::ClassDef& class_def = dex_file->GetClassDef(i);
- const char* descriptor = dex_file->GetClassDescriptor(class_def);
- cls.Assign(class_linker_->FindClass(soa.Self(), descriptor, class_loader_handle));
+ cls.Assign(class_linker_->FindClass(
+ soa.Self(), *dex_file, dex_file->GetClassDef(i).class_idx_, class_loader_handle));
if (cls == nullptr) {
CHECK(soa.Self()->IsExceptionPending());
soa.Self()->ClearException();
@@ -273,8 +272,9 @@ class VerifierDepsTest : public CommonCompilerDriverTest {
for (auto& set : storage) {
for (auto& entry : set) {
std::string actual_destination =
- verifier_deps_->GetStringFromId(dex_file, entry.GetDestination());
- std::string actual_source = verifier_deps_->GetStringFromId(dex_file, entry.GetSource());
+ verifier_deps_->GetStringFromIndex(dex_file, entry.GetDestination());
+ std::string actual_source =
+ verifier_deps_->GetStringFromIndex(dex_file, entry.GetSource());
if ((expected_destination == actual_destination) && (expected_source == actual_source)) {
return true;
}
@@ -351,19 +351,19 @@ TEST_F(VerifierDepsTest, StringToId) {
dex::StringIndex id_Main1 = verifier_deps_->GetIdFromString(*primary_dex_file_, "LMain;");
ASSERT_LT(id_Main1.index_, primary_dex_file_->NumStringIds());
- ASSERT_EQ("LMain;", verifier_deps_->GetStringFromId(*primary_dex_file_, id_Main1));
+ ASSERT_STREQ("LMain;", verifier_deps_->GetStringFromIndex(*primary_dex_file_, id_Main1));
dex::StringIndex id_Main2 = verifier_deps_->GetIdFromString(*primary_dex_file_, "LMain;");
ASSERT_LT(id_Main2.index_, primary_dex_file_->NumStringIds());
- ASSERT_EQ("LMain;", verifier_deps_->GetStringFromId(*primary_dex_file_, id_Main2));
+ ASSERT_STREQ("LMain;", verifier_deps_->GetStringFromIndex(*primary_dex_file_, id_Main2));
dex::StringIndex id_Lorem1 = verifier_deps_->GetIdFromString(*primary_dex_file_, "Lorem ipsum");
ASSERT_GE(id_Lorem1.index_, primary_dex_file_->NumStringIds());
- ASSERT_EQ("Lorem ipsum", verifier_deps_->GetStringFromId(*primary_dex_file_, id_Lorem1));
+ ASSERT_STREQ("Lorem ipsum", verifier_deps_->GetStringFromIndex(*primary_dex_file_, id_Lorem1));
dex::StringIndex id_Lorem2 = verifier_deps_->GetIdFromString(*primary_dex_file_, "Lorem ipsum");
ASSERT_GE(id_Lorem2.index_, primary_dex_file_->NumStringIds());
- ASSERT_EQ("Lorem ipsum", verifier_deps_->GetStringFromId(*primary_dex_file_, id_Lorem2));
+ ASSERT_STREQ("Lorem ipsum", verifier_deps_->GetStringFromIndex(*primary_dex_file_, id_Lorem2));
ASSERT_EQ(id_Main1, id_Main2);
ASSERT_EQ(id_Lorem1, id_Lorem2);
diff --git a/libdexfile/dex/dex_file-inl.h b/libdexfile/dex/dex_file-inl.h
index ad6c8c31ba..a6ea97d705 100644
--- a/libdexfile/dex/dex_file-inl.h
+++ b/libdexfile/dex/dex_file-inl.h
@@ -46,12 +46,15 @@ inline int DexFile::CompareMemberNames(std::string_view lhs, std::string_view rh
return lhs.compare(rhs);
}
+inline size_t DexFile::Utf8Length(const char* utf8_data, size_t utf16_length) {
+ return LIKELY(utf8_data[utf16_length] == 0) // Is ASCII?
+ ? utf16_length
+ : utf16_length + strlen(utf8_data + utf16_length);
+}
+
inline std::string_view DexFile::StringViewFromUtf16Length(const char* utf8_data,
size_t utf16_length) {
- size_t utf8_length = LIKELY(utf8_data[utf16_length] == 0) // Is ASCII?
- ? utf16_length
- : utf16_length + strlen(utf8_data + utf16_length);
- return std::string_view(utf8_data, utf8_length);
+ return std::string_view(utf8_data, Utf8Length(utf8_data, utf16_length));
}
ALWAYS_INLINE
diff --git a/libdexfile/dex/dex_file.h b/libdexfile/dex/dex_file.h
index 6c41849616..619ee0d4f5 100644
--- a/libdexfile/dex/dex_file.h
+++ b/libdexfile/dex/dex_file.h
@@ -911,6 +911,7 @@ class DexFile {
static int CompareDescriptors(std::string_view lhs, std::string_view rhs);
static int CompareMemberNames(std::string_view lhs, std::string_view rhs);
+ static size_t Utf8Length(const char* utf8_data, size_t utf16_length);
static std::string_view StringViewFromUtf16Length(const char* utf8_data, size_t utf16_length);
protected:
diff --git a/libprofile/profile/profile_compilation_info.h b/libprofile/profile/profile_compilation_info.h
index f6b0105ff6..c8c325939c 100644
--- a/libprofile/profile/profile_compilation_info.h
+++ b/libprofile/profile/profile_compilation_info.h
@@ -33,7 +33,7 @@
#include "base/malloc_arena_pool.h"
#include "base/mem_map.h"
#include "base/safe_map.h"
-#include "dex/dex_file.h"
+#include "dex/dex_file-inl.h"
#include "dex/dex_file_types.h"
#include "dex/method_reference.h"
#include "dex/type_reference.h"
@@ -674,13 +674,25 @@ class ProfileCompilationInfo {
// Get type descriptor for a valid type index, whether a normal type index
// referencing a `dex::TypeId` in the dex file, or an artificial type index
// referencing an "extra descriptor".
- const char* GetTypeDescriptor(const DexFile* dex_file, dex::TypeIndex type_index) const {
+ const char* GetTypeDescriptor(const DexFile* dex_file,
+ dex::TypeIndex type_index,
+ /*out*/ size_t* utf8_length = nullptr) const {
DCHECK(type_index.IsValid());
uint32_t num_type_ids = dex_file->NumTypeIds();
if (type_index.index_ < num_type_ids) {
- return dex_file->GetTypeDescriptor(type_index);
+ uint32_t utf16_length;
+ const char* descriptor = dex_file->GetStringDataAndUtf16Length(
+ dex_file->GetTypeId(type_index).descriptor_idx_, &utf16_length);
+ if (utf8_length != nullptr) {
+ *utf8_length = DexFile::Utf8Length(descriptor, utf16_length);
+ }
+ return descriptor;
} else {
- return extra_descriptors_[type_index.index_ - num_type_ids].c_str();
+ const std::string& descriptor = extra_descriptors_[type_index.index_ - num_type_ids];
+ if (utf8_length != nullptr) {
+ *utf8_length = descriptor.length();
+ }
+ return descriptor.c_str();
}
}
diff --git a/oatdump/oatdump.cc b/oatdump/oatdump.cc
index 2c97f92636..feba70ff3a 100644
--- a/oatdump/oatdump.cc
+++ b/oatdump/oatdump.cc
@@ -2803,10 +2803,11 @@ class IMTDumper {
class_def_index != dex_file->NumClassDefs();
++class_def_index) {
const dex::ClassDef& class_def = dex_file->GetClassDef(class_def_index);
- const char* descriptor = dex_file->GetClassDescriptor(class_def);
- h_klass.Assign(class_linker->FindClass(self, descriptor, h_class_loader));
+ h_klass.Assign(
+ class_linker->FindClass(self, *dex_file, class_def.class_idx_, h_class_loader));
if (h_klass == nullptr) {
- std::cerr << "Warning: could not load " << descriptor << std::endl;
+ std::cerr << "Warning: could not load "
+ << dex_file->GetTypeDescriptor(class_def.class_idx_) << std::endl;
continue;
}
@@ -2929,8 +2930,8 @@ class IMTDumper {
descriptor = DotToDescriptor(class_name.c_str());
}
- ObjPtr<mirror::Class> klass =
- runtime->GetClassLinker()->FindClass(self, descriptor.c_str(), h_loader);
+ ObjPtr<mirror::Class> klass = runtime->GetClassLinker()->FindClass(
+ self, descriptor.c_str(), descriptor.length(), h_loader);
if (klass == nullptr) {
self->ClearException();
diff --git a/openjdkjvmti/ti_method.cc b/openjdkjvmti/ti_method.cc
index bf89b6e476..f9f043dbe5 100644
--- a/openjdkjvmti/ti_method.cc
+++ b/openjdkjvmti/ti_method.cc
@@ -1066,8 +1066,7 @@ class SetLocalVariableClosure : public CommonLocalVariableClosure {
art::ObjPtr<art::mirror::Class> set_class = caller_->DecodeJObject(val_.l)->GetClass();
art::ObjPtr<art::mirror::ClassLoader> loader =
method->GetDeclaringClass()->GetClassLoader();
- art::ObjPtr<art::mirror::Class> slot_class =
- cl->LookupClass(caller_, descriptor.c_str(), loader);
+ art::ObjPtr<art::mirror::Class> slot_class = cl->LookupClass(caller_, descriptor, loader);
DCHECK(!slot_class.IsNull()) << descriptor << " slot: " << slot_type;
return slot_class->IsAssignableFrom(set_class) ? OK : ERR(TYPE_MISMATCH);
}
diff --git a/profman/profile_assistant_test.cc b/profman/profile_assistant_test.cc
index 1e056f119d..8699a021f6 100644
--- a/profman/profile_assistant_test.cc
+++ b/profman/profile_assistant_test.cc
@@ -285,7 +285,7 @@ class ProfileAssistantTest : public CommonRuntimeTest, public ProfileTestHelper
StackHandleScope<1> hs(soa.Self());
Handle<mirror::ClassLoader> h_loader(hs.NewHandle(
ObjPtr<mirror::ClassLoader>::DownCast(soa.Self()->DecodeJObject(class_loader))));
- return class_linker->FindClass(soa.Self(), clazz.c_str(), h_loader);
+ return FindClass(clazz.c_str(), h_loader);
}
ArtMethod* GetVirtualMethod(jobject class_loader,
diff --git a/runtime/art_field-inl.h b/runtime/art_field-inl.h
index cbe38db80e..dd86e68164 100644
--- a/runtime/art_field-inl.h
+++ b/runtime/art_field-inl.h
@@ -371,7 +371,7 @@ inline bool ArtField::IsPrimitiveType() {
inline ObjPtr<mirror::Class> ArtField::LookupResolvedType() {
ScopedAssertNoThreadSuspension ants(__FUNCTION__);
if (UNLIKELY(IsProxyField())) {
- return ProxyFindSystemClass(GetTypeDescriptor());
+ return ProxyFindSystemClass(GetTypeDescriptorView());
}
ObjPtr<mirror::Class> type = Runtime::Current()->GetClassLinker()->LookupResolvedType(
GetDexFile()->GetFieldId(GetDexFieldIndex()).type_idx_, this);
@@ -381,7 +381,7 @@ inline ObjPtr<mirror::Class> ArtField::LookupResolvedType() {
inline ObjPtr<mirror::Class> ArtField::ResolveType() {
if (UNLIKELY(IsProxyField())) {
- return ProxyFindSystemClass(GetTypeDescriptor());
+ return ProxyFindSystemClass(GetTypeDescriptorView());
}
ObjPtr<mirror::Class> type = Runtime::Current()->GetClassLinker()->ResolveType(
GetDexFile()->GetFieldId(GetDexFieldIndex()).type_idx_, this);
diff --git a/runtime/art_field.cc b/runtime/art_field.cc
index 70d6d2ba94..b7b2a779fe 100644
--- a/runtime/art_field.cc
+++ b/runtime/art_field.cc
@@ -39,7 +39,7 @@ void ArtField::SetOffset(MemberOffset num_bytes) {
offset_ = num_bytes.Uint32Value();
}
-ObjPtr<mirror::Class> ArtField::ProxyFindSystemClass(const char* descriptor) {
+ObjPtr<mirror::Class> ArtField::ProxyFindSystemClass(std::string_view descriptor) {
DCHECK(IsProxyField());
ObjPtr<mirror::Class> klass = Runtime::Current()->GetClassLinker()->LookupClass(
Thread::Current(), descriptor, /* class_loader= */ nullptr);
diff --git a/runtime/art_field.h b/runtime/art_field.h
index 141de5650d..fd991cd53a 100644
--- a/runtime/art_field.h
+++ b/runtime/art_field.h
@@ -256,7 +256,7 @@ class EXPORT ArtField final {
private:
bool IsProxyField() REQUIRES_SHARED(Locks::mutator_lock_);
- ObjPtr<mirror::Class> ProxyFindSystemClass(const char* descriptor)
+ ObjPtr<mirror::Class> ProxyFindSystemClass(std::string_view descriptor)
REQUIRES_SHARED(Locks::mutator_lock_);
GcRoot<mirror::Class> declaring_class_;
diff --git a/runtime/class_linker-inl.h b/runtime/class_linker-inl.h
index 6461f54f5f..7d84fc1c09 100644
--- a/runtime/class_linker-inl.h
+++ b/runtime/class_linker-inl.h
@@ -25,7 +25,7 @@
#include "base/mutex.h"
#include "class_linker.h"
#include "class_table-inl.h"
-#include "dex/dex_file.h"
+#include "dex/dex_file-inl.h"
#include "dex/dex_file_structs.h"
#include "gc_root-inl.h"
#include "handle_scope-inl.h"
@@ -54,7 +54,8 @@ inline ObjPtr<mirror::Class> ClassLinker::FindArrayClass(Thread* self,
descriptor += element_class->GetDescriptor(&temp);
StackHandleScope<1> hs(Thread::Current());
Handle<mirror::ClassLoader> class_loader(hs.NewHandle(element_class->GetClassLoader()));
- ObjPtr<mirror::Class> array_class = FindClass(self, descriptor.c_str(), class_loader);
+ ObjPtr<mirror::Class> array_class =
+ FindClass(self, descriptor.c_str(), descriptor.length(), class_loader);
if (array_class != nullptr) {
// Benign races in storing array class and incrementing index.
size_t victim_index = find_array_class_cache_next_victim_;
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index 2d3217be2e..b4c2e4a54d 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -2878,8 +2878,9 @@ void ClassLinker::FinishCoreArrayClassSetup(ClassRoot array_root) {
ObjPtr<mirror::Class> array_class = GetClassRoot(array_root, this);
FinishArrayClassSetup(array_class);
- std::string temp;
- const char* descriptor = array_class->GetDescriptor(&temp);
+ std::string descriptor;
+ const char* raw_descriptor = array_class->GetDescriptor(&descriptor);
+ DCHECK(raw_descriptor == descriptor.c_str());
size_t hash = ComputeModifiedUtf8Hash(descriptor);
ObjPtr<mirror::Class> existing = InsertClass(descriptor, array_class, hash);
CHECK(existing == nullptr);
@@ -3243,18 +3244,31 @@ bool ClassLinker::FindClassInBaseDexClassLoaderClassPath(
}
ObjPtr<mirror::Class> ClassLinker::FindClass(Thread* self,
+ const DexFile& dex_file,
+ dex::TypeIndex type_index,
+ Handle<mirror::ClassLoader> class_loader) {
+ dex::StringIndex descriptor_idx = dex_file.GetTypeId(type_index).descriptor_idx_;
+ uint32_t utf16_length;
+ const char* descriptor = dex_file.GetStringDataAndUtf16Length(descriptor_idx, &utf16_length);
+ size_t descriptor_length = DexFile::Utf8Length(descriptor, utf16_length);
+ return FindClass(self, descriptor, descriptor_length, class_loader);
+}
+
+ObjPtr<mirror::Class> ClassLinker::FindClass(Thread* self,
const char* descriptor,
+ size_t descriptor_length,
Handle<mirror::ClassLoader> class_loader) {
- DCHECK_NE(*descriptor, '\0') << "descriptor is empty string";
+ DCHECK_EQ(strlen(descriptor), descriptor_length);
+ DCHECK_NE(descriptor_length, 0u) << "descriptor is empty string";
DCHECK(self != nullptr);
self->AssertNoPendingException();
self->PoisonObjectPointers(); // For DefineClass, CreateArrayClass, etc...
- if (descriptor[1] == '\0') {
+ if (descriptor_length == 1u) {
// only the descriptors of primitive types should be 1 character long, also avoid class lookup
// for primitive classes that aren't backed by dex files.
return FindPrimitiveClass(descriptor[0]);
}
- const std::string_view sv_descriptor(descriptor);
+ const std::string_view sv_descriptor(descriptor, descriptor_length);
const size_t hash = ComputeModifiedUtf8Hash(sv_descriptor);
// Find the class in the loaded classes table.
ObjPtr<mirror::Class> klass = LookupClass(self, sv_descriptor, hash, class_loader.Get());
@@ -3264,11 +3278,11 @@ ObjPtr<mirror::Class> ClassLinker::FindClass(Thread* self,
// Class is not yet loaded.
if (descriptor[0] != '[' && class_loader == nullptr) {
// Non-array class and the boot class loader, search the boot class path.
- ClassPathEntry pair = FindInClassPath(descriptor, hash, boot_class_path_);
+ ClassPathEntry pair = FindInClassPath(sv_descriptor, hash, boot_class_path_);
if (pair.second != nullptr) {
return DefineClass(self,
descriptor,
- sv_descriptor.length(),
+ descriptor_length,
hash,
ScopedNullHandle<mirror::ClassLoader>(),
*pair.first,
@@ -3286,14 +3300,14 @@ ObjPtr<mirror::Class> ClassLinker::FindClass(Thread* self,
ObjPtr<mirror::Class> result_ptr;
bool descriptor_equals;
if (descriptor[0] == '[') {
- result_ptr = CreateArrayClass(self, descriptor, hash, class_loader);
+ result_ptr = CreateArrayClass(self, descriptor, descriptor_length, hash, class_loader);
DCHECK_EQ(result_ptr == nullptr, self->IsExceptionPending());
DCHECK(result_ptr == nullptr || result_ptr->DescriptorEquals(sv_descriptor));
descriptor_equals = true;
} else {
ScopedObjectAccessUnchecked soa(self);
bool known_hierarchy = FindClassInBaseDexClassLoader(
- self, descriptor, sv_descriptor.length(), hash, class_loader, &result_ptr);
+ self, descriptor, descriptor_length, hash, class_loader, &result_ptr);
if (result_ptr != nullptr) {
// The chain was understood and we found the class. We still need to add the class to
// the class table to protect from racy programs that can try and redefine the path list
@@ -3329,13 +3343,13 @@ ObjPtr<mirror::Class> ClassLinker::FindClass(Thread* self,
// instead of "Ljava/lang/String;", the message below using the "dot" names would be
// "class loader [...] returned class java.lang.String instead of java.lang.String".
if (UNLIKELY(descriptor[0] != 'L') ||
- UNLIKELY(descriptor[sv_descriptor.length() - 1] != ';') ||
- UNLIKELY(memchr(descriptor + 1, '.', sv_descriptor.length() - 2) != nullptr)) {
+ UNLIKELY(descriptor[descriptor_length - 1] != ';') ||
+ UNLIKELY(memchr(descriptor + 1, '.', descriptor_length - 2) != nullptr)) {
ThrowNoClassDefFoundError("Invalid descriptor: %s.", descriptor);
return nullptr;
}
- std::string class_name_string(sv_descriptor.substr(1u, sv_descriptor.length() - 2u));
+ std::string class_name_string(sv_descriptor.substr(1u, descriptor_length - 2u));
std::replace(class_name_string.begin(), class_name_string.end(), '/', '.');
if (known_hierarchy &&
fast_class_not_found_exceptions_ &&
@@ -3580,11 +3594,11 @@ ObjPtr<mirror::Class> ClassLinker::DefineClass(Thread* self,
klass->SetIfTable(GetClassRoot<mirror::Object>(this)->GetIfTable());
// Add the newly loaded class to the loaded classes table.
- ObjPtr<mirror::Class> existing = InsertClass(descriptor, klass.Get(), hash);
+ ObjPtr<mirror::Class> existing = InsertClass(sv_descriptor, klass.Get(), hash);
if (existing != nullptr) {
// We failed to insert because we raced with another thread. Calling EnsureResolved may cause
// this thread to block.
- return sdc.Finish(EnsureResolved(self, descriptor, existing));
+ return sdc.Finish(EnsureResolved(self, sv_descriptor, existing));
}
// Load the fields and other things after we are inserted in the table. This is so that we don't
@@ -4585,7 +4599,7 @@ void ClassLinker::CreatePrimitiveClass(Thread* self,
DCHECK_EQ(primitive_class->NumMethods(), 0u);
// Primitive classes are initialized during single threaded startup, so visibly initialized.
primitive_class->SetStatusForPrimitiveOrArray(ClassStatus::kVisiblyInitialized);
- const char* descriptor = Primitive::Descriptor(type);
+ std::string_view descriptor(Primitive::Descriptor(type));
ObjPtr<mirror::Class> existing = InsertClass(descriptor,
primitive_class,
ComputeModifiedUtf8Hash(descriptor));
@@ -4612,10 +4626,12 @@ inline ObjPtr<mirror::IfTable> ClassLinker::GetArrayIfTable() {
// Returns null with an exception raised on failure.
ObjPtr<mirror::Class> ClassLinker::CreateArrayClass(Thread* self,
const char* descriptor,
+ size_t descriptor_length,
size_t hash,
Handle<mirror::ClassLoader> class_loader) {
// Identify the underlying component type
CHECK_EQ('[', descriptor[0]);
+ std::string_view sv_descriptor(descriptor, descriptor_length);
StackHandleScope<2> hs(self);
// This is to prevent the calls to ClassLoad and ClassPrepare which can cause java/user-supplied
@@ -4629,14 +4645,16 @@ ObjPtr<mirror::Class> ClassLinker::CreateArrayClass(Thread* self,
return nullptr;
}
- MutableHandle<mirror::Class> component_type(hs.NewHandle(FindClass(self, descriptor + 1,
- class_loader)));
+ MutableHandle<mirror::Class> component_type =
+ hs.NewHandle(FindClass(self, descriptor + 1, descriptor_length - 1, class_loader));
if (component_type == nullptr) {
DCHECK(self->IsExceptionPending());
// We need to accept erroneous classes as component types. Under AOT, we
// don't accept them as we cannot encode the erroneous class in an image.
- const size_t component_hash = ComputeModifiedUtf8Hash(descriptor + 1);
- component_type.Assign(LookupClass(self, descriptor + 1, component_hash, class_loader.Get()));
+ std::string_view component_descriptor = sv_descriptor.substr(1u);
+ const size_t component_hash = ComputeModifiedUtf8Hash(component_descriptor);
+ component_type.Assign(
+ LookupClass(self, component_descriptor, component_hash, class_loader.Get()));
if (component_type == nullptr || Runtime::Current()->IsAotCompiler()) {
DCHECK(self->IsExceptionPending());
return nullptr;
@@ -4667,7 +4685,7 @@ ObjPtr<mirror::Class> ClassLinker::CreateArrayClass(Thread* self,
// other threads.)
if (class_loader.Get() != component_type->GetClassLoader()) {
ObjPtr<mirror::Class> new_class =
- LookupClass(self, descriptor, hash, component_type->GetClassLoader());
+ LookupClass(self, sv_descriptor, hash, component_type->GetClassLoader());
if (new_class != nullptr) {
return new_class;
}
@@ -4711,7 +4729,7 @@ ObjPtr<mirror::Class> ClassLinker::CreateArrayClass(Thread* self,
return nullptr;
}
- ObjPtr<mirror::Class> existing = InsertClass(descriptor, new_class.Get(), hash);
+ ObjPtr<mirror::Class> existing = InsertClass(sv_descriptor, new_class.Get(), hash);
if (existing == nullptr) {
// We postpone ClassLoad and ClassPrepare events to this point in time to avoid
// duplicate events in case of races. Array classes don't really follow dedicated
@@ -5271,8 +5289,9 @@ ObjPtr<mirror::Class> ClassLinker::CreateProxyClass(ScopedObjectAccessAlreadyRun
// Object has an empty iftable, copy it for that reason.
temp_klass->SetIfTable(GetClassRoot<mirror::Object>(this)->GetIfTable());
mirror::Class::SetStatus(temp_klass, ClassStatus::kIdx, self);
- std::string storage;
- const char* descriptor = temp_klass->GetDescriptor(&storage);
+ std::string descriptor;
+ const char* raw_descriptor = temp_klass->GetDescriptor(&descriptor);
+ DCHECK(raw_descriptor == descriptor.c_str());
const size_t hash = ComputeModifiedUtf8Hash(descriptor);
// Needs to be before we insert the class so that the allocator field is set.
@@ -5396,7 +5415,7 @@ ObjPtr<mirror::Class> ClassLinker::CreateProxyClass(ScopedObjectAccessAlreadyRun
// The new class will replace the old one in the class table.
Handle<mirror::ObjectArray<mirror::Class>> h_interfaces(
hs.NewHandle(soa.Decode<mirror::ObjectArray<mirror::Class>>(interfaces)));
- if (!LinkClass(self, descriptor, temp_klass, h_interfaces, &klass)) {
+ if (!LinkClass(self, descriptor.c_str(), temp_klass, h_interfaces, &klass)) {
if (!temp_klass->IsErroneous()) {
mirror::Class::SetStatus(temp_klass, ClassStatus::kErrorUnresolved, self);
}
@@ -9910,7 +9929,7 @@ ObjPtr<mirror::Class> ClassLinker::DoLookupResolvedType(dex::TypeIndex type_idx,
ObjPtr<mirror::ClassLoader> class_loader) {
DCHECK(dex_cache->GetClassLoader() == class_loader);
const DexFile& dex_file = *dex_cache->GetDexFile();
- const char* descriptor = dex_file.GetTypeDescriptor(type_idx);
+ std::string_view descriptor = dex_file.GetTypeDescriptorView(type_idx);
ObjPtr<mirror::Class> type = LookupResolvedType(descriptor, class_loader);
if (type != nullptr) {
DCHECK(type->IsResolved());
@@ -9919,11 +9938,11 @@ ObjPtr<mirror::Class> ClassLinker::DoLookupResolvedType(dex::TypeIndex type_idx,
return type;
}
-ObjPtr<mirror::Class> ClassLinker::LookupResolvedType(const char* descriptor,
+ObjPtr<mirror::Class> ClassLinker::LookupResolvedType(std::string_view descriptor,
ObjPtr<mirror::ClassLoader> class_loader) {
- DCHECK_NE(*descriptor, '\0') << "descriptor is empty string";
+ DCHECK(!descriptor.empty()) << "descriptor is empty string";
ObjPtr<mirror::Class> type = nullptr;
- if (descriptor[1] == '\0') {
+ if (descriptor.length() == 1u) {
// only the descriptors of primitive types should be 1 character long, also avoid class lookup
// for primitive classes that aren't backed by dex files.
type = LookupPrimitiveClass(descriptor[0]);
@@ -9958,8 +9977,8 @@ ObjPtr<mirror::Class> ClassLinker::DoResolveType(dex::TypeIndex type_idx,
Handle<mirror::ClassLoader> class_loader) {
DCHECK(dex_cache->GetClassLoader() == class_loader.Get());
Thread* self = Thread::Current();
- const char* descriptor = dex_cache->GetDexFile()->GetTypeDescriptor(type_idx);
- ObjPtr<mirror::Class> resolved = FindClass(self, descriptor, class_loader);
+ const DexFile* dex_file = dex_cache->GetDexFile();
+ ObjPtr<mirror::Class> resolved = FindClass(self, *dex_file, type_idx, class_loader);
if (resolved != nullptr) {
// TODO: we used to throw here if resolved's class loader was not the
// boot class loader. This was to permit different classes with the
@@ -9967,14 +9986,15 @@ ObjPtr<mirror::Class> ClassLinker::DoResolveType(dex::TypeIndex type_idx,
dex_cache->SetResolvedType(type_idx, resolved);
} else {
CHECK(self->IsExceptionPending())
- << "Expected pending exception for failed resolution of: " << descriptor;
+ << "Expected pending exception for failed resolution of: "
+ << dex_file->GetTypeDescriptor(type_idx);
// Convert a ClassNotFoundException to a NoClassDefFoundError.
StackHandleScope<1> hs(self);
Handle<mirror::Throwable> cause(hs.NewHandle(self->GetException()));
if (cause->InstanceOf(GetClassRoot(ClassRoot::kJavaLangClassNotFoundException, this))) {
DCHECK(resolved == nullptr); // No Handle needed to preserve resolved.
self->ClearException();
- ThrowNoClassDefFoundError("Failed resolution of: %s", descriptor);
+ ThrowNoClassDefFoundError("Failed resolution of: %s", dex_file->GetTypeDescriptor(type_idx));
self->GetException()->SetCause(cause.Get());
}
}
diff --git a/runtime/class_linker.h b/runtime/class_linker.h
index ef8241ad2f..d1c82776cc 100644
--- a/runtime/class_linker.h
+++ b/runtime/class_linker.h
@@ -207,6 +207,15 @@ class ClassLinker {
// If class_loader is null, searches boot_class_path_.
EXPORT ObjPtr<mirror::Class> FindClass(Thread* self,
const char* descriptor,
+ size_t descriptor_length,
+ Handle<mirror::ClassLoader> class_loader)
+ REQUIRES_SHARED(Locks::mutator_lock_)
+ REQUIRES(!Locks::dex_lock_);
+
+ // Helper overload that retrieves the descriptor and its length from the `dex_file`.
+ EXPORT ObjPtr<mirror::Class> FindClass(Thread* self,
+ const DexFile& dex_file,
+ dex::TypeIndex type_index,
Handle<mirror::ClassLoader> class_loader)
REQUIRES_SHARED(Locks::mutator_lock_)
REQUIRES(!Locks::dex_lock_);
@@ -216,7 +225,7 @@ class ClassLinker {
ObjPtr<mirror::Class> FindSystemClass(Thread* self, const char* descriptor)
REQUIRES_SHARED(Locks::mutator_lock_)
REQUIRES(!Locks::dex_lock_) {
- return FindClass(self, descriptor, ScopedNullHandle<mirror::ClassLoader>());
+ return FindClass(self, descriptor, strlen(descriptor), ScopedNullHandle<mirror::ClassLoader>());
}
// Finds the array class given for the element class.
@@ -321,7 +330,7 @@ class ClassLinker {
REQUIRES_SHARED(Locks::mutator_lock_);
// Look up a resolved type with the given descriptor associated with the given ClassLoader.
- ObjPtr<mirror::Class> LookupResolvedType(const char* descriptor,
+ ObjPtr<mirror::Class> LookupResolvedType(std::string_view descriptor,
ObjPtr<mirror::ClassLoader> class_loader)
REQUIRES_SHARED(Locks::mutator_lock_);
@@ -1102,6 +1111,7 @@ class ClassLinker {
ObjPtr<mirror::Class> CreateArrayClass(Thread* self,
const char* descriptor,
+ size_t descriptor_length,
size_t hash,
Handle<mirror::ClassLoader> class_loader)
REQUIRES_SHARED(Locks::mutator_lock_)
diff --git a/runtime/class_linker_test.cc b/runtime/class_linker_test.cc
index 9c4e0289ae..d4fcefef27 100644
--- a/runtime/class_linker_test.cc
+++ b/runtime/class_linker_test.cc
@@ -181,8 +181,7 @@ class ClassLinkerTest : public CommonRuntimeTest {
Thread* self = Thread::Current();
StackHandleScope<2> hs(self);
Handle<mirror::ClassLoader> loader(hs.NewHandle(class_loader));
- Handle<mirror::Class> array(
- hs.NewHandle(class_linker_->FindClass(self, array_descriptor.c_str(), loader)));
+ Handle<mirror::Class> array = hs.NewHandle(FindClass(array_descriptor.c_str(), loader));
std::string temp;
EXPECT_STREQ(component_type.c_str(), array->GetComponentType()->GetDescriptor(&temp));
EXPECT_OBJ_PTR_EQ(loader.Get(), array->GetClassLoader());
@@ -912,13 +911,12 @@ TEST_F(ClassLinkerTest, FindClassNested) {
Handle<mirror::ClassLoader> class_loader(
hs.NewHandle(soa.Decode<mirror::ClassLoader>(LoadDex("Nested"))));
- ObjPtr<mirror::Class> outer = class_linker_->FindClass(soa.Self(), "LNested;", class_loader);
+ ObjPtr<mirror::Class> outer = FindClass("LNested;", class_loader);
ASSERT_TRUE(outer != nullptr);
EXPECT_EQ(0U, outer->NumVirtualMethods());
EXPECT_EQ(1U, outer->NumDirectMethods());
- ObjPtr<mirror::Class> inner =
- class_linker_->FindClass(soa.Self(), "LNested$Inner;", class_loader);
+ ObjPtr<mirror::Class> inner = FindClass("LNested$Inner;", class_loader);
ASSERT_TRUE(inner != nullptr);
EXPECT_EQ(0U, inner->NumVirtualMethods());
EXPECT_EQ(1U, inner->NumDirectMethods());
@@ -948,7 +946,7 @@ TEST_F(ClassLinkerTest, FindClass) {
Handle<mirror::ClassLoader> class_loader(
hs.NewHandle(soa.Decode<mirror::ClassLoader>(LoadDex("MyClass"))));
AssertNonExistentClass("LMyClass;");
- ObjPtr<mirror::Class> MyClass = class_linker_->FindClass(soa.Self(), "LMyClass;", class_loader);
+ ObjPtr<mirror::Class> MyClass = FindClass("LMyClass;", class_loader);
ASSERT_TRUE(MyClass != nullptr);
ASSERT_TRUE(MyClass->GetClass() != nullptr);
ASSERT_OBJ_PTR_EQ(MyClass->GetClass(), MyClass->GetClass()->GetClass());
@@ -997,7 +995,7 @@ TEST_F(ClassLinkerTest, LookupResolvedType) {
Handle<mirror::ClassLoader> class_loader(
hs.NewHandle(soa.Decode<mirror::ClassLoader>(LoadDex("MyClass"))));
AssertNonExistentClass("LMyClass;");
- ObjPtr<mirror::Class> klass = class_linker_->FindClass(soa.Self(), "LMyClass;", class_loader);
+ ObjPtr<mirror::Class> klass = FindClass("LMyClass;", class_loader);
dex::TypeIndex type_idx = klass->GetClassDef()->class_idx_;
ObjPtr<mirror::DexCache> dex_cache = klass->GetDexCache();
EXPECT_OBJ_PTR_EQ(
@@ -1017,8 +1015,7 @@ TEST_F(ClassLinkerTest, LookupResolvedTypeArray) {
Handle<mirror::ClassLoader> class_loader(
hs.NewHandle(soa.Decode<mirror::ClassLoader>(LoadDex("AllFields"))));
// Get the AllFields class for the dex cache and dex file.
- ObjPtr<mirror::Class> all_fields_klass
- = class_linker_->FindClass(soa.Self(), "LAllFields;", class_loader);
+ ObjPtr<mirror::Class> all_fields_klass = FindClass("LAllFields;", class_loader);
ASSERT_TRUE(all_fields_klass != nullptr);
Handle<mirror::DexCache> dex_cache = hs.NewHandle(all_fields_klass->GetDexCache());
const DexFile& dex_file = *dex_cache->GetDexFile();
@@ -1030,8 +1027,7 @@ TEST_F(ClassLinkerTest, LookupResolvedTypeArray) {
EXPECT_TRUE(
class_linker_->LookupResolvedType(array_idx, dex_cache.Get(), class_loader.Get()) == nullptr);
// Resolve the array class we want to test.
- ObjPtr<mirror::Class> array_klass
- = class_linker_->FindClass(soa.Self(), "[Ljava/lang/Object;", class_loader);
+ ObjPtr<mirror::Class> array_klass = FindClass("[Ljava/lang/Object;", class_loader);
ASSERT_TRUE(array_klass != nullptr);
// Test that LookupResolvedType() finds the array class.
EXPECT_OBJ_PTR_EQ(
@@ -1051,8 +1047,7 @@ TEST_F(ClassLinkerTest, LookupResolvedTypeErroneousInit) {
Handle<mirror::ClassLoader> class_loader(
hs.NewHandle(soa.Decode<mirror::ClassLoader>(LoadDex("ErroneousInit"))));
AssertNonExistentClass("LErroneousInit;");
- Handle<mirror::Class> klass =
- hs.NewHandle(class_linker_->FindClass(soa.Self(), "LErroneousInit;", class_loader));
+ Handle<mirror::Class> klass = hs.NewHandle(FindClass("LErroneousInit;", class_loader));
ASSERT_TRUE(klass != nullptr);
dex::TypeIndex type_idx = klass->GetClassDef()->class_idx_;
Handle<mirror::DexCache> dex_cache = hs.NewHandle(klass->GetDexCache());
@@ -1146,21 +1141,21 @@ TEST_F(ClassLinkerTest, ValidateBoxedTypes) {
ScopedObjectAccess soa(Thread::Current());
ScopedNullHandle<mirror::ClassLoader> class_loader;
ObjPtr<mirror::Class> c;
- c = class_linker_->FindClass(soa.Self(), "Ljava/lang/Boolean;", class_loader);
+ c = FindClass("Ljava/lang/Boolean;", class_loader);
EXPECT_STREQ("value", c->GetIFieldsPtr()->At(0).GetName());
- c = class_linker_->FindClass(soa.Self(), "Ljava/lang/Byte;", class_loader);
+ c = FindClass("Ljava/lang/Byte;", class_loader);
EXPECT_STREQ("value", c->GetIFieldsPtr()->At(0).GetName());
- c = class_linker_->FindClass(soa.Self(), "Ljava/lang/Character;", class_loader);
+ c = FindClass("Ljava/lang/Character;", class_loader);
EXPECT_STREQ("value", c->GetIFieldsPtr()->At(0).GetName());
- c = class_linker_->FindClass(soa.Self(), "Ljava/lang/Double;", class_loader);
+ c = FindClass("Ljava/lang/Double;", class_loader);
EXPECT_STREQ("value", c->GetIFieldsPtr()->At(0).GetName());
- c = class_linker_->FindClass(soa.Self(), "Ljava/lang/Float;", class_loader);
+ c = FindClass("Ljava/lang/Float;", class_loader);
EXPECT_STREQ("value", c->GetIFieldsPtr()->At(0).GetName());
- c = class_linker_->FindClass(soa.Self(), "Ljava/lang/Integer;", class_loader);
+ c = FindClass("Ljava/lang/Integer;", class_loader);
EXPECT_STREQ("value", c->GetIFieldsPtr()->At(0).GetName());
- c = class_linker_->FindClass(soa.Self(), "Ljava/lang/Long;", class_loader);
+ c = FindClass("Ljava/lang/Long;", class_loader);
EXPECT_STREQ("value", c->GetIFieldsPtr()->At(0).GetName());
- c = class_linker_->FindClass(soa.Self(), "Ljava/lang/Short;", class_loader);
+ c = FindClass("Ljava/lang/Short;", class_loader);
EXPECT_STREQ("value", c->GetIFieldsPtr()->At(0).GetName());
}
@@ -1171,10 +1166,8 @@ TEST_F(ClassLinkerTest, TwoClassLoadersOneClass) {
hs.NewHandle(soa.Decode<mirror::ClassLoader>(LoadDex("MyClass"))));
Handle<mirror::ClassLoader> class_loader_2(
hs.NewHandle(soa.Decode<mirror::ClassLoader>(LoadDex("MyClass"))));
- Handle<mirror::Class> MyClass_1 = hs.NewHandle(
- class_linker_->FindClass(soa.Self(), "LMyClass;", class_loader_1));
- ObjPtr<mirror::Class> MyClass_2 =
- class_linker_->FindClass(soa.Self(), "LMyClass;", class_loader_2);
+ Handle<mirror::Class> MyClass_1 = hs.NewHandle(FindClass("LMyClass;", class_loader_1));
+ ObjPtr<mirror::Class> MyClass_2 = FindClass("LMyClass;", class_loader_2);
EXPECT_TRUE(MyClass_1 != nullptr);
EXPECT_TRUE(MyClass_2 != nullptr);
EXPECT_OBJ_PTR_NE(MyClass_1.Get(), MyClass_2);
@@ -1185,8 +1178,7 @@ TEST_F(ClassLinkerTest, StaticFields) {
StackHandleScope<2> hs(soa.Self());
Handle<mirror::ClassLoader> class_loader(
hs.NewHandle(soa.Decode<mirror::ClassLoader>(LoadDex("Statics"))));
- Handle<mirror::Class> statics(
- hs.NewHandle(class_linker_->FindClass(soa.Self(), "LStatics;", class_loader)));
+ Handle<mirror::Class> statics = hs.NewHandle(FindClass("LStatics;", class_loader));
class_linker_->EnsureInitialized(soa.Self(), statics, true, true);
// Static final primitives that are initialized by a compile-time constant
@@ -1261,16 +1253,11 @@ TEST_F(ClassLinkerTest, Interfaces) {
StackHandleScope<6> hs(soa.Self());
Handle<mirror::ClassLoader> class_loader(
hs.NewHandle(soa.Decode<mirror::ClassLoader>(LoadDex("Interfaces"))));
- 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)));
+ Handle<mirror::Class> I = hs.NewHandle(FindClass("LInterfaces$I;", class_loader));
+ Handle<mirror::Class> J = hs.NewHandle(FindClass("LInterfaces$J;", class_loader));
+ Handle<mirror::Class> K = hs.NewHandle(FindClass("LInterfaces$K;", class_loader));
+ Handle<mirror::Class> A = hs.NewHandle(FindClass("LInterfaces$A;", class_loader));
+ Handle<mirror::Class> B = hs.NewHandle(FindClass("LInterfaces$B;", class_loader));
EXPECT_TRUE(I->IsAssignableFrom(A.Get()));
EXPECT_TRUE(J->IsAssignableFrom(A.Get()));
EXPECT_TRUE(J->IsAssignableFrom(K.Get()));
@@ -1336,8 +1323,7 @@ TEST_F(ClassLinkerTest, ResolveVerifyAndClinit) {
StackHandleScope<1> hs(soa.Self());
Handle<mirror::ClassLoader> class_loader(
hs.NewHandle(soa.Decode<mirror::ClassLoader>(jclass_loader)));
- ObjPtr<mirror::Class> klass =
- class_linker_->FindClass(soa.Self(), "LStaticsFromCode;", class_loader);
+ ObjPtr<mirror::Class> klass = FindClass("LStaticsFromCode;", class_loader);
ArtMethod* clinit = klass->FindClassInitializer(kRuntimePointerSize);
ArtMethod* getS0 =
klass->FindClassMethod("getS0", "()Ljava/lang/Object;", kRuntimePointerSize);
@@ -1370,7 +1356,7 @@ TEST_F(ClassLinkerTest, ErroneousClass) {
hs.NewHandle(soa.Decode<mirror::ClassLoader>(jclass_loader)));
hs.Self()->AssertNoPendingException();
const char* descriptor = "LErroneous;";
- ObjPtr<mirror::Class> klass = class_linker_->FindClass(soa.Self(), descriptor, class_loader);
+ ObjPtr<mirror::Class> klass = FindClass(descriptor, class_loader);
// Erronenous since we are extending final class.
hs.Self()->AssertPendingException();
EXPECT_TRUE(klass == nullptr);
@@ -1429,19 +1415,19 @@ TEST_F(ClassLinkerTest, ValidatePredefinedClassSizes) {
ScopedNullHandle<mirror::ClassLoader> class_loader;
ObjPtr<mirror::Class> c;
- c = class_linker_->FindClass(soa.Self(), "Ljava/lang/Class;", class_loader);
+ c = FindClass("Ljava/lang/Class;", class_loader);
ASSERT_TRUE(c != nullptr);
EXPECT_EQ(c->GetClassSize(), mirror::Class::ClassClassSize(kRuntimePointerSize));
- c = class_linker_->FindClass(soa.Self(), "Ljava/lang/Object;", class_loader);
+ c = FindClass("Ljava/lang/Object;", class_loader);
ASSERT_TRUE(c != nullptr);
EXPECT_EQ(c->GetClassSize(), mirror::Object::ClassSize(kRuntimePointerSize));
- c = class_linker_->FindClass(soa.Self(), "Ljava/lang/String;", class_loader);
+ c = FindClass("Ljava/lang/String;", class_loader);
ASSERT_TRUE(c != nullptr);
EXPECT_EQ(c->GetClassSize(), mirror::String::ClassSize(kRuntimePointerSize));
- c = class_linker_->FindClass(soa.Self(), "Ljava/lang/DexCache;", class_loader);
+ c = FindClass("Ljava/lang/DexCache;", class_loader);
ASSERT_TRUE(c != nullptr);
EXPECT_EQ(c->GetClassSize(), mirror::DexCache::ClassSize(kRuntimePointerSize));
}
@@ -1494,8 +1480,7 @@ TEST_F(ClassLinkerTest, Preverified_App) {
StackHandleScope<2> hs(soa.Self());
Handle<mirror::ClassLoader> class_loader(
hs.NewHandle(soa.Decode<mirror::ClassLoader>(LoadDex("Statics"))));
- Handle<mirror::Class> statics(
- hs.NewHandle(class_linker_->FindClass(soa.Self(), "LStatics;", class_loader)));
+ Handle<mirror::Class> statics = hs.NewHandle(FindClass("LStatics;", class_loader));
CheckVerificationAttempted(statics.Get(), false);
@@ -1517,8 +1502,7 @@ TEST_F(ClassLinkerTest, IsBootStrapClassLoaded) {
EXPECT_TRUE(jlo_class->IsBootStrapClassLoaded());
// Statics is not a bootstrap class.
- Handle<mirror::Class> statics(
- hs.NewHandle(class_linker_->FindClass(soa.Self(), "LStatics;", class_loader)));
+ Handle<mirror::Class> statics = hs.NewHandle(FindClass("LStatics;", class_loader));
ASSERT_TRUE(statics != nullptr);
EXPECT_FALSE(statics->IsBootStrapClassLoaded());
}
@@ -1568,8 +1552,7 @@ TEST_F(ClassLinkerMethodHandlesTest, TestResolveMethodTypes) {
Handle<mirror::ClassLoader> class_loader(
hs.NewHandle(soa.Decode<mirror::ClassLoader>(LoadDex("MethodTypes"))));
- Handle<mirror::Class> method_types(
- hs.NewHandle(class_linker_->FindClass(soa.Self(), "LMethodTypes;", class_loader)));
+ Handle<mirror::Class> method_types = hs.NewHandle(FindClass("LMethodTypes;", class_loader));
class_linker_->EnsureInitialized(soa.Self(), method_types, true, true);
ArtMethod* method1 = method_types->FindClassMethod(
@@ -1596,9 +1579,7 @@ TEST_F(ClassLinkerMethodHandlesTest, TestResolveMethodTypes) {
ASSERT_TRUE(method1_type != nullptr);
// Assert that the return type and the method arguments are as we expect.
- Handle<mirror::Class> string_class(hs.NewHandle(class_linker_->FindClass(soa.Self(),
- "Ljava/lang/String;",
- class_loader)));
+ Handle<mirror::Class> string_class = hs.NewHandle(FindClass("Ljava/lang/String;", class_loader));
ASSERT_OBJ_PTR_EQ(string_class.Get(), method1_type->GetRType());
ASSERT_OBJ_PTR_EQ(string_class.Get(), method1_type->GetPTypes()->Get(0));
@@ -1704,8 +1685,8 @@ class ClassLinkerClassLoaderTest : public ClassLinkerTest {
Handle<mirror::ClassLoader> class_loader_to_search(
hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader_to_search_obj)));
- Handle<mirror::Class> klass = hs.NewHandle(
- class_linker_->FindClass(soa.Self(), descriptor.c_str(), class_loader_to_search));
+ Handle<mirror::Class> klass =
+ hs.NewHandle(FindClass(descriptor.c_str(), class_loader_to_search));
if (!should_find) {
if (self->IsExceptionPending()) {
diff --git a/runtime/class_table_test.cc b/runtime/class_table_test.cc
index 15cca6dda9..88530bcec8 100644
--- a/runtime/class_table_test.cc
+++ b/runtime/class_table_test.cc
@@ -80,10 +80,8 @@ TEST_F(ClassTableTest, ClassTable) {
Handle<ClassLoader> class_loader(hs.NewHandle(soa.Decode<ClassLoader>(jclass_loader)));
const char* descriptor_x = "LX;";
const char* descriptor_y = "LY;";
- Handle<mirror::Class> h_X(
- hs.NewHandle(class_linker_->FindClass(soa.Self(), descriptor_x, class_loader)));
- Handle<mirror::Class> h_Y(
- hs.NewHandle(class_linker_->FindClass(soa.Self(), descriptor_y, class_loader)));
+ Handle<mirror::Class> h_X = hs.NewHandle(FindClass(descriptor_x, class_loader));
+ Handle<mirror::Class> h_Y = hs.NewHandle(FindClass(descriptor_y, class_loader));
Handle<mirror::Object> obj_X = hs.NewHandle(h_X->AllocObject(soa.Self()));
ASSERT_TRUE(obj_X != nullptr);
ClassTable table;
diff --git a/runtime/common_runtime_test.cc b/runtime/common_runtime_test.cc
index 165b3a9c8a..ab7ddbcb25 100644
--- a/runtime/common_runtime_test.cc
+++ b/runtime/common_runtime_test.cc
@@ -601,6 +601,12 @@ void CommonRuntimeTestImpl::GenerateProfile(ArrayRef<const std::string> dexes,
EXPECT_EQ(out_file->Flush(), 0);
}
+ObjPtr<mirror::Class> CommonRuntimeTestImpl::FindClass(
+ const char* descriptor,
+ Handle<mirror::ClassLoader> class_loader) const {
+ return class_linker_->FindClass(Thread::Current(), descriptor, strlen(descriptor), class_loader);
+}
+
CheckJniAbortCatcher::CheckJniAbortCatcher() : vm_(Runtime::Current()->GetJavaVM()) {
vm_->SetCheckJniAbortHook(Hook, &actual_);
}
diff --git a/runtime/common_runtime_test.h b/runtime/common_runtime_test.h
index 5416cb493c..7c20de30fd 100644
--- a/runtime/common_runtime_test.h
+++ b/runtime/common_runtime_test.h
@@ -190,6 +190,10 @@ class CommonRuntimeTestImpl : public CommonArtTestImpl {
dexes, out_file, method_frequency, type_frequency, /*for_boot_image=*/ true);
}
+ ObjPtr<mirror::Class> FindClass(const char* descriptor,
+ Handle<mirror::ClassLoader> class_loader) const
+ REQUIRES_SHARED(Locks::mutator_lock_);
+
std::unique_ptr<Runtime> runtime_;
// The class_linker_, java_lang_dex_file_, and boot_class_path_ are all
@@ -202,7 +206,7 @@ class CommonRuntimeTestImpl : public CommonArtTestImpl {
// This only looks into the current class loader and does not recurse into the parents.
std::vector<const DexFile*> GetDexFiles(jobject jclass_loader);
std::vector<const DexFile*> GetDexFiles(Thread* self, Handle<mirror::ClassLoader> class_loader)
- REQUIRES_SHARED(Locks::mutator_lock_);
+ REQUIRES_SHARED(Locks::mutator_lock_);
// Get the first dex file from a PathClassLoader. Will abort if it is null.
const DexFile* GetFirstDexFile(jobject jclass_loader);
diff --git a/runtime/fuzzer_corpus_test.cc b/runtime/fuzzer_corpus_test.cc
index 24edebcc20..6b312d5973 100644
--- a/runtime/fuzzer_corpus_test.cc
+++ b/runtime/fuzzer_corpus_test.cc
@@ -124,8 +124,8 @@ class FuzzerCorpusTest : public CommonRuntimeTest {
scope.NewHandle<art::mirror::DexCache>(nullptr));
for (art::ClassAccessor accessor : dex_file.GetClasses()) {
- const char* descriptor = accessor.GetDescriptor();
- h_klass.Assign(class_linker->FindClass(soa.Self(), descriptor, h_loader));
+ h_klass.Assign(
+ class_linker->FindClass(soa.Self(), dex_file, accessor.GetClassIdx(), h_loader));
// Ignore classes that couldn't be loaded since we are looking for crashes during
// class/method verification.
if (h_klass == nullptr || h_klass->IsErroneous()) {
diff --git a/runtime/gc/reference_queue_test.cc b/runtime/gc/reference_queue_test.cc
index 2b5c3fdea7..ce4f8d93b0 100644
--- a/runtime/gc/reference_queue_test.cc
+++ b/runtime/gc/reference_queue_test.cc
@@ -42,8 +42,7 @@ TEST_F(ReferenceQueueTest, EnqueueDequeue) {
ASSERT_TRUE(queue.IsEmpty());
ASSERT_EQ(queue.GetLength(), 0U);
auto ref_class = hs.NewHandle(
- Runtime::Current()->GetClassLinker()->FindClass(self, "Ljava/lang/ref/WeakReference;",
- ScopedNullHandle<mirror::ClassLoader>()));
+ FindClass("Ljava/lang/ref/WeakReference;", ScopedNullHandle<mirror::ClassLoader>()));
ASSERT_TRUE(ref_class != nullptr);
auto ref1(hs.NewHandle(ref_class->AllocObject(self)->AsReference()));
ASSERT_TRUE(ref1 != nullptr);
@@ -77,12 +76,10 @@ TEST_F(ReferenceQueueTest, Dump) {
queue.Dump(oss);
LOG(INFO) << oss.str();
auto weak_ref_class = hs.NewHandle(
- Runtime::Current()->GetClassLinker()->FindClass(self, "Ljava/lang/ref/WeakReference;",
- ScopedNullHandle<mirror::ClassLoader>()));
+ FindClass("Ljava/lang/ref/WeakReference;", ScopedNullHandle<mirror::ClassLoader>()));
ASSERT_TRUE(weak_ref_class != nullptr);
auto finalizer_ref_class = hs.NewHandle(
- Runtime::Current()->GetClassLinker()->FindClass(self, "Ljava/lang/ref/FinalizerReference;",
- ScopedNullHandle<mirror::ClassLoader>()));
+ FindClass("Ljava/lang/ref/FinalizerReference;", ScopedNullHandle<mirror::ClassLoader>()));
ASSERT_TRUE(finalizer_ref_class != nullptr);
auto ref1(hs.NewHandle(weak_ref_class->AllocObject(self)->AsReference()));
ASSERT_TRUE(ref1 != nullptr);
diff --git a/runtime/hidden_api_test.cc b/runtime/hidden_api_test.cc
index eff54bd861..b16c42f1a7 100644
--- a/runtime/hidden_api_test.cc
+++ b/runtime/hidden_api_test.cc
@@ -626,8 +626,8 @@ TEST_F(HiddenApiTest, CheckMemberSignatureForProxyClass) {
hs.NewHandle(soa.Decode<mirror::ClassLoader>(jclass_loader_)));
// Find interface we will create a proxy for.
- Handle<mirror::Class> h_iface(hs.NewHandle(
- class_linker_->FindClass(soa.Self(), "Lmypackage/packagea/Interface;", class_loader)));
+ Handle<mirror::Class> h_iface =
+ hs.NewHandle(FindClass("Lmypackage/packagea/Interface;", class_loader));
ASSERT_TRUE(h_iface != nullptr);
// Create the proxy class.
diff --git a/runtime/imtable_test.cc b/runtime/imtable_test.cc
index 9fed220f44..30c5c0b611 100644
--- a/runtime/imtable_test.cc
+++ b/runtime/imtable_test.cc
@@ -51,8 +51,7 @@ class ImTableTest : public CommonRuntimeTest {
// A.
h_class_loader.Assign(
ObjPtr<mirror::ClassLoader>::DownCast(self->DecodeJObject(jclass_loader_a)));
- Handle<mirror::Class> h_class_a(
- hs.NewHandle(class_linker->FindClass(self, class_name.c_str(), h_class_loader)));
+ Handle<mirror::Class> h_class_a = hs.NewHandle(FindClass(class_name.c_str(), h_class_loader));
if (h_class_a == nullptr) {
LOG(ERROR) << self->GetException()->Dump();
CHECK(false) << "h_class_a == nullptr";
@@ -61,8 +60,7 @@ class ImTableTest : public CommonRuntimeTest {
// B.
h_class_loader.Assign(
ObjPtr<mirror::ClassLoader>::DownCast(self->DecodeJObject(jclass_loader_b)));
- Handle<mirror::Class> h_class_b(
- hs.NewHandle(class_linker->FindClass(self, class_name.c_str(), h_class_loader)));
+ Handle<mirror::Class> h_class_b = hs.NewHandle(FindClass(class_name.c_str(), h_class_loader));
if (h_class_b == nullptr) {
LOG(ERROR) << self->GetException()->Dump();
CHECK(false) << "h_class_b == nullptr";
diff --git a/runtime/instrumentation_test.cc b/runtime/instrumentation_test.cc
index 664d3577be..e9fb0eafd2 100644
--- a/runtime/instrumentation_test.cc
+++ b/runtime/instrumentation_test.cc
@@ -491,7 +491,7 @@ TEST_F(InstrumentationTest, MethodEntryEvent) {
ClassLinker* class_linker = runtime->GetClassLinker();
StackHandleScope<1> hs(soa.Self());
Handle<mirror::ClassLoader> loader(hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader)));
- ObjPtr<mirror::Class> klass = class_linker->FindClass(soa.Self(), "LInstrumentation;", loader);
+ ObjPtr<mirror::Class> klass = FindClass("LInstrumentation;", loader);
ASSERT_TRUE(klass != nullptr);
ArtMethod* method =
klass->FindClassMethod("returnReference", "()Ljava/lang/Object;", kRuntimePointerSize);
@@ -512,7 +512,7 @@ TEST_F(InstrumentationTest, MethodExitObjectEvent) {
StackHandleScope<1> hs(soa.Self());
MutableHandle<mirror::ClassLoader> loader(
hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader)));
- ObjPtr<mirror::Class> klass = class_linker->FindClass(soa.Self(), "LInstrumentation;", loader);
+ ObjPtr<mirror::Class> klass = FindClass("LInstrumentation;", loader);
ASSERT_TRUE(klass != nullptr);
ArtMethod* method =
klass->FindClassMethod("returnReference", "()Ljava/lang/Object;", kRuntimePointerSize);
@@ -532,7 +532,7 @@ TEST_F(InstrumentationTest, MethodExitPrimEvent) {
ClassLinker* class_linker = runtime->GetClassLinker();
StackHandleScope<1> hs(soa.Self());
Handle<mirror::ClassLoader> loader(hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader)));
- ObjPtr<mirror::Class> klass = class_linker->FindClass(soa.Self(), "LInstrumentation;", loader);
+ ObjPtr<mirror::Class> klass = FindClass("LInstrumentation;", loader);
ASSERT_TRUE(klass != nullptr);
ArtMethod* method = klass->FindClassMethod("returnPrimitive", "()I", kRuntimePointerSize);
ASSERT_TRUE(method != nullptr);
@@ -567,7 +567,7 @@ TEST_F(InstrumentationTest, FieldWriteObjectEvent) {
ClassLinker* class_linker = runtime->GetClassLinker();
StackHandleScope<1> hs(soa.Self());
Handle<mirror::ClassLoader> loader(hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader)));
- ObjPtr<mirror::Class> klass = class_linker->FindClass(soa.Self(), "LInstrumentation;", loader);
+ ObjPtr<mirror::Class> klass = FindClass("LInstrumentation;", loader);
ASSERT_TRUE(klass != nullptr);
ArtField* field = klass->FindDeclaredStaticField("referenceField", "Ljava/lang/Object;");
ASSERT_TRUE(field != nullptr);
@@ -585,7 +585,7 @@ TEST_F(InstrumentationTest, FieldWritePrimEvent) {
ClassLinker* class_linker = runtime->GetClassLinker();
StackHandleScope<1> hs(soa.Self());
Handle<mirror::ClassLoader> loader(hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader)));
- ObjPtr<mirror::Class> klass = class_linker->FindClass(soa.Self(), "LInstrumentation;", loader);
+ ObjPtr<mirror::Class> klass = FindClass("LInstrumentation;", loader);
ASSERT_TRUE(klass != nullptr);
ArtField* field = klass->FindDeclaredStaticField("primitiveField", "I");
ASSERT_TRUE(field != nullptr);
@@ -616,7 +616,7 @@ TEST_F(InstrumentationTest, DeoptimizeDirectMethod) {
ClassLinker* class_linker = runtime->GetClassLinker();
StackHandleScope<1> hs(soa.Self());
Handle<mirror::ClassLoader> loader(hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader)));
- ObjPtr<mirror::Class> klass = class_linker->FindClass(soa.Self(), "LInstrumentation;", loader);
+ ObjPtr<mirror::Class> klass = FindClass("LInstrumentation;", loader);
ASSERT_TRUE(klass != nullptr);
ArtMethod* method_to_deoptimize =
klass->FindClassMethod("instanceMethod", "()V", kRuntimePointerSize);
@@ -666,7 +666,7 @@ TEST_F(InstrumentationTest, MixedDeoptimization) {
ClassLinker* class_linker = runtime->GetClassLinker();
StackHandleScope<1> hs(soa.Self());
Handle<mirror::ClassLoader> loader(hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader)));
- ObjPtr<mirror::Class> klass = class_linker->FindClass(soa.Self(), "LInstrumentation;", loader);
+ ObjPtr<mirror::Class> klass = FindClass("LInstrumentation;", loader);
ASSERT_TRUE(klass != nullptr);
ArtMethod* method_to_deoptimize =
klass->FindClassMethod("instanceMethod", "()V", kRuntimePointerSize);
diff --git a/runtime/interpreter/unstarted_runtime.cc b/runtime/interpreter/unstarted_runtime.cc
index db4ff095ef..9149f3a6c2 100644
--- a/runtime/interpreter/unstarted_runtime.cc
+++ b/runtime/interpreter/unstarted_runtime.cc
@@ -142,7 +142,8 @@ static void UnstartedRuntimeFindClass(Thread* self,
std::string descriptor(DotToDescriptor(className->ToModifiedUtf8().c_str()));
ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
- ObjPtr<mirror::Class> found = class_linker->FindClass(self, descriptor.c_str(), class_loader);
+ ObjPtr<mirror::Class> found =
+ class_linker->FindClass(self, descriptor.c_str(), descriptor.length(), class_loader);
if (found != nullptr && !found->CheckIsVisibleWithTargetSdk(self)) {
CHECK(self->IsExceptionPending());
return;
@@ -626,9 +627,7 @@ static void GetResourceAsStream(Thread* self,
// Create a ByteArrayInputStream.
Handle<mirror::Class> h_class(hs.NewHandle(
- runtime->GetClassLinker()->FindClass(self,
- "Ljava/io/ByteArrayInputStream;",
- ScopedNullHandle<mirror::ClassLoader>())));
+ runtime->GetClassLinker()->FindSystemClass(self, "Ljava/io/ByteArrayInputStream;")));
if (h_class == nullptr) {
AbortTransactionOrFail(self, "Could not find ByteArrayInputStream class");
return;
@@ -1015,9 +1014,7 @@ static void GetSystemProperty(Thread* self,
// Get the storage class.
ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
Handle<mirror::Class> h_props_class(hs.NewHandle(
- class_linker->FindClass(self,
- "Ljava/lang/AndroidHardcodedSystemProperties;",
- ScopedNullHandle<mirror::ClassLoader>())));
+ class_linker->FindSystemClass(self, "Ljava/lang/AndroidHardcodedSystemProperties;")));
if (h_props_class == nullptr) {
AbortTransactionOrFail(self, "Could not find AndroidHardcodedSystemProperties");
return;
@@ -1124,8 +1121,7 @@ static ObjPtr<mirror::Object> CreateInstanceOf(Thread* self, const char* class_d
REQUIRES_SHARED(Locks::mutator_lock_) {
// Find the requested class.
ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
- ObjPtr<mirror::Class> klass =
- class_linker->FindClass(self, class_descriptor, ScopedNullHandle<mirror::ClassLoader>());
+ ObjPtr<mirror::Class> klass = class_linker->FindSystemClass(self, class_descriptor);
if (klass == nullptr) {
AbortTransactionOrFail(self, "Could not load class %s", class_descriptor);
return nullptr;
@@ -1156,8 +1152,9 @@ void UnstartedRuntime::UnstartedThreadLocalGet(Thread* self,
ShadowFrame* shadow_frame,
JValue* result,
[[maybe_unused]] size_t arg_offset) {
- if (CheckCallers(shadow_frame, { "jdk.internal.math.FloatingDecimal$BinaryToASCIIBuffer "
- "jdk.internal.math.FloatingDecimal.getBinaryToASCIIBuffer()" })) {
+ if (CheckCallers(shadow_frame,
+ { "jdk.internal.math.FloatingDecimal$BinaryToASCIIBuffer "
+ "jdk.internal.math.FloatingDecimal.getBinaryToASCIIBuffer()" })) {
result->SetL(CreateInstanceOf(self, "Ljdk/internal/math/FloatingDecimal$BinaryToASCIIBuffer;"));
} else {
AbortTransactionOrFail(self,
diff --git a/runtime/interpreter/unstarted_runtime_test.cc b/runtime/interpreter/unstarted_runtime_test.cc
index cf7782dcdc..1f5f111c59 100644
--- a/runtime/interpreter/unstarted_runtime_test.cc
+++ b/runtime/interpreter/unstarted_runtime_test.cc
@@ -784,7 +784,7 @@ TEST_F(UnstartedRuntimeTest, IsAnonymousClass) {
StackHandleScope<1> hs(soa.Self());
Handle<mirror::ClassLoader> loader(
hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader)));
- ObjPtr<mirror::Class> c = class_linker_->FindClass(soa.Self(), "LNested$1;", loader);
+ ObjPtr<mirror::Class> c = FindClass("LNested$1;", loader);
ASSERT_TRUE(c != nullptr);
shadow_frame->SetVRegReference(0, c);
UnstartedClassIsAnonymousClass(self, shadow_frame.get(), &result, 0);
@@ -803,12 +803,9 @@ TEST_F(UnstartedRuntimeTest, GetDeclaringClass) {
Handle<mirror::ClassLoader> loader(
hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader)));
- Handle<mirror::Class> nested_klass(hs.NewHandle(
- class_linker_->FindClass(soa.Self(), "LNested;", loader)));
- Handle<mirror::Class> inner_klass(hs.NewHandle(
- class_linker_->FindClass(soa.Self(), "LNested$Inner;", loader)));
- Handle<mirror::Class> anon_klass(hs.NewHandle(
- class_linker_->FindClass(soa.Self(), "LNested$1;", loader)));
+ Handle<mirror::Class> nested_klass = hs.NewHandle(FindClass("LNested;", loader));
+ Handle<mirror::Class> inner_klass = hs.NewHandle(FindClass("LNested$Inner;", loader));
+ Handle<mirror::Class> anon_klass = hs.NewHandle(FindClass("LNested$1;", loader));
shadow_frame->SetVRegReference(0, nested_klass.Get());
UnstartedClassGetDeclaringClass(self, shadow_frame.get(), &result, 0);
@@ -835,9 +832,7 @@ TEST_F(UnstartedRuntimeTest, ThreadLocalGet) {
// Positive test. See that We get something for float conversion.
{
Handle<mirror::Class> floating_decimal = hs.NewHandle(
- class_linker_->FindClass(self,
- "Ljdk/internal/math/FloatingDecimal;",
- ScopedNullHandle<mirror::ClassLoader>()));
+ FindClass("Ljdk/internal/math/FloatingDecimal;", ScopedNullHandle<mirror::ClassLoader>()));
ASSERT_TRUE(floating_decimal != nullptr);
ASSERT_TRUE(class_linker_->EnsureInitialized(self, floating_decimal, true, true));
@@ -865,10 +860,8 @@ TEST_F(UnstartedRuntimeTest, FloatConversion) {
ScopedObjectAccess soa(self);
StackHandleScope<1> hs(self);
- Handle<mirror::Class> double_class = hs.NewHandle(
- class_linker_->FindClass(self,
- "Ljava/lang/Double;",
- ScopedNullHandle<mirror::ClassLoader>()));
+ Handle<mirror::Class> double_class =
+ hs.NewHandle(FindClass("Ljava/lang/Double;", ScopedNullHandle<mirror::ClassLoader>()));
ASSERT_TRUE(double_class != nullptr);
ASSERT_TRUE(class_linker_->EnsureInitialized(self, double_class, true, true));
@@ -905,8 +898,8 @@ TEST_F(UnstartedRuntimeTest, LogManager) {
ScopedObjectAccess soa(self);
StackHandleScope<1> hs(self);
- Handle<mirror::Class> log_manager_class = hs.NewHandle(class_linker_->FindClass(
- self, "Ljava/util/logging/LogManager;", ScopedNullHandle<mirror::ClassLoader>()));
+ Handle<mirror::Class> log_manager_class = hs.NewHandle(
+ FindClass("Ljava/util/logging/LogManager;", ScopedNullHandle<mirror::ClassLoader>()));
ASSERT_TRUE(log_manager_class.Get() != nullptr);
ASSERT_TRUE(class_linker_->EnsureInitialized(self, log_manager_class, true, true));
}
@@ -991,10 +984,8 @@ TEST_F(UnstartedRuntimeTest, ClassGetSignatureAnnotation) {
ScopedObjectAccess soa(self);
StackHandleScope<1> hs(self);
- Handle<mirror::Class> list_class = hs.NewHandle(
- class_linker_->FindClass(self,
- "Ljava/util/List;",
- ScopedNullHandle<mirror::ClassLoader>()));
+ Handle<mirror::Class> list_class =
+ hs.NewHandle(FindClass("Ljava/util/List;", ScopedNullHandle<mirror::ClassLoader>()));
ASSERT_TRUE(list_class.Get() != nullptr);
ASSERT_TRUE(class_linker_->EnsureInitialized(self, list_class, true, true));
diff --git a/runtime/interpreter/unstarted_runtime_test.h b/runtime/interpreter/unstarted_runtime_test.h
index 465a4268ea..eb0a28aaec 100644
--- a/runtime/interpreter/unstarted_runtime_test.h
+++ b/runtime/interpreter/unstarted_runtime_test.h
@@ -85,8 +85,8 @@ class UnstartedRuntimeTestBase : public CommonRuntimeTest {
StackHandleScope<2> hs(self);
// Create the fake boot classloader. Any instance is fine, they are technically interchangeable.
- Handle<mirror::Class> boot_cp_class = hs.NewHandle(class_linker_->FindClass(
- self, "Ljava/lang/BootClassLoader;", ScopedNullHandle<mirror::ClassLoader>()));
+ Handle<mirror::Class> boot_cp_class = hs.NewHandle(
+ FindClass("Ljava/lang/BootClassLoader;", ScopedNullHandle<mirror::ClassLoader>()));
CHECK(boot_cp_class != nullptr);
CHECK(class_linker_->EnsureInitialized(
self, boot_cp_class, /*can_init_fields=*/ true, /*can_init_parents=*/ true));
diff --git a/runtime/jit/jit.cc b/runtime/jit/jit.cc
index 66fc1e639a..c8e274a846 100644
--- a/runtime/jit/jit.cc
+++ b/runtime/jit/jit.cc
@@ -803,15 +803,17 @@ class ZygoteVerificationTask final : public Task {
const std::vector<const DexFile*>& boot_class_path =
runtime->GetClassLinker()->GetBootClassPath();
ScopedObjectAccess soa(self);
- StackHandleScope<1> hs(self);
+ StackHandleScope<2> hs(self);
+ MutableHandle<mirror::DexCache> dex_cache = hs.NewHandle<mirror::DexCache>(nullptr);
MutableHandle<mirror::Class> klass = hs.NewHandle<mirror::Class>(nullptr);
uint64_t start_ns = ThreadCpuNanoTime();
uint64_t number_of_classes = 0;
for (const DexFile* dex_file : boot_class_path) {
+ dex_cache.Assign(linker->FindDexCache(self, *dex_file));
for (uint32_t i = 0; i < dex_file->NumClassDefs(); ++i) {
const dex::ClassDef& class_def = dex_file->GetClassDef(i);
- const char* descriptor = dex_file->GetClassDescriptor(class_def);
- klass.Assign(linker->LookupResolvedType(descriptor, /* class_loader= */ nullptr));
+ klass.Assign(linker->LookupResolvedType(
+ class_def.class_idx_, dex_cache.Get(), /* class_loader= */ nullptr));
if (klass == nullptr) {
// Class not loaded yet.
DCHECK(!self->IsExceptionPending());
diff --git a/runtime/jit/profiling_info_test.cc b/runtime/jit/profiling_info_test.cc
index 9b91c28ac5..41f75b87fc 100644
--- a/runtime/jit/profiling_info_test.cc
+++ b/runtime/jit/profiling_info_test.cc
@@ -46,15 +46,14 @@ class ProfileCompilationInfoTest : public CommonRuntimeTest {
}
protected:
- std::vector<ArtMethod*> GetVirtualMethods(jobject class_loader,
- const std::string& clazz) {
+ std::vector<ArtMethod*> GetVirtualMethods(jobject class_loader, const char* clazz) {
ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
Thread* self = Thread::Current();
ScopedObjectAccess soa(self);
StackHandleScope<1> hs(self);
Handle<mirror::ClassLoader> h_loader(
hs.NewHandle(self->DecodeJObject(class_loader)->AsClassLoader()));
- ObjPtr<mirror::Class> klass = class_linker->FindClass(self, clazz.c_str(), h_loader);
+ ObjPtr<mirror::Class> klass = FindClass(clazz, h_loader);
const auto pointer_size = class_linker->GetImagePointerSize();
std::vector<ArtMethod*> methods;
diff --git a/runtime/jni/jni_internal.cc b/runtime/jni/jni_internal.cc
index 51350dc713..f1ea88da4e 100644
--- a/runtime/jni/jni_internal.cc
+++ b/runtime/jni/jni_internal.cc
@@ -535,7 +535,7 @@ ArtField* FindFieldJNI(const ScopedObjectAccess& soa,
DCHECK(field == nullptr);
} else if (sig[1] != '\0') {
Handle<mirror::ClassLoader> class_loader(hs.NewHandle(c->GetClassLoader()));
- field_type = class_linker->FindClass(soa.Self(), sig, class_loader);
+ field_type = class_linker->FindClass(soa.Self(), sig, strlen(sig), class_loader);
} else {
field_type = class_linker->FindPrimitiveClass(*sig);
}
@@ -675,14 +675,11 @@ class JNI {
ClassLinker* class_linker = runtime->GetClassLinker();
std::string descriptor(NormalizeJniClassDescriptor(name));
ScopedObjectAccess soa(env);
- ObjPtr<mirror::Class> c = nullptr;
- if (runtime->IsStarted()) {
- StackHandleScope<1> hs(soa.Self());
- Handle<mirror::ClassLoader> class_loader(hs.NewHandle(GetClassLoader<kEnableIndexIds>(soa)));
- c = class_linker->FindClass(soa.Self(), descriptor.c_str(), class_loader);
- } else {
- c = class_linker->FindSystemClass(soa.Self(), descriptor.c_str());
- }
+ StackHandleScope<1> hs(soa.Self());
+ Handle<mirror::ClassLoader> class_loader = hs.NewHandle(
+ runtime->IsStarted() ? GetClassLoader<kEnableIndexIds>(soa) : nullptr);
+ ObjPtr<mirror::Class> c = class_linker->FindClass(
+ soa.Self(), descriptor.c_str(), descriptor.length(), class_loader);
return soa.AddLocalReference<jclass>(c);
}
diff --git a/runtime/jni/jni_internal_test.cc b/runtime/jni/jni_internal_test.cc
index ed97e4d4c8..6115556940 100644
--- a/runtime/jni/jni_internal_test.cc
+++ b/runtime/jni/jni_internal_test.cc
@@ -624,7 +624,7 @@ class JniInternalTest : public CommonRuntimeTest {
StackHandleScope<1> hs(soa.Self());
Handle<mirror::ClassLoader> loader(
hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader_)));
- ObjPtr<mirror::Class> c = class_linker_->FindClass(soa.Self(), "LMyClassNatives;", loader);
+ ObjPtr<mirror::Class> c = FindClass("LMyClassNatives;", loader);
const auto pointer_size = class_linker_->GetImagePointerSize();
ArtMethod* method = c->FindClassMethod(method_name, method_sig, pointer_size);
ASSERT_TRUE(method != nullptr) << method_name << " " << method_sig;
diff --git a/runtime/mirror/class_ext.cc b/runtime/mirror/class_ext.cc
index 49177aca02..b4ab2dc26a 100644
--- a/runtime/mirror/class_ext.cc
+++ b/runtime/mirror/class_ext.cc
@@ -84,9 +84,7 @@ bool ClassExt::ExtendObsoleteArrays(Handle<ClassExt> h_this, Thread* self, uint3
}
Handle<ObjectArray<DexCache>> new_dex_caches(hs.NewHandle<ObjectArray<DexCache>>(
ObjectArray<DexCache>::Alloc(self,
- cl->FindClass(self,
- "[Ljava/lang/DexCache;",
- ScopedNullHandle<ClassLoader>()),
+ cl->FindSystemClass(self, "[Ljava/lang/DexCache;"),
new_len)));
if (new_dex_caches.IsNull()) {
// Fail.
diff --git a/runtime/mirror/dex_cache_test.cc b/runtime/mirror/dex_cache_test.cc
index 9ca8d307ba..1429bb3e04 100644
--- a/runtime/mirror/dex_cache_test.cc
+++ b/runtime/mirror/dex_cache_test.cc
@@ -79,11 +79,9 @@ TEST_F(DexCacheTest, TestResolvedFieldAccess) {
StackHandleScope<3> hs(soa.Self());
Handle<mirror::ClassLoader> class_loader(hs.NewHandle(
soa.Decode<mirror::ClassLoader>(jclass_loader)));
- Handle<mirror::Class> klass1 =
- hs.NewHandle(class_linker_->FindClass(soa.Self(), "Lpackage1/Package1;", class_loader));
+ Handle<mirror::Class> klass1 = hs.NewHandle(FindClass("Lpackage1/Package1;", class_loader));
ASSERT_TRUE(klass1 != nullptr);
- Handle<mirror::Class> klass2 =
- hs.NewHandle(class_linker_->FindClass(soa.Self(), "Lpackage2/Package2;", class_loader));
+ Handle<mirror::Class> klass2 = hs.NewHandle(FindClass("Lpackage2/Package2;", class_loader));
ASSERT_TRUE(klass2 != nullptr);
EXPECT_OBJ_PTR_EQ(klass1->GetDexCache(), klass2->GetDexCache());
@@ -107,8 +105,7 @@ TEST_F(DexCacheMethodHandlesTest, TestResolvedMethodTypes) {
Handle<mirror::ClassLoader> class_loader(hs.NewHandle(
soa.Decode<mirror::ClassLoader>(jclass_loader)));
- Handle<mirror::Class> method_types(
- hs.NewHandle(class_linker_->FindClass(soa.Self(), "LMethodTypes;", class_loader)));
+ Handle<mirror::Class> method_types = hs.NewHandle(FindClass("LMethodTypes;", class_loader));
class_linker_->EnsureInitialized(soa.Self(), method_types, true, true);
ArtMethod* method1 = method_types->FindClassMethod(
diff --git a/runtime/mirror/method_type_test.cc b/runtime/mirror/method_type_test.cc
index 9d23f8f23d..c5ab7dd522 100644
--- a/runtime/mirror/method_type_test.cc
+++ b/runtime/mirror/method_type_test.cc
@@ -32,43 +32,48 @@
namespace art HIDDEN {
namespace mirror {
-class MethodTypeTest : public CommonRuntimeTest {};
+class MethodTypeTest : public CommonRuntimeTest {
+ protected:
+ ObjPtr<mirror::MethodType> CreateMethodType(const std::string& return_type,
+ const std::vector<std::string>& param_types);
+};
static std::string FullyQualifiedType(const std::string& shorthand) {
return "Ljava/lang/" + shorthand + ";";
}
-ObjPtr<mirror::Class> FindClass(Thread* self, ClassLinker* const cl, const std::string& shorthand)
- REQUIRES_SHARED(Locks::mutator_lock_) {
- StackHandleScope<1> hs(self);
- Handle<mirror::ClassLoader> boot_class_loader = hs.NewHandle<mirror::ClassLoader>(nullptr);
+std::string ExpandShortHand(const std::string& shorthand) {
if (shorthand.size() == 1) {
- return cl->FindSystemClass(self, shorthand.c_str());
+ return shorthand;
} else if (shorthand.find('/') == std::string::npos) {
- return cl->FindClass(self, FullyQualifiedType(shorthand).c_str(), boot_class_loader);
+ return FullyQualifiedType(shorthand);
} else {
- return cl->FindClass(self, shorthand.c_str(), boot_class_loader);
+ return shorthand;
}
}
-static ObjPtr<mirror::MethodType> CreateMethodType(const std::string& return_type,
- const std::vector<std::string>& param_types) {
+ObjPtr<mirror::MethodType> MethodTypeTest::CreateMethodType(
+ const std::string& return_type,
+ const std::vector<std::string>& param_types) {
Runtime* const runtime = Runtime::Current();
- ClassLinker* const class_linker = runtime->GetClassLinker();
Thread* const self = Thread::Current();
ScopedObjectAccess soa(self);
StackHandleScope<2> hs(soa.Self());
- Handle<mirror::Class> return_clazz = hs.NewHandle(FindClass(self, class_linker, return_type));
+ ScopedNullHandle<mirror::ClassLoader> boot_class_loader;
+ Handle<mirror::Class> return_clazz =
+ hs.NewHandle(FindClass(ExpandShortHand(return_type).c_str(), boot_class_loader));
CHECK(return_clazz != nullptr);
ObjPtr<mirror::Class> class_array_type =
- GetClassRoot<mirror::ObjectArray<mirror::Class>>(class_linker);
+ GetClassRoot<mirror::ObjectArray<mirror::Class>>(class_linker_);
Handle<mirror::ObjectArray<mirror::Class>> param_classes = hs.NewHandle(
mirror::ObjectArray<mirror::Class>::Alloc(self, class_array_type, param_types.size()));
+ CHECK(param_classes != nullptr);
for (uint32_t i = 0; i < param_types.size(); ++i) {
- ObjPtr<mirror::Class> param = FindClass(self, class_linker, param_types[i]);
+ ObjPtr<mirror::Class> param =
+ FindClass(ExpandShortHand(param_types[i]).c_str(), boot_class_loader);
CHECK(!param.IsNull());
param_classes->Set(i, param);
}
diff --git a/runtime/mirror/object_test.cc b/runtime/mirror/object_test.cc
index f879b805a9..579ccdce01 100644
--- a/runtime/mirror/object_test.cc
+++ b/runtime/mirror/object_test.cc
@@ -407,8 +407,7 @@ TEST_F(ObjectTest, StaticFieldFromCode) {
StackHandleScope<3> hs(soa.Self());
Handle<mirror::ClassLoader> loader(hs.NewHandle(soa.Decode<ClassLoader>(class_loader)));
- Handle<Class> klass =
- hs.NewHandle(class_linker_->FindClass(soa.Self(), "LStaticsFromCode;", loader));
+ Handle<Class> klass = hs.NewHandle(FindClass("LStaticsFromCode;", loader));
ArtMethod* clinit = klass->FindClassInitializer(kRuntimePointerSize);
const dex::TypeId* klass_type_id = dex_file->FindTypeId("LStaticsFromCode;");
ASSERT_TRUE(klass_type_id != nullptr);
@@ -534,7 +533,6 @@ TEST_F(ObjectTest, StringLength) {
TEST_F(ObjectTest, DescriptorCompare) {
// Two classloaders conflicts in compile_time_class_paths_.
ScopedObjectAccess soa(Thread::Current());
- ClassLinker* linker = class_linker_;
jobject jclass_loader_1 = LoadDex("ProtoCompare");
jobject jclass_loader_2 = LoadDex("ProtoCompare2");
@@ -542,11 +540,9 @@ TEST_F(ObjectTest, DescriptorCompare) {
Handle<ClassLoader> class_loader_1(hs.NewHandle(soa.Decode<ClassLoader>(jclass_loader_1)));
Handle<ClassLoader> class_loader_2(hs.NewHandle(soa.Decode<ClassLoader>(jclass_loader_2)));
- Handle<Class> klass1 =
- hs.NewHandle(linker->FindClass(soa.Self(), "LProtoCompare;", class_loader_1));
+ Handle<Class> klass1 = hs.NewHandle(FindClass("LProtoCompare;", class_loader_1));
ASSERT_TRUE(klass1 != nullptr);
- Handle<Class> klass2 =
- hs.NewHandle(linker->FindClass(soa.Self(), "LProtoCompare2;", class_loader_2));
+ Handle<Class> klass2 = hs.NewHandle(FindClass("LProtoCompare2;", class_loader_2));
ASSERT_TRUE(klass2 != nullptr);
ArtMethod* m1_1 = klass1->GetVirtualMethod(0, kRuntimePointerSize);
@@ -586,8 +582,8 @@ TEST_F(ObjectTest, InstanceOf) {
StackHandleScope<10> hs(soa.Self());
Handle<ClassLoader> class_loader(hs.NewHandle(soa.Decode<ClassLoader>(jclass_loader)));
- Handle<Class> X = hs.NewHandle(class_linker_->FindClass(soa.Self(), "LX;", class_loader));
- Handle<Class> Y = hs.NewHandle(class_linker_->FindClass(soa.Self(), "LY;", class_loader));
+ Handle<Class> X = hs.NewHandle(FindClass("LX;", class_loader));
+ Handle<Class> Y = hs.NewHandle(FindClass("LY;", class_loader));
ASSERT_TRUE(X != nullptr);
ASSERT_TRUE(Y != nullptr);
@@ -625,8 +621,8 @@ TEST_F(ObjectTest, IsAssignableFrom) {
jobject jclass_loader = LoadDex("XandY");
StackHandleScope<5> hs(soa.Self());
Handle<ClassLoader> class_loader(hs.NewHandle(soa.Decode<ClassLoader>(jclass_loader)));
- Handle<Class> X = hs.NewHandle(class_linker_->FindClass(soa.Self(), "LX;", class_loader));
- Handle<Class> Y = hs.NewHandle(class_linker_->FindClass(soa.Self(), "LY;", class_loader));
+ Handle<Class> X = hs.NewHandle(FindClass("LX;", class_loader));
+ Handle<Class> Y = hs.NewHandle(FindClass("LY;", class_loader));
EXPECT_TRUE(X->IsAssignableFrom(X.Get()));
EXPECT_TRUE(X->IsAssignableFrom(Y.Get()));
@@ -665,17 +661,17 @@ TEST_F(ObjectTest, IsAssignableFromArray) {
jobject jclass_loader = LoadDex("XandY");
StackHandleScope<14> hs(soa.Self());
Handle<ClassLoader> class_loader(hs.NewHandle(soa.Decode<ClassLoader>(jclass_loader)));
- Handle<Class> X = hs.NewHandle(class_linker_->FindClass(soa.Self(), "LX;", class_loader));
- Handle<Class> Y = hs.NewHandle(class_linker_->FindClass(soa.Self(), "LY;", class_loader));
+ Handle<Class> X = hs.NewHandle(FindClass("LX;", class_loader));
+ Handle<Class> Y = hs.NewHandle(FindClass("LY;", class_loader));
ASSERT_TRUE(X != nullptr);
ASSERT_TRUE(Y != nullptr);
- Handle<Class> YA = hs.NewHandle(class_linker_->FindClass(soa.Self(), "[LY;", class_loader));
- Handle<Class> YAA = hs.NewHandle(class_linker_->FindClass(soa.Self(), "[[LY;", class_loader));
+ Handle<Class> YA = hs.NewHandle(FindClass("[LY;", class_loader));
+ Handle<Class> YAA = hs.NewHandle(FindClass("[[LY;", class_loader));
ASSERT_TRUE(YA != nullptr);
ASSERT_TRUE(YAA != nullptr);
- Handle<Class> XAA = hs.NewHandle(class_linker_->FindClass(soa.Self(), "[[LX;", class_loader));
+ Handle<Class> XAA = hs.NewHandle(FindClass("[[LX;", class_loader));
ASSERT_TRUE(XAA != nullptr);
Handle<Class> O = hs.NewHandle(class_linker_->FindSystemClass(soa.Self(), "Ljava/lang/Object;"));
@@ -797,8 +793,7 @@ TEST_F(ObjectTest, ObjectPointer) {
jobject jclass_loader = LoadDex("XandY");
StackHandleScope<2> hs(soa.Self());
Handle<ClassLoader> class_loader(hs.NewHandle(soa.Decode<ClassLoader>(jclass_loader)));
- Handle<mirror::Class> h_X(
- hs.NewHandle(class_linker_->FindClass(soa.Self(), "LX;", class_loader)));
+ Handle<mirror::Class> h_X = hs.NewHandle(FindClass("LX;", class_loader));
if (kObjPtrPoisoning) {
ObjPtr<mirror::Object> null_ptr;
@@ -816,7 +811,7 @@ TEST_F(ObjectTest, ObjectPointer) {
EXPECT_TRUE(X.Ptr() != nullptr);
EXPECT_OBJ_PTR_EQ(h_X.Get(), X);
// FindClass may cause thread suspension, it should invalidate X.
- ObjPtr<Class> Y(class_linker_->FindClass(soa.Self(), "LY;", class_loader));
+ ObjPtr<Class> Y = FindClass("LY;", class_loader);
EXPECT_TRUE(!Y.IsNull());
EXPECT_TRUE(Y.IsValid());
EXPECT_TRUE(Y.Ptr() != nullptr);
diff --git a/runtime/mirror/var_handle_test.cc b/runtime/mirror/var_handle_test.cc
index 22d1e4a6d4..bb7753c42a 100644
--- a/runtime/mirror/var_handle_test.cc
+++ b/runtime/mirror/var_handle_test.cc
@@ -137,6 +137,26 @@ class VarHandleTest : public CommonRuntimeTest {
return AccessModesBitMask(first) | AccessModesBitMask(args...);
}
+ ObjPtr<MethodType> MethodTypeOf(const std::string& method_descriptor);
+
+ template <typename VH>
+ bool AccessModeExactMatch(Handle<VH> vh,
+ VarHandle::AccessMode access_mode,
+ const char* descriptor)
+ REQUIRES_SHARED(Locks::mutator_lock_);
+
+ template <typename VH>
+ bool AccessModeWithConversionsMatch(Handle<VH> vh,
+ VarHandle::AccessMode access_mode,
+ const char* descriptor)
+ REQUIRES_SHARED(Locks::mutator_lock_);
+
+ template <typename VH>
+ bool AccessModeNoMatch(Handle<VH> vh,
+ VarHandle::AccessMode access_mode,
+ const char* descriptor)
+ REQUIRES_SHARED(Locks::mutator_lock_);
+
private:
static void InitializeVarHandle(ObjPtr<VarHandle> vh,
Handle<Class> var_type,
@@ -169,7 +189,7 @@ class VarHandleTest : public CommonRuntimeTest {
// Convenience method for constructing MethodType instances from
// well-formed method descriptors.
-static ObjPtr<MethodType> MethodTypeOf(const std::string& method_descriptor) {
+ObjPtr<MethodType> VarHandleTest::MethodTypeOf(const std::string& method_descriptor) {
std::vector<std::string> descriptors;
auto it = method_descriptor.cbegin();
@@ -226,10 +246,9 @@ static ObjPtr<MethodType> MethodTypeOf(const std::string& method_descriptor) {
ObjectArray<Class>::Alloc(Thread::Current(), array_of_class, ptypes_count));
Handle<mirror::ClassLoader> boot_class_loader = hs.NewHandle<mirror::ClassLoader>(nullptr);
for (int i = 0; i < ptypes_count; ++i) {
- ptypes->Set(i, class_linker->FindClass(self, descriptors[i].c_str(), boot_class_loader));
+ ptypes->Set(i, FindClass(descriptors[i].c_str(), boot_class_loader));
}
- Handle<Class> rtype =
- hs.NewHandle(class_linker->FindClass(self, descriptors.back().c_str(), boot_class_loader));
+ Handle<Class> rtype = hs.NewHandle(FindClass(descriptors.back().c_str(), boot_class_loader));
return MethodType::Create(self, rtype, ptypes);
}
@@ -242,10 +261,9 @@ static bool AccessModeMatch(ObjPtr<VarHandle> vh,
}
template <typename VH>
-static bool AccessModeExactMatch(Handle<VH> vh,
- VarHandle::AccessMode access_mode,
- const char* descriptor)
- REQUIRES_SHARED(Locks::mutator_lock_) {
+bool VarHandleTest::AccessModeExactMatch(Handle<VH> vh,
+ VarHandle::AccessMode access_mode,
+ const char* descriptor) {
ObjPtr<MethodType> method_type = MethodTypeOf(descriptor);
return AccessModeMatch(vh.Get(),
access_mode,
@@ -254,10 +272,9 @@ static bool AccessModeExactMatch(Handle<VH> vh,
}
template <typename VH>
-static bool AccessModeWithConversionsMatch(Handle<VH> vh,
- VarHandle::AccessMode access_mode,
- const char* descriptor)
- REQUIRES_SHARED(Locks::mutator_lock_) {
+bool VarHandleTest::AccessModeWithConversionsMatch(Handle<VH> vh,
+ VarHandle::AccessMode access_mode,
+ const char* descriptor) {
ObjPtr<MethodType> method_type = MethodTypeOf(descriptor);
return AccessModeMatch(vh.Get(),
access_mode,
@@ -266,10 +283,9 @@ static bool AccessModeWithConversionsMatch(Handle<VH> vh,
}
template <typename VH>
-static bool AccessModeNoMatch(Handle<VH> vh,
- VarHandle::AccessMode access_mode,
- const char* descriptor)
- REQUIRES_SHARED(Locks::mutator_lock_) {
+bool VarHandleTest::AccessModeNoMatch(Handle<VH> vh,
+ VarHandle::AccessMode access_mode,
+ const char* descriptor) {
ObjPtr<MethodType> method_type = MethodTypeOf(descriptor);
return AccessModeMatch(vh.Get(),
access_mode,
diff --git a/runtime/native/java_lang_Class.cc b/runtime/native/java_lang_Class.cc
index 79c8176027..c31c9790bd 100644
--- a/runtime/native/java_lang_Class.cc
+++ b/runtime/native/java_lang_Class.cc
@@ -111,8 +111,8 @@ static jclass Class_classForName(JNIEnv* env, jclass, jstring javaName, jboolean
Handle<mirror::ClassLoader> class_loader(
hs.NewHandle(soa.Decode<mirror::ClassLoader>(javaLoader)));
ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
- Handle<mirror::Class> c(
- hs.NewHandle(class_linker->FindClass(soa.Self(), descriptor.c_str(), class_loader)));
+ Handle<mirror::Class> c = hs.NewHandle(
+ class_linker->FindClass(soa.Self(), descriptor.c_str(), descriptor.length(), class_loader));
if (UNLIKELY(c == nullptr)) {
StackHandleScope<2> hs2(soa.Self());
Handle<mirror::Object> cause = hs2.NewHandle(soa.Self()->GetException());
diff --git a/runtime/native/java_lang_VMClassLoader.cc b/runtime/native/java_lang_VMClassLoader.cc
index a735765bdd..eeae51c5e7 100644
--- a/runtime/native/java_lang_VMClassLoader.cc
+++ b/runtime/native/java_lang_VMClassLoader.cc
@@ -45,7 +45,7 @@ class VMClassLoader {
public:
static ObjPtr<mirror::Class> LookupClass(ClassLinker* cl,
Thread* self,
- const char* descriptor,
+ std::string_view descriptor,
size_t hash,
ObjPtr<mirror::ClassLoader> class_loader)
REQUIRES(!Locks::classlinker_classes_lock_)
@@ -89,7 +89,7 @@ static jclass VMClassLoader_findLoadedClass(JNIEnv* env, jclass, jobject javaLoa
ObjPtr<mirror::Class> c = VMClassLoader::LookupClass(cl,
soa.Self(),
- descriptor.c_str(),
+ descriptor,
descriptor_hash,
loader);
if (c != nullptr && c->IsResolved()) {
diff --git a/runtime/oat/oat_file_manager.cc b/runtime/oat/oat_file_manager.cc
index f10ba673df..320961755f 100644
--- a/runtime/oat/oat_file_manager.cc
+++ b/runtime/oat/oat_file_manager.cc
@@ -724,10 +724,8 @@ class BackgroundVerificationTask final : public Task {
StackHandleScope<2> hs(self);
Handle<mirror::ClassLoader> h_loader(hs.NewHandle(
soa.Decode<mirror::ClassLoader>(class_loader_)));
- Handle<mirror::Class> h_class(hs.NewHandle<mirror::Class>(class_linker->FindClass(
- self,
- dex_file->GetClassDescriptor(class_def),
- h_loader)));
+ Handle<mirror::Class> h_class =
+ hs.NewHandle(class_linker->FindClass(self, *dex_file, class_def.class_idx_, h_loader));
if (h_class == nullptr) {
DCHECK(self->IsExceptionPending());
diff --git a/runtime/proxy_test.cc b/runtime/proxy_test.cc
index fb877d3ec5..f9bf31bedd 100644
--- a/runtime/proxy_test.cc
+++ b/runtime/proxy_test.cc
@@ -43,10 +43,8 @@ TEST_F(ProxyTest, ProxyClassHelper) {
Handle<mirror::ClassLoader> class_loader(
hs.NewHandle(soa.Decode<mirror::ClassLoader>(jclass_loader)));
- 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> I = hs.NewHandle(FindClass("LInterfaces$I;", class_loader));
+ Handle<mirror::Class> J = hs.NewHandle(FindClass("LInterfaces$J;", class_loader));
ASSERT_TRUE(I != nullptr);
ASSERT_TRUE(J != nullptr);
@@ -77,10 +75,8 @@ TEST_F(ProxyTest, ProxyFieldHelper) {
Handle<mirror::ClassLoader> class_loader(
hs.NewHandle(soa.Decode<mirror::ClassLoader>(jclass_loader)));
- 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> I = hs.NewHandle(FindClass("LInterfaces$I;", class_loader));
+ Handle<mirror::Class> J = hs.NewHandle(FindClass("LInterfaces$J;", class_loader));
ASSERT_TRUE(I != nullptr);
ASSERT_TRUE(J != nullptr);
diff --git a/runtime/reference_table_test.cc b/runtime/reference_table_test.cc
index af8f4e50bc..40c22c8a3e 100644
--- a/runtime/reference_table_test.cc
+++ b/runtime/reference_table_test.cc
@@ -45,10 +45,12 @@ class ReferenceTableTest : public CommonRuntimeTest {
ReferenceTableTest() {
use_boot_image_ = true; // Make the Runtime creation cheaper.
}
+
+ ObjPtr<mirror::Object> CreateWeakReference(ObjPtr<mirror::Object> referent)
+ REQUIRES_SHARED(Locks::mutator_lock_);
};
-static ObjPtr<mirror::Object> CreateWeakReference(ObjPtr<mirror::Object> referent)
- REQUIRES_SHARED(Locks::mutator_lock_) {
+ObjPtr<mirror::Object> ReferenceTableTest::CreateWeakReference(ObjPtr<mirror::Object> referent) {
Thread* self = Thread::Current();
ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
@@ -56,9 +58,7 @@ static ObjPtr<mirror::Object> CreateWeakReference(ObjPtr<mirror::Object> referen
Handle<mirror::Object> h_referent(scope.NewHandle<mirror::Object>(referent));
Handle<mirror::Class> h_ref_class(scope.NewHandle<mirror::Class>(
- class_linker->FindClass(self,
- "Ljava/lang/ref/WeakReference;",
- ScopedNullHandle<mirror::ClassLoader>())));
+ FindClass("Ljava/lang/ref/WeakReference;", ScopedNullHandle<mirror::ClassLoader>())));
CHECK(h_ref_class != nullptr);
CHECK(class_linker->EnsureInitialized(self, h_ref_class, true, true));
diff --git a/runtime/reflection_test.cc b/runtime/reflection_test.cc
index d307ba0cca..f65a244fef 100644
--- a/runtime/reflection_test.cc
+++ b/runtime/reflection_test.cc
@@ -103,9 +103,7 @@ class ReflectionTest : public CommonRuntimeTest {
MakeInterpreted(class_linker_->FindSystemClass(self, "Ljava/lang/Object;"));
}
- ObjPtr<mirror::Class> c = class_linker_->FindClass(self,
- DotToDescriptor(class_name).c_str(),
- class_loader);
+ ObjPtr<mirror::Class> c = FindClass(DotToDescriptor(class_name).c_str(), class_loader);
CHECK(c != nullptr);
MakeInterpreted(c);
diff --git a/runtime/runtime_callbacks_test.cc b/runtime/runtime_callbacks_test.cc
index 719cae5e3c..053d4eaaf5 100644
--- a/runtime/runtime_callbacks_test.cc
+++ b/runtime/runtime_callbacks_test.cc
@@ -303,8 +303,7 @@ TEST_F(ClassLoadCallbackRuntimeCallbacksTest, ClassLoadCallback) {
soa.Decode<mirror::ClassLoader>(jclass_loader)));
const char* descriptor_y = "LY;";
- Handle<mirror::Class> h_Y(
- hs.NewHandle(class_linker_->FindClass(soa.Self(), descriptor_y, class_loader)));
+ Handle<mirror::Class> h_Y = hs.NewHandle(FindClass(descriptor_y, class_loader));
ASSERT_TRUE(h_Y != nullptr);
bool expect1 = Expect({ "PreDefine:LY; <art-gtest-jars-XandY.jar>",
diff --git a/runtime/thread.cc b/runtime/thread.cc
index 319782b351..5bd97eb59a 100644
--- a/runtime/thread.cc
+++ b/runtime/thread.cc
@@ -3642,7 +3642,8 @@ void Thread::ThrowNewWrappedException(const char* exception_class_descriptor,
Runtime* runtime = Runtime::Current();
auto* cl = runtime->GetClassLinker();
Handle<mirror::Class> exception_class(
- hs.NewHandle(cl->FindClass(this, exception_class_descriptor, class_loader)));
+ hs.NewHandle(cl->FindClass(
+ this, exception_class_descriptor, strlen(exception_class_descriptor), class_loader)));
if (UNLIKELY(exception_class == nullptr)) {
CHECK(IsExceptionPending());
LOG(ERROR) << "No exception class " << PrettyDescriptor(exception_class_descriptor);
diff --git a/runtime/vdex_file.cc b/runtime/vdex_file.cc
index 6702970c68..db2a976c22 100644
--- a/runtime/vdex_file.cc
+++ b/runtime/vdex_file.cc
@@ -392,10 +392,12 @@ bool VdexFile::HasOnlyStandardDexFiles() const {
static ObjPtr<mirror::Class> FindClassAndClearException(ClassLinker* class_linker,
Thread* self,
- const char* name,
+ const char* descriptor,
+ size_t descriptor_length,
Handle<mirror::ClassLoader> class_loader)
REQUIRES_SHARED(Locks::mutator_lock_) {
- ObjPtr<mirror::Class> result = class_linker->FindClass(self, name, class_loader);
+ ObjPtr<mirror::Class> result =
+ class_linker->FindClass(self, descriptor, descriptor_length, class_loader);
if (result == nullptr) {
DCHECK(self->IsExceptionPending());
self->ClearException();
@@ -403,18 +405,24 @@ static ObjPtr<mirror::Class> FindClassAndClearException(ClassLinker* class_linke
return result;
}
-static const char* GetStringFromId(const DexFile& dex_file,
- dex::StringIndex string_id,
- uint32_t number_of_extra_strings,
- const uint32_t* extra_strings_offsets,
- const uint8_t* verifier_deps) {
+static const char* GetStringFromIndex(const DexFile& dex_file,
+ dex::StringIndex string_id,
+ uint32_t number_of_extra_strings,
+ const uint32_t* extra_strings_offsets,
+ const uint8_t* verifier_deps,
+ /*out*/ size_t* utf8_length) {
uint32_t num_ids_in_dex = dex_file.NumStringIds();
if (string_id.index_ < num_ids_in_dex) {
- return dex_file.GetStringData(string_id);
+ uint32_t utf16_length;
+ const char* str = dex_file.GetStringDataAndUtf16Length(string_id, &utf16_length);
+ *utf8_length = DexFile::Utf8Length(str, utf16_length);
+ return str;
} else {
CHECK_LT(string_id.index_ - num_ids_in_dex, number_of_extra_strings);
uint32_t offset = extra_strings_offsets[string_id.index_ - num_ids_in_dex];
- return reinterpret_cast<const char*>(verifier_deps) + offset;
+ const char* str = reinterpret_cast<const char*>(verifier_deps) + offset;
+ *utf8_length = strlen(str);
+ return str;
}
}
@@ -499,20 +507,25 @@ ClassStatus VdexFile::ComputeClassStatus(Thread* self, Handle<mirror::Class> cls
// Error parsing the data, just return that we are not verified.
return ClassStatus::kResolved;
}
- const char* destination_desc = GetStringFromId(dex_file,
- dex::StringIndex(destination_index),
- number_of_extra_strings,
- extra_strings_offsets,
- verifier_deps);
- destination.Assign(
- FindClassAndClearException(class_linker, self, destination_desc, class_loader));
-
- const char* source_desc = GetStringFromId(dex_file,
- dex::StringIndex(source_index),
- number_of_extra_strings,
- extra_strings_offsets,
- verifier_deps);
- source.Assign(FindClassAndClearException(class_linker, self, source_desc, class_loader));
+ size_t destination_desc_length;
+ const char* destination_desc = GetStringFromIndex(dex_file,
+ dex::StringIndex(destination_index),
+ number_of_extra_strings,
+ extra_strings_offsets,
+ verifier_deps,
+ &destination_desc_length);
+ destination.Assign(FindClassAndClearException(
+ class_linker, self, destination_desc, destination_desc_length, class_loader));
+
+ size_t source_desc_length;
+ const char* source_desc = GetStringFromIndex(dex_file,
+ dex::StringIndex(source_index),
+ number_of_extra_strings,
+ extra_strings_offsets,
+ verifier_deps,
+ &source_desc_length);
+ source.Assign(FindClassAndClearException(
+ class_linker, self, source_desc, source_desc_length, class_loader));
if (destination == nullptr || source == nullptr) {
// The interpreter / compiler can handle a missing class.
diff --git a/runtime/verifier/reg_type_cache.cc b/runtime/verifier/reg_type_cache.cc
index 3a88458a42..47bb35cec9 100644
--- a/runtime/verifier/reg_type_cache.cc
+++ b/runtime/verifier/reg_type_cache.cc
@@ -140,15 +140,16 @@ bool RegTypeCache::MatchDescriptor(size_t idx, const std::string_view& descripto
return true;
}
-ObjPtr<mirror::Class> RegTypeCache::ResolveClass(const char* descriptor) {
+ObjPtr<mirror::Class> RegTypeCache::ResolveClass(const char* descriptor, size_t descriptor_length) {
// Class was not found, must create new type.
// Try resolving class
Thread* self = Thread::Current();
ObjPtr<mirror::Class> klass = nullptr;
if (can_load_classes_) {
- klass = class_linker_->FindClass(self, descriptor, class_loader_);
+ klass = class_linker_->FindClass(self, descriptor, descriptor_length, class_loader_);
} else {
- klass = class_linker_->LookupClass(self, descriptor, class_loader_.Get());
+ std::string_view sv_descriptor(descriptor, descriptor_length);
+ klass = class_linker_->LookupClass(self, sv_descriptor, class_loader_.Get());
if (klass != nullptr && !klass->IsResolved()) {
// We found the class but without it being loaded its not safe for use.
klass = nullptr;
@@ -164,6 +165,7 @@ std::string_view RegTypeCache::AddString(const std::string_view& str) {
}
const RegType& RegTypeCache::From(const char* descriptor) {
+ // TODO: Avoid the implicit `strlen()` call for ASCII descriptors from the dex file.
std::string_view sv_descriptor(descriptor);
// Try looking up the class in the cache first. We use a std::string_view to avoid
// repeated strlen operations on the descriptor.
@@ -174,7 +176,7 @@ const RegType& RegTypeCache::From(const char* descriptor) {
}
// Class not found in the cache, will create a new type for that.
// Try resolving class.
- ObjPtr<mirror::Class> klass = ResolveClass(descriptor);
+ ObjPtr<mirror::Class> klass = ResolveClass(descriptor, sv_descriptor.length());
// TODO: Avoid copying the `descriptor` with `AddString()` below if the `descriptor`
// comes from the dex file, for example through `FromTypeIndex()`.
if (klass != nullptr) {
diff --git a/runtime/verifier/reg_type_cache.h b/runtime/verifier/reg_type_cache.h
index db7f4291e1..023f7bce32 100644
--- a/runtime/verifier/reg_type_cache.h
+++ b/runtime/verifier/reg_type_cache.h
@@ -189,7 +189,7 @@ class RegTypeCache {
private:
void FillPrimitiveAndSmallConstantTypes() REQUIRES_SHARED(Locks::mutator_lock_);
- ObjPtr<mirror::Class> ResolveClass(const char* descriptor)
+ ObjPtr<mirror::Class> ResolveClass(const char* descriptor, size_t descriptor_length)
REQUIRES_SHARED(Locks::mutator_lock_);
bool MatchDescriptor(size_t idx, const std::string_view& descriptor)
REQUIRES_SHARED(Locks::mutator_lock_);
diff --git a/runtime/verifier/reg_type_test.cc b/runtime/verifier/reg_type_test.cc
index 8841c9f62e..736b51ed1e 100644
--- a/runtime/verifier/reg_type_test.cc
+++ b/runtime/verifier/reg_type_test.cc
@@ -1115,10 +1115,8 @@ class RegTypeClassJoinTest : public RegTypeTest {
Handle<mirror::ClassLoader> class_loader(
hs.NewHandle(soa.Decode<mirror::ClassLoader>(jclass_loader)));
- Handle<mirror::Class> c1(hs.NewHandle(
- class_linker_->FindClass(soa.Self(), in1, class_loader)));
- Handle<mirror::Class> c2(hs.NewHandle(
- class_linker_->FindClass(soa.Self(), in2, class_loader)));
+ Handle<mirror::Class> c1 = hs.NewHandle(FindClass(in1, class_loader));
+ Handle<mirror::Class> c2 = hs.NewHandle(FindClass(in2, class_loader));
ASSERT_TRUE(c1 != nullptr);
ASSERT_TRUE(c2 != nullptr);
const DexFile* dex_file = &c1->GetDexFile();
diff --git a/runtime/verifier/verifier_deps.cc b/runtime/verifier/verifier_deps.cc
index 81f0a9cd2e..98d9e27c97 100644
--- a/runtime/verifier/verifier_deps.cc
+++ b/runtime/verifier/verifier_deps.cc
@@ -167,22 +167,32 @@ dex::StringIndex VerifierDeps::GetIdFromString(const DexFile& dex_file, const st
deps->strings_.push_back(str);
dex::StringIndex new_id(num_ids_in_dex + deps->strings_.size() - 1);
CHECK_GE(new_id.index_, num_ids_in_dex); // check for overflows
- DCHECK_EQ(str, singleton->GetStringFromId(dex_file, new_id));
+ DCHECK_EQ(str, singleton->GetStringFromIndex(dex_file, new_id));
return new_id;
}
}
-std::string VerifierDeps::GetStringFromId(const DexFile& dex_file,
- dex::StringIndex string_id) const {
+const char* VerifierDeps::GetStringFromIndex(const DexFile& dex_file,
+ dex::StringIndex string_idx,
+ /*out*/ size_t* utf8_length) const {
uint32_t num_ids_in_dex = dex_file.NumStringIds();
- if (string_id.index_ < num_ids_in_dex) {
- return std::string(dex_file.GetStringView(string_id));
+ if (string_idx.index_ < num_ids_in_dex) {
+ uint32_t utf16_length;
+ const char* str = dex_file.GetStringDataAndUtf16Length(string_idx, &utf16_length);
+ if (utf8_length != nullptr) {
+ *utf8_length = DexFile::Utf8Length(str, utf16_length);
+ }
+ return str;
} else {
const DexFileDeps* deps = GetDexFileDeps(dex_file);
DCHECK(deps != nullptr);
- string_id.index_ -= num_ids_in_dex;
- CHECK_LT(string_id.index_, deps->strings_.size());
- return deps->strings_[string_id.index_];
+ size_t index = string_idx.index_ - num_ids_in_dex;
+ CHECK_LT(index, deps->strings_.size());
+ const std::string& str = deps->strings_[index];
+ if (utf8_length != nullptr) {
+ *utf8_length = str.length();
+ }
+ return str.c_str();
}
}
@@ -660,8 +670,9 @@ void VerifierDeps::Dump(VariableIndentationOutputStream* vios) const {
vios->Stream() << "Dependencies of " << dex_file.GetClassDescriptor(dex_file.GetClassDef(idx))
<< ":\n";
for (const TypeAssignability& entry : dep.second->assignable_types_[idx]) {
- vios->Stream() << GetStringFromId(dex_file, entry.GetSource()) << " must be assignable to "
- << GetStringFromId(dex_file, entry.GetDestination()) << "\n";
+ vios->Stream() << GetStringFromIndex(dex_file, entry.GetSource())
+ << " must be assignable to "
+ << GetStringFromIndex(dex_file, entry.GetDestination()) << "\n";
}
}
@@ -692,10 +703,12 @@ bool VerifierDeps::ValidateDependenciesAndUpdateStatus(
// the same lookup pattern.
static ObjPtr<mirror::Class> FindClassAndClearException(ClassLinker* class_linker,
Thread* self,
- const std::string& name,
+ const char* descriptor,
+ size_t descriptor_length,
Handle<mirror::ClassLoader> class_loader)
REQUIRES_SHARED(Locks::mutator_lock_) {
- ObjPtr<mirror::Class> result = class_linker->FindClass(self, name.c_str(), class_loader);
+ ObjPtr<mirror::Class> result =
+ class_linker->FindClass(self, descriptor, descriptor_length, class_loader);
if (result == nullptr) {
DCHECK(self->IsExceptionPending());
self->ClearException();
@@ -720,11 +733,16 @@ bool VerifierDeps::VerifyDexFileAndUpdateStatus(
static constexpr uint32_t kMaxWarnings = 5;
for (const auto& vec : assignables) {
for (const auto& entry : vec) {
- const std::string& destination_desc = GetStringFromId(dex_file, entry.GetDestination());
- destination.Assign(
- FindClassAndClearException(class_linker, self, destination_desc, class_loader));
- const std::string& source_desc = GetStringFromId(dex_file, entry.GetSource());
- source.Assign(FindClassAndClearException(class_linker, self, source_desc, class_loader));
+ size_t destination_desc_length;
+ const char* destination_desc =
+ GetStringFromIndex(dex_file, entry.GetDestination(), &destination_desc_length);
+ destination.Assign(FindClassAndClearException(
+ class_linker, self, destination_desc, destination_desc_length, class_loader));
+ size_t source_desc_length;
+ const char* source_desc =
+ GetStringFromIndex(dex_file, entry.GetSource(), &source_desc_length);
+ source.Assign(FindClassAndClearException(
+ class_linker, self, source_desc, source_desc_length, class_loader));
if (destination == nullptr || source == nullptr) {
// We currently don't use assignability information for unresolved
diff --git a/runtime/verifier/verifier_deps.h b/runtime/verifier/verifier_deps.h
index 5e3fb63c2d..293a6d99b3 100644
--- a/runtime/verifier/verifier_deps.h
+++ b/runtime/verifier/verifier_deps.h
@@ -207,8 +207,10 @@ class VerifierDeps {
dex::StringIndex GetIdFromString(const DexFile& dex_file, const std::string& str)
REQUIRES(!Locks::verifier_deps_lock_);
- // Returns the string represented by `id`.
- std::string GetStringFromId(const DexFile& dex_file, dex::StringIndex string_id) const;
+ // Returns the string represented by `string_idx`.
+ const char* GetStringFromIndex(const DexFile& dex_file,
+ dex::StringIndex string_idx,
+ /*out*/ size_t* utf8_length = nullptr) const;
// Returns a string ID of the descriptor of the class.
dex::StringIndex GetClassDescriptorStringId(const DexFile& dex_file, ObjPtr<mirror::Class> klass)
diff --git a/test/692-vdex-inmem-loader/vdex_inmem_loader.cc b/test/692-vdex-inmem-loader/vdex_inmem_loader.cc
index e1278becbd..919107eb63 100644
--- a/test/692-vdex-inmem-loader/vdex_inmem_loader.cc
+++ b/test/692-vdex-inmem-loader/vdex_inmem_loader.cc
@@ -59,9 +59,9 @@ extern "C" JNIEXPORT jboolean JNICALL Java_Main_areClassesVerified(JNIEnv*,
bool all_verified = false;
for (const DexFile* dex_file : dex_files) {
for (uint16_t cdef_idx = 0; cdef_idx < dex_file->NumClassDefs(); ++cdef_idx) {
- const char* desc = dex_file->GetClassDescriptor(dex_file->GetClassDef(cdef_idx));
- h_class.Assign(class_linker->FindClass(soa.Self(), desc, h_loader));
- CHECK(h_class != nullptr) << "Could not find class " << desc;
+ dex::TypeIndex type_idx = dex_file->GetClassDef(cdef_idx).class_idx_;
+ h_class.Assign(class_linker->FindClass(soa.Self(), *dex_file, type_idx, h_loader));
+ CHECK(h_class != nullptr) << "Could not find class " << dex_file->GetTypeDescriptor(type_idx);
bool is_verified = h_class->IsVerified();
if (is_first) {
all_verified = is_verified;
@@ -155,9 +155,9 @@ extern "C" JNIEXPORT jboolean JNICALL Java_Main_areClassesPreverified(JNIEnv*,
bool all_preverified = false;
for (const DexFile* dex_file : dex_files) {
for (uint16_t cdef_idx = 0; cdef_idx < dex_file->NumClassDefs(); ++cdef_idx) {
- const char* desc = dex_file->GetClassDescriptor(dex_file->GetClassDef(cdef_idx));
- h_class.Assign(class_linker->FindClass(soa.Self(), desc, h_loader));
- CHECK(h_class != nullptr) << "Could not find class " << desc;
+ dex::TypeIndex type_idx = dex_file->GetClassDef(cdef_idx).class_idx_;
+ h_class.Assign(class_linker->FindClass(soa.Self(), *dex_file, type_idx, h_loader));
+ CHECK(h_class != nullptr) << "Could not find class " << dex_file->GetTypeDescriptor(type_idx);
ClassStatus oat_file_class_status(ClassStatus::kNotReady);
bool is_preverified = class_linker->VerifyClassUsingOatFile(
diff --git a/tools/art_verifier/art_verifier.cc b/tools/art_verifier/art_verifier.cc
index f5d957683a..66cb326dbb 100644
--- a/tools/art_verifier/art_verifier.cc
+++ b/tools/art_verifier/art_verifier.cc
@@ -234,11 +234,11 @@ struct MethodVerifierMain : public CmdlineMain<MethodVerifierArgs> {
}
for (const DexFile* dex_file : dex_files) {
for (ClassAccessor accessor : dex_file->GetClasses()) {
- const char* descriptor = accessor.GetDescriptor();
- h_klass.Assign(class_linker->FindClass(soa.Self(), descriptor, h_loader));
+ h_klass.Assign(
+ class_linker->FindClass(soa.Self(), *dex_file, accessor.GetClassIdx(), h_loader));
if (h_klass == nullptr || h_klass->IsErroneous()) {
if (args_->repetitions_ == 0) {
- LOG(ERROR) << "Warning: could not load " << descriptor;
+ LOG(ERROR) << "Warning: could not load " << accessor.GetDescriptor();
}
soa.Self()->ClearException();
continue;
@@ -258,7 +258,7 @@ struct MethodVerifierMain : public CmdlineMain<MethodVerifierArgs> {
args_->api_level_,
&error_msg);
if (args_->repetitions_ == 0) {
- LOG(INFO) << descriptor << ": " << res << " " << error_msg;
+ LOG(INFO) << accessor.GetDescriptor() << ": " << res << " " << error_msg;
}
}
}
diff --git a/tools/fuzzer/libart_verify_classes_fuzzer.cc b/tools/fuzzer/libart_verify_classes_fuzzer.cc
index d066ef4b6e..13abd7c613 100644
--- a/tools/fuzzer/libart_verify_classes_fuzzer.cc
+++ b/tools/fuzzer/libart_verify_classes_fuzzer.cc
@@ -186,8 +186,8 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
scope.NewHandle<art::mirror::DexCache>(nullptr));
for (art::ClassAccessor accessor : dex_file.GetClasses()) {
- const char* descriptor = accessor.GetDescriptor();
- h_klass.Assign(class_linker->FindClass(soa.Self(), descriptor, h_loader));
+ h_klass.Assign(
+ class_linker->FindClass(soa.Self(), dex_file, accessor.GetClassIdx(), h_loader));
// Ignore classes that couldn't be loaded since we are looking for crashes during
// class/method verification.
if (h_klass == nullptr || h_klass->IsErroneous()) {