annotate src/share/vm/services/heapDumper.cpp @ 452:00b023ae2d78

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