jni: Add @CriticalNative optimization to speed up JNI transitions
Change-Id: I963059ac3a72dd8e6a867596c356d7062deb6da7
diff --git a/test/004-JniTest/jni_test.cc b/test/004-JniTest/jni_test.cc
index bb18a70..81be531 100644
--- a/test/004-JniTest/jni_test.cc
+++ b/test/004-JniTest/jni_test.cc
@@ -28,9 +28,11 @@
static JavaVM* jvm = nullptr;
static jint Java_Main_intFastNativeMethod(JNIEnv*, jclass, jint a, jint b, jint c);
+static jint Java_Main_intCriticalNativeMethod(jint a, jint b, jint c);
static JNINativeMethod sMainMethods[] = {
- {"intFastNativeMethod", "(III)I", reinterpret_cast<void*>(Java_Main_intFastNativeMethod) }
+ {"intFastNativeMethod", "(III)I", reinterpret_cast<void*>(Java_Main_intFastNativeMethod) },
+ {"intCriticalNativeMethod", "(III)I", reinterpret_cast<void*>(Java_Main_intCriticalNativeMethod) },
};
extern "C" JNIEXPORT jint JNI_OnLoad(JavaVM *vm, void*) {
@@ -766,5 +768,12 @@
return a + b + c;
}
+// Annotated with @CriticalNative in Java code. Doesn't need to be explicitly registered with "!".
+// NOTE: Has to be registered explicitly to avoid mutator lock check failures.
+static jint Java_Main_intCriticalNativeMethod(jint a, jint b, jint c) {
+ // Note that unlike a "Fast Native" method this excludes JNIEnv and the jclass parameters.
+ return a + b + c;
+}
+
} // namespace art
diff --git a/test/004-JniTest/src/Main.java b/test/004-JniTest/src/Main.java
index 573afdb..bb098e4 100644
--- a/test/004-JniTest/src/Main.java
+++ b/test/004-JniTest/src/Main.java
@@ -18,6 +18,7 @@
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
+import dalvik.annotation.optimization.CriticalNative;
import dalvik.annotation.optimization.FastNative;
public class Main {
@@ -49,6 +50,7 @@
registerNativesJniTest();
testFastNativeMethods();
+ testCriticalNativeMethods();
}
private static native boolean registerNativesJniTest();
@@ -288,7 +290,23 @@
}
}
+ // Smoke test for @CriticalNative
+ // TODO: Way more thorough tests since it involved quite a bit of changes.
+ // Return sum of a+b+c.
+ @CriticalNative
+ static native int intCriticalNativeMethod(int a, int b, int c);
+
+ private static void testCriticalNativeMethods() {
+ int returns[] = { 3, 6, 9, 12, 15 };
+ for (int i = 0; i < returns.length; i++) {
+ int result = intCriticalNativeMethod(i, i+1, i+2);
+ if (returns[i] != result) {
+ System.out.println("CriticalNative Int Run " + i + " with " + returns[i] + " vs " + result);
+ throw new AssertionError();
+ }
+ }
+ }
}
@FunctionalInterface