use of org.vmmagic.pragma.Unpreemptible in project JikesRVM by JikesRVM.
the class BaselineExceptionDeliverer method unwindStackFrame.
/**
* Unwind a stackframe.
*/
@Override
@Unpreemptible("Unwind stack possibly from unpreemptible code")
public void unwindStackFrame(CompiledMethod compiledMethod, AbstractRegisters registers) {
NormalMethod method = (NormalMethod) compiledMethod.getMethod();
ArchBaselineCompiledMethod bcm = (ArchBaselineCompiledMethod) compiledMethod;
if (method.isSynchronized()) {
Address ip = registers.getInnermostInstructionAddress();
Offset instr = compiledMethod.getInstructionOffset(ip);
Offset lockOffset = bcm.getLockAcquisitionOffset();
if (instr.sGT(lockOffset)) {
// we actually have the lock, so must unlock it.
Object lock;
if (method.isStatic()) {
lock = method.getDeclaringClass().getResolvedClassForType();
} else {
Address fp = registers.getInnermostFramePointer();
short location = bcm.getGeneralLocalLocation(0);
Address addr;
if (BaselineCompilerImpl.isRegister(location)) {
lock = Magic.addressAsObject(registers.getGPRs().get(location).toAddress());
} else {
addr = fp.plus(BaselineCompilerImpl.locationToOffset(location) - // location offsets are positioned on top of their stackslot
BYTES_IN_ADDRESS);
lock = Magic.addressAsObject(addr.loadAddress());
}
}
if (ObjectModel.holdsLock(lock, RVMThread.getCurrentThread())) {
ObjectModel.genericUnlock(lock);
}
}
}
// restore non-volatile registers
Address fp = registers.getInnermostFramePointer();
Offset frameOffset = Offset.fromIntSignExtend(bcm.getFrameSize());
for (int i = bcm.getLastFloatStackRegister(); i >= FIRST_FLOAT_LOCAL_REGISTER.value(); --i) {
frameOffset = frameOffset.minus(BYTES_IN_DOUBLE);
long temp = Magic.getLongAtOffset(Magic.addressAsObject(fp), frameOffset);
registers.getFPRs()[i] = Magic.longBitsAsDouble(temp);
}
for (int i = bcm.getLastFixedStackRegister(); i >= FIRST_FIXED_LOCAL_REGISTER.value(); --i) {
frameOffset = frameOffset.minus(BYTES_IN_ADDRESS);
registers.getGPRs().set(i, fp.loadWord(frameOffset));
}
registers.unwindStackFrame();
}
use of org.vmmagic.pragma.Unpreemptible in project JikesRVM by JikesRVM.
the class MemoryManager method allocateArray.
/**
* Allocate an array object. This is the interruptible component, including throwing
* an OutOfMemoryError for arrays that are too large.
*
* @param numElements number of array elements
* @param logElementSize size in bytes of an array element, log base 2.
* @param headerSize size in bytes of array header
* @param tib type information block for array object
* @param allocator int that encodes which allocator should be used
* @param align the alignment requested; must be a power of 2.
* @param offset the offset at which the alignment is desired.
* @param site allocation site.
* @return array object with header installed and all elements set
* to zero/null
* See also: bytecode 0xbc ("newarray") and 0xbd ("anewarray")
*/
@Inline
@Unpreemptible
public static Object allocateArray(int numElements, int logElementSize, int headerSize, TIB tib, int allocator, int align, int offset, int site) {
int elemBytes = numElements << logElementSize;
if (elemBytes < 0 || (elemBytes >>> logElementSize) != numElements) {
/* asked to allocate more than Integer.MAX_VALUE bytes */
throwLargeArrayOutOfMemoryError();
}
int size = elemBytes + headerSize;
return allocateArrayInternal(numElements, size, tib, allocator, align, offset, site);
}
use of org.vmmagic.pragma.Unpreemptible in project JikesRVM by JikesRVM.
the class MemoryManager method newStack.
/**
* Allocate a stack
* @param bytes the number of bytes to allocate. Must be greater than
* 0.
* @return The stack
*/
@NoInline
@Unpreemptible
public static byte[] newStack(int bytes) {
if (bytes <= 0) {
if (VM.VerifyAssertions) {
VM.sysWrite("Invalid stack size: ");
VM.sysWrite(bytes);
VM.sysWriteln("!");
VM._assert(VM.NOT_REACHED, "Attempted to create stack with size (in bytes) of 0 or smaller!");
} else {
bytes = StackFrameLayout.getStackSizeNormal();
}
}
if (!VM.runningVM) {
return new byte[bytes];
} else {
RVMArray stackType = RVMArray.ByteArray;
int headerSize = ObjectModel.computeArrayHeaderSize(stackType);
int align = ObjectModel.getAlignment(stackType);
int offset = ObjectModel.getOffsetForAlignment(stackType, false);
int width = stackType.getLogElementSize();
TIB stackTib = stackType.getTypeInformationBlock();
return (byte[]) allocateArray(bytes, width, headerSize, stackTib, Plan.ALLOC_STACK, align, offset, Plan.DEFAULT_SITE);
}
}
use of org.vmmagic.pragma.Unpreemptible in project JikesRVM by JikesRVM.
the class BaselineExceptionDeliverer method deliverException.
/**
* Pass control to a catch block.
*/
@Override
@Unpreemptible("Deliver exception possibly from unpreemptible code")
public void deliverException(CompiledMethod compiledMethod, Address catchBlockInstructionAddress, Throwable exceptionObject, AbstractRegisters registers) {
Address fp = registers.getInnermostFramePointer();
RVMThread myThread = RVMThread.getCurrentThread();
// reset sp to "empty expression stack" state
//
Address sp = fp.plus(((ArchBaselineCompiledMethod) compiledMethod).getEmptyStackOffset());
// push exception object as argument to catch block
//
sp = sp.minus(BYTES_IN_ADDRESS);
sp.store(Magic.objectAsAddress(exceptionObject));
registers.getGPRs().set(SP.value(), sp.toWord());
// set address at which to resume executing frame
registers.setIP(catchBlockInstructionAddress);
// branch to catch block
//
// disabled right before RuntimeEntrypoints.deliverException was called
VM.enableGC();
if (VM.VerifyAssertions)
VM._assert(registers.getInUse());
registers.setInUse(false);
// 'give back' the portion of the stack we borrowed to run
// exception delivery code when invoked for a hardware trap.
// If this was a straight software trap (athrow) then setting
// the stacklimit should be harmless, since the stacklimit should already have exactly
// the value we are setting it too.
myThread.stackLimit = Magic.objectAsAddress(myThread.getStack()).plus(STACK_SIZE_GUARD);
Magic.restoreHardwareExceptionState(registers);
if (VM.VerifyAssertions)
VM._assert(NOT_REACHED);
}
use of org.vmmagic.pragma.Unpreemptible in project JikesRVM by JikesRVM.
the class BaselineExceptionDeliverer method unwindStackFrame.
/**
* Unwind a stackframe.
*/
@Override
@Unpreemptible("Unwind stack possibly from unpreemptible code")
public void unwindStackFrame(CompiledMethod compiledMethod, AbstractRegisters registers) {
NormalMethod method = (NormalMethod) compiledMethod.getMethod();
Address fp = registers.getInnermostFramePointer();
if (method.isSynchronized()) {
// release the lock, if it is being held
Address ip = registers.getInnermostInstructionAddress();
Offset instr = compiledMethod.getInstructionOffset(ip);
Offset lockOffset = ((ArchBaselineCompiledMethod) compiledMethod).getLockAcquisitionOffset();
if (instr.sGT(lockOffset)) {
// we actually have the lock, so must unlock it.
Object lock;
if (method.isStatic()) {
lock = method.getDeclaringClass().getResolvedClassForType();
} else {
lock = Magic.addressAsObject(fp.plus(BaselineCompilerImpl.locationToOffset(((ArchBaselineCompiledMethod) compiledMethod).getGeneralLocalLocation(0)) - BYTES_IN_ADDRESS).loadAddress());
}
if (ObjectModel.holdsLock(lock, RVMThread.getCurrentThread())) {
ObjectModel.genericUnlock(lock);
}
}
}
// Restore nonvolatile registers used by the baseline compiler.
if (VM.VerifyAssertions)
VM._assert(SAVED_GPRS == 2);
registers.getGPRs().set(EDI.value(), fp.plus(EDI_SAVE_OFFSET).loadWord());
registers.getGPRs().set(EBX.value(), fp.plus(EBX_SAVE_OFFSET).loadWord());
if (method.hasBaselineSaveLSRegistersAnnotation()) {
registers.getGPRs().set(EBP.value(), fp.plus(EBP_SAVE_OFFSET).toWord());
}
registers.unwindStackFrame();
}
Aggregations