/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*/
package instrumentj;
import instrumentj.impl.CallStackHelper;
import instrumentj.impl.InstrumentMethodVisitor;
import instrumentj.impl.ProfilerControllerImpl;
import instrumentj.probes.Probe;
import java.io.PrintStream;
/**
* @author Stephen Evanchik (evanchsa@gmail.com)
*
*/
public enum StaticProfilerInterface {
INSTANCE;
/**
*
* @author Stephen Evanchik (evanchsa@gmail.com)
*
*/
public interface Profiler extends ProbeManager, ProfilerController, CallStack {
};
private static boolean initialized = false;
private static final CallStackHelper CALL_STACK_HELPER = new CallStackHelper();
/**
* Invoked by the profile whenever a method entry is detected. This includes
* constructors (<init> methods)
*
* @param className
* the name of the class
* @param methodName
* the name of the method
* @param methodDescription
* the argument descriptors for the method
*/
public static void methodEnterProbes(
final String className,
final String methodName,
final String methodDescription,
final Object[] methodArgs)
{
if (!INSTANCE.profilerController.isActive()) {
return;
}
CALL_STACK_HELPER.push(methodName, methodDescription);
INSTANCE.probeExecutor.methodEntryProbes(className, methodName, methodDescription, methodArgs);
}
/**
* Invoked by the profile whenever a method exit is detected. This includes
* constructors (<init> methods) and exceptions
*
* @param className
* the name of the class
* @param methodName
* the name of the method
* @param methodDescription
* the argument descriptors for the method
* @param opcode
* consult {@link InstrumentMethodVisitor#MethodExit(int)} for
* more information about this value
*/
public static void methodExitProbes(
final String className,
final String methodName,
final String methodDescription,
final int opcode)
{
if (!INSTANCE.profilerController.isActive()) {
return;
}
CALL_STACK_HELPER.peek().markExiting();
INSTANCE.probeExecutor.methodExitProbes(className, methodName, methodDescription, opcode);
CALL_STACK_HELPER.pop();
}
public static void objectAllocationProbes(final String className) {
if (!INSTANCE.profilerController.isActive()) {
return;
}
INSTANCE.probeExecutor.objectAllocationProbes(className);
};
/**
* Initializes the fields of this enum singleton
*
* @param profilerController
*/
static void initialize(final ProfilerControllerImpl profilerController) {
if (!initialized) {
INSTANCE.profilerController = profilerController;
INSTANCE.probeManager = profilerController.getProbeManager();
INSTANCE.probeExecutor = profilerController.getProbeExecutor();
initialized = true;
}
}
private ProbeExecutor probeExecutor;
/*
* Static methods called by the instrumented code
*/
private ProbeManager probeManager;
private ProfilerController profilerController;
/**
* Returns a new instance of the {@link Profiler} interface
*
* @return a new instance of the {@link Profiler} interface
*/
public Profiler getProfiler() {
return new Profiler() {
@Override
public void activate() {
profilerController.activate();
}
@Override
public void addProbe(final Probe probe) {
probeManager.addProbe(probe);
}
@Override
public void deactivate() {
profilerController.deactivate();
}
@Override
public boolean defineProbes(final Class<?> clazz) {
return probeManager.defineProbes(clazz);
}
@Override
public boolean findFirstParent(String methodName) {
return CALL_STACK_HELPER.findFirstParent(methodName);
}
@Override
public boolean findParent(String methodName) {
return CALL_STACK_HELPER.findParent(methodName);
}
@Override
public long getObjectSize(final Object objectToSize) {
return profilerController.getObjectSize(objectToSize);
}
@Override
public boolean isActive() {
return profilerController.isActive();
}
@Override
public Entry peek() {
return CALL_STACK_HELPER.peek();
}
@Override
public void pop() {
CALL_STACK_HELPER.pop();
}
@Override
public void push(final String methodName, final String methodDescription) {
CALL_STACK_HELPER.push(methodName, methodDescription);
}
@Override
public void printStackTrace(final PrintStream out) {
CALL_STACK_HELPER.printStackTrace(out);
}
@Override
public boolean removeProbe(final Probe probe) {
return probeManager.removeProbe(probe);
}
};
}
}