home *** CD-ROM | disk | FTP | other *** search
Wrap
Text File | 2000-05-04 | 45.5 KB | 1,210 lines
/*++ Copyright (c) 1997-1998 Microsoft Corporation, All Rights Reserved Module Name: jevmon.idl Abstract: Defines the Java VM event monitor interface. --*/ cpp_quote("//+-------------------------------------------------------------------------") cpp_quote("//") cpp_quote("// Microsoft Virtual Machine for Java(TM) Event Monitor Interfaces") cpp_quote("// Copyright (C) Microsoft Corporation, 1997-1998.") cpp_quote("//") cpp_quote("//--------------------------------------------------------------------------") cpp_quote("") cpp_quote("//") cpp_quote("// Declarations for the Java VM event monitor interface.") cpp_quote("//") cpp_quote("") cpp_quote("#ifndef __JEVMON_H__") cpp_quote("#define __JEVMON_H__") cpp_quote("") #ifndef DO_NO_IMPORTS import "oleidl.idl"; #endif // // Event monitor registration: // // HKEY_LOCAL_MACHINE\Software\Microsoft\Java VM\Monitors\<monitor key name> // default value REG_SZ = "<event monitor description>" // CLSID REG_SZ = "{<event monitor CLSID>}" // // E.g., // // HKEY_LOCAL_MACHINE\Software\Microsoft\Java VM\Monitors\FleaMonitor // default value REG_SZ = "Flea Software's Java Event Monitor version 2.1" // CLSID REG_SZ = "{57339315-CE82-11d0-A329-00C04FB68D0E}" // A unique handle from the Java VM to an event monitor typedef DWORD UniqueID; // A ThreadID uniquely identifies a thread. typedef UniqueID ThreadID; // A StackID uniquely identifies a stack frame. typedef UniqueID StackID; // An ObjectID uniquely identifies an object. typedef UniqueID ObjectID; // An ObjectHandleID uniquely identifies a handle to an object. typedef UniqueID ObjectHandleID; // A MethodID uniquely identifies a method. typedef UniqueID MethodID; // A FieldID uniquely identifies a field. typedef UniqueID FieldID; // A ClassID uniquely identifies a class. typedef UniqueID ClassID; typedef enum jvm_id_type { JVM_ID_FIRST, JVM_ID_THREAD, JVM_ID_STACK, JVM_ID_OBJECT, JVM_ID_OBJECT_HANDLE, JVM_ID_METHOD, JVM_ID_FIELD, JVM_ID_CLASS, JVM_ID_LAST, } JVM_ID_TYPE; // Source code line number information is expressed as an array of SourceLineInfos. typedef struct tagSourceLineInfo { DWORD code_offset; DWORD line_number; } SourceLineInfo; // Interpreted methods are compoosed of BYTE_CODEs. typedef unsigned char BYTE_CODE; // The following environment variables and associated registry settings control // the Java VM's execution state: // // MSJAVA_ENABLE_MONITORS event monitors default off // "EnableEventMonitors" REG_DWORD under "HKEY_CURRENT_USER\Software\Microsoft\Java VM" // // MSJAVA_ENABLE_DEBUGGING debugger default off // "HKEY_LOCAL_MACHINE\Software\Microsoft\Java VM\Debug", or // "HKEY_LOCAL_MACHINE\Software\Microsoft\Java VM\ActiveXDebug" key // // MSJAVA_ENABLE_JIT JIT compiler default on // "EnableJIT" REG_DWORD under "HKEY_CURRENT_USER\Software\Microsoft\Java VM" // // MSJAVA_ENABLE_FI fast interpreter default on // "EnableFI" REG_DWORD under "HKEY_CURRENT_USER\Software\Microsoft\Java VM" // // Set a variable to a non-0 value to enable it, 0 to disable it, or leave it unset // to accept the default setting. Any environment variable setting overrides the // associated registry setting. // Java VM state flags. typedef enum java_state_flags { // Interpreter loop enabled. JVM_STATE_INTERPRETER_ENABLED = 0x0001, // Fast interpreter loop enabled. JVM_STATE_FAST_INTERPRETER_ENABLED = 0x0002, // JIT compiler enabled. JVM_STATE_JIT_COMPILER_ENABLED = 0x0004, // Debugging enabled. JVM_STATE_DEBUGGER_ENABLED = 0x0008, // flag combinations ALL_JVM_FLAGS = (JVM_STATE_INTERPRETER_ENABLED | JVM_STATE_FAST_INTERPRETER_ENABLED | JVM_STATE_JIT_COMPILER_ENABLED | JVM_STATE_DEBUGGER_ENABLED) } JAVA_STATE_FLAGS; // Event monitors can request notification of these event categories. typedef enum java_event_category { JVM_MONITOR_NONE = 0x00000000, JVM_MONITOR_CLASS_LOADS = 0x00000001, JVM_MONITOR_METHOD_CALLS = 0x00000002, JVM_MONITOR_JIT_COMPILATION = 0x00000004, JVM_MONITOR_BYTE_CODE_EXECUTION = 0x00000008, JVM_MONITOR_SOURCE_LINE_EXECUTION = 0x00000010, JVM_MONITOR_EXCEPTIONS = 0x00000020, JVM_MONITOR_MONITOR_OPERATIONS = 0x00000040, JVM_MONITOR_GARBAGE_COLLECTIONS = 0x00000080, JVM_MONITOR_THREADS = 0x00000100, JVM_MONITOR_SAMPLING = 0x00000200, JVM_MONITOR_EXCEPTION_UNWIND = 0x00000400, JVM_MONITOR_SPECIFIC_METHOD_CALLS = 0x00000800, ALL_JVM_MONITOR_EVENTS = (JVM_MONITOR_NONE | JVM_MONITOR_CLASS_LOADS | JVM_MONITOR_METHOD_CALLS | JVM_MONITOR_JIT_COMPILATION | JVM_MONITOR_BYTE_CODE_EXECUTION | JVM_MONITOR_SOURCE_LINE_EXECUTION | JVM_MONITOR_EXCEPTIONS | JVM_MONITOR_MONITOR_OPERATIONS | JVM_MONITOR_GARBAGE_COLLECTIONS | JVM_MONITOR_THREADS | JVM_MONITOR_SAMPLING | JVM_MONITOR_EXCEPTION_UNWIND | JVM_MONITOR_SPECIFIC_METHOD_CALLS) } JAVA_EVENT_CATEGORY; // Options that may be modified during initialization of the monitor. The VM // uses these settings to optimize event monitoring overhead. typedef enum java_monitor_init_options { // The monitor will preserve floating point state during MethodEntry and // MethodExit[2] callbacks. JVM_INIT_OPT_FP_SAFE_METHOD_CALLS = 0x00000001, // The monitor will not enable garbage collection during MethodEntry and // MethodExit[2] callbacks. JVM_INIT_OPT_GC_SAFE_METHOD_CALLS = 0x00000002, // The monitor will not call GetMethodExitReturnValue. JVM_INIT_OPT_RETURN_VALUE_NOT_NEEDED = 0x00000004, // The monitor will not toggle method call events after initialization. JVM_INIT_OPT_WONT_TOGGLE_METHOD_CALL_EVENTS = 0x00000008, ALL_JVM_INIT_OPTIONS = (JVM_INIT_OPT_FP_SAFE_METHOD_CALLS | JVM_INIT_OPT_GC_SAFE_METHOD_CALLS | JVM_INIT_OPT_RETURN_VALUE_NOT_NEEDED | JVM_INIT_OPT_WONT_TOGGLE_METHOD_CALL_EVENTS), } JAVA_MONITOR_INIT_OPTIONS; // Method execution models. typedef enum java_execution_model { // sentinel JVM_EXECUTION_FIRST = -2, JVM_EXECUTION_INVALID, JVM_EXECUTION_JIT_COMPILED, JVM_EXECUTION_NATIVE, JVM_EXECUTION_INTERPRETED, JVM_EXECUTION_FAST_INTERPRETED, JVM_EXECUTION_COM, // sentinel JVM_EXECUTION_LAST } JAVA_EXECUTION_MODEL; // Field flags. typedef enum java_field_flags { JVM_FIELD_STATIC = 0x00000001, JVM_FIELD_OBJECTREF = 0x00000002, ALL_JVM_FIELD_FLAGS = (JVM_FIELD_STATIC|JVM_FIELD_OBJECTREF), } JVM_FIELD_FLAGS; // Object flags. typedef enum java_object_flags { JVM_OBJ_ALREADY_REPORTED = 0x00000001, // Object has already been reported as a reference. JVM_OBJ_ALREADY_VISITED = 0x00000002, // Object has already been visited and will not be traversed. JVM_OBJ_MORE_REFERENCES = 0x00010000, // Additional references from the same object will be reported in subsequent calls. ALL_JVM_OBJECT_FLAGS = (JVM_OBJ_ALREADY_REPORTED|JVM_OBJ_ALREADY_VISITED|JVM_OBJ_MORE_REFERENCES), } JVM_OBJECT_FLAGS; // Special class properties. typedef enum java_class_properties { JVM_CLS_VARIABLE_SIZE = 0x00000001, // Fields may not be present in all instances of the class. JVM_CLS_HAS_DESCRIPTION = 0x00000002, // The object may proxy to or contain internal VM data structures. // 'DescribeObject' may be used to describe the contents of instances. ALL_JVM_CLS_PROPERTIES = (JVM_CLS_VARIABLE_SIZE|JVM_CLS_HAS_DESCRIPTION), } JVM_CLASS_PROPERTIES; typedef enum java_method_sample_accuracy { JVM_SAMPLE_NONE = 0, // A sample could not be obtained. JVM_SAMPLE_POOR = 1, // The sample is not very accurate. JVM_SAMPLE_EXACT = 100, // The sample is 100% accurate. } JVM_METHOD_SAMPLE_ACCURACY; typedef enum java_method_sample_location_type { JVM_LOCATION_UNKNOWN, // The sampled location could not be identified. JVM_LOCATION_JIT, // is in JIT-compiled code. JVM_LOCATION_NATIVE, // is in misc. native code (VM, DLL, OS, etc.). JVM_LOCATION_GC, // is performing a garbage-collection-related task. JVM_LOCATION_COMPILER, // is compiling a method or performing on-first-call tasks for a method. JVM_LOCATION_LOADER, // is performing a VM loader-related task. JVM_LOCATION_DEBUGGER, // is performing a VM debugger-related task. JVM_LOCATION_SECURITY, // is performing a VM security-related task. JVM_LOCATION_PROFILER, // is performing a VM profiling-related task. JVM_LOCATION_BLOCKING, // is in a wait state. JVM_LOCATION_LAST, } JVM_METHOD_SAMPLE_LOCATION_TYPE; typedef enum java_method_sample_flags { JVM_SAMPLE_STACK_ID = 0x00000001, // stack_id is valid JVM_SAMPLE_METHOD_ID = 0x00000002, // method_id is valid JVM_SAMPLE_LOCATION = 0x00000004, // location_type is valid JVM_SAMPLE_GENERATED_CODE = 0x00000008, // the sampled ip was in VM-generated code. if possible, // ip has been filled in with the caller of the generated // code, which may also be generated code. JVM_SAMPLE_PC = 0x00000010, // pc_offset is valid ALL_JVM_SAMPLE_FIELDS = JVM_SAMPLE_STACK_ID | JVM_SAMPLE_METHOD_ID | JVM_SAMPLE_LOCATION | JVM_SAMPLE_PC, ALL_JVM_SAMPLE_FLAGS = ALL_JVM_SAMPLE_FIELDS | JVM_SAMPLE_GENERATED_CODE, } JVM_METHOD_SAMPLE_FLAGS; typedef struct java_method_sample { DWORD flags; // bit mask of flags from JVM_METHOD_SAMPLE_FLAGS, JVM_METHOD_SAMPLE_ACCURACY accuracy; // estimate of the relative accuracy of the information in this struct StackID stack_id; // stack frame for the current location MethodID method_id; // method for which the code is executing JVM_METHOD_SAMPLE_LOCATION_TYPE location_type; // type/activity of code at the location, if known DWORD ip; // instruction pointer at the time of the sample DWORD sp; // stack pointer at the time of the sample DWORD pc_offset; // bytecode offset, if the method is currently interpreted } JVM_METHOD_SAMPLE; typedef enum java_calling_convention { JVM_CALL_FIRST, JVM_CALL_PASCAL, JVM_CALL_CDECL, JVM_CALL_LAST, } JVM_CALLING_CONVENTION; typedef enum java_call_flags { JVM_CALL_THIS = 0x00000001, ALL_JVM_CALL_FLAGS = JVM_CALL_THIS, } JVM_CALL_FLAGS; // Java VM events // These events are passed to IJavaEventMonitor::NotifyEvent(). Notification of // other events occurs through other methods on IJavaEventMonitor or // IJavaEventMonitor2. Each event has an additional information ID associated // with it. // // Certain events may require special synchronization with use of apis that // operate on the event's parameters. For example, a THREAD_DESTROYED event // may be sent before another thread gets to use ThreadInformation. The VM // does not check that the id has been destroyed. Profilers should take care // to synchronize the destruction events with their uses by ensuring that // the last use of the id occurs before returning from handling the destruction // event. Events/ids that need to be synchronized: // THREAD_DESTROYED: ThreadID // CLASS_UNLOADED: ClassID, MethodIDs for members of the unloaded ClassID typedef enum tagJVM_EVENT_TYPE { // sentinel JVM_EVENT_TYPE_FIRST = -1, // execution JVM_EVENT_TYPE_EXCEPTION_OCCURRED = 0, // An exception occurred. The exception handler will be executed in StackID's stack frame. // object monitors JVM_EVENT_TYPE_MONITOR_BLOCKED = 1, // NOT IMPLEMENTED: The current thread blocked while trying to acquire object ObjectID's monitor. JVM_EVENT_TYPE_MONITOR_ACQUIRING = 2, // The current thread is about to try to acquire object ObjectID's monitor. JVM_EVENT_TYPE_MONITOR_ACQUIRED = 16, // The current thread acquired object ObjectID's monitor. JVM_EVENT_TYPE_MONITOR_RELEASED = 3, // The current thread released object ObjectID's monitor. // threads JVM_EVENT_TYPE_THREAD_CREATE = 4, // Java thread ThreadID is being created. JVM_EVENT_TYPE_THREAD_DESTROY = 5, // Java thread ThreadID is being destroyed. // classes JVM_EVENT_TYPE_CLASS_LOAD_STARTED = 6, // A class is starting to be loaded. ID is pointer to UTF8 string name of class. JVM_EVENT_TYPE_CLASS_LOAD_FINISHED = 7, // Class ClassID is finished being loaded. JVM_EVENT_TYPE_CLASS_LOAD_FAILED = 17, // A class load failed. ID is pointer to UTF8 string name of class. JVM_EVENT_TYPE_CLASS_UNLOAD = 8, // Class ClassID is being unloaded. // JIT compiler JVM_EVENT_TYPE_JIT_COMPILE_STARTED = 9, // The JIT compiler is starting to compile method MethodID. JVM_EVENT_TYPE_JIT_COMPILE_FINISHED = 10, // The JIT compiler is finished compiling method MethodID. JVM_EVENT_TYPE_JIT_COMPILE_FAILED = 18, // The JIT compiler failed to compile method MethodID. // garbage collection JVM_EVENT_TYPE_GC_STARTED = 11, // Garbage collection is starting (ID undefined). JVM_EVENT_TYPE_GC_FINISHED = 12, // Garbage collection is finished (ID undefined). // shutdown JVM_EVENT_TYPE_SHUTDOWN = 13, // The program is exiting (ID undefined). // reserved JVM_EVENT_TYPE_RESERVED_14 = 14, // Deprecated. Formerly JVM_EVENT_TYPE_SHUTDOWN_ERROR. No longer dispatched. JVM_EVENT_TYPE_RESERVED_15 = 15, // Deprecated. Formerly JVM_EVENT_TYPE_SHUTDOWN_INTERRUPTED. No longer dispatched. JVM_EVENT_TYPE_RESERVED_16 = 16, // Used as JVM_EVENT_TYPE_MONITOR_ACQUIRED above. JVM_EVENT_TYPE_RESERVED_17 = 17, // Used as JVM_EVENT_TYPE_CLASS_LOAD_FAILED above. JVM_EVENT_TYPE_RESERVED_18 = 18, // Used as JVM_EVENT_TYPE_JIT_COMPILE_FAILED above. // sentinel JVM_EVENT_TYPE_LAST } JVM_EVENT_TYPE; // These events are passed to IJavaEventMonitor2::NotifyEvent2(). Notification // of other events occurs through other methods on IJavaEventMonitor or // IJavaEventMonitor2. Each event has two additional information IDs // associated with it. typedef enum tagJVM_EVENT_TYPE2 { // sentinel JVM_EVENT_TYPE2_FIRST = 1024, // threads JVM_EVENT_TYPE2_THREAD_SET_NAME, // A thread's name has been set. ID1 is ThreadID. ID2 is pointer to Unicode string thread name. // execution JVM_EVENT_TYPE2_EXCEPTION_OCCURRED, // An exception occurred. ID1 is MethodID, ID2 is StackID. The exception handler will be executed in MethodID/StackID's stack frame. JVM_EVENT_TYPE2_EXCEPTION_THROWN, // An exception is about to be thrown. ID1 is the ClassID of the exception, ID2 is the ObjectID of the exception. JVM_EVENT_TYPE2_EXCEPTION_UNWIND, // An exception is being thrown past this frame. ID1 is MethodID, ID2 is StackID. // stack trace JVM_EVENT_TYPE2_STACK_TRACE, // Callback from GetStackTrace. ID1 is MethodID, ID2 is StackID. // initialization JVM_EVENT_TYPE2_INITIALIZED, // The vm has fully initialized. JVM_EVENT_TYPE2_MONITORS_INITIALIZED, // All event monitors have initialized. Returning a failed // HRESULT from NotifyEvent2 will detach the monitor from the VM, and // no more events will be sent to the monitor. ID1 is the number of // event monitors attached to the VM. ID2 is a bitmask of // JAVA_EVENT_CATEGORY, indicating the maximum possible set of events // that may be enabled by all attached profilers. // sentinel JVM_EVENT_TYPE2_LAST } JVM_EVENT_TYPE2; // The Java VM implements IEventMonitorInfo. The Java VM passes an IEventMonitorInfo // to each event monitor during initialization. The event monitor should AddRef() // the IJavaEventMonitorInfo interface. Given an ID, an event monitor can call // back on IEventMonitorInfo to get information about the method, thread, object, // class, etc., associated with the ID. The IEventMonitorInfo methods must be // called on the same thread that the ID was supplied on. // // Return S_OK on success, or E_FAIL on failure. // // If non-NULL, the [out] buffer parameters are filled with pointers to buffers // created with CoTaskMemAlloc(). The callee must free them via CoTaskMemFree(). // IJavaEventMonitorIDInfo interface cpp_quote("DEFINE_GUID(IID_IJavaEventMonitorIDInfo, 0xa57d3f40, 0x8b8a, 0x11d0, 0x93, 0x81, 0x0, 0xa0, 0xc9, 0xa, 0x8f, 0xbe);") [ object, uuid(A57D3F40-8B8A-11d0-9381-00A0C90A8FBE), helpstring("IJavaEventMonitorIDInfo interface"), pointer_default(unique) ] interface IJavaEventMonitorIDInfo : IUnknown { // Set the event notifications requested. HRESULT SetEventMask( [in] DWORD events); // bit mask of flags from JAVA_EVENT_CATEGORY // Get the event notifications requested. HRESULT GetEventMask( [in] DWORD *pevents); // bit mask of flags from JAVA_EVENT_CATEGORY // Describe a method. HRESULT MethodInformation( [in] MethodID method_id, [out] LPSTR *ppmethod_name, [out] ClassID *pclass_id, [out] JAVA_EXECUTION_MODEL *pexec, [out] int *psource_line_info_length, [out] SourceLineInfo **ppsource_line_info); // Describe an interpreted method. HRESULT InterpretedMethodInformation( [in] MethodID method_id, [out] unsigned int *pbyte_code_length, [out] BYTE_CODE **ppbyte_codes); // Describe a JIT-compiled method. HRESULT JITCompiledMethodInformation( [in] MethodID method_id, [out] unsigned int *pjit_code_length, [out] unsigned char **ppjit_code); // Describe a class. HRESULT ClassInformation( [in] ClassID class_id, [out] LPSTR *ppclass_name, [out] LPSTR *ppsource_file_name, [out] int *pmethods, [out] MethodID **ppmethod_ids, [out] __int64 *pobjects_created); // Describe an object. HRESULT ObjectInformation( [in] ObjectID objectID, [out] ClassID *pclass_id); // Get the number of object monitors that have been used. HRESULT GetMonitorUsage( [out] __int64 *pmonitors_used); } // IJavaEventMonitorIDInfo2 interface cpp_quote("DEFINE_GUID(IID_IJavaEventMonitorIDInfo2, 0x25ef5e75, 0x5b53, 0x11d1, 0xa3, 0x89, 0x0, 0xc0, 0x4f, 0xb6, 0x8d, 0xe);") [ object, uuid(25EF5E75-5B53-11d1-A389-00C04FB68D0E), helpstring("IJavaEventMonitorIDInfo2 interface"), pointer_default(unique) ] interface IJavaEventMonitorIDInfo2 : IJavaEventMonitorIDInfo { // Describe a thread. HRESULT ThreadInformation( [in] ThreadID threadID, [out] DWORD *pWin32ThreadID); // Static class information. HRESULT StaticClassInformation( [in] ClassID class_id, [out] DWORD *pStaticDataSize, [out] DWORD *pInstanceSize); // Obtains class path. HRESULT GetClassPath( [out] LPSTR *ppszClassPath); // Get object size. HRESULT GetObjectSize( [in] ObjectID objectID, [out] DWORD *pSize); // Profiling capabilities. HRESULT GetProfilingCapabilities( [out] DWORD *pStates, // bit mask of flags from JAVA_STATE_FLAGS [out] DWORD *pCategories, // bit mask of flags from JAVA_EVENT_CATEGORY [out] JAVA_EXECUTION_MODEL *pLastModel, [out] JVM_EVENT_TYPE *pLastType, [out] JVM_EVENT_TYPE2 *pLastType2); // Describes fields of a class. The fields are ordered in memory // layout - not necessarily the order they are declared. HRESULT GetClassFields( [in] ClassID class_id, [out] unsigned *pnfields, [out] FieldID **pfield_ids); HRESULT FieldInformation( [in] FieldID id, [out] LPSTR *pname, [out] DWORD *pflags); // bit mask of flags from JVM_FIELD_FLAGS // Obatins the current thread. HRESULT GetCurrentThread( [out] ThreadID *pcurrent_thread_id); // Obtains a stack trace for the specified thread. Frames are enumerated // from lowest to highest through NotifyEvent2 with JVM_EVENT_TYPE2_STACK_TRACE. // The thread will be temporarily suspended - no other events will be sent // for this thread for the duration of this method. // The NotifyEvent2 callback should return S_OK to continue enumerating stack frames. // // thread_id may be NULL to indicate the current thread. // // Returns E_FAIL if the thread is not in a state in which a stack trace can be obtained. // Otherwise, returns the result of the last NotifyEvent2 callback, or S_OK if // the stack was empty or all callbacks return S_OK. HRESULT GetStackTrace( [in] ThreadID thread_id); // Samples the current method for the given thread. If the method is not // known, a "guess" (a recent caller, nearest native caller, etc.) may be // returned, along with an estimate of the accuracy. A precise sample may // always be obtained using GetStackTrace; however, it is slower and may // require code to be executed before reporting stack frames. // JVM_MONITOR_SAMPLING is not required, but will improve the ability to // provide accurate samples at the expense of some overhead on non-jit // method calls. HRESULT SampleThreadLocation( [in] ThreadID thread_id, [in,out] JVM_METHOD_SAMPLE *psample); // Obtains a list of classes that have special properties. HRESULT GetSpecialClassProperties( [out] unsigned *pnspecial_classes, [out] ClassID **ppclass_ids, [out] DWORD **ppclass_flags); // mask of JVM_CLASS_PROPERTIES for each class // Obtains a description of a special object that contains vm-dependent // fields. A list of objects supported by this function may be obtained // through GetSpecialClassProperties - this function works on any class // with JVM_CLS_HAS_DESCRIPTION. ex. for a java/lang/Class instance, this // returns the class's name. HRESULT DescribeObject( [in] ObjectID object_id, [out] LPWSTR *pdescr); // Obtains the value of a field from an object. // For references fields, *pvalue will be an ObjectID. Otherwise, *pvalue // is the value of the field. HRESULT GetObjectField( [in] ObjectID object_id, [in] FieldID field_id, [out] __int64 *pvalue); // Obtains the value of an array element. index is 0-based. // For arrays of objects, *pvalue will be an ObjectID. Otherwise, *pvalue // is the value of the element. HRESULT GetArrayElement( [in] ObjectID object_id, [in] unsigned index, [out] __int64 *pvalue); // Obtains persistent handles to objects. The handles are valid across // garbage collections and may be converted to their current ObjectIDs // to allow tracking of specific objects. Owning a handle to an object // will not prevent the object from being garbage collected. HRESULT GetHandlesToObjects( [in] unsigned nobjects, [in] ObjectID *pobject_ids, [in,out] ObjectHandleID *pobject_handles); HRESULT FreeHandlesToObjects( [in] unsigned nhandles, [in] ObjectHandleID *pobject_handles); // Obtains the current ObjectIDs for a list of ObjectHandleIDs. Objects // that have been collected will have a NULL ObjectID, the handle will be // automatically freed, and the handle be set to NULL. HRESULT GetObjectsFromHandles( [in] unsigned nhandles, [in,out] ObjectHandleID *pobject_handles, [in,out] ObjectID *pobject_ids); } typedef enum method_call_events_disposition { JVM_PROHIBIT_METHOD_CALL_EVENTS = 1, JVM_PERMIT_METHOD_CALL_EVENTS = 2, JVM_QUERY_DISPOSITION = 3, } JVM_METHOD_CALL_EVENTS_DISPOSITION; // IJavaEventMonitorIDInfo3 interface cpp_quote("DEFINE_GUID(IID_IJavaEventMonitorIDInfo3, 0x5be7cd50, 0xe3eb, 0x11d1, 0xb0, 0x42, 0x0, 0x60, 0x8, 0x3, 0x9b, 0xf0);") [ object, uuid(5BE7CD50-E3EB-11d1-B042-006008039BF0), helpstring("IJavaEventMonitorIDInfo3 interface"), pointer_default(unique) ] interface IJavaEventMonitorIDInfo3 : IJavaEventMonitorIDInfo2 { // Turns method call events (MethodEnter/MethodExit/MethodExit2 calls) on // or off for a specific method. The final determination to hook a method // is as follows: // // - if any profiler has requested that a specific method *not* be hooked // by specifying JVM_PROHIBIT_METHOD_CALL_EVENTS, no profilers will // receive callbacks for the method. The decision by a profiler to not // hook a method is irreversible. This is intended for use by a profiler // to disable hooking of methods that are required to execute unobstructed // for the proper functioning of the profiler (ex. a profiler that has // Java-implemented methods that are invoked in response to a method call // event). // // - if any profiler may possibly enable JVM_MONITOR_METHOD_CALLS, then all // methods (except those specifically forbidden above) will be hooked. // Any profiler that has requested JVM_MONITOR_METHOD_CALLS or // JVM_MONITOR_SPECIFIC_METHOD_CALLS will receive method call events for // the method. // // - if any profiler turns on method call events for a specific set of // methods by specifying JVM_PERMIT_METHOD_CALL_EVENTS, all profilers that // have requested JVM_MONITOR_SPECIFIC_METHOD_CALLS will receive the events // for the methods. This means that if one profiler requests events for a // specific method, all profilers will receive the events. // // A profiler should *not* use JVM_PROHIBIT_METHOD_CALL_EVENTS to // selectively disable method call events for a method. Instead, request // that no methods be hooked and then enable hooking for those that are // interesting, i.e. implement IJavaEventMonitorIDInfo2, do not return // JVM_MONITOR_METHOD_CALLS from GetPossibleEventCategories, enable // JVM_MONITOR_CLASS_LOADS, and at each JVM_EVENT_TYPE_CLASS_LOAD_FINISHED // event, use JVM_PERMIT_METHOD_CALL_EVENTS to enable hooking for the // methods that are interesting. // // Currently, this function will fail if the method has already been // executed; it should be called during the class load event for the // method's class. // // If 'idtype' is JVM_ID_METHOD, 'id' should be a MethodID. Returns S_OK // if the method will be hooked, S_FALSE if not, or E_FAIL if the method is // already running, hooking does not apply to the method, or hooking cannot // be disabled for the method. // // If 'idtype' is JVM_ID_CLASS, 'id' should be a ClassID - this is the // same as enumerating all of the MethodIDs of a class and invoking this // function on each. In this case, the function returns S_OK if all of // the methods will be hooked, S_FALSE if any of them will not or cannot // be hooked, or E_FAIL if none of them can be hooked. // // JVM_QUERY_DISPOSITION may be specified to determine the hook status of // a method. HRESULT EnableMethodCallEvents( [in] UniqueID id, [in] JVM_ID_TYPE idtype, [in] JVM_METHOD_CALL_EVENTS_DISPOSITION Disposition); // Obtains a pointer to the base of the parameters passed to the current // method. This function should only be called during a MethodEntry // callback. HRESULT GetMethodEntryParameters( [out] DWORD **pslots, [out] DWORD **preserved, [out] JVM_CALLING_CONVENTION *pcalling_convention, [out] DWORD *pflags); // bitmask of JVM_CALL_FLAGS // Obtains a pointer to the method return value for the method that just // returned. This function should only be called during a // MethodExit/MethodExit2 callback. HRESULT GetMethodExitReturnValue( [out] MethodID *preturning_method_id, [out] __int64 **pret_value); // Obtains more information about a class: the superclass, interfaces, and // all methods implemented by the class, including those inherited from // superclasses but not those overridden in superclasses. // // An interface may appear in the returned interface list more than once. // Base interfaces of explicitly implemented interfaces will be in the // list, i.e. it is not necessary to call ClassInformation2 again for each // listed interface. // // The list of methods includes the contents of the vtable plus all static // and non-virtual methods. The list of methods will include any private // methods of superclasses or other methods that may not be accessible // through the given class. Methods may be in the list more than once, and // if the class is abstract, abstract methods may also be listed. HRESULT ClassInformation2( [in] ClassID class_id, [out] ClassID *psuperclass, // ClassID of superclass, or NULL for java/lang/Object [out] ClassID **pinterfaces, // ClassIDs of implemented interfaces [out] unsigned *pinterfaces_length, [out] MethodID **pimplemented_methods, // MethodIDs of all implemented methods, including those inherited [out] unsigned *pimplemented_methods_length); } // IJavaEventMonitorIDInfo4 interface cpp_quote("DEFINE_GUID(IID_IJavaEventMonitorIDInfo4, 0x5a183bd0, 0x4f46, 0x11d2, 0xb0, 0x64, 0x0, 0x60, 0x8, 0x3, 0x9b, 0xf0);") [ object, uuid(5A183BD0-4F46-11d2-B064-006008039BF0), helpstring("IJavaEventMonitorIDInfo4 interface"), pointer_default(unique) ] interface IJavaEventMonitorIDInfo4 : IJavaEventMonitorIDInfo3 { // Retrieves the per-monitor initialization options that were set through // SetMonitorInitializationOptions. After all monitors have been // initialized, GetFinalInitializationOptions may be used to retrieve the // options that were actually used to initialize profiling support. HRESULT GetMonitorInitializationOptions ( [out] DWORD *pflags); // bitmask of JAVA_MONITOR_INIT_OPTIONS // Sets the initialization options requested by this monitor. This method // will fail after all monitors have been initialized, which is indicated // by receipt of JVM_EVENT_TYPE2_MONITORS_INITIALIZED. Event monitors may // call GetFinalInitializationOptions when // JVM_EVENT_TYPE2_MONITORS_INITIALIZED is received to check which options // were enabled. HRESULT SetMonitorInitializationOptions ( [in] DWORD flags); // bitmask of JAVA_MONITOR_INIT_OPTIONS // Retrives the final options used to initialize profiling support. This // method will fail before all monitors have been initialized, which is // indicated by receipt of JVM_EVENT_TYPE2_MONITORS_INITIALIZED. HRESULT GetFinalInitializationOptions ( [out] DWORD *pflags); // bitmask of JAVA_MONITOR_INIT_OPTIONS } // Each event monitor implements IJavaEventMonitor. The Java VM calls methods // on IJavaEventMonitor to notify the event monitor of events that occur during // Java VM execution. // // Return S_OK on success, or E_FAIL on failure. // IJavaEventMonitor interface cpp_quote("DEFINE_GUID(IID_IJavaEventMonitor, 0xa57d3f41, 0x8b8a, 0x11d0, 0x93, 0x81, 0x0, 0xa0, 0xc9, 0xa, 0x8f, 0xbe);") [ object, uuid(A57D3F41-8B8A-11d0-9381-00A0C90A8FBE), helpstring("IJavaEventMonitor interface"), pointer_default(unique) ] interface IJavaEventMonitor : IUnknown { // Initialize an event monitor. HRESULT Initialize( [in] LPCSTR pclass_file_name, [in] IJavaEventMonitorIDInfo *pmonitor_info, [in] DWORD java_flags, // bit mask of flags from JAVA_STATE_FLAGS [out] DWORD *prequested_events); // bit mask of events from JAVA_EVENT_CATEGORY // An event from JVM_EVENT_TYPE is about to occur. HRESULT NotifyEvent( [in] JVM_EVENT_TYPE event, [in] UniqueID event_id); // A method is about to be entered. HRESULT MethodEntry( [in] MethodID method_id, [in] StackID stack_id); // A method is about to be exited. HRESULT MethodExit( [in] StackID stack_id); // The execution of a bytecode instruction is about to occur. HRESULT ExecuteByteCode( [in] MethodID method_id, [in] BYTE_CODE *pbyte_code, [in] DWORD byte_code_offset); // The execution of a source line is about to occur. HRESULT ExecuteSourceLine( [in] MethodID method_id, [in] DWORD line_number); } // Each event monitor may implement IJavaEventMonitor2. The Java VM calls // methods on IJavaEventMonitor2 to notify the event monitor of events that // occur during Java VM execution. // // Return S_OK on success, or E_FAIL on failure. // IJavaEventMonitor2 interface cpp_quote("DEFINE_GUID(IID_IJavaEventMonitor2, 0x20f66f6f, 0x5b32, 0x11d1, 0xa3, 0x89, 0x0, 0xc0, 0x4f, 0xb6, 0x8d, 0xe);") [ object, uuid(20F66F6F-5B32-11d1-A389-00C04FB68D0E), helpstring("IJavaEventMonitor2 interface"), pointer_default(unique) ] interface IJavaEventMonitor2 : IJavaEventMonitor { // An event from JVM_EVENT_TYPE2 is about to occur. HRESULT NotifyEvent2( [in] JVM_EVENT_TYPE2 event2, [in] UniqueID first_event_id, [in] UniqueID second_event_id); // A method is about to be exited. HRESULT MethodExit2( [in] MethodID method_id, [in] StackID stack_id); // Obtains the maximal set of event categories that will ever be enabled. // This information is used to eliminate profiling overhead for callbacks // that will never be requested. HRESULT GetPossibleEventCategories( [out] DWORD *ppossible_events); // bit mask of events from JAVA_EVENT_CATEGORY } // G C H E A P M O N I T O R I N T E R F A C E S // // The heap monitoring API's allow one to get the following: // - notification on each object allocation // - heap dump (right after a GC) // // The Heap Dump will first dump all roots. The roots are // labeled with C_RT_XXXXXX. After all roots are dumped, // any remaining heap contents are dumped as C_HEAP. // C O N T A I N E R S // // The notion of a container is used when passing heap information // to the monitor. This way the monitor can completely rebuild // all containment hierarchy within the roots. // // Stack frame types are always subcontainers of a THREAD container, and are // reported bottom-up. Other types are top-level containers. // // THREAD containers may be reported multiple times. The same frames // may not be reported both times, but equal ids in both reports can // be assumed to be the same frames, and frames may be ordered by // their id values. typedef enum container_type { C_FIRST, C_BEGIN, // Dummy container noting the start of heap enumeration. C_RT_THREAD, // Roots for thread // id1=ThreadID C_RT_JIT, // Live Pointers in JIT'd methods // id1=StackID, id2=MethodID C_RT_NATIVE, // Native Frame // id1=StackID, id2=MethodID C_RT_NATIVEGC, // Native GC Frame // id1=StackID C_RT_COM, // COM Frame // id1=StackID, id2=MethodID C_RT_INTERPRETED, // Interpreted Method Frame // id1=StackID, id2=MethodID C_RT_FASTINTERPRETED, // Fast Interpreted Method Frame // id1=StackID, id2=MethodID C_RT_INTERNALFRAME, // Internal VM Frame // id1=StackID C_RT_INTERNALVM, // Internal VM Object C_RT_CLASS, // Static class references // id1=ClassID C_RT_ROOTTABLE, // Misc. roots C_RT_STRONGPTR, // Strong ptr C_FINALIZED, // Objects awaiting finalization C_HEAP, // Remaining portions of the heap not reported in the above C_END, // Dummy container noting the end of heap enumeration. C_LAST, } CONTAINER_TYPE; // // I H e a p I n f o C a l l b a c k // // Callback interface implemented by tool for heap dumping. cpp_quote("DEFINE_GUID(IID_IHeapInfoCallback, 0x81a26182, 0x439f, 0x11d1, 0xb1, 0x4a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0);") [ object, uuid(81A26182-439F-11d1-B14A-000000000000), helpstring("IHeapInfo Interface"), pointer_default(unique) ] interface IHeapInfoCallback : IUnknown { HRESULT BeginContainer( [in] CONTAINER_TYPE type, [in] UniqueID id1, [in] UniqueID id2); // // RootReferences: reports references from the current container. // ObjectReferences: reports an object and the object's references. // // Each reference will be traversed in a depth-first fashion. A parallel // array indicates objects that have been seen before that will not be // traversed. This identifies recursive structures and objects with // multiple references. If an object has a reference to itself, the // reference will be reported as visited. // // All references in an object will be reported before descending. If // all references cannot be reported in a single call, // JVM_OBJ_MORE_REFERENCES will be set for the object. // // References not reported during root traversal are reported later // within the C_HEAP container. // // Each reference corresponds to a field, in the same order obtained // from GetClassFields, so 'null' references are reported. Note that // only fields with JVM_FIELD_OBJECTREF and without JVM_FIELD_STATIC // are relevant. Note that for some objects (ex. java/lang/String), // the number of references reported may not match the number of fields. // // Clients can obtain a flat list of objects by always returning // S_POSTPONE_REFERENCES. // // Result codes: // FAILED(): stop heap enumeration completely // S_POSTPONE_REFERENCES && !(flags & JVM_OBJ_MORE_REFERENCES): // do not descend references - report them independently in C_HEAP. // Only respected on the final reference dump for an object, e.g. // JVM_OBJ_MORE_REFERENCES is not set in 'flags'. // else SUCCEEDED(): continue/descend all references from this object // HRESULT RootReferences( [in] const ObjectID *prefs, // references within this root [in] unsigned nrefs, // number of references being reported [in] const DWORD *pflags); // JVM_OBJECT_FLAGS for each reference HRESULT ObjectReferences( [in] ObjectID id, // object being reported [in] DWORD flags, // JVM_OBJECT_FLAGS for the object [in] const ObjectID *prefs, // references within this object [in] unsigned nrefs, // number of references being reported [in] const DWORD *pflags); // JVM_OBJECT_FLAGS for each reference }; // Postpone reporting references to C_HEAP. cpp_quote("static const int S_POSTPONE_REFERENCES = MAKE_HRESULT(0, FACILITY_ITF, 0x01);") // // I O b j e c t A l l o c a t i o n C a l l b a c k // // Callback interface implemented by tool for notification on object allocation. cpp_quote("DEFINE_GUID(IID_IObjectAllocationCallback, 0x76514ea2, 0x33f4, 0x11d1, 0xa4, 0xa3, 0x0, 0xa0, 0xc9, 0xa, 0xeb, 0x5d);") [ object, uuid(76514EA2-33F4-11d1-A4A3-00A0C90AEB5D), helpstring("IObjectAllocationCallback Interface"), pointer_default(unique) ] interface IObjectAllocationCallback : IUnknown { // Return S_OK. HRESULT OnObjectAllocated( [in] ObjectID oid, [in] ClassID type); }; typedef enum tagJVM_HEAPMON_CAPABILITIES { // Requests that the vm track the age of each object where possible. // Must be enabled/disabled during the event monitor's Initialize. JVM_HEAPMON_OBJECT_AGE = 0x00000001, ALL_JVM_HEAPMON_CAPABILITIES = JVM_HEAPMON_OBJECT_AGE, } JVM_HEAPMON_CAPABILITIES; // // I J a v a H e a p M o n i t o r // // Heap Monitor interface implemented by Java VM // cpp_quote("DEFINE_GUID(IID_IJavaHeapMonitor, 0x81a26183, 0x439f, 0x11d1, 0xb1, 0x4a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0);") [ object, uuid(81A26183-439F-11d1-B14A-000000000000), helpstring("IJavaHeapMonitor Interface"), pointer_default(unique) ] interface IJavaHeapMonitor : IUnknown { // Registers a heap callback. The heap is dumped at the end of each gc. // A monitor may only have one callback installed at a time. If // pihicb == NULL, the callback is revoked. HRESULT GetHeapInfo( [in] IHeapInfoCallback *pihicb); // Registers an object allocation callback. // A monitor may only have one callback installed at a time. If // pioacb == NULL, the callback is revoked. HRESULT NotifyOnObjectAllocations( [in] IObjectAllocationCallback *pioacb); // Obtains descriptions of the given container type. HRESULT GetContainerDescription( [in] CONTAINER_TYPE type, [out] LPWSTR *pshort, [out] LPWSTR *plong); // Requests that specific heap monitor functionality be enabled or // disabled. Certain capabilities may have specific times during // which they may be enabled or disabled. HRESULT ModifyHeapMonitorCapabilities( [in] DWORD capabilities, // mask of JVM_HEAPMON_CAPABILITIES [in] BOOL fenable, // TRUE to enable capabilities, FALSE to disable [out] DWORD *penabled_capabilities); // mask of JVM_HEAPMON_CAPABILITIES // Obtains the number of collections an object has survived. HRESULT GetObjectAge( [in] ObjectID object_id, [out] DWORD *pncollections_survived); }; typedef enum tagJVM_WALKHEAP_FLAGS { // Do not enumerate through roots. No BeginContainer or RootReferences // calls will be received. JVM_WALKHEAP_NO_ROOTS = 0x00000001, } JVM_WALKHEAP_FLAGS; cpp_quote("DEFINE_GUID(IID_IJavaHeapMonitor2, 0x86e81530, 0x5dd8, 0x11d2, 0xb0, 0x67, 0x0, 0x60, 0x8, 0x3, 0x9b, 0xf0);") [ object, uuid(86E81530-5DD8-11d2-B067-006008039BF0), helpstring("IJavaHeapMonitor2 Interface"), pointer_default(unique) ] interface IJavaHeapMonitor2 : IJavaHeapMonitor { // Initiates a heap dump. This method may only be called from the // profiler's BeginContainer callback when C_END is received. This method // will return E_FAIL if called from a different thread or at any other // time. ObjectIDs from the previous heap dump will remain valid across // the new heap dump. // // Unlike passive heap callbacks, C_BEGIN and C_END notifications will not // be received. (They convey no useful information, since the caller is // initiating the dump.) HRESULT WalkHeap( [in] IHeapInfoCallback *pihicb, [in] DWORD flags); // mask of JVM_WALKHEAP_FLAGS }; cpp_quote("") cpp_quote("#endif // __JEVMON_H__") cpp_quote("")