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;
}
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);
}
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();
}
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);
}
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;
}
Aggregations