annotate src/share/vm/services/heapDumper.cpp @ 1721:413ad0331a0c

6977924: Changes for 6975078 produce build error with certain gcc versions Summary: The changes introduced for 6975078 assign badHeapOopVal to the _allocation field in the ResourceObj class. In 32 bit linux builds with certain versions of gcc this assignment will be flagged as an error while compiling allocation.cpp. In 32 bit builds the constant value badHeapOopVal (which is cast to an intptr_t) is negative. The _allocation field is typed as an unsigned intptr_t and gcc catches this as an error. Reviewed-by: jcoomes, ysr, phh
author johnc
date Wed, 18 Aug 2010 10:59:06 -0700
parents c18cbe5936b8
children 30f67acf635d
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1 /*
1552
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1142
diff changeset
2 * Copyright (c) 2005, 2009, Oracle and/or its affiliates. All rights reserved.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
a61af66fc99e Initial load
duke
parents:
diff changeset
4 *
a61af66fc99e Initial load
duke
parents:
diff changeset
5 * This code is free software; you can redistribute it and/or modify it
a61af66fc99e Initial load
duke
parents:
diff changeset
6 * under the terms of the GNU General Public License version 2 only, as
a61af66fc99e Initial load
duke
parents:
diff changeset
7 * published by the Free Software Foundation.
a61af66fc99e Initial load
duke
parents:
diff changeset
8 *
a61af66fc99e Initial load
duke
parents:
diff changeset
9 * This code is distributed in the hope that it will be useful, but WITHOUT
a61af66fc99e Initial load
duke
parents:
diff changeset
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
a61af66fc99e Initial load
duke
parents:
diff changeset
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
a61af66fc99e Initial load
duke
parents:
diff changeset
12 * version 2 for more details (a copy is included in the LICENSE file that
a61af66fc99e Initial load
duke
parents:
diff changeset
13 * accompanied this code).
a61af66fc99e Initial load
duke
parents:
diff changeset
14 *
a61af66fc99e Initial load
duke
parents:
diff changeset
15 * You should have received a copy of the GNU General Public License version
a61af66fc99e Initial load
duke
parents:
diff changeset
16 * 2 along with this work; if not, write to the Free Software Foundation,
a61af66fc99e Initial load
duke
parents:
diff changeset
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
a61af66fc99e Initial load
duke
parents:
diff changeset
18 *
1552
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1142
diff changeset
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1142
diff changeset
20 * or visit www.oracle.com if you need additional information or have any
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1142
diff changeset
21 * questions.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
22 *
a61af66fc99e Initial load
duke
parents:
diff changeset
23 */
a61af66fc99e Initial load
duke
parents:
diff changeset
24
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 // Supports I/O operations on a dump file
a61af66fc99e Initial load
duke
parents:
diff changeset
351
a61af66fc99e Initial load
duke
parents:
diff changeset
352 class DumpWriter : public StackObj {
a61af66fc99e Initial load
duke
parents:
diff changeset
353 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
354 enum {
a61af66fc99e Initial load
duke
parents:
diff changeset
355 io_buffer_size = 8*M
a61af66fc99e Initial load
duke
parents:
diff changeset
356 };
a61af66fc99e Initial load
duke
parents:
diff changeset
357
a61af66fc99e Initial load
duke
parents:
diff changeset
358 int _fd; // file descriptor (-1 if dump file not open)
a61af66fc99e Initial load
duke
parents:
diff changeset
359 jlong _bytes_written; // number of byte written to dump file
a61af66fc99e Initial load
duke
parents:
diff changeset
360
a61af66fc99e Initial load
duke
parents:
diff changeset
361 char* _buffer; // internal buffer
a61af66fc99e Initial load
duke
parents:
diff changeset
362 int _size;
a61af66fc99e Initial load
duke
parents:
diff changeset
363 int _pos;
a61af66fc99e Initial load
duke
parents:
diff changeset
364
a61af66fc99e Initial load
duke
parents:
diff changeset
365 char* _error; // error message when I/O fails
a61af66fc99e Initial load
duke
parents:
diff changeset
366
a61af66fc99e Initial load
duke
parents:
diff changeset
367 void set_file_descriptor(int fd) { _fd = fd; }
a61af66fc99e Initial load
duke
parents:
diff changeset
368 int file_descriptor() const { return _fd; }
a61af66fc99e Initial load
duke
parents:
diff changeset
369
a61af66fc99e Initial load
duke
parents:
diff changeset
370 char* buffer() const { return _buffer; }
a61af66fc99e Initial load
duke
parents:
diff changeset
371 int buffer_size() const { return _size; }
a61af66fc99e Initial load
duke
parents:
diff changeset
372 int position() const { return _pos; }
a61af66fc99e Initial load
duke
parents:
diff changeset
373 void set_position(int pos) { _pos = pos; }
a61af66fc99e Initial load
duke
parents:
diff changeset
374
a61af66fc99e Initial load
duke
parents:
diff changeset
375 void set_error(const char* error) { _error = (char*)os::strdup(error); }
a61af66fc99e Initial load
duke
parents:
diff changeset
376
a61af66fc99e Initial load
duke
parents:
diff changeset
377 // all I/O go through this function
a61af66fc99e Initial load
duke
parents:
diff changeset
378 void write_internal(void* s, int len);
a61af66fc99e Initial load
duke
parents:
diff changeset
379
a61af66fc99e Initial load
duke
parents:
diff changeset
380 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
381 DumpWriter(const char* path);
a61af66fc99e Initial load
duke
parents:
diff changeset
382 ~DumpWriter();
a61af66fc99e Initial load
duke
parents:
diff changeset
383
a61af66fc99e Initial load
duke
parents:
diff changeset
384 void close();
a61af66fc99e Initial load
duke
parents:
diff changeset
385 bool is_open() const { return file_descriptor() >= 0; }
a61af66fc99e Initial load
duke
parents:
diff changeset
386 void flush();
a61af66fc99e Initial load
duke
parents:
diff changeset
387
a61af66fc99e Initial load
duke
parents:
diff changeset
388 // total number of bytes written to the disk
a61af66fc99e Initial load
duke
parents:
diff changeset
389 jlong bytes_written() const { return _bytes_written; }
a61af66fc99e Initial load
duke
parents:
diff changeset
390
a61af66fc99e Initial load
duke
parents:
diff changeset
391 // adjust the number of bytes written to disk (used to keep the count
a61af66fc99e Initial load
duke
parents:
diff changeset
392 // of the number of bytes written in case of rewrites)
a61af66fc99e Initial load
duke
parents:
diff changeset
393 void adjust_bytes_written(jlong n) { _bytes_written += n; }
a61af66fc99e Initial load
duke
parents:
diff changeset
394
a61af66fc99e Initial load
duke
parents:
diff changeset
395 // number of (buffered) bytes as yet unwritten to the dump file
a61af66fc99e Initial load
duke
parents:
diff changeset
396 jlong bytes_unwritten() const { return (jlong)position(); }
a61af66fc99e Initial load
duke
parents:
diff changeset
397
a61af66fc99e Initial load
duke
parents:
diff changeset
398 char* error() const { return _error; }
a61af66fc99e Initial load
duke
parents:
diff changeset
399
a61af66fc99e Initial load
duke
parents:
diff changeset
400 jlong current_offset();
a61af66fc99e Initial load
duke
parents:
diff changeset
401 void seek_to_offset(jlong pos);
a61af66fc99e Initial load
duke
parents:
diff changeset
402
a61af66fc99e Initial load
duke
parents:
diff changeset
403 // writer functions
a61af66fc99e Initial load
duke
parents:
diff changeset
404 void write_raw(void* s, int len);
a61af66fc99e Initial load
duke
parents:
diff changeset
405 void write_u1(u1 x) { write_raw((void*)&x, 1); }
a61af66fc99e Initial load
duke
parents:
diff changeset
406 void write_u2(u2 x);
a61af66fc99e Initial load
duke
parents:
diff changeset
407 void write_u4(u4 x);
a61af66fc99e Initial load
duke
parents:
diff changeset
408 void write_u8(u8 x);
a61af66fc99e Initial load
duke
parents:
diff changeset
409 void write_objectID(oop o);
a61af66fc99e Initial load
duke
parents:
diff changeset
410 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
411 void write_id(u4 x);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
412 };
a61af66fc99e Initial load
duke
parents:
diff changeset
413
a61af66fc99e Initial load
duke
parents:
diff changeset
414 DumpWriter::DumpWriter(const char* path) {
a61af66fc99e Initial load
duke
parents:
diff changeset
415 // try to allocate an I/O buffer of io_buffer_size. If there isn't
a61af66fc99e Initial load
duke
parents:
diff changeset
416 // sufficient memory then reduce size until we can allocate something.
a61af66fc99e Initial load
duke
parents:
diff changeset
417 _size = io_buffer_size;
a61af66fc99e Initial load
duke
parents:
diff changeset
418 do {
a61af66fc99e Initial load
duke
parents:
diff changeset
419 _buffer = (char*)os::malloc(_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
420 if (_buffer == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
421 _size = _size >> 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
422 }
a61af66fc99e Initial load
duke
parents:
diff changeset
423 } while (_buffer == NULL && _size > 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
424 assert((_size > 0 && _buffer != NULL) || (_size == 0 && _buffer == NULL), "sanity check");
a61af66fc99e Initial load
duke
parents:
diff changeset
425 _pos = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
426 _error = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
427 _bytes_written = 0L;
a61af66fc99e Initial load
duke
parents:
diff changeset
428 _fd = os::create_binary_file(path, false); // don't replace existing file
a61af66fc99e Initial load
duke
parents:
diff changeset
429
a61af66fc99e Initial load
duke
parents:
diff changeset
430 // if the open failed we record the error
a61af66fc99e Initial load
duke
parents:
diff changeset
431 if (_fd < 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
432 _error = (char*)os::strdup(strerror(errno));
a61af66fc99e Initial load
duke
parents:
diff changeset
433 }
a61af66fc99e Initial load
duke
parents:
diff changeset
434 }
a61af66fc99e Initial load
duke
parents:
diff changeset
435
a61af66fc99e Initial load
duke
parents:
diff changeset
436 DumpWriter::~DumpWriter() {
a61af66fc99e Initial load
duke
parents:
diff changeset
437 // flush and close dump file
a61af66fc99e Initial load
duke
parents:
diff changeset
438 if (file_descriptor() >= 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
439 close();
a61af66fc99e Initial load
duke
parents:
diff changeset
440 }
a61af66fc99e Initial load
duke
parents:
diff changeset
441 if (_buffer != NULL) os::free(_buffer);
a61af66fc99e Initial load
duke
parents:
diff changeset
442 if (_error != NULL) os::free(_error);
a61af66fc99e Initial load
duke
parents:
diff changeset
443 }
a61af66fc99e Initial load
duke
parents:
diff changeset
444
a61af66fc99e Initial load
duke
parents:
diff changeset
445 // closes dump file (if open)
a61af66fc99e Initial load
duke
parents:
diff changeset
446 void DumpWriter::close() {
a61af66fc99e Initial load
duke
parents:
diff changeset
447 // flush and close dump file
a61af66fc99e Initial load
duke
parents:
diff changeset
448 if (file_descriptor() >= 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
449 flush();
a61af66fc99e Initial load
duke
parents:
diff changeset
450 ::close(file_descriptor());
a61af66fc99e Initial load
duke
parents:
diff changeset
451 }
a61af66fc99e Initial load
duke
parents:
diff changeset
452 }
a61af66fc99e Initial load
duke
parents:
diff changeset
453
a61af66fc99e Initial load
duke
parents:
diff changeset
454 // write directly to the file
a61af66fc99e Initial load
duke
parents:
diff changeset
455 void DumpWriter::write_internal(void* s, int len) {
a61af66fc99e Initial load
duke
parents:
diff changeset
456 if (is_open()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
457 int n = ::write(file_descriptor(), s, len);
a61af66fc99e Initial load
duke
parents:
diff changeset
458 if (n > 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
459 _bytes_written += n;
a61af66fc99e Initial load
duke
parents:
diff changeset
460 }
a61af66fc99e Initial load
duke
parents:
diff changeset
461 if (n != len) {
a61af66fc99e Initial load
duke
parents:
diff changeset
462 if (n < 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
463 set_error(strerror(errno));
a61af66fc99e Initial load
duke
parents:
diff changeset
464 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
465 set_error("file size limit");
a61af66fc99e Initial load
duke
parents:
diff changeset
466 }
a61af66fc99e Initial load
duke
parents:
diff changeset
467 ::close(file_descriptor());
a61af66fc99e Initial load
duke
parents:
diff changeset
468 set_file_descriptor(-1);
a61af66fc99e Initial load
duke
parents:
diff changeset
469 }
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 // write raw bytes
a61af66fc99e Initial load
duke
parents:
diff changeset
474 void DumpWriter::write_raw(void* s, int len) {
a61af66fc99e Initial load
duke
parents:
diff changeset
475 if (is_open()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
476 // flush buffer to make toom
a61af66fc99e Initial load
duke
parents:
diff changeset
477 if ((position()+ len) >= buffer_size()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
478 flush();
a61af66fc99e Initial load
duke
parents:
diff changeset
479 }
a61af66fc99e Initial load
duke
parents:
diff changeset
480
a61af66fc99e Initial load
duke
parents:
diff changeset
481 // buffer not available or too big to buffer it
a61af66fc99e Initial load
duke
parents:
diff changeset
482 if ((buffer() == NULL) || (len >= buffer_size())) {
a61af66fc99e Initial load
duke
parents:
diff changeset
483 write_internal(s, len);
a61af66fc99e Initial load
duke
parents:
diff changeset
484 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
485 // Should optimize this for u1/u2/u4/u8 sizes.
a61af66fc99e Initial load
duke
parents:
diff changeset
486 memcpy(buffer() + position(), s, len);
a61af66fc99e Initial load
duke
parents:
diff changeset
487 set_position(position() + len);
a61af66fc99e Initial load
duke
parents:
diff changeset
488 }
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 // flush any buffered bytes to the file
a61af66fc99e Initial load
duke
parents:
diff changeset
493 void DumpWriter::flush() {
a61af66fc99e Initial load
duke
parents:
diff changeset
494 if (is_open() && position() > 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
495 write_internal(buffer(), position());
a61af66fc99e Initial load
duke
parents:
diff changeset
496 set_position(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
497 }
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 jlong DumpWriter::current_offset() {
a61af66fc99e Initial load
duke
parents:
diff changeset
502 if (is_open()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
503 // the offset is the file offset plus whatever we have buffered
a61af66fc99e Initial load
duke
parents:
diff changeset
504 jlong offset = os::current_file_offset(file_descriptor());
a61af66fc99e Initial load
duke
parents:
diff changeset
505 assert(offset >= 0, "lseek failed");
a61af66fc99e Initial load
duke
parents:
diff changeset
506 return offset + (jlong)position();
a61af66fc99e Initial load
duke
parents:
diff changeset
507 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
508 return (jlong)-1;
a61af66fc99e Initial load
duke
parents:
diff changeset
509 }
a61af66fc99e Initial load
duke
parents:
diff changeset
510 }
a61af66fc99e Initial load
duke
parents:
diff changeset
511
a61af66fc99e Initial load
duke
parents:
diff changeset
512 void DumpWriter::seek_to_offset(jlong off) {
a61af66fc99e Initial load
duke
parents:
diff changeset
513 assert(off >= 0, "bad offset");
a61af66fc99e Initial load
duke
parents:
diff changeset
514
a61af66fc99e Initial load
duke
parents:
diff changeset
515 // need to flush before seeking
a61af66fc99e Initial load
duke
parents:
diff changeset
516 flush();
a61af66fc99e Initial load
duke
parents:
diff changeset
517
a61af66fc99e Initial load
duke
parents:
diff changeset
518 // may be closed due to I/O error
a61af66fc99e Initial load
duke
parents:
diff changeset
519 if (is_open()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
520 jlong n = os::seek_to_file_offset(file_descriptor(), off);
a61af66fc99e Initial load
duke
parents:
diff changeset
521 assert(n >= 0, "lseek failed");
a61af66fc99e Initial load
duke
parents:
diff changeset
522 }
a61af66fc99e Initial load
duke
parents:
diff changeset
523 }
a61af66fc99e Initial load
duke
parents:
diff changeset
524
a61af66fc99e Initial load
duke
parents:
diff changeset
525 void DumpWriter::write_u2(u2 x) {
a61af66fc99e Initial load
duke
parents:
diff changeset
526 u2 v;
a61af66fc99e Initial load
duke
parents:
diff changeset
527 Bytes::put_Java_u2((address)&v, x);
a61af66fc99e Initial load
duke
parents:
diff changeset
528 write_raw((void*)&v, 2);
a61af66fc99e Initial load
duke
parents:
diff changeset
529 }
a61af66fc99e Initial load
duke
parents:
diff changeset
530
a61af66fc99e Initial load
duke
parents:
diff changeset
531 void DumpWriter::write_u4(u4 x) {
a61af66fc99e Initial load
duke
parents:
diff changeset
532 u4 v;
a61af66fc99e Initial load
duke
parents:
diff changeset
533 Bytes::put_Java_u4((address)&v, x);
a61af66fc99e Initial load
duke
parents:
diff changeset
534 write_raw((void*)&v, 4);
a61af66fc99e Initial load
duke
parents:
diff changeset
535 }
a61af66fc99e Initial load
duke
parents:
diff changeset
536
a61af66fc99e Initial load
duke
parents:
diff changeset
537 void DumpWriter::write_u8(u8 x) {
a61af66fc99e Initial load
duke
parents:
diff changeset
538 u8 v;
a61af66fc99e Initial load
duke
parents:
diff changeset
539 Bytes::put_Java_u8((address)&v, x);
a61af66fc99e Initial load
duke
parents:
diff changeset
540 write_raw((void*)&v, 8);
a61af66fc99e Initial load
duke
parents:
diff changeset
541 }
a61af66fc99e Initial load
duke
parents:
diff changeset
542
a61af66fc99e Initial load
duke
parents:
diff changeset
543 void DumpWriter::write_objectID(oop o) {
a61af66fc99e Initial load
duke
parents:
diff changeset
544 address a = (address)((uintptr_t)o);
a61af66fc99e Initial load
duke
parents:
diff changeset
545 #ifdef _LP64
a61af66fc99e Initial load
duke
parents:
diff changeset
546 write_u8((u8)a);
a61af66fc99e Initial load
duke
parents:
diff changeset
547 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
548 write_u4((u4)a);
a61af66fc99e Initial load
duke
parents:
diff changeset
549 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
550 }
a61af66fc99e Initial load
duke
parents:
diff changeset
551
396
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
552 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
553 #ifdef _LP64
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
554 write_u8((u8) x);
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
555 #else
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
556 write_u4(x);
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
557 #endif
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
558 }
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
559
0
a61af66fc99e Initial load
duke
parents:
diff changeset
560 // We use java mirror as the class ID
a61af66fc99e Initial load
duke
parents:
diff changeset
561 void DumpWriter::write_classID(Klass* k) {
a61af66fc99e Initial load
duke
parents:
diff changeset
562 write_objectID(k->java_mirror());
a61af66fc99e Initial load
duke
parents:
diff changeset
563 }
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 // Support class with a collection of functions used when dumping the heap
a61af66fc99e Initial load
duke
parents:
diff changeset
568
a61af66fc99e Initial load
duke
parents:
diff changeset
569 class DumperSupport : AllStatic {
a61af66fc99e Initial load
duke
parents:
diff changeset
570 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
571
a61af66fc99e Initial load
duke
parents:
diff changeset
572 // write a header of the given type
a61af66fc99e Initial load
duke
parents:
diff changeset
573 static void write_header(DumpWriter* writer, hprofTag tag, u4 len);
a61af66fc99e Initial load
duke
parents:
diff changeset
574
a61af66fc99e Initial load
duke
parents:
diff changeset
575 // returns hprof tag for the given type signature
a61af66fc99e Initial load
duke
parents:
diff changeset
576 static hprofTag sig2tag(symbolOop sig);
a61af66fc99e Initial load
duke
parents:
diff changeset
577 // returns hprof tag for the given basic type
a61af66fc99e Initial load
duke
parents:
diff changeset
578 static hprofTag type2tag(BasicType type);
a61af66fc99e Initial load
duke
parents:
diff changeset
579
a61af66fc99e Initial load
duke
parents:
diff changeset
580 // returns the size of the instance of the given class
a61af66fc99e Initial load
duke
parents:
diff changeset
581 static u4 instance_size(klassOop k);
a61af66fc99e Initial load
duke
parents:
diff changeset
582
a61af66fc99e Initial load
duke
parents:
diff changeset
583 // dump a jfloat
a61af66fc99e Initial load
duke
parents:
diff changeset
584 static void dump_float(DumpWriter* writer, jfloat f);
a61af66fc99e Initial load
duke
parents:
diff changeset
585 // dump a jdouble
a61af66fc99e Initial load
duke
parents:
diff changeset
586 static void dump_double(DumpWriter* writer, jdouble d);
a61af66fc99e Initial load
duke
parents:
diff changeset
587 // dumps the raw value of the given field
a61af66fc99e Initial load
duke
parents:
diff changeset
588 static void dump_field_value(DumpWriter* writer, char type, address addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
589 // dumps static fields of the given class
a61af66fc99e Initial load
duke
parents:
diff changeset
590 static void dump_static_fields(DumpWriter* writer, klassOop k);
a61af66fc99e Initial load
duke
parents:
diff changeset
591 // dump the raw values of the instance fields of the given object
a61af66fc99e Initial load
duke
parents:
diff changeset
592 static void dump_instance_fields(DumpWriter* writer, oop o);
a61af66fc99e Initial load
duke
parents:
diff changeset
593 // dumps the definition of the instance fields for a given class
a61af66fc99e Initial load
duke
parents:
diff changeset
594 static void dump_instance_field_descriptors(DumpWriter* writer, klassOop k);
a61af66fc99e Initial load
duke
parents:
diff changeset
595 // creates HPROF_GC_INSTANCE_DUMP record for the given object
a61af66fc99e Initial load
duke
parents:
diff changeset
596 static void dump_instance(DumpWriter* writer, oop o);
a61af66fc99e Initial load
duke
parents:
diff changeset
597 // creates HPROF_GC_CLASS_DUMP record for the given class and each of its
a61af66fc99e Initial load
duke
parents:
diff changeset
598 // array classes
a61af66fc99e Initial load
duke
parents:
diff changeset
599 static void dump_class_and_array_classes(DumpWriter* writer, klassOop k);
a61af66fc99e Initial load
duke
parents:
diff changeset
600 // creates HPROF_GC_CLASS_DUMP record for a given primitive array
a61af66fc99e Initial load
duke
parents:
diff changeset
601 // class (and each multi-dimensional array class too)
a61af66fc99e Initial load
duke
parents:
diff changeset
602 static void dump_basic_type_array_class(DumpWriter* writer, klassOop k);
a61af66fc99e Initial load
duke
parents:
diff changeset
603
a61af66fc99e Initial load
duke
parents:
diff changeset
604 // creates HPROF_GC_OBJ_ARRAY_DUMP record for the given object array
a61af66fc99e Initial load
duke
parents:
diff changeset
605 static void dump_object_array(DumpWriter* writer, objArrayOop array);
a61af66fc99e Initial load
duke
parents:
diff changeset
606 // creates HPROF_GC_PRIM_ARRAY_DUMP record for the given type array
a61af66fc99e Initial load
duke
parents:
diff changeset
607 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
608 // 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
609 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
610 };
a61af66fc99e Initial load
duke
parents:
diff changeset
611
a61af66fc99e Initial load
duke
parents:
diff changeset
612 // write a header of the given type
a61af66fc99e Initial load
duke
parents:
diff changeset
613 void DumperSupport:: write_header(DumpWriter* writer, hprofTag tag, u4 len) {
a61af66fc99e Initial load
duke
parents:
diff changeset
614 writer->write_u1((u1)tag);
a61af66fc99e Initial load
duke
parents:
diff changeset
615 writer->write_u4(0); // current ticks
a61af66fc99e Initial load
duke
parents:
diff changeset
616 writer->write_u4(len);
a61af66fc99e Initial load
duke
parents:
diff changeset
617 }
a61af66fc99e Initial load
duke
parents:
diff changeset
618
a61af66fc99e Initial load
duke
parents:
diff changeset
619 // returns hprof tag for the given type signature
a61af66fc99e Initial load
duke
parents:
diff changeset
620 hprofTag DumperSupport::sig2tag(symbolOop sig) {
a61af66fc99e Initial load
duke
parents:
diff changeset
621 switch (sig->byte_at(0)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
622 case JVM_SIGNATURE_CLASS : return HPROF_NORMAL_OBJECT;
a61af66fc99e Initial load
duke
parents:
diff changeset
623 case JVM_SIGNATURE_ARRAY : return HPROF_NORMAL_OBJECT;
a61af66fc99e Initial load
duke
parents:
diff changeset
624 case JVM_SIGNATURE_BYTE : return HPROF_BYTE;
a61af66fc99e Initial load
duke
parents:
diff changeset
625 case JVM_SIGNATURE_CHAR : return HPROF_CHAR;
a61af66fc99e Initial load
duke
parents:
diff changeset
626 case JVM_SIGNATURE_FLOAT : return HPROF_FLOAT;
a61af66fc99e Initial load
duke
parents:
diff changeset
627 case JVM_SIGNATURE_DOUBLE : return HPROF_DOUBLE;
a61af66fc99e Initial load
duke
parents:
diff changeset
628 case JVM_SIGNATURE_INT : return HPROF_INT;
a61af66fc99e Initial load
duke
parents:
diff changeset
629 case JVM_SIGNATURE_LONG : return HPROF_LONG;
a61af66fc99e Initial load
duke
parents:
diff changeset
630 case JVM_SIGNATURE_SHORT : return HPROF_SHORT;
a61af66fc99e Initial load
duke
parents:
diff changeset
631 case JVM_SIGNATURE_BOOLEAN : return HPROF_BOOLEAN;
a61af66fc99e Initial load
duke
parents:
diff changeset
632 default : ShouldNotReachHere(); /* to shut up compiler */ return HPROF_BYTE;
a61af66fc99e Initial load
duke
parents:
diff changeset
633 }
a61af66fc99e Initial load
duke
parents:
diff changeset
634 }
a61af66fc99e Initial load
duke
parents:
diff changeset
635
a61af66fc99e Initial load
duke
parents:
diff changeset
636 hprofTag DumperSupport::type2tag(BasicType type) {
a61af66fc99e Initial load
duke
parents:
diff changeset
637 switch (type) {
a61af66fc99e Initial load
duke
parents:
diff changeset
638 case T_BYTE : return HPROF_BYTE;
a61af66fc99e Initial load
duke
parents:
diff changeset
639 case T_CHAR : return HPROF_CHAR;
a61af66fc99e Initial load
duke
parents:
diff changeset
640 case T_FLOAT : return HPROF_FLOAT;
a61af66fc99e Initial load
duke
parents:
diff changeset
641 case T_DOUBLE : return HPROF_DOUBLE;
a61af66fc99e Initial load
duke
parents:
diff changeset
642 case T_INT : return HPROF_INT;
a61af66fc99e Initial load
duke
parents:
diff changeset
643 case T_LONG : return HPROF_LONG;
a61af66fc99e Initial load
duke
parents:
diff changeset
644 case T_SHORT : return HPROF_SHORT;
a61af66fc99e Initial load
duke
parents:
diff changeset
645 case T_BOOLEAN : return HPROF_BOOLEAN;
a61af66fc99e Initial load
duke
parents:
diff changeset
646 default : ShouldNotReachHere(); /* to shut up compiler */ return HPROF_BYTE;
a61af66fc99e Initial load
duke
parents:
diff changeset
647 }
a61af66fc99e Initial load
duke
parents:
diff changeset
648 }
a61af66fc99e Initial load
duke
parents:
diff changeset
649
a61af66fc99e Initial load
duke
parents:
diff changeset
650 // dump a jfloat
a61af66fc99e Initial load
duke
parents:
diff changeset
651 void DumperSupport::dump_float(DumpWriter* writer, jfloat f) {
a61af66fc99e Initial load
duke
parents:
diff changeset
652 if (g_isnan(f)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
653 writer->write_u4(0x7fc00000); // collapsing NaNs
a61af66fc99e Initial load
duke
parents:
diff changeset
654 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
655 union {
a61af66fc99e Initial load
duke
parents:
diff changeset
656 int i;
a61af66fc99e Initial load
duke
parents:
diff changeset
657 float f;
a61af66fc99e Initial load
duke
parents:
diff changeset
658 } u;
a61af66fc99e Initial load
duke
parents:
diff changeset
659 u.f = (float)f;
a61af66fc99e Initial load
duke
parents:
diff changeset
660 writer->write_u4((u4)u.i);
a61af66fc99e Initial load
duke
parents:
diff changeset
661 }
a61af66fc99e Initial load
duke
parents:
diff changeset
662 }
a61af66fc99e Initial load
duke
parents:
diff changeset
663
a61af66fc99e Initial load
duke
parents:
diff changeset
664 // dump a jdouble
a61af66fc99e Initial load
duke
parents:
diff changeset
665 void DumperSupport::dump_double(DumpWriter* writer, jdouble d) {
a61af66fc99e Initial load
duke
parents:
diff changeset
666 union {
a61af66fc99e Initial load
duke
parents:
diff changeset
667 jlong l;
a61af66fc99e Initial load
duke
parents:
diff changeset
668 double d;
a61af66fc99e Initial load
duke
parents:
diff changeset
669 } u;
a61af66fc99e Initial load
duke
parents:
diff changeset
670 if (g_isnan(d)) { // collapsing NaNs
a61af66fc99e Initial load
duke
parents:
diff changeset
671 u.l = (jlong)(0x7ff80000);
a61af66fc99e Initial load
duke
parents:
diff changeset
672 u.l = (u.l << 32);
a61af66fc99e Initial load
duke
parents:
diff changeset
673 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
674 u.d = (double)d;
a61af66fc99e Initial load
duke
parents:
diff changeset
675 }
a61af66fc99e Initial load
duke
parents:
diff changeset
676 writer->write_u8((u8)u.l);
a61af66fc99e Initial load
duke
parents:
diff changeset
677 }
a61af66fc99e Initial load
duke
parents:
diff changeset
678
a61af66fc99e Initial load
duke
parents:
diff changeset
679 // dumps the raw value of the given field
a61af66fc99e Initial load
duke
parents:
diff changeset
680 void DumperSupport::dump_field_value(DumpWriter* writer, char type, address addr) {
a61af66fc99e Initial load
duke
parents:
diff changeset
681 switch (type) {
a61af66fc99e Initial load
duke
parents:
diff changeset
682 case JVM_SIGNATURE_CLASS :
a61af66fc99e Initial load
duke
parents:
diff changeset
683 case JVM_SIGNATURE_ARRAY : {
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 29
diff changeset
684 oop o;
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 29
diff changeset
685 if (UseCompressedOops) {
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 29
diff changeset
686 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
687 } else {
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 29
diff changeset
688 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
689 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
690
a61af66fc99e Initial load
duke
parents:
diff changeset
691 // reflection and sun.misc.Unsafe classes may have a reference to a
a61af66fc99e Initial load
duke
parents:
diff changeset
692 // klassOop so filter it out.
a61af66fc99e Initial load
duke
parents:
diff changeset
693 if (o != NULL && o->is_klass()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
694 o = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
695 }
a61af66fc99e Initial load
duke
parents:
diff changeset
696
a61af66fc99e Initial load
duke
parents:
diff changeset
697 // FIXME: When sharing is enabled we don't emit field references to objects
a61af66fc99e Initial load
duke
parents:
diff changeset
698 // in shared spaces. We can remove this once we write records for the classes
a61af66fc99e Initial load
duke
parents:
diff changeset
699 // and strings that are shared.
a61af66fc99e Initial load
duke
parents:
diff changeset
700 if (o != NULL && o->is_shared()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
701 o = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
702 }
a61af66fc99e Initial load
duke
parents:
diff changeset
703 writer->write_objectID(o);
a61af66fc99e Initial load
duke
parents:
diff changeset
704 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
705 }
a61af66fc99e Initial load
duke
parents:
diff changeset
706 case JVM_SIGNATURE_BYTE : {
a61af66fc99e Initial load
duke
parents:
diff changeset
707 jbyte* b = (jbyte*)addr;
a61af66fc99e Initial load
duke
parents:
diff changeset
708 writer->write_u1((u1)*b);
a61af66fc99e Initial load
duke
parents:
diff changeset
709 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
710 }
a61af66fc99e Initial load
duke
parents:
diff changeset
711 case JVM_SIGNATURE_CHAR : {
a61af66fc99e Initial load
duke
parents:
diff changeset
712 jchar* c = (jchar*)addr;
a61af66fc99e Initial load
duke
parents:
diff changeset
713 writer->write_u2((u2)*c);
a61af66fc99e Initial load
duke
parents:
diff changeset
714 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
715 }
a61af66fc99e Initial load
duke
parents:
diff changeset
716 case JVM_SIGNATURE_SHORT : {
a61af66fc99e Initial load
duke
parents:
diff changeset
717 jshort* s = (jshort*)addr;
a61af66fc99e Initial load
duke
parents:
diff changeset
718 writer->write_u2((u2)*s);
a61af66fc99e Initial load
duke
parents:
diff changeset
719 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
720 }
a61af66fc99e Initial load
duke
parents:
diff changeset
721 case JVM_SIGNATURE_FLOAT : {
a61af66fc99e Initial load
duke
parents:
diff changeset
722 jfloat* f = (jfloat*)addr;
a61af66fc99e Initial load
duke
parents:
diff changeset
723 dump_float(writer, *f);
a61af66fc99e Initial load
duke
parents:
diff changeset
724 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
725 }
a61af66fc99e Initial load
duke
parents:
diff changeset
726 case JVM_SIGNATURE_DOUBLE : {
a61af66fc99e Initial load
duke
parents:
diff changeset
727 jdouble* f = (jdouble*)addr;
a61af66fc99e Initial load
duke
parents:
diff changeset
728 dump_double(writer, *f);
a61af66fc99e Initial load
duke
parents:
diff changeset
729 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
730 }
a61af66fc99e Initial load
duke
parents:
diff changeset
731 case JVM_SIGNATURE_INT : {
a61af66fc99e Initial load
duke
parents:
diff changeset
732 jint* i = (jint*)addr;
a61af66fc99e Initial load
duke
parents:
diff changeset
733 writer->write_u4((u4)*i);
a61af66fc99e Initial load
duke
parents:
diff changeset
734 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
735 }
a61af66fc99e Initial load
duke
parents:
diff changeset
736 case JVM_SIGNATURE_LONG : {
a61af66fc99e Initial load
duke
parents:
diff changeset
737 jlong* l = (jlong*)addr;
a61af66fc99e Initial load
duke
parents:
diff changeset
738 writer->write_u8((u8)*l);
a61af66fc99e Initial load
duke
parents:
diff changeset
739 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
740 }
a61af66fc99e Initial load
duke
parents:
diff changeset
741 case JVM_SIGNATURE_BOOLEAN : {
a61af66fc99e Initial load
duke
parents:
diff changeset
742 jboolean* b = (jboolean*)addr;
a61af66fc99e Initial load
duke
parents:
diff changeset
743 writer->write_u1((u1)*b);
a61af66fc99e Initial load
duke
parents:
diff changeset
744 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
745 }
a61af66fc99e Initial load
duke
parents:
diff changeset
746 default : ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
747 }
a61af66fc99e Initial load
duke
parents:
diff changeset
748 }
a61af66fc99e Initial load
duke
parents:
diff changeset
749
a61af66fc99e Initial load
duke
parents:
diff changeset
750 // returns the size of the instance of the given class
a61af66fc99e Initial load
duke
parents:
diff changeset
751 u4 DumperSupport::instance_size(klassOop k) {
a61af66fc99e Initial load
duke
parents:
diff changeset
752 HandleMark hm;
a61af66fc99e Initial load
duke
parents:
diff changeset
753 instanceKlassHandle ikh = instanceKlassHandle(Thread::current(), k);
a61af66fc99e Initial load
duke
parents:
diff changeset
754
a61af66fc99e Initial load
duke
parents:
diff changeset
755 int size = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
756
a61af66fc99e Initial load
duke
parents:
diff changeset
757 for (FieldStream fld(ikh, false, false); !fld.eos(); fld.next()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
758 if (!fld.access_flags().is_static()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
759 symbolOop sig = fld.signature();
a61af66fc99e Initial load
duke
parents:
diff changeset
760 switch (sig->byte_at(0)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
761 case JVM_SIGNATURE_CLASS :
a61af66fc99e Initial load
duke
parents:
diff changeset
762 case JVM_SIGNATURE_ARRAY : size += oopSize; break;
a61af66fc99e Initial load
duke
parents:
diff changeset
763
a61af66fc99e Initial load
duke
parents:
diff changeset
764 case JVM_SIGNATURE_BYTE :
a61af66fc99e Initial load
duke
parents:
diff changeset
765 case JVM_SIGNATURE_BOOLEAN : size += 1; break;
a61af66fc99e Initial load
duke
parents:
diff changeset
766
a61af66fc99e Initial load
duke
parents:
diff changeset
767 case JVM_SIGNATURE_CHAR :
a61af66fc99e Initial load
duke
parents:
diff changeset
768 case JVM_SIGNATURE_SHORT : size += 2; break;
a61af66fc99e Initial load
duke
parents:
diff changeset
769
a61af66fc99e Initial load
duke
parents:
diff changeset
770 case JVM_SIGNATURE_INT :
a61af66fc99e Initial load
duke
parents:
diff changeset
771 case JVM_SIGNATURE_FLOAT : size += 4; break;
a61af66fc99e Initial load
duke
parents:
diff changeset
772
a61af66fc99e Initial load
duke
parents:
diff changeset
773 case JVM_SIGNATURE_LONG :
a61af66fc99e Initial load
duke
parents:
diff changeset
774 case JVM_SIGNATURE_DOUBLE : size += 8; break;
a61af66fc99e Initial load
duke
parents:
diff changeset
775
a61af66fc99e Initial load
duke
parents:
diff changeset
776 default : ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
777 }
a61af66fc99e Initial load
duke
parents:
diff changeset
778 }
a61af66fc99e Initial load
duke
parents:
diff changeset
779 }
a61af66fc99e Initial load
duke
parents:
diff changeset
780 return (u4)size;
a61af66fc99e Initial load
duke
parents:
diff changeset
781 }
a61af66fc99e Initial load
duke
parents:
diff changeset
782
a61af66fc99e Initial load
duke
parents:
diff changeset
783 // dumps static fields of the given class
a61af66fc99e Initial load
duke
parents:
diff changeset
784 void DumperSupport::dump_static_fields(DumpWriter* writer, klassOop k) {
a61af66fc99e Initial load
duke
parents:
diff changeset
785 HandleMark hm;
a61af66fc99e Initial load
duke
parents:
diff changeset
786 instanceKlassHandle ikh = instanceKlassHandle(Thread::current(), k);
a61af66fc99e Initial load
duke
parents:
diff changeset
787
a61af66fc99e Initial load
duke
parents:
diff changeset
788 // pass 1 - count the static fields
a61af66fc99e Initial load
duke
parents:
diff changeset
789 u2 field_count = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
790 for (FieldStream fldc(ikh, true, true); !fldc.eos(); fldc.next()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
791 if (fldc.access_flags().is_static()) field_count++;
a61af66fc99e Initial load
duke
parents:
diff changeset
792 }
a61af66fc99e Initial load
duke
parents:
diff changeset
793
a61af66fc99e Initial load
duke
parents:
diff changeset
794 writer->write_u2(field_count);
a61af66fc99e Initial load
duke
parents:
diff changeset
795
a61af66fc99e Initial load
duke
parents:
diff changeset
796 // pass 2 - dump the field descriptors and raw values
a61af66fc99e Initial load
duke
parents:
diff changeset
797 for (FieldStream fld(ikh, true, true); !fld.eos(); fld.next()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
798 if (fld.access_flags().is_static()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
799 symbolOop sig = fld.signature();
a61af66fc99e Initial load
duke
parents:
diff changeset
800
a61af66fc99e Initial load
duke
parents:
diff changeset
801 writer->write_objectID(fld.name()); // name
a61af66fc99e Initial load
duke
parents:
diff changeset
802 writer->write_u1(sig2tag(sig)); // type
a61af66fc99e Initial load
duke
parents:
diff changeset
803
a61af66fc99e Initial load
duke
parents:
diff changeset
804 // value
a61af66fc99e Initial load
duke
parents:
diff changeset
805 int offset = fld.offset();
a61af66fc99e Initial load
duke
parents:
diff changeset
806 address addr = (address)k + offset;
a61af66fc99e Initial load
duke
parents:
diff changeset
807
a61af66fc99e Initial load
duke
parents:
diff changeset
808 dump_field_value(writer, sig->byte_at(0), addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
809 }
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 // dump the raw values of the instance fields of the given object
a61af66fc99e Initial load
duke
parents:
diff changeset
814 void DumperSupport::dump_instance_fields(DumpWriter* writer, oop o) {
a61af66fc99e Initial load
duke
parents:
diff changeset
815 HandleMark hm;
a61af66fc99e Initial load
duke
parents:
diff changeset
816 instanceKlassHandle ikh = instanceKlassHandle(Thread::current(), o->klass());
a61af66fc99e Initial load
duke
parents:
diff changeset
817
a61af66fc99e Initial load
duke
parents:
diff changeset
818 for (FieldStream fld(ikh, false, false); !fld.eos(); fld.next()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
819 if (!fld.access_flags().is_static()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
820 symbolOop sig = fld.signature();
a61af66fc99e Initial load
duke
parents:
diff changeset
821 address addr = (address)o + fld.offset();
a61af66fc99e Initial load
duke
parents:
diff changeset
822
a61af66fc99e Initial load
duke
parents:
diff changeset
823 dump_field_value(writer, sig->byte_at(0), addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
824 }
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 // dumps the definition of the instance fields for a given class
a61af66fc99e Initial load
duke
parents:
diff changeset
829 void DumperSupport::dump_instance_field_descriptors(DumpWriter* writer, klassOop k) {
a61af66fc99e Initial load
duke
parents:
diff changeset
830 HandleMark hm;
a61af66fc99e Initial load
duke
parents:
diff changeset
831 instanceKlassHandle ikh = instanceKlassHandle(Thread::current(), k);
a61af66fc99e Initial load
duke
parents:
diff changeset
832
a61af66fc99e Initial load
duke
parents:
diff changeset
833 // pass 1 - count the instance fields
a61af66fc99e Initial load
duke
parents:
diff changeset
834 u2 field_count = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
835 for (FieldStream fldc(ikh, true, true); !fldc.eos(); fldc.next()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
836 if (!fldc.access_flags().is_static()) field_count++;
a61af66fc99e Initial load
duke
parents:
diff changeset
837 }
a61af66fc99e Initial load
duke
parents:
diff changeset
838
a61af66fc99e Initial load
duke
parents:
diff changeset
839 writer->write_u2(field_count);
a61af66fc99e Initial load
duke
parents:
diff changeset
840
a61af66fc99e Initial load
duke
parents:
diff changeset
841 // pass 2 - dump the field descriptors
a61af66fc99e Initial load
duke
parents:
diff changeset
842 for (FieldStream fld(ikh, true, true); !fld.eos(); fld.next()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
843 if (!fld.access_flags().is_static()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
844 symbolOop sig = fld.signature();
a61af66fc99e Initial load
duke
parents:
diff changeset
845
a61af66fc99e Initial load
duke
parents:
diff changeset
846 writer->write_objectID(fld.name()); // name
a61af66fc99e Initial load
duke
parents:
diff changeset
847 writer->write_u1(sig2tag(sig)); // type
a61af66fc99e Initial load
duke
parents:
diff changeset
848 }
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 // creates HPROF_GC_INSTANCE_DUMP record for the given object
a61af66fc99e Initial load
duke
parents:
diff changeset
853 void DumperSupport::dump_instance(DumpWriter* writer, oop o) {
a61af66fc99e Initial load
duke
parents:
diff changeset
854 klassOop k = o->klass();
a61af66fc99e Initial load
duke
parents:
diff changeset
855
a61af66fc99e Initial load
duke
parents:
diff changeset
856 writer->write_u1(HPROF_GC_INSTANCE_DUMP);
a61af66fc99e Initial load
duke
parents:
diff changeset
857 writer->write_objectID(o);
a61af66fc99e Initial load
duke
parents:
diff changeset
858 writer->write_u4(STACK_TRACE_ID);
a61af66fc99e Initial load
duke
parents:
diff changeset
859
a61af66fc99e Initial load
duke
parents:
diff changeset
860 // class ID
a61af66fc99e Initial load
duke
parents:
diff changeset
861 writer->write_classID(Klass::cast(k));
a61af66fc99e Initial load
duke
parents:
diff changeset
862
a61af66fc99e Initial load
duke
parents:
diff changeset
863 // number of bytes that follow
a61af66fc99e Initial load
duke
parents:
diff changeset
864 writer->write_u4(instance_size(k) );
a61af66fc99e Initial load
duke
parents:
diff changeset
865
a61af66fc99e Initial load
duke
parents:
diff changeset
866 // field values
a61af66fc99e Initial load
duke
parents:
diff changeset
867 dump_instance_fields(writer, o);
a61af66fc99e Initial load
duke
parents:
diff changeset
868 }
a61af66fc99e Initial load
duke
parents:
diff changeset
869
a61af66fc99e Initial load
duke
parents:
diff changeset
870 // creates HPROF_GC_CLASS_DUMP record for the given class and each of
a61af66fc99e Initial load
duke
parents:
diff changeset
871 // its array classes
a61af66fc99e Initial load
duke
parents:
diff changeset
872 void DumperSupport::dump_class_and_array_classes(DumpWriter* writer, klassOop k) {
a61af66fc99e Initial load
duke
parents:
diff changeset
873 Klass* klass = Klass::cast(k);
a61af66fc99e Initial load
duke
parents:
diff changeset
874 assert(klass->oop_is_instance(), "not an instanceKlass");
a61af66fc99e Initial load
duke
parents:
diff changeset
875 instanceKlass* ik = (instanceKlass*)klass;
a61af66fc99e Initial load
duke
parents:
diff changeset
876
a61af66fc99e Initial load
duke
parents:
diff changeset
877 writer->write_u1(HPROF_GC_CLASS_DUMP);
a61af66fc99e Initial load
duke
parents:
diff changeset
878
a61af66fc99e Initial load
duke
parents:
diff changeset
879 // class ID
a61af66fc99e Initial load
duke
parents:
diff changeset
880 writer->write_classID(ik);
a61af66fc99e Initial load
duke
parents:
diff changeset
881 writer->write_u4(STACK_TRACE_ID);
a61af66fc99e Initial load
duke
parents:
diff changeset
882
a61af66fc99e Initial load
duke
parents:
diff changeset
883 // super class ID
a61af66fc99e Initial load
duke
parents:
diff changeset
884 klassOop java_super = ik->java_super();
a61af66fc99e Initial load
duke
parents:
diff changeset
885 if (java_super == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
886 writer->write_objectID(NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
887 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
888 writer->write_classID(Klass::cast(java_super));
a61af66fc99e Initial load
duke
parents:
diff changeset
889 }
a61af66fc99e Initial load
duke
parents:
diff changeset
890
a61af66fc99e Initial load
duke
parents:
diff changeset
891 writer->write_objectID(ik->class_loader());
a61af66fc99e Initial load
duke
parents:
diff changeset
892 writer->write_objectID(ik->signers());
a61af66fc99e Initial load
duke
parents:
diff changeset
893 writer->write_objectID(ik->protection_domain());
a61af66fc99e Initial load
duke
parents:
diff changeset
894
a61af66fc99e Initial load
duke
parents:
diff changeset
895 // reserved
a61af66fc99e Initial load
duke
parents:
diff changeset
896 writer->write_objectID(NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
897 writer->write_objectID(NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
898
a61af66fc99e Initial load
duke
parents:
diff changeset
899 // instance size
a61af66fc99e Initial load
duke
parents:
diff changeset
900 writer->write_u4(DumperSupport::instance_size(k));
a61af66fc99e Initial load
duke
parents:
diff changeset
901
a61af66fc99e Initial load
duke
parents:
diff changeset
902 // size of constant pool - ignored by HAT 1.1
a61af66fc99e Initial load
duke
parents:
diff changeset
903 writer->write_u2(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
904
a61af66fc99e Initial load
duke
parents:
diff changeset
905 // number of static fields
a61af66fc99e Initial load
duke
parents:
diff changeset
906 dump_static_fields(writer, k);
a61af66fc99e Initial load
duke
parents:
diff changeset
907
a61af66fc99e Initial load
duke
parents:
diff changeset
908 // description of instance fields
a61af66fc99e Initial load
duke
parents:
diff changeset
909 dump_instance_field_descriptors(writer, k);
a61af66fc99e Initial load
duke
parents:
diff changeset
910
a61af66fc99e Initial load
duke
parents:
diff changeset
911 // array classes
a61af66fc99e Initial load
duke
parents:
diff changeset
912 k = klass->array_klass_or_null();
a61af66fc99e Initial load
duke
parents:
diff changeset
913 while (k != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
914 Klass* klass = Klass::cast(k);
a61af66fc99e Initial load
duke
parents:
diff changeset
915 assert(klass->oop_is_objArray(), "not an objArrayKlass");
a61af66fc99e Initial load
duke
parents:
diff changeset
916
a61af66fc99e Initial load
duke
parents:
diff changeset
917 writer->write_u1(HPROF_GC_CLASS_DUMP);
a61af66fc99e Initial load
duke
parents:
diff changeset
918 writer->write_classID(klass);
a61af66fc99e Initial load
duke
parents:
diff changeset
919 writer->write_u4(STACK_TRACE_ID);
a61af66fc99e Initial load
duke
parents:
diff changeset
920
a61af66fc99e Initial load
duke
parents:
diff changeset
921 // super class of array classes is java.lang.Object
a61af66fc99e Initial load
duke
parents:
diff changeset
922 java_super = klass->java_super();
a61af66fc99e Initial load
duke
parents:
diff changeset
923 assert(java_super != NULL, "checking");
a61af66fc99e Initial load
duke
parents:
diff changeset
924 writer->write_classID(Klass::cast(java_super));
a61af66fc99e Initial load
duke
parents:
diff changeset
925
a61af66fc99e Initial load
duke
parents:
diff changeset
926 writer->write_objectID(ik->class_loader());
a61af66fc99e Initial load
duke
parents:
diff changeset
927 writer->write_objectID(ik->signers());
a61af66fc99e Initial load
duke
parents:
diff changeset
928 writer->write_objectID(ik->protection_domain());
a61af66fc99e Initial load
duke
parents:
diff changeset
929
a61af66fc99e Initial load
duke
parents:
diff changeset
930 writer->write_objectID(NULL); // reserved
a61af66fc99e Initial load
duke
parents:
diff changeset
931 writer->write_objectID(NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
932 writer->write_u4(0); // instance size
a61af66fc99e Initial load
duke
parents:
diff changeset
933 writer->write_u2(0); // constant pool
a61af66fc99e Initial load
duke
parents:
diff changeset
934 writer->write_u2(0); // static fields
a61af66fc99e Initial load
duke
parents:
diff changeset
935 writer->write_u2(0); // instance fields
a61af66fc99e Initial load
duke
parents:
diff changeset
936
a61af66fc99e Initial load
duke
parents:
diff changeset
937 // get the array class for the next rank
a61af66fc99e Initial load
duke
parents:
diff changeset
938 k = klass->array_klass_or_null();
a61af66fc99e Initial load
duke
parents:
diff changeset
939 }
a61af66fc99e Initial load
duke
parents:
diff changeset
940 }
a61af66fc99e Initial load
duke
parents:
diff changeset
941
a61af66fc99e Initial load
duke
parents:
diff changeset
942 // creates HPROF_GC_CLASS_DUMP record for a given primitive array
a61af66fc99e Initial load
duke
parents:
diff changeset
943 // class (and each multi-dimensional array class too)
a61af66fc99e Initial load
duke
parents:
diff changeset
944 void DumperSupport::dump_basic_type_array_class(DumpWriter* writer, klassOop k) {
a61af66fc99e Initial load
duke
parents:
diff changeset
945 // array classes
a61af66fc99e Initial load
duke
parents:
diff changeset
946 while (k != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
947 Klass* klass = Klass::cast(k);
a61af66fc99e Initial load
duke
parents:
diff changeset
948
a61af66fc99e Initial load
duke
parents:
diff changeset
949 writer->write_u1(HPROF_GC_CLASS_DUMP);
a61af66fc99e Initial load
duke
parents:
diff changeset
950 writer->write_classID(klass);
a61af66fc99e Initial load
duke
parents:
diff changeset
951 writer->write_u4(STACK_TRACE_ID);
a61af66fc99e Initial load
duke
parents:
diff changeset
952
a61af66fc99e Initial load
duke
parents:
diff changeset
953 // super class of array classes is java.lang.Object
a61af66fc99e Initial load
duke
parents:
diff changeset
954 klassOop java_super = klass->java_super();
a61af66fc99e Initial load
duke
parents:
diff changeset
955 assert(java_super != NULL, "checking");
a61af66fc99e Initial load
duke
parents:
diff changeset
956 writer->write_classID(Klass::cast(java_super));
a61af66fc99e Initial load
duke
parents:
diff changeset
957
a61af66fc99e Initial load
duke
parents:
diff changeset
958 writer->write_objectID(NULL); // loader
a61af66fc99e Initial load
duke
parents:
diff changeset
959 writer->write_objectID(NULL); // signers
a61af66fc99e Initial load
duke
parents:
diff changeset
960 writer->write_objectID(NULL); // protection domain
a61af66fc99e Initial load
duke
parents:
diff changeset
961
a61af66fc99e Initial load
duke
parents:
diff changeset
962 writer->write_objectID(NULL); // reserved
a61af66fc99e Initial load
duke
parents:
diff changeset
963 writer->write_objectID(NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
964 writer->write_u4(0); // instance size
a61af66fc99e Initial load
duke
parents:
diff changeset
965 writer->write_u2(0); // constant pool
a61af66fc99e Initial load
duke
parents:
diff changeset
966 writer->write_u2(0); // static fields
a61af66fc99e Initial load
duke
parents:
diff changeset
967 writer->write_u2(0); // instance fields
a61af66fc99e Initial load
duke
parents:
diff changeset
968
a61af66fc99e Initial load
duke
parents:
diff changeset
969 // get the array class for the next rank
a61af66fc99e Initial load
duke
parents:
diff changeset
970 k = klass->array_klass_or_null();
a61af66fc99e Initial load
duke
parents:
diff changeset
971 }
a61af66fc99e Initial load
duke
parents:
diff changeset
972 }
a61af66fc99e Initial load
duke
parents:
diff changeset
973
a61af66fc99e Initial load
duke
parents:
diff changeset
974 // creates HPROF_GC_OBJ_ARRAY_DUMP record for the given object array
a61af66fc99e Initial load
duke
parents:
diff changeset
975 void DumperSupport::dump_object_array(DumpWriter* writer, objArrayOop array) {
a61af66fc99e Initial load
duke
parents:
diff changeset
976
a61af66fc99e Initial load
duke
parents:
diff changeset
977 // filter this
a61af66fc99e Initial load
duke
parents:
diff changeset
978 if (array->klass() == Universe::systemObjArrayKlassObj()) return;
a61af66fc99e Initial load
duke
parents:
diff changeset
979
a61af66fc99e Initial load
duke
parents:
diff changeset
980 writer->write_u1(HPROF_GC_OBJ_ARRAY_DUMP);
a61af66fc99e Initial load
duke
parents:
diff changeset
981 writer->write_objectID(array);
a61af66fc99e Initial load
duke
parents:
diff changeset
982 writer->write_u4(STACK_TRACE_ID);
a61af66fc99e Initial load
duke
parents:
diff changeset
983 writer->write_u4((u4)array->length());
a61af66fc99e Initial load
duke
parents:
diff changeset
984
a61af66fc99e Initial load
duke
parents:
diff changeset
985 // array class ID
a61af66fc99e Initial load
duke
parents:
diff changeset
986 writer->write_classID(Klass::cast(array->klass()));
a61af66fc99e Initial load
duke
parents:
diff changeset
987
a61af66fc99e Initial load
duke
parents:
diff changeset
988 // [id]* elements
a61af66fc99e Initial load
duke
parents:
diff changeset
989 for (int index=0; index<array->length(); index++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
990 oop o = array->obj_at(index);
a61af66fc99e Initial load
duke
parents:
diff changeset
991 writer->write_objectID(o);
a61af66fc99e Initial load
duke
parents:
diff changeset
992 }
a61af66fc99e Initial load
duke
parents:
diff changeset
993 }
a61af66fc99e Initial load
duke
parents:
diff changeset
994
a61af66fc99e Initial load
duke
parents:
diff changeset
995 #define WRITE_ARRAY(Array, Type, Size) \
a61af66fc99e Initial load
duke
parents:
diff changeset
996 for (int i=0; i<Array->length(); i++) { writer->write_##Size((Size)array->Type##_at(i)); }
a61af66fc99e Initial load
duke
parents:
diff changeset
997
a61af66fc99e Initial load
duke
parents:
diff changeset
998
a61af66fc99e Initial load
duke
parents:
diff changeset
999 // creates HPROF_GC_PRIM_ARRAY_DUMP record for the given type array
a61af66fc99e Initial load
duke
parents:
diff changeset
1000 void DumperSupport::dump_prim_array(DumpWriter* writer, typeArrayOop array) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1001 BasicType type = typeArrayKlass::cast(array->klass())->element_type();
a61af66fc99e Initial load
duke
parents:
diff changeset
1002
a61af66fc99e Initial load
duke
parents:
diff changeset
1003 writer->write_u1(HPROF_GC_PRIM_ARRAY_DUMP);
a61af66fc99e Initial load
duke
parents:
diff changeset
1004 writer->write_objectID(array);
a61af66fc99e Initial load
duke
parents:
diff changeset
1005 writer->write_u4(STACK_TRACE_ID);
a61af66fc99e Initial load
duke
parents:
diff changeset
1006 writer->write_u4((u4)array->length());
a61af66fc99e Initial load
duke
parents:
diff changeset
1007 writer->write_u1(type2tag(type));
a61af66fc99e Initial load
duke
parents:
diff changeset
1008
a61af66fc99e Initial load
duke
parents:
diff changeset
1009 // nothing to copy
a61af66fc99e Initial load
duke
parents:
diff changeset
1010 if (array->length() == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1011 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
1012 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1013
a61af66fc99e Initial load
duke
parents:
diff changeset
1014 // 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
1015 int length_in_bytes = array->length() * type2aelembytes(type);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1016 assert(length_in_bytes > 0, "nothing to copy");
a61af66fc99e Initial load
duke
parents:
diff changeset
1017
a61af66fc99e Initial load
duke
parents:
diff changeset
1018 switch (type) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1019 case T_INT : {
a61af66fc99e Initial load
duke
parents:
diff changeset
1020 if (Bytes::is_Java_byte_ordering_different()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1021 WRITE_ARRAY(array, int, u4);
a61af66fc99e Initial load
duke
parents:
diff changeset
1022 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1023 writer->write_raw((void*)(array->int_at_addr(0)), length_in_bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
1024 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1025 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1026 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1027 case T_BYTE : {
a61af66fc99e Initial load
duke
parents:
diff changeset
1028 writer->write_raw((void*)(array->byte_at_addr(0)), length_in_bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
1029 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1030 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1031 case T_CHAR : {
a61af66fc99e Initial load
duke
parents:
diff changeset
1032 if (Bytes::is_Java_byte_ordering_different()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1033 WRITE_ARRAY(array, char, u2);
a61af66fc99e Initial load
duke
parents:
diff changeset
1034 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1035 writer->write_raw((void*)(array->char_at_addr(0)), length_in_bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
1036 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1037 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1038 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1039 case T_SHORT : {
a61af66fc99e Initial load
duke
parents:
diff changeset
1040 if (Bytes::is_Java_byte_ordering_different()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1041 WRITE_ARRAY(array, short, u2);
a61af66fc99e Initial load
duke
parents:
diff changeset
1042 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1043 writer->write_raw((void*)(array->short_at_addr(0)), length_in_bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
1044 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1045 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1046 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1047 case T_BOOLEAN : {
a61af66fc99e Initial load
duke
parents:
diff changeset
1048 if (Bytes::is_Java_byte_ordering_different()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1049 WRITE_ARRAY(array, bool, u1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1050 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1051 writer->write_raw((void*)(array->bool_at_addr(0)), length_in_bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
1052 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1053 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1054 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1055 case T_LONG : {
a61af66fc99e Initial load
duke
parents:
diff changeset
1056 if (Bytes::is_Java_byte_ordering_different()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1057 WRITE_ARRAY(array, long, u8);
a61af66fc99e Initial load
duke
parents:
diff changeset
1058 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1059 writer->write_raw((void*)(array->long_at_addr(0)), length_in_bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
1060 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1061 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1062 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1063
a61af66fc99e Initial load
duke
parents:
diff changeset
1064 // handle float/doubles in a special value to ensure than NaNs are
a61af66fc99e Initial load
duke
parents:
diff changeset
1065 // written correctly. TO DO: Check if we can avoid this on processors that
a61af66fc99e Initial load
duke
parents:
diff changeset
1066 // use IEEE 754.
a61af66fc99e Initial load
duke
parents:
diff changeset
1067
a61af66fc99e Initial load
duke
parents:
diff changeset
1068 case T_FLOAT : {
a61af66fc99e Initial load
duke
parents:
diff changeset
1069 for (int i=0; i<array->length(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1070 dump_float( writer, array->float_at(i) );
a61af66fc99e Initial load
duke
parents:
diff changeset
1071 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1072 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1073 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1074 case T_DOUBLE : {
a61af66fc99e Initial load
duke
parents:
diff changeset
1075 for (int i=0; i<array->length(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1076 dump_double( writer, array->double_at(i) );
a61af66fc99e Initial load
duke
parents:
diff changeset
1077 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1078 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1079 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1080 default : ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
1081 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1082 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1083
396
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1084 // 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
1085 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
1086 int frame_serial_num,
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1087 int class_serial_num,
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1088 methodOop m,
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1089 int bci) {
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1090 int line_number;
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1091 if (m->is_native()) {
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1092 line_number = -3; // native frame
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1093 } else {
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1094 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
1095 }
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 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
1098 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
1099 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
1100 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
1101
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1102 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
1103 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
1104 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
1105 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
1106 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1107
a61af66fc99e Initial load
duke
parents:
diff changeset
1108 // Support class used to generate HPROF_UTF8 records from the entries in the
a61af66fc99e Initial load
duke
parents:
diff changeset
1109 // SymbolTable.
a61af66fc99e Initial load
duke
parents:
diff changeset
1110
a61af66fc99e Initial load
duke
parents:
diff changeset
1111 class SymbolTableDumper : public OopClosure {
a61af66fc99e Initial load
duke
parents:
diff changeset
1112 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
1113 DumpWriter* _writer;
a61af66fc99e Initial load
duke
parents:
diff changeset
1114 DumpWriter* writer() const { return _writer; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1115 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
1116 SymbolTableDumper(DumpWriter* writer) { _writer = writer; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1117 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
1118 void do_oop(narrowOop* obj_p) { ShouldNotReachHere(); }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1119 };
a61af66fc99e Initial load
duke
parents:
diff changeset
1120
a61af66fc99e Initial load
duke
parents:
diff changeset
1121 void SymbolTableDumper::do_oop(oop* obj_p) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1122 ResourceMark rm;
a61af66fc99e Initial load
duke
parents:
diff changeset
1123 symbolOop sym = (symbolOop)*obj_p;
a61af66fc99e Initial load
duke
parents:
diff changeset
1124
a61af66fc99e Initial load
duke
parents:
diff changeset
1125 int len = sym->utf8_length();
a61af66fc99e Initial load
duke
parents:
diff changeset
1126 if (len > 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1127 char* s = sym->as_utf8();
a61af66fc99e Initial load
duke
parents:
diff changeset
1128 DumperSupport::write_header(writer(), HPROF_UTF8, oopSize + len);
a61af66fc99e Initial load
duke
parents:
diff changeset
1129 writer()->write_objectID(sym);
a61af66fc99e Initial load
duke
parents:
diff changeset
1130 writer()->write_raw(s, len);
a61af66fc99e Initial load
duke
parents:
diff changeset
1131 }
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 // Support class used to generate HPROF_GC_ROOT_JNI_LOCAL records
a61af66fc99e Initial load
duke
parents:
diff changeset
1136
a61af66fc99e Initial load
duke
parents:
diff changeset
1137 class JNILocalsDumper : public OopClosure {
a61af66fc99e Initial load
duke
parents:
diff changeset
1138 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
1139 DumpWriter* _writer;
a61af66fc99e Initial load
duke
parents:
diff changeset
1140 u4 _thread_serial_num;
396
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1141 int _frame_num;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1142 DumpWriter* writer() const { return _writer; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1143 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
1144 JNILocalsDumper(DumpWriter* writer, u4 thread_serial_num) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1145 _writer = writer;
a61af66fc99e Initial load
duke
parents:
diff changeset
1146 _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
1147 _frame_num = -1; // default - empty stack
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1148 }
396
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1149 void set_frame_number(int n) { _frame_num = n; }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1150 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
1151 void do_oop(narrowOop* obj_p) { ShouldNotReachHere(); }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1152 };
a61af66fc99e Initial load
duke
parents:
diff changeset
1153
a61af66fc99e Initial load
duke
parents:
diff changeset
1154
a61af66fc99e Initial load
duke
parents:
diff changeset
1155 void JNILocalsDumper::do_oop(oop* obj_p) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1156 // ignore null or deleted handles
a61af66fc99e Initial load
duke
parents:
diff changeset
1157 oop o = *obj_p;
a61af66fc99e Initial load
duke
parents:
diff changeset
1158 if (o != NULL && o != JNIHandles::deleted_handle()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1159 writer()->write_u1(HPROF_GC_ROOT_JNI_LOCAL);
a61af66fc99e Initial load
duke
parents:
diff changeset
1160 writer()->write_objectID(o);
a61af66fc99e Initial load
duke
parents:
diff changeset
1161 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
1162 writer()->write_u4((u4)_frame_num);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1163 }
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 // Support class used to generate HPROF_GC_ROOT_JNI_GLOBAL records
a61af66fc99e Initial load
duke
parents:
diff changeset
1168
a61af66fc99e Initial load
duke
parents:
diff changeset
1169 class JNIGlobalsDumper : public OopClosure {
a61af66fc99e Initial load
duke
parents:
diff changeset
1170 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
1171 DumpWriter* _writer;
a61af66fc99e Initial load
duke
parents:
diff changeset
1172 DumpWriter* writer() const { return _writer; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1173
a61af66fc99e Initial load
duke
parents:
diff changeset
1174 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
1175 JNIGlobalsDumper(DumpWriter* writer) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1176 _writer = writer;
a61af66fc99e Initial load
duke
parents:
diff changeset
1177 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1178 void do_oop(oop* obj_p);
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 29
diff changeset
1179 void do_oop(narrowOop* obj_p) { ShouldNotReachHere(); }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1180 };
a61af66fc99e Initial load
duke
parents:
diff changeset
1181
a61af66fc99e Initial load
duke
parents:
diff changeset
1182 void JNIGlobalsDumper::do_oop(oop* obj_p) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1183 oop o = *obj_p;
a61af66fc99e Initial load
duke
parents:
diff changeset
1184
a61af66fc99e Initial load
duke
parents:
diff changeset
1185 // ignore these
a61af66fc99e Initial load
duke
parents:
diff changeset
1186 if (o == NULL || o == JNIHandles::deleted_handle()) return;
a61af66fc99e Initial load
duke
parents:
diff changeset
1187
a61af66fc99e Initial load
duke
parents:
diff changeset
1188 // we ignore global ref to symbols and other internal objects
a61af66fc99e Initial load
duke
parents:
diff changeset
1189 if (o->is_instance() || o->is_objArray() || o->is_typeArray()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1190 writer()->write_u1(HPROF_GC_ROOT_JNI_GLOBAL);
a61af66fc99e Initial load
duke
parents:
diff changeset
1191 writer()->write_objectID(o);
a61af66fc99e Initial load
duke
parents:
diff changeset
1192 writer()->write_objectID((oopDesc*)obj_p); // global ref ID
a61af66fc99e Initial load
duke
parents:
diff changeset
1193 }
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 // Support class used to generate HPROF_GC_ROOT_MONITOR_USED records
a61af66fc99e Initial load
duke
parents:
diff changeset
1198
a61af66fc99e Initial load
duke
parents:
diff changeset
1199 class MonitorUsedDumper : public OopClosure {
a61af66fc99e Initial load
duke
parents:
diff changeset
1200 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
1201 DumpWriter* _writer;
a61af66fc99e Initial load
duke
parents:
diff changeset
1202 DumpWriter* writer() const { return _writer; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1203 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
1204 MonitorUsedDumper(DumpWriter* writer) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1205 _writer = writer;
a61af66fc99e Initial load
duke
parents:
diff changeset
1206 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1207 void do_oop(oop* obj_p) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1208 writer()->write_u1(HPROF_GC_ROOT_MONITOR_USED);
a61af66fc99e Initial load
duke
parents:
diff changeset
1209 writer()->write_objectID(*obj_p);
a61af66fc99e Initial load
duke
parents:
diff changeset
1210 }
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 29
diff changeset
1211 void do_oop(narrowOop* obj_p) { ShouldNotReachHere(); }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1212 };
a61af66fc99e Initial load
duke
parents:
diff changeset
1213
a61af66fc99e Initial load
duke
parents:
diff changeset
1214
a61af66fc99e Initial load
duke
parents:
diff changeset
1215 // Support class used to generate HPROF_GC_ROOT_STICKY_CLASS records
a61af66fc99e Initial load
duke
parents:
diff changeset
1216
a61af66fc99e Initial load
duke
parents:
diff changeset
1217 class StickyClassDumper : public OopClosure {
a61af66fc99e Initial load
duke
parents:
diff changeset
1218 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
1219 DumpWriter* _writer;
a61af66fc99e Initial load
duke
parents:
diff changeset
1220 DumpWriter* writer() const { return _writer; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1221 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
1222 StickyClassDumper(DumpWriter* writer) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1223 _writer = writer;
a61af66fc99e Initial load
duke
parents:
diff changeset
1224 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1225 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
1226 void do_oop(narrowOop* obj_p) { ShouldNotReachHere(); }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1227 };
a61af66fc99e Initial load
duke
parents:
diff changeset
1228
a61af66fc99e Initial load
duke
parents:
diff changeset
1229 void StickyClassDumper::do_oop(oop* obj_p) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1230 if (*obj_p != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1231 oop o = *obj_p;
a61af66fc99e Initial load
duke
parents:
diff changeset
1232 if (o->is_klass()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1233 klassOop k = klassOop(o);
a61af66fc99e Initial load
duke
parents:
diff changeset
1234 if (Klass::cast(k)->oop_is_instance()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1235 instanceKlass* ik = instanceKlass::cast(k);
a61af66fc99e Initial load
duke
parents:
diff changeset
1236 writer()->write_u1(HPROF_GC_ROOT_STICKY_CLASS);
a61af66fc99e Initial load
duke
parents:
diff changeset
1237 writer()->write_classID(ik);
a61af66fc99e Initial load
duke
parents:
diff changeset
1238 }
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 class VM_HeapDumper;
a61af66fc99e Initial load
duke
parents:
diff changeset
1245
a61af66fc99e Initial load
duke
parents:
diff changeset
1246 // Support class using when iterating over the heap.
a61af66fc99e Initial load
duke
parents:
diff changeset
1247
a61af66fc99e Initial load
duke
parents:
diff changeset
1248 class HeapObjectDumper : public ObjectClosure {
a61af66fc99e Initial load
duke
parents:
diff changeset
1249 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
1250 VM_HeapDumper* _dumper;
a61af66fc99e Initial load
duke
parents:
diff changeset
1251 DumpWriter* _writer;
a61af66fc99e Initial load
duke
parents:
diff changeset
1252
a61af66fc99e Initial load
duke
parents:
diff changeset
1253 VM_HeapDumper* dumper() { return _dumper; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1254 DumpWriter* writer() { return _writer; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1255
a61af66fc99e Initial load
duke
parents:
diff changeset
1256 // used to indicate that a record has been writen
a61af66fc99e Initial load
duke
parents:
diff changeset
1257 void mark_end_of_record();
a61af66fc99e Initial load
duke
parents:
diff changeset
1258
a61af66fc99e Initial load
duke
parents:
diff changeset
1259 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
1260 HeapObjectDumper(VM_HeapDumper* dumper, DumpWriter* writer) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1261 _dumper = dumper;
a61af66fc99e Initial load
duke
parents:
diff changeset
1262 _writer = writer;
a61af66fc99e Initial load
duke
parents:
diff changeset
1263 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1264
a61af66fc99e Initial load
duke
parents:
diff changeset
1265 // called for each object in the heap
a61af66fc99e Initial load
duke
parents:
diff changeset
1266 void do_object(oop o);
a61af66fc99e Initial load
duke
parents:
diff changeset
1267 };
a61af66fc99e Initial load
duke
parents:
diff changeset
1268
a61af66fc99e Initial load
duke
parents:
diff changeset
1269 void HeapObjectDumper::do_object(oop o) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1270 // hide the sentinel for deleted handles
a61af66fc99e Initial load
duke
parents:
diff changeset
1271 if (o == JNIHandles::deleted_handle()) return;
a61af66fc99e Initial load
duke
parents:
diff changeset
1272
a61af66fc99e Initial load
duke
parents:
diff changeset
1273 // ignore KlassKlass objects
a61af66fc99e Initial load
duke
parents:
diff changeset
1274 if (o->is_klass()) return;
a61af66fc99e Initial load
duke
parents:
diff changeset
1275
a61af66fc99e Initial load
duke
parents:
diff changeset
1276 // skip classes as these emitted as HPROF_GC_CLASS_DUMP records
1142
4ce7240d622c 6914300: ciEnv should export all well known classes
never
parents: 1046
diff changeset
1277 if (o->klass() == SystemDictionary::Class_klass()) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1278 if (!java_lang_Class::is_primitive(o)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1279 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
1280 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1281 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1282
a61af66fc99e Initial load
duke
parents:
diff changeset
1283 // create a HPROF_GC_INSTANCE record for each object
a61af66fc99e Initial load
duke
parents:
diff changeset
1284 if (o->is_instance()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1285 DumperSupport::dump_instance(writer(), o);
a61af66fc99e Initial load
duke
parents:
diff changeset
1286 mark_end_of_record();
a61af66fc99e Initial load
duke
parents:
diff changeset
1287 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1288 // create a HPROF_GC_OBJ_ARRAY_DUMP record for each object array
a61af66fc99e Initial load
duke
parents:
diff changeset
1289 if (o->is_objArray()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1290 DumperSupport::dump_object_array(writer(), objArrayOop(o));
a61af66fc99e Initial load
duke
parents:
diff changeset
1291 mark_end_of_record();
a61af66fc99e Initial load
duke
parents:
diff changeset
1292 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1293 // create a HPROF_GC_PRIM_ARRAY_DUMP record for each type array
a61af66fc99e Initial load
duke
parents:
diff changeset
1294 if (o->is_typeArray()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1295 DumperSupport::dump_prim_array(writer(), typeArrayOop(o));
a61af66fc99e Initial load
duke
parents:
diff changeset
1296 mark_end_of_record();
a61af66fc99e Initial load
duke
parents:
diff changeset
1297 }
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 // The VM operation that performs the heap dump
a61af66fc99e Initial load
duke
parents:
diff changeset
1303 class VM_HeapDumper : public VM_GC_Operation {
a61af66fc99e Initial load
duke
parents:
diff changeset
1304 private:
615
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1305 static VM_HeapDumper* _global_dumper;
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1306 static DumpWriter* _global_writer;
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1307 DumpWriter* _local_writer;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1308 bool _gc_before_heap_dump;
a61af66fc99e Initial load
duke
parents:
diff changeset
1309 bool _is_segmented_dump;
a61af66fc99e Initial load
duke
parents:
diff changeset
1310 jlong _dump_start;
396
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1311 GrowableArray<Klass*>* _klass_map;
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1312 ThreadStackTrace** _stack_traces;
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1313 int _num_threads;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1314
615
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1315 // accessors and setters
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1316 static VM_HeapDumper* dumper() { assert(_global_dumper != NULL, "Error"); return _global_dumper; }
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1317 static DumpWriter* writer() { assert(_global_writer != NULL, "Error"); return _global_writer; }
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1318 void set_global_dumper() {
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1319 assert(_global_dumper == NULL, "Error");
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1320 _global_dumper = this;
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1321 }
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1322 void set_global_writer() {
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1323 assert(_global_writer == NULL, "Error");
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1324 _global_writer = _local_writer;
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1325 }
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1326 void clear_global_dumper() { _global_dumper = NULL; }
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1327 void clear_global_writer() { _global_writer = NULL; }
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1328
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1329 bool is_segmented_dump() const { return _is_segmented_dump; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1330 void set_segmented_dump() { _is_segmented_dump = true; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1331 jlong dump_start() const { return _dump_start; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1332 void set_dump_start(jlong pos);
a61af66fc99e Initial load
duke
parents:
diff changeset
1333
a61af66fc99e Initial load
duke
parents:
diff changeset
1334 bool skip_operation() const;
a61af66fc99e Initial load
duke
parents:
diff changeset
1335
a61af66fc99e Initial load
duke
parents:
diff changeset
1336 // writes a HPROF_LOAD_CLASS record
a61af66fc99e Initial load
duke
parents:
diff changeset
1337 static void do_load_class(klassOop k);
a61af66fc99e Initial load
duke
parents:
diff changeset
1338
a61af66fc99e Initial load
duke
parents:
diff changeset
1339 // writes a HPROF_GC_CLASS_DUMP record for the given class
a61af66fc99e Initial load
duke
parents:
diff changeset
1340 // (and each array class too)
a61af66fc99e Initial load
duke
parents:
diff changeset
1341 static void do_class_dump(klassOop k);
a61af66fc99e Initial load
duke
parents:
diff changeset
1342
a61af66fc99e Initial load
duke
parents:
diff changeset
1343 // writes a HPROF_GC_CLASS_DUMP records for a given basic type
a61af66fc99e Initial load
duke
parents:
diff changeset
1344 // array (and each multi-dimensional array too)
a61af66fc99e Initial load
duke
parents:
diff changeset
1345 static void do_basic_type_array_class_dump(klassOop k);
a61af66fc99e Initial load
duke
parents:
diff changeset
1346
a61af66fc99e Initial load
duke
parents:
diff changeset
1347 // 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
1348 int do_thread(JavaThread* thread, u4 thread_serial_num);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1349 void do_threads();
a61af66fc99e Initial load
duke
parents:
diff changeset
1350
396
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1351 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
1352 _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
1353 }
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1354
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1355 // 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
1356 void dump_stack_traces();
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1357
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1358 // writes a HPROF_HEAP_DUMP or HPROF_HEAP_DUMP_SEGMENT record
a61af66fc99e Initial load
duke
parents:
diff changeset
1359 void write_dump_header();
a61af66fc99e Initial load
duke
parents:
diff changeset
1360
a61af66fc99e Initial load
duke
parents:
diff changeset
1361 // fixes up the length of the current dump record
a61af66fc99e Initial load
duke
parents:
diff changeset
1362 void write_current_dump_record_length();
a61af66fc99e Initial load
duke
parents:
diff changeset
1363
a61af66fc99e Initial load
duke
parents:
diff changeset
1364 // fixes up the current dump record )and writes HPROF_HEAP_DUMP_END
a61af66fc99e Initial load
duke
parents:
diff changeset
1365 // record in the case of a segmented heap dump)
a61af66fc99e Initial load
duke
parents:
diff changeset
1366 void end_of_dump();
a61af66fc99e Initial load
duke
parents:
diff changeset
1367
a61af66fc99e Initial load
duke
parents:
diff changeset
1368 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
1369 VM_HeapDumper(DumpWriter* writer, bool gc_before_heap_dump) :
a61af66fc99e Initial load
duke
parents:
diff changeset
1370 VM_GC_Operation(0 /* total collections, dummy, ignored */,
a61af66fc99e Initial load
duke
parents:
diff changeset
1371 0 /* total full collections, dummy, ignored */,
a61af66fc99e Initial load
duke
parents:
diff changeset
1372 gc_before_heap_dump) {
615
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1373 _local_writer = writer;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1374 _gc_before_heap_dump = gc_before_heap_dump;
a61af66fc99e Initial load
duke
parents:
diff changeset
1375 _is_segmented_dump = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1376 _dump_start = (jlong)-1;
396
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1377 _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
1378 _stack_traces = NULL;
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1379 _num_threads = 0;
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1380 }
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1381 ~VM_HeapDumper() {
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1382 if (_stack_traces != NULL) {
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1383 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
1384 delete _stack_traces[i];
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1385 }
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1386 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
1387 }
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1388 delete _klass_map;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1389 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1390
a61af66fc99e Initial load
duke
parents:
diff changeset
1391 VMOp_Type type() const { return VMOp_HeapDumper; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1392 // used to mark sub-record boundary
a61af66fc99e Initial load
duke
parents:
diff changeset
1393 void check_segment_length();
a61af66fc99e Initial load
duke
parents:
diff changeset
1394 void doit();
a61af66fc99e Initial load
duke
parents:
diff changeset
1395 };
a61af66fc99e Initial load
duke
parents:
diff changeset
1396
615
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1397 VM_HeapDumper* VM_HeapDumper::_global_dumper = NULL;
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1398 DumpWriter* VM_HeapDumper::_global_writer = NULL;
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1399
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1400 bool VM_HeapDumper::skip_operation() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
1401 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1402 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1403
a61af66fc99e Initial load
duke
parents:
diff changeset
1404 // sets the dump starting position
a61af66fc99e Initial load
duke
parents:
diff changeset
1405 void VM_HeapDumper::set_dump_start(jlong pos) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1406 _dump_start = pos;
a61af66fc99e Initial load
duke
parents:
diff changeset
1407 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1408
a61af66fc99e Initial load
duke
parents:
diff changeset
1409 // writes a HPROF_HEAP_DUMP or HPROF_HEAP_DUMP_SEGMENT record
a61af66fc99e Initial load
duke
parents:
diff changeset
1410 void VM_HeapDumper::write_dump_header() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1411 if (writer()->is_open()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1412 if (is_segmented_dump()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1413 writer()->write_u1(HPROF_HEAP_DUMP_SEGMENT);
a61af66fc99e Initial load
duke
parents:
diff changeset
1414 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1415 writer()->write_u1(HPROF_HEAP_DUMP);
a61af66fc99e Initial load
duke
parents:
diff changeset
1416 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1417 writer()->write_u4(0); // current ticks
a61af66fc99e Initial load
duke
parents:
diff changeset
1418
a61af66fc99e Initial load
duke
parents:
diff changeset
1419 // record the starting position for the dump (its length will be fixed up later)
a61af66fc99e Initial load
duke
parents:
diff changeset
1420 set_dump_start(writer()->current_offset());
a61af66fc99e Initial load
duke
parents:
diff changeset
1421 writer()->write_u4(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1422 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1423 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1424
a61af66fc99e Initial load
duke
parents:
diff changeset
1425 // fixes up the length of the current dump record
a61af66fc99e Initial load
duke
parents:
diff changeset
1426 void VM_HeapDumper::write_current_dump_record_length() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1427 if (writer()->is_open()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1428 assert(dump_start() >= 0, "no dump start recorded");
a61af66fc99e Initial load
duke
parents:
diff changeset
1429
a61af66fc99e Initial load
duke
parents:
diff changeset
1430 // calculate the size of the dump record
a61af66fc99e Initial load
duke
parents:
diff changeset
1431 jlong dump_end = writer()->current_offset();
a61af66fc99e Initial load
duke
parents:
diff changeset
1432 jlong dump_len = (dump_end - dump_start() - 4);
a61af66fc99e Initial load
duke
parents:
diff changeset
1433
a61af66fc99e Initial load
duke
parents:
diff changeset
1434 // record length must fit in a u4
a61af66fc99e Initial load
duke
parents:
diff changeset
1435 if (dump_len > (jlong)(4L*(jlong)G)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1436 warning("record is too large");
a61af66fc99e Initial load
duke
parents:
diff changeset
1437 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1438
a61af66fc99e Initial load
duke
parents:
diff changeset
1439 // seek to the dump start and fix-up the length
a61af66fc99e Initial load
duke
parents:
diff changeset
1440 writer()->seek_to_offset(dump_start());
a61af66fc99e Initial load
duke
parents:
diff changeset
1441 writer()->write_u4((u4)dump_len);
a61af66fc99e Initial load
duke
parents:
diff changeset
1442
a61af66fc99e Initial load
duke
parents:
diff changeset
1443 // adjust the total size written to keep the bytes written correct.
a61af66fc99e Initial load
duke
parents:
diff changeset
1444 writer()->adjust_bytes_written(-((long) sizeof(u4)));
a61af66fc99e Initial load
duke
parents:
diff changeset
1445
a61af66fc99e Initial load
duke
parents:
diff changeset
1446 // seek to dump end so we can continue
a61af66fc99e Initial load
duke
parents:
diff changeset
1447 writer()->seek_to_offset(dump_end);
a61af66fc99e Initial load
duke
parents:
diff changeset
1448
a61af66fc99e Initial load
duke
parents:
diff changeset
1449 // no current dump record
a61af66fc99e Initial load
duke
parents:
diff changeset
1450 set_dump_start((jlong)-1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1451 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1452 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1453
a61af66fc99e Initial load
duke
parents:
diff changeset
1454 // used on a sub-record boundary to check if we need to start a
a61af66fc99e Initial load
duke
parents:
diff changeset
1455 // new segment.
a61af66fc99e Initial load
duke
parents:
diff changeset
1456 void VM_HeapDumper::check_segment_length() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1457 if (writer()->is_open()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1458 if (is_segmented_dump()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1459 // don't use current_offset that would be too expensive on a per record basis
a61af66fc99e Initial load
duke
parents:
diff changeset
1460 jlong dump_end = writer()->bytes_written() + writer()->bytes_unwritten();
a61af66fc99e Initial load
duke
parents:
diff changeset
1461 assert(dump_end == writer()->current_offset(), "checking");
a61af66fc99e Initial load
duke
parents:
diff changeset
1462 jlong dump_len = (dump_end - dump_start() - 4);
a61af66fc99e Initial load
duke
parents:
diff changeset
1463 assert(dump_len >= 0 && dump_len <= max_juint, "bad dump length");
a61af66fc99e Initial load
duke
parents:
diff changeset
1464
a61af66fc99e Initial load
duke
parents:
diff changeset
1465 if (dump_len > (jlong)HeapDumpSegmentSize) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1466 write_current_dump_record_length();
a61af66fc99e Initial load
duke
parents:
diff changeset
1467 write_dump_header();
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
a61af66fc99e Initial load
duke
parents:
diff changeset
1473 // fixes up the current dump record )and writes HPROF_HEAP_DUMP_END
a61af66fc99e Initial load
duke
parents:
diff changeset
1474 // record in the case of a segmented heap dump)
a61af66fc99e Initial load
duke
parents:
diff changeset
1475 void VM_HeapDumper::end_of_dump() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1476 if (writer()->is_open()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1477 write_current_dump_record_length();
a61af66fc99e Initial load
duke
parents:
diff changeset
1478
a61af66fc99e Initial load
duke
parents:
diff changeset
1479 // for segmented dump we write the end record
a61af66fc99e Initial load
duke
parents:
diff changeset
1480 if (is_segmented_dump()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1481 writer()->write_u1(HPROF_HEAP_DUMP_END);
a61af66fc99e Initial load
duke
parents:
diff changeset
1482 writer()->write_u4(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1483 writer()->write_u4(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1484 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1485 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1486 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1487
a61af66fc99e Initial load
duke
parents:
diff changeset
1488 // marks sub-record boundary
a61af66fc99e Initial load
duke
parents:
diff changeset
1489 void HeapObjectDumper::mark_end_of_record() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1490 dumper()->check_segment_length();
a61af66fc99e Initial load
duke
parents:
diff changeset
1491 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1492
a61af66fc99e Initial load
duke
parents:
diff changeset
1493 // writes a HPROF_LOAD_CLASS record for the class (and each of its
a61af66fc99e Initial load
duke
parents:
diff changeset
1494 // array classes)
a61af66fc99e Initial load
duke
parents:
diff changeset
1495 void VM_HeapDumper::do_load_class(klassOop k) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1496 static u4 class_serial_num = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
1497
a61af66fc99e Initial load
duke
parents:
diff changeset
1498 // len of HPROF_LOAD_CLASS record
a61af66fc99e Initial load
duke
parents:
diff changeset
1499 u4 remaining = 2*oopSize + 2*sizeof(u4);
a61af66fc99e Initial load
duke
parents:
diff changeset
1500
a61af66fc99e Initial load
duke
parents:
diff changeset
1501 // write a HPROF_LOAD_CLASS for the class and each array class
a61af66fc99e Initial load
duke
parents:
diff changeset
1502 do {
615
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1503 DumperSupport::write_header(writer(), HPROF_LOAD_CLASS, remaining);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1504
a61af66fc99e Initial load
duke
parents:
diff changeset
1505 // class serial number is just a number
615
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1506 writer()->write_u4(++class_serial_num);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1507
a61af66fc99e Initial load
duke
parents:
diff changeset
1508 // class ID
a61af66fc99e Initial load
duke
parents:
diff changeset
1509 Klass* klass = Klass::cast(k);
615
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1510 writer()->write_classID(klass);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1511
396
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1512 // add the klassOop and class serial number pair
615
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1513 dumper()->add_class_serial_number(klass, class_serial_num);
396
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1514
615
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1515 writer()->write_u4(STACK_TRACE_ID);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1516
a61af66fc99e Initial load
duke
parents:
diff changeset
1517 // class name ID
a61af66fc99e Initial load
duke
parents:
diff changeset
1518 symbolOop name = klass->name();
615
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1519 writer()->write_objectID(name);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1520
a61af66fc99e Initial load
duke
parents:
diff changeset
1521 // write a LOAD_CLASS record for the array type (if it exists)
a61af66fc99e Initial load
duke
parents:
diff changeset
1522 k = klass->array_klass_or_null();
a61af66fc99e Initial load
duke
parents:
diff changeset
1523 } while (k != NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
1524 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1525
a61af66fc99e Initial load
duke
parents:
diff changeset
1526 // writes a HPROF_GC_CLASS_DUMP record for the given class
a61af66fc99e Initial load
duke
parents:
diff changeset
1527 void VM_HeapDumper::do_class_dump(klassOop k) {
615
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1528 DumperSupport::dump_class_and_array_classes(writer(), k);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1529 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1530
a61af66fc99e Initial load
duke
parents:
diff changeset
1531 // writes a HPROF_GC_CLASS_DUMP records for a given basic type
a61af66fc99e Initial load
duke
parents:
diff changeset
1532 // array (and each multi-dimensional array too)
a61af66fc99e Initial load
duke
parents:
diff changeset
1533 void VM_HeapDumper::do_basic_type_array_class_dump(klassOop k) {
615
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1534 DumperSupport::dump_basic_type_array_class(writer(), k);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1535 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1536
a61af66fc99e Initial load
duke
parents:
diff changeset
1537 // Walk the stack of the given thread.
a61af66fc99e Initial load
duke
parents:
diff changeset
1538 // Dumps a HPROF_GC_ROOT_JAVA_FRAME record for each local
a61af66fc99e Initial load
duke
parents:
diff changeset
1539 // 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
1540 //
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1541 // 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
1542 int VM_HeapDumper::do_thread(JavaThread* java_thread, u4 thread_serial_num) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1543 JNILocalsDumper blk(writer(), thread_serial_num);
a61af66fc99e Initial load
duke
parents:
diff changeset
1544
a61af66fc99e Initial load
duke
parents:
diff changeset
1545 oop threadObj = java_thread->threadObj();
a61af66fc99e Initial load
duke
parents:
diff changeset
1546 assert(threadObj != NULL, "sanity check");
a61af66fc99e Initial load
duke
parents:
diff changeset
1547
396
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1548 int stack_depth = 0;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1549 if (java_thread->has_last_Java_frame()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1550
a61af66fc99e Initial load
duke
parents:
diff changeset
1551 // vframes are resource allocated
a61af66fc99e Initial load
duke
parents:
diff changeset
1552 Thread* current_thread = Thread::current();
a61af66fc99e Initial load
duke
parents:
diff changeset
1553 ResourceMark rm(current_thread);
a61af66fc99e Initial load
duke
parents:
diff changeset
1554 HandleMark hm(current_thread);
a61af66fc99e Initial load
duke
parents:
diff changeset
1555
a61af66fc99e Initial load
duke
parents:
diff changeset
1556 RegisterMap reg_map(java_thread);
a61af66fc99e Initial load
duke
parents:
diff changeset
1557 frame f = java_thread->last_frame();
a61af66fc99e Initial load
duke
parents:
diff changeset
1558 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
1559 frame* last_entry_frame = NULL;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1560
a61af66fc99e Initial load
duke
parents:
diff changeset
1561 while (vf != NULL) {
396
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1562 blk.set_frame_number(stack_depth);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1563 if (vf->is_java_frame()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1564
a61af66fc99e Initial load
duke
parents:
diff changeset
1565 // java frame (interpreted, compiled, ...)
a61af66fc99e Initial load
duke
parents:
diff changeset
1566 javaVFrame *jvf = javaVFrame::cast(vf);
a61af66fc99e Initial load
duke
parents:
diff changeset
1567 if (!(jvf->method()->is_native())) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1568 StackValueCollection* locals = jvf->locals();
a61af66fc99e Initial load
duke
parents:
diff changeset
1569 for (int slot=0; slot<locals->size(); slot++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1570 if (locals->at(slot)->type() == T_OBJECT) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1571 oop o = locals->obj_at(slot)();
a61af66fc99e Initial load
duke
parents:
diff changeset
1572
a61af66fc99e Initial load
duke
parents:
diff changeset
1573 if (o != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1574 writer()->write_u1(HPROF_GC_ROOT_JAVA_FRAME);
a61af66fc99e Initial load
duke
parents:
diff changeset
1575 writer()->write_objectID(o);
a61af66fc99e Initial load
duke
parents:
diff changeset
1576 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
1577 writer()->write_u4((u4) stack_depth);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1578 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1579 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1580 }
396
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1581 } else {
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1582 // native frame
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1583 if (stack_depth == 0) {
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1584 // 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
1585 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
1586 } else {
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1587 if (last_entry_frame != NULL) {
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1588 // 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
1589 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
1590 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
1591 }
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1592 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1593 }
396
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1594 // increment only for Java frames
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1595 stack_depth++;
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1596 last_entry_frame = NULL;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1597
396
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1598 } else {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1599 // 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
1600 // as roots when we find the corresponding native javaVFrame
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1601 frame* fr = vf->frame_pointer();
a61af66fc99e Initial load
duke
parents:
diff changeset
1602 assert(fr != NULL, "sanity check");
a61af66fc99e Initial load
duke
parents:
diff changeset
1603 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
1604 last_entry_frame = fr;
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 vf = vf->sender();
a61af66fc99e Initial load
duke
parents:
diff changeset
1608 }
396
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1609 } else {
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1610 // 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
1611 java_thread->active_handles()->oops_do(&blk);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1612 }
396
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1613 return stack_depth;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1614 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1615
a61af66fc99e Initial load
duke
parents:
diff changeset
1616
a61af66fc99e Initial load
duke
parents:
diff changeset
1617 // write a HPROF_GC_ROOT_THREAD_OBJ record for each java thread. Then walk
a61af66fc99e Initial load
duke
parents:
diff changeset
1618 // the stack so that locals and JNI locals are dumped.
a61af66fc99e Initial load
duke
parents:
diff changeset
1619 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
1620 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
1621 JavaThread* thread = _stack_traces[i]->thread();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1622 oop threadObj = thread->threadObj();
396
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1623 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
1624 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
1625 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
1626 writer()->write_objectID(threadObj);
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1627 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
1628 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
1629 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
1630 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
1631 "total number of Java frames not matched");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1632 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1633 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1634
a61af66fc99e Initial load
duke
parents:
diff changeset
1635
a61af66fc99e Initial load
duke
parents:
diff changeset
1636 // The VM operation that dumps the heap. The dump consists of the following
a61af66fc99e Initial load
duke
parents:
diff changeset
1637 // records:
a61af66fc99e Initial load
duke
parents:
diff changeset
1638 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1639 // HPROF_HEADER
a61af66fc99e Initial load
duke
parents:
diff changeset
1640 // [HPROF_UTF8]*
a61af66fc99e Initial load
duke
parents:
diff changeset
1641 // [HPROF_LOAD_CLASS]*
396
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1642 // [[HPROF_FRAME]*|HPROF_TRACE]*
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1643 // [HPROF_GC_CLASS_DUMP]*
a61af66fc99e Initial load
duke
parents:
diff changeset
1644 // HPROF_HEAP_DUMP
a61af66fc99e Initial load
duke
parents:
diff changeset
1645 //
396
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1646 // 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
1647 // 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
1648 // 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
1649 // unknown object alloc site.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1650 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1651 // The HPROF_HEAP_DUMP record has a length following by sub-records. To allow
a61af66fc99e Initial load
duke
parents:
diff changeset
1652 // the heap dump be generated in a single pass we remember the position of
a61af66fc99e Initial load
duke
parents:
diff changeset
1653 // the dump length and fix it up after all sub-records have been written.
a61af66fc99e Initial load
duke
parents:
diff changeset
1654 // To generate the sub-records we iterate over the heap, writing
a61af66fc99e Initial load
duke
parents:
diff changeset
1655 // HPROF_GC_INSTANCE_DUMP, HPROF_GC_OBJ_ARRAY_DUMP, and HPROF_GC_PRIM_ARRAY_DUMP
a61af66fc99e Initial load
duke
parents:
diff changeset
1656 // records as we go. Once that is done we write records for some of the GC
a61af66fc99e Initial load
duke
parents:
diff changeset
1657 // roots.
a61af66fc99e Initial load
duke
parents:
diff changeset
1658
a61af66fc99e Initial load
duke
parents:
diff changeset
1659 void VM_HeapDumper::doit() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1660
a61af66fc99e Initial load
duke
parents:
diff changeset
1661 HandleMark hm;
a61af66fc99e Initial load
duke
parents:
diff changeset
1662 CollectedHeap* ch = Universe::heap();
a61af66fc99e Initial load
duke
parents:
diff changeset
1663 if (_gc_before_heap_dump) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1664 ch->collect_as_vm_thread(GCCause::_heap_dump);
a61af66fc99e Initial load
duke
parents:
diff changeset
1665 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1666 // make the heap parsable (no need to retire TLABs)
a61af66fc99e Initial load
duke
parents:
diff changeset
1667 ch->ensure_parsability(false);
a61af66fc99e Initial load
duke
parents:
diff changeset
1668 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1669
615
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1670 // At this point we should be the only dumper active, so
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1671 // the following should be safe.
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1672 set_global_dumper();
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1673 set_global_writer();
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1674
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1675 // 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
1676 size_t used = ch->used();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1677 const char* header;
a61af66fc99e Initial load
duke
parents:
diff changeset
1678 if (used > (size_t)SegmentedHeapDumpThreshold) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1679 set_segmented_dump();
a61af66fc99e Initial load
duke
parents:
diff changeset
1680 header = "JAVA PROFILE 1.0.2";
a61af66fc99e Initial load
duke
parents:
diff changeset
1681 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1682 header = "JAVA PROFILE 1.0.1";
a61af66fc99e Initial load
duke
parents:
diff changeset
1683 }
615
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1684
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1685 // header is few bytes long - no chance to overflow int
a61af66fc99e Initial load
duke
parents:
diff changeset
1686 writer()->write_raw((void*)header, (int)strlen(header));
a61af66fc99e Initial load
duke
parents:
diff changeset
1687 writer()->write_u1(0); // terminator
a61af66fc99e Initial load
duke
parents:
diff changeset
1688 writer()->write_u4(oopSize);
a61af66fc99e Initial load
duke
parents:
diff changeset
1689 writer()->write_u8(os::javaTimeMillis());
a61af66fc99e Initial load
duke
parents:
diff changeset
1690
a61af66fc99e Initial load
duke
parents:
diff changeset
1691 // HPROF_UTF8 records
a61af66fc99e Initial load
duke
parents:
diff changeset
1692 SymbolTableDumper sym_dumper(writer());
a61af66fc99e Initial load
duke
parents:
diff changeset
1693 SymbolTable::oops_do(&sym_dumper);
a61af66fc99e Initial load
duke
parents:
diff changeset
1694
a61af66fc99e Initial load
duke
parents:
diff changeset
1695 // write HPROF_LOAD_CLASS records
a61af66fc99e Initial load
duke
parents:
diff changeset
1696 SystemDictionary::classes_do(&do_load_class);
a61af66fc99e Initial load
duke
parents:
diff changeset
1697 Universe::basic_type_classes_do(&do_load_class);
a61af66fc99e Initial load
duke
parents:
diff changeset
1698
396
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1699 // 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
1700 // 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
1701 dump_stack_traces();
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1702
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1703 // write HPROF_HEAP_DUMP or HPROF_HEAP_DUMP_SEGMENT
a61af66fc99e Initial load
duke
parents:
diff changeset
1704 write_dump_header();
a61af66fc99e Initial load
duke
parents:
diff changeset
1705
a61af66fc99e Initial load
duke
parents:
diff changeset
1706 // Writes HPROF_GC_CLASS_DUMP records
a61af66fc99e Initial load
duke
parents:
diff changeset
1707 SystemDictionary::classes_do(&do_class_dump);
a61af66fc99e Initial load
duke
parents:
diff changeset
1708 Universe::basic_type_classes_do(&do_basic_type_array_class_dump);
a61af66fc99e Initial load
duke
parents:
diff changeset
1709 check_segment_length();
a61af66fc99e Initial load
duke
parents:
diff changeset
1710
a61af66fc99e Initial load
duke
parents:
diff changeset
1711 // writes HPROF_GC_INSTANCE_DUMP records.
a61af66fc99e Initial load
duke
parents:
diff changeset
1712 // After each sub-record is written check_segment_length will be invoked. When
a61af66fc99e Initial load
duke
parents:
diff changeset
1713 // generated a segmented heap dump this allows us to check if the current
a61af66fc99e Initial load
duke
parents:
diff changeset
1714 // segment exceeds a threshold and if so, then a new segment is started.
a61af66fc99e Initial load
duke
parents:
diff changeset
1715 // The HPROF_GC_CLASS_DUMP and HPROF_GC_INSTANCE_DUMP are the vast bulk
a61af66fc99e Initial load
duke
parents:
diff changeset
1716 // of the heap dump.
a61af66fc99e Initial load
duke
parents:
diff changeset
1717 HeapObjectDumper obj_dumper(this, writer());
517
e9be0e04635a 6689653: JMapPerm fails with UseConcMarkSweepIncGC and compressed oops off
jmasa
parents: 396
diff changeset
1718 Universe::heap()->safe_object_iterate(&obj_dumper);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1719
a61af66fc99e Initial load
duke
parents:
diff changeset
1720 // HPROF_GC_ROOT_THREAD_OBJ + frames + jni locals
a61af66fc99e Initial load
duke
parents:
diff changeset
1721 do_threads();
a61af66fc99e Initial load
duke
parents:
diff changeset
1722 check_segment_length();
a61af66fc99e Initial load
duke
parents:
diff changeset
1723
a61af66fc99e Initial load
duke
parents:
diff changeset
1724 // HPROF_GC_ROOT_MONITOR_USED
a61af66fc99e Initial load
duke
parents:
diff changeset
1725 MonitorUsedDumper mon_dumper(writer());
a61af66fc99e Initial load
duke
parents:
diff changeset
1726 ObjectSynchronizer::oops_do(&mon_dumper);
a61af66fc99e Initial load
duke
parents:
diff changeset
1727 check_segment_length();
a61af66fc99e Initial load
duke
parents:
diff changeset
1728
a61af66fc99e Initial load
duke
parents:
diff changeset
1729 // HPROF_GC_ROOT_JNI_GLOBAL
a61af66fc99e Initial load
duke
parents:
diff changeset
1730 JNIGlobalsDumper jni_dumper(writer());
a61af66fc99e Initial load
duke
parents:
diff changeset
1731 JNIHandles::oops_do(&jni_dumper);
a61af66fc99e Initial load
duke
parents:
diff changeset
1732 check_segment_length();
a61af66fc99e Initial load
duke
parents:
diff changeset
1733
a61af66fc99e Initial load
duke
parents:
diff changeset
1734 // HPROF_GC_ROOT_STICKY_CLASS
a61af66fc99e Initial load
duke
parents:
diff changeset
1735 StickyClassDumper class_dumper(writer());
a61af66fc99e Initial load
duke
parents:
diff changeset
1736 SystemDictionary::always_strong_oops_do(&class_dumper);
a61af66fc99e Initial load
duke
parents:
diff changeset
1737
a61af66fc99e Initial load
duke
parents:
diff changeset
1738 // fixes up the length of the dump record. In the case of a segmented
a61af66fc99e Initial load
duke
parents:
diff changeset
1739 // heap then the HPROF_HEAP_DUMP_END record is also written.
a61af66fc99e Initial load
duke
parents:
diff changeset
1740 end_of_dump();
615
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1741
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1742 // Now we clear the global variables, so that a future dumper might run.
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1743 clear_global_dumper();
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1744 clear_global_writer();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1745 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1746
396
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1747 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
1748 // 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
1749 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
1750 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
1751 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
1752 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
1753
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1754 _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
1755 int frame_serial_num = 0;
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1756 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
1757 oop threadObj = thread->threadObj();
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1758 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
1759 // dump thread stack trace
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1760 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
1761 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
1762 _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
1763
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1764 // 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
1765 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
1766 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
1767 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
1768 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
1769 methodOop m = frame->method();
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1770 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
1771 // 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
1772 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
1773 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
1774 }
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1775
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1776 // 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
1777 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
1778 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
1779 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
1780 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
1781 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
1782 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
1783 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
1784 }
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1785 }
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1786 }
4d05b7cb7842 6306922: Dump dump created by +HeapDumpOnOutOfMemoryError should include stack traces for stack roots
mchung
parents: 356
diff changeset
1787 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1788
a61af66fc99e Initial load
duke
parents:
diff changeset
1789 // dump the heap to given path.
a61af66fc99e Initial load
duke
parents:
diff changeset
1790 int HeapDumper::dump(const char* path) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1791 assert(path != NULL && strlen(path) > 0, "path missing");
a61af66fc99e Initial load
duke
parents:
diff changeset
1792
a61af66fc99e Initial load
duke
parents:
diff changeset
1793 // print message in interactive case
a61af66fc99e Initial load
duke
parents:
diff changeset
1794 if (print_to_tty()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1795 tty->print_cr("Dumping heap to %s ...", path);
a61af66fc99e Initial load
duke
parents:
diff changeset
1796 timer()->start();
a61af66fc99e Initial load
duke
parents:
diff changeset
1797 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1798
a61af66fc99e Initial load
duke
parents:
diff changeset
1799 // create the dump writer. If the file can be opened then bail
a61af66fc99e Initial load
duke
parents:
diff changeset
1800 DumpWriter writer(path);
a61af66fc99e Initial load
duke
parents:
diff changeset
1801 if (!writer.is_open()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1802 set_error(writer.error());
a61af66fc99e Initial load
duke
parents:
diff changeset
1803 if (print_to_tty()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1804 tty->print_cr("Unable to create %s: %s", path,
a61af66fc99e Initial load
duke
parents:
diff changeset
1805 (error() != NULL) ? error() : "reason unknown");
a61af66fc99e Initial load
duke
parents:
diff changeset
1806 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1807 return -1;
a61af66fc99e Initial load
duke
parents:
diff changeset
1808 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1809
a61af66fc99e Initial load
duke
parents:
diff changeset
1810 // generate the dump
a61af66fc99e Initial load
duke
parents:
diff changeset
1811 VM_HeapDumper dumper(&writer, _gc_before_heap_dump);
615
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1812 if (Thread::current()->is_VM_thread()) {
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1813 assert(SafepointSynchronize::is_at_safepoint(), "Expected to be called at a safepoint");
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1814 dumper.doit();
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1815 } else {
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1816 VMThread::execute(&dumper);
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1817 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1818
a61af66fc99e Initial load
duke
parents:
diff changeset
1819 // close dump file and record any error that the writer may have encountered
a61af66fc99e Initial load
duke
parents:
diff changeset
1820 writer.close();
a61af66fc99e Initial load
duke
parents:
diff changeset
1821 set_error(writer.error());
a61af66fc99e Initial load
duke
parents:
diff changeset
1822
a61af66fc99e Initial load
duke
parents:
diff changeset
1823 // print message in interactive case
a61af66fc99e Initial load
duke
parents:
diff changeset
1824 if (print_to_tty()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1825 timer()->stop();
a61af66fc99e Initial load
duke
parents:
diff changeset
1826 if (error() == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1827 char msg[256];
a61af66fc99e Initial load
duke
parents:
diff changeset
1828 sprintf(msg, "Heap dump file created [%s bytes in %3.3f secs]",
a61af66fc99e Initial load
duke
parents:
diff changeset
1829 os::jlong_format_specifier(), timer()->seconds());
a61af66fc99e Initial load
duke
parents:
diff changeset
1830 tty->print_cr(msg, writer.bytes_written());
a61af66fc99e Initial load
duke
parents:
diff changeset
1831 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1832 tty->print_cr("Dump file is incomplete: %s", writer.error());
a61af66fc99e Initial load
duke
parents:
diff changeset
1833 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1834 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1835
a61af66fc99e Initial load
duke
parents:
diff changeset
1836 return (writer.error() == NULL) ? 0 : -1;
a61af66fc99e Initial load
duke
parents:
diff changeset
1837 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1838
a61af66fc99e Initial load
duke
parents:
diff changeset
1839 // stop timer (if still active), and free any error string we might be holding
a61af66fc99e Initial load
duke
parents:
diff changeset
1840 HeapDumper::~HeapDumper() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1841 if (timer()->is_active()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1842 timer()->stop();
a61af66fc99e Initial load
duke
parents:
diff changeset
1843 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1844 set_error(NULL);
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 // returns the error string (resource allocated), or NULL
a61af66fc99e Initial load
duke
parents:
diff changeset
1849 char* HeapDumper::error_as_C_string() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
1850 if (error() != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1851 char* str = NEW_RESOURCE_ARRAY(char, strlen(error())+1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1852 strcpy(str, error());
a61af66fc99e Initial load
duke
parents:
diff changeset
1853 return str;
a61af66fc99e Initial load
duke
parents:
diff changeset
1854 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1855 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1856 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1857 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1858
a61af66fc99e Initial load
duke
parents:
diff changeset
1859 // set the error string
a61af66fc99e Initial load
duke
parents:
diff changeset
1860 void HeapDumper::set_error(char* error) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1861 if (_error != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1862 os::free(_error);
a61af66fc99e Initial load
duke
parents:
diff changeset
1863 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1864 if (error == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1865 _error = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1866 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1867 _error = os::strdup(error);
a61af66fc99e Initial load
duke
parents:
diff changeset
1868 assert(_error != NULL, "allocation failure");
a61af66fc99e Initial load
duke
parents:
diff changeset
1869 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1870 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1871
615
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1872 // Called by error reporting by a single Java thread outside of a JVM safepoint,
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1873 // or by heap dumping by the VM thread during a (GC) safepoint. Thus, these various
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1874 // callers are strictly serialized and guaranteed not to interfere below. For more
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1875 // general use, however, this method will need modification to prevent
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1876 // inteference when updating the static variables base_path and dump_file_seq below.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1877 void HeapDumper::dump_heap() {
615
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1878 static char base_path[JVM_MAXPATHLEN] = {'\0'};
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1879 static uint dump_file_seq = 0;
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1880 char my_path[JVM_MAXPATHLEN] = {'\0'};
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1881
a61af66fc99e Initial load
duke
parents:
diff changeset
1882 // The dump file defaults to java_pid<pid>.hprof in the current working
a61af66fc99e Initial load
duke
parents:
diff changeset
1883 // directory. HeapDumpPath=<file> can be used to specify an alternative
a61af66fc99e Initial load
duke
parents:
diff changeset
1884 // dump file name or a directory where dump file is created.
615
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1885 if (dump_file_seq == 0) { // first time in, we initialize base_path
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1886 bool use_default_filename = true;
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1887 if (HeapDumpPath == NULL || HeapDumpPath[0] == '\0') {
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1888 // HeapDumpPath=<file> not specified
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1889 } else {
615
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1890 assert(strlen(HeapDumpPath) < sizeof(base_path), "HeapDumpPath too long");
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1891 strcpy(base_path, HeapDumpPath);
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1892 // check if the path is a directory (must exist)
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1893 DIR* dir = os::opendir(base_path);
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1894 if (dir == NULL) {
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1895 use_default_filename = false;
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1896 } else {
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1897 // HeapDumpPath specified a directory. We append a file separator
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1898 // (if needed).
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1899 os::closedir(dir);
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1900 size_t fs_len = strlen(os::file_separator());
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1901 if (strlen(base_path) >= fs_len) {
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1902 char* end = base_path;
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1903 end += (strlen(base_path) - fs_len);
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1904 if (strcmp(end, os::file_separator()) != 0) {
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1905 assert(strlen(base_path) + strlen(os::file_separator()) < sizeof(base_path),
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1906 "HeapDumpPath too long");
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1907 strcat(base_path, os::file_separator());
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1908 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1909 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1910 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1911 }
615
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1912 // If HeapDumpPath wasn't a file name then we append the default name
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1913 if (use_default_filename) {
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1914 char fn[32];
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1915 sprintf(fn, "java_pid%d", os::current_process_id());
1046
72a6752ac432 6818264: Heap dumper unexpectedly adds .hprof suffix
ysr
parents: 628
diff changeset
1916 assert(strlen(base_path) + strlen(fn) + strlen(".hprof") < sizeof(base_path), "HeapDumpPath too long");
615
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1917 strcat(base_path, fn);
1046
72a6752ac432 6818264: Heap dumper unexpectedly adds .hprof suffix
ysr
parents: 628
diff changeset
1918 strcat(base_path, ".hprof");
615
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1919 }
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1920 assert(strlen(base_path) < sizeof(my_path), "Buffer too small");
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1921 strcpy(my_path, base_path);
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1922 } else {
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1923 // Append a sequence number id for dumps following the first
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1924 char fn[33];
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1925 sprintf(fn, ".%d", dump_file_seq);
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1926 assert(strlen(base_path) + strlen(fn) < sizeof(my_path), "HeapDumpPath too long");
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1927 strcpy(my_path, base_path);
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1928 strcat(my_path, fn);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1929 }
615
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1930 dump_file_seq++; // increment seq number for next time we dump
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1931
a61af66fc99e Initial load
duke
parents:
diff changeset
1932 HeapDumper dumper(false /* no GC before heap dump */,
a61af66fc99e Initial load
duke
parents:
diff changeset
1933 true /* send to tty */);
615
c6c601a0f2d6 6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents: 517
diff changeset
1934 dumper.dump(my_path);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1935 }