| /* | |
| * Copyright (C) 2016 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 <stdio.h> | |
| #ifndef NATIVE_METHOD | |
| #define NATIVE_METHOD(className, functionName, signature) \ | |
| { #functionName, signature, reinterpret_cast<void*>(className ## _ ## functionName) } | |
| #endif | |
| #define NELEM(x) (sizeof(x)/sizeof((x)[0])) | |
| #define GLUE4(a, b, c, d) a ## b ## c ## d | |
| #define GLUE4_(a, b, c, d) GLUE4(a, b, c, d) | |
| #define CLASS_NAME "benchmarks/MicroNative/java/NativeMethods" | |
| #define CLASS_INFIX benchmarks_MicroNative_java_NativeMethods | |
| #define NAME_NORMAL_JNI_METHOD(name) GLUE4_(Java_, CLASS_INFIX, _, name) | |
| #define NAME_CRITICAL_JNI_METHOD(name) GLUE4_(JavaCritical_, CLASS_INFIX, _, name) | |
| #define DEFINE_NORMAL_JNI_METHOD(ret, name) extern "C" JNIEXPORT ret JNICALL GLUE4_(Java_, CLASS_INFIX, _, name) | |
| #define DEFINE_CRITICAL_JNI_METHOD(ret, name) extern "C" JNIEXPORT ret JNICALL GLUE4_(JavaCritical_, CLASS_INFIX, _, name) | |
| static void NativeMethods_emptyJniStaticSynchronizedMethod0(JNIEnv*, jclass) { } | |
| static void NativeMethods_emptyJniSynchronizedMethod0(JNIEnv*, jclass) { } | |
| static JNINativeMethod gMethods_NormalOnly[] = { | |
| NATIVE_METHOD(NativeMethods, emptyJniStaticSynchronizedMethod0, "()V"), | |
| NATIVE_METHOD(NativeMethods, emptyJniSynchronizedMethod0, "()V"), | |
| }; | |
| static void NativeMethods_emptyJniMethod0(JNIEnv*, jobject) { } | |
| static void NativeMethods_emptyJniMethod6(JNIEnv*, jobject, int, int, int, int, int, int) { } | |
| static void NativeMethods_emptyJniMethod6L(JNIEnv*, jobject, jobject, jarray, jarray, jobject, | |
| jarray, jarray) { } | |
| static void NativeMethods_emptyJniStaticMethod6L(JNIEnv*, jclass, jobject, jarray, jarray, jobject, | |
| jarray, jarray) { } | |
| static void NativeMethods_emptyJniStaticMethod0(JNIEnv*, jclass) { } | |
| static void NativeMethods_emptyJniStaticMethod6(JNIEnv*, jclass, int, int, int, int, int, int) { } | |
| static JNINativeMethod gMethods[] = { | |
| NATIVE_METHOD(NativeMethods, emptyJniMethod0, "()V"), | |
| NATIVE_METHOD(NativeMethods, emptyJniMethod6, "(IIIIII)V"), | |
| NATIVE_METHOD(NativeMethods, emptyJniMethod6L, "(Ljava/lang/String;[Ljava/lang/String;[[ILjava/lang/Object;[Ljava/lang/Object;[[[[Ljava/lang/Object;)V"), | |
| NATIVE_METHOD(NativeMethods, emptyJniStaticMethod6L, "(Ljava/lang/String;[Ljava/lang/String;[[ILjava/lang/Object;[Ljava/lang/Object;[[[[Ljava/lang/Object;)V"), | |
| NATIVE_METHOD(NativeMethods, emptyJniStaticMethod0, "()V"), | |
| NATIVE_METHOD(NativeMethods, emptyJniStaticMethod6, "(IIIIII)V"), | |
| }; | |
| static void NativeMethods_emptyJniMethod0_Fast(JNIEnv*, jobject) { } | |
| static void NativeMethods_emptyJniMethod6_Fast(JNIEnv*, jobject, int, int, int, int, int, int) { } | |
| static void NativeMethods_emptyJniMethod6L_Fast(JNIEnv*, jobject, jobject, jarray, jarray, jobject, | |
| jarray, jarray) { } | |
| static void NativeMethods_emptyJniStaticMethod6L_Fast(JNIEnv*, jclass, jobject, jarray, jarray, | |
| jobject, jarray, jarray) { } | |
| static void NativeMethods_emptyJniStaticMethod0_Fast(JNIEnv*, jclass) { } | |
| static void NativeMethods_emptyJniStaticMethod6_Fast(JNIEnv*, jclass, int, int, int, int, int, int) { } | |
| static JNINativeMethod gMethods_Fast[] = { | |
| NATIVE_METHOD(NativeMethods, emptyJniMethod0_Fast, "()V"), | |
| NATIVE_METHOD(NativeMethods, emptyJniMethod6_Fast, "(IIIIII)V"), | |
| NATIVE_METHOD(NativeMethods, emptyJniMethod6L_Fast, "(Ljava/lang/String;[Ljava/lang/String;[[ILjava/lang/Object;[Ljava/lang/Object;[[[[Ljava/lang/Object;)V"), | |
| NATIVE_METHOD(NativeMethods, emptyJniStaticMethod6L_Fast, "(Ljava/lang/String;[Ljava/lang/String;[[ILjava/lang/Object;[Ljava/lang/Object;[[[[Ljava/lang/Object;)V"), | |
| NATIVE_METHOD(NativeMethods, emptyJniStaticMethod0_Fast, "()V"), | |
| NATIVE_METHOD(NativeMethods, emptyJniStaticMethod6_Fast, "(IIIIII)V"), | |
| }; | |
| // Have both a Java_ and a JavaCritical_ version of the same empty method. | |
| // The runtime automatically selects the right one when doing a dlsym-based native lookup. | |
| DEFINE_NORMAL_JNI_METHOD(void, emptyJniStaticMethod0_1Critical)(JNIEnv*, jclass) { } | |
| DEFINE_CRITICAL_JNI_METHOD(void, emptyJniStaticMethod0_1Critical)() { } | |
| DEFINE_NORMAL_JNI_METHOD(void, emptyJniStaticMethod6_1Critical)(JNIEnv*, jclass, int, int, int, int, int, int) { } | |
| DEFINE_CRITICAL_JNI_METHOD(void, emptyJniStaticMethod6_1Critical)(int, int, int, int, int, int) { } | |
| static JNINativeMethod gMethods_Critical[] = { | |
| // Don't use NATIVE_METHOD because the name is mangled differently. | |
| { "emptyJniStaticMethod0_Critical", "()V", | |
| reinterpret_cast<void*>(NAME_CRITICAL_JNI_METHOD(emptyJniStaticMethod0_1Critical)) }, | |
| { "emptyJniStaticMethod6_Critical", "(IIIIII)V", | |
| reinterpret_cast<void*>(NAME_CRITICAL_JNI_METHOD(emptyJniStaticMethod6_1Critical)) } | |
| }; | |
| void jniRegisterNativeMethods(JNIEnv* env, | |
| const char* className, | |
| const JNINativeMethod* methods, | |
| int numMethods) { | |
| jclass c = env->FindClass(className); | |
| if (c == nullptr) { | |
| char* tmp; | |
| const char* msg; | |
| if (asprintf(&tmp, | |
| "Native registration unable to find class '%s'; aborting...", | |
| className) == -1) { | |
| // Allocation failed, print default warning. | |
| msg = "Native registration unable to find class; aborting..."; | |
| } else { | |
| msg = tmp; | |
| } | |
| env->FatalError(msg); | |
| } | |
| if (env->RegisterNatives(c, methods, numMethods) < 0) { | |
| char* tmp; | |
| const char* msg; | |
| if (asprintf(&tmp, "RegisterNatives failed for '%s'; aborting...", className) == -1) { | |
| // Allocation failed, print default warning. | |
| msg = "RegisterNatives failed; aborting..."; | |
| } else { | |
| msg = tmp; | |
| } | |
| env->FatalError(msg); | |
| } | |
| } | |
| void register_micro_native_methods(JNIEnv* env) { | |
| jniRegisterNativeMethods(env, CLASS_NAME, gMethods_NormalOnly, NELEM(gMethods_NormalOnly)); | |
| jniRegisterNativeMethods(env, CLASS_NAME, gMethods, NELEM(gMethods)); | |
| jniRegisterNativeMethods(env, CLASS_NAME, gMethods_Fast, NELEM(gMethods_Fast)); | |
| if (env->FindClass("dalvik/annotation/optimization/CriticalNative") != nullptr) { | |
| // Only register them explicitly if the annotation is present. | |
| jniRegisterNativeMethods(env, CLASS_NAME, gMethods_Critical, NELEM(gMethods_Critical)); | |
| } else { | |
| if (env->ExceptionCheck()) { | |
| // It will throw NoClassDefFoundError | |
| env->ExceptionClear(); | |
| } | |
| } | |
| // else let them be registered implicitly. | |
| } |