Mercurial > hg > truffle
view agent/src/share/classes/sun/jvm/hotspot/jdi/StackFrameImpl.java @ 19491:4d66c000d253
Truffle/Instrumentation: more cleanup in Probe
author | Michael Van De Vanter <michael.van.de.vanter@oracle.com> |
---|---|
date | Wed, 18 Feb 2015 18:30:49 -0800 |
parents | 7588156f5cf9 |
children |
line wrap: on
line source
/* * Copyright (c) 2002, 2005, 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 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. if (values.get(0).getType() == BasicType.getTConflict()) { return null; } 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(); if (mmm.isNative()) return null; 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 (values.get(ss).getType() == BasicType.getTConflict()) { // Dead locals, so just represent them as a zero of the appropriate type if (variableType == BasicType.T_BOOLEAN) { valueImpl = (BooleanValueImpl) vm.mirrorOf(false); } else if (variableType == BasicType.T_CHAR) { valueImpl = (CharValueImpl) vm.mirrorOf((char)0); } else if (variableType == BasicType.T_FLOAT) { valueImpl = (FloatValueImpl) vm.mirrorOf((float)0); } else if (variableType == BasicType.T_DOUBLE) { valueImpl = (DoubleValueImpl) vm.mirrorOf((double)0); } else if (variableType == BasicType.T_BYTE) { valueImpl = (ByteValueImpl) vm.mirrorOf((byte)0); } else if (variableType == BasicType.T_SHORT) { valueImpl = (ShortValueImpl) vm.mirrorOf((short)0); } else if (variableType == BasicType.T_INT) { valueImpl = (IntegerValueImpl) vm.mirrorOf((int)0); } else if (variableType == BasicType.T_LONG) { valueImpl = (LongValueImpl) vm.mirrorOf((long)0); } 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 = null; valueImpl = (ObjectReferenceImpl) vm.objectMirror(heap.newOop(handle)); } else if (variableType == BasicType.T_ARRAY) { handle = null; 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"); } } else { 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(); } }