use of org.vmmagic.unboxed.Address in project JikesRVM by JikesRVM.
the class MultianewarrayHelper method newArrayArray.
/**
* Allocate something like {@code new Foo[cnt0][cnt1]...[cntN-1]},
* or {@code new int[cnt0][cnt1]...[cntN-1]}.
* @param methodId method id of caller
* @param numDimensions number of array dimensions
* @param typeId type id of type reference for array
* @param argOffset position of word *above* `cnt0' argument within
* caller's frame This is used to access the number of elements to
* be allocated for each dimension.
*
* See also: bytecode 0xc5 ("multianewarray") in BaselineCompilerImpl
*
* @return newly allocated multidimensional array
*/
@Entrypoint
static Object newArrayArray(int methodId, int numDimensions, int typeId, int argOffset) throws NoClassDefFoundError, NegativeArraySizeException, OutOfMemoryError {
if (numDimensions == 2) {
int dim0, dim1;
// fetch number of elements to be allocated for each array dimension
VM.disableGC();
Address argp = Magic.getFramePointer().plus(argOffset);
argp = argp.minus(BYTES_IN_WORD);
dim0 = argp.loadInt();
argp = argp.minus(BYTES_IN_WORD);
dim1 = argp.loadInt();
VM.enableGC();
// validate arguments
if ((dim0 < 0) || (dim1 < 0))
throw new NegativeArraySizeException();
// create array
TypeReference tRef = TypeReference.getTypeRef(typeId);
RVMArray array = tRef.resolve().asArray();
return RuntimeEntrypoints.buildTwoDimensionalArray(methodId, dim0, dim1, array);
} else {
// fetch number of elements to be allocated for each array dimension
int[] numElements = new int[numDimensions];
VM.disableGC();
Address argp = Magic.getFramePointer().plus(argOffset);
for (int i = 0; i < numDimensions; ++i) {
argp = argp.minus(BYTES_IN_WORD);
numElements[i] = argp.loadInt();
}
VM.enableGC();
// validate arguments
for (int elements : numElements) {
if (elements < 0)
throw new NegativeArraySizeException();
}
// create array
TypeReference tRef = TypeReference.getTypeRef(typeId);
RVMArray array = tRef.resolve().asArray();
return RuntimeEntrypoints.buildMultiDimensionalArray(methodId, numElements, array);
}
}
use of org.vmmagic.unboxed.Address 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.unboxed.Address in project JikesRVM by JikesRVM.
the class Registers method setInnermost.
/**
* set ip and fp values to those of the caller. used just prior to entering
* sigwait to set fp & ip so that GC will scan the threads stack
* starting at the frame of the method that called sigwait.
*/
public void setInnermost() {
Address current_fp = Magic.getFramePointer();
ip = Magic.getReturnAddress(current_fp);
fp = Magic.getCallerFramePointer(current_fp);
}
use of org.vmmagic.unboxed.Address in project JikesRVM by JikesRVM.
the class OptGCMapIterator method updateLocateRegisters.
/**
* If any non-volatile GPRs were saved by the method being processed
* then update the registerLocations array with the locations where the
* registers were saved. Also, check for special methods that also
* save the volatile GPRs.
*/
@Override
protected void updateLocateRegisters() {
// HIGH MEMORY
//
// +---------------+ |
// FP-> | saved FP | <-- this frame's caller's frame |
// +---------------+ |
// | cmid | <-- this frame's compiledmethod id |
// +---------------+ |
// | | |
// | Spill Area | <-- spills and other method-specific |
// | ... | compiler-managed storage |
// +---------------+ |
// | Saved FP | only SaveVolatile Frames |
// | State | |
// +---------------+ |
// | VolGPR[0] |
// | ... | only SaveVolatile Frames
// | VolGPR[n] |
// +---------------+
// | NVolGPR[k] | <-- cm.getUnsignedNonVolatileOffset()
// | ... | k == cm.getFirstNonVolatileGPR()
// | NVolGPR[n] |
// +---------------+
//
// LOW MEMORY
int frameOffset = compiledMethod.getUnsignedNonVolatileOffset();
if (frameOffset >= 0) {
// get to the non vol area
Address nonVolArea = framePtr.minus(frameOffset);
// update non-volatiles
int first = compiledMethod.getFirstNonVolatileGPR();
if (first >= 0) {
// move to the beginning of the nonVol area
Address location = nonVolArea;
for (int i = first; i < NUM_NONVOLATILE_GPRS; i++) {
// determine what register index corresponds to this location
int registerIndex = NONVOLATILE_GPRS[i].value();
registerLocations.set(registerIndex, location);
if (DEBUG) {
VM.sysWrite("UpdateRegisterLocations: Register ");
VM.sysWrite(registerIndex);
VM.sysWrite(" to Location ");
VM.sysWrite(location);
VM.sysWriteln();
}
location = location.minus(BYTES_IN_ADDRESS);
}
}
// update volatiles if needed
if (compiledMethod.isSaveVolatile()) {
// move to the beginning of the nonVol area
Address location = nonVolArea.plus(BYTES_IN_ADDRESS * NUM_VOLATILE_GPRS);
for (int i = 0; i < NUM_VOLATILE_GPRS; i++) {
// determine what register index corresponds to this location
int registerIndex = VOLATILE_GPRS[i].value();
registerLocations.set(registerIndex, location);
if (DEBUG) {
VM.sysWrite("UpdateRegisterLocations: Register ");
VM.sysWrite(registerIndex);
VM.sysWrite(" to Location ");
VM.sysWrite(location);
VM.sysWriteln();
}
location = location.minus(BYTES_IN_ADDRESS);
}
}
}
}
use of org.vmmagic.unboxed.Address in project JikesRVM by JikesRVM.
the class OptExceptionDeliverer method deliverException.
/**
* Pass control to a catch block.
*/
@Override
@Unpreemptible("Deliver exception possibly from unpreemptible code")
public void deliverException(CompiledMethod cm, Address catchBlockInstructionAddress, Throwable exceptionObject, AbstractRegisters registers) {
// store exception object for later retrieval by catch block
OptCompiledMethod compiledMethod = (OptCompiledMethod) cm;
Offset offset = Offset.fromIntSignExtend(compiledMethod.getUnsignedExceptionOffset());
if (!offset.isZero()) {
// only put the exception object in the stackframe if the catch block is expecting it.
// (if the method hasn't allocated a stack slot for caught exceptions, then we can safely
// drop the exceptionObject on the floor).
Address fp = registers.getInnermostFramePointer();
Magic.setObjectAtOffset(Magic.addressAsObject(fp), offset, exceptionObject);
}
// set address at which to resume executing frame
registers.setIP(catchBlockInstructionAddress);
// disabled right before Runtime.deliverException was called
VM.enableGC();
if (VM.VerifyAssertions)
VM._assert(registers.getInUse());
registers.setInUse(false);
// "branches" to catchBlockInstructionAddress
Magic.restoreHardwareExceptionState(registers);
if (VM.VerifyAssertions)
VM._assert(NOT_REACHED);
}
Aggregations