use of org.vmmagic.unboxed.WordArray in project JikesRVM by JikesRVM.
the class ArchBridgeDataExtractorTest method longParametersInBridgeMethodsAreProcessedCorrectlyFor64BitAddressing.
@Test
@Category(Requires64BitAddressing.class)
public void longParametersInBridgeMethodsAreProcessedCorrectlyFor64BitAddressing() {
TypeReference[] types = { TypeReference.Long, TypeReference.JavaLangObject };
bridge.setBridgeParameterTypes(types);
Word expected = Word.fromIntSignExtend(11);
int length = 4;
WordArray stackFrame = createNonMovableWordArray(length);
int bridgeRegLocSlotIndex = stackFrame.length() - 1;
stackFrame.set(bridgeRegLocSlotIndex - 1, expected);
Address brideRegLoc = Magic.objectAsAddress(stackFrame).plus(bridgeRegLocSlotIndex * BYTES_IN_WORD);
bridge.setBridgeRegisterLocation(brideRegLoc);
Address bridgeParameterAddr = bridge.getNextBridgeParameterAddress();
Word bridgeParameter = bridgeParameterAddr.loadWord();
assertEquals(expected, bridgeParameter);
}
use of org.vmmagic.unboxed.WordArray in project JikesRVM by JikesRVM.
the class Reflection method outOfLineInvoke.
private static Object outOfLineInvoke(RVMMethod method, Object thisArg, Object[] otherArgs, boolean isNonvirtual) {
// the class must be initialized before we can invoke a method
//
RVMClass klass = method.getDeclaringClass();
if (!klass.isInitialized()) {
RuntimeEntrypoints.initializeClassForDynamicLink(klass);
}
// remember return type
// Determine primitive type-ness early to avoid call (possible yield)
// later while refs are possibly being held in int arrays.
//
TypeReference returnType = method.getReturnType();
boolean returnIsPrimitive = returnType.isPrimitiveType();
// decide how to pass parameters
//
int triple = 0;
if (VM.BuildForIA32) {
triple = org.jikesrvm.ia32.MachineReflection.countParameters(method);
} else {
if (VM.VerifyAssertions)
VM._assert(VM.BuildForPowerPC);
triple = org.jikesrvm.ppc.MachineReflection.countParameters(method);
}
int gprs = triple & REFLECTION_GPRS_MASK;
WordArray GPRs = (gprs > 0) ? WordArray.create(gprs) : emptyWordArray;
int fprs = (triple >> REFLECTION_GPRS_BITS) & 0x1F;
double[] FPRs = (fprs > 0) ? new double[fprs] : emptyDoubleArray;
byte[] FPRmeta;
if (BuildForSSE2Full) {
FPRmeta = (fprs > 0) ? new byte[fprs] : emptyByteArray;
} else {
FPRmeta = null;
}
int spillCount = triple >> (REFLECTION_GPRS_BITS + REFLECTION_FPRS_BITS);
WordArray Spills = (spillCount > 0) ? WordArray.create(spillCount) : emptyWordArray;
if (firstUse) {
// force dynamic link sites in unwrappers to get resolved,
// before disabling gc.
// this is a bit silly, but I can't think of another way to do it [--DL]
unwrapBoolean(wrapBoolean(0));
unwrapByte(wrapByte((byte) 0));
unwrapChar(wrapChar((char) 0));
unwrapShort(wrapShort((short) 0));
unwrapInt(wrapInt(0));
unwrapLong(wrapLong(0));
unwrapFloat(wrapFloat(0));
unwrapDouble(wrapDouble(0));
firstUse = false;
}
// choose actual method to be called
//
RVMMethod targetMethod;
if (isNonvirtual || method.isStatic() || method.isObjectInitializer()) {
targetMethod = method;
} else {
RVMClass C = Magic.getObjectType(thisArg).asClass();
if (!method.getDeclaringClass().isInterface()) {
int tibIndex = method.getOffset().toInt() >>> LOG_BYTES_IN_ADDRESS;
targetMethod = C.getVirtualMethods()[tibIndex - TIB_FIRST_VIRTUAL_METHOD_INDEX];
} else {
RVMClass I = method.getDeclaringClass();
if (!RuntimeEntrypoints.isAssignableWith(I, C))
throw new IncompatibleClassChangeError();
targetMethod = C.findVirtualMethod(method.getName(), method.getDescriptor());
if (targetMethod == null)
throw new IncompatibleClassChangeError();
}
}
// getCurrentCompiledMethod is synchronized but Unpreemptible.
// Therefore there are no possible yieldpoints from the time
// the compiledMethod is loaded in getCurrentCompiledMethod
// to when we disable GC below.
// We can't allow any yieldpoints between these points because of the way in which
// we GC compiled code. Once a method is marked as obsolete, if it is not
// executing on the stack of some thread, then the process of collecting the
// code and meta-data might be initiated.
targetMethod.compile();
CompiledMethod cm = targetMethod.getCurrentCompiledMethod();
while (cm == null) {
targetMethod.compile();
cm = targetMethod.getCurrentCompiledMethod();
}
RVMThread.getCurrentThread().disableYieldpoints();
CodeArray code = cm.getEntryCodeArray();
if (VM.BuildForIA32) {
org.jikesrvm.ia32.MachineReflection.packageParameters(method, thisArg, otherArgs, GPRs, FPRs, FPRmeta, Spills);
} else {
if (VM.VerifyAssertions)
VM._assert(VM.BuildForPowerPC);
org.jikesrvm.ppc.MachineReflection.packageParameters(method, thisArg, otherArgs, GPRs, FPRs, FPRmeta, Spills);
}
// critical: no yieldpoints/GCpoints between here and the invoke of code!
// We may have references hidden in the GPRs and Spills arrays!!!
RVMThread.getCurrentThread().enableYieldpoints();
if (!returnIsPrimitive) {
return Magic.invokeMethodReturningObject(code, GPRs, FPRs, FPRmeta, Spills);
}
if (returnType.isVoidType()) {
Magic.invokeMethodReturningVoid(code, GPRs, FPRs, FPRmeta, Spills);
return null;
}
if (returnType.isBooleanType()) {
int x = Magic.invokeMethodReturningInt(code, GPRs, FPRs, FPRmeta, Spills);
return x == 1;
}
if (returnType.isByteType()) {
int x = Magic.invokeMethodReturningInt(code, GPRs, FPRs, FPRmeta, Spills);
return (byte) x;
}
if (returnType.isShortType()) {
int x = Magic.invokeMethodReturningInt(code, GPRs, FPRs, FPRmeta, Spills);
return (short) x;
}
if (returnType.isCharType()) {
int x = Magic.invokeMethodReturningInt(code, GPRs, FPRs, FPRmeta, Spills);
return (char) x;
}
if (returnType.isIntType()) {
return Magic.invokeMethodReturningInt(code, GPRs, FPRs, FPRmeta, Spills);
}
if (returnType.isLongType()) {
return Magic.invokeMethodReturningLong(code, GPRs, FPRs, FPRmeta, Spills);
}
if (returnType.isFloatType()) {
return Magic.invokeMethodReturningFloat(code, GPRs, FPRs, FPRmeta, Spills);
}
if (returnType.isDoubleType()) {
return Magic.invokeMethodReturningDouble(code, GPRs, FPRs, FPRmeta, Spills);
}
if (VM.VerifyAssertions)
VM._assert(NOT_REACHED);
return null;
}
use of org.vmmagic.unboxed.WordArray in project JikesRVM by JikesRVM.
the class HardwareTrapGCMapIterator method getNextReferenceAddress.
@Override
public Address getNextReferenceAddress() {
// update register locations, noting that the trap handler represented by this stackframe
// saved all registers into the thread's "exceptionRegisters" object
//
WordArray gprs = thread.getExceptionRegisters().getGPRs();
Address gprAddr = Magic.objectAsAddress(gprs);
for (int i = 0; i < gprs.length(); ++i) {
registerLocations.set(i, gprAddr);
gprAddr = gprAddr.plus(BYTES_IN_ADDRESS);
}
return Address.zero();
}
use of org.vmmagic.unboxed.WordArray in project JikesRVM by JikesRVM.
the class BaselineGCMapIteratorTest method getNextReferenceAddressReturnsCorrectReferenceIfReferencesArePresent.
@Test
public void getNextReferenceAddressReturnsCorrectReferenceIfReferencesArePresent() throws Exception {
NormalMethod nm = TestingTools.getNormalMethod(MethodsForTests.class, "emptyStaticMethodWithObjectParam", Object.class);
CompiledMethod cm = nm.getCurrentCompiledMethod();
// Fake a stack frame
int stackWords = 5;
WordArray wa = createNonMovableWordArray(stackWords);
for (int i = 0; i < wa.length(); i++) {
wa.set(i, Word.fromIntSignExtend(5 * i));
}
int targetSlot = wa.length() - 1;
Address fp = Magic.objectAsAddress(wa).plus(targetSlot * BYTES_IN_WORD);
// local 0 is reference.
// +/- 0 words: FP
// - 1 words: CMID
// - 2 words: saved GPRs (EDI)
// - 3 words: saved GPRs (EBX)
// - 4 words: local0 == reference
Address targetAddress = fp.minus(4 * BYTES_IN_STACKSLOT);
Word targetContents = targetAddress.loadWord();
gcMapIter.setupIterator(cm, Offset.fromIntZeroExtend(cm.getEntryCodeArray().length()), fp);
Address referenceAddr = gcMapIter.getNextReferenceAddress();
assertEquals(targetAddress, referenceAddr);
assertEquals(targetContents, referenceAddr.loadWord());
}
use of org.vmmagic.unboxed.WordArray 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.
*
* |----------|
* | NON |
* |Volatiles |
* | | <-- volatile offset
* |Volatiles |
* | |
* |FPR states|
* |__________| ___ FP
*/
private void restoreValuesFromOptSaveVolatile(byte[] stack, Offset osrFPoff, TempRegisters registers, int regmap, CompiledMethod cm) {
OptCompiledMethod tsfromCM = (OptCompiledMethod) cm;
boolean saveVolatile = tsfromCM.isSaveVolatile();
if (VM.VerifyAssertions) {
VM._assert(saveVolatile);
}
WordArray gprs = registers.gprs;
// enter critical section
// precall methods potientially causing dynamic compilation
int firstNonVolatile = tsfromCM.getFirstNonVolatileGPR();
int nonVolatiles = tsfromCM.getNumberOfNonvolatileGPRs();
int nonVolatileOffset = tsfromCM.getUnsignedNonVolatileOffset() + (nonVolatiles - 1) * BYTES_IN_STACKSLOT;
VM.disableGC();
// recover nonvolatile GPRs
for (int i = firstNonVolatile + nonVolatiles - 1; i >= firstNonVolatile; i--) {
gprs.set(NONVOLATILE_GPRS[i].value(), Magic.objectAsAddress(stack).loadWord(osrFPoff.minus(nonVolatileOffset)));
nonVolatileOffset -= BYTES_IN_STACKSLOT;
}
// restore with VOLATILES yet
int volatileOffset = nonVolatileOffset;
for (int i = NUM_VOLATILE_GPRS - 1; i >= 0; i--) {
gprs.set(VOLATILE_GPRS[i].value(), Magic.objectAsAddress(stack).loadWord(osrFPoff.minus(volatileOffset)));
volatileOffset -= BYTES_IN_STACKSLOT;
}
// powerPC starts from register 1
for (int i = 0; i < NUM_GPRS; i++) {
if (EncodedOSRMap.registerIsSet(regmap, i)) {
registers.objs[i] = Magic.addressAsObject(registers.gprs.get(i).toAddress());
}
}
VM.enableGC();
if (VM.TraceOnStackReplacement) {
for (GPR reg : GPR.values()) {
VM.sysWrite(reg.toString());
VM.sysWrite(" = ");
VM.sysWrite(registers.gprs.get(reg.value()).toAddress());
VM.sysWriteln();
}
}
}
Aggregations