summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Mathieu Chartier <mathieuc@google.com> 2018-01-14 00:22:04 +0000
committer Mathieu Chartier <mathieuc@google.com> 2018-01-14 00:29:51 +0000
commitc971f6e06a43e70a2d86cb4b3ad0e13a9ae9a06c (patch)
tree9fa6be931e7bc8d0f47b0eb2d91a683ffcf1c3f1
parent94730ef9ca432b5ede81e928cffc4006911aa650 (diff)
Revert "Ensure that methods requiring interpreter entrypoint always have it."
This reverts commit 94730ef9ca432b5ede81e928cffc4006911aa650. Debug tests failing. Ran: test/run-test --always-clean --prebuild --compact-dex-level none --optimizing --no-relocate --runtime-option -Xcheck:jni --64 --build-with-javac-dx 067-preemptive-unpark Bug: 62821960 Change-Id: Ia4fb7b7b3a60879662dea50ce32b1cfb5e0a3eff
-rw-r--r--runtime/art_method.cc15
-rw-r--r--runtime/class_linker.cc54
-rw-r--r--runtime/class_linker.h5
-rw-r--r--runtime/entrypoints/quick/quick_trampoline_entrypoints.cc6
-rw-r--r--runtime/instrumentation.cc8
5 files changed, 30 insertions, 58 deletions
diff --git a/runtime/art_method.cc b/runtime/art_method.cc
index f9eedae23e..44a5dde485 100644
--- a/runtime/art_method.cc
+++ b/runtime/art_method.cc
@@ -319,21 +319,6 @@ void ArtMethod::Invoke(Thread* self, uint32_t* args, uint32_t args_size, JValue*
self->AssertThreadSuspensionIsAllowable();
CHECK_EQ(kRunnable, self->GetState());
CHECK_STREQ(GetInterfaceMethodIfProxy(kRuntimePointerSize)->GetShorty(), shorty);
-
- if (!IsNative() &&
- !IsObsolete() &&
- !IsProxyMethod() &&
- IsInvokable() &&
- ClassLinker::ShouldUseInterpreterEntrypoint(this, GetEntryPointFromQuickCompiledCode())) {
- ClassLinker* cl = Runtime::Current()->GetClassLinker();
- const void* entry_point = GetEntryPointFromQuickCompiledCode();
- DCHECK(cl->IsQuickToInterpreterBridge(entry_point) ||
- cl->IsQuickResolutionStub(entry_point) ||
- entry_point == GetQuickInstrumentationEntryPoint())
- << PrettyMethod() << " is expected to be interpreted but has an unexpected entrypoint."
- << " The entrypoint is " << entry_point << " (incorrect) oat entrypoint would be "
- << GetOatMethodQuickCode(cl->GetImagePointerSize());
- }
}
// Push a transition back into managed code onto the linked list in thread.
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index c487808161..877654247c 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -1296,32 +1296,22 @@ void AppImageClassLoadersAndDexCachesHelper::Update(
}
for (ArtMethod& m : klass->GetDirectMethods(kRuntimePointerSize)) {
const void* code = m.GetEntryPointFromQuickCompiledCode();
- if (!m.IsProxyMethod() &&
- !m.IsNative() &&
- !class_linker->IsQuickResolutionStub(code) &&
+ const void* oat_code = m.IsInvokable() ? class_linker->GetQuickOatCodeFor(&m) : code;
+ if (!class_linker->IsQuickResolutionStub(code) &&
+ !class_linker->IsQuickGenericJniStub(code) &&
!class_linker->IsQuickToInterpreterBridge(code) &&
- 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();
- }
+ !m.IsNative()) {
+ DCHECK_EQ(code, oat_code) << m.PrettyMethod();
}
}
for (ArtMethod& m : klass->GetVirtualMethods(kRuntimePointerSize)) {
const void* code = m.GetEntryPointFromQuickCompiledCode();
- if (!m.IsProxyMethod() &&
- !m.IsNative() &&
- !class_linker->IsQuickResolutionStub(code) &&
+ const void* oat_code = m.IsInvokable() ? class_linker->GetQuickOatCodeFor(&m) : code;
+ if (!class_linker->IsQuickResolutionStub(code) &&
+ !class_linker->IsQuickGenericJniStub(code) &&
!class_linker->IsQuickToInterpreterBridge(code) &&
- 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();
- }
+ !m.IsNative()) {
+ DCHECK_EQ(code, oat_code) << m.PrettyMethod();
}
}
}
@@ -2909,25 +2899,21 @@ uint32_t ClassLinker::SizeOfClassWithoutEmbeddedTables(const DexFile& dex_file,
image_pointer_size_);
}
-const void* ClassLinker::GetQuickEntrypointFor(ArtMethod* method) {
+// Special case to get oat code without overwriting a trampoline.
+const void* ClassLinker::GetQuickOatCodeFor(ArtMethod* method) {
CHECK(method->IsInvokable()) << method->PrettyMethod();
if (method->IsProxyMethod()) {
return GetQuickProxyInvokeHandler();
}
- 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;
+ auto* code = method->GetOatMethodQuickCode(GetImagePointerSize());
+ if (code != nullptr) {
+ return code;
+ }
+ if (method->IsNative()) {
+ // No code and native? Use generic trampoline.
+ return GetQuickGenericJniStub();
}
+ return GetQuickToInterpreterBridge();
}
bool ClassLinker::ShouldUseInterpreterEntrypoint(ArtMethod* method, const void* quick_code) {
diff --git a/runtime/class_linker.h b/runtime/class_linker.h
index 62804e79c5..3e3425f5ac 100644
--- a/runtime/class_linker.h
+++ b/runtime/class_linker.h
@@ -498,8 +498,9 @@ class ClassLinker {
std::string GetDescriptorForProxy(ObjPtr<mirror::Class> proxy_class)
REQUIRES_SHARED(Locks::mutator_lock_);
- // Get the correct entrypoint for a method as far as the class-linker is concerned.
- const void* GetQuickEntrypointFor(ArtMethod* method) REQUIRES_SHARED(Locks::mutator_lock_);
+ // Get the oat code for a method when its class isn't yet initialized.
+ const void* GetQuickOatCodeFor(ArtMethod* method)
+ REQUIRES_SHARED(Locks::mutator_lock_);
pid_t GetClassesLockOwner(); // For SignalCatcher.
pid_t GetDexLockOwner(); // For SignalCatcher.
diff --git a/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc b/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc
index a32c717ffe..f727690c11 100644
--- a/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc
+++ b/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc
@@ -1294,9 +1294,9 @@ extern "C" const void* artQuickResolutionTrampoline(
// with the interpreter.
code = GetQuickToInterpreterBridge();
} else if (invoke_type == kStatic) {
- // Class is still initializing. The entrypoint contains the trampoline, so we cannot return
- // it. Instead, ask the class linker what is the actual code that needs to be invoked.
- code = linker->GetQuickEntrypointFor(called);
+ // Class is still initializing, go to oat and grab code (trampoline must be left in place
+ // until class is initialized to stop races between threads).
+ code = linker->GetQuickOatCodeFor(called);
} else {
// No trampoline for non-static methods.
code = called->GetEntryPointFromQuickCompiledCode();
diff --git a/runtime/instrumentation.cc b/runtime/instrumentation.cc
index 2a1f219fae..4524448916 100644
--- a/runtime/instrumentation.cc
+++ b/runtime/instrumentation.cc
@@ -167,7 +167,7 @@ void Instrumentation::InstallStubsForMethod(ArtMethod* method) {
if (NeedDebugVersionFor(method)) {
new_quick_code = GetQuickToInterpreterBridge();
} else {
- new_quick_code = class_linker->GetQuickEntrypointFor(method);
+ new_quick_code = class_linker->GetQuickOatCodeFor(method);
}
} else {
new_quick_code = GetQuickResolutionStub();
@@ -188,7 +188,7 @@ void Instrumentation::InstallStubsForMethod(ArtMethod* method) {
} else if (entry_exit_stubs_installed_) {
new_quick_code = GetQuickInstrumentationEntryPoint();
} else {
- new_quick_code = class_linker->GetQuickEntrypointFor(method);
+ new_quick_code = class_linker->GetQuickOatCodeFor(method);
}
} else {
new_quick_code = GetQuickResolutionStub();
@@ -877,7 +877,7 @@ void Instrumentation::Undeoptimize(ArtMethod* method) {
} else {
const void* quick_code = NeedDebugVersionFor(method)
? GetQuickToInterpreterBridge()
- : class_linker->GetQuickEntrypointFor(method);
+ : class_linker->GetQuickOatCodeFor(method);
UpdateEntrypoints(method, quick_code);
}
@@ -971,7 +971,7 @@ const void* Instrumentation::GetQuickCodeFor(ArtMethod* method, PointerSize poin
return code;
}
}
- return class_linker->GetQuickEntrypointFor(method);
+ return class_linker->GetQuickOatCodeFor(method);
}
void Instrumentation::MethodEnterEventImpl(Thread* thread,