Upstream version 11.40.277.0
[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 <inttypes.h>
11 #include <stdarg.h>
12 #include <stdint.h>
13 #include <stdio.h>
14 #include <stdlib.h>
15 #include <string.h>
16 #include <unistd.h>
17 #include "xray/xray_priv.h"
18
19 #if defined(XRAY)
20
21 struct XRayTotal {
22   int index;
23   int frame;
24   uint64_t ticks;
25 };
26
27
28 /* Dumps the trace report for a given frame. */
29 void XRayTraceReport(struct XRayTraceCapture* capture,
30                      FILE* f,
31                      int frame,
32                      char* label,
33                      float percent_cutoff,
34                      int ticks_cutoff) {
35   int index;
36   int start;
37   int end;
38   float total;
39   char space[257];
40   struct XRaySymbolTable* symbols = XRayGetSymbolTable(capture);
41   memset(space, ' ', 256);
42   space[256] = 0;
43   if (NULL == f) {
44     f = stdout;
45   }
46   fprintf(f,
47       "====================================================================\n");
48   if (NULL != label)
49     fprintf(f, "label %s\n", label);
50   fprintf(f, "\n");
51   fprintf(f,
52       "   Address          Ticks   Percent      Function    [annotation...]\n");
53   fprintf(f,
54       "--------------------------------------------------------------------\n");
55   total = XRayFrameGetTotalTicks(capture, frame);
56   start = XRayFrameGetTraceStartIndex(capture, frame);
57   end = XRayFrameGetTraceEndIndex(capture, frame);
58   index = start;
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;
67       uint64_t ticks =
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);
76         } else {
77           strcpy(annotation, "");
78         }
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);
82       }
83     }
84     index = XRayTraceNextEntry(capture, index);
85   }
86   fflush(f);
87 }
88
89
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)
94     return 1;
95   else if (ib->ticks < ia->ticks)
96     return -1;
97   return 0;
98 }
99
100
101 /* Dumps a frame report */
102 void XRayFrameReport(struct XRayTraceCapture* capture, FILE* f) {
103   int i;
104   int head = XRayFrameGetHead(capture);
105   int frame = XRayFrameGetTail(capture);
106   int counter = 0;
107   int total_capture = 0;
108   struct XRayTotal* totals;
109   totals = (struct XRayTotal*)
110     alloca(XRayFrameGetCount(capture) * sizeof(struct XRayTotal));
111   fprintf(f, "\n");
112   fprintf(f,
113       "Frame#        Total Ticks      Capture size    Annotations   Label\n");
114   fprintf(f,
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",
124       counter,
125       valid ? " " : "*",
126       total_ticks,
127       capture_size,
128       annotation_count,
129       label);
130     totals[counter].index = counter;
131     totals[counter].frame = frame;
132     totals[counter].ticks = total_ticks;
133     total_capture += capture_size;
134     ++counter;
135     frame = XRayFrameGetNext(capture, frame);
136   }
137   fprintf(f,
138       "--------------------------------------------------------------------\n");
139   fprintf(f,
140   "XRay: %d frame(s)    %d total capture(s)\n", counter, total_capture);
141   fprintf(f, "\n");
142   /* Sort and take average of the median cut */
143   qsort(totals, counter, sizeof(struct XRayTotal), qcompare);
144   fprintf(f, "\n");
145   fprintf(f, "Sorted by total ticks (most expensive first):\n");
146   fprintf(f, "\n");
147   fprintf(f,
148       "Frame#        Total Ticks      Capture size    Annotations   Label\n");
149   fprintf(f,
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",
160         index,
161         total_ticks,
162         capture_size,
163         annotation_count,
164         label);
165   }
166   fflush(f);
167 }
168
169
170 /* Dump a frame report followed by trace report(s) for each frame. */
171 void XRayReport(struct XRayTraceCapture* capture,
172                 FILE* f,
173                 float percent_cutoff,
174                 int ticks_cutoff) {
175   int head = XRayFrameGetHead(capture);
176   int frame = XRayFrameGetTail(capture);
177   int counter = 0;
178   XRayFrameReport(capture, f);
179   fprintf(f, "\n");
180   while (frame != head) {
181     char label[XRAY_MAX_LABEL];
182     fprintf(f, "\n");
183     XRayFrameMakeLabel(capture, counter, label);
184     XRayTraceReport(capture, f, frame, label, percent_cutoff, ticks_cutoff);
185     ++counter;
186     frame = XRayFrameGetNext(capture, frame);
187   }
188   fprintf(f,
189       "====================================================================\n");
190 #if defined(XRAY_OUTPUT_HASH_COLLISIONS)
191   XRayHashTableHisto(capture, f);
192 #endif
193   fflush(f);
194 }
195
196 /* Write a profile report to text file. */
197 void XRaySaveReport(struct XRayTraceCapture* capture,
198                     const char* filename,
199                     float percent_cutoff,
200                     int ticks_cutoff) {
201   FILE* f;
202   f = fopen(filename, "wt");
203   if (NULL != f) {
204     XRayReport(capture, f, percent_cutoff, ticks_cutoff);
205     fclose(f);
206   }
207 }
208
209 #endif  /* XRAY */