Search in sources :

Example 1 with UnpreemptibleNoWarn

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

the class VM method boot.

/**
 * Begin VM execution.<p>
 *
 * Uninterruptible because we are not setup to execute a yieldpoint
 * or stackoverflow check in the prologue this early in booting.<p>
 *
 * The following machine registers are set by "C" bootstrap program
 * before calling this method:
 * <ol>
 *   <li>JTOC_POINTER - required for accessing globals
 *   <li>FRAME_POINTER - required for accessing locals
 *   <li>THREAD_ID_REGISTER - required for method prolog (stack overflow check)
 * </ol>
 */
@UnpreemptibleNoWarn("No point threading until threading is booted")
@Entrypoint
public static void boot() {
    writingBootImage = false;
    runningVM = true;
    verboseBoot = BootRecord.the_boot_record.verboseBoot;
    verboseSignalHandling = BootRecord.the_boot_record.verboseSignalHandling != 0;
    sysWriteLockOffset = Entrypoints.sysWriteLockField.getOffset();
    if (verboseBoot >= 1)
        VM.sysWriteln("Booting");
    // register.
    if (verboseBoot >= 1)
        VM.sysWriteln("Setting up current RVMThread");
    if (VM.BuildForIA32) {
        org.jikesrvm.ia32.ThreadLocalState.boot();
    } else {
        if (VM.VerifyAssertions)
            VM._assert(VM.BuildForPowerPC);
        org.jikesrvm.ppc.ThreadLocalState.boot();
    }
    // 
    if (verboseBoot >= 1)
        VM.sysWriteln("Doing thread initialization");
    RVMThread currentThread = RVMThread.getCurrentThread();
    currentThread.stackLimit = Magic.objectAsAddress(currentThread.getStack()).plus(StackFrameLayout.getStackSizeGuard());
    finishBooting();
}
Also used : RVMThread(org.jikesrvm.scheduler.RVMThread) Entrypoint(org.vmmagic.pragma.Entrypoint) UnpreemptibleNoWarn(org.vmmagic.pragma.UnpreemptibleNoWarn)

Example 2 with UnpreemptibleNoWarn

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

the class MachineReflection method packageParameters.

/**
 * Collects parameters into arrays of registers/spills, as required to
 * call specified method.
 *
 * @param method method whose parameters are to be packaged
 * @param thisArg the receiver argument
 * @param otherArgs all other arguments (primitives are boxed)
 * @param GPRs space for GPRs (empty array if none needed)
 * @param FPRs space for FPRs (empty array if none needed)
 * @param FPRmeta meta-data for FPRs ({@code null} if no SSE2)
 * @param Parameters more space for parameters. Refer to the source code
 *  to get all the details.
 *
 * @see #countParameters(RVMMethod) more machine-specific details
 */
@UnpreemptibleNoWarn("GC is disabled as Objects are turned into Words." + "avoid preemption but still allow calls to preemptible unboxing routines")
public static void packageParameters(RVMMethod method, Object thisArg, Object[] otherArgs, WordArray GPRs, double[] FPRs, byte[] FPRmeta, WordArray Parameters) {
    int GPR = 0;
    int FPR = SSE2_FULL ? 0 : FPRs.length;
    int parameter = 0;
    // 0, 1, 2
    int gp = NUM_PARAMETER_GPRS;
    // 0-8
    int fp = NUM_PARAMETER_FPRS;
    if (!method.isStatic()) {
        Word val = Magic.objectAsAddress(thisArg).toWord();
        if (gp > 0) {
            gp--;
            GPRs.set(GPR++, val);
        }
        Parameters.set(parameter++, val);
    }
    TypeReference[] types = method.getParameterTypes();
    for (int i = 0; i < types.length; i++) {
        TypeReference t = types[i];
        if (!t.isPrimitiveType()) {
            Word val = Magic.objectAsAddress(otherArgs[i]).toWord();
            if (gp > 0) {
                gp--;
                GPRs.set(GPR++, val);
            }
            Parameters.set(parameter++, val);
        } else if (t.isLongType()) {
            long l = (Long) otherArgs[i];
            if (VM.BuildFor32Addr) {
                if (gp > 0) {
                    gp--;
                    GPRs.set(GPR++, Word.fromIntZeroExtend((int) (l >>> 32)));
                    if (gp > 0) {
                        gp--;
                        GPRs.set(GPR++, Word.fromIntZeroExtend((int) (l)));
                    }
                }
                Parameters.set(parameter++, Word.fromIntZeroExtend((int) (l >>> 32)));
                Parameters.set(parameter++, Word.fromIntZeroExtend((int) l));
            } else {
                Word val = Word.fromLong(l);
                if (gp > 0) {
                    gp--;
                    GPRs.set(GPR++, val);
                }
                Parameters.set(parameter++, val);
                Parameters.set(parameter++, val);
            }
        } else if (t.isFloatType()) {
            if (fp > 0) {
                fp--;
                if (SSE2_FULL) {
                    FPRs[FPR] = (Float) otherArgs[i];
                    FPRmeta[FPR] = 0x0;
                    FPR++;
                } else {
                    FPRs[--FPR] = (Float) otherArgs[i];
                }
            }
            float f = (Float) otherArgs[i];
            Parameters.set(parameter++, Word.fromIntZeroExtend(Float.floatToIntBits(f)));
        } else if (t.isDoubleType()) {
            if (VM.BuildFor32Addr) {
                if (fp > 0) {
                    fp--;
                    if (SSE2_FULL) {
                        FPRs[FPR] = (Double) otherArgs[i];
                        FPRmeta[FPR] = 0x1;
                        FPR++;
                    } else {
                        FPRs[--FPR] = (Double) otherArgs[i];
                    }
                }
                double d = (Double) otherArgs[i];
                long l = Double.doubleToLongBits(d);
                Parameters.set(parameter++, Word.fromIntZeroExtend((int) (l >>> 32)));
                Parameters.set(parameter++, Word.fromIntZeroExtend((int) l));
            } else {
                if (fp > 0) {
                    fp--;
                    if (SSE2_FULL) {
                        FPRs[FPR] = (Double) otherArgs[i];
                        FPRmeta[FPR] = 0x1;
                        FPR++;
                    } else {
                        FPRs[--FPR] = (Double) otherArgs[i];
                    }
                }
                double d = (Double) otherArgs[i];
                long l = Double.doubleToLongBits(d);
                Word val = Word.fromLong(l);
                Parameters.set(parameter++, val);
                Parameters.set(parameter++, val);
            }
        } else if (t.isBooleanType()) {
            boolean b = (Boolean) otherArgs[i];
            Word val = Word.fromIntZeroExtend(b ? 1 : 0);
            if (gp > 0) {
                gp--;
                GPRs.set(GPR++, val);
            }
            Parameters.set(parameter++, val);
        } else if (t.isCharType()) {
            char c = (Character) otherArgs[i];
            Word val = Word.fromIntZeroExtend(c);
            if (gp > 0) {
                gp--;
                GPRs.set(GPR++, val);
            }
            Parameters.set(parameter++, val);
        } else {
            if (VM.VerifyAssertions)
                VM._assert(t.isByteType() || t.isShortType() || t.isIntType());
            int x = ((Number) otherArgs[i]).intValue();
            Word val = Word.fromIntZeroExtend(x);
            if (gp > 0) {
                gp--;
                GPRs.set(GPR++, val);
            }
            Parameters.set(parameter++, val);
        }
    }
}
Also used : Word(org.vmmagic.unboxed.Word) TypeReference(org.jikesrvm.classloader.TypeReference) UnpreemptibleNoWarn(org.vmmagic.pragma.UnpreemptibleNoWarn)

