# JVMTM Tool Interface ### Version 1.1

- Introduction
  - What is the JVM Tool Interface?
  - Architecture
  - Writing Agents
  - Deploying Agents
  - Agent Command Line Options
  - Agent Start-Up
  - Agent Start-Up (OnLoad phase)
  - Agent Start-Up (Live phase)
  - Agent Shutdown
  - JAVA_TOOL_OPTIONS
  - Environments
  - Bytecode Instrumentation
  - Modified UTF-8 String Encoding
  - Specification Context
- Functions
  - Accessing Functions
  - Function Return Values
  - Managing JNI Object References
  - Prerequisite State for Calling Functions
  - Exceptions and Functions
  - Function Index
    - Memory Management
    - Thread
    - Thread Group
    - Stack Frame
    - Force Early Return
    - Heap
    - Heap (1.0)
    - Local Variable
    - Breakpoint
    - Watched Field
    - Class
    - Object
    - Field
    - Method
    - Raw Monitor
    - JNI Function Interception
    - Event Management
    - Extension Mechanism
    - Capability
    - Timers
    - Class Loader Search
    - System Properties
    - General
  - Error Codes
- Events
  - Event Index
- Data Types
  - JNI Types Used in the JVM Tool Interface
  - JVM Tool Interface Base Types
  - Structure Type Definitions
  - Function Type Definitions
  - Enumeration Definitions
  - Function Table
- Constant Index
- Change History

#### What is the JVM Tool Interface?

The JVMTM Tool Interface (JVM TI) is a programming interface used by development and monitoring tools. It provides both a way to inspect the state and to control the execution of applications running in the JavaTM virtual machine (VM).

JVM TI is intended to provide a VM interface for the full breadth of tools that need access to VM state, including but not limited to: profiling, debugging, monitoring, thread analysis, and coverage analysis tools.

JVM TI may not be available in all implementations of the JavaTM virtual machine.

JVM TI is a two-way interface. A client of JVM TI, hereafter called an agent, can be notified of interesting occurrences through events. JVM TI can query and control the application through many functions, either in response to events or independent of them.

Agents run in the same process with and communicate directly with the virtual machine executing the application being examined. This communication is through a native interface (JVM TI). The native in-process interface allows maximal control with minimal intrusion on the part of a tool. Typically, agents are relatively compact. They can be controlled by a separate process which implements the bulk of a tool's function without interfering with the target application's normal execution.

#### Architecture

Tools can be written directly to JVM TI or indirectly through higher level interfaces. The Java Platform Debugger Architecture includes JVM TI, but also contains higher-level, out-of-process debugger interfaces. The higher-level interfaces are more appropriate than JVM TI for many tools. For more information on the Java Platform Debugger Architecture, see the Java Platform Debugger Architecture website.

#### Writing Agents

Agents can be written in any native language that supports C language calling conventions and C or C++ definitions.

The function, event, data type, and constant definitions needed for using JVM TI are defined in the include file `jvmti.h`. To use these definitions add the J2SETM include directory to your include path and add

>     #include <jvmti.h>

to your source code.

#### Deploying Agents

An agent is deployed in a platform specific manner but is typically the platform equivalent of a dynamic library. On the WindowsTM operating system, for example, an agent library is a "Dynamic Linked Library" (DLL). On the SolarisTM Operating Environment, an agent library is a shared object (`.so` file).

An agent may be started at VM startup by specifying the agent library name using a command line option. Some implementations may support a mechanism to start agents in the live phase. The details of how this is initiated are implementation specific.

#### Agent Command Line Options

The term "command-line option" is used below to mean options supplied in the `JavaVMInitArgs` argument to the `JNI_CreateJavaVM` function of the JNI Invocation API.

One of the two following command-line options is used on VM startup to properly load and run agents. These arguments identify the library containing the agent as well as an options string to be passed in at startup.

`-agentlib:`<agent-lib-name>`=`<options>
  The name following `-agentlib:` is the name of the library to load. Lookup of the library, both its full name and location, proceeds in a platform-specific manner. Typically, the <agent-lib-name> is expanded to an operating system specific file name. The <options> will be passed to the agent on start-up. For example, if the option `-agentlib:foo=opt1,opt2` is specified, the VM will attempt to load the shared library `foo.dll` from the system `PATH` under WindowsTM or `libfoo.so` from the `LD_LIBRARY_PATH` under the SolarisTM operating environment.
`-agentpath:`<path-to-agent>`=`<options>
  The path following `-agentpath:` is the absolute path from which to load the library. No library name expansion will occur. The <options> will be passed to the agent on start-up. For example, if the option `-agentpath:c:\myLibs\foo.dll=opt1,opt2` is specified, the VM will attempt to load the shared library `c:\myLibs\foo.dll`.

The start-up routine `Agent_OnLoad` in the library will be invoked.

Libraries loaded with `-agentlib:` or `-agentpath:` will be searched for JNI native method implementations to facilitate the use of Java programming language code in tools, as is needed for bytecode instrumentation.

The agent libraries will be searched after all other libraries have been searched (agents wishing to override or intercept the native method implementations of non-agent methods can use the NativeMethodBind event).

These switches do the above and nothing more - they do not change the state of the VM or JVM TI. No command line options are needed to enable JVM TI or aspects of JVM TI, this is handled programmatically by the use of capabilities.

#### Agent Start-Up

The VM starts each agent by invoking a start-up function. If the agent is started in the `OnLoad` phase the function `Agent_OnLoad` will be invoked. If the agent is started in the live phase the function `Agent_OnAttach` will be invoked. Exactly one call to a start-up function is made per agent.

#### Agent Start-Up (OnLoad phase)

If an agent is started during the `OnLoad` phase then its agent library must export a start-up function with the following prototype:

>     JNIEXPORT jint JNICALL
>     Agent_OnLoad(JavaVM *vm, char *options, void *reserved)

The VM will start the agent by calling this function. It will be called early enough in VM initialization that:

- system properties may be set before they have been used in the start-up of the VM
- the full set of capabilities is still available (note that capabilities that configure the VM may only be available at this time--see the Capability function section)
- no bytecodes have executed
- no classes have been loaded
- no objects have been created

The VM will call the `Agent_OnLoad` function with <options> as the second argument - that is, using the command-line option examples, `"opt1,opt2"` will be passed to the `char *options` argument of `Agent_OnLoad`. The `options` argument is encoded as a modified UTF-8 string. If =<options> is not specified, a zero length string is passed to `options`. The lifespan of the `options` string is the `Agent_OnLoad` call. If needed beyond this time the string or parts of the string must be copied. The period between when `Agent_OnLoad` is called and when it returns is called the OnLoad phase. Since the VM is not initialized during the OnLoad phase, the set of allowed operations inside `Agent_OnLoad` is restricted (see the function descriptions for the functionality available at this time). The agent can safely process the options and set event callbacks with `SetEventCallbacks`. Once the VM initialization event is received (that is, the VMInit callback is invoked), the agent can complete its initialization.

Rationale: Early startup is required so that agents can set the desired capabilities, many of which must be set before the VM is initialized. In JVMDI, the -Xdebug command-line option provided very coarse-grain control of capabilities. JVMPI implementations use various tricks to provide a single "JVMPI on" switch. No reasonable command-line option could provide the fine-grain of control required to balance needed capabilities vs performance impact. Early startup is also needed so that agents can control the execution environment - modifying the file system and system properties to install their functionality.

The return value from `Agent_OnLoad` is used to indicate an error. Any value other than zero indicates an error and causes termination of the VM.

#### Agent Start-Up (Live phase)

A VM may support a mechanism that allows agents to be started in the VM during the live phase. The details of how this is supported, are implementation specific. For example, a tool may use some platform specific mechanism, or implementation specific API, to attach to the running VM, and request it start a given agent.

If an agent is started during the live phase then its agent library must export a start-up function with the following prototype:

>     JNIEXPORT jint JNICALL
>     Agent_OnAttach(JavaVM* vm, char *options, void *reserved)

The VM will start the agent by calling this function. It will be called in the context of a thread that is attached to the VM. The first argument <vm> is the Java VM. The <options> argument is the startup options provided to the agent. <options> is encoded as a modified UTF-8 string. If startup options were not provided, a zero length string is passed to `options`. The lifespan of the `options` string is the `Agent_OnAttach` call. If needed beyond this time the string or parts of the string must be copied.

Note that some capabilities may not be available in the live phase.

The `Agent_OnAttach` function initializes the agent and returns a value to the VM to indicate if an error occurred. Any value other than zero indicates an error. An error does not cause the VM to terminate. Instead the VM ignores the error, or takes some implementation specific action -- for example it might print an error to standard error, or record the error in a system log.

#### Agent Shutdown

The library may optionally export a shutdown function with the following prototype:

>     JNIEXPORT void JNICALL
>     Agent_OnUnload(JavaVM *vm)

This function will be called by the VM when the library is about to be unloaded. The library will be unloaded and this function will be called if some platform specific mechanism causes the unload (an unload mechanism is not specified in this document) or the library is (in effect) unloaded by the termination of the VM whether through normal termination or VM failure, including start-up failure. Uncontrolled shutdown is, of couse, an exception to this rule. Note the distinction between this function and the VM Death event: for the VM Death event to be sent, the VM must have run at least to the point of initialization and a valid JVM TI environment must exist which has set a callback for VMDeath and enabled the event None of these are required for `Agent_OnUnload` and this function is also called if the library is unloaded for other reasons. In the case that a VM Death event is sent, it will be sent before this function is called (assuming this function is called due to VM termination). This function can be used to clean-up resources allocated by the agent.

#### JAVA_TOOL_OPTIONS

Since the command-line cannot always be accessed or modified, for example in embedded VMs or simply VMs launched deep within scripts, a `JAVA_TOOL_OPTIONS` variable is provided so that agents may be launched in these cases.

Platforms which support environment variables or other named strings, may support the `JAVA_TOOL_OPTIONS` variable. This variable will be broken into options at white-space boundaries. White-space characters include space, tab, carriage-return, new-line, vertical-tab, and form-feed. Sequences of white-space characters are considered equivalent to a single white-space character. No white-space is included in the options unless quoted. Quoting is as follows:

- All characters enclosed between a pair of single quote marks (''), except a single quote, are quoted.
- Double quote characters have no special meaning inside a pair of single quote marks.
- All characters enclosed between a pair of double quote marks (""), except a double quote, are quoted.
- Single quote characters have no special meaning inside a pair of double quote marks.
- A quoted part can start or end anywhere in the variable.
- White-space characters have no special meaning when quoted -- they are included in the option like any other character and do not mark white-space boundaries.
- The pair of quote marks is not included in the option.

`JNI_CreateJavaVM` (in the JNI Invocation API) will prepend these options to the options supplied in its `JavaVMInitArgs` argument. Platforms may disable this feature in cases where security is a concern; for example, the Reference Implementation disables this feature on Unix systems when the effective user or group ID differs from the real ID. This feature is intended to support the initialization of tools -- specifically including the launching of native or Java programming language agents. Multiple tools may wish to use this feature, so the variable should not be overwritten, instead, options should be appended to the variable. Note that since the variable is processed at the time of the JNI Invocation API create VM call, options processed by a launcher (e.g., VM selection options) will not be handled.

#### Environments

The JVM TI specification supports the use of multiple simultaneous JVM TI agents. Each agent has its own JVM TI environment. That is, the JVM TI state is separate for each agent - changes to one environment do not affect the others. The state of a JVM TI environment includes:

- the event callbacks
- the set of events which are enabled
- the capabilities
- the memory allocation/deallocation hooks

Although their JVM TI state is separate, agents inspect and modify the shared state of the VM, they also share the native environment in which they execute. As such, an agent can perturb the results of other agents or cause them to fail. It is the responsibility of the agent writer to specify the level of compatibility with other agents. JVM TI implementations are not capable of preventing destructive interactions between agents. Techniques to reduce the likelihood of these occurrences are beyond the scope of this document.

An agent creates a JVM TI environment by passing a JVM TI version as the interface ID to the JNI Invocation API function GetEnv. See Accessing JVM TI Functions for more details on the creation and use of JVM TI environments. Typically, JVM TI environments are created by calling `GetEnv` from `Agent_OnLoad`.

#### Bytecode Instrumentation

This interface does not include some events that one might expect in an interface with profiling support. Some examples include object allocation events and full speed method enter and exit events. The interface instead provides support for bytecode instrumentation, the ability to alter the Java virtual machine bytecode instructions which comprise the target program. Typically, these alterations are to add "events" to the code of a method - for example, to add, at the beginning of a method, a call to `MyProfiler.methodEntered()`. Since the changes are purely additive, they do not modify application state or behavior. Because the inserted agent code is standard bytecodes, the VM can run at full speed, optimizing not only the target program but also the instrumentation. If the instrumentation does not involve switching from bytecode execution, no expensive state transitions are needed. The result is high performance events. This approach also provides complete control to the agent: instrumentation can be restricted to "interesting" portions of the code (e.g., the end user's code) and can be conditional. Instrumentation can run entirely in Java programming language code or can call into the native agent. Instrumentation can simply maintain counters or can statistically sample events.

Instrumentation can be inserted in one of three ways:

- Static Instrumentation: The class file is instrumented before it is loaded into the VM - for example, by creating a duplicate directory of `*.class` files which have been modified to add the instrumentation. This method is extremely awkward and, in general, an agent cannot know the origin of the class files which will be loaded.
- Load-Time Instrumentation: When a class file is loaded by the VM, the raw bytes of the class file are sent for instrumentation to the agent. The `ClassFileLoadHook` event, triggered by the class load, provides this functionality. This mechanism provides efficient and complete access to one-time instrumentation.
- Dynamic Instrumentation: A class which is already loaded (and possibly even running) is modified. This optional feature is provided by the `ClassFileLoadHook` event, triggered by calling the `RetransformClasses` function. Classes can be modified multiple times and can be returned to their original state. The mechanism allows instrumentation which changes during the course of execution.

The class modification functionality provided in this interface is intended to provide a mechanism for instrumentation (the `ClassFileLoadHook` event and the `RetransformClasses` function) and, during development, for fix-and-continue debugging (the `RedefineClasses` function).

Care must be taken to avoid perturbing dependencies, especially when instrumenting core classes. For example, an approach to getting notification of every object allocation is to instrument the constructor on `Object`. Assuming that the constructor is initially empty, the constructor could be changed to:

>           public Object() {
>             MyProfiler.allocationTracker(this);
>           }

However, if this change was made using the `ClassFileLoadHook` event then this might impact a typical VM as follows: the first created object will call the constructor causing a class load of `MyProfiler`; which will then cause object creation, and since `MyProfiler` isn't loaded yet, infinite recursion; resulting in a stack overflow. A refinement of this would be to delay invoking the tracking method until a safe time. For example, `trackAllocations` could be set in the handler for the `VMInit` event.

>           static boolean trackAllocations = false;

>           public Object() {
>             if (trackAllocations) {
>               MyProfiler.allocationTracker(this);
>             }
>           }

The `SetNativeMethodPrefix` allows native methods to be instrumented by the use of wrapper methods.

#### Modified UTF-8 String Encoding

JVM TI uses modified UTF-8 to encode character strings. This is the same encoding used by JNI. Modified UTF-8 differs from standard UTF-8 in the representation of supplementary characters and of the null character. See the Modified UTF-8 Strings section of the JNI specification for details.

#### Specification Context

Since this interface provides access to the state of applications running in the Java virtual machine; terminology refers to the Java platform and not the native platform (unless stated otherwise). For example:

- "thread" means Java programming language thread.
- "stack frame" means Java virtual machine stack frame.
- "class" means Java programming language class.
- "heap" means Java virtual machine heap.
- "monitor" means Java programming language object monitor.

Sun, Sun Microsystems, the Sun logo, Java, and JVM are trademarks or registered trademarks of Sun Microsystems, Inc. in the U.S. and other countries.

## Functions

#### Accessing Functions

Native code accesses JVM TI features by calling JVM TI functions. Access to JVM TI functions is by use of an interface pointer in the same manner as Java Native Interface (JNI) functions are accessed. The JVM TI interface pointer is called the environment pointer.

An environment pointer is a pointer to an environment and has the type `jvmtiEnv*`. An environment has information about its JVM TI connection. The first value in the environment is a pointer to the function table. The function table is an array of pointers to JVM TI functions. Every function pointer is at a predefined offset inside the array.

When used from the C language: double indirection is used to access the functions; the environment pointer provides context and is the first parameter of each function call; for example:

>     jvmtiEnv *jvmti;
>     ...
>     jvmtiError err = (*jvmti)->GetLoadedClasses(jvmti, &class_count, &classes);

When used from the C++ language: functions are accessed as member functions of `jvmtiEnv`; the environment pointer is not passed to the function call; for example:

>     jvmtiEnv *jvmti;
>     ...
>     jvmtiError err = jvmti->GetLoadedClasses(&class_count, &classes);

Unless otherwise stated, all examples and declarations in this specification use the C language.

A JVM TI environment can be obtained through the JNI Invocation API `GetEnv` function:

>     jvmtiEnv *jvmti;
>     ...
>     (*jvm)->GetEnv(jvm, &jvmti, JVMTI_VERSION_1_0);

Each call to `GetEnv` creates a new JVM TI connection and thus a new JVM TI environment. The `version` argument of `GetEnv` must be a JVM TI version. The returned environment may have a different version than the requested version but the returned environment must be compatible. `GetEnv` will return `JNI_EVERSION` if a compatible version is not available, if JVM TI is not supported or JVM TI is not supported in the current VM configuration. Other interfaces may be added for creating JVM TI environments in specific contexts. Each environment has its own state (for example, desired events, event handling functions, and capabilities). An environment is released with `DisposeEnvironment`. Thus, unlike JNI which has one environment per thread, JVM TI environments work across threads and are created dynamically.

#### Function Return Values

JVM TI functions always return an error code via the `jvmtiError` function return value. Some functions can return additional values through pointers provided by the calling function. In some cases, JVM TI functions allocate memory that your program must explicitly deallocate. This is indicated in the individual JVM TI function descriptions. Empty lists, arrays, sequences, etc are returned as `NULL`.

In the event that the JVM TI function encounters an error (any return value other than `JVMTI_ERROR_NONE`) the values of memory referenced by argument pointers is undefined, but no memory will have been allocated and no global references will have been allocated. If the error occurs because of invalid input, no action will have occurred.

#### Managing JNI Object References

JVM TI functions identify objects with JNI references (`jobject` and `jclass`) and their derivatives (`jthread` and `jthreadGroup`). References passed to JVM TI functions can be either global or local, but they must be strong references. All references returned by JVM TI functions are local references--these local references are created during the JVM TI call. Local references are a resource that must be managed (see the JNI Documentation). When threads return from native code all local references are freed. Note that some threads, including typical agent threads, will never return from native code. A thread is ensured the ability to create sixteen local references without the need for any explicit management. For threads executing a limited number of JVM TI calls before returning from native code (for example, threads processing events), it may be determined that no explicit management is needed. However, long running agent threads will need explicit local reference management--usually with the JNI functions `PushLocalFrame` and `PopLocalFrame`. Conversely, to preserve references beyond the return from native code, they must be converted to global references. These rules do not apply to `jmethodID` and `jfieldID` as they are not `jobject`s.

#### Prerequisite State for Calling Functions

Unless the function explicitly states that the agent must bring a thread or the VM to a particular state (for example, suspended), the JVM TI implementation is responsible for bringing the VM to a safe and consistent state for performing the function.

#### Exceptions and Functions

JVM TI functions never throw exceptions; error conditions are communicated via the function return value. Any existing exception state is preserved across a call to a JVM TI function. See the Java Exceptions section of the JNI specification for information on handling exceptions.

### Function Index

- Memory Management
  - Allocate
  - Deallocate
- Thread
  - Get Thread State
  - Get Current Thread
  - Get All Threads
  - Suspend Thread
  - Suspend Thread List
  - Resume Thread
  - Resume Thread List
  - Stop Thread
  - Interrupt Thread
  - Get Thread Info
  - Get Owned Monitor Info
  - Get Owned Monitor Stack Depth Info
  - Get Current Contended Monitor
  - Run Agent Thread
  - Set Thread Local Storage
  - Get Thread Local Storage
- Thread Group
  - Get Top Thread Groups
  - Get Thread Group Info
  - Get Thread Group Children
- Stack Frame
  - Get Stack Trace
  - Get All Stack Traces
  - Get Thread List Stack Traces
  - Get Frame Count
  - Pop Frame
  - Get Frame Location
  - Notify Frame Pop
- Force Early Return
  - Force Early Return - Object
  - Force Early Return - Int
  - Force Early Return - Long
  - Force Early Return - Float
  - Force Early Return - Double
  - Force Early Return - Void
- Heap
  - Follow References
  - Iterate Through Heap
  - Get Tag
  - Set Tag
  - Get Objects With Tags
  - Force Garbage Collection
- Heap (1.0)
  - Iterate Over Objects Reachable From Object
  - Iterate Over Reachable Objects
  - Iterate Over Heap
  - Iterate Over Instances Of Class
- Local Variable
  - Get Local Variable - Object
  - Get Local Variable - Int
  - Get Local Variable - Long
  - Get Local Variable - Float
  - Get Local Variable - Double
  - Set Local Variable - Object
  - Set Local Variable - Int
  - Set Local Variable - Long
  - Set Local Variable - Float
  - Set Local Variable - Double
- Breakpoint
  - Set Breakpoint
  - Clear Breakpoint
- Watched Field
  - Set Field Access Watch
  - Clear Field Access Watch
  - Set Field Modification Watch
  - Clear Field Modification Watch
- Class
  - Get Loaded Classes
  - Get Classloader Classes
  - Get Class Signature
  - Get Class Status
  - Get Source File Name
  - Get Class Modifiers
  - Get Class Methods
  - Get Class Fields
  - Get Implemented Interfaces
  - Get Class Version Numbers
  - Get Constant Pool
  - Is Interface
  - Is Array Class
  - Is Modifiable Class
  - Get Class Loader
  - Get Source Debug Extension
  - Retransform Classes
  - Redefine Classes
- Object
  - Get Object Size
  - Get Object Hash Code
  - Get Object Monitor Usage
- Field
  - Get Field Name (and Signature)
  - Get Field Declaring Class
  - Get Field Modifiers
  - Is Field Synthetic
- Method
  - Get Method Name (and Signature)
  - Get Method Declaring Class
  - Get Method Modifiers
  - Get Max Locals
  - Get Arguments Size
  - Get Line Number Table
  - Get Method Location
  - Get Local Variable Table
  - Get Bytecodes
  - Is Method Native
  - Is Method Synthetic
  - Is Method Obsolete
  - Set Native Method Prefix
  - Set Native Method Prefixes
- Raw Monitor
  - Create Raw Monitor
  - Destroy Raw Monitor
  - Raw Monitor Enter
  - Raw Monitor Exit
  - Raw Monitor Wait
  - Raw Monitor Notify
  - Raw Monitor Notify All
- JNI Function Interception
  - Set JNI Function Table
  - Get JNI Function Table
- Event Management
  - Set Event Callbacks
  - Set Event Notification Mode
  - Generate Events
- Extension Mechanism
  - Get Extension Functions
  - Get Extension Events
  - Set Extension Event Callback
- Capability
  - Get Potential Capabilities
  - Add Capabilities
  - Relinquish Capabilities
  - Get Capabilities
- Timers
  - Get Current Thread CPU Timer Information
  - Get Current Thread CPU Time
  - Get Thread CPU Timer Information
  - Get Thread CPU Time
  - Get Timer Information
  - Get Time
  - Get Available Processors
- Class Loader Search
  - Add To Bootstrap Class Loader Search
  - Add To System Class Loader Search
- System Properties
  - Get System Properties
  - Get System Property
  - Set System Property
- General
  - Get Phase
  - Dispose Environment
  - Set Environment Local Storage
  - Get Environment Local Storage
  - Get Version Number
  - Get Error Name
  - Set Verbose Flag
  - Get JLocation Format

## Memory Management

Memory Management functions:

- Allocate
- Deallocate

These functions provide for the allocation and deallocation of memory used by JVM TI functionality and can be used to provide working memory for agents. Memory managed by JVM TI is not compatible with other memory allocation libraries and mechanisms.

### Allocate

>     jvmtiError
>     Allocate(jvmtiEnv* env,
>                 jlong size,
>                 unsigned char** mem_ptr)

Allocate an area of memory through the JVM TI allocator. The allocated memory should be freed with `Deallocate`.

Phase | Callback Safe | Position | Since
may be called during any phase | This function may be called from the callbacks to the Heap iteration functions, or from the event handlers for the `GarbageCollectionStart`, `GarbageCollectionFinish`, and `ObjectFree` events. | 46 | 1.0

Capabilities
Required Functionality

Parameters
Name | Type | Description
`size` | `jlong` | The number of bytes to allocate. Rationale: `jlong` is used for compatibility with JVMDI.
`mem_ptr` | `unsigned char**` | On return, a pointer to the beginning of the allocated memory. If `size` is zero, `NULL` is returned. Agent passes a pointer to a `unsigned char*`. On return, the `unsigned char*` points to a newly allocated array of size `size`. The array should be freed with `Deallocate`.

Errors
This function returns either a universal error or one of the following errors
Error | Description
`JVMTI_ERROR_OUT_OF_MEMORY` | Memory request cannot be honored.
`JVMTI_ERROR_ILLEGAL_ARGUMENT` | `size` is less than zero.
`JVMTI_ERROR_NULL_POINTER` | `mem_ptr` is `NULL`.

### Deallocate

>     jvmtiError
>     Deallocate(jvmtiEnv* env,
>                 unsigned char* mem)

Deallocate `mem` using the JVM TI allocator. This function should be used to deallocate any memory allocated and returned by a JVM TI function (including memory allocated with `Allocate`). All allocated memory must be deallocated or the memory cannot be reclaimed.

Phase | Callback Safe | Position | Since
may be called during any phase | This function may be called from the callbacks to the Heap iteration functions, or from the event handlers for the `GarbageCollectionStart`, `GarbageCollectionFinish`, and `ObjectFree` events. | 47 | 1.0

Capabilities
Required Functionality

Parameters
Name | Type | Description
`mem` | `unsigned char *` | A pointer to the beginning of the allocated memory. Please ignore "On return, the elements are set." Agent passes an array of `unsigned char`. The incoming values of the elements of the array are ignored. On return, the elements are set. If `mem` is `NULL`, the call is ignored.

Errors
This function returns a universal error

## Thread

Thread functions:

- Get Thread State
- Get Current Thread
- Get All Threads
- Suspend Thread
- Suspend Thread List
- Resume Thread
- Resume Thread List
- Stop Thread
- Interrupt Thread
- Get Thread Info
- Get Owned Monitor Info
- Get Owned Monitor Stack Depth Info
- Get Current Contended Monitor
- Run Agent Thread
- Set Thread Local Storage
- Get Thread Local Storage

Thread function types:

- Agent Start Function

Thread types:

- `jvmtiThreadInfo` - Thread information structure
- `jvmtiMonitorStackDepthInfo` - Monitor stack depth information structure

Thread flags and constants:

- Thread State Flags
- java.lang.Thread.State Conversion Masks
- Thread Priority Constants

### Get Thread State

>     jvmtiError
>     GetThreadState(jvmtiEnv* env,
>                 jthread thread,
>                 jint* thread_state_ptr)

Get the state of a thread. The state of the thread is represented by the answers to the hierarchical set of questions below:

- Alive?
  - Not alive.
    - Why not alive?
      - New.
      - Terminated (`JVMTI_THREAD_STATE_TERMINATED`)
  - Alive (`JVMTI_THREAD_STATE_ALIVE`)
    - Suspended?
      - Suspended (`JVMTI_THREAD_STATE_SUSPENDED`)
      - Not suspended
    - Interrupted?
      - Interrupted (`JVMTI_THREAD_STATE_INTERRUPTED`)
      - Not interrupted.
    - In native?
      - In native code (`JVMTI_THREAD_STATE_IN_NATIVE`)
      - In Java programming language code
    - What alive state?
      - Runnable (`JVMTI_THREAD_STATE_RUNNABLE`)
      - Blocked (`JVMTI_THREAD_STATE_BLOCKED_ON_MONITOR_ENTER`)
      - Waiting (`JVMTI_THREAD_STATE_WAITING`)
        - Timed wait?
          - Indefinite (`JVMTI_THREAD_STATE_WAITING_INDEFINITELY`
          - Timed (`JVMTI_THREAD_STATE_WAITING_WITH_TIMEOUT`)
        - Why waiting?
          - Object.wait (`JVMTI_THREAD_STATE_IN_OBJECT_WAIT`)
          - LockSupport.park (`JVMTI_THREAD_STATE_PARKED`)
          - Sleeping (`JVMTI_THREAD_STATE_SLEEPING`)

The answers are represented by the following bit vector.

> Thread State Flags
> Constant | Value | Description
> `JVMTI_THREAD_STATE_ALIVE` | 0x0001 | Thread is alive. Zero if thread is new (not started) or terminated.
> `JVMTI_THREAD_STATE_TERMINATED` | 0x0002 | Thread has completed execution.
> `JVMTI_THREAD_STATE_RUNNABLE` | 0x0004 | Thread is runnable.
> `JVMTI_THREAD_STATE_BLOCKED_ON_MONITOR_ENTER` | 0x0400 | Thread is waiting to enter a synchronization block/method or, after an `Object.wait()`, waiting to re-enter a synchronization block/method.
> `JVMTI_THREAD_STATE_WAITING` | 0x0080 | Thread is waiting.
> `JVMTI_THREAD_STATE_WAITING_INDEFINITELY` | 0x0010 | Thread is waiting without a timeout. For example, `Object.wait()`.
> `JVMTI_THREAD_STATE_WAITING_WITH_TIMEOUT` | 0x0020 | Thread is waiting with a maximum time to wait specified. For example, `Object.wait(long)`.
> `JVMTI_THREAD_STATE_SLEEPING` | 0x0040 | Thread is sleeping -- `Thread.sleep(long)`.
> `JVMTI_THREAD_STATE_IN_OBJECT_WAIT` | 0x0100 | Thread is waiting on an object monitor -- `Object.wait`.
> `JVMTI_THREAD_STATE_PARKED` | 0x0200 | Thread is parked, for example: `LockSupport.park`, `LockSupport.parkUtil` and `LockSupport.parkNanos`.
> `JVMTI_THREAD_STATE_SUSPENDED` | 0x100000 | Thread suspended. `java.lang.Thread.suspend()` or a JVM TI suspend function (such as `SuspendThread`) has been called on the thread. If this bit is set, the other bits refer to the thread state before suspension.
> `JVMTI_THREAD_STATE_INTERRUPTED` | 0x200000 | Thread has been interrupted.
> `JVMTI_THREAD_STATE_IN_NATIVE` | 0x400000 | Thread is in native code--that is, a native method is running which has not called back into the VM or Java programming language code. This flag is not set when running VM compiled Java programming language code nor is it set when running VM code or VM support code. Native VM interface functions, such as JNI and JVM TI functions, may be implemented as VM code.
> `JVMTI_THREAD_STATE_VENDOR_1` | 0x10000000 | Defined by VM vendor.
> `JVMTI_THREAD_STATE_VENDOR_2` | 0x20000000 | Defined by VM vendor.
> `JVMTI_THREAD_STATE_VENDOR_3` | 0x40000000 | Defined by VM vendor.

The following definitions are used to convert JVM TI thread state to `java.lang.Thread.State` style states.

> java.lang.Thread.State Conversion Masks
> Constant | Value | Description
> `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 | Mask the state with this before comparison
> `JVMTI_JAVA_LANG_THREAD_STATE_NEW` | 0 | `java.lang.Thread.State.NEW`
> `JVMTI_JAVA_LANG_THREAD_STATE_TERMINATED` | JVMTI_THREAD_STATE_TERMINATED | `java.lang.Thread.State.TERMINATED`
> `JVMTI_JAVA_LANG_THREAD_STATE_RUNNABLE` | JVMTI_THREAD_STATE_ALIVE | JVMTI_THREAD_STATE_RUNNABLE | `java.lang.Thread.State.RUNNABLE`
> `JVMTI_JAVA_LANG_THREAD_STATE_BLOCKED` | JVMTI_THREAD_STATE_ALIVE | JVMTI_THREAD_STATE_BLOCKED_ON_MONITOR_ENTER | `java.lang.Thread.State.BLOCKED`
> `JVMTI_JAVA_LANG_THREAD_STATE_WAITING` | JVMTI_THREAD_STATE_ALIVE | JVMTI_THREAD_STATE_WAITING | JVMTI_THREAD_STATE_WAITING_INDEFINITELY | `java.lang.Thread.State.WAITING`
> `JVMTI_JAVA_LANG_THREAD_STATE_TIMED_WAITING` | JVMTI_THREAD_STATE_ALIVE | JVMTI_THREAD_STATE_WAITING | JVMTI_THREAD_STATE_WAITING_WITH_TIMEOUT | `java.lang.Thread.State.TIMED_WAITING`

Rules

There can be no more than one answer to a question, although there can be no answer (because the answer is unknown, does not apply, or none of the answers is correct). An answer is set only when the enclosing answers match. That is, no more than one of

- `JVMTI_THREAD_STATE_RUNNABLE`
- `JVMTI_THREAD_STATE_BLOCKED_ON_MONITOR_ENTER`
- `JVMTI_THREAD_STATE_WAITING`

can be set (a J2SETM compliant implementation will always set one of these if `JVMTI_THREAD_STATE_ALIVE` is set). And if any of these are set, the enclosing answer `JVMTI_THREAD_STATE_ALIVE` is set. No more than one of

- `JVMTI_THREAD_STATE_WAITING_INDEFINITELY`
- `JVMTI_THREAD_STATE_WAITING_WITH_TIMEOUT`

can be set (a J2SETM compliant implementation will always set one of these if `JVMTI_THREAD_STATE_WAITING` is set). And if either is set, the enclosing answers `JVMTI_THREAD_STATE_ALIVE` and `JVMTI_THREAD_STATE_WAITING` are set. No more than one of

- `JVMTI_THREAD_STATE_IN_OBJECT_WAIT`
- `JVMTI_THREAD_STATE_PARKED`
- `JVMTI_THREAD_STATE_SLEEPING`

can be set. And if any of these is set, the enclosing answers `JVMTI_THREAD_STATE_ALIVE` and `JVMTI_THREAD_STATE_WAITING` are set. Also, if `JVMTI_THREAD_STATE_SLEEPING` is set, then `JVMTI_THREAD_STATE_WAITING_WITH_TIMEOUT` is set. If a state A is implemented using the mechanism of state B then it is state A which is returned by this function. For example, if `Thread.sleep(long)` is implemented using `Object.wait(long)` then it is still `JVMTI_THREAD_STATE_SLEEPING` which is returned. More than one of

- `JVMTI_THREAD_STATE_SUSPENDED`
- `JVMTI_THREAD_STATE_INTERRUPTED`
- `JVMTI_THREAD_STATE_IN_NATIVE`

can be set, but if any is set, `JVMTI_THREAD_STATE_ALIVE` is set.

And finally, `JVMTI_THREAD_STATE_TERMINATED` cannot be set unless `JVMTI_THREAD_STATE_ALIVE` is not set.

The thread state representation is designed for extension in future versions of the specification; thread state values should be used accordingly, that is they should not be used as ordinals. Most queries can be made by testing a single bit, if use in a switch statement is desired, the state bits should be masked with the interesting bits. All bits not defined above are reserved for future use. A VM, compliant to the current specification, must set reserved bits to zero. An agent should ignore reserved bits -- they should not be assumed to be zero and thus should not be included in comparisons.

Examples

Note that the values below exclude reserved and vendor bits.

The state of a thread blocked at a `synchronized`-statement would be:

>                 JVMTI_THREAD_STATE_ALIVE + JVMTI_THREAD_STATE_BLOCKED_ON_MONITOR_ENTER

The state of a thread which hasn't started yet would be:

>                 0

The state of a thread at a `Object.wait(3000)` would be:

>                 JVMTI_THREAD_STATE_ALIVE + JVMTI_THREAD_STATE_WAITING +
>                     JVMTI_THREAD_STATE_WAITING_WITH_TIMEOUT +
>                     JVMTI_THREAD_STATE_MONITOR_WAITING

The state of a thread suspended while runnable would be:

>                 JVMTI_THREAD_STATE_ALIVE + JVMTI_THREAD_STATE_RUNNABLE + JVMTI_THREAD_STATE_SUSPENDED

Testing the State

In most cases, the thread state can be determined by testing the one bit corresponding to that question. For example, the code to test if a thread is sleeping:

>     	jint state;
>     	jvmtiError err;

>     	err = (*jvmti)->GetThreadState(jvmti, thread, &state);
>     	if (err == JVMTI_ERROR_NONE) {
>     	   if (state & JVMTI_THREAD_STATE_SLEEPING) {  ...

For waiting (that is, in `Object.wait`, parked, or sleeping) it would be:

>     	   if (state & JVMTI_THREAD_STATE_WAITING) {  ...

For some states, more than one bit will need to be tested as is the case when testing if a thread has not yet been started:

>     	   if ((state & (JVMTI_THREAD_STATE_ALIVE | JVMTI_THREAD_STATE_TERMINATED)) == 0)  {  ...

To distinguish timed from untimed `Object.wait`:

>     	   if (state & JVMTI_THREAD_STATE_IN_OBJECT_WAIT)  {
>                  if (state & JVMTI_THREAD_STATE_WAITING_WITH_TIMEOUT)  {
>                    printf("in Object.wait(long timeout)\n");
>                  } else {
>                    printf("in Object.wait()\n");
>                  }
>                }

Relationship to `java.lang.Thread.State`

The thread state represented by `java.lang.Thread.State` returned from `java.lang.Thread.getState()` is a subset of the information returned from this function. The corresponding `java.lang.Thread.State` can be determined by using the provided conversion masks. For example, this returns the name of the `java.lang.Thread.State` thread state:

>     	    err = (*jvmti)->GetThreadState(jvmti, thread, &state);
>     	    abortOnError(err);
>                 switch (state & JVMTI_JAVA_LANG_THREAD_STATE_MASK) {
>                 case JVMTI_JAVA_LANG_THREAD_STATE_NEW:
>                   return "NEW";
>                 case JVMTI_JAVA_LANG_THREAD_STATE_TERMINATED:
>                   return "TERMINATED";
>                 case JVMTI_JAVA_LANG_THREAD_STATE_RUNNABLE:
>                   return "RUNNABLE";
>                 case JVMTI_JAVA_LANG_THREAD_STATE_BLOCKED:
>                   return "BLOCKED";
>                 case JVMTI_JAVA_LANG_THREAD_STATE_WAITING:
>                   return "WAITING";
>                 case JVMTI_JAVA_LANG_THREAD_STATE_TIMED_WAITING:
>                   return "TIMED_WAITING";
>                 }

Phase | Callback Safe | Position | Since
may only be called during the live phase | No | 17 | 1.0

Capabilities
Required Functionality

Parameters
Name | Type | Description
`thread` | `jthread` | The thread to query. If `thread` is `NULL`, the current thread is used.
`thread_state_ptr` | `jint*` | On return, points to state flags, as defined by the Thread State Flags. Agent passes a pointer to a `jint`. On return, the `jint` has been set.

Errors
This function returns either a universal error or one of the following errors
Error | Description
`JVMTI_ERROR_INVALID_THREAD` | `thread` is not a thread object.
`JVMTI_ERROR_NULL_POINTER` | `thread_state_ptr` is `NULL`.

### Get Current Thread

>     jvmtiError
>     GetCurrentThread(jvmtiEnv* env,
>                 jthread* thread_ptr)

Get the current thread. The current thread is the Java programming language thread which has called the function.

Note that most JVM TI functions that take a thread as an argument will accept `NULL` to mean the current thread.

Phase | Callback Safe | Position | Since
may only be called during the start or the live phase | No | 18 | 1.1

Capabilities
Required Functionality

Parameters
Name | Type | Description
`thread_ptr` | `jthread*` | On return, points to the current thread. Agent passes a pointer to a `jthread`. On return, the `jthread` has been set. The object returned by `thread_ptr` is a JNI local reference and must be managed.

Errors
This function returns either a universal error or one of the following errors
Error | Description
`JVMTI_ERROR_NULL_POINTER` | `thread_ptr` is `NULL`.

### Get All Threads

>     jvmtiError
>     GetAllThreads(jvmtiEnv* env,
>                 jint* threads_count_ptr,
>                 jthread** threads_ptr)

Get all live threads. The threads are Java programming language threads; that is, threads that are attached to the VM. A thread is live if `java.lang.Thread.isAlive()` would return `true`, that is, the thread has been started and has not yet died. The universe of threads is determined by the context of the JVM TI environment, which typically is all threads attached to the VM. Note that this includes JVM TI agent threads (see `RunAgentThread`).

Phase | Callback Safe | Position | Since
may only be called during the live phase | No | 4 | 1.0

Capabilities
Required Functionality

Parameters
Name | Type | Description
`threads_count_ptr` | `jint*` | On return, points to the number of running threads. Agent passes a pointer to a `jint`. On return, the `jint` has been set.
`threads_ptr` | `jthread**` | On return, points to an array of references, one for each running thread. Agent passes a pointer to a `jthread*`. On return, the `jthread*` points to a newly allocated array of size `*threads_count_ptr`. The array should be freed with `Deallocate`. The objects returned by `threads_ptr` are JNI local references and must be managed.

Errors
This function returns either a universal error or one of the following errors
Error | Description
`JVMTI_ERROR_NULL_POINTER` | `threads_count_ptr` is `NULL`.
`JVMTI_ERROR_NULL_POINTER` | `threads_ptr` is `NULL`.

### Suspend Thread

>     jvmtiError
>     SuspendThread(jvmtiEnv* env,
>                 jthread thread)

Suspend the specified thread. If the calling thread is specified, this function will not return until some other thread calls `ResumeThread`. If the thread is currently suspended, this function does nothing and returns an error.

Phase | Callback Safe | Position | Since
may only be called during the live phase | No | 5 | 1.0

Capabilities
Optional Functionality: might not be implemented for all virtual machines. The following capability (as returned by `GetCapabilities`) must be true to use this function.
Capability | Effect
`can_suspend` | Can suspend and resume threads

Parameters
Name | Type | Description
`thread` | `jthread` | The thread to suspend. If `thread` is `NULL`, the current thread is used.

Errors
This function returns either a universal error or one of the following errors
Error | Description
`JVMTI_ERROR_MUST_POSSESS_CAPABILITY` | The environment does not possess the capability `can_suspend`. Use `AddCapabilities`.
`JVMTI_ERROR_THREAD_SUSPENDED` | Thread already suspended.
`JVMTI_ERROR_INVALID_THREAD` | `thread` is not a thread object.
`JVMTI_ERROR_THREAD_NOT_ALIVE` | `thread` is not live (has not been started or is now dead).

### Suspend Thread List

>     jvmtiError
>     SuspendThreadList(jvmtiEnv* env,
>                 jint request_count,
>                 const jthread* request_list,
>                 jvmtiError* results)

Suspend the `request_count` threads specified in the `request_list` array. Threads may be resumed with `ResumeThreadList` or `ResumeThread`. If the calling thread is specified in the `request_list` array, this function will not return until some other thread resumes it. Errors encountered in the suspension of a thread are returned in the `results` array, not in the return value of this function. Threads that are currently suspended do not change state.

Phase | Callback Safe | Position | Since
may only be called during the live phase | No | 92 | 1.0

Capabilities
Optional Functionality: might not be implemented for all virtual machines. The following capability (as returned by `GetCapabilities`) must be true to use this function.
Capability | Effect
`can_suspend` | Can suspend and resume threads

Parameters
Name | Type | Description
`request_count` | `jint` | The number of threads to suspend.
`request_list` | `const jthread*` | The list of threads to suspend. Agent passes in an array of `request_count` elements of `jthread`.
`results` | `jvmtiError*` | An agent supplied array of `request_count` elements. On return, filled with the error code for the suspend of the corresponding thread. The error code will be `JVMTI_ERROR_NONE` if the thread was suspended by this call. Possible error codes are those specified for `SuspendThread`. Agent passes an array large enough to hold `request_count` elements of `jvmtiError`. The incoming values of the elements of the array are ignored. On return, the elements are set.

Errors
This function returns either a universal error or one of the following errors
Error | Description
`JVMTI_ERROR_MUST_POSSESS_CAPABILITY` | The environment does not possess the capability `can_suspend`. Use `AddCapabilities`.
`JVMTI_ERROR_ILLEGAL_ARGUMENT` | `request_count` is less than `0`.
`JVMTI_ERROR_NULL_POINTER` | `request_list` is `NULL`.
`JVMTI_ERROR_NULL_POINTER` | `results` is `NULL`.

### Resume Thread

>     jvmtiError
>     ResumeThread(jvmtiEnv* env,
>                 jthread thread)

Resume a suspended thread. Any threads currently suspended through a JVM TI suspend function (eg. `SuspendThread`) or `java.lang.Thread.suspend()` will resume execution; all other threads are unaffected.

Phase | Callback Safe | Position | Since
may only be called during the live phase | No | 6 | 1.0

Capabilities
Optional Functionality: might not be implemented for all virtual machines. The following capability (as returned by `GetCapabilities`) must be true to use this function.
Capability | Effect
`can_suspend` | Can suspend and resume threads

Parameters
Name | Type | Description
`thread` | `jthread` | The thread to resume.

Errors
This function returns either a universal error or one of the following errors
Error | Description
`JVMTI_ERROR_MUST_POSSESS_CAPABILITY` | The environment does not possess the capability `can_suspend`. Use `AddCapabilities`.
`JVMTI_ERROR_THREAD_NOT_SUSPENDED` | Thread was not suspended.
`JVMTI_ERROR_INVALID_TYPESTATE` | The state of the thread has been modified, and is now inconsistent.
`JVMTI_ERROR_INVALID_THREAD` | `thread` is not a thread object.
`JVMTI_ERROR_THREAD_NOT_ALIVE` | `thread` is not live (has not been started or is now dead).

### Resume Thread List

>     jvmtiError
>     ResumeThreadList(jvmtiEnv* env,
>                 jint request_count,
>                 const jthread* request_list,
>                 jvmtiError* results)

Resume the `request_count` threads specified in the `request_list` array. Any thread suspended through a JVM TI suspend function (eg. `SuspendThreadList`) or `java.lang.Thread.suspend()` will resume execution.

Phase | Callback Safe | Position | Since
may only be called during the live phase | No | 93 | 1.0

Capabilities
Optional Functionality: might not be implemented for all virtual machines. The following capability (as returned by `GetCapabilities`) must be true to use this function.
Capability | Effect
`can_suspend` | Can suspend and resume threads

Parameters
Name | Type | Description
`request_count` | `jint` | The number of threads to resume.
`request_list` | `const jthread*` | The threads to resume. Agent passes in an array of `request_count` elements of `jthread`.
`results` | `jvmtiError*` | An agent supplied array of `request_count` elements. On return, filled with the error code for the resume of the corresponding thread. The error code will be `JVMTI_ERROR_NONE` if the thread was suspended by this call. Possible error codes are those specified for `ResumeThread`. Agent passes an array large enough to hold `request_count` elements of `jvmtiError`. The incoming values of the elements of the array are ignored. On return, the elements are set.

Errors
This function returns either a universal error or one of the following errors
Error | Description
`JVMTI_ERROR_MUST_POSSESS_CAPABILITY` | The environment does not possess the capability `can_suspend`. Use `AddCapabilities`.
`JVMTI_ERROR_ILLEGAL_ARGUMENT` | `request_count` is less than `0`.
`JVMTI_ERROR_NULL_POINTER` | `request_list` is `NULL`.
`JVMTI_ERROR_NULL_POINTER` | `results` is `NULL`.

### Stop Thread

>     jvmtiError
>     StopThread(jvmtiEnv* env,
>                 jthread thread,
>                 jobject exception)

Send the specified asynchronous exception to the specified thread (similar to `java.lang.Thread.stop`). Normally, this function is used to kill the specified thread with an instance of the exception `ThreadDeath`.

Phase | Callback Safe | Position | Since
may only be called during the live phase | No | 7 | 1.0

Capabilities
Optional Functionality: might not be implemented for all virtual machines. The following capability (as returned by `GetCapabilities`) must be true to use this function.
Capability | Effect
`can_signal_thread` | Can send stop or interrupt to threads

Parameters
Name | Type | Description
`thread` | `jthread` | The thread to stop.
`exception` | `jobject` | The asynchronous exception object.

Errors
This function returns either a universal error or one of the following errors
Error | Description
`JVMTI_ERROR_MUST_POSSESS_CAPABILITY` | The environment does not possess the capability `can_signal_thread`. Use `AddCapabilities`.
`JVMTI_ERROR_INVALID_THREAD` | `thread` is not a thread object.
`JVMTI_ERROR_THREAD_NOT_ALIVE` | `thread` is not live (has not been started or is now dead).
`JVMTI_ERROR_INVALID_OBJECT` | `exception` is not an object.

### Interrupt Thread

>     jvmtiError
>     InterruptThread(jvmtiEnv* env,
>                 jthread thread)

Interrupt the specified thread (similar to `java.lang.Thread.interrupt`).

Phase | Callback Safe | Position | Since
may only be called during the live phase | No | 8 | 1.0

Capabilities
Optional Functionality: might not be implemented for all virtual machines. The following capability (as returned by `GetCapabilities`) must be true to use this function.
Capability | Effect
`can_signal_thread` | Can send stop or interrupt to threads

Parameters
Name | Type | Description
`thread` | `jthread` | The thread to interrupt.

Errors
This function returns either a universal error or one of the following errors
Error | Description
`JVMTI_ERROR_MUST_POSSESS_CAPABILITY` | The environment does not possess the capability `can_signal_thread`. Use `AddCapabilities`.
`JVMTI_ERROR_INVALID_THREAD` | `thread` is not a thread object.
`JVMTI_ERROR_THREAD_NOT_ALIVE` | `thread` is not live (has not been started or is now dead).

### Get Thread Info

>     typedef struct {
>         char* name;
>         jint priority;
>         jboolean is_daemon;
>         jthreadGroup thread_group;
>         jobject context_class_loader;
>     } jvmtiThreadInfo;

>     jvmtiError
>     GetThreadInfo(jvmtiEnv* env,
>                 jthread thread,
>                 jvmtiThreadInfo* info_ptr)

Get thread information. The fields of the `jvmtiThreadInfo` structure are filled in with details of the specified thread.

Phase | Callback Safe | Position | Since
may only be called during the live phase | No | 9 | 1.0

Capabilities
Required Functionality

`jvmtiThreadInfo` - Thread information structure
Field | Type | Description
`name` | `char*` | The thread name, encoded as a modified UTF-8 string.
`priority` | `jint` | The thread priority. See the thread priority constants: `jvmtiThreadPriority`.
`is_daemon` | `jboolean` | Is this a daemon thread?
`thread_group` | `jthreadGroup` | The thread group to which this thread belongs. `NULL` if the thread has died.
`context_class_loader` | `jobject` | The context class loader associated with this thread.

Parameters
Name | Type | Description
`thread` | `jthread` | The thread to query. If `thread` is `NULL`, the current thread is used.
`info_ptr` | `jvmtiThreadInfo*` | On return, filled with information describing the specified thread. For JDK 1.1 implementations that don't recognize context class loaders, the `context_class_loader` field will be NULL. Agent passes a pointer to a `jvmtiThreadInfo`. On return, the `jvmtiThreadInfo` has been set. The pointer returned in the field `name` of `jvmtiThreadInfo` is a newly allocated array. The array should be freed with `Deallocate`. The object returned in the field `thread_group` of `jvmtiThreadInfo` is a JNI local reference and must be managed. The object returned in the field `context_class_loader` of `jvmtiThreadInfo` is a JNI local reference and must be managed.

Errors
This function returns either a universal error or one of the following errors
Error | Description
`JVMTI_ERROR_INVALID_THREAD` | `thread` is not a thread object.
`JVMTI_ERROR_NULL_POINTER` | `info_ptr` is `NULL`.

### Get Owned Monitor Info

>     jvmtiError
>     GetOwnedMonitorInfo(jvmtiEnv* env,
>                 jthread thread,
>                 jint* owned_monitor_count_ptr,
>                 jobject** owned_monitors_ptr)

Get information about the monitors owned by the specified thread.

Phase | Callback Safe | Position | Since
may only be called during the live phase | No | 10 | 1.0

Capabilities
Optional Functionality: might not be implemented for all virtual machines. The following capability (as returned by `GetCapabilities`) must be true to use this function.
Capability | Effect
`can_get_owned_monitor_info` | Can get information about ownership of monitors - `GetOwnedMonitorInfo`

Parameters
Name | Type | Description
`thread` | `jthread` | The thread to query. If `thread` is `NULL`, the current thread is used.
`owned_monitor_count_ptr` | `jint*` | The number of monitors returned. Agent passes a pointer to a `jint`. On return, the `jint` has been set.
`owned_monitors_ptr` | `jobject**` | The array of owned monitors. Agent passes a pointer to a `jobject*`. On return, the `jobject*` points to a newly allocated array of size `*owned_monitor_count_ptr`. The array should be freed with `Deallocate`. The objects returned by `owned_monitors_ptr` are JNI local references and must be managed.

Errors
This function returns either a universal error or one of the following errors
Error | Description
`JVMTI_ERROR_MUST_POSSESS_CAPABILITY` | The environment does not possess the capability `can_get_owned_monitor_info`. Use `AddCapabilities`.
`JVMTI_ERROR_INVALID_THREAD` | `thread` is not a thread object.
`JVMTI_ERROR_THREAD_NOT_ALIVE` | `thread` is not live (has not been started or is now dead).
`JVMTI_ERROR_NULL_POINTER` | `owned_monitor_count_ptr` is `NULL`.
`JVMTI_ERROR_NULL_POINTER` | `owned_monitors_ptr` is `NULL`.

### Get Owned Monitor Stack Depth Info

>     typedef struct {
>         jobject monitor;
>         jint stack_depth;
>     } jvmtiMonitorStackDepthInfo;

>     jvmtiError
>     GetOwnedMonitorStackDepthInfo(jvmtiEnv* env,
>                 jthread thread,
>                 jint* monitor_info_count_ptr,
>                 jvmtiMonitorStackDepthInfo** monitor_info_ptr)

Get information about the monitors owned by the specified thread and the depth of the stack frame which locked them.

Phase | Callback Safe | Position | Since
may only be called during the live phase | No | 153 | 1.1

Capabilities
Optional Functionality: might not be implemented for all virtual machines. The following capability (as returned by `GetCapabilities`) must be true to use this function.
Capability | Effect
`can_get_owned_monitor_stack_depth_info` | Can get information about owned monitors with stack depth - `GetOwnedMonitorStackDepthInfo`

`jvmtiMonitorStackDepthInfo` - Monitor stack depth information structure
Field | Type | Description
`monitor` | `jobject` | The owned monitor.
`stack_depth` | `jint` | The stack depth. Corresponds to the stack depth used in the Stack Frame functions. That is, zero is the current frame, one is the frame which called the current frame. And it is negative one if the implementation cannot determine the stack depth (e.g., for monitors acquired by JNI `MonitorEnter`).

Parameters
Name | Type | Description
`thread` | `jthread` | The thread to query. If `thread` is `NULL`, the current thread is used.
`monitor_info_count_ptr` | `jint*` | The number of monitors returned. Agent passes a pointer to a `jint`. On return, the `jint` has been set.
`monitor_info_ptr` | `jvmtiMonitorStackDepthInfo **` | The array of owned monitor depth information. Agent passes a pointer to a `jvmtiMonitorStackDepthInfo*`. On return, the `jvmtiMonitorStackDepthInfo*` points to a newly allocated array of size `*owned_monitor_depth_count_ptr`. The array should be freed with `Deallocate`. The objects returned in the field `monitor` of `jvmtiMonitorStackDepthInfo` are JNI local references and must be managed.

Errors
This function returns either a universal error or one of the following errors
Error | Description
`JVMTI_ERROR_MUST_POSSESS_CAPABILITY` | The environment does not possess the capability `can_get_owned_monitor_stack_depth_info`. Use `AddCapabilities`.
`JVMTI_ERROR_INVALID_THREAD` | `thread` is not a thread object.
`JVMTI_ERROR_THREAD_NOT_ALIVE` | `thread` is not live (has not been started or is now dead).
`JVMTI_ERROR_NULL_POINTER` | `monitor_info_count_ptr` is `NULL`.
`JVMTI_ERROR_NULL_POINTER` | `monitor_info_ptr` is `NULL`.

### Get Current Contended Monitor

>     jvmtiError
>     GetCurrentContendedMonitor(jvmtiEnv* env,
>                 jthread thread,
>                 jobject* monitor_ptr)

Get the object, if any, whose monitor the specified thread is waiting to enter or waiting to regain through `java.lang.Object.wait`.

Phase | Callback Safe | Position | Since
may only be called during the live phase | No | 11 | 1.0

Capabilities
Optional Functionality: might not be implemented for all virtual machines. The following capability (as returned by `GetCapabilities`) must be true to use this function.
Capability | Effect
`can_get_current_contended_monitor` | Can `GetCurrentContendedMonitor`

Parameters
Name | Type | Description
`thread` | `jthread` | The thread to query. If `thread` is `NULL`, the current thread is used.
`monitor_ptr` | `jobject*` | On return, filled with the current contended monitor, or NULL if there is none. Agent passes a pointer to a `jobject`. On return, the `jobject` has been set. The object returned by `monitor_ptr` is a JNI local reference and must be managed.

Errors
This function returns either a universal error or one of the following errors
Error | Description
`JVMTI_ERROR_MUST_POSSESS_CAPABILITY` | The environment does not possess the capability `can_get_current_contended_monitor`. Use `AddCapabilities`.
`JVMTI_ERROR_INVALID_THREAD` | `thread` is not a thread object.
`JVMTI_ERROR_THREAD_NOT_ALIVE` | `thread` is not live (has not been started or is now dead).
`JVMTI_ERROR_NULL_POINTER` | `monitor_ptr` is `NULL`.

### Agent Start Function

>     typedef void (JNICALL *jvmtiStartFunction)
>         (jvmtiEnv* jvmti_env,
>          JNIEnv* jni_env,
>          void* arg);
Agent supplied callback function. This function is the entry point for an agent thread started with `RunAgentThread`.
Parameters
Name | Type | Description
`jvmti_env` | `jvmtiEnv *` | The JVM TI environment.
`jni_env` | `JNIEnv *` | The JNI environment.
`arg` | `void *` | The `arg` parameter passed to `RunAgentThread`.

### Run Agent Thread

>     jvmtiError
>     RunAgentThread(jvmtiEnv* env,
>                 jthread thread,
>                 jvmtiStartFunction proc,
>                 const void* arg,
>                 jint priority)

Starts the execution of an agent thread. with the specified native function. The parameter `arg` is forwarded on to the start function (specified with `proc`) as its single argument. This function allows the creation of agent threads for handling communication with another process or for handling events without the need to load a special subclass of `java.lang.Thread` or implementer of `java.lang.Runnable`. Instead, the created thread can run entirely in native code. However, the created thread does require a newly created instance of `java.lang.Thread` (referenced by the argument `thread`) to which it will be associated. The thread object can be created with JNI calls.

The following common thread priorities are provided for your convenience:

> Thread Priority Constants
> Constant | Value | Description
> `JVMTI_THREAD_MIN_PRIORITY` | 1 | Minimum possible thread priority
> `JVMTI_THREAD_NORM_PRIORITY` | 5 | Normal thread priority
> `JVMTI_THREAD_MAX_PRIORITY` | 10 | Maximum possible thread priority

The new thread is started as a daemon thread with the specified `priority`. If enabled, a `ThreadStart` event will be sent.

Since the thread has been started, the thread will be live when this function returns, unless the thread has died immediately.

The thread group of the thread is ignored -- specifically, the thread is not added to the thread group and the thread is not seen on queries of the thread group at either the Java programming language or JVM TI levels.

The thread is not visible to Java programming language queries but is included in JVM TI queries (for example, `GetAllThreads` and `GetAllStackTraces`).

Upon execution of `proc`, the new thread will be attached to the VM--see the JNI documentation on Attaching to the VM.

Phase | Callback Safe | Position | Since
may only be called during the live phase | No | 12 | 1.0

Capabilities
Required Functionality

Parameters
Name | Type | Description
`thread` | `jthread` | The thread to run.
`proc` | `jvmtiStartFunction` | The start function.
`arg` | `const void *` | The argument to the start function. Agent passes in a pointer. If `arg` is `NULL`, `NULL` is passed to the start function.
`priority` | `jint` | The priority of the started thread. Any thread priority allowed by `java.lang.Thread.setPriority` can be used including those in `jvmtiThreadPriority`.

Errors
This function returns either a universal error or one of the following errors
Error | Description
`JVMTI_ERROR_INVALID_PRIORITY` | `priority` is less than `JVMTI_THREAD_MIN_PRIORITY` or greater than `JVMTI_THREAD_MAX_PRIORITY`
`JVMTI_ERROR_INVALID_THREAD` | `thread` is not a thread object.
`JVMTI_ERROR_NULL_POINTER` | `proc` is `NULL`.

### Set Thread Local Storage

>     jvmtiError
>     SetThreadLocalStorage(jvmtiEnv* env,
>                 jthread thread,
>                 const void* data)

The VM stores a pointer value associated with each environment-thread pair. This pointer value is called thread-local storage. This value is `NULL` unless set with this function. Agents can allocate memory in which they store thread specific information. By setting thread-local storage it can then be accessed with `GetThreadLocalStorage`.

This function is called by the agent to set the value of the JVM TI thread-local storage. JVM TI supplies to the agent a pointer-size thread-local storage that can be used to record per-thread information.

Phase | Callback Safe | Position | Since
may only be called during the start or the live phase | No | 103 | 1.0

Capabilities
Required Functionality

Parameters
Name | Type | Description
`thread` | `jthread` | Store to this thread. If `thread` is `NULL`, the current thread is used.
`data` | `const void *` | The value to be entered into the thread-local storage. Agent passes in a pointer. If `data` is `NULL`, value is set to `NULL`.

Errors
This function returns either a universal error or one of the following errors
Error | Description
`JVMTI_ERROR_INVALID_THREAD` | `thread` is not a thread object.
`JVMTI_ERROR_THREAD_NOT_ALIVE` | `thread` is not live (has not been started or is now dead).

### Get Thread Local Storage

>     jvmtiError
>     GetThreadLocalStorage(jvmtiEnv* env,
>                 jthread thread,
>                 void** data_ptr)

Called by the agent to get the value of the JVM TI thread-local storage.

Phase | Callback Safe | Position | Since
may only be called during the start or the live phase | No | 102 | 1.0

Capabilities
Required Functionality

Parameters
Name | Type | Description
`thread` | `jthread` | Retrieve from this thread. If `thread` is `NULL`, the current thread is used.
`data_ptr` | `void**` | Pointer through which the value of the thread local storage is returned. If thread-local storage has not been set with `SetThreadLocalStorage` the returned pointer is `NULL`.

Errors
This function returns either a universal error or one of the following errors
Error | Description
`JVMTI_ERROR_INVALID_THREAD` | `thread` is not a thread object.
`JVMTI_ERROR_THREAD_NOT_ALIVE` | `thread` is not live (has not been started or is now dead).
`JVMTI_ERROR_NULL_POINTER` | `data_ptr` is `NULL`.

## Thread Group

Thread Group functions:

- Get Top Thread Groups
- Get Thread Group Info
- Get Thread Group Children

Thread Group types:

- `jvmtiThreadGroupInfo` - Thread group information structure

### Get Top Thread Groups

>     jvmtiError
>     GetTopThreadGroups(jvmtiEnv* env,
>                 jint* group_count_ptr,
>                 jthreadGroup** groups_ptr)

Return all top-level (parentless) thread groups in the VM.

Phase | Callback Safe | Position | Since
may only be called during the live phase | No | 13 | 1.0

Capabilities
Required Functionality

Parameters
Name | Type | Description
`group_count_ptr` | `jint*` | On return, points to the number of top-level thread groups. Agent passes a pointer to a `jint`. On return, the `jint` has been set.
`groups_ptr` | `jthreadGroup**` | On return, refers to a pointer to the top-level thread group array. Agent passes a pointer to a `jthreadGroup*`. On return, the `jthreadGroup*` points to a newly allocated array of size `*group_count_ptr`. The array should be freed with `Deallocate`. The objects returned by `groups_ptr` are JNI local references and must be managed.

Errors
This function returns either a universal error or one of the following errors
Error | Description
`JVMTI_ERROR_NULL_POINTER` | `group_count_ptr` is `NULL`.
`JVMTI_ERROR_NULL_POINTER` | `groups_ptr` is `NULL`.

### Get Thread Group Info

>     typedef struct {
>         jthreadGroup parent;
>         char* name;
>         jint max_priority;
>         jboolean is_daemon;
>     } jvmtiThreadGroupInfo;

>     jvmtiError
>     GetThreadGroupInfo(jvmtiEnv* env,
>                 jthreadGroup group,
>                 jvmtiThreadGroupInfo* info_ptr)

Get information about the thread group. The fields of the `jvmtiThreadGroupInfo` structure are filled in with details of the specified thread group.

Phase | Callback Safe | Position | Since
may only be called during the live phase | No | 14 | 1.0

Capabilities
Required Functionality

`jvmtiThreadGroupInfo` - Thread group information structure
Field | Type | Description
`parent` | `jthreadGroup` | The parent thread group.
`name` | `char*` | The thread group's name, encoded as a modified UTF-8 string.
`max_priority` | `jint` | The maximum priority for this thread group.
`is_daemon` | `jboolean` | Is this a daemon thread group?

Parameters
Name | Type | Description
`group` | `jthreadGroup` | The thread group to query.
`info_ptr` | `jvmtiThreadGroupInfo*` | On return, filled with information describing the specified thread group. Agent passes a pointer to a `jvmtiThreadGroupInfo`. On return, the `jvmtiThreadGroupInfo` has been set. The object returned in the field `parent` of `jvmtiThreadGroupInfo` is a JNI local reference and must be managed. The pointer returned in the field `name` of `jvmtiThreadGroupInfo` is a newly allocated array. The array should be freed with `Deallocate`.

Errors
This function returns either a universal error or one of the following errors
Error | Description
`JVMTI_ERROR_INVALID_THREAD_GROUP` | `group` is not a thread group object.
`JVMTI_ERROR_NULL_POINTER` | `info_ptr` is `NULL`.

### Get Thread Group Children

>     jvmtiError
>     GetThreadGroupChildren(jvmtiEnv* env,
>                 jthreadGroup group,
>                 jint* thread_count_ptr,
>                 jthread** threads_ptr,
>                 jint* group_count_ptr,
>                 jthreadGroup** groups_ptr)

Get the live threads and active subgroups in this thread group.

Phase | Callback Safe | Position | Since
may only be called during the live phase | No | 15 | 1.0

Capabilities
Required Functionality

Parameters
Name | Type | Description
`group` | `jthreadGroup` | The group to query.
`thread_count_ptr` | `jint*` | On return, points to the number of live threads in this thread group. Agent passes a pointer to a `jint`. On return, the `jint` has been set.
`threads_ptr` | `jthread**` | On return, points to an array of the live threads in this thread group. Agent passes a pointer to a `jthread*`. On return, the `jthread*` points to a newly allocated array of size `*thread_count_ptr`. The array should be freed with `Deallocate`. The objects returned by `threads_ptr` are JNI local references and must be managed.
`group_count_ptr` | `jint*` | On return, points to the number of active child thread groups Agent passes a pointer to a `jint`. On return, the `jint` has been set.
`groups_ptr` | `jthreadGroup**` | On return, points to an array of the active child thread groups. Agent passes a pointer to a `jthreadGroup*`. On return, the `jthreadGroup*` points to a newly allocated array of size `*group_count_ptr`. The array should be freed with `Deallocate`. The objects returned by `groups_ptr` are JNI local references and must be managed.

Errors
This function returns either a universal error or one of the following errors
Error | Description
`JVMTI_ERROR_INVALID_THREAD_GROUP` | `group` is not a thread group object.
`JVMTI_ERROR_NULL_POINTER` | `thread_count_ptr` is `NULL`.
`JVMTI_ERROR_NULL_POINTER` | `threads_ptr` is `NULL`.
`JVMTI_ERROR_NULL_POINTER` | `group_count_ptr` is `NULL`.
`JVMTI_ERROR_NULL_POINTER` | `groups_ptr` is `NULL`.

## Stack Frame

Stack Frame functions:

- Get Stack Trace
- Get All Stack Traces
- Get Thread List Stack Traces
- Get Frame Count
- Pop Frame
- Get Frame Location
- Notify Frame Pop

Stack Frame types:

- `jvmtiFrameInfo` - Stack frame information structure
- `jvmtiStackInfo` - Stack information structure

These functions provide information about the stack of a thread. Stack frames are referenced by depth. The frame at depth zero is the current frame.

Stack frames are as described in the Frames section of the Java Virtual Machine Specification. That is, they correspond to method invocations (including native methods) but do not correspond to platform native or VM internal frames.

A JVM TI implementation may use method invocations to launch a thread and the corresponding frames may be included in the stack as presented by these functions -- that is, there may be frames shown deeper than `main()` and `run()`. However this presentation must be consistent across all JVM TI functionality which uses stack frames or stack depth.

#### Stack frame information structure

Information about a stack frame is returned in this structure.

>     typedef struct {
>         jmethodID method;
>         jlocation location;
>     } jvmtiFrameInfo;

> `jvmtiFrameInfo` - Stack frame information structure
> Field | Type | Description
> `method` | `jmethodID` | The method executing in this frame.
> `location` | `jlocation` | The index of the instruction executing in this frame. `-1` if the frame is executing a native method.

#### Stack information structure

Information about a set of stack frames is returned in this structure.

>     typedef struct {
>         jthread thread;
>         jint state;
>         jvmtiFrameInfo* frame_buffer;
>         jint frame_count;
>     } jvmtiStackInfo;

> `jvmtiStackInfo` - Stack information structure
> Field | Type | Description
> `thread` | `jthread` | On return, the thread traced.
> `state` | `jint` | On return, the thread state. See `GetThreadState`.
> `frame_buffer` | `jvmtiFrameInfo *` | On return, this agent allocated buffer is filled with stack frame information.
> `frame_count` | `jint` | On return, the number of records filled into `frame_buffer`. This will be min(`max_frame_count`, stackDepth).

### Get Stack Trace

>     jvmtiError
>     GetStackTrace(jvmtiEnv* env,
>                 jthread thread,
>                 jint start_depth,
>                 jint max_frame_count,
>                 jvmtiFrameInfo* frame_buffer,
>                 jint* count_ptr)

Get information about the stack of a thread. If `max_frame_count` is less than the depth of the stack, the `max_frame_count` topmost frames are returned, otherwise the entire stack is returned. The topmost frames, those most recently invoked, are at the beginning of the returned buffer.

The following example causes up to five of the topmost frames to be returned and (if there are any frames) the currently executing method name to be printed.

>     jvmtiFrameInfo frames[5];
>     jint count;
>     jvmtiError err;

>     err = (*jvmti)->GetStackTrace(jvmti, aThread, 0, 5,
>                                    &frames, &count);
>     if (err == JVMTI_ERROR_NONE && count >= 1) {
>        char *methodName;
>        err = (*jvmti)->GetMethodName(jvmti, frames[0].method,
>                            &methodName, NULL);
>        if (err == JVMTI_ERROR_NONE) {
>           printf("Executing method: %s", methodName);
>        }
>     }

The `thread` need not be suspended to call this function.

The `GetLineNumberTable` function can be used to map locations to line numbers. Note that this mapping can be done lazily.

Phase | Callback Safe | Position | Since
may only be called during the live phase | No | 104 | 1.0

Capabilities
Required Functionality

Parameters
Name | Type | Description
`thread` | `jthread` | Fetch the stack trace of this thread. If `thread` is `NULL`, the current thread is used.
`start_depth` | `jint` | Begin retrieving frames at this depth. If non-negative, count from the current frame, the first frame retrieved is at depth `start_depth`. For example, if zero, start from the current frame; if one, start from the caller of the current frame; if two, start from the caller of the caller of the current frame; and so on. If negative, count from below the oldest frame, the first frame retrieved is at depth stackDepth`+ start_depth`, where stackDepth is the count of frames on the stack. For example, if negative one, only the oldest frame is retrieved; if negative two, start from the frame called by the oldest frame.
`max_frame_count` | `jint` | The maximum number of `jvmtiFrameInfo` records to retrieve.
`frame_buffer` | `jvmtiFrameInfo *` | On return, this agent allocated buffer is filled with stack frame information. Agent passes an array large enough to hold `max_frame_count` elements of `jvmtiFrameInfo`. The incoming values of the elements of the array are ignored. On return, `*count_ptr` of the elements are set.
`count_ptr` | `jint*` | On return, points to the number of records filled in. For non-negative `start_depth`, this will be min(`max_frame_count`, stackDepth`- start_depth`). For negative `start_depth`, this will be min(`max_frame_count`, `-start_depth`). Agent passes a pointer to a `jint`. On return, the `jint` has been set.

Errors
This function returns either a universal error or one of the following errors
Error | Description
`JVMTI_ERROR_ILLEGAL_ARGUMENT` | `start_depth` is positive and greater than or equal to stackDepth. Or `start_depth` is negative and less than -stackDepth.
`JVMTI_ERROR_INVALID_THREAD` | `thread` is not a thread object.
`JVMTI_ERROR_THREAD_NOT_ALIVE` | `thread` is not live (has not been started or is now dead).
`JVMTI_ERROR_ILLEGAL_ARGUMENT` | `max_frame_count` is less than `0`.
`JVMTI_ERROR_NULL_POINTER` | `frame_buffer` is `NULL`.
`JVMTI_ERROR_NULL_POINTER` | `count_ptr` is `NULL`.

### Get All Stack Traces

>     jvmtiError
>     GetAllStackTraces(jvmtiEnv* env,
>                 jint max_frame_count,
>                 jvmtiStackInfo** stack_info_ptr,
>                 jint* thread_count_ptr)

Get information about the stacks of all live threads (including agent threads). If `max_frame_count` is less than the depth of a stack, the `max_frame_count` topmost frames are returned for that thread, otherwise the entire stack is returned. The topmost frames, those most recently invoked, are at the beginning of the returned buffer.

All stacks are collected simultaneously, that is, no changes will occur to the thread state or stacks between the sampling of one thread and the next. The threads need not be suspended.

>     jvmtiStackInfo *stack_info;
>     jint thread_count;
>     int ti;
>     jvmtiError err;

>     err = (*jvmti)->GetAllStackTraces(jvmti, MAX_FRAMES, &stack_info, &thread_count);
>     if (err != JVMTI_ERROR_NONE) {
>        ...
>     }
>     for (ti = 0; ti < thread_count; ++ti) {
>        jvmtiStackInfo *infop = &stack_info[ti];
>        jthread thread = infop->thread;
>        jint state = infop->state;
>        jvmtiFrameInfo *frames = infop->frame_buffer;
>        int fi;

>        myThreadAndStatePrinter(thread, state);
>        for (fi = 0; fi < infop->frame_count; fi++) {
>           myFramePrinter(frames[fi].method, frames[fi].location);
>        }
>     }
>     /* this one Deallocate call frees all data allocated by GetAllStackTraces */
>     err = (*jvmti)->Deallocate(jvmti, stack_info);

Phase | Callback Safe | Position | Since
may only be called during the live phase | No | 100 | 1.0

Capabilities
Required Functionality

Parameters
Name | Type | Description
`max_frame_count` | `jint` | The maximum number of `jvmtiFrameInfo` records to retrieve per thread.
`stack_info_ptr` | `jvmtiStackInfo **` | On return, this buffer is filled with stack information for each thread. The number of `jvmtiStackInfo` records is determined by `thread_count_ptr`. Note that this buffer is allocated to include the `jvmtiFrameInfo` buffers pointed to by `jvmtiStackInfo.frame_buffer`. These buffers must not be separately deallocated. Agent passes a pointer to a `jvmtiStackInfo*`. On return, the `jvmtiStackInfo*` points to a newly allocated array. The array should be freed with `Deallocate`. The objects returned in the field `thread` of `jvmtiStackInfo` are JNI local references and must be managed.
`thread_count_ptr` | `jint*` | The number of threads traced. Agent passes a pointer to a `jint`. On return, the `jint` has been set.

Errors
This function returns either a universal error or one of the following errors
Error | Description
`JVMTI_ERROR_ILLEGAL_ARGUMENT` | `max_frame_count` is less than `0`.
`JVMTI_ERROR_NULL_POINTER` | `stack_info_ptr` is `NULL`.
`JVMTI_ERROR_NULL_POINTER` | `thread_count_ptr` is `NULL`.

### Get Thread List Stack Traces

>     jvmtiError
>     GetThreadListStackTraces(jvmtiEnv* env,
>                 jint thread_count,
>                 const jthread* thread_list,
>                 jint max_frame_count,
>                 jvmtiStackInfo** stack_info_ptr)

Get information about the stacks of the supplied threads. If `max_frame_count` is less than the depth of a stack, the `max_frame_count` topmost frames are returned for that thread, otherwise the entire stack is returned. The topmost frames, those most recently invoked, are at the beginning of the returned buffer.

All stacks are collected simultaneously, that is, no changes will occur to the thread state or stacks between the sampling one thread and the next. The threads need not be suspended.

If a thread has not yet started or terminates before the stack information is collected, a zero length stack (`jvmtiStackInfo.frame_count` will be zero) will be returned and the thread `jvmtiStackInfo.state` can be checked.

See the example for the similar function `GetAllStackTraces`.

Phase | Callback Safe | Position | Since
may only be called during the live phase | No | 101 | 1.0

Capabilities
Required Functionality

Parameters
Name | Type | Description
`thread_count` | `jint` | The number of threads to trace.
`thread_list` | `const jthread*` | The list of threads to trace. Agent passes in an array of `thread_count` elements of `jthread`.
`max_frame_count` | `jint` | The maximum number of `jvmtiFrameInfo` records to retrieve per thread.
`stack_info_ptr` | `jvmtiStackInfo **` | On return, this buffer is filled with stack information for each thread. The number of `jvmtiStackInfo` records is determined by `thread_count`. Note that this buffer is allocated to include the `jvmtiFrameInfo` buffers pointed to by `jvmtiStackInfo.frame_buffer`. These buffers must not be separately deallocated. Agent passes a pointer to a `jvmtiStackInfo*`. On return, the `jvmtiStackInfo*` points to a newly allocated array of size `*thread_count`. The array should be freed with `Deallocate`. The objects returned in the field `thread` of `jvmtiStackInfo` are JNI local references and must be managed.

Errors
This function returns either a universal error or one of the following errors
Error | Description
`JVMTI_ERROR_INVALID_THREAD` | An element in `thread_list` is not a thread object.
`JVMTI_ERROR_ILLEGAL_ARGUMENT` | `thread_count` is less than `0`.
`JVMTI_ERROR_NULL_POINTER` | `thread_list` is `NULL`.
`JVMTI_ERROR_ILLEGAL_ARGUMENT` | `max_frame_count` is less than `0`.
`JVMTI_ERROR_NULL_POINTER` | `stack_info_ptr` is `NULL`.

### Get Frame Count

>     jvmtiError
>     GetFrameCount(jvmtiEnv* env,
>                 jthread thread,
>                 jint* count_ptr)

Get the number of frames currently in the specified thread's call stack.

If this function is called for a thread actively executing bytecodes (for example, not the current thread and not suspended), the information returned is transient.

Phase | Callback Safe | Position | Since
may only be called during the live phase | No | 16 | 1.0

Capabilities
Required Functionality

Parameters
Name | Type | Description
`thread` | `jthread` | The thread to query. If `thread` is `NULL`, the current thread is used.
`count_ptr` | `jint*` | On return, points to the number of frames in the call stack. Agent passes a pointer to a `jint`. On return, the `jint` has been set.

Errors
This function returns either a universal error or one of the following errors
Error | Description
`JVMTI_ERROR_INVALID_THREAD` | `thread` is not a thread object.
`JVMTI_ERROR_THREAD_NOT_ALIVE` | `thread` is not live (has not been started or is now dead).
`JVMTI_ERROR_NULL_POINTER` | `count_ptr` is `NULL`.

### Pop Frame

>     jvmtiError
>     PopFrame(jvmtiEnv* env,
>                 jthread thread)

Pop the current frame of `thread`'s stack. Popping a frame takes you to the previous frame. When the thread is resumed, the execution state of the thread is reset to the state immediately before the called method was invoked. That is (using the Java Virtual Machine Specification terminology):

- the current frame is discarded as the previous frame becomes the current one
- the operand stack is restored--the argument values are added back and if the invoke was not `invokestatic`, `objectref` is added back as well
- the Java virtual machine PC is restored to the opcode of the invoke instruction

Note however, that any changes to the arguments, which occurred in the called method, remain; when execution continues, the first instruction to execute will be the invoke.

Between calling `PopFrame` and resuming the thread the state of the stack is undefined. To pop frames beyond the first, these three steps must be repeated:

- suspend the thread via an event (step, breakpoint, ...)
- call `PopFrame`
- resume the thread

A lock acquired by calling the called method (if it is a `synchronized` method) and locks acquired by entering `synchronized` blocks within the called method are released. Note: this does not apply to native locks or `java.util.concurrent.locks` locks.

Finally blocks are not executed.

Changes to global state are not addressed and thus remain changed.

The specified thread must be suspended (which implies it cannot be the current thread).

Both the called method and calling method must be non-native Java programming language methods.

No JVM TI events are generated by this function.

Phase | Callback Safe | Position | Since
may only be called during the live phase | No | 80 | 1.0

Capabilities
Optional Functionality: might not be implemented for all virtual machines. The following capability (as returned by `GetCapabilities`) must be true to use this function.
Capability | Effect
`can_pop_frame` | Can pop frames off the stack - `PopFrame`

Parameters
Name | Type | Description
`thread` | `jthread` | The thread whose current frame is to be popped.

Errors
This function returns either a universal error or one of the following errors
Error | Description
`JVMTI_ERROR_MUST_POSSESS_CAPABILITY` | The environment does not possess the capability `can_pop_frame`. Use `AddCapabilities`.
`JVMTI_ERROR_OPAQUE_FRAME` | Called or calling method is a native method. The implementation is unable to pop this frame.
`JVMTI_ERROR_THREAD_NOT_SUSPENDED` | Thread was not suspended.
`JVMTI_ERROR_NO_MORE_FRAMES` | There are less than two stack frames on the call stack.
`JVMTI_ERROR_INVALID_THREAD` | `thread` is not a thread object.
`JVMTI_ERROR_THREAD_NOT_ALIVE` | `thread` is not live (has not been started or is now dead).

### Get Frame Location

>     jvmtiError
>     GetFrameLocation(jvmtiEnv* env,
>                 jthread thread,
>                 jint depth,
>                 jmethodID* method_ptr,
>                 jlocation* location_ptr)

For a Java programming language frame, return the location of the instruction currently executing.

Phase | Callback Safe | Position | Since
may only be called during the live phase | No | 19 | 1.0

Capabilities
Required Functionality

Parameters
Name | Type | Description
`thread` | `jthread` | The thread of the frame to query. If `thread` is `NULL`, the current thread is used.
`depth` | `jint` | The depth of the frame to query.
`method_ptr` | `jmethodID*` | On return, points to the method for the current location. Agent passes a pointer to a `jmethodID`. On return, the `jmethodID` has been set.
`location_ptr` | `jlocation*` | On return, points to the index of the currently executing instruction. Is set to `-1` if the frame is executing a native method. Agent passes a pointer to a `jlocation`. On return, the `jlocation` has been set.

Errors
This function returns either a universal error or one of the following errors
Error | Description
`JVMTI_ERROR_INVALID_THREAD` | `thread` is not a thread object.
`JVMTI_ERROR_THREAD_NOT_ALIVE` | `thread` is not live (has not been started or is now dead).
`JVMTI_ERROR_ILLEGAL_ARGUMENT` | `depth` is less than zero.
`JVMTI_ERROR_NO_MORE_FRAMES` | There are no stack frames at the specified `depth`.
`JVMTI_ERROR_NULL_POINTER` | `method_ptr` is `NULL`.
`JVMTI_ERROR_NULL_POINTER` | `location_ptr` is `NULL`.

### Notify Frame Pop

>     jvmtiError
>     NotifyFramePop(jvmtiEnv* env,
>                 jthread thread,
>                 jint depth)

When the frame that is currently at `depth` is popped from the stack, generate a `FramePop` event. See the `FramePop` event for details. Only frames corresponding to non-native Java programming language methods can receive notification.

The specified thread must either be the current thread or the thread must be suspended.

Phase | Callback Safe | Position | Since
may only be called during the live phase | No | 20 | 1.0

Capabilities
Optional Functionality: might not be implemented for all virtual machines. The following capability (as returned by `GetCapabilities`) must be true to use this function.
Capability | Effect
`can_generate_frame_pop_events` | Can set and thus get `FramePop` events

Parameters
Name | Type | Description
`thread` | `jthread` | The thread of the frame for which the frame pop event will be generated. If `thread` is `NULL`, the current thread is used.
`depth` | `jint` | The depth of the frame for which the frame pop event will be generated.

Errors
This function returns either a universal error or one of the following errors
Error | Description
`JVMTI_ERROR_MUST_POSSESS_CAPABILITY` | The environment does not possess the capability `can_generate_frame_pop_events`. Use `AddCapabilities`.
`JVMTI_ERROR_OPAQUE_FRAME` | The frame at `depth` is executing a native method.
`JVMTI_ERROR_THREAD_NOT_SUSPENDED` | Thread was not suspended and was not the current thread.
`JVMTI_ERROR_INVALID_THREAD` | `thread` is not a thread object.
`JVMTI_ERROR_THREAD_NOT_ALIVE` | `thread` is not live (has not been started or is now dead).
`JVMTI_ERROR_ILLEGAL_ARGUMENT` | `depth` is less than zero.
`JVMTI_ERROR_NO_MORE_FRAMES` | There are no stack frames at the specified `depth`.

## Force Early Return

Force Early Return functions:

- Force Early Return - Object
- Force Early Return - Int
- Force Early Return - Long
- Force Early Return - Float
- Force Early Return - Double
- Force Early Return - Void

These functions allow an agent to force a method to return at any point during its execution. The method which will return early is referred to as the called method. The called method is the current method (as defined by the Frames section of the Java Virtual Machine Specification) for the specified thread at the time the function is called.

The specified thread must be suspended or must be the current thread. The return occurs when execution of Java programming language code is resumed on this thread. Between calling one of these functions and resumption of thread execution, the state of the stack is undefined.

No further instructions are executed in the called method. Specifically, finally blocks are not executed. Note: this can cause inconsistent states in the application.

A lock acquired by calling the called method (if it is a `synchronized` method) and locks acquired by entering `synchronized` blocks within the called method are released. Note: this does not apply to native locks or `java.util.concurrent.locks` locks.

Events, such as `MethodExit`, are generated as they would be in a normal return.

The called method must be a non-native Java programming language method. Forcing return on a thread with only one frame on the stack causes the thread to exit when resumed.

### Force Early Return - Object

>     jvmtiError
>     ForceEarlyReturnObject(jvmtiEnv* env,
>                 jthread thread,
>                 jobject value)

This function can be used to return from a method whose result type is `Object` or a subclass of `Object`.

Phase | Callback Safe | Position | Since
may only be called during the live phase | No | 81 | 1.1

Capabilities
Optional Functionality: might not be implemented for all virtual machines. The following capability (as returned by `GetCapabilities`) must be true to use this function.
Capability | Effect
`can_force_early_return` | Can return early from a method, as described in the Force Early Return category.

Parameters
Name | Type | Description
`thread` | `jthread` | The thread whose current frame is to return early. If `thread` is `NULL`, the current thread is used.
`value` | `jobject` | The return value for the called frame. An object or `NULL`.

Errors
This function returns either a universal error or one of the following errors
Error | Description
`JVMTI_ERROR_MUST_POSSESS_CAPABILITY` | The environment does not possess the capability `can_force_early_return`. Use `AddCapabilities`.
`JVMTI_ERROR_OPAQUE_FRAME` | Attempted to return early from a frame corresponding to a native method. Or the implementation is unable to provide this functionality on this frame.
`JVMTI_ERROR_TYPE_MISMATCH` | The result type of the called method is not `Object` or a subclass of `Object`.
`JVMTI_ERROR_TYPE_MISMATCH` | The supplied `value` is not compatible with the result type of the called method.
`JVMTI_ERROR_THREAD_NOT_SUSPENDED` | Thread was not the current thread and was not suspended.
`JVMTI_ERROR_NO_MORE_FRAMES` | There are no more frames on the call stack.
`JVMTI_ERROR_INVALID_THREAD` | `thread` is not a thread object.
`JVMTI_ERROR_THREAD_NOT_ALIVE` | `thread` is not live (has not been started or is now dead).
`JVMTI_ERROR_INVALID_OBJECT` | `value` is not an object.

### Force Early Return - Int

>     jvmtiError
>     ForceEarlyReturnInt(jvmtiEnv* env,
>                 jthread thread,
>                 jint value)

This function can be used to return from a method whose result type is `int`, `short`, `char`, `byte`, or `boolean`.

Phase | Callback Safe | Position | Since
may only be called during the live phase | No | 82 | 1.1

Capabilities
Optional Functionality: might not be implemented for all virtual machines. The following capability (as returned by `GetCapabilities`) must be true to use this function.
Capability | Effect
`can_force_early_return` | Can return early from a method, as described in the Force Early Return category.

Parameters
Name | Type | Description
`thread` | `jthread` | The thread whose current frame is to return early. If `thread` is `NULL`, the current thread is used.
`value` | `jint` | The return value for the called frame.

Errors
This function returns either a universal error or one of the following errors
Error | Description
`JVMTI_ERROR_MUST_POSSESS_CAPABILITY` | The environment does not possess the capability `can_force_early_return`. Use `AddCapabilities`.
`JVMTI_ERROR_OPAQUE_FRAME` | Attempted to return early from a frame corresponding to a native method. Or the implementation is unable to provide this functionality on this frame.
`JVMTI_ERROR_TYPE_MISMATCH` | The result type of the called method is not `int`, `short`, `char`, `byte`, or `boolean`.
`JVMTI_ERROR_THREAD_NOT_SUSPENDED` | Thread was not the current thread and was not suspended.
`JVMTI_ERROR_NO_MORE_FRAMES` | There are no frames on the call stack.
`JVMTI_ERROR_INVALID_THREAD` | `thread` is not a thread object.
`JVMTI_ERROR_THREAD_NOT_ALIVE` | `thread` is not live (has not been started or is now dead).

### Force Early Return - Long

>     jvmtiError
>     ForceEarlyReturnLong(jvmtiEnv* env,
>                 jthread thread,
>                 jlong value)

This function can be used to return from a method whose result type is `long`.

Phase | Callback Safe | Position | Since
may only be called during the live phase | No | 83 | 1.1

Capabilities
Optional Functionality: might not be implemented for all virtual machines. The following capability (as returned by `GetCapabilities`) must be true to use this function.
Capability | Effect
`can_force_early_return` | Can return early from a method, as described in the Force Early Return category.

Parameters
Name | Type | Description
`thread` | `jthread` | The thread whose current frame is to return early. If `thread` is `NULL`, the current thread is used.
`value` | `jlong` | The return value for the called frame.

Errors
This function returns either a universal error or one of the following errors
Error | Description
`JVMTI_ERROR_MUST_POSSESS_CAPABILITY` | The environment does not possess the capability `can_force_early_return`. Use `AddCapabilities`.
`JVMTI_ERROR_OPAQUE_FRAME` | Attempted to return early from a frame corresponding to a native method. Or the implementation is unable to provide this functionality on this frame.
`JVMTI_ERROR_TYPE_MISMATCH` | The result type of the called method is not `long`.
`JVMTI_ERROR_THREAD_NOT_SUSPENDED` | Thread was not the current thread and was not suspended.
`JVMTI_ERROR_NO_MORE_FRAMES` | There are no frames on the call stack.
`JVMTI_ERROR_INVALID_THREAD` | `thread` is not a thread object.
`JVMTI_ERROR_THREAD_NOT_ALIVE` | `thread` is not live (has not been started or is now dead).

### Force Early Return - Float

>     jvmtiError
>     ForceEarlyReturnFloat(jvmtiEnv* env,
>                 jthread thread,
>                 jfloat value)

This function can be used to return from a method whose result type is `float`.

Phase | Callback Safe | Position | Since
may only be called during the live phase | No | 84 | 1.1

Capabilities
Optional Functionality: might not be implemented for all virtual machines. The following capability (as returned by `GetCapabilities`) must be true to use this function.
Capability | Effect
`can_force_early_return` | Can return early from a method, as described in the Force Early Return category.

Parameters
Name | Type | Description
`thread` | `jthread` | The thread whose current frame is to return early. If `thread` is `NULL`, the current thread is used.
`value` | `jfloat` | The return value for the called frame.

Errors
This function returns either a universal error or one of the following errors
Error | Description
`JVMTI_ERROR_MUST_POSSESS_CAPABILITY` | The environment does not possess the capability `can_force_early_return`. Use `AddCapabilities`.
`JVMTI_ERROR_OPAQUE_FRAME` | Attempted to return early from a frame corresponding to a native method. Or the implementation is unable to provide this functionality on this frame.
`JVMTI_ERROR_TYPE_MISMATCH` | The result type of the called method is not `float`.
`JVMTI_ERROR_THREAD_NOT_SUSPENDED` | Thread was not the current thread and was not suspended.
`JVMTI_ERROR_NO_MORE_FRAMES` | There are no frames on the call stack.
`JVMTI_ERROR_INVALID_THREAD` | `thread` is not a thread object.
`JVMTI_ERROR_THREAD_NOT_ALIVE` | `thread` is not live (has not been started or is now dead).

### Force Early Return - Double

>     jvmtiError
>     ForceEarlyReturnDouble(jvmtiEnv* env,
>                 jthread thread,
>                 jdouble value)

This function can be used to return from a method whose result type is `double`.

Phase | Callback Safe | Position | Since
may only be called during the live phase | No | 85 | 1.1

Capabilities
Optional Functionality: might not be implemented for all virtual machines. The following capability (as returned by `GetCapabilities`) must be true to use this function.
Capability | Effect
`can_force_early_return` | Can return early from a method, as described in the Force Early Return category.

Parameters
Name | Type | Description
`thread` | `jthread` | The thread whose current frame is to return early. If `thread` is `NULL`, the current thread is used.
`value` | `jdouble` | The return value for the called frame.

Errors
This function returns either a universal error or one of the following errors
Error | Description
`JVMTI_ERROR_MUST_POSSESS_CAPABILITY` | The environment does not possess the capability `can_force_early_return`. Use `AddCapabilities`.
`JVMTI_ERROR_OPAQUE_FRAME` | Attempted to return early from a frame corresponding to a native method. Or the implementation is unable to provide this functionality on this frame.
`JVMTI_ERROR_TYPE_MISMATCH` | The result type of the called method is not `double`.
`JVMTI_ERROR_THREAD_NOT_SUSPENDED` | Thread was not the current thread and was not suspended.
`JVMTI_ERROR_NO_MORE_FRAMES` | There are no frames on the call stack.
`JVMTI_ERROR_INVALID_THREAD` | `thread` is not a thread object.
`JVMTI_ERROR_THREAD_NOT_ALIVE` | `thread` is not live (has not been started or is now dead).

### Force Early Return - Void

>     jvmtiError
>     ForceEarlyReturnVoid(jvmtiEnv* env,
>                 jthread thread)

This function can be used to return from a method with no result type. That is, the called method must be declared `void`.

Phase | Callback Safe | Position | Since
may only be called during the live phase | No | 86 | 1.1

Capabilities
Optional Functionality: might not be implemented for all virtual machines. The following capability (as returned by `GetCapabilities`) must be true to use this function.
Capability | Effect
`can_force_early_return` | Can return early from a method, as described in the Force Early Return category.

Parameters
Name | Type | Description
`thread` | `jthread` | The thread whose current frame is to return early. If `thread` is `NULL`, the current thread is used.

Errors
This function returns either a universal error or one of the following errors
Error | Description
`JVMTI_ERROR_MUST_POSSESS_CAPABILITY` | The environment does not possess the capability `can_force_early_return`. Use `AddCapabilities`.
`JVMTI_ERROR_OPAQUE_FRAME` | Attempted to return early from a frame corresponding to a native method. Or the implementation is unable to provide this functionality on this frame.
`JVMTI_ERROR_TYPE_MISMATCH` | The called method has a result type.
`JVMTI_ERROR_THREAD_NOT_SUSPENDED` | Thread was not the current thread and was not suspended.
`JVMTI_ERROR_NO_MORE_FRAMES` | There are no frames on the call stack.
`JVMTI_ERROR_INVALID_THREAD` | `thread` is not a thread object.
`JVMTI_ERROR_THREAD_NOT_ALIVE` | `thread` is not live (has not been started or is now dead).

## Heap

Heap functions:

- Follow References
- Iterate Through Heap
- Get Tag
- Set Tag
- Get Objects With Tags
- Force Garbage Collection

Heap function types:

- Heap Iteration Callback
- Heap Reference Callback
- Primitive Field Callback
- Array Primitive Value Callback
- String Primitive Value Callback
- reserved for future use Callback

Heap types:

- `jvmtiHeapReferenceKind` - Heap Reference Enumeration
- `jvmtiPrimitiveType` - Primitive Type Enumeration
- `jvmtiHeapReferenceInfoField` - Reference information structure for Field references
- `jvmtiHeapReferenceInfoArray` - Reference information structure for Array references
- `jvmtiHeapReferenceInfoConstantPool` - Reference information structure for Constant Pool references
- `jvmtiHeapReferenceInfoStackLocal` - Reference information structure for Local Variable references
- `jvmtiHeapReferenceInfoJniLocal` - Reference information structure for JNI local references
- `jvmtiHeapReferenceInfoReserved` - Reference information structure for Other references
- `jvmtiHeapReferenceInfo` - Reference information structure
- `jvmtiHeapCallbacks` - Heap callback function structure

Heap flags and constants:

- Heap Filter Flags
- Heap Visit Control Flags

These functions are used to analyze the heap. Functionality includes the ability to view the objects in the heap and to tag these objects.

#### Object Tags

A tag is a value associated with an object. Tags are explicitly set by the agent using the `SetTag` function or by callback functions such as `jvmtiHeapIterationCallback`.

Tags are local to the environment; that is, the tags of one environment are not visible in another.

Tags are `jlong` values which can be used simply to mark an object or to store a pointer to more detailed information. Objects which have not been tagged have a tag of zero. Setting a tag to zero makes the object untagged.

#### Heap Callback Functions

Heap functions which iterate through the heap and recursively follow object references use agent supplied callback functions to deliver the information.

These heap callback functions must adhere to the following restrictions -- These callbacks must not use JNI functions. These callbacks must not use JVM TI functions except callback safe functions which specifically allow such use (see the raw monitor, memory management, and environment local storage functions).

An implementation may invoke a callback on an internal thread or the thread which called the iteration function. Heap callbacks are single threaded -- no more than one callback will be invoked at a time.

The Heap Filter Flags can be used to prevent reporting based on the tag status of an object or its class. If no flags are set (the `jint` is zero), objects will not be filtered out.

> Heap Filter Flags
> Constant | Value | Description
> `JVMTI_HEAP_FILTER_TAGGED` | 0x4 | Filter out tagged objects. Objects which are tagged are not included.
> `JVMTI_HEAP_FILTER_UNTAGGED` | 0x8 | Filter out untagged objects. Objects which are not tagged are not included.
> `JVMTI_HEAP_FILTER_CLASS_TAGGED` | 0x10 | Filter out objects with tagged classes. Objects whose class is tagged are not included.
> `JVMTI_HEAP_FILTER_CLASS_UNTAGGED` | 0x20 | Filter out objects with untagged classes. Objects whose class is not tagged are not included.

The Heap Visit Control Flags are returned by the heap callbacks and can be used to abort the iteration. For the Heap Reference Callback, it can also be used to prune the graph of traversed references (`JVMTI_VISIT_OBJECTS` is not set).

> Heap Visit Control Flags
> Constant | Value | Description
> `JVMTI_VISIT_OBJECTS` | 0x100 | If we are visiting an object and if this callback was initiated by `FollowReferences`, traverse the references of this object. Otherwise ignored.
> `JVMTI_VISIT_ABORT` | 0x8000 | Abort the iteration. Ignore all other bits.

The Heap Reference Enumeration is provided by the Heap Reference Callback and Primitive Field Callback to describe the kind of reference being reported.

> Heap Reference Enumeration (`jvmtiHeapReferenceKind`)
> Constant | Value | Description
> `JVMTI_HEAP_REFERENCE_CLASS` | 1 | Reference from an object to its class.
> `JVMTI_HEAP_REFERENCE_FIELD` | 2 | Reference from an object to the value of one of its instance fields.
> `JVMTI_HEAP_REFERENCE_ARRAY_ELEMENT` | 3 | Reference from an array to one of its elements.
> `JVMTI_HEAP_REFERENCE_CLASS_LOADER` | 4 | Reference from a class to its class loader.
> `JVMTI_HEAP_REFERENCE_SIGNERS` | 5 | Reference from a class to its signers array.
> `JVMTI_HEAP_REFERENCE_PROTECTION_DOMAIN` | 6 | Reference from a class to its protection domain.
> `JVMTI_HEAP_REFERENCE_INTERFACE` | 7 | Reference from a class to one of its interfaces. Note: interfaces are defined via a constant pool reference, so the referenced interfaces may also be reported with a `JVMTI_HEAP_REFERENCE_CONSTANT_POOL` reference kind.
> `JVMTI_HEAP_REFERENCE_STATIC_FIELD` | 8 | Reference from a class to the value of one of its static fields.
> `JVMTI_HEAP_REFERENCE_CONSTANT_POOL` | 9 | Reference from a class to a resolved entry in the constant pool.
> `JVMTI_HEAP_REFERENCE_SUPERCLASS` | 10 | Reference from a class to its superclass. A callback is bot sent if the superclass is `java.lang.Object`. Note: loaded classes define superclasses via a constant pool reference, so the referenced superclass may also be reported with a `JVMTI_HEAP_REFERENCE_CONSTANT_POOL` reference kind.
> `JVMTI_HEAP_REFERENCE_JNI_GLOBAL` | 21 | Heap root reference: JNI global reference.
> `JVMTI_HEAP_REFERENCE_SYSTEM_CLASS` | 22 | Heap root reference: System class.
> `JVMTI_HEAP_REFERENCE_MONITOR` | 23 | Heap root reference: monitor.
> `JVMTI_HEAP_REFERENCE_STACK_LOCAL` | 24 | Heap root reference: local variable on the stack.
> `JVMTI_HEAP_REFERENCE_JNI_LOCAL` | 25 | Heap root reference: JNI local reference.
> `JVMTI_HEAP_REFERENCE_THREAD` | 26 | Heap root reference: Thread.
> `JVMTI_HEAP_REFERENCE_OTHER` | 27 | Heap root reference: other heap root reference.

Definitions for the single character type descriptors of primitive types.

> Primitive Type Enumeration (`jvmtiPrimitiveType`)
> Constant | Value | Description
> `JVMTI_PRIMITIVE_TYPE_BOOLEAN` | 90 | 'Z' - Java programming language `boolean` - JNI `jboolean`
> `JVMTI_PRIMITIVE_TYPE_BYTE` | 66 | 'B' - Java programming language `byte` - JNI `jbyte`
> `JVMTI_PRIMITIVE_TYPE_CHAR` | 67 | 'C' - Java programming language `char` - JNI `jchar`
> `JVMTI_PRIMITIVE_TYPE_SHORT` | 83 | 'S' - Java programming language `short` - JNI `jshort`
> `JVMTI_PRIMITIVE_TYPE_INT` | 73 | 'I' - Java programming language `int` - JNI `jint`
> `JVMTI_PRIMITIVE_TYPE_LONG` | 74 | 'J' - Java programming language `long` - JNI `jlong`
> `JVMTI_PRIMITIVE_TYPE_FLOAT` | 70 | 'F' - Java programming language `float` - JNI `jfloat`
> `JVMTI_PRIMITIVE_TYPE_DOUBLE` | 68 | 'D' - Java programming language `double` - JNI `jdouble`

#### Reference information structure for Field references

Reference information returned for `JVMTI_HEAP_REFERENCE_FIELD` and `JVMTI_HEAP_REFERENCE_STATIC_FIELD` references.

>     typedef struct {
>         jint index;
>     } jvmtiHeapReferenceInfoField;

> `jvmtiHeapReferenceInfoField` - Reference information structure for Field references
> Field | Type | Description
> > `index` | `jint` | For `JVMTI_HEAP_REFERENCE_FIELD`, the referrer object is not a class or an inteface. In this case, `index` is the index of the field in the class of the referrer object. This class is referred to below as C. For `JVMTI_HEAP_REFERENCE_STATIC_FIELD`, the referrer object is a class (referred to below as C) or an interface (referred to below as I). In this case, `index` is the index of the field in that class or interface. If the referrer object is not an interface, then the field indices are determined as follows: make a list of all the fields in C and its superclasses, starting with all the fields in `java.lang.Object` and ending with all the fields in C. Within this list, put the fields for a given class in the order returned by `GetClassFields`. Assign the fields in this list indices n, n+1, ..., in order, where n is the count of the fields in all the interfaces implemented by C. Note that C implements all interfaces directly implemented by its superclasses; as well as all superinterfaces of these interfaces. If the referrer object is an interface, then the field indices are determined as follows: make a list of the fields directly declared in I. Within this list, put the fields in the order returned by `GetClassFields`. Assign the fields in this list indices n, n+1, ..., in order, where n is the count of the fields in all the superinterfaces of I. All fields are included in this computation, regardless of field modifier (static, public, private, etc). For example, given the following classes and interfaces:
> >     interface I0 {
> >         int p = 0;
> >     }

> >     interface I1 extends I0 {
> >         int x = 1;
> >     }

> >     interface I2 extends I0 {
> >         int y = 2;
> >     }

> >     class C1 implements I1 {
> >         public static int a = 3;
> >         private int b = 4;
> >     }

> >     class C2 extends C1 implements I2 {
> >         static int q = 5;
> >         final int r = 6;
> >     }
>   Assume that `GetClassFields` called on `C1` returns the fields of `C1` in the order: a, b; and that the fields of `C2` are returned in the order: q, r. An instance of class `C1` will have the following field indices:
>   a | 2 | The count of the fields in the interfaces implemented by `C1` is two (n=2): `p` of `I0` and `x` of `I1`.
>   b | 3 | the subsequent index.
>   The class `C1` will have the same field indices. An instance of class `C2` will have the following field indices:
>   a | 3 | The count of the fields in the interfaces implemented by `C2` is three (n=3): `p` of `I0`, `x` of `I1` and `y` of `I2` (an interface of `C2`). Note that the field `p` of `I0` is only included once.
>   b | 4 | the subsequent index to "a".
>   q | 5 | the subsequent index to "b".
>   r | 6 | the subsequent index to "q".
>   The class `C2` will have the same field indices. Note that a field may have a different index depending on the object that is viewing it -- for example field "a" above. Note also: not all field indices may be visible from the callbacks, but all indices are shown for illustrative purposes. The interface `I1` will have the following field indices:
>   x | 1 | The count of the fields in the superinterfaces of `I1` is one (n=1): `p` of `I0`.

#### Reference information structure for Array references

Reference information returned for `JVMTI_HEAP_REFERENCE_ARRAY_ELEMENT` references.

>     typedef struct {
>         jint index;
>     } jvmtiHeapReferenceInfoArray;

> `jvmtiHeapReferenceInfoArray` - Reference information structure for Array references
> Field | Type | Description
> `index` | `jint` | The array index.

#### Reference information structure for Constant Pool references

Reference information returned for `JVMTI_HEAP_REFERENCE_CONSTANT_POOL` references.

>     typedef struct {
>         jint index;
>     } jvmtiHeapReferenceInfoConstantPool;

> `jvmtiHeapReferenceInfoConstantPool` - Reference information structure for Constant Pool references
> Field | Type | Description
> `index` | `jint` | The index into the constant pool of the class. See the Constant Pool section of the Java Virtual Machine Specification description.

#### Reference information structure for Local Variable references

Reference information returned for `JVMTI_HEAP_REFERENCE_STACK_LOCAL` references.

>     typedef struct {
>         jlong thread_tag;
>         jlong thread_id;
>         jint depth;
>         jmethodID method;
>         jlocation location;
>         jint slot;
>     } jvmtiHeapReferenceInfoStackLocal;

> `jvmtiHeapReferenceInfoStackLocal` - Reference information structure for Local Variable references
> Field | Type | Description
> `thread_tag` | `jlong` | The tag of the thread corresponding to this stack, zero if not tagged.
> `thread_id` | `jlong` | The unique thread ID of the thread corresponding to this stack.
> `depth` | `jint` | The depth of the frame.
> `method` | `jmethodID` | The method executing in this frame.
> `location` | `jlocation` | The currently executing location in this frame.
> `slot` | `jint` | The slot number of the local variable.

#### Reference information structure for JNI local references

Reference information returned for `JVMTI_HEAP_REFERENCE_JNI_LOCAL` references.

>     typedef struct {
>         jlong thread_tag;
>         jlong thread_id;
>         jint depth;
>         jmethodID method;
>     } jvmtiHeapReferenceInfoJniLocal;

> `jvmtiHeapReferenceInfoJniLocal` - Reference information structure for JNI local references
> Field | Type | Description
> `thread_tag` | `jlong` | The tag of the thread corresponding to this stack, zero if not tagged.
> `thread_id` | `jlong` | The unique thread ID of the thread corresponding to this stack.
> `depth` | `jint` | The depth of the frame.
> `method` | `jmethodID` | The method executing in this frame.

#### Reference information structure for Other references

Reference information returned for other references.

>     typedef struct {
>         jlong reserved1;
>         jlong reserved2;
>         jlong reserved3;
>         jlong reserved4;
>         jlong reserved5;
>         jlong reserved6;
>         jlong reserved7;
>         jlong reserved8;
>     } jvmtiHeapReferenceInfoReserved;

> `jvmtiHeapReferenceInfoReserved` - Reference information structure for Other references
> Field | Type | Description
> `reserved1` | `jlong` | reserved for future use.
> `reserved2` | `jlong` | reserved for future use.
> `reserved3` | `jlong` | reserved for future use.
> `reserved4` | `jlong` | reserved for future use.
> `reserved5` | `jlong` | reserved for future use.
> `reserved6` | `jlong` | reserved for future use.
> `reserved7` | `jlong` | reserved for future use.
> `reserved8` | `jlong` | reserved for future use.

#### Reference information structure

The information returned about referrers. Represented as a union of the various kinds of reference information.

>     typedef union {
>         jvmtiHeapReferenceInfoField field;
>         jvmtiHeapReferenceInfoArray array;
>         jvmtiHeapReferenceInfoConstantPool constant_pool;
>         jvmtiHeapReferenceInfoStackLocal stack_local;
>         jvmtiHeapReferenceInfoJniLocal jni_local;
>         jvmtiHeapReferenceInfoReserved other;
>     } jvmtiHeapReferenceInfo;

> `jvmtiHeapReferenceInfo` - Reference information structure
> Field | Type | Description
> `field` | `jvmtiHeapReferenceInfoField` | The referrer information for `JVMTI_HEAP_REFERENCE_FIELD` and `JVMTI_HEAP_REFERENCE_STATIC_FIELD` references.
> `array` | `jvmtiHeapReferenceInfoArray` | The referrer information for For `JVMTI_HEAP_REFERENCE_ARRAY_ELEMENT` references.
> `constant_pool` | `jvmtiHeapReferenceInfoConstantPool` | The referrer information for For `JVMTI_HEAP_REFERENCE_CONSTANT_POOL` references.
> `stack_local` | `jvmtiHeapReferenceInfoStackLocal` | The referrer information for For `JVMTI_HEAP_REFERENCE_STACK_LOCAL` references.
> `jni_local` | `jvmtiHeapReferenceInfoJniLocal` | The referrer information for For `JVMTI_HEAP_REFERENCE_JNI_LOCAL` references.
> `other` | `jvmtiHeapReferenceInfoReserved` | reserved for future use.

#### Heap callback function structure

>     typedef struct {
>         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;
>     } jvmtiHeapCallbacks;

> `jvmtiHeapCallbacks` - Heap callback function structure
> Field | Type | Description
> `heap_iteration_callback` | `jvmtiHeapIterationCallback` | The callback to be called to describe an object in the heap. Used by the `IterateThroughHeap` function, ignored by the `FollowReferences` function.
> `heap_reference_callback` | `jvmtiHeapReferenceCallback` | The callback to be called to describe an object reference. Used by the `FollowReferences` function, ignored by the `IterateThroughHeap` function.
> `primitive_field_callback` | `jvmtiPrimitiveFieldCallback` | The callback to be called to describe a primitive field.
> `array_primitive_value_callback` | `jvmtiArrayPrimitiveValueCallback` | The callback to be called to describe an array of primitive values.
> `string_primitive_value_callback` | `jvmtiStringPrimitiveValueCallback` | The callback to be called to describe a String value.
> `reserved5` | `jvmtiReservedCallback` | Reserved for future use..
> `reserved6` | `jvmtiReservedCallback` | Reserved for future use..
> `reserved7` | `jvmtiReservedCallback` | Reserved for future use..
> `reserved8` | `jvmtiReservedCallback` | Reserved for future use..
> `reserved9` | `jvmtiReservedCallback` | Reserved for future use..
> `reserved10` | `jvmtiReservedCallback` | Reserved for future use..
> `reserved11` | `jvmtiReservedCallback` | Reserved for future use..
> `reserved12` | `jvmtiReservedCallback` | Reserved for future use..
> `reserved13` | `jvmtiReservedCallback` | Reserved for future use..
> `reserved14` | `jvmtiReservedCallback` | Reserved for future use..
> `reserved15` | `jvmtiReservedCallback` | Reserved for future use..

Rationale: The heap dumping functionality (below) uses a callback for each object. While it would seem that a buffered approach would provide better throughput, tests do not show this to be the case--possibly due to locality of memory reference or array access overhead.

### Heap Iteration Callback

>     typedef jint (JNICALL *jvmtiHeapIterationCallback)
>         (jlong class_tag,
>          jlong size,
>          jlong* tag_ptr,
>          jint length,
>          void* user_data);
Agent supplied callback function. Describes (but does not pass in) an object in the heap. This function should return a bit vector of the desired visit control flags. This will determine if the entire iteration should be aborted (the `JVMTI_VISIT_OBJECTS` flag is ignored). See the heap callback function restrictions.
Parameters
Name | Type | Description
`class_tag` | `jlong` | The tag of the class of object (zero if the class is not tagged). If the object represents a runtime class, the `class_tag` is the tag associated with `java.lang.Class` (zero if `java.lang.Class` is not tagged).
`size` | `jlong` | Size of the object (in bytes). See `GetObjectSize`.
`tag_ptr` | `jlong*` | The object tag value, or zero if the object is not tagged. To set the tag value to be associated with the object the agent sets the `jlong` pointed to by the parameter.
`length` | `jint` | If this object is an array, the length of the array. Otherwise negative one (-1).
`user_data` | `void*` | The user supplied data that was passed into the iteration function.

### Heap Reference Callback

>     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);
Agent supplied callback function. Describes a reference from an object or the VM (the referrer) to another object (the referree) or a heap root to a referree. This function should return a bit vector of the desired visit control flags. This will determine if the objects referenced by the referree should be visited or if the entire iteration should be aborted. See the heap callback function restrictions.
Parameters
Name | Type | Description
`reference_kind` | `jvmtiHeapReferenceKind` | The kind of reference.
`reference_info` | `const jvmtiHeapReferenceInfo *` | Details about the reference. Set when the `reference_kind` is `JVMTI_HEAP_REFERENCE_FIELD`, `JVMTI_HEAP_REFERENCE_STATIC_FIELD`, `JVMTI_HEAP_REFERENCE_ARRAY_ELEMENT`, `JVMTI_HEAP_REFERENCE_CONSTANT_POOL`, `JVMTI_HEAP_REFERENCE_STACK_LOCAL`, or `JVMTI_HEAP_REFERENCE_JNI_LOCAL`. Otherwise `NULL`.
`class_tag` | `jlong` | The tag of the class of referree object (zero if the class is not tagged). If the referree object represents a runtime class, the `class_tag` is the tag associated with `java.lang.Class` (zero if `java.lang.Class` is not tagged).
`referrer_class_tag` | `jlong` | The tag of the class of the referrer object (zero if the class is not tagged or the referree is a heap root). If the referrer object represents a runtime class, the `referrer_class_tag` is the tag associated with the `java.lang.Class` (zero if `java.lang.Class` is not tagged).
`size` | `jlong` | Size of the referree object (in bytes). See `GetObjectSize`.
`tag_ptr` | `jlong*` | Points to the referree object tag value, or zero if the object is not tagged. To set the tag value to be associated with the object the agent sets the `jlong` pointed to by the parameter.
`referrer_tag_ptr` | `jlong*` | Points to the tag of the referrer object, or points to the zero if the referrer object is not tagged. `NULL` if the referrer in not an object (that is, this callback is reporting a heap root). To set the tag value to be associated with the referrer object the agent sets the `jlong` pointed to by the parameter. If this callback is reporting a reference from an object to itself, `referrer_tag_ptr == tag_ptr`.
`length` | `jint` | If this object is an array, the length of the array. Otherwise negative one (-1).
`user_data` | `void*` | The user supplied data that was passed into the iteration function.

### Primitive Field Callback

>     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);
Agent supplied callback function which describes a primitive field of an object (the object). A primitive field is a field whose type is a primitive type. This callback will describe a static field if the object is a class, and otherwise will describe an instance field. This function should return a bit vector of the desired visit control flags. This will determine if the entire iteration should be aborted (the `JVMTI_VISIT_OBJECTS` flag is ignored). See the heap callback function restrictions.
Parameters
Name | Type | Description
`kind` | `jvmtiHeapReferenceKind` | The kind of field -- instance or static (`JVMTI_HEAP_REFERENCE_FIELD` or `JVMTI_HEAP_REFERENCE_STATIC_FIELD`).
`info` | `const jvmtiHeapReferenceInfo *` | Which field (the field index).
`object_class_tag` | `jlong` | The tag of the class of the object (zero if the class is not tagged). If the object represents a runtime class, the `object_class_tag` is the tag associated with `java.lang.Class` (zero if `java.lang.Class` is not tagged).
`object_tag_ptr` | `jlong*` | Points to the tag of the object, or zero if the object is not tagged. To set the tag value to be associated with the object the agent sets the `jlong` pointed to by the parameter.
`value` | `jvalue` | The value of the field.
`value_type` | `jvmtiPrimitiveType` | The type of the field.
`user_data` | `void*` | The user supplied data that was passed into the iteration function.

### Array Primitive Value Callback

>     typedef jint (JNICALL *jvmtiArrayPrimitiveValueCallback)
>         (jlong class_tag,
>          jlong size,
>          jlong* tag_ptr,
>          jint element_count,
>          jvmtiPrimitiveType element_type,
>          const void* elements,
>          void* user_data);
Agent supplied callback function. Describes the values in an array of a primitive type. This function should return a bit vector of the desired visit control flags. This will determine if the entire iteration should be aborted (the `JVMTI_VISIT_OBJECTS` flag is ignored). See the heap callback function restrictions.
Parameters
Name | Type | Description
`class_tag` | `jlong` | The tag of the class of the array object (zero if the class is not tagged).
`size` | `jlong` | Size of the array (in bytes). See `GetObjectSize`.
`tag_ptr` | `jlong*` | Points to the tag of the array object, or zero if the object is not tagged. To set the tag value to be associated with the object the agent sets the `jlong` pointed to by the parameter.
`element_count` | `jint` | The length of the primitive array.
`element_type` | `jvmtiPrimitiveType` | The type of the elements of the array.
`elements` | `const void*` | The elements of the array in a packed array of `element_count` items of `element_type` size each.
`user_data` | `void*` | The user supplied data that was passed into the iteration function.

### String Primitive Value Callback

>     typedef jint (JNICALL *jvmtiStringPrimitiveValueCallback)
>         (jlong class_tag,
>          jlong size,
>          jlong* tag_ptr,
>          const jchar* value,
>          jint value_length,
>          void* user_data);
Agent supplied callback function. Describes the value of a java.lang.String. This function should return a bit vector of the desired visit control flags. This will determine if the entire iteration should be aborted (the `JVMTI_VISIT_OBJECTS` flag is ignored). See the heap callback function restrictions.
Parameters
Name | Type | Description
`class_tag` | `jlong` | The tag of the class of the String class (zero if the class is not tagged).
`size` | `jlong` | Size of the string (in bytes). See `GetObjectSize`.
`tag_ptr` | `jlong*` | Points to the tag of the String object, or zero if the object is not tagged. To set the tag value to be associated with the object the agent sets the `jlong` pointed to by the parameter.
`value` | `const jchar*` | The value of the String, encoded as a Unicode string.
`value_length` | `jint` | The length of the string. The length is equal to the number of 16-bit Unicode characters in the string.
`user_data` | `void*` | The user supplied data that was passed into the iteration function.

### reserved for future use Callback

>     typedef jint (JNICALL *jvmtiReservedCallback)
>         ();
Placeholder -- reserved for future use.
Parameters
Name | Type | Description

### Follow References

>     jvmtiError
>     FollowReferences(jvmtiEnv* env,
>                 jint heap_filter,
>                 jclass klass,
>                 jobject initial_object,
>                 const jvmtiHeapCallbacks* callbacks,
>                 const void* user_data)

This function initiates a traversal over the objects that are directly and indirectly reachable from the specified object or, if `initial_object` is not specified, all objects reachable from the heap roots. The heap root are the set of system classes, JNI globals, references from thread stacks, and other objects used as roots for the purposes of garbage collection.

This function operates by traversing the reference graph. Let A, B, ... represent objects. When a reference from A to B is traversed, when a reference from a heap root to B is traversed, or when B is specified as the `initial_object`, then B is said to be visited. A reference from A to B is not traversed until A is visited. References are reported in the same order that the references are traversed. Object references are reported by invoking the agent supplied callback function `jvmtiHeapReferenceCallback`. In a reference from A to B, A is known as the referrer and B as the referree. The callback is invoked exactly once for each reference from a referrer; this is true even if there are reference cycles or multiple paths to the referrer. There may be more than one reference between a referrer and a referree, each reference is reported. These references may be distinguished by examining the `reference_kind` and `reference_info` parameters of the `jvmtiHeapReferenceCallback` callback.

This function reports a Java programming language view of object references, not a virtual machine implementation view. The following object references are reported when they are non-null:

- Instance objects report references to each non-primitive instance fields (including inherited fields).
- Instance objects report a reference to the object type (class).
- Classes report a reference to the superclass and directly implemented/extended interfaces.
- Classes report a reference to the class loader, protection domain, signers, and resolved entries in the constant pool.
- Classes report a reference to each directly declared non-primitive static field.
- Arrays report a reference to the array type (class) and each array element.
- Primitive arrays report a reference to the array type.

This function can also be used to examine primitive (non-object) values. The primitive value of an array or String is reported after the object has been visited; it is reported by invoking the agent supplied callback function `jvmtiArrayPrimitiveValueCallback` or `jvmtiStringPrimitiveValueCallback`. A primitive field is reported after the object with that field is visited; it is reported by invoking the agent supplied callback function `jvmtiPrimitiveFieldCallback`.

Whether a callback is provided or is `NULL` only determines whether the callback will be invoked, it does not influence which objects are visited nor does it influence whether other callbacks will be invoked. However, the visit control flags returned by `jvmtiHeapReferenceCallback` do determine if the objects referenced by the current object as visited. The heap filter flags and `klass` provided as parameters to this function do not control which objects are visited but they do control which objects and primitive values are reported by the callbacks. For example, if the only callback that was set is `array_primitive_value_callback` and `klass` is set to the array of bytes class, then only arrays of byte will be reported. The table below summarizes this:

| Controls objects visited | Controls objects reported | Controls primitives reported
--- | --- | --- | ---
the Heap Visit Control Flags returned by `jvmtiHeapReferenceCallback` | Yes | Yes, since visits are controlled | Yes, since visits are controlled
`object_reference_callback` in `callbacks` set | No | Yes | No
`heap_filter` | No | Yes | Yes
`klass` | No | Yes | Yes

During the execution of this function the state of the heap does not change: no objects are allocated, no objects are garbage collected, and the state of objects (including held values) does not change. As a result, threads executing Java programming language code, threads attempting to resume the execution of Java programming language code, and threads attempting to execute JNI functions are typically stalled.

Phase | Callback Safe | Position | Since
may only be called during the live phase | No | 115 | 1.1

Capabilities
Optional Functionality: might not be implemented for all virtual machines. The following capability (as returned by `GetCapabilities`) must be true to use this function.
Capability | Effect
`can_tag_objects` | Can set and get tags, as described in the Heap category.

Parameters
Name | Type | Description
`heap_filter` | `jint` | This bit vector of heap filter flags. restricts the objects for which the callback function is called. This applies to both the object and primitive callbacks.
`klass` | `jclass` | Callbacks are only reported when the object is an instance of this class. Objects which are instances of a subclass of `klass` are not reported. If `klass` is an interface, no objects are reported. This applies to both the object and primitive callbacks. If `klass` is `NULL`, callbacks are not limited to instances of a particular class.
`initial_object` | `jobject` | The object to follow If `initial_object` is `NULL`, references are followed from the heap roots.
`callbacks` | `const jvmtiHeapCallbacks *` | Structure defining the set of callback functions. Agent passes in a pointer to `jvmtiHeapCallbacks`.
`user_data` | `const void *` | User supplied data to be passed to the callback. Agent passes in a pointer. If `user_data` is `NULL`, `NULL` is passed as the user supplied data.

Errors
This function returns either a universal error or one of the following errors
Error | Description
`JVMTI_ERROR_MUST_POSSESS_CAPABILITY` | The environment does not possess the capability `can_tag_objects`. Use `AddCapabilities`.
`JVMTI_ERROR_INVALID_CLASS` | `klass` is not a valid class.
`JVMTI_ERROR_INVALID_OBJECT` | `initial_object` is not a valid object.
`JVMTI_ERROR_NULL_POINTER` | `callbacks` is `NULL`.

### Iterate Through Heap

>     jvmtiError
>     IterateThroughHeap(jvmtiEnv* env,
>                 jint heap_filter,
>                 jclass klass,
>                 const jvmtiHeapCallbacks* callbacks,
>                 const void* user_data)

Initiate an iteration over all objects in the heap. This includes both reachable and unreachable objects. Objects are visited in no particular order.

Heap objects are reported by invoking the agent supplied callback function `jvmtiHeapIterationCallback`. References between objects are not reported. If only reachable objects are desired, or if object reference information is needed, use `FollowReferences`.

This function can also be used to examine primitive (non-object) values. The primitive value of an array or String is reported after the object has been visited; it is reported by invoking the agent supplied callback function `jvmtiArrayPrimitiveValueCallback` or `jvmtiStringPrimitiveValueCallback`. A primitive field is reported after the object with that field is visited; it is reported by invoking the agent supplied callback function `jvmtiPrimitiveFieldCallback`.

Unless the iteration is aborted by the Heap Visit Control Flags returned by a callback, all objects in the heap are visited. Whether a callback is provided or is `NULL` only determines whether the callback will be invoked, it does not influence which objects are visited nor does it influence whether other callbacks will be invoked. The heap filter flags and `klass` provided as parameters to this function do not control which objects are visited but they do control which objects and primitive values are reported by the callbacks. For example, if the only callback that was set is `array_primitive_value_callback` and `klass` is set to the array of bytes class, then only arrays of byte will be reported. The table below summarizes this (contrast this with `FollowReferences`):

| Controls objects visited | Controls objects reported | Controls primitives reported
--- | --- | --- | ---
the Heap Visit Control Flags returned by `jvmtiHeapIterationCallback` | No (unless they abort the iteration) | No (unless they abort the iteration) | No (unless they abort the iteration)
`object_callback` in `callbacks` set | No | Yes | No
`heap_filter` | No | Yes | Yes
`klass` | No | Yes | Yes

During the execution of this function the state of the heap does not change: no objects are allocated, no objects are garbage collected, and the state of objects (including held values) does not change. As a result, threads executing Java programming language code, threads attempting to resume the execution of Java programming language code, and threads attempting to execute JNI functions are typically stalled.

Phase | Callback Safe | Position | Since
may only be called during the live phase | No | 116 | 1.1

Capabilities
Optional Functionality: might not be implemented for all virtual machines. The following capability (as returned by `GetCapabilities`) must be true to use this function.
Capability | Effect
`can_tag_objects` | Can set and get tags, as described in the Heap category.

Parameters
Name | Type | Description
`heap_filter` | `jint` | This bit vector of heap filter flags. restricts the objects for which the callback function is called. This applies to both the object and primitive callbacks.
`klass` | `jclass` | Callbacks are only reported when the object is an instance of this class. Objects which are instances of a subclass of `klass` are not reported. If `klass` is an interface, no objects are reported. This applies to both the object and primitive callbacks. If `klass` is `NULL`, callbacks are not limited to instances of a particular class.
`callbacks` | `const jvmtiHeapCallbacks *` | Structure defining the set callback functions. Agent passes in a pointer to `jvmtiHeapCallbacks`.
`user_data` | `const void *` | User supplied data to be passed to the callback. Agent passes in a pointer. If `user_data` is `NULL`, `NULL` is passed as the user supplied data.

Errors
This function returns either a universal error or one of the following errors
Error | Description
`JVMTI_ERROR_MUST_POSSESS_CAPABILITY` | The environment does not possess the capability `can_tag_objects`. Use `AddCapabilities`.
`JVMTI_ERROR_INVALID_CLASS` | `klass` is not a valid class.
`JVMTI_ERROR_NULL_POINTER` | `callbacks` is `NULL`.

### Get Tag

>     jvmtiError
>     GetTag(jvmtiEnv* env,
>                 jobject object,
>                 jlong* tag_ptr)

Retrieve the tag associated with an object. The tag is a long value typically used to store a unique identifier or pointer to object information. The tag is set with `SetTag`. Objects for which no tags have been set return a tag value of zero.

Phase | Callback Safe | Position | Since
may only be called during the start or the live phase | No | 106 | 1.0

Capabilities
Optional Functionality: might not be implemented for all virtual machines. The following capability (as returned by `GetCapabilities`) must be true to use this function.
Capability | Effect
`can_tag_objects` | Can set and get tags, as described in the Heap category.

Parameters
Name | Type | Description
`object` | `jobject` | The object whose tag is to be retrieved.
`tag_ptr` | `jlong*` | On return, the referenced long is set to the value of the tag. Agent passes a pointer to a `jlong`. On return, the `jlong` has been set.

Errors
This function returns either a universal error or one of the following errors
Error | Description
`JVMTI_ERROR_MUST_POSSESS_CAPABILITY` | The environment does not possess the capability `can_tag_objects`. Use `AddCapabilities`.
`JVMTI_ERROR_INVALID_OBJECT` | `object` is not an object.
`JVMTI_ERROR_NULL_POINTER` | `tag_ptr` is `NULL`.

### Set Tag

>     jvmtiError
>     SetTag(jvmtiEnv* env,
>                 jobject object,
>                 jlong tag)

Set the tag associated with an object. The tag is a long value typically used to store a unique identifier or pointer to object information. The tag is visible with `GetTag`.

Phase | Callback Safe | Position | Since
may only be called during the start or the live phase | No | 107 | 1.0

Capabilities
Optional Functionality: might not be implemented for all virtual machines. The following capability (as returned by `GetCapabilities`) must be true to use this function.
Capability | Effect
`can_tag_objects` | Can set and get tags, as described in the Heap category.

Parameters
Name | Type | Description
`object` | `jobject` | The object whose tag is to be set.
`tag` | `jlong` | The new value of the tag.

Errors
This function returns either a universal error or one of the following errors
Error | Description
`JVMTI_ERROR_MUST_POSSESS_CAPABILITY` | The environment does not possess the capability `can_tag_objects`. Use `AddCapabilities`.
`JVMTI_ERROR_INVALID_OBJECT` | `object` is not an object.

### Get Objects With Tags

>     jvmtiError
>     GetObjectsWithTags(jvmtiEnv* env,
>                 jint tag_count,
>                 const jlong* tags,
>                 jint* count_ptr,
>                 jobject** object_result_ptr,
>                 jlong** tag_result_ptr)

Return objects in the heap with the specified tags. The format is parallel arrays of objects and tags.

Phase | Callback Safe | Position | Since
may only be called during the live phase | No | 114 | 1.0

Capabilities
Optional Functionality: might not be implemented for all virtual machines. The following capability (as returned by `GetCapabilities`) must be true to use this function.
Capability | Effect
`can_tag_objects` | Can set and get tags, as described in the Heap category.

Parameters
Name | Type | Description
`tag_count` | `jint` | Number of tags to scan for.
`tags` | `const jlong *` | Scan for objects with these tags. Zero is not permitted in this array. Agent passes in an array of `tag_count` elements of `jlong`.
`count_ptr` | `jint *` | Return the number of objects with any of the tags in `tags`. Agent passes a pointer to a `jint`. On return, the `jint` has been set.
`object_result_ptr` | `jobject **` | Returns the array of objects with any of the tags in `tags`. Agent passes a pointer to a `jobject*`. On return, the `jobject*` points to a newly allocated array of size `*count_ptr`. The array should be freed with `Deallocate`. If `object_result_ptr` is `NULL`, this information is not returned. The objects returned by `object_result_ptr` are JNI local references and must be managed.
`tag_result_ptr` | `jlong **` | For each object in `object_result_ptr`, return the tag at the corresponding index. Agent passes a pointer to a `jlong*`. On return, the `jlong*` points to a newly allocated array of size `*count_ptr`. The array should be freed with `Deallocate`. If `tag_result_ptr` is `NULL`, this information is not returned.

Errors
This function returns either a universal error or one of the following errors
Error | Description
`JVMTI_ERROR_MUST_POSSESS_CAPABILITY` | The environment does not possess the capability `can_tag_objects`. Use `AddCapabilities`.
`JVMTI_ERROR_ILLEGAL_ARGUMENT` | Zero is present in `tags`.
`JVMTI_ERROR_ILLEGAL_ARGUMENT` | `tag_count` is less than `0`.
`JVMTI_ERROR_NULL_POINTER` | `tags` is `NULL`.
`JVMTI_ERROR_NULL_POINTER` | `count_ptr` is `NULL`.

### Force Garbage Collection

>     jvmtiError
>     ForceGarbageCollection(jvmtiEnv* env)

Force the VM to perform a garbage collection. The garbage collection is as complete as possible. This function does not cause finalizers to be run. This function does not return until the garbage collection is finished.

Although garbage collection is as complete as possible there is no guarantee that all `ObjectFree` events will have been sent by the time that this function returns. In particular, an object may be prevented from being freed because it is awaiting finalization.

Phase | Callback Safe | Position | Since
may only be called during the live phase | No | 108 | 1.0

Capabilities
Required Functionality

Parameters
Name | Type | Description

Errors
This function returns a universal error

## Heap (1.0)

Heap (1.0) functions:

- Iterate Over Objects Reachable From Object
- Iterate Over Reachable Objects
- Iterate Over Heap
- Iterate Over Instances Of Class

Heap (1.0) function types:

- Heap Object Callback
- Heap Root Object Callback
- Stack Reference Object Callback
- Object Reference Callback

Heap (1.0) types:

- `jvmtiHeapObjectFilter` - Heap Object Filter Enumeration
- `jvmtiHeapRootKind` - Heap Root Kind Enumeration
- `jvmtiObjectReferenceKind` - Object Reference Enumeration
- `jvmtiIterationControl` - Iteration Control Enumeration

These functions and data types were introduced in the original JVM TI version 1.0 and have been superseded by more powerful and flexible versions which:

- Allow access to primitive values (the value of Strings, arrays, and primitive fields)
- Allow the tag of the referrer to be set, thus enabling more efficient localized reference graph building
- Provide more extensive filtering abilities
- Are extensible, allowing their abilities to grow in future versions of JVM TI

Please use the current Heap functions.

> Heap Object Filter Enumeration (`jvmtiHeapObjectFilter`)
> Constant | Value | Description
> `JVMTI_HEAP_OBJECT_TAGGED` | 1 | Tagged objects only.
> `JVMTI_HEAP_OBJECT_UNTAGGED` | 2 | Untagged objects only.
> `JVMTI_HEAP_OBJECT_EITHER` | 3 | Either tagged or untagged objects.

> Heap Root Kind Enumeration (`jvmtiHeapRootKind`)
> Constant | Value | Description
> `JVMTI_HEAP_ROOT_JNI_GLOBAL` | 1 | JNI global reference.
> `JVMTI_HEAP_ROOT_SYSTEM_CLASS` | 2 | System class.
> `JVMTI_HEAP_ROOT_MONITOR` | 3 | Monitor.
> `JVMTI_HEAP_ROOT_STACK_LOCAL` | 4 | Stack local.
> `JVMTI_HEAP_ROOT_JNI_LOCAL` | 5 | JNI local reference.
> `JVMTI_HEAP_ROOT_THREAD` | 6 | Thread.
> `JVMTI_HEAP_ROOT_OTHER` | 7 | Other.

> Object Reference Enumeration (`jvmtiObjectReferenceKind`)
> Constant | Value | Description
> `JVMTI_REFERENCE_CLASS` | 1 | Reference from an object to its class.
> `JVMTI_REFERENCE_FIELD` | 2 | Reference from an object to the value of one of its instance fields. For references of this kind the `referrer_index` parameter to the jvmtiObjectReferenceCallback is the index of the the instance field. The index is based on the order of all the object's fields. This includes all fields of the directly declared static and instance fields in the class, and includes all fields (both public and private) fields declared in superclasses and superinterfaces. The index is thus calculated by summing the index of the field in the directly declared class (see `GetClassFields`), with the total number of fields (both public and private) declared in all superclasses and superinterfaces. The index starts at zero.
> `JVMTI_REFERENCE_ARRAY_ELEMENT` | 3 | Reference from an array to one of its elements. For references of this kind the `referrer_index` parameter to the jvmtiObjectReferenceCallback is the array index.
> `JVMTI_REFERENCE_CLASS_LOADER` | 4 | Reference from a class to its class loader.
> `JVMTI_REFERENCE_SIGNERS` | 5 | Reference from a class to its signers array.
> `JVMTI_REFERENCE_PROTECTION_DOMAIN` | 6 | Reference from a class to its protection domain.
> `JVMTI_REFERENCE_INTERFACE` | 7 | Reference from a class to one of its interfaces.
> `JVMTI_REFERENCE_STATIC_FIELD` | 8 | Reference from a class to the value of one of its static fields. For references of this kind the `referrer_index` parameter to the jvmtiObjectReferenceCallback is the index of the the static field. The index is based on the order of all the object's fields. This includes all fields of the directly declared static and instance fields in the class, and includes all fields (both public and private) fields declared in superclasses and superinterfaces. The index is thus calculated by summing the index of the field in the directly declared class (see `GetClassFields`), with the total number of fields (both public and private) declared in all superclasses and superinterfaces. The index starts at zero. Note: this definition differs from that in the JVM TI 1.0 Specification. Rationale: No known implementations used the 1.0 definition.
> `JVMTI_REFERENCE_CONSTANT_POOL` | 9 | Reference from a class to a resolved entry in the constant pool. For references of this kind the `referrer_index` parameter to the jvmtiObjectReferenceCallback is the index into constant pool table of the class, starting at 1. See the Constant Pool section of the Java Virtual Machine Specification

> Iteration Control Enumeration (`jvmtiIterationControl`)
> Constant | Value | Description
> `JVMTI_ITERATION_CONTINUE` | 1 | Continue the iteration. If this is a reference iteration, follow the references of this object.
> `JVMTI_ITERATION_IGNORE` | 2 | Continue the iteration. If this is a reference iteration, ignore the references of this object.
> `JVMTI_ITERATION_ABORT` | 0 | Abort the iteration.

### Heap Object Callback

>     typedef jvmtiIterationControl (JNICALL *jvmtiHeapObjectCallback)
>         (jlong class_tag,
>          jlong size,
>          jlong* tag_ptr,
>          void* user_data);
Agent supplied callback function. Describes (but does not pass in) an object in the heap. Return value should be `JVMTI_ITERATION_CONTINUE` to continue iteration, or `JVMTI_ITERATION_ABORT` to stop iteration. See the heap callback function restrictions.
Parameters
Name | Type | Description
`class_tag` | `jlong` | The tag of the class of object (zero if the class is not tagged). If the object represents a runtime class, the `class_tag` is the tag associated with `java.lang.Class` (zero if `java.lang.Class` is not tagged).
`size` | `jlong` | Size of the object (in bytes). See `GetObjectSize`.
`tag_ptr` | `jlong*` | The object tag value, or zero if the object is not tagged. To set the tag value to be associated with the object the agent sets the `jlong` pointed to by the parameter.
`user_data` | `void*` | The user supplied data that was passed into the iteration function.

### Heap Root Object Callback

>     typedef jvmtiIterationControl (JNICALL *jvmtiHeapRootCallback)
>         (jvmtiHeapRootKind root_kind,
>          jlong class_tag,
>          jlong size,
>          jlong* tag_ptr,
>          void* user_data);
Agent supplied callback function. Describes (but does not pass in) an object that is a root for the purposes of garbage collection. Return value should be `JVMTI_ITERATION_CONTINUE` to continue iteration, `JVMTI_ITERATION_IGNORE` to continue iteration without pursuing references from referree object or `JVMTI_ITERATION_ABORT` to stop iteration. See the heap callback function restrictions.
Parameters
Name | Type | Description
`root_kind` | `jvmtiHeapRootKind` | The kind of heap root.
`class_tag` | `jlong` | The tag of the class of object (zero if the class is not tagged). If the object represents a runtime class, the `class_tag` is the tag associated with `java.lang.Class` (zero if `java.lang.Class` is not tagged).
`size` | `jlong` | Size of the object (in bytes). See `GetObjectSize`.
`tag_ptr` | `jlong*` | The object tag value, or zero if the object is not tagged. To set the tag value to be associated with the object the agent sets the `jlong` pointed to by the parameter.
`user_data` | `void*` | The user supplied data that was passed into the iteration function.

### Stack Reference Object Callback

>     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);
Agent supplied callback function. Describes (but does not pass in) an object on the stack that is a root for the purposes of garbage collection. Return value should be `JVMTI_ITERATION_CONTINUE` to continue iteration, `JVMTI_ITERATION_IGNORE` to continue iteration without pursuing references from referree object or `JVMTI_ITERATION_ABORT` to stop iteration. See the heap callback function restrictions.
Parameters
Name | Type | Description
`root_kind` | `jvmtiHeapRootKind` | The kind of root (either `JVMTI_HEAP_ROOT_STACK_LOCAL` or `JVMTI_HEAP_ROOT_JNI_LOCAL`).
`class_tag` | `jlong` | The tag of the class of object (zero if the class is not tagged). If the object represents a runtime class, the `class_tag` is the tag associated with `java.lang.Class` (zero if `java.lang.Class` is not tagged).
`size` | `jlong` | Size of the object (in bytes). See `GetObjectSize`.
`tag_ptr` | `jlong*` | The object tag value, or zero if the object is not tagged. To set the tag value to be associated with the object the agent sets the `jlong` pointed to by the parameter.
`thread_tag` | `jlong` | The tag of the thread corresponding to this stack, zero if not tagged.
`depth` | `jint` | The depth of the frame.
`method` | `jmethodID` | The method executing in this frame.
`slot` | `jint` | The slot number.
`user_data` | `void*` | The user supplied data that was passed into the iteration function.

### Object Reference Callback

>     typedef jvmtiIterationControl (JNICALL *jvmtiObjectReferenceCallback)
>         (jvmtiObjectReferenceKind reference_kind,
>          jlong class_tag,
>          jlong size,
>          jlong* tag_ptr,
>          jlong referrer_tag,
>          jint referrer_index,
>          void* user_data);
Agent supplied callback function. Describes a reference from an object (the referrer) to another object (the referree). Return value should be `JVMTI_ITERATION_CONTINUE` to continue iteration, `JVMTI_ITERATION_IGNORE` to continue iteration without pursuing references from referree object or `JVMTI_ITERATION_ABORT` to stop iteration. See the heap callback function restrictions.
Parameters
Name | Type | Description
`reference_kind` | `jvmtiObjectReferenceKind` | The type of reference.
`class_tag` | `jlong` | The tag of the class of referree object (zero if the class is not tagged). If the referree object represents a runtime class, the `class_tag` is the tag associated with `java.lang.Class` (zero if `java.lang.Class` is not tagged).
`size` | `jlong` | Size of the referree object (in bytes). See `GetObjectSize`.
`tag_ptr` | `jlong*` | The referree object tag value, or zero if the object is not tagged. To set the tag value to be associated with the object the agent sets the `jlong` pointed to by the parameter.
`referrer_tag` | `jlong` | The tag of the referrer object, or zero if the referrer object is not tagged.
`referrer_index` | `jint` | For references of type `JVMTI_REFERENCE_FIELD` or `JVMTI_REFERENCE_STATIC_FIELD` the index of the field in the referrer object. The index is based on the order of all the object's fields - see JVMTI_REFERENCE_FIELD or JVMTI_REFERENCE_STATIC_FIELD for further description. For references of type `JVMTI_REFERENCE_ARRAY_ELEMENT` the array index - see JVMTI_REFERENCE_ARRAY_ELEMENT for further description. For references of type `JVMTI_REFERENCE_CONSTANT_POOL` the index into the constant pool of the class - see JVMTI_REFERENCE_CONSTANT_POOL for further description. For references of other kinds the `referrer_index` is `-1`.
`user_data` | `void*` | The user supplied data that was passed into the iteration function.

### Iterate Over Objects Reachable From Object

>     jvmtiError
>     IterateOverObjectsReachableFromObject(jvmtiEnv* env,
>                 jobject object,
>                 jvmtiObjectReferenceCallback object_reference_callback,
>                 const void* user_data)

This function iterates over all objects that are directly and indirectly reachable from the specified object. For each object A (known as the referrer) with a reference to object B the specified callback function is called to describe the object reference. The callback is called exactly once for each reference from a referrer; this is true even if there are reference cycles or multiple paths to the referrer. There may be more than one reference between a referrer and a referree, These may be distinguished by the `jvmtiObjectReferenceCallback.reference_kind` and `jvmtiObjectReferenceCallback.referrer_index`. The callback for an object will always occur after the callback for its referrer.

See `FollowReferences` for the object references which are reported.

During the execution of this function the state of the heap does not change: no objects are allocated, no objects are garbage collected, and the state of objects (including held values) does not change. As a result, threads executing Java programming language code, threads attempting to resume the execution of Java programming language code, and threads attempting to execute JNI functions are typically stalled.

Phase | Callback Safe | Position | Since
may only be called during the live phase | No | 109 | 1.0

Capabilities
Optional Functionality: might not be implemented for all virtual machines. The following capability (as returned by `GetCapabilities`) must be true to use this function.
Capability | Effect
`can_tag_objects` | Can set and get tags, as described in the Heap category.

Parameters
Name | Type | Description
`object` | `jobject` | The object
`object_reference_callback` | `jvmtiObjectReferenceCallback` | The callback to be called to describe each object reference.
`user_data` | `const void *` | User supplied data to be passed to the callback. Agent passes in a pointer. If `user_data` is `NULL`, `NULL` is passed as the user supplied data.

Errors
This function returns either a universal error or one of the following errors
Error | Description
`JVMTI_ERROR_MUST_POSSESS_CAPABILITY` | The environment does not possess the capability `can_tag_objects`. Use `AddCapabilities`.
`JVMTI_ERROR_INVALID_OBJECT` | `object` is not an object.
`JVMTI_ERROR_NULL_POINTER` | `object_reference_callback` is `NULL`.

### Iterate Over Reachable Objects

>     jvmtiError
>     IterateOverReachableObjects(jvmtiEnv* env,
>                 jvmtiHeapRootCallback heap_root_callback,
>                 jvmtiStackReferenceCallback stack_ref_callback,
>                 jvmtiObjectReferenceCallback object_ref_callback,
>                 const void* user_data)

This function iterates over the root objects and all objects that are directly and indirectly reachable from the root objects. The root objects comprise the set of system classes, JNI globals, references from thread stacks, and other objects used as roots for the purposes of garbage collection.

For each root the `heap_root_callback` or `stack_ref_callback` callback is called. An object can be a root object for more than one reason and in that case the appropriate callback is called for each reason.

For each object reference the `object_ref_callback` callback function is called to describe the object reference. The callback is called exactly once for each reference from a referrer; this is true even if there are reference cycles or multiple paths to the referrer. There may be more than one reference between a referrer and a referree, These may be distinguished by the `jvmtiObjectReferenceCallback.reference_kind` and `jvmtiObjectReferenceCallback.referrer_index`. The callback for an object will always occur after the callback for its referrer.

See `FollowReferences` for the object references which are reported.

Roots are always reported to the profiler before any object references are reported. In other words, the `object_ref_callback` callback will not be called until the appropriate callback has been called for all roots. If the `object_ref_callback` callback is specified as `NULL` then this function returns after reporting the root objects to the profiler.

During the execution of this function the state of the heap does not change: no objects are allocated, no objects are garbage collected, and the state of objects (including held values) does not change. As a result, threads executing Java programming language code, threads attempting to resume the execution of Java programming language code, and threads attempting to execute JNI functions are typically stalled.

Phase | Callback Safe | Position | Since
may only be called during the live phase | No | 110 | 1.0

Capabilities
Optional Functionality: might not be implemented for all virtual machines. The following capability (as returned by `GetCapabilities`) must be true to use this function.
Capability | Effect
`can_tag_objects` | Can set and get tags, as described in the Heap category.

Parameters
Name | Type | Description
`heap_root_callback` | `jvmtiHeapRootCallback` | The callback function to be called for each heap root of type `JVMTI_HEAP_ROOT_JNI_GLOBAL`, `JVMTI_HEAP_ROOT_SYSTEM_CLASS`, `JVMTI_HEAP_ROOT_MONITOR`, `JVMTI_HEAP_ROOT_THREAD`, or `JVMTI_HEAP_ROOT_OTHER`. If `heap_root_callback` is `NULL`, do not report heap roots.
`stack_ref_callback` | `jvmtiStackReferenceCallback` | The callback function to be called for each heap root of `JVMTI_HEAP_ROOT_STACK_LOCAL` or `JVMTI_HEAP_ROOT_JNI_LOCAL`. If `stack_ref_callback` is `NULL`, do not report stack references.
`object_ref_callback` | `jvmtiObjectReferenceCallback` | The callback function to be called for each object reference. If `object_ref_callback` is `NULL`, do not follow references from the root objects.
`user_data` | `const void *` | User supplied data to be passed to the callback. Agent passes in a pointer. If `user_data` is `NULL`, `NULL` is passed as the user supplied data.

Errors
This function returns either a universal error or one of the following errors
Error | Description
`JVMTI_ERROR_MUST_POSSESS_CAPABILITY` | The environment does not possess the capability `can_tag_objects`. Use `AddCapabilities`.

### Iterate Over Heap

>     jvmtiError
>     IterateOverHeap(jvmtiEnv* env,
>                 jvmtiHeapObjectFilter object_filter,
>                 jvmtiHeapObjectCallback heap_object_callback,
>                 const void* user_data)

Iterate over all objects in the heap. This includes both reachable and unreachable objects.

The `object_filter` parameter indicates the objects for which the callback function is called. If this parameter is `JVMTI_HEAP_OBJECT_TAGGED` then the callback will only be called for every object that is tagged. If the parameter is `JVMTI_HEAP_OBJECT_UNTAGGED` then the callback will only be for objects that are not tagged. If the parameter is `JVMTI_HEAP_OBJECT_EITHER` then the callback will be called for every object in the heap, irrespective of whether it is tagged or not.

During the execution of this function the state of the heap does not change: no objects are allocated, no objects are garbage collected, and the state of objects (including held values) does not change. As a result, threads executing Java programming language code, threads attempting to resume the execution of Java programming language code, and threads attempting to execute JNI functions are typically stalled.

Phase | Callback Safe | Position | Since
may only be called during the live phase | No | 111 | 1.0

Capabilities
Optional Functionality: might not be implemented for all virtual machines. The following capability (as returned by `GetCapabilities`) must be true to use this function.
Capability | Effect
`can_tag_objects` | Can set and get tags, as described in the Heap category.

Parameters
Name | Type | Description
`object_filter` | `jvmtiHeapObjectFilter` | Indicates the objects for which the callback function is called.
`heap_object_callback` | `jvmtiHeapObjectCallback` | The iterator function to be called for each object matching the `object_filter`.
`user_data` | `const void *` | User supplied data to be passed to the callback. Agent passes in a pointer. If `user_data` is `NULL`, `NULL` is passed as the user supplied data.

Errors
This function returns either a universal error or one of the following errors
Error | Description
`JVMTI_ERROR_MUST_POSSESS_CAPABILITY` | The environment does not possess the capability `can_tag_objects`. Use `AddCapabilities`.
`JVMTI_ERROR_ILLEGAL_ARGUMENT` | `object_filter` is not a jvmtiHeapObjectFilter.
`JVMTI_ERROR_NULL_POINTER` | `heap_object_callback` is `NULL`.

### Iterate Over Instances Of Class

>     jvmtiError
>     IterateOverInstancesOfClass(jvmtiEnv* env,
>                 jclass klass,
>                 jvmtiHeapObjectFilter object_filter,
>                 jvmtiHeapObjectCallback heap_object_callback,
>                 const void* user_data)

Iterate over all objects in the heap that are instances of the specified class. This includes direct instances of the specified class and instances of all subclasses of the specified class. This includes both reachable and unreachable objects.

The `object_filter` parameter indicates the objects for which the callback function is called. If this parameter is `JVMTI_HEAP_OBJECT_TAGGED` then the callback will only be called for every object that is tagged. If the parameter is `JVMTI_HEAP_OBJECT_UNTAGGED` then the callback will only be called for objects that are not tagged. If the parameter is `JVMTI_HEAP_OBJECT_EITHER` then the callback will be called for every object in the heap, irrespective of whether it is tagged or not.

During the execution of this function the state of the heap does not change: no objects are allocated, no objects are garbage collected, and the state of objects (including held values) does not change. As a result, threads executing Java programming language code, threads attempting to resume the execution of Java programming language code, and threads attempting to execute JNI functions are typically stalled.

Phase | Callback Safe | Position | Since
may only be called during the live phase | No | 112 | 1.0

Capabilities
Optional Functionality: might not be implemented for all virtual machines. The following capability (as returned by `GetCapabilities`) must be true to use this function.
Capability | Effect
`can_tag_objects` | Can set and get tags, as described in the Heap category.

Parameters
Name | Type | Description
`klass` | `jclass` | Iterate over objects of this class only.
`object_filter` | `jvmtiHeapObjectFilter` | Indicates the objects for which the callback function is called.
`heap_object_callback` | `jvmtiHeapObjectCallback` | The iterator function to be called for each `klass` instance matching the `object_filter`.
`user_data` | `const void *` | User supplied data to be passed to the callback. Agent passes in a pointer. If `user_data` is `NULL`, `NULL` is passed as the user supplied data.

Errors
This function returns either a universal error or one of the following errors
Error | Description
`JVMTI_ERROR_MUST_POSSESS_CAPABILITY` | The environment does not possess the capability `can_tag_objects`. Use `AddCapabilities`.
`JVMTI_ERROR_INVALID_CLASS` | `klass` is not a class object or the class has been unloaded.
`JVMTI_ERROR_ILLEGAL_ARGUMENT` | `object_filter` is not a jvmtiHeapObjectFilter.
`JVMTI_ERROR_NULL_POINTER` | `heap_object_callback` is `NULL`.

## Local Variable

Local Variable functions:

- Get Local Variable - Object
- Get Local Variable - Int
- Get Local Variable - Long
- Get Local Variable - Float
- Get Local Variable - Double
- Set Local Variable - Object
- Set Local Variable - Int
- Set Local Variable - Long
- Set Local Variable - Float
- Set Local Variable - Double

These functions are used to retrieve or set the value of a local variable. The variable is identified by the depth of the frame containing its value and the variable's slot number within that frame. The mapping of variables to slot numbers can be obtained with the function `GetLocalVariableTable`.

### Get Local Variable - Object

>     jvmtiError
>     GetLocalObject(jvmtiEnv* env,
>                 jthread thread,
>                 jint depth,
>                 jint slot,
>                 jobject* value_ptr)

This function can be used to retrieve the value of a local variable whose type is `Object` or a subclass of `Object`.

Phase | Callback Safe | Position | Since
may only be called during the live phase | No | 21 | 1.0

Capabilities
Optional Functionality: might not be implemented for all virtual machines. The following capability (as returned by `GetCapabilities`) must be true to use this function.
Capability | Effect
`can_access_local_variables` | Can set and get local variables

Parameters
Name | Type | Description
`thread` | `jthread` | The thread of the frame containing the variable's value. If `thread` is `NULL`, the current thread is used.
`depth` | `jint` | The depth of the frame containing the variable's value.
`slot` | `jint` | The variable's slot number.
`value_ptr` | `jobject*` | On return, points to the variable's value. Agent passes a pointer to a `jobject`. On return, the `jobject` has been set. The object returned by `value_ptr` is a JNI local reference and must be managed.

Errors
This function returns either a universal error or one of the following errors
Error | Description
`JVMTI_ERROR_MUST_POSSESS_CAPABILITY` | The environment does not possess the capability `can_access_local_variables`. Use `AddCapabilities`.
`JVMTI_ERROR_INVALID_SLOT` | Invalid `slot`.
`JVMTI_ERROR_TYPE_MISMATCH` | The variable type is not `Object` or a subclass of `Object`.
`JVMTI_ERROR_OPAQUE_FRAME` | Not a visible frame
`JVMTI_ERROR_INVALID_THREAD` | `thread` is not a thread object.
`JVMTI_ERROR_THREAD_NOT_ALIVE` | `thread` is not live (has not been started or is now dead).
`JVMTI_ERROR_ILLEGAL_ARGUMENT` | `depth` is less than zero.
`JVMTI_ERROR_NO_MORE_FRAMES` | There are no stack frames at the specified `depth`.
`JVMTI_ERROR_NULL_POINTER` | `value_ptr` is `NULL`.

### Get Local Variable - Int

>     jvmtiError
>     GetLocalInt(jvmtiEnv* env,
>                 jthread thread,
>                 jint depth,
>                 jint slot,
>                 jint* value_ptr)

This function can be used to retrieve the value of a local variable whose type is `int`, `short`, `char`, `byte`, or `boolean`.

Phase | Callback Safe | Position | Since
may only be called during the live phase | No | 22 | 1.0

Capabilities
Optional Functionality: might not be implemented for all virtual machines. The following capability (as returned by `GetCapabilities`) must be true to use this function.
Capability | Effect
`can_access_local_variables` | Can set and get local variables

Parameters
Name | Type | Description
`thread` | `jthread` | The thread of the frame containing the variable's value. If `thread` is `NULL`, the current thread is used.
`depth` | `jint` | The depth of the frame containing the variable's value.
`slot` | `jint` | The variable's slot number.
`value_ptr` | `jint*` | On return, points to the variable's value. Agent passes a pointer to a `jint`. On return, the `jint` has been set.

Errors
This function returns either a universal error or one of the following errors
Error | Description
`JVMTI_ERROR_MUST_POSSESS_CAPABILITY` | The environment does not possess the capability `can_access_local_variables`. Use `AddCapabilities`.
`JVMTI_ERROR_INVALID_SLOT` | Invalid `slot`.
`JVMTI_ERROR_TYPE_MISMATCH` | The variable type is not `int`, `short`, `char`, `byte`, or `boolean`.
`JVMTI_ERROR_OPAQUE_FRAME` | Not a visible frame
`JVMTI_ERROR_INVALID_THREAD` | `thread` is not a thread object.
`JVMTI_ERROR_THREAD_NOT_ALIVE` | `thread` is not live (has not been started or is now dead).
`JVMTI_ERROR_ILLEGAL_ARGUMENT` | `depth` is less than zero.
`JVMTI_ERROR_NO_MORE_FRAMES` | There are no stack frames at the specified `depth`.
`JVMTI_ERROR_NULL_POINTER` | `value_ptr` is `NULL`.

### Get Local Variable - Long

>     jvmtiError
>     GetLocalLong(jvmtiEnv* env,
>                 jthread thread,
>                 jint depth,
>                 jint slot,
>                 jlong* value_ptr)

This function can be used to retrieve the value of a local variable whose type is `long`.

Phase | Callback Safe | Position | Since
may only be called during the live phase | No | 23 | 1.0

Capabilities
Optional Functionality: might not be implemented for all virtual machines. The following capability (as returned by `GetCapabilities`) must be true to use this function.
Capability | Effect
`can_access_local_variables` | Can set and get local variables

Parameters
Name | Type | Description
`thread` | `jthread` | The thread of the frame containing the variable's value. If `thread` is `NULL`, the current thread is used.
`depth` | `jint` | The depth of the frame containing the variable's value.
`slot` | `jint` | The variable's slot number.
`value_ptr` | `jlong*` | On return, points to the variable's value. Agent passes a pointer to a `jlong`. On return, the `jlong` has been set.

Errors
This function returns either a universal error or one of the following errors
Error | Description
`JVMTI_ERROR_MUST_POSSESS_CAPABILITY` | The environment does not possess the capability `can_access_local_variables`. Use `AddCapabilities`.
`JVMTI_ERROR_INVALID_SLOT` | Invalid `slot`.
`JVMTI_ERROR_TYPE_MISMATCH` | The variable type is not `long`.
`JVMTI_ERROR_OPAQUE_FRAME` | Not a visible frame
`JVMTI_ERROR_INVALID_THREAD` | `thread` is not a thread object.
`JVMTI_ERROR_THREAD_NOT_ALIVE` | `thread` is not live (has not been started or is now dead).
`JVMTI_ERROR_ILLEGAL_ARGUMENT` | `depth` is less than zero.
`JVMTI_ERROR_NO_MORE_FRAMES` | There are no stack frames at the specified `depth`.
`JVMTI_ERROR_NULL_POINTER` | `value_ptr` is `NULL`.

### Get Local Variable - Float

>     jvmtiError
>     GetLocalFloat(jvmtiEnv* env,
>                 jthread thread,
>                 jint depth,
>                 jint slot,
>                 jfloat* value_ptr)

This function can be used to retrieve the value of a local variable whose type is `float`.

Phase | Callback Safe | Position | Since
may only be called during the live phase | No | 24 | 1.0

Capabilities
Optional Functionality: might not be implemented for all virtual machines. The following capability (as returned by `GetCapabilities`) must be true to use this function.
Capability | Effect
`can_access_local_variables` | Can set and get local variables

Parameters
Name | Type | Description
`thread` | `jthread` | The thread of the frame containing the variable's value. If `thread` is `NULL`, the current thread is used.
`depth` | `jint` | The depth of the frame containing the variable's value.
`slot` | `jint` | The variable's slot number.
`value_ptr` | `jfloat*` | On return, points to the variable's value. Agent passes a pointer to a `jfloat`. On return, the `jfloat` has been set.

Errors
This function returns either a universal error or one of the following errors
Error | Description
`JVMTI_ERROR_MUST_POSSESS_CAPABILITY` | The environment does not possess the capability `can_access_local_variables`. Use `AddCapabilities`.
`JVMTI_ERROR_INVALID_SLOT` | Invalid `slot`.
`JVMTI_ERROR_TYPE_MISMATCH` | The variable type is not `float`.
`JVMTI_ERROR_OPAQUE_FRAME` | Not a visible frame
`JVMTI_ERROR_INVALID_THREAD` | `thread` is not a thread object.
`JVMTI_ERROR_THREAD_NOT_ALIVE` | `thread` is not live (has not been started or is now dead).
`JVMTI_ERROR_ILLEGAL_ARGUMENT` | `depth` is less than zero.
`JVMTI_ERROR_NO_MORE_FRAMES` | There are no stack frames at the specified `depth`.
`JVMTI_ERROR_NULL_POINTER` | `value_ptr` is `NULL`.

### Get Local Variable - Double

>     jvmtiError
>     GetLocalDouble(jvmtiEnv* env,
>                 jthread thread,
>                 jint depth,
>                 jint slot,
>                 jdouble* value_ptr)

This function can be used to retrieve the value of a local variable whose type is `long`.

Phase | Callback Safe | Position | Since
may only be called during the live phase | No | 25 | 1.0

Capabilities
Optional Functionality: might not be implemented for all virtual machines. The following capability (as returned by `GetCapabilities`) must be true to use this function.
Capability | Effect
`can_access_local_variables` | Can set and get local variables

Parameters
Name | Type | Description
`thread` | `jthread` | The thread of the frame containing the variable's value. If `thread` is `NULL`, the current thread is used.
`depth` | `jint` | The depth of the frame containing the variable's value.
`slot` | `jint` | The variable's slot number.
`value_ptr` | `jdouble*` | On return, points to the variable's value. Agent passes a pointer to a `jdouble`. On return, the `jdouble` has been set.

Errors
This function returns either a universal error or one of the following errors
Error | Description
`JVMTI_ERROR_MUST_POSSESS_CAPABILITY` | The environment does not possess the capability `can_access_local_variables`. Use `AddCapabilities`.
`JVMTI_ERROR_INVALID_SLOT` | Invalid `slot`.
`JVMTI_ERROR_TYPE_MISMATCH` | The variable type is not `double`.
`JVMTI_ERROR_OPAQUE_FRAME` | Not a visible frame
`JVMTI_ERROR_INVALID_THREAD` | `thread` is not a thread object.
`JVMTI_ERROR_THREAD_NOT_ALIVE` | `thread` is not live (has not been started or is now dead).
`JVMTI_ERROR_ILLEGAL_ARGUMENT` | `depth` is less than zero.
`JVMTI_ERROR_NO_MORE_FRAMES` | There are no stack frames at the specified `depth`.
`JVMTI_ERROR_NULL_POINTER` | `value_ptr` is `NULL`.

### Set Local Variable - Object

>     jvmtiError
>     SetLocalObject(jvmtiEnv* env,
>                 jthread thread,
>                 jint depth,
>                 jint slot,
>                 jobject value)

This function can be used to set the value of a local variable whose type is `Object` or a subclass of `Object`.

Phase | Callback Safe | Position | Since
may only be called during the live phase | No | 26 | 1.0

Capabilities
Optional Functionality: might not be implemented for all virtual machines. The following capability (as returned by `GetCapabilities`) must be true to use this function.
Capability | Effect
`can_access_local_variables` | Can set and get local variables

Parameters
Name | Type | Description
`thread` | `jthread` | The thread of the frame containing the variable's value. If `thread` is `NULL`, the current thread is used.
`depth` | `jint` | The depth of the frame containing the variable's value.
`slot` | `jint` | The variable's slot number.
`value` | `jobject` | The new value for the variable.

Errors
This function returns either a universal error or one of the following errors
Error | Description
`JVMTI_ERROR_MUST_POSSESS_CAPABILITY` | The environment does not possess the capability `can_access_local_variables`. Use `AddCapabilities`.
`JVMTI_ERROR_INVALID_SLOT` | Invalid `slot`.
`JVMTI_ERROR_TYPE_MISMATCH` | The variable type is not `Object` or a subclass of `Object`.
`JVMTI_ERROR_TYPE_MISMATCH` | The supplied `value` is not compatible with the variable type.
`JVMTI_ERROR_OPAQUE_FRAME` | Not a visible frame
`JVMTI_ERROR_INVALID_THREAD` | `thread` is not a thread object.
`JVMTI_ERROR_THREAD_NOT_ALIVE` | `thread` is not live (has not been started or is now dead).
`JVMTI_ERROR_ILLEGAL_ARGUMENT` | `depth` is less than zero.
`JVMTI_ERROR_NO_MORE_FRAMES` | There are no stack frames at the specified `depth`.
`JVMTI_ERROR_INVALID_OBJECT` | `value` is not an object.

### Set Local Variable - Int

>     jvmtiError
>     SetLocalInt(jvmtiEnv* env,
>                 jthread thread,
>                 jint depth,
>                 jint slot,
>                 jint value)

This function can be used to set the value of a local variable whose type is `int`, `short`, `char`, `byte`, or `boolean`.

Phase | Callback Safe | Position | Since
may only be called during the live phase | No | 27 | 1.0

Capabilities
Optional Functionality: might not be implemented for all virtual machines. The following capability (as returned by `GetCapabilities`) must be true to use this function.
Capability | Effect
`can_access_local_variables` | Can set and get local variables

Parameters
Name | Type | Description
`thread` | `jthread` | The thread of the frame containing the variable's value. If `thread` is `NULL`, the current thread is used.
`depth` | `jint` | The depth of the frame containing the variable's value.
`slot` | `jint` | The variable's slot number.
`value` | `jint` | The new value for the variable.

Errors
This function returns either a universal error or one of the following errors
Error | Description
`JVMTI_ERROR_MUST_POSSESS_CAPABILITY` | The environment does not possess the capability `can_access_local_variables`. Use `AddCapabilities`.
`JVMTI_ERROR_INVALID_SLOT` | Invalid `slot`.
`JVMTI_ERROR_TYPE_MISMATCH` | The variable type is not `int`, `short`, `char`, `byte`, or `boolean`.
`JVMTI_ERROR_OPAQUE_FRAME` | Not a visible frame
`JVMTI_ERROR_INVALID_THREAD` | `thread` is not a thread object.
`JVMTI_ERROR_THREAD_NOT_ALIVE` | `thread` is not live (has not been started or is now dead).
`JVMTI_ERROR_ILLEGAL_ARGUMENT` | `depth` is less than zero.
`JVMTI_ERROR_NO_MORE_FRAMES` | There are no stack frames at the specified `depth`.

### Set Local Variable - Long

>     jvmtiError
>     SetLocalLong(jvmtiEnv* env,
>                 jthread thread,
>                 jint depth,
>                 jint slot,
>                 jlong value)

This function can be used to set the value of a local variable whose type is `long`.

Phase | Callback Safe | Position | Since
may only be called during the live phase | No | 28 | 1.0

Capabilities
Optional Functionality: might not be implemented for all virtual machines. The following capability (as returned by `GetCapabilities`) must be true to use this function.
Capability | Effect
`can_access_local_variables` | Can set and get local variables

Parameters
Name | Type | Description
`thread` | `jthread` | The thread of the frame containing the variable's value. If `thread` is `NULL`, the current thread is used.
`depth` | `jint` | The depth of the frame containing the variable's value.
`slot` | `jint` | The variable's slot number.
`value` | `jlong` | The new value for the variable.

Errors
This function returns either a universal error or one of the following errors
Error | Description
`JVMTI_ERROR_MUST_POSSESS_CAPABILITY` | The environment does not possess the capability `can_access_local_variables`. Use `AddCapabilities`.
`JVMTI_ERROR_INVALID_SLOT` | Invalid `slot`.
`JVMTI_ERROR_TYPE_MISMATCH` | The variable type is not `long`.
`JVMTI_ERROR_OPAQUE_FRAME` | Not a visible frame
`JVMTI_ERROR_INVALID_THREAD` | `thread` is not a thread object.
`JVMTI_ERROR_THREAD_NOT_ALIVE` | `thread` is not live (has not been started or is now dead).
`JVMTI_ERROR_ILLEGAL_ARGUMENT` | `depth` is less than zero.
`JVMTI_ERROR_NO_MORE_FRAMES` | There are no stack frames at the specified `depth`.

### Set Local Variable - Float

>     jvmtiError
>     SetLocalFloat(jvmtiEnv* env,
>                 jthread thread,
>                 jint depth,
>                 jint slot,
>                 jfloat value)

This function can be used to set the value of a local variable whose type is `float`.

Phase | Callback Safe | Position | Since
may only be called during the live phase | No | 29 | 1.0

Capabilities
Optional Functionality: might not be implemented for all virtual machines. The following capability (as returned by `GetCapabilities`) must be true to use this function.
Capability | Effect
`can_access_local_variables` | Can set and get local variables

Parameters
Name | Type | Description
`thread` | `jthread` | The thread of the frame containing the variable's value. If `thread` is `NULL`, the current thread is used.
`depth` | `jint` | The depth of the frame containing the variable's value.
`slot` | `jint` | The variable's slot number.
`value` | `jfloat` | The new value for the variable.

Errors
This function returns either a universal error or one of the following errors
Error | Description
`JVMTI_ERROR_MUST_POSSESS_CAPABILITY` | The environment does not possess the capability `can_access_local_variables`. Use `AddCapabilities`.
`JVMTI_ERROR_INVALID_SLOT` | Invalid `slot`.
`JVMTI_ERROR_TYPE_MISMATCH` | The variable type is not `float`.
`JVMTI_ERROR_OPAQUE_FRAME` | Not a visible frame
`JVMTI_ERROR_INVALID_THREAD` | `thread` is not a thread object.
`JVMTI_ERROR_THREAD_NOT_ALIVE` | `thread` is not live (has not been started or is now dead).
`JVMTI_ERROR_ILLEGAL_ARGUMENT` | `depth` is less than zero.
`JVMTI_ERROR_NO_MORE_FRAMES` | There are no stack frames at the specified `depth`.

### Set Local Variable - Double

>     jvmtiError
>     SetLocalDouble(jvmtiEnv* env,
>                 jthread thread,
>                 jint depth,
>                 jint slot,
>                 jdouble value)

This function can be used to set the value of a local variable whose type is `double`.

Phase | Callback Safe | Position | Since
may only be called during the live phase | No | 30 | 1.0

Capabilities
Optional Functionality: might not be implemented for all virtual machines. The following capability (as returned by `GetCapabilities`) must be true to use this function.
Capability | Effect
`can_access_local_variables` | Can set and get local variables

Parameters
Name | Type | Description
`thread` | `jthread` | The thread of the frame containing the variable's value. If `thread` is `NULL`, the current thread is used.
`depth` | `jint` | The depth of the frame containing the variable's value.
`slot` | `jint` | The variable's slot number.
`value` | `jdouble` | The new value for the variable.

Errors
This function returns either a universal error or one of the following errors
Error | Description
`JVMTI_ERROR_MUST_POSSESS_CAPABILITY` | The environment does not possess the capability `can_access_local_variables`. Use `AddCapabilities`.
`JVMTI_ERROR_INVALID_SLOT` | Invalid `slot`.
`JVMTI_ERROR_TYPE_MISMATCH` | The variable type is not `double`.
`JVMTI_ERROR_OPAQUE_FRAME` | Not a visible frame
`JVMTI_ERROR_INVALID_THREAD` | `thread` is not a thread object.
`JVMTI_ERROR_THREAD_NOT_ALIVE` | `thread` is not live (has not been started or is now dead).
`JVMTI_ERROR_ILLEGAL_ARGUMENT` | `depth` is less than zero.
`JVMTI_ERROR_NO_MORE_FRAMES` | There are no stack frames at the specified `depth`.

## Breakpoint

Breakpoint functions:

- Set Breakpoint
- Clear Breakpoint

### Set Breakpoint

>     jvmtiError
>     SetBreakpoint(jvmtiEnv* env,
>                 jmethodID method,
>                 jlocation location)

Set a breakpoint at the instruction indicated by `method` and `location`. An instruction can only have one breakpoint.

Whenever the designated instruction is about to be executed, a `Breakpoint` event is generated.

Phase | Callback Safe | Position | Since
may only be called during the live phase | No | 38 | 1.0

Capabilities
Optional Functionality: might not be implemented for all virtual machines. The following capability (as returned by `GetCapabilities`) must be true to use this function.
Capability | Effect
`can_generate_breakpoint_events` | Can set and thus get `Breakpoint` events

Parameters
Name | Type | Description
`method` | `jmethodID` | The method in which to set the breakpoint
`location` | `jlocation` | the index of the instruction at which to set the breakpoint

Errors
This function returns either a universal error or one of the following errors
Error | Description
`JVMTI_ERROR_MUST_POSSESS_CAPABILITY` | The environment does not possess the capability `can_generate_breakpoint_events`. Use `AddCapabilities`.
`JVMTI_ERROR_DUPLICATE` | The designated bytecode already has a breakpoint.
`JVMTI_ERROR_INVALID_METHODID` | `method` is not a jmethodID.
`JVMTI_ERROR_INVALID_LOCATION` | `location` is not a valid location.

### Clear Breakpoint

>     jvmtiError
>     ClearBreakpoint(jvmtiEnv* env,
>                 jmethodID method,
>                 jlocation location)

Clear the breakpoint at the bytecode indicated by `method` and `location`.

Phase | Callback Safe | Position | Since
may only be called during the live phase | No | 39 | 1.0

Capabilities
Optional Functionality: might not be implemented for all virtual machines. The following capability (as returned by `GetCapabilities`) must be true to use this function.
Capability | Effect
`can_generate_breakpoint_events` | Can set and thus get `Breakpoint` events

Parameters
Name | Type | Description
`method` | `jmethodID` | The method in which to clear the breakpoint
`location` | `jlocation` | the index of the instruction at which to clear the breakpoint

Errors
This function returns either a universal error or one of the following errors
Error | Description
`JVMTI_ERROR_MUST_POSSESS_CAPABILITY` | The environment does not possess the capability `can_generate_breakpoint_events`. Use `AddCapabilities`.
`JVMTI_ERROR_NOT_FOUND` | There's no breakpoint at the designated bytecode.
`JVMTI_ERROR_INVALID_METHODID` | `method` is not a jmethodID.
`JVMTI_ERROR_INVALID_LOCATION` | `location` is not a valid location.

## Watched Field

Watched Field functions:

- Set Field Access Watch
- Clear Field Access Watch
- Set Field Modification Watch
- Clear Field Modification Watch

### Set Field Access Watch

>     jvmtiError
>     SetFieldAccessWatch(jvmtiEnv* env,
>                 jclass klass,
>                 jfieldID field)

Generate a `FieldAccess` event when the field specified by `klass` and `field` is about to be accessed. An event will be generated for each access of the field until it is canceled with `ClearFieldAccessWatch`. Field accesses from Java programming language code or from JNI code are watched, fields modified by other means are not watched. Note that JVM TI users should be aware that their own field accesses will trigger the watch. A field can only have one field access watch set. Modification of a field is not considered an access--use `SetFieldModificationWatch` to monitor modifications.

Phase | Callback Safe | Position | Since
may only be called during the live phase | No | 41 | 1.0

Capabilities
Optional Functionality: might not be implemented for all virtual machines. The following capability (as returned by `GetCapabilities`) must be true to use this function.
Capability | Effect
`can_generate_field_access_events` | Can set watchpoints on field access - `SetFieldAccessWatch`

Parameters
Name | Type | Description
`klass` | `jclass` | The class containing the field to watch
`field` | `jfieldID` | The field to watch

Errors
This function returns either a universal error or one of the following errors
Error | Description
`JVMTI_ERROR_MUST_POSSESS_CAPABILITY` | The environment does not possess the capability `can_generate_field_access_events`. Use `AddCapabilities`.
`JVMTI_ERROR_DUPLICATE` | The designated field is already being watched for accesses.
`JVMTI_ERROR_INVALID_CLASS` | `klass` is not a class object or the class has been unloaded.
`JVMTI_ERROR_INVALID_FIELDID` | `field` is not a jfieldID.

### Clear Field Access Watch

>     jvmtiError
>     ClearFieldAccessWatch(jvmtiEnv* env,
>                 jclass klass,
>                 jfieldID field)

Cancel a field access watch previously set by `SetFieldAccessWatch`, on the field specified by `klass` and `field`.

Phase | Callback Safe | Position | Since
may only be called during the live phase | No | 42 | 1.0

Capabilities
Optional Functionality: might not be implemented for all virtual machines. The following capability (as returned by `GetCapabilities`) must be true to use this function.
Capability | Effect
`can_generate_field_access_events` | Can set watchpoints on field access - `SetFieldAccessWatch`

Parameters
Name | Type | Description
`klass` | `jclass` | The class containing the field to watch
`field` | `jfieldID` | The field to watch

Errors
This function returns either a universal error or one of the following errors
Error | Description
`JVMTI_ERROR_MUST_POSSESS_CAPABILITY` | The environment does not possess the capability `can_generate_field_access_events`. Use `AddCapabilities`.
`JVMTI_ERROR_NOT_FOUND` | The designated field is not being watched for accesses.
`JVMTI_ERROR_INVALID_CLASS` | `klass` is not a class object or the class has been unloaded.
`JVMTI_ERROR_INVALID_FIELDID` | `field` is not a jfieldID.

### Set Field Modification Watch

>     jvmtiError
>     SetFieldModificationWatch(jvmtiEnv* env,
>                 jclass klass,
>                 jfieldID field)

Generate a `FieldModification` event when the field specified by `klass` and `field` is about to be modified. An event will be generated for each modification of the field until it is canceled with `ClearFieldModificationWatch`. Field modifications from Java programming language code or from JNI code are watched, fields modified by other means are not watched. Note that JVM TI users should be aware that their own field modifications will trigger the watch. A field can only have one field modification watch set.

Phase | Callback Safe | Position | Since
may only be called during the live phase | No | 43 | 1.0

Capabilities
Optional Functionality: might not be implemented for all virtual machines. The following capability (as returned by `GetCapabilities`) must be true to use this function.
Capability | Effect
`can_generate_field_modification_events` | Can set watchpoints on field modification - `SetFieldModificationWatch`

Parameters
Name | Type | Description
`klass` | `jclass` | The class containing the field to watch
`field` | `jfieldID` | The field to watch

Errors
This function returns either a universal error or one of the following errors
Error | Description
`JVMTI_ERROR_MUST_POSSESS_CAPABILITY` | The environment does not possess the capability `can_generate_field_modification_events`. Use `AddCapabilities`.
`JVMTI_ERROR_DUPLICATE` | The designated field is already being watched for modifications.
`JVMTI_ERROR_INVALID_CLASS` | `klass` is not a class object or the class has been unloaded.
`JVMTI_ERROR_INVALID_FIELDID` | `field` is not a jfieldID.

### Clear Field Modification Watch

>     jvmtiError
>     ClearFieldModificationWatch(jvmtiEnv* env,
>                 jclass klass,
>                 jfieldID field)

Cancel a field modification watch previously set by `SetFieldModificationWatch`, on the field specified by `klass` and `field`.

Phase | Callback Safe | Position | Since
may only be called during the live phase | No | 44 | 1.0

Capabilities
Optional Functionality: might not be implemented for all virtual machines. The following capability (as returned by `GetCapabilities`) must be true to use this function.
Capability | Effect
`can_generate_field_modification_events` | Can set watchpoints on field modification - `SetFieldModificationWatch`

Parameters
Name | Type | Description
`klass` | `jclass` | The class containing the field to watch
`field` | `jfieldID` | The field to watch

Errors
This function returns either a universal error or one of the following errors
Error | Description
`JVMTI_ERROR_MUST_POSSESS_CAPABILITY` | The environment does not possess the capability `can_generate_field_modification_events`. Use `AddCapabilities`.
`JVMTI_ERROR_NOT_FOUND` | The designated field is not being watched for modifications.
`JVMTI_ERROR_INVALID_CLASS` | `klass` is not a class object or the class has been unloaded.
`JVMTI_ERROR_INVALID_FIELDID` | `field` is not a jfieldID.

## Class

Class functions:

- Get Loaded Classes
- Get Classloader Classes
- Get Class Signature
- Get Class Status
- Get Source File Name
- Get Class Modifiers
- Get Class Methods
- Get Class Fields
- Get Implemented Interfaces
- Get Class Version Numbers
- Get Constant Pool
- Is Interface
- Is Array Class
- Is Modifiable Class
- Get Class Loader
- Get Source Debug Extension
- Retransform Classes
- Redefine Classes

Class types:

- `jvmtiClassDefinition` - Class redefinition description

Class flags and constants:

- Class Status Flags

### Get Loaded Classes

>     jvmtiError
>     GetLoadedClasses(jvmtiEnv* env,
>                 jint* class_count_ptr,
>                 jclass** classes_ptr)

Return an array of all classes loaded in the virtual machine. The number of classes in the array is returned via `class_count_ptr`, and the array itself via `classes_ptr`.

Array classes of all types (including arrays of primitive types) are included in the returned list. Primitive classes (for example, `java.lang.Integer.TYPE`) are not included in this list.

Phase | Callback Safe | Position | Since
may only be called during the live phase | No | 78 | 1.0

Capabilities
Required Functionality

Parameters
Name | Type | Description
`class_count_ptr` | `jint*` | On return, points to the number of classes. Agent passes a pointer to a `jint`. On return, the `jint` has been set.
`classes_ptr` | `jclass**` | On return, points to an array of references, one for each class. Agent passes a pointer to a `jclass*`. On return, the `jclass*` points to a newly allocated array of size `*class_count_ptr`. The array should be freed with `Deallocate`. The objects returned by `classes_ptr` are JNI local references and must be managed.

Errors
This function returns either a universal error or one of the following errors
Error | Description
`JVMTI_ERROR_NULL_POINTER` | `class_count_ptr` is `NULL`.
`JVMTI_ERROR_NULL_POINTER` | `classes_ptr` is `NULL`.

### Get Classloader Classes

>     jvmtiError
>     GetClassLoaderClasses(jvmtiEnv* env,
>                 jobject initiating_loader,
>                 jint* class_count_ptr,
>                 jclass** classes_ptr)

Returns an array of those classes for which this class loader has been recorded as an initiating loader. Each class in the returned array was created by this class loader, either by defining it directly or by delegation to another class loader. See the Creation and Loading section of the Java Virtual Machine Specification.

For JDK version 1.1 implementations that don't recognize the distinction between initiating and defining class loaders, this function should return all classes loaded in the virtual machine. The number of classes in the array is returned via `class_count_ptr`, and the array itself via `classes_ptr`.

Phase | Callback Safe | Position | Since
may only be called during the live phase | No | 79 | 1.0

Capabilities
Required Functionality

Parameters
Name | Type | Description
`initiating_loader` | `jobject` | An initiating class loader. If `initiating_loader` is `NULL`, the classes initiated by the bootstrap loader will be returned.
`class_count_ptr` | `jint*` | On return, points to the number of classes. Agent passes a pointer to a `jint`. On return, the `jint` has been set.
`classes_ptr` | `jclass**` | On return, points to an array of references, one for each class. Agent passes a pointer to a `jclass*`. On return, the `jclass*` points to a newly allocated array of size `*class_count_ptr`. The array should be freed with `Deallocate`. The objects returned by `classes_ptr` are JNI local references and must be managed.

Errors
This function returns either a universal error or one of the following errors
Error | Description
`JVMTI_ERROR_NULL_POINTER` | `class_count_ptr` is `NULL`.
`JVMTI_ERROR_NULL_POINTER` | `classes_ptr` is `NULL`.

### Get Class Signature

>     jvmtiError
>     GetClassSignature(jvmtiEnv* env,
>                 jclass klass,
>                 char** signature_ptr,
>                 char** generic_ptr)

For the class indicated by `klass`, return the JNI type signature and the generic signature of the class. For example, `java.util.List` is `"Ljava/util/List;"` and `int[]` is `"[I"` The returned name for primitive classes is the type signature character of the corresponding primitive type. For example, `java.lang.Integer.TYPE` is `"I"`.

Phase | Callback Safe | Position | Since
may only be called during the start or the live phase | No | 48 | 1.0

Capabilities
Required Functionality

Parameters
Name | Type | Description
`klass` | `jclass` | The class to query.
`signature_ptr` | `char **` | On return, points to the JNI type signature of the class, encoded as a modified UTF-8 string. Agent passes a pointer to a `char*`. On return, the `char*` points to a newly allocated array. The array should be freed with `Deallocate`. If `signature_ptr` is `NULL`, the signature is not returned.
`generic_ptr` | `char **` | On return, points to the generic signature of the class, encoded as a modified UTF-8 string. If there is no generic signature attribute for the class, then, on return, points to `NULL`. Agent passes a pointer to a `char*`. On return, the `char*` points to a newly allocated array. The array should be freed with `Deallocate`. If `generic_ptr` is `NULL`, the generic signature is not returned.

Errors
This function returns either a universal error or one of the following errors
Error | Description
`JVMTI_ERROR_INVALID_CLASS` | `klass` is not a class object or the class has been unloaded.

### Get Class Status

>     jvmtiError
>     GetClassStatus(jvmtiEnv* env,
>                 jclass klass,
>                 jint* status_ptr)

Get the status of the class. Zero or more of the following bits can be set.

> Class Status Flags
> Constant | Value | Description
> `JVMTI_CLASS_STATUS_VERIFIED` | 1 | Class bytecodes have been verified
> `JVMTI_CLASS_STATUS_PREPARED` | 2 | Class preparation is complete
> `JVMTI_CLASS_STATUS_INITIALIZED` | 4 | Class initialization is complete. Static initializer has been run.
> `JVMTI_CLASS_STATUS_ERROR` | 8 | Error during initialization makes class unusable
> `JVMTI_CLASS_STATUS_ARRAY` | 16 | Class is an array. If set, all other bits are zero.
> `JVMTI_CLASS_STATUS_PRIMITIVE` | 32 | Class is a primitive class (for example, `java.lang.Integer.TYPE`). If set, all other bits are zero.

Phase | Callback Safe | Position | Since
may only be called during the start or the live phase | No | 49 | 1.0

Capabilities
Required Functionality

Parameters
Name | Type | Description
`klass` | `jclass` | The class to query.
`status_ptr` | `jint*` | On return, points to the current state of this class as one or more of the class status flags. Agent passes a pointer to a `jint`. On return, the `jint` has been set.

Errors
This function returns either a universal error or one of the following errors
Error | Description
`JVMTI_ERROR_INVALID_CLASS` | `klass` is not a class object or the class has been unloaded.
`JVMTI_ERROR_NULL_POINTER` | `status_ptr` is `NULL`.

### Get Source File Name

>     jvmtiError
>     GetSourceFileName(jvmtiEnv* env,
>                 jclass klass,
>                 char** source_name_ptr)

For the class indicated by `klass`, return the source file name via `source_name_ptr`. The returned string is a file name only and never contains a directory name.

For primitive classes (for example, `java.lang.Integer.TYPE`) and for arrays this function returns `JVMTI_ERROR_ABSENT_INFORMATION`.

Phase | Callback Safe | Position | Since
may only be called during the start or the live phase | No | 50 | 1.0

Capabilities
Optional Functionality: might not be implemented for all virtual machines. The following capability (as returned by `GetCapabilities`) must be true to use this function.
Capability | Effect
`can_get_source_file_name` | Can get the source file name of a class

Parameters
Name | Type | Description
`klass` | `jclass` | The class to query.
`source_name_ptr` | `char**` | On return, points to the class's source file name, encoded as a modified UTF-8 string. Agent passes a pointer to a `char*`. On return, the `char*` points to a newly allocated array. The array should be freed with `Deallocate`.

Errors
This function returns either a universal error or one of the following errors
Error | Description
`JVMTI_ERROR_MUST_POSSESS_CAPABILITY` | The environment does not possess the capability `can_get_source_file_name`. Use `AddCapabilities`.
`JVMTI_ERROR_ABSENT_INFORMATION` | Class information does not include a source file name. This includes cases where the class is an array class or primitive class.
`JVMTI_ERROR_INVALID_CLASS` | `klass` is not a class object or the class has been unloaded.
`JVMTI_ERROR_NULL_POINTER` | `source_name_ptr` is `NULL`.

### Get Class Modifiers

>     jvmtiError
>     GetClassModifiers(jvmtiEnv* env,
>                 jclass klass,
>                 jint* modifiers_ptr)

For the class indicated by `klass`, return the access flags via `modifiers_ptr`. Access flags are defined in the Class File Format chapter of the Java Virtual Machine Specification.

If the class is an array class, then its public, private, and protected modifiers are the same as those of its component type. For arrays of primitives, this component type is represented by one of the primitive classes (for example, `java.lang.Integer.TYPE`).

If the class is a primitive class, its public modifier is always true, and its protected and private modifiers are always false.

If the class is an array class or a primitive class then its final modifier is always true and its interface modifier is always false. The values of its other modifiers are not determined by this specification.

Phase | Callback Safe | Position | Since
may only be called during the start or the live phase | No | 51 | 1.0

Capabilities
Required Functionality

Parameters
Name | Type | Description
`klass` | `jclass` | The class to query.
`modifiers_ptr` | `jint*` | On return, points to the current access flags of this class. Agent passes a pointer to a `jint`. On return, the `jint` has been set.

Errors
This function returns either a universal error or one of the following errors
Error | Description
`JVMTI_ERROR_INVALID_CLASS` | `klass` is not a class object or the class has been unloaded.
`JVMTI_ERROR_NULL_POINTER` | `modifiers_ptr` is `NULL`.

### Get Class Methods

>     jvmtiError
>     GetClassMethods(jvmtiEnv* env,
>                 jclass klass,
>                 jint* method_count_ptr,
>                 jmethodID** methods_ptr)

For the class indicated by `klass`, return a count of methods via `method_count_ptr` and a list of method IDs via `methods_ptr`. The method list contains constructors and static initializers as well as true methods. Only directly declared methods are returned (not inherited methods). An empty method list is returned for array classes and primitive classes (for example, `java.lang.Integer.TYPE`).

Phase | Callback Safe | Position | Since
may only be called during the start or the live phase | No | 52 | 1.0

Capabilities
Required Functionality
Optional Features
Capability | Effect
`can_maintain_original_method_order` | Can return methods in the order they occur in the class file

Parameters
Name | Type | Description
`klass` | `jclass` | The class to query.
`method_count_ptr` | `jint*` | On return, points to the number of methods declared in this class. Agent passes a pointer to a `jint`. On return, the `jint` has been set.
`methods_ptr` | `jmethodID**` | On return, points to the method ID array. Agent passes a pointer to a `jmethodID*`. On return, the `jmethodID*` points to a newly allocated array of size `*method_count_ptr`. The array should be freed with `Deallocate`.

Errors
This function returns either a universal error or one of the following errors
Error | Description
`JVMTI_ERROR_CLASS_NOT_PREPARED` | `klass` is not prepared.
`JVMTI_ERROR_INVALID_CLASS` | `klass` is not a class object or the class has been unloaded.
`JVMTI_ERROR_NULL_POINTER` | `method_count_ptr` is `NULL`.
`JVMTI_ERROR_NULL_POINTER` | `methods_ptr` is `NULL`.

### Get Class Fields

>     jvmtiError
>     GetClassFields(jvmtiEnv* env,
>                 jclass klass,
>                 jint* field_count_ptr,
>                 jfieldID** fields_ptr)

For the class indicated by `klass`, return a count of fields via `field_count_ptr` and a list of field IDs via `fields_ptr`. Only directly declared fields are returned (not inherited fields). Fields are returned in the order they occur in the class file. An empty field list is returned for array classes and primitive classes (for example, `java.lang.Integer.TYPE`). Use JNI to determine the length of an array.

Phase | Callback Safe | Position | Since
may only be called during the start or the live phase | No | 53 | 1.0

Capabilities
Required Functionality

Parameters
Name | Type | Description
`klass` | `jclass` | The class to query.
`field_count_ptr` | `jint*` | On return, points to the number of fields declared in this class. Agent passes a pointer to a `jint`. On return, the `jint` has been set.
`fields_ptr` | `jfieldID**` | On return, points to the field ID array. Agent passes a pointer to a `jfieldID*`. On return, the `jfieldID*` points to a newly allocated array of size `*field_count_ptr`. The array should be freed with `Deallocate`.

Errors
This function returns either a universal error or one of the following errors
Error | Description
`JVMTI_ERROR_CLASS_NOT_PREPARED` | `klass` is not prepared.
`JVMTI_ERROR_INVALID_CLASS` | `klass` is not a class object or the class has been unloaded.
`JVMTI_ERROR_NULL_POINTER` | `field_count_ptr` is `NULL`.
`JVMTI_ERROR_NULL_POINTER` | `fields_ptr` is `NULL`.

### Get Implemented Interfaces

>     jvmtiError
>     GetImplementedInterfaces(jvmtiEnv* env,
>                 jclass klass,
>                 jint* interface_count_ptr,
>                 jclass** interfaces_ptr)

Return the direct super-interfaces of this class. For a class, this function returns the interfaces declared in its `implements` clause. For an interface, this function returns the interfaces declared in its `extends` clause. An empty interface list is returned for array classes and primitive classes (for example, `java.lang.Integer.TYPE`).

Phase | Callback Safe | Position | Since
may only be called during the start or the live phase | No | 54 | 1.0

Capabilities
Required Functionality

Parameters
Name | Type | Description
`klass` | `jclass` | The class to query.
`interface_count_ptr` | `jint*` | On return, points to the number of interfaces. Agent passes a pointer to a `jint`. On return, the `jint` has been set.
`interfaces_ptr` | `jclass**` | On return, points to the interface array. Agent passes a pointer to a `jclass*`. On return, the `jclass*` points to a newly allocated array of size `*interface_count_ptr`. The array should be freed with `Deallocate`. The objects returned by `interfaces_ptr` are JNI local references and must be managed.

Errors
This function returns either a universal error or one of the following errors
Error | Description
`JVMTI_ERROR_CLASS_NOT_PREPARED` | `klass` is not prepared.
`JVMTI_ERROR_INVALID_CLASS` | `klass` is not a class object or the class has been unloaded.
`JVMTI_ERROR_NULL_POINTER` | `interface_count_ptr` is `NULL`.
`JVMTI_ERROR_NULL_POINTER` | `interfaces_ptr` is `NULL`.

### Get Class Version Numbers

>     jvmtiError
>     GetClassVersionNumbers(jvmtiEnv* env,
>                 jclass klass,
>                 jint* minor_version_ptr,
>                 jint* major_version_ptr)

For the class indicated by `klass`, return the minor and major version numbers, as defined in the Class File Format chapter of the Java Virtual Machine Specification.

Phase | Callback Safe | Position | Since
may only be called during the start or the live phase | No | 145 | 1.1

Capabilities
Required Functionality

Parameters
Name | Type | Description
`klass` | `jclass` | The class to query.
`minor_version_ptr` | `jint*` | On return, points to the value of the `minor_version` item of the Class File Format. Note: to be consistent with the Class File Format, the minor version number is the first parameter. Agent passes a pointer to a `jint`. On return, the `jint` has been set.
`major_version_ptr` | `jint*` | On return, points to the value of the `major_version` item of the Class File Format. Agent passes a pointer to a `jint`. On return, the `jint` has been set.

Errors
This function returns either a universal error or one of the following errors
Error | Description
`JVMTI_ERROR_ABSENT_INFORMATION` | The class is a primitive or array class.
`JVMTI_ERROR_INVALID_CLASS` | `klass` is not a class object or the class has been unloaded.
`JVMTI_ERROR_NULL_POINTER` | `minor_version_ptr` is `NULL`.
`JVMTI_ERROR_NULL_POINTER` | `major_version_ptr` is `NULL`.

### Get Constant Pool

>     jvmtiError
>     GetConstantPool(jvmtiEnv* env,
>                 jclass klass,
>                 jint* constant_pool_count_ptr,
>                 jint* constant_pool_byte_count_ptr,
>                 unsigned char** constant_pool_bytes_ptr)

For the class indicated by `klass`, return the raw bytes of the constant pool in the format of the `constant_pool` item of the Class File Format in the Java Virtual Machine Specification. The format of the constant pool may differ between versions of the Class File Format, so, the minor and major class version numbers should be checked for compatibility.

The returned constant pool might not have the same layout or contents as the constant pool in the defining class file. The constant pool returned by GetConstantPool() may have more or fewer entries than the defining constant pool. Entries may be in a different order. The constant pool returned by GetConstantPool() will match the constant pool used by GetBytecodes(). That is, the bytecodes returned by GetBytecodes() will have constant pool indices which refer to constant pool entries returned by GetConstantPool(). Note that since `RetransformClasses` and `RedefineClasses` can change the constant pool, the constant pool returned by this function can change accordingly. Thus, the correspondence between GetConstantPool() and GetBytecodes() does not hold if there is an intervening class retransformation or redefinition. The value of a constant pool entry used by a given bytecode will match that of the defining class file (even if the indices don't match). Constant pool entries which are not used directly or indirectly by bytecodes (for example, UTF-8 strings associated with annotations) are not required to exist in the returned constant pool.

Phase | Callback Safe | Position | Since
may only be called during the start or the live phase | No | 146 | 1.1

Capabilities
Optional Functionality: might not be implemented for all virtual machines. The following capability (as returned by `GetCapabilities`) must be true to use this function.
Capability | Effect
`can_get_constant_pool` | Can get the constant pool of a class - `GetConstantPool`

Parameters
Name | Type | Description
`klass` | `jclass` | The class to query.
`constant_pool_count_ptr` | `jint*` | On return, points to the number of entries in the constant pool table plus one. This corresponds to the `constant_pool_count` item of the Class File Format. Agent passes a pointer to a `jint`. On return, the `jint` has been set.
`constant_pool_byte_count_ptr` | `jint*` | On return, points to the number of bytes in the returned raw constant pool. Agent passes a pointer to a `jint`. On return, the `jint` has been set.
`constant_pool_bytes_ptr` | `unsigned char**` | On return, points to the raw constant pool, that is the bytes defined by the `constant_pool` item of the Class File Format Agent passes a pointer to a `unsigned char*`. On return, the `unsigned char*` points to a newly allocated array of size `*constant_pool_byte_count_ptr`. The array should be freed with `Deallocate`.

Errors
This function returns either a universal error or one of the following errors
Error | Description
`JVMTI_ERROR_MUST_POSSESS_CAPABILITY` | The environment does not possess the capability `can_get_constant_pool`. Use `AddCapabilities`.
`JVMTI_ERROR_ABSENT_INFORMATION` | The class is a primitive or array class.
`JVMTI_ERROR_INVALID_CLASS` | `klass` is not a class object or the class has been unloaded.
`JVMTI_ERROR_NULL_POINTER` | `constant_pool_count_ptr` is `NULL`.
`JVMTI_ERROR_NULL_POINTER` | `constant_pool_byte_count_ptr` is `NULL`.
`JVMTI_ERROR_NULL_POINTER` | `constant_pool_bytes_ptr` is `NULL`.

### Is Interface

>     jvmtiError
>     IsInterface(jvmtiEnv* env,
>                 jclass klass,
>                 jboolean* is_interface_ptr)

Determines whether a class object reference represents an interface. The `jboolean` result is `JNI_TRUE` if the "class" is actually an interface, `JNI_FALSE` otherwise.

Phase | Callback Safe | Position | Since
may only be called during the start or the live phase | No | 55 | 1.0

Capabilities
Required Functionality

Parameters
Name | Type | Description
`klass` | `jclass` | The class to query.
`is_interface_ptr` | `jboolean*` | On return, points to the boolean result of this function. Agent passes a pointer to a `jboolean`. On return, the `jboolean` has been set.

Errors
This function returns either a universal error or one of the following errors
Error | Description
`JVMTI_ERROR_INVALID_CLASS` | `klass` is not a class object or the class has been unloaded.
`JVMTI_ERROR_NULL_POINTER` | `is_interface_ptr` is `NULL`.

### Is Array Class

>     jvmtiError
>     IsArrayClass(jvmtiEnv* env,
>                 jclass klass,
>                 jboolean* is_array_class_ptr)

Determines whether a class object reference represents an array. The `jboolean` result is `JNI_TRUE` if the class is an array, `JNI_FALSE` otherwise.

Phase | Callback Safe | Position | Since
may only be called during the start or the live phase | No | 56 | 1.0

Capabilities
Required Functionality

Parameters
Name | Type | Description
`klass` | `jclass` | The class to query.
`is_array_class_ptr` | `jboolean*` | On return, points to the boolean result of this function. Agent passes a pointer to a `jboolean`. On return, the `jboolean` has been set.

Errors
This function returns either a universal error or one of the following errors
Error | Description
`JVMTI_ERROR_INVALID_CLASS` | `klass` is not a class object or the class has been unloaded.
`JVMTI_ERROR_NULL_POINTER` | `is_array_class_ptr` is `NULL`.

### Is Modifiable Class

>     jvmtiError
>     IsModifiableClass(jvmtiEnv* env,
>                 jclass klass,
>                 jboolean* is_modifiable_class_ptr)

Determines whether a class is modifiable. If a class is modifiable (`is_modifiable_class_ptr` returns `JNI_TRUE`) the class can be redefined with `RedefineClasses` (assuming the agent possesses the `can_redefine_classes` capability) or retransformed with `RetransformClasses` (assuming the agent possesses the `can_retransform_classes` capability). If a class is not modifiable (`is_modifiable_class_ptr` returns `JNI_FALSE`) the class can be neither redefined nor retransformed.

Primitive classes (for example, `java.lang.Integer.TYPE`) and array classes are never modifiable.

Phase | Callback Safe | Position | Since
may only be called during the start or the live phase | No | 45 | 1.1

Capabilities
Required Functionality
Optional Features
Capability | Effect
`can_redefine_any_class` | If possessed then all classes (except primitive and array classes) are modifiable.
`can_redefine_classes` | No effect on the result of the function. But must additionally be possessed to modify the class with `RedefineClasses`.
`can_retransform_classes` | No effect on the result of the function. But must additionally be possessed to modify the class with `RetransformClasses`.

Parameters
Name | Type | Description
`klass` | `jclass` | The class to query.
`is_modifiable_class_ptr` | `jboolean*` | On return, points to the boolean result of this function. Agent passes a pointer to a `jboolean`. On return, the `jboolean` has been set.

Errors
This function returns either a universal error or one of the following errors
Error | Description
`JVMTI_ERROR_INVALID_CLASS` | `klass` is not a class object or the class has been unloaded.
`JVMTI_ERROR_NULL_POINTER` | `is_modifiable_class_ptr` is `NULL`.

### Get Class Loader

>     jvmtiError
>     GetClassLoader(jvmtiEnv* env,
>                 jclass klass,
>                 jobject* classloader_ptr)

For the class indicated by `klass`, return via `classloader_ptr` a reference to the class loader for the class.

Phase | Callback Safe | Position | Since
may only be called during the start or the live phase | No | 57 | 1.0

Capabilities
Required Functionality

Parameters
Name | Type | Description
`klass` | `jclass` | The class to query.
`classloader_ptr` | `jobject*` | On return, points to the class loader that loaded this class. If the class was not created by a class loader or if the class loader is the bootstrap class loader, points to `NULL`. Agent passes a pointer to a `jobject`. On return, the `jobject` has been set. The object returned by `classloader_ptr` is a JNI local reference and must be managed.

Errors
This function returns either a universal error or one of the following errors
Error | Description
`JVMTI_ERROR_INVALID_CLASS` | `klass` is not a class object or the class has been unloaded.
`JVMTI_ERROR_NULL_POINTER` | `classloader_ptr` is `NULL`.

### Get Source Debug Extension

>     jvmtiError
>     GetSourceDebugExtension(jvmtiEnv* env,
>                 jclass klass,
>                 char** source_debug_extension_ptr)

For the class indicated by `klass`, return the debug extension via `source_debug_extension_ptr`. The returned string contains exactly the debug extension information present in the class file of `klass`.

Phase | Callback Safe | Position | Since
may only be called during the start or the live phase | No | 90 | 1.0

Capabilities
Optional Functionality: might not be implemented for all virtual machines. The following capability (as returned by `GetCapabilities`) must be true to use this function.
Capability | Effect
`can_get_source_debug_extension` | Can get the source debug extension of a class

Parameters
Name | Type | Description
`klass` | `jclass` | The class to query.
`source_debug_extension_ptr` | `char**` | On return, points to the class's debug extension, encoded as a modified UTF-8 string. Agent passes a pointer to a `char*`. On return, the `char*` points to a newly allocated array. The array should be freed with `Deallocate`.

Errors
This function returns either a universal error or one of the following errors
Error | Description
`JVMTI_ERROR_MUST_POSSESS_CAPABILITY` | The environment does not possess the capability `can_get_source_debug_extension`. Use `AddCapabilities`.
`JVMTI_ERROR_ABSENT_INFORMATION` | Class information does not include a debug extension.
`JVMTI_ERROR_INVALID_CLASS` | `klass` is not a class object or the class has been unloaded.
`JVMTI_ERROR_NULL_POINTER` | `source_debug_extension_ptr` is `NULL`.

### Retransform Classes

>     jvmtiError
>     RetransformClasses(jvmtiEnv* env,
>                 jint class_count,
>                 const jclass* classes)

This function facilitates the bytecode instrumentation of already loaded classes. To replace the class definition without reference to the existing bytecodes, as one might do when recompiling from source for fix-and-continue debugging, `RedefineClasses` function should be used instead.

When classes are initially loaded or when they are redefined, the initial class file bytes can be transformed with the `ClassFileLoadHook` event. This function reruns the transformation process (whether or not a transformation has previously occurred). This retransformation follows these steps:

- starting from the initial class file bytes
- for each retransformation incapable agent which received a `ClassFileLoadHook` event during the previous load or redefine, the bytes it returned (via the `new_class_data` parameter) are reused as the output of the transformation; note that this is equivalent to reapplying the previous transformation, unaltered. except that the `ClassFileLoadHook` event is not sent to these agents
- for each retransformation capable agent, the `ClassFileLoadHook` event is sent, allowing a new transformation to be applied
- the transformed class file bytes are installed as the new definition of the class

See the `ClassFileLoadHook` event for more details.

The initial class file bytes represent the bytes passed to `ClassLoader.defineClass` or `RedefineClasses` (before any transformations were applied), however they may not exactly match them. The constant pool may differ in ways described in `GetConstantPool`. Constant pool indices in the bytecodes of methods will correspond. Some attributes may not be present. Where order is not meaningful, for example the order of methods, order may not be preserved.

Retransformation can cause new versions of methods to be installed. Old method versions may become obsolete The new method version will be used on new invokes. If a method has active stack frames, those active frames continue to run the bytecodes of the original method version.

This function does not cause any initialization except that which would occur under the customary JVM semantics. In other words, retransforming a class does not cause its initializers to be run. The values of static fields will remain as they were prior to the call.

Threads need not be suspended.

All breakpoints in the class are cleared.

All attributes are updated.

Instances of the retransformed class are not affected -- fields retain their previous values. Tags on the instances are also unaffected.

In response to this call, no events other than the `ClassFileLoadHook` event will be sent.

The retransformation may change method bodies, the constant pool and attributes. The retransformation must not add, remove or rename fields or methods, change the signatures of methods, change modifiers, or change inheritance. These restrictions may be lifted in future versions. See the error return description below for information on error codes returned if an unsupported retransformation is attempted. The class file bytes are not verified or installed until they have passed through the chain of `ClassFileLoadHook` events, thus the returned error code reflects the result of the transformations. If any error code is returned other than `JVMTI_ERROR_NONE`, none of the classes to be retransformed will have a new definition installed. When this function returns (with the error code of `JVMTI_ERROR_NONE`) all of the classes to be retransformed will have their new definitions installed.

Phase | Callback Safe | Position | Since
may only be called during the live phase | No | 152 | 1.1

Capabilities
Optional Functionality: might not be implemented for all virtual machines. The following capability (as returned by `GetCapabilities`) must be true to use this function.
Capability | Effect
`can_retransform_classes` | Can retransform classes with `RetransformClasses`. In addition to the restrictions imposed by the specific implementation on this capability (see the Capability section), this capability must be set before the `ClassFileLoadHook` event is enabled for the first time in this environment. An environment that possesses this capability at the time that `ClassFileLoadHook` is enabled for the first time is said to be retransformation capable. An environment that does not possess this capability at the time that `ClassFileLoadHook` is enabled for the first time is said to be retransformation incapable.
Optional Features
`can_retransform_any_class` | `RetransformClasses` can be called on any class (`can_retransform_classes` must also be set)

Parameters
Name | Type | Description
`class_count` | `jint` | The number of classes to be retransformed.
`classes` | `const jclass*` | The array of classes to be retransformed. Agent passes in an array of `class_count` elements of `jclass`.

Errors
This function returns either a universal error or one of the following errors
Error | Description
`JVMTI_ERROR_MUST_POSSESS_CAPABILITY` | The environment does not possess the capability `can_retransform_classes`. Use `AddCapabilities`.
`JVMTI_ERROR_UNMODIFIABLE_CLASS` | One of the `classes` cannot be modified. See `IsModifiableClass`.
`JVMTI_ERROR_INVALID_CLASS` | One of the `classes` is not a valid class.
`JVMTI_ERROR_UNSUPPORTED_VERSION` | A retransformed class file has a version number not supported by this VM.
`JVMTI_ERROR_INVALID_CLASS_FORMAT` | A retransformed class file is malformed (The VM would return a `ClassFormatError`).
`JVMTI_ERROR_CIRCULAR_CLASS_DEFINITION` | The retransformed class file definitions would lead to a circular definition (the VM would return a `ClassCircularityError`).
`JVMTI_ERROR_FAILS_VERIFICATION` | The retransformed class file bytes fail verification.
`JVMTI_ERROR_NAMES_DONT_MATCH` | The class name defined in a retransformed class file is different from the name in the old class object.
`JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_ADDED` | A retransformed class file would require adding a method.
`JVMTI_ERROR_UNSUPPORTED_REDEFINITION_SCHEMA_CHANGED` | A retransformed class file changes a field.
`JVMTI_ERROR_UNSUPPORTED_REDEFINITION_HIERARCHY_CHANGED` | A direct superclass is different for a retransformed class file, or the set of directly implemented interfaces is different.
`JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_DELETED` | A retransformed class file does not declare a method declared in the old class version.
`JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_MODIFIERS_CHANGED` | A retransformed class file has different class modifiers.
`JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_MODIFIERS_CHANGED` | A method in the retransformed class file has different modifiers than its counterpart in the old class version.
`JVMTI_ERROR_ILLEGAL_ARGUMENT` | `class_count` is less than `0`.
`JVMTI_ERROR_NULL_POINTER` | `classes` is `NULL`.

### Redefine Classes

>     typedef struct {
>         jclass klass;
>         jint class_byte_count;
>         const unsigned char* class_bytes;
>     } jvmtiClassDefinition;

>     jvmtiError
>     RedefineClasses(jvmtiEnv* env,
>                 jint class_count,
>                 const jvmtiClassDefinition* class_definitions)

All classes given are redefined according to the definitions supplied. This function is used to replace the definition of a class with a new definition, as might be needed in fix-and-continue debugging. Where the existing class file bytes are to be transformed, for example in bytecode instrumentation, `RetransformClasses` should be used.

Redefinition can cause new versions of methods to be installed. Old method versions may become obsolete The new method version will be used on new invokes. If a method has active stack frames, those active frames continue to run the bytecodes of the original method version. If resetting of stack frames is desired, use `PopFrame` to pop frames with obsolete method versions.

This function does not cause any initialization except that which would occur under the customary JVM semantics. In other words, redefining a class does not cause its initializers to be run. The values of static fields will remain as they were prior to the call.

Threads need not be suspended.

All breakpoints in the class are cleared.

All attributes are updated.

Instances of the redefined class are not affected -- fields retain their previous values. Tags on the instances are also unaffected.

In response to this call, the JVM TI event Class File Load Hook will be sent (if enabled), but no other JVM TI events will be sent.

The redefinition may change method bodies, the constant pool and attributes. The redefinition must not add, remove or rename fields or methods, change the signatures of methods, change modifiers, or change inheritance. These restrictions may be lifted in future versions. See the error return description below for information on error codes returned if an unsupported redefinition is attempted. The class file bytes are not verified or installed until they have passed through the chain of `ClassFileLoadHook` events, thus the returned error code reflects the result of the transformations applied to the bytes passed into `class_definitions`. If any error code is returned other than `JVMTI_ERROR_NONE`, none of the classes to be redefined will have a new definition installed. When this function returns (with the error code of `JVMTI_ERROR_NONE`) all of the classes to be redefined will have their new definitions installed.

Phase | Callback Safe | Position | Since
may only be called during the live phase | No | 87 | 1.0

Capabilities
Optional Functionality: might not be implemented for all virtual machines. The following capability (as returned by `GetCapabilities`) must be true to use this function.
Capability | Effect
`can_redefine_classes` | Can redefine classes with `RedefineClasses`.
Optional Features
`can_redefine_any_class` | Can modify (retransform or redefine) any non-primitive non-array class. See `IsModifiableClass`.

`jvmtiClassDefinition` - Class redefinition description
Field | Type | Description
`klass` | `jclass` | Class object for this class
`class_byte_count` | `jint` | Number of bytes defining class (below)
`class_bytes` | `const unsigned char*` | Bytes defining class (in the Class File Format of the Java Virtual Machine Specification)

Parameters
Name | Type | Description
`class_count` | `jint` | The number of classes specified in `class_definitions`
`class_definitions` | `const jvmtiClassDefinition*` | The array of new class definitions Agent passes in an array of `class_count` elements of `jvmtiClassDefinition`.

Errors
This function returns either a universal error or one of the following errors
Error | Description
`JVMTI_ERROR_MUST_POSSESS_CAPABILITY` | The environment does not possess the capability `can_redefine_classes`. Use `AddCapabilities`.
`JVMTI_ERROR_NULL_POINTER` | One of `class_bytes` is `NULL`.
`JVMTI_ERROR_UNMODIFIABLE_CLASS` | An element of `class_definitions` cannot be modified. See `IsModifiableClass`.
`JVMTI_ERROR_INVALID_CLASS` | An element of `class_definitions` is not a valid class.
`JVMTI_ERROR_UNSUPPORTED_VERSION` | A new class file has a version number not supported by this VM.
`JVMTI_ERROR_INVALID_CLASS_FORMAT` | A new class file is malformed (The VM would return a `ClassFormatError`).
`JVMTI_ERROR_CIRCULAR_CLASS_DEFINITION` | The new class file definitions would lead to a circular definition (the VM would return a `ClassCircularityError`).
`JVMTI_ERROR_FAILS_VERIFICATION` | The class bytes fail verification.
`JVMTI_ERROR_NAMES_DONT_MATCH` | The class name defined in a new class file is different from the name in the old class object.
`JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_ADDED` | A new class file would require adding a method.
`JVMTI_ERROR_UNSUPPORTED_REDEFINITION_SCHEMA_CHANGED` | A new class version changes a field.
`JVMTI_ERROR_UNSUPPORTED_REDEFINITION_HIERARCHY_CHANGED` | A direct superclass is different for a new class version, or the set of directly implemented interfaces is different.
`JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_DELETED` | A new class version does not declare a method declared in the old class version.
`JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_MODIFIERS_CHANGED` | A new class version has different modifiers.
`JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_MODIFIERS_CHANGED` | A method in the new class version has different modifiers than its counterpart in the old class version.
`JVMTI_ERROR_ILLEGAL_ARGUMENT` | `class_count` is less than `0`.
`JVMTI_ERROR_NULL_POINTER` | `class_definitions` is `NULL`.

## Object

Object functions:

- Get Object Size
- Get Object Hash Code
- Get Object Monitor Usage

Object types:

- `jvmtiMonitorUsage` - Object monitor usage information

### Get Object Size

>     jvmtiError
>     GetObjectSize(jvmtiEnv* env,
>                 jobject object,
>                 jlong* size_ptr)

For the object indicated by `object`, return via `size_ptr` the size of the object. This size is an implementation-specific approximation of the amount of storage consumed by this object. It may include some or all of the object's overhead, and thus is useful for comparison within an implementation but not between implementations. The estimate may change during a single invocation of the JVM.

Phase | Callback Safe | Position | Since
may only be called during the start or the live phase | No | 154 | 1.0

Capabilities
Required Functionality

Parameters
Name | Type | Description
`object` | `jobject` | The object to query.
`size_ptr` | `jlong*` | On return, points to the object's size in bytes. Agent passes a pointer to a `jlong`. On return, the `jlong` has been set.

Errors
This function returns either a universal error or one of the following errors
Error | Description
`JVMTI_ERROR_INVALID_OBJECT` | `object` is not an object.
`JVMTI_ERROR_NULL_POINTER` | `size_ptr` is `NULL`.

### Get Object Hash Code

>     jvmtiError
>     GetObjectHashCode(jvmtiEnv* env,
>                 jobject object,
>                 jint* hash_code_ptr)

For the object indicated by `object`, return via `hash_code_ptr` a hash code. This hash code could be used to maintain a hash table of object references, however, on some implementations this can cause significant performance impacts--in most cases tags will be a more efficient means of associating information with objects. This function guarantees the same hash code value for a particular object throughout its life

Phase | Callback Safe | Position | Since
may only be called during the start or the live phase | No | 58 | 1.0

Capabilities
Required Functionality

Parameters
Name | Type | Description
`object` | `jobject` | The object to query.
`hash_code_ptr` | `jint*` | On return, points to the object's hash code. Agent passes a pointer to a `jint`. On return, the `jint` has been set.

Errors
This function returns either a universal error or one of the following errors
Error | Description
`JVMTI_ERROR_INVALID_OBJECT` | `object` is not an object.
`JVMTI_ERROR_NULL_POINTER` | `hash_code_ptr` is `NULL`.

### Get Object Monitor Usage

>     typedef struct {
>         jthread owner;
>         jint entry_count;
>         jint waiter_count;
>         jthread* waiters;
>         jint notify_waiter_count;
>         jthread* notify_waiters;
>     } jvmtiMonitorUsage;

>     jvmtiError
>     GetObjectMonitorUsage(jvmtiEnv* env,
>                 jobject object,
>                 jvmtiMonitorUsage* info_ptr)

Get information about the object's monitor. The fields of the `jvmtiMonitorUsage` structure are filled in with information about usage of the monitor.

Phase | Callback Safe | Position | Since
may only be called during the live phase | No | 59 | 1.0

Capabilities
Optional Functionality: might not be implemented for all virtual machines. The following capability (as returned by `GetCapabilities`) must be true to use this function.
Capability | Effect
`can_get_monitor_info` | Can `GetObjectMonitorUsage`

`jvmtiMonitorUsage` - Object monitor usage information
Field | Type | Description
`owner` | `jthread` | The thread owning this monitor, or `NULL` if unused
`entry_count` | `jint` | The number of times the owning thread has entered the monitor
`waiter_count` | `jint` | The number of threads waiting to own this monitor
`waiters` | `jthread*` | The `waiter_count` waiting threads
`notify_waiter_count` | `jint` | The number of threads waiting to be notified by this monitor
`notify_waiters` | `jthread*` | The `notify_waiter_count` threads waiting to be notified

Parameters
Name | Type | Description
`object` | `jobject` | The object to query.
`info_ptr` | `jvmtiMonitorUsage*` | On return, filled with monitor information for the specified object. Agent passes a pointer to a `jvmtiMonitorUsage`. On return, the `jvmtiMonitorUsage` has been set. The object returned in the field `owner` of `jvmtiMonitorUsage` is a JNI local reference and must be managed. The pointer returned in the field `waiters` of `jvmtiMonitorUsage` is a newly allocated array. The array should be freed with `Deallocate`. The objects returned in the field `waiters` of `jvmtiMonitorUsage` are JNI local references and must be managed. The pointer returned in the field `notify_waiters` of `jvmtiMonitorUsage` is a newly allocated array. The array should be freed with `Deallocate`. The objects returned in the field `notify_waiters` of `jvmtiMonitorUsage` are JNI local references and must be managed.

Errors
This function returns either a universal error or one of the following errors
Error | Description
`JVMTI_ERROR_MUST_POSSESS_CAPABILITY` | The environment does not possess the capability `can_get_monitor_info`. Use `AddCapabilities`.
`JVMTI_ERROR_INVALID_OBJECT` | `object` is not an object.
`JVMTI_ERROR_NULL_POINTER` | `info_ptr` is `NULL`.

## Field

Field functions:

- Get Field Name (and Signature)
- Get Field Declaring Class
- Get Field Modifiers
- Is Field Synthetic

### Get Field Name (and Signature)

>     jvmtiError
>     GetFieldName(jvmtiEnv* env,
>                 jclass klass,
>                 jfieldID field,
>                 char** name_ptr,
>                 char** signature_ptr,
>                 char** generic_ptr)

For the field indicated by `klass` and `field`, return the field name via `name_ptr` and field signature via `signature_ptr`.

Field signatures are defined in the JNI Specification and are referred to as field descriptors in the Java Virtual Machine Specification.

Phase | Callback Safe | Position | Since
may only be called during the start or the live phase | No | 60 | 1.0

Capabilities
Required Functionality

Parameters
Name | Type | Description
`klass` | `jclass` | The class of the field to query.
`field` | `jfieldID` | The field to query.
`name_ptr` | `char **` | On return, points to the field name, encoded as a modified UTF-8 string. Agent passes a pointer to a `char*`. On return, the `char*` points to a newly allocated array. The array should be freed with `Deallocate`. If `name_ptr` is `NULL`, the name is not returned.
`signature_ptr` | `char **` | On return, points to the field signature, encoded as a modified UTF-8 string. Agent passes a pointer to a `char*`. On return, the `char*` points to a newly allocated array. The array should be freed with `Deallocate`. If `signature_ptr` is `NULL`, the signature is not returned.
`generic_ptr` | `char **` | On return, points to the generic signature of the field, encoded as a modified UTF-8 string. If there is no generic signature attribute for the field, then, on return, points to `NULL`. Agent passes a pointer to a `char*`. On return, the `char*` points to a newly allocated array. The array should be freed with `Deallocate`. If `generic_ptr` is `NULL`, the generic signature is not returned.

Errors
This function returns either a universal error or one of the following errors
Error | Description
`JVMTI_ERROR_INVALID_CLASS` | `klass` is not a class object or the class has been unloaded.
`JVMTI_ERROR_INVALID_FIELDID` | `field` is not a jfieldID.

### Get Field Declaring Class

>     jvmtiError
>     GetFieldDeclaringClass(jvmtiEnv* env,
>                 jclass klass,
>                 jfieldID field,
>                 jclass* declaring_class_ptr)

For the field indicated by `klass` and `field` return the class that defined it via `declaring_class_ptr`. The declaring class will either be `klass`, a superclass, or an implemented interface.

Phase | Callback Safe | Position | Since
may only be called during the start or the live phase | No | 61 | 1.0

Capabilities
Required Functionality

Parameters
Name | Type | Description
`klass` | `jclass` | The class to query.
`field` | `jfieldID` | The field to query.
`declaring_class_ptr` | `jclass*` | On return, points to the declaring class Agent passes a pointer to a `jclass`. On return, the `jclass` has been set. The object returned by `declaring_class_ptr` is a JNI local reference and must be managed.

Errors
This function returns either a universal error or one of the following errors
Error | Description
`JVMTI_ERROR_INVALID_CLASS` | `klass` is not a class object or the class has been unloaded.
`JVMTI_ERROR_INVALID_FIELDID` | `field` is not a jfieldID.
`JVMTI_ERROR_NULL_POINTER` | `declaring_class_ptr` is `NULL`.

### Get Field Modifiers

>     jvmtiError
>     GetFieldModifiers(jvmtiEnv* env,
>                 jclass klass,
>                 jfieldID field,
>                 jint* modifiers_ptr)

For the field indicated by `klass` and `field` return the access flags via `modifiers_ptr`. Access flags are defined in the Class File Format chapter of the Java Virtual Machine Specification.

Phase | Callback Safe | Position | Since
may only be called during the start or the live phase | No | 62 | 1.0

Capabilities
Required Functionality

Parameters
Name | Type | Description
`klass` | `jclass` | The class to query.
`field` | `jfieldID` | The field to query.
`modifiers_ptr` | `jint*` | On return, points to the access flags. Agent passes a pointer to a `jint`. On return, the `jint` has been set.

Errors
This function returns either a universal error or one of the following errors
Error | Description
`JVMTI_ERROR_INVALID_CLASS` | `klass` is not a class object or the class has been unloaded.
`JVMTI_ERROR_INVALID_FIELDID` | `field` is not a jfieldID.
`JVMTI_ERROR_NULL_POINTER` | `modifiers_ptr` is `NULL`.

### Is Field Synthetic

>     jvmtiError
>     IsFieldSynthetic(jvmtiEnv* env,
>                 jclass klass,
>                 jfieldID field,
>                 jboolean* is_synthetic_ptr)

For the field indicated by `klass` and `field`, return a value indicating whether the field is synthetic via `is_synthetic_ptr`. Synthetic fields are generated by the compiler but not present in the original source code.

Phase | Callback Safe | Position | Since
may only be called during the start or the live phase | No | 63 | 1.0

Capabilities
Optional Functionality: might not be implemented for all virtual machines. The following capability (as returned by `GetCapabilities`) must be true to use this function.
Capability | Effect
`can_get_synthetic_attribute` | Can test if a field or method is synthetic - `IsFieldSynthetic` and `IsMethodSynthetic`

Parameters
Name | Type | Description
`klass` | `jclass` | The class of the field to query.
`field` | `jfieldID` | The field to query.
`is_synthetic_ptr` | `jboolean*` | On return, points to the boolean result of this function. Agent passes a pointer to a `jboolean`. On return, the `jboolean` has been set.

Errors
This function returns either a universal error or one of the following errors
Error | Description
`JVMTI_ERROR_MUST_POSSESS_CAPABILITY` | The environment does not possess the capability `can_get_synthetic_attribute`. Use `AddCapabilities`.
`JVMTI_ERROR_INVALID_CLASS` | `klass` is not a class object or the class has been unloaded.
`JVMTI_ERROR_INVALID_FIELDID` | `field` is not a jfieldID.
`JVMTI_ERROR_NULL_POINTER` | `is_synthetic_ptr` is `NULL`.

## Method

Method functions:

- Get Method Name (and Signature)
- Get Method Declaring Class
- Get Method Modifiers
- Get Max Locals
- Get Arguments Size
- Get Line Number Table
- Get Method Location
- Get Local Variable Table
- Get Bytecodes
- Is Method Native
- Is Method Synthetic
- Is Method Obsolete
- Set Native Method Prefix
- Set Native Method Prefixes

Method types:

- `jvmtiLineNumberEntry` - Line number table entry
- `jvmtiLocalVariableEntry` - Local variable table entry

These functions provide information about a method (represented as a `jmethodID`) and set how methods are processed.

#### Obsolete Methods

The functions `RetransformClasses` and `RedefineClasses` can cause new versions of methods to be installed. An original version of a method is considered equivalent to the new version if:

- their bytecodes are the same except for indices into the constant pool and
- the referenced constants are equal.

An original method version which is not equivalent to the new method version is called obsolete and is assigned a new method ID; the original method ID now refers to the new method version. A method ID can be tested for obsolescence with `IsMethodObsolete`.

### Get Method Name (and Signature)

>     jvmtiError
>     GetMethodName(jvmtiEnv* env,
>                 jmethodID method,
>                 char** name_ptr,
>                 char** signature_ptr,
>                 char** generic_ptr)

For the method indicated by `method`, return the method name via `name_ptr` and method signature via `signature_ptr`.

Method signatures are defined in the JNI Specification and are referred to as method descriptors in the Java Virtual Machine Specification. Note this is different than method signatures as defined in the Java Language Specification.

Phase | Callback Safe | Position | Since
may only be called during the start or the live phase | No | 64 | 1.0

Capabilities
Required Functionality

Parameters
Name | Type | Description
`method` | `jmethodID` | The method to query.
`name_ptr` | `char **` | On return, points to the method name, encoded as a modified UTF-8 string. Agent passes a pointer to a `char*`. On return, the `char*` points to a newly allocated array. The array should be freed with `Deallocate`. If `name_ptr` is `NULL`, the name is not returned.
`signature_ptr` | `char **` | On return, points to the method signature, encoded as a modified UTF-8 string. Agent passes a pointer to a `char*`. On return, the `char*` points to a newly allocated array. The array should be freed with `Deallocate`. If `signature_ptr` is `NULL`, the signature is not returned.
`generic_ptr` | `char **` | On return, points to the generic signature of the method, encoded as a modified UTF-8 string. If there is no generic signature attribute for the method, then, on return, points to `NULL`. Agent passes a pointer to a `char*`. On return, the `char*` points to a newly allocated array. The array should be freed with `Deallocate`. If `generic_ptr` is `NULL`, the generic signature is not returned.

Errors
This function returns either a universal error or one of the following errors
Error | Description
`JVMTI_ERROR_INVALID_METHODID` | `method` is not a jmethodID.

### Get Method Declaring Class

>     jvmtiError
>     GetMethodDeclaringClass(jvmtiEnv* env,
>                 jmethodID method,
>                 jclass* declaring_class_ptr)

For the method indicated by `method`, return the class that defined it via `declaring_class_ptr`.

Phase | Callback Safe | Position | Since
may only be called during the start or the live phase | No | 65 | 1.0

Capabilities
Required Functionality

Parameters
Name | Type | Description
`method` | `jmethodID` | The method to query.
`declaring_class_ptr` | `jclass*` | On return, points to the declaring class Agent passes a pointer to a `jclass`. On return, the `jclass` has been set. The object returned by `declaring_class_ptr` is a JNI local reference and must be managed.

Errors
This function returns either a universal error or one of the following errors
Error | Description
`JVMTI_ERROR_INVALID_METHODID` | `method` is not a jmethodID.
`JVMTI_ERROR_NULL_POINTER` | `declaring_class_ptr` is `NULL`.

### Get Method Modifiers

>     jvmtiError
>     GetMethodModifiers(jvmtiEnv* env,
>                 jmethodID method,
>                 jint* modifiers_ptr)

For the method indicated by `method`, return the access flags via `modifiers_ptr`. Access flags are defined in the Class File Format chapter of the Java Virtual Machine Specification.

Phase | Callback Safe | Position | Since
may only be called during the start or the live phase | No | 66 | 1.0

Capabilities
Required Functionality

Parameters
Name | Type | Description
`method` | `jmethodID` | The method to query.
`modifiers_ptr` | `jint*` | On return, points to the access flags. Agent passes a pointer to a `jint`. On return, the `jint` has been set.

Errors
This function returns either a universal error or one of the following errors
Error | Description
`JVMTI_ERROR_INVALID_METHODID` | `method` is not a jmethodID.
`JVMTI_ERROR_NULL_POINTER` | `modifiers_ptr` is `NULL`.

### Get Max Locals

>     jvmtiError
>     GetMaxLocals(jvmtiEnv* env,
>                 jmethodID method,
>                 jint* max_ptr)

For the method indicated by `method`, return the number of local variable slots used by the method, including the local variables used to pass parameters to the method on its invocation.

See `max_locals` in the Code Attribute section of the Java Virtual Machine Specification.

Phase | Callback Safe | Position | Since
may only be called during the start or the live phase | No | 68 | 1.0

Capabilities
Required Functionality

Parameters
Name | Type | Description
`method` | `jmethodID` | The method to query.
`max_ptr` | `jint*` | On return, points to the maximum number of local slots Agent passes a pointer to a `jint`. On return, the `jint` has been set.

Errors
This function returns either a universal error or one of the following errors
Error | Description
`JVMTI_ERROR_INVALID_METHODID` | `method` is not a jmethodID.
`JVMTI_ERROR_NATIVE_METHOD` | `method` is a native method.
`JVMTI_ERROR_NULL_POINTER` | `max_ptr` is `NULL`.

### Get Arguments Size

>     jvmtiError
>     GetArgumentsSize(jvmtiEnv* env,
>                 jmethodID method,
>                 jint* size_ptr)

For the method indicated by `method`, return via `max_ptr` the number of local variable slots used by the method's arguments. Note that two-word arguments use two slots.

Phase | Callback Safe | Position | Since
may only be called during the start or the live phase | No | 69 | 1.0

Capabilities
Required Functionality

Parameters
Name | Type | Description
`method` | `jmethodID` | The method to query.
`size_ptr` | `jint*` | On return, points to the number of argument slots Agent passes a pointer to a `jint`. On return, the `jint` has been set.

Errors
This function returns either a universal error or one of the following errors
Error | Description
`JVMTI_ERROR_INVALID_METHODID` | `method` is not a jmethodID.
`JVMTI_ERROR_NATIVE_METHOD` | `method` is a native method.
`JVMTI_ERROR_NULL_POINTER` | `size_ptr` is `NULL`.

### Get Line Number Table

>     typedef struct {
>         jlocation start_location;
>         jint line_number;
>     } jvmtiLineNumberEntry;

>     jvmtiError
>     GetLineNumberTable(jvmtiEnv* env,
>                 jmethodID method,
>                 jint* entry_count_ptr,
>                 jvmtiLineNumberEntry** table_ptr)

For the method indicated by `method`, return a table of source line number entries. The size of the table is returned via `entry_count_ptr` and the table itself is returned via `table_ptr`.

Phase | Callback Safe | Position | Since
may only be called during the start or the live phase | No | 70 | 1.0

Capabilities
Optional Functionality: might not be implemented for all virtual machines. The following capability (as returned by `GetCapabilities`) must be true to use this function.
Capability | Effect
`can_get_line_numbers` | Can get the line number table of a method

`jvmtiLineNumberEntry` - Line number table entry
Field | Type | Description
`start_location` | `jlocation` | the `jlocation` where the line begins
`line_number` | `jint` | the line number

Parameters
Name | Type | Description
`method` | `jmethodID` | The method to query.
`entry_count_ptr` | `jint*` | On return, points to the number of entries in the table Agent passes a pointer to a `jint`. On return, the `jint` has been set.
`table_ptr` | `jvmtiLineNumberEntry**` | On return, points to the line number table pointer. Agent passes a pointer to a `jvmtiLineNumberEntry*`. On return, the `jvmtiLineNumberEntry*` points to a newly allocated array of size `*entry_count_ptr`. The array should be freed with `Deallocate`.

Errors
This function returns either a universal error or one of the following errors
Error | Description
`JVMTI_ERROR_MUST_POSSESS_CAPABILITY` | The environment does not possess the capability `can_get_line_numbers`. Use `AddCapabilities`.
`JVMTI_ERROR_ABSENT_INFORMATION` | Class information does not include line numbers.
`JVMTI_ERROR_INVALID_METHODID` | `method` is not a jmethodID.
`JVMTI_ERROR_NATIVE_METHOD` | `method` is a native method.
`JVMTI_ERROR_NULL_POINTER` | `entry_count_ptr` is `NULL`.
`JVMTI_ERROR_NULL_POINTER` | `table_ptr` is `NULL`.

### Get Method Location

>     jvmtiError
>     GetMethodLocation(jvmtiEnv* env,
>                 jmethodID method,
>                 jlocation* start_location_ptr,
>                 jlocation* end_location_ptr)

For the method indicated by `method`, return the beginning and ending addresses through `start_location_ptr` and `end_location_ptr`. In a conventional byte code indexing scheme, `start_location_ptr` will always point to zero and `end_location_ptr` will always point to the byte code count minus one.

Phase | Callback Safe | Position | Since
may only be called during the start or the live phase | No | 71 | 1.0

Capabilities
Required Functionality

Parameters
Name | Type | Description
`method` | `jmethodID` | The method to query.
`start_location_ptr` | `jlocation*` | On return, points to the first location, or `-1` if location information is not available. If the information is available and `GetJLocationFormat` returns `JVMTI_JLOCATION_JVMBCI` then this will always be zero. Agent passes a pointer to a `jlocation`. On return, the `jlocation` has been set.
`end_location_ptr` | `jlocation*` | On return, points to the last location, or `-1` if location information is not available. Agent passes a pointer to a `jlocation`. On return, the `jlocation` has been set.

Errors
This function returns either a universal error or one of the following errors
Error | Description
`JVMTI_ERROR_ABSENT_INFORMATION` | Class information does not include method sizes.
`JVMTI_ERROR_INVALID_METHODID` | `method` is not a jmethodID.
`JVMTI_ERROR_NATIVE_METHOD` | `method` is a native method.
`JVMTI_ERROR_NULL_POINTER` | `start_location_ptr` is `NULL`.
`JVMTI_ERROR_NULL_POINTER` | `end_location_ptr` is `NULL`.

### Get Local Variable Table

>     typedef struct {
>         jlocation start_location;
>         jint length;
>         char* name;
>         char* signature;
>         char* generic_signature;
>         jint slot;
>     } jvmtiLocalVariableEntry;

>     jvmtiError
>     GetLocalVariableTable(jvmtiEnv* env,
>                 jmethodID method,
>                 jint* entry_count_ptr,
>                 jvmtiLocalVariableEntry** table_ptr)

Return local variable information.

Phase | Callback Safe | Position | Since
may only be called during the live phase | No | 72 | 1.0

Capabilities
Optional Functionality: might not be implemented for all virtual machines. The following capability (as returned by `GetCapabilities`) must be true to use this function.
Capability | Effect
`can_access_local_variables` | Can set and get local variables

`jvmtiLocalVariableEntry` - Local variable table entry
Field | Type | Description
`start_location` | `jlocation` | The code array index where the local variable is first valid (that is, where it must have a value).
`length` | `jint` | The length of the valid section for this local variable. The last code array index where the local variable is valid is `start_location + length`.
`name` | `char*` | The local variable name, encoded as a modified UTF-8 string.
`signature` | `char*` | The local variable's type signature, encoded as a modified UTF-8 string. The signature format is the same as that defined in Field Descriptors section of the Java Virtual Machine Specification
`generic_signature` | `char*` | The local variable's generic signature, encoded as a modified UTF-8 string. The value of this field will be `NULL` for any local variable which does not have a generic type.
`slot` | `jint` | The local variable's slot. See Local Variables.

Parameters
Name | Type | Description
`method` | `jmethodID` | The method to query.
`entry_count_ptr` | `jint*` | On return, points to the number of entries in the table Agent passes a pointer to a `jint`. On return, the `jint` has been set.
`table_ptr` | `jvmtiLocalVariableEntry**` | On return, points to an array of local variable table entries. Agent passes a pointer to a `jvmtiLocalVariableEntry*`. On return, the `jvmtiLocalVariableEntry*` points to a newly allocated array of size `*entry_count_ptr`. The array should be freed with `Deallocate`. The pointers returned in the field `name` of `jvmtiLocalVariableEntry` are newly allocated arrays. The arrays should be freed with `Deallocate`. The pointers returned in the field `signature` of `jvmtiLocalVariableEntry` are newly allocated arrays. The arrays should be freed with `Deallocate`. The pointers returned in the field `generic_signature` of `jvmtiLocalVariableEntry` are newly allocated arrays. The arrays should be freed with `Deallocate`.

Errors
This function returns either a universal error or one of the following errors
Error | Description
`JVMTI_ERROR_MUST_POSSESS_CAPABILITY` | The environment does not possess the capability `can_access_local_variables`. Use `AddCapabilities`.
`JVMTI_ERROR_ABSENT_INFORMATION` | Class information does not include local variable information.
`JVMTI_ERROR_INVALID_METHODID` | `method` is not a jmethodID.
`JVMTI_ERROR_NATIVE_METHOD` | `method` is a native method.
`JVMTI_ERROR_NULL_POINTER` | `entry_count_ptr` is `NULL`.
`JVMTI_ERROR_NULL_POINTER` | `table_ptr` is `NULL`.

### Get Bytecodes

>     jvmtiError
>     GetBytecodes(jvmtiEnv* env,
>                 jmethodID method,
>                 jint* bytecode_count_ptr,
>                 unsigned char** bytecodes_ptr)

For the method indicated by `method`, return the byte codes that implement the method. The number of bytecodes is returned via `bytecode_count_ptr`. The byte codes themselves are returned via `bytecodes_ptr`.

Phase | Callback Safe | Position | Since
may only be called during the start or the live phase | No | 75 | 1.0

Capabilities
Optional Functionality: might not be implemented for all virtual machines. The following capability (as returned by `GetCapabilities`) must be true to use this function.
Capability | Effect
`can_get_bytecodes` | Can get bytecodes of a method `GetBytecodes`

Parameters
Name | Type | Description
`method` | `jmethodID` | The method to query.
`bytecode_count_ptr` | `jint*` | On return, points to the length of the byte code array Agent passes a pointer to a `jint`. On return, the `jint` has been set.
`bytecodes_ptr` | `unsigned char**` | On return, points to the pointer to the byte code array Agent passes a pointer to a `unsigned char*`. On return, the `unsigned char*` points to a newly allocated array of size `*bytecode_count_ptr`. The array should be freed with `Deallocate`.

Errors
This function returns either a universal error or one of the following errors
Error | Description
`JVMTI_ERROR_MUST_POSSESS_CAPABILITY` | The environment does not possess the capability `can_get_bytecodes`. Use `AddCapabilities`.
`JVMTI_ERROR_INVALID_METHODID` | `method` is not a jmethodID.
`JVMTI_ERROR_NATIVE_METHOD` | `method` is a native method.
`JVMTI_ERROR_NULL_POINTER` | `bytecode_count_ptr` is `NULL`.
`JVMTI_ERROR_NULL_POINTER` | `bytecodes_ptr` is `NULL`.

### Is Method Native

>     jvmtiError
>     IsMethodNative(jvmtiEnv* env,
>                 jmethodID method,
>                 jboolean* is_native_ptr)

For the method indicated by `method`, return a value indicating whether the method is native via `is_native_ptr`

Phase | Callback Safe | Position | Since
may only be called during the start or the live phase | No | 76 | 1.0

Capabilities
Required Functionality

Parameters
Name | Type | Description
`method` | `jmethodID` | The method to query.
`is_native_ptr` | `jboolean*` | On return, points to the boolean result of this function. Agent passes a pointer to a `jboolean`. On return, the `jboolean` has been set.

Errors
This function returns either a universal error or one of the following errors
Error | Description
`JVMTI_ERROR_INVALID_METHODID` | `method` is not a jmethodID.
`JVMTI_ERROR_NULL_POINTER` | `is_native_ptr` is `NULL`.

### Is Method Synthetic

>     jvmtiError
>     IsMethodSynthetic(jvmtiEnv* env,
>                 jmethodID method,
>                 jboolean* is_synthetic_ptr)

For the method indicated by `method`, return a value indicating whether the method is synthetic via `is_synthetic_ptr`. Synthetic methods are generated by the compiler but not present in the original source code.

Phase | Callback Safe | Position | Since
may only be called during the start or the live phase | No | 77 | 1.0

Capabilities
Optional Functionality: might not be implemented for all virtual machines. The following capability (as returned by `GetCapabilities`) must be true to use this function.
Capability | Effect
`can_get_synthetic_attribute` | Can test if a field or method is synthetic - `IsFieldSynthetic` and `IsMethodSynthetic`

Parameters
Name | Type | Description
`method` | `jmethodID` | The method to query.
`is_synthetic_ptr` | `jboolean*` | On return, points to the boolean result of this function. Agent passes a pointer to a `jboolean`. On return, the `jboolean` has been set.

Errors
This function returns either a universal error or one of the following errors
Error | Description
`JVMTI_ERROR_MUST_POSSESS_CAPABILITY` | The environment does not possess the capability `can_get_synthetic_attribute`. Use `AddCapabilities`.
`JVMTI_ERROR_INVALID_METHODID` | `method` is not a jmethodID.
`JVMTI_ERROR_NULL_POINTER` | `is_synthetic_ptr` is `NULL`.

### Is Method Obsolete

>     jvmtiError
>     IsMethodObsolete(jvmtiEnv* env,
>                 jmethodID method,
>                 jboolean* is_obsolete_ptr)

Determine if a method ID refers to an obsolete method version.

Phase | Callback Safe | Position | Since
may only be called during the start or the live phase | No | 91 | 1.0

Capabilities
Required Functionality

Parameters
Name | Type | Description
`method` | `jmethodID` | The method ID to query.
`is_obsolete_ptr` | `jboolean*` | On return, points to the boolean result of this function. Agent passes a pointer to a `jboolean`. On return, the `jboolean` has been set.

Errors
This function returns either a universal error or one of the following errors
Error | Description
`JVMTI_ERROR_INVALID_METHODID` | `method` is not a jmethodID.
`JVMTI_ERROR_NULL_POINTER` | `is_obsolete_ptr` is `NULL`.

### Set Native Method Prefix

>     jvmtiError
>     SetNativeMethodPrefix(jvmtiEnv* env,
>                 const char* prefix)

This function modifies the failure handling of native method resolution by allowing retry with a prefix applied to the name. When used with the ClassFileLoadHook event, it enables native methods to be instrumented.

Since native methods cannot be directly instrumented (they have no bytecodes), they must be wrapped with a non-native method which can be instrumented. For example, if we had:

>     native boolean foo(int x);

We could transform the class file (with the ClassFileLoadHook event) so that this becomes:

>     boolean foo(int x) {
>       ... record entry to foo ...
>       return wrapped_foo(x);
>     }

>     native boolean wrapped_foo(int x);

Where foo becomes a wrapper for the actual native method with the appended prefix "wrapped_". Note that "wrapped_" would be a poor choice of prefix since it might conceivably form the name of an existing method thus something like "$$$MyAgentWrapped$$$_" would be better but would make these examples less readable.

The wrapper will allow data to be collected on the native method call, but now the problem becomes linking up the wrapped method with the native implementation. That is, the method `wrapped_foo` needs to be resolved to the native implementation of `foo`, which might be:

>     Java_somePackage_someClass_foo(JNIEnv* env, jint x)

This function allows the prefix to be specified and the proper resolution to occur. Specifically, when the standard resolution fails, the resolution is retried taking the prefix into consideration. There are two ways that resolution occurs, explicit resolution with the JNI function `RegisterNatives` and the normal automatic resolution. For `RegisterNatives`, the VM will attempt this association:

>     method(foo) -> nativeImplementation(foo)

When this fails, the resolution will be retried with the specified prefix prepended to the method name, yielding the correct resolution:

>     method(wrapped_foo) -> nativeImplementation(foo)

For automatic resolution, the VM will attempt:

>     method(wrapped_foo) -> nativeImplementation(wrapped_foo)

When this fails, the resolution will be retried with the specified prefix deleted from the implementation name, yielding the correct resolution:

>     method(wrapped_foo) -> nativeImplementation(foo)

Note that since the prefix is only used when standard resolution fails, native methods can be wrapped selectively.

Since each JVM TI environment is independent and can do its own transformation of the bytecodes, more than one layer of wrappers may be applied. Thus each environment needs its own prefix. Since transformations are applied in order, the prefixes, if applied, will be applied in the same order. The order of transformation application is described in the `ClassFileLoadHook` event. Thus if three environments applied wrappers, `foo` might become `$env3_$env2_$env1_foo`. But if, say, the second environment did not apply a wrapper to `foo` it would be just `$env3_$env1_foo`. To be able to efficiently determine the sequence of prefixes, an intermediate prefix is only applied if its non-native wrapper exists. Thus, in the last example, even though `$env1_foo` is not a native method, the `$env1_` prefix is applied since `$env1_foo` exists.

Since the prefixes are used at resolution time and since resolution may be arbitrarily delayed, a native method prefix must remain set as long as there are corresponding prefixed native methods.

Phase | Callback Safe | Position | Since
may be called during any phase | No | 73 | 1.1

Capabilities
Optional Functionality: might not be implemented for all virtual machines. The following capability (as returned by `GetCapabilities`) must be true to use this function.
Capability | Effect
`can_set_native_method_prefix` | Can set prefix to be applied when native method cannot be resolved - `SetNativeMethodPrefix` and `SetNativeMethodPrefixes`

Parameters
Name | Type | Description
`prefix` | `const char *` | The prefix to apply, encoded as a modified UTF-8 string. Agent passes in an array of `char`. If `prefix` is `NULL`, any existing prefix in this environment is cancelled .

Errors
This function returns either a universal error or one of the following errors
Error | Description
`JVMTI_ERROR_MUST_POSSESS_CAPABILITY` | The environment does not possess the capability `can_set_native_method_prefix`. Use `AddCapabilities`.

### Set Native Method Prefixes

>     jvmtiError
>     SetNativeMethodPrefixes(jvmtiEnv* env,
>                 jint prefix_count,
>                 char** prefixes)

For a normal agent, `SetNativeMethodPrefix` will provide all needed native method prefixing. For a meta-agent that performs multiple independent class file transformations (for example as a proxy for another layer of agents) this function allows each transformation to have its own prefix. The prefixes are applied in the order supplied and are processed in the same manor as described for the application of prefixes from multiple JVM TI environments in `SetNativeMethodPrefix`.

Any previous prefixes are replaced. Thus, calling this function with a `prefix_count` of `0` disables prefixing in this environment.

`SetNativeMethodPrefix` and this function are the two ways to set the prefixes. Calling `SetNativeMethodPrefix` with a prefix is the same as calling this function with `prefix_count` of `1`. Calling `SetNativeMethodPrefix` with `NULL` is the same as calling this function with `prefix_count` of `0`.

Phase | Callback Safe | Position | Since
may be called during any phase | No | 74 | 1.1

Capabilities
Optional Functionality: might not be implemented for all virtual machines. The following capability (as returned by `GetCapabilities`) must be true to use this function.
Capability | Effect
`can_set_native_method_prefix` | Can set prefix to be applied when native method cannot be resolved - `SetNativeMethodPrefix` and `SetNativeMethodPrefixes`

Parameters
Name | Type | Description
`prefix_count` | `jint` | The number of prefixes to apply.
`prefixes` | `char **` | The prefixes to apply for this environment, each encoded as a modified UTF-8 string.

Errors
This function returns either a universal error or one of the following errors
Error | Description
`JVMTI_ERROR_MUST_POSSESS_CAPABILITY` | The environment does not possess the capability `can_set_native_method_prefix`. Use `AddCapabilities`.
`JVMTI_ERROR_ILLEGAL_ARGUMENT` | `prefix_count` is less than `0`.
`JVMTI_ERROR_NULL_POINTER` | `prefixes` is `NULL`.

## Raw Monitor

Raw Monitor functions:

- Create Raw Monitor
- Destroy Raw Monitor
- Raw Monitor Enter
- Raw Monitor Exit
- Raw Monitor Wait
- Raw Monitor Notify
- Raw Monitor Notify All

### Create Raw Monitor

>     jvmtiError
>     CreateRawMonitor(jvmtiEnv* env,
>                 const char* name,
>                 jrawMonitorID* monitor_ptr)

Create a raw monitor.

Phase | Callback Safe | Position | Since
may only be called during the OnLoad or the live phase | This function may be called from the callbacks to the Heap iteration functions, or from the event handlers for the `GarbageCollectionStart`, `GarbageCollectionFinish`, and `ObjectFree` events. | 31 | 1.0

Capabilities
Required Functionality

Parameters
Name | Type | Description
`name` | `const char*` | A name to identify the monitor, encoded as a modified UTF-8 string. Agent passes in an array of `char`.
`monitor_ptr` | `jrawMonitorID*` | On return, points to the created monitor. Agent passes a pointer to a `jrawMonitorID`. On return, the `jrawMonitorID` has been set.

Errors
This function returns either a universal error or one of the following errors
Error | Description
`JVMTI_ERROR_NULL_POINTER` | `name` is `NULL`.
`JVMTI_ERROR_NULL_POINTER` | `monitor_ptr` is `NULL`.

### Destroy Raw Monitor

>     jvmtiError
>     DestroyRawMonitor(jvmtiEnv* env,
>                 jrawMonitorID monitor)

Destroy the raw monitor. If the monitor being destroyed has been entered by this thread, it will be exited before it is destroyed. If the monitor being destroyed has been entered by another thread, an error will be returned and the monitor will not be destroyed.

Phase | Callback Safe | Position | Since
may only be called during the OnLoad or the live phase | This function may be called from the callbacks to the Heap iteration functions, or from the event handlers for the `GarbageCollectionStart`, `GarbageCollectionFinish`, and `ObjectFree` events. | 32 | 1.0

Capabilities
Required Functionality

Parameters
Name | Type | Description
`monitor` | `jrawMonitorID` | The monitor

Errors
This function returns either a universal error or one of the following errors
Error | Description
`JVMTI_ERROR_NOT_MONITOR_OWNER` | Not monitor owner
`JVMTI_ERROR_INVALID_MONITOR` | `monitor` is not a jrawMonitorID.

### Raw Monitor Enter

>     jvmtiError
>     RawMonitorEnter(jvmtiEnv* env,
>                 jrawMonitorID monitor)

Gain exclusive ownership of a raw monitor. The same thread may enter a monitor more then once. The thread must exit the monitor the same number of times as it is entered. If a monitor is entered during `OnLoad` (before attached threads exist) and has not exited when attached threads come into existence, the enter is considered to have occurred on the main thread.

Phase | Callback Safe | Position | Since
may be called during any phase | This function may be called from the callbacks to the Heap iteration functions, or from the event handlers for the `GarbageCollectionStart`, `GarbageCollectionFinish`, and `ObjectFree` events. | 33 | 1.0

Capabilities
Required Functionality

Parameters
Name | Type | Description
`monitor` | `jrawMonitorID` | The monitor

Errors
This function returns either a universal error or one of the following errors
Error | Description
`JVMTI_ERROR_INVALID_MONITOR` | `monitor` is not a jrawMonitorID.

### Raw Monitor Exit

>     jvmtiError
>     RawMonitorExit(jvmtiEnv* env,
>                 jrawMonitorID monitor)

Release exclusive ownership of a raw monitor.

Phase | Callback Safe | Position | Since
may be called during any phase | This function may be called from the callbacks to the Heap iteration functions, or from the event handlers for the `GarbageCollectionStart`, `GarbageCollectionFinish`, and `ObjectFree` events. | 34 | 1.0

Capabilities
Required Functionality

Parameters
Name | Type | Description
`monitor` | `jrawMonitorID` | The monitor

Errors
This function returns either a universal error or one of the following errors
Error | Description
`JVMTI_ERROR_NOT_MONITOR_OWNER` | Not monitor owner
`JVMTI_ERROR_INVALID_MONITOR` | `monitor` is not a jrawMonitorID.

### Raw Monitor Wait

>     jvmtiError
>     RawMonitorWait(jvmtiEnv* env,
>                 jrawMonitorID monitor,
>                 jlong millis)

Wait for notification of the raw monitor.

Causes the current thread to wait until either another thread calls `RawMonitorNotify` or `RawMonitorNotifyAll` for the specified raw monitor, or the specified timeout has elapsed.

Phase | Callback Safe | Position | Since
may be called during any phase | This function may be called from the callbacks to the Heap iteration functions, or from the event handlers for the `GarbageCollectionStart`, `GarbageCollectionFinish`, and `ObjectFree` events. | 35 | 1.0

Capabilities
Required Functionality

Parameters
Name | Type | Description
`monitor` | `jrawMonitorID` | The monitor
`millis` | `jlong` | The timeout, in milliseconds. If the timeout is zero, then real time is not taken into consideration and the thread simply waits until notified.

Errors
This function returns either a universal error or one of the following errors
Error | Description
`JVMTI_ERROR_NOT_MONITOR_OWNER` | Not monitor owner
`JVMTI_ERROR_INTERRUPT` | Wait was interrupted, try again
`JVMTI_ERROR_INVALID_MONITOR` | `monitor` is not a jrawMonitorID.

### Raw Monitor Notify

>     jvmtiError
>     RawMonitorNotify(jvmtiEnv* env,
>                 jrawMonitorID monitor)

Notify a single thread waiting on the raw monitor.

Phase | Callback Safe | Position | Since
may be called during any phase | This function may be called from the callbacks to the Heap iteration functions, or from the event handlers for the `GarbageCollectionStart`, `GarbageCollectionFinish`, and `ObjectFree` events. | 36 | 1.0

Capabilities
Required Functionality

Parameters
Name | Type | Description
`monitor` | `jrawMonitorID` | The monitor

Errors
This function returns either a universal error or one of the following errors
Error | Description
`JVMTI_ERROR_NOT_MONITOR_OWNER` | Not monitor owner
`JVMTI_ERROR_INVALID_MONITOR` | `monitor` is not a jrawMonitorID.

### Raw Monitor Notify All

>     jvmtiError
>     RawMonitorNotifyAll(jvmtiEnv* env,
>                 jrawMonitorID monitor)

Notify all threads waiting on the raw monitor.

Phase | Callback Safe | Position | Since
may be called during any phase | This function may be called from the callbacks to the Heap iteration functions, or from the event handlers for the `GarbageCollectionStart`, `GarbageCollectionFinish`, and `ObjectFree` events. | 37 | 1.0

Capabilities
Required Functionality

Parameters
Name | Type | Description
`monitor` | `jrawMonitorID` | The monitor

Errors
This function returns either a universal error or one of the following errors
Error | Description
`JVMTI_ERROR_NOT_MONITOR_OWNER` | Not monitor owner
`JVMTI_ERROR_INVALID_MONITOR` | `monitor` is not a jrawMonitorID.

## JNI Function Interception

JNI Function Interception functions:

- Set JNI Function Table
- Get JNI Function Table

Provides the ability to intercept and resend Java Native Interface (JNI) function calls by manipulating the JNI function table. See JNI Functions in the Java Native Interface Specification.

The following example illustrates intercepting the `NewGlobalRef` JNI call in order to count reference creation.

>     JNIEnv original_jni_Functions;
>     JNIEnv redirected_jni_Functions;
>     int my_global_ref_count = 0;

>     jobject
>     MyNewGlobalRef(JNIEnv *jni_env, jobject lobj) {
>        ++my_global_ref_count;
>        return originalJNIFunctions->NewGlobalRef(env, lobj);
>     }

>     void
>     myInit() {
>        jvmtiError err;

>        err = (*jvmti_env)->GetJNIFunctionTable(jvmti_env, &original_jni_Functions);
>        if (err != JVMTI_ERROR_NONE) {
>           die();
>        }
>        err = (*jvmti_env)->GetJNIFunctionTable(jvmti_env, &redirected_jni_Functions);
>        if (err != JVMTI_ERROR_NONE) {
>           die();
>        }
>        redirectedJNIFunctions->NewGlobalRef = MyNewGlobalRef;
>           err = (*jvmti_env)->SetJNIFunctionTable(jvmti_env, redirected_jni_Functions);
>        if (err != JVMTI_ERROR_NONE) {
>           die();
>        }
>     }

Sometime after `myInit` is called the user's JNI code is executed which makes the call to create a new global reference. Instead of going to the normal JNI implementation the call goes to `myNewGlobalRef`. Note that a copy of the original function table is kept so that the normal JNI function can be called after the data is collected. Note also that any JNI functions which are not overwritten will behave normally.

### Set JNI Function Table

>     jvmtiError
>     SetJNIFunctionTable(jvmtiEnv* env,
>                 const jniNativeInterface* function_table)

Set the JNI function table in all current and future JNI environments. As a result, all future JNI calls are directed to the specified functions. Use `GetJNIFunctionTable` to get the function table to pass to this function. For this function to take effect the the updated table entries must be used by the JNI clients. Since the table is defined `const` some compilers may optimize away the access to the table, thus preventing this function from taking effect. The table is copied--changes to the local copy of the table have no effect. This function affects only the function table, all other aspects of the environment are unaffected. See the examples above.

Phase | Callback Safe | Position | Since
may only be called during the start or the live phase | No | 120 | 1.0

Capabilities
Required Functionality

Parameters
Name | Type | Description
`function_table` | `const jniNativeInterface *` | Points to the new JNI function table. Agent passes in a pointer to `jniNativeInterface`.

Errors
This function returns either a universal error or one of the following errors
Error | Description
`JVMTI_ERROR_NULL_POINTER` | `function_table` is `NULL`.

### Get JNI Function Table

>     jvmtiError
>     GetJNIFunctionTable(jvmtiEnv* env,
>                 jniNativeInterface** function_table)

Get the JNI function table. The JNI function table is copied into allocated memory. If `SetJNIFunctionTable` has been called, the modified (not the original) function table is returned. Only the function table is copied, no other aspects of the environment are copied. See the examples above.

Phase | Callback Safe | Position | Since
may only be called during the start or the live phase | No | 121 | 1.0

Capabilities
Required Functionality

Parameters
Name | Type | Description
`function_table` | `jniNativeInterface **` | On return, `*function_table` points a newly allocated copy of the JNI function table. Agent passes a pointer to a `jniNativeInterface*`. On return, the `jniNativeInterface*` points to a newly allocated array. The array should be freed with `Deallocate`.

Errors
This function returns either a universal error or one of the following errors
Error | Description
`JVMTI_ERROR_NULL_POINTER` | `function_table` is `NULL`.

## Event Management

Event Management functions:

- Set Event Callbacks
- Set Event Notification Mode
- Generate Events

Event Management types:

- `jvmtiEventMode` - Event Enable/Disable

### Set Event Callbacks

>     jvmtiError
>     SetEventCallbacks(jvmtiEnv* env,
>                 const jvmtiEventCallbacks* callbacks,
>                 jint size_of_callbacks)

Set the functions to be called for each event. The callbacks are specified by supplying a replacement function table. The function table is copied--changes to the local copy of the table have no effect. This is an atomic action, all callbacks are set at once. No events are sent before this function is called. When an entry is `NULL` or when the event is beyond `size_of_callbacks` no event is sent. Details on events are described later in this document. An event must be enabled and have a callback in order to be sent--the order in which this function and `SetEventNotificationMode` are called does not affect the result.

Phase | Callback Safe | Position | Since
may only be called during the OnLoad or the live phase | No | 122 | 1.0

Capabilities
Required Functionality

Parameters
Name | Type | Description
`callbacks` | `const jvmtiEventCallbacks *` | The new event callbacks. Agent passes in a pointer to `jvmtiEventCallbacks`. If `callbacks` is `NULL`, remove the existing callbacks.
`size_of_callbacks` | `jint` | `sizeof(jvmtiEventCallbacks)`--for version compatibility.

Errors
This function returns either a universal error or one of the following errors
Error | Description
`JVMTI_ERROR_ILLEGAL_ARGUMENT` | `size_of_callbacks` is less than `0`.

### Set Event Notification Mode

>     typedef enum {
>         JVMTI_ENABLE = 1,
>         JVMTI_DISABLE = 0
>     } jvmtiEventMode;

>     jvmtiError
>     SetEventNotificationMode(jvmtiEnv* env,
>                 jvmtiEventMode mode,
>                 jvmtiEvent event_type,
>                 jthread event_thread,
>                  ...)

Control the generation of events.

> Event Enable/Disable (`jvmtiEventMode`)
> Constant | Value | Description
> `JVMTI_ENABLE` | 1 | If `mode` is `JVMTI_ENABLE`, the event `event_type` will be enabled
> `JVMTI_DISABLE` | 0 | If `mode` is `JVMTI_DISABLE`, the event `event_type` will be disabled

If `thread` is `NULL`, the event is enabled or disabled globally; otherwise, it is enabled or disabled for a particular thread. An event is generated for a particular thread if it is enabled either at the thread or global levels.

See below for information on specific events.

The following events cannot be controlled at the thread level through this function.

- `VMInit`
- `VMStart`
- `VMDeath`
- `ThreadStart`
- `CompiledMethodLoad`
- `CompiledMethodUnload`
- `DynamicCodeGenerated`
- `DataDumpRequest`

Initially, no events are enabled at either the thread level or the global level.

Any needed capabilities (see Event Enabling Capabilities below) must be possessed before calling this function.

Details on events are described below.

Phase | Callback Safe | Position | Since
may only be called during the OnLoad or the live phase | No | 2 | 1.0

Capabilities
Required Functionality
Event Enabling Capabilities
Capability | Events
`can_generate_field_modification_events` | `FieldModification`
`can_generate_field_access_events` | `FieldAccess`
`can_generate_single_step_events` | `SingleStep`
`can_generate_exception_events` | `Exception` `ExceptionCatch`
`can_generate_frame_pop_events` | `FramePop`
`can_generate_breakpoint_events` | `Breakpoint`
`can_generate_method_entry_events` | `MethodEntry`
`can_generate_method_exit_events` | `MethodExit`
`can_generate_compiled_method_load_events` | `CompiledMethodLoad` `CompiledMethodUnload`
`can_generate_monitor_events` | `MonitorContendedEnter` `MonitorContendedEntered` `MonitorWait` `MonitorWaited`
`can_generate_vm_object_alloc_events` | `VMObjectAlloc`
`can_generate_native_method_bind_events` | `NativeMethodBind`
`can_generate_garbage_collection_events` | `GarbageCollectionStart` `GarbageCollectionFinish`
`can_generate_object_free_events` | `ObjectFree`

Parameters
Name | Type | Description
`mode` | `jvmtiEventMode` | `JVMTI_ENABLE` or `JVMTI_DISABLE`
`event_type` | `jvmtiEvent` | the event to control
`event_thread` | `jthread` | The thread to control If `event_thread` is `NULL`, event is controlled at the global level.
`...` | `...` | for future expansion

Errors
This function returns either a universal error or one of the following errors
Error | Description
`JVMTI_ERROR_INVALID_THREAD` | `event_thread` is non-`NULL` and is not a valid thread.
`JVMTI_ERROR_THREAD_NOT_ALIVE` | `event_thread` is non-`NULL` and is not live (has not been started or is now dead).
`JVMTI_ERROR_ILLEGAL_ARGUMENT` | thread level control was attempted on events which do not permit thread level control.
`JVMTI_ERROR_MUST_POSSESS_CAPABILITY` | The Required Event Enabling Capability is not possessed.
`JVMTI_ERROR_ILLEGAL_ARGUMENT` | `mode` is not a jvmtiEventMode.
`JVMTI_ERROR_INVALID_EVENT_TYPE` | `event_type` is not a jvmtiEvent.

### Generate Events

>     jvmtiError
>     GenerateEvents(jvmtiEnv* env,
>                 jvmtiEvent event_type)

Generate events to represent the current state of the VM. For example, if `event_type` is `JVMTI_EVENT_COMPILED_METHOD_LOAD`, a `CompiledMethodLoad` event will be sent for each currently compiled method. Methods that were loaded and now have been unloaded are not sent. The history of what events have previously been sent does not effect what events are sent by this function--for example, all currently compiled methods will be sent each time this function is called.

This function is useful when events may have been missed due to the agent attaching after program execution begins; this function generates the missed events.

Attempts to execute Java programming language code or JNI functions may be paused until this function returns - so neither should be called from the thread sending the event. This function returns only after the missed events have been sent, processed and have returned. The event may be sent on a different thread than the thread on which the event occurred. The callback for the event must be set with `SetEventCallbacks` and the event must be enabled with `SetEventNotificationMode` or the events will not occur. If the VM no longer has the information to generate some or all of the requested events, the events are simply not sent - no error is returned.

Only the following events are supported:

- `CompiledMethodLoad`
- `DynamicCodeGenerated`

Phase | Callback Safe | Position | Since
may only be called during the live phase | No | 123 | 1.0

Capabilities
Required Functionality
Optional Features
Capability | Effect
`can_generate_compiled_method_load_events` | Can generate events when a method is compiled or unloaded

Parameters
Name | Type | Description
`event_type` | `jvmtiEvent` | The type of event to generate. Must be one of these: `JVMTI_EVENT_COMPILED_METHOD_LOAD` `JVMTI_EVENT_DYNAMIC_CODE_GENERATED`

Errors
This function returns either a universal error or one of the following errors
Error | Description
`JVMTI_ERROR_MUST_POSSESS_CAPABILITY` | `event_type` is `JVMTI_EVENT_COMPILED_METHOD_LOAD` and `can_generate_compiled_method_load_events` is `false`.
`JVMTI_ERROR_ILLEGAL_ARGUMENT` | `event_type` is other than `JVMTI_EVENT_COMPILED_METHOD_LOAD` or `JVMTI_EVENT_DYNAMIC_CODE_GENERATED`.
`JVMTI_ERROR_INVALID_EVENT_TYPE` | `event_type` is not a jvmtiEvent.

## Extension Mechanism

Extension Mechanism functions:

- Get Extension Functions
- Get Extension Events
- Set Extension Event Callback

Extension Mechanism function types:

- Extension Function
- Extension Event

Extension Mechanism types:

- `jvmtiParamTypes` - Extension Function/Event Parameter Types
- `jvmtiParamKind` - Extension Function/Event Parameter Kinds
- `jvmtiParamInfo` - Extension Function/Event Parameter Info
- `jvmtiExtensionFunctionInfo` - Extension Function Info
- `jvmtiExtensionEventInfo` - Extension Event Info

These functions allow a JVM TI implementation to provide functions and events beyond those defined in this specification.

Both extension functions and extension events have parameters each of which has a 'type' and 'kind' chosen from the following tables:

> Extension Function/Event Parameter Types (`jvmtiParamTypes`)
> Constant | Value | Description
> `JVMTI_TYPE_JBYTE` | 101 | Java programming language primitive type - `byte`. JNI type `jbyte`.
> `JVMTI_TYPE_JCHAR` | 102 | Java programming language primitive type - `char`. JNI type `jchar`.
> `JVMTI_TYPE_JSHORT` | 103 | Java programming language primitive type - `short`. JNI type `jshort`.
> `JVMTI_TYPE_JINT` | 104 | Java programming language primitive type - `int`. JNI type `jint`.
> `JVMTI_TYPE_JLONG` | 105 | Java programming language primitive type - `long`. JNI type `jlong`.
> `JVMTI_TYPE_JFLOAT` | 106 | Java programming language primitive type - `float`. JNI type `jfloat`.
> `JVMTI_TYPE_JDOUBLE` | 107 | Java programming language primitive type - `double`. JNI type `jdouble`.
> `JVMTI_TYPE_JBOOLEAN` | 108 | Java programming language primitive type - `boolean`. JNI type `jboolean`.
> `JVMTI_TYPE_JOBJECT` | 109 | Java programming language object type - `java.lang.Object`. JNI type `jobject`. Returned values are JNI local references and must be managed.
> `JVMTI_TYPE_JTHREAD` | 110 | Java programming language object type - `java.lang.Thread`. JVM TI type `jthread`. Returned values are JNI local references and must be managed.
> `JVMTI_TYPE_JCLASS` | 111 | Java programming language object type - `java.lang.Class`. JNI type `jclass`. Returned values are JNI local references and must be managed.
> `JVMTI_TYPE_JVALUE` | 112 | Union of all Java programming language primitive and object types - JNI type `jvalue`. Returned values which represent object types are JNI local references and must be managed.
> `JVMTI_TYPE_JFIELDID` | 113 | Java programming language field identifier - JNI type `jfieldID`.
> `JVMTI_TYPE_JMETHODID` | 114 | Java programming language method identifier - JNI type `jmethodID`.
> `JVMTI_TYPE_CCHAR` | 115 | C programming language type - `char`.
> `JVMTI_TYPE_CVOID` | 116 | C programming language type - `void`.
> `JVMTI_TYPE_JNIENV` | 117 | JNI environment - `JNIEnv`. Should be used with the correct `jvmtiParamKind` to make it a pointer type.

> Extension Function/Event Parameter Kinds (`jvmtiParamKind`)
> Constant | Value | Description
> `JVMTI_KIND_IN` | 91 | Ingoing argument - `foo`.
> `JVMTI_KIND_IN_PTR` | 92 | Ingoing pointer argument - `const foo*`.
> `JVMTI_KIND_IN_BUF` | 93 | Ingoing array argument - `const foo*`.
> `JVMTI_KIND_ALLOC_BUF` | 94 | Outgoing allocated array argument - `foo**`. Free with `Deallocate`.
> `JVMTI_KIND_ALLOC_ALLOC_BUF` | 95 | Outgoing allocated array of allocated arrays argument - `foo***`. Free with `Deallocate`.
> `JVMTI_KIND_OUT` | 96 | Outgoing argument - `foo*`.
> `JVMTI_KIND_OUT_BUF` | 97 | Outgoing array argument (pre-allocated by agent) - `foo*`. Do not `Deallocate`.

#### Extension Function/Event Parameter Info

>     typedef struct {
>         char* name;
>         jvmtiParamKind kind;
>         jvmtiParamTypes base_type;
>         jboolean null_ok;
>     } jvmtiParamInfo;

> `jvmtiParamInfo` - Extension Function/Event Parameter Info
> Field | Type | Description
> `name` | `char*` | The parameter name, encoded as a modified UTF-8 string
> `kind` | `jvmtiParamKind` | The kind of the parameter - type modifiers
> `base_type` | `jvmtiParamTypes` | The base type of the parameter - modified by `kind`
> `null_ok` | `jboolean` | Is a `NULL` argument permitted? Applies only to pointer and object types.

### Extension Function

>     typedef jvmtiError (JNICALL *jvmtiExtensionFunction)
>         (jvmtiEnv* jvmti_env,
>           ...);
This is the implementation-specific extension function.
Parameters
Name | Type | Description
`jvmti_env` | `jvmtiEnv *` | The JVM TI environment is the only fixed parameter for extension functions.
`...` | `...` | The extension function-specific parameters

### Get Extension Functions

>     typedef struct {
>         jvmtiExtensionFunction func;
>         char* id;
>         char* short_description;
>         jint param_count;
>         jvmtiParamInfo* params;
>         jint error_count;
>         jvmtiError* errors;
>     } jvmtiExtensionFunctionInfo;

>     jvmtiError
>     GetExtensionFunctions(jvmtiEnv* env,
>                 jint* extension_count_ptr,
>                 jvmtiExtensionFunctionInfo** extensions)

Returns the set of extension functions.

Phase | Callback Safe | Position | Since
may only be called during the OnLoad or the live phase | No | 124 | 1.0

Capabilities
Required Functionality

`jvmtiExtensionFunctionInfo` - Extension Function Info
Field | Type | Description
`func` | `jvmtiExtensionFunction` | The actual function to call
`id` | `char*` | The identifier for the extension function, encoded as a modified UTF-8 string. Uses package name conventions. For example, `com.sun.hotspot.bar`
`short_description` | `char*` | A one sentence description of the function, encoded as a modified UTF-8 string.
`param_count` | `jint` | The number of parameters excluding `jvmtiEnv *jvmti_env`
`params` | `jvmtiParamInfo *` | Array of `param_count` parameters (`jvmtiEnv *jvmti_env` excluded)
`error_count` | `jint` | The number of possible error returns (excluding universal errors)
`errors` | `jvmtiError *` | Array of `error_count` possible errors

Parameters
Name | Type | Description
`extension_count_ptr` | `jint*` | On return, points to the number of extension functions Agent passes a pointer to a `jint`. On return, the `jint` has been set.
`extensions` | `jvmtiExtensionFunctionInfo**` | Returns an array of extension function info, one per function Agent passes a pointer to a `jvmtiExtensionFunctionInfo*`. On return, the `jvmtiExtensionFunctionInfo*` points to a newly allocated array of size `*extension_count_ptr`. The array should be freed with `Deallocate`. The pointers returned in the field `id` of `jvmtiExtensionFunctionInfo` are newly allocated arrays. The arrays should be freed with `Deallocate`. The pointers returned in the field `short_description` of `jvmtiExtensionFunctionInfo` are newly allocated arrays. The arrays should be freed with `Deallocate`. The pointers returned in the field `params` of `jvmtiExtensionFunctionInfo` are newly allocated arrays. The arrays should be freed with `Deallocate`. The pointers returned in the field `name` of `jvmtiParamInfo` are newly allocated arrays. The arrays should be freed with `Deallocate`. The pointers returned in the field `errors` of `jvmtiExtensionFunctionInfo` are newly allocated arrays. The arrays should be freed with `Deallocate`.

Errors
This function returns either a universal error or one of the following errors
Error | Description
`JVMTI_ERROR_NULL_POINTER` | `extension_count_ptr` is `NULL`.
`JVMTI_ERROR_NULL_POINTER` | `extensions` is `NULL`.

### Get Extension Events

>     typedef struct {
>         jint extension_event_index;
>         char* id;
>         char* short_description;
>         jint param_count;
>         jvmtiParamInfo* params;
>     } jvmtiExtensionEventInfo;

>     jvmtiError
>     GetExtensionEvents(jvmtiEnv* env,
>                 jint* extension_count_ptr,
>                 jvmtiExtensionEventInfo** extensions)

Returns the set of extension events.

Phase | Callback Safe | Position | Since
may only be called during the OnLoad or the live phase | No | 125 | 1.0

Capabilities
Required Functionality

`jvmtiExtensionEventInfo` - Extension Event Info
Field | Type | Description
`extension_event_index` | `jint` | The identifying index of the event
`id` | `char*` | The identifier for the extension event, encoded as a modified UTF-8 string. Uses package name conventions. For example, `com.sun.hotspot.bar`
`short_description` | `char*` | A one sentence description of the event, encoded as a modified UTF-8 string.
`param_count` | `jint` | The number of parameters excluding `jvmtiEnv *jvmti_env`
`params` | `jvmtiParamInfo *` | Array of `param_count` parameters (`jvmtiEnv *jvmti_env` excluded)

Parameters
Name | Type | Description
`extension_count_ptr` | `jint*` | On return, points to the number of extension events Agent passes a pointer to a `jint`. On return, the `jint` has been set.
`extensions` | `jvmtiExtensionEventInfo**` | Returns an array of extension event info, one per event Agent passes a pointer to a `jvmtiExtensionEventInfo*`. On return, the `jvmtiExtensionEventInfo*` points to a newly allocated array of size `*extension_count_ptr`. The array should be freed with `Deallocate`. The pointers returned in the field `id` of `jvmtiExtensionEventInfo` are newly allocated arrays. The arrays should be freed with `Deallocate`. The pointers returned in the field `short_description` of `jvmtiExtensionEventInfo` are newly allocated arrays. The arrays should be freed with `Deallocate`. The pointers returned in the field `params` of `jvmtiExtensionEventInfo` are newly allocated arrays. The arrays should be freed with `Deallocate`. The pointers returned in the field `name` of `jvmtiParamInfo` are newly allocated arrays. The arrays should be freed with `Deallocate`.

Errors
This function returns either a universal error or one of the following errors
Error | Description
`JVMTI_ERROR_NULL_POINTER` | `extension_count_ptr` is `NULL`.
`JVMTI_ERROR_NULL_POINTER` | `extensions` is `NULL`.

### Extension Event

>     typedef void (JNICALL *jvmtiExtensionEvent)
>         (jvmtiEnv* jvmti_env,
>           ...);
> This is the implementation-specific event. The event handler is set with `SetExtensionEventCallback`. Event handlers for extension events must be declared varargs to match this definition. Failure to do so could result in calling convention mismatch and undefined behavior on some platforms. For example, if the `jvmtiParamInfo` returned by `GetExtensionEvents` indicates that there is a `jint` parameter, the event handler should be declared:
>         void JNICALL myHandler(jvmtiEnv* jvmti_env, jint myInt, ...)
Note the terminal "`...`" which indicates varargs.
Parameters
Name | Type | Description
`jvmti_env` | `jvmtiEnv *` | The JVM TI environment is the only fixed parameter for extension events.
`...` | `...` | The extension event-specific parameters

### Set Extension Event Callback

>     jvmtiError
>     SetExtensionEventCallback(jvmtiEnv* env,
>                 jint extension_event_index,
>                 jvmtiExtensionEvent callback)

Sets the callback function for an extension event and enables the event. Or, if the callback is `NULL`, disables the event. Note that unlike standard events, setting the callback and enabling the event are a single operation.

Phase | Callback Safe | Position | Since
may only be called during the OnLoad or the live phase | No | 126 | 1.0

Capabilities
Required Functionality

Parameters
Name | Type | Description
`extension_event_index` | `jint` | Identifies which callback to set. This index is the `extension_event_index` field of `jvmtiExtensionEventInfo`.
`callback` | `jvmtiExtensionEvent` | If `callback` is non-`NULL`, set `callback` to be the event callback function and enable the event. If `callback` is `NULL`, disable the event.

Errors
This function returns either a universal error or one of the following errors
Error | Description
`JVMTI_ERROR_ILLEGAL_ARGUMENT` | `extension_event_index` is not an `extension_event_index` returned by `GetExtensionEvents`

## Capability

Capability functions:

- Get Potential Capabilities
- Add Capabilities
- Relinquish Capabilities
- Get Capabilities

Capability types:

- `jvmtiCapabilities` - The Capabilities Structure

The capabilities functions allow you to change the functionality available to JVM TI--that is, which JVM TI functions can be called, what events can be generated, and what functionality these events and functions can provide.

The "Capabilities" section of each function and event describe which capabilities, if any, they are associated with. "Required Functionality" means it is available for use and no capabilities must be added to use it. "Optional Functionality" means the agent must possess the capability before it can be used. To possess a capability, the agent must add the capability. "Optional Features" describe capabilities which, if added, extend the feature set.

The potentially available capabilities of each JVM TI implementation are different. Depending on the implementation, a capability:

- may never be added
- may be added in either the `OnLoad` or live phase in any environment
- may be added only during the `OnLoad` phase
- may be possessed by only one environment at a time
- may be possessed by only one environment at a time, and only during the `OnLoad` phase
- and so on ...

Frequently, the addition of a capability may incur a cost in execution speed, start up time, and/or memory footprint. Note that the overhead of using a capability is completely different than the overhead of possessing a capability. Take single stepping as an example. When single stepping is on (that is, when the event is enabled and thus actively sending events) the overhead of sending and processing an event on each instruction is huge in any implementation. However, the overhead of possessing the capability may be small or large, depending on the implementation. Also, when and if a capability is potentially available depends on the implementation. Some examples:

- One VM might perform all execution by compiling bytecodes into native code and be unable to generate single step instructions. In this implementation the capability can not be added.
- Another VM may be able to switch execution to a single stepping interpreter at any time. In this implementation, having the capability has no overhead and could be added at any time.
- Yet another VM might be able to choose a bytecode compiling or single stepping capable interpreted execution engine at start up, but be unable to switch between them. In this implementation the capability would need to be added during the `OnLoad` phase (before bytecode execution begins) and would have a large impact on execution speed even if single stepping was never used.
- Still another VM might be able to add an "is single stepping on" check into compiled bytecodes or a generated interpreter. Again in this implementation the capability would need to be added during the `OnLoad` phase but the overhead (a test and branch on each instruction) would be considerably less.

Each JVM TI environment has its own set of capabilities. Initially, that set is empty. Any desired capability must be added. If possible, capabilities should be added during the `OnLoad` phase. For most virtual machines certain capabilities require special set up for the virtual machine and this set up must happen during the `OnLoad` phase, before the virtual machine begins execution. Once a capability is added, it can only be removed if explicitly relinquished by the environment.

The agent can, determine what capabilities this VM can potentially provide, add the capabilities to be used, release capabilities which are no longer needed, and examine the currently available capabilities.

#### Capability Examples

For example, a freshly started agent (in the `OnLoad` function) wants to enable all possible capabilities. Note that, in general, this is not advisable as the agent may suffer a performance penalty for functionality it is not using. The code might look like this in C:

>     	jvmtiCapabilities capa;
>     	jvmtiError err;

>     	err = (*jvmti)->GetPotentialCapabilities(jvmti, &capa);
>     	if (err == JVMTI_ERROR_NONE) {
>     	   err = (*jvmti)->AddCapabilities(jvmti, &capa);

For example, if an agent wants to check if it can get the bytecodes of a method (that is, it wants to check if it previously added this capability and has not relinquished it), the code might look like this in C:

>     	jvmtiCapabilities capa;
>     	jvmtiError err;

>     	err = (*jvmti)->GetCapabilities(jvmti, &capa);
>     	if (err == JVMTI_ERROR_NONE) {
>        	   if (capa.can_get_bytecodes) { ... } }

#### The Capabilities Structure

The functions in this category use this capabilities structure which contains boolean flags corresponding to each capability:

> >     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;

> `jvmtiCapabilities` - The Capabilities Structure
> All types are `unsigned int : 1`
> Field | Description | Since
> `can_tag_objects` | Can set and get tags, as described in the Heap category. | 1.0
> `can_generate_field_modification_events` | Can set watchpoints on field modification - `SetFieldModificationWatch` | 1.0
> `can_generate_field_access_events` | Can set watchpoints on field access - `SetFieldAccessWatch` | 1.0
> `can_get_bytecodes` | Can get bytecodes of a method `GetBytecodes` | 1.0
> `can_get_synthetic_attribute` | Can test if a field or method is synthetic - `IsFieldSynthetic` and `IsMethodSynthetic` | 1.0
> `can_get_owned_monitor_info` | Can get information about ownership of monitors - `GetOwnedMonitorInfo` | 1.0
> `can_get_current_contended_monitor` | Can `GetCurrentContendedMonitor` | 1.0
> `can_get_monitor_info` | Can `GetObjectMonitorUsage` | 1.0
> `can_pop_frame` | Can pop frames off the stack - `PopFrame` | 1.0
> `can_redefine_classes` | Can redefine classes with `RedefineClasses`. | 1.0
> `can_signal_thread` | Can send stop or interrupt to threads | 1.0
> `can_get_source_file_name` | Can get the source file name of a class | 1.0
> `can_get_line_numbers` | Can get the line number table of a method | 1.0
> `can_get_source_debug_extension` | Can get the source debug extension of a class | 1.0
> `can_access_local_variables` | Can set and get local variables | 1.0
> `can_maintain_original_method_order` | Can return methods in the order they occur in the class file | 1.0
> `can_generate_single_step_events` | Can get single step events | 1.0
> `can_generate_exception_events` | Can get exception thrown and exception catch events | 1.0
> `can_generate_frame_pop_events` | Can set and thus get `FramePop` events | 1.0
> `can_generate_breakpoint_events` | Can set and thus get `Breakpoint` events | 1.0
> `can_suspend` | Can suspend and resume threads | 1.0
> `can_redefine_any_class` | Can modify (retransform or redefine) any non-primitive non-array class. See `IsModifiableClass`. | 1.0
> `can_get_current_thread_cpu_time` | Can get current thread CPU time | 1.0
> `can_get_thread_cpu_time` | Can get thread CPU time | 1.0
> `can_generate _method_entry_events` | Can generate method entry events on entering a method | 1.0
> `can_generate _method_exit_events` | Can generate method exit events on leaving a method | 1.0
> `can_generate _all_class_hook_events` | Can generate ClassFileLoadHook events for every loaded class. | 1.0
> `can_generate _compiled_method_load_events` | Can generate events when a method is compiled or unloaded | 1.0
> `can_generate _monitor_events` | Can generate events on monitor activity | 1.0
> `can_generate _vm_object_alloc_events` | Can generate events on VM allocation of an object | 1.0
> `can_generate _native_method_bind_events` | Can generate events when a native method is bound to its implementation | 1.0
> `can_generate _garbage_collection_events` | Can generate events when garbage collection begins or ends | 1.0
> `can_generate _object_free_events` | Can generate events when the garbage collector frees an object | 1.0
> `can_force_early_return` | Can return early from a method, as described in the Force Early Return category. | 1.1
> `can_get_owned_monitor_stack_depth_info` | Can get information about owned monitors with stack depth - `GetOwnedMonitorStackDepthInfo` | 1.1
> `can_get_constant_pool` | Can get the constant pool of a class - `GetConstantPool` | 1.1
> `can_set_native_method_prefix` | Can set prefix to be applied when native method cannot be resolved - `SetNativeMethodPrefix` and `SetNativeMethodPrefixes` | 1.1
> `can_retransform_classes` | Can retransform classes with `RetransformClasses`. In addition to the restrictions imposed by the specific implementation on this capability (see the Capability section), this capability must be set before the `ClassFileLoadHook` event is enabled for the first time in this environment. An environment that possesses this capability at the time that `ClassFileLoadHook` is enabled for the first time is said to be retransformation capable. An environment that does not possess this capability at the time that `ClassFileLoadHook` is enabled for the first time is said to be retransformation incapable. | 1.1
> `can_retransform_any_class` | `RetransformClasses` can be called on any class (`can_retransform_classes` must also be set) | 1.1
> `can_generate_resource_exhaustion_heap_events` | Can generate events when the VM is unable to allocate memory from the JavaTM platform heap. See `ResourceExhausted`. | 1.1
> `can_generate_resource_exhaustion_threads_events` | Can generate events when the VM is unable to create a thread. See `ResourceExhausted`. | 1.1

### Get Potential Capabilities

>     jvmtiError
>     GetPotentialCapabilities(jvmtiEnv* env,
>                 jvmtiCapabilities* capabilities_ptr)

Returns via `capabilities_ptr` the JVM TI features that can potentially be possessed by this environment at this time. The returned capabilities differ from the complete set of capabilities implemented by the VM in two cases: another environment possesses capabilities that can only be possessed by one environment, or the current phase is live, and certain capabilities can only be added during the `OnLoad` phase. The `AddCapabilities` function may be used to set any or all or these capabilities. Currently possessed capabilities are included.

Typically this function is used in the `OnLoad` function. Some virtual machines may allow a limited set of capabilities to be added in the live phase. In this case, the set of potentially available capabilities will likely differ from the `OnLoad` phase set.

See the Capability Examples.

Phase | Callback Safe | Position | Since
may only be called during the OnLoad or the live phase | No | 140 | 1.0

Capabilities
Required Functionality

Parameters
Name | Type | Description
`capabilities_ptr` | `jvmtiCapabilities*` | On return, points to the JVM TI capabilities that may be added. Agent passes a pointer to a `jvmtiCapabilities`. On return, the `jvmtiCapabilities` has been set.

Errors
This function returns either a universal error or one of the following errors
Error | Description
`JVMTI_ERROR_NULL_POINTER` | `capabilities_ptr` is `NULL`.

### Add Capabilities

>     jvmtiError
>     AddCapabilities(jvmtiEnv* env,
>                 const jvmtiCapabilities* capabilities_ptr)

Set new capabilities by adding the capabilities whose values are set to one (`1`) in `*``capabilities_ptr`. All previous capabilities are retained. Typically this function is used in the `OnLoad` function. Some virtual machines may allow a limited set of capabilities to be added in the live phase.

See the Capability Examples.

Phase | Callback Safe | Position | Since
may only be called during the OnLoad or the live phase | No | 142 | 1.0

Capabilities
Required Functionality

Parameters
Name | Type | Description
`capabilities_ptr` | `const jvmtiCapabilities*` | Points to the JVM TI capabilities to add. Agent passes in a pointer to `jvmtiCapabilities`.

Errors
This function returns either a universal error or one of the following errors
Error | Description
`JVMTI_ERROR_NOT_AVAILABLE` | The desired capabilities are not even potentially available.
`JVMTI_ERROR_NULL_POINTER` | `capabilities_ptr` is `NULL`.

### Relinquish Capabilities

>     jvmtiError
>     RelinquishCapabilities(jvmtiEnv* env,
>                 const jvmtiCapabilities* capabilities_ptr)

Relinquish the capabilities whose values are set to one (`1`) in `*``capabilities_ptr`. Some implementations may allow only one environment to have a capability (see the capability introduction). This function releases capabilities so that they may be used by other agents. All other capabilities are retained. The capability will no longer be present in `GetCapabilities`. Attempting to relinquish a capability that the agent does not possess is not an error.

Phase | Callback Safe | Position | Since
may only be called during the OnLoad or the live phase | No | 143 | 1.0

Capabilities
Required Functionality

Parameters
Name | Type | Description
`capabilities_ptr` | `const jvmtiCapabilities*` | Points to the JVM TI capabilities to relinquish. Agent passes in a pointer to `jvmtiCapabilities`.

Errors
This function returns either a universal error or one of the following errors
Error | Description
`JVMTI_ERROR_NULL_POINTER` | `capabilities_ptr` is `NULL`.

### Get Capabilities

>     jvmtiError
>     GetCapabilities(jvmtiEnv* env,
>                 jvmtiCapabilities* capabilities_ptr)

Returns via `capabilities_ptr` the optional JVM TI features which this environment currently possesses. Each possessed capability is indicated by a one (`1`) in the corresponding field of the capabilities structure. An environment does not possess a capability unless it has been successfully added with `AddCapabilities`. An environment only loses possession of a capability if it has been relinquished with `RelinquishCapabilities`. Thus, this function returns the net result of the `AddCapabilities` and `RelinquishCapabilities` calls which have been made.

See the Capability Examples.

Phase | Callback Safe | Position | Since
may be called during any phase | No | 89 | 1.0

Capabilities
Required Functionality

Parameters
Name | Type | Description
`capabilities_ptr` | `jvmtiCapabilities*` | On return, points to the JVM TI capabilities. Agent passes a pointer to a `jvmtiCapabilities`. On return, the `jvmtiCapabilities` has been set.

Errors
This function returns either a universal error or one of the following errors
Error | Description
`JVMTI_ERROR_NULL_POINTER` | `capabilities_ptr` is `NULL`.

## Timers

Timers functions:

- Get Current Thread CPU Timer Information
- Get Current Thread CPU Time
- Get Thread CPU Timer Information
- Get Thread CPU Time
- Get Timer Information
- Get Time
- Get Available Processors

Timers types:

- `jvmtiTimerInfo` - Timer Info
- `jvmtiTimerKind` - Timer Kinds

These functions provide timing information. The resolution at which the time is updated is not specified. They provides nanosecond precision, but not necessarily nanosecond accuracy. Details about the timers, such as their maximum values, can be accessed with the timer information functions.

#### Timer Info

The information function for each timer returns this data structure.

>     typedef struct {
>         jlong max_value;
>         jboolean may_skip_forward;
>         jboolean may_skip_backward;
>         jvmtiTimerKind kind;
>         jlong reserved1;
>         jlong reserved2;
>     } jvmtiTimerInfo;

> `jvmtiTimerInfo` - Timer Info
> Field | Type | Description
> `max_value` | `jlong` | The maximum value the timer can reach. After this value is reached the timer wraps back to zero. This is an unsigned value. If tested or printed as a jlong (signed value) it may appear to be a negative number.
> `may_skip_forward` | `jboolean` | If true, the timer can be externally adjusted and as a result skip forward. If false, the timer value will never increase faster than real time.
> `may_skip_backward` | `jboolean` | If true, the timer can be externally adjusted and as a result skip backward. If false, the timer value will be monotonically increasing.
> `kind` | `jvmtiTimerKind` | The kind of timer. On a platform that does not distinguish between user and system time, `JVMTI_TIMER_TOTAL_CPU` is returned.
> `reserved1` | `jlong` | Reserved for future use.
> `reserved2` | `jlong` | Reserved for future use.

Where the timer kind is --

> Timer Kinds (`jvmtiTimerKind`)
> Constant | Value | Description
> `JVMTI_TIMER_USER_CPU` | 30 | CPU time that a thread is in user mode.
> `JVMTI_TIMER_TOTAL_CPU` | 31 | CPU time that a thread is in user or system mode.
> `JVMTI_TIMER_ELAPSED` | 32 | Elapsed time.

### Get Current Thread CPU Timer Information

>     jvmtiError
>     GetCurrentThreadCpuTimerInfo(jvmtiEnv* env,
>                 jvmtiTimerInfo* info_ptr)

Get information about the `GetCurrentThreadCpuTime` timer. The fields of the `jvmtiTimerInfo` structure are filled in with details about the timer. This information is specific to the platform and the implementation of `GetCurrentThreadCpuTime` and thus does not vary by thread nor does it vary during a particular invocation of the VM.

Note that the implementations of `GetCurrentThreadCpuTime` and `GetThreadCpuTime` may differ, and thus the values returned by `GetCurrentThreadCpuTimerInfo` and `GetThreadCpuTimerInfo` may differ -- see `GetCurrentThreadCpuTime` for more information.

Phase | Callback Safe | Position | Since
may only be called during the start or the live phase | This function may be called from the callbacks to the Heap iteration functions, or from the event handlers for the `GarbageCollectionStart`, `GarbageCollectionFinish`, and `ObjectFree` events. | 134 | 1.0

Capabilities
Optional Functionality: might not be implemented for all virtual machines. The following capability (as returned by `GetCapabilities`) must be true to use this function.
Capability | Effect
`can_get_current_thread_cpu_time` | Can get current thread CPU time.

Parameters
Name | Type | Description
`info_ptr` | `jvmtiTimerInfo*` | On return, filled with information describing the time returned by `GetCurrentThreadCpuTime`. Agent passes a pointer to a `jvmtiTimerInfo`. On return, the `jvmtiTimerInfo` has been set.

Errors
This function returns either a universal error or one of the following errors
Error | Description
`JVMTI_ERROR_MUST_POSSESS_CAPABILITY` | The environment does not possess the capability `can_get_current_thread_cpu_time`. Use `AddCapabilities`.
`JVMTI_ERROR_NULL_POINTER` | `info_ptr` is `NULL`.

### Get Current Thread CPU Time

>     jvmtiError
>     GetCurrentThreadCpuTime(jvmtiEnv* env,
>                 jlong* nanos_ptr)

Return the CPU time utilized by the current thread.

Note that the `GetThreadCpuTime` function provides CPU time for any thread, including the current thread. `GetCurrentThreadCpuTime` exists to support platforms which cannot supply CPU time for threads other than the current thread or which have more accurate information for the current thread (see `GetCurrentThreadCpuTimerInfo` vs `GetThreadCpuTimerInfo`). On many platforms this call will be equivalent to:

>       GetThreadCpuTime(env, NULL, nanos_ptr)

Phase | Callback Safe | Position | Since
may only be called during the start or the live phase | This function may be called from the callbacks to the Heap iteration functions, or from the event handlers for the `GarbageCollectionStart`, `GarbageCollectionFinish`, and `ObjectFree` events. | 135 | 1.0

Capabilities
Optional Functionality: might not be implemented for all virtual machines. The following capability (as returned by `GetCapabilities`) must be true to use this function.
Capability | Effect
`can_get_current_thread_cpu_time` | Can get current thread CPU time. If this capability is enabled after threads have started, the implementation may choose any time up to and including the time that the capability is enabled as the point where CPU time collection starts. This capability must be potentially available on any platform where `can_get_thread_cpu_time` is potentially available.

Parameters
Name | Type | Description
`nanos_ptr` | `jlong*` | On return, points to the CPU time used by this thread in nanoseconds. This is an unsigned value. If tested or printed as a jlong (signed value) it may appear to be a negative number. Agent passes a pointer to a `jlong`. On return, the `jlong` has been set.

Errors
This function returns either a universal error or one of the following errors
Error | Description
`JVMTI_ERROR_MUST_POSSESS_CAPABILITY` | The environment does not possess the capability `can_get_current_thread_cpu_time`. Use `AddCapabilities`.
`JVMTI_ERROR_NULL_POINTER` | `nanos_ptr` is `NULL`.

### Get Thread CPU Timer Information

>     jvmtiError
>     GetThreadCpuTimerInfo(jvmtiEnv* env,
>                 jvmtiTimerInfo* info_ptr)

Get information about the `GetThreadCpuTime` timer. The fields of the `jvmtiTimerInfo` structure are filled in with details about the timer. This information is specific to the platform and the implementation of `GetThreadCpuTime` and thus does not vary by thread nor does it vary during a particular invocation of the VM.

Note that the implementations of `GetCurrentThreadCpuTime` and `GetThreadCpuTime` may differ, and thus the values returned by `GetCurrentThreadCpuTimerInfo` and `GetThreadCpuTimerInfo` may differ -- see `GetCurrentThreadCpuTime` for more information.

Phase | Callback Safe | Position | Since
may only be called during the live phase | No | 136 | 1.0

Capabilities
Optional Functionality: might not be implemented for all virtual machines. The following capability (as returned by `GetCapabilities`) must be true to use this function.
Capability | Effect
`can_get_thread_cpu_time` | Can get thread CPU time.

Parameters
Name | Type | Description
`info_ptr` | `jvmtiTimerInfo*` | On return, filled with information describing the time returned by `GetThreadCpuTime`. Agent passes a pointer to a `jvmtiTimerInfo`. On return, the `jvmtiTimerInfo` has been set.

Errors
This function returns either a universal error or one of the following errors
Error | Description
`JVMTI_ERROR_MUST_POSSESS_CAPABILITY` | The environment does not possess the capability `can_get_thread_cpu_time`. Use `AddCapabilities`.
`JVMTI_ERROR_NULL_POINTER` | `info_ptr` is `NULL`.

### Get Thread CPU Time

>     jvmtiError
>     GetThreadCpuTime(jvmtiEnv* env,
>                 jthread thread,
>                 jlong* nanos_ptr)

Return the CPU time utilized by the specified thread.

Get information about this timer with `GetThreadCpuTimerInfo`.

Phase | Callback Safe | Position | Since
may only be called during the live phase | No | 137 | 1.0

Capabilities
Optional Functionality: might not be implemented for all virtual machines. The following capability (as returned by `GetCapabilities`) must be true to use this function.
Capability | Effect
`can_get_thread_cpu_time` | Can get thread CPU time. If this capability is enabled after threads have started, the implementation may choose any time up to and including the time that the capability is enabled as the point where CPU time collection starts.

Parameters
Name | Type | Description
`thread` | `jthread` | The thread to query. If `thread` is `NULL`, the current thread is used.
`nanos_ptr` | `jlong*` | On return, points to the CPU time used by the specified thread in nanoseconds. This is an unsigned value. If tested or printed as a jlong (signed value) it may appear to be a negative number. Agent passes a pointer to a `jlong`. On return, the `jlong` has been set.

Errors
This function returns either a universal error or one of the following errors
Error | Description
`JVMTI_ERROR_MUST_POSSESS_CAPABILITY` | The environment does not possess the capability `can_get_thread_cpu_time`. Use `AddCapabilities`.
`JVMTI_ERROR_INVALID_THREAD` | `thread` is not a thread object.
`JVMTI_ERROR_THREAD_NOT_ALIVE` | `thread` is not live (has not been started or is now dead).
`JVMTI_ERROR_NULL_POINTER` | `nanos_ptr` is `NULL`.

### Get Timer Information

>     jvmtiError
>     GetTimerInfo(jvmtiEnv* env,
>                 jvmtiTimerInfo* info_ptr)

Get information about the `GetTime` timer. The fields of the `jvmtiTimerInfo` structure are filled in with details about the timer. This information will not change during a particular invocation of the VM.

Phase | Callback Safe | Position | Since
may be called during any phase | This function may be called from the callbacks to the Heap iteration functions, or from the event handlers for the `GarbageCollectionStart`, `GarbageCollectionFinish`, and `ObjectFree` events. | 138 | 1.0

Capabilities
Required Functionality

Parameters
Name | Type | Description
`info_ptr` | `jvmtiTimerInfo*` | On return, filled with information describing the time returned by `GetTime`. Agent passes a pointer to a `jvmtiTimerInfo`. On return, the `jvmtiTimerInfo` has been set.

Errors
This function returns either a universal error or one of the following errors
Error | Description
`JVMTI_ERROR_NULL_POINTER` | `info_ptr` is `NULL`.

### Get Time

>     jvmtiError
>     GetTime(jvmtiEnv* env,
>                 jlong* nanos_ptr)

Return the current value of the system timer, in nanoseconds.

The value returned represents nanoseconds since some fixed but arbitrary time (perhaps in the future, so values may be negative). This function provides nanosecond precision, but not necessarily nanosecond accuracy. No guarantees are made about how frequently values change.

Get information about this timer with `GetTimerInfo`.

Phase | Callback Safe | Position | Since
may be called during any phase | This function may be called from the callbacks to the Heap iteration functions, or from the event handlers for the `GarbageCollectionStart`, `GarbageCollectionFinish`, and `ObjectFree` events. | 139 | 1.0

Capabilities
Required Functionality

Parameters
Name | Type | Description
`nanos_ptr` | `jlong*` | On return, points to the time in nanoseconds. This is an unsigned value. If tested or printed as a jlong (signed value) it may appear to be a negative number. Agent passes a pointer to a `jlong`. On return, the `jlong` has been set.

Errors
This function returns either a universal error or one of the following errors
Error | Description
`JVMTI_ERROR_NULL_POINTER` | `nanos_ptr` is `NULL`.

### Get Available Processors

>     jvmtiError
>     GetAvailableProcessors(jvmtiEnv* env,
>                 jint* processor_count_ptr)

Returns the number of processors available to the Java virtual machine.

This value may change during a particular invocation of the virtual machine. Applications that are sensitive to the number of available processors should therefore occasionally poll this property.

Phase | Callback Safe | Position | Since
may be called during any phase | No | 144 | 1.0

Capabilities
Required Functionality

Parameters
Name | Type | Description
`processor_count_ptr` | `jint*` | On return, points to the maximum number of processors available to the virtual machine; never smaller than one. Agent passes a pointer to a `jint`. On return, the `jint` has been set.

Errors
This function returns either a universal error or one of the following errors
Error | Description
`JVMTI_ERROR_NULL_POINTER` | `processor_count_ptr` is `NULL`.

## Class Loader Search

Class Loader Search functions:

- Add To Bootstrap Class Loader Search
- Add To System Class Loader Search

These functions allow the agent to add to the locations that a class loader searches for a class. This is useful for installing instrumentation under the correct class loader.

### Add To Bootstrap Class Loader Search

>     jvmtiError
>     AddToBootstrapClassLoaderSearch(jvmtiEnv* env,
>                 const char* segment)

This function can be used to cause instrumentation classes to be defined by the bootstrap class loader. See Loading Using the Bootstrap Class Loader in the Java Virtual Machine Specification. After the bootstrap class loader unsuccessfully searches for a class, the specified platform-dependent search path `segment` will be searched as well. Only one segment may be specified in the `segment`. This function may be called multiple times to add multiple segments, the segments will be searched in the order that this function was called.

In the `OnLoad` phase the function may be used to specify any platform-dependent search path segment to be searched after the bootstrap class loader unsuccessfully searches for a class. The segment is typically a directory or JAR file.

In the live phase the `segment` may be used to specify any platform-dependent path to a JAR file. The agent should take care that the JAR file does not contain any classes or resources other than those to be defined by the bootstrap class loader for the purposes of instrumentation.

The Java Virtual Machine Specification specifies that a subsequent attempt to resolve a symbolic reference that the Java virtual machine has previously unsuccessfully attempted to resolve always fails with the same error that was thrown as a result of the initial resolution attempt. Consequently, if the JAR file contains an entry that corresponds to a class for which the Java virtual machine has unsuccessfully attempted to resolve a reference, then subsequent attempts to resolve that reference will fail with the same error as the initial attempt.

Phase | Callback Safe | Position | Since
may only be called during the OnLoad or the live phase | No | 149 | 1.0

Capabilities
Required Functionality

Parameters
Name | Type | Description
`segment` | `const char*` | The platform-dependent search path segment, encoded as a modified UTF-8 string. Agent passes in an array of `char`.

Errors
This function returns either a universal error or one of the following errors
Error | Description
`JVMTI_ERROR_ILLEGAL_ARGUMENT` | `segment` is an invalid path. In the live phase, anything other than an existing JAR file is an invalid path.
`JVMTI_ERROR_NULL_POINTER` | `segment` is `NULL`.

### Add To System Class Loader Search

>     jvmtiError
>     AddToSystemClassLoaderSearch(jvmtiEnv* env,
>                 const char* segment)

This function can be used to cause instrumentation classes to be defined by the system class loader. See Loading Using a User-defined Class Loader in the Java Virtual Machine Specification. After the class loader unsuccessfully searches for a class, the specified platform-dependent search path `segment` will be searched as well. Only one segment may be specified in the `segment`. This function may be called multiple times to add multiple segments, the segments will be searched in the order that this function was called.

In the `OnLoad` phase the function may be used to specify any platform-dependent search path segment to be searched after the system class loader unsuccessfully searches for a class. The segment is typically a directory or JAR file.

In the live phase the `segment` is a platform-dependent path to a JAR file to be searched after the system class loader unsuccessfully searches for a class. The agent should take care that the JAR file does not contain any classes or resources other than those to be defined by the system class loader for the purposes of instrumentation.

In the live phase the system class loader supports adding a JAR file to be searched if the system class loader implements a method name `appendToClassPathForInstrumentation` which takes a single parameter of type `java.lang.String`. The method is not required to have `public` access.

The Java Virtual Machine Specification specifies that a subsequent attempt to resolve a symbolic reference that the Java virtual machine has previously unsuccessfully attempted to resolve always fails with the same error that was thrown as a result of the initial resolution attempt. Consequently, if the JAR file contains an entry that corresponds to a class for which the Java virtual machine has unsuccessfully attempted to resolve a reference, then subsequent attempts to resolve that reference will fail with the same error as the initial attempt.

Phase | Callback Safe | Position | Since
may only be called during the OnLoad or the live phase | No | 151 | 1.1

Capabilities
Required Functionality

Parameters
Name | Type | Description
`segment` | `const char*` | The platform-dependent search path segment, encoded as a modified UTF-8 string. Agent passes in an array of `char`.

Errors
This function returns either a universal error or one of the following errors
Error | Description
`JVMTI_ERROR_ILLEGAL_ARGUMENT` | `segment` is an invalid path. In the live phase, anything other than an existing JAR file is an invalid path.
`JVMTI_ERROR_CLASS_LOADER_UNSUPPORTED` | Operation not supported by the system class loader.
`JVMTI_ERROR_NULL_POINTER` | `segment` is `NULL`.

## System Properties

System Properties functions:

- Get System Properties
- Get System Property
- Set System Property

These functions get and set system properties.

### Get System Properties

>     jvmtiError
>     GetSystemProperties(jvmtiEnv* env,
>                 jint* count_ptr,
>                 char*** property_ptr)

The list of VM system property keys which may be used with `GetSystemProperty` is returned. It is strongly recommended that virtual machines provide the following property keys:

- `java.vm.vendor`
- `java.vm.version`
- `java.vm.name`
- `java.vm.info`
- `java.library.path`
- `java.class.path`

Provides access to system properties defined by and used by the VM. Properties set on the command-line are included. This allows getting and setting of these properties before the VM even begins executing bytecodes. Since this is a VM view of system properties, the set of available properties will usually be different than that in `java.lang.System.getProperties`. JNI method invocation may be used to access `java.lang.System.getProperties`.

The set of properties may grow during execution.

Phase | Callback Safe | Position | Since
may only be called during the OnLoad or the live phase | No | 130 | 1.0

Capabilities
Required Functionality

Parameters
Name | Type | Description
`count_ptr` | `jint*` | On return, points to the number of property keys returned. Agent passes a pointer to a `jint`. On return, the `jint` has been set.
`property_ptr` | `char***` | On return, points to an array of property keys, encoded as modified UTF-8 strings. Agent passes a pointer to a `char**`. On return, the `char**` points to a newly allocated array of size `*count_ptr`, each element of which is also newly allocated. The array should be freed with `Deallocate`. Each of the elements should be freed with `Deallocate`.

Errors
This function returns either a universal error or one of the following errors
Error | Description
`JVMTI_ERROR_NULL_POINTER` | `count_ptr` is `NULL`.
`JVMTI_ERROR_NULL_POINTER` | `property_ptr` is `NULL`.

### Get System Property

>     jvmtiError
>     GetSystemProperty(jvmtiEnv* env,
>                 const char* property,
>                 char** value_ptr)

Return a VM system property value given the property key.

The function `GetSystemProperties` returns the set of property keys which may be used. The properties which can be retrieved may grow during execution.

Since this is a VM view of system properties, the values of properties may differ from that returned by `java.lang.System.getProperty(String)`. A typical VM might copy the values of the VM system properties into the `Properties` held by `java.lang.System` during the initialization of that class. Thereafter any changes to the VM system properties (with `SetSystemProperty`) or the `java.lang.System` system properties (with `java.lang.System.setProperty(String,String)`) would cause the values to diverge. JNI method invocation may be used to access `java.lang.System.getProperty(String)`.

Phase | Callback Safe | Position | Since
may only be called during the OnLoad or the live phase | No | 131 | 1.0

Capabilities
Required Functionality

Parameters
Name | Type | Description
`property` | `const char*` | The key of the property to retrieve, encoded as a modified UTF-8 string. Agent passes in an array of `char`.
`value_ptr` | `char**` | On return, points to the property value, encoded as a modified UTF-8 string. Agent passes a pointer to a `char*`. On return, the `char*` points to a newly allocated array. The array should be freed with `Deallocate`.

Errors
This function returns either a universal error or one of the following errors
Error | Description
`JVMTI_ERROR_NOT_AVAILABLE` | This property is not available. Use `GetSystemProperties` to find available properties.
`JVMTI_ERROR_NULL_POINTER` | `property` is `NULL`.
`JVMTI_ERROR_NULL_POINTER` | `value_ptr` is `NULL`.

### Set System Property

>     jvmtiError
>     SetSystemProperty(jvmtiEnv* env,
>                 const char* property,
>                 const char* value)

Set a VM system property value.

The function `GetSystemProperties` returns the set of property keys, some of these may be settable. See `GetSystemProperty`.

Phase | Callback Safe | Position | Since
may only be called during the OnLoad phase | No | 132 | 1.0

Capabilities
Required Functionality

Parameters
Name | Type | Description
`property` | `const char*` | The key of the property, encoded as a modified UTF-8 string. Agent passes in an array of `char`.
`value` | `const char *` | The property value to set, encoded as a modified UTF-8 string. Agent passes in an array of `char`. If `value` is `NULL`, do not set the value, but return `JVMTI_ERROR_NOT_AVAILABLE` if the property is not writeable .

Errors
This function returns either a universal error or one of the following errors
Error | Description
`JVMTI_ERROR_NOT_AVAILABLE` | This property is not available or is not writeable.
`JVMTI_ERROR_NULL_POINTER` | `property` is `NULL`.

## General

General functions:

- Get Phase
- Dispose Environment
- Set Environment Local Storage
- Get Environment Local Storage
- Get Version Number
- Get Error Name
- Set Verbose Flag
- Get JLocation Format

General types:

- `jvmtiPhase` - Phases of execution
- `jvmtiVerboseFlag` - Verbose Flag Enumeration
- `jvmtiJlocationFormat` - JLocation Format Enumeration

General flags and constants:

- Version Interface Types
- Version Masks
- Version Shifts

### Get Phase

>     typedef enum {
>         JVMTI_PHASE_ONLOAD = 1,
>         JVMTI_PHASE_PRIMORDIAL = 2,
>         JVMTI_PHASE_START = 6,
>         JVMTI_PHASE_LIVE = 4,
>         JVMTI_PHASE_DEAD = 8
>     } jvmtiPhase;

>     jvmtiError
>     GetPhase(jvmtiEnv* env,
>                 jvmtiPhase* phase_ptr)

Return the current phase of VM execution. The phases proceed in sequence:

> Phases of execution (`jvmtiPhase`)
> Constant | Value | Description
> `JVMTI_PHASE_ONLOAD` | 1 | `OnLoad` phase: while in the `Agent_OnLoad` function.
> `JVMTI_PHASE_PRIMORDIAL` | 2 | Primordial phase: between return from `Agent_OnLoad` and the `VMStart` event.
> `JVMTI_PHASE_START` | 6 | Start phase: when the `VMStart` event is sent and until the `VMInit` event is sent.
> `JVMTI_PHASE_LIVE` | 4 | Live phase: when the `VMInit` event is sent and until the `VMDeath` event returns.
> `JVMTI_PHASE_DEAD` | 8 | Dead phase: after the `VMDeath` event returns or after start-up failure.

In the case of start-up failure the VM will proceed directly to the dead phase skipping intermediate phases and neither a `VMInit` nor `VMDeath` event will be sent.

Most JVM TI functions operate only in the live phase. The following functions operate in either the `OnLoad` or live phases:

- CreateRawMonitor
- DestroyRawMonitor
- SetEventCallbacks
- SetEventNotificationMode
- GetExtensionFunctions
- GetExtensionEvents
- SetExtensionEventCallback
- GetPotentialCapabilities
- AddCapabilities
- RelinquishCapabilities
- AddToBootstrapClassLoaderSearch
- AddToSystemClassLoaderSearch
- GetSystemProperties
- GetSystemProperty

The following functions operate in only the `OnLoad` phase:

- SetSystemProperty

The following functions operate in the start or live phases:

- GetCurrentThread
- SetThreadLocalStorage
- GetThreadLocalStorage
- GetTag
- SetTag
- GetClassSignature
- GetClassStatus
- GetSourceFileName
- GetClassModifiers
- GetClassMethods
- GetClassFields
- GetImplementedInterfaces
- GetClassVersionNumbers
- GetConstantPool
- IsInterface
- IsArrayClass
- IsModifiableClass
- GetClassLoader
- GetSourceDebugExtension
- GetObjectSize
- GetObjectHashCode
- GetFieldName
- GetFieldDeclaringClass
- GetFieldModifiers
- IsFieldSynthetic
- GetMethodName
- GetMethodDeclaringClass
- GetMethodModifiers
- GetMaxLocals
- GetArgumentsSize
- GetLineNumberTable
- GetMethodLocation
- GetBytecodes
- IsMethodNative
- IsMethodSynthetic
- IsMethodObsolete
- SetJNIFunctionTable
- GetJNIFunctionTable
- GetCurrentThreadCpuTimerInfo
- GetCurrentThreadCpuTime

The following functions operate in any phase:

- Allocate
- Deallocate
- SetNativeMethodPrefix
- SetNativeMethodPrefixes
- RawMonitorEnter
- RawMonitorExit
- RawMonitorWait
- RawMonitorNotify
- RawMonitorNotifyAll
- GetCapabilities
- GetTimerInfo
- GetTime
- GetAvailableProcessors
- GetPhase
- DisposeEnvironment
- SetEnvironmentLocalStorage
- GetEnvironmentLocalStorage
- GetVersionNumber
- GetErrorName
- SetVerboseFlag
- GetJLocationFormat

JNI functions (except the Invocation API) must only be used in the start or live phases.

Most JVM TI events are sent only in the live phase. The following events operate in others phases:

- ThreadStart
- ThreadEnd
- ClassLoad
- ClassPrepare
- VMStart

- NativeMethodBind
- ClassFileLoadHook
- DynamicCodeGenerated

Phase | Callback Safe | Position | Since
may be called during any phase | No | 133 | 1.0

Capabilities
Required Functionality

Parameters
Name | Type | Description
`phase_ptr` | `jvmtiPhase*` | On return, points to the phase. Agent passes a pointer to a `jvmtiPhase`. On return, the `jvmtiPhase` has been set.

Errors
This function returns either a universal error or one of the following errors
Error | Description
`JVMTI_ERROR_NULL_POINTER` | `phase_ptr` is `NULL`.

### Dispose Environment

>     jvmtiError
>     DisposeEnvironment(jvmtiEnv* env)

Shutdown a JVM TI connection created with JNI `GetEnv` (see JVM TI Environments). Dispose of any resources held by the environment. Threads suspended by this environment are not resumed by this call, this must be done explicitly by the agent. Memory allocated by this environment via calls to JVM TI functions is not released, this can be done explicitly by the agent by calling `Deallocate`. Raw monitors created by this environment are not destroyed, this can be done explicitly by the agent by calling `DestroyRawMonitor`. The state of threads waiting on raw monitors created by this environment are not affected.

Any native method prefixes for this environment will be unset; the agent must remove any prefixed native methods before dispose is called.

Any capabilities held by this environment are relinquished.

Events enabled by this environment will no longer be sent, however event handlers currently running will continue to run. Caution must be exercised in the design of event handlers whose environment may be disposed and thus become invalid during their execution.

This environment may not be used after this call. This call returns to the caller.

Phase | Callback Safe | Position | Since
may be called during any phase | No | 127 | 1.0

Capabilities
Required Functionality

Parameters
Name | Type | Description

Errors
This function returns a universal error

### Set Environment Local Storage

>     jvmtiError
>     SetEnvironmentLocalStorage(jvmtiEnv* env,
>                 const void* data)

The VM stores a pointer value associated with each environment. This pointer value is called environment-local storage. This value is `NULL` unless set with this function. Agents can allocate memory in which they store environment specific information. By setting environment-local storage it can then be accessed with `GetEnvironmentLocalStorage`.

Called by the agent to set the value of the JVM TI environment-local storage. JVM TI supplies to the agent a pointer-size environment-local storage that can be used to record per-environment information.

Phase | Callback Safe | Position | Since
may be called during any phase | This function may be called from the callbacks to the Heap iteration functions, or from the event handlers for the `GarbageCollectionStart`, `GarbageCollectionFinish`, and `ObjectFree` events. | 148 | 1.0

Capabilities
Required Functionality

Parameters
Name | Type | Description
`data` | `const void *` | The value to be entered into the environment-local storage. Agent passes in a pointer. If `data` is `NULL`, value is set to `NULL`.

Errors
This function returns a universal error

### Get Environment Local Storage

>     jvmtiError
>     GetEnvironmentLocalStorage(jvmtiEnv* env,
>                 void** data_ptr)

Called by the agent to get the value of the JVM TI environment-local storage.

Phase | Callback Safe | Position | Since
may be called during any phase | This function may be called from the callbacks to the Heap iteration functions, or from the event handlers for the `GarbageCollectionStart`, `GarbageCollectionFinish`, and `ObjectFree` events. | 147 | 1.0

Capabilities
Required Functionality

Parameters
Name | Type | Description
`data_ptr` | `void**` | Pointer through which the value of the environment local storage is returned. If environment-local storage has not been set with `SetEnvironmentLocalStorage` returned pointer is `NULL`.

Errors
This function returns either a universal error or one of the following errors
Error | Description
`JVMTI_ERROR_NULL_POINTER` | `data_ptr` is `NULL`.

### Get Version Number

>     jvmtiError
>     GetVersionNumber(jvmtiEnv* env,
>                 jint* version_ptr)

Return the JVM TI version via `version_ptr`. The return value is the version identifier. The version identifier includes major, minor and micro version as well as the interface type.

> Version Interface Types
> Constant | Value | Description
> `JVMTI_VERSION_INTERFACE_JNI` | 0x00000000 | Value of `JVMTI_VERSION_MASK_INTERFACE_TYPE` for JNI.
> `JVMTI_VERSION_INTERFACE_JVMTI` | 0x30000000 | Value of `JVMTI_VERSION_MASK_INTERFACE_TYPE` for JVM TI.

> Version Masks
> Constant | Value | Description
> `JVMTI_VERSION_MASK_INTERFACE_TYPE` | 0x70000000 | Mask to extract interface type. The value of the version returned by this function masked with `JVMTI_VERSION_MASK_INTERFACE_TYPE` is always `JVMTI_VERSION_INTERFACE_JVMTI` since this is a JVM TI function.
> `JVMTI_VERSION_MASK_MAJOR` | 0x0FFF0000 | Mask to extract major version number.
> `JVMTI_VERSION_MASK_MINOR` | 0x0000FF00 | Mask to extract minor version number.
> `JVMTI_VERSION_MASK_MICRO` | 0x000000FF | Mask to extract micro version number.

> Version Shifts
> Constant | Value | Description
> `JVMTI_VERSION_SHIFT_MAJOR` | 16 | Shift to extract major version number.
> `JVMTI_VERSION_SHIFT_MINOR` | 8 | Shift to extract minor version number.
> `JVMTI_VERSION_SHIFT_MICRO` | 0 | Shift to extract micro version number.

Phase | Callback Safe | Position | Since
may be called during any phase | No | 88 | 1.0

Capabilities
Required Functionality

Parameters
Name | Type | Description
`version_ptr` | `jint*` | On return, points to the JVM TI version. Agent passes a pointer to a `jint`. On return, the `jint` has been set.

Errors
This function returns either a universal error or one of the following errors
Error | Description
`JVMTI_ERROR_NULL_POINTER` | `version_ptr` is `NULL`.

### Get Error Name

>     jvmtiError
>     GetErrorName(jvmtiEnv* env,
>                 jvmtiError error,
>                 char** name_ptr)

Return the symbolic name for an error code.

For example `GetErrorName(env, JVMTI_ERROR_NONE, &err_name)` would return in `err_name` the string `"JVMTI_ERROR_NONE"`.

Phase | Callback Safe | Position | Since
may be called during any phase | No | 128 | 1.0

Capabilities
Required Functionality

Parameters
Name | Type | Description
`error` | `jvmtiError` | The error code.
`name_ptr` | `char**` | On return, points to the error name. The name is encoded as a modified UTF-8 string, but is restricted to the ASCII subset. Agent passes a pointer to a `char*`. On return, the `char*` points to a newly allocated array. The array should be freed with `Deallocate`.

Errors
This function returns either a universal error or one of the following errors
Error | Description
`JVMTI_ERROR_ILLEGAL_ARGUMENT` | `error` is not a jvmtiError.
`JVMTI_ERROR_NULL_POINTER` | `name_ptr` is `NULL`.

### Set Verbose Flag

>     typedef enum {
>         JVMTI_VERBOSE_OTHER = 0,
>         JVMTI_VERBOSE_GC = 1,
>         JVMTI_VERBOSE_CLASS = 2,
>         JVMTI_VERBOSE_JNI = 4
>     } jvmtiVerboseFlag;

>     jvmtiError
>     SetVerboseFlag(jvmtiEnv* env,
>                 jvmtiVerboseFlag flag,
>                 jboolean value)

> Verbose Flag Enumeration (`jvmtiVerboseFlag`)
> Constant | Value | Description
> `JVMTI_VERBOSE_OTHER` | 0 | Verbose output other than the below.
> `JVMTI_VERBOSE_GC` | 1 | Verbose garbage collector output, like that specified with `-verbose:gc`.
> `JVMTI_VERBOSE_CLASS` | 2 | Verbose class loading output, like that specified with `-verbose:class`.
> `JVMTI_VERBOSE_JNI` | 4 | Verbose JNI output, like that specified with `-verbose:jni`.

Control verbose output. This is the output which typically is sent to `stderr`.

Phase | Callback Safe | Position | Since
may be called during any phase | No | 150 | 1.0

Capabilities
Required Functionality

Parameters
Name | Type | Description
`flag` | `jvmtiVerboseFlag` | Which verbose flag to set.
`value` | `jboolean` | New value of the flag.

Errors
This function returns either a universal error or one of the following errors
Error | Description
`JVMTI_ERROR_ILLEGAL_ARGUMENT` | `flag` is not a jvmtiVerboseFlag.

### Get JLocation Format

>     typedef enum {
>         JVMTI_JLOCATION_JVMBCI = 1,
>         JVMTI_JLOCATION_MACHINEPC = 2,
>         JVMTI_JLOCATION_OTHER = 0
>     } jvmtiJlocationFormat;

>     jvmtiError
>     GetJLocationFormat(jvmtiEnv* env,
>                 jvmtiJlocationFormat* format_ptr)

Although the greatest functionality is achieved with location information referencing the virtual machine bytecode index, the definition of `jlocation` has intentionally been left unconstrained to allow VM implementations that do not have this information.

This function describes the representation of `jlocation` used in this VM. If the returned format is `JVMTI_JLOCATION_JVMBCI`, `jlocation`s can be used as in indices into the array returned by `GetBytecodes`.

> JLocation Format Enumeration (`jvmtiJlocationFormat`)
> Constant | Value | Description
> `JVMTI_JLOCATION_JVMBCI` | 1 | `jlocation` values represent virtual machine bytecode indices--that is, offsets into the virtual machine code for a method.
> `JVMTI_JLOCATION_MACHINEPC` | 2 | `jlocation` values represent native machine program counter values.
> `JVMTI_JLOCATION_OTHER` | 0 | `jlocation` values have some other representation.

Phase | Callback Safe | Position | Since
may be called during any phase | No | 129 | 1.0

Capabilities
Required Functionality

Parameters
Name | Type | Description
`format_ptr` | `jvmtiJlocationFormat*` | On return, points to the format identifier for `jlocation` values. Agent passes a pointer to a `jvmtiJlocationFormat`. On return, the `jvmtiJlocationFormat` has been set.

Errors
This function returns either a universal error or one of the following errors
Error | Description
`JVMTI_ERROR_NULL_POINTER` | `format_ptr` is `NULL`.

## Errors

Every JVM TI function returns a `jvmtiError` error code.

It is the responsibility of the agent to call JVM TI functions with valid parameters and in the proper context (calling thread is attached, phase is correct, etc.). Detecting some error conditions may be difficult, inefficient, or impossible for an implementation. The errors listed in Function Specific Required Errors must be detected by the implementation. All other errors represent the recommended response to the error condition.

### Universal Errors

The following errors may be returned by any function

`JVMTI_ERROR_NONE (0)`
  No error has occurred. This is the error code that is returned on successful completion of the function.

`JVMTI_ERROR_NULL_POINTER (100)`
  Pointer is unexpectedly `NULL`.

`JVMTI_ERROR_OUT_OF_MEMORY (110)`
  The function attempted to allocate memory and no more memory was available for allocation.

`JVMTI_ERROR_ACCESS_DENIED (111)`
  The desired functionality has not been enabled in this virtual machine.

`JVMTI_ERROR_UNATTACHED_THREAD (115)`
  The thread being used to call this function is not attached to the virtual machine. Calls must be made from attached threads. See `AttachCurrentThread` in the JNI invocation API.

`JVMTI_ERROR_INVALID_ENVIRONMENT (116)`
  The JVM TI environment provided is no longer connected or is not an environment.

`JVMTI_ERROR_WRONG_PHASE (112)`
  The desired functionality is not available in the current phase. Always returned if the virtual machine has completed running.

`JVMTI_ERROR_INTERNAL (113)`
  An unexpected internal error has occurred.

### Function Specific Required Errors

The following errors are returned by some JVM TI functions and must be returned by the implementation when the condition occurs.

`JVMTI_ERROR_INVALID_PRIORITY (12)`
  Invalid priority.

`JVMTI_ERROR_THREAD_NOT_SUSPENDED (13)`
  Thread was not suspended.

`JVMTI_ERROR_THREAD_SUSPENDED (14)`
  Thread already suspended.

`JVMTI_ERROR_THREAD_NOT_ALIVE (15)`
  This operation requires the thread to be alive--that is, it must be started and not yet have died.

`JVMTI_ERROR_CLASS_NOT_PREPARED (22)`
  The class has been loaded but not yet prepared.

`JVMTI_ERROR_NO_MORE_FRAMES (31)`
  There are no Java programming language or JNI stack frames at the specified depth.

`JVMTI_ERROR_OPAQUE_FRAME (32)`
  Information about the frame is not available (e.g. for native frames).

`JVMTI_ERROR_DUPLICATE (40)`
  Item already set.

`JVMTI_ERROR_NOT_FOUND (41)`
  Desired element (e.g. field or breakpoint) not found

`JVMTI_ERROR_NOT_MONITOR_OWNER (51)`
  This thread doesn't own the raw monitor.

`JVMTI_ERROR_INTERRUPT (52)`
  The call has been interrupted before completion.

`JVMTI_ERROR_UNMODIFIABLE_CLASS (79)`
  The class cannot be modified.

`JVMTI_ERROR_NOT_AVAILABLE (98)`
  The functionality is not available in this virtual machine.

`JVMTI_ERROR_ABSENT_INFORMATION (101)`
  The requested information is not available.

`JVMTI_ERROR_INVALID_EVENT_TYPE (102)`
  The specified event type ID is not recognized.

`JVMTI_ERROR_NATIVE_METHOD (104)`
  The requested information is not available for native method.

`JVMTI_ERROR_CLASS_LOADER_UNSUPPORTED (106)`
  The class loader does not support this operation.

### Function Specific Agent Errors

The following errors are returned by some JVM TI functions. They are returned in the event of invalid parameters passed by the agent or usage in an invalid context. An implementation is not required to detect these errors.

`JVMTI_ERROR_INVALID_THREAD (10)`
  The passed thread is not a valid thread.

`JVMTI_ERROR_INVALID_FIELDID (25)`
  Invalid field.

`JVMTI_ERROR_INVALID_METHODID (23)`
  Invalid method.

`JVMTI_ERROR_INVALID_LOCATION (24)`
  Invalid location.

`JVMTI_ERROR_INVALID_OBJECT (20)`
  Invalid object.

`JVMTI_ERROR_INVALID_CLASS (21)`
  Invalid class.

`JVMTI_ERROR_TYPE_MISMATCH (34)`
  The variable is not an appropriate type for the function used.

`JVMTI_ERROR_INVALID_SLOT (35)`
  Invalid slot.

`JVMTI_ERROR_MUST_POSSESS_CAPABILITY (99)`
  The capability being used is false in this environment.

`JVMTI_ERROR_INVALID_THREAD_GROUP (11)`
  Thread group invalid.

`JVMTI_ERROR_INVALID_MONITOR (50)`
  Invalid raw monitor.

`JVMTI_ERROR_ILLEGAL_ARGUMENT (103)`
  Illegal argument.

`JVMTI_ERROR_INVALID_TYPESTATE (65)`
  The state of the thread has been modified, and is now inconsistent.

`JVMTI_ERROR_UNSUPPORTED_VERSION (68)`
  A new class file has a version number not supported by this VM.

`JVMTI_ERROR_INVALID_CLASS_FORMAT (60)`
  A new class file is malformed (the VM would return a `ClassFormatError`).

`JVMTI_ERROR_CIRCULAR_CLASS_DEFINITION (61)`
  The new class file definitions would lead to a circular definition (the VM would return a `ClassCircularityError`).

`JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_ADDED (63)`
  A new class file would require adding a method.

`JVMTI_ERROR_UNSUPPORTED_REDEFINITION_SCHEMA_CHANGED (64)`
  A new class version changes a field.

`JVMTI_ERROR_FAILS_VERIFICATION (62)`
  The class bytes fail verification.

`JVMTI_ERROR_UNSUPPORTED_REDEFINITION_HIERARCHY_CHANGED (66)`
  A direct superclass is different for the new class version, or the set of directly implemented interfaces is different.

`JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_DELETED (67)`
  A new class version does not declare a method declared in the old class version.

`JVMTI_ERROR_NAMES_DONT_MATCH (69)`
  The class name defined in the new class file is different from the name in the old class object.

`JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_MODIFIERS_CHANGED (70)`
  A new class version has different modifiers.

`JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_MODIFIERS_CHANGED (71)`
  A method in the new class version has different modifiers than its counterpart in the old class version.

## Data Types

JVM TI extends the data types defined by JNI.

JNI Types Used in the JVM Tool Interface
Type | Description
`jboolean` | Holds a Java programming language `boolean`. Unsigned 8 bits.
`jint` | Holds a Java programming language `int`. Signed 32 bits.
`jlong` | Holds a Java programming language `long`. Signed 64 bits.
`jfloat` | Holds a Java programming language `float`. 32 bits.
`jdouble` | Holds a Java programming language `double`. 64 bits.
`jobject` | Holds a Java programming language object.
`jclass` | Holds a Java programming language class.
`jvalue` | Is a union of all primitive types and `jobject`. Thus, holds any Java programming language value.
`jfieldID` | Identifies a Java programming language field. `jfieldID`s returned by JVM TI functions and events may be safely stored.
`jmethodID` | Identifies a Java programming language method, initializer, or constructor. `jmethodID`s returned by JVM TI functions and events may be safely stored. However, if the class is unloaded, they become invalid and must not be used.
`JNIEnv` | Pointer to the JNI function table. Pointer to this (`JNIEnv *`) is a JNI environment.

JVM Tool Interface Base Types
Type | Description
`jvmtiEnv` | The JVM TI environment pointer. See the Function Section. `jvmtiEnv` points to the function table pointer.
`jthread` | Subtype of `jobject` that holds a thread.
    typedef jobject jthread;
`jthreadGroup` | Subtype of `jobject` that holds a thread group.
    typedef jobject jthreadGroup;
`jlocation` | A 64 bit value, representing a monotonically increasing executable position within a method. `-1` indicates a native method. See `GetJLocationFormat` for the format on a given VM.
    typedef jlong jlocation;
`jrawMonitorID` | A raw monitor.
    struct _jrawMonitorID;
    typedef struct _jrawMonitorID *jrawMonitorID;
> `jvmtiError` | Holds an error return code. See the Error section for possible values.
>     typedef enum {
>         JVMTI_ERROR_NONE = 0,
>         JVMTI_ERROR_INVALID_THREAD = 10,
>           ...
>     } jvmtiError;
> `jvmtiEvent` | An identifier for an event type. See the Event section for possible values. It is guaranteed that future versions of this specification will never assign zero as an event type identifier.
>     typedef enum {
>         JVMTI_EVENT_SINGLE_STEP = 1,
>         JVMTI_EVENT_BREAKPOINT = 2,
>           ...
>     } jvmtiEvent;
> `jvmtiEventCallbacks` | The callbacks used for events.
>     typedef struct {
>         jvmtiEventVMInit VMInit;
>         jvmtiEventVMDeath VMDeath;
>           ...
>     } jvmtiEventCallbacks;
> See event callbacks for the complete structure. Where, for example, the VM initialization callback is defined:
>     typedef void (JNICALL *jvmtiEventVMInit)
>         (jvmtiEnv *jvmti_env,
>          JNIEnv* jni_env,
>          jthread thread);
See the individual events for the callback function definition.
`jniNativeInterface` | Typedef for the JNI function table `JNINativeInterface` defined in the JNI Specification. The JNI reference implementation defines this with an underscore.
    typedef struct JNINativeInterface_ jniNativeInterface;

Structure Type Definitions
Type | Description
`jvmtiAddrLocationMap` | Native address to location entry
`jvmtiCapabilities` | The Capabilities Structure
`jvmtiClassDefinition` | Class redefinition description
`jvmtiExtensionEventInfo` | Extension Event Info
`jvmtiExtensionFunctionInfo` | Extension Function Info
`jvmtiFrameInfo` | Stack frame information structure
`jvmtiHeapCallbacks` | Heap callback function structure
`jvmtiHeapReferenceInfo` | Reference information structure
`jvmtiHeapReferenceInfoArray` | Reference information structure for Array references
`jvmtiHeapReferenceInfoConstantPool` | Reference information structure for Constant Pool references
`jvmtiHeapReferenceInfoField` | Reference information structure for Field references
`jvmtiHeapReferenceInfoJniLocal` | Reference information structure for JNI local references
`jvmtiHeapReferenceInfoReserved` | Reference information structure for Other references
`jvmtiHeapReferenceInfoStackLocal` | Reference information structure for Local Variable references
`jvmtiLineNumberEntry` | Line number table entry
`jvmtiLocalVariableEntry` | Local variable table entry
`jvmtiMonitorStackDepthInfo` | Monitor stack depth information structure
`jvmtiMonitorUsage` | Object monitor usage information
`jvmtiParamInfo` | Extension Function/Event Parameter Info
`jvmtiStackInfo` | Stack information structure
`jvmtiThreadGroupInfo` | Thread group information structure
`jvmtiThreadInfo` | Thread information structure
`jvmtiTimerInfo` | Timer Info

Function Type Definitions
Type | Description
`jvmtiArrayPrimitiveValueCallback` | Array Primitive Value Callback
`jvmtiExtensionEvent` | Extension Event
`jvmtiExtensionFunction` | Extension Function
`jvmtiHeapIterationCallback` | Heap Iteration Callback
`jvmtiHeapObjectCallback` | Heap Object Callback
`jvmtiHeapReferenceCallback` | Heap Reference Callback
`jvmtiHeapRootCallback` | Heap Root Object Callback
`jvmtiObjectReferenceCallback` | Object Reference Callback
`jvmtiPrimitiveFieldCallback` | Primitive Field Callback
`jvmtiReservedCallback` | reserved for future use Callback
`jvmtiStackReferenceCallback` | Stack Reference Object Callback
`jvmtiStartFunction` | Agent Start Function
`jvmtiStringPrimitiveValueCallback` | String Primitive Value Callback

Enumeration Definitions
Type | Description
`jvmtiEventMode` | Event Enable/Disable
`jvmtiHeapObjectFilter` | Heap Object Filter Enumeration
`jvmtiHeapReferenceKind` | Heap Reference Enumeration
`jvmtiHeapRootKind` | Heap Root Kind Enumeration
`jvmtiIterationControl` | Iteration Control Enumeration
`jvmtiJlocationFormat` | JLocation Format Enumeration
`jvmtiObjectReferenceKind` | Object Reference Enumeration
`jvmtiParamKind` | Extension Function/Event Parameter Kinds
`jvmtiParamTypes` | Extension Function/Event Parameter Types
`jvmtiPhase` | Phases of execution
`jvmtiPrimitiveType` | Primitive Type Enumeration
`jvmtiTimerKind` | Timer Kinds
`jvmtiVerboseFlag` | Verbose Flag Enumeration

Function Table Layout
Position | Function | Declaration
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);

## Events

#### Handling Events

Agents can be informed of many events that occur in application programs.

To handle events, designate a set of callback functions with `SetEventCallbacks`. For each event the corresponding callback function will be called. Arguments to the callback function provide additional information about the event.

The callback function is usually called from within an application thread. The JVM TI implementation does not queue events in any way. This means that event callback functions must be written carefully. Here are some general guidelines. See the individual event descriptions for further suggestions.

- Any exception thrown during the execution of an event callback can overwrite any current pending exception in the current application thread. Care must be taken to preserve a pending exception when an event callback makes a JNI call that might generate an exception.
- Event callback functions must be re-entrant. The JVM TI implementation does not queue events. If an agent needs to process events one at a time, it can use a raw monitor inside the event callback functions to serialize event processing.
- Event callback functions that execute JNI's FindClass function to load classes need to note that FindClass locates the class loader associated with the current native method. For the purposes of class loading, an event callback that includes a JNI environment as a parameter to the callback will treated as if it is a native call, where the native method is in the class of the event thread's current frame.

Some JVM TI events identify objects with JNI references. All references in JVM TI events are JNI local references and will become invalid after the event callback returns. Unless stated otherwise, memory referenced by pointers sent in event callbacks may not be referenced after the event callback returns.

Except where stated otherwise, events are delivered on the thread that caused the event. Events are sent at the time they occur. The specification for each event includes the set of phases in which it can be sent; if an event triggering activity occurs during another phase, no event is sent.

A thread that generates an event does not change its execution status (for example, the event does not cause the thread to be suspended). If an agent wishes the event to result in suspension, then the agent is responsible for explicitly suspending the thread with `SuspendThread`.

If an event is enabled in multiple environments, the event will be sent to each agent in the order that the environments were created.

#### Enabling Events

All events are initially disabled. In order to receive any event:

- If the event requires a capability, that capability must be added with `AddCapabilities`.
- A callback for the event must be set with `SetEventCallbacks`.
- The event must be enabled with `SetEventNotificationMode`.

#### Multiple Co-located Events

In many situations it is possible for multiple events to occur at the same location in one thread. When this happens, all the events are reported through the event callbacks in the order specified in this section.

If the current location is at the entry point of a method, the `MethodEntry` event is reported before any other event at the current location in the same thread.

If an exception catch has been detected at the current location, either because it is the beginning of a catch clause or a native method that cleared a pending exception has returned, the `exceptionCatch` event is reported before any other event at the current location in the same thread.

If a `singleStep` event or `breakpoint` event is triggered at the current location, the event is defined to occur immediately before the code at the current location is executed. These events are reported before any events which are triggered by the execution of code at the current location in the same thread (specifically: `exception`, `fieldAccess`, and `fieldModification`). If both a step and breakpoint event are triggered for the same thread and location, the step event is reported before the breakpoint event.

If the current location is the exit point of a method (that is, the last location before returning to the caller), the `MethodExit` event and the `FramePop` event (if requested) are reported after all other events at the current location in the same thread. There is no specified ordering of these two events with respect to each other.

Co-located events can be triggered during the processing of some other event by the agent at the same location in the same thread. If such an event, of type y, is triggered during the processing of an event of type x, and if x precedes y in the ordering specified above, the co-located event y is reported for the current thread and location. If x does not precede y, y is not reported for the current thread and location. For example, if a breakpoint is set at the current location during the processing of `SingleStep`, that breakpoint will be reported before the thread moves off the current location.

The following events are never considered to be co-located with other events.

- `VMStart`
- `VMInit`
- `VMDeath`
- `ThreadStart`
- `ThreadEnd`
- `ClassLoad`
- `ClassPrepare`

#### Event Callbacks

The event callback structure below is used to specify the handler function for events. It is set with the `SetEventCallbacks` function.

>     typedef struct {
>         jvmtiEventVMInit VMInit;
>         jvmtiEventVMDeath VMDeath;
>         jvmtiEventThreadStart ThreadStart;
>         jvmtiEventThreadEnd ThreadEnd;
>         jvmtiEventClassFileLoadHook ClassFileLoadHook;
>         jvmtiEventClassLoad ClassLoad;
>         jvmtiEventClassPrepare ClassPrepare;
>         jvmtiEventVMStart VMStart;
>         jvmtiEventException Exception;
>         jvmtiEventExceptionCatch ExceptionCatch;
>         jvmtiEventSingleStep SingleStep;
>         jvmtiEventFramePop FramePop;
>         jvmtiEventBreakpoint Breakpoint;
>         jvmtiEventFieldAccess FieldAccess;
>         jvmtiEventFieldModification FieldModification;
>         jvmtiEventMethodEntry MethodEntry;
>         jvmtiEventMethodExit MethodExit;
>         jvmtiEventNativeMethodBind NativeMethodBind;
>         jvmtiEventCompiledMethodLoad CompiledMethodLoad;
>         jvmtiEventCompiledMethodUnload CompiledMethodUnload;
>         jvmtiEventDynamicCodeGenerated DynamicCodeGenerated;
>         jvmtiEventDataDumpRequest DataDumpRequest;
>         jvmtiEventReserved reserved72;
>         jvmtiEventMonitorWait MonitorWait;
>         jvmtiEventMonitorWaited MonitorWaited;
>         jvmtiEventMonitorContendedEnter MonitorContendedEnter;
>         jvmtiEventMonitorContendedEntered MonitorContendedEntered;
>         jvmtiEventReserved reserved77;
>         jvmtiEventReserved reserved78;
>         jvmtiEventReserved reserved79;
>         jvmtiEventResourceExhausted ResourceExhausted;
>         jvmtiEventGarbageCollectionStart GarbageCollectionStart;
>         jvmtiEventGarbageCollectionFinish GarbageCollectionFinish;
>         jvmtiEventObjectFree ObjectFree;
>         jvmtiEventVMObjectAlloc VMObjectAlloc;
>     } jvmtiEventCallbacks;

### Event Index

- Breakpoint
- Class File Load Hook
- Class Load
- Class Prepare
- Compiled Method Load
- Compiled Method Unload
- Data Dump Request
- Dynamic Code Generated
- Exception
- Exception Catch
- Field Access
- Field Modification
- Frame Pop
- Garbage Collection Finish
- Garbage Collection Start
- Method Entry
- Method Exit
- Monitor Contended Enter
- Monitor Contended Entered
- Monitor Wait
- Monitor Waited
- Native Method Bind
- Object Free
- Resource Exhausted
- Single Step
- Thread End
- Thread Start
- VM Death Event
- VM Initialization Event
- VM Object Allocation
- VM Start Event

## Single Step

>     void JNICALL
>     SingleStep(jvmtiEnv *jvmti_env,
>                 JNIEnv* jni_env,
>                 jthread thread,
>                 jmethodID method,
>                 jlocation location)

Single step events allow the agent to trace thread execution at the finest granularity allowed by the VM. A single step event is generated whenever a thread reaches a new location. Typically, single step events represent the completion of one VM instruction as defined in the Java Virtual Machine Specification. However, some implementations may define locations differently. In any case the `method` and `location` parameters uniquely identify the current location and allow the mapping to source file and line number when that information is available.

No single step events are generated from within native methods.

Phase | Event Type | Number | Enabling | Since
sent only during the live phase | `JVMTI_EVENT_SINGLE_STEP` | 60 | `SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_SINGLE_STEP, NULL)` | 1.0

Capabilities
Optional Functionality: might not be implemented for all virtual machines. The following capability (as returned by `GetCapabilities`) must be true to use this event.
Capability | Effect
`can_generate_single_step_events` | Can get single step events

Parameters
Name | Type | Description
`jni_env` | `JNIEnv *` | The JNI environment of the event (current) thread
`thread` | `jthread` | Thread about to execution a new instruction
`method` | `jmethodID` | Method about to execute a new instruction
`location` | `jlocation` | Location of the new instruction

## Breakpoint

>     void JNICALL
>     Breakpoint(jvmtiEnv *jvmti_env,
>                 JNIEnv* jni_env,
>                 jthread thread,
>                 jmethodID method,
>                 jlocation location)

Breakpoint events are generated whenever a thread reaches a location designated as a breakpoint with `SetBreakpoint`. The `method` and `location` parameters uniquely identify the current location and allow the mapping to source file and line number when that information is available.

Phase | Event Type | Number | Enabling | Since
sent only during the live phase | `JVMTI_EVENT_BREAKPOINT` | 62 | `SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_BREAKPOINT, NULL)` | 1.0

Capabilities
Optional Functionality: might not be implemented for all virtual machines. The following capability (as returned by `GetCapabilities`) must be true to use this event.
Capability | Effect
`can_generate_breakpoint_events` | Can set and thus get `Breakpoint` events

Parameters
Name | Type | Description
`jni_env` | `JNIEnv *` | The JNI environment of the event (current) thread.
`thread` | `jthread` | Thread that hit the breakpoint
`method` | `jmethodID` | Method that hit the breakpoint
`location` | `jlocation` | location of the breakpoint

## Field Access

>     void JNICALL
>     FieldAccess(jvmtiEnv *jvmti_env,
>                 JNIEnv* jni_env,
>                 jthread thread,
>                 jmethodID method,
>                 jlocation location,
>                 jclass field_klass,
>                 jobject object,
>                 jfieldID field)

Field access events are generated whenever a thread accesses a field that was designated as a watchpoint with `SetFieldAccessWatch`. The `method` and `location` parameters uniquely identify the current location and allow the mapping to source file and line number when that information is available.

Phase | Event Type | Number | Enabling | Since
sent only during the live phase | `JVMTI_EVENT_FIELD_ACCESS` | 63 | `SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_FIELD_ACCESS, NULL)` | 1.0

Capabilities
Optional Functionality: might not be implemented for all virtual machines. The following capability (as returned by `GetCapabilities`) must be true to use this event.
Capability | Effect
`can_generate_field_access_events` | Can set watchpoints on field access - `SetFieldAccessWatch`

Parameters
Name | Type | Description
`jni_env` | `JNIEnv *` | The JNI environment of the event (current) thread
`thread` | `jthread` | Thread accessing the field
`method` | `jmethodID` | Method where the access is occurring
`location` | `jlocation` | Location where the access is occurring
`field_klass` | `jclass` | Class of the field being accessed
`object` | `jobject` | Object with the field being accessed if the field is an instance field; `NULL` otherwise
`field` | `jfieldID` | Field being accessed

## Field Modification

>     void JNICALL
>     FieldModification(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)

Field modification events are generated whenever a thread modifies a field that was designated as a watchpoint with `SetFieldModificationWatch`. The `method` and `location` parameters uniquely identify the current location and allow the mapping to source file and line number when that information is available.

Phase | Event Type | Number | Enabling | Since
sent only during the live phase | `JVMTI_EVENT_FIELD_MODIFICATION` | 64 | `SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_FIELD_MODIFICATION, NULL)` | 1.0

Capabilities
Optional Functionality: might not be implemented for all virtual machines. The following capability (as returned by `GetCapabilities`) must be true to use this event.
Capability | Effect
`can_generate_field_modification_events` | Can set watchpoints on field modification - `SetFieldModificationWatch`

Parameters
Name | Type | Description
`jni_env` | `JNIEnv *` | The JNI environment of the event (current) thread
`thread` | `jthread` | Thread modifying the field
`method` | `jmethodID` | Method where the modification is occurring
`location` | `jlocation` | Location where the modification is occurring
`field_klass` | `jclass` | Class of the field being modified
`object` | `jobject` | Object with the field being modified if the field is an instance field; `NULL` otherwise
`field` | `jfieldID` | Field being modified
`signature_type` | `char` | Signature type of the new value
`new_value` | `jvalue` | The new value

## Frame Pop

>     void JNICALL
>     FramePop(jvmtiEnv *jvmti_env,
>                 JNIEnv* jni_env,
>                 jthread thread,
>                 jmethodID method,
>                 jboolean was_popped_by_exception)

Frame pop events are generated upon exit from a single method in a single frame as specified in a call to `NotifyFramePop`. This is true whether termination is caused by executing its return instruction or by throwing an exception to its caller (see `was_popped_by_exception`). However, frame pops caused by the `PopFrame` function are not reported.

The location reported by `GetFrameLocation` identifies the executable location in the returning method, immediately prior to the return.

Phase | Event Type | Number | Enabling | Since
sent only during the live phase | `JVMTI_EVENT_FRAME_POP` | 61 | `SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_FRAME_POP, NULL)` | 1.0

Capabilities
Optional Functionality: might not be implemented for all virtual machines. The following capability (as returned by `GetCapabilities`) must be true to use this event.
Capability | Effect
`can_generate_frame_pop_events` | Can set and thus get `FramePop` events

Parameters
Name | Type | Description
`jni_env` | `JNIEnv *` | The JNI environment of the event (current) thread
`thread` | `jthread` | Thread that is popping the frame
`method` | `jmethodID` | Method being popped
`was_popped_by_exception` | `jboolean` | True if frame was popped by a thrown exception. False if method exited through its return instruction.

## Method Entry

>     void JNICALL
>     MethodEntry(jvmtiEnv *jvmti_env,
>                 JNIEnv* jni_env,
>                 jthread thread,
>                 jmethodID method)

Method entry events are generated upon entry of Java programming language methods (including native methods).

The location reported by `GetFrameLocation` identifies the initial executable location in the method.

Enabling method entry or exit events will significantly degrade performance on many platforms and is thus not advised for performance critical usage (such as profiling). Bytecode instrumentation should be used in these cases.

Phase | Event Type | Number | Enabling | Since
sent only during the live phase | `JVMTI_EVENT_METHOD_ENTRY` | 65 | `SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_METHOD_ENTRY, NULL)` | 1.0

Capabilities
Optional Functionality: might not be implemented for all virtual machines. The following capability (as returned by `GetCapabilities`) must be true to use this event.
Capability | Effect
`can_generate_method_entry_events` | Can generate method entry events on entering a method

Parameters
Name | Type | Description
`jni_env` | `JNIEnv *` | The JNI environment of the event (current) thread
`thread` | `jthread` | Thread entering the method
`method` | `jmethodID` | Method being entered

## Method Exit

>     void JNICALL
>     MethodExit(jvmtiEnv *jvmti_env,
>                 JNIEnv* jni_env,
>                 jthread thread,
>                 jmethodID method,
>                 jboolean was_popped_by_exception,
>                 jvalue return_value)

Method exit events are generated upon exit from Java programming language methods (including native methods). This is true whether termination is caused by executing its return instruction or by throwing an exception to its caller (see `was_popped_by_exception`).

The `method` field uniquely identifies the method being entered or exited. The `frame` field provides access to the stack frame for the method.

The location reported by `GetFrameLocation` identifies the executable location in the returning method immediately prior to the return.

Enabling method entry or exit events will significantly degrade performance on many platforms and is thus not advised for performance critical usage (such as profiling). Bytecode instrumentation should be used in these cases.

Phase | Event Type | Number | Enabling | Since
sent only during the live phase | `JVMTI_EVENT_METHOD_EXIT` | 66 | `SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_METHOD_EXIT, NULL)` | 1.0

Capabilities
Optional Functionality: might not be implemented for all virtual machines. The following capability (as returned by `GetCapabilities`) must be true to use this event.
Capability | Effect
`can_generate_method_exit_events` | Can generate method exit events on leaving a method

Parameters
Name | Type | Description
`jni_env` | `JNIEnv *` | The JNI environment of the event (current) thread
`thread` | `jthread` | Thread exiting the method
`method` | `jmethodID` | Method being exited
`was_popped_by_exception` | `jboolean` | True if frame was popped by a thrown exception. False if method exited through its return instruction.
`return_value` | `jvalue` | The return value of the method being exited. Undefined and should not be used if `was_popped_by_exception` is true.

## Native Method Bind

>     void JNICALL
>     NativeMethodBind(jvmtiEnv *jvmti_env,
>                 JNIEnv* jni_env,
>                 jthread thread,
>                 jmethodID method,
>                 void* address,
>                 void** new_address_ptr)

A Native Method Bind event is sent when a VM binds a Java programming language native method to the address of a function that implements the native method. This will occur when the native method is called for the first time and also occurs when the JNI function `RegisterNatives` is called. This event allows the bind to be redirected to an agent-specified proxy function. This event is not sent when the native method is unbound. Typically, this proxy function will need to be specific to a particular method or, to handle the general case, automatically generated assembly code, since after instrumentation code is executed the function at the original binding address will usually be invoked. The original binding can be restored or the redirection changed by use of the JNI function `RegisterNatives`. Some events may be sent during the primordial phase, JNI and most of JVM TI cannot be used at this time but the method and address can be saved for use later.

Phase | Event Type | Number | Enabling | Since
sent during the primordial, start or live phase | `JVMTI_EVENT_NATIVE_METHOD_BIND` | 67 | `SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_NATIVE_METHOD_BIND, NULL)` | 1.0

Capabilities
Optional Functionality: might not be implemented for all virtual machines. The following capability (as returned by `GetCapabilities`) must be true to use this event.
Capability | Effect
`can_generate_native_method_bind_events` | Can generate events when a native method is bound to its implementation

Parameters
Name | Type | Description
`jni_env` | `JNIEnv *` | The JNI environment of the event (current) thread Will be `NULL` if sent during the primordial phase.
`thread` | `jthread` | Thread requesting the bind
`method` | `jmethodID` | Native method being bound
`address` | `void*` | The address the VM is about to bind to--that is, the address of the implementation of the native method
`new_address_ptr` | `void**` | if the referenced address is changed (that is, if `*new_address_ptr` is set), the binding will instead be made to the supplied address.

## Exception

>     void JNICALL
>     Exception(jvmtiEnv *jvmti_env,
>                 JNIEnv* jni_env,
>                 jthread thread,
>                 jmethodID method,
>                 jlocation location,
>                 jobject exception,
>                 jmethodID catch_method,
>                 jlocation catch_location)

Exception events are generated whenever an exception is first detected in a Java programming language method. Where "exception" means any `java.lang.Throwable`. The exception may have been thrown by a Java programming language or native method, but in the case of native methods, the event is not generated until the exception is first seen by a Java programming language method. If an exception is set and cleared in a native method (and thus is never visible to Java programming language code), no exception event is generated.

The `method` and `location` parameters uniquely identify the current location (where the exception was detected) and allow the mapping to source file and line number when that information is available. The `exception` field identifies the thrown exception object. The `catch_method` and `catch_location` identify the location of the catch clause, if any, that handles the thrown exception. If there is no such catch clause, each field is set to 0. There is no guarantee that the thread will ever reach this catch clause. If there are native methods on the call stack between the throw location and the catch clause, the exception may be reset by one of those native methods. Similarly, exceptions that are reported as uncaught (`catch_klass` et al. set to 0) may in fact be caught by native code. Agents can check for these occurrences by monitoring `ExceptionCatch` events. Note that finally clauses are implemented as catch and re-throw. Therefore they will be reported in the catch location.

Phase | Event Type | Number | Enabling | Since
sent only during the live phase | `JVMTI_EVENT_EXCEPTION` | 58 | `SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_EXCEPTION, NULL)` | 1.0

Capabilities
Optional Functionality: might not be implemented for all virtual machines. The following capability (as returned by `GetCapabilities`) must be true to use this event.
Capability | Effect
`can_generate_exception_events` | Can get exception thrown and exception catch events

Parameters
Name | Type | Description
`jni_env` | `JNIEnv *` | The JNI environment of the event (current) thread
`thread` | `jthread` | Thread generating the exception
`method` | `jmethodID` | Method generating the exception
`location` | `jlocation` | Location where exception occurred
`exception` | `jobject` | The exception being thrown
`catch_method` | `jmethodID` | Method that will catch the exception, or `NULL` if no known catch
`catch_location` | `jlocation` | location which will catch the exception or zero if no known catch

## Exception Catch

>     void JNICALL
>     ExceptionCatch(jvmtiEnv *jvmti_env,
>                 JNIEnv* jni_env,
>                 jthread thread,
>                 jmethodID method,
>                 jlocation location,
>                 jobject exception)

Exception catch events are generated whenever a thrown exception is caught. Where "exception" means any `java.lang.Throwable`. If the exception is caught in a Java programming language method, the event is generated when the catch clause is reached. If the exception is caught in a native method, the event is generated as soon as control is returned to a Java programming language method. Exception catch events are generated for any exception for which a throw was detected in a Java programming language method. Note that finally clauses are implemented as catch and re-throw. Therefore they will generate exception catch events.

The `method` and `location` parameters uniquely identify the current location and allow the mapping to source file and line number when that information is available. For exceptions caught in a Java programming language method, the `exception` object identifies the exception object. Exceptions caught in native methods are not necessarily available by the time the exception catch is reported, so the `exception` field is set to `NULL`.

Phase | Event Type | Number | Enabling | Since
sent only during the live phase | `JVMTI_EVENT_EXCEPTION_CATCH` | 59 | `SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_EXCEPTION_CATCH, NULL)` | 1.0

Capabilities
Optional Functionality: might not be implemented for all virtual machines. The following capability (as returned by `GetCapabilities`) must be true to use this event.
Capability | Effect
`can_generate_exception_events` | Can get exception thrown and exception catch events

Parameters
Name | Type | Description
`jni_env` | `JNIEnv *` | The JNI environment of the event (current) thread
`thread` | `jthread` | Thread catching the exception
`method` | `jmethodID` | Method catching the exception
`location` | `jlocation` | Location where exception is being caught
`exception` | `jobject` | Exception being caught

## Thread Start

>     void JNICALL
>     ThreadStart(jvmtiEnv *jvmti_env,
>                 JNIEnv* jni_env,
>                 jthread thread)

Thread start events are generated by a new thread before its initial method executes.

A thread may be listed in the array returned by `GetAllThreads` before its thread start event is generated. It is possible for other events to be generated on a thread before its thread start event.

The event is sent on the newly started `thread`.

Phase | Event Type | Number | Enabling | Since
sent during the start or live phase | `JVMTI_EVENT_THREAD_START` | 52 | `SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_THREAD_START, NULL)` | 1.0

Capabilities
Required Functionality

Parameters
Name | Type | Description
`jni_env` | `JNIEnv *` | The JNI environment of the event (current) thread.
`thread` | `jthread` | Thread starting

## Thread End

>     void JNICALL
>     ThreadEnd(jvmtiEnv *jvmti_env,
>                 JNIEnv* jni_env,
>                 jthread thread)

Thread end events are generated by a terminating thread after its initial method has finished execution.

A thread may be listed in the array returned by `GetAllThreads` after its thread end event is generated. No events are generated on a thread after its thread end event.

The event is sent on the dying `thread`.

Phase | Event Type | Number | Enabling | Since
sent during the start or live phase | `JVMTI_EVENT_THREAD_END` | 53 | `SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_THREAD_END, NULL)` | 1.0

Capabilities
Required Functionality

Parameters
Name | Type | Description
`jni_env` | `JNIEnv *` | The JNI environment of the event (current) thread.
`thread` | `jthread` | Thread ending

## Class Load

>     void JNICALL
>     ClassLoad(jvmtiEnv *jvmti_env,
>                 JNIEnv* jni_env,
>                 jthread thread,
>                 jclass klass)

A class load event is generated when a class is first loaded. The order of class load events generated by a particular thread are guaranteed to match the order of class loading within that thread. Array class creation does not generate a class load event. The creation of a primitive class (for example, java.lang.Integer.TYPE) does not generate a class load event.

This event is sent at an early stage in loading the class. As a result the class should be used carefully. Note, for example, that methods and fields are not yet loaded, so queries for methods, fields, subclasses, and so on will not give correct results. See "Loading of Classes and Interfaces" in the Java Language Specification. For most purposes the `ClassPrepare` event will be more useful.

Phase | Event Type | Number | Enabling | Since
sent during the start or live phase | `JVMTI_EVENT_CLASS_LOAD` | 55 | `SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_CLASS_LOAD, NULL)` | 1.0

Capabilities
Required Functionality

Parameters
Name | Type | Description
`jni_env` | `JNIEnv *` | The JNI environment of the event (current) thread
`thread` | `jthread` | Thread loading the class
`klass` | `jclass` | Class being loaded

## Class Prepare

>     void JNICALL
>     ClassPrepare(jvmtiEnv *jvmti_env,
>                 JNIEnv* jni_env,
>                 jthread thread,
>                 jclass klass)

A class prepare event is generated when class preparation is complete. At this point, class fields, methods, and implemented interfaces are available, and no code from the class has been executed. Since array classes never have fields or methods, class prepare events are not generated for them. Class prepare events are not generated for primitive classes (for example, `java.lang.Integer.TYPE`).

Phase | Event Type | Number | Enabling | Since
sent during the start or live phase | `JVMTI_EVENT_CLASS_PREPARE` | 56 | `SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_CLASS_PREPARE, NULL)` | 1.0

Capabilities
Required Functionality

Parameters
Name | Type | Description
`jni_env` | `JNIEnv *` | The JNI environment of the event (current) thread
`thread` | `jthread` | Thread generating the class prepare
`klass` | `jclass` | Class being prepared

## Class File Load Hook

>     void JNICALL
>     ClassFileLoadHook(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)

This event is sent when the VM obtains class file data, but before it constructs the in-memory representation for that class. This event is also sent when the class is being modified by the `RetransformClasses` function or the `RedefineClasses` function, called in any JVM TI environment. The agent can instrument the existing class file data sent by the VM to include profiling/debugging hooks. See the description of bytecode instrumentation for usage information.

This event may be sent before the VM is initialized (the primordial phase). During this time no VM resources should be created. Some classes might not be compatible with the function (eg. ROMized classes) and this event will not be generated for these classes.

The agent must allocate the space for the modified class file data buffer using the memory allocation function `Allocate` because the VM is responsible for freeing the new class file data buffer using `Deallocate`. Note that `Allocate` is permitted during the primordial phase.

If the agent wishes to modify the class file, it must set `new_class_data` to point to the newly instrumented class file data buffer and set `new_class_data_len` to the length of that buffer before returning from this call. If no modification is desired, the agent simply does not set `new_class_data`. If multiple agents have enabled this event the results are chained. That is, if `new_class_data` has been set, it becomes the `class_data` for the next agent.

The order that this event is sent to each environment differs from other events. This event is sent to environments in the following order:

- retransformation incapable environments, in the order in which they were created
- retransformation capable environments, in the order in which they were created

When triggered by `RetransformClasses`, this event is sent only to retransformation capable environments.

Phase | Event Type | Number | Enabling | Since
sent during the primordial, start or live phase | `JVMTI_EVENT_CLASS_FILE_LOAD_HOOK` | 54 | `SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_CLASS_FILE_LOAD_HOOK, NULL)` | 1.0

Capabilities
Required Functionality
Optional Features
Capability | Effect
`can_generate_all_class_hook_events` | Can generate ClassFileLoadHook events for every loaded class.

Parameters
Name | Type | Description
`jni_env` | `JNIEnv *` | The JNI environment of the event (current) thread. Will be `NULL` if sent during the primordial phase.
`class_being_redefined` | `jclass` | The class being redefined or retransformed. `NULL` if sent by class load.
`loader` | `jobject` | The class loader loading the class. `NULL` if the bootstrap class loader.
`name` | `const char*` | Name of class being loaded as a VM internal qualified name (for example, "java/util/List"), encoded as a modified UTF-8 string. Note: if the class is defined with a `NULL` name or without a name specified, `name` will be `NULL`.
`protection_domain` | `jobject` | The `ProtectionDomain` of the class.
`class_data_len` | `jint` | Length of current class file data buffer.
`class_data` | `const unsigned char*` | Pointer to the current class file data buffer.
`new_class_data_len` | `jint*` | Pointer to the length of the new class file data buffer.
`new_class_data` | `unsigned char**` | Pointer to the pointer to the instrumented class file data buffer.

## VM Start Event

>     void JNICALL
>     VMStart(jvmtiEnv *jvmti_env,
>                 JNIEnv* jni_env)

The VM initialization event signals the start of the VM. At this time JNI is live but the VM is not yet fully initialized. Once this event is generated, the agent is free to call any JNI function. This event signals the beginning of the start phase, JVM TI functions permitted in the start phase may be called.

In the case of VM start-up failure, this event will not be sent.

Phase | Event Type | Number | Enabling | Since
sent during the start or live phase | `JVMTI_EVENT_VM_START` | 57 | `SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_VM_START, NULL)` | 1.0

Capabilities
Required Functionality

Parameters
Name | Type | Description
`jni_env` | `JNIEnv *` | The JNI environment of the event (current) thread.

## VM Initialization Event

>     void JNICALL
>     VMInit(jvmtiEnv *jvmti_env,
>                 JNIEnv* jni_env,
>                 jthread thread)

The VM initialization event signals the completion of VM initialization. Once this event is generated, the agent is free to call any JNI or JVM TI function. The VM initialization event can be preceded by or can be concurrent with other events, but the preceding events should be handled carefully, if at all, because the VM has not completed its initialization. The thread start event for the main application thread is guaranteed not to occur until after the handler for the VM initialization event returns.

In the case of VM start-up failure, this event will not be sent.

Phase | Event Type | Number | Enabling | Since
sent only during the live phase | `JVMTI_EVENT_VM_INIT` | 50 | `SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_VM_INIT, NULL)` | 1.0

Capabilities
Required Functionality

Parameters
Name | Type | Description
`jni_env` | `JNIEnv *` | The JNI environment of the event (current) thread.
`thread` | `jthread` | The initial thread

## VM Death Event

>     void JNICALL
>     VMDeath(jvmtiEnv *jvmti_env,
>                 JNIEnv* jni_env)

The VM death event notifies the agent of the termination of the VM. No events will occur after the VMDeath event.

In the case of VM start-up failure, this event will not be sent. Note that Agent_OnUnload will still be called in these cases.

Phase | Event Type | Number | Enabling | Since
sent only during the live phase | `JVMTI_EVENT_VM_DEATH` | 51 | `SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_VM_DEATH, NULL)` | 1.0

Capabilities
Required Functionality

Parameters
Name | Type | Description
`jni_env` | `JNIEnv *` | The JNI environment of the event (current) thread

## Compiled Method Load

>     typedef struct {
>         const void* start_address;
>         jlocation location;
>     } jvmtiAddrLocationMap;

>     void JNICALL
>     CompiledMethodLoad(jvmtiEnv *jvmti_env,
>                 jmethodID method,
>                 jint code_size,
>                 const void* code_addr,
>                 jint map_length,
>                 const jvmtiAddrLocationMap* map,
>                 const void* compile_info)

Sent when a method is compiled and loaded into memory by the VM. If it is unloaded, the `CompiledMethodUnload` event is sent. If it is moved, the `CompiledMethodUnload` event is sent, followed by a new `CompiledMethodLoad` event. Note that a single method may have multiple compiled forms, and that this event will be sent for each form. Note also that several methods may be inlined into a single address range, and that this event will be sent for each method.

These events can be sent after their initial occurrence with `GenerateEvents`.

Phase | Event Type | Number | Enabling | Since
sent only during the live phase | `JVMTI_EVENT_COMPILED_METHOD_LOAD` | 68 | `SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_COMPILED_METHOD_LOAD, NULL)` | 1.0

`jvmtiAddrLocationMap` - Native address to location entry
Field | Type | Description
`start_address` | `const void*` | Starting native address of code corresponding to a location
`location` | `jlocation` | Corresponding location. See `GetJLocationFormat` for the meaning of location.

Capabilities
Optional Functionality: might not be implemented for all virtual machines. The following capability (as returned by `GetCapabilities`) must be true to use this event.
Capability | Effect
`can_generate_compiled_method_load_events` | Can generate events when a method is compiled or unloaded

Parameters
Name | Type | Description
`method` | `jmethodID` | Method being compiled and loaded
`code_size` | `jint` | Size of compiled code
`code_addr` | `const void*` | Address where compiled method code is loaded
`map_length` | `jint` | Number of `jvmtiAddrLocationMap` entries in the address map. Zero if mapping information cannot be supplied.
`map` | `const jvmtiAddrLocationMap*` | Map from native addresses to location. The native address range of each entry is from `start_address` to `start_address-1` of the next entry. `NULL` if mapping information cannot be supplied.
`compile_info` | `const void*` | VM-specific compilation information. The referenced compile information is managed by the VM and must not depend on the agent for collection. A VM implementation defines the content and lifetime of the information.

## Compiled Method Unload

>     void JNICALL
>     CompiledMethodUnload(jvmtiEnv *jvmti_env,
>                 jmethodID method,
>                 const void* code_addr)

Sent when a compiled method is unloaded from memory. This event might not be sent on the thread which performed the unload. This event may be sent sometime after the unload occurs, but will be sent before the memory is reused by a newly generated compiled method. This event may be sent after the class is unloaded.

Phase | Event Type | Number | Enabling | Since
sent only during the live phase | `JVMTI_EVENT_COMPILED_METHOD_UNLOAD` | 69 | `SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_COMPILED_METHOD_UNLOAD, NULL)` | 1.0

Capabilities
Optional Functionality: might not be implemented for all virtual machines. The following capability (as returned by `GetCapabilities`) must be true to use this event.
Capability | Effect
`can_generate_compiled_method_load_events` | Can generate events when a method is compiled or unloaded

Parameters
Name | Type | Description
`method` | `jmethodID` | Compiled method being unloaded. For identification of the compiled method only -- the class may be unloaded and therefore the method should not be used as an argument to further JNI or JVM TI functions.
`code_addr` | `const void*` | Address where compiled method code was loaded. For identification of the compiled method only -- the space may have been reclaimed.

## Dynamic Code Generated

>     void JNICALL
>     DynamicCodeGenerated(jvmtiEnv *jvmti_env,
>                 const char* name,
>                 const void* address,
>                 jint length)

Sent when a component of the virtual machine is generated dynamically. This does not correspond to Java programming language code that is compiled--see `CompiledMethodLoad`. This is for native code--for example, an interpreter that is generated differently depending on command-line options.

Note that this event has no controlling capability. If a VM cannot generate these events, it simply does not send any.

These events can be sent after their initial occurrence with `GenerateEvents`.

Phase | Event Type | Number | Enabling | Since
sent during the primordial, start or live phase | `JVMTI_EVENT_DYNAMIC_CODE_GENERATED` | 70 | `SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_DYNAMIC_CODE_GENERATED, NULL)` | 1.0

Capabilities
Required Functionality

Parameters
Name | Type | Description
`name` | `const char*` | Name of the code, encoded as a modified UTF-8 string. Intended for display to an end-user. The name might not be unique.
`address` | `const void*` | Native address of the code
`length` | `jint` | Length in bytes of the code

## Data Dump Request

>     void JNICALL
>     DataDumpRequest(jvmtiEnv *jvmti_env)

Sent by the VM to request the agent to dump its data. This is just a hint and the agent need not react to this event. This is useful for processing command-line signals from users. For example, in the Java 2 SDK a CTRL-Break on Win32 and a CTRL-\ on Solaris causes the VM to send this event to the agent.

Phase | Event Type | Number | Enabling | Since
sent only during the live phase | `JVMTI_EVENT_DATA_DUMP_REQUEST` | 71 | `SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_DATA_DUMP_REQUEST, NULL)` | 1.0

Capabilities
Required Functionality

Parameters
Name | Type | Description

## Monitor Contended Enter

>     void JNICALL
>     MonitorContendedEnter(jvmtiEnv *jvmti_env,
>                 JNIEnv* jni_env,
>                 jthread thread,
>                 jobject object)

Sent when a thread is attempting to enter a Java programming language monitor already acquired by another thread.

Phase | Event Type | Number | Enabling | Since
sent only during the live phase | `JVMTI_EVENT_MONITOR_CONTENDED_ENTER` | 75 | `SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_MONITOR_CONTENDED_ENTER, NULL)` | 1.0

Capabilities
Optional Functionality: might not be implemented for all virtual machines. The following capability (as returned by `GetCapabilities`) must be true to use this event.
Capability | Effect
`can_generate_monitor_events` | Can generate events on monitor activity

Parameters
Name | Type | Description
`jni_env` | `JNIEnv *` | The JNI environment of the event (current) thread
`thread` | `jthread` | JNI local reference to the thread attempting to enter the monitor
`object` | `jobject` | JNI local reference to the monitor

## Monitor Contended Entered

>     void JNICALL
>     MonitorContendedEntered(jvmtiEnv *jvmti_env,
>                 JNIEnv* jni_env,
>                 jthread thread,
>                 jobject object)

Sent when a thread enters a Java programming language monitor after waiting for it to be released by another thread.

Phase | Event Type | Number | Enabling | Since
sent only during the live phase | `JVMTI_EVENT_MONITOR_CONTENDED_ENTERED` | 76 | `SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_MONITOR_CONTENDED_ENTERED, NULL)` | 1.0

Capabilities
Optional Functionality: might not be implemented for all virtual machines. The following capability (as returned by `GetCapabilities`) must be true to use this event.
Capability | Effect
`can_generate_monitor_events` | Can generate events on monitor activity

Parameters
Name | Type | Description
`jni_env` | `JNIEnv *` | The JNI environment of the event (current) thread
`thread` | `jthread` | JNI local reference to the thread entering the monitor
`object` | `jobject` | JNI local reference to the monitor

## Monitor Wait

>     void JNICALL
>     MonitorWait(jvmtiEnv *jvmti_env,
>                 JNIEnv* jni_env,
>                 jthread thread,
>                 jobject object,
>                 jlong timeout)

Sent when a thread is about to wait on an object.

Phase | Event Type | Number | Enabling | Since
sent only during the live phase | `JVMTI_EVENT_MONITOR_WAIT` | 73 | `SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_MONITOR_WAIT, NULL)` | 1.0

Capabilities
Optional Functionality: might not be implemented for all virtual machines. The following capability (as returned by `GetCapabilities`) must be true to use this event.
Capability | Effect
`can_generate_monitor_events` | Can generate events on monitor activity

Parameters
Name | Type | Description
`jni_env` | `JNIEnv *` | The JNI environment of the event (current) thread
`thread` | `jthread` | JNI local reference to the thread about to wait
`object` | `jobject` | JNI local reference to the monitor
`timeout` | `jlong` | The number of milliseconds the thread will wait

## Monitor Waited

>     void JNICALL
>     MonitorWaited(jvmtiEnv *jvmti_env,
>                 JNIEnv* jni_env,
>                 jthread thread,
>                 jobject object,
>                 jboolean timed_out)

Sent when a thread finishes waiting on an object.

Phase | Event Type | Number | Enabling | Since
sent only during the live phase | `JVMTI_EVENT_MONITOR_WAITED` | 74 | `SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_MONITOR_WAITED, NULL)` | 1.0

Capabilities
Optional Functionality: might not be implemented for all virtual machines. The following capability (as returned by `GetCapabilities`) must be true to use this event.
Capability | Effect
`can_generate_monitor_events` | Can generate events on monitor activity

Parameters
Name | Type | Description
`jni_env` | `JNIEnv *` | The JNI environment of the event (current) thread
`thread` | `jthread` | JNI local reference to the thread that was finished waiting
`object` | `jobject` | JNI local reference to the monitor.
`timed_out` | `jboolean` | True if the monitor timed out

## Resource Exhausted

>     void JNICALL
>     ResourceExhausted(jvmtiEnv *jvmti_env,
>                 JNIEnv* jni_env,
>                 jint flags,
>                 const void* reserved,
>                 const char* description)

Sent when a VM resource needed by a running application has been exhausted. Except as required by the optional capabilities, the set of resources which report exhaustion is implementation dependent.

The following bit flags define the properties of the resource exhaustion:

> Resource Exhaustion Flags
> Constant | Value | Description
> `JVMTI_RESOURCE_EXHAUSTED_OOM_ERROR` | 0x0001 | After this event returns, the VM will throw a `java.lang.OutOfMemoryError`.
> `JVMTI_RESOURCE_EXHAUSTED_JAVA_HEAP` | 0x0002 | The VM was unable to allocate memory from the JavaTM platform heap. The heap is the runtime data area from which memory for all class instances and arrays are allocated.
> `JVMTI_RESOURCE_EXHAUSTED_THREADS` | 0x0004 | The VM was unable to create a thread.

Phase | Event Type | Number | Enabling | Since
sent only during the live phase | `JVMTI_EVENT_RESOURCE_EXHAUSTED` | 80 | `SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_RESOURCE_EXHAUSTED, NULL)` | 1.1

Capabilities
Required Functionality
Optional Features
Capability | Effect
`can_generate_resource_exhaustion_heap_events` | Can generate events when the VM is unable to allocate memory from the heap.
`can_generate_resource_exhaustion_threads_events` | Can generate events when the VM is unable to create a thread.

Parameters
Name | Type | Description
`jni_env` | `JNIEnv *` | The JNI environment of the event (current) thread
`flags` | `jint` | Flags defining the properties of the of resource exhaustion as specified by the Resource Exhaustion Flags.
`reserved` | `const void*` | Reserved.
`description` | `const char*` | Description of the resource exhaustion, encoded as a modified UTF-8 string.

## VM Object Allocation

>     void JNICALL
>     VMObjectAlloc(jvmtiEnv *jvmti_env,
>                 JNIEnv* jni_env,
>                 jthread thread,
>                 jobject object,
>                 jclass object_klass,
>                 jlong size)

Sent when a method causes the virtual machine to allocate an Object visible to Java programming language code and the allocation is not detectable by other intrumentation mechanisms. Generally object allocation should be detected by instrumenting the bytecodes of allocating methods. Object allocation generated in native code by JNI function calls should be detected using JNI function interception. Some methods might not have associated bytecodes and are not native methods, they instead are executed directly by the VM. These methods should send this event. Virtual machines which are incapable of bytecode instrumentation for some or all of their methods can send this event.

Typical examples where this event might be sent:

- Reflection -- for example, `java.lang.Class.newInstance()`
- Methods not represented by bytecodes -- for example, VM intrinsics and J2ME preloaded classes

Cases where this event would not be generated:

- Allocation due to bytecodes -- for example, the `new` and `newarray` VM instructions
- Allocation due to JNI function calls -- for example, `AllocObject`
- Allocations during VM initialization
- VM internal objects

Phase | Event Type | Number | Enabling | Since
sent only during the live phase | `JVMTI_EVENT_VM_OBJECT_ALLOC` | 84 | `SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_VM_OBJECT_ALLOC, NULL)` | 1.0

Capabilities
Optional Functionality: might not be implemented for all virtual machines. The following capability (as returned by `GetCapabilities`) must be true to use this event.
Capability | Effect
`can_generate_vm_object_alloc_events` | Can generate events on VM allocation of an object

Parameters
Name | Type | Description
`jni_env` | `JNIEnv *` | The JNI environment of the event (current) thread
`thread` | `jthread` | Thread allocating the object.
`object` | `jobject` | JNI local reference to the object that was allocated
`object_klass` | `jclass` | JNI local reference to the class of the object
`size` | `jlong` | Size of the object (in bytes). See `GetObjectSize`.

## Object Free

>     void JNICALL
>     ObjectFree(jvmtiEnv *jvmti_env,
>                 jlong tag)

An Object Free event is sent when the garbage collector frees an object. Events are only sent for tagged objects--see heap functions.

The event handler must not use JNI functions and must not use JVM TI functions except those which specifically allow such use (see the raw monitor, memory management, and environment local storage functions).

Phase | Event Type | Number | Enabling | Since
sent only during the live phase | `JVMTI_EVENT_OBJECT_FREE` | 83 | `SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_OBJECT_FREE, NULL)` | 1.0

Capabilities
Optional Functionality: might not be implemented for all virtual machines. The following capability (as returned by `GetCapabilities`) must be true to use this event.
Capability | Effect
`can_generate_object_free_events` | Can generate events when the garbage collector frees an object

Parameters
Name | Type | Description
`tag` | `jlong` | The freed object's tag

## Garbage Collection Start

>     void JNICALL
>     GarbageCollectionStart(jvmtiEnv *jvmti_env)

A Garbage Collection Start event is sent when a full cycle garbage collection begins. Only stop-the-world collections are reported--that is, collections during which all threads cease to modify the state of the Java virtual machine. This means that some collectors will never generate these events. This event is sent while the VM is still stopped, thus the event handler must not use JNI functions and must not use JVM TI functions except those which specifically allow such use (see the raw monitor, memory management, and environment local storage functions).

This event is always sent as a matched pair with `GarbageCollectionFinish` (assuming both events are enabled) and no garbage collection events will occur between them.

Phase | Event Type | Number | Enabling | Since
sent only during the live phase | `JVMTI_EVENT_GARBAGE_COLLECTION_START` | 81 | `SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_GARBAGE_COLLECTION_START, NULL)` | 1.0

Capabilities
Optional Functionality: might not be implemented for all virtual machines. The following capability (as returned by `GetCapabilities`) must be true to use this event.
Capability | Effect
`can_generate_garbage_collection_events` | Can generate events when garbage collection begins or ends

Parameters
Name | Type | Description

## Garbage Collection Finish

>     void JNICALL
>     GarbageCollectionFinish(jvmtiEnv *jvmti_env)

A Garbage Collection Finish event is sent when a full garbage collection cycle ends. This event is sent while the VM is still stopped, thus the event handler must not use JNI functions and must not use JVM TI functions except those which specifically allow such use (see the raw monitor, memory management, and environment local storage functions).

Some agents may need to do post garbage collection operations that require the use of the disallowed JVM TI or JNI functions. For these cases an agent thread can be created which waits on a raw monitor, and the handler for the Garbage Collection Finish event simply notifies the raw monitor

This event is always sent as a matched pair with `GarbageCollectionStart` (assuming both events are enabled).

Phase | Event Type | Number | Enabling | Since
sent only during the live phase | `JVMTI_EVENT_GARBAGE_COLLECTION_FINISH` | 82 | `SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_GARBAGE_COLLECTION_FINISH, NULL)` | 1.0

Capabilities
Optional Functionality: might not be implemented for all virtual machines. The following capability (as returned by `GetCapabilities`) must be true to use this event.
Capability | Effect
`can_generate_garbage_collection_events` | Can generate events when garbage collection begins or ends

Parameters
Name | Type | Description

## Constant Index

> `JVMTI_CLASS_STATUS_ARRAY`
> `JVMTI_CLASS_STATUS_ERROR`
> `JVMTI_CLASS_STATUS_INITIALIZED`
> `JVMTI_CLASS_STATUS_PREPARED`
> `JVMTI_CLASS_STATUS_PRIMITIVE`
> `JVMTI_CLASS_STATUS_VERIFIED`
> `JVMTI_DISABLE`
> `JVMTI_ENABLE`
> `JVMTI_HEAP_FILTER_CLASS_TAGGED`
> `JVMTI_HEAP_FILTER_CLASS_UNTAGGED`
> `JVMTI_HEAP_FILTER_TAGGED`
> `JVMTI_HEAP_FILTER_UNTAGGED`
> `JVMTI_HEAP_OBJECT_EITHER`
> `JVMTI_HEAP_OBJECT_TAGGED`
> `JVMTI_HEAP_OBJECT_UNTAGGED`
> `JVMTI_HEAP_REFERENCE_ARRAY_ELEMENT`
> `JVMTI_HEAP_REFERENCE_CLASS`
> `JVMTI_HEAP_REFERENCE_CLASS_LOADER`
> `JVMTI_HEAP_REFERENCE_CONSTANT_POOL`
> `JVMTI_HEAP_REFERENCE_FIELD`
> `JVMTI_HEAP_REFERENCE_INTERFACE`
> `JVMTI_HEAP_REFERENCE_JNI_GLOBAL`
> `JVMTI_HEAP_REFERENCE_JNI_LOCAL`
> `JVMTI_HEAP_REFERENCE_MONITOR`
> `JVMTI_HEAP_REFERENCE_OTHER`
> `JVMTI_HEAP_REFERENCE_PROTECTION_DOMAIN`
> `JVMTI_HEAP_REFERENCE_SIGNERS`
> `JVMTI_HEAP_REFERENCE_STACK_LOCAL`
> `JVMTI_HEAP_REFERENCE_STATIC_FIELD`
> `JVMTI_HEAP_REFERENCE_SUPERCLASS`
> `JVMTI_HEAP_REFERENCE_SYSTEM_CLASS`
> `JVMTI_HEAP_REFERENCE_THREAD`
> `JVMTI_HEAP_ROOT_JNI_GLOBAL`
> `JVMTI_HEAP_ROOT_JNI_LOCAL`
> `JVMTI_HEAP_ROOT_MONITOR`
> `JVMTI_HEAP_ROOT_OTHER`
> `JVMTI_HEAP_ROOT_STACK_LOCAL`
> `JVMTI_HEAP_ROOT_SYSTEM_CLASS`
> `JVMTI_HEAP_ROOT_THREAD`
> `JVMTI_ITERATION_ABORT`
> `JVMTI_ITERATION_CONTINUE`
> `JVMTI_ITERATION_IGNORE`
> `JVMTI_JAVA_LANG_THREAD_STATE_BLOCKED`
> `JVMTI_JAVA_LANG_THREAD_STATE_MASK`
> `JVMTI_JAVA_LANG_THREAD_STATE_NEW`
> `JVMTI_JAVA_LANG_THREAD_STATE_RUNNABLE`
> `JVMTI_JAVA_LANG_THREAD_STATE_TERMINATED`
> `JVMTI_JAVA_LANG_THREAD_STATE_TIMED_WAITING`
> `JVMTI_JAVA_LANG_THREAD_STATE_WAITING`
> `JVMTI_JLOCATION_JVMBCI`
> `JVMTI_JLOCATION_MACHINEPC`
> `JVMTI_JLOCATION_OTHER`
> `JVMTI_KIND_ALLOC_ALLOC_BUF`
> `JVMTI_KIND_ALLOC_BUF`
> `JVMTI_KIND_IN`
> `JVMTI_KIND_IN_BUF`
> `JVMTI_KIND_IN_PTR`
> `JVMTI_KIND_OUT`
> `JVMTI_KIND_OUT_BUF`
> `JVMTI_PHASE_DEAD`
> `JVMTI_PHASE_LIVE`
> `JVMTI_PHASE_ONLOAD`
> `JVMTI_PHASE_PRIMORDIAL`
> `JVMTI_PHASE_START`
> `JVMTI_PRIMITIVE_TYPE_BOOLEAN`
> `JVMTI_PRIMITIVE_TYPE_BYTE`
> `JVMTI_PRIMITIVE_TYPE_CHAR`
> `JVMTI_PRIMITIVE_TYPE_DOUBLE`
> `JVMTI_PRIMITIVE_TYPE_FLOAT`
> `JVMTI_PRIMITIVE_TYPE_INT`
> `JVMTI_PRIMITIVE_TYPE_LONG`
> `JVMTI_PRIMITIVE_TYPE_SHORT`
> `JVMTI_REFERENCE_ARRAY_ELEMENT`
> `JVMTI_REFERENCE_CLASS`
> `JVMTI_REFERENCE_CLASS_LOADER`
> `JVMTI_REFERENCE_CONSTANT_POOL`
> `JVMTI_REFERENCE_FIELD`
> `JVMTI_REFERENCE_INTERFACE`
> `JVMTI_REFERENCE_PROTECTION_DOMAIN`
> `JVMTI_REFERENCE_SIGNERS`
> `JVMTI_REFERENCE_STATIC_FIELD`
> `JVMTI_RESOURCE_EXHAUSTED_JAVA_HEAP`
> `JVMTI_RESOURCE_EXHAUSTED_OOM_ERROR`
> `JVMTI_RESOURCE_EXHAUSTED_THREADS`
> `JVMTI_THREAD_MAX_PRIORITY`
> `JVMTI_THREAD_MIN_PRIORITY`
> `JVMTI_THREAD_NORM_PRIORITY`
> `JVMTI_THREAD_STATE_ALIVE`
> `JVMTI_THREAD_STATE_BLOCKED_ON_MONITOR_ENTER`
> `JVMTI_THREAD_STATE_IN_NATIVE`
> `JVMTI_THREAD_STATE_IN_OBJECT_WAIT`
> `JVMTI_THREAD_STATE_INTERRUPTED`
> `JVMTI_THREAD_STATE_PARKED`
> `JVMTI_THREAD_STATE_RUNNABLE`
> `JVMTI_THREAD_STATE_SLEEPING`
> `JVMTI_THREAD_STATE_SUSPENDED`
> `JVMTI_THREAD_STATE_TERMINATED`
> `JVMTI_THREAD_STATE_VENDOR_1`
> `JVMTI_THREAD_STATE_VENDOR_2`
> `JVMTI_THREAD_STATE_VENDOR_3`
> `JVMTI_THREAD_STATE_WAITING`
> `JVMTI_THREAD_STATE_WAITING_INDEFINITELY`
> `JVMTI_THREAD_STATE_WAITING_WITH_TIMEOUT`
> `JVMTI_TIMER_ELAPSED`
> `JVMTI_TIMER_TOTAL_CPU`
> `JVMTI_TIMER_USER_CPU`
> `JVMTI_TYPE_CCHAR`
> `JVMTI_TYPE_CVOID`
> `JVMTI_TYPE_JBOOLEAN`
> `JVMTI_TYPE_JBYTE`
> `JVMTI_TYPE_JCHAR`
> `JVMTI_TYPE_JCLASS`
> `JVMTI_TYPE_JDOUBLE`
> `JVMTI_TYPE_JFIELDID`
> `JVMTI_TYPE_JFLOAT`
> `JVMTI_TYPE_JINT`
> `JVMTI_TYPE_JLONG`
> `JVMTI_TYPE_JMETHODID`
> `JVMTI_TYPE_JNIENV`
> `JVMTI_TYPE_JOBJECT`
> `JVMTI_TYPE_JSHORT`
> `JVMTI_TYPE_JTHREAD`
> `JVMTI_TYPE_JVALUE`
> `JVMTI_VERBOSE_CLASS`
> `JVMTI_VERBOSE_GC`
> `JVMTI_VERBOSE_JNI`
> `JVMTI_VERBOSE_OTHER`
> `JVMTI_VERSION_INTERFACE_JNI`
> `JVMTI_VERSION_INTERFACE_JVMTI`
> `JVMTI_VERSION_MASK_INTERFACE_TYPE`
> `JVMTI_VERSION_MASK_MAJOR`
> `JVMTI_VERSION_MASK_MICRO`
> `JVMTI_VERSION_MASK_MINOR`
> `JVMTI_VERSION_SHIFT_MAJOR`
> `JVMTI_VERSION_SHIFT_MICRO`
> `JVMTI_VERSION_SHIFT_MINOR`
> `JVMTI_VISIT_ABORT`
> `JVMTI_VISIT_OBJECTS`

## Change History

Last update: 09/05/07
Version: 1.1.109

The JVM TI specification is an evolving document with major, minor, and micro version numbers. A released version of the specification is uniquely identified by its major and minor version. The functions, events, and capabilities in this specification indicate a "Since" value which is the major and minor version in which it was introduced. The version of the specification implemented by the VM can be retrieved at runtime with the `GetVersionNumber` function.

Version Date | Changes
14 Nov 2002 | Converted to XML document.
14 Nov 2002 | Elided heap dump functions (for now) since what was there was wrong.
18 Nov 2002 | Added detail throughout.
18 Nov 2002 | Changed JVMTI_THREAD_STATUS_RUNNING to JVMTI_THREAD_STATUS_RUNNABLE.
19 Nov 2002 | Added AsyncGetStackTrace.
19 Nov 2002 | Added jframeID return to GetStackTrace.
19 Nov 2002 | Elided GetCurrentFrame and GetCallingFrame functions (for now) since what was there since they are redundant with GetStackTrace.
19 Nov 2002 | Elided ClearAllBreakpoints since it has always been redundant.
19 Nov 2002 | Added GetSystemProperties.
19 Nov 2002 | Changed the thread local storage functions to use jthread.
20 Nov 2002 | Added GetJLocationFormat.
22 Nov 2002 | Added events and introductory text.
22 Nov 2002 | Cross reference type and constant definitions.
24 Nov 2002 | Added DTD.
24 Nov 2002 | Added capabilities function section.
29 Nov 2002 | Assign capabilities to each function and event.
29 Nov 2002 | Add JNI interception functions.
30 Nov 2002 | Auto generate SetEventNotificationMode capabilities.
30 Nov 2002 | Add `VMObjectAlloc` event.
30 Nov 2002 | Add `DynamicCodeGenerated` event.
30 Nov 2002 | Add const to declarations.
30 Nov 2002 | Change method exit and frame pop to send on exception.
1 Dec 2002 | Add ForceGarbageCollection.
2 Dec 2002 | Redo Xrun section; clarify GetStackTrace and add example; Fix width problems; use "agent" consistently.
8 Dec 2002 | Remove previous start-up intro. Add JVM TI Environments section.
8 Dec 2002 | Add `DisposeEnvironment`.
9 Dec 2002 | Numerous minor updates.
15 Dec 2002 | Add heap profiling functions added: get/set annotation, iterate live objects/heap. Add heap profiling functions place holder added: heap roots. Heap profiling event added: object free. Heap profiling event redesigned: vm object allocation. Heap profiling event placeholders added: garbage collection start/finish. Native method bind event added.
19 Dec 2002 | Revamp suspend/resume functions. Add origin information with jvmdi tag. Misc fixes.
24 Dec 2002 | Add semantics to types.
27 Dec 2002 | Add local reference section. Autogenerate parameter descriptions from types.
28 Dec 2002 | Document that RunAgentThread sends threadStart.
29 Dec 2002 | Remove redundant local ref and dealloc warning. Convert GetRawMonitorName to allocated buffer. Add GenerateEvents.
30 Dec 2002 | Make raw monitors a type and rename to "jrawMonitorID".
1 Jan 2003 | Include origin information. Clean-up JVMDI issue references. Remove Deallocate warnings which are now automatically generated.
2 Jan 2003 | Fix representation issues for jthread.
3 Jan 2003 | Make capabilities buffered out to 64 bits - and do it automatically.
4 Jan 2003 | Make constants which are enumeration into enum types. Parameters now of enum type. Clean-up and index type section. Replace remaining datadef entities with callback.
7 Jan 2003 | Correct GenerateEvents description. More internal semantics work.
9 Jan 2003 | Replace previous GetSystemProperties with two functions which use allocated information instead fixed. Add SetSystemProperty. More internal semantics work.
12 Jan 2003 | Add varargs to end of SetEventNotificationMode.
20 Jan 2003 | Finish fixing spec to reflect that alloc sizes are jlong.
22 Jan 2003 | Allow NULL as RunAgentThread arg.
22 Jan 2003 | Fixed names to standardized naming convention Removed AsyncGetStackTrace.
29 Jan 2003 | Since we are using jthread, removed GetThread.
31 Jan 2003 | Change GetFieldName to allow NULLs like GetMethodName.
v40 29 Feb 2003 | Rewrite the introductory text, adding sections on start-up, environments and bytecode instrumentation. Change the command line arguments per EG discussions. Add an introduction to the capabilities section. Add the extension mechanism category and functions. Mark for deletion, but clarified anyhow, SuspendAllThreads. Rename IterateOverLiveObjects to IterateOverReachableObjects and change the text accordingly. Clarify IterateOverHeap. Clarify CompiledMethodLoad. Discuss prerequisite state for Calling Functions. Clarify SetAllocationHooks. Added issues ("To be resolved:") through-out. And so on...
v41 6 Mar 2003 | Remove struct from the call to GetOwnedMonitorInfo. Automatically generate most error documentation, remove (rather broken) hand written error doc. Better describe capability use (empty initial set). Add min value to jint params. Remove the capability can_access_thread_local_storage. Rename error JVMTI_ERROR_NOT_IMPLEMENTED to JVMTI_ERROR_MUST_POSSESS_CAPABILITY; same for *NOT_IMPLEMENTED. Description fixes.
v42 8 Mar 2003 | Rename GetClassSignature to GetClassName. Rename IterateOverClassObjects to IterateOverInstancesOfClass. Remove GetMaxStack (operand stack isn't used in JVM TI). Description fixes: define launch-time, remove native frame pop from PopFrame, and assorted clarifications.
v43 8 Mar 2003 | Fix minor editing problem.
v44 10 Mar 2003 | Add phase information. Remap (compact) event numbers.
v45 11 Mar 2003 | More phase information - allow "any". Elide raw monitor queries and events. Minor description fixes.
v46 12 Mar 2003 | Add GetPhase. Use "phase" through document. Elide GetRawMonitorName. Elide GetObjectMonitors.
v47 12 Mar 2003 | Fixes from link, XML, and spell checking. Auto-generate the callback structure.
v48 13 Mar 2003 | One character XML fix.
v49 13 Mar 2003 | Change function parameter names to be consistent with event parameters (fooBarBaz becomes foo_bar_baz).
v50 14 Mar 2003 | Fix broken link. Fix thread markers.
v51 14 Mar 2003 | Change constants so they are under 128 to workaround compiler problems.
v52 23 Mar 2003 | Overhaul capabilities. Separate GetStackTrace into GetStackTrace and GetStackFrames.
v54 8 Apr 2003 | Use depth instead of jframeID to reference frames. Remove the now irrelevant GetCurrentFrame, GetCallerFrame and GetStackFrames. Remove frame arg from events.
v55 9 Apr 2003 | Remove GetObjectWithAnnotation since tests show bufferred approach more efficient. Add missing annotation_count to GetObjectsWithAnnotations
v56 10 Apr 2003 | Remove confusing parenthetical statement in GetObjectsWithAnnotations
v58 13 Apr 2003 | Replace jclass/jmethodID representation of method with simply jmethodID; Pass JvmtiEnv* as first arg of every event; remove JNIEnv* where inappropriate. Replace can_access_frames with can_access_local_variables; remove from purely stack access. Use can_get_synthetic_attribute; fix description. Clarify that zero length arrays must be deallocated. Clarify RelinquishCapabilities. Generalize JVMTI_ERROR_VM_DEAD to JVMTI_ERROR_WRONG_PHASE.
v59 27 Apr 2003 | Remove lingering indirect references to OBSOLETE_METHOD_ID.
v60 4 May 2003 | Allow DestroyRawMonitor during OnLoad.
v61 7 May 2003 | Added not monitor owner error return to DestroyRawMonitor.
v62 13 May 2003 | Clarify semantics of raw monitors. Change flags on `GetThreadStatus`. `GetClassLoader` return NULL for the bootstrap class loader. Add `GetClassName` issue. Define local variable signature. Disallow zero in annotations array of `GetObjectsWithAnnotations`. Remove over specification in `GetObjectsWithAnnotations`. Elide `SetAllocationHooks`. Elide `SuspendAllThreads`.
v63 14 May 2003 | Define the data type `jvmtiEventCallbacks`. Zero length allocations return NULL. Keep SetAllocationHooks in JVMDI, but remove from JVM TI. Add JVMTI_THREAD_STATUS_FLAG_INTERRUPTED.
v64 15 May 2003 | Better wording, per review.
v65 15 May 2003 | First Alpha. Make jmethodID and jfieldID unique, jclass not used.
v66 27 May 2003 | Fix minor XSLT errors.
v67 13 June 2003 | Undo making jfieldID unique (jmethodID still is).
v68 17 June 2003 | Changes per June 11th Expert Group meeting -- Overhaul Heap functionality: single callback, remove GetHeapRoots, add reachable iterators, and rename "annotation" to "tag". NULL thread parameter on most functions is current thread. Add timers. Remove ForceExit. Add GetEnvironmentLocalStorage. Add verbose flag and event. Add AddToBootstrapClassLoaderSearch. Update ClassFileLoadHook.
v69 18 June 2003 | Clean up issues sections. Rename GetClassName back to GetClassSignature and fix description. Add generic signature to GetClassSignature, GetFieldSignature, GetMethodSignature, and GetLocalVariableTable. Elide EstimateCostOfCapabilities. Clarify that the system property functions operate on the VM view of system properties. Clarify Agent_OnLoad. Remove "const" from JNIEnv* in events. Add metadata accessors.
v70 18 June 2003 | Add start_depth to GetStackTrace. Move system properties to a new category. Add GetObjectSize. Remove "X" from command line flags. XML, HTML, and spell check corrections.
v71 19 June 2003 | Fix JVMTI_HEAP_ROOT_THREAD to be 6. Make each synopsis match the function name. Fix unclear wording.
v72 26 June 2003 | SetThreadLocalStorage and SetEnvironmentLocalStorage should allow value to be set to NULL. NotifyFramePop, GetFrameLocationm and all the local variable operations needed to have their wording about frames fixed. Grammar and clarity need to be fixed throughout. Capitalization and puntuation need to be consistent. Need micro version number and masks for accessing major, minor, and micro. The error code lists should indicate which must be returned by an implementation. The command line properties should be visible in the properties functions. Disallow popping from the current thread. Allow implementations to return opaque frame error when they cannot pop. The NativeMethodBind event should be sent during any phase. The DynamicCodeGenerated event should be sent during any phase. The following functions should be allowed to operate before VMInit: Set/GetEnvironmentLocalStorage GetMethodDeclaringClass GetClassSignature GetClassModifiers IsInterface IsArrayClass GetMethodName GetMethodModifiers GetMaxLocals GetArgumentsSize GetLineNumberTable GetMethodLocation IsMethodNative IsMethodSynthetic. Other changes (to XSL): Argument description should show asterisk after not before pointers. NotifyFramePop, GetFrameLocationm and all the local variable operations should hsve the NO_MORE_FRAMES error added. Not alive threads should have a different error return than invalid thread.
v73 7 July 2003 | VerboseOutput event was missing message parameter. Minor fix-ups.
v74 14 July 2003 | Technical Publications Department corrections. Allow thread and environment local storage to be set to NULL.
v75 23 July 2003 | Use new Agent_OnLoad rather than overloaded JVM_OnLoad. Add JNICALL to callbacks (XSL). Document JNICALL requirement for both events and callbacks (XSL). Restrict RedefineClasses to methods and attributes. Elide the VerboseOutput event. VMObjectAlloc: restrict when event is sent and remove method parameter. Finish loose ends from Tech Pubs edit.
v76 24 July 2003 | Change ClassFileLoadHook event to send the class instead of a boolean of redefine.
v77 24 July 2003 | XML fixes. Minor text clarifications and corrections.
v78 24 July 2003 | Remove GetExceptionHandlerTable and GetThrownExceptions from JVM TI. Clarify that stack frames are JVM Spec frames. Split can_get_source_info into can_get_source_file_name, can_get_line_numbers, and can_get_source_debug_extension. PopFrame cannot have a native calling method. Removed incorrect statement in GetClassloaderClasses (see http://java.sun.com/docs/books/vmspec/2nd-edition/html/ConstantPool.doc.html#79383).
v79 24 July 2003 | XML and text fixes. Move stack frame description into Stack Frame category.
v80 26 July 2003 | Allow NULL (means bootstrap loader) for GetClassloaderClasses. Add new heap reference kinds for references from classes. Add timer information struct and query functions. Add AvailableProcessors. Rename GetOtherThreadCpuTime to GetThreadCpuTime. Explicitly add JVMTI_ERROR_INVALID_THREAD and JVMTI_ERROR_THREAD_NOT_ALIVE to SetEventNotification mode. Add initial thread to the VM_INIT event. Remove platform assumptions from AddToBootstrapClassLoaderSearch.
v81 26 July 2003 | Grammar and clarity changes per review.
v82 27 July 2003 | More grammar and clarity changes per review. Add Agent_OnUnload.
v83 28 July 2003 | Change return type of Agent_OnUnload to void.
v84 28 July 2003 | Rename JVMTI_REFERENCE_ARRAY to JVMTI_REFERENCE_ARRAY_ELEMENT.
v85 28 July 2003 | Steal java.lang.Runtime.availableProcessors() wording for AvailableProcessors(). Guarantee that zero will never be an event ID. Remove some issues which are no longer issues. Per review, rename and more completely document the timer information functions.
v86 29 July 2003 | Non-spec visible change to XML controlled implementation: SetThreadLocalStorage must run in VM mode.
0.1.87 5 August 2003 | Add GetErrorName. Add varargs warning to jvmtiExtensionEvent. Remove "const" on the jvmtiEnv* of jvmtiExtensionEvent. Remove unused can_get_exception_info capability. Pass jvmtiEnv* and JNIEnv* to the jvmtiStartFunction. Fix jvmtiExtensionFunctionInfo.func declared type. Extension function returns error code. Use new version numbering.
0.2.88 5 August 2003 | Remove the ClassUnload event.
0.2.89 8 August 2003 | Heap reference iterator callbacks return an enum that allows outgoing object references to be ignored. Allow JNIEnv as a param type to extension events/functions.
0.2.90 15 August 2003 | Fix a typo.
0.2.91 2 September 2003 | Remove all metadata functions: GetClassMetadata, GetFieldMetadata, and GetMethodMetadata.
0.2.92 1 October 2003 | Mark the functions Allocate. Deallocate, RawMonitor*, SetEnvironmentLocalStorage, and GetEnvironmentLocalStorage as safe for use in heap callbacks and GC events.
0.2.93 24 November 2003 | Add pass through opaque user data pointer to heap iterate functions and callbacks. In the CompiledMethodUnload event, send the code address. Add GarbageCollectionOccurred event. Add constant pool reference kind. Mark the functions CreateRawMonitor and DestroyRawMonitor as safe for use in heap callbacks and GC events. Clarify: VMDeath, GetCurrentThreadCpuTimerInfo, GetThreadCpuTimerInfo, IterateOverReachableObjects, IterateOverObjectsReachableFromObject, GetTime and JVMTI_ERROR_NULL_POINTER. Add missing errors to: GenerateEvents and AddToBootstrapClassLoaderSearch. Fix description of ClassFileLoadHook name parameter. In heap callbacks and GC/ObjectFree events, specify that only explicitly allowed functions can be called. Allow GetCurrentThreadCpuTimerInfo, GetCurrentThreadCpuTime, GetTimerInfo, and GetTime during callback. Allow calling SetTag/GetTag during the onload phase. SetEventNotificationMode, add: error attempted inappropriate thread level control. Remove jvmtiExceptionHandlerEntry. Fix handling of native methods on the stack -- location_ptr param of GetFrameLocation, remove JVMTI_ERROR_OPAQUE_FRAME from GetFrameLocation, jvmtiFrameInfo.location, and jlocation. Remove typo (from JVMPI) implying that the MonitorWaited event is sent on sleep.
0.2.94 25 November 2003 | Clarifications and typos.
0.2.95 3 December 2003 | Allow NULL user_data in heap iterators.
0.2.97 28 January 2004 | Add GetThreadState, deprecate GetThreadStatus.
0.2.98 29 January 2004 | INVALID_SLOT and TYPE_MISMATCH errors should be optional.
0.2.102 12 February 2004 | Remove MonitorContendedExit. Added JNIEnv parameter to VMObjectAlloc. Clarified definition of class_tag and referrer_index parameters to heap callbacks.
0.2.103 16 Febuary 2004 | Document JAVA_TOOL_OPTIONS.
0.2.105 17 Febuary 2004 | Divide start phase into primordial and start. Add VMStart event Change phase associations of functions and events.
0.3.6 18 Febuary 2004 | Elide deprecated GetThreadStatus. Bump minor version, subtract 100 from micro version
0.3.7 18 Febuary 2004 | Document that timer nanosecond values are unsigned. Clarify text having to do with native methods.
0.3.8 19 Febuary 2004 | Fix typos. Remove elided deprecated GetThreadStatus.
0.3.9 23 Febuary 2004 | Require NotifyFramePop to act on suspended threads.
0.3.10 24 Febuary 2004 | Add capabilities (`can_redefine_any_class` and `can_generate_all_class_hook_events`) and an error (`JVMTI_ERROR_UNMODIFIABLE_CLASS`) which allow some classes to be unmodifiable.
0.3.11 28 Febuary 2004 | Add JVMTI_ERROR_MUST_POSSESS_CAPABILITY to SetEventNotificationMode.
0.3.12 8 March 2004 | Clarified CompiledMethodUnload so that it is clear the event may be posted after the class has been unloaded.
0.3.13 5 March 2004 | Change the size parameter of VMObjectAlloc to jlong to match GetObjectSize.
0.3.14 13 March 2004 | Added guideline for the use of the JNI FindClass function in event callback functions.
0.3.15 15 March 2004 | Add GetAllStackTraces and GetThreadListStackTraces.
0.3.16 19 March 2004 | ClassLoad and ClassPrepare events can be posted during start phase.
0.3.17 25 March 2004 | Add JVMTI_ERROR_NATIVE_METHOD to GetLineNumberTable, GetLocalVariableTable, GetMaxLocals, GetArgumentsSize, GetMethodLocation, GetBytecodes.
0.3.18 29 March 2004 | Return the timer kind in the timer information structure.
0.3.19 31 March 2004 | Spec clarifications: JVMTI_THREAD_STATE_IN_NATIVE might not include JNI or JVM TI. ForceGarbageCollection does not run finalizers. The context of the specification is the Java platform. Warn about early instrumentation.
0.3.20 1 April 2004 | Refinements to the above clarifications and Clarify that an error returned by Agent_OnLoad terminates the VM.
0.3.21 1 April 2004 | Array class creation does not generate a class load event.
0.3.22 7 April 2004 | Align thread state hierarchy more closely with java.lang.Thread.State.
0.3.23 12 April 2004 | Clarify the documentation of thread state.
0.3.24 19 April 2004 | Remove GarbageCollectionOccurred event -- can be done by agent.
0.3.25 22 April 2004 | Define "command-line option".
0.3.26 29 April 2004 | Describe the intended use of bytecode instrumentation. Fix description of extension event first parameter.
0.3.27 30 April 2004 | Clarification and typos.
0.3.28 18 May 2004 | Remove DataDumpRequest event.
0.3.29 18 May 2004 | Clarify RawMonitorWait with zero timeout. Clarify thread state after RunAgentThread.
0.3.30 24 May 2004 | Clean-up: fix bad/old links, etc.
0.3.31 30 May 2004 | Clarifications including: All character strings are modified UTF-8. Agent thread visibiity. Meaning of obsolete method version. Thread invoking heap callbacks,
1.0.32 1 June 2004 | Bump major.minor version numbers to "1.0".
1.0.33 2 June 2004 | Clarify interaction between ForceGarbageCollection and ObjectFree.
1.0.34 6 June 2004 | Restrict AddToBootstrapClassLoaderSearch and SetSystemProperty to the OnLoad phase only.
1.0.35 11 June 2004 | Fix typo in SetTag.
1.0.36 18 June 2004 | Fix trademarks. Add missing parameter in example GetThreadState usage.
1.0.37 4 August 2004 | Copyright updates.
1.0.38 5 November 2004 | Add missing function table layout. Add missing description of C++ member function format of functions. Clarify that name in CFLH can be NULL. Released as part of J2SETM 5.0.
1.1.47 24 April 2005 | Bump major.minor version numbers to "1.1". Add ForceEarlyReturn* functions. Add GetOwnedMonitorStackDepthInfo function. Add GetCurrentThread function. Add "since" version marker. Add AddToSystemClassLoaderSearch. Allow AddToBootstrapClassLoaderSearch be used in live phase. Fix historic rubbish in the descriptions of the heap_object_callback parameter of IterateOverHeap and IterateOverInstancesOfClass functions; disallow NULL for this parameter. Clarify, correct and make consistent: wording about current thread, opaque frames and insufficient number of frames in PopFrame. Consistently use "current frame" rather than "topmost". Clarify the JVMTI_ERROR_TYPE_MISMATCH errors in GetLocal* and SetLocal* by making them compatible with those in ForceEarlyReturn*. Many other clarifications and wording clean ups.
1.1.48 25 April 2005 | Add GetConstantPool. Switch references to the first edition of the VM Spec, to the seconds edition.
1.1.49 26 April 2005 | Clarify minor/major version order in GetConstantPool.
1.1.50 26 April 2005 | Add SetNativeMethodPrefix and SetNativeMethodPrefixes. Reassign GetOwnedMonitorStackDepthInfo to position 153. Break out Class Loader Search in its own documentation category. Deal with overly long lines in XML source.
1.1.51 29 April 2005 | Allow agents be started in the live phase. Added paragraph about deploying agents.
1.1.52 30 April 2005 | Add specification description to SetNativeMethodPrefix(es). Better define the conditions on GetConstantPool.
1.1.53 30 April 2005 | Break out the GetClassVersionNumber function from GetConstantPool. Clean-up the references to the VM Spec.
1.1.54 1 May 2005 | Allow SetNativeMethodPrefix(es) in any phase. Add clarifications about the impact of redefinition on GetConstantPool.
1.1.56 2 May 2005 | Various clarifications to SetNativeMethodPrefix(es).
1.1.57 2 May 2005 | Add missing performance warning to the method entry event.
1.1.58 5 May 2005 | Remove internal JVMDI support.
1.1.59 8 May 2005 | Add `RetransformClasses`. Revamp the bytecode instrumentation documentation. Change `IsMethodObsolete` to no longer require the can_redefine_classes capability.
1.1.63 11 May 2005 | Clarifications for retransformation.
1.1.64 11 May 2005 | Clarifications for retransformation, per review. Lock "retransformation (in)capable" at class load enable time.
1.1.67 4 June 2005 | Add new heap functionity which supports reporting primitive values, allows setting the referrer tag, and has more powerful filtering: FollowReferences, IterateThroughHeap, and their associated callbacks, structs, enums, and constants.
1.1.68 4 June 2005 | Clarification.
1.1.69 6 June 2005 | FollowReferences, IterateThroughHeap: Put callbacks in a struct; Add missing error codes; reduce bits in the visit control flags.
1.1.70 14 June 2005 | More on new heap functionity: spec clean-up per review.
1.1.71 15 June 2005 | More on new heap functionity: Rename old heap section to Heap (1.0).
1.1.72 21 June 2005 | Fix typos.
1.1.73 27 June 2005 | Make referrer info structure a union.
1.1.74 9 September 2005 | In new heap functions: Add missing superclass reference kind. Use a single scheme for computing field indexes. Remove outdated references to struct based referrer info.
1.1.75 12 September 2005 | Don't callback during FollowReferences on frivolous java.lang.Object superclass.
1.1.76 13 September 2005 | In string primitive callback, length now Unicode length. In array and string primitive callbacks, value now "const". Note possible compiler impacts on setting JNI function table.
1.1.77 13 September 2005 | GetClassVersionNumbers() and GetConstantPool() should return error on array or primitive class.
1.1.78 14 September 2005 | Grammar fixes.
1.1.79 26 September 2005 | Add IsModifiableClass query.
1.1.81 9 February 2006 | Add referrer_class_tag parameter to jvmtiHeapReferenceCallback.
1.1.82 13 February 2006 | Doc fixes: update can_redefine_any_class to include retransform. Clarify that exception events cover all Throwables. In GetStackTrace, no test is done for start_depth too big if start_depth is zero, Clarify fields reported in Primitive Field Callback -- static vs instance. Repair confusing names of heap types, including callback names. Require consistent usage of stack depth in the face of thread launch methods. Note incompatibility of JVM TI memory management with other systems.
1.1.85 14 February 2006 | Fix typos and missing renames.
1.1.86 13 March 2006 | Clarify that jmethodIDs and jfieldIDs can be saved. Clarify that Iterate Over Instances Of Class includes subclasses.
1.1.87 14 March 2006 | Better phrasing.
1.1.88 16 March 2006 | Match the referrer_index for static fields in Object Reference Callback with the Reference Implementation (and all other known implementations); that is, make it match the definition for instance fields. In GetThreadListStackTraces, add JVMTI_ERROR_INVALID_THREAD to cover an invalid thread in the list; and specify that not started threads return empty stacks.
1.1.89 17 March 2006 | Typo.
1.1.90 25 March 2006 | Typo.
1.1.91 6 April 2006 | Remove restrictions on AddToBootstrapClassLoaderSearch and AddToSystemClassLoaderSearch.
1.1.93 1 May 2006 | Changed spec to return -1 for monitor stack depth for the implementation which can not determine stack depth.
1.1.94 3 May 2006 | Corrections for readability and accuracy courtesy of Alan Pratt of IBM. List the object relationships reported in FollowReferences.
1.1.95 5 May 2006 | Clarify the object relationships reported in FollowReferences.
1.1.98 28 June 2006 | Clarify DisposeEnvironment; add warning. Fix typos in SetLocalXXX "retrieve" => "set". Clarify that native method prefixes must remain set while used. Clarify that exactly one Agent_OnXXX is called per agent. Clarify that library loading is independent from start-up. Remove ambiguous reference to Agent_OnLoad in the Agent_OnUnload spec.
1.1.99 31 July 2006 | Clarify the interaction between functions and exceptions. Clarify and give examples of field indices. Remove confusing "That is" sentence from MonitorWait and MonitorWaited events. Update links to point to Java 6.
1.1.102 6 August 2006 | Add ResourceExhaustedEvent.