use of org.jikesrvm.scheduler.RVMThread in project JikesRVM by JikesRVM.
the class OnStackReplacementTrigger method trigger.
@NoInline
@Unpreemptible
public static void trigger(int ypTakenInCMID, Offset tsFromFPoff, Offset ypTakenFPoff, int whereFrom) {
RVMThread thread = RVMThread.getCurrentThread();
CompiledMethod ypTakenInCM = CompiledMethods.getCompiledMethod(ypTakenInCMID);
RVMMethod ypTakenInMethod = ypTakenInCM.getMethod();
boolean isInBootImage = ypTakenInMethod.getDeclaringClass().isInBootImage();
if (isInBootImage)
return;
OnStackReplacementEvent event = (OnStackReplacementEvent) thread.onStackReplacementEvent;
event.suspendedThread = thread;
event.whereFrom = whereFrom;
event.CMID = ypTakenInCMID;
event.tsFromFPoff = tsFromFPoff;
event.ypTakenFPoff = ypTakenFPoff;
thread.monitor().lockNoHandshake();
thread.requesting_osr = true;
thread.monitor().unlock();
Controller.osrOrganizer.activate();
// PNT: Assumes that OSR doesn't need access to our context regs
thread.monitor().lockNoHandshake();
while (!thread.osr_done) {
thread.monitor().waitWithHandshake();
}
thread.osr_done = false;
thread.monitor().unlock();
}
use of org.jikesrvm.scheduler.RVMThread in project JikesRVM by JikesRVM.
the class VMThread method create.
/**
* Creates the VM thread, sets this in the parent Thread and starts its
* execution.
*/
static void create(Thread parent, long stacksize) {
int boundedStackSize = stackSizeFromAPIToJikesRVM(stacksize);
RVMThread vmd = new RVMThread(parent, boundedStackSize, parent.name, parent.daemon, parent.priority);
parent.vmThread = new VMThread(vmd);
vmd.start();
}
use of org.jikesrvm.scheduler.RVMThread in project JikesRVM by JikesRVM.
the class Scanning method computeThreadRoots.
/**
* Compute roots pointed to by threads.
*
* @param trace The trace to use for computing roots.
* @param newRootsSufficient True if it sufficient for this method to only
* compute those roots that are new since the previous stack scan. If false
* then all roots must be computed (both new and preexisting).
*/
private void computeThreadRoots(TraceLocal trace, boolean newRootsSufficient) {
boolean processCodeLocations = MOVES_CODE;
/* scan all threads */
while (true) {
int threadIndex = threadCounter.increment();
if (threadIndex > RVMThread.numThreads)
break;
RVMThread thread = RVMThread.threads[threadIndex];
if (thread == null || thread.isCollectorThread())
continue;
/* scan the thread (stack etc.) */
ScanThread.scanThread(thread, trace, processCodeLocations, newRootsSufficient);
}
/* flush out any remset entries generated during the above activities */
Selected.Mutator.get().flushRememberedSets();
}
use of org.jikesrvm.scheduler.RVMThread in project JikesRVM by JikesRVM.
the class Collection method prepareMutator.
@Override
public final void prepareMutator(MutatorContext m) {
/*
* The collector threads of processors currently running threads
* off in JNI-land cannot run.
*/
RVMThread t = ((Selected.Mutator) m).getThread();
t.monitor().lockNoHandshake();
// are these the only unexpected states?
t.assertUnacceptableStates(RVMThread.IN_JNI, RVMThread.IN_NATIVE);
int execStatus = t.getExecStatus();
// but having more assertions never hurts...
if (VM.VerifyAssertions)
VM._assert(execStatus != RVMThread.IN_JNI);
if (VM.VerifyAssertions)
VM._assert(execStatus != RVMThread.IN_NATIVE);
if (execStatus == RVMThread.BLOCKED_IN_JNI) {
if (false) {
VM.sysWriteln("for thread #", t.getThreadSlot(), " setting up JNI stack scan");
VM.sysWriteln("thread #", t.getThreadSlot(), " has top java fp = ", t.getJNIEnv().topJavaFP());
}
/* thread is blocked in C for this GC.
Its stack needs to be scanned, starting from the "top" java
frame, which has been saved in the running threads JNIEnv. Put
the saved frame pointer into the threads saved context regs,
which is where the stack scan starts. */
t.contextRegisters.setInnermost(Address.zero(), t.getJNIEnv().topJavaFP());
}
t.monitor().unlock();
}
use of org.jikesrvm.scheduler.RVMThread in project JikesRVM by JikesRVM.
the class VM method disableGC.
/**
* disableGC: Disable GC if it hasn't already been disabled. This
* enforces a stack discipline; we need it for the JNI Get*Critical and
* Release*Critical functions. Should be matched with a subsequent call to
* enableGC().
*
* @param recursiveOK whether recursion is allowed.
*/
@Inline
@Unpreemptible("We may boost the size of the stack with GC disabled and may get preempted doing this")
public static void disableGC(boolean recursiveOK) {
// current (non-GC) thread is going to be holding raw addresses, therefore we must:
//
// 1. make sure we have enough stack space to run until GC is re-enabled
// (otherwise we might trigger a stack reallocation)
// (We can't resize the stack if there's a native frame, so don't
// do it and hope for the best)
//
// 2. force all other threads that need GC to wait until this thread
// is done with the raw addresses
//
// 3. ensure that this thread doesn't try to allocate any objects
// (because an allocation attempt might trigger a collection that
// would invalidate the addresses we're holding)
//
RVMThread myThread = RVMThread.getCurrentThread();
// 0. Sanity Check; recursion
int gcDepth = myThread.getDisableGCDepth();
if (VM.VerifyAssertions)
VM._assert(gcDepth >= 0);
gcDepth++;
myThread.setDisableGCDepth(gcDepth);
if (gcDepth > 1) {
// We've already disabled it.
return;
}
//
if (Magic.getFramePointer().minus(StackFrameLayout.getStackSizeGCDisabled()).LT(myThread.stackLimit) && !myThread.hasNativeStackFrame()) {
RVMThread.resizeCurrentStack(myThread.getStackLength() + StackFrameLayout.getStackSizeGCDisabled(), null);
}
// 2.
//
myThread.disableYieldpoints();
//
if (VM.VerifyAssertions) {
if (!recursiveOK) {
// recursion not allowed
VM._assert(!myThread.getDisallowAllocationsByThisThread());
}
myThread.setDisallowAllocationsByThisThread();
}
}
Aggregations