1d5f2ccc7ea09ae87ff704786daa6d20c10be21dbAndreas Gampe/*
2d5f2ccc7ea09ae87ff704786daa6d20c10be21dbAndreas Gampe * Copyright (C) 2013 The Android Open Source Project
3d5f2ccc7ea09ae87ff704786daa6d20c10be21dbAndreas Gampe *
4d5f2ccc7ea09ae87ff704786daa6d20c10be21dbAndreas Gampe * Licensed under the Apache License, Version 2.0 (the "License");
5d5f2ccc7ea09ae87ff704786daa6d20c10be21dbAndreas Gampe * you may not use this file except in compliance with the License.
6d5f2ccc7ea09ae87ff704786daa6d20c10be21dbAndreas Gampe * You may obtain a copy of the License at
7d5f2ccc7ea09ae87ff704786daa6d20c10be21dbAndreas Gampe *
8d5f2ccc7ea09ae87ff704786daa6d20c10be21dbAndreas Gampe *      http://www.apache.org/licenses/LICENSE-2.0
9d5f2ccc7ea09ae87ff704786daa6d20c10be21dbAndreas Gampe *
10d5f2ccc7ea09ae87ff704786daa6d20c10be21dbAndreas Gampe * Unless required by applicable law or agreed to in writing, software
11d5f2ccc7ea09ae87ff704786daa6d20c10be21dbAndreas Gampe * distributed under the License is distributed on an "AS IS" BASIS,
12d5f2ccc7ea09ae87ff704786daa6d20c10be21dbAndreas Gampe * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13d5f2ccc7ea09ae87ff704786daa6d20c10be21dbAndreas Gampe * See the License for the specific language governing permissions and
14d5f2ccc7ea09ae87ff704786daa6d20c10be21dbAndreas Gampe * limitations under the License.
15d5f2ccc7ea09ae87ff704786daa6d20c10be21dbAndreas Gampe */
16d5f2ccc7ea09ae87ff704786daa6d20c10be21dbAndreas Gampe
17d5f2ccc7ea09ae87ff704786daa6d20c10be21dbAndreas Gampe#include <stdio.h>
18d5f2ccc7ea09ae87ff704786daa6d20c10be21dbAndreas Gampe
19d5f2ccc7ea09ae87ff704786daa6d20c10be21dbAndreas Gampe#include <mutex>
20d5f2ccc7ea09ae87ff704786daa6d20c10be21dbAndreas Gampe#include <vector>
21d5f2ccc7ea09ae87ff704786daa6d20c10be21dbAndreas Gampe
22d5f2ccc7ea09ae87ff704786daa6d20c10be21dbAndreas Gampe#include "android-base/macros.h"
23d5f2ccc7ea09ae87ff704786daa6d20c10be21dbAndreas Gampe#include "android-base/stringprintf.h"
24d5f2ccc7ea09ae87ff704786daa6d20c10be21dbAndreas Gampe
25d5f2ccc7ea09ae87ff704786daa6d20c10be21dbAndreas Gampe#include "jni.h"
26d5f2ccc7ea09ae87ff704786daa6d20c10be21dbAndreas Gampe#include "jvmti.h"
27d5f2ccc7ea09ae87ff704786daa6d20c10be21dbAndreas Gampe
28d5f2ccc7ea09ae87ff704786daa6d20c10be21dbAndreas Gampe// Test infrastructure
29d5f2ccc7ea09ae87ff704786daa6d20c10be21dbAndreas Gampe#include "jni_helper.h"
30d5f2ccc7ea09ae87ff704786daa6d20c10be21dbAndreas Gampe#include "jvmti_helper.h"
31d5f2ccc7ea09ae87ff704786daa6d20c10be21dbAndreas Gampe#include "scoped_local_ref.h"
32d5f2ccc7ea09ae87ff704786daa6d20c10be21dbAndreas Gampe#include "scoped_utf_chars.h"
33d5f2ccc7ea09ae87ff704786daa6d20c10be21dbAndreas Gampe#include "test_env.h"
34d5f2ccc7ea09ae87ff704786daa6d20c10be21dbAndreas Gampe
35d5f2ccc7ea09ae87ff704786daa6d20c10be21dbAndreas Gampenamespace art {
36d5f2ccc7ea09ae87ff704786daa6d20c10be21dbAndreas Gampenamespace Test912ArtClasses {
37d5f2ccc7ea09ae87ff704786daa6d20c10be21dbAndreas Gampe
38d5f2ccc7ea09ae87ff704786daa6d20c10be21dbAndreas Gampestatic void EnableEvents(JNIEnv* env,
39d5f2ccc7ea09ae87ff704786daa6d20c10be21dbAndreas Gampe                         jboolean enable,
40d5f2ccc7ea09ae87ff704786daa6d20c10be21dbAndreas Gampe                         decltype(jvmtiEventCallbacks().ClassLoad) class_load,
41d5f2ccc7ea09ae87ff704786daa6d20c10be21dbAndreas Gampe                         decltype(jvmtiEventCallbacks().ClassPrepare) class_prepare) {
42d5f2ccc7ea09ae87ff704786daa6d20c10be21dbAndreas Gampe  if (enable == JNI_FALSE) {
43d5f2ccc7ea09ae87ff704786daa6d20c10be21dbAndreas Gampe    jvmtiError ret = jvmti_env->SetEventNotificationMode(JVMTI_DISABLE,
44d5f2ccc7ea09ae87ff704786daa6d20c10be21dbAndreas Gampe                                                         JVMTI_EVENT_CLASS_LOAD,
45d5f2ccc7ea09ae87ff704786daa6d20c10be21dbAndreas Gampe                                                         nullptr);
46d5f2ccc7ea09ae87ff704786daa6d20c10be21dbAndreas Gampe    if (JvmtiErrorToException(env, jvmti_env, ret)) {
47d5f2ccc7ea09ae87ff704786daa6d20c10be21dbAndreas Gampe      return;
48d5f2ccc7ea09ae87ff704786daa6d20c10be21dbAndreas Gampe    }
49d5f2ccc7ea09ae87ff704786daa6d20c10be21dbAndreas Gampe    ret = jvmti_env->SetEventNotificationMode(JVMTI_DISABLE,
50d5f2ccc7ea09ae87ff704786daa6d20c10be21dbAndreas Gampe                                              JVMTI_EVENT_CLASS_PREPARE,
51d5f2ccc7ea09ae87ff704786daa6d20c10be21dbAndreas Gampe                                              nullptr);
52d5f2ccc7ea09ae87ff704786daa6d20c10be21dbAndreas Gampe    JvmtiErrorToException(env, jvmti_env, ret);
53d5f2ccc7ea09ae87ff704786daa6d20c10be21dbAndreas Gampe    return;
54d5f2ccc7ea09ae87ff704786daa6d20c10be21dbAndreas Gampe  }
55d5f2ccc7ea09ae87ff704786daa6d20c10be21dbAndreas Gampe
56d5f2ccc7ea09ae87ff704786daa6d20c10be21dbAndreas Gampe  jvmtiEventCallbacks callbacks;
57d5f2ccc7ea09ae87ff704786daa6d20c10be21dbAndreas Gampe  memset(&callbacks, 0, sizeof(jvmtiEventCallbacks));
58d5f2ccc7ea09ae87ff704786daa6d20c10be21dbAndreas Gampe  callbacks.ClassLoad = class_load;
59d5f2ccc7ea09ae87ff704786daa6d20c10be21dbAndreas Gampe  callbacks.ClassPrepare = class_prepare;
60d5f2ccc7ea09ae87ff704786daa6d20c10be21dbAndreas Gampe  jvmtiError ret = jvmti_env->SetEventCallbacks(&callbacks, sizeof(callbacks));
61d5f2ccc7ea09ae87ff704786daa6d20c10be21dbAndreas Gampe  if (JvmtiErrorToException(env, jvmti_env, ret)) {
62d5f2ccc7ea09ae87ff704786daa6d20c10be21dbAndreas Gampe    return;
63d5f2ccc7ea09ae87ff704786daa6d20c10be21dbAndreas Gampe  }
64d5f2ccc7ea09ae87ff704786daa6d20c10be21dbAndreas Gampe
65d5f2ccc7ea09ae87ff704786daa6d20c10be21dbAndreas Gampe  ret = jvmti_env->SetEventNotificationMode(JVMTI_ENABLE,
66d5f2ccc7ea09ae87ff704786daa6d20c10be21dbAndreas Gampe                                            JVMTI_EVENT_CLASS_LOAD,
67d5f2ccc7ea09ae87ff704786daa6d20c10be21dbAndreas Gampe                                            nullptr);
68d5f2ccc7ea09ae87ff704786daa6d20c10be21dbAndreas Gampe  if (JvmtiErrorToException(env, jvmti_env, ret)) {
69d5f2ccc7ea09ae87ff704786daa6d20c10be21dbAndreas Gampe    return;
70d5f2ccc7ea09ae87ff704786daa6d20c10be21dbAndreas Gampe  }
71d5f2ccc7ea09ae87ff704786daa6d20c10be21dbAndreas Gampe  ret = jvmti_env->SetEventNotificationMode(JVMTI_ENABLE,
72d5f2ccc7ea09ae87ff704786daa6d20c10be21dbAndreas Gampe                                            JVMTI_EVENT_CLASS_PREPARE,
73d5f2ccc7ea09ae87ff704786daa6d20c10be21dbAndreas Gampe                                            nullptr);
74d5f2ccc7ea09ae87ff704786daa6d20c10be21dbAndreas Gampe  JvmtiErrorToException(env, jvmti_env, ret);
75d5f2ccc7ea09ae87ff704786daa6d20c10be21dbAndreas Gampe}
76d5f2ccc7ea09ae87ff704786daa6d20c10be21dbAndreas Gampe
77d5f2ccc7ea09ae87ff704786daa6d20c10be21dbAndreas Gampestruct ClassLoadSeen {
78d5f2ccc7ea09ae87ff704786daa6d20c10be21dbAndreas Gampe  static void JNICALL ClassLoadSeenCallback(jvmtiEnv* jenv ATTRIBUTE_UNUSED,
79d5f2ccc7ea09ae87ff704786daa6d20c10be21dbAndreas Gampe                                            JNIEnv* jni_env ATTRIBUTE_UNUSED,
80d5f2ccc7ea09ae87ff704786daa6d20c10be21dbAndreas Gampe                                            jthread thread ATTRIBUTE_UNUSED,
81d5f2ccc7ea09ae87ff704786daa6d20c10be21dbAndreas Gampe                                            jclass klass ATTRIBUTE_UNUSED) {
82d5f2ccc7ea09ae87ff704786daa6d20c10be21dbAndreas Gampe    saw_event = true;
83d5f2ccc7ea09ae87ff704786daa6d20c10be21dbAndreas Gampe  }
84d5f2ccc7ea09ae87ff704786daa6d20c10be21dbAndreas Gampe
85d5f2ccc7ea09ae87ff704786daa6d20c10be21dbAndreas Gampe  static bool saw_event;
86d5f2ccc7ea09ae87ff704786daa6d20c10be21dbAndreas Gampe};
87d5f2ccc7ea09ae87ff704786daa6d20c10be21dbAndreas Gampebool ClassLoadSeen::saw_event = false;
88d5f2ccc7ea09ae87ff704786daa6d20c10be21dbAndreas Gampe
89d5f2ccc7ea09ae87ff704786daa6d20c10be21dbAndreas Gampeextern "C" JNIEXPORT void JNICALL Java_art_Test912Art_enableClassLoadSeenEvents(
90d5f2ccc7ea09ae87ff704786daa6d20c10be21dbAndreas Gampe    JNIEnv* env, jclass Main_klass ATTRIBUTE_UNUSED, jboolean b) {
91d5f2ccc7ea09ae87ff704786daa6d20c10be21dbAndreas Gampe  EnableEvents(env, b, ClassLoadSeen::ClassLoadSeenCallback, nullptr);
92d5f2ccc7ea09ae87ff704786daa6d20c10be21dbAndreas Gampe}
93d5f2ccc7ea09ae87ff704786daa6d20c10be21dbAndreas Gampe
94d5f2ccc7ea09ae87ff704786daa6d20c10be21dbAndreas Gampeextern "C" JNIEXPORT jboolean JNICALL Java_art_Test912Art_hadLoadEvent(
95d5f2ccc7ea09ae87ff704786daa6d20c10be21dbAndreas Gampe    JNIEnv* env ATTRIBUTE_UNUSED, jclass Main_klass ATTRIBUTE_UNUSED) {
96d5f2ccc7ea09ae87ff704786daa6d20c10be21dbAndreas Gampe  return ClassLoadSeen::saw_event ? JNI_TRUE : JNI_FALSE;
97d5f2ccc7ea09ae87ff704786daa6d20c10be21dbAndreas Gampe}
98d5f2ccc7ea09ae87ff704786daa6d20c10be21dbAndreas Gampe
99d5f2ccc7ea09ae87ff704786daa6d20c10be21dbAndreas Gampeextern "C" JNIEXPORT jboolean JNICALL Java_art_Test912Art_isLoadedClass(
100d5f2ccc7ea09ae87ff704786daa6d20c10be21dbAndreas Gampe    JNIEnv* env, jclass Main_klass ATTRIBUTE_UNUSED, jstring class_name) {
101d5f2ccc7ea09ae87ff704786daa6d20c10be21dbAndreas Gampe  ScopedUtfChars name(env, class_name);
102d5f2ccc7ea09ae87ff704786daa6d20c10be21dbAndreas Gampe
103d5f2ccc7ea09ae87ff704786daa6d20c10be21dbAndreas Gampe  jint class_count;
104d5f2ccc7ea09ae87ff704786daa6d20c10be21dbAndreas Gampe  jclass* classes;
105d5f2ccc7ea09ae87ff704786daa6d20c10be21dbAndreas Gampe  jvmtiError res = jvmti_env->GetLoadedClasses(&class_count, &classes);
106d5f2ccc7ea09ae87ff704786daa6d20c10be21dbAndreas Gampe  if (JvmtiErrorToException(env, jvmti_env, res)) {
107d5f2ccc7ea09ae87ff704786daa6d20c10be21dbAndreas Gampe    return JNI_FALSE;
108d5f2ccc7ea09ae87ff704786daa6d20c10be21dbAndreas Gampe  }
109d5f2ccc7ea09ae87ff704786daa6d20c10be21dbAndreas Gampe
110d5f2ccc7ea09ae87ff704786daa6d20c10be21dbAndreas Gampe  bool found = false;
111d5f2ccc7ea09ae87ff704786daa6d20c10be21dbAndreas Gampe  for (jint i = 0; !found && i < class_count; ++i) {
112d5f2ccc7ea09ae87ff704786daa6d20c10be21dbAndreas Gampe    char* sig;
113d5f2ccc7ea09ae87ff704786daa6d20c10be21dbAndreas Gampe    jvmtiError res2 = jvmti_env->GetClassSignature(classes[i], &sig, nullptr);
114d5f2ccc7ea09ae87ff704786daa6d20c10be21dbAndreas Gampe    if (JvmtiErrorToException(env, jvmti_env, res2)) {
115d5f2ccc7ea09ae87ff704786daa6d20c10be21dbAndreas Gampe      return JNI_FALSE;
116d5f2ccc7ea09ae87ff704786daa6d20c10be21dbAndreas Gampe    }
117d5f2ccc7ea09ae87ff704786daa6d20c10be21dbAndreas Gampe
118d5f2ccc7ea09ae87ff704786daa6d20c10be21dbAndreas Gampe    found = strcmp(name.c_str(), sig) == 0;
119d5f2ccc7ea09ae87ff704786daa6d20c10be21dbAndreas Gampe
120d5f2ccc7ea09ae87ff704786daa6d20c10be21dbAndreas Gampe    CheckJvmtiError(jvmti_env, jvmti_env->Deallocate(reinterpret_cast<unsigned char*>(sig)));
121d5f2ccc7ea09ae87ff704786daa6d20c10be21dbAndreas Gampe  }
122d5f2ccc7ea09ae87ff704786daa6d20c10be21dbAndreas Gampe
123d5f2ccc7ea09ae87ff704786daa6d20c10be21dbAndreas Gampe  CheckJvmtiError(jvmti_env, jvmti_env->Deallocate(reinterpret_cast<unsigned char*>(classes)));
124d5f2ccc7ea09ae87ff704786daa6d20c10be21dbAndreas Gampe
125d5f2ccc7ea09ae87ff704786daa6d20c10be21dbAndreas Gampe  return found;
126d5f2ccc7ea09ae87ff704786daa6d20c10be21dbAndreas Gampe}
127d5f2ccc7ea09ae87ff704786daa6d20c10be21dbAndreas Gampe
128d5f2ccc7ea09ae87ff704786daa6d20c10be21dbAndreas Gampe// We use the implementations from runtime_state.cc.
129d5f2ccc7ea09ae87ff704786daa6d20c10be21dbAndreas Gampe
130d5f2ccc7ea09ae87ff704786daa6d20c10be21dbAndreas Gampeextern "C" JNIEXPORT void JNICALL Java_Main_ensureJitCompiled(JNIEnv* env,
131d5f2ccc7ea09ae87ff704786daa6d20c10be21dbAndreas Gampe                                                             jclass,
132d5f2ccc7ea09ae87ff704786daa6d20c10be21dbAndreas Gampe                                                             jclass cls,
133d5f2ccc7ea09ae87ff704786daa6d20c10be21dbAndreas Gampe                                                             jstring method_name);
134d5f2ccc7ea09ae87ff704786daa6d20c10be21dbAndreas Gampeextern "C" JNIEXPORT jboolean JNICALL Java_Main_hasJit(JNIEnv*, jclass);
135d5f2ccc7ea09ae87ff704786daa6d20c10be21dbAndreas Gampe
136d5f2ccc7ea09ae87ff704786daa6d20c10be21dbAndreas Gampeextern "C" JNIEXPORT void JNICALL Java_art_Test912Art_ensureJitCompiled(
137d5f2ccc7ea09ae87ff704786daa6d20c10be21dbAndreas Gampe    JNIEnv* env, jclass klass, jclass test_class, jstring name) {
138d5f2ccc7ea09ae87ff704786daa6d20c10be21dbAndreas Gampe  Java_Main_ensureJitCompiled(env, klass, test_class, name);
139d5f2ccc7ea09ae87ff704786daa6d20c10be21dbAndreas Gampe}
140d5f2ccc7ea09ae87ff704786daa6d20c10be21dbAndreas Gampe
141d5f2ccc7ea09ae87ff704786daa6d20c10be21dbAndreas Gampeextern "C" JNIEXPORT jboolean JNICALL Java_art_Test912Art_hasJit(JNIEnv* env, jclass klass) {
142d5f2ccc7ea09ae87ff704786daa6d20c10be21dbAndreas Gampe  return Java_Main_hasJit(env, klass);
143d5f2ccc7ea09ae87ff704786daa6d20c10be21dbAndreas Gampe}
144d5f2ccc7ea09ae87ff704786daa6d20c10be21dbAndreas Gampe
145d5f2ccc7ea09ae87ff704786daa6d20c10be21dbAndreas Gampe}  // namespace Test912ArtClasses
146d5f2ccc7ea09ae87ff704786daa6d20c10be21dbAndreas Gampe}  // namespace art
147