summaryrefslogtreecommitdiff
path: root/runtime/class_linker.cc
diff options
context:
space:
mode:
Diffstat (limited to 'runtime/class_linker.cc')
-rw-r--r--runtime/class_linker.cc54
1 files changed, 34 insertions, 20 deletions
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index 877654247c..c487808161 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -1296,22 +1296,32 @@ void AppImageClassLoadersAndDexCachesHelper::Update(
}
for (ArtMethod& m : klass->GetDirectMethods(kRuntimePointerSize)) {
const void* code = m.GetEntryPointFromQuickCompiledCode();
- const void* oat_code = m.IsInvokable() ? class_linker->GetQuickOatCodeFor(&m) : code;
- if (!class_linker->IsQuickResolutionStub(code) &&
- !class_linker->IsQuickGenericJniStub(code) &&
+ if (!m.IsProxyMethod() &&
+ !m.IsNative() &&
+ !class_linker->IsQuickResolutionStub(code) &&
!class_linker->IsQuickToInterpreterBridge(code) &&
- !m.IsNative()) {
- DCHECK_EQ(code, oat_code) << m.PrettyMethod();
+ m.IsInvokable()) {
+ // Since this is just a sanity check it's okay to get the oat code here regardless
+ // of whether it's usable.
+ const void* oat_code = m.GetOatMethodQuickCode(class_linker->GetImagePointerSize());
+ if (oat_code != nullptr) {
+ DCHECK_EQ(code, oat_code) << m.PrettyMethod();
+ }
}
}
for (ArtMethod& m : klass->GetVirtualMethods(kRuntimePointerSize)) {
const void* code = m.GetEntryPointFromQuickCompiledCode();
- const void* oat_code = m.IsInvokable() ? class_linker->GetQuickOatCodeFor(&m) : code;
- if (!class_linker->IsQuickResolutionStub(code) &&
- !class_linker->IsQuickGenericJniStub(code) &&
+ if (!m.IsProxyMethod() &&
+ !m.IsNative() &&
+ !class_linker->IsQuickResolutionStub(code) &&
!class_linker->IsQuickToInterpreterBridge(code) &&
- !m.IsNative()) {
- DCHECK_EQ(code, oat_code) << m.PrettyMethod();
+ m.IsInvokable()) {
+ // Since this is just a sanity check it's okay to get the oat code here regardless
+ // of whether it's usable.
+ const void* oat_code = m.GetOatMethodQuickCode(class_linker->GetImagePointerSize());
+ if (oat_code != nullptr) {
+ DCHECK_EQ(code, oat_code) << m.PrettyMethod();
+ }
}
}
}
@@ -2899,21 +2909,25 @@ uint32_t ClassLinker::SizeOfClassWithoutEmbeddedTables(const DexFile& dex_file,
image_pointer_size_);
}
-// Special case to get oat code without overwriting a trampoline.
-const void* ClassLinker::GetQuickOatCodeFor(ArtMethod* method) {
+const void* ClassLinker::GetQuickEntrypointFor(ArtMethod* method) {
CHECK(method->IsInvokable()) << method->PrettyMethod();
if (method->IsProxyMethod()) {
return GetQuickProxyInvokeHandler();
}
- auto* code = method->GetOatMethodQuickCode(GetImagePointerSize());
- if (code != nullptr) {
- return code;
- }
- if (method->IsNative()) {
- // No code and native? Use generic trampoline.
- return GetQuickGenericJniStub();
+ const void* oat_code = method->GetOatMethodQuickCode(GetImagePointerSize());
+ if (oat_code == nullptr) {
+ // We need either the generic jni or interpreter bridge.
+ if (method->IsNative()) {
+ return GetQuickGenericJniStub();
+ } else {
+ return GetQuickToInterpreterBridge();
+ }
+ } else if (ClassLinker::ShouldUseInterpreterEntrypoint(method, oat_code)) {
+ // We have oat code but we cannot use it for some reason.
+ return GetQuickToInterpreterBridge();
+ } else {
+ return oat_code;
}
- return GetQuickToInterpreterBridge();
}
bool ClassLinker::ShouldUseInterpreterEntrypoint(ArtMethod* method, const void* quick_code) {