Example 3 with UnpreemptibleNoWarn

use of org.vmmagic.pragma.UnpreemptibleNoWarn 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 4 with UnpreemptibleNoWarn

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

the class FinalizableProcessor method add.

/**
 * Allocate an entry in the table. This should be called from an unpreemptible
 * context so that the entry can be filled. This method is responsible for growing
 * the table if necessary.
 *
 * @param object the object to add to the table of candidates
 */
@NoInline
@UnpreemptibleNoWarn("Non-preemptible but yield when table needs to be grown")
public void add(Object object) {
    lock.acquire();
    while (maxIndex >= table.length() || maxIndex >= freeReady()) {
        int newTableSize = -1;
        int newReadyForFinalizeSize = -1;
        AddressArray newTable = null;
        Object[] newReadyForFinalize = null;
        if (maxIndex >= table.length()) {
            newTableSize = STRESS ? table.length() + 1 : (int) (table.length() * GROWTH_FACTOR);
        }
        if (maxIndex >= freeReady()) {
            newReadyForFinalizeSize = table.length() + countReady();
            if (newReadyForFinalizeSize <= readyForFinalize.length) {
                newReadyForFinalizeSize = -1;
            }
        }
        {
            lock.release();
            if (newTableSize >= 0) {
                newTable = AddressArray.create(newTableSize);
            }
            if (newReadyForFinalizeSize >= 0) {
                newReadyForFinalize = new Object[newReadyForFinalizeSize];
            }
            lock.acquire();
        }
        if (maxIndex >= table.length() && newTable != null) {
            for (int i = 0; i < table.length(); i++) {
                newTable.set(i, table.get(i));
            }
            table = newTable;
        }
        if (maxIndex >= freeReady() && newReadyForFinalize != null) {
            int j = 0;
            for (int i = nextReadyIndex; i < lastReadyIndex && i < readyForFinalize.length; i++) {
                newReadyForFinalize[j++] = readyForFinalize[i];
            }
            if (lastReadyIndex < nextReadyIndex) {
                for (int i = 0; i < lastReadyIndex; i++) {
                    newReadyForFinalize[j++] = readyForFinalize[i];
                }
            }
            lastReadyIndex = j;
            nextReadyIndex = 0;
            readyForFinalize = newReadyForFinalize;
        }
    }
    table.set(maxIndex++, Magic.objectAsAddress(object));
    lock.release();
}
Also used : AddressArray(org.vmmagic.unboxed.AddressArray) NoInline(org.vmmagic.pragma.NoInline) UnpreemptibleNoWarn(org.vmmagic.pragma.UnpreemptibleNoWarn)

Aggregations

UnpreemptibleNoWarn (org.vmmagic.pragma.UnpreemptibleNoWarn)4 RVMThread (org.jikesrvm.scheduler.RVMThread)2 Entrypoint (org.vmmagic.pragma.Entrypoint)2 AbstractRegisters (org.jikesrvm.architecture.AbstractRegisters)1 TypeReference (org.jikesrvm.classloader.TypeReference)1 CompiledMethod (org.jikesrvm.compilers.common.CompiledMethod)1 NoInline (org.vmmagic.pragma.NoInline)1 Address (org.vmmagic.unboxed.Address)1 AddressArray (org.vmmagic.unboxed.AddressArray)1 Offset (org.vmmagic.unboxed.Offset)1 Word (org.vmmagic.unboxed.Word)1