Search in sources :

Example 1 with AbstractRegisters

use of org.jikesrvm.architecture.AbstractRegisters in project JikesRVM by JikesRVM.

the class RuntimeEntrypoints method athrow.

// ---------------------------------------------------------------//
// Exception Handling.                        //
// ---------------------------------------------------------------//
/**
 * Deliver a software exception to current java thread.
 * @param exceptionObject exception object to deliver
 * (null --> deliver NullPointerException).
 * does not return
 * (stack is unwound and execution resumes in a catch block)
 *
 * This method is public so that it can be invoked by java.lang.VMClass.
 */
@NoInline
@Entrypoint
@Unpreemptible("Deliver exception possibly from unpreemptible code")
public static void athrow(Throwable exceptionObject) {
    if (traceAthrow) {
        VM.sysWriteln("in athrow.");
        RVMThread.dumpStack();
    }
    RVMThread myThread = RVMThread.getCurrentThread();
    AbstractRegisters exceptionRegisters = myThread.getExceptionRegisters();
    // VM.enableGC() is called when the exception is delivered.
    VM.disableGC();
    Magic.saveThreadState(exceptionRegisters);
    exceptionRegisters.setInUse(true);
    deliverException(exceptionObject, exceptionRegisters);
}
Also used : RVMThread(org.jikesrvm.scheduler.RVMThread) AbstractRegisters(org.jikesrvm.architecture.AbstractRegisters) Unpreemptible(org.vmmagic.pragma.Unpreemptible) Entrypoint(org.vmmagic.pragma.Entrypoint) NoInline(org.vmmagic.pragma.NoInline)

Example 2 with AbstractRegisters

use of org.jikesrvm.architecture.AbstractRegisters in project JikesRVM by JikesRVM.

the class RuntimeEntrypoints method deliverHardwareException.

/**
 * Deliver a hardware exception to current java thread.
 * <p>
 * Does not return.
 * (stack is unwound, starting at trap site, and
 *           execution resumes in a catch block somewhere up the stack)
 *     /or/  execution resumes at instruction following trap
 *     (for TRAP_STACK_OVERFLOW)
 *
 * <p> Note:     Control reaches here by the actions of an
 *           external "C" signal handler
 *           which saves the register state of the trap site into the
 *           "exceptionRegisters" field of the current
 *           Thread object.
 *           The signal handler also inserts a &lt;hardware trap&gt; frame
 *           onto the stack immediately above this frame, for use by
 *           HardwareTrapGCMapIterator during garbage collection.
 *
 * @param trapCode code indicating kind of exception that was trapped
 * (see TRAP_xxx, above)
 * @param trapInfo array subscript (for array bounds trap, only), marker
 * (for stack overflow traps on PPC) or
 */
