1 /* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include <jni.h> 18 #include <stdio.h> 19 20 #ifndef NATIVE_METHOD 21 #define NATIVE_METHOD(className, functionName, signature) \ 22 { #functionName, signature, reinterpret_cast<void*>(className ## _ ## functionName) } 23 #endif 24 #define NELEM(x) (sizeof(x)/sizeof((x)[0])) 25 26 #define GLUE4(a, b, c, d) a ## b ## c ## d 27 #define GLUE4_(a, b, c, d) GLUE4(a, b, c, d) 28 29 #define CLASS_NAME "benchmarks/MicroNative/java/NativeMethods" 30 #define CLASS_INFIX benchmarks_MicroNative_java_NativeMethods 31 32 #define NAME_NORMAL_JNI_METHOD(name) GLUE4_(Java_, CLASS_INFIX, _, name) 33 #define NAME_CRITICAL_JNI_METHOD(name) GLUE4_(JavaCritical_, CLASS_INFIX, _, name) 34 35 #define DEFINE_NORMAL_JNI_METHOD(ret, name) extern "C" JNIEXPORT ret JNICALL GLUE4_(Java_, CLASS_INFIX, _, name) 36 #define DEFINE_CRITICAL_JNI_METHOD(ret, name) extern "C" JNIEXPORT ret JNICALL GLUE4_(JavaCritical_, CLASS_INFIX, _, name) 37 38 static void NativeMethods_emptyJniStaticSynchronizedMethod0(JNIEnv*, jclass) { } 39 static void NativeMethods_emptyJniSynchronizedMethod0(JNIEnv*, jclass) { } 40 41 static JNINativeMethod gMethods_NormalOnly[] = { 42 NATIVE_METHOD(NativeMethods, emptyJniStaticSynchronizedMethod0, "()V"), 43 NATIVE_METHOD(NativeMethods, emptyJniSynchronizedMethod0, "()V"), 44 }; 45 46 static void NativeMethods_emptyJniMethod0(JNIEnv*, jobject) { } 47 static void NativeMethods_emptyJniMethod6(JNIEnv*, jobject, int, int, int, int, int, int) { } 48 static void NativeMethods_emptyJniMethod6L(JNIEnv*, jobject, jobject, jarray, jarray, jobject, 49 jarray, jarray) { } 50 static void NativeMethods_emptyJniStaticMethod6L(JNIEnv*, jclass, jobject, jarray, jarray, jobject, 51 jarray, jarray) { } 52 53 static void NativeMethods_emptyJniStaticMethod0(JNIEnv*, jclass) { } 54 static void NativeMethods_emptyJniStaticMethod6(JNIEnv*, jclass, int, int, int, int, int, int) { } 55 56 static JNINativeMethod gMethods[] = { 57 NATIVE_METHOD(NativeMethods, emptyJniMethod0, "()V"), 58 NATIVE_METHOD(NativeMethods, emptyJniMethod6, "(IIIIII)V"), 59 NATIVE_METHOD(NativeMethods, emptyJniMethod6L, "(Ljava/lang/String;[Ljava/lang/String;[[ILjava/lang/Object;[Ljava/lang/Object;[[[[Ljava/lang/Object;)V"), 60 NATIVE_METHOD(NativeMethods, emptyJniStaticMethod6L, "(Ljava/lang/String;[Ljava/lang/String;[[ILjava/lang/Object;[Ljava/lang/Object;[[[[Ljava/lang/Object;)V"), 61 NATIVE_METHOD(NativeMethods, emptyJniStaticMethod0, "()V"), 62 NATIVE_METHOD(NativeMethods, emptyJniStaticMethod6, "(IIIIII)V"), 63 }; 64 65 static void NativeMethods_emptyJniMethod0_Fast(JNIEnv*, jobject) { } 66 static void NativeMethods_emptyJniMethod6_Fast(JNIEnv*, jobject, int, int, int, int, int, int) { } 67 static void NativeMethods_emptyJniMethod6L_Fast(JNIEnv*, jobject, jobject, jarray, jarray, jobject, 68 jarray, jarray) { } 69 static void NativeMethods_emptyJniStaticMethod6L_Fast(JNIEnv*, jclass, jobject, jarray, jarray, 70 jobject, jarray, jarray) { } 71 72 static void NativeMethods_emptyJniStaticMethod0_Fast(JNIEnv*, jclass) { } 73 static void NativeMethods_emptyJniStaticMethod6_Fast(JNIEnv*, jclass, int, int, int, int, int, int) { } 74 75 static JNINativeMethod gMethods_Fast[] = { 76 NATIVE_METHOD(NativeMethods, emptyJniMethod0_Fast, "()V"), 77 NATIVE_METHOD(NativeMethods, emptyJniMethod6_Fast, "(IIIIII)V"), 78 NATIVE_METHOD(NativeMethods, emptyJniMethod6L_Fast, "(Ljava/lang/String;[Ljava/lang/String;[[ILjava/lang/Object;[Ljava/lang/Object;[[[[Ljava/lang/Object;)V"), 79 NATIVE_METHOD(NativeMethods, emptyJniStaticMethod6L_Fast, "(Ljava/lang/String;[Ljava/lang/String;[[ILjava/lang/Object;[Ljava/lang/Object;[[[[Ljava/lang/Object;)V"), 80 NATIVE_METHOD(NativeMethods, emptyJniStaticMethod0_Fast, "()V"), 81 NATIVE_METHOD(NativeMethods, emptyJniStaticMethod6_Fast, "(IIIIII)V"), 82 }; 83 84 // Have both a Java_ and a JavaCritical_ version of the same empty method. 85 // The runtime automatically selects the right one when doing a dlsym-based native lookup. 86 DEFINE_NORMAL_JNI_METHOD(void, emptyJniStaticMethod0_1Critical)(JNIEnv*, jclass) { } 87 DEFINE_CRITICAL_JNI_METHOD(void, emptyJniStaticMethod0_1Critical)() { } 88 DEFINE_NORMAL_JNI_METHOD(void, emptyJniStaticMethod6_1Critical)(JNIEnv*, jclass, int, int, int, int, int, int) { } 89 DEFINE_CRITICAL_JNI_METHOD(void, emptyJniStaticMethod6_1Critical)(int, int, int, int, int, int) { } 90 91 static JNINativeMethod gMethods_Critical[] = { 92 // Don't use NATIVE_METHOD because the name is mangled differently. 93 { "emptyJniStaticMethod0_Critical", "()V", 94 reinterpret_cast<void*>(NAME_CRITICAL_JNI_METHOD(emptyJniStaticMethod0_1Critical)) }, 95 { "emptyJniStaticMethod6_Critical", "(IIIIII)V", 96 reinterpret_cast<void*>(NAME_CRITICAL_JNI_METHOD(emptyJniStaticMethod6_1Critical)) } 97 }; 98 99 void jniRegisterNativeMethods(JNIEnv* env, 100 const char* className, 101 const JNINativeMethod* methods, 102 int numMethods) { 103 jclass c = env->FindClass(className); 104 if (c == nullptr) { 105 char* tmp; 106 const char* msg; 107 if (asprintf(&tmp, 108 "Native registration unable to find class '%s'; aborting...", 109 className) == -1) { 110 // Allocation failed, print default warning. 111 msg = "Native registration unable to find class; aborting..."; 112 } else { 113 msg = tmp; 114 } 115 env->FatalError(msg); 116 } 117 118 if (env->RegisterNatives(c, methods, numMethods) < 0) { 119 char* tmp; 120 const char* msg; 121 if (asprintf(&tmp, "RegisterNatives failed for '%s'; aborting...", className) == -1) { 122 // Allocation failed, print default warning. 123 msg = "RegisterNatives failed; aborting..."; 124 } else { 125 msg = tmp; 126 } 127 env->FatalError(msg); 128 } 129 } 130 131 void register_micro_native_methods(JNIEnv* env) { 132 jniRegisterNativeMethods(env, CLASS_NAME, gMethods_NormalOnly, NELEM(gMethods_NormalOnly)); 133 jniRegisterNativeMethods(env, CLASS_NAME, gMethods, NELEM(gMethods)); 134 jniRegisterNativeMethods(env, CLASS_NAME, gMethods_Fast, NELEM(gMethods_Fast)); 135 136 if (env->FindClass("dalvik/annotation/optimization/CriticalNative") != nullptr) { 137 // Only register them explicitly if the annotation is present. 138 jniRegisterNativeMethods(env, CLASS_NAME, gMethods_Critical, NELEM(gMethods_Critical)); 139 } else { 140 if (env->ExceptionCheck()) { 141 // It will throw NoClassDefFoundError 142 env->ExceptionClear(); 143 } 144 } 145 // else let them be registered implicitly. 146 } 147