- add sources.
[platform/framework/web/crosswalk.git] / src / native_client_sdk / src / libraries / xray / report.c
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. */
4
5
6 /* XRay -- a simple profiler for Native Client */
7
8 #include <alloca.h>
9 #include <errno.h>
10 #include <stdarg.h>
11 #include <stdint.h>
12 #include <stdio.h>
13 #include <stdlib.h>
14 #include <string.h>
15 #include <unistd.h>
16 #include "xray/xray_priv.h"
17
18 #if defined(XRAY)
19
20 struct XRayTotal {
21   int index;
22   int frame;
23   uint64_t ticks;
24 };
25
26
27 /* Dumps the trace report for a given frame. */
28 void XRayTraceReport(struct XRayTraceCapture* capture,
29                      FILE* f,
30                      int frame,
31                      char* label,
32                      float percent_cutoff,
33                      int ticks_cutoff) {
34   int index;
35   int start;
36   int end;
37   float total;
38   char space[257];
39   struct XRaySymbolTable* symbols = XRayGetSymbolTable(capture);
40   memset(space, ' ', 256);
41   space[256] = 0;
42   if (NULL == f) {
43     f = stdout;
44   }
45   fprintf(f,
46       "====================================================================\n");
47   if (NULL != label)
48     fprintf(f, "label %s\n", label);
49   fprintf(f, "\n");
50   fprintf(f,
51       "   Address        Ticks   Percent      Function    [annotation...]\n");
52   fprintf(f,
53       "--------------------------------------------------------------------\n");
54   total = XRayFrameGetTotalTicks(capture, frame);
55   start = XRayFrameGetTraceStartIndex(capture, frame);
56   end = XRayFrameGetTraceEndIndex(capture, frame);
57   index = start;
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);
74         } else {
75           strcpy(annotation, "");
76         }
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);
80       }
81     }
82     index = XRayTraceNextEntry(capture, index);
83   }
84   fflush(f);
85 }
86
87
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;
92 }
93
94
95 /* Dumps a frame report */
96 void XRayFrameReport(struct XRayTraceCapture* capture, FILE* f) {
97   int i;
98   int head = XRayFrameGetHead(capture);
99   int frame = XRayFrameGetTail(capture);
100   int counter = 0;
101   int total_capture = 0;
102   struct XRayTotal* totals;
103   totals = (struct XRayTotal*)
104     alloca(XRayFrameGetCount(capture) * sizeof(struct XRayTotal));
105   fprintf(f, "\n");
106   fprintf(f,
107       "Frame#      Total Ticks      Capture size    Annotations   Label\n");
108   fprintf(f,
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",
118       counter,
119       valid ? " " : "*",
120       (int64_t)total_ticks,
121       capture_size,
122       annotation_count,
123       label);
124     totals[counter].index = counter;
125     totals[counter].frame = frame;
126     totals[counter].ticks = total_ticks;
127     total_capture += capture_size;
128     ++counter;
129     frame = XRayFrameGetNext(capture, frame);
130   }
131   fprintf(f,
132       "--------------------------------------------------------------------\n");
133   fprintf(f,
134   "XRay: %d frame(s)    %d total capture(s)\n", counter, total_capture);
135   fprintf(f, "\n");
136   /* Sort and take average of the median cut */
137   qsort(totals, counter, sizeof(struct XRayTotal), qcompare);
138   fprintf(f, "\n");
139   fprintf(f, "Sorted by total ticks (most expensive first):\n");
140   fprintf(f, "\n");
141   fprintf(f,
142       "Frame#      Total Ticks      Capture size    Annotations   Label\n");
143   fprintf(f,
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",
154         index,
155         (int64_t)total_ticks,
156         capture_size,
157         annotation_count,
158         label);
159   }
160   fflush(f);
161 }
162
163
164 /* Dump a frame report followed by trace report(s) for each frame. */
165 void XRayReport(struct XRayTraceCapture* capture,
166                 FILE* f,
167                 float percent_cutoff,
168                 int ticks_cutoff) {
169   int head = XRayFrameGetHead(capture);
170   int frame = XRayFrameGetTail(capture);
171   int counter = 0;
172   XRayFrameReport(capture, f);
173   fprintf(f, "\n");
174   while (frame != head) {
175     char label[XRAY_MAX_LABEL];
176     fprintf(f, "\n");
177     XRayFrameMakeLabel(capture, counter, label);
178     XRayTraceReport(capture, f, frame, label, percent_cutoff, ticks_cutoff);
179     ++counter;
180     frame = XRayFrameGetNext(capture, frame);
181   }
182   fprintf(f,
183       "====================================================================\n");
184 #if defined(XRAY_OUTPUT_HASH_COLLISIONS)
185   XRayHashTableHisto(capture, f);
186 #endif
187   fflush(f);
188 }
189
190 /* Write a profile report to text file. */
191 void XRaySaveReport(struct XRayTraceCapture* capture,
192                     const char* filename,
193                     float percent_cutoff,
194                     int ticks_cutoff) {
195   FILE* f;
196   f = fopen(filename, "wt");
197   if (NULL != f) {
198     XRayReport(capture, f, percent_cutoff, ticks_cutoff);
199     fclose(f);
200   }
201 }
202
203 #endif  /* XRAY */