Home | History | Annotate | Download | only in ti-agent
      1 /*
      2  * Copyright (C) 2017 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 "common_helper.h"
     18 
     19 #include "jni.h"
     20 #include "jvmti.h"
     21 
     22 #include "jvmti_helper.h"
     23 #include "scoped_local_ref.h"
     24 #include "test_env.h"
     25 
     26 namespace art {
     27 namespace common_locals {
     28 
     29 static void DeallocateContents(jvmtiLocalVariableEntry* vars, jint nvars) {
     30   for (jint i = 0; i < nvars; i++) {
     31     jvmti_env->Deallocate(reinterpret_cast<unsigned char*>(vars[i].name));
     32     jvmti_env->Deallocate(reinterpret_cast<unsigned char*>(vars[i].signature));
     33     jvmti_env->Deallocate(reinterpret_cast<unsigned char*>(vars[i].generic_signature));
     34   }
     35 }
     36 
     37 extern "C" JNIEXPORT void Java_art_Locals_EnableLocalVariableAccess(JNIEnv* env, jclass) {
     38   jvmtiCapabilities caps;
     39   if (JvmtiErrorToException(env, jvmti_env, jvmti_env->GetCapabilities(&caps))) {
     40     return;
     41   }
     42   caps.can_access_local_variables = 1;
     43   JvmtiErrorToException(env, jvmti_env, jvmti_env->AddCapabilities(&caps));
     44 }
     45 
     46 extern "C" JNIEXPORT void Java_art_Locals_SetLocalVariableObject(JNIEnv* env,
     47                                                                  jclass,
     48                                                                  jthread t,
     49                                                                  jint depth,
     50                                                                  jint slot,
     51                                                                  jobject val) {
     52   JvmtiErrorToException(env, jvmti_env, jvmti_env->SetLocalObject(t, depth, slot, val));
     53 }
     54 
     55 extern "C" JNIEXPORT void Java_art_Locals_SetLocalVariableDouble(JNIEnv* env,
     56                                                                  jclass,
     57                                                                  jthread t,
     58                                                                  jint depth,
     59                                                                  jint slot,
     60                                                                  jdouble val) {
     61   JvmtiErrorToException(env, jvmti_env, jvmti_env->SetLocalDouble(t, depth, slot, val));
     62 }
     63 
     64 extern "C" JNIEXPORT void Java_art_Locals_SetLocalVariableFloat(JNIEnv* env,
     65                                                                 jclass,
     66                                                                 jthread t,
     67                                                                 jint depth,
     68                                                                 jint slot,
     69                                                                 jfloat val) {
     70   JvmtiErrorToException(env, jvmti_env, jvmti_env->SetLocalFloat(t, depth, slot, val));
     71 }
     72 
     73 extern "C" JNIEXPORT void Java_art_Locals_SetLocalVariableLong(JNIEnv* env,
     74                                                                jclass,
     75                                                                jthread t,
     76                                                                jint depth,
     77                                                                jint slot,
     78                                                                jlong val) {
     79   JvmtiErrorToException(env, jvmti_env, jvmti_env->SetLocalLong(t, depth, slot, val));
     80 }
     81 
     82 extern "C" JNIEXPORT void Java_art_Locals_SetLocalVariableInt(JNIEnv* env,
     83                                                               jclass,
     84                                                               jthread t,
     85                                                               jint depth,
     86                                                               jint slot,
     87                                                               jint val) {
     88   JvmtiErrorToException(env, jvmti_env, jvmti_env->SetLocalInt(t, depth, slot, val));
     89 }
     90 
     91 extern "C" JNIEXPORT jdouble Java_art_Locals_GetLocalVariableDouble(JNIEnv* env,
     92                                                                     jclass,
     93                                                                     jthread t,
     94                                                                     jint depth,
     95                                                                     jint slot) {
     96   jdouble ret = 0;
     97   JvmtiErrorToException(env, jvmti_env, jvmti_env->GetLocalDouble(t, depth, slot, &ret));
     98   return ret;
     99 }
    100 
    101 extern "C" JNIEXPORT jfloat Java_art_Locals_GetLocalVariableFloat(JNIEnv* env,
    102                                                                   jclass,
    103                                                                   jthread t,
    104                                                                   jint depth,
    105                                                                   jint slot) {
    106   jfloat ret = 0;
    107   JvmtiErrorToException(env, jvmti_env, jvmti_env->GetLocalFloat(t, depth, slot, &ret));
    108   return ret;
    109 }
    110 
    111 extern "C" JNIEXPORT jlong Java_art_Locals_GetLocalVariableLong(JNIEnv* env,
    112                                                                 jclass,
    113                                                                 jthread t,
    114                                                                 jint depth,
    115                                                                 jint slot) {
    116   jlong ret = 0;
    117   JvmtiErrorToException(env, jvmti_env, jvmti_env->GetLocalLong(t, depth, slot, &ret));
    118   return ret;
    119 }
    120 
    121 extern "C" JNIEXPORT jint Java_art_Locals_GetLocalVariableInt(JNIEnv* env,
    122                                                               jclass,
    123                                                               jthread t,
    124                                                               jint depth,
    125                                                               jint slot) {
    126   jint ret = 0;
    127   JvmtiErrorToException(env, jvmti_env, jvmti_env->GetLocalInt(t, depth, slot, &ret));
    128   return ret;
    129 }
    130 
    131 extern "C" JNIEXPORT jobject Java_art_Locals_GetLocalInstance(JNIEnv* env,
    132                                                               jclass,
    133                                                               jthread t,
    134                                                               jint depth) {
    135   jobject ret = nullptr;
    136   JvmtiErrorToException(env, jvmti_env, jvmti_env->GetLocalInstance(t, depth, &ret));
    137   return ret;
    138 }
    139 
    140 extern "C" JNIEXPORT jobject Java_art_Locals_GetLocalVariableObject(JNIEnv* env,
    141                                                                     jclass,
    142                                                                     jthread t,
    143                                                                     jint depth,
    144                                                                     jint slot) {
    145   jobject ret = nullptr;
    146   JvmtiErrorToException(env, jvmti_env, jvmti_env->GetLocalObject(t, depth, slot, &ret));
    147   return ret;
    148 }
    149 
    150 extern "C" JNIEXPORT jobjectArray Java_art_Locals_GetLocalVariableTable(JNIEnv* env,
    151                                                                         jclass,
    152                                                                         jobject m) {
    153   jmethodID method = env->FromReflectedMethod(m);
    154   if (env->ExceptionCheck()) {
    155     return nullptr;
    156   }
    157   ScopedLocalRef<jclass> klass(env, env->FindClass("art/Locals$VariableDescription"));
    158   if (env->ExceptionCheck()) {
    159     return nullptr;
    160   }
    161   jint nvars;
    162   jvmtiLocalVariableEntry* vars = nullptr;
    163   if (JvmtiErrorToException(env, jvmti_env,
    164                             jvmti_env->GetLocalVariableTable(method, &nvars, &vars))) {
    165     return nullptr;
    166   }
    167   jobjectArray vars_array = env->NewObjectArray(nvars, klass.get(), nullptr);
    168   if (env->ExceptionCheck()) {
    169     DeallocateContents(vars, nvars);
    170     jvmti_env->Deallocate(reinterpret_cast<unsigned char*>(vars));
    171     return nullptr;
    172   }
    173 
    174   jmethodID constructor = env->GetMethodID(
    175       klass.get(), "<init>", "(JILjava/lang/String;Ljava/lang/String;Ljava/lang/String;I)V");
    176   if (env->ExceptionCheck()) {
    177     return nullptr;
    178   }
    179   for (jint i = 0; i < nvars; i++) {
    180     ScopedLocalRef<jstring> name_string(env, env->NewStringUTF(vars[i].name));
    181     ScopedLocalRef<jstring> sig_string(env, env->NewStringUTF(vars[i].signature));
    182     ScopedLocalRef<jstring> generic_sig_string(env, env->NewStringUTF(vars[i].generic_signature));
    183     jobject var_obj = env->NewObject(klass.get(),
    184                                      constructor,
    185                                      vars[i].start_location,
    186                                      vars[i].length,
    187                                      name_string.get(),
    188                                      sig_string.get(),
    189                                      generic_sig_string.get(),
    190                                      vars[i].slot);
    191     if (env->ExceptionCheck()) {
    192       DeallocateContents(vars, nvars);
    193       jvmti_env->Deallocate(reinterpret_cast<unsigned char*>(vars));
    194       return nullptr;
    195     }
    196     env->SetObjectArrayElement(vars_array, i, var_obj);
    197     if (env->ExceptionCheck()) {
    198       DeallocateContents(vars, nvars);
    199       jvmti_env->Deallocate(reinterpret_cast<unsigned char*>(vars));
    200       return nullptr;
    201     }
    202   }
    203 
    204   DeallocateContents(vars, nvars);
    205   jvmti_env->Deallocate(reinterpret_cast<unsigned char*>(vars));
    206   return vars_array;
    207 }
    208 
    209 }  // namespace common_locals
    210 }  // namespace art
    211