Search in sources :

Example 56 with Offset

use of org.vmmagic.unboxed.Offset in project JikesRVM by JikesRVM.

the class OptGenericGCMapIterator method setupIterator.

/**
 * Initialize the iterator for another stack frame scan
 * @param cm                The compiled method we are interested in
 * @param instructionOffset The place in the method where we currently are
 * @param framePtr          The current frame pointer
 */
@Override
public final void setupIterator(CompiledMethod cm, Offset instructionOffset, Address framePtr) {
    if (DEBUG) {
        VM.sysWriteln();
        VM.sysWrite("\t   ==========================");
        VM.sysWriteln();
        VM.sysWrite("Reference map request made");
        VM.sysWrite(" for machine code offset: ");
        VM.sysWrite(instructionOffset);
        VM.sysWriteln();
        VM.sysWrite("\tframePtr: ");
        VM.sysWrite(framePtr);
        VM.sysWriteln();
    }
    reset();
    // retrieve and save the corresponding OptMachineCodeMap for
    // this method and instructionOffset
    compiledMethod = (OptCompiledMethod) cm;
    map = compiledMethod.getMCMap();
    mapIndex = map.findGCMapIndex(instructionOffset);
    if (mapIndex == OptGCMap.ERROR) {
        if (instructionOffset.sLT(Offset.zero())) {
            VM.sysWriteln("OptGenericGCMapIterator.setupIterator called with negative instructionOffset", instructionOffset);
        } else {
            Offset possibleLen = Offset.fromIntZeroExtend(cm.numberOfInstructions() << ArchConstants.getLogInstructionWidth());
            if (possibleLen.sLT(instructionOffset)) {
                VM.sysWriteln("OptGenericGCMapIterator.setupIterator called with too big of an instructionOffset");
                VM.sysWriteln("offset is", instructionOffset);
                VM.sysWriteln(" bytes of machine code for method ", possibleLen);
            } else {
                VM.sysWriteln("OptGenericGCMapIterator.setupIterator called with apparently valid offset, but no GC map found!");
                VM.sysWrite("Method: ");
                VM.sysWrite(compiledMethod.getMethod());
                VM.sysWrite(", Machine Code (MC) Offset: ");
                VM.sysWriteln(instructionOffset);
                VM.sysFail("OptGenericMapIterator: findGCMapIndex failed\n");
            }
        }
        VM.sysWrite("Supposed method: ");
        VM.sysWrite(compiledMethod.getMethod());
        VM.sysWriteln();
        VM.sysWriteln("Base of its code array", Magic.objectAsAddress(cm.getEntryCodeArray()));
        Address ra = cm.getInstructionAddress(instructionOffset);
        VM.sysWriteln("Calculated actual return address is ", ra);
        CompiledMethod realCM = CompiledMethods.findMethodForInstruction(ra);
        if (realCM == null) {
            VM.sysWriteln("Unable to find compiled method corresponding to this return address");
        } else {
            VM.sysWrite("Found compiled method ");
            VM.sysWrite(realCM.getMethod());
            VM.sysWriteln(" whose code contains this return address");
        }
        VM.sysFail("OptGenericMapIterator: setupIterator failed\n");
    }
    // save the frame pointer
    this.framePtr = framePtr;
    if (DEBUG) {
        VM.sysWrite("\tMethod: ");
        VM.sysWrite(compiledMethod.getMethod());
        VM.sysWriteln();
        if (mapIndex == OptGCMap.NO_MAP_ENTRY) {
            VM.sysWriteln("... empty map found");
        } else {
            VM.sysWriteln("... found a map");
        }
        if (lookForMissedReferencesInSpills) {
            VM.sysWrite("FramePtr: ");
            VM.sysWrite(framePtr);
            VM.sysWrite("\tFirst Spill: ");
            VM.sysWrite(getFirstSpillLoc());
            VM.sysWrite("\tLast Spill: ");
            VM.sysWrite(getLastSpillLoc());
            VM.sysWriteln();
        }
    }
}
Also used : Address(org.vmmagic.unboxed.Address) CompiledMethod(org.jikesrvm.compilers.common.CompiledMethod) Offset(org.vmmagic.unboxed.Offset)

