You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
146 lines
7.0 KiB
146 lines
7.0 KiB
/* |
|
* 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 <stdio.h> |
|
#include <jni.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. |
|
}
|
|
|