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