0N/A#!/usr/sbin/dtrace -Zs
0N/A
0N/A/*
2362N/A * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
0N/A *
0N/A * Redistribution and use in source and binary forms, with or without
0N/A * modification, are permitted provided that the following conditions
0N/A * are met:
0N/A *
0N/A * - Redistributions of source code must retain the above copyright
0N/A * notice, this list of conditions and the following disclaimer.
0N/A *
0N/A * - Redistributions in binary form must reproduce the above copyright
0N/A * notice, this list of conditions and the following disclaimer in the
0N/A * documentation and/or other materials provided with the distribution.
0N/A *
2362N/A * - Neither the name of Oracle nor the names of its
0N/A * contributors may be used to endorse or promote products derived
0N/A * from this software without specific prior written permission.
0N/A *
0N/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
0N/A * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
0N/A * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
0N/A * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
0N/A * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
0N/A * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
0N/A * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
0N/A * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
0N/A * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
0N/A * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
0N/A * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
0N/A */
0N/A
0N/A/*
0N/A*/
0N/A
0N/A/*
0N/A * Usage:
0N/A * 1. method_invocation_stat_filter.d -c "java ..." p|c|m package|class_name|method_name
0N/A * 2. method_invocation_stat_filter.d -p JAVA_PID p|c|m package|class_name|method_name
0N/A *
0N/A * example:
0N/A * method_invocation_stat_filter.d -c "java -version" '"p"' '"sun/util"'
0N/A *
0N/A * This script collects statistics about Java method invocations.
0N/A *
0N/A * Notes:
0N/A * - These probes are disabled by default since it incurs performance
0N/A * overhead to the application. To trace the method-entry and
0N/A * method-exit probes, you need to turn on the ExtendedDTraceProbes VM
0N/A * option.
0N/A * You can either start the application with -XX:+ExtendedDTraceProbes
0N/A * option or use the jinfo command to enable it at runtime as follows:
0N/A *
0N/A * jinfo -flag +ExtendedDTraceProbes <java_pid>
0N/A *
0N/A */
0N/A
0N/A#pragma D option quiet
0N/A#pragma D option destructive
0N/A#pragma D option defaultargs
0N/A#pragma D option bufsize=16m
0N/A#pragma D option aggrate=100ms
0N/A
0N/A
0N/Aself char *str_ptr;
0N/Aself string class_name;
0N/Aself string method_name;
0N/Aself string signature;
0N/Aself string package_name;
0N/Aself string last_class_name;
0N/A
0N/Along long JAVA_CALLS;
0N/A
0N/Along long START_TIME;
0N/Along long JAVA_TIME;
0N/Along long RUN_TIME;
0N/A
0N/Astring FILTER_TYPE;
0N/Astring FILTER_VALUE;
0N/A
0N/A
0N/A:::BEGIN
0N/A{
0N/A SAMPLE_NAME = "hotspot method invocation tracing";
0N/A
0N/A START_TIME = timestamp;
0N/A
0N/A FILTER_TYPE = $1;
0N/A FILTER_VALUE = $2;
0N/A
0N/A START_TIME = timestamp;
0N/A
0N/A printf("BEGIN %s\n\n", SAMPLE_NAME);
0N/A}
0N/A
0N/A/*
0N/A * hotspot:::method-entry, hotspot:::method-return probe arguments:
0N/A * arg0: uintptr_t, Java thread id
0N/A * arg1: char*, a pointer to mUTF-8 string containing the name of
0N/A * the class of the method being entered
0N/A * arg2: uintptr_t, the length of the class name (in bytes)
0N/A * arg3: char*, a pointer to mUTF-8 string data which contains the
0N/A * name of the method being entered
0N/A * arg4: uintptr_t, the length of the method name (in bytes)
0N/A * arg5: char*, a pointer to mUTF-8 string data which contains the
0N/A * signature of the method being entered
0N/A * arg6: uintptr_t, the length of the signature(in bytes)
0N/A */
0N/Ahotspot$target:::method-entry
0N/A{
0N/A self->str_ptr = (char*) copyin(arg1, arg2+1);
0N/A self->str_ptr[arg2] = '\0';
0N/A self->class_name = (string) self->str_ptr;
0N/A
0N/A self->str_ptr = (char*) copyin(arg3, arg4+1);
0N/A self->str_ptr[arg4] = '\0';
0N/A self->method_name = (string) self->str_ptr;
0N/A
0N/A self->str_ptr = (char*) copyin(arg5, arg6+1);
0N/A self->str_ptr[arg6] = '\0';
0N/A self->signature = (string) self->str_ptr;
0N/A
0N/A
0N/A self->package_name = dirname(self->class_name);
0N/A}
0N/A
0N/Ahotspot$target:::method-entry
0N/A/FILTER_TYPE == ""/
0N/A{
0N/A JAVA_CALLS ++;
0N/A @method_calls[self->class_name,
0N/A self->method_name, self->signature] = count();
0N/A @class_calls[self->class_name] = count();
0N/A @package_calls[self->package_name] = count();
0N/A}
0N/A
0N/Ahotspot$target:::method-entry
0N/A/FILTER_TYPE == "p" && self->package_name == FILTER_VALUE/
0N/A{
0N/A JAVA_CALLS ++;
0N/A @method_calls[self->class_name,
0N/A self->method_name, self->signature] = count();
0N/A @class_calls[self->class_name] = count();
0N/A @package_calls[self->package_name] = count();
0N/A}
0N/A
0N/Ahotspot$target:::method-entry
0N/A/FILTER_TYPE == "c" && self->class_name == FILTER_VALUE/
0N/A{
0N/A JAVA_CALLS ++;
0N/A @method_calls[self->class_name,
0N/A self->method_name, self->signature] = count();
0N/A @class_calls[self->class_name] = count();
0N/A @package_calls[self->package_name] = count();
0N/A}
0N/A
0N/Ahotspot$target:::method-entry
0N/A/FILTER_TYPE == "m" && self->method_name == FILTER_VALUE/
0N/A{
0N/A JAVA_CALLS ++;
0N/A @method_calls[self->class_name,
0N/A self->method_name, self->signature] = count();
0N/A @class_calls[self->class_name] = count();
0N/A @package_calls[self->package_name] = count();
0N/A}
0N/A
0N/A
0N/A:::END
0N/A{
0N/A RUN_TIME = (timestamp - START_TIME);
0N/A JAVA_TIME = RUN_TIME;
0N/A
0N/A printf("Top packages calls:\n");
0N/A printa("%10@d %s\n", @package_calls);
0N/A printf("\n");
0N/A
0N/A printf("Top class calls:\n");
0N/A printa("%10@d %s\n", @class_calls);
0N/A printf("\n");
0N/A
0N/A printf("Top method calls:\n");
0N/A printa("%10@d %s:%s:%s\n", @method_calls);
0N/A printf("\n");
0N/A
0N/A printf("=======================================\n");
0N/A printf("JAVA_CALLS: %10d\n", JAVA_CALLS);
0N/A printf("\n");
0N/A
0N/A printf("Run time: %15d\n", RUN_TIME);
0N/A printf("\n");
0N/A}
0N/A
0N/A:::END
0N/A{
0N/A printf("\nEND of %s\n", SAMPLE_NAME);
0N/A}
0N/A
0N/Asyscall::rexit:entry,
0N/Asyscall::exit:entry
0N/A/pid == $target/
0N/A{
0N/A exit(0);
0N/A}