1 | // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file |
2 | // for details. All rights reserved. Use of this source code is governed by a |
3 | // BSD-style license that can be found in the LICENSE file. |
4 | |
5 | #ifndef RUNTIME_VM_LOG_H_ |
6 | #define RUNTIME_VM_LOG_H_ |
7 | |
8 | #include "vm/allocation.h" |
9 | #include "vm/growable_array.h" |
10 | #include "vm/os.h" |
11 | |
12 | namespace dart { |
13 | |
14 | class IsolateGroup; |
15 | class LogBlock; |
16 | |
17 | #if defined(_MSC_VER) |
18 | #define THR_Print(format, ...) Log::Current()->Print(format, __VA_ARGS__) |
19 | #else |
20 | #define THR_Print(format, ...) Log::Current()->Print(format, ##__VA_ARGS__) |
21 | #endif |
22 | |
23 | #define THR_VPrint(format, args) Log::Current()->VPrint(format, args) |
24 | |
25 | typedef void (*LogPrinter)(const char* str, ...) PRINTF_ATTRIBUTE(1, 2); |
26 | |
27 | class Log { |
28 | public: |
29 | explicit Log(LogPrinter printer = OS::PrintErr); |
30 | ~Log(); |
31 | |
32 | static Log* Current(); |
33 | |
34 | // Append a formatted string to the log. |
35 | void Print(const char* format, ...) PRINTF_ATTRIBUTE(2, 3); |
36 | |
37 | void VPrint(const char* format, va_list args); |
38 | |
39 | // Flush and truncate the log. The log is flushed starting at cursor |
40 | // and truncated to cursor afterwards. |
41 | void Flush(const intptr_t cursor = 0); |
42 | |
43 | // Clears the log. |
44 | void Clear(); |
45 | |
46 | // Current cursor. |
47 | intptr_t cursor() const; |
48 | |
49 | // A logger that does nothing. |
50 | static Log* NoOpLog(); |
51 | |
52 | private: |
53 | void TerminateString(); |
54 | void EnableManualFlush(); |
55 | void DisableManualFlush(const intptr_t cursor); |
56 | |
57 | // Returns true when flush is required. |
58 | bool ShouldFlush() const; |
59 | |
60 | // Returns false if we should drop log messages related to 'isolate'. |
61 | static bool ShouldLogForIsolateGroup(const IsolateGroup* isolate); |
62 | |
63 | static Log noop_log_; |
64 | LogPrinter printer_; |
65 | intptr_t manual_flush_; |
66 | MallocGrowableArray<char> buffer_; |
67 | |
68 | friend class LogBlock; |
69 | friend class LogTestHelper; |
70 | DISALLOW_COPY_AND_ASSIGN(Log); |
71 | }; |
72 | |
73 | // Causes all log messages to be buffered until destructor is called. |
74 | // Can be nested. |
75 | class LogBlock : public StackResource { |
76 | public: |
77 | LogBlock(ThreadState* thread, Log* log) |
78 | : StackResource(thread), log_(log), cursor_(log->cursor()) { |
79 | Initialize(); |
80 | } |
81 | |
82 | LogBlock() |
83 | : StackResource(ThreadState::Current()), |
84 | log_(Log::Current()), |
85 | cursor_(Log::Current()->cursor()) { |
86 | Initialize(); |
87 | } |
88 | |
89 | ~LogBlock(); |
90 | |
91 | private: |
92 | void Initialize(); |
93 | |
94 | Log* const log_; |
95 | const intptr_t cursor_; |
96 | }; |
97 | |
98 | } // namespace dart |
99 | |
100 | #endif // RUNTIME_VM_LOG_H_ |
101 | |