summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/655-jit-clinit/src/Main.java4
-rw-r--r--test/667-jit-jni-stub/expected.txt1
-rw-r--r--test/667-jit-jni-stub/info.txt1
-rw-r--r--test/667-jit-jni-stub/jit_jni_stub_test.cc63
-rwxr-xr-xtest/667-jit-jni-stub/run18
-rw-r--r--test/667-jit-jni-stub/src/Main.java180
-rw-r--r--test/Android.bp1
-rw-r--r--test/common/runtime_state.cc25
8 files changed, 6 insertions, 287 deletions
diff --git a/test/655-jit-clinit/src/Main.java b/test/655-jit-clinit/src/Main.java
index 2fb8f2a86e..44b315478f 100644
--- a/test/655-jit-clinit/src/Main.java
+++ b/test/655-jit-clinit/src/Main.java
@@ -23,7 +23,7 @@ public class Main {
Foo.hotMethod();
}
- public native static boolean hasJitCompiledEntrypoint(Class<?> cls, String methodName);
+ public native static boolean isJitCompiled(Class<?> cls, String methodName);
private native static boolean hasJit();
}
@@ -36,7 +36,7 @@ class Foo {
static {
array = new Object[10000];
- while (!Main.hasJitCompiledEntrypoint(Foo.class, "hotMethod")) {
+ while (!Main.isJitCompiled(Foo.class, "hotMethod")) {
Foo.hotMethod();
try {
// Sleep to give a chance for the JIT to compile `hotMethod`.
diff --git a/test/667-jit-jni-stub/expected.txt b/test/667-jit-jni-stub/expected.txt
deleted file mode 100644
index 6a5618ebc6..0000000000
--- a/test/667-jit-jni-stub/expected.txt
+++ /dev/null
@@ -1 +0,0 @@
-JNI_OnLoad called
diff --git a/test/667-jit-jni-stub/info.txt b/test/667-jit-jni-stub/info.txt
deleted file mode 100644
index 6f25c44592..0000000000
--- a/test/667-jit-jni-stub/info.txt
+++ /dev/null
@@ -1 +0,0 @@
-Tests for JITting and collecting JNI stubs.
diff --git a/test/667-jit-jni-stub/jit_jni_stub_test.cc b/test/667-jit-jni-stub/jit_jni_stub_test.cc
deleted file mode 100644
index 82e06fc018..0000000000
--- a/test/667-jit-jni-stub/jit_jni_stub_test.cc
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright 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.
- */
-
-#include <jni.h>
-
-#include "jit/jit.h"
-#include "jit/jit_code_cache.h"
-#include "mirror/class.h"
-#include "mirror/string.h"
-#include "runtime.h"
-#include "scoped_thread_state_change-inl.h"
-
-namespace art {
-
-// Local class declared as a friend of JitCodeCache so that we can access its internals.
-class JitJniStubTestHelper {
- public:
- static bool isNextJitGcFull(Thread* self) REQUIRES_SHARED(Locks::mutator_lock_) {
- CHECK(Runtime::Current()->GetJit() != nullptr);
- jit::JitCodeCache* cache = Runtime::Current()->GetJit()->GetCodeCache();
- MutexLock mu(self, cache->lock_);
- return cache->ShouldDoFullCollection();
- }
-};
-
-// Calls through to a static method with signature "()V".
-extern "C" JNIEXPORT
-void Java_Main_callThrough(JNIEnv* env, jclass, jclass klass, jstring methodName) {
- ScopedObjectAccess soa(Thread::Current());
- std::string name = soa.Decode<mirror::String>(methodName)->ToModifiedUtf8();
- jmethodID method = env->GetStaticMethodID(klass, name.c_str(), "()V");
- CHECK(method != nullptr) << soa.Decode<mirror::Class>(klass)->PrettyDescriptor() << "." << name;
- env->CallStaticVoidMethod(klass, method);
-}
-
-extern "C" JNIEXPORT
-void Java_Main_jitGc(JNIEnv*, jclass) {
- CHECK(Runtime::Current()->GetJit() != nullptr);
- jit::JitCodeCache* cache = Runtime::Current()->GetJit()->GetCodeCache();
- ScopedObjectAccess soa(Thread::Current());
- cache->GarbageCollectCache(Thread::Current());
-}
-
-extern "C" JNIEXPORT
-jboolean Java_Main_isNextJitGcFull(JNIEnv*, jclass) {
- ScopedObjectAccess soa(Thread::Current());
- return JitJniStubTestHelper::isNextJitGcFull(soa.Self());
-}
-
-} // namespace art
diff --git a/test/667-jit-jni-stub/run b/test/667-jit-jni-stub/run
deleted file mode 100755
index 1877be482e..0000000000
--- a/test/667-jit-jni-stub/run
+++ /dev/null
@@ -1,18 +0,0 @@
-#!/bin/bash
-#
-# 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.
-
-# Disable AOT compilation of JNI stubs.
-${RUN} "${@}" --no-prebuild --no-dex2oat
diff --git a/test/667-jit-jni-stub/src/Main.java b/test/667-jit-jni-stub/src/Main.java
deleted file mode 100644
index b867970eab..0000000000
--- a/test/667-jit-jni-stub/src/Main.java
+++ /dev/null
@@ -1,180 +0,0 @@
-/*
- * 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 (isAotCompiled(Main.class, "hasJit")) {
- throw new Error("This test must be run with --no-prebuild --no-dex2oat!");
- }
- if (!hasJit()) {
- return;
- }
-
- testCompilationUseAndCollection();
- testMixedFramesOnStack();
- }
-
- public static void testCompilationUseAndCollection() {
- // Test that callThrough() can be JIT-compiled.
- assertFalse(hasJitCompiledEntrypoint(Main.class, "callThrough"));
- assertFalse(hasJitCompiledCode(Main.class, "callThrough"));
- ensureCompiledCallThroughEntrypoint(/* call */ true);
- assertTrue(hasJitCompiledEntrypoint(Main.class, "callThrough"));
- assertTrue(hasJitCompiledCode(Main.class, "callThrough"));
-
- // Use callThrough() once again now that the method has a JIT-compiled stub.
- callThrough(Main.class, "doNothing");
-
- // Test that GC with the JIT-compiled stub on the stack does not collect it.
- // Also tests stack walk over the JIT-compiled stub.
- callThrough(Main.class, "testGcWithCallThroughStubOnStack");
-
- // Test that, when marking used methods before a full JIT GC, a single execution
- // of the GenericJNI trampoline can save the compiled stub from being collected.
- testSingleInvocationTriggersRecompilation();
-
- // Test that the JNI compiled stub can actually be collected.
- testStubCanBeCollected();
- }
-
- public static void testGcWithCallThroughStubOnStack() {
- // Check that this method was called via JIT-compiled callThrough() stub.
- assertTrue(hasJitCompiledEntrypoint(Main.class, "callThrough"));
- // This assertion also exercises stack walk over the JIT-compiled callThrough() stub.
- assertTrue(new Throwable().getStackTrace()[1].getMethodName().equals("callThrough"));
-
- doJitGcsUntilFullJitGcIsScheduled();
- // The callThrough() on the stack above this method is using the compiled stub,
- // so the JIT GC should not remove the compiled code.
- jitGc();
- assertTrue(hasJitCompiledCode(Main.class, "callThrough"));
- }
-
- public static void testSingleInvocationTriggersRecompilation() {
- // After scheduling a full JIT GC, single call through the GenericJNI
- // trampoline should ensure that the compiled stub is used again.
- doJitGcsUntilFullJitGcIsScheduled();
- callThrough(Main.class, "doNothing");
- ensureCompiledCallThroughEntrypoint(/* call */ false); // Wait for the compilation task to run.
- assertTrue(hasJitCompiledEntrypoint(Main.class, "callThrough"));
- jitGc(); // This JIT GC should not collect the callThrough() stub.
- assertTrue(hasJitCompiledCode(Main.class, "callThrough"));
- }
-
- public static void testMixedFramesOnStack() {
- // Starts without a compiled JNI stub for callThrough().
- assertFalse(hasJitCompiledEntrypoint(Main.class, "callThrough"));
- assertFalse(hasJitCompiledCode(Main.class, "callThrough"));
- callThrough(Main.class, "testMixedFramesOnStackStage2");
- // We have just returned through the JIT-compiled JNI stub, so it must still
- // be compiled (though not necessarily with the entrypoint pointing to it).
- assertTrue(hasJitCompiledCode(Main.class, "callThrough"));
- // Though the callThrough() is on the stack, that frame is using the GenericJNI
- // and does not prevent the collection of the JNI stub.
- testStubCanBeCollected();
- }
-
- public static void testMixedFramesOnStackStage2() {
- // We cannot assert that callThrough() has no JIT compiled stub as that check
- // may race against the compilation task. Just check the caller.
- assertTrue(new Throwable().getStackTrace()[1].getMethodName().equals("callThrough"));
- // Now ensure that the JNI stub is compiled and used.
- ensureCompiledCallThroughEntrypoint(/* call */ true);
- callThrough(Main.class, "testMixedFramesOnStackStage3");
- }
-
- public static void testMixedFramesOnStackStage3() {
- // Check that this method was called via JIT-compiled callThrough() stub.
- assertTrue(hasJitCompiledEntrypoint(Main.class, "callThrough"));
- // This assertion also exercises stack walk over the JIT-compiled callThrough() stub.
- assertTrue(new Throwable().getStackTrace()[1].getMethodName().equals("callThrough"));
- // For a good measure, try a JIT GC.
- jitGc();
- }
-
- public static void testStubCanBeCollected() {
- assertTrue(hasJitCompiledCode(Main.class, "callThrough"));
- doJitGcsUntilFullJitGcIsScheduled();
- assertFalse(hasJitCompiledEntrypoint(Main.class, "callThrough"));
- assertTrue(hasJitCompiledCode(Main.class, "callThrough"));
- jitGc(); // JIT GC without callThrough() on the stack should collect the callThrough() stub.
- assertFalse(hasJitCompiledEntrypoint(Main.class, "callThrough"));
- assertFalse(hasJitCompiledCode(Main.class, "callThrough"));
- }
-
- public static void doJitGcsUntilFullJitGcIsScheduled() {
- // We enter with a compiled stub for callThrough() but we also need the entrypoint to be set.
- assertTrue(hasJitCompiledCode(Main.class, "callThrough"));
- ensureCompiledCallThroughEntrypoint(/* call */ true);
- // Perform JIT GC until the next GC is marked to do full collection.
- do {
- assertTrue(hasJitCompiledEntrypoint(Main.class, "callThrough"));
- callThrough(Main.class, "jitGc"); // JIT GC with callThrough() safely on the stack.
- } while (!isNextJitGcFull());
- // The JIT GC before the full collection resets entrypoints and waits to see
- // if the methods are still in use.
- assertFalse(hasJitCompiledEntrypoint(Main.class, "callThrough"));
- assertTrue(hasJitCompiledCode(Main.class, "callThrough"));
- }
-
- public static void ensureCompiledCallThroughEntrypoint(boolean call) {
- int count = 0;
- while (!hasJitCompiledEntrypoint(Main.class, "callThrough")) {
- // If `call` is true, also exercise the `callThrough()` method to increase hotness.
- int limit = call ? 1 << Math.min(count, 12) : 0;
- for (int i = 0; i < limit; ++i) {
- callThrough(Main.class, "doNothing");
- }
- try {
- // Sleep to give a chance for the JIT to compile `hasJit` stub.
- Thread.sleep(100);
- } catch (Exception e) {
- // Ignore
- }
- if (++count == 50) {
- throw new Error("TIMEOUT");
- }
- };
- }
-
- public static void assertTrue(boolean value) {
- if (!value) {
- throw new AssertionError("Expected true!");
- }
- }
-
- public static void assertFalse(boolean value) {
- if (value) {
- throw new AssertionError("Expected false!");
- }
- }
-
- public static void doNothing() { }
- public static void throwError() { throw new Error(); }
-
- // Note that the callThrough()'s shorty differs from shorties of the other
- // native methods used in this test because of the return type `void.`
- public native static void callThrough(Class<?> cls, String methodName);
-
- public native static void jitGc();
- public native static boolean isNextJitGcFull();
-
- public native static boolean isAotCompiled(Class<?> cls, String methodName);
- public native static boolean hasJitCompiledEntrypoint(Class<?> cls, String methodName);
- public native static boolean hasJitCompiledCode(Class<?> cls, String methodName);
- private native static boolean hasJit();
-}
diff --git a/test/Android.bp b/test/Android.bp
index 01e424d5e3..ace62c23b8 100644
--- a/test/Android.bp
+++ b/test/Android.bp
@@ -385,7 +385,6 @@ cc_defaults {
"656-annotation-lookup-generic-jni/test.cc",
"661-oat-writer-layout/oat_writer_layout.cc",
"664-aget-verifier/aget-verifier.cc",
- "667-jit-jni-stub/jit_jni_stub_test.cc",
"708-jit-cache-churn/jit.cc",
],
shared_libs: [
diff --git a/test/common/runtime_state.cc b/test/common/runtime_state.cc
index 34580800cc..df497c1181 100644
--- a/test/common/runtime_state.cc
+++ b/test/common/runtime_state.cc
@@ -152,10 +152,10 @@ extern "C" JNIEXPORT jboolean JNICALL Java_Main_isAotCompiled(JNIEnv* env,
return method->GetOatMethodQuickCode(kRuntimePointerSize) != nullptr;
}
-extern "C" JNIEXPORT jboolean JNICALL Java_Main_hasJitCompiledEntrypoint(JNIEnv* env,
- jclass,
- jclass cls,
- jstring method_name) {
+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;
@@ -169,23 +169,6 @@ extern "C" JNIEXPORT jboolean JNICALL Java_Main_hasJitCompiledEntrypoint(JNIEnv*
return jit->GetCodeCache()->ContainsPc(method->GetEntryPointFromQuickCompiledCode());
}
-extern "C" JNIEXPORT jboolean JNICALL Java_Main_hasJitCompiledCode(JNIEnv* env,
- jclass,
- jclass cls,
- jstring method_name) {
- jit::Jit* jit = GetJitIfEnabled();
- if (jit == nullptr) {
- return false;
- }
- 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()->ContainsMethod(method);
-}
-
extern "C" JNIEXPORT void JNICALL Java_Main_ensureJitCompiled(JNIEnv* env,
jclass,
jclass cls,