use of org.vmmagic.pragma.Uninterruptible in project JikesRVM by JikesRVM.
the class ThinLock method holdsLock.
@Uninterruptible
@NoNullCheck
public static boolean holdsLock(Object o, Offset lockOffset, RVMThread thread) {
for (int cnt = 0; ; ++cnt) {
int tid = thread.getLockingId();
Word bits = Magic.getWordAtOffset(o, lockOffset);
if (bits.and(TL_STAT_MASK).EQ(TL_STAT_BIASABLE)) {
// if locked, then it is locked with a thin lock
return bits.and(TL_THREAD_ID_MASK).toInt() == tid && !bits.and(TL_LOCK_COUNT_MASK).isZero();
} else if (bits.and(TL_STAT_MASK).EQ(TL_STAT_THIN)) {
return bits.and(TL_THREAD_ID_MASK).toInt() == tid;
} else {
if (VM.VerifyAssertions)
VM._assert(bits.and(TL_STAT_MASK).EQ(TL_STAT_FAT));
// if locked, then it is locked with a fat lock
Lock l = Lock.getLock(getLockIndex(bits));
if (l != null) {
l.mutex.lock();
boolean result = (l.getOwnerId() == tid && l.getLockedObject() == o);
l.mutex.unlock();
return result;
}
}
RVMThread.yieldNoHandshake();
}
}
use of org.vmmagic.pragma.Uninterruptible in project JikesRVM by JikesRVM.
the class RuntimeMeasurements method takeTimerSample.
/**
* Called from Thread.yieldpoint every time it is invoked due to
* a timer interrupt.
*
* @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 takeTimerSample(int whereFrom, Address yieldpointServiceMethodFP) {
// We use timer ticks as a rough approximation of time.
// TODO: kill controller clock in favor of reportedTimerTicks
// PNT: huh?
Controller.controllerClock++;
// 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()) {
ypTakenInCallerCMID = -1;
}
// Notify all registered listeners
for (NullListener aNl : timerNullListeners) {
if (aNl.isActive()) {
aNl.update(whereFrom);
}
}
for (MethodListener aMl : timerMethodListeners) {
if (aMl.isActive()) {
aMl.update(ypTakenInCMID, ypTakenInCallerCMID, whereFrom);
}
}
if (ypTakenInCallerCMID != -1) {
for (ContextListener aCl : timerContextListeners) {
if (aCl.isActive()) {
aCl.update(ypTakenInFP, whereFrom);
}
}
}
}
use of org.vmmagic.pragma.Uninterruptible in project JikesRVM by JikesRVM.
the class RuntimeMeasurements method takeCBSMethodSample.
/**
* Called from Thread.yieldpoint when it is time to take a CBS method 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 takeCBSMethodSample(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()) {
ypTakenInCallerCMID = -1;
}
// Notify all registered listeners
for (MethodListener methodListener : cbsMethodListeners) {
if (methodListener.isActive()) {
methodListener.update(ypTakenInCMID, ypTakenInCallerCMID, whereFrom);
}
}
}
use of org.vmmagic.pragma.Uninterruptible in project JikesRVM by JikesRVM.
the class OptMachineCodeMap method findMCEntry.
// /////////////////////////////////////
// Implementation
// /////////////////////////////////////
/**
* Does a binary search of the machine code maps to find the index
* in MCInformation where the entry for the argument machine code
* offset starts. Will return -1 if the entry doesn't exist.
*
* @param MCOffset the machine code offset of interest
* @return -1 if no entry exists, the index of the matching entry otherwise
*/
@Uninterruptible
private int findMCEntry(Offset MCOffset) {
// Given a machine code instruction MCOffset, find the corresponding entry
if (MCInformation == null)
return -1;
if (MCInformation.length == 0)
return -1;
int left = 0;
int right = MCInformation.length - 1;
while (left <= right) {
// take the average
int middle = (left + right) >> 1;
while ((MCInformation[middle] & START_OF_ENTRY) != START_OF_ENTRY) {
// if necessary, step backwards to beginning of entry.
middle--;
}
Offset offset = Offset.fromIntSignExtend(getMCOffset(middle));
if (MCOffset.EQ(offset)) {
return middle;
} else if (MCOffset.sGT(offset)) {
// middle is too small, shift interval to the right
left = middle + 1;
if (left >= MCInformation.length)
return -1;
while ((MCInformation[left] & START_OF_ENTRY) != START_OF_ENTRY) {
// if necessary, step forward to find next entry, but not passed end
// Need to do this to avoid finding middle again
left++;
if (left >= MCInformation.length) {
return -1;
}
}
} else {
// middle is too small, shift interval to the left
right = middle - 1;
// Note no need to adjust as, we won't chance finding middle again
}
}
return -1;
}
use of org.vmmagic.pragma.Uninterruptible in project JikesRVM by JikesRVM.
the class CompiledMethod method getInstructionOffset.
/**
* Return the offset in bytes of the given Address from the start
* of the machine code array.
* @param ip a Address (should be an interior pointer to instructions)
* @param dieOnFailure if ip is invalid should we kill the VM (we don't want
* to if already in the process of killing the VM)
* @return offset of addr from start of instructions in bytes
*/
@Uninterruptible
public final Offset getInstructionOffset(Address ip, boolean dieOnFailure) {
if (getCompilerType() == JNI || getCompilerType() == TRAP) {
return Offset.zero();
} else {
Offset offset = ip.diff(Magic.objectAsAddress(instructions));
int max = (instructions.length() + 1) << ArchConstants.getLogInstructionWidth();
if (!offset.toWord().LT(Word.fromIntZeroExtend(max))) {
if (RVMThread.isTrampolineIP(ip)) {
ip = RVMThread.getCurrentThread().getTrampolineHijackedReturnAddress();
offset = ip.diff(Magic.objectAsAddress(instructions));
if (offset.toWord().LT(Word.fromIntZeroExtend(max)))
return offset;
}
Address instructionStart = Magic.objectAsAddress(instructions);
VM.sysWriteln();
VM.sysWriteln("In thread ", RVMThread.getCurrentThreadSlot(), " getInstructionOffset: ip is not within compiled code for method: ", ip);
VM.sysWrite("\tsupposed method is ");
VM.sysWrite(method);
VM.sysWriteln();
VM.sysWriteln("\tcode for this method starts at ", instructionStart);
VM.sysWriteln("\t and has last valid return address of ", instructionStart.plus(max));
VM.sysWriteln("The requested instruction address was ", ip);
CompiledMethod realCM = CompiledMethods.findMethodForInstruction(ip);
if (realCM == null) {
VM.sysWriteln("\tUnable to find compiled method corresponding to this return address");
} else {
VM.sysWrite("\tFound compiled method ");
VM.sysWrite(realCM.getMethod());
VM.sysWriteln(" whose code contains this return address");
}
if (dieOnFailure) {
VM.sysWriteln("Attempting to dump virtual machine state before exiting");
RVMThread.dumpVirtualMachine();
VM.sysFail("Terminating VM due to invalid request for instruction offset");
}
}
// Thus, we do the assertion checking above to ensure that ip is in range.
return offset;
}
}
Aggregations