@Entrypoint
@UnpreemptibleNoWarn
static void deliverHardwareException(int trapCode, Word trapInfo) {
    if (VM.verboseSignalHandling)
        VM.sysWriteln("delivering hardware exception");
    RVMThread myThread = RVMThread.getCurrentThread();
    if (VM.verboseSignalHandling)
        VM.sysWriteln("we have a thread = ", Magic.objectAsAddress(myThread));
    if (VM.verboseSignalHandling)
        VM.sysWriteln("it's in state = ", myThread.getExecStatus());
    AbstractRegisters exceptionRegisters = myThread.getExceptionRegisters();
    if (VM.verboseSignalHandling)
        VM.sysWriteln("we have exception registers = ", Magic.objectAsAddress(exceptionRegisters));
    if ((trapCode == TRAP_STACK_OVERFLOW || trapCode == TRAP_JNI_STACK) && myThread.getStack().length < (StackFrameLayout.getMaxStackSize() >> LOG_BYTES_IN_ADDRESS) && !myThread.hasNativeStackFrame()) {
        // (C trap handler has set register.ip to the instruction following the trap).
        if (trapCode == TRAP_JNI_STACK) {
            RVMThread.resizeCurrentStack(myThread.getStackLength() + StackFrameLayout.getJNIStackGrowthSize(), exceptionRegisters);
        } else {
            RVMThread.resizeCurrentStack(myThread.getStackLength() + StackFrameLayout.getStackGrowthSize(), exceptionRegisters);
        }
        if (VM.VerifyAssertions)
            VM._assert(exceptionRegisters.getInUse());
        exceptionRegisters.setInUse(false);
        Magic.restoreHardwareExceptionState(exceptionRegisters);
        if (VM.VerifyAssertions)
            VM._assert(NOT_REACHED);
    }
    // GC stress testing
    if (canForceGC()) {
        // VM.sysWriteln("FORCING GC: in deliverHardwareException");
        System.gc();
    }
    // Hardware traps in uninterruptible code should be considered hard failures.
    if (!VM.sysFailInProgress()) {
        Address fp = exceptionRegisters.getInnermostFramePointer();
        int compiledMethodId = Magic.getCompiledMethodID(fp);
        if (compiledMethodId != StackFrameLayout.getInvisibleMethodID()) {
            CompiledMethod compiledMethod = CompiledMethods.getCompiledMethod(compiledMethodId);
            Address ip = exceptionRegisters.getInnermostInstructionAddress();
            Offset instructionOffset = compiledMethod.getInstructionOffset(ip);
            if (compiledMethod.isWithinUninterruptibleCode(instructionOffset)) {
                VM.sysWriteln();
                switch(trapCode) {
                    case TRAP_NULL_POINTER:
                        VM.sysWriteln("Fatal error: NullPointerException within uninterruptible region.");
                        break;
                    case TRAP_ARRAY_BOUNDS:
                        VM.sysWriteln("Fatal error: ArrayIndexOutOfBoundsException within uninterruptible region (index was ", trapInfo.toInt(), ").");
                        break;
                    case TRAP_DIVIDE_BY_ZERO:
                        VM.sysWriteln("Fatal error: DivideByZero within uninterruptible region.");
                        break;
                    case TRAP_STACK_OVERFLOW:
                    case TRAP_JNI_STACK:
                        VM.sysWriteln("Fatal error: StackOverflowError within uninterruptible region.");
                        break;
                    case TRAP_CHECKCAST:
                        VM.sysWriteln("Fatal error: ClassCastException within uninterruptible region.");
                        break;
                    case TRAP_MUST_IMPLEMENT:
                        VM.sysWriteln("Fatal error: IncompatibleClassChangeError within uninterruptible region.");
                        break;
                    case TRAP_STORE_CHECK:
                        VM.sysWriteln("Fatal error: ArrayStoreException within uninterruptible region.");
                        break;
                    case TRAP_UNREACHABLE_BYTECODE:
                        VM.sysWriteln("Fatal error: Reached a bytecode that was determined to be unreachable within uninterruptible region.");
                        break;
                    default:
                        VM.sysWriteln("Fatal error: Unknown hardware trap within uninterruptible region.");
                        break;
                }
                VM.sysWriteln("trapCode = ", trapCode);
                VM.sysWriteln("trapInfo = ", trapInfo.toAddress());
                VM.sysFail("Exiting virtual machine due to uninterruptibility violation.");
            }
        }
    }
    Throwable exceptionObject;
    switch(trapCode) {
        case TRAP_NULL_POINTER:
            exceptionObject = new java.lang.NullPointerException();
            break;
        case TRAP_ARRAY_BOUNDS:
            exceptionObject = new java.lang.ArrayIndexOutOfBoundsException(trapInfo.toInt());
            break;
        case TRAP_DIVIDE_BY_ZERO:
            exceptionObject = new java.lang.ArithmeticException();
            break;
        case TRAP_STACK_OVERFLOW:
        case TRAP_JNI_STACK:
            exceptionObject = new java.lang.StackOverflowError();
            break;
        case TRAP_CHECKCAST:
            exceptionObject = new java.lang.ClassCastException();
            break;
        case TRAP_MUST_IMPLEMENT:
            exceptionObject = new java.lang.IncompatibleClassChangeError();
            break;
        case TRAP_STORE_CHECK:
            exceptionObject = new java.lang.ArrayStoreException();
            break;
        case TRAP_UNREACHABLE_BYTECODE:
            exceptionObject = new java.lang.InternalError(UNREACHABLE_BC_MESSAGE);
            break;
        default:
            exceptionObject = new java.lang.UnknownError();
            RVMThread.traceback("UNKNOWN ERROR");
            break;
    }
    // VM.enableGC() is called when the exception is delivered.
    VM.disableGC();
    deliverException(exceptionObject, exceptionRegisters);
}
Also used : Address(org.vmmagic.unboxed.Address) RVMThread(org.jikesrvm.scheduler.RVMThread) AbstractRegisters(org.jikesrvm.architecture.AbstractRegisters) Entrypoint(org.vmmagic.pragma.Entrypoint) CompiledMethod(org.jikesrvm.compilers.common.CompiledMethod) Offset(org.vmmagic.unboxed.Offset) Entrypoint(org.vmmagic.pragma.Entrypoint) UnpreemptibleNoWarn(org.vmmagic.pragma.UnpreemptibleNoWarn)

