111
112 bool should_log() {
113 // Don't bother adding new entries when we're crashing. This also
114 // avoids mutating the ring buffer when printing the log.
115 return !VMError::fatal_error_in_progress();
116 }
117
118 // Print the contents of the log
119 void print_log_on(outputStream* out);
120
121 private:
122 void print_log_impl(outputStream* out);
123
124 // Print a single element. A templated implementation might need to
125 // be declared by subclasses.
126 void print(outputStream* out, T& e);
127
128 void print(outputStream* out, EventRecord<T>& e) {
129 out->print("Event: %.3f ", e.timestamp);
130 if (e.thread != NULL) {
131 out->print("Thread " INTPTR_FORMAT " ", e.thread);
132 }
133 print(out, e.data);
134 }
135 };
136
137 // A simple wrapper class for fixed size text messages.
138 class StringLogMessage : public FormatBuffer<256> {
139 public:
140 // Wrap this buffer in a stringStream.
141 stringStream stream() {
142 return stringStream(_buf, size());
143 }
144 };
145
146 // A simple ring buffer of fixed size text messages.
147 class StringEventLog : public EventLogBase<StringLogMessage> {
148 public:
149 StringEventLog(const char* name, int count = LogEventsBufferEntries) : EventLogBase<StringLogMessage>(name, count) {}
150
151 void logv(Thread* thread, const char* format, va_list ap) {
152 if (!should_log()) return;
153
154 double timestamp = fetch_timestamp();
155 MutexLockerEx ml(&_mutex, Mutex::_no_safepoint_check_flag);
156 int index = compute_log_index();
157 _records[index].thread = thread;
158 _records[index].timestamp = timestamp;
159 _records[index].data.printv(format, ap);
160 }
161
162 void log(Thread* thread, const char* format, ...) {
163 va_list ap;
164 va_start(ap, format);
165 logv(thread, format, ap);
166 va_end(ap);
167 }
168
169 };
170
171
172
173 class Events : AllStatic {
174 friend class EventLog;
175
176 private:
177 static EventLog* _logs;
178
179 // A log for generic messages that aren't well categorized.
180 static StringEventLog* _messages;
181
182 // A log for internal exception related messages, like internal
183 // throws and implicit exceptions.
184 static StringEventLog* _exceptions;
185
186 // Deoptization related messages
187 static StringEventLog* _deopt_messages;
188
189 public:
190 static void print_all(outputStream* out);
191
192 // Dump all events to the tty
193 static void print();
194
195 // Logs a generic message with timestamp and format as printf.
196 static void log(Thread* thread, const char* format, ...);
197
198 // Log exception related message
199 static void log_exception(Thread* thread, const char* format, ...);
200
201 static void log_deopt_message(Thread* thread, const char* format, ...);
202
203 // Register default loggers
204 static void init();
205 };
206
207
208 inline void Events::log(Thread* thread, const char* format, ...) {
209 if (LogEvents) {
210 va_list ap;
211 va_start(ap, format);
212 _messages->logv(thread, format, ap);
213 va_end(ap);
214 }
215 }
216
217 inline void Events::log_exception(Thread* thread, const char* format, ...) {
218 if (LogEvents) {
219 va_list ap;
220 va_start(ap, format);
221 _exceptions->logv(thread, format, ap);
222 va_end(ap);
223 }
224 }
225
226 inline void Events::log_deopt_message(Thread* thread, const char* format, ...) {
227 if (LogEvents) {
266 print(out, _records[i]);
267 }
268 }
269 out->cr();
270 }
271
272 // Implement a printing routine for the StringLogMessage
273 template <>
274 inline void EventLogBase<StringLogMessage>::print(outputStream* out, StringLogMessage& lm) {
275 out->print_raw(lm);
276 out->cr();
277 }
278
279 // Place markers for the beginning and end up of a set of events.
280 // These end up in the default log.
281 class EventMark : public StackObj {
282 StringLogMessage _buffer;
283
284 public:
285 // log a begin event, format as printf
286 EventMark(const char* format, ...);
287 // log an end event
288 ~EventMark();
289 };
290
291 #endif // SHARE_VM_UTILITIES_EVENTS_HPP
|
111
112 bool should_log() {
113 // Don't bother adding new entries when we're crashing. This also
114 // avoids mutating the ring buffer when printing the log.
115 return !VMError::fatal_error_in_progress();
116 }
117
118 // Print the contents of the log
119 void print_log_on(outputStream* out);
120
121 private:
122 void print_log_impl(outputStream* out);
123
124 // Print a single element. A templated implementation might need to
125 // be declared by subclasses.
126 void print(outputStream* out, T& e);
127
128 void print(outputStream* out, EventRecord<T>& e) {
129 out->print("Event: %.3f ", e.timestamp);
130 if (e.thread != NULL) {
131 out->print("Thread " INTPTR_FORMAT " ", p2i(e.thread));
132 }
133 print(out, e.data);
134 }
135 };
136
137 // A simple wrapper class for fixed size text messages.
138 class StringLogMessage : public FormatBuffer<256> {
139 public:
140 // Wrap this buffer in a stringStream.
141 stringStream stream() {
142 return stringStream(_buf, size());
143 }
144 };
145
146 // A simple ring buffer of fixed size text messages.
147 class StringEventLog : public EventLogBase<StringLogMessage> {
148 public:
149 StringEventLog(const char* name, int count = LogEventsBufferEntries) : EventLogBase<StringLogMessage>(name, count) {}
150
151 void logv(Thread* thread, const char* format, va_list ap) {
152 if (!should_log()) return;
153
154 double timestamp = fetch_timestamp();
155 MutexLockerEx ml(&_mutex, Mutex::_no_safepoint_check_flag);
156 int index = compute_log_index();
157 _records[index].thread = thread;
158 _records[index].timestamp = timestamp;
159 _records[index].data.printv(format, ap);
160 }
161
162 void log(Thread* thread, const char* format, ...) ATTRIBUTE_PRINTF(3, 4) {
163 va_list ap;
164 va_start(ap, format);
165 logv(thread, format, ap);
166 va_end(ap);
167 }
168
169 };
170
171
172
173 class Events : AllStatic {
174 friend class EventLog;
175
176 private:
177 static EventLog* _logs;
178
179 // A log for generic messages that aren't well categorized.
180 static StringEventLog* _messages;
181
182 // A log for internal exception related messages, like internal
183 // throws and implicit exceptions.
184 static StringEventLog* _exceptions;
185
186 // Deoptization related messages
187 static StringEventLog* _deopt_messages;
188
189 public:
190 static void print_all(outputStream* out);
191
192 // Dump all events to the tty
193 static void print();
194
195 // Logs a generic message with timestamp and format as printf.
196 static void log(Thread* thread, const char* format, ...) ATTRIBUTE_PRINTF(2, 3);
197
198 // Log exception related message
199 static void log_exception(Thread* thread, const char* format, ...) ATTRIBUTE_PRINTF(2, 3);
200
201 static void log_deopt_message(Thread* thread, const char* format, ...) ATTRIBUTE_PRINTF(2, 3);
202
203 // Register default loggers
204 static void init();
205 };
206
207 inline void Events::log(Thread* thread, const char* format, ...) {
208 if (LogEvents) {
209 va_list ap;
210 va_start(ap, format);
211 _messages->logv(thread, format, ap);
212 va_end(ap);
213 }
214 }
215
216 inline void Events::log_exception(Thread* thread, const char* format, ...) {
217 if (LogEvents) {
218 va_list ap;
219 va_start(ap, format);
220 _exceptions->logv(thread, format, ap);
221 va_end(ap);
222 }
223 }
224
225 inline void Events::log_deopt_message(Thread* thread, const char* format, ...) {
226 if (LogEvents) {
265 print(out, _records[i]);
266 }
267 }
268 out->cr();
269 }
270
271 // Implement a printing routine for the StringLogMessage
272 template <>
273 inline void EventLogBase<StringLogMessage>::print(outputStream* out, StringLogMessage& lm) {
274 out->print_raw(lm);
275 out->cr();
276 }
277
278 // Place markers for the beginning and end up of a set of events.
279 // These end up in the default log.
280 class EventMark : public StackObj {
281 StringLogMessage _buffer;
282
283 public:
284 // log a begin event, format as printf
285 EventMark(const char* format, ...) ATTRIBUTE_PRINTF(2, 3);
286 // log an end event
287 ~EventMark();
288 };
289
290 #endif // SHARE_VM_UTILITIES_EVENTS_HPP
|