summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--compiler/common_compiler_test.h4
-rw-r--r--compiler/driver/compiler_driver-inl.h31
-rw-r--r--compiler/driver/compiler_driver.cc14
-rw-r--r--compiler/driver/compiler_driver.h16
-rw-r--r--compiler/driver/compiler_driver_test.cc7
-rw-r--r--compiler/elf_writer_mclinker.cc7
-rw-r--r--compiler/image_writer.cc14
-rw-r--r--compiler/oat_test.cc4
-rw-r--r--compiler/oat_writer.cc5
-rw-r--r--oatdump/oatdump.cc4
-rw-r--r--runtime/class_linker-inl.h54
-rw-r--r--runtime/class_linker.cc151
-rw-r--r--runtime/class_linker.h105
-rw-r--r--runtime/class_linker_test.cc7
-rw-r--r--runtime/entrypoints/entrypoint_utils.h42
-rw-r--r--runtime/entrypoints/interpreter/interpreter_entrypoints.cc3
-rw-r--r--runtime/entrypoints/portable/portable_invoke_entrypoints.cc11
-rw-r--r--runtime/entrypoints/portable/portable_trampoline_entrypoints.cc10
-rw-r--r--runtime/entrypoints/quick/quick_trampoline_entrypoints.cc14
-rw-r--r--runtime/handle.h20
-rw-r--r--runtime/interpreter/interpreter.cc15
-rw-r--r--runtime/interpreter/interpreter_common.cc6
-rw-r--r--runtime/interpreter/interpreter_common.h15
-rw-r--r--runtime/jni_internal.cc2
-rw-r--r--runtime/jni_internal.h2
-rw-r--r--runtime/mirror/array.cc8
-rw-r--r--runtime/mirror/array.h4
-rw-r--r--runtime/mirror/art_method.cc2
-rw-r--r--runtime/mirror/art_method.h2
-rw-r--r--runtime/mirror/stack_trace_element.cc10
-rw-r--r--runtime/mirror/stack_trace_element.h10
-rw-r--r--runtime/mirror/string.cc2
-rw-r--r--runtime/mirror/string.h2
-rw-r--r--runtime/monitor.cc2
-rw-r--r--runtime/monitor.h2
-rw-r--r--runtime/native/dalvik_system_VMRuntime.cc8
-rw-r--r--runtime/verifier/method_verifier.cc18
-rw-r--r--runtime/verifier/method_verifier.h12
38 files changed, 339 insertions, 306 deletions
diff --git a/compiler/common_compiler_test.h b/compiler/common_compiler_test.h
index fb6c625926..5050d4eb78 100644
--- a/compiler/common_compiler_test.h
+++ b/compiler/common_compiler_test.h
@@ -377,7 +377,7 @@ class CommonCompilerTest : public CommonRuntimeTest {
timings.EndSplit();
}
- void CompileDirectMethod(Handle<mirror::ClassLoader>& class_loader, const char* class_name,
+ void CompileDirectMethod(Handle<mirror::ClassLoader> class_loader, const char* class_name,
const char* method_name, const char* signature)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
std::string class_descriptor(DotToDescriptor(class_name));
@@ -390,7 +390,7 @@ class CommonCompilerTest : public CommonRuntimeTest {
CompileMethod(method);
}
- void CompileVirtualMethod(Handle<mirror::ClassLoader>& class_loader, const char* class_name,
+ void CompileVirtualMethod(Handle<mirror::ClassLoader> class_loader, const char* class_name,
const char* method_name, const char* signature)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
std::string class_descriptor(DotToDescriptor(class_name));
diff --git a/compiler/driver/compiler_driver-inl.h b/compiler/driver/compiler_driver-inl.h
index 08fd386226..45abfcc895 100644
--- a/compiler/driver/compiler_driver-inl.h
+++ b/compiler/driver/compiler_driver-inl.h
@@ -42,8 +42,8 @@ inline mirror::ClassLoader* CompilerDriver::GetClassLoader(ScopedObjectAccess& s
}
inline mirror::Class* CompilerDriver::ResolveCompilingMethodsClass(
- ScopedObjectAccess& soa, const Handle<mirror::DexCache>& dex_cache,
- const Handle<mirror::ClassLoader>& class_loader, const DexCompilationUnit* mUnit) {
+ ScopedObjectAccess& soa, Handle<mirror::DexCache> dex_cache,
+ Handle<mirror::ClassLoader> class_loader, const DexCompilationUnit* mUnit) {
DCHECK_EQ(dex_cache->GetDexFile(), mUnit->GetDexFile());
DCHECK_EQ(class_loader.Get(), soa.Decode<mirror::ClassLoader*>(mUnit->GetClassLoader()));
const DexFile::MethodId& referrer_method_id =
@@ -59,8 +59,8 @@ inline mirror::Class* CompilerDriver::ResolveCompilingMethodsClass(
}
inline mirror::ArtField* CompilerDriver::ResolveField(
- ScopedObjectAccess& soa, const Handle<mirror::DexCache>& dex_cache,
- const Handle<mirror::ClassLoader>& class_loader, const DexCompilationUnit* mUnit,
+ ScopedObjectAccess& soa, Handle<mirror::DexCache> dex_cache,
+ Handle<mirror::ClassLoader> class_loader, const DexCompilationUnit* mUnit,
uint32_t field_idx, bool is_static) {
DCHECK_EQ(dex_cache->GetDexFile(), mUnit->GetDexFile());
DCHECK_EQ(class_loader.Get(), soa.Decode<mirror::ClassLoader*>(mUnit->GetClassLoader()));
@@ -165,13 +165,14 @@ inline std::pair<bool, bool> CompilerDriver::IsFastStaticField(
}
inline mirror::ArtMethod* CompilerDriver::ResolveMethod(
- ScopedObjectAccess& soa, const Handle<mirror::DexCache>& dex_cache,
- const Handle<mirror::ClassLoader>& class_loader, const DexCompilationUnit* mUnit,
+ ScopedObjectAccess& soa, Handle<mirror::DexCache> dex_cache,
+ Handle<mirror::ClassLoader> class_loader, const DexCompilationUnit* mUnit,
uint32_t method_idx, InvokeType invoke_type) {
- DCHECK(dex_cache->GetDexFile() == mUnit->GetDexFile());
- DCHECK(class_loader.Get() == soa.Decode<mirror::ClassLoader*>(mUnit->GetClassLoader()));
+ DCHECK_EQ(dex_cache->GetDexFile(), mUnit->GetDexFile());
+ DCHECK_EQ(class_loader.Get(), soa.Decode<mirror::ClassLoader*>(mUnit->GetClassLoader()));
mirror::ArtMethod* resolved_method = mUnit->GetClassLinker()->ResolveMethod(
- *mUnit->GetDexFile(), method_idx, dex_cache, class_loader, nullptr, invoke_type);
+ *mUnit->GetDexFile(), method_idx, dex_cache, class_loader, NullHandle<mirror::ArtMethod>(),
+ invoke_type);
DCHECK_EQ(resolved_method == nullptr, soa.Self()->IsExceptionPending());
if (UNLIKELY(resolved_method == nullptr)) {
// Clean up any exception left by type resolution.
@@ -206,8 +207,8 @@ inline uint16_t CompilerDriver::GetResolvedMethodVTableIndex(
}
inline int CompilerDriver::IsFastInvoke(
- ScopedObjectAccess& soa, const Handle<mirror::DexCache>& dex_cache,
- const Handle<mirror::ClassLoader>& class_loader, const DexCompilationUnit* mUnit,
+ ScopedObjectAccess& soa, Handle<mirror::DexCache> dex_cache,
+ Handle<mirror::ClassLoader> class_loader, const DexCompilationUnit* mUnit,
mirror::Class* referrer_class, mirror::ArtMethod* resolved_method, InvokeType* invoke_type,
MethodReference* target_method, const MethodReference* devirt_target,
uintptr_t* direct_code, uintptr_t* direct_method) {
@@ -256,15 +257,17 @@ inline int CompilerDriver::IsFastInvoke(
ClassLinker* class_linker = mUnit->GetClassLinker();
if (LIKELY(devirt_target->dex_file == mUnit->GetDexFile())) {
called_method = class_linker->ResolveMethod(*devirt_target->dex_file,
- devirt_target->dex_method_index,
- dex_cache, class_loader, NULL, kVirtual);
+ devirt_target->dex_method_index, dex_cache,
+ class_loader, NullHandle<mirror::ArtMethod>(),
+ kVirtual);
} else {
StackHandleScope<1> hs(soa.Self());
Handle<mirror::DexCache> target_dex_cache(
hs.NewHandle(class_linker->FindDexCache(*devirt_target->dex_file)));
called_method = class_linker->ResolveMethod(*devirt_target->dex_file,
devirt_target->dex_method_index,
- target_dex_cache, class_loader, NULL, kVirtual);
+ target_dex_cache, class_loader,
+ NullHandle<mirror::ArtMethod>(), kVirtual);
}
CHECK(called_method != NULL);
CHECK(!called_method->IsAbstract());
diff --git a/compiler/driver/compiler_driver.cc b/compiler/driver/compiler_driver.cc
index 0f41d2b2f6..330456180b 100644
--- a/compiler/driver/compiler_driver.cc
+++ b/compiler/driver/compiler_driver.cc
@@ -511,7 +511,7 @@ void CompilerDriver::CompileAll(jobject class_loader,
}
static DexToDexCompilationLevel GetDexToDexCompilationlevel(
- Thread* self, Handle<mirror::ClassLoader>& class_loader, const DexFile& dex_file,
+ Thread* self, Handle<mirror::ClassLoader> class_loader, const DexFile& dex_file,
const DexFile::ClassDef& class_def) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
const char* descriptor = dex_file.GetClassDescriptor(class_def);
ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
@@ -731,11 +731,11 @@ void CompilerDriver::LoadImageClasses(TimingLogger* timings)
for (const std::pair<uint16_t, const DexFile*>& exception_type : unresolved_exception_types) {
uint16_t exception_type_idx = exception_type.first;
const DexFile* dex_file = exception_type.second;
- StackHandleScope<3> hs(self);
+ StackHandleScope<2> hs(self);
Handle<mirror::DexCache> dex_cache(hs.NewHandle(class_linker->FindDexCache(*dex_file)));
- auto class_loader(hs.NewHandle<mirror::ClassLoader>(nullptr));
Handle<mirror::Class> klass(hs.NewHandle(
- class_linker->ResolveType(*dex_file, exception_type_idx, dex_cache, class_loader)));
+ class_linker->ResolveType(*dex_file, exception_type_idx, dex_cache,
+ NullHandle<mirror::ClassLoader>())));
if (klass.Get() == NULL) {
const DexFile::TypeId& type_id = dex_file->GetTypeId(exception_type_idx);
const char* descriptor = dex_file->GetTypeDescriptor(type_id);
@@ -1541,7 +1541,8 @@ static void ResolveClassFieldsAndMethods(const ParallelCompilationManager* manag
if (resolve_fields_and_methods) {
while (it.HasNextDirectMethod()) {
mirror::ArtMethod* method = class_linker->ResolveMethod(dex_file, it.GetMemberIndex(),
- dex_cache, class_loader, NULL,
+ dex_cache, class_loader,
+ NullHandle<mirror::ArtMethod>(),
it.GetMethodInvokeType(class_def));
if (method == NULL) {
CHECK(soa.Self()->IsExceptionPending());
@@ -1551,7 +1552,8 @@ static void ResolveClassFieldsAndMethods(const ParallelCompilationManager* manag
}
while (it.HasNextVirtualMethod()) {
mirror::ArtMethod* method = class_linker->ResolveMethod(dex_file, it.GetMemberIndex(),
- dex_cache, class_loader, NULL,
+ dex_cache, class_loader,
+ NullHandle<mirror::ArtMethod>(),
it.GetMethodInvokeType(class_def));
if (method == NULL) {
CHECK(soa.Self()->IsExceptionPending());
diff --git a/compiler/driver/compiler_driver.h b/compiler/driver/compiler_driver.h
index abca659cce..14ccb5047b 100644
--- a/compiler/driver/compiler_driver.h
+++ b/compiler/driver/compiler_driver.h
@@ -221,15 +221,15 @@ class CompilerDriver {
// Resolve compiling method's class. Returns nullptr on failure.
mirror::Class* ResolveCompilingMethodsClass(
- ScopedObjectAccess& soa, const Handle<mirror::DexCache>& dex_cache,
- const Handle<mirror::ClassLoader>& class_loader, const DexCompilationUnit* mUnit)
+ ScopedObjectAccess& soa, Handle<mirror::DexCache> dex_cache,
+ Handle<mirror::ClassLoader> class_loader, const DexCompilationUnit* mUnit)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
// Resolve a field. Returns nullptr on failure, including incompatible class change.
// NOTE: Unlike ClassLinker's ResolveField(), this method enforces is_static.
mirror::ArtField* ResolveField(
- ScopedObjectAccess& soa, const Handle<mirror::DexCache>& dex_cache,
- const Handle<mirror::ClassLoader>& class_loader, const DexCompilationUnit* mUnit,
+ ScopedObjectAccess& soa, Handle<mirror::DexCache> dex_cache,
+ Handle<mirror::ClassLoader> class_loader, const DexCompilationUnit* mUnit,
uint32_t field_idx, bool is_static)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
@@ -258,8 +258,8 @@ class CompilerDriver {
// Resolve a method. Returns nullptr on failure, including incompatible class change.
mirror::ArtMethod* ResolveMethod(
- ScopedObjectAccess& soa, const Handle<mirror::DexCache>& dex_cache,
- const Handle<mirror::ClassLoader>& class_loader, const DexCompilationUnit* mUnit,
+ ScopedObjectAccess& soa, Handle<mirror::DexCache> dex_cache,
+ Handle<mirror::ClassLoader> class_loader, const DexCompilationUnit* mUnit,
uint32_t method_idx, InvokeType invoke_type)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
@@ -277,8 +277,8 @@ class CompilerDriver {
// Can we fast-path an INVOKE? If no, returns 0. If yes, returns a non-zero opaque flags value
// for ProcessedInvoke() and computes the necessary lowering info.
int IsFastInvoke(
- ScopedObjectAccess& soa, const Handle<mirror::DexCache>& dex_cache,
- const Handle<mirror::ClassLoader>& class_loader, const DexCompilationUnit* mUnit,
+ ScopedObjectAccess& soa, Handle<mirror::DexCache> dex_cache,
+ Handle<mirror::ClassLoader> class_loader, const DexCompilationUnit* mUnit,
mirror::Class* referrer_class, mirror::ArtMethod* resolved_method, InvokeType* invoke_type,
MethodReference* target_method, const MethodReference* devirt_target,
uintptr_t* direct_code, uintptr_t* direct_method)
diff --git a/compiler/driver/compiler_driver_test.cc b/compiler/driver/compiler_driver_test.cc
index 4efd27d476..964dfeb5b1 100644
--- a/compiler/driver/compiler_driver_test.cc
+++ b/compiler/driver/compiler_driver_test.cc
@@ -152,10 +152,9 @@ TEST_F(CompilerDriverTest, AbstractMethodErrorStub) {
jobject class_loader;
{
ScopedObjectAccess soa(Thread::Current());
- StackHandleScope<1> hs(soa.Self());
- auto null_loader(hs.NewHandle<mirror::ClassLoader>(nullptr));
- CompileVirtualMethod(null_loader, "java.lang.Class", "isFinalizable", "()Z");
- CompileDirectMethod(null_loader, "java.lang.Object", "<init>", "()V");
+ CompileVirtualMethod(NullHandle<mirror::ClassLoader>(), "java.lang.Class", "isFinalizable",
+ "()Z");
+ CompileDirectMethod(NullHandle<mirror::ClassLoader>(), "java.lang.Object", "<init>", "()V");
class_loader = LoadDex("AbstractMethod");
}
ASSERT_TRUE(class_loader != NULL);
diff --git a/compiler/elf_writer_mclinker.cc b/compiler/elf_writer_mclinker.cc
index 0e2721014a..3dba426242 100644
--- a/compiler/elf_writer_mclinker.cc
+++ b/compiler/elf_writer_mclinker.cc
@@ -361,10 +361,11 @@ void ElfWriterMclinker::FixupOatMethodOffsets(const std::vector<const DexFile*>&
ClassLinker* linker = Runtime::Current()->GetClassLinker();
// Unchecked as we hold mutator_lock_ on entry.
ScopedObjectAccessUnchecked soa(Thread::Current());
- StackHandleScope<2> hs(soa.Self());
+ StackHandleScope<1> hs(soa.Self());
Handle<mirror::DexCache> dex_cache(hs.NewHandle(linker->FindDexCache(dex_file)));
- auto class_loader(hs.NewHandle<mirror::ClassLoader>(nullptr));
- method = linker->ResolveMethod(dex_file, method_idx, dex_cache, class_loader, NULL, invoke_type);
+ method = linker->ResolveMethod(dex_file, method_idx, dex_cache,
+ NullHandle<mirror::ClassLoader>(),
+ NullHandle<mirror::ArtMethod>(), invoke_type);
CHECK(method != NULL);
}
const CompiledMethod* compiled_method =
diff --git a/compiler/image_writer.cc b/compiler/image_writer.cc
index 70144c80fc..be53926ac8 100644
--- a/compiler/image_writer.cc
+++ b/compiler/image_writer.cc
@@ -695,15 +695,14 @@ void ImageWriter::FixupMethod(ArtMethod* orig, ArtMethod* copy) {
static ArtMethod* GetTargetMethod(const CompilerDriver::CallPatchInformation* patch)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
- StackHandleScope<2> hs(Thread::Current());
+ StackHandleScope<1> hs(Thread::Current());
Handle<mirror::DexCache> dex_cache(
hs.NewHandle(class_linker->FindDexCache(*patch->GetTargetDexFile())));
- auto class_loader(hs.NewHandle<mirror::ClassLoader>(nullptr));
ArtMethod* method = class_linker->ResolveMethod(*patch->GetTargetDexFile(),
patch->GetTargetMethodIdx(),
dex_cache,
- class_loader,
- NULL,
+ NullHandle<mirror::ClassLoader>(),
+ NullHandle<mirror::ArtMethod>(),
patch->GetTargetInvokeType());
CHECK(method != NULL)
<< patch->GetTargetDexFile()->GetLocation() << " " << patch->GetTargetMethodIdx();
@@ -721,11 +720,8 @@ static Class* GetTargetType(const CompilerDriver::TypePatchInformation* patch)
ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
StackHandleScope<2> hs(Thread::Current());
Handle<mirror::DexCache> dex_cache(hs.NewHandle(class_linker->FindDexCache(patch->GetDexFile())));
- auto class_loader(hs.NewHandle<mirror::ClassLoader>(nullptr));
- Class* klass = class_linker->ResolveType(patch->GetDexFile(),
- patch->GetTargetTypeIdx(),
- dex_cache,
- class_loader);
+ Class* klass = class_linker->ResolveType(patch->GetDexFile(), patch->GetTargetTypeIdx(),
+ dex_cache, NullHandle<mirror::ClassLoader>());
CHECK(klass != NULL)
<< patch->GetDexFile().GetLocation() << " " << patch->GetTargetTypeIdx();
CHECK(dex_cache->GetResolvedTypes()->Get(patch->GetTargetTypeIdx()) == klass)
diff --git a/compiler/oat_test.cc b/compiler/oat_test.cc
index a7ee82edd3..6812f3c9df 100644
--- a/compiler/oat_test.cc
+++ b/compiler/oat_test.cc
@@ -154,8 +154,8 @@ TEST_F(OatTest, WriteRead) {
}
const char* descriptor = dex_file->GetClassDescriptor(class_def);
StackHandleScope<1> hs(soa.Self());
- auto loader(hs.NewHandle<mirror::ClassLoader>(nullptr));
- mirror::Class* klass = class_linker->FindClass(soa.Self(), descriptor, loader);
+ mirror::Class* klass = class_linker->FindClass(soa.Self(), descriptor,
+ NullHandle<mirror::ClassLoader>());
const OatFile::OatClass oat_class = oat_dex_file->GetOatClass(i);
CHECK_EQ(mirror::Class::Status::kStatusNotReady, oat_class.GetStatus()) << descriptor;
diff --git a/compiler/oat_writer.cc b/compiler/oat_writer.cc
index bace25c84e..5d532abdd6 100644
--- a/compiler/oat_writer.cc
+++ b/compiler/oat_writer.cc
@@ -513,9 +513,10 @@ class OatWriter::InitImageMethodVisitor : public OatDexMethodVisitor {
ScopedObjectAccessUnchecked soa(Thread::Current());
StackHandleScope<2> hs(soa.Self());
Handle<mirror::DexCache> dex_cache(hs.NewHandle(linker->FindDexCache(*dex_file_)));
- auto class_loader = hs.NewHandle<mirror::ClassLoader>(nullptr);
mirror::ArtMethod* method = linker->ResolveMethod(*dex_file_, it.GetMemberIndex(), dex_cache,
- class_loader, nullptr, invoke_type);
+ NullHandle<mirror::ClassLoader>(),
+ NullHandle<mirror::ArtMethod>(),
+ invoke_type);
CHECK(method != NULL);
// Portable code offsets are set by ElfWriterMclinker::FixupCompiledCodeOffset after linking.
method->SetQuickOatCodeOffset(offsets.code_offset_);
diff --git a/oatdump/oatdump.cc b/oatdump/oatdump.cc
index dcae50284a..8fd6b6d02f 100644
--- a/oatdump/oatdump.cc
+++ b/oatdump/oatdump.cc
@@ -417,10 +417,10 @@ class OatDumper {
Runtime* runtime = Runtime::Current();
if (runtime != nullptr) {
ScopedObjectAccess soa(Thread::Current());
- StackHandleScope<2> hs(soa.Self());
+ StackHandleScope<1> hs(soa.Self());
Handle<mirror::DexCache> dex_cache(
hs.NewHandle(runtime->GetClassLinker()->FindDexCache(dex_file)));
- auto class_loader(hs.NewHandle<mirror::ClassLoader>(nullptr));
+ NullHandle<mirror::ClassLoader> class_loader;
verifier::MethodVerifier verifier(&dex_file, &dex_cache, &class_loader, &class_def,
code_item, dex_method_idx, nullptr, method_access_flags,
true, true);
diff --git a/runtime/class_linker-inl.h b/runtime/class_linker-inl.h
index ac86014545..84afb2d3f6 100644
--- a/runtime/class_linker-inl.h
+++ b/runtime/class_linker-inl.h
@@ -34,9 +34,7 @@ inline bool ClassLinker::IsInBootClassPath(const char* descriptor) {
}
inline mirror::Class* ClassLinker::FindSystemClass(Thread* self, const char* descriptor) {
- StackHandleScope<1> hs(self);
- auto class_loader = hs.NewHandle<mirror::ClassLoader>(nullptr);
- return FindClass(self, descriptor, class_loader);
+ return FindClass(self, descriptor, NullHandle<mirror::ClassLoader>());
}
inline mirror::Class* ClassLinker::FindArrayClass(Thread* self, mirror::Class* element_class) {
@@ -110,31 +108,47 @@ inline mirror::Class* ClassLinker::ResolveType(uint16_t type_idx, mirror::ArtFie
return resolved_type;
}
-inline mirror::ArtMethod* ClassLinker::ResolveMethod(uint32_t method_idx,
- mirror::ArtMethod* referrer,
- InvokeType type) {
+inline mirror::ArtMethod* ClassLinker::GetResolvedMethod(uint32_t method_idx,
+ mirror::ArtMethod* referrer,
+ InvokeType type) {
mirror::ArtMethod* resolved_method =
referrer->GetDexCacheResolvedMethods()->Get(method_idx);
- if (UNLIKELY(resolved_method == NULL || resolved_method->IsRuntimeMethod())) {
- mirror::Class* declaring_class = referrer->GetDeclaringClass();
- StackHandleScope<2> hs(Thread::Current());
- Handle<mirror::DexCache> dex_cache(hs.NewHandle(declaring_class->GetDexCache()));
- Handle<mirror::ClassLoader> class_loader(hs.NewHandle(declaring_class->GetClassLoader()));
- const DexFile& dex_file = *dex_cache->GetDexFile();
- resolved_method = ResolveMethod(dex_file, method_idx, dex_cache, class_loader, referrer, type);
- if (resolved_method != nullptr) {
- DCHECK_EQ(dex_cache->GetResolvedMethod(method_idx), resolved_method);
- }
+ if (resolved_method == nullptr || resolved_method->IsRuntimeMethod()) {
+ return nullptr;
}
return resolved_method;
}
-inline mirror::ArtField* ClassLinker::ResolveField(uint32_t field_idx,
- mirror::ArtMethod* referrer,
+inline mirror::ArtMethod* ClassLinker::ResolveMethod(Thread* self, uint32_t method_idx,
+ mirror::ArtMethod** referrer,
+ InvokeType type) {
+ mirror::ArtMethod* resolved_method = GetResolvedMethod(method_idx, *referrer, type);
+ if (LIKELY(resolved_method != nullptr)) {
+ return resolved_method;
+ }
+ mirror::Class* declaring_class = (*referrer)->GetDeclaringClass();
+ StackHandleScope<3> hs(self);
+ Handle<mirror::DexCache> h_dex_cache(hs.NewHandle(declaring_class->GetDexCache()));
+ Handle<mirror::ClassLoader> h_class_loader(hs.NewHandle(declaring_class->GetClassLoader()));
+ HandleWrapper<mirror::ArtMethod> h_referrer(hs.NewHandleWrapper(referrer));
+ const DexFile* dex_file = h_dex_cache->GetDexFile();
+ resolved_method = ResolveMethod(*dex_file, method_idx, h_dex_cache, h_class_loader, h_referrer,
+ type);
+ if (resolved_method != nullptr) {
+ DCHECK_EQ(h_dex_cache->GetResolvedMethod(method_idx), resolved_method);
+ }
+ return resolved_method;
+}
+
+inline mirror::ArtField* ClassLinker::GetResolvedField(uint32_t field_idx,
+ mirror::Class* field_declaring_class) {
+ return field_declaring_class->GetDexCache()->GetResolvedField(field_idx);
+}
+
+inline mirror::ArtField* ClassLinker::ResolveField(uint32_t field_idx, mirror::ArtMethod* referrer,
bool is_static) {
mirror::Class* declaring_class = referrer->GetDeclaringClass();
- mirror::ArtField* resolved_field =
- declaring_class->GetDexCache()->GetResolvedField(field_idx);
+ mirror::ArtField* resolved_field = GetResolvedField(field_idx, declaring_class);
if (UNLIKELY(resolved_field == NULL)) {
StackHandleScope<2> hs(Thread::Current());
Handle<mirror::DexCache> dex_cache(hs.NewHandle(declaring_class->GetDexCache()));
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index c7302b5a73..afff7a2e7b 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -1369,7 +1369,7 @@ static mirror::Class* EnsureResolved(Thread* self, mirror::Class* klass)
}
mirror::Class* ClassLinker::FindClass(Thread* self, const char* descriptor,
- const Handle<mirror::ClassLoader>& class_loader) {
+ Handle<mirror::ClassLoader> class_loader) {
DCHECK_NE(*descriptor, '\0') << "descriptor is empty string";
DCHECK(self != nullptr);
self->AssertNoPendingException();
@@ -1390,8 +1390,7 @@ mirror::Class* ClassLinker::FindClass(Thread* self, const char* descriptor,
DexFile::ClassPathEntry pair = DexFile::FindInClassPath(descriptor, boot_class_path_);
if (pair.second != NULL) {
StackHandleScope<1> hs(self);
- auto class_loader = hs.NewHandle<mirror::ClassLoader>(nullptr);
- return DefineClass(descriptor, class_loader, *pair.first, *pair.second);
+ return DefineClass(descriptor, NullHandle<mirror::ClassLoader>(), *pair.first, *pair.second);
}
} else if (Runtime::Current()->UseCompileTimeClassPath()) {
// First try the boot class path, we check the descriptor first to avoid an unnecessary
@@ -1452,7 +1451,7 @@ mirror::Class* ClassLinker::FindClass(Thread* self, const char* descriptor,
}
mirror::Class* ClassLinker::DefineClass(const char* descriptor,
- const Handle<mirror::ClassLoader>& class_loader,
+ Handle<mirror::ClassLoader> class_loader,
const DexFile& dex_file,
const DexFile::ClassDef& dex_class_def) {
Thread* self = Thread::Current();
@@ -1796,10 +1795,9 @@ void ClassLinker::FixupStaticTrampolines(mirror::Class* klass) {
// Ignore virtual methods on the iterator.
}
-void ClassLinker::LinkCode(const Handle<mirror::ArtMethod>& method,
- const OatFile::OatClass* oat_class,
+void ClassLinker::LinkCode(Handle<mirror::ArtMethod> method, const OatFile::OatClass* oat_class,
const DexFile& dex_file, uint32_t dex_method_index,
- uint32_t method_index) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+ uint32_t method_index) {
// Method shouldn't have already been linked.
DCHECK(method->GetEntryPointFromQuickCompiledCode() == nullptr);
DCHECK(method->GetEntryPointFromPortableCompiledCode() == nullptr);
@@ -1871,7 +1869,7 @@ void ClassLinker::LinkCode(const Handle<mirror::ArtMethod>& method,
void ClassLinker::LoadClass(const DexFile& dex_file,
const DexFile::ClassDef& dex_class_def,
- const Handle<mirror::Class>& klass,
+ Handle<mirror::Class> klass,
mirror::ClassLoader* class_loader) {
CHECK(klass.Get() != NULL);
CHECK(klass->GetDexCache() != NULL);
@@ -1909,7 +1907,7 @@ void ClassLinker::LoadClass(const DexFile& dex_file,
void ClassLinker::LoadClassMembers(const DexFile& dex_file,
const byte* class_data,
- const Handle<mirror::Class>& klass,
+ Handle<mirror::Class> klass,
mirror::ClassLoader* class_loader,
const OatFile::OatClass* oat_class) {
// Load fields.
@@ -2007,8 +2005,7 @@ void ClassLinker::LoadClassMembers(const DexFile& dex_file,
}
void ClassLinker::LoadField(const DexFile& /*dex_file*/, const ClassDataItemIterator& it,
- const Handle<mirror::Class>& klass,
- const Handle<mirror::ArtField>& dst) {
+ Handle<mirror::Class> klass, Handle<mirror::ArtField> dst) {
uint32_t field_idx = it.GetMemberIndex();
dst->SetDexFieldIndex(field_idx);
dst->SetDeclaringClass(klass.Get());
@@ -2017,7 +2014,7 @@ void ClassLinker::LoadField(const DexFile& /*dex_file*/, const ClassDataItemIter
mirror::ArtMethod* ClassLinker::LoadMethod(Thread* self, const DexFile& dex_file,
const ClassDataItemIterator& it,
- const Handle<mirror::Class>& klass) {
+ Handle<mirror::Class> klass) {
uint32_t dex_method_idx = it.GetMemberIndex();
const DexFile::MethodId& method_id = dex_file.GetMethodId(dex_method_idx);
const char* method_name = dex_file.StringDataByIdx(method_id.name_idx_);
@@ -2088,7 +2085,7 @@ void ClassLinker::AppendToBootClassPath(const DexFile& dex_file) {
}
void ClassLinker::AppendToBootClassPath(const DexFile& dex_file,
- const Handle<mirror::DexCache>& dex_cache) {
+ Handle<mirror::DexCache> dex_cache) {
CHECK(dex_cache.Get() != NULL) << dex_file.GetLocation();
boot_class_path_.push_back(&dex_file);
RegisterDexFile(dex_file, dex_cache);
@@ -2110,7 +2107,7 @@ bool ClassLinker::IsDexFileRegistered(const DexFile& dex_file) const {
}
void ClassLinker::RegisterDexFileLocked(const DexFile& dex_file,
- const Handle<mirror::DexCache>& dex_cache) {
+ Handle<mirror::DexCache> dex_cache) {
dex_lock_.AssertExclusiveHeld(Thread::Current());
CHECK(dex_cache.Get() != NULL) << dex_file.GetLocation();
CHECK(dex_cache->GetLocation()->Equals(dex_file.GetLocation()))
@@ -2147,7 +2144,7 @@ void ClassLinker::RegisterDexFile(const DexFile& dex_file) {
}
void ClassLinker::RegisterDexFile(const DexFile& dex_file,
- const Handle<mirror::DexCache>& dex_cache) {
+ Handle<mirror::DexCache> dex_cache) {
WriterMutexLock mu(Thread::Current(), dex_lock_);
RegisterDexFileLocked(dex_file, dex_cache);
}
@@ -2224,7 +2221,7 @@ mirror::Class* ClassLinker::InitializePrimitiveClass(mirror::Class* primitive_cl
//
// Returns NULL with an exception raised on failure.
mirror::Class* ClassLinker::CreateArrayClass(Thread* self, const char* descriptor,
- const Handle<mirror::ClassLoader>& class_loader) {
+ Handle<mirror::ClassLoader> class_loader) {
// Identify the underlying component type
CHECK_EQ('[', descriptor[0]);
StackHandleScope<2> hs(self);
@@ -2416,7 +2413,7 @@ bool ClassLinker::RemoveClass(const char* descriptor, const mirror::ClassLoader*
it != end && it->first == hash;
++it) {
mirror::Class* klass = it->second;
- if (klass->GetClassLoader() == class_loader && descriptor == klass->GetDescriptor()) {
+ if (klass->GetClassLoader() == class_loader && klass->DescriptorEquals(descriptor)) {
class_table_.erase(it);
return true;
}
@@ -2460,13 +2457,13 @@ mirror::Class* ClassLinker::LookupClassFromTableLocked(const char* descriptor,
auto end = class_table_.end();
for (auto it = class_table_.lower_bound(hash); it != end && it->first == hash; ++it) {
mirror::Class* klass = it->second;
- if (klass->GetClassLoader() == class_loader && descriptor == klass->GetDescriptor()) {
+ if (klass->GetClassLoader() == class_loader && klass->DescriptorEquals(descriptor)) {
if (kIsDebugBuild) {
// Check for duplicates in the table.
for (++it; it != end && it->first == hash; ++it) {
mirror::Class* klass2 = it->second;
- CHECK(!((klass2->GetClassLoader() == class_loader) &&
- descriptor == klass2->GetDescriptor()))
+ CHECK(!(klass2->GetClassLoader() == class_loader &&
+ klass2->DescriptorEquals(descriptor)))
<< PrettyClass(klass) << " " << klass << " " << klass->GetClassLoader() << " "
<< PrettyClass(klass2) << " " << klass2 << " " << klass2->GetClassLoader();
}
@@ -2557,13 +2554,13 @@ void ClassLinker::LookupClasses(const char* descriptor, std::vector<mirror::Clas
for (auto it = class_table_.lower_bound(hash), end = class_table_.end();
it != end && it->first == hash; ++it) {
mirror::Class* klass = it->second;
- if (descriptor == klass->GetDescriptor()) {
+ if (klass->DescriptorEquals(descriptor)) {
result.push_back(klass);
}
}
}
-void ClassLinker::VerifyClass(const Handle<mirror::Class>& klass) {
+void ClassLinker::VerifyClass(Handle<mirror::Class> klass) {
// TODO: assert that the monitor on the Class is held
Thread* self = Thread::Current();
ObjectLock<mirror::Class> lock(self, klass);
@@ -2776,7 +2773,7 @@ bool ClassLinker::VerifyClassUsingOatFile(const DexFile& dex_file, mirror::Class
}
void ClassLinker::ResolveClassExceptionHandlerTypes(const DexFile& dex_file,
- const Handle<mirror::Class>& klass) {
+ Handle<mirror::Class> klass) {
for (size_t i = 0; i < klass->NumDirectMethods(); i++) {
ResolveMethodExceptionHandlerTypes(dex_file, klass->GetDirectMethod(i));
}
@@ -2817,7 +2814,7 @@ void ClassLinker::ResolveMethodExceptionHandlerTypes(const DexFile& dex_file,
static void CheckProxyConstructor(mirror::ArtMethod* constructor);
static void CheckProxyMethod(mirror::ArtMethod* method,
- Handle<mirror::ArtMethod>& prototype);
+ Handle<mirror::ArtMethod> prototype);
mirror::Class* ClassLinker::CreateProxyClass(ScopedObjectAccessAlreadyRunnable& soa, jstring name,
jobjectArray interfaces, jobject loader,
@@ -2999,7 +2996,7 @@ mirror::ArtMethod* ClassLinker::FindMethodForProxy(mirror::Class* proxy_class,
mirror::ArtMethod* ClassLinker::CreateProxyConstructor(Thread* self,
- const Handle<mirror::Class>& klass,
+ Handle<mirror::Class> klass,
mirror::Class* proxy_class) {
// Create constructor for Proxy that must initialize h
mirror::ObjectArray<mirror::ArtMethod>* proxy_direct_methods =
@@ -3030,8 +3027,8 @@ static void CheckProxyConstructor(mirror::ArtMethod* constructor)
}
mirror::ArtMethod* ClassLinker::CreateProxyMethod(Thread* self,
- const Handle<mirror::Class>& klass,
- const Handle<mirror::ArtMethod>& prototype) {
+ Handle<mirror::Class> klass,
+ Handle<mirror::ArtMethod> prototype) {
// Ensure prototype is in dex cache so that we can use the dex cache to look up the overridden
// prototype method
prototype->GetDeclaringClass()->GetDexCache()->SetResolvedMethod(prototype->GetDexMethodIndex(),
@@ -3058,8 +3055,7 @@ mirror::ArtMethod* ClassLinker::CreateProxyMethod(Thread* self,
return method;
}
-static void CheckProxyMethod(mirror::ArtMethod* method,
- Handle<mirror::ArtMethod>& prototype)
+static void CheckProxyMethod(mirror::ArtMethod* method, Handle<mirror::ArtMethod> prototype)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
// Basic sanity
CHECK(!prototype->IsFinal());
@@ -3119,7 +3115,7 @@ bool ClassLinker::IsInitialized() const {
return init_done_;
}
-bool ClassLinker::InitializeClass(const Handle<mirror::Class>& klass, bool can_init_statics,
+bool ClassLinker::InitializeClass(Handle<mirror::Class> klass, bool can_init_statics,
bool can_init_parents) {
// see JLS 3rd edition, 12.4.2 "Detailed Initialization Procedure" for the locking protocol
@@ -3286,7 +3282,7 @@ bool ClassLinker::InitializeClass(const Handle<mirror::Class>& klass, bool can_i
return success;
}
-bool ClassLinker::WaitForInitializeClass(const Handle<mirror::Class>& klass, Thread* self,
+bool ClassLinker::WaitForInitializeClass(Handle<mirror::Class> klass, Thread* self,
ObjectLock<mirror::Class>& lock)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
while (true) {
@@ -3326,7 +3322,7 @@ bool ClassLinker::WaitForInitializeClass(const Handle<mirror::Class>& klass, Thr
LOG(FATAL) << "Not Reached" << PrettyClass(klass.Get());
}
-bool ClassLinker::ValidateSuperClassDescriptors(const Handle<mirror::Class>& klass) {
+bool ClassLinker::ValidateSuperClassDescriptors(Handle<mirror::Class> klass) {
if (klass->IsInterface()) {
return true;
}
@@ -3368,18 +3364,12 @@ bool ClassLinker::ValidateSuperClassDescriptors(const Handle<mirror::Class>& kla
return true;
}
-bool ClassLinker::EnsureInitialized(const Handle<mirror::Class>& c, bool can_init_fields,
+bool ClassLinker::EnsureInitialized(Handle<mirror::Class> c, bool can_init_fields,
bool can_init_parents) {
- DCHECK(c.Get() != NULL);
- if (c->IsInitialized()) {
- return true;
- }
-
- bool success = InitializeClass(c, can_init_fields, can_init_parents);
- if (!success) {
- if (can_init_fields && can_init_parents) {
- CHECK(Thread::Current()->IsExceptionPending()) << PrettyClass(c.Get());
- }
+ DCHECK(c.Get() != nullptr);
+ const bool success = c->IsInitialized() || InitializeClass(c, can_init_fields, can_init_parents);
+ if (!success && can_init_fields && can_init_parents) {
+ CHECK(Thread::Current()->IsExceptionPending()) << PrettyClass(c.Get());
}
return success;
}
@@ -3398,8 +3388,8 @@ void ClassLinker::ConstructFieldMap(const DexFile& dex_file, const DexFile::Clas
}
}
-bool ClassLinker::LinkClass(Thread* self, const Handle<mirror::Class>& klass,
- const Handle<mirror::ObjectArray<mirror::Class>>& interfaces) {
+bool ClassLinker::LinkClass(Thread* self, Handle<mirror::Class> klass,
+ Handle<mirror::ObjectArray<mirror::Class>> interfaces) {
CHECK_EQ(mirror::Class::kStatusLoaded, klass->GetStatus());
if (!LinkSuperClass(klass)) {
return false;
@@ -3420,8 +3410,7 @@ bool ClassLinker::LinkClass(Thread* self, const Handle<mirror::Class>& klass,
return true;
}
-bool ClassLinker::LoadSuperAndInterfaces(const Handle<mirror::Class>& klass,
- const DexFile& dex_file) {
+bool ClassLinker::LoadSuperAndInterfaces(Handle<mirror::Class> klass, const DexFile& dex_file) {
CHECK_EQ(mirror::Class::kStatusIdx, klass->GetStatus());
const DexFile::ClassDef& class_def = dex_file.GetClassDef(klass->GetDexClassDefIndex());
uint16_t super_class_idx = class_def.superclass_idx_;
@@ -3464,7 +3453,7 @@ bool ClassLinker::LoadSuperAndInterfaces(const Handle<mirror::Class>& klass,
return true;
}
-bool ClassLinker::LinkSuperClass(const Handle<mirror::Class>& klass) {
+bool ClassLinker::LinkSuperClass(Handle<mirror::Class> klass) {
CHECK(!klass->IsPrimitive());
mirror::Class* super = klass->GetSuperClass();
if (klass.Get() == GetClassRoot(kJavaLangObject)) {
@@ -3524,8 +3513,8 @@ bool ClassLinker::LinkSuperClass(const Handle<mirror::Class>& klass) {
}
// Populate the class vtable and itable. Compute return type indices.
-bool ClassLinker::LinkMethods(const Handle<mirror::Class>& klass,
- const Handle<mirror::ObjectArray<mirror::Class>>& interfaces) {
+bool ClassLinker::LinkMethods(Handle<mirror::Class> klass,
+ Handle<mirror::ObjectArray<mirror::Class>> interfaces) {
if (klass->IsInterface()) {
// No vtable.
size_t count = klass->NumVirtualMethods();
@@ -3545,7 +3534,7 @@ bool ClassLinker::LinkMethods(const Handle<mirror::Class>& klass,
return true;
}
-bool ClassLinker::LinkVirtualMethods(const Handle<mirror::Class>& klass) {
+bool ClassLinker::LinkVirtualMethods(Handle<mirror::Class> klass) {
Thread* self = Thread::Current();
if (klass->HasSuperClass()) {
uint32_t max_count = (klass->NumVirtualMethods() +
@@ -3632,9 +3621,8 @@ bool ClassLinker::LinkVirtualMethods(const Handle<mirror::Class>& klass) {
return true;
}
-bool ClassLinker::LinkInterfaceMethods(
- const Handle<mirror::Class>& klass,
- const Handle<mirror::ObjectArray<mirror::Class>>& interfaces) {
+bool ClassLinker::LinkInterfaceMethods(Handle<mirror::Class> klass,
+ Handle<mirror::ObjectArray<mirror::Class>> interfaces) {
Thread* const self = Thread::Current();
// Set the imt table to be all conflicts by default.
klass->SetImTable(Runtime::Current()->GetDefaultImt());
@@ -3889,12 +3877,12 @@ bool ClassLinker::LinkInterfaceMethods(
return true;
}
-bool ClassLinker::LinkInstanceFields(const Handle<mirror::Class>& klass) {
+bool ClassLinker::LinkInstanceFields(Handle<mirror::Class> klass) {
CHECK(klass.Get() != NULL);
return LinkFields(klass, false);
}
-bool ClassLinker::LinkStaticFields(const Handle<mirror::Class>& klass) {
+bool ClassLinker::LinkStaticFields(Handle<mirror::Class> klass) {
CHECK(klass.Get() != NULL);
size_t allocated_class_size = klass->GetClassSize();
bool success = LinkFields(klass, true);
@@ -3933,7 +3921,7 @@ struct LinkFieldsComparator {
}
};
-bool ClassLinker::LinkFields(const Handle<mirror::Class>& klass, bool is_static) {
+bool ClassLinker::LinkFields(Handle<mirror::Class> klass, bool is_static) {
size_t num_fields =
is_static ? klass->NumStaticFields() : klass->NumInstanceFields();
@@ -4029,7 +4017,7 @@ bool ClassLinker::LinkFields(const Handle<mirror::Class>& klass, bool is_static)
}
// We lie to the GC about the java.lang.ref.Reference.referent field, so it doesn't scan it.
- if (!is_static && "Ljava/lang/ref/Reference;" == klass->GetDescriptor()) {
+ if (!is_static && klass->DescriptorEquals("Ljava/lang/ref/Reference;")) {
// We know there are no non-reference fields in the Reference classes, and we know
// that 'referent' is alphabetically last, so this is easy...
CHECK_EQ(num_reference_fields, num_fields) << PrettyClass(klass.Get());
@@ -4054,7 +4042,7 @@ bool ClassLinker::LinkFields(const Handle<mirror::Class>& klass, bool is_static)
FieldHelper fh(field);
Primitive::Type type = fh.GetTypeAsPrimitiveType();
bool is_primitive = type != Primitive::kPrimNot;
- if ("Ljava/lang/ref/Reference;" == klass->GetDescriptor() &&
+ if (klass->DescriptorEquals("Ljava/lang/ref/Reference;") &&
strcmp("referent", fh.GetName()) == 0) {
is_primitive = true; // We lied above, so we have to expect a lie here.
}
@@ -4093,7 +4081,7 @@ bool ClassLinker::LinkFields(const Handle<mirror::Class>& klass, bool is_static)
// Set the bitmap of reference offsets, refOffsets, from the ifields
// list.
-void ClassLinker::CreateReferenceInstanceOffsets(const Handle<mirror::Class>& klass) {
+void ClassLinker::CreateReferenceInstanceOffsets(Handle<mirror::Class> klass) {
uint32_t reference_offsets = 0;
mirror::Class* super_class = klass->GetSuperClass();
if (super_class != NULL) {
@@ -4107,11 +4095,11 @@ void ClassLinker::CreateReferenceInstanceOffsets(const Handle<mirror::Class>& kl
CreateReferenceOffsets(klass, false, reference_offsets);
}
-void ClassLinker::CreateReferenceStaticOffsets(const Handle<mirror::Class>& klass) {
+void ClassLinker::CreateReferenceStaticOffsets(Handle<mirror::Class> klass) {
CreateReferenceOffsets(klass, true, 0);
}
-void ClassLinker::CreateReferenceOffsets(const Handle<mirror::Class>& klass, bool is_static,
+void ClassLinker::CreateReferenceOffsets(Handle<mirror::Class> klass, bool is_static,
uint32_t reference_offsets) {
size_t num_reference_fields =
is_static ? klass->NumReferenceStaticFieldsDuringLinking()
@@ -4144,7 +4132,7 @@ void ClassLinker::CreateReferenceOffsets(const Handle<mirror::Class>& klass, boo
}
mirror::String* ClassLinker::ResolveString(const DexFile& dex_file, uint32_t string_idx,
- const Handle<mirror::DexCache>& dex_cache) {
+ Handle<mirror::DexCache> dex_cache) {
DCHECK(dex_cache.Get() != nullptr);
mirror::String* resolved = dex_cache->GetResolvedString(string_idx);
if (resolved != NULL) {
@@ -4166,8 +4154,8 @@ mirror::Class* ClassLinker::ResolveType(const DexFile& dex_file, uint16_t type_i
}
mirror::Class* ClassLinker::ResolveType(const DexFile& dex_file, uint16_t type_idx,
- const Handle<mirror::DexCache>& dex_cache,
- const Handle<mirror::ClassLoader>& class_loader) {
+ Handle<mirror::DexCache> dex_cache,
+ Handle<mirror::ClassLoader> class_loader) {
DCHECK(dex_cache.Get() != NULL);
mirror::Class* resolved = dex_cache->GetResolvedType(type_idx);
if (resolved == NULL) {
@@ -4198,16 +4186,15 @@ mirror::Class* ClassLinker::ResolveType(const DexFile& dex_file, uint16_t type_i
return resolved;
}
-mirror::ArtMethod* ClassLinker::ResolveMethod(const DexFile& dex_file,
- uint32_t method_idx,
- const Handle<mirror::DexCache>& dex_cache,
- const Handle<mirror::ClassLoader>& class_loader,
- mirror::ArtMethod* referrer,
+mirror::ArtMethod* ClassLinker::ResolveMethod(const DexFile& dex_file, uint32_t method_idx,
+ Handle<mirror::DexCache> dex_cache,
+ Handle<mirror::ClassLoader> class_loader,
+ Handle<mirror::ArtMethod> referrer,
InvokeType type) {
DCHECK(dex_cache.Get() != NULL);
// Check for hit in the dex cache.
mirror::ArtMethod* resolved = dex_cache->GetResolvedMethod(method_idx);
- if (resolved != NULL && !resolved->IsRuntimeMethod()) {
+ if (resolved != nullptr && !resolved->IsRuntimeMethod()) {
return resolved;
}
// Fail, get the declaring class.
@@ -4282,7 +4269,7 @@ mirror::ArtMethod* ClassLinker::ResolveMethod(const DexFile& dex_file,
}
// If we found something, check that it can be accessed by the referrer.
- if (resolved != NULL && referrer != NULL) {
+ if (resolved != NULL && referrer.Get() != NULL) {
mirror::Class* methods_class = resolved->GetDeclaringClass();
mirror::Class* referring_class = referrer->GetDeclaringClass();
if (!referring_class->CanAccess(methods_class)) {
@@ -4302,11 +4289,11 @@ mirror::ArtMethod* ClassLinker::ResolveMethod(const DexFile& dex_file,
case kDirect:
case kStatic:
if (resolved != NULL) {
- ThrowIncompatibleClassChangeError(type, kVirtual, resolved, referrer);
+ ThrowIncompatibleClassChangeError(type, kVirtual, resolved, referrer.Get());
} else {
resolved = klass->FindInterfaceMethod(name, signature);
if (resolved != NULL) {
- ThrowIncompatibleClassChangeError(type, kInterface, resolved, referrer);
+ ThrowIncompatibleClassChangeError(type, kInterface, resolved, referrer.Get());
} else {
ThrowNoSuchMethodError(type, klass, name, signature);
}
@@ -4314,11 +4301,11 @@ mirror::ArtMethod* ClassLinker::ResolveMethod(const DexFile& dex_file,
break;
case kInterface:
if (resolved != NULL) {
- ThrowIncompatibleClassChangeError(type, kDirect, resolved, referrer);
+ ThrowIncompatibleClassChangeError(type, kDirect, resolved, referrer.Get());
} else {
resolved = klass->FindVirtualMethod(name, signature);
if (resolved != NULL) {
- ThrowIncompatibleClassChangeError(type, kVirtual, resolved, referrer);
+ ThrowIncompatibleClassChangeError(type, kVirtual, resolved, referrer.Get());
} else {
ThrowNoSuchMethodError(type, klass, name, signature);
}
@@ -4329,11 +4316,11 @@ mirror::ArtMethod* ClassLinker::ResolveMethod(const DexFile& dex_file,
break;
case kVirtual:
if (resolved != NULL) {
- ThrowIncompatibleClassChangeError(type, kDirect, resolved, referrer);
+ ThrowIncompatibleClassChangeError(type, kDirect, resolved, referrer.Get());
} else {
resolved = klass->FindInterfaceMethod(name, signature);
if (resolved != NULL) {
- ThrowIncompatibleClassChangeError(type, kInterface, resolved, referrer);
+ ThrowIncompatibleClassChangeError(type, kInterface, resolved, referrer.Get());
} else {
ThrowNoSuchMethodError(type, klass, name, signature);
}
@@ -4346,8 +4333,8 @@ mirror::ArtMethod* ClassLinker::ResolveMethod(const DexFile& dex_file,
}
mirror::ArtField* ClassLinker::ResolveField(const DexFile& dex_file, uint32_t field_idx,
- const Handle<mirror::DexCache>& dex_cache,
- const Handle<mirror::ClassLoader>& class_loader,
+ Handle<mirror::DexCache> dex_cache,
+ Handle<mirror::ClassLoader> class_loader,
bool is_static) {
DCHECK(dex_cache.Get() != nullptr);
mirror::ArtField* resolved = dex_cache->GetResolvedField(field_idx);
@@ -4389,8 +4376,8 @@ mirror::ArtField* ClassLinker::ResolveField(const DexFile& dex_file, uint32_t fi
mirror::ArtField* ClassLinker::ResolveFieldJLS(const DexFile& dex_file,
uint32_t field_idx,
- const Handle<mirror::DexCache>& dex_cache,
- const Handle<mirror::ClassLoader>& class_loader) {
+ Handle<mirror::DexCache> dex_cache,
+ Handle<mirror::ClassLoader> class_loader) {
DCHECK(dex_cache.Get() != nullptr);
mirror::ArtField* resolved = dex_cache->GetResolvedField(field_idx);
if (resolved != NULL) {
diff --git a/runtime/class_linker.h b/runtime/class_linker.h
index 54805be42e..a8271eda9a 100644
--- a/runtime/class_linker.h
+++ b/runtime/class_linker.h
@@ -75,7 +75,7 @@ class ClassLinker {
// Finds a class by its descriptor, loading it if necessary.
// If class_loader is null, searches boot_class_path_.
mirror::Class* FindClass(Thread* self, const char* descriptor,
- const Handle<mirror::ClassLoader>& class_loader)
+ Handle<mirror::ClassLoader> class_loader)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
// Finds a class by its descriptor using the "system" class loader, ie by searching the
@@ -92,7 +92,7 @@ class ClassLinker {
// Define a new a class based on a ClassDef from a DexFile
mirror::Class* DefineClass(const char* descriptor,
- const Handle<mirror::ClassLoader>& class_loader,
+ Handle<mirror::ClassLoader> class_loader,
const DexFile& dex_file, const DexFile::ClassDef& dex_class_def)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
@@ -136,7 +136,7 @@ class ClassLinker {
// Resolve a String with the given index from the DexFile, storing the
// result in the DexCache.
mirror::String* ResolveString(const DexFile& dex_file, uint32_t string_idx,
- const Handle<mirror::DexCache>& dex_cache)
+ Handle<mirror::DexCache> dex_cache)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
// Resolve a Type with the given index from the DexFile, storing the
@@ -159,8 +159,8 @@ class ClassLinker {
// type, since it may be referenced from but not contained within
// the given DexFile.
mirror::Class* ResolveType(const DexFile& dex_file, uint16_t type_idx,
- const Handle<mirror::DexCache>& dex_cache,
- const Handle<mirror::ClassLoader>& class_loader)
+ Handle<mirror::DexCache> dex_cache,
+ Handle<mirror::ClassLoader> class_loader)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
// Resolve a method with a given ID from the DexFile, storing the
@@ -170,16 +170,21 @@ class ClassLinker {
// virtual method.
mirror::ArtMethod* ResolveMethod(const DexFile& dex_file,
uint32_t method_idx,
- const Handle<mirror::DexCache>& dex_cache,
- const Handle<mirror::ClassLoader>& class_loader,
- mirror::ArtMethod* referrer,
+ Handle<mirror::DexCache> dex_cache,
+ Handle<mirror::ClassLoader> class_loader,
+ Handle<mirror::ArtMethod> referrer,
InvokeType type)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- mirror::ArtMethod* ResolveMethod(uint32_t method_idx, mirror::ArtMethod* referrer,
+ mirror::ArtMethod* GetResolvedMethod(uint32_t method_idx, mirror::ArtMethod* referrer,
+ InvokeType type)
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ mirror::ArtMethod* ResolveMethod(Thread* self, uint32_t method_idx, mirror::ArtMethod** referrer,
InvokeType type)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ mirror::ArtField* GetResolvedField(uint32_t field_idx, mirror::Class* field_declaring_class)
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
mirror::ArtField* ResolveField(uint32_t field_idx, mirror::ArtMethod* referrer,
bool is_static)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
@@ -191,8 +196,8 @@ class ClassLinker {
// field.
mirror::ArtField* ResolveField(const DexFile& dex_file,
uint32_t field_idx,
- const Handle<mirror::DexCache>& dex_cache,
- const Handle<mirror::ClassLoader>& class_loader,
+ Handle<mirror::DexCache> dex_cache,
+ Handle<mirror::ClassLoader> class_loader,
bool is_static)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
@@ -200,10 +205,9 @@ class ClassLinker {
// result in DexCache. The ClassLinker and ClassLoader are used as
// in ResolveType. No is_static argument is provided so that Java
// field resolution semantics are followed.
- mirror::ArtField* ResolveFieldJLS(const DexFile& dex_file,
- uint32_t field_idx,
- const Handle<mirror::DexCache>& dex_cache,
- const Handle<mirror::ClassLoader>& class_loader)
+ mirror::ArtField* ResolveFieldJLS(const DexFile& dex_file, uint32_t field_idx,
+ Handle<mirror::DexCache> dex_cache,
+ Handle<mirror::ClassLoader> class_loader)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
// Get shorty from method index without resolution. Used to do handlerization.
@@ -213,8 +217,7 @@ class ClassLinker {
// Returns true on success, false if there's an exception pending.
// can_run_clinit=false allows the compiler to attempt to init a class,
// given the restriction that no <clinit> execution is possible.
- bool EnsureInitialized(const Handle<mirror::Class>& c,
- bool can_init_fields, bool can_init_parents)
+ bool EnsureInitialized(Handle<mirror::Class> c, bool can_init_fields, bool can_init_parents)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
// Initializes classes that have instances in the image but that have
@@ -224,7 +227,7 @@ class ClassLinker {
void RegisterDexFile(const DexFile& dex_file)
LOCKS_EXCLUDED(dex_lock_)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- void RegisterDexFile(const DexFile& dex_file, const Handle<mirror::DexCache>& dex_cache)
+ void RegisterDexFile(const DexFile& dex_file, Handle<mirror::DexCache> dex_cache)
LOCKS_EXCLUDED(dex_lock_)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
@@ -316,12 +319,12 @@ class ClassLinker {
size_t length)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- void VerifyClass(const Handle<mirror::Class>& klass) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ void VerifyClass(Handle<mirror::Class> klass) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
bool VerifyClassUsingOatFile(const DexFile& dex_file, mirror::Class* klass,
mirror::Class::Status& oat_file_class_status)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
void ResolveClassExceptionHandlerTypes(const DexFile& dex_file,
- const Handle<mirror::Class>& klass)
+ Handle<mirror::Class> klass)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
void ResolveMethodExceptionHandlerTypes(const DexFile& dex_file, mirror::ArtMethod* klass)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
@@ -420,12 +423,12 @@ class ClassLinker {
mirror::Class* CreateArrayClass(Thread* self, const char* descriptor,
- const Handle<mirror::ClassLoader>& class_loader)
+ Handle<mirror::ClassLoader> class_loader)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
void AppendToBootClassPath(const DexFile& dex_file)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- void AppendToBootClassPath(const DexFile& dex_file, const Handle<mirror::DexCache>& dex_cache)
+ void AppendToBootClassPath(const DexFile& dex_file, Handle<mirror::DexCache> dex_cache)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
void ConstructFieldMap(const DexFile& dex_file, const DexFile::ClassDef& dex_class_def,
@@ -437,23 +440,23 @@ class ClassLinker {
void LoadClass(const DexFile& dex_file,
const DexFile::ClassDef& dex_class_def,
- const Handle<mirror::Class>& klass,
+ Handle<mirror::Class> klass,
mirror::ClassLoader* class_loader)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
void LoadClassMembers(const DexFile& dex_file,
const byte* class_data,
- const Handle<mirror::Class>& klass,
+ Handle<mirror::Class> klass,
mirror::ClassLoader* class_loader,
const OatFile::OatClass* oat_class)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
void LoadField(const DexFile& dex_file, const ClassDataItemIterator& it,
- const Handle<mirror::Class>& klass, const Handle<mirror::ArtField>& dst)
+ Handle<mirror::Class> klass, Handle<mirror::ArtField> dst)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
mirror::ArtMethod* LoadMethod(Thread* self, const DexFile& dex_file,
const ClassDataItemIterator& dex_method,
- const Handle<mirror::Class>& klass)
+ Handle<mirror::Class> klass)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
void FixupStaticTrampolines(mirror::Class* klass) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
@@ -462,23 +465,23 @@ class ClassLinker {
OatFile::OatClass GetOatClass(const DexFile& dex_file, uint16_t class_def_idx)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- void RegisterDexFileLocked(const DexFile& dex_file, const Handle<mirror::DexCache>& dex_cache)
+ void RegisterDexFileLocked(const DexFile& dex_file, Handle<mirror::DexCache> dex_cache)
EXCLUSIVE_LOCKS_REQUIRED(dex_lock_)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
bool IsDexFileRegisteredLocked(const DexFile& dex_file) const
SHARED_LOCKS_REQUIRED(dex_lock_, Locks::mutator_lock_);
- bool InitializeClass(const Handle<mirror::Class>& klass, bool can_run_clinit,
+ bool InitializeClass(Handle<mirror::Class> klass, bool can_run_clinit,
bool can_init_parents)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- bool WaitForInitializeClass(const Handle<mirror::Class>& klass, Thread* self,
+ bool WaitForInitializeClass(Handle<mirror::Class> klass, Thread* self,
ObjectLock<mirror::Class>& lock);
- bool ValidateSuperClassDescriptors(const Handle<mirror::Class>& klass)
+ bool ValidateSuperClassDescriptors(Handle<mirror::Class> klass)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
bool IsSameDescriptorInDifferentClassContexts(Thread* self, const char* descriptor,
- Handle<mirror::ClassLoader>& class_loader1,
- Handle<mirror::ClassLoader>& class_loader2)
+ Handle<mirror::ClassLoader> class_loader1,
+ Handle<mirror::ClassLoader> class_loader2)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
bool IsSameMethodSignatureInDifferentClassContexts(Thread* self, mirror::ArtMethod* method,
@@ -486,43 +489,43 @@ class ClassLinker {
mirror::Class* klass2)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- bool LinkClass(Thread* self, const Handle<mirror::Class>& klass,
- const Handle<mirror::ObjectArray<mirror::Class>>& interfaces)
+ bool LinkClass(Thread* self, Handle<mirror::Class> klass,
+ Handle<mirror::ObjectArray<mirror::Class>> interfaces)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- bool LinkSuperClass(const Handle<mirror::Class>& klass)
+ bool LinkSuperClass(Handle<mirror::Class> klass)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- bool LoadSuperAndInterfaces(const Handle<mirror::Class>& klass, const DexFile& dex_file)
+ bool LoadSuperAndInterfaces(Handle<mirror::Class> klass, const DexFile& dex_file)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- bool LinkMethods(const Handle<mirror::Class>& klass,
- const Handle<mirror::ObjectArray<mirror::Class>>& interfaces)
+ bool LinkMethods(Handle<mirror::Class> klass,
+ Handle<mirror::ObjectArray<mirror::Class>> interfaces)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- bool LinkVirtualMethods(const Handle<mirror::Class>& klass)
+ bool LinkVirtualMethods(Handle<mirror::Class> klass)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- bool LinkInterfaceMethods(const Handle<mirror::Class>& klass,
- const Handle<mirror::ObjectArray<mirror::Class>>& interfaces)
+ bool LinkInterfaceMethods(Handle<mirror::Class> klass,
+ Handle<mirror::ObjectArray<mirror::Class>> interfaces)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- bool LinkStaticFields(const Handle<mirror::Class>& klass)
+ bool LinkStaticFields(Handle<mirror::Class> klass)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- bool LinkInstanceFields(const Handle<mirror::Class>& klass)
+ bool LinkInstanceFields(Handle<mirror::Class> klass)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- bool LinkFields(const Handle<mirror::Class>& klass, bool is_static)
+ bool LinkFields(Handle<mirror::Class> klass, bool is_static)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- void LinkCode(const Handle<mirror::ArtMethod>& method, const OatFile::OatClass* oat_class,
+ void LinkCode(Handle<mirror::ArtMethod> method, const OatFile::OatClass* oat_class,
const DexFile& dex_file, uint32_t dex_method_index, uint32_t method_index)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- void CreateReferenceInstanceOffsets(const Handle<mirror::Class>& klass)
+ void CreateReferenceInstanceOffsets(Handle<mirror::Class> klass)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- void CreateReferenceStaticOffsets(const Handle<mirror::Class>& klass)
+ void CreateReferenceStaticOffsets(Handle<mirror::Class> klass)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- void CreateReferenceOffsets(const Handle<mirror::Class>& klass, bool is_static,
+ void CreateReferenceOffsets(Handle<mirror::Class> klass, bool is_static,
uint32_t reference_offsets)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
@@ -551,11 +554,11 @@ class ClassLinker {
bool* open_failed)
LOCKS_EXCLUDED(dex_lock_);
- mirror::ArtMethod* CreateProxyConstructor(Thread* self, const Handle<mirror::Class>& klass,
+ mirror::ArtMethod* CreateProxyConstructor(Thread* self, Handle<mirror::Class> klass,
mirror::Class* proxy_class)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- mirror::ArtMethod* CreateProxyMethod(Thread* self, const Handle<mirror::Class>& klass,
- const Handle<mirror::ArtMethod>& prototype)
+ mirror::ArtMethod* CreateProxyMethod(Thread* self, Handle<mirror::Class> klass,
+ Handle<mirror::ArtMethod> prototype)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
std::vector<const DexFile*> boot_class_path_;
diff --git a/runtime/class_linker_test.cc b/runtime/class_linker_test.cc
index d04f02ba3a..c11aeccee4 100644
--- a/runtime/class_linker_test.cc
+++ b/runtime/class_linker_test.cc
@@ -108,7 +108,7 @@ class ClassLinkerTest : public CommonRuntimeTest {
AssertArrayClass(array_descriptor, array);
}
- void AssertArrayClass(const std::string& array_descriptor, const Handle<mirror::Class>& array)
+ void AssertArrayClass(const std::string& array_descriptor, Handle<mirror::Class> array)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
ASSERT_TRUE(array.Get() != NULL);
ASSERT_TRUE(array->GetClass() != NULL);
@@ -178,7 +178,7 @@ class ClassLinkerTest : public CommonRuntimeTest {
EXPECT_TRUE(fh.GetType() != NULL);
}
- void AssertClass(const std::string& descriptor, const Handle<mirror::Class>& klass)
+ void AssertClass(const std::string& descriptor, Handle<mirror::Class> klass)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
EXPECT_STREQ(descriptor.c_str(), klass->GetDescriptor().c_str());
if (descriptor == "Ljava/lang/Object;") {
@@ -846,8 +846,7 @@ TEST_F(ClassLinkerTest, ValidateBoxedTypes) {
// Validate that the "value" field is always the 0th field in each of java.lang's box classes.
// This lets UnboxPrimitive avoid searching for the field by name at runtime.
ScopedObjectAccess soa(Thread::Current());
- StackHandleScope<1> hs(soa.Self());
- auto class_loader(hs.NewHandle<mirror::ClassLoader>(nullptr));
+ NullHandle<mirror::ClassLoader> class_loader;
mirror::Class* c;
c = class_linker_->FindClass(soa.Self(), "Ljava/lang/Boolean;", class_loader);
FieldHelper fh(c->GetIFields()->Get(0));
diff --git a/runtime/entrypoints/entrypoint_utils.h b/runtime/entrypoints/entrypoint_utils.h
index f1795a5a63..58b4286c30 100644
--- a/runtime/entrypoints/entrypoint_utils.h
+++ b/runtime/entrypoints/entrypoint_utils.h
@@ -385,31 +385,36 @@ EXPLICIT_FIND_FIELD_FROM_CODE_TYPED_TEMPLATE_DECL(StaticPrimitiveWrite);
template<InvokeType type, bool access_check>
static inline mirror::ArtMethod* FindMethodFromCode(uint32_t method_idx,
- mirror::Object* this_object,
- mirror::ArtMethod* referrer, Thread* self) {
- ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
- StackHandleScope<1> hs(self);
- Handle<mirror::Object> handle_scope_this(hs.NewHandle(type == kStatic ? nullptr : this_object));
- mirror::ArtMethod* resolved_method = class_linker->ResolveMethod(method_idx, referrer, type);
+ mirror::Object** this_object,
+ mirror::ArtMethod** referrer, Thread* self) {
+ ClassLinker* const class_linker = Runtime::Current()->GetClassLinker();
+ mirror::ArtMethod* resolved_method = class_linker->GetResolvedMethod(method_idx, *referrer, type);
+ if (resolved_method == nullptr) {
+ StackHandleScope<1> hs(self);
+ mirror::Object* null_this = nullptr;
+ HandleWrapper<mirror::Object> h_this(
+ hs.NewHandleWrapper(type == kStatic ? &null_this : this_object));
+ resolved_method = class_linker->ResolveMethod(self, method_idx, referrer, type);
+ }
if (UNLIKELY(resolved_method == nullptr)) {
DCHECK(self->IsExceptionPending()); // Throw exception and unwind.
return nullptr; // Failure.
- } else if (UNLIKELY(handle_scope_this.Get() == nullptr && type != kStatic)) {
+ } else if (UNLIKELY(*this_object == nullptr && type != kStatic)) {
// Maintain interpreter-like semantics where NullPointerException is thrown
// after potential NoSuchMethodError from class linker.
ThrowLocation throw_location = self->GetCurrentLocationForThrow();
- DCHECK(referrer == throw_location.GetMethod());
+ DCHECK_EQ(*referrer, throw_location.GetMethod());
ThrowNullPointerExceptionForMethodAccess(throw_location, method_idx, type);
return nullptr; // Failure.
} else if (access_check) {
// Incompatible class change should have been handled in resolve method.
if (UNLIKELY(resolved_method->CheckIncompatibleClassChange(type))) {
ThrowIncompatibleClassChangeError(type, resolved_method->GetInvokeType(), resolved_method,
- referrer);
+ *referrer);
return nullptr; // Failure.
}
mirror::Class* methods_class = resolved_method->GetDeclaringClass();
- mirror::Class* referring_class = referrer->GetDeclaringClass();
+ mirror::Class* referring_class = (*referrer)->GetDeclaringClass();
bool can_access_resolved_method =
referring_class->CheckResolvedMethodAccess<type>(methods_class, resolved_method,
method_idx);
@@ -423,7 +428,7 @@ static inline mirror::ArtMethod* FindMethodFromCode(uint32_t method_idx,
case kDirect:
return resolved_method;
case kVirtual: {
- mirror::ObjectArray<mirror::ArtMethod>* vtable = handle_scope_this->GetClass()->GetVTable();
+ mirror::ObjectArray<mirror::ArtMethod>* vtable = (*this_object)->GetClass()->GetVTable();
uint16_t vtable_index = resolved_method->GetMethodIndex();
if (access_check &&
(vtable == nullptr || vtable_index >= static_cast<uint32_t>(vtable->GetLength()))) {
@@ -437,7 +442,7 @@ static inline mirror::ArtMethod* FindMethodFromCode(uint32_t method_idx,
return vtable->GetWithoutChecks(vtable_index);
}
case kSuper: {
- mirror::Class* super_class = referrer->GetDeclaringClass()->GetSuperClass();
+ mirror::Class* super_class = (*referrer)->GetDeclaringClass()->GetSuperClass();
uint16_t vtable_index = resolved_method->GetMethodIndex();
mirror::ObjectArray<mirror::ArtMethod>* vtable;
if (access_check) {
@@ -460,20 +465,19 @@ static inline mirror::ArtMethod* FindMethodFromCode(uint32_t method_idx,
}
case kInterface: {
uint32_t imt_index = resolved_method->GetDexMethodIndex() % ClassLinker::kImtSize;
- mirror::ObjectArray<mirror::ArtMethod>* imt_table = handle_scope_this->GetClass()->GetImTable();
+ mirror::ObjectArray<mirror::ArtMethod>* imt_table = (*this_object)->GetClass()->GetImTable();
mirror::ArtMethod* imt_method = imt_table->Get(imt_index);
if (!imt_method->IsImtConflictMethod()) {
return imt_method;
} else {
mirror::ArtMethod* interface_method =
- handle_scope_this->GetClass()->FindVirtualMethodForInterface(resolved_method);
+ (*this_object)->GetClass()->FindVirtualMethodForInterface(resolved_method);
if (UNLIKELY(interface_method == nullptr)) {
ThrowIncompatibleClassChangeErrorClassForInterfaceDispatch(resolved_method,
- handle_scope_this.Get(), referrer);
+ *this_object, *referrer);
return nullptr; // Failure.
- } else {
- return interface_method;
}
+ return interface_method;
}
}
default:
@@ -486,8 +490,8 @@ static inline mirror::ArtMethod* FindMethodFromCode(uint32_t method_idx,
#define EXPLICIT_FIND_METHOD_FROM_CODE_TEMPLATE_DECL(_type, _access_check) \
template SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) ALWAYS_INLINE \
mirror::ArtMethod* FindMethodFromCode<_type, _access_check>(uint32_t method_idx, \
- mirror::Object* this_object, \
- mirror::ArtMethod* referrer, \
+ mirror::Object** this_object, \
+ mirror::ArtMethod** referrer, \
Thread* self)
#define EXPLICIT_FIND_METHOD_FROM_CODE_TYPED_TEMPLATE_DECL(_type) \
EXPLICIT_FIND_METHOD_FROM_CODE_TEMPLATE_DECL(_type, false); \
diff --git a/runtime/entrypoints/interpreter/interpreter_entrypoints.cc b/runtime/entrypoints/interpreter/interpreter_entrypoints.cc
index 3f02ec7f73..f2e2bf7aa9 100644
--- a/runtime/entrypoints/interpreter/interpreter_entrypoints.cc
+++ b/runtime/entrypoints/interpreter/interpreter_entrypoints.cc
@@ -25,6 +25,7 @@
namespace art {
+// TODO: Make the MethodHelper here be compaction safe.
extern "C" void artInterpreterToCompiledCodeBridge(Thread* self, MethodHelper& mh,
const DexFile::CodeItem* code_item,
ShadowFrame* shadow_frame, JValue* result) {
@@ -43,6 +44,8 @@ extern "C" void artInterpreterToCompiledCodeBridge(Thread* self, MethodHelper& m
}
self->PopShadowFrame();
CHECK(h_class->IsInitializing());
+ // Reload from shadow frame in case the method moved, this is faster than adding a handle.
+ method = shadow_frame->GetMethod();
}
}
uint16_t arg_offset = (code_item == NULL) ? 0 : code_item->registers_size_ - code_item->ins_size_;
diff --git a/runtime/entrypoints/portable/portable_invoke_entrypoints.cc b/runtime/entrypoints/portable/portable_invoke_entrypoints.cc
index d34b09737f..3a898e8ed5 100644
--- a/runtime/entrypoints/portable/portable_invoke_entrypoints.cc
+++ b/runtime/entrypoints/portable/portable_invoke_entrypoints.cc
@@ -23,17 +23,20 @@ namespace art {
template<InvokeType type, bool access_check>
mirror::ArtMethod* FindMethodHelper(uint32_t method_idx, mirror::Object* this_object,
- mirror::ArtMethod* caller_method, Thread* thread) {
+ mirror::ArtMethod* caller_method, Thread* self) {
mirror::ArtMethod* method = FindMethodFast(method_idx, this_object, caller_method,
access_check, type);
if (UNLIKELY(method == NULL)) {
- method = FindMethodFromCode<type, access_check>(method_idx, this_object, caller_method, thread);
+ // Note: This can cause thread suspension.
+ self->AssertThreadSuspensionIsAllowable();
+ method = FindMethodFromCode<type, access_check>(method_idx, &this_object, &caller_method,
+ self);
if (UNLIKELY(method == NULL)) {
- CHECK(thread->IsExceptionPending());
+ CHECK(self->IsExceptionPending());
return 0; // failure
}
}
- DCHECK(!thread->IsExceptionPending());
+ DCHECK(!self->IsExceptionPending());
const void* code = method->GetEntryPointFromPortableCompiledCode();
// When we return, the caller will branch to this address, so it had better not be 0!
diff --git a/runtime/entrypoints/portable/portable_trampoline_entrypoints.cc b/runtime/entrypoints/portable/portable_trampoline_entrypoints.cc
index 17c3222ff1..3756f47311 100644
--- a/runtime/entrypoints/portable/portable_trampoline_entrypoints.cc
+++ b/runtime/entrypoints/portable/portable_trampoline_entrypoints.cc
@@ -317,11 +317,11 @@ extern "C" uint64_t artPortableProxyInvokeHandler(mirror::ArtMethod* proxy_metho
// Lazily resolve a method for portable. Called by stub code.
extern "C" const void* artPortableResolutionTrampoline(mirror::ArtMethod* called,
mirror::Object* receiver,
- Thread* thread,
+ Thread* self,
mirror::ArtMethod** called_addr)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
uint32_t dex_pc;
- mirror::ArtMethod* caller = thread->GetCurrentMethod(&dex_pc);
+ mirror::ArtMethod* caller = self->GetCurrentMethod(&dex_pc);
ClassLinker* linker = Runtime::Current()->GetClassLinker();
InvokeType invoke_type;
@@ -379,7 +379,7 @@ extern "C" const void* artPortableResolutionTrampoline(mirror::ArtMethod* called
is_range = true;
}
uint32_t dex_method_idx = (is_range) ? instr->VRegB_3rc() : instr->VRegB_35c();
- called = linker->ResolveMethod(dex_method_idx, caller, invoke_type);
+ called = linker->ResolveMethod(Thread::Current(), dex_method_idx, &caller, invoke_type);
// Incompatible class change should have been handled in resolve method.
CHECK(!called->CheckIncompatibleClassChange(invoke_type));
// Refine called method based on receiver.
@@ -395,9 +395,9 @@ extern "C" const void* artPortableResolutionTrampoline(mirror::ArtMethod* called
CHECK(!called->CheckIncompatibleClassChange(invoke_type));
}
const void* code = nullptr;
- if (LIKELY(!thread->IsExceptionPending())) {
+ if (LIKELY(!self->IsExceptionPending())) {
// Ensure that the called method's class is initialized.
- StackHandleScope<1> hs(Thread::Current());
+ StackHandleScope<1> hs(self);
Handle<mirror::Class> called_class(hs.NewHandle(called->GetDeclaringClass()));
linker->EnsureInitialized(called_class, true, true);
if (LIKELY(called_class->IsInitialized())) {
diff --git a/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc b/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc
index ee276c1670..2c920decb9 100644
--- a/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc
+++ b/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc
@@ -755,11 +755,12 @@ extern "C" const void* artQuickResolutionTrampoline(mirror::ArtMethod* called,
self->EndAssertNoThreadSuspension(old_cause);
bool virtual_or_interface = invoke_type == kVirtual || invoke_type == kInterface;
// Resolve method filling in dex cache.
- if (called->IsRuntimeMethod()) {
+ if (UNLIKELY(called->IsRuntimeMethod())) {
StackHandleScope<1> hs(self);
- Handle<mirror::Object> handle_scope_receiver(hs.NewHandle(virtual_or_interface ? receiver : nullptr));
- called = linker->ResolveMethod(dex_method_idx, caller, invoke_type);
- receiver = handle_scope_receiver.Get();
+ mirror::Object* dummy = nullptr;
+ HandleWrapper<mirror::Object> h_receiver(
+ hs.NewHandleWrapper(virtual_or_interface ? &receiver : &dummy));
+ called = linker->ResolveMethod(self, dex_method_idx, &caller, invoke_type);
}
const void* code = NULL;
if (LIKELY(!self->IsExceptionPending())) {
@@ -1681,7 +1682,8 @@ static MethodAndCode artInvokeCommon(uint32_t method_idx, mirror::Object* this_o
ScopedObjectAccessUnchecked soa(self->GetJniEnv());
RememberForGcArgumentVisitor visitor(sp, type == kStatic, shorty, shorty_len, &soa);
visitor.VisitArguments();
- method = FindMethodFromCode<type, access_check>(method_idx, this_object, caller_method, self);
+ method = FindMethodFromCode<type, access_check>(method_idx, &this_object, &caller_method,
+ self);
visitor.FixupReferences();
}
@@ -1871,7 +1873,7 @@ extern "C" MethodAndCode artInvokeInterfaceTrampoline(mirror::ArtMethod* interfa
ScopedObjectAccessUnchecked soa(self->GetJniEnv());
RememberForGcArgumentVisitor visitor(sp, false, shorty, shorty_len, &soa);
visitor.VisitArguments();
- method = FindMethodFromCode<kInterface, false>(dex_method_idx, this_object, caller_method,
+ method = FindMethodFromCode<kInterface, false>(dex_method_idx, &this_object, &caller_method,
self);
visitor.FixupReferences();
}
diff --git a/runtime/handle.h b/runtime/handle.h
index 3127864e19..c4e92851e2 100644
--- a/runtime/handle.h
+++ b/runtime/handle.h
@@ -53,29 +53,43 @@ class Handle {
reference_->Assign(reference);
return old;
}
- jobject ToJObject() const ALWAYS_INLINE {
+ jobject ToJObject() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) ALWAYS_INLINE {
+ if (UNLIKELY(reference_->AsMirrorPtr() == nullptr)) {
+ // Special case so that we work with NullHandles.
+ return nullptr;
+ }
return reinterpret_cast<jobject>(reference_);
}
- private:
+ protected:
StackReference<T>* reference_;
template<typename S>
explicit Handle(StackReference<S>* reference)
: reference_(reinterpret_cast<StackReference<T>*>(reference)) {
}
-
template<typename S>
explicit Handle(const Handle<S>& handle)
: reference_(reinterpret_cast<StackReference<T>*>(handle.reference_)) {
}
+ private:
template<class S> friend class Handle;
friend class HandleScope;
template<class S> friend class HandleWrapper;
template<size_t kNumReferences> friend class StackHandleScope;
};
+template<class T>
+class NullHandle : public Handle<T> {
+ public:
+ NullHandle() : Handle<T>(&null_ref_) {
+ }
+
+ private:
+ StackReference<T> null_ref_;
+};
+
} // namespace art
#endif // ART_RUNTIME_HANDLE_H_
diff --git a/runtime/interpreter/interpreter.cc b/runtime/interpreter/interpreter.cc
index 478c74cd25..f77a0f6d35 100644
--- a/runtime/interpreter/interpreter.cc
+++ b/runtime/interpreter/interpreter.cc
@@ -524,16 +524,17 @@ extern "C" void artInterpreterToInterpreterBridge(Thread* self, MethodHelper& mh
ArtMethod* method = shadow_frame->GetMethod();
// Ensure static methods are initialized.
if (method->IsStatic()) {
- StackHandleScope<1> hs(self);
- Handle<Class> declaringClass(hs.NewHandle(method->GetDeclaringClass()));
- if (UNLIKELY(!declaringClass->IsInitializing())) {
- if (UNLIKELY(!Runtime::Current()->GetClassLinker()->EnsureInitialized(declaringClass, true,
- true))) {
- DCHECK(Thread::Current()->IsExceptionPending());
+ mirror::Class* declaring_class = method->GetDeclaringClass();
+ if (UNLIKELY(!declaring_class->IsInitializing())) {
+ StackHandleScope<1> hs(self);
+ HandleWrapper<Class> h_declaring_class(hs.NewHandleWrapper(&declaring_class));
+ if (UNLIKELY(!Runtime::Current()->GetClassLinker()->EnsureInitialized(
+ h_declaring_class, true, true))) {
+ DCHECK(self->IsExceptionPending());
self->PopShadowFrame();
return;
}
- CHECK(declaringClass->IsInitializing());
+ CHECK(h_declaring_class->IsInitializing());
}
}
diff --git a/runtime/interpreter/interpreter_common.cc b/runtime/interpreter/interpreter_common.cc
index 418aff51dc..63ae6fdf18 100644
--- a/runtime/interpreter/interpreter_common.cc
+++ b/runtime/interpreter/interpreter_common.cc
@@ -296,11 +296,9 @@ static void UnstartedRuntimeInvoke(Thread* self, MethodHelper& mh,
// other variants that take more arguments should also be added.
std::string descriptor(DotToDescriptor(shadow_frame->GetVRegReference(arg_offset)->AsString()->ToModifiedUtf8().c_str()));
- StackHandleScope<1> hs(self);
// shadow_frame.GetMethod()->GetDeclaringClass()->GetClassLoader();
- auto class_loader = hs.NewHandle<ClassLoader>(nullptr);
- Class* found = Runtime::Current()->GetClassLinker()->FindClass(self, descriptor.c_str(),
- class_loader);
+ Class* found = Runtime::Current()->GetClassLinker()->FindClass(
+ self, descriptor.c_str(), NullHandle<mirror::ClassLoader>());
CHECK(found != NULL) << "Class.forName failed in un-started runtime for class: "
<< PrettyDescriptor(descriptor);
result->SetL(found);
diff --git a/runtime/interpreter/interpreter_common.h b/runtime/interpreter/interpreter_common.h
index b42af11986..cfc90a6618 100644
--- a/runtime/interpreter/interpreter_common.h
+++ b/runtime/interpreter/interpreter_common.h
@@ -29,6 +29,7 @@
#include "dex_instruction.h"
#include "entrypoints/entrypoint_utils.h"
#include "gc/accounting/card_table-inl.h"
+#include "handle_scope-inl.h"
#include "nth_caller_visitor.h"
#include "mirror/art_field-inl.h"
#include "mirror/art_method.h"
@@ -112,9 +113,10 @@ static inline bool DoInvoke(Thread* self, ShadowFrame& shadow_frame, const Instr
const uint32_t method_idx = (is_range) ? inst->VRegB_3rc() : inst->VRegB_35c();
const uint32_t vregC = (is_range) ? inst->VRegC_3rc() : inst->VRegC_35c();
Object* receiver = (type == kStatic) ? nullptr : shadow_frame.GetVRegReference(vregC);
- ArtMethod* const method = FindMethodFromCode<type, do_access_check>(method_idx, receiver,
- shadow_frame.GetMethod(),
- self);
+ mirror::ArtMethod* sf_method = shadow_frame.GetMethod();
+ ArtMethod* const method = FindMethodFromCode<type, do_access_check>(
+ method_idx, &receiver, &sf_method, self);
+ // The shadow frame should already be pushed, so we don't need to update it.
if (UNLIKELY(method == nullptr)) {
CHECK(self->IsExceptionPending());
result->SetJ(0);
@@ -348,6 +350,10 @@ static SOMETIMES_INLINE_KEYWORD bool DoFieldPut(Thread* self, const ShadowFrame&
case Primitive::kPrimNot: {
Object* reg = shadow_frame.GetVRegReference(vregA);
if (do_assignability_check && reg != nullptr) {
+ // FieldHelper::GetType can resolve classes, use a handle wrapper which will restore the
+ // object in the destructor.
+ StackHandleScope<1> hs(self);
+ HandleWrapper<mirror::Object> wrapper(hs.NewHandleWrapper(&obj));
Class* field_class = FieldHelper(f).GetType();
if (!reg->VerifierInstanceOf(field_class)) {
// This should never happen.
@@ -372,7 +378,8 @@ static SOMETIMES_INLINE_KEYWORD bool DoFieldPut(Thread* self, const ShadowFrame&
// Handles iput-quick, iput-wide-quick and iput-object-quick instructions.
// Returns true on success, otherwise throws an exception and returns false.
template<Primitive::Type field_type, bool transaction_active>
-static SOMETIMES_INLINE_KEYWORD bool DoIPutQuick(const ShadowFrame& shadow_frame, const Instruction* inst, uint16_t inst_data) {
+static SOMETIMES_INLINE_KEYWORD bool DoIPutQuick(const ShadowFrame& shadow_frame,
+ const Instruction* inst, uint16_t inst_data) {
Object* obj = shadow_frame.GetVRegReference(inst->VRegB_22c(inst_data));
if (UNLIKELY(obj == nullptr)) {
// We lost the reference to the field index so we cannot get a more
diff --git a/runtime/jni_internal.cc b/runtime/jni_internal.cc
index 6f3317da6b..b51e1d586c 100644
--- a/runtime/jni_internal.cc
+++ b/runtime/jni_internal.cc
@@ -3138,7 +3138,7 @@ void JavaVMExt::DumpReferenceTables(std::ostream& os) {
}
bool JavaVMExt::LoadNativeLibrary(const std::string& path,
- const Handle<mirror::ClassLoader>& class_loader,
+ Handle<mirror::ClassLoader> class_loader,
std::string* detail) {
detail->clear();
diff --git a/runtime/jni_internal.h b/runtime/jni_internal.h
index 37195eb34a..7e76e11c71 100644
--- a/runtime/jni_internal.h
+++ b/runtime/jni_internal.h
@@ -67,7 +67,7 @@ class JavaVMExt : public JavaVM {
* Returns 'true' on success. On failure, sets 'detail' to a
* human-readable description of the error.
*/
- bool LoadNativeLibrary(const std::string& path, const Handle<mirror::ClassLoader>& class_loader,
+ bool LoadNativeLibrary(const std::string& path, Handle<mirror::ClassLoader> class_loader,
std::string* detail)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
diff --git a/runtime/mirror/array.cc b/runtime/mirror/array.cc
index 552652cd24..107664381a 100644
--- a/runtime/mirror/array.cc
+++ b/runtime/mirror/array.cc
@@ -42,8 +42,8 @@ namespace mirror {
// Recursively create an array with multiple dimensions. Elements may be
// Objects or primitive types.
static Array* RecursiveCreateMultiArray(Thread* self,
- const Handle<Class>& array_class, int current_dimension,
- const Handle<mirror::IntArray>& dimensions)
+ Handle<Class> array_class, int current_dimension,
+ Handle<mirror::IntArray> dimensions)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
int32_t array_length = dimensions->Get(current_dimension);
StackHandleScope<1> hs(self);
@@ -73,8 +73,8 @@ static Array* RecursiveCreateMultiArray(Thread* self,
return new_array.Get();
}
-Array* Array::CreateMultiArray(Thread* self, const Handle<Class>& element_class,
- const Handle<IntArray>& dimensions) {
+Array* Array::CreateMultiArray(Thread* self, Handle<Class> element_class,
+ Handle<IntArray> dimensions) {
// Verify dimensions.
//
// The caller is responsible for verifying that "dimArray" is non-null
diff --git a/runtime/mirror/array.h b/runtime/mirror/array.h
index 1b8106e05f..64e2317cfb 100644
--- a/runtime/mirror/array.h
+++ b/runtime/mirror/array.h
@@ -38,8 +38,8 @@ class MANAGED Array : public Object {
bool fill_usable = false)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- static Array* CreateMultiArray(Thread* self, const Handle<Class>& element_class,
- const Handle<IntArray>& dimensions)
+ static Array* CreateMultiArray(Thread* self, Handle<Class> element_class,
+ Handle<IntArray> dimensions)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags,
diff --git a/runtime/mirror/art_method.cc b/runtime/mirror/art_method.cc
index af544fdf72..e2d3f41603 100644
--- a/runtime/mirror/art_method.cc
+++ b/runtime/mirror/art_method.cc
@@ -229,7 +229,7 @@ uintptr_t ArtMethod::ToNativePc(const uint32_t dex_pc) {
return 0;
}
-uint32_t ArtMethod::FindCatchBlock(Handle<Class>& exception_type, uint32_t dex_pc,
+uint32_t ArtMethod::FindCatchBlock(Handle<Class> exception_type, uint32_t dex_pc,
bool* has_no_move_exception, bool* exc_changed) {
MethodHelper mh(this);
const DexFile::CodeItem* code_item = mh.GetCodeItem();
diff --git a/runtime/mirror/art_method.h b/runtime/mirror/art_method.h
index 34fe0bf530..2e8253fad7 100644
--- a/runtime/mirror/art_method.h
+++ b/runtime/mirror/art_method.h
@@ -401,7 +401,7 @@ class MANAGED ArtMethod : public Object {
// In the process of finding a catch block we might trigger resolution errors. This is flagged
// by exc_changed, which indicates that a different exception is now stored in the thread and
// should be reloaded.
- uint32_t FindCatchBlock(Handle<Class>& exception_type, uint32_t dex_pc,
+ uint32_t FindCatchBlock(Handle<Class> exception_type, uint32_t dex_pc,
bool* has_no_move_exception, bool* exc_changed)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
diff --git a/runtime/mirror/stack_trace_element.cc b/runtime/mirror/stack_trace_element.cc
index d8591cca7a..b1de2b6f7d 100644
--- a/runtime/mirror/stack_trace_element.cc
+++ b/runtime/mirror/stack_trace_element.cc
@@ -39,10 +39,8 @@ void StackTraceElement::ResetClass() {
java_lang_StackTraceElement_ = NULL;
}
-StackTraceElement* StackTraceElement::Alloc(Thread* self,
- Handle<String>& declaring_class,
- Handle<String>& method_name,
- Handle<String>& file_name,
+StackTraceElement* StackTraceElement::Alloc(Thread* self, Handle<String> declaring_class,
+ Handle<String> method_name, Handle<String> file_name,
int32_t line_number) {
StackTraceElement* trace =
down_cast<StackTraceElement*>(GetStackTraceElement()->AllocObject(self));
@@ -57,8 +55,8 @@ StackTraceElement* StackTraceElement::Alloc(Thread* self,
}
template<bool kTransactionActive>
-void StackTraceElement::Init(Handle<String>& declaring_class, Handle<String>& method_name,
- Handle<String>& file_name, int32_t line_number) {
+void StackTraceElement::Init(Handle<String> declaring_class, Handle<String> method_name,
+ Handle<String> file_name, int32_t line_number) {
SetFieldObject<kTransactionActive>(OFFSET_OF_OBJECT_MEMBER(StackTraceElement, declaring_class_),
declaring_class.Get());
SetFieldObject<kTransactionActive>(OFFSET_OF_OBJECT_MEMBER(StackTraceElement, method_name_),
diff --git a/runtime/mirror/stack_trace_element.h b/runtime/mirror/stack_trace_element.h
index 22d9b71410..e094e8bc85 100644
--- a/runtime/mirror/stack_trace_element.h
+++ b/runtime/mirror/stack_trace_element.h
@@ -46,10 +46,8 @@ class MANAGED StackTraceElement : public Object {
return GetField32(OFFSET_OF_OBJECT_MEMBER(StackTraceElement, line_number_));
}
- static StackTraceElement* Alloc(Thread* self,
- Handle<String>& declaring_class,
- Handle<String>& method_name,
- Handle<String>& file_name,
+ static StackTraceElement* Alloc(Thread* self, Handle<String> declaring_class,
+ Handle<String> method_name, Handle<String> file_name,
int32_t line_number)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
@@ -70,8 +68,8 @@ class MANAGED StackTraceElement : public Object {
int32_t line_number_;
template<bool kTransactionActive>
- void Init(Handle<String>& declaring_class, Handle<String>& method_name,
- Handle<String>& file_name, int32_t line_number)
+ void Init(Handle<String> declaring_class, Handle<String> method_name, Handle<String> file_name,
+ int32_t line_number)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
static Class* java_lang_StackTraceElement_;
diff --git a/runtime/mirror/string.cc b/runtime/mirror/string.cc
index ee719b477b..1d79106a44 100644
--- a/runtime/mirror/string.cc
+++ b/runtime/mirror/string.cc
@@ -131,7 +131,7 @@ String* String::Alloc(Thread* self, int32_t utf16_length) {
return Alloc(self, array);
}
-String* String::Alloc(Thread* self, const Handle<CharArray>& array) {
+String* String::Alloc(Thread* self, Handle<CharArray> array) {
// Hold reference in case AllocObject causes GC.
String* string = down_cast<String*>(GetJavaLangString()->AllocObject(self));
if (LIKELY(string != nullptr)) {
diff --git a/runtime/mirror/string.h b/runtime/mirror/string.h
index 169b671574..6c3015f4d0 100644
--- a/runtime/mirror/string.h
+++ b/runtime/mirror/string.h
@@ -137,7 +137,7 @@ class MANAGED String : public Object {
static String* Alloc(Thread* self, int32_t utf16_length)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- static String* Alloc(Thread* self, const Handle<CharArray>& array)
+ static String* Alloc(Thread* self, Handle<CharArray> array)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
void SetArray(CharArray* new_array) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
diff --git a/runtime/monitor.cc b/runtime/monitor.cc
index f783edbfc3..fe1ef6cba0 100644
--- a/runtime/monitor.cc
+++ b/runtime/monitor.cc
@@ -637,7 +637,7 @@ void Monitor::Inflate(Thread* self, Thread* owner, mirror::Object* obj, int32_t
}
}
-void Monitor::InflateThinLocked(Thread* self, Handle<mirror::Object>& obj, LockWord lock_word,
+void Monitor::InflateThinLocked(Thread* self, Handle<mirror::Object> obj, LockWord lock_word,
uint32_t hash_code) {
DCHECK_EQ(lock_word.GetState(), LockWord::kThinLocked);
uint32_t owner_thread_id = lock_word.ThinLockOwner();
diff --git a/runtime/monitor.h b/runtime/monitor.h
index bc1b2ed4eb..007f54d9b1 100644
--- a/runtime/monitor.h
+++ b/runtime/monitor.h
@@ -114,7 +114,7 @@ class Monitor {
return monitor_id_;
}
- static void InflateThinLocked(Thread* self, Handle<mirror::Object>& obj, LockWord lock_word,
+ static void InflateThinLocked(Thread* self, Handle<mirror::Object> obj, LockWord lock_word,
uint32_t hash_code) NO_THREAD_SAFETY_ANALYSIS;
static bool Deflate(Thread* self, mirror::Object* obj)
diff --git a/runtime/native/dalvik_system_VMRuntime.cc b/runtime/native/dalvik_system_VMRuntime.cc
index d9c9b5937d..d55b5450c3 100644
--- a/runtime/native/dalvik_system_VMRuntime.cc
+++ b/runtime/native/dalvik_system_VMRuntime.cc
@@ -221,7 +221,7 @@ static void PreloadDexCachesStringsCallback(mirror::Object** root, void* arg,
}
// Based on ClassLinker::ResolveString.
-static void PreloadDexCachesResolveString(Handle<mirror::DexCache>& dex_cache, uint32_t string_idx,
+static void PreloadDexCachesResolveString(Handle<mirror::DexCache> dex_cache, uint32_t string_idx,
StringTable& strings)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
mirror::String* string = dex_cache->GetResolvedString(string_idx);
@@ -267,8 +267,7 @@ static void PreloadDexCachesResolveType(mirror::DexCache* dex_cache, uint32_t ty
}
// Based on ClassLinker::ResolveField.
-static void PreloadDexCachesResolveField(Handle<mirror::DexCache>& dex_cache,
- uint32_t field_idx,
+static void PreloadDexCachesResolveField(Handle<mirror::DexCache> dex_cache, uint32_t field_idx,
bool is_static)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
mirror::ArtField* field = dex_cache->GetResolvedField(field_idx);
@@ -296,8 +295,7 @@ static void PreloadDexCachesResolveField(Handle<mirror::DexCache>& dex_cache,
}
// Based on ClassLinker::ResolveMethod.
-static void PreloadDexCachesResolveMethod(Handle<mirror::DexCache>& dex_cache,
- uint32_t method_idx,
+static void PreloadDexCachesResolveMethod(Handle<mirror::DexCache> dex_cache, uint32_t method_idx,
InvokeType invoke_type)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
mirror::ArtMethod* method = dex_cache->GetResolvedMethod(method_idx);
diff --git a/runtime/verifier/method_verifier.cc b/runtime/verifier/method_verifier.cc
index 4863b8367b..2293ad7c08 100644
--- a/runtime/verifier/method_verifier.cc
+++ b/runtime/verifier/method_verifier.cc
@@ -121,8 +121,8 @@ MethodVerifier::FailureKind MethodVerifier::VerifyClass(mirror::Class* klass,
}
MethodVerifier::FailureKind MethodVerifier::VerifyClass(const DexFile* dex_file,
- Handle<mirror::DexCache>& dex_cache,
- Handle<mirror::ClassLoader>& class_loader,
+ Handle<mirror::DexCache> dex_cache,
+ Handle<mirror::ClassLoader> class_loader,
const DexFile::ClassDef* class_def,
bool allow_soft_failures,
std::string* error) {
@@ -151,7 +151,8 @@ MethodVerifier::FailureKind MethodVerifier::VerifyClass(const DexFile* dex_file,
previous_direct_method_idx = method_idx;
InvokeType type = it.GetMethodInvokeType(*class_def);
mirror::ArtMethod* method =
- linker->ResolveMethod(*dex_file, method_idx, dex_cache, class_loader, NULL, type);
+ linker->ResolveMethod(*dex_file, method_idx, dex_cache, class_loader,
+ NullHandle<mirror::ArtMethod>(), type);
if (method == NULL) {
DCHECK(Thread::Current()->IsExceptionPending());
// We couldn't resolve the method, but continue regardless.
@@ -193,7 +194,8 @@ MethodVerifier::FailureKind MethodVerifier::VerifyClass(const DexFile* dex_file,
previous_virtual_method_idx = method_idx;
InvokeType type = it.GetMethodInvokeType(*class_def);
mirror::ArtMethod* method =
- linker->ResolveMethod(*dex_file, method_idx, dex_cache, class_loader, NULL, type);
+ linker->ResolveMethod(*dex_file, method_idx, dex_cache, class_loader,
+ NullHandle<mirror::ArtMethod>(), type);
if (method == NULL) {
DCHECK(Thread::Current()->IsExceptionPending());
// We couldn't resolve the method, but continue regardless.
@@ -232,8 +234,8 @@ MethodVerifier::FailureKind MethodVerifier::VerifyClass(const DexFile* dex_file,
MethodVerifier::FailureKind MethodVerifier::VerifyMethod(uint32_t method_idx,
const DexFile* dex_file,
- Handle<mirror::DexCache>& dex_cache,
- Handle<mirror::ClassLoader>& class_loader,
+ Handle<mirror::DexCache> dex_cache,
+ Handle<mirror::ClassLoader> class_loader,
const DexFile::ClassDef* class_def,
const DexFile::CodeItem* code_item,
mirror::ArtMethod* method,
@@ -277,8 +279,8 @@ MethodVerifier::FailureKind MethodVerifier::VerifyMethod(uint32_t method_idx,
void MethodVerifier::VerifyMethodAndDump(std::ostream& os, uint32_t dex_method_idx,
const DexFile* dex_file,
- Handle<mirror::DexCache>& dex_cache,
- Handle<mirror::ClassLoader>& class_loader,
+ Handle<mirror::DexCache> dex_cache,
+ Handle<mirror::ClassLoader> class_loader,
const DexFile::ClassDef* class_def,
const DexFile::CodeItem* code_item,
mirror::ArtMethod* method,
diff --git a/runtime/verifier/method_verifier.h b/runtime/verifier/method_verifier.h
index 495d3c5353..f614425a91 100644
--- a/runtime/verifier/method_verifier.h
+++ b/runtime/verifier/method_verifier.h
@@ -142,15 +142,15 @@ class MethodVerifier {
/* Verify a class. Returns "kNoFailure" on success. */
static FailureKind VerifyClass(mirror::Class* klass, bool allow_soft_failures, std::string* error)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- static FailureKind VerifyClass(const DexFile* dex_file, Handle<mirror::DexCache>& dex_cache,
- Handle<mirror::ClassLoader>& class_loader,
+ static FailureKind VerifyClass(const DexFile* dex_file, Handle<mirror::DexCache> dex_cache,
+ Handle<mirror::ClassLoader> class_loader,
const DexFile::ClassDef* class_def,
bool allow_soft_failures, std::string* error)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
static void VerifyMethodAndDump(std::ostream& os, uint32_t method_idx, const DexFile* dex_file,
- Handle<mirror::DexCache>& dex_cache,
- Handle<mirror::ClassLoader>& class_loader,
+ Handle<mirror::DexCache> dex_cache,
+ Handle<mirror::ClassLoader> class_loader,
const DexFile::ClassDef* class_def,
const DexFile::CodeItem* code_item,
mirror::ArtMethod* method, uint32_t method_access_flags)
@@ -255,8 +255,8 @@ class MethodVerifier {
* for code flow problems.
*/
static FailureKind VerifyMethod(uint32_t method_idx, const DexFile* dex_file,
- Handle<mirror::DexCache>& dex_cache,
- Handle<mirror::ClassLoader>& class_loader,
+ Handle<mirror::DexCache> dex_cache,
+ Handle<mirror::ClassLoader> class_loader,
const DexFile::ClassDef* class_def_idx,
const DexFile::CodeItem* code_item,
mirror::ArtMethod* method, uint32_t method_access_flags,