blob: 01b306dea5d7ac784d323e5c038984b13a3a9843 [file] [log] [blame]
Alex Lightc7588752018-02-20 11:15:54 -08001/*
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 "jvmti.h"
18
19// Test infrastructure
20#include "jvmti_helper.h"
21#include "scoped_local_ref.h"
22#include "test_env.h"
23
24namespace art {
25namespace Test1946Descriptors {
26
27typedef jvmtiError (*GetDescriptorList)(jvmtiEnv* env, jobject loader, jint* cnt, char*** descs);
28
29struct DescriptorData {
30 GetDescriptorList get_descriptor_list;
31};
32
33template <typename T>
34static void Dealloc(T* t) {
35 jvmti_env->Deallocate(reinterpret_cast<unsigned char*>(t));
36}
37
38template <typename T, typename ...Rest>
39static void Dealloc(T* t, Rest... rs) {
40 Dealloc(t);
41 Dealloc(rs...);
42}
43
44static void Cleanup(char** data, jint cnt) {
45 for (jint i = 0; i < cnt; i++) {
46 Dealloc(data[i]);
47 }
48 Dealloc(data);
49}
50
51extern "C" JNIEXPORT jobjectArray JNICALL Java_art_Test1946_getClassloaderDescriptors(
52 JNIEnv* env, jclass, jobject loader) {
53 DescriptorData* data = nullptr;
54 if (JvmtiErrorToException(
55 env, jvmti_env, jvmti_env->GetEnvironmentLocalStorage(reinterpret_cast<void**>(&data)))) {
56 return nullptr;
57 }
58 if (data == nullptr || data->get_descriptor_list == nullptr) {
59 ScopedLocalRef<jclass> rt_exception(env, env->FindClass("java/lang/RuntimeException"));
60 env->ThrowNew(rt_exception.get(), "Alloc tracking data not initialized.");
61 return nullptr;
62 }
63 char** classes = nullptr;
64 jint cnt = -1;
65 if (JvmtiErrorToException(env, jvmti_env, data->get_descriptor_list(jvmti_env,
66 loader,
67 &cnt,
68 &classes))) {
69 return nullptr;
70 }
71 ScopedLocalRef<jobjectArray> arr(env, env->NewObjectArray(cnt,
72 env->FindClass("java/lang/String"),
73 nullptr));
74 if (env->ExceptionCheck()) {
75 Cleanup(classes, cnt);
76 return nullptr;
77 }
78
79 for (jint i = 0; i < cnt; i++) {
80 env->SetObjectArrayElement(arr.get(), i, env->NewStringUTF(classes[i]));
81 if (env->ExceptionCheck()) {
82 Cleanup(classes, cnt);
83 return nullptr;
84 }
85 }
86 Cleanup(classes, cnt);
87 return arr.release();
88}
89
90static void DeallocParams(jvmtiParamInfo* params, jint n_params) {
91 for (jint i = 0; i < n_params; i++) {
92 Dealloc(params[i].name);
93 }
94}
95
96extern "C" JNIEXPORT void JNICALL Java_art_Test1946_initializeTest(JNIEnv* env, jclass) {
97 void* old_data = nullptr;
98 if (JvmtiErrorToException(env, jvmti_env, jvmti_env->GetEnvironmentLocalStorage(&old_data))) {
99 return;
100 } else if (old_data != nullptr) {
101 ScopedLocalRef<jclass> rt_exception(env, env->FindClass("java/lang/RuntimeException"));
102 env->ThrowNew(rt_exception.get(), "Environment already has local storage set!");
103 return;
104 }
105 DescriptorData* data = nullptr;
106 if (JvmtiErrorToException(env,
107 jvmti_env,
108 jvmti_env->Allocate(sizeof(DescriptorData),
109 reinterpret_cast<unsigned char**>(&data)))) {
110 return;
111 }
112 memset(data, 0, sizeof(DescriptorData));
113 // Get the extensions.
114 jint n_ext = 0;
115 jvmtiExtensionFunctionInfo* infos = nullptr;
116 if (JvmtiErrorToException(env, jvmti_env, jvmti_env->GetExtensionFunctions(&n_ext, &infos))) {
117 return;
118 }
119 for (jint i = 0; i < n_ext; i++) {
120 jvmtiExtensionFunctionInfo* cur_info = &infos[i];
121 if (strcmp("com.android.art.class.get_class_loader_class_descriptors", cur_info->id) == 0) {
122 data->get_descriptor_list = reinterpret_cast<GetDescriptorList>(cur_info->func);
123 }
124 // Cleanup the cur_info
125 DeallocParams(cur_info->params, cur_info->param_count);
126 Dealloc(cur_info->id, cur_info->short_description, cur_info->params, cur_info->errors);
127 }
128 // Cleanup the array.
129 Dealloc(infos);
130 if (data->get_descriptor_list == nullptr) {
131 ScopedLocalRef<jclass> rt_exception(env, env->FindClass("java/lang/RuntimeException"));
132 env->ThrowNew(rt_exception.get(), "Unable to find memory tracking extensions.");
133 return;
134 }
135 JvmtiErrorToException(env, jvmti_env, jvmti_env->SetEnvironmentLocalStorage(data));
136 return;
137}
138
139} // namespace Test1946Descriptors
140} // namespace art