88 #define Log(...) LogImpl<LOG_TAGS(__VA_ARGS__)>
89
90 //
91 // Log class that embeds both log tags and a log level.
92 //
93 // The class provides a way to write the tags and log level once,
94 // so that redundant specification of tags or levels can be avoided.
95 //
96 // Example usage:
97 // LogTarget(Debug, gc) out;
98 // if (out.is_enabled()) {
99 // ...
100 // out.print("Worker: %u", i);
101 // out.print(" data: %d", x);
102 // ...
103 // print_stats(out.stream());
104 // }
105 //
106 #define LogTarget(level, ...) LogTargetImpl<LogLevel::level, LOG_TAGS(__VA_ARGS__)>
107
108 // Forward declaration to decouple this file from the outputStream API.
109 class outputStream;
110 outputStream* create_log_stream(LogLevelType level, LogTagSet* tagset);
111
112 template <LogLevelType level, LogTagType T0, LogTagType T1, LogTagType T2, LogTagType T3, LogTagType T4, LogTagType GuardTag>
113 class LogTargetImpl;
114
115 template <LogTagType T0, LogTagType T1 = LogTag::__NO_TAG, LogTagType T2 = LogTag::__NO_TAG, LogTagType T3 = LogTag::__NO_TAG,
116 LogTagType T4 = LogTag::__NO_TAG, LogTagType GuardTag = LogTag::__NO_TAG>
117 class LogImpl VALUE_OBJ_CLASS_SPEC {
118 private:
119 static const size_t LogBufferSize = 512;
120 public:
121 // Make sure no more than the maximum number of tags have been given.
122 // The GuardTag allows this to be detected if/when it happens. If the GuardTag
123 // is not __NO_TAG, the number of tags given exceeds the maximum allowed.
124 STATIC_ASSERT(GuardTag == LogTag::__NO_TAG); // Number of logging tags exceeds maximum supported!
125
126 // Empty constructor to avoid warnings on MSVC about unused variables
127 // when the log instance is only used for static functions.
128 LogImpl() {
129 }
130
131 static bool is_level(LogLevelType level) {
156 ATTRIBUTE_PRINTF(2, 0)
157 static void vwrite(LogLevelType level, const char* fmt, va_list args) {
158 LogTagSetMapping<T0, T1, T2, T3, T4>::tagset().vwrite(level, fmt, args);
159 }
160
161 #define LOG_LEVEL(level, name) ATTRIBUTE_PRINTF(2, 0) \
162 LogImpl& v##name(const char* fmt, va_list args) { \
163 vwrite(LogLevel::level, fmt, args); \
164 return *this; \
165 } \
166 LogImpl& name(const char* fmt, ...) ATTRIBUTE_PRINTF(2, 3) { \
167 va_list args; \
168 va_start(args, fmt); \
169 vwrite(LogLevel::level, fmt, args); \
170 va_end(args); \
171 return *this; \
172 } \
173 static bool is_##name() { \
174 return is_level(LogLevel::level); \
175 } \
176 static outputStream* name##_stream() { \
177 return create_log_stream(LogLevel::level, &LogTagSetMapping<T0, T1, T2, T3, T4>::tagset()); \
178 } \
179 static LogTargetImpl<LogLevel::level, T0, T1, T2, T3, T4, GuardTag>* name() { \
180 return (LogTargetImpl<LogLevel::level, T0, T1, T2, T3, T4, GuardTag>*)NULL; \
181 }
182 LOG_LEVEL_LIST
183 #undef LOG_LEVEL
184 };
185
186 // Combines logging tags and a logging level.
187 template <LogLevelType level, LogTagType T0, LogTagType T1 = LogTag::__NO_TAG, LogTagType T2 = LogTag::__NO_TAG,
188 LogTagType T3 = LogTag::__NO_TAG, LogTagType T4 = LogTag::__NO_TAG, LogTagType GuardTag = LogTag::__NO_TAG>
189 class LogTargetImpl {
190 public:
191 // Empty constructor to avoid warnings on MSVC about unused variables
192 // when the log instance is only used for static functions.
193 LogTargetImpl() {
194 }
195
196 static bool is_enabled() {
197 return LogImpl<T0, T1, T2, T3, T4, GuardTag>::is_level(level);
198 }
199
200 static void print(const char* fmt, ...) ATTRIBUTE_PRINTF(1, 2) {
201 va_list args;
202 va_start(args, fmt);
203 LogImpl<T0, T1, T2, T3, T4, GuardTag>::vwrite(level, fmt, args);
204 va_end(args);
205 }
206
207 static outputStream* stream() {
208 return create_log_stream(level, &LogTagSetMapping<T0, T1, T2, T3, T4>::tagset());
209 }
210 };
211
212 #endif // SHARE_VM_LOGGING_LOG_HPP
|
88 #define Log(...) LogImpl<LOG_TAGS(__VA_ARGS__)>
89
90 //
91 // Log class that embeds both log tags and a log level.
92 //
93 // The class provides a way to write the tags and log level once,
94 // so that redundant specification of tags or levels can be avoided.
95 //
96 // Example usage:
97 // LogTarget(Debug, gc) out;
98 // if (out.is_enabled()) {
99 // ...
100 // out.print("Worker: %u", i);
101 // out.print(" data: %d", x);
102 // ...
103 // print_stats(out.stream());
104 // }
105 //
106 #define LogTarget(level, ...) LogTargetImpl<LogLevel::level, LOG_TAGS(__VA_ARGS__)>
107
108 template <LogLevelType level, LogTagType T0, LogTagType T1, LogTagType T2, LogTagType T3, LogTagType T4, LogTagType GuardTag>
109 class LogTargetImpl;
110
111 template <LogTagType T0, LogTagType T1 = LogTag::__NO_TAG, LogTagType T2 = LogTag::__NO_TAG, LogTagType T3 = LogTag::__NO_TAG,
112 LogTagType T4 = LogTag::__NO_TAG, LogTagType GuardTag = LogTag::__NO_TAG>
113 class LogImpl VALUE_OBJ_CLASS_SPEC {
114 private:
115 static const size_t LogBufferSize = 512;
116 public:
117 // Make sure no more than the maximum number of tags have been given.
118 // The GuardTag allows this to be detected if/when it happens. If the GuardTag
119 // is not __NO_TAG, the number of tags given exceeds the maximum allowed.
120 STATIC_ASSERT(GuardTag == LogTag::__NO_TAG); // Number of logging tags exceeds maximum supported!
121
122 // Empty constructor to avoid warnings on MSVC about unused variables
123 // when the log instance is only used for static functions.
124 LogImpl() {
125 }
126
127 static bool is_level(LogLevelType level) {
152 ATTRIBUTE_PRINTF(2, 0)
153 static void vwrite(LogLevelType level, const char* fmt, va_list args) {
154 LogTagSetMapping<T0, T1, T2, T3, T4>::tagset().vwrite(level, fmt, args);
155 }
156
157 #define LOG_LEVEL(level, name) ATTRIBUTE_PRINTF(2, 0) \
158 LogImpl& v##name(const char* fmt, va_list args) { \
159 vwrite(LogLevel::level, fmt, args); \
160 return *this; \
161 } \
162 LogImpl& name(const char* fmt, ...) ATTRIBUTE_PRINTF(2, 3) { \
163 va_list args; \
164 va_start(args, fmt); \
165 vwrite(LogLevel::level, fmt, args); \
166 va_end(args); \
167 return *this; \
168 } \
169 static bool is_##name() { \
170 return is_level(LogLevel::level); \
171 } \
172 static LogTargetImpl<LogLevel::level, T0, T1, T2, T3, T4, GuardTag>* name() { \
173 return (LogTargetImpl<LogLevel::level, T0, T1, T2, T3, T4, GuardTag>*)NULL; \
174 }
175 LOG_LEVEL_LIST
176 #undef LOG_LEVEL
177 };
178
179 // Combines logging tags and a logging level.
180 template <LogLevelType level, LogTagType T0, LogTagType T1 = LogTag::__NO_TAG, LogTagType T2 = LogTag::__NO_TAG,
181 LogTagType T3 = LogTag::__NO_TAG, LogTagType T4 = LogTag::__NO_TAG, LogTagType GuardTag = LogTag::__NO_TAG>
182 class LogTargetImpl {
183 public:
184 // Empty constructor to avoid warnings on MSVC about unused variables
185 // when the log instance is only used for static functions.
186 LogTargetImpl() {
187 }
188
189 static bool is_enabled() {
190 return LogImpl<T0, T1, T2, T3, T4, GuardTag>::is_level(level);
191 }
192
193 static void print(const char* fmt, ...) ATTRIBUTE_PRINTF(1, 2) {
194 va_list args;
195 va_start(args, fmt);
196 LogImpl<T0, T1, T2, T3, T4, GuardTag>::vwrite(level, fmt, args);
197 va_end(args);
198 }
199
200 };
201
202 #endif // SHARE_VM_LOGGING_LOG_HPP
|