1 /*
   2  * Copyright (c) 2014, 2015, Dynatrace and/or its affiliates. All rights reserved.
   3  * 
   4  * This file is part of the Lock Contention Tracing Subsystem for the HotSpot
   5  * Virtual Machine, which is developed at Christian Doppler Laboratory on
   6  * Monitoring and Evolution of Very-Large-Scale Software Systems. Please
   7  * contact us at <http://mevss.jku.at/> if you need additional information
   8  * or have any questions.
   9  *
  10  * This code is free software; you can redistribute it and/or modify it
  11  * under the terms of the GNU General Public License version 2 only, as
  12  * published by the Free Software Foundation.
  13  *
  14  * This code is distributed in the hope that it will be useful, but WITHOUT
  15  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  16  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  17  * version 2 for more details (a copy is included in the LICENSE file that
  18  * accompanied this code).
  19  *
  20  * You should have received a copy of the GNU General Public License version
  21  * 2 along with this work. If not, see <http://www.gnu.org/licenses/>.
  22  *
  23  */ 
  24 package sun.evtracing.processing;
  25 
  26 import java.util.Map;
  27 
  28 import sun.evtracing.parser.ClassLoaderUnloadEvent;
  29 import sun.evtracing.parser.ClassMetadataEvent;
  30 import sun.evtracing.parser.GroupEvent;
  31 import sun.evtracing.parser.IdenticalStacksMetadataEvent;
  32 import sun.evtracing.parser.MetadataResetEvent;
  33 import sun.evtracing.parser.MethodMetadataEvent;
  34 import sun.evtracing.parser.MonitorContendedEnterEvent;
  35 import sun.evtracing.parser.MonitorContendedExitedEvent;
  36 import sun.evtracing.parser.MonitorInflateEvent;
  37 import sun.evtracing.parser.StackMetadataEvent;
  38 import sun.evtracing.parser.ThreadExitEvent;
  39 import sun.evtracing.parser.ThreadInterruptEvent;
  40 import sun.evtracing.parser.ThreadNameChangeEvent;
  41 import sun.evtracing.parser.ThreadParkBeginEvent;
  42 import sun.evtracing.parser.ThreadStartEvent;
  43 import sun.evtracing.parser.ThreadStateChangeEvent;
  44 import sun.evtracing.parser.ThreadUnparkEvent;
  45 import sun.evtracing.parser.TraceEvent;
  46 import sun.evtracing.parser.VMEndEvent;
  47 import sun.evtracing.parser.metadata.JavaClass;
  48 import sun.evtracing.parser.metadata.JavaStack;
  49 import sun.evtracing.parser.metadata.JavaThread;
  50 import sun.evtracing.parser.metadata.MetadataRef;
  51 
  52 public class TraceEventMetadataResolveHandler extends TraceEventUniversalHandler {
  53 
  54         private class ResolveHandler extends DelegateTraceEventHandler {
  55                 public ResolveHandler(TraceEventHandler delegate) {
  56                         super(delegate);
  57                 }
  58 
  59                 //
  60                 // Metadata events
  61                 //
  62 
  63                 @Override
  64                 public void threadStart(ThreadStartEvent event) {
  65                         JavaThread t = event.thread().metadata();
  66                         t.setName(event.name());
  67                         t.setStart(event.timestamp());
  68                         super.threadStart(event);
  69                 }
  70 
  71                 @Override
  72                 public void threadNameChange(ThreadNameChangeEvent event) {
  73                         resolveThread(event.affectedThread()).setName(event.newName());
  74                         super.threadNameChange(event);
  75                 }
  76 
  77                 @Override
  78                 public void threadExit(ThreadExitEvent event) {
  79                         event.thread().metadata().setEnd(event.timestamp());
  80                         super.threadExit(event);
  81                 }
  82 
  83                 @Override
  84                 public void endVM(VMEndEvent event) {
  85                         persistentMetadata.endAllJavaThreads(event.timestamp());
  86                         super.endVM(event);
  87                 }
  88 
  89                 @Override
  90                 public void classMetadata(ClassMetadataEvent event) {
  91                         metadata.getOrAddClass(event.clazz()).set(event.classLoader(), event.name());
  92                         super.classMetadata(event);
  93                 }
  94 
  95                 @Override
  96                 public void stackMetadata(StackMetadataEvent event) {
  97                         metadata.getOrAddStack(event.stack()).fill(event.methods(), event.bcis(), metadata);
  98                         super.stackMetadata(event);
  99                 }
 100 
 101                 @Override
 102                 public void identicalStacksMetadata(IdenticalStacksMetadataEvent event) {
 103                         JavaStack known = metadata.getOrAddStack(event.knownStack());
 104                         metadata.getOrAddStack(event.stack()).assign(known);
 105                         super.identicalStacksMetadata(event);
 106                 }
 107 
 108                 @Override
 109                 public void methodMetadata(MethodMetadataEvent event) {
 110                         metadata.getOrAddMethod(event.method()).set(resolveClass(event.clazz()), event.name(), event.signature());
 111                         super.methodMetadata(event);
 112                 }
 113 
 114                 @Override
 115                 public void classLoaderUnload(ClassLoaderUnloadEvent event) {
 116                         metadata.purgeUnloadedClassesFrom(event.classLoader());
 117                         super.classLoaderUnload(event);
 118                 }
 119 
 120                 @Override
 121                 public void metadataReset(MetadataResetEvent event) {
 122                         metadata = new MetadataStore();
 123                         super.metadataReset(event);
 124                 }
 125 
 126                 //
 127                 // Events with metadata to resolve
 128                 //
 129 
 130                 @Override
 131                 public void monitorInflate(MonitorInflateEvent event) {
 132                         resolveClass(event.clazz());
 133                         super.monitorInflate(event);
 134                 }
 135 
 136                 @Override
 137                 public void monitorContendedEnter(MonitorContendedEnterEvent event) {
 138                         resolveStack(event.stack());
 139                         super.monitorContendedEnter(event);
 140                 }
 141 
 142                 @Override
 143                 public void monitorContendedExited(MonitorContendedExitedEvent event) {
 144                         resolveStack(event.stack());
 145                         super.monitorContendedExited(event);
 146                 }
 147 
 148                 @Override
 149                 public void threadParkBegin(ThreadParkBeginEvent event) {
 150                         resolveClass(event.clazz());
 151                         resolveStack(event.stack());
 152                         super.threadParkBegin(event);
 153                 }
 154 
 155                 @Override
 156                 public void threadUnpark(ThreadUnparkEvent event) {
 157                         resolveThread(event.unparkedThread());
 158                         resolveStack(event.stack());
 159                         super.threadUnpark(event);
 160                 }
 161 
 162                 @Override
 163                 public void group(GroupEvent event) {
 164                         resolveClass(event.clazz());
 165                         super.group(event);
 166                 }
 167 
 168                 @Override
 169                 public void threadStateChange(ThreadStateChangeEvent event) {
 170                         resolveThread(event.affectedThread());
 171                         super.threadStateChange(event);
 172                 }
 173 
 174                 @Override
 175                 public void threadInterrupt(ThreadInterruptEvent event) {
 176                         resolveThread(event.affectedThread());
 177                         super.threadInterrupt(event);
 178                 }
 179         }
 180 
 181         private final TraceEventHandler resolveHandler;
 182         private final PersistentMetadataStore persistentMetadata = new PersistentMetadataStore();
 183         private MetadataStore metadata = new MetadataStore();
 184 
 185         public TraceEventMetadataResolveHandler(TraceEventHandler delegate) {
 186                 resolveHandler = new ResolveHandler(delegate);
 187         }
 188 
 189         private JavaThread resolveThread(MetadataRef<JavaThread> thread) {
 190                 thread.setMetadata(persistentMetadata.getOrAddJavaThread(thread.identifier()));
 191                 return thread.metadata();
 192         }
 193 
 194         private JavaClass resolveClass(MetadataRef<JavaClass> clazz) {
 195                 clazz.setMetadata(metadata.getOrAddClass(clazz.identifier()));
 196                 return clazz.metadata();
 197         }
 198 
 199         private JavaStack resolveStack(MetadataRef<JavaStack> stack) {
 200                 stack.setMetadata(metadata.getOrAddStack(stack.identifier()));
 201                 return stack.metadata();
 202         }
 203 
 204         @Override
 205         public void handle(TraceEvent event) {
 206                 resolveThread(event.thread());
 207                 event.accept(resolveHandler);
 208         }
 209 
 210         @Override
 211         public void putStatistics(Map<String, Double> map) {
 212                 resolveHandler.putStatistics(map);
 213         }
 214 
 215         @Override
 216         public void resetStatistics() {
 217                 resolveHandler.resetStatistics();
 218         }
 219 }