/*
* 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();
}
}