summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Nicolas Geoffray <ngeoffray@google.com> 2017-06-07 14:09:43 +0100
committer Nicolas Geoffray <ngeoffray@google.com> 2017-06-07 14:11:57 +0100
commit23ddfe86788fe1c95b8be6c76f3a127f8f51dd9f (patch)
treee1070a3eeb7ba8f489339415324f98417b7eb94c
parent0a87f31513e5f9da27856af054d2241452898b22 (diff)
Don't call EnsureInitialized in the JIT.
Calling EnsureInitialized can block due to locking on the class object, that an application can also do. Just rely that the compilation request is for a reason. The compiler aleady knows how to compile methods of classes that are not initialized. bug: 62243120 Test: test.py --jit Change-Id: I6cd6828b4c2179504cf5334921fcb8d46615c77b
-rw-r--r--compiler/jit/jit_compiler.cc10
-rw-r--r--test/655-jit-clinit/expected.txt1
-rw-r--r--test/655-jit-clinit/info.txt3
-rw-r--r--test/655-jit-clinit/src/Main.java46
-rw-r--r--test/common/runtime_state.cc22
5 files changed, 69 insertions, 13 deletions
diff --git a/compiler/jit/jit_compiler.cc b/compiler/jit/jit_compiler.cc
index fed1f48d65..66135414f7 100644
--- a/compiler/jit/jit_compiler.cc
+++ b/compiler/jit/jit_compiler.cc
@@ -189,18 +189,12 @@ JitCompiler::~JitCompiler() {
bool JitCompiler::CompileMethod(Thread* self, ArtMethod* method, bool osr) {
DCHECK(!method->IsProxyMethod());
+ DCHECK(method->GetDeclaringClass()->IsResolved());
+
TimingLogger logger("JIT compiler timing logger", true, VLOG_IS_ON(jit));
- StackHandleScope<2> hs(self);
self->AssertNoPendingException();
Runtime* runtime = Runtime::Current();
- // Ensure the class is initialized.
- Handle<mirror::Class> h_class(hs.NewHandle(method->GetDeclaringClass()));
- if (!runtime->GetClassLinker()->EnsureInitialized(self, h_class, true, true)) {
- VLOG(jit) << "JIT failed to initialize " << method->PrettyMethod();
- return false;
- }
-
// Do the compilation.
bool success = false;
{
diff --git a/test/655-jit-clinit/expected.txt b/test/655-jit-clinit/expected.txt
new file mode 100644
index 0000000000..6a5618ebc6
--- /dev/null
+++ b/test/655-jit-clinit/expected.txt
@@ -0,0 +1 @@
+JNI_OnLoad called
diff --git a/test/655-jit-clinit/info.txt b/test/655-jit-clinit/info.txt
new file mode 100644
index 0000000000..39c6dec368
--- /dev/null
+++ b/test/655-jit-clinit/info.txt
@@ -0,0 +1,3 @@
+Regression test for the JIT compiler, which used to wait
+on a class object, meaning applocation code could just block
+all JIT compilations.
diff --git a/test/655-jit-clinit/src/Main.java b/test/655-jit-clinit/src/Main.java
new file mode 100644
index 0000000000..5d32180c50
--- /dev/null
+++ b/test/655-jit-clinit/src/Main.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+public class Main {
+ public static void main(String[] args) throws Exception {
+ System.loadLibrary(args[0]);
+ if (!hasJit()) {
+ return;
+ }
+ Foo.hotMethod();
+ }
+
+ public native static boolean isJitCompiled(Class<?> cls, String methodName);
+ private native static boolean hasJit();
+}
+
+class Foo {
+ static void hotMethod() {
+ for (int i = 0; i < array.length; ++i) {
+ array[i] = array;
+ }
+ }
+
+ static {
+ array = new Object[10000];
+ while (!Main.isJitCompiled(Foo.class, "hotMethod")) {
+ Foo.hotMethod();
+ Thread.yield();
+ }
+ }
+
+ static Object[] array;
+}
diff --git a/test/common/runtime_state.cc b/test/common/runtime_state.cc
index 7ac019e5d3..d8e5b571bd 100644
--- a/test/common/runtime_state.cc
+++ b/test/common/runtime_state.cc
@@ -148,12 +148,24 @@ extern "C" JNIEXPORT jboolean JNICALL Java_Main_isAotCompiled(JNIEnv* env,
CHECK(chars.c_str() != nullptr);
ArtMethod* method = soa.Decode<mirror::Class>(cls)->FindDeclaredDirectMethodByName(
chars.c_str(), kRuntimePointerSize);
- const void* code = method->GetOatMethodQuickCode(kRuntimePointerSize);
- jit::Jit* jit = Runtime::Current()->GetJit();
- if (jit != nullptr && jit->GetCodeCache()->ContainsPc(code)) {
- return true;
+ return method->GetOatMethodQuickCode(kRuntimePointerSize) != nullptr;
+}
+
+extern "C" JNIEXPORT jboolean JNICALL Java_Main_isJitCompiled(JNIEnv* env,
+ jclass,
+ jclass cls,
+ jstring method_name) {
+ jit::Jit* jit = GetJitIfEnabled();
+ if (jit == nullptr) {
+ return false;
}
- return code != nullptr;
+ Thread* self = Thread::Current();
+ ScopedObjectAccess soa(self);
+ ScopedUtfChars chars(env, method_name);
+ CHECK(chars.c_str() != nullptr);
+ ArtMethod* method = soa.Decode<mirror::Class>(cls)->FindDeclaredDirectMethodByName(
+ chars.c_str(), kRuntimePointerSize);
+ return jit->GetCodeCache()->ContainsPc(method->GetEntryPointFromQuickCompiledCode());
}
extern "C" JNIEXPORT void JNICALL Java_Main_ensureJitCompiled(JNIEnv* env,