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
25package sun.jvm.hotspot.utilities;
26
27import sun.jvm.hotspot.code.*;
28import sun.jvm.hotspot.debugger.*;
29import sun.jvm.hotspot.gc.shared.*;
30import sun.jvm.hotspot.interpreter.*;
31import sun.jvm.hotspot.runtime.*;
32import sun.jvm.hotspot.memory.*;
33
34/** This class, only intended for use in the debugging system,
35    provides the functionality of find() in the VM. */
36
37public class PointerFinder {
38  public static PointerLocation find(Address a) {
39    PointerLocation loc = new PointerLocation(a);
40
41    CollectedHeap heap = VM.getVM().getUniverse().heap();
42    if (heap instanceof GenCollectedHeap) {
43      GenCollectedHeap genheap = (GenCollectedHeap) heap;
44      if (genheap.isIn(a)) {
45        for (int i = 0; i < genheap.nGens(); i++) {
46          Generation g = genheap.getGen(i);
47          if (g.isIn(a)) {
48            loc.gen = g;
49            break;
50          }
51        }
52
53          if (Assert.ASSERTS_ENABLED) {
54          Assert.that(loc.gen != null, "Should have found this in a generation");
55        }
56
57        if (VM.getVM().getUseTLAB()) {
58          // Try to find thread containing it
59          for (JavaThread t = VM.getVM().getThreads().first(); t != null; t = t.next()) {
60            ThreadLocalAllocBuffer tlab = t.tlab();
61            if (tlab.contains(a)) {
62              loc.inTLAB = true;
63              loc.tlabThread = t;
64              loc.tlab = tlab;
65              break;
66            }
67          }
68        }
69
70        return loc;
71      }
72    } else {
73      if (heap.isIn(a)) {
74        loc.heap = heap;
75        return loc;
76      }
77    }
78
79    Interpreter interp = VM.getVM().getInterpreter();
80    if (interp.contains(a)) {
81      loc.inInterpreter = true;
82      loc.interpreterCodelet = interp.getCodeletContaining(a);
83      return loc;
84    }
85
86    if (!VM.getVM().isCore()) {
87      CodeCache c = VM.getVM().getCodeCache();
88      if (c.contains(a)) {
89        loc.inCodeCache = true;
90        loc.blob = c.findBlobUnsafe(a);
91        if (Assert.ASSERTS_ENABLED) {
92          Assert.that(loc.blob != null, "Should have found CodeBlob");
93        }
94        loc.inBlobCode = loc.blob.codeContains(a);
95        loc.inBlobData = loc.blob.dataContains(a);
96
97        if (loc.blob.isNMethod()) {
98            NMethod nm = (NMethod) loc.blob;
99            loc.inBlobOops = nm.oopsContains(a);
100        }
101
102        loc.inBlobUnknownLocation = (!(loc.inBlobCode ||
103                                       loc.inBlobData ||
104                                       loc.inBlobOops));
105        return loc;
106      }
107    }
108
109    // Check JNIHandles; both local and global
110    JNIHandles handles = VM.getVM().getJNIHandles();
111    JNIHandleBlock handleBlock = handles.globalHandles();
112    if (handleBlock != null) {
113      handleBlock = handleBlock.blockContainingHandle(a);
114    }
115    if (handleBlock != null) {
116      loc.inStrongGlobalJNIHandleBlock = true;
117      loc.handleBlock = handleBlock;
118      return loc;
119    } else {
120      handleBlock = handles.weakGlobalHandles();
121      if (handleBlock != null) {
122        handleBlock = handleBlock.blockContainingHandle(a);
123        if (handleBlock != null) {
124          loc.inWeakGlobalJNIHandleBlock = true;
125          loc.handleBlock = handleBlock;
126          return loc;
127        } else {
128          // Look in thread-local handles
129          for (JavaThread t = VM.getVM().getThreads().first(); t != null; t = t.next()) {
130            handleBlock = t.activeHandles();
131            if (handleBlock != null) {
132              handleBlock = handleBlock.blockContainingHandle(a);
133              if (handleBlock != null) {
134                loc.inLocalJNIHandleBlock = true;
135                loc.handleBlock = handleBlock;
136                loc.handleThread = t;
137                return loc;
138              }
139            }
140          }
141        }
142      }
143    }
144
145
146    // Fall through; have to return it anyway.
147    return loc;
148  }
149}
150