diff options
author | 2016-08-11 15:35:28 -0700 | |
---|---|---|
committer | 2016-08-17 10:50:37 -0700 | |
commit | 49948e9d4e66e68ea077031f9aa80b6c332bd673 (patch) | |
tree | cc50d0259b02d3021241f74ed659f74f52771268 /runtime/openjdkjvmti/OpenjdkJvmTi.cc | |
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
Diffstat (limited to 'runtime/openjdkjvmti/OpenjdkJvmTi.cc')
-rw-r--r-- | runtime/openjdkjvmti/OpenjdkJvmTi.cc | 1120 |
1 files changed, 1120 insertions, 0 deletions
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 |