Search in sources :

Example 16 with RVMThread

use of org.jikesrvm.scheduler.RVMThread in project JikesRVM by JikesRVM.

the class JikesRVMSupport method createThread.

/**
 * Thread stuff
 */
public static Thread createThread(RVMThread vmdata, String myName) {
    if (VM.VerifyAssertions)
        VM._assert(VM.runningVM);
    Thread bootThread = new Thread(new VMThread(vmdata), myName, vmdata.getPriority(), vmdata.isDaemonThread());
    bootThread.group = ThreadGroup.root;
    return bootThread;
}
Also used : RVMThread(org.jikesrvm.scheduler.RVMThread) RVMThread(org.jikesrvm.scheduler.RVMThread)

Example 17 with RVMThread

use of org.jikesrvm.scheduler.RVMThread in project JikesRVM by JikesRVM.

the class Collection method blockForGC.

@Override
@Unpreemptible
public void blockForGC() {
    RVMThread t = RVMThread.getCurrentThread();
    t.assertAcceptableStates(RVMThread.IN_JAVA, RVMThread.IN_JAVA_TO_BLOCK);
    RVMThread.observeExecStatusAtSTW(t.getExecStatus());
    RVMThread.getCurrentThread().block(RVMThread.gcBlockAdapter);
}
Also used : RVMThread(org.jikesrvm.scheduler.RVMThread) Unpreemptible(org.vmmagic.pragma.Unpreemptible)

Example 18 with RVMThread

use of org.jikesrvm.scheduler.RVMThread in project JikesRVM by JikesRVM.

the class Lock method acquire.

@Override
public void acquire() {
    RVMThread me = RVMThread.getCurrentThread();
    Offset offset = Entrypoints.lockStateField.getOffset();
    boolean acquired = false;
    for (int i = 0; me.isOnQueue() || i < SPIN_LIMIT; ++i) {
        int oldState = Magic.prepareInt(this, offset);
        // would make the lock slightly more fair.
        if ((oldState == CLEAR && Magic.attemptInt(this, offset, CLEAR, LOCKED)) || (oldState == CLEAR_QUEUED && Magic.attemptInt(this, offset, CLEAR_QUEUED, LOCKED_QUEUED))) {
            acquired = true;
            break;
        }
    }
    if (!acquired) {
        for (; ; ) {
            int oldState = Magic.prepareInt(this, offset);
            if ((oldState == CLEAR && Magic.attemptInt(this, offset, CLEAR, LOCKED)) || (oldState == CLEAR_QUEUED && Magic.attemptInt(this, offset, CLEAR_QUEUED, LOCKED_QUEUED))) {
                break;
            } else if ((oldState == LOCKED && Magic.attemptInt(this, offset, LOCKED, QUEUEING)) || (oldState == LOCKED_QUEUED && Magic.attemptInt(this, offset, LOCKED_QUEUED, QUEUEING))) {
                if (!VM.MagicAttemptImpliesStoreLoadBarrier)
                    Magic.fence();
                queue.enqueue(me);
                Magic.fence();
                state = LOCKED_QUEUED;
                me.monitor().lockNoHandshake();
                while (queue.isQueued(me)) {
                    // use waitNoHandshake instead of waitWithHandshake because this is NOT a GC point!
                    me.monitor().waitNoHandshake();
                }
                me.monitor().unlock();
            }
        }
    }
    thread = me;
    where = -1;
    Magic.combinedLoadBarrier();
}
Also used : RVMThread(org.jikesrvm.scheduler.RVMThread)

Example 19 with RVMThread

use of org.jikesrvm.scheduler.RVMThread in project JikesRVM by JikesRVM.

the class RuntimeEntrypoints method deliverException.

/**
 * Deliver an exception to current java thread.
 * <STRONG> Precondition: </STRONG> VM.disableGC has already been called.
 *  <ol>
 *   <li> exceptionRegisters may not match any reasonable stack
 *          frame at this point.
 *   <li> we're going to be playing with raw addresses (fp, ip).
 *  </ol>
 * <p>
 * Does not return:
 * <ul>
 *  <li> stack is unwound and execution resumes in a catch block
 *  <li> <em> or </em> current thread is terminated if no catch block is found
 * </ul>
 *
 * @param exceptionObject exception object to deliver
 * @param exceptionRegisters register state corresponding to exception site
 */
