/*
* Copyright (c) 2012, 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.
*/
package com.sun.max.vm.ext.jvmti;
import static com.sun.max.vm.ext.jvmti.JVMTICapabilities.E.*;
import java.security.*;
import java.util.*;
import com.sun.max.unsafe.*;
import com.sun.max.vm.actor.holder.*;
import com.sun.max.vm.actor.member.*;
/**
/**
* A functionally equivalent <A href="http://docs.oracle.com/javase/6/docs/platform/jvmti/jvmti.html">JVMTI</a> interface
* but cast in terms of Maxine Java types that can be called from agents written in Java (for Maxine).
*
* Some of the JVMTI functions are redundant in that they essentially replicate existing functionality in the JDK,
* however, we include them for completeness.
*
* A few of the JVMTI functions don't have a Java equivalent, and these are omitted. Raw monitors are
* unnecessary as agents can use standard Java synchronization mechanisms. The functions for environment
* local storage and thread local storage are omitted as these can easily be handled directly by the agent.
*
* Whereas native JVMTI returns errors as the function result, {@link JJVMTI} throws a {@link JJVMTIException}.
*
* Classes, fields and methods are denoted using the Maxine {@link Actor} classes. The other choice would have been to use
* the types defined in the standard reflection package. The native JVMTI API uses JNI handles for Class instances and
* scalar values for field and method instances, the latter corresponding to Maxine's {@link MemberID} class.
* One reason for not using the standard reflection types is that a {@link Method} instance cannot represent a, {@code <init>}
* method, which is represented with {@link Constructor}, whereas Maxine's {@link MethodActor} can represent all method instances
* uniformly. In contrast, the API uses {@link Thread} over Maxine's {@link VmThread}, as there is no compelling reason to choose
* the latter. Conversion between the Maxine types and platform types is, if necessary, straightforward using the {@code fromJava}
* and {@code toJava} methods.
*/
public interface JJVMTI {
/**
* JVMTI errors. Whereas native JVMTI indicates errors by a return code, Java JVMTI uses an exception with the error
* code as argument. Since errors are rare this is a {@link RuntimeException}.
*/
public static class JJVMTIException extends RuntimeException {
public final int error;
public JJVMTIException(int error) {
super();
this.error = error;
}
@Override
public String toString() {
return getClass().getName() + ": " + Integer.toString(error);
}
}
/**
* See <a href="http://docs.oracle.com/javase/6/docs/platform/jvmti/jvmti.html#jvmtiFrameInfo">jvmtiFrameInfo</a>.
*/
public static class FrameInfo {
public int location;
public MethodActor method;
public FrameInfo() {
}
public FrameInfo(MethodActor method, int location) {
this.method = method;
this.location = location;
}
}
/**
* See <a href="http://docs.oracle.com/javase/6/docs/platform/jvmti/jvmti.html#jvmtiStackInfo">jvmtiStackInfo</a>.
*/
public static class StackInfo {
public Thread thread;
public int state;
public FrameInfo[] frameInfo;
public int frameCount;
public StackInfo() {
}
public StackInfo(Thread thread, int state, FrameInfo[] frameInfo, int frameCount) {
this.thread = thread;
this.state = state;
this.frameInfo = frameInfo;
this.frameCount = frameCount;
}
}
/**
* See <a href="http://docs.oracle.com/javase/6/docs/platform/jvmti/jvmti.html#GetMethodLocation">GetMethodLocation</a>.
*/
public static class MethodLocation {
public final int start;
public final int end;
public MethodLocation(int start, int end) {
this.start = start;
this.end = end;
}
}
/**
* See <a href="http://docs.oracle.com/javase/6/docs/platform/jvmti/jvmti.html#jvmtiLineNumberEntry">jvmtiLineNumberEntry</a>.
*/
public static class LineNumberEntry {
public final int bci;
public final int lineNumber;
public LineNumberEntry(int bci, int lineNumber) {
this.bci = bci;
this.lineNumber = lineNumber;
}
}
/**
* See <a href="http://docs.oracle.com/javase/6/docs/platform/jvmti/jvmti.html#jvmtiLocalVariableEntry">jvmtiLocalVariableEntry</a>.
*/
public static class LocalVariableEntry {
public final long location;
public final int length;
public final String name;
public final String signature;
public final String genericSignature;
public final int slot;
public LocalVariableEntry(long location, int length, String name, String signature, String genericSignature, int slot) {
this.location = location;
this.length = length;
this.name = name;
this.signature = signature;
this.genericSignature = genericSignature;
this.slot = slot;
}
}
public static class ClassDefinition {
public final ClassActor klass;
public final byte[] classBytes;
public ClassDefinition(ClassActor klass, byte[] classBytes) {
this.klass = klass;
this.classBytes = classBytes;
}
}
public static class ClassVersionInfo {
public final int major;
public final int minor;
public ClassVersionInfo(int major, int minor) {
this.major = major;
this.minor = minor;
}
}
public static class ObjectMonitorUsage {
// TODO
}
public static class MonitorStackDepthInfo {
public final Object monitor;
public final int stackDepth;
MonitorStackDepthInfo(Object monitor, int stackDepth) {
this.monitor = monitor;
this.stackDepth = stackDepth;
}
}
public static class AddrLocation {
Address startAddress;
long location;
}
/**
* See <a href="http://docs.oracle.com/javase/6/docs/platform/jvmti/jvmti.html#jvmtiThreadInfo">jvmtiThreadInfo</a>
* Somewhat redundant but for completeness cf native JVMTI.
*/
public static class ThreadInfo {
public final String name;
public final int priority;
public final boolean isDaemon;
public final ThreadGroup threadGroup;
public final ClassLoader contextClassLoader;
ThreadInfo(String name, int priority, boolean isDaemon, ThreadGroup threadGroup, ClassLoader contextClassLoader) {
this.name = name;
this.priority = priority;
this.isDaemon = isDaemon;
this.threadGroup = threadGroup;
this.contextClassLoader = contextClassLoader;
}
}
/**
* See <a href="http://docs.oracle.com/javase/6/docs/platform/jvmti/jvmti.html#jvmtiThreadGroupInfo">jvmtiThreadGroupInfo</a>
* Somewhat redundant but for completeness cf native JVMTI.
*/
public static class ThreadGroupInfo {
public final ThreadGroup parent;
public final String name;
public final int maxPriority;
public final boolean isDaemon;
ThreadGroupInfo(ThreadGroup parent, String name, int maxPriority, boolean isDaemon) {
this.parent = parent;
this.name = name;
this.maxPriority = maxPriority;
this.isDaemon = isDaemon;
}
}
public static class ThreadGroupChildrenInfo {
public final Thread[] threads;
public final ThreadGroup[] groups;
ThreadGroupChildrenInfo(Thread[] threads, ThreadGroup[] groups) {
this.threads = threads;
this.groups = groups;
}
}
/**
* Event callbacks to a JJVMTI agent. Unlike the native JVMTI interface where callbacks are registered individually,
* Java agents register a single object and use overriding to handle just those events they want. The delivery of
* events is still also controlled by {@link #setEventNotificationMode} as per the JVMTI spec.
*
* These are defined in a separate interface partly to call them out and partly to permit some implementation
* flexibility.
*
* There is no separate {@code VM_START} event as Maxine cannot usefully distinguish it from {@code VM_INIT}.
* There is no separate {@code CLASS_PREPARE} event as Maxine cannot usefully distinguish it from {@code CLASS_LOAD}.
*
* N.B: Not all events are supported by the VM at this point. Those marked // TODO are not supported.
*/
public interface EventCallbacks {
/**
* This is not really an event, but is essentially equivalent to <a
* href="http://docs.oracle.com/javase/6/docs/platform/jvmti/jvmti.html#startup">startup</a>, and it is more
* more convenient to define it as an event in {@code JJVMTI}. <b>N.B.</b>This will only be called for agents
* that are built into the boot image and it is called in {code PRIMORDIAL} mode, where VM functionality is very
* limited. Dynamically loaded agents have their {@code onLoad} method called instead. Both variants will
* receive the {@code vmInit} event, which is the best place to do general agent setup.
*/
void onBoot();
/*
* The standard events. The method names match the JVMTI event names, modulo case and '_' differences.
*/
void breakpoint(Thread thread, MethodActor method, long location);
byte[] classFileLoadHook(ClassLoader loader, String name,
ProtectionDomain protectionDomain, byte[] classData);
void classLoad(Thread thread, ClassActor klass);
void compiledMethodLoad(MethodActor method, int codeSize, Address codeAddr, AddrLocation[] map, Object compileInfo);
void compiledMethodUnload(MethodActor method, Address codeAddr);
void dataDumpRequest(); // TODO
void dynamicCodeGenerated(String name, Address codeAddr, int length); // TODO
void exception(Thread thread, MethodActor method, long location, Object exception, MethodActor catchMethod, long catchLocation);
void exceptionCatch(Thread thread, MethodActor method, long location, Object exception); // TODO
void fieldAccess(Thread thread, MethodActor method, long location, ClassActor classActor, Object object, FieldActor field);
void fieldModification(Thread thread, MethodActor method, long location, ClassActor classActor, Object object, FieldActor field, Object newValue);
void framePop(Thread thread, MethodActor method, boolean wasPoppedByException);
void garbageCollectionStart();
void garbageCollectionFinish();
void methodEntry(Thread thread, MethodActor method);
void methodExit(Thread thread, MethodActor method, boolean exeception, Object returnValue);
void monitorContendedEnter(Thread thread, Object object); // TODO
void monitorContendedEntered(Thread thread, Object object); // TODO
void monitorWait(Thread thread, Object object, long timeout); // TODO
void monitorWaited(Thread thread, Object object, long timeout); // TODO
void objectFree(Object tag); // TODO
void resourceExhausted(int flags, String description); // TODO
void singleStep(Thread thread, MethodActor method, long location);
void threadStart(Thread thread);
void threadEnd(Thread thread);
void vmDeath();
void vmInit();
void vmObjectAlloc(Thread thread, Object object, ClassActor classActor, int size); // TODO
}
/**
* Heap callbacks.
* TODO: complete
*/
public interface HeapCallbacks {
/**
* See <a href="http://docs.oracle.com/javase/6/docs/platform/jvmti/jvmti.html#jvmtiHeapIterationCallback">heap iteration callback</a>.
* @return visit control flags
*/
int heapIteration(Object classTag, long size, Object objectTag, int length, Object userData);
/**
* A Maxine-specific variant that just passes the object, which is much simpler and more
* efficient for the client.
*/
int heapIterationMax(Object object, Object userData);
}
/*
* The following methods are independent of Class, Field and Method types.
*/
void setEventNotificationMode(int mode, JVMTIEvents.E event, Thread thread) throws JJVMTIException;
Thread[] getAllThreads() throws JJVMTIException;
@JJVMTI_FUNCTION(cap = CAN_SUSPEND)
void suspendThread(Thread thread) throws JJVMTIException;
@JJVMTI_FUNCTION(cap = CAN_SUSPEND)
void resumeThread(Thread thread) throws JJVMTIException;
@JJVMTI_FUNCTION(cap = CAN_SUSPEND)
int[] suspendThreadList(Thread[] threads) throws JJVMTIException;
@JJVMTI_FUNCTION(cap = CAN_SUSPEND)
int[] resumeThreadList(Thread[] threads) throws JJVMTIException;
@JJVMTI_FUNCTION(cap = CAN_SIGNAL_THREAD)
void interruptThread(Thread thread) throws JJVMTIException;
@JJVMTI_FUNCTION(cap = CAN_SIGNAL_THREAD)
void stopThread(Thread thread, Throwable t) throws JJVMTIException;
ThreadInfo getThreadInfo(Thread thread) throws JJVMTIException;
@JJVMTI_FUNCTION(cap = CAN_GET_OWNED_MONITOR_INFO)
void getOwnedMonitorInfo(Thread thread) throws JJVMTIException;
@JJVMTI_FUNCTION(cap = CAN_GET_OWNED_MONITOR_STACK_DEPTH_INFO)
MonitorStackDepthInfo[] getOwnedMonitorStackDepthInfo(Thread thread) throws JJVMTIException;
@JJVMTI_FUNCTION(cap = CAN_GET_CURRENT_CONTENDED_MONITOR)
Object getCurrentContendedMonitor(Thread thread) throws JJVMTIException;
void runAgentThread(Thread thread, int priority) throws JJVMTIException;
ThreadGroup[] getTopThreadGroups() throws JJVMTIException;
ThreadGroupInfo getThreadGroupInfo(ThreadGroup threadGroup) throws JJVMTIException;
ThreadGroupChildrenInfo getThreadGroupChildren(ThreadGroup threadGroup) throws JJVMTIException;
int getFrameCount(Thread thread) throws JJVMTIException;
int getThreadState(Thread thread) throws JJVMTIException;
Thread getCurrentThread() throws JJVMTIException;
FrameInfo getFrameLocation(Thread thread, int depth) throws JJVMTIException;
@JJVMTI_FUNCTION(cap = CAN_GENERATE_FRAME_POP_EVENTS)
void notifyFramePop(Thread thread, int depth) throws JJVMTIException;
@JJVMTI_FUNCTION(cap = CAN_ACCESS_LOCAL_VARIABLES)
Object getLocalObject(Thread thread, int depth, int slot) throws JJVMTIException;
@JJVMTI_FUNCTION(cap = CAN_ACCESS_LOCAL_VARIABLES)
int getLocalInt(Thread thread, int depth, int slot) throws JJVMTIException;
@JJVMTI_FUNCTION(cap = CAN_ACCESS_LOCAL_VARIABLES)
long getLocalLong(Thread thread, int depth, int slot) throws JJVMTIException;
@JJVMTI_FUNCTION(cap = CAN_ACCESS_LOCAL_VARIABLES)
float getLocalFloat(Thread thread, int depth, int slot) throws JJVMTIException;
@JJVMTI_FUNCTION(cap = CAN_ACCESS_LOCAL_VARIABLES)
double getLocalDouble(Thread thread, int depth, int slot) throws JJVMTIException;
@JJVMTI_FUNCTION(cap = CAN_ACCESS_LOCAL_VARIABLES)
void setLocalObject(Thread thread, int depth, int slot, Object value) throws JJVMTIException;
@JJVMTI_FUNCTION(cap = CAN_ACCESS_LOCAL_VARIABLES)
void setLocalInt(Thread thread, int depth, int slot, int value) throws JJVMTIException;
@JJVMTI_FUNCTION(cap = CAN_ACCESS_LOCAL_VARIABLES)
void setLocalLong(Thread thread, int depth, int slot, long value) throws JJVMTIException;
@JJVMTI_FUNCTION(cap = CAN_ACCESS_LOCAL_VARIABLES)
void setLocalFloat(Thread thread, int depth, int slot, float value) throws JJVMTIException;
@JJVMTI_FUNCTION(cap = CAN_ACCESS_LOCAL_VARIABLES)
void setLocalDouble(Thread thread, int arg2, int arg3, double value) throws JJVMTIException;
int getObjectHashCode(Object object) throws JJVMTIException;
@JJVMTI_FUNCTION(cap = CAN_GET_MONITOR_INFO)
ObjectMonitorUsage getObjectMonitorUsage(Object object) throws JJVMTIException;
@JJVMTI_FUNCTION(cap = CAN_SET_NATIVE_METHOD_PREFIX)
void setNativeMethodPrefix(String prefix) throws JJVMTIException;
@JJVMTI_FUNCTION(cap = CAN_SET_NATIVE_METHOD_PREFIX)
void setNativeMethodPrefixes(String[] prefixes) throws JJVMTIException;
@JJVMTI_FUNCTION(cap = CAN_POP_FRAME)
void popFrame(Thread thread) throws JJVMTIException;
@JJVMTI_FUNCTION(cap = CAN_FORCE_EARLY_RETURN)
void forceEarlyReturnObject(Thread thread, Object value) throws JJVMTIException;
@JJVMTI_FUNCTION(cap = CAN_FORCE_EARLY_RETURN)
void forceEarlyReturnInt(Thread thread, int value) throws JJVMTIException;
@JJVMTI_FUNCTION(cap = CAN_FORCE_EARLY_RETURN)
void forceEarlyReturnLong(Thread thread, long value) throws JJVMTIException;
@JJVMTI_FUNCTION(cap = CAN_FORCE_EARLY_RETURN)
void forceEarlyReturnFloat(Thread thread, float value) throws JJVMTIException;
@JJVMTI_FUNCTION(cap = CAN_FORCE_EARLY_RETURN)
void forceEarlyReturnDouble(Thread thread, double value) throws JJVMTIException;
@JJVMTI_FUNCTION(cap = CAN_FORCE_EARLY_RETURN)
void forceEarlyReturnVoid(Thread thread) throws JJVMTIException;
int getVersionNumber() throws JJVMTIException;
EnumSet<JVMTICapabilities.E> getCapabilities() throws JJVMTIException;
StackInfo[] getThreadListStackTraces(Thread[] threads, int maxFrameCount) throws JJVMTIException;
StackInfo[] getAllStackTraces(int maxFrameCount) throws JJVMTIException;
FrameInfo[] getStackTrace(Thread thread, int startDepth, int maxFrameCount) throws JJVMTIException;
@JJVMTI_FUNCTION(cap = CAN_TAG_OBJECTS)
Object getTag(Object object) throws JJVMTIException;
@JJVMTI_FUNCTION(cap = CAN_TAG_OBJECTS)
void setTag(Object object, Object tag) throws JJVMTIException;
void forceGarbageCollection() throws JJVMTIException;
/*
void iterateOverObjectsReachableFromObject(JniHandle arg1, Address arg2, Pointer arg3) throws Exception;
void iterateOverReachableObjects(Address arg1, Address arg2, Address arg3, Pointer arg4) throws Exception;
void iterateOverHeap(int arg1, Address arg2, Pointer arg3) throws Exception;
void iterateOverInstancesOfClass(JniHandle arg1, int arg2, Address arg3, Pointer arg4) throws Exception;
void getObjectsWithTags(int arg1, Pointer arg2, Pointer arg3, Pointer arg4, Pointer arg5) throws Exception;
void followReferences(int arg1, JniHandle arg2, JniHandle arg3, Pointer arg4, Pointer arg5) throws Exception;
void generateEvents(int arg1) throws Exception;
void getExtensionFunctions(Pointer arg1, Pointer arg2) throws Exception;
void getExtensionEvents(Pointer arg1, Pointer arg2) throws Exception;
void setExtensionEventCallback(int arg1, Address arg2) throws Exception;
*/
@JJVMTI_FUNCTION(cap = CAN_TAG_OBJECTS)
void iterateThroughHeap(int filter, ClassActor classActor, HeapCallbacks heapCallbacks, Object userData) throws JJVMTIException;
/**
* Maxine-specific version invokes {@link HeapCallbacks#heapIteration(Object, Object)}.
*/
void iterateThroughHeapMax(int filter, ClassActor classActor, HeapCallbacks heapCallbacks, Object userData) throws JJVMTIException;
void disposeEnvironment() throws JJVMTIException;
String getErrorName(int error) throws JJVMTIException;
int getJLocationFormat() throws JJVMTIException;
String[] getSystemProperties() throws JJVMTIException;
String getSystemProperty(String key) throws JJVMTIException;
void setSystemProperty(String key, String value) throws JJVMTIException;
int getPhase() throws JJVMTIException;
// void getCurrentThreadCpuTimerInfo(Pointer arg1) throws Exception;
long getCurrentThreadCpuTime() throws JJVMTIException;
// void getThreadCpuTimerInfo(Pointer arg1) throws Exception;
long getThreadCpuTime(Thread thread) throws JJVMTIException;
// void getTimerInfo(Pointer arg1) throws Exception;
long getTime() throws JJVMTIException;
EnumSet<JVMTICapabilities.E> getPotentialCapabilities() throws JJVMTIException;
void addCapabilities(EnumSet<JVMTICapabilities.E> caps) throws JJVMTIException;
void relinquishCapabilities(EnumSet<JVMTICapabilities.E> caps) throws JJVMTIException;
int getAvailableProcessors() throws JJVMTIException;
void addToBootstrapClassLoaderSearch(String path) throws JJVMTIException;
void setVerboseFlag(int flag, boolean value) throws JJVMTIException;
void addToSystemClassLoaderSearch(String path) throws JJVMTIException;
long getObjectSize(Object object) throws JJVMTIException;
// void getLocalInstance(JniHandle arg1, int arg2, Pointer arg3) throws Exception;
/*
* These methods refer to methods, fields and classes. in native JVMTI these values are represented
* by scalar values that correspond to Maxine's MemberID, ClassID. Here we choose to use the Maxine
* Actor types.
*/
@JJVMTI_FUNCTION(cap = CAN_GENERATE_BREAKPOINT_EVENTS)
void setBreakpoint(ClassMethodActor method, long location) throws JJVMTIException;
@JJVMTI_FUNCTION(cap = CAN_GENERATE_BREAKPOINT_EVENTS)
void clearBreakpoint(ClassMethodActor method, long location) throws JJVMTIException;
@JJVMTI_FUNCTION(cap = CAN_GENERATE_FIELD_ACCESS_EVENTS)
void setFieldAccessWatch(FieldActor field) throws JJVMTIException;
@JJVMTI_FUNCTION(cap = CAN_GENERATE_FIELD_ACCESS_EVENTS)
void clearFieldAccessWatch(FieldActor field) throws JJVMTIException;
@JJVMTI_FUNCTION(cap = CAN_GENERATE_FIELD_MODIFICATION_EVENTS)
void setFieldModificationWatch(FieldActor field) throws JJVMTIException;
@JJVMTI_FUNCTION(cap = CAN_GENERATE_FIELD_MODIFICATION_EVENTS)
void clearFieldModificationWatch(FieldActor field) throws JJVMTIException;
boolean isModifiableClass(ClassActor klass) throws JJVMTIException;
String getClassSignature(ClassActor klass) throws JJVMTIException;
int getClassStatus(ClassActor klass) throws JJVMTIException;
@JJVMTI_FUNCTION(cap = CAN_GET_SOURCE_FILE_NAME)
String getSourceFileName(ClassActor klass) throws JJVMTIException;
int getClassModifiers(ClassActor klass) throws JJVMTIException;
MethodActor[] getClassMethods(ClassActor klass) throws JJVMTIException;
FieldActor[] getClassFields(ClassActor klass) throws JJVMTIException;
ClassActor[] getImplementedInterfaces(ClassActor klass) throws JJVMTIException;
boolean isInterface(ClassActor klass) throws JJVMTIException;
boolean isArrayClass(ClassActor klass) throws JJVMTIException;
ClassLoader getClassLoader(ClassActor klass) throws JJVMTIException;
String getFieldName(FieldActor field) throws JJVMTIException;
String getFieldSignature(FieldActor field) throws JJVMTIException;
ClassActor getFieldDeclaringClass(FieldActor field) throws JJVMTIException;
int getFieldModifiers(FieldActor field) throws JJVMTIException;
@JJVMTI_FUNCTION(cap = CAN_GET_SYNTHETIC_ATTRIBUTE)
boolean isFieldSynthetic(FieldActor field) throws JJVMTIException;
String getMethodName(MethodActor method) throws JJVMTIException;
String getMethodSignature(MethodActor method) throws JJVMTIException;
String getMethodGenericSignature(MethodActor method) throws JJVMTIException;
ClassActor getMethodDeclaringClass(MethodActor method) throws JJVMTIException;
int getMethodModifiers(MethodActor method) throws JJVMTIException;
int getMaxLocals(ClassMethodActor method) throws JJVMTIException;
int getArgumentsSize(ClassMethodActor method) throws JJVMTIException;
@JJVMTI_FUNCTION(cap = CAN_GET_LINE_NUMBERS)
LineNumberEntry[] getLineNumberTable(ClassMethodActor method) throws JJVMTIException;
MethodLocation getMethodLocation(ClassMethodActor method) throws JJVMTIException;
@JJVMTI_FUNCTION(cap = CAN_ACCESS_LOCAL_VARIABLES)
LocalVariableEntry[] getLocalVariableTable(ClassMethodActor member) throws JJVMTIException;
@JJVMTI_FUNCTION(cap = CAN_GET_BYTECODES)
byte[] getBytecodes(ClassMethodActor method) throws JJVMTIException;
boolean isMethodNative(MethodActor method) throws JJVMTIException;
@JJVMTI_FUNCTION(cap = CAN_GET_SYNTHETIC_ATTRIBUTE)
boolean isMethodSynthetic(MethodActor method) throws JJVMTIException;
ClassActor[] getLoadedClasses() throws JJVMTIException;
ClassActor[] getClassLoaderClasses(ClassLoader loader) throws JJVMTIException;
@JJVMTI_FUNCTION(cap = CAN_REDEFINE_CLASSES)
void redefineClasses(ClassDefinition[] classDefinitions) throws JJVMTIException;
String getSourceDebugExtension(ClassActor klass) throws JJVMTIException;
boolean isMethodObsolete(MethodActor method) throws JJVMTIException;
ClassVersionInfo getClassVersionNumbers(ClassActor klass) throws JJVMTIException;
@JJVMTI_FUNCTION(cap = CAN_GET_CONSTANT_POOL)
byte[] getConstantPool(ClassActor klass) throws JJVMTIException;
void retransformClasses(ClassActor[] klasses) throws JJVMTIException;
/**
* Maxine-specific call to include VM classes in the analysis, which are usually suppressed.
*/
void includeMaxVMClasses(boolean include);
}