Example 3 with AbstractRegisters

use of org.jikesrvm.architecture.AbstractRegisters in project JikesRVM by JikesRVM.

the class StackTrace method countFramesUninterruptible.

/**
 * Walk the stack counting the number of stack frames encountered.
 * The stack being walked is our stack, so code is Uninterruptible to stop the
 * stack moving.
 *
 * @param stackTraceThread the thread whose stack is walked
 * @return number of stack frames encountered
 */
@Uninterruptible
@NoInline
private int countFramesUninterruptible(RVMThread stackTraceThread) {
    int stackFrameCount = 0;
    Address fp;
    /* Stack trace for the thread */
    if (stackTraceThread == RVMThread.getCurrentThread()) {
        fp = Magic.getFramePointer();
    } else {
        AbstractRegisters contextRegisters = stackTraceThread.getContextRegisters();
        fp = contextRegisters.getInnermostFramePointer();
    }
    fp = Magic.getCallerFramePointer(fp);
    while (Magic.getCallerFramePointer(fp).NE(StackFrameLayout.getStackFrameSentinelFP())) {
        int compiledMethodId = Magic.getCompiledMethodID(fp);
        if (compiledMethodId != StackFrameLayout.getInvisibleMethodID()) {
            CompiledMethod compiledMethod = CompiledMethods.getCompiledMethod(compiledMethodId);
            if ((compiledMethod.getCompilerType() != CompiledMethod.TRAP) && compiledMethod.hasBridgeFromNativeAnnotation()) {
                // skip native frames, stopping at last native frame preceeding the
                // Java To C transition frame
                fp = RuntimeEntrypoints.unwindNativeStackFrame(fp);
            }
        }
        stackFrameCount++;
        fp = Magic.getCallerFramePointer(fp);
    }
    // VM.sysWriteln("stack frame count = ",stackFrameCount);
    return stackFrameCount;
}
Also used : Address(org.vmmagic.unboxed.Address) AbstractRegisters(org.jikesrvm.architecture.AbstractRegisters) BaselineCompiledMethod(org.jikesrvm.compilers.baseline.BaselineCompiledMethod) CompiledMethod(org.jikesrvm.compilers.common.CompiledMethod) OptCompiledMethod(org.jikesrvm.compilers.opt.runtimesupport.OptCompiledMethod) Uninterruptible(org.vmmagic.pragma.Uninterruptible) NoInline(org.vmmagic.pragma.NoInline)

Example 4 with AbstractRegisters

use of org.jikesrvm.architecture.AbstractRegisters in project JikesRVM by JikesRVM.

the class ScanThread method scanThread.

/**
 *********************************************************************
 *
 * Thread scanning
 */
/**
 * Scan a thread, placing the addresses of pointers into supplied buffers.
 *
 * @param thread The thread to be scanned
 * @param trace The trace instance to use for reporting references.
 * @param processCodeLocations Should code locations be processed?
 * @param newRootsSufficient Is a partial stack scan sufficient, or must we do a full scan?
 */
