JDK14/Java14源码在线阅读

<?xml version="1.0" encoding="ISO-8859-1"?>
<?xml-stylesheet type="text/xsl" href="jvmti.xsl"?>
<!--
 Copyright (c) 2002, 2019, Oracle and/or its affiliates. All rights reserved.
 DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.

 This code is free software; you can redistribute it and/or modify it
 under the terms of the GNU General Public License version 2 only, as
 published by the Free Software Foundation.

 This code is distributed in the hope that it will be useful, but WITHOUT
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 version 2 for more details (a copy is included in the LICENSE file that
 accompanied this code).

 You should have received a copy of the GNU General Public License version
 2 along with this work; if not, write to the Free Software Foundation,
 Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.

 Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 or visit www.oracle.com if you need additional information or have any
 questions.
-->

<!DOCTYPE specification [
   <!ELEMENT specification (title, intro*, functionsection, errorsection,
                            eventsection, datasection, issuessection, changehistory)>
   <!ATTLIST specification label CDATA #REQUIRED>

   <!ELEMENT title (#PCDATA|jvmti|tm)*>
   <!ATTLIST title subtitle CDATA #REQUIRED>

   <!ELEMENT intro ANY>
   <!ATTLIST intro id CDATA #IMPLIED
                   label CDATA "">

   <!ELEMENT functionsection (intro*, category*)>
   <!ATTLIST functionsection label CDATA #REQUIRED>

   <!ELEMENT category ((intro|typedef|uniontypedef|capabilitiestypedef)*,
                          (function|callback|elide)*)>
   <!ATTLIST category id CDATA #REQUIRED
                      label CDATA #REQUIRED>

   <!ELEMENT function (synopsis, typedef*, description?, origin,
                         (capabilities|eventcapabilities),
                         parameters, errors)>
   <!ATTLIST function id CDATA #REQUIRED
                      num CDATA #REQUIRED
                      phase (onload|onloadOnly|start|live|any) #IMPLIED
                      callbacksafe (safe|unsafe) #IMPLIED
                      impl CDATA #IMPLIED
                      hide CDATA #IMPLIED
                      jkernel (yes|no) #IMPLIED
                      since CDATA "1.0">

   <!ELEMENT callback ((jmethodID|jfieldID|jframeID|jrawMonitorID|jclass|jthread|jthreadGroup|jobject|
                        jvalue|enum|jint|jlong|jfloat|jdouble|jlocation|jboolean|char|uchar|size_t|void),
                        synopsis, description?, parameters)>
   <!ATTLIST callback id CDATA #REQUIRED
                      since CDATA "1.0">

   <!ELEMENT synopsis (#PCDATA|jvmti)*>

   <!ELEMENT typedef (description?, field*)>
   <!ATTLIST typedef id CDATA #REQUIRED
                     label CDATA #REQUIRED
                     since CDATA "1.0">

   <!ELEMENT uniontypedef (description?, field*)>
   <!ATTLIST uniontypedef id CDATA #REQUIRED
                     label CDATA #REQUIRED
                     since CDATA "1.0">

   <!ELEMENT field ((jmethodID|jfieldID|jframeID|jrawMonitorID|jclass|jthread|jthreadGroup|jobject|
                     jvalue|enum|jint|jlong|jfloat|jdouble|jlocation|jboolean|char|uchar|size_t|void|allocfieldbuf|inptr|inbuf|outbuf|vmbuf|ptrtype|struct),
                    description)>
   <!ATTLIST field id CDATA #REQUIRED>

   <!ELEMENT capabilitiestypedef (description?, capabilityfield*)>
   <!ATTLIST capabilitiestypedef id CDATA #REQUIRED
                     label CDATA #REQUIRED>

   <!ELEMENT capabilityfield (description)>
   <!ATTLIST capabilityfield id CDATA #REQUIRED
                   disp1 CDATA ""
                   disp2 CDATA ""
                   since CDATA "1.0">

   <!ELEMENT description ANY>

   <!ELEMENT capabilities (required*, capability*)>

   <!ELEMENT eventcapabilities EMPTY>

   <!ELEMENT required ANY>
   <!ATTLIST required id CDATA #REQUIRED>

   <!ELEMENT capability ANY>
   <!ATTLIST capability id CDATA #REQUIRED>

   <!ELEMENT parameters (param*)>

   <!ELEMENT param ((jmethodID|jfieldID|jframeID|jrawMonitorID|jclass|jthread|jthreadGroup|jobject|
                     jvalue|enum|jint|jlong|jfloat|jdouble|jlocation|jboolean|char|uchar|size_t|void|varargs|struct|ptrtype|
                     outptr|allocbuf|allocallocbuf|inptr|inbuf|outbuf|vmbuf|agentbuf),
                    description)>
   <!ATTLIST param id CDATA #REQUIRED>

   <!ELEMENT jmethodID EMPTY>
   <!ATTLIST jmethodID class  CDATA #IMPLIED
                       native CDATA #IMPLIED>

   <!ELEMENT jfieldID EMPTY>
   <!ATTLIST jfieldID class CDATA #IMPLIED>

   <!ELEMENT jclass EMPTY>
   <!ATTLIST jclass method CDATA #IMPLIED
                    field  CDATA #IMPLIED>

   <!ELEMENT jframeID EMPTY>
   <!ATTLIST jframeID thread CDATA #IMPLIED>

   <!ELEMENT jrawMonitorID EMPTY>

   <!ELEMENT jthread EMPTY>
   <!ATTLIST jthread started CDATA #IMPLIED
                     null CDATA #IMPLIED
                     frame CDATA #IMPLIED
                     impl CDATA #IMPLIED>

   <!ELEMENT varargs EMPTY>

   <!ELEMENT jthreadGroup EMPTY>
   <!ELEMENT jobject EMPTY>
   <!ELEMENT jvalue EMPTY>
   <!ELEMENT jchar EMPTY>
   <!ELEMENT jint EMPTY>
   <!ATTLIST jint min CDATA #IMPLIED>
   <!ELEMENT jlong EMPTY>
   <!ELEMENT jfloat EMPTY>
   <!ELEMENT jdouble EMPTY>
   <!ELEMENT jlocation EMPTY>
   <!ELEMENT jboolean EMPTY>
   <!ELEMENT char EMPTY>
   <!ELEMENT uchar EMPTY>
   <!ELEMENT size_t EMPTY>
   <!ELEMENT void EMPTY>
   <!ELEMENT enum (#PCDATA)*>
   <!ELEMENT struct (#PCDATA)*>

   <!ELEMENT nullok ANY>

   <!ELEMENT ptrtype     ((struct|jmethodID|jfieldID|jframeID|jrawMonitorID|jclass|jthread|
                                   jthreadGroup|jobject|jvalue), nullok?)>

   <!ELEMENT outptr     ((struct|jmethodID|jfieldID|jframeID|jrawMonitorID|jclass|jthread|
                                   jthreadGroup|jobject|jvalue|enum|jchar|jint|jlong|jfloat|jdouble|
                                   jlocation|jboolean|char|uchar|size_t|void), nullok?)>

   <!ELEMENT allocbuf   ((struct|jmethodID|jfieldID|jframeID|jrawMonitorID|jclass|jthread|
                                   jthreadGroup|jobject|jvalue|enum|jint|jlong|jfloat|jdouble|
                                   jlocation|jboolean|char|uchar|size_t|void), nullok?)>
   <!ATTLIST allocbuf incount CDATA #IMPLIED
                      outcount CDATA #IMPLIED>

   <!ELEMENT allocallocbuf   ((struct|jmethodID|jfieldID|jframeID|jrawMonitorID|jclass|jthread|
                                   jthreadGroup|jobject|jvalue|enum|jint|jlong|jfloat|jdouble|
                                   jlocation|jboolean|char|uchar|size_t|void), nullok?)>
   <!ATTLIST allocallocbuf incount CDATA #IMPLIED
                      outcount CDATA #IMPLIED>

   <!ELEMENT inptr      (struct, nullok?)>

   <!ELEMENT inbuf      ((struct|jmethodID|jfieldID|jframeID|jrawMonitorID|jclass|jthread|
                                   jthreadGroup|jobject|jvalue|enum|jint|jlong|jfloat|jdouble|
                                   jlocation|jboolean|char|uchar|size_t|void), nullok?)>
   <!ATTLIST inbuf    incount CDATA #IMPLIED>

   <!ELEMENT outbuf     ((struct|jmethodID|jfieldID|jframeID|jrawMonitorID|jclass|jthread|
                                   jthreadGroup|jobject|jvalue|enum|jint|jlong|jfloat|jdouble|
                                   jlocation|jboolean|char|uchar|size_t|void|outbuf), nullok?)>
   <!ATTLIST outbuf   incount CDATA #IMPLIED
                      outcount CDATA #IMPLIED>

   <!ELEMENT vmbuf      ((struct|jmethodID|jfieldID|jframeID|jrawMonitorID|jclass|jthread|
                                   jthreadGroup|jobject|jvalue|enum|jchar|jint|jlong|jfloat|jdouble|
                                   jlocation|jboolean|char|uchar|size_t|void), nullok?)>
   <!ATTLIST vmbuf    incount CDATA #IMPLIED
                      outcount CDATA #IMPLIED>

   <!ELEMENT agentbuf   ((struct|jmethodID|jfieldID|jframeID|jrawMonitorID|jclass|jthread|
                                   jthreadGroup|jobject|jvalue|enum|jint|jlong|jfloat|jdouble|
                                   jlocation|jboolean|char|uchar|size_t|void), nullok?)>
   <!ATTLIST agentbuf incount CDATA #IMPLIED
                      outcount CDATA #IMPLIED>

   <!ELEMENT allocfieldbuf   ((struct|jmethodID|jfieldID|jframeID|jrawMonitorID|jclass|jthread|
                                   jthreadGroup|jobject|jvalue|enum|jint|jlong|jfloat|jdouble|
                                   jlocation|jboolean|char|uchar|size_t|void))>
   <!ATTLIST allocfieldbuf outcount CDATA #IMPLIED>

   <!ELEMENT errors (error*)>

   <!ELEMENT error ANY>
   <!ATTLIST error id CDATA #REQUIRED>

   <!ELEMENT errorsection (intro*, errorcategory*)>
   <!ATTLIST errorsection label CDATA #REQUIRED>

   <!ELEMENT errorcategory (intro*, errorid*)>
   <!ATTLIST errorcategory id CDATA #REQUIRED
                           label CDATA #REQUIRED>

   <!ELEMENT errorid ANY>
   <!ATTLIST errorid id CDATA #REQUIRED
                     num CDATA #REQUIRED>

   <!ELEMENT datasection (intro*, basetypes*)>

   <!ELEMENT basetypes (intro*, basetype*)>
   <!ATTLIST basetypes id CDATA #REQUIRED
                       label CDATA #REQUIRED>

   <!ELEMENT basetype (definition?,description)>
   <!ATTLIST basetype id CDATA #REQUIRED
                      name CDATA #IMPLIED>

   <!ELEMENT definition (#PCDATA|jvmti)*>

   <!ELEMENT eventsection (intro*, (event|elide)*)>
   <!ATTLIST eventsection label CDATA #REQUIRED>

   <!ELEMENT event (description, origin, typedef*, capabilities, parameters)>
   <!ATTLIST event id CDATA #REQUIRED
                   label CDATA #REQUIRED
                   const CDATA #REQUIRED
                   num CDATA #REQUIRED
                   phase (onload|start|live|any) #IMPLIED
                   filtered (thread|global) #IMPLIED
                   since CDATA "1.0">

   <!ELEMENT issuessection (intro*)>
   <!ATTLIST issuessection label CDATA #REQUIRED>

   <!ELEMENT changehistory (intro*, change*)>
   <!ATTLIST changehistory update CDATA #REQUIRED
                           id CDATA #REQUIRED>

   <!ELEMENT change ANY>
   <!ATTLIST change date CDATA #REQUIRED
                    version CDATA #IMPLIED>

   <!ELEMENT functionlink (#PCDATA|jvmti|code|i|b)*>
   <!ATTLIST functionlink id CDATA #REQUIRED>

   <!ELEMENT datalink (#PCDATA|jvmti|code|i|b)*>
   <!ATTLIST datalink id CDATA #REQUIRED>

   <!ELEMENT typelink (#PCDATA|jvmti|code|i|b)*>
   <!ATTLIST typelink id CDATA #REQUIRED>

   <!ELEMENT fieldlink (#PCDATA|jvmti|code|i|b)*>
   <!ATTLIST fieldlink id CDATA #REQUIRED
                       struct CDATA #REQUIRED>

   <!ELEMENT paramlink (#PCDATA|jvmti|code|i|b)*>
   <!ATTLIST paramlink id CDATA #REQUIRED>

   <!ELEMENT eventlink (#PCDATA|jvmti|code|i|b)*>
   <!ATTLIST eventlink id CDATA #REQUIRED>

   <!ELEMENT errorlink (#PCDATA|jvmti|code|i|b|tm)*>
   <!ATTLIST errorlink id CDATA #REQUIRED>

   <!ELEMENT externallink (#PCDATA|jvmti|code|i|b|tm)*>
   <!ATTLIST externallink id CDATA #REQUIRED>

   <!ELEMENT vmspec EMPTY>
   <!ATTLIST vmspec chapter CDATA #IMPLIED>

   <!ELEMENT internallink (#PCDATA|jvmti|code|i|b)*>
   <!ATTLIST internallink id CDATA #REQUIRED>

   <!ELEMENT functionphaselist EMPTY>
   <!ATTLIST functionphaselist phase (onload|onloadOnly|start|live|any) #REQUIRED>

   <!ELEMENT eventphaselist EMPTY>
   <!ATTLIST eventphaselist phase (onload|start|live|any) #REQUIRED>

   <!ELEMENT issue ANY>

   <!ELEMENT rationale ANY>

   <!ELEMENT todo ANY>

   <!ELEMENT origin (#PCDATA)*>

   <!ELEMENT elide (intro|function|callback|event)*>
   <!ATTLIST elide why CDATA #IMPLIED>

   <!ELEMENT constants (constant*)>
   <!ATTLIST constants id CDATA #REQUIRED
                       label CDATA #REQUIRED
                       kind (enum|bits|const) #REQUIRED
                       since CDATA "1.0">

   <!ELEMENT constant ANY>
   <!ATTLIST constant id CDATA #REQUIRED
                      num CDATA #REQUIRED>

   <!ELEMENT tm (#PCDATA)>

   <!ELEMENT i (#PCDATA|jvmti|tm)*>

   <!ELEMENT b (#PCDATA|jvmti|code)*>

   <!ELEMENT code (#PCDATA|space)*>

   <!ELEMENT pre ANY>

   <!ELEMENT space EMPTY>

   <!ELEMENT jvmti EMPTY>

   <!ELEMENT example (#PCDATA|i)*>

   <!ELEMENT br EMPTY>

   <!ELEMENT p EMPTY>

   <!ELEMENT blockquote ANY>

   <!ELEMENT dl  (dt|dd)+>

   <!ELEMENT dd  ANY>

   <!ELEMENT dt  (#PCDATA|jvmti|code|i|b)*>

   <!ELEMENT table  (tr)+>

   <!ELEMENT tr  (td|th)*>
   <!ATTLIST tr class CDATA #IMPLIED>

   <!ELEMENT td  ANY>
   <!ATTLIST td class CDATA #IMPLIED>

   <!ELEMENT th  ANY>
   <!ATTLIST th class CDATA #IMPLIED
                scope (col|row) #IMPLIED>

   <!ELEMENT ul  (li)+>
   <!ATTLIST ul type (disc|circle|square) "disc">

   <!ELEMENT li  ANY>
 ]>

<specification label="JVM(TM) Tool Interface">
  <title subtitle="Version">
    <tm>JVM</tm> Tool Interface
  </title>

  <intro id="whatIs" label="What is the JVM Tool Interface?">
    The <tm>JVM</tm> Tool Interface (<jvmti/>)
    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
    <tm>Java</tm> virtual machine (VM).
    <p/>
    <jvmti/> 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.
    <p/>
    <jvmti/> may not be available in all implementations of the <tm>Java</tm> virtual
    machine.
    <p/>
    <jvmti/> is a two-way interface.
    A client of <jvmti/>, hereafter called an <i>agent</i>,
    can be notified of
    interesting occurrences through <internallink id="EventSection">events</internallink>.
    <jvmti/>
    can query and control the application through many
    <internallink id="FunctionSection">functions</internallink>,
    either in response to events or
    independent of them.
    <p/>
    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 (<jvmti/>). 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.
  </intro>

  <intro id="architecture" label="Architecture">
    Tools can be written directly to <jvmti/> or indirectly
    through higher level interfaces.
    The Java Platform Debugger Architecture includes <jvmti/>, but also
    contains higher-level, out-of-process debugger interfaces. The higher-level
    interfaces are more appropriate than <jvmti/> for many tools.
    For more information on the Java Platform Debugger Architecture,
    see the
    <externallink id="jpda/architecture.html">Java
      Platform Debugger Architecture website</externallink>.
  </intro>

  <intro id="writingAgents" label="Writing Agents">
    Agents can be written in any native language that supports C
    language calling conventions and C or C++
    definitions.
    <p/>
    The function, event, data type, and constant definitions needed for
    using <jvmti/> are defined in the include file <code>jvmti.h</code>.
    To use these definitions add the <tm>J2SE</tm> include directory
    to your include path and add
    <example>
#include &lt;jvmti.h&gt;
    </example>
    to your source code.
  </intro>

  <intro id="deployingAgents" label="Deploying Agents">
    An agent is deployed in a platform specific manner but is typically the
    platform equivalent of a dynamic library. On the <tm>Windows</tm> operating
    system, for example, an agent library is a "Dynamic Linked Library" (DLL).
    On the <tm>Solaris</tm> Operating Environment, an agent library is a shared
    object (<code>.so</code> file).
    <p/>

    An agent may be started at VM startup by specifying the agent library
    name using a <internallink id="starting">command line option</internallink>.
    Some implementations may support a mechanism to <internallink id="onattach">
    start agents</internallink> in the live <functionlink id="GetPhase">phase</functionlink>.
    The details of how this is initiated are implementation specific.
  </intro>

    <intro id="entryPoint" label="Statically Linked Agents (since version 1.2.3)">

      A native JVMTI Agent may be <i>statically linked</i> with the VM.
      The manner in which the library and VM image are combined is
      implementation-dependent.
      An agent L whose image has been combined with the VM is defined as
      <i>statically linked</i> if and only if the agent exports a function
      called Agent_OnLoad_L.
<p/>
      If a <i>statically linked</i> agent L exports a function called
      Agent_OnLoad_L and a function called Agent_OnLoad, the Agent_OnLoad
      function will be ignored.
      If an agent L is <i>statically linked</i>, an Agent_OnLoad_L
      function will be invoked with the same arguments and expected return
      value as specified for the Agent_OnLoad function.
      An agent L that is <i>statically linked</i> will prohibit an agent of
      the same name from being loaded dynamically.
<p/>
      The VM will invoke the Agent_OnUnload_L function of the agent, if such
      a function is exported, at the same point during VM execution as it would
      have called the dynamic entry point Agent_OnUnLoad. A statically loaded
      agent cannot be unloaded. The Agent_OnUnload_L function will still be
      called to do any other agent shutdown related tasks.
      If a <i>statically linked</i> agent L exports a function called
      Agent_OnUnLoad_L and a function called Agent_OnUnLoad, the Agent_OnUnLoad
      function will be ignored.
<p/>
      If an agent L is <i>statically linked</i>, an Agent_OnAttach_L function
      will be invoked with the same arguments and expected return value as
      specified for the Agent_OnAttach function.
      If a <i>statically linked</i> agent L exports a function called
      Agent_OnAttach_L and a function called Agent_OnAttach, the Agent_OnAttach
      function will be ignored.
</intro>

  <intro id="starting" label="Agent Command Line Options">
    The term "command-line option" is used below to
    mean options supplied in the <code>JavaVMInitArgs</code> argument
    to the <code>JNI_CreateJavaVM</code> function of the JNI
    Invocation API.
    <p/>
    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.
    <dl>
      <dt><code>-agentlib:</code><i>&lt;agent-lib-name&gt;</i><code>=</code><i>&lt;options&gt;</i></dt>
      <dd>
        The name following <code>-agentlib:</code> 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 <i>&lt;agent-lib-name&gt;</i> is expanded to an
        operating system specific file name.
        The <i>&lt;options&gt;</i> will be passed to the agent on start-up.
        For example, if the option
        <code>-agentlib:foo=opt1,opt2</code> is specified, the VM will attempt to
        load the shared library <code>foo.dll</code> from the system <code>PATH</code>
        under <tm>Windows</tm> or <code>libfoo.so</code> from the
        <code>LD_LIBRARY_PATH</code> under the <tm>Solaris</tm> operating
        environment.
        If the agent library is statically linked into the executable
        then no actual loading takes place.
    <p/>
      </dd>
      <dt><code>-agentpath:</code><i>&lt;path-to-agent&gt;</i><code>=</code><i>&lt;options&gt;</i></dt>
      <dd>
        The path following <code>-agentpath:</code> is the absolute path from which
        to load the library.
        No library name expansion will occur.
        The <i>&lt;options&gt;</i> will be passed to the agent on start-up.
        For example, if the option
        <code>-agentpath:c:\myLibs\foo.dll=opt1,opt2</code> is specified, the VM will attempt to
        load the shared library <code>c:\myLibs\foo.dll</code>. If the agent
        library is statically linked into the executable
        then no actual loading takes place.
    <p/>
      </dd>
    </dl>
    For a dynamic shared library agent, the start-up routine
    <internallink id="onload"><code>Agent_OnLoad</code></internallink>
    in the library will be invoked. If the agent library is statically linked
    into the executable then the system will attempt to invoke the
    <code>Agent_OnLoad_&lt;agent-lib-name&gt;</code> entry point where
    &lt;agent-lib-name&gt; is the basename of the
    agent. In the above example <code>-agentpath:c:\myLibs\foo.dll=opt1,opt2</code>,
    the system will attempt to find and call the <code>Agent_OnLoad_foo</code> start-up routine.
    <p/>
    Libraries loaded with <code>-agentlib:</code> or <code>-agentpath:</code>
    will be searched for JNI native method implementations to facilitate the
    use of Java programming language code in tools, as is needed for
    <internallink id="bci">bytecode instrumentation</internallink>.
    <p/>
    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
    <eventlink id="NativeMethodBind">NativeMethodBind event</eventlink>).
    <p/>
    These switches do the above and nothing more - they do not change the
    state of the VM or <jvmti/>.  No command line options are needed
    to enable <jvmti/>
    or aspects of <jvmti/>, this is handled programmatically
    by the use of
    <internallink id="capability">capabilities</internallink>.
  </intro>

  <intro id="startup" label="Agent Start-Up">
    The VM starts each agent by invoking a start-up function.
    If the agent is started in the <code>OnLoad</code>
    <functionlink id="GetPhase">phase</functionlink> the function
    <internallink id="onload"><code>Agent_OnLoad</code></internallink>
    or <internallink id="onload"><code>Agent_OnLoad_L</code></internallink>
    for statically linked agents will be invoked.
    If the agent is started in the live
    <functionlink id="GetPhase">phase</functionlink> the function
    <internallink id="onattach"><code>Agent_OnAttach</code></internallink>
    or <internallink id="onattach"><code>Agent_OnAttach_L</code></internallink>
    for statically linked agents will be invoked.
    Exactly one call to a start-up function is made per agent.
  </intro>

  <intro id="onload" label="Agent Start-Up (OnLoad phase)">
    If an agent is started during the <code>OnLoad</code> phase then its
    agent library must export a start-up function with the following prototype:
    <example>
JNIEXPORT jint JNICALL
Agent_OnLoad(JavaVM *vm, char *options, void *reserved)</example>
    Or for a statically linked agent named 'L':
    <example>
JNIEXPORT jint JNICALL
Agent_OnLoad_L(JavaVM *vm, char *options, void *reserved)</example>

    The VM will start the agent by calling this function.
    It will be called early enough in VM initialization that:
    <ul>
      <li><functionlink id="SetSystemProperty">system properties</functionlink>
        may be set before they have been used in the start-up of the VM</li>
      <li>the full set of
        <internallink id="capability">capabilities</internallink>
        is still available (note that capabilities that configure the VM
        may only be available at this time--see the
        <internallink id="capability">Capability function section</internallink>)</li>
      <li>no bytecodes have executed</li>
      <li>no classes have been loaded</li>
      <li>no objects have been created</li>
    </ul>
    <p/>
    The VM will call the <code>Agent_OnLoad</code> or
    <code>Agent_OnLoad_&lt;agent-lib-name&gt;</code> function with
    <i>&lt;options&gt;</i> as the second argument -
    that is, using the command-line option examples,
    <code>"opt1,opt2"</code> will be passed to the <code>char *options</code>
    argument of <code>Agent_OnLoad</code>.
    The <code>options</code> argument is encoded as a
    <internallink id="mUTF">modified UTF-8</internallink> string.
    If <i>=&lt;options&gt;</i> is not specified,
    a zero length string is passed to <code>options</code>.
    The lifespan of the <code>options</code> string is the
    <code>Agent_OnLoad</code> or <code>Agent_OnLoad_&lt;agent-lib-name&gt;</code>
    call.  If needed beyond this time the string or parts of the string must
    be copied.
    The period between when <code>Agent_OnLoad</code> is called and when it
    returns is called the <i>OnLoad phase</i>.
    Since the VM is not initialized during the OnLoad
    <functionlink id="GetPhase">phase</functionlink>,
    the set of allowed operations
    inside <code>Agent_OnLoad</code> 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 <functionlink id="SetEventCallbacks"></functionlink>. Once
    the VM initialization event is received
    (that is, the <eventlink id="VMInit">VMInit</eventlink>
    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.
    </rationale>
    <p/>
    The return value from <code>Agent_OnLoad</code> or
    <code>Agent_OnLoad_&lt;agent-lib-name&gt;</code> is used to indicate an error.
    Any value other than zero indicates an error and causes termination of the VM.
  </intro>

  <intro id="onattach" label="Agent Start-Up (Live phase)">
    A VM may support a mechanism that allows agents to be started in the VM during the live
    <functionlink id="GetPhase">phase</functionlink>. 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.
    <p/>
    If an agent is started during the live phase then its agent library
    must export a start-up function
    with the following prototype:
    <example>
JNIEXPORT jint JNICALL
Agent_OnAttach(JavaVM* vm, char *options, void *reserved)</example>
Or for a statically linked agent named 'L':
    <example>
JNIEXPORT jint JNICALL
Agent_OnAttach_L(JavaVM* vm, char *options, void *reserved)</example>

    <p/>
    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 <i>&lt;vm&gt;</i> is the Java VM.
    The <i>&lt;options&gt;</i> argument is the startup options provided to the agent.
    <i>&lt;options&gt;</i> is encoded as a <internallink id="mUTF">modified UTF-8
    </internallink> string.
    If startup options were not provided, a zero length string is passed to
    <code>options</code>. The lifespan of the <code>options</code> string is the
    <code>Agent_OnAttach</code> or <code>Agent_OnAttach_&lt;agent-lib-name&gt;</code> call.
    If needed beyond this time the string or parts of the string must be copied.
    <p/>
    Note that some <internallink id="capability">capabilities</internallink>
    may not be available in the live phase.
    <p/>
    The <code>Agent_OnAttach</code> or <code>Agent_OnAttach_&lt;agent-lib-name
    &gt;</code> 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.
  </intro>

  <intro id="onunload" label="Agent Shutdown">
    The library may optionally export a
    shutdown function with the following prototype:
    <example>
JNIEXPORT void JNICALL
Agent_OnUnload(JavaVM *vm)</example>
    Or for a statically linked agent named 'L':
    <example>
JNIEXPORT void JNICALL
Agent_OnUnload_L(JavaVM *vm)</example>

    This function will be called by the VM when the library is about to be unloaded.
    The library will be unloaded (unless it is statically linked into the
    executable) 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 course, an exception to this rule.
    Note the distinction between this function and the
    <eventlink id="VMDeath">VM Death event</eventlink>: for the VM Death event
    to be sent, the VM must have run at least to the point of initialization and a valid
    <jvmti/> environment must exist which has set a callback for VMDeath
    and enabled the event.
    None of these are required for <code>Agent_OnUnload</code> or
    <code>Agent_OnUnload_&lt;agent-lib-name&gt;</code> 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.
  </intro>

  <intro id="tooloptions" label="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 <code>JAVA_TOOL_OPTIONS</code> variable is
    provided so that agents may be launched in these cases.
    <p/>
    Platforms which support environment variables or other named strings, may support the
    <code>JAVA_TOOL_OPTIONS</code> 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:
    <ul>
        <li>All characters enclosed between a pair of single quote marks (''), except a single
        quote, are quoted.</li>
        <li>Double quote characters have no special meaning inside a pair of single quote marks.</li>
        <li>All characters enclosed between a pair of double quote marks (""), except a double
        quote, are quoted.</li>
        <li>Single quote characters have no special meaning inside a pair of double quote marks.</li>
        <li>A quoted part can start or end anywhere in the variable.</li>
        <li>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.</li>
        <li>The pair of quote marks is not included in the option.</li>
    </ul>
    <code>JNI_CreateJavaVM</code> (in the JNI Invocation API) will prepend these options to the options supplied
    in its <code>JavaVMInitArgs</code> 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.
  </intro>

  <intro id="environments" label="Environments">
    The <jvmti/> specification supports the use of multiple simultaneous
    <jvmti/> agents.
    Each agent has its own <jvmti/> environment.
    That is, the <jvmti/> state is
    separate for each agent - changes to one environment do not affect the
    others.  The state of a <jvmti/>
    environment includes:
    <ul>
      <li><functionlink id="SetEventCallbacks">the event callbacks</functionlink></li>
      <li><functionlink id="SetEventNotificationMode">the set of events which are enabled</functionlink></li>
      <li><internallink id="capability">the capabilities</internallink></li>
      <li><internallink id="memory">the memory allocation/deallocation hooks</internallink></li>
    </ul>
    Although their <jvmti/> 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.  <jvmti/> 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.
    <p/>
    An agent creates a <jvmti/> environment
    by passing a <jvmti/> version
    as the interface ID to the JNI Invocation API function
    <externallink id="jni/invocation.html#getenv">
      <code>GetEnv</code></externallink>.
    See <internallink id="jvmtiEnvAccess">Accessing <jvmti/> Functions</internallink>
    for more details on the creation and use of
    <jvmti/> environments.
    Typically, <jvmti/> environments are created by calling <code>GetEnv</code> from
    <internallink id="onload"><code>Agent_OnLoad</code></internallink>.
  </intro>

  <intro id="bci" label="Bytecode Instrumentation">
    This interface does not include some events that one might expect in an interface with
    profiling support.  Some examples include full speed
    method enter and exit events.  The interface instead provides support for
    <i>bytecode instrumentation</i>, 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 <code>MyProfiler.methodEntered()</code>.
    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.
    <p/>
    Instrumentation can be inserted in one of three ways:
    <ul>
      <li>
        Static Instrumentation: The class file is instrumented before it
        is loaded into the VM - for example, by creating a duplicate directory of
        <code>*.class</code> 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.
      </li>
      <li>
        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 <eventlink id="ClassFileLoadHook"/>
        event, triggered by the class load,
        provides this functionality.  This mechanism provides efficient
        and complete access to one-time instrumentation.
      </li>
      <li>
        Dynamic Instrumentation: A class which is already loaded (and possibly
        even running) is modified.  This optional feature is provided by the
        <eventlink id="ClassFileLoadHook"/> event, triggered by calling the
        <functionlink id="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.
      </li>
    </ul>
    <p/>
    The class modification functionality provided in this interface
    is intended to provide a mechanism for instrumentation
    (the <eventlink id="ClassFileLoadHook"/> event
    and the <functionlink id="RetransformClasses"/> function)
    and, during development, for fix-and-continue debugging
    (the <functionlink id="RedefineClasses"/> function).
    <p/>
    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
    <code>Object</code>.  Assuming that the constructor is initially
    empty, the constructor could be changed to:
    <example>
      public Object() {
        MyProfiler.allocationTracker(this);
      }
    </example>
    However, if this change was made using the
    <eventlink id="ClassFileLoadHook"/>
    event then this might impact a typical VM as follows:
    the first created object will call the constructor causing a class load of
    <code>MyProfiler</code>; which will then cause
    object creation, and since <code>MyProfiler</code> 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, <code>trackAllocations</code> could be set in the
    handler for the <code>VMInit</code> event.
    <example>
      static boolean trackAllocations = false;

      public Object() {
        if (trackAllocations) {
          MyProfiler.allocationTracker(this);
        }
      }
    </example>
    <p/>
    The <functionlink id="SetNativeMethodPrefix"/> allows native methods
    to be instrumented by the use of wrapper methods.
  </intro>

<intro id="bcimodules" label="Bytecode Instrumentation of code in modules">
  Agents can use the functions <functionlink id="AddModuleReads"/>,
  <functionlink id="AddModuleExports"/>, <functionlink id="AddModuleOpens"/>,
  <functionlink id="AddModuleUses"/> and <functionlink id="AddModuleProvides"/>
  to update a module to expand the set of modules that it reads, the set of
  packages that it exports or opens to other modules, or the services that it
  uses and provides.
  <p/>
  As an aid to agents that deploy supporting classes on the search path of
  the bootstrap class loader, or the search path of the class loader that
  loads the main class, the Java virtual machine arranges for the module
  of classes transformed by the <eventlink id="ClassFileLoadHook"/> event to
  read the unnamed module of both class loaders.
</intro>

  <intro id="mUTF" label="Modified UTF-8 String Encoding">
    <jvmti/> 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
    <externallink id="jni/types.html#modified-utf-8-strings">
      Modified UTF-8 Strings</externallink>
    section of the JNI specification for details.
  </intro>

  <intro id="context" label="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:
    <ul>
      <li>"thread" means Java programming language thread.</li>
      <li>"stack frame" means Java virtual machine stack frame.</li>
      <li>"class" means Java programming language class.</li>
      <li>"heap" means Java virtual machine heap.</li>
      <li>"monitor" means Java programming language object monitor.</li>
    </ul>
    <p/>
    Sun, Sun Microsystems, the Sun logo, Java, and JVM
    are trademarks or registered trademarks of Oracle
    and/or its affiliates, in the U.S. and other countries.
  </intro>


<functionsection label="Functions">
  <intro id="jvmtiEnvAccess" label="Accessing Functions">
    Native code accesses <jvmti/> features
    by calling <jvmti/> functions.
    Access to <jvmti/> functions is by use of an interface pointer
    in the same manner as
    <externallink id="jni/design.html">Java
      Native Interface (JNI) functions</externallink> are accessed.
    The <jvmti/> interface pointer is called the
    <i>environment pointer</i>.
    <p/>
    An environment pointer is a pointer to an environment and has
    the type <code>jvmtiEnv*</code>.
    An environment has information about its <jvmti/> connection.
    The first value in the environment is a pointer to the function table.
    The function table is an array of pointers to <jvmti/> functions.
    Every function pointer is at a predefined offset inside the
    array.
    <p/>
    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:
    <example>
jvmtiEnv *jvmti;
...
jvmtiError err = (*jvmti)->GetLoadedClasses(jvmti, &amp;class_count, &amp;classes);
    </example>
    <p/>
    When used from the C++ language:
    functions are accessed as member functions of <code>jvmtiEnv</code>;
    the environment pointer is not passed to the function call; for example:
    <example>
jvmtiEnv *jvmti;
...
jvmtiError err = jvmti->GetLoadedClasses(&amp;class_count, &amp;classes);
    </example>
    Unless otherwise stated, all examples and declarations in this
    specification use the C language.
    <p/>
    A <jvmti/> environment can be obtained through the JNI Invocation API
    <code>GetEnv</code> function:
    <example>
jvmtiEnv *jvmti;
...
(*jvm)->GetEnv(jvm, &amp;jvmti, JVMTI_VERSION_1_0);
    </example>
    Each call to <code>GetEnv</code>
    creates a new <jvmti/> connection and thus
    a new <jvmti/> environment.
    The <code>version</code> argument of <code>GetEnv</code> must be
    a <jvmti/> version.
    The returned environment may have a different version than the
    requested version but the returned environment must be compatible.
    <code>GetEnv</code> will return <code>JNI_EVERSION</code> if a
    compatible version is not available, if <jvmti/> is not supported or
    <jvmti/> is not supported in the current VM configuration.
    Other interfaces may be added for creating <jvmti/> environments
    in specific contexts.
    Each environment has its own state (for example,
    <functionlink id="SetEventNotificationMode">desired events</functionlink>,
    <functionlink id="SetEventCallbacks">event handling functions</functionlink>, and
    <functionlink id="AddCapabilities">capabilities</functionlink>).
    An environment is released with
    <functionlink id="DisposeEnvironment"></functionlink>.
    Thus, unlike JNI which has one environment per thread, <jvmti/> environments work
    across threads and are created dynamically.
  </intro>

  <intro id="functionReturn" label="Function Return Values">
    <jvmti/> functions always return an
    <internallink id="ErrorSection">error code</internallink> via the
    <datalink id="jvmtiError"/> function return value.
    Some functions can return additional
    values through pointers provided by the calling function.
    In some cases, <jvmti/> functions allocate memory that your program must
    explicitly deallocate. This is indicated in the individual <jvmti/>
    function descriptions.  Empty lists, arrays, sequences, etc are
    returned as <code>NULL</code>.
    <p/>
    In the event that the <jvmti/> function encounters
    an error (any return value other than <code>JVMTI_ERROR_NONE</code>) 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.
  </intro>

<intro id="refs" label="Managing JNI Object References">
    <jvmti/> functions identify objects with JNI references
    (<datalink id="jobject"/> and <datalink id="jclass"/>)
    and their derivatives
    (<datalink id="jthread"/> and <datalink id="jthreadGroup"/>).
    References passed to
    <jvmti/> functions can be either global or local, but they must be
    strong references. All references returned by <jvmti/> functions are
    local references--these local references are created
    during the <jvmti/> call.
    Local references are a resource that must be managed (see the
    <externallink id="jni/functions.html#local-references">
      JNI Documentation</externallink>).
    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 <jvmti/> 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
    <code>PushLocalFrame</code> and <code>PopLocalFrame</code>.
    Conversely, to preserve references beyond the
    return from native code, they must be converted to global references.
    These rules do not apply to <datalink id="jmethodID"/> and <datalink id="jfieldID"/>
    as they are not <datalink id="jobject"/>s.
</intro>

    <intro id="prereqState" label="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 <jvmti/> implementation is responsible for bringing the VM to a
      safe and consistent state for performing the function.
    </intro>

    <intro id="functionsExceptions" label="Exceptions and Functions">
      <jvmti/> functions never throw exceptions; error conditions are
      communicated via the
      <internallink id="functionReturn">function return value</internallink>.
      Any existing exception state is preserved across a call to a
      <jvmti/> function.
      See the
      <externallink
        id="jni/design.html#java-exceptions"
             >Java Exceptions</externallink>
      section of the JNI specification for information on handling exceptions.
    </intro>

  <category id="memory" label="Memory Management">
    <intro>
      These functions provide for the allocation and deallocation of
      memory used by <jvmti/> functionality and can be used to provide
      working memory for agents.
      Memory managed by <jvmti/> is not compatible with other memory
      allocation libraries and mechanisms.
    </intro>

    <function id="Allocate" jkernel="yes" phase="any" callbacksafe="safe" impl="notrace" num="46">
      <synopsis>Allocate</synopsis>
      <description>
        Allocate an area of memory through the <jvmti/> allocator.
        The allocated
        memory should be freed with <functionlink id="Deallocate"></functionlink>.
      </description>
      <origin>jvmdi</origin>
      <capabilities>
      </capabilities>
      <parameters>
        <param id="size">
          <jlong/>
          <description>
            The number of bytes to allocate.
            <rationale>
              <code>jlong</code> is used for compatibility with JVMDI.
            </rationale>
          </description>
        </param>
        <param id="mem_ptr">
          <allocbuf incount="size"><uchar/></allocbuf>
          <description>
            On return, a pointer to the beginning of the allocated memory.
            If <code>size</code> is zero, <code>NULL</code> is returned.
          </description>
        </param>
      </parameters>
      <errors>
        <error id="JVMTI_ERROR_OUT_OF_MEMORY">
          Memory request cannot be honored.
        </error>
        <error id="JVMTI_ERROR_ILLEGAL_ARGUMENT">
          <paramlink id="size"></paramlink> is less than zero.
        </error>
      </errors>
    </function>

    <function id="Deallocate" jkernel="yes" phase="any" callbacksafe="safe" impl="notrace" num="47">
      <synopsis>Deallocate</synopsis>
      <description>
        Deallocate <code>mem</code>  using the <jvmti/> allocator.
        This function should
        be used to deallocate any memory allocated and returned
        by a <jvmti/> function
        (including memory allocated with <functionlink id="Allocate"></functionlink>).
        All allocated memory must be deallocated
        or the memory cannot be reclaimed.
      </description>
      <origin>jvmdi</origin>
      <capabilities>
      </capabilities>
      <parameters>
        <param id="mem">
          <outbuf>
            <uchar/>
            <nullok>the call is ignored</nullok>
          </outbuf>
          <description>
            A pointer to the beginning of the allocated memory.
            Please ignore "On return, the elements are set."
              <todo>keep it from generating "On return, the elements are set"</todo>
          </description>
        </param>
      </parameters>
      <errors>
      </errors>
    </function>
  </category>

  <category id="threadCategory" label="Thread">
    <intro>
    </intro>

    <function id="GetThreadState" num="17">
      <synopsis>Get Thread State</synopsis>
      <description>
        Get the state of a thread.  The state of the thread is represented by the
        answers to the hierarchical set of questions below:
          <ul type="circle">
            <li><i>Alive?</i>
              <ul>
                <li>Not alive.
                  <ul type="circle">
                    <li><i>Why not alive?</i>
                      <ul>
                        <li>New.</li>
                        <li>Terminated (<datalink
                            id="JVMTI_THREAD_STATE_TERMINATED"><code>JVMTI_THREAD_STATE_TERMINATED</code></datalink>)</li>
                      </ul>
                    </li>
                  </ul>
                </li>
                <li>Alive (<datalink
                    id="JVMTI_THREAD_STATE_ALIVE"><code>JVMTI_THREAD_STATE_ALIVE</code></datalink>)
                  <ul type="circle">
                    <li><i>Suspended?</i>
                      <ul>
                        <li>Suspended (<datalink
                            id="JVMTI_THREAD_STATE_SUSPENDED"><code>JVMTI_THREAD_STATE_SUSPENDED</code></datalink>)</li>
                        <li>Not suspended</li>
                      </ul>
                    </li>
                    <li><i>Interrupted?</i>
                      <ul>
                        <li>Interrupted (<datalink
                            id="JVMTI_THREAD_STATE_INTERRUPTED"><code>JVMTI_THREAD_STATE_INTERRUPTED</code></datalink>)</li>
                        <li>Not interrupted.</li>
                      </ul>
                    </li>
                    <li><i>In native?</i>
                      <ul>
                        <li>In native code (<datalink
                            id="JVMTI_THREAD_STATE_IN_NATIVE"><code>JVMTI_THREAD_STATE_IN_NATIVE</code></datalink>)</li>
                        <li>In Java programming language code</li>
                      </ul>
                    </li>
                    <li><i>What alive state?</i>
                      <ul>
                        <li>Runnable (<datalink
                            id="JVMTI_THREAD_STATE_RUNNABLE"><code>JVMTI_THREAD_STATE_RUNNABLE</code></datalink>)</li>
                        <li>Blocked (<datalink
                            id="JVMTI_THREAD_STATE_BLOCKED_ON_MONITOR_ENTER"><code>JVMTI_THREAD_STATE_BLOCKED_ON_MONITOR_ENTER</code></datalink>)</li>
                        <li>Waiting (<datalink
                            id="JVMTI_THREAD_STATE_WAITING"><code>JVMTI_THREAD_STATE_WAITING</code></datalink>)
                          <ul type="circle">
                            <li><i>Timed wait?</i>
                              <ul>
                                <li>Indefinite (<datalink
                                    id="JVMTI_THREAD_STATE_WAITING_INDEFINITELY"><code>JVMTI_THREAD_STATE_WAITING_INDEFINITELY</code></datalink></li>
                                <li>Timed (<datalink
                                    id="JVMTI_THREAD_STATE_WAITING_WITH_TIMEOUT"><code>JVMTI_THREAD_STATE_WAITING_WITH_TIMEOUT</code></datalink>)</li>
                              </ul>
                            </li>
                            <li><i>Why waiting?</i>
                              <ul>
                                <li>Object.wait (<datalink
                                    id="JVMTI_THREAD_STATE_IN_OBJECT_WAIT"><code>JVMTI_THREAD_STATE_IN_OBJECT_WAIT</code></datalink>)</li>
                                <li>LockSupport.park (<datalink
                                    id="JVMTI_THREAD_STATE_PARKED"><code>JVMTI_THREAD_STATE_PARKED</code></datalink>)</li>
                                <li>Sleeping (<datalink
                                    id="JVMTI_THREAD_STATE_SLEEPING"><code>JVMTI_THREAD_STATE_SLEEPING</code></datalink>)</li>
                              </ul>
                            </li>
                          </ul>
                        </li>
                      </ul>
                    </li>
                  </ul>
                </li>
              </ul>
            </li>
          </ul>
        <p/>
        The answers are represented by the following bit vector.
        <constants id="jvmtiThreadState" label="Thread State Flags" kind="bits">
          <constant id="JVMTI_THREAD_STATE_ALIVE" num="0x0001">
            Thread is alive. Zero if thread is new (not started) or terminated.
          </constant>
          <constant id="JVMTI_THREAD_STATE_TERMINATED" num="0x0002">
            Thread has completed execution.
          </constant>
          <constant id="JVMTI_THREAD_STATE_RUNNABLE" num="0x0004">
            Thread is runnable.
          </constant>
          <constant id="JVMTI_THREAD_STATE_BLOCKED_ON_MONITOR_ENTER" num="0x0400">
            Thread is waiting to enter a synchronization block/method or,
            after an <code>Object.wait()</code>, waiting to re-enter a
            synchronization block/method.
          </constant>
          <constant id="JVMTI_THREAD_STATE_WAITING" num="0x0080">
            Thread is waiting.
          </constant>
          <constant id="JVMTI_THREAD_STATE_WAITING_INDEFINITELY" num="0x0010">
            Thread is waiting without a timeout.
            For example, <code>Object.wait()</code>.
          </constant>
          <constant id="JVMTI_THREAD_STATE_WAITING_WITH_TIMEOUT" num="0x0020">
            Thread is waiting with a maximum time to wait specified.
            For example, <code>Object.wait(long)</code>.
          </constant>
          <constant id="JVMTI_THREAD_STATE_SLEEPING" num="0x0040">
            Thread is sleeping -- <code>Thread.sleep(long)</code>.
          </constant>
          <constant id="JVMTI_THREAD_STATE_IN_OBJECT_WAIT" num="0x0100">
            Thread is waiting on an object monitor -- <code>Object.wait</code>.
          </constant>
          <constant id="JVMTI_THREAD_STATE_PARKED" num="0x0200">
            Thread is parked, for example: <code>LockSupport.park</code>,
            <code>LockSupport.parkUtil</code> and <code>LockSupport.parkNanos</code>.
          </constant>
          <constant id="JVMTI_THREAD_STATE_SUSPENDED" num="0x100000">
            Thread suspended.
            <code>java.lang.Thread.suspend()</code>
            or a <jvmti/> suspend function
            (such as <functionlink id="SuspendThread"></functionlink>)
            has been called on the thread. If this bit
            is set, the other bits refer to the thread state before suspension.
          </constant>
          <constant id="JVMTI_THREAD_STATE_INTERRUPTED" num="0x200000">
            Thread has been interrupted.
          </constant>
          <constant id="JVMTI_THREAD_STATE_IN_NATIVE" num="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.
            <p/>
            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
            <jvmti/> functions, may be implemented as VM code.
          </constant>
          <constant id="JVMTI_THREAD_STATE_VENDOR_1" num="0x10000000">
            Defined by VM vendor.
          </constant>
          <constant id="JVMTI_THREAD_STATE_VENDOR_2" num="0x20000000">
            Defined by VM vendor.
          </constant>
          <constant id="JVMTI_THREAD_STATE_VENDOR_3" num="0x40000000">
            Defined by VM vendor.
          </constant>
        </constants>
        The following definitions are used to convert <jvmti/> thread state
        to <code>java.lang.Thread.State</code> style states.
        <constants id="jvmtiJavaLangThreadState" label="java.lang.Thread.State Conversion Masks" kind="bits">
          <constant id="JVMTI_JAVA_LANG_THREAD_STATE_MASK"
                     num="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
          </constant>
          <constant id="JVMTI_JAVA_LANG_THREAD_STATE_NEW"
                     num="0">
            <code>java.lang.Thread.State.NEW</code>
          </constant>
          <constant id="JVMTI_JAVA_LANG_THREAD_STATE_TERMINATED"
                     num="JVMTI_THREAD_STATE_TERMINATED">
            <code>java.lang.Thread.State.TERMINATED</code>
          </constant>
          <constant id="JVMTI_JAVA_LANG_THREAD_STATE_RUNNABLE"
                     num="JVMTI_THREAD_STATE_ALIVE | JVMTI_THREAD_STATE_RUNNABLE">
            <code>java.lang.Thread.State.RUNNABLE</code>
          </constant>
          <constant id="JVMTI_JAVA_LANG_THREAD_STATE_BLOCKED"
                     num="JVMTI_THREAD_STATE_ALIVE | JVMTI_THREAD_STATE_BLOCKED_ON_MONITOR_ENTER">
            <code>java.lang.Thread.State.BLOCKED</code>
          </constant>
          <constant id="JVMTI_JAVA_LANG_THREAD_STATE_WAITING"
                     num="JVMTI_THREAD_STATE_ALIVE | JVMTI_THREAD_STATE_WAITING | JVMTI_THREAD_STATE_WAITING_INDEFINITELY">
            <code>java.lang.Thread.State.WAITING</code>
          </constant>
          <constant id="JVMTI_JAVA_LANG_THREAD_STATE_TIMED_WAITING"
                     num="JVMTI_THREAD_STATE_ALIVE | JVMTI_THREAD_STATE_WAITING | JVMTI_THREAD_STATE_WAITING_WITH_TIMEOUT">
            <code>java.lang.Thread.State.TIMED_WAITING</code>
          </constant>
        </constants>
        <b>Rules</b>
        <p/>
        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
          <ul type="circle">
              <li><code>JVMTI_THREAD_STATE_RUNNABLE</code></li>
              <li><code>JVMTI_THREAD_STATE_BLOCKED_ON_MONITOR_ENTER</code></li>
              <li><code>JVMTI_THREAD_STATE_WAITING</code></li>
          </ul>
        can be set (a <tm>J2SE</tm> compliant implementation will always set
        one of these if <code>JVMTI_THREAD_STATE_ALIVE</code> is set).
        And if any of these are set, the enclosing answer
        <code>JVMTI_THREAD_STATE_ALIVE</code> is set.
        No more than one of
          <ul type="circle">
              <li><code>JVMTI_THREAD_STATE_WAITING_INDEFINITELY</code></li>
              <li><code>JVMTI_THREAD_STATE_WAITING_WITH_TIMEOUT</code></li>
          </ul>
        can be set (a <tm>J2SE</tm> compliant implementation will always set
        one of these if <code>JVMTI_THREAD_STATE_WAITING</code> is set).
        And if either is set, the enclosing answers
        <code>JVMTI_THREAD_STATE_ALIVE</code> and
        <code>JVMTI_THREAD_STATE_WAITING</code> are set.
        No more than one of
          <ul type="circle">
              <li><code>JVMTI_THREAD_STATE_IN_OBJECT_WAIT</code></li>
              <li><code>JVMTI_THREAD_STATE_PARKED</code></li>
              <li><code>JVMTI_THREAD_STATE_SLEEPING</code></li>
          </ul>
        can be set. And if any of these is set, the enclosing answers
        <code>JVMTI_THREAD_STATE_ALIVE</code> and
        <code>JVMTI_THREAD_STATE_WAITING</code> are set.
        Also, if <code>JVMTI_THREAD_STATE_SLEEPING</code> is set,
        then <code>JVMTI_THREAD_STATE_WAITING_WITH_TIMEOUT</code> is set.
        If a state <i>A</i> is implemented using the mechanism of
        state <i>B</i> then it is state <i>A</i> which
        is returned by this function.
        For example, if <code>Thread.sleep(long)</code>
        is implemented using <code>Object.wait(long)</code>
        then it is still <code>JVMTI_THREAD_STATE_SLEEPING</code>
        which is returned.
        More than one of
          <ul type="circle">
              <li><code>JVMTI_THREAD_STATE_SUSPENDED</code></li>
              <li><code>JVMTI_THREAD_STATE_INTERRUPTED</code></li>
              <li><code>JVMTI_THREAD_STATE_IN_NATIVE</code></li>
          </ul>
        can be set, but if any is set,
        <code>JVMTI_THREAD_STATE_ALIVE</code> is set.
        <p/>
        And finally,
        <code>JVMTI_THREAD_STATE_TERMINATED</code> cannot be set unless
        <code>JVMTI_THREAD_STATE_ALIVE</code> is not set.
        <p/>
        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.
        <p/>
        <b>Examples</b>
        <p/>
        Note that the values below exclude reserved and vendor bits.
        <p/>
        The state of a thread blocked at a <code>synchronized</code>-statement would be:
        <example>
            JVMTI_THREAD_STATE_ALIVE + JVMTI_THREAD_STATE_BLOCKED_ON_MONITOR_ENTER
        </example>
        The state of a thread which hasn't started yet would be:
        <example>
            0
        </example>
        The state of a thread at a <code>Object.wait(3000)</code> would be:
        <example>
            JVMTI_THREAD_STATE_ALIVE + JVMTI_THREAD_STATE_WAITING +
                JVMTI_THREAD_STATE_WAITING_WITH_TIMEOUT +
                JVMTI_THREAD_STATE_MONITOR_WAITING
        </example>
        The state of a thread suspended while runnable would be:
        <example>
            JVMTI_THREAD_STATE_ALIVE + JVMTI_THREAD_STATE_RUNNABLE + JVMTI_THREAD_STATE_SUSPENDED
        </example>
        <p/>
        <b>Testing the State</b>
        <p/>
        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:
        <example>
        jint state;
        jvmtiError err;

        err = (*jvmti)-&gt;GetThreadState(jvmti, thread, &amp;state);
        if (err == JVMTI_ERROR_NONE) {
           if (state &amp; JVMTI_THREAD_STATE_SLEEPING) {  ...
        </example>
        <p/>
        For waiting (that is, in <code>Object.wait</code>, parked, or sleeping) it would be:
        <example>
           if (state &amp; JVMTI_THREAD_STATE_WAITING) {  ...
        </example>
        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:
        <example>
           if ((state &amp; (JVMTI_THREAD_STATE_ALIVE | JVMTI_THREAD_STATE_TERMINATED)) == 0)  {  ...
        </example>
        To distinguish timed from untimed <code>Object.wait</code>:
        <example>
           if (state &amp; JVMTI_THREAD_STATE_IN_OBJECT_WAIT)  {
             if (state &amp; JVMTI_THREAD_STATE_WAITING_WITH_TIMEOUT)  {
               printf("in Object.wait(long timeout)\n");
             } else {
               printf("in Object.wait()\n");
             }
           }
        </example>
        <p/>
        <b>Relationship to <code>java.lang.Thread.State</code></b>
        <p/>
        The thread state represented by <code>java.lang.Thread.State</code>
        returned from <code>java.lang.Thread.getState()</code> is a subset of the
        information returned from this function.
        The corresponding <code>java.lang.Thread.State</code> can be determined
        by using the provided conversion masks.
        For example, this returns the name of the <code>java.lang.Thread.State</code> thread state:
        <example>
            err = (*jvmti)-&gt;GetThreadState(jvmti, thread, &amp;state);
            abortOnError(err);
            switch (state &amp; 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";
            }
        </example>
      </description>
      <origin>new</origin>
      <capabilities>
      </capabilities>
      <parameters>
        <param id="thread">
          <jthread null="current" started="maybe" impl="noconvert"/>
            <description>
              The thread to query.
            </description>
        </param>
        <param id="thread_state_ptr">
          <outptr><jint/></outptr>
          <description>
            On return, points to state flags,
            as defined by the <internallink id="jvmtiThreadState">Thread State Flags</internallink>.
          </description>
        </param>
      </parameters>
      <errors>
      </errors>
    </function>

    <function id="GetCurrentThread" phase="start" num="18" since="1.1">
      <synopsis>Get Current Thread</synopsis>
      <description>
        Get the current thread.
        The current thread is the Java programming language thread which has called the function.
        The function may return <code>NULL</code> in the start phase if the
        <internallink id="jvmtiCapabilities.can_generate_early_vmstart">
        <code>can_generate_early_vmstart</code></internallink> capability is enabled
        and the <code>java.lang.Thread</code> class has not been initialized yet.
        <p/>
        Note that most <jvmti/> functions that take a thread
        as an argument will accept <code>NULL</code> to mean
        the current thread.
      </description>
      <origin>new</origin>
      <capabilities>
      </capabilities>
      <parameters>
        <param id="thread_ptr">
          <outptr><jthread/></outptr>
          <description>
             On return, points to the current thread, or <code>NULL</code>.
          </description>
        </param>
      </parameters>
      <errors>
      </errors>
    </function>

    <function id="GetAllThreads" num="4">
      <synopsis>Get All Threads</synopsis>
      <description>
        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 <code>java.lang.Thread.isAlive()</code>
        would return <code>true</code>, that is, the thread has
        been started and has not yet died.
        The universe of threads is determined by the context of the <jvmti/>
        environment, which typically is all threads attached to the VM.
        Note that this includes <jvmti/> agent threads
        (see <functionlink id="RunAgentThread"/>).
      </description>
      <origin>jvmdi</origin>
      <capabilities>
      </capabilities>
      <parameters>
        <param id="threads_count_ptr">
          <outptr><jint/></outptr>
          <description>
            On return, points to the number of running threads.
          </description>
        </param>
        <param id="threads_ptr">
          <allocbuf outcount="threads_count_ptr"><jthread/></allocbuf>
            <description>
              On return, points to an array of references, one
              for each running thread.
            </description>
        </param>
      </parameters>
      <errors>
      </errors>
    </function>

    <function id="SuspendThread" num="5">
      <synopsis>Suspend Thread</synopsis>
      <description>
        Suspend the specified thread. If the calling thread is specified,
        this function will not return until some other thread calls
        <functionlink id="ResumeThread"></functionlink>.
        If the thread is currently suspended, this function
        does nothing and returns an error.
      </description>
      <origin>jvmdi</origin>
      <capabilities>
        <required id="can_suspend"></required>
      </capabilities>
      <parameters>
        <param id="thread">
          <jthread null="current"/>
            <description>
              The thread to suspend.
            </description>
        </param>
      </parameters>
      <errors>
        <error id="JVMTI_ERROR_THREAD_SUSPENDED">
          Thread already suspended.
        </error>
      </errors>
    </function>

    <elide>
    <function id="SuspendAllThreads" num="101">
      <synopsis>Suspend All Threads</synopsis>
      <description>
        <issue>
            There has been no explicit call for this function, and it will
            thus be removed if there is no interest.
        </issue>
        Suspend all live threads except:
        <ul>
          <li>already suspended threads</li>
          <li>those listed in <paramlink id="except_list"></paramlink></li>
          <li>certain system (non application) threads, as determined
            by the VM implementation</li>
        </ul>
        The threads are Java programming language threads;
        native threads which are not attached to the VM are not
        Java programming language threads.
        A thread is live if <code>java.lang.Thread.isAlive()</code>
        would return <code>true</code>, that is, the thread has
        been started and has not yet died.
        The universe of threads is determined
        by the context of the <jvmti/>
        environment, which, typically, is all threads attached to the VM,
        except critical VM internal threads and <jvmti/> agent threads
        (see <functionlink id="RunAgentThread"/>).
        <p/>
        If the calling thread is specified,
        all other threads are suspended first then the caller thread is suspended -
        this function will not return until some other thread calls
        <functionlink id="ResumeThread"></functionlink>.
        <p/>
        The list of actually
        suspended threads is returned in
        <paramlink id="suspended_list_ptr"></paramlink>.
        Suspension is as defined in <functionlink id="SuspendThread"></functionlink>.
        <functionlink id="ResumeThreadList"></functionlink>
        can be used to resume the suspended threads.
      </description>
      <origin>new</origin>
      <capabilities>
        <required id="can_suspend"></required>
      </capabilities>
      <parameters>
        <param id="except_count">
          <jint min="0"/>
          <description>
            The number of threads in the list of threads not to be suspended.
          </description>
        </param>
        <param id="except_list">
            <inbuf incount="except_count">
              <jthread/>
              <nullok>not an error if <code>except_count == 0</code></nullok>
            </inbuf>
            <description>
              The list of threads not to be suspended.
            </description>
        </param>
        <param id="suspended_count_ptr">
          <outptr><jint/></outptr>
          <description>
            On return, points to the number of threads suspended by this call.
          </description>
        </param>
        <param id="suspended_list_ptr">
          <allocbuf outcount="suspended_count_ptr"><jthread/></allocbuf>
            <description>
              On return, points to an array of references, one
              for each thread suspended.
            </description>
        </param>
      </parameters>
      <errors>
        <error id="JVMTI_ERROR_INVALID_THREAD">
          A thread in <paramlink id="except_list"></paramlink> was invalid.
        </error>
        <error id="JVMTI_ERROR_NULL_POINTER">
          Both <paramlink id="except_list"></paramlink> was <code>NULL</code>
          and <paramlink id="except_count"></paramlink> was non-zero.
        </error>
      </errors>
    </function>
    </elide>

    <function id="SuspendThreadList" num="92">
      <synopsis>Suspend Thread List</synopsis>
      <description>
        Suspend the <paramlink id="request_count"></paramlink>
        threads specified in the
        <paramlink id="request_list"></paramlink> array.
        Threads may be resumed with
        <functionlink id="ResumeThreadList"></functionlink> or
        <functionlink id="ResumeThread"></functionlink>.
        If the calling thread is specified in the
        <paramlink id="request_list"></paramlink> array, this function will
        not return until some other thread resumes it.
        Errors encountered in the suspension of a thread
        are returned in the <paramlink id="results"></paramlink>
        array, <b>not</b> in the return value of this function.
        Threads that are currently suspended do not change state.
      </description>
      <origin>jvmdi</origin>
      <capabilities>
        <required id="can_suspend"></required>
      </capabilities>
      <parameters>
        <param id="request_count">
          <jint min="0"/>
          <description>
            The number of threads to suspend.
          </description>
        </param>
        <param id="request_list">
          <inbuf incount="request_count"><jthread/></inbuf>
            <description>
              The list of threads to suspend.
            </description>
        </param>
        <param id="results">
          <outbuf incount="request_count"><enum>jvmtiError</enum></outbuf>
          <description>
            An agent supplied array of
            <paramlink id="request_count"></paramlink> elements.
            On return, filled with the error code for
            the suspend of the corresponding thread.
            The error code will be
            <errorlink id="JVMTI_ERROR_NONE"></errorlink>
            if the thread was suspended by this call.
            Possible error codes are those specified
            for <functionlink id="SuspendThread"></functionlink>.
          </description>
        </param>
      </parameters>
      <errors>
      </errors>
    </function>

    <function id="ResumeThread" num="6">
      <synopsis>Resume Thread</synopsis>
      <description>
        Resume a suspended thread.
        Any threads currently suspended through
        a <jvmti/> suspend function (eg.
        <functionlink id="SuspendThread"></functionlink>)
        or <code>java.lang.Thread.suspend()</code>
        will resume execution;
        all other threads are unaffected.
      </description>
      <origin>jvmdi</origin>
      <capabilities>
        <required id="can_suspend"></required>
      </capabilities>
      <parameters>
        <param id="thread">
          <jthread/>
            <description>
              The thread to resume.
            </description>
        </param>
      </parameters>
      <errors>
        <error id="JVMTI_ERROR_THREAD_NOT_SUSPENDED">
          Thread was not suspended.
        </error>
        <error id="JVMTI_ERROR_INVALID_TYPESTATE">
          The state of the thread has been modified, and is now inconsistent.
        </error>
      </errors>
    </function>

    <function id="ResumeThreadList" num="93">
      <synopsis>Resume Thread List</synopsis>
      <description>
        Resume the <paramlink id="request_count"></paramlink>
        threads specified in the
        <paramlink id="request_list"></paramlink> array.
        Any thread suspended through
        a <jvmti/> suspend function (eg.
        <functionlink id="SuspendThreadList"></functionlink>)
        or <code>java.lang.Thread.suspend()</code>
        will resume execution.
      </description>
      <origin>jvmdi</origin>
      <capabilities>
        <required id="can_suspend"></required>
      </capabilities>
      <parameters>
        <param id="request_count">
          <jint min="0"/>
          <description>
            The number of threads to resume.
          </description>
        </param>
        <param id="request_list">
          <inbuf incount="request_count"><jthread/></inbuf>
            <description>
              The threads to resume.
            </description>
        </param>
        <param id="results">
          <outbuf incount="request_count"><enum>jvmtiError</enum></outbuf>
          <description>
            An agent supplied array of
            <paramlink id="request_count"></paramlink> elements.
            On return, filled with the error code for
            the resume of the corresponding thread.
            The error code will be
            <errorlink id="JVMTI_ERROR_NONE"></errorlink>
            if the thread was suspended by this call.
            Possible error codes are those specified
            for <functionlink id="ResumeThread"></functionlink>.
          </description>
        </param>
      </parameters>
      <errors>
      </errors>
    </function>

    <function id="StopThread" num="7">
      <synopsis>Stop Thread</synopsis>
      <description>
        Send the specified asynchronous exception to the specified thread.
        Normally, this function is used to kill the specified thread with an
        instance of the exception <code>ThreadDeath</code>, similar to
        <code>java.lang.Thread.stop</code>.
      </description>
      <origin>jvmdi</origin>
      <capabilities>
        <required id="can_signal_thread"></required>
      </capabilities>
      <parameters>
        <param id="thread">
          <jthread/>
            <description>
              The thread to stop.
            </description>
        </param>
        <param id="exception">
          <jobject/>
            <description>
              The asynchronous exception object.
            </description>
        </param>
      </parameters>
      <errors>
      </errors>
    </function>

    <function id="InterruptThread" num="8">
      <synopsis>Interrupt Thread</synopsis>
      <description>
        Interrupt the specified thread
        (similar to <code>java.lang.Thread.interrupt</code>).
      </description>
      <origin>jvmdi</origin>
      <capabilities>
        <required id="can_signal_thread"></required>
      </capabilities>
      <parameters>
        <param id="thread">
          <jthread impl="noconvert"/>
            <description>
              The thread to interrupt.
            </description>
        </param>
      </parameters>
      <errors>
      </errors>
    </function>

    <function id="GetThreadInfo" num="9">
      <synopsis>Get Thread Info</synopsis>
      <typedef id="jvmtiThreadInfo" label="Thread information structure">
        <field id="name">
          <allocfieldbuf><char/></allocfieldbuf>
          <description>
            The thread name, encoded as a
            <internallink id="mUTF">modified UTF-8</internallink> string.
          </description>
        </field>
        <field id="priority">
          <jint/>
          <description>
            The thread priority.  See the thread priority constants:
            <datalink id="jvmtiThreadPriority"></datalink>.
          </description>
        </field>
        <field id="is_daemon">
          <jboolean/>
          <description>
            Is this a daemon thread?
          </description>
        </field>
        <field id="thread_group">
          <jthreadGroup/>
          <description>
            The thread group to which this thread belongs.
            <code>NULL</code> if the thread has died.
          </description>
        </field>
        <field id="context_class_loader">
          <jobject/>
            <description>
              The context class loader associated with this thread.
            </description>
        </field>
      </typedef>
      <description>
        Get thread information. The fields of the <datalink id="jvmtiThreadInfo"/> structure
        are filled in with details of the specified thread.
      </description>
      <origin>jvmdi</origin>
      <capabilities>
      </capabilities>
      <parameters>
        <param id="thread">
          <jthread null="current" impl="noconvert" started="maybe"/>
            <description>
              The thread to query.
            </description>
        </param>
        <param id="info_ptr">
          <outptr><struct>jvmtiThreadInfo</struct></outptr>
          <description>
            On return, filled with information describing the specified thread.
          </description>
        </param>
      </parameters>
      <errors>
      </errors>
    </function>

    <function id="GetOwnedMonitorInfo" num="10">
      <synopsis>Get Owned Monitor Info</synopsis>
      <description>
        Get information about the monitors owned by the
        specified thread.
      </description>
      <origin>jvmdiClone</origin>
      <capabilities>
        <required id="can_get_owned_monitor_info"></required>
      </capabilities>
      <parameters>
        <param id="thread">
          <jthread null="current"/>
            <description>
              The thread to query.
            </description>
        </param>
        <param id="owned_monitor_count_ptr">
          <outptr><jint/></outptr>
          <description>
            The number of monitors returned.
          </description>
        </param>
        <param id="owned_monitors_ptr">
          <allocbuf outcount="owned_monitor_count_ptr"><jobject/></allocbuf>
            <description>
              The array of owned monitors.
            </description>
        </param>
      </parameters>
      <errors>
      </errors>
    </function>

    <function id="GetOwnedMonitorStackDepthInfo" num="153" since="1.1">
      <synopsis>Get Owned Monitor Stack Depth Info</synopsis>
      <typedef id="jvmtiMonitorStackDepthInfo"
               label="Monitor stack depth information structure">
        <field id="monitor">
          <jobject/>
            <description>
              The owned monitor.
            </description>
        </field>
        <field id="stack_depth">
          <jint/>
          <description>
            The stack depth.  Corresponds to the stack depth used in the
            <internallink id="stack">Stack Frame functions</internallink>.
            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 <code>MonitorEnter</code>).
          </description>
        </field>
      </typedef>
      <description>
        Get information about the monitors owned by the
        specified thread and the depth of the stack frame which locked them.
      </description>
      <origin>new</origin>
      <capabilities>
        <required id="can_get_owned_monitor_stack_depth_info"></required>
      </capabilities>
      <parameters>
        <param id="thread">
          <jthread null="current"/>
            <description>
              The thread to query.
            </description>
        </param>
        <param id="monitor_info_count_ptr">
          <outptr><jint/></outptr>
          <description>
            The number of monitors returned.
          </description>
        </param>
        <param id="monitor_info_ptr">
          <allocbuf outcount="monitor_info_count_ptr">
            <struct>jvmtiMonitorStackDepthInfo</struct>
          </allocbuf>
          <description>
            The array of owned monitor depth information.
          </description>
        </param>
      </parameters>
      <errors>
      </errors>
    </function>

    <function id="GetCurrentContendedMonitor" num="11">
      <synopsis>Get Current Contended Monitor</synopsis>
      <description>
        Get the object, if any, whose monitor the specified thread is waiting to
        enter or waiting to regain through <code>java.lang.Object.wait</code>.
      </description>
      <origin>jvmdi</origin>
      <capabilities>
        <required id="can_get_current_contended_monitor"></required>
      </capabilities>
      <parameters>
        <param id="thread">
          <jthread null="current"/>
            <description>
              The thread to query.
            </description>
        </param>
        <param id="monitor_ptr">
          <outptr><jobject/></outptr>
            <description>
              On return, filled with the current contended monitor, or
              NULL if there is none.
            </description>
        </param>
      </parameters>
      <errors>
      </errors>
    </function>

    <callback id="jvmtiStartFunction">
      <void/>
      <synopsis>Agent Start Function</synopsis>
      <description>
        Agent supplied callback function.
        This function is the entry point for an agent thread
        started with
        <functionlink id="RunAgentThread"></functionlink>.
      </description>
      <parameters>
          <param id="jvmti_env">
            <outptr>
              <struct>jvmtiEnv</struct>
            </outptr>
            <description>
              The <jvmti/> environment.
            </description>
          </param>
          <param id="jni_env">
            <outptr>
              <struct>JNIEnv</struct>
            </outptr>
            <description>
              The JNI environment.
            </description>
          </param>
          <param id="arg">
            <outptr>
              <void/>
            </outptr>
              <description>
                The <code>arg</code> parameter passed to
                <functionlink id="RunAgentThread"></functionlink>.
              </description>
          </param>
      </parameters>
    </callback>

    <function id="RunAgentThread" num="12">
      <synopsis>Run Agent Thread</synopsis>
      <description>
        Starts the execution of an agent thread. with the specified native function.
        The parameter <paramlink id="arg"></paramlink> is forwarded on to the
        <functionlink id="jvmtiStartFunction">start function</functionlink>
        (specified with <paramlink id="proc"></paramlink>) 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 <code>java.lang.Thread</code> or
        implementer of <code>java.lang.Runnable</code>.
        Instead, the created thread can run entirely in native code.
        However, the created thread does require a newly created instance
        of <code>java.lang.Thread</code> (referenced by the argument <code>thread</code>) to
        which it will be associated.
        The thread object can be created with JNI calls.
        <p/>
        The following common thread priorities are provided for your convenience:
        <constants id="jvmtiThreadPriority" label="Thread Priority Constants" kind="const">
          <constant id="JVMTI_THREAD_MIN_PRIORITY" num="1">
            Minimum possible thread priority
          </constant>
          <constant id="JVMTI_THREAD_NORM_PRIORITY" num="5">
            Normal thread priority
          </constant>
          <constant id="JVMTI_THREAD_MAX_PRIORITY" num="10">
            Maximum possible thread priority
          </constant>
        </constants>
        <p/>
        The new thread is started as a daemon thread with the specified
        <paramlink id="priority"></paramlink>.
        If enabled, a <eventlink id="ThreadStart"/> event will be sent.
        <p/>
        Since the thread has been started, the thread will be live when this function
        returns, unless the thread has died immediately.
        <p/>
        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 <jvmti/> levels.
        <p/>
        The thread is not visible to Java programming language queries but is
        included in <jvmti/> queries (for example,
        <functionlink id="GetAllThreads"/> and
        <functionlink id="GetAllStackTraces"/>).
        <p/>
        Upon execution of <code>proc</code>, the new thread will be attached to the
        VM -- see the JNI documentation on
        <externallink id="jni/invocation.html#attaching-to-the-vm"
                      >Attaching to the VM</externallink>.
      </description>
      <origin>jvmdiClone</origin>
      <capabilities>
      </capabilities>
      <parameters>
        <param id="thread">
          <jthread impl="noconvert" started="no"/>
            <description>
              The thread to run.
            </description>
        </param>
        <param id="proc">
          <ptrtype>
            <struct>jvmtiStartFunction</struct>
          </ptrtype>
          <description>
            The start function.
          </description>
        </param>
        <param id="arg">
          <inbuf>
            <void/>
            <nullok><code>NULL</code> is passed to the start function</nullok>
          </inbuf>
          <description>
            The argument to the start function.
          </description>
        </param>
        <param id="priority">
          <jint/>
          <description>
            The priority of the started thread. Any thread
            priority allowed by <code>java.lang.Thread.setPriority</code> can be used including
            those in <datalink id="jvmtiThreadPriority"></datalink>.
          </description>
        </param>
      </parameters>
      <errors>
        <error id="JVMTI_ERROR_INVALID_PRIORITY">
            <paramlink id="priority"/> is less than
            <datalink id="JVMTI_THREAD_MIN_PRIORITY"/>
              or greater than
            <datalink id="JVMTI_THREAD_MAX_PRIORITY"/>
        </error>
      </errors>
    </function>

    <function id="SetThreadLocalStorage" jkernel="yes" impl="notrace" phase="start" num="103">
      <synopsis>Set Thread Local Storage</synopsis>
      <description>
        The VM stores a pointer value associated with each environment-thread
        pair. This pointer value is called <i>thread-local storage</i>.
        This value is <code>NULL</code> 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
        <functionlink id="GetThreadLocalStorage"></functionlink>.
        <p/>
        This function is called by the agent to set the value of the <jvmti/>
        thread-local storage. <jvmti/> supplies to the agent a pointer-size
        thread-local storage that can be used to record per-thread
        information.
      </description>
      <origin>jvmpi</origin>
      <capabilities>
      </capabilities>
      <parameters>
        <param id="thread">
          <jthread null="current"/>
            <description>
              Store to this thread.
            </description>
        </param>
        <param id="data">
          <inbuf>
            <void/>
            <nullok>value is set to <code>NULL</code></nullok>
          </inbuf>
          <description>
            The value to be entered into the thread-local storage.
          </description>
        </param>
      </parameters>
      <errors>
      </errors>
    </function>

    <function id="GetThreadLocalStorage" jkernel="yes" impl="innative notrace" phase="start" num="102">
      <synopsis>Get Thread Local Storage</synopsis>
      <description>
        Called by the agent to get the value of the <jvmti/> thread-local
        storage.
      </description>
      <origin>jvmpi</origin>
      <capabilities>
      </capabilities>
      <parameters>
        <param id="thread">
          <jthread null="current" impl="noconvert"/>
            <description>
              Retrieve from this thread.
            </description>
        </param>
        <param id="data_ptr">
          <agentbuf><void/></agentbuf>
          <description>
            Pointer through which the value of the thread local
            storage is returned.
            If thread-local storage has not been set with
            <functionlink id="SetThreadLocalStorage"></functionlink> the returned
            pointer is <code>NULL</code>.
          </description>
        </param>
      </parameters>
      <errors>
      </errors>
    </function>

  </category>

  <category id="thread_groups" label="Thread Group">
    <intro>
    </intro>

    <function id="GetTopThreadGroups" num="13">
      <synopsis>Get Top Thread Groups</synopsis>
      <description>
        Return all top-level (parentless) thread groups in the VM.
      </description>
      <origin>jvmdi</origin>
      <capabilities>
      </capabilities>
      <parameters>
        <param id="group_count_ptr">
          <outptr><jint/></outptr>
          <description>
            On return, points to the number of top-level thread groups.
          </description>
        </param>
        <param id="groups_ptr">
          <allocbuf outcount="group_count_ptr"><jthreadGroup/></allocbuf>
            <description>
              On return, refers to a pointer to the top-level thread group array.
            </description>
        </param>
      </parameters>
      <errors>
      </errors>
    </function>

    <function id="GetThreadGroupInfo" num="14">
      <synopsis>Get Thread Group Info</synopsis>
      <typedef id="jvmtiThreadGroupInfo" label="Thread group information structure">
        <field id="parent">
          <jthreadGroup/>
          <description>
            The parent thread group.
          </description>
        </field>
        <field id="name">
          <allocfieldbuf><char/></allocfieldbuf>
          <description>
            The thread group's name, encoded as a
            <internallink id="mUTF">modified UTF-8</internallink> string.
          </description>
        </field>
        <field id="max_priority">
          <jint/>
          <description>
            The maximum priority for this thread group.
          </description>
        </field>
        <field id="is_daemon">
          <jboolean/>
          <description>
            Is this a daemon thread group?
          </description>
        </field>
      </typedef>
      <description>
        Get information about the thread group. The fields of the
        <functionlink id="jvmtiThreadGroupInfo"></functionlink> structure
        are filled in with details of the specified thread group.
      </description>
      <origin>jvmdi</origin>
      <capabilities>
      </capabilities>
      <parameters>
        <param id="group">
          <jthreadGroup/>
          <description>
            The thread group to query.
          </description>
        </param>
        <param id="info_ptr">
          <outptr><struct>jvmtiThreadGroupInfo</struct></outptr>
          <description>
            On return, filled with information describing the specified
            thread group.
          </description>
        </param>
      </parameters>
      <errors>
      </errors>
    </function>

    <function id="GetThreadGroupChildren" num="15">
      <synopsis>Get Thread Group Children</synopsis>
      <description>
        Get the live threads and active subgroups in this thread group.
      </description>
      <origin>jvmdi</origin>
      <capabilities>
      </capabilities>
      <parameters>
        <param id="group">
          <jthreadGroup/>
          <description>
            The group to query.
          </description>
        </param>
        <param id="thread_count_ptr">
          <outptr><jint/></outptr>
          <description>
            On return, points to the number of live threads in this thread group.
          </description>
        </param>
        <param id="threads_ptr">
          <allocbuf outcount="thread_count_ptr"><jthread/></allocbuf>
            <description>
              On return, points to an array of the live threads in this thread group.
            </description>
        </param>
        <param id="group_count_ptr">
          <outptr><jint/></outptr>
          <description>
            On return, points to the number of active child thread groups
          </description>
        </param>
        <param id="groups_ptr">
          <allocbuf outcount="group_count_ptr"><jthreadGroup/></allocbuf>
            <description>
              On return, points to an array of the active child thread groups.
            </description>
        </param>
      </parameters>
      <errors>
      </errors>
    </function>
  </category>

  <category id="stack" label="Stack Frame">
    <intro>
        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.
        <p/>
        Stack frames are as described in
        <vmspec chapter="3.6"/>,
        That is, they correspond to method
        invocations (including native methods) but do not correspond to platform native or
        VM internal frames.
        <p/>
        A <jvmti/> 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 <code>main()</code> and <code>run()</code>.
        However this presentation must be consistent across all <jvmti/> functionality which
        uses stack frames or stack depth.
    </intro>

      <typedef id="jvmtiFrameInfo" label="Stack frame information structure">
        <description>
          Information about a stack frame is returned in this structure.
        </description>
        <field id="method">
          <jmethodID/>
            <description>
              The method executing in this frame.
            </description>
        </field>
        <field id="location">
          <jlocation/>
          <description>
            The index of the instruction executing in this frame.
            <code>-1</code> if the frame is executing a native method.
          </description>
        </field>
      </typedef>

      <typedef id="jvmtiStackInfo" label="Stack information structure">
        <description>
          Information about a set of stack frames is returned in this structure.
        </description>
        <field id="thread">
          <jthread/>
          <description>
            On return, the thread traced.
          </description>
        </field>
        <field id="state">
          <jint/>
          <description>
            On return, the thread state. See <functionlink id="GetThreadState"></functionlink>.
          </description>
        </field>
        <field id="frame_buffer">
          <outbuf incount="max_frame_count">
            <struct>jvmtiFrameInfo</struct>
          </outbuf>
            <description>
              On return, this agent allocated buffer is filled
              with stack frame information.
            </description>
        </field>
        <field id="frame_count">
          <jint/>
          <description>
            On return, the number of records filled into
            <code>frame_buffer</code>.
            This will be
            min(<code>max_frame_count</code>, <i>stackDepth</i>).
          </description>
        </field>
      </typedef>

    <function id="GetStackTrace" num="104">
      <synopsis>Get Stack Trace</synopsis>
      <description>
        Get information about the stack of a thread.
        If <paramlink id="max_frame_count"></paramlink> is less than the depth of the stack,
        the <paramlink id="max_frame_count"></paramlink> 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.
        <p/>
        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.
        <example>
jvmtiFrameInfo frames[5];
jint count;
jvmtiError err;

err = (*jvmti)-&gt;GetStackTrace(jvmti, aThread, 0, 5,
                               frames, &amp;count);
if (err == JVMTI_ERROR_NONE &amp;&amp; count &gt;= 1) {
   char *methodName;
   err = (*jvmti)-&gt;GetMethodName(jvmti, frames[0].method,
                       &amp;methodName, NULL, NULL);
   if (err == JVMTI_ERROR_NONE) {
      printf("Executing method: %s", methodName);
   }
}
        </example>
        <todo>
          check example code.
        </todo>
        <p/>
        The <paramlink id="thread"></paramlink> need not be suspended
        to call this function.
        <p/>
        The <functionlink id="GetLineNumberTable"></functionlink>
        function can be used to map locations to line numbers. Note that
        this mapping can be done lazily.
      </description>
      <origin>jvmpi</origin>
      <capabilities>
      </capabilities>
      <parameters>
        <param id="thread">
          <jthread null="current"/>
            <description>
              Fetch the stack trace of this thread.
            </description>
        </param>
        <param id="start_depth">
          <jint/>
          <description>
            Begin retrieving frames at this depth.
            If non-negative, count from the current frame,
            the first frame retrieved is at depth <code>start_depth</code>.
            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 <i>stackDepth</i><code> + start_depth</code>,
            where <i>stackDepth</i> 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.
          </description>
        </param>
        <param id="max_frame_count">
          <jint min="0"/>
          <description>
            The maximum number of <datalink id="jvmtiFrameInfo"/> records to retrieve.
          </description>
        </param>
        <param id="frame_buffer">
          <outbuf incount="max_frame_count" outcount="count_ptr">
            <struct>jvmtiFrameInfo</struct>
          </outbuf>
            <description>
              On return, this agent allocated buffer is filled
              with stack frame information.
            </description>
        </param>
        <param id="count_ptr">
          <outptr><jint/></outptr>
          <description>
            On return, points to the number of records filled in.
            For non-negative <code>start_depth</code>, this will be
            min(<code>max_frame_count</code>, <i>stackDepth</i><code> - start_depth</code>).
            For negative <code>start_depth</code>, this will be
            min(<code>max_frame_count</code>, <code>-start_depth</code>).
          </description>
        </param>
      </parameters>
      <errors>
        <error id="JVMTI_ERROR_ILLEGAL_ARGUMENT">
          <paramlink id="start_depth"/> is positive and greater than or equal to <i>stackDepth</i>.
          Or <paramlink id="start_depth"/> is negative and less than <i>-stackDepth</i>.
        </error>
      </errors>
    </function>


    <function id="GetAllStackTraces" num="100">
      <synopsis>Get All Stack Traces</synopsis>
      <description>
        Get information about the stacks of all live threads
        (including <internallink id="RunAgentThread">agent threads</internallink>).
        If <paramlink id="max_frame_count"/> is less than the depth of a stack,
        the <paramlink id="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.
        <p/>
        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.

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

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

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

      </description>
      <origin>new</origin>
      <capabilities>
      </capabilities>
      <parameters>
        <param id="max_frame_count">
          <jint min="0"/>
          <description>
            The maximum number of <datalink id="jvmtiFrameInfo"/> records to retrieve per thread.
          </description>
        </param>
        <param id="stack_info_ptr">
          <allocbuf>
            <struct>jvmtiStackInfo</struct>
          </allocbuf>
            <description>
              On return, this buffer is filled
              with stack information for each thread.
              The number of <datalink id="jvmtiStackInfo"/> records is determined
              by <paramlink id="thread_count_ptr"/>.
              <p/>
              Note that this buffer is allocated to include the <datalink id="jvmtiFrameInfo"/>
              buffers pointed to by <datalink id="jvmtiStackInfo.frame_buffer"/>.
              These buffers must not be separately deallocated.
            </description>
        </param>
        <param id="thread_count_ptr">
          <outptr><jint/></outptr>
          <description>
            The number of threads traced.
          </description>
        </param>
      </parameters>
      <errors>
      </errors>
    </function>

    <function id="GetThreadListStackTraces" num="101">
      <synopsis>Get Thread List Stack Traces</synopsis>
      <description>
        Get information about the stacks of the supplied threads.
        If <paramlink id="max_frame_count"/> is less than the depth of a stack,
        the <paramlink id="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.
        <p/>
        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.
        <p/>
        If a thread has not yet started or terminates before the stack information is collected,
        a zero length stack (<datalink id="jvmtiStackInfo.frame_count"/> will be zero)
        will be returned and the thread <datalink id="jvmtiStackInfo.state"/> can be checked.
        <p/>
        See the example for the similar function
        <functionlink id="GetAllStackTraces"/>.
      </description>
      <origin>new</origin>
      <capabilities>
      </capabilities>
      <parameters>
        <param id="thread_count">
          <jint min="0"/>
          <description>
            The number of threads to trace.
          </description>
        </param>
        <param id="thread_list">
          <inbuf incount="thread_count"><jthread/></inbuf>
            <description>
              The list of threads to trace.
            </description>
        </param>
        <param id="max_frame_count">
          <jint min="0"/>
          <description>
            The maximum number of <datalink id="jvmtiFrameInfo"/> records to retrieve per thread.
          </description>
        </param>
        <param id="stack_info_ptr">
          <allocbuf outcount="thread_count">
            <struct>jvmtiStackInfo</struct>
          </allocbuf>
            <description>
              On return, this buffer is filled
              with stack information for each thread.
              The number of <datalink id="jvmtiStackInfo"/> records is determined
              by <paramlink id="thread_count"/>.
              <p/>
              Note that this buffer is allocated to include the <datalink id="jvmtiFrameInfo"/>
              buffers pointed to by <datalink id="jvmtiStackInfo.frame_buffer"/>.
              These buffers must not be separately deallocated.
            </description>
        </param>
      </parameters>
      <errors>
        <error id="JVMTI_ERROR_INVALID_THREAD">
          An element in <paramlink id="thread_list"/> is not a thread object.
        </error>
      </errors>
    </function>

    <elide>
    <function id="AsyncGetStackTrace" num="1000">
      <synopsis>Get Stack Trace--Asynchronous</synopsis>
      <description>
        Get information about the entire stack of a thread (or a sub-section of it).
        This is the asynchronous version of <functionlink id="GetStackTrace"></functionlink>
        and is reentrant and safe to call
        from asynchronous signal handlers.
        The stack trace is returned only for the calling thread.
        <p/>
        The <functionlink id="GetLineNumberTable"></functionlink>
        function can be used to map locations to line numbers. Note that
        this mapping can be done lazily.
      </description>
      <origin>jvmpi</origin>
      <capabilities>
        <required id="can_get_async_stack_trace"></required>
        <capability id="can_show_JVM_spec_async_frames">
          If <code>false</code>,
          <paramlink id="use_java_stack"></paramlink>
          must be <code>false</code>.
        </capability>
      </capabilities>
      <parameters>
        <param id="use_java_stack">
          <jboolean/>
          <description>
            Return the stack showing <vmspec/>
            model of the stack;
            otherwise, show the internal representation of the stack with
            inlined and optimized methods missing.  If the virtual machine
            is using the <i>Java Virtual Machine Specification</i> stack model
            internally, this flag is ignored.
          </description>
        </param>
        <param id="max_count">
          <jint min="0"/>
          <description>
            The maximum number of <datalink id="jvmtiFrameInfo"/> records to retrieve.
            Retrieve this many unless the stack depth is less than <code>max_count</code>.
          </description>
        </param>
        <param id="frame_buffer">
          <outbuf incount="max_count" outcount="count_ptr">
            <struct>jvmtiFrameInfo</struct>
            <nullok>this information is not returned</nullok>
          </outbuf>
            <description>
              The agent passes in a buffer
              large enough to hold <code>max_count</code> records of
              <datalink id="jvmtiFrameInfo"></datalink>.  This buffer must be
              pre-allocated by the agent.
            </description>
        </param>
        <param id="count_ptr">
          <outptr><jint/></outptr>
          <description>
            On return, points to the number of records filled in..
          </description>
        </param>
      </parameters>
      <errors>
        <error id="JVMTI_ERROR_UNATTACHED_THREAD">
          The thread being used to call this function is not attached
          to the virtual machine.  Calls must be made from attached threads.
        </error>
      </errors>
    </function>
    </elide>

    <function id="GetFrameCount" num="16">
      <synopsis>Get Frame Count</synopsis>
      <description>
        Get the number of frames currently in the specified thread's call stack.
        <p/>
        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.
      </description>
      <origin>jvmdi</origin>
      <capabilities>
      </capabilities>
      <parameters>
        <param id="thread">
          <jthread null="current"/>
            <description>
              The thread to query.
            </description>
        </param>
        <param id="count_ptr">
          <outptr><jint/></outptr>
          <description>
            On return, points to the number of frames in the call stack.
          </description>
        </param>
      </parameters>
      <errors>
      </errors>
    </function>

    <function id="PopFrame" num="80">
      <synopsis>Pop Frame</synopsis>
      <description>
        Pop the current frame of <code>thread</code>'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 <vmspec/> terminology):
          <ul>
            <li>the current frame is discarded as the previous frame becomes the current one</li>
            <li>the operand stack is restored--the argument values are added back
              and if the invoke was not <code>invokestatic</code>,
              <code>objectref</code> is added back as well</li>
            <li>the Java virtual machine PC is restored to the opcode
              of the invoke instruction</li>
          </ul>
        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.
        <p/>
        Between calling <code>PopFrame</code> and resuming the
        thread the state of the stack is undefined.
        To pop frames beyond the first,
        these three steps must be repeated:
        <ul>
          <li>suspend the thread via an event (step, breakpoint, ...)</li>
          <li>call <code>PopFrame</code></li>
          <li>resume the thread</li>
        </ul>
        <p/>
        A lock acquired by calling the called method
        (if it is a <code>synchronized</code>  method)
        and locks acquired by entering <code>synchronized</code>
        blocks within the called method are released.
        Note: this does not apply to native locks or
        <code>java.util.concurrent.locks</code> locks.
        <p/>
        Finally blocks are not executed.
        <p/>
        Changes to global state are not addressed and thus remain changed.
        <p/>
        The specified thread must be suspended or must be the current thread.
        <p/>
        Both the called method and calling method must be non-native Java programming
        language methods.
        <p/>
        No <jvmti/> events are generated by this function.
      </description>
      <origin>jvmdi</origin>
      <capabilities>
        <required id="can_pop_frame"></required>
      </capabilities>
      <parameters>
        <param id="thread">
          <jthread/>
            <description>
              The thread whose current frame is to be popped.
            </description>
        </param>
      </parameters>
      <errors>
        <error id="JVMTI_ERROR_OPAQUE_FRAME">
          Called or calling method is a native method.
          The implementation is unable to pop this frame.
        </error>
        <error id="JVMTI_ERROR_THREAD_NOT_SUSPENDED">
          Thread was not suspended and was not the current thread.
        </error>
        <error id="JVMTI_ERROR_NO_MORE_FRAMES">
          There are less than two stack frames on the call stack.
        </error>
      </errors>
    </function>

    <function id="GetFrameLocation" num="19">
      <synopsis>Get Frame Location</synopsis>
      <description>
        <p/>
        For a Java programming language frame, return the location of the instruction
        currently executing.
      </description>
      <origin>jvmdiClone</origin>
      <capabilities>
      </capabilities>
      <parameters>
        <param id="thread">
          <jthread null="current" frame="frame"/>
          <description>
            The thread of the frame to query.
          </description>
        </param>
        <param id="depth">
          <jframeID thread="thread"/>
          <description>
            The depth of the frame to query.
          </description>
        </param>
        <param id="method_ptr">
          <outptr><jmethodID/></outptr>
            <description>
              On return, points to the method for the current location.
            </description>
        </param>
        <param id="location_ptr">
          <outptr><jlocation/></outptr>
          <description>
            On return, points to the index of the currently
            executing instruction.
            Is set to <code>-1</code> if the frame is executing
            a native method.
          </description>
        </param>
      </parameters>
      <errors>
      </errors>
    </function>

    <function id="NotifyFramePop" num="20">
      <synopsis>Notify Frame Pop</synopsis>
      <description>
        When the frame that is currently at <paramlink id="depth"></paramlink>
        is popped from the stack, generate a
        <eventlink id="FramePop"></eventlink> event.  See the
        <eventlink id="FramePop"></eventlink> event for details.
        Only frames corresponding to non-native Java programming language
        methods can receive notification.
        <p/>
        The specified thread must be suspended or must be the current thread.
      </description>
      <origin>jvmdi</origin>
      <capabilities>
        <required id="can_generate_frame_pop_events"></required>
      </capabilities>
      <parameters>
        <param id="thread">
          <jthread null="current" frame="depth"/>
          <description>
            The thread of the frame for which the frame pop event will be generated.
          </description>
        </param>
        <param id="depth">
          <jframeID thread="thread"/>
          <description>
            The depth of the frame for which the frame pop event will be generated.
          </description>
        </param>
      </parameters>
      <errors>
        <error id="JVMTI_ERROR_OPAQUE_FRAME">
          The frame at <code>depth</code> is executing a
          native method.
        </error>
        <error id="JVMTI_ERROR_THREAD_NOT_SUSPENDED">
          Thread was not suspended and was not the current thread.
        </error>
      </errors>
    </function>

  </category>

  <category id="ForceEarlyReturn" label="Force Early Return">
    <intro>
      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 <i>called method</i>.
      The called method is the current method
      (as defined by
      <vmspec chapter="3.6"/>)
      for the specified thread at
      the time the function is called.
      <p/>
      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.
      <p/>
      No further instructions are executed in the called method.
      Specifically, finally blocks are not executed.
      Note: this can cause inconsistent states in the application.
      <p/>
      A lock acquired by calling the called method
      (if it is a <code>synchronized</code>  method)
      and locks acquired by entering <code>synchronized</code>
      blocks within the called method are released.
      Note: this does not apply to native locks or
      <code>java.util.concurrent.locks</code> locks.
      <p/>
      Events, such as <eventlink id="MethodExit"></eventlink>,
      are generated as they would be in a normal return.
      <p/>
      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.
    </intro>

    <function id="ForceEarlyReturnObject" num="81" since="1.1">
      <synopsis>Force Early Return - Object</synopsis>
      <description>
        This function can be used to return from a method whose
        result type is <code>Object</code>
        or a subclass of <code>Object</code>.
      </description>
      <origin>new</origin>
      <capabilities>
        <required id="can_force_early_return"></required>
      </capabilities>
      <parameters>
        <param id="thread">
          <jthread null="current"/>
          <description>
            The thread whose current frame is to return early.
          </description>
        </param>
        <param id="value">
          <jobject/>
          <description>
            The return value for the called frame.
            An object or <code>NULL</code>.
          </description>
        </param>
      </parameters>
      <errors>
        <error id="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.
        </error>
        <error id="JVMTI_ERROR_TYPE_MISMATCH">
          The result type of the called method is not
          <code>Object</code> or a subclass of <code>Object</code>.
        </error>
        <error id="JVMTI_ERROR_TYPE_MISMATCH">
          The supplied <paramlink id="value"/> is not compatible with the
          result type of the called method.
        </error>
        <error id="JVMTI_ERROR_THREAD_NOT_SUSPENDED">
          Thread was not suspended and was not the current thread.
        </error>
        <error id="JVMTI_ERROR_NO_MORE_FRAMES">
          There are no more frames on the call stack.
        </error>
      </errors>
    </function>

    <function id="ForceEarlyReturnInt" num="82" since="1.1">
      <synopsis>Force Early Return - Int</synopsis>
      <description>
        This function can be used to return from a method whose
        result type is <code>int</code>, <code>short</code>,
        <code>char</code>, <code>byte</code>, or
        <code>boolean</code>.
      </description>
      <origin>new</origin>
      <capabilities>
        <required id="can_force_early_return"></required>
      </capabilities>
      <parameters>
        <param id="thread">
          <jthread null="current"/>
          <description>
            The thread whose current frame is to return early.
          </description>
        </param>
        <param id="value">
          <jint/>
          <description>
            The return value for the called frame.
          </description>
        </param>
      </parameters>
      <errors>
        <error id="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.
        </error>
        <error id="JVMTI_ERROR_TYPE_MISMATCH">
          The result type of the called method is not
          <code>int</code>, <code>short</code>,
          <code>char</code>, <code>byte</code>, or
          <code>boolean</code>.
        </error>
        <error id="JVMTI_ERROR_THREAD_NOT_SUSPENDED">
          Thread was not suspended and was not the current thread.
        </error>
        <error id="JVMTI_ERROR_NO_MORE_FRAMES">
          There are no frames on the call stack.
        </error>
      </errors>
    </function>

    <function id="ForceEarlyReturnLong" num="83" since="1.1">
      <synopsis>Force Early Return - Long</synopsis>
      <description>
        This function can be used to return from a method whose
        result type is <code>long</code>.
      </description>
      <origin>new</origin>
      <capabilities>
        <required id="can_force_early_return"></required>
      </capabilities>
      <parameters>
        <param id="thread">
          <jthread null="current"/>
          <description>
            The thread whose current frame is to return early.
          </description>
        </param>
        <param id="value">
          <jlong/>
          <description>
            The return value for the called frame.
          </description>
        </param>
      </parameters>
      <errors>
        <error id="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.
        </error>
        <error id="JVMTI_ERROR_TYPE_MISMATCH">
          The result type of the called method is not <code>long</code>.
        </error>
        <error id="JVMTI_ERROR_THREAD_NOT_SUSPENDED">
          Thread was not suspended and was not the current thread.
        </error>
        <error id="JVMTI_ERROR_NO_MORE_FRAMES">
          There are no frames on the call stack.
        </error>
      </errors>
    </function>

    <function id="ForceEarlyReturnFloat" num="84" since="1.1">
      <synopsis>Force Early Return - Float</synopsis>
      <description>
        This function can be used to return from a method whose
        result type is <code>float</code>.
      </description>
      <origin>new</origin>
      <capabilities>
        <required id="can_force_early_return"></required>
      </capabilities>
      <parameters>
        <param id="thread">
          <jthread null="current"/>
          <description>
            The thread whose current frame is to return early.
          </description>
        </param>
        <param id="value">
          <jfloat/>
          <description>
            The return value for the called frame.
          </description>
        </param>
      </parameters>
      <errors>
        <error id="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.
        </error>
        <error id="JVMTI_ERROR_TYPE_MISMATCH">
          The result type of the called method is not <code>float</code>.
        </error>
        <error id="JVMTI_ERROR_THREAD_NOT_SUSPENDED">
          Thread was not suspended and was not the current thread.
        </error>
        <error id="JVMTI_ERROR_NO_MORE_FRAMES">
          There are no frames on the call stack.
        </error>
      </errors>
    </function>

    <function id="ForceEarlyReturnDouble" num="85" since="1.1">
      <synopsis>Force Early Return - Double</synopsis>
      <description>
        This function can be used to return from a method whose
        result type is <code>double</code>.
      </description>
      <origin>new</origin>
      <capabilities>
        <required id="can_force_early_return"></required>
      </capabilities>
      <parameters>
        <param id="thread">
          <jthread null="current"/>
          <description>
            The thread whose current frame is to return early.
          </description>
        </param>
        <param id="value">
          <jdouble/>
          <description>
            The return value for the called frame.
          </description>
        </param>
      </parameters>
      <errors>
        <error id="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.
        </error>
        <error id="JVMTI_ERROR_TYPE_MISMATCH">
          The result type of the called method is not <code>double</code>.
        </error>
        <error id="JVMTI_ERROR_THREAD_NOT_SUSPENDED">
          Thread was not suspended and was not the current thread.
        </error>
        <error id="JVMTI_ERROR_NO_MORE_FRAMES">
          There are no frames on the call stack.
        </error>
      </errors>
    </function>

    <function id="ForceEarlyReturnVoid" num="86" since="1.1">
      <synopsis>Force Early Return - Void</synopsis>
      <description>
        This function can be used to return from a method with no result type.
        That is, the called method must be declared <code>void</code>.
      </description>
      <origin>new</origin>
      <capabilities>
        <required id="can_force_early_return"></required>
      </capabilities>
      <parameters>
        <param id="thread">
          <jthread null="current"/>
          <description>
            The thread whose current frame is to return early.
          </description>
        </param>
      </parameters>
      <errors>
        <error id="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.
        </error>
        <error id="JVMTI_ERROR_TYPE_MISMATCH">
          The called method has a result type.
        </error>
        <error id="JVMTI_ERROR_THREAD_NOT_SUSPENDED">
          Thread was not suspended and was not the current thread.
        </error>
        <error id="JVMTI_ERROR_NO_MORE_FRAMES">
          There are no frames on the call stack.
        </error>
      </errors>
    </function>

  </category>

  <category id="Heap" label="Heap">
    <intro>
      These functions are used to analyze the heap.
      Functionality includes the ability to view the objects in the
      heap and to tag these objects.
    </intro>

    <intro id="objectTags" label="Object Tags">
      A <i>tag</i> is a value associated with an object.
      Tags are explicitly set by the agent using the
      <functionlink id="SetTag"></functionlink> function or by
      callback functions such as <functionlink id="jvmtiHeapIterationCallback"/>.
      <p/>
      Tags are local to the environment; that is, the tags of one
      environment are not visible in another.
      <p/>
      Tags are <code>jlong</code> 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.
    </intro>

    <intro id="heapCallbacks" label="Heap Callback Functions">
        Heap functions which iterate through the heap and recursively
        follow object references use agent supplied callback functions
        to deliver the information.
        <p/>
        These heap callback functions must adhere to the following restrictions --
        These callbacks must not use JNI functions.
        These callbacks must not use <jvmti/> functions except
        <i>callback safe</i> functions which
        specifically allow such use (see the raw monitor, memory management,
        and environment local storage functions).
        <p/>
        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.
        <p/>
        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 <code>jint</code> is zero), objects
        will not be filtered out.

        <constants id="jvmtiHeapFilter" label="Heap Filter Flags" kind="bits">
          <constant id="JVMTI_HEAP_FILTER_TAGGED" num="0x4">
            Filter out tagged objects. Objects which are tagged are not included.
          </constant>
          <constant id="JVMTI_HEAP_FILTER_UNTAGGED" num="0x8">
            Filter out untagged objects. Objects which are not tagged are not included.
          </constant>
          <constant id="JVMTI_HEAP_FILTER_CLASS_TAGGED" num="0x10">
            Filter out objects with tagged classes. Objects whose class is tagged are not included.
          </constant>
          <constant id="JVMTI_HEAP_FILTER_CLASS_UNTAGGED" num="0x20">
            Filter out objects with untagged classes. Objects whose class is not tagged are not included.
          </constant>
        </constants>

        <p/>
        The Heap Visit Control Flags are returned by the heap callbacks
        and can be used to abort the iteration.  For the
        <functionlink id="jvmtiHeapReferenceCallback">Heap
        Reference Callback</functionlink>, it can also be used
        to prune the graph of traversed references
        (<code>JVMTI_VISIT_OBJECTS</code> is not set).

        <constants id="jvmtiHeapVisitControl"
                   label="Heap Visit Control Flags"
                   kind="bits"
                   since="1.1">
          <constant id="JVMTI_VISIT_OBJECTS" num="0x100">
            If we are visiting an object and if this callback
            was initiated by <functionlink id="FollowReferences"/>,
            traverse the references of this object.
            Otherwise ignored.
          </constant>
          <constant id="JVMTI_VISIT_ABORT" num="0x8000">
            Abort the iteration.  Ignore all other bits.
          </constant>
        </constants>

        <p/>
        The Heap Reference Enumeration is provided by the
        <functionlink id="jvmtiHeapReferenceCallback">Heap
        Reference Callback</functionlink> and
        <functionlink id="jvmtiPrimitiveFieldCallback">Primitive Field
        Callback</functionlink> to
        describe the kind of reference
        being reported.

        <constants id="jvmtiHeapReferenceKind"
                   label="Heap Reference Enumeration"
                   kind="enum"
                   since="1.1">
          <constant id="JVMTI_HEAP_REFERENCE_CLASS" num="1">
            Reference from an object to its class.
          </constant>
          <constant id="JVMTI_HEAP_REFERENCE_FIELD" num="2">
            Reference from an object to the value of one of its instance fields.
          </constant>
          <constant id="JVMTI_HEAP_REFERENCE_ARRAY_ELEMENT" num="3">
            Reference from an array to one of its elements.
          </constant>
          <constant id="JVMTI_HEAP_REFERENCE_CLASS_LOADER" num="4">
            Reference from a class to its class loader.
          </constant>
          <constant id="JVMTI_HEAP_REFERENCE_SIGNERS" num="5">
            Reference from a class to its signers array.
          </constant>
          <constant id="JVMTI_HEAP_REFERENCE_PROTECTION_DOMAIN" num="6">
            Reference from a class to its protection domain.
          </constant>
          <constant id="JVMTI_HEAP_REFERENCE_INTERFACE" num="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
            <code>JVMTI_HEAP_REFERENCE_CONSTANT_POOL</code> reference kind.
          </constant>
          <constant id="JVMTI_HEAP_REFERENCE_STATIC_FIELD" num="8">
            Reference from a class to the value of one of its static fields.
          </constant>
          <constant id="JVMTI_HEAP_REFERENCE_CONSTANT_POOL" num="9">
            Reference from a class to a resolved entry in the constant pool.
          </constant>
          <constant id="JVMTI_HEAP_REFERENCE_SUPERCLASS" num="10">
            Reference from a class to its superclass.
            A callback is not sent if the superclass is <code>java.lang.Object</code>.
            Note: loaded classes define superclasses via a constant pool
            reference, so the referenced superclass may also be reported with
            a <code>JVMTI_HEAP_REFERENCE_CONSTANT_POOL</code> reference kind.
          </constant>
          <constant id="JVMTI_HEAP_REFERENCE_JNI_GLOBAL" num="21">
            Heap root reference: JNI global reference.
          </constant>
          <constant id="JVMTI_HEAP_REFERENCE_SYSTEM_CLASS" num="22">
            Heap root reference: System class.
          </constant>
          <constant id="JVMTI_HEAP_REFERENCE_MONITOR" num="23">
            Heap root reference: monitor.
          </constant>
          <constant id="JVMTI_HEAP_REFERENCE_STACK_LOCAL" num="24">
            Heap root reference: local variable on the stack.
          </constant>
          <constant id="JVMTI_HEAP_REFERENCE_JNI_LOCAL" num="25">
            Heap root reference: JNI local reference.
          </constant>
          <constant id="JVMTI_HEAP_REFERENCE_THREAD" num="26">
            Heap root reference: Thread.
          </constant>
          <constant id="JVMTI_HEAP_REFERENCE_OTHER" num="27">
            Heap root reference: other heap root reference.
          </constant>
        </constants>

        <p/>
        Definitions for the single character type descriptors of
        primitive types.

        <constants id="jvmtiPrimitiveType"
                   label="Primitive Type Enumeration"
                   kind="enum"
                   since="1.1">
          <constant id="JVMTI_PRIMITIVE_TYPE_BOOLEAN" num="90">
            'Z' - Java programming language <code>boolean</code> - JNI <code>jboolean</code>
          </constant>
          <constant id="JVMTI_PRIMITIVE_TYPE_BYTE" num="66">
            'B' - Java programming language <code>byte</code> - JNI <code>jbyte</code>
          </constant>
          <constant id="JVMTI_PRIMITIVE_TYPE_CHAR" num="67">
            'C' - Java programming language <code>char</code> - JNI <code>jchar</code>
          </constant>
          <constant id="JVMTI_PRIMITIVE_TYPE_SHORT" num="83">
            'S' - Java programming language <code>short</code> - JNI <code>jshort</code>
          </constant>
          <constant id="JVMTI_PRIMITIVE_TYPE_INT" num="73">
            'I' - Java programming language <code>int</code> - JNI <code>jint</code>
          </constant>
          <constant id="JVMTI_PRIMITIVE_TYPE_LONG" num="74">
            'J' - Java programming language <code>long</code> - JNI <code>jlong</code>
          </constant>
          <constant id="JVMTI_PRIMITIVE_TYPE_FLOAT" num="70">
            'F' - Java programming language <code>float</code> - JNI <code>jfloat</code>
          </constant>
          <constant id="JVMTI_PRIMITIVE_TYPE_DOUBLE" num="68">
            'D' - Java programming language <code>double</code> - JNI <code>jdouble</code>
          </constant>
        </constants>
    </intro>

      <typedef id="jvmtiHeapReferenceInfoField"
               label="Reference information structure for Field references"
               since="1.1">
        <description>
          Reference information returned for
          <datalink id="JVMTI_HEAP_REFERENCE_FIELD"/> and
          <datalink id="JVMTI_HEAP_REFERENCE_STATIC_FIELD"/> references.
        </description>
        <field id="index">
          <jint/>
          <description>
            For <datalink id="JVMTI_HEAP_REFERENCE_FIELD"/>, the
            referrer object is not a class or an interface.
            In this case, <code>index</code> is the index of the field
            in the class of the referrer object.
            This class is referred to below as <i>C</i>.
            <p/>
            For <datalink id="JVMTI_HEAP_REFERENCE_STATIC_FIELD"/>,
            the referrer object is a class (referred to below as <i>C</i>)
            or an interface (referred to below as <i>I</i>).
            In this case, <code>index</code> is the index of the field in
            that class or interface.
            <p/>
            If the referrer object is not an interface, then the field
            indices are determined as follows:
            <ul>
              <li>make a list of all the fields in <i>C</i> and its
                  superclasses, starting with all the fields in
                  <code>java.lang.Object</code> and ending with all the
                  fields in <i>C</i>.</li>
              <li>Within this list, put
                  the fields for a given class in the order returned by
                  <functionlink id="GetClassFields"/>.</li>
              <li>Assign the fields in this list indices
                  <i>n</i>, <i>n</i>+1, ..., in order, where <i>n</i>
                  is the count of the fields in all the interfaces
                  implemented by <i>C</i>.
                  Note that <i>C</i> implements all interfaces
                  directly implemented by its superclasses; as well
                  as all superinterfaces of these interfaces.</li>
            </ul>
            If the referrer object is an interface, then the field
            indices are determined as follows:
            <ul>
              <li>make a list of the fields directly declared in
                  <i>I</i>.</li>
              <li>Within this list, put
                  the fields in the order returned by
                  <functionlink id="GetClassFields"/>.</li>
              <li>Assign the fields in this list indices
                  <i>n</i>, <i>n</i>+1, ..., in order, where <i>n</i>
                  is the count of the fields in all the superinterfaces
                  of <i>I</i>.</li>
            </ul>
            All fields are included in this computation, regardless of
            field modifier (static, public, private, etc).
            <p/>
            For example, given the following classes and interfaces:
            <example>
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;
}
            </example>
            Assume that <functionlink id="GetClassFields"/> called on
            <code>C1</code> returns the fields of <code>C1</code> in the
            order: a, b; and that the fields of <code>C2</code> are
            returned in the order: q, r.
            An instance of class <code>C1</code> will have the
            following field indices:
            <blockquote><table>
              <tr class="bgLight">
                <th class="centered" scope="col">Field</th>
                <th class="centered" scope="col">Index</th>
                <th scope="col">Description</th>
              </tr>
              <tr>
                <th class="centered" scope="row">
                  a
                </th>
                <td class="centered">
                  2
                </td>
                <td>
                  The count of the fields in the interfaces
                  implemented by <code>C1</code> is two (<i>n</i>=2):
                  <code>p</code> of <code>I0</code>
                  and <code>x</code> of <code>I1</code>.
                </td>
              </tr>
              <tr>
                <th class="centered" scope="row">
                  b
                </th>
                <td class="centered">
                  3
                </td>
                <td>
                  the subsequent index.
                </td>
              </tr>
            </table></blockquote>
            The class <code>C1</code> will have the same field indices.
            <p/>
            An instance of class <code>C2</code> will have the
            following field indices:
            <blockquote><table>
              <tr class="bgLight">
                <th class="centered" scope="col">Field</th>
                <th class="centered" scope="col">Index</th>
                <th scope="col">Description</th>
              </tr>
              <tr>
                <th class="centered" scope="row">
                  a
                </th>
                <td class="centered">
                  3
                </td>
                <td>
                  The count of the fields in the interfaces
                  implemented by <code>C2</code> is three (<i>n</i>=3):
                  <code>p</code> of <code>I0</code>,
                  <code>x</code> of <code>I1</code> and <code>y</code> of <code>I2</code>
                  (an interface of <code>C2</code>).  Note that the field <code>p</code>
                  of <code>I0</code> is only included once.
                </td>
              </tr>
              <tr>
                <th class="centered" scope="row">
                  b
                </th>
                <td class="centered">
                  4
                </td>
                <td>
                  the subsequent index to "a".
                </td>
              </tr>
              <tr>
                <th class="centered" scope="row">
                  q
                </th>
                <td class="centered">
                  5
                </td>
                <td>
                  the subsequent index to "b".
                </td>
              </tr>
              <tr>
                <th class="centered" scope="row">
                  r
                </th>
                <td class="centered">
                  6
                </td>
                <td>
                  the subsequent index to "q".
                </td>
              </tr>
            </table></blockquote>
            The class <code>C2</code> 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.
            <p/>
            The interface <code>I1</code> will have the
            following field indices:
            <blockquote><table>
              <tr class="bgLight">
                <th class="centered" scope="col">Field</th>
                <th class="centered" scope="col">Index</th>
                <th scope="col">Description</th>
              </tr>
              <tr>
                <th class="centered" scope="row">
                  x
                </th>
                <td class="centered">
                  1
                </td>
                <td>
                  The count of the fields in the superinterfaces
                  of <code>I1</code> is one (<i>n</i>=1):
                  <code>p</code> of <code>I0</code>.
                </td>
              </tr>
            </table></blockquote>
          </description>
        </field>
      </typedef>

      <typedef id="jvmtiHeapReferenceInfoArray"
               label="Reference information structure for Array references"
               since="1.1">
        <description>
          Reference information returned for
         <datalink id="JVMTI_HEAP_REFERENCE_ARRAY_ELEMENT"/> references.
        </description>
        <field id="index">
          <jint/>
          <description>
            The array index.
          </description>
        </field>
      </typedef>

      <typedef id="jvmtiHeapReferenceInfoConstantPool"
               label="Reference information structure for Constant Pool references"
               since="1.1">
        <description>
          Reference information returned for
          <datalink id="JVMTI_HEAP_REFERENCE_CONSTANT_POOL"/> references.
        </description>
        <field id="index">
          <jint/>
          <description>
            The index into the constant pool of the class. See the description in
      <vmspec chapter="4.4"/>.
          </description>
        </field>
      </typedef>

      <typedef id="jvmtiHeapReferenceInfoStackLocal"
               label="Reference information structure for Local Variable references"
               since="1.1">
        <description>
          Reference information returned for
          <datalink id="JVMTI_HEAP_REFERENCE_STACK_LOCAL"/> references.
        </description>
        <field id="thread_tag">
          <jlong/>
          <description>
            The tag of the thread corresponding to this stack, zero if not tagged.
          </description>
        </field>
        <field id="thread_id">
          <jlong/>
          <description>
            The unique thread ID of the thread corresponding to this stack.
          </description>
        </field>
        <field id="depth">
          <jint/>
          <description>
            The depth of the frame.
          </description>
        </field>
        <field id="method">
          <jmethodID/>
          <description>
            The method executing in this frame.
          </description>
        </field>
        <field id="location">
          <jlocation/>
          <description>
            The currently executing location in this frame.
          </description>
        </field>
        <field id="slot">
          <jint/>
          <description>
            The slot number of the local variable.
          </description>
        </field>
      </typedef>

      <typedef id="jvmtiHeapReferenceInfoJniLocal"
               label="Reference information structure for JNI local references"
               since="1.1">
        <description>
          Reference information returned for
          <datalink id="JVMTI_HEAP_REFERENCE_JNI_LOCAL"/> references.
        </description>
        <field id="thread_tag">
          <jlong/>
          <description>
            The tag of the thread corresponding to this stack, zero if not tagged.
          </description>
        </field>
        <field id="thread_id">
          <jlong/>
          <description>
            The unique thread ID of the thread corresponding to this stack.
          </description>
        </field>
        <field id="depth">
          <jint/>
          <description>
            The depth of the frame.
          </description>
        </field>
        <field id="method">
          <jmethodID/>
          <description>
            The method executing in this frame.
          </description>
        </field>
      </typedef>

      <typedef id="jvmtiHeapReferenceInfoReserved"
               label="Reference information structure for Other references"
               since="1.1">
        <description>
          Reference information returned for other references.
        </description>
        <field id="reserved1">
          <jlong/>
          <description>
            reserved for future use.
          </description>
        </field>
        <field id="reserved2">
          <jlong/>
          <description>
            reserved for future use.
          </description>
        </field>
        <field id="reserved3">
          <jlong/>
          <description>
            reserved for future use.
          </description>
        </field>
        <field id="reserved4">
          <jlong/>
          <description>
            reserved for future use.
          </description>
        </field>
        <field id="reserved5">
          <jlong/>
          <description>
            reserved for future use.
          </description>
        </field>
        <field id="reserved6">
          <jlong/>
          <description>
            reserved for future use.
          </description>
        </field>
        <field id="reserved7">
          <jlong/>
          <description>
            reserved for future use.
          </description>
        </field>
        <field id="reserved8">
          <jlong/>
          <description>
            reserved for future use.
          </description>
        </field>
      </typedef>

      <uniontypedef id="jvmtiHeapReferenceInfo"
               label="Reference information structure"
               since="1.1">
        <description>
          The information returned about referrers.
          Represented as a union of the various kinds of reference information.
        </description>
        <field id="field">
          <struct>jvmtiHeapReferenceInfoField</struct>
          <description>
            The referrer information for
            <datalink id="JVMTI_HEAP_REFERENCE_FIELD"/>
            and <datalink id="JVMTI_HEAP_REFERENCE_STATIC_FIELD"/> references.
          </description>
        </field>
        <field id="array">
          <struct>jvmtiHeapReferenceInfoArray</struct>
          <description>
            The referrer information for
            For <datalink id="JVMTI_HEAP_REFERENCE_ARRAY_ELEMENT"/> references.
          </description>
        </field>
        <field id="constant_pool">
          <struct>jvmtiHeapReferenceInfoConstantPool</struct>
          <description>
            The referrer information for
            For <datalink id="JVMTI_HEAP_REFERENCE_CONSTANT_POOL"/> references.
          </description>
        </field>
        <field id="stack_local">
          <struct>jvmtiHeapReferenceInfoStackLocal</struct>
          <description>
            The referrer information for
            For <datalink id="JVMTI_HEAP_REFERENCE_STACK_LOCAL"/> references.
          </description>
        </field>
        <field id="jni_local">
          <struct>jvmtiHeapReferenceInfoJniLocal</struct>
          <description>
            The referrer information for
            For <datalink id="JVMTI_HEAP_REFERENCE_JNI_LOCAL"/> references.
          </description>
        </field>
        <field id="other">
          <struct>jvmtiHeapReferenceInfoReserved</struct>
          <description>
            reserved for future use.
          </description>
        </field>
      </uniontypedef>

      <typedef id="jvmtiHeapCallbacks"
               label="Heap callback function structure"
               since="1.1">
        <field id="heap_iteration_callback">
          <ptrtype>
            <struct>jvmtiHeapIterationCallback</struct>
          </ptrtype>
          <description>
            The callback to be called to describe an
            object in the heap. Used by the
            <functionlink id="IterateThroughHeap"/> function, ignored by the
            <functionlink id="FollowReferences"/> function.
          </description>
        </field>
        <field id="heap_reference_callback">
          <ptrtype>
            <struct>jvmtiHeapReferenceCallback</struct>
          </ptrtype>
          <description>
            The callback to be called to describe an
            object reference.  Used by the
            <functionlink id="FollowReferences"/> function, ignored by the
            <functionlink id="IterateThroughHeap"/> function.
          </description>
        </field>
        <field id="primitive_field_callback">
          <ptrtype>
            <struct>jvmtiPrimitiveFieldCallback</struct>
          </ptrtype>
          <description>
            The callback to be called to describe a
            primitive field.
          </description>
        </field>
        <field id="array_primitive_value_callback">
          <ptrtype>
            <struct>jvmtiArrayPrimitiveValueCallback</struct>
          </ptrtype>
          <description>
            The callback to be called to describe an
            array of primitive values.
          </description>
        </field>
        <field id="string_primitive_value_callback">
          <ptrtype>
            <struct>jvmtiStringPrimitiveValueCallback</struct>
          </ptrtype>
          <description>
            The callback to be called to describe a String value.
          </description>
        </field>
        <field id="reserved5">
          <ptrtype>
            <struct>jvmtiReservedCallback</struct>
          </ptrtype>
          <description>
            Reserved for future use..
          </description>
        </field>
        <field id="reserved6">
          <ptrtype>
            <struct>jvmtiReservedCallback</struct>
          </ptrtype>
          <description>
            Reserved for future use..
          </description>
        </field>
        <field id="reserved7">
          <ptrtype>
            <struct>jvmtiReservedCallback</struct>
          </ptrtype>
          <description>
            Reserved for future use..
          </description>
        </field>
        <field id="reserved8">
          <ptrtype>
            <struct>jvmtiReservedCallback</struct>
          </ptrtype>
          <description>
            Reserved for future use..
          </description>
        </field>
        <field id="reserved9">
          <ptrtype>
            <struct>jvmtiReservedCallback</struct>
          </ptrtype>
          <description>
            Reserved for future use..
          </description>
        </field>
        <field id="reserved10">
          <ptrtype>
            <struct>jvmtiReservedCallback</struct>
          </ptrtype>
          <description>
            Reserved for future use..
          </description>
        </field>
        <field id="reserved11">
          <ptrtype>
            <struct>jvmtiReservedCallback</struct>
          </ptrtype>
          <description>
            Reserved for future use..
          </description>
        </field>
        <field id="reserved12">
          <ptrtype>
            <struct>jvmtiReservedCallback</struct>
          </ptrtype>
          <description>
            Reserved for future use..
          </description>
        </field>
        <field id="reserved13">
          <ptrtype>
            <struct>jvmtiReservedCallback</struct>
          </ptrtype>
          <description>
            Reserved for future use..
          </description>
        </field>
        <field id="reserved14">
          <ptrtype>
            <struct>jvmtiReservedCallback</struct>
          </ptrtype>
          <description>
            Reserved for future use..
          </description>
        </field>
        <field id="reserved15">
          <ptrtype>
            <struct>jvmtiReservedCallback</struct>
          </ptrtype>
          <description>
            Reserved for future use..
          </description>
        </field>
      </typedef>


    <intro>
      <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.
      </rationale>

      <issue>
        Still under investigation as to if java.lang.ref references
        are reported as a different type of reference.
      </issue>

      <issue>
        Should or can an indication of the cost or relative cost of
        these operations be included?
      </issue>

    </intro>

    <callback id="jvmtiHeapIterationCallback" since="1.1">
      <jint/>
      <synopsis>Heap Iteration Callback</synopsis>
      <description>
        Agent supplied callback function.
        Describes (but does not pass in) an object in the heap.
        <p/>
        This function should return a bit vector of the desired
        <datalink id="jvmtiHeapVisitControl">visit control flags</datalink>.
        This will determine if the entire iteration should be aborted
        (the <code>JVMTI_VISIT_OBJECTS</code> flag is ignored).
        <p/>
        See the <internallink id="heapCallbacks">heap callback
        function restrictions</internallink>.
      </description>
      <parameters>
        <param id="class_tag">
          <jlong/>
          <description>
            The tag of the class of object (zero if the class is not tagged).
            If the object represents a runtime class,
            the <code>class_tag</code> is the tag
            associated with <code>java.lang.Class</code>
            (zero if <code>java.lang.Class</code> is not tagged).
          </description>
        </param>
        <param id="size">
          <jlong/>
          <description>
            Size of the object (in bytes). See <functionlink id="GetObjectSize"/>.
          </description>
        </param>
        <param id="tag_ptr">
          <outptr><jlong/></outptr>
          <description>
            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 <code>jlong</code> pointed to by the parameter.
          </description>
        </param>
        <param id="length">
          <jint/>
          <description>
            If this object is an array, the length of the array. Otherwise negative one (-1).
          </description>
        </param>
        <param id="user_data">
          <outptr><void/></outptr>
          <description>
            The user supplied data that was passed into the iteration function.
          </description>
        </param>
      </parameters>
    </callback>

    <callback id="jvmtiHeapReferenceCallback" since="1.1">
      <jint/>
      <synopsis>Heap Reference Callback</synopsis>
      <description>
        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.
        <p/>
        This function should return a bit vector of the desired
        <datalink id="jvmtiHeapVisitControl">visit control flags</datalink>.
        This will determine if the objects referenced by the referree
        should be visited or if the entire iteration should be aborted.
        <p/>
        See the <internallink id="heapCallbacks">heap callback
        function restrictions</internallink>.
      </description>
      <parameters>
        <param id="reference_kind">
          <enum>jvmtiHeapReferenceKind</enum>
          <description>
            The kind of reference.
          </description>
        </param>
        <param id="reference_info">
          <inptr>
            <struct>jvmtiHeapReferenceInfo</struct>
          </inptr>
          <description>
            Details about the reference.
            Set when the <datalink id="jvmtiHeapReferenceCallback.reference_kind">reference_kind</datalink> is
            <datalink id="JVMTI_HEAP_REFERENCE_FIELD"/>,
            <datalink id="JVMTI_HEAP_REFERENCE_STATIC_FIELD"/>,
            <datalink id="JVMTI_HEAP_REFERENCE_ARRAY_ELEMENT"/>,
            <datalink id="JVMTI_HEAP_REFERENCE_CONSTANT_POOL"/>,
            <datalink id="JVMTI_HEAP_REFERENCE_STACK_LOCAL"/>,
            or <datalink id="JVMTI_HEAP_REFERENCE_JNI_LOCAL"/>.
            Otherwise <code>NULL</code>.
          </description>
        </param>
        <param id="class_tag">
          <jlong/>
          <description>
            The tag of the class of referree object (zero if the class is not tagged).
            If the referree object represents a runtime class,
            the <code>class_tag</code> is the tag
            associated with <code>java.lang.Class</code>
            (zero if <code>java.lang.Class</code> is not tagged).
          </description>
        </param>
        <param id="referrer_class_tag">
          <jlong/>
          <description>
            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 <code>referrer_class_tag</code> is the tag associated with
            the <code>java.lang.Class</code>
            (zero if <code>java.lang.Class</code> is not tagged).
          </description>
        </param>
        <param id="size">
          <jlong/>
          <description>
            Size of the referree object (in bytes).
            See <functionlink id="GetObjectSize"/>.
          </description>
        </param>
        <param id="tag_ptr">
          <outptr><jlong/></outptr>
          <description>
            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 <code>jlong</code> pointed to by the parameter.
          </description>
        </param>
        <param id="referrer_tag_ptr">
          <outptr><jlong/></outptr>
          <description>
            Points to the tag of the referrer object, or
            points to the zero if the referrer
            object is not tagged.
            <code>NULL</code> 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 <code>jlong</code> pointed to by the parameter.
            If this callback is reporting a reference from an object to itself,
            <code>referrer_tag_ptr == tag_ptr</code>.
          </description>
        </param>
        <param id="length">
          <jint/>
          <description>
            If this object is an array, the length of the array. Otherwise negative one (-1).
          </description>
        </param>
        <param id="user_data">
          <outptr><void/></outptr>
          <description>
            The user supplied data that was passed into the iteration function.
          </description>
        </param>
      </parameters>
    </callback>

    <callback id="jvmtiPrimitiveFieldCallback" since="1.1">
      <jint/>
      <synopsis>Primitive Field Callback</synopsis>
      <description>
        Agent supplied callback function which
        describes a primitive field of an object (<i>the object</i>).
        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.
        <p/>
        This function should return a bit vector of the desired
        <datalink id="jvmtiHeapVisitControl">visit control flags</datalink>.
        This will determine if the entire iteration should be aborted
        (the <code>JVMTI_VISIT_OBJECTS</code> flag is ignored).
        <p/>
        See the <internallink id="heapCallbacks">heap callback
        function restrictions</internallink>.
      </description>
      <parameters>
        <param id="kind">
          <enum>jvmtiHeapReferenceKind</enum>
          <description>
            The kind of field -- instance or static (<datalink id="JVMTI_HEAP_REFERENCE_FIELD"/> or
            <datalink id="JVMTI_HEAP_REFERENCE_STATIC_FIELD"/>).
          </description>
        </param>
        <param id="info">
          <inptr>
            <struct>jvmtiHeapReferenceInfo</struct>
          </inptr>
          <description>
            Which field (the field index).
          </description>
        </param>
        <param id="object_class_tag">
          <jlong/>
          <description>
            The tag of the class of the object (zero if the class is not tagged).
            If the object represents a runtime class, the
            <code>object_class_tag</code> is the tag
            associated with <code>java.lang.Class</code>
            (zero if <code>java.lang.Class</code> is not tagged).
          </description>
        </param>
        <param id="object_tag_ptr">
          <outptr><jlong/></outptr>
          <description>
            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 <code>jlong</code> pointed to by the parameter.
          </description>
        </param>
        <param id="value">
          <jvalue/>
          <description>
            The value of the field.
          </description>
        </param>
        <param id="value_type">
          <enum>jvmtiPrimitiveType</enum>
          <description>
            The type of the field.
          </description>
        </param>
        <param id="user_data">
          <outptr><void/></outptr>
          <description>
            The user supplied data that was passed into the iteration function.
          </description>
        </param>
      </parameters>
    </callback>

    <callback id="jvmtiArrayPrimitiveValueCallback" since="1.1">
      <jint/>
      <synopsis>Array Primitive Value Callback</synopsis>
      <description>
        Agent supplied callback function.
        Describes the values in an array of a primitive type.
        <p/>
        This function should return a bit vector of the desired
        <datalink id="jvmtiHeapVisitControl">visit control flags</datalink>.
        This will determine if the entire iteration should be aborted
        (the <code>JVMTI_VISIT_OBJECTS</code> flag is ignored).
        <p/>
        See the <internallink id="heapCallbacks">heap callback
        function restrictions</internallink>.
      </description>
      <parameters>
        <param id="class_tag">
          <jlong/>
          <description>
            The tag of the class of the array object (zero if the class is not tagged).
          </description>
        </param>
        <param id="size">
          <jlong/>
          <description>
            Size of the array (in bytes).
            See <functionlink id="GetObjectSize"/>.
          </description>
        </param>
        <param id="tag_ptr">
          <outptr><jlong/></outptr>
          <description>
            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 <code>jlong</code> pointed to by the parameter.
          </description>
        </param>
        <param id="element_count">
          <jint/>
          <description>
            The length of the primitive array.
          </description>
        </param>
        <param id="element_type">
          <enum>jvmtiPrimitiveType</enum>
          <description>
            The type of the elements of the array.
          </description>
        </param>
        <param id="elements">
          <vmbuf><void/></vmbuf>
          <description>
            The elements of the array in a packed array of <code>element_count</code>
            items of <code>element_type</code> size each.
          </description>
        </param>
        <param id="user_data">
          <outptr><void/></outptr>
          <description>
            The user supplied data that was passed into the iteration function.
          </description>
        </param>
      </parameters>
    </callback>

    <callback id="jvmtiStringPrimitiveValueCallback" since="1.1">
      <jint/>
      <synopsis>String Primitive Value Callback</synopsis>
      <description>
        Agent supplied callback function.
        Describes the value of a java.lang.String.
        <p/>
        This function should return a bit vector of the desired
        <datalink id="jvmtiHeapVisitControl">visit control flags</datalink>.
        This will determine if the entire iteration should be aborted
        (the <code>JVMTI_VISIT_OBJECTS</code> flag is ignored).
        <p/>
        See the <internallink id="heapCallbacks">heap callback
        function restrictions</internallink>.
      </description>
      <parameters>
        <param id="class_tag">
          <jlong/>
          <description>
            The tag of the class of the String class (zero if the class is not tagged).
            <issue>Is this needed?</issue>
          </description>
        </param>
        <param id="size">
          <jlong/>
          <description>
            Size of the string (in bytes).
            See <functionlink id="GetObjectSize"/>.
          </description>
        </param>
        <param id="tag_ptr">
          <outptr><jlong/></outptr>
          <description>
            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 <code>jlong</code> pointed to by the parameter.
          </description>
        </param>
        <param id="value">
          <vmbuf><jchar/></vmbuf>
          <description>
            The value of the String, encoded as a Unicode string.
          </description>
        </param>
        <param id="value_length">
          <jint/>
          <description>
            The length of the string.
            The length is equal to the number of 16-bit Unicode
            characters in the string.
          </description>
        </param>
        <param id="user_data">
          <outptr><void/></outptr>
          <description>
            The user supplied data that was passed into the iteration function.
          </description>
        </param>
      </parameters>
    </callback>


    <callback id="jvmtiReservedCallback" since="1.1">
      <jint/>
      <synopsis>reserved for future use Callback</synopsis>
      <description>
        Placeholder -- reserved for future use.
      </description>
      <parameters>
      </parameters>
    </callback>

    <function id="FollowReferences" num="115" since="1.1">
      <synopsis>Follow References</synopsis>
      <description>
        This function initiates a traversal over the objects that are
        directly and indirectly reachable from the specified object or,
        if <code>initial_object</code> 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.
        <p/>
        This function operates by traversing the reference graph.
        Let <i>A</i>, <i>B</i>, ... represent objects.
        When a reference from <i>A</i> to <i>B</i> is traversed,
        when a reference from a heap root to <i>B</i> is traversed,
        or when <i>B</i> is specified as the <paramlink id="initial_object"/>,
        then <i>B</i> is said to be <i>visited</i>.
        A reference from <i>A</i> to <i>B</i> is not traversed until <i>A</i>
        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 <functionlink id="jvmtiHeapReferenceCallback"/>.
        In a reference from <i>A</i> to <i>B</i>, <i>A</i> is known
        as the <i>referrer</i> and <i>B</i> as the <i>referree</i>.
        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
        <datalink
         id="jvmtiHeapReferenceCallback.reference_kind"><code>reference_kind</code></datalink>
         and
        <datalink
         id="jvmtiHeapReferenceCallback.reference_info"><code>reference_info</code></datalink>
        parameters of the <functionlink id="jvmtiHeapReferenceCallback"/> callback.
        <p/>
        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:
        <ul>
          <li>Instance objects report references to each non-primitive instance fields
              (including inherited fields).</li>
          <li>Instance objects report a reference to the object type (class).</li>
          <li>Classes report a reference to the superclass and directly
              implemented/extended interfaces.</li>
          <li>Classes report a reference to the class loader, protection domain,
              signers, and resolved entries in the constant pool.</li>
          <li>Classes report a reference to each directly declared non-primitive
              static field.</li>
          <li>Arrays report a reference to the array type (class) and each
              array element.</li>
          <li>Primitive arrays report a reference to the array type.</li>
        </ul>
        <p/>
        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
        <functionlink id="jvmtiArrayPrimitiveValueCallback"/> or
        <functionlink id="jvmtiStringPrimitiveValueCallback"/>.
        A primitive field
        is reported after the object with that field is visited;
        it is reported by invoking the agent supplied callback function
        <functionlink id="jvmtiPrimitiveFieldCallback"/>.
        <p/>
        Whether a callback is provided or is <code>NULL</code> 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
        <datalink id="jvmtiHeapVisitControl">visit control flags</datalink>
        returned by <functionlink id="jvmtiHeapReferenceCallback"/>
        do determine if the objects referenced by the
        current object as visited.
        The <datalink id="jvmtiHeapFilter">heap filter flags</datalink>
        and <paramlink id="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
        <fieldlink id="array_primitive_value_callback" struct="jvmtiHeapCallbacks"/> and <code>klass</code>
        is set to the array of bytes class, then only arrays of byte will be
        reported.
        The table below summarizes this:
        <p/>
        <table>
          <tr class="bgLight">
            <th/>
            <th class="centered" scope="col">Controls objects visited</th>
            <th class="centered" scope="col">Controls objects reported</th>
            <th class="centered" scope="col">Controls primitives reported</th>
          </tr>
          <tr>
            <th scope="row">
              the
              <datalink id="jvmtiHeapVisitControl">Heap Visit Control Flags</datalink>
              returned by <functionlink id="jvmtiHeapReferenceCallback"/>
            </th>
            <td class="centered">
              <b>Yes</b>
            </td>
            <td class="centered">
              <b>Yes</b>, since visits are controlled
            </td>
            <td class="centered">
              <b>Yes</b>, since visits are controlled
            </td>
          </tr>
          <tr>
            <th scope="row">
              <fieldlink id="array_primitive_value_callback" struct="jvmtiHeapCallbacks"/>
              in <paramlink id="callbacks"/> set
            </th>
            <td class="centered">
              No
            </td>
            <td class="centered">
              <b>Yes</b>
            </td>
            <td class="centered">
              No
            </td>
          </tr>
          <tr>
            <th scope="row">
              <paramlink id="heap_filter"/>
            </th>
            <td class="centered">
              No
            </td>
            <td class="centered">
              <b>Yes</b>
            </td>
            <td class="centered">
              <b>Yes</b>
            </td>
          </tr>
          <tr>
            <th scope="row">
              <paramlink id="klass"/>
            </th>
            <td class="centered">
              No
            </td>
            <td class="centered">
              <b>Yes</b>
            </td>
            <td class="centered">
              <b>Yes</b>
            </td>
          </tr>
        </table>
        <p/>
        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.
      </description>
      <origin>new</origin>
      <capabilities>
        <required id="can_tag_objects"></required>
      </capabilities>
      <parameters>
        <param id="heap_filter">
          <jint/>
          <description>
            This bit vector of
            <datalink id="jvmtiHeapFilter">heap filter flags</datalink>.
            restricts the objects for which the callback function is called.
            This applies to both the object and primitive callbacks.
          </description>
        </param>
        <param id="klass">
          <ptrtype>
            <jclass/>
            <nullok>callbacks are not limited to instances of a particular
                    class</nullok>
          </ptrtype>
          <description>
            Callbacks are only reported when the object is an instance of
            this class.
            Objects which are instances of a subclass of <code>klass</code>
            are not reported.
            If <code>klass</code> is an interface, no objects are reported.
            This applies to both the object and primitive callbacks.
          </description>
        </param>
        <param id="initial_object">
          <ptrtype>
            <jobject/>
            <nullok>references are followed from the heap roots</nullok>
          </ptrtype>
          <description>
            The object to follow
          </description>
        </param>
        <param id="callbacks">
          <inptr>
            <struct>jvmtiHeapCallbacks</struct>
          </inptr>
          <description>
            Structure defining the set of callback functions.
          </description>
        </param>
        <param id="user_data">
          <inbuf>
            <void/>
            <nullok><code>NULL</code> is passed as the user supplied data</nullok>
          </inbuf>
          <description>
            User supplied data to be passed to the callback.
          </description>
        </param>
      </parameters>
      <errors>
        <error id="JVMTI_ERROR_INVALID_CLASS">
          <paramlink id="klass"/> is not a valid class.
        </error>
        <error id="JVMTI_ERROR_INVALID_OBJECT">
          <paramlink id="initial_object"/> is not a valid object.
        </error>
      </errors>
    </function>


    <function id="IterateThroughHeap" num="116" since="1.1">
      <synopsis>Iterate Through Heap</synopsis>
      <description>
        Initiate an iteration over all objects in the heap.
        This includes both reachable and
        unreachable objects. Objects are visited in no particular order.
        <p/>
        Heap objects are reported by invoking the agent supplied
        callback function <functionlink id="jvmtiHeapIterationCallback"/>.
        References between objects are not reported.
        If only reachable objects are desired, or if object reference information
        is needed, use <functionlink id="FollowReferences"/>.
        <p/>
        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
        <functionlink id="jvmtiArrayPrimitiveValueCallback"/> or
        <functionlink id="jvmtiStringPrimitiveValueCallback"/>.
        A primitive field
        is reported after the object with that field is visited;
        it is reported by invoking the agent supplied
        callback function
        <functionlink id="jvmtiPrimitiveFieldCallback"/>.
        <p/>
        Unless the iteration is aborted by the
        <datalink id="jvmtiHeapVisitControl">Heap Visit Control Flags</datalink>
        returned by a callback, all objects in the heap are visited.
        Whether a callback is provided or is <code>NULL</code> 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 <datalink id="jvmtiHeapFilter">heap filter flags</datalink>
        and <paramlink id="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
        <fieldlink id="array_primitive_value_callback" struct="jvmtiHeapCallbacks"/> and <code>klass</code>
        is set to the array of bytes class, then only arrays of byte will be
        reported. The table below summarizes this (contrast this with
        <functionlink id="FollowReferences"/>):
        <p/>
        <table>
          <tr class="bgLight">
            <th/>
            <th class="centered" scope="col">Controls objects visited</th>
            <th class="centered" scope="col">Controls objects reported</th>
            <th class="centered" scope="col">Controls primitives reported</th>
          </tr>
          <tr>
            <th scope="row">
              the
              <datalink id="jvmtiHeapVisitControl">Heap Visit Control Flags</datalink>
              returned by <functionlink id="jvmtiHeapIterationCallback"/>
            </th>
            <td class="centered">
              No<br/>(unless they abort the iteration)
            </td>
            <td class="centered">
              No<br/>(unless they abort the iteration)
            </td>
            <td class="centered">
              No<br/>(unless they abort the iteration)
            </td>
          </tr>
          <tr>
            <th scope="row">
              <fieldlink id="array_primitive_value_callback" struct="jvmtiHeapCallbacks"/>
              in <paramlink id="callbacks"/> set
            </th>
            <td class="centered">
              No
            </td>
            <td class="centered">
              <b>Yes</b>
            </td>
            <td class="centered">
              No
            </td>
          </tr>
          <tr>
            <th scope="row">
              <paramlink id="heap_filter"/>
            </th>
            <td class="centered">
              No
            </td>
            <td class="centered">
              <b>Yes</b>
            </td>
            <td class="centered">
              <b>Yes</b>
            </td>
          </tr>
          <tr>
            <th scope="row">
              <paramlink id="klass"/>
            </th>
            <td class="centered">
              No
            </td>
            <td class="centered">
              <b>Yes</b>
            </td>
            <td class="centered">
              <b>Yes</b>
            </td>
          </tr>
        </table>
        <p/>
        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.
      </description>
      <origin>new</origin>
      <capabilities>
        <required id="can_tag_objects"></required>
      </capabilities>
      <parameters>
        <param id="heap_filter">
          <jint/>
          <description>
            This bit vector of
            <datalink id="jvmtiHeapFilter">heap filter flags</datalink>.
            restricts the objects for which the callback function is called.
            This applies to both the object and primitive callbacks.
          </description>
        </param>
        <param id="klass">
          <ptrtype>
            <jclass/>
            <nullok>callbacks are not limited to instances of a particular class</nullok>
          </ptrtype>
          <description>
            Callbacks are only reported when the object is an instance of
            this class.
            Objects which are instances of a subclass of <code>klass</code>
            are not reported.
            If <code>klass</code> is an interface, no objects are reported.
            This applies to both the object and primitive callbacks.
          </description>
        </param>
        <param id="callbacks">
          <inptr>
            <struct>jvmtiHeapCallbacks</struct>
          </inptr>
          <description>
            Structure defining the set callback functions.
          </description>
        </param>
        <param id="user_data">
          <inbuf>
            <void/>
            <nullok><code>NULL</code> is passed as the user supplied data</nullok>
          </inbuf>
          <description>
            User supplied data to be passed to the callback.
          </description>
        </param>
      </parameters>
      <errors>
        <error id="JVMTI_ERROR_INVALID_CLASS">
          <paramlink id="klass"/> is not a valid class.
        </error>
      </errors>
    </function>

    <function id="GetTag" phase="start" num="106">
      <synopsis>Get Tag</synopsis>
      <description>
        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
        <functionlink id="SetTag"></functionlink>.
        Objects for which no tags have been set return a
        tag value of zero.
      </description>
      <origin>new</origin>
      <capabilities>
        <required id="can_tag_objects"></required>
      </capabilities>
      <parameters>
        <param id="object">
          <jobject/>
            <description>
              The object whose tag is to be retrieved.
            </description>
        </param>
        <param id="tag_ptr">
          <outptr><jlong/></outptr>
          <description>
            On return, the referenced long is set to the value
            of the tag.
          </description>
        </param>
      </parameters>
      <errors>
      </errors>
    </function>

    <function id="SetTag" phase="start" num="107">
      <synopsis>Set Tag</synopsis>
      <description>
        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
        <functionlink id="GetTag"></functionlink>.
      </description>
      <origin>new</origin>
      <capabilities>
        <required id="can_tag_objects"></required>
      </capabilities>
      <parameters>
        <param id="object">
          <jobject/>
            <description>
              The object whose tag is to be set.
            </description>
        </param>
        <param id="tag">
          <jlong/>
          <description>
            The new value of the tag.
          </description>
        </param>
      </parameters>
      <errors>
      </errors>
    </function>

    <function id="GetObjectsWithTags" num="114">
      <synopsis>Get Objects With Tags</synopsis>
      <description>
        Return objects in the heap with the specified tags.
        The format is parallel arrays of objects and tags.
      </description>
      <origin>new</origin>
      <capabilities>
        <required id="can_tag_objects"></required>
      </capabilities>
      <parameters>
        <param id="tag_count">
          <jint min="0"/>
            <description>
              Number of tags to scan for.
            </description>
        </param>
        <param id="tags">
          <inbuf incount="tag_count">
            <jlong/>
          </inbuf>
            <description>
              Scan for objects with these tags.
              Zero is not permitted in this array.
            </description>
        </param>
        <param id="count_ptr">
          <outptr>
            <jint/>
          </outptr>
            <description>
              Return the number of objects with any of the tags
              in <paramlink id="tags"/>.
            </description>
        </param>
        <param id="object_result_ptr">
          <allocbuf outcount="count_ptr">
            <jobject/>
            <nullok>this information is not returned</nullok>
          </allocbuf>
            <description>
              Returns the array of objects with any of the tags
              in <paramlink id="tags"/>.
            </description>
        </param>
        <param id="tag_result_ptr">
          <allocbuf outcount="count_ptr">
            <jlong/>
            <nullok>this information is not returned</nullok>
          </allocbuf>
            <description>
              For each object in <paramlink id="object_result_ptr"/>,
              return the tag at the corresponding index.
            </description>
        </param>
      </parameters>
      <errors>
        <error id="JVMTI_ERROR_ILLEGAL_ARGUMENT">
          Zero is present in <paramlink id="tags"></paramlink>.
        </error>
      </errors>
    </function>

    <function id="ForceGarbageCollection" num="108">
      <synopsis>Force Garbage Collection</synopsis>
      <description>
        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.
        <p/>
        Although garbage collection is as complete
        as possible there is no guarantee that all
        <eventlink id="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.
      </description>
      <origin>new</origin>
      <capabilities>
      </capabilities>
      <parameters>
      </parameters>
      <errors>
      </errors>
    </function>


  </category>

  <category id="Heap_1_0" label="Heap (1.0)">
    <intro>
      <b>
        These functions and data types were introduced in the original
        <jvmti/> version 1.0 and have been superseded by more
      </b>
      <internallink id="Heap"><b>powerful and flexible versions</b></internallink>
      <b>
        which:
      </b>
      <ul>
        <li>
          <b>
            Allow access to primitive values (the value of Strings, arrays,
            and primitive fields)
          </b>
        </li>
        <li>
          <b>
            Allow the tag of the referrer to be set, thus enabling more
            efficient localized reference graph building
          </b>
        </li>
        <li>
          <b>
            Provide more extensive filtering abilities
          </b>
        </li>
        <li>
          <b>
            Are extensible, allowing their abilities to grow in future versions of <jvmti/>
          </b>
        </li>
      </ul>
      <p/>
      <b>Please use the </b>
      <internallink id="Heap"><b>current Heap functions</b></internallink>.
        <p/>
        <constants id="jvmtiHeapObjectFilter" label="Heap Object Filter Enumeration" kind="enum">
          <constant id="JVMTI_HEAP_OBJECT_TAGGED" num="1">
            Tagged objects only.
          </constant>
          <constant id="JVMTI_HEAP_OBJECT_UNTAGGED" num="2">
            Untagged objects only.
          </constant>
          <constant id="JVMTI_HEAP_OBJECT_EITHER" num="3">
            Either tagged or untagged objects.
          </constant>
        </constants>

        <constants id="jvmtiHeapRootKind" label="Heap Root Kind Enumeration" kind="enum">
          <constant id="JVMTI_HEAP_ROOT_JNI_GLOBAL" num="1">
            JNI global reference.
          </constant>
          <constant id="JVMTI_HEAP_ROOT_SYSTEM_CLASS" num="2">
            System class.
          </constant>
          <constant id="JVMTI_HEAP_ROOT_MONITOR" num="3">
            Monitor.
          </constant>
          <constant id="JVMTI_HEAP_ROOT_STACK_LOCAL" num="4">
            Stack local.
          </constant>
          <constant id="JVMTI_HEAP_ROOT_JNI_LOCAL" num="5">
            JNI local reference.
          </constant>
          <constant id="JVMTI_HEAP_ROOT_THREAD" num="6">
            Thread.
          </constant>
          <constant id="JVMTI_HEAP_ROOT_OTHER" num="7">
            Other.
          </constant>
        </constants>

        <constants id="jvmtiObjectReferenceKind" label="Object Reference Enumeration" kind="enum">
          <constant id="JVMTI_REFERENCE_CLASS" num="1">
            Reference from an object to its class.
          </constant>
          <constant id="JVMTI_REFERENCE_FIELD" num="2">
            Reference from an object to the value of one of its instance fields.
            For references of this kind the <code>referrer_index</code>
            parameter to the <internallink id="jvmtiObjectReferenceCallback">
            jvmtiObjectReferenceCallback</internallink> 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 <functionlink id="GetClassFields"/>), with the total
            number of fields (both public and private) declared in all superclasses
            and superinterfaces. The index starts at zero.
          </constant>
          <constant id="JVMTI_REFERENCE_ARRAY_ELEMENT" num="3">
            Reference from an array to one of its elements.
            For references of this kind the <code>referrer_index</code>
            parameter to the <internallink id="jvmtiObjectReferenceCallback">
            jvmtiObjectReferenceCallback</internallink> is the array index.
          </constant>
          <constant id="JVMTI_REFERENCE_CLASS_LOADER" num="4">
            Reference from a class to its class loader.
          </constant>
          <constant id="JVMTI_REFERENCE_SIGNERS" num="5">
            Reference from a class to its signers array.
          </constant>
          <constant id="JVMTI_REFERENCE_PROTECTION_DOMAIN" num="6">
            Reference from a class to its protection domain.
          </constant>
          <constant id="JVMTI_REFERENCE_INTERFACE" num="7">
            Reference from a class to one of its interfaces.
          </constant>
          <constant id="JVMTI_REFERENCE_STATIC_FIELD" num="8">
            Reference from a class to the value of one of its static fields.
            For references of this kind the <code>referrer_index</code>
            parameter to the <internallink id="jvmtiObjectReferenceCallback">
            jvmtiObjectReferenceCallback</internallink> 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 <functionlink id="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 <jvmti/> 1.0 Specification.
            <rationale>No known implementations used the 1.0 definition.</rationale>
          </constant>
          <constant id="JVMTI_REFERENCE_CONSTANT_POOL" num="9">
            Reference from a class to a resolved entry in the constant pool.
            For references of this kind the <code>referrer_index</code>
            parameter to the <internallink id="jvmtiObjectReferenceCallback">
            jvmtiObjectReferenceCallback</internallink> is the index into
            constant pool table of the class, starting at 1. See
            <vmspec chapter="4.4"/>.
          </constant>
        </constants>

        <constants id="jvmtiIterationControl" label="Iteration Control Enumeration" kind="enum">
          <constant id="JVMTI_ITERATION_CONTINUE" num="1">
            Continue the iteration.
            If this is a reference iteration, follow the references of this object.
          </constant>
          <constant id="JVMTI_ITERATION_IGNORE" num="2">
            Continue the iteration.
            If this is a reference iteration, ignore the references of this object.
          </constant>
          <constant id="JVMTI_ITERATION_ABORT" num="0">
            Abort the iteration.
          </constant>
        </constants>
    </intro>

    <callback id="jvmtiHeapObjectCallback">
      <enum>jvmtiIterationControl</enum>
      <synopsis>Heap Object Callback</synopsis>
      <description>
        Agent supplied callback function.
        Describes (but does not pass in) an object in the heap.
        <p/>
        Return value should be <code>JVMTI_ITERATION_CONTINUE</code> to continue iteration,
        or <code>JVMTI_ITERATION_ABORT</code> to stop iteration.
        <p/>
        See the <internallink id="heapCallbacks">heap callback
        function restrictions</internallink>.
      </description>
      <parameters>
        <param id="class_tag">
          <jlong/>
          <description>
            The tag of the class of object (zero if the class is not tagged).
            If the object represents a runtime class,
            the <code>class_tag</code> is the tag
            associated with <code>java.lang.Class</code>
            (zero if <code>java.lang.Class</code> is not tagged).
          </description>
        </param>
        <param id="size">
          <jlong/>
          <description>
            Size of the object (in bytes). See <functionlink id="GetObjectSize"/>.
          </description>
        </param>
        <param id="tag_ptr">
          <outptr><jlong/></outptr>
          <description>
            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 <code>jlong</code> pointed to by the parameter.
          </description>
        </param>
        <param id="user_data">
          <outptr><void/></outptr>
          <description>
            The user supplied data that was passed into the iteration function.
          </description>
        </param>
      </parameters>
    </callback>

    <callback id="jvmtiHeapRootCallback">
      <enum>jvmtiIterationControl</enum>
      <synopsis>Heap Root Object Callback</synopsis>
      <description>
        Agent supplied callback function.
        Describes (but does not pass in) an object that is a root for the purposes
        of garbage collection.
        <p/>
        Return value should be <code>JVMTI_ITERATION_CONTINUE</code> to continue iteration,
        <code>JVMTI_ITERATION_IGNORE</code> to continue iteration without pursuing
        references from referree object or <code>JVMTI_ITERATION_ABORT</code> to stop iteration.
        <p/>
        See the <internallink id="heapCallbacks">heap callback
        function restrictions</internallink>.
      </description>
      <parameters>
        <param id="root_kind">
          <enum>jvmtiHeapRootKind</enum>
          <description>
            The kind of heap root.
          </description>
        </param>
        <param id="class_tag">
          <jlong/>
          <description>
            The tag of the class of object (zero if the class is not tagged).
            If the object represents a runtime class, the <code>class_tag</code> is the tag
            associated with <code>java.lang.Class</code>
            (zero if <code>java.lang.Class</code> is not tagged).
          </description>
        </param>
        <param id="size">
          <jlong/>
          <description>
            Size of the object (in bytes). See <functionlink id="GetObjectSize"/>.
          </description>
        </param>
        <param id="tag_ptr">
          <outptr><jlong/></outptr>
          <description>
            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 <code>jlong</code> pointed to by the parameter.
          </description>
        </param>
        <param id="user_data">
          <outptr><void/></outptr>
          <description>
            The user supplied data that was passed into the iteration function.
          </description>
        </param>
      </parameters>
    </callback>

    <callback id="jvmtiStackReferenceCallback">
      <enum>jvmtiIterationControl</enum>
      <synopsis>Stack Reference Object Callback</synopsis>
      <description>
        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.
        <p/>
        Return value should be <code>JVMTI_ITERATION_CONTINUE</code> to continue iteration,
        <code>JVMTI_ITERATION_IGNORE</code> to continue iteration without pursuing
        references from referree object or <code>JVMTI_ITERATION_ABORT</code> to stop iteration.
        <p/>
        See the <internallink id="heapCallbacks">heap callback
        function restrictions</internallink>.
      </description>
      <parameters>
        <param id="root_kind">
          <enum>jvmtiHeapRootKind</enum>
          <description>
            The kind of root (either <code>JVMTI_HEAP_ROOT_STACK_LOCAL</code> or
            <code>JVMTI_HEAP_ROOT_JNI_LOCAL</code>).
          </description>
        </param>
        <param id="class_tag">
          <jlong/>
          <description>
           The tag of the class of object (zero if the class is not tagged).
           If the object represents a runtime class, the  <code>class_tag</code> is the tag
           associated with <code>java.lang.Class</code>
           (zero if <code>java.lang.Class</code> is not tagged).
          </description>
        </param>
        <param id="size">
          <jlong/>
          <description>
            Size of the object (in bytes). See <functionlink id="GetObjectSize"/>.
          </description>
        </param>
        <param id="tag_ptr">
          <outptr><jlong/></outptr>
          <description>
            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 <code>jlong</code> pointed to by the parameter.
          </description>
        </param>
        <param id="thread_tag">
          <jlong/>
          <description>
            The tag of the thread corresponding to this stack, zero if not tagged.
          </description>
        </param>
        <param id="depth">
          <jint/>
          <description>
            The depth of the frame.
          </description>
        </param>
        <param id="method">
          <jmethodID/>
          <description>
            The method executing in this frame.
          </description>
        </param>
        <param id="slot">
          <jint/>
          <description>
            The slot number.
          </description>
        </param>
        <param id="user_data">
          <outptr><void/></outptr>
          <description>
            The user supplied data that was passed into the iteration function.
          </description>
        </param>
      </parameters>
    </callback>

    <callback id="jvmtiObjectReferenceCallback">
      <enum>jvmtiIterationControl</enum>
      <synopsis>Object Reference Callback</synopsis>
      <description>
        Agent supplied callback function.
        Describes a reference from an object (the referrer) to another object
        (the referree).
        <p/>
        Return value should be <code>JVMTI_ITERATION_CONTINUE</code> to continue iteration,
        <code>JVMTI_ITERATION_IGNORE</code> to continue iteration without pursuing
        references from referree object or <code>JVMTI_ITERATION_ABORT</code> to stop iteration.
        <p/>
        See the <internallink id="heapCallbacks">heap callback
        function restrictions</internallink>.
      </description>
      <parameters>
        <param id="reference_kind">
          <enum>jvmtiObjectReferenceKind</enum>
          <description>
            The type of reference.
          </description>
        </param>
        <param id="class_tag">
          <jlong/>
          <description>
            The tag of the class of referree object (zero if the class is not tagged).
            If the referree object represents a runtime class,
            the  <code>class_tag</code> is the tag
            associated with <code>java.lang.Class</code>
            (zero if <code>java.lang.Class</code> is not tagged).
          </description>
        </param>
        <param id="size">
          <jlong/>
          <description>
            Size of the referree object (in bytes).
            See <functionlink id="GetObjectSize"/>.
          </description>
        </param>
        <param id="tag_ptr">
          <outptr><jlong/></outptr>
          <description>
            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 <code>jlong</code> pointed to by the parameter.
          </description>
        </param>
        <param id="referrer_tag">
          <jlong/>
          <description>
            The tag of the referrer object, or zero if the referrer
            object is not tagged.
          </description>
        </param>
        <param id="referrer_index">
          <jint/>
          <description>
            For references of type <code>JVMTI_REFERENCE_FIELD</code> or
            <code>JVMTI_REFERENCE_STATIC_FIELD</code> the index
            of the field in the referrer object. The index is based on the
            order of all the object's fields - see <internallink
            id="JVMTI_REFERENCE_FIELD">JVMTI_REFERENCE_FIELD</internallink>
            or <internallink
            id="JVMTI_REFERENCE_STATIC_FIELD">JVMTI_REFERENCE_STATIC_FIELD
            </internallink> for further description.
            <p/>
            For references of type <code>JVMTI_REFERENCE_ARRAY_ELEMENT</code>
            the array index - see <internallink id="JVMTI_REFERENCE_ARRAY_ELEMENT">
            JVMTI_REFERENCE_ARRAY_ELEMENT</internallink> for further description.
            <p/>
            For references of type <code>JVMTI_REFERENCE_CONSTANT_POOL</code>
            the index into the constant pool of the class - see
            <internallink id="JVMTI_REFERENCE_CONSTANT_POOL">
            JVMTI_REFERENCE_CONSTANT_POOL</internallink> for further
            description.
            <p/>
            For references of other kinds the <code>referrer_index</code> is
            <code>-1</code>.
          </description>
        </param>
        <param id="user_data">
          <outptr><void/></outptr>
          <description>
            The user supplied data that was passed into the iteration function.
          </description>
        </param>
      </parameters>
    </callback>

    <function id="IterateOverObjectsReachableFromObject" num="109">
      <synopsis>Iterate Over Objects Reachable From Object</synopsis>
      <description>
        This function iterates over all objects that are directly
        and indirectly reachable from the specified object.
        For each object <i>A</i> (known
        as the referrer) with a reference to object <i>B</i> 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
        <datalink id="jvmtiObjectReferenceCallback.reference_kind"></datalink> and
        <datalink id="jvmtiObjectReferenceCallback.referrer_index"></datalink>.
        The callback for an object will always occur after the callback for
        its referrer.
        <p/>
        See <functionlink id="FollowReferences"/> for the object
        references which are reported.
        <p/>
        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.
      </description>
      <origin>new</origin>
      <capabilities>
        <required id="can_tag_objects"></required>
      </capabilities>
      <parameters>
        <param id="object">
          <jobject/>
            <description>
              The object
            </description>
        </param>
        <param id="object_reference_callback">
          <ptrtype>
            <struct>jvmtiObjectReferenceCallback</struct>
          </ptrtype>
            <description>
              The callback to be called to describe each
              object reference.
            </description>
        </param>
        <param id="user_data">
          <inbuf>
            <void/>
            <nullok><code>NULL</code> is passed as the user supplied data</nullok>
          </inbuf>
          <description>
            User supplied data to be passed to the callback.
          </description>
        </param>
      </parameters>
      <errors>
      </errors>
    </function>

    <function id="IterateOverReachableObjects" num="110">
      <synopsis>Iterate Over Reachable Objects</synopsis>
      <description>
        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.
        <p/>
        For each root the <paramlink id="heap_root_callback"></paramlink>
        or <paramlink id="stack_ref_callback"></paramlink> 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.
        <p/>
        For each object reference the <paramlink id="object_ref_callback"></paramlink>
        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
        <datalink id="jvmtiObjectReferenceCallback.reference_kind"></datalink> and
        <datalink id="jvmtiObjectReferenceCallback.referrer_index"></datalink>.
        The callback for an object will always occur after the callback for
        its referrer.
        <p/>
        See <functionlink id="FollowReferences"/> for the object
        references which are reported.
        <p/>
        Roots are always reported to the profiler before any object references
        are reported. In other words, the <paramlink id="object_ref_callback"></paramlink>
        callback will not be called until the appropriate callback has been called
        for all roots. If the <paramlink id="object_ref_callback"></paramlink> callback is
        specified as <code>NULL</code> then this function returns after
        reporting the root objects to the profiler.
        <p/>
        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.
      </description>
      <origin>new</origin>
      <capabilities>
        <required id="can_tag_objects"></required>
      </capabilities>
      <parameters>
        <param id="heap_root_callback">
          <ptrtype>
            <struct>jvmtiHeapRootCallback</struct>
            <nullok>do not report heap roots</nullok>
          </ptrtype>
            <description>
              The callback function to be called for each heap root of type
              <code>JVMTI_HEAP_ROOT_JNI_GLOBAL</code>,
              <code>JVMTI_HEAP_ROOT_SYSTEM_CLASS</code>,
              <code>JVMTI_HEAP_ROOT_MONITOR</code>,
              <code>JVMTI_HEAP_ROOT_THREAD</code>, or
              <code>JVMTI_HEAP_ROOT_OTHER</code>.
            </description>
        </param>
        <param id="stack_ref_callback">
          <ptrtype>
            <struct>jvmtiStackReferenceCallback</struct>
            <nullok>do not report stack references</nullok>
          </ptrtype>
            <description>
              The callback function to be called for each heap root of
              <code>JVMTI_HEAP_ROOT_STACK_LOCAL</code> or
              <code>JVMTI_HEAP_ROOT_JNI_LOCAL</code>.
            </description>
        </param>
        <param id="object_ref_callback">
          <ptrtype>
            <struct>jvmtiObjectReferenceCallback</struct>
            <nullok>do not follow references from the root objects</nullok>
          </ptrtype>
            <description>
              The callback function to be called for each object reference.
            </description>
        </param>
        <param id="user_data">
          <inbuf>
            <void/>
            <nullok><code>NULL</code> is passed as the user supplied data</nullok>
          </inbuf>
          <description>
            User supplied data to be passed to the callback.
          </description>
        </param>
      </parameters>
      <errors>
      </errors>
    </function>

    <function id="IterateOverHeap" num="111">
      <synopsis>Iterate Over Heap</synopsis>
      <description>
        Iterate over all objects in the heap. This includes both reachable and
        unreachable objects.
        <p/>
        The <paramlink id="object_filter"></paramlink> parameter indicates the
        objects for which the callback function is called. If this parameter
        is <code>JVMTI_HEAP_OBJECT_TAGGED</code> then the callback will only be
        called for every object that is tagged. If the parameter is
        <code>JVMTI_HEAP_OBJECT_UNTAGGED</code> then the callback will only be
        for objects that are not tagged. If the parameter
        is <code>JVMTI_HEAP_OBJECT_EITHER</code> then the callback will be
        called for every object in the heap, irrespective of whether it is
        tagged or not.
        <p/>
        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.
      </description>
      <origin>new</origin>
      <capabilities>
        <required id="can_tag_objects"></required>
      </capabilities>
      <parameters>
        <param id="object_filter">
          <enum>jvmtiHeapObjectFilter</enum>
          <description>
            Indicates the objects for which the callback function is called.
          </description>
        </param>
        <param id="heap_object_callback">
          <ptrtype>
            <struct>jvmtiHeapObjectCallback</struct>
          </ptrtype>
            <description>
              The iterator function to be called for each
              object matching the <paramlink id="object_filter"/>.
            </description>
        </param>
        <param id="user_data">
          <inbuf>
            <void/>
            <nullok><code>NULL</code> is passed as the user supplied data</nullok>
          </inbuf>
          <description>
            User supplied data to be passed to the callback.
          </description>
        </param>
      </parameters>
      <errors>
      </errors>
    </function>

    <function id="IterateOverInstancesOfClass" num="112">
      <synopsis>Iterate Over Instances Of Class</synopsis>
      <description>
        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.
        <p/>
        The <paramlink id="object_filter"></paramlink> parameter indicates the
        objects for which the callback function is called. If this parameter
        is <code>JVMTI_HEAP_OBJECT_TAGGED</code> then the callback will only be
        called for every object that is tagged. If the parameter is
        <code>JVMTI_HEAP_OBJECT_UNTAGGED</code> then the callback will only be
        called for objects that are not tagged. If the parameter
        is <code>JVMTI_HEAP_OBJECT_EITHER</code> then the callback will be
        called for every object in the heap, irrespective of whether it is
        tagged or not.
        <p/>
        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.
      </description>
      <origin>new</origin>
      <capabilities>
        <required id="can_tag_objects"></required>
      </capabilities>
      <parameters>
        <param id="klass">
          <jclass/>
            <description>
              Iterate over objects of this class only.
            </description>
        </param>
        <param id="object_filter">
          <enum>jvmtiHeapObjectFilter</enum>
          <description>
            Indicates the objects for which the callback function is called.
          </description>
        </param>
        <param id="heap_object_callback">
          <ptrtype>
            <struct>jvmtiHeapObjectCallback</struct>
          </ptrtype>
            <description>
              The iterator function to be called for each
              <paramlink id="klass"/> instance matching
              the <paramlink id="object_filter"/>.
            </description>
        </param>
        <param id="user_data">
          <inbuf>
            <void/>
            <nullok><code>NULL</code> is passed as the user supplied data</nullok>
          </inbuf>
          <description>
            User supplied data to be passed to the callback.
          </description>
        </param>
      </parameters>
      <errors>
      </errors>
    </function>

  </category>

  <category id="local" label="Local Variable">

    <intro>
      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
      <functionlink id="GetLocalVariableTable"></functionlink>.
    </intro>

    <function id="GetLocalObject" num="21">
      <synopsis>Get Local Variable - Object</synopsis>
      <description>
        This function can be used to retrieve the value of a local
        variable whose type is <code>Object</code> or a subclass of <code>Object</code>.
      </description>
      <origin>jvmdi</origin>
      <capabilities>
        <required id="can_access_local_variables"></required>
      </capabilities>
      <parameters>
        <param id="thread">
          <jthread null="current" frame="frame"/>
          <description>
            The thread of the frame containing the variable's value.
          </description>
        </param>
        <param id="depth">
          <jframeID thread="thread"/>
          <description>
            The depth of the frame containing the variable's value.
          </description>
        </param>
        <param id="slot">
          <jint/>
          <description>
            The variable's slot number.
          </description>
        </param>
        <param id="value_ptr">
          <outptr><jobject/></outptr>
            <description>
              On return, points to the variable's value.
            </description>
        </param>
      </parameters>
      <errors>
        <error id="JVMTI_ERROR_INVALID_SLOT">
          Invalid <code>slot</code>.
        </error>
        <error id="JVMTI_ERROR_TYPE_MISMATCH">
          The variable type is not
          <code>Object</code> or a subclass of <code>Object</code>.
        </error>
        <error id="JVMTI_ERROR_OPAQUE_FRAME">
          Not a visible frame
        </error>
      </errors>
    </function>

    <function id="GetLocalInstance" num="155" since="1.2">
      <synopsis>Get Local Instance</synopsis>
      <description>
        This function can be used to retrieve the value of the local object
        variable at slot 0 (the "<code>this</code>" object) from non-static
        frames.  This function can retrieve the "<code>this</code>" object from
        native method frames, whereas <code>GetLocalObject()</code> would
        return <code>JVMTI_ERROR_OPAQUE_FRAME</code> in those cases.
      </description>
      <origin>new</origin>
      <capabilities>
        <required id="can_access_local_variables"></required>
      </capabilities>
      <parameters>
        <param id="thread">
          <jthread null="current" frame="frame"/>
          <description>
            The thread of the frame containing the variable's value.
          </description>
        </param>
        <param id="depth">
          <jframeID thread="thread"/>
          <description>
            The depth of the frame containing the variable's value.
          </description>
        </param>
        <param id="value_ptr">
          <outptr><jobject/></outptr>
            <description>
              On return, points to the variable's value.
            </description>
        </param>
      </parameters>
      <errors>
        <error id="JVMTI_ERROR_INVALID_SLOT">
          If the specified frame is a static method frame.
        </error>
      </errors>
    </function>
    <function id="GetLocalInt" num="22">
      <synopsis>Get Local Variable - Int</synopsis>
      <description>
        This function can be used to retrieve the value of a local
        variable whose type is <code>int</code>,
        <code>short</code>, <code>char</code>, <code>byte</code>, or
        <code>boolean</code>.
      </description>
      <origin>jvmdi</origin>
      <capabilities>
        <required id="can_access_local_variables"></required>
      </capabilities>
      <parameters>
        <param id="thread">
          <jthread null="current" frame="frame"/>
          <description>
            The thread of the frame containing the variable's value.
          </description>
        </param>
        <param id="depth">
          <jframeID thread="thread"/>
          <description>
            The depth of the frame containing the variable's value.
          </description>
        </param>
        <param id="slot">
          <jint/>
          <description>
            The variable's slot number.
          </description>
        </param>
        <param id="value_ptr">
          <outptr><jint/></outptr>
          <description>
            On return, points to the variable's value.
          </description>
        </param>
      </parameters>
      <errors>
        <error id="JVMTI_ERROR_INVALID_SLOT">
          Invalid <code>slot</code>.
        </error>
        <error id="JVMTI_ERROR_TYPE_MISMATCH">
          The variable type is not
          <code>int</code>, <code>short</code>,
          <code>char</code>, <code>byte</code>, or
          <code>boolean</code>.
        </error>
        <error id="JVMTI_ERROR_OPAQUE_FRAME">
          Not a visible frame
        </error>
      </errors>
    </function>

    <function id="GetLocalLong" num="23">
      <synopsis>Get Local Variable - Long</synopsis>
      <description>
        This function can be used to retrieve the value of a local
        variable whose type is <code>long</code>.
      </description>
      <origin>jvmdi</origin>
      <capabilities>
        <required id="can_access_local_variables"></required>
      </capabilities>
      <parameters>
        <param id="thread">
          <jthread null="current" frame="frame"/>
          <description>
            The thread of the frame containing the variable's value.
          </description>
        </param>
        <param id="depth">
          <jframeID thread="thread"/>
          <description>
            The depth of the frame containing the variable's value.
          </description>
        </param>
        <param id="slot">
          <jint/>
          <description>
            The variable's slot number.
          </description>
        </param>
        <param id="value_ptr">
          <outptr><jlong/></outptr>
          <description>
            On return, points to the variable's value.
          </description>
        </param>
      </parameters>
      <errors>
        <error id="JVMTI_ERROR_INVALID_SLOT">
          Invalid <code>slot</code>.
        </error>
        <error id="JVMTI_ERROR_TYPE_MISMATCH">
          The variable type is not <code>long</code>.
        </error>
        <error id="JVMTI_ERROR_OPAQUE_FRAME">
          Not a visible frame
        </error>
      </errors>
    </function>

    <function id="GetLocalFloat" num="24">
      <synopsis>Get Local Variable - Float</synopsis>
      <description>
        This function can be used to retrieve the value of a local
        variable whose type is <code>float</code>.
      </description>
      <origin>jvmdi</origin>
      <capabilities>
        <required id="can_access_local_variables"></required>
      </capabilities>
      <parameters>
        <param id="thread">
          <jthread null="current" frame="frame"/>
          <description>
            The thread of the frame containing the variable's value.
          </description>
        </param>
        <param id="depth">
          <jframeID thread="thread"/>
          <description>
            The depth of the frame containing the variable's value.
          </description>
        </param>
        <param id="slot">
          <jint/>
          <description>
            The variable's slot number.
          </description>
        </param>
        <param id="value_ptr">
          <outptr><jfloat/></outptr>
          <description>
            On return, points to the variable's value.
          </description>
        </param>
      </parameters>
      <errors>
        <error id="JVMTI_ERROR_INVALID_SLOT">
          Invalid <code>slot</code>.
        </error>
        <error id="JVMTI_ERROR_TYPE_MISMATCH">
          The variable type is not <code>float</code>.
        </error>
        <error id="JVMTI_ERROR_OPAQUE_FRAME">
          Not a visible frame
        </error>
      </errors>
    </function>

    <function id="GetLocalDouble" num="25">
      <synopsis>Get Local Variable - Double</synopsis>
      <description>
        This function can be used to retrieve the value of a local
        variable whose type is <code>long</code>.
      </description>
      <origin>jvmdi</origin>
      <capabilities>
        <required id="can_access_local_variables"></required>
      </capabilities>
      <parameters>
        <param id="thread">
          <jthread null="current" frame="frame"/>
          <description>
            The thread of the frame containing the variable's value.
          </description>
        </param>
        <param id="depth">
          <jframeID thread="thread"/>
          <description>
            The depth of the frame containing the variable's value.
          </description>
        </param>
        <param id="slot">
          <jint/>
          <description>
            The variable's slot number.
          </description>
        </param>
        <param id="value_ptr">
          <outptr><jdouble/></outptr>
          <description>
            On return, points to the variable's value.
          </description>
        </param>
      </parameters>
      <errors>
        <error id="JVMTI_ERROR_INVALID_SLOT">
          Invalid <code>slot</code>.
        </error>
        <error id="JVMTI_ERROR_TYPE_MISMATCH">
          The variable type is not <code>double</code>.
        </error>
        <error id="JVMTI_ERROR_OPAQUE_FRAME">
          Not a visible frame
        </error>
      </errors>
    </function>

    <function id="SetLocalObject" num="26">
      <synopsis>Set Local Variable - Object</synopsis>
      <description>
        This function can be used to set the value of a local
        variable whose type is <code>Object</code> or a subclass of <code>Object</code>.
      </description>
      <origin>jvmdi</origin>
      <capabilities>
        <required id="can_access_local_variables"></required>
      </capabilities>
      <parameters>
        <param id="thread">
          <jthread null="current" frame="frame"/>
          <description>
            The thread of the frame containing the variable's value.
          </description>
        </param>
        <param id="depth">
          <jframeID thread="thread"/>
          <description>
            The depth of the frame containing the variable's value.
          </description>
        </param>
        <param id="slot">
          <jint/>
          <description>
            The variable's slot number.
          </description>
        </param>
        <param id="value">
          <jobject/>
            <description>
              The new value for the variable.
            </description>
        </param>
      </parameters>
      <errors>
        <error id="JVMTI_ERROR_INVALID_SLOT">
          Invalid <code>slot</code>.
        </error>
        <error id="JVMTI_ERROR_TYPE_MISMATCH">
          The variable type is not
          <code>Object</code> or a subclass of <code>Object</code>.
        </error>
        <error id="JVMTI_ERROR_TYPE_MISMATCH">
          The supplied <paramlink id="value"/> is not compatible
          with the variable type.
        </error>
        <error id="JVMTI_ERROR_OPAQUE_FRAME">
          Not a visible frame
        </error>
      </errors>
    </function>

    <function id="SetLocalInt" num="27">
      <synopsis>Set Local Variable - Int</synopsis>
      <description>
        This function can be used to set the value of a local
        variable whose type is <code>int</code>,
        <code>short</code>, <code>char</code>, <code>byte</code>, or
        <code>boolean</code>.
      </description>
      <origin>jvmdi</origin>
      <capabilities>
        <required id="can_access_local_variables"></required>
      </capabilities>
      <parameters>
        <param id="thread">
          <jthread null="current" frame="frame"/>
          <description>
            The thread of the frame containing the variable's value.
          </description>
        </param>
        <param id="depth">
          <jframeID thread="thread"/>
          <description>
            The depth of the frame containing the variable's value.
          </description>
        </param>
        <param id="slot">
          <jint/>
          <description>
            The variable's slot number.
          </description>
        </param>
        <param id="value">
          <jint/>
          <description>
            The new value for the variable.
          </description>
        </param>
      </parameters>
      <errors>
        <error id="JVMTI_ERROR_INVALID_SLOT">
          Invalid <code>slot</code>.
        </error>
        <error id="JVMTI_ERROR_TYPE_MISMATCH">
          The variable type is not
          <code>int</code>, <code>short</code>,
          <code>char</code>, <code>byte</code>, or
          <code>boolean</code>.
        </error>
        <error id="JVMTI_ERROR_OPAQUE_FRAME">
          Not a visible frame
        </error>
      </errors>
    </function>

    <function id="SetLocalLong" num="28">
      <synopsis>Set Local Variable - Long</synopsis>
      <description>
        This function can be used to set the value of a local
        variable whose type is <code>long</code>.
      </description>
      <origin>jvmdi</origin>
      <capabilities>
        <required id="can_access_local_variables"></required>
      </capabilities>
      <parameters>
        <param id="thread">
          <jthread null="current" frame="frame"/>
          <description>
            The thread of the frame containing the variable's value.
          </description>
        </param>
        <param id="depth">
          <jframeID thread="thread"/>
          <description>
            The depth of the frame containing the variable's value.
          </description>
        </param>
        <param id="slot">
          <jint/>
          <description>
            The variable's slot number.
          </description>
        </param>
        <param id="value">
          <jlong/>
          <description>
            The new value for the variable.
          </description>
        </param>
      </parameters>
      <errors>
        <error id="JVMTI_ERROR_INVALID_SLOT">
          Invalid <code>slot</code>.
        </error>
        <error id="JVMTI_ERROR_TYPE_MISMATCH">
          The variable type is not <code>long</code>.
        </error>
        <error id="JVMTI_ERROR_OPAQUE_FRAME">
          Not a visible frame
        </error>
      </errors>
    </function>

    <function id="SetLocalFloat" num="29">
      <synopsis>Set Local Variable - Float</synopsis>
      <description>
        This function can be used to set the value of a local
        variable whose type is <code>float</code>.
      </description>
      <origin>jvmdi</origin>
      <capabilities>
        <required id="can_access_local_variables"></required>
      </capabilities>
      <parameters>
        <param id="thread">
          <jthread null="current" frame="frame"/>
          <description>
            The thread of the frame containing the variable's value.
          </description>
        </param>
        <param id="depth">
          <jframeID thread="thread"/>
          <description>
            The depth of the frame containing the variable's value.
          </description>
        </param>
        <param id="slot">
          <jint/>
          <description>
            The variable's slot number.
          </description>
        </param>
        <param id="value">
          <jfloat/>
          <description>
            The new value for the variable.
          </description>
        </param>
      </parameters>
      <errors>
        <error id="JVMTI_ERROR_INVALID_SLOT">
          Invalid <code>slot</code>.
        </error>
        <error id="JVMTI_ERROR_TYPE_MISMATCH">
          The variable type is not <code>float</code>.
        </error>
        <error id="JVMTI_ERROR_OPAQUE_FRAME">
          Not a visible frame
        </error>
      </errors>
    </function>

    <function id="SetLocalDouble" num="30">
      <synopsis>Set Local Variable - Double</synopsis>
      <description>
        This function can be used to set the value of a local
        variable whose type is <code>double</code>.
      </description>
      <origin>jvmdi</origin>
      <capabilities>
        <required id="can_access_local_variables"></required>
      </capabilities>
      <parameters>
        <param id="thread">
          <jthread null="current" frame="frame"/>
          <description>
            The thread of the frame containing the variable's value.
          </description>
        </param>
        <param id="depth">
          <jframeID thread="thread"/>
          <description>
            The depth of the frame containing the variable's value.
          </description>
        </param>
        <param id="slot">
          <jint/>
          <description>
            The variable's slot number.
          </description>
        </param>
        <param id="value">
          <jdouble/>
          <description>
            The new value for the variable.
          </description>
        </param>
      </parameters>
      <errors>
        <error id="JVMTI_ERROR_INVALID_SLOT">
          Invalid <code>slot</code>.
        </error>
        <error id="JVMTI_ERROR_TYPE_MISMATCH">
          The variable type is not <code>double</code>.
        </error>
        <error id="JVMTI_ERROR_OPAQUE_FRAME">
          Not a visible frame
        </error>
      </errors>
    </function>
  </category>

  <category id="breakpointCategory" label="Breakpoint">

    <intro>
    </intro>

    <function id="SetBreakpoint" num="38">
      <synopsis>Set Breakpoint</synopsis>
      <description>
        Set a breakpoint at the instruction indicated by
        <code>method</code> and <code>location</code>.
        An instruction can only have one breakpoint.
        <p/>
        Whenever the designated instruction is about to be executed, a
        <eventlink id="Breakpoint"></eventlink> event is generated.
      </description>
      <origin>jvmdi</origin>
      <capabilities>
        <required id="can_generate_breakpoint_events"></required>
      </capabilities>
      <parameters>
        <param id="klass">
          <jclass method="method"/>
            <description>
              The class in which to set the breakpoint
            </description>
        </param>
        <param id="method">
          <jmethodID class="klass"/>
            <description>
              The method in which to set the breakpoint
            </description>
        </param>
        <param id="location">
          <jlocation/>
          <description>
            the index of the instruction at which to set the breakpoint

          </description>
        </param>
      </parameters>
      <errors>
        <error id="JVMTI_ERROR_DUPLICATE">
          The designated bytecode already has a breakpoint.
        </error>
      </errors>
    </function>

    <function id="ClearBreakpoint" num="39">
      <synopsis>Clear Breakpoint</synopsis>
      <description>
        Clear the breakpoint at the bytecode indicated by
        <code>method</code> and <code>location</code>.
      </description>
      <origin>jvmdi</origin>
      <capabilities>
        <required id="can_generate_breakpoint_events"></required>
      </capabilities>
      <parameters>
        <param id="klass">
          <jclass method="method"/>
            <description>
              The class in which to clear the breakpoint
            </description>
        </param>
        <param id="method">
          <jmethodID class="klass"/>
            <description>
              The method in which to clear the breakpoint
            </description>
        </param>
        <param id="location">
          <jlocation/>
          <description>
            the index of the instruction at which to clear the breakpoint
          </description>
        </param>
      </parameters>
      <errors>
        <error id="JVMTI_ERROR_NOT_FOUND">
          There's no breakpoint at the designated bytecode.
        </error>
      </errors>
    </function>

  </category>

  <category id="fieldWatch" label="Watched Field">

    <intro>
    </intro>

    <function id="SetFieldAccessWatch" num="41">
      <synopsis>Set Field Access Watch</synopsis>
      <description>
        Generate a <eventlink id="FieldAccess"></eventlink> event
        when the field specified
        by <code>klass</code> and
        <code>field</code> is about to be accessed.
        An event will be generated for each access of the field
        until it is canceled with
        <functionlink id="ClearFieldAccessWatch"></functionlink>.
        Field accesses from Java programming language code or from JNI code are watched,
        fields modified by other means are not watched.
        Note that <jvmti/> 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
        <functionlink id="SetFieldModificationWatch"></functionlink>
        to monitor modifications.
      </description>
      <origin>jvmdi</origin>
      <capabilities>
        <required id="can_generate_field_access_events"></required>
      </capabilities>
      <parameters>
        <param id="klass">
          <jclass field="field"/>
            <description>
              The class containing the field to watch
            </description>
        </param>
        <param id="field">
          <jfieldID class="klass"/>
            <description>
              The field to watch

            </description>
        </param>
      </parameters>
      <errors>
        <error id="JVMTI_ERROR_DUPLICATE">
          The designated field is already being watched for accesses.
        </error>
      </errors>
    </function>

    <function id="ClearFieldAccessWatch" num="42">
      <synopsis>Clear Field Access Watch</synopsis>
      <description>
        Cancel a field access watch previously set by
        <functionlink id="SetFieldAccessWatch"></functionlink>, on the
        field specified
        by <code>klass</code> and
        <code>field</code>.
      </description>
      <origin>jvmdi</origin>
      <capabilities>
        <required id="can_generate_field_access_events"></required>
      </capabilities>
      <parameters>
        <param id="klass">
          <jclass field="field"/>
            <description>
              The class containing the field to watch
            </description>
        </param>
        <param id="field">
          <jfieldID class="klass"/>
            <description>
              The field to watch

            </description>
        </param>
      </parameters>
      <errors>
        <error id="JVMTI_ERROR_NOT_FOUND">
          The designated field is not being watched for accesses.
        </error>
      </errors>
    </function>

    <function id="SetFieldModificationWatch" num="43">
      <synopsis>Set Field Modification Watch</synopsis>
      <description>
        Generate a <eventlink id="FieldModification"></eventlink> event
        when the field specified
        by <code>klass</code> and
        <code>field</code> is about to be modified.
        An event will be generated for each modification of the field
        until it is canceled with
        <functionlink id="ClearFieldModificationWatch"></functionlink>.
        Field modifications from Java programming language code or from JNI code are watched,
        fields modified by other means are not watched.
        Note that <jvmti/> users should be aware that their own field modifications
        will trigger the watch.
        A field can only have one field modification watch set.
      </description>
      <origin>jvmdi</origin>
      <capabilities>
        <required id="can_generate_field_modification_events"></required>
      </capabilities>
      <parameters>
        <param id="klass">
          <jclass field="field"/>
            <description>
              The class containing the field to watch
            </description>
        </param>
        <param id="field">
          <jfieldID class="klass"/>
            <description>
              The field to watch

            </description>
        </param>
      </parameters>
      <errors>
        <error id="JVMTI_ERROR_DUPLICATE">
          The designated field is already being watched for modifications.
        </error>
      </errors>
    </function>

    <function id="ClearFieldModificationWatch" num="44">
      <synopsis>Clear Field Modification Watch</synopsis>
      <description>

        Cancel a field modification watch previously set by
        <functionlink id="SetFieldModificationWatch"></functionlink>, on the
        field specified
        by <code>klass</code> and
        <code>field</code>.
      </description>
      <origin>jvmdi</origin>
      <capabilities>
        <required id="can_generate_field_modification_events"></required>
      </capabilities>
      <parameters>
        <param id="klass">
          <jclass field="field"/>
            <description>
              The class containing the field to watch
            </description>
        </param>
        <param id="field">
          <jfieldID class="klass"/>
            <description>
              The field to watch

            </description>
        </param>
      </parameters>
      <errors>
        <error id="JVMTI_ERROR_NOT_FOUND">
          The designated field is not being watched for modifications.
        </error>
      </errors>
    </function>
  </category>

  <category id="module" label="Module">

    <intro>
    </intro>

    <function id="GetAllModules" num="3" since="9">
      <synopsis>Get All Modules</synopsis>
      <description>
        Return an array of all modules loaded in the virtual machine.
        The array includes the unnamed module for each class loader.
        The number of modules in the array is returned via
        <code>module_count_ptr</code>, and the array itself via
        <code>modules_ptr</code>.
        <p/>
      </description>
      <origin>new</origin>
      <capabilities>
      </capabilities>
      <parameters>
        <param id="module_count_ptr">
          <outptr><jint/></outptr>
          <description>
            On return, points to the number of returned modules.
          </description>
        </param>
        <param id="modules_ptr">
          <allocbuf outcount="module_count_ptr"><jobject/></allocbuf>
            <description>
              On return, points to an array of references, one
              for each module.
            </description>
        </param>
      </parameters>
      <errors>
      </errors>
    </function>

    <function id="GetNamedModule" num="40" since="9">
      <synopsis>Get Named Module</synopsis>
      <description>
        Return the <code>java.lang.Module</code> object for a named
        module defined to a class loader that contains a given package.
        The module is returned via <code>module_ptr</code>.
        <p/>
        If a named module is defined to the class loader and it
        contains the package then that named module is returned,
        otherwise <code>NULL</code> is returned.
        <p/>
      </description>
      <origin>new</origin>
      <capabilities>
      </capabilities>
      <parameters>
        <param id="class_loader">
          <ptrtype>
            <jobject/>
            <nullok>the bootstrap loader is assumed</nullok>
          </ptrtype>
          <description>
            A class loader.
            If the <code>class_loader</code> is not <code>NULL</code>
            or a subclass of <code>java.lang.ClassLoader</code>
            this function returns
            <errorlink id="JVMTI_ERROR_ILLEGAL_ARGUMENT"></errorlink>.
          </description>
        </param>
        <param id="package_name">
          <inbuf><char/></inbuf>
          <description>
            The name of the package, encoded as a
            <internallink id="mUTF">modified UTF-8</internallink> string.
            The package name is in internal form (JVMS 4.2.1);
            identifiers are separated by forward slashes rather than periods.
          </description>
        </param>
        <param id="module_ptr">
          <outptr><jobject/></outptr>
          <description>
            On return, points to a <code>java.lang.Module</code> object
            or points to <code>NULL</code>.
          </description>
        </param>
      </parameters>
      <errors>
        <error id="JVMTI_ERROR_ILLEGAL_ARGUMENT">
          If class loader is not <code>NULL</code> and is not a class loader object.
        </error>
      </errors>
    </function>

    <function id="AddModuleReads" num="94" since="9">
      <synopsis>Add Module Reads</synopsis>
      <description>
         Update a module to read another module. This function is a no-op
         when <paramlink id="module"></paramlink> is an unnamed module.
         This function facilitates the instrumentation of code
         in named modules where that instrumentation requires
         expanding the set of modules that a module reads.
      </description>
      <origin>new</origin>
      <capabilities>
      </capabilities>
      <parameters>
        <param id="module">
          <ptrtype><jobject/></ptrtype>
          <description>
            The module to update.
          </description>
        </param>
        <param id="to_module">
          <ptrtype><jobject/></ptrtype>
          <description>
            The additional module to read.
          </description>
        </param>
      </parameters>
      <errors>
        <error id="JVMTI_ERROR_INVALID_MODULE">
          If <paramlink id="module"></paramlink> is not a module object.
        </error>
        <error id="JVMTI_ERROR_INVALID_MODULE">
          If <paramlink id="to_module"></paramlink> is not a module object.
        </error>
        <error id="JVMTI_ERROR_UNMODIFIABLE_MODULE">
          if the module cannot be modified.
          See <functionlink id="IsModifiableModule"/>.
        </error>
      </errors>
    </function>

    <function id="AddModuleExports" num="95" since="9">
      <synopsis>Add Module Exports</synopsis>
      <description>
         Update a module to export a package to another module.
         This function is a no-op when <paramlink id="module"></paramlink>
         is an unnamed module or an open module.
         This function facilitates the instrumentation of code
         in named modules where that instrumentation requires
         expanding the set of packages that a module exports.
      </description>
      <origin>new</origin>
      <capabilities>
      </capabilities>
      <parameters>
        <param id="module">
          <ptrtype><jobject/></ptrtype>
          <description>
            The module to update.
          </description>
        </param>
        <param id="pkg_name">
          <inbuf><char/></inbuf>
          <description>
            The exported package name.
          </description>
        </param>
        <param id="to_module">
          <ptrtype><jobject/></ptrtype>
          <description>
            The module the package is exported to.
            If the <code>to_module</code> is not a subclass of
            <code>java.lang.Module</code> this function returns
            <errorlink id="JVMTI_ERROR_INVALID_MODULE"></errorlink>.
          </description>
        </param>
      </parameters>
      <errors>
        <error id="JVMTI_ERROR_INVALID_MODULE">
          If <paramlink id="module"></paramlink> is not a module object.
        </error>
        <error id="JVMTI_ERROR_INVALID_MODULE">
          If <paramlink id="to_module"></paramlink> is not a module object.
        </error>
        <error id="JVMTI_ERROR_ILLEGAL_ARGUMENT">
          If the package <paramlink id="pkg_name"></paramlink>
          does not belong to the module.
        </error>
        <error id="JVMTI_ERROR_UNMODIFIABLE_MODULE">
          if the module cannot be modified.
          See <functionlink id="IsModifiableModule"/>.
        </error>
      </errors>
    </function>

    <function id="AddModuleOpens" num="96" since="9">
      <synopsis>Add Module Opens</synopsis>
      <description>
         Update a module to open a package to another module.
         This function is a no-op when <paramlink id="module"></paramlink>
         is an unnamed module or an open module.
         This function facilitates the instrumentation of code
         in modules where that instrumentation requires
         expanding the set of packages that a module opens to
         other modules.
      </description>
      <origin>new</origin>
      <capabilities>
      </capabilities>
      <parameters>
        <param id="module">
          <ptrtype><jobject/></ptrtype>
          <description>
            The module to update.
          </description>
        </param>
        <param id="pkg_name">
          <inbuf><char/></inbuf>
          <description>
            The package name of the package to open.
          </description>
        </param>
        <param id="to_module">
          <ptrtype><jobject/></ptrtype>
          <description>
            The module with the package to open.
            If the <code>to_module</code> is not a subclass of
            <code>java.lang.Module</code> this function returns
            <errorlink id="JVMTI_ERROR_INVALID_MODULE"></errorlink>.
          </description>
        </param>
      </parameters>
      <errors>
        <error id="JVMTI_ERROR_INVALID_MODULE">
          If <paramlink id="module"></paramlink> is not a module object.
        </error>
        <error id="JVMTI_ERROR_INVALID_MODULE">
          If <paramlink id="to_module"></paramlink> is not a module object.
        </error>
        <error id="JVMTI_ERROR_ILLEGAL_ARGUMENT">
          If the package <paramlink id="pkg_name"></paramlink>
          does not belong to the module.
        </error>
        <error id="JVMTI_ERROR_UNMODIFIABLE_MODULE">
          if the module cannot be modified.
          See <functionlink id="IsModifiableModule"/>.
        </error>
      </errors>
    </function>

    <function id="AddModuleUses" num="97" since="9">
      <synopsis>Add Module Uses</synopsis>
      <description>
         Updates a module to add a service to the set of services that
         a module uses. This function is a no-op when the module
         is an unnamed module.
         This function facilitates the instrumentation of code
         in named modules where that instrumentation requires
         expanding the set of services that a module is using.
      </description>
      <origin>new</origin>
      <capabilities>
      </capabilities>
      <parameters>
        <param id="module">
          <ptrtype><jobject/></ptrtype>
          <description>
            The module to update.
          </description>
        </param>
        <param id="service">
          <ptrtype><jclass/></ptrtype>
          <description>
            The service to use.
          </description>
        </param>
      </parameters>
      <errors>
        <error id="JVMTI_ERROR_INVALID_MODULE">
          If <paramlink id="module"></paramlink> is not a module object.
        </error>
        <error id="JVMTI_ERROR_INVALID_CLASS">
          If <paramlink id="service"></paramlink> is not a class object.
        </error>
        <error id="JVMTI_ERROR_UNMODIFIABLE_MODULE">
          if the module cannot be modified.
          See <functionlink id="IsModifiableModule"/>.
        </error>
      </errors>
    </function>

    <function id="AddModuleProvides" num="98" since="9">
      <synopsis>Add Module Provides</synopsis>
      <description>
         Updates a module to add a service to the set of services that
         a module provides. This function is a no-op when the module
         is an unnamed module.
         This function facilitates the instrumentation of code
         in named modules where that instrumentation requires
         changes to the services that are provided.
      </description>
      <origin>new</origin>
      <capabilities>
      </capabilities>
      <parameters>
        <param id="module">
          <ptrtype><jobject/></ptrtype>
          <description>
            The module to update.
          </description>
        </param>
        <param id="service">
          <ptrtype><jclass/></ptrtype>
          <description>
            The service to provide.
          </description>
        </param>
        <param id="impl_class">
          <ptrtype><jclass/></ptrtype>
          <description>
            The implementation class for the provided service.
          </description>
        </param>
      </parameters>
      <errors>
        <error id="JVMTI_ERROR_INVALID_MODULE">
          If <paramlink id="module"></paramlink> is not a module object.
        </error>
        <error id="JVMTI_ERROR_INVALID_CLASS">
          If <paramlink id="service"></paramlink> is not a class object.
        </error>
        <error id="JVMTI_ERROR_INVALID_CLASS">
          If <paramlink id="impl_class"></paramlink> is not a class object.
        </error>
        <error id="JVMTI_ERROR_UNMODIFIABLE_MODULE">
          if the module cannot be modified.
          See <functionlink id="IsModifiableModule"/>.
        </error>
      </errors>
    </function>

    <function id="IsModifiableModule" num="99" since="9">
      <synopsis>Is Modifiable Module</synopsis>
      <description>
        Determines whether a module is modifiable.
        If a module is modifiable then this module can be updated with
        <functionlink id="AddModuleReads"/>, <functionlink id="AddModuleExports"/>,
        <functionlink id="AddModuleOpens"/>, <functionlink id="AddModuleUses"/>,
        and <functionlink id="AddModuleProvides"/>. If a module is not modifiable
        then the module can not be updated with these functions. The result of
        this function is always <code>JNI_TRUE</code> when called to determine
        if an unnamed module is modifiable.
      </description>
      <origin>new</origin>
      <capabilities>
      </capabilities>
      <parameters>
        <param id="module">
          <ptrtype><jobject/></ptrtype>
          <description>
            The module to query.
          </description>
        </param>
        <param id="is_modifiable_module_ptr">
          <outptr><jboolean/></outptr>
          <description>
            On return, points to the boolean result of this function.
          </description>
        </param>
      </parameters>
      <errors>
        <error id="JVMTI_ERROR_INVALID_MODULE">
          If <paramlink id="module"></paramlink> is not a module object.
        </error>
      </errors>
    </function>

  </category>

  <category id="class" label="Class">

    <intro>
    </intro>

    <function id="GetLoadedClasses" jkernel="yes" num="78">
      <synopsis>Get Loaded Classes</synopsis>
      <description>
        Return an array of all classes loaded in the virtual machine.
        The number of classes in the array is returned via
        <code>class_count_ptr</code>, and the array itself via
        <code>classes_ptr</code>.
        <p/>
        Array classes of all types (including arrays of primitive types) are
        included in the returned list. Primitive classes (for example,
        <code>java.lang.Integer.TYPE</code>) are <i>not</i> included in this list.
      </description>
      <origin>jvmdi</origin>
      <capabilities>
      </capabilities>
      <parameters>
        <param id="class_count_ptr">
          <outptr><jint/></outptr>
          <description>
            On return, points to the number of classes.
          </description>
        </param>
        <param id="classes_ptr">
          <allocbuf outcount="class_count_ptr"><jclass/></allocbuf>
            <description>
              On return, points to an array of references, one
              for each class.
            </description>
        </param>
      </parameters>
      <errors>
      </errors>
    </function>

    <function id="GetClassLoaderClasses" jkernel="yes" num="79">
      <synopsis>Get Classloader Classes</synopsis>
      <description>
        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 <vmspec chapter="5.3"/>.
        <p/>
        The number of classes in the array is returned via
        <code>class_count_ptr</code>, and the array itself via
        <code>classes_ptr</code>.
      </description>
      <origin>jvmdi</origin>
      <capabilities>
      </capabilities>
      <parameters>
        <param id="initiating_loader">
          <ptrtype>
            <jobject/>
            <nullok>the classes initiated by the bootstrap loader will be returned</nullok>
          </ptrtype>
            <description>
              An initiating class loader.
            </description>
        </param>
        <param id="class_count_ptr">
          <outptr><jint/></outptr>
          <description>
            On return, points to the number of classes.
          </description>
        </param>
        <param id="classes_ptr">
          <allocbuf outcount="class_count_ptr"><jclass/></allocbuf>
            <description>
              On return, points to an array of references, one
              for each class.
            </description>
        </param>
      </parameters>
      <errors>
      </errors>
    </function>

    <function id="GetClassSignature" phase="start" num="48">
      <synopsis>Get Class Signature</synopsis>
      <description>
        For the class indicated by <code>klass</code>, return the
        <externallink id="jni/types.html#type-signatures">JNI
            type signature</externallink>
        and the generic signature of the class.
        For example, <code>java.util.List</code> is <code>"Ljava/util/List;"</code>
        and <code>int[]</code> is <code>"[I"</code>
        The returned name for primitive classes
        is the type signature character of the corresponding primitive type.
        For example, <code>java.lang.Integer.TYPE</code> is <code>"I"</code>.
      </description>
      <origin>jvmdiClone</origin>
      <capabilities>
      </capabilities>
      <parameters>
        <param id="klass">
          <jclass/>
            <description>
              The class to query.
            </description>
        </param>
        <param id="signature_ptr">
          <allocbuf>
            <char/>
            <nullok>the signature is not returned</nullok>
          </allocbuf>
          <description>
            On return, points to the JNI type signature of the class, encoded as a
            <internallink id="mUTF">modified UTF-8</internallink> string.
          </description>
        </param>
        <param id="generic_ptr">
          <allocbuf>
            <char/>
            <nullok>the generic signature is not returned</nullok>
          </allocbuf>
          <description>
            On return, points to the generic signature of the class, encoded as a
            <internallink id="mUTF">modified UTF-8</internallink> string.
            If there is no generic signature attribute for the class, then,
            on return, points to <code>NULL</code>.
          </description>
        </param>
      </parameters>
      <errors>
      </errors>
    </function>

    <function id="GetClassStatus" phase="start" num="49">
      <synopsis>Get Class Status</synopsis>
      <description>
        Get the status of the class. Zero or more of the following bits can be
        set.
        <constants id="jvmtiClassStatus" label="Class Status Flags" kind="bits">
          <constant id="JVMTI_CLASS_STATUS_VERIFIED" num="1">
            Class bytecodes have been verified
          </constant>
          <constant id="JVMTI_CLASS_STATUS_PREPARED" num="2">
            Class preparation is complete
          </constant>
          <constant id="JVMTI_CLASS_STATUS_INITIALIZED" num="4">
            Class initialization is complete. Static initializer has been run.
          </constant>
          <constant id="JVMTI_CLASS_STATUS_ERROR" num="8">
            Error during initialization makes class unusable
          </constant>
          <constant id="JVMTI_CLASS_STATUS_ARRAY" num="16">
            Class is an array.  If set, all other bits are zero.
          </constant>
          <constant id="JVMTI_CLASS_STATUS_PRIMITIVE" num="32">
            Class is a primitive class (for example, <code>java.lang.Integer.TYPE</code>).
            If set, all other bits are zero.
          </constant>
        </constants>
      </description>
      <origin>jvmdi</origin>
      <capabilities>
      </capabilities>
      <parameters>
        <param id="klass">
          <jclass/>
            <description>
              The class to query.
            </description>
        </param>
        <param id="status_ptr">
          <outptr><jint/></outptr>
          <description>
            On return, points to the current state of this class as one or
            more of the <internallink id="jvmtiClassStatus">class status flags</internallink>.
          </description>
        </param>
      </parameters>
      <errors>
      </errors>
    </function>

    <function id="GetSourceFileName" phase="start" num="50">
      <synopsis>Get Source File Name</synopsis>
      <description>
        For the class indicated by <code>klass</code>, return the source file
        name via <code>source_name_ptr</code>. The returned string
        is a file name only and never contains a directory name.
        <p/>
        For primitive classes (for example, <code>java.lang.Integer.TYPE</code>)
        and for arrays this function returns
        <errorlink id="JVMTI_ERROR_ABSENT_INFORMATION"></errorlink>.
      </description>
      <origin>jvmdi</origin>
      <capabilities>
        <required id="can_get_source_file_name"></required>
      </capabilities>
      <parameters>
        <param id="klass">
          <jclass/>
            <description>
              The class to query.
            </description>
        </param>
        <param id="source_name_ptr">
          <allocbuf><char/></allocbuf>
          <description>
            On return, points to the class's source file name, encoded as a
            <internallink id="mUTF">modified UTF-8</internallink> string.
          </description>
        </param>
      </parameters>
      <errors>
        <error id="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.
        </error>
      </errors>
    </function>

    <function id="GetClassModifiers" phase="start" num="51">
      <synopsis>Get Class Modifiers</synopsis>
      <description>
        For the class indicated by <code>klass</code>, return the access
        flags
        via <code>modifiers_ptr</code>.
        Access flags are defined in <vmspec chapter="4"/>.
        <p/>
        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, <code>java.lang.Integer.TYPE</code>).
        <p/>
        If the class is a primitive class, its public modifier is always true,
        and its protected and private modifiers are always false.
        <p/>
        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.

      </description>
      <origin>jvmdi</origin>
      <capabilities>
      </capabilities>
      <parameters>
        <param id="klass">
          <jclass/>
            <description>
              The class to query.
            </description>
        </param>
        <param id="modifiers_ptr">
          <outptr><jint/></outptr>
          <description>
            On return, points to the current access flags of this class.

          </description>
        </param>
      </parameters>
      <errors>
      </errors>
    </function>

    <function id="GetClassMethods" phase="start" num="52">
      <synopsis>Get Class Methods</synopsis>
      <description>
        For the class indicated by <code>klass</code>, return a count of
        methods via <code>method_count_ptr</code> and a list of
        method IDs via <code>methods_ptr</code>. 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, <code>java.lang.Integer.TYPE</code>).
      </description>
      <origin>jvmdi</origin>
      <capabilities>
        <capability id="can_maintain_original_method_order"/>
      </capabilities>
      <parameters>
        <param id="klass">
          <jclass/>
            <description>
              The class to query.
            </description>
        </param>
        <param id="method_count_ptr">
          <outptr><jint/></outptr>
          <description>
            On return, points to the number of methods declared in this class.
          </description>
        </param>
        <param id="methods_ptr">
          <allocbuf outcount="method_count_ptr"><jmethodID class="klass"/></allocbuf>
            <description>
              On return, points to the method ID array.
            </description>
        </param>
      </parameters>
      <errors>
        <error id="JVMTI_ERROR_CLASS_NOT_PREPARED">
          <paramlink id="klass"></paramlink> is not prepared.
        </error>
      </errors>
    </function>

    <function id="GetClassFields" phase="start" num="53">
      <synopsis>Get Class Fields</synopsis>
      <description>
        For the class indicated by <code>klass</code>, return a count of fields
        via <code>field_count_ptr</code> and a list of field IDs via
        <code>fields_ptr</code>.
        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, <code>java.lang.Integer.TYPE</code>).
        Use JNI to determine the length of an array.
      </description>
      <origin>jvmdi</origin>
      <capabilities>
      </capabilities>
      <parameters>
        <param id="klass">
          <jclass/>
            <description>
              The class to query.
            </description>
        </param>
        <param id="field_count_ptr">
          <outptr><jint/></outptr>
          <description>
            On return, points to the number of fields declared in this class.
          </description>
        </param>
        <param id="fields_ptr">
          <allocbuf outcount="field_count_ptr"><jfieldID/></allocbuf>
            <description>
              On return, points to the field ID array.
            </description>
        </param>
      </parameters>
      <errors>
        <error id="JVMTI_ERROR_CLASS_NOT_PREPARED">
          <paramlink id="klass"></paramlink> is not prepared.
        </error>
      </errors>
    </function>

    <function id="GetImplementedInterfaces" phase="start" num="54">
      <synopsis>Get Implemented Interfaces</synopsis>
      <description>
        Return the direct super-interfaces of this class. For a class, this
        function returns the interfaces declared in its <code>implements</code>
        clause. For an interface, this function returns the interfaces declared in
        its <code>extends</code> clause.
        An empty interface list is returned for array classes and primitive classes
        (for example, <code>java.lang.Integer.TYPE</code>).
      </description>
      <origin>jvmdi</origin>
      <capabilities>
      </capabilities>
      <parameters>
        <param id="klass">
          <jclass/>
            <description>
              The class to query.
            </description>
        </param>
        <param id="interface_count_ptr">
          <outptr><jint/></outptr>
          <description>
            On return, points to the number of interfaces.
          </description>
        </param>
        <param id="interfaces_ptr">
          <allocbuf outcount="interface_count_ptr"><jclass/></allocbuf>
            <description>
              On return, points to the interface array.
            </description>
        </param>
      </parameters>
      <errors>
        <error id="JVMTI_ERROR_CLASS_NOT_PREPARED">
          <paramlink id="klass"></paramlink> is not prepared.
        </error>
      </errors>
    </function>

    <function id="GetClassVersionNumbers" phase="start" num="145" since="1.1">
      <synopsis>Get Class Version Numbers</synopsis>
      <description>
        For the class indicated by <code>klass</code>,
        return the minor and major version numbers,
        as defined in
        <vmspec chapter="4"/>.
      </description>
      <origin>new</origin>
      <capabilities>
      </capabilities>
      <parameters>
        <param id="klass">
          <jclass/>
            <description>
              The class to query.
            </description>
        </param>
        <param id="minor_version_ptr">
          <outptr><jint/></outptr>
          <description>
            On return, points to the value of the
            <code>minor_version</code> item of the
            Class File Format.
            Note: to be consistent with the Class File Format,
            the minor version number is the first parameter.
          </description>
        </param>
        <param id="major_version_ptr">
          <outptr><jint/></outptr>
          <description>
            On return, points to the value of the
            <code>major_version</code> item of the
            Class File Format.
          </description>
        </param>
      </parameters>
      <errors>
        <error id="JVMTI_ERROR_ABSENT_INFORMATION">
          The class is a primitive or array class.
        </error>
      </errors>
    </function>

    <function id="GetConstantPool" phase="start" num="146" since="1.1">
      <synopsis>Get Constant Pool</synopsis>
      <description>
        For the class indicated by <code>klass</code>,
        return the raw bytes of the constant pool in the format of the
        <code>constant_pool</code> item of
        <vmspec chapter="4"/>.
        The format of the constant pool may differ between versions
        of the Class File Format, so, the
        <functionlink id="GetClassVersionNumbers">minor and major
        class version numbers</functionlink> should be checked for
        compatibility.
        <p/>
        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
        <functionlink id="GetBytecodes">GetBytecodes()</functionlink>.
        That is, the bytecodes returned by GetBytecodes() will have
        constant pool indices which refer to constant pool entries returned
        by GetConstantPool().
        Note that since <functionlink id="RetransformClasses"/>
        and <functionlink id="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.
      </description>
      <origin>new</origin>
      <capabilities>
        <required id="can_get_constant_pool"></required>
      </capabilities>
      <parameters>
        <param id="klass">
          <jclass/>
            <description>
              The class to query.
            </description>
        </param>
        <param id="constant_pool_count_ptr">
          <outptr><jint/></outptr>
          <description>
            On return, points to the number of entries
            in the constant pool table plus one.
            This corresponds to the <code>constant_pool_count</code>
            item of the Class File Format.
          </description>
        </param>
        <param id="constant_pool_byte_count_ptr">
          <outptr><jint/></outptr>
          <description>
            On return, points to the number of bytes
            in the returned raw constant pool.
          </description>
        </param>
        <param id="constant_pool_bytes_ptr">
          <allocbuf outcount="constant_pool_byte_count_ptr"><uchar/></allocbuf>
            <description>
              On return, points to the raw constant pool, that is the bytes
              defined by the <code>constant_pool</code> item of the
              Class File Format
            </description>
        </param>
      </parameters>
      <errors>
        <error id="JVMTI_ERROR_ABSENT_INFORMATION">
          The class is a primitive or array class.
        </error>
      </errors>
    </function>

    <function id="IsInterface" phase="start" num="55">
      <synopsis>Is Interface</synopsis>
      <description>
        Determines whether a class object reference represents an interface.
        The <code>jboolean</code> result is
        <code>JNI_TRUE</code> if the "class" is actually an interface,
        <code>JNI_FALSE</code> otherwise.
      </description>
      <origin>jvmdi</origin>
      <capabilities>
      </capabilities>
      <parameters>
        <param id="klass">
          <jclass/>
            <description>
              The class to query.
            </description>
        </param>
        <param id="is_interface_ptr">
          <outptr><jboolean/></outptr>
          <description>
            On return, points to the boolean result of this function.

          </description>
        </param>
      </parameters>
      <errors>
      </errors>
    </function>

    <function id="IsArrayClass" phase="start" num="56">
      <synopsis>Is Array Class</synopsis>
      <description>
        Determines whether a class object reference represents an array.
        The <code>jboolean</code> result is
        <code>JNI_TRUE</code> if the class is an array,
        <code>JNI_FALSE</code> otherwise.
      </description>
      <origin>jvmdi</origin>
      <capabilities>
      </capabilities>
      <parameters>
        <param id="klass">
          <jclass/>
            <description>
              The class to query.
            </description>
        </param>
        <param id="is_array_class_ptr">
          <outptr><jboolean/></outptr>
          <description>
            On return, points to the boolean result of this function.

          </description>
        </param>
      </parameters>
      <errors>
      </errors>
    </function>

    <function id="IsModifiableClass" jkernel="yes" phase="start" num="45" since="1.1">
      <synopsis>Is Modifiable Class</synopsis>
      <description>
        Determines whether a class is modifiable.
        If a class is modifiable (<paramlink id="is_modifiable_class_ptr"/>
        returns <code>JNI_TRUE</code>) the class can be
        redefined with <functionlink id="RedefineClasses"/> (assuming
        the agent possesses the
        <fieldlink id="can_redefine_classes" struct="jvmtiCapabilities"/>
        capability) or
        retransformed with <functionlink id="RetransformClasses"/> (assuming
        the agent possesses the
        <fieldlink id="can_retransform_classes" struct="jvmtiCapabilities"/>
        capability).
        If a class is not modifiable (<paramlink id="is_modifiable_class_ptr"/>
        returns <code>JNI_FALSE</code>) the class can be neither
        redefined nor retransformed.
        <p/>
        Primitive classes (for example, <code>java.lang.Integer.TYPE</code>),
        array classes, and some implementation defined classes are never modifiable.
        <p/>
      </description>
      <origin>new</origin>
      <capabilities>
        <capability id="can_redefine_any_class">
          If possessed then all classes (except primitive, array, and some implementation defined
          classes) are modifiable with <functionlink id="RedefineClasses"/>.
        </capability>
        <capability id="can_retransform_any_class">
          If possessed then all classes (except primitive, array, and some implementation defined
          classes) are modifiable with <functionlink id="RetransformClasses"/>.
        </capability>
        <capability id="can_redefine_classes">
          No effect on the result of the function.
          But must additionally be possessed to modify the class with
          <functionlink id="RedefineClasses"/>.
        </capability>
        <capability id="can_retransform_classes">
          No effect on the result of the function.
          But must additionally be possessed to modify the class with
          <functionlink id="RetransformClasses"/>.
        </capability>
      </capabilities>
      <parameters>
        <param id="klass">
          <jclass/>
            <description>
              The class to query.
            </description>
        </param>
        <param id="is_modifiable_class_ptr">
          <outptr><jboolean/></outptr>
          <description>
            On return, points to the boolean result of this function.
          </description>
        </param>
      </parameters>
      <errors>
      </errors>
    </function>

    <function id="GetClassLoader" phase="start" num="57">
      <synopsis>Get Class Loader</synopsis>
      <description>
        For the class indicated by <code>klass</code>, return via
        <code>classloader_ptr</code> a reference to the class loader for the
        class.
      </description>
      <origin>jvmdi</origin>
      <capabilities>
      </capabilities>
      <parameters>
        <param id="klass">
          <jclass/>
            <description>
              The class to query.
            </description>
        </param>
        <param id="classloader_ptr">
          <outptr><jobject/></outptr>
            <description>
              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 <code>NULL</code>.
            </description>
        </param>
      </parameters>
      <errors>
      </errors>

    </function>

    <function id="GetSourceDebugExtension" phase="start" num="90">
      <synopsis>Get Source Debug Extension</synopsis>
      <description>
        For the class indicated by <code>klass</code>, return the debug
        extension via <code>source_debug_extension_ptr</code>.
        The returned string
        contains exactly the debug extension information present in the
        class file of <code>klass</code>.
      </description>
      <origin>jvmdi</origin>
      <capabilities>
        <required id="can_get_source_debug_extension"></required>
      </capabilities>
      <parameters>
        <param id="klass">
          <jclass/>
            <description>
              The class to query.
            </description>
        </param>
        <param id="source_debug_extension_ptr">
          <allocbuf><char/></allocbuf>
          <description>
            On return, points to the class's debug extension, encoded as a
            <internallink id="mUTF">modified UTF-8</internallink> string.
          </description>
        </param>
      </parameters>
      <errors>
        <error id="JVMTI_ERROR_ABSENT_INFORMATION">
          Class information does not include a debug extension.
        </error>
      </errors>
    </function>

    <function id="RetransformClasses" jkernel="yes" num="152" since="1.1">
      <synopsis>Retransform Classes</synopsis>
      <description>
        This function facilitates the
        <internallink id="bci">bytecode instrumentation</internallink>
        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, <functionlink id="RedefineClasses"/>
        function should be used instead.
        <p/>
        When classes are initially loaded or when they are
        <functionlink id="RedefineClasses">redefined</functionlink>,
        the initial class file bytes can be transformed with the
        <eventlink id="ClassFileLoadHook"/> event.
        This function reruns the transformation process
        (whether or not a transformation has previously occurred).
        This retransformation follows these steps:
        <ul>
          <li>starting from the initial class file bytes
          </li>
          <li>for each <fieldlink id="can_retransform_classes"
                     struct="jvmtiCapabilities">retransformation
                                                incapable</fieldlink>
            agent which received a
            <code>ClassFileLoadHook</code> event during the previous
            load or redefine, the bytes it returned
            (via the <code>new_class_data</code> parameter)
            are reused as the output of the transformation;
            note that this is equivalent to reapplying
            the previous transformation, unaltered. except that
            the <code>ClassFileLoadHook</code> event
            is <b>not</b> sent to these agents
          </li>
          <li>for each <fieldlink id="can_retransform_classes"
                     struct="jvmtiCapabilities">retransformation
                                                capable</fieldlink>
            agent, the <code>ClassFileLoadHook</code> event is sent,
            allowing a new transformation to be applied
          </li>
          <li>the transformed class file bytes are installed as the new
            definition of the class
          </li>
        </ul>
        See the <eventlink id="ClassFileLoadHook"/> event for more details.
        <p/>
        The initial class file bytes represent the bytes passed to
        <code>ClassLoader.defineClass</code>
        or <code>RedefineClasses</code> (before any transformations
        were applied), however they may not exactly match them.
        The constant pool may differ in ways described in
        <functionlink id="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.
        <p/>
        Retransformation can cause new versions of methods to be installed.
        Old method versions may become
        <internallink id="obsoleteMethods">obsolete</internallink>
        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.
        <p/>
        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.
        <p/>
        Threads need not be suspended.
        <p/>
        All breakpoints in the class are cleared.
        <p/>
        All attributes are updated.
        <p/>
        Instances of the retransformed class are not affected -- fields retain their
        previous values.
        <functionlink id="GetTag">Tags</functionlink> on the instances are
        also unaffected.
        <p/>
        In response to this call, no events other than the
        <eventlink id="ClassFileLoadHook"/> event
        will be sent.
        <p/>
        The retransformation may change method bodies, the constant pool and attributes
        (unless explicitly prohibited).
        The retransformation must not add, remove or rename fields or methods, change the
        signatures of methods, change modifiers, or change inheritance.
        The retransformation must not change the <code>NestHost</code>,
        <code>NestMembers</code>, or <code>Record</code> attributes.
        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 <eventlink id="ClassFileLoadHook"/> events, thus the
        returned error code reflects the result of the transformations.
        If any error code is returned other than <code>JVMTI_ERROR_NONE</code>,
        none of the classes to be retransformed will have a new definition installed.
        When this function returns (with the error code of <code>JVMTI_ERROR_NONE</code>)
        all of the classes to be retransformed will have their new definitions installed.
      </description>
      <origin>new</origin>
      <capabilities>
        <required id="can_retransform_classes"></required>
        <capability id="can_retransform_any_class"></capability>
      </capabilities>
      <parameters>
        <param id="class_count">
          <jint min="0"/>
          <description>
            The number of classes to be retransformed.
          </description>
        </param>
        <param id="classes">
          <inbuf incount="class_count"><jclass/></inbuf>
          <description>
            The array of classes to be retransformed.
          </description>
        </param>
      </parameters>
      <errors>
        <error id="JVMTI_ERROR_UNMODIFIABLE_CLASS">
          One of the <paramlink id="classes"/> cannot be modified.
          See <functionlink id="IsModifiableClass"/>.
        </error>
        <error id="JVMTI_ERROR_INVALID_CLASS">
          One of the <paramlink id="classes"/> is not a valid class.
        </error>
        <error id="JVMTI_ERROR_UNSUPPORTED_VERSION">
          A retransformed class file has a version number not supported by this VM.
        </error>
        <error id="JVMTI_ERROR_INVALID_CLASS_FORMAT">
          A retransformed class file is malformed (The VM would return a <code>ClassFormatError</code>).
        </error>
        <error id="JVMTI_ERROR_CIRCULAR_CLASS_DEFINITION">
          The retransformed class file definitions would lead to a circular definition
          (the VM would return a <code>ClassCircularityError</code>).
        </error>
        <error id="JVMTI_ERROR_FAILS_VERIFICATION">
          The retransformed class file bytes fail verification.
        </error>
        <error id="JVMTI_ERROR_NAMES_DONT_MATCH">
          The class name defined in a retransformed class file is
          different from the name in the old class object.
        </error>
        <error id="JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_ADDED">
          A retransformed class file would require adding a method.
        </error>
        <error id="JVMTI_ERROR_UNSUPPORTED_REDEFINITION_SCHEMA_CHANGED">
          A retransformed class file changes a field.
        </error>
        <error id="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.
        </error>
        <error id="JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_DELETED">
          A retransformed class file does not declare a method
          declared in the old class version.
        </error>
        <error id="JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_ATTRIBUTE_CHANGED">
          A retransformed class file has unsupported differences in class attributes.
        </error>
        <error id="JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_MODIFIERS_CHANGED">
          A retransformed class file has different class modifiers.
        </error>
        <error id="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.
        </error>
      </errors>
    </function>

    <function id="RedefineClasses" jkernel="yes" num="87">
      <synopsis>Redefine Classes</synopsis>
      <typedef id="jvmtiClassDefinition" label="Class redefinition description">
        <field id="klass">
          <jclass/>
            <description>
              Class object for this class
            </description>
        </field>
        <field id="class_byte_count">
          <jint/>
          <description>
            Number of bytes defining class (below)
          </description>
        </field>
        <field id="class_bytes">
          <inbuf incount="class_byte_count"><uchar/></inbuf>
          <description>
            Bytes defining class (in <vmspec chapter="4"/>)
          </description>
        </field>
      </typedef>
      <description>
        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
        <internallink id="bci">bytecode instrumentation</internallink>,
        <functionlink id="RetransformClasses"/> should be used.
        <p/>
        Redefinition can cause new versions of methods to be installed.
        Old method versions may become
        <internallink id="obsoleteMethods">obsolete</internallink>
        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
        <functionlink id="PopFrame"></functionlink>
        to pop frames with obsolete method versions.
        <p/>
        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.
        <p/>
        Threads need not be suspended.
        <p/>
        All breakpoints in the class are cleared.
        <p/>
        All attributes are updated.
        <p/>
        Instances of the redefined class are not affected -- fields retain their
        previous values.
        <functionlink id="GetTag">Tags</functionlink> on the instances are
        also unaffected.
        <p/>
        In response to this call, the <jvmti/> event
        <eventlink id="ClassFileLoadHook">Class File Load Hook</eventlink>
        will be sent (if enabled), but no other <jvmti/> events will be sent.
        <p/>
        The redefinition may change method bodies, the constant pool and attributes
        (unless explicitly prohibited).
        The redefinition must not add, remove or rename fields or methods, change the
        signatures of methods, change modifiers, or change inheritance.
        The redefinition must not change the <code>NestHost</code>,
        <code>NestMembers</code>, or <code>Record</code> attributes.
        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 <eventlink id="ClassFileLoadHook"/> events, thus the
        returned error code reflects the result of the transformations applied
        to the bytes passed into <paramlink id="class_definitions"/>.
        If any error code is returned other than <code>JVMTI_ERROR_NONE</code>,
        none of the classes to be redefined will have a new definition installed.
        When this function returns (with the error code of <code>JVMTI_ERROR_NONE</code>)
        all of the classes to be redefined will have their new definitions installed.
      </description>
      <origin>jvmdi</origin>
      <capabilities>
        <required id="can_redefine_classes"></required>
        <capability id="can_redefine_any_class"></capability>
      </capabilities>
      <parameters>
        <param id="class_count">
          <jint min="0"/>
          <description>
            The number of classes specified in <code>class_definitions</code>
          </description>
        </param>
        <param id="class_definitions">
          <inbuf incount="class_count"><struct>jvmtiClassDefinition</struct></inbuf>
          <description>
            The array of new class definitions
          </description>
        </param>
      </parameters>
      <errors>
        <error id="JVMTI_ERROR_NULL_POINTER">
          One of <code>class_bytes</code> is <code>NULL</code>.
        </error>
        <error id="JVMTI_ERROR_UNMODIFIABLE_CLASS">
          An element of <code>class_definitions</code> cannot be modified.
          See <functionlink id="IsModifiableClass"/>.
        </error>
        <error id="JVMTI_ERROR_INVALID_CLASS">
          An element of <code>class_definitions</code> is not a valid class.
        </error>
        <error id="JVMTI_ERROR_UNSUPPORTED_VERSION">
          A new class file has a version number not supported by this VM.
        </error>
        <error id="JVMTI_ERROR_INVALID_CLASS_FORMAT">
          A new class file is malformed (The VM would return a <code>ClassFormatError</code>).
        </error>
        <error id="JVMTI_ERROR_CIRCULAR_CLASS_DEFINITION">
          The new class file definitions would lead to a circular definition
          (the VM would return a <code>ClassCircularityError</code>).
        </error>
        <error id="JVMTI_ERROR_FAILS_VERIFICATION">
          The class bytes fail verification.
        </error>
        <error id="JVMTI_ERROR_NAMES_DONT_MATCH">
          The class name defined in a new class file is
          different from the name in the old class object.
        </error>
        <error id="JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_ADDED">
          A new class file would require adding a method.
        </error>
        <error id="JVMTI_ERROR_UNSUPPORTED_REDEFINITION_SCHEMA_CHANGED">
          A new class version changes a field.
        </error>
        <error id="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.
        </error>
        <error id="JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_DELETED">
          A new class version does not declare a method
          declared in the old class version.
        </error>
        <error id="JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_ATTRIBUTE_CHANGED">
          A new class version has unsupported differences in class attributes.
        </error>
        <error id="JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_MODIFIERS_CHANGED">
          A new class version has different modifiers.
        </error>
        <error id="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.
        </error>
        <error id="JVMTI_ERROR_UNMODIFIABLE_MODULE">
          A module cannot be modified.
          See <functionlink id="IsModifiableModule"/>.
        </error>
      </errors>
    </function>

  </category>

  <category id="object" label="Object">

    <function id="GetObjectSize" jkernel="yes" phase="start" num="154">
      <synopsis>Get Object Size</synopsis>
      <description>
        For the object indicated by <code>object</code>,
        return via <code>size_ptr</code> 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.
      </description>
      <origin>new</origin>
      <capabilities>
      </capabilities>
      <parameters>
        <param id="object">
          <jobject/>
            <description>
              The object to query.
            </description>
        </param>
        <param id="size_ptr">
          <outptr><jlong/></outptr>
          <description>
            On return, points to the object's size in bytes.
          </description>
        </param>
      </parameters>
      <errors>
      </errors>
    </function>

    <function id="GetObjectHashCode" phase="start" num="58">
      <synopsis>Get Object Hash Code</synopsis>
      <description>
        For the object indicated by <code>object</code>,
        return via <code>hash_code_ptr</code> 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
        <internallink id="Heap">tags</internallink>
        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
      </description>
      <origin>jvmdi</origin>
      <capabilities>
      </capabilities>
      <parameters>
        <param id="object">
          <jobject/>
            <description>
              The object to query.
            </description>
        </param>
        <param id="hash_code_ptr">
          <outptr><jint/></outptr>
          <description>
            On return, points to the object's hash code.
          </description>
        </param>
      </parameters>
      <errors>
      </errors>
    </function>

    <function id="GetObjectMonitorUsage" num="59">
      <synopsis>Get Object Monitor Usage</synopsis>
      <typedef id="jvmtiMonitorUsage" label="Object monitor usage information">
        <field id="owner">
          <jthread/>
            <description>
              The thread owning this monitor, or <code>NULL</code> if unused
            </description>
        </field>
        <field id="entry_count">
          <jint/>
          <description>
            The number of times the owning thread has entered the monitor
          </description>
        </field>
        <field id="waiter_count">
          <jint/>
          <description>
            The number of threads waiting to own this monitor
          </description>
        </field>
        <field id="waiters">
          <allocfieldbuf><jthread/></allocfieldbuf>
            <description>
              The <code>waiter_count</code> waiting threads
            </description>
        </field>
        <field id="notify_waiter_count">
          <jint/>
          <description>
            The number of threads waiting to be notified by this monitor
          </description>
        </field>
        <field id="notify_waiters">
          <allocfieldbuf><jthread/></allocfieldbuf>
            <description>
              The <code>notify_waiter_count</code> threads waiting to be notified
            </description>
        </field>
      </typedef>
      <description>
        Get information about the object's monitor.
        The fields of the <functionlink id="jvmtiMonitorUsage"></functionlink> structure
        are filled in with information about usage of the monitor.
          <todo>
            Decide and then clarify suspend requirements.
          </todo>
      </description>
      <origin>jvmdi</origin>
      <capabilities>
        <required id="can_get_monitor_info"></required>
      </capabilities>
      <parameters>
        <param id="object">
          <jobject/>
            <description>
              The object to query.
            </description>
        </param>
        <param id="info_ptr">
          <outptr><struct>jvmtiMonitorUsage</struct></outptr>
          <description>
            On return, filled with monitor information for the
            specified object.
          </description>
        </param>
      </parameters>
      <errors>
      </errors>
    </function>

    <elide>
    <function id="GetObjectMonitors" num="116">
      <synopsis>Get Object Monitors</synopsis>
      <description>
        Return the list of object monitors.
        <p/>
        Note: details about each monitor can be examined with
        <functionlink id="GetObjectMonitorUsage"></functionlink>.
      </description>
      <origin>new</origin>
      <capabilities>
        <required id="can_get_monitor_info"></required>
      </capabilities>
      <parameters>
        <param id="monitorCnt">
          <outptr><jint/></outptr>
          <description>
            On return, pointer to the number
            of monitors returned in <code>monitors_ptr</code>.
          </description>
        </param>
        <param id="monitors_ptr">
          <allocbuf outcount="monitorCnt"><jobject/></allocbuf>
            <description>
              On return, pointer to the monitor list.
            </description>
        </param>
      </parameters>
      <errors>
      </errors>
    </function>
    </elide>

  </category>

  <category id="fieldCategory" label="Field">

    <intro>
    </intro>

    <function id="GetFieldName" phase="start" num="60">
      <synopsis>Get Field Name (and Signature)</synopsis>
      <description>
        For the field indicated by <paramlink id="klass"/> and <paramlink id="field"/>,
        return the field name via <paramlink id="name_ptr"/> and field signature via
        <paramlink id="signature_ptr"/>.
        <p/>
        Field signatures are defined in the
        <externallink id="jni/index.html">JNI Specification</externallink>
        and are referred to as <code>field descriptors</code> in
        <vmspec chapter="4.3.2"/>.
      </description>
      <origin>jvmdiClone</origin>
      <capabilities>
      </capabilities>
      <parameters>
        <param id="klass">
          <jclass field="field"/>
            <description>
              The class of the field to query.
            </description>
        </param>
        <param id="field">
          <jfieldID class="klass"/>
            <description>
              The field to query.
            </description>
        </param>
        <param id="name_ptr">
          <allocbuf>
            <char/>
            <nullok>the name is not returned</nullok>
          </allocbuf>
          <description>
            On return, points to the field name, encoded as a
            <internallink id="mUTF">modified UTF-8</internallink> string.
          </description>
        </param>
        <param id="signature_ptr">
          <allocbuf>
            <char/>
            <nullok>the signature is not returned</nullok>
          </allocbuf>
          <description>
            On return, points to the field signature, encoded as a
            <internallink id="mUTF">modified UTF-8</internallink> string.
          </description>
        </param>
        <param id="generic_ptr">
          <allocbuf>
            <char/>
            <nullok>the generic signature is not returned</nullok>
          </allocbuf>
          <description>
            On return, points to the generic signature of the field, encoded as a
            <internallink id="mUTF">modified UTF-8</internallink> string.
            If there is no generic signature attribute for the field, then,
            on return, points to <code>NULL</code>.
          </description>
        </param>
      </parameters>
      <errors>
      </errors>
    </function>

    <function id="GetFieldDeclaringClass" phase="start" num="61">
      <synopsis>Get Field Declaring Class</synopsis>
      <description>
        For the field indicated by <code>klass</code> and <code>field</code>
        return the class that defined it via <code>declaring_class_ptr</code>.
        The declaring class will either be <code>klass</code>, a superclass, or
        an implemented interface.
      </description>
      <origin>jvmdi</origin>
      <capabilities>
      </capabilities>
      <parameters>
        <param id="klass">
          <jclass field="field"/>
            <description>
              The class to query.
            </description>
        </param>
        <param id="field">
          <jfieldID class="klass"/>
            <description>
              The field to query.
            </description>
        </param>
        <param id="declaring_class_ptr">
          <outptr><jclass/></outptr>
            <description>
              On return, points to the declaring class
            </description>
        </param>
      </parameters>
      <errors>
      </errors>
    </function>

    <function id="GetFieldModifiers" phase="start" num="62">
      <synopsis>Get Field Modifiers</synopsis>
      <description>
        For the field indicated by <code>klass</code> and <code>field</code>
        return the access flags via <code>modifiers_ptr</code>.
        Access flags are defined in <vmspec chapter="4"/>.
      </description>
      <origin>jvmdi</origin>
      <capabilities>
      </capabilities>
      <parameters>
        <param id="klass">
          <jclass field="field"/>
            <description>
              The class to query.
            </description>
        </param>
        <param id="field">
          <jfieldID class="klass"/>
            <description>
              The field to query.
            </description>
        </param>
        <param id="modifiers_ptr">
          <outptr><jint/></outptr>
          <description>
            On return, points to the access flags.
          </description>
        </param>
      </parameters>
      <errors>
      </errors>
    </function>

    <function id="IsFieldSynthetic" phase="start" num="63">
      <synopsis>Is Field Synthetic</synopsis>
      <description>
        For the field indicated by <code>klass</code> and <code>field</code>, return a
        value indicating whether the field is synthetic via <code>is_synthetic_ptr</code>.
        Synthetic fields are generated by the compiler but not present in the
        original source code.
      </description>
      <origin>jvmdi</origin>
      <capabilities>
        <required id="can_get_synthetic_attribute"></required>
      </capabilities>
      <parameters>
        <param id="klass">
          <jclass field="field"/>
            <description>
              The class of the field to query.
            </description>
        </param>
        <param id="field">
          <jfieldID class="klass"/>
            <description>
              The field to query.
            </description>
        </param>
        <param id="is_synthetic_ptr">
          <outptr><jboolean/></outptr>
          <description>
            On return, points to the boolean result of this function.
          </description>
        </param>
      </parameters>
      <errors>
      </errors>
    </function>

  </category>

  <category id="method" label="Method">

    <intro>
      These functions provide information about a method (represented as a
      <typelink id="jmethodID"/>) and set how methods are processed.
    </intro>

    <intro id="obsoleteMethods" label="Obsolete Methods">
      The functions <functionlink id="RetransformClasses"/> and
      <functionlink id="RedefineClasses"/> can cause new versions
      of methods to be installed.
      An original version of a method is considered equivalent
      to the new version if:
      <ul>
        <li>their bytecodes are the same except for indices into the
          constant pool and </li>
        <li>the referenced constants are equal.</li>
      </ul>
      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
      <functionlink id="IsMethodObsolete"/>.
    </intro>

    <function id="GetMethodName" phase="start" num="64">
      <synopsis>Get Method Name (and Signature)</synopsis>
      <description>
        For the method indicated by <code>method</code>,
        return the method name via <code>name_ptr</code> and method signature via
        <code>signature_ptr</code>.
        <p/>
        Method signatures are defined in the
        <externallink id="jni/index.html">JNI Specification</externallink>
        and are referred to as <code>method descriptors</code> in
        <vmspec chapter="4.3.3"/>.
        Note this is different
        than method signatures as defined in the <i>Java Language Specification</i>.
      </description>
      <origin>jvmdiClone</origin>
      <capabilities>
      </capabilities>
      <parameters>
        <param id="method">
          <jmethodID/>
            <description>
              The method to query.
            </description>
        </param>
        <param id="name_ptr">
          <allocbuf>
            <char/>
            <nullok>the name is not returned</nullok>
          </allocbuf>
          <description>
            On return, points to the method name, encoded as a
            <internallink id="mUTF">modified UTF-8</internallink> string.
          </description>
        </param>
        <param id="signature_ptr">
          <allocbuf>
            <char/>
            <nullok>the signature is not returned</nullok>
          </allocbuf>
          <description>
            On return, points to the method signature, encoded as a
            <internallink id="mUTF">modified UTF-8</internallink> string.
          </description>
        </param>
        <param id="generic_ptr">
          <allocbuf>
            <char/>
            <nullok>the generic signature is not returned</nullok>
          </allocbuf>
          <description>
            On return, points to the generic signature of the method, encoded as a
            <internallink id="mUTF">modified UTF-8</internallink> string.
            If there is no generic signature attribute for the method, then,
            on return, points to <code>NULL</code>.
          </description>
        </param>
      </parameters>
      <errors>
      </errors>
    </function>

    <function id="GetMethodDeclaringClass" phase="start" num="65">
      <synopsis>Get Method Declaring Class</synopsis>
      <description>
        For the method indicated by <code>method</code>,
        return the class that defined it via <code>declaring_class_ptr</code>.
      </description>
      <origin>jvmdi</origin>
      <capabilities>
      </capabilities>
      <parameters>
        <param id="klass">
          <jclass method="method"/>
            <description>
              The class to query.
            </description>
        </param>
        <param id="method">
          <jmethodID class="klass"/>
            <description>
              The method to query.
            </description>
        </param>
        <param id="declaring_class_ptr">
          <outptr><jclass/></outptr>
            <description>
              On return, points to the declaring class
            </description>
        </param>
      </parameters>
      <errors>
      </errors>
    </function>

    <function id="GetMethodModifiers" phase="start" num="66">
      <synopsis>Get Method Modifiers</synopsis>
      <description>
        For the method indicated by <code>method</code>,
        return the access flags via <code>modifiers_ptr</code>.
        Access flags are defined in <vmspec chapter="4"/>.
      </description>
      <origin>jvmdi</origin>
      <capabilities>
      </capabilities>
      <parameters>
        <param id="klass">
          <jclass method="method"/>
            <description>
              The class to query.
            </description>
        </param>
        <param id="method">
          <jmethodID class="klass"/>
            <description>
              The method to query.
            </description>
        </param>
        <param id="modifiers_ptr">
          <outptr><jint/></outptr>
          <description>
            On return, points to the access flags.
          </description>
        </param>
      </parameters>
      <errors>
      </errors>
    </function>

    <function id="GetMaxLocals" phase="start" num="68">
      <synopsis>Get Max Locals</synopsis>
      <description>
          For the method indicated by <code>method</code>,
          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.
          <p/>
          See <code>max_locals</code> in <vmspec chapter="4.7.3"/>.
      </description>
      <origin>jvmdi</origin>
      <capabilities>
      </capabilities>
      <parameters>
        <param id="klass">
          <jclass method="method"/>
            <description>
              The class to query.
            </description>
        </param>
        <param id="method">
          <jmethodID class="klass" native="error"/>
            <description>
              The method to query.
            </description>
        </param>
        <param id="max_ptr">
          <outptr><jint/></outptr>
          <description>
            On return, points to the maximum number of local slots
          </description>
        </param>
      </parameters>
      <errors>
      </errors>
    </function>

    <function id="GetArgumentsSize" phase="start" num="69">
      <synopsis>Get Arguments Size</synopsis>
      <description>
        For the method indicated by <code>method</code>,
        return via <code>max_ptr</code> the number of local variable slots used
        by the method's arguments.
        Note that two-word arguments use two slots.
      </description>
      <origin>jvmdi</origin>
      <capabilities>
      </capabilities>
      <parameters>
        <param id="klass">
          <jclass method="method"/>
            <description>
              The class to query.
            </description>
        </param>
        <param id="method">
          <jmethodID class="klass" native="error"/>
            <description>
              The method to query.
            </description>
        </param>
        <param id="size_ptr">
          <outptr><jint/></outptr>
          <description>
            On return, points to the number of argument slots
          </description>
        </param>
      </parameters>
      <errors>
      </errors>
    </function>

    <function id="GetLineNumberTable" phase="start" num="70">
      <synopsis>Get Line Number Table</synopsis>
      <typedef id="jvmtiLineNumberEntry" label="Line number table entry">
        <field id="start_location">
          <jlocation/>
          <description>
            the <datalink id="jlocation"></datalink> where the line begins
          </description>
        </field>
        <field id="line_number">
          <jint/>
          <description>
            the line number
          </description>
        </field>
      </typedef>
      <description>
        For the method indicated by <code>method</code>,
        return a table of source line number entries. The size of the table is
        returned via <code>entry_count_ptr</code> and the table itself is
        returned via <code>table_ptr</code>.
      </description>
      <origin>jvmdi</origin>
      <capabilities>
        <required id="can_get_line_numbers"></required>
      </capabilities>
      <parameters>
        <param id="klass">
          <jclass method="method"/>
            <description>
              The class to query.
            </description>
        </param>
        <param id="method">
          <jmethodID class="klass" native="error"/>
            <description>
              The method to query.
            </description>
        </param>
        <param id="entry_count_ptr">
          <outptr><jint/></outptr>
          <description>
            On return, points to the number of entries in the table
          </description>
        </param>
        <param id="table_ptr">
          <allocbuf outcount="entry_count_ptr"><struct>jvmtiLineNumberEntry</struct></allocbuf>
          <description>
            On return, points to the line number table pointer.
          </description>
        </param>
      </parameters>
      <errors>
        <error id="JVMTI_ERROR_ABSENT_INFORMATION">
          Class information does not include line numbers.
        </error>
      </errors>
    </function>

    <function id="GetMethodLocation" phase="start" num="71">
      <synopsis>Get Method Location</synopsis>
      <description>
        For the method indicated by <code>method</code>,
        return the beginning and ending addresses through
        <code>start_location_ptr</code> and <code>end_location_ptr</code>. In a
        conventional bytecode indexing scheme,
        <code>start_location_ptr</code> will always point to zero
        and <code>end_location_ptr</code>
        will always point to the bytecode count minus one.
      </description>
      <origin>jvmdi</origin>
      <capabilities>
      </capabilities>
      <parameters>
        <param id="klass">
          <jclass method="method"/>
            <description>
              The class to query.
            </description>
        </param>
        <param id="method">
          <jmethodID class="klass" native="error"/>
            <description>
              The method to query.
            </description>
        </param>
        <param id="start_location_ptr">
          <outptr><jlocation/></outptr>
          <description>
            On return, points to the first location, or
            <code>-1</code> if location information is not available.
            If the information is available and
            <functionlink id="GetJLocationFormat"></functionlink>
            returns <datalink id="JVMTI_JLOCATION_JVMBCI"></datalink>
            then this will always be zero.
          </description>
        </param>
        <param id="end_location_ptr">
          <outptr><jlocation/></outptr>
          <description>
            On return, points to the last location,
            or <code>-1</code> if location information is not available.
          </description>
        </param>
      </parameters>
      <errors>
        <error id="JVMTI_ERROR_ABSENT_INFORMATION">
          Class information does not include method sizes.
        </error>
      </errors>
    </function>

    <function id="GetLocalVariableTable" num="72">
      <synopsis>Get Local Variable Table</synopsis>
      <typedef id="jvmtiLocalVariableEntry" label="Local variable table entry">
        <field id="start_location">
          <jlocation/>
          <description>
            The code array index where the local variable is first valid
            (that is, where it must have a value).
          </description>
        </field>
        <field id="length">
          <jint/>
          <description>
            The length of the valid section for this local variable.
            The last code array index where the local variable is valid
            is <code>start_location + length</code>.
          </description>
        </field>
        <field id="name">
          <allocfieldbuf><char/></allocfieldbuf>
          <description>
            The local variable name, encoded as a
            <internallink id="mUTF">modified UTF-8</internallink> string.
          </description>
        </field>
        <field id="signature">
          <allocfieldbuf><char/></allocfieldbuf>
          <description>
            The local variable's type signature, encoded as a
            <internallink id="mUTF">modified UTF-8</internallink> string.
            The signature format is the same as that defined in
            <vmspec chapter="4.3.2"/>.
          </description>
        </field>
        <field id="generic_signature">
          <allocfieldbuf><char/></allocfieldbuf>
          <description>
            The local variable's generic signature, encoded as a
            <internallink id="mUTF">modified UTF-8</internallink> string.
            The value of this field will be <code>NULL</code> for any local
            variable which does not have a generic type.
          </description>
        </field>
        <field id="slot">
          <jint/>
          <description>
            The local variable's slot.  See <internallink id="local">Local Variables</internallink>.
          </description>
        </field>
      </typedef>
      <description>
        Return local variable information.
      </description>
      <origin>jvmdiClone</origin>
      <capabilities>
        <required id="can_access_local_variables"></required>
      </capabilities>
      <parameters>
        <param id="method">
          <jmethodID native="error"/>
            <description>
              The method to query.
            </description>
        </param>
        <param id="entry_count_ptr">
          <outptr><jint/></outptr>
          <description>
            On return, points to the number of entries in the table
          </description>
        </param>
        <param id="table_ptr">
          <allocbuf outcount="entry_count_ptr"><struct>jvmtiLocalVariableEntry</struct></allocbuf>
          <description>
            On return, points to an array of local variable table entries.
          </description>
        </param>
      </parameters>
      <errors>
        <error id="JVMTI_ERROR_ABSENT_INFORMATION">
          Class information does not include local variable
          information.
        </error>
      </errors>
    </function>

    <function id="GetBytecodes" phase="start" num="75">
      <synopsis>Get Bytecodes</synopsis>
      <description>
        For the method indicated by <code>method</code>,
        return the bytecodes that implement the method. The number of
        bytecodes is returned via <code>bytecode_count_ptr</code>. The bytecodes
        themselves are returned via <code>bytecodes_ptr</code>.
      </description>
      <origin>jvmdi</origin>
      <capabilities>
        <required id="can_get_bytecodes"></required>
      </capabilities>
      <parameters>
        <param id="klass">
          <jclass method="method"/>
            <description>
              The class to query.
            </description>
        </param>
        <param id="method">
          <jmethodID class="klass" native="error"/>
            <description>
              The method to query.
            </description>
        </param>
        <param id="bytecode_count_ptr">
          <outptr><jint/></outptr>
          <description>
            On return, points to the length of the bytecode array
          </description>
        </param>
        <param id="bytecodes_ptr">
          <allocbuf outcount="bytecode_count_ptr"><uchar/></allocbuf>
          <description>
            On return, points to the pointer to the bytecode array
          </description>
        </param>
      </parameters>
      <errors>
      </errors>
    </function>

    <function id="IsMethodNative" phase="start" num="76">
      <synopsis>Is Method Native</synopsis>
      <description>
        For the method indicated by <code>method</code>, return a
        value indicating whether the method is native via <code>is_native_ptr</code>
      </description>
      <origin>jvmdi</origin>
      <capabilities>
      </capabilities>
      <parameters>
        <param id="klass">
          <jclass method="method"/>
            <description>
              The class to query.
            </description>
        </param>
        <param id="method">
          <jmethodID class="klass"/>
            <description>
              The method to query.
            </description>
        </param>
        <param id="is_native_ptr">
          <outptr><jboolean/></outptr>
          <description>
            On return, points to the boolean result of this function.
          </description>
        </param>
      </parameters>
      <errors>
      </errors>
    </function>

    <function id="IsMethodSynthetic" phase="start" num="77">
      <synopsis>Is Method Synthetic</synopsis>
      <description>
        For the method indicated by <code>method</code>, return a
        value indicating whether the method is synthetic via <code>is_synthetic_ptr</code>.
        Synthetic methods are generated by the compiler but not present in the
        original source code.
      </description>
      <origin>jvmdi</origin>
      <capabilities>
        <required id="can_get_synthetic_attribute"></required>
      </capabilities>
      <parameters>
        <param id="klass">
          <jclass method="method"/>
            <description>
              The class to query.
            </description>
        </param>
        <param id="method">
          <jmethodID class="klass"/>
            <description>
              The method to query.
            </description>
        </param>
        <param id="is_synthetic_ptr">
          <outptr><jboolean/></outptr>
          <description>
            On return, points to the boolean result of this function.
          </description>
        </param>
      </parameters>
      <errors>
      </errors>
    </function>

    <function id="IsMethodObsolete" phase="start" num="91">
      <synopsis>Is Method Obsolete</synopsis>
      <description>
        Determine if a method ID refers to an
        <internallink id="obsoleteMethods">obsolete</internallink>
        method version.
      </description>
      <origin>jvmdi</origin>
      <capabilities>
      </capabilities>
      <parameters>
        <param id="klass">
          <jclass method="method"/>
            <description>
              The class to query.
            </description>
        </param>
        <param id="method">
          <jmethodID class="klass"/>
            <description>
              The method ID to query.
            </description>
        </param>
        <param id="is_obsolete_ptr">
          <outptr><jboolean/></outptr>
          <description>
            On return, points to the boolean result of this function.
          </description>
        </param>
      </parameters>
      <errors>
      </errors>
    </function>

    <function id="SetNativeMethodPrefix" jkernel="yes" phase="any" num="73" since="1.1">
      <synopsis>Set Native Method Prefix</synopsis>
      <description>
        This function modifies the failure handling of
        native method resolution by allowing retry
        with a prefix applied to the name.
        When used with the
        <eventlink id="ClassFileLoadHook">ClassFileLoadHook
        event</eventlink>, it enables native methods to be
        <internallink id="bci">instrumented</internallink>.
        <p/>
        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:
        <example>
native boolean foo(int x);</example>
        <p/>
        We could transform the class file (with the
        ClassFileLoadHook event) so that this becomes:
        <example>
boolean foo(int x) {
  <i>... record entry to foo ...</i>
  return wrapped_foo(x);
}

native boolean wrapped_foo(int x);</example>
        <p/>
        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.
        <p/>
        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 <code>wrapped_foo</code> needs to be
        resolved to the native implementation of <code>foo</code>,
        which might be:
        <example>
Java_somePackage_someClass_foo(JNIEnv* env, jint x)</example>
        <p/>
        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 <code>RegisterNatives</code>
        and the normal automatic resolution.  For
        <code>RegisterNatives</code>, the VM will attempt this
        association:
        <example>
method(foo) -> nativeImplementation(foo)</example>
        <p/>
        When this fails, the resolution will be retried with
        the specified prefix prepended to the method name,
        yielding the correct resolution:
        <example>
method(wrapped_foo) -> nativeImplementation(foo)</example>
        <p/>
        For automatic resolution, the VM will attempt:
        <example>
method(wrapped_foo) -> nativeImplementation(wrapped_foo)</example>
        <p/>
        When this fails, the resolution will be retried with
        the specified prefix deleted from the implementation name,
        yielding the correct resolution:
        <example>
method(wrapped_foo) -> nativeImplementation(foo)</example>
        <p/>
        Note that since the prefix is only used when standard
        resolution fails, native methods can be wrapped selectively.
        <p/>
        Since each <jvmti/> 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 <eventlink id="ClassFileLoadHook"/> event.
        Thus if three environments applied
        wrappers, <code>foo</code> might become
        <code>$env3_$env2_$env1_foo</code>.  But if, say,
        the second environment did not apply a wrapper to
        <code>foo</code> it would be just
        <code>$env3_$env1_foo</code>.  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
        <code>$env1_foo</code> is not a native method, the
        <code>$env1_</code> prefix is applied since
        <code>$env1_foo</code> exists.
        <p/>
        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.
      </description>
      <origin>new</origin>
      <capabilities>
        <required id="can_set_native_method_prefix"></required>
      </capabilities>
      <parameters>
        <param id="prefix">
          <inbuf>
            <char/>
            <nullok>
              any existing prefix in this environment is cancelled
            </nullok>
          </inbuf>
          <description>
            The prefix to apply, encoded as a
            <internallink id="mUTF">modified UTF-8</internallink> string.
          </description>
        </param>
      </parameters>
      <errors>
      </errors>
    </function>

    <function id="SetNativeMethodPrefixes" jkernel="yes" phase="any" num="74" since="1.1">
      <synopsis>Set Native Method Prefixes</synopsis>
      <description>
         For a normal agent, <functionlink id="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 manner as described for the
         application of prefixes from multiple <jvmti/> environments
         in <functionlink id="SetNativeMethodPrefix"/>.
         <p/>
         Any previous prefixes are replaced.  Thus, calling this
         function with a <paramlink id="prefix_count"/> of <code>0</code>
         disables prefixing in this environment.
         <p/>
         <functionlink id="SetNativeMethodPrefix"/> and this function
         are the two ways to set the prefixes.
         Calling <code>SetNativeMethodPrefix</code> with
         a prefix is the same as calling this function with
         <paramlink id="prefix_count"/> of <code>1</code>.
         Calling <code>SetNativeMethodPrefix</code> with
         <code>NULL</code> is the same as calling this function with
         <paramlink id="prefix_count"/> of <code>0</code>.
      </description>
      <origin>new</origin>
      <capabilities>
        <required id="can_set_native_method_prefix"></required>
      </capabilities>
      <parameters>
        <param id="prefix_count">
          <jint min="0"/>
            <description>
              The number of prefixes to apply.
            </description>
        </param>
        <param id="prefixes">
          <agentbuf>
            <char/>
          </agentbuf>
          <description>
            The prefixes to apply for this environment, each encoded as a
            <internallink id="mUTF">modified UTF-8</internallink> string.
          </description>
        </param>
      </parameters>
      <errors>
      </errors>
    </function>

  </category>

  <category id="RawMonitors" label="Raw Monitor">

    <function id="CreateRawMonitor" phase="onload" callbacksafe="safe" num="31">
      <synopsis>Create Raw Monitor</synopsis>
      <description>
        Create a raw monitor.
      </description>
      <origin>jvmdi</origin>
      <capabilities>
      </capabilities>
      <parameters>
        <param id="name">
          <inbuf><char/></inbuf>
          <description>
            A name to identify the monitor, encoded as a
            <internallink id="mUTF">modified UTF-8</internallink> string.
          </description>
        </param>
        <param id="monitor_ptr">
          <outptr><jrawMonitorID/></outptr>
          <description>
            On return, points to the created monitor.
          </description>
        </param>
      </parameters>
      <errors>
      </errors>
    </function>

    <function id="DestroyRawMonitor" phase="onload" callbacksafe="safe" num="32">
      <synopsis>Destroy Raw Monitor</synopsis>
      <description>
        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.
      </description>
      <origin>jvmdi</origin>
      <capabilities>
      </capabilities>
      <parameters>
        <param id="monitor">
          <jrawMonitorID/>
          <description>
            The monitor
          </description>
        </param>
      </parameters>
      <errors>
        <error id="JVMTI_ERROR_NOT_MONITOR_OWNER">
          Not monitor owner
        </error>
      </errors>
    </function>

    <function id="RawMonitorEnter" phase="any" callbacksafe="safe" impl="innative notrace" num="33">
      <synopsis>Raw Monitor Enter</synopsis>
      <description>
        Gain exclusive ownership of a raw monitor.
        The same thread may enter a monitor more then once.
        The thread must
        <functionlink id="RawMonitorExit">exit</functionlink>
        the monitor the same number of times as it is entered.
        If a monitor is entered during <code>OnLoad</code> (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.
      </description>
      <origin>jvmdi</origin>
      <capabilities>
      </capabilities>
      <parameters>
        <param id="monitor">
          <jrawMonitorID/>
          <description>
            The monitor
          </description>
        </param>
      </parameters>
      <errors>
      </errors>
    </function>

    <function id="RawMonitorExit" phase="any" callbacksafe="safe" impl="innative notrace" num="34">
      <synopsis>Raw Monitor Exit</synopsis>
      <description>
        Release exclusive ownership of a raw monitor.
      </description>
      <origin>jvmdi</origin>
      <capabilities>
      </capabilities>
      <parameters>
        <param id="monitor">
          <jrawMonitorID/>
          <description>
            The monitor
          </description>
        </param>
      </parameters>
      <errors>
        <error id="JVMTI_ERROR_NOT_MONITOR_OWNER">
          Not monitor owner
        </error>
      </errors>
    </function>

    <function id="RawMonitorWait" phase="any" callbacksafe="safe" impl="innative notrace" num="35">
      <synopsis>Raw Monitor Wait</synopsis>
      <description>
        Wait for notification of the raw monitor.
        <p/>
        Causes the current thread to wait until either another thread calls
        <functionlink id="RawMonitorNotify"/> or
        <functionlink id="RawMonitorNotifyAll"/>
        for the specified raw monitor, or the specified
        <paramlink id="millis">timeout</paramlink>
        has elapsed.
      </description>
      <origin>jvmdi</origin>
      <capabilities>
      </capabilities>
      <parameters>
        <param id="monitor">
          <jrawMonitorID/>
          <description>
            The monitor
          </description>
        </param>
        <param id="millis">
          <jlong/>
          <description>
            The timeout, in milliseconds.  If the timeout is
            zero, then real time is not taken into consideration
            and the thread simply waits until notified.
          </description>
        </param>
      </parameters>
      <errors>
        <error id="JVMTI_ERROR_NOT_MONITOR_OWNER">
          Not monitor owner
        </error>
        <error id="JVMTI_ERROR_INTERRUPT">
          Wait was interrupted, try again
        </error>
      </errors>
    </function>

    <function id="RawMonitorNotify" phase="any" callbacksafe="safe" impl="notrace" num="36">
      <synopsis>Raw Monitor Notify</synopsis>
      <description>
        Notify a single thread waiting on the raw monitor.
      </description>
      <origin>jvmdi</origin>
      <capabilities>
      </capabilities>
      <parameters>
        <param id="monitor">
          <jrawMonitorID/>
          <description>
            The monitor
          </description>
        </param>
      </parameters>
      <errors>
        <error id="JVMTI_ERROR_NOT_MONITOR_OWNER">
          Not monitor owner
        </error>
      </errors>
    </function>

    <function id="RawMonitorNotifyAll" phase="any" callbacksafe="safe" impl="notrace" num="37">
      <synopsis>Raw Monitor Notify All</synopsis>
      <description>
        Notify all threads waiting on the raw monitor.
      </description>
      <origin>jvmdi</origin>
      <capabilities>
      </capabilities>
      <parameters>
        <param id="monitor">
          <jrawMonitorID/>
          <description>
            The monitor
          </description>
        </param>
      </parameters>
      <errors>
        <error id="JVMTI_ERROR_NOT_MONITOR_OWNER">
          Not monitor owner
        </error>
      </errors>
    </function>

   <elide>
    <function id="GetRawMonitorUse" num="118">
      <synopsis>Get Raw Monitor Use</synopsis>
      <description>
        The fields of the <functionlink id="jvmtiMonitorUsage"></functionlink> structure
        are filled in with information about usage of the raw monitor.
      </description>
      <origin>new</origin>
      <capabilities>
        <required id="can_get_raw_monitor_usage"></required>
      </capabilities>
      <parameters>
        <param id="monitor">
          <jrawMonitorID/>
          <description>
            the raw monitor to query.
          </description>
        </param>
        <param id="info_ptr">
          <outptr><struct>jvmtiMonitorUsage</struct></outptr>
          <description>
            On return, filled with monitor information for the
            specified raw monitor.
          </description>
        </param>
      </parameters>
      <errors>
      </errors>
    </function>

    <function id="GetRawMonitors" num="119">
      <synopsis>Get Raw Monitors</synopsis>
      <description>
        Return the list of raw monitors.
        <p/>
        Note: details about each monitor can be examined with
        <functionlink id="GetRawMonitorUse"></functionlink>.
      </description>
      <origin>new</origin>
      <capabilities>
        <required id="can_get_raw_monitor_usage"></required>
      </capabilities>
      <parameters>
        <param id="monitorCnt">
          <outptr><jint/></outptr>
          <description>
            On return, pointer to the number
            of monitors returned in <code>monitors_ptr</code>.
          </description>
        </param>
        <param id="monitors_ptr">
          <allocbuf outcount="monitorCnt"><jrawMonitorID/></allocbuf>
          <description>
            On return, pointer to the monitor list.
          </description>
        </param>
      </parameters>
      <errors>
      </errors>
    </function>
    </elide>
  </category>

  <category id="jniIntercept" label="JNI Function Interception">

    <intro>
      Provides the ability to intercept and resend
      Java Native Interface (JNI) function calls
      by manipulating the JNI function table.
      See <externallink id="jni/functions.html">JNI
        Functions</externallink> in the <i>Java Native Interface Specification</i>.
      <p/>
      The following example illustrates intercepting the
      <code>NewGlobalRef</code> JNI call in order to count reference
      creation.
      <example>
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-&gt;NewGlobalRef(env, lobj);
}

void
myInit() {
   jvmtiError err;

   err = (*jvmti_env)-&gt;GetJNIFunctionTable(jvmti_env, &amp;original_jni_Functions);
   if (err != JVMTI_ERROR_NONE) {
      die();
   }
   err = (*jvmti_env)-&gt;GetJNIFunctionTable(jvmti_env, &amp;redirected_jni_Functions);
   if (err != JVMTI_ERROR_NONE) {
      die();
   }
   redirectedJNIFunctions-&gt;NewGlobalRef = MyNewGlobalRef;
      err = (*jvmti_env)-&gt;SetJNIFunctionTable(jvmti_env, redirected_jni_Functions);
   if (err != JVMTI_ERROR_NONE) {
      die();
   }
}
      </example>
      Sometime after <code>myInit</code> 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 <code>myNewGlobalRef</code>.  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.
      <todo>
        check that the example compiles and executes.
      </todo>
    </intro>

    <function id="SetJNIFunctionTable" phase="start" num="120">
      <synopsis>Set JNI Function Table</synopsis>
      <description>
        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 <functionlink id="GetJNIFunctionTable"></functionlink> 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 <code>const</code> 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 <internallink id="jniIntercept">above</internallink>.
      </description>
      <origin>new</origin>
      <capabilities>
      </capabilities>
      <parameters>
        <param id="function_table">
          <inptr>
            <struct>jniNativeInterface</struct>
          </inptr>
          <description>
            Points to the new JNI function table.
          </description>
        </param>
      </parameters>
      <errors>
      </errors>
    </function>

    <function id="GetJNIFunctionTable" phase="start" num="121">
      <synopsis>Get JNI Function Table</synopsis>
      <description>
        Get the JNI function table.
        The JNI function table is copied into allocated memory.
        If <functionlink id="SetJNIFunctionTable"></functionlink>
        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 <internallink id="jniIntercept">above</internallink>.
      </description>
      <origin>new</origin>
      <capabilities>
      </capabilities>
      <parameters>
        <param id="function_table">
          <allocbuf>
            <struct>jniNativeInterface</struct>
          </allocbuf>
          <description>
            On return, <code>*function_table</code>
            points a newly allocated copy of the JNI function table.
          </description>
        </param>
      </parameters>
      <errors>
      </errors>
    </function>

  </category>

  <category id="eventManagement" label="Event Management">

    <function id="SetEventCallbacks" jkernel="yes" phase="onload" num="122">
      <synopsis>Set Event Callbacks</synopsis>
      <description>
        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 <code>NULL</code> or when the event is beyond
        <paramlink id="size_of_callbacks"></paramlink> no event is sent.
        Details on events are
        described <internallink id="EventSection">later</internallink> in this document.
        An event must be enabled and have a callback in order to be
        sent--the order in which this function and
        <functionlink id="SetEventNotificationMode"></functionlink>
        are called does not affect the result.
      </description>
      <origin>new</origin>
      <capabilities>
      </capabilities>
      <parameters>
        <param id="callbacks">
          <inptr>
            <struct>jvmtiEventCallbacks</struct>
            <nullok>remove the existing callbacks</nullok>
          </inptr>
          <description>
            The new event callbacks.
          </description>
        </param>
        <param id="size_of_callbacks">
          <jint min="0"/>
          <description>
            <code>sizeof(jvmtiEventCallbacks)</code>--for version
            compatibility.
          </description>
        </param>
      </parameters>
      <errors>
      </errors>
    </function>

    <function id="SetEventNotificationMode" jkernel="yes" phase="onload" num="2">
      <synopsis>Set Event Notification Mode</synopsis>
      <description>
        Control the generation of events.
        <constants id="jvmtiEventMode" label="Event Enable/Disable" kind="enum">
          <constant id="JVMTI_ENABLE" num="1">
            If <paramlink id="mode"></paramlink> is <code>JVMTI_ENABLE</code>,
            the event <paramlink id="event_type"></paramlink> will be enabled
          </constant>
          <constant id="JVMTI_DISABLE" num="0">
            If <paramlink id="mode"></paramlink> is <code>JVMTI_DISABLE</code>,
            the event <paramlink id="event_type"></paramlink> will be disabled
          </constant>
        </constants>
        If <code>event_thread</code> is <code>NULL</code>,
        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.
        <p/>
        See <internallink id="EventIndex">below</internallink> for information on specific events.
        <p/>
        The following events cannot be controlled at the thread
        level through this function.
        <ul>
          <li><eventlink id="VMInit"></eventlink></li>
          <li><eventlink id="VMStart"></eventlink></li>
          <li><eventlink id="VMDeath"></eventlink></li>
          <li><eventlink id="ThreadStart"></eventlink></li>
          <li><eventlink id="CompiledMethodLoad"></eventlink></li>
          <li><eventlink id="CompiledMethodUnload"></eventlink></li>
          <li><eventlink id="DynamicCodeGenerated"></eventlink></li>
          <li><eventlink id="DataDumpRequest"></eventlink></li>
        </ul>
        <p/>
        Initially, no events are enabled at either the thread level
        or the global level.
        <p/>
        Any needed capabilities (see Event Enabling Capabilities below) must be possessed
        before calling this function.
        <p/>
        Details on events are
        described <internallink id="EventSection">below</internallink>.
      </description>
      <origin>jvmdiClone</origin>
      <eventcapabilities></eventcapabilities>
      <parameters>
        <param id="mode">
          <enum>jvmtiEventMode</enum>
          <description>
            <code>JVMTI_ENABLE</code> or <code>JVMTI_DISABLE</code>
          </description>
        </param>
        <param id="event_type">
          <enum>jvmtiEvent</enum>
          <description>
            the event to control
          </description>
        </param>
        <param id="event_thread">
          <ptrtype>
            <jthread impl="noconvert"/>
            <nullok>event is controlled at the global level</nullok>
          </ptrtype>
            <description>
              The thread to control
            </description>
        </param>
        <param id="...">
          <varargs/>
            <description>
              for future expansion
            </description>
        </param>
      </parameters>
      <errors>
        <error id="JVMTI_ERROR_INVALID_THREAD">
          <paramlink id="event_thread"/> is non-<code>NULL</code> and is not a valid thread.
        </error>
        <error id="JVMTI_ERROR_THREAD_NOT_ALIVE">
          <paramlink id="event_thread"/> is non-<code>NULL</code> and is not live (has not been started or is now dead).
        </error>
        <error id="JVMTI_ERROR_ILLEGAL_ARGUMENT">
          thread level control was attempted on events which do not
          permit thread level control.
        </error>
        <error id="JVMTI_ERROR_MUST_POSSESS_CAPABILITY">
          The Required Event Enabling Capability is not possessed.
        </error>
      </errors>
    </function>

    <function id="GenerateEvents" num="123">
      <synopsis>Generate Events</synopsis>
      <description>
        Generate events to represent the current state of the VM.
        For example, if <paramlink id="event_type"/> is
        <code>JVMTI_EVENT_COMPILED_METHOD_LOAD</code>,
        a <eventlink id="CompiledMethodLoad"></eventlink> 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.
        <p/>
        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.
        <p/>
        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
        <functionlink id="SetEventCallbacks"></functionlink>
        and the event must be enabled with
        <functionlink id="SetEventNotificationMode"></functionlink>
        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.
        <p/>
        Only the following events are supported:
        <ul>
          <li><eventlink id="CompiledMethodLoad"></eventlink></li>
          <li><eventlink id="DynamicCodeGenerated"></eventlink></li>
        </ul>
      </description>
      <origin>new</origin>
      <capabilities>
        <capability id="can_generate_compiled_method_load_events"></capability>
      </capabilities>
      <parameters>
        <param id="event_type">
          <enum>jvmtiEvent</enum>
          <description>
            The type of event to generate.  Must be one of these:
            <ul>
              <li><eventlink id="CompiledMethodLoad"><code>JVMTI_EVENT_COMPILED_METHOD_LOAD</code></eventlink></li>
              <li><eventlink id="DynamicCodeGenerated"><code>JVMTI_EVENT_DYNAMIC_CODE_GENERATED</code></eventlink></li>
            </ul>
          </description>
        </param>
      </parameters>
      <errors>
        <error id="JVMTI_ERROR_MUST_POSSESS_CAPABILITY">
          <paramlink id="event_type"/> is
          <eventlink id="CompiledMethodLoad"><code>JVMTI_EVENT_COMPILED_METHOD_LOAD</code></eventlink>
          and <fieldlink id="can_generate_compiled_method_load_events" struct="jvmtiCapabilities"></fieldlink>
          is <code>false</code>.
        </error>
        <error id="JVMTI_ERROR_ILLEGAL_ARGUMENT">
          <paramlink id="event_type"/> is other than
          <eventlink id="CompiledMethodLoad"><code>JVMTI_EVENT_COMPILED_METHOD_LOAD</code></eventlink>
          or <eventlink id="DynamicCodeGenerated"><code>JVMTI_EVENT_DYNAMIC_CODE_GENERATED</code></eventlink>.
        </error>
      </errors>
    </function>

  </category>

    <category id="extension" label="Extension Mechanism">

      <intro>
        These functions
        allow a <jvmti/> implementation to provide functions and events
        beyond those defined in this specification.
        <p/>
        Both extension functions and extension events have parameters
        each of which has a 'type' and 'kind' chosen from the following tables:

        <constants id="jvmtiParamTypes" label="Extension Function/Event Parameter Types" kind="enum">
          <constant id="JVMTI_TYPE_JBYTE" num="101">
            Java programming language primitive type - <code>byte</code>.
            JNI type <code>jbyte</code>.
          </constant>
          <constant id="JVMTI_TYPE_JCHAR" num="102">
            Java programming language primitive type - <code>char</code>.
            JNI type <code>jchar</code>.
          </constant>
          <constant id="JVMTI_TYPE_JSHORT" num="103">
            Java programming language primitive type - <code>short</code>.
            JNI type <code>jshort</code>.
          </constant>
          <constant id="JVMTI_TYPE_JINT" num="104">
            Java programming language primitive type - <code>int</code>.
            JNI type <datalink id="jint"></datalink>.
          </constant>
          <constant id="JVMTI_TYPE_JLONG" num="105">
            Java programming language primitive type - <code>long</code>.
            JNI type <datalink id="jlong"></datalink>.
          </constant>
          <constant id="JVMTI_TYPE_JFLOAT" num="106">
            Java programming language primitive type - <code>float</code>.
            JNI type <datalink id="jfloat"></datalink>.
          </constant>
          <constant id="JVMTI_TYPE_JDOUBLE" num="107">
            Java programming language primitive type - <code>double</code>.
            JNI type <datalink id="jdouble"></datalink>.
          </constant>
          <constant id="JVMTI_TYPE_JBOOLEAN" num="108">
            Java programming language primitive type - <code>boolean</code>.
            JNI type <datalink id="jboolean"></datalink>.
          </constant>
          <constant id="JVMTI_TYPE_JOBJECT" num="109">
            Java programming language object type - <code>java.lang.Object</code>.
            JNI type <datalink id="jobject"></datalink>.
            Returned values are JNI local references and must be managed.
          </constant>
          <constant id="JVMTI_TYPE_JTHREAD" num="110">
            Java programming language object type - <code>java.lang.Thread</code>.
            <jvmti/> type <datalink id="jthread"></datalink>.
            Returned values are JNI local references and must be managed.
          </constant>
          <constant id="JVMTI_TYPE_JCLASS" num="111">
            Java programming language object type - <code>java.lang.Class</code>.
            JNI type <datalink id="jclass"></datalink>.
            Returned values are JNI local references and must be managed.
          </constant>
          <constant id="JVMTI_TYPE_JVALUE" num="112">
            Union of all Java programming language primitive and object types -
            JNI type <datalink id="jvalue"></datalink>.
            Returned values which represent object types are JNI local references and must be managed.
          </constant>
          <constant id="JVMTI_TYPE_JFIELDID" num="113">
            Java programming language field identifier -
            JNI type <datalink id="jfieldID"></datalink>.
          </constant>
          <constant id="JVMTI_TYPE_JMETHODID" num="114">
            Java programming language method identifier -
            JNI type <datalink id="jmethodID"></datalink>.
          </constant>
          <constant id="JVMTI_TYPE_CCHAR" num="115">
            C programming language type - <code>char</code>.
          </constant>
          <constant id="JVMTI_TYPE_CVOID" num="116">
            C programming language type - <code>void</code>.
          </constant>
          <constant id="JVMTI_TYPE_JNIENV" num="117">
            JNI environment - <code>JNIEnv</code>.
            Should be used with the correct <datalink id="jvmtiParamKind"/> to make it a pointer type.
          </constant>
        </constants>

        <constants id="jvmtiParamKind" label="Extension Function/Event Parameter Kinds" kind="enum">
          <constant id="JVMTI_KIND_IN" num="91">
            Ingoing argument - <code>foo</code>.
          </constant>
          <constant id="JVMTI_KIND_IN_PTR" num="92">
            Ingoing pointer argument - <code>const foo*</code>.
          </constant>
          <constant id="JVMTI_KIND_IN_BUF" num="93">
            Ingoing array argument - <code>const foo*</code>.
          </constant>
          <constant id="JVMTI_KIND_ALLOC_BUF" num="94">
            Outgoing allocated array argument -  <code>foo**</code>.
            Free with <code>Deallocate</code>.
          </constant>
          <constant id="JVMTI_KIND_ALLOC_ALLOC_BUF" num="95">
            Outgoing allocated array of allocated arrays argument - <code>foo***</code>.
            Free with <code>Deallocate</code>.
          </constant>
          <constant id="JVMTI_KIND_OUT" num="96">
            Outgoing argument - <code>foo*</code>.
          </constant>
          <constant id="JVMTI_KIND_OUT_BUF" num="97">
            Outgoing array argument (pre-allocated by agent) - <code>foo*</code>.
            Do not <code>Deallocate</code>.
          </constant>
        </constants>

      </intro>

      <typedef id="jvmtiParamInfo" label="Extension Function/Event Parameter Info">
        <field id="name">
          <allocfieldbuf><char/></allocfieldbuf>
            <description>
              The parameter name, encoded as a
              <internallink id="mUTF">modified UTF-8</internallink> string
            </description>
        </field>
        <field id="kind">
          <enum>jvmtiParamKind</enum>
          <description>
            The kind of the parameter - type modifiers
          </description>
        </field>
        <field id="base_type">
          <enum>jvmtiParamTypes</enum>
          <description>
            The base type of the parameter -  modified by <code>kind</code>
          </description>
        </field>
        <field id="null_ok">
          <jboolean/>
            <description>
              Is a <code>NULL</code> argument permitted? Applies only to pointer and object types.
            </description>
        </field>
      </typedef>

      <callback id="jvmtiExtensionFunction">
        <enum>jvmtiError</enum>
          <synopsis>Extension Function</synopsis>
        <description>
          This is the implementation-specific extension function.
        </description>
        <parameters>
          <param id="jvmti_env">
            <outptr>
              <struct>jvmtiEnv</struct>
            </outptr>
            <description>
              The <jvmti/> environment is the only fixed parameter for extension functions.
            </description>
          </param>
          <param id="...">
            <varargs/>
              <description>
                The extension function-specific parameters
              </description>
          </param>
        </parameters>
      </callback>

      <function id="GetExtensionFunctions" phase="onload" num="124">
        <synopsis>Get Extension Functions</synopsis>

        <typedef id="jvmtiExtensionFunctionInfo" label="Extension Function Info">
          <field id="func">
            <ptrtype>
              <struct>jvmtiExtensionFunction</struct>
            </ptrtype>
            <description>
              The actual function to call
            </description>
          </field>
          <field id="id">
            <allocfieldbuf><char/></allocfieldbuf>
              <description>
                The identifier for the extension function, encoded as a
                <internallink id="mUTF">modified UTF-8</internallink> string.
                Uses package name conventions.
                For example, <code>com.sun.hotspot.bar</code>
              </description>
          </field>
          <field id="short_description">
            <allocfieldbuf><char/></allocfieldbuf>
              <description>
                A one sentence description of the function, encoded as a
                <internallink id="mUTF">modified UTF-8</internallink> string.
              </description>
          </field>
          <field id="param_count">
            <jint/>
              <description>
                The number of parameters excluding <code>jvmtiEnv *jvmti_env</code>
              </description>
          </field>
          <field id="params">
            <allocfieldbuf outcount="param_count">
              <struct>jvmtiParamInfo</struct>
            </allocfieldbuf>
            <description>
              Array of
              <fieldlink id="param_count" struct="jvmtiExtensionFunctionInfo"></fieldlink>
              parameters (<code>jvmtiEnv *jvmti_env</code> excluded)
            </description>
          </field>
          <field id="error_count">
            <jint/>
              <description>
                The number of possible error returns (excluding universal errors)
              </description>
          </field>
          <field id="errors">
            <allocfieldbuf outcount="error_count">
              <enum>jvmtiError</enum>
            </allocfieldbuf>
            <description>
              Array of <fieldlink id="error_count" struct="jvmtiExtensionFunctionInfo"></fieldlink>
              possible errors
            </description>
          </field>
        </typedef>

        <description>
          Returns the set of extension functions.
        </description>
        <origin>new</origin>
        <capabilities>
        </capabilities>
        <parameters>
          <param id="extension_count_ptr">
            <outptr><jint/></outptr>
              <description>
                On return, points to the number of extension functions
              </description>
          </param>
          <param id="extensions">
            <allocbuf outcount="extension_count_ptr"><struct>jvmtiExtensionFunctionInfo</struct></allocbuf>
            <description>
              Returns an array of extension function info, one per function
            </description>
          </param>
        </parameters>
        <errors>
        </errors>
      </function>

      <function id="GetExtensionEvents" phase="onload" num="125">
        <synopsis>Get Extension Events</synopsis>

        <typedef id="jvmtiExtensionEventInfo" label="Extension Event Info">
          <field id="extension_event_index">
            <jint/>
            <description>
              The identifying index of the event
            </description>
          </field>
          <field id="id">
            <allocfieldbuf><char/></allocfieldbuf>
              <description>
                The identifier for the extension event, encoded as a
                <internallink id="mUTF">modified UTF-8</internallink> string.
                Uses package name conventions.
                For example, <code>com.sun.hotspot.bar</code>
              </description>
          </field>
          <field id="short_description">
            <allocfieldbuf><char/></allocfieldbuf>
              <description>
                A one sentence description of the event, encoded as a
                <internallink id="mUTF">modified UTF-8</internallink> string.
              </description>
          </field>
          <field id="param_count">
            <jint/>
              <description>
                The number of parameters excluding <code>jvmtiEnv *jvmti_env</code>
              </description>
          </field>
          <field id="params">
            <allocfieldbuf outcount="param_count">
              <struct>jvmtiParamInfo</struct>
            </allocfieldbuf>
            <description>
              Array of
              <fieldlink id="param_count" struct="jvmtiExtensionEventInfo"></fieldlink>
              parameters (<code>jvmtiEnv *jvmti_env</code> excluded)
            </description>
          </field>
        </typedef>

        <description>
          Returns the set of extension events.
        </description>
        <origin>new</origin>
        <capabilities>
        </capabilities>
        <parameters>
          <param id="extension_count_ptr">
            <outptr><jint/></outptr>
              <description>
                On return, points to the number of extension events
              </description>
          </param>
          <param id="extensions">
            <allocbuf outcount="extension_count_ptr"><struct>jvmtiExtensionEventInfo</struct></allocbuf>
            <description>
              Returns an array of extension event info, one per event
            </description>
          </param>
        </parameters>
        <errors>
        </errors>
      </function>

      <callback id="jvmtiExtensionEvent">
        <void/>
          <synopsis>Extension Event</synopsis>
        <description>
          This is the implementation-specific event.
          The event handler is set with
          <functionlink id="SetExtensionEventCallback"/>.
          <p/>
          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.
          <p/>
          For example, if the <code>jvmtiParamInfo</code>
          returned by <functionlink id="GetExtensionEvents"/> indicates that
          there is a <code>jint</code> parameter, the event handler should be
          declared:
<example>
    void JNICALL myHandler(jvmtiEnv* jvmti_env, jint myInt, ...)
</example>
          Note the terminal "<code>...</code>" which indicates varargs.
        </description>
        <parameters>
          <param id="jvmti_env">
            <outptr>
              <struct>jvmtiEnv</struct>
            </outptr>
            <description>
              The <jvmti/> environment is the only fixed parameter for extension events.
            </description>
          </param>
          <param id="...">
            <varargs/>
              <description>
                The extension event-specific parameters
              </description>
          </param>
        </parameters>
      </callback>

      <function id="SetExtensionEventCallback" phase="onload" num="126">
        <synopsis>Set Extension Event Callback</synopsis>

        <description>
          Sets the callback function for an extension event and
          enables the event. Or, if the callback is <code>NULL</code>, disables
          the event.  Note that unlike standard events, setting
          the callback and enabling the event are a single operation.
        </description>
        <origin>new</origin>
        <capabilities>
        </capabilities>
        <parameters>
          <param id="extension_event_index">
            <jint/>
              <description>
                Identifies which callback to set.
                This index is the
                <fieldlink id="extension_event_index" struct="jvmtiExtensionEventInfo"></fieldlink>
                field of
                <datalink id="jvmtiExtensionEventInfo"/>.
              </description>
          </param>
          <param id="callback">
            <ptrtype>
              <struct>jvmtiExtensionEvent</struct>
              <nullok>disable the event</nullok>
            </ptrtype>
            <description>
              If <code>callback</code> is non-<code>NULL</code>,
              set <code>callback</code> to be the event callback function
              and enable the event.
            </description>
          </param>
        </parameters>
        <errors>
        <error id="JVMTI_ERROR_ILLEGAL_ARGUMENT">
            <paramlink id="extension_event_index"/> is not an
            <fieldlink id="extension_event_index"
                       struct="jvmtiExtensionEventInfo"/>
            returned by
            <functionlink id="GetExtensionEvents"/>
        </error>
        </errors>
      </function>

    </category>

  <category id="capability" label="Capability">

    <intro>
      The capabilities functions allow you to change the
      functionality available to <jvmti/>--that is,
      which <jvmti/>
      functions can be called, what events can be generated,
      and what functionality these events and functions can
      provide.
      <p/>
        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
        <functionlink id="AddCapabilities">add the capability</functionlink>.
        "Optional Features" describe capabilities which,
        if added, extend the feature set.
        <p/>
        The potentially available capabilities of each <jvmti/> implementation are different.
        Depending on the implementation, a capability:
        <ul>
          <li>may never be added</li>
          <li>may be added in either the <code>OnLoad</code> or live phase in any environment</li>
          <li>may be added only during the <code>OnLoad</code> phase</li>
          <li>may be possessed by only one environment at a time</li>
          <li>may be possessed by only one environment at a time,
              and only during the <code>OnLoad</code> phase</li>
          <li>and so on ...</li>
        </ul>
      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:
      <ul>
        <li>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.</li>
        <li>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.</li>
        <li>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 <code>OnLoad</code> phase (before bytecode
          execution begins) and would have a large impact on execution speed
          even if single stepping was never used.</li>
        <li>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 <code>OnLoad</code> phase but the overhead (a test
          and branch on each instruction) would be considerably less.</li>
      </ul>
      <p/>
      Each <jvmti/> <internallink id="environments">environment</internallink>
      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 <code>OnLoad</code> phase.  For most
      virtual machines certain capabilities require special set up for
      the virtual machine and this set up must happen
      during the <code>OnLoad</code> phase, before the virtual machine begins execution.
      Once a capability is added, it can
      only be removed if explicitly relinquished by the environment.
      <p/>
      The agent can,
      <functionlink id="GetPotentialCapabilities">determine what
        capabilities this VM can potentially provide</functionlink>,
      <functionlink id="AddCapabilities">add the capabilities
        to be used</functionlink>,
      <functionlink id="RelinquishCapabilities">release capabilities
        which are no longer needed</functionlink>, and
      <functionlink id="GetCapabilities">examine the currently available
        capabilities</functionlink>.
    </intro>

    <intro id="capabilityExamples" label="Capability Examples">
      For example, a freshly started agent (in the <code>OnLoad</code> 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:
      <example>
        jvmtiCapabilities capa;
        jvmtiError err;

        err = (*jvmti)-&gt;GetPotentialCapabilities(jvmti, &amp;capa);
        if (err == JVMTI_ERROR_NONE) {
           err = (*jvmti)-&gt;AddCapabilities(jvmti, &amp;capa);
      </example>
      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:
      <example>
        jvmtiCapabilities capa;
        jvmtiError err;

        err = (*jvmti)-&gt;GetCapabilities(jvmti, &amp;capa);
        if (err == JVMTI_ERROR_NONE) {
           if (capa.can_get_bytecodes) { ... } }
      </example>
    </intro>

    <capabilitiestypedef id="jvmtiCapabilities" label="The Capabilities Structure">
      <description>
        The functions in this category use this capabilities structure
        which contains boolean flags corresponding to each capability:
      </description>
      <capabilityfield id="can_tag_objects">
        <description>
          Can set and get tags, as described in the
          <internallink id="Heap">Heap category</internallink>.
        </description>
      </capabilityfield>
      <capabilityfield id="can_generate_field_modification_events">
        <description>
          Can set watchpoints on field modification -
          <functionlink id="SetFieldModificationWatch"></functionlink>
        </description>
      </capabilityfield>
      <capabilityfield id="can_generate_field_access_events">
        <description>
          Can set watchpoints on field access -
          <functionlink id="SetFieldAccessWatch"></functionlink>
        </description>
      </capabilityfield>
      <capabilityfield id="can_get_bytecodes">
        <description>
          Can get bytecodes of a method <functionlink id="GetBytecodes"></functionlink>
        </description>
      </capabilityfield>
      <capabilityfield id="can_get_synthetic_attribute">
        <description>
          Can test if a field or method is synthetic -
          <functionlink id="IsFieldSynthetic"></functionlink> and
          <functionlink id="IsMethodSynthetic"></functionlink>
        </description>
      </capabilityfield>
      <capabilityfield id="can_get_owned_monitor_info">
        <description>
          Can get information about ownership of monitors -
          <functionlink id="GetOwnedMonitorInfo"></functionlink>
        </description>
      </capabilityfield>
      <capabilityfield id="can_get_current_contended_monitor">
        <description>
          Can <functionlink id="GetCurrentContendedMonitor"></functionlink>
        </description>
      </capabilityfield>
      <capabilityfield id="can_get_monitor_info">
      <description>
        Can <functionlink id="GetObjectMonitorUsage"></functionlink>
      </description>
      </capabilityfield>
      <capabilityfield id="can_pop_frame">
        <description>
          Can pop frames off the stack - <functionlink id="PopFrame"></functionlink>
        </description>
      </capabilityfield>
      <capabilityfield id="can_redefine_classes">
        <description>
          Can redefine classes with <functionlink id="RedefineClasses"/>.
        </description>
      </capabilityfield>
      <capabilityfield id="can_signal_thread">
        <description>
          Can send stop or interrupt to threads
        </description>
      </capabilityfield>
      <capabilityfield id="can_get_source_file_name">
        <description>
          Can get the source file name of a class
        </description>
      </capabilityfield>
      <capabilityfield id="can_get_line_numbers">
        <description>
          Can get the line number table of a method
        </description>
      </capabilityfield>
      <capabilityfield id="can_get_source_debug_extension">
        <description>
          Can get the source debug extension of a class
        </description>
      </capabilityfield>
      <capabilityfield id="can_access_local_variables">
        <description>
          Can set and get local variables
        </description>
      </capabilityfield>
      <capabilityfield id="can_maintain_original_method_order">
        <description>
          Can return methods in the order they occur in the class file
        </description>
      </capabilityfield>
      <capabilityfield id="can_generate_single_step_events">
        <description>
          Can get <eventlink id="SingleStep">single step</eventlink> events
        </description>
      </capabilityfield>
      <capabilityfield id="can_generate_exception_events">
        <description>
          Can get <eventlink id="Exception">exception thrown</eventlink> and
            <eventlink id="ExceptionCatch">exception catch</eventlink> events
        </description>
      </capabilityfield>
      <capabilityfield id="can_generate_frame_pop_events">
        <description>
          Can <functionlink id="NotifyFramePop">set</functionlink> and thus get
            <eventlink id="FramePop"></eventlink> events
        </description>
      </capabilityfield>
      <capabilityfield id="can_generate_breakpoint_events">
        <description>
          Can <functionlink id="SetBreakpoint">set</functionlink> and thus get
            <eventlink id="Breakpoint"></eventlink> events
        </description>
      </capabilityfield>
      <capabilityfield id="can_suspend">
        <description>
          Can suspend and resume threads
        </description>
      </capabilityfield>
      <capabilityfield id="can_redefine_any_class">
        <description>
          <functionlink id="RedefineClasses"/> can be called on any modifiable class.
          See <functionlink id="IsModifiableClass"/>.
          (<fieldlink id="can_redefine_classes" struct="jvmtiCapabilities"/>
          must also be set)
        </description>
      </capabilityfield>
      <capabilityfield id="can_get_current_thread_cpu_time">
        <description>
          Can <functionlink id="GetCurrentThreadCpuTime">get</functionlink>
          current thread CPU time
        </description>
      </capabilityfield>
      <capabilityfield id="can_get_thread_cpu_time">
        <description>
          Can <functionlink id="GetThreadCpuTime">get</functionlink>
          thread CPU time
        </description>
      </capabilityfield>
      <capabilityfield id="can_generate_method_entry_events"
                       disp1="can_generate" disp2="_method_entry_events"
                       >
        <description>
          Can generate method entry events on entering a method
        </description>
      </capabilityfield>
      <capabilityfield id="can_generate_method_exit_events"
                       disp1="can_generate" disp2="_method_exit_events"
                       >
        <description>
          Can generate method exit events on leaving a method
        </description>
      </capabilityfield>
      <capabilityfield id="can_generate_all_class_hook_events"
                       disp1="can_generate" disp2="_all_class_hook_events"
                       >
        <description>
          Can generate ClassFileLoadHook events for every loaded class.
        </description>
      </capabilityfield>
      <capabilityfield id="can_generate_compiled_method_load_events"
                       disp1="can_generate" disp2="_compiled_method_load_events"
                       >
        <description>
          Can generate events when a method is compiled or unloaded
        </description>
      </capabilityfield>
      <capabilityfield id="can_generate_monitor_events"
                       disp1="can_generate" disp2="_monitor_events"
                       >
        <description>
          Can generate events on monitor activity
        </description>
      </capabilityfield>
      <capabilityfield id="can_generate_vm_object_alloc_events"
                       disp1="can_generate" disp2="_vm_object_alloc_events"
                       >
        <description>
          Can generate events on VM allocation of an object
        </description>
      </capabilityfield>
      <capabilityfield id="can_generate_native_method_bind_events"
                       disp1="can_generate" disp2="_native_method_bind_events"
                       >
        <description>
          Can generate events when a native method is bound to its
          implementation
        </description>
      </capabilityfield>
      <capabilityfield id="can_generate_garbage_collection_events"
                       disp1="can_generate" disp2="_garbage_collection_events"
                       >
        <description>
          Can generate events when garbage collection begins or ends
        </description>
      </capabilityfield>
      <capabilityfield id="can_generate_object_free_events"
                       disp1="can_generate" disp2="_object_free_events"
                       >
        <description>
          Can generate events when the garbage collector frees an object
        </description>
      </capabilityfield>
      <capabilityfield id="can_force_early_return" since="1.1">
        <description>
          Can return early from a method, as described in the
          <internallink id="ForceEarlyReturn">Force Early Return category</internallink>.
        </description>
      </capabilityfield>
      <capabilityfield id="can_get_owned_monitor_stack_depth_info" since="1.1">
        <description>
          Can get information about owned monitors with stack depth -
          <functionlink id="GetOwnedMonitorStackDepthInfo"></functionlink>
        </description>
      </capabilityfield>
      <capabilityfield id="can_get_constant_pool" since="1.1">
        <description>
          Can get the constant pool of a class -
          <functionlink id="GetConstantPool"></functionlink>
        </description>
      </capabilityfield>
      <capabilityfield id="can_set_native_method_prefix" since="1.1">
        <description>
          Can set prefix to be applied when native method cannot be resolved -
          <functionlink id="SetNativeMethodPrefix"/> and
          <functionlink id="SetNativeMethodPrefixes"/>
        </description>
      </capabilityfield>
      <capabilityfield id="can_retransform_classes" since="1.1">
        <description>
          Can retransform classes with <functionlink id="RetransformClasses"/>.
          In addition to the restrictions imposed by the specific
          implementation on this capability (see the
          <internallink id="capability">Capability</internallink> section),
          this capability must be set before the
          <eventlink id="ClassFileLoadHook"/> event is enabled for the
          first time in this environment.
          An environment that possesses this capability at the time that
          <code>ClassFileLoadHook</code> is enabled for the first time is
          said to be <i>retransformation capable</i>.
          An environment that does not possess this capability at the time that
          <code>ClassFileLoadHook</code> is enabled for the first time is
          said to be <i>retransformation incapable</i>.
        </description>
      </capabilityfield>
      <capabilityfield id="can_retransform_any_class" since="1.1">
        <description>
          <functionlink id="RetransformClasses"/> can be called on any modifiable class.
          See <functionlink id="IsModifiableClass"/>.
          (<fieldlink id="can_retransform_classes" struct="jvmtiCapabilities"/>
          must also be set)
        </description>
      </capabilityfield>
      <capabilityfield id="can_generate_resource_exhaustion_heap_events" since="1.1">
        <description>
          Can generate events when the VM is unable to allocate memory from
          the <tm>Java</tm> platform heap.
          See <eventlink id="ResourceExhausted"/>.
        </description>
      </capabilityfield>
      <capabilityfield id="can_generate_resource_exhaustion_threads_events" since="1.1">
        <description>
          Can generate events when the VM is unable to create a thread.
          See <eventlink id="ResourceExhausted"/>.
        </description>
      </capabilityfield>
      <capabilityfield id="can_generate_early_vmstart" since="9">
        <description>
          Can generate the <code>VMStart</code> event early.
          See <eventlink id="VMStart"/>.
        </description>
      </capabilityfield>
      <capabilityfield id="can_generate_early_class_hook_events" since="9">
        <description>
          Can generate the <eventlink id="ClassFileLoadHook"/> events
          in the primordial phase. If this capability and
          <internallink id="jvmtiCapabilities.can_generate_all_class_hook_events">
          <code>can_generate_all_class_hook_events</code></internallink>
          are enabled then the <eventlink id="ClassFileLoadHook"/> events
          can be posted for classes loaded in the primordial phase.
          See <eventlink id="ClassFileLoadHook"/>.
        </description>
      </capabilityfield>
      <capabilityfield id="can_generate_sampled_object_alloc_events" since="11">
        <description>
          Can generate sampled allocation events.
          If this capability is enabled then the heap sampling method
          <functionlink id="SetHeapSamplingInterval"></functionlink> can be
          called and <eventlink id="SampledObjectAlloc"></eventlink> events can be generated.
        </description>
      </capabilityfield>
    </capabilitiestypedef>

    <function id="GetPotentialCapabilities" jkernel="yes" phase="onload" num="140">
      <synopsis>Get Potential Capabilities</synopsis>
      <description>
        Returns via <paramlink id="capabilities_ptr"></paramlink> the <jvmti/>
        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 <functionlink id="GetPhase">phase</functionlink> is live,
        and certain capabilities can only be added during the <code>OnLoad</code> phase.
        The <functionlink id="AddCapabilities"></functionlink> function
        may be used to set any or all or these capabilities.
        Currently possessed capabilities are included.
        <p/>
        Typically this function is used in the <code>OnLoad</code> 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 <code>OnLoad</code> phase set.
        <p/>
        See the
        <internallink id="capabilityExamples">Capability Examples</internallink>.
      </description>
      <origin>new</origin>
      <capabilities>
      </capabilities>
      <parameters>
        <param id="capabilities_ptr">
          <outptr><struct>jvmtiCapabilities</struct></outptr>
          <description>
            On return, points to the <jvmti/> capabilities that may be added.
          </description>
        </param>
      </parameters>
      <errors>
      </errors>
    </function>

    <elide>
    <function id="EstimateCostOfCapabilities" phase="onload" num="141">
      <synopsis>Estimate Cost Of Capabilities</synopsis>
      <description>
        <issue>There is strong opposition to this function.  The concern is
          that it would be difficult or impossible to provide meaningful
          numbers, as the amount of impact is conditional on many factors
          that a single number could not represent.  There is doubt that
          conditional implementations would be used or are even a good idea.
          The thought is that release documentation for the implementation
          would be the best means of exposing this information.
          Unless new arguments are presented, I intend to remove this
          function in the next revision.
        </issue>
        <p/>
        Return via the <paramlink id="time_impact_ptr"></paramlink> and
        <paramlink id="space_impact_ptr"></paramlink> an estimate of the impact
        of adding the capabilities pointed to by
        <paramlink id="capabilities_ptr"></paramlink>.
        The returned estimates are in percentage of additional overhead, thus
        a time impact of 100 mean the application might run
        at half the speed.
        The estimates are very rough approximations and are not guaranteed.
        Note also, that the estimates are of the impact of having the
        capability available--when and if it is used the impact may be
        much greater.
        Estimates can be for a single capability or for a set of
        capabilities.  Note that the costs are not necessarily additive,
        adding support for one capability might make another available
        for free or conversely having two capabilities at once may
        have multiplicative impact.
        Estimates are relative to the current set of capabilities -
        that is, how much more impact given the currently possessed capabilities.
        <p/>
        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.
        <p/>
        See the
        <internallink id="capabilityExamples">Capability Examples</internallink>.
      </description>
      <origin>new</origin>
      <capabilities>
      </capabilities>
      <parameters>
        <param id="capabilities_ptr">
          <inptr><struct>jvmtiCapabilities</struct></inptr>
          <description>
            points to the <jvmti/> capabilities to evaluate.
          </description>
        </param>
        <param id="time_impact_ptr">
          <outptr><jint/></outptr>
          <description>
            On return, points to the estimated percentage increase in
            run time if this capability was added.
          </description>
        </param>
        <param id="space_impact_ptr">
          <outptr><jint/></outptr>
          <description>
            On return, points to the estimated percentage increase in
            memory space used if this capability was added.
          </description>
        </param>
      </parameters>
      <errors>
        <error id="JVMTI_ERROR_NOT_AVAILABLE">
          The desired capabilities are not even potentially available.
        </error>
      </errors>
    </function>
    </elide>

    <function id="AddCapabilities" jkernel="yes" phase="onload" num="142">
      <synopsis>Add Capabilities</synopsis>
      <description>
        Set new capabilities by adding the capabilities
        whose values are set to one (<code>1</code>) in
        <code>*</code><paramlink id="capabilities_ptr"></paramlink>.
        All previous capabilities are retained.
        Typically this function is used in the <code>OnLoad</code> function.
        Some virtual machines may allow a limited set of capabilities to be
        added in the live phase.
        <p/>
        See the
        <internallink id="capabilityExamples">Capability Examples</internallink>.
      </description>
      <origin>new</origin>
      <capabilities>
      </capabilities>
      <parameters>
        <param id="capabilities_ptr">
          <inptr><struct>jvmtiCapabilities</struct></inptr>
          <description>
            Points to the <jvmti/> capabilities to add.
          </description>
        </param>
      </parameters>
      <errors>
        <error id="JVMTI_ERROR_NOT_AVAILABLE">
          The desired capabilities are not even potentially available.
        </error>
      </errors>
    </function>


    <function id="RelinquishCapabilities" phase="onload" num="143">
      <synopsis>Relinquish Capabilities</synopsis>
      <description>
        Relinquish the capabilities
        whose values are set to one (<code>1</code>) in
        <code>*</code><paramlink id="capabilities_ptr"></paramlink>.
        Some implementations may allow only one environment to have a capability
        (see the <internallink id="capability">capability introduction</internallink>).
        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 <functionlink id="GetCapabilities"></functionlink>.
        Attempting to relinquish a capability that the agent does not possess is not an error.
          <issue>
            It is possible for the agent to be actively using capabilities
            which are being relinquished.  For example, a thread is currently
            suspended and can_suspend is being relinquished or an event is currently
            enabled and can_generate_whatever is being relinquished.
            There are three possible ways we could spec this:
            <ul>
              <li>relinquish automatically releases them</li>
              <li>relinquish checks and returns some error code if held</li>
              <li>it is the agent's responsibility and it is not checked</li>
            </ul>
            One of these should be chosen.
          </issue>
      </description>
      <origin>new</origin>
      <capabilities>
      </capabilities>
      <parameters>
        <param id="capabilities_ptr">
          <inptr><struct>jvmtiCapabilities</struct></inptr>
          <description>
            Points to the <jvmti/> capabilities to relinquish.
          </description>
        </param>
      </parameters>
      <errors>
      </errors>
    </function>



    <function id="GetCapabilities" jkernel="yes" phase="any" num="89">
      <synopsis>Get Capabilities</synopsis>
        <description>
          Returns via <paramlink id="capabilities_ptr"></paramlink> the optional <jvmti/>
          features which this environment currently possesses.
          Each possessed capability is indicated by a one (<code>1</code>) in the
          corresponding field of the <internallink id="jvmtiCapabilities">capabilities
          structure</internallink>.
          An environment does not possess a capability unless it has been successfully added with
          <functionlink id="AddCapabilities"/>.
          An environment only loses possession of a capability if it has been relinquished with
          <functionlink id="RelinquishCapabilities"/>. Thus, this function returns the net result
          of the <code>AddCapabilities</code> and <code>RelinquishCapabilities</code> calls which
          have been made.
          <p/>
          See the
          <internallink id="capabilityExamples">Capability Examples</internallink>.
        </description>
      <origin>jvmdiClone</origin>
      <capabilities>
      </capabilities>
      <parameters>
        <param id="capabilities_ptr">
          <outptr><struct>jvmtiCapabilities</struct></outptr>
          <description>
            On return, points to the <jvmti/> capabilities.
          </description>
        </param>
      </parameters>
      <errors>
      </errors>
    </function>

  </category>


  <category id="timers" label="Timers">

      <intro>
        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.
      </intro>

      <typedef id="jvmtiTimerInfo" label="Timer Info">
        <description>
          The information function for each timer returns this data structure.
        </description>
        <field id="max_value">
          <jlong/>
            <description>
              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.
            </description>
        </field>
        <field id="may_skip_forward">
          <jboolean/>
          <description>
            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.
          </description>
        </field>
        <field id="may_skip_backward">
          <jboolean/>
          <description>
            If true, the timer can be externally adjusted and as a result skip backward.
            If false, the timer value will be monotonically increasing.
          </description>
        </field>
        <field id="kind">
          <enum>jvmtiTimerKind</enum>
          <description>
            The kind of timer.
            On a platform that does not distinguish between user and system time, <datalink
                 id="JVMTI_TIMER_TOTAL_CPU"><code>JVMTI_TIMER_TOTAL_CPU</code></datalink>
            is returned.
          </description>
        </field>
        <field id="reserved1">
          <jlong/>
            <description>
              Reserved for future use.
            </description>
        </field>
        <field id="reserved2">
          <jlong/>
            <description>
              Reserved for future use.
            </description>
        </field>
      </typedef>

      <intro>
        Where the timer kind is --

        <constants id="jvmtiTimerKind" label="Timer Kinds" kind="enum">
          <constant id="JVMTI_TIMER_USER_CPU" num="30">
            CPU time that a thread is in user mode.
          </constant>
          <constant id="JVMTI_TIMER_TOTAL_CPU" num="31">
            CPU time that a thread is in user or system mode.
          </constant>
          <constant id="JVMTI_TIMER_ELAPSED" num="32">
            Elapsed time.
          </constant>
        </constants>
      </intro>

    <function id="GetCurrentThreadCpuTimerInfo" callbacksafe="safe"  impl="innative notrace" phase="start" num="134">
      <synopsis>Get Current Thread CPU Timer Information</synopsis>
      <description>
        Get information about the
        <functionlink id="GetCurrentThreadCpuTime"/> timer.
        The fields of the <datalink id="jvmtiTimerInfo"/> structure
        are filled in with details about the timer.
        This information is specific to the platform and the implementation of
        <functionlink id="GetCurrentThreadCpuTime"/> and thus
        does not vary by thread nor does it vary
        during a particular invocation of the VM.
        <p/>
        Note that the implementations of <functionlink id="GetCurrentThreadCpuTime"/>
        and <functionlink id="GetThreadCpuTime"/> may differ, and thus the values
        returned by <code>GetCurrentThreadCpuTimerInfo</code>
        and <functionlink id="GetThreadCpuTimerInfo"/>
        may differ -- see <functionlink id="GetCurrentThreadCpuTime"/> for more information.
      </description>
      <origin>new</origin>
      <capabilities>
        <required id="can_get_current_thread_cpu_time">
            Can get current thread CPU time.
        </required>
      </capabilities>
      <parameters>
        <param id="info_ptr">
          <outptr><struct>jvmtiTimerInfo</struct></outptr>
          <description>
            On return, filled with information describing the time
            returned by <functionlink id="GetCurrentThreadCpuTime"/>.
          </description>
        </param>
      </parameters>
      <errors>
      </errors>
    </function>

    <function id="GetCurrentThreadCpuTime" callbacksafe="safe" impl="innative notrace" phase="start" num="135">
      <synopsis>Get Current Thread CPU Time</synopsis>
      <description>
            Return the CPU time utilized by the current thread.
            <p/>
            Note that the <functionlink id="GetThreadCpuTime"/>
            function provides CPU time for any thread, including
            the current thread. <code>GetCurrentThreadCpuTime</code>
            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
            <functionlink id="GetCurrentThreadCpuTimerInfo"/> vs
            <functionlink id="GetThreadCpuTimerInfo"/>).
            On many platforms this call will be equivalent to:
<example>
  GetThreadCpuTime(env, NULL, nanos_ptr)
</example>
      </description>
      <origin>new</origin>
      <capabilities>
        <required id="can_get_current_thread_cpu_time">
            Can get current thread CPU time.
            <p/>
            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.
            <p/>
            This capability must be potentially available on any
            platform where
            <internallink id="jvmtiCapabilities.can_get_thread_cpu_time"><code>can_get_thread_cpu_time</code></internallink>
            is potentially available.
        </required>
      </capabilities>
      <parameters>
        <param id="nanos_ptr">
          <outptr><jlong/></outptr>
          <description>
            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.
          </description>
        </param>
      </parameters>
      <errors>
      </errors>
    </function>

    <function id="GetThreadCpuTimerInfo" num="136">
      <synopsis>Get Thread CPU Timer Information</synopsis>
      <description>
        Get information about the
        <functionlink id="GetThreadCpuTime"/> timer.
        The fields of the <datalink id="jvmtiTimerInfo"/> structure
        are filled in with details about the timer.
        This information is specific to the platform and the implementation of
        <functionlink id="GetThreadCpuTime"/> and thus
        does not vary by thread nor does it vary
        during a particular invocation of the VM.
        <p/>
        Note that the implementations of <functionlink id="GetCurrentThreadCpuTime"/>
        and <functionlink id="GetThreadCpuTime"/> may differ, and thus the values
        returned by <functionlink id="GetCurrentThreadCpuTimerInfo"/>
        and <code>GetThreadCpuTimerInfo</code>
        may differ -- see <functionlink id="GetCurrentThreadCpuTime"/> for more information.
      </description>
      <origin>new</origin>
      <capabilities>
        <required id="can_get_thread_cpu_time">
            Can get thread CPU time.
        </required>
      </capabilities>
      <parameters>
        <param id="info_ptr">
          <outptr><struct>jvmtiTimerInfo</struct></outptr>
          <description>
            On return, filled with information describing the time
            returned by <functionlink id="GetThreadCpuTime"/>.
          </description>
        </param>
      </parameters>
      <errors>
      </errors>
    </function>

    <function id="GetThreadCpuTime" num="137">
      <synopsis>Get Thread CPU Time</synopsis>
      <description>
          Return the CPU time utilized by the specified thread.
          <p/>
          Get information about this timer with
          <functionlink id="GetThreadCpuTimerInfo"/>.
      </description>
      <origin>new</origin>
      <capabilities>
        <required id="can_get_thread_cpu_time">
            Can get thread CPU time.
            <p/>
            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.
        </required>
      </capabilities>
      <parameters>
        <param id="thread">
          <jthread null="current"/>
            <description>
              The thread to query.
            </description>
        </param>
        <param id="nanos_ptr">
          <outptr><jlong/></outptr>
          <description>
            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.
          </description>
        </param>
      </parameters>
      <errors>
      </errors>
    </function>

    <function id="GetTimerInfo" phase="any" callbacksafe="safe" num="138">
      <synopsis>Get Timer Information</synopsis>
      <description>
        Get information about the
        <functionlink id="GetTime"/> timer.
        The fields of the <datalink id="jvmtiTimerInfo"/> structure
        are filled in with details about the timer.
        This information will not change during a particular invocation of the VM.
      </description>
      <origin>new</origin>
      <capabilities>
      </capabilities>
      <parameters>
        <param id="info_ptr">
          <outptr><struct>jvmtiTimerInfo</struct></outptr>
          <description>
            On return, filled with information describing the time
            returned by <functionlink id="GetTime"/>.
          </description>
        </param>
      </parameters>
      <errors>
      </errors>
    </function>

    <function id="GetTime" phase="any" callbacksafe="safe" num="139">
      <synopsis>Get Time</synopsis>
      <description>
          Return the current value of the system timer, in nanoseconds.
          <p/>
          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.
          <p/>
          Get information about this timer with
          <functionlink id="GetTimerInfo"/>.
      </description>
      <origin>new</origin>
      <capabilities>
      </capabilities>
      <parameters>
        <param id="nanos_ptr">
          <outptr><jlong/></outptr>
          <description>
            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.
          </description>
        </param>
      </parameters>
      <errors>
      </errors>
    </function>

    <function id="GetAvailableProcessors" phase="any" num="144">
      <synopsis>Get Available Processors</synopsis>
      <description>
          Returns the number of processors available to the Java virtual machine.
          <p/>
          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.
      </description>
      <origin>new</origin>
      <capabilities>
      </capabilities>
      <parameters>
        <param id="processor_count_ptr">
          <outptr><jint/></outptr>
          <description>
            On return, points to the maximum number of processors available to the
            virtual machine; never smaller than one.
          </description>
        </param>
      </parameters>
      <errors>
      </errors>
    </function>

  </category>


  <category id="classLoaderSearch" label="Class Loader Search">

    <intro>
      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.
    </intro>

    <function id="AddToBootstrapClassLoaderSearch" jkernel="yes" phase="onload" num="149">
      <synopsis>Add To Bootstrap Class Loader Search</synopsis>
      <description>
          This function can be used to cause instrumentation classes to be defined by the
          bootstrap class loader. See <vmspec chapter="5.3.1"/>.
          After the bootstrap
          class loader unsuccessfully searches for a class, the specified platform-dependent
          search path <paramlink id="segment"/> will be searched as well. Only one segment may be specified in
          the <paramlink id="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.
          <p/>
          In the <code>OnLoad</code> 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.
          <p/>
          In the live phase the <paramlink id="segment"/> may be used to specify any platform-dependent
          path to a <externallink id="jar/jar.html">
          JAR file</externallink>. 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.
          <p/>
          <vmspec/> 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.
      </description>
      <origin>new</origin>
      <capabilities>
      </capabilities>
      <parameters>
        <param id="segment">
          <inbuf><char/></inbuf>
          <description>
            The platform-dependent search path segment, encoded as a
            <internallink id="mUTF">modified UTF-8</internallink> string.
          </description>
        </param>
      </parameters>
      <errors>
        <error id="JVMTI_ERROR_ILLEGAL_ARGUMENT">
          <paramlink id="segment"/> is an invalid path. In the live phase, anything other than an
           existing JAR file is an invalid path.
        </error>
      </errors>
    </function>

    <function id="AddToSystemClassLoaderSearch" jkernel="yes" phase="onload" num="151" since="1.1">
      <synopsis>Add To System Class Loader Search</synopsis>
      <description>
          This function can be used to cause instrumentation classes to be
          defined by the system class loader. See <vmspec chapter="5.3.2"/>.
          After the class loader unsuccessfully searches for a class, the specified platform-dependent search
          path <paramlink id="segment"/> will be searched as well. Only one segment may be specified in the
          <paramlink id="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.
          <p/>
          In the <code>OnLoad</code> 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.
          <p/>
          In the live phase the <paramlink id="segment"/> is a platform-dependent path to a
          <externallink id="jar/jar.html">JAR file</externallink> 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.
          <p/>
          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 <code>appendToClassPathForInstrumentation</code>
          which takes a single parameter of type <code>java.lang.String</code>. The method is not required
          to have <code>public</code> access.
          <p/>
          <vmspec/> 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.
      </description>
      <origin>new</origin>
      <capabilities>
      </capabilities>
      <parameters>
        <param id="segment">
          <inbuf><char/></inbuf>
          <description>
            The platform-dependent search path segment, encoded as a
            <internallink id="mUTF">modified UTF-8</internallink> string.
          </description>
        </param>
      </parameters>
      <errors>
        <error id="JVMTI_ERROR_ILLEGAL_ARGUMENT">
          <paramlink id="segment"/> is an invalid path. In the live phase, anything other than an
           existing JAR file is an invalid path.
        </error>
        <error id="JVMTI_ERROR_CLASS_LOADER_UNSUPPORTED">
          Operation not supported by the system class loader.
        </error>
      </errors>
    </function>

  </category>


  <category id="props" label="System Properties">

    <intro>
      These functions get and set system properties.
    </intro>

    <function id="GetSystemProperties" phase="onload" num="130">
      <synopsis>Get System Properties</synopsis>
      <description>
        The list of VM system property keys which may be used with
        <functionlink id="GetSystemProperty"/> is returned.
        It is strongly recommended that virtual machines provide the
        following property keys:
        <ul>
          <li><code>java.vm.vendor</code></li>
          <li><code>java.vm.version</code></li>
          <li><code>java.vm.name</code></li>
          <li><code>java.vm.info</code></li>
          <li><code>java.library.path</code></li>
          <li><code>java.class.path</code></li>
        </ul>
        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 <code>java.lang.System.getProperties</code>.
        JNI method invocation may be used to access
        <code>java.lang.System.getProperties</code>.
        <p/>
        The set of properties may grow during execution.
      </description>
      <origin>new</origin>
      <capabilities>
      </capabilities>
      <parameters>
        <param id="count_ptr">
          <outptr><jint/></outptr>
          <description>
            On return, points to the number of property keys returned.
          </description>
        </param>
        <param id="property_ptr">
          <allocallocbuf outcount="count_ptr"><char/></allocallocbuf>
          <description>
            On return, points to an array of property keys, encoded as
            <internallink id="mUTF">modified UTF-8</internallink> strings.
          </description>
        </param>
      </parameters>
      <errors>
      </errors>
    </function>

    <function id="GetSystemProperty" phase="onload" num="131">
      <synopsis>Get System Property</synopsis>
      <description>
        Return a VM system property value given the property key.
        <p/>
        The function <functionlink id="GetSystemProperties"/>
        returns the set of property keys which may be used.
        The properties which can be retrieved may grow during
        execution.
        <p/>
        Since this is a VM view of system properties, the values
        of properties may differ from that returned by
        <code>java.lang.System.getProperty(String)</code>.
        A typical VM might copy the values of the VM system
        properties into the <code>Properties</code> held by
        <code>java.lang.System</code> during the initialization
        of that class. Thereafter any changes to the VM system
        properties (with <functionlink id="SetSystemProperty"/>)
        or the <code>java.lang.System</code> system properties
        (with <code>java.lang.System.setProperty(String,String)</code>)
        would cause the values to diverge.
        JNI method invocation may be used to access
        <code>java.lang.System.getProperty(String)</code>.
      </description>
      <origin>new</origin>
      <capabilities>
      </capabilities>
      <parameters>
        <param id="property">
          <inbuf><char/></inbuf>
          <description>
            The key of the property to retrieve, encoded as a
            <internallink id="mUTF">modified UTF-8</internallink> string.
          </description>
        </param>
        <param id="value_ptr">
          <allocbuf><char/></allocbuf>
          <description>
            On return, points to the property value, encoded as a
            <internallink id="mUTF">modified UTF-8</internallink> string.
          </description>
        </param>
      </parameters>
      <errors>
        <error id="JVMTI_ERROR_NOT_AVAILABLE">
          This property is not available.
          Use <functionlink id="GetSystemProperties"/> to find available properties.
        </error>
      </errors>
    </function>

    <function id="SetSystemProperty" phase="onloadOnly" num="132">
      <synopsis>Set System Property</synopsis>
      <description>
        Set a VM system property value.
        <p/>
        The function <functionlink id="GetSystemProperties"/>
        returns the set of property keys, some of these may be settable.
        See <functionlink id="GetSystemProperty"/>.
      </description>
      <origin>new</origin>
      <capabilities>
      </capabilities>
      <parameters>
        <param id="property">
          <inbuf><char/></inbuf>
          <description>
            The key of the property, encoded as a
            <internallink id="mUTF">modified UTF-8</internallink> string.
          </description>
        </param>
        <param id="value_ptr">
          <inbuf>
            <char/>
            <nullok>
              do not set the value, but return <errorlink id="JVMTI_ERROR_NOT_AVAILABLE"/>
              if the property is not writeable
            </nullok>
          </inbuf>
          <description>
            The property value to set, encoded as a
            <internallink id="mUTF">modified UTF-8</internallink> string.
          </description>
        </param>
      </parameters>
      <errors>
        <error id="JVMTI_ERROR_NOT_AVAILABLE">
          This property is not available or is not writeable.
        </error>
      </errors>
    </function>

  </category>

  <category id="general" label="General">

    <intro>
    </intro>

    <function id="GetPhase" jkernel="yes" phase="any" num="133">
      <synopsis>Get Phase</synopsis>
      <description>
          Return the current phase of VM execution.
          The phases proceed in sequence:
          <constants id="jvmtiPhase" label="Phases of execution" kind="enum">
            <constant id="JVMTI_PHASE_ONLOAD" num="1">
              <code>OnLoad</code> phase: while in the
              <internallink id="onload"><code>Agent_OnLoad</code></internallink>
              or, for statically linked agents, the <internallink id="onload">
              <code>Agent_OnLoad_&lt;agent-lib-name&gt;
              </code></internallink> function.
            </constant>
            <constant id="JVMTI_PHASE_PRIMORDIAL" num="2">
              Primordial phase: between return from <code>Agent_OnLoad</code>
              or <code>Agent_OnLoad_&lt;agent-lib-name&gt;</code> and the
              <code>VMStart</code> event.
            </constant>
            <constant id="JVMTI_PHASE_START" num="6">
              Start phase: when the <eventlink id="VMStart"><code>VMStart</code></eventlink> event
              is sent and until the <code>VMInit</code> event is sent.
            </constant>
            <constant id="JVMTI_PHASE_LIVE" num="4">
              Live phase: when the <eventlink id="VMInit"><code>VMInit</code></eventlink> event is sent
              and until the <eventlink id="VMDeath"></eventlink> event returns.
            </constant>
            <constant id="JVMTI_PHASE_DEAD" num="8">
              Dead phase: after the <eventlink id="VMDeath"></eventlink> event returns or after
              start-up failure.
            </constant>
          </constants>
          In the case of start-up failure the VM will proceed directly to the dead
          phase skipping intermediate phases and neither a <code>VMInit</code> nor
          <code>VMDeath</code> event will be sent.
          <p/>
          Most <jvmti/> functions operate only in the live phase.
          The following functions operate in either the <code>OnLoad</code> or live phases:
          <functionphaselist phase="onload"/>
          The following functions operate in only the <code>OnLoad</code> phase:
          <functionphaselist phase="onloadOnly"/>
          The following functions operate in the start or live phases:
          <functionphaselist phase="start"/>
          The following functions operate in any phase:
          <functionphaselist phase="any"/>
          JNI functions (except the Invocation API) must only be used in the start or live phases.
          <p/>
          Most <jvmti/> events are sent only in the live phase.
          The following events operate in others phases:
          <eventphaselist phase="start"/>
          <eventphaselist phase="any"/>
      </description>
      <origin>new</origin>
      <capabilities>
      </capabilities>
      <parameters>
        <param id="phase_ptr">
          <outptr><enum>jvmtiPhase</enum></outptr>
          <description>
            On return, points to the phase.
          </description>
        </param>
      </parameters>
      <errors>
      </errors>
    </function>

    <function id="DisposeEnvironment" jkernel="yes" phase="any" num="127">
      <synopsis>Dispose Environment</synopsis>
      <description>
        Shutdown a <jvmti/> connection created with JNI <code>GetEnv</code>
        (see <internallink id="environments"><jvmti/> Environments</internallink>).
        Dispose of any resources held by the environment.
        <issue>
            What resources are reclaimed? What is undone?
            Breakpoints,watchpoints removed?
        </issue>
        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 <jvmti/> functions
        is not released, this can be done explicitly by the agent
        by calling <functionlink id="Deallocate"/>.
        Raw monitors created by this environment are not destroyed,
        this can be done explicitly by the agent
        by calling <functionlink id="DestroyRawMonitor"/>.
        The state of threads waiting on raw monitors created by this environment
        are not affected.
        <p/>
        Any <functionlink id="SetNativeMethodPrefix">native method
        prefixes</functionlink> for this environment will be unset;
        the agent must remove any prefixed native methods before
        dispose is called.
        <p/>
        Any <internallink id="capability">capabilities</internallink>
        held by this environment are relinquished.
        <p/>
        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.
        <p/>
        This environment may not be used after this call.
        This call returns to the caller.
      </description>
      <origin>new</origin>
      <capabilities>
      </capabilities>
      <parameters>
      </parameters>
      <errors>
      </errors>
    </function>

    <function id="SetEnvironmentLocalStorage" jkernel="yes" phase="any" callbacksafe="safe" impl="innative notrace" num="148">
      <synopsis>Set Environment Local Storage</synopsis>
      <description>
        The VM stores a pointer value associated with each environment.
        This pointer value is called <i>environment-local storage</i>.
        This value is <code>NULL</code> 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
        <functionlink id="GetEnvironmentLocalStorage"></functionlink>.
        <p/>
        Called by the agent to set the value of the <jvmti/>
        environment-local storage. <jvmti/> supplies to the agent a pointer-size
        environment-local storage that can be used to record per-environment
        information.
      </description>
      <origin>new</origin>
      <capabilities>
      </capabilities>
      <parameters>
        <param id="data">
          <inbuf>
            <void/>
            <nullok>value is set to <code>NULL</code></nullok>
          </inbuf>
          <description>
            The value to be entered into the environment-local storage.
          </description>
        </param>
      </parameters>
      <errors>
      </errors>
    </function>

    <function id="GetEnvironmentLocalStorage" jkernel="yes" phase="any" callbacksafe="safe" impl="innative notrace" num="147">
      <synopsis>Get Environment Local Storage</synopsis>
      <description>
        Called by the agent to get the value of the <jvmti/> environment-local
        storage.
      </description>
      <origin>new</origin>
      <capabilities>
      </capabilities>
      <parameters>
        <param id="data_ptr">
          <agentbuf><void/></agentbuf>
          <description>
            Pointer through which the value of the environment local
            storage is returned.
            If environment-local storage has not been set with
            <functionlink id="SetEnvironmentLocalStorage"></functionlink> returned
            pointer is <code>NULL</code>.
          </description>
        </param>
      </parameters>
      <errors>
      </errors>
    </function>

    <function id="GetVersionNumber" jkernel="yes" phase="any" num="88">
      <synopsis>Get Version Number</synopsis>
      <description>
        Return the <jvmti/> version via <code>version_ptr</code>.
        The return value is the version identifier.
        The version identifier includes major, minor and micro
        version as well as the interface type.
        <constants id="jvmtiVersionInterfaceTypes" label="Version Interface Types" kind="bits">
          <constant id="JVMTI_VERSION_INTERFACE_JNI" num="0x00000000">
            Value of <code>JVMTI_VERSION_MASK_INTERFACE_TYPE</code> for JNI.
          </constant>
          <constant id="JVMTI_VERSION_INTERFACE_JVMTI" num="0x30000000">
            Value of <code>JVMTI_VERSION_MASK_INTERFACE_TYPE</code> for <jvmti/>.
          </constant>
        </constants>
        <constants id="jvmtiVersionMasks" label="Version Masks" kind="bits">
          <constant id="JVMTI_VERSION_MASK_INTERFACE_TYPE" num="0x70000000">
            Mask to extract interface type.
            The value of the version returned by this function masked with
            <code>JVMTI_VERSION_MASK_INTERFACE_TYPE</code> is always
            <code>JVMTI_VERSION_INTERFACE_JVMTI</code>
            since this is a <jvmti/> function.
          </constant>
          <constant id="JVMTI_VERSION_MASK_MAJOR" num="0x0FFF0000">
            Mask to extract major version number.
          </constant>
          <constant id="JVMTI_VERSION_MASK_MINOR" num="0x0000FF00">
            Mask to extract minor version number.
          </constant>
          <constant id="JVMTI_VERSION_MASK_MICRO" num="0x000000FF">
            Mask to extract micro version number.
          </constant>
        </constants>
        <constants id="jvmtiVersionShifts" label="Version Shifts" kind="bits">
          <constant id="JVMTI_VERSION_SHIFT_MAJOR" num="16">
            Shift to extract major version number.
          </constant>
          <constant id="JVMTI_VERSION_SHIFT_MINOR" num="8">
            Shift to extract minor version number.
          </constant>
          <constant id="JVMTI_VERSION_SHIFT_MICRO" num="0">
            Shift to extract micro version number.
          </constant>
        </constants>
      </description>
      <origin>jvmdi</origin>
      <capabilities>
      </capabilities>
      <parameters>
        <param id="version_ptr">
          <outptr><jint/></outptr>
          <description>
            On return, points to the <jvmti/> version.
          </description>
        </param>
      </parameters>
      <errors>
      </errors>
    </function>


    <function id="GetErrorName" phase="any" num="128">
      <synopsis>Get Error Name</synopsis>
      <description>
        Return the symbolic name for an
          <internallink id="ErrorSection">error code</internallink>.
        <p/>
        For example
        <code>GetErrorName(env, JVMTI_ERROR_NONE, &amp;err_name)</code>
        would return in <code>err_name</code> the string
        <code>"JVMTI_ERROR_NONE"</code>.
      </description>
      <origin>new</origin>
      <capabilities>
      </capabilities>
      <parameters>
        <param id="error">
          <enum>jvmtiError</enum>
          <description>
            The error code.
          </description>
        </param>
        <param id="name_ptr">
          <allocbuf><char/></allocbuf>
          <description>
            On return, points to the error name.
            The name is encoded as a
            <internallink id="mUTF">modified UTF-8</internallink> string,
            but is restricted to the ASCII subset.
          </description>
        </param>
      </parameters>
      <errors>
      </errors>
    </function>

    <function id="SetVerboseFlag" phase="any" num="150">
      <synopsis>Set Verbose Flag</synopsis>
      <description>
        <constants id="jvmtiVerboseFlag" label="Verbose Flag Enumeration" kind="enum">
          <constant id="JVMTI_VERBOSE_OTHER" num="0">
            Verbose output other than the below.
          </constant>
          <constant id="JVMTI_VERBOSE_GC" num="1">
            Verbose garbage collector output, like that specified with <code>-verbose:gc</code>.
          </constant>
          <constant id="JVMTI_VERBOSE_CLASS" num="2">
            Verbose class loading output, like that specified with <code>-verbose:class</code>.
          </constant>
          <constant id="JVMTI_VERBOSE_JNI" num="4">
            Verbose JNI output, like that specified with <code>-verbose:jni</code>.
          </constant>
        </constants>
        Control verbose output.
        This is the output which typically is sent to <code>stderr</code>.
      </description>
      <origin>new</origin>
      <capabilities>
      </capabilities>
      <parameters>
        <param id="flag">
          <enum>jvmtiVerboseFlag</enum>
          <description>
            Which verbose flag to set.
          </description>
        </param>
        <param id="value">
          <jboolean/>
          <description>
            New value of the flag.
          </description>
        </param>
      </parameters>
      <errors>
      </errors>
    </function>


    <function id="GetJLocationFormat" phase="any" num="129">
      <synopsis>Get JLocation Format</synopsis>
      <description>
        Although the greatest functionality is achieved with location information
        referencing the virtual machine bytecode index, the definition of
        <code>jlocation</code> has intentionally been left unconstrained to allow VM
        implementations that do not have this information.
        <p/>
        This function describes the representation of <code>jlocation</code> used in this VM.
        If the returned format is <datalink id="JVMTI_JLOCATION_JVMBCI"></datalink>,
        <code>jlocation</code>s can
        be used as in indices into the array returned by
        <functionlink id="GetBytecodes"></functionlink>.
        <constants id="jvmtiJlocationFormat" label="JLocation Format Enumeration" kind="enum">
          <constant id="JVMTI_JLOCATION_JVMBCI" num="1">
            <code>jlocation</code> values represent virtual machine
            bytecode indices--that is, offsets into the
            virtual machine code for a method.
          </constant>
          <constant id="JVMTI_JLOCATION_MACHINEPC" num="2">
            <code>jlocation</code> values represent native machine
            program counter values.
          </constant>
          <constant id="JVMTI_JLOCATION_OTHER" num="0">
            <code>jlocation</code> values have some other representation.
          </constant>
        </constants>
      </description>
      <origin>new</origin>
      <capabilities>
      </capabilities>
      <parameters>
        <param id="format_ptr">
          <outptr><enum>jvmtiJlocationFormat</enum></outptr>
          <description>
            On return, points to the format identifier for <code>jlocation</code> values.
          </description>
        </param>
      </parameters>
      <errors>
      </errors>
    </function>

  </category>

  <category id="heap_monitoring" label="Heap Monitoring">
    <function id="SetHeapSamplingInterval" phase="onload" num="156" since="11">
      <synopsis>Set Heap Sampling Interval</synopsis>
      <description>
        Generate a <eventlink id="SampledObjectAlloc"/> event when objects are allocated.
        Each thread keeps a counter of bytes allocated. The event will only be generated
        when that counter exceeds an average of <paramlink id="sampling_interval"></paramlink>
        since the last sample.
        <p/>
        Setting <paramlink id="sampling_interval"></paramlink> to 0 will cause an event to be
        generated by each allocation supported by the system once the new interval is taken into account.
        <p/>
        Note that updating the new sampling interval might take various number of allocations
        to provoke internal data structure updates.  Therefore it is important to
        consider the sampling interval as an average. This includes the interval 0, where events
        might not be generated straight away for each allocation.
      </description>
      <origin>new</origin>
      <capabilities>
        <required id="can_generate_sampled_object_alloc_events"></required>
      </capabilities>
      <parameters>
        <param id="sampling_interval">
          <jint/>
          <description>
            The sampling interval in bytes. The sampler uses a statistical approach to
            generate an event, on average, once for every <paramlink id="sampling_interval"/> bytes of
            memory allocated by a given thread.
            <p/>
            Once the new sampling interval is taken into account, 0 as a sampling interval will generate
            a sample for every allocation.
            <p/>
            Note: The overhead of this feature is directly correlated with the sampling interval.
            A high sampling interval, such as 1024 bytes, will incur a high overhead.
            A lower interval, such as 1024KB, will have a much lower overhead.  Sampling should only
            be used with an understanding that it may impact performance.
          </description>
        </param>
      </parameters>
      <errors>
        <error id="JVMTI_ERROR_ILLEGAL_ARGUMENT">
          <paramlink id="sampling_interval"></paramlink> is less than zero.
        </error>
      </errors>
    </function>
  </category>

</functionsection>

<errorsection label="Error Reference">
  <intro>
    Every <jvmti/> function returns a <b><code>jvmtiError</code></b> error code.
    <p/>
    It is the responsibility of the agent to call <jvmti/> 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
    <internallink id="reqerrors">Function Specific Required Errors</internallink>
    must be detected by the implementation.
    All other errors represent the recommended response to the error
    condition.
  </intro>

  <errorcategory id="universal-error" label="Universal Errors">
    <intro>
      The following errors may be returned by any function
    </intro>

    <errorid id="JVMTI_ERROR_NONE" num="0">
      No error has occurred.  This is the error code that is returned
      on successful completion of the function.
    </errorid>
    <errorid id="JVMTI_ERROR_NULL_POINTER" num="100">
      Pointer is unexpectedly <code>NULL</code>.
    </errorid>
    <errorid id="JVMTI_ERROR_OUT_OF_MEMORY" num="110">
      The function attempted to allocate memory and no more memory was
      available for allocation.
    </errorid>
    <errorid id="JVMTI_ERROR_ACCESS_DENIED" num="111">
      The desired functionality has not been enabled in this virtual machine.
    </errorid>
    <errorid id="JVMTI_ERROR_UNATTACHED_THREAD" num="115">
      The thread being used to call this function is not attached
      to the virtual machine.  Calls must be made from attached threads.
      See <code>AttachCurrentThread</code> in the JNI invocation API.
    </errorid>
    <errorid id="JVMTI_ERROR_INVALID_ENVIRONMENT" num="116">
      The <jvmti/> environment provided is no longer connected or is
      not an environment.
    </errorid>
    <errorid id="JVMTI_ERROR_WRONG_PHASE" num="112">
      The desired functionality is not available in the current
        <functionlink id="GetPhase">phase</functionlink>.
      Always returned if the virtual machine has completed running.
    </errorid>
    <errorid id="JVMTI_ERROR_INTERNAL" num="113">
      An unexpected internal error has occurred.
    </errorid>
  </errorcategory>

  <errorcategory id="reqerrors" label="Function Specific Required Errors">
    <intro>
      The following errors are returned by some <jvmti/> functions and must
      be returned by the implementation when the condition occurs.
    </intro>

    <errorid id="JVMTI_ERROR_INVALID_PRIORITY" num="12">
      Invalid priority.
    </errorid>
    <errorid id="JVMTI_ERROR_THREAD_NOT_SUSPENDED" num="13">
      Thread was not suspended.
    </errorid>
    <errorid id="JVMTI_ERROR_THREAD_SUSPENDED" num="14">
      Thread already suspended.
    </errorid>
    <errorid id="JVMTI_ERROR_THREAD_NOT_ALIVE" num="15">
      This operation requires the thread to be alive--that is,
      it must be started and not yet have died.
    </errorid>
    <errorid id="JVMTI_ERROR_CLASS_NOT_PREPARED" num="22">
      The class has been loaded but not yet prepared.
    </errorid>
    <errorid id="JVMTI_ERROR_NO_MORE_FRAMES" num="31">
      There are no Java programming language or JNI stack frames at the specified depth.
    </errorid>
    <errorid id="JVMTI_ERROR_OPAQUE_FRAME" num="32">
      Information about the frame is not available (e.g. for native frames).
    </errorid>
    <errorid id="JVMTI_ERROR_DUPLICATE" num="40">
      Item already set.
    </errorid>
    <errorid id="JVMTI_ERROR_NOT_FOUND" num="41">
      Desired element (e.g. field or breakpoint) not found
    </errorid>
    <errorid id="JVMTI_ERROR_NOT_MONITOR_OWNER" num="51">
      This thread doesn't own the raw monitor.
    </errorid>
    <errorid id="JVMTI_ERROR_INTERRUPT" num="52">
      The call has been interrupted before completion.
    </errorid>
    <errorid id="JVMTI_ERROR_UNMODIFIABLE_CLASS" num="79">
      The class cannot be modified.
    </errorid>
    <errorid id="JVMTI_ERROR_UNMODIFIABLE_MODULE" num="80">
      The module cannot be modified.
    </errorid>
    <errorid id="JVMTI_ERROR_NOT_AVAILABLE" num="98">
      The functionality is not available in this virtual machine.
    </errorid>
    <errorid id="JVMTI_ERROR_ABSENT_INFORMATION" num="101">
      The requested information is not available.
    </errorid>
    <errorid id="JVMTI_ERROR_INVALID_EVENT_TYPE" num="102">
      The specified event type ID is not recognized.
    </errorid>
    <errorid id="JVMTI_ERROR_NATIVE_METHOD" num="104">
      The requested information is not available for native method.
    </errorid>
    <errorid id="JVMTI_ERROR_CLASS_LOADER_UNSUPPORTED" num="106">
      The class loader does not support this operation.
    </errorid>
  </errorcategory>

  <errorcategory id="function-specific-errors" label="Function Specific Agent Errors">
    <intro>
      The following errors are returned by some <jvmti/> 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.
    </intro>

    <errorid id="JVMTI_ERROR_INVALID_THREAD" num="10">
      The passed thread is not a valid thread.
    </errorid>
    <errorid id="JVMTI_ERROR_INVALID_FIELDID" num="25">
      Invalid field.
    </errorid>
    <errorid id="JVMTI_ERROR_INVALID_MODULE" num="26">
      Invalid module.
    </errorid>
    <errorid id="JVMTI_ERROR_INVALID_METHODID" num="23">
      Invalid method.
    </errorid>
    <errorid id="JVMTI_ERROR_INVALID_LOCATION" num="24">
      Invalid location.
    </errorid>
    <errorid id="JVMTI_ERROR_INVALID_OBJECT" num="20">
      Invalid object.
    </errorid>
    <errorid id="JVMTI_ERROR_INVALID_CLASS" num="21">
      Invalid class.
    </errorid>
    <errorid id="JVMTI_ERROR_TYPE_MISMATCH" num="34">
      The variable is not an appropriate type for the function used.
    </errorid>
    <errorid id="JVMTI_ERROR_INVALID_SLOT" num="35">
      Invalid slot.
    </errorid>
    <errorid id="JVMTI_ERROR_MUST_POSSESS_CAPABILITY" num="99">
      The capability being used is false in this environment.
    </errorid>
    <errorid id="JVMTI_ERROR_INVALID_THREAD_GROUP" num="11">
      Thread group invalid.
    </errorid>
    <errorid id="JVMTI_ERROR_INVALID_MONITOR" num="50">
      Invalid raw monitor.
    </errorid>
    <errorid id="JVMTI_ERROR_ILLEGAL_ARGUMENT" num="103">
      Illegal argument.
    </errorid>
    <errorid id="JVMTI_ERROR_INVALID_TYPESTATE" num="65">
      The state of the thread has been modified, and is now inconsistent.
    </errorid>
    <errorid id="JVMTI_ERROR_UNSUPPORTED_VERSION" num="68">
      A new class file has a version number not supported by this VM.
    </errorid>
    <errorid id="JVMTI_ERROR_INVALID_CLASS_FORMAT" num="60">
      A new class file is malformed (the VM would return a <code>ClassFormatError</code>).
    </errorid>
    <errorid id="JVMTI_ERROR_CIRCULAR_CLASS_DEFINITION" num="61">
      The new class file definitions would lead to a circular
      definition (the VM would return a <code>ClassCircularityError</code>).
    </errorid>
    <errorid id="JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_ADDED" num="63">
      A new class file would require adding a method.
    </errorid>
    <errorid id="JVMTI_ERROR_UNSUPPORTED_REDEFINITION_SCHEMA_CHANGED" num="64">
      A new class version changes a field.
    </errorid>
    <errorid id="JVMTI_ERROR_FAILS_VERIFICATION" num="62">
      The class bytes fail verification.
    </errorid>
    <errorid id="JVMTI_ERROR_UNSUPPORTED_REDEFINITION_HIERARCHY_CHANGED" num="66">
      A direct superclass is different for the new class
      version, or the set of directly implemented
      interfaces is different.
    </errorid>
    <errorid id="JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_DELETED" num="67">
      A new class version does not declare a method
      declared in the old class version.
    </errorid>
    <errorid id="JVMTI_ERROR_NAMES_DONT_MATCH" num="69">
      The class name defined in the new class file is
      different from the name in the old class object.
    </errorid>
    <errorid id="JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_MODIFIERS_CHANGED" num="70">
      A new class version has different modifiers.
    </errorid>
    <errorid id="JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_MODIFIERS_CHANGED" num="71">
      A method in the new class version has different modifiers
      than its counterpart in the old class version.
    </errorid>
    <errorid id="JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_ATTRIBUTE_CHANGED" num="72">
      A new class version has unsupported differences in class attributes.
    </errorid>
  </errorcategory>
</errorsection>

<eventsection label="Events">
  <intro label="Handling Events" id="eventIntro">
    Agents can be informed of many events that occur in application
    programs.
    <p/>
    To handle events, designate a set of callback functions with
    <functionlink id="SetEventCallbacks"></functionlink>.
    For each event the corresponding callback function will be
    called.
    Arguments to the callback function provide additional
    information about the event.
    <p/>
    The callback function is usually called from within an application
    thread. The <jvmti/> 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.
    <p/>
    <ul>
      <li>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.
      </li>
      <li>Event callback functions must be re-entrant. The <jvmti/> 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.
      </li>
      <li>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.
      </li>
    </ul>
    <p/>
    Some <jvmti/> events identify objects with JNI references.
    All references
    in <jvmti/> 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.
    <p/>
    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
    <functionlink id="GetPhase">phases</functionlink> in which it can be sent;
    if an event triggering activity occurs during another phase, no event
    is sent.
    <p/>
    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
    <functionlink id="SuspendThread"></functionlink>.
    <p/>
    If an event is enabled in multiple environments, the event will be sent
    to each agent in the order that the environments were created.
  </intro>

  <intro label="Enabling Events" id="enablingevents">
    All events are initially disabled.  In order to receive any
    event:
      <ul>
        <li>
          If the event requires a capability, that capability must
          be added with
          <functionlink id="AddCapabilities"></functionlink>.
        </li>
        <li>
          A callback for the event must be set with
          <functionlink id="SetEventCallbacks"></functionlink>.
        </li>
        <li>
          The event must be enabled with
          <functionlink id="SetEventNotificationMode"></functionlink>.
        </li>
      </ul>
  </intro>

  <intro label="Multiple Co-located Events" id="eventorder">
    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.
    <p/>
    If the current location is at the entry point of a method, the
    <eventlink id="MethodEntry"></eventlink> event is reported before
    any other event at the current location in the same thread.
    <p/>
    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
    <code>exceptionCatch</code> event is reported before
    any other event at the current location in the same thread.
    <p/>
    If a <code>singleStep</code> event or
    <code>breakpoint</code> 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:
    <code>exception</code>,
    <code>fieldAccess</code>, and
    <code>fieldModification</code>).
    If both a step and breakpoint event are triggered for the same thread and
    location, the step event is reported before the breakpoint event.
    <p/>
    If the current location is the exit point of a method (that is, the last
    location before returning to the caller), the
    <eventlink id="MethodExit"></eventlink> event and
    the <eventlink id="FramePop"></eventlink> 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.
    <p/>
    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 <i>y</i>, is triggered during the processing of
    an event of type <i>x</i>, and if <i>x</i>
    precedes <i>y</i> in the ordering specified above, the co-located event
    <i>y</i> is reported for the current thread and location. If <i>x</i> does not precede
    <i>y</i>, <i>y</i> is not reported for the current thread and location.
    For example, if a breakpoint is set at the current location
    during the processing of <eventlink id="SingleStep"></eventlink>,
    that breakpoint will be reported before the thread moves off the current
    location.
    <p/>The following events are never considered to be co-located with
    other events.
    <ul>
      <li><eventlink id="VMStart"></eventlink></li>
      <li><eventlink id="VMInit"></eventlink></li>
      <li><eventlink id="VMDeath"></eventlink></li>
      <li><eventlink id="ThreadStart"></eventlink></li>
      <li><eventlink id="ThreadEnd"></eventlink></li>
      <li><eventlink id="ClassLoad"></eventlink></li>
      <li><eventlink id="ClassPrepare"></eventlink></li>
    </ul>
  </intro>

  <intro label="Event Callbacks" id="jvmtiEventCallbacks">
      The event callback structure below is used to specify the handler function
      for events.  It is set with the
      <functionlink id="SetEventCallbacks"></functionlink> function.
  </intro>

  <event label="Single Step"
         id="SingleStep" const="JVMTI_EVENT_SINGLE_STEP" filtered="thread" num="60">
    <description>
      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 <vmspec/>. However, some implementations
      may define locations differently. In any case the
      <code>method</code> and <code>location</code>
      parameters  uniquely identify the current location and allow
      the mapping to source file and line number when that information is
      available.
      <p/>
      No single step events are generated from within native methods.
    </description>
    <origin>jvmdi</origin>
    <capabilities>
      <required id="can_generate_single_step_events"></required>
    </capabilities>
    <parameters>
      <param id="jni_env">
        <outptr>
          <struct>JNIEnv</struct>
        </outptr>
          <description>
            The JNI environment of the event (current) thread
          </description>
      </param>
      <param id="thread">
        <jthread/>
          <description>
            Thread about to execution a new instruction
          </description>
      </param>
      <param id="klass">
        <jclass method="method"/>
          <description>
            Class of the method about to execute a new instruction
          </description>
      </param>
      <param id="method">
        <jmethodID class="klass"/>
          <description>
            Method about to execute a new instruction
          </description>
      </param>
      <param id="location">
        <jlocation/>
        <description>
          Location of the new instruction
        </description>
      </param>
    </parameters>
  </event>

  <event label="Breakpoint"
         id="Breakpoint" const="JVMTI_EVENT_BREAKPOINT" filtered="thread" num="62">
    <description>
      Breakpoint events are generated whenever a thread reaches a location
      designated as a breakpoint with <functionlink id="SetBreakpoint"></functionlink>.
      The <code>method</code> and <code>location</code>
      parameters uniquely identify the current location and allow
      the mapping to source file and line number when that information is
      available.
    </description>
    <origin>jvmdi</origin>
    <capabilities>
      <required id="can_generate_breakpoint_events"></required>
    </capabilities>
    <parameters>
      <param id="jni_env">
        <outptr>
          <struct>JNIEnv</struct>
        </outptr>
          <description>
            The JNI environment of the event (current) thread.
          </description>
      </param>
      <param id="thread">
        <jthread/>
          <description>
            Thread that hit the breakpoint
          </description>
      </param>
      <param id="klass">
        <jclass method="method"/>
          <description>
            Class of the method that hit the breakpoint
          </description>
      </param>
      <param id="method">
        <jmethodID class="klass"/>
          <description>
            Method that hit the breakpoint
          </description>
      </param>
      <param id="location">
        <jlocation/>
        <description>
          location of the breakpoint
        </description>
      </param>
    </parameters>
  </event>

  <event label="Field Access"
         id="FieldAccess" const="JVMTI_EVENT_FIELD_ACCESS" filtered="thread" num="63">
    <description>
      Field access events are generated whenever a thread accesses
      a field that was designated as a watchpoint
      with <functionlink id="SetFieldAccessWatch"></functionlink>.
      The <code>method</code> and <code>location</code>
      parameters uniquely identify the current location and allow
      the mapping to source file and line number when that information is
      available.
    </description>
    <origin>jvmdi</origin>
    <capabilities>
      <required id="can_generate_field_access_events"></required>
    </capabilities>
    <parameters>
      <param id="jni_env">
        <outptr>
          <struct>JNIEnv</struct>
        </outptr>
          <description>
            The JNI environment of the event (current) thread
          </description>
      </param>
      <param id="thread">
        <jthread/>
          <description>
            Thread accessing the field
          </description>
      </param>
      <param id="klass">
        <jclass method="method"/>
          <description>
            Class of the method where the access is occurring
          </description>
      </param>
      <param id="method">
        <jmethodID class="klass"/>
          <description>
            Method where the access is occurring
          </description>
      </param>
      <param id="location">
        <jlocation/>
        <description>
          Location where the access is occurring
        </description>
      </param>
      <param id="field_klass">
        <jclass field="field"/>
          <description>
            Class of the field being accessed
          </description>
      </param>
      <param id="object">
        <jobject/>
          <description>
            Object with the field being accessed if the field is an
            instance field; <code>NULL</code> otherwise
          </description>
      </param>
      <param id="field">
        <jfieldID class="field_klass"/>
          <description>
            Field being accessed
          </description>
      </param>
    </parameters>
  </event>

  <event label="Field Modification"
         id="FieldModification" const="JVMTI_EVENT_FIELD_MODIFICATION" filtered="thread" num="64">
    <description>
      Field modification events are generated whenever a thread modifies
      a field that was designated as a watchpoint
      with <functionlink id="SetFieldModificationWatch"></functionlink>.
      The <code>method</code> and <code>location</code>
      parameters uniquely identify the current location and allow
      the mapping to source file and line number when that information is
      available.
    </description>
    <origin>jvmdi</origin>
    <capabilities>
      <required id="can_generate_field_modification_events"></required>
    </capabilities>
    <parameters>
      <param id="jni_env">
        <outptr>
          <struct>JNIEnv</struct>
        </outptr>
          <description>
            The JNI environment of the event (current) thread
          </description>
      </param>
      <param id="thread">
        <jthread/>
          <description>
            Thread modifying the field
          </description>
      </param>
      <param id="klass">
        <jclass method="method"/>
          <description>
            Class of the method where the modification is occurring
          </description>
      </param>
      <param id="method">
        <jmethodID class="klass"/>
          <description>
            Method where the modification is occurring
          </description>
      </param>
      <param id="location">
        <jlocation/>
        <description>
          Location where the modification is occurring
        </description>
      </param>
      <param id="field_klass">
        <jclass field="field"/>
          <description>
            Class of the field being modified
          </description>
      </param>
      <param id="object">
        <jobject/>
          <description>
            Object with the field being modified if the field is an
            instance field; <code>NULL</code> otherwise
          </description>
      </param>
      <param id="field">
        <jfieldID class="field_klass"/>
          <description>
            Field being modified
          </description>
      </param>
      <param id="signature_type">
        <char/>
        <description>
          Signature type of the new value
        </description>
      </param>
      <param id="new_value">
        <jvalue/>
        <description>
          The new value
        </description>
      </param>
    </parameters>
  </event>

  <event label="Frame Pop"
         id="FramePop" const="JVMTI_EVENT_FRAME_POP" filtered="thread" num="61">
    <description>
      Frame pop events are generated upon exit from a single method
      in a single frame as specified
      in a call to <functionlink id="NotifyFramePop"></functionlink>.
      This is true whether termination is caused by
      executing its return instruction
      or by throwing an exception to its caller
      (see <paramlink id="was_popped_by_exception"></paramlink>).
      However, frame pops caused by the <functionlink id="PopFrame"/>
      function are not reported.
      <p/>
      The location reported by <functionlink id="GetFrameLocation"></functionlink>
      identifies the executable location in the returning method,
      immediately prior to the return.
    </description>
    <origin>jvmdi</origin>
    <capabilities>
      <required id="can_generate_frame_pop_events"></required>
    </capabilities>
    <parameters>
      <param id="jni_env">
        <outptr>
          <struct>JNIEnv</struct>
        </outptr>
          <description>
            The JNI environment of the event (current) thread
          </description>
      </param>
      <param id="thread">
        <jthread/>
          <description>
            Thread that is popping the frame
          </description>
      </param>
      <param id="klass">
        <jclass method="method"/>
          <description>
            Class of the method being popped
          </description>
      </param>
      <param id="method">
        <jmethodID class="klass"/>
          <description>
            Method being popped
          </description>
      </param>
      <param id="was_popped_by_exception">
        <jboolean/>
        <description>
          True if frame was popped by a thrown exception.
          False if method exited through its return instruction.
        </description>
      </param>
    </parameters>
  </event>

  <event label="Method Entry"
         id="MethodEntry" const="JVMTI_EVENT_METHOD_ENTRY" filtered="thread" num="65">
    <description>
      Method entry events are generated upon entry of Java
      programming language methods (including native methods).
      <p/>
      The location reported by <functionlink id="GetFrameLocation"></functionlink>
      identifies the initial executable location in
      the method.
      <p/>
      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).
      <internallink id="bci">Bytecode instrumentation</internallink> should be
      used in these cases.
    </description>
    <origin>jvmdi</origin>
    <capabilities>
      <required id="can_generate_method_entry_events"></required>
    </capabilities>
    <parameters>
      <param id="jni_env">
        <outptr>
          <struct>JNIEnv</struct>
        </outptr>
          <description>
            The JNI environment of the event (current) thread
          </description>
      </param>
      <param id="thread">
        <jthread/>
          <description>
            Thread entering the method
          </description>
      </param>
      <param id="klass">
        <jclass method="method"/>
          <description>
            Class of the method being entered
          </description>
      </param>
      <param id="method">
        <jmethodID class="klass"/>
          <description>
            Method being entered
          </description>
      </param>
    </parameters>
  </event>

  <event label="Method Exit"
         id="MethodExit" const="JVMTI_EVENT_METHOD_EXIT" filtered="thread" num="66">
    <description>
      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 <paramlink id="was_popped_by_exception"></paramlink>).
      <p/>
      The <code>method</code> field uniquely identifies the
      method being entered or exited. The <code>frame</code> field provides
      access to the stack frame for the method.
      <p/>
      The location reported by <functionlink id="GetFrameLocation"></functionlink>
      identifies the executable location in the returning method
      immediately prior to the return.
      <p/>
        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).
        <internallink id="bci">Bytecode instrumentation</internallink> should be
        used in these cases.
    </description>
    <origin>jvmdi</origin>
    <capabilities>
      <required id="can_generate_method_exit_events"></required>
    </capabilities>
    <parameters>
      <param id="jni_env">
        <outptr>
          <struct>JNIEnv</struct>
        </outptr>
          <description>
            The JNI environment of the event (current) thread
          </description>
      </param>
      <param id="thread">
        <jthread/>
          <description>
            Thread exiting the method
          </description>
      </param>
      <param id="klass">
        <jclass method="method"/>
          <description>
            Class of the method being exited
          </description>
      </param>
      <param id="method">
        <jmethodID class="klass"/>
          <description>
            Method being exited
          </description>
      </param>
      <param id="was_popped_by_exception">
        <jboolean/>
        <description>
          True if frame was popped by a thrown exception.
          False if method exited through its return instruction.
        </description>
      </param>
      <param id="return_value">
        <jvalue/>
        <description>
          The return value of the method being exited.
          Undefined and should not be used if
          <paramlink id="was_popped_by_exception"></paramlink>
          is true.
        </description>
      </param>
    </parameters>
  </event>

  <event label="Native Method Bind" phase="any"
         id="NativeMethodBind" const="JVMTI_EVENT_NATIVE_METHOD_BIND" num="67">
    <description>
      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 <code>RegisterNatives</code> 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 <code>RegisterNatives</code>.
      Some events may be sent during the primordial phase, JNI and
      most of <jvmti/> cannot be used at this time but the method and
      address can be saved for use later.
    </description>
    <origin>new</origin>
    <capabilities>
      <required id="can_generate_native_method_bind_events"></required>
    </capabilities>
    <parameters>
      <param id="jni_env">
        <outptr>
          <struct>JNIEnv</struct>
        </outptr>
          <description>
            The JNI environment of the event (current) thread
            Will be <code>NULL</code> if sent during the primordial
            <functionlink id="GetPhase">phase</functionlink>.
          </description>
      </param>
      <param id="thread">
        <jthread/>
          <description>
            Thread requesting the bind
          </description>
      </param>
      <param id="klass">
        <jclass method="method"/>
          <description>
            Class of the method being bound
          </description>
      </param>
      <param id="method">
        <jmethodID class="klass"/>
          <description>
            Native method being bound
          </description>
      </param>
      <param id="address">
        <outptr><void/></outptr>
        <description>
          The address the VM is about to bind to--that is, the
          address of the implementation of the native method
        </description>
      </param>
      <param id="new_address_ptr">
        <agentbuf><void/></agentbuf>
        <description>
          if the referenced address is changed (that is, if
          <code>*new_address_ptr</code> is set), the binding
          will instead be made to the supplied address.
        </description>
      </param>
    </parameters>
  </event>

  <event label="Exception"
         id="Exception" const="JVMTI_EVENT_EXCEPTION" filtered="thread" num="58">
    <description>
      Exception events are generated whenever an exception is first detected
      in a Java programming language method.
      Where "exception" means any <code>java.lang.Throwable</code>.
      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.
      <p/>
      The <code>method</code> and <code>location</code>
      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 <code>exception</code> field identifies the thrown
      exception object. The <code>catch_method</code>
      and <code>catch_location</code> 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 (<code>catch_klass</code>
      et al. set to 0) may in fact be caught by native code.
      Agents can check for these occurrences by monitoring
      <eventlink id="ExceptionCatch"></eventlink> events.
      Note that finally clauses are implemented as catch and re-throw. Therefore they
      will be reported in the catch location.
    </description>
    <origin>jvmdi</origin>
    <capabilities>
      <required id="can_generate_exception_events"></required>
    </capabilities>
    <parameters>
      <param id="jni_env">
        <outptr>
          <struct>JNIEnv</struct>
        </outptr>
          <description>
            The JNI environment of the event (current) thread
          </description>
      </param>
      <param id="thread">
        <jthread/>
          <description>
            Thread generating the exception
          </description>
      </param>
      <param id="klass">
        <jclass method="method"/>
          <description>
            Class generating the exception
          </description>
      </param>
      <param id="method">
        <jmethodID class="klass"/>
          <description>
            Method generating the exception
          </description>
      </param>
      <param id="location">
        <jlocation/>
        <description>
          Location where exception occurred
        </description>
      </param>
      <param id="exception">
        <jobject/>
          <description>
            The exception being thrown
          </description>
      </param>
      <param id="catch_klass">
        <jclass method="catch_method"/>
          <description>
            Class that will catch the exception, or <code>NULL</code> if no known catch
          </description>
      </param>
      <param id="catch_method">
        <jmethodID class="catch_klass"/>
          <description>
            Method that will catch the exception, or <code>NULL</code> if no known catch
          </description>
      </param>
      <param id="catch_location">
        <jlocation/>
        <description>
          location which will catch the exception or zero if no known catch
        </description>
      </param>
    </parameters>
  </event>

  <event label="Exception Catch"
         id="ExceptionCatch" const="JVMTI_EVENT_EXCEPTION_CATCH" filtered="thread" num="59">
    <description>
      Exception catch events are generated whenever a thrown exception is caught.
      Where "exception" means any <code>java.lang.Throwable</code>.
      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.
      <p/>
      The <code>method</code> and <code>location</code>
      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
      <code>exception</code> object identifies the exception object. Exceptions
      caught in native methods are not necessarily available by the time the
      exception catch is reported, so the <code>exception</code> field is set
      to <code>NULL</code>.
    </description>
    <origin>jvmdi</origin>
    <capabilities>
      <required id="can_generate_exception_events"></required>
    </capabilities>
    <parameters>
      <param id="jni_env">
        <outptr>
          <struct>JNIEnv</struct>
        </outptr>
          <description>
            The JNI environment of the event (current) thread
          </description>
      </param>
      <param id="thread">
        <jthread/>
          <description>
            Thread catching the exception
          </description>
      </param>
      <param id="klass">
        <jclass method="method"/>
          <description>
            Class catching the exception
          </description>
      </param>
      <param id="method">
        <jmethodID class="klass"/>
          <description>
            Method catching the exception
          </description>
      </param>
      <param id="location">
        <jlocation/>
        <description>
          Location where exception is being caught
        </description>
      </param>
      <param id="exception">
        <jobject/>
          <description>
            Exception being caught
          </description>
      </param>
    </parameters>
  </event>

  <event label="Thread Start"
         id="ThreadStart" const="JVMTI_EVENT_THREAD_START" num="52" phase="start">
    <description>
      Thread start events are generated by a new thread before its initial
      method executes.
      <p/>
      A thread may be listed in the array returned by
      <functionlink id="GetAllThreads"></functionlink>
      before its thread start event is generated.
      It is possible for other events to be generated
      on a thread before its thread start event.
      <p/>
      The event is sent on the newly started <paramlink id="thread"></paramlink>.
    </description>
    <origin>jvmdi</origin>
    <capabilities>
    </capabilities>
    <parameters>
      <param id="jni_env">
        <outptr>
          <struct>JNIEnv</struct>
        </outptr>
          <description>
            The JNI environment of the event (current) thread.
          </description>
      </param>
      <param id="thread">
        <jthread/>
          <description>
            Thread starting
          </description>
      </param>
    </parameters>
  </event>

  <event label="Thread End"
         id="ThreadEnd" const="JVMTI_EVENT_THREAD_END" filtered="thread" num="53" phase="start">
    <description>
      Thread end events are generated by a terminating thread
      after its initial method has finished execution.
      <p/>
      A thread may be listed in the array returned by
      <functionlink id="GetAllThreads"></functionlink>
      after its thread end event is generated.
      No events are generated on a thread
      after its thread end event.
      <p/>
      The event is sent on the dying <paramlink id="thread"></paramlink>.
    </description>
    <origin>jvmdi</origin>
    <capabilities>
    </capabilities>
    <parameters>
      <param id="jni_env">
        <outptr>
          <struct>JNIEnv</struct>
        </outptr>
          <description>
            The JNI environment of the event (current) thread.
          </description>
      </param>
      <param id="thread">
        <jthread/>
          <description>
            Thread ending
          </description>
      </param>
    </parameters>
  </event>

  <event label="Class Load"
         id="ClassLoad" const="JVMTI_EVENT_CLASS_LOAD" filtered="thread" phase="start" num="55">
    <description>
      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.
      <p/>
      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 <i>Java Language
      Specification</i>.  For most
      purposes the <eventlink id="ClassPrepare"></eventlink> event will
      be more useful.
    </description>
    <origin>jvmdi</origin>
    <capabilities>
    </capabilities>
    <parameters>
      <param id="jni_env">
        <outptr>
          <struct>JNIEnv</struct>
        </outptr>
          <description>
            The JNI environment of the event (current) thread
          </description>
      </param>
      <param id="thread">
        <jthread/>
          <description>
            Thread loading the class
          </description>
      </param>
      <param id="klass">
        <jclass/>
          <description>
            Class being loaded
          </description>
      </param>
    </parameters>
  </event>

  <elide>
  <event label="Class Unload"
         id="ClassUnload" const="JVMTI_EVENT_CLASS_UNLOAD" num="57">
    <description>
      A class unload event is generated when the class is about to be unloaded.
      Class unload events take place during garbage collection and must be
      handled extremely carefully. The garbage collector holds many locks
      and has suspended all other threads, so the event handler cannot depend
      on the ability to acquire any locks. The class unload event handler should
      do as little as possible, perhaps by queuing information to be processed
      later.  In particular, the <code>jclass</code> should be used only in
      the JNI function <code>isSameObject</code> or in the following <jvmti/> functions:
      <ul>
        <li><functionlink id="GetClassSignature"></functionlink></li>
        <li><functionlink id="GetSourceFileName"></functionlink></li>
        <li><functionlink id="IsInterface"></functionlink></li>
        <li><functionlink id="IsArrayClass"></functionlink></li>
      </ul>
    </description>
    <origin>jvmdi</origin>
    <capabilities>
    </capabilities>
    <parameters>
      <param id="jni_env">
        <outptr>
          <struct>JNIEnv</struct>
        </outptr>
          <description>
            The JNI environment of the event (current) thread
          </description>
      </param>
      <param id="thread">
        <jthread/>
          <description>
            Thread generating the class unload
          </description>
      </param>
      <param id="klass">
        <jclass/>
          <description>
            Class being unloaded
          </description>
      </param>
    </parameters>
  </event>
  </elide>

  <event label="Class Prepare"
         id="ClassPrepare" const="JVMTI_EVENT_CLASS_PREPARE" filtered="thread" phase="start" num="56">
    <description>
      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, <code>java.lang.Integer.TYPE</code>).
    </description>
    <origin>jvmdi</origin>
    <capabilities>
    </capabilities>
    <parameters>
      <param id="jni_env">
        <outptr>
          <struct>JNIEnv</struct>
        </outptr>
          <description>
            The JNI environment of the event (current) thread
          </description>
      </param>
      <param id="thread">
        <jthread/>
          <description>
            Thread generating the class prepare
          </description>
      </param>
      <param id="klass">
        <jclass/>
          <description>
            Class being prepared
          </description>
      </param>
    </parameters>
  </event>

  <event label="Class File Load Hook" phase="any"
         id="ClassFileLoadHook" const="JVMTI_EVENT_CLASS_FILE_LOAD_HOOK" num="54">
    <description>
      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
      <functionlink id="RetransformClasses"/> function or
      the <functionlink id="RedefineClasses"/> function,
      called in any <jvmti/> environment.
      The agent can instrument
      the existing class file data sent by the VM to include profiling/debugging hooks.
      See the description of
      <internallink id="bci">bytecode instrumentation</internallink>
      for usage information.
      <p/>
    When the capabilities
    <internallink id="jvmtiCapabilities.can_generate_early_class_hook_events">
    <code>can_generate_early_class_hook_events</code></internallink> and
    <internallink id="jvmtiCapabilities.can_generate_all_class_hook_events">
    <code>can_generate_all_class_hook_events</code></internallink>
    are enabled then this event may be sent in the primordial phase.
    Otherwise, this event may be sent before the VM is initialized (the start
    <functionlink id="GetPhase">phase</functionlink>).
    Some classes might not be compatible
    with the function (eg. ROMized classes or implementation defined classes) and this event will
    not be generated for these classes.
    <p/>
    The agent must allocate the space for the modified
    class file data buffer
    using the memory allocation function
    <functionlink id="Allocate"></functionlink> because the
    VM is responsible for freeing the new class file data buffer
    using <functionlink id="Deallocate"></functionlink>.
    <p/>
    If the agent wishes to modify the class file, it must set
    <code>new_class_data</code> to point
    to the newly instrumented class file data buffer and set
    <code>new_class_data_len</code> to the length of that
    buffer before returning
    from this call.  If no modification is desired, the agent simply
    does not set <code>new_class_data</code>.  If multiple agents
    have enabled this event the results are chained. That is, if
    <code>new_class_data</code> has been set, it becomes the
    <code>class_data</code> for the next agent.
    <p/>
    When handling a class load in the live phase, then the
    <functionlink id="GetNamedModule"></functionlink>
    function can be used to map class loader and a package name to a module.
    When a class is being redefined or retransformed then
    <code>class_being_redefined</code> is non <code>NULL</code> and so
    the JNI <code>GetModule</code> function can also be used
    to obtain the Module.
    <p/>
    The order that this event is sent to each environment differs
    from other events.
    This event is sent to environments in the following order:
    <ul>
      <li><fieldlink id="can_retransform_classes"
                     struct="jvmtiCapabilities">retransformation
                                                incapable</fieldlink>
          environments, in the
          order in which they were created
      </li>
      <li><fieldlink id="can_retransform_classes"
                     struct="jvmtiCapabilities">retransformation
                                                capable</fieldlink>
          environments, in the
          order in which they were created
      </li>
    </ul>
    When triggered by <functionlink id="RetransformClasses"/>,
    this event is sent only to <fieldlink id="can_retransform_classes"
                     struct="jvmtiCapabilities">retransformation
                                                capable</fieldlink>
    environments.
  </description>
  <origin>jvmpi</origin>
    <capabilities>
      <capability id="can_generate_all_class_hook_events"></capability>
      <capability id="can_generate_early_class_hook_events"></capability>
    </capabilities>
    <parameters>
      <param id="jni_env">
        <outptr>
          <struct>JNIEnv</struct>
        </outptr>
          <description>
            The JNI environment of the event (current) thread.
          </description>
      </param>
      <param id="class_being_redefined">
        <jclass/>
        <description>
          The class being
          <functionlink id="RedefineClasses">redefined</functionlink> or
          <functionlink id="RetransformClasses">retransformed</functionlink>.
          <code>NULL</code> if sent by class load.
        </description>
      </param>
      <param id="loader">
        <jobject/>
          <description>
            The class loader loading the class.
            <code>NULL</code> if the bootstrap class loader.
          </description>
      </param>
      <param id="name">
        <vmbuf><char/></vmbuf>
        <description>
            Name of class being loaded as a VM internal qualified name
            (for example, "java/util/List"), encoded as a
            <internallink id="mUTF">modified UTF-8</internallink> string.
            Note: if the class is defined with a <code>NULL</code> name or
            without a name specified, <code>name</code> will be <code>NULL</code>.
        </description>
      </param>
      <param id="protection_domain">
        <jobject/>
        <description>
          The <code>ProtectionDomain</code> of the class.
        </description>
      </param>
      <param id="class_data_len">
        <jint/>
        <description>
          Length of current class file data buffer.
        </description>
      </param>
      <param id="class_data">
        <vmbuf><uchar/></vmbuf>
        <description>
          Pointer to the current class file data buffer.
        </description>
      </param>
      <param id="new_class_data_len">
        <outptr><jint/></outptr>
        <description>
          Pointer to the length of the new class file data buffer.
        </description>
      </param>
      <param id="new_class_data">
        <agentbuf incount="new_class_data_len"><uchar/></agentbuf>
        <description>
          Pointer to the pointer to the instrumented class file data buffer.
        </description>
      </param>
    </parameters>
  </event>

  <event label="VM Start Event"
         id="VMStart" const="JVMTI_EVENT_VM_START" num="57" phase="start">
    <description>
      The VM start 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,
      <jvmti/> functions permitted in the start phase may be called.
      <p/>
      The timing of this event may depend on whether the agent has added the
      <internallink id="jvmtiCapabilities.can_generate_early_vmstart">
      <code>can_generate_early_vmstart</code></internallink> capability or not.
      If the capability has been added then the VM posts the event as early
      as possible. The VM is capable of executing bytecode but it may not have
      initialized to the point where it can load classes in modules other than
      <code>java.base</code>, or even arbitrary classes in <code>java.base</code>.
      Agents that do load-time instrumentation in this
      phase must take great care when instrumenting code that potentially
      executes in this phase. Extreme care should also be taken with JNI
      <code>FindClass</code> as it may not be possible to load classes and attempts
      to do so may result in unpredictable behavior, maybe even stability issues
      on some VM implementations.
      If the capability has not been added then the VM delays posting this
      event until it is capable of loading classes in modules other than
      <code>java.base</code> or the VM has completed its initialization.
      Agents that create more than one JVM TI environment, where the
      capability is added to some but not all environments, may observe the
      start phase beginning earlier in the JVM TI environments that possess
      the capability.
      <p/>
      In the case of VM start-up failure, this event will not be sent.
    </description>
    <origin>jvmdi</origin>
    <capabilities>
    </capabilities>
    <parameters>
      <param id="jni_env">
        <outptr>
          <struct>JNIEnv</struct>
        </outptr>
          <description>
            The JNI environment of the event (current) thread.
          </description>
      </param>
    </parameters>
  </event>

  <event label="VM Initialization Event"
         id="VMInit" const="JVMTI_EVENT_VM_INIT" num="50">
    <description>
      The VM initialization event signals the completion of VM initialization. Once
      this event is generated, the agent is free to call any JNI or <jvmti/>
      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.
      <p/>
      In the case of VM start-up failure, this event will not be sent.
    </description>
    <origin>jvmdi</origin>
    <capabilities>
    </capabilities>
    <parameters>
      <param id="jni_env">
        <outptr>
          <struct>JNIEnv</struct>
        </outptr>
          <description>
            The JNI environment of the event (current) thread.
          </description>
      </param>
      <param id="thread">
        <jthread/>
          <description>
            The initial thread
          </description>
      </param>
    </parameters>
  </event>

  <event label="VM Death Event"
         id="VMDeath" const="JVMTI_EVENT_VM_DEATH" num="51">
    <description>
      The VM death event notifies the agent of the termination of the VM.
      No events will occur after the VMDeath event.
      <p/>
      In the case of VM start-up failure, this event will not be sent.
      Note that <internallink id="onunload">Agent_OnUnload</internallink>
      will still be called in these cases.
    </description>
    <origin>jvmdi</origin>
    <capabilities>
    </capabilities>
    <parameters>
      <param id="jni_env">
        <outptr>
          <struct>JNIEnv</struct>
        </outptr>
          <description>
            The JNI environment of the event (current) thread
          </description>
      </param>
    </parameters>
  </event>

  <event label="Compiled Method Load" phase="start"
         id="CompiledMethodLoad" const="JVMTI_EVENT_COMPILED_METHOD_LOAD" num="68">
    <description>
      Sent when a method is compiled and loaded into memory by the VM.
      If it is unloaded, the <eventlink id="CompiledMethodUnload"/> event is sent.
      If it is moved, the <eventlink id="CompiledMethodUnload"/> event is sent,
      followed by a new <code>CompiledMethodLoad</code> 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.
      <p/>
      These events can be sent after their initial occurrence with
      <functionlink id="GenerateEvents"></functionlink>.
    </description>
    <origin>jvmpi</origin>
    <typedef id="jvmtiAddrLocationMap" label="Native address to location entry">
      <field id="start_address">
        <vmbuf><void/></vmbuf>
        <description>
          Starting native address of code corresponding to a location
        </description>
      </field>
      <field id="location">
        <jlocation/>
        <description>
          Corresponding location. See
          <functionlink id="GetJLocationFormat"></functionlink>
          for the meaning of location.
        </description>
      </field>
    </typedef>
    <capabilities>
      <required id="can_generate_compiled_method_load_events"></required>
    </capabilities>
    <parameters>
      <param id="klass">
        <jclass method="method"/>
          <description>
            Class of the method being compiled and loaded
          </description>
      </param>
      <param id="method">
        <jmethodID class="klass"/>
          <description>
            Method being compiled and loaded
          </description>
      </param>
      <param id="code_size">
        <jint/>
        <description>
          Size of compiled code
        </description>
      </param>
      <param id="code_addr">
        <vmbuf><void/></vmbuf>
        <description>
          Address where compiled method code is loaded
        </description>
      </param>
      <param id="map_length">
        <jint/>
        <description>
          Number of <typelink id="jvmtiAddrLocationMap"></typelink>
          entries in the address map.
          Zero if mapping information cannot be supplied.
        </description>
      </param>
      <param id="map">
        <vmbuf><struct>jvmtiAddrLocationMap</struct></vmbuf>
        <description>
          Map from native addresses to location.
          The native address range of each entry is from
          <fieldlink id="start_address" struct="jvmtiAddrLocationMap"></fieldlink>
          to <code>start_address-1</code> of the next entry.
          <code>NULL</code> if mapping information cannot be supplied.
        </description>
      </param>
      <param id="compile_info">
        <vmbuf><void/></vmbuf>
        <description>
          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.
        </description>
      </param>
    </parameters>
  </event>

  <event label="Compiled Method Unload" phase="start"
         id="CompiledMethodUnload" const="JVMTI_EVENT_COMPILED_METHOD_UNLOAD" num="69">
    <description>
      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.
    </description>
    <origin>jvmpi</origin>
    <capabilities>
      <required id="can_generate_compiled_method_load_events"></required>
    </capabilities>
    <parameters>
      <param id="klass">
        <jclass method="method"/>
          <description>
            Class of the compiled method being unloaded.
          </description>
      </param>
      <param id="method">
        <jmethodID class="klass"/>
          <description>
            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 <jvmti/> functions.
          </description>
      </param>
      <param id="code_addr">
        <vmbuf><void/></vmbuf>
        <description>
          Address where compiled method code was loaded.
          For identification of the compiled method only --
          the space may have been reclaimed.
        </description>
      </param>
    </parameters>
  </event>

  <event label="Dynamic Code Generated" phase="any"
         id="DynamicCodeGenerated" const="JVMTI_EVENT_DYNAMIC_CODE_GENERATED" num="70">
    <description>
      Sent when a component of the virtual machine is generated dynamically.
      This does not correspond to Java programming language code that is
      compiled--see <eventlink id="CompiledMethodLoad"></eventlink>.
      This is for native code--for example, an interpreter that is generated
      differently depending on command-line options.
      <p/>
      Note that this event has no controlling capability.
      If a VM cannot generate these events, it simply does not send any.
      <p/>
      These events can be sent after their initial occurrence with
      <functionlink id="GenerateEvents"></functionlink>.
    </description>
    <origin>jvmpi</origin>
    <capabilities>
    </capabilities>
    <parameters>
      <param id="name">
        <vmbuf><char/></vmbuf>
        <description>
          Name of the code, encoded as a
          <internallink id="mUTF">modified UTF-8</internallink> string.
          Intended for display to an end-user.
          The name might not be unique.
        </description>
      </param>
      <param id="address">
        <vmbuf><void/></vmbuf>
        <description>
          Native address of the code
        </description>
      </param>
      <param id="length">
        <jint/>
        <description>
          Length in bytes of the code
        </description>
      </param>
    </parameters>
  </event>

  <event label="Data Dump Request"
         id="DataDumpRequest" const="JVMTI_EVENT_DATA_DUMP_REQUEST" num="71">
    <description>
      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.
    </description>
    <origin>jvmpi</origin>
    <capabilities>
    </capabilities>
    <parameters>
    </parameters>
  </event>

  <event label="Monitor Contended Enter"
         id="MonitorContendedEnter" const="JVMTI_EVENT_MONITOR_CONTENDED_ENTER" filtered="thread" num="75">
    <description>
      Sent when a thread is attempting to enter a Java programming language
      monitor already acquired by another thread.
    </description>
    <origin>jvmpi</origin>
    <capabilities>
      <required id="can_generate_monitor_events"></required>
    </capabilities>
    <parameters>
      <param id="jni_env">
        <outptr>
          <struct>JNIEnv</struct>
        </outptr>
          <description>
            The JNI environment of the event (current) thread
          </description>
      </param>
      <param id="thread">
        <jthread/>
          <description>
            JNI local reference to the thread
            attempting to enter the monitor
          </description>
      </param>
      <param id="object">
        <jobject/>
          <description>
            JNI local reference to the monitor
          </description>
      </param>
    </parameters>
  </event>

  <event label="Monitor Contended Entered"
         id="MonitorContendedEntered" const="JVMTI_EVENT_MONITOR_CONTENDED_ENTERED" filtered="thread" num="76">
    <description>
      Sent when a thread enters a Java programming language
      monitor after waiting for it to be released by another thread.
    </description>
    <origin>jvmpi</origin>
    <capabilities>
      <required id="can_generate_monitor_events"></required>
    </capabilities>
    <parameters>
      <param id="jni_env">
        <outptr>
          <struct>JNIEnv</struct>
        </outptr>
          <description>
            The JNI environment of the event (current) thread
          </description>
      </param>
      <param id="thread">
        <jthread/>
          <description>
            JNI local reference to the thread entering
            the monitor
          </description>
      </param>
      <param id="object">
        <jobject/>
          <description>
            JNI local reference to the monitor
          </description>
      </param>
    </parameters>
  </event>

  <event label="Monitor Wait"
         id="MonitorWait" const="JVMTI_EVENT_MONITOR_WAIT" filtered="thread" num="73">
    <description>
      Sent when a thread is about to wait on an object.
    </description>
    <origin>jvmpi</origin>
    <capabilities>
      <required id="can_generate_monitor_events"></required>
    </capabilities>
    <parameters>
      <param id="jni_env">
        <outptr>
          <struct>JNIEnv</struct>
        </outptr>
          <description>
            The JNI environment of the event (current) thread
          </description>
      </param>
      <param id="thread">
        <jthread/>
          <description>
            JNI local reference to the thread about to wait
          </description>
      </param>
      <param id="object">
        <jobject/>
          <description>
            JNI local reference to the monitor
          </description>
      </param>
      <param id="timeout">
        <jlong/>
        <description>
          The number of milliseconds the thread will wait
        </description>
      </param>
    </parameters>
  </event>

  <event label="Monitor Waited"
         id="MonitorWaited" const="JVMTI_EVENT_MONITOR_WAITED" filtered="thread" num="74">
    <description>
      Sent when a thread finishes waiting on an object.
    </description>
    <origin>jvmpi</origin>
    <capabilities>
      <required id="can_generate_monitor_events"></required>
    </capabilities>
    <parameters>
      <param id="jni_env">
        <outptr>
          <struct>JNIEnv</struct>
        </outptr>
          <description>
            The JNI environment of the event (current) thread
          </description>
      </param>
      <param id="thread">
        <jthread/>
          <description>
            JNI local reference to the thread that was finished waiting
          </description>
      </param>
      <param id="object">
        <jobject/>
          <description>
            JNI local reference to the monitor.
          </description>
      </param>
      <param id="timed_out">
        <jboolean/>
        <description>
          True if the monitor timed out
        </description>
      </param>
    </parameters>
  </event>

  <event label="Resource Exhausted"
         id="ResourceExhausted" const="JVMTI_EVENT_RESOURCE_EXHAUSTED" num="80"
         since="1.1">
    <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.
      <p/>
      The following bit flags define the properties of the resource exhaustion:
      <constants id="jvmtiResourceExhaustionFlags"
                 label="Resource Exhaustion Flags"
                 kind="bits"
                 since="1.1">
        <constant id="JVMTI_RESOURCE_EXHAUSTED_OOM_ERROR" num="0x0001">
          After this event returns, the VM will throw a
          <code>java.lang.OutOfMemoryError</code>.
        </constant>
        <constant id="JVMTI_RESOURCE_EXHAUSTED_JAVA_HEAP" num="0x0002">
          The VM was unable to allocate memory from the <tm>Java</tm>
          platform <i>heap</i>.
          The <i>heap</i> is the runtime
          data area from which memory for all class instances and
          arrays are allocated.
        </constant>
        <constant id="JVMTI_RESOURCE_EXHAUSTED_THREADS" num="0x0004">
          The VM was unable to create a thread.
        </constant>
      </constants>
    </description>
    <origin>new</origin>
    <capabilities>
      <capability id="can_generate_resource_exhaustion_heap_events">
        Can generate events when the VM is unable to allocate memory from the
        <internallink id="JVMTI_RESOURCE_EXHAUSTED_JAVA_HEAP">heap</internallink>.
      </capability>
      <capability id="can_generate_resource_exhaustion_threads_events">
        Can generate events when the VM is unable to
        <internallink id="JVMTI_RESOURCE_EXHAUSTED_THREADS">create
        a thread</internallink>.
      </capability>
    </capabilities>
    <parameters>
      <param id="jni_env">
        <outptr>
          <struct>JNIEnv</struct>
        </outptr>
          <description>
            The JNI environment of the event (current) thread
          </description>
      </param>
      <param id="flags">
        <jint/>
        <description>
          Flags defining the properties of the of resource exhaustion
          as specified by the
          <internallink id="jvmtiResourceExhaustionFlags">Resource
          Exhaustion Flags</internallink>.
          </description>
        </param>
      <param id="reserved">
        <vmbuf><void/></vmbuf>
        <description>
          Reserved.
        </description>
      </param>
      <param id="description">
        <vmbuf><char/></vmbuf>
        <description>
          Description of the resource exhaustion, encoded as a
          <internallink id="mUTF">modified UTF-8</internallink> string.
        </description>
      </param>
    </parameters>
  </event>

  <event label="VM Object Allocation"
         id="VMObjectAlloc" const="JVMTI_EVENT_VM_OBJECT_ALLOC" num="84">
    <description>
      Sent when a method causes the virtual machine to directly allocate an
      Object visible to Java programming language code.
      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
      <internallink id="jniIntercept">JNI function interception</internallink>.
      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.


/**代码未完, 请加载全部代码(NowJava.com).**/
展开阅读全文

关注时代Java

关注时代Java