Mercurial > hg > graal-jvmci-8
annotate src/share/vm/prims/jvmtiTrace.cpp @ 6972:bd7a7ce2e264
6830717: replay of compilations would help with debugging
Summary: When java process crashed in compiler thread, repeat the compilation process will help finding root cause. This is done with using SA dump application class data and replay data from core dump, then use debug version of jvm to recompile the problematic java method.
Reviewed-by: kvn, twisti, sspitsyn
Contributed-by: yumin.qi@oracle.com
author | minqi |
---|---|
date | Mon, 12 Nov 2012 14:03:53 -0800 |
parents | da91efe96a93 |
children | 070d523b96a7 |
rev | line source |
---|---|
0 | 1 /* |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
1972
diff
changeset
|
2 * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. |
0 | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | |
5 * This code is free software; you can redistribute it and/or modify it | |
6 * under the terms of the GNU General Public License version 2 only, as | |
7 * published by the Free Software Foundation. | |
8 * | |
9 * This code is distributed in the hope that it will be useful, but WITHOUT | |
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
12 * version 2 for more details (a copy is included in the LICENSE file that | |
13 * accompanied this code). | |
14 * | |
15 * You should have received a copy of the GNU General Public License version | |
16 * 2 along with this work; if not, write to the Free Software Foundation, | |
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
18 * | |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
470
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
470
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:
470
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
1972 | 25 #include "precompiled.hpp" |
26 #include "jvmtifiles/jvmtiEnv.hpp" | |
27 #include "prims/jvmtiTrace.hpp" | |
0 | 28 |
29 // | |
30 // class JvmtiTrace | |
31 // | |
32 // Support for JVMTI tracing code | |
33 // | |
34 // ------------ | |
35 // Usage: | |
36 // -XX:TraceJVMTI=DESC,DESC,DESC | |
37 // | |
38 // DESC is DOMAIN ACTION KIND | |
39 // | |
40 // DOMAIN is function name | |
41 // event name | |
42 // "all" (all functions and events) | |
43 // "func" (all functions except boring) | |
44 // "allfunc" (all functions) | |
45 // "event" (all events) | |
46 // "ec" (event controller) | |
47 // | |
48 // ACTION is "+" (add) | |
49 // "-" (remove) | |
50 // | |
51 // KIND is | |
52 // for func | |
53 // "i" (input params) | |
54 // "e" (error returns) | |
55 // "o" (output) | |
56 // for event | |
57 // "t" (event triggered aka posted) | |
58 // "s" (event sent) | |
59 // | |
60 // Example: | |
61 // -XX:TraceJVMTI=ec+,GetCallerFrame+ie,Breakpoint+s | |
62 | |
63 #ifdef JVMTI_TRACE | |
64 | |
65 bool JvmtiTrace::_initialized = false; | |
66 bool JvmtiTrace::_on = false; | |
67 bool JvmtiTrace::_trace_event_controller = false; | |
68 | |
69 void JvmtiTrace::initialize() { | |
70 if (_initialized) { | |
71 return; | |
72 } | |
73 SafeResourceMark rm; | |
74 | |
75 const char *very_end; | |
76 const char *curr; | |
370
885fe0f95828
6744783: HotSpot segfaults if given -XX options with an empty string argument
never
parents:
0
diff
changeset
|
77 if (TraceJVMTI != NULL) { |
0 | 78 curr = TraceJVMTI; |
79 } else { | |
80 curr = ""; // hack in fixed tracing here | |
81 } | |
82 very_end = curr + strlen(curr); | |
83 while (curr < very_end) { | |
84 const char *curr_end = strchr(curr, ','); | |
85 if (curr_end == NULL) { | |
86 curr_end = very_end; | |
87 } | |
88 const char *op_pos = strchr(curr, '+'); | |
89 const char *minus_pos = strchr(curr, '-'); | |
90 if (minus_pos != NULL && (minus_pos < op_pos || op_pos == NULL)) { | |
91 op_pos = minus_pos; | |
92 } | |
93 char op; | |
94 const char *flags = op_pos + 1; | |
95 const char *flags_end = curr_end; | |
96 if (op_pos == NULL || op_pos > curr_end) { | |
97 flags = "ies"; | |
98 flags_end = flags + strlen(flags); | |
99 op_pos = curr_end; | |
100 op = '+'; | |
101 } else { | |
102 op = *op_pos; | |
103 } | |
104 jbyte bits = 0; | |
105 for (; flags < flags_end; ++flags) { | |
106 switch (*flags) { | |
107 case 'i': | |
108 bits |= SHOW_IN; | |
109 break; | |
110 case 'I': | |
111 bits |= SHOW_IN_DETAIL; | |
112 break; | |
113 case 'e': | |
114 bits |= SHOW_ERROR; | |
115 break; | |
116 case 'o': | |
117 bits |= SHOW_OUT; | |
118 break; | |
119 case 'O': | |
120 bits |= SHOW_OUT_DETAIL; | |
121 break; | |
122 case 't': | |
123 bits |= SHOW_EVENT_TRIGGER; | |
124 break; | |
125 case 's': | |
126 bits |= SHOW_EVENT_SENT; | |
127 break; | |
128 default: | |
129 tty->print_cr("Invalid trace flag '%c'", *flags); | |
130 break; | |
131 } | |
132 } | |
133 const int FUNC = 1; | |
134 const int EXCLUDE = 2; | |
135 const int ALL_FUNC = 4; | |
136 const int EVENT = 8; | |
137 const int ALL_EVENT = 16; | |
138 int domain = 0; | |
139 size_t len = op_pos - curr; | |
140 if (op_pos == curr) { | |
141 domain = ALL_FUNC | FUNC | ALL_EVENT | EVENT | EXCLUDE; | |
142 } else if (len==3 && strncmp(curr, "all", 3)==0) { | |
143 domain = ALL_FUNC | FUNC | ALL_EVENT | EVENT; | |
144 } else if (len==7 && strncmp(curr, "allfunc", 7)==0) { | |
145 domain = ALL_FUNC | FUNC; | |
146 } else if (len==4 && strncmp(curr, "func", 4)==0) { | |
147 domain = ALL_FUNC | FUNC | EXCLUDE; | |
148 } else if (len==8 && strncmp(curr, "allevent", 8)==0) { | |
149 domain = ALL_EVENT | EVENT; | |
150 } else if (len==5 && strncmp(curr, "event", 5)==0) { | |
151 domain = ALL_EVENT | EVENT; | |
152 } else if (len==2 && strncmp(curr, "ec", 2)==0) { | |
153 _trace_event_controller = true; | |
154 tty->print_cr("JVMTI Tracing the event controller"); | |
155 } else { | |
156 domain = FUNC | EVENT; // go searching | |
157 } | |
158 | |
159 int exclude_index = 0; | |
160 if (domain & FUNC) { | |
161 if (domain & ALL_FUNC) { | |
162 if (domain & EXCLUDE) { | |
163 tty->print("JVMTI Tracing all significant functions"); | |
164 } else { | |
165 tty->print_cr("JVMTI Tracing all functions"); | |
166 } | |
167 } | |
168 for (int i = 0; i <= _max_function_index; ++i) { | |
169 if (domain & EXCLUDE && i == _exclude_functions[exclude_index]) { | |
170 ++exclude_index; | |
171 } else { | |
172 bool do_op = false; | |
173 if (domain & ALL_FUNC) { | |
174 do_op = true; | |
175 } else { | |
176 const char *fname = function_name(i); | |
177 if (fname != NULL) { | |
178 size_t fnlen = strlen(fname); | |
179 if (len==fnlen && strncmp(curr, fname, fnlen)==0) { | |
180 tty->print_cr("JVMTI Tracing the function: %s", fname); | |
181 do_op = true; | |
182 } | |
183 } | |
184 } | |
185 if (do_op) { | |
186 if (op == '+') { | |
187 _trace_flags[i] |= bits; | |
188 } else { | |
189 _trace_flags[i] &= ~bits; | |
190 } | |
191 _on = true; | |
192 } | |
193 } | |
194 } | |
195 } | |
196 if (domain & EVENT) { | |
197 if (domain & ALL_EVENT) { | |
198 tty->print_cr("JVMTI Tracing all events"); | |
199 } | |
200 for (int i = 0; i <= _max_event_index; ++i) { | |
201 bool do_op = false; | |
202 if (domain & ALL_EVENT) { | |
203 do_op = true; | |
204 } else { | |
205 const char *ename = event_name(i); | |
206 if (ename != NULL) { | |
207 size_t evtlen = strlen(ename); | |
208 if (len==evtlen && strncmp(curr, ename, evtlen)==0) { | |
209 tty->print_cr("JVMTI Tracing the event: %s", ename); | |
210 do_op = true; | |
211 } | |
212 } | |
213 } | |
214 if (do_op) { | |
215 if (op == '+') { | |
216 _event_trace_flags[i] |= bits; | |
217 } else { | |
218 _event_trace_flags[i] &= ~bits; | |
219 } | |
220 _on = true; | |
221 } | |
222 } | |
223 } | |
224 if (!_on && (domain & (FUNC|EVENT))) { | |
225 tty->print_cr("JVMTI Trace domain not found"); | |
226 } | |
227 curr = curr_end + 1; | |
228 } | |
229 _initialized = true; | |
230 } | |
231 | |
232 | |
233 void JvmtiTrace::shutdown() { | |
234 int i; | |
235 _on = false; | |
236 _trace_event_controller = false; | |
237 for (i = 0; i <= _max_function_index; ++i) { | |
238 _trace_flags[i] = 0; | |
239 } | |
240 for (i = 0; i <= _max_event_index; ++i) { | |
241 _event_trace_flags[i] = 0; | |
242 } | |
243 } | |
244 | |
245 | |
246 const char* JvmtiTrace::enum_name(const char** names, const jint* values, jint value) { | |
247 for (int index = 0; names[index] != 0; ++index) { | |
248 if (values[index] == value) { | |
249 return names[index]; | |
250 } | |
251 } | |
252 return "*INVALID-ENUM-VALUE*"; | |
253 } | |
254 | |
255 | |
256 // return a valid string no matter what state the thread is in | |
257 const char *JvmtiTrace::safe_get_thread_name(Thread *thread) { | |
258 if (thread == NULL) { | |
259 return "NULL"; | |
260 } | |
261 if (!thread->is_Java_thread()) { | |
262 return thread->name(); | |
263 } | |
264 JavaThread *java_thread = (JavaThread *)thread; | |
265 oop threadObj = java_thread->threadObj(); | |
266 if (threadObj == NULL) { | |
267 return "NULL"; | |
268 } | |
269 typeArrayOop name = java_lang_Thread::name(threadObj); | |
270 if (name == NULL) { | |
271 return "<NOT FILLED IN>"; | |
272 } | |
273 return UNICODE::as_utf8((jchar*) name->base(T_CHAR), name->length()); | |
274 } | |
275 | |
276 | |
277 // return the name of the current thread | |
278 const char *JvmtiTrace::safe_get_current_thread_name() { | |
279 if (JvmtiEnv::is_vm_live()) { | |
280 return JvmtiTrace::safe_get_thread_name(Thread::current()); | |
281 } else { | |
282 return "VM not live"; | |
283 } | |
284 } | |
285 | |
286 // return a valid string no matter what the state of k_mirror | |
287 const char * JvmtiTrace::get_class_name(oop k_mirror) { | |
288 if (java_lang_Class::is_primitive(k_mirror)) { | |
289 return "primitive"; | |
290 } | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
1972
diff
changeset
|
291 Klass* k_oop = java_lang_Class::as_Klass(k_mirror); |
0 | 292 if (k_oop == NULL) { |
293 return "INVALID"; | |
294 } | |
295 return Klass::cast(k_oop)->external_name(); | |
296 } | |
297 | |
298 #endif /*JVMTI_TRACE */ |