mirror of https://github.com/contiki-ng/mspsim
added initial support for stack profiling
This commit is contained in:
parent
67e7b4ba21
commit
d978202030
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue