Print this page
Split |
Close |
Expand all |
Collapse all |
--- old/agent/src/share/classes/sun/jvm/hotspot/code/CodeCache.java
+++ new/agent/src/share/classes/sun/jvm/hotspot/code/CodeCache.java
1 1 /*
2 2 * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
3 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 4 *
5 5 * This code is free software; you can redistribute it and/or modify it
6 6 * under the terms of the GNU General Public License version 2 only, as
7 7 * published by the Free Software Foundation.
8 8 *
9 9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 12 * version 2 for more details (a copy is included in the LICENSE file that
13 13 * accompanied this code).
14 14 *
15 15 * You should have received a copy of the GNU General Public License version
16 16 * 2 along with this work; if not, write to the Free Software Foundation,
17 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 18 *
19 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 20 * or visit www.oracle.com if you need additional information or have any
21 21 * questions.
22 22 *
23 23 */
24 24
25 25 package sun.jvm.hotspot.code;
26 26
27 27 import java.util.*;
28 28 import sun.jvm.hotspot.debugger.*;
29 29 import sun.jvm.hotspot.memory.*;
30 30 import sun.jvm.hotspot.runtime.*;
31 31 import sun.jvm.hotspot.types.*;
32 32 import sun.jvm.hotspot.utilities.*;
33 33
34 34 public class CodeCache {
35 35 private static AddressField heapField;
36 36 private static AddressField scavengeRootNMethodsField;
37 37 private static VirtualConstructor virtualConstructor;
38 38
39 39 private CodeHeap heap;
40 40
41 41 static {
42 42 VM.registerVMInitializedObserver(new Observer() {
43 43 public void update(Observable o, Object data) {
44 44 initialize(VM.getVM().getTypeDataBase());
45 45 }
46 46 });
47 47 }
48 48
49 49 private static synchronized void initialize(TypeDataBase db) {
↓ open down ↓ |
49 lines elided |
↑ open up ↑ |
50 50 Type type = db.lookupType("CodeCache");
51 51
52 52 heapField = type.getAddressField("_heap");
53 53 scavengeRootNMethodsField = type.getAddressField("_scavenge_root_nmethods");
54 54
55 55 virtualConstructor = new VirtualConstructor(db);
56 56 // Add mappings for all possible CodeBlob subclasses
57 57 virtualConstructor.addMapping("BufferBlob", BufferBlob.class);
58 58 virtualConstructor.addMapping("nmethod", NMethod.class);
59 59 virtualConstructor.addMapping("RuntimeStub", RuntimeStub.class);
60 - virtualConstructor.addMapping("RicochetBlob", RicochetBlob.class);
61 60 virtualConstructor.addMapping("AdapterBlob", AdapterBlob.class);
62 61 virtualConstructor.addMapping("MethodHandlesAdapterBlob", MethodHandlesAdapterBlob.class);
63 62 virtualConstructor.addMapping("SafepointBlob", SafepointBlob.class);
64 63 virtualConstructor.addMapping("DeoptimizationBlob", DeoptimizationBlob.class);
65 64 if (VM.getVM().isServerCompiler()) {
66 65 virtualConstructor.addMapping("ExceptionBlob", ExceptionBlob.class);
67 66 virtualConstructor.addMapping("UncommonTrapBlob", UncommonTrapBlob.class);
68 67 }
69 68 }
70 69
71 70 public CodeCache() {
72 71 heap = (CodeHeap) VMObjectFactory.newObject(CodeHeap.class, heapField.getValue());
73 72 }
74 73
75 74 public NMethod scavengeRootMethods() {
76 75 return (NMethod) VMObjectFactory.newObject(NMethod.class, scavengeRootNMethodsField.getValue());
77 76 }
78 77
79 78 public boolean contains(Address p) {
80 79 return getHeap().contains(p);
81 80 }
82 81
83 82 /** When VM.getVM().isDebugging() returns true, this behaves like
84 83 findBlobUnsafe */
85 84 public CodeBlob findBlob(Address start) {
86 85 CodeBlob result = findBlobUnsafe(start);
87 86 if (result == null) return null;
88 87 if (VM.getVM().isDebugging()) {
89 88 return result;
90 89 }
91 90 // We could potientially look up non_entrant methods
92 91 // NOTE: this is effectively a "guarantee", and is slightly different from the one in the VM
93 92 if (Assert.ASSERTS_ENABLED) {
94 93 Assert.that(!(result.isZombie() || result.isLockedByVM()), "unsafe access to zombie method");
95 94 }
96 95 return result;
97 96 }
98 97
99 98 public CodeBlob findBlobUnsafe(Address start) {
100 99 CodeBlob result = null;
101 100
102 101 try {
103 102 result = (CodeBlob) virtualConstructor.instantiateWrapperFor(getHeap().findStart(start));
104 103 }
105 104 catch (WrongTypeException wte) {
106 105 Address cbAddr = null;
107 106 try {
108 107 cbAddr = getHeap().findStart(start);
109 108 }
110 109 catch (Exception findEx) {
111 110 findEx.printStackTrace();
112 111 }
113 112
114 113 String message = "Couldn't deduce type of CodeBlob ";
115 114 if (cbAddr != null) {
116 115 message = message + "@" + cbAddr + " ";
117 116 }
118 117 message = message + "for PC=" + start;
119 118
↓ open down ↓ |
49 lines elided |
↑ open up ↑ |
120 119 throw new RuntimeException(message, wte);
121 120 }
122 121 if (result == null) return null;
123 122 if (Assert.ASSERTS_ENABLED) {
124 123 // The HeapBlock that contains this blob is outside of the blob
125 124 // but it shouldn't be an error to find a blob based on the
126 125 // pointer to the HeapBlock.
127 126 Assert.that(result.blobContains(start) || result.blobContains(start.addOffsetTo(8)),
128 127 "found wrong CodeBlob");
129 128 }
130 - if (result.isRicochetBlob()) {
131 - // This should probably be done for other SingletonBlobs
132 - return VM.getVM().ricochetBlob();
133 - }
134 129 return result;
135 130 }
136 131
137 132 public NMethod findNMethod(Address start) {
138 133 CodeBlob cb = findBlob(start);
139 134 if (Assert.ASSERTS_ENABLED) {
140 135 Assert.that(cb == null || cb.isNMethod(), "did not find an nmethod");
141 136 }
142 137 return (NMethod) cb;
143 138 }
144 139
145 140 public NMethod findNMethodUnsafe(Address start) {
146 141 CodeBlob cb = findBlobUnsafe(start);
147 142 if (Assert.ASSERTS_ENABLED) {
148 143 Assert.that(cb == null || cb.isNMethod(), "did not find an nmethod");
149 144 }
150 145 return (NMethod) cb;
151 146 }
152 147
153 148 /** Routine for instantiating appropriately-typed wrapper for a
154 149 CodeBlob. Used by CodeCache, Runtime1, etc. */
155 150 public CodeBlob createCodeBlobWrapper(Address codeBlobAddr) {
156 151 try {
157 152 return (CodeBlob) virtualConstructor.instantiateWrapperFor(codeBlobAddr);
158 153 }
159 154 catch (Exception e) {
160 155 String message = "Unable to deduce type of CodeBlob from address " + codeBlobAddr +
161 156 " (expected type nmethod, RuntimeStub, ";
162 157 if (VM.getVM().isClientCompiler()) {
163 158 message = message + " or ";
164 159 }
165 160 message = message + "SafepointBlob";
166 161 if (VM.getVM().isServerCompiler()) {
167 162 message = message + ", DeoptimizationBlob, or ExceptionBlob";
168 163 }
169 164 message = message + ")";
170 165 throw new RuntimeException(message);
171 166 }
172 167 }
173 168
174 169 public void iterate(CodeCacheVisitor visitor) {
175 170 CodeHeap heap = getHeap();
176 171 Address ptr = heap.begin();
177 172 Address end = heap.end();
178 173
179 174 visitor.prologue(ptr, end);
180 175 CodeBlob lastBlob = null;
181 176 while (ptr != null && ptr.lessThan(end)) {
182 177 try {
183 178 // Use findStart to get a pointer inside blob other findBlob asserts
184 179 CodeBlob blob = findBlobUnsafe(heap.findStart(ptr));
185 180 if (blob != null) {
186 181 visitor.visit(blob);
187 182 if (blob == lastBlob) {
188 183 throw new InternalError("saw same blob twice");
189 184 }
190 185 lastBlob = blob;
191 186 }
192 187 } catch (RuntimeException e) {
193 188 e.printStackTrace();
194 189 }
195 190 Address next = heap.nextBlock(ptr);
196 191 if (next != null && next.lessThan(ptr)) {
197 192 throw new InternalError("pointer moved backwards");
198 193 }
199 194 ptr = next;
200 195 }
201 196 visitor.epilogue();
202 197 }
203 198
204 199 //--------------------------------------------------------------------------------
205 200 // Internals only below this point
206 201 //
207 202
208 203 private CodeHeap getHeap() {
209 204 return heap;
210 205 }
211 206 }
↓ open down ↓ |
68 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX