diff options
author | 2016-08-11 15:35:28 -0700 | |
---|---|---|
committer | 2016-08-17 10:50:37 -0700 | |
commit | 49948e9d4e66e68ea077031f9aa80b6c332bd673 (patch) | |
tree | cc50d0259b02d3021241f74ed659f74f52771268 | |
parent | 3f410202b177416c785e6172138a265a91c81b0a (diff) |
Add skeleton of a jvmti plugin for art.
Test: mma test-art-host-run-test-901-hello-ti-agent
Change-Id: If6807b6238d57471e4ba0dd75c717721246443f6
-rw-r--r-- | Android.mk | 1 | ||||
-rw-r--r-- | build/Android.common_path.mk | 2 | ||||
-rw-r--r-- | build/Android.cpplint.mk | 6 | ||||
-rw-r--r-- | runtime/Android.mk | 30 | ||||
-rw-r--r-- | runtime/openjdkjvmti/Android.mk | 20 | ||||
-rw-r--r-- | runtime/openjdkjvmti/MODULE_LICENSE_GPL_WITH_CLASSPATH_EXCEPTION | 0 | ||||
-rw-r--r-- | runtime/openjdkjvmti/NOTICE | 29 | ||||
-rw-r--r-- | runtime/openjdkjvmti/OpenjdkJvmTi.cc | 1120 | ||||
-rw-r--r-- | runtime/openjdkjvmti/README.md | 7 | ||||
-rw-r--r-- | runtime/openjdkjvmti/jvmti.h | 2534 | ||||
-rw-r--r-- | runtime/ti/agent.cc | 6 | ||||
-rw-r--r-- | test/901-hello-ti-agent/basics.cc | 80 | ||||
-rw-r--r-- | test/901-hello-ti-agent/basics.h | 30 | ||||
-rwxr-xr-x | test/901-hello-ti-agent/build | 17 | ||||
-rw-r--r-- | test/901-hello-ti-agent/expected.txt | 2 | ||||
-rw-r--r-- | test/901-hello-ti-agent/info.txt | 1 | ||||
-rwxr-xr-x | test/901-hello-ti-agent/run | 27 | ||||
-rw-r--r-- | test/901-hello-ti-agent/src/Main.java | 21 | ||||
-rw-r--r-- | test/Android.libtiagent.mk | 102 | ||||
-rw-r--r-- | test/Android.run-test.mk | 13 | ||||
-rw-r--r-- | test/ti-agent/common_load.cc | 112 |
21 files changed, 4153 insertions, 7 deletions
diff --git a/Android.mk b/Android.mk index 4ff857bae1..4dc84c4802 100644 --- a/Android.mk +++ b/Android.mk @@ -556,6 +556,7 @@ art_test_bother := TEST_ART_TARGET_SYNC_DEPS := include $(art_path)/runtime/openjdkjvm/Android.mk +include $(art_path)/runtime/openjdkjvmti/Android.mk # Helper target that depends on boot image creation. # diff --git a/build/Android.common_path.mk b/build/Android.common_path.mk index e213dc4750..86bb475f33 100644 --- a/build/Android.common_path.mk +++ b/build/Android.common_path.mk @@ -102,7 +102,7 @@ TARGET_JACK_CLASSPATH := $(abspath $(call intermediates-dir-for,JAV ART_HOST_DEX_DEPENDENCIES := $(foreach jar,$(HOST_CORE_JARS),$(HOST_OUT_JAVA_LIBRARIES)/$(jar).jar) ART_TARGET_DEX_DEPENDENCIES := $(foreach jar,$(TARGET_CORE_JARS),$(TARGET_OUT_JAVA_LIBRARIES)/$(jar).jar) -ART_CORE_SHARED_LIBRARIES := libjavacore libopenjdk libopenjdkjvm +ART_CORE_SHARED_LIBRARIES := libjavacore libopenjdk libopenjdkjvm libopenjdkjvmti ART_HOST_SHARED_LIBRARY_DEPENDENCIES := $(foreach lib,$(ART_CORE_SHARED_LIBRARIES), $(ART_HOST_OUT_SHARED_LIBRARIES)/$(lib)$(ART_HOST_SHLIB_EXTENSION)) ifdef HOST_2ND_ARCH ART_HOST_SHARED_LIBRARY_DEPENDENCIES += $(foreach lib,$(ART_CORE_SHARED_LIBRARIES), $(2ND_HOST_OUT_SHARED_LIBRARIES)/$(lib).so) diff --git a/build/Android.cpplint.mk b/build/Android.cpplint.mk index a06f45a4fb..03791f3907 100644 --- a/build/Android.cpplint.mk +++ b/build/Android.cpplint.mk @@ -19,11 +19,15 @@ include art/build/Android.common_build.mk ART_CPPLINT := $(LOCAL_PATH)/tools/cpplint.py ART_CPPLINT_FILTER := --filter=-whitespace/line_length,-build/include,-readability/function,-readability/streams,-readability/todo,-runtime/references,-runtime/sizeof,-runtime/threadsafe_fn,-runtime/printf ART_CPPLINT_FLAGS := --quiet +ART_CPPLINT_INGORED := \ + runtime/elf.h \ + runtime/openjdkjvmti/jvmti.h + # This: # 1) Gets a list of all .h & .cc files in the art directory. # 2) Prepends 'art/' to each of them to make the full name. # 3) removes art/runtime/elf.h from the list. -ART_CPPLINT_SRC := $(filter-out $(LOCAL_PATH)/runtime/elf.h, $(addprefix $(LOCAL_PATH)/, $(call all-subdir-named-files,*.h) $(call all-subdir-named-files,*$(ART_CPP_EXTENSION)))) +ART_CPPLINT_SRC := $(filter-out $(patsubst %,$(LOCAL_PATH)/%,$(ART_CPPLINT_INGORED)), $(addprefix $(LOCAL_PATH)/, $(call all-subdir-named-files,*.h) $(call all-subdir-named-files,*$(ART_CPP_EXTENSION)))) # "mm cpplint-art" to verify we aren't regressing .PHONY: cpplint-art diff --git a/runtime/Android.mk b/runtime/Android.mk index b31eaf60d8..c0a0951693 100644 --- a/runtime/Android.mk +++ b/runtime/Android.mk @@ -376,6 +376,7 @@ LIBART_ENUM_OPERATOR_OUT_HEADER_FILES := \ verifier/method_verifier.h LIBOPENJDKJVM_SRC_FILES := openjdkjvm/OpenjdkJvm.cc +LIBOPENJDKJVMTI_SRC_FILES := openjdkjvmti/OpenjdkJvmTi.cc LIBART_CFLAGS := -DBUILDING_LIBART=1 @@ -408,7 +409,7 @@ endif # $(1): target or host # $(2): ndebug or debug # $(3): static or shared (note that static only applies for host) -# $(4): module name : either libart or libopenjdkjvm +# $(4): module name : either libart, libopenjdkjvm, or libopenjdkjvmti define build-runtime-library ifneq ($(1),target) ifneq ($(1),host) @@ -422,7 +423,9 @@ define build-runtime-library endif ifneq ($(4),libart) ifneq ($(4),libopenjdkjvm) - $$(error expected libart or libopenjdkjvm for argument 4, received $(4)) + ifneq ($(4),libopenjdkjvmti) + $$(error expected libart, libopenjdkjvmti, or libopenjdkjvm for argument 4, received $(4)) + endif endif endif @@ -460,8 +463,12 @@ define build-runtime-library LOCAL_SRC_FILES_64 := $$(LIBART_HOST_SRC_FILES_64) LOCAL_IS_HOST_MODULE := true endif - else # libopenjdkjvm - LOCAL_SRC_FILES := $$(LIBOPENJDKJVM_SRC_FILES) + else + ifeq ($(4),libopenjdkjvmti) + LOCAL_SRC_FILES := $$(LIBOPENJDKJVMTI_SRC_FILES) + else # libopenjdkjvm + LOCAL_SRC_FILES := $$(LIBOPENJDKJVM_SRC_FILES) + endif ifeq ($$(art_target_or_host),host) LOCAL_IS_HOST_MODULE := true endif @@ -570,6 +577,15 @@ endif LOCAL_SHARED_LIBRARIES += libartd endif LOCAL_NOTICE_FILE := $(LOCAL_PATH)/openjdkjvm/NOTICE + else + ifeq ($(4),libopenjdkjvmti) + ifeq ($$(art_ndebug_or_debug),ndebug) + LOCAL_SHARED_LIBRARIES += libart + else + LOCAL_SHARED_LIBRARIES += libartd + endif + LOCAL_NOTICE_FILE := $(LOCAL_PATH)/openjdkjvmti/NOTICE + endif endif LOCAL_ADDITIONAL_DEPENDENCIES := art/build/Android.common_build.mk LOCAL_ADDITIONAL_DEPENDENCIES += $$(LOCAL_PATH)/Android.mk @@ -609,17 +625,21 @@ endef ifeq ($(ART_BUILD_HOST_NDEBUG),true) $(eval $(call build-runtime-library,host,ndebug,shared,libart)) $(eval $(call build-runtime-library,host,ndebug,shared,libopenjdkjvm)) + $(eval $(call build-runtime-library,host,ndebug,shared,libopenjdkjvmti)) ifeq ($(ART_BUILD_HOST_STATIC),true) $(eval $(call build-runtime-library,host,ndebug,static,libart)) $(eval $(call build-runtime-library,host,ndebug,static,libopenjdkjvm)) + $(eval $(call build-runtime-library,host,ndebug,static,libopenjdkjvmti)) endif endif ifeq ($(ART_BUILD_HOST_DEBUG),true) $(eval $(call build-runtime-library,host,debug,shared,libart)) $(eval $(call build-runtime-library,host,debug,shared,libopenjdkjvm)) + $(eval $(call build-runtime-library,host,debug,shared,libopenjdkjvmti)) ifeq ($(ART_BUILD_HOST_STATIC),true) $(eval $(call build-runtime-library,host,debug,static,libart)) $(eval $(call build-runtime-library,host,debug,static,libopenjdkjvm)) + $(eval $(call build-runtime-library,host,debug,static,libopenjdkjvmti)) endif endif @@ -627,10 +647,12 @@ ifeq ($(ART_BUILD_TARGET_NDEBUG),true) # $(error $(call build-runtime-library,target,ndebug)) $(eval $(call build-runtime-library,target,ndebug,shared,libart)) $(eval $(call build-runtime-library,target,ndebug,shared,libopenjdkjvm)) + $(eval $(call build-runtime-library,target,ndebug,shared,libopenjdkjvmti)) endif ifeq ($(ART_BUILD_TARGET_DEBUG),true) $(eval $(call build-runtime-library,target,debug,shared,libart)) $(eval $(call build-runtime-library,target,debug,shared,libopenjdkjvm)) + $(eval $(call build-runtime-library,target,debug,shared,libopenjdkjvmti)) endif # Clear locally defined variables. diff --git a/runtime/openjdkjvmti/Android.mk b/runtime/openjdkjvmti/Android.mk new file mode 100644 index 0000000000..1de20e84bc --- /dev/null +++ b/runtime/openjdkjvmti/Android.mk @@ -0,0 +1,20 @@ +# +# Copyright (C) 2016 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +LOCAL_PATH := $(call my-dir) + +include $(CLEAR_VARS) +LOCAL_MODULE := openjdkjvmti-phony +include $(BUILD_PHONY_PACKAGE) diff --git a/runtime/openjdkjvmti/MODULE_LICENSE_GPL_WITH_CLASSPATH_EXCEPTION b/runtime/openjdkjvmti/MODULE_LICENSE_GPL_WITH_CLASSPATH_EXCEPTION new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/runtime/openjdkjvmti/MODULE_LICENSE_GPL_WITH_CLASSPATH_EXCEPTION diff --git a/runtime/openjdkjvmti/NOTICE b/runtime/openjdkjvmti/NOTICE new file mode 100644 index 0000000000..6ec62cd4f1 --- /dev/null +++ b/runtime/openjdkjvmti/NOTICE @@ -0,0 +1,29 @@ +Copyright (C) 2016 The Android Open Source Project +DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + +This file implements interfaces from the file jvmti.h. This implementation +is licensed under the same terms as the file jvmti.h. The +copyright and license information for the file jvmti.h follows. + +Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. +DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + +This code is free software; you can redistribute it and/or modify it +under the terms of the GNU General Public License version 2 only, as +published by the Free Software Foundation. Oracle designates this +particular file as subject to the "Classpath" exception as provided +by Oracle in the LICENSE file that accompanied this code. + +This code is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +version 2 for more details (a copy is included in the LICENSE file that +accompanied this code). + +You should have received a copy of the GNU General Public License version +2 along with this work; if not, write to the Free Software Foundation, +Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +or visit www.oracle.com if you need additional information or have any +questions. diff --git a/runtime/openjdkjvmti/OpenjdkJvmTi.cc b/runtime/openjdkjvmti/OpenjdkJvmTi.cc new file mode 100644 index 0000000000..339c457c66 --- /dev/null +++ b/runtime/openjdkjvmti/OpenjdkJvmTi.cc @@ -0,0 +1,1120 @@ +/* Copyright (C) 2016 The Android Open Source Project + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This file implements interfaces from the file jvmti.h. This implementation + * is licensed under the same terms as the file jvmti.h. The + * copyright and license information for the file jvmti.h follows. + * + * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +#include <jni.h> +#include "openjdkjvmti/jvmti.h" + +#include "gc_root-inl.h" +#include "globals.h" +#include "jni_env_ext-inl.h" +#include "scoped_thread_state_change.h" +#include "thread_list.h" + +// TODO Remove this at some point by annotating all the methods. It was put in to make the skeleton +// easier to create. +#pragma GCC diagnostic ignored "-Wunused-parameter" + +namespace openjdkjvmti { + +extern const jvmtiInterface_1 gJvmtiInterface; + +// A structure that is a jvmtiEnv with additional information for the runtime. +struct ArtJvmTiEnv : public jvmtiEnv { + art::JavaVMExt* art_vm; + void* local_data; + + explicit ArtJvmTiEnv(art::JavaVMExt* runtime) : art_vm(runtime), local_data(nullptr) { + functions = &gJvmtiInterface; + } +}; + +// Macro and constexpr to make error values less annoying to write. +#define ERR(e) JVMTI_ERROR_ ## e +static constexpr jvmtiError OK = JVMTI_ERROR_NONE; + +// Special error code for unimplemented functions in JVMTI +static constexpr jvmtiError ERR(NOT_IMPLEMENTED) = JVMTI_ERROR_NOT_AVAILABLE; + +class JvmtiFunctions { + private: + static bool IsValidEnv(jvmtiEnv* env) { + return env != nullptr; + } + + public: + static jvmtiError Allocate(jvmtiEnv* env, jlong size, unsigned char** mem_ptr) { + if (!IsValidEnv(env)) { + return ERR(INVALID_ENVIRONMENT); + } + if (mem_ptr == nullptr) { + return ERR(NULL_POINTER); + } + if (size < 0) { + return ERR(ILLEGAL_ARGUMENT); + } else if (size == 0) { + *mem_ptr = nullptr; + return OK; + } + *mem_ptr = static_cast<unsigned char*>(malloc(size)); + return (*mem_ptr != nullptr) ? OK : ERR(OUT_OF_MEMORY); + } + + static jvmtiError Deallocate(jvmtiEnv* env, unsigned char* mem) { + if (!IsValidEnv(env)) { + return ERR(INVALID_ENVIRONMENT); + } + if (mem != nullptr) { + free(mem); + } + return OK; + } + + static jvmtiError GetThreadState(jvmtiEnv* env, jthread thread, jint* thread_state_ptr) { + return ERR(NOT_IMPLEMENTED); + } + + static jvmtiError GetCurrentThread(jvmtiEnv* env, jthread* thread_ptr) { + return ERR(NOT_IMPLEMENTED); + } + + static jvmtiError GetAllThreads(jvmtiEnv* env, jint* threads_count_ptr, jthread** threads_ptr) { + return ERR(NOT_IMPLEMENTED); + } + + static jvmtiError SuspendThread(jvmtiEnv* env, jthread thread) { + return ERR(NOT_IMPLEMENTED); + } + + static jvmtiError SuspendThreadList(jvmtiEnv* env, + jint request_count, + const jthread* request_list, + jvmtiError* results) { + return ERR(NOT_IMPLEMENTED); + } + + static jvmtiError ResumeThread(jvmtiEnv* env, jthread thread) { + return ERR(NOT_IMPLEMENTED); + } + + static jvmtiError ResumeThreadList(jvmtiEnv* env, + jint request_count, + const jthread* request_list, + jvmtiError* results) { + return ERR(NOT_IMPLEMENTED); + } + + static jvmtiError StopThread(jvmtiEnv* env, jthread thread, jobject exception) { + return ERR(NOT_IMPLEMENTED); + } + + static jvmtiError InterruptThread(jvmtiEnv* env, jthread thread) { + return ERR(NOT_IMPLEMENTED); + } + + static jvmtiError GetThreadInfo(jvmtiEnv* env, jthread thread, jvmtiThreadInfo* info_ptr) { + return ERR(NOT_IMPLEMENTED); + } + + static jvmtiError GetOwnedMonitorInfo(jvmtiEnv* env, + jthread thread, + jint* owned_monitor_count_ptr, + jobject** owned_monitors_ptr) { + return ERR(NOT_IMPLEMENTED); + } + + static jvmtiError GetOwnedMonitorStackDepthInfo(jvmtiEnv* env, + jthread thread, + jint* monitor_info_count_ptr, + jvmtiMonitorStackDepthInfo** monitor_info_ptr) { + return ERR(NOT_IMPLEMENTED); + } + + static jvmtiError GetCurrentContendedMonitor(jvmtiEnv* env, + jthread thread, + jobject* monitor_ptr) { + return ERR(NOT_IMPLEMENTED); + } + + static jvmtiError RunAgentThread(jvmtiEnv* env, + jthread thread, + jvmtiStartFunction proc, + const void* arg, + jint priority) { + return ERR(NOT_IMPLEMENTED); + } + + static jvmtiError SetThreadLocalStorage(jvmtiEnv* env, jthread thread, const void* data) { + return ERR(NOT_IMPLEMENTED); + } + + static jvmtiError GetThreadLocalStorage(jvmtiEnv* env, jthread thread, void** data_ptr) { + return ERR(NOT_IMPLEMENTED); + } + + static jvmtiError GetTopThreadGroups(jvmtiEnv* env, + jint* group_count_ptr, + jthreadGroup** groups_ptr) { + return ERR(NOT_IMPLEMENTED); + } + + static jvmtiError GetThreadGroupInfo(jvmtiEnv* env, + jthreadGroup group, + jvmtiThreadGroupInfo* info_ptr) { + return ERR(NOT_IMPLEMENTED); + } + + static jvmtiError GetThreadGroupChildren(jvmtiEnv* env, + jthreadGroup group, + jint* thread_count_ptr, + jthread** threads_ptr, + jint* group_count_ptr, + jthreadGroup** groups_ptr) { + return ERR(NOT_IMPLEMENTED); + } + + static jvmtiError GetStackTrace(jvmtiEnv* env, + jthread thread, + jint start_depth, + jint max_frame_count, + jvmtiFrameInfo* frame_buffer, + jint* count_ptr) { + return ERR(NOT_IMPLEMENTED); + } + + static jvmtiError GetAllStackTraces(jvmtiEnv* env, + jint max_frame_count, + jvmtiStackInfo** stack_info_ptr, + jint* thread_count_ptr) { + return ERR(NOT_IMPLEMENTED); + } + + static jvmtiError GetThreadListStackTraces(jvmtiEnv* env, + jint thread_count, + const jthread* thread_list, + jint max_frame_count, + jvmtiStackInfo** stack_info_ptr) { + return ERR(NOT_IMPLEMENTED); + } + + static jvmtiError GetFrameCount(jvmtiEnv* env, jthread thread, jint* count_ptr) { + return ERR(NOT_IMPLEMENTED); + } + + static jvmtiError PopFrame(jvmtiEnv* env, jthread thread) { + return ERR(NOT_IMPLEMENTED); + } + + static jvmtiError GetFrameLocation(jvmtiEnv* env, + jthread thread, + jint depth, + jmethodID* method_ptr, + jlocation* location_ptr) { + return ERR(NOT_IMPLEMENTED); + } + + static jvmtiError NotifyFramePop(jvmtiEnv* env, jthread thread, jint depth) { + return ERR(NOT_IMPLEMENTED); + } + + static jvmtiError ForceEarlyReturnObject(jvmtiEnv* env, jthread thread, jobject value) { + return ERR(NOT_IMPLEMENTED); + } + + static jvmtiError ForceEarlyReturnInt(jvmtiEnv* env, jthread thread, jint value) { + return ERR(NOT_IMPLEMENTED); + } + + static jvmtiError ForceEarlyReturnLong(jvmtiEnv* env, jthread thread, jlong value) { + return ERR(NOT_IMPLEMENTED); + } + + static jvmtiError ForceEarlyReturnFloat(jvmtiEnv* env, jthread thread, jfloat value) { + return ERR(NOT_IMPLEMENTED); + } + + static jvmtiError ForceEarlyReturnDouble(jvmtiEnv* env, jthread thread, jdouble value) { + return ERR(NOT_IMPLEMENTED); + } + + static jvmtiError ForceEarlyReturnVoid(jvmtiEnv* env, jthread thread) { + return ERR(NOT_IMPLEMENTED); + } + + static jvmtiError FollowReferences(jvmtiEnv* env, + jint heap_filter, + jclass klass, + jobject initial_object, + const jvmtiHeapCallbacks* callbacks, + const void* user_data) { + return ERR(NOT_IMPLEMENTED); + } + + static jvmtiError IterateThroughHeap(jvmtiEnv* env, + jint heap_filter, + jclass klass, + const jvmtiHeapCallbacks* callbacks, + const void* user_data) { + return ERR(NOT_IMPLEMENTED); + } + + static jvmtiError GetTag(jvmtiEnv* env, jobject object, jlong* tag_ptr) { + return ERR(NOT_IMPLEMENTED); + } + + static jvmtiError SetTag(jvmtiEnv* env, jobject object, jlong tag) { + return ERR(NOT_IMPLEMENTED); + } + + static jvmtiError GetObjectsWithTags(jvmtiEnv* env, + jint tag_count, + const jlong* tags, + jint* count_ptr, + jobject** object_result_ptr, + jlong** tag_result_ptr) { + return ERR(NOT_IMPLEMENTED); + } + + static jvmtiError ForceGarbageCollection(jvmtiEnv* env) { + return ERR(NOT_IMPLEMENTED); + } + + static jvmtiError IterateOverObjectsReachableFromObject( + jvmtiEnv* env, + jobject object, + jvmtiObjectReferenceCallback object_reference_callback, + const void* user_data) { + return ERR(NOT_IMPLEMENTED); + } + + static jvmtiError IterateOverReachableObjects(jvmtiEnv* env, + jvmtiHeapRootCallback heap_root_callback, + jvmtiStackReferenceCallback stack_ref_callback, + jvmtiObjectReferenceCallback object_ref_callback, + const void* user_data) { + return ERR(NOT_IMPLEMENTED); + } + + static jvmtiError IterateOverHeap(jvmtiEnv* env, + jvmtiHeapObjectFilter object_filter, + jvmtiHeapObjectCallback heap_object_callback, + const void* user_data) { + return ERR(NOT_IMPLEMENTED); + } + + static jvmtiError IterateOverInstancesOfClass(jvmtiEnv* env, + jclass klass, + jvmtiHeapObjectFilter object_filter, + jvmtiHeapObjectCallback heap_object_callback, + const void* user_data) { + return ERR(NOT_IMPLEMENTED); + } + + static jvmtiError GetLocalObject(jvmtiEnv* env, + jthread thread, + jint depth, + jint slot, + jobject* value_ptr) { + return ERR(NOT_IMPLEMENTED); + } + + static jvmtiError GetLocalInstance(jvmtiEnv* env, + jthread thread, + jint depth, + jobject* value_ptr) { + return ERR(NOT_IMPLEMENTED); + } + + static jvmtiError GetLocalInt(jvmtiEnv* env, + jthread thread, + jint depth, + jint slot, + jint* value_ptr) { + return ERR(NOT_IMPLEMENTED); + } + + static jvmtiError GetLocalLong(jvmtiEnv* env, + jthread thread, + jint depth, + jint slot, + jlong* value_ptr) { + return ERR(NOT_IMPLEMENTED); + } + + static jvmtiError GetLocalFloat(jvmtiEnv* env, + jthread thread, + jint depth, + jint slot, + jfloat* value_ptr) { + return ERR(NOT_IMPLEMENTED); + } + + static jvmtiError GetLocalDouble(jvmtiEnv* env, + jthread thread, + jint depth, + jint slot, + jdouble* value_ptr) { + return ERR(NOT_IMPLEMENTED); + } + + static jvmtiError SetLocalObject(jvmtiEnv* env, + jthread thread, + jint depth, + jint slot, + jobject value) { + return ERR(NOT_IMPLEMENTED); + } + + static jvmtiError SetLocalInt(jvmtiEnv* env, + jthread thread, + jint depth, + jint slot, + jint value) { + return ERR(NOT_IMPLEMENTED); + } + + static jvmtiError SetLocalLong(jvmtiEnv* env, + jthread thread, + jint depth, + jint slot, + jlong value) { + return ERR(NOT_IMPLEMENTED); + } + + static jvmtiError SetLocalFloat(jvmtiEnv* env, + jthread thread, + jint depth, + jint slot, + jfloat value) { + return ERR(NOT_IMPLEMENTED); + } + + static jvmtiError SetLocalDouble(jvmtiEnv* env, + jthread thread, + jint depth, + jint slot, + jdouble value) { + return ERR(NOT_IMPLEMENTED); + } + + static jvmtiError SetBreakpoint(jvmtiEnv* env, jmethodID method, jlocation location) { + return ERR(NOT_IMPLEMENTED); + } + + static jvmtiError ClearBreakpoint(jvmtiEnv* env, jmethodID method, jlocation location) { + return ERR(NOT_IMPLEMENTED); + } + + static jvmtiError SetFieldAccessWatch(jvmtiEnv* env, jclass klass, jfieldID field) { + return ERR(NOT_IMPLEMENTED); + } + + static jvmtiError ClearFieldAccessWatch(jvmtiEnv* env, jclass klass, jfieldID field) { + return ERR(NOT_IMPLEMENTED); + } + + static jvmtiError SetFieldModificationWatch(jvmtiEnv* env, jclass klass, jfieldID field) { + return ERR(NOT_IMPLEMENTED); + } + + static jvmtiError ClearFieldModificationWatch(jvmtiEnv* env, jclass klass, jfieldID field) { + return ERR(NOT_IMPLEMENTED); + } + + static jvmtiError GetLoadedClasses(jvmtiEnv* env, jint* class_count_ptr, jclass** classes_ptr) { + return ERR(NOT_IMPLEMENTED); + } + + static jvmtiError GetClassLoaderClasses(jvmtiEnv* env, + jobject initiating_loader, + jint* class_count_ptr, + jclass** classes_ptr) { + return ERR(NOT_IMPLEMENTED); + } + + static jvmtiError GetClassSignature(jvmtiEnv* env, + jclass klass, + char** signature_ptr, + char** generic_ptr) { + return ERR(NOT_IMPLEMENTED); + } + + static jvmtiError GetClassStatus(jvmtiEnv* env, jclass klass, jint* status_ptr) { + return ERR(NOT_IMPLEMENTED); + } + + static jvmtiError GetSourceFileName(jvmtiEnv* env, jclass klass, char** source_name_ptr) { + return ERR(NOT_IMPLEMENTED); + } + + static jvmtiError GetClassModifiers(jvmtiEnv* env, jclass klass, jint* modifiers_ptr) { + return ERR(NOT_IMPLEMENTED); + } + + static jvmtiError GetClassMethods(jvmtiEnv* env, + jclass klass, + jint* method_count_ptr, + jmethodID** methods_ptr) { + return ERR(NOT_IMPLEMENTED); + } + + static jvmtiError GetClassFields(jvmtiEnv* env, + jclass klass, + jint* field_count_ptr, + jfieldID** fields_ptr) { + return ERR(NOT_IMPLEMENTED); + } + + static jvmtiError GetImplementedInterfaces(jvmtiEnv* env, + jclass klass, + jint* interface_count_ptr, + jclass** interfaces_ptr) { + return ERR(NOT_IMPLEMENTED); + } + + static jvmtiError GetClassVersionNumbers(jvmtiEnv* env, + jclass klass, + jint* minor_version_ptr, + jint* major_version_ptr) { + return ERR(NOT_IMPLEMENTED); + } + + static jvmtiError GetConstantPool(jvmtiEnv* env, + jclass klass, + jint* constant_pool_count_ptr, + jint* constant_pool_byte_count_ptr, + unsigned char** constant_pool_bytes_ptr) { + return ERR(NOT_IMPLEMENTED); + } + + static jvmtiError IsInterface(jvmtiEnv* env, jclass klass, jboolean* is_interface_ptr) { + return ERR(NOT_IMPLEMENTED); + } + + static jvmtiError IsArrayClass(jvmtiEnv* env, + jclass klass, + jboolean* is_array_class_ptr) { + return ERR(NOT_IMPLEMENTED); + } + + static jvmtiError IsModifiableClass(jvmtiEnv* env, + jclass klass, + jboolean* is_modifiable_class_ptr) { + return ERR(NOT_IMPLEMENTED); + } + + static jvmtiError GetClassLoader(jvmtiEnv* env, jclass klass, jobject* classloader_ptr) { + return ERR(NOT_IMPLEMENTED); + } + + static jvmtiError GetSourceDebugExtension(jvmtiEnv* env, + jclass klass, + char** source_debug_extension_ptr) { + return ERR(NOT_IMPLEMENTED); + } + + static jvmtiError RetransformClasses(jvmtiEnv* env, jint class_count, const jclass* classes) { + return ERR(NOT_IMPLEMENTED); + } + + static jvmtiError RedefineClasses(jvmtiEnv* env, + jint class_count, + const jvmtiClassDefinition* class_definitions) { + return ERR(NOT_IMPLEMENTED); + } + + static jvmtiError GetObjectSize(jvmtiEnv* env, jobject object, jlong* size_ptr) { + return ERR(NOT_IMPLEMENTED); + } + + static jvmtiError GetObjectHashCode(jvmtiEnv* env, jobject object, jint* hash_code_ptr) { + return ERR(NOT_IMPLEMENTED); + } + + static jvmtiError GetObjectMonitorUsage(jvmtiEnv* env, + jobject object, + jvmtiMonitorUsage* info_ptr) { + return ERR(NOT_IMPLEMENTED); + } + + static jvmtiError GetFieldName(jvmtiEnv* env, + jclass klass, + jfieldID field, + char** name_ptr, + char** signature_ptr, + char** generic_ptr) { + return ERR(NOT_IMPLEMENTED); + } + + static jvmtiError GetFieldDeclaringClass(jvmtiEnv* env, + jclass klass, + jfieldID field, + jclass* declaring_class_ptr) { + return ERR(NOT_IMPLEMENTED); + } + + static jvmtiError GetFieldModifiers(jvmtiEnv* env, + jclass klass, + jfieldID field, + jint* modifiers_ptr) { + return ERR(NOT_IMPLEMENTED); + } + + static jvmtiError IsFieldSynthetic(jvmtiEnv* env, + jclass klass, + jfieldID field, + jboolean* is_synthetic_ptr) { + return ERR(NOT_IMPLEMENTED); + } + + static jvmtiError GetMethodName(jvmtiEnv* env, + jmethodID method, + char** name_ptr, + char** signature_ptr, + char** generic_ptr) { + return ERR(NOT_IMPLEMENTED); + } + + static jvmtiError GetMethodDeclaringClass(jvmtiEnv* env, + jmethodID method, + jclass* declaring_class_ptr) { + return ERR(NOT_IMPLEMENTED); + } + + static jvmtiError GetMethodModifiers(jvmtiEnv* env, + jmethodID method, + jint* modifiers_ptr) { + return ERR(NOT_IMPLEMENTED); + } + + static jvmtiError GetMaxLocals(jvmtiEnv* env, + jmethodID method, + jint* max_ptr) { + return ERR(NOT_IMPLEMENTED); + } + + static jvmtiError GetArgumentsSize(jvmtiEnv* env, + jmethodID method, + jint* size_ptr) { + return ERR(NOT_IMPLEMENTED); + } + + static jvmtiError GetLineNumberTable(jvmtiEnv* env, + jmethodID method, + jint* entry_count_ptr, + jvmtiLineNumberEntry** table_ptr) { + return ERR(NOT_IMPLEMENTED); + } + + static jvmtiError GetMethodLocation(jvmtiEnv* env, + jmethodID method, + jlocation* start_location_ptr, + jlocation* end_location_ptr) { + return ERR(NOT_IMPLEMENTED); + } + + static jvmtiError GetLocalVariableTable(jvmtiEnv* env, + jmethodID method, + jint* entry_count_ptr, + jvmtiLocalVariableEntry** table_ptr) { + return ERR(NOT_IMPLEMENTED); + } + + static jvmtiError GetBytecodes(jvmtiEnv* env, + jmethodID method, + jint* bytecode_count_ptr, + unsigned char** bytecodes_ptr) { + return ERR(NOT_IMPLEMENTED); + } + + static jvmtiError IsMethodNative(jvmtiEnv* env, jmethodID method, jboolean* is_native_ptr) { + return ERR(NOT_IMPLEMENTED); + } + + static jvmtiError IsMethodSynthetic(jvmtiEnv* env, jmethodID method, jboolean* is_synthetic_ptr) { + return ERR(NOT_IMPLEMENTED); + } + + static jvmtiError IsMethodObsolete(jvmtiEnv* env, jmethodID method, jboolean* is_obsolete_ptr) { + return ERR(NOT_IMPLEMENTED); + } + + static jvmtiError SetNativeMethodPrefix(jvmtiEnv* env, const char* prefix) { + return ERR(NOT_IMPLEMENTED); + } + + static jvmtiError SetNativeMethodPrefixes(jvmtiEnv* env, jint prefix_count, char** prefixes) { + return ERR(NOT_IMPLEMENTED); + } + + static jvmtiError CreateRawMonitor(jvmtiEnv* env, const char* name, jrawMonitorID* monitor_ptr) { + return ERR(NOT_IMPLEMENTED); + } + + static jvmtiError DestroyRawMonitor(jvmtiEnv* env, jrawMonitorID monitor) { + return ERR(NOT_IMPLEMENTED); + } + + static jvmtiError RawMonitorEnter(jvmtiEnv* env, jrawMonitorID monitor) { + return ERR(NOT_IMPLEMENTED); + } + + static jvmtiError RawMonitorExit(jvmtiEnv* env, jrawMonitorID monitor) { + return ERR(NOT_IMPLEMENTED); + } + + static jvmtiError RawMonitorWait(jvmtiEnv* env, jrawMonitorID monitor, jlong millis) { + return ERR(NOT_IMPLEMENTED); + } + + static jvmtiError RawMonitorNotify(jvmtiEnv* env, jrawMonitorID monitor) { + return ERR(NOT_IMPLEMENTED); + } + + static jvmtiError RawMonitorNotifyAll(jvmtiEnv* env, jrawMonitorID monitor) { + return ERR(NOT_IMPLEMENTED); + } + + static jvmtiError SetJNIFunctionTable(jvmtiEnv* env, const jniNativeInterface* function_table) { + return ERR(NOT_IMPLEMENTED); + } + + static jvmtiError GetJNIFunctionTable(jvmtiEnv* env, jniNativeInterface** function_table) { + return ERR(NOT_IMPLEMENTED); + } + + static jvmtiError SetEventCallbacks(jvmtiEnv* env, + const jvmtiEventCallbacks* callbacks, + jint size_of_callbacks) { + return ERR(NOT_IMPLEMENTED); + } + + static jvmtiError SetEventNotificationMode(jvmtiEnv* env, + jvmtiEventMode mode, + jvmtiEvent event_type, + jthread event_thread, + ...) { + return ERR(NOT_IMPLEMENTED); + } + + static jvmtiError GenerateEvents(jvmtiEnv* env, jvmtiEvent event_type) { + return ERR(NOT_IMPLEMENTED); + } + + static jvmtiError GetExtensionFunctions(jvmtiEnv* env, + jint* extension_count_ptr, + jvmtiExtensionFunctionInfo** extensions) { + return ERR(NOT_IMPLEMENTED); + } + + static jvmtiError GetExtensionEvents(jvmtiEnv* env, + jint* extension_count_ptr, + jvmtiExtensionEventInfo** extensions) { + return ERR(NOT_IMPLEMENTED); + } + + static jvmtiError SetExtensionEventCallback(jvmtiEnv* env, + jint extension_event_index, + jvmtiExtensionEvent callback) { + return ERR(NOT_IMPLEMENTED); + } + + static jvmtiError GetPotentialCapabilities(jvmtiEnv* env, jvmtiCapabilities* capabilities_ptr) { + return ERR(NOT_IMPLEMENTED); + } + + static jvmtiError AddCapabilities(jvmtiEnv* env, const jvmtiCapabilities* capabilities_ptr) { + return ERR(NOT_IMPLEMENTED); + } + + static jvmtiError RelinquishCapabilities(jvmtiEnv* env, + const jvmtiCapabilities* capabilities_ptr) { + return ERR(NOT_IMPLEMENTED); + } + + static jvmtiError GetCapabilities(jvmtiEnv* env, jvmtiCapabilities* capabilities_ptr) { + return ERR(NOT_IMPLEMENTED); + } + + static jvmtiError GetCurrentThreadCpuTimerInfo(jvmtiEnv* env, jvmtiTimerInfo* info_ptr) { + return ERR(NOT_IMPLEMENTED); + } + + static jvmtiError GetCurrentThreadCpuTime(jvmtiEnv* env, jlong* nanos_ptr) { + return ERR(NOT_IMPLEMENTED); + } + + static jvmtiError GetThreadCpuTimerInfo(jvmtiEnv* env, jvmtiTimerInfo* info_ptr) { + return ERR(NOT_IMPLEMENTED); + } + + static jvmtiError GetThreadCpuTime(jvmtiEnv* env, jthread thread, jlong* nanos_ptr) { + return ERR(NOT_IMPLEMENTED); + } + + static jvmtiError GetTimerInfo(jvmtiEnv* env, jvmtiTimerInfo* info_ptr) { + return ERR(NOT_IMPLEMENTED); + } + + static jvmtiError GetTime(jvmtiEnv* env, jlong* nanos_ptr) { + return ERR(NOT_IMPLEMENTED); + } + + static jvmtiError GetAvailableProcessors(jvmtiEnv* env, jint* processor_count_ptr) { + return ERR(NOT_IMPLEMENTED); + } + + static jvmtiError AddToBootstrapClassLoaderSearch(jvmtiEnv* env, const char* segment) { + return ERR(NOT_IMPLEMENTED); + } + + static jvmtiError AddToSystemClassLoaderSearch(jvmtiEnv* env, const char* segment) { + return ERR(NOT_IMPLEMENTED); + } + + static jvmtiError GetSystemProperties(jvmtiEnv* env, jint* count_ptr, char*** property_ptr) { + return ERR(NOT_IMPLEMENTED); + } + + static jvmtiError GetSystemProperty(jvmtiEnv* env, const char* property, char** value_ptr) { + return ERR(NOT_IMPLEMENTED); + } + + static jvmtiError SetSystemProperty(jvmtiEnv* env, const char* property, const char* value) { + return ERR(NOT_IMPLEMENTED); + } + + static jvmtiError GetPhase(jvmtiEnv* env, jvmtiPhase* phase_ptr) { + return ERR(NOT_IMPLEMENTED); + } + + static jvmtiError DisposeEnvironment(jvmtiEnv* env) { + if (!IsValidEnv(env)) { + return ERR(INVALID_ENVIRONMENT); + } + delete env; + return OK; + } + + static jvmtiError SetEnvironmentLocalStorage(jvmtiEnv* env, const void* data) { + if (!IsValidEnv(env)) { + return ERR(INVALID_ENVIRONMENT); + } + reinterpret_cast<ArtJvmTiEnv*>(env)->local_data = const_cast<void*>(data); + return OK; + } + + static jvmtiError GetEnvironmentLocalStorage(jvmtiEnv* env, void** data_ptr) { + if (!IsValidEnv(env)) { + return ERR(INVALID_ENVIRONMENT); + } + *data_ptr = reinterpret_cast<ArtJvmTiEnv*>(env)->local_data; + return OK; + } + + static jvmtiError GetVersionNumber(jvmtiEnv* env, jint* version_ptr) { + if (!IsValidEnv(env)) { + return ERR(INVALID_ENVIRONMENT); + } + *version_ptr = JVMTI_VERSION; + return OK; + } + + static jvmtiError GetErrorName(jvmtiEnv* env, jvmtiError error, char** name_ptr) { + if (!IsValidEnv(env)) { + return ERR(INVALID_ENVIRONMENT); + } + if (name_ptr == nullptr) { + return ERR(NULL_POINTER); + } + switch (error) { +#define ERROR_CASE(e) case (JVMTI_ERROR_ ## e) : do { \ + *name_ptr = const_cast<char*>("JVMTI_ERROR_"#e); \ + return OK; \ + } while (false) + ERROR_CASE(NONE); + ERROR_CASE(INVALID_THREAD); + ERROR_CASE(INVALID_THREAD_GROUP); + ERROR_CASE(INVALID_PRIORITY); + ERROR_CASE(THREAD_NOT_SUSPENDED); + ERROR_CASE(THREAD_NOT_ALIVE); + ERROR_CASE(INVALID_OBJECT); + ERROR_CASE(INVALID_CLASS); + ERROR_CASE(CLASS_NOT_PREPARED); + ERROR_CASE(INVALID_METHODID); + ERROR_CASE(INVALID_LOCATION); + ERROR_CASE(INVALID_FIELDID); + ERROR_CASE(NO_MORE_FRAMES); + ERROR_CASE(OPAQUE_FRAME); + ERROR_CASE(TYPE_MISMATCH); + ERROR_CASE(INVALID_SLOT); + ERROR_CASE(DUPLICATE); + ERROR_CASE(NOT_FOUND); + ERROR_CASE(INVALID_MONITOR); + ERROR_CASE(NOT_MONITOR_OWNER); + ERROR_CASE(INTERRUPT); + ERROR_CASE(INVALID_CLASS_FORMAT); + ERROR_CASE(CIRCULAR_CLASS_DEFINITION); + ERROR_CASE(FAILS_VERIFICATION); + ERROR_CASE(UNSUPPORTED_REDEFINITION_METHOD_ADDED); + ERROR_CASE(UNSUPPORTED_REDEFINITION_SCHEMA_CHANGED); + ERROR_CASE(INVALID_TYPESTATE); + ERROR_CASE(UNSUPPORTED_REDEFINITION_HIERARCHY_CHANGED); + ERROR_CASE(UNSUPPORTED_REDEFINITION_METHOD_DELETED); + ERROR_CASE(UNSUPPORTED_VERSION); + ERROR_CASE(NAMES_DONT_MATCH); + ERROR_CASE(UNSUPPORTED_REDEFINITION_CLASS_MODIFIERS_CHANGED); + ERROR_CASE(UNSUPPORTED_REDEFINITION_METHOD_MODIFIERS_CHANGED); + ERROR_CASE(UNMODIFIABLE_CLASS); + ERROR_CASE(NOT_AVAILABLE); + ERROR_CASE(MUST_POSSESS_CAPABILITY); + ERROR_CASE(NULL_POINTER); + ERROR_CASE(ABSENT_INFORMATION); + ERROR_CASE(INVALID_EVENT_TYPE); + ERROR_CASE(ILLEGAL_ARGUMENT); + ERROR_CASE(NATIVE_METHOD); + ERROR_CASE(CLASS_LOADER_UNSUPPORTED); + ERROR_CASE(OUT_OF_MEMORY); + ERROR_CASE(ACCESS_DENIED); + ERROR_CASE(WRONG_PHASE); + ERROR_CASE(INTERNAL); + ERROR_CASE(UNATTACHED_THREAD); + ERROR_CASE(INVALID_ENVIRONMENT); +#undef ERROR_CASE + default: { + *name_ptr = const_cast<char*>("JVMTI_ERROR_UNKNOWN"); + return ERR(ILLEGAL_ARGUMENT); + } + } + } + + static jvmtiError SetVerboseFlag(jvmtiEnv* env, jvmtiVerboseFlag flag, jboolean value) { + return ERR(NOT_IMPLEMENTED); + } + + static jvmtiError GetJLocationFormat(jvmtiEnv* env, jvmtiJlocationFormat* format_ptr) { + return ERR(NOT_IMPLEMENTED); + } +}; + +static bool IsJvmtiVersion(jint version) { + return version == JVMTI_VERSION_1 || + version == JVMTI_VERSION_1_0 || + version == JVMTI_VERSION_1_1 || + version == JVMTI_VERSION_1_2 || + version == JVMTI_VERSION; +} + +// Creates a jvmtiEnv and returns it with the art::ti::Env that is associated with it. new_art_ti +// is a pointer to the uninitialized memory for an art::ti::Env. +static void CreateArtJvmTiEnv(art::JavaVMExt* vm, /*out*/void** new_jvmtiEnv) { + struct ArtJvmTiEnv* env = new ArtJvmTiEnv(vm); + *new_jvmtiEnv = env; +} + +// A hook that the runtime uses to allow plugins to handle GetEnv calls. It returns true and +// places the return value in 'env' if this library can handle the GetEnv request. Otherwise +// returns false and does not modify the 'env' pointer. +static jint GetEnvHandler(art::JavaVMExt* vm, /*out*/void** env, jint version) { + if (IsJvmtiVersion(version)) { + CreateArtJvmTiEnv(vm, env); + return JNI_OK; + } else { + printf("version 0x%x is not valid!", version); + return JNI_EVERSION; + } +} + +// The plugin initialization function. This adds the jvmti environment. +extern "C" bool ArtPlugin_Initialize() { + art::Runtime::Current()->GetJavaVM()->AddEnvironmentHook(GetEnvHandler); + return true; +} + +// The actual struct holding all of the entrypoints into the jvmti interface. +const jvmtiInterface_1 gJvmtiInterface = { + nullptr, // reserved1 + JvmtiFunctions::SetEventNotificationMode, + nullptr, // reserved3 + JvmtiFunctions::GetAllThreads, + JvmtiFunctions::SuspendThread, + JvmtiFunctions::ResumeThread, + JvmtiFunctions::StopThread, + JvmtiFunctions::InterruptThread, + JvmtiFunctions::GetThreadInfo, + JvmtiFunctions::GetOwnedMonitorInfo, // 10 + JvmtiFunctions::GetCurrentContendedMonitor, + JvmtiFunctions::RunAgentThread, + JvmtiFunctions::GetTopThreadGroups, + JvmtiFunctions::GetThreadGroupInfo, + JvmtiFunctions::GetThreadGroupChildren, + JvmtiFunctions::GetFrameCount, + JvmtiFunctions::GetThreadState, + JvmtiFunctions::GetCurrentThread, + JvmtiFunctions::GetFrameLocation, + JvmtiFunctions::NotifyFramePop, // 20 + JvmtiFunctions::GetLocalObject, + JvmtiFunctions::GetLocalInt, + JvmtiFunctions::GetLocalLong, + JvmtiFunctions::GetLocalFloat, + JvmtiFunctions::GetLocalDouble, + JvmtiFunctions::SetLocalObject, + JvmtiFunctions::SetLocalInt, + JvmtiFunctions::SetLocalLong, + JvmtiFunctions::SetLocalFloat, + JvmtiFunctions::SetLocalDouble, // 30 + JvmtiFunctions::CreateRawMonitor, + JvmtiFunctions::DestroyRawMonitor, + JvmtiFunctions::RawMonitorEnter, + JvmtiFunctions::RawMonitorExit, + JvmtiFunctions::RawMonitorWait, + JvmtiFunctions::RawMonitorNotify, + JvmtiFunctions::RawMonitorNotifyAll, + JvmtiFunctions::SetBreakpoint, + JvmtiFunctions::ClearBreakpoint, + nullptr, // reserved40 + JvmtiFunctions::SetFieldAccessWatch, + JvmtiFunctions::ClearFieldAccessWatch, + JvmtiFunctions::SetFieldModificationWatch, + JvmtiFunctions::ClearFieldModificationWatch, + JvmtiFunctions::IsModifiableClass, + JvmtiFunctions::Allocate, + JvmtiFunctions::Deallocate, + JvmtiFunctions::GetClassSignature, + JvmtiFunctions::GetClassStatus, + JvmtiFunctions::GetSourceFileName, // 50 + JvmtiFunctions::GetClassModifiers, + JvmtiFunctions::GetClassMethods, + JvmtiFunctions::GetClassFields, + JvmtiFunctions::GetImplementedInterfaces, + JvmtiFunctions::IsInterface, + JvmtiFunctions::IsArrayClass, + JvmtiFunctions::GetClassLoader, + JvmtiFunctions::GetObjectHashCode, + JvmtiFunctions::GetObjectMonitorUsage, + JvmtiFunctions::GetFieldName, // 60 + JvmtiFunctions::GetFieldDeclaringClass, + JvmtiFunctions::GetFieldModifiers, + JvmtiFunctions::IsFieldSynthetic, + JvmtiFunctions::GetMethodName, + JvmtiFunctions::GetMethodDeclaringClass, + JvmtiFunctions::GetMethodModifiers, + nullptr, // reserved67 + JvmtiFunctions::GetMaxLocals, + JvmtiFunctions::GetArgumentsSize, + JvmtiFunctions::GetLineNumberTable, // 70 + JvmtiFunctions::GetMethodLocation, + JvmtiFunctions::GetLocalVariableTable, + JvmtiFunctions::SetNativeMethodPrefix, + JvmtiFunctions::SetNativeMethodPrefixes, + JvmtiFunctions::GetBytecodes, + JvmtiFunctions::IsMethodNative, + JvmtiFunctions::IsMethodSynthetic, + JvmtiFunctions::GetLoadedClasses, + JvmtiFunctions::GetClassLoaderClasses, + JvmtiFunctions::PopFrame, // 80 + JvmtiFunctions::ForceEarlyReturnObject, + JvmtiFunctions::ForceEarlyReturnInt, + JvmtiFunctions::ForceEarlyReturnLong, + JvmtiFunctions::ForceEarlyReturnFloat, + JvmtiFunctions::ForceEarlyReturnDouble, + JvmtiFunctions::ForceEarlyReturnVoid, + JvmtiFunctions::RedefineClasses, + JvmtiFunctions::GetVersionNumber, + JvmtiFunctions::GetCapabilities, + JvmtiFunctions::GetSourceDebugExtension, // 90 + JvmtiFunctions::IsMethodObsolete, + JvmtiFunctions::SuspendThreadList, + JvmtiFunctions::ResumeThreadList, + nullptr, // reserved94 + nullptr, // reserved95 + nullptr, // reserved96 + nullptr, // reserved97 + nullptr, // reserved98 + nullptr, // reserved99 + JvmtiFunctions::GetAllStackTraces, // 100 + JvmtiFunctions::GetThreadListStackTraces, + JvmtiFunctions::GetThreadLocalStorage, + JvmtiFunctions::SetThreadLocalStorage, + JvmtiFunctions::GetStackTrace, + nullptr, // reserved105 + JvmtiFunctions::GetTag, + JvmtiFunctions::SetTag, + JvmtiFunctions::ForceGarbageCollection, + JvmtiFunctions::IterateOverObjectsReachableFromObject, + JvmtiFunctions::IterateOverReachableObjects, // 110 + JvmtiFunctions::IterateOverHeap, + JvmtiFunctions::IterateOverInstancesOfClass, + nullptr, // reserved113 + JvmtiFunctions::GetObjectsWithTags, + JvmtiFunctions::FollowReferences, + JvmtiFunctions::IterateThroughHeap, + nullptr, // reserved117 + nullptr, // reserved118 + nullptr, // reserved119 + JvmtiFunctions::SetJNIFunctionTable, // 120 + JvmtiFunctions::GetJNIFunctionTable, + JvmtiFunctions::SetEventCallbacks, + JvmtiFunctions::GenerateEvents, + JvmtiFunctions::GetExtensionFunctions, + JvmtiFunctions::GetExtensionEvents, + JvmtiFunctions::SetExtensionEventCallback, + JvmtiFunctions::DisposeEnvironment, + JvmtiFunctions::GetErrorName, + JvmtiFunctions::GetJLocationFormat, + JvmtiFunctions::GetSystemProperties, // 130 + JvmtiFunctions::GetSystemProperty, + JvmtiFunctions::SetSystemProperty, + JvmtiFunctions::GetPhase, + JvmtiFunctions::GetCurrentThreadCpuTimerInfo, + JvmtiFunctions::GetCurrentThreadCpuTime, + JvmtiFunctions::GetThreadCpuTimerInfo, + JvmtiFunctions::GetThreadCpuTime, + JvmtiFunctions::GetTimerInfo, + JvmtiFunctions::GetTime, + JvmtiFunctions::GetPotentialCapabilities, // 140 + nullptr, // reserved141 + JvmtiFunctions::AddCapabilities, + JvmtiFunctions::RelinquishCapabilities, + JvmtiFunctions::GetAvailableProcessors, + JvmtiFunctions::GetClassVersionNumbers, + JvmtiFunctions::GetConstantPool, + JvmtiFunctions::GetEnvironmentLocalStorage, + JvmtiFunctions::SetEnvironmentLocalStorage, + JvmtiFunctions::AddToBootstrapClassLoaderSearch, + JvmtiFunctions::SetVerboseFlag, // 150 + JvmtiFunctions::AddToSystemClassLoaderSearch, + JvmtiFunctions::RetransformClasses, + JvmtiFunctions::GetOwnedMonitorStackDepthInfo, + JvmtiFunctions::GetObjectSize, + JvmtiFunctions::GetLocalInstance, +}; + +}; // namespace openjdkjvmti diff --git a/runtime/openjdkjvmti/README.md b/runtime/openjdkjvmti/README.md new file mode 100644 index 0000000000..b8bab573d1 --- /dev/null +++ b/runtime/openjdkjvmti/README.md @@ -0,0 +1,7 @@ +openjdkjvmti plugin +==== + +This is a partial implementation of the JVMTI v1.2 interface for the android +runtime as a plugin. This allows the use of agents that can modify the running +state of the program by modifying dex files in memory and performing other +operations on the global runtime state. diff --git a/runtime/openjdkjvmti/jvmti.h b/runtime/openjdkjvmti/jvmti.h new file mode 100644 index 0000000000..ee708cb193 --- /dev/null +++ b/runtime/openjdkjvmti/jvmti.h @@ -0,0 +1,2534 @@ +/* + * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + + /* AUTOMATICALLY GENERATED FILE - DO NOT EDIT */ + + + /* Include file for the Java(tm) Virtual Machine Tool Interface */ + +#ifndef _JAVA_JVMTI_H_ +#define _JAVA_JVMTI_H_ + +#include "jni.h" + +#ifdef __cplusplus +extern "C" { +#endif + +enum { + JVMTI_VERSION_1 = 0x30010000, + JVMTI_VERSION_1_0 = 0x30010000, + JVMTI_VERSION_1_1 = 0x30010100, + JVMTI_VERSION_1_2 = 0x30010200, + + JVMTI_VERSION = 0x30000000 + (1 * 0x10000) + (2 * 0x100) + 1 /* version: 1.2.1 */ +}; + +JNIEXPORT jint JNICALL +Agent_OnLoad(JavaVM *vm, char *options, void *reserved); + +JNIEXPORT jint JNICALL +Agent_OnAttach(JavaVM* vm, char* options, void* reserved); + +JNIEXPORT void JNICALL +Agent_OnUnload(JavaVM *vm); + + /* Forward declaration of the environment */ + +struct _jvmtiEnv; + +struct jvmtiInterface_1_; + +#ifdef __cplusplus +typedef _jvmtiEnv jvmtiEnv; +#else +typedef const struct jvmtiInterface_1_ *jvmtiEnv; +#endif /* __cplusplus */ + +/* Derived Base Types */ + +typedef jobject jthread; +typedef jobject jthreadGroup; +typedef jlong jlocation; +struct _jrawMonitorID; +typedef struct _jrawMonitorID *jrawMonitorID; +typedef struct JNINativeInterface_ jniNativeInterface; + + /* Constants */ + + + /* Thread State Flags */ + +enum { + JVMTI_THREAD_STATE_ALIVE = 0x0001, + JVMTI_THREAD_STATE_TERMINATED = 0x0002, + JVMTI_THREAD_STATE_RUNNABLE = 0x0004, + JVMTI_THREAD_STATE_BLOCKED_ON_MONITOR_ENTER = 0x0400, + JVMTI_THREAD_STATE_WAITING = 0x0080, + JVMTI_THREAD_STATE_WAITING_INDEFINITELY = 0x0010, + JVMTI_THREAD_STATE_WAITING_WITH_TIMEOUT = 0x0020, + JVMTI_THREAD_STATE_SLEEPING = 0x0040, + JVMTI_THREAD_STATE_IN_OBJECT_WAIT = 0x0100, + JVMTI_THREAD_STATE_PARKED = 0x0200, + JVMTI_THREAD_STATE_SUSPENDED = 0x100000, + JVMTI_THREAD_STATE_INTERRUPTED = 0x200000, + JVMTI_THREAD_STATE_IN_NATIVE = 0x400000, + JVMTI_THREAD_STATE_VENDOR_1 = 0x10000000, + JVMTI_THREAD_STATE_VENDOR_2 = 0x20000000, + JVMTI_THREAD_STATE_VENDOR_3 = 0x40000000 +}; + + /* java.lang.Thread.State Conversion Masks */ + +enum { + JVMTI_JAVA_LANG_THREAD_STATE_MASK = JVMTI_THREAD_STATE_TERMINATED | JVMTI_THREAD_STATE_ALIVE | JVMTI_THREAD_STATE_RUNNABLE | JVMTI_THREAD_STATE_BLOCKED_ON_MONITOR_ENTER | JVMTI_THREAD_STATE_WAITING | JVMTI_THREAD_STATE_WAITING_INDEFINITELY | JVMTI_THREAD_STATE_WAITING_WITH_TIMEOUT, + JVMTI_JAVA_LANG_THREAD_STATE_NEW = 0, + JVMTI_JAVA_LANG_THREAD_STATE_TERMINATED = JVMTI_THREAD_STATE_TERMINATED, + JVMTI_JAVA_LANG_THREAD_STATE_RUNNABLE = JVMTI_THREAD_STATE_ALIVE | JVMTI_THREAD_STATE_RUNNABLE, + JVMTI_JAVA_LANG_THREAD_STATE_BLOCKED = JVMTI_THREAD_STATE_ALIVE | JVMTI_THREAD_STATE_BLOCKED_ON_MONITOR_ENTER, + JVMTI_JAVA_LANG_THREAD_STATE_WAITING = JVMTI_THREAD_STATE_ALIVE | JVMTI_THREAD_STATE_WAITING | JVMTI_THREAD_STATE_WAITING_INDEFINITELY, + JVMTI_JAVA_LANG_THREAD_STATE_TIMED_WAITING = JVMTI_THREAD_STATE_ALIVE | JVMTI_THREAD_STATE_WAITING | JVMTI_THREAD_STATE_WAITING_WITH_TIMEOUT +}; + + /* Thread Priority Constants */ + +enum { + JVMTI_THREAD_MIN_PRIORITY = 1, + JVMTI_THREAD_NORM_PRIORITY = 5, + JVMTI_THREAD_MAX_PRIORITY = 10 +}; + + /* Heap Filter Flags */ + +enum { + JVMTI_HEAP_FILTER_TAGGED = 0x4, + JVMTI_HEAP_FILTER_UNTAGGED = 0x8, + JVMTI_HEAP_FILTER_CLASS_TAGGED = 0x10, + JVMTI_HEAP_FILTER_CLASS_UNTAGGED = 0x20 +}; + + /* Heap Visit Control Flags */ + +enum { + JVMTI_VISIT_OBJECTS = 0x100, + JVMTI_VISIT_ABORT = 0x8000 +}; + + /* Heap Reference Enumeration */ + +typedef enum { + JVMTI_HEAP_REFERENCE_CLASS = 1, + JVMTI_HEAP_REFERENCE_FIELD = 2, + JVMTI_HEAP_REFERENCE_ARRAY_ELEMENT = 3, + JVMTI_HEAP_REFERENCE_CLASS_LOADER = 4, + JVMTI_HEAP_REFERENCE_SIGNERS = 5, + JVMTI_HEAP_REFERENCE_PROTECTION_DOMAIN = 6, + JVMTI_HEAP_REFERENCE_INTERFACE = 7, + JVMTI_HEAP_REFERENCE_STATIC_FIELD = 8, + JVMTI_HEAP_REFERENCE_CONSTANT_POOL = 9, + JVMTI_HEAP_REFERENCE_SUPERCLASS = 10, + JVMTI_HEAP_REFERENCE_JNI_GLOBAL = 21, + JVMTI_HEAP_REFERENCE_SYSTEM_CLASS = 22, + JVMTI_HEAP_REFERENCE_MONITOR = 23, + JVMTI_HEAP_REFERENCE_STACK_LOCAL = 24, + JVMTI_HEAP_REFERENCE_JNI_LOCAL = 25, + JVMTI_HEAP_REFERENCE_THREAD = 26, + JVMTI_HEAP_REFERENCE_OTHER = 27 +} jvmtiHeapReferenceKind; + + /* Primitive Type Enumeration */ + +typedef enum { + JVMTI_PRIMITIVE_TYPE_BOOLEAN = 90, + JVMTI_PRIMITIVE_TYPE_BYTE = 66, + JVMTI_PRIMITIVE_TYPE_CHAR = 67, + JVMTI_PRIMITIVE_TYPE_SHORT = 83, + JVMTI_PRIMITIVE_TYPE_INT = 73, + JVMTI_PRIMITIVE_TYPE_LONG = 74, + JVMTI_PRIMITIVE_TYPE_FLOAT = 70, + JVMTI_PRIMITIVE_TYPE_DOUBLE = 68 +} jvmtiPrimitiveType; + + /* Heap Object Filter Enumeration */ + +typedef enum { + JVMTI_HEAP_OBJECT_TAGGED = 1, + JVMTI_HEAP_OBJECT_UNTAGGED = 2, + JVMTI_HEAP_OBJECT_EITHER = 3 +} jvmtiHeapObjectFilter; + + /* Heap Root Kind Enumeration */ + +typedef enum { + JVMTI_HEAP_ROOT_JNI_GLOBAL = 1, + JVMTI_HEAP_ROOT_SYSTEM_CLASS = 2, + JVMTI_HEAP_ROOT_MONITOR = 3, + JVMTI_HEAP_ROOT_STACK_LOCAL = 4, + JVMTI_HEAP_ROOT_JNI_LOCAL = 5, + JVMTI_HEAP_ROOT_THREAD = 6, + JVMTI_HEAP_ROOT_OTHER = 7 +} jvmtiHeapRootKind; + + /* Object Reference Enumeration */ + +typedef enum { + JVMTI_REFERENCE_CLASS = 1, + JVMTI_REFERENCE_FIELD = 2, + JVMTI_REFERENCE_ARRAY_ELEMENT = 3, + JVMTI_REFERENCE_CLASS_LOADER = 4, + JVMTI_REFERENCE_SIGNERS = 5, + JVMTI_REFERENCE_PROTECTION_DOMAIN = 6, + JVMTI_REFERENCE_INTERFACE = 7, + JVMTI_REFERENCE_STATIC_FIELD = 8, + JVMTI_REFERENCE_CONSTANT_POOL = 9 +} jvmtiObjectReferenceKind; + + /* Iteration Control Enumeration */ + +typedef enum { + JVMTI_ITERATION_CONTINUE = 1, + JVMTI_ITERATION_IGNORE = 2, + JVMTI_ITERATION_ABORT = 0 +} jvmtiIterationControl; + + /* Class Status Flags */ + +enum { + JVMTI_CLASS_STATUS_VERIFIED = 1, + JVMTI_CLASS_STATUS_PREPARED = 2, + JVMTI_CLASS_STATUS_INITIALIZED = 4, + JVMTI_CLASS_STATUS_ERROR = 8, + JVMTI_CLASS_STATUS_ARRAY = 16, + JVMTI_CLASS_STATUS_PRIMITIVE = 32 +}; + + /* Event Enable/Disable */ + +typedef enum { + JVMTI_ENABLE = 1, + JVMTI_DISABLE = 0 +} jvmtiEventMode; + + /* Extension Function/Event Parameter Types */ + +typedef enum { + JVMTI_TYPE_JBYTE = 101, + JVMTI_TYPE_JCHAR = 102, + JVMTI_TYPE_JSHORT = 103, + JVMTI_TYPE_JINT = 104, + JVMTI_TYPE_JLONG = 105, + JVMTI_TYPE_JFLOAT = 106, + JVMTI_TYPE_JDOUBLE = 107, + JVMTI_TYPE_JBOOLEAN = 108, + JVMTI_TYPE_JOBJECT = 109, + JVMTI_TYPE_JTHREAD = 110, + JVMTI_TYPE_JCLASS = 111, + JVMTI_TYPE_JVALUE = 112, + JVMTI_TYPE_JFIELDID = 113, + JVMTI_TYPE_JMETHODID = 114, + JVMTI_TYPE_CCHAR = 115, + JVMTI_TYPE_CVOID = 116, + JVMTI_TYPE_JNIENV = 117 +} jvmtiParamTypes; + + /* Extension Function/Event Parameter Kinds */ + +typedef enum { + JVMTI_KIND_IN = 91, + JVMTI_KIND_IN_PTR = 92, + JVMTI_KIND_IN_BUF = 93, + JVMTI_KIND_ALLOC_BUF = 94, + JVMTI_KIND_ALLOC_ALLOC_BUF = 95, + JVMTI_KIND_OUT = 96, + JVMTI_KIND_OUT_BUF = 97 +} jvmtiParamKind; + + /* Timer Kinds */ + +typedef enum { + JVMTI_TIMER_USER_CPU = 30, + JVMTI_TIMER_TOTAL_CPU = 31, + JVMTI_TIMER_ELAPSED = 32 +} jvmtiTimerKind; + + /* Phases of execution */ + +typedef enum { + JVMTI_PHASE_ONLOAD = 1, + JVMTI_PHASE_PRIMORDIAL = 2, + JVMTI_PHASE_START = 6, + JVMTI_PHASE_LIVE = 4, + JVMTI_PHASE_DEAD = 8 +} jvmtiPhase; + + /* Version Interface Types */ + +enum { + JVMTI_VERSION_INTERFACE_JNI = 0x00000000, + JVMTI_VERSION_INTERFACE_JVMTI = 0x30000000 +}; + + /* Version Masks */ + +enum { + JVMTI_VERSION_MASK_INTERFACE_TYPE = 0x70000000, + JVMTI_VERSION_MASK_MAJOR = 0x0FFF0000, + JVMTI_VERSION_MASK_MINOR = 0x0000FF00, + JVMTI_VERSION_MASK_MICRO = 0x000000FF +}; + + /* Version Shifts */ + +enum { + JVMTI_VERSION_SHIFT_MAJOR = 16, + JVMTI_VERSION_SHIFT_MINOR = 8, + JVMTI_VERSION_SHIFT_MICRO = 0 +}; + + /* Verbose Flag Enumeration */ + +typedef enum { + JVMTI_VERBOSE_OTHER = 0, + JVMTI_VERBOSE_GC = 1, + JVMTI_VERBOSE_CLASS = 2, + JVMTI_VERBOSE_JNI = 4 +} jvmtiVerboseFlag; + + /* JLocation Format Enumeration */ + +typedef enum { + JVMTI_JLOCATION_JVMBCI = 1, + JVMTI_JLOCATION_MACHINEPC = 2, + JVMTI_JLOCATION_OTHER = 0 +} jvmtiJlocationFormat; + + /* Resource Exhaustion Flags */ + +enum { + JVMTI_RESOURCE_EXHAUSTED_OOM_ERROR = 0x0001, + JVMTI_RESOURCE_EXHAUSTED_JAVA_HEAP = 0x0002, + JVMTI_RESOURCE_EXHAUSTED_THREADS = 0x0004 +}; + + /* Errors */ + +typedef enum { + JVMTI_ERROR_NONE = 0, + JVMTI_ERROR_INVALID_THREAD = 10, + JVMTI_ERROR_INVALID_THREAD_GROUP = 11, + JVMTI_ERROR_INVALID_PRIORITY = 12, + JVMTI_ERROR_THREAD_NOT_SUSPENDED = 13, + JVMTI_ERROR_THREAD_SUSPENDED = 14, + JVMTI_ERROR_THREAD_NOT_ALIVE = 15, + JVMTI_ERROR_INVALID_OBJECT = 20, + JVMTI_ERROR_INVALID_CLASS = 21, + JVMTI_ERROR_CLASS_NOT_PREPARED = 22, + JVMTI_ERROR_INVALID_METHODID = 23, + JVMTI_ERROR_INVALID_LOCATION = 24, + JVMTI_ERROR_INVALID_FIELDID = 25, + JVMTI_ERROR_NO_MORE_FRAMES = 31, + JVMTI_ERROR_OPAQUE_FRAME = 32, + JVMTI_ERROR_TYPE_MISMATCH = 34, + JVMTI_ERROR_INVALID_SLOT = 35, + JVMTI_ERROR_DUPLICATE = 40, + JVMTI_ERROR_NOT_FOUND = 41, + JVMTI_ERROR_INVALID_MONITOR = 50, + JVMTI_ERROR_NOT_MONITOR_OWNER = 51, + JVMTI_ERROR_INTERRUPT = 52, + JVMTI_ERROR_INVALID_CLASS_FORMAT = 60, + JVMTI_ERROR_CIRCULAR_CLASS_DEFINITION = 61, + JVMTI_ERROR_FAILS_VERIFICATION = 62, + JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_ADDED = 63, + JVMTI_ERROR_UNSUPPORTED_REDEFINITION_SCHEMA_CHANGED = 64, + JVMTI_ERROR_INVALID_TYPESTATE = 65, + JVMTI_ERROR_UNSUPPORTED_REDEFINITION_HIERARCHY_CHANGED = 66, + JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_DELETED = 67, + JVMTI_ERROR_UNSUPPORTED_VERSION = 68, + JVMTI_ERROR_NAMES_DONT_MATCH = 69, + JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_MODIFIERS_CHANGED = 70, + JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_MODIFIERS_CHANGED = 71, + JVMTI_ERROR_UNMODIFIABLE_CLASS = 79, + JVMTI_ERROR_NOT_AVAILABLE = 98, + JVMTI_ERROR_MUST_POSSESS_CAPABILITY = 99, + JVMTI_ERROR_NULL_POINTER = 100, + JVMTI_ERROR_ABSENT_INFORMATION = 101, + JVMTI_ERROR_INVALID_EVENT_TYPE = 102, + JVMTI_ERROR_ILLEGAL_ARGUMENT = 103, + JVMTI_ERROR_NATIVE_METHOD = 104, + JVMTI_ERROR_CLASS_LOADER_UNSUPPORTED = 106, + JVMTI_ERROR_OUT_OF_MEMORY = 110, + JVMTI_ERROR_ACCESS_DENIED = 111, + JVMTI_ERROR_WRONG_PHASE = 112, + JVMTI_ERROR_INTERNAL = 113, + JVMTI_ERROR_UNATTACHED_THREAD = 115, + JVMTI_ERROR_INVALID_ENVIRONMENT = 116, + JVMTI_ERROR_MAX = 116 +} jvmtiError; + + /* Event IDs */ + +typedef enum { + JVMTI_MIN_EVENT_TYPE_VAL = 50, + JVMTI_EVENT_VM_INIT = 50, + JVMTI_EVENT_VM_DEATH = 51, + JVMTI_EVENT_THREAD_START = 52, + JVMTI_EVENT_THREAD_END = 53, + JVMTI_EVENT_CLASS_FILE_LOAD_HOOK = 54, + JVMTI_EVENT_CLASS_LOAD = 55, + JVMTI_EVENT_CLASS_PREPARE = 56, + JVMTI_EVENT_VM_START = 57, + JVMTI_EVENT_EXCEPTION = 58, + JVMTI_EVENT_EXCEPTION_CATCH = 59, + JVMTI_EVENT_SINGLE_STEP = 60, + JVMTI_EVENT_FRAME_POP = 61, + JVMTI_EVENT_BREAKPOINT = 62, + JVMTI_EVENT_FIELD_ACCESS = 63, + JVMTI_EVENT_FIELD_MODIFICATION = 64, + JVMTI_EVENT_METHOD_ENTRY = 65, + JVMTI_EVENT_METHOD_EXIT = 66, + JVMTI_EVENT_NATIVE_METHOD_BIND = 67, + JVMTI_EVENT_COMPILED_METHOD_LOAD = 68, + JVMTI_EVENT_COMPILED_METHOD_UNLOAD = 69, + JVMTI_EVENT_DYNAMIC_CODE_GENERATED = 70, + JVMTI_EVENT_DATA_DUMP_REQUEST = 71, + JVMTI_EVENT_MONITOR_WAIT = 73, + JVMTI_EVENT_MONITOR_WAITED = 74, + JVMTI_EVENT_MONITOR_CONTENDED_ENTER = 75, + JVMTI_EVENT_MONITOR_CONTENDED_ENTERED = 76, + JVMTI_EVENT_RESOURCE_EXHAUSTED = 80, + JVMTI_EVENT_GARBAGE_COLLECTION_START = 81, + JVMTI_EVENT_GARBAGE_COLLECTION_FINISH = 82, + JVMTI_EVENT_OBJECT_FREE = 83, + JVMTI_EVENT_VM_OBJECT_ALLOC = 84, + JVMTI_MAX_EVENT_TYPE_VAL = 84 +} jvmtiEvent; + + + /* Pre-Declarations */ +struct _jvmtiThreadInfo; +typedef struct _jvmtiThreadInfo jvmtiThreadInfo; +struct _jvmtiMonitorStackDepthInfo; +typedef struct _jvmtiMonitorStackDepthInfo jvmtiMonitorStackDepthInfo; +struct _jvmtiThreadGroupInfo; +typedef struct _jvmtiThreadGroupInfo jvmtiThreadGroupInfo; +struct _jvmtiFrameInfo; +typedef struct _jvmtiFrameInfo jvmtiFrameInfo; +struct _jvmtiStackInfo; +typedef struct _jvmtiStackInfo jvmtiStackInfo; +struct _jvmtiHeapReferenceInfoField; +typedef struct _jvmtiHeapReferenceInfoField jvmtiHeapReferenceInfoField; +struct _jvmtiHeapReferenceInfoArray; +typedef struct _jvmtiHeapReferenceInfoArray jvmtiHeapReferenceInfoArray; +struct _jvmtiHeapReferenceInfoConstantPool; +typedef struct _jvmtiHeapReferenceInfoConstantPool jvmtiHeapReferenceInfoConstantPool; +struct _jvmtiHeapReferenceInfoStackLocal; +typedef struct _jvmtiHeapReferenceInfoStackLocal jvmtiHeapReferenceInfoStackLocal; +struct _jvmtiHeapReferenceInfoJniLocal; +typedef struct _jvmtiHeapReferenceInfoJniLocal jvmtiHeapReferenceInfoJniLocal; +struct _jvmtiHeapReferenceInfoReserved; +typedef struct _jvmtiHeapReferenceInfoReserved jvmtiHeapReferenceInfoReserved; +union _jvmtiHeapReferenceInfo; +typedef union _jvmtiHeapReferenceInfo jvmtiHeapReferenceInfo; +struct _jvmtiHeapCallbacks; +typedef struct _jvmtiHeapCallbacks jvmtiHeapCallbacks; +struct _jvmtiClassDefinition; +typedef struct _jvmtiClassDefinition jvmtiClassDefinition; +struct _jvmtiMonitorUsage; +typedef struct _jvmtiMonitorUsage jvmtiMonitorUsage; +struct _jvmtiLineNumberEntry; +typedef struct _jvmtiLineNumberEntry jvmtiLineNumberEntry; +struct _jvmtiLocalVariableEntry; +typedef struct _jvmtiLocalVariableEntry jvmtiLocalVariableEntry; +struct _jvmtiParamInfo; +typedef struct _jvmtiParamInfo jvmtiParamInfo; +struct _jvmtiExtensionFunctionInfo; +typedef struct _jvmtiExtensionFunctionInfo jvmtiExtensionFunctionInfo; +struct _jvmtiExtensionEventInfo; +typedef struct _jvmtiExtensionEventInfo jvmtiExtensionEventInfo; +struct _jvmtiTimerInfo; +typedef struct _jvmtiTimerInfo jvmtiTimerInfo; +struct _jvmtiAddrLocationMap; +typedef struct _jvmtiAddrLocationMap jvmtiAddrLocationMap; + + /* Function Types */ + +typedef void (JNICALL *jvmtiStartFunction) + (jvmtiEnv* jvmti_env, JNIEnv* jni_env, void* arg); + +typedef jint (JNICALL *jvmtiHeapIterationCallback) + (jlong class_tag, jlong size, jlong* tag_ptr, jint length, void* user_data); + +typedef jint (JNICALL *jvmtiHeapReferenceCallback) + (jvmtiHeapReferenceKind reference_kind, const jvmtiHeapReferenceInfo* reference_info, jlong class_tag, jlong referrer_class_tag, jlong size, jlong* tag_ptr, jlong* referrer_tag_ptr, jint length, void* user_data); + +typedef jint (JNICALL *jvmtiPrimitiveFieldCallback) + (jvmtiHeapReferenceKind kind, const jvmtiHeapReferenceInfo* info, jlong object_class_tag, jlong* object_tag_ptr, jvalue value, jvmtiPrimitiveType value_type, void* user_data); + +typedef jint (JNICALL *jvmtiArrayPrimitiveValueCallback) + (jlong class_tag, jlong size, jlong* tag_ptr, jint element_count, jvmtiPrimitiveType element_type, const void* elements, void* user_data); + +typedef jint (JNICALL *jvmtiStringPrimitiveValueCallback) + (jlong class_tag, jlong size, jlong* tag_ptr, const jchar* value, jint value_length, void* user_data); + +typedef jint (JNICALL *jvmtiReservedCallback) + (); + +typedef jvmtiIterationControl (JNICALL *jvmtiHeapObjectCallback) + (jlong class_tag, jlong size, jlong* tag_ptr, void* user_data); + +typedef jvmtiIterationControl (JNICALL *jvmtiHeapRootCallback) + (jvmtiHeapRootKind root_kind, jlong class_tag, jlong size, jlong* tag_ptr, void* user_data); + +typedef jvmtiIterationControl (JNICALL *jvmtiStackReferenceCallback) + (jvmtiHeapRootKind root_kind, jlong class_tag, jlong size, jlong* tag_ptr, jlong thread_tag, jint depth, jmethodID method, jint slot, void* user_data); + +typedef jvmtiIterationControl (JNICALL *jvmtiObjectReferenceCallback) + (jvmtiObjectReferenceKind reference_kind, jlong class_tag, jlong size, jlong* tag_ptr, jlong referrer_tag, jint referrer_index, void* user_data); + +typedef jvmtiError (JNICALL *jvmtiExtensionFunction) + (jvmtiEnv* jvmti_env, ...); + +typedef void (JNICALL *jvmtiExtensionEvent) + (jvmtiEnv* jvmti_env, ...); + + + /* Structure Types */ +struct _jvmtiThreadInfo { + char* name; + jint priority; + jboolean is_daemon; + jthreadGroup thread_group; + jobject context_class_loader; +}; +struct _jvmtiMonitorStackDepthInfo { + jobject monitor; + jint stack_depth; +}; +struct _jvmtiThreadGroupInfo { + jthreadGroup parent; + char* name; + jint max_priority; + jboolean is_daemon; +}; +struct _jvmtiFrameInfo { + jmethodID method; + jlocation location; +}; +struct _jvmtiStackInfo { + jthread thread; + jint state; + jvmtiFrameInfo* frame_buffer; + jint frame_count; +}; +struct _jvmtiHeapReferenceInfoField { + jint index; +}; +struct _jvmtiHeapReferenceInfoArray { + jint index; +}; +struct _jvmtiHeapReferenceInfoConstantPool { + jint index; +}; +struct _jvmtiHeapReferenceInfoStackLocal { + jlong thread_tag; + jlong thread_id; + jint depth; + jmethodID method; + jlocation location; + jint slot; +}; +struct _jvmtiHeapReferenceInfoJniLocal { + jlong thread_tag; + jlong thread_id; + jint depth; + jmethodID method; +}; +struct _jvmtiHeapReferenceInfoReserved { + jlong reserved1; + jlong reserved2; + jlong reserved3; + jlong reserved4; + jlong reserved5; + jlong reserved6; + jlong reserved7; + jlong reserved8; +}; +union _jvmtiHeapReferenceInfo { + jvmtiHeapReferenceInfoField field; + jvmtiHeapReferenceInfoArray array; + jvmtiHeapReferenceInfoConstantPool constant_pool; + jvmtiHeapReferenceInfoStackLocal stack_local; + jvmtiHeapReferenceInfoJniLocal jni_local; + jvmtiHeapReferenceInfoReserved other; +}; +struct _jvmtiHeapCallbacks { + jvmtiHeapIterationCallback heap_iteration_callback; + jvmtiHeapReferenceCallback heap_reference_callback; + jvmtiPrimitiveFieldCallback primitive_field_callback; + jvmtiArrayPrimitiveValueCallback array_primitive_value_callback; + jvmtiStringPrimitiveValueCallback string_primitive_value_callback; + jvmtiReservedCallback reserved5; + jvmtiReservedCallback reserved6; + jvmtiReservedCallback reserved7; + jvmtiReservedCallback reserved8; + jvmtiReservedCallback reserved9; + jvmtiReservedCallback reserved10; + jvmtiReservedCallback reserved11; + jvmtiReservedCallback reserved12; + jvmtiReservedCallback reserved13; + jvmtiReservedCallback reserved14; + jvmtiReservedCallback reserved15; +}; +struct _jvmtiClassDefinition { + jclass klass; + jint class_byte_count; + const unsigned char* class_bytes; +}; +struct _jvmtiMonitorUsage { + jthread owner; + jint entry_count; + jint waiter_count; + jthread* waiters; + jint notify_waiter_count; + jthread* notify_waiters; +}; +struct _jvmtiLineNumberEntry { + jlocation start_location; + jint line_number; +}; +struct _jvmtiLocalVariableEntry { + jlocation start_location; + jint length; + char* name; + char* signature; + char* generic_signature; + jint slot; +}; +struct _jvmtiParamInfo { + char* name; + jvmtiParamKind kind; + jvmtiParamTypes base_type; + jboolean null_ok; +}; +struct _jvmtiExtensionFunctionInfo { + jvmtiExtensionFunction func; + char* id; + char* short_description; + jint param_count; + jvmtiParamInfo* params; + jint error_count; + jvmtiError* errors; +}; +struct _jvmtiExtensionEventInfo { + jint extension_event_index; + char* id; + char* short_description; + jint param_count; + jvmtiParamInfo* params; +}; +struct _jvmtiTimerInfo { + jlong max_value; + jboolean may_skip_forward; + jboolean may_skip_backward; + jvmtiTimerKind kind; + jlong reserved1; + jlong reserved2; +}; +struct _jvmtiAddrLocationMap { + const void* start_address; + jlocation location; +}; + +typedef struct { + unsigned int can_tag_objects : 1; + unsigned int can_generate_field_modification_events : 1; + unsigned int can_generate_field_access_events : 1; + unsigned int can_get_bytecodes : 1; + unsigned int can_get_synthetic_attribute : 1; + unsigned int can_get_owned_monitor_info : 1; + unsigned int can_get_current_contended_monitor : 1; + unsigned int can_get_monitor_info : 1; + unsigned int can_pop_frame : 1; + unsigned int can_redefine_classes : 1; + unsigned int can_signal_thread : 1; + unsigned int can_get_source_file_name : 1; + unsigned int can_get_line_numbers : 1; + unsigned int can_get_source_debug_extension : 1; + unsigned int can_access_local_variables : 1; + unsigned int can_maintain_original_method_order : 1; + unsigned int can_generate_single_step_events : 1; + unsigned int can_generate_exception_events : 1; + unsigned int can_generate_frame_pop_events : 1; + unsigned int can_generate_breakpoint_events : 1; + unsigned int can_suspend : 1; + unsigned int can_redefine_any_class : 1; + unsigned int can_get_current_thread_cpu_time : 1; + unsigned int can_get_thread_cpu_time : 1; + unsigned int can_generate_method_entry_events : 1; + unsigned int can_generate_method_exit_events : 1; + unsigned int can_generate_all_class_hook_events : 1; + unsigned int can_generate_compiled_method_load_events : 1; + unsigned int can_generate_monitor_events : 1; + unsigned int can_generate_vm_object_alloc_events : 1; + unsigned int can_generate_native_method_bind_events : 1; + unsigned int can_generate_garbage_collection_events : 1; + unsigned int can_generate_object_free_events : 1; + unsigned int can_force_early_return : 1; + unsigned int can_get_owned_monitor_stack_depth_info : 1; + unsigned int can_get_constant_pool : 1; + unsigned int can_set_native_method_prefix : 1; + unsigned int can_retransform_classes : 1; + unsigned int can_retransform_any_class : 1; + unsigned int can_generate_resource_exhaustion_heap_events : 1; + unsigned int can_generate_resource_exhaustion_threads_events : 1; + unsigned int : 7; + unsigned int : 16; + unsigned int : 16; + unsigned int : 16; + unsigned int : 16; + unsigned int : 16; +} jvmtiCapabilities; + + + /* Event Definitions */ + +typedef void (JNICALL *jvmtiEventReserved)(void); + + +typedef void (JNICALL *jvmtiEventBreakpoint) + (jvmtiEnv *jvmti_env, + JNIEnv* jni_env, + jthread thread, + jmethodID method, + jlocation location); + +typedef void (JNICALL *jvmtiEventClassFileLoadHook) + (jvmtiEnv *jvmti_env, + JNIEnv* jni_env, + jclass class_being_redefined, + jobject loader, + const char* name, + jobject protection_domain, + jint class_data_len, + const unsigned char* class_data, + jint* new_class_data_len, + unsigned char** new_class_data); + +typedef void (JNICALL *jvmtiEventClassLoad) + (jvmtiEnv *jvmti_env, + JNIEnv* jni_env, + jthread thread, + jclass klass); + +typedef void (JNICALL *jvmtiEventClassPrepare) + (jvmtiEnv *jvmti_env, + JNIEnv* jni_env, + jthread thread, + jclass klass); + +typedef void (JNICALL *jvmtiEventCompiledMethodLoad) + (jvmtiEnv *jvmti_env, + jmethodID method, + jint code_size, + const void* code_addr, + jint map_length, + const jvmtiAddrLocationMap* map, + const void* compile_info); + +typedef void (JNICALL *jvmtiEventCompiledMethodUnload) + (jvmtiEnv *jvmti_env, + jmethodID method, + const void* code_addr); + +typedef void (JNICALL *jvmtiEventDataDumpRequest) + (jvmtiEnv *jvmti_env); + +typedef void (JNICALL *jvmtiEventDynamicCodeGenerated) + (jvmtiEnv *jvmti_env, + const char* name, + const void* address, + jint length); + +typedef void (JNICALL *jvmtiEventException) + (jvmtiEnv *jvmti_env, + JNIEnv* jni_env, + jthread thread, + jmethodID method, + jlocation location, + jobject exception, + jmethodID catch_method, + jlocation catch_location); + +typedef void (JNICALL *jvmtiEventExceptionCatch) + (jvmtiEnv *jvmti_env, + JNIEnv* jni_env, + jthread thread, + jmethodID method, + jlocation location, + jobject exception); + +typedef void (JNICALL *jvmtiEventFieldAccess) + (jvmtiEnv *jvmti_env, + JNIEnv* jni_env, + jthread thread, + jmethodID method, + jlocation location, + jclass field_klass, + jobject object, + jfieldID field); + +typedef void (JNICALL *jvmtiEventFieldModification) + (jvmtiEnv *jvmti_env, + JNIEnv* jni_env, + jthread thread, + jmethodID method, + jlocation location, + jclass field_klass, + jobject object, + jfieldID field, + char signature_type, + jvalue new_value); + +typedef void (JNICALL *jvmtiEventFramePop) + (jvmtiEnv *jvmti_env, + JNIEnv* jni_env, + jthread thread, + jmethodID method, + jboolean was_popped_by_exception); + +typedef void (JNICALL *jvmtiEventGarbageCollectionFinish) + (jvmtiEnv *jvmti_env); + +typedef void (JNICALL *jvmtiEventGarbageCollectionStart) + (jvmtiEnv *jvmti_env); + +typedef void (JNICALL *jvmtiEventMethodEntry) + (jvmtiEnv *jvmti_env, + JNIEnv* jni_env, + jthread thread, + jmethodID method); + +typedef void (JNICALL *jvmtiEventMethodExit) + (jvmtiEnv *jvmti_env, + JNIEnv* jni_env, + jthread thread, + jmethodID method, + jboolean was_popped_by_exception, + jvalue return_value); + +typedef void (JNICALL *jvmtiEventMonitorContendedEnter) + (jvmtiEnv *jvmti_env, + JNIEnv* jni_env, + jthread thread, + jobject object); + +typedef void (JNICALL *jvmtiEventMonitorContendedEntered) + (jvmtiEnv *jvmti_env, + JNIEnv* jni_env, + jthread thread, + jobject object); + +typedef void (JNICALL *jvmtiEventMonitorWait) + (jvmtiEnv *jvmti_env, + JNIEnv* jni_env, + jthread thread, + jobject object, + jlong timeout); + +typedef void (JNICALL *jvmtiEventMonitorWaited) + (jvmtiEnv *jvmti_env, + JNIEnv* jni_env, + jthread thread, + jobject object, + jboolean timed_out); + +typedef void (JNICALL *jvmtiEventNativeMethodBind) + (jvmtiEnv *jvmti_env, + JNIEnv* jni_env, + jthread thread, + jmethodID method, + void* address, + void** new_address_ptr); + +typedef void (JNICALL *jvmtiEventObjectFree) + (jvmtiEnv *jvmti_env, + jlong tag); + +typedef void (JNICALL *jvmtiEventResourceExhausted) + (jvmtiEnv *jvmti_env, + JNIEnv* jni_env, + jint flags, + const void* reserved, + const char* description); + +typedef void (JNICALL *jvmtiEventSingleStep) + (jvmtiEnv *jvmti_env, + JNIEnv* jni_env, + jthread thread, + jmethodID method, + jlocation location); + +typedef void (JNICALL *jvmtiEventThreadEnd) + (jvmtiEnv *jvmti_env, + JNIEnv* jni_env, + jthread thread); + +typedef void (JNICALL *jvmtiEventThreadStart) + (jvmtiEnv *jvmti_env, + JNIEnv* jni_env, + jthread thread); + +typedef void (JNICALL *jvmtiEventVMDeath) + (jvmtiEnv *jvmti_env, + JNIEnv* jni_env); + +typedef void (JNICALL *jvmtiEventVMInit) + (jvmtiEnv *jvmti_env, + JNIEnv* jni_env, + jthread thread); + +typedef void (JNICALL *jvmtiEventVMObjectAlloc) + (jvmtiEnv *jvmti_env, + JNIEnv* jni_env, + jthread thread, + jobject object, + jclass object_klass, + jlong size); + +typedef void (JNICALL *jvmtiEventVMStart) + (jvmtiEnv *jvmti_env, + JNIEnv* jni_env); + + /* Event Callback Structure */ + +typedef struct { + /* 50 : VM Initialization Event */ + jvmtiEventVMInit VMInit; + /* 51 : VM Death Event */ + jvmtiEventVMDeath VMDeath; + /* 52 : Thread Start */ + jvmtiEventThreadStart ThreadStart; + /* 53 : Thread End */ + jvmtiEventThreadEnd ThreadEnd; + /* 54 : Class File Load Hook */ + jvmtiEventClassFileLoadHook ClassFileLoadHook; + /* 55 : Class Load */ + jvmtiEventClassLoad ClassLoad; + /* 56 : Class Prepare */ + jvmtiEventClassPrepare ClassPrepare; + /* 57 : VM Start Event */ + jvmtiEventVMStart VMStart; + /* 58 : Exception */ + jvmtiEventException Exception; + /* 59 : Exception Catch */ + jvmtiEventExceptionCatch ExceptionCatch; + /* 60 : Single Step */ + jvmtiEventSingleStep SingleStep; + /* 61 : Frame Pop */ + jvmtiEventFramePop FramePop; + /* 62 : Breakpoint */ + jvmtiEventBreakpoint Breakpoint; + /* 63 : Field Access */ + jvmtiEventFieldAccess FieldAccess; + /* 64 : Field Modification */ + jvmtiEventFieldModification FieldModification; + /* 65 : Method Entry */ + jvmtiEventMethodEntry MethodEntry; + /* 66 : Method Exit */ + jvmtiEventMethodExit MethodExit; + /* 67 : Native Method Bind */ + jvmtiEventNativeMethodBind NativeMethodBind; + /* 68 : Compiled Method Load */ + jvmtiEventCompiledMethodLoad CompiledMethodLoad; + /* 69 : Compiled Method Unload */ + jvmtiEventCompiledMethodUnload CompiledMethodUnload; + /* 70 : Dynamic Code Generated */ + jvmtiEventDynamicCodeGenerated DynamicCodeGenerated; + /* 71 : Data Dump Request */ + jvmtiEventDataDumpRequest DataDumpRequest; + /* 72 */ + jvmtiEventReserved reserved72; + /* 73 : Monitor Wait */ + jvmtiEventMonitorWait MonitorWait; + /* 74 : Monitor Waited */ + jvmtiEventMonitorWaited MonitorWaited; + /* 75 : Monitor Contended Enter */ + jvmtiEventMonitorContendedEnter MonitorContendedEnter; + /* 76 : Monitor Contended Entered */ + jvmtiEventMonitorContendedEntered MonitorContendedEntered; + /* 77 */ + jvmtiEventReserved reserved77; + /* 78 */ + jvmtiEventReserved reserved78; + /* 79 */ + jvmtiEventReserved reserved79; + /* 80 : Resource Exhausted */ + jvmtiEventResourceExhausted ResourceExhausted; + /* 81 : Garbage Collection Start */ + jvmtiEventGarbageCollectionStart GarbageCollectionStart; + /* 82 : Garbage Collection Finish */ + jvmtiEventGarbageCollectionFinish GarbageCollectionFinish; + /* 83 : Object Free */ + jvmtiEventObjectFree ObjectFree; + /* 84 : VM Object Allocation */ + jvmtiEventVMObjectAlloc VMObjectAlloc; +} jvmtiEventCallbacks; + + + /* Function Interface */ + +typedef struct jvmtiInterface_1_ { + + /* 1 : RESERVED */ + void *reserved1; + + /* 2 : Set Event Notification Mode */ + jvmtiError (JNICALL *SetEventNotificationMode) (jvmtiEnv* env, + jvmtiEventMode mode, + jvmtiEvent event_type, + jthread event_thread, + ...); + + /* 3 : RESERVED */ + void *reserved3; + + /* 4 : Get All Threads */ + jvmtiError (JNICALL *GetAllThreads) (jvmtiEnv* env, + jint* threads_count_ptr, + jthread** threads_ptr); + + /* 5 : Suspend Thread */ + jvmtiError (JNICALL *SuspendThread) (jvmtiEnv* env, + jthread thread); + + /* 6 : Resume Thread */ + jvmtiError (JNICALL *ResumeThread) (jvmtiEnv* env, + jthread thread); + + /* 7 : Stop Thread */ + jvmtiError (JNICALL *StopThread) (jvmtiEnv* env, + jthread thread, + jobject exception); + + /* 8 : Interrupt Thread */ + jvmtiError (JNICALL *InterruptThread) (jvmtiEnv* env, + jthread thread); + + /* 9 : Get Thread Info */ + jvmtiError (JNICALL *GetThreadInfo) (jvmtiEnv* env, + jthread thread, + jvmtiThreadInfo* info_ptr); + + /* 10 : Get Owned Monitor Info */ + jvmtiError (JNICALL *GetOwnedMonitorInfo) (jvmtiEnv* env, + jthread thread, + jint* owned_monitor_count_ptr, + jobject** owned_monitors_ptr); + + /* 11 : Get Current Contended Monitor */ + jvmtiError (JNICALL *GetCurrentContendedMonitor) (jvmtiEnv* env, + jthread thread, + jobject* monitor_ptr); + + /* 12 : Run Agent Thread */ + jvmtiError (JNICALL *RunAgentThread) (jvmtiEnv* env, + jthread thread, + jvmtiStartFunction proc, + const void* arg, + jint priority); + + /* 13 : Get Top Thread Groups */ + jvmtiError (JNICALL *GetTopThreadGroups) (jvmtiEnv* env, + jint* group_count_ptr, + jthreadGroup** groups_ptr); + + /* 14 : Get Thread Group Info */ + jvmtiError (JNICALL *GetThreadGroupInfo) (jvmtiEnv* env, + jthreadGroup group, + jvmtiThreadGroupInfo* info_ptr); + + /* 15 : Get Thread Group Children */ + jvmtiError (JNICALL *GetThreadGroupChildren) (jvmtiEnv* env, + jthreadGroup group, + jint* thread_count_ptr, + jthread** threads_ptr, + jint* group_count_ptr, + jthreadGroup** groups_ptr); + + /* 16 : Get Frame Count */ + jvmtiError (JNICALL *GetFrameCount) (jvmtiEnv* env, + jthread thread, + jint* count_ptr); + + /* 17 : Get Thread State */ + jvmtiError (JNICALL *GetThreadState) (jvmtiEnv* env, + jthread thread, + jint* thread_state_ptr); + + /* 18 : Get Current Thread */ + jvmtiError (JNICALL *GetCurrentThread) (jvmtiEnv* env, + jthread* thread_ptr); + + /* 19 : Get Frame Location */ + jvmtiError (JNICALL *GetFrameLocation) (jvmtiEnv* env, + jthread thread, + jint depth, + jmethodID* method_ptr, + jlocation* location_ptr); + + /* 20 : Notify Frame Pop */ + jvmtiError (JNICALL *NotifyFramePop) (jvmtiEnv* env, + jthread thread, + jint depth); + + /* 21 : Get Local Variable - Object */ + jvmtiError (JNICALL *GetLocalObject) (jvmtiEnv* env, + jthread thread, + jint depth, + jint slot, + jobject* value_ptr); + + /* 22 : Get Local Variable - Int */ + jvmtiError (JNICALL *GetLocalInt) (jvmtiEnv* env, + jthread thread, + jint depth, + jint slot, + jint* value_ptr); + + /* 23 : Get Local Variable - Long */ + jvmtiError (JNICALL *GetLocalLong) (jvmtiEnv* env, + jthread thread, + jint depth, + jint slot, + jlong* value_ptr); + + /* 24 : Get Local Variable - Float */ + jvmtiError (JNICALL *GetLocalFloat) (jvmtiEnv* env, + jthread thread, + jint depth, + jint slot, + jfloat* value_ptr); + + /* 25 : Get Local Variable - Double */ + jvmtiError (JNICALL *GetLocalDouble) (jvmtiEnv* env, + jthread thread, + jint depth, + jint slot, + jdouble* value_ptr); + + /* 26 : Set Local Variable - Object */ + jvmtiError (JNICALL *SetLocalObject) (jvmtiEnv* env, + jthread thread, + jint depth, + jint slot, + jobject value); + + /* 27 : Set Local Variable - Int */ + jvmtiError (JNICALL *SetLocalInt) (jvmtiEnv* env, + jthread thread, + jint depth, + jint slot, + jint value); + + /* 28 : Set Local Variable - Long */ + jvmtiError (JNICALL *SetLocalLong) (jvmtiEnv* env, + jthread thread, + jint depth, + jint slot, + jlong value); + + /* 29 : Set Local Variable - Float */ + jvmtiError (JNICALL *SetLocalFloat) (jvmtiEnv* env, + jthread thread, + jint depth, + jint slot, + jfloat value); + + /* 30 : Set Local Variable - Double */ + jvmtiError (JNICALL *SetLocalDouble) (jvmtiEnv* env, + jthread thread, + jint depth, + jint slot, + jdouble value); + + /* 31 : Create Raw Monitor */ + jvmtiError (JNICALL *CreateRawMonitor) (jvmtiEnv* env, + const char* name, + jrawMonitorID* monitor_ptr); + + /* 32 : Destroy Raw Monitor */ + jvmtiError (JNICALL *DestroyRawMonitor) (jvmtiEnv* env, + jrawMonitorID monitor); + + /* 33 : Raw Monitor Enter */ + jvmtiError (JNICALL *RawMonitorEnter) (jvmtiEnv* env, + jrawMonitorID monitor); + + /* 34 : Raw Monitor Exit */ + jvmtiError (JNICALL *RawMonitorExit) (jvmtiEnv* env, + jrawMonitorID monitor); + + /* 35 : Raw Monitor Wait */ + jvmtiError (JNICALL *RawMonitorWait) (jvmtiEnv* env, + jrawMonitorID monitor, + jlong millis); + + /* 36 : Raw Monitor Notify */ + jvmtiError (JNICALL *RawMonitorNotify) (jvmtiEnv* env, + jrawMonitorID monitor); + + /* 37 : Raw Monitor Notify All */ + jvmtiError (JNICALL *RawMonitorNotifyAll) (jvmtiEnv* env, + jrawMonitorID monitor); + + /* 38 : Set Breakpoint */ + jvmtiError (JNICALL *SetBreakpoint) (jvmtiEnv* env, + jmethodID method, + jlocation location); + + /* 39 : Clear Breakpoint */ + jvmtiError (JNICALL *ClearBreakpoint) (jvmtiEnv* env, + jmethodID method, + jlocation location); + + /* 40 : RESERVED */ + void *reserved40; + + /* 41 : Set Field Access Watch */ + jvmtiError (JNICALL *SetFieldAccessWatch) (jvmtiEnv* env, + jclass klass, + jfieldID field); + + /* 42 : Clear Field Access Watch */ + jvmtiError (JNICALL *ClearFieldAccessWatch) (jvmtiEnv* env, + jclass klass, + jfieldID field); + + /* 43 : Set Field Modification Watch */ + jvmtiError (JNICALL *SetFieldModificationWatch) (jvmtiEnv* env, + jclass klass, + jfieldID field); + + /* 44 : Clear Field Modification Watch */ + jvmtiError (JNICALL *ClearFieldModificationWatch) (jvmtiEnv* env, + jclass klass, + jfieldID field); + + /* 45 : Is Modifiable Class */ + jvmtiError (JNICALL *IsModifiableClass) (jvmtiEnv* env, + jclass klass, + jboolean* is_modifiable_class_ptr); + + /* 46 : Allocate */ + jvmtiError (JNICALL *Allocate) (jvmtiEnv* env, + jlong size, + unsigned char** mem_ptr); + + /* 47 : Deallocate */ + jvmtiError (JNICALL *Deallocate) (jvmtiEnv* env, + unsigned char* mem); + + /* 48 : Get Class Signature */ + jvmtiError (JNICALL *GetClassSignature) (jvmtiEnv* env, + jclass klass, + char** signature_ptr, + char** generic_ptr); + + /* 49 : Get Class Status */ + jvmtiError (JNICALL *GetClassStatus) (jvmtiEnv* env, + jclass klass, + jint* status_ptr); + + /* 50 : Get Source File Name */ + jvmtiError (JNICALL *GetSourceFileName) (jvmtiEnv* env, + jclass klass, + char** source_name_ptr); + + /* 51 : Get Class Modifiers */ + jvmtiError (JNICALL *GetClassModifiers) (jvmtiEnv* env, + jclass klass, + jint* modifiers_ptr); + + /* 52 : Get Class Methods */ + jvmtiError (JNICALL *GetClassMethods) (jvmtiEnv* env, + jclass klass, + jint* method_count_ptr, + jmethodID** methods_ptr); + + /* 53 : Get Class Fields */ + jvmtiError (JNICALL *GetClassFields) (jvmtiEnv* env, + jclass klass, + jint* field_count_ptr, + jfieldID** fields_ptr); + + /* 54 : Get Implemented Interfaces */ + jvmtiError (JNICALL *GetImplementedInterfaces) (jvmtiEnv* env, + jclass klass, + jint* interface_count_ptr, + jclass** interfaces_ptr); + + /* 55 : Is Interface */ + jvmtiError (JNICALL *IsInterface) (jvmtiEnv* env, + jclass klass, + jboolean* is_interface_ptr); + + /* 56 : Is Array Class */ + jvmtiError (JNICALL *IsArrayClass) (jvmtiEnv* env, + jclass klass, + jboolean* is_array_class_ptr); + + /* 57 : Get Class Loader */ + jvmtiError (JNICALL *GetClassLoader) (jvmtiEnv* env, + jclass klass, + jobject* classloader_ptr); + + /* 58 : Get Object Hash Code */ + jvmtiError (JNICALL *GetObjectHashCode) (jvmtiEnv* env, + jobject object, + jint* hash_code_ptr); + + /* 59 : Get Object Monitor Usage */ + jvmtiError (JNICALL *GetObjectMonitorUsage) (jvmtiEnv* env, + jobject object, + jvmtiMonitorUsage* info_ptr); + + /* 60 : Get Field Name (and Signature) */ + jvmtiError (JNICALL *GetFieldName) (jvmtiEnv* env, + jclass klass, + jfieldID field, + char** name_ptr, + char** signature_ptr, + char** generic_ptr); + + /* 61 : Get Field Declaring Class */ + jvmtiError (JNICALL *GetFieldDeclaringClass) (jvmtiEnv* env, + jclass klass, + jfieldID field, + jclass* declaring_class_ptr); + + /* 62 : Get Field Modifiers */ + jvmtiError (JNICALL *GetFieldModifiers) (jvmtiEnv* env, + jclass klass, + jfieldID field, + jint* modifiers_ptr); + + /* 63 : Is Field Synthetic */ + jvmtiError (JNICALL *IsFieldSynthetic) (jvmtiEnv* env, + jclass klass, + jfieldID field, + jboolean* is_synthetic_ptr); + + /* 64 : Get Method Name (and Signature) */ + jvmtiError (JNICALL *GetMethodName) (jvmtiEnv* env, + jmethodID method, + char** name_ptr, + char** signature_ptr, + char** generic_ptr); + + /* 65 : Get Method Declaring Class */ + jvmtiError (JNICALL *GetMethodDeclaringClass) (jvmtiEnv* env, + jmethodID method, + jclass* declaring_class_ptr); + + /* 66 : Get Method Modifiers */ + jvmtiError (JNICALL *GetMethodModifiers) (jvmtiEnv* env, + jmethodID method, + jint* modifiers_ptr); + + /* 67 : RESERVED */ + void *reserved67; + + /* 68 : Get Max Locals */ + jvmtiError (JNICALL *GetMaxLocals) (jvmtiEnv* env, + jmethodID method, + jint* max_ptr); + + /* 69 : Get Arguments Size */ + jvmtiError (JNICALL *GetArgumentsSize) (jvmtiEnv* env, + jmethodID method, + jint* size_ptr); + + /* 70 : Get Line Number Table */ + jvmtiError (JNICALL *GetLineNumberTable) (jvmtiEnv* env, + jmethodID method, + jint* entry_count_ptr, + jvmtiLineNumberEntry** table_ptr); + + /* 71 : Get Method Location */ + jvmtiError (JNICALL *GetMethodLocation) (jvmtiEnv* env, + jmethodID method, + jlocation* start_location_ptr, + jlocation* end_location_ptr); + + /* 72 : Get Local Variable Table */ + jvmtiError (JNICALL *GetLocalVariableTable) (jvmtiEnv* env, + jmethodID method, + jint* entry_count_ptr, + jvmtiLocalVariableEntry** table_ptr); + + /* 73 : Set Native Method Prefix */ + jvmtiError (JNICALL *SetNativeMethodPrefix) (jvmtiEnv* env, + const char* prefix); + + /* 74 : Set Native Method Prefixes */ + jvmtiError (JNICALL *SetNativeMethodPrefixes) (jvmtiEnv* env, + jint prefix_count, + char** prefixes); + + /* 75 : Get Bytecodes */ + jvmtiError (JNICALL *GetBytecodes) (jvmtiEnv* env, + jmethodID method, + jint* bytecode_count_ptr, + unsigned char** bytecodes_ptr); + + /* 76 : Is Method Native */ + jvmtiError (JNICALL *IsMethodNative) (jvmtiEnv* env, + jmethodID method, + jboolean* is_native_ptr); + + /* 77 : Is Method Synthetic */ + jvmtiError (JNICALL *IsMethodSynthetic) (jvmtiEnv* env, + jmethodID method, + jboolean* is_synthetic_ptr); + + /* 78 : Get Loaded Classes */ + jvmtiError (JNICALL *GetLoadedClasses) (jvmtiEnv* env, + jint* class_count_ptr, + jclass** classes_ptr); + + /* 79 : Get Classloader Classes */ + jvmtiError (JNICALL *GetClassLoaderClasses) (jvmtiEnv* env, + jobject initiating_loader, + jint* class_count_ptr, + jclass** classes_ptr); + + /* 80 : Pop Frame */ + jvmtiError (JNICALL *PopFrame) (jvmtiEnv* env, + jthread thread); + + /* 81 : Force Early Return - Object */ + jvmtiError (JNICALL *ForceEarlyReturnObject) (jvmtiEnv* env, + jthread thread, + jobject value); + + /* 82 : Force Early Return - Int */ + jvmtiError (JNICALL *ForceEarlyReturnInt) (jvmtiEnv* env, + jthread thread, + jint value); + + /* 83 : Force Early Return - Long */ + jvmtiError (JNICALL *ForceEarlyReturnLong) (jvmtiEnv* env, + jthread thread, + jlong value); + + /* 84 : Force Early Return - Float */ + jvmtiError (JNICALL *ForceEarlyReturnFloat) (jvmtiEnv* env, + jthread thread, + jfloat value); + + /* 85 : Force Early Return - Double */ + jvmtiError (JNICALL *ForceEarlyReturnDouble) (jvmtiEnv* env, + jthread thread, + jdouble value); + + /* 86 : Force Early Return - Void */ + jvmtiError (JNICALL *ForceEarlyReturnVoid) (jvmtiEnv* env, + jthread thread); + + /* 87 : Redefine Classes */ + jvmtiError (JNICALL *RedefineClasses) (jvmtiEnv* env, + jint class_count, + const jvmtiClassDefinition* class_definitions); + + /* 88 : Get Version Number */ + jvmtiError (JNICALL *GetVersionNumber) (jvmtiEnv* env, + jint* version_ptr); + + /* 89 : Get Capabilities */ + jvmtiError (JNICALL *GetCapabilities) (jvmtiEnv* env, + jvmtiCapabilities* capabilities_ptr); + + /* 90 : Get Source Debug Extension */ + jvmtiError (JNICALL *GetSourceDebugExtension) (jvmtiEnv* env, + jclass klass, + char** source_debug_extension_ptr); + + /* 91 : Is Method Obsolete */ + jvmtiError (JNICALL *IsMethodObsolete) (jvmtiEnv* env, + jmethodID method, + jboolean* is_obsolete_ptr); + + /* 92 : Suspend Thread List */ + jvmtiError (JNICALL *SuspendThreadList) (jvmtiEnv* env, + jint request_count, + const jthread* request_list, + jvmtiError* results); + + /* 93 : Resume Thread List */ + jvmtiError (JNICALL *ResumeThreadList) (jvmtiEnv* env, + jint request_count, + const jthread* request_list, + jvmtiError* results); + + /* 94 : RESERVED */ + void *reserved94; + + /* 95 : RESERVED */ + void *reserved95; + + /* 96 : RESERVED */ + void *reserved96; + + /* 97 : RESERVED */ + void *reserved97; + + /* 98 : RESERVED */ + void *reserved98; + + /* 99 : RESERVED */ + void *reserved99; + + /* 100 : Get All Stack Traces */ + jvmtiError (JNICALL *GetAllStackTraces) (jvmtiEnv* env, + jint max_frame_count, + jvmtiStackInfo** stack_info_ptr, + jint* thread_count_ptr); + + /* 101 : Get Thread List Stack Traces */ + jvmtiError (JNICALL *GetThreadListStackTraces) (jvmtiEnv* env, + jint thread_count, + const jthread* thread_list, + jint max_frame_count, + jvmtiStackInfo** stack_info_ptr); + + /* 102 : Get Thread Local Storage */ + jvmtiError (JNICALL *GetThreadLocalStorage) (jvmtiEnv* env, + jthread thread, + void** data_ptr); + + /* 103 : Set Thread Local Storage */ + jvmtiError (JNICALL *SetThreadLocalStorage) (jvmtiEnv* env, + jthread thread, + const void* data); + + /* 104 : Get Stack Trace */ + jvmtiError (JNICALL *GetStackTrace) (jvmtiEnv* env, + jthread thread, + jint start_depth, + jint max_frame_count, + jvmtiFrameInfo* frame_buffer, + jint* count_ptr); + + /* 105 : RESERVED */ + void *reserved105; + + /* 106 : Get Tag */ + jvmtiError (JNICALL *GetTag) (jvmtiEnv* env, + jobject object, + jlong* tag_ptr); + + /* 107 : Set Tag */ + jvmtiError (JNICALL *SetTag) (jvmtiEnv* env, + jobject object, + jlong tag); + + /* 108 : Force Garbage Collection */ + jvmtiError (JNICALL *ForceGarbageCollection) (jvmtiEnv* env); + + /* 109 : Iterate Over Objects Reachable From Object */ + jvmtiError (JNICALL *IterateOverObjectsReachableFromObject) (jvmtiEnv* env, + jobject object, + jvmtiObjectReferenceCallback object_reference_callback, + const void* user_data); + + /* 110 : Iterate Over Reachable Objects */ + jvmtiError (JNICALL *IterateOverReachableObjects) (jvmtiEnv* env, + jvmtiHeapRootCallback heap_root_callback, + jvmtiStackReferenceCallback stack_ref_callback, + jvmtiObjectReferenceCallback object_ref_callback, + const void* user_data); + + /* 111 : Iterate Over Heap */ + jvmtiError (JNICALL *IterateOverHeap) (jvmtiEnv* env, + jvmtiHeapObjectFilter object_filter, + jvmtiHeapObjectCallback heap_object_callback, + const void* user_data); + + /* 112 : Iterate Over Instances Of Class */ + jvmtiError (JNICALL *IterateOverInstancesOfClass) (jvmtiEnv* env, + jclass klass, + jvmtiHeapObjectFilter object_filter, + jvmtiHeapObjectCallback heap_object_callback, + const void* user_data); + + /* 113 : RESERVED */ + void *reserved113; + + /* 114 : Get Objects With Tags */ + jvmtiError (JNICALL *GetObjectsWithTags) (jvmtiEnv* env, + jint tag_count, + const jlong* tags, + jint* count_ptr, + jobject** object_result_ptr, + jlong** tag_result_ptr); + + /* 115 : Follow References */ + jvmtiError (JNICALL *FollowReferences) (jvmtiEnv* env, + jint heap_filter, + jclass klass, + jobject initial_object, + const jvmtiHeapCallbacks* callbacks, + const void* user_data); + + /* 116 : Iterate Through Heap */ + jvmtiError (JNICALL *IterateThroughHeap) (jvmtiEnv* env, + jint heap_filter, + jclass klass, + const jvmtiHeapCallbacks* callbacks, + const void* user_data); + + /* 117 : RESERVED */ + void *reserved117; + + /* 118 : RESERVED */ + void *reserved118; + + /* 119 : RESERVED */ + void *reserved119; + + /* 120 : Set JNI Function Table */ + jvmtiError (JNICALL *SetJNIFunctionTable) (jvmtiEnv* env, + const jniNativeInterface* function_table); + + /* 121 : Get JNI Function Table */ + jvmtiError (JNICALL *GetJNIFunctionTable) (jvmtiEnv* env, + jniNativeInterface** function_table); + + /* 122 : Set Event Callbacks */ + jvmtiError (JNICALL *SetEventCallbacks) (jvmtiEnv* env, + const jvmtiEventCallbacks* callbacks, + jint size_of_callbacks); + + /* 123 : Generate Events */ + jvmtiError (JNICALL *GenerateEvents) (jvmtiEnv* env, + jvmtiEvent event_type); + + /* 124 : Get Extension Functions */ + jvmtiError (JNICALL *GetExtensionFunctions) (jvmtiEnv* env, + jint* extension_count_ptr, + jvmtiExtensionFunctionInfo** extensions); + + /* 125 : Get Extension Events */ + jvmtiError (JNICALL *GetExtensionEvents) (jvmtiEnv* env, + jint* extension_count_ptr, + jvmtiExtensionEventInfo** extensions); + + /* 126 : Set Extension Event Callback */ + jvmtiError (JNICALL *SetExtensionEventCallback) (jvmtiEnv* env, + jint extension_event_index, + jvmtiExtensionEvent callback); + + /* 127 : Dispose Environment */ + jvmtiError (JNICALL *DisposeEnvironment) (jvmtiEnv* env); + + /* 128 : Get Error Name */ + jvmtiError (JNICALL *GetErrorName) (jvmtiEnv* env, + jvmtiError error, + char** name_ptr); + + /* 129 : Get JLocation Format */ + jvmtiError (JNICALL *GetJLocationFormat) (jvmtiEnv* env, + jvmtiJlocationFormat* format_ptr); + + /* 130 : Get System Properties */ + jvmtiError (JNICALL *GetSystemProperties) (jvmtiEnv* env, + jint* count_ptr, + char*** property_ptr); + + /* 131 : Get System Property */ + jvmtiError (JNICALL *GetSystemProperty) (jvmtiEnv* env, + const char* property, + char** value_ptr); + + /* 132 : Set System Property */ + jvmtiError (JNICALL *SetSystemProperty) (jvmtiEnv* env, + const char* property, + const char* value); + + /* 133 : Get Phase */ + jvmtiError (JNICALL *GetPhase) (jvmtiEnv* env, + jvmtiPhase* phase_ptr); + + /* 134 : Get Current Thread CPU Timer Information */ + jvmtiError (JNICALL *GetCurrentThreadCpuTimerInfo) (jvmtiEnv* env, + jvmtiTimerInfo* info_ptr); + + /* 135 : Get Current Thread CPU Time */ + jvmtiError (JNICALL *GetCurrentThreadCpuTime) (jvmtiEnv* env, + jlong* nanos_ptr); + + /* 136 : Get Thread CPU Timer Information */ + jvmtiError (JNICALL *GetThreadCpuTimerInfo) (jvmtiEnv* env, + jvmtiTimerInfo* info_ptr); + + /* 137 : Get Thread CPU Time */ + jvmtiError (JNICALL *GetThreadCpuTime) (jvmtiEnv* env, + jthread thread, + jlong* nanos_ptr); + + /* 138 : Get Timer Information */ + jvmtiError (JNICALL *GetTimerInfo) (jvmtiEnv* env, + jvmtiTimerInfo* info_ptr); + + /* 139 : Get Time */ + jvmtiError (JNICALL *GetTime) (jvmtiEnv* env, + jlong* nanos_ptr); + + /* 140 : Get Potential Capabilities */ + jvmtiError (JNICALL *GetPotentialCapabilities) (jvmtiEnv* env, + jvmtiCapabilities* capabilities_ptr); + + /* 141 : RESERVED */ + void *reserved141; + + /* 142 : Add Capabilities */ + jvmtiError (JNICALL *AddCapabilities) (jvmtiEnv* env, + const jvmtiCapabilities* capabilities_ptr); + + /* 143 : Relinquish Capabilities */ + jvmtiError (JNICALL *RelinquishCapabilities) (jvmtiEnv* env, + const jvmtiCapabilities* capabilities_ptr); + + /* 144 : Get Available Processors */ + jvmtiError (JNICALL *GetAvailableProcessors) (jvmtiEnv* env, + jint* processor_count_ptr); + + /* 145 : Get Class Version Numbers */ + jvmtiError (JNICALL *GetClassVersionNumbers) (jvmtiEnv* env, + jclass klass, + jint* minor_version_ptr, + jint* major_version_ptr); + + /* 146 : Get Constant Pool */ + jvmtiError (JNICALL *GetConstantPool) (jvmtiEnv* env, + jclass klass, + jint* constant_pool_count_ptr, + jint* constant_pool_byte_count_ptr, + unsigned char** constant_pool_bytes_ptr); + + /* 147 : Get Environment Local Storage */ + jvmtiError (JNICALL *GetEnvironmentLocalStorage) (jvmtiEnv* env, + void** data_ptr); + + /* 148 : Set Environment Local Storage */ + jvmtiError (JNICALL *SetEnvironmentLocalStorage) (jvmtiEnv* env, + const void* data); + + /* 149 : Add To Bootstrap Class Loader Search */ + jvmtiError (JNICALL *AddToBootstrapClassLoaderSearch) (jvmtiEnv* env, + const char* segment); + + /* 150 : Set Verbose Flag */ + jvmtiError (JNICALL *SetVerboseFlag) (jvmtiEnv* env, + jvmtiVerboseFlag flag, + jboolean value); + + /* 151 : Add To System Class Loader Search */ + jvmtiError (JNICALL *AddToSystemClassLoaderSearch) (jvmtiEnv* env, + const char* segment); + + /* 152 : Retransform Classes */ + jvmtiError (JNICALL *RetransformClasses) (jvmtiEnv* env, + jint class_count, + const jclass* classes); + + /* 153 : Get Owned Monitor Stack Depth Info */ + jvmtiError (JNICALL *GetOwnedMonitorStackDepthInfo) (jvmtiEnv* env, + jthread thread, + jint* monitor_info_count_ptr, + jvmtiMonitorStackDepthInfo** monitor_info_ptr); + + /* 154 : Get Object Size */ + jvmtiError (JNICALL *GetObjectSize) (jvmtiEnv* env, + jobject object, + jlong* size_ptr); + + /* 155 : Get Local Instance */ + jvmtiError (JNICALL *GetLocalInstance) (jvmtiEnv* env, + jthread thread, + jint depth, + jobject* value_ptr); + +} jvmtiInterface_1; + +struct _jvmtiEnv { + const struct jvmtiInterface_1_ *functions; +#ifdef __cplusplus + + + jvmtiError Allocate(jlong size, + unsigned char** mem_ptr) { + return functions->Allocate(this, size, mem_ptr); + } + + jvmtiError Deallocate(unsigned char* mem) { + return functions->Deallocate(this, mem); + } + + jvmtiError GetThreadState(jthread thread, + jint* thread_state_ptr) { + return functions->GetThreadState(this, thread, thread_state_ptr); + } + + jvmtiError GetCurrentThread(jthread* thread_ptr) { + return functions->GetCurrentThread(this, thread_ptr); + } + + jvmtiError GetAllThreads(jint* threads_count_ptr, + jthread** threads_ptr) { + return functions->GetAllThreads(this, threads_count_ptr, threads_ptr); + } + + jvmtiError SuspendThread(jthread thread) { + return functions->SuspendThread(this, thread); + } + + jvmtiError SuspendThreadList(jint request_count, + const jthread* request_list, + jvmtiError* results) { + return functions->SuspendThreadList(this, request_count, request_list, results); + } + + jvmtiError ResumeThread(jthread thread) { + return functions->ResumeThread(this, thread); + } + + jvmtiError ResumeThreadList(jint request_count, + const jthread* request_list, + jvmtiError* results) { + return functions->ResumeThreadList(this, request_count, request_list, results); + } + + jvmtiError StopThread(jthread thread, + jobject exception) { + return functions->StopThread(this, thread, exception); + } + + jvmtiError InterruptThread(jthread thread) { + return functions->InterruptThread(this, thread); + } + + jvmtiError GetThreadInfo(jthread thread, + jvmtiThreadInfo* info_ptr) { + return functions->GetThreadInfo(this, thread, info_ptr); + } + + jvmtiError GetOwnedMonitorInfo(jthread thread, + jint* owned_monitor_count_ptr, + jobject** owned_monitors_ptr) { + return functions->GetOwnedMonitorInfo(this, thread, owned_monitor_count_ptr, owned_monitors_ptr); + } + + jvmtiError GetOwnedMonitorStackDepthInfo(jthread thread, + jint* monitor_info_count_ptr, + jvmtiMonitorStackDepthInfo** monitor_info_ptr) { + return functions->GetOwnedMonitorStackDepthInfo(this, thread, monitor_info_count_ptr, monitor_info_ptr); + } + + jvmtiError GetCurrentContendedMonitor(jthread thread, + jobject* monitor_ptr) { + return functions->GetCurrentContendedMonitor(this, thread, monitor_ptr); + } + + jvmtiError RunAgentThread(jthread thread, + jvmtiStartFunction proc, + const void* arg, + jint priority) { + return functions->RunAgentThread(this, thread, proc, arg, priority); + } + + jvmtiError SetThreadLocalStorage(jthread thread, + const void* data) { + return functions->SetThreadLocalStorage(this, thread, data); + } + + jvmtiError GetThreadLocalStorage(jthread thread, + void** data_ptr) { + return functions->GetThreadLocalStorage(this, thread, data_ptr); + } + + jvmtiError GetTopThreadGroups(jint* group_count_ptr, + jthreadGroup** groups_ptr) { + return functions->GetTopThreadGroups(this, group_count_ptr, groups_ptr); + } + + jvmtiError GetThreadGroupInfo(jthreadGroup group, + jvmtiThreadGroupInfo* info_ptr) { + return functions->GetThreadGroupInfo(this, group, info_ptr); + } + + jvmtiError GetThreadGroupChildren(jthreadGroup group, + jint* thread_count_ptr, + jthread** threads_ptr, + jint* group_count_ptr, + jthreadGroup** groups_ptr) { + return functions->GetThreadGroupChildren(this, group, thread_count_ptr, threads_ptr, group_count_ptr, groups_ptr); + } + + jvmtiError GetStackTrace(jthread thread, + jint start_depth, + jint max_frame_count, + jvmtiFrameInfo* frame_buffer, + jint* count_ptr) { + return functions->GetStackTrace(this, thread, start_depth, max_frame_count, frame_buffer, count_ptr); + } + + jvmtiError GetAllStackTraces(jint max_frame_count, + jvmtiStackInfo** stack_info_ptr, + jint* thread_count_ptr) { + return functions->GetAllStackTraces(this, max_frame_count, stack_info_ptr, thread_count_ptr); + } + + jvmtiError GetThreadListStackTraces(jint thread_count, + const jthread* thread_list, + jint max_frame_count, + jvmtiStackInfo** stack_info_ptr) { + return functions->GetThreadListStackTraces(this, thread_count, thread_list, max_frame_count, stack_info_ptr); + } + + jvmtiError GetFrameCount(jthread thread, + jint* count_ptr) { + return functions->GetFrameCount(this, thread, count_ptr); + } + + jvmtiError PopFrame(jthread thread) { + return functions->PopFrame(this, thread); + } + + jvmtiError GetFrameLocation(jthread thread, + jint depth, + jmethodID* method_ptr, + jlocation* location_ptr) { + return functions->GetFrameLocation(this, thread, depth, method_ptr, location_ptr); + } + + jvmtiError NotifyFramePop(jthread thread, + jint depth) { + return functions->NotifyFramePop(this, thread, depth); + } + + jvmtiError ForceEarlyReturnObject(jthread thread, + jobject value) { + return functions->ForceEarlyReturnObject(this, thread, value); + } + + jvmtiError ForceEarlyReturnInt(jthread thread, + jint value) { + return functions->ForceEarlyReturnInt(this, thread, value); + } + + jvmtiError ForceEarlyReturnLong(jthread thread, + jlong value) { + return functions->ForceEarlyReturnLong(this, thread, value); + } + + jvmtiError ForceEarlyReturnFloat(jthread thread, + jfloat value) { + return functions->ForceEarlyReturnFloat(this, thread, value); + } + + jvmtiError ForceEarlyReturnDouble(jthread thread, + jdouble value) { + return functions->ForceEarlyReturnDouble(this, thread, value); + } + + jvmtiError ForceEarlyReturnVoid(jthread thread) { + return functions->ForceEarlyReturnVoid(this, thread); + } + + jvmtiError FollowReferences(jint heap_filter, + jclass klass, + jobject initial_object, + const jvmtiHeapCallbacks* callbacks, + const void* user_data) { + return functions->FollowReferences(this, heap_filter, klass, initial_object, callbacks, user_data); + } + + jvmtiError IterateThroughHeap(jint heap_filter, + jclass klass, + const jvmtiHeapCallbacks* callbacks, + const void* user_data) { + return functions->IterateThroughHeap(this, heap_filter, klass, callbacks, user_data); + } + + jvmtiError GetTag(jobject object, + jlong* tag_ptr) { + return functions->GetTag(this, object, tag_ptr); + } + + jvmtiError SetTag(jobject object, + jlong tag) { + return functions->SetTag(this, object, tag); + } + + jvmtiError GetObjectsWithTags(jint tag_count, + const jlong* tags, + jint* count_ptr, + jobject** object_result_ptr, + jlong** tag_result_ptr) { + return functions->GetObjectsWithTags(this, tag_count, tags, count_ptr, object_result_ptr, tag_result_ptr); + } + + jvmtiError ForceGarbageCollection() { + return functions->ForceGarbageCollection(this); + } + + jvmtiError IterateOverObjectsReachableFromObject(jobject object, + jvmtiObjectReferenceCallback object_reference_callback, + const void* user_data) { + return functions->IterateOverObjectsReachableFromObject(this, object, object_reference_callback, user_data); + } + + jvmtiError IterateOverReachableObjects(jvmtiHeapRootCallback heap_root_callback, + jvmtiStackReferenceCallback stack_ref_callback, + jvmtiObjectReferenceCallback object_ref_callback, + const void* user_data) { + return functions->IterateOverReachableObjects(this, heap_root_callback, stack_ref_callback, object_ref_callback, user_data); + } + + jvmtiError IterateOverHeap(jvmtiHeapObjectFilter object_filter, + jvmtiHeapObjectCallback heap_object_callback, + const void* user_data) { + return functions->IterateOverHeap(this, object_filter, heap_object_callback, user_data); + } + + jvmtiError IterateOverInstancesOfClass(jclass klass, + jvmtiHeapObjectFilter object_filter, + jvmtiHeapObjectCallback heap_object_callback, + const void* user_data) { + return functions->IterateOverInstancesOfClass(this, klass, object_filter, heap_object_callback, user_data); + } + + jvmtiError GetLocalObject(jthread thread, + jint depth, + jint slot, + jobject* value_ptr) { + return functions->GetLocalObject(this, thread, depth, slot, value_ptr); + } + + jvmtiError GetLocalInstance(jthread thread, + jint depth, + jobject* value_ptr) { + return functions->GetLocalInstance(this, thread, depth, value_ptr); + } + + jvmtiError GetLocalInt(jthread thread, + jint depth, + jint slot, + jint* value_ptr) { + return functions->GetLocalInt(this, thread, depth, slot, value_ptr); + } + + jvmtiError GetLocalLong(jthread thread, + jint depth, + jint slot, + jlong* value_ptr) { + return functions->GetLocalLong(this, thread, depth, slot, value_ptr); + } + + jvmtiError GetLocalFloat(jthread thread, + jint depth, + jint slot, + jfloat* value_ptr) { + return functions->GetLocalFloat(this, thread, depth, slot, value_ptr); + } + + jvmtiError GetLocalDouble(jthread thread, + jint depth, + jint slot, + jdouble* value_ptr) { + return functions->GetLocalDouble(this, thread, depth, slot, value_ptr); + } + + jvmtiError SetLocalObject(jthread thread, + jint depth, + jint slot, + jobject value) { + return functions->SetLocalObject(this, thread, depth, slot, value); + } + + jvmtiError SetLocalInt(jthread thread, + jint depth, + jint slot, + jint value) { + return functions->SetLocalInt(this, thread, depth, slot, value); + } + + jvmtiError SetLocalLong(jthread thread, + jint depth, + jint slot, + jlong value) { + return functions->SetLocalLong(this, thread, depth, slot, value); + } + + jvmtiError SetLocalFloat(jthread thread, + jint depth, + jint slot, + jfloat value) { + return functions->SetLocalFloat(this, thread, depth, slot, value); + } + + jvmtiError SetLocalDouble(jthread thread, + jint depth, + jint slot, + jdouble value) { + return functions->SetLocalDouble(this, thread, depth, slot, value); + } + + jvmtiError SetBreakpoint(jmethodID method, + jlocation location) { + return functions->SetBreakpoint(this, method, location); + } + + jvmtiError ClearBreakpoint(jmethodID method, + jlocation location) { + return functions->ClearBreakpoint(this, method, location); + } + + jvmtiError SetFieldAccessWatch(jclass klass, + jfieldID field) { + return functions->SetFieldAccessWatch(this, klass, field); + } + + jvmtiError ClearFieldAccessWatch(jclass klass, + jfieldID field) { + return functions->ClearFieldAccessWatch(this, klass, field); + } + + jvmtiError SetFieldModificationWatch(jclass klass, + jfieldID field) { + return functions->SetFieldModificationWatch(this, klass, field); + } + + jvmtiError ClearFieldModificationWatch(jclass klass, + jfieldID field) { + return functions->ClearFieldModificationWatch(this, klass, field); + } + + jvmtiError GetLoadedClasses(jint* class_count_ptr, + jclass** classes_ptr) { + return functions->GetLoadedClasses(this, class_count_ptr, classes_ptr); + } + + jvmtiError GetClassLoaderClasses(jobject initiating_loader, + jint* class_count_ptr, + jclass** classes_ptr) { + return functions->GetClassLoaderClasses(this, initiating_loader, class_count_ptr, classes_ptr); + } + + jvmtiError GetClassSignature(jclass klass, + char** signature_ptr, + char** generic_ptr) { + return functions->GetClassSignature(this, klass, signature_ptr, generic_ptr); + } + + jvmtiError GetClassStatus(jclass klass, + jint* status_ptr) { + return functions->GetClassStatus(this, klass, status_ptr); + } + + jvmtiError GetSourceFileName(jclass klass, + char** source_name_ptr) { + return functions->GetSourceFileName(this, klass, source_name_ptr); + } + + jvmtiError GetClassModifiers(jclass klass, + jint* modifiers_ptr) { + return functions->GetClassModifiers(this, klass, modifiers_ptr); + } + + jvmtiError GetClassMethods(jclass klass, + jint* method_count_ptr, + jmethodID** methods_ptr) { + return functions->GetClassMethods(this, klass, method_count_ptr, methods_ptr); + } + + jvmtiError GetClassFields(jclass klass, + jint* field_count_ptr, + jfieldID** fields_ptr) { + return functions->GetClassFields(this, klass, field_count_ptr, fields_ptr); + } + + jvmtiError GetImplementedInterfaces(jclass klass, + jint* interface_count_ptr, + jclass** interfaces_ptr) { + return functions->GetImplementedInterfaces(this, klass, interface_count_ptr, interfaces_ptr); + } + + jvmtiError GetClassVersionNumbers(jclass klass, + jint* minor_version_ptr, + jint* major_version_ptr) { + return functions->GetClassVersionNumbers(this, klass, minor_version_ptr, major_version_ptr); + } + + jvmtiError GetConstantPool(jclass klass, + jint* constant_pool_count_ptr, + jint* constant_pool_byte_count_ptr, + unsigned char** constant_pool_bytes_ptr) { + return functions->GetConstantPool(this, klass, constant_pool_count_ptr, constant_pool_byte_count_ptr, constant_pool_bytes_ptr); + } + + jvmtiError IsInterface(jclass klass, + jboolean* is_interface_ptr) { + return functions->IsInterface(this, klass, is_interface_ptr); + } + + jvmtiError IsArrayClass(jclass klass, + jboolean* is_array_class_ptr) { + return functions->IsArrayClass(this, klass, is_array_class_ptr); + } + + jvmtiError IsModifiableClass(jclass klass, + jboolean* is_modifiable_class_ptr) { + return functions->IsModifiableClass(this, klass, is_modifiable_class_ptr); + } + + jvmtiError GetClassLoader(jclass klass, + jobject* classloader_ptr) { + return functions->GetClassLoader(this, klass, classloader_ptr); + } + + jvmtiError GetSourceDebugExtension(jclass klass, + char** source_debug_extension_ptr) { + return functions->GetSourceDebugExtension(this, klass, source_debug_extension_ptr); + } + + jvmtiError RetransformClasses(jint class_count, + const jclass* classes) { + return functions->RetransformClasses(this, class_count, classes); + } + + jvmtiError RedefineClasses(jint class_count, + const jvmtiClassDefinition* class_definitions) { + return functions->RedefineClasses(this, class_count, class_definitions); + } + + jvmtiError GetObjectSize(jobject object, + jlong* size_ptr) { + return functions->GetObjectSize(this, object, size_ptr); + } + + jvmtiError GetObjectHashCode(jobject object, + jint* hash_code_ptr) { + return functions->GetObjectHashCode(this, object, hash_code_ptr); + } + + jvmtiError GetObjectMonitorUsage(jobject object, + jvmtiMonitorUsage* info_ptr) { + return functions->GetObjectMonitorUsage(this, object, info_ptr); + } + + jvmtiError GetFieldName(jclass klass, + jfieldID field, + char** name_ptr, + char** signature_ptr, + char** generic_ptr) { + return functions->GetFieldName(this, klass, field, name_ptr, signature_ptr, generic_ptr); + } + + jvmtiError GetFieldDeclaringClass(jclass klass, + jfieldID field, + jclass* declaring_class_ptr) { + return functions->GetFieldDeclaringClass(this, klass, field, declaring_class_ptr); + } + + jvmtiError GetFieldModifiers(jclass klass, + jfieldID field, + jint* modifiers_ptr) { + return functions->GetFieldModifiers(this, klass, field, modifiers_ptr); + } + + jvmtiError IsFieldSynthetic(jclass klass, + jfieldID field, + jboolean* is_synthetic_ptr) { + return functions->IsFieldSynthetic(this, klass, field, is_synthetic_ptr); + } + + jvmtiError GetMethodName(jmethodID method, + char** name_ptr, + char** signature_ptr, + char** generic_ptr) { + return functions->GetMethodName(this, method, name_ptr, signature_ptr, generic_ptr); + } + + jvmtiError GetMethodDeclaringClass(jmethodID method, + jclass* declaring_class_ptr) { + return functions->GetMethodDeclaringClass(this, method, declaring_class_ptr); + } + + jvmtiError GetMethodModifiers(jmethodID method, + jint* modifiers_ptr) { + return functions->GetMethodModifiers(this, method, modifiers_ptr); + } + + jvmtiError GetMaxLocals(jmethodID method, + jint* max_ptr) { + return functions->GetMaxLocals(this, method, max_ptr); + } + + jvmtiError GetArgumentsSize(jmethodID method, + jint* size_ptr) { + return functions->GetArgumentsSize(this, method, size_ptr); + } + + jvmtiError GetLineNumberTable(jmethodID method, + jint* entry_count_ptr, + jvmtiLineNumberEntry** table_ptr) { + return functions->GetLineNumberTable(this, method, entry_count_ptr, table_ptr); + } + + jvmtiError GetMethodLocation(jmethodID method, + jlocation* start_location_ptr, + jlocation* end_location_ptr) { + return functions->GetMethodLocation(this, method, start_location_ptr, end_location_ptr); + } + + jvmtiError GetLocalVariableTable(jmethodID method, + jint* entry_count_ptr, + jvmtiLocalVariableEntry** table_ptr) { + return functions->GetLocalVariableTable(this, method, entry_count_ptr, table_ptr); + } + + jvmtiError GetBytecodes(jmethodID method, + jint* bytecode_count_ptr, + unsigned char** bytecodes_ptr) { + return functions->GetBytecodes(this, method, bytecode_count_ptr, bytecodes_ptr); + } + + jvmtiError IsMethodNative(jmethodID method, + jboolean* is_native_ptr) { + return functions->IsMethodNative(this, method, is_native_ptr); + } + + jvmtiError IsMethodSynthetic(jmethodID method, + jboolean* is_synthetic_ptr) { + return functions->IsMethodSynthetic(this, method, is_synthetic_ptr); + } + + jvmtiError IsMethodObsolete(jmethodID method, + jboolean* is_obsolete_ptr) { + return functions->IsMethodObsolete(this, method, is_obsolete_ptr); + } + + jvmtiError SetNativeMethodPrefix(const char* prefix) { + return functions->SetNativeMethodPrefix(this, prefix); + } + + jvmtiError SetNativeMethodPrefixes(jint prefix_count, + char** prefixes) { + return functions->SetNativeMethodPrefixes(this, prefix_count, prefixes); + } + + jvmtiError CreateRawMonitor(const char* name, + jrawMonitorID* monitor_ptr) { + return functions->CreateRawMonitor(this, name, monitor_ptr); + } + + jvmtiError DestroyRawMonitor(jrawMonitorID monitor) { + return functions->DestroyRawMonitor(this, monitor); + } + + jvmtiError RawMonitorEnter(jrawMonitorID monitor) { + return functions->RawMonitorEnter(this, monitor); + } + + jvmtiError RawMonitorExit(jrawMonitorID monitor) { + return functions->RawMonitorExit(this, monitor); + } + + jvmtiError RawMonitorWait(jrawMonitorID monitor, + jlong millis) { + return functions->RawMonitorWait(this, monitor, millis); + } + + jvmtiError RawMonitorNotify(jrawMonitorID monitor) { + return functions->RawMonitorNotify(this, monitor); + } + + jvmtiError RawMonitorNotifyAll(jrawMonitorID monitor) { + return functions->RawMonitorNotifyAll(this, monitor); + } + + jvmtiError SetJNIFunctionTable(const jniNativeInterface* function_table) { + return functions->SetJNIFunctionTable(this, function_table); + } + + jvmtiError GetJNIFunctionTable(jniNativeInterface** function_table) { + return functions->GetJNIFunctionTable(this, function_table); + } + + jvmtiError SetEventCallbacks(const jvmtiEventCallbacks* callbacks, + jint size_of_callbacks) { + return functions->SetEventCallbacks(this, callbacks, size_of_callbacks); + } + + jvmtiError SetEventNotificationMode(jvmtiEventMode mode, + jvmtiEvent event_type, + jthread event_thread, + ...) { + return functions->SetEventNotificationMode(this, mode, event_type, event_thread); + } + + jvmtiError GenerateEvents(jvmtiEvent event_type) { + return functions->GenerateEvents(this, event_type); + } + + jvmtiError GetExtensionFunctions(jint* extension_count_ptr, + jvmtiExtensionFunctionInfo** extensions) { + return functions->GetExtensionFunctions(this, extension_count_ptr, extensions); + } + + jvmtiError GetExtensionEvents(jint* extension_count_ptr, + jvmtiExtensionEventInfo** extensions) { + return functions->GetExtensionEvents(this, extension_count_ptr, extensions); + } + + jvmtiError SetExtensionEventCallback(jint extension_event_index, + jvmtiExtensionEvent callback) { + return functions->SetExtensionEventCallback(this, extension_event_index, callback); + } + + jvmtiError GetPotentialCapabilities(jvmtiCapabilities* capabilities_ptr) { + return functions->GetPotentialCapabilities(this, capabilities_ptr); + } + + jvmtiError AddCapabilities(const jvmtiCapabilities* capabilities_ptr) { + return functions->AddCapabilities(this, capabilities_ptr); + } + + jvmtiError RelinquishCapabilities(const jvmtiCapabilities* capabilities_ptr) { + return functions->RelinquishCapabilities(this, capabilities_ptr); + } + + jvmtiError GetCapabilities(jvmtiCapabilities* capabilities_ptr) { + return functions->GetCapabilities(this, capabilities_ptr); + } + + jvmtiError GetCurrentThreadCpuTimerInfo(jvmtiTimerInfo* info_ptr) { + return functions->GetCurrentThreadCpuTimerInfo(this, info_ptr); + } + + jvmtiError GetCurrentThreadCpuTime(jlong* nanos_ptr) { + return functions->GetCurrentThreadCpuTime(this, nanos_ptr); + } + + jvmtiError GetThreadCpuTimerInfo(jvmtiTimerInfo* info_ptr) { + return functions->GetThreadCpuTimerInfo(this, info_ptr); + } + + jvmtiError GetThreadCpuTime(jthread thread, + jlong* nanos_ptr) { + return functions->GetThreadCpuTime(this, thread, nanos_ptr); + } + + jvmtiError GetTimerInfo(jvmtiTimerInfo* info_ptr) { + return functions->GetTimerInfo(this, info_ptr); + } + + jvmtiError GetTime(jlong* nanos_ptr) { + return functions->GetTime(this, nanos_ptr); + } + + jvmtiError GetAvailableProcessors(jint* processor_count_ptr) { + return functions->GetAvailableProcessors(this, processor_count_ptr); + } + + jvmtiError AddToBootstrapClassLoaderSearch(const char* segment) { + return functions->AddToBootstrapClassLoaderSearch(this, segment); + } + + jvmtiError AddToSystemClassLoaderSearch(const char* segment) { + return functions->AddToSystemClassLoaderSearch(this, segment); + } + + jvmtiError GetSystemProperties(jint* count_ptr, + char*** property_ptr) { + return functions->GetSystemProperties(this, count_ptr, property_ptr); + } + + jvmtiError GetSystemProperty(const char* property, + char** value_ptr) { + return functions->GetSystemProperty(this, property, value_ptr); + } + + jvmtiError SetSystemProperty(const char* property, + const char* value) { + return functions->SetSystemProperty(this, property, value); + } + + jvmtiError GetPhase(jvmtiPhase* phase_ptr) { + return functions->GetPhase(this, phase_ptr); + } + + jvmtiError DisposeEnvironment() { + return functions->DisposeEnvironment(this); + } + + jvmtiError SetEnvironmentLocalStorage(const void* data) { + return functions->SetEnvironmentLocalStorage(this, data); + } + + jvmtiError GetEnvironmentLocalStorage(void** data_ptr) { + return functions->GetEnvironmentLocalStorage(this, data_ptr); + } + + jvmtiError GetVersionNumber(jint* version_ptr) { + return functions->GetVersionNumber(this, version_ptr); + } + + jvmtiError GetErrorName(jvmtiError error, + char** name_ptr) { + return functions->GetErrorName(this, error, name_ptr); + } + + jvmtiError SetVerboseFlag(jvmtiVerboseFlag flag, + jboolean value) { + return functions->SetVerboseFlag(this, flag, value); + } + + jvmtiError GetJLocationFormat(jvmtiJlocationFormat* format_ptr) { + return functions->GetJLocationFormat(this, format_ptr); + } + +#endif /* __cplusplus */ +}; + + +#ifdef __cplusplus +} /* extern "C" */ +#endif /* __cplusplus */ + +#endif /* !_JAVA_JVMTI_H_ */ + diff --git a/runtime/ti/agent.cc b/runtime/ti/agent.cc index 41a21f70f3..7c0ea64228 100644 --- a/runtime/ti/agent.cc +++ b/runtime/ti/agent.cc @@ -38,6 +38,7 @@ Agent Agent::Create(std::string arg) { Agent::LoadError Agent::Load(/*out*/jint* call_res, /*out*/ std::string* error_msg) { DCHECK(call_res != nullptr); DCHECK(error_msg != nullptr); + if (IsStarted()) { *error_msg = StringPrintf("the agent at %s has already been started!", name_.c_str()); VLOG(agents) << "err: " << *error_msg; @@ -54,9 +55,12 @@ Agent::LoadError Agent::Load(/*out*/jint* call_res, /*out*/ std::string* error_m VLOG(agents) << "err: " << *error_msg; return kLoadingError; } + // Need to let the function fiddle with the array. + std::unique_ptr<char[]> copied_args(new char[args_.size() + 1]); + strcpy(copied_args.get(), args_.c_str()); // TODO Need to do some checks that we are at a good spot etc. *call_res = onload_(static_cast<JavaVM*>(Runtime::Current()->GetJavaVM()), - args_.c_str(), + copied_args.get(), nullptr); if (*call_res != 0) { *error_msg = StringPrintf("Initialization of %s returned non-zero value of %d", diff --git a/test/901-hello-ti-agent/basics.cc b/test/901-hello-ti-agent/basics.cc new file mode 100644 index 0000000000..81a1b66683 --- /dev/null +++ b/test/901-hello-ti-agent/basics.cc @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "901-hello-ti-agent/basics.h" + +#include <jni.h> +#include <stdio.h> +#include <string.h> +#include "base/macros.h" +#include "openjdkjvmti/jvmti.h" + +namespace art { +namespace Test901HelloTi { + +jint OnLoad(JavaVM* vm, + char* options ATTRIBUTE_UNUSED, + void* reserved ATTRIBUTE_UNUSED) { + printf("Loaded Agent for test 901-hello-ti-agent\n"); + fsync(1); + jvmtiEnv* env = nullptr; + jvmtiEnv* env2 = nullptr; + +#define CHECK_CALL_SUCCESS(c) \ + do { \ + if (c != JNI_OK) { \ + printf("call " #c " did not succeed\n"); \ + return -1; \ + } \ + } while (false) + + CHECK_CALL_SUCCESS(vm->GetEnv(reinterpret_cast<void**>(&env), JVMTI_VERSION_1_0)); + CHECK_CALL_SUCCESS(vm->GetEnv(reinterpret_cast<void**>(&env2), JVMTI_VERSION_1_0)); + if (env == env2) { + printf("GetEnv returned same environment twice!\n"); + return -1; + } + unsigned char* local_data = nullptr; + CHECK_CALL_SUCCESS(env->Allocate(8, &local_data)); + strcpy(reinterpret_cast<char*>(local_data), "hello!!"); + CHECK_CALL_SUCCESS(env->SetEnvironmentLocalStorage(local_data)); + unsigned char* get_data = nullptr; + CHECK_CALL_SUCCESS(env->GetEnvironmentLocalStorage(reinterpret_cast<void**>(&get_data))); + if (get_data != local_data) { + printf("Got different data from local storage then what was set!\n"); + return -1; + } + CHECK_CALL_SUCCESS(env2->GetEnvironmentLocalStorage(reinterpret_cast<void**>(&get_data))); + if (get_data != nullptr) { + printf("env2 did not have nullptr local storage.\n"); + return -1; + } + CHECK_CALL_SUCCESS(env->Deallocate(local_data)); + jint version = 0; + CHECK_CALL_SUCCESS(env->GetVersionNumber(&version)); + if ((version & JVMTI_VERSION_1) != JVMTI_VERSION_1) { + printf("Unexpected version number!\n"); + return -1; + } + CHECK_CALL_SUCCESS(env->DisposeEnvironment()); + CHECK_CALL_SUCCESS(env2->DisposeEnvironment()); +#undef CHECK_CALL_SUCCESS + return JNI_OK; +} + + +} // namespace Test901HelloTi +} // namespace art diff --git a/test/901-hello-ti-agent/basics.h b/test/901-hello-ti-agent/basics.h new file mode 100644 index 0000000000..f482950aa9 --- /dev/null +++ b/test/901-hello-ti-agent/basics.h @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ART_TEST_901_HELLO_TI_AGENT_BASICS_H_ +#define ART_TEST_901_HELLO_TI_AGENT_BASICS_H_ + +#include <jni.h> + +namespace art { +namespace Test901HelloTi { + +jint OnLoad(JavaVM* vm, char* options, void* reserved); + +} // namespace Test901HelloTi +} // namespace art + +#endif // ART_TEST_901_HELLO_TI_AGENT_BASICS_H_ diff --git a/test/901-hello-ti-agent/build b/test/901-hello-ti-agent/build new file mode 100755 index 0000000000..898e2e54a2 --- /dev/null +++ b/test/901-hello-ti-agent/build @@ -0,0 +1,17 @@ +#!/bin/bash +# +# Copyright 2016 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +./default-build "$@" --experimental agents diff --git a/test/901-hello-ti-agent/expected.txt b/test/901-hello-ti-agent/expected.txt new file mode 100644 index 0000000000..414eb3b2ae --- /dev/null +++ b/test/901-hello-ti-agent/expected.txt @@ -0,0 +1,2 @@ +Loaded Agent for test 901-hello-ti-agent +Hello, world! diff --git a/test/901-hello-ti-agent/info.txt b/test/901-hello-ti-agent/info.txt new file mode 100644 index 0000000000..875a5f6ec1 --- /dev/null +++ b/test/901-hello-ti-agent/info.txt @@ -0,0 +1 @@ +Tests basic functions in the jvmti plugin. diff --git a/test/901-hello-ti-agent/run b/test/901-hello-ti-agent/run new file mode 100755 index 0000000000..8079a8c457 --- /dev/null +++ b/test/901-hello-ti-agent/run @@ -0,0 +1,27 @@ +#!/bin/bash +# +# Copyright 2016 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +plugin=libopenjdkjvmtid.so +agent=libtiagentd.so +if [[ "$@" == *"-O"* ]]; then + agent=libtiagent.so + plugin=libopenjdkjvmti.so +fi + +./default-run "$@" --experimental agents \ + --experimental runtime-plugins \ + --runtime-option -agentpath:${agent}=901-hello-ti-agent \ + --android-runtime-option -Xplugin:${plugin} diff --git a/test/901-hello-ti-agent/src/Main.java b/test/901-hello-ti-agent/src/Main.java new file mode 100644 index 0000000000..1ef6289559 --- /dev/null +++ b/test/901-hello-ti-agent/src/Main.java @@ -0,0 +1,21 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +public class Main { + public static void main(String[] args) { + System.out.println("Hello, world!"); + } +} diff --git a/test/Android.libtiagent.mk b/test/Android.libtiagent.mk new file mode 100644 index 0000000000..626dc3b8b3 --- /dev/null +++ b/test/Android.libtiagent.mk @@ -0,0 +1,102 @@ +# +# Copyright (C) 2016 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + + +LOCAL_PATH := $(call my-dir) + +include art/build/Android.common_build.mk + +LIBARTAGENT_COMMON_SRC_FILES := \ + ti-agent/common_load.cc \ + 901-hello-ti-agent/basics.cc + +# $(1): target or host +# $(2): debug or <empty> +define build-libtiagent + ifneq ($(1),target) + ifneq ($(1),host) + $$(error expected target or host for argument 1, received $(1)) + endif + endif + ifneq ($(2),debug) + ifneq ($(2),) + $$(error d or empty for argument 2, received $(2)) + endif + suffix := d + else + suffix := + endif + + art_target_or_host := $(1) + + include $(CLEAR_VARS) + LOCAL_CPP_EXTENSION := $(ART_CPP_EXTENSION) + LOCAL_MODULE := libtiagent$$(suffix) + ifeq ($$(art_target_or_host),target) + LOCAL_MODULE_TAGS := tests + endif + LOCAL_SRC_FILES := $(LIBARTAGENT_COMMON_SRC_FILES) + LOCAL_SHARED_LIBRARIES += libart$$(suffix) libbacktrace libnativehelper libopenjdkjvmti$$(suffix) + LOCAL_C_INCLUDES += $(ART_C_INCLUDES) art/runtime art/test + LOCAL_ADDITIONAL_DEPENDENCIES := art/build/Android.common_build.mk + LOCAL_ADDITIONAL_DEPENDENCIES += $(LOCAL_PATH)/Android.libtiagent.mk + ifeq ($$(art_target_or_host),target) + $(call set-target-local-clang-vars) + ifeq ($$(suffix),d) + $(call set-target-local-cflags-vars,debug) + else + $(call set-target-local-cflags-vars,ndebug) + endif + LOCAL_SHARED_LIBRARIES += libdl + LOCAL_MULTILIB := both + LOCAL_MODULE_PATH_32 := $(ART_TARGET_TEST_OUT)/$(ART_TARGET_ARCH_32) + LOCAL_MODULE_PATH_64 := $(ART_TARGET_TEST_OUT)/$(ART_TARGET_ARCH_64) + LOCAL_MODULE_TARGET_ARCH := $(ART_SUPPORTED_ARCH) + include $(BUILD_SHARED_LIBRARY) + else # host + LOCAL_CLANG := $(ART_HOST_CLANG) + LOCAL_CFLAGS := $(ART_HOST_CFLAGS) + LOCAL_ASFLAGS := $(ART_HOST_ASFLAGS) + ifeq ($$(suffix),d) + LOCAL_CFLAGS += $(ART_HOST_DEBUG_CFLAGS) + LOCAL_ASFLAGS += $(ART_HOST_DEBUG_ASFLAGS) + else + LOCAL_CFLAGS += $(ART_HOST_NON_DEBUG_CFLAGS) + LOCAL_ASFLAGS += $(ART_HOST_NON_DEBUG_ASFLAGS) + endif + LOCAL_LDLIBS := $(ART_HOST_LDLIBS) -ldl -lpthread + LOCAL_IS_HOST_MODULE := true + LOCAL_MULTILIB := both + include $(BUILD_HOST_SHARED_LIBRARY) + endif + + # Clear locally used variables. + art_target_or_host := + suffix := +endef + +ifeq ($(ART_BUILD_TARGET),true) + $(eval $(call build-libtiagent,target,)) + $(eval $(call build-libtiagent,target,debug)) +endif +ifeq ($(ART_BUILD_HOST),true) + $(eval $(call build-libtiagent,host,)) + $(eval $(call build-libtiagent,host,debug)) +endif + +# Clear locally used variables. +LOCAL_PATH := +LIBARTAGENT_COMMON_SRC_FILES := diff --git a/test/Android.run-test.mk b/test/Android.run-test.mk index b87e142811..65debc9a53 100644 --- a/test/Android.run-test.mk +++ b/test/Android.run-test.mk @@ -664,6 +664,14 @@ TEST_ART_TARGET_SYNC_DEPS += $(ART_TARGET_TEST_OUT)/$(TARGET_2ND_ARCH)/libartage TEST_ART_TARGET_SYNC_DEPS += $(ART_TARGET_TEST_OUT)/$(TARGET_2ND_ARCH)/libartagentd.so endif +# Also need libtiagent. +TEST_ART_TARGET_SYNC_DEPS += $(ART_TARGET_TEST_OUT)/$(TARGET_ARCH)/libtiagent.so +TEST_ART_TARGET_SYNC_DEPS += $(ART_TARGET_TEST_OUT)/$(TARGET_ARCH)/libtiagentd.so +ifdef TARGET_2ND_ARCH +TEST_ART_TARGET_SYNC_DEPS += $(ART_TARGET_TEST_OUT)/$(TARGET_2ND_ARCH)/libtiagent.so +TEST_ART_TARGET_SYNC_DEPS += $(ART_TARGET_TEST_OUT)/$(TARGET_2ND_ARCH)/libtiagentd.so +endif + # Also need libarttest. TEST_ART_TARGET_SYNC_DEPS += $(ART_TARGET_TEST_OUT)/$(TARGET_ARCH)/libarttest.so TEST_ART_TARGET_SYNC_DEPS += $(ART_TARGET_TEST_OUT)/$(TARGET_ARCH)/libarttestd.so @@ -682,6 +690,8 @@ endif # specific version depending on the compiler. ART_TEST_HOST_RUN_TEST_DEPENDENCIES := \ $(ART_HOST_EXECUTABLES) \ + $(ART_HOST_OUT_SHARED_LIBRARIES)/libtiagent$(ART_HOST_SHLIB_EXTENSION) \ + $(ART_HOST_OUT_SHARED_LIBRARIES)/libtiagentd$(ART_HOST_SHLIB_EXTENSION) \ $(ART_HOST_OUT_SHARED_LIBRARIES)/libartagent$(ART_HOST_SHLIB_EXTENSION) \ $(ART_HOST_OUT_SHARED_LIBRARIES)/libartagentd$(ART_HOST_SHLIB_EXTENSION) \ $(ART_HOST_OUT_SHARED_LIBRARIES)/libarttest$(ART_HOST_SHLIB_EXTENSION) \ @@ -693,6 +703,8 @@ ART_TEST_HOST_RUN_TEST_DEPENDENCIES := \ ifneq ($(HOST_PREFER_32_BIT),true) ART_TEST_HOST_RUN_TEST_DEPENDENCIES += \ + $(2ND_ART_HOST_OUT_SHARED_LIBRARIES)/libtiagent$(ART_HOST_SHLIB_EXTENSION) \ + $(2ND_ART_HOST_OUT_SHARED_LIBRARIES)/libtiagentd$(ART_HOST_SHLIB_EXTENSION) \ $(2ND_ART_HOST_OUT_SHARED_LIBRARIES)/libartagent$(ART_HOST_SHLIB_EXTENSION) \ $(2ND_ART_HOST_OUT_SHARED_LIBRARIES)/libartagentd$(ART_HOST_SHLIB_EXTENSION) \ $(2ND_ART_HOST_OUT_SHARED_LIBRARIES)/libarttest$(ART_HOST_SHLIB_EXTENSION) \ @@ -1109,6 +1121,7 @@ DEBUGGABLE_TYPES := MY_LOCAL_PATH := $(LOCAL_PATH) include $(MY_LOCAL_PATH)/Android.libartagent.mk +include $(MY_LOCAL_PATH)/Android.libtiagent.mk include $(MY_LOCAL_PATH)/Android.libarttest.mk include $(MY_LOCAL_PATH)/Android.libnativebridgetest.mk MY_LOCAL_PATH := diff --git a/test/ti-agent/common_load.cc b/test/ti-agent/common_load.cc new file mode 100644 index 0000000000..ed280e4fdc --- /dev/null +++ b/test/ti-agent/common_load.cc @@ -0,0 +1,112 @@ +/* + * Copyright 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <jni.h> +#include <stdio.h> +// TODO I don't know? +#include "openjdkjvmti/jvmti.h" + +#include "art_method-inl.h" +#include "base/logging.h" +#include "base/macros.h" + +#include "901-hello-ti-agent/basics.h" + +namespace art { + +using OnLoad = jint (*)(JavaVM* vm, char* options, void* reserved); +using OnAttach = jint (*)(JavaVM* vm, char* options, void* reserved); + +struct AgentLib { + const char* name; + OnLoad load; + OnAttach attach; +}; + +// A list of all the agents we have for testing. +AgentLib agents[] = { + { "901-hello-ti-agent", Test901HelloTi::OnLoad, nullptr }, +}; + +static AgentLib* FindAgent(char* name) { + for (AgentLib& l : agents) { + if (strncmp(l.name, name, strlen(l.name)) == 0) { + return &l; + } + } + return nullptr; +} + +static bool FindAgentNameAndOptions(char* options, + /*out*/char** name, + /*out*/char** other_options) { + // Name is the first element. + *name = options; + char* rest = options; + // name is the first thing in the options + while (*rest != '\0' && *rest != ',') { + rest++; + } + if (*rest == ',') { + *rest = '\0'; + rest++; + } + *other_options = rest; + return true; +} + +extern "C" JNIEXPORT jint JNICALL Agent_OnLoad(JavaVM* vm, char* options, void* reserved) { + char* remaining_options = nullptr; + char* name_option = nullptr; + if (!FindAgentNameAndOptions(options, &name_option, &remaining_options)) { + printf("Unable to find agent name in options: %s\n", options); + return -1; + } + AgentLib* lib = FindAgent(name_option); + if (lib == nullptr) { + printf("Unable to find agent named: %s, add it to the list in test/ti-agent/common_load.cc\n", + name_option); + return -2; + } + if (lib->load == nullptr) { + printf("agent: %s does not include an OnLoad method.\n", name_option); + return -3; + } + return lib->load(vm, remaining_options, reserved); +} + + +extern "C" JNIEXPORT jint JNICALL Agent_OnAttach(JavaVM* vm, char* options, void* reserved) { + char* remaining_options = nullptr; + char* name_option = nullptr; + if (!FindAgentNameAndOptions(options, &name_option, &remaining_options)) { + printf("Unable to find agent name in options: %s\n", options); + return -1; + } + AgentLib* lib = FindAgent(name_option); + if (lib == nullptr) { + printf("Unable to find agent named: %s, add it to the list in test/ti-agent/common_load.cc\n", + name_option); + return -2; + } + if (lib->attach == nullptr) { + printf("agent: %s does not include an OnAttach method.\n", name_option); + return -3; + } + return lib->attach(vm, remaining_options, reserved); +} + +} // namespace art |