Mercurial > hg > truffle
diff agent/src/share/classes/sun/jvm/hotspot/jdi/StackFrameImpl.java @ 0:a61af66fc99e jdk7-b24
Initial load
author | duke |
---|---|
date | Sat, 01 Dec 2007 00:00:00 +0000 |
parents | |
children | c18cbe5936b8 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/agent/src/share/classes/sun/jvm/hotspot/jdi/StackFrameImpl.java Sat Dec 01 00:00:00 2007 +0000 @@ -0,0 +1,276 @@ +/* + * Copyright 2002-2005 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +package sun.jvm.hotspot.jdi; + +import com.sun.jdi.*; +import sun.jvm.hotspot.oops.ObjectHeap; +import sun.jvm.hotspot.debugger.OopHandle; +import sun.jvm.hotspot.oops.Array; +import sun.jvm.hotspot.oops.ObjArray; +import sun.jvm.hotspot.oops.TypeArray; +import sun.jvm.hotspot.oops.Instance; +import sun.jvm.hotspot.runtime.BasicType; +import sun.jvm.hotspot.runtime.JavaVFrame; +import sun.jvm.hotspot.runtime.StackValue; +import sun.jvm.hotspot.runtime.StackValueCollection; +import sun.jvm.hotspot.utilities.Assert; +import java.util.List; +import java.util.Map; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Collections; + +public class StackFrameImpl extends MirrorImpl + implements StackFrame +{ + /* Once false, frame should not be used. + * access synchronized on (vm.state()) + */ + private boolean isValid = true; + + private final ThreadReferenceImpl thread; + private final JavaVFrame saFrame; + private final Location location; + private Map visibleVariables = null; + private ObjectReference thisObject = null; + + StackFrameImpl(VirtualMachine vm, ThreadReferenceImpl thread, + JavaVFrame jvf) { + super(vm); + this.thread = thread; + this.saFrame = jvf; + + sun.jvm.hotspot.oops.Method SAMethod = jvf.getMethod(); + + ReferenceType rt = ((VirtualMachineImpl)vm).referenceType(SAMethod.getMethodHolder()); + + this.location = new LocationImpl(vm, rt, SAMethod, (long)jvf.getBCI()); + } + + private void validateStackFrame() { + if (!isValid) { + throw new InvalidStackFrameException("Thread has been resumed"); + } + } + + JavaVFrame getJavaVFrame() { + return saFrame; + } + + /** + * Return the frame location. + * Need not be synchronized since it cannot be provably stale. + */ + public Location location() { + validateStackFrame(); + return location; + } + + /** + * Return the thread holding the frame. + * Need not be synchronized since it cannot be provably stale. + */ + public ThreadReference thread() { + validateStackFrame(); + return thread; + } + + public boolean equals(Object obj) { + if ((obj != null) && (obj instanceof StackFrameImpl)) { + StackFrameImpl other = (StackFrameImpl)obj; + return (saFrame.equals(other.saFrame)); + } else { + return false; + } + } + + public int hashCode() { + return saFrame.hashCode(); + } + + public ObjectReference thisObject() { + validateStackFrame(); + MethodImpl currentMethod = (MethodImpl)location.method(); + if (currentMethod.isStatic() || currentMethod.isNative()) { + return null; + } + if (thisObject == null) { + StackValueCollection values = saFrame.getLocals(); + if (Assert.ASSERTS_ENABLED) { + Assert.that(values.size() > 0, "this is missing"); + } + // 'this' at index 0. + OopHandle handle = values.oopHandleAt(0); + ObjectHeap heap = vm.saObjectHeap(); + thisObject = vm.objectMirror(heap.newOop(handle)); + } + return thisObject; + } + + /** + * Build the visible variable map. + * Need not be synchronized since it cannot be provably stale. + */ + private void createVisibleVariables() throws AbsentInformationException { + if (visibleVariables == null) { + List allVariables = location.method().variables(); + Map map = new HashMap(allVariables.size()); + + Iterator iter = allVariables.iterator(); + while (iter.hasNext()) { + LocalVariableImpl variable = (LocalVariableImpl)iter.next(); + String name = variable.name(); + if (variable.isVisible(this)) { + LocalVariable existing = (LocalVariable)map.get(name); + if ((existing == null) || + variable.hides(existing)) { + map.put(name, variable); + } + } + } + visibleVariables = map; + } + } + + /** + * Return the list of visible variable in the frame. + * Need not be synchronized since it cannot be provably stale. + */ + public List visibleVariables() throws AbsentInformationException { + validateStackFrame(); + createVisibleVariables(); + List mapAsList = new ArrayList(visibleVariables.values()); + Collections.sort(mapAsList); + return mapAsList; + } + + /** + * Return a particular variable in the frame. + * Need not be synchronized since it cannot be provably stale. + */ + public LocalVariable visibleVariableByName(String name) throws AbsentInformationException { + validateStackFrame(); + createVisibleVariables(); + return (LocalVariable)visibleVariables.get(name); + } + + public Value getValue(LocalVariable variable) { + List list = new ArrayList(1); + list.add(variable); + Map map = getValues(list); + return (Value)map.get(variable); + } + + public Map getValues(List variables) { + validateStackFrame(); + StackValueCollection values = saFrame.getLocals(); + + int count = variables.size(); + Map map = new HashMap(count); + for (int ii=0; ii<count; ++ii) { + LocalVariableImpl variable = (LocalVariableImpl)variables.get(ii); + if (!variable.isVisible(this)) { + throw new IllegalArgumentException(variable.name() + + " is not valid at this frame location"); + } + ValueImpl valueImpl; + int ss = variable.slot(); + char c = variable.signature().charAt(0); + BasicType variableType = BasicType.charToBasicType(c); + valueImpl = getSlotValue(values, variableType, ss); + map.put(variable, valueImpl); + } + return map; + } + + public List getArgumentValues() { + validateStackFrame(); + StackValueCollection values = saFrame.getLocals(); + MethodImpl mmm = (MethodImpl)location.method(); + List argSigs = mmm.argumentSignatures(); + int count = argSigs.size(); + List res = new ArrayList(0); + + int slot = mmm.isStatic()? 0 : 1; + for (int ii = 0; ii < count; ++slot, ++ii) { + char sigChar = ((String)argSigs.get(ii)).charAt(0); + BasicType variableType = BasicType.charToBasicType(sigChar); + res.add(getSlotValue(values, variableType, slot)); + if (sigChar == 'J' || sigChar == 'D') { + slot++; + } + } + return res; + } + + private ValueImpl getSlotValue(StackValueCollection values, + BasicType variableType, int ss) { + ValueImpl valueImpl = null; + OopHandle handle = null; + ObjectHeap heap = vm.saObjectHeap(); + if (variableType == BasicType.T_BOOLEAN) { + valueImpl = (BooleanValueImpl) vm.mirrorOf(values.booleanAt(ss)); + } else if (variableType == BasicType.T_CHAR) { + valueImpl = (CharValueImpl) vm.mirrorOf(values.charAt(ss)); + } else if (variableType == BasicType.T_FLOAT) { + valueImpl = (FloatValueImpl) vm.mirrorOf(values.floatAt(ss)); + } else if (variableType == BasicType.T_DOUBLE) { + valueImpl = (DoubleValueImpl) vm.mirrorOf(values.doubleAt(ss)); + } else if (variableType == BasicType.T_BYTE) { + valueImpl = (ByteValueImpl) vm.mirrorOf(values.byteAt(ss)); + } else if (variableType == BasicType.T_SHORT) { + valueImpl = (ShortValueImpl) vm.mirrorOf(values.shortAt(ss)); + } else if (variableType == BasicType.T_INT) { + valueImpl = (IntegerValueImpl) vm.mirrorOf(values.intAt(ss)); + } else if (variableType == BasicType.T_LONG) { + valueImpl = (LongValueImpl) vm.mirrorOf(values.longAt(ss)); + } else if (variableType == BasicType.T_OBJECT) { + // we may have an [Ljava/lang/Object; - i.e., Object[] with the + // elements themselves may be arrays because every array is an Object. + handle = values.oopHandleAt(ss); + valueImpl = (ObjectReferenceImpl) vm.objectMirror(heap.newOop(handle)); + } else if (variableType == BasicType.T_ARRAY) { + handle = values.oopHandleAt(ss); + valueImpl = vm.arrayMirror((Array)heap.newOop(handle)); + } else if (variableType == BasicType.T_VOID) { + valueImpl = new VoidValueImpl(vm); + } else { + throw new RuntimeException("Should not read here"); + } + + return valueImpl; + } + + public void setValue(LocalVariable variableIntf, Value valueIntf) + throws InvalidTypeException, ClassNotLoadedException { + + vm.throwNotReadOnlyException("StackFrame.setValue()"); + } + + public String toString() { + return location.toString() + " in thread " + thread.toString(); + } +}