From: <mic...@us...> - 2007-08-02 13:59:59
|
Revision: 154 http://pearcolator.svn.sourceforge.net/pearcolator/?rev=154&view=rev Author: michael_baer Date: 2007-08-02 06:59:57 -0700 (Thu, 02 Aug 2007) Log Message: ----------- - Corrected bug in staged emulation controller - added javadoc Modified Paths: -------------- src/org/binarytranslator/DBT_Options.java src/org/binarytranslator/Main.java src/org/binarytranslator/generic/execution/InterpreterController.java src/org/binarytranslator/generic/execution/ProfilingInterpreterController.java src/org/binarytranslator/generic/execution/StagedEmulationController.java Modified: src/org/binarytranslator/DBT_Options.java =================================================================== --- src/org/binarytranslator/DBT_Options.java 2007-08-02 12:22:44 UTC (rev 153) +++ src/org/binarytranslator/DBT_Options.java 2007-08-02 13:59:57 UTC (rev 154) @@ -90,6 +90,9 @@ /** GDB stub port */ public static int gdbStubPort = 1234; + /** Just a temporary variable for testing. It describes, when the staged emulation controller switches from interpretation to translation. */ + public static int minTraceValue = 20; + /** Print debug information during the translation of instructions. */ public static boolean debugTranslation = true; @@ -153,49 +156,52 @@ } /** Parses a single argument into the options class. */ - private static void parseSingleArgument(String arg, String value) { + private static void parseSingleArgument(String key, String value) { - if (!arg.startsWith("-X:dbt:")) { + if (!key.startsWith("-X:dbt:")) { throw new Error("Invalid argument. Argument prefix '-X:dbt:' expected."); } - arg = arg.substring(7); + key = key.substring(7); - if (arg.equalsIgnoreCase("debugInstr")) { + if (key.equalsIgnoreCase("debugInstr")) { debugInstr = Boolean.parseBoolean(value); - } else if (arg.equalsIgnoreCase("debugRuntime")) { + } else if (key.equalsIgnoreCase("debugRuntime")) { debugRuntime = Boolean.parseBoolean(value); - } else if (arg.equalsIgnoreCase("debugBranchResolution")) { + } else if (key.equalsIgnoreCase("debugBranchResolution")) { debugBranchResolution = Boolean.parseBoolean(value); - } else if (arg.equalsIgnoreCase("debugMemory")) { + } else if (key.equalsIgnoreCase("debugMemory")) { debugMemory = Boolean.parseBoolean(value); - } else if (arg.equalsIgnoreCase("debugSyscall")) { + } else if (key.equalsIgnoreCase("debugSyscall")) { debugSyscall = Boolean.parseBoolean(value); - } else if (arg.equalsIgnoreCase("debugSyscallMore")) { + } else if (key.equalsIgnoreCase("debugSyscallMore")) { debugSyscallMore = Boolean.parseBoolean(value); - } else if (arg.equalsIgnoreCase("instrOpt0")) { + } else if (key.equalsIgnoreCase("instrOpt0")) { instrOpt0 = Integer.parseInt(value); - } else if (arg.equalsIgnoreCase("instrOpt1")) { + } else if (key.equalsIgnoreCase("instrOpt1")) { instrOpt1 = Integer.parseInt(value); - } else if (arg.equalsIgnoreCase("instrOpt2")) { + } else if (key.equalsIgnoreCase("instrOpt2")) { instrOpt2 = Integer.parseInt(value); - } else if (arg.equalsIgnoreCase("singleInstrTranslation")) { + } else if (key.equalsIgnoreCase("singleInstrTranslation")) { singleInstrTranslation = Boolean.parseBoolean(value); - } else if (arg.equalsIgnoreCase("resolveDirectBranchesFirst")) { + } else if (key.equalsIgnoreCase("resolveDirectBranchesFirst")) { resolveDirectBranchesFirst = Boolean.parseBoolean(value); - } else if (arg.equalsIgnoreCase("gdbStub")) { + } else if (key.equalsIgnoreCase("gdbStub")) { gdbStub = Boolean.parseBoolean(value); - } else if (arg.equalsIgnoreCase("gdbStubPort")) { + } else if (key.equalsIgnoreCase("gdbStubPort")) { gdbStubPort = Integer.parseInt(value); - } else if (arg.equalsIgnoreCase("controller")) { + } else if (key.equalsIgnoreCase("controller")) { executionController = ExecutionController.Type.valueOf(value); - } else if (arg.equalsIgnoreCase("loadProfile")) { - loadProfileFromFile = arg; - } else if (arg.equalsIgnoreCase("saveProfile")) { - saveProfileToFile = arg; + } else if (key.equalsIgnoreCase("loadProfile")) { + loadProfileFromFile = value; + } else if (key.equalsIgnoreCase("saveProfile")) { + saveProfileToFile = value; + } else if (key.equalsIgnoreCase("minTraceValue")) { + minTraceValue = Integer.parseInt(value); } + else { - throw new Error("Unknown DBT option: " + arg); + throw new Error("Unknown DBT option: " + key); } } Modified: src/org/binarytranslator/Main.java =================================================================== --- src/org/binarytranslator/Main.java 2007-08-02 12:22:44 UTC (rev 153) +++ src/org/binarytranslator/Main.java 2007-08-02 13:59:57 UTC (rev 154) @@ -105,7 +105,7 @@ //on SUN's VM, only the interpreter has been tested if (DBT_Options.buildForSunVM) { - DBT_Options.executionController = ExecutionController.Type.PredecodingInterpreter; + DBT_Options.executionController = ExecutionController.Type.StagedEmulation; } //load a previously saved branch profile from file, if the user requested it Modified: src/org/binarytranslator/generic/execution/InterpreterController.java =================================================================== --- src/org/binarytranslator/generic/execution/InterpreterController.java 2007-08-02 12:22:44 UTC (rev 153) +++ src/org/binarytranslator/generic/execution/InterpreterController.java 2007-08-02 13:59:57 UTC (rev 154) @@ -1,9 +1,12 @@ package org.binarytranslator.generic.execution; -import org.binarytranslator.DBT_Options; import org.binarytranslator.generic.decoder.Interpreter; import org.binarytranslator.generic.os.process.ProcessSpace; +/** + * Implements straight-forward interpretation using the {@link Interpreter} + * and {@link Interpreter.Instruction} interfaces. + */ public class InterpreterController extends ExecutionController { public InterpreterController(ProcessSpace ps) { Modified: src/org/binarytranslator/generic/execution/ProfilingInterpreterController.java =================================================================== --- src/org/binarytranslator/generic/execution/ProfilingInterpreterController.java 2007-08-02 12:22:44 UTC (rev 153) +++ src/org/binarytranslator/generic/execution/ProfilingInterpreterController.java 2007-08-02 13:59:57 UTC (rev 154) @@ -3,6 +3,12 @@ import org.binarytranslator.generic.decoder.Interpreter; import org.binarytranslator.generic.os.process.ProcessSpace; +/** + * Implements straight-forward interpretation using the {@link Interpreter} + * and {@link Interpreter.Instruction} interfaces. + * + * Additionally, this controller performs profiling during the interpretation. + */ public class ProfilingInterpreterController extends ExecutionController { public ProfilingInterpreterController(ProcessSpace ps) { Modified: src/org/binarytranslator/generic/execution/StagedEmulationController.java =================================================================== --- src/org/binarytranslator/generic/execution/StagedEmulationController.java 2007-08-02 12:22:44 UTC (rev 153) +++ src/org/binarytranslator/generic/execution/StagedEmulationController.java 2007-08-02 13:59:57 UTC (rev 154) @@ -13,24 +13,46 @@ import org.binarytranslator.vmInterface.DynamicCodeRunner; import org.jikesrvm.ArchitectureSpecific.VM_CodeArray; +/** + * This controller implements staged emulation, i.e. switching between interpretation + * and translation dynamically. + * + */ public class StagedEmulationController extends ExecutionController { - private final class Trace { - public final List<Interpreter.Instruction> instructions; + /** Represents a dynamic basic block of instructions. */ + private final class DynamicBasicBlock { + /** The instructions within this dynamic basic block. */ + public List<Interpreter.Instruction> instructions; + + /** A value describing how "hot" the basic block is, i.e. how often it has been executed.*/ public int value; + + /** A handle to the compiled version of this dynamic basic block or null, if there is none. */ public DBT_Trace compiledTrace; - public Trace(List<Interpreter.Instruction> instructions) { + public DynamicBasicBlock(List<Interpreter.Instruction> instructions) { this.instructions = instructions; value = 0; } } - private final HashMap<Integer, Trace> traceCache = new HashMap<Integer, Trace>(); + /** Maps a dynamic basic block to the address of the first instruction within that block. */ + private final HashMap<Integer, DynamicBasicBlock> traceCache = new HashMap<Integer, DynamicBasicBlock>(); + + /** The interpreter that is used to perform the actual execution of single instructions. */ private final Interpreter interpreter; - private Trace getTrace(int pc) { - Trace cachedTrace = traceCache.get(pc); + /** + * Returns the dynamic basic block starting at address <code>pc</code>. + * + * @param pc + * The starting address of a dynamic basic block. + * @return + * An object representation of the dynamic basic block. + */ + private DynamicBasicBlock getBlock(int pc) { + DynamicBasicBlock cachedTrace = traceCache.get(pc); if (cachedTrace != null) return cachedTrace; @@ -46,7 +68,7 @@ //is the successor to this instruction known? if (pc == -1) { //No, so stop and create a trace from the decoded instructions - Trace newTrace = new Trace(instructions); + DynamicBasicBlock newTrace = new DynamicBasicBlock(instructions); if (instructions.size() > 3) { //add this trace to the trace cache, if it contains enough instructions @@ -58,17 +80,34 @@ } } - private void compileTrace(Trace trace, int pc) { + /** + * Compiles a dynamic basic block into a trace. + * + * @param trace + * The dynamic basic block to compile. + * @param pc + * The address of the first instruction within the dynamic basic block. + */ + private void compileBlock(DynamicBasicBlock trace, int pc) { if (DBT.VerifyAssertions) DBT._assert(trace.compiledTrace == null); trace.compiledTrace = new DBT_Trace(ps, pc); trace.compiledTrace.compile(); + trace.instructions = null; } - private void executeTrace(Trace trace, int pc) { + /** + * Executes the instructions within a dynamic basic block. + * + * @param trace + * The dynamic basic block whose instructions shall be executed. + * @param pc + * The address of the first instruction within that dynamic basic block. + */ + private void executeBlock(DynamicBasicBlock trace, int pc) { //check if the trace is being executed very frequently... - if (trace.value > 20) { + if (trace.value > DBT_Options.minTraceValue) { if (DBT_Options.debugTranslation) System.out.println("Switching to interpretation at address 0x" + Integer.toHexString(pc)); @@ -76,13 +115,18 @@ //yes, so we should rather try to execute a translated version if (trace.compiledTrace == null) { //compile the trace, if necessary - compileTrace(trace, pc); + compileBlock(trace, pc); if (DBT.VerifyAssertions) DBT._assert(trace.compiledTrace != null); } //execute the trace VM_CodeArray code = trace.compiledTrace.getCurrentCompiledMethod().getEntryCodeArray(); ps.setCurrentInstructionAddress(DynamicCodeRunner.invokeCode(code, ps)); + + if (DBT_Options.debugTranslation) + System.out.println("Returning from interpretation at 0x" + Integer.toHexString(ps.getCurrentInstructionAddress())); + + return; } else { trace.value += trace.instructions.size(); @@ -102,6 +146,7 @@ } } + /** Default constructor */ public StagedEmulationController(ProcessSpace ps) { super(ps); interpreter = ps.createInterpreter(); @@ -113,8 +158,8 @@ while (!ps.finished) { - Trace trace = getTrace(pc); - executeTrace(trace, pc); + DynamicBasicBlock trace = getBlock(pc); + executeBlock(trace, pc); pc = ps.getCurrentInstructionAddress(); } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |