| // Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file | 
 | // for details. All rights reserved. Use of this source code is governed by a | 
 | // BSD-style license that can be found in the LICENSE file. | 
 |  | 
 | #ifndef RUNTIME_VM_LOG_H_ | 
 | #define RUNTIME_VM_LOG_H_ | 
 |  | 
 | #include "vm/allocation.h" | 
 | #include "vm/growable_array.h" | 
 | #include "vm/os.h" | 
 |  | 
 | namespace dart { | 
 |  | 
 | class IsolateGroup; | 
 | class LogBlock; | 
 |  | 
 | #if defined(_MSC_VER) | 
 | #define THR_Print(format, ...) Log::Current()->Print(format, __VA_ARGS__) | 
 | #else | 
 | #define THR_Print(format, ...) Log::Current()->Print(format, ##__VA_ARGS__) | 
 | #endif | 
 |  | 
 | #define THR_VPrint(format, args) Log::Current()->VPrint(format, args) | 
 |  | 
 | typedef void (*LogPrinter)(const char* data); | 
 |  | 
 | class Log { | 
 |  public: | 
 |   explicit Log(LogPrinter printer = nullptr); | 
 |   ~Log(); | 
 |  | 
 |   static Log* Current(); | 
 |  | 
 |   // Append a formatted string to the log. | 
 |   void Print(const char* format, ...) PRINTF_ATTRIBUTE(2, 3); | 
 |  | 
 |   void VPrint(const char* format, va_list args); | 
 |  | 
 |   // Flush and truncate the log. The log is flushed starting at cursor | 
 |   // and truncated to cursor afterwards. | 
 |   void Flush(const intptr_t cursor = 0); | 
 |  | 
 |   // Clears the log. | 
 |   void Clear(); | 
 |  | 
 |   // Current cursor. | 
 |   intptr_t cursor() const; | 
 |  | 
 |   // A logger that does nothing. | 
 |   static Log* NoOpLog(); | 
 |  | 
 |  private: | 
 |   void TerminateString(); | 
 |   void EnableManualFlush(); | 
 |   void DisableManualFlush(const intptr_t cursor); | 
 |  | 
 |   // Returns true when flush is required. | 
 |   bool ShouldFlush() const; | 
 |  | 
 |   // Returns false if we should drop log messages related to 'isolate'. | 
 |   static bool ShouldLogForIsolateGroup(const IsolateGroup* isolate); | 
 |  | 
 |   static Log noop_log_; | 
 |   LogPrinter printer_; | 
 |   intptr_t manual_flush_; | 
 |   MallocGrowableArray<char> buffer_; | 
 |  | 
 |   friend class LogBlock; | 
 |   friend class LogTestHelper; | 
 |   DISALLOW_COPY_AND_ASSIGN(Log); | 
 | }; | 
 |  | 
 | // Causes all log messages to be buffered until destructor is called. | 
 | // Can be nested. | 
 | class LogBlock : public StackResource { | 
 |  public: | 
 |   LogBlock(ThreadState* thread, Log* log) | 
 |       : StackResource(thread), log_(log), cursor_(log->cursor()) { | 
 |     Initialize(); | 
 |   } | 
 |  | 
 |   LogBlock() | 
 |       : StackResource(ThreadState::Current()), | 
 |         log_(Log::Current()), | 
 |         cursor_(Log::Current()->cursor()) { | 
 |     Initialize(); | 
 |   } | 
 |  | 
 |   ~LogBlock(); | 
 |  | 
 |  private: | 
 |   void Initialize(); | 
 |  | 
 |   Log* const log_; | 
 |   const intptr_t cursor_; | 
 | }; | 
 |  | 
 | }  // namespace dart | 
 |  | 
 | #endif  // RUNTIME_VM_LOG_H_ |