use of org.vmmagic.unboxed.Word in project JikesRVM by JikesRVM.
the class Memory method aligned32Copy.
/**
* Copy copyBytes from src to dst.
* Assumption: either the ranges are non overlapping, or {@code src >= dst + 4}.
* Also, src and dst are 4 byte aligned and numBytes is a multiple of 4.
*
* @param dst the destination addr
* @param src the source addr
* @param copyBytes the number of bytes top copy
*/
public static void aligned32Copy(Address dst, Address src, int copyBytes) {
if (VM.VerifyAssertions) {
VM._assert(copyBytes >= 0);
VM._assert((copyBytes & (BYTES_IN_INT - 1)) == 0);
VM._assert(src.toWord().and(Word.fromIntZeroExtend(BYTES_IN_INT - 1)).isZero());
VM._assert(dst.toWord().and(Word.fromIntZeroExtend(BYTES_IN_INT - 1)).isZero());
VM._assert(src.plus(copyBytes).LE(dst) || src.GE(dst.plus(BYTES_IN_INT)));
}
if (USE_NATIVE && copyBytes > NATIVE_THRESHOLD) {
memcopy(dst, src, copyBytes);
} else {
Offset numBytes = Offset.fromIntSignExtend(copyBytes);
if (BYTES_IN_COPY == 8 && copyBytes != 0) {
Word wordMask = Word.fromIntZeroExtend(BYTES_IN_COPY - 1);
Word srcAlignment = src.toWord().and(wordMask);
if (srcAlignment.EQ(dst.toWord().and(wordMask))) {
Offset i = Offset.zero();
if (srcAlignment.EQ(Word.fromIntZeroExtend(BYTES_IN_INT))) {
copy4Bytes(dst.plus(i), src.plus(i));
i = i.plus(BYTES_IN_INT);
}
Word endAlignment = srcAlignment.plus(numBytes).and(wordMask);
numBytes = numBytes.minus(endAlignment.toOffset());
for (; i.sLT(numBytes); i = i.plus(BYTES_IN_COPY)) {
copy8Bytes(dst.plus(i), src.plus(i));
}
if (!endAlignment.isZero()) {
copy4Bytes(dst.plus(i), src.plus(i));
}
return;
}
}
// normal case: 32 bit or (64 bit not aligned)
for (Offset i = Offset.zero(); i.sLT(numBytes); i = i.plus(BYTES_IN_INT)) {
copy4Bytes(dst.plus(i), src.plus(i));
}
}
}
use of org.vmmagic.unboxed.Word in project JikesRVM by JikesRVM.
the class Memory method dumpMemory.
public static void dumpMemory(Address start, int beforeBytes, int afterBytes) {
beforeBytes = alignDown(beforeBytes, BYTES_IN_ADDRESS);
afterBytes = alignUp(afterBytes, BYTES_IN_ADDRESS);
VM.sysWrite("---- Dumping memory from ");
VM.sysWrite(start.minus(beforeBytes));
VM.sysWrite(" to ");
VM.sysWrite(start.plus(afterBytes));
VM.sysWriteln(" ----");
for (int i = -beforeBytes; i < afterBytes; i += BYTES_IN_ADDRESS) {
VM.sysWrite(i, ": ");
VM.sysWrite(start.plus(i));
Word value = start.plus(i).loadWord();
VM.sysWriteln(" ", value);
}
}
use of org.vmmagic.unboxed.Word in project JikesRVM by JikesRVM.
the class OptExecutionStateExtractor method dumpStackContent.
@SuppressWarnings("unused")
private static void dumpStackContent(byte[] stack, Offset fpOffset) {
int cmid = Magic.getIntAtOffset(stack, fpOffset.plus(STACKFRAME_METHOD_ID_OFFSET));
OptCompiledMethod cm = (OptCompiledMethod) CompiledMethods.getCompiledMethod(cmid);
int firstNonVolatile = cm.getFirstNonVolatileGPR();
int nonVolatiles = cm.getNumberOfNonvolatileGPRs();
int nonVolatileOffset = cm.getUnsignedNonVolatileOffset() + (nonVolatiles - 1) * BYTES_IN_STACKSLOT;
VM.sysWriteln("stack of " + cm.getMethod());
VM.sysWriteln(" fp offset ", fpOffset);
VM.sysWriteln(" NV area offset ", nonVolatileOffset);
VM.sysWriteln(" first NV GPR ", firstNonVolatile);
Address aFP = Magic.objectAsAddress(stack).plus(fpOffset);
for (Address a = aFP.plus(nonVolatileOffset); a.GE(aFP); a = a.minus(BYTES_IN_STACKSLOT)) {
Word content = a.loadWord();
VM.sysWriteHex(a);
VM.sysWrite(" ");
VM.sysWrite(content);
VM.sysWriteln();
}
}
use of org.vmmagic.unboxed.Word in project JikesRVM by JikesRVM.
the class BaselineExecutionStateExtractor method extractState.
@Override
public ExecutionState extractState(RVMThread thread, Offset tsFromFPoff, Offset methFPoff, int cmid) {
if (VM.TraceOnStackReplacement) {
VM.sysWriteln("BASE execStateExtractor starting ...");
}
AbstractRegisters contextRegisters = thread.getContextRegisters();
byte[] stack = thread.getStack();
if (VM.VerifyAssertions) {
int fooCmid = Magic.getIntAtOffset(stack, methFPoff.plus(STACKFRAME_METHOD_ID_OFFSET));
VM._assert(fooCmid == cmid);
}
ArchBaselineCompiledMethod fooCM = (ArchBaselineCompiledMethod) CompiledMethods.getCompiledMethod(cmid);
NormalMethod fooM = (NormalMethod) fooCM.getMethod();
// get the next bc index
VM.disableGC();
Address rowIP = Magic.objectAsAddress(stack).loadAddress(methFPoff.plus(STACKFRAME_RETURN_ADDRESS_OFFSET));
Offset ipOffset = fooCM.getInstructionOffset(rowIP);
VM.enableGC();
// CAUTION: IP Offset should point to next instruction
int bcIndex = fooCM.findBytecodeIndexForInstruction(ipOffset.plus(INSTRUCTION_WIDTH));
// assertions
if (VM.VerifyAssertions)
VM._assert(bcIndex != -1);
// create execution state object
ExecutionState state = new ExecutionState(thread, methFPoff, cmid, bcIndex, tsFromFPoff);
/* extract values for local and stack, but first of all
* we need to get type information for current PC.
*/
BytecodeTraverser typer = new BytecodeTraverser();
typer.computeLocalStackTypes(fooM, bcIndex);
byte[] localTypes = typer.getLocalTypes();
byte[] stackTypes = typer.getStackTypes();
// type. We should remove non-reference type
for (int i = 0, n = localTypes.length; i < n; i++) {
// if typer reports a local is reference type, but the GC map says no
// then set the localType to uninitialized, see VM spec, bytecode verifier
// CAUTION: gc map uses mc offset in bytes!!!
boolean gcref = fooCM.referenceMaps.isLocalRefType(fooM, ipOffset.plus(INSTRUCTION_WIDTH), i);
if (!gcref && (localTypes[i] == ClassTypeCode)) {
// use gc map as reference
localTypes[i] = VoidTypeCode;
if (VM.TraceOnStackReplacement) {
VM.sysWriteln("GC maps disgrees with type matcher at " + i + "th local");
VM.sysWriteln();
}
}
}
if (VM.TraceOnStackReplacement) {
Offset ipIndex = ipOffset.toWord().rsha(LG_INSTRUCTION_WIDTH).toOffset();
VM.sysWriteln("BC Index : " + bcIndex);
VM.sysWriteln("IP Index : ", ipIndex.plus(1));
VM.sysWriteln("MC Offset : ", ipOffset.plus(INSTRUCTION_WIDTH));
VM.sysWrite("Local Types :");
for (byte localType : localTypes) {
VM.sysWrite(" " + (char) localType);
}
VM.sysWriteln();
VM.sysWrite("Stack Types :");
for (byte stackType : stackTypes) {
VM.sysWrite(" " + (char) stackType);
}
VM.sysWriteln();
}
// go through the stack frame and extract values
// In the variable value list, we keep the order as follows:
// L0, L1, ..., S0, S1, ....
// adjust local offset and stack offset
// NOTE: donot call BaselineCompilerImpl.getFirstLocalOffset(method)
int bufCMID = Magic.getIntAtOffset(stack, tsFromFPoff.plus(STACKFRAME_METHOD_ID_OFFSET));
CompiledMethod bufCM = CompiledMethods.getCompiledMethod(bufCMID);
int cType = bufCM.getCompilerType();
// restore non-volatile registers that could contain locals; saved by yieldpointfrom methods
// for the moment disabled OPT compilation of yieldpointfrom, because here we assume baselinecompilation !! TODO
TempRegisters registers = new TempRegisters(contextRegisters);
WordArray gprs = registers.gprs;
double[] fprs = registers.fprs;
Object[] objs = registers.objs;
VM.disableGC();
// the threadswitchfrom... method on the other hand can be baseline or opt!
if (cType == CompiledMethod.BASELINE) {
if (VM.VerifyAssertions) {
VM._assert(bufCM.getMethod().hasBaselineSaveLSRegistersAnnotation());
VM._assert(methFPoff.EQ(tsFromFPoff.plus(((ArchBaselineCompiledMethod) bufCM).getFrameSize())));
}
Offset currentRegisterLocation = tsFromFPoff.plus(((ArchBaselineCompiledMethod) bufCM).getFrameSize());
for (int i = LAST_FLOAT_STACK_REGISTER.value(); i >= FIRST_FLOAT_LOCAL_REGISTER.value(); --i) {
currentRegisterLocation = currentRegisterLocation.minus(BYTES_IN_DOUBLE);
long lbits = Magic.getLongAtOffset(stack, currentRegisterLocation);
fprs[i] = Magic.longBitsAsDouble(lbits);
}
for (int i = LAST_FIXED_STACK_REGISTER.value(); i >= FIRST_FIXED_LOCAL_REGISTER.value(); --i) {
currentRegisterLocation = currentRegisterLocation.minus(BYTES_IN_ADDRESS);
Word w = Magic.objectAsAddress(stack).loadWord(currentRegisterLocation);
gprs.set(i, w);
}
} else {
// (cType == CompiledMethod.OPT)
// KV: this code needs to be modified. We need the tsFrom methods to save all NON-VOLATILES in their prolog (as is the case for baseline)
// This is because we don't know at compile time which registers might be in use and wich not by the caller method at runtime!!
// For now we disallow tsFrom methods to be opt compiled when the caller is baseline compiled
// todo: fix this together with the SaveVolatile rewrite
OptCompiledMethod fooOpt = (OptCompiledMethod) bufCM;
// foo definitely not save volatile.
if (VM.VerifyAssertions) {
boolean saveVolatile = fooOpt.isSaveVolatile();
VM._assert(!saveVolatile);
}
Offset offset = tsFromFPoff.plus(fooOpt.getUnsignedNonVolatileOffset());
// recover nonvolatile GPRs
int firstGPR = fooOpt.getFirstNonVolatileGPR();
if (firstGPR != -1) {
for (int i = firstGPR; i <= LAST_NONVOLATILE_GPR.value(); i++) {
Word w = Magic.objectAsAddress(stack).loadWord(offset);
gprs.set(i, w);
offset = offset.plus(BYTES_IN_ADDRESS);
}
}
// recover nonvolatile FPRs
int firstFPR = fooOpt.getFirstNonVolatileFPR();
if (firstFPR != -1) {
for (int i = firstFPR; i <= LAST_NONVOLATILE_FPR.value(); i++) {
long lbits = Magic.getLongAtOffset(stack, offset);
fprs[i] = Magic.longBitsAsDouble(lbits);
offset = offset.plus(BYTES_IN_DOUBLE);
}
}
}
// save objects in registers in register object array
int size = localTypes.length;
for (int i = 0; i < size; i++) {
if ((localTypes[i] == ClassTypeCode) || (localTypes[i] == ArrayTypeCode)) {
short loc = fooCM.getGeneralLocalLocation(i);
if (BaselineCompilerImpl.isRegister(loc)) {
objs[loc] = Magic.addressAsObject(gprs.get(loc).toAddress());
}
}
}
VM.enableGC();
// for locals
getVariableValueFromLocations(stack, methFPoff, localTypes, fooCM, LOCAL, registers, state);
// for stacks
Offset stackOffset = methFPoff.plus(fooCM.getEmptyStackOffset());
getVariableValue(stack, stackOffset, stackTypes, fooCM, STACK, state);
if (VM.TraceOnStackReplacement) {
state.printState();
}
if (VM.TraceOnStackReplacement) {
VM.sysWriteln("BASE executionStateExtractor done ");
}
return state;
}
use of org.vmmagic.unboxed.Word in project JikesRVM by JikesRVM.
the class OptExecutionStateExtractor method restoreValuesFromOptSaveVolatile.
/* OptSaveVolatile has different stack layout from DynamicBridge
* Have to separately recover them now, but there should be unified
* later on. TODO:
*
* Current SaveVolatile stack frame:
*
* GPR 3 -- 14 15 16 17 -- 31, cr, xer, ctr, FPR 0 -- 15
*/
private void restoreValuesFromOptSaveVolatile(byte[] stack, Offset osrFPoff, TempRegisters registers, int regmap, CompiledMethod cm) {
OptCompiledMethod tsfromCM = (OptCompiledMethod) cm;
Offset nvArea = osrFPoff.plus(tsfromCM.getUnsignedNonVolatileOffset());
WordArray gprs = registers.gprs;
double[] fprs = registers.fprs;
// temporarialy hold ct, xer, ctr register
int cr = 0;
int xer = 0;
Word ctr = Word.zero();
// enter critical section
// precall methods potientially causing dynamic compilation
int firstGPR = tsfromCM.getFirstNonVolatileGPR();
VM.disableGC();
// recover volatile GPRs.
Offset lastVoffset = nvArea;
for (int i = LAST_SCRATCH_GPR.value(); i >= FIRST_VOLATILE_GPR.value(); i--) {
lastVoffset = lastVoffset.minus(BYTES_IN_STACKSLOT);
gprs.set(i, Magic.objectAsAddress(stack).loadWord(lastVoffset));
}
// recover nonvolatile GPRs
if (firstGPR != -1) {
for (int i = firstGPR; i <= LAST_NONVOLATILE_GPR.value(); i++) {
gprs.set(i, Magic.objectAsAddress(stack).loadWord(nvArea));
nvArea = nvArea.plus(BYTES_IN_STACKSLOT);
}
}
// recover CR, XER, and CTR
cr = Magic.getIntAtOffset(stack, nvArea);
nvArea = nvArea.plus(BYTES_IN_STACKSLOT);
xer = Magic.getIntAtOffset(stack, nvArea);
nvArea = nvArea.plus(BYTES_IN_STACKSLOT);
ctr = Magic.getWordAtOffset(stack, nvArea);
nvArea = nvArea.plus(BYTES_IN_STACKSLOT);
// recover all volatile FPRs
for (int i = FIRST_SCRATCH_FPR.value(); i <= LAST_VOLATILE_FPR.value(); i++) {
long lbits = Magic.getLongAtOffset(stack, nvArea);
fprs[i] = Magic.longBitsAsDouble(lbits);
nvArea = nvArea.plus(BYTES_IN_DOUBLE);
}
// convert addresses in registers to references
for (int i = 1; i < NUM_GPRS; i++) {
if (EncodedOSRMap.registerIsSet(regmap, i)) {
registers.objs[i] = Magic.addressAsObject(registers.gprs.get(i).toAddress());
}
}
VM.enableGC();
registers.cr = cr;
registers.xer = xer;
registers.ctr = ctr;
}
Aggregations