diff options
Diffstat (limited to 'test')
| -rw-r--r-- | test/656-annotation-lookup-generic-jni/expected.txt | 3 | ||||
| -rw-r--r-- | test/656-annotation-lookup-generic-jni/info.txt | 5 | ||||
| -rw-r--r-- | test/656-annotation-lookup-generic-jni/src-ex/DummyAnnotation.java | 17 | ||||
| -rw-r--r-- | test/656-annotation-lookup-generic-jni/src-ex/Test.java | 28 | ||||
| -rw-r--r-- | test/656-annotation-lookup-generic-jni/src/Main.java | 76 | ||||
| -rw-r--r-- | test/656-annotation-lookup-generic-jni/test.cc | 28 | ||||
| -rw-r--r-- | test/Android.bp | 1 |
7 files changed, 158 insertions, 0 deletions
diff --git a/test/656-annotation-lookup-generic-jni/expected.txt b/test/656-annotation-lookup-generic-jni/expected.txt new file mode 100644 index 0000000000..4519c7e442 --- /dev/null +++ b/test/656-annotation-lookup-generic-jni/expected.txt @@ -0,0 +1,3 @@ +JNI_OnLoad called +Java_Test_nativeMethodWithAnnotation +passed diff --git a/test/656-annotation-lookup-generic-jni/info.txt b/test/656-annotation-lookup-generic-jni/info.txt new file mode 100644 index 0000000000..ddc19300ce --- /dev/null +++ b/test/656-annotation-lookup-generic-jni/info.txt @@ -0,0 +1,5 @@ +Non-regression test for b/38454151, where the invocation of a native +method with an annotatation through Generic JNI would crash the +Generic JNI trampoline because it would throw and exception when +trying to resolve the annotation (during the CriticalNative/FastNative +optimization annotation lookup). diff --git a/test/656-annotation-lookup-generic-jni/src-ex/DummyAnnotation.java b/test/656-annotation-lookup-generic-jni/src-ex/DummyAnnotation.java new file mode 100644 index 0000000000..6caac6685e --- /dev/null +++ b/test/656-annotation-lookup-generic-jni/src-ex/DummyAnnotation.java @@ -0,0 +1,17 @@ +/* + * 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 @interface DummyAnnotation {} diff --git a/test/656-annotation-lookup-generic-jni/src-ex/Test.java b/test/656-annotation-lookup-generic-jni/src-ex/Test.java new file mode 100644 index 0000000000..838b4fe0d6 --- /dev/null +++ b/test/656-annotation-lookup-generic-jni/src-ex/Test.java @@ -0,0 +1,28 @@ +/* + * 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 Test { + + public static void initialize(String libname) { + // Load test native library to get access to the implementation of + // Test.nativeMethodWithAnnotation. + System.loadLibrary(libname); + } + + @DummyAnnotation + public static native void nativeMethodWithAnnotation(); + +} diff --git a/test/656-annotation-lookup-generic-jni/src/Main.java b/test/656-annotation-lookup-generic-jni/src/Main.java new file mode 100644 index 0000000000..01b288a900 --- /dev/null +++ b/test/656-annotation-lookup-generic-jni/src/Main.java @@ -0,0 +1,76 @@ +/* + * 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. + */ + +import dalvik.system.InMemoryDexClassLoader; + +import java.io.InputStream; +import java.lang.reflect.Method; +import java.nio.ByteBuffer; +import java.util.zip.ZipEntry; +import java.util.zip.ZipFile; + +public class Main { + + public static void main(String[] args) throws Exception { + // Extract Dex file contents from the secondary Jar file. + String jarFilename = + System.getenv("DEX_LOCATION") + "/656-annotation-lookup-generic-jni-ex.jar"; + ZipFile zipFile = new ZipFile(jarFilename); + ZipEntry zipEntry = zipFile.getEntry("classes.dex"); + InputStream inputStream = zipFile.getInputStream(zipEntry); + int dexFileSize = (int) zipEntry.getSize(); + byte[] dexFileContents = new byte[dexFileSize]; + inputStream.read(dexFileContents, 0, dexFileSize); + + // Create class loader from secondary Dex file. + ByteBuffer dexBuffer = ByteBuffer.wrap(dexFileContents); + ClassLoader classLoader = createUnquickenedDexClassLoader(dexBuffer); + + // Load and initialize the Test class. + Class<?> testClass = classLoader.loadClass("Test"); + Method initialize = testClass.getMethod("initialize", String.class); + initialize.invoke(null, args[0]); + + // Invoke Test.nativeMethodWithAnnotation(). + Method nativeMethodWithAnnotation = testClass.getMethod("nativeMethodWithAnnotation"); + // Invoking the native method Test.nativeMethodWithAnnotation used + // to crash the Generic JNI trampoline during the resolution of + // the method's annotations (DummyAnnotation) (see b/38454151). + nativeMethodWithAnnotation.invoke(null); + + zipFile.close(); + System.out.println("passed"); + } + + // Create a class loader loading a Dex file in memory + // *without creating an Oat file*. This way, the Dex file won't be + // quickened and JNI stubs won't be compiled, thus forcing the use + // of Generic JNI when invoking the native method + // Test.nativeMethodWithAnnotation. + static ClassLoader createUnquickenedDexClassLoader(ByteBuffer dexBuffer) { + InMemoryDexClassLoader cl = new InMemoryDexClassLoader(dexBuffer, getBootClassLoader()); + return cl; + } + + static ClassLoader getBootClassLoader() { + ClassLoader cl = Main.class.getClassLoader(); + while (cl.getParent() != null) { + cl = cl.getParent(); + } + return cl; + } + +} diff --git a/test/656-annotation-lookup-generic-jni/test.cc b/test/656-annotation-lookup-generic-jni/test.cc new file mode 100644 index 0000000000..c8aa2af921 --- /dev/null +++ b/test/656-annotation-lookup-generic-jni/test.cc @@ -0,0 +1,28 @@ +/* + * 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. + */ + +#include "jni.h" + +#include <iostream> + +namespace art { + +// Native method annotated with `DummyAnnotation` in Java source. +extern "C" JNIEXPORT void JNICALL Java_Test_nativeMethodWithAnnotation(JNIEnv*, jclass) { + std::cout << "Java_Test_nativeMethodWithAnnotation" << std::endl; +} + +} // namespace art diff --git a/test/Android.bp b/test/Android.bp index 1679669056..2d682ed0e0 100644 --- a/test/Android.bp +++ b/test/Android.bp @@ -393,6 +393,7 @@ cc_defaults { "626-const-class-linking/clear_dex_cache_types.cc", "642-fp-callees/fp_callees.cc", "647-jni-get-field-id/get_field_id.cc", + "656-annotation-lookup-generic-jni/test.cc" ], shared_libs: [ "libbacktrace", |