src/share/vm/prims/jvmtiTrace.cpp

Sun, 15 Sep 2013 15:28:58 +0200

author
goetz
date
Sun, 15 Sep 2013 15:28:58 +0200
changeset 6470
abe03600372a
parent 4278
070d523b96a7
child 6876
710a3c8b516e
child 8288
efe013052465
permissions
-rw-r--r--

8024468: PPC64 (part 201): cppInterpreter: implement bytecode profiling
Summary: Implement profiling for c2 jit compilation. Also enable new cppInterpreter features.
Reviewed-by: kvn

     1 /*
     2  * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
     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  *
    19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    20  * or visit www.oracle.com if you need additional information or have any
    21  * questions.
    22  *
    23  */
    25 #include "precompiled.hpp"
    26 #include "jvmtifiles/jvmtiEnv.hpp"
    27 #include "prims/jvmtiTrace.hpp"
    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
    63 #ifdef JVMTI_TRACE
    65 bool JvmtiTrace::_initialized = false;
    66 bool JvmtiTrace::_on = false;
    67 bool JvmtiTrace::_trace_event_controller = false;
    69 void JvmtiTrace::initialize() {
    70   if (_initialized) {
    71     return;
    72   }
    73   SafeResourceMark rm;
    75   const char *very_end;
    76   const char *curr;
    77   if (TraceJVMTI != NULL) {
    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     }
   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 }
   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 }
   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 }
   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 }
   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 }
   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   }
   291   Klass* k_oop = java_lang_Class::as_Klass(k_mirror);
   292   if (k_oop == NULL) {
   293     return "INVALID";
   294   }
   295   return k_oop->external_name();
   296 }
   298 #endif /*JVMTI_TRACE */

mercurial