public static void scanThread(RVMThread thread, TraceLocal trace, boolean processCodeLocations, boolean newRootsSufficient) {
    if (DEFAULT_VERBOSITY >= 1) {
        VM.sysWriteln("scanning ", thread.getThreadSlot());
    }
    /* get the gprs associated with this thread */
    AbstractRegisters regs = thread.getContextRegisters();
    Address gprs = Magic.objectAsAddress(regs.getGPRs());
    Address ip = regs.getInnermostInstructionAddress();
    Address fp = regs.getInnermostFramePointer();
    regs.clear();
    regs.setInnermost(ip, fp);
    scanThread(thread, trace, processCodeLocations, gprs, Address.zero(), newRootsSufficient);
}
Also used : Address(org.vmmagic.unboxed.Address) AbstractRegisters(org.jikesrvm.architecture.AbstractRegisters)

Example 5 with AbstractRegisters

use of org.jikesrvm.architecture.AbstractRegisters in project JikesRVM by JikesRVM.

the class ScanThread method getHWExceptionRegisters.

/**
 * When an exception occurs, registers are saved temporarily.  If
 * the stack being scanned is in this state, we need to scan those
 * registers for code pointers.  If the codeLocations deque is null,
 * then scanning for code pointers is not required, so we don't need
 * to do anything. (SB: Why only code pointers?).
 * <p>
 * Dave G:  The contents of the GPRs of the exceptionRegisters
 * are handled during normal stack scanning
 * (@see org.jikesrvm.runtime.compilers.common.HardwareTrapCompiledMethod.
 * It looks to me like the main goal of this method is to ensure that the
 * method in which the trap happened isn't treated as dead code and collected
 * (if it's been marked as obsolete, we are setting its activeOnStackFlag below).
 */
private void getHWExceptionRegisters() {
    AbstractRegisters exReg = thread.getExceptionRegisters();
    if (processCodeLocations && exReg.getInUse()) {
        Address ip = exReg.getIP();
        CompiledMethod compiledMethod = CompiledMethods.findMethodForInstruction(ip);
        if (VM.VerifyAssertions) {
            VM._assert(compiledMethod != null);
            VM._assert(compiledMethod.containsReturnAddress(ip));
        }
        compiledMethod.setActiveOnStack();
        ObjectReference code = ObjectReference.fromObject(compiledMethod.getEntryCodeArray());
        Address ipLoc = exReg.getIPLocation();
        if (VM.VerifyAssertions)
            VM._assert(ip.EQ(ipLoc.loadAddress()));
        processCodeLocation(code, ipLoc);
    }
}
Also used : Address(org.vmmagic.unboxed.Address) ObjectReference(org.vmmagic.unboxed.ObjectReference) AbstractRegisters(org.jikesrvm.architecture.AbstractRegisters) CompiledMethod(org.jikesrvm.compilers.common.CompiledMethod)

Aggregations

AbstractRegisters (org.jikesrvm.architecture.AbstractRegisters)7 Address (org.vmmagic.unboxed.Address)6 CompiledMethod (org.jikesrvm.compilers.common.CompiledMethod)5 OptCompiledMethod (org.jikesrvm.compilers.opt.runtimesupport.OptCompiledMethod)3 NoInline (org.vmmagic.pragma.NoInline)3 BaselineCompiledMethod (org.jikesrvm.compilers.baseline.BaselineCompiledMethod)2 RVMThread (org.jikesrvm.scheduler.RVMThread)2 Entrypoint (org.vmmagic.pragma.Entrypoint)2 Uninterruptible (org.vmmagic.pragma.Uninterruptible)2 Offset (org.vmmagic.unboxed.Offset)2 NormalMethod (org.jikesrvm.classloader.NormalMethod)1 ArchBaselineCompiledMethod (org.jikesrvm.compilers.baseline.ppc.ArchBaselineCompiledMethod)1 BytecodeTraverser (org.jikesrvm.osr.BytecodeTraverser)1 ExecutionState (org.jikesrvm.osr.ExecutionState)1 Unpreemptible (org.vmmagic.pragma.Unpreemptible)1 UnpreemptibleNoWarn (org.vmmagic.pragma.UnpreemptibleNoWarn)1 ObjectReference (org.vmmagic.unboxed.ObjectReference)1 Word (org.vmmagic.unboxed.Word)1 WordArray (org.vmmagic.unboxed.WordArray)1