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.
147 lines
7.0 KiB
147 lines
7.0 KiB
4 months ago
|
/*
|
||
|
* 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.
|
||
|
}
|