Path: blob/master/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/RegisterMap.java
62930 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.runtime;2526import java.io.*;27import java.util.*;2829import sun.jvm.hotspot.debugger.*;30import sun.jvm.hotspot.interpreter.*;31import sun.jvm.hotspot.code.*;32import sun.jvm.hotspot.types.*;33import sun.jvm.hotspot.utilities.*;34import sun.jvm.hotspot.utilities.Observable;35import sun.jvm.hotspot.utilities.Observer;3637/** <P> A companion structure used for stack traversal. The38RegisterMap contains misc. information needed in order to do39correct stack traversal of stack frames. Hence, it must always be40passed in as an argument to Frame.sender(RegisterMap). </P>4142<P> The use of RegisterMaps is slightly different in the43Serviceability Agent APIs than in the VM itself. In the VM, a44RegisterMap is created either for a particular thread or cloned45from another RegisterMap. In these APIs, a JavaThread is the46top-level factory for RegisterMaps, and RegisterMaps know how to47copy themselves (through either the clone() or copy()48methods). </P> */4950public abstract class RegisterMap implements Cloneable {51/** Location of registers */52protected Address[] location;53// FIXME: don't know about LocationValidType54protected long[] locationValid;55/** Should include argument_oop marked locations for compiler */56protected boolean includeArgumentOops;57/** Reference to current thread */58protected JavaThread thread;59/** Tells if the register map needs to be updated when traversing the stack */60protected boolean updateMap;61/** Location of a frame where the pc is not at a call (NULL if no frame exists) */62protected static int regCount;63protected static int locationValidTypeSize;64protected static int locationValidSize;6566static {67VM.registerVMInitializedObserver(new Observer() {68public void update(Observable o, Object data) {69initialize(VM.getVM().getTypeDataBase());70}71});72}7374private static void initialize(TypeDataBase db) {75regCount = db.lookupIntConstant("ConcreteRegisterImpl::number_of_registers").intValue();76// FIXME: don't know about LocationValidType. The LocationValidType is typedef'ed as julong77// so used julong to get the size of LocationValidType.78locationValidTypeSize = (int)db.lookupType("julong").getSize() * 8;79locationValidSize = (regCount + locationValidTypeSize - 1) / locationValidTypeSize;80}8182protected RegisterMap(JavaThread thread, boolean updateMap) {83this.thread = thread;84this.updateMap = updateMap;85location = new Address[regCount];86locationValid = new long[locationValidSize];87clear();88}8990/** Makes a copy of map into this */91protected RegisterMap(RegisterMap map) {92if (Assert.ASSERTS_ENABLED) {93Assert.that(map != null, "RegisterMap must be present");94}95this.thread = map.getThread();96this.updateMap = map.getUpdateMap();97this.includeArgumentOops = map.getIncludeArgumentOops();98location = new Address[map.location.length];99locationValid = new long[map.locationValid.length];100initializeFromPD(map);101if (updateMap) {102for (int i = 0; i < locationValidSize; i++) {103long bits = (!getUpdateMap()) ? 0 : map.locationValid[i];104locationValid[i] = bits;105// for whichever bits are set, pull in the corresponding map->_location106int j = i*locationValidTypeSize;107while (bits != 0) {108if ((bits & 1) != 0) {109if (Assert.ASSERTS_ENABLED) {110Assert.that(0 <= j && j < regCount, "range check");111}112location[j] = map.location[j];113}114bits >>>= 1;115j += 1;116}117}118}119}120121public abstract Object clone();122123public RegisterMap copy() {124return (RegisterMap) clone();125}126127public void clear() {128setIncludeArgumentOops(true);129if (!VM.getVM().isCore()) {130if (updateMap) {131for (int i = 0; i < locationValid.length; i++) {132locationValid[i] = 0;133}134clearPD();135} else {136initializePD();137}138}139}140141public Address getLocation(VMReg reg) {142int i = reg.getValue();143int index = i / locationValidTypeSize;144if (Assert.ASSERTS_ENABLED) {145Assert.that(0 <= i && i < regCount, "sanity check");146Assert.that(0 <= index && index < locationValidSize, "sanity check");147}148if ((locationValid[index] & (1 << i % locationValidTypeSize)) != 0) {149return location[i];150} else {151return getLocationPD(reg);152}153}154155public void setLocation(VMReg reg, Address loc) {156int i = reg.getValue();157int index = i / locationValidTypeSize;158if (Assert.ASSERTS_ENABLED) {159Assert.that(0 <= i && i < regCount, "sanity check");160Assert.that(0 <= index && index < locationValidSize, "sanity check");161Assert.that(updateMap, "updating map that does not need updating");162}163location[i] = loc;164locationValid[index] |= (1 << (i % locationValidTypeSize));165}166167public boolean getIncludeArgumentOops() {168return includeArgumentOops;169}170171public void setIncludeArgumentOops(boolean f) {172includeArgumentOops = f;173}174175public JavaThread getThread() {176return thread;177}178179public boolean getUpdateMap() {180return updateMap;181}182183public void print() {184printOn(System.out);185}186187public void printOn(PrintStream tty) {188tty.println("Register map");189for (int i = 0; i < location.length; i++) {190Address src = getLocation(new VMReg(i));191if (src != null) {192tty.print(" " + VMRegImpl.getRegisterName(i) +193" [" + src + "] = ");194if (src.andWithMask(VM.getVM().getAddressSize() - 1) != null) {195tty.print("<misaligned>");196} else {197tty.print(src.getAddressAt(0));198}199}200}201}202203/** Platform-dependent clear() functionality */204protected abstract void clearPD();205/** Platform-dependent initialize() functionality */206protected abstract void initializePD();207/** Platform-dependent initializeFrom() functionality */208protected abstract void initializeFromPD(RegisterMap map);209/** Platform-dependent getLocation() functionality */210protected abstract Address getLocationPD(VMReg reg);211}212213214