Example 57 with Offset

use of org.vmmagic.unboxed.Offset in project JikesRVM by JikesRVM.

the class OptSaveVolatile method resolve.

/**
 * Wrapper to save/restore volatile registers when a class needs to be
 * dynamically loaded/resolved/etc.
 */
@Entrypoint
@Interruptible
public static void resolve() throws NoClassDefFoundError {
    VM.disableGC();
    // (1) Get the compiled method & compilerInfo for the (opt)
    // compiled method that called resolve
    Address fp = Magic.getCallerFramePointer(Magic.getFramePointer());
    int cmid = Magic.getCompiledMethodID(fp);
    OptCompiledMethod cm = (OptCompiledMethod) CompiledMethods.getCompiledMethod(cmid);
    // (2) Get the return address
    Address ip = Magic.getReturnAddressUnchecked(Magic.getFramePointer());
    Offset offset = cm.getInstructionOffset(ip);
    VM.enableGC();
    // (3) Call the routine in OptLinker that does all the real work.
    OptLinker.resolveDynamicLink(cm, offset);
}
Also used : Address(org.vmmagic.unboxed.Address) Entrypoint(org.vmmagic.pragma.Entrypoint) Offset(org.vmmagic.unboxed.Offset) Interruptible(org.vmmagic.pragma.Interruptible) Entrypoint(org.vmmagic.pragma.Entrypoint)

Example 58 with Offset

use of org.vmmagic.unboxed.Offset in project JikesRVM by JikesRVM.

the class OutOfLineMachineCode method generateSaveThreadStateInstructions.

/**
 * Machine code to implement "Magic.saveThreadState()".
 * <pre>
 *  Registers taken at runtime:
 *    T0 == address of Registers object
 *
 *  Registers returned at runtime:
 *    none
 *
 *  Side effects at runtime:
 *    S0, T1 destroyed
 *    Thread state stored into Registers object
 * </pre>
 *
 * @return instructions for saving the thread state
 */
