OLD | NEW |
---|---|
1 /* Copyright (c) 2013 The Chromium Authors. All rights reserved. | 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 | 2 * Use of this source code is governed by a BSD-style license that can be |
3 * found in the LICENSE file. | 3 * found in the LICENSE file. |
4 */ | 4 */ |
5 | 5 |
6 | 6 |
7 /* XRay -- a simple profiler for Native Client */ | 7 /* XRay -- a simple profiler for Native Client */ |
8 | 8 |
9 #include <assert.h> | 9 #include <assert.h> |
10 #include <errno.h> | 10 #include <errno.h> |
(...skipping 22 matching lines...) Expand all Loading... | |
33 #define GTSC(_x) __asm__ __volatile__ ("rdtsc" : "=A" (_x)); | 33 #define GTSC(_x) __asm__ __volatile__ ("rdtsc" : "=A" (_x)); |
34 #else | 34 #else |
35 FORCE_INLINE uint64_t GTOD() { | 35 FORCE_INLINE uint64_t GTOD() { |
36 struct timeval tv; | 36 struct timeval tv; |
37 gettimeofday(&tv, NULL); | 37 gettimeofday(&tv, NULL); |
38 return (uint64_t)tv.tv_sec * 1000000 + (uint64_t)tv.tv_usec; | 38 return (uint64_t)tv.tv_sec * 1000000 + (uint64_t)tv.tv_usec; |
39 } | 39 } |
40 #define GTSC(_x) _x = GTOD(); | 40 #define GTSC(_x) _x = GTOD(); |
41 #endif | 41 #endif |
42 | 42 |
43 | |
44 /* Use a TLS variable for cheap thread uid. */ | 43 /* Use a TLS variable for cheap thread uid. */ |
45 __thread struct XRayTraceCapture* g_xray_capture = NULL; | 44 __thread struct XRayTraceCapture* g_xray_capture = NULL; |
46 | 45 |
47 | 46 |
48 struct XRayTraceStackEntry { | 47 struct XRayTraceStackEntry { |
49 uint32_t depth_addr; | 48 uint32_t depth_addr; |
50 uint64_t tsc; | 49 uint64_t tsc; |
51 uint32_t dest; | 50 uint32_t dest; |
52 uint32_t annotation_index; | 51 uint32_t annotation_index; |
53 }; | 52 }; |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
86 bool initialized; | 85 bool initialized; |
87 uint32_t annotation_filter; | 86 uint32_t annotation_filter; |
88 uint32_t guard0; | 87 uint32_t guard0; |
89 struct XRayTraceStackEntry stack[XRAY_TRACE_STACK_SIZE] XRAY_ALIGN64; | 88 struct XRayTraceStackEntry stack[XRAY_TRACE_STACK_SIZE] XRAY_ALIGN64; |
90 uint32_t guard1; | 89 uint32_t guard1; |
91 uint32_t guard2; | 90 uint32_t guard2; |
92 char annotation[XRAY_ANNOTATION_STACK_SIZE] XRAY_ALIGN64; | 91 char annotation[XRAY_ANNOTATION_STACK_SIZE] XRAY_ALIGN64; |
93 uint32_t guard3; | 92 uint32_t guard3; |
94 struct XRayTraceBufferEntry* buffer; | 93 struct XRayTraceBufferEntry* buffer; |
95 struct XRayTraceFrame frame; | 94 struct XRayTraceFrame frame; |
95 | |
96 struct XrayTimestampPair start_time; | |
97 bool start_time_initialized; | |
nfullagar1
2013/07/17 00:53:19
wrap these as well with XRAY_DISABLE_BROWSER_INTEG
grosse
2013/07/17 19:37:56
Done.
| |
96 } XRAY_ALIGN64; | 98 } XRAY_ALIGN64; |
97 | 99 |
98 | 100 |
99 #ifdef __cplusplus | 101 #ifdef __cplusplus |
100 extern "C" { | 102 extern "C" { |
101 #endif | 103 #endif |
102 | 104 |
103 XRAY_NO_INSTRUMENT void __cyg_profile_func_enter(void* this_fn, | 105 XRAY_NO_INSTRUMENT void __pnacl_profile_func_enter(const char* fname); |
104 void* call_site); | 106 XRAY_NO_INSTRUMENT void __pnacl_profile_func_exit(const char* fname); |
nfullagar1
2013/07/17 00:53:19
above: need to add back __cyg_profile versions for
grosse
2013/07/17 19:37:56
Done.
| |
105 XRAY_NO_INSTRUMENT void __cyg_profile_func_exit(void* this_fn, | |
106 void* call_site); | |
107 XRAY_NO_INSTRUMENT void __xray_profile_append_annotation( | 107 XRAY_NO_INSTRUMENT void __xray_profile_append_annotation( |
108 struct XRayTraceCapture* capture, | 108 struct XRayTraceCapture* capture, |
109 struct XRayTraceStackEntry* se, | 109 struct XRayTraceStackEntry* se, |
110 struct XRayTraceBufferEntry* be); | 110 struct XRayTraceBufferEntry* be); |
111 | 111 |
112 #ifdef __cplusplus | 112 #ifdef __cplusplus |
113 } | 113 } |
114 #endif | 114 #endif |
115 | 115 |
116 | |
117 /* Asserts that the guard values haven't changed. */ | 116 /* Asserts that the guard values haven't changed. */ |
118 void XRayCheckGuards(struct XRayTraceCapture* capture) { | 117 void XRayCheckGuards(struct XRayTraceCapture* capture) { |
119 assert(capture->guard0 == XRAY_GUARD_VALUE_0x12345678); | 118 assert(capture->guard0 == XRAY_GUARD_VALUE_0x12345678); |
120 assert(capture->guard1 == XRAY_GUARD_VALUE_0x12345678); | 119 assert(capture->guard1 == XRAY_GUARD_VALUE_0x12345678); |
121 assert(capture->guard2 == XRAY_GUARD_VALUE_0x87654321); | 120 assert(capture->guard2 == XRAY_GUARD_VALUE_0x87654321); |
122 assert(capture->guard3 == XRAY_GUARD_VALUE_0x12345678); | 121 assert(capture->guard3 == XRAY_GUARD_VALUE_0x12345678); |
123 } | 122 } |
124 | 123 |
125 /* Decrements the trace index, wrapping around if needed. */ | 124 /* Decrements the trace index, wrapping around if needed. */ |
126 XRAY_FORCE_INLINE int XRayTraceDecrementIndexInline( | 125 XRAY_FORCE_INLINE int XRayTraceDecrementIndexInline( |
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
296 } | 295 } |
297 | 296 |
298 | 297 |
299 /* Generic memory free for XRay */ | 298 /* Generic memory free for XRay */ |
300 void XRayFree(void* data) { | 299 void XRayFree(void* data) { |
301 assert(NULL != data); | 300 assert(NULL != data); |
302 free(data); | 301 free(data); |
303 } | 302 } |
304 | 303 |
305 | 304 |
306 | 305 #if defined(__pnacl__) |
307 /* Main profile capture function that is called at the start */ | 306 /* Main profile capture function that is called at the start */ |
308 /* of every instrumented function. This function is implicitly */ | 307 /* of every instrumented function. This function is implicitly */ |
309 /* called when code is compilied with the -finstrument-functions option */ | 308 /* called when code is compilied with the -finstrument-functions option */ |
nfullagar1
2013/07/17 00:53:19
comment above should include compiler options for
| |
309 void __pnacl_profile_func_enter(const char* fname) { | |
nfullagar1
2013/07/17 00:53:19
fname -> this_fn, and I think you could avoid a lo
| |
310 struct XRayTraceCapture* capture = g_xray_capture; | |
311 if (capture && capture->recording) { | |
312 uint32_t depth = capture->stack_depth; | |
313 if (depth < capture->max_stack_depth) { | |
314 struct XRayTraceStackEntry* se = &capture->stack[depth]; | |
315 uint32_t addr = (uint32_t)fname; | |
316 se->depth_addr = XRAY_PACK_DEPTH_ADDR(depth, addr); | |
317 se->dest = capture->buffer_index; | |
318 se->annotation_index = 0; | |
319 GTSC(se->tsc); | |
320 capture->buffer_index = | |
321 XRayTraceIncrementIndexInline(capture, capture->buffer_index); | |
322 } | |
323 ++capture->stack_depth; | |
324 } | |
325 } | |
326 | |
327 | |
328 /* Main profile capture function that is called at the exit of */ | |
329 /* every instrumented function. This function is implicity called */ | |
330 /* when the code is compiled with the -finstrument-functions option */ | |
331 void __pnacl_profile_func_exit(const char* fname) { | |
332 struct XRayTraceCapture* capture = g_xray_capture; | |
333 if (capture && capture->recording) { | |
334 --capture->stack_depth; | |
335 if (capture->stack_depth < capture->max_stack_depth) { | |
336 uint32_t depth = capture->stack_depth; | |
337 struct XRayTraceStackEntry* se = &capture->stack[depth]; | |
338 uint32_t buffer_index = se->dest; | |
339 uint64_t tsc; | |
340 struct XRayTraceBufferEntry* be = &capture->buffer[buffer_index]; | |
341 GTSC(tsc); | |
342 be->depth_addr = se->depth_addr; | |
343 be->start_tick = se->tsc; | |
344 be->end_tick = tsc; | |
345 be->annotation_index = 0; | |
346 if (0 != se->annotation_index) | |
347 __xray_profile_append_annotation(capture, se, be); | |
348 } | |
349 } | |
350 } | |
351 #else | |
352 /* Main profile capture function that is called at the start */ | |
353 /* of every instrumented function. This function is implicitly */ | |
354 /* called when code is compilied with the -finstrument-functions option */ | |
310 void __cyg_profile_func_enter(void* this_fn, void* call_site) { | 355 void __cyg_profile_func_enter(void* this_fn, void* call_site) { |
311 struct XRayTraceCapture* capture = g_xray_capture; | 356 struct XRayTraceCapture* capture = g_xray_capture; |
312 if (capture && capture->recording) { | 357 if (capture && capture->recording) { |
313 uint32_t depth = capture->stack_depth; | 358 uint32_t depth = capture->stack_depth; |
314 if (depth < capture->max_stack_depth) { | 359 if (depth < capture->max_stack_depth) { |
315 struct XRayTraceStackEntry* se = &capture->stack[depth]; | 360 struct XRayTraceStackEntry* se = &capture->stack[depth]; |
316 uint32_t addr = (uint32_t)this_fn; | 361 uint32_t addr = (uint32_t)this_fn; |
317 se->depth_addr = XRAY_PACK_DEPTH_ADDR(depth, addr); | 362 se->depth_addr = XRAY_PACK_DEPTH_ADDR(depth, addr); |
318 se->dest = capture->buffer_index; | 363 se->dest = capture->buffer_index; |
319 se->annotation_index = 0; | 364 se->annotation_index = 0; |
(...skipping 22 matching lines...) Expand all Loading... | |
342 GTSC(tsc); | 387 GTSC(tsc); |
343 be->depth_addr = se->depth_addr; | 388 be->depth_addr = se->depth_addr; |
344 be->start_tick = se->tsc; | 389 be->start_tick = se->tsc; |
345 be->end_tick = tsc; | 390 be->end_tick = tsc; |
346 be->annotation_index = 0; | 391 be->annotation_index = 0; |
347 if (0 != se->annotation_index) | 392 if (0 != se->annotation_index) |
348 __xray_profile_append_annotation(capture, se, be); | 393 __xray_profile_append_annotation(capture, se, be); |
349 } | 394 } |
350 } | 395 } |
351 } | 396 } |
397 #endif // __pnacl__ | |
nfullagar1
2013/07/17 00:53:19
above: /* __pnacl__ */
/* c style comment */
grosse
2013/07/17 19:37:56
Done.
| |
398 | |
399 | |
400 void XRayGetTSC(uint64_t* tsc) {GTSC(*tsc);} | |
401 | |
402 struct XrayTimestampPair* XRayGetStartTimestamp( | |
403 struct XRayTraceCapture* capture) | |
404 { | |
405 assert(capture->start_time_initialized); | |
406 return &capture->start_time; | |
407 } | |
352 | 408 |
353 | 409 |
354 /* Special case appending annotation string to trace buffer */ | 410 /* Special case appending annotation string to trace buffer */ |
355 /* this function should only ever be called from __cyg_profile_func_exit() */ | 411 /* this function should only ever be called from __cyg_profile_func_exit() */ |
356 void __xray_profile_append_annotation(struct XRayTraceCapture* capture, | 412 void __xray_profile_append_annotation(struct XRayTraceCapture* capture, |
357 struct XRayTraceStackEntry* se, | 413 struct XRayTraceStackEntry* se, |
358 struct XRayTraceBufferEntry* be) { | 414 struct XRayTraceBufferEntry* be) { |
359 struct XRayTraceStackEntry* parent = se - 1; | 415 struct XRayTraceStackEntry* parent = se - 1; |
360 int start = parent->annotation_index; | 416 int start = parent->annotation_index; |
361 be->annotation_index = capture->buffer_index; | 417 be->annotation_index = capture->buffer_index; |
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
566 /* The trace stack[0] is reserved */ | 622 /* The trace stack[0] is reserved */ |
567 memset(&capture->stack[0], 0, sizeof(capture->stack[0])); | 623 memset(&capture->stack[0], 0, sizeof(capture->stack[0])); |
568 /* Annotation index 0 is reserved to indicate no annotation */ | 624 /* Annotation index 0 is reserved to indicate no annotation */ |
569 capture->stack[0].annotation_index = 1; | 625 capture->stack[0].annotation_index = 1; |
570 capture->annotation[0] = 0; | 626 capture->annotation[0] = 0; |
571 capture->annotation[1] = 0; | 627 capture->annotation[1] = 0; |
572 capture->annotation_count = 0; | 628 capture->annotation_count = 0; |
573 capture->recording = true; | 629 capture->recording = true; |
574 GTSC(capture->frame.entry[i].start_tsc); | 630 GTSC(capture->frame.entry[i].start_tsc); |
575 g_xray_capture = capture; | 631 g_xray_capture = capture; |
632 | |
633 #ifndef XRAY_NOPEPPER | |
nfullagar1
2013/07/17 00:53:19
XRAY_DISABLE_BROWSER_INTEGRATION (here & elsewher
grosse
2013/07/17 19:37:56
Done.
| |
634 if (!capture->start_time_initialized) { | |
635 capture->start_time = XRayPepperBeginCalibration(); | |
nfullagar1
2013/07/17 00:53:19
XRayBrowserBeginCalibration ?
| |
636 capture->start_time_initialized = true; | |
637 } | |
638 #endif /* XRAY_NOPEPPER */ | |
nfullagar1
2013/07/17 00:53:19
I think the above may be better if this was done f
| |
639 | |
576 } | 640 } |
577 | 641 |
578 | 642 |
579 /* Ends a frame and disables capturing. Advances to the next frame. */ | 643 /* Ends a frame and disables capturing. Advances to the next frame. */ |
580 /* Must be paired with XRayStartFrame(), and called from the same thread. */ | 644 /* Must be paired with XRayStartFrame(), and called from the same thread. */ |
581 void XRayEndFrame(struct XRayTraceCapture* capture) { | 645 void XRayEndFrame(struct XRayTraceCapture* capture) { |
582 int i; | 646 int i; |
583 assert(capture); | 647 assert(capture); |
584 assert(capture->initialized); | 648 assert(capture->initialized); |
585 assert(capture->recording); | 649 assert(capture->recording); |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
683 capture->frame.head = 0; | 747 capture->frame.head = 0; |
684 capture->frame.tail = 0; | 748 capture->frame.tail = 0; |
685 capture->disabled = 0; | 749 capture->disabled = 0; |
686 capture->annotation_filter = 0xFFFFFFFF; | 750 capture->annotation_filter = 0xFFFFFFFF; |
687 capture->guard0 = XRAY_GUARD_VALUE_0x12345678; | 751 capture->guard0 = XRAY_GUARD_VALUE_0x12345678; |
688 capture->guard1 = XRAY_GUARD_VALUE_0x12345678; | 752 capture->guard1 = XRAY_GUARD_VALUE_0x12345678; |
689 capture->guard2 = XRAY_GUARD_VALUE_0x87654321; | 753 capture->guard2 = XRAY_GUARD_VALUE_0x87654321; |
690 capture->guard3 = XRAY_GUARD_VALUE_0x12345678; | 754 capture->guard3 = XRAY_GUARD_VALUE_0x12345678; |
691 capture->initialized = true; | 755 capture->initialized = true; |
692 capture->recording = false; | 756 capture->recording = false; |
757 capture->start_time_initialized = false; | |
693 XRaySetMaxStackDepth(capture, stack_depth); | 758 XRaySetMaxStackDepth(capture, stack_depth); |
694 XRayReset(capture); | 759 XRayReset(capture); |
695 | 760 |
696 /* Mapfile is optional; we don't need it for captures, only for reports. */ | 761 /* Mapfile is optional; we don't need it for captures, only for reports. */ |
697 capture->symbols = | 762 capture->symbols = |
698 XRaySymbolTableCreate(XRAY_DEFAULT_SYMBOL_TABLE_SIZE); | 763 XRaySymbolTableCreate(XRAY_DEFAULT_SYMBOL_TABLE_SIZE); |
699 if (NULL != mapfilename) | 764 if (NULL != mapfilename) |
700 XRaySymbolTableParseMapfile(capture->symbols, mapfilename); | 765 XRaySymbolTableParseMapfile(capture->symbols, mapfilename); |
701 | 766 |
702 return capture; | 767 return capture; |
703 } | 768 } |
704 | 769 |
705 | 770 |
706 /* Shut down and free memory used by XRay. */ | 771 /* Shut down and free memory used by XRay. */ |
707 void XRayShutdown(struct XRayTraceCapture* capture) { | 772 void XRayShutdown(struct XRayTraceCapture* capture) { |
708 assert(capture); | 773 assert(capture); |
709 assert(capture->initialized); | 774 assert(capture->initialized); |
710 assert(!capture->recording); | 775 assert(!capture->recording); |
711 XRayCheckGuards(capture); | 776 XRayCheckGuards(capture); |
712 if (NULL != capture->symbols) { | 777 if (NULL != capture->symbols) { |
713 XRaySymbolTableFree(capture->symbols); | 778 XRaySymbolTableFree(capture->symbols); |
714 } | 779 } |
715 XRayFree(capture->frame.entry); | 780 XRayFree(capture->frame.entry); |
716 XRayFree(capture->buffer); | 781 XRayFree(capture->buffer); |
717 capture->initialized = false; | 782 capture->initialized = false; |
718 XRayFree(capture); | 783 XRayFree(capture); |
719 } | 784 } |
720 | 785 |
721 #endif /* XRAY */ | 786 #endif /* XRAY */ |
OLD | NEW |