| /* |
| * 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. |
| } |