Mercurial > hg > graal-jvmci-8
annotate agent/src/share/classes/sun/jvm/hotspot/oops/ObjectHeap.java @ 24234:ea6f94ab283b default tip
Added tag jvmci-0.36 for changeset 8128b98d4736
author | Gilles Duboscq <gilles.m.duboscq@oracle.com> |
---|---|
date | Mon, 18 Sep 2017 18:49:45 +0200 |
parents | 89152779163c |
children |
rev | line source |
---|---|
0 | 1 /* |
17524 | 2 * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. |
0 | 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 * | |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
235
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
235
diff
changeset
|
20 * or visit www.oracle.com if you need additional information or have any |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
235
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
25 // | |
26 // The ObjectHeap is an abstraction over all generations in the VM | |
27 // It gives access to all present objects and classes. | |
28 // | |
29 | |
30 package sun.jvm.hotspot.oops; | |
31 | |
32 import java.util.*; | |
33 | |
34 import sun.jvm.hotspot.debugger.*; | |
35 import sun.jvm.hotspot.gc_interface.*; | |
3972 | 36 import sun.jvm.hotspot.gc_implementation.g1.*; |
0 | 37 import sun.jvm.hotspot.gc_implementation.parallelScavenge.*; |
38 import sun.jvm.hotspot.memory.*; | |
39 import sun.jvm.hotspot.runtime.*; | |
40 import sun.jvm.hotspot.types.*; | |
41 import sun.jvm.hotspot.utilities.*; | |
42 | |
43 public class ObjectHeap { | |
44 | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
45 private static final boolean DEBUG; |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
46 |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
47 static { |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
48 DEBUG = System.getProperty("sun.jvm.hotspot.oops.ObjectHeap.DEBUG") != null; |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
49 } |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
50 |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3972
diff
changeset
|
51 private Address boolArrayKlassHandle; |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3972
diff
changeset
|
52 private Address byteArrayKlassHandle; |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3972
diff
changeset
|
53 private Address charArrayKlassHandle; |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3972
diff
changeset
|
54 private Address intArrayKlassHandle; |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3972
diff
changeset
|
55 private Address shortArrayKlassHandle; |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3972
diff
changeset
|
56 private Address longArrayKlassHandle; |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3972
diff
changeset
|
57 private Address singleArrayKlassHandle; |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3972
diff
changeset
|
58 private Address doubleArrayKlassHandle; |
0 | 59 |
60 private TypeArrayKlass boolArrayKlassObj; | |
61 private TypeArrayKlass byteArrayKlassObj; | |
62 private TypeArrayKlass charArrayKlassObj; | |
63 private TypeArrayKlass intArrayKlassObj; | |
64 private TypeArrayKlass shortArrayKlassObj; | |
65 private TypeArrayKlass longArrayKlassObj; | |
66 private TypeArrayKlass singleArrayKlassObj; | |
67 private TypeArrayKlass doubleArrayKlassObj; | |
68 | |
69 public void initialize(TypeDataBase db) throws WrongTypeException { | |
70 // Lookup the roots in the object hierarchy. | |
71 Type universeType = db.lookupType("Universe"); | |
72 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3972
diff
changeset
|
73 boolArrayKlassHandle = universeType.getAddressField("_boolArrayKlassObj").getValue(); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3972
diff
changeset
|
74 boolArrayKlassObj = new TypeArrayKlass(boolArrayKlassHandle); |
0 | 75 |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3972
diff
changeset
|
76 byteArrayKlassHandle = universeType.getAddressField("_byteArrayKlassObj").getValue(); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3972
diff
changeset
|
77 byteArrayKlassObj = new TypeArrayKlass(byteArrayKlassHandle); |
0 | 78 |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3972
diff
changeset
|
79 charArrayKlassHandle = universeType.getAddressField("_charArrayKlassObj").getValue(); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3972
diff
changeset
|
80 charArrayKlassObj = new TypeArrayKlass(charArrayKlassHandle); |
0 | 81 |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3972
diff
changeset
|
82 intArrayKlassHandle = universeType.getAddressField("_intArrayKlassObj").getValue(); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3972
diff
changeset
|
83 intArrayKlassObj = new TypeArrayKlass(intArrayKlassHandle); |
0 | 84 |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3972
diff
changeset
|
85 shortArrayKlassHandle = universeType.getAddressField("_shortArrayKlassObj").getValue(); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3972
diff
changeset
|
86 shortArrayKlassObj = new TypeArrayKlass(shortArrayKlassHandle); |
0 | 87 |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3972
diff
changeset
|
88 longArrayKlassHandle = universeType.getAddressField("_longArrayKlassObj").getValue(); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3972
diff
changeset
|
89 longArrayKlassObj = new TypeArrayKlass(longArrayKlassHandle); |
0 | 90 |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3972
diff
changeset
|
91 singleArrayKlassHandle = universeType.getAddressField("_singleArrayKlassObj").getValue(); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3972
diff
changeset
|
92 singleArrayKlassObj = new TypeArrayKlass(singleArrayKlassHandle); |
0 | 93 |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3972
diff
changeset
|
94 doubleArrayKlassHandle = universeType.getAddressField("_doubleArrayKlassObj").getValue(); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3972
diff
changeset
|
95 doubleArrayKlassObj = new TypeArrayKlass(doubleArrayKlassHandle); |
0 | 96 } |
97 | |
98 public ObjectHeap(TypeDataBase db) throws WrongTypeException { | |
99 // Get commonly used sizes of basic types | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
100 oopSize = VM.getVM().getOopSize(); |
0 | 101 byteSize = db.getJByteType().getSize(); |
102 charSize = db.getJCharType().getSize(); | |
103 booleanSize = db.getJBooleanType().getSize(); | |
104 intSize = db.getJIntType().getSize(); | |
105 shortSize = db.getJShortType().getSize(); | |
106 longSize = db.getJLongType().getSize(); | |
107 floatSize = db.getJFloatType().getSize(); | |
108 doubleSize = db.getJDoubleType().getSize(); | |
109 | |
110 initialize(db); | |
111 } | |
112 | |
113 /** Comparison operation for oops, either or both of which may be null */ | |
114 public boolean equal(Oop o1, Oop o2) { | |
115 if (o1 != null) return o1.equals(o2); | |
116 return (o2 == null); | |
117 } | |
118 | |
119 // Cached sizes of basic types | |
120 private long oopSize; | |
121 private long byteSize; | |
122 private long charSize; | |
123 private long booleanSize; | |
124 private long intSize; | |
125 private long shortSize; | |
126 private long longSize; | |
127 private long floatSize; | |
128 private long doubleSize; | |
129 | |
130 public long getOopSize() { return oopSize; } | |
131 public long getByteSize() { return byteSize; } | |
132 public long getCharSize() { return charSize; } | |
133 public long getBooleanSize() { return booleanSize; } | |
134 public long getIntSize() { return intSize; } | |
135 public long getShortSize() { return shortSize; } | |
136 public long getLongSize() { return longSize; } | |
137 public long getFloatSize() { return floatSize; } | |
138 public long getDoubleSize() { return doubleSize; } | |
139 | |
140 // Accessors for well-known system classes (from Universe) | |
141 public TypeArrayKlass getBoolArrayKlassObj() { return boolArrayKlassObj; } | |
142 public TypeArrayKlass getByteArrayKlassObj() { return byteArrayKlassObj; } | |
143 public TypeArrayKlass getCharArrayKlassObj() { return charArrayKlassObj; } | |
144 public TypeArrayKlass getIntArrayKlassObj() { return intArrayKlassObj; } | |
145 public TypeArrayKlass getShortArrayKlassObj() { return shortArrayKlassObj; } | |
146 public TypeArrayKlass getLongArrayKlassObj() { return longArrayKlassObj; } | |
147 public TypeArrayKlass getSingleArrayKlassObj() { return singleArrayKlassObj; } | |
148 public TypeArrayKlass getDoubleArrayKlassObj() { return doubleArrayKlassObj; } | |
149 | |
150 /** Takes a BasicType and returns the corresponding primitive array | |
151 klass */ | |
152 public Klass typeArrayKlassObj(int t) { | |
153 if (t == BasicType.getTBoolean()) return getBoolArrayKlassObj(); | |
154 if (t == BasicType.getTChar()) return getCharArrayKlassObj(); | |
155 if (t == BasicType.getTFloat()) return getSingleArrayKlassObj(); | |
156 if (t == BasicType.getTDouble()) return getDoubleArrayKlassObj(); | |
157 if (t == BasicType.getTByte()) return getByteArrayKlassObj(); | |
158 if (t == BasicType.getTShort()) return getShortArrayKlassObj(); | |
159 if (t == BasicType.getTInt()) return getIntArrayKlassObj(); | |
160 if (t == BasicType.getTLong()) return getLongArrayKlassObj(); | |
161 throw new RuntimeException("Illegal basic type " + t); | |
162 } | |
163 | |
164 /** an interface to filter objects while walking heap */ | |
165 public static interface ObjectFilter { | |
166 public boolean canInclude(Oop obj); | |
167 } | |
168 | |
169 /** The base heap iteration mechanism */ | |
170 public void iterate(HeapVisitor visitor) { | |
171 iterateLiveRegions(collectLiveRegions(), visitor, null); | |
172 } | |
173 | |
174 /** iterate objects satisfying a specified ObjectFilter */ | |
175 public void iterate(HeapVisitor visitor, ObjectFilter of) { | |
176 iterateLiveRegions(collectLiveRegions(), visitor, of); | |
177 } | |
178 | |
179 /** iterate objects of given Klass. param 'includeSubtypes' tells whether to | |
180 * include objects of subtypes or not */ | |
181 public void iterateObjectsOfKlass(HeapVisitor visitor, final Klass k, boolean includeSubtypes) { | |
182 if (includeSubtypes) { | |
183 if (k.isFinal()) { | |
184 // do the simpler "exact" klass loop | |
185 iterateExact(visitor, k); | |
186 } else { | |
187 iterateSubtypes(visitor, k); | |
188 } | |
189 } else { | |
190 // there can no object of abstract classes and interfaces | |
191 if (!k.isAbstract() && !k.isInterface()) { | |
192 iterateExact(visitor, k); | |
193 } | |
194 } | |
195 } | |
196 | |
197 /** iterate objects of given Klass (objects of subtypes included) */ | |
198 public void iterateObjectsOfKlass(HeapVisitor visitor, final Klass k) { | |
199 iterateObjectsOfKlass(visitor, k, true); | |
200 } | |
201 | |
202 /** This routine can be used to iterate through the heap at an | |
203 extremely low level (stepping word-by-word) to provide the | |
204 ability to do very low-level debugging */ | |
205 public void iterateRaw(RawHeapVisitor visitor) { | |
206 List liveRegions = collectLiveRegions(); | |
207 | |
208 // Summarize size | |
209 long totalSize = 0; | |
210 for (int i = 0; i < liveRegions.size(); i += 2) { | |
211 Address bottom = (Address) liveRegions.get(i); | |
212 Address top = (Address) liveRegions.get(i+1); | |
213 totalSize += top.minus(bottom); | |
214 } | |
215 visitor.prologue(totalSize); | |
216 | |
217 for (int i = 0; i < liveRegions.size(); i += 2) { | |
218 Address bottom = (Address) liveRegions.get(i); | |
219 Address top = (Address) liveRegions.get(i+1); | |
220 | |
221 // Traverses the space from bottom to top | |
222 while (bottom.lessThan(top)) { | |
223 visitor.visitAddress(bottom); | |
224 bottom = bottom.addOffsetTo(VM.getVM().getAddressSize()); | |
225 } | |
226 } | |
227 | |
228 visitor.epilogue(); | |
229 } | |
230 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3972
diff
changeset
|
231 public boolean isValidMethod(Address handle) { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3972
diff
changeset
|
232 try { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3972
diff
changeset
|
233 Method m = (Method)Metadata.instantiateWrapperFor(handle); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3972
diff
changeset
|
234 return true; |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3972
diff
changeset
|
235 } catch (Exception e) { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3972
diff
changeset
|
236 return false; |
0 | 237 } |
218
a5838065ab24
6620329: jstack prints double native methods on Solaris/sparc
swamyv
parents:
113
diff
changeset
|
238 } |
a5838065ab24
6620329: jstack prints double native methods on Solaris/sparc
swamyv
parents:
113
diff
changeset
|
239 |
0 | 240 // Creates an instance from the Oop hierarchy based based on the handle |
241 public Oop newOop(OopHandle handle) { | |
242 // The only known way to detect the right type of an oop is | |
243 // traversing the class chain until a well-known klass is recognized. | |
244 // A more direct solution would require the klasses to expose | |
245 // the C++ vtbl structure. | |
246 | |
247 // Handle the null reference | |
248 if (handle == null) return null; | |
249 | |
250 // Then check if obj.klass() is one of the root objects | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3972
diff
changeset
|
251 Klass klass = Oop.getKlassForOopHandle(handle); |
0 | 252 if (klass != null) { |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3972
diff
changeset
|
253 if (klass instanceof TypeArrayKlass) return new TypeArray(handle, this); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3972
diff
changeset
|
254 if (klass instanceof ObjArrayKlass) return new ObjArray(handle, this); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3972
diff
changeset
|
255 if (klass instanceof InstanceKlass) return new Instance(handle, this); |
0 | 256 } |
257 | |
218
a5838065ab24
6620329: jstack prints double native methods on Solaris/sparc
swamyv
parents:
113
diff
changeset
|
258 if (DEBUG) { |
a5838065ab24
6620329: jstack prints double native methods on Solaris/sparc
swamyv
parents:
113
diff
changeset
|
259 System.err.println("Unknown oop at " + handle); |
a5838065ab24
6620329: jstack prints double native methods on Solaris/sparc
swamyv
parents:
113
diff
changeset
|
260 System.err.println("Oop's klass is " + klass); |
a5838065ab24
6620329: jstack prints double native methods on Solaris/sparc
swamyv
parents:
113
diff
changeset
|
261 } |
0 | 262 |
263 throw new UnknownOopException(); | |
264 } | |
265 | |
266 // Print all objects in the object heap | |
267 public void print() { | |
268 HeapPrinter printer = new HeapPrinter(System.out); | |
269 iterate(printer); | |
270 } | |
271 | |
272 //--------------------------------------------------------------------------- | |
273 // Internals only below this point | |
274 // | |
275 | |
276 private void iterateExact(HeapVisitor visitor, final Klass k) { | |
277 iterateLiveRegions(collectLiveRegions(), visitor, new ObjectFilter() { | |
278 public boolean canInclude(Oop obj) { | |
279 Klass tk = obj.getKlass(); | |
280 // null Klass is seen sometimes! | |
281 return (tk != null && tk.equals(k)); | |
282 } | |
283 }); | |
284 } | |
285 | |
286 private void iterateSubtypes(HeapVisitor visitor, final Klass k) { | |
287 iterateLiveRegions(collectLiveRegions(), visitor, new ObjectFilter() { | |
288 public boolean canInclude(Oop obj) { | |
289 Klass tk = obj.getKlass(); | |
290 // null Klass is seen sometimes! | |
291 return (tk != null && tk.isSubtypeOf(k)); | |
292 } | |
293 }); | |
294 } | |
295 | |
296 private void iterateLiveRegions(List liveRegions, HeapVisitor visitor, ObjectFilter of) { | |
297 // Summarize size | |
298 long totalSize = 0; | |
299 for (int i = 0; i < liveRegions.size(); i += 2) { | |
300 Address bottom = (Address) liveRegions.get(i); | |
301 Address top = (Address) liveRegions.get(i+1); | |
302 totalSize += top.minus(bottom); | |
303 } | |
304 visitor.prologue(totalSize); | |
305 | |
306 CompactibleFreeListSpace cmsSpaceOld = null; | |
307 CollectedHeap heap = VM.getVM().getUniverse().heap(); | |
308 | |
309 if (heap instanceof GenCollectedHeap) { | |
310 GenCollectedHeap genHeap = (GenCollectedHeap) heap; | |
311 Generation genOld = genHeap.getGen(1); | |
312 if (genOld instanceof ConcurrentMarkSweepGeneration) { | |
313 ConcurrentMarkSweepGeneration concGen = (ConcurrentMarkSweepGeneration)genOld; | |
314 cmsSpaceOld = concGen.cmsSpace(); | |
315 } | |
316 } | |
317 | |
318 for (int i = 0; i < liveRegions.size(); i += 2) { | |
319 Address bottom = (Address) liveRegions.get(i); | |
320 Address top = (Address) liveRegions.get(i+1); | |
321 | |
322 try { | |
323 // Traverses the space from bottom to top | |
324 OopHandle handle = bottom.addOffsetToAsOopHandle(0); | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
325 |
0 | 326 while (handle.lessThan(top)) { |
327 Oop obj = null; | |
328 | |
329 try { | |
330 obj = newOop(handle); | |
331 } catch (UnknownOopException exp) { | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
332 if (DEBUG) { |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
333 throw new RuntimeException(" UnknownOopException " + exp); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
334 } |
0 | 335 } |
336 if (obj == null) { | |
337 //Find the object size using Printezis bits and skip over | |
338 long size = 0; | |
339 | |
340 if ( (cmsSpaceOld != null) && cmsSpaceOld.contains(handle) ){ | |
341 size = cmsSpaceOld.collector().blockSizeUsingPrintezisBits(handle); | |
342 } | |
343 | |
344 if (size <= 0) { | |
345 //Either Printezis bits not set or handle is not in cms space. | |
346 throw new UnknownOopException(); | |
347 } | |
348 | |
349 handle = handle.addOffsetToAsOopHandle(CompactibleFreeListSpace.adjustObjectSizeInBytes(size)); | |
350 continue; | |
351 } | |
352 if (of == null || of.canInclude(obj)) { | |
353 if (visitor.doObj(obj)) { | |
354 // doObj() returns true to abort this loop. | |
355 break; | |
356 } | |
357 } | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3972
diff
changeset
|
358 if ( (cmsSpaceOld != null) && cmsSpaceOld.contains(handle)) { |
0 | 359 handle = handle.addOffsetToAsOopHandle(CompactibleFreeListSpace.adjustObjectSizeInBytes(obj.getObjectSize()) ); |
360 } else { | |
361 handle = handle.addOffsetToAsOopHandle(obj.getObjectSize()); | |
362 } | |
363 } | |
364 } | |
365 catch (AddressException e) { | |
366 // This is okay at the top of these regions | |
13431 | 367 } |
0 | 368 catch (UnknownOopException e) { |
369 // This is okay at the top of these regions | |
370 } | |
371 } | |
372 | |
373 visitor.epilogue(); | |
374 } | |
375 | |
13431 | 376 private void addLiveRegions(String name, List input, List output) { |
0 | 377 for (Iterator itr = input.iterator(); itr.hasNext();) { |
378 MemRegion reg = (MemRegion) itr.next(); | |
379 Address top = reg.end(); | |
380 Address bottom = reg.start(); | |
381 if (Assert.ASSERTS_ENABLED) { | |
382 Assert.that(top != null, "top address in a live region should not be null"); | |
383 } | |
384 if (Assert.ASSERTS_ENABLED) { | |
385 Assert.that(bottom != null, "bottom address in a live region should not be null"); | |
386 } | |
387 output.add(top); | |
388 output.add(bottom); | |
13431 | 389 if (DEBUG) { |
390 System.err.println("Live region: " + name + ": " + bottom + ", " + top); | |
391 } | |
0 | 392 } |
393 } | |
394 | |
395 private class LiveRegionsCollector implements SpaceClosure { | |
396 LiveRegionsCollector(List l) { | |
397 liveRegions = l; | |
398 } | |
399 | |
400 public void doSpace(Space s) { | |
13431 | 401 addLiveRegions(s.toString(), s.getLiveRegions(), liveRegions); |
0 | 402 } |
403 private List liveRegions; | |
404 } | |
405 | |
406 // Returns a List<Address> where the addresses come in pairs. These | |
407 // designate the live regions of the heap. | |
408 private List collectLiveRegions() { | |
409 // We want to iterate through all live portions of the heap, but | |
410 // do not want to abort the heap traversal prematurely if we find | |
411 // a problem (like an allocated but uninitialized object at the | |
412 // top of a generation). To do this we enumerate all generations' | |
413 // bottom and top regions, and factor in TLABs if necessary. | |
414 | |
415 // List<Address>. Addresses come in pairs. | |
416 List liveRegions = new ArrayList(); | |
417 LiveRegionsCollector lrc = new LiveRegionsCollector(liveRegions); | |
418 | |
419 CollectedHeap heap = VM.getVM().getUniverse().heap(); | |
420 | |
421 if (heap instanceof GenCollectedHeap) { | |
422 GenCollectedHeap genHeap = (GenCollectedHeap) heap; | |
423 // Run through all generations, obtaining bottom-top pairs. | |
424 for (int i = 0; i < genHeap.nGens(); i++) { | |
425 Generation gen = genHeap.getGen(i); | |
426 gen.spaceIterate(lrc, true); | |
427 } | |
428 } else if (heap instanceof ParallelScavengeHeap) { | |
429 ParallelScavengeHeap psh = (ParallelScavengeHeap) heap; | |
430 PSYoungGen youngGen = psh.youngGen(); | |
431 // Add eden space | |
13431 | 432 addLiveRegions("eden", youngGen.edenSpace().getLiveRegions(), liveRegions); |
0 | 433 // Add from-space but not to-space |
13431 | 434 addLiveRegions("from", youngGen.fromSpace().getLiveRegions(), liveRegions); |
0 | 435 PSOldGen oldGen = psh.oldGen(); |
13431 | 436 addLiveRegions("old ", oldGen.objectSpace().getLiveRegions(), liveRegions); |
3972 | 437 } else if (heap instanceof G1CollectedHeap) { |
438 G1CollectedHeap g1h = (G1CollectedHeap) heap; | |
439 g1h.heapRegionIterate(lrc); | |
0 | 440 } else { |
441 if (Assert.ASSERTS_ENABLED) { | |
3972 | 442 Assert.that(false, "Expecting GenCollectedHeap, G1CollectedHeap, " + |
443 "or ParallelScavengeHeap, but got " + | |
444 heap.getClass().getName()); | |
0 | 445 } |
446 } | |
447 | |
448 // If UseTLAB is enabled, snip out regions associated with TLABs' | |
449 // dead regions. Note that TLABs can be present in any generation. | |
450 | |
451 // FIXME: consider adding fewer boundaries to live region list. | |
452 // Theoretically only need to stop at TLAB's top and resume at its | |
453 // end. | |
454 | |
455 if (VM.getVM().getUseTLAB()) { | |
456 for (JavaThread thread = VM.getVM().getThreads().first(); thread != null; thread = thread.next()) { | |
13431 | 457 ThreadLocalAllocBuffer tlab = thread.tlab(); |
458 if (tlab.start() != null) { | |
459 if ((tlab.top() == null) || (tlab.end() == null)) { | |
460 System.err.print("Warning: skipping invalid TLAB for thread "); | |
461 thread.printThreadIDOn(System.err); | |
462 System.err.println(); | |
463 } else { | |
464 if (DEBUG) { | |
465 System.err.print("TLAB for " + thread.getThreadName() + ", #"); | |
0 | 466 thread.printThreadIDOn(System.err); |
13431 | 467 System.err.print(": "); |
468 tlab.printOn(System.err); | |
0 | 469 } |
13431 | 470 // Go from: |
471 // - below start() to start() | |
472 // - start() to top() | |
473 // - end() and above | |
474 liveRegions.add(tlab.start()); | |
475 liveRegions.add(tlab.start()); | |
476 liveRegions.add(tlab.top()); | |
477 liveRegions.add(tlab.hardEnd()); | |
0 | 478 } |
479 } | |
480 } | |
481 } | |
482 | |
483 // Now sort live regions | |
484 sortLiveRegions(liveRegions); | |
485 | |
486 if (Assert.ASSERTS_ENABLED) { | |
487 Assert.that(liveRegions.size() % 2 == 0, "Must have even number of region boundaries"); | |
488 } | |
489 | |
13431 | 490 if (DEBUG) { |
491 System.err.println("liveRegions:"); | |
492 for (int i = 0; i < liveRegions.size(); i += 2) { | |
493 Address bottom = (Address) liveRegions.get(i); | |
494 Address top = (Address) liveRegions.get(i+1); | |
495 System.err.println(" " + bottom + " - " + top); | |
496 } | |
497 } | |
498 | |
0 | 499 return liveRegions; |
500 } | |
501 | |
502 private void sortLiveRegions(List liveRegions) { | |
503 Collections.sort(liveRegions, new Comparator() { | |
504 public int compare(Object o1, Object o2) { | |
505 Address a1 = (Address) o1; | |
506 Address a2 = (Address) o2; | |
507 if (AddressOps.lt(a1, a2)) { | |
508 return -1; | |
509 } else if (AddressOps.gt(a1, a2)) { | |
510 return 1; | |
511 } | |
512 return 0; | |
513 } | |
514 }); | |
515 } | |
516 } |