Path: blob/master/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/code/ScopeDesc.java
41171 views
/*1* Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*22*/2324package sun.jvm.hotspot.code;2526import java.io.*;27import java.util.*;2829import sun.jvm.hotspot.debugger.*;30import sun.jvm.hotspot.oops.*;31import sun.jvm.hotspot.runtime.*;32import sun.jvm.hotspot.utilities.*;3334/** ScopeDescs contain the information that makes source-level35debugging of nmethods possible; each scopeDesc describes a method36activation */3738public class ScopeDesc {39/** NMethod information */40private NMethod code;41private Method method;42private int bci;43private boolean reexecute;44/** Decoding offsets */45private int decodeOffset;46private int senderDecodeOffset;47private int localsDecodeOffset;48private int expressionsDecodeOffset;49private int monitorsDecodeOffset;50/** Scalar replaced bjects pool */51private List<ObjectValue> objects;5253private ScopeDesc(NMethod code, int decodeOffset, List<ObjectValue> objects, boolean reexecute) {54this.code = code;55this.decodeOffset = decodeOffset;56this.objects = objects;57this.reexecute = reexecute;5859// Decode header60DebugInfoReadStream stream = streamAt(decodeOffset);6162senderDecodeOffset = stream.readInt();63method = stream.readMethod();64bci = stream.readBCI();65// Decode offsets for body and sender66localsDecodeOffset = stream.readInt();67expressionsDecodeOffset = stream.readInt();68monitorsDecodeOffset = stream.readInt();69}7071public ScopeDesc(NMethod code, int decodeOffset, int objectDecodeOffset, boolean reexecute) {72this.code = code;73this.decodeOffset = decodeOffset;74this.objects = decodeObjectValues(objectDecodeOffset);75this.reexecute = reexecute;7677// Decode header78DebugInfoReadStream stream = streamAt(decodeOffset);7980senderDecodeOffset = stream.readInt();81method = stream.readMethod();82bci = stream.readBCI();83// Decode offsets for body and sender84localsDecodeOffset = stream.readInt();85expressionsDecodeOffset = stream.readInt();86monitorsDecodeOffset = stream.readInt();87}8889public NMethod getNMethod() { return code; }90public Method getMethod() { return method; }91public int getBCI() { return bci; }92public boolean getReexecute() { return reexecute;}9394/** Returns a List<ScopeValue> */95public List<ScopeValue> getLocals() {96return decodeScopeValues(localsDecodeOffset);97}9899/** Returns a List<ScopeValue> */100public List<ScopeValue> getExpressions() {101return decodeScopeValues(expressionsDecodeOffset);102}103104/** Returns a List<MonitorValue> */105public List<MonitorValue> getMonitors() {106return decodeMonitorValues(monitorsDecodeOffset);107}108109/** Returns a List<ObjectValue> */110public List<ObjectValue> getObjects() {111return objects;112}113114/** Stack walking. Returns null if this is the outermost scope. */115public ScopeDesc sender() {116if (isTop()) {117return null;118}119120return new ScopeDesc(code, senderDecodeOffset, objects, false);121}122123/** Returns where the scope was decoded */124public int getDecodeOffset() {125return decodeOffset;126}127128/** Tells whether sender() returns null */129public boolean isTop() {130return (senderDecodeOffset == DebugInformationRecorder.SERIALIZED_NULL);131}132133public boolean equals(Object arg) {134if (arg == null) {135return false;136}137138if (!(arg instanceof ScopeDesc)) {139return false;140}141142ScopeDesc sd = (ScopeDesc) arg;143144return (sd.method.equals(method) && (sd.bci == bci));145}146147public void printValue() {148printValueOn(System.out);149}150151public void printValueOn(PrintStream tty) {152tty.print("ScopeDesc for ");153method.printValueOn(tty);154tty.print(" @bci " + bci);155tty.println(" reexecute=" + reexecute);156}157158// FIXME: add more accessors159160//--------------------------------------------------------------------------------161// Internals only below this point162//163private DebugInfoReadStream streamAt(int decodeOffset) {164return new DebugInfoReadStream(code, decodeOffset, objects);165}166167/** Returns a List<ScopeValue> or null if no values were present */168private List<ScopeValue> decodeScopeValues(int decodeOffset) {169if (decodeOffset == DebugInformationRecorder.SERIALIZED_NULL) {170return null;171}172DebugInfoReadStream stream = streamAt(decodeOffset);173int length = stream.readInt();174List<ScopeValue> res = new ArrayList<>(length);175for (int i = 0; i < length; i++) {176res.add(ScopeValue.readFrom(stream));177}178return res;179}180181/** Returns a List<MonitorValue> or null if no values were present */182private List<MonitorValue> decodeMonitorValues(int decodeOffset) {183if (decodeOffset == DebugInformationRecorder.SERIALIZED_NULL) {184return null;185}186DebugInfoReadStream stream = streamAt(decodeOffset);187int length = stream.readInt();188List<MonitorValue> res = new ArrayList<>(length);189for (int i = 0; i < length; i++) {190res.add(new MonitorValue(stream));191}192return res;193}194195/** Returns a List<ObjectValue> or null if no values were present */196private List<ObjectValue> decodeObjectValues(int decodeOffset) {197if (decodeOffset == DebugInformationRecorder.SERIALIZED_NULL) {198return null;199}200List<ObjectValue> res = new ArrayList<>();201DebugInfoReadStream stream = new DebugInfoReadStream(code, decodeOffset, res);202int length = stream.readInt();203for (int i = 0; i < length; i++) {204// Objects values are pushed to 'res' array during read so that205// object's fields could reference it (OBJECT_ID_CODE).206ScopeValue.readFrom(stream);207// res.add(ScopeValue.readFrom(stream));208}209Assert.that(res.size() == length, "inconsistent debug information");210return res;211}212}213214215