annotate src/share/vm/services/heapDumper.cpp @ 10185:d50cc62e94ff

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