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