@Unpreemptible("Deliver exception trying to avoid preemption")
private static void deliverException(Throwable exceptionObject, AbstractRegisters exceptionRegisters) {
    if (VM.TraceExceptionDelivery) {
        VM.sysWriteln("RuntimeEntrypoints.deliverException() entered; just got an exception object.");
    }
    // 
    if (VM.TraceExceptionDelivery) {
        VM.sysWrite("Hunting for a catch block...");
    }
    RVMType exceptionType = Magic.getObjectType(exceptionObject);
    Address fp = exceptionRegisters.getInnermostFramePointer();
    Address hijackedCalleeFp = RVMThread.getCurrentThread().getHijackedReturnCalleeFp();
    boolean leapfroggedReturnBarrier = false;
    if (VM.VerifyAssertions)
        VM._assert(hijackedCalleeFp.isZero() || hijackedCalleeFp.GE(fp));
    while (Magic.getCallerFramePointer(fp).NE(StackFrameLayout.getStackFrameSentinelFP())) {
        if (!hijackedCalleeFp.isZero() && hijackedCalleeFp.LE(fp)) {
            leapfroggedReturnBarrier = true;
        }
        int compiledMethodId = Magic.getCompiledMethodID(fp);
        if (compiledMethodId != StackFrameLayout.getInvisibleMethodID()) {
            CompiledMethod compiledMethod = CompiledMethods.getCompiledMethod(compiledMethodId);
            ExceptionDeliverer exceptionDeliverer = compiledMethod.getExceptionDeliverer();
            Address ip = exceptionRegisters.getInnermostInstructionAddress();
            Offset ipOffset = compiledMethod.getInstructionOffset(ip);
            int catchBlockOffset = compiledMethod.findCatchBlockForInstruction(ipOffset, exceptionType);
            if (catchBlockOffset >= 0) {
                // found an appropriate catch block
                if (VM.TraceExceptionDelivery) {
                    VM.sysWriteln("found one; delivering.");
                }
                if (leapfroggedReturnBarrier) {
                    RVMThread t = RVMThread.getCurrentThread();
                    if (RVMThread.DEBUG_STACK_TRAMPOLINE)
                        VM.sysWriteln("leapfrogged...");
                    t.deInstallStackTrampoline();
                }
                Address catchBlockStart = compiledMethod.getInstructionAddress(Offset.fromIntSignExtend(catchBlockOffset));
                exceptionDeliverer.deliverException(compiledMethod, catchBlockStart, exceptionObject, exceptionRegisters);
                if (VM.VerifyAssertions)
                    VM._assert(NOT_REACHED);
            }
            exceptionDeliverer.unwindStackFrame(compiledMethod, exceptionRegisters);
        } else {
            unwindInvisibleStackFrame(exceptionRegisters);
        }
        fp = exceptionRegisters.getInnermostFramePointer();
    }
    if (VM.TraceExceptionDelivery) {
        VM.sysWriteln("Nope.");
        VM.sysWriteln("RuntimeEntrypoints.deliverException() found no catch block.");
    }
    /* No appropriate catch block found. */
    if (RVMThread.DEBUG_STACK_TRAMPOLINE && leapfroggedReturnBarrier)
        VM.sysWriteln("Leapfrogged, and unhandled!");
    handleUncaughtException(exceptionObject);
}
Also used : Address(org.vmmagic.unboxed.Address) RVMThread(org.jikesrvm.scheduler.RVMThread) RVMType(org.jikesrvm.classloader.RVMType) Entrypoint(org.vmmagic.pragma.Entrypoint) CompiledMethod(org.jikesrvm.compilers.common.CompiledMethod) Offset(org.vmmagic.unboxed.Offset) Unpreemptible(org.vmmagic.pragma.Unpreemptible)

Example 20 with RVMThread

use of org.jikesrvm.scheduler.RVMThread in project JikesRVM by JikesRVM.

the class CodeInstaller method install.

