annotate src/share/vm/services/heapDumper.cpp @ 5763:a3d71693e0ce

removed bytecode disassembly from CodeCacheRuntime into separate BytecodeDisassembler class removed VM call for doing bytecode disassembly added support for explicitly excluding classes from JaCoCo (put '// JaCoCo Exclude' somewhere in the source file) added node intrinsics to MaterializeNode added snippets for the UnsignedMath classes each file opened by CFGPrinter now includes a unique id in its name to avoid a race of multiple threads writing to the same file the IdealGraphPrinter uses the new BytecodeDisassembler mechanism teh UnsignedMath class is exclude from JaCoCo processing as it is used in snippets
author Doug Simon <doug.simon@oracle.com>
date Wed, 04 Jul 2012 21:57:49 +0200
parents 2ceafe3ceb65
children d2a62e0f25eb
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1 /*
2225
c798c277ddd1 7015169: GC Cause not always set
brutisso
parents: 2177
diff changeset
2 * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
a61af66fc99e Initial load
duke
parents:
diff changeset
4 *
a61af66fc99e Initial load
duke
parents:
diff changeset
5 * This code is free software; you can redistribute it and/or modify it
a61af66fc99e Initial load
duke
parents:
diff changeset
6 * under the terms of the GNU General Public License version 2 only, as
a61af66fc99e Initial load
duke
parents:
diff changeset
7 * published by the Free Software Foundation.
a61af66fc99e Initial load
duke
parents:
diff changeset
8 *
a61af66fc99e Initial load
duke
parents:
diff changeset
9 * This code is distributed in the hope that it will be useful, but WITHOUT
a61af66fc99e Initial load
duke
parents:
diff changeset
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
a61af66fc99e Initial load
duke
parents:
diff changeset
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
a61af66fc99e Initial load
duke
parents:
diff changeset
12 * version 2 for more details (a copy is included in the LICENSE file that
a61af66fc99e Initial load
duke
parents:
diff changeset
13 * accompanied this code).
a61af66fc99e Initial load
duke
parents:
diff changeset
14 *
a61af66fc99e Initial load
duke
parents:
diff changeset
15 * You should have received a copy of the GNU General Public License version
a61af66fc99e Initial load
duke
parents:
diff changeset
16 * 2 along with this work; if not, write to the Free Software Foundation,
a61af66fc99e Initial load
duke
parents:
diff changeset
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
a61af66fc99e Initial load
duke
parents:
diff changeset
18 *
1552
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1142
diff changeset
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1142
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: 1142
diff changeset
21 * questions.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
22 *
a61af66fc99e Initial load
duke
parents:
diff changeset
23 */
a61af66fc99e Initial load
duke
parents:
diff changeset
24
1972
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1775
diff changeset
25 #include "precompiled.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1775
diff changeset
26 #include "classfile/symbolTable.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1775
diff changeset
27 #include "classfile/systemDictionary.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1775
diff changeset
28 #include "classfile/vmSymbols.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1775
diff changeset
29 #include "gc_implementation/shared/vmGCOperations.hpp"
4076
2ceafe3ceb65 7110428: Crash during HeapDump operation
poonam
parents: 3363
diff changeset
30 #include "memory/gcLocker.inline.hpp"
1972
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1775
diff changeset
31 #include "memory/genCollectedHeap.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1775
diff changeset
32 #include "memory/universe.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1775
diff changeset
33 #include "oops/objArrayKlass.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1775
diff changeset
34 #include "runtime/javaCalls.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1775
diff changeset
35 #include "runtime/jniHandles.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1775
diff changeset
36 #include "runtime/reflectionUtils.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1775
diff changeset
37 #include "runtime/vframe.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1775
diff changeset
38 #include "runtime/vmThread.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1775
diff changeset
39 #include "runtime/vm_operations.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1775
diff changeset
40 #include "services/heapDumper.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1775
diff changeset
41 #include "services/threadService.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1775
diff changeset
42 #include "utilities/ostream.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1775
diff changeset
43 #ifndef SERIALGC
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1775
diff changeset
44 #include "gc_implementation/parallelScavenge/parallelScavengeHeap.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1775
diff changeset
45 #endif
0
a61af66fc99e Initial load
duke
parents:
diff changeset
46
a61af66fc99e Initial load
duke
parents:
diff changeset
47 /*
a61af66fc99e Initial load
duke
parents:
diff changeset
48 * HPROF binary format - description copied from:
a61af66fc99e Initial load
duke
parents:
diff changeset
49 * src/share/demo/jvmti/hprof/hprof_io.c
a61af66fc99e Initial load
duke
parents:
diff changeset
50 *
a61af66fc99e Initial load
duke
parents:
diff changeset
51 *
a61af66fc99e Initial load
duke
parents:
diff changeset
52 * header "JAVA PROFILE 1.0.1" or "JAVA PROFILE 1.0.2"
a61af66fc99e Initial load
duke
parents:
diff changeset
53 * (0-terminated)
a61af66fc99e Initial load
duke
parents:
diff changeset
54 *
a61af66fc99e Initial load
duke
parents:
diff changeset
55 * u4 size of identifiers. Identifiers are used to represent
a61af66fc99e Initial load
duke
parents:
diff changeset
56 * UTF8 strings, objects, stack traces, etc. They usually
a61af66fc99e Initial load
duke
parents:
diff changeset
57 * have the same size as host pointers. For example, on
a61af66fc99e Initial load
duke
parents:
diff changeset
58 * Solaris and Win32, the size is 4.
a61af66fc99e Initial load
duke
parents:
diff changeset
59 * u4 high word
a61af66fc99e Initial load
duke
parents:
diff changeset
60 * u4 low word number of milliseconds since 0:00 GMT, 1/1/70
a61af66fc99e Initial load
duke
parents:
diff changeset
61 * [record]* a sequence of records.
a61af66fc99e Initial load
duke
parents:
diff changeset
62 *
a61af66fc99e Initial load
duke
parents:
diff changeset
63 *
a61af66fc99e Initial load
duke
parents:
diff changeset
64 * Record format:
a61af66fc99e Initial load
duke
parents:
diff changeset
65 *
a61af66fc99e Initial load
duke
parents:
diff changeset
66 * u1 a TAG denoting the type of the record
a61af66fc99e Initial load
duke
parents:
diff changeset
67 * u4 number of *microseconds* since the time stamp in the
a61af66fc99e Initial load
duke
parents:
diff changeset
68 * header. (wraps around in a little more than an hour)
a61af66fc99e Initial load
duke
parents:
diff changeset
69 * u4 number of bytes *remaining* in the record. Note that
a61af66fc99e Initial load
duke
parents:
diff changeset
70 * this number excludes the tag and the length field itself.
a61af66fc99e Initial load
duke
parents:
diff changeset
71 * [u1]* BODY of the record (a sequence of bytes)
a61af66fc99e Initial load
duke
parents:
diff changeset
72 *
a61af66fc99e Initial load
duke
parents:
diff changeset
73 *
a61af66fc99e Initial load
duke
parents:
diff changeset
74 * The following TAGs are supported:
a61af66fc99e Initial load
duke
parents:
diff changeset
75 *
a61af66fc99e Initial load
duke
parents:
diff changeset
76 * TAG BODY notes
a61af66fc99e Initial load
duke
parents:
diff changeset
77 *----------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
78 * HPROF_UTF8 a UTF8-encoded name
a61af66fc99e Initial load
duke
parents:
diff changeset
79 *
a61af66fc99e Initial load
duke
parents:
diff changeset
80 * id name ID
a61af66fc99e Initial load
duke
parents:
diff changeset
81 * [u1]* UTF8 characters (no trailing zero)
a61af66fc99e Initial load
duke
parents:
diff changeset
82 *
a61af66fc99e Initial load
duke
parents:
diff changeset
83 * HPROF_LOAD_CLASS a newly loaded class
a61af66fc99e Initial load
duke
parents:
diff changeset
84 *
a61af66fc99e Initial load
duke
parents:
diff changeset
85 * u4 class serial number (> 0)
a61af66fc99e Initial load
duke
parents:
diff changeset
86 * id class object ID
a61af66fc99e Initial load
duke
parents:
diff changeset
87 * u4 stack trace serial number
a61af66fc99e Initial load
duke
parents:
diff changeset
88 * id class name ID
a61af66fc99e Initial load
duke
parents:
diff changeset
89 *
a61af66fc99e Initial load
duke
parents:
diff changeset
90 * HPROF_UNLOAD_CLASS an unloading class
a61af66fc99e Initial load
duke
parents:
diff changeset
91 *
a61af66fc99e Initial load
duke
parents:
diff changeset
92 * u4 class serial_number
a61af66fc99e Initial load
duke
parents:
diff changeset
93 *
a61af66fc99e Initial load
duke
parents:
diff changeset
94 * HPROF_FRAME a Java stack frame
a61af66fc99e Initial load
duke
parents:
diff changeset
95 *
a61af66fc99e Initial load
duke
parents:
diff changeset
96 * id stack frame ID
a61af66fc99e Initial load
duke
parents:
diff changeset
97 * id method name ID
a61af66fc99e Initial load
duke
parents:
diff changeset
98 * id method signature ID
a61af66fc99e Initial load
duke
parents:
diff changeset
99 * id source file name ID
a61af66fc99e Initial load
duke
parents:
diff changeset
100 * u4 class serial number
a61af66fc99e Initial load
duke
parents:
diff changeset
101 * i4 line number. >0: normal
a61af66fc99e Initial load
duke
parents:
diff changeset
102 * -1: unknown
a61af66fc99e Initial load
duke
parents:
diff changeset
103 * -2: compiled method
a61af66fc99e Initial load
duke
parents:
diff changeset
104 * -3: native method
a61af66fc99e Initial load
duke
parents:
diff changeset
105 *
a61af66fc99e Initial load
duke
parents:
diff changeset
106 * HPROF_TRACE a Java stack trace
a61af66fc99e Initial load
duke
parents:
diff changeset
107 *
a61af66fc99e Initial load
duke
parents:
diff changeset
108 * u4 stack trace serial number
a61af66fc99e Initial load
duke
parents:
diff changeset
109 * u4 thread serial number
a61af66fc99e Initial load
duke
parents:
diff changeset
110 * u4 number of frames
a61af66fc99e Initial load
duke
parents:
diff changeset
111 * [id]* stack frame IDs
a61af66fc99e Initial load
duke
parents:
diff changeset
112 *
a61af66fc99e Initial load
duke
parents:
diff changeset
113 *
a61af66fc99e Initial load
duke
parents:
diff changeset
114 * HPROF_ALLOC_SITES a set of heap allocation sites, obtained after GC
a61af66fc99e Initial load
duke
parents:
diff changeset
115 *
a61af66fc99e Initial load
duke
parents:
diff changeset
116 * u2 flags 0x0001: incremental vs. complete
a61af66fc99e Initial load
duke
parents:
diff changeset
117 * 0x0002: sorted by allocation vs. live
a61af66fc99e Initial load
duke
parents:
diff changeset
118 * 0x0004: whether to force a GC
a61af66fc99e Initial load
duke
parents:
diff changeset
119 * u4 cutoff ratio
a61af66fc99e Initial load
duke
parents:
diff changeset
120 * u4 total live bytes
a61af66fc99e Initial load
duke
parents:
diff changeset
121 * u4 total live instances
a61af66fc99e Initial load
duke
parents:
diff changeset
122 * u8 total bytes allocated
a61af66fc99e Initial load
duke
parents:
diff changeset
123 * u8 total instances allocated
a61af66fc99e Initial load
duke
parents:
diff changeset
124 * u4 number of sites that follow
a61af66fc99e Initial load
duke
parents:
diff changeset
125 * [u1 is_array: 0: normal object
a61af66fc99e Initial load
duke
parents:
diff changeset
126 * 2: object array
a61af66fc99e Initial load
duke
parents:
diff changeset
127 * 4: boolean array
a61af66fc99e Initial load
duke
parents:
diff changeset
128 * 5: char array
a61af66fc99e Initial load
duke
parents:
diff changeset
129 * 6: float array
a61af66fc99e Initial load
duke
parents:
diff changeset
130 * 7: double array
a61af66fc99e Initial load
duke
parents:
diff changeset
131 * 8: byte array
a61af66fc99e Initial load
duke
parents:
diff changeset
132 * 9: short array
a61af66fc99e Initial load
duke
parents:
diff changeset
133 * 10: int array
a61af66fc99e Initial load
duke
parents:
diff changeset
134 * 11: long array
a61af66fc99e Initial load
duke
parents:
diff changeset
135 * u4 class serial number (may be zero during startup)
a61af66fc99e Initial load
duke
parents:
diff changeset
136 * u4 stack trace serial number
a61af66fc99e Initial load
duke
parents:
diff changeset
137 * u4 number of bytes alive
a61af66fc99e Initial load
duke
parents:
diff changeset
138 * u4 number of instances alive
a61af66fc99e Initial load
duke
parents:
diff changeset
139 * u4 number of bytes allocated
a61af66fc99e Initial load
duke
parents:
diff changeset
140 * u4]* number of instance allocated
a61af66fc99e Initial load
duke
parents:
diff changeset
141 *
a61af66fc99e Initial load
duke
parents:
diff changeset
142 * HPROF_START_THREAD a newly started thread.
a61af66fc99e Initial load
duke
parents:
diff changeset
143 *
a61af66fc99e Initial load
duke
parents:
diff changeset
144 * u4 thread serial number (> 0)
a61af66fc99e Initial load
duke
parents:
diff changeset
145 * id thread object ID
a61af66fc99e Initial load
duke
parents:
diff changeset
146 * u4 stack trace serial number
a61af66fc99e Initial load
duke
parents:
diff changeset
147 * id thread name ID
a61af66fc99e Initial load
duke
parents:
diff changeset
148 * id thread group name ID
a61af66fc99e Initial load
duke
parents:
diff changeset
149 * id thread group parent name ID
a61af66fc99e Initial load
duke
parents:
diff changeset
150 *
a61af66fc99e Initial load
duke
parents:
diff changeset
151 * HPROF_END_THREAD a terminating thread.
a61af66fc99e Initial load
duke
parents:
diff changeset
152 *
a61af66fc99e Initial load
duke
parents:
diff changeset
153 * u4 thread serial number
a61af66fc99e Initial load
duke
parents:
diff changeset
154 *
a61af66fc99e Initial load
duke
parents:
diff changeset
155 * HPROF_HEAP_SUMMARY heap summary
a61af66fc99e Initial load
duke
parents:
diff changeset
156 *
a61af66fc99e Initial load
duke
parents:
diff changeset
157 * u4 total live bytes
a61af66fc99e Initial load
duke
parents:
diff changeset
158 * u4 total live instances
a61af66fc99e Initial load
duke
parents:
diff changeset
159 * u8 total bytes allocated
a61af66fc99e Initial load
duke
parents:
diff changeset
160 * u8 total instances allocated
a61af66fc99e Initial load
duke
parents:
diff changeset
161 *
a61af66fc99e Initial load
duke
parents:
diff changeset
162 * HPROF_HEAP_DUMP denote a heap dump
a61af66fc99e Initial load
duke
parents:
diff changeset
163 *
a61af66fc99e Initial load
duke
parents:
diff changeset
164 * [heap dump sub-records]*
a61af66fc99e Initial load
duke
parents:
diff changeset
165 *
a61af66fc99e Initial load
duke
parents:
diff changeset
166 * There are four kinds of heap dump sub-records:
a61af66fc99e Initial load
duke
parents:
diff changeset
167 *
a61af66fc99e Initial load
duke
parents:
diff changeset
168 * u1 sub-record type
a61af66fc99e Initial load
duke
parents:
diff changeset
169 *
a61af66fc99e Initial load
duke
parents:
diff changeset
170 * HPROF_GC_ROOT_UNKNOWN unknown root
a61af66fc99e Initial load
duke
parents:
diff changeset
171 *
a61af66fc99e Initial load
duke
parents:
diff changeset
172 * id object ID
a61af66fc99e Initial load
duke
parents:
diff changeset
173 *
a61af66fc99e Initial load
duke
parents:
diff changeset
174 * HPROF_GC_ROOT_THREAD_OBJ thread object
a61af66fc99e Initial load
duke
parents:
diff changeset
175 *
a61af66fc99e Initial load
duke
parents:
diff changeset
176 * id thread object ID (may be 0 for a
a61af66fc99e Initial load
duke
parents:
diff changeset
177 * thread newly attached through JNI)
a61af66fc99e Initial load
duke
parents:
diff changeset
178 * u4 thread sequence number
a61af66fc99e Initial load
duke
parents:
diff changeset
179 * u4 stack trace sequence number
a61af66fc99e Initial load
duke
parents:
diff changeset
180 *
a61af66fc99e Initial load
duke
parents:
diff changeset
181 * HPROF_GC_ROOT_JNI_GLOBAL JNI global ref root
a61af66fc99e Initial load
duke
parents:
diff changeset
182 *
a61af66fc99e Initial load
duke
parents:
diff changeset
183 * id object ID
a61af66fc99e Initial load
duke
parents:
diff changeset
184 * id JNI global ref ID
a61af66fc99e Initial load
duke
parents:
diff changeset
185 *
a61af66fc99e Initial load
duke
parents:
diff changeset
186 * HPROF_GC_ROOT_JNI_LOCAL JNI local ref
a61af66fc99e Initial load
duke
parents:
diff changeset
187 *
a61af66fc99e Initial load
duke
parents:
diff changeset
188 * id object ID
a61af66fc99e Initial load
duke
parents:
diff changeset
189 * u4 thread serial number
a61af66fc99e Initial load
duke
parents:
diff changeset
190 * u4 frame # in stack trace (-1 for empty)
a61af66fc99e Initial load
duke
parents:
diff changeset
191 *
a61af66fc99e Initial load
duke
parents:
diff changeset
192 * HPROF_GC_ROOT_JAVA_FRAME Java stack frame
a61af66fc99e Initial load
duke
parents:
diff changeset
193 *
a61af66fc99e Initial load
duke
parents:
diff changeset
194 * id object ID
a61af66fc99e Initial load
duke
parents:
diff changeset
195 * u4 thread serial number
a61af66fc99e Initial load
duke
parents:
diff changeset
196 * u4 frame # in stack trace (-1 for empty)
a61af66fc99e Initial load
duke
parents:
diff changeset
197 *
a61af66fc99e Initial load
duke
parents:
diff changeset
198 * HPROF_GC_ROOT_NATIVE_STACK Native stack
a61af66fc99e Initial load
duke
parents:
diff changeset
199 *
a61af66fc99e Initial load
duke
parents:
diff changeset
200 * id object ID
a61af66fc99e Initial load
duke
parents:
diff changeset
201 * u4 thread serial number
a61af66fc99e Initial load
duke
parents:
diff changeset
202 *
a61af66fc99e Initial load
duke
parents:
diff changeset
203 * HPROF_GC_ROOT_STICKY_CLASS System class
a61af66fc99e Initial load
duke
parents:
diff changeset
204 *
a61af66fc99e Initial load
duke
parents:
diff changeset
205 * id object ID
a61af66fc99e Initial load
duke
parents:
diff changeset
206 *
a61af66fc99e Initial load
duke
parents:
diff changeset
207 * HPROF_GC_ROOT_THREAD_BLOCK Reference from thread block
a61af66fc99e Initial load
duke
parents:
diff changeset
208 *
a61af66fc99e Initial load
duke
parents:
diff changeset
209 * id object ID
a61af66fc99e Initial load
duke
parents:
diff changeset
210 * u4 thread serial number
a61af66fc99e Initial load
duke
parents:
diff changeset
211 *
a61af66fc99e Initial load
duke
parents:
diff changeset
212 * HPROF_GC_ROOT_MONITOR_USED Busy monitor
a61af66fc99e Initial load
duke
parents:
diff changeset
213 *
a61af66fc99e Initial load
duke
parents:
diff changeset
214 * id object ID
a61af66fc99e Initial load
duke
parents:
diff changeset
215 *
a61af66fc99e Initial load
duke
parents:
diff changeset
216 * HPROF_GC_CLASS_DUMP dump of a class object
a61af66fc99e Initial load
duke
parents:
diff changeset
217 *
a61af66fc99e Initial load
duke
parents:
diff changeset
218 * id class object ID
a61af66fc99e Initial load
duke
parents:
diff changeset
219 * u4 stack trace serial number
a61af66fc99e Initial load
duke
parents:
diff changeset
220 * id super class object ID
a61af66fc99e Initial load
duke
parents:
diff changeset
221 * id class loader object ID
a61af66fc99e Initial load
duke
parents:
diff changeset
222 * id signers object ID
a61af66fc99e Initial load
duke
parents:
diff changeset
223 * id protection domain object ID
a61af66fc99e Initial load
duke
parents:
diff changeset
224 * id reserved
a61af66fc99e Initial load
duke
parents:
diff changeset
225 * id reserved
a61af66fc99e Initial load
duke
parents:
diff changeset
226 *
a61af66fc99e Initial load
duke
parents:
diff changeset
227 * u4 instance size (in bytes)
a61af66fc99e Initial load
duke
parents:
diff changeset
228 *
a61af66fc99e Initial load
duke
parents:
diff changeset
229 * u2 size of constant pool
a61af66fc99e Initial load
duke
parents:
diff changeset
230 * [u2, constant pool index,
a61af66fc99e Initial load
duke
parents:
diff changeset
231 * ty, type
a61af66fc99e Initial load
duke
parents:
diff changeset
232 * 2: object
a61af66fc99e Initial load
duke
parents:
diff changeset
233 * 4: boolean
a61af66fc99e Initial load
duke
parents:
diff changeset
234 * 5: char
a61af66fc99e Initial load
duke
parents:
diff changeset
235 * 6: float
a61af66fc99e Initial load
duke
parents:
diff changeset
236 * 7: double
a61af66fc99e Initial load
duke
parents:
diff changeset
237 * 8: byte
a61af66fc99e Initial load
duke
parents:
diff changeset
238 * 9: short
a61af66fc99e Initial load
duke
parents:
diff changeset
239 * 10: int
a61af66fc99e Initial load
duke
parents:
diff changeset
240 * 11: long
a61af66fc99e Initial load
duke
parents:
diff changeset
241 * vl]* and value
a61af66fc99e Initial load
duke
parents:
diff changeset
242 *
a61af66fc99e Initial load
duke
parents:
diff changeset
243 * u2 number of static fields
a61af66fc99e Initial load
duke
parents:
diff changeset
244 * [id, static field name,
a61af66fc99e Initial load
duke
parents:
diff changeset
245 * ty, type,
a61af66fc99e Initial load
duke
parents:
diff changeset
246 * vl]* and value
a61af66fc99e Initial load
duke
parents:
diff changeset
247 *
a61af66fc99e Initial load
duke
parents:
diff changeset
248 * u2 number of inst. fields (not inc. super)
a61af66fc99e Initial load
duke
parents:
diff changeset
249 * [id, instance field name,
a61af66fc99e Initial load
duke
parents:
diff changeset
250 * ty]* type
a61af66fc99e Initial load
duke
parents:
diff changeset
251 *
a61af66fc99e Initial load
duke
parents:
diff changeset
252 * HPROF_GC_INSTANCE_DUMP dump of a normal object
a61af66fc99e Initial load
duke
parents:
diff changeset
253 *
a61af66fc99e Initial load
duke
parents:
diff changeset
254 * id object ID
a61af66fc99e Initial load
duke
parents:
diff changeset
255 * u4 stack trace serial number
a61af66fc99e Initial load
duke
parents:
diff changeset
256 * id class object ID
a61af66fc99e Initial load
duke
parents:
diff changeset
257 * u4 number of bytes that follow
a61af66fc99e Initial load
duke
parents:
diff changeset
258 * [vl]* instance field values (class, followed
a61af66fc99e Initial load
duke
parents:
diff changeset
259 * by super, super's super ...)
a61af66fc99e Initial load
duke
parents:
diff changeset
260 *
a61af66fc99e Initial load
duke
parents:
diff changeset
261 * HPROF_GC_OBJ_ARRAY_DUMP dump of an object array
a61af66fc99e Initial load
duke
parents:
diff changeset
262 *
a61af66fc99e Initial load
duke
parents:
diff changeset
263 * id array object ID
a61af66fc99e Initial load
duke
parents:
diff changeset
264 * u4 stack trace serial number
a61af66fc99e Initial load
duke
parents:
diff changeset
265 * u4 number of elements
a61af66fc99e Initial load
duke
parents:
diff changeset
266 * id array class ID
a61af66fc99e Initial load
duke
parents:
diff changeset
267 * [id]* elements
a61af66fc99e Initial load
duke
parents:
diff changeset
268 *
a61af66fc99e Initial load
duke
parents:
diff changeset
269 * HPROF_GC_PRIM_ARRAY_DUMP dump of a primitive array
a61af66fc99e Initial load
duke
parents:
diff changeset
270 *
a61af66fc99e Initial load
duke
parents:
diff changeset
271 * id array object ID
a61af66fc99e Initial load
duke
parents:
diff changeset
272 * u4 stack trace serial number
a61af66fc99e Initial load
duke
parents:
diff changeset
273 * u4 number of elements
a61af66fc99e Initial load
duke
parents:
diff changeset
274 * u1 element type
a61af66fc99e Initial load
duke
parents:
diff changeset
275 * 4: boolean array
a61af66fc99e Initial load
duke
parents:
diff changeset
276 * 5: char array
a61af66fc99e Initial load
duke
parents:
diff changeset
277 * 6: float array
a61af66fc99e Initial load
duke
parents:
diff changeset
278 * 7: double array
a61af66fc99e Initial load
duke
parents:
diff changeset
279 * 8: byte array
a61af66fc99e Initial load
duke
parents:
diff changeset
280 * 9: short array
a61af66fc99e Initial load
duke
parents:
diff changeset
281 * 10: int array
a61af66fc99e Initial load
duke
parents:
diff changeset
282 * 11: long array
a61af66fc99e Initial load
duke
parents:
diff changeset
283 * [u1]* elements
a61af66fc99e Initial load
duke
parents:
diff changeset
284 *
a61af66fc99e Initial load
duke
parents:
diff changeset
285 * HPROF_CPU_SAMPLES a set of sample traces of running threads
a61af66fc99e Initial load
duke
parents:
diff changeset
286 *
a61af66fc99e Initial load
duke
parents:
diff changeset
287 * u4 total number of samples
a61af66fc99e Initial load
duke
parents:
diff changeset
288 * u4 # of traces
a61af66fc99e Initial load
duke
parents:
diff changeset
289 * [u4 # of samples
a61af66fc99e Initial load
duke
parents:
diff changeset
290 * u4]* stack trace serial number
a61af66fc99e Initial load
duke
parents:
diff changeset
291 *
a61af66fc99e Initial load
duke
parents:
diff changeset
292 * HPROF_CONTROL_SETTINGS the settings of on/off switches
a61af66fc99e Initial load
duke
parents:
diff changeset
293 *
a61af66fc99e Initial load
duke
parents:
diff changeset
294 * u4 0x00000001: alloc traces on/off
a61af66fc99e Initial load
duke
parents:
diff changeset
295 * 0x00000002: cpu sampling on/off
a61af66fc99e Initial load
duke
parents:
diff changeset
296 * u2 stack trace depth
a61af66fc99e Initial load
duke
parents:
diff changeset
297 *
a61af66fc99e Initial load
duke
parents:
diff changeset
298 *
a61af66fc99e Initial load
duke
parents:
diff changeset
299 * When the header is "JAVA PROFILE 1.0.2" a heap dump can optionally
a61af66fc99e Initial load
duke
parents:
diff changeset
300 * be generated as a sequence of heap dump segments. This sequence is
a61af66fc99e Initial load
duke
parents:
diff changeset
301 * terminated by an end record. The additional tags allowed by format
a61af66fc99e Initial load
duke
parents:
diff changeset
302 * "JAVA PROFILE 1.0.2" are:
a61af66fc99e Initial load
duke
parents:
diff changeset
303 *
a61af66fc99e Initial load
duke
parents:
diff changeset
304 * HPROF_HEAP_DUMP_SEGMENT denote a heap dump segment
a61af66fc99e Initial load
duke
parents:
diff changeset
305 *
a61af66fc99e Initial load
duke
parents:
diff changeset
306 * [heap dump sub-records]*
a61af66fc99e Initial load
duke
parents:
diff changeset
307 * The same sub-record types allowed by HPROF_HEAP_DUMP
a61af66fc99e Initial load
duke
parents:
diff changeset
308 *
a61af66fc99e Initial load
duke
parents:
diff changeset
309 * HPROF_HEAP_DUMP_END denotes the end of a heap dump
a61af66fc99e Initial load
duke
parents:
diff changeset
310 *
a61af66fc99e Initial load
duke
parents:
diff changeset
311 */
a61af66fc99e Initial load
duke
parents:
diff changeset
312
a61af66fc99e Initial load
duke
parents:
diff changeset
313
a61af66fc99e Initial load
duke
parents:
diff changeset
314 // HPROF tags
a61af66fc99e Initial load
duke
parents:
diff changeset
315
a61af66fc99e Initial load
duke
parents:
diff changeset
316 typedef enum {
a61af66fc99e Initial load
duke
parents:
diff changeset
317 // top-level records
a61af66fc99e Initial load
duke
parents:
diff changeset
318 HPROF_UTF8 = 0x01,
a61af66fc99e Initial load
duke
parents:
diff changeset
319 HPROF_LOAD_CLASS = 0x02,
a61af66fc99e Initial load
duke
parents:
diff changeset
320 HPROF_UNLOAD_CLASS = 0x03,
a61af66fc99e Initial load
duke
parents:
diff changeset
321 HPROF_FRAME = 0x04,
a61af66fc99e Initial load
duke
parents:
diff changeset
322 HPROF_TRACE = 0x05,
a61af66fc99e Initial load
duke
parents:
diff changeset
323 HPROF_ALLOC_SITES = 0x06,
a61af66fc99e Initial load
duke
parents:
diff changeset
324 HPROF_HEAP_SUMMARY = 0x07,
a61af66fc99e Initial load
duke
parents:
diff changeset
325 HPROF_START_THREAD = 0x0A,
a61af66fc99e Initial load
duke
parents:
diff changeset
326 HPROF_END_THREAD = 0x0B,
a61af66fc99e Initial load
duke
parents:
diff changeset
327 HPROF_HEAP_DUMP = 0x0C,
a61af66fc99e Initial load
duke
parents:
diff changeset
328 HPROF_CPU_SAMPLES = 0x0D,
a61af66fc99e Initial load
duke
parents:
diff changeset
329 HPROF_CONTROL_SETTINGS = 0x0E,
a61af66fc99e Initial load
duke
parents:
diff changeset
330
a61af66fc99e Initial load
duke
parents:
diff changeset
331 // 1.0.2 record types
a61af66fc99e Initial load
duke
parents:
diff changeset
332 HPROF_HEAP_DUMP_SEGMENT = 0x1C,
a61af66fc99e Initial load
duke
parents:
diff changeset
333 HPROF_HEAP_DUMP_END = 0x2C,
a61af66fc99e Initial load
duke
parents:
diff changeset
334
a61af66fc99e Initial load
duke
parents:
diff changeset
335 // field types
a61af66fc99e Initial load
duke
parents:
diff changeset
336 HPROF_ARRAY_OBJECT = 0x01,
a61af66fc99e Initial load
duke
parents:
diff changeset
337 HPROF_NORMAL_OBJECT = 0x02,
a61af66fc99e Initial load
duke
parents:
diff changeset
338 HPROF_BOOLEAN = 0x04,
a61af66fc99e Initial load
duke
parents:
diff changeset
339 HPROF_CHAR = 0x05,
a61af66fc99e Initial load
duke
parents:
diff changeset
340 HPROF_FLOAT = 0x06,
a61af66fc99e Initial load
duke
parents:
diff changeset
341 HPROF_DOUBLE = 0x07,
a61af66fc99e Initial load
duke
parents:
diff changeset
342 HPROF_BYTE = 0x08,
a61af66fc99e Initial load
duke
parents:
diff changeset
343 HPROF_SHORT = 0x09,
a61af66fc99e Initial load
duke
parents:
diff changeset
344 HPROF_INT = 0x0A,
a61af66fc99e Initial load
duke
parents:
diff changeset
345 HPROF_LONG = 0x0B,
a61af66fc99e Initial load
duke
parents:
diff changeset
346
a61af66fc99e Initial load
duke
parents:
diff changeset
347 // data-dump sub-records
a61af66fc99e Initial load
duke
parents:
diff changeset
348 HPROF_GC_ROOT_UNKNOWN = 0xFF,
a61af66fc99e Initial load
duke
parents:
diff changeset
349 HPROF_GC_ROOT_JNI_GLOBAL = 0x01,
a61af66fc99e Initial load
duke
parents:
diff changeset
350 HPROF_GC_ROOT_JNI_LOCAL = 0x02,
a61af66fc99e Initial load
duke
parents:
diff changeset
351 HPROF_GC_ROOT_JAVA_FRAME = 0x03,
a61af66fc99e Initial load
duke
parents:
diff changeset
352 HPROF_GC_ROOT_NATIVE_STACK = 0x04,
a61af66fc99e Initial load
duke
parents:
diff changeset
353 HPROF_GC_ROOT_STICKY_CLASS = 0x05,
a61af66fc99e Initial load
duke
parents:
diff changeset
354 HPROF_GC_ROOT_THREAD_BLOCK = 0x06,
a61af66fc99e Initial load
duke
parents:
diff changeset
355 HPROF_GC_ROOT_MONITOR_USED = 0x07,
a61af66fc99e Initial load
duke
parents:
diff changeset
356 HPROF_GC_ROOT_THREAD_OBJ = 0x08,
a61af66fc99e Initial load
duke
parents:
diff changeset
357 HPROF_GC_CLASS_DUMP = 0x20,
a61af66fc99e Initial load
duke
parents:
diff changeset
358 HPROF_GC_INSTANCE_DUMP = 0x21,
a61af66fc99e Initial load
duke
parents:
diff changeset
359 HPROF_GC_OBJ_ARRAY_DUMP = 0x22,
a61af66fc99e Initial load
duke
parents:
diff changeset
360 HPROF_GC_PRIM_ARRAY_DUMP = 0x23
a61af66fc99e Initial load
duke
parents:
diff changeset
361 } hprofTag;
a61af66fc99e Initial load
duke
parents:
diff changeset
362
a61af66fc99e Initial load
duke
parents:
diff changeset
363 // Default stack trace ID (used for dummy HPROF_TRACE record)
a61af66fc99e Initial load
duke
parents:
diff changeset
364 enum {
396
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
365 STACK_TRACE_ID = 1,
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
366 INITIAL_CLASS_COUNT = 200
0
a61af66fc99e Initial load
duke
parents:
diff changeset
367 };
a61af66fc99e Initial load
duke
parents:
diff changeset
368
a61af66fc99e Initial load
duke
parents:
diff changeset
369 // Supports I/O operations on a dump file
a61af66fc99e Initial load
duke
parents:
diff changeset
370
a61af66fc99e Initial load
duke
parents:
diff changeset
371 class DumpWriter : public StackObj {
a61af66fc99e Initial load
duke
parents:
diff changeset
372 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
373 enum {
a61af66fc99e Initial load
duke
parents:
diff changeset
374 io_buffer_size = 8*M
a61af66fc99e Initial load
duke
parents:
diff changeset
375 };
a61af66fc99e Initial load
duke
parents:
diff changeset
376
a61af66fc99e Initial load
duke
parents:
diff changeset
377 int _fd; // file descriptor (-1 if dump file not open)
a61af66fc99e Initial load
duke
parents:
diff changeset
378 jlong _bytes_written; // number of byte written to dump file
a61af66fc99e Initial load
duke
parents:
diff changeset
379
a61af66fc99e Initial load
duke
parents:
diff changeset
380 char* _buffer; // internal buffer
a61af66fc99e Initial load
duke
parents:
diff changeset
381 int _size;
a61af66fc99e Initial load
duke
parents:
diff changeset
382 int _pos;
a61af66fc99e Initial load
duke
parents:
diff changeset
383
a61af66fc99e Initial load
duke
parents:
diff changeset
384 char* _error; // error message when I/O fails
a61af66fc99e Initial load
duke
parents:
diff changeset
385
a61af66fc99e Initial load
duke
parents:
diff changeset
386 void set_file_descriptor(int fd) { _fd = fd; }
a61af66fc99e Initial load
duke
parents:
diff changeset
387 int file_descriptor() const { return _fd; }
a61af66fc99e Initial load
duke
parents:
diff changeset
388
a61af66fc99e Initial load
duke
parents:
diff changeset
389 char* buffer() const { return _buffer; }
a61af66fc99e Initial load
duke
parents:
diff changeset
390 int buffer_size() const { return _size; }
a61af66fc99e Initial load
duke
parents:
diff changeset
391 int position() const { return _pos; }
a61af66fc99e Initial load
duke
parents:
diff changeset
392 void set_position(int pos) { _pos = pos; }
a61af66fc99e Initial load
duke
parents:
diff changeset
393
a61af66fc99e Initial load
duke
parents:
diff changeset
394 void set_error(const char* error) { _error = (char*)os::strdup(error); }
a61af66fc99e Initial load
duke
parents:
diff changeset
395
a61af66fc99e Initial load
duke
parents:
diff changeset
396 // all I/O go through this function
a61af66fc99e Initial load
duke
parents:
diff changeset
397 void write_internal(void* s, int len);
a61af66fc99e Initial load
duke
parents:
diff changeset
398
a61af66fc99e Initial load
duke
parents:
diff changeset
399 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
400 DumpWriter(const char* path);
a61af66fc99e Initial load
duke
parents:
diff changeset
401 ~DumpWriter();
a61af66fc99e Initial load
duke
parents:
diff changeset
402
a61af66fc99e Initial load
duke
parents:
diff changeset
403 void close();
a61af66fc99e Initial load
duke
parents:
diff changeset
404 bool is_open() const { return file_descriptor() >= 0; }
a61af66fc99e Initial load
duke
parents:
diff changeset
405 void flush();
a61af66fc99e Initial load
duke
parents:
diff changeset
406
a61af66fc99e Initial load
duke
parents:
diff changeset
407 // total number of bytes written to the disk
a61af66fc99e Initial load
duke
parents:
diff changeset
408 jlong bytes_written() const { return _bytes_written; }
a61af66fc99e Initial load
duke
parents:
diff changeset
409
a61af66fc99e Initial load
duke
parents:
diff changeset
410 // adjust the number of bytes written to disk (used to keep the count
a61af66fc99e Initial load
duke
parents:
diff changeset
411 // of the number of bytes written in case of rewrites)
a61af66fc99e Initial load
duke
parents:
diff changeset
412 void adjust_bytes_written(jlong n) { _bytes_written += n; }
a61af66fc99e Initial load
duke
parents:
diff changeset
413
a61af66fc99e Initial load
duke
parents:
diff changeset
414 // number of (buffered) bytes as yet unwritten to the dump file
a61af66fc99e Initial load
duke
parents:
diff changeset
415 jlong bytes_unwritten() const { return (jlong)position(); }
a61af66fc99e Initial load
duke
parents:
diff changeset
416
a61af66fc99e Initial load
duke
parents:
diff changeset
417 char* error() const { return _error; }
a61af66fc99e Initial load
duke
parents:
diff changeset
418
a61af66fc99e Initial load
duke
parents:
diff changeset
419 jlong current_offset();
a61af66fc99e Initial load
duke
parents:
diff changeset
420 void seek_to_offset(jlong pos);
a61af66fc99e Initial load
duke
parents:
diff changeset
421
a61af66fc99e Initial load
duke
parents:
diff changeset
422 // writer functions
a61af66fc99e Initial load
duke
parents:
diff changeset
423 void write_raw(void* s, int len);
a61af66fc99e Initial load
duke
parents:
diff changeset
424 void write_u1(u1 x) { write_raw((void*)&x, 1); }
a61af66fc99e Initial load
duke
parents:
diff changeset
425 void write_u2(u2 x);
a61af66fc99e Initial load
duke
parents:
diff changeset
426 void write_u4(u4 x);
a61af66fc99e Initial load
duke
parents:
diff changeset
427 void write_u8(u8 x);
a61af66fc99e Initial load
duke
parents:
diff changeset
428 void write_objectID(oop o);
2177
3582bf76420e 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 2143
diff changeset
429 void write_symbolID(Symbol* o);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
430 void write_classID(Klass* k);
396
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
431 void write_id(u4 x);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
432 };
a61af66fc99e Initial load
duke
parents:
diff changeset
433
a61af66fc99e Initial load
duke
parents:
diff changeset
434 DumpWriter::DumpWriter(const char* path) {
a61af66fc99e Initial load
duke
parents:
diff changeset
435 // try to allocate an I/O buffer of io_buffer_size. If there isn't
a61af66fc99e Initial load
duke
parents:
diff changeset
436 // sufficient memory then reduce size until we can allocate something.
a61af66fc99e Initial load
duke
parents:
diff changeset
437 _size = io_buffer_size;
a61af66fc99e Initial load
duke
parents:
diff changeset
438 do {
a61af66fc99e Initial load
duke
parents:
diff changeset
439 _buffer = (char*)os::malloc(_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
440 if (_buffer == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
441 _size = _size >> 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
442 }
a61af66fc99e Initial load
duke
parents:
diff changeset
443 } while (_buffer == NULL && _size > 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
444 assert((_size > 0 && _buffer != NULL) || (_size == 0 && _buffer == NULL), "sanity check");
a61af66fc99e Initial load
duke
parents:
diff changeset
445 _pos = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
446 _error = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
447 _bytes_written = 0L;
a61af66fc99e Initial load
duke
parents:
diff changeset
448 _fd = os::create_binary_file(path, false); // don't replace existing file
a61af66fc99e Initial load
duke
parents:
diff changeset
449
a61af66fc99e Initial load
duke
parents:
diff changeset
450 // if the open failed we record the error
a61af66fc99e Initial load
duke
parents:
diff changeset
451 if (_fd < 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
452 _error = (char*)os::strdup(strerror(errno));
a61af66fc99e Initial load
duke
parents:
diff changeset
453 }
a61af66fc99e Initial load
duke
parents:
diff changeset
454 }
a61af66fc99e Initial load
duke
parents:
diff changeset
455
a61af66fc99e Initial load
duke
parents:
diff changeset
456 DumpWriter::~DumpWriter() {
a61af66fc99e Initial load
duke
parents:
diff changeset
457 // flush and close dump file
2143
17c778814856 6811367: Fix code in HeapDumper::dump_heap() to avoid buffer overrun
coleenp
parents: 1972
diff changeset
458 if (is_open()) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
459 close();
a61af66fc99e Initial load
duke
parents:
diff changeset
460 }
a61af66fc99e Initial load
duke
parents:
diff changeset
461 if (_buffer != NULL) os::free(_buffer);
a61af66fc99e Initial load
duke
parents:
diff changeset
462 if (_error != NULL) os::free(_error);
a61af66fc99e Initial load
duke
parents:
diff changeset
463 }
a61af66fc99e Initial load
duke
parents:
diff changeset
464
a61af66fc99e Initial load
duke
parents:
diff changeset
465 // closes dump file (if open)
a61af66fc99e Initial load
duke
parents:
diff changeset
466 void DumpWriter::close() {
a61af66fc99e Initial load
duke
parents:
diff changeset
467 // flush and close dump file
2143
17c778814856 6811367: Fix code in HeapDumper::dump_heap() to avoid buffer overrun
coleenp
parents: 1972
diff changeset
468 if (is_open()) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
469 flush();
a61af66fc99e Initial load
duke
parents:
diff changeset
470 ::close(file_descriptor());
2143
17c778814856 6811367: Fix code in HeapDumper::dump_heap() to avoid buffer overrun
coleenp
parents: 1972
diff changeset
471 set_file_descriptor(-1);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
472 }
a61af66fc99e Initial load
duke
parents:
diff changeset
473 }
a61af66fc99e Initial load
duke
parents:
diff changeset
474
a61af66fc99e Initial load
duke
parents:
diff changeset
475 // write directly to the file
a61af66fc99e Initial load
duke
parents:
diff changeset
476 void DumpWriter::write_internal(void* s, int len) {
a61af66fc99e Initial load
duke
parents:
diff changeset
477 if (is_open()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
478 int n = ::write(file_descriptor(), s, len);
a61af66fc99e Initial load
duke
parents:
diff changeset
479 if (n > 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
480 _bytes_written += n;
a61af66fc99e Initial load
duke
parents:
diff changeset
481 }
a61af66fc99e Initial load
duke
parents:
diff changeset
482 if (n != len) {
a61af66fc99e Initial load
duke
parents:
diff changeset
483 if (n < 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
484 set_error(strerror(errno));
a61af66fc99e Initial load
duke
parents:
diff changeset
485 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
486 set_error("file size limit");
a61af66fc99e Initial load
duke
parents:
diff changeset
487 }
a61af66fc99e Initial load
duke
parents:
diff changeset
488 ::close(file_descriptor());
a61af66fc99e Initial load
duke
parents:
diff changeset
489 set_file_descriptor(-1);
a61af66fc99e Initial load
duke
parents:
diff changeset
490 }
a61af66fc99e Initial load
duke
parents:
diff changeset
491 }
a61af66fc99e Initial load
duke
parents:
diff changeset
492 }
a61af66fc99e Initial load
duke
parents:
diff changeset
493
a61af66fc99e Initial load
duke
parents:
diff changeset
494 // write raw bytes
a61af66fc99e Initial load
duke
parents:
diff changeset
495 void DumpWriter::write_raw(void* s, int len) {
a61af66fc99e Initial load
duke
parents:
diff changeset
496 if (is_open()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
497 // flush buffer to make toom
a61af66fc99e Initial load
duke
parents:
diff changeset
498 if ((position()+ len) >= buffer_size()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
499 flush();
a61af66fc99e Initial load
duke
parents:
diff changeset
500 }
a61af66fc99e Initial load
duke
parents:
diff changeset
501
a61af66fc99e Initial load
duke
parents:
diff changeset
502 // buffer not available or too big to buffer it
a61af66fc99e Initial load
duke
parents:
diff changeset
503 if ((buffer() == NULL) || (len >= buffer_size())) {
a61af66fc99e Initial load
duke
parents:
diff changeset
504 write_internal(s, len);
a61af66fc99e Initial load
duke
parents:
diff changeset
505 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
506 // Should optimize this for u1/u2/u4/u8 sizes.
a61af66fc99e Initial load
duke
parents:
diff changeset
507 memcpy(buffer() + position(), s, len);
a61af66fc99e Initial load
duke
parents:
diff changeset
508 set_position(position() + len);
a61af66fc99e Initial load
duke
parents:
diff changeset
509 }
a61af66fc99e Initial load
duke
parents:
diff changeset
510 }
a61af66fc99e Initial load
duke
parents:
diff changeset
511 }
a61af66fc99e Initial load
duke
parents:
diff changeset
512
a61af66fc99e Initial load
duke
parents:
diff changeset
513 // flush any buffered bytes to the file
a61af66fc99e Initial load
duke
parents:
diff changeset
514 void DumpWriter::flush() {
a61af66fc99e Initial load
duke
parents:
diff changeset
515 if (is_open() && position() > 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
516 write_internal(buffer(), position());
a61af66fc99e Initial load
duke
parents:
diff changeset
517 set_position(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
518 }
a61af66fc99e Initial load
duke
parents:
diff changeset
519 }
a61af66fc99e Initial load
duke
parents:
diff changeset
520
a61af66fc99e Initial load
duke
parents:
diff changeset
521
a61af66fc99e Initial load
duke
parents:
diff changeset
522 jlong DumpWriter::current_offset() {
a61af66fc99e Initial load
duke
parents:
diff changeset
523 if (is_open()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
524 // the offset is the file offset plus whatever we have buffered
a61af66fc99e Initial load
duke
parents:
diff changeset
525 jlong offset = os::current_file_offset(file_descriptor());
a61af66fc99e Initial load
duke
parents:
diff changeset
526 assert(offset >= 0, "lseek failed");
a61af66fc99e Initial load
duke
parents:
diff changeset
527 return offset + (jlong)position();
a61af66fc99e Initial load
duke
parents:
diff changeset
528 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
529 return (jlong)-1;
a61af66fc99e Initial load
duke
parents:
diff changeset
530 }
a61af66fc99e Initial load
duke
parents:
diff changeset
531 }
a61af66fc99e Initial load
duke
parents:
diff changeset
532
a61af66fc99e Initial load
duke
parents:
diff changeset
533 void DumpWriter::seek_to_offset(jlong off) {
a61af66fc99e Initial load
duke
parents:
diff changeset
534 assert(off >= 0, "bad offset");
a61af66fc99e Initial load
duke
parents:
diff changeset
535
a61af66fc99e Initial load
duke
parents:
diff changeset
536 // need to flush before seeking
a61af66fc99e Initial load
duke
parents:
diff changeset
537 flush();
a61af66fc99e Initial load
duke
parents:
diff changeset
538
a61af66fc99e Initial load
duke
parents:
diff changeset
539 // may be closed due to I/O error
a61af66fc99e Initial load
duke
parents:
diff changeset
540 if (is_open()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
541 jlong n = os::seek_to_file_offset(file_descriptor(), off);
a61af66fc99e Initial load
duke
parents:
diff changeset
542 assert(n >= 0, "lseek failed");
a61af66fc99e Initial load
duke
parents:
diff changeset
543 }
a61af66fc99e Initial load
duke
parents:
diff changeset
544 }
a61af66fc99e Initial load
duke
parents:
diff changeset
545
a61af66fc99e Initial load
duke
parents:
diff changeset
546 void DumpWriter::write_u2(u2 x) {
a61af66fc99e Initial load
duke
parents:
diff changeset
547 u2 v;
a61af66fc99e Initial load
duke
parents:
diff changeset
548 Bytes::put_Java_u2((address)&v, x);
a61af66fc99e Initial load
duke
parents:
diff changeset
549 write_raw((void*)&v, 2);
a61af66fc99e Initial load
duke
parents:
diff changeset
550 }
a61af66fc99e Initial load
duke
parents:
diff changeset
551
a61af66fc99e Initial load
duke
parents:
diff changeset
552 void DumpWriter::write_u4(u4 x) {
a61af66fc99e Initial load
duke
parents:
diff changeset
553 u4 v;
a61af66fc99e Initial load
duke
parents:
diff changeset
554 Bytes::put_Java_u4((address)&v, x);
a61af66fc99e Initial load
duke
parents:
diff changeset
555 write_raw((void*)&v, 4);
a61af66fc99e Initial load
duke
parents:
diff changeset
556 }
a61af66fc99e Initial load
duke
parents:
diff changeset
557
a61af66fc99e Initial load
duke
parents:
diff changeset
558 void DumpWriter::write_u8(u8 x) {
a61af66fc99e Initial load
duke
parents:
diff changeset
559 u8 v;
a61af66fc99e Initial load
duke
parents:
diff changeset
560 Bytes::put_Java_u8((address)&v, x);
a61af66fc99e Initial load
duke
parents:
diff changeset
561 write_raw((void*)&v, 8);
a61af66fc99e Initial load
duke
parents:
diff changeset
562 }
a61af66fc99e Initial load
duke
parents:
diff changeset
563
a61af66fc99e Initial load
duke
parents:
diff changeset
564 void DumpWriter::write_objectID(oop o) {
a61af66fc99e Initial load
duke
parents:
diff changeset
565 address a = (address)((uintptr_t)o);
a61af66fc99e Initial load
duke
parents:
diff changeset
566 #ifdef _LP64
a61af66fc99e Initial load
duke
parents:
diff changeset
567 write_u8((u8)a);
a61af66fc99e Initial load
duke
parents:
diff changeset
568 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
569 write_u4((u4)a);
a61af66fc99e Initial load
duke
parents:
diff changeset
570 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
571 }
a61af66fc99e Initial load
duke
parents:
diff changeset
572
2177
3582bf76420e 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 2143
diff changeset
573 void DumpWriter::write_symbolID(Symbol* s) {
3582bf76420e 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 2143
diff changeset
574 address a = (address)((uintptr_t)s);
3582bf76420e 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 2143
diff changeset
575 #ifdef _LP64
3582bf76420e 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 2143
diff changeset
576 write_u8((u8)a);
3582bf76420e 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 2143
diff changeset
577 #else
3582bf76420e 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 2143
diff changeset
578 write_u4((u4)a);
3582bf76420e 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 2143
diff changeset
579 #endif
3582bf76420e 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 2143
diff changeset
580 }
3582bf76420e 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 2143
diff changeset
581
396
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
582 void DumpWriter::write_id(u4 x) {
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
583 #ifdef _LP64
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
584 write_u8((u8) x);
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
585 #else
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
586 write_u4(x);
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
587 #endif
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
588 }
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
589
0
a61af66fc99e Initial load
duke
parents:
diff changeset
590 // We use java mirror as the class ID
a61af66fc99e Initial load
duke
parents:
diff changeset
591 void DumpWriter::write_classID(Klass* k) {
a61af66fc99e Initial load
duke
parents:
diff changeset
592 write_objectID(k->java_mirror());
a61af66fc99e Initial load
duke
parents:
diff changeset
593 }
a61af66fc99e Initial load
duke
parents:
diff changeset
594
a61af66fc99e Initial load
duke
parents:
diff changeset
595
a61af66fc99e Initial load
duke
parents:
diff changeset
596
a61af66fc99e Initial load
duke
parents:
diff changeset
597 // Support class with a collection of functions used when dumping the heap
a61af66fc99e Initial load
duke
parents:
diff changeset
598
a61af66fc99e Initial load
duke
parents:
diff changeset
599 class DumperSupport : AllStatic {
a61af66fc99e Initial load
duke
parents:
diff changeset
600 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
601
a61af66fc99e Initial load
duke
parents:
diff changeset
602 // write a header of the given type
a61af66fc99e Initial load
duke
parents:
diff changeset
603 static void write_header(DumpWriter* writer, hprofTag tag, u4 len);
a61af66fc99e Initial load
duke
parents:
diff changeset
604
a61af66fc99e Initial load
duke
parents:
diff changeset
605 // returns hprof tag for the given type signature
2177
3582bf76420e 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 2143
diff changeset
606 static hprofTag sig2tag(Symbol* sig);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
607 // returns hprof tag for the given basic type
a61af66fc99e Initial load
duke
parents:
diff changeset
608 static hprofTag type2tag(BasicType type);
a61af66fc99e Initial load
duke
parents:
diff changeset
609
a61af66fc99e Initial load
duke
parents:
diff changeset
610 // returns the size of the instance of the given class
a61af66fc99e Initial load
duke
parents:
diff changeset
611 static u4 instance_size(klassOop k);
a61af66fc99e Initial load
duke
parents:
diff changeset
612
a61af66fc99e Initial load
duke
parents:
diff changeset
613 // dump a jfloat
a61af66fc99e Initial load
duke
parents:
diff changeset
614 static void dump_float(DumpWriter* writer, jfloat f);
a61af66fc99e Initial load
duke
parents:
diff changeset
615 // dump a jdouble
a61af66fc99e Initial load
duke
parents:
diff changeset
616 static void dump_double(DumpWriter* writer, jdouble d);
a61af66fc99e Initial load
duke
parents:
diff changeset
617 // dumps the raw value of the given field
a61af66fc99e Initial load
duke
parents:
diff changeset
618 static void dump_field_value(DumpWriter* writer, char type, address addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
619 // dumps static fields of the given class
a61af66fc99e Initial load
duke
parents:
diff changeset
620 static void dump_static_fields(DumpWriter* writer, klassOop k);
a61af66fc99e Initial load
duke
parents:
diff changeset
621 // dump the raw values of the instance fields of the given object
a61af66fc99e Initial load
duke
parents:
diff changeset
622 static void dump_instance_fields(DumpWriter* writer, oop o);
a61af66fc99e Initial load
duke
parents:
diff changeset
623 // dumps the definition of the instance fields for a given class
a61af66fc99e Initial load
duke
parents:
diff changeset
624 static void dump_instance_field_descriptors(DumpWriter* writer, klassOop k);
a61af66fc99e Initial load
duke
parents:
diff changeset
625 // creates HPROF_GC_INSTANCE_DUMP record for the given object
a61af66fc99e Initial load
duke
parents:
diff changeset
626 static void dump_instance(DumpWriter* writer, oop o);
a61af66fc99e Initial load
duke
parents:
diff changeset
627 // creates HPROF_GC_CLASS_DUMP record for the given class and each of its
a61af66fc99e Initial load
duke
parents:
diff changeset
628 // array classes
a61af66fc99e Initial load
duke
parents:
diff changeset
629 static void dump_class_and_array_classes(DumpWriter* writer, klassOop k);
a61af66fc99e Initial load
duke
parents:
diff changeset
630 // creates HPROF_GC_CLASS_DUMP record for a given primitive array
a61af66fc99e Initial load
duke
parents:
diff changeset
631 // class (and each multi-dimensional array class too)
a61af66fc99e Initial load
duke
parents:
diff changeset
632 static void dump_basic_type_array_class(DumpWriter* writer, klassOop k);
a61af66fc99e Initial load
duke
parents:
diff changeset
633
a61af66fc99e Initial load
duke
parents:
diff changeset
634 // creates HPROF_GC_OBJ_ARRAY_DUMP record for the given object array
a61af66fc99e Initial load
duke
parents:
diff changeset
635 static void dump_object_array(DumpWriter* writer, objArrayOop array);
a61af66fc99e Initial load
duke
parents:
diff changeset
636 // creates HPROF_GC_PRIM_ARRAY_DUMP record for the given type array
a61af66fc99e Initial load
duke
parents:
diff changeset
637 static void dump_prim_array(DumpWriter* writer, typeArrayOop array);
396
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
638 // create HPROF_FRAME record for the given method and bci
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
639 static void dump_stack_frame(DumpWriter* writer, int frame_serial_num, int class_serial_num, methodOop m, int bci);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
640 };
a61af66fc99e Initial load
duke
parents:
diff changeset
641
a61af66fc99e Initial load
duke
parents:
diff changeset
642 // write a header of the given type
a61af66fc99e Initial load
duke
parents:
diff changeset
643 void DumperSupport:: write_header(DumpWriter* writer, hprofTag tag, u4 len) {
a61af66fc99e Initial load
duke
parents:
diff changeset
644 writer->write_u1((u1)tag);
a61af66fc99e Initial load
duke
parents:
diff changeset
645 writer->write_u4(0); // current ticks
a61af66fc99e Initial load
duke
parents:
diff changeset
646 writer->write_u4(len);
a61af66fc99e Initial load
duke
parents:
diff changeset
647 }
a61af66fc99e Initial load
duke
parents:
diff changeset
648
a61af66fc99e Initial load
duke
parents:
diff changeset
649 // returns hprof tag for the given type signature
2177
3582bf76420e 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 2143
diff changeset
650 hprofTag DumperSupport::sig2tag(Symbol* sig) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
651 switch (sig->byte_at(0)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
652 case JVM_SIGNATURE_CLASS : return HPROF_NORMAL_OBJECT;
a61af66fc99e Initial load
duke
parents:
diff changeset
653 case JVM_SIGNATURE_ARRAY : return HPROF_NORMAL_OBJECT;
a61af66fc99e Initial load
duke
parents:
diff changeset
654 case JVM_SIGNATURE_BYTE : return HPROF_BYTE;
a61af66fc99e Initial load
duke
parents:
diff changeset
655 case JVM_SIGNATURE_CHAR : return HPROF_CHAR;
a61af66fc99e Initial load
duke
parents:
diff changeset
656 case JVM_SIGNATURE_FLOAT : return HPROF_FLOAT;
a61af66fc99e Initial load
duke
parents:
diff changeset
657 case JVM_SIGNATURE_DOUBLE : return HPROF_DOUBLE;
a61af66fc99e Initial load
duke
parents:
diff changeset
658 case JVM_SIGNATURE_INT : return HPROF_INT;
a61af66fc99e Initial load
duke
parents:
diff changeset
659 case JVM_SIGNATURE_LONG : return HPROF_LONG;
a61af66fc99e Initial load
duke
parents:
diff changeset
660 case JVM_SIGNATURE_SHORT : return HPROF_SHORT;
a61af66fc99e Initial load
duke
parents:
diff changeset
661 case JVM_SIGNATURE_BOOLEAN : return HPROF_BOOLEAN;
a61af66fc99e Initial load
duke
parents:
diff changeset
662 default : ShouldNotReachHere(); /* to shut up compiler */ return HPROF_BYTE;
a61af66fc99e Initial load
duke
parents:
diff changeset
663 }
a61af66fc99e Initial load
duke
parents:
diff changeset
664 }
a61af66fc99e Initial load
duke
parents:
diff changeset
665
a61af66fc99e Initial load
duke
parents:
diff changeset
666 hprofTag DumperSupport::type2tag(BasicType type) {
a61af66fc99e Initial load
duke
parents:
diff changeset
667 switch (type) {
a61af66fc99e Initial load
duke
parents:
diff changeset
668 case T_BYTE : return HPROF_BYTE;
a61af66fc99e Initial load
duke
parents:
diff changeset
669 case T_CHAR : return HPROF_CHAR;
a61af66fc99e Initial load
duke
parents:
diff changeset
670 case T_FLOAT : return HPROF_FLOAT;
a61af66fc99e Initial load
duke
parents:
diff changeset
671 case T_DOUBLE : return HPROF_DOUBLE;
a61af66fc99e Initial load
duke
parents:
diff changeset
672 case T_INT : return HPROF_INT;
a61af66fc99e Initial load
duke
parents:
diff changeset
673 case T_LONG : return HPROF_LONG;
a61af66fc99e Initial load
duke
parents:
diff changeset
674 case T_SHORT : return HPROF_SHORT;
a61af66fc99e Initial load
duke
parents:
diff changeset
675 case T_BOOLEAN : return HPROF_BOOLEAN;
a61af66fc99e Initial load
duke
parents:
diff changeset
676 default : ShouldNotReachHere(); /* to shut up compiler */ return HPROF_BYTE;
a61af66fc99e Initial load
duke
parents:
diff changeset
677 }
a61af66fc99e Initial load
duke
parents:
diff changeset
678 }
a61af66fc99e Initial load
duke
parents:
diff changeset
679
a61af66fc99e Initial load
duke
parents:
diff changeset
680 // dump a jfloat
a61af66fc99e Initial load
duke
parents:
diff changeset
681 void DumperSupport::dump_float(DumpWriter* writer, jfloat f) {
a61af66fc99e Initial load
duke
parents:
diff changeset
682 if (g_isnan(f)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
683 writer->write_u4(0x7fc00000); // collapsing NaNs
a61af66fc99e Initial load
duke
parents:
diff changeset
684 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
685 union {
a61af66fc99e Initial load
duke
parents:
diff changeset
686 int i;
a61af66fc99e Initial load
duke
parents:
diff changeset
687 float f;
a61af66fc99e Initial load
duke
parents:
diff changeset
688 } u;
a61af66fc99e Initial load
duke
parents:
diff changeset
689 u.f = (float)f;
a61af66fc99e Initial load
duke
parents:
diff changeset
690 writer->write_u4((u4)u.i);
a61af66fc99e Initial load
duke
parents:
diff changeset
691 }
a61af66fc99e Initial load
duke
parents:
diff changeset
692 }
a61af66fc99e Initial load
duke
parents:
diff changeset
693
a61af66fc99e Initial load
duke
parents:
diff changeset
694 // dump a jdouble
a61af66fc99e Initial load
duke
parents:
diff changeset
695 void DumperSupport::dump_double(DumpWriter* writer, jdouble d) {
a61af66fc99e Initial load
duke
parents:
diff changeset
696 union {
a61af66fc99e Initial load
duke
parents:
diff changeset
697 jlong l;
a61af66fc99e Initial load
duke
parents:
diff changeset
698 double d;
a61af66fc99e Initial load
duke
parents:
diff changeset
699 } u;
a61af66fc99e Initial load
duke
parents:
diff changeset
700 if (g_isnan(d)) { // collapsing NaNs
a61af66fc99e Initial load
duke
parents:
diff changeset
701 u.l = (jlong)(0x7ff80000);
a61af66fc99e Initial load
duke
parents:
diff changeset
702 u.l = (u.l << 32);
a61af66fc99e Initial load
duke
parents:
diff changeset
703 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
704 u.d = (double)d;
a61af66fc99e Initial load
duke
parents:
diff changeset
705 }
a61af66fc99e Initial load
duke
parents:
diff changeset
706 writer->write_u8((u8)u.l);
a61af66fc99e Initial load
duke
parents:
diff changeset
707 }
a61af66fc99e Initial load
duke
parents:
diff changeset
708
a61af66fc99e Initial load
duke
parents:
diff changeset
709 // dumps the raw value of the given field
a61af66fc99e Initial load
duke
parents:
diff changeset
710 void DumperSupport::dump_field_value(DumpWriter* writer, char type, address addr) {
a61af66fc99e Initial load
duke
parents:
diff changeset
711 switch (type) {
a61af66fc99e Initial load
duke
parents:
diff changeset
712 case JVM_SIGNATURE_CLASS :
a61af66fc99e Initial load
duke
parents:
diff changeset
713 case JVM_SIGNATURE_ARRAY : {
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 29
diff changeset
714 oop o;
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 29
diff changeset
715 if (UseCompressedOops) {
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 29
diff changeset
716 o = oopDesc::load_decode_heap_oop((narrowOop*)addr);
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 29
diff changeset
717 } else {
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 29
diff changeset
718 o = oopDesc::load_decode_heap_oop((oop*)addr);
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 29
diff changeset
719 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
720
a61af66fc99e Initial load
duke
parents:
diff changeset
721 // reflection and sun.misc.Unsafe classes may have a reference to a
a61af66fc99e Initial load
duke
parents:
diff changeset
722 // klassOop so filter it out.
a61af66fc99e Initial load
duke
parents:
diff changeset
723 if (o != NULL && o->is_klass()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
724 o = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
725 }
a61af66fc99e Initial load
duke
parents:
diff changeset
726
a61af66fc99e Initial load
duke
parents:
diff changeset
727 // FIXME: When sharing is enabled we don't emit field references to objects
a61af66fc99e Initial load
duke
parents:
diff changeset
728 // in shared spaces. We can remove this once we write records for the classes
a61af66fc99e Initial load
duke
parents:
diff changeset
729 // and strings that are shared.
a61af66fc99e Initial load
duke
parents:
diff changeset
730 if (o != NULL && o->is_shared()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
731 o = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
732 }
a61af66fc99e Initial load
duke
parents:
diff changeset
733 writer->write_objectID(o);
a61af66fc99e Initial load
duke
parents:
diff changeset
734 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
735 }
a61af66fc99e Initial load
duke
parents:
diff changeset
736 case JVM_SIGNATURE_BYTE : {
a61af66fc99e Initial load
duke
parents:
diff changeset
737 jbyte* b = (jbyte*)addr;
a61af66fc99e Initial load
duke
parents:
diff changeset
738 writer->write_u1((u1)*b);
a61af66fc99e Initial load
duke
parents:
diff changeset
739 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
740 }
a61af66fc99e Initial load
duke
parents:
diff changeset
741 case JVM_SIGNATURE_CHAR : {
a61af66fc99e Initial load
duke
parents:
diff changeset
742 jchar* c = (jchar*)addr;
a61af66fc99e Initial load
duke
parents:
diff changeset
743 writer->write_u2((u2)*c);
a61af66fc99e Initial load
duke
parents:
diff changeset
744 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
745 }
a61af66fc99e Initial load
duke
parents:
diff changeset
746 case JVM_SIGNATURE_SHORT : {
a61af66fc99e Initial load
duke
parents:
diff changeset
747 jshort* s = (jshort*)addr;
a61af66fc99e Initial load
duke
parents:
diff changeset
748 writer->write_u2((u2)*s);
a61af66fc99e Initial load
duke
parents:
diff changeset
749 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
750 }
a61af66fc99e Initial load
duke
parents:
diff changeset
751 case JVM_SIGNATURE_FLOAT : {
a61af66fc99e Initial load
duke
parents:
diff changeset
752 jfloat* f = (jfloat*)addr;
a61af66fc99e Initial load
duke
parents:
diff changeset
753 dump_float(writer, *f);
a61af66fc99e Initial load
duke
parents:
diff changeset
754 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
755 }
a61af66fc99e Initial load
duke
parents:
diff changeset
756 case JVM_SIGNATURE_DOUBLE : {
a61af66fc99e Initial load
duke
parents:
diff changeset
757 jdouble* f = (jdouble*)addr;
a61af66fc99e Initial load
duke
parents:
diff changeset
758 dump_double(writer, *f);
a61af66fc99e Initial load
duke
parents:
diff changeset
759 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
760 }
a61af66fc99e Initial load
duke
parents:
diff changeset
761 case JVM_SIGNATURE_INT : {
a61af66fc99e Initial load
duke
parents:
diff changeset
762 jint* i = (jint*)addr;
a61af66fc99e Initial load
duke
parents:
diff changeset
763 writer->write_u4((u4)*i);
a61af66fc99e Initial load
duke
parents:
diff changeset
764 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
765 }
a61af66fc99e Initial load
duke
parents:
diff changeset
766 case JVM_SIGNATURE_LONG : {
a61af66fc99e Initial load
duke
parents:
diff changeset
767 jlong* l = (jlong*)addr;
a61af66fc99e Initial load
duke
parents:
diff changeset
768 writer->write_u8((u8)*l);
a61af66fc99e Initial load
duke
parents:
diff changeset
769 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
770 }
a61af66fc99e Initial load
duke
parents:
diff changeset
771 case JVM_SIGNATURE_BOOLEAN : {
a61af66fc99e Initial load
duke
parents:
diff changeset
772 jboolean* b = (jboolean*)addr;
a61af66fc99e Initial load
duke
parents:
diff changeset
773 writer->write_u1((u1)*b);
a61af66fc99e Initial load
duke
parents:
diff changeset
774 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
775 }
a61af66fc99e Initial load
duke
parents:
diff changeset
776 default : ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
777 }
a61af66fc99e Initial load
duke
parents:
diff changeset
778 }
a61af66fc99e Initial load
duke
parents:
diff changeset
779
a61af66fc99e Initial load
duke
parents:
diff changeset
780 // returns the size of the instance of the given class
a61af66fc99e Initial load
duke
parents:
diff changeset
781 u4 DumperSupport::instance_size(klassOop k) {
a61af66fc99e Initial load
duke
parents:
diff changeset
782 HandleMark hm;
a61af66fc99e Initial load
duke
parents:
diff changeset
783 instanceKlassHandle ikh = instanceKlassHandle(Thread::current(), k);
a61af66fc99e Initial load
duke
parents:
diff changeset
784
a61af66fc99e Initial load
duke
parents:
diff changeset
785 int size = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
786
a61af66fc99e Initial load
duke
parents:
diff changeset
787 for (FieldStream fld(ikh, false, false); !fld.eos(); fld.next()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
788 if (!fld.access_flags().is_static()) {
2177
3582bf76420e 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 2143
diff changeset
789 Symbol* sig = fld.signature();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
790 switch (sig->byte_at(0)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
791 case JVM_SIGNATURE_CLASS :
a61af66fc99e Initial load
duke
parents:
diff changeset
792 case JVM_SIGNATURE_ARRAY : size += oopSize; break;
a61af66fc99e Initial load
duke
parents:
diff changeset
793
a61af66fc99e Initial load
duke
parents:
diff changeset
794 case JVM_SIGNATURE_BYTE :
a61af66fc99e Initial load
duke
parents:
diff changeset
795 case JVM_SIGNATURE_BOOLEAN : size += 1; break;
a61af66fc99e Initial load
duke
parents:
diff changeset
796
a61af66fc99e Initial load
duke
parents:
diff changeset
797 case JVM_SIGNATURE_CHAR :
a61af66fc99e Initial load
duke
parents:
diff changeset
798 case JVM_SIGNATURE_SHORT : size += 2; break;
a61af66fc99e Initial load
duke
parents:
diff changeset
799
a61af66fc99e Initial load
duke
parents:
diff changeset
800 case JVM_SIGNATURE_INT :
a61af66fc99e Initial load
duke
parents:
diff changeset
801 case JVM_SIGNATURE_FLOAT : size += 4; break;
a61af66fc99e Initial load
duke
parents:
diff changeset
802
a61af66fc99e Initial load
duke
parents:
diff changeset
803 case JVM_SIGNATURE_LONG :
a61af66fc99e Initial load
duke
parents:
diff changeset
804 case JVM_SIGNATURE_DOUBLE : size += 8; break;
a61af66fc99e Initial load
duke
parents:
diff changeset
805
a61af66fc99e Initial load
duke
parents:
diff changeset
806 default : ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
807 }
a61af66fc99e Initial load
duke
parents:
diff changeset
808 }
a61af66fc99e Initial load
duke
parents:
diff changeset
809 }
a61af66fc99e Initial load
duke
parents:
diff changeset
810 return (u4)size;
a61af66fc99e Initial load
duke
parents:
diff changeset
811 }
a61af66fc99e Initial load
duke
parents:
diff changeset
812
a61af66fc99e Initial load
duke
parents:
diff changeset
813 // dumps static fields of the given class
a61af66fc99e Initial load
duke
parents:
diff changeset
814 void DumperSupport::dump_static_fields(DumpWriter* writer, klassOop k) {
a61af66fc99e Initial load
duke
parents:
diff changeset
815 HandleMark hm;
a61af66fc99e Initial load
duke
parents:
diff changeset
816 instanceKlassHandle ikh = instanceKlassHandle(Thread::current(), k);
a61af66fc99e Initial load
duke
parents:
diff changeset
817
a61af66fc99e Initial load
duke
parents:
diff changeset
818 // pass 1 - count the static fields
a61af66fc99e Initial load
duke
parents:
diff changeset
819 u2 field_count = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
820 for (FieldStream fldc(ikh, true, true); !fldc.eos(); fldc.next()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
821 if (fldc.access_flags().is_static()) field_count++;
a61af66fc99e Initial load
duke
parents:
diff changeset
822 }
a61af66fc99e Initial load
duke
parents:
diff changeset
823
a61af66fc99e Initial load
duke
parents:
diff changeset
824 writer->write_u2(field_count);
a61af66fc99e Initial load
duke
parents:
diff changeset
825
a61af66fc99e Initial load
duke
parents:
diff changeset
826 // pass 2 - dump the field descriptors and raw values
a61af66fc99e Initial load
duke
parents:
diff changeset
827 for (FieldStream fld(ikh, true, true); !fld.eos(); fld.next()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
828 if (fld.access_flags().is_static()) {
2177
3582bf76420e 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 2143
diff changeset
829 Symbol* sig = fld.signature();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
830
2177
3582bf76420e 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 2143
diff changeset
831 writer->write_symbolID(fld.name()); // name
0
a61af66fc99e Initial load
duke
parents:
diff changeset
832 writer->write_u1(sig2tag(sig)); // type
a61af66fc99e Initial load
duke
parents:
diff changeset
833
a61af66fc99e Initial load
duke
parents:
diff changeset
834 // value
a61af66fc99e Initial load
duke
parents:
diff changeset
835 int offset = fld.offset();
2377
57552dca1708 7029509: nightly failures after static fields in Class
never
parents: 2225
diff changeset
836 address addr = (address)ikh->java_mirror() + offset;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
837
a61af66fc99e Initial load
duke
parents:
diff changeset
838 dump_field_value(writer, sig->byte_at(0), addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
839 }
a61af66fc99e Initial load
duke
parents:
diff changeset
840 }
a61af66fc99e Initial load
duke
parents:
diff changeset
841 }
a61af66fc99e Initial load
duke
parents:
diff changeset
842
a61af66fc99e Initial load
duke
parents:
diff changeset
843 // dump the raw values of the instance fields of the given object
a61af66fc99e Initial load
duke
parents:
diff changeset
844 void DumperSupport::dump_instance_fields(DumpWriter* writer, oop o) {
a61af66fc99e Initial load
duke
parents:
diff changeset
845 HandleMark hm;
a61af66fc99e Initial load
duke
parents:
diff changeset
846 instanceKlassHandle ikh = instanceKlassHandle(Thread::current(), o->klass());
a61af66fc99e Initial load
duke
parents:
diff changeset
847
a61af66fc99e Initial load
duke
parents:
diff changeset
848 for (FieldStream fld(ikh, false, false); !fld.eos(); fld.next()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
849 if (!fld.access_flags().is_static()) {
2177
3582bf76420e 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 2143
diff changeset
850 Symbol* sig = fld.signature();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
851 address addr = (address)o + fld.offset();
a61af66fc99e Initial load
duke
parents:
diff changeset
852
a61af66fc99e Initial load
duke
parents:
diff changeset
853 dump_field_value(writer, sig->byte_at(0), addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
854 }
a61af66fc99e Initial load
duke
parents:
diff changeset
855 }
a61af66fc99e Initial load
duke
parents:
diff changeset
856 }
a61af66fc99e Initial load
duke
parents:
diff changeset
857
a61af66fc99e Initial load
duke
parents:
diff changeset
858 // dumps the definition of the instance fields for a given class
a61af66fc99e Initial load
duke
parents:
diff changeset
859 void DumperSupport::dump_instance_field_descriptors(DumpWriter* writer, klassOop k) {
a61af66fc99e Initial load
duke
parents:
diff changeset
860 HandleMark hm;
a61af66fc99e Initial load
duke
parents:
diff changeset
861 instanceKlassHandle ikh = instanceKlassHandle(Thread::current(), k);
a61af66fc99e Initial load
duke
parents:
diff changeset
862
a61af66fc99e Initial load
duke
parents:
diff changeset
863 // pass 1 - count the instance fields
a61af66fc99e Initial load
duke
parents:
diff changeset
864 u2 field_count = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
865 for (FieldStream fldc(ikh, true, true); !fldc.eos(); fldc.next()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
866 if (!fldc.access_flags().is_static()) field_count++;
a61af66fc99e Initial load
duke
parents:
diff changeset
867 }
a61af66fc99e Initial load
duke
parents:
diff changeset
868
a61af66fc99e Initial load
duke
parents:
diff changeset
869 writer->write_u2(field_count);
a61af66fc99e Initial load
duke
parents:
diff changeset
870
a61af66fc99e Initial load
duke
parents:
diff changeset
871 // pass 2 - dump the field descriptors
a61af66fc99e Initial load
duke
parents:
diff changeset
872 for (FieldStream fld(ikh, true, true); !fld.eos(); fld.next()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
873 if (!fld.access_flags().is_static()) {
2177
3582bf76420e 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 2143
diff changeset
874 Symbol* sig = fld.signature();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
875
2177
3582bf76420e 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 2143
diff changeset
876 writer->write_symbolID(fld.name()); // name
0
a61af66fc99e Initial load
duke
parents:
diff changeset
877 writer->write_u1(sig2tag(sig)); // type
a61af66fc99e Initial load
duke
parents:
diff changeset
878 }
a61af66fc99e Initial load
duke
parents:
diff changeset
879 }
a61af66fc99e Initial load
duke
parents:
diff changeset
880 }
a61af66fc99e Initial load
duke
parents:
diff changeset
881
a61af66fc99e Initial load
duke
parents:
diff changeset
882 // creates HPROF_GC_INSTANCE_DUMP record for the given object
a61af66fc99e Initial load
duke
parents:
diff changeset
883 void DumperSupport::dump_instance(DumpWriter* writer, oop o) {
a61af66fc99e Initial load
duke
parents:
diff changeset
884 klassOop k = o->klass();
a61af66fc99e Initial load
duke
parents:
diff changeset
885
a61af66fc99e Initial load
duke
parents:
diff changeset
886 writer->write_u1(HPROF_GC_INSTANCE_DUMP);
a61af66fc99e Initial load
duke
parents:
diff changeset
887 writer->write_objectID(o);
a61af66fc99e Initial load
duke
parents:
diff changeset
888 writer->write_u4(STACK_TRACE_ID);
a61af66fc99e Initial load
duke
parents:
diff changeset
889
a61af66fc99e Initial load
duke
parents:
diff changeset
890 // class ID
a61af66fc99e Initial load
duke
parents:
diff changeset
891 writer->write_classID(Klass::cast(k));
a61af66fc99e Initial load
duke
parents:
diff changeset
892
a61af66fc99e Initial load
duke
parents:
diff changeset
893 // number of bytes that follow
a61af66fc99e Initial load
duke
parents:
diff changeset
894 writer->write_u4(instance_size(k) );
a61af66fc99e Initial load
duke
parents:
diff changeset
895
a61af66fc99e Initial load
duke
parents:
diff changeset
896 // field values
a61af66fc99e Initial load
duke
parents:
diff changeset
897 dump_instance_fields(writer, o);
a61af66fc99e Initial load
duke
parents:
diff changeset
898 }
a61af66fc99e Initial load
duke
parents:
diff changeset
899
a61af66fc99e Initial load
duke
parents:
diff changeset
900 // creates HPROF_GC_CLASS_DUMP record for the given class and each of
a61af66fc99e Initial load
duke
parents:
diff changeset
901 // its array classes
a61af66fc99e Initial load
duke
parents:
diff changeset
902 void DumperSupport::dump_class_and_array_classes(DumpWriter* writer, klassOop k) {
a61af66fc99e Initial load
duke
parents:
diff changeset
903 Klass* klass = Klass::cast(k);
a61af66fc99e Initial load
duke
parents:
diff changeset
904 assert(klass->oop_is_instance(), "not an instanceKlass");
a61af66fc99e Initial load
duke
parents:
diff changeset
905 instanceKlass* ik = (instanceKlass*)klass;
a61af66fc99e Initial load
duke
parents:
diff changeset
906
a61af66fc99e Initial load
duke
parents:
diff changeset
907 writer->write_u1(HPROF_GC_CLASS_DUMP);
a61af66fc99e Initial load
duke
parents:
diff changeset
908
a61af66fc99e Initial load
duke
parents:
diff changeset
909 // class ID
a61af66fc99e Initial load
duke
parents:
diff changeset
910 writer->write_classID(ik);
a61af66fc99e Initial load
duke
parents:
diff changeset
911 writer->write_u4(STACK_TRACE_ID);
a61af66fc99e Initial load
duke
parents:
diff changeset
912
a61af66fc99e Initial load
duke
parents:
diff changeset
913 // super class ID
a61af66fc99e Initial load
duke
parents:
diff changeset
914 klassOop java_super = ik->java_super();
a61af66fc99e Initial load
duke
parents:
diff changeset
915 if (java_super == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
916 writer->write_objectID(NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
917 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
918 writer->write_classID(Klass::cast(java_super));
a61af66fc99e Initial load
duke
parents:
diff changeset
919 }
a61af66fc99e Initial load
duke
parents:
diff changeset
920
a61af66fc99e Initial load
duke
parents:
diff changeset
921 writer->write_objectID(ik->class_loader());
a61af66fc99e Initial load
duke
parents:
diff changeset
922 writer->write_objectID(ik->signers());
a61af66fc99e Initial load
duke
parents:
diff changeset
923 writer->write_objectID(ik->protection_domain());
a61af66fc99e Initial load
duke
parents:
diff changeset
924
a61af66fc99e Initial load
duke
parents:
diff changeset
925 // reserved
a61af66fc99e Initial load
duke
parents:
diff changeset
926 writer->write_objectID(NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
927 writer->write_objectID(NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
928
a61af66fc99e Initial load
duke
parents:
diff changeset
929 // instance size
a61af66fc99e Initial load
duke
parents:
diff changeset
930 writer->write_u4(DumperSupport::instance_size(k));
a61af66fc99e Initial load
duke
parents:
diff changeset
931
a61af66fc99e Initial load
duke
parents:
diff changeset
932 // size of constant pool - ignored by HAT 1.1
a61af66fc99e Initial load
duke
parents:
diff changeset
933 writer->write_u2(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
934
a61af66fc99e Initial load
duke
parents:
diff changeset
935 // number of static fields
a61af66fc99e Initial load
duke
parents:
diff changeset
936 dump_static_fields(writer, k);
a61af66fc99e Initial load
duke
parents:
diff changeset
937
a61af66fc99e Initial load
duke
parents:
diff changeset
938 // description of instance fields
a61af66fc99e Initial load
duke
parents:
diff changeset
939 dump_instance_field_descriptors(writer, k);
a61af66fc99e Initial load
duke
parents:
diff changeset
940
a61af66fc99e Initial load
duke
parents:
diff changeset
941 // array classes
a61af66fc99e Initial load
duke
parents:
diff changeset
942 k = klass->array_klass_or_null();
a61af66fc99e Initial load
duke
parents:
diff changeset
943 while (k != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
944 Klass* klass = Klass::cast(k);
a61af66fc99e Initial load
duke
parents:
diff changeset
945 assert(klass->oop_is_objArray(), "not an objArrayKlass");
a61af66fc99e Initial load
duke
parents:
diff changeset
946
a61af66fc99e Initial load
duke
parents:
diff changeset
947 writer->write_u1(HPROF_GC_CLASS_DUMP);
a61af66fc99e Initial load
duke
parents:
diff changeset
948 writer->write_classID(klass);
a61af66fc99e Initial load
duke
parents:
diff changeset
949 writer->write_u4(STACK_TRACE_ID);
a61af66fc99e Initial load
duke
parents:
diff changeset
950
a61af66fc99e Initial load
duke
parents:
diff changeset
951 // super class of array classes is java.lang.Object
a61af66fc99e Initial load
duke
parents:
diff changeset
952 java_super = klass->java_super();
a61af66fc99e Initial load
duke
parents:
diff changeset
953 assert(java_super != NULL, "checking");
a61af66fc99e Initial load
duke
parents:
diff changeset
954 writer->write_classID(Klass::cast(java_super));
a61af66fc99e Initial load
duke
parents:
diff changeset
955
a61af66fc99e Initial load
duke
parents:
diff changeset
956 writer->write_objectID(ik->class_loader());
a61af66fc99e Initial load
duke
parents:
diff changeset
957 writer->write_objectID(ik->signers());
a61af66fc99e Initial load
duke
parents:
diff changeset
958 writer->write_objectID(ik->protection_domain());
a61af66fc99e Initial load
duke
parents:
diff changeset
959
a61af66fc99e Initial load
duke
parents:
diff changeset
960 writer->write_objectID(NULL); // reserved
a61af66fc99e Initial load
duke
parents:
diff changeset
961 writer->write_objectID(NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
962 writer->write_u4(0); // instance size
a61af66fc99e Initial load
duke
parents:
diff changeset
963 writer->write_u2(0); // constant pool
a61af66fc99e Initial load
duke
parents:
diff changeset
964 writer->write_u2(0); // static fields
a61af66fc99e Initial load
duke
parents:
diff changeset
965 writer->write_u2(0); // instance fields
a61af66fc99e Initial load
duke
parents:
diff changeset
966
a61af66fc99e Initial load
duke
parents:
diff changeset
967 // get the array class for the next rank
a61af66fc99e Initial load
duke
parents:
diff changeset
968 k = klass->array_klass_or_null();
a61af66fc99e Initial load
duke
parents:
diff changeset
969 }
a61af66fc99e Initial load
duke
parents:
diff changeset
970 }
a61af66fc99e Initial load
duke
parents:
diff changeset
971
a61af66fc99e Initial load
duke
parents:
diff changeset
972 // creates HPROF_GC_CLASS_DUMP record for a given primitive array
a61af66fc99e Initial load
duke
parents:
diff changeset
973 // class (and each multi-dimensional array class too)
a61af66fc99e Initial load
duke
parents:
diff changeset
974 void DumperSupport::dump_basic_type_array_class(DumpWriter* writer, klassOop k) {
a61af66fc99e Initial load
duke
parents:
diff changeset
975 // array classes
a61af66fc99e Initial load
duke
parents:
diff changeset
976 while (k != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
977 Klass* klass = Klass::cast(k);
a61af66fc99e Initial load
duke
parents:
diff changeset
978
a61af66fc99e Initial load
duke
parents:
diff changeset
979 writer->write_u1(HPROF_GC_CLASS_DUMP);
a61af66fc99e Initial load
duke
parents:
diff changeset
980 writer->write_classID(klass);
a61af66fc99e Initial load
duke
parents:
diff changeset
981 writer->write_u4(STACK_TRACE_ID);
a61af66fc99e Initial load
duke
parents:
diff changeset
982
a61af66fc99e Initial load
duke
parents:
diff changeset
983 // super class of array classes is java.lang.Object
a61af66fc99e Initial load
duke
parents:
diff changeset
984 klassOop java_super = klass->java_super();
a61af66fc99e Initial load
duke
parents:
diff changeset
985 assert(java_super != NULL, "checking");
a61af66fc99e Initial load
duke
parents:
diff changeset
986 writer->write_classID(Klass::cast(java_super));
a61af66fc99e Initial load
duke
parents:
diff changeset
987
a61af66fc99e Initial load
duke
parents:
diff changeset
988 writer->write_objectID(NULL); // loader
a61af66fc99e Initial load
duke
parents:
diff changeset
989 writer->write_objectID(NULL); // signers
a61af66fc99e Initial load
duke
parents:
diff changeset
990 writer->write_objectID(NULL); // protection domain
a61af66fc99e Initial load
duke
parents:
diff changeset
991
a61af66fc99e Initial load
duke
parents:
diff changeset
992 writer->write_objectID(NULL); // reserved
a61af66fc99e Initial load
duke
parents:
diff changeset
993 writer->write_objectID(NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
994 writer->write_u4(0); // instance size
a61af66fc99e Initial load
duke
parents:
diff changeset
995 writer->write_u2(0); // constant pool
a61af66fc99e Initial load
duke
parents:
diff changeset
996 writer->write_u2(0); // static fields
a61af66fc99e Initial load
duke
parents:
diff changeset
997 writer->write_u2(0); // instance fields
a61af66fc99e Initial load
duke
parents:
diff changeset
998
a61af66fc99e Initial load
duke
parents:
diff changeset
999 // get the array class for the next rank
a61af66fc99e Initial load
duke
parents:
diff changeset
1000 k = klass->array_klass_or_null();
a61af66fc99e Initial load
duke
parents:
diff changeset
1001 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1002 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1003
a61af66fc99e Initial load
duke
parents:
diff changeset
1004 // creates HPROF_GC_OBJ_ARRAY_DUMP record for the given object array
a61af66fc99e Initial load
duke
parents:
diff changeset
1005 void DumperSupport::dump_object_array(DumpWriter* writer, objArrayOop array) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1006
a61af66fc99e Initial load
duke
parents:
diff changeset
1007 // filter this
a61af66fc99e Initial load
duke
parents:
diff changeset
1008 if (array->klass() == Universe::systemObjArrayKlassObj()) return;
a61af66fc99e Initial load
duke
parents:
diff changeset
1009
a61af66fc99e Initial load
duke
parents:
diff changeset
1010 writer->write_u1(HPROF_GC_OBJ_ARRAY_DUMP);
a61af66fc99e Initial load
duke
parents:
diff changeset
1011 writer->write_objectID(array);
a61af66fc99e Initial load
duke
parents:
diff changeset
1012 writer->write_u4(STACK_TRACE_ID);
a61af66fc99e Initial load
duke
parents:
diff changeset
1013 writer->write_u4((u4)array->length());
a61af66fc99e Initial load
duke
parents:
diff changeset
1014
a61af66fc99e Initial load
duke
parents:
diff changeset
1015 // array class ID
a61af66fc99e Initial load
duke
parents:
diff changeset
1016 writer->write_classID(Klass::cast(array->klass()));
a61af66fc99e Initial load
duke
parents:
diff changeset
1017
a61af66fc99e Initial load
duke
parents:
diff changeset
1018 // [id]* elements
a61af66fc99e Initial load
duke
parents:
diff changeset
1019 for (int index=0; index<array->length(); index++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1020 oop o = array->obj_at(index);
a61af66fc99e Initial load
duke
parents:
diff changeset
1021 writer->write_objectID(o);
a61af66fc99e Initial load
duke
parents:
diff changeset
1022 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1023 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1024
a61af66fc99e Initial load
duke
parents:
diff changeset
1025 #define WRITE_ARRAY(Array, Type, Size) \
a61af66fc99e Initial load
duke
parents:
diff changeset
1026 for (int i=0; i<Array->length(); i++) { writer->write_##Size((Size)array->Type##_at(i)); }
a61af66fc99e Initial load
duke
parents:
diff changeset
1027
a61af66fc99e Initial load
duke
parents:
diff changeset
1028
a61af66fc99e Initial load
duke
parents:
diff changeset
1029 // creates HPROF_GC_PRIM_ARRAY_DUMP record for the given type array
a61af66fc99e Initial load
duke
parents:
diff changeset
1030 void DumperSupport::dump_prim_array(DumpWriter* writer, typeArrayOop array) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1031 BasicType type = typeArrayKlass::cast(array->klass())->element_type();
a61af66fc99e Initial load
duke
parents:
diff changeset
1032
a61af66fc99e Initial load
duke
parents:
diff changeset
1033 writer->write_u1(HPROF_GC_PRIM_ARRAY_DUMP);
a61af66fc99e Initial load
duke
parents:
diff changeset
1034 writer->write_objectID(array);
a61af66fc99e Initial load
duke
parents:
diff changeset
1035 writer->write_u4(STACK_TRACE_ID);
a61af66fc99e Initial load
duke
parents:
diff changeset
1036 writer->write_u4((u4)array->length());
a61af66fc99e Initial load
duke
parents:
diff changeset
1037 writer->write_u1(type2tag(type));
a61af66fc99e Initial load
duke
parents:
diff changeset
1038
a61af66fc99e Initial load
duke
parents:
diff changeset
1039 // nothing to copy
a61af66fc99e Initial load
duke
parents:
diff changeset
1040 if (array->length() == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1041 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
1042 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1043
a61af66fc99e Initial load
duke
parents:
diff changeset
1044 // If the byte ordering is big endian then we can copy most types directly
29
d5fc211aea19 6633953: type2aelembytes{T_ADDRESS} should be 8 bytes in 64 bit VM
kvn
parents: 0
diff changeset
1045 int length_in_bytes = array->length() * type2aelembytes(type);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1046 assert(length_in_bytes > 0, "nothing to copy");
a61af66fc99e Initial load
duke
parents:
diff changeset
1047
a61af66fc99e Initial load
duke
parents:
diff changeset
1048 switch (type) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1049 case T_INT : {
a61af66fc99e Initial load
duke
parents:
diff changeset
1050 if (Bytes::is_Java_byte_ordering_different()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1051 WRITE_ARRAY(array, int, u4);
a61af66fc99e Initial load
duke
parents:
diff changeset
1052 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1053 writer->write_raw((void*)(array->int_at_addr(0)), length_in_bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
1054 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1055 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1056 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1057 case T_BYTE : {
a61af66fc99e Initial load
duke
parents:
diff changeset
1058 writer->write_raw((void*)(array->byte_at_addr(0)), length_in_bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
1059 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1060 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1061 case T_CHAR : {
a61af66fc99e Initial load
duke
parents:
diff changeset
1062 if (Bytes::is_Java_byte_ordering_different()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1063 WRITE_ARRAY(array, char, u2);
a61af66fc99e Initial load
duke
parents:
diff changeset
1064 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1065 writer->write_raw((void*)(array->char_at_addr(0)), length_in_bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
1066 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1067 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1068 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1069 case T_SHORT : {
a61af66fc99e Initial load
duke
parents:
diff changeset
1070 if (Bytes::is_Java_byte_ordering_different()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1071 WRITE_ARRAY(array, short, u2);
a61af66fc99e Initial load
duke
parents:
diff changeset
1072 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1073 writer->write_raw((void*)(array->short_at_addr(0)), length_in_bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
1074 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1075 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1076 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1077 case T_BOOLEAN : {
a61af66fc99e Initial load
duke
parents:
diff changeset
1078 if (Bytes::is_Java_byte_ordering_different()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1079 WRITE_ARRAY(array, bool, u1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1080 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1081 writer->write_raw((void*)(array->bool_at_addr(0)), length_in_bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
1082 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1083 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1084 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1085 case T_LONG : {
a61af66fc99e Initial load
duke
parents:
diff changeset
1086 if (Bytes::is_Java_byte_ordering_different()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1087 WRITE_ARRAY(array, long, u8);
a61af66fc99e Initial load
duke
parents:
diff changeset
1088 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1089 writer->write_raw((void*)(array->long_at_addr(0)), length_in_bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
1090 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1091 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1092 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1093
a61af66fc99e Initial load
duke
parents:
diff changeset
1094 // handle float/doubles in a special value to ensure than NaNs are
a61af66fc99e Initial load
duke
parents:
diff changeset
1095 // written correctly. TO DO: Check if we can avoid this on processors that
a61af66fc99e Initial load
duke
parents:
diff changeset
1096 // use IEEE 754.
a61af66fc99e Initial load
duke
parents:
diff changeset
1097
a61af66fc99e Initial load
duke
parents:
diff changeset
1098 case T_FLOAT : {
a61af66fc99e Initial load
duke
parents:
diff changeset
1099 for (int i=0; i<array->length(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1100 dump_float( writer, array->float_at(i) );
a61af66fc99e Initial load
duke
parents:
diff changeset
1101 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1102 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1103 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1104 case T_DOUBLE : {
a61af66fc99e Initial load
duke
parents:
diff changeset
1105 for (int i=0; i<array->length(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1106 dump_double( writer, array->double_at(i) );
a61af66fc99e Initial load
duke
parents:
diff changeset
1107 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1108 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1109 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1110 default : ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
1111 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1112 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1113
396
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1114 // create a HPROF_FRAME record of the given methodOop and bci
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1115 void DumperSupport::dump_stack_frame(DumpWriter* writer,
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1116 int frame_serial_num,
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1117 int class_serial_num,
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1118 methodOop m,
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1119 int bci) {
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1120 int line_number;
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1121 if (m->is_native()) {
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1122 line_number = -3; // native frame
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1123 } else {
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1124 line_number = m->line_number_from_bci(bci);
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1125 }
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1126
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1127 write_header(writer, HPROF_FRAME, 4*oopSize + 2*sizeof(u4));
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1128 writer->write_id(frame_serial_num); // frame serial number
2177
3582bf76420e 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 2143
diff changeset
1129 writer->write_symbolID(m->name()); // method's name
3582bf76420e 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 2143
diff changeset
1130 writer->write_symbolID(m->signature()); // method's signature
396
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1131
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1132 assert(Klass::cast(m->method_holder())->oop_is_instance(), "not instanceKlass");
2177
3582bf76420e 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 2143
diff changeset
1133 writer->write_symbolID(instanceKlass::cast(m->method_holder())->source_file_name()); // source file name
396
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1134 writer->write_u4(class_serial_num); // class serial number
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1135 writer->write_u4((u4) line_number); // line number
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1136 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1137
2177
3582bf76420e 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 2143
diff changeset
1138
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1139 // Support class used to generate HPROF_UTF8 records from the entries in the
a61af66fc99e Initial load
duke
parents:
diff changeset
1140 // SymbolTable.
a61af66fc99e Initial load
duke
parents:
diff changeset
1141
2177
3582bf76420e 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 2143
diff changeset
1142 class SymbolTableDumper : public SymbolClosure {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1143 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
1144 DumpWriter* _writer;
a61af66fc99e Initial load
duke
parents:
diff changeset
1145 DumpWriter* writer() const { return _writer; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1146 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
1147 SymbolTableDumper(DumpWriter* writer) { _writer = writer; }
2177
3582bf76420e 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 2143
diff changeset
1148 void do_symbol(Symbol** p);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1149 };
a61af66fc99e Initial load
duke
parents:
diff changeset
1150
2177
3582bf76420e 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 2143
diff changeset
1151 void SymbolTableDumper::do_symbol(Symbol** p) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1152 ResourceMark rm;
2177
3582bf76420e 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 2143
diff changeset
1153 Symbol* sym = load_symbol(p);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1154 int len = sym->utf8_length();
a61af66fc99e Initial load
duke
parents:
diff changeset
1155 if (len > 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1156 char* s = sym->as_utf8();
a61af66fc99e Initial load
duke
parents:
diff changeset
1157 DumperSupport::write_header(writer(), HPROF_UTF8, oopSize + len);
2177
3582bf76420e 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 2143
diff changeset
1158 writer()->write_symbolID(sym);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1159 writer()->write_raw(s, len);
a61af66fc99e Initial load
duke
parents:
diff changeset
1160 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1161 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1162
a61af66fc99e Initial load
duke
parents:
diff changeset
1163 // Support class used to generate HPROF_GC_ROOT_JNI_LOCAL records
a61af66fc99e Initial load
duke
parents:
diff changeset
1164
a61af66fc99e Initial load
duke
parents:
diff changeset
1165 class JNILocalsDumper : public OopClosure {
a61af66fc99e Initial load
duke
parents:
diff changeset
1166 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
1167 DumpWriter* _writer;
a61af66fc99e Initial load
duke
parents:
diff changeset
1168 u4 _thread_serial_num;
396
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1169 int _frame_num;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1170 DumpWriter* writer() const { return _writer; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1171 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
1172 JNILocalsDumper(DumpWriter* writer, u4 thread_serial_num) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1173 _writer = writer;
a61af66fc99e Initial load
duke
parents:
diff changeset
1174 _thread_serial_num = thread_serial_num;
396
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1175 _frame_num = -1; // default - empty stack
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1176 }
396
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1177 void set_frame_number(int n) { _frame_num = n; }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1178 void do_oop(oop* obj_p);
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 29
diff changeset
1179 void do_oop(narrowOop* obj_p) { ShouldNotReachHere(); }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1180 };
a61af66fc99e Initial load
duke
parents:
diff changeset
1181
a61af66fc99e Initial load
duke
parents:
diff changeset
1182
a61af66fc99e Initial load
duke
parents:
diff changeset
1183 void JNILocalsDumper::do_oop(oop* obj_p) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1184 // ignore null or deleted handles
a61af66fc99e Initial load
duke
parents:
diff changeset
1185 oop o = *obj_p;
a61af66fc99e Initial load
duke
parents:
diff changeset
1186 if (o != NULL && o != JNIHandles::deleted_handle()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1187 writer()->write_u1(HPROF_GC_ROOT_JNI_LOCAL);
a61af66fc99e Initial load
duke
parents:
diff changeset
1188 writer()->write_objectID(o);
a61af66fc99e Initial load
duke
parents:
diff changeset
1189 writer()->write_u4(_thread_serial_num);
396
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1190 writer()->write_u4((u4)_frame_num);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1191 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1192 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1193
a61af66fc99e Initial load
duke
parents:
diff changeset
1194
a61af66fc99e Initial load
duke
parents:
diff changeset
1195 // Support class used to generate HPROF_GC_ROOT_JNI_GLOBAL records
a61af66fc99e Initial load
duke
parents:
diff changeset
1196
a61af66fc99e Initial load
duke
parents:
diff changeset
1197 class JNIGlobalsDumper : public OopClosure {
a61af66fc99e Initial load
duke
parents:
diff changeset
1198 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
1199 DumpWriter* _writer;
a61af66fc99e Initial load
duke
parents:
diff changeset
1200 DumpWriter* writer() const { return _writer; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1201
a61af66fc99e Initial load
duke
parents:
diff changeset
1202 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
1203 JNIGlobalsDumper(DumpWriter* writer) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1204 _writer = writer;
a61af66fc99e Initial load
duke
parents:
diff changeset
1205 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1206 void do_oop(oop* obj_p);
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 29
diff changeset
1207 void do_oop(narrowOop* obj_p) { ShouldNotReachHere(); }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1208 };
a61af66fc99e Initial load
duke
parents:
diff changeset
1209
a61af66fc99e Initial load
duke
parents:
diff changeset
1210 void JNIGlobalsDumper::do_oop(oop* obj_p) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1211 oop o = *obj_p;
a61af66fc99e Initial load
duke
parents:
diff changeset
1212
a61af66fc99e Initial load
duke
parents:
diff changeset
1213 // ignore these
a61af66fc99e Initial load
duke
parents:
diff changeset
1214 if (o == NULL || o == JNIHandles::deleted_handle()) return;
a61af66fc99e Initial load
duke
parents:
diff changeset
1215
a61af66fc99e Initial load
duke
parents:
diff changeset
1216 // we ignore global ref to symbols and other internal objects
a61af66fc99e Initial load
duke
parents:
diff changeset
1217 if (o->is_instance() || o->is_objArray() || o->is_typeArray()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1218 writer()->write_u1(HPROF_GC_ROOT_JNI_GLOBAL);
a61af66fc99e Initial load
duke
parents:
diff changeset
1219 writer()->write_objectID(o);
a61af66fc99e Initial load
duke
parents:
diff changeset
1220 writer()->write_objectID((oopDesc*)obj_p); // global ref ID
a61af66fc99e Initial load
duke
parents:
diff changeset
1221 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1222 };
a61af66fc99e Initial load
duke
parents:
diff changeset
1223
a61af66fc99e Initial load
duke
parents:
diff changeset
1224
a61af66fc99e Initial load
duke
parents:
diff changeset
1225 // Support class used to generate HPROF_GC_ROOT_MONITOR_USED records
a61af66fc99e Initial load
duke
parents:
diff changeset
1226
a61af66fc99e Initial load
duke
parents:
diff changeset
1227 class MonitorUsedDumper : public OopClosure {
a61af66fc99e Initial load
duke
parents:
diff changeset
1228 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
1229 DumpWriter* _writer;
a61af66fc99e Initial load
duke
parents:
diff changeset
1230 DumpWriter* writer() const { return _writer; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1231 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
1232 MonitorUsedDumper(DumpWriter* writer) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1233 _writer = writer;
a61af66fc99e Initial load
duke
parents:
diff changeset
1234 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1235 void do_oop(oop* obj_p) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1236 writer()->write_u1(HPROF_GC_ROOT_MONITOR_USED);
a61af66fc99e Initial load
duke
parents:
diff changeset
1237 writer()->write_objectID(*obj_p);
a61af66fc99e Initial load
duke
parents:
diff changeset
1238 }
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 29
diff changeset
1239 void do_oop(narrowOop* obj_p) { ShouldNotReachHere(); }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1240 };
a61af66fc99e Initial load
duke
parents:
diff changeset
1241
a61af66fc99e Initial load
duke
parents:
diff changeset
1242
a61af66fc99e Initial load
duke
parents:
diff changeset
1243 // Support class used to generate HPROF_GC_ROOT_STICKY_CLASS records
a61af66fc99e Initial load
duke
parents:
diff changeset
1244
a61af66fc99e Initial load
duke
parents:
diff changeset
1245 class StickyClassDumper : public OopClosure {
a61af66fc99e Initial load
duke
parents:
diff changeset
1246 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
1247 DumpWriter* _writer;
a61af66fc99e Initial load
duke
parents:
diff changeset
1248 DumpWriter* writer() const { return _writer; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1249 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
1250 StickyClassDumper(DumpWriter* writer) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1251 _writer = writer;
a61af66fc99e Initial load
duke
parents:
diff changeset
1252 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1253 void do_oop(oop* obj_p);
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 29
diff changeset
1254 void do_oop(narrowOop* obj_p) { ShouldNotReachHere(); }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1255 };
a61af66fc99e Initial load
duke
parents:
diff changeset
1256
a61af66fc99e Initial load
duke
parents:
diff changeset
1257 void StickyClassDumper::do_oop(oop* obj_p) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1258 if (*obj_p != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1259 oop o = *obj_p;
a61af66fc99e Initial load
duke
parents:
diff changeset
1260 if (o->is_klass()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1261 klassOop k = klassOop(o);
a61af66fc99e Initial load
duke
parents:
diff changeset
1262 if (Klass::cast(k)->oop_is_instance()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1263 instanceKlass* ik = instanceKlass::cast(k);
a61af66fc99e Initial load
duke
parents:
diff changeset
1264 writer()->write_u1(HPROF_GC_ROOT_STICKY_CLASS);
a61af66fc99e Initial load
duke
parents:
diff changeset
1265 writer()->write_classID(ik);
a61af66fc99e Initial load
duke
parents:
diff changeset
1266 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1267 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1268 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1269 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1270
a61af66fc99e Initial load
duke
parents:
diff changeset
1271
a61af66fc99e Initial load
duke
parents:
diff changeset
1272 class VM_HeapDumper;
a61af66fc99e Initial load
duke
parents:
diff changeset
1273
a61af66fc99e Initial load
duke
parents:
diff changeset
1274 // Support class using when iterating over the heap.
a61af66fc99e Initial load
duke
parents:
diff changeset
1275
a61af66fc99e Initial load
duke
parents:
diff changeset
1276 class HeapObjectDumper : public ObjectClosure {
a61af66fc99e Initial load
duke
parents:
diff changeset
1277 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
1278 VM_HeapDumper* _dumper;
a61af66fc99e Initial load
duke
parents:
diff changeset
1279 DumpWriter* _writer;
a61af66fc99e Initial load
duke
parents:
diff changeset
1280
a61af66fc99e Initial load
duke
parents:
diff changeset
1281 VM_HeapDumper* dumper() { return _dumper; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1282 DumpWriter* writer() { return _writer; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1283
a61af66fc99e Initial load
duke
parents:
diff changeset
1284 // used to indicate that a record has been writen
a61af66fc99e Initial load
duke
parents:
diff changeset
1285 void mark_end_of_record();
a61af66fc99e Initial load
duke
parents:
diff changeset
1286
a61af66fc99e Initial load
duke
parents:
diff changeset
1287 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
1288 HeapObjectDumper(VM_HeapDumper* dumper, DumpWriter* writer) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1289 _dumper = dumper;
a61af66fc99e Initial load
duke
parents:
diff changeset
1290 _writer = writer;
a61af66fc99e Initial load
duke
parents:
diff changeset
1291 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1292
a61af66fc99e Initial load
duke
parents:
diff changeset
1293 // called for each object in the heap
a61af66fc99e Initial load
duke
parents:
diff changeset
1294 void do_object(oop o);
a61af66fc99e Initial load
duke
parents:
diff changeset
1295 };
a61af66fc99e Initial load
duke
parents:
diff changeset
1296
a61af66fc99e Initial load
duke
parents:
diff changeset
1297 void HeapObjectDumper::do_object(oop o) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1298 // hide the sentinel for deleted handles
a61af66fc99e Initial load
duke
parents:
diff changeset
1299 if (o == JNIHandles::deleted_handle()) return;
a61af66fc99e Initial load
duke
parents:
diff changeset
1300
a61af66fc99e Initial load
duke
parents:
diff changeset
1301 // ignore KlassKlass objects
a61af66fc99e Initial load
duke
parents:
diff changeset
1302 if (o->is_klass()) return;
a61af66fc99e Initial load
duke
parents:
diff changeset
1303
a61af66fc99e Initial load
duke
parents:
diff changeset
1304 // skip classes as these emitted as HPROF_GC_CLASS_DUMP records
1142
4ce7240d622c 6914300: ciEnv should export all well known classes
never
parents: 1046
diff changeset
1305 if (o->klass() == SystemDictionary::Class_klass()) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1306 if (!java_lang_Class::is_primitive(o)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1307 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
1308 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1309 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1310
a61af66fc99e Initial load
duke
parents:
diff changeset
1311 // create a HPROF_GC_INSTANCE record for each object
a61af66fc99e Initial load
duke
parents:
diff changeset
1312 if (o->is_instance()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1313 DumperSupport::dump_instance(writer(), o);
a61af66fc99e Initial load
duke
parents:
diff changeset
1314 mark_end_of_record();
a61af66fc99e Initial load
duke
parents:
diff changeset
1315 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1316 // create a HPROF_GC_OBJ_ARRAY_DUMP record for each object array
a61af66fc99e Initial load
duke
parents:
diff changeset
1317 if (o->is_objArray()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1318 DumperSupport::dump_object_array(writer(), objArrayOop(o));
a61af66fc99e Initial load
duke
parents:
diff changeset
1319 mark_end_of_record();
a61af66fc99e Initial load
duke
parents:
diff changeset
1320 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1321 // create a HPROF_GC_PRIM_ARRAY_DUMP record for each type array
a61af66fc99e Initial load
duke
parents:
diff changeset
1322 if (o->is_typeArray()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1323 DumperSupport::dump_prim_array(writer(), typeArrayOop(o));
a61af66fc99e Initial load
duke
parents:
diff changeset
1324 mark_end_of_record();
a61af66fc99e Initial load
duke
parents:
diff changeset
1325 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1326 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1327 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1328 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1329
a61af66fc99e Initial load
duke
parents:
diff changeset
1330 // The VM operation that performs the heap dump
a61af66fc99e Initial load
duke
parents:
diff changeset
1331 class VM_HeapDumper : public VM_GC_Operation {
a61af66fc99e Initial load
duke
parents:
diff changeset
1332 private:
615
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1333 static VM_HeapDumper* _global_dumper;
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1334 static DumpWriter* _global_writer;
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1335 DumpWriter* _local_writer;
1775
30f67acf635d 6765718: Indicate which thread throwing OOME when generating the heap dump at OOME
thurka
parents: 1552
diff changeset
1336 JavaThread* _oome_thread;
30f67acf635d 6765718: Indicate which thread throwing OOME when generating the heap dump at OOME
thurka
parents: 1552
diff changeset
1337 methodOop _oome_constructor;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1338 bool _gc_before_heap_dump;
a61af66fc99e Initial load
duke
parents:
diff changeset
1339 bool _is_segmented_dump;
a61af66fc99e Initial load
duke
parents:
diff changeset
1340 jlong _dump_start;
396
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1341 GrowableArray<Klass*>* _klass_map;
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1342 ThreadStackTrace** _stack_traces;
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1343 int _num_threads;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1344
615
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1345 // accessors and setters
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1346 static VM_HeapDumper* dumper() { assert(_global_dumper != NULL, "Error"); return _global_dumper; }
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1347 static DumpWriter* writer() { assert(_global_writer != NULL, "Error"); return _global_writer; }
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1348 void set_global_dumper() {
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1349 assert(_global_dumper == NULL, "Error");
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1350 _global_dumper = this;
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1351 }
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1352 void set_global_writer() {
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1353 assert(_global_writer == NULL, "Error");
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1354 _global_writer = _local_writer;
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1355 }
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1356 void clear_global_dumper() { _global_dumper = NULL; }
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1357 void clear_global_writer() { _global_writer = NULL; }
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1358
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1359 bool is_segmented_dump() const { return _is_segmented_dump; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1360 void set_segmented_dump() { _is_segmented_dump = true; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1361 jlong dump_start() const { return _dump_start; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1362 void set_dump_start(jlong pos);
a61af66fc99e Initial load
duke
parents:
diff changeset
1363
a61af66fc99e Initial load
duke
parents:
diff changeset
1364 bool skip_operation() const;
a61af66fc99e Initial load
duke
parents:
diff changeset
1365
a61af66fc99e Initial load
duke
parents:
diff changeset
1366 // writes a HPROF_LOAD_CLASS record
a61af66fc99e Initial load
duke
parents:
diff changeset
1367 static void do_load_class(klassOop k);
a61af66fc99e Initial load
duke
parents:
diff changeset
1368
a61af66fc99e Initial load
duke
parents:
diff changeset
1369 // writes a HPROF_GC_CLASS_DUMP record for the given class
a61af66fc99e Initial load
duke
parents:
diff changeset
1370 // (and each array class too)
a61af66fc99e Initial load
duke
parents:
diff changeset
1371 static void do_class_dump(klassOop k);
a61af66fc99e Initial load
duke
parents:
diff changeset
1372
a61af66fc99e Initial load
duke
parents:
diff changeset
1373 // writes a HPROF_GC_CLASS_DUMP records for a given basic type
a61af66fc99e Initial load
duke
parents:
diff changeset
1374 // array (and each multi-dimensional array too)
a61af66fc99e Initial load
duke
parents:
diff changeset
1375 static void do_basic_type_array_class_dump(klassOop k);
a61af66fc99e Initial load
duke
parents:
diff changeset
1376
a61af66fc99e Initial load
duke
parents:
diff changeset
1377 // HPROF_GC_ROOT_THREAD_OBJ records
396
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1378 int do_thread(JavaThread* thread, u4 thread_serial_num);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1379 void do_threads();
a61af66fc99e Initial load
duke
parents:
diff changeset
1380
396
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1381 void add_class_serial_number(Klass* k, int serial_num) {
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1382 _klass_map->at_put_grow(serial_num, k);
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1383 }
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1384
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1385 // HPROF_TRACE and HPROF_FRAME records
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1386 void dump_stack_traces();
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1387
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1388 // writes a HPROF_HEAP_DUMP or HPROF_HEAP_DUMP_SEGMENT record
a61af66fc99e Initial load
duke
parents:
diff changeset
1389 void write_dump_header();
a61af66fc99e Initial load
duke
parents:
diff changeset
1390
a61af66fc99e Initial load
duke
parents:
diff changeset
1391 // fixes up the length of the current dump record
a61af66fc99e Initial load
duke
parents:
diff changeset
1392 void write_current_dump_record_length();
a61af66fc99e Initial load
duke
parents:
diff changeset
1393
a61af66fc99e Initial load
duke
parents:
diff changeset
1394 // fixes up the current dump record )and writes HPROF_HEAP_DUMP_END
a61af66fc99e Initial load
duke
parents:
diff changeset
1395 // record in the case of a segmented heap dump)
a61af66fc99e Initial load
duke
parents:
diff changeset
1396 void end_of_dump();
a61af66fc99e Initial load
duke
parents:
diff changeset
1397
a61af66fc99e Initial load
duke
parents:
diff changeset
1398 public:
1775
30f67acf635d 6765718: Indicate which thread throwing OOME when generating the heap dump at OOME
thurka
parents: 1552
diff changeset
1399 VM_HeapDumper(DumpWriter* writer, bool gc_before_heap_dump, bool oome) :
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1400 VM_GC_Operation(0 /* total collections, dummy, ignored */,
2225
c798c277ddd1 7015169: GC Cause not always set
brutisso
parents: 2177
diff changeset
1401 GCCause::_heap_dump /* GC Cause */,
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1402 0 /* total full collections, dummy, ignored */,
a61af66fc99e Initial load
duke
parents:
diff changeset
1403 gc_before_heap_dump) {
615
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1404 _local_writer = writer;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1405 _gc_before_heap_dump = gc_before_heap_dump;
a61af66fc99e Initial load
duke
parents:
diff changeset
1406 _is_segmented_dump = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1407 _dump_start = (jlong)-1;
396
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1408 _klass_map = new (ResourceObj::C_HEAP) GrowableArray<Klass*>(INITIAL_CLASS_COUNT, true);
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1409 _stack_traces = NULL;
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1410 _num_threads = 0;
1775
30f67acf635d 6765718: Indicate which thread throwing OOME when generating the heap dump at OOME
thurka
parents: 1552
diff changeset
1411 if (oome) {
30f67acf635d 6765718: Indicate which thread throwing OOME when generating the heap dump at OOME
thurka
parents: 1552
diff changeset
1412 assert(!Thread::current()->is_VM_thread(), "Dump from OutOfMemoryError cannot be called by the VMThread");
30f67acf635d 6765718: Indicate which thread throwing OOME when generating the heap dump at OOME
thurka
parents: 1552
diff changeset
1413 // get OutOfMemoryError zero-parameter constructor
30f67acf635d 6765718: Indicate which thread throwing OOME when generating the heap dump at OOME
thurka
parents: 1552
diff changeset
1414 instanceKlass* oome_ik = instanceKlass::cast(SystemDictionary::OutOfMemoryError_klass());
30f67acf635d 6765718: Indicate which thread throwing OOME when generating the heap dump at OOME
thurka
parents: 1552
diff changeset
1415 _oome_constructor = oome_ik->find_method(vmSymbols::object_initializer_name(),
30f67acf635d 6765718: Indicate which thread throwing OOME when generating the heap dump at OOME
thurka
parents: 1552
diff changeset
1416 vmSymbols::void_method_signature());
30f67acf635d 6765718: Indicate which thread throwing OOME when generating the heap dump at OOME
thurka
parents: 1552
diff changeset
1417 // get thread throwing OOME when generating the heap dump at OOME
30f67acf635d 6765718: Indicate which thread throwing OOME when generating the heap dump at OOME
thurka
parents: 1552
diff changeset
1418 _oome_thread = JavaThread::current();
30f67acf635d 6765718: Indicate which thread throwing OOME when generating the heap dump at OOME
thurka
parents: 1552
diff changeset
1419 } else {
30f67acf635d 6765718: Indicate which thread throwing OOME when generating the heap dump at OOME
thurka
parents: 1552
diff changeset
1420 _oome_thread = NULL;
30f67acf635d 6765718: Indicate which thread throwing OOME when generating the heap dump at OOME
thurka
parents: 1552
diff changeset
1421 _oome_constructor = NULL;
30f67acf635d 6765718: Indicate which thread throwing OOME when generating the heap dump at OOME
thurka
parents: 1552
diff changeset
1422 }
396
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1423 }
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1424 ~VM_HeapDumper() {
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1425 if (_stack_traces != NULL) {
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1426 for (int i=0; i < _num_threads; i++) {
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1427 delete _stack_traces[i];
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1428 }
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1429 FREE_C_HEAP_ARRAY(ThreadStackTrace*, _stack_traces);
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1430 }
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1431 delete _klass_map;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1432 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1433
a61af66fc99e Initial load
duke
parents:
diff changeset
1434 VMOp_Type type() const { return VMOp_HeapDumper; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1435 // used to mark sub-record boundary
a61af66fc99e Initial load
duke
parents:
diff changeset
1436 void check_segment_length();
a61af66fc99e Initial load
duke
parents:
diff changeset
1437 void doit();
a61af66fc99e Initial load
duke
parents:
diff changeset
1438 };
a61af66fc99e Initial load
duke
parents:
diff changeset
1439
615
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1440 VM_HeapDumper* VM_HeapDumper::_global_dumper = NULL;
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1441 DumpWriter* VM_HeapDumper::_global_writer = NULL;
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1442
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1443 bool VM_HeapDumper::skip_operation() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
1444 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1445 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1446
a61af66fc99e Initial load
duke
parents:
diff changeset
1447 // sets the dump starting position
a61af66fc99e Initial load
duke
parents:
diff changeset
1448 void VM_HeapDumper::set_dump_start(jlong pos) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1449 _dump_start = pos;
a61af66fc99e Initial load
duke
parents:
diff changeset
1450 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1451
a61af66fc99e Initial load
duke
parents:
diff changeset
1452 // writes a HPROF_HEAP_DUMP or HPROF_HEAP_DUMP_SEGMENT record
a61af66fc99e Initial load
duke
parents:
diff changeset
1453 void VM_HeapDumper::write_dump_header() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1454 if (writer()->is_open()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1455 if (is_segmented_dump()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1456 writer()->write_u1(HPROF_HEAP_DUMP_SEGMENT);
a61af66fc99e Initial load
duke
parents:
diff changeset
1457 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1458 writer()->write_u1(HPROF_HEAP_DUMP);
a61af66fc99e Initial load
duke
parents:
diff changeset
1459 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1460 writer()->write_u4(0); // current ticks
a61af66fc99e Initial load
duke
parents:
diff changeset
1461
a61af66fc99e Initial load
duke
parents:
diff changeset
1462 // record the starting position for the dump (its length will be fixed up later)
a61af66fc99e Initial load
duke
parents:
diff changeset
1463 set_dump_start(writer()->current_offset());
a61af66fc99e Initial load
duke
parents:
diff changeset
1464 writer()->write_u4(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1465 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1466 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1467
a61af66fc99e Initial load
duke
parents:
diff changeset
1468 // fixes up the length of the current dump record
a61af66fc99e Initial load
duke
parents:
diff changeset
1469 void VM_HeapDumper::write_current_dump_record_length() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1470 if (writer()->is_open()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1471 assert(dump_start() >= 0, "no dump start recorded");
a61af66fc99e Initial load
duke
parents:
diff changeset
1472
a61af66fc99e Initial load
duke
parents:
diff changeset
1473 // calculate the size of the dump record
a61af66fc99e Initial load
duke
parents:
diff changeset
1474 jlong dump_end = writer()->current_offset();
a61af66fc99e Initial load
duke
parents:
diff changeset
1475 jlong dump_len = (dump_end - dump_start() - 4);
a61af66fc99e Initial load
duke
parents:
diff changeset
1476
a61af66fc99e Initial load
duke
parents:
diff changeset
1477 // record length must fit in a u4
a61af66fc99e Initial load
duke
parents:
diff changeset
1478 if (dump_len > (jlong)(4L*(jlong)G)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1479 warning("record is too large");
a61af66fc99e Initial load
duke
parents:
diff changeset
1480 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1481
a61af66fc99e Initial load
duke
parents:
diff changeset
1482 // seek to the dump start and fix-up the length
a61af66fc99e Initial load
duke
parents:
diff changeset
1483 writer()->seek_to_offset(dump_start());
a61af66fc99e Initial load
duke
parents:
diff changeset
1484 writer()->write_u4((u4)dump_len);
a61af66fc99e Initial load
duke
parents:
diff changeset
1485
a61af66fc99e Initial load
duke
parents:
diff changeset
1486 // adjust the total size written to keep the bytes written correct.
a61af66fc99e Initial load
duke
parents:
diff changeset
1487 writer()->adjust_bytes_written(-((long) sizeof(u4)));
a61af66fc99e Initial load
duke
parents:
diff changeset
1488
a61af66fc99e Initial load
duke
parents:
diff changeset
1489 // seek to dump end so we can continue
a61af66fc99e Initial load
duke
parents:
diff changeset
1490 writer()->seek_to_offset(dump_end);
a61af66fc99e Initial load
duke
parents:
diff changeset
1491
a61af66fc99e Initial load
duke
parents:
diff changeset
1492 // no current dump record
a61af66fc99e Initial load
duke
parents:
diff changeset
1493 set_dump_start((jlong)-1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1494 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1495 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1496
a61af66fc99e Initial load
duke
parents:
diff changeset
1497 // used on a sub-record boundary to check if we need to start a
a61af66fc99e Initial load
duke
parents:
diff changeset
1498 // new segment.
a61af66fc99e Initial load
duke
parents:
diff changeset
1499 void VM_HeapDumper::check_segment_length() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1500 if (writer()->is_open()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1501 if (is_segmented_dump()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1502 // don't use current_offset that would be too expensive on a per record basis
a61af66fc99e Initial load
duke
parents:
diff changeset
1503 jlong dump_end = writer()->bytes_written() + writer()->bytes_unwritten();
a61af66fc99e Initial load
duke
parents:
diff changeset
1504 assert(dump_end == writer()->current_offset(), "checking");
a61af66fc99e Initial load
duke
parents:
diff changeset
1505 jlong dump_len = (dump_end - dump_start() - 4);
a61af66fc99e Initial load
duke
parents:
diff changeset
1506 assert(dump_len >= 0 && dump_len <= max_juint, "bad dump length");
a61af66fc99e Initial load
duke
parents:
diff changeset
1507
a61af66fc99e Initial load
duke
parents:
diff changeset
1508 if (dump_len > (jlong)HeapDumpSegmentSize) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1509 write_current_dump_record_length();
a61af66fc99e Initial load
duke
parents:
diff changeset
1510 write_dump_header();
a61af66fc99e Initial load
duke
parents:
diff changeset
1511 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1512 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1513 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1514 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1515
a61af66fc99e Initial load
duke
parents:
diff changeset
1516 // fixes up the current dump record )and writes HPROF_HEAP_DUMP_END
a61af66fc99e Initial load
duke
parents:
diff changeset
1517 // record in the case of a segmented heap dump)
a61af66fc99e Initial load
duke
parents:
diff changeset
1518 void VM_HeapDumper::end_of_dump() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1519 if (writer()->is_open()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1520 write_current_dump_record_length();
a61af66fc99e Initial load
duke
parents:
diff changeset
1521
a61af66fc99e Initial load
duke
parents:
diff changeset
1522 // for segmented dump we write the end record
a61af66fc99e Initial load
duke
parents:
diff changeset
1523 if (is_segmented_dump()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1524 writer()->write_u1(HPROF_HEAP_DUMP_END);
a61af66fc99e Initial load
duke
parents:
diff changeset
1525 writer()->write_u4(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1526 writer()->write_u4(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1527 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1528 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1529 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1530
a61af66fc99e Initial load
duke
parents:
diff changeset
1531 // marks sub-record boundary
a61af66fc99e Initial load
duke
parents:
diff changeset
1532 void HeapObjectDumper::mark_end_of_record() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1533 dumper()->check_segment_length();
a61af66fc99e Initial load
duke
parents:
diff changeset
1534 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1535
a61af66fc99e Initial load
duke
parents:
diff changeset
1536 // writes a HPROF_LOAD_CLASS record for the class (and each of its
a61af66fc99e Initial load
duke
parents:
diff changeset
1537 // array classes)
a61af66fc99e Initial load
duke
parents:
diff changeset
1538 void VM_HeapDumper::do_load_class(klassOop k) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1539 static u4 class_serial_num = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
1540
a61af66fc99e Initial load
duke
parents:
diff changeset
1541 // len of HPROF_LOAD_CLASS record
a61af66fc99e Initial load
duke
parents:
diff changeset
1542 u4 remaining = 2*oopSize + 2*sizeof(u4);
a61af66fc99e Initial load
duke
parents:
diff changeset
1543
a61af66fc99e Initial load
duke
parents:
diff changeset
1544 // write a HPROF_LOAD_CLASS for the class and each array class
a61af66fc99e Initial load
duke
parents:
diff changeset
1545 do {
615
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1546 DumperSupport::write_header(writer(), HPROF_LOAD_CLASS, remaining);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1547
a61af66fc99e Initial load
duke
parents:
diff changeset
1548 // class serial number is just a number
615
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1549 writer()->write_u4(++class_serial_num);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1550
a61af66fc99e Initial load
duke
parents:
diff changeset
1551 // class ID
a61af66fc99e Initial load
duke
parents:
diff changeset
1552 Klass* klass = Klass::cast(k);
615
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1553 writer()->write_classID(klass);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1554
396
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1555 // add the klassOop and class serial number pair
615
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1556 dumper()->add_class_serial_number(klass, class_serial_num);
396
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1557
615
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1558 writer()->write_u4(STACK_TRACE_ID);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1559
a61af66fc99e Initial load
duke
parents:
diff changeset
1560 // class name ID
2177
3582bf76420e 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 2143
diff changeset
1561 Symbol* name = klass->name();
3582bf76420e 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 2143
diff changeset
1562 writer()->write_symbolID(name);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1563
a61af66fc99e Initial load
duke
parents:
diff changeset
1564 // write a LOAD_CLASS record for the array type (if it exists)
a61af66fc99e Initial load
duke
parents:
diff changeset
1565 k = klass->array_klass_or_null();
a61af66fc99e Initial load
duke
parents:
diff changeset
1566 } while (k != NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
1567 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1568
a61af66fc99e Initial load
duke
parents:
diff changeset
1569 // writes a HPROF_GC_CLASS_DUMP record for the given class
a61af66fc99e Initial load
duke
parents:
diff changeset
1570 void VM_HeapDumper::do_class_dump(klassOop k) {
615
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1571 DumperSupport::dump_class_and_array_classes(writer(), k);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1572 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1573
a61af66fc99e Initial load
duke
parents:
diff changeset
1574 // writes a HPROF_GC_CLASS_DUMP records for a given basic type
a61af66fc99e Initial load
duke
parents:
diff changeset
1575 // array (and each multi-dimensional array too)
a61af66fc99e Initial load
duke
parents:
diff changeset
1576 void VM_HeapDumper::do_basic_type_array_class_dump(klassOop k) {
615
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1577 DumperSupport::dump_basic_type_array_class(writer(), k);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1578 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1579
a61af66fc99e Initial load
duke
parents:
diff changeset
1580 // Walk the stack of the given thread.
a61af66fc99e Initial load
duke
parents:
diff changeset
1581 // Dumps a HPROF_GC_ROOT_JAVA_FRAME record for each local
a61af66fc99e Initial load
duke
parents:
diff changeset
1582 // Dumps a HPROF_GC_ROOT_JNI_LOCAL record for each JNI local
396
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1583 //
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1584 // It returns the number of Java frames in this thread stack
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1585 int VM_HeapDumper::do_thread(JavaThread* java_thread, u4 thread_serial_num) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1586 JNILocalsDumper blk(writer(), thread_serial_num);
a61af66fc99e Initial load
duke
parents:
diff changeset
1587
a61af66fc99e Initial load
duke
parents:
diff changeset
1588 oop threadObj = java_thread->threadObj();
a61af66fc99e Initial load
duke
parents:
diff changeset
1589 assert(threadObj != NULL, "sanity check");
a61af66fc99e Initial load
duke
parents:
diff changeset
1590
396
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1591 int stack_depth = 0;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1592 if (java_thread->has_last_Java_frame()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1593
a61af66fc99e Initial load
duke
parents:
diff changeset
1594 // vframes are resource allocated
a61af66fc99e Initial load
duke
parents:
diff changeset
1595 Thread* current_thread = Thread::current();
a61af66fc99e Initial load
duke
parents:
diff changeset
1596 ResourceMark rm(current_thread);
a61af66fc99e Initial load
duke
parents:
diff changeset
1597 HandleMark hm(current_thread);
a61af66fc99e Initial load
duke
parents:
diff changeset
1598
a61af66fc99e Initial load
duke
parents:
diff changeset
1599 RegisterMap reg_map(java_thread);
a61af66fc99e Initial load
duke
parents:
diff changeset
1600 frame f = java_thread->last_frame();
a61af66fc99e Initial load
duke
parents:
diff changeset
1601 vframe* vf = vframe::new_vframe(&f, &reg_map, java_thread);
396
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1602 frame* last_entry_frame = NULL;
1775
30f67acf635d 6765718: Indicate which thread throwing OOME when generating the heap dump at OOME
thurka
parents: 1552
diff changeset
1603 int extra_frames = 0;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1604
1775
30f67acf635d 6765718: Indicate which thread throwing OOME when generating the heap dump at OOME
thurka
parents: 1552
diff changeset
1605 if (java_thread == _oome_thread && _oome_constructor != NULL) {
30f67acf635d 6765718: Indicate which thread throwing OOME when generating the heap dump at OOME
thurka
parents: 1552
diff changeset
1606 extra_frames++;
30f67acf635d 6765718: Indicate which thread throwing OOME when generating the heap dump at OOME
thurka
parents: 1552
diff changeset
1607 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1608 while (vf != NULL) {
396
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1609 blk.set_frame_number(stack_depth);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1610 if (vf->is_java_frame()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1611
a61af66fc99e Initial load
duke
parents:
diff changeset
1612 // java frame (interpreted, compiled, ...)
a61af66fc99e Initial load
duke
parents:
diff changeset
1613 javaVFrame *jvf = javaVFrame::cast(vf);
a61af66fc99e Initial load
duke
parents:
diff changeset
1614 if (!(jvf->method()->is_native())) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1615 StackValueCollection* locals = jvf->locals();
a61af66fc99e Initial load
duke
parents:
diff changeset
1616 for (int slot=0; slot<locals->size(); slot++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1617 if (locals->at(slot)->type() == T_OBJECT) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1618 oop o = locals->obj_at(slot)();
a61af66fc99e Initial load
duke
parents:
diff changeset
1619
a61af66fc99e Initial load
duke
parents:
diff changeset
1620 if (o != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1621 writer()->write_u1(HPROF_GC_ROOT_JAVA_FRAME);
a61af66fc99e Initial load
duke
parents:
diff changeset
1622 writer()->write_objectID(o);
a61af66fc99e Initial load
duke
parents:
diff changeset
1623 writer()->write_u4(thread_serial_num);
1775
30f67acf635d 6765718: Indicate which thread throwing OOME when generating the heap dump at OOME
thurka
parents: 1552
diff changeset
1624 writer()->write_u4((u4) (stack_depth + extra_frames));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1625 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1626 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1627 }
396
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1628 } else {
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1629 // native frame
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1630 if (stack_depth == 0) {
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1631 // JNI locals for the top frame.
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1632 java_thread->active_handles()->oops_do(&blk);
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1633 } else {
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1634 if (last_entry_frame != NULL) {
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1635 // JNI locals for the entry frame
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1636 assert(last_entry_frame->is_entry_frame(), "checking");
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1637 last_entry_frame->entry_frame_call_wrapper()->handles()->oops_do(&blk);
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1638 }
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1639 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1640 }
396
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1641 // increment only for Java frames
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1642 stack_depth++;
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1643 last_entry_frame = NULL;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1644
396
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1645 } else {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1646 // externalVFrame - if it's an entry frame then report any JNI locals
396
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1647 // as roots when we find the corresponding native javaVFrame
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1648 frame* fr = vf->frame_pointer();
a61af66fc99e Initial load
duke
parents:
diff changeset
1649 assert(fr != NULL, "sanity check");
a61af66fc99e Initial load
duke
parents:
diff changeset
1650 if (fr->is_entry_frame()) {
396
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1651 last_entry_frame = fr;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1652 }
3363
167b70ff3abc 6939861: JVM should handle more conversion operations
never
parents: 2377
diff changeset
1653 if (fr->is_ricochet_frame()) {
167b70ff3abc 6939861: JVM should handle more conversion operations
never
parents: 2377
diff changeset
1654 fr->oops_ricochet_do(&blk, vf->register_map());
167b70ff3abc 6939861: JVM should handle more conversion operations
never
parents: 2377
diff changeset
1655 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1656 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1657 vf = vf->sender();
a61af66fc99e Initial load
duke
parents:
diff changeset
1658 }
396
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1659 } else {
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1660 // no last java frame but there may be JNI locals
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1661 java_thread->active_handles()->oops_do(&blk);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1662 }
396
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1663 return stack_depth;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1664 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1665
a61af66fc99e Initial load
duke
parents:
diff changeset
1666
a61af66fc99e Initial load
duke
parents:
diff changeset
1667 // write a HPROF_GC_ROOT_THREAD_OBJ record for each java thread. Then walk
a61af66fc99e Initial load
duke
parents:
diff changeset
1668 // the stack so that locals and JNI locals are dumped.
a61af66fc99e Initial load
duke
parents:
diff changeset
1669 void VM_HeapDumper::do_threads() {
396
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1670 for (int i=0; i < _num_threads; i++) {
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1671 JavaThread* thread = _stack_traces[i]->thread();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1672 oop threadObj = thread->threadObj();
396
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1673 u4 thread_serial_num = i+1;
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1674 u4 stack_serial_num = thread_serial_num + STACK_TRACE_ID;
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1675 writer()->write_u1(HPROF_GC_ROOT_THREAD_OBJ);
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1676 writer()->write_objectID(threadObj);
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1677 writer()->write_u4(thread_serial_num); // thread number
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1678 writer()->write_u4(stack_serial_num); // stack trace serial number
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1679 int num_frames = do_thread(thread, thread_serial_num);
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1680 assert(num_frames == _stack_traces[i]->get_stack_depth(),
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1681 "total number of Java frames not matched");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1682 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1683 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1684
a61af66fc99e Initial load
duke
parents:
diff changeset
1685
a61af66fc99e Initial load
duke
parents:
diff changeset
1686 // The VM operation that dumps the heap. The dump consists of the following
a61af66fc99e Initial load
duke
parents:
diff changeset
1687 // records:
a61af66fc99e Initial load
duke
parents:
diff changeset
1688 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1689 // HPROF_HEADER
a61af66fc99e Initial load
duke
parents:
diff changeset
1690 // [HPROF_UTF8]*
a61af66fc99e Initial load
duke
parents:
diff changeset
1691 // [HPROF_LOAD_CLASS]*
396
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1692 // [[HPROF_FRAME]*|HPROF_TRACE]*
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1693 // [HPROF_GC_CLASS_DUMP]*
a61af66fc99e Initial load
duke
parents:
diff changeset
1694 // HPROF_HEAP_DUMP
a61af66fc99e Initial load
duke
parents:
diff changeset
1695 //
396
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1696 // The HPROF_TRACE records represent the stack traces where the heap dump
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1697 // is generated and a "dummy trace" record which does not include
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1698 // any frames. The dummy trace record is used to be referenced as the
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1699 // unknown object alloc site.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1700 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1701 // The HPROF_HEAP_DUMP record has a length following by sub-records. To allow
a61af66fc99e Initial load
duke
parents:
diff changeset
1702 // the heap dump be generated in a single pass we remember the position of
a61af66fc99e Initial load
duke
parents:
diff changeset
1703 // the dump length and fix it up after all sub-records have been written.
a61af66fc99e Initial load
duke
parents:
diff changeset
1704 // To generate the sub-records we iterate over the heap, writing
a61af66fc99e Initial load
duke
parents:
diff changeset
1705 // HPROF_GC_INSTANCE_DUMP, HPROF_GC_OBJ_ARRAY_DUMP, and HPROF_GC_PRIM_ARRAY_DUMP
a61af66fc99e Initial load
duke
parents:
diff changeset
1706 // records as we go. Once that is done we write records for some of the GC
a61af66fc99e Initial load
duke
parents:
diff changeset
1707 // roots.
a61af66fc99e Initial load
duke
parents:
diff changeset
1708
a61af66fc99e Initial load
duke
parents:
diff changeset
1709 void VM_HeapDumper::doit() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1710
a61af66fc99e Initial load
duke
parents:
diff changeset
1711 HandleMark hm;
a61af66fc99e Initial load
duke
parents:
diff changeset
1712 CollectedHeap* ch = Universe::heap();
4076
2ceafe3ceb65 7110428: Crash during HeapDump operation
poonam
parents: 3363
diff changeset
1713
2ceafe3ceb65 7110428: Crash during HeapDump operation
poonam
parents: 3363
diff changeset
1714 ch->ensure_parsability(false); // must happen, even if collection does
2ceafe3ceb65 7110428: Crash during HeapDump operation
poonam
parents: 3363
diff changeset
1715 // not happen (e.g. due to GC_locker)
2ceafe3ceb65 7110428: Crash during HeapDump operation
poonam
parents: 3363
diff changeset
1716
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1717 if (_gc_before_heap_dump) {
4076
2ceafe3ceb65 7110428: Crash during HeapDump operation
poonam
parents: 3363
diff changeset
1718 if (GC_locker::is_active()) {
2ceafe3ceb65 7110428: Crash during HeapDump operation
poonam
parents: 3363
diff changeset
1719 warning("GC locker is held; pre-heapdump GC was skipped");
2ceafe3ceb65 7110428: Crash during HeapDump operation
poonam
parents: 3363
diff changeset
1720 } else {
2ceafe3ceb65 7110428: Crash during HeapDump operation
poonam
parents: 3363
diff changeset
1721 ch->collect_as_vm_thread(GCCause::_heap_dump);
2ceafe3ceb65 7110428: Crash during HeapDump operation
poonam
parents: 3363
diff changeset
1722 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1723 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1724
615
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1725 // At this point we should be the only dumper active, so
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1726 // the following should be safe.
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1727 set_global_dumper();
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1728 set_global_writer();
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1729
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1730 // Write the file header - use 1.0.2 for large heaps, otherwise 1.0.1
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
1731 size_t used = ch->used();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1732 const char* header;
a61af66fc99e Initial load
duke
parents:
diff changeset
1733 if (used > (size_t)SegmentedHeapDumpThreshold) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1734 set_segmented_dump();
a61af66fc99e Initial load
duke
parents:
diff changeset
1735 header = "JAVA PROFILE 1.0.2";
a61af66fc99e Initial load
duke
parents:
diff changeset
1736 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1737 header = "JAVA PROFILE 1.0.1";
a61af66fc99e Initial load
duke
parents:
diff changeset
1738 }
615
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1739
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1740 // header is few bytes long - no chance to overflow int
a61af66fc99e Initial load
duke
parents:
diff changeset
1741 writer()->write_raw((void*)header, (int)strlen(header));
a61af66fc99e Initial load
duke
parents:
diff changeset
1742 writer()->write_u1(0); // terminator
a61af66fc99e Initial load
duke
parents:
diff changeset
1743 writer()->write_u4(oopSize);
a61af66fc99e Initial load
duke
parents:
diff changeset
1744 writer()->write_u8(os::javaTimeMillis());
a61af66fc99e Initial load
duke
parents:
diff changeset
1745
a61af66fc99e Initial load
duke
parents:
diff changeset
1746 // HPROF_UTF8 records
a61af66fc99e Initial load
duke
parents:
diff changeset
1747 SymbolTableDumper sym_dumper(writer());
2177
3582bf76420e 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 2143
diff changeset
1748 SymbolTable::symbols_do(&sym_dumper);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1749
a61af66fc99e Initial load
duke
parents:
diff changeset
1750 // write HPROF_LOAD_CLASS records
a61af66fc99e Initial load
duke
parents:
diff changeset
1751 SystemDictionary::classes_do(&do_load_class);
a61af66fc99e Initial load
duke
parents:
diff changeset
1752 Universe::basic_type_classes_do(&do_load_class);
a61af66fc99e Initial load
duke
parents:
diff changeset
1753
396
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1754 // write HPROF_FRAME and HPROF_TRACE records
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1755 // this must be called after _klass_map is built when iterating the classes above.
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1756 dump_stack_traces();
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1757
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1758 // write HPROF_HEAP_DUMP or HPROF_HEAP_DUMP_SEGMENT
a61af66fc99e Initial load
duke
parents:
diff changeset
1759 write_dump_header();
a61af66fc99e Initial load
duke
parents:
diff changeset
1760
a61af66fc99e Initial load
duke
parents:
diff changeset
1761 // Writes HPROF_GC_CLASS_DUMP records
a61af66fc99e Initial load
duke
parents:
diff changeset
1762 SystemDictionary::classes_do(&do_class_dump);
a61af66fc99e Initial load
duke
parents:
diff changeset
1763 Universe::basic_type_classes_do(&do_basic_type_array_class_dump);
a61af66fc99e Initial load
duke
parents:
diff changeset
1764 check_segment_length();
a61af66fc99e Initial load
duke
parents:
diff changeset
1765
a61af66fc99e Initial load
duke
parents:
diff changeset
1766 // writes HPROF_GC_INSTANCE_DUMP records.
a61af66fc99e Initial load
duke
parents:
diff changeset
1767 // After each sub-record is written check_segment_length will be invoked. When
a61af66fc99e Initial load
duke
parents:
diff changeset
1768 // generated a segmented heap dump this allows us to check if the current
a61af66fc99e Initial load
duke
parents:
diff changeset
1769 // segment exceeds a threshold and if so, then a new segment is started.
a61af66fc99e Initial load
duke
parents:
diff changeset
1770 // The HPROF_GC_CLASS_DUMP and HPROF_GC_INSTANCE_DUMP are the vast bulk
a61af66fc99e Initial load
duke
parents:
diff changeset
1771 // of the heap dump.
a61af66fc99e Initial load
duke
parents:
diff changeset
1772 HeapObjectDumper obj_dumper(this, writer());
517
e9be0e04635a 6689653: JMapPerm fails with UseConcMarkSweepIncGC and compressed oops off
jmasa
parents: 396
diff changeset
1773 Universe::heap()->safe_object_iterate(&obj_dumper);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1774
a61af66fc99e Initial load
duke
parents:
diff changeset
1775 // HPROF_GC_ROOT_THREAD_OBJ + frames + jni locals
a61af66fc99e Initial load
duke
parents:
diff changeset
1776 do_threads();
a61af66fc99e Initial load
duke
parents:
diff changeset
1777 check_segment_length();
a61af66fc99e Initial load
duke
parents:
diff changeset
1778
a61af66fc99e Initial load
duke
parents:
diff changeset
1779 // HPROF_GC_ROOT_MONITOR_USED
a61af66fc99e Initial load
duke
parents:
diff changeset
1780 MonitorUsedDumper mon_dumper(writer());
a61af66fc99e Initial load
duke
parents:
diff changeset
1781 ObjectSynchronizer::oops_do(&mon_dumper);
a61af66fc99e Initial load
duke
parents:
diff changeset
1782 check_segment_length();
a61af66fc99e Initial load
duke
parents:
diff changeset
1783
a61af66fc99e Initial load
duke
parents:
diff changeset
1784 // HPROF_GC_ROOT_JNI_GLOBAL
a61af66fc99e Initial load
duke
parents:
diff changeset
1785 JNIGlobalsDumper jni_dumper(writer());
a61af66fc99e Initial load
duke
parents:
diff changeset
1786 JNIHandles::oops_do(&jni_dumper);
a61af66fc99e Initial load
duke
parents:
diff changeset
1787 check_segment_length();
a61af66fc99e Initial load
duke
parents:
diff changeset
1788
a61af66fc99e Initial load
duke
parents:
diff changeset
1789 // HPROF_GC_ROOT_STICKY_CLASS
a61af66fc99e Initial load
duke
parents:
diff changeset
1790 StickyClassDumper class_dumper(writer());
a61af66fc99e Initial load
duke
parents:
diff changeset
1791 SystemDictionary::always_strong_oops_do(&class_dumper);
a61af66fc99e Initial load
duke
parents:
diff changeset
1792
a61af66fc99e Initial load
duke
parents:
diff changeset
1793 // fixes up the length of the dump record. In the case of a segmented
a61af66fc99e Initial load
duke
parents:
diff changeset
1794 // heap then the HPROF_HEAP_DUMP_END record is also written.
a61af66fc99e Initial load
duke
parents:
diff changeset
1795 end_of_dump();
615
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1796
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1797 // Now we clear the global variables, so that a future dumper might run.
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1798 clear_global_dumper();
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1799 clear_global_writer();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1800 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1801
396
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1802 void VM_HeapDumper::dump_stack_traces() {
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1803 // write a HPROF_TRACE record without any frames to be referenced as object alloc sites
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1804 DumperSupport::write_header(writer(), HPROF_TRACE, 3*sizeof(u4));
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1805 writer()->write_u4((u4) STACK_TRACE_ID);
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1806 writer()->write_u4(0); // thread number
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1807 writer()->write_u4(0); // frame count
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1808
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1809 _stack_traces = NEW_C_HEAP_ARRAY(ThreadStackTrace*, Threads::number_of_threads());
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1810 int frame_serial_num = 0;
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1811 for (JavaThread* thread = Threads::first(); thread != NULL ; thread = thread->next()) {
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1812 oop threadObj = thread->threadObj();
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1813 if (threadObj != NULL && !thread->is_exiting() && !thread->is_hidden_from_external_view()) {
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1814 // dump thread stack trace
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1815 ThreadStackTrace* stack_trace = new ThreadStackTrace(thread, false);
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1816 stack_trace->dump_stack_at_safepoint(-1);
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1817 _stack_traces[_num_threads++] = stack_trace;
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1818
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1819 // write HPROF_FRAME records for this thread's stack trace
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1820 int depth = stack_trace->get_stack_depth();
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1821 int thread_frame_start = frame_serial_num;
1775
30f67acf635d 6765718: Indicate which thread throwing OOME when generating the heap dump at OOME
thurka
parents: 1552
diff changeset
1822 int extra_frames = 0;
30f67acf635d 6765718: Indicate which thread throwing OOME when generating the heap dump at OOME
thurka
parents: 1552
diff changeset
1823 // write fake frame that makes it look like the thread, which caused OOME,
30f67acf635d 6765718: Indicate which thread throwing OOME when generating the heap dump at OOME
thurka
parents: 1552
diff changeset
1824 // is in the OutOfMemoryError zero-parameter constructor
30f67acf635d 6765718: Indicate which thread throwing OOME when generating the heap dump at OOME
thurka
parents: 1552
diff changeset
1825 if (thread == _oome_thread && _oome_constructor != NULL) {
30f67acf635d 6765718: Indicate which thread throwing OOME when generating the heap dump at OOME
thurka
parents: 1552
diff changeset
1826 int oome_serial_num = _klass_map->find(Klass::cast(_oome_constructor->method_holder()));
30f67acf635d 6765718: Indicate which thread throwing OOME when generating the heap dump at OOME
thurka
parents: 1552
diff changeset
1827 // the class serial number starts from 1
30f67acf635d 6765718: Indicate which thread throwing OOME when generating the heap dump at OOME
thurka
parents: 1552
diff changeset
1828 assert(oome_serial_num > 0, "OutOfMemoryError class not found");
30f67acf635d 6765718: Indicate which thread throwing OOME when generating the heap dump at OOME
thurka
parents: 1552
diff changeset
1829 DumperSupport::dump_stack_frame(writer(), ++frame_serial_num, oome_serial_num,
30f67acf635d 6765718: Indicate which thread throwing OOME when generating the heap dump at OOME
thurka
parents: 1552
diff changeset
1830 _oome_constructor, 0);
30f67acf635d 6765718: Indicate which thread throwing OOME when generating the heap dump at OOME
thurka
parents: 1552
diff changeset
1831 extra_frames++;
30f67acf635d 6765718: Indicate which thread throwing OOME when generating the heap dump at OOME
thurka
parents: 1552
diff changeset
1832 }
396
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1833 for (int j=0; j < depth; j++) {
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1834 StackFrameInfo* frame = stack_trace->stack_frame_at(j);
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1835 methodOop m = frame->method();
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1836 int class_serial_num = _klass_map->find(Klass::cast(m->method_holder()));
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1837 // the class serial number starts from 1
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1838 assert(class_serial_num > 0, "class not found");
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1839 DumperSupport::dump_stack_frame(writer(), ++frame_serial_num, class_serial_num, m, frame->bci());
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1840 }
1775
30f67acf635d 6765718: Indicate which thread throwing OOME when generating the heap dump at OOME
thurka
parents: 1552
diff changeset
1841 depth += extra_frames;
396
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1842
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1843 // write HPROF_TRACE record for one thread
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1844 DumperSupport::write_header(writer(), HPROF_TRACE, 3*sizeof(u4) + depth*oopSize);
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1845 int stack_serial_num = _num_threads + STACK_TRACE_ID;
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1846 writer()->write_u4(stack_serial_num); // stack trace serial number
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1847 writer()->write_u4((u4) _num_threads); // thread serial number
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1848 writer()->write_u4(depth); // frame count
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1849 for (int j=1; j <= depth; j++) {
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1850 writer()->write_id(thread_frame_start + j);
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1851 }
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1852 }
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1853 }
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1854 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1855
a61af66fc99e Initial load
duke
parents:
diff changeset
1856 // dump the heap to given path.
a61af66fc99e Initial load
duke
parents:
diff changeset
1857 int HeapDumper::dump(const char* path) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1858 assert(path != NULL && strlen(path) > 0, "path missing");
a61af66fc99e Initial load
duke
parents:
diff changeset
1859
a61af66fc99e Initial load
duke
parents:
diff changeset
1860 // print message in interactive case
a61af66fc99e Initial load
duke
parents:
diff changeset
1861 if (print_to_tty()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1862 tty->print_cr("Dumping heap to %s ...", path);
a61af66fc99e Initial load
duke
parents:
diff changeset
1863 timer()->start();
a61af66fc99e Initial load
duke
parents:
diff changeset
1864 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1865
a61af66fc99e Initial load
duke
parents:
diff changeset
1866 // create the dump writer. If the file can be opened then bail
a61af66fc99e Initial load
duke
parents:
diff changeset
1867 DumpWriter writer(path);
a61af66fc99e Initial load
duke
parents:
diff changeset
1868 if (!writer.is_open()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1869 set_error(writer.error());
a61af66fc99e Initial load
duke
parents:
diff changeset
1870 if (print_to_tty()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1871 tty->print_cr("Unable to create %s: %s", path,
a61af66fc99e Initial load
duke
parents:
diff changeset
1872 (error() != NULL) ? error() : "reason unknown");
a61af66fc99e Initial load
duke
parents:
diff changeset
1873 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1874 return -1;
a61af66fc99e Initial load
duke
parents:
diff changeset
1875 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1876
a61af66fc99e Initial load
duke
parents:
diff changeset
1877 // generate the dump
1775
30f67acf635d 6765718: Indicate which thread throwing OOME when generating the heap dump at OOME
thurka
parents: 1552
diff changeset
1878 VM_HeapDumper dumper(&writer, _gc_before_heap_dump, _oome);
615
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1879 if (Thread::current()->is_VM_thread()) {
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1880 assert(SafepointSynchronize::is_at_safepoint(), "Expected to be called at a safepoint");
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1881 dumper.doit();
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1882 } else {
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1883 VMThread::execute(&dumper);
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1884 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1885
a61af66fc99e Initial load
duke
parents:
diff changeset
1886 // close dump file and record any error that the writer may have encountered
a61af66fc99e Initial load
duke
parents:
diff changeset
1887 writer.close();
a61af66fc99e Initial load
duke
parents:
diff changeset
1888 set_error(writer.error());
a61af66fc99e Initial load
duke
parents:
diff changeset
1889
a61af66fc99e Initial load
duke
parents:
diff changeset
1890 // print message in interactive case
a61af66fc99e Initial load
duke
parents:
diff changeset
1891 if (print_to_tty()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1892 timer()->stop();
a61af66fc99e Initial load
duke
parents:
diff changeset
1893 if (error() == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1894 char msg[256];
a61af66fc99e Initial load
duke
parents:
diff changeset
1895 sprintf(msg, "Heap dump file created [%s bytes in %3.3f secs]",
a61af66fc99e Initial load
duke
parents:
diff changeset
1896 os::jlong_format_specifier(), timer()->seconds());
a61af66fc99e Initial load
duke
parents:
diff changeset
1897 tty->print_cr(msg, writer.bytes_written());
a61af66fc99e Initial load
duke
parents:
diff changeset
1898 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1899 tty->print_cr("Dump file is incomplete: %s", writer.error());
a61af66fc99e Initial load
duke
parents:
diff changeset
1900 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1901 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1902
a61af66fc99e Initial load
duke
parents:
diff changeset
1903 return (writer.error() == NULL) ? 0 : -1;
a61af66fc99e Initial load
duke
parents:
diff changeset
1904 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1905
a61af66fc99e Initial load
duke
parents:
diff changeset
1906 // stop timer (if still active), and free any error string we might be holding
a61af66fc99e Initial load
duke
parents:
diff changeset
1907 HeapDumper::~HeapDumper() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1908 if (timer()->is_active()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1909 timer()->stop();
a61af66fc99e Initial load
duke
parents:
diff changeset
1910 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1911 set_error(NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
1912 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1913
a61af66fc99e Initial load
duke
parents:
diff changeset
1914
a61af66fc99e Initial load
duke
parents:
diff changeset
1915 // returns the error string (resource allocated), or NULL
a61af66fc99e Initial load
duke
parents:
diff changeset
1916 char* HeapDumper::error_as_C_string() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
1917 if (error() != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1918 char* str = NEW_RESOURCE_ARRAY(char, strlen(error())+1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1919 strcpy(str, error());
a61af66fc99e Initial load
duke
parents:
diff changeset
1920 return str;
a61af66fc99e Initial load
duke
parents:
diff changeset
1921 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1922 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1923 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1924 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1925
a61af66fc99e Initial load
duke
parents:
diff changeset
1926 // set the error string
a61af66fc99e Initial load
duke
parents:
diff changeset
1927 void HeapDumper::set_error(char* error) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1928 if (_error != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1929 os::free(_error);
a61af66fc99e Initial load
duke
parents:
diff changeset
1930 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1931 if (error == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1932 _error = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1933 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1934 _error = os::strdup(error);
a61af66fc99e Initial load
duke
parents:
diff changeset
1935 assert(_error != NULL, "allocation failure");
a61af66fc99e Initial load
duke
parents:
diff changeset
1936 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1937 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1938
1775
30f67acf635d 6765718: Indicate which thread throwing OOME when generating the heap dump at OOME
thurka
parents: 1552
diff changeset
1939 // Called by out-of-memory error reporting by a single Java thread
30f67acf635d 6765718: Indicate which thread throwing OOME when generating the heap dump at OOME
thurka
parents: 1552
diff changeset
1940 // outside of a JVM safepoint
30f67acf635d 6765718: Indicate which thread throwing OOME when generating the heap dump at OOME
thurka
parents: 1552
diff changeset
1941 void HeapDumper::dump_heap_from_oome() {
30f67acf635d 6765718: Indicate which thread throwing OOME when generating the heap dump at OOME
thurka
parents: 1552
diff changeset
1942 HeapDumper::dump_heap(true);
30f67acf635d 6765718: Indicate which thread throwing OOME when generating the heap dump at OOME
thurka
parents: 1552
diff changeset
1943 }
30f67acf635d 6765718: Indicate which thread throwing OOME when generating the heap dump at OOME
thurka
parents: 1552
diff changeset
1944
615
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1945 // Called by error reporting by a single Java thread outside of a JVM safepoint,
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1946 // or by heap dumping by the VM thread during a (GC) safepoint. Thus, these various
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1947 // callers are strictly serialized and guaranteed not to interfere below. For more
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1948 // general use, however, this method will need modification to prevent
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1949 // inteference when updating the static variables base_path and dump_file_seq below.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1950 void HeapDumper::dump_heap() {
1775
30f67acf635d 6765718: Indicate which thread throwing OOME when generating the heap dump at OOME
thurka
parents: 1552
diff changeset
1951 HeapDumper::dump_heap(false);
30f67acf635d 6765718: Indicate which thread throwing OOME when generating the heap dump at OOME
thurka
parents: 1552
diff changeset
1952 }
30f67acf635d 6765718: Indicate which thread throwing OOME when generating the heap dump at OOME
thurka
parents: 1552
diff changeset
1953
30f67acf635d 6765718: Indicate which thread throwing OOME when generating the heap dump at OOME
thurka
parents: 1552
diff changeset
1954 void HeapDumper::dump_heap(bool oome) {
615
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1955 static char base_path[JVM_MAXPATHLEN] = {'\0'};
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1956 static uint dump_file_seq = 0;
2143
17c778814856 6811367: Fix code in HeapDumper::dump_heap() to avoid buffer overrun
coleenp
parents: 1972
diff changeset
1957 char* my_path;
17c778814856 6811367: Fix code in HeapDumper::dump_heap() to avoid buffer overrun
coleenp
parents: 1972
diff changeset
1958 const int max_digit_chars = 20;
17c778814856 6811367: Fix code in HeapDumper::dump_heap() to avoid buffer overrun
coleenp
parents: 1972
diff changeset
1959
17c778814856 6811367: Fix code in HeapDumper::dump_heap() to avoid buffer overrun
coleenp
parents: 1972
diff changeset
1960 const char* dump_file_name = "java_pid";
17c778814856 6811367: Fix code in HeapDumper::dump_heap() to avoid buffer overrun
coleenp
parents: 1972
diff changeset
1961 const char* dump_file_ext = ".hprof";
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1962
a61af66fc99e Initial load
duke
parents:
diff changeset
1963 // The dump file defaults to java_pid<pid>.hprof in the current working
a61af66fc99e Initial load
duke
parents:
diff changeset
1964 // directory. HeapDumpPath=<file> can be used to specify an alternative
a61af66fc99e Initial load
duke
parents:
diff changeset
1965 // dump file name or a directory where dump file is created.
615
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1966 if (dump_file_seq == 0) { // first time in, we initialize base_path
2143
17c778814856 6811367: Fix code in HeapDumper::dump_heap() to avoid buffer overrun
coleenp
parents: 1972
diff changeset
1967 // Calculate potentially longest base path and check if we have enough
17c778814856 6811367: Fix code in HeapDumper::dump_heap() to avoid buffer overrun
coleenp
parents: 1972
diff changeset
1968 // allocated statically.
17c778814856 6811367: Fix code in HeapDumper::dump_heap() to avoid buffer overrun
coleenp
parents: 1972
diff changeset
1969 const size_t total_length =
17c778814856 6811367: Fix code in HeapDumper::dump_heap() to avoid buffer overrun
coleenp
parents: 1972
diff changeset
1970 (HeapDumpPath == NULL ? 0 : strlen(HeapDumpPath)) +
17c778814856 6811367: Fix code in HeapDumper::dump_heap() to avoid buffer overrun
coleenp
parents: 1972
diff changeset
1971 strlen(os::file_separator()) + max_digit_chars +
17c778814856 6811367: Fix code in HeapDumper::dump_heap() to avoid buffer overrun
coleenp
parents: 1972
diff changeset
1972 strlen(dump_file_name) + strlen(dump_file_ext) + 1;
17c778814856 6811367: Fix code in HeapDumper::dump_heap() to avoid buffer overrun
coleenp
parents: 1972
diff changeset
1973 if (total_length > sizeof(base_path)) {
17c778814856 6811367: Fix code in HeapDumper::dump_heap() to avoid buffer overrun
coleenp
parents: 1972
diff changeset
1974 warning("Cannot create heap dump file. HeapDumpPath is too long.");
17c778814856 6811367: Fix code in HeapDumper::dump_heap() to avoid buffer overrun
coleenp
parents: 1972
diff changeset
1975 return;
17c778814856 6811367: Fix code in HeapDumper::dump_heap() to avoid buffer overrun
coleenp
parents: 1972
diff changeset
1976 }
17c778814856 6811367: Fix code in HeapDumper::dump_heap() to avoid buffer overrun
coleenp
parents: 1972
diff changeset
1977
615
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1978 bool use_default_filename = true;
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1979 if (HeapDumpPath == NULL || HeapDumpPath[0] == '\0') {
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1980 // HeapDumpPath=<file> not specified
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1981 } else {
2143
17c778814856 6811367: Fix code in HeapDumper::dump_heap() to avoid buffer overrun
coleenp
parents: 1972
diff changeset
1982 strncpy(base_path, HeapDumpPath, sizeof(base_path));
615
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1983 // check if the path is a directory (must exist)
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1984 DIR* dir = os::opendir(base_path);
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1985 if (dir == NULL) {
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1986 use_default_filename = false;
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1987 } else {
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1988 // HeapDumpPath specified a directory. We append a file separator
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1989 // (if needed).
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1990 os::closedir(dir);
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1991 size_t fs_len = strlen(os::file_separator());
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1992 if (strlen(base_path) >= fs_len) {
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1993 char* end = base_path;
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1994 end += (strlen(base_path) - fs_len);
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1995 if (strcmp(end, os::file_separator()) != 0) {
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1996 strcat(base_path, os::file_separator());
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1997 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1998 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1999 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2000 }
615
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
2001 // If HeapDumpPath wasn't a file name then we append the default name
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
2002 if (use_default_filename) {
2143
17c778814856 6811367: Fix code in HeapDumper::dump_heap() to avoid buffer overrun
coleenp
parents: 1972
diff changeset
2003 const size_t dlen = strlen(base_path); // if heap dump dir specified
17c778814856 6811367: Fix code in HeapDumper::dump_heap() to avoid buffer overrun
coleenp
parents: 1972
diff changeset
2004 jio_snprintf(&base_path[dlen], sizeof(base_path)-dlen, "%s%d%s",
17c778814856 6811367: Fix code in HeapDumper::dump_heap() to avoid buffer overrun
coleenp
parents: 1972
diff changeset
2005 dump_file_name, os::current_process_id(), dump_file_ext);
615
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
2006 }
2143
17c778814856 6811367: Fix code in HeapDumper::dump_heap() to avoid buffer overrun
coleenp
parents: 1972
diff changeset
2007 const size_t len = strlen(base_path) + 1;
17c778814856 6811367: Fix code in HeapDumper::dump_heap() to avoid buffer overrun
coleenp
parents: 1972
diff changeset
2008 my_path = (char*)os::malloc(len);
17c778814856 6811367: Fix code in HeapDumper::dump_heap() to avoid buffer overrun
coleenp
parents: 1972
diff changeset
2009 if (my_path == NULL) {
17c778814856 6811367: Fix code in HeapDumper::dump_heap() to avoid buffer overrun
coleenp
parents: 1972
diff changeset
2010 warning("Cannot create heap dump file. Out of system memory.");
17c778814856 6811367: Fix code in HeapDumper::dump_heap() to avoid buffer overrun
coleenp
parents: 1972
diff changeset
2011 return;
17c778814856 6811367: Fix code in HeapDumper::dump_heap() to avoid buffer overrun
coleenp
parents: 1972
diff changeset
2012 }
17c778814856 6811367: Fix code in HeapDumper::dump_heap() to avoid buffer overrun
coleenp
parents: 1972
diff changeset
2013 strncpy(my_path, base_path, len);
615
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
2014 } else {
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
2015 // Append a sequence number id for dumps following the first
2143
17c778814856 6811367: Fix code in HeapDumper::dump_heap() to avoid buffer overrun
coleenp
parents: 1972
diff changeset
2016 const size_t len = strlen(base_path) + max_digit_chars + 2; // for '.' and \0
17c778814856 6811367: Fix code in HeapDumper::dump_heap() to avoid buffer overrun
coleenp
parents: 1972
diff changeset
2017 my_path = (char*)os::malloc(len);
17c778814856 6811367: Fix code in HeapDumper::dump_heap() to avoid buffer overrun
coleenp
parents: 1972
diff changeset
2018 if (my_path == NULL) {
17c778814856 6811367: Fix code in HeapDumper::dump_heap() to avoid buffer overrun
coleenp
parents: 1972
diff changeset
2019 warning("Cannot create heap dump file. Out of system memory.");
17c778814856 6811367: Fix code in HeapDumper::dump_heap() to avoid buffer overrun
coleenp
parents: 1972
diff changeset
2020 return;
17c778814856 6811367: Fix code in HeapDumper::dump_heap() to avoid buffer overrun
coleenp
parents: 1972
diff changeset
2021 }
17c778814856 6811367: Fix code in HeapDumper::dump_heap() to avoid buffer overrun
coleenp
parents: 1972
diff changeset
2022 jio_snprintf(my_path, len, "%s.%d", base_path, dump_file_seq);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2023 }
615
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
2024 dump_file_seq++; // increment seq number for next time we dump
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2025
a61af66fc99e Initial load
duke
parents:
diff changeset
2026 HeapDumper dumper(false /* no GC before heap dump */,
1775
30f67acf635d 6765718: Indicate which thread throwing OOME when generating the heap dump at OOME
thurka
parents: 1552
diff changeset
2027 true /* send to tty */,
30f67acf635d 6765718: Indicate which thread throwing OOME when generating the heap dump at OOME
thurka
parents: 1552
diff changeset
2028 oome /* pass along out-of-memory-error flag */);
615
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
2029 dumper.dump(my_path);
2143
17c778814856 6811367: Fix code in HeapDumper::dump_heap() to avoid buffer overrun
coleenp
parents: 1972
diff changeset
2030 os::free(my_path);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2031 }