use of org.vmmagic.pragma.Uninterruptible in project JikesRVM by JikesRVM.
the class JNIEnvironment method entryToJNI.
/**
* Save data and perform necessary conversions for entry into JNI.
* NB only used for Intel.
*
* @param encodedReferenceOffsets
* bit mask marking which elements on the stack hold objects that need
* encoding as JNI ref identifiers
*/
@Uninterruptible("Objects on the stack won't be recognized by GC, therefore don't allow GC")
@Entrypoint
public void entryToJNI(int encodedReferenceOffsets) {
// Save processor
savedTRreg = Magic.getThreadRegister();
// Save frame pointer of calling routine, once so that native stack frames
// are skipped and once for use by GC
Address callersFP = Magic.getCallerFramePointer(Magic.getFramePointer());
// NB old value saved on call stack
basePointerOnEntryToNative = callersFP;
JNITopJavaFP = callersFP;
if (VM.traceJNI) {
RVMMethod m = CompiledMethods.getCompiledMethod(Magic.getCompiledMethodID(callersFP)).getMethod();
VM.sysWrite("calling JNI from ");
VM.sysWrite(m.getDeclaringClass().getDescriptor());
VM.sysWrite(" ");
VM.sysWrite(m.getName());
VM.sysWrite(m.getDescriptor());
VM.sysWriteln();
}
// Save current JNI ref stack pointer
if (JNIRefsTop > 0) {
uninterruptiblePushJNIRef(Address.fromIntSignExtend(JNIRefsSavedFP), false);
JNIRefsSavedFP = JNIRefsTop;
}
// Convert arguments on stack from objects to JNI references
Address fp = Magic.getFramePointer();
Offset argOffset = Offset.fromIntSignExtend(5 * BYTES_IN_ADDRESS);
fp.store(uninterruptiblePushJNIRef(fp.loadAddress(argOffset), true), argOffset);
while (encodedReferenceOffsets != 0) {
argOffset = argOffset.plus(BYTES_IN_ADDRESS);
if ((encodedReferenceOffsets & 1) != 0) {
fp.store(uninterruptiblePushJNIRef(fp.loadAddress(argOffset), true), argOffset);
}
encodedReferenceOffsets >>>= 1;
}
// Transition processor from IN_JAVA to IN_JNI
RVMThread.enterJNIFromCallIntoNative();
}
use of org.vmmagic.pragma.Uninterruptible in project JikesRVM by JikesRVM.
the class Registers method initializeStack.
/**
* The following method initializes a thread stack as if
* "startoff" method had been called by an empty baseline-compiled
* "sentinel" frame with one local variable
*
* @param ip The instruction pointer for the "startoff" method
* @param sp The base of the stack
*/
@Override
@Uninterruptible
public void initializeStack(Address ip, Address sp) {
Address fp;
// last word of header
sp = sp.minus(STACKFRAME_HEADER_SIZE);
fp = sp.minus(BYTES_IN_ADDRESS).minus(STACKFRAME_BODY_OFFSET);
Magic.setCallerFramePointer(fp, STACKFRAME_SENTINEL_FP);
Magic.setCompiledMethodID(fp, INVISIBLE_METHOD_ID);
// allow for one local
sp = sp.minus(BYTES_IN_ADDRESS);
getGPRs().set(ESP.value(), sp.toWord());
this.fp = fp;
this.ip = ip;
}
use of org.vmmagic.pragma.Uninterruptible in project JikesRVM by JikesRVM.
the class RuntimeMeasurements method takeCBSCallSample.
/**
* Called from Thread.yieldpoint when it is time to take a CBS call sample.
*
* @param whereFrom source of the yieldpoint (e.g. backedge)
* @param yieldpointServiceMethodFP the frame pointer of the service
* method that is responsible for handling the yieldpoint
*/
@Uninterruptible
public static void takeCBSCallSample(int whereFrom, Address yieldpointServiceMethodFP) {
// method that took yieldpoint
Address ypTakenInFP = Magic.getCallerFramePointer(yieldpointServiceMethodFP);
// Get the cmid for the method in which the yieldpoint was taken.
int ypTakenInCMID = Magic.getCompiledMethodID(ypTakenInFP);
// Get the cmid for that method's caller.
Address ypTakenInCallerFP = Magic.getCallerFramePointer(ypTakenInFP);
int ypTakenInCallerCMID = Magic.getCompiledMethodID(ypTakenInCallerFP);
// Determine if ypTakenInCallerCMID corresponds to a real Java stackframe.
// If one of the following conditions is detected, set ypTakenInCallerCMID to -1
// Caller is out-of-line assembly (no RVMMethod object) or top-of-stack psuedo-frame
// Caller is a native method
CompiledMethod ypTakenInCM = CompiledMethods.getCompiledMethod(ypTakenInCMID);
if (ypTakenInCallerCMID == StackFrameLayout.getInvisibleMethodID() || ypTakenInCM.getMethod().getDeclaringClass().hasBridgeFromNativeAnnotation()) {
// drop sample
} else {
// Notify all registered listeners
for (ContextListener listener : cbsContextListeners) {
if (listener.isActive()) {
listener.update(ypTakenInFP, whereFrom);
}
}
}
}
use of org.vmmagic.pragma.Uninterruptible in project JikesRVM by JikesRVM.
the class RCHeader method makeUnlogged.
/**
* Change <code>object</code>'s state to <code>UNLOGGED</code>.
*
* @param object The object whose state is to be changed.
*/
@Inline
@Uninterruptible
public static void makeUnlogged(ObjectReference object) {
Word oldValue, newValue;
do {
oldValue = VM.objectModel.prepareAvailableBits(object);
if (VM.VERIFY_ASSERTIONS)
VM.assertions._assert(oldValue.and(LOGGING_MASK).EQ(LOGGED));
newValue = oldValue.or(UNLOGGED);
} while (!VM.objectModel.attemptAvailableBits(object, oldValue, newValue));
}
use of org.vmmagic.pragma.Uninterruptible in project JikesRVM by JikesRVM.
the class RCHeader method attemptToLog.
/**
* Attempt to log <code>object</code> for coalescing RC. This is
* used to handle a race to log the object, and returns
* <code>true</code> if we are to log the object and
* <code>false</code> if we lost the race to log the object.
*
* <p>If this method returns <code>true</code>, it leaves the object
* in the <code>BEING_LOGGED</code> state. It is the responsibility
* of the caller to change the object to <code>LOGGED</code> once
* the logging is complete.
*
* @see #makeLogged(ObjectReference)
* @param object The object in question
* @return <code>true</code> if the race to log
* <code>object</code>was won.
*/
@Inline
@Uninterruptible
public static boolean attemptToLog(ObjectReference object) {
Word oldValue;
do {
oldValue = VM.objectModel.prepareAvailableBits(object);
if (oldValue.and(LOGGING_MASK).EQ(LOGGED)) {
return false;
}
} while ((oldValue.and(LOGGING_MASK).EQ(BEING_LOGGED)) || !VM.objectModel.attemptAvailableBits(object, oldValue, oldValue.or(BEING_LOGGED)));
if (VM.VERIFY_ASSERTIONS) {
Word value = VM.objectModel.readAvailableBitsWord(object);
VM.assertions._assert(value.and(LOGGING_MASK).EQ(BEING_LOGGED));
}
return true;
}
Aggregations