1 /* Copyright (C) 2016 The Android Open Source Project
2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
3 *
4 * This file implements interfaces from the file jvmti.h. This implementation
5 * is licensed under the same terms as the file jvmti.h. The
6 * copyright and license information for the file jvmti.h follows.
7 *
8 * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
9 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
10 *
11 * This code is free software; you can redistribute it and/or modify it
12 * under the terms of the GNU General Public License version 2 only, as
13 * published by the Free Software Foundation. Oracle designates this
14 * particular file as subject to the "Classpath" exception as provided
15 * by Oracle in the LICENSE file that accompanied this code.
16 *
17 * This code is distributed in the hope that it will be useful, but WITHOUT
18 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
19 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
20 * version 2 for more details (a copy is included in the LICENSE file that
21 * accompanied this code).
22 *
23 * You should have received a copy of the GNU General Public License version
24 * 2 along with this work; if not, write to the Free Software Foundation,
25 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
26 *
27 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
28 * or visit www.oracle.com if you need additional information or have any
29 * questions.
30 */
31
32 #include <string>
33 #include <type_traits>
34 #include <vector>
35
36 #include <jni.h>
37
38 #include "jvmti.h"
39
40 #include "art_jvmti.h"
41 #include "base/logging.h"
42 #include "base/mutex.h"
43 #include "events-inl.h"
44 #include "jni_env_ext-inl.h"
45 #include "obj_ptr-inl.h"
46 #include "object_tagging.h"
47 #include "runtime.h"
48 #include "scoped_thread_state_change-inl.h"
49 #include "thread-inl.h"
50 #include "thread_list.h"
51 #include "ti_class.h"
52 #include "ti_dump.h"
53 #include "ti_field.h"
54 #include "ti_heap.h"
55 #include "ti_jni.h"
56 #include "ti_method.h"
57 #include "ti_monitor.h"
58 #include "ti_object.h"
59 #include "ti_phase.h"
60 #include "ti_properties.h"
61 #include "ti_redefine.h"
62 #include "ti_search.h"
63 #include "ti_stack.h"
64 #include "ti_thread.h"
65 #include "ti_threadgroup.h"
66 #include "ti_timers.h"
67 #include "transform.h"
68
69 namespace openjdkjvmti {
70
71 EventHandler gEventHandler;
72
73 #define ENSURE_NON_NULL(n) \
74 do { \
75 if ((n) == nullptr) { \
76 return ERR(NULL_POINTER); \
77 } \
78 } while (false)
79
80 class JvmtiFunctions {
81 private:
getEnvironmentError(jvmtiEnv * env)82 static jvmtiError getEnvironmentError(jvmtiEnv* env) {
83 if (env == nullptr) {
84 return ERR(INVALID_ENVIRONMENT);
85 } else if (art::Thread::Current() == nullptr) {
86 return ERR(UNATTACHED_THREAD);
87 } else {
88 return OK;
89 }
90 }
91
92 #define ENSURE_VALID_ENV(env) \
93 do { \
94 jvmtiError ensure_valid_env_ ## __LINE__ = getEnvironmentError(env); \
95 if (ensure_valid_env_ ## __LINE__ != OK) { \
96 return ensure_valid_env_ ## __LINE__ ; \
97 } \
98 } while (false)
99
100 #define ENSURE_HAS_CAP(env, cap) \
101 do { \
102 if (ArtJvmTiEnv::AsArtJvmTiEnv(env)->capabilities.cap != 1) { \
103 return ERR(MUST_POSSESS_CAPABILITY); \
104 } \
105 } while (false)
106
107 public:
Allocate(jvmtiEnv * env,jlong size,unsigned char ** mem_ptr)108 static jvmtiError Allocate(jvmtiEnv* env, jlong size, unsigned char** mem_ptr) {
109 ENSURE_VALID_ENV(env);
110 ENSURE_NON_NULL(mem_ptr);
111 if (size < 0) {
112 return ERR(ILLEGAL_ARGUMENT);
113 } else if (size == 0) {
114 *mem_ptr = nullptr;
115 return OK;
116 }
117 *mem_ptr = static_cast<unsigned char*>(malloc(size));
118 return (*mem_ptr != nullptr) ? OK : ERR(OUT_OF_MEMORY);
119 }
120
Deallocate(jvmtiEnv * env,unsigned char * mem)121 static jvmtiError Deallocate(jvmtiEnv* env, unsigned char* mem) {
122 ENSURE_VALID_ENV(env);
123 if (mem != nullptr) {
124 free(mem);
125 }
126 return OK;
127 }
128
GetThreadState(jvmtiEnv * env,jthread thread,jint * thread_state_ptr)129 static jvmtiError GetThreadState(jvmtiEnv* env, jthread thread, jint* thread_state_ptr) {
130 ENSURE_VALID_ENV(env);
131 return ThreadUtil::GetThreadState(env, thread, thread_state_ptr);
132 }
133
GetCurrentThread(jvmtiEnv * env,jthread * thread_ptr)134 static jvmtiError GetCurrentThread(jvmtiEnv* env, jthread* thread_ptr) {
135 ENSURE_VALID_ENV(env);
136 return ThreadUtil::GetCurrentThread(env, thread_ptr);
137 }
138
GetAllThreads(jvmtiEnv * env,jint * threads_count_ptr,jthread ** threads_ptr)139 static jvmtiError GetAllThreads(jvmtiEnv* env, jint* threads_count_ptr, jthread** threads_ptr) {
140 ENSURE_VALID_ENV(env);
141 return ThreadUtil::GetAllThreads(env, threads_count_ptr, threads_ptr);
142 }
143
SuspendThread(jvmtiEnv * env,jthread thread ATTRIBUTE_UNUSED)144 static jvmtiError SuspendThread(jvmtiEnv* env, jthread thread ATTRIBUTE_UNUSED) {
145 ENSURE_VALID_ENV(env);
146 ENSURE_HAS_CAP(env, can_suspend);
147 return ERR(NOT_IMPLEMENTED);
148 }
149
SuspendThreadList(jvmtiEnv * env,jint request_count ATTRIBUTE_UNUSED,const jthread * request_list ATTRIBUTE_UNUSED,jvmtiError * results ATTRIBUTE_UNUSED)150 static jvmtiError SuspendThreadList(jvmtiEnv* env,
151 jint request_count ATTRIBUTE_UNUSED,
152 const jthread* request_list ATTRIBUTE_UNUSED,
153 jvmtiError* results ATTRIBUTE_UNUSED) {
154 ENSURE_VALID_ENV(env);
155 ENSURE_HAS_CAP(env, can_suspend);
156 return ERR(NOT_IMPLEMENTED);
157 }
158
ResumeThread(jvmtiEnv * env,jthread thread ATTRIBUTE_UNUSED)159 static jvmtiError ResumeThread(jvmtiEnv* env, jthread thread ATTRIBUTE_UNUSED) {
160 ENSURE_VALID_ENV(env);
161 ENSURE_HAS_CAP(env, can_suspend);
162 return ERR(NOT_IMPLEMENTED);
163 }
164
ResumeThreadList(jvmtiEnv * env,jint request_count ATTRIBUTE_UNUSED,const jthread * request_list ATTRIBUTE_UNUSED,jvmtiError * results ATTRIBUTE_UNUSED)165 static jvmtiError ResumeThreadList(jvmtiEnv* env,
166 jint request_count ATTRIBUTE_UNUSED,
167 const jthread* request_list ATTRIBUTE_UNUSED,
168 jvmtiError* results ATTRIBUTE_UNUSED) {
169 ENSURE_VALID_ENV(env);
170 ENSURE_HAS_CAP(env, can_suspend);
171 return ERR(NOT_IMPLEMENTED);
172 }
173
StopThread(jvmtiEnv * env,jthread thread ATTRIBUTE_UNUSED,jobject exception ATTRIBUTE_UNUSED)174 static jvmtiError StopThread(jvmtiEnv* env,
175 jthread thread ATTRIBUTE_UNUSED,
176 jobject exception ATTRIBUTE_UNUSED) {
177 ENSURE_VALID_ENV(env);
178 ENSURE_HAS_CAP(env, can_signal_thread);
179 return ERR(NOT_IMPLEMENTED);
180 }
181
InterruptThread(jvmtiEnv * env,jthread thread ATTRIBUTE_UNUSED)182 static jvmtiError InterruptThread(jvmtiEnv* env, jthread thread ATTRIBUTE_UNUSED) {
183 ENSURE_VALID_ENV(env);
184 ENSURE_HAS_CAP(env, can_signal_thread);
185 return ERR(NOT_IMPLEMENTED);
186 }
187
GetThreadInfo(jvmtiEnv * env,jthread thread,jvmtiThreadInfo * info_ptr)188 static jvmtiError GetThreadInfo(jvmtiEnv* env, jthread thread, jvmtiThreadInfo* info_ptr) {
189 ENSURE_VALID_ENV(env);
190 return ThreadUtil::GetThreadInfo(env, thread, info_ptr);
191 }
192
GetOwnedMonitorInfo(jvmtiEnv * env,jthread thread ATTRIBUTE_UNUSED,jint * owned_monitor_count_ptr ATTRIBUTE_UNUSED,jobject ** owned_monitors_ptr ATTRIBUTE_UNUSED)193 static jvmtiError GetOwnedMonitorInfo(jvmtiEnv* env,
194 jthread thread ATTRIBUTE_UNUSED,
195 jint* owned_monitor_count_ptr ATTRIBUTE_UNUSED,
196 jobject** owned_monitors_ptr ATTRIBUTE_UNUSED) {
197 ENSURE_VALID_ENV(env);
198 ENSURE_HAS_CAP(env, can_get_owned_monitor_info);
199 return ERR(NOT_IMPLEMENTED);
200 }
201
GetOwnedMonitorStackDepthInfo(jvmtiEnv * env,jthread thread ATTRIBUTE_UNUSED,jint * monitor_info_count_ptr ATTRIBUTE_UNUSED,jvmtiMonitorStackDepthInfo ** monitor_info_ptr ATTRIBUTE_UNUSED)202 static jvmtiError GetOwnedMonitorStackDepthInfo(
203 jvmtiEnv* env,
204 jthread thread ATTRIBUTE_UNUSED,
205 jint* monitor_info_count_ptr ATTRIBUTE_UNUSED,
206 jvmtiMonitorStackDepthInfo** monitor_info_ptr ATTRIBUTE_UNUSED) {
207 ENSURE_VALID_ENV(env);
208 ENSURE_HAS_CAP(env, can_get_owned_monitor_stack_depth_info);
209 return ERR(NOT_IMPLEMENTED);
210 }
211
GetCurrentContendedMonitor(jvmtiEnv * env,jthread thread ATTRIBUTE_UNUSED,jobject * monitor_ptr ATTRIBUTE_UNUSED)212 static jvmtiError GetCurrentContendedMonitor(jvmtiEnv* env,
213 jthread thread ATTRIBUTE_UNUSED,
214 jobject* monitor_ptr ATTRIBUTE_UNUSED) {
215 ENSURE_VALID_ENV(env);
216 ENSURE_HAS_CAP(env, can_get_current_contended_monitor);
217 return ERR(NOT_IMPLEMENTED);
218 }
219
RunAgentThread(jvmtiEnv * env,jthread thread,jvmtiStartFunction proc,const void * arg,jint priority)220 static jvmtiError RunAgentThread(jvmtiEnv* env,
221 jthread thread,
222 jvmtiStartFunction proc,
223 const void* arg,
224 jint priority) {
225 ENSURE_VALID_ENV(env);
226 return ThreadUtil::RunAgentThread(env, thread, proc, arg, priority);
227 }
228
SetThreadLocalStorage(jvmtiEnv * env,jthread thread,const void * data)229 static jvmtiError SetThreadLocalStorage(jvmtiEnv* env, jthread thread, const void* data) {
230 ENSURE_VALID_ENV(env);
231 return ThreadUtil::SetThreadLocalStorage(env, thread, data);
232 }
233
GetThreadLocalStorage(jvmtiEnv * env,jthread thread,void ** data_ptr)234 static jvmtiError GetThreadLocalStorage(jvmtiEnv* env, jthread thread, void** data_ptr) {
235 ENSURE_VALID_ENV(env);
236 return ThreadUtil::GetThreadLocalStorage(env, thread, data_ptr);
237 }
238
GetTopThreadGroups(jvmtiEnv * env,jint * group_count_ptr,jthreadGroup ** groups_ptr)239 static jvmtiError GetTopThreadGroups(jvmtiEnv* env,
240 jint* group_count_ptr,
241 jthreadGroup** groups_ptr) {
242 ENSURE_VALID_ENV(env);
243 return ThreadGroupUtil::GetTopThreadGroups(env, group_count_ptr, groups_ptr);
244 }
245
GetThreadGroupInfo(jvmtiEnv * env,jthreadGroup group,jvmtiThreadGroupInfo * info_ptr)246 static jvmtiError GetThreadGroupInfo(jvmtiEnv* env,
247 jthreadGroup group,
248 jvmtiThreadGroupInfo* info_ptr) {
249 ENSURE_VALID_ENV(env);
250 return ThreadGroupUtil::GetThreadGroupInfo(env, group, info_ptr);
251 }
252
GetThreadGroupChildren(jvmtiEnv * env,jthreadGroup group,jint * thread_count_ptr,jthread ** threads_ptr,jint * group_count_ptr,jthreadGroup ** groups_ptr)253 static jvmtiError GetThreadGroupChildren(jvmtiEnv* env,
254 jthreadGroup group,
255 jint* thread_count_ptr,
256 jthread** threads_ptr,
257 jint* group_count_ptr,
258 jthreadGroup** groups_ptr) {
259 ENSURE_VALID_ENV(env);
260 return ThreadGroupUtil::GetThreadGroupChildren(env,
261 group,
262 thread_count_ptr,
263 threads_ptr,
264 group_count_ptr,
265 groups_ptr);
266 }
267
GetStackTrace(jvmtiEnv * env,jthread thread,jint start_depth,jint max_frame_count,jvmtiFrameInfo * frame_buffer,jint * count_ptr)268 static jvmtiError GetStackTrace(jvmtiEnv* env,
269 jthread thread,
270 jint start_depth,
271 jint max_frame_count,
272 jvmtiFrameInfo* frame_buffer,
273 jint* count_ptr) {
274 ENSURE_VALID_ENV(env);
275 return StackUtil::GetStackTrace(env,
276 thread,
277 start_depth,
278 max_frame_count,
279 frame_buffer,
280 count_ptr);
281 }
282
GetAllStackTraces(jvmtiEnv * env,jint max_frame_count,jvmtiStackInfo ** stack_info_ptr,jint * thread_count_ptr)283 static jvmtiError GetAllStackTraces(jvmtiEnv* env,
284 jint max_frame_count,
285 jvmtiStackInfo** stack_info_ptr,
286 jint* thread_count_ptr) {
287 ENSURE_VALID_ENV(env);
288 return StackUtil::GetAllStackTraces(env, max_frame_count, stack_info_ptr, thread_count_ptr);
289 }
290
GetThreadListStackTraces(jvmtiEnv * env,jint thread_count,const jthread * thread_list,jint max_frame_count,jvmtiStackInfo ** stack_info_ptr)291 static jvmtiError GetThreadListStackTraces(jvmtiEnv* env,
292 jint thread_count,
293 const jthread* thread_list,
294 jint max_frame_count,
295 jvmtiStackInfo** stack_info_ptr) {
296 ENSURE_VALID_ENV(env);
297 return StackUtil::GetThreadListStackTraces(env,
298 thread_count,
299 thread_list,
300 max_frame_count,
301 stack_info_ptr);
302 }
303
GetFrameCount(jvmtiEnv * env,jthread thread,jint * count_ptr)304 static jvmtiError GetFrameCount(jvmtiEnv* env, jthread thread, jint* count_ptr) {
305 ENSURE_VALID_ENV(env);
306 return StackUtil::GetFrameCount(env, thread, count_ptr);
307 }
308
PopFrame(jvmtiEnv * env,jthread thread ATTRIBUTE_UNUSED)309 static jvmtiError PopFrame(jvmtiEnv* env, jthread thread ATTRIBUTE_UNUSED) {
310 ENSURE_VALID_ENV(env);
311 ENSURE_HAS_CAP(env, can_pop_frame);
312 return ERR(NOT_IMPLEMENTED);
313 }
314
GetFrameLocation(jvmtiEnv * env,jthread thread,jint depth,jmethodID * method_ptr,jlocation * location_ptr)315 static jvmtiError GetFrameLocation(jvmtiEnv* env,
316 jthread thread,
317 jint depth,
318 jmethodID* method_ptr,
319 jlocation* location_ptr) {
320 ENSURE_VALID_ENV(env);
321 return StackUtil::GetFrameLocation(env, thread, depth, method_ptr, location_ptr);
322 }
323
NotifyFramePop(jvmtiEnv * env,jthread thread ATTRIBUTE_UNUSED,jint depth ATTRIBUTE_UNUSED)324 static jvmtiError NotifyFramePop(jvmtiEnv* env,
325 jthread thread ATTRIBUTE_UNUSED,
326 jint depth ATTRIBUTE_UNUSED) {
327 ENSURE_VALID_ENV(env);
328 ENSURE_HAS_CAP(env, can_generate_frame_pop_events);
329 return ERR(NOT_IMPLEMENTED);
330 }
331
ForceEarlyReturnObject(jvmtiEnv * env,jthread thread ATTRIBUTE_UNUSED,jobject value ATTRIBUTE_UNUSED)332 static jvmtiError ForceEarlyReturnObject(jvmtiEnv* env,
333 jthread thread ATTRIBUTE_UNUSED,
334 jobject value ATTRIBUTE_UNUSED) {
335 ENSURE_VALID_ENV(env);
336 ENSURE_HAS_CAP(env, can_force_early_return);
337 return ERR(NOT_IMPLEMENTED);
338 }
339
ForceEarlyReturnInt(jvmtiEnv * env,jthread thread ATTRIBUTE_UNUSED,jint value ATTRIBUTE_UNUSED)340 static jvmtiError ForceEarlyReturnInt(jvmtiEnv* env,
341 jthread thread ATTRIBUTE_UNUSED,
342 jint value ATTRIBUTE_UNUSED) {
343 ENSURE_VALID_ENV(env);
344 ENSURE_HAS_CAP(env, can_force_early_return);
345 return ERR(NOT_IMPLEMENTED);
346 }
347
ForceEarlyReturnLong(jvmtiEnv * env,jthread thread ATTRIBUTE_UNUSED,jlong value ATTRIBUTE_UNUSED)348 static jvmtiError ForceEarlyReturnLong(jvmtiEnv* env,
349 jthread thread ATTRIBUTE_UNUSED,
350 jlong value ATTRIBUTE_UNUSED) {
351 ENSURE_VALID_ENV(env);
352 ENSURE_HAS_CAP(env, can_force_early_return);
353 return ERR(NOT_IMPLEMENTED);
354 }
355
ForceEarlyReturnFloat(jvmtiEnv * env,jthread thread ATTRIBUTE_UNUSED,jfloat value ATTRIBUTE_UNUSED)356 static jvmtiError ForceEarlyReturnFloat(jvmtiEnv* env,
357 jthread thread ATTRIBUTE_UNUSED,
358 jfloat value ATTRIBUTE_UNUSED) {
359 ENSURE_VALID_ENV(env);
360 ENSURE_HAS_CAP(env, can_force_early_return);
361 return ERR(NOT_IMPLEMENTED);
362 }
363
ForceEarlyReturnDouble(jvmtiEnv * env,jthread thread ATTRIBUTE_UNUSED,jdouble value ATTRIBUTE_UNUSED)364 static jvmtiError ForceEarlyReturnDouble(jvmtiEnv* env,
365 jthread thread ATTRIBUTE_UNUSED,
366 jdouble value ATTRIBUTE_UNUSED) {
367 ENSURE_VALID_ENV(env);
368 ENSURE_HAS_CAP(env, can_force_early_return);
369 return ERR(NOT_IMPLEMENTED);
370 }
371
ForceEarlyReturnVoid(jvmtiEnv * env,jthread thread ATTRIBUTE_UNUSED)372 static jvmtiError ForceEarlyReturnVoid(jvmtiEnv* env, jthread thread ATTRIBUTE_UNUSED) {
373 ENSURE_VALID_ENV(env);
374 ENSURE_HAS_CAP(env, can_force_early_return);
375 return ERR(NOT_IMPLEMENTED);
376 }
377
FollowReferences(jvmtiEnv * env,jint heap_filter,jclass klass,jobject initial_object,const jvmtiHeapCallbacks * callbacks,const void * user_data)378 static jvmtiError FollowReferences(jvmtiEnv* env,
379 jint heap_filter,
380 jclass klass,
381 jobject initial_object,
382 const jvmtiHeapCallbacks* callbacks,
383 const void* user_data) {
384 ENSURE_VALID_ENV(env);
385 ENSURE_HAS_CAP(env, can_tag_objects);
386 HeapUtil heap_util(ArtJvmTiEnv::AsArtJvmTiEnv(env)->object_tag_table.get());
387 return heap_util.FollowReferences(env,
388 heap_filter,
389 klass,
390 initial_object,
391 callbacks,
392 user_data);
393 }
394
IterateThroughHeap(jvmtiEnv * env,jint heap_filter,jclass klass,const jvmtiHeapCallbacks * callbacks,const void * user_data)395 static jvmtiError IterateThroughHeap(jvmtiEnv* env,
396 jint heap_filter,
397 jclass klass,
398 const jvmtiHeapCallbacks* callbacks,
399 const void* user_data) {
400 ENSURE_VALID_ENV(env);
401 ENSURE_HAS_CAP(env, can_tag_objects);
402 HeapUtil heap_util(ArtJvmTiEnv::AsArtJvmTiEnv(env)->object_tag_table.get());
403 return heap_util.IterateThroughHeap(env, heap_filter, klass, callbacks, user_data);
404 }
405
GetTag(jvmtiEnv * env,jobject object,jlong * tag_ptr)406 static jvmtiError GetTag(jvmtiEnv* env, jobject object, jlong* tag_ptr) {
407 ENSURE_VALID_ENV(env);
408 ENSURE_HAS_CAP(env, can_tag_objects);
409
410 JNIEnv* jni_env = GetJniEnv(env);
411 if (jni_env == nullptr) {
412 return ERR(INTERNAL);
413 }
414
415 art::ScopedObjectAccess soa(jni_env);
416 art::ObjPtr<art::mirror::Object> obj = soa.Decode<art::mirror::Object>(object);
417 if (!ArtJvmTiEnv::AsArtJvmTiEnv(env)->object_tag_table->GetTag(obj.Ptr(), tag_ptr)) {
418 *tag_ptr = 0;
419 }
420
421 return ERR(NONE);
422 }
423
SetTag(jvmtiEnv * env,jobject object,jlong tag)424 static jvmtiError SetTag(jvmtiEnv* env, jobject object, jlong tag) {
425 ENSURE_VALID_ENV(env);
426 ENSURE_HAS_CAP(env, can_tag_objects);
427
428 if (object == nullptr) {
429 return ERR(NULL_POINTER);
430 }
431
432 JNIEnv* jni_env = GetJniEnv(env);
433 if (jni_env == nullptr) {
434 return ERR(INTERNAL);
435 }
436
437 art::ScopedObjectAccess soa(jni_env);
438 art::ObjPtr<art::mirror::Object> obj = soa.Decode<art::mirror::Object>(object);
439 ArtJvmTiEnv::AsArtJvmTiEnv(env)->object_tag_table->Set(obj.Ptr(), tag);
440
441 return ERR(NONE);
442 }
443
GetObjectsWithTags(jvmtiEnv * env,jint tag_count,const jlong * tags,jint * count_ptr,jobject ** object_result_ptr,jlong ** tag_result_ptr)444 static jvmtiError GetObjectsWithTags(jvmtiEnv* env,
445 jint tag_count,
446 const jlong* tags,
447 jint* count_ptr,
448 jobject** object_result_ptr,
449 jlong** tag_result_ptr) {
450 ENSURE_VALID_ENV(env);
451 ENSURE_HAS_CAP(env, can_tag_objects);
452
453 JNIEnv* jni_env = GetJniEnv(env);
454 if (jni_env == nullptr) {
455 return ERR(INTERNAL);
456 }
457
458 art::ScopedObjectAccess soa(jni_env);
459 return ArtJvmTiEnv::AsArtJvmTiEnv(env)->object_tag_table->GetTaggedObjects(env,
460 tag_count,
461 tags,
462 count_ptr,
463 object_result_ptr,
464 tag_result_ptr);
465 }
466
ForceGarbageCollection(jvmtiEnv * env)467 static jvmtiError ForceGarbageCollection(jvmtiEnv* env) {
468 ENSURE_VALID_ENV(env);
469 return HeapUtil::ForceGarbageCollection(env);
470 }
471
IterateOverObjectsReachableFromObject(jvmtiEnv * env,jobject object ATTRIBUTE_UNUSED,jvmtiObjectReferenceCallback object_reference_callback ATTRIBUTE_UNUSED,const void * user_data ATTRIBUTE_UNUSED)472 static jvmtiError IterateOverObjectsReachableFromObject(
473 jvmtiEnv* env,
474 jobject object ATTRIBUTE_UNUSED,
475 jvmtiObjectReferenceCallback object_reference_callback ATTRIBUTE_UNUSED,
476 const void* user_data ATTRIBUTE_UNUSED) {
477 ENSURE_VALID_ENV(env);
478 ENSURE_HAS_CAP(env, can_tag_objects);
479 return ERR(NOT_IMPLEMENTED);
480 }
481
IterateOverReachableObjects(jvmtiEnv * env,jvmtiHeapRootCallback heap_root_callback ATTRIBUTE_UNUSED,jvmtiStackReferenceCallback stack_ref_callback ATTRIBUTE_UNUSED,jvmtiObjectReferenceCallback object_ref_callback ATTRIBUTE_UNUSED,const void * user_data ATTRIBUTE_UNUSED)482 static jvmtiError IterateOverReachableObjects(
483 jvmtiEnv* env,
484 jvmtiHeapRootCallback heap_root_callback ATTRIBUTE_UNUSED,
485 jvmtiStackReferenceCallback stack_ref_callback ATTRIBUTE_UNUSED,
486 jvmtiObjectReferenceCallback object_ref_callback ATTRIBUTE_UNUSED,
487 const void* user_data ATTRIBUTE_UNUSED) {
488 ENSURE_VALID_ENV(env);
489 ENSURE_HAS_CAP(env, can_tag_objects);
490 return ERR(NOT_IMPLEMENTED);
491 }
492
IterateOverHeap(jvmtiEnv * env,jvmtiHeapObjectFilter object_filter ATTRIBUTE_UNUSED,jvmtiHeapObjectCallback heap_object_callback ATTRIBUTE_UNUSED,const void * user_data ATTRIBUTE_UNUSED)493 static jvmtiError IterateOverHeap(jvmtiEnv* env,
494 jvmtiHeapObjectFilter object_filter ATTRIBUTE_UNUSED,
495 jvmtiHeapObjectCallback heap_object_callback ATTRIBUTE_UNUSED,
496 const void* user_data ATTRIBUTE_UNUSED) {
497 ENSURE_VALID_ENV(env);
498 ENSURE_HAS_CAP(env, can_tag_objects);
499 return ERR(NOT_IMPLEMENTED);
500 }
501
IterateOverInstancesOfClass(jvmtiEnv * env,jclass klass ATTRIBUTE_UNUSED,jvmtiHeapObjectFilter object_filter ATTRIBUTE_UNUSED,jvmtiHeapObjectCallback heap_object_callback ATTRIBUTE_UNUSED,const void * user_data ATTRIBUTE_UNUSED)502 static jvmtiError IterateOverInstancesOfClass(
503 jvmtiEnv* env,
504 jclass klass ATTRIBUTE_UNUSED,
505 jvmtiHeapObjectFilter object_filter ATTRIBUTE_UNUSED,
506 jvmtiHeapObjectCallback heap_object_callback ATTRIBUTE_UNUSED,
507 const void* user_data ATTRIBUTE_UNUSED) {
508 ENSURE_VALID_ENV(env);
509 ENSURE_HAS_CAP(env, can_tag_objects);
510 return ERR(NOT_IMPLEMENTED);
511 }
512
GetLocalObject(jvmtiEnv * env,jthread thread ATTRIBUTE_UNUSED,jint depth ATTRIBUTE_UNUSED,jint slot ATTRIBUTE_UNUSED,jobject * value_ptr ATTRIBUTE_UNUSED)513 static jvmtiError GetLocalObject(jvmtiEnv* env,
514 jthread thread ATTRIBUTE_UNUSED,
515 jint depth ATTRIBUTE_UNUSED,
516 jint slot ATTRIBUTE_UNUSED,
517 jobject* value_ptr ATTRIBUTE_UNUSED) {
518 ENSURE_VALID_ENV(env);
519 ENSURE_HAS_CAP(env, can_access_local_variables);
520 return ERR(NOT_IMPLEMENTED);
521 }
522
GetLocalInstance(jvmtiEnv * env,jthread thread ATTRIBUTE_UNUSED,jint depth ATTRIBUTE_UNUSED,jobject * value_ptr ATTRIBUTE_UNUSED)523 static jvmtiError GetLocalInstance(jvmtiEnv* env,
524 jthread thread ATTRIBUTE_UNUSED,
525 jint depth ATTRIBUTE_UNUSED,
526 jobject* value_ptr ATTRIBUTE_UNUSED) {
527 ENSURE_VALID_ENV(env);
528 ENSURE_HAS_CAP(env, can_access_local_variables);
529 return ERR(NOT_IMPLEMENTED);
530 }
531
GetLocalInt(jvmtiEnv * env,jthread thread ATTRIBUTE_UNUSED,jint depth ATTRIBUTE_UNUSED,jint slot ATTRIBUTE_UNUSED,jint * value_ptr ATTRIBUTE_UNUSED)532 static jvmtiError GetLocalInt(jvmtiEnv* env,
533 jthread thread ATTRIBUTE_UNUSED,
534 jint depth ATTRIBUTE_UNUSED,
535 jint slot ATTRIBUTE_UNUSED,
536 jint* value_ptr ATTRIBUTE_UNUSED) {
537 ENSURE_VALID_ENV(env);
538 ENSURE_HAS_CAP(env, can_access_local_variables);
539 return ERR(NOT_IMPLEMENTED);
540 }
541
GetLocalLong(jvmtiEnv * env,jthread thread ATTRIBUTE_UNUSED,jint depth ATTRIBUTE_UNUSED,jint slot ATTRIBUTE_UNUSED,jlong * value_ptr ATTRIBUTE_UNUSED)542 static jvmtiError GetLocalLong(jvmtiEnv* env,
543 jthread thread ATTRIBUTE_UNUSED,
544 jint depth ATTRIBUTE_UNUSED,
545 jint slot ATTRIBUTE_UNUSED,
546 jlong* value_ptr ATTRIBUTE_UNUSED) {
547 ENSURE_VALID_ENV(env);
548 ENSURE_HAS_CAP(env, can_access_local_variables);
549 return ERR(NOT_IMPLEMENTED);
550 }
551
GetLocalFloat(jvmtiEnv * env,jthread thread ATTRIBUTE_UNUSED,jint depth ATTRIBUTE_UNUSED,jint slot ATTRIBUTE_UNUSED,jfloat * value_ptr ATTRIBUTE_UNUSED)552 static jvmtiError GetLocalFloat(jvmtiEnv* env,
553 jthread thread ATTRIBUTE_UNUSED,
554 jint depth ATTRIBUTE_UNUSED,
555 jint slot ATTRIBUTE_UNUSED,
556 jfloat* value_ptr ATTRIBUTE_UNUSED) {
557 ENSURE_VALID_ENV(env);
558 ENSURE_HAS_CAP(env, can_access_local_variables);
559 return ERR(NOT_IMPLEMENTED);
560 }
561
GetLocalDouble(jvmtiEnv * env,jthread thread ATTRIBUTE_UNUSED,jint depth ATTRIBUTE_UNUSED,jint slot ATTRIBUTE_UNUSED,jdouble * value_ptr ATTRIBUTE_UNUSED)562 static jvmtiError GetLocalDouble(jvmtiEnv* env,
563 jthread thread ATTRIBUTE_UNUSED,
564 jint depth ATTRIBUTE_UNUSED,
565 jint slot ATTRIBUTE_UNUSED,
566 jdouble* value_ptr ATTRIBUTE_UNUSED) {
567 ENSURE_VALID_ENV(env);
568 ENSURE_HAS_CAP(env, can_access_local_variables);
569 return ERR(NOT_IMPLEMENTED);
570 }
571
SetLocalObject(jvmtiEnv * env,jthread thread ATTRIBUTE_UNUSED,jint depth ATTRIBUTE_UNUSED,jint slot ATTRIBUTE_UNUSED,jobject value ATTRIBUTE_UNUSED)572 static jvmtiError SetLocalObject(jvmtiEnv* env,
573 jthread thread ATTRIBUTE_UNUSED,
574 jint depth ATTRIBUTE_UNUSED,
575 jint slot ATTRIBUTE_UNUSED,
576 jobject value ATTRIBUTE_UNUSED) {
577 ENSURE_VALID_ENV(env);
578 ENSURE_HAS_CAP(env, can_access_local_variables);
579 return ERR(NOT_IMPLEMENTED);
580 }
581
SetLocalInt(jvmtiEnv * env,jthread thread ATTRIBUTE_UNUSED,jint depth ATTRIBUTE_UNUSED,jint slot ATTRIBUTE_UNUSED,jint value ATTRIBUTE_UNUSED)582 static jvmtiError SetLocalInt(jvmtiEnv* env,
583 jthread thread ATTRIBUTE_UNUSED,
584 jint depth ATTRIBUTE_UNUSED,
585 jint slot ATTRIBUTE_UNUSED,
586 jint value ATTRIBUTE_UNUSED) {
587 ENSURE_VALID_ENV(env);
588 ENSURE_HAS_CAP(env, can_access_local_variables);
589 return ERR(NOT_IMPLEMENTED);
590 }
591
SetLocalLong(jvmtiEnv * env,jthread thread ATTRIBUTE_UNUSED,jint depth ATTRIBUTE_UNUSED,jint slot ATTRIBUTE_UNUSED,jlong value ATTRIBUTE_UNUSED)592 static jvmtiError SetLocalLong(jvmtiEnv* env,
593 jthread thread ATTRIBUTE_UNUSED,
594 jint depth ATTRIBUTE_UNUSED,
595 jint slot ATTRIBUTE_UNUSED,
596 jlong value ATTRIBUTE_UNUSED) {
597 ENSURE_VALID_ENV(env);
598 ENSURE_HAS_CAP(env, can_access_local_variables);
599 return ERR(NOT_IMPLEMENTED);
600 }
601
SetLocalFloat(jvmtiEnv * env,jthread thread ATTRIBUTE_UNUSED,jint depth ATTRIBUTE_UNUSED,jint slot ATTRIBUTE_UNUSED,jfloat value ATTRIBUTE_UNUSED)602 static jvmtiError SetLocalFloat(jvmtiEnv* env,
603 jthread thread ATTRIBUTE_UNUSED,
604 jint depth ATTRIBUTE_UNUSED,
605 jint slot ATTRIBUTE_UNUSED,
606 jfloat value ATTRIBUTE_UNUSED) {
607 ENSURE_VALID_ENV(env);
608 ENSURE_HAS_CAP(env, can_access_local_variables);
609 return ERR(NOT_IMPLEMENTED);
610 }
611
SetLocalDouble(jvmtiEnv * env,jthread thread ATTRIBUTE_UNUSED,jint depth ATTRIBUTE_UNUSED,jint slot ATTRIBUTE_UNUSED,jdouble value ATTRIBUTE_UNUSED)612 static jvmtiError SetLocalDouble(jvmtiEnv* env,
613 jthread thread ATTRIBUTE_UNUSED,
614 jint depth ATTRIBUTE_UNUSED,
615 jint slot ATTRIBUTE_UNUSED,
616 jdouble value ATTRIBUTE_UNUSED) {
617 ENSURE_VALID_ENV(env);
618 ENSURE_HAS_CAP(env, can_access_local_variables);
619 return ERR(NOT_IMPLEMENTED);
620 }
621
SetBreakpoint(jvmtiEnv * env,jmethodID method ATTRIBUTE_UNUSED,jlocation location ATTRIBUTE_UNUSED)622 static jvmtiError SetBreakpoint(jvmtiEnv* env,
623 jmethodID method ATTRIBUTE_UNUSED,
624 jlocation location ATTRIBUTE_UNUSED) {
625 ENSURE_VALID_ENV(env);
626 ENSURE_HAS_CAP(env, can_generate_breakpoint_events);
627 return ERR(NOT_IMPLEMENTED);
628 }
629
ClearBreakpoint(jvmtiEnv * env,jmethodID method ATTRIBUTE_UNUSED,jlocation location ATTRIBUTE_UNUSED)630 static jvmtiError ClearBreakpoint(jvmtiEnv* env,
631 jmethodID method ATTRIBUTE_UNUSED,
632 jlocation location ATTRIBUTE_UNUSED) {
633 ENSURE_VALID_ENV(env);
634 ENSURE_HAS_CAP(env, can_generate_breakpoint_events);
635 return ERR(NOT_IMPLEMENTED);
636 }
637
SetFieldAccessWatch(jvmtiEnv * env,jclass klass ATTRIBUTE_UNUSED,jfieldID field ATTRIBUTE_UNUSED)638 static jvmtiError SetFieldAccessWatch(jvmtiEnv* env,
639 jclass klass ATTRIBUTE_UNUSED,
640 jfieldID field ATTRIBUTE_UNUSED) {
641 ENSURE_VALID_ENV(env);
642 ENSURE_HAS_CAP(env, can_generate_field_access_events);
643 return ERR(NOT_IMPLEMENTED);
644 }
645
ClearFieldAccessWatch(jvmtiEnv * env,jclass klass ATTRIBUTE_UNUSED,jfieldID field ATTRIBUTE_UNUSED)646 static jvmtiError ClearFieldAccessWatch(jvmtiEnv* env,
647 jclass klass ATTRIBUTE_UNUSED,
648 jfieldID field ATTRIBUTE_UNUSED) {
649 ENSURE_VALID_ENV(env);
650 ENSURE_HAS_CAP(env, can_generate_field_access_events);
651 return ERR(NOT_IMPLEMENTED);
652 }
653
SetFieldModificationWatch(jvmtiEnv * env,jclass klass ATTRIBUTE_UNUSED,jfieldID field ATTRIBUTE_UNUSED)654 static jvmtiError SetFieldModificationWatch(jvmtiEnv* env,
655 jclass klass ATTRIBUTE_UNUSED,
656 jfieldID field ATTRIBUTE_UNUSED) {
657 ENSURE_VALID_ENV(env);
658 ENSURE_HAS_CAP(env, can_generate_field_modification_events);
659 return ERR(NOT_IMPLEMENTED);
660 }
661
ClearFieldModificationWatch(jvmtiEnv * env,jclass klass ATTRIBUTE_UNUSED,jfieldID field ATTRIBUTE_UNUSED)662 static jvmtiError ClearFieldModificationWatch(jvmtiEnv* env,
663 jclass klass ATTRIBUTE_UNUSED,
664 jfieldID field ATTRIBUTE_UNUSED) {
665 ENSURE_VALID_ENV(env);
666 ENSURE_HAS_CAP(env, can_generate_field_modification_events);
667 return ERR(NOT_IMPLEMENTED);
668 }
669
GetLoadedClasses(jvmtiEnv * env,jint * class_count_ptr,jclass ** classes_ptr)670 static jvmtiError GetLoadedClasses(jvmtiEnv* env, jint* class_count_ptr, jclass** classes_ptr) {
671 ENSURE_VALID_ENV(env);
672 HeapUtil heap_util(ArtJvmTiEnv::AsArtJvmTiEnv(env)->object_tag_table.get());
673 return heap_util.GetLoadedClasses(env, class_count_ptr, classes_ptr);
674 }
675
GetClassLoaderClasses(jvmtiEnv * env,jobject initiating_loader,jint * class_count_ptr,jclass ** classes_ptr)676 static jvmtiError GetClassLoaderClasses(jvmtiEnv* env,
677 jobject initiating_loader,
678 jint* class_count_ptr,
679 jclass** classes_ptr) {
680 ENSURE_VALID_ENV(env);
681 return ClassUtil::GetClassLoaderClasses(env, initiating_loader, class_count_ptr, classes_ptr);
682 }
683
GetClassSignature(jvmtiEnv * env,jclass klass,char ** signature_ptr,char ** generic_ptr)684 static jvmtiError GetClassSignature(jvmtiEnv* env,
685 jclass klass,
686 char** signature_ptr,
687 char** generic_ptr) {
688 ENSURE_VALID_ENV(env);
689 return ClassUtil::GetClassSignature(env, klass, signature_ptr, generic_ptr);
690 }
691
GetClassStatus(jvmtiEnv * env,jclass klass,jint * status_ptr)692 static jvmtiError GetClassStatus(jvmtiEnv* env, jclass klass, jint* status_ptr) {
693 ENSURE_VALID_ENV(env);
694 return ClassUtil::GetClassStatus(env, klass, status_ptr);
695 }
696
GetSourceFileName(jvmtiEnv * env,jclass klass ATTRIBUTE_UNUSED,char ** source_name_ptr ATTRIBUTE_UNUSED)697 static jvmtiError GetSourceFileName(jvmtiEnv* env,
698 jclass klass ATTRIBUTE_UNUSED,
699 char** source_name_ptr ATTRIBUTE_UNUSED) {
700 ENSURE_VALID_ENV(env);
701 ENSURE_HAS_CAP(env, can_get_source_file_name);
702 return ERR(NOT_IMPLEMENTED);
703 }
704
GetClassModifiers(jvmtiEnv * env,jclass klass,jint * modifiers_ptr)705 static jvmtiError GetClassModifiers(jvmtiEnv* env, jclass klass, jint* modifiers_ptr) {
706 ENSURE_VALID_ENV(env);
707 return ClassUtil::GetClassModifiers(env, klass, modifiers_ptr);
708 }
709
GetClassMethods(jvmtiEnv * env,jclass klass,jint * method_count_ptr,jmethodID ** methods_ptr)710 static jvmtiError GetClassMethods(jvmtiEnv* env,
711 jclass klass,
712 jint* method_count_ptr,
713 jmethodID** methods_ptr) {
714 ENSURE_VALID_ENV(env);
715 return ClassUtil::GetClassMethods(env, klass, method_count_ptr, methods_ptr);
716 }
717
GetClassFields(jvmtiEnv * env,jclass klass,jint * field_count_ptr,jfieldID ** fields_ptr)718 static jvmtiError GetClassFields(jvmtiEnv* env,
719 jclass klass,
720 jint* field_count_ptr,
721 jfieldID** fields_ptr) {
722 ENSURE_VALID_ENV(env);
723 return ClassUtil::GetClassFields(env, klass, field_count_ptr, fields_ptr);
724 }
725
GetImplementedInterfaces(jvmtiEnv * env,jclass klass,jint * interface_count_ptr,jclass ** interfaces_ptr)726 static jvmtiError GetImplementedInterfaces(jvmtiEnv* env,
727 jclass klass,
728 jint* interface_count_ptr,
729 jclass** interfaces_ptr) {
730 ENSURE_VALID_ENV(env);
731 return ClassUtil::GetImplementedInterfaces(env, klass, interface_count_ptr, interfaces_ptr);
732 }
733
GetClassVersionNumbers(jvmtiEnv * env,jclass klass,jint * minor_version_ptr,jint * major_version_ptr)734 static jvmtiError GetClassVersionNumbers(jvmtiEnv* env,
735 jclass klass,
736 jint* minor_version_ptr,
737 jint* major_version_ptr) {
738 ENSURE_VALID_ENV(env);
739 return ClassUtil::GetClassVersionNumbers(env, klass, minor_version_ptr, major_version_ptr);
740 }
741
GetConstantPool(jvmtiEnv * env,jclass klass ATTRIBUTE_UNUSED,jint * constant_pool_count_ptr ATTRIBUTE_UNUSED,jint * constant_pool_byte_count_ptr ATTRIBUTE_UNUSED,unsigned char ** constant_pool_bytes_ptr ATTRIBUTE_UNUSED)742 static jvmtiError GetConstantPool(jvmtiEnv* env,
743 jclass klass ATTRIBUTE_UNUSED,
744 jint* constant_pool_count_ptr ATTRIBUTE_UNUSED,
745 jint* constant_pool_byte_count_ptr ATTRIBUTE_UNUSED,
746 unsigned char** constant_pool_bytes_ptr ATTRIBUTE_UNUSED) {
747 ENSURE_VALID_ENV(env);
748 ENSURE_HAS_CAP(env, can_get_constant_pool);
749 return ERR(NOT_IMPLEMENTED);
750 }
751
IsInterface(jvmtiEnv * env,jclass klass,jboolean * is_interface_ptr)752 static jvmtiError IsInterface(jvmtiEnv* env, jclass klass, jboolean* is_interface_ptr) {
753 ENSURE_VALID_ENV(env);
754 return ClassUtil::IsInterface(env, klass, is_interface_ptr);
755 }
756
IsArrayClass(jvmtiEnv * env,jclass klass,jboolean * is_array_class_ptr)757 static jvmtiError IsArrayClass(jvmtiEnv* env,
758 jclass klass,
759 jboolean* is_array_class_ptr) {
760 ENSURE_VALID_ENV(env);
761 return ClassUtil::IsArrayClass(env, klass, is_array_class_ptr);
762 }
763
IsModifiableClass(jvmtiEnv * env,jclass klass,jboolean * is_modifiable_class_ptr)764 static jvmtiError IsModifiableClass(jvmtiEnv* env,
765 jclass klass,
766 jboolean* is_modifiable_class_ptr) {
767 ENSURE_VALID_ENV(env);
768 return Redefiner::IsModifiableClass(env, klass, is_modifiable_class_ptr);
769 }
770
GetClassLoader(jvmtiEnv * env,jclass klass,jobject * classloader_ptr)771 static jvmtiError GetClassLoader(jvmtiEnv* env, jclass klass, jobject* classloader_ptr) {
772 ENSURE_VALID_ENV(env);
773 return ClassUtil::GetClassLoader(env, klass, classloader_ptr);
774 }
775
GetSourceDebugExtension(jvmtiEnv * env,jclass klass ATTRIBUTE_UNUSED,char ** source_debug_extension_ptr ATTRIBUTE_UNUSED)776 static jvmtiError GetSourceDebugExtension(jvmtiEnv* env,
777 jclass klass ATTRIBUTE_UNUSED,
778 char** source_debug_extension_ptr ATTRIBUTE_UNUSED) {
779 ENSURE_VALID_ENV(env);
780 ENSURE_HAS_CAP(env, can_get_source_debug_extension);
781 return ERR(NOT_IMPLEMENTED);
782 }
783
RetransformClasses(jvmtiEnv * env,jint class_count,const jclass * classes)784 static jvmtiError RetransformClasses(jvmtiEnv* env, jint class_count, const jclass* classes) {
785 ENSURE_VALID_ENV(env);
786 ENSURE_HAS_CAP(env, can_retransform_classes);
787 std::string error_msg;
788 jvmtiError res = Transformer::RetransformClasses(ArtJvmTiEnv::AsArtJvmTiEnv(env),
789 &gEventHandler,
790 art::Runtime::Current(),
791 art::Thread::Current(),
792 class_count,
793 classes,
794 &error_msg);
795 if (res != OK) {
796 LOG(WARNING) << "FAILURE TO RETRANFORM " << error_msg;
797 }
798 return res;
799 }
800
RedefineClasses(jvmtiEnv * env,jint class_count,const jvmtiClassDefinition * class_definitions)801 static jvmtiError RedefineClasses(jvmtiEnv* env,
802 jint class_count,
803 const jvmtiClassDefinition* class_definitions) {
804 ENSURE_VALID_ENV(env);
805 ENSURE_HAS_CAP(env, can_redefine_classes);
806 std::string error_msg;
807 jvmtiError res = Redefiner::RedefineClasses(ArtJvmTiEnv::AsArtJvmTiEnv(env),
808 &gEventHandler,
809 art::Runtime::Current(),
810 art::Thread::Current(),
811 class_count,
812 class_definitions,
813 &error_msg);
814 if (res != OK) {
815 LOG(WARNING) << "FAILURE TO REDEFINE " << error_msg;
816 }
817 return res;
818 }
819
GetObjectSize(jvmtiEnv * env,jobject object,jlong * size_ptr)820 static jvmtiError GetObjectSize(jvmtiEnv* env, jobject object, jlong* size_ptr) {
821 ENSURE_VALID_ENV(env);
822 return ObjectUtil::GetObjectSize(env, object, size_ptr);
823 }
824
GetObjectHashCode(jvmtiEnv * env,jobject object,jint * hash_code_ptr)825 static jvmtiError GetObjectHashCode(jvmtiEnv* env, jobject object, jint* hash_code_ptr) {
826 ENSURE_VALID_ENV(env);
827 return ObjectUtil::GetObjectHashCode(env, object, hash_code_ptr);
828 }
829
GetObjectMonitorUsage(jvmtiEnv * env,jobject object ATTRIBUTE_UNUSED,jvmtiMonitorUsage * info_ptr ATTRIBUTE_UNUSED)830 static jvmtiError GetObjectMonitorUsage(jvmtiEnv* env,
831 jobject object ATTRIBUTE_UNUSED,
832 jvmtiMonitorUsage* info_ptr ATTRIBUTE_UNUSED) {
833 ENSURE_VALID_ENV(env);
834 ENSURE_HAS_CAP(env, can_get_monitor_info);
835 return ERR(NOT_IMPLEMENTED);
836 }
837
GetFieldName(jvmtiEnv * env,jclass klass,jfieldID field,char ** name_ptr,char ** signature_ptr,char ** generic_ptr)838 static jvmtiError GetFieldName(jvmtiEnv* env,
839 jclass klass,
840 jfieldID field,
841 char** name_ptr,
842 char** signature_ptr,
843 char** generic_ptr) {
844 ENSURE_VALID_ENV(env);
845 return FieldUtil::GetFieldName(env, klass, field, name_ptr, signature_ptr, generic_ptr);
846 }
847
GetFieldDeclaringClass(jvmtiEnv * env,jclass klass,jfieldID field,jclass * declaring_class_ptr)848 static jvmtiError GetFieldDeclaringClass(jvmtiEnv* env,
849 jclass klass,
850 jfieldID field,
851 jclass* declaring_class_ptr) {
852 ENSURE_VALID_ENV(env);
853 return FieldUtil::GetFieldDeclaringClass(env, klass, field, declaring_class_ptr);
854 }
855
GetFieldModifiers(jvmtiEnv * env,jclass klass,jfieldID field,jint * modifiers_ptr)856 static jvmtiError GetFieldModifiers(jvmtiEnv* env,
857 jclass klass,
858 jfieldID field,
859 jint* modifiers_ptr) {
860 ENSURE_VALID_ENV(env);
861 return FieldUtil::GetFieldModifiers(env, klass, field, modifiers_ptr);
862 }
863
IsFieldSynthetic(jvmtiEnv * env,jclass klass,jfieldID field,jboolean * is_synthetic_ptr)864 static jvmtiError IsFieldSynthetic(jvmtiEnv* env,
865 jclass klass,
866 jfieldID field,
867 jboolean* is_synthetic_ptr) {
868 ENSURE_VALID_ENV(env);
869 ENSURE_HAS_CAP(env, can_get_synthetic_attribute);
870 return FieldUtil::IsFieldSynthetic(env, klass, field, is_synthetic_ptr);
871 }
872
GetMethodName(jvmtiEnv * env,jmethodID method,char ** name_ptr,char ** signature_ptr,char ** generic_ptr)873 static jvmtiError GetMethodName(jvmtiEnv* env,
874 jmethodID method,
875 char** name_ptr,
876 char** signature_ptr,
877 char** generic_ptr) {
878 ENSURE_VALID_ENV(env);
879 return MethodUtil::GetMethodName(env, method, name_ptr, signature_ptr, generic_ptr);
880 }
881
GetMethodDeclaringClass(jvmtiEnv * env,jmethodID method,jclass * declaring_class_ptr)882 static jvmtiError GetMethodDeclaringClass(jvmtiEnv* env,
883 jmethodID method,
884 jclass* declaring_class_ptr) {
885 ENSURE_VALID_ENV(env);
886 return MethodUtil::GetMethodDeclaringClass(env, method, declaring_class_ptr);
887 }
888
GetMethodModifiers(jvmtiEnv * env,jmethodID method,jint * modifiers_ptr)889 static jvmtiError GetMethodModifiers(jvmtiEnv* env,
890 jmethodID method,
891 jint* modifiers_ptr) {
892 ENSURE_VALID_ENV(env);
893 return MethodUtil::GetMethodModifiers(env, method, modifiers_ptr);
894 }
895
GetMaxLocals(jvmtiEnv * env,jmethodID method,jint * max_ptr)896 static jvmtiError GetMaxLocals(jvmtiEnv* env,
897 jmethodID method,
898 jint* max_ptr) {
899 ENSURE_VALID_ENV(env);
900 return MethodUtil::GetMaxLocals(env, method, max_ptr);
901 }
902
GetArgumentsSize(jvmtiEnv * env,jmethodID method,jint * size_ptr)903 static jvmtiError GetArgumentsSize(jvmtiEnv* env,
904 jmethodID method,
905 jint* size_ptr) {
906 ENSURE_VALID_ENV(env);
907 return MethodUtil::GetArgumentsSize(env, method, size_ptr);
908 }
909
GetLineNumberTable(jvmtiEnv * env,jmethodID method,jint * entry_count_ptr,jvmtiLineNumberEntry ** table_ptr)910 static jvmtiError GetLineNumberTable(jvmtiEnv* env,
911 jmethodID method,
912 jint* entry_count_ptr,
913 jvmtiLineNumberEntry** table_ptr) {
914 ENSURE_VALID_ENV(env);
915 ENSURE_HAS_CAP(env, can_get_line_numbers);
916 return MethodUtil::GetLineNumberTable(env, method, entry_count_ptr, table_ptr);
917 }
918
GetMethodLocation(jvmtiEnv * env,jmethodID method,jlocation * start_location_ptr,jlocation * end_location_ptr)919 static jvmtiError GetMethodLocation(jvmtiEnv* env,
920 jmethodID method,
921 jlocation* start_location_ptr,
922 jlocation* end_location_ptr) {
923 ENSURE_VALID_ENV(env);
924 return MethodUtil::GetMethodLocation(env, method, start_location_ptr, end_location_ptr);
925 }
926
GetLocalVariableTable(jvmtiEnv * env,jmethodID method ATTRIBUTE_UNUSED,jint * entry_count_ptr ATTRIBUTE_UNUSED,jvmtiLocalVariableEntry ** table_ptr ATTRIBUTE_UNUSED)927 static jvmtiError GetLocalVariableTable(jvmtiEnv* env,
928 jmethodID method ATTRIBUTE_UNUSED,
929 jint* entry_count_ptr ATTRIBUTE_UNUSED,
930 jvmtiLocalVariableEntry** table_ptr ATTRIBUTE_UNUSED) {
931 ENSURE_VALID_ENV(env);
932 ENSURE_HAS_CAP(env, can_access_local_variables);
933 return ERR(NOT_IMPLEMENTED);
934 }
935
GetBytecodes(jvmtiEnv * env,jmethodID method ATTRIBUTE_UNUSED,jint * bytecode_count_ptr ATTRIBUTE_UNUSED,unsigned char ** bytecodes_ptr ATTRIBUTE_UNUSED)936 static jvmtiError GetBytecodes(jvmtiEnv* env,
937 jmethodID method ATTRIBUTE_UNUSED,
938 jint* bytecode_count_ptr ATTRIBUTE_UNUSED,
939 unsigned char** bytecodes_ptr ATTRIBUTE_UNUSED) {
940 ENSURE_VALID_ENV(env);
941 ENSURE_HAS_CAP(env, can_get_bytecodes);
942 return ERR(NOT_IMPLEMENTED);
943 }
944
IsMethodNative(jvmtiEnv * env,jmethodID method,jboolean * is_native_ptr)945 static jvmtiError IsMethodNative(jvmtiEnv* env, jmethodID method, jboolean* is_native_ptr) {
946 ENSURE_VALID_ENV(env);
947 return MethodUtil::IsMethodNative(env, method, is_native_ptr);
948 }
949
IsMethodSynthetic(jvmtiEnv * env,jmethodID method,jboolean * is_synthetic_ptr)950 static jvmtiError IsMethodSynthetic(jvmtiEnv* env, jmethodID method, jboolean* is_synthetic_ptr) {
951 ENSURE_VALID_ENV(env);
952 ENSURE_HAS_CAP(env, can_get_synthetic_attribute);
953 return MethodUtil::IsMethodSynthetic(env, method, is_synthetic_ptr);
954 }
955
IsMethodObsolete(jvmtiEnv * env,jmethodID method,jboolean * is_obsolete_ptr)956 static jvmtiError IsMethodObsolete(jvmtiEnv* env, jmethodID method, jboolean* is_obsolete_ptr) {
957 ENSURE_VALID_ENV(env);
958 return MethodUtil::IsMethodObsolete(env, method, is_obsolete_ptr);
959 }
960
SetNativeMethodPrefix(jvmtiEnv * env,const char * prefix ATTRIBUTE_UNUSED)961 static jvmtiError SetNativeMethodPrefix(jvmtiEnv* env, const char* prefix ATTRIBUTE_UNUSED) {
962 ENSURE_VALID_ENV(env);
963 ENSURE_HAS_CAP(env, can_set_native_method_prefix);
964 return ERR(NOT_IMPLEMENTED);
965 }
966
SetNativeMethodPrefixes(jvmtiEnv * env,jint prefix_count ATTRIBUTE_UNUSED,char ** prefixes ATTRIBUTE_UNUSED)967 static jvmtiError SetNativeMethodPrefixes(jvmtiEnv* env,
968 jint prefix_count ATTRIBUTE_UNUSED,
969 char** prefixes ATTRIBUTE_UNUSED) {
970 ENSURE_VALID_ENV(env);
971 ENSURE_HAS_CAP(env, can_set_native_method_prefix);
972 return ERR(NOT_IMPLEMENTED);
973 }
974
CreateRawMonitor(jvmtiEnv * env,const char * name,jrawMonitorID * monitor_ptr)975 static jvmtiError CreateRawMonitor(jvmtiEnv* env, const char* name, jrawMonitorID* monitor_ptr) {
976 ENSURE_VALID_ENV(env);
977 return MonitorUtil::CreateRawMonitor(env, name, monitor_ptr);
978 }
979
DestroyRawMonitor(jvmtiEnv * env,jrawMonitorID monitor)980 static jvmtiError DestroyRawMonitor(jvmtiEnv* env, jrawMonitorID monitor) {
981 ENSURE_VALID_ENV(env);
982 return MonitorUtil::DestroyRawMonitor(env, monitor);
983 }
984
RawMonitorEnter(jvmtiEnv * env,jrawMonitorID monitor)985 static jvmtiError RawMonitorEnter(jvmtiEnv* env, jrawMonitorID monitor) {
986 ENSURE_VALID_ENV(env);
987 return MonitorUtil::RawMonitorEnter(env, monitor);
988 }
989
RawMonitorExit(jvmtiEnv * env,jrawMonitorID monitor)990 static jvmtiError RawMonitorExit(jvmtiEnv* env, jrawMonitorID monitor) {
991 ENSURE_VALID_ENV(env);
992 return MonitorUtil::RawMonitorExit(env, monitor);
993 }
994
RawMonitorWait(jvmtiEnv * env,jrawMonitorID monitor,jlong millis)995 static jvmtiError RawMonitorWait(jvmtiEnv* env, jrawMonitorID monitor, jlong millis) {
996 ENSURE_VALID_ENV(env);
997 return MonitorUtil::RawMonitorWait(env, monitor, millis);
998 }
999
RawMonitorNotify(jvmtiEnv * env,jrawMonitorID monitor)1000 static jvmtiError RawMonitorNotify(jvmtiEnv* env, jrawMonitorID monitor) {
1001 ENSURE_VALID_ENV(env);
1002 return MonitorUtil::RawMonitorNotify(env, monitor);
1003 }
1004
RawMonitorNotifyAll(jvmtiEnv * env,jrawMonitorID monitor)1005 static jvmtiError RawMonitorNotifyAll(jvmtiEnv* env, jrawMonitorID monitor) {
1006 ENSURE_VALID_ENV(env);
1007 return MonitorUtil::RawMonitorNotifyAll(env, monitor);
1008 }
1009
SetJNIFunctionTable(jvmtiEnv * env,const jniNativeInterface * function_table)1010 static jvmtiError SetJNIFunctionTable(jvmtiEnv* env, const jniNativeInterface* function_table) {
1011 ENSURE_VALID_ENV(env);
1012 return JNIUtil::SetJNIFunctionTable(env, function_table);
1013 }
1014
GetJNIFunctionTable(jvmtiEnv * env,jniNativeInterface ** function_table)1015 static jvmtiError GetJNIFunctionTable(jvmtiEnv* env, jniNativeInterface** function_table) {
1016 ENSURE_VALID_ENV(env);
1017 return JNIUtil::GetJNIFunctionTable(env, function_table);
1018 }
1019
1020 // TODO: This will require locking, so that an agent can't remove callbacks when we're dispatching
1021 // an event.
SetEventCallbacks(jvmtiEnv * env,const jvmtiEventCallbacks * callbacks,jint size_of_callbacks)1022 static jvmtiError SetEventCallbacks(jvmtiEnv* env,
1023 const jvmtiEventCallbacks* callbacks,
1024 jint size_of_callbacks) {
1025 ENSURE_VALID_ENV(env);
1026 if (size_of_callbacks < 0) {
1027 return ERR(ILLEGAL_ARGUMENT);
1028 }
1029
1030 if (callbacks == nullptr) {
1031 ArtJvmTiEnv::AsArtJvmTiEnv(env)->event_callbacks.reset();
1032 return ERR(NONE);
1033 }
1034
1035 std::unique_ptr<jvmtiEventCallbacks> tmp(new jvmtiEventCallbacks());
1036 memset(tmp.get(), 0, sizeof(jvmtiEventCallbacks));
1037 size_t copy_size = std::min(sizeof(jvmtiEventCallbacks),
1038 static_cast<size_t>(size_of_callbacks));
1039 copy_size = art::RoundDown(copy_size, sizeof(void*));
1040 memcpy(tmp.get(), callbacks, copy_size);
1041
1042 ArtJvmTiEnv::AsArtJvmTiEnv(env)->event_callbacks = std::move(tmp);
1043
1044 return ERR(NONE);
1045 }
1046
SetEventNotificationMode(jvmtiEnv * env,jvmtiEventMode mode,jvmtiEvent event_type,jthread event_thread,...)1047 static jvmtiError SetEventNotificationMode(jvmtiEnv* env,
1048 jvmtiEventMode mode,
1049 jvmtiEvent event_type,
1050 jthread event_thread,
1051 ...) {
1052 ENSURE_VALID_ENV(env);
1053 art::Thread* art_thread = nullptr;
1054 if (event_thread != nullptr) {
1055 // TODO: Need non-aborting call here, to return JVMTI_ERROR_INVALID_THREAD.
1056 art::ScopedObjectAccess soa(art::Thread::Current());
1057 art::MutexLock mu(soa.Self(), *art::Locks::thread_list_lock_);
1058 art_thread = art::Thread::FromManagedThread(soa, event_thread);
1059
1060 if (art_thread == nullptr || // The thread hasn't been started or is already dead.
1061 art_thread->IsStillStarting()) {
1062 // TODO: We may want to let the EventHandler know, so it could clean up masks, potentially.
1063 return ERR(THREAD_NOT_ALIVE);
1064 }
1065 }
1066
1067 ArtJvmTiEnv* art_env = ArtJvmTiEnv::AsArtJvmTiEnv(env);
1068 return gEventHandler.SetEvent(art_env, art_thread, GetArtJvmtiEvent(art_env, event_type), mode);
1069 }
1070
GenerateEvents(jvmtiEnv * env,jvmtiEvent event_type ATTRIBUTE_UNUSED)1071 static jvmtiError GenerateEvents(jvmtiEnv* env,
1072 jvmtiEvent event_type ATTRIBUTE_UNUSED) {
1073 ENSURE_VALID_ENV(env);
1074 return OK;
1075 }
1076
GetExtensionFunctions(jvmtiEnv * env,jint * extension_count_ptr,jvmtiExtensionFunctionInfo ** extensions)1077 static jvmtiError GetExtensionFunctions(jvmtiEnv* env,
1078 jint* extension_count_ptr,
1079 jvmtiExtensionFunctionInfo** extensions) {
1080 ENSURE_VALID_ENV(env);
1081 ENSURE_NON_NULL(extension_count_ptr);
1082 ENSURE_NON_NULL(extensions);
1083
1084 std::vector<jvmtiExtensionFunctionInfo> ext_vector;
1085
1086 // Holders for allocated values.
1087 std::vector<JvmtiUniquePtr<char[]>> char_buffers;
1088 std::vector<JvmtiUniquePtr<jvmtiParamInfo[]>> param_buffers;
1089 std::vector<JvmtiUniquePtr<jvmtiError[]>> error_buffers;
1090
1091 // Add a helper struct that takes an arbitrary const char*. add_extension will use Allocate
1092 // appropriately.
1093 struct CParamInfo {
1094 const char* name;
1095 jvmtiParamKind kind;
1096 jvmtiParamTypes base_type;
1097 jboolean null_ok;
1098 };
1099
1100 auto add_extension = [&](jvmtiExtensionFunction func,
1101 const char* id,
1102 const char* short_description,
1103 jint param_count,
1104 const std::vector<CParamInfo>& params,
1105 jint error_count,
1106 const std::vector<jvmtiError>& errors) {
1107 jvmtiExtensionFunctionInfo func_info;
1108 jvmtiError error;
1109
1110 func_info.func = func;
1111
1112 JvmtiUniquePtr<char[]> id_ptr = CopyString(env, id, &error);
1113 if (id_ptr == nullptr) {
1114 return error;
1115 }
1116 func_info.id = id_ptr.get();
1117 char_buffers.push_back(std::move(id_ptr));
1118
1119 JvmtiUniquePtr<char[]> descr = CopyString(env, short_description, &error);
1120 if (descr == nullptr) {
1121 return error;
1122 }
1123 func_info.short_description = descr.get();
1124 char_buffers.push_back(std::move(descr));
1125
1126 func_info.param_count = param_count;
1127 if (param_count > 0) {
1128 JvmtiUniquePtr<jvmtiParamInfo[]> params_ptr =
1129 AllocJvmtiUniquePtr<jvmtiParamInfo[]>(env, param_count, &error);
1130 if (params_ptr == nullptr) {
1131 return error;
1132 }
1133 func_info.params = params_ptr.get();
1134 param_buffers.push_back(std::move(params_ptr));
1135
1136 for (jint i = 0; i != param_count; ++i) {
1137 JvmtiUniquePtr<char[]> param_name = CopyString(env, params[i].name, &error);
1138 if (param_name == nullptr) {
1139 return error;
1140 }
1141 func_info.params[i].name = param_name.get();
1142 char_buffers.push_back(std::move(param_name));
1143
1144 func_info.params[i].kind = params[i].kind;
1145 func_info.params[i].base_type = params[i].base_type;
1146 func_info.params[i].null_ok = params[i].null_ok;
1147 }
1148 } else {
1149 func_info.params = nullptr;
1150 }
1151
1152 func_info.error_count = error_count;
1153 if (error_count > 0) {
1154 JvmtiUniquePtr<jvmtiError[]> errors_ptr =
1155 AllocJvmtiUniquePtr<jvmtiError[]>(env, error_count, &error);
1156 if (errors_ptr == nullptr) {
1157 return error;
1158 }
1159 func_info.errors = errors_ptr.get();
1160 error_buffers.push_back(std::move(errors_ptr));
1161
1162 for (jint i = 0; i != error_count; ++i) {
1163 func_info.errors[i] = errors[i];
1164 }
1165 } else {
1166 func_info.errors = nullptr;
1167 }
1168
1169 ext_vector.push_back(func_info);
1170
1171 return ERR(NONE);
1172 };
1173
1174 jvmtiError error;
1175
1176 // Heap extensions.
1177 error = add_extension(
1178 reinterpret_cast<jvmtiExtensionFunction>(HeapExtensions::GetObjectHeapId),
1179 "com.android.art.heap.get_object_heap_id",
1180 "Retrieve the heap id of the the object tagged with the given argument. An "
1181 "arbitrary object is chosen if multiple objects exist with the same tag.",
1182 2,
1183 { // NOLINT [whitespace/braces] [4]
1184 { "tag", JVMTI_KIND_IN, JVMTI_TYPE_JLONG, false},
1185 { "heap_id", JVMTI_KIND_OUT, JVMTI_TYPE_JINT, false}
1186 },
1187 1,
1188 { JVMTI_ERROR_NOT_FOUND });
1189 if (error != ERR(NONE)) {
1190 return error;
1191 }
1192
1193 error = add_extension(
1194 reinterpret_cast<jvmtiExtensionFunction>(HeapExtensions::GetHeapName),
1195 "com.android.art.heap.get_heap_name",
1196 "Retrieve the name of the heap with the given id.",
1197 2,
1198 { // NOLINT [whitespace/braces] [4]
1199 { "heap_id", JVMTI_KIND_IN, JVMTI_TYPE_JINT, false},
1200 { "heap_name", JVMTI_KIND_ALLOC_BUF, JVMTI_TYPE_CCHAR, false}
1201 },
1202 1,
1203 { JVMTI_ERROR_ILLEGAL_ARGUMENT });
1204 if (error != ERR(NONE)) {
1205 return error;
1206 }
1207
1208 error = add_extension(
1209 reinterpret_cast<jvmtiExtensionFunction>(HeapExtensions::IterateThroughHeapExt),
1210 "com.android.art.heap.iterate_through_heap_ext",
1211 "Iterate through a heap. This is equivalent to the standard IterateThroughHeap function,"
1212 " except for additionally passing the heap id of the current object. The jvmtiHeapCallbacks"
1213 " structure is reused, with the callbacks field overloaded to a signature of "
1214 "jint (*)(jlong, jlong, jlong*, jint length, void*, jint).",
1215 4,
1216 { // NOLINT [whitespace/braces] [4]
1217 { "heap_filter", JVMTI_KIND_IN, JVMTI_TYPE_JINT, false},
1218 { "klass", JVMTI_KIND_IN, JVMTI_TYPE_JCLASS, true},
1219 { "callbacks", JVMTI_KIND_IN_PTR, JVMTI_TYPE_CVOID, false},
1220 { "user_data", JVMTI_KIND_IN_PTR, JVMTI_TYPE_CVOID, true}
1221 },
1222 3,
1223 { // NOLINT [whitespace/braces] [4]
1224 JVMTI_ERROR_MUST_POSSESS_CAPABILITY,
1225 JVMTI_ERROR_INVALID_CLASS,
1226 JVMTI_ERROR_NULL_POINTER
1227 });
1228 if (error != ERR(NONE)) {
1229 return error;
1230 }
1231
1232 // Copy into output buffer.
1233
1234 *extension_count_ptr = ext_vector.size();
1235 JvmtiUniquePtr<jvmtiExtensionFunctionInfo[]> out_data =
1236 AllocJvmtiUniquePtr<jvmtiExtensionFunctionInfo[]>(env, ext_vector.size(), &error);
1237 if (out_data == nullptr) {
1238 return error;
1239 }
1240 memcpy(out_data.get(),
1241 ext_vector.data(),
1242 ext_vector.size() * sizeof(jvmtiExtensionFunctionInfo));
1243 *extensions = out_data.release();
1244
1245 // Release all the buffer holders, we're OK now.
1246 for (auto& holder : char_buffers) {
1247 holder.release();
1248 }
1249 for (auto& holder : param_buffers) {
1250 holder.release();
1251 }
1252 for (auto& holder : error_buffers) {
1253 holder.release();
1254 }
1255
1256 return ERR(NONE);
1257 }
1258
GetExtensionEvents(jvmtiEnv * env,jint * extension_count_ptr,jvmtiExtensionEventInfo ** extensions)1259 static jvmtiError GetExtensionEvents(jvmtiEnv* env,
1260 jint* extension_count_ptr,
1261 jvmtiExtensionEventInfo** extensions) {
1262 ENSURE_VALID_ENV(env);
1263 // We do not have any extension events.
1264 *extension_count_ptr = 0;
1265 *extensions = nullptr;
1266
1267 return ERR(NONE);
1268 }
1269
SetExtensionEventCallback(jvmtiEnv * env,jint extension_event_index ATTRIBUTE_UNUSED,jvmtiExtensionEvent callback ATTRIBUTE_UNUSED)1270 static jvmtiError SetExtensionEventCallback(jvmtiEnv* env,
1271 jint extension_event_index ATTRIBUTE_UNUSED,
1272 jvmtiExtensionEvent callback ATTRIBUTE_UNUSED) {
1273 ENSURE_VALID_ENV(env);
1274 // We do not have any extension events, so any call is illegal.
1275 return ERR(ILLEGAL_ARGUMENT);
1276 }
1277
GetPotentialCapabilities(jvmtiEnv * env,jvmtiCapabilities * capabilities_ptr)1278 static jvmtiError GetPotentialCapabilities(jvmtiEnv* env, jvmtiCapabilities* capabilities_ptr) {
1279 ENSURE_VALID_ENV(env);
1280 ENSURE_NON_NULL(capabilities_ptr);
1281 *capabilities_ptr = kPotentialCapabilities;
1282 return OK;
1283 }
1284
AddCapabilities(jvmtiEnv * env,const jvmtiCapabilities * capabilities_ptr)1285 static jvmtiError AddCapabilities(jvmtiEnv* env, const jvmtiCapabilities* capabilities_ptr) {
1286 ENSURE_VALID_ENV(env);
1287 ENSURE_NON_NULL(capabilities_ptr);
1288 ArtJvmTiEnv* art_env = static_cast<ArtJvmTiEnv*>(env);
1289 jvmtiError ret = OK;
1290 jvmtiCapabilities changed = {};
1291 jvmtiCapabilities potential_capabilities = {};
1292 ret = env->GetPotentialCapabilities(&potential_capabilities);
1293 if (ret != OK) {
1294 return ret;
1295 }
1296 #define ADD_CAPABILITY(e) \
1297 do { \
1298 if (capabilities_ptr->e == 1) { \
1299 if (potential_capabilities.e == 1) { \
1300 if (art_env->capabilities.e != 1) { \
1301 art_env->capabilities.e = 1; \
1302 changed.e = 1; \
1303 }\
1304 } else { \
1305 ret = ERR(NOT_AVAILABLE); \
1306 } \
1307 } \
1308 } while (false)
1309
1310 ADD_CAPABILITY(can_tag_objects);
1311 ADD_CAPABILITY(can_generate_field_modification_events);
1312 ADD_CAPABILITY(can_generate_field_access_events);
1313 ADD_CAPABILITY(can_get_bytecodes);
1314 ADD_CAPABILITY(can_get_synthetic_attribute);
1315 ADD_CAPABILITY(can_get_owned_monitor_info);
1316 ADD_CAPABILITY(can_get_current_contended_monitor);
1317 ADD_CAPABILITY(can_get_monitor_info);
1318 ADD_CAPABILITY(can_pop_frame);
1319 ADD_CAPABILITY(can_redefine_classes);
1320 ADD_CAPABILITY(can_signal_thread);
1321 ADD_CAPABILITY(can_get_source_file_name);
1322 ADD_CAPABILITY(can_get_line_numbers);
1323 ADD_CAPABILITY(can_get_source_debug_extension);
1324 ADD_CAPABILITY(can_access_local_variables);
1325 ADD_CAPABILITY(can_maintain_original_method_order);
1326 ADD_CAPABILITY(can_generate_single_step_events);
1327 ADD_CAPABILITY(can_generate_exception_events);
1328 ADD_CAPABILITY(can_generate_frame_pop_events);
1329 ADD_CAPABILITY(can_generate_breakpoint_events);
1330 ADD_CAPABILITY(can_suspend);
1331 ADD_CAPABILITY(can_redefine_any_class);
1332 ADD_CAPABILITY(can_get_current_thread_cpu_time);
1333 ADD_CAPABILITY(can_get_thread_cpu_time);
1334 ADD_CAPABILITY(can_generate_method_entry_events);
1335 ADD_CAPABILITY(can_generate_method_exit_events);
1336 ADD_CAPABILITY(can_generate_all_class_hook_events);
1337 ADD_CAPABILITY(can_generate_compiled_method_load_events);
1338 ADD_CAPABILITY(can_generate_monitor_events);
1339 ADD_CAPABILITY(can_generate_vm_object_alloc_events);
1340 ADD_CAPABILITY(can_generate_native_method_bind_events);
1341 ADD_CAPABILITY(can_generate_garbage_collection_events);
1342 ADD_CAPABILITY(can_generate_object_free_events);
1343 ADD_CAPABILITY(can_force_early_return);
1344 ADD_CAPABILITY(can_get_owned_monitor_stack_depth_info);
1345 ADD_CAPABILITY(can_get_constant_pool);
1346 ADD_CAPABILITY(can_set_native_method_prefix);
1347 ADD_CAPABILITY(can_retransform_classes);
1348 ADD_CAPABILITY(can_retransform_any_class);
1349 ADD_CAPABILITY(can_generate_resource_exhaustion_heap_events);
1350 ADD_CAPABILITY(can_generate_resource_exhaustion_threads_events);
1351 #undef ADD_CAPABILITY
1352 gEventHandler.HandleChangedCapabilities(ArtJvmTiEnv::AsArtJvmTiEnv(env),
1353 changed,
1354 /*added*/true);
1355 return ret;
1356 }
1357
RelinquishCapabilities(jvmtiEnv * env,const jvmtiCapabilities * capabilities_ptr)1358 static jvmtiError RelinquishCapabilities(jvmtiEnv* env,
1359 const jvmtiCapabilities* capabilities_ptr) {
1360 ENSURE_VALID_ENV(env);
1361 ENSURE_NON_NULL(capabilities_ptr);
1362 ArtJvmTiEnv* art_env = reinterpret_cast<ArtJvmTiEnv*>(env);
1363 jvmtiCapabilities changed = {};
1364 #define DEL_CAPABILITY(e) \
1365 do { \
1366 if (capabilities_ptr->e == 1) { \
1367 if (art_env->capabilities.e == 1) { \
1368 art_env->capabilities.e = 0;\
1369 changed.e = 1; \
1370 } \
1371 } \
1372 } while (false)
1373
1374 DEL_CAPABILITY(can_tag_objects);
1375 DEL_CAPABILITY(can_generate_field_modification_events);
1376 DEL_CAPABILITY(can_generate_field_access_events);
1377 DEL_CAPABILITY(can_get_bytecodes);
1378 DEL_CAPABILITY(can_get_synthetic_attribute);
1379 DEL_CAPABILITY(can_get_owned_monitor_info);
1380 DEL_CAPABILITY(can_get_current_contended_monitor);
1381 DEL_CAPABILITY(can_get_monitor_info);
1382 DEL_CAPABILITY(can_pop_frame);
1383 DEL_CAPABILITY(can_redefine_classes);
1384 DEL_CAPABILITY(can_signal_thread);
1385 DEL_CAPABILITY(can_get_source_file_name);
1386 DEL_CAPABILITY(can_get_line_numbers);
1387 DEL_CAPABILITY(can_get_source_debug_extension);
1388 DEL_CAPABILITY(can_access_local_variables);
1389 DEL_CAPABILITY(can_maintain_original_method_order);
1390 DEL_CAPABILITY(can_generate_single_step_events);
1391 DEL_CAPABILITY(can_generate_exception_events);
1392 DEL_CAPABILITY(can_generate_frame_pop_events);
1393 DEL_CAPABILITY(can_generate_breakpoint_events);
1394 DEL_CAPABILITY(can_suspend);
1395 DEL_CAPABILITY(can_redefine_any_class);
1396 DEL_CAPABILITY(can_get_current_thread_cpu_time);
1397 DEL_CAPABILITY(can_get_thread_cpu_time);
1398 DEL_CAPABILITY(can_generate_method_entry_events);
1399 DEL_CAPABILITY(can_generate_method_exit_events);
1400 DEL_CAPABILITY(can_generate_all_class_hook_events);
1401 DEL_CAPABILITY(can_generate_compiled_method_load_events);
1402 DEL_CAPABILITY(can_generate_monitor_events);
1403 DEL_CAPABILITY(can_generate_vm_object_alloc_events);
1404 DEL_CAPABILITY(can_generate_native_method_bind_events);
1405 DEL_CAPABILITY(can_generate_garbage_collection_events);
1406 DEL_CAPABILITY(can_generate_object_free_events);
1407 DEL_CAPABILITY(can_force_early_return);
1408 DEL_CAPABILITY(can_get_owned_monitor_stack_depth_info);
1409 DEL_CAPABILITY(can_get_constant_pool);
1410 DEL_CAPABILITY(can_set_native_method_prefix);
1411 DEL_CAPABILITY(can_retransform_classes);
1412 DEL_CAPABILITY(can_retransform_any_class);
1413 DEL_CAPABILITY(can_generate_resource_exhaustion_heap_events);
1414 DEL_CAPABILITY(can_generate_resource_exhaustion_threads_events);
1415 #undef DEL_CAPABILITY
1416 gEventHandler.HandleChangedCapabilities(ArtJvmTiEnv::AsArtJvmTiEnv(env),
1417 changed,
1418 /*added*/false);
1419 return OK;
1420 }
1421
GetCapabilities(jvmtiEnv * env,jvmtiCapabilities * capabilities_ptr)1422 static jvmtiError GetCapabilities(jvmtiEnv* env, jvmtiCapabilities* capabilities_ptr) {
1423 ENSURE_VALID_ENV(env);
1424 ENSURE_NON_NULL(capabilities_ptr);
1425 ArtJvmTiEnv* artenv = reinterpret_cast<ArtJvmTiEnv*>(env);
1426 *capabilities_ptr = artenv->capabilities;
1427 return OK;
1428 }
1429
GetCurrentThreadCpuTimerInfo(jvmtiEnv * env,jvmtiTimerInfo * info_ptr ATTRIBUTE_UNUSED)1430 static jvmtiError GetCurrentThreadCpuTimerInfo(jvmtiEnv* env,
1431 jvmtiTimerInfo* info_ptr ATTRIBUTE_UNUSED) {
1432 ENSURE_VALID_ENV(env);
1433 ENSURE_HAS_CAP(env, can_get_current_thread_cpu_time);
1434 return ERR(NOT_IMPLEMENTED);
1435 }
1436
GetCurrentThreadCpuTime(jvmtiEnv * env,jlong * nanos_ptr ATTRIBUTE_UNUSED)1437 static jvmtiError GetCurrentThreadCpuTime(jvmtiEnv* env, jlong* nanos_ptr ATTRIBUTE_UNUSED) {
1438 ENSURE_VALID_ENV(env);
1439 ENSURE_HAS_CAP(env, can_get_current_thread_cpu_time);
1440 return ERR(NOT_IMPLEMENTED);
1441 }
1442
GetThreadCpuTimerInfo(jvmtiEnv * env,jvmtiTimerInfo * info_ptr ATTRIBUTE_UNUSED)1443 static jvmtiError GetThreadCpuTimerInfo(jvmtiEnv* env,
1444 jvmtiTimerInfo* info_ptr ATTRIBUTE_UNUSED) {
1445 ENSURE_VALID_ENV(env);
1446 ENSURE_HAS_CAP(env, can_get_thread_cpu_time);
1447 return ERR(NOT_IMPLEMENTED);
1448 }
1449
GetThreadCpuTime(jvmtiEnv * env,jthread thread ATTRIBUTE_UNUSED,jlong * nanos_ptr ATTRIBUTE_UNUSED)1450 static jvmtiError GetThreadCpuTime(jvmtiEnv* env,
1451 jthread thread ATTRIBUTE_UNUSED,
1452 jlong* nanos_ptr ATTRIBUTE_UNUSED) {
1453 ENSURE_VALID_ENV(env);
1454 ENSURE_HAS_CAP(env, can_get_thread_cpu_time);
1455 return ERR(NOT_IMPLEMENTED);
1456 }
1457
GetTimerInfo(jvmtiEnv * env,jvmtiTimerInfo * info_ptr)1458 static jvmtiError GetTimerInfo(jvmtiEnv* env, jvmtiTimerInfo* info_ptr) {
1459 ENSURE_VALID_ENV(env);
1460 return TimerUtil::GetTimerInfo(env, info_ptr);
1461 }
1462
GetTime(jvmtiEnv * env,jlong * nanos_ptr)1463 static jvmtiError GetTime(jvmtiEnv* env, jlong* nanos_ptr) {
1464 ENSURE_VALID_ENV(env);
1465 return TimerUtil::GetTime(env, nanos_ptr);
1466 }
1467
GetAvailableProcessors(jvmtiEnv * env,jint * processor_count_ptr)1468 static jvmtiError GetAvailableProcessors(jvmtiEnv* env, jint* processor_count_ptr) {
1469 ENSURE_VALID_ENV(env);
1470 return TimerUtil::GetAvailableProcessors(env, processor_count_ptr);
1471 }
1472
AddToBootstrapClassLoaderSearch(jvmtiEnv * env,const char * segment)1473 static jvmtiError AddToBootstrapClassLoaderSearch(jvmtiEnv* env, const char* segment) {
1474 ENSURE_VALID_ENV(env);
1475 return SearchUtil::AddToBootstrapClassLoaderSearch(env, segment);
1476 }
1477
AddToSystemClassLoaderSearch(jvmtiEnv * env,const char * segment)1478 static jvmtiError AddToSystemClassLoaderSearch(jvmtiEnv* env, const char* segment) {
1479 ENSURE_VALID_ENV(env);
1480 return SearchUtil::AddToSystemClassLoaderSearch(env, segment);
1481 }
1482
GetSystemProperties(jvmtiEnv * env,jint * count_ptr,char *** property_ptr)1483 static jvmtiError GetSystemProperties(jvmtiEnv* env, jint* count_ptr, char*** property_ptr) {
1484 ENSURE_VALID_ENV(env);
1485 return PropertiesUtil::GetSystemProperties(env, count_ptr, property_ptr);
1486 }
1487
GetSystemProperty(jvmtiEnv * env,const char * property,char ** value_ptr)1488 static jvmtiError GetSystemProperty(jvmtiEnv* env, const char* property, char** value_ptr) {
1489 ENSURE_VALID_ENV(env);
1490 return PropertiesUtil::GetSystemProperty(env, property, value_ptr);
1491 }
1492
SetSystemProperty(jvmtiEnv * env,const char * property,const char * value)1493 static jvmtiError SetSystemProperty(jvmtiEnv* env, const char* property, const char* value) {
1494 ENSURE_VALID_ENV(env);
1495 return PropertiesUtil::SetSystemProperty(env, property, value);
1496 }
1497
GetPhase(jvmtiEnv * env,jvmtiPhase * phase_ptr)1498 static jvmtiError GetPhase(jvmtiEnv* env, jvmtiPhase* phase_ptr) {
1499 ENSURE_VALID_ENV(env);
1500 return PhaseUtil::GetPhase(env, phase_ptr);
1501 }
1502
DisposeEnvironment(jvmtiEnv * env)1503 static jvmtiError DisposeEnvironment(jvmtiEnv* env) {
1504 ENSURE_VALID_ENV(env);
1505 gEventHandler.RemoveArtJvmTiEnv(ArtJvmTiEnv::AsArtJvmTiEnv(env));
1506 art::Runtime::Current()->RemoveSystemWeakHolder(
1507 ArtJvmTiEnv::AsArtJvmTiEnv(env)->object_tag_table.get());
1508 delete env;
1509 return OK;
1510 }
1511
SetEnvironmentLocalStorage(jvmtiEnv * env,const void * data)1512 static jvmtiError SetEnvironmentLocalStorage(jvmtiEnv* env, const void* data) {
1513 ENSURE_VALID_ENV(env);
1514 reinterpret_cast<ArtJvmTiEnv*>(env)->local_data = const_cast<void*>(data);
1515 return OK;
1516 }
1517
GetEnvironmentLocalStorage(jvmtiEnv * env,void ** data_ptr)1518 static jvmtiError GetEnvironmentLocalStorage(jvmtiEnv* env, void** data_ptr) {
1519 ENSURE_VALID_ENV(env);
1520 *data_ptr = reinterpret_cast<ArtJvmTiEnv*>(env)->local_data;
1521 return OK;
1522 }
1523
GetVersionNumber(jvmtiEnv * env,jint * version_ptr)1524 static jvmtiError GetVersionNumber(jvmtiEnv* env, jint* version_ptr) {
1525 ENSURE_VALID_ENV(env);
1526 *version_ptr = JVMTI_VERSION;
1527 return OK;
1528 }
1529
GetErrorName(jvmtiEnv * env,jvmtiError error,char ** name_ptr)1530 static jvmtiError GetErrorName(jvmtiEnv* env, jvmtiError error, char** name_ptr) {
1531 ENSURE_NON_NULL(name_ptr);
1532 auto copy_fn = [&](const char* name_cstr) {
1533 jvmtiError res;
1534 JvmtiUniquePtr<char[]> copy = CopyString(env, name_cstr, &res);
1535 if (copy == nullptr) {
1536 *name_ptr = nullptr;
1537 return res;
1538 } else {
1539 *name_ptr = copy.release();
1540 return OK;
1541 }
1542 };
1543 switch (error) {
1544 #define ERROR_CASE(e) case (JVMTI_ERROR_ ## e) : \
1545 return copy_fn("JVMTI_ERROR_"#e);
1546 ERROR_CASE(NONE);
1547 ERROR_CASE(INVALID_THREAD);
1548 ERROR_CASE(INVALID_THREAD_GROUP);
1549 ERROR_CASE(INVALID_PRIORITY);
1550 ERROR_CASE(THREAD_NOT_SUSPENDED);
1551 ERROR_CASE(THREAD_SUSPENDED);
1552 ERROR_CASE(THREAD_NOT_ALIVE);
1553 ERROR_CASE(INVALID_OBJECT);
1554 ERROR_CASE(INVALID_CLASS);
1555 ERROR_CASE(CLASS_NOT_PREPARED);
1556 ERROR_CASE(INVALID_METHODID);
1557 ERROR_CASE(INVALID_LOCATION);
1558 ERROR_CASE(INVALID_FIELDID);
1559 ERROR_CASE(NO_MORE_FRAMES);
1560 ERROR_CASE(OPAQUE_FRAME);
1561 ERROR_CASE(TYPE_MISMATCH);
1562 ERROR_CASE(INVALID_SLOT);
1563 ERROR_CASE(DUPLICATE);
1564 ERROR_CASE(NOT_FOUND);
1565 ERROR_CASE(INVALID_MONITOR);
1566 ERROR_CASE(NOT_MONITOR_OWNER);
1567 ERROR_CASE(INTERRUPT);
1568 ERROR_CASE(INVALID_CLASS_FORMAT);
1569 ERROR_CASE(CIRCULAR_CLASS_DEFINITION);
1570 ERROR_CASE(FAILS_VERIFICATION);
1571 ERROR_CASE(UNSUPPORTED_REDEFINITION_METHOD_ADDED);
1572 ERROR_CASE(UNSUPPORTED_REDEFINITION_SCHEMA_CHANGED);
1573 ERROR_CASE(INVALID_TYPESTATE);
1574 ERROR_CASE(UNSUPPORTED_REDEFINITION_HIERARCHY_CHANGED);
1575 ERROR_CASE(UNSUPPORTED_REDEFINITION_METHOD_DELETED);
1576 ERROR_CASE(UNSUPPORTED_VERSION);
1577 ERROR_CASE(NAMES_DONT_MATCH);
1578 ERROR_CASE(UNSUPPORTED_REDEFINITION_CLASS_MODIFIERS_CHANGED);
1579 ERROR_CASE(UNSUPPORTED_REDEFINITION_METHOD_MODIFIERS_CHANGED);
1580 ERROR_CASE(UNMODIFIABLE_CLASS);
1581 ERROR_CASE(NOT_AVAILABLE);
1582 ERROR_CASE(MUST_POSSESS_CAPABILITY);
1583 ERROR_CASE(NULL_POINTER);
1584 ERROR_CASE(ABSENT_INFORMATION);
1585 ERROR_CASE(INVALID_EVENT_TYPE);
1586 ERROR_CASE(ILLEGAL_ARGUMENT);
1587 ERROR_CASE(NATIVE_METHOD);
1588 ERROR_CASE(CLASS_LOADER_UNSUPPORTED);
1589 ERROR_CASE(OUT_OF_MEMORY);
1590 ERROR_CASE(ACCESS_DENIED);
1591 ERROR_CASE(WRONG_PHASE);
1592 ERROR_CASE(INTERNAL);
1593 ERROR_CASE(UNATTACHED_THREAD);
1594 ERROR_CASE(INVALID_ENVIRONMENT);
1595 #undef ERROR_CASE
1596 }
1597
1598 return ERR(ILLEGAL_ARGUMENT);
1599 }
1600
SetVerboseFlag(jvmtiEnv * env,jvmtiVerboseFlag flag,jboolean value)1601 static jvmtiError SetVerboseFlag(jvmtiEnv* env,
1602 jvmtiVerboseFlag flag,
1603 jboolean value) {
1604 ENSURE_VALID_ENV(env);
1605 if (flag == jvmtiVerboseFlag::JVMTI_VERBOSE_OTHER) {
1606 // OTHER is special, as it's 0, so can't do a bit check.
1607 bool val = (value == JNI_TRUE) ? true : false;
1608
1609 art::gLogVerbosity.collector = val;
1610 art::gLogVerbosity.compiler = val;
1611 art::gLogVerbosity.deopt = val;
1612 art::gLogVerbosity.heap = val;
1613 art::gLogVerbosity.jdwp = val;
1614 art::gLogVerbosity.jit = val;
1615 art::gLogVerbosity.monitor = val;
1616 art::gLogVerbosity.oat = val;
1617 art::gLogVerbosity.profiler = val;
1618 art::gLogVerbosity.signals = val;
1619 art::gLogVerbosity.simulator = val;
1620 art::gLogVerbosity.startup = val;
1621 art::gLogVerbosity.third_party_jni = val;
1622 art::gLogVerbosity.threads = val;
1623 art::gLogVerbosity.verifier = val;
1624 art::gLogVerbosity.image = val;
1625
1626 // Note: can't switch systrace_lock_logging. That requires changing entrypoints.
1627
1628 art::gLogVerbosity.agents = val;
1629 } else {
1630 // Spec isn't clear whether "flag" is a mask or supposed to be single. We implement the mask
1631 // semantics.
1632 constexpr std::underlying_type<jvmtiVerboseFlag>::type kMask =
1633 jvmtiVerboseFlag::JVMTI_VERBOSE_GC |
1634 jvmtiVerboseFlag::JVMTI_VERBOSE_CLASS |
1635 jvmtiVerboseFlag::JVMTI_VERBOSE_JNI;
1636 if ((flag & ~kMask) != 0) {
1637 return ERR(ILLEGAL_ARGUMENT);
1638 }
1639
1640 bool val = (value == JNI_TRUE) ? true : false;
1641
1642 if ((flag & jvmtiVerboseFlag::JVMTI_VERBOSE_GC) != 0) {
1643 art::gLogVerbosity.gc = val;
1644 }
1645
1646 if ((flag & jvmtiVerboseFlag::JVMTI_VERBOSE_CLASS) != 0) {
1647 art::gLogVerbosity.class_linker = val;
1648 }
1649
1650 if ((flag & jvmtiVerboseFlag::JVMTI_VERBOSE_JNI) != 0) {
1651 art::gLogVerbosity.jni = val;
1652 }
1653 }
1654
1655 return ERR(NONE);
1656 }
1657
GetJLocationFormat(jvmtiEnv * env,jvmtiJlocationFormat * format_ptr)1658 static jvmtiError GetJLocationFormat(jvmtiEnv* env, jvmtiJlocationFormat* format_ptr) {
1659 ENSURE_VALID_ENV(env);
1660 // Report BCI as jlocation format. We report dex bytecode indices.
1661 if (format_ptr == nullptr) {
1662 return ERR(NULL_POINTER);
1663 }
1664 *format_ptr = jvmtiJlocationFormat::JVMTI_JLOCATION_JVMBCI;
1665 return ERR(NONE);
1666 }
1667 };
1668
IsJvmtiVersion(jint version)1669 static bool IsJvmtiVersion(jint version) {
1670 return version == JVMTI_VERSION_1 ||
1671 version == JVMTI_VERSION_1_0 ||
1672 version == JVMTI_VERSION_1_1 ||
1673 version == JVMTI_VERSION_1_2 ||
1674 version == JVMTI_VERSION;
1675 }
1676
1677 extern const jvmtiInterface_1 gJvmtiInterface;
ArtJvmTiEnv(art::JavaVMExt * runtime,EventHandler * event_handler)1678 ArtJvmTiEnv::ArtJvmTiEnv(art::JavaVMExt* runtime, EventHandler* event_handler)
1679 : art_vm(runtime),
1680 local_data(nullptr),
1681 capabilities() {
1682 object_tag_table = std::unique_ptr<ObjectTagTable>(new ObjectTagTable(event_handler, this));
1683 functions = &gJvmtiInterface;
1684 }
1685
1686 // Creates a jvmtiEnv and returns it with the art::ti::Env that is associated with it. new_art_ti
1687 // is a pointer to the uninitialized memory for an art::ti::Env.
CreateArtJvmTiEnv(art::JavaVMExt * vm,void ** new_jvmtiEnv)1688 static void CreateArtJvmTiEnv(art::JavaVMExt* vm, /*out*/void** new_jvmtiEnv) {
1689 struct ArtJvmTiEnv* env = new ArtJvmTiEnv(vm, &gEventHandler);
1690 *new_jvmtiEnv = env;
1691
1692 gEventHandler.RegisterArtJvmTiEnv(env);
1693
1694 art::Runtime::Current()->AddSystemWeakHolder(
1695 ArtJvmTiEnv::AsArtJvmTiEnv(env)->object_tag_table.get());
1696 }
1697
1698 // A hook that the runtime uses to allow plugins to handle GetEnv calls. It returns true and
1699 // places the return value in 'env' if this library can handle the GetEnv request. Otherwise
1700 // returns false and does not modify the 'env' pointer.
GetEnvHandler(art::JavaVMExt * vm,void ** env,jint version)1701 static jint GetEnvHandler(art::JavaVMExt* vm, /*out*/void** env, jint version) {
1702 if (IsJvmtiVersion(version)) {
1703 CreateArtJvmTiEnv(vm, env);
1704 return JNI_OK;
1705 } else {
1706 printf("version 0x%x is not valid!", version);
1707 return JNI_EVERSION;
1708 }
1709 }
1710
1711 // The plugin initialization function. This adds the jvmti environment.
ArtPlugin_Initialize()1712 extern "C" bool ArtPlugin_Initialize() {
1713 art::Runtime* runtime = art::Runtime::Current();
1714
1715 if (runtime->IsStarted()) {
1716 PhaseUtil::SetToLive();
1717 } else {
1718 PhaseUtil::SetToOnLoad();
1719 }
1720 PhaseUtil::Register(&gEventHandler);
1721 ThreadUtil::Register(&gEventHandler);
1722 ClassUtil::Register(&gEventHandler);
1723 DumpUtil::Register(&gEventHandler);
1724 MethodUtil::Register(&gEventHandler);
1725 SearchUtil::Register();
1726 HeapUtil::Register();
1727
1728 runtime->GetJavaVM()->AddEnvironmentHook(GetEnvHandler);
1729
1730 return true;
1731 }
1732
ArtPlugin_Deinitialize()1733 extern "C" bool ArtPlugin_Deinitialize() {
1734 PhaseUtil::Unregister();
1735 ThreadUtil::Unregister();
1736 ClassUtil::Unregister();
1737 DumpUtil::Unregister();
1738 MethodUtil::Unregister();
1739 SearchUtil::Unregister();
1740 HeapUtil::Unregister();
1741
1742 return true;
1743 }
1744
1745 // The actual struct holding all of the entrypoints into the jvmti interface.
1746 const jvmtiInterface_1 gJvmtiInterface = {
1747 nullptr, // reserved1
1748 JvmtiFunctions::SetEventNotificationMode,
1749 nullptr, // reserved3
1750 JvmtiFunctions::GetAllThreads,
1751 JvmtiFunctions::SuspendThread,
1752 JvmtiFunctions::ResumeThread,
1753 JvmtiFunctions::StopThread,
1754 JvmtiFunctions::InterruptThread,
1755 JvmtiFunctions::GetThreadInfo,
1756 JvmtiFunctions::GetOwnedMonitorInfo, // 10
1757 JvmtiFunctions::GetCurrentContendedMonitor,
1758 JvmtiFunctions::RunAgentThread,
1759 JvmtiFunctions::GetTopThreadGroups,
1760 JvmtiFunctions::GetThreadGroupInfo,
1761 JvmtiFunctions::GetThreadGroupChildren,
1762 JvmtiFunctions::GetFrameCount,
1763 JvmtiFunctions::GetThreadState,
1764 JvmtiFunctions::GetCurrentThread,
1765 JvmtiFunctions::GetFrameLocation,
1766 JvmtiFunctions::NotifyFramePop, // 20
1767 JvmtiFunctions::GetLocalObject,
1768 JvmtiFunctions::GetLocalInt,
1769 JvmtiFunctions::GetLocalLong,
1770 JvmtiFunctions::GetLocalFloat,
1771 JvmtiFunctions::GetLocalDouble,
1772 JvmtiFunctions::SetLocalObject,
1773 JvmtiFunctions::SetLocalInt,
1774 JvmtiFunctions::SetLocalLong,
1775 JvmtiFunctions::SetLocalFloat,
1776 JvmtiFunctions::SetLocalDouble, // 30
1777 JvmtiFunctions::CreateRawMonitor,
1778 JvmtiFunctions::DestroyRawMonitor,
1779 JvmtiFunctions::RawMonitorEnter,
1780 JvmtiFunctions::RawMonitorExit,
1781 JvmtiFunctions::RawMonitorWait,
1782 JvmtiFunctions::RawMonitorNotify,
1783 JvmtiFunctions::RawMonitorNotifyAll,
1784 JvmtiFunctions::SetBreakpoint,
1785 JvmtiFunctions::ClearBreakpoint,
1786 nullptr, // reserved40
1787 JvmtiFunctions::SetFieldAccessWatch,
1788 JvmtiFunctions::ClearFieldAccessWatch,
1789 JvmtiFunctions::SetFieldModificationWatch,
1790 JvmtiFunctions::ClearFieldModificationWatch,
1791 JvmtiFunctions::IsModifiableClass,
1792 JvmtiFunctions::Allocate,
1793 JvmtiFunctions::Deallocate,
1794 JvmtiFunctions::GetClassSignature,
1795 JvmtiFunctions::GetClassStatus,
1796 JvmtiFunctions::GetSourceFileName, // 50
1797 JvmtiFunctions::GetClassModifiers,
1798 JvmtiFunctions::GetClassMethods,
1799 JvmtiFunctions::GetClassFields,
1800 JvmtiFunctions::GetImplementedInterfaces,
1801 JvmtiFunctions::IsInterface,
1802 JvmtiFunctions::IsArrayClass,
1803 JvmtiFunctions::GetClassLoader,
1804 JvmtiFunctions::GetObjectHashCode,
1805 JvmtiFunctions::GetObjectMonitorUsage,
1806 JvmtiFunctions::GetFieldName, // 60
1807 JvmtiFunctions::GetFieldDeclaringClass,
1808 JvmtiFunctions::GetFieldModifiers,
1809 JvmtiFunctions::IsFieldSynthetic,
1810 JvmtiFunctions::GetMethodName,
1811 JvmtiFunctions::GetMethodDeclaringClass,
1812 JvmtiFunctions::GetMethodModifiers,
1813 nullptr, // reserved67
1814 JvmtiFunctions::GetMaxLocals,
1815 JvmtiFunctions::GetArgumentsSize,
1816 JvmtiFunctions::GetLineNumberTable, // 70
1817 JvmtiFunctions::GetMethodLocation,
1818 JvmtiFunctions::GetLocalVariableTable,
1819 JvmtiFunctions::SetNativeMethodPrefix,
1820 JvmtiFunctions::SetNativeMethodPrefixes,
1821 JvmtiFunctions::GetBytecodes,
1822 JvmtiFunctions::IsMethodNative,
1823 JvmtiFunctions::IsMethodSynthetic,
1824 JvmtiFunctions::GetLoadedClasses,
1825 JvmtiFunctions::GetClassLoaderClasses,
1826 JvmtiFunctions::PopFrame, // 80
1827 JvmtiFunctions::ForceEarlyReturnObject,
1828 JvmtiFunctions::ForceEarlyReturnInt,
1829 JvmtiFunctions::ForceEarlyReturnLong,
1830 JvmtiFunctions::ForceEarlyReturnFloat,
1831 JvmtiFunctions::ForceEarlyReturnDouble,
1832 JvmtiFunctions::ForceEarlyReturnVoid,
1833 JvmtiFunctions::RedefineClasses,
1834 JvmtiFunctions::GetVersionNumber,
1835 JvmtiFunctions::GetCapabilities,
1836 JvmtiFunctions::GetSourceDebugExtension, // 90
1837 JvmtiFunctions::IsMethodObsolete,
1838 JvmtiFunctions::SuspendThreadList,
1839 JvmtiFunctions::ResumeThreadList,
1840 nullptr, // reserved94
1841 nullptr, // reserved95
1842 nullptr, // reserved96
1843 nullptr, // reserved97
1844 nullptr, // reserved98
1845 nullptr, // reserved99
1846 JvmtiFunctions::GetAllStackTraces, // 100
1847 JvmtiFunctions::GetThreadListStackTraces,
1848 JvmtiFunctions::GetThreadLocalStorage,
1849 JvmtiFunctions::SetThreadLocalStorage,
1850 JvmtiFunctions::GetStackTrace,
1851 nullptr, // reserved105
1852 JvmtiFunctions::GetTag,
1853 JvmtiFunctions::SetTag,
1854 JvmtiFunctions::ForceGarbageCollection,
1855 JvmtiFunctions::IterateOverObjectsReachableFromObject,
1856 JvmtiFunctions::IterateOverReachableObjects, // 110
1857 JvmtiFunctions::IterateOverHeap,
1858 JvmtiFunctions::IterateOverInstancesOfClass,
1859 nullptr, // reserved113
1860 JvmtiFunctions::GetObjectsWithTags,
1861 JvmtiFunctions::FollowReferences,
1862 JvmtiFunctions::IterateThroughHeap,
1863 nullptr, // reserved117
1864 nullptr, // reserved118
1865 nullptr, // reserved119
1866 JvmtiFunctions::SetJNIFunctionTable, // 120
1867 JvmtiFunctions::GetJNIFunctionTable,
1868 JvmtiFunctions::SetEventCallbacks,
1869 JvmtiFunctions::GenerateEvents,
1870 JvmtiFunctions::GetExtensionFunctions,
1871 JvmtiFunctions::GetExtensionEvents,
1872 JvmtiFunctions::SetExtensionEventCallback,
1873 JvmtiFunctions::DisposeEnvironment,
1874 JvmtiFunctions::GetErrorName,
1875 JvmtiFunctions::GetJLocationFormat,
1876 JvmtiFunctions::GetSystemProperties, // 130
1877 JvmtiFunctions::GetSystemProperty,
1878 JvmtiFunctions::SetSystemProperty,
1879 JvmtiFunctions::GetPhase,
1880 JvmtiFunctions::GetCurrentThreadCpuTimerInfo,
1881 JvmtiFunctions::GetCurrentThreadCpuTime,
1882 JvmtiFunctions::GetThreadCpuTimerInfo,
1883 JvmtiFunctions::GetThreadCpuTime,
1884 JvmtiFunctions::GetTimerInfo,
1885 JvmtiFunctions::GetTime,
1886 JvmtiFunctions::GetPotentialCapabilities, // 140
1887 nullptr, // reserved141
1888 JvmtiFunctions::AddCapabilities,
1889 JvmtiFunctions::RelinquishCapabilities,
1890 JvmtiFunctions::GetAvailableProcessors,
1891 JvmtiFunctions::GetClassVersionNumbers,
1892 JvmtiFunctions::GetConstantPool,
1893 JvmtiFunctions::GetEnvironmentLocalStorage,
1894 JvmtiFunctions::SetEnvironmentLocalStorage,
1895 JvmtiFunctions::AddToBootstrapClassLoaderSearch,
1896 JvmtiFunctions::SetVerboseFlag, // 150
1897 JvmtiFunctions::AddToSystemClassLoaderSearch,
1898 JvmtiFunctions::RetransformClasses,
1899 JvmtiFunctions::GetOwnedMonitorStackDepthInfo,
1900 JvmtiFunctions::GetObjectSize,
1901 JvmtiFunctions::GetLocalInstance,
1902 };
1903
1904 }; // namespace openjdkjvmti
1905