1 /*
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
17 #include <jni.h>
18 #include <stdio.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)
28
29 #define CLASS_NAME "benchmarks/MicroNative/java/NativeMethods"
30 #define CLASS_INFIX benchmarks_MicroNative_java_NativeMethods
31
32 #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)
37
NativeMethods_emptyJniStaticSynchronizedMethod0(JNIEnv *,jclass)38 static void NativeMethods_emptyJniStaticSynchronizedMethod0(JNIEnv*, jclass) { }
NativeMethods_emptyJniSynchronizedMethod0(JNIEnv *,jclass)39 static void NativeMethods_emptyJniSynchronizedMethod0(JNIEnv*, jclass) { }
40
41 static JNINativeMethod gMethods_NormalOnly[] = {
42 NATIVE_METHOD(NativeMethods, emptyJniStaticSynchronizedMethod0, "()V"),
43 NATIVE_METHOD(NativeMethods, emptyJniSynchronizedMethod0, "()V"),
44 };
45
NativeMethods_emptyJniMethod0(JNIEnv *,jobject)46 static void NativeMethods_emptyJniMethod0(JNIEnv*, jobject) { }
NativeMethods_emptyJniMethod6(JNIEnv *,jobject,int,int,int,int,int,int)47 static void NativeMethods_emptyJniMethod6(JNIEnv*, jobject, int, int, int, int, int, int) { }
NativeMethods_emptyJniMethod6L(JNIEnv *,jobject,jobject,jarray,jarray,jobject,jarray,jarray)48 static void NativeMethods_emptyJniMethod6L(JNIEnv*, jobject, jobject, jarray, jarray, jobject,
49 jarray, jarray) { }
NativeMethods_emptyJniStaticMethod6L(JNIEnv *,jclass,jobject,jarray,jarray,jobject,jarray,jarray)50 static void NativeMethods_emptyJniStaticMethod6L(JNIEnv*, jclass, jobject, jarray, jarray, jobject,
51 jarray, jarray) { }
52
NativeMethods_emptyJniStaticMethod0(JNIEnv *,jclass)53 static void NativeMethods_emptyJniStaticMethod0(JNIEnv*, jclass) { }
NativeMethods_emptyJniStaticMethod6(JNIEnv *,jclass,int,int,int,int,int,int)54 static void NativeMethods_emptyJniStaticMethod6(JNIEnv*, jclass, int, int, int, int, int, int) { }
55
56 static 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
NativeMethods_emptyJniMethod0_Fast(JNIEnv *,jobject)65 static void NativeMethods_emptyJniMethod0_Fast(JNIEnv*, jobject) { }
NativeMethods_emptyJniMethod6_Fast(JNIEnv *,jobject,int,int,int,int,int,int)66 static void NativeMethods_emptyJniMethod6_Fast(JNIEnv*, jobject, int, int, int, int, int, int) { }
NativeMethods_emptyJniMethod6L_Fast(JNIEnv *,jobject,jobject,jarray,jarray,jobject,jarray,jarray)67 static void NativeMethods_emptyJniMethod6L_Fast(JNIEnv*, jobject, jobject, jarray, jarray, jobject,
68 jarray, jarray) { }
NativeMethods_emptyJniStaticMethod6L_Fast(JNIEnv *,jclass,jobject,jarray,jarray,jobject,jarray,jarray)69 static void NativeMethods_emptyJniStaticMethod6L_Fast(JNIEnv*, jclass, jobject, jarray, jarray,
70 jobject, jarray, jarray) { }
71
NativeMethods_emptyJniStaticMethod0_Fast(JNIEnv *,jclass)72 static void NativeMethods_emptyJniStaticMethod0_Fast(JNIEnv*, jclass) { }
NativeMethods_emptyJniStaticMethod6_Fast(JNIEnv *,jclass,int,int,int,int,int,int)73 static void NativeMethods_emptyJniStaticMethod6_Fast(JNIEnv*, jclass, int, int, int, int, int, int) { }
74
75 static 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
84 // 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.
DEFINE_NORMAL_JNI_METHOD(void,emptyJniStaticMethod0_1Critical)86 DEFINE_NORMAL_JNI_METHOD(void, emptyJniStaticMethod0_1Critical)(JNIEnv*, jclass) { }
DEFINE_CRITICAL_JNI_METHOD(void,emptyJniStaticMethod0_1Critical)87 DEFINE_CRITICAL_JNI_METHOD(void, emptyJniStaticMethod0_1Critical)() { }
DEFINE_NORMAL_JNI_METHOD(void,emptyJniStaticMethod6_1Critical)88 DEFINE_NORMAL_JNI_METHOD(void, emptyJniStaticMethod6_1Critical)(JNIEnv*, jclass, int, int, int, int, int, int) { }
DEFINE_CRITICAL_JNI_METHOD(void,emptyJniStaticMethod6_1Critical)89 DEFINE_CRITICAL_JNI_METHOD(void, emptyJniStaticMethod6_1Critical)(int, int, int, int, int, int) { }
90
91 static JNINativeMethod gMethods_Critical[] = {
92 // 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)) }
97 };
98
jniRegisterNativeMethods(JNIEnv * env,const char * className,const JNINativeMethod * methods,int numMethods)99 void 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
register_micro_native_methods(JNIEnv * env)131 void 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));
135
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.
146 }
147