blob: d366d9d465fcff46fddc833af3cf95e80482a87a [file] [log] [blame]
Igor Murashkin017efa82016-09-22 15:46:29 -07001/*
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
Igor Murashkinf5658b42016-09-30 14:12:14 -070017#include <stdio.h>
18#include <jni.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)
Igor Murashkin017efa82016-09-22 15:46:29 -070028
29#define CLASS_NAME "benchmarks/MicroNative/java/NativeMethods"
Igor Murashkinf5658b42016-09-30 14:12:14 -070030#define CLASS_INFIX benchmarks_MicroNative_java_NativeMethods
Igor Murashkin017efa82016-09-22 15:46:29 -070031
Igor Murashkinf5658b42016-09-30 14:12:14 -070032#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)
Igor Murashkin017efa82016-09-22 15:46:29 -070037
38static void NativeMethods_emptyJniStaticSynchronizedMethod0(JNIEnv*, jclass) { }
39static void NativeMethods_emptyJniSynchronizedMethod0(JNIEnv*, jclass) { }
40
41static JNINativeMethod gMethods_NormalOnly[] = {
42 NATIVE_METHOD(NativeMethods, emptyJniStaticSynchronizedMethod0, "()V"),
43 NATIVE_METHOD(NativeMethods, emptyJniSynchronizedMethod0, "()V"),
44};
45
46static void NativeMethods_emptyJniMethod0(JNIEnv*, jobject) { }
47static void NativeMethods_emptyJniMethod6(JNIEnv*, jobject, int, int, int, int, int, int) { }
48static void NativeMethods_emptyJniMethod6L(JNIEnv*, jobject, jobject, jarray, jarray, jobject,
49 jarray, jarray) { }
50static void NativeMethods_emptyJniStaticMethod6L(JNIEnv*, jclass, jobject, jarray, jarray, jobject,
51 jarray, jarray) { }
52
53static void NativeMethods_emptyJniStaticMethod0(JNIEnv*, jclass) { }
54static void NativeMethods_emptyJniStaticMethod6(JNIEnv*, jclass, int, int, int, int, int, int) { }
55
56static 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
65static void NativeMethods_emptyJniMethod0_Fast(JNIEnv*, jobject) { }
66static void NativeMethods_emptyJniMethod6_Fast(JNIEnv*, jobject, int, int, int, int, int, int) { }
67static void NativeMethods_emptyJniMethod6L_Fast(JNIEnv*, jobject, jobject, jarray, jarray, jobject,
68 jarray, jarray) { }
69static void NativeMethods_emptyJniStaticMethod6L_Fast(JNIEnv*, jclass, jobject, jarray, jarray,
70 jobject, jarray, jarray) { }
71
72static void NativeMethods_emptyJniStaticMethod0_Fast(JNIEnv*, jclass) { }
73static void NativeMethods_emptyJniStaticMethod6_Fast(JNIEnv*, jclass, int, int, int, int, int, int) { }
74
75static 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
Igor Murashkinf5658b42016-09-30 14:12:14 -070084// 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.
86DEFINE_NORMAL_JNI_METHOD(void, emptyJniStaticMethod0_1Critical)(JNIEnv*, jclass) { }
87DEFINE_CRITICAL_JNI_METHOD(void, emptyJniStaticMethod0_1Critical)() { }
88DEFINE_NORMAL_JNI_METHOD(void, emptyJniStaticMethod6_1Critical)(JNIEnv*, jclass, int, int, int, int, int, int) { }
89DEFINE_CRITICAL_JNI_METHOD(void, emptyJniStaticMethod6_1Critical)(int, int, int, int, int, int) { }
Igor Murashkin017efa82016-09-22 15:46:29 -070090
91static JNINativeMethod gMethods_Critical[] = {
Igor Murashkinf5658b42016-09-30 14:12:14 -070092 // 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)) }
Igor Murashkin017efa82016-09-22 15:46:29 -070097};
98
Igor Murashkinf5658b42016-09-30 14:12:14 -070099void 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
Igor Murashkin017efa82016-09-22 15:46:29 -0700131void 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));
Igor Murashkinf5658b42016-09-30 14:12:14 -0700135
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.
Igor Murashkin017efa82016-09-22 15:46:29 -0700146}