1 /* Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 * Use of this source code is governed by a BSD-style license that can be
3 * found in the LICENSE file. */
6 /* XRay -- a simple profiler for Native Client */
17 #include "xray/xray_priv.h"
28 /* Dumps the trace report for a given frame. */
29 void XRayTraceReport(struct XRayTraceCapture
* capture
,
40 struct XRaySymbolTable
* symbols
= XRayGetSymbolTable(capture
);
41 memset(space
, ' ', 256);
47 "====================================================================\n");
49 fprintf(f
, "label %s\n", label
);
52 " Address Ticks Percent Function [annotation...]\n");
54 "--------------------------------------------------------------------\n");
55 total
= XRayFrameGetTotalTicks(capture
, frame
);
56 start
= XRayFrameGetTraceStartIndex(capture
, frame
);
57 end
= XRayFrameGetTraceEndIndex(capture
, frame
);
59 while (index
!= end
) {
60 if (!XRayTraceIsAnnotation(capture
, index
)) {
61 const char* symbol_name
;
62 char annotation
[XRAY_TRACE_ANNOTATION_LENGTH
];
63 struct XRayTraceBufferEntry
* e
= XRayTraceGetEntry(capture
, index
);
64 uint32_t depth
= XRAY_EXTRACT_DEPTH(e
->depth_addr
);
65 uint32_t addr
= XRAY_EXTRACT_ADDR(e
->depth_addr
);
66 uint32_t annotation_index
= e
->annotation_index
;
68 e
->end_tick
> e
->start_tick
? e
->end_tick
- e
->start_tick
: 0;
69 float percent
= 100.0f
* (float)ticks
/ total
;
70 if (percent
>= percent_cutoff
&& ticks
>= ticks_cutoff
) {
71 struct XRaySymbol
* symbol
;
72 symbol
= XRaySymbolTableLookup(symbols
, addr
);
73 symbol_name
= XRaySymbolGetName(symbol
);
74 if (0 != annotation_index
) {
75 XRayTraceCopyToString(capture
, annotation_index
, annotation
);
77 strcpy(annotation
, "");
79 fprintf(f
, "0x%08X %12" PRIu64
" %5.1f %s%s %s\n",
80 (unsigned int)addr
, ticks
, percent
,
81 &space
[256 - depth
], symbol_name
, annotation
);
84 index
= XRayTraceNextEntry(capture
, index
);
90 int qcompare(const void* a
, const void* b
) {
91 struct XRayTotal
* ia
= (struct XRayTotal
*)a
;
92 struct XRayTotal
* ib
= (struct XRayTotal
*)b
;
93 if (ib
->ticks
> ia
->ticks
)
95 else if (ib
->ticks
< ia
->ticks
)
101 /* Dumps a frame report */
102 void XRayFrameReport(struct XRayTraceCapture
* capture
, FILE* f
) {
104 int head
= XRayFrameGetHead(capture
);
105 int frame
= XRayFrameGetTail(capture
);
107 int total_capture
= 0;
108 struct XRayTotal
* totals
;
109 totals
= (struct XRayTotal
*)
110 alloca(XRayFrameGetCount(capture
) * sizeof(struct XRayTotal
));
113 "Frame# Total Ticks Capture size Annotations Label\n");
115 "--------------------------------------------------------------------\n");
116 while (frame
!= head
) {
117 uint64_t total_ticks
= XRayFrameGetTotalTicks(capture
, frame
);
118 int capture_size
= XRayFrameGetTraceCount(capture
, frame
);
119 int annotation_count
= XRayFrameGetAnnotationCount(capture
, frame
);
120 bool valid
= XRayFrameIsValid(capture
, frame
);
121 char label
[XRAY_MAX_LABEL
];
122 XRayFrameMakeLabel(capture
, counter
, label
);
123 fprintf(f
, " %3d %s %12" PRIu64
" %10d %10d %s\n",
130 totals
[counter
].index
= counter
;
131 totals
[counter
].frame
= frame
;
132 totals
[counter
].ticks
= total_ticks
;
133 total_capture
+= capture_size
;
135 frame
= XRayFrameGetNext(capture
, frame
);
138 "--------------------------------------------------------------------\n");
140 "XRay: %d frame(s) %d total capture(s)\n", counter
, total_capture
);
142 /* Sort and take average of the median cut */
143 qsort(totals
, counter
, sizeof(struct XRayTotal
), qcompare
);
145 fprintf(f
, "Sorted by total ticks (most expensive first):\n");
148 "Frame# Total Ticks Capture size Annotations Label\n");
150 "--------------------------------------------------------------------\n");
151 for (i
= 0; i
< counter
; ++i
) {
152 int index
= totals
[i
].index
;
153 int frame
= totals
[i
].frame
;
154 uint64_t total_ticks
= XRayFrameGetTotalTicks(capture
, frame
);
155 int capture_size
= XRayFrameGetTraceCount(capture
, frame
);
156 int annotation_count
= XRayFrameGetAnnotationCount(capture
, frame
);
157 char label
[XRAY_MAX_LABEL
];
158 XRayFrameMakeLabel(capture
, index
, label
);
159 fprintf(f
, " %3d %12" PRIu64
" %10d %10d %s\n",
170 /* Dump a frame report followed by trace report(s) for each frame. */
171 void XRayReport(struct XRayTraceCapture
* capture
,
173 float percent_cutoff
,
175 int head
= XRayFrameGetHead(capture
);
176 int frame
= XRayFrameGetTail(capture
);
178 XRayFrameReport(capture
, f
);
180 while (frame
!= head
) {
181 char label
[XRAY_MAX_LABEL
];
183 XRayFrameMakeLabel(capture
, counter
, label
);
184 XRayTraceReport(capture
, f
, frame
, label
, percent_cutoff
, ticks_cutoff
);
186 frame
= XRayFrameGetNext(capture
, frame
);
189 "====================================================================\n");
190 #if defined(XRAY_OUTPUT_HASH_COLLISIONS)
191 XRayHashTableHisto(capture
, f
);
196 /* Write a profile report to text file. */
197 void XRaySaveReport(struct XRayTraceCapture
* capture
,
198 const char* filename
,
199 float percent_cutoff
,
202 f
= fopen(filename
, "wt");
204 XRayReport(capture
, f
, percent_cutoff
, ticks_cutoff
);