Path: blob/master/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/utilities/PointerLocation.java
41161 views
/*1* Copyright (c) 2000, 2021, 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.utilities;2526import java.io.*;27import sun.jvm.hotspot.code.*;28import sun.jvm.hotspot.debugger.*;29import sun.jvm.hotspot.debugger.cdbg.*;30import sun.jvm.hotspot.gc.shared.*;31import sun.jvm.hotspot.interpreter.*;32import sun.jvm.hotspot.memory.*;33import sun.jvm.hotspot.oops.Metadata;34import sun.jvm.hotspot.runtime.*;35import sun.jvm.hotspot.types.Type;3637/** This class attempts to describe possible locations of pointers in38the VM. */3940public class PointerLocation {41//////////////////////////////////////////////////////////////////42// //43// These are package private to simplify the implementation and //44// interaction with PointerFinder //45// //46//////////////////////////////////////////////////////////////////4748Address addr;4950Metadata metadata;51Type ctype;52JavaThread stackThread;5354LoadObject loadObject;55ClosestSymbol nativeSymbol;5657CollectedHeap heap;58Generation gen;5960// If UseTLAB was enabled and the pointer was found in a61// currently-active TLAB, these will be set62boolean inTLAB;63JavaThread tlabThread;64ThreadLocalAllocBuffer tlab;6566// Generated code locations67boolean inInterpreter;68boolean inCodeCache;6970// FIXME: add other locations like VTableStubs, StubRoutines, maybe71// even "on thread x's stack"7273InterpreterCodelet interpreterCodelet;74CodeBlob blob;75// FIXME: add more detail about CodeBlob76boolean inBlobCode;77boolean inBlobData;78boolean inBlobOops;79boolean inBlobUnknownLocation;8081boolean inStrongGlobalJNIHandles;82boolean inWeakGlobalJNIHandles;8384boolean inLocalJNIHandleBlock;85JNIHandleBlock handleBlock;86sun.jvm.hotspot.runtime.Thread handleThread;8788public PointerLocation(Address addr) {89this.addr = addr;90}9192public boolean isMetadata() {93return metadata != null;94}9596public boolean isCtype() {97return ctype != null;98}99100public boolean isInJavaStack() {101return stackThread != null;102}103104public boolean isNativeSymbol() {105return loadObject != null;106}107108public boolean isInHeap() {109return (heap != null || (gen != null));110}111112public boolean isInNewGen() {113return ((gen != null) && (gen == ((GenCollectedHeap)heap).getGen(0)));114}115116public boolean isInOldGen() {117return ((gen != null) && (gen == ((GenCollectedHeap)heap).getGen(1)));118}119120public boolean inOtherGen() {121return (!isInNewGen() && !isInOldGen());122}123124/** Only valid if isInHeap() */125public Generation getGeneration() {126return gen;127}128129/** This may be true if isInNewGen is also true */130public boolean isInTLAB() {131return inTLAB;132}133134/** Only valid if isInTLAB() returns true */135public JavaThread getTLABThread() {136return tlabThread;137}138139/** Only valid if isInTLAB() returns true */140public ThreadLocalAllocBuffer getTLAB() {141return tlab;142}143144public boolean isInInterpreter() {145return inInterpreter;146}147148/** For now, only valid if isInInterpreter is true */149public InterpreterCodelet getInterpreterCodelet() {150return interpreterCodelet;151}152153public boolean isInCodeCache() {154return inCodeCache;155}156157/** For now, only valid if isInCodeCache is true */158public CodeBlob getCodeBlob() {159return blob;160}161162public boolean isInBlobCode() {163return inBlobCode;164}165166public boolean isInBlobData() {167return inBlobData;168}169170public boolean isInBlobOops() {171return inBlobOops;172}173174public boolean isInBlobUnknownLocation() {175return inBlobUnknownLocation;176}177178public boolean isInStrongGlobalJNIHandles() {179return inStrongGlobalJNIHandles;180}181182public boolean isInWeakGlobalJNIHandles() {183return inWeakGlobalJNIHandles;184}185186public boolean isInLocalJNIHandleBlock() {187return inLocalJNIHandleBlock;188}189190/** Only valid if isInLocalJNIHandleBlock is true */191public JNIHandleBlock getJNIHandleBlock() {192assert isInLocalJNIHandleBlock();193return handleBlock;194}195196/** Only valid if isInLocalJNIHandleBlock is true */197public sun.jvm.hotspot.runtime.Thread getJNIHandleThread() {198assert isInLocalJNIHandleBlock();199return handleThread;200}201202public boolean isUnknown() {203return (!(isMetadata() || isCtype() || isInJavaStack() || isNativeSymbol() || isInHeap() ||204isInInterpreter() || isInCodeCache() || isInStrongGlobalJNIHandles() ||205isInWeakGlobalJNIHandles() || isInLocalJNIHandleBlock()));206}207208public String toString() {209ByteArrayOutputStream bos = new ByteArrayOutputStream();210printOn(new PrintStream(bos));211return bos.toString();212}213214public void print() {215printOn(System.out, true, true);216}217218public void print(boolean printAddress, boolean verbose) {219printOn(System.out, printAddress, verbose);220}221222public void printOn(PrintStream tty) {223printOn(tty, true, true);224}225226public void printOn(PrintStream tty, boolean printAddress, boolean verbose) {227if (printAddress) {228tty.print("Address ");229if (addr == null) {230tty.print("0x0");231} else {232tty.print(addr.toString());233}234tty.print(": ");235}236if (isMetadata()) {237metadata.printValueOn(tty); // does not include "\n"238tty.println();239} else if (isCtype()) {240tty.println("Is of type " + ctype.getName());241} else if (isInJavaStack()) {242if (verbose) {243tty.format("In java stack [%s,%s,%s] for thread %s:\n ",244stackThread.getStackBase(), stackThread.lastSPDbg(),245stackThread.getStackBase().addOffsetTo(-stackThread.getStackSize()),246stackThread);247stackThread.printThreadInfoOn(tty); // includes "\n"248} else {249tty.format("In java stack for thread \"%s\" %s\n", stackThread.getThreadName(), stackThread);250}251} else if (isNativeSymbol()) {252CDebugger cdbg = VM.getVM().getDebugger().getCDebugger();253long diff;254if (nativeSymbol != null) {255String name = nativeSymbol.getName();256if (cdbg.canDemangle()) {257name = cdbg.demangle(name);258}259tty.print(name);260diff = nativeSymbol.getOffset();261} else {262tty.print(loadObject.getName());263diff = addr.minus(loadObject.getBase());264}265if (diff != 0L) {266tty.print(" + 0x" + Long.toHexString(diff));267}268tty.println();269} else if (isInHeap()) {270if (isInTLAB()) {271tty.print("In thread-local allocation buffer for thread (");272getTLABThread().printThreadInfoOn(tty);273tty.print(") ");274getTLAB().printOn(tty); // includes "\n"275} else {276if (isInNewGen()) {277tty.print("In new generation ");278} else if (isInOldGen()) {279tty.print("In old generation ");280} else {281tty.print("In unknown section of Java heap");282}283if (getGeneration() != null) {284getGeneration().printOn(tty); // does not include "\n"285}286tty.println();287}288} else if (isInInterpreter()) {289tty.print("In interpreter codelet: ");290interpreterCodelet.printOn(tty); // includes "\n"291} else if (isInCodeCache()) {292// TODO: print the type of CodeBlob. See "look for known code blobs" comment293// in PStack.java for example code.294CodeBlob b = getCodeBlob();295tty.print("In ");296if (isInBlobCode()) {297tty.print("code");298} else if (isInBlobData()) {299tty.print("data");300} else if (isInBlobOops()) {301tty.print("oops");302} else {303if (Assert.ASSERTS_ENABLED) {304Assert.that(isInBlobUnknownLocation(), "Should have known location in CodeBlob");305}306tty.print("unknown location");307}308tty.print(" in ");309if (verbose) {310b.printOn(tty); // includes "\n"311} else {312tty.println(b.toString());313}314315// FIXME: add more detail316} else if (isInStrongGlobalJNIHandles()) {317tty.println("In JNI strong global");318} else if (isInWeakGlobalJNIHandles()) {319tty.println("In JNI weak global");320} else if (isInLocalJNIHandleBlock()) {321tty.print("In thread-local");322tty.print(" JNI handle block (" + handleBlock.top() + " handle slots present)");323if (handleThread.isJavaThread()) {324tty.print(" for JavaThread ");325((JavaThread) handleThread).printThreadIDOn(tty); // includes "\n"326} else {327tty.println(" for a non-Java Thread");328}329} else {330// This must be last331if (Assert.ASSERTS_ENABLED) {332Assert.that(isUnknown(), "Should have unknown location");333}334tty.println("In unknown location");335}336}337}338339340