private static CodeArray generateSaveThreadStateInstructions() {
    if (VM.VerifyAssertions) {
        // assuming no NV FPRs (otherwise would have to save them here)
        VM._assert(NUM_NONVOLATILE_FPRS == 0);
    }
    Assembler asm = new Assembler(0);
    Offset ipOffset = ArchEntrypoints.registersIPField.getOffset();
    Offset fpOffset = ArchEntrypoints.registersFPField.getOffset();
    Offset gprsOffset = ArchEntrypoints.registersGPRsField.getOffset();
    if (VM.BuildFor32Addr) {
        asm.emitMOV_Reg_RegDisp(S0, TR, ArchEntrypoints.framePointerField.getOffset());
        // registers.fp := pr.framePointer
        asm.emitMOV_RegDisp_Reg(T0, fpOffset, S0);
    } else {
        asm.emitMOV_Reg_RegDisp_Quad(S0, TR, ArchEntrypoints.framePointerField.getOffset());
        // registers.fp := pr.framePointer
        asm.emitMOV_RegDisp_Reg_Quad(T0, fpOffset, S0);
    }
    // T1 := return address (target of final jmp)
    asm.emitPOP_Reg(T1);
    if (VM.BuildFor32Addr) {
        // registers.ip := return address
        asm.emitMOV_RegDisp_Reg(T0, ipOffset, T1);
    } else {
        // registers.ip := return address
        asm.emitMOV_RegDisp_Reg_Quad(T0, ipOffset, T1);
    }
    // throw away space for registers parameter (in T0)
    asm.emitPOP_Reg(S0);
    if (VM.BuildFor32Addr) {
        // S0 := registers.gprs[]
        asm.emitMOV_Reg_RegDisp(S0, T0, gprsOffset);
        // registers.gprs[#SP] := SP
        asm.emitMOV_RegDisp_Reg(S0, Offset.fromIntZeroExtend(SP.value() << LG_WORDSIZE), SP);
        for (int i = 0; i < NUM_NONVOLATILE_GPRS; i++) {
            asm.emitMOV_RegDisp_Reg(S0, Offset.fromIntZeroExtend(NONVOLATILE_GPRS[i].value() << LG_WORDSIZE), // registers.gprs[i] := i'th register
            NONVOLATILE_GPRS[i]);
        }
    } else {
        // S0 := registers.gprs[]
        asm.emitMOV_Reg_RegDisp_Quad(S0, T0, gprsOffset);
        // registers.gprs[#SP] := SP
        asm.emitMOV_RegDisp_Reg_Quad(S0, Offset.fromIntZeroExtend(SP.value() << LG_WORDSIZE), SP);
        for (int i = 0; i < NUM_NONVOLATILE_GPRS; i++) {
            asm.emitMOV_RegDisp_Reg_Quad(S0, Offset.fromIntZeroExtend(NONVOLATILE_GPRS[i].value() << LG_WORDSIZE), // registers.gprs[i] := i'th register
            NONVOLATILE_GPRS[i]);
        }
    }
    // return to return address
    asm.emitJMP_Reg(T1);
    return asm.getMachineCodes();
}
Also used : Assembler(org.jikesrvm.compilers.common.assembler.ia32.Assembler) Entrypoint(org.vmmagic.pragma.Entrypoint) Offset(org.vmmagic.unboxed.Offset)

Example 59 with Offset

use of org.vmmagic.unboxed.Offset in project JikesRVM by JikesRVM.

the class OutOfLineMachineCode method generateThreadSwitchInstructions.

/**
 * Machine code to implement "Magic.threadSwitch()".
 * <pre>
 * NOTE: Currently not functional for PNT: left as a guide for possible reimplementation.
 *
 *  Parameters taken at runtime:
 *    T0 == address of Thread object for the current thread
 *    T1 == address of Registers object for the new thread
 *
 *  Registers returned at runtime:
 *    none
 *
 *  Side effects at runtime:
 *    sets current Thread's beingDispatched field to false
 *    saves current Thread's nonvolatile hardware state in its Registers object
 *    restores new thread's Registers nonvolatile hardware state.
 *    execution resumes at address specificed by restored thread's Registers ip field
 * </pre>
 *
 * @return instructions for doing a thread switch
 */
