added initial support for stack profiling

This commit is contained in:
Joakim Eriksson 2011-03-21 20:06:43 +01:00
parent 67e7b4ba21
commit d978202030
4 changed files with 97 additions and 8 deletions

View File

@ -50,6 +50,7 @@ import se.sics.mspsim.ui.CPUHeatMap;
import se.sics.mspsim.ui.WindowManager;
import se.sics.mspsim.util.ComponentRegistry;
import se.sics.mspsim.util.SimpleProfiler;
import se.sics.mspsim.util.StackMonitor;
/**
*
@ -119,9 +120,15 @@ public class ProfilerCommands implements CommandBundle {
profiler.printStackTrace(context.out);
return 0;
}
});
ch.registerCommand("stackprof", new BasicCommand("Start stack profiler", "") {
public int executeCommand(CommandContext context) {
new StackMonitor(cpu);
return 0;
}
});
// ch.registerCommand("irqprofile", new BasicCommand("show interrupt profile", "") {
// public int executeCommand(CommandContext context) {
// long[] time = cpu.getInterruptTime();

View File

@ -41,8 +41,12 @@ import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.net.URISyntaxException;
import java.net.URL;
import javax.swing.JFrame;
import se.sics.mspsim.cli.CommandHandler;
import se.sics.mspsim.cli.DebugCommands;
import se.sics.mspsim.cli.FileCommands;
@ -58,6 +62,7 @@ import se.sics.mspsim.core.MSP430;
import se.sics.mspsim.core.MSP430Config;
import se.sics.mspsim.core.MSP430Constants;
import se.sics.mspsim.extutil.highlight.HighlightSourceViewer;
import se.sics.mspsim.ui.ConsoleUI;
import se.sics.mspsim.ui.ControlUI;
import se.sics.mspsim.ui.JFrameWindowManager;
import se.sics.mspsim.ui.StackUI;
@ -207,10 +212,25 @@ public abstract class GenericNode extends Chip implements Runnable {
cpu.setEmulationLogger(logger);
CommandHandler ch = (CommandHandler) registry.getComponent("commandHandler");
if (ch == null) {
ch = new StreamCommandHandler(System.in, System.out, System.err, PROMPT);
registry.registerComponent("commandHandler", ch);
if (!config.getPropertyAsBoolean("nogui", false)) {
ConsoleUI console = new ConsoleUI();
PrintStream consoleStream = new PrintStream(console.getOutputStream());
ch = new CommandHandler(consoleStream, consoleStream);
JFrame w = new JFrame("ConsoleUI");
w.add(console);
w.setBounds(20, 20, 520, 400);
w.setLocationByPlatform(true);
w.setVisible(true);
console.setCommandHandler(ch);
registry.registerComponent("commandHandler", ch);
} else {
ch = new StreamCommandHandler(System.in, System.out, System.err, PROMPT);
registry.registerComponent("commandHandler", ch);
}
}
stats = new OperatingModeStatistics(cpu);
registry.registerComponent("pluginRepository", new PluginRepository());

View File

@ -81,6 +81,8 @@ public class SimpleProfiler implements Profiler, EventListener {
private int interruptLevel;
private int interruptFrom;
private boolean newIRQ;
private StackMonitor stackMonitor;
public SimpleProfiler() {
profileData = new HashMap<MapEntry, CallEntry>();
@ -140,7 +142,17 @@ public class SimpleProfiler implements Profiler, EventListener {
ce.hide = hide;
ce.fromPC = from;
newIRQ = false;
if (stackMonitor != null) {
/* get the current stack MAX for previous function */
if (cSP > 1) {
callStack[cSP - 2].currentStackMax = stackMonitor.getProfStackMax();
}
/* start stack here! */
ce.stackStart = stackMonitor.getStack();
stackMonitor.setProfStackMax(stackMonitor.getStack());
}
CallListener[] listeners = callListeners;
if (listeners != null) {
@ -164,12 +176,14 @@ public class SimpleProfiler implements Profiler, EventListener {
CallEntry cspEntry = callStack[--cSP];
MapEntry fkn = cspEntry.function;
// System.out.println("Profiler: return / call stack: " + cSP + ", " + fkn);
long elapsed = cycles - cspEntry.cycles;
long exElapsed = cycles - cspEntry.exclusiveCycles;
if (cSP != 0) {
callStack[cSP-1].exclusiveCycles += elapsed;
}
int maxUsage = 0;
if (cspEntry.calls >= 0) {
CallEntry ce = profileData.get(fkn);
if (ce == null) {
@ -179,6 +193,21 @@ public class SimpleProfiler implements Profiler, EventListener {
ce.cycles += elapsed;
ce.exclusiveCycles += exElapsed;
ce.calls++;
if (stackMonitor != null) {
maxUsage = stackMonitor.getProfStackMax() - cspEntry.stackStart;
ce.stackStart = cspEntry.stackStart;
if (maxUsage > ce.currentStackMax) {
ce.currentStackMax = maxUsage;
}
if (cSP != 0) {
/* put the max for previous function back into the max profiler */
stackMonitor.setProfStackMax(callStack[cSP-1].currentStackMax);
}
}
if (cSP != 0) {
MapEntry caller = callStack[cSP-1].function;
HashMap<MapEntry,CallCounter> callers = ce.callers;
@ -195,7 +224,7 @@ public class SimpleProfiler implements Profiler, EventListener {
if ((cspEntry.hide <= 1) && (!hideIRQ || servicedInterrupt == -1)) {
if (servicedInterrupt >= 0) logger.printf("[%2d] ",servicedInterrupt);
printSpace(logger, (cSP - interruptLevel) * 2);
logger.println("return from " + ce.function.getInfo() + " elapsed: " + elapsed);
logger.println("return from " + ce.function.getInfo() + " elapsed: " + elapsed + " maxStackUsage: " + maxUsage);
}
}
@ -408,6 +437,9 @@ public class SimpleProfiler implements Profiler, EventListener {
long exclusiveCycles;
int calls;
int hide;
int stackStart;
int currentStackMax;
HashMap<MapEntry,CallCounter> callers;
public CallEntry() {
@ -521,4 +553,9 @@ public class SimpleProfiler implements Profiler, EventListener {
public String getCall(int i) {
return callStack[cSP - i].function.getInfo();
}
public void setStackMonitor(StackMonitor stackMonitor) {
System.out.println("Setting Stack monitor to: " + stackMonitor);
this.stackMonitor = stackMonitor;
}
}

View File

@ -13,6 +13,7 @@ public class StackMonitor implements CPUMonitor {
private int stackMin = 0;
private int stackMax = 0;
private int stack = 0;
private int profStackMax = 0;
private DataSource maxDataSource = new DataSource() {
public int getValue() {
@ -48,7 +49,13 @@ public class StackMonitor implements CPUMonitor {
public StackMonitor(MSP430 cpu) {
this.cpu = cpu;
this.cpu.setRegisterWriteMonitor(MSP430.SP, this);
Object p = cpu.getRegistry().getComponent("profiler");
if (p instanceof SimpleProfiler) {
((SimpleProfiler) p).setStackMonitor(this);
System.out.println("Found simple profiler!!!: " + p);
} else {
System.out.println("Could not find simple profiler: " + p);
}
if (cpu.getDisAsm() != null) {
MapTable mapTable = cpu.getDisAsm().getMap();
if (mapTable != null) {
@ -79,13 +86,31 @@ public class StackMonitor implements CPUMonitor {
return dataSource;
}
/* specialized profiler support for the stack */
/* set current profiler Stack max to this value */
public void setProfStackMax(int max) {
profStackMax = max;
}
/* get profiler stack max */
public int getProfStackMax() {
return profStackMax;
}
public int getStack() {
return stack;
}
public void cpuAction(int type, int adr, int data) {
stack = ((stackStartAddress - data) + 0xffff) % 0xffff;
stack = ((stackStartAddress - data) + 0xffff) & 0xffff;
if (stack > stackMax) {
stackMax = stack;
}
if (stack < stackMin) {
stackMin = stack;
}
if (stack > profStackMax) {
profStackMax = stack;
}
}
}
}