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 */
16 #include "xray/xray_priv.h"
27 /* Dumps the trace report for a given frame. */
28 void XRayTraceReport(struct XRayTraceCapture* capture,
39 struct XRaySymbolTable* symbols = XRayGetSymbolTable(capture);
40 memset(space, ' ', 256);
46 "====================================================================\n");
48 fprintf(f, "label %s\n", label);
51 " Address Ticks Percent Function [annotation...]\n");
53 "--------------------------------------------------------------------\n");
54 total = XRayFrameGetTotalTicks(capture, frame);
55 start = XRayFrameGetTraceStartIndex(capture, frame);
56 end = XRayFrameGetTraceEndIndex(capture, frame);
58 while (index != end) {
59 if (!XRayTraceIsAnnotation(capture, index)) {
60 const char* symbol_name;
61 char annotation[XRAY_TRACE_ANNOTATION_LENGTH];
62 struct XRayTraceBufferEntry* e = XRayTraceGetEntry(capture, index);
63 uint32_t depth = XRAY_EXTRACT_DEPTH(e->depth_addr);
64 uint32_t addr = XRAY_EXTRACT_ADDR(e->depth_addr);
65 uint32_t ticks = e->end_tick - e->start_tick;
66 uint32_t annotation_index = e->annotation_index;
67 float percent = 100.0f * (float)ticks / total;
68 if (percent >= percent_cutoff && ticks >= ticks_cutoff) {
69 struct XRaySymbol* symbol;
70 symbol = XRaySymbolTableLookup(symbols, addr);
71 symbol_name = XRaySymbolGetName(symbol);
72 if (0 != annotation_index) {
73 XRayTraceCopyToString(capture, annotation_index, annotation);
75 strcpy(annotation, "");
77 fprintf(f, "0x%08X %10lld %5.1f %s%s %s\n",
78 (unsigned int)addr, (int64_t)ticks, percent,
79 &space[256 - depth], symbol_name, annotation);
82 index = XRayTraceNextEntry(capture, index);
88 int qcompare(const void* a, const void* b) {
89 struct XRayTotal* ia = (struct XRayTotal*)a;
90 struct XRayTotal* ib = (struct XRayTotal*)b;
91 return ib->ticks - ia->ticks;
95 /* Dumps a frame report */
96 void XRayFrameReport(struct XRayTraceCapture* capture, FILE* f) {
98 int head = XRayFrameGetHead(capture);
99 int frame = XRayFrameGetTail(capture);
101 int total_capture = 0;
102 struct XRayTotal* totals;
103 totals = (struct XRayTotal*)
104 alloca(XRayFrameGetCount(capture) * sizeof(struct XRayTotal));
107 "Frame# Total Ticks Capture size Annotations Label\n");
109 "--------------------------------------------------------------------\n");
110 while (frame != head) {
111 int64_t total_ticks = XRayFrameGetTotalTicks(capture, frame);
112 int capture_size = XRayFrameGetTraceCount(capture, frame);
113 int annotation_count = XRayFrameGetAnnotationCount(capture, frame);
114 bool valid = XRayFrameIsValid(capture, frame);
115 char label[XRAY_MAX_LABEL];
116 XRayFrameMakeLabel(capture, counter, label);
117 fprintf(f, " %3d %s %10lld %10d %10d %s\n",
120 (int64_t)total_ticks,
124 totals[counter].index = counter;
125 totals[counter].frame = frame;
126 totals[counter].ticks = total_ticks;
127 total_capture += capture_size;
129 frame = XRayFrameGetNext(capture, frame);
132 "--------------------------------------------------------------------\n");
134 "XRay: %d frame(s) %d total capture(s)\n", counter, total_capture);
136 /* Sort and take average of the median cut */
137 qsort(totals, counter, sizeof(struct XRayTotal), qcompare);
139 fprintf(f, "Sorted by total ticks (most expensive first):\n");
142 "Frame# Total Ticks Capture size Annotations Label\n");
144 "--------------------------------------------------------------------\n");
145 for (i = 0; i < counter; ++i) {
146 int index = totals[i].index;
147 int frame = totals[i].frame;
148 int64_t total_ticks = XRayFrameGetTotalTicks(capture, frame);
149 int capture_size = XRayFrameGetTraceCount(capture, frame);
150 int annotation_count = XRayFrameGetAnnotationCount(capture, frame);
151 char label[XRAY_MAX_LABEL];
152 XRayFrameMakeLabel(capture, index, label);
153 fprintf(f, " %3d %10lld %10d %10d %s\n",
155 (int64_t)total_ticks,
164 /* Dump a frame report followed by trace report(s) for each frame. */
165 void XRayReport(struct XRayTraceCapture* capture,
167 float percent_cutoff,
169 int head = XRayFrameGetHead(capture);
170 int frame = XRayFrameGetTail(capture);
172 XRayFrameReport(capture, f);
174 while (frame != head) {
175 char label[XRAY_MAX_LABEL];
177 XRayFrameMakeLabel(capture, counter, label);
178 XRayTraceReport(capture, f, frame, label, percent_cutoff, ticks_cutoff);
180 frame = XRayFrameGetNext(capture, frame);
183 "====================================================================\n");
184 #if defined(XRAY_OUTPUT_HASH_COLLISIONS)
185 XRayHashTableHisto(capture, f);
190 /* Write a profile report to text file. */
191 void XRaySaveReport(struct XRayTraceCapture* capture,
192 const char* filename,
193 float percent_cutoff,
196 f = fopen(filename, "wt");
198 XRayReport(capture, f, percent_cutoff, ticks_cutoff);