annotate src/share/vm/prims/jvmtiTrace.cpp @ 5820:87ee5ee27509

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