src/share/vm/prims/jvmtiTrace.cpp

Wed, 27 Apr 2016 01:25:04 +0800

author
aoqi
date
Wed, 27 Apr 2016 01:25:04 +0800
changeset 0
f90c822e73f8
child 6876
710a3c8b516e
permissions
-rw-r--r--

Initial load
http://hg.openjdk.java.net/jdk8u/jdk8u/hotspot/
changeset: 6782:28b50d07f6f8
tag: jdk8u25-b17

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

mercurial