diff --git a/se/sics/mspsim/cli/ProfilerCommands.java b/se/sics/mspsim/cli/ProfilerCommands.java index e1fd767..c53f7b3 100644 --- a/se/sics/mspsim/cli/ProfilerCommands.java +++ b/se/sics/mspsim/cli/ProfilerCommands.java @@ -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(); diff --git a/se/sics/mspsim/platform/GenericNode.java b/se/sics/mspsim/platform/GenericNode.java index f69e537..ed7a817 100644 --- a/se/sics/mspsim/platform/GenericNode.java +++ b/se/sics/mspsim/platform/GenericNode.java @@ -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()); diff --git a/se/sics/mspsim/util/SimpleProfiler.java b/se/sics/mspsim/util/SimpleProfiler.java index 9ce4779..2eb7f4b 100644 --- a/se/sics/mspsim/util/SimpleProfiler.java +++ b/se/sics/mspsim/util/SimpleProfiler.java @@ -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(); @@ -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 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 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; + } } diff --git a/se/sics/mspsim/util/StackMonitor.java b/se/sics/mspsim/util/StackMonitor.java index 91229e8..49c523e 100644 --- a/se/sics/mspsim/util/StackMonitor.java +++ b/se/sics/mspsim/util/StackMonitor.java @@ -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; + } } -} +} \ No newline at end of file