diff options
-rw-r--r-- | ChangeLog | 49 | ||||
-rw-r--r-- | gnu/classpath/jdwp/processor/EventRequestCommandSet.java | 25 | ||||
-rw-r--r-- | gnu/classpath/jdwp/processor/MethodCommandSet.java | 18 | ||||
-rw-r--r-- | gnu/classpath/jdwp/processor/ObjectReferenceCommandSet.java | 20 | ||||
-rw-r--r-- | gnu/classpath/jdwp/processor/ReferenceTypeCommandSet.java | 13 | ||||
-rw-r--r-- | gnu/classpath/jdwp/processor/StackFrameCommandSet.java | 15 | ||||
-rw-r--r-- | gnu/classpath/jdwp/processor/ThreadReferenceCommandSet.java | 42 | ||||
-rw-r--r-- | gnu/classpath/jdwp/processor/VirtualMachineCommandSet.java | 82 | ||||
-rw-r--r-- | gnu/classpath/jdwp/util/MonitorInfo.java | 76 | ||||
-rw-r--r-- | vm/reference/gnu/classpath/jdwp/VMVirtualMachine.java | 101 |
10 files changed, 377 insertions, 64 deletions
@@ -1,3 +1,52 @@ +2007-02-28 Keith Seitz <keiths@redhat.com> + + * gnu/classpath/jdwp/processor/EventRequestCommandSet.java + (executeSet): Check if VM has capability for field access + or modification events. + * gnu/classpath/jdwp/processor/MethodCommandSet.java + (executeByteCodes): Check if VM has capability and + implement. + * gnu/classpath/jdwp/processor/ObjectReferenceCommandSet.java + (executeMonitorInfo): Likewise. + * gnu/classpath/jdwp/processor/ReferenceTypeCommandSet.java + (executeSourceDebugExtension): Likewise. + * gnu/classpath/jdwp/processor/StackFrameCommandSet.java + (executePopFrames): Likewise. + * gnu/classpath/jdwp/processor/ThreadReferenceCommandSet.java + (executeOwnedMonitors): Likewise. + (executeCurrentContendedMonitor): Likewise. + * gnu/classpath/jdwp/processor/VirtualMachineCommandSet.java + (executeCapabilities): Rewrite using new VMVirtualMachine + capabilities. + (executeRedefineClasses): Check if VM has capability and + implement. + (executeSetDefaultStratum): Likewise. + * gnu/classpath/jdwp/util/MonitorInfo.java; New file. + * vm/reference/gnu/classpath/jdwp/VMVirtualMachine.java + (canWatchFieldModification): New class constant. + (canWatchFieldAccess): Likewise. + (canGetBytecodes): Likewise. + (canGetSyntheticAttribute): Likewise. + (canGetOwnedMonitorInfo): Likewise. + (canGetCurrentContendedMonitor): Likewise. + (canGetMonitorInfo): Likewise. + (canRedefineClasses): Likewise. + (canAddMethod): Likewise. + (canUnrestrictedlyRedefineClasses): Likewise. + (canPopFrames): Likewise. + (canUseInstanceFilters): Likewise. + (canGetSourceDebugExtension): Likewise. + (canRequestVMDeathEvent): Likewise. + (canSetDefaultStratum): Likewise. + (redefineClasses): New method. + (setDefaultStratum): Likewise. + (getSourceDebugExtension): Likewise. + (getBytecodes): Likewise. + (getMonitorInfo): Likewise. + (getOwnedMonitors): Likewise. + (getCurrentContendedMonitor): Likewise. + (popFrames): Likewise. + 2007-03-01 Roman Kennke <kennke@aicas.com> * java/awt/Canvas.java diff --git a/gnu/classpath/jdwp/processor/EventRequestCommandSet.java b/gnu/classpath/jdwp/processor/EventRequestCommandSet.java index 59cfb94d3..d7ebbc3a3 100644 --- a/gnu/classpath/jdwp/processor/EventRequestCommandSet.java +++ b/gnu/classpath/jdwp/processor/EventRequestCommandSet.java @@ -1,6 +1,6 @@ /* EventRequestCommandSet.java -- class to implement the EventRequest Command Set - Copyright (C) 2005 Free Software Foundation + Copyright (C) 2005, 2007 Free Software Foundation This file is part of GNU Classpath. @@ -40,6 +40,7 @@ exception statement from your version. */ package gnu.classpath.jdwp.processor; import gnu.classpath.jdwp.JdwpConstants; +import gnu.classpath.jdwp.VMVirtualMachine; import gnu.classpath.jdwp.event.EventManager; import gnu.classpath.jdwp.event.EventRequest; import gnu.classpath.jdwp.event.filters.ClassExcludeFilter; @@ -113,6 +114,28 @@ public class EventRequestCommandSet byte suspendPolicy = bb.get(); int modifiers = bb.getInt(); + switch (eventKind) + { + case JdwpConstants.EventKind.FIELD_ACCESS: + if (!VMVirtualMachine.canWatchFieldAccess) + { + String msg = "watching field accesses is not supported"; + throw new NotImplementedException(msg); + } + break; + + case JdwpConstants.EventKind.FIELD_MODIFICATION: + if (!VMVirtualMachine.canWatchFieldModification) + { + String msg = "watching field modifications is not supported"; + throw new NotImplementedException(msg); + } + break; + + default: + // okay + } + EventRequest eventReq = new EventRequest(eventKind, suspendPolicy); IEventFilter filter = null; ReferenceTypeId refId; diff --git a/gnu/classpath/jdwp/processor/MethodCommandSet.java b/gnu/classpath/jdwp/processor/MethodCommandSet.java index 64956e847..4d1bf7098 100644 --- a/gnu/classpath/jdwp/processor/MethodCommandSet.java +++ b/gnu/classpath/jdwp/processor/MethodCommandSet.java @@ -40,6 +40,7 @@ package gnu.classpath.jdwp.processor; import gnu.classpath.jdwp.JdwpConstants; import gnu.classpath.jdwp.VMMethod; +import gnu.classpath.jdwp.VMVirtualMachine; import gnu.classpath.jdwp.exception.JdwpException; import gnu.classpath.jdwp.exception.JdwpInternalErrorException; import gnu.classpath.jdwp.exception.NotImplementedException; @@ -119,11 +120,20 @@ public class MethodCommandSet } private void executeByteCodes(ByteBuffer bb, DataOutputStream os) - throws JdwpException + throws JdwpException, IOException { - // This command is optional, determined by VirtualMachines CapabilitiesNew - // so we'll leave it till later to implement - throw new NotImplementedException("Command ByteCodes not implemented."); + if (!VMVirtualMachine.canGetBytecodes) + { + String msg = "getting bytecodes is unsupported"; + throw new NotImplementedException(msg); + } + + ReferenceTypeId id = idMan.readReferenceTypeId(bb); + Class klass = id.getType(); + VMMethod method = VMMethod.readId(klass, bb); + byte[] bytecode = VMVirtualMachine.getBytecodes(method); + os.writeInt(bytecode.length); + os.write(bytecode); } private void executeIsObsolete(ByteBuffer bb, DataOutputStream os) diff --git a/gnu/classpath/jdwp/processor/ObjectReferenceCommandSet.java b/gnu/classpath/jdwp/processor/ObjectReferenceCommandSet.java index ef421ea5b..6bcd11e89 100644 --- a/gnu/classpath/jdwp/processor/ObjectReferenceCommandSet.java +++ b/gnu/classpath/jdwp/processor/ObjectReferenceCommandSet.java @@ -1,6 +1,6 @@ /* ObjectReferenceCommandSet.java -- class to implement the ObjectReference Command Set - Copyright (C) 2005 Free Software Foundation + Copyright (C) 2005, 2007 Free Software Foundation This file is part of GNU Classpath. @@ -47,8 +47,9 @@ import gnu.classpath.jdwp.exception.JdwpInternalErrorException; import gnu.classpath.jdwp.exception.NotImplementedException; import gnu.classpath.jdwp.id.ObjectId; import gnu.classpath.jdwp.id.ReferenceTypeId; -import gnu.classpath.jdwp.util.Value; import gnu.classpath.jdwp.util.MethodResult; +import gnu.classpath.jdwp.util.MonitorInfo; +import gnu.classpath.jdwp.util.Value; import java.io.DataOutputStream; import java.io.IOException; @@ -183,13 +184,18 @@ public class ObjectReferenceCommandSet } private void executeMonitorInfo(ByteBuffer bb, DataOutputStream os) - throws JdwpException + throws JdwpException, IOException { - // This command is optional, determined by VirtualMachines CapabilitiesNew - // so we'll leave it till later to implement - throw new NotImplementedException( - "Command ExecuteMonitorInfo not implemented."); + if (!VMVirtualMachine.canGetMonitorInfo) + { + String msg = "getting monitor info not supported"; + throw new NotImplementedException(msg); + } + ObjectId oid = idMan.readObjectId(bb); + Object obj = oid.getObject(); + MonitorInfo info = VMVirtualMachine.getMonitorInfo(obj); + info.write(os); } private void executeInvokeMethod(ByteBuffer bb, DataOutputStream os) diff --git a/gnu/classpath/jdwp/processor/ReferenceTypeCommandSet.java b/gnu/classpath/jdwp/processor/ReferenceTypeCommandSet.java index c46b2bdfa..cfee7194d 100644 --- a/gnu/classpath/jdwp/processor/ReferenceTypeCommandSet.java +++ b/gnu/classpath/jdwp/processor/ReferenceTypeCommandSet.java @@ -303,10 +303,15 @@ public class ReferenceTypeCommandSet private void executeSourceDebugExtension(ByteBuffer bb, DataOutputStream os) throws JdwpException, IOException { - // This command is optional, determined by VirtualMachines CapabilitiesNew - // so we'll leave it till later to implement - throw new NotImplementedException( - "Command SourceDebugExtension not implemented."); + if (!VMVirtualMachine.canGetSourceDebugExtension) + { + String msg = "source debug extension is not supported"; + throw new NotImplementedException(msg); + } + + ReferenceTypeId id = idMan.readReferenceTypeId(bb); + String ext = VMVirtualMachine.getSourceDebugExtension (id.getType()); + JdwpString.writeString(os, ext); } private void executeSignatureWithGeneric(ByteBuffer bb, DataOutputStream os) diff --git a/gnu/classpath/jdwp/processor/StackFrameCommandSet.java b/gnu/classpath/jdwp/processor/StackFrameCommandSet.java index d62f5d783..4cfb25183 100644 --- a/gnu/classpath/jdwp/processor/StackFrameCommandSet.java +++ b/gnu/classpath/jdwp/processor/StackFrameCommandSet.java @@ -152,10 +152,17 @@ public class StackFrameCommandSet } private void executePopFrames(ByteBuffer bb, DataOutputStream os) - throws JdwpException + throws JdwpException, IOException { - // This command is optional, determined by VirtualMachines CapabilitiesNew - // so we'll leave it till later to implement - throw new NotImplementedException("Command PopFrames not implemented."); + if (!VMVirtualMachine.canPopFrames) + { + String msg = "popping frames is unsupported"; + throw new NotImplementedException(msg); + } + + ThreadId tid = (ThreadId) idMan.readObjectId(bb); + Thread thread = tid.getThread(); + long fid = bb.getLong(); + VMVirtualMachine.popFrames(thread, fid); } } diff --git a/gnu/classpath/jdwp/processor/ThreadReferenceCommandSet.java b/gnu/classpath/jdwp/processor/ThreadReferenceCommandSet.java index fd7fa743e..0dd10200b 100644 --- a/gnu/classpath/jdwp/processor/ThreadReferenceCommandSet.java +++ b/gnu/classpath/jdwp/processor/ThreadReferenceCommandSet.java @@ -1,5 +1,5 @@ /* ThreadReferenceCommandSet.java -- class to implement the ThreadReference - Command Set Copyright (C) 2005 Free Software Foundation + Command Set Copyright (C) 2005, 2007 Free Software Foundation This file is part of GNU Classpath. @@ -198,22 +198,42 @@ public class ThreadReferenceCommandSet } private void executeOwnedMonitors(ByteBuffer bb, DataOutputStream os) - throws JdwpException + throws JdwpException, IOException { - // This command is optional, determined by VirtualMachines CapabilitiesNew - // so we'll leave it till later to implement - throw new NotImplementedException( - "Command OwnedMonitors not implemented."); + if (!VMVirtualMachine.canGetOwnedMonitorInfo) + { + String msg = "getting owned monitors is not supported"; + throw new NotImplementedException(msg); + } + + ThreadId tid = (ThreadId) idMan.readObjectId(bb); + Thread thread = tid.getThread(); + Object[] monitors = VMVirtualMachine.getOwnedMonitors(thread); + + os.write(monitors.length); + for (int i = 0; i < monitors.length; ++i) + { + ObjectId id = idMan.getObjectId(monitors[i]); + id.writeTagged(os); + } } private void executeCurrentContendedMonitor(ByteBuffer bb, DataOutputStream os) - throws JdwpException + throws JdwpException, IOException { - // This command is optional, determined by VirtualMachines CapabilitiesNew - // so we'll leave it till later to implement - throw new NotImplementedException( - "Command CurrentContentedMonitors not implemented."); + if (!VMVirtualMachine.canGetCurrentContendedMonitor) + { + String msg = "getting current contended monitor is not supported"; + throw new NotImplementedException(msg); + } + + ThreadId tid = (ThreadId) idMan.readObjectId(bb); + Thread thread = tid.getThread(); + + Object monitor = VMVirtualMachine.getCurrentContendedMonitor(thread); + ObjectId id = idMan.getObjectId(monitor); + id.writeTagged(os); } private void executeStop(ByteBuffer bb, DataOutputStream os) diff --git a/gnu/classpath/jdwp/processor/VirtualMachineCommandSet.java b/gnu/classpath/jdwp/processor/VirtualMachineCommandSet.java index 33cb8a319..e2703908b 100644 --- a/gnu/classpath/jdwp/processor/VirtualMachineCommandSet.java +++ b/gnu/classpath/jdwp/processor/VirtualMachineCommandSet.java @@ -331,14 +331,13 @@ public class VirtualMachineCommandSet private void executeCapabilities(ByteBuffer bb, DataOutputStream os) throws JdwpException, IOException { - // Store these somewhere? - os.writeBoolean(false); // canWatchFieldModification - os.writeBoolean(false); // canWatchFieldAccess - os.writeBoolean(false); // canGetBytecodes - os.writeBoolean(false); // canGetSyntheticAttribute - os.writeBoolean(false); // canGetOwnedMonitorInfo - os.writeBoolean(false); // canGetCurrentContendedMonitor - os.writeBoolean(false); // canGetMonitorInfo + os.writeBoolean(VMVirtualMachine.canWatchFieldModification); + os.writeBoolean(VMVirtualMachine.canWatchFieldAccess); + os.writeBoolean(VMVirtualMachine.canGetBytecodes); + os.writeBoolean(VMVirtualMachine.canGetSyntheticAttribute); + os.writeBoolean(VMVirtualMachine.canGetOwnedMonitorInfo); + os.writeBoolean(VMVirtualMachine.canGetCurrentContendedMonitor); + os.writeBoolean(VMVirtualMachine.canGetMonitorInfo); } private void executeClassPaths(ByteBuffer bb, DataOutputStream os) @@ -392,43 +391,60 @@ public class VirtualMachineCommandSet private void executeCapabilitiesNew(ByteBuffer bb, DataOutputStream os) throws JdwpException, IOException { - // Store these somewhere? final int CAPABILITIES_NEW_SIZE = 32; - os.writeBoolean(false); // canWatchFieldModification - os.writeBoolean(false); // canWatchFieldAccess - os.writeBoolean(false); // canGetBytecodes - os.writeBoolean(false); // canGetSyntheticAttribute - os.writeBoolean(false); // canGetOwnedMonitorInfo - os.writeBoolean(false); // canGetCurrentContendedMonitor - os.writeBoolean(false); // canGetMonitorInfo - os.writeBoolean(false); // canRedefineClasses - os.writeBoolean(false); // canAddMethod - os.writeBoolean(false); // canUnrestrictedlyRedefineClasses - os.writeBoolean(false); // canPopFrames - os.writeBoolean(false); // canUseInstanceFilters - os.writeBoolean(false); // canGetSourceDebugExtension - os.writeBoolean(false); // canRequestVMDeathEvent - os.writeBoolean(false); // canSetDefaultStratum + + executeCapabilities(bb, os); + os.writeBoolean(VMVirtualMachine.canRedefineClasses); + os.writeBoolean(VMVirtualMachine.canAddMethod); + os.writeBoolean(VMVirtualMachine.canUnrestrictedlyRedefineClasses); + os.writeBoolean(VMVirtualMachine.canPopFrames); + os.writeBoolean(VMVirtualMachine.canUseInstanceFilters); + os.writeBoolean(VMVirtualMachine.canGetSourceDebugExtension); + os.writeBoolean(VMVirtualMachine.canRequestVMDeathEvent); + os.writeBoolean(VMVirtualMachine.canSetDefaultStratum); for (int i = 15; i < CAPABILITIES_NEW_SIZE; i++) - // Future capabilities - // currently unused - os.writeBoolean(false); // Set to false + { + // Future capabilities (currently unused) + os.writeBoolean(false); + } } private void executeRedefineClasses(ByteBuffer bb, DataOutputStream os) throws JdwpException { - // Optional command, don't implement - throw new NotImplementedException( - "Command VirtualMachine.RedefineClasses not implemented"); + if (!VMVirtualMachine.canRedefineClasses) + { + String msg = "redefinition of classes is not supported"; + throw new NotImplementedException(msg); + } + + int classes = bb.getInt(); + Class[] types = new Class[classes]; + byte[][] bytecodes = new byte[classes][]; + for (int i = 0; i < classes; ++i) + { + ReferenceTypeId id = idMan.readReferenceTypeId(bb); + int classfile = bb.getInt(); + byte[] bytecode = new byte[classfile]; + bb.get(bytecode); + types[i] = id.getType(); + bytecodes[i] = bytecode; + } + + VMVirtualMachine.redefineClasses (types, bytecodes); } private void executeSetDefaultStratum(ByteBuffer bb, DataOutputStream os) throws JdwpException { - // Optional command, don't implement - throw new NotImplementedException( - "Command VirtualMachine.SetDefaultStratum not implemented"); + if (!VMVirtualMachine.canSetDefaultStratum) + { + String msg = "setting the default stratum is not supported"; + throw new NotImplementedException(msg); + } + + String stratum = JdwpString.readString(bb); + VMVirtualMachine.setDefaultStratum(stratum); } private void executeAllClassesWithGeneric(ByteBuffer bb, DataOutputStream os) diff --git a/gnu/classpath/jdwp/util/MonitorInfo.java b/gnu/classpath/jdwp/util/MonitorInfo.java new file mode 100644 index 000000000..f28eabf83 --- /dev/null +++ b/gnu/classpath/jdwp/util/MonitorInfo.java @@ -0,0 +1,76 @@ +/* MonitorInfo.java -- class used to return monitor information + for JDWP. + + Copyright (C) 2007 Free Software Foundation + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath 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 for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.classpath.jdwp.util; + +import gnu.classpath.jdwp.VMIdManager; +import gnu.classpath.jdwp.id.ObjectId; + +import java.io.DataOutputStream; +import java.io.IOException; + +/** + * This class is used to pass monitor information between + * the JDWP back-end and the virtual machine. + * + * @author Keith Seitz (keiths@redhat.com) + */ +public class MonitorInfo +{ + public int entryCount; + public Thread owner; + public Thread[] waiters; + + public void write(DataOutputStream os) + throws IOException + { + VMIdManager idm = VMIdManager.getDefault(); + ObjectId id = idm.getObjectId(owner); + id.write(os); + os.write(entryCount); + os.write(waiters.length); + for (int i = 0; i < waiters.length; ++i) + { + id = idm.getObjectId(waiters[i]); + id.write(os); + } + } +} diff --git a/vm/reference/gnu/classpath/jdwp/VMVirtualMachine.java b/vm/reference/gnu/classpath/jdwp/VMVirtualMachine.java index dbd8449d7..c49298288 100644 --- a/vm/reference/gnu/classpath/jdwp/VMVirtualMachine.java +++ b/vm/reference/gnu/classpath/jdwp/VMVirtualMachine.java @@ -45,6 +45,8 @@ import gnu.classpath.jdwp.event.EventRequest; import gnu.classpath.jdwp.exception.InvalidMethodException; import gnu.classpath.jdwp.exception.JdwpException; import gnu.classpath.jdwp.util.MethodResult; +import gnu.classpath.jdwp.util.MonitorInfo; + import java.lang.reflect.Method; import java.nio.ByteBuffer; import java.util.ArrayList; @@ -57,6 +59,23 @@ import java.util.Collection; */ public class VMVirtualMachine { + // VM Capabilities + public static final boolean canWatchFieldModification = false; + public static final boolean canWatchFieldAccess = false; + public static final boolean canGetBytecodes = false; + public static final boolean canGetSyntheticAttribute = false; + public static final boolean canGetOwnedMonitorInfo = false; + public static final boolean canGetCurrentContendedMonitor = false; + public static final boolean canGetMonitorInfo = false; + public static final boolean canRedefineClasses = false; + public static final boolean canAddMethod = false; + public static final boolean canUnrestrictedlyRedefineClasses = false; + public static final boolean canPopFrames = false; + public static final boolean canUseInstanceFilters = false; + public static final boolean canGetSourceDebugExtension = false; + public static final boolean canRequestVMDeathEvent = false; + public static final boolean canSetDefaultStratum = false; + /** * Suspend a thread * @@ -320,4 +339,86 @@ public class VMVirtualMachine */ public static native void clearEvents(byte kind) throws JdwpException; + + /** + * Redefines the given types. VM must support canRedefineClasses + * capability (may also require canAddMethod and/or + * canUnrestrictedlyRedefineClasses capabilities) + * + * @param types the classes to redefine + * @param bytecodes the new bytecode definitions for the classes + */ + public static native void redefineClasses(Class[] types, byte[][] bytecodes) + throws JdwpException; + + /** + * Sets the default stratum. VM must support the + * canSetDefaultStratum capability. + * + * @param stratum the new default stratum or empty string to + * use the reference default + */ + public static native void setDefaultStratum(String stratum) + throws JdwpException; + + /** + * Returns the source debug extension. VM must support the + * canGetSourceDebugExtension capability. + * + * @param klass the class for which to return information + * @returns the source debug extension + */ + public static native String getSourceDebugExtension(Class klass) + throws JdwpException; + + /** + * Returns the bytecode for the given method. VM must support the + * canGetBytecodes capability. + * + * @param method the method for which to get bytecodes + * @returns the bytecodes + */ + public static native byte[] getBytecodes(VMMethod method) + throws JdwpException; + + /** + * Returns monitor information about an object. VM must support + * the canGetMonitorInformation capability. + * + * @param obj the object + * @returns monitor information (owner, entry count, waiters) + */ + public static native MonitorInfo getMonitorInfo(Object obj) + throws JdwpException; + + /** + * Returns a list of owned monitors. VM must support the + * canGetOwnedMonitorInfo capability. + * + * @param thread a thread + * @returns the list of monitors owned by this thread + */ + public static native Object[] getOwnedMonitors(Thread thread) + throws JdwpException; + + /** + * Returns the current contended monitor for a thread. VM must + * support canGetCurrentContendedMonitor capability. + * + * @param thread the thread + * @returns the contended monitor + */ + public static native Object getCurrentContendedMonitor(Thread thread) + throws JdwpException; + + /** + * Pop all frames up to and including the given frame. VM must + * support canPopFrames capability. It is the responsibility + * of the VM to check if the thread is suspended. If it is not, + * the VM should throw ThreadNotSuspendedException. + * + * @param thread the thread + * @param frame the frame ID + */ + public static native void popFrames(Thread thread, long frameId); } |