151 void logv(Thread* thread, const char* format, va_list ap) ATTRIBUTE_PRINTF(3, 0) { 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 // Redefinition related messages 190 static StringEventLog* _redefinitions; 191 272 print(out, _records[i]); 273 } 274 } else { 275 for (int i = _index; i < _length; i++) { 276 print(out, _records[i]); 277 } 278 for (int i = 0; i < _index; i++) { 279 print(out, _records[i]); 280 } 281 } 282 out->cr(); 283 } 284 285 // Implement a printing routine for the StringLogMessage 286 template <> 287 inline void EventLogBase<StringLogMessage>::print(outputStream* out, StringLogMessage& lm) { 288 out->print_raw(lm); 289 out->cr(); 290 } 291 292 // Place markers for the beginning and end up of a set of events. 293 // These end up in the default log. 294 class EventMark : public StackObj { 295 StringLogMessage _buffer; 296 297 public: 298 // log a begin event, format as printf 299 EventMark(const char* format, ...) ATTRIBUTE_PRINTF(2, 3); 300 // log an end event 301 ~EventMark(); 302 }; 303 304 #endif // SHARE_VM_UTILITIES_EVENTS_HPP | 151 void logv(Thread* thread, const char* format, va_list ap) ATTRIBUTE_PRINTF(3, 0) { 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 class GCLogMessage { 172 friend class EventLogBase<GCLogMessage>; 173 const static size_t GCLOG_MAX_BUFSIZE = 128; 174 char buf[GCLOG_MAX_BUFSIZE]; 175 size_t size; 176 177 public: 178 void write(const char* s, size_t len) { 179 size = MIN2(len, GCLOG_MAX_BUFSIZE - 1); 180 memcpy(buf, s, size); 181 } 182 }; 183 184 class GCLogEvent: public EventLogBase<GCLogMessage> { 185 private: 186 static uint _buffer_overflow_count; 187 188 public: 189 GCLogEvent(const char* name, int count = LogEventsBufferEntries) 190 : EventLogBase<GCLogMessage> (name, count) {} 191 192 void log(Thread* thread, const char* s, size_t len) { 193 if (!should_log()) return; 194 if (full()) { 195 _buffer_overflow_count++; 196 } 197 198 double timestamp = fetch_timestamp(); 199 int index = compute_log_index(); 200 _records[index].thread = thread; 201 _records[index].timestamp = timestamp; 202 _records[index].data.write(s, len); 203 } 204 205 bool full() const { 206 return _count >= _length; 207 } 208 209 bool empty() const { 210 return 0 == _count; 211 } 212 213 void reset() { 214 _index = _count = 0; 215 } 216 217 static uint buffer_overflow_count() { return _buffer_overflow_count; } 218 }; 219 220 class Events : AllStatic { 221 friend class EventLog; 222 223 private: 224 static EventLog* _logs; 225 226 // A log for generic messages that aren't well categorized. 227 static StringEventLog* _messages; 228 229 // A log for internal exception related messages, like internal 230 // throws and implicit exceptions. 231 static StringEventLog* _exceptions; 232 233 // Deoptization related messages 234 static StringEventLog* _deopt_messages; 235 236 // Redefinition related messages 237 static StringEventLog* _redefinitions; 238 319 print(out, _records[i]); 320 } 321 } else { 322 for (int i = _index; i < _length; i++) { 323 print(out, _records[i]); 324 } 325 for (int i = 0; i < _index; i++) { 326 print(out, _records[i]); 327 } 328 } 329 out->cr(); 330 } 331 332 // Implement a printing routine for the StringLogMessage 333 template <> 334 inline void EventLogBase<StringLogMessage>::print(outputStream* out, StringLogMessage& lm) { 335 out->print_raw(lm); 336 out->cr(); 337 } 338 339 template<> 340 inline void EventLogBase<GCLogMessage>::print(outputStream* out, GCLogMessage& lm) { 341 gcLogFileStream* gclog = static_cast<gcLogFileStream* >(out); 342 gclog->write_blocking(lm.buf, lm.size); 343 } 344 345 template <> 346 inline void EventLogBase<GCLogMessage>::print_log_impl(outputStream* out) { 347 if (_count == 0) { 348 return; 349 } 350 351 if (_count < _length) { 352 for (int i = 0; i < _count; i++) { 353 print(out, _records[i].data); 354 } 355 } else { 356 for (int i = _index; i < _length; i++) { 357 print(out, _records[i].data); 358 } 359 for (int i = 0; i < _index; i++) { 360 print(out, _records[i].data); 361 } 362 } 363 } 364 365 366 // Place markers for the beginning and end up of a set of events. 367 // These end up in the default log. 368 class EventMark : public StackObj { 369 StringLogMessage _buffer; 370 371 public: 372 // log a begin event, format as printf 373 EventMark(const char* format, ...) ATTRIBUTE_PRINTF(2, 3); 374 // log an end event 375 ~EventMark(); 376 }; 377 378 #endif // SHARE_VM_UTILITIES_EVENTS_HPP |