1#!/usr/sbin/dtrace -CZs
2/*
3 * j_calldist.d - measure Java elapsed times for different types of operation.
4 *                Written for the Java hotspot DTrace provider.
5 *
6 * $Id: j_calldist.d 59 2007-10-03 08:21:58Z brendan $
7 *
8 * This traces activity from all Java processes on the system with hotspot
9 * provider support (1.6.0). Method calls are only visible when using the
10 * flag "+ExtendedDTraceProbes". eg, java -XX:+ExtendedDTraceProbes classfile
11 *
12 * USAGE: j_calldist.d [top]	# hit Ctrl-C to end
13 *
14 * The "top" optional argument will truncate the output for each report
15 * section to that many lines, with a default of 10.
16 *
17 * FIELDS:
18 *		1		Process ID
19 *		2		Type of call (method/gc)
20 *		3		Name of call
21 *
22 * COPYRIGHT: Copyright (c) 2007 Brendan Gregg.
23 *
24 * CDDL HEADER START
25 *
26 *  The contents of this file are subject to the terms of the
27 *  Common Development and Distribution License, Version 1.0 only
28 *  (the "License").  You may not use this file except in compliance
29 *  with the License.
30 *
31 *  You can obtain a copy of the license at Docs/cddl1.txt
32 *  or http://www.opensolaris.org/os/licensing.
33 *  See the License for the specific language governing permissions
34 *  and limitations under the License.
35 *
36 * CDDL HEADER END
37 *
38 * 09-Sep-2007	Brendan Gregg	Created this.
39 */
40
41#define TOP	10		/* default output truncation */
42#define B_FALSE	0
43
44#pragma D option quiet
45#pragma D option defaultargs
46
47dtrace:::BEGIN
48{
49	printf("Tracing... Hit Ctrl-C to end.\n");
50	top = $1 != 0 ? $1 : TOP;
51}
52
53hotspot*:::method-entry
54{
55	self->depth[arg0]++;
56	self->exclude[arg0, self->depth[arg0]] = 0;
57	self->method[arg0, self->depth[arg0]] = timestamp;
58}
59
60hotspot*:::method-return
61/self->method[arg0, self->depth[arg0]]/
62{
63	this->elapsed_incl = timestamp - self->method[arg0, self->depth[arg0]];
64	this->elapsed_excl = this->elapsed_incl -
65	    self->exclude[arg0, self->depth[arg0]];
66	self->method[arg0, self->depth[arg0]] = 0;
67	self->exclude[arg0, self->depth[arg0]] = 0;
68
69	this->class = (char *)copyin(arg1, arg2 + 1);
70	this->class[arg2] = '\0';
71	this->method = (char *)copyin(arg3, arg4 + 1);
72	this->method[arg4] = '\0';
73	this->name = strjoin(strjoin(stringof(this->class), "."),
74	    stringof(this->method));
75
76	@types_incl[pid, "method", this->name] =
77	    quantize(this->elapsed_incl / 1000);
78	@types_excl[pid, "method", this->name] =
79	    quantize(this->elapsed_excl / 1000);
80
81	self->depth[arg0]--;
82	self->exclude[arg0, self->depth[arg0]] += this->elapsed_incl;
83}
84
85hotspot*:::gc-begin
86{
87	self->gc = timestamp;
88	self->full = (boolean_t)arg0;
89}
90
91hotspot*:::gc-end
92/self->gc/
93{
94	this->elapsed = timestamp - self->gc;
95
96	@types[pid, "gc", self->full == B_FALSE ? "GC" : "Full GC"] =
97	    quantize(this->elapsed / 1000);
98
99	self->gc = 0;
100	self->full = 0;
101}
102
103dtrace:::END
104{
105	trunc(@types, top);
106	printf("\nTop %d elapsed times (us),\n", top);
107	printa("   PID=%d, %s, %s %@d\n", @types);
108
109	trunc(@types_excl, top);
110	printf("\nTop %d exclusive method elapsed times (us),\n", top);
111	printa("   PID=%d, %s, %s %@d\n", @types_excl);
112
113	trunc(@types_incl, top);
114	printf("\nTop %d inclusive method elapsed times (us),\n", top);
115	printa("   PID=%d, %s, %s %@d\n", @types_incl);
116}
117