Search in sources :

Example 31 with Entrypoint

use of org.vmmagic.pragma.Entrypoint 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 32 with Entrypoint

use of org.vmmagic.pragma.Entrypoint 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 33 with Entrypoint

use of org.vmmagic.pragma.Entrypoint in project JikesRVM by JikesRVM.

the class RVMThread method yieldpointFromBackedge.

/**
 * Yieldpoint taken on backedge.
 */
@BaselineSaveLSRegisters
// Save all non-volatile registers in prologue
@NoOptCompile
@NoInline
// TODO fix this -- related to SaveVolatile
@Entrypoint
@Unpreemptible("Becoming another thread interrupts the current thread, avoid preemption in the process")
public static void yieldpointFromBackedge() {
    Address fp = Magic.getFramePointer();
    yieldpoint(BACKEDGE, fp);
}
Also used : Address(org.vmmagic.unboxed.Address) Unpreemptible(org.vmmagic.pragma.Unpreemptible) Entrypoint(org.vmmagic.pragma.Entrypoint) BaselineSaveLSRegisters(org.vmmagic.pragma.BaselineSaveLSRegisters) NoInline(org.vmmagic.pragma.NoInline) NoOptCompile(org.vmmagic.pragma.NoOptCompile)

Example 34 with Entrypoint

use of org.vmmagic.pragma.Entrypoint in project JikesRVM by JikesRVM.

the class ThinLock method inlineLock.

@Inline
@NoNullCheck
@Unpreemptible
@Entrypoint
public static void inlineLock(Object o, Offset lockOffset) {
    // FIXME: bad for PPC?
    Word old = Magic.prepareWord(o, lockOffset);
    Word id = old.and(TL_THREAD_ID_MASK.or(TL_STAT_MASK));
    Word tid = Word.fromIntSignExtend(RVMThread.getCurrentThread().getLockingId());
    if (id.EQ(tid)) {
        Word changed = old.plus(TL_LOCK_COUNT_UNIT);
        if (!changed.and(TL_LOCK_COUNT_MASK).isZero()) {
            setDedicatedU16(o, lockOffset, changed);
            Magic.combinedLoadBarrier();
            return;
        }
    } else if (id.EQ(TL_STAT_THIN)) {
        // lock is thin and not held by anyone
        if (Magic.attemptWord(o, lockOffset, old, old.or(tid))) {
            if (!VM.MagicAttemptImpliesStoreLoadBarrier)
                Magic.fence();
            return;
        }
    }
    lock(o, lockOffset);
}
Also used : Word(org.vmmagic.unboxed.Word) Unpreemptible(org.vmmagic.pragma.Unpreemptible) Entrypoint(org.vmmagic.pragma.Entrypoint) NoNullCheck(org.vmmagic.pragma.NoNullCheck) Inline(org.vmmagic.pragma.Inline) NoInline(org.vmmagic.pragma.NoInline)

Example 35 with Entrypoint

use of org.vmmagic.pragma.Entrypoint in project JikesRVM by JikesRVM.

the class MultianewarrayHelper method newArrayArray.

/**
 * Allocate something like {@code new Foo[cnt0][cnt1]...[cntN-1]},
 *                      or {@code new int[cnt0][cnt1]...[cntN-1]}.
 * @param methodId      id of caller
 * @param numDimensions number of array dimensions
 * @param typeId        {@link TypeReference} id of type of array
 * @param argOffset     position of word *above* `cnt0' argument within caller's frame
 *                      This is used to access the number of elements to
 *                      be allocated for each dimension.
 * See also: bytecode 0xc5 ("multianewarray") in Compiler
 * @return the new array
 */
@Entrypoint
static Object newArrayArray(int methodId, int numDimensions, int typeId, int argOffset) throws NoClassDefFoundError, NegativeArraySizeException, OutOfMemoryError {
    if (numDimensions == 2) {
        int dim0, dim1;
        // fetch number of elements to be allocated for each array dimension
        VM.disableGC();
        Address argp = Magic.getFramePointer().loadAddress().plus(argOffset);
        int offset = (BYTES_IN_STACKSLOT * 0) + BYTES_IN_INT;
        dim0 = argp.minus(offset).loadInt();
        offset = (BYTES_IN_STACKSLOT * 1) + BYTES_IN_INT;
        dim1 = argp.minus(offset).loadInt();
        VM.enableGC();
        // validate arguments
        if ((dim0 < 0) || (dim1 < 0))
            throw new NegativeArraySizeException();
        // create array
        TypeReference tRef = TypeReference.getTypeRef(typeId);
        RVMArray array = tRef.resolve().asArray();
        return RuntimeEntrypoints.buildTwoDimensionalArray(methodId, dim0, dim1, array);
    } else {
        // fetch number of elements to be allocated for each array dimension
        int[] numElements = new int[numDimensions];
        VM.disableGC();
        Address argp = Magic.getFramePointer().loadAddress().plus(argOffset);
        for (int i = 0; i < numDimensions; ++i) {
            int offset = (BYTES_IN_STACKSLOT * i) + BYTES_IN_INT;
            numElements[i] = argp.minus(offset).loadInt();
        }
        VM.enableGC();
        // validate arguments
        for (int elements : numElements) {
            if (elements < 0)
                throw new NegativeArraySizeException();
        }
        // create array
        TypeReference tRef = TypeReference.getTypeRef(typeId);
        RVMArray array = tRef.resolve().asArray();
        return RuntimeEntrypoints.buildMultiDimensionalArray(methodId, numElements, array);
    }
}
Also used : Address(org.vmmagic.unboxed.Address) RVMArray(org.jikesrvm.classloader.RVMArray) TypeReference(org.jikesrvm.classloader.TypeReference) Entrypoint(org.vmmagic.pragma.Entrypoint) Entrypoint(org.vmmagic.pragma.Entrypoint)

Aggregations

Entrypoint (org.vmmagic.pragma.Entrypoint)69 Inline (org.vmmagic.pragma.Inline)35 ObjectReference (org.vmmagic.unboxed.ObjectReference)33 Offset (org.vmmagic.unboxed.Offset)22 Address (org.vmmagic.unboxed.Address)12 TypeReference (org.jikesrvm.classloader.TypeReference)7 NoInline (org.vmmagic.pragma.NoInline)7 RVMType (org.jikesrvm.classloader.RVMType)6 Unpreemptible (org.vmmagic.pragma.Unpreemptible)6 RVMMethod (org.jikesrvm.classloader.RVMMethod)5 RVMArray (org.jikesrvm.classloader.RVMArray)3 RVMClass (org.jikesrvm.classloader.RVMClass)3 RVMThread (org.jikesrvm.scheduler.RVMThread)3 BaselineSaveLSRegisters (org.vmmagic.pragma.BaselineSaveLSRegisters)3 NoOptCompile (org.vmmagic.pragma.NoOptCompile)3 AbstractRegisters (org.jikesrvm.architecture.AbstractRegisters)2 CompiledMethod (org.jikesrvm.compilers.common.CompiledMethod)2 ForwardReference (org.jikesrvm.compilers.common.assembler.ForwardReference)2 ITable (org.jikesrvm.objectmodel.ITable)2 TIB (org.jikesrvm.objectmodel.TIB)2