/* * Copyright (c) 2014, 2015, Dynatrace and/or its affiliates. All rights reserved. * * This file is part of the Lock Contention Tracing Subsystem for the HotSpot * Virtual Machine, which is developed at Christian Doppler Laboratory on * Monitoring and Evolution of Very-Large-Scale Software Systems. Please * contact us at if you need additional information * or have any questions. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work. If not, see . * */ package sun.evtracing.processing; import java.util.Map; import sun.evtracing.parser.ClassLoaderUnloadEvent; import sun.evtracing.parser.ClassMetadataEvent; import sun.evtracing.parser.GroupEvent; import sun.evtracing.parser.IdenticalStacksMetadataEvent; import sun.evtracing.parser.MetadataResetEvent; import sun.evtracing.parser.MethodMetadataEvent; import sun.evtracing.parser.MonitorContendedEnterEvent; import sun.evtracing.parser.MonitorContendedExitedEvent; import sun.evtracing.parser.MonitorInflateEvent; import sun.evtracing.parser.StackMetadataEvent; import sun.evtracing.parser.ThreadExitEvent; import sun.evtracing.parser.ThreadInterruptEvent; import sun.evtracing.parser.ThreadNameChangeEvent; import sun.evtracing.parser.ThreadParkBeginEvent; import sun.evtracing.parser.ThreadStartEvent; import sun.evtracing.parser.ThreadStateChangeEvent; import sun.evtracing.parser.ThreadUnparkEvent; import sun.evtracing.parser.TraceEvent; import sun.evtracing.parser.VMEndEvent; import sun.evtracing.parser.metadata.JavaClass; import sun.evtracing.parser.metadata.JavaStack; import sun.evtracing.parser.metadata.JavaThread; import sun.evtracing.parser.metadata.MetadataRef; public class TraceEventMetadataResolveHandler extends TraceEventUniversalHandler { private class ResolveHandler extends DelegateTraceEventHandler { public ResolveHandler(TraceEventHandler delegate) { super(delegate); } // // Metadata events // @Override public void threadStart(ThreadStartEvent event) { JavaThread t = event.thread().metadata(); t.setName(event.name()); t.setStart(event.timestamp()); super.threadStart(event); } @Override public void threadNameChange(ThreadNameChangeEvent event) { resolveThread(event.affectedThread()).setName(event.newName()); super.threadNameChange(event); } @Override public void threadExit(ThreadExitEvent event) { event.thread().metadata().setEnd(event.timestamp()); super.threadExit(event); } @Override public void endVM(VMEndEvent event) { persistentMetadata.endAllJavaThreads(event.timestamp()); super.endVM(event); } @Override public void classMetadata(ClassMetadataEvent event) { metadata.getOrAddClass(event.clazz()).set(event.classLoader(), event.name()); super.classMetadata(event); } @Override public void stackMetadata(StackMetadataEvent event) { metadata.getOrAddStack(event.stack()).fill(event.methods(), event.bcis(), metadata); super.stackMetadata(event); } @Override public void identicalStacksMetadata(IdenticalStacksMetadataEvent event) { JavaStack known = metadata.getOrAddStack(event.knownStack()); metadata.getOrAddStack(event.stack()).assign(known); super.identicalStacksMetadata(event); } @Override public void methodMetadata(MethodMetadataEvent event) { metadata.getOrAddMethod(event.method()).set(resolveClass(event.clazz()), event.name(), event.signature()); super.methodMetadata(event); } @Override public void classLoaderUnload(ClassLoaderUnloadEvent event) { metadata.purgeUnloadedClassesFrom(event.classLoader()); super.classLoaderUnload(event); } @Override public void metadataReset(MetadataResetEvent event) { metadata = new MetadataStore(); super.metadataReset(event); } // // Events with metadata to resolve // @Override public void monitorInflate(MonitorInflateEvent event) { resolveClass(event.clazz()); super.monitorInflate(event); } @Override public void monitorContendedEnter(MonitorContendedEnterEvent event) { resolveStack(event.stack()); super.monitorContendedEnter(event); } @Override public void monitorContendedExited(MonitorContendedExitedEvent event) { resolveStack(event.stack()); super.monitorContendedExited(event); } @Override public void threadParkBegin(ThreadParkBeginEvent event) { resolveClass(event.clazz()); resolveStack(event.stack()); super.threadParkBegin(event); } @Override public void threadUnpark(ThreadUnparkEvent event) { resolveThread(event.unparkedThread()); resolveStack(event.stack()); super.threadUnpark(event); } @Override public void group(GroupEvent event) { resolveClass(event.clazz()); super.group(event); } @Override public void threadStateChange(ThreadStateChangeEvent event) { resolveThread(event.affectedThread()); super.threadStateChange(event); } @Override public void threadInterrupt(ThreadInterruptEvent event) { resolveThread(event.affectedThread()); super.threadInterrupt(event); } } private final TraceEventHandler resolveHandler; private final PersistentMetadataStore persistentMetadata = new PersistentMetadataStore(); private MetadataStore metadata = new MetadataStore(); public TraceEventMetadataResolveHandler(TraceEventHandler delegate) { resolveHandler = new ResolveHandler(delegate); } private JavaThread resolveThread(MetadataRef thread) { thread.setMetadata(persistentMetadata.getOrAddJavaThread(thread.identifier())); return thread.metadata(); } private JavaClass resolveClass(MetadataRef clazz) { clazz.setMetadata(metadata.getOrAddClass(clazz.identifier())); return clazz.metadata(); } private JavaStack resolveStack(MetadataRef stack) { stack.setMetadata(metadata.getOrAddStack(stack.identifier())); return stack.metadata(); } @Override public void handle(TraceEvent event) { resolveThread(event.thread()); event.accept(resolveHandler); } @Override public void putStatistics(Map map) { resolveHandler.putStatistics(map); } @Override public void resetStatistics() { resolveHandler.resetStatistics(); } }