xref: /aosp_15_r20/art/test/912-classes/classes_art.cc (revision 795d594fd825385562da6b089ea9b2033f3abf5a)
1*795d594fSAndroid Build Coastguard Worker /*
2*795d594fSAndroid Build Coastguard Worker  * Copyright (C) 2013 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 <stdio.h>
18*795d594fSAndroid Build Coastguard Worker 
19*795d594fSAndroid Build Coastguard Worker #include <mutex>
20*795d594fSAndroid Build Coastguard Worker #include <vector>
21*795d594fSAndroid Build Coastguard Worker 
22*795d594fSAndroid Build Coastguard Worker #include "android-base/macros.h"
23*795d594fSAndroid Build Coastguard Worker #include "android-base/stringprintf.h"
24*795d594fSAndroid Build Coastguard Worker 
25*795d594fSAndroid Build Coastguard Worker #include "jni.h"
26*795d594fSAndroid Build Coastguard Worker #include "jvmti.h"
27*795d594fSAndroid Build Coastguard Worker 
28*795d594fSAndroid Build Coastguard Worker // Test infrastructure
29*795d594fSAndroid Build Coastguard Worker #include "jni_helper.h"
30*795d594fSAndroid Build Coastguard Worker #include "jvmti_helper.h"
31*795d594fSAndroid Build Coastguard Worker #include "scoped_local_ref.h"
32*795d594fSAndroid Build Coastguard Worker #include "scoped_utf_chars.h"
33*795d594fSAndroid Build Coastguard Worker #include "test_env.h"
34*795d594fSAndroid Build Coastguard Worker 
35*795d594fSAndroid Build Coastguard Worker namespace art {
36*795d594fSAndroid Build Coastguard Worker namespace Test912ArtClasses {
37*795d594fSAndroid Build Coastguard Worker 
38*795d594fSAndroid Build Coastguard Worker static void EnableEvents(JNIEnv* env,
39*795d594fSAndroid Build Coastguard Worker                          jboolean enable,
40*795d594fSAndroid Build Coastguard Worker                          decltype(jvmtiEventCallbacks().ClassLoad) class_load,
41*795d594fSAndroid Build Coastguard Worker                          decltype(jvmtiEventCallbacks().ClassPrepare) class_prepare) {
42*795d594fSAndroid Build Coastguard Worker   if (enable == JNI_FALSE) {
43*795d594fSAndroid Build Coastguard Worker     jvmtiError ret = jvmti_env->SetEventNotificationMode(JVMTI_DISABLE,
44*795d594fSAndroid Build Coastguard Worker                                                          JVMTI_EVENT_CLASS_LOAD,
45*795d594fSAndroid Build Coastguard Worker                                                          nullptr);
46*795d594fSAndroid Build Coastguard Worker     if (JvmtiErrorToException(env, jvmti_env, ret)) {
47*795d594fSAndroid Build Coastguard Worker       return;
48*795d594fSAndroid Build Coastguard Worker     }
49*795d594fSAndroid Build Coastguard Worker     ret = jvmti_env->SetEventNotificationMode(JVMTI_DISABLE,
50*795d594fSAndroid Build Coastguard Worker                                               JVMTI_EVENT_CLASS_PREPARE,
51*795d594fSAndroid Build Coastguard Worker                                               nullptr);
52*795d594fSAndroid Build Coastguard Worker     JvmtiErrorToException(env, jvmti_env, ret);
53*795d594fSAndroid Build Coastguard Worker     return;
54*795d594fSAndroid Build Coastguard Worker   }
55*795d594fSAndroid Build Coastguard Worker 
56*795d594fSAndroid Build Coastguard Worker   jvmtiEventCallbacks callbacks;
57*795d594fSAndroid Build Coastguard Worker   memset(&callbacks, 0, sizeof(jvmtiEventCallbacks));
58*795d594fSAndroid Build Coastguard Worker   callbacks.ClassLoad = class_load;
59*795d594fSAndroid Build Coastguard Worker   callbacks.ClassPrepare = class_prepare;
60*795d594fSAndroid Build Coastguard Worker   jvmtiError ret = jvmti_env->SetEventCallbacks(&callbacks, sizeof(callbacks));
61*795d594fSAndroid Build Coastguard Worker   if (JvmtiErrorToException(env, jvmti_env, ret)) {
62*795d594fSAndroid Build Coastguard Worker     return;
63*795d594fSAndroid Build Coastguard Worker   }
64*795d594fSAndroid Build Coastguard Worker 
65*795d594fSAndroid Build Coastguard Worker   ret = jvmti_env->SetEventNotificationMode(JVMTI_ENABLE,
66*795d594fSAndroid Build Coastguard Worker                                             JVMTI_EVENT_CLASS_LOAD,
67*795d594fSAndroid Build Coastguard Worker                                             nullptr);
68*795d594fSAndroid Build Coastguard Worker   if (JvmtiErrorToException(env, jvmti_env, ret)) {
69*795d594fSAndroid Build Coastguard Worker     return;
70*795d594fSAndroid Build Coastguard Worker   }
71*795d594fSAndroid Build Coastguard Worker   ret = jvmti_env->SetEventNotificationMode(JVMTI_ENABLE,
72*795d594fSAndroid Build Coastguard Worker                                             JVMTI_EVENT_CLASS_PREPARE,
73*795d594fSAndroid Build Coastguard Worker                                             nullptr);
74*795d594fSAndroid Build Coastguard Worker   JvmtiErrorToException(env, jvmti_env, ret);
75*795d594fSAndroid Build Coastguard Worker }
76*795d594fSAndroid Build Coastguard Worker 
77*795d594fSAndroid Build Coastguard Worker struct ClassLoadSeen {
ClassLoadSeenCallbackart::Test912ArtClasses::ClassLoadSeen78*795d594fSAndroid Build Coastguard Worker   static void JNICALL ClassLoadSeenCallback([[maybe_unused]] jvmtiEnv* jenv,
79*795d594fSAndroid Build Coastguard Worker                                             [[maybe_unused]] JNIEnv* jni_env,
80*795d594fSAndroid Build Coastguard Worker                                             [[maybe_unused]] jthread thread,
81*795d594fSAndroid Build Coastguard Worker                                             [[maybe_unused]] jclass klass) {
82*795d594fSAndroid Build Coastguard Worker     saw_event = true;
83*795d594fSAndroid Build Coastguard Worker   }
84*795d594fSAndroid Build Coastguard Worker 
85*795d594fSAndroid Build Coastguard Worker   static bool saw_event;
86*795d594fSAndroid Build Coastguard Worker };
87*795d594fSAndroid Build Coastguard Worker bool ClassLoadSeen::saw_event = false;
88*795d594fSAndroid Build Coastguard Worker 
Java_art_Test912Art_enableClassLoadSeenEvents(JNIEnv * env,jclass Main_klass,jboolean b)89*795d594fSAndroid Build Coastguard Worker extern "C" JNIEXPORT void JNICALL Java_art_Test912Art_enableClassLoadSeenEvents(
90*795d594fSAndroid Build Coastguard Worker     JNIEnv* env, [[maybe_unused]] jclass Main_klass, jboolean b) {
91*795d594fSAndroid Build Coastguard Worker   EnableEvents(env, b, ClassLoadSeen::ClassLoadSeenCallback, nullptr);
92*795d594fSAndroid Build Coastguard Worker }
93*795d594fSAndroid Build Coastguard Worker 
Java_art_Test912Art_hadLoadEvent(JNIEnv * env,jclass Main_klass)94*795d594fSAndroid Build Coastguard Worker extern "C" JNIEXPORT jboolean JNICALL Java_art_Test912Art_hadLoadEvent(
95*795d594fSAndroid Build Coastguard Worker     [[maybe_unused]] JNIEnv* env, [[maybe_unused]] jclass Main_klass) {
96*795d594fSAndroid Build Coastguard Worker   return ClassLoadSeen::saw_event ? JNI_TRUE : JNI_FALSE;
97*795d594fSAndroid Build Coastguard Worker }
98*795d594fSAndroid Build Coastguard Worker 
Java_art_Test912Art_isLoadedClass(JNIEnv * env,jclass Main_klass,jstring class_name)99*795d594fSAndroid Build Coastguard Worker extern "C" JNIEXPORT jboolean JNICALL Java_art_Test912Art_isLoadedClass(
100*795d594fSAndroid Build Coastguard Worker     JNIEnv* env, [[maybe_unused]] jclass Main_klass, jstring class_name) {
101*795d594fSAndroid Build Coastguard Worker   ScopedUtfChars name(env, class_name);
102*795d594fSAndroid Build Coastguard Worker 
103*795d594fSAndroid Build Coastguard Worker   jint class_count;
104*795d594fSAndroid Build Coastguard Worker   jclass* classes;
105*795d594fSAndroid Build Coastguard Worker   jvmtiError res = jvmti_env->GetLoadedClasses(&class_count, &classes);
106*795d594fSAndroid Build Coastguard Worker   if (JvmtiErrorToException(env, jvmti_env, res)) {
107*795d594fSAndroid Build Coastguard Worker     return JNI_FALSE;
108*795d594fSAndroid Build Coastguard Worker   }
109*795d594fSAndroid Build Coastguard Worker 
110*795d594fSAndroid Build Coastguard Worker   bool found = false;
111*795d594fSAndroid Build Coastguard Worker   for (jint i = 0; !found && i < class_count; ++i) {
112*795d594fSAndroid Build Coastguard Worker     char* sig;
113*795d594fSAndroid Build Coastguard Worker     jvmtiError res2 = jvmti_env->GetClassSignature(classes[i], &sig, nullptr);
114*795d594fSAndroid Build Coastguard Worker     if (JvmtiErrorToException(env, jvmti_env, res2)) {
115*795d594fSAndroid Build Coastguard Worker       return JNI_FALSE;
116*795d594fSAndroid Build Coastguard Worker     }
117*795d594fSAndroid Build Coastguard Worker 
118*795d594fSAndroid Build Coastguard Worker     found = strcmp(name.c_str(), sig) == 0;
119*795d594fSAndroid Build Coastguard Worker 
120*795d594fSAndroid Build Coastguard Worker     CheckJvmtiError(jvmti_env, jvmti_env->Deallocate(reinterpret_cast<unsigned char*>(sig)));
121*795d594fSAndroid Build Coastguard Worker   }
122*795d594fSAndroid Build Coastguard Worker 
123*795d594fSAndroid Build Coastguard Worker   CheckJvmtiError(jvmti_env, jvmti_env->Deallocate(reinterpret_cast<unsigned char*>(classes)));
124*795d594fSAndroid Build Coastguard Worker 
125*795d594fSAndroid Build Coastguard Worker   return found;
126*795d594fSAndroid Build Coastguard Worker }
127*795d594fSAndroid Build Coastguard Worker 
128*795d594fSAndroid Build Coastguard Worker // We use the implementations from runtime_state.cc.
129*795d594fSAndroid Build Coastguard Worker 
130*795d594fSAndroid Build Coastguard Worker extern "C" JNIEXPORT void JNICALL Java_Main_ensureJitCompiled(JNIEnv* env,
131*795d594fSAndroid Build Coastguard Worker                                                              jclass,
132*795d594fSAndroid Build Coastguard Worker                                                              jclass cls,
133*795d594fSAndroid Build Coastguard Worker                                                              jstring method_name);
134*795d594fSAndroid Build Coastguard Worker extern "C" JNIEXPORT jboolean JNICALL Java_Main_hasJit(JNIEnv*, jclass);
135*795d594fSAndroid Build Coastguard Worker 
Java_art_Test912Art_ensureJitCompiled(JNIEnv * env,jclass klass,jclass test_class,jstring name)136*795d594fSAndroid Build Coastguard Worker extern "C" JNIEXPORT void JNICALL Java_art_Test912Art_ensureJitCompiled(
137*795d594fSAndroid Build Coastguard Worker     JNIEnv* env, jclass klass, jclass test_class, jstring name) {
138*795d594fSAndroid Build Coastguard Worker   Java_Main_ensureJitCompiled(env, klass, test_class, name);
139*795d594fSAndroid Build Coastguard Worker }
140*795d594fSAndroid Build Coastguard Worker 
Java_art_Test912Art_hasJit(JNIEnv * env,jclass klass)141*795d594fSAndroid Build Coastguard Worker extern "C" JNIEXPORT jboolean JNICALL Java_art_Test912Art_hasJit(JNIEnv* env, jclass klass) {
142*795d594fSAndroid Build Coastguard Worker   return Java_Main_hasJit(env, klass);
143*795d594fSAndroid Build Coastguard Worker }
144*795d594fSAndroid Build Coastguard Worker 
145*795d594fSAndroid Build Coastguard Worker }  // namespace Test912ArtClasses
146*795d594fSAndroid Build Coastguard Worker }  // namespace art
147