1 /*
   2  * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 #ifndef SHARE_VM_UTILITIES_EVENTS_HPP
  26 #define SHARE_VM_UTILITIES_EVENTS_HPP
  27 
  28 #include "memory/allocation.hpp"
  29 #include "runtime/mutexLocker.hpp"
  30 #include "runtime/thread.hpp"
  31 #include "utilities/top.hpp"
  32 #include "utilities/vmError.hpp"
  33 
  34 // Events and EventMark provide interfaces to log events taking place in the vm.
  35 // This facility is extremly useful for post-mortem debugging. The eventlog
  36 // often provides crucial information about events leading up to the crash.
  37 //
  38 // All arguments past the format string must be passed as an intptr_t.
  39 //
  40 // To log a single event use:
  41 //    Events::log("New nmethod has been created " INTPTR_FORMAT, nm);
  42 //
  43 // To log a block of events use:
  44 //    EventMark m("GarbageCollecting %d", (intptr_t)gc_number);
  45 //
  46 // The constructor to eventlog indents the eventlog until the
  47 // destructor has been executed.
  48 //
  49 // IMPLEMENTATION RESTRICTION:
  50 //   Max 3 arguments are saved for each logged event.
  51 //
  52 
  53 // The base event log dumping class that is registered for dumping at
  54 // crash time.  This is a very generic interface that is mainly here
  55 // for completeness.  Normally the templated EventLogBase would be
  56 // subclassed to provide different log types.
  57 class EventLog : public CHeapObj {
  58   friend class Events;
  59 
  60  private:
  61   EventLog* _next;
  62 
  63   EventLog* next() const { return _next; }
  64 
  65  public:
  66   // Automatically registers the log so that it will be printed during
  67   // crashes.
  68   EventLog();
  69 
  70   virtual void print_log_on(outputStream* out) = 0;
  71 };
  72 
  73 
  74 // A templated subclass of EventLog that provides basic ring buffer
  75 // functionality.  Most event loggers should subclass this, possibly
  76 // providing a more featureful log function if the existing copy
  77 // semantics aren't appropriate.  The name is used as the label of the
  78 // log when it is dumped during a crash.
  79 template <class T> class EventLogBase : public EventLog {
  80   template <class X> class EventRecord {
  81    public:
  82     jlong   timestamp;
  83     Thread* thread;
  84     X       data;
  85   };
  86 
  87  protected:
  88   Mutex           _mutex;
  89   const char*     _name;
  90   int             _length;
  91   int             _index;
  92   int             _count;
  93   EventRecord<T>* _records;
  94 
  95  public:
  96   EventLogBase<T>(const char* name, int length = LogEventsBufferEntries):
  97     _name(name),
  98     _length(length),
  99     _count(0),
 100     _index(0),
 101     _mutex(Mutex::event, name) {
 102     _records = new EventRecord<T>[length];
 103   }
 104 
 105   // move the ring buffer to next open slot and return the index of
 106   // the slot to use for the current message.  Should only be called
 107   // while mutex is held.
 108   int compute_log_index() {
 109     int index = _index;
 110     if (_count < _length) _count++;
 111     _index++;
 112     if (_index >= _length) _index = 0;
 113     return index;
 114   }
 115 
 116   bool should_log() {
 117     // Don't bother adding new entries when we're crashing.  This also
 118     // avoids mutating the ring buffer when printing the log.
 119     return !VMError::fatal_error_in_progress();
 120   }
 121 
 122   // Print the contents of the log
 123   void print_log_on(outputStream* out);
 124 
 125  private:
 126   void print_log_impl(outputStream* out);
 127 
 128   // Print a single element.  A templated implementation might need to
 129   // be declared by subclasses.
 130   void print(outputStream* out, T& e);
 131 
 132   void print(outputStream* out, EventRecord<T>& e) {
 133     out->print("Event: " INT64_FORMAT " ", e.timestamp);
 134     if (e.thread != NULL) {
 135       out->print("Thread " INTPTR_FORMAT " ", e.thread);
 136     }
 137     print(out, e.data);
 138   }
 139 };
 140 
 141 // A simple wrapper class for fixed size text messages.
 142 class StringLogMessage : public FormatBuffer<132> {
 143  public:
 144   // Wrap this buffer in a stringStream.
 145   stringStream stream() {
 146     return stringStream(_buf, sizeof(_buf));
 147   }
 148 };
 149 
 150 // A simple ring buffer of fixed size text messages.
 151 class StringEventLog : public EventLogBase<StringLogMessage> {
 152  public:
 153   StringEventLog(const char* name, int count = LogEventsBufferEntries) : EventLogBase<StringLogMessage>(name, count) {}
 154 
 155   void logv(Thread* thread, const char* format, va_list ap) {
 156     if (!should_log()) return;
 157 
 158     jlong timestamp = os::javaTimeNanos() / NANOSECS_PER_MILLISEC;
 159     MutexLockerEx ml(&_mutex, Mutex::_no_safepoint_check_flag);
 160     int index = compute_log_index();
 161     _records[index].thread = thread;
 162     _records[index].timestamp = timestamp;
 163     _records[index].data.printv(format, ap);
 164   }
 165 
 166   void log(Thread* thread, const char* format, ...) {
 167     va_list ap;
 168     va_start(ap, format);
 169     logv(thread, format, ap);
 170     va_end(ap);
 171   }
 172 
 173 };
 174 
 175 
 176 
 177 class Events : AllStatic {
 178   friend class EventLog;
 179 
 180  private:
 181   static EventLog* _logs;
 182 
 183   // A log for generic messages that aren't well categorized.
 184   static StringEventLog* _messages;
 185 
 186   // A log for internal exception related messages, like internal
 187   // throws and implicit exceptions.
 188   static StringEventLog* _exceptions;
 189 
 190   // Deoptization related messages
 191   static StringEventLog* _deopt_messages;
 192 
 193  public:
 194   static void print_all(outputStream* out);
 195 
 196   static void print() {
 197     print_all(tty);
 198   }
 199 
 200   // Logs a generic message with timestamp and format as printf.
 201   static void log(Thread* thread, const char* format, ...);
 202 
 203   // Log exception related message
 204   static void log_exception(Thread* thread, const char* format, ...);
 205 
 206   static void log_deopt_message(Thread* thread, const char* format, ...);
 207 
 208   // Register default loggers
 209   static void init();
 210 };
 211 
 212 
 213 inline void Events::log(Thread* thread, const char* format, ...) {
 214   if (LogEvents) {
 215     va_list ap;
 216     va_start(ap, format);
 217     _messages->logv(thread, format, ap);
 218     va_end(ap);
 219   }
 220 }
 221 
 222 inline void Events::log_exception(Thread* thread, const char* format, ...) {
 223   if (LogEvents) {
 224     va_list ap;
 225     va_start(ap, format);
 226     _exceptions->logv(thread, format, ap);
 227     va_end(ap);
 228   }
 229 }
 230 
 231 inline void Events::log_deopt_message(Thread* thread, const char* format, ...) {
 232   if (LogEvents) {
 233     va_list ap;
 234     va_start(ap, format);
 235     _deopt_messages->logv(thread, format, ap);
 236     va_end(ap);
 237   }
 238 }
 239 
 240 
 241 template <class T>
 242 inline void EventLogBase<T>::print_log_on(outputStream* out) {
 243   if (ThreadLocalStorage::get_thread_slow() == NULL) {
 244     // Not a regular Java thread so don't bother locking
 245     print_log_impl(out);
 246   } else {
 247     MutexLockerEx ml(&_mutex, Mutex::_no_safepoint_check_flag);
 248     print_log_impl(out);
 249   }
 250 }
 251 
 252 // Dump the ring buffer entries that current have entries.
 253 template <class T>
 254 inline void EventLogBase<T>::print_log_impl(outputStream* out) {
 255   out->print_cr("%s (%d events):", _name, _count);
 256   if (_count == 0) {
 257     out->print_cr("No events");
 258     return;
 259   }
 260 
 261   if (_count < _length) {
 262     for (int i = 0; i < _count; i++) {
 263       print(out, _records[i]);
 264     }
 265   } else {
 266     for (int i = _index; i < _length; i++) {
 267       print(out, _records[i]);
 268     }
 269     for (int i = 0; i < _index; i++) {
 270       print(out, _records[i]);
 271     }
 272   }
 273   out->cr();
 274 }
 275 
 276 // Implement a printing routine for the StringLogMessage
 277 template <>
 278 inline void EventLogBase<StringLogMessage>::print(outputStream* out, StringLogMessage& lm) {
 279   out->print_raw(lm);
 280   out->cr();
 281 }
 282 
 283 // Place markers for the beginning and end up of a set of events.
 284 // These end up in the default log.
 285 class EventMark : public StackObj {
 286   StringLogMessage _buffer;
 287 
 288  public:
 289   // log a begin event, format as printf
 290   EventMark(const char* format, ...);
 291   // log an end event
 292   ~EventMark();
 293 };
 294 
 295 #endif // SHARE_VM_UTILITIES_EVENTS_HPP