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 }