/* install the newly compiled instructions. */
public static boolean install(ExecutionState state, CompiledMethod cm) {
    RVMThread thread = state.getThread();
    byte[] stack = thread.getStack();
    Offset fooFPOffset = state.getFPOffset();
    // we are going to dynamically generate some code recover
    // register values from the stack frame.
    int foomid = Magic.getIntAtOffset(stack, fooFPOffset.plus(STACKFRAME_METHOD_ID_OFFSET));
    CompiledMethod foo = CompiledMethods.getCompiledMethod(foomid);
    int cType = foo.getCompilerType();
    Assembler asm = new Assembler(0, VM.TraceOnStackReplacement);
    // ///////////////////////////////////
    if (cType == CompiledMethod.BASELINE) {
        ArchBaselineCompiledMethod bcm = (ArchBaselineCompiledMethod) foo;
        int offset = bcm.getFrameSize();
        for (int i = bcm.getLastFloatStackRegister(); i >= FIRST_FLOAT_LOCAL_REGISTER.value(); --i) {
            offset -= BYTES_IN_DOUBLE;
            asm.emitLFD(FPR.lookup(i), offset, FP);
        }
        for (int i = bcm.getLastFixedStackRegister(); i >= FIRST_FIXED_LOCAL_REGISTER.value(); --i) {
            offset -= BYTES_IN_ADDRESS;
            asm.emitLAddr(GPR.lookup(i), offset, FP);
        }
    } else if (cType == CompiledMethod.OPT) {
        OptCompiledMethod fooOpt = (OptCompiledMethod) foo;
        // foo definitely not save volatile.
        boolean saveVolatile = fooOpt.isSaveVolatile();
        if (VM.VerifyAssertions) {
            VM._assert(!saveVolatile);
        }
        int offset = fooOpt.getUnsignedNonVolatileOffset();
        // recover nonvolatile GPRs
        int firstGPR = fooOpt.getFirstNonVolatileGPR();
        if (firstGPR != -1) {
            for (int i = firstGPR; i <= LAST_NONVOLATILE_GPR.value(); i++) {
                asm.emitLAddr(GPR.lookup(i), offset, FP);
                offset += BYTES_IN_STACKSLOT;
            }
        }
        // recover nonvolatile FPRs
        int firstFPR = fooOpt.getFirstNonVolatileFPR();
        if (firstFPR != -1) {
            for (int i = firstFPR; i <= LAST_NONVOLATILE_FPR.value(); i++) {
                asm.emitLFD(FPR.lookup(i), offset, FP);
                offset += BYTES_IN_DOUBLE;
            }
        }
    }
    if (VM.VerifyAssertions) {
        Object jtocContent = Statics.getSlotContentsAsObject(cm.getOsrJTOCoffset());
        VM._assert(jtocContent == cm.getEntryCodeArray());
    }
    // load address of newInstructions from JTOC
    asm.emitLAddrToc(S0, cm.getOsrJTOCoffset());
    // mov CTR addr
    asm.emitMTCTR(S0);
    // lwz FP, 0(FP)
    asm.emitLAddr(FP, 0, FP);
    // lwz T0, NEXT_INSTR(FP)
    asm.emitLAddr(S0, STACKFRAME_RETURN_ADDRESS_OFFSET.toInt(), FP);
    // mov LR, addr
    asm.emitMTLR(S0);
    // bctr
    asm.emitBCCTR();
    // mark the thread as waiting for on stack replacement.
    thread.isWaitingForOsr = true;
    thread.bridgeInstructions = asm.getMachineCodes();
    thread.fooFPOffset = fooFPOffset;
    Address bridgeaddr = Magic.objectAsAddress(thread.bridgeInstructions);
    Memory.sync(bridgeaddr, thread.bridgeInstructions.length() << LG_INSTRUCTION_WIDTH);
    AOSLogging.logger.logOsrEvent("OSR code installation succeeded");
    return true;
}
Also used : ArchBaselineCompiledMethod(org.jikesrvm.compilers.baseline.ppc.ArchBaselineCompiledMethod) OptCompiledMethod(org.jikesrvm.compilers.opt.runtimesupport.OptCompiledMethod) Address(org.vmmagic.unboxed.Address) RVMThread(org.jikesrvm.scheduler.RVMThread) Assembler(org.jikesrvm.compilers.common.assembler.ppc.Assembler) ArchBaselineCompiledMethod(org.jikesrvm.compilers.baseline.ppc.ArchBaselineCompiledMethod) OptCompiledMethod(org.jikesrvm.compilers.opt.runtimesupport.OptCompiledMethod) CompiledMethod(org.jikesrvm.compilers.common.CompiledMethod) Offset(org.vmmagic.unboxed.Offset)

Aggregations

RVMThread (org.jikesrvm.scheduler.RVMThread)22 Unpreemptible (org.vmmagic.pragma.Unpreemptible)7 Address (org.vmmagic.unboxed.Address)7 Entrypoint (org.vmmagic.pragma.Entrypoint)6 CompiledMethod (org.jikesrvm.compilers.common.CompiledMethod)5 Offset (org.vmmagic.unboxed.Offset)5 NoInline (org.vmmagic.pragma.NoInline)4 OptCompiledMethod (org.jikesrvm.compilers.opt.runtimesupport.OptCompiledMethod)3 AbstractRegisters (org.jikesrvm.architecture.AbstractRegisters)2 Test (org.junit.Test)2 Inline (org.vmmagic.pragma.Inline)2 UnpreemptibleNoWarn (org.vmmagic.pragma.UnpreemptibleNoWarn)2 LockInfo (java.lang.management.LockInfo)1 MonitorInfo (java.lang.management.MonitorInfo)1 ThreadInfo (java.lang.management.ThreadInfo)1 InvocationTargetException (java.lang.reflect.InvocationTargetException)1 RVMMethod (org.jikesrvm.classloader.RVMMethod)1 RVMType (org.jikesrvm.classloader.RVMType)1 ArchBaselineCompiledMethod (org.jikesrvm.compilers.baseline.ppc.ArchBaselineCompiledMethod)1 Assembler (org.jikesrvm.compilers.common.assembler.ia32.Assembler)1