Home | History | Annotate | Download | only in xray
      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 
      7 /* XRay -- a simple profiler for Native Client */
      8 
      9 #ifndef XRAY_DISABLE_BROWSER_INTEGRATION
     10 
     11 #include <alloca.h>
     12 #include <assert.h>
     13 #include <errno.h>
     14 #include <stdarg.h>
     15 #include <stdint.h>
     16 #include <stdio.h>
     17 #include <stdlib.h>
     18 #include <string.h>
     19 #include <unistd.h>
     20 #include "ppapi/c/dev/ppb_trace_event_dev.h"
     21 #include "xray/xray_priv.h"
     22 
     23 
     24 #if defined(XRAY)
     25 static PPB_Trace_Event_Dev* ppb_trace_event_interface = NULL;
     26 
     27 static const char* XRayGetName(struct XRaySymbolTable* symbols,
     28       struct XRayTraceBufferEntry* e) {
     29   uint32_t addr = XRAY_EXTRACT_ADDR(e->depth_addr);
     30   struct XRaySymbol* symbol = XRaySymbolTableLookup(symbols, addr);
     31   return XRaySymbolGetName(symbol);
     32 }
     33 
     34 struct XRayTimestampPair XRayGenerateTimestampsNow(void) {
     35   struct XRayTimestampPair pair;
     36   assert(ppb_trace_event_interface);
     37 
     38   XRayGetTSC(&pair.xray);
     39   pair.pepper = ppb_trace_event_interface->Now();
     40   return pair;
     41 }
     42 
     43 /* see chromium/src/base/debug/trace_event.h */
     44 #define TRACE_VALUE_TYPE_UINT (2)
     45 #define TRACE_VALUE_TYPE_DOUBLE (4)
     46 #define TRACE_VALUE_TYPE_COPY_STRING (7)
     47 
     48 union TraceValue {
     49     bool as_bool;
     50     unsigned long long as_uint;
     51     long long as_int;
     52     double as_double;
     53     const void* as_pointer;
     54     const char* as_string;
     55   };
     56 
     57 void XRayBrowserTraceReport(struct XRayTraceCapture* capture) {
     58 
     59   const void* cat_enabled = ppb_trace_event_interface->GetCategoryEnabled(
     60       "xray");
     61   struct XRaySymbolTable* symbols = XRayGetSymbolTable(capture);
     62 
     63   int32_t thread_id = XRayGetSavedThreadID(capture);
     64 
     65   int head = XRayFrameGetHead(capture);
     66   int frame = XRayFrameGetTail(capture);
     67   while(frame != head) {
     68 
     69     struct XRayTimestampPair start_time = XRayFrameGetStartTimestampPair(
     70         capture, frame);
     71     struct XRayTimestampPair end_time = XRayFrameGetEndTimestampPair(
     72         capture, frame);
     73 
     74     double pdiff = (end_time.pepper - start_time.pepper);
     75     double odiff = (end_time.xray - start_time.xray);
     76     double scale_a = pdiff / odiff;
     77     double scale_b = ((double)end_time.pepper) - (scale_a * end_time.xray);
     78     printf("Xray timestamp calibration frame %d: %f %f\n",
     79         frame, scale_a, scale_b);
     80 
     81     int start = XRayFrameGetTraceStartIndex(capture, frame);
     82     int end = XRayFrameGetTraceEndIndex(capture, frame);
     83 
     84     struct XRayTraceBufferEntry** stack_base = XRayMalloc(
     85       sizeof(struct XRayTraceBufferEntry*) * (XRAY_TRACE_STACK_SIZE + 1));
     86     struct XRayTraceBufferEntry** stack_top = stack_base;
     87     *stack_top = NULL;
     88 
     89     uint32_t num_args = 0;
     90     const char* arg_names[] = {"annotation"};
     91     uint8_t arg_types[] = {TRACE_VALUE_TYPE_COPY_STRING};
     92     uint64_t arg_values[] = {0};
     93     char annotation[XRAY_TRACE_ANNOTATION_LENGTH];
     94 
     95     int i;
     96     for(i = start; i != end; i = XRayTraceNextEntry(capture, i)) {
     97       if (XRayTraceIsAnnotation(capture, i)) {
     98         continue;
     99       }
    100 
    101       uint32_t depth = XRAY_EXTRACT_DEPTH(
    102           XRayTraceGetEntry(capture, i)->depth_addr);
    103 
    104       while(*stack_top &&
    105           XRAY_EXTRACT_DEPTH((*stack_top)->depth_addr) >= depth) {
    106         struct XRayTraceBufferEntry* e = *(stack_top--);
    107         ppb_trace_event_interface->AddTraceEventWithThreadIdAndTimestamp(
    108             'E', cat_enabled,
    109             XRayGetName(symbols, e),
    110             0, thread_id,
    111             (scale_a * e->end_tick) + scale_b,
    112             0, NULL, NULL, NULL, 0
    113         );
    114       }
    115 
    116       num_args = 0;
    117       struct XRayTraceBufferEntry* e = XRayTraceGetEntry(capture, i);
    118       uint32_t annotation_index = e->annotation_index;
    119       if (annotation_index) {
    120         XRayTraceCopyToString(capture, annotation_index, annotation);
    121 
    122         union TraceValue val;
    123         val.as_string = (const char*)annotation;
    124 
    125         arg_values[0] = val.as_uint;
    126         num_args = 1;
    127       }
    128 
    129       ppb_trace_event_interface->AddTraceEventWithThreadIdAndTimestamp(
    130           'B', cat_enabled,
    131           XRayGetName(symbols, e),
    132           0, thread_id,
    133           (scale_a * e->start_tick) + scale_b,
    134           num_args, arg_names, arg_types, arg_values, 0
    135       );
    136 
    137       *(++stack_top) = e;
    138     }
    139 
    140     while(*stack_top) {
    141       struct XRayTraceBufferEntry* e = *(stack_top--);
    142       ppb_trace_event_interface->AddTraceEventWithThreadIdAndTimestamp(
    143           'E', cat_enabled,
    144           XRayGetName(symbols, e),
    145           0, thread_id,
    146           (scale_a * e->end_tick) + scale_b,
    147           0, NULL, NULL, NULL, 0
    148       );
    149     }
    150 
    151     frame = XRayFrameGetNext(capture, frame);
    152     XRayFree(stack_base);
    153   }
    154 }
    155 
    156 void XRayRegisterBrowserInterface(PPB_GetInterface interface) {
    157   ppb_trace_event_interface = (PPB_Trace_Event_Dev*)interface(
    158       PPB_TRACE_EVENT_DEV_INTERFACE);
    159   assert(ppb_trace_event_interface);
    160 }
    161 
    162 #endif  /* XRAY */
    163 #endif  /* XRAY_DISABLE_BROWSER_INTEGRATION */