private static CodeArray generateThreadSwitchInstructions() {
    if (VM.VerifyAssertions) {
        // assuming no NV FPRs (otherwise would have to save them here)
        VM._assert(NUM_NONVOLATILE_FPRS == 0);
    }
    Assembler asm = new Assembler(0);
    Offset ipOffset = ArchEntrypoints.registersIPField.getOffset();
    Offset fpOffset = ArchEntrypoints.registersFPField.getOffset();
    Offset gprsOffset = ArchEntrypoints.registersGPRsField.getOffset();
    Offset regsOffset = Entrypoints.threadContextRegistersField.getOffset();
    // (1) Save hardware state of thread we are switching off of.
    if (VM.BuildFor32Addr) {
        // S0 = T0.contextRegisters
        asm.emitMOV_Reg_RegDisp(S0, T0, regsOffset);
    } else {
        // S0 = T0.contextRegisters
        asm.emitMOV_Reg_RegDisp_Quad(S0, T0, regsOffset);
    }
    // T0.contextRegisters.ip = returnAddress
    asm.emitPOP_RegDisp(S0, ipOffset);
    // push TR.framePointer
    asm.emitPUSH_RegDisp(TR, ArchEntrypoints.framePointerField.getOffset());
    // T0.contextRegisters.fp = pushed framepointer
    asm.emitPOP_RegDisp(S0, fpOffset);
    if (VM.BuildFor32Addr) {
        // discard 2 words of parameters (T0, T1)
        asm.emitADD_Reg_Imm(SP, 2 * WORDSIZE);
        // S0 = T0.contextRegisters.gprs;
        asm.emitMOV_Reg_RegDisp(S0, S0, gprsOffset);
        // T0.contextRegisters.gprs[#SP] := SP
        asm.emitMOV_RegDisp_Reg(S0, Offset.fromIntZeroExtend(SP.value() << LG_WORDSIZE), SP);
        for (int i = 0; i < NUM_NONVOLATILE_GPRS; i++) {
            // T0.contextRegisters.gprs[i] := i'th register
            asm.emitMOV_RegDisp_Reg(S0, Offset.fromIntZeroExtend(NONVOLATILE_GPRS[i].value() << LG_WORDSIZE), NONVOLATILE_GPRS[i]);
        }
    } else {
        // discard 2 words of parameters (T0, T1)
        asm.emitADD_Reg_Imm_Quad(SP, 2 * WORDSIZE);
        // S0 = T0.contextRegisters.gprs;
        asm.emitMOV_Reg_RegDisp_Quad(S0, S0, gprsOffset);
        // T0.contextRegisters.gprs[#SP] := SP
        asm.emitMOV_RegDisp_Reg_Quad(S0, Offset.fromIntZeroExtend(SP.value() << LG_WORDSIZE), SP);
        for (int i = 0; i < NUM_NONVOLATILE_GPRS; i++) {
            // T0.contextRegisters.gprs[i] := i'th register
            asm.emitMOV_RegDisp_Reg_Quad(S0, Offset.fromIntZeroExtend(NONVOLATILE_GPRS[i].value() << LG_WORDSIZE), NONVOLATILE_GPRS[i]);
        }
    }
    // (3) Restore hardware state of thread we are switching to.
    if (VM.BuildFor32Addr) {
        // S0 := restoreRegs.fp
        asm.emitMOV_Reg_RegDisp(S0, T1, fpOffset);
    } else {
        // S0 := restoreRegs.fp
        asm.emitMOV_Reg_RegDisp_Quad(S0, T1, fpOffset);
    }
    // TR.framePointer = restoreRegs.fp
    if (VM.BuildFor32Addr) {
        asm.emitMOV_RegDisp_Reg(THREAD_REGISTER, ArchEntrypoints.framePointerField.getOffset(), S0);
        // S0 := restoreRegs.gprs[]
        asm.emitMOV_Reg_RegDisp(S0, T1, gprsOffset);
        // SP := restoreRegs.gprs[#SP]
        asm.emitMOV_Reg_RegDisp(SP, S0, Offset.fromIntZeroExtend(SP.value() << LG_WORDSIZE));
        for (int i = 0; i < NUM_NONVOLATILE_GPRS; i++) {
            // i'th register := restoreRegs.gprs[i]
            asm.emitMOV_Reg_RegDisp(NONVOLATILE_GPRS[i], S0, Offset.fromIntZeroExtend(NONVOLATILE_GPRS[i].value() << LG_WORDSIZE));
        }
    } else {
        asm.emitMOV_RegDisp_Reg_Quad(THREAD_REGISTER, ArchEntrypoints.framePointerField.getOffset(), S0);
        // S0 := restoreRegs.gprs[]
        asm.emitMOV_Reg_RegDisp_Quad(S0, T1, gprsOffset);
        // SP := restoreRegs.gprs[#SP]
        asm.emitMOV_Reg_RegDisp_Quad(SP, S0, Offset.fromIntZeroExtend(SP.value() << LG_WORDSIZE));
        for (int i = 0; i < NUM_NONVOLATILE_GPRS; i++) {
            // i'th register := restoreRegs.gprs[i]
            asm.emitMOV_Reg_RegDisp_Quad(NONVOLATILE_GPRS[i], S0, Offset.fromIntZeroExtend(NONVOLATILE_GPRS[i].value() << LG_WORDSIZE));
        }
    }
    // return to (save) return address
    asm.emitJMP_RegDisp(T1, ipOffset);
    return asm.getMachineCodes();
}
Also used : Assembler(org.jikesrvm.compilers.common.assembler.ia32.Assembler) Entrypoint(org.vmmagic.pragma.Entrypoint) Offset(org.vmmagic.unboxed.Offset)

