1*795d594fSAndroid Build Coastguard Worker /*
2*795d594fSAndroid Build Coastguard Worker * Copyright (C) 2016 The Android Open Source Project
3*795d594fSAndroid Build Coastguard Worker *
4*795d594fSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*795d594fSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*795d594fSAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*795d594fSAndroid Build Coastguard Worker *
8*795d594fSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*795d594fSAndroid Build Coastguard Worker *
10*795d594fSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*795d594fSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*795d594fSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*795d594fSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*795d594fSAndroid Build Coastguard Worker * limitations under the License.
15*795d594fSAndroid Build Coastguard Worker */
16*795d594fSAndroid Build Coastguard Worker
17*795d594fSAndroid Build Coastguard Worker #include <jni.h>
18*795d594fSAndroid Build Coastguard Worker #include <stdio.h>
19*795d594fSAndroid Build Coastguard Worker
20*795d594fSAndroid Build Coastguard Worker #ifndef NATIVE_METHOD
21*795d594fSAndroid Build Coastguard Worker #define NATIVE_METHOD(className, functionName, signature) \
22*795d594fSAndroid Build Coastguard Worker { #functionName, signature, reinterpret_cast<void*>(className ## _ ## functionName) }
23*795d594fSAndroid Build Coastguard Worker #endif
24*795d594fSAndroid Build Coastguard Worker #define NELEM(x) (sizeof(x)/sizeof((x)[0]))
25*795d594fSAndroid Build Coastguard Worker
26*795d594fSAndroid Build Coastguard Worker #define GLUE4(a, b, c, d) a ## b ## c ## d
27*795d594fSAndroid Build Coastguard Worker #define GLUE4_(a, b, c, d) GLUE4(a, b, c, d)
28*795d594fSAndroid Build Coastguard Worker
29*795d594fSAndroid Build Coastguard Worker #define CLASS_NAME "benchmarks/MicroNative/java/NativeMethods"
30*795d594fSAndroid Build Coastguard Worker #define CLASS_INFIX benchmarks_MicroNative_java_NativeMethods
31*795d594fSAndroid Build Coastguard Worker
32*795d594fSAndroid Build Coastguard Worker #define NAME_NORMAL_JNI_METHOD(name) GLUE4_(Java_, CLASS_INFIX, _, name)
33*795d594fSAndroid Build Coastguard Worker #define NAME_CRITICAL_JNI_METHOD(name) GLUE4_(JavaCritical_, CLASS_INFIX, _, name)
34*795d594fSAndroid Build Coastguard Worker
35*795d594fSAndroid Build Coastguard Worker #define DEFINE_NORMAL_JNI_METHOD(ret, name) extern "C" JNIEXPORT ret JNICALL GLUE4_(Java_, CLASS_INFIX, _, name)
36*795d594fSAndroid Build Coastguard Worker #define DEFINE_CRITICAL_JNI_METHOD(ret, name) extern "C" JNIEXPORT ret JNICALL GLUE4_(JavaCritical_, CLASS_INFIX, _, name)
37*795d594fSAndroid Build Coastguard Worker
NativeMethods_emptyJniStaticSynchronizedMethod0(JNIEnv *,jclass)38*795d594fSAndroid Build Coastguard Worker static void NativeMethods_emptyJniStaticSynchronizedMethod0(JNIEnv*, jclass) { }
NativeMethods_emptyJniSynchronizedMethod0(JNIEnv *,jclass)39*795d594fSAndroid Build Coastguard Worker static void NativeMethods_emptyJniSynchronizedMethod0(JNIEnv*, jclass) { }
40*795d594fSAndroid Build Coastguard Worker
41*795d594fSAndroid Build Coastguard Worker static JNINativeMethod gMethods_NormalOnly[] = {
42*795d594fSAndroid Build Coastguard Worker NATIVE_METHOD(NativeMethods, emptyJniStaticSynchronizedMethod0, "()V"),
43*795d594fSAndroid Build Coastguard Worker NATIVE_METHOD(NativeMethods, emptyJniSynchronizedMethod0, "()V"),
44*795d594fSAndroid Build Coastguard Worker };
45*795d594fSAndroid Build Coastguard Worker
NativeMethods_emptyJniMethod0(JNIEnv *,jobject)46*795d594fSAndroid Build Coastguard Worker static void NativeMethods_emptyJniMethod0(JNIEnv*, jobject) { }
NativeMethods_emptyJniMethod6(JNIEnv *,jobject,int,int,int,int,int,int)47*795d594fSAndroid Build Coastguard Worker static void NativeMethods_emptyJniMethod6(JNIEnv*, jobject, int, int, int, int, int, int) { }
NativeMethods_emptyJniMethod6L(JNIEnv *,jobject,jobject,jarray,jarray,jobject,jarray,jarray)48*795d594fSAndroid Build Coastguard Worker static void NativeMethods_emptyJniMethod6L(JNIEnv*, jobject, jobject, jarray, jarray, jobject,
49*795d594fSAndroid Build Coastguard Worker jarray, jarray) { }
NativeMethods_emptyJniStaticMethod6L(JNIEnv *,jclass,jobject,jarray,jarray,jobject,jarray,jarray)50*795d594fSAndroid Build Coastguard Worker static void NativeMethods_emptyJniStaticMethod6L(JNIEnv*, jclass, jobject, jarray, jarray, jobject,
51*795d594fSAndroid Build Coastguard Worker jarray, jarray) { }
52*795d594fSAndroid Build Coastguard Worker
NativeMethods_emptyJniStaticMethod0(JNIEnv *,jclass)53*795d594fSAndroid Build Coastguard Worker static void NativeMethods_emptyJniStaticMethod0(JNIEnv*, jclass) { }
NativeMethods_emptyJniStaticMethod6(JNIEnv *,jclass,int,int,int,int,int,int)54*795d594fSAndroid Build Coastguard Worker static void NativeMethods_emptyJniStaticMethod6(JNIEnv*, jclass, int, int, int, int, int, int) { }
55*795d594fSAndroid Build Coastguard Worker
56*795d594fSAndroid Build Coastguard Worker static JNINativeMethod gMethods[] = {
57*795d594fSAndroid Build Coastguard Worker NATIVE_METHOD(NativeMethods, emptyJniMethod0, "()V"),
58*795d594fSAndroid Build Coastguard Worker NATIVE_METHOD(NativeMethods, emptyJniMethod6, "(IIIIII)V"),
59*795d594fSAndroid Build Coastguard Worker NATIVE_METHOD(NativeMethods, emptyJniMethod6L, "(Ljava/lang/String;[Ljava/lang/String;[[ILjava/lang/Object;[Ljava/lang/Object;[[[[Ljava/lang/Object;)V"),
60*795d594fSAndroid Build Coastguard Worker NATIVE_METHOD(NativeMethods, emptyJniStaticMethod6L, "(Ljava/lang/String;[Ljava/lang/String;[[ILjava/lang/Object;[Ljava/lang/Object;[[[[Ljava/lang/Object;)V"),
61*795d594fSAndroid Build Coastguard Worker NATIVE_METHOD(NativeMethods, emptyJniStaticMethod0, "()V"),
62*795d594fSAndroid Build Coastguard Worker NATIVE_METHOD(NativeMethods, emptyJniStaticMethod6, "(IIIIII)V"),
63*795d594fSAndroid Build Coastguard Worker };
64*795d594fSAndroid Build Coastguard Worker
NativeMethods_emptyJniMethod0_Fast(JNIEnv *,jobject)65*795d594fSAndroid Build Coastguard Worker static void NativeMethods_emptyJniMethod0_Fast(JNIEnv*, jobject) { }
NativeMethods_emptyJniMethod6_Fast(JNIEnv *,jobject,int,int,int,int,int,int)66*795d594fSAndroid Build Coastguard Worker 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*795d594fSAndroid Build Coastguard Worker static void NativeMethods_emptyJniMethod6L_Fast(JNIEnv*, jobject, jobject, jarray, jarray, jobject,
68*795d594fSAndroid Build Coastguard Worker jarray, jarray) { }
NativeMethods_emptyJniStaticMethod6L_Fast(JNIEnv *,jclass,jobject,jarray,jarray,jobject,jarray,jarray)69*795d594fSAndroid Build Coastguard Worker static void NativeMethods_emptyJniStaticMethod6L_Fast(JNIEnv*, jclass, jobject, jarray, jarray,
70*795d594fSAndroid Build Coastguard Worker jobject, jarray, jarray) { }
71*795d594fSAndroid Build Coastguard Worker
NativeMethods_emptyJniStaticMethod0_Fast(JNIEnv *,jclass)72*795d594fSAndroid Build Coastguard Worker static void NativeMethods_emptyJniStaticMethod0_Fast(JNIEnv*, jclass) { }
NativeMethods_emptyJniStaticMethod6_Fast(JNIEnv *,jclass,int,int,int,int,int,int)73*795d594fSAndroid Build Coastguard Worker static void NativeMethods_emptyJniStaticMethod6_Fast(JNIEnv*, jclass, int, int, int, int, int, int) { }
74*795d594fSAndroid Build Coastguard Worker
75*795d594fSAndroid Build Coastguard Worker static JNINativeMethod gMethods_Fast[] = {
76*795d594fSAndroid Build Coastguard Worker NATIVE_METHOD(NativeMethods, emptyJniMethod0_Fast, "()V"),
77*795d594fSAndroid Build Coastguard Worker NATIVE_METHOD(NativeMethods, emptyJniMethod6_Fast, "(IIIIII)V"),
78*795d594fSAndroid Build Coastguard Worker NATIVE_METHOD(NativeMethods, emptyJniMethod6L_Fast, "(Ljava/lang/String;[Ljava/lang/String;[[ILjava/lang/Object;[Ljava/lang/Object;[[[[Ljava/lang/Object;)V"),
79*795d594fSAndroid Build Coastguard Worker NATIVE_METHOD(NativeMethods, emptyJniStaticMethod6L_Fast, "(Ljava/lang/String;[Ljava/lang/String;[[ILjava/lang/Object;[Ljava/lang/Object;[[[[Ljava/lang/Object;)V"),
80*795d594fSAndroid Build Coastguard Worker NATIVE_METHOD(NativeMethods, emptyJniStaticMethod0_Fast, "()V"),
81*795d594fSAndroid Build Coastguard Worker NATIVE_METHOD(NativeMethods, emptyJniStaticMethod6_Fast, "(IIIIII)V"),
82*795d594fSAndroid Build Coastguard Worker };
83*795d594fSAndroid Build Coastguard Worker
84*795d594fSAndroid Build Coastguard Worker // Have both a Java_ and a JavaCritical_ version of the same empty method.
85*795d594fSAndroid Build Coastguard Worker // The runtime automatically selects the right one when doing a dlsym-based native lookup.
DEFINE_NORMAL_JNI_METHOD(void,emptyJniStaticMethod0_1Critical)86*795d594fSAndroid Build Coastguard Worker DEFINE_NORMAL_JNI_METHOD(void, emptyJniStaticMethod0_1Critical)(JNIEnv*, jclass) { }
DEFINE_CRITICAL_JNI_METHOD(void,emptyJniStaticMethod0_1Critical)87*795d594fSAndroid Build Coastguard Worker DEFINE_CRITICAL_JNI_METHOD(void, emptyJniStaticMethod0_1Critical)() { }
DEFINE_NORMAL_JNI_METHOD(void,emptyJniStaticMethod6_1Critical)88*795d594fSAndroid Build Coastguard Worker DEFINE_NORMAL_JNI_METHOD(void, emptyJniStaticMethod6_1Critical)(JNIEnv*, jclass, int, int, int, int, int, int) { }
DEFINE_CRITICAL_JNI_METHOD(void,emptyJniStaticMethod6_1Critical)89*795d594fSAndroid Build Coastguard Worker DEFINE_CRITICAL_JNI_METHOD(void, emptyJniStaticMethod6_1Critical)(int, int, int, int, int, int) { }
90*795d594fSAndroid Build Coastguard Worker
91*795d594fSAndroid Build Coastguard Worker static JNINativeMethod gMethods_Critical[] = {
92*795d594fSAndroid Build Coastguard Worker // Don't use NATIVE_METHOD because the name is mangled differently.
93*795d594fSAndroid Build Coastguard Worker { "emptyJniStaticMethod0_Critical", "()V",
94*795d594fSAndroid Build Coastguard Worker reinterpret_cast<void*>(NAME_CRITICAL_JNI_METHOD(emptyJniStaticMethod0_1Critical)) },
95*795d594fSAndroid Build Coastguard Worker { "emptyJniStaticMethod6_Critical", "(IIIIII)V",
96*795d594fSAndroid Build Coastguard Worker reinterpret_cast<void*>(NAME_CRITICAL_JNI_METHOD(emptyJniStaticMethod6_1Critical)) }
97*795d594fSAndroid Build Coastguard Worker };
98*795d594fSAndroid Build Coastguard Worker
jniRegisterNativeMethods(JNIEnv * env,const char * className,const JNINativeMethod * methods,int numMethods)99*795d594fSAndroid Build Coastguard Worker void jniRegisterNativeMethods(JNIEnv* env,
100*795d594fSAndroid Build Coastguard Worker const char* className,
101*795d594fSAndroid Build Coastguard Worker const JNINativeMethod* methods,
102*795d594fSAndroid Build Coastguard Worker int numMethods) {
103*795d594fSAndroid Build Coastguard Worker jclass c = env->FindClass(className);
104*795d594fSAndroid Build Coastguard Worker if (c == nullptr) {
105*795d594fSAndroid Build Coastguard Worker char* tmp;
106*795d594fSAndroid Build Coastguard Worker const char* msg;
107*795d594fSAndroid Build Coastguard Worker if (asprintf(&tmp,
108*795d594fSAndroid Build Coastguard Worker "Native registration unable to find class '%s'; aborting...",
109*795d594fSAndroid Build Coastguard Worker className) == -1) {
110*795d594fSAndroid Build Coastguard Worker // Allocation failed, print default warning.
111*795d594fSAndroid Build Coastguard Worker msg = "Native registration unable to find class; aborting...";
112*795d594fSAndroid Build Coastguard Worker } else {
113*795d594fSAndroid Build Coastguard Worker msg = tmp;
114*795d594fSAndroid Build Coastguard Worker }
115*795d594fSAndroid Build Coastguard Worker env->FatalError(msg);
116*795d594fSAndroid Build Coastguard Worker }
117*795d594fSAndroid Build Coastguard Worker
118*795d594fSAndroid Build Coastguard Worker if (env->RegisterNatives(c, methods, numMethods) < 0) {
119*795d594fSAndroid Build Coastguard Worker char* tmp;
120*795d594fSAndroid Build Coastguard Worker const char* msg;
121*795d594fSAndroid Build Coastguard Worker if (asprintf(&tmp, "RegisterNatives failed for '%s'; aborting...", className) == -1) {
122*795d594fSAndroid Build Coastguard Worker // Allocation failed, print default warning.
123*795d594fSAndroid Build Coastguard Worker msg = "RegisterNatives failed; aborting...";
124*795d594fSAndroid Build Coastguard Worker } else {
125*795d594fSAndroid Build Coastguard Worker msg = tmp;
126*795d594fSAndroid Build Coastguard Worker }
127*795d594fSAndroid Build Coastguard Worker env->FatalError(msg);
128*795d594fSAndroid Build Coastguard Worker }
129*795d594fSAndroid Build Coastguard Worker }
130*795d594fSAndroid Build Coastguard Worker
register_micro_native_methods(JNIEnv * env)131*795d594fSAndroid Build Coastguard Worker void register_micro_native_methods(JNIEnv* env) {
132*795d594fSAndroid Build Coastguard Worker jniRegisterNativeMethods(env, CLASS_NAME, gMethods_NormalOnly, NELEM(gMethods_NormalOnly));
133*795d594fSAndroid Build Coastguard Worker jniRegisterNativeMethods(env, CLASS_NAME, gMethods, NELEM(gMethods));
134*795d594fSAndroid Build Coastguard Worker jniRegisterNativeMethods(env, CLASS_NAME, gMethods_Fast, NELEM(gMethods_Fast));
135*795d594fSAndroid Build Coastguard Worker
136*795d594fSAndroid Build Coastguard Worker if (env->FindClass("dalvik/annotation/optimization/CriticalNative") != nullptr) {
137*795d594fSAndroid Build Coastguard Worker // Only register them explicitly if the annotation is present.
138*795d594fSAndroid Build Coastguard Worker jniRegisterNativeMethods(env, CLASS_NAME, gMethods_Critical, NELEM(gMethods_Critical));
139*795d594fSAndroid Build Coastguard Worker } else {
140*795d594fSAndroid Build Coastguard Worker if (env->ExceptionCheck()) {
141*795d594fSAndroid Build Coastguard Worker // It will throw NoClassDefFoundError
142*795d594fSAndroid Build Coastguard Worker env->ExceptionClear();
143*795d594fSAndroid Build Coastguard Worker }
144*795d594fSAndroid Build Coastguard Worker }
145*795d594fSAndroid Build Coastguard Worker // else let them be registered implicitly.
146*795d594fSAndroid Build Coastguard Worker }
147