Path: blob/master/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/code/Location.java
41161 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.runtime.*;30import sun.jvm.hotspot.types.*;31import sun.jvm.hotspot.utilities.*;32import sun.jvm.hotspot.utilities.Observable;33import sun.jvm.hotspot.utilities.Observer;3435/** <P> A Location describes a concrete machine variable location36(such as integer or floating point register or a stack-held37variable). Used when generating debug-information for38nmethods. </P>3940<P> Encoding: </P>41<PRE>42bits:43Type: [3..0]44Where: [4]45Offset: [31..5]46</PRE>47*/4849public class Location {50static {51VM.registerVMInitializedObserver(new Observer() {52public void update(Observable o, Object data) {53initialize(VM.getVM().getTypeDataBase());54}55});56}5758private static void initialize(TypeDataBase db) {59if (Assert.ASSERTS_ENABLED) {60Assert.that(!VM.getVM().isCore(), "Debug info not used in core build");61}6263OFFSET_MASK = db.lookupIntConstant("Location::OFFSET_MASK").intValue();64OFFSET_SHIFT = db.lookupIntConstant("Location::OFFSET_SHIFT").intValue();65TYPE_MASK = db.lookupIntConstant("Location::TYPE_MASK").intValue();66TYPE_SHIFT = db.lookupIntConstant("Location::TYPE_SHIFT").intValue();67WHERE_MASK = db.lookupIntConstant("Location::WHERE_MASK").intValue();68WHERE_SHIFT = db.lookupIntConstant("Location::WHERE_SHIFT").intValue();6970// Location::Type constants71TYPE_NORMAL = db.lookupIntConstant("Location::normal").intValue();72TYPE_OOP = db.lookupIntConstant("Location::oop").intValue();73TYPE_NARROWOOP = db.lookupIntConstant("Location::narrowoop").intValue();74TYPE_INT_IN_LONG = db.lookupIntConstant("Location::int_in_long").intValue();75TYPE_LNG = db.lookupIntConstant("Location::lng").intValue();76TYPE_FLOAT_IN_DBL = db.lookupIntConstant("Location::float_in_dbl").intValue();77TYPE_DBL = db.lookupIntConstant("Location::dbl").intValue();78TYPE_ADDR = db.lookupIntConstant("Location::addr").intValue();79TYPE_INVALID = db.lookupIntConstant("Location::invalid").intValue();8081// Location::Where constants82WHERE_ON_STACK = db.lookupIntConstant("Location::on_stack").intValue();83WHERE_IN_REGISTER = db.lookupIntConstant("Location::in_register").intValue();84}8586private int value;8788// type safe enum for "Where"89public static class Where {90public static final Where ON_STACK = new Where("on_stack");91public static final Where IN_REGISTER = new Where("in_register");9293private Where(String value) {94this.value = value;95}9697public String toString() {98return value;99}100101private String value;102103public int getValue() {104if (this == ON_STACK) {105return WHERE_ON_STACK;106} else if (this == IN_REGISTER) {107return WHERE_IN_REGISTER;108} else {109throw new RuntimeException("should not reach here");110}111}112}113114// type safe enum for "Type"115public static class Type {116/** Ints, floats, double halves */117public static final Type NORMAL = new Type("normal");118/** Oop (please GC me!) */119public static final Type OOP = new Type("oop");120/** NarrowOop (please GC me!) */121public static final Type NARROWOOP = new Type("narrowoop");122/** Long held in one register */123public static final Type INT_IN_LONG = new Type("int_in_long");124/** Long held in one register */125public static final Type LNG = new Type("lng");126/** Float held in double register */127public static final Type FLOAT_IN_DBL = new Type("float_in_dbl");128/** Double held in one register */129public static final Type DBL = new Type("dbl");130/** JSR return address */131public static final Type ADDR = new Type("addr");132/** Invalid location */133public static final Type INVALID = new Type("invalid");134135private Type(String value) {136this.value = value;137}138private String value;139140public String toString() {141return value;142}143144public int getValue() {145if (this == NORMAL) {146return TYPE_NORMAL;147} else if (this == OOP) {148return TYPE_OOP;149} else if (this == NARROWOOP) {150return TYPE_NARROWOOP;151} else if (this == INT_IN_LONG) {152return TYPE_INT_IN_LONG;153} else if (this == LNG) {154return TYPE_LNG;155} else if (this == FLOAT_IN_DBL) {156return TYPE_FLOAT_IN_DBL;157} else if (this == DBL) {158return TYPE_DBL;159} else if (this == ADDR) {160return TYPE_ADDR;161} else if (this == INVALID) {162return TYPE_INVALID;163} else {164throw new RuntimeException("should not reach here");165}166}167}168169private static int OFFSET_MASK;170private static int OFFSET_SHIFT;171private static int TYPE_MASK;172private static int TYPE_SHIFT;173private static int WHERE_MASK;174private static int WHERE_SHIFT;175176// constants in Type enum177private static int TYPE_NORMAL;178private static int TYPE_OOP;179private static int TYPE_NARROWOOP;180private static int TYPE_INT_IN_LONG;181private static int TYPE_LNG;182private static int TYPE_FLOAT_IN_DBL;183private static int TYPE_DBL;184private static int TYPE_ADDR;185private static int TYPE_INVALID;186187// constants in Where enum188private static int WHERE_ON_STACK;189private static int WHERE_IN_REGISTER;190191/** Create a bit-packed Location */192Location(Where where, Type type, int offset) {193setWhere(where);194setType(type);195setOffset(offset);196}197198public Where getWhere() {199int where = (value & WHERE_MASK) >> WHERE_SHIFT;200if (where == WHERE_ON_STACK) {201return Where.ON_STACK;202} else if (where == WHERE_IN_REGISTER) {203return Where.IN_REGISTER;204} else {205throw new RuntimeException("should not reach here");206}207}208209public Type getType() {210int type = (value & TYPE_MASK) >> TYPE_SHIFT;211if (type == TYPE_NORMAL) {212return Type.NORMAL;213} else if (type == TYPE_OOP) {214return Type.OOP;215} else if (type == TYPE_NARROWOOP) {216return Type.NARROWOOP;217} else if (type == TYPE_INT_IN_LONG) {218return Type.INT_IN_LONG;219} else if (type == TYPE_LNG) {220return Type.LNG;221} else if (type == TYPE_FLOAT_IN_DBL) {222return Type.FLOAT_IN_DBL;223} else if (type == TYPE_DBL) {224return Type.DBL;225} else if (type == TYPE_ADDR) {226return Type.ADDR;227} else if (type == TYPE_INVALID) {228return Type.INVALID;229} else {230throw new RuntimeException("should not reach here");231}232}233234public short getOffset() {235return (short) ((value & OFFSET_MASK) >> OFFSET_SHIFT);236}237238public boolean isRegister() {239return getWhere() == Where.IN_REGISTER;240}241242public boolean isStack() {243return getWhere() == Where.ON_STACK;244}245246public boolean holdsOop() {247return getType() == Type.OOP;248}249250public boolean holdsNarrowOop() {251return getType() == Type.NARROWOOP;252}253254public boolean holdsInt() {255return getType() == Type.INT_IN_LONG;256}257258public boolean holdsLong() {259return getType() == Type.LNG;260}261262public boolean holdsFloat() {263return getType() == Type.FLOAT_IN_DBL;264}265266public boolean holdsDouble() {267return getType() == Type.DBL;268}269270public boolean holdsAddr() {271return getType() == Type.ADDR;272}273274public boolean isIllegal() {275return getType() == Type.INVALID;276}277278public int getStackOffset() {279if (Assert.ASSERTS_ENABLED) {280Assert.that(getWhere() == Where.ON_STACK, "wrong Where");281}282return getOffset() * (int)VM.getVM().getIntSize();283}284285public int getRegisterNumber() {286if (Assert.ASSERTS_ENABLED) {287Assert.that(getWhere() == Where.IN_REGISTER, "wrong Where");288}289return getOffset();290}291292public void print() {293printOn(System.out);294}295296public void printOn(PrintStream tty) {297tty.print("Value " + value + ", ");298if (isIllegal()) {299tty.print("Illegal");300} else {301Where w = getWhere();302if (w == Where.ON_STACK) {303tty.print("stack[" + getStackOffset() + "]");304} else if (w == Where.IN_REGISTER) {305tty.print("reg " + getRegisterNumber());306}307308Type type = getType();309if (type == Type.NORMAL) {310} else if (type == Type.OOP) {311tty.print(",oop");312} else if (type == Type.NARROWOOP) {313tty.print(",narrowoop");314} else if (type == Type.INT_IN_LONG) {315tty.print(",int");316} else if (type == Type.LNG) {317tty.print(",long");318} else if (type == Type.FLOAT_IN_DBL) {319tty.print(",float");320} else if (type == Type.DBL) {321tty.print(",double");322} else if (type == Type.ADDR) {323tty.print(",address");324} else if (type == Type.INVALID) {325tty.print(",invalid");326}327}328}329330/** Serialization of debugging information */331public Location(DebugInfoReadStream stream) {332value = stream.readInt();333}334335// FIXME: not yet implementable336// void write_on(DebugInfoWriteStream* stream);337338339//-----------------------------------------------------------------------------340// Internals only below this point341//342343private void setWhere(Where where) {344value |= ((where.getValue() << WHERE_SHIFT) & WHERE_MASK);345}346347private void setType(Type type) {348value |= ((type.getValue() << TYPE_SHIFT) & TYPE_MASK);349}350351private void setOffset(int offset) {352value |= ((offset << OFFSET_SHIFT) & OFFSET_MASK);353}354}355356357