Example 60 with Offset

use of org.vmmagic.unboxed.Offset in project JikesRVM by JikesRVM.

the class OptExceptionDeliverer method deliverException.

/**
 * Pass control to a catch block.
 */
@Override
@Unpreemptible("Deliver exception possibly from unpreemptible code")
public void deliverException(CompiledMethod cm, Address catchBlockInstructionAddress, Throwable exceptionObject, AbstractRegisters registers) {
    // store exception object for later retrieval by catch block
    OptCompiledMethod compiledMethod = (OptCompiledMethod) cm;
    Offset offset = Offset.fromIntSignExtend(compiledMethod.getUnsignedExceptionOffset());
    if (!offset.isZero()) {
        // only put the exception object in the stackframe if the catch block is expecting it.
        // (if the method hasn't allocated a stack slot for caught exceptions, then we can safely
        // drop the exceptionObject on the floor).
        Address fp = registers.getInnermostFramePointer();
        Magic.setObjectAtOffset(Magic.addressAsObject(fp), offset, exceptionObject);
    }
    // set address at which to resume executing frame
    registers.setIP(catchBlockInstructionAddress);
    // disabled right before Runtime.deliverException was called
    VM.enableGC();
    if (VM.VerifyAssertions)
        VM._assert(registers.getInUse());
    registers.setInUse(false);
    // "branches" to catchBlockInstructionAddress
    Magic.restoreHardwareExceptionState(registers);
    if (VM.VerifyAssertions)
        VM._assert(NOT_REACHED);
}
Also used : OptCompiledMethod(org.jikesrvm.compilers.opt.runtimesupport.OptCompiledMethod) Address(org.vmmagic.unboxed.Address) Offset(org.vmmagic.unboxed.Offset) Unpreemptible(org.vmmagic.pragma.Unpreemptible)

Aggregations

Offset (org.vmmagic.unboxed.Offset)215 Address (org.vmmagic.unboxed.Address)48 Inline (org.vmmagic.pragma.Inline)38 Entrypoint (org.vmmagic.pragma.Entrypoint)32 ObjectReference (org.vmmagic.unboxed.ObjectReference)21 CompiledMethod (org.jikesrvm.compilers.common.CompiledMethod)20 TypeReference (org.jikesrvm.classloader.TypeReference)17 RVMField (org.jikesrvm.classloader.RVMField)14 ForwardReference (org.jikesrvm.compilers.common.assembler.ForwardReference)13 OptCompiledMethod (org.jikesrvm.compilers.opt.runtimesupport.OptCompiledMethod)13 NoInline (org.vmmagic.pragma.NoInline)13 RVMMethod (org.jikesrvm.classloader.RVMMethod)11 RegisterOperand (org.jikesrvm.compilers.opt.ir.operand.RegisterOperand)10 Word (org.vmmagic.unboxed.Word)10 Instruction (org.jikesrvm.compilers.opt.ir.Instruction)9 IntConstantOperand (org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand)9 RVMType (org.jikesrvm.classloader.RVMType)8 Register (org.jikesrvm.compilers.opt.ir.Register)8 RVMClass (org.jikesrvm.classloader.RVMClass)7 Operand (org.jikesrvm.compilers.opt.ir.operand.Operand)7