Output.h 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. //-------------------------------------------------------------------------------------------------------
  2. // Copyright (C) Microsoft. All rights reserved.
  3. // Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
  4. //-------------------------------------------------------------------------------------------------------
  5. #pragma once
  6. // xplat-todo: error: ISO C++ forbids forward references to 'enum' types
  7. #if defined(ENABLE_TRACE)
  8. namespace Js
  9. {
  10. enum Flag: unsigned short;
  11. enum Phase: unsigned short;
  12. };
  13. #endif
  14. #if defined(ENABLE_DEBUG_CONFIG_OPTIONS) && defined(BGJIT_STATS)
  15. #define OUTPUT_TRACE(Phase, ...) Output::Trace((Phase), __VA_ARGS__)
  16. #define OUTPUT_TRACE_2(Phase, ...) Output::Trace2((Phase), __VA_ARGS__)
  17. #define OUTPUT_VERBOSE_TRACE(Phase, ...) \
  18. if(Js::Configuration::Global.flags.Verbose) \
  19. { \
  20. OUTPUT_TRACE((Phase), __VA_ARGS__); \
  21. }
  22. #define OUTPUT_STATS(Phase, ...) Output::TraceStats((Phase), __VA_ARGS__)
  23. #define OUTPUT_VERBOSE_STATS(Phase, ...) \
  24. if(Js::Configuration::Global.flags.Verbose) \
  25. { \
  26. OUTPUT_STATS((Phase), __VA_ARGS__); \
  27. }
  28. #define OUTPUT_FLUSH() Output::Flush()
  29. #else
  30. #define OUTPUT_TRACE(Phase, ...)
  31. #define OUTPUT_TRACE_2(Phase, ...)
  32. #define OUTPUT_VERBOSE_TRACE(Phase, ...)
  33. #define OUTPUT_STATS(Phase, ...)
  34. #define OUTPUT_VERBOSE_STATS(Phase, ...)
  35. #define OUTPUT_FLUSH()
  36. #endif
  37. #if DBG
  38. #define OUTPUT_TRACE_DEBUGONLY_ENABLED 1
  39. #define OUTPUT_TRACE_DEBUGONLY(Phase, ...) Output::TraceWithFlush((Phase), __VA_ARGS__)
  40. #define OUTPUT_TRACE_DEBUGONLY(Flag, ...) Output::TraceWithFlush((Flag), __VA_ARGS__)
  41. #else
  42. #define OUTPUT_TRACE_DEBUGONLY(Phase, ...)
  43. #define OUTPUT_TRACE_FLAG_DEBUGONLY(Flag, ...)
  44. #endif
  45. namespace Js
  46. {
  47. // Logging interfaces:
  48. // decouple implementation so that in common.lib we don't have dependency on memory.lib
  49. struct ILogger
  50. {
  51. virtual void Write(const char16* msg) = 0;
  52. };
  53. #ifdef STACK_BACK_TRACE
  54. struct IStackTraceHelper
  55. {
  56. virtual size_t PrintStackTrace(ULONG framesToSkip, ULONG framesToCapture) = 0; // Returns # of chars printed.
  57. virtual ULONG GetStackTrace(ULONG framesToSkip, ULONG framesToCapture, void** stackFrames) = 0; // Returns # of frames captured.
  58. };
  59. #endif
  60. } // namespace Js.
  61. class Output
  62. {
  63. public:
  64. static size_t __cdecl VerboseNote(const char16 * format, ...);
  65. #ifdef ENABLE_TRACE
  66. static size_t __cdecl Trace(Js::Phase phase, const char16 *form, ...);
  67. static size_t __cdecl Trace2(Js::Phase phase, const char16 *form, ...);
  68. static size_t __cdecl TraceWithPrefix(Js::Phase phase, const char16 prefix[], const char16 *form, ...);
  69. static size_t __cdecl TraceWithFlush(Js::Phase phase, const char16 *form, ...);
  70. static size_t __cdecl TraceWithFlush(Js::Flag flag, const char16 *form, ...);
  71. static size_t __cdecl TraceStats(Js::Phase phase, const char16 *form, ...);
  72. template<class Fn>
  73. static size_t __cdecl
  74. TraceWithCallback(Js::Phase phase, Fn callback, const char16 *form, ...)
  75. {
  76. size_t retValue = 0;
  77. if(Js::Configuration::Global.flags.Trace.IsEnabled(phase))
  78. {
  79. va_list argptr;
  80. va_start(argptr, form);
  81. retValue = Output::Print(_u("%s:"), Js::PhaseNames[static_cast<int>(phase)]);
  82. retValue += Output::VPrint(form, argptr);
  83. retValue += Output::Print(_u("%s"), callback());
  84. va_end(argptr);
  85. }
  86. return retValue;
  87. }
  88. static void SetInMemoryLogger(Js::ILogger* logger);
  89. #ifdef STACK_BACK_TRACE
  90. static void SetStackTraceHelper(Js::IStackTraceHelper* helper);
  91. #endif
  92. #endif // ENABLE_TRACE
  93. static size_t __cdecl Print(const char16 *form, ...);
  94. static size_t __cdecl Print(int column, const char16 *form, ...);
  95. static size_t __cdecl PrintBuffer(const char16 * buffer, size_t size);
  96. static size_t __cdecl VPrint(const char16 *form, va_list argptr);
  97. static void SkipToColumn(size_t column);
  98. static FILE* SetFile(FILE *);
  99. static FILE* GetFile();
  100. static void SetOutputFile(FILE *);
  101. static FILE* GetOutputFile();
  102. static void UseDebuggerWindow() { s_useDebuggerWindow = true; }
  103. static void Flush();
  104. static WORD SetConsoleForeground(WORD color);
  105. static void CaptureStart();
  106. static char16* CaptureEnd();
  107. private:
  108. static void DirectPrint(const char16 * string);
  109. static AutoFILE s_outputFile;
  110. static bool s_useDebuggerWindow;
  111. static CriticalSection s_critsect;
  112. #ifdef ENABLE_TRACE
  113. static Js::ILogger* s_inMemoryLogger; // Used to trace into memory so that when process crashes, you can see tracing in crash dump file.
  114. static unsigned int s_traceEntryId; // Sequential id of trace entry for rich output format.
  115. #ifdef STACK_BACK_TRACE
  116. static Js::IStackTraceHelper* s_stackTraceHelper; // Used for capturing stack trace.
  117. #endif
  118. static size_t VTrace(const char16* shortPrefixFormat, const char16* prefix, const char16 *form, va_list argptr);
  119. #endif // ENABLE_TRACE
  120. #define THREAD_ST THREAD_LOCAL
  121. THREAD_ST static bool s_capture;
  122. THREAD_ST static FILE * s_file;
  123. #ifdef _WIN32
  124. THREAD_ST static char16 * buffer;
  125. THREAD_ST static size_t bufferFreeSize;
  126. THREAD_ST static size_t bufferAllocSize;
  127. #endif
  128. THREAD_ST static size_t s_Column;
  129. THREAD_ST static WORD s_color;
  130. THREAD_ST static bool s_hasColor;
  131. };