hotspot/src/share/vm/utilities/events.hpp
changeset 11788 bef6166c683c
parent 11636 3c07b54482a5
child 11795 0c892974d26c
equal deleted inserted replaced
11787:cfb5950b7706 11788:bef6166c683c
    33 
    33 
    34 // Events and EventMark provide interfaces to log events taking place in the vm.
    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
    35 // This facility is extremly useful for post-mortem debugging. The eventlog
    36 // often provides crucial information about events leading up to the crash.
    36 // often provides crucial information about events leading up to the crash.
    37 //
    37 //
    38 // All arguments past the format string must be passed as an intptr_t.
    38 // Abstractly the logs can record whatever they way but normally they
    39 //
    39 // would record at least a timestamp and the current Thread, along
    40 // To log a single event use:
    40 // with whatever data they need in a ring buffer.  Commonly fixed
    41 //    Events::log("New nmethod has been created " INTPTR_FORMAT, nm);
    41 // length text messages are recorded for simplicity but other
    42 //
    42 // strategies could be used.  Several logs are provided by default but
    43 // To log a block of events use:
    43 // new instances can be created as needed.
    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 
    44 
    53 // The base event log dumping class that is registered for dumping at
    45 // 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
    46 // crash time.  This is a very generic interface that is mainly here
    55 // for completeness.  Normally the templated EventLogBase would be
    47 // for completeness.  Normally the templated EventLogBase would be
    56 // subclassed to provide different log types.
    48 // subclassed to provide different log types.
    77 // semantics aren't appropriate.  The name is used as the label of the
    69 // semantics aren't appropriate.  The name is used as the label of the
    78 // log when it is dumped during a crash.
    70 // log when it is dumped during a crash.
    79 template <class T> class EventLogBase : public EventLog {
    71 template <class T> class EventLogBase : public EventLog {
    80   template <class X> class EventRecord {
    72   template <class X> class EventRecord {
    81    public:
    73    public:
    82     jlong   timestamp;
    74     double  timestamp;
    83     Thread* thread;
    75     Thread* thread;
    84     X       data;
    76     X       data;
    85   };
    77   };
    86 
    78 
    87  protected:
    79  protected:
    98     _length(length),
    90     _length(length),
    99     _count(0),
    91     _count(0),
   100     _index(0),
    92     _index(0),
   101     _mutex(Mutex::event, name) {
    93     _mutex(Mutex::event, name) {
   102     _records = new EventRecord<T>[length];
    94     _records = new EventRecord<T>[length];
       
    95   }
       
    96 
       
    97   double fetch_timestamp() {
       
    98     return tty->time_stamp().seconds();
   103   }
    99   }
   104 
   100 
   105   // move the ring buffer to next open slot and return the index of
   101   // 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
   102   // the slot to use for the current message.  Should only be called
   107   // while mutex is held.
   103   // while mutex is held.
   128   // Print a single element.  A templated implementation might need to
   124   // Print a single element.  A templated implementation might need to
   129   // be declared by subclasses.
   125   // be declared by subclasses.
   130   void print(outputStream* out, T& e);
   126   void print(outputStream* out, T& e);
   131 
   127 
   132   void print(outputStream* out, EventRecord<T>& e) {
   128   void print(outputStream* out, EventRecord<T>& e) {
   133     out->print("Event: " INT64_FORMAT " ", e.timestamp);
   129     out->print("Event: %.3f ", e.timestamp);
   134     if (e.thread != NULL) {
   130     if (e.thread != NULL) {
   135       out->print("Thread " INTPTR_FORMAT " ", e.thread);
   131       out->print("Thread " INTPTR_FORMAT " ", e.thread);
   136     }
   132     }
   137     print(out, e.data);
   133     print(out, e.data);
   138   }
   134   }
   153   StringEventLog(const char* name, int count = LogEventsBufferEntries) : EventLogBase<StringLogMessage>(name, count) {}
   149   StringEventLog(const char* name, int count = LogEventsBufferEntries) : EventLogBase<StringLogMessage>(name, count) {}
   154 
   150 
   155   void logv(Thread* thread, const char* format, va_list ap) {
   151   void logv(Thread* thread, const char* format, va_list ap) {
   156     if (!should_log()) return;
   152     if (!should_log()) return;
   157 
   153 
   158     jlong timestamp = os::javaTimeNanos() / NANOSECS_PER_MILLISEC;
   154     double timestamp = fetch_timestamp();
   159     MutexLockerEx ml(&_mutex, Mutex::_no_safepoint_check_flag);
   155     MutexLockerEx ml(&_mutex, Mutex::_no_safepoint_check_flag);
   160     int index = compute_log_index();
   156     int index = compute_log_index();
   161     _records[index].thread = thread;
   157     _records[index].thread = thread;
   162     _records[index].timestamp = timestamp;
   158     _records[index].timestamp = timestamp;
   163     _records[index].data.printv(format, ap);
   159     _records[index].data.printv(format, ap);
   191   static StringEventLog* _deopt_messages;
   187   static StringEventLog* _deopt_messages;
   192 
   188 
   193  public:
   189  public:
   194   static void print_all(outputStream* out);
   190   static void print_all(outputStream* out);
   195 
   191 
   196   static void print() {
   192   // Dump all events to the tty
   197     print_all(tty);
   193   static void print();
   198   }
       
   199 
   194 
   200   // Logs a generic message with timestamp and format as printf.
   195   // Logs a generic message with timestamp and format as printf.
   201   static void log(Thread* thread, const char* format, ...);
   196   static void log(Thread* thread, const char* format, ...);
   202 
   197 
   203   // Log exception related message
   198   // Log exception related message
   253 template <class T>
   248 template <class T>
   254 inline void EventLogBase<T>::print_log_impl(outputStream* out) {
   249 inline void EventLogBase<T>::print_log_impl(outputStream* out) {
   255   out->print_cr("%s (%d events):", _name, _count);
   250   out->print_cr("%s (%d events):", _name, _count);
   256   if (_count == 0) {
   251   if (_count == 0) {
   257     out->print_cr("No events");
   252     out->print_cr("No events");
       
   253     out->cr();
   258     return;
   254     return;
   259   }
   255   }
   260 
   256 
   261   if (_count < _length) {
   257   if (_count < _length) {
   262     for (int i = 0; i < _count; i++) {
   258     for (int i = 0; i < _count; i++) {