1 /* 2 * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 * 23 */ 24 25 package sun.jvm.hotspot.utilities; 26 27 import java.io.*; 28 import sun.jvm.hotspot.code.*; 29 import sun.jvm.hotspot.debugger.*; 30 import sun.jvm.hotspot.gc.shared.*; 31 import sun.jvm.hotspot.interpreter.*; 32 import sun.jvm.hotspot.runtime.*; 33 import sun.jvm.hotspot.memory.*; 34 35 /** This class attempts to describe possible locations of pointers in 36 the VM. */ 37 38 public class PointerLocation { 39 ////////////////////////////////////////////////////////////////// 40 // // 41 // These are package private to simplify the implementation and // 42 // interaction with PointerFinder // 43 // // 44 ////////////////////////////////////////////////////////////////// 45 46 Address addr; 47 48 CollectedHeap heap; 49 Generation gen; 50 51 // If UseTLAB was enabled and the pointer was found in a 52 // currently-active TLAB, these will be set 53 boolean inTLAB; 54 JavaThread tlabThread; 55 ThreadLocalAllocBuffer tlab; 56 57 // Generated code locations 58 boolean inInterpreter; 59 boolean inCodeCache; 60 61 // FIXME: add other locations like VTableStubs, StubRoutines, maybe 62 // even "on thread x's stack" 63 64 InterpreterCodelet interpreterCodelet; 65 CodeBlob blob; 66 // FIXME: add more detail about CodeBlob 67 boolean inBlobCode; 68 boolean inBlobData; 69 boolean inBlobOops; 70 boolean inBlobUnknownLocation; 71 72 boolean inStrongGlobalJNIHandleBlock; 73 boolean inWeakGlobalJNIHandleBlock; 74 boolean inLocalJNIHandleBlock; 75 JNIHandleBlock handleBlock; 76 sun.jvm.hotspot.runtime.Thread handleThread; 77 78 public PointerLocation(Address addr) { 79 this.addr = addr; 80 } 81 82 public boolean isInHeap() { 83 return (heap != null || (gen != null)); 84 } 85 86 public boolean isInNewGen() { 87 return ((gen != null) && (gen.level() == 0)); 88 } 89 90 public boolean isInOldGen() { 91 return ((gen != null) && (gen.level() == 1)); 92 } 93 94 public boolean inOtherGen() { 95 return (!isInNewGen() && !isInOldGen()); 96 } 97 98 /** Only valid if isInHeap() */ 99 public Generation getGeneration() { 100 return gen; 101 } 102 103 /** This may be true if isInNewGen is also true */ 104 public boolean isInTLAB() { 105 return inTLAB; 106 } 107 108 /** Only valid if isInTLAB() returns true */ 109 public JavaThread getTLABThread() { 110 return tlabThread; 111 } 112 113 /** Only valid if isInTLAB() returns true */ 114 public ThreadLocalAllocBuffer getTLAB() { 115 return tlab; 116 } 117 118 public boolean isInInterpreter() { 119 return inInterpreter; 120 } 121 122 /** For now, only valid if isInInterpreter is true */ 123 public InterpreterCodelet getInterpreterCodelet() { 124 return interpreterCodelet; 125 } 126 127 public boolean isInCodeCache() { 128 return inCodeCache; 129 } 130 131 /** For now, only valid if isInCodeCache is true */ 132 public CodeBlob getCodeBlob() { 133 return blob; 134 } 135 136 public boolean isInBlobCode() { 137 return inBlobCode; 138 } 139 140 public boolean isInBlobData() { 141 return inBlobData; 142 } 143 144 public boolean isInBlobOops() { 145 return inBlobOops; 146 } 147 148 public boolean isInBlobUnknownLocation() { 149 return inBlobUnknownLocation; 150 } 151 152 public boolean isInStrongGlobalJNIHandleBlock() { 153 return inStrongGlobalJNIHandleBlock; 154 } 155 156 public boolean isInWeakGlobalJNIHandleBlock() { 157 return inWeakGlobalJNIHandleBlock; 158 } 159 160 public boolean isInLocalJNIHandleBlock() { 161 return inLocalJNIHandleBlock; 162 } 163 164 /** Only valid if isInStrongGlobalJNIHandleBlock, 165 isInWeakGlobalJNIHandleBlock, or isInLocalJNIHandleBlock is true */ 166 public JNIHandleBlock getJNIHandleBlock() { 167 return handleBlock; 168 } 169 170 /** Only valid if isInLocalJNIHandleBlock is true */ 171 public sun.jvm.hotspot.runtime.Thread getJNIHandleThread() { 172 return handleThread; 173 } 174 175 public boolean isUnknown() { 176 return (!(isInHeap() || isInInterpreter() || isInCodeCache() || 177 isInStrongGlobalJNIHandleBlock() || isInWeakGlobalJNIHandleBlock() || isInLocalJNIHandleBlock())); 178 } 179 180 public String toString() { 181 ByteArrayOutputStream bos = new ByteArrayOutputStream(); 182 printOn(new PrintStream(bos)); 183 return bos.toString(); 184 } 185 186 public void print() { 187 printOn(System.out); 188 } 189 190 public void printOn(PrintStream tty) { 191 tty.print("Address "); 192 if (addr == null) { 193 tty.print("0x0"); 194 } else { 195 tty.print(addr.toString()); 196 } 197 tty.print(": "); 198 if (isInHeap()) { 199 if (isInTLAB()) { 200 tty.print("In thread-local allocation buffer for thread \"" + 201 getTLABThread().getThreadName() + "\" ("); 202 getTLABThread().printThreadIDOn(tty); 203 tty.print(") "); 204 getTLAB().printOn(tty); 205 } else { 206 if (isInNewGen()) { 207 tty.print("In new generation "); 208 } else if (isInOldGen()) { 209 tty.print("In old generation "); 210 } else if (gen != null) { 211 tty.print("In Generation " + getGeneration().level()); 212 } else { 213 tty.print("In unknown section of Java heap"); 214 } 215 if (getGeneration() != null) { 216 getGeneration().printOn(tty); 217 } 218 } 219 } else if (isInInterpreter()) { 220 tty.println("In interpreter codelet \"" + interpreterCodelet.getDescription() + "\""); 221 interpreterCodelet.printOn(tty); 222 } else if (isInCodeCache()) { 223 CodeBlob b = getCodeBlob(); 224 tty.print("In "); 225 if (isInBlobCode()) { 226 tty.print("code"); 227 } else if (isInBlobData()) { 228 tty.print("data"); 229 } else if (isInBlobOops()) { 230 tty.print("oops"); 231 } else { 232 if (Assert.ASSERTS_ENABLED) { 233 Assert.that(isInBlobUnknownLocation(), "Should have known location in CodeBlob"); 234 } 235 tty.print("unknown location"); 236 } 237 tty.print(" in "); 238 b.printOn(tty); 239 240 // FIXME: add more detail 241 } else if (isInStrongGlobalJNIHandleBlock() || 242 isInWeakGlobalJNIHandleBlock() || 243 isInLocalJNIHandleBlock()) { 244 tty.print("In "); 245 if (isInStrongGlobalJNIHandleBlock()) { 246 tty.print("strong global"); 247 } else if (isInWeakGlobalJNIHandleBlock()) { 248 tty.print("weak global"); 249 } else { 250 tty.print("thread-local"); 251 } 252 tty.print(" JNI handle block (" + handleBlock.top() + " handle slots present)"); 253 if (isInLocalJNIHandleBlock()) { 254 if (handleThread.isJavaThread()) { 255 tty.print(" for JavaThread "); 256 ((JavaThread) handleThread).printThreadIDOn(tty); 257 } else { 258 tty.print("for a non-Java Thread"); 259 } 260 } 261 } else { 262 // This must be last 263 if (Assert.ASSERTS_ENABLED) { 264 Assert.that(isUnknown(), "Should have unknown location"); 265 } 266 tty.print("In unknown location"); 267 } 268 } 269 }