From: <cap...@us...> - 2007-03-24 23:14:37
|
Revision: 10 http://svn.sourceforge.net/pearcolator/?rev=10&view=rev Author: captain5050 Date: 2007-03-24 16:14:38 -0700 (Sat, 24 Mar 2007) Log Message: ----------- Fix dynamic linking, fix for lazy keys, branch code tidy up, try to spread the use of final fields. Modified Paths: -------------- src/org/binarytranslator/DBT_Options.java src/org/binarytranslator/arch/ppc/decoder/PPC2IR.java src/org/binarytranslator/arch/ppc/decoder/PPC_InstructionDecoder.java src/org/binarytranslator/arch/ppc/decoder/PPC_Laziness.java src/org/binarytranslator/arch/x86/decoder/X86_Laziness.java src/org/binarytranslator/generic/branch/BranchLogic.java src/org/binarytranslator/generic/decoder/DecoderUtils.java src/org/binarytranslator/generic/decoder/Laziness.java src/org/binarytranslator/generic/memory/ByteAddressedByteSwapMemory.java src/org/binarytranslator/generic/memory/ByteAddressedMemory.java src/org/binarytranslator/generic/memory/CallBasedMemory.java src/org/binarytranslator/generic/memory/IntAddressedByteSwapMemory.java src/org/binarytranslator/generic/memory/IntAddressedMemory.java src/org/binarytranslator/generic/memory/IntAddressedPreSwappedMemory.java src/org/binarytranslator/generic/memory/IntAddressedReversedMemory.java src/org/binarytranslator/generic/memory/Memory.java src/org/binarytranslator/generic/os/process/ProcessSpace.java src/org/binarytranslator/vmInterface/DBT_Trace.java src/org/binarytranslator/vmInterface/DynamicCodeRunner.java Modified: src/org/binarytranslator/DBT_Options.java =================================================================== --- src/org/binarytranslator/DBT_Options.java 2007-03-21 15:20:26 UTC (rev 9) +++ src/org/binarytranslator/DBT_Options.java 2007-03-24 23:14:38 UTC (rev 10) @@ -54,16 +54,11 @@ public final static boolean optimizeBackwardBranches = true; /** - * Set this to true to record uncaught bclr instructions + * Set this to true to record uncaught branch instructions */ - public static boolean plantUncaughtBclrWatcher = false; + public static boolean plantUncaughtBranchWatcher = false; /** - * Set this to true to record uncaught bcctr instructions - */ - public static boolean plantUncaughtBcctrWatcher = true; - - /** * Should all branches (excluding to lr and ctr) be resolved in one * big go or one at at a time */ Modified: src/org/binarytranslator/arch/ppc/decoder/PPC2IR.java =================================================================== --- src/org/binarytranslator/arch/ppc/decoder/PPC2IR.java 2007-03-21 15:20:26 UTC (rev 9) +++ src/org/binarytranslator/arch/ppc/decoder/PPC2IR.java 2007-03-24 23:14:38 UTC (rev 10) @@ -125,17 +125,9 @@ /** Reference to PPC process space pc field */ private static final VM_FieldReference pcFieldRef; - /** Reference to PPC process space recordUncaughtBclr method */ - private static final VM_MethodReference recordUncaughtBclrMethRef; - - /** Reference to PPC process space recordUncaughtBcctr method */ - private static final VM_MethodReference recordUncaughtBcctrMethRef; - /* Static initializer */ static { - psTref = VM_TypeReference.findOrCreate(VM_BootstrapClassLoader.getBootstrapClassLoader(), - VM_Atom.findOrCreateAsciiAtom("Lorg/binarytranslator/arch/ppc/os/process/PPC_ProcessSpace;") - ); + psTref = VM_TypeReference.findOrCreate(PPC_ProcessSpace.class); gprFieldRefs = new VM_FieldReference[32]; fprFieldRefs = new VM_FieldReference[32]; final VM_Atom intAtom = VM_Atom.findOrCreateAsciiAtom("I"); @@ -189,12 +181,6 @@ pcFieldRef = VM_MemberReference.findOrCreate(psTref,VM_Atom.findOrCreateAsciiAtom("pc"), intAtom ).asFieldReference(); - recordUncaughtBclrMethRef = (VM_MethodReference)VM_MemberReference.findOrCreate(psTref, - VM_Atom.findOrCreateAsciiAtom("recordUncaughtBclr"), - VM_Atom.findOrCreateAsciiAtom("(II)V")); - recordUncaughtBcctrMethRef = (VM_MethodReference)VM_MemberReference.findOrCreate(psTref, - VM_Atom.findOrCreateAsciiAtom("recordUncaughtBcctr"), - VM_Atom.findOrCreateAsciiAtom("(II)V")); } // -oO PPC register to HIR register mappings Oo- @@ -1018,58 +1004,6 @@ registerBranchAndLink(pc, pc+4, dest); } - // -oO Trace helping methods Oo- - - /** - * Plant a record bclr call. NB register state won't get resolved for call - * @param pc the address of the bclr instruction - * @param lr the link register value - */ - public void plantRecordUncaughtBclr(int pc, OPT_RegisterOperand lr) { - // Is it sensible to record this information? - if((gc.options.getOptLevel() > 0) && (DBT_Options.plantUncaughtBclrWatcher)) { - // Plant call - OPT_Instruction s = Call.create(CALL, null, null, null, null, 3); - VM_Method method = recordUncaughtBclrMethRef.resolve(); - OPT_MethodOperand methOp = OPT_MethodOperand.VIRTUAL(recordUncaughtBclrMethRef, method); - - OPT_Operand psRef = gc.makeLocal(1,psTref); - Call.setParam(s, 0, psRef); // Reference to ps, sets 'this' pointer - Call.setParam(s, 1, new OPT_IntConstantOperand(pc)); // Address of bclr instruction - Call.setParam(s, 2, lr); // Link register value - Call.setGuard(s, new OPT_TrueGuardOperand()); - Call.setMethod(s, methOp); - Call.setAddress(s, new OPT_AddressConstantOperand(recordUncaughtBclrMethRef.peekResolvedMethod().getOffset())); - s.position = gc.inlineSequence; - s.bcIndex = 7; - appendInstructionToCurrentBlock(s); - } - } - - /** - * Plant a record bcctr call. NB register state won't get resolved for call - * @param pc the address of the bclr instruction - * @param ctr the count register value - */ - public void plantRecordUncaughtBcctr(int pc, OPT_RegisterOperand ctr) { - if(DBT_Options.plantUncaughtBcctrWatcher) { - // Plant call - OPT_Instruction s = Call.create(CALL, null, null, null, null, 3); - VM_Method method = recordUncaughtBcctrMethRef.resolve(); - OPT_MethodOperand methOp = OPT_MethodOperand.VIRTUAL(recordUncaughtBcctrMethRef, method); - OPT_Operand psRef = gc.makeLocal(1,psTref); - Call.setParam(s, 0, psRef); // Reference to ps, sets 'this' pointer - Call.setParam(s, 1, new OPT_IntConstantOperand(pc)); // Address of bcctr instruction - Call.setParam(s, 2, ctr); // Count register value - Call.setGuard(s, new OPT_TrueGuardOperand()); - Call.setMethod(s, methOp); - Call.setAddress(s, new OPT_AddressConstantOperand(recordUncaughtBcctrMethRef.peekResolvedMethod().getOffset())); - s.position = gc.inlineSequence; - s.bcIndex = 13; - appendInstructionToCurrentBlock(s); - } - } - // -oO Optimisations on the generated HIR Oo- /** Modified: src/org/binarytranslator/arch/ppc/decoder/PPC_InstructionDecoder.java =================================================================== --- src/org/binarytranslator/arch/ppc/decoder/PPC_InstructionDecoder.java 2007-03-21 15:20:26 UTC (rev 9) +++ src/org/binarytranslator/arch/ppc/decoder/PPC_InstructionDecoder.java 2007-03-24 23:14:38 UTC (rev 10) @@ -13,6 +13,7 @@ import org.binarytranslator.arch.ppc.os.process.PPC_ProcessSpace; import org.binarytranslator.generic.fault.BadInstructionException; import org.binarytranslator.generic.decoder.InstructionDecoder; +import org.binarytranslator.generic.branch.BranchLogic; import org.jikesrvm.opt.ir.*; import org.jikesrvm.*; @@ -3338,7 +3339,7 @@ ppc2ir.appendInstructionToCurrentBlock(lookupswitch_instr); ppc2ir.registerLookupSwitchForReturnUnresolved(lookupswitch_instr, pc, (PPC_Laziness)lazy.clone()); ppc2ir.setCurrentBlock(fallThrough); - ppc2ir.plantRecordUncaughtBclr(pc, branchAddress.copyRO()); + ppc2ir.plantRecordUncaughtBranch(pc, branchAddress.copyRO(), BranchLogic.RETURN); ppc2ir.setReturnValueResolveLazinessAndBranchToFinish((PPC_Laziness)lazy.clone(), branchAddress.copyRO()); // stop translation on branch always @@ -3981,7 +3982,7 @@ ppc2ir.appendInstructionToCurrentBlock(lookupswitch_instr); ppc2ir.registerLookupSwitchForSwitchUnresolved(lookupswitch_instr, pc, (PPC_Laziness)lazy.clone(), lk != 0); ppc2ir.setCurrentBlock(fallThrough); - ppc2ir.plantRecordUncaughtBcctr(pc, branchAddress.copyRO()); + ppc2ir.plantRecordUncaughtBranch(pc, branchAddress.copyRO(), BranchLogic.INDIRECT_BRANCH); ppc2ir.setReturnValueResolveLazinessAndBranchToFinish((PPC_Laziness)lazy.clone(), branchAddress.copyRO()); // stop translation on branch always Modified: src/org/binarytranslator/arch/ppc/decoder/PPC_Laziness.java =================================================================== --- src/org/binarytranslator/arch/ppc/decoder/PPC_Laziness.java 2007-03-21 15:20:26 UTC (rev 9) +++ src/org/binarytranslator/arch/ppc/decoder/PPC_Laziness.java 2007-03-24 23:14:38 UTC (rev 10) @@ -17,6 +17,25 @@ */ public final class PPC_Laziness extends Laziness { /** + * Key for when laziness is stored in a hash table along with a PC + */ + class PPC_LazinessKey extends Key { + int pc; + public int hashCode() { + return pc; + } + public boolean equals(Object o) { + return ((o instanceof PPC_LazinessKey) && ((PPC_LazinessKey)o).pc == pc); + } + PPC_LazinessKey (int pc) { + this.pc = pc; + } + public String toString() { + return "0x" + Integer.toHexString(pc); + } + } + + /** * Default constructor - nothing is lazy */ PPC_Laziness() { @@ -39,23 +58,8 @@ * Generate a key value encoding this laziness and a PC value * @parm pc the PC value we're trying to make a key for */ - public Object makeKey(int pc) { - class Key { - int pc; - public int hashCode() { - return pc; - } - public boolean equals(Object o) { - return ((o instanceof Key) && ((Key)o).pc == pc); - } - Key (int pc) { - this.pc = pc; - } - public String toString() { - return "0x" + Integer.toHexString(pc); - } - } - return new Key(pc); + public Key makeKey(int pc) { + return new PPC_LazinessKey(pc); } /** Modified: src/org/binarytranslator/arch/x86/decoder/X86_Laziness.java =================================================================== --- src/org/binarytranslator/arch/x86/decoder/X86_Laziness.java 2007-03-21 15:20:26 UTC (rev 9) +++ src/org/binarytranslator/arch/x86/decoder/X86_Laziness.java 2007-03-24 23:14:38 UTC (rev 10) @@ -14,6 +14,32 @@ * Capture lazy information for X86 */ public class X86_Laziness extends Laziness { + /** + * Key for when laziness is stored in a hash table along with a PC + */ + static class X86_LazinessKey extends Key { + private final int mangledRegisterState; + private final int pc; + X86_LazinessKey(int mangledRegisterState, int pc) { + this.mangledRegisterState = mangledRegisterState; + this.pc = pc; + } + public boolean equals(Object o) { + if (o instanceof X86_LazinessKey) { + X86_LazinessKey other = (X86_LazinessKey)o; + return (other.pc == pc) && (other.mangledRegisterState == mangledRegisterState); + } else { + return false; + } + } + public int hashCode() { + return mangledRegisterState ^ pc; + } + public String toString() { + return "0x" + Integer.toHexString(pc) + ".0x" + Integer.toHexString(mangledRegisterState); + } + } + /** * In this state, is the 32bit register valid? (default) */ @@ -69,8 +95,8 @@ * Given the current program position make a key object that will * allow */ - public Object makeKey(int pc) { - return new Long(((long)mangledRegisterState << 32) | pc); + public Key makeKey(int pc) { + return new X86_LazinessKey(mangledRegisterState, pc); } /** Modified: src/org/binarytranslator/generic/branch/BranchLogic.java =================================================================== --- src/org/binarytranslator/generic/branch/BranchLogic.java 2007-03-21 15:20:26 UTC (rev 9) +++ src/org/binarytranslator/generic/branch/BranchLogic.java 2007-03-24 23:14:38 UTC (rev 10) @@ -22,15 +22,21 @@ * terminating on branches whose destinations aren't known */ public class BranchLogic { + /** Code to indicate branch was an indirect branch */ + public static final int INDIRECT_BRANCH=0; + + /** Code to indicate branch was a return */ + public static final int RETURN=1; + /** * A set of procedure information */ - private SortedMap procedures; + private final SortedMap procedures; /** * A set of switch like branchs sites and their destinations */ - private SortedMap branchSitesAndDestinations; + private final SortedMap branchSitesAndDestinations; /** * Global branch information @@ -61,13 +67,13 @@ * @param dest the destination of the branch instruction */ public void registerCall(int pc, int ret, int dest) { - ProcedureInformation procedure = (ProcedureInformation)procedures.get(new Integer(dest)); + ProcedureInformation procedure = (ProcedureInformation)procedures.get(Integer.valueOf(dest)); if (procedure != null) { procedure.registerCall(pc, ret); } else { procedure = new ProcedureInformation(pc, ret, dest); - procedures.put(new Integer(dest), procedure); + procedures.put(Integer.valueOf(dest), procedure); } } @@ -90,7 +96,7 @@ */ private ProcedureInformation getLikelyProcedure(int pc) { if (procedures.size() > 0) { - SortedMap priorProcedures = procedures.headMap(new Integer(pc)); + SortedMap priorProcedures = procedures.headMap(Integer.valueOf(pc)); if (priorProcedures.size() > 0) { Integer procedureEntry = (Integer)priorProcedures.lastKey(); return (ProcedureInformation)procedures.get(procedureEntry); @@ -104,19 +110,19 @@ * @param pc the address of the branch instruction * @param lr the value of the link register */ - public void registerBranch(int pc, int ctr) { - Set dests = (Set)branchSitesAndDestinations.get(new Integer(pc)); + public void registerBranch(int pc, int ctr, int type) { + Set dests = (Set)branchSitesAndDestinations.get(Integer.valueOf(pc)); if (dests != null) { - if (dests.contains(new Integer(ctr))) { + if (dests.contains(Integer.valueOf(ctr))) { // This ctr address is already registered return; } } else { dests = new HashSet(); - branchSitesAndDestinations.put(new Integer(pc), dests); + branchSitesAndDestinations.put(Integer.valueOf(pc), dests); } - dests.add(new Integer(ctr)); + dests.add(Integer.valueOf(ctr)); } } Modified: src/org/binarytranslator/generic/decoder/DecoderUtils.java =================================================================== --- src/org/binarytranslator/generic/decoder/DecoderUtils.java 2007-03-21 15:20:26 UTC (rev 9) +++ src/org/binarytranslator/generic/decoder/DecoderUtils.java 2007-03-24 23:14:38 UTC (rev 10) @@ -18,6 +18,7 @@ import org.binarytranslator.vmInterface.DBT_Trace; import org.binarytranslator.vmInterface.TranslationHelper; import org.binarytranslator.generic.os.process.ProcessSpace; +import org.binarytranslator.generic.fault.BadInstructionException; import org.binarytranslator.DBT_Options; import org.jikesrvm.VM; @@ -84,7 +85,174 @@ * </dl> */ public abstract class DecoderUtils implements OPT_Constants, OPT_Operators, TranslationHelper { + // -oO Constants Oo- + + /** + * VM_TypeReference of + * org.binarytranslator.generic.os.process.ProcessSpace + */ + private static final VM_TypeReference psTref; + + /** + * Method ProcessSpace.doSysCall + */ + public static final VM_Method sysCallMethod; + + /** + * VM_TypeReference of + * org.binarytranslator.generic.fault.BadInstructionException + */ + private static final VM_Class badInstrKlass; + + /** + * Method BadInstructionException.<init> + */ + public static final VM_Method badInstrKlassInitMethod; + + /** + * Method ProcessSpace.recordUncaughtBranchBadInstructionException.<init> + */ + public static final VM_Method recordUncaughtBranchMethod; + + static { + psTref = java.lang.JikesRVMSupport.getTypeForClass(ProcessSpace.class).getTypeRef(); + VM_MethodReference sysCallMethRef = (VM_MethodReference) + VM_MemberReference.findOrCreate(psTref, + VM_Atom.findOrCreateAsciiAtom("doSysCall"), + VM_Atom.findOrCreateAsciiAtom("()V")); + sysCallMethod = sysCallMethRef.resolveInvokeSpecial(); + + badInstrKlass = java.lang.JikesRVMSupport.getTypeForClass(BadInstructionException.class).asClass(); + + VM_MethodReference badInstrKlassInitMethRef = (VM_MethodReference) + VM_MemberReference.findOrCreate(badInstrKlass.getTypeRef(), + VM_Atom.findOrCreateAsciiAtom("<init>"), + VM_Atom.findOrCreateAsciiAtom("(I" + + psTref.getName() + + ")V")); + badInstrKlassInitMethod = badInstrKlassInitMethRef.resolveInvokeSpecial(); + + VM_MethodReference recordUncaughtBranchMethRef = (VM_MethodReference) + VM_MemberReference.findOrCreate(psTref, + VM_Atom.findOrCreateAsciiAtom("recordUncaughtBranch"), + VM_Atom.findOrCreateAsciiAtom("(III)V")); + recordUncaughtBranchMethod = recordUncaughtBranchMethRef.resolveInvokeSpecial(); + } + + + // -oO Global IR Oo- + + /** + * Number of translated instructions + */ + public int numberOfInstructions; + + /** + * The process space object used by the running PPC binary. + */ + public ProcessSpace ps; + + /** + * The generation context. + */ + protected OPT_GenerationContext gc; + + // -oO Global HIR basic blocks Oo- + + /** + * The OPT_BasicBlock in which instructions are currently being + * inserted + */ + protected OPT_BasicBlock currentBlock; + + /** + * The pc value corresponding to the instruction currently being + * translated + */ + protected int currentPC; + + /** + * The OPT_BasicBlock which will contain the next translated instruction + */ + protected OPT_BasicBlock nextBlock; + + /** + * The basic block is used by finish trace to hold all the code that + * must be executed before returning to the main run loop + */ + protected OPT_BasicBlock finishBlock; + + /** + * This block gets instructions to pre-fill registers inserted into + * it. + */ + protected OPT_BasicBlock preFillBlock; + + /** + * Map to locate HIR basic blocks to re-use translation within a + * trace + */ + protected final HashMap<Laziness.Key,OPT_BasicBlock> blockMap; + + /** + * List of unresolved Goto instructions + */ + protected final ArrayList<OPT_Instruction> unresolvedGoto; + + /** + * List of where unresolved Goto instructions are trying to go + */ + protected final ArrayList<Integer> unresolvedGoto_PC; + /** + * List of what the unresolved Goto instruction's target laziness should be + */ + protected final ArrayList<Laziness> unresolvedGoto_Laziness; + + /** + * List of unresolved IfCmp instructions + */ + protected final ArrayList<OPT_Instruction> unresolvedIfCmp; + /** + * List of where unresolved IfCmp instructions are trying to go + */ + protected final ArrayList<Integer> unresolvedIfCmp_PC; + /** + * List of what the unresolved IfCmp instruction's target laziness should be + */ + protected final ArrayList<Laziness> unresolvedIfCmp_Laziness; + + /** + * List of unresolved LookupSwitch instructions used for branching to the link register + */ + protected final ArrayList<OPT_Instruction> unresolvedLookupSwitchForReturns; + /** + * List of where unresolved Goto instructions are trying to go + */ + protected final ArrayList<Integer> unresolvedLookupSwitchForReturns_PC; + /** + * List of what the unresolved Goto instruction's target laziness should be + */ + protected final ArrayList<Laziness> unresolvedLookupSwitchForReturns_Laziness; + + /** + * List of unresolved LookupSwitch instructions used for branching to the count register + */ + protected final ArrayList<OPT_Instruction> unresolvedLookupSwitchForSwitches; + /** + * List of where unresolved LookupSwitch instructions are branching from + */ + protected final ArrayList<Integer> unresolvedLookupSwitchForSwitches_PC; + /** + * List of what the unresolved LookupSwitch instruction's target laziness should be + */ + protected final ArrayList<Laziness> unresolvedLookupSwitchForSwitches_Laziness; + /** + * List of whether the unresolved LookupSwitch instruction's was a call + */ + protected final ArrayList<Boolean> unresolvedLookupSwitchForSwitches_WasCall; + // -oO Debug Oo- + /** * Report some debug output */ @@ -117,22 +285,22 @@ finishBlock = createBlockAfterCurrent(); // Fix up stores - unresolvedGoto = new ArrayList(); - unresolvedGoto_PC = new ArrayList(); - unresolvedGoto_Laziness = new ArrayList(); + unresolvedGoto = new ArrayList<OPT_Instruction>(); + unresolvedGoto_PC = new ArrayList<Integer>(); + unresolvedGoto_Laziness = new ArrayList<Laziness>(); - unresolvedIfCmp = new ArrayList(); - unresolvedIfCmp_PC = new ArrayList(); - unresolvedIfCmp_Laziness = new ArrayList(); + unresolvedIfCmp = new ArrayList<OPT_Instruction>(); + unresolvedIfCmp_PC = new ArrayList<Integer>(); + unresolvedIfCmp_Laziness = new ArrayList<Laziness>(); - unresolvedLookupSwitchForReturns = new ArrayList(); - unresolvedLookupSwitchForReturns_PC = new ArrayList(); - unresolvedLookupSwitchForReturns_Laziness = new ArrayList(); + unresolvedLookupSwitchForReturns = new ArrayList<OPT_Instruction>(); + unresolvedLookupSwitchForReturns_PC = new ArrayList<Integer>(); + unresolvedLookupSwitchForReturns_Laziness = new ArrayList<Laziness>(); - unresolvedLookupSwitchForSwitches = new ArrayList(); - unresolvedLookupSwitchForSwitches_PC = new ArrayList(); - unresolvedLookupSwitchForSwitches_Laziness = new ArrayList(); - unresolvedLookupSwitchForSwitches_WasCall = new ArrayList(); + unresolvedLookupSwitchForSwitches = new ArrayList<OPT_Instruction>(); + unresolvedLookupSwitchForSwitches_PC = new ArrayList<Integer>(); + unresolvedLookupSwitchForSwitches_Laziness = new ArrayList<Laziness>(); + unresolvedLookupSwitchForSwitches_WasCall = new ArrayList<Boolean>(); } /** @@ -253,62 +421,7 @@ */ protected abstract int translateInstruction(Laziness lazy, int pc); - // -oO Global IR Oo- - /** - * Number of translated instructions - */ - public int numberOfInstructions; - - /** - * The process space object used by the running PPC binary. - */ - public ProcessSpace ps; - - /** - * The generation context. - */ - protected OPT_GenerationContext gc; - - /** - * Get the generation context. - */ - public OPT_GenerationContext getGenerationContext() { - return gc; - } - - // -oO Global HIR basic blocks Oo- - - /** - * The OPT_BasicBlock in which instructions are currently being - * inserted - */ - protected OPT_BasicBlock currentBlock; - - /** - * The pc value corresponding to the instruction currently being - * translated - */ - protected int currentPC; - - /** - * The OPT_BasicBlock which will contain the next translated instruction - */ - protected OPT_BasicBlock nextBlock; - - /** - * The basic block is used by finish trace to hold all the code that - * must be executed before returning to the main run loop - */ - protected OPT_BasicBlock finishBlock; - - /** - * This block gets instructions to pre-fill registers inserted into - * it. - */ - protected OPT_BasicBlock preFillBlock; - - /** * Get the block which is currently having instructions inserted * into it * @return the current block @@ -421,7 +534,12 @@ public void appendInstructionToCurrentBlock(OPT_Instruction i) { if(i.bcIndex == UNKNOWN_BCI) { i.position = gc.inlineSequence; - i.bcIndex = (currentPC >> 2) & 0xFFFF; + // we only have 16bits to distinguish instructions (the bcIndex + // is effective 16bit when stored in the machine code map), + // Intel can't distinguish branches within 16bytes, so neither + // can we, the top bit is saved for distinguished addresses we + // need to know to dynamically link things + i.bcIndex = (currentPC >> 4) & 0x7FFF; } currentBlock.appendInstruction(i); } @@ -447,71 +565,16 @@ spillAllRegisters(); } - // -oO Laziness Oo- - - /** - * Map to locate HIR basic blocks to re-use translation within a - * trace - */ - protected HashMap blockMap; - /** - * List of unresolved Goto instructions + * Get the generation context. */ - protected ArrayList unresolvedGoto; - /** - * List of where unresolved Goto instructions are trying to go - */ - protected ArrayList unresolvedGoto_PC; - /** - * List of what the unresolved Goto instruction's target laziness should be - */ - protected ArrayList unresolvedGoto_Laziness; + public OPT_GenerationContext getGenerationContext() { + return gc; + } - /** - * List of unresolved IfCmp instructions - */ - protected ArrayList unresolvedIfCmp; - /** - * List of where unresolved IfCmp instructions are trying to go - */ - protected ArrayList unresolvedIfCmp_PC; - /** - * List of what the unresolved IfCmp instruction's target laziness should be - */ - protected ArrayList unresolvedIfCmp_Laziness; + // -oO Laziness Oo- /** - * List of unresolved LookupSwitch instructions used for branching to the link register - */ - protected ArrayList unresolvedLookupSwitchForReturns; - /** - * List of where unresolved Goto instructions are trying to go - */ - protected ArrayList unresolvedLookupSwitchForReturns_PC; - /** - * List of what the unresolved Goto instruction's target laziness should be - */ - protected ArrayList unresolvedLookupSwitchForReturns_Laziness; - - /** - * List of unresolved LookupSwitch instructions used for branching to the count register - */ - protected ArrayList unresolvedLookupSwitchForSwitches; - /** - * List of where unresolved LookupSwitch instructions are branching from - */ - protected ArrayList unresolvedLookupSwitchForSwitches_PC; - /** - * List of what the unresolved LookupSwitch instruction's target laziness should be - */ - protected ArrayList unresolvedLookupSwitchForSwitches_Laziness; - /** - * List of whether the unresolved LookupSwitch instruction's was a call - */ - protected ArrayList unresolvedLookupSwitchForSwitches_WasCall; - - /** * Create the initial object for capturing lazy information */ protected abstract Laziness createInitialLaziness(); @@ -538,7 +601,7 @@ * @return basic block or null if no translation exists */ public OPT_BasicBlock findMapping(int pc, Laziness lazy) { - return (OPT_BasicBlock)blockMap.get(lazy.makeKey(pc)); + return blockMap.get(lazy.makeKey(pc)); } /** @@ -549,7 +612,7 @@ */ public void registerIfCmpTargetUnresolved(OPT_Instruction ifcmp_instr, int targetPC, Laziness targetLaziness){ unresolvedIfCmp.add(ifcmp_instr); - unresolvedIfCmp_PC.add(new Integer(targetPC)); + unresolvedIfCmp_PC.add(targetPC); unresolvedIfCmp_Laziness.add(targetLaziness); } @@ -596,7 +659,7 @@ */ public void registerGotoTargetUnresolved(OPT_Instruction goto_instr, int targetPC, Laziness targetLaziness){ unresolvedGoto.add(goto_instr); - unresolvedGoto_PC.add(new Integer(targetPC)); + unresolvedGoto_PC.add(targetPC); unresolvedGoto_Laziness.add(targetLaziness); } @@ -662,7 +725,7 @@ */ public void registerLookupSwitchForReturnUnresolved(OPT_Instruction lookupswitch_instr, int pc, Laziness targetLaziness){ unresolvedLookupSwitchForReturns.add(lookupswitch_instr); - unresolvedLookupSwitchForReturns_PC.add(new Integer(pc)); + unresolvedLookupSwitchForReturns_PC.add(pc); unresolvedLookupSwitchForReturns_Laziness.add(targetLaziness); } /** @@ -769,9 +832,9 @@ */ public void registerLookupSwitchForSwitchUnresolved(OPT_Instruction lookupswitch_instr, int pc, Laziness targetLaziness, boolean link){ unresolvedLookupSwitchForSwitches.add(lookupswitch_instr); - unresolvedLookupSwitchForSwitches_PC.add(new Integer(pc)); + unresolvedLookupSwitchForSwitches_PC.add(pc); unresolvedLookupSwitchForSwitches_Laziness.add(targetLaziness); - unresolvedLookupSwitchForSwitches_WasCall.add(Boolean.valueOf(link)); + unresolvedLookupSwitchForSwitches_WasCall.add(link); } /** * Are all LookupSwitch instructions for branches to CTR ready to be @@ -1024,25 +1087,19 @@ // Plant call OPT_Instruction s = Call.create(CALL, null, null, null, null, 1); - VM_TypeReference psTref = VM_TypeReference.findOrCreate(VM_BootstrapClassLoader.getBootstrapClassLoader(), - VM_Atom.findOrCreateAsciiAtom("Lorg/binarytranslator/arch/ppc/os/process/PPC_ProcessSpace;") - ); - VM_MethodReference methRef = (VM_MethodReference)VM_MemberReference.findOrCreate(psTref, - VM_Atom.findOrCreateAsciiAtom("doSysCall"), - VM_Atom.findOrCreateAsciiAtom("()V")); - VM_Method method = methRef.resolveInvokeSpecial(); // VM_CompiledMethod cm = method.getCurrentCompiledMethod(); // OPT_MethodOperand methOp = OPT_MethodOperand.COMPILED(method, cm.getOsrJTOCoffset()); - OPT_MethodOperand methOp = OPT_MethodOperand.VIRTUAL(methRef, method); + OPT_MethodOperand methOp = OPT_MethodOperand.VIRTUAL(sysCallMethod.getMemberRef().asMethodReference(), + sysCallMethod); OPT_Operand psRef = gc.makeLocal(1,psTref); Call.setParam(s, 0, psRef); // Reference to ps, sets 'this' pointer for doSysCall Call.setGuard(s, new OPT_TrueGuardOperand()); Call.setMethod(s, methOp); - Call.setAddress(s, new OPT_AddressConstantOperand(methRef.peekResolvedMethod().getOffset())); + Call.setAddress(s, new OPT_AddressConstantOperand(sysCallMethod.getOffset())); s.position = gc.inlineSequence; - s.bcIndex = 7; + s.bcIndex = DBT_Trace.DO_SYSCALL; appendInstructionToCurrentBlock(s); // Fill all registers again following system call @@ -1065,52 +1122,40 @@ resolveLaziness(lazy); spillAllRegisters(); - VM_TypeReference eTref = VM_TypeReference.findOrCreate(VM_BootstrapClassLoader.getBootstrapClassLoader(), - VM_Atom.findOrCreateAsciiAtom("Lorg/binarytranslator/generic/os/fault/BadInstructionException;") - ); - VM_Class badInstrKlass = (VM_Class)eTref.peekResolvedType(); OPT_Operator newOperator; - OPT_TypeOperand typeOperand; + OPT_TypeOperand typeOperand = new OPT_TypeOperand(badInstrKlass); + VM_TypeReference eTref = badInstrKlass.getTypeRef(); - if ((badInstrKlass != null) && (badInstrKlass.isInitialized() || badInstrKlass.isInBootImage())) { + if (badInstrKlass.isInitialized() || badInstrKlass.isInBootImage()) { newOperator = NEW; - typeOperand = new OPT_TypeOperand(badInstrKlass); - } - else { + } else { newOperator = NEW_UNRESOLVED; - typeOperand = new OPT_TypeOperand(eTref); } OPT_RegisterOperand eRef = gc.temps.makeTemp(eTref); OPT_Instruction n = New.create(newOperator,eRef, typeOperand); n.position = gc.inlineSequence; - n.bcIndex = 0; + n.bcIndex = DBT_Trace.BAD_INSTRUCTION_NEW; - VM_MemberReference methRef = VM_MemberReference.findOrCreate(eTref, VM_Atom.findOrCreateAsciiAtom("<init>"), - VM_Atom.findOrCreateAsciiAtom("(ILorg/binarytranslator/arch/ppc/os/process/PPC_ProcessSpace;)V")); - VM_Method method = ((VM_MethodReference)methRef).resolveInvokeSpecial(); - OPT_MethodOperand methOp = OPT_MethodOperand.VIRTUAL((VM_MethodReference)methRef, method); - VM_TypeReference psTref = VM_TypeReference.findOrCreate(VM_BootstrapClassLoader.getBootstrapClassLoader(), - VM_Atom.findOrCreateAsciiAtom("Lorg/binarytranslator/arch/ppc/os/process/PPC_ProcessSpace;") - ); - OPT_Operand psRef = gc.makeLocal(1,psTref); OPT_Instruction c = Call.create(CALL, null, null, null, null, 3); + OPT_MethodOperand methOp = OPT_MethodOperand.VIRTUAL(badInstrKlassInitMethod.getMemberRef().asMethodReference(), + badInstrKlassInitMethod); Call.setParam(c, 0, eRef.copy()); // 'this' pointer in BadInstructionException.init Call.setParam(c, 1, new OPT_IntConstantOperand(pc)); Call.setParam(c, 2, psRef); Call.setGuard(c, new OPT_TrueGuardOperand()); Call.setMethod(c, methOp); - Call.setAddress(c, new OPT_AddressConstantOperand(((VM_MethodReference)methRef).peekResolvedMethod().getOffset())); + Call.setAddress(c, new OPT_AddressConstantOperand(badInstrKlassInitMethod.getOffset())); c.position = gc.inlineSequence; - c.bcIndex = 21; + c.bcIndex = DBT_Trace.BAD_INSTRUCTION_INIT; OPT_Instruction t = Athrow.create(ATHROW, eRef.copyRO()); t.position = gc.inlineSequence; - t.bcIndex = 0; + t.bcIndex = DBT_Trace.BAD_INSTRUCTION_THROW; appendInstructionToCurrentBlock(n); @@ -1122,6 +1167,35 @@ } } + // -oO Trace helping methods Oo- + + /** + * Plant a record uncaught branch call. NB register state won't get resolved for call + * @param pc the address of the branch instruction + * @param destination the register operand holding the destination + * @param code a code that can be a hint of the branch type + */ + public void plantRecordUncaughtBranch(int pc, OPT_RegisterOperand destination, int code) { + // Is it sensible to record this information? + if((gc.options.getOptLevel() > 0) && (DBT_Options.plantUncaughtBranchWatcher)) { + // Plant call + OPT_Instruction s = Call.create(CALL, null, null, null, null, 4); + OPT_MethodOperand methOp = OPT_MethodOperand.VIRTUAL(recordUncaughtBranchMethod.getMemberRef().asMethodReference(), + recordUncaughtBranchMethod); + OPT_Operand psRef = gc.makeLocal(1,psTref); + Call.setParam(s, 0, psRef); // Reference to ps, sets 'this' pointer + Call.setParam(s, 1, new OPT_IntConstantOperand(pc)); // Address of branch instruction + Call.setParam(s, 2, destination); // Destination of branch value + Call.setParam(s, 3, new OPT_IntConstantOperand(code)); // Branch code value + Call.setGuard(s, new OPT_TrueGuardOperand()); + Call.setMethod(s, methOp); + Call.setAddress(s, new OPT_AddressConstantOperand(recordUncaughtBranchMethod.getOffset())); + s.position = gc.inlineSequence; + s.bcIndex = DBT_Trace.RECORD_BRANCH; + appendInstructionToCurrentBlock(s); + } + } + // -oO Temporaries used during translation Oo- /** @@ -1274,8 +1348,8 @@ /** * Get the method */ - public VM_Method getMethod() { - return gc.method; + public DBT_Trace getMethod() { + return (DBT_Trace)gc.method; } /** * Make a temporary register Modified: src/org/binarytranslator/generic/decoder/Laziness.java =================================================================== --- src/org/binarytranslator/generic/decoder/Laziness.java 2007-03-21 15:20:26 UTC (rev 9) +++ src/org/binarytranslator/generic/decoder/Laziness.java 2007-03-24 23:14:38 UTC (rev 10) @@ -20,6 +20,12 @@ * elimination will suffice. */ public abstract class Laziness { + /** + * A Key class used when making a key from the laziness and PC + * value combined + */ + public static class Key {} + /** * Constructor */ @@ -35,7 +41,7 @@ * Given the current program position make a key object that will * allow */ - public abstract Object makeKey(int pc); + public abstract Key makeKey(int pc); /** * Create a copy of this lazy state - usually to record where one Modified: src/org/binarytranslator/generic/memory/ByteAddressedByteSwapMemory.java =================================================================== --- src/org/binarytranslator/generic/memory/ByteAddressedByteSwapMemory.java 2007-03-21 15:20:26 UTC (rev 9) +++ src/org/binarytranslator/generic/memory/ByteAddressedByteSwapMemory.java 2007-03-24 23:14:38 UTC (rev 10) @@ -35,7 +35,7 @@ * Constructor - used when this is the instatiated class */ public ByteAddressedByteSwapMemory() { - super("org/binarytranslator/generic/memory/ByteAddressedByteSwapMemory"); + super(ByteAddressedByteSwapMemory.class); } /** * Perform a 16bit load where the sign extended result fills the Modified: src/org/binarytranslator/generic/memory/ByteAddressedMemory.java =================================================================== --- src/org/binarytranslator/generic/memory/ByteAddressedMemory.java 2007-03-21 15:20:26 UTC (rev 9) +++ src/org/binarytranslator/generic/memory/ByteAddressedMemory.java 2007-03-24 23:14:38 UTC (rev 10) @@ -63,17 +63,17 @@ * Constructor - used when this is the instatiated class */ public ByteAddressedMemory() { - super("org/binarytranslator/generic/memory/ByteAddressedMemory"); + super(ByteAddressedMemory.class); readableMemory = new byte[NUM_PAGES][]; writableMemory = new byte[NUM_PAGES][]; executableMemory = new byte[NUM_PAGES][]; } /** * Constructor - used when deriving a class - * @param className the name of the over-riding class + * @param classType the name of the over-riding class */ - protected ByteAddressedMemory(String className) { - super(className); + protected ByteAddressedMemory(Class classType) { + super(classType); readableMemory = new byte[NUM_PAGES][]; writableMemory = new byte[NUM_PAGES][]; executableMemory = new byte[NUM_PAGES][]; Modified: src/org/binarytranslator/generic/memory/CallBasedMemory.java =================================================================== --- src/org/binarytranslator/generic/memory/CallBasedMemory.java 2007-03-21 15:20:26 UTC (rev 9) +++ src/org/binarytranslator/generic/memory/CallBasedMemory.java 2007-03-24 23:14:38 UTC (rev 10) @@ -29,6 +29,8 @@ import org.jikesrvm.opt.ir.OPT_RegisterOperand; import org.jikesrvm.opt.ir.OPT_TrueGuardOperand; import org.binarytranslator.vmInterface.TranslationHelper; +import org.binarytranslator.vmInterface.DBT_Trace; +import org.binarytranslator.generic.os.process.ProcessSpace; /** * CallBasedMemory abstraction: @@ -37,23 +39,59 @@ * which are still abstract, ie there's no memory backing store yet */ public abstract class CallBasedMemory extends Memory implements OPT_Operators { + /** - * The name of the class we are to plant calls to + * The process space type reference */ - private final VM_Atom memoryClassName; + private static final VM_TypeReference psTref; /** - * The name of the store methods + * Field reference to ps.memory */ - private final VM_Atom store8, store16, store32; + private static final VM_FieldReference psMemoryRef; + + static { + psTref = VM_TypeReference.findOrCreate(ProcessSpace.class); + psMemoryRef = VM_MemberReference.findOrCreate(psTref, + VM_Atom.findOrCreateAsciiAtom("memory"), + VM_Atom.findOrCreateAsciiAtom + ("Lorg/binarytranslator/generic/memory/Memory;") + ).asFieldReference(); + } /** - * The name of the load methods + * The store 8 method */ - private final VM_Atom loadS8, loadU8, loadS16, loadU16, load32; + private final VM_Method store8; /** - * Descriptors for the methods + * The store 16 method */ - private final VM_Atom storeDescriptor, loadDescriptor; + private final VM_Method store16; /** + * The store 32 method + */ + private final VM_Method store32; + + /** + * The load signed 8 method + */ + private final VM_Method loadS8; + /** + * The load unsigned 8 method + */ + private final VM_Method loadU8; + /** + * The load signed 8 method + */ + private final VM_Method loadS16; + /** + * The load unsigned 8 method + */ + private final VM_Method loadU16; + /** + * The load 32 method + */ + private final VM_Method load32; + + /** * Type of underlying memory */ final VM_TypeReference memoryType; @@ -74,20 +112,44 @@ * Constructor * @param className the name of the over-riding class */ - protected CallBasedMemory(String className) { - this.memoryClassName = VM_Atom.findOrCreateAsciiAtom("L"+className+";"); - store8 = VM_Atom.findOrCreateAsciiAtom("store8"); - store16 = VM_Atom.findOrCreateAsciiAtom("store16"); - store32 = VM_Atom.findOrCreateAsciiAtom("store32"); - storeDescriptor = VM_Atom.findOrCreateAsciiAtom("(II)V"); - loadS8 = VM_Atom.findOrCreateAsciiAtom("loadSigned8"); - loadU8 = VM_Atom.findOrCreateAsciiAtom("loadUnsigned8"); - loadS16 = VM_Atom.findOrCreateAsciiAtom("loadSigned16"); - loadU16 = VM_Atom.findOrCreateAsciiAtom("loadUnsigned16"); - load32 = VM_Atom.findOrCreateAsciiAtom("load32"); - loadDescriptor = VM_Atom.findOrCreateAsciiAtom("(I)I"); - memoryType = VM_TypeReference.findOrCreate(VM_BootstrapClassLoader.getBootstrapClassLoader(), - memoryClassName); + protected CallBasedMemory(Class memoryClass) { + memoryType = VM_TypeReference.findOrCreate(memoryClass); + + VM_Atom storeDescriptor = VM_Atom.findOrCreateAsciiAtom("(II)V"); + store8 = VM_MemberReference.findOrCreate(memoryType, + VM_Atom.findOrCreateAsciiAtom("store8"), + storeDescriptor + ).asMethodReference().resolve(); + store16 = VM_MemberReference.findOrCreate(memoryType, + VM_Atom.findOrCreateAsciiAtom("store16"), + storeDescriptor + ).asMethodReference().resolve(); + store32 = VM_MemberReference.findOrCreate(memoryType, + VM_Atom.findOrCreateAsciiAtom("store32"), + storeDescriptor + ).asMethodReference().resolve(); + + VM_Atom loadDescriptor = VM_Atom.findOrCreateAsciiAtom("(I)I"); + loadS8 = VM_MemberReference.findOrCreate(memoryType, + VM_Atom.findOrCreateAsciiAtom("loadSigned8"), + loadDescriptor + ).asMethodReference().resolve(); + loadU8 = VM_MemberReference.findOrCreate(memoryType, + VM_Atom.findOrCreateAsciiAtom("loadUnsigned8"), + loadDescriptor + ).asMethodReference().resolve(); + loadS16 = VM_MemberReference.findOrCreate(memoryType, + VM_Atom.findOrCreateAsciiAtom("loadSigned16"), + loadDescriptor + ).asMethodReference().resolve(); + loadU16 = VM_MemberReference.findOrCreate(memoryType, + VM_Atom.findOrCreateAsciiAtom("loadUnsigned16"), + loadDescriptor + ).asMethodReference().resolve(); + load32 = VM_MemberReference.findOrCreate(memoryType, + VM_Atom.findOrCreateAsciiAtom("load32"), + loadDescriptor + ).asMethodReference().resolve(); } /** * Generate memory prologue,... for the beignning of a @@ -96,55 +158,35 @@ public void initTranslate(TranslationHelper helper) { this.helper = helper; this.gc = helper.getGenerationContext(); - VM_TypeReference psTref = VM_TypeReference.findOrCreate(VM_BootstrapClassLoader.getBootstrapClassLoader(), - VM_Atom.findOrCreateAsciiAtom("Lorg/binarytranslator/generic/os/process/ProcessSpace;") - ); - VM_FieldReference ref = VM_MemberReference.findOrCreate(psTref, VM_Atom.findOrCreateAsciiAtom("memory"), - VM_Atom.findOrCreateAsciiAtom - ("Lorg/binarytranslator/generic/memory/Memory;") - ).asFieldReference(); OPT_RegisterOperand memoryOp = helper.makeTemp(memoryType); helper.appendInstructionToCurrentBlock(GetField.create(GETFIELD, memoryOp, gc.makeLocal(1,psTref), - new OPT_AddressConstantOperand(ref.peekResolvedField().getOffset()), - new OPT_LocationOperand(ref), + new OPT_AddressConstantOperand(psMemoryRef.peekResolvedField().getOffset()), + new OPT_LocationOperand(psMemoryRef), new OPT_TrueGuardOperand())); memory = memoryOp.register; } /** * Generate the IR code for the specified load - * @param loadType the atom name of the type of load + * @param loadMethod the load method to create * @param bcIndex the bytecode index in * DummyDynamicCodeRunner.invokeCode of this method call - required * for lazy method resolution. * @param dest the register to hold the result * @param addr the address of the value to load */ - private void translateLoad(VM_Atom loadType, int bcIndex, OPT_RegisterOperand addr, OPT_RegisterOperand dest) { + private void translateLoad(VM_Method loadMethod, int bcIndex, OPT_RegisterOperand addr, OPT_RegisterOperand dest) { OPT_Instruction s = Call.create(CALL, dest, null, null, null, - 2); - VM_MemberReference methRef = VM_MemberReference.findOrCreate(memoryType, - loadType, - loadDescriptor - ); - boolean unresolved = methRef.needsDynamicLink(helper.getMethod()); - VM_Method method = ((VM_MethodReference)methRef).resolveInvokeSpecial(); - OPT_MethodOperand methOp = OPT_MethodOperand.VIRTUAL((VM_MethodReference)methRef, method); + 2); + VM_MethodReference loadMethRef = loadMethod.getMemberRef().asMethodReference(); + + OPT_MethodOperand methOp = OPT_MethodOperand.VIRTUAL(loadMethRef, loadMethod); OPT_RegisterOperand memoryOp = new OPT_RegisterOperand(memory, memoryType); Call.setParam(s, 0, memoryOp); // Sets 'this' pointer Call.setParam(s, 1, addr); Call.setGuard(s, new OPT_TrueGuardOperand()); Call.setMethod(s, methOp); - if (unresolved) { - OPT_RegisterOperand offsetrop = gc.temps.makeTempOffset(); - helper.appendInstructionToCurrentBlock(Unary.create(RESOLVE_MEMBER, offsetrop, - Call.getMethod(s).copy())); - Call.setAddress(s, offsetrop.copyRO()); - } - else { - Call.setAddress(s, new OPT_AddressConstantOperand - (((VM_MethodReference)methRef).peekResolvedMethod().getOffset())); - } + Call.setAddress(s, new OPT_AddressConstantOperand(loadMethod.getOffset())); s.position = gc.inlineSequence; s.bcIndex = bcIndex; helper.appendInstructionToCurrentBlock(s); @@ -156,7 +198,7 @@ * @param addr the address of the value to load */ public void translateLoadSigned8(OPT_RegisterOperand addr, OPT_RegisterOperand dest) { - translateLoad(loadS8, 56, addr, dest); + translateLoad(loadS8, DBT_Trace.MEMORY_LOAD8, addr, dest); } /** * Generate the IR code for a byte load where the zero extended @@ -165,7 +207,7 @@ * @param addr the address of the value to load */ public void translateLoadUnsigned8(OPT_RegisterOperand addr, OPT_RegisterOperand dest) { - translateLoad(loadU8, 65, addr, dest); + translateLoad(loadU8, DBT_Trace.MEMORY_ULOAD8, addr, dest); } /** * Generate the IR code for a 16bit load where the sign extended @@ -174,7 +216,7 @@ * @param addr the address of the value to load */ public void translateLoadSigned16(OPT_RegisterOperand addr, OPT_RegisterOperand dest) { - translateLoad(loadS16, 74, addr, dest); + translateLoad(loadS16, DBT_Trace.MEMORY_LOAD16, addr, dest); } /** * Generate the IR code for a 16bit load where the zero extended @@ -183,7 +225,7 @@ * @param addr the address of the value to load */ public void translateLoadUnsigned16(OPT_RegisterOperand addr, OPT_RegisterOperand dest) { - translateLoad(loadU16, 83, addr, dest); + translateLoad(loadU16, DBT_Trace.MEMORY_ULOAD16, addr, dest); } /** * Generate the IR code for a 32bit load @@ -191,7 +233,7 @@ * @param addr the address of the value to load */ public void translateLoad32(OPT_RegisterOperand addr, OPT_RegisterOperand dest) { - translateLoad(load32, 92, addr, dest); + translateLoad(load32, DBT_Trace.MEMORY_LOAD32, addr, dest); } /** * Generate the IR code for a 16bit load where the sign extended @@ -200,7 +242,7 @@ * @param addr the address of the value to load */ protected void translateCallBasedLoadSigned16(OPT_RegisterOperand addr, OPT_RegisterOperand dest) { - translateLoad(loadS16, 74, addr, dest); + translateLoad(loadS16, DBT_Trace.MEMORY_LOAD16, addr, dest); } /** * Generate the IR code for a 16bit load where the zero extended @@ -209,7 +251,7 @@ * @param addr the address of the value to load */ protected void translateCallBasedLoadUnsigned16(OPT_RegisterOperand addr, OPT_RegisterOperand dest) { - translateLoad(loadU16, 83, addr, dest); + translateLoad(loadU16, DBT_Trace.MEMORY_ULOAD16, addr, dest); } /** * Generate the IR code for a 32bit load @@ -217,42 +259,28 @@ * @param addr the address of the value to load */ protected void translateCallBasedLoad32(OPT_RegisterOperand addr, OPT_RegisterOperand dest) { - translateLoad(load32, 92, addr, dest); + translateLoad(load32, DBT_Trace.MEMORY_LOAD32, addr, dest); } /** * Generate the IR code for the specified store - * @param storeType the atom name of the type of store + * @param storeMethod the store method to call * @param bcIndex the bytecode index in * DummyDynamicCodeRunner.invokeCode of this method call - required * for lazy method resolution. * @param src the register that holds the value to store * @param addr the address of the value to store */ - private void translateStore(VM_Atom storeType, int bcIndex, OPT_RegisterOperand addr, OPT_RegisterOperand src) { + private void translateStore(VM_Method storeMethod, int bcIndex, OPT_RegisterOperand addr, OPT_RegisterOperand src) { OPT_Instruction s = Call.create(CALL, null, null, null, null, 3); - VM_MemberReference methRef = VM_MemberReference.findOrCreate(memoryType, - storeType, - storeDescriptor - ); - boolean unresolved = methRef.needsDynamicLink(helper.getMethod()); - VM_Method method = ((VM_MethodReference)methRef).resolveInvokeSpecial(); - OPT_MethodOperand methOp = OPT_MethodOperand.VIRTUAL((VM_MethodReference)methRef, method); + VM_MethodReference storeMethRef = storeMethod.getMemberRef().asMethodReference(); + OPT_MethodOperand methOp = OPT_MethodOperand.VIRTUAL(storeMethRef, storeMethod); OPT_RegisterOperand memoryOp = new OPT_RegisterOperand(memory, memoryType); Call.setParam(s, 0, memoryOp); // Sets 'this' pointer Call.setParam(s, 1, addr); Call.setParam(s, 2, src); Call.setGuard(s, new OPT_TrueGuardOperand()); Call.setMethod(s, methOp); - if (unresolved) { - OPT_RegisterOperand offsetrop = gc.temps.makeTempOffset(); - helper.appendInstructionToCurrentBlock(Unary.create(RESOLVE_MEMBER, offsetrop, - Call.getMethod(s).copy())); - Call.setAddress(s, offsetrop.copyRO()); - } - else { - Call.setAddress(s, new OPT_AddressConstantOperand - (((VM_MethodReference)methRef).peekResolvedMethod().getOffset())); - } + Call.setAddress(s, new OPT_AddressConstantOperand(storeMethod.getOffset())); s.position = gc.inlineSequence; s.bcIndex = bcIndex; helper.appendInstructionToCurrentBlock(s); @@ -263,7 +291,7 @@ * @param addr the address of the value to store */ public void translateStore8(OPT_RegisterOperand addr, OPT_RegisterOperand src) { - translateStore(store8, 30, addr, src); + translateStore(store8, DBT_Trace.MEMORY_STORE8, addr, src); } /** * Generate the IR code for a 16bit store @@ -271,7 +299,7 @@ * @param addr the address of the value to store */ public void translateStore16(OPT_RegisterOperand addr, OPT_RegisterOperand src) { - translateStore(store16, 39, addr, src); + translateStore(store16, DBT_Trace.MEMORY_STORE16, addr, src); } /** * Generate the IR code for a 32bit store @@ -279,7 +307,7 @@ * @param addr the address of the value to store */ public void translateStore32(OPT_RegisterOperand addr, OPT_RegisterOperand src) { - translateStore(store32, 48, addr, src); + translateStore(store32, DBT_Trace.MEMORY_STORE32, addr, src); } /** * Generate the IR code for a byte store @@ -287,7 +315,7 @@ * @param addr the address of the value to store */ public void translateCallBasedStore8(OPT_RegisterOperand addr, OPT_RegisterOperand src) { - translateStore(store8, 30, addr, src); + translateStore(store8, DBT_Trace.MEMORY_STORE8, addr, src); } /** * Generate the IR code for a 16bit store @@ -295,7 +323,7 @@ * @param addr the address of the value to store */ public void translateCallBasedStore16(OPT_RegisterOperand addr, OPT_RegisterOperand src) { - translateStore(store16, 39, addr, src); + translateStore(store16, DBT_Trace.MEMORY_STORE16, addr, src); } /** * Generate the IR code for a 32bit store @@ -303,6 +331,32 @@ * @param addr the address of the value to store */ public void translateCallBasedStore32(OPT_RegisterOperand addr, OPT_RegisterOperand src) { - translateStore(store32, 48, addr, src); + translateStore(store32, DBT_Trace.MEMORY_STORE32, addr, src); } + /** + * Get method reference if linking a call + * @param callAddress the address associated with this call + */ + public VM_MethodReference getMethodRef(int callAddress) { + switch (callAddress) { + case DBT_Trace.MEMORY_STORE8: + return store8.getMemberRef().asMethodReference(); + case DBT_Trace.MEMORY_STORE16: + return store16.getMemberRef().asMethodReference(); + case DBT_Trace.MEMORY_STORE32: + return store32.getMemberRef().asMethodReference(); + case DBT_Trace.MEMORY_LOAD8: + return loadS8.getMemberRef().asMethodReference(); + case DBT_Trace.MEMORY_ULOAD8: + return loadU8.getMemberRef().asMethodReference(); + case DBT_Trace.MEMORY_LOAD16: + return loadS16.getMemberRef().asMethodReference(); + case DBT_Trace.MEMORY_ULOAD16: + return loadU16.getMemberRef().asMethodReference(); + case DBT_Trace.MEMORY_LOAD32: + return load32.getMemberRef().asMethodReference(); + default: + throw new Error("Error linking method at " + callAddress + " for memory model " + this.getClass()); + } + } } Modified: src/org/binarytranslator/generic/memory/IntAddressedByteSwapMemory.java =================================================================== --- src/org/binarytranslator/generic/memory/IntAddressedByteSwapMemory.java 2007-03-21 15:20:26 UTC (rev 9) +++ src/org/binarytranslator/generic/memory/IntAddressedByteSwapMemory.java 2007-03-24 23:14:38 UTC (rev 10) @@ -31,7 +31,7 @@ * Constructor - used when this is the instatiated class */ public IntAddressedByteSwapMemory() { - super("org/binarytranslator/IntAddressedByteSwapMemory"); + super(IntAddressedByteSwapMemory.class); } /** * Perform a 16bit load where the sign extended result fills the Modified: src/org/binarytranslator/generic/memory/IntAddressedMemory.java =================================================================== --- src/org/binarytranslator/generic/memory/IntAddressedMemory.java 2007-03-21 15:20:26 UTC (rev 9) +++ src/org/binarytranslator/generic/memory/IntAddressedMemory.java 2007-03-24 23:14:38 UTC (rev 10) @@ -58,17 +58,17 @@ * Constructor - used when this is the instatiated class */ public IntAddressedMemory() { - super("org/binarytranslator/IntAddressedMemory"); + super(IntAddressedMemory.class); readableMemory = new int[NUM_PAGES][]; writableMemory = new int[NUM_PAGES][]; executableMemory = new int[NUM_PAGES][]; } /** * Constructor - used when deriving a class - * @param className the name of the over-riding class + * @param classType the type of the over-riding class */ - protected IntAddressedMemory(String className) { - super(className); + protected IntAddressedMemory(Class classType) { + super(classType); readableMemory = new int[NUM_PAGES][]; writableMemory = new int[NUM_PAGES][]; executableMemory = new int[NUM_PAGES][]; Modified: src/org/binarytranslator/generic/memory/IntAddressedPreSwappedMemory.java =================================================================== --- src/org/binarytranslator/generic/memory/IntAddressedPreSwappedMemory.java 2007-03-21 15:20:26 UTC (rev 9) +++ src/org/binarytranslator/generic/memory/IntAddressedPreSwappedMemory.java 2007-03-24 23:14:38 UTC (rev 10) @@ -54,13 +54,13 @@ * Constructor */ public IntAddressedPreSwappedMemory() { - super("org/binarytranslator/IntAddressedPreSwappedMemory"); + super(IntAddressedPreSwappedMemory.class); } /** * Constructor */ - protected IntAddressedPreSwappedMemory(String className) { - super(className); + protected IntAddressedPreSwappedMemory(Class classType) { + super(classType); } /** * Read an int from RandomAccessFile ensuring that a byte swap is performed Modified: src/org/binarytranslator/generic/memory/IntAddressedReversedMemory.java =================================================================== --- src/org/binarytranslator/generic/memory/IntAddressedReversedMemory.java 2007-03-21 15:20:26 UTC (rev 9) +++ src/org/binarytranslator/generic/memory/IntAddressedReversedMemory.java 2007-03-24 23:14:38 UTC (rev 10) @@ -33,7 +33,7 @@ * Constructor */ public IntAddressedReversedMemory() { - super("org/binarytranslator/IntAddressedReversedMemory"); + super(IntAddressedReversedMemory.class); } /** * Return the offset part of the address Modified: src/org/binarytranslator/generic/memory/Memory.java =================================================================== --- src/org/binarytranslator/generic/memory/Memory.java 2007-03-21 15:20:26 UTC (rev 9) +++ src/org/binarytranslator/generic/memory/Memory.java 2007-03-24 23:14:38 UTC (rev 10) @@ -9,6 +9,7 @@ package org.binarytranslator.generic.memory; import org.jikesrvm.opt.ir.OPT_RegisterOperand; +import org.jikesrvm.classloader.VM_MethodReference; import org.binarytranslator.vmInterface.TranslationHelper; import java.io.RandomAccessFile; @@ -182,4 +183,11 @@ * @param addr the address of the value to store */ public abstract void translateStore32(OPT_RegisterOperand addr, OPT_RegisterOperand src); + /** + * Get method reference if linking a call + * @param callAddress the address associated with this call + *... [truncated message content] |