-// Copyright 2003 Adam Megacz, see the COPYING file for licensing [GPL]
+// Copyright 2004 Adam Megacz, see the COPYING file for licensing [GPL]
package org.xwt.mips;
import java.util.*;
// a FaultException will be throw which is easier to catch and deal with, however. as the name implies, this is slower
private static boolean fastMem = true;
- // This MUST be a power of two. If it is not horrible things will happen
+ // log_2 of the maximum bytes per method
// NOTE: This value can be much higher without breaking the classfile
// specs (around 1024) but Hotstop seems to do much better with smaller
// methods.
- private static int MAX_INSN_PER_METHOD = 32;
-
- // Don't touch this
- private static int MAX_BYTES_PER_METHOD = MAX_INSN_PER_METHOD*4;
- private static int METHOD_MASK = ~(MAX_BYTES_PER_METHOD-1);
+ private static int LOG_MAX_BYTES_PER_METHOD = 9;
+ private static int MAX_BYTES_PER_METHOD = 512;
// Store frequently used registers in local variables
// Unfortunately this doesn't seem to speed things up much
p("// This file was generated by MipsToJava");
if (packageName != null) p("package " + packageName + ";");
- p("public class " + className + " extends Runtime {");
+ p("public class " + className + " extends org.xwt.mips.Runtime {");
p("");
p(" // program counter");
p(" private int pc = 0;");
p(" private final void trampoline() throws ExecutionException {");
p(" boolean finished = false;");
p(" while(!finished) {");
- p(" switch(this.pc & " + toHex(~(MAX_BYTES_PER_METHOD-1)) + ") {");
+ p(" switch(this.pc >> " + LOG_MAX_BYTES_PER_METHOD + ") {");
p(runs.toString());
p(" default: throw new Error(\"invalid address 0x\" + Long.toString(this.pc&0xffffffffL,16));");
p(" }");
private static void startMethod(int addr) {
addr &= ~(MAX_BYTES_PER_METHOD-1);
- endOfMethod = addr + MAX_BYTES_PER_METHOD;
+ endOfMethod= addr + MAX_BYTES_PER_METHOD;
String methodName = "run_" + Long.toString(addr & 0xffffffffL, 16);
- runs.append(indents[4] + "case " + toHex(addr) + ": finished = !" + methodName + "(); break;\n");
+ runs.append(indents[4] + "case " + toHex(addr>>LOG_MAX_BYTES_PER_METHOD) + ": finished = !" + methodName + "(); break;\n");
p("private final boolean " + methodName + "() throws ExecutionException { /"+"* " + toHex(addr) + " - " + toHex(endOfMethod) + " *" + "/");
indent++;
p("int addr, tmp;");
p("int " + freqRegs[i] + " = this." + freqRegs[i] + ";");
p("for(;;) {");
indent++;
- p("switch(pc) {");
+ p("switch(pc>>2) {");
indent++;
startOfMethod = addr;
private static void endMethod(int lastAddr) {
if(startOfMethod == 0) return;
// This isn't strictly necessary; its just here to work around unreachable code errors
- p("case " + toHex(lastAddr) + ":");
+ p("case " + toHex(lastAddr>>2) + ":");
indent++;
p("pc=" + toHex(lastAddr) + ";");
leaveMethod();
if(debugCompiler)
p("lastPC = " + toHex(pc) + ";");
p("pc=" + toHex(target) + ";");
- if((pc&METHOD_MASK) == (target&METHOD_MASK))
+ if((pc>>LOG_MAX_BYTES_PER_METHOD) == (target>>LOG_MAX_BYTES_PER_METHOD))
p("continue;");
else
leaveMethod();
nextInsn = (i == count-1) ? -1 : dis.readInt();
if(addr >= endOfMethod) { endMethod(); startMethod(addr); }
if(jumpableAddresses==null || addr == startOfMethod || jumpableAddresses.contains(new Integer(addr))) {
- p("case " + toHex(addr) + ":");
+ p("case " + toHex(addr>>2) + ":");
unreachable = false;
} else if(